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 /*@ 2672c3e9f7SHong Zhang DMNetworkGetSizes - Gets the the number of subnetworks and coupling subnetworks 2772c3e9f7SHong Zhang 2872c3e9f7SHong Zhang Collective on dm 2972c3e9f7SHong Zhang 3072c3e9f7SHong Zhang Input Parameters: 3172c3e9f7SHong Zhang + dm - the dm object 3272c3e9f7SHong Zhang . Nsubnet - global number of subnetworks 3372c3e9f7SHong Zhang - NsubnetCouple - global number of coupling subnetworks 3472c3e9f7SHong Zhang 3597bb938eSShri Abhyankar Level: beginner 3672c3e9f7SHong Zhang 3772c3e9f7SHong Zhang .seealso: DMNetworkCreate() 3872c3e9f7SHong Zhang @*/ 3972c3e9f7SHong Zhang PetscErrorCode DMNetworkGetSizes(DM netdm, PetscInt *Nsubnet, PetscInt *Ncsubnet) 4072c3e9f7SHong Zhang { 4172c3e9f7SHong Zhang DM_Network *network = (DM_Network*) netdm->data; 4272c3e9f7SHong Zhang 4372c3e9f7SHong Zhang PetscFunctionBegin; 4472c3e9f7SHong Zhang *Nsubnet = network->nsubnet; 4572c3e9f7SHong Zhang *Ncsubnet = network->ncsubnet; 4672c3e9f7SHong Zhang PetscFunctionReturn(0); 4772c3e9f7SHong Zhang } 4872c3e9f7SHong Zhang 4972c3e9f7SHong 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 6497bb938eSShri Abhyankar Level: beginner 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 14997bb938eSShri Abhyankar Level: beginner 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; 17072c3e9f7SHong Zhang PetscInt i; 1715f2c45f1SShri Abhyankar 1725f2c45f1SShri Abhyankar PetscFunctionBegin; 17372c3e9f7SHong Zhang for (i=0; i < (network->nsubnet-network->ncsubnet); i++) network->subnet[i].edgelist = edgelist[i]; 17472c3e9f7SHong Zhang if (network->ncsubnet) { 17572c3e9f7SHong Zhang PetscInt j = 0; 17672c3e9f7SHong Zhang if (!edgelistCouple) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Must provide edgelist_couple"); 17772c3e9f7SHong 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 1877a7aea1fSJed Brown 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 19697bb938eSShri Abhyankar Level: beginner 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; 204*8e71b177SVaclav Hapla PetscInt numCorners=2,dim = 1; /* One dimensional network */ 205caf410d2SHong Zhang PetscInt i,j,ctr,nsubnet,*eowners,np,*edges,*subnetvtx,vStart; 206caf410d2SHong Zhang PetscInt k,netid,vid, *vidxlTog,*edgelist_couple=NULL; 207caf410d2SHong Zhang const PetscInt *cone; 208caf410d2SHong Zhang MPI_Comm comm; 209caf410d2SHong Zhang PetscMPIInt size,rank; 2106500d4abSHong Zhang 2116500d4abSHong Zhang PetscFunctionBegin; 212caf410d2SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 213caf410d2SHong Zhang ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 214caf410d2SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 2156500d4abSHong Zhang 216caf410d2SHong Zhang /* Create the local edgelist for the network by concatenating local input edgelists of the subnetworks */ 217*8e71b177SVaclav Hapla ierr = PetscCalloc1(2*network->nEdges,&edges);CHKERRQ(ierr); 2187765340cSHong Zhang nsubnet = network->nsubnet - network->ncsubnet; 219caf410d2SHong Zhang ctr = 0; 2207765340cSHong Zhang for (i=0; i < nsubnet; i++) { 2216500d4abSHong Zhang for (j = 0; j < network->subnet[i].nedge; j++) { 222ba38b151SHong Zhang edges[2*ctr] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j]; 223ba38b151SHong Zhang edges[2*ctr+1] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j+1]; 2246500d4abSHong Zhang ctr++; 2256500d4abSHong Zhang } 2266500d4abSHong Zhang } 2277765340cSHong Zhang 228caf410d2SHong Zhang /* Append local coupling edgelists of the subnetworks */ 2297765340cSHong Zhang i = nsubnet; /* netid of coupling subnet */ 2307765340cSHong Zhang nsubnet = network->nsubnet; 2317765340cSHong Zhang while (i < nsubnet) { 232991cf414SHong Zhang edgelist_couple = network->subnet[i].edgelist; 23372c3e9f7SHong Zhang 2346500d4abSHong Zhang k = 0; 2356500d4abSHong Zhang for (j = 0; j < network->subnet[i].nedge; j++) { 2366500d4abSHong Zhang netid = edgelist_couple[k]; vid = edgelist_couple[k+1]; 237caf410d2SHong Zhang edges[2*ctr] = network->subnet[netid].vStart + vid; k += 2; 2386500d4abSHong Zhang 2396500d4abSHong Zhang netid = edgelist_couple[k]; vid = edgelist_couple[k+1]; 240caf410d2SHong Zhang edges[2*ctr+1] = network->subnet[netid].vStart + vid; k+=2; 2416500d4abSHong Zhang ctr++; 2426500d4abSHong Zhang } 2437765340cSHong Zhang i++; 2447765340cSHong Zhang } 245caf410d2SHong Zhang /* 246caf410d2SHong Zhang if (rank == 0) { 247caf410d2SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF,"[%d] edgelist:\n",rank); 2486500d4abSHong Zhang for(i=0; i < network->nEdges; i++) { 249caf410d2SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF,"[%D %D]",edges[2*i],edges[2*i+1]);CHKERRQ(ierr); 2506500d4abSHong Zhang printf("\n"); 2516500d4abSHong Zhang } 252caf410d2SHong Zhang } 253caf410d2SHong Zhang */ 2546500d4abSHong Zhang 255caf410d2SHong Zhang /* Create network->plex */ 256*8e71b177SVaclav Hapla ierr = DMCreate(comm,&network->plex);CHKERRQ(ierr); 257*8e71b177SVaclav Hapla ierr = DMSetType(network->plex,DMPLEX);CHKERRQ(ierr); 258*8e71b177SVaclav Hapla ierr = DMSetDimension(network->plex,dim);CHKERRQ(ierr); 259caf410d2SHong Zhang if (size == 1) { 260*8e71b177SVaclav Hapla ierr = DMPlexBuildFromCellList(network->plex,network->nEdges,network->nVertices,numCorners,edges,PETSC_FALSE);CHKERRQ(ierr); 261caf410d2SHong Zhang } else { 262*8e71b177SVaclav Hapla ierr = DMPlexBuildFromCellListParallel(network->plex,network->nEdges,network->nVertices,numCorners,edges,PETSC_FALSE,NULL);CHKERRQ(ierr); 263acdb140fSBarry Smith } 2646500d4abSHong Zhang 2656500d4abSHong Zhang ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr); 2666500d4abSHong Zhang ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr); 2676500d4abSHong Zhang ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr); 268caf410d2SHong Zhang vStart = network->vStart; 2696500d4abSHong Zhang 270caf410d2SHong Zhang ierr = PetscSectionCreate(comm,&network->DataSection);CHKERRQ(ierr); 271caf410d2SHong Zhang ierr = PetscSectionCreate(comm,&network->DofSection);CHKERRQ(ierr); 2726500d4abSHong Zhang ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr); 2736500d4abSHong Zhang ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr); 2746500d4abSHong Zhang 275caf410d2SHong Zhang network->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType); 276caf410d2SHong Zhang np = network->pEnd - network->pStart; 277caf410d2SHong Zhang ierr = PetscCalloc2(np,&network->header,np,&network->cvalue);CHKERRQ(ierr); 278caf410d2SHong Zhang 279caf410d2SHong Zhang /* Create vidxlTog: maps local vertex index to global index */ 280caf410d2SHong Zhang np = network->vEnd - vStart; 281caf410d2SHong Zhang ierr = PetscMalloc2(np,&vidxlTog,size+1,&eowners);CHKERRQ(ierr); 282caf410d2SHong Zhang ctr = 0; 283caf410d2SHong Zhang for (i=network->eStart; i<network->eEnd; i++) { 284caf410d2SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,i,&cone);CHKERRQ(ierr); 285caf410d2SHong Zhang vidxlTog[cone[0] - vStart] = edges[2*ctr]; 286caf410d2SHong Zhang vidxlTog[cone[1] - vStart] = edges[2*ctr+1]; 287caf410d2SHong Zhang ctr++; 288caf410d2SHong Zhang } 289*8e71b177SVaclav Hapla ierr = PetscFree(edges);CHKERRQ(ierr); 290caf410d2SHong Zhang 2916500d4abSHong Zhang /* Create vertices and edges array for the subnetworks */ 2926500d4abSHong Zhang for (j=0; j < network->nsubnet; j++) { 2936500d4abSHong Zhang ierr = PetscCalloc1(network->subnet[j].nedge,&network->subnet[j].edges);CHKERRQ(ierr); 294caf410d2SHong Zhang 2956500d4abSHong Zhang /* Temporarily setting nvtx and nedge to 0 so we can use them as counters in the below for loop. 2966500d4abSHong Zhang These get updated when the vertices and edges are added. */ 297caf410d2SHong Zhang network->subnet[j].nvtx = 0; 298caf410d2SHong Zhang network->subnet[j].nedge = 0; 2996500d4abSHong Zhang } 300caf410d2SHong Zhang ierr = PetscCalloc1(np,&network->subnetvtx);CHKERRQ(ierr); 3016500d4abSHong Zhang 302caf410d2SHong Zhang 303caf410d2SHong Zhang /* Get edge ownership */ 304caf410d2SHong Zhang np = network->eEnd - network->eStart; 305caf410d2SHong Zhang ierr = MPI_Allgather(&np,1,MPIU_INT,eowners+1,1,MPIU_INT,comm);CHKERRQ(ierr); 306caf410d2SHong Zhang eowners[0] = 0; 307caf410d2SHong Zhang for (i=2; i<=size; i++) eowners[i] += eowners[i-1]; 308caf410d2SHong Zhang 309caf410d2SHong Zhang i = 0; j = 0; 310caf410d2SHong Zhang while (i < np) { /* local edges, including coupling edges */ 311caf410d2SHong Zhang network->header[i].index = i + eowners[rank]; /* Global edge index */ 312caf410d2SHong Zhang 313caf410d2SHong Zhang if (j < network->nsubnet && i < network->subnet[j].eEnd) { 3146500d4abSHong Zhang network->header[i].subnetid = j; /* Subnetwork id */ 3156500d4abSHong Zhang network->subnet[j].edges[network->subnet[j].nedge++] = i; 316caf410d2SHong Zhang 317caf410d2SHong Zhang network->header[i].ndata = 0; 318caf410d2SHong Zhang ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr); 319caf410d2SHong Zhang network->header[i].offset[0] = 0; 3209988b915SShri Abhyankar network->header[i].offsetvarrel[0] = 0; 321caf410d2SHong Zhang i++; 322caf410d2SHong Zhang } 323caf410d2SHong Zhang if (i >= network->subnet[j].eEnd) j++; 324caf410d2SHong Zhang } 325caf410d2SHong Zhang 326caf410d2SHong Zhang /* Count network->subnet[*].nvtx */ 327caf410d2SHong Zhang for (i=vStart; i<network->vEnd; i++) { /* local vertices, including ghosts */ 328caf410d2SHong Zhang k = vidxlTog[i-vStart]; 329caf410d2SHong Zhang for (j=0; j < network->nsubnet; j++) { 330caf410d2SHong Zhang if (network->subnet[j].vStart <= k && k < network->subnet[j].vEnd) { 331caf410d2SHong Zhang network->subnet[j].nvtx++; 3326500d4abSHong Zhang break; 3336500d4abSHong Zhang } 3346500d4abSHong Zhang } 3356500d4abSHong Zhang } 3366500d4abSHong Zhang 337caf410d2SHong Zhang /* Set network->subnet[*].vertices on array network->subnetvtx */ 338caf410d2SHong Zhang subnetvtx = network->subnetvtx; 3396500d4abSHong Zhang for (j=0; j<network->nsubnet; j++) { 340caf410d2SHong Zhang network->subnet[j].vertices = subnetvtx; 341caf410d2SHong Zhang subnetvtx += network->subnet[j].nvtx; 342caf410d2SHong Zhang network->subnet[j].nvtx = 0; 343caf410d2SHong Zhang } 344caf410d2SHong Zhang 345caf410d2SHong Zhang /* Set vertex array for the subnetworks */ 346caf410d2SHong Zhang for (i=vStart; i<network->vEnd; i++) { /* local vertices, including ghosts */ 347caf410d2SHong Zhang network->header[i].index = vidxlTog[i-vStart]; /* Global vertex index */ 348caf410d2SHong Zhang 349caf410d2SHong Zhang k = vidxlTog[i-vStart]; 350caf410d2SHong Zhang for (j=0; j < network->nsubnet; j++) { 351caf410d2SHong Zhang if (network->subnet[j].vStart <= k && k < network->subnet[j].vEnd) { 3526500d4abSHong Zhang network->header[i].subnetid = j; 3536500d4abSHong Zhang network->subnet[j].vertices[network->subnet[j].nvtx++] = i; 3546500d4abSHong Zhang break; 3556500d4abSHong Zhang } 3566500d4abSHong Zhang } 357caf410d2SHong Zhang 3586500d4abSHong Zhang network->header[i].ndata = 0; 3596500d4abSHong Zhang ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr); 360caf410d2SHong Zhang network->header[i].offset[0] = 0; 3619988b915SShri Abhyankar network->header[i].offsetvarrel[0] = 0; 3626500d4abSHong Zhang } 3636500d4abSHong Zhang 364caf410d2SHong Zhang ierr = PetscFree2(vidxlTog,eowners);CHKERRQ(ierr); 3655f2c45f1SShri Abhyankar PetscFunctionReturn(0); 3665f2c45f1SShri Abhyankar } 3675f2c45f1SShri Abhyankar 36894ef8ddeSSatish Balay /*@C 3692727e31bSShri Abhyankar DMNetworkGetSubnetworkInfo - Returns the info for the subnetwork 3702727e31bSShri Abhyankar 3717a7aea1fSJed Brown Input Parameters: 372caf410d2SHong Zhang + dm - the DM object 3732727e31bSShri Abhyankar - id - the ID (integer) of the subnetwork 3742727e31bSShri Abhyankar 3757a7aea1fSJed Brown Output Parameters: 3762727e31bSShri Abhyankar + nv - number of vertices (local) 3772727e31bSShri Abhyankar . ne - number of edges (local) 3782727e31bSShri Abhyankar . vtx - local vertices for this subnetwork 379a2b725a8SWilliam Gropp - edge - local edges for this subnetwork 3802727e31bSShri Abhyankar 3812727e31bSShri Abhyankar Notes: 3822727e31bSShri Abhyankar Cannot call this routine before DMNetworkLayoutSetup() 3832727e31bSShri Abhyankar 38406dd6b0eSSatish Balay Level: intermediate 38506dd6b0eSSatish Balay 3862727e31bSShri Abhyankar .seealso: DMNetworkLayoutSetUp, DMNetworkCreate 3872727e31bSShri Abhyankar @*/ 388caf410d2SHong Zhang PetscErrorCode DMNetworkGetSubnetworkInfo(DM dm,PetscInt id,PetscInt *nv, PetscInt *ne,const PetscInt **vtx, const PetscInt **edge) 3892727e31bSShri Abhyankar { 390caf410d2SHong Zhang DM_Network *network = (DM_Network*)dm->data; 3912727e31bSShri Abhyankar 3922727e31bSShri Abhyankar PetscFunctionBegin; 39372c3e9f7SHong 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); 3942727e31bSShri Abhyankar *nv = network->subnet[id].nvtx; 3952727e31bSShri Abhyankar *ne = network->subnet[id].nedge; 3962727e31bSShri Abhyankar *vtx = network->subnet[id].vertices; 3972727e31bSShri Abhyankar *edge = network->subnet[id].edges; 3982727e31bSShri Abhyankar PetscFunctionReturn(0); 3992727e31bSShri Abhyankar } 4002727e31bSShri Abhyankar 4012727e31bSShri Abhyankar /*@C 402caf410d2SHong Zhang DMNetworkGetSubnetworkCoupleInfo - Returns the info for the coupling subnetwork 403caf410d2SHong Zhang 4047a7aea1fSJed Brown Input Parameters: 405caf410d2SHong Zhang + dm - the DM object 406caf410d2SHong Zhang - id - the ID (integer) of the coupling subnetwork 407caf410d2SHong Zhang 4087a7aea1fSJed Brown Output Parameters: 409caf410d2SHong Zhang + ne - number of edges (local) 410caf410d2SHong Zhang - edge - local edges for this coupling subnetwork 411caf410d2SHong Zhang 412caf410d2SHong Zhang Notes: 413caf410d2SHong Zhang Cannot call this routine before DMNetworkLayoutSetup() 414caf410d2SHong Zhang 415caf410d2SHong Zhang Level: intermediate 416caf410d2SHong Zhang 417caf410d2SHong Zhang .seealso: DMNetworkGetSubnetworkInfo, DMNetworkLayoutSetUp, DMNetworkCreate 418caf410d2SHong Zhang @*/ 419caf410d2SHong Zhang PetscErrorCode DMNetworkGetSubnetworkCoupleInfo(DM dm,PetscInt id,PetscInt *ne,const PetscInt **edge) 420caf410d2SHong Zhang { 421caf410d2SHong Zhang DM_Network *net = (DM_Network*)dm->data; 42272c3e9f7SHong Zhang PetscInt id1; 423caf410d2SHong Zhang 424caf410d2SHong Zhang PetscFunctionBegin; 42572c3e9f7SHong Zhang if (net->ncsubnet) { 42672c3e9f7SHong 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); 42772c3e9f7SHong Zhang 42872c3e9f7SHong Zhang id1 = id + net->nsubnet - net->ncsubnet; 429caf410d2SHong Zhang *ne = net->subnet[id1].nedge; 430caf410d2SHong Zhang *edge = net->subnet[id1].edges; 43172c3e9f7SHong Zhang } else { 43272c3e9f7SHong Zhang *ne = 0; 43372c3e9f7SHong Zhang *edge = NULL; 43472c3e9f7SHong Zhang } 435caf410d2SHong Zhang PetscFunctionReturn(0); 436caf410d2SHong Zhang } 437caf410d2SHong Zhang 438caf410d2SHong Zhang /*@C 4395f2c45f1SShri Abhyankar DMNetworkRegisterComponent - Registers the network component 4405f2c45f1SShri Abhyankar 441d083f849SBarry Smith Logically collective on dm 4425f2c45f1SShri Abhyankar 4437a7aea1fSJed Brown Input Parameters: 4445f2c45f1SShri Abhyankar + dm - the network object 4455f2c45f1SShri Abhyankar . name - the component name 4465f2c45f1SShri Abhyankar - size - the storage size in bytes for this component data 4475f2c45f1SShri Abhyankar 4487a7aea1fSJed Brown Output Parameters: 4495f2c45f1SShri Abhyankar . key - an integer key that defines the component 4505f2c45f1SShri Abhyankar 4515f2c45f1SShri Abhyankar Notes 4525f2c45f1SShri Abhyankar This routine should be called by all processors before calling DMNetworkLayoutSetup(). 4535f2c45f1SShri Abhyankar 45497bb938eSShri Abhyankar Level: beginner 4555f2c45f1SShri Abhyankar 4565f2c45f1SShri Abhyankar .seealso: DMNetworkLayoutSetUp, DMNetworkCreate 4575f2c45f1SShri Abhyankar @*/ 458caf410d2SHong Zhang PetscErrorCode DMNetworkRegisterComponent(DM dm,const char *name,size_t size,PetscInt *key) 4595f2c45f1SShri Abhyankar { 4605f2c45f1SShri Abhyankar PetscErrorCode ierr; 4615f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*) dm->data; 4625f2c45f1SShri Abhyankar DMNetworkComponent *component=&network->component[network->ncomponent]; 4635f2c45f1SShri Abhyankar PetscBool flg=PETSC_FALSE; 4645f2c45f1SShri Abhyankar PetscInt i; 4655f2c45f1SShri Abhyankar 4665f2c45f1SShri Abhyankar PetscFunctionBegin; 4675f2c45f1SShri Abhyankar for (i=0; i < network->ncomponent; i++) { 4685f2c45f1SShri Abhyankar ierr = PetscStrcmp(component->name,name,&flg);CHKERRQ(ierr); 4695f2c45f1SShri Abhyankar if (flg) { 4705f2c45f1SShri Abhyankar *key = i; 4715f2c45f1SShri Abhyankar PetscFunctionReturn(0); 4725f2c45f1SShri Abhyankar } 4736d64e262SShri Abhyankar } 4746d64e262SShri Abhyankar if(network->ncomponent == MAX_COMPONENTS) { 4756d64e262SShri Abhyankar SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Number of components registered exceeds the max %D",MAX_COMPONENTS); 4765f2c45f1SShri Abhyankar } 4775f2c45f1SShri Abhyankar 4785f2c45f1SShri Abhyankar ierr = PetscStrcpy(component->name,name);CHKERRQ(ierr); 4795f2c45f1SShri Abhyankar component->size = size/sizeof(DMNetworkComponentGenericDataType); 4805f2c45f1SShri Abhyankar *key = network->ncomponent; 4815f2c45f1SShri Abhyankar network->ncomponent++; 4825f2c45f1SShri Abhyankar PetscFunctionReturn(0); 4835f2c45f1SShri Abhyankar } 4845f2c45f1SShri Abhyankar 4855f2c45f1SShri Abhyankar /*@ 4865f2c45f1SShri Abhyankar DMNetworkGetVertexRange - Get the bounds [start, end) for the vertices. 4875f2c45f1SShri Abhyankar 4885f2c45f1SShri Abhyankar Not Collective 4895f2c45f1SShri Abhyankar 4905f2c45f1SShri Abhyankar Input Parameters: 491a2b725a8SWilliam Gropp . dm - The DMNetwork object 4925f2c45f1SShri Abhyankar 493fd292e60Sprj- Output Parameters: 4945f2c45f1SShri Abhyankar + vStart - The first vertex point 4955f2c45f1SShri Abhyankar - vEnd - One beyond the last vertex point 4965f2c45f1SShri Abhyankar 49797bb938eSShri Abhyankar Level: beginner 4985f2c45f1SShri Abhyankar 4995f2c45f1SShri Abhyankar .seealso: DMNetworkGetEdgeRange 5005f2c45f1SShri Abhyankar @*/ 5015f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVertexRange(DM dm,PetscInt *vStart,PetscInt *vEnd) 5025f2c45f1SShri Abhyankar { 5035f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 5045f2c45f1SShri Abhyankar 5055f2c45f1SShri Abhyankar PetscFunctionBegin; 5065f2c45f1SShri Abhyankar if (vStart) *vStart = network->vStart; 5075f2c45f1SShri Abhyankar if (vEnd) *vEnd = network->vEnd; 5085f2c45f1SShri Abhyankar PetscFunctionReturn(0); 5095f2c45f1SShri Abhyankar } 5105f2c45f1SShri Abhyankar 5115f2c45f1SShri Abhyankar /*@ 5125f2c45f1SShri Abhyankar DMNetworkGetEdgeRange - Get the bounds [start, end) for the edges. 5135f2c45f1SShri Abhyankar 5145f2c45f1SShri Abhyankar Not Collective 5155f2c45f1SShri Abhyankar 5165f2c45f1SShri Abhyankar Input Parameters: 517a2b725a8SWilliam Gropp . dm - The DMNetwork object 5185f2c45f1SShri Abhyankar 519fd292e60Sprj- Output Parameters: 5205f2c45f1SShri Abhyankar + eStart - The first edge point 5215f2c45f1SShri Abhyankar - eEnd - One beyond the last edge point 5225f2c45f1SShri Abhyankar 52397bb938eSShri Abhyankar Level: beginner 5245f2c45f1SShri Abhyankar 5255f2c45f1SShri Abhyankar .seealso: DMNetworkGetVertexRange 5265f2c45f1SShri Abhyankar @*/ 5275f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetEdgeRange(DM dm,PetscInt *eStart,PetscInt *eEnd) 5285f2c45f1SShri Abhyankar { 5295f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 5305f2c45f1SShri Abhyankar 5315f2c45f1SShri Abhyankar PetscFunctionBegin; 5325f2c45f1SShri Abhyankar if (eStart) *eStart = network->eStart; 5335f2c45f1SShri Abhyankar if (eEnd) *eEnd = network->eEnd; 5345f2c45f1SShri Abhyankar PetscFunctionReturn(0); 5355f2c45f1SShri Abhyankar } 5365f2c45f1SShri Abhyankar 5377b6afd5bSHong Zhang /*@ 538e85e6aecSHong Zhang DMNetworkGetGlobalEdgeIndex - Get the user global numbering for the edge. 5397b6afd5bSHong Zhang 5407b6afd5bSHong Zhang Not Collective 5417b6afd5bSHong Zhang 5427b6afd5bSHong Zhang Input Parameters: 5437b6afd5bSHong Zhang + dm - DMNetwork object 544e85e6aecSHong Zhang - p - edge point 5457b6afd5bSHong Zhang 546fd292e60Sprj- Output Parameters: 547e85e6aecSHong Zhang . index - user global numbering for the edge 5487b6afd5bSHong Zhang 5497b6afd5bSHong Zhang Level: intermediate 5507b6afd5bSHong Zhang 551e85e6aecSHong Zhang .seealso: DMNetworkGetGlobalVertexIndex 5527b6afd5bSHong Zhang @*/ 553e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalEdgeIndex(DM dm,PetscInt p,PetscInt *index) 5547b6afd5bSHong Zhang { 5557b6afd5bSHong Zhang PetscErrorCode ierr; 5567b6afd5bSHong Zhang DM_Network *network = (DM_Network*)dm->data; 5577b6afd5bSHong Zhang PetscInt offsetp; 5587b6afd5bSHong Zhang DMNetworkComponentHeader header; 5597b6afd5bSHong Zhang 5607b6afd5bSHong Zhang PetscFunctionBegin; 561caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 5627b6afd5bSHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 5637b6afd5bSHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp); 564e85e6aecSHong Zhang *index = header->index; 5657b6afd5bSHong Zhang PetscFunctionReturn(0); 5667b6afd5bSHong Zhang } 5677b6afd5bSHong Zhang 5685f2c45f1SShri Abhyankar /*@ 569e85e6aecSHong Zhang DMNetworkGetGlobalVertexIndex - Get the user global numbering for the vertex. 570e85e6aecSHong Zhang 571e85e6aecSHong Zhang Not Collective 572e85e6aecSHong Zhang 573e85e6aecSHong Zhang Input Parameters: 574e85e6aecSHong Zhang + dm - DMNetwork object 575e85e6aecSHong Zhang - p - vertex point 576e85e6aecSHong Zhang 577fd292e60Sprj- Output Parameters: 578e85e6aecSHong Zhang . index - user global numbering for the vertex 579e85e6aecSHong Zhang 580e85e6aecSHong Zhang Level: intermediate 581e85e6aecSHong Zhang 582e85e6aecSHong Zhang .seealso: DMNetworkGetGlobalEdgeIndex 583e85e6aecSHong Zhang @*/ 584e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalVertexIndex(DM dm,PetscInt p,PetscInt *index) 585e85e6aecSHong Zhang { 586e85e6aecSHong Zhang PetscErrorCode ierr; 587e85e6aecSHong Zhang DM_Network *network = (DM_Network*)dm->data; 588e85e6aecSHong Zhang PetscInt offsetp; 589e85e6aecSHong Zhang DMNetworkComponentHeader header; 590e85e6aecSHong Zhang 591e85e6aecSHong Zhang PetscFunctionBegin; 592caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 593e85e6aecSHong Zhang ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 594e85e6aecSHong Zhang header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp); 595e85e6aecSHong Zhang *index = header->index; 596e85e6aecSHong Zhang PetscFunctionReturn(0); 597e85e6aecSHong Zhang } 598e85e6aecSHong Zhang 599c3b11c7cSShri Abhyankar /* 600c3b11c7cSShri Abhyankar DMNetworkGetComponentKeyOffset - Gets the type along with the offset for indexing the 601c3b11c7cSShri Abhyankar component value from the component data array 602c3b11c7cSShri Abhyankar 603c3b11c7cSShri Abhyankar Not Collective 604c3b11c7cSShri Abhyankar 605c3b11c7cSShri Abhyankar Input Parameters: 606c3b11c7cSShri Abhyankar + dm - The DMNetwork object 607c3b11c7cSShri Abhyankar . p - vertex/edge point 608c3b11c7cSShri Abhyankar - compnum - component number 609c3b11c7cSShri Abhyankar 610c3b11c7cSShri Abhyankar Output Parameters: 611c3b11c7cSShri Abhyankar + compkey - the key obtained when registering the component 612c3b11c7cSShri Abhyankar - offset - offset into the component data array associated with the vertex/edge point 613c3b11c7cSShri Abhyankar 614c3b11c7cSShri Abhyankar Notes: 615c3b11c7cSShri Abhyankar Typical usage: 616c3b11c7cSShri Abhyankar 617c3b11c7cSShri Abhyankar DMNetworkGetComponentDataArray(dm, &arr); 618c3b11c7cSShri Abhyankar DMNetworkGetVertex/EdgeRange(dm,&Start,&End); 619c3b11c7cSShri Abhyankar Loop over vertices or edges 620c3b11c7cSShri Abhyankar DMNetworkGetNumComponents(dm,v,&numcomps); 621c3b11c7cSShri Abhyankar Loop over numcomps 622c3b11c7cSShri Abhyankar DMNetworkGetComponentKeyOffset(dm,v,compnum,&key,&offset); 623c3b11c7cSShri Abhyankar compdata = (UserCompDataType)(arr+offset); 624c3b11c7cSShri Abhyankar 625c3b11c7cSShri Abhyankar Level: intermediate 626c3b11c7cSShri Abhyankar 627c3b11c7cSShri Abhyankar .seealso: DMNetworkGetNumComponents, DMNetworkGetComponentDataArray, 628c3b11c7cSShri Abhyankar */ 629c3b11c7cSShri Abhyankar PetscErrorCode DMNetworkGetComponentKeyOffset(DM dm,PetscInt p, PetscInt compnum, PetscInt *compkey, PetscInt *offset) 630c3b11c7cSShri Abhyankar { 631c3b11c7cSShri Abhyankar PetscErrorCode ierr; 632c3b11c7cSShri Abhyankar PetscInt offsetp; 633c3b11c7cSShri Abhyankar DMNetworkComponentHeader header; 634c3b11c7cSShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 635c3b11c7cSShri Abhyankar 636c3b11c7cSShri Abhyankar PetscFunctionBegin; 637c3b11c7cSShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 638c3b11c7cSShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp); 639c3b11c7cSShri Abhyankar if (compkey) *compkey = header->key[compnum]; 640c3b11c7cSShri Abhyankar if (offset) *offset = offsetp+network->dataheadersize+header->offset[compnum]; 641c3b11c7cSShri Abhyankar PetscFunctionReturn(0); 642c3b11c7cSShri Abhyankar } 643c3b11c7cSShri Abhyankar 644c3b11c7cSShri Abhyankar /*@ 645c3b11c7cSShri Abhyankar DMNetworkGetComponent - Returns the network component and its key 646c3b11c7cSShri Abhyankar 647c3b11c7cSShri Abhyankar Not Collective 648c3b11c7cSShri Abhyankar 6497a7aea1fSJed Brown Input Parameters: 650c3b11c7cSShri Abhyankar + dm - DMNetwork object 651c3b11c7cSShri Abhyankar . p - edge or vertex point 652c3b11c7cSShri Abhyankar - compnum - component number 653c3b11c7cSShri Abhyankar 654c3b11c7cSShri Abhyankar Output Parameters: 655c3b11c7cSShri Abhyankar + compkey - the key set for this computing during registration 656c3b11c7cSShri Abhyankar - component - the component data 657c3b11c7cSShri Abhyankar 658c3b11c7cSShri Abhyankar Notes: 659c3b11c7cSShri Abhyankar Typical usage: 660c3b11c7cSShri Abhyankar 661c3b11c7cSShri Abhyankar DMNetworkGetVertex/EdgeRange(dm,&Start,&End); 662c3b11c7cSShri Abhyankar Loop over vertices or edges 663c3b11c7cSShri Abhyankar DMNetworkGetNumComponents(dm,v,&numcomps); 664c3b11c7cSShri Abhyankar Loop over numcomps 665c3b11c7cSShri Abhyankar DMNetworkGetComponent(dm,v,compnum,&key,&component); 666c3b11c7cSShri Abhyankar 66797bb938eSShri Abhyankar Level: beginner 668c3b11c7cSShri Abhyankar 669c3b11c7cSShri Abhyankar .seealso: DMNetworkGetNumComponents, DMNetworkGetVariableOffset 670c3b11c7cSShri Abhyankar @*/ 671c3b11c7cSShri Abhyankar PetscErrorCode DMNetworkGetComponent(DM dm, PetscInt p, PetscInt compnum, PetscInt *key, void **component) 672c3b11c7cSShri Abhyankar { 673c3b11c7cSShri Abhyankar PetscErrorCode ierr; 674c3b11c7cSShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 675e108cb99SStefano Zampini PetscInt offsetd = 0; 676c3b11c7cSShri Abhyankar 677c3b11c7cSShri Abhyankar PetscFunctionBegin; 678c3b11c7cSShri Abhyankar ierr = DMNetworkGetComponentKeyOffset(dm,p,compnum,key,&offsetd);CHKERRQ(ierr); 679c3b11c7cSShri Abhyankar *component = network->componentdataarray+offsetd; 680c3b11c7cSShri Abhyankar PetscFunctionReturn(0); 681c3b11c7cSShri Abhyankar } 682c3b11c7cSShri Abhyankar 683e85e6aecSHong Zhang /*@ 684325661f6SSatish Balay DMNetworkAddComponent - Adds a network component at the given point (vertex/edge) 6855f2c45f1SShri Abhyankar 6865f2c45f1SShri Abhyankar Not Collective 6875f2c45f1SShri Abhyankar 6885f2c45f1SShri Abhyankar Input Parameters: 6895f2c45f1SShri Abhyankar + dm - The DMNetwork object 6905f2c45f1SShri Abhyankar . p - vertex/edge point 6915f2c45f1SShri Abhyankar . componentkey - component key returned while registering the component 6925f2c45f1SShri Abhyankar - compvalue - pointer to the data structure for the component 6935f2c45f1SShri Abhyankar 69497bb938eSShri Abhyankar Level: beginner 6955f2c45f1SShri Abhyankar 6965f2c45f1SShri Abhyankar .seealso: DMNetworkGetVertexRange, DMNetworkGetEdgeRange, DMNetworkRegisterComponent 6975f2c45f1SShri Abhyankar @*/ 6985f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddComponent(DM dm, PetscInt p,PetscInt componentkey,void* compvalue) 6995f2c45f1SShri Abhyankar { 7005f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 70143a39a44SBarry Smith DMNetworkComponent *component = &network->component[componentkey]; 7025f2c45f1SShri Abhyankar DMNetworkComponentHeader header = &network->header[p]; 7035f2c45f1SShri Abhyankar DMNetworkComponentValue cvalue = &network->cvalue[p]; 7045f2c45f1SShri Abhyankar PetscErrorCode ierr; 7055f2c45f1SShri Abhyankar 7065f2c45f1SShri Abhyankar PetscFunctionBegin; 707fa58f0a9SHong 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); 708fa58f0a9SHong Zhang 70943a39a44SBarry Smith header->size[header->ndata] = component->size; 71043a39a44SBarry Smith ierr = PetscSectionAddDof(network->DataSection,p,component->size);CHKERRQ(ierr); 7115f2c45f1SShri Abhyankar header->key[header->ndata] = componentkey; 7125f2c45f1SShri Abhyankar if (header->ndata != 0) header->offset[header->ndata] = header->offset[header->ndata-1] + header->size[header->ndata-1]; 7139988b915SShri Abhyankar header->nvar[header->ndata] = 0; 7145f2c45f1SShri Abhyankar 7155f2c45f1SShri Abhyankar cvalue->data[header->ndata] = (void*)compvalue; 7165f2c45f1SShri Abhyankar header->ndata++; 7175f2c45f1SShri Abhyankar PetscFunctionReturn(0); 7185f2c45f1SShri Abhyankar } 7195f2c45f1SShri Abhyankar 7205f2c45f1SShri Abhyankar /*@ 7219988b915SShri Abhyankar DMNetworkSetComponentNumVariables - Sets the number of variables for a component 7229988b915SShri Abhyankar 7239988b915SShri Abhyankar Not Collective 7249988b915SShri Abhyankar 7259988b915SShri Abhyankar Input Parameters: 7269988b915SShri Abhyankar + dm - The DMNetwork object 7279988b915SShri Abhyankar . p - vertex/edge point 7289988b915SShri Abhyankar . compnum - component number (First component added = 0, second = 1, ...) 7299988b915SShri Abhyankar - nvar - number of variables for the component 7309988b915SShri Abhyankar 73197bb938eSShri Abhyankar Level: beginner 7329988b915SShri Abhyankar 7339dacc45bSShrirang Abhyankar .seealso: DMNetworkAddComponent(), DMNetworkGetNumComponents(),DMNetworkRegisterComponent() 7349988b915SShri Abhyankar @*/ 7359988b915SShri Abhyankar PetscErrorCode DMNetworkSetComponentNumVariables(DM dm, PetscInt p,PetscInt compnum,PetscInt nvar) 7369988b915SShri Abhyankar { 7379988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 7389988b915SShri Abhyankar DMNetworkComponentHeader header = &network->header[p]; 7399988b915SShri Abhyankar PetscErrorCode ierr; 7409988b915SShri Abhyankar 7419988b915SShri Abhyankar PetscFunctionBegin; 7429988b915SShri Abhyankar ierr = DMNetworkAddNumVariables(dm,p,nvar);CHKERRQ(ierr); 7439988b915SShri Abhyankar header->nvar[compnum] = nvar; 7449988b915SShri Abhyankar if (compnum != 0) header->offsetvarrel[compnum] = header->offsetvarrel[compnum-1] + header->nvar[compnum-1]; 7459988b915SShri Abhyankar PetscFunctionReturn(0); 7469988b915SShri Abhyankar } 7479988b915SShri Abhyankar 7489988b915SShri Abhyankar /*@ 7495f2c45f1SShri Abhyankar DMNetworkGetNumComponents - Get the number of components at a vertex/edge 7505f2c45f1SShri Abhyankar 7515f2c45f1SShri Abhyankar Not Collective 7525f2c45f1SShri Abhyankar 7535f2c45f1SShri Abhyankar Input Parameters: 7545f2c45f1SShri Abhyankar + dm - The DMNetwork object 755a2b725a8SWilliam Gropp - p - vertex/edge point 7565f2c45f1SShri Abhyankar 7575f2c45f1SShri Abhyankar Output Parameters: 7585f2c45f1SShri Abhyankar . numcomponents - Number of components at the vertex/edge 7595f2c45f1SShri Abhyankar 76097bb938eSShri Abhyankar Level: beginner 7615f2c45f1SShri Abhyankar 7625f2c45f1SShri Abhyankar .seealso: DMNetworkRegisterComponent, DMNetworkAddComponent 7635f2c45f1SShri Abhyankar @*/ 7645f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetNumComponents(DM dm,PetscInt p,PetscInt *numcomponents) 7655f2c45f1SShri Abhyankar { 7665f2c45f1SShri Abhyankar PetscErrorCode ierr; 7675f2c45f1SShri Abhyankar PetscInt offset; 7685f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 7695f2c45f1SShri Abhyankar 7705f2c45f1SShri Abhyankar PetscFunctionBegin; 7715f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr); 7725f2c45f1SShri Abhyankar *numcomponents = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata; 7735f2c45f1SShri Abhyankar PetscFunctionReturn(0); 7745f2c45f1SShri Abhyankar } 7755f2c45f1SShri Abhyankar 7765f2c45f1SShri Abhyankar /*@ 7775f2c45f1SShri Abhyankar DMNetworkGetVariableOffset - Get the offset for accessing the variable associated with the given vertex/edge from the local vector. 7785f2c45f1SShri Abhyankar 7795f2c45f1SShri Abhyankar Not Collective 7805f2c45f1SShri Abhyankar 7815f2c45f1SShri Abhyankar Input Parameters: 7825f2c45f1SShri Abhyankar + dm - The DMNetwork object 7835f2c45f1SShri Abhyankar - p - the edge/vertex point 7845f2c45f1SShri Abhyankar 7855f2c45f1SShri Abhyankar Output Parameters: 7865f2c45f1SShri Abhyankar . offset - the offset 7875f2c45f1SShri Abhyankar 78897bb938eSShri Abhyankar Level: beginner 7895f2c45f1SShri Abhyankar 7905f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 7915f2c45f1SShri Abhyankar @*/ 7925f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableOffset(DM dm,PetscInt p,PetscInt *offset) 7935f2c45f1SShri Abhyankar { 7945f2c45f1SShri Abhyankar PetscErrorCode ierr; 7955f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 7965f2c45f1SShri Abhyankar 7975f2c45f1SShri Abhyankar PetscFunctionBegin; 7981bb6d2a8SBarry Smith ierr = PetscSectionGetOffset(network->plex->localSection,p,offset);CHKERRQ(ierr); 7995f2c45f1SShri Abhyankar PetscFunctionReturn(0); 8005f2c45f1SShri Abhyankar } 8015f2c45f1SShri Abhyankar 8025f2c45f1SShri Abhyankar /*@ 8035f2c45f1SShri Abhyankar DMNetworkGetVariableGlobalOffset - Get the global offset for the variable associated with the given vertex/edge from the global vector. 8045f2c45f1SShri Abhyankar 8055f2c45f1SShri Abhyankar Not Collective 8065f2c45f1SShri Abhyankar 8075f2c45f1SShri Abhyankar Input Parameters: 8085f2c45f1SShri Abhyankar + dm - The DMNetwork object 8095f2c45f1SShri Abhyankar - p - the edge/vertex point 8105f2c45f1SShri Abhyankar 8115f2c45f1SShri Abhyankar Output Parameters: 8125f2c45f1SShri Abhyankar . offsetg - the offset 8135f2c45f1SShri Abhyankar 81497bb938eSShri Abhyankar Level: beginner 8155f2c45f1SShri Abhyankar 8165f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableOffset, DMGetLocalVector 8175f2c45f1SShri Abhyankar @*/ 8185f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableGlobalOffset(DM dm,PetscInt p,PetscInt *offsetg) 8195f2c45f1SShri Abhyankar { 8205f2c45f1SShri Abhyankar PetscErrorCode ierr; 8215f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 8225f2c45f1SShri Abhyankar 8235f2c45f1SShri Abhyankar PetscFunctionBegin; 8241bb6d2a8SBarry Smith ierr = PetscSectionGetOffset(network->plex->globalSection,p,offsetg);CHKERRQ(ierr); 8256fefedf4SHong Zhang if (*offsetg < 0) *offsetg = -(*offsetg + 1); /* Convert to actual global offset for ghost vertex */ 8265f2c45f1SShri Abhyankar PetscFunctionReturn(0); 8275f2c45f1SShri Abhyankar } 8285f2c45f1SShri Abhyankar 82924121865SAdrian Maldonado /*@ 8309988b915SShri Abhyankar DMNetworkGetComponentVariableOffset - Get the offset for accessing the variable associated with a component for the given vertex/edge from the local vector. 8319988b915SShri Abhyankar 8329988b915SShri Abhyankar Not Collective 8339988b915SShri Abhyankar 8349988b915SShri Abhyankar Input Parameters: 8359988b915SShri Abhyankar + dm - The DMNetwork object 8367d928bffSSatish Balay . p - the edge/vertex point 8377d928bffSSatish Balay - compnum - component number 8389988b915SShri Abhyankar 8399988b915SShri Abhyankar Output Parameters: 8409988b915SShri Abhyankar . offset - the offset 8419988b915SShri Abhyankar 8429988b915SShri Abhyankar Level: intermediate 8439988b915SShri Abhyankar 8449dacc45bSShrirang Abhyankar .seealso: DMNetworkGetVariableGlobalOffset(), DMGetLocalVector(), DMNetworkSetComponentNumVariables() 8459988b915SShri Abhyankar @*/ 8469988b915SShri Abhyankar PetscErrorCode DMNetworkGetComponentVariableOffset(DM dm,PetscInt p,PetscInt compnum,PetscInt *offset) 8479988b915SShri Abhyankar { 8489988b915SShri Abhyankar PetscErrorCode ierr; 8499988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 8509988b915SShri Abhyankar PetscInt offsetp,offsetd; 8519988b915SShri Abhyankar DMNetworkComponentHeader header; 8529988b915SShri Abhyankar 8539988b915SShri Abhyankar PetscFunctionBegin; 8549988b915SShri Abhyankar ierr = DMNetworkGetVariableOffset(dm,p,&offsetp);CHKERRQ(ierr); 8559988b915SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetd);CHKERRQ(ierr); 8569988b915SShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetd); 8579988b915SShri Abhyankar *offset = offsetp + header->offsetvarrel[compnum]; 8589988b915SShri Abhyankar PetscFunctionReturn(0); 8599988b915SShri Abhyankar } 8609988b915SShri Abhyankar 8619988b915SShri Abhyankar /*@ 8629988b915SShri Abhyankar DMNetworkGetComponentVariableGlobalOffset - Get the global offset for accessing the variable associated with a component for the given vertex/edge from the local vector. 8639988b915SShri Abhyankar 8649988b915SShri Abhyankar Not Collective 8659988b915SShri Abhyankar 8669988b915SShri Abhyankar Input Parameters: 8679988b915SShri Abhyankar + dm - The DMNetwork object 8687d928bffSSatish Balay . p - the edge/vertex point 8697d928bffSSatish Balay - compnum - component number 8709988b915SShri Abhyankar 8719988b915SShri Abhyankar Output Parameters: 8729988b915SShri Abhyankar . offsetg - the global offset 8739988b915SShri Abhyankar 8749988b915SShri Abhyankar Level: intermediate 8759988b915SShri Abhyankar 8769dacc45bSShrirang Abhyankar .seealso: DMNetworkGetVariableGlobalOffset(), DMNetworkGetComponentVariableOffset(), DMGetLocalVector(), DMNetworkSetComponentNumVariables() 8779988b915SShri Abhyankar @*/ 8789988b915SShri Abhyankar PetscErrorCode DMNetworkGetComponentVariableGlobalOffset(DM dm,PetscInt p,PetscInt compnum,PetscInt *offsetg) 8799988b915SShri Abhyankar { 8809988b915SShri Abhyankar PetscErrorCode ierr; 8819988b915SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 8829988b915SShri Abhyankar PetscInt offsetp,offsetd; 8839988b915SShri Abhyankar DMNetworkComponentHeader header; 8849988b915SShri Abhyankar 8859988b915SShri Abhyankar PetscFunctionBegin; 8869988b915SShri Abhyankar ierr = DMNetworkGetVariableGlobalOffset(dm,p,&offsetp);CHKERRQ(ierr); 8879988b915SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetd);CHKERRQ(ierr); 8889988b915SShri Abhyankar header = (DMNetworkComponentHeader)(network->componentdataarray+offsetd); 8899988b915SShri Abhyankar *offsetg = offsetp + header->offsetvarrel[compnum]; 8909988b915SShri Abhyankar PetscFunctionReturn(0); 8919988b915SShri Abhyankar } 8929988b915SShri Abhyankar 8939988b915SShri Abhyankar /*@ 89424121865SAdrian Maldonado DMNetworkGetEdgeOffset - Get the offset for accessing the variable associated with the given edge from the local subvector. 89524121865SAdrian Maldonado 89624121865SAdrian Maldonado Not Collective 89724121865SAdrian Maldonado 89824121865SAdrian Maldonado Input Parameters: 89924121865SAdrian Maldonado + dm - The DMNetwork object 90024121865SAdrian Maldonado - p - the edge point 90124121865SAdrian Maldonado 90224121865SAdrian Maldonado Output Parameters: 90324121865SAdrian Maldonado . offset - the offset 90424121865SAdrian Maldonado 90524121865SAdrian Maldonado Level: intermediate 90624121865SAdrian Maldonado 90724121865SAdrian Maldonado .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 90824121865SAdrian Maldonado @*/ 90924121865SAdrian Maldonado PetscErrorCode DMNetworkGetEdgeOffset(DM dm,PetscInt p,PetscInt *offset) 91024121865SAdrian Maldonado { 91124121865SAdrian Maldonado PetscErrorCode ierr; 91224121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 91324121865SAdrian Maldonado 91424121865SAdrian Maldonado PetscFunctionBegin; 91524121865SAdrian Maldonado 91624121865SAdrian Maldonado ierr = PetscSectionGetOffset(network->edge.DofSection,p,offset);CHKERRQ(ierr); 91724121865SAdrian Maldonado PetscFunctionReturn(0); 91824121865SAdrian Maldonado } 91924121865SAdrian Maldonado 92024121865SAdrian Maldonado /*@ 92124121865SAdrian Maldonado DMNetworkGetVertexOffset - Get the offset for accessing the variable associated with the given vertex from the local subvector. 92224121865SAdrian Maldonado 92324121865SAdrian Maldonado Not Collective 92424121865SAdrian Maldonado 92524121865SAdrian Maldonado Input Parameters: 92624121865SAdrian Maldonado + dm - The DMNetwork object 92724121865SAdrian Maldonado - p - the vertex point 92824121865SAdrian Maldonado 92924121865SAdrian Maldonado Output Parameters: 93024121865SAdrian Maldonado . offset - the offset 93124121865SAdrian Maldonado 93224121865SAdrian Maldonado Level: intermediate 93324121865SAdrian Maldonado 93424121865SAdrian Maldonado .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector 93524121865SAdrian Maldonado @*/ 93624121865SAdrian Maldonado PetscErrorCode DMNetworkGetVertexOffset(DM dm,PetscInt p,PetscInt *offset) 93724121865SAdrian Maldonado { 93824121865SAdrian Maldonado PetscErrorCode ierr; 93924121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 94024121865SAdrian Maldonado 94124121865SAdrian Maldonado PetscFunctionBegin; 94224121865SAdrian Maldonado 94324121865SAdrian Maldonado p -= network->vStart; 94424121865SAdrian Maldonado 94524121865SAdrian Maldonado ierr = PetscSectionGetOffset(network->vertex.DofSection,p,offset);CHKERRQ(ierr); 94624121865SAdrian Maldonado PetscFunctionReturn(0); 94724121865SAdrian Maldonado } 9485f2c45f1SShri Abhyankar /*@ 9495f2c45f1SShri Abhyankar DMNetworkAddNumVariables - Add number of variables associated with a given point. 9505f2c45f1SShri Abhyankar 9515f2c45f1SShri Abhyankar Not Collective 9525f2c45f1SShri Abhyankar 9535f2c45f1SShri Abhyankar Input Parameters: 9545f2c45f1SShri Abhyankar + dm - The DMNetworkObject 9555f2c45f1SShri Abhyankar . p - the vertex/edge point 9565f2c45f1SShri Abhyankar - nvar - number of additional variables 9575f2c45f1SShri Abhyankar 95897bb938eSShri Abhyankar Level: beginner 9595f2c45f1SShri Abhyankar 9605f2c45f1SShri Abhyankar .seealso: DMNetworkSetNumVariables 9615f2c45f1SShri Abhyankar @*/ 9625f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddNumVariables(DM dm,PetscInt p,PetscInt nvar) 9635f2c45f1SShri Abhyankar { 9645f2c45f1SShri Abhyankar PetscErrorCode ierr; 9655f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 9665f2c45f1SShri Abhyankar 9675f2c45f1SShri Abhyankar PetscFunctionBegin; 9685f2c45f1SShri Abhyankar ierr = PetscSectionAddDof(network->DofSection,p,nvar);CHKERRQ(ierr); 9695f2c45f1SShri Abhyankar PetscFunctionReturn(0); 9705f2c45f1SShri Abhyankar } 9715f2c45f1SShri Abhyankar 97227f51fceSHong Zhang /*@ 97327f51fceSHong Zhang DMNetworkGetNumVariables - Gets number of variables for a vertex/edge point. 97427f51fceSHong Zhang 97527f51fceSHong Zhang Not Collective 97627f51fceSHong Zhang 97727f51fceSHong Zhang Input Parameters: 97827f51fceSHong Zhang + dm - The DMNetworkObject 97927f51fceSHong Zhang - p - the vertex/edge point 98027f51fceSHong Zhang 98127f51fceSHong Zhang Output Parameters: 98227f51fceSHong Zhang . nvar - number of variables 98327f51fceSHong Zhang 98497bb938eSShri Abhyankar Level: beginner 98527f51fceSHong Zhang 98627f51fceSHong Zhang .seealso: DMNetworkAddNumVariables, DMNetworkSddNumVariables 98727f51fceSHong Zhang @*/ 98827f51fceSHong Zhang PetscErrorCode DMNetworkGetNumVariables(DM dm,PetscInt p,PetscInt *nvar) 98927f51fceSHong Zhang { 99027f51fceSHong Zhang PetscErrorCode ierr; 99127f51fceSHong Zhang DM_Network *network = (DM_Network*)dm->data; 99227f51fceSHong Zhang 99327f51fceSHong Zhang PetscFunctionBegin; 99427f51fceSHong Zhang ierr = PetscSectionGetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 99527f51fceSHong Zhang PetscFunctionReturn(0); 99627f51fceSHong Zhang } 99727f51fceSHong Zhang 9985f2c45f1SShri Abhyankar /*@ 9995f2c45f1SShri Abhyankar DMNetworkSetNumVariables - Sets number of variables for a vertex/edge point. 10005f2c45f1SShri Abhyankar 10015f2c45f1SShri Abhyankar Not Collective 10025f2c45f1SShri Abhyankar 10035f2c45f1SShri Abhyankar Input Parameters: 10045f2c45f1SShri Abhyankar + dm - The DMNetworkObject 10055f2c45f1SShri Abhyankar . p - the vertex/edge point 10065f2c45f1SShri Abhyankar - nvar - number of variables 10075f2c45f1SShri Abhyankar 100897bb938eSShri Abhyankar Level: beginner 10095f2c45f1SShri Abhyankar 10105f2c45f1SShri Abhyankar .seealso: DMNetworkAddNumVariables 10115f2c45f1SShri Abhyankar @*/ 10125f2c45f1SShri Abhyankar PetscErrorCode DMNetworkSetNumVariables(DM dm,PetscInt p,PetscInt nvar) 10135f2c45f1SShri Abhyankar { 10145f2c45f1SShri Abhyankar PetscErrorCode ierr; 10155f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 10165f2c45f1SShri Abhyankar 10175f2c45f1SShri Abhyankar PetscFunctionBegin; 10185f2c45f1SShri Abhyankar ierr = PetscSectionSetDof(network->DofSection,p,nvar);CHKERRQ(ierr); 10195f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10205f2c45f1SShri Abhyankar } 10215f2c45f1SShri Abhyankar 10225f2c45f1SShri Abhyankar /* Sets up the array that holds the data for all components and its associated section. This 10235f2c45f1SShri Abhyankar function is called during DMSetUp() */ 10245f2c45f1SShri Abhyankar PetscErrorCode DMNetworkComponentSetUp(DM dm) 10255f2c45f1SShri Abhyankar { 10265f2c45f1SShri Abhyankar PetscErrorCode ierr; 10275f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 1028e53b5ba3SHong Zhang PetscInt arr_size,p,offset,offsetp,ncomp,i; 10295f2c45f1SShri Abhyankar DMNetworkComponentHeader header; 10305f2c45f1SShri Abhyankar DMNetworkComponentValue cvalue; 10315f2c45f1SShri Abhyankar DMNetworkComponentGenericDataType *componentdataarray; 10325f2c45f1SShri Abhyankar 10335f2c45f1SShri Abhyankar PetscFunctionBegin; 10345f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DataSection);CHKERRQ(ierr); 10355f2c45f1SShri Abhyankar ierr = PetscSectionGetStorageSize(network->DataSection,&arr_size);CHKERRQ(ierr); 103675b160a0SShri Abhyankar ierr = PetscMalloc1(arr_size,&network->componentdataarray);CHKERRQ(ierr); 10375f2c45f1SShri Abhyankar componentdataarray = network->componentdataarray; 10385f2c45f1SShri Abhyankar for (p = network->pStart; p < network->pEnd; p++) { 10395f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr); 10405f2c45f1SShri Abhyankar /* Copy header */ 10415f2c45f1SShri Abhyankar header = &network->header[p]; 1042302440fdSBarry Smith ierr = PetscMemcpy(componentdataarray+offsetp,header,network->dataheadersize*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 10435f2c45f1SShri Abhyankar /* Copy data */ 10445f2c45f1SShri Abhyankar cvalue = &network->cvalue[p]; 10455f2c45f1SShri Abhyankar ncomp = header->ndata; 10465f2c45f1SShri Abhyankar for (i = 0; i < ncomp; i++) { 10475f2c45f1SShri Abhyankar offset = offsetp + network->dataheadersize + header->offset[i]; 1048302440fdSBarry Smith ierr = PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr); 10495f2c45f1SShri Abhyankar } 10505f2c45f1SShri Abhyankar } 10515f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10525f2c45f1SShri Abhyankar } 10535f2c45f1SShri Abhyankar 10545f2c45f1SShri Abhyankar /* Sets up the section for dofs. This routine is called during DMSetUp() */ 10555f2c45f1SShri Abhyankar PetscErrorCode DMNetworkVariablesSetUp(DM dm) 10565f2c45f1SShri Abhyankar { 10575f2c45f1SShri Abhyankar PetscErrorCode ierr; 10585f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 10595f2c45f1SShri Abhyankar 10605f2c45f1SShri Abhyankar PetscFunctionBegin; 10615f2c45f1SShri Abhyankar ierr = PetscSectionSetUp(network->DofSection);CHKERRQ(ierr); 10625f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10635f2c45f1SShri Abhyankar } 10645f2c45f1SShri Abhyankar 106597bb938eSShri Abhyankar /* 10665f2c45f1SShri Abhyankar DMNetworkGetComponentDataArray - Returns the component data array 10675f2c45f1SShri Abhyankar 10685f2c45f1SShri Abhyankar Not Collective 10695f2c45f1SShri Abhyankar 10705f2c45f1SShri Abhyankar Input Parameters: 10715f2c45f1SShri Abhyankar . dm - The DMNetwork Object 10725f2c45f1SShri Abhyankar 10735f2c45f1SShri Abhyankar Output Parameters: 10745f2c45f1SShri Abhyankar . componentdataarray - array that holds data for all components 10755f2c45f1SShri Abhyankar 10765f2c45f1SShri Abhyankar Level: intermediate 10775f2c45f1SShri Abhyankar 1078a730d845SHong Zhang .seealso: DMNetworkGetComponentKeyOffset, DMNetworkGetNumComponents 107997bb938eSShri Abhyankar */ 10805f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetComponentDataArray(DM dm,DMNetworkComponentGenericDataType **componentdataarray) 10815f2c45f1SShri Abhyankar { 10825f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 10835f2c45f1SShri Abhyankar 10845f2c45f1SShri Abhyankar PetscFunctionBegin; 10855f2c45f1SShri Abhyankar *componentdataarray = network->componentdataarray; 10865f2c45f1SShri Abhyankar PetscFunctionReturn(0); 10875f2c45f1SShri Abhyankar } 10885f2c45f1SShri Abhyankar 108924121865SAdrian Maldonado /* Get a subsection from a range of points */ 109024121865SAdrian Maldonado PetscErrorCode DMNetworkGetSubSection_private(PetscSection master, PetscInt pstart, PetscInt pend,PetscSection *subsection) 109124121865SAdrian Maldonado { 109224121865SAdrian Maldonado PetscErrorCode ierr; 109324121865SAdrian Maldonado PetscInt i, nvar; 109424121865SAdrian Maldonado 109524121865SAdrian Maldonado PetscFunctionBegin; 109624121865SAdrian Maldonado ierr = PetscSectionCreate(PetscObjectComm((PetscObject)master), subsection);CHKERRQ(ierr); 109724121865SAdrian Maldonado ierr = PetscSectionSetChart(*subsection, 0, pend - pstart);CHKERRQ(ierr); 109824121865SAdrian Maldonado for (i = pstart; i < pend; i++) { 109924121865SAdrian Maldonado ierr = PetscSectionGetDof(master,i,&nvar);CHKERRQ(ierr); 110024121865SAdrian Maldonado ierr = PetscSectionSetDof(*subsection, i - pstart, nvar);CHKERRQ(ierr); 110124121865SAdrian Maldonado } 110224121865SAdrian Maldonado 110324121865SAdrian Maldonado ierr = PetscSectionSetUp(*subsection);CHKERRQ(ierr); 110424121865SAdrian Maldonado PetscFunctionReturn(0); 110524121865SAdrian Maldonado } 110624121865SAdrian Maldonado 110724121865SAdrian Maldonado /* Create a submap of points with a GlobalToLocal structure */ 110824121865SAdrian Maldonado PetscErrorCode DMNetworkSetSubMap_private(PetscInt pstart, PetscInt pend, ISLocalToGlobalMapping *map) 110924121865SAdrian Maldonado { 111024121865SAdrian Maldonado PetscErrorCode ierr; 111124121865SAdrian Maldonado PetscInt i, *subpoints; 111224121865SAdrian Maldonado 111324121865SAdrian Maldonado PetscFunctionBegin; 111424121865SAdrian Maldonado /* Create index sets to map from "points" to "subpoints" */ 111524121865SAdrian Maldonado ierr = PetscMalloc1(pend - pstart, &subpoints);CHKERRQ(ierr); 111624121865SAdrian Maldonado for (i = pstart; i < pend; i++) { 111724121865SAdrian Maldonado subpoints[i - pstart] = i; 111824121865SAdrian Maldonado } 1119459726d8SSatish Balay ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,pend-pstart,subpoints,PETSC_COPY_VALUES,map);CHKERRQ(ierr); 112024121865SAdrian Maldonado ierr = PetscFree(subpoints);CHKERRQ(ierr); 112124121865SAdrian Maldonado PetscFunctionReturn(0); 112224121865SAdrian Maldonado } 112324121865SAdrian Maldonado 112424121865SAdrian Maldonado /*@ 112524121865SAdrian Maldonado DMNetworkAssembleGraphStructures - Assembles vertex and edge data structures. Must be called after DMNetworkDistribute. 112624121865SAdrian Maldonado 112724121865SAdrian Maldonado Collective 112824121865SAdrian Maldonado 112924121865SAdrian Maldonado Input Parameters: 113024121865SAdrian Maldonado . dm - The DMNetworkObject 113124121865SAdrian Maldonado 113224121865SAdrian Maldonado Note: the routine will create alternative orderings for the vertices and edges. Assume global network points are: 113324121865SAdrian Maldonado 113424121865SAdrian Maldonado points = [0 1 2 3 4 5 6] 113524121865SAdrian Maldonado 1136caf410d2SHong 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]). 113724121865SAdrian Maldonado 113824121865SAdrian Maldonado With this new ordering a local PetscSection, global PetscSection and PetscSF will be created specific to the subset. 113924121865SAdrian Maldonado 114024121865SAdrian Maldonado Level: intermediate 114124121865SAdrian Maldonado 114224121865SAdrian Maldonado @*/ 114324121865SAdrian Maldonado PetscErrorCode DMNetworkAssembleGraphStructures(DM dm) 114424121865SAdrian Maldonado { 114524121865SAdrian Maldonado PetscErrorCode ierr; 114624121865SAdrian Maldonado MPI_Comm comm; 11479852e123SBarry Smith PetscMPIInt rank, size; 114824121865SAdrian Maldonado DM_Network *network = (DM_Network*)dm->data; 114924121865SAdrian Maldonado 1150eab1376dSHong Zhang PetscFunctionBegin; 115124121865SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 115224121865SAdrian Maldonado ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 11539852e123SBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 115424121865SAdrian Maldonado 115524121865SAdrian Maldonado /* Create maps for vertices and edges */ 115624121865SAdrian Maldonado ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 115724121865SAdrian Maldonado ierr = DMNetworkSetSubMap_private(network->eStart,network->eEnd,&network->edge.mapping);CHKERRQ(ierr); 115824121865SAdrian Maldonado 115924121865SAdrian Maldonado /* Create local sub-sections */ 116024121865SAdrian Maldonado ierr = DMNetworkGetSubSection_private(network->DofSection,network->vStart,network->vEnd,&network->vertex.DofSection);CHKERRQ(ierr); 116124121865SAdrian Maldonado ierr = DMNetworkGetSubSection_private(network->DofSection,network->eStart,network->eEnd,&network->edge.DofSection);CHKERRQ(ierr); 116224121865SAdrian Maldonado 11639852e123SBarry Smith if (size > 1) { 116424121865SAdrian Maldonado ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 116522bbedd7SHong Zhang 116624121865SAdrian Maldonado ierr = PetscSectionCreateGlobalSection(network->vertex.DofSection, network->vertex.sf, PETSC_FALSE, PETSC_FALSE, &network->vertex.GlobalDofSection);CHKERRQ(ierr); 116724121865SAdrian Maldonado ierr = PetscSFGetSubSF(network->plex->sf, network->edge.mapping, &network->edge.sf);CHKERRQ(ierr); 116824121865SAdrian Maldonado ierr = PetscSectionCreateGlobalSection(network->edge.DofSection, network->edge.sf, PETSC_FALSE, PETSC_FALSE, &network->edge.GlobalDofSection);CHKERRQ(ierr); 116924121865SAdrian Maldonado } else { 117024121865SAdrian Maldonado /* create structures for vertex */ 117124121865SAdrian Maldonado ierr = PetscSectionClone(network->vertex.DofSection,&network->vertex.GlobalDofSection);CHKERRQ(ierr); 117224121865SAdrian Maldonado /* create structures for edge */ 117324121865SAdrian Maldonado ierr = PetscSectionClone(network->edge.DofSection,&network->edge.GlobalDofSection);CHKERRQ(ierr); 117424121865SAdrian Maldonado } 117524121865SAdrian Maldonado 117624121865SAdrian Maldonado /* Add viewers */ 117724121865SAdrian Maldonado ierr = PetscObjectSetName((PetscObject)network->edge.GlobalDofSection,"Global edge dof section");CHKERRQ(ierr); 117824121865SAdrian Maldonado ierr = PetscObjectSetName((PetscObject)network->vertex.GlobalDofSection,"Global vertex dof section");CHKERRQ(ierr); 117924121865SAdrian Maldonado ierr = PetscSectionViewFromOptions(network->edge.GlobalDofSection, NULL, "-edge_global_section_view");CHKERRQ(ierr); 118024121865SAdrian Maldonado ierr = PetscSectionViewFromOptions(network->vertex.GlobalDofSection, NULL, "-vertex_global_section_view");CHKERRQ(ierr); 118124121865SAdrian Maldonado PetscFunctionReturn(0); 118224121865SAdrian Maldonado } 11837b6afd5bSHong Zhang 11845f2c45f1SShri Abhyankar /*@ 11855f2c45f1SShri Abhyankar DMNetworkDistribute - Distributes the network and moves associated component data. 11865f2c45f1SShri Abhyankar 11875f2c45f1SShri Abhyankar Collective 11885f2c45f1SShri Abhyankar 11895f2c45f1SShri Abhyankar Input Parameter: 1190d3464fd4SAdrian Maldonado + DM - the DMNetwork object 11915f2c45f1SShri Abhyankar - overlap - The overlap of partitions, 0 is the default 11925f2c45f1SShri Abhyankar 11935f2c45f1SShri Abhyankar Notes: 11948b171c8eSHong Zhang Distributes the network with <overlap>-overlapping partitioning of the edges. 11955f2c45f1SShri Abhyankar 11965f2c45f1SShri Abhyankar Level: intermediate 11975f2c45f1SShri Abhyankar 11985f2c45f1SShri Abhyankar .seealso: DMNetworkCreate 11995f2c45f1SShri Abhyankar @*/ 1200d3464fd4SAdrian Maldonado PetscErrorCode DMNetworkDistribute(DM *dm,PetscInt overlap) 12015f2c45f1SShri Abhyankar { 1202d3464fd4SAdrian Maldonado MPI_Comm comm; 12035f2c45f1SShri Abhyankar PetscErrorCode ierr; 1204d3464fd4SAdrian Maldonado PetscMPIInt size; 1205d3464fd4SAdrian Maldonado DM_Network *oldDMnetwork = (DM_Network*)((*dm)->data); 1206d3464fd4SAdrian Maldonado DM_Network *newDMnetwork; 1207caf410d2SHong Zhang PetscSF pointsf=NULL; 12085f2c45f1SShri Abhyankar DM newDM; 1209caf410d2SHong Zhang PetscInt j,e,v,offset,*subnetvtx; 121051ac5effSHong Zhang PetscPartitioner part; 1211b9c6e19dSShri Abhyankar DMNetworkComponentHeader header; 12125f2c45f1SShri Abhyankar 12135f2c45f1SShri Abhyankar PetscFunctionBegin; 1214d3464fd4SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)*dm,&comm);CHKERRQ(ierr); 1215d3464fd4SAdrian Maldonado ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 1216d3464fd4SAdrian Maldonado if (size == 1) PetscFunctionReturn(0); 1217d3464fd4SAdrian Maldonado 1218d3464fd4SAdrian Maldonado ierr = DMNetworkCreate(PetscObjectComm((PetscObject)*dm),&newDM);CHKERRQ(ierr); 12195f2c45f1SShri Abhyankar newDMnetwork = (DM_Network*)newDM->data; 12205f2c45f1SShri Abhyankar newDMnetwork->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType); 122151ac5effSHong Zhang 122251ac5effSHong Zhang /* Enable runtime options for petscpartitioner */ 122351ac5effSHong Zhang ierr = DMPlexGetPartitioner(oldDMnetwork->plex,&part);CHKERRQ(ierr); 122451ac5effSHong Zhang ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr); 122551ac5effSHong Zhang 12265f2c45f1SShri Abhyankar /* Distribute plex dm and dof section */ 122780cf41d5SMatthew G. Knepley ierr = DMPlexDistribute(oldDMnetwork->plex,overlap,&pointsf,&newDMnetwork->plex);CHKERRQ(ierr); 122851ac5effSHong Zhang 12295f2c45f1SShri Abhyankar /* Distribute dof section */ 1230d3464fd4SAdrian Maldonado ierr = PetscSectionCreate(PetscObjectComm((PetscObject)*dm),&newDMnetwork->DofSection);CHKERRQ(ierr); 12315f2c45f1SShri Abhyankar ierr = PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);CHKERRQ(ierr); 1232d3464fd4SAdrian Maldonado ierr = PetscSectionCreate(PetscObjectComm((PetscObject)*dm),&newDMnetwork->DataSection);CHKERRQ(ierr); 123351ac5effSHong Zhang 12345f2c45f1SShri Abhyankar /* Distribute data and associated section */ 123531da1fc8SHong Zhang ierr = DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPIU_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);CHKERRQ(ierr); 123624121865SAdrian Maldonado 12375f2c45f1SShri Abhyankar ierr = PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);CHKERRQ(ierr); 12385f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);CHKERRQ(ierr); 12395f2c45f1SShri Abhyankar ierr = DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);CHKERRQ(ierr); 12405f2c45f1SShri Abhyankar newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart; 12416fefedf4SHong Zhang newDMnetwork->nVertices = newDMnetwork->vEnd - newDMnetwork->vStart; 12426fefedf4SHong Zhang newDMnetwork->NVertices = oldDMnetwork->NVertices; 12435f2c45f1SShri Abhyankar newDMnetwork->NEdges = oldDMnetwork->NEdges; 124424121865SAdrian Maldonado 12451bb6d2a8SBarry Smith /* Set Dof section as the section for dm */ 124692fd8e1eSJed Brown ierr = DMSetLocalSection(newDMnetwork->plex,newDMnetwork->DofSection);CHKERRQ(ierr); 1247e87a4003SBarry Smith ierr = DMGetGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);CHKERRQ(ierr); 12485f2c45f1SShri Abhyankar 1249b9c6e19dSShri Abhyankar /* Set up subnetwork info in the newDM */ 1250b9c6e19dSShri Abhyankar newDMnetwork->nsubnet = oldDMnetwork->nsubnet; 1251caf410d2SHong Zhang newDMnetwork->ncsubnet = oldDMnetwork->ncsubnet; 1252b9c6e19dSShri Abhyankar ierr = PetscCalloc1(newDMnetwork->nsubnet,&newDMnetwork->subnet);CHKERRQ(ierr); 1253b9c6e19dSShri Abhyankar /* Copy over the global number of vertices and edges in each subnetwork. Note that these are already 1254b9c6e19dSShri Abhyankar calculated in DMNetworkLayoutSetUp() 1255b9c6e19dSShri Abhyankar */ 1256b9c6e19dSShri Abhyankar for(j=0; j < newDMnetwork->nsubnet; j++) { 1257b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].Nvtx = oldDMnetwork->subnet[j].Nvtx; 1258b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].Nedge = oldDMnetwork->subnet[j].Nedge; 1259b9c6e19dSShri Abhyankar } 1260b9c6e19dSShri Abhyankar 1261b9c6e19dSShri Abhyankar for (e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++ ) { 1262b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr); 1263b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1264b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].nedge++; 1265b9c6e19dSShri Abhyankar } 1266b9c6e19dSShri Abhyankar 1267b9c6e19dSShri Abhyankar for (v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++ ) { 1268b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr); 1269b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1270b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].nvtx++; 1271b9c6e19dSShri Abhyankar } 1272b9c6e19dSShri Abhyankar 1273b9c6e19dSShri Abhyankar /* Now create the vertices and edge arrays for the subnetworks */ 1274caf410d2SHong Zhang ierr = PetscCalloc1(newDMnetwork->vEnd-newDMnetwork->vStart,&newDMnetwork->subnetvtx);CHKERRQ(ierr); 1275caf410d2SHong Zhang subnetvtx = newDMnetwork->subnetvtx; 1276caf410d2SHong Zhang 1277b9c6e19dSShri Abhyankar for (j=0; j<newDMnetwork->nsubnet; j++) { 1278b9c6e19dSShri Abhyankar ierr = PetscCalloc1(newDMnetwork->subnet[j].nedge,&newDMnetwork->subnet[j].edges);CHKERRQ(ierr); 1279caf410d2SHong Zhang newDMnetwork->subnet[j].vertices = subnetvtx; 1280caf410d2SHong Zhang subnetvtx += newDMnetwork->subnet[j].nvtx; 1281caf410d2SHong Zhang 1282b9c6e19dSShri Abhyankar /* Temporarily setting nvtx and nedge to 0 so we can use them as counters in the below for loop. 1283b9c6e19dSShri Abhyankar These get updated when the vertices and edges are added. */ 1284b9c6e19dSShri Abhyankar newDMnetwork->subnet[j].nvtx = newDMnetwork->subnet[j].nedge = 0; 1285b9c6e19dSShri Abhyankar } 1286b9c6e19dSShri Abhyankar 1287b9c6e19dSShri Abhyankar /* Set the vertices and edges in each subnetwork */ 1288b9c6e19dSShri Abhyankar for (e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++ ) { 1289b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr); 1290b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1291b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].edges[newDMnetwork->subnet[header->subnetid].nedge++] = e; 1292b9c6e19dSShri Abhyankar } 1293b9c6e19dSShri Abhyankar 1294b9c6e19dSShri Abhyankar for (v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++ ) { 1295b9c6e19dSShri Abhyankar ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr); 1296b9c6e19dSShri Abhyankar header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr); 1297b9c6e19dSShri Abhyankar newDMnetwork->subnet[header->subnetid].vertices[newDMnetwork->subnet[header->subnetid].nvtx++] = v; 1298b9c6e19dSShri Abhyankar } 1299b9c6e19dSShri Abhyankar 1300caf410d2SHong Zhang newDM->setupcalled = (*dm)->setupcalled; 130122bbedd7SHong Zhang newDMnetwork->distributecalled = PETSC_TRUE; 1302caf410d2SHong Zhang 130324121865SAdrian Maldonado /* Destroy point SF */ 130424121865SAdrian Maldonado ierr = PetscSFDestroy(&pointsf);CHKERRQ(ierr); 130524121865SAdrian Maldonado 1306d3464fd4SAdrian Maldonado ierr = DMDestroy(dm);CHKERRQ(ierr); 1307d3464fd4SAdrian Maldonado *dm = newDM; 13085f2c45f1SShri Abhyankar PetscFunctionReturn(0); 13095f2c45f1SShri Abhyankar } 13105f2c45f1SShri Abhyankar 131124121865SAdrian Maldonado /*@C 131224121865SAdrian Maldonado PetscSFGetSubSF - Returns an SF for a specific subset of points. Leaves are re-numbered to reflect the new ordering. 131324121865SAdrian Maldonado 131424121865SAdrian Maldonado Input Parameters: 131524121865SAdrian Maldonado + masterSF - the original SF structure 131624121865SAdrian Maldonado - map - a ISLocalToGlobal mapping that contains the subset of points 131724121865SAdrian Maldonado 131824121865SAdrian Maldonado Output Parameters: 131924121865SAdrian Maldonado . subSF - a subset of the masterSF for the desired subset. 13207d928bffSSatish Balay @*/ 132124121865SAdrian Maldonado PetscErrorCode PetscSFGetSubSF(PetscSF mastersf, ISLocalToGlobalMapping map, PetscSF *subSF) { 132224121865SAdrian Maldonado 132324121865SAdrian Maldonado PetscErrorCode ierr; 132424121865SAdrian Maldonado PetscInt nroots, nleaves, *ilocal_sub; 132524121865SAdrian Maldonado PetscInt i, *ilocal_map, nroots_sub, nleaves_sub = 0; 132624121865SAdrian Maldonado PetscInt *local_points, *remote_points; 132724121865SAdrian Maldonado PetscSFNode *iremote_sub; 132824121865SAdrian Maldonado const PetscInt *ilocal; 132924121865SAdrian Maldonado const PetscSFNode *iremote; 133024121865SAdrian Maldonado 133124121865SAdrian Maldonado PetscFunctionBegin; 133224121865SAdrian Maldonado ierr = PetscSFGetGraph(mastersf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr); 133324121865SAdrian Maldonado 133424121865SAdrian Maldonado /* Look for leaves that pertain to the subset of points. Get the local ordering */ 133524121865SAdrian Maldonado ierr = PetscMalloc1(nleaves,&ilocal_map);CHKERRQ(ierr); 133624121865SAdrian Maldonado ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nleaves,ilocal,NULL,ilocal_map);CHKERRQ(ierr); 133724121865SAdrian Maldonado for (i = 0; i < nleaves; i++) { 133824121865SAdrian Maldonado if (ilocal_map[i] != -1) nleaves_sub += 1; 133924121865SAdrian Maldonado } 134024121865SAdrian Maldonado /* Re-number ilocal with subset numbering. Need information from roots */ 134124121865SAdrian Maldonado ierr = PetscMalloc2(nroots,&local_points,nroots,&remote_points);CHKERRQ(ierr); 134224121865SAdrian Maldonado for (i = 0; i < nroots; i++) local_points[i] = i; 134324121865SAdrian Maldonado ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nroots,local_points,NULL,local_points);CHKERRQ(ierr); 134424121865SAdrian Maldonado ierr = PetscSFBcastBegin(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr); 134524121865SAdrian Maldonado ierr = PetscSFBcastEnd(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr); 134624121865SAdrian Maldonado /* Fill up graph using local (that is, local to the subset) numbering. */ 13474b70a8deSAdrian Maldonado ierr = PetscMalloc1(nleaves_sub,&ilocal_sub);CHKERRQ(ierr); 13484b70a8deSAdrian Maldonado ierr = PetscMalloc1(nleaves_sub,&iremote_sub);CHKERRQ(ierr); 134924121865SAdrian Maldonado nleaves_sub = 0; 135024121865SAdrian Maldonado for (i = 0; i < nleaves; i++) { 135124121865SAdrian Maldonado if (ilocal_map[i] != -1) { 135224121865SAdrian Maldonado ilocal_sub[nleaves_sub] = ilocal_map[i]; 13534b70a8deSAdrian Maldonado iremote_sub[nleaves_sub].rank = iremote[i].rank; 135424121865SAdrian Maldonado iremote_sub[nleaves_sub].index = remote_points[ilocal[i]]; 135524121865SAdrian Maldonado nleaves_sub += 1; 135624121865SAdrian Maldonado } 135724121865SAdrian Maldonado } 135824121865SAdrian Maldonado ierr = PetscFree2(local_points,remote_points);CHKERRQ(ierr); 135924121865SAdrian Maldonado ierr = ISLocalToGlobalMappingGetSize(map,&nroots_sub);CHKERRQ(ierr); 136024121865SAdrian Maldonado 136124121865SAdrian Maldonado /* Create new subSF */ 136224121865SAdrian Maldonado ierr = PetscSFCreate(PETSC_COMM_WORLD,subSF);CHKERRQ(ierr); 136324121865SAdrian Maldonado ierr = PetscSFSetFromOptions(*subSF);CHKERRQ(ierr); 13644b70a8deSAdrian Maldonado ierr = PetscSFSetGraph(*subSF,nroots_sub,nleaves_sub,ilocal_sub,PETSC_OWN_POINTER,iremote_sub,PETSC_COPY_VALUES);CHKERRQ(ierr); 136524121865SAdrian Maldonado ierr = PetscFree(ilocal_map);CHKERRQ(ierr); 13664b70a8deSAdrian Maldonado ierr = PetscFree(iremote_sub);CHKERRQ(ierr); 136724121865SAdrian Maldonado PetscFunctionReturn(0); 136824121865SAdrian Maldonado } 136924121865SAdrian Maldonado 13705f2c45f1SShri Abhyankar /*@C 13715f2c45f1SShri Abhyankar DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point 13725f2c45f1SShri Abhyankar 13735f2c45f1SShri Abhyankar Not Collective 13745f2c45f1SShri Abhyankar 13755f2c45f1SShri Abhyankar Input Parameters: 13765f2c45f1SShri Abhyankar + dm - The DMNetwork object 13775f2c45f1SShri Abhyankar - p - the vertex point 13785f2c45f1SShri Abhyankar 1379fd292e60Sprj- Output Parameters: 13805f2c45f1SShri Abhyankar + nedges - number of edges connected to this vertex point 13815f2c45f1SShri Abhyankar - edges - List of edge points 13825f2c45f1SShri Abhyankar 138397bb938eSShri Abhyankar Level: beginner 13845f2c45f1SShri Abhyankar 13855f2c45f1SShri Abhyankar Fortran Notes: 13865f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 13875f2c45f1SShri Abhyankar include petsc.h90 in your code. 13885f2c45f1SShri Abhyankar 1389d842c372SHong Zhang .seealso: DMNetworkCreate, DMNetworkGetConnectedVertices 13905f2c45f1SShri Abhyankar @*/ 13915f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[]) 13925f2c45f1SShri Abhyankar { 13935f2c45f1SShri Abhyankar PetscErrorCode ierr; 13945f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 13955f2c45f1SShri Abhyankar 13965f2c45f1SShri Abhyankar PetscFunctionBegin; 13975f2c45f1SShri Abhyankar ierr = DMPlexGetSupportSize(network->plex,vertex,nedges);CHKERRQ(ierr); 13985f2c45f1SShri Abhyankar ierr = DMPlexGetSupport(network->plex,vertex,edges);CHKERRQ(ierr); 13995f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14005f2c45f1SShri Abhyankar } 14015f2c45f1SShri Abhyankar 14025f2c45f1SShri Abhyankar /*@C 1403d842c372SHong Zhang DMNetworkGetConnectedVertices - Return the connected vertices for this edge point 14045f2c45f1SShri Abhyankar 14055f2c45f1SShri Abhyankar Not Collective 14065f2c45f1SShri Abhyankar 14075f2c45f1SShri Abhyankar Input Parameters: 14085f2c45f1SShri Abhyankar + dm - The DMNetwork object 14095f2c45f1SShri Abhyankar - p - the edge point 14105f2c45f1SShri Abhyankar 1411fd292e60Sprj- Output Parameters: 14125f2c45f1SShri Abhyankar . vertices - vertices connected to this edge 14135f2c45f1SShri Abhyankar 141497bb938eSShri Abhyankar Level: beginner 14155f2c45f1SShri Abhyankar 14165f2c45f1SShri Abhyankar Fortran Notes: 14175f2c45f1SShri Abhyankar Since it returns an array, this routine is only available in Fortran 90, and you must 14185f2c45f1SShri Abhyankar include petsc.h90 in your code. 14195f2c45f1SShri Abhyankar 14205f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkGetSupportingEdges 14215f2c45f1SShri Abhyankar @*/ 1422d842c372SHong Zhang PetscErrorCode DMNetworkGetConnectedVertices(DM dm,PetscInt edge,const PetscInt *vertices[]) 14235f2c45f1SShri Abhyankar { 14245f2c45f1SShri Abhyankar PetscErrorCode ierr; 14255f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 14265f2c45f1SShri Abhyankar 14275f2c45f1SShri Abhyankar PetscFunctionBegin; 14285f2c45f1SShri Abhyankar ierr = DMPlexGetCone(network->plex,edge,vertices);CHKERRQ(ierr); 14295f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14305f2c45f1SShri Abhyankar } 14315f2c45f1SShri Abhyankar 14325f2c45f1SShri Abhyankar /*@ 14335f2c45f1SShri Abhyankar DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex 14345f2c45f1SShri Abhyankar 14355f2c45f1SShri Abhyankar Not Collective 14365f2c45f1SShri Abhyankar 14375f2c45f1SShri Abhyankar Input Parameters: 14385f2c45f1SShri Abhyankar + dm - The DMNetwork object 1439a2b725a8SWilliam Gropp - p - the vertex point 14405f2c45f1SShri Abhyankar 14415f2c45f1SShri Abhyankar Output Parameter: 14425f2c45f1SShri Abhyankar . isghost - TRUE if the vertex is a ghost point 14435f2c45f1SShri Abhyankar 144497bb938eSShri Abhyankar Level: beginner 14455f2c45f1SShri Abhyankar 1446d842c372SHong Zhang .seealso: DMNetworkCreate, DMNetworkGetConnectedVertices, DMNetworkGetVertexRange 14475f2c45f1SShri Abhyankar @*/ 14485f2c45f1SShri Abhyankar PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost) 14495f2c45f1SShri Abhyankar { 14505f2c45f1SShri Abhyankar PetscErrorCode ierr; 14515f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 14525f2c45f1SShri Abhyankar PetscInt offsetg; 14535f2c45f1SShri Abhyankar PetscSection sectiong; 14545f2c45f1SShri Abhyankar 14555f2c45f1SShri Abhyankar PetscFunctionBegin; 1456caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 14575f2c45f1SShri Abhyankar *isghost = PETSC_FALSE; 1458e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,§iong);CHKERRQ(ierr); 14595f2c45f1SShri Abhyankar ierr = PetscSectionGetOffset(sectiong,p,&offsetg);CHKERRQ(ierr); 14605f2c45f1SShri Abhyankar if (offsetg < 0) *isghost = PETSC_TRUE; 14615f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14625f2c45f1SShri Abhyankar } 14635f2c45f1SShri Abhyankar 14645f2c45f1SShri Abhyankar PetscErrorCode DMSetUp_Network(DM dm) 14655f2c45f1SShri Abhyankar { 14665f2c45f1SShri Abhyankar PetscErrorCode ierr; 14675f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 14685f2c45f1SShri Abhyankar 14695f2c45f1SShri Abhyankar PetscFunctionBegin; 14705f2c45f1SShri Abhyankar ierr = DMNetworkComponentSetUp(dm);CHKERRQ(ierr); 14715f2c45f1SShri Abhyankar ierr = DMNetworkVariablesSetUp(dm);CHKERRQ(ierr); 14725f2c45f1SShri Abhyankar 147392fd8e1eSJed Brown ierr = DMSetLocalSection(network->plex,network->DofSection);CHKERRQ(ierr); 1474e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,&network->GlobalDofSection);CHKERRQ(ierr); 14759e1d080bSHong Zhang 14769e1d080bSHong Zhang dm->setupcalled = PETSC_TRUE; 14779e1d080bSHong Zhang ierr = DMViewFromOptions(dm,NULL,"-dm_view");CHKERRQ(ierr); 14785f2c45f1SShri Abhyankar PetscFunctionReturn(0); 14795f2c45f1SShri Abhyankar } 14805f2c45f1SShri Abhyankar 14811ad426b7SHong Zhang /*@ 148217df6e9eSHong Zhang DMNetworkHasJacobian - Sets global flag for using user's sub Jacobian matrices 14831ad426b7SHong Zhang -- replaced by DMNetworkSetOption(network,userjacobian,PETSC_TURE)? 14841ad426b7SHong Zhang 14851ad426b7SHong Zhang Collective 14861ad426b7SHong Zhang 14871ad426b7SHong Zhang Input Parameters: 148883b2e829SHong Zhang + dm - The DMNetwork object 148983b2e829SHong Zhang . eflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for edges 149083b2e829SHong Zhang - vflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for vertices 14911ad426b7SHong Zhang 14921ad426b7SHong Zhang Level: intermediate 14931ad426b7SHong Zhang 14941ad426b7SHong Zhang @*/ 149583b2e829SHong Zhang PetscErrorCode DMNetworkHasJacobian(DM dm,PetscBool eflg,PetscBool vflg) 14961ad426b7SHong Zhang { 14971ad426b7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 14988675203cSHong Zhang PetscErrorCode ierr; 149966b4e0ffSHong Zhang PetscInt nVertices = network->nVertices; 15001ad426b7SHong Zhang 15011ad426b7SHong Zhang PetscFunctionBegin; 150283b2e829SHong Zhang network->userEdgeJacobian = eflg; 150383b2e829SHong Zhang network->userVertexJacobian = vflg; 15048675203cSHong Zhang 15058675203cSHong Zhang if (eflg && !network->Je) { 15068675203cSHong Zhang ierr = PetscCalloc1(3*network->nEdges,&network->Je);CHKERRQ(ierr); 15078675203cSHong Zhang } 15088675203cSHong Zhang 150966b4e0ffSHong Zhang if (vflg && !network->Jv && nVertices) { 15108675203cSHong Zhang PetscInt i,*vptr,nedges,vStart=network->vStart; 151166b4e0ffSHong Zhang PetscInt nedges_total; 15128675203cSHong Zhang const PetscInt *edges; 15138675203cSHong Zhang 15148675203cSHong Zhang /* count nvertex_total */ 15158675203cSHong Zhang nedges_total = 0; 15168675203cSHong Zhang ierr = PetscMalloc1(nVertices+1,&vptr);CHKERRQ(ierr); 15178675203cSHong Zhang 15188675203cSHong Zhang vptr[0] = 0; 15198675203cSHong Zhang for (i=0; i<nVertices; i++) { 15208675203cSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,i+vStart,&nedges,&edges);CHKERRQ(ierr); 15218675203cSHong Zhang nedges_total += nedges; 15228675203cSHong Zhang vptr[i+1] = vptr[i] + 2*nedges + 1; 15238675203cSHong Zhang } 15248675203cSHong Zhang 15258675203cSHong Zhang ierr = PetscCalloc1(2*nedges_total+nVertices,&network->Jv);CHKERRQ(ierr); 15268675203cSHong Zhang network->Jvptr = vptr; 15278675203cSHong Zhang } 15281ad426b7SHong Zhang PetscFunctionReturn(0); 15291ad426b7SHong Zhang } 15301ad426b7SHong Zhang 15311ad426b7SHong Zhang /*@ 153283b2e829SHong Zhang DMNetworkEdgeSetMatrix - Sets user-provided Jacobian matrices for this edge to the network 153383b2e829SHong Zhang 153483b2e829SHong Zhang Not Collective 153583b2e829SHong Zhang 153683b2e829SHong Zhang Input Parameters: 153783b2e829SHong Zhang + dm - The DMNetwork object 153883b2e829SHong Zhang . p - the edge point 15393e97b6e8SHong Zhang - J - array (size = 3) of Jacobian submatrices for this edge point: 15403e97b6e8SHong Zhang J[0]: this edge 1541d842c372SHong Zhang J[1] and J[2]: connected vertices, obtained by calling DMNetworkGetConnectedVertices() 154283b2e829SHong Zhang 154397bb938eSShri Abhyankar Level: advanced 154483b2e829SHong Zhang 154583b2e829SHong Zhang .seealso: DMNetworkVertexSetMatrix 154683b2e829SHong Zhang @*/ 154783b2e829SHong Zhang PetscErrorCode DMNetworkEdgeSetMatrix(DM dm,PetscInt p,Mat J[]) 154883b2e829SHong Zhang { 154983b2e829SHong Zhang DM_Network *network=(DM_Network*)dm->data; 155083b2e829SHong Zhang 155183b2e829SHong Zhang PetscFunctionBegin; 15528675203cSHong Zhang if (!network->Je) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkEdgeSetMatrix"); 15538675203cSHong Zhang 15548675203cSHong Zhang if (J) { 1555883e35e8SHong Zhang network->Je[3*p] = J[0]; 1556883e35e8SHong Zhang network->Je[3*p+1] = J[1]; 1557883e35e8SHong Zhang network->Je[3*p+2] = J[2]; 15588675203cSHong Zhang } 155983b2e829SHong Zhang PetscFunctionReturn(0); 156083b2e829SHong Zhang } 156183b2e829SHong Zhang 156283b2e829SHong Zhang /*@ 156376ddfea5SHong Zhang DMNetworkVertexSetMatrix - Sets user-provided Jacobian matrix for this vertex to the network 15641ad426b7SHong Zhang 15651ad426b7SHong Zhang Not Collective 15661ad426b7SHong Zhang 15671ad426b7SHong Zhang Input Parameters: 15681ad426b7SHong Zhang + dm - The DMNetwork object 15691ad426b7SHong Zhang . p - the vertex point 15703e97b6e8SHong Zhang - J - array of Jacobian (size = 2*(num of supporting edges) + 1) submatrices for this vertex point: 15713e97b6e8SHong Zhang J[0]: this vertex 15723e97b6e8SHong Zhang J[1+2*i]: i-th supporting edge 15733e97b6e8SHong Zhang J[1+2*i+1]: i-th connected vertex 15741ad426b7SHong Zhang 157597bb938eSShri Abhyankar Level: advanced 15761ad426b7SHong Zhang 157783b2e829SHong Zhang .seealso: DMNetworkEdgeSetMatrix 15781ad426b7SHong Zhang @*/ 1579883e35e8SHong Zhang PetscErrorCode DMNetworkVertexSetMatrix(DM dm,PetscInt p,Mat J[]) 15805f2c45f1SShri Abhyankar { 15815f2c45f1SShri Abhyankar PetscErrorCode ierr; 15825f2c45f1SShri Abhyankar DM_Network *network=(DM_Network*)dm->data; 15838675203cSHong Zhang PetscInt i,*vptr,nedges,vStart=network->vStart; 1584883e35e8SHong Zhang const PetscInt *edges; 15855f2c45f1SShri Abhyankar 15865f2c45f1SShri Abhyankar PetscFunctionBegin; 15878675203cSHong Zhang if (!network->Jv) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkVertexSetMatrix"); 1588883e35e8SHong Zhang 15898675203cSHong Zhang if (J) { 1590883e35e8SHong Zhang vptr = network->Jvptr; 15913e97b6e8SHong Zhang network->Jv[vptr[p-vStart]] = J[0]; /* Set Jacobian for this vertex */ 15923e97b6e8SHong Zhang 15933e97b6e8SHong Zhang /* Set Jacobian for each supporting edge and connected vertex */ 1594883e35e8SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,p,&nedges,&edges);CHKERRQ(ierr); 1595883e35e8SHong Zhang for (i=1; i<=2*nedges; i++) network->Jv[vptr[p-vStart]+i] = J[i]; 15968675203cSHong Zhang } 1597883e35e8SHong Zhang PetscFunctionReturn(0); 1598883e35e8SHong Zhang } 1599883e35e8SHong Zhang 1600e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 16015cf7da58SHong Zhang { 16025cf7da58SHong Zhang PetscErrorCode ierr; 16035cf7da58SHong Zhang PetscInt j; 16045cf7da58SHong Zhang PetscScalar val=(PetscScalar)ncols; 16055cf7da58SHong Zhang 16065cf7da58SHong Zhang PetscFunctionBegin; 16075cf7da58SHong Zhang if (!ghost) { 16085cf7da58SHong Zhang for (j=0; j<nrows; j++) { 16095cf7da58SHong Zhang ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 16105cf7da58SHong Zhang } 16115cf7da58SHong Zhang } else { 16125cf7da58SHong Zhang for (j=0; j<nrows; j++) { 16135cf7da58SHong Zhang ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 16145cf7da58SHong Zhang } 16155cf7da58SHong Zhang } 16165cf7da58SHong Zhang PetscFunctionReturn(0); 16175cf7da58SHong Zhang } 16185cf7da58SHong Zhang 1619e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 16205cf7da58SHong Zhang { 16215cf7da58SHong Zhang PetscErrorCode ierr; 16225cf7da58SHong Zhang PetscInt j,ncols_u; 16235cf7da58SHong Zhang PetscScalar val; 16245cf7da58SHong Zhang 16255cf7da58SHong Zhang PetscFunctionBegin; 16265cf7da58SHong Zhang if (!ghost) { 16275cf7da58SHong Zhang for (j=0; j<nrows; j++) { 16285cf7da58SHong Zhang ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 16295cf7da58SHong Zhang val = (PetscScalar)ncols_u; 16305cf7da58SHong Zhang ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 16315cf7da58SHong Zhang ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 16325cf7da58SHong Zhang } 16335cf7da58SHong Zhang } else { 16345cf7da58SHong Zhang for (j=0; j<nrows; j++) { 16355cf7da58SHong Zhang ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 16365cf7da58SHong Zhang val = (PetscScalar)ncols_u; 16375cf7da58SHong Zhang ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr); 16385cf7da58SHong Zhang ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr); 16395cf7da58SHong Zhang } 16405cf7da58SHong Zhang } 16415cf7da58SHong Zhang PetscFunctionReturn(0); 16425cf7da58SHong Zhang } 16435cf7da58SHong Zhang 1644e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz) 16455cf7da58SHong Zhang { 16465cf7da58SHong Zhang PetscErrorCode ierr; 16475cf7da58SHong Zhang 16485cf7da58SHong Zhang PetscFunctionBegin; 16495cf7da58SHong Zhang if (Ju) { 16505cf7da58SHong Zhang ierr = MatSetPreallocationUserblock_private(Ju,nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 16515cf7da58SHong Zhang } else { 16525cf7da58SHong Zhang ierr = MatSetPreallocationDenseblock_private(nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr); 16535cf7da58SHong Zhang } 16545cf7da58SHong Zhang PetscFunctionReturn(0); 16555cf7da58SHong Zhang } 16565cf7da58SHong Zhang 1657e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 1658883e35e8SHong Zhang { 1659883e35e8SHong Zhang PetscErrorCode ierr; 1660883e35e8SHong Zhang PetscInt j,*cols; 1661883e35e8SHong Zhang PetscScalar *zeros; 1662883e35e8SHong Zhang 1663883e35e8SHong Zhang PetscFunctionBegin; 1664883e35e8SHong Zhang ierr = PetscCalloc2(ncols,&cols,nrows*ncols,&zeros);CHKERRQ(ierr); 1665883e35e8SHong Zhang for (j=0; j<ncols; j++) cols[j] = j+ cstart; 1666883e35e8SHong Zhang ierr = MatSetValues(*J,nrows,rows,ncols,cols,zeros,INSERT_VALUES);CHKERRQ(ierr); 1667883e35e8SHong Zhang ierr = PetscFree2(cols,zeros);CHKERRQ(ierr); 16681ad426b7SHong Zhang PetscFunctionReturn(0); 16691ad426b7SHong Zhang } 1670a4e85ca8SHong Zhang 1671e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 16723e97b6e8SHong Zhang { 16733e97b6e8SHong Zhang PetscErrorCode ierr; 16743e97b6e8SHong Zhang PetscInt j,M,N,row,col,ncols_u; 16753e97b6e8SHong Zhang const PetscInt *cols; 16763e97b6e8SHong Zhang PetscScalar zero=0.0; 16773e97b6e8SHong Zhang 16783e97b6e8SHong Zhang PetscFunctionBegin; 16793e97b6e8SHong Zhang ierr = MatGetSize(Ju,&M,&N);CHKERRQ(ierr); 16803e97b6e8SHong 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); 16813e97b6e8SHong Zhang 16823e97b6e8SHong Zhang for (row=0; row<nrows; row++) { 16833e97b6e8SHong Zhang ierr = MatGetRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 16843e97b6e8SHong Zhang for (j=0; j<ncols_u; j++) { 16853e97b6e8SHong Zhang col = cols[j] + cstart; 16863e97b6e8SHong Zhang ierr = MatSetValues(*J,1,&rows[row],1,&col,&zero,INSERT_VALUES);CHKERRQ(ierr); 16873e97b6e8SHong Zhang } 16883e97b6e8SHong Zhang ierr = MatRestoreRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr); 16893e97b6e8SHong Zhang } 16903e97b6e8SHong Zhang PetscFunctionReturn(0); 16913e97b6e8SHong Zhang } 16921ad426b7SHong Zhang 1693e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J) 1694a4e85ca8SHong Zhang { 1695a4e85ca8SHong Zhang PetscErrorCode ierr; 1696f4431b8cSHong Zhang 1697a4e85ca8SHong Zhang PetscFunctionBegin; 1698a4e85ca8SHong Zhang if (Ju) { 1699a4e85ca8SHong Zhang ierr = MatSetUserblock_private(Ju,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 1700a4e85ca8SHong Zhang } else { 1701a4e85ca8SHong Zhang ierr = MatSetDenseblock_private(nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 1702a4e85ca8SHong Zhang } 1703a4e85ca8SHong Zhang PetscFunctionReturn(0); 1704a4e85ca8SHong Zhang } 1705a4e85ca8SHong Zhang 170624121865SAdrian 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. 170724121865SAdrian Maldonado */ 170824121865SAdrian Maldonado PetscErrorCode CreateSubGlobalToLocalMapping_private(PetscSection globalsec, PetscSection localsec, ISLocalToGlobalMapping *ltog) 170924121865SAdrian Maldonado { 171024121865SAdrian Maldonado PetscErrorCode ierr; 171124121865SAdrian Maldonado PetscInt i,size,dof; 171224121865SAdrian Maldonado PetscInt *glob2loc; 171324121865SAdrian Maldonado 171424121865SAdrian Maldonado PetscFunctionBegin; 171524121865SAdrian Maldonado ierr = PetscSectionGetStorageSize(localsec,&size);CHKERRQ(ierr); 171624121865SAdrian Maldonado ierr = PetscMalloc1(size,&glob2loc);CHKERRQ(ierr); 171724121865SAdrian Maldonado 171824121865SAdrian Maldonado for (i = 0; i < size; i++) { 171924121865SAdrian Maldonado ierr = PetscSectionGetOffset(globalsec,i,&dof);CHKERRQ(ierr); 172024121865SAdrian Maldonado dof = (dof >= 0) ? dof : -(dof + 1); 172124121865SAdrian Maldonado glob2loc[i] = dof; 172224121865SAdrian Maldonado } 172324121865SAdrian Maldonado 172424121865SAdrian Maldonado ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,size,glob2loc,PETSC_OWN_POINTER,ltog);CHKERRQ(ierr); 172524121865SAdrian Maldonado #if 0 172624121865SAdrian Maldonado ierr = PetscIntView(size,glob2loc,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 172724121865SAdrian Maldonado #endif 172824121865SAdrian Maldonado PetscFunctionReturn(0); 172924121865SAdrian Maldonado } 173024121865SAdrian Maldonado 173101ad2aeeSHong Zhang #include <petsc/private/matimpl.h> 17329e1d080bSHong Zhang 17339e1d080bSHong Zhang PetscErrorCode DMCreateMatrix_Network_Nest(DM dm,Mat *J) 17341ad426b7SHong Zhang { 17351ad426b7SHong Zhang PetscErrorCode ierr; 17361ad426b7SHong Zhang DM_Network *network = (DM_Network*)dm->data; 17379e1d080bSHong Zhang PetscMPIInt rank, size; 173824121865SAdrian Maldonado PetscInt eDof,vDof; 173924121865SAdrian Maldonado Mat j11,j12,j21,j22,bA[2][2]; 17409e1d080bSHong Zhang MPI_Comm comm; 174124121865SAdrian Maldonado ISLocalToGlobalMapping eISMap,vISMap; 174224121865SAdrian Maldonado 17439e1d080bSHong Zhang PetscFunctionBegin; 174424121865SAdrian Maldonado ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 174524121865SAdrian Maldonado ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 174624121865SAdrian Maldonado ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 174724121865SAdrian Maldonado 174824121865SAdrian Maldonado ierr = PetscSectionGetConstrainedStorageSize(network->edge.GlobalDofSection,&eDof);CHKERRQ(ierr); 174924121865SAdrian Maldonado ierr = PetscSectionGetConstrainedStorageSize(network->vertex.GlobalDofSection,&vDof);CHKERRQ(ierr); 175024121865SAdrian Maldonado 175101ad2aeeSHong Zhang ierr = MatCreate(comm, &j11);CHKERRQ(ierr); 175224121865SAdrian Maldonado ierr = MatSetSizes(j11, eDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 175324121865SAdrian Maldonado ierr = MatSetType(j11, MATMPIAIJ);CHKERRQ(ierr); 175424121865SAdrian Maldonado 175501ad2aeeSHong Zhang ierr = MatCreate(comm, &j12);CHKERRQ(ierr); 175624121865SAdrian Maldonado ierr = MatSetSizes(j12, eDof, vDof, PETSC_DETERMINE ,PETSC_DETERMINE);CHKERRQ(ierr); 175724121865SAdrian Maldonado ierr = MatSetType(j12, MATMPIAIJ);CHKERRQ(ierr); 175824121865SAdrian Maldonado 175901ad2aeeSHong Zhang ierr = MatCreate(comm, &j21);CHKERRQ(ierr); 176024121865SAdrian Maldonado ierr = MatSetSizes(j21, vDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 176124121865SAdrian Maldonado ierr = MatSetType(j21, MATMPIAIJ);CHKERRQ(ierr); 176224121865SAdrian Maldonado 176301ad2aeeSHong Zhang ierr = MatCreate(comm, &j22);CHKERRQ(ierr); 176424121865SAdrian Maldonado ierr = MatSetSizes(j22, vDof, vDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 176524121865SAdrian Maldonado ierr = MatSetType(j22, MATMPIAIJ);CHKERRQ(ierr); 176624121865SAdrian Maldonado 17673f6a6bdaSHong Zhang bA[0][0] = j11; 17683f6a6bdaSHong Zhang bA[0][1] = j12; 17693f6a6bdaSHong Zhang bA[1][0] = j21; 17703f6a6bdaSHong Zhang bA[1][1] = j22; 177124121865SAdrian Maldonado 177224121865SAdrian Maldonado ierr = CreateSubGlobalToLocalMapping_private(network->edge.GlobalDofSection,network->edge.DofSection,&eISMap);CHKERRQ(ierr); 177324121865SAdrian Maldonado ierr = CreateSubGlobalToLocalMapping_private(network->vertex.GlobalDofSection,network->vertex.DofSection,&vISMap);CHKERRQ(ierr); 177424121865SAdrian Maldonado 177524121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j11,eISMap,eISMap);CHKERRQ(ierr); 177624121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j12,eISMap,vISMap);CHKERRQ(ierr); 177724121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j21,vISMap,eISMap);CHKERRQ(ierr); 177824121865SAdrian Maldonado ierr = MatSetLocalToGlobalMapping(j22,vISMap,vISMap);CHKERRQ(ierr); 177924121865SAdrian Maldonado 178024121865SAdrian Maldonado ierr = MatSetUp(j11);CHKERRQ(ierr); 178124121865SAdrian Maldonado ierr = MatSetUp(j12);CHKERRQ(ierr); 178224121865SAdrian Maldonado ierr = MatSetUp(j21);CHKERRQ(ierr); 178324121865SAdrian Maldonado ierr = MatSetUp(j22);CHKERRQ(ierr); 178424121865SAdrian Maldonado 178501ad2aeeSHong Zhang ierr = MatCreateNest(comm,2,NULL,2,NULL,&bA[0][0],J);CHKERRQ(ierr); 178624121865SAdrian Maldonado ierr = MatSetUp(*J);CHKERRQ(ierr); 178724121865SAdrian Maldonado ierr = MatNestSetVecType(*J,VECNEST);CHKERRQ(ierr); 178824121865SAdrian Maldonado ierr = MatDestroy(&j11);CHKERRQ(ierr); 178924121865SAdrian Maldonado ierr = MatDestroy(&j12);CHKERRQ(ierr); 179024121865SAdrian Maldonado ierr = MatDestroy(&j21);CHKERRQ(ierr); 179124121865SAdrian Maldonado ierr = MatDestroy(&j22);CHKERRQ(ierr); 179224121865SAdrian Maldonado 179324121865SAdrian Maldonado ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 179424121865SAdrian Maldonado ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17959e1d080bSHong Zhang ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 179624121865SAdrian Maldonado 179724121865SAdrian Maldonado /* Free structures */ 179824121865SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&eISMap);CHKERRQ(ierr); 179924121865SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&vISMap);CHKERRQ(ierr); 180024121865SAdrian Maldonado PetscFunctionReturn(0); 18019e1d080bSHong Zhang } 18029e1d080bSHong Zhang 18039e1d080bSHong Zhang PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J) 18049e1d080bSHong Zhang { 18059e1d080bSHong Zhang PetscErrorCode ierr; 18069e1d080bSHong Zhang DM_Network *network = (DM_Network*)dm->data; 18079e1d080bSHong Zhang PetscInt eStart,eEnd,vStart,vEnd,rstart,nrows,*rows,localSize; 18089e1d080bSHong Zhang PetscInt cstart,ncols,j,e,v; 18099e1d080bSHong Zhang PetscBool ghost,ghost_vc,ghost2,isNest; 18109e1d080bSHong Zhang Mat Juser; 18119e1d080bSHong Zhang PetscSection sectionGlobal; 18129e1d080bSHong Zhang PetscInt nedges,*vptr=NULL,vc,*rows_v; /* suppress maybe-uninitialized warning */ 18139e1d080bSHong Zhang const PetscInt *edges,*cone; 18149e1d080bSHong Zhang MPI_Comm comm; 18159e1d080bSHong Zhang MatType mtype; 18169e1d080bSHong Zhang Vec vd_nz,vo_nz; 18179e1d080bSHong Zhang PetscInt *dnnz,*onnz; 18189e1d080bSHong Zhang PetscScalar *vdnz,*vonz; 18199e1d080bSHong Zhang 18209e1d080bSHong Zhang PetscFunctionBegin; 18219e1d080bSHong Zhang mtype = dm->mattype; 18229e1d080bSHong Zhang ierr = PetscStrcmp(mtype,MATNEST,&isNest);CHKERRQ(ierr); 18239e1d080bSHong Zhang if (isNest) { 18249e1d080bSHong Zhang ierr = DMCreateMatrix_Network_Nest(dm,J);CHKERRQ(ierr); 1825c6b011d8SStefano Zampini ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 18269e1d080bSHong Zhang PetscFunctionReturn(0); 18279e1d080bSHong Zhang } 18289e1d080bSHong Zhang 18299e1d080bSHong Zhang if (!network->userEdgeJacobian && !network->userVertexJacobian) { 1830a4e85ca8SHong Zhang /* user does not provide Jacobian blocks */ 18319e1d080bSHong Zhang ierr = DMCreateMatrix_Plex(network->plex,J);CHKERRQ(ierr); 1832bfbc38dcSHong Zhang ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 18331ad426b7SHong Zhang PetscFunctionReturn(0); 18341ad426b7SHong Zhang } 18351ad426b7SHong Zhang 1836bfbc38dcSHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)dm),J);CHKERRQ(ierr); 1837e87a4003SBarry Smith ierr = DMGetGlobalSection(network->plex,§ionGlobal);CHKERRQ(ierr); 1838bfbc38dcSHong Zhang ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal,&localSize);CHKERRQ(ierr); 1839bfbc38dcSHong Zhang ierr = MatSetSizes(*J,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 18402a945128SHong Zhang 18412a945128SHong Zhang ierr = MatSetType(*J,MATAIJ);CHKERRQ(ierr); 18422a945128SHong Zhang ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 184389898e50SHong Zhang 184489898e50SHong Zhang /* (1) Set matrix preallocation */ 184589898e50SHong Zhang /*------------------------------*/ 1846840c2264SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 1847840c2264SHong Zhang ierr = VecCreate(comm,&vd_nz);CHKERRQ(ierr); 1848840c2264SHong Zhang ierr = VecSetSizes(vd_nz,localSize,PETSC_DECIDE);CHKERRQ(ierr); 1849840c2264SHong Zhang ierr = VecSetFromOptions(vd_nz);CHKERRQ(ierr); 1850840c2264SHong Zhang ierr = VecSet(vd_nz,0.0);CHKERRQ(ierr); 1851840c2264SHong Zhang ierr = VecDuplicate(vd_nz,&vo_nz);CHKERRQ(ierr); 1852840c2264SHong Zhang 185389898e50SHong Zhang /* Set preallocation for edges */ 185489898e50SHong Zhang /*-----------------------------*/ 1855840c2264SHong Zhang ierr = DMNetworkGetEdgeRange(dm,&eStart,&eEnd);CHKERRQ(ierr); 1856840c2264SHong Zhang 1857bdcb62a2SHong Zhang ierr = PetscMalloc1(localSize,&rows);CHKERRQ(ierr); 1858840c2264SHong Zhang for (e=eStart; e<eEnd; e++) { 1859840c2264SHong Zhang /* Get row indices */ 1860840c2264SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr); 1861840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr); 1862840c2264SHong Zhang if (nrows) { 1863840c2264SHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 1864840c2264SHong Zhang 18655cf7da58SHong Zhang /* Set preallocation for conntected vertices */ 1866d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 1867840c2264SHong Zhang for (v=0; v<2; v++) { 1868840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr); 1869840c2264SHong Zhang 18708675203cSHong Zhang if (network->Je) { 1871840c2264SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 18728675203cSHong Zhang } else Juser = NULL; 1873840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,cone[v],&ghost);CHKERRQ(ierr); 18745cf7da58SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 1875840c2264SHong Zhang } 1876840c2264SHong Zhang 187789898e50SHong Zhang /* Set preallocation for edge self */ 1878840c2264SHong Zhang cstart = rstart; 18798675203cSHong Zhang if (network->Je) { 1880840c2264SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 18818675203cSHong Zhang } else Juser = NULL; 18825cf7da58SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 1883840c2264SHong Zhang } 1884840c2264SHong Zhang } 1885840c2264SHong Zhang 188689898e50SHong Zhang /* Set preallocation for vertices */ 188789898e50SHong Zhang /*--------------------------------*/ 1888840c2264SHong Zhang ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr); 18898675203cSHong Zhang if (vEnd - vStart) vptr = network->Jvptr; 1890840c2264SHong Zhang 1891840c2264SHong Zhang for (v=vStart; v<vEnd; v++) { 1892840c2264SHong Zhang /* Get row indices */ 1893840c2264SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr); 1894840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr); 1895840c2264SHong Zhang if (!nrows) continue; 1896840c2264SHong Zhang 1897bdcb62a2SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 1898bdcb62a2SHong Zhang if (ghost) { 1899bdcb62a2SHong Zhang ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 1900bdcb62a2SHong Zhang } else { 1901bdcb62a2SHong Zhang rows_v = rows; 1902bdcb62a2SHong Zhang } 1903bdcb62a2SHong Zhang 1904bdcb62a2SHong Zhang for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 1905840c2264SHong Zhang 1906840c2264SHong Zhang /* Get supporting edges and connected vertices */ 1907840c2264SHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 1908840c2264SHong Zhang 1909840c2264SHong Zhang for (e=0; e<nedges; e++) { 1910840c2264SHong Zhang /* Supporting edges */ 1911840c2264SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr); 1912840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr); 1913840c2264SHong Zhang 19148675203cSHong Zhang if (network->Jv) { 1915840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 19168675203cSHong Zhang } else Juser = NULL; 1917bdcb62a2SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr); 1918840c2264SHong Zhang 1919840c2264SHong Zhang /* Connected vertices */ 1920d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr); 1921840c2264SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 1922840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,vc,&ghost_vc);CHKERRQ(ierr); 1923840c2264SHong Zhang 1924840c2264SHong Zhang ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr); 1925840c2264SHong Zhang 19268675203cSHong Zhang if (network->Jv) { 1927840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 19288675203cSHong Zhang } else Juser = NULL; 1929e102a522SHong Zhang if (ghost_vc||ghost) { 1930e102a522SHong Zhang ghost2 = PETSC_TRUE; 1931e102a522SHong Zhang } else { 1932e102a522SHong Zhang ghost2 = PETSC_FALSE; 1933e102a522SHong Zhang } 1934e102a522SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost2,vd_nz,vo_nz);CHKERRQ(ierr); 1935840c2264SHong Zhang } 1936840c2264SHong Zhang 193789898e50SHong Zhang /* Set preallocation for vertex self */ 1938840c2264SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 1939840c2264SHong Zhang if (!ghost) { 1940840c2264SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr); 19418675203cSHong Zhang if (network->Jv) { 1942840c2264SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 19438675203cSHong Zhang } else Juser = NULL; 1944bdcb62a2SHong Zhang ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr); 1945840c2264SHong Zhang } 1946bdcb62a2SHong Zhang if (ghost) { 1947bdcb62a2SHong Zhang ierr = PetscFree(rows_v);CHKERRQ(ierr); 1948bdcb62a2SHong Zhang } 1949840c2264SHong Zhang } 1950840c2264SHong Zhang 1951840c2264SHong Zhang ierr = VecAssemblyBegin(vd_nz);CHKERRQ(ierr); 1952840c2264SHong Zhang ierr = VecAssemblyBegin(vo_nz);CHKERRQ(ierr); 19535cf7da58SHong Zhang 19545cf7da58SHong Zhang ierr = PetscMalloc2(localSize,&dnnz,localSize,&onnz);CHKERRQ(ierr); 19555cf7da58SHong Zhang 19565cf7da58SHong Zhang ierr = VecAssemblyEnd(vd_nz);CHKERRQ(ierr); 1957840c2264SHong Zhang ierr = VecAssemblyEnd(vo_nz);CHKERRQ(ierr); 1958840c2264SHong Zhang 1959840c2264SHong Zhang ierr = VecGetArray(vd_nz,&vdnz);CHKERRQ(ierr); 1960840c2264SHong Zhang ierr = VecGetArray(vo_nz,&vonz);CHKERRQ(ierr); 1961840c2264SHong Zhang for (j=0; j<localSize; j++) { 1962e102a522SHong Zhang dnnz[j] = (PetscInt)PetscRealPart(vdnz[j]); 1963e102a522SHong Zhang onnz[j] = (PetscInt)PetscRealPart(vonz[j]); 1964840c2264SHong Zhang } 1965840c2264SHong Zhang ierr = VecRestoreArray(vd_nz,&vdnz);CHKERRQ(ierr); 1966840c2264SHong Zhang ierr = VecRestoreArray(vo_nz,&vonz);CHKERRQ(ierr); 1967840c2264SHong Zhang ierr = VecDestroy(&vd_nz);CHKERRQ(ierr); 1968840c2264SHong Zhang ierr = VecDestroy(&vo_nz);CHKERRQ(ierr); 1969840c2264SHong Zhang 19705cf7da58SHong Zhang ierr = MatSeqAIJSetPreallocation(*J,0,dnnz);CHKERRQ(ierr); 19715cf7da58SHong Zhang ierr = MatMPIAIJSetPreallocation(*J,0,dnnz,0,onnz);CHKERRQ(ierr); 19725cf7da58SHong Zhang ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 19735cf7da58SHong Zhang 19745cf7da58SHong Zhang ierr = PetscFree2(dnnz,onnz);CHKERRQ(ierr); 19755cf7da58SHong Zhang 197689898e50SHong Zhang /* (2) Set matrix entries for edges */ 197789898e50SHong Zhang /*----------------------------------*/ 19781ad426b7SHong Zhang for (e=eStart; e<eEnd; e++) { 1979bfbc38dcSHong Zhang /* Get row indices */ 19801ad426b7SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr); 198117df6e9eSHong Zhang ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr); 19824b976069SHong Zhang if (nrows) { 198317df6e9eSHong Zhang for (j=0; j<nrows; j++) rows[j] = j + rstart; 19841ad426b7SHong Zhang 1985bfbc38dcSHong Zhang /* Set matrix entries for conntected vertices */ 1986d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr); 1987bfbc38dcSHong Zhang for (v=0; v<2; v++) { 1988bfbc38dcSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,cone[v],&cstart);CHKERRQ(ierr); 1989883e35e8SHong Zhang ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr); 19903e97b6e8SHong Zhang 19918675203cSHong Zhang if (network->Je) { 1992a4e85ca8SHong Zhang Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */ 19938675203cSHong Zhang } else Juser = NULL; 1994a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,ncols,cstart,J);CHKERRQ(ierr); 1995bfbc38dcSHong Zhang } 199617df6e9eSHong Zhang 1997bfbc38dcSHong Zhang /* Set matrix entries for edge self */ 19983e97b6e8SHong Zhang cstart = rstart; 19998675203cSHong Zhang if (network->Je) { 2000a4e85ca8SHong Zhang Juser = network->Je[3*e]; /* Jacobian(e,e) */ 20018675203cSHong Zhang } else Juser = NULL; 2002a4e85ca8SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows,nrows,cstart,J);CHKERRQ(ierr); 20031ad426b7SHong Zhang } 20044b976069SHong Zhang } 20051ad426b7SHong Zhang 2006bfbc38dcSHong Zhang /* Set matrix entries for vertices */ 200783b2e829SHong Zhang /*---------------------------------*/ 20081ad426b7SHong Zhang for (v=vStart; v<vEnd; v++) { 2009bfbc38dcSHong Zhang /* Get row indices */ 2010596e729fSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr); 2011596e729fSHong Zhang ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr); 20124b976069SHong Zhang if (!nrows) continue; 2013596e729fSHong Zhang 2014bdcb62a2SHong Zhang ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr); 2015bdcb62a2SHong Zhang if (ghost) { 2016bdcb62a2SHong Zhang ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr); 2017bdcb62a2SHong Zhang } else { 2018bdcb62a2SHong Zhang rows_v = rows; 2019bdcb62a2SHong Zhang } 2020bdcb62a2SHong Zhang for (j=0; j<nrows; j++) rows_v[j] = j + rstart; 2021596e729fSHong Zhang 2022bfbc38dcSHong Zhang /* Get supporting edges and connected vertices */ 2023596e729fSHong Zhang ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr); 2024596e729fSHong Zhang 2025596e729fSHong Zhang for (e=0; e<nedges; e++) { 2026bfbc38dcSHong Zhang /* Supporting edges */ 2027596e729fSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr); 2028596e729fSHong Zhang ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr); 2029596e729fSHong Zhang 20308675203cSHong Zhang if (network->Jv) { 2031a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */ 20328675203cSHong Zhang } else Juser = NULL; 2033bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 2034596e729fSHong Zhang 2035bfbc38dcSHong Zhang /* Connected vertices */ 2036d842c372SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr); 20372a945128SHong Zhang vc = (v == cone[0]) ? cone[1]:cone[0]; 20382a945128SHong Zhang 203944aca652SHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,vc,&cstart);CHKERRQ(ierr); 204044aca652SHong Zhang ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr); 2041a4e85ca8SHong Zhang 20428675203cSHong Zhang if (network->Jv) { 2043a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */ 20448675203cSHong Zhang } else Juser = NULL; 2045bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr); 2046596e729fSHong Zhang } 2047596e729fSHong Zhang 2048bfbc38dcSHong Zhang /* Set matrix entries for vertex self */ 20491ad426b7SHong Zhang if (!ghost) { 2050596e729fSHong Zhang ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr); 20518675203cSHong Zhang if (network->Jv) { 2052a4e85ca8SHong Zhang Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */ 20538675203cSHong Zhang } else Juser = NULL; 2054bdcb62a2SHong Zhang ierr = MatSetblock_private(Juser,nrows,rows_v,nrows,cstart,J);CHKERRQ(ierr); 2055bdcb62a2SHong Zhang } 2056bdcb62a2SHong Zhang if (ghost) { 2057bdcb62a2SHong Zhang ierr = PetscFree(rows_v);CHKERRQ(ierr); 2058bdcb62a2SHong Zhang } 20591ad426b7SHong Zhang } 2060a4e85ca8SHong Zhang ierr = PetscFree(rows);CHKERRQ(ierr); 2061bdcb62a2SHong Zhang 20621ad426b7SHong Zhang ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20631ad426b7SHong Zhang ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2064dd6f46cdSHong Zhang 20655f2c45f1SShri Abhyankar ierr = MatSetDM(*J,dm);CHKERRQ(ierr); 20665f2c45f1SShri Abhyankar PetscFunctionReturn(0); 20675f2c45f1SShri Abhyankar } 20685f2c45f1SShri Abhyankar 20695f2c45f1SShri Abhyankar PetscErrorCode DMDestroy_Network(DM dm) 20705f2c45f1SShri Abhyankar { 20715f2c45f1SShri Abhyankar PetscErrorCode ierr; 20725f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 20732727e31bSShri Abhyankar PetscInt j; 20745f2c45f1SShri Abhyankar 20755f2c45f1SShri Abhyankar PetscFunctionBegin; 20768415c774SShri Abhyankar if (--network->refct > 0) PetscFunctionReturn(0); 207783b2e829SHong Zhang if (network->Je) { 207883b2e829SHong Zhang ierr = PetscFree(network->Je);CHKERRQ(ierr); 207983b2e829SHong Zhang } 208083b2e829SHong Zhang if (network->Jv) { 2081883e35e8SHong Zhang ierr = PetscFree(network->Jvptr);CHKERRQ(ierr); 208283b2e829SHong Zhang ierr = PetscFree(network->Jv);CHKERRQ(ierr); 20831ad426b7SHong Zhang } 208413c2a604SAdrian Maldonado 208513c2a604SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&network->vertex.mapping);CHKERRQ(ierr); 208613c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->vertex.DofSection);CHKERRQ(ierr); 208713c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->vertex.GlobalDofSection);CHKERRQ(ierr); 2088f5427c60SHong Zhang if (network->vltog) { 2089f5427c60SHong Zhang ierr = PetscFree(network->vltog);CHKERRQ(ierr); 2090f5427c60SHong Zhang } 209113c2a604SAdrian Maldonado if (network->vertex.sf) { 209213c2a604SAdrian Maldonado ierr = PetscSFDestroy(&network->vertex.sf);CHKERRQ(ierr); 209313c2a604SAdrian Maldonado } 209413c2a604SAdrian Maldonado /* edge */ 209513c2a604SAdrian Maldonado ierr = ISLocalToGlobalMappingDestroy(&network->edge.mapping);CHKERRQ(ierr); 209613c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->edge.DofSection);CHKERRQ(ierr); 209713c2a604SAdrian Maldonado ierr = PetscSectionDestroy(&network->edge.GlobalDofSection);CHKERRQ(ierr); 209813c2a604SAdrian Maldonado if (network->edge.sf) { 209913c2a604SAdrian Maldonado ierr = PetscSFDestroy(&network->edge.sf);CHKERRQ(ierr); 210013c2a604SAdrian Maldonado } 21015f2c45f1SShri Abhyankar ierr = DMDestroy(&network->plex);CHKERRQ(ierr); 21025f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DataSection);CHKERRQ(ierr); 21035f2c45f1SShri Abhyankar ierr = PetscSectionDestroy(&network->DofSection);CHKERRQ(ierr); 210483b2e829SHong Zhang 21052727e31bSShri Abhyankar for(j=0; j<network->nsubnet; j++) { 21062727e31bSShri Abhyankar ierr = PetscFree(network->subnet[j].edges);CHKERRQ(ierr); 21072727e31bSShri Abhyankar } 2108caf410d2SHong Zhang ierr = PetscFree(network->subnetvtx);CHKERRQ(ierr); 2109caf410d2SHong Zhang 2110e2aaf10cSShri Abhyankar ierr = PetscFree(network->subnet);CHKERRQ(ierr); 21115f2c45f1SShri Abhyankar ierr = PetscFree(network->componentdataarray);CHKERRQ(ierr); 2112caf410d2SHong Zhang ierr = PetscFree2(network->header,network->cvalue);CHKERRQ(ierr); 21135f2c45f1SShri Abhyankar ierr = PetscFree(network);CHKERRQ(ierr); 21145f2c45f1SShri Abhyankar PetscFunctionReturn(0); 21155f2c45f1SShri Abhyankar } 21165f2c45f1SShri Abhyankar 21175f2c45f1SShri Abhyankar PetscErrorCode DMView_Network(DM dm,PetscViewer viewer) 21185f2c45f1SShri Abhyankar { 21195f2c45f1SShri Abhyankar PetscErrorCode ierr; 21205f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 2121caf410d2SHong Zhang PetscBool iascii; 2122caf410d2SHong Zhang PetscMPIInt rank; 2123caf410d2SHong Zhang PetscInt p,nsubnet; 21245f2c45f1SShri Abhyankar 21255f2c45f1SShri Abhyankar PetscFunctionBegin; 2126caf410d2SHong Zhang if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE,"Must call DMSetUp() first"); 2127caf410d2SHong Zhang ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr); 2128caf410d2SHong Zhang PetscValidHeaderSpecific(dm,DM_CLASSID, 1); 2129caf410d2SHong Zhang PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2130caf410d2SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 2131caf410d2SHong Zhang if (iascii) { 2132caf410d2SHong Zhang const PetscInt *cone,*vtx,*edges; 2133caf410d2SHong Zhang PetscInt vfrom,vto,i,j,nv,ne; 2134caf410d2SHong Zhang 2135caf410d2SHong Zhang nsubnet = network->nsubnet - network->ncsubnet; /* num of subnetworks */ 2136caf410d2SHong Zhang ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 2137caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " [%d] nsubnet: %D; nsubnetCouple: %D; nEdges: %D; nVertices: %D\n",rank,nsubnet,network->ncsubnet,network->nEdges,network->nVertices);CHKERRQ(ierr); 2138caf410d2SHong Zhang 2139caf410d2SHong Zhang for (i=0; i<nsubnet; i++) { 2140caf410d2SHong Zhang ierr = DMNetworkGetSubnetworkInfo(dm,i,&nv,&ne,&vtx,&edges);CHKERRQ(ierr); 2141caf410d2SHong Zhang if (ne) { 2142caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " Subnet %D: nEdges %D, nVertices %D\n",i,ne,nv);CHKERRQ(ierr); 2143caf410d2SHong Zhang for (j=0; j<ne; j++) { 2144caf410d2SHong Zhang p = edges[j]; 2145caf410d2SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,p,&cone);CHKERRQ(ierr); 2146caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[0],&vfrom);CHKERRQ(ierr); 2147caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[1],&vto);CHKERRQ(ierr); 2148caf410d2SHong Zhang ierr = DMNetworkGetGlobalEdgeIndex(dm,edges[j],&p);CHKERRQ(ierr); 2149caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " edge %D: %D----> %D\n",p,vfrom,vto);CHKERRQ(ierr); 2150caf410d2SHong Zhang } 2151caf410d2SHong Zhang } 2152caf410d2SHong Zhang } 2153caf410d2SHong Zhang /* Coupling subnets */ 2154caf410d2SHong Zhang nsubnet = network->nsubnet; 2155caf410d2SHong Zhang for (; i<nsubnet; i++) { 2156caf410d2SHong Zhang ierr = DMNetworkGetSubnetworkInfo(dm,i,&nv,&ne,&vtx,&edges);CHKERRQ(ierr); 2157caf410d2SHong Zhang if (ne) { 2158caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " Subnet %D (couple): nEdges %D, nVertices %D\n",i,ne,nv);CHKERRQ(ierr); 2159caf410d2SHong Zhang for (j=0; j<ne; j++) { 2160caf410d2SHong Zhang p = edges[j]; 2161caf410d2SHong Zhang ierr = DMNetworkGetConnectedVertices(dm,p,&cone);CHKERRQ(ierr); 2162caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[0],&vfrom);CHKERRQ(ierr); 2163caf410d2SHong Zhang ierr = DMNetworkGetGlobalVertexIndex(dm,cone[1],&vto);CHKERRQ(ierr); 2164d5c9c0c4SHong Zhang ierr = DMNetworkGetGlobalEdgeIndex(dm,edges[j],&p);CHKERRQ(ierr); 2165caf410d2SHong Zhang ierr = PetscViewerASCIISynchronizedPrintf(viewer, " edge %D: %D----> %D\n",p,vfrom,vto);CHKERRQ(ierr); 2166caf410d2SHong Zhang } 2167caf410d2SHong Zhang } 2168caf410d2SHong Zhang } 2169caf410d2SHong Zhang ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2170caf410d2SHong Zhang ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 2171caf410d2SHong Zhang } else SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMNetwork writing", ((PetscObject)viewer)->type_name); 21725f2c45f1SShri Abhyankar PetscFunctionReturn(0); 21735f2c45f1SShri Abhyankar } 21745f2c45f1SShri Abhyankar 21755f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l) 21765f2c45f1SShri Abhyankar { 21775f2c45f1SShri Abhyankar PetscErrorCode ierr; 21785f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 21795f2c45f1SShri Abhyankar 21805f2c45f1SShri Abhyankar PetscFunctionBegin; 21815f2c45f1SShri Abhyankar ierr = DMGlobalToLocalBegin(network->plex,g,mode,l);CHKERRQ(ierr); 21825f2c45f1SShri Abhyankar PetscFunctionReturn(0); 21835f2c45f1SShri Abhyankar } 21845f2c45f1SShri Abhyankar 21855f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l) 21865f2c45f1SShri Abhyankar { 21875f2c45f1SShri Abhyankar PetscErrorCode ierr; 21885f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 21895f2c45f1SShri Abhyankar 21905f2c45f1SShri Abhyankar PetscFunctionBegin; 21915f2c45f1SShri Abhyankar ierr = DMGlobalToLocalEnd(network->plex,g,mode,l);CHKERRQ(ierr); 21925f2c45f1SShri Abhyankar PetscFunctionReturn(0); 21935f2c45f1SShri Abhyankar } 21945f2c45f1SShri Abhyankar 21955f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g) 21965f2c45f1SShri Abhyankar { 21975f2c45f1SShri Abhyankar PetscErrorCode ierr; 21985f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 21995f2c45f1SShri Abhyankar 22005f2c45f1SShri Abhyankar PetscFunctionBegin; 22015f2c45f1SShri Abhyankar ierr = DMLocalToGlobalBegin(network->plex,l,mode,g);CHKERRQ(ierr); 22025f2c45f1SShri Abhyankar PetscFunctionReturn(0); 22035f2c45f1SShri Abhyankar } 22045f2c45f1SShri Abhyankar 22055f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g) 22065f2c45f1SShri Abhyankar { 22075f2c45f1SShri Abhyankar PetscErrorCode ierr; 22085f2c45f1SShri Abhyankar DM_Network *network = (DM_Network*)dm->data; 22095f2c45f1SShri Abhyankar 22105f2c45f1SShri Abhyankar PetscFunctionBegin; 22115f2c45f1SShri Abhyankar ierr = DMLocalToGlobalEnd(network->plex,l,mode,g);CHKERRQ(ierr); 22125f2c45f1SShri Abhyankar PetscFunctionReturn(0); 22135f2c45f1SShri Abhyankar } 221422bbedd7SHong Zhang 221522bbedd7SHong Zhang /*@ 221664238763SRodolfo Oliveira DMNetworkGetVertexLocalToGlobalOrdering - Get vertex global index 221722bbedd7SHong Zhang 221822bbedd7SHong Zhang Not collective 221922bbedd7SHong Zhang 22207a7aea1fSJed Brown Input Parameters: 222122bbedd7SHong Zhang + dm - the dm object 222222bbedd7SHong Zhang - vloc - local vertex ordering, start from 0 222322bbedd7SHong Zhang 22247a7aea1fSJed Brown Output Parameters: 2225f0fc11ceSJed Brown . vg - global vertex ordering, start from 0 222622bbedd7SHong Zhang 222797bb938eSShri Abhyankar Level: advanced 222822bbedd7SHong Zhang 222922bbedd7SHong Zhang .seealso: DMNetworkSetVertexLocalToGlobalOrdering() 223022bbedd7SHong Zhang @*/ 223122bbedd7SHong Zhang PetscErrorCode DMNetworkGetVertexLocalToGlobalOrdering(DM dm,PetscInt vloc,PetscInt *vg) 223222bbedd7SHong Zhang { 223322bbedd7SHong Zhang DM_Network *network = (DM_Network*)dm->data; 223422bbedd7SHong Zhang PetscInt *vltog = network->vltog; 223522bbedd7SHong Zhang 223622bbedd7SHong Zhang PetscFunctionBegin; 223722bbedd7SHong Zhang if (!vltog) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Must call DMNetworkSetVertexLocalToGlobalOrdering() first"); 223822bbedd7SHong Zhang *vg = vltog[vloc]; 223922bbedd7SHong Zhang PetscFunctionReturn(0); 224022bbedd7SHong Zhang } 224122bbedd7SHong Zhang 224222bbedd7SHong Zhang /*@ 224364238763SRodolfo Oliveira DMNetworkSetVertexLocalToGlobalOrdering - Create and setup vertex local to global map 224422bbedd7SHong Zhang 224522bbedd7SHong Zhang Collective 224622bbedd7SHong Zhang 224722bbedd7SHong Zhang Input Parameters: 2248f0fc11ceSJed Brown . dm - the dm object 224922bbedd7SHong Zhang 225097bb938eSShri Abhyankar Level: advanced 225122bbedd7SHong Zhang 225263029d29SHong Zhang .seealso: DMNetworkGetGlobalVertexIndex() 225322bbedd7SHong Zhang @*/ 225422bbedd7SHong Zhang PetscErrorCode DMNetworkSetVertexLocalToGlobalOrdering(DM dm) 225522bbedd7SHong Zhang { 225622bbedd7SHong Zhang PetscErrorCode ierr; 225722bbedd7SHong Zhang DM_Network *network=(DM_Network*)dm->data; 225822bbedd7SHong Zhang MPI_Comm comm; 225963029d29SHong Zhang PetscMPIInt rank,size,*displs,*recvcounts,remoterank; 226022bbedd7SHong Zhang PetscBool ghost; 226163029d29SHong Zhang PetscInt *vltog,nroots,nleaves,i,*vrange,k,N,lidx; 226222bbedd7SHong Zhang const PetscSFNode *iremote; 226322bbedd7SHong Zhang PetscSF vsf; 226463029d29SHong Zhang Vec Vleaves,Vleaves_seq; 226563029d29SHong Zhang VecScatter ctx; 226663029d29SHong Zhang PetscScalar *varr,val; 226763029d29SHong Zhang const PetscScalar *varr_read; 226822bbedd7SHong Zhang 226922bbedd7SHong Zhang PetscFunctionBegin; 227022bbedd7SHong Zhang ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 227122bbedd7SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 227263029d29SHong Zhang ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 227322bbedd7SHong Zhang 227422bbedd7SHong Zhang if (size == 1) { 227522bbedd7SHong Zhang nroots = network->vEnd - network->vStart; 227622bbedd7SHong Zhang ierr = PetscMalloc1(nroots, &vltog);CHKERRQ(ierr); 227722bbedd7SHong Zhang for (i=0; i<nroots; i++) vltog[i] = i; 227822bbedd7SHong Zhang network->vltog = vltog; 227922bbedd7SHong Zhang PetscFunctionReturn(0); 228022bbedd7SHong Zhang } 228122bbedd7SHong Zhang 228222bbedd7SHong Zhang if (!network->distributecalled) SETERRQ(comm, PETSC_ERR_ARG_WRONGSTATE,"Must call DMNetworkDistribute() first"); 228322bbedd7SHong Zhang if (network->vltog) { 228422bbedd7SHong Zhang ierr = PetscFree(network->vltog);CHKERRQ(ierr); 228522bbedd7SHong Zhang } 228622bbedd7SHong Zhang 228722bbedd7SHong Zhang ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr); 228822bbedd7SHong Zhang ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr); 228922bbedd7SHong Zhang vsf = network->vertex.sf; 229022bbedd7SHong Zhang 229122bbedd7SHong Zhang ierr = PetscMalloc3(size+1,&vrange,size+1,&displs,size,&recvcounts);CHKERRQ(ierr); 2292f5427c60SHong Zhang ierr = PetscSFGetGraph(vsf,&nroots,&nleaves,NULL,&iremote);CHKERRQ(ierr); 229322bbedd7SHong Zhang 229422bbedd7SHong Zhang for (i=0; i<size; i++) { displs[i] = i; recvcounts[i] = 1;} 229522bbedd7SHong Zhang 229622bbedd7SHong Zhang i = nroots - nleaves; /* local number of vertices, excluding ghosts */ 229722bbedd7SHong Zhang vrange[0] = 0; 229822bbedd7SHong Zhang ierr = MPI_Allgatherv(&i,1,MPIU_INT,vrange+1,recvcounts,displs,MPIU_INT,comm);CHKERRQ(ierr); 229967dd800bSHong Zhang for (i=2; i<size+1; i++) {vrange[i] += vrange[i-1];} 230022bbedd7SHong Zhang 230122bbedd7SHong Zhang ierr = PetscMalloc1(nroots, &vltog);CHKERRQ(ierr); 230222bbedd7SHong Zhang network->vltog = vltog; 230322bbedd7SHong Zhang 230463029d29SHong Zhang /* Set vltog for non-ghost vertices */ 230563029d29SHong Zhang k = 0; 230622bbedd7SHong Zhang for (i=0; i<nroots; i++) { 230722bbedd7SHong Zhang ierr = DMNetworkIsGhostVertex(dm,i+network->vStart,&ghost);CHKERRQ(ierr); 230863029d29SHong Zhang if (ghost) continue; 230963029d29SHong Zhang vltog[i] = vrange[rank] + k++; 231022bbedd7SHong Zhang } 2311f5427c60SHong Zhang ierr = PetscFree3(vrange,displs,recvcounts);CHKERRQ(ierr); 231263029d29SHong Zhang 231363029d29SHong Zhang /* Set vltog for ghost vertices */ 231463029d29SHong Zhang /* (a) create parallel Vleaves and sequential Vleaves_seq to convert local iremote[*].index to global index */ 231563029d29SHong Zhang ierr = VecCreate(comm,&Vleaves);CHKERRQ(ierr); 231663029d29SHong Zhang ierr = VecSetSizes(Vleaves,2*nleaves,PETSC_DETERMINE);CHKERRQ(ierr); 231763029d29SHong Zhang ierr = VecSetFromOptions(Vleaves);CHKERRQ(ierr); 231863029d29SHong Zhang ierr = VecGetArray(Vleaves,&varr);CHKERRQ(ierr); 231963029d29SHong Zhang for (i=0; i<nleaves; i++) { 232063029d29SHong Zhang varr[2*i] = (PetscScalar)(iremote[i].rank); /* rank of remote process */ 232163029d29SHong Zhang varr[2*i+1] = (PetscScalar)(iremote[i].index); /* local index in remote process */ 232263029d29SHong Zhang } 232363029d29SHong Zhang ierr = VecRestoreArray(Vleaves,&varr);CHKERRQ(ierr); 232463029d29SHong Zhang 232563029d29SHong Zhang /* (b) scatter local info to remote processes via VecScatter() */ 232663029d29SHong Zhang ierr = VecScatterCreateToAll(Vleaves,&ctx,&Vleaves_seq);CHKERRQ(ierr); 232763029d29SHong Zhang ierr = VecScatterBegin(ctx,Vleaves,Vleaves_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 232863029d29SHong Zhang ierr = VecScatterEnd(ctx,Vleaves,Vleaves_seq,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 232963029d29SHong Zhang 233063029d29SHong Zhang /* (c) convert local indices to global indices in parallel vector Vleaves */ 233163029d29SHong Zhang ierr = VecGetSize(Vleaves_seq,&N);CHKERRQ(ierr); 233263029d29SHong Zhang ierr = VecGetArrayRead(Vleaves_seq,&varr_read);CHKERRQ(ierr); 233363029d29SHong Zhang for (i=0; i<N; i+=2) { 23342e4cff2eSHong Zhang remoterank = (PetscMPIInt)PetscRealPart(varr_read[i]); 233563029d29SHong Zhang if (remoterank == rank) { 233663029d29SHong Zhang k = i+1; /* row number */ 23372e4cff2eSHong Zhang lidx = (PetscInt)PetscRealPart(varr_read[i+1]); 233863029d29SHong Zhang val = (PetscScalar)vltog[lidx]; /* global index for non-ghost vertex computed above */ 233963029d29SHong Zhang ierr = VecSetValues(Vleaves,1,&k,&val,INSERT_VALUES);CHKERRQ(ierr); 234063029d29SHong Zhang } 234163029d29SHong Zhang } 234263029d29SHong Zhang ierr = VecRestoreArrayRead(Vleaves_seq,&varr_read);CHKERRQ(ierr); 234363029d29SHong Zhang ierr = VecAssemblyBegin(Vleaves);CHKERRQ(ierr); 234463029d29SHong Zhang ierr = VecAssemblyEnd(Vleaves);CHKERRQ(ierr); 234563029d29SHong Zhang 234663029d29SHong Zhang /* (d) Set vltog for ghost vertices by copying local values of Vleaves */ 234763029d29SHong Zhang ierr = VecGetArrayRead(Vleaves,&varr_read);CHKERRQ(ierr); 234863029d29SHong Zhang k = 0; 234963029d29SHong Zhang for (i=0; i<nroots; i++) { 235063029d29SHong Zhang ierr = DMNetworkIsGhostVertex(dm,i+network->vStart,&ghost);CHKERRQ(ierr); 235163029d29SHong Zhang if (!ghost) continue; 23522e4cff2eSHong Zhang vltog[i] = (PetscInt)PetscRealPart(varr_read[2*k+1]); k++; 235363029d29SHong Zhang } 235463029d29SHong Zhang ierr = VecRestoreArrayRead(Vleaves,&varr_read);CHKERRQ(ierr); 235563029d29SHong Zhang 235663029d29SHong Zhang ierr = VecDestroy(&Vleaves);CHKERRQ(ierr); 235763029d29SHong Zhang ierr = VecDestroy(&Vleaves_seq);CHKERRQ(ierr); 235863029d29SHong Zhang ierr = VecScatterDestroy(&ctx);CHKERRQ(ierr); 235922bbedd7SHong Zhang PetscFunctionReturn(0); 236022bbedd7SHong Zhang } 2361