xref: /petsc/src/dm/impls/network/network.c (revision 6500d4ab0b72a0e67bc93fd604cf502bd6a384b1)
1af0996ceSBarry Smith #include <petsc/private/dmnetworkimpl.h>  /*I  "petscdmnetwork.h"  I*/
25f2c45f1SShri Abhyankar #include <petscdmplex.h>
35f2c45f1SShri Abhyankar #include <petscsf.h>
45f2c45f1SShri Abhyankar 
55f2c45f1SShri Abhyankar /*@
6556ed216SShri Abhyankar   DMNetworkGetPlex - Gets the Plex DM associated with this network DM
7556ed216SShri Abhyankar 
8556ed216SShri Abhyankar   Not collective
9556ed216SShri Abhyankar 
10556ed216SShri Abhyankar   Input Parameters:
11556ed216SShri Abhyankar + netdm - the dm object
12556ed216SShri Abhyankar - plexmdm - the plex dm object
13556ed216SShri Abhyankar 
14556ed216SShri Abhyankar   Level: Advanced
15556ed216SShri Abhyankar 
16556ed216SShri Abhyankar .seealso: DMNetworkCreate()
17556ed216SShri Abhyankar @*/
18556ed216SShri Abhyankar PetscErrorCode DMNetworkGetPlex(DM netdm, DM *plexdm)
19556ed216SShri Abhyankar {
20556ed216SShri Abhyankar   DM_Network     *network = (DM_Network*) netdm->data;
21556ed216SShri Abhyankar 
22556ed216SShri Abhyankar   PetscFunctionBegin;
23556ed216SShri Abhyankar   *plexdm = network->plex;
24556ed216SShri Abhyankar   PetscFunctionReturn(0);
25556ed216SShri Abhyankar }
26556ed216SShri Abhyankar 
27556ed216SShri Abhyankar /*@
28e2aaf10cSShri Abhyankar   DMNetworkSetSizes - Sets the number of subnetworks,local and global vertices and edges for each subnetwork.
295f2c45f1SShri Abhyankar 
305f2c45f1SShri Abhyankar   Collective on DM
315f2c45f1SShri Abhyankar 
325f2c45f1SShri Abhyankar   Input Parameters:
335f2c45f1SShri Abhyankar + dm - the dm object
34e2aaf10cSShri Abhyankar . Nsubnet - number of subnetworks
35e2aaf10cSShri Abhyankar . nV - number of local vertices for each subnetwork
36e2aaf10cSShri Abhyankar . nE - number of local edges for each subnetwork
37e2aaf10cSShri Abhyankar . NV - number of global vertices (or PETSC_DETERMINE) for each subnetwork
38e2aaf10cSShri Abhyankar - NE - number of global edges (or PETSC_DETERMINE) for each subnetwork
395f2c45f1SShri Abhyankar 
405f2c45f1SShri Abhyankar    Notes
415f2c45f1SShri Abhyankar    If one processor calls this with NV (NE) of PETSC_DECIDE then all processors must, otherwise the prgram will hang.
425f2c45f1SShri Abhyankar 
435f2c45f1SShri Abhyankar    You cannot change the sizes once they have been set
445f2c45f1SShri Abhyankar 
451b266c99SBarry Smith    Level: intermediate
461b266c99SBarry Smith 
471b266c99SBarry Smith .seealso: DMNetworkCreate()
485f2c45f1SShri Abhyankar @*/
49e2aaf10cSShri Abhyankar PetscErrorCode DMNetworkSetSizes(DM dm, PetscInt Nsubnet, PetscInt nV[], PetscInt nE[], PetscInt NV[], PetscInt NE[])
505f2c45f1SShri Abhyankar {
515f2c45f1SShri Abhyankar   PetscErrorCode ierr;
525f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
53e2aaf10cSShri Abhyankar   PetscInt       a[2],b[2],i;
545f2c45f1SShri Abhyankar 
555f2c45f1SShri Abhyankar   PetscFunctionBegin;
565f2c45f1SShri Abhyankar   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
57e2aaf10cSShri Abhyankar   if (Nsubnet <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of subnetworks %D cannot be less than 1",Nsubnet);
58e2aaf10cSShri Abhyankar 
59e2aaf10cSShri Abhyankar   if(Nsubnet > 0) PetscValidLogicalCollectiveInt(dm,Nsubnet,2);
60e2aaf10cSShri Abhyankar   if(network->nsubnet != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Network sizes alread set, cannot resize the network");
61e2aaf10cSShri Abhyankar 
62e2aaf10cSShri Abhyankar   network->nsubnet = Nsubnet;
63e2aaf10cSShri Abhyankar   ierr = PetscCalloc1(Nsubnet,&network->subnet);CHKERRQ(ierr);
64e2aaf10cSShri Abhyankar   for(i=0; i < network->nsubnet; i++) {
65e2aaf10cSShri Abhyankar     if (NV[i] > 0) PetscValidLogicalCollectiveInt(dm,NV[i],5);
66e2aaf10cSShri Abhyankar     if (NE[i] > 0) PetscValidLogicalCollectiveInt(dm,NE[i],6);
67e2aaf10cSShri Abhyankar     if (NV[i] > 0 && nV[i] > NV[i]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Subnetwork %D: Local vertex size %D cannot be larger than global vertex size %D",i,nV[i],NV[i]);
68e2aaf10cSShri Abhyankar     if (NE[i] > 0 && nE[i] > NE[i]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Subnetwork %D: Local edge size %D cannot be larger than global edge size %D",i,nE[i],NE[i]);
69e2aaf10cSShri Abhyankar     a[0] = nV[i]; a[1] = nE[i];
70b2566f29SBarry Smith     ierr = MPIU_Allreduce(a,b,2,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
71e2aaf10cSShri Abhyankar     network->subnet[i].Nvtx = b[0]; network->subnet[i].Nedge = b[1];
72e2aaf10cSShri Abhyankar 
73e2aaf10cSShri Abhyankar     network->subnet[i].id = i;
74e2aaf10cSShri Abhyankar 
75e2aaf10cSShri Abhyankar     network->subnet[i].nvtx = nV[i];
76e2aaf10cSShri Abhyankar     network->subnet[i].vStart = network->nVertices;
77e2aaf10cSShri Abhyankar     network->subnet[i].vEnd   = network->subnet[i].vStart + network->subnet[i].Nvtx;
78e2aaf10cSShri Abhyankar     network->nVertices += network->subnet[i].nvtx;
79e2aaf10cSShri Abhyankar     network->NVertices += network->subnet[i].Nvtx;
80e2aaf10cSShri Abhyankar 
81e2aaf10cSShri Abhyankar     network->subnet[i].nedge = nE[i];
82e2aaf10cSShri Abhyankar     network->subnet[i].eStart = network->nEdges;
83e2aaf10cSShri Abhyankar     network->subnet[i].eEnd = network->subnet[i].eStart + network->subnet[i].Nedge;
84e2aaf10cSShri Abhyankar     network->nEdges += network->subnet[i].nedge;
85e2aaf10cSShri Abhyankar     network->NEdges += network->subnet[i].Nedge;
865f2c45f1SShri Abhyankar   }
875f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
885f2c45f1SShri Abhyankar }
895f2c45f1SShri Abhyankar 
905f2c45f1SShri Abhyankar /*@
915f2c45f1SShri Abhyankar   DMNetworkSetEdgeList - Sets the list of local edges (vertex connectivity) for the network
925f2c45f1SShri Abhyankar 
935f2c45f1SShri Abhyankar   Logically collective on DM
945f2c45f1SShri Abhyankar 
955f2c45f1SShri Abhyankar   Input Parameters:
96e2aaf10cSShri Abhyankar . edges - list of edges for each subnetwork
975f2c45f1SShri Abhyankar 
985f2c45f1SShri Abhyankar   Notes:
995f2c45f1SShri Abhyankar   There is no copy involved in this operation, only the pointer is referenced. The edgelist should
1005f2c45f1SShri Abhyankar   not be destroyed before the call to DMNetworkLayoutSetUp
1015f2c45f1SShri Abhyankar 
1025f2c45f1SShri Abhyankar   Level: intermediate
1035f2c45f1SShri Abhyankar 
1045f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkSetSizes
1055f2c45f1SShri Abhyankar @*/
106e2aaf10cSShri Abhyankar PetscErrorCode DMNetworkSetEdgeList(DM dm, int *edgelist[])
1075f2c45f1SShri Abhyankar {
1085f2c45f1SShri Abhyankar   DM_Network *network = (DM_Network*) dm->data;
109e2aaf10cSShri Abhyankar   PetscInt   i;
1105f2c45f1SShri Abhyankar 
1115f2c45f1SShri Abhyankar   PetscFunctionBegin;
112e2aaf10cSShri Abhyankar   for(i=0; i < network->nsubnet; i++) {
113e2aaf10cSShri Abhyankar     network->subnet[i].edgelist = edgelist[i];
114e2aaf10cSShri Abhyankar   }
1155f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
1165f2c45f1SShri Abhyankar }
1175f2c45f1SShri Abhyankar 
1185f2c45f1SShri Abhyankar /*@
1195f2c45f1SShri Abhyankar   DMNetworkLayoutSetUp - Sets up the bare layout (graph) for the network
1205f2c45f1SShri Abhyankar 
1215f2c45f1SShri Abhyankar   Collective on DM
1225f2c45f1SShri Abhyankar 
1235f2c45f1SShri Abhyankar   Input Parameters
1245f2c45f1SShri Abhyankar . DM - the dmnetwork object
1255f2c45f1SShri Abhyankar 
1265f2c45f1SShri Abhyankar   Notes:
1275f2c45f1SShri Abhyankar   This routine should be called after the network sizes and edgelists have been provided. It creates
1285f2c45f1SShri Abhyankar   the bare layout of the network and sets up the network to begin insertion of components.
1295f2c45f1SShri Abhyankar 
1305f2c45f1SShri Abhyankar   All the components should be registered before calling this routine.
1315f2c45f1SShri Abhyankar 
1325f2c45f1SShri Abhyankar   Level: intermediate
1335f2c45f1SShri Abhyankar 
1345f2c45f1SShri Abhyankar .seealso: DMNetworkSetSizes, DMNetworkSetEdgeList
1355f2c45f1SShri Abhyankar @*/
1365f2c45f1SShri Abhyankar PetscErrorCode DMNetworkLayoutSetUp(DM dm)
1375f2c45f1SShri Abhyankar {
1385f2c45f1SShri Abhyankar   PetscErrorCode ierr;
1395f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
1405f2c45f1SShri Abhyankar   PetscInt       dim = 1; /* One dimensional network */
1415f2c45f1SShri Abhyankar   PetscInt       numCorners=2;
1425f2c45f1SShri Abhyankar   PetscInt       spacedim=2;
1435f2c45f1SShri Abhyankar   double         *vertexcoords=NULL;
144e2aaf10cSShri Abhyankar   PetscInt       i,j;
1455f2c45f1SShri Abhyankar   PetscInt       ndata;
146e2aaf10cSShri Abhyankar   PetscInt       ctr=0;
1475f2c45f1SShri Abhyankar 
1485f2c45f1SShri Abhyankar   PetscFunctionBegin;
1496fefedf4SHong Zhang   if (network->nVertices) {
1506fefedf4SHong Zhang     ierr = PetscCalloc1(numCorners*network->nVertices,&vertexcoords);CHKERRQ(ierr);
1515f2c45f1SShri Abhyankar   }
152e2aaf10cSShri Abhyankar 
153e2aaf10cSShri Abhyankar   /* Create the edgelist for the network by concatenating edgelists of the subnetworks */
154e2aaf10cSShri Abhyankar   ierr = PetscCalloc1(2*network->nEdges,&network->edges);CHKERRQ(ierr);
155e2aaf10cSShri Abhyankar   for(i=0; i < network->nsubnet; i++) {
156e2aaf10cSShri Abhyankar     for(j = 0; j < network->subnet[i].nedge; j++) {
157e2aaf10cSShri Abhyankar       network->edges[2*ctr] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j];
158e2aaf10cSShri Abhyankar       network->edges[2*ctr+1] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j+1];
159e2aaf10cSShri Abhyankar       ctr++;
160e2aaf10cSShri Abhyankar     }
161e2aaf10cSShri Abhyankar   }
162e2aaf10cSShri Abhyankar 
163*6500d4abSHong Zhang #if 1
164e2aaf10cSShri Abhyankar   for(i=0; i < network->nEdges; i++) {
165e2aaf10cSShri Abhyankar     ierr = PetscPrintf(PETSC_COMM_SELF,"[%D %D]",network->edges[2*i],network->edges[2*i+1]);CHKERRQ(ierr);
166e2aaf10cSShri Abhyankar   }
167e2aaf10cSShri Abhyankar #endif
168e2aaf10cSShri Abhyankar 
1696fefedf4SHong Zhang   ierr = DMPlexCreateFromCellList(PetscObjectComm((PetscObject)dm),dim,network->nEdges,network->nVertices,numCorners,PETSC_FALSE,network->edges,spacedim,vertexcoords,&network->plex);CHKERRQ(ierr);
1706fefedf4SHong Zhang   if (network->nVertices) {
1715f2c45f1SShri Abhyankar     ierr = PetscFree(vertexcoords);CHKERRQ(ierr);
1725f2c45f1SShri Abhyankar   }
173e2aaf10cSShri Abhyankar   ierr = PetscFree(network->edges);CHKERRQ(ierr);
174e2aaf10cSShri Abhyankar 
1755f2c45f1SShri Abhyankar   ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr);
1765f2c45f1SShri Abhyankar   ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr);
1775f2c45f1SShri Abhyankar   ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr);
1785f2c45f1SShri Abhyankar 
1795f2c45f1SShri Abhyankar   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm),&network->DataSection);CHKERRQ(ierr);
1805f2c45f1SShri Abhyankar   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm),&network->DofSection);CHKERRQ(ierr);
1815f2c45f1SShri Abhyankar   ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr);
1825f2c45f1SShri Abhyankar   ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr);
1835f2c45f1SShri Abhyankar 
1842727e31bSShri Abhyankar   /* Create vertices and edges array for the subnetworks */
1852727e31bSShri Abhyankar   for(j=0; j < network->nsubnet; j++) {
1862727e31bSShri Abhyankar     ierr = PetscCalloc1(network->subnet[j].nedge,&network->subnet[j].edges);CHKERRQ(ierr);
1872727e31bSShri Abhyankar     ierr = PetscCalloc1(network->subnet[j].nvtx,&network->subnet[j].vertices);CHKERRQ(ierr);
1882727e31bSShri Abhyankar     /* Temporarily setting nvtx and nedge to 0 so we can use them as counters in the below for loop.
1892727e31bSShri Abhyankar        These get updated when the vertices and edges are added. */
1902727e31bSShri Abhyankar     network->subnet[j].nvtx = network->subnet[j].nedge = 0;
1912727e31bSShri Abhyankar   }
1922727e31bSShri Abhyankar 
1935f2c45f1SShri Abhyankar   network->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType);
1946caa05f4SBarry Smith   ierr = PetscCalloc1(network->pEnd-network->pStart,&network->header);CHKERRQ(ierr);
195e2aaf10cSShri Abhyankar   for(i=network->eStart; i < network->eEnd; i++) {
196e2aaf10cSShri Abhyankar     network->header[i].index = i;   /* Global edge number */
197e2aaf10cSShri Abhyankar     for(j=0; j < network->nsubnet; j++) {
198e2aaf10cSShri Abhyankar       if((network->subnet[j].eStart <= i) && (i < network->subnet[j].eEnd)) {
199e2aaf10cSShri Abhyankar 	network->header[i].subnetid = j; /* Subnetwork id */
2002727e31bSShri Abhyankar 	network->subnet[j].edges[network->subnet[j].nedge++] = i;
201e2aaf10cSShri Abhyankar 	break;
202e2aaf10cSShri Abhyankar       }
2037b6afd5bSHong Zhang     }
2045f2c45f1SShri Abhyankar     network->header[i].ndata = 0;
2055f2c45f1SShri Abhyankar     ndata = network->header[i].ndata;
2065f2c45f1SShri Abhyankar     ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr);
2075f2c45f1SShri Abhyankar     network->header[i].offset[ndata] = 0;
2085f2c45f1SShri Abhyankar   }
209e2aaf10cSShri Abhyankar 
210e2aaf10cSShri Abhyankar   for(i=network->vStart; i < network->vEnd; i++) {
211e2aaf10cSShri Abhyankar     network->header[i].index = i - network->vStart;
212e2aaf10cSShri Abhyankar     for(j=0; j < network->nsubnet; j++) {
213e2aaf10cSShri Abhyankar       if((network->subnet[j].vStart <= i-network->vStart) && (i-network->vStart < network->subnet[j].vEnd)) {
214e2aaf10cSShri Abhyankar 	network->header[i].subnetid = j;
2152727e31bSShri Abhyankar 	network->subnet[j].vertices[network->subnet[j].nvtx++] = i;
216e2aaf10cSShri Abhyankar 	break;
217e2aaf10cSShri Abhyankar       }
218e2aaf10cSShri Abhyankar     }
219e2aaf10cSShri Abhyankar     network->header[i].ndata = 0;
220e2aaf10cSShri Abhyankar     ndata = network->header[i].ndata;
221e2aaf10cSShri Abhyankar     ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr);
222e2aaf10cSShri Abhyankar     network->header[i].offset[ndata] = 0;
223e2aaf10cSShri Abhyankar   }
224e2aaf10cSShri Abhyankar 
225854ce69bSBarry Smith   ierr = PetscMalloc1(network->pEnd-network->pStart,&network->cvalue);CHKERRQ(ierr);
226*6500d4abSHong Zhang   PetscFunctionReturn(0);
227*6500d4abSHong Zhang }
228e2aaf10cSShri Abhyankar 
229*6500d4abSHong Zhang 
230*6500d4abSHong Zhang PetscErrorCode DMNetworkLayoutSetUpCoupled(DM dm)
231*6500d4abSHong Zhang {
232*6500d4abSHong Zhang   PetscErrorCode ierr;
233*6500d4abSHong Zhang   DM_Network     *network = (DM_Network*) dm->data;
234*6500d4abSHong Zhang   PetscInt       dim = 1; /* One dimensional network */
235*6500d4abSHong Zhang   PetscInt       numCorners=2;
236*6500d4abSHong Zhang   PetscInt       spacedim=2;
237*6500d4abSHong Zhang   double         *vertexcoords=NULL;
238*6500d4abSHong Zhang   PetscInt       i,j;
239*6500d4abSHong Zhang   PetscInt       ndata;
240*6500d4abSHong Zhang   PetscInt       ctr=0;
241*6500d4abSHong Zhang 
242*6500d4abSHong Zhang   PetscFunctionBegin;
243*6500d4abSHong Zhang   printf("DMNetworkLayoutSetUpCoupled...\n");
244*6500d4abSHong Zhang   if (network->nVertices) {
245*6500d4abSHong Zhang     ierr = PetscCalloc1(numCorners*network->nVertices,&vertexcoords);CHKERRQ(ierr);
246*6500d4abSHong Zhang   }
247*6500d4abSHong Zhang 
248*6500d4abSHong Zhang   /* Create the edgelist for the network by concatenating edgelists of the subnetworks */
249*6500d4abSHong Zhang   ierr = PetscCalloc1(2*network->nEdges,&network->edges);CHKERRQ(ierr);
250*6500d4abSHong Zhang   for (i=0; i < network->nsubnet-1; i++) {
251*6500d4abSHong Zhang     for (j = 0; j < network->subnet[i].nedge; j++) {
252*6500d4abSHong Zhang       network->edges[2*ctr] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j];
253*6500d4abSHong Zhang       network->edges[2*ctr+1] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j+1];
254*6500d4abSHong Zhang       ctr++;
255*6500d4abSHong Zhang     }
256*6500d4abSHong Zhang   }
257*6500d4abSHong Zhang   i = network->nsubnet-1; /* coupling subnet */
258*6500d4abSHong Zhang   PetscInt *edgelist_couple = network->subnet[i].edgelist,k,netid,vid;
259*6500d4abSHong Zhang   k = 0;
260*6500d4abSHong Zhang   for (j = 0; j < network->subnet[i].nedge; j++) {
261*6500d4abSHong Zhang     netid = edgelist_couple[k]; vid = edgelist_couple[k+1];
262*6500d4abSHong Zhang     network->edges[2*ctr] = network->subnet[netid].vStart + vid; k += 2;
263*6500d4abSHong Zhang 
264*6500d4abSHong Zhang     netid = edgelist_couple[k]; vid = edgelist_couple[k+1];
265*6500d4abSHong Zhang     network->edges[2*ctr+1] = network->subnet[netid].vStart + vi; k+=2;
266*6500d4abSHong Zhang     ctr++;
267*6500d4abSHong Zhang   }
268*6500d4abSHong Zhang 
269*6500d4abSHong Zhang #if 1
270*6500d4abSHong Zhang   for(i=0; i < network->nEdges; i++) {
271*6500d4abSHong Zhang     ierr = PetscPrintf(PETSC_COMM_SELF,"[%D %D]",network->edges[2*i],network->edges[2*i+1]);CHKERRQ(ierr);
272*6500d4abSHong Zhang     printf("\n");
273*6500d4abSHong Zhang   }
274*6500d4abSHong Zhang #endif
275*6500d4abSHong Zhang 
276*6500d4abSHong Zhang   ierr = DMPlexCreateFromCellList(PetscObjectComm((PetscObject)dm),dim,network->nEdges,network->nVertices,numCorners,PETSC_FALSE,network->edges,spacedim,vertexcoords,&network->plex);CHKERRQ(ierr);
277*6500d4abSHong Zhang   if (network->nVertices) {
278*6500d4abSHong Zhang     ierr = PetscFree(vertexcoords);CHKERRQ(ierr);
279*6500d4abSHong Zhang   }
280*6500d4abSHong Zhang   ierr = PetscFree(network->edges);CHKERRQ(ierr);
281*6500d4abSHong Zhang 
282*6500d4abSHong Zhang   ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr);
283*6500d4abSHong Zhang   ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr);
284*6500d4abSHong Zhang   ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr);
285*6500d4abSHong Zhang 
286*6500d4abSHong Zhang   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm),&network->DataSection);CHKERRQ(ierr);
287*6500d4abSHong Zhang   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm),&network->DofSection);CHKERRQ(ierr);
288*6500d4abSHong Zhang   ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr);
289*6500d4abSHong Zhang   ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr);
290*6500d4abSHong Zhang 
291*6500d4abSHong Zhang   /* Create vertices and edges array for the subnetworks */
292*6500d4abSHong Zhang   for(j=0; j < network->nsubnet; j++) {
293*6500d4abSHong Zhang     ierr = PetscCalloc1(network->subnet[j].nedge,&network->subnet[j].edges);CHKERRQ(ierr);
294*6500d4abSHong Zhang     ierr = PetscCalloc1(network->subnet[j].nvtx,&network->subnet[j].vertices);CHKERRQ(ierr);
295*6500d4abSHong Zhang     /* Temporarily setting nvtx and nedge to 0 so we can use them as counters in the below for loop.
296*6500d4abSHong Zhang        These get updated when the vertices and edges are added. */
297*6500d4abSHong Zhang     network->subnet[j].nvtx = network->subnet[j].nedge = 0;
298*6500d4abSHong Zhang   }
299*6500d4abSHong Zhang 
300*6500d4abSHong Zhang   network->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType);
301*6500d4abSHong Zhang   ierr = PetscCalloc1(network->pEnd-network->pStart,&network->header);CHKERRQ(ierr);
302*6500d4abSHong Zhang   for(i=network->eStart; i < network->eEnd; i++) {
303*6500d4abSHong Zhang     network->header[i].index = i;   /* Global edge number */
304*6500d4abSHong Zhang     for(j=0; j < network->nsubnet; j++) {
305*6500d4abSHong Zhang       if((network->subnet[j].eStart <= i) && (i < network->subnet[j].eEnd)) {
306*6500d4abSHong Zhang 	network->header[i].subnetid = j; /* Subnetwork id */
307*6500d4abSHong Zhang 	network->subnet[j].edges[network->subnet[j].nedge++] = i;
308*6500d4abSHong Zhang 	break;
309*6500d4abSHong Zhang       }
310*6500d4abSHong Zhang     }
311*6500d4abSHong Zhang     network->header[i].ndata = 0;
312*6500d4abSHong Zhang     ndata = network->header[i].ndata;
313*6500d4abSHong Zhang     ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr);
314*6500d4abSHong Zhang     network->header[i].offset[ndata] = 0;
315*6500d4abSHong Zhang   }
316*6500d4abSHong Zhang 
317*6500d4abSHong Zhang   for(i=network->vStart; i < network->vEnd; i++) {
318*6500d4abSHong Zhang     network->header[i].index = i - network->vStart;
319*6500d4abSHong Zhang     for(j=0; j < network->nsubnet; j++) {
320*6500d4abSHong Zhang       if((network->subnet[j].vStart <= i-network->vStart) && (i-network->vStart < network->subnet[j].vEnd)) {
321*6500d4abSHong Zhang 	network->header[i].subnetid = j;
322*6500d4abSHong Zhang 	network->subnet[j].vertices[network->subnet[j].nvtx++] = i;
323*6500d4abSHong Zhang 	break;
324*6500d4abSHong Zhang       }
325*6500d4abSHong Zhang     }
326*6500d4abSHong Zhang     network->header[i].ndata = 0;
327*6500d4abSHong Zhang     ndata = network->header[i].ndata;
328*6500d4abSHong Zhang     ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr);
329*6500d4abSHong Zhang     network->header[i].offset[ndata] = 0;
330*6500d4abSHong Zhang   }
331*6500d4abSHong Zhang 
332*6500d4abSHong Zhang   ierr = PetscMalloc1(network->pEnd-network->pStart,&network->cvalue);CHKERRQ(ierr);
3335f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
3345f2c45f1SShri Abhyankar }
3355f2c45f1SShri Abhyankar 
33694ef8ddeSSatish Balay /*@C
3372727e31bSShri Abhyankar   DMNetworkGetSubnetworkInfo - Returns the info for the subnetwork
3382727e31bSShri Abhyankar 
3392727e31bSShri Abhyankar   Input Parameters
3402727e31bSShri Abhyankar + dm   - the number object
3412727e31bSShri Abhyankar - id   - the ID (integer) of the subnetwork
3422727e31bSShri Abhyankar 
3432727e31bSShri Abhyankar   Output Parameters
3442727e31bSShri Abhyankar + nv    - number of vertices (local)
3452727e31bSShri Abhyankar . ne    - number of edges (local)
3462727e31bSShri Abhyankar . vtx   - local vertices for this subnetwork
3472727e31bSShri Abhyankar . edge  - local edges for this subnetwork
3482727e31bSShri Abhyankar 
3492727e31bSShri Abhyankar   Notes:
3502727e31bSShri Abhyankar   Cannot call this routine before DMNetworkLayoutSetup()
3512727e31bSShri Abhyankar 
3522727e31bSShri Abhyankar .seealso: DMNetworkLayoutSetUp, DMNetworkCreate
3532727e31bSShri Abhyankar @*/
3542727e31bSShri Abhyankar PetscErrorCode DMNetworkGetSubnetworkInfo(DM netdm,PetscInt id,PetscInt *nv, PetscInt *ne,const PetscInt **vtx, const PetscInt **edge)
3552727e31bSShri Abhyankar {
3562727e31bSShri Abhyankar   DM_Network     *network = (DM_Network*) netdm->data;
3572727e31bSShri Abhyankar 
3582727e31bSShri Abhyankar   PetscFunctionBegin;
3592727e31bSShri Abhyankar   *nv = network->subnet[id].nvtx;
3602727e31bSShri Abhyankar   *ne = network->subnet[id].nedge;
3612727e31bSShri Abhyankar   *vtx = network->subnet[id].vertices;
3622727e31bSShri Abhyankar   *edge = network->subnet[id].edges;
3632727e31bSShri Abhyankar   PetscFunctionReturn(0);
3642727e31bSShri Abhyankar }
3652727e31bSShri Abhyankar 
3662727e31bSShri Abhyankar /*@C
3675f2c45f1SShri Abhyankar   DMNetworkRegisterComponent - Registers the network component
3685f2c45f1SShri Abhyankar 
3695f2c45f1SShri Abhyankar   Logically collective on DM
3705f2c45f1SShri Abhyankar 
3715f2c45f1SShri Abhyankar   Input Parameters
3725f2c45f1SShri Abhyankar + dm   - the network object
3735f2c45f1SShri Abhyankar . name - the component name
3745f2c45f1SShri Abhyankar - size - the storage size in bytes for this component data
3755f2c45f1SShri Abhyankar 
3765f2c45f1SShri Abhyankar    Output Parameters
3775f2c45f1SShri Abhyankar .   key - an integer key that defines the component
3785f2c45f1SShri Abhyankar 
3795f2c45f1SShri Abhyankar    Notes
3805f2c45f1SShri Abhyankar    This routine should be called by all processors before calling DMNetworkLayoutSetup().
3815f2c45f1SShri Abhyankar 
3825f2c45f1SShri Abhyankar    Level: intermediate
3835f2c45f1SShri Abhyankar 
3845f2c45f1SShri Abhyankar .seealso: DMNetworkLayoutSetUp, DMNetworkCreate
3855f2c45f1SShri Abhyankar @*/
3865f2c45f1SShri Abhyankar PetscErrorCode DMNetworkRegisterComponent(DM dm,const char *name,PetscInt size,PetscInt *key)
3875f2c45f1SShri Abhyankar {
3885f2c45f1SShri Abhyankar   PetscErrorCode        ierr;
3895f2c45f1SShri Abhyankar   DM_Network            *network = (DM_Network*) dm->data;
3905f2c45f1SShri Abhyankar   DMNetworkComponent    *component=&network->component[network->ncomponent];
3915f2c45f1SShri Abhyankar   PetscBool             flg=PETSC_FALSE;
3925f2c45f1SShri Abhyankar   PetscInt              i;
3935f2c45f1SShri Abhyankar 
3945f2c45f1SShri Abhyankar   PetscFunctionBegin;
3955f2c45f1SShri Abhyankar 
3965f2c45f1SShri Abhyankar   for (i=0; i < network->ncomponent; i++) {
3975f2c45f1SShri Abhyankar     ierr = PetscStrcmp(component->name,name,&flg);CHKERRQ(ierr);
3985f2c45f1SShri Abhyankar     if (flg) {
3995f2c45f1SShri Abhyankar       *key = i;
4005f2c45f1SShri Abhyankar       PetscFunctionReturn(0);
4015f2c45f1SShri Abhyankar     }
4026d64e262SShri Abhyankar   }
4036d64e262SShri Abhyankar   if(network->ncomponent == MAX_COMPONENTS) {
4046d64e262SShri Abhyankar     SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Number of components registered exceeds the max %D",MAX_COMPONENTS);
4055f2c45f1SShri Abhyankar   }
4065f2c45f1SShri Abhyankar 
4075f2c45f1SShri Abhyankar   ierr = PetscStrcpy(component->name,name);CHKERRQ(ierr);
4085f2c45f1SShri Abhyankar   component->size = size/sizeof(DMNetworkComponentGenericDataType);
4095f2c45f1SShri Abhyankar   *key = network->ncomponent;
4105f2c45f1SShri Abhyankar   network->ncomponent++;
4115f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
4125f2c45f1SShri Abhyankar }
4135f2c45f1SShri Abhyankar 
4145f2c45f1SShri Abhyankar /*@
4155f2c45f1SShri Abhyankar   DMNetworkGetVertexRange - Get the bounds [start, end) for the vertices.
4165f2c45f1SShri Abhyankar 
4175f2c45f1SShri Abhyankar   Not Collective
4185f2c45f1SShri Abhyankar 
4195f2c45f1SShri Abhyankar   Input Parameters:
4205f2c45f1SShri Abhyankar + dm - The DMNetwork object
4215f2c45f1SShri Abhyankar 
4225f2c45f1SShri Abhyankar   Output Paramters:
4235f2c45f1SShri Abhyankar + vStart - The first vertex point
4245f2c45f1SShri Abhyankar - vEnd   - One beyond the last vertex point
4255f2c45f1SShri Abhyankar 
4265f2c45f1SShri Abhyankar   Level: intermediate
4275f2c45f1SShri Abhyankar 
4285f2c45f1SShri Abhyankar .seealso: DMNetworkGetEdgeRange
4295f2c45f1SShri Abhyankar @*/
4305f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVertexRange(DM dm,PetscInt *vStart,PetscInt *vEnd)
4315f2c45f1SShri Abhyankar {
4325f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
4335f2c45f1SShri Abhyankar 
4345f2c45f1SShri Abhyankar   PetscFunctionBegin;
4355f2c45f1SShri Abhyankar   if (vStart) *vStart = network->vStart;
4365f2c45f1SShri Abhyankar   if (vEnd) *vEnd = network->vEnd;
4375f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
4385f2c45f1SShri Abhyankar }
4395f2c45f1SShri Abhyankar 
4405f2c45f1SShri Abhyankar /*@
4415f2c45f1SShri Abhyankar   DMNetworkGetEdgeRange - Get the bounds [start, end) for the edges.
4425f2c45f1SShri Abhyankar 
4435f2c45f1SShri Abhyankar   Not Collective
4445f2c45f1SShri Abhyankar 
4455f2c45f1SShri Abhyankar   Input Parameters:
4465f2c45f1SShri Abhyankar + dm - The DMNetwork object
4475f2c45f1SShri Abhyankar 
4485f2c45f1SShri Abhyankar   Output Paramters:
4495f2c45f1SShri Abhyankar + eStart - The first edge point
4505f2c45f1SShri Abhyankar - eEnd   - One beyond the last edge point
4515f2c45f1SShri Abhyankar 
4525f2c45f1SShri Abhyankar   Level: intermediate
4535f2c45f1SShri Abhyankar 
4545f2c45f1SShri Abhyankar .seealso: DMNetworkGetVertexRange
4555f2c45f1SShri Abhyankar @*/
4565f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetEdgeRange(DM dm,PetscInt *eStart,PetscInt *eEnd)
4575f2c45f1SShri Abhyankar {
4585f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
4595f2c45f1SShri Abhyankar 
4605f2c45f1SShri Abhyankar   PetscFunctionBegin;
4615f2c45f1SShri Abhyankar   if (eStart) *eStart = network->eStart;
4625f2c45f1SShri Abhyankar   if (eEnd) *eEnd = network->eEnd;
4635f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
4645f2c45f1SShri Abhyankar }
4655f2c45f1SShri Abhyankar 
4667b6afd5bSHong Zhang /*@
467e85e6aecSHong Zhang   DMNetworkGetGlobalEdgeIndex - Get the user global numbering for the edge.
4687b6afd5bSHong Zhang 
4697b6afd5bSHong Zhang   Not Collective
4707b6afd5bSHong Zhang 
4717b6afd5bSHong Zhang   Input Parameters:
4727b6afd5bSHong Zhang + dm - DMNetwork object
473e85e6aecSHong Zhang - p  - edge point
4747b6afd5bSHong Zhang 
4757b6afd5bSHong Zhang   Output Paramters:
476e85e6aecSHong Zhang . index - user global numbering for the edge
4777b6afd5bSHong Zhang 
4787b6afd5bSHong Zhang   Level: intermediate
4797b6afd5bSHong Zhang 
480e85e6aecSHong Zhang .seealso: DMNetworkGetGlobalVertexIndex
4817b6afd5bSHong Zhang @*/
482e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalEdgeIndex(DM dm,PetscInt p,PetscInt *index)
4837b6afd5bSHong Zhang {
4847b6afd5bSHong Zhang   PetscErrorCode    ierr;
4857b6afd5bSHong Zhang   DM_Network        *network = (DM_Network*)dm->data;
4867b6afd5bSHong Zhang   PetscInt          offsetp;
4877b6afd5bSHong Zhang   DMNetworkComponentHeader header;
4887b6afd5bSHong Zhang 
4897b6afd5bSHong Zhang   PetscFunctionBegin;
4907b6afd5bSHong Zhang   ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr);
4917b6afd5bSHong Zhang   header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp);
492e85e6aecSHong Zhang   *index = header->index;
4937b6afd5bSHong Zhang   PetscFunctionReturn(0);
4947b6afd5bSHong Zhang }
4957b6afd5bSHong Zhang 
4965f2c45f1SShri Abhyankar /*@
497e85e6aecSHong Zhang   DMNetworkGetGlobalVertexIndex - Get the user global numbering for the vertex.
498e85e6aecSHong Zhang 
499e85e6aecSHong Zhang   Not Collective
500e85e6aecSHong Zhang 
501e85e6aecSHong Zhang   Input Parameters:
502e85e6aecSHong Zhang + dm - DMNetwork object
503e85e6aecSHong Zhang - p  - vertex point
504e85e6aecSHong Zhang 
505e85e6aecSHong Zhang   Output Paramters:
506e85e6aecSHong Zhang . index - user global numbering for the vertex
507e85e6aecSHong Zhang 
508e85e6aecSHong Zhang   Level: intermediate
509e85e6aecSHong Zhang 
510e85e6aecSHong Zhang .seealso: DMNetworkGetGlobalEdgeIndex
511e85e6aecSHong Zhang @*/
512e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalVertexIndex(DM dm,PetscInt p,PetscInt *index)
513e85e6aecSHong Zhang {
514e85e6aecSHong Zhang   PetscErrorCode    ierr;
515e85e6aecSHong Zhang   DM_Network        *network = (DM_Network*)dm->data;
516e85e6aecSHong Zhang   PetscInt          offsetp;
517e85e6aecSHong Zhang   DMNetworkComponentHeader header;
518e85e6aecSHong Zhang 
519e85e6aecSHong Zhang   PetscFunctionBegin;
520e85e6aecSHong Zhang   ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr);
521e85e6aecSHong Zhang   header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp);
522e85e6aecSHong Zhang   *index = header->index;
523e85e6aecSHong Zhang   PetscFunctionReturn(0);
524e85e6aecSHong Zhang }
525e85e6aecSHong Zhang 
526c3b11c7cSShri Abhyankar /*
527c3b11c7cSShri Abhyankar   DMNetworkGetComponentKeyOffset - Gets the type along with the offset for indexing the
528c3b11c7cSShri Abhyankar                                     component value from the component data array
529c3b11c7cSShri Abhyankar 
530c3b11c7cSShri Abhyankar   Not Collective
531c3b11c7cSShri Abhyankar 
532c3b11c7cSShri Abhyankar   Input Parameters:
533c3b11c7cSShri Abhyankar + dm      - The DMNetwork object
534c3b11c7cSShri Abhyankar . p       - vertex/edge point
535c3b11c7cSShri Abhyankar - compnum - component number
536c3b11c7cSShri Abhyankar 
537c3b11c7cSShri Abhyankar   Output Parameters:
538c3b11c7cSShri Abhyankar + compkey - the key obtained when registering the component
539c3b11c7cSShri Abhyankar - offset  - offset into the component data array associated with the vertex/edge point
540c3b11c7cSShri Abhyankar 
541c3b11c7cSShri Abhyankar   Notes:
542c3b11c7cSShri Abhyankar   Typical usage:
543c3b11c7cSShri Abhyankar 
544c3b11c7cSShri Abhyankar   DMNetworkGetComponentDataArray(dm, &arr);
545c3b11c7cSShri Abhyankar   DMNetworkGetVertex/EdgeRange(dm,&Start,&End);
546c3b11c7cSShri Abhyankar   Loop over vertices or edges
547c3b11c7cSShri Abhyankar     DMNetworkGetNumComponents(dm,v,&numcomps);
548c3b11c7cSShri Abhyankar     Loop over numcomps
549c3b11c7cSShri Abhyankar       DMNetworkGetComponentKeyOffset(dm,v,compnum,&key,&offset);
550c3b11c7cSShri Abhyankar       compdata = (UserCompDataType)(arr+offset);
551c3b11c7cSShri Abhyankar 
552c3b11c7cSShri Abhyankar   Level: intermediate
553c3b11c7cSShri Abhyankar 
554c3b11c7cSShri Abhyankar .seealso: DMNetworkGetNumComponents, DMNetworkGetComponentDataArray,
555c3b11c7cSShri Abhyankar */
556c3b11c7cSShri Abhyankar PetscErrorCode DMNetworkGetComponentKeyOffset(DM dm,PetscInt p, PetscInt compnum, PetscInt *compkey, PetscInt *offset)
557c3b11c7cSShri Abhyankar {
558c3b11c7cSShri Abhyankar   PetscErrorCode           ierr;
559c3b11c7cSShri Abhyankar   PetscInt                 offsetp;
560c3b11c7cSShri Abhyankar   DMNetworkComponentHeader header;
561c3b11c7cSShri Abhyankar   DM_Network               *network = (DM_Network*)dm->data;
562c3b11c7cSShri Abhyankar 
563c3b11c7cSShri Abhyankar   PetscFunctionBegin;
564c3b11c7cSShri Abhyankar   ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr);
565c3b11c7cSShri Abhyankar   header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp);
566c3b11c7cSShri Abhyankar   if (compkey) *compkey = header->key[compnum];
567c3b11c7cSShri Abhyankar   if (offset) *offset  = offsetp+network->dataheadersize+header->offset[compnum];
568c3b11c7cSShri Abhyankar   PetscFunctionReturn(0);
569c3b11c7cSShri Abhyankar }
570c3b11c7cSShri Abhyankar 
571c3b11c7cSShri Abhyankar /*@
572c3b11c7cSShri Abhyankar   DMNetworkGetComponent - Returns the network component and its key
573c3b11c7cSShri Abhyankar 
574c3b11c7cSShri Abhyankar   Not Collective
575c3b11c7cSShri Abhyankar 
576c3b11c7cSShri Abhyankar   Input Parameters
577c3b11c7cSShri Abhyankar + dm - DMNetwork object
578c3b11c7cSShri Abhyankar . p  - edge or vertex point
579c3b11c7cSShri Abhyankar - compnum - component number
580c3b11c7cSShri Abhyankar 
581c3b11c7cSShri Abhyankar   Output Parameters:
582c3b11c7cSShri Abhyankar + compkey - the key set for this computing during registration
583c3b11c7cSShri Abhyankar - component - the component data
584c3b11c7cSShri Abhyankar 
585c3b11c7cSShri Abhyankar   Notes:
586c3b11c7cSShri Abhyankar   Typical usage:
587c3b11c7cSShri Abhyankar 
588c3b11c7cSShri Abhyankar   DMNetworkGetVertex/EdgeRange(dm,&Start,&End);
589c3b11c7cSShri Abhyankar   Loop over vertices or edges
590c3b11c7cSShri Abhyankar     DMNetworkGetNumComponents(dm,v,&numcomps);
591c3b11c7cSShri Abhyankar     Loop over numcomps
592c3b11c7cSShri Abhyankar       DMNetworkGetComponent(dm,v,compnum,&key,&component);
593c3b11c7cSShri Abhyankar 
594c3b11c7cSShri Abhyankar   Level: intermediate
595c3b11c7cSShri Abhyankar 
596c3b11c7cSShri Abhyankar .seealso: DMNetworkGetNumComponents, DMNetworkGetVariableOffset
597c3b11c7cSShri Abhyankar @*/
598c3b11c7cSShri Abhyankar PetscErrorCode DMNetworkGetComponent(DM dm, PetscInt p, PetscInt compnum, PetscInt *key, void **component)
599c3b11c7cSShri Abhyankar {
600c3b11c7cSShri Abhyankar   PetscErrorCode ierr;
601c3b11c7cSShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
602c3b11c7cSShri Abhyankar   PetscInt       offsetd;
603c3b11c7cSShri Abhyankar 
604c3b11c7cSShri Abhyankar   PetscFunctionBegin;
605c3b11c7cSShri Abhyankar 
606c3b11c7cSShri Abhyankar   ierr = DMNetworkGetComponentKeyOffset(dm,p,compnum,key,&offsetd);CHKERRQ(ierr);
607c3b11c7cSShri Abhyankar   *component = network->componentdataarray+offsetd;
608c3b11c7cSShri Abhyankar 
609c3b11c7cSShri Abhyankar   PetscFunctionReturn(0);
610c3b11c7cSShri Abhyankar }
611c3b11c7cSShri Abhyankar 
612e85e6aecSHong Zhang /*@
613325661f6SSatish Balay   DMNetworkAddComponent - Adds a network component at the given point (vertex/edge)
6145f2c45f1SShri Abhyankar 
6155f2c45f1SShri Abhyankar   Not Collective
6165f2c45f1SShri Abhyankar 
6175f2c45f1SShri Abhyankar   Input Parameters:
6185f2c45f1SShri Abhyankar + dm           - The DMNetwork object
6195f2c45f1SShri Abhyankar . p            - vertex/edge point
6205f2c45f1SShri Abhyankar . componentkey - component key returned while registering the component
6215f2c45f1SShri Abhyankar - compvalue    - pointer to the data structure for the component
6225f2c45f1SShri Abhyankar 
6235f2c45f1SShri Abhyankar   Level: intermediate
6245f2c45f1SShri Abhyankar 
6255f2c45f1SShri Abhyankar .seealso: DMNetworkGetVertexRange, DMNetworkGetEdgeRange, DMNetworkRegisterComponent
6265f2c45f1SShri Abhyankar @*/
6275f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddComponent(DM dm, PetscInt p,PetscInt componentkey,void* compvalue)
6285f2c45f1SShri Abhyankar {
6295f2c45f1SShri Abhyankar   DM_Network               *network = (DM_Network*)dm->data;
63043a39a44SBarry Smith   DMNetworkComponent       *component = &network->component[componentkey];
6315f2c45f1SShri Abhyankar   DMNetworkComponentHeader header = &network->header[p];
6325f2c45f1SShri Abhyankar   DMNetworkComponentValue  cvalue = &network->cvalue[p];
6335f2c45f1SShri Abhyankar   PetscErrorCode           ierr;
6345f2c45f1SShri Abhyankar 
6355f2c45f1SShri Abhyankar   PetscFunctionBegin;
636fa58f0a9SHong 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);
637fa58f0a9SHong Zhang 
63843a39a44SBarry Smith   header->size[header->ndata] = component->size;
63943a39a44SBarry Smith   ierr = PetscSectionAddDof(network->DataSection,p,component->size);CHKERRQ(ierr);
6405f2c45f1SShri Abhyankar   header->key[header->ndata] = componentkey;
6415f2c45f1SShri Abhyankar   if (header->ndata != 0) header->offset[header->ndata] = header->offset[header->ndata-1] + header->size[header->ndata-1];
6425f2c45f1SShri Abhyankar 
6435f2c45f1SShri Abhyankar   cvalue->data[header->ndata] = (void*)compvalue;
6445f2c45f1SShri Abhyankar   header->ndata++;
6455f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
6465f2c45f1SShri Abhyankar }
6475f2c45f1SShri Abhyankar 
6485f2c45f1SShri Abhyankar /*@
6495f2c45f1SShri Abhyankar   DMNetworkGetNumComponents - Get the number of components at a vertex/edge
6505f2c45f1SShri Abhyankar 
6515f2c45f1SShri Abhyankar   Not Collective
6525f2c45f1SShri Abhyankar 
6535f2c45f1SShri Abhyankar   Input Parameters:
6545f2c45f1SShri Abhyankar + dm - The DMNetwork object
6555f2c45f1SShri Abhyankar . p  - vertex/edge point
6565f2c45f1SShri Abhyankar 
6575f2c45f1SShri Abhyankar   Output Parameters:
6585f2c45f1SShri Abhyankar . numcomponents - Number of components at the vertex/edge
6595f2c45f1SShri Abhyankar 
6605f2c45f1SShri Abhyankar   Level: intermediate
6615f2c45f1SShri Abhyankar 
6625f2c45f1SShri Abhyankar .seealso: DMNetworkRegisterComponent, DMNetworkAddComponent
6635f2c45f1SShri Abhyankar @*/
6645f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetNumComponents(DM dm,PetscInt p,PetscInt *numcomponents)
6655f2c45f1SShri Abhyankar {
6665f2c45f1SShri Abhyankar   PetscErrorCode ierr;
6675f2c45f1SShri Abhyankar   PetscInt       offset;
6685f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
6695f2c45f1SShri Abhyankar 
6705f2c45f1SShri Abhyankar   PetscFunctionBegin;
6715f2c45f1SShri Abhyankar   ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr);
6725f2c45f1SShri Abhyankar   *numcomponents = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata;
6735f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
6745f2c45f1SShri Abhyankar }
6755f2c45f1SShri Abhyankar 
6765f2c45f1SShri Abhyankar /*@
6775f2c45f1SShri Abhyankar   DMNetworkGetVariableOffset - Get the offset for accessing the variable associated with the given vertex/edge from the local vector.
6785f2c45f1SShri Abhyankar 
6795f2c45f1SShri Abhyankar   Not Collective
6805f2c45f1SShri Abhyankar 
6815f2c45f1SShri Abhyankar   Input Parameters:
6825f2c45f1SShri Abhyankar + dm     - The DMNetwork object
6835f2c45f1SShri Abhyankar - p      - the edge/vertex point
6845f2c45f1SShri Abhyankar 
6855f2c45f1SShri Abhyankar   Output Parameters:
6865f2c45f1SShri Abhyankar . offset - the offset
6875f2c45f1SShri Abhyankar 
6885f2c45f1SShri Abhyankar   Level: intermediate
6895f2c45f1SShri Abhyankar 
6905f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector
6915f2c45f1SShri Abhyankar @*/
6925f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableOffset(DM dm,PetscInt p,PetscInt *offset)
6935f2c45f1SShri Abhyankar {
6945f2c45f1SShri Abhyankar   PetscErrorCode ierr;
6955f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
6965f2c45f1SShri Abhyankar 
6975f2c45f1SShri Abhyankar   PetscFunctionBegin;
6985f78ed8bSShri Abhyankar   ierr = PetscSectionGetOffset(network->plex->defaultSection,p,offset);CHKERRQ(ierr);
6995f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
7005f2c45f1SShri Abhyankar }
7015f2c45f1SShri Abhyankar 
7025f2c45f1SShri Abhyankar /*@
7035f2c45f1SShri Abhyankar   DMNetworkGetVariableGlobalOffset - Get the global offset for the variable associated with the given vertex/edge from the global vector.
7045f2c45f1SShri Abhyankar 
7055f2c45f1SShri Abhyankar   Not Collective
7065f2c45f1SShri Abhyankar 
7075f2c45f1SShri Abhyankar   Input Parameters:
7085f2c45f1SShri Abhyankar + dm      - The DMNetwork object
7095f2c45f1SShri Abhyankar - p       - the edge/vertex point
7105f2c45f1SShri Abhyankar 
7115f2c45f1SShri Abhyankar   Output Parameters:
7125f2c45f1SShri Abhyankar . offsetg - the offset
7135f2c45f1SShri Abhyankar 
7145f2c45f1SShri Abhyankar   Level: intermediate
7155f2c45f1SShri Abhyankar 
7165f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableOffset, DMGetLocalVector
7175f2c45f1SShri Abhyankar @*/
7185f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableGlobalOffset(DM dm,PetscInt p,PetscInt *offsetg)
7195f2c45f1SShri Abhyankar {
7205f2c45f1SShri Abhyankar   PetscErrorCode ierr;
7215f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
7225f2c45f1SShri Abhyankar 
7235f2c45f1SShri Abhyankar   PetscFunctionBegin;
7245f78ed8bSShri Abhyankar   ierr = PetscSectionGetOffset(network->plex->defaultGlobalSection,p,offsetg);CHKERRQ(ierr);
7256fefedf4SHong Zhang   if (*offsetg < 0) *offsetg = -(*offsetg + 1); /* Convert to actual global offset for ghost vertex */
7265f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
7275f2c45f1SShri Abhyankar }
7285f2c45f1SShri Abhyankar 
72924121865SAdrian Maldonado /*@
73024121865SAdrian Maldonado   DMNetworkGetEdgeOffset - Get the offset for accessing the variable associated with the given edge from the local subvector.
73124121865SAdrian Maldonado 
73224121865SAdrian Maldonado   Not Collective
73324121865SAdrian Maldonado 
73424121865SAdrian Maldonado   Input Parameters:
73524121865SAdrian Maldonado + dm     - The DMNetwork object
73624121865SAdrian Maldonado - p      - the edge point
73724121865SAdrian Maldonado 
73824121865SAdrian Maldonado   Output Parameters:
73924121865SAdrian Maldonado . offset - the offset
74024121865SAdrian Maldonado 
74124121865SAdrian Maldonado   Level: intermediate
74224121865SAdrian Maldonado 
74324121865SAdrian Maldonado .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector
74424121865SAdrian Maldonado @*/
74524121865SAdrian Maldonado PetscErrorCode DMNetworkGetEdgeOffset(DM dm,PetscInt p,PetscInt *offset)
74624121865SAdrian Maldonado {
74724121865SAdrian Maldonado   PetscErrorCode ierr;
74824121865SAdrian Maldonado   DM_Network     *network = (DM_Network*)dm->data;
74924121865SAdrian Maldonado 
75024121865SAdrian Maldonado   PetscFunctionBegin;
75124121865SAdrian Maldonado 
75224121865SAdrian Maldonado   ierr = PetscSectionGetOffset(network->edge.DofSection,p,offset);CHKERRQ(ierr);
75324121865SAdrian Maldonado   PetscFunctionReturn(0);
75424121865SAdrian Maldonado }
75524121865SAdrian Maldonado 
75624121865SAdrian Maldonado /*@
75724121865SAdrian Maldonado   DMNetworkGetVertexOffset - Get the offset for accessing the variable associated with the given vertex from the local subvector.
75824121865SAdrian Maldonado 
75924121865SAdrian Maldonado   Not Collective
76024121865SAdrian Maldonado 
76124121865SAdrian Maldonado   Input Parameters:
76224121865SAdrian Maldonado + dm     - The DMNetwork object
76324121865SAdrian Maldonado - p      - the vertex point
76424121865SAdrian Maldonado 
76524121865SAdrian Maldonado   Output Parameters:
76624121865SAdrian Maldonado . offset - the offset
76724121865SAdrian Maldonado 
76824121865SAdrian Maldonado   Level: intermediate
76924121865SAdrian Maldonado 
77024121865SAdrian Maldonado .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector
77124121865SAdrian Maldonado @*/
77224121865SAdrian Maldonado PetscErrorCode DMNetworkGetVertexOffset(DM dm,PetscInt p,PetscInt *offset)
77324121865SAdrian Maldonado {
77424121865SAdrian Maldonado   PetscErrorCode ierr;
77524121865SAdrian Maldonado   DM_Network     *network = (DM_Network*)dm->data;
77624121865SAdrian Maldonado 
77724121865SAdrian Maldonado   PetscFunctionBegin;
77824121865SAdrian Maldonado 
77924121865SAdrian Maldonado   p -= network->vStart;
78024121865SAdrian Maldonado 
78124121865SAdrian Maldonado   ierr = PetscSectionGetOffset(network->vertex.DofSection,p,offset);CHKERRQ(ierr);
78224121865SAdrian Maldonado   PetscFunctionReturn(0);
78324121865SAdrian Maldonado }
7845f2c45f1SShri Abhyankar /*@
7855f2c45f1SShri Abhyankar   DMNetworkAddNumVariables - Add number of variables associated with a given point.
7865f2c45f1SShri Abhyankar 
7875f2c45f1SShri Abhyankar   Not Collective
7885f2c45f1SShri Abhyankar 
7895f2c45f1SShri Abhyankar   Input Parameters:
7905f2c45f1SShri Abhyankar + dm   - The DMNetworkObject
7915f2c45f1SShri Abhyankar . p    - the vertex/edge point
7925f2c45f1SShri Abhyankar - nvar - number of additional variables
7935f2c45f1SShri Abhyankar 
7945f2c45f1SShri Abhyankar   Level: intermediate
7955f2c45f1SShri Abhyankar 
7965f2c45f1SShri Abhyankar .seealso: DMNetworkSetNumVariables
7975f2c45f1SShri Abhyankar @*/
7985f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddNumVariables(DM dm,PetscInt p,PetscInt nvar)
7995f2c45f1SShri Abhyankar {
8005f2c45f1SShri Abhyankar   PetscErrorCode ierr;
8015f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
8025f2c45f1SShri Abhyankar 
8035f2c45f1SShri Abhyankar   PetscFunctionBegin;
8045f2c45f1SShri Abhyankar   ierr = PetscSectionAddDof(network->DofSection,p,nvar);CHKERRQ(ierr);
8055f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
8065f2c45f1SShri Abhyankar }
8075f2c45f1SShri Abhyankar 
80827f51fceSHong Zhang /*@
80927f51fceSHong Zhang   DMNetworkGetNumVariables - Gets number of variables for a vertex/edge point.
81027f51fceSHong Zhang 
81127f51fceSHong Zhang   Not Collective
81227f51fceSHong Zhang 
81327f51fceSHong Zhang   Input Parameters:
81427f51fceSHong Zhang + dm   - The DMNetworkObject
81527f51fceSHong Zhang - p    - the vertex/edge point
81627f51fceSHong Zhang 
81727f51fceSHong Zhang   Output Parameters:
81827f51fceSHong Zhang . nvar - number of variables
81927f51fceSHong Zhang 
82027f51fceSHong Zhang   Level: intermediate
82127f51fceSHong Zhang 
82227f51fceSHong Zhang .seealso: DMNetworkAddNumVariables, DMNetworkSddNumVariables
82327f51fceSHong Zhang @*/
82427f51fceSHong Zhang PetscErrorCode DMNetworkGetNumVariables(DM dm,PetscInt p,PetscInt *nvar)
82527f51fceSHong Zhang {
82627f51fceSHong Zhang   PetscErrorCode ierr;
82727f51fceSHong Zhang   DM_Network     *network = (DM_Network*)dm->data;
82827f51fceSHong Zhang 
82927f51fceSHong Zhang   PetscFunctionBegin;
83027f51fceSHong Zhang   ierr = PetscSectionGetDof(network->DofSection,p,nvar);CHKERRQ(ierr);
83127f51fceSHong Zhang   PetscFunctionReturn(0);
83227f51fceSHong Zhang }
83327f51fceSHong Zhang 
8345f2c45f1SShri Abhyankar /*@
8355f2c45f1SShri Abhyankar   DMNetworkSetNumVariables - Sets number of variables for a vertex/edge point.
8365f2c45f1SShri Abhyankar 
8375f2c45f1SShri Abhyankar   Not Collective
8385f2c45f1SShri Abhyankar 
8395f2c45f1SShri Abhyankar   Input Parameters:
8405f2c45f1SShri Abhyankar + dm   - The DMNetworkObject
8415f2c45f1SShri Abhyankar . p    - the vertex/edge point
8425f2c45f1SShri Abhyankar - nvar - number of variables
8435f2c45f1SShri Abhyankar 
8445f2c45f1SShri Abhyankar   Level: intermediate
8455f2c45f1SShri Abhyankar 
8465f2c45f1SShri Abhyankar .seealso: DMNetworkAddNumVariables
8475f2c45f1SShri Abhyankar @*/
8485f2c45f1SShri Abhyankar PetscErrorCode DMNetworkSetNumVariables(DM dm,PetscInt p,PetscInt nvar)
8495f2c45f1SShri Abhyankar {
8505f2c45f1SShri Abhyankar   PetscErrorCode ierr;
8515f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
8525f2c45f1SShri Abhyankar 
8535f2c45f1SShri Abhyankar   PetscFunctionBegin;
8545f2c45f1SShri Abhyankar   ierr = PetscSectionSetDof(network->DofSection,p,nvar);CHKERRQ(ierr);
8555f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
8565f2c45f1SShri Abhyankar }
8575f2c45f1SShri Abhyankar 
8585f2c45f1SShri Abhyankar /* Sets up the array that holds the data for all components and its associated section. This
8595f2c45f1SShri Abhyankar    function is called during DMSetUp() */
8605f2c45f1SShri Abhyankar PetscErrorCode DMNetworkComponentSetUp(DM dm)
8615f2c45f1SShri Abhyankar {
8625f2c45f1SShri Abhyankar   PetscErrorCode              ierr;
8635f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
8645f2c45f1SShri Abhyankar   PetscInt                    arr_size;
8655f2c45f1SShri Abhyankar   PetscInt                    p,offset,offsetp;
8665f2c45f1SShri Abhyankar   DMNetworkComponentHeader header;
8675f2c45f1SShri Abhyankar   DMNetworkComponentValue  cvalue;
8685f2c45f1SShri Abhyankar   DMNetworkComponentGenericDataType      *componentdataarray;
8695f2c45f1SShri Abhyankar   PetscInt ncomp, i;
8705f2c45f1SShri Abhyankar 
8715f2c45f1SShri Abhyankar   PetscFunctionBegin;
8725f2c45f1SShri Abhyankar   ierr = PetscSectionSetUp(network->DataSection);CHKERRQ(ierr);
8735f2c45f1SShri Abhyankar   ierr = PetscSectionGetStorageSize(network->DataSection,&arr_size);CHKERRQ(ierr);
87475b160a0SShri Abhyankar   ierr = PetscMalloc1(arr_size,&network->componentdataarray);CHKERRQ(ierr);
8755f2c45f1SShri Abhyankar   componentdataarray = network->componentdataarray;
8765f2c45f1SShri Abhyankar   for (p = network->pStart; p < network->pEnd; p++) {
8775f2c45f1SShri Abhyankar     ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr);
8785f2c45f1SShri Abhyankar     /* Copy header */
8795f2c45f1SShri Abhyankar     header = &network->header[p];
880302440fdSBarry Smith     ierr = PetscMemcpy(componentdataarray+offsetp,header,network->dataheadersize*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr);
8815f2c45f1SShri Abhyankar     /* Copy data */
8825f2c45f1SShri Abhyankar     cvalue = &network->cvalue[p];
8835f2c45f1SShri Abhyankar     ncomp = header->ndata;
8845f2c45f1SShri Abhyankar     for (i = 0; i < ncomp; i++) {
8855f2c45f1SShri Abhyankar       offset = offsetp + network->dataheadersize + header->offset[i];
886302440fdSBarry Smith       ierr = PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr);
8875f2c45f1SShri Abhyankar     }
8885f2c45f1SShri Abhyankar   }
8895f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
8905f2c45f1SShri Abhyankar }
8915f2c45f1SShri Abhyankar 
8925f2c45f1SShri Abhyankar /* Sets up the section for dofs. This routine is called during DMSetUp() */
8935f2c45f1SShri Abhyankar PetscErrorCode DMNetworkVariablesSetUp(DM dm)
8945f2c45f1SShri Abhyankar {
8955f2c45f1SShri Abhyankar   PetscErrorCode ierr;
8965f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
8975f2c45f1SShri Abhyankar 
8985f2c45f1SShri Abhyankar   PetscFunctionBegin;
8995f2c45f1SShri Abhyankar   ierr = PetscSectionSetUp(network->DofSection);CHKERRQ(ierr);
9005f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
9015f2c45f1SShri Abhyankar }
9025f2c45f1SShri Abhyankar 
9035f2c45f1SShri Abhyankar /*@C
9045f2c45f1SShri Abhyankar   DMNetworkGetComponentDataArray - Returns the component data array
9055f2c45f1SShri Abhyankar 
9065f2c45f1SShri Abhyankar   Not Collective
9075f2c45f1SShri Abhyankar 
9085f2c45f1SShri Abhyankar   Input Parameters:
9095f2c45f1SShri Abhyankar . dm - The DMNetwork Object
9105f2c45f1SShri Abhyankar 
9115f2c45f1SShri Abhyankar   Output Parameters:
9125f2c45f1SShri Abhyankar . componentdataarray - array that holds data for all components
9135f2c45f1SShri Abhyankar 
9145f2c45f1SShri Abhyankar   Level: intermediate
9155f2c45f1SShri Abhyankar 
916a730d845SHong Zhang .seealso: DMNetworkGetComponentKeyOffset, DMNetworkGetNumComponents
9175f2c45f1SShri Abhyankar @*/
9185f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetComponentDataArray(DM dm,DMNetworkComponentGenericDataType **componentdataarray)
9195f2c45f1SShri Abhyankar {
9205f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
9215f2c45f1SShri Abhyankar 
9225f2c45f1SShri Abhyankar   PetscFunctionBegin;
9235f2c45f1SShri Abhyankar   *componentdataarray = network->componentdataarray;
9245f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
9255f2c45f1SShri Abhyankar }
9265f2c45f1SShri Abhyankar 
92724121865SAdrian Maldonado /* Get a subsection from a range of points */
92824121865SAdrian Maldonado PetscErrorCode DMNetworkGetSubSection_private(PetscSection master, PetscInt pstart, PetscInt pend,PetscSection *subsection)
92924121865SAdrian Maldonado {
93024121865SAdrian Maldonado   PetscErrorCode ierr;
93124121865SAdrian Maldonado   PetscInt       i, nvar;
93224121865SAdrian Maldonado 
93324121865SAdrian Maldonado   PetscFunctionBegin;
93424121865SAdrian Maldonado   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)master), subsection);CHKERRQ(ierr);
93524121865SAdrian Maldonado   ierr = PetscSectionSetChart(*subsection, 0, pend - pstart);CHKERRQ(ierr);
93624121865SAdrian Maldonado   for (i = pstart; i < pend; i++) {
93724121865SAdrian Maldonado     ierr = PetscSectionGetDof(master,i,&nvar);CHKERRQ(ierr);
93824121865SAdrian Maldonado     ierr = PetscSectionSetDof(*subsection, i - pstart, nvar);CHKERRQ(ierr);
93924121865SAdrian Maldonado   }
94024121865SAdrian Maldonado 
94124121865SAdrian Maldonado   ierr = PetscSectionSetUp(*subsection);CHKERRQ(ierr);
94224121865SAdrian Maldonado   PetscFunctionReturn(0);
94324121865SAdrian Maldonado }
94424121865SAdrian Maldonado 
94524121865SAdrian Maldonado /* Create a submap of points with a GlobalToLocal structure */
94624121865SAdrian Maldonado PetscErrorCode DMNetworkSetSubMap_private(PetscInt pstart, PetscInt pend, ISLocalToGlobalMapping *map)
94724121865SAdrian Maldonado {
94824121865SAdrian Maldonado   PetscErrorCode ierr;
94924121865SAdrian Maldonado   PetscInt       i, *subpoints;
95024121865SAdrian Maldonado 
95124121865SAdrian Maldonado   PetscFunctionBegin;
95224121865SAdrian Maldonado   /* Create index sets to map from "points" to "subpoints" */
95324121865SAdrian Maldonado   ierr = PetscMalloc1(pend - pstart, &subpoints);CHKERRQ(ierr);
95424121865SAdrian Maldonado   for (i = pstart; i < pend; i++) {
95524121865SAdrian Maldonado     subpoints[i - pstart] = i;
95624121865SAdrian Maldonado   }
957459726d8SSatish Balay   ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,pend-pstart,subpoints,PETSC_COPY_VALUES,map);CHKERRQ(ierr);
95824121865SAdrian Maldonado   ierr = PetscFree(subpoints);CHKERRQ(ierr);
95924121865SAdrian Maldonado   PetscFunctionReturn(0);
96024121865SAdrian Maldonado }
96124121865SAdrian Maldonado 
96224121865SAdrian Maldonado /*@
96324121865SAdrian Maldonado   DMNetworkAssembleGraphStructures - Assembles vertex and edge data structures. Must be called after DMNetworkDistribute.
96424121865SAdrian Maldonado 
96524121865SAdrian Maldonado   Collective
96624121865SAdrian Maldonado 
96724121865SAdrian Maldonado   Input Parameters:
96824121865SAdrian Maldonado . dm   - The DMNetworkObject
96924121865SAdrian Maldonado 
97024121865SAdrian Maldonado   Note: the routine will create alternative orderings for the vertices and edges. Assume global network points are:
97124121865SAdrian Maldonado 
97224121865SAdrian Maldonado   points = [0 1 2 3 4 5 6]
97324121865SAdrian Maldonado 
97424121865SAdrian Maldonado   where edges = [0, 3] and vertices = [4, 6]. The new orderings will be specific to the subset (i.e vertices = [0, 2]).
97524121865SAdrian Maldonado 
97624121865SAdrian Maldonado   With this new ordering a local PetscSection, global PetscSection and PetscSF will be created specific to the subset.
97724121865SAdrian Maldonado 
97824121865SAdrian Maldonado   Level: intermediate
97924121865SAdrian Maldonado 
98024121865SAdrian Maldonado @*/
98124121865SAdrian Maldonado PetscErrorCode DMNetworkAssembleGraphStructures(DM dm)
98224121865SAdrian Maldonado {
98324121865SAdrian Maldonado   PetscErrorCode ierr;
98424121865SAdrian Maldonado   MPI_Comm       comm;
9859852e123SBarry Smith   PetscMPIInt    rank, size;
98624121865SAdrian Maldonado   DM_Network     *network = (DM_Network*)dm->data;
98724121865SAdrian Maldonado 
988eab1376dSHong Zhang   PetscFunctionBegin;
98924121865SAdrian Maldonado   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
99024121865SAdrian Maldonado   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
9919852e123SBarry Smith   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
99224121865SAdrian Maldonado 
99324121865SAdrian Maldonado   /* Create maps for vertices and edges */
99424121865SAdrian Maldonado   ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr);
99524121865SAdrian Maldonado   ierr = DMNetworkSetSubMap_private(network->eStart,network->eEnd,&network->edge.mapping);CHKERRQ(ierr);
99624121865SAdrian Maldonado 
99724121865SAdrian Maldonado   /* Create local sub-sections */
99824121865SAdrian Maldonado   ierr = DMNetworkGetSubSection_private(network->DofSection,network->vStart,network->vEnd,&network->vertex.DofSection);CHKERRQ(ierr);
99924121865SAdrian Maldonado   ierr = DMNetworkGetSubSection_private(network->DofSection,network->eStart,network->eEnd,&network->edge.DofSection);CHKERRQ(ierr);
100024121865SAdrian Maldonado 
10019852e123SBarry Smith   if (size > 1) {
100224121865SAdrian Maldonado     ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr);
100324121865SAdrian Maldonado     ierr = PetscSectionCreateGlobalSection(network->vertex.DofSection, network->vertex.sf, PETSC_FALSE, PETSC_FALSE, &network->vertex.GlobalDofSection);CHKERRQ(ierr);
100424121865SAdrian Maldonado   ierr = PetscSFGetSubSF(network->plex->sf, network->edge.mapping, &network->edge.sf);CHKERRQ(ierr);
100524121865SAdrian Maldonado   ierr = PetscSectionCreateGlobalSection(network->edge.DofSection, network->edge.sf, PETSC_FALSE, PETSC_FALSE, &network->edge.GlobalDofSection);CHKERRQ(ierr);
100624121865SAdrian Maldonado   } else {
100724121865SAdrian Maldonado   /* create structures for vertex */
100824121865SAdrian Maldonado   ierr = PetscSectionClone(network->vertex.DofSection,&network->vertex.GlobalDofSection);CHKERRQ(ierr);
100924121865SAdrian Maldonado   /* create structures for edge */
101024121865SAdrian Maldonado   ierr = PetscSectionClone(network->edge.DofSection,&network->edge.GlobalDofSection);CHKERRQ(ierr);
101124121865SAdrian Maldonado   }
101224121865SAdrian Maldonado 
101324121865SAdrian Maldonado 
101424121865SAdrian Maldonado   /* Add viewers */
101524121865SAdrian Maldonado   ierr = PetscObjectSetName((PetscObject)network->edge.GlobalDofSection,"Global edge dof section");CHKERRQ(ierr);
101624121865SAdrian Maldonado   ierr = PetscObjectSetName((PetscObject)network->vertex.GlobalDofSection,"Global vertex dof section");CHKERRQ(ierr);
101724121865SAdrian Maldonado   ierr = PetscSectionViewFromOptions(network->edge.GlobalDofSection, NULL, "-edge_global_section_view");CHKERRQ(ierr);
101824121865SAdrian Maldonado   ierr = PetscSectionViewFromOptions(network->vertex.GlobalDofSection, NULL, "-vertex_global_section_view");CHKERRQ(ierr);
101924121865SAdrian Maldonado 
102024121865SAdrian Maldonado   PetscFunctionReturn(0);
102124121865SAdrian Maldonado }
10227b6afd5bSHong Zhang 
10235f2c45f1SShri Abhyankar /*@
10245f2c45f1SShri Abhyankar   DMNetworkDistribute - Distributes the network and moves associated component data.
10255f2c45f1SShri Abhyankar 
10265f2c45f1SShri Abhyankar   Collective
10275f2c45f1SShri Abhyankar 
10285f2c45f1SShri Abhyankar   Input Parameter:
1029d3464fd4SAdrian Maldonado + DM - the DMNetwork object
10305f2c45f1SShri Abhyankar - overlap - The overlap of partitions, 0 is the default
10315f2c45f1SShri Abhyankar 
10325f2c45f1SShri Abhyankar   Notes:
10338b171c8eSHong Zhang   Distributes the network with <overlap>-overlapping partitioning of the edges.
10345f2c45f1SShri Abhyankar 
10355f2c45f1SShri Abhyankar   Level: intermediate
10365f2c45f1SShri Abhyankar 
10375f2c45f1SShri Abhyankar .seealso: DMNetworkCreate
10385f2c45f1SShri Abhyankar @*/
1039d3464fd4SAdrian Maldonado PetscErrorCode DMNetworkDistribute(DM *dm,PetscInt overlap)
10405f2c45f1SShri Abhyankar {
1041d3464fd4SAdrian Maldonado   MPI_Comm       comm;
10425f2c45f1SShri Abhyankar   PetscErrorCode ierr;
1043d3464fd4SAdrian Maldonado   PetscMPIInt    size;
1044d3464fd4SAdrian Maldonado   DM_Network     *oldDMnetwork = (DM_Network*)((*dm)->data);
1045d3464fd4SAdrian Maldonado   DM_Network     *newDMnetwork;
10465f2c45f1SShri Abhyankar   PetscSF        pointsf;
10475f2c45f1SShri Abhyankar   DM             newDM;
104851ac5effSHong Zhang   PetscPartitioner part;
1049b9c6e19dSShri Abhyankar   PetscInt         j,e,v,offset;
1050b9c6e19dSShri Abhyankar   DMNetworkComponentHeader header;
10515f2c45f1SShri Abhyankar 
10525f2c45f1SShri Abhyankar   PetscFunctionBegin;
1053d3464fd4SAdrian Maldonado 
1054d3464fd4SAdrian Maldonado   ierr = PetscObjectGetComm((PetscObject)*dm,&comm);CHKERRQ(ierr);
1055d3464fd4SAdrian Maldonado   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
1056d3464fd4SAdrian Maldonado   if (size == 1) PetscFunctionReturn(0);
1057d3464fd4SAdrian Maldonado 
1058d3464fd4SAdrian Maldonado   ierr = DMNetworkCreate(PetscObjectComm((PetscObject)*dm),&newDM);CHKERRQ(ierr);
10595f2c45f1SShri Abhyankar   newDMnetwork = (DM_Network*)newDM->data;
10605f2c45f1SShri Abhyankar   newDMnetwork->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType);
106151ac5effSHong Zhang 
106251ac5effSHong Zhang   /* Enable runtime options for petscpartitioner */
106351ac5effSHong Zhang   ierr = DMPlexGetPartitioner(oldDMnetwork->plex,&part);CHKERRQ(ierr);
106451ac5effSHong Zhang   ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr);
106551ac5effSHong Zhang 
10665f2c45f1SShri Abhyankar   /* Distribute plex dm and dof section */
106780cf41d5SMatthew G. Knepley   ierr = DMPlexDistribute(oldDMnetwork->plex,overlap,&pointsf,&newDMnetwork->plex);CHKERRQ(ierr);
106851ac5effSHong Zhang 
10695f2c45f1SShri Abhyankar   /* Distribute dof section */
1070d3464fd4SAdrian Maldonado   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)*dm),&newDMnetwork->DofSection);CHKERRQ(ierr);
10715f2c45f1SShri Abhyankar   ierr = PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);CHKERRQ(ierr);
1072d3464fd4SAdrian Maldonado   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)*dm),&newDMnetwork->DataSection);CHKERRQ(ierr);
107351ac5effSHong Zhang 
10745f2c45f1SShri Abhyankar   /* Distribute data and associated section */
107531da1fc8SHong Zhang   ierr = DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPIU_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);CHKERRQ(ierr);
107624121865SAdrian Maldonado 
10775f2c45f1SShri Abhyankar   ierr = PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);CHKERRQ(ierr);
10785f2c45f1SShri Abhyankar   ierr = DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);CHKERRQ(ierr);
10795f2c45f1SShri Abhyankar   ierr = DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);CHKERRQ(ierr);
10805f2c45f1SShri Abhyankar   newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart;
10816fefedf4SHong Zhang   newDMnetwork->nVertices = newDMnetwork->vEnd - newDMnetwork->vStart;
10826fefedf4SHong Zhang   newDMnetwork->NVertices = oldDMnetwork->NVertices;
10835f2c45f1SShri Abhyankar   newDMnetwork->NEdges = oldDMnetwork->NEdges;
108424121865SAdrian Maldonado 
10855f2c45f1SShri Abhyankar   /* Set Dof section as the default section for dm */
10865f2c45f1SShri Abhyankar   ierr = DMSetDefaultSection(newDMnetwork->plex,newDMnetwork->DofSection);CHKERRQ(ierr);
10875f2c45f1SShri Abhyankar   ierr = DMGetDefaultGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);CHKERRQ(ierr);
10885f2c45f1SShri Abhyankar 
1089b9c6e19dSShri Abhyankar   /* Set up subnetwork info in the newDM */
1090b9c6e19dSShri Abhyankar   newDMnetwork->nsubnet = oldDMnetwork->nsubnet;
1091b9c6e19dSShri Abhyankar   ierr = PetscCalloc1(newDMnetwork->nsubnet,&newDMnetwork->subnet);CHKERRQ(ierr);
1092b9c6e19dSShri Abhyankar   /* Copy over the global number of vertices and edges in each subnetwork. Note that these are already
1093b9c6e19dSShri Abhyankar      calculated in DMNetworkLayoutSetUp()
1094b9c6e19dSShri Abhyankar   */
1095b9c6e19dSShri Abhyankar   for(j=0; j < newDMnetwork->nsubnet; j++) {
1096b9c6e19dSShri Abhyankar     newDMnetwork->subnet[j].Nvtx = oldDMnetwork->subnet[j].Nvtx;
1097b9c6e19dSShri Abhyankar     newDMnetwork->subnet[j].Nedge = oldDMnetwork->subnet[j].Nedge;
1098b9c6e19dSShri Abhyankar   }
1099b9c6e19dSShri Abhyankar 
1100b9c6e19dSShri Abhyankar   for(e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++ ) {
1101b9c6e19dSShri Abhyankar     ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr);
1102b9c6e19dSShri Abhyankar     header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr);
1103b9c6e19dSShri Abhyankar     newDMnetwork->subnet[header->subnetid].nedge++;
1104b9c6e19dSShri Abhyankar   }
1105b9c6e19dSShri Abhyankar 
1106b9c6e19dSShri Abhyankar   for(v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++ ) {
1107b9c6e19dSShri Abhyankar     ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr);
1108b9c6e19dSShri Abhyankar     header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr);
1109b9c6e19dSShri Abhyankar     newDMnetwork->subnet[header->subnetid].nvtx++;
1110b9c6e19dSShri Abhyankar   }
1111b9c6e19dSShri Abhyankar 
1112b9c6e19dSShri Abhyankar   /* Now create the vertices and edge arrays for the subnetworks */
1113b9c6e19dSShri Abhyankar   for(j=0; j < newDMnetwork->nsubnet; j++) {
1114b9c6e19dSShri Abhyankar     ierr = PetscCalloc1(newDMnetwork->subnet[j].nedge,&newDMnetwork->subnet[j].edges);CHKERRQ(ierr);
1115b9c6e19dSShri Abhyankar     ierr = PetscCalloc1(newDMnetwork->subnet[j].nvtx,&newDMnetwork->subnet[j].vertices);CHKERRQ(ierr);
1116b9c6e19dSShri Abhyankar     /* Temporarily setting nvtx and nedge to 0 so we can use them as counters in the below for loop.
1117b9c6e19dSShri Abhyankar        These get updated when the vertices and edges are added. */
1118b9c6e19dSShri Abhyankar     newDMnetwork->subnet[j].nvtx = newDMnetwork->subnet[j].nedge = 0;
1119b9c6e19dSShri Abhyankar   }
1120b9c6e19dSShri Abhyankar 
1121b9c6e19dSShri Abhyankar   /* Set the vertices and edges in each subnetwork */
1122b9c6e19dSShri Abhyankar   for(e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++ ) {
1123b9c6e19dSShri Abhyankar     ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr);
1124b9c6e19dSShri Abhyankar     header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr);
1125b9c6e19dSShri Abhyankar     newDMnetwork->subnet[header->subnetid].edges[newDMnetwork->subnet[header->subnetid].nedge++]  = e;
1126b9c6e19dSShri Abhyankar   }
1127b9c6e19dSShri Abhyankar 
1128b9c6e19dSShri Abhyankar   for(v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++ ) {
1129b9c6e19dSShri Abhyankar     ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr);
1130b9c6e19dSShri Abhyankar     header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr);
1131b9c6e19dSShri Abhyankar     newDMnetwork->subnet[header->subnetid].vertices[newDMnetwork->subnet[header->subnetid].nvtx++]  = v;
1132b9c6e19dSShri Abhyankar   }
1133b9c6e19dSShri Abhyankar 
113424121865SAdrian Maldonado   /* Destroy point SF */
113524121865SAdrian Maldonado   ierr = PetscSFDestroy(&pointsf);CHKERRQ(ierr);
113624121865SAdrian Maldonado 
1137d3464fd4SAdrian Maldonado   ierr = DMDestroy(dm);CHKERRQ(ierr);
1138d3464fd4SAdrian Maldonado   *dm  = newDM;
11395f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
11405f2c45f1SShri Abhyankar }
11415f2c45f1SShri Abhyankar 
114224121865SAdrian Maldonado /*@C
114324121865SAdrian Maldonado   PetscSFGetSubSF - Returns an SF for a specific subset of points. Leaves are re-numbered to reflect the new ordering.
114424121865SAdrian Maldonado 
114524121865SAdrian Maldonado   Input Parameters:
114624121865SAdrian Maldonado + masterSF - the original SF structure
114724121865SAdrian Maldonado - map      - a ISLocalToGlobal mapping that contains the subset of points
114824121865SAdrian Maldonado 
114924121865SAdrian Maldonado   Output Parameters:
115024121865SAdrian Maldonado . subSF    - a subset of the masterSF for the desired subset.
115124121865SAdrian Maldonado */
115224121865SAdrian Maldonado 
115324121865SAdrian Maldonado PetscErrorCode PetscSFGetSubSF(PetscSF mastersf, ISLocalToGlobalMapping map, PetscSF *subSF) {
115424121865SAdrian Maldonado 
115524121865SAdrian Maldonado   PetscErrorCode        ierr;
115624121865SAdrian Maldonado   PetscInt              nroots, nleaves, *ilocal_sub;
115724121865SAdrian Maldonado   PetscInt              i, *ilocal_map, nroots_sub, nleaves_sub = 0;
115824121865SAdrian Maldonado   PetscInt              *local_points, *remote_points;
115924121865SAdrian Maldonado   PetscSFNode           *iremote_sub;
116024121865SAdrian Maldonado   const PetscInt        *ilocal;
116124121865SAdrian Maldonado   const PetscSFNode     *iremote;
116224121865SAdrian Maldonado 
116324121865SAdrian Maldonado   PetscFunctionBegin;
116424121865SAdrian Maldonado   ierr = PetscSFGetGraph(mastersf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr);
116524121865SAdrian Maldonado 
116624121865SAdrian Maldonado   /* Look for leaves that pertain to the subset of points. Get the local ordering */
116724121865SAdrian Maldonado   ierr = PetscMalloc1(nleaves,&ilocal_map);CHKERRQ(ierr);
116824121865SAdrian Maldonado   ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nleaves,ilocal,NULL,ilocal_map);CHKERRQ(ierr);
116924121865SAdrian Maldonado   for (i = 0; i < nleaves; i++) {
117024121865SAdrian Maldonado     if (ilocal_map[i] != -1) nleaves_sub += 1;
117124121865SAdrian Maldonado   }
117224121865SAdrian Maldonado   /* Re-number ilocal with subset numbering. Need information from roots */
117324121865SAdrian Maldonado   ierr = PetscMalloc2(nroots,&local_points,nroots,&remote_points);CHKERRQ(ierr);
117424121865SAdrian Maldonado   for (i = 0; i < nroots; i++) local_points[i] = i;
117524121865SAdrian Maldonado   ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nroots,local_points,NULL,local_points);CHKERRQ(ierr);
117624121865SAdrian Maldonado   ierr = PetscSFBcastBegin(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr);
117724121865SAdrian Maldonado   ierr = PetscSFBcastEnd(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr);
117824121865SAdrian Maldonado   /* Fill up graph using local (that is, local to the subset) numbering. */
11794b70a8deSAdrian Maldonado   ierr = PetscMalloc1(nleaves_sub,&ilocal_sub);CHKERRQ(ierr);
11804b70a8deSAdrian Maldonado   ierr = PetscMalloc1(nleaves_sub,&iremote_sub);CHKERRQ(ierr);
118124121865SAdrian Maldonado   nleaves_sub = 0;
118224121865SAdrian Maldonado   for (i = 0; i < nleaves; i++) {
118324121865SAdrian Maldonado     if (ilocal_map[i] != -1) {
118424121865SAdrian Maldonado       ilocal_sub[nleaves_sub] = ilocal_map[i];
11854b70a8deSAdrian Maldonado       iremote_sub[nleaves_sub].rank = iremote[i].rank;
118624121865SAdrian Maldonado       iremote_sub[nleaves_sub].index = remote_points[ilocal[i]];
118724121865SAdrian Maldonado       nleaves_sub += 1;
118824121865SAdrian Maldonado     }
118924121865SAdrian Maldonado   }
119024121865SAdrian Maldonado   ierr = PetscFree2(local_points,remote_points);CHKERRQ(ierr);
119124121865SAdrian Maldonado   ierr = ISLocalToGlobalMappingGetSize(map,&nroots_sub);CHKERRQ(ierr);
119224121865SAdrian Maldonado 
119324121865SAdrian Maldonado   /* Create new subSF */
119424121865SAdrian Maldonado   ierr = PetscSFCreate(PETSC_COMM_WORLD,subSF);CHKERRQ(ierr);
119524121865SAdrian Maldonado   ierr = PetscSFSetFromOptions(*subSF);CHKERRQ(ierr);
11964b70a8deSAdrian Maldonado   ierr = PetscSFSetGraph(*subSF,nroots_sub,nleaves_sub,ilocal_sub,PETSC_OWN_POINTER,iremote_sub,PETSC_COPY_VALUES);CHKERRQ(ierr);
119724121865SAdrian Maldonado   ierr = PetscFree(ilocal_map);CHKERRQ(ierr);
11984b70a8deSAdrian Maldonado   ierr = PetscFree(iremote_sub);CHKERRQ(ierr);
119924121865SAdrian Maldonado   PetscFunctionReturn(0);
120024121865SAdrian Maldonado }
120124121865SAdrian Maldonado 
12025f2c45f1SShri Abhyankar /*@C
12035f2c45f1SShri Abhyankar   DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point
12045f2c45f1SShri Abhyankar 
12055f2c45f1SShri Abhyankar   Not Collective
12065f2c45f1SShri Abhyankar 
12075f2c45f1SShri Abhyankar   Input Parameters:
12085f2c45f1SShri Abhyankar + dm - The DMNetwork object
12095f2c45f1SShri Abhyankar - p  - the vertex point
12105f2c45f1SShri Abhyankar 
12115f2c45f1SShri Abhyankar   Output Paramters:
12125f2c45f1SShri Abhyankar + nedges - number of edges connected to this vertex point
12135f2c45f1SShri Abhyankar - edges  - List of edge points
12145f2c45f1SShri Abhyankar 
12155f2c45f1SShri Abhyankar   Level: intermediate
12165f2c45f1SShri Abhyankar 
12175f2c45f1SShri Abhyankar   Fortran Notes:
12185f2c45f1SShri Abhyankar   Since it returns an array, this routine is only available in Fortran 90, and you must
12195f2c45f1SShri Abhyankar   include petsc.h90 in your code.
12205f2c45f1SShri Abhyankar 
1221d842c372SHong Zhang .seealso: DMNetworkCreate, DMNetworkGetConnectedVertices
12225f2c45f1SShri Abhyankar @*/
12235f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[])
12245f2c45f1SShri Abhyankar {
12255f2c45f1SShri Abhyankar   PetscErrorCode ierr;
12265f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
12275f2c45f1SShri Abhyankar 
12285f2c45f1SShri Abhyankar   PetscFunctionBegin;
12295f2c45f1SShri Abhyankar   ierr = DMPlexGetSupportSize(network->plex,vertex,nedges);CHKERRQ(ierr);
12305f2c45f1SShri Abhyankar   ierr = DMPlexGetSupport(network->plex,vertex,edges);CHKERRQ(ierr);
12315f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
12325f2c45f1SShri Abhyankar }
12335f2c45f1SShri Abhyankar 
12345f2c45f1SShri Abhyankar /*@C
1235d842c372SHong Zhang   DMNetworkGetConnectedVertices - Return the connected vertices for this edge point
12365f2c45f1SShri Abhyankar 
12375f2c45f1SShri Abhyankar   Not Collective
12385f2c45f1SShri Abhyankar 
12395f2c45f1SShri Abhyankar   Input Parameters:
12405f2c45f1SShri Abhyankar + dm - The DMNetwork object
12415f2c45f1SShri Abhyankar - p  - the edge point
12425f2c45f1SShri Abhyankar 
12435f2c45f1SShri Abhyankar   Output Paramters:
12445f2c45f1SShri Abhyankar . vertices  - vertices connected to this edge
12455f2c45f1SShri Abhyankar 
12465f2c45f1SShri Abhyankar   Level: intermediate
12475f2c45f1SShri Abhyankar 
12485f2c45f1SShri Abhyankar   Fortran Notes:
12495f2c45f1SShri Abhyankar   Since it returns an array, this routine is only available in Fortran 90, and you must
12505f2c45f1SShri Abhyankar   include petsc.h90 in your code.
12515f2c45f1SShri Abhyankar 
12525f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkGetSupportingEdges
12535f2c45f1SShri Abhyankar @*/
1254d842c372SHong Zhang PetscErrorCode DMNetworkGetConnectedVertices(DM dm,PetscInt edge,const PetscInt *vertices[])
12555f2c45f1SShri Abhyankar {
12565f2c45f1SShri Abhyankar   PetscErrorCode ierr;
12575f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
12585f2c45f1SShri Abhyankar 
12595f2c45f1SShri Abhyankar   PetscFunctionBegin;
12605f2c45f1SShri Abhyankar   ierr = DMPlexGetCone(network->plex,edge,vertices);CHKERRQ(ierr);
12615f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
12625f2c45f1SShri Abhyankar }
12635f2c45f1SShri Abhyankar 
12645f2c45f1SShri Abhyankar /*@
12655f2c45f1SShri Abhyankar   DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex
12665f2c45f1SShri Abhyankar 
12675f2c45f1SShri Abhyankar   Not Collective
12685f2c45f1SShri Abhyankar 
12695f2c45f1SShri Abhyankar   Input Parameters:
12705f2c45f1SShri Abhyankar + dm - The DMNetwork object
12715f2c45f1SShri Abhyankar . p  - the vertex point
12725f2c45f1SShri Abhyankar 
12735f2c45f1SShri Abhyankar   Output Parameter:
12745f2c45f1SShri Abhyankar . isghost - TRUE if the vertex is a ghost point
12755f2c45f1SShri Abhyankar 
12765f2c45f1SShri Abhyankar   Level: intermediate
12775f2c45f1SShri Abhyankar 
1278d842c372SHong Zhang .seealso: DMNetworkCreate, DMNetworkGetConnectedVertices, DMNetworkGetVertexRange
12795f2c45f1SShri Abhyankar @*/
12805f2c45f1SShri Abhyankar PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost)
12815f2c45f1SShri Abhyankar {
12825f2c45f1SShri Abhyankar   PetscErrorCode ierr;
12835f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
12845f2c45f1SShri Abhyankar   PetscInt       offsetg;
12855f2c45f1SShri Abhyankar   PetscSection   sectiong;
12865f2c45f1SShri Abhyankar 
12875f2c45f1SShri Abhyankar   PetscFunctionBegin;
12885f2c45f1SShri Abhyankar   *isghost = PETSC_FALSE;
12895f2c45f1SShri Abhyankar   ierr = DMGetDefaultGlobalSection(network->plex,&sectiong);CHKERRQ(ierr);
12905f2c45f1SShri Abhyankar   ierr = PetscSectionGetOffset(sectiong,p,&offsetg);CHKERRQ(ierr);
12915f2c45f1SShri Abhyankar   if (offsetg < 0) *isghost = PETSC_TRUE;
12925f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
12935f2c45f1SShri Abhyankar }
12945f2c45f1SShri Abhyankar 
12955f2c45f1SShri Abhyankar PetscErrorCode DMSetUp_Network(DM dm)
12965f2c45f1SShri Abhyankar {
12975f2c45f1SShri Abhyankar   PetscErrorCode ierr;
12985f2c45f1SShri Abhyankar   DM_Network     *network=(DM_Network*)dm->data;
12995f2c45f1SShri Abhyankar 
13005f2c45f1SShri Abhyankar   PetscFunctionBegin;
13015f2c45f1SShri Abhyankar   ierr = DMNetworkComponentSetUp(dm);CHKERRQ(ierr);
13025f2c45f1SShri Abhyankar   ierr = DMNetworkVariablesSetUp(dm);CHKERRQ(ierr);
13035f2c45f1SShri Abhyankar 
13045f2c45f1SShri Abhyankar   ierr = DMSetDefaultSection(network->plex,network->DofSection);CHKERRQ(ierr);
13055f2c45f1SShri Abhyankar   ierr = DMGetDefaultGlobalSection(network->plex,&network->GlobalDofSection);CHKERRQ(ierr);
13065f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
13075f2c45f1SShri Abhyankar }
13085f2c45f1SShri Abhyankar 
13091ad426b7SHong Zhang /*@
131017df6e9eSHong Zhang     DMNetworkHasJacobian - Sets global flag for using user's sub Jacobian matrices
13111ad426b7SHong Zhang                             -- replaced by DMNetworkSetOption(network,userjacobian,PETSC_TURE)?
13121ad426b7SHong Zhang 
13131ad426b7SHong Zhang     Collective
13141ad426b7SHong Zhang 
13151ad426b7SHong Zhang     Input Parameters:
131683b2e829SHong Zhang +   dm - The DMNetwork object
131783b2e829SHong Zhang .   eflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for edges
131883b2e829SHong Zhang -   vflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for vertices
13191ad426b7SHong Zhang 
13201ad426b7SHong Zhang     Level: intermediate
13211ad426b7SHong Zhang 
13221ad426b7SHong Zhang @*/
132383b2e829SHong Zhang PetscErrorCode DMNetworkHasJacobian(DM dm,PetscBool eflg,PetscBool vflg)
13241ad426b7SHong Zhang {
13251ad426b7SHong Zhang   DM_Network     *network=(DM_Network*)dm->data;
13268675203cSHong Zhang   PetscErrorCode ierr;
13271ad426b7SHong Zhang 
13281ad426b7SHong Zhang   PetscFunctionBegin;
132983b2e829SHong Zhang   network->userEdgeJacobian   = eflg;
133083b2e829SHong Zhang   network->userVertexJacobian = vflg;
13318675203cSHong Zhang 
13328675203cSHong Zhang   if (eflg && !network->Je) {
13338675203cSHong Zhang     ierr = PetscCalloc1(3*network->nEdges,&network->Je);CHKERRQ(ierr);
13348675203cSHong Zhang   }
13358675203cSHong Zhang 
13368675203cSHong Zhang   if (vflg && !network->Jv) {
13378675203cSHong Zhang     PetscInt       i,*vptr,nedges,vStart=network->vStart;
13388675203cSHong Zhang     PetscInt       nVertices = network->nVertices,nedges_total;
13398675203cSHong Zhang     const PetscInt *edges;
13408675203cSHong Zhang 
13418675203cSHong Zhang     /* count nvertex_total */
13428675203cSHong Zhang     nedges_total = 0;
13438675203cSHong Zhang     ierr = PetscMalloc1(nVertices+1,&vptr);CHKERRQ(ierr);
13448675203cSHong Zhang 
13458675203cSHong Zhang     vptr[0] = 0;
13468675203cSHong Zhang     for (i=0; i<nVertices; i++) {
13478675203cSHong Zhang       ierr = DMNetworkGetSupportingEdges(dm,i+vStart,&nedges,&edges);CHKERRQ(ierr);
13488675203cSHong Zhang       nedges_total += nedges;
13498675203cSHong Zhang       vptr[i+1] = vptr[i] + 2*nedges + 1;
13508675203cSHong Zhang     }
13518675203cSHong Zhang 
13528675203cSHong Zhang     ierr = PetscCalloc1(2*nedges_total+nVertices,&network->Jv);CHKERRQ(ierr);
13538675203cSHong Zhang     network->Jvptr = vptr;
13548675203cSHong Zhang   }
13551ad426b7SHong Zhang   PetscFunctionReturn(0);
13561ad426b7SHong Zhang }
13571ad426b7SHong Zhang 
13581ad426b7SHong Zhang /*@
135983b2e829SHong Zhang     DMNetworkEdgeSetMatrix - Sets user-provided Jacobian matrices for this edge to the network
136083b2e829SHong Zhang 
136183b2e829SHong Zhang     Not Collective
136283b2e829SHong Zhang 
136383b2e829SHong Zhang     Input Parameters:
136483b2e829SHong Zhang +   dm - The DMNetwork object
136583b2e829SHong Zhang .   p  - the edge point
13663e97b6e8SHong Zhang -   J - array (size = 3) of Jacobian submatrices for this edge point:
13673e97b6e8SHong Zhang         J[0]: this edge
1368d842c372SHong Zhang         J[1] and J[2]: connected vertices, obtained by calling DMNetworkGetConnectedVertices()
136983b2e829SHong Zhang 
137083b2e829SHong Zhang     Level: intermediate
137183b2e829SHong Zhang 
137283b2e829SHong Zhang .seealso: DMNetworkVertexSetMatrix
137383b2e829SHong Zhang @*/
137483b2e829SHong Zhang PetscErrorCode DMNetworkEdgeSetMatrix(DM dm,PetscInt p,Mat J[])
137583b2e829SHong Zhang {
137683b2e829SHong Zhang   DM_Network     *network=(DM_Network*)dm->data;
137783b2e829SHong Zhang 
137883b2e829SHong Zhang   PetscFunctionBegin;
13798675203cSHong Zhang   if (!network->Je) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkEdgeSetMatrix");
13808675203cSHong Zhang 
13818675203cSHong Zhang   if (J) {
1382883e35e8SHong Zhang     network->Je[3*p]   = J[0];
1383883e35e8SHong Zhang     network->Je[3*p+1] = J[1];
1384883e35e8SHong Zhang     network->Je[3*p+2] = J[2];
13858675203cSHong Zhang   }
138683b2e829SHong Zhang   PetscFunctionReturn(0);
138783b2e829SHong Zhang }
138883b2e829SHong Zhang 
138983b2e829SHong Zhang /*@
139076ddfea5SHong Zhang     DMNetworkVertexSetMatrix - Sets user-provided Jacobian matrix for this vertex to the network
13911ad426b7SHong Zhang 
13921ad426b7SHong Zhang     Not Collective
13931ad426b7SHong Zhang 
13941ad426b7SHong Zhang     Input Parameters:
13951ad426b7SHong Zhang +   dm - The DMNetwork object
13961ad426b7SHong Zhang .   p  - the vertex point
13973e97b6e8SHong Zhang -   J - array of Jacobian (size = 2*(num of supporting edges) + 1) submatrices for this vertex point:
13983e97b6e8SHong Zhang         J[0]:       this vertex
13993e97b6e8SHong Zhang         J[1+2*i]:   i-th supporting edge
14003e97b6e8SHong Zhang         J[1+2*i+1]: i-th connected vertex
14011ad426b7SHong Zhang 
14021ad426b7SHong Zhang     Level: intermediate
14031ad426b7SHong Zhang 
140483b2e829SHong Zhang .seealso: DMNetworkEdgeSetMatrix
14051ad426b7SHong Zhang @*/
1406883e35e8SHong Zhang PetscErrorCode DMNetworkVertexSetMatrix(DM dm,PetscInt p,Mat J[])
14075f2c45f1SShri Abhyankar {
14085f2c45f1SShri Abhyankar   PetscErrorCode ierr;
14095f2c45f1SShri Abhyankar   DM_Network     *network=(DM_Network*)dm->data;
14108675203cSHong Zhang   PetscInt       i,*vptr,nedges,vStart=network->vStart;
1411883e35e8SHong Zhang   const PetscInt *edges;
14125f2c45f1SShri Abhyankar 
14135f2c45f1SShri Abhyankar   PetscFunctionBegin;
14148675203cSHong Zhang   if (!network->Jv) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkVertexSetMatrix");
1415883e35e8SHong Zhang 
14168675203cSHong Zhang   if (J) {
1417883e35e8SHong Zhang     vptr = network->Jvptr;
14183e97b6e8SHong Zhang     network->Jv[vptr[p-vStart]] = J[0]; /* Set Jacobian for this vertex */
14193e97b6e8SHong Zhang 
14203e97b6e8SHong Zhang     /* Set Jacobian for each supporting edge and connected vertex */
1421883e35e8SHong Zhang     ierr = DMNetworkGetSupportingEdges(dm,p,&nedges,&edges);CHKERRQ(ierr);
1422883e35e8SHong Zhang     for (i=1; i<=2*nedges; i++) network->Jv[vptr[p-vStart]+i] = J[i];
14238675203cSHong Zhang   }
1424883e35e8SHong Zhang   PetscFunctionReturn(0);
1425883e35e8SHong Zhang }
1426883e35e8SHong Zhang 
1427e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz)
14285cf7da58SHong Zhang {
14295cf7da58SHong Zhang   PetscErrorCode ierr;
14305cf7da58SHong Zhang   PetscInt       j;
14315cf7da58SHong Zhang   PetscScalar    val=(PetscScalar)ncols;
14325cf7da58SHong Zhang 
14335cf7da58SHong Zhang   PetscFunctionBegin;
14345cf7da58SHong Zhang   if (!ghost) {
14355cf7da58SHong Zhang     for (j=0; j<nrows; j++) {
14365cf7da58SHong Zhang       ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr);
14375cf7da58SHong Zhang     }
14385cf7da58SHong Zhang   } else {
14395cf7da58SHong Zhang     for (j=0; j<nrows; j++) {
14405cf7da58SHong Zhang       ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr);
14415cf7da58SHong Zhang     }
14425cf7da58SHong Zhang   }
14435cf7da58SHong Zhang   PetscFunctionReturn(0);
14445cf7da58SHong Zhang }
14455cf7da58SHong Zhang 
1446e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz)
14475cf7da58SHong Zhang {
14485cf7da58SHong Zhang   PetscErrorCode ierr;
14495cf7da58SHong Zhang   PetscInt       j,ncols_u;
14505cf7da58SHong Zhang   PetscScalar    val;
14515cf7da58SHong Zhang 
14525cf7da58SHong Zhang   PetscFunctionBegin;
14535cf7da58SHong Zhang   if (!ghost) {
14545cf7da58SHong Zhang     for (j=0; j<nrows; j++) {
14555cf7da58SHong Zhang       ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr);
14565cf7da58SHong Zhang       val = (PetscScalar)ncols_u;
14575cf7da58SHong Zhang       ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr);
14585cf7da58SHong Zhang       ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr);
14595cf7da58SHong Zhang     }
14605cf7da58SHong Zhang   } else {
14615cf7da58SHong Zhang     for (j=0; j<nrows; j++) {
14625cf7da58SHong Zhang       ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr);
14635cf7da58SHong Zhang       val = (PetscScalar)ncols_u;
14645cf7da58SHong Zhang       ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr);
14655cf7da58SHong Zhang       ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr);
14665cf7da58SHong Zhang     }
14675cf7da58SHong Zhang   }
14685cf7da58SHong Zhang   PetscFunctionReturn(0);
14695cf7da58SHong Zhang }
14705cf7da58SHong Zhang 
1471e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz)
14725cf7da58SHong Zhang {
14735cf7da58SHong Zhang   PetscErrorCode ierr;
14745cf7da58SHong Zhang 
14755cf7da58SHong Zhang   PetscFunctionBegin;
14765cf7da58SHong Zhang   if (Ju) {
14775cf7da58SHong Zhang     ierr = MatSetPreallocationUserblock_private(Ju,nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr);
14785cf7da58SHong Zhang   } else {
14795cf7da58SHong Zhang     ierr = MatSetPreallocationDenseblock_private(nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr);
14805cf7da58SHong Zhang   }
14815cf7da58SHong Zhang   PetscFunctionReturn(0);
14825cf7da58SHong Zhang }
14835cf7da58SHong Zhang 
1484e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J)
1485883e35e8SHong Zhang {
1486883e35e8SHong Zhang   PetscErrorCode ierr;
1487883e35e8SHong Zhang   PetscInt       j,*cols;
1488883e35e8SHong Zhang   PetscScalar    *zeros;
1489883e35e8SHong Zhang 
1490883e35e8SHong Zhang   PetscFunctionBegin;
1491883e35e8SHong Zhang   ierr = PetscCalloc2(ncols,&cols,nrows*ncols,&zeros);CHKERRQ(ierr);
1492883e35e8SHong Zhang   for (j=0; j<ncols; j++) cols[j] = j+ cstart;
1493883e35e8SHong Zhang   ierr = MatSetValues(*J,nrows,rows,ncols,cols,zeros,INSERT_VALUES);CHKERRQ(ierr);
1494883e35e8SHong Zhang   ierr = PetscFree2(cols,zeros);CHKERRQ(ierr);
14951ad426b7SHong Zhang   PetscFunctionReturn(0);
14961ad426b7SHong Zhang }
1497a4e85ca8SHong Zhang 
1498e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J)
14993e97b6e8SHong Zhang {
15003e97b6e8SHong Zhang   PetscErrorCode ierr;
15013e97b6e8SHong Zhang   PetscInt       j,M,N,row,col,ncols_u;
15023e97b6e8SHong Zhang   const PetscInt *cols;
15033e97b6e8SHong Zhang   PetscScalar    zero=0.0;
15043e97b6e8SHong Zhang 
15053e97b6e8SHong Zhang   PetscFunctionBegin;
15063e97b6e8SHong Zhang   ierr = MatGetSize(Ju,&M,&N);CHKERRQ(ierr);
15073e97b6e8SHong 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);
15083e97b6e8SHong Zhang 
15093e97b6e8SHong Zhang   for (row=0; row<nrows; row++) {
15103e97b6e8SHong Zhang     ierr = MatGetRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr);
15113e97b6e8SHong Zhang     for (j=0; j<ncols_u; j++) {
15123e97b6e8SHong Zhang       col = cols[j] + cstart;
15133e97b6e8SHong Zhang       ierr = MatSetValues(*J,1,&rows[row],1,&col,&zero,INSERT_VALUES);CHKERRQ(ierr);
15143e97b6e8SHong Zhang     }
15153e97b6e8SHong Zhang     ierr = MatRestoreRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr);
15163e97b6e8SHong Zhang   }
15173e97b6e8SHong Zhang   PetscFunctionReturn(0);
15183e97b6e8SHong Zhang }
15191ad426b7SHong Zhang 
1520e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J)
1521a4e85ca8SHong Zhang {
1522a4e85ca8SHong Zhang   PetscErrorCode ierr;
1523f4431b8cSHong Zhang 
1524a4e85ca8SHong Zhang   PetscFunctionBegin;
1525a4e85ca8SHong Zhang   if (Ju) {
1526a4e85ca8SHong Zhang     ierr = MatSetUserblock_private(Ju,nrows,rows,ncols,cstart,J);CHKERRQ(ierr);
1527a4e85ca8SHong Zhang   } else {
1528a4e85ca8SHong Zhang     ierr = MatSetDenseblock_private(nrows,rows,ncols,cstart,J);CHKERRQ(ierr);
1529a4e85ca8SHong Zhang   }
1530a4e85ca8SHong Zhang   PetscFunctionReturn(0);
1531a4e85ca8SHong Zhang }
1532a4e85ca8SHong Zhang 
153324121865SAdrian 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.
153424121865SAdrian Maldonado */
153524121865SAdrian Maldonado PetscErrorCode CreateSubGlobalToLocalMapping_private(PetscSection globalsec, PetscSection localsec, ISLocalToGlobalMapping *ltog)
153624121865SAdrian Maldonado {
153724121865SAdrian Maldonado   PetscErrorCode ierr;
153824121865SAdrian Maldonado   PetscInt       i, size, dof;
153924121865SAdrian Maldonado   PetscInt       *glob2loc;
154024121865SAdrian Maldonado 
154124121865SAdrian Maldonado   PetscFunctionBegin;
154224121865SAdrian Maldonado   ierr = PetscSectionGetStorageSize(localsec,&size);CHKERRQ(ierr);
154324121865SAdrian Maldonado   ierr = PetscMalloc1(size,&glob2loc);CHKERRQ(ierr);
154424121865SAdrian Maldonado 
154524121865SAdrian Maldonado   for (i = 0; i < size; i++) {
154624121865SAdrian Maldonado     ierr = PetscSectionGetOffset(globalsec,i,&dof);CHKERRQ(ierr);
154724121865SAdrian Maldonado     dof = (dof >= 0) ? dof : -(dof + 1);
154824121865SAdrian Maldonado     glob2loc[i] = dof;
154924121865SAdrian Maldonado   }
155024121865SAdrian Maldonado 
155124121865SAdrian Maldonado   ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,size,glob2loc,PETSC_OWN_POINTER,ltog);CHKERRQ(ierr);
155224121865SAdrian Maldonado #if 0
155324121865SAdrian Maldonado   ierr = PetscIntView(size,glob2loc,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
155424121865SAdrian Maldonado #endif
155524121865SAdrian Maldonado   PetscFunctionReturn(0);
155624121865SAdrian Maldonado }
155724121865SAdrian Maldonado 
155801ad2aeeSHong Zhang #include <petsc/private/matimpl.h>
15591ad426b7SHong Zhang PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J)
15601ad426b7SHong Zhang {
15611ad426b7SHong Zhang   PetscErrorCode ierr;
156224121865SAdrian Maldonado   PetscMPIInt    rank, size;
15631ad426b7SHong Zhang   DM_Network     *network = (DM_Network*) dm->data;
1564a4e85ca8SHong Zhang   PetscInt       eStart,eEnd,vStart,vEnd,rstart,nrows,*rows,localSize;
1565840c2264SHong Zhang   PetscInt       cstart,ncols,j,e,v;
156624121865SAdrian Maldonado   PetscBool      ghost,ghost_vc,ghost2,isNest;
1567a4e85ca8SHong Zhang   Mat            Juser;
1568bfbc38dcSHong Zhang   PetscSection   sectionGlobal;
1569447d78afSSatish Balay   PetscInt       nedges,*vptr=NULL,vc,*rows_v; /* suppress maybe-uninitialized warning */
1570a4e85ca8SHong Zhang   const PetscInt *edges,*cone;
15715cf7da58SHong Zhang   MPI_Comm       comm;
157224121865SAdrian Maldonado   MatType        mtype;
15735cf7da58SHong Zhang   Vec            vd_nz,vo_nz;
15745cf7da58SHong Zhang   PetscInt       *dnnz,*onnz;
15755cf7da58SHong Zhang   PetscScalar    *vdnz,*vonz;
15761ad426b7SHong Zhang 
15771ad426b7SHong Zhang   PetscFunctionBegin;
157824121865SAdrian Maldonado   mtype = dm->mattype;
157924121865SAdrian Maldonado   ierr = PetscStrcmp(mtype, MATNEST, &isNest);CHKERRQ(ierr);
158024121865SAdrian Maldonado 
158124121865SAdrian Maldonado   if (isNest) {
15820731d606SHong Zhang     /* ierr = DMCreateMatrix_Network_Nest(); */
158324121865SAdrian Maldonado     PetscInt   eDof, vDof;
158424121865SAdrian Maldonado     Mat        j11, j12, j21, j22, bA[2][2];
158524121865SAdrian Maldonado     ISLocalToGlobalMapping eISMap, vISMap;
158624121865SAdrian Maldonado 
158724121865SAdrian Maldonado     ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
158824121865SAdrian Maldonado     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
158924121865SAdrian Maldonado     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
159024121865SAdrian Maldonado 
159124121865SAdrian Maldonado     ierr = PetscSectionGetConstrainedStorageSize(network->edge.GlobalDofSection,&eDof);CHKERRQ(ierr);
159224121865SAdrian Maldonado     ierr = PetscSectionGetConstrainedStorageSize(network->vertex.GlobalDofSection,&vDof);CHKERRQ(ierr);
159324121865SAdrian Maldonado 
159401ad2aeeSHong Zhang     ierr = MatCreate(comm, &j11);CHKERRQ(ierr);
159524121865SAdrian Maldonado     ierr = MatSetSizes(j11, eDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
159624121865SAdrian Maldonado     ierr = MatSetType(j11, MATMPIAIJ);CHKERRQ(ierr);
159724121865SAdrian Maldonado 
159801ad2aeeSHong Zhang     ierr = MatCreate(comm, &j12);CHKERRQ(ierr);
159924121865SAdrian Maldonado     ierr = MatSetSizes(j12, eDof, vDof, PETSC_DETERMINE ,PETSC_DETERMINE);CHKERRQ(ierr);
160024121865SAdrian Maldonado     ierr = MatSetType(j12, MATMPIAIJ);CHKERRQ(ierr);
160124121865SAdrian Maldonado 
160201ad2aeeSHong Zhang     ierr = MatCreate(comm, &j21);CHKERRQ(ierr);
160324121865SAdrian Maldonado     ierr = MatSetSizes(j21, vDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
160424121865SAdrian Maldonado     ierr = MatSetType(j21, MATMPIAIJ);CHKERRQ(ierr);
160524121865SAdrian Maldonado 
160601ad2aeeSHong Zhang     ierr = MatCreate(comm, &j22);CHKERRQ(ierr);
160724121865SAdrian Maldonado     ierr = MatSetSizes(j22, vDof, vDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
160824121865SAdrian Maldonado     ierr = MatSetType(j22, MATMPIAIJ);CHKERRQ(ierr);
160924121865SAdrian Maldonado 
16103f6a6bdaSHong Zhang     bA[0][0] = j11;
16113f6a6bdaSHong Zhang     bA[0][1] = j12;
16123f6a6bdaSHong Zhang     bA[1][0] = j21;
16133f6a6bdaSHong Zhang     bA[1][1] = j22;
161424121865SAdrian Maldonado 
161524121865SAdrian Maldonado     ierr = CreateSubGlobalToLocalMapping_private(network->edge.GlobalDofSection,network->edge.DofSection,&eISMap);CHKERRQ(ierr);
161624121865SAdrian Maldonado     ierr = CreateSubGlobalToLocalMapping_private(network->vertex.GlobalDofSection,network->vertex.DofSection,&vISMap);CHKERRQ(ierr);
161724121865SAdrian Maldonado 
161824121865SAdrian Maldonado     ierr = MatSetLocalToGlobalMapping(j11,eISMap,eISMap);CHKERRQ(ierr);
161924121865SAdrian Maldonado     ierr = MatSetLocalToGlobalMapping(j12,eISMap,vISMap);CHKERRQ(ierr);
162024121865SAdrian Maldonado     ierr = MatSetLocalToGlobalMapping(j21,vISMap,eISMap);CHKERRQ(ierr);
162124121865SAdrian Maldonado     ierr = MatSetLocalToGlobalMapping(j22,vISMap,vISMap);CHKERRQ(ierr);
162224121865SAdrian Maldonado 
162324121865SAdrian Maldonado     ierr = MatSetUp(j11);CHKERRQ(ierr);
162424121865SAdrian Maldonado     ierr = MatSetUp(j12);CHKERRQ(ierr);
162524121865SAdrian Maldonado     ierr = MatSetUp(j21);CHKERRQ(ierr);
162624121865SAdrian Maldonado     ierr = MatSetUp(j22);CHKERRQ(ierr);
162724121865SAdrian Maldonado 
162801ad2aeeSHong Zhang     ierr = MatCreateNest(comm,2,NULL,2,NULL,&bA[0][0],J);CHKERRQ(ierr);
162924121865SAdrian Maldonado     ierr = MatSetUp(*J);CHKERRQ(ierr);
163024121865SAdrian Maldonado     ierr = MatNestSetVecType(*J,VECNEST);CHKERRQ(ierr);
163124121865SAdrian Maldonado     ierr = MatDestroy(&j11);CHKERRQ(ierr);
163224121865SAdrian Maldonado     ierr = MatDestroy(&j12);CHKERRQ(ierr);
163324121865SAdrian Maldonado     ierr = MatDestroy(&j21);CHKERRQ(ierr);
163424121865SAdrian Maldonado     ierr = MatDestroy(&j22);CHKERRQ(ierr);
163524121865SAdrian Maldonado 
163624121865SAdrian Maldonado     ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
163724121865SAdrian Maldonado     ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
163824121865SAdrian Maldonado 
163924121865SAdrian Maldonado     /* Free structures */
164024121865SAdrian Maldonado     ierr = ISLocalToGlobalMappingDestroy(&eISMap);CHKERRQ(ierr);
164124121865SAdrian Maldonado     ierr = ISLocalToGlobalMappingDestroy(&vISMap);CHKERRQ(ierr);
164224121865SAdrian Maldonado 
164324121865SAdrian Maldonado     PetscFunctionReturn(0);
164424121865SAdrian Maldonado   } else if (!network->userEdgeJacobian && !network->userVertexJacobian) {
1645a4e85ca8SHong Zhang     /* user does not provide Jacobian blocks */
1646bfbc38dcSHong Zhang     ierr = DMCreateMatrix(network->plex,J);CHKERRQ(ierr);
1647bfbc38dcSHong Zhang     ierr = MatSetDM(*J,dm);CHKERRQ(ierr);
16481ad426b7SHong Zhang     PetscFunctionReturn(0);
16491ad426b7SHong Zhang   }
16501ad426b7SHong Zhang 
1651bfbc38dcSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)dm),J);CHKERRQ(ierr);
16522a945128SHong Zhang   ierr = DMGetDefaultGlobalSection(network->plex,&sectionGlobal);CHKERRQ(ierr);
1653bfbc38dcSHong Zhang   ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal,&localSize);CHKERRQ(ierr);
1654bfbc38dcSHong Zhang   ierr = MatSetSizes(*J,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
16552a945128SHong Zhang 
16562a945128SHong Zhang   ierr = MatSetType(*J,MATAIJ);CHKERRQ(ierr);
16572a945128SHong Zhang   ierr = MatSetFromOptions(*J);CHKERRQ(ierr);
165889898e50SHong Zhang 
165989898e50SHong Zhang   /* (1) Set matrix preallocation */
166089898e50SHong Zhang   /*------------------------------*/
1661840c2264SHong Zhang   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
1662840c2264SHong Zhang   ierr = VecCreate(comm,&vd_nz);CHKERRQ(ierr);
1663840c2264SHong Zhang   ierr = VecSetSizes(vd_nz,localSize,PETSC_DECIDE);CHKERRQ(ierr);
1664840c2264SHong Zhang   ierr = VecSetFromOptions(vd_nz);CHKERRQ(ierr);
1665840c2264SHong Zhang   ierr = VecSet(vd_nz,0.0);CHKERRQ(ierr);
1666840c2264SHong Zhang   ierr = VecDuplicate(vd_nz,&vo_nz);CHKERRQ(ierr);
1667840c2264SHong Zhang 
166889898e50SHong Zhang   /* Set preallocation for edges */
166989898e50SHong Zhang   /*-----------------------------*/
1670840c2264SHong Zhang   ierr = DMNetworkGetEdgeRange(dm,&eStart,&eEnd);CHKERRQ(ierr);
1671840c2264SHong Zhang 
1672bdcb62a2SHong Zhang   ierr = PetscMalloc1(localSize,&rows);CHKERRQ(ierr);
1673840c2264SHong Zhang   for (e=eStart; e<eEnd; e++) {
1674840c2264SHong Zhang     /* Get row indices */
1675840c2264SHong Zhang     ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr);
1676840c2264SHong Zhang     ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr);
1677840c2264SHong Zhang     if (nrows) {
1678840c2264SHong Zhang       for (j=0; j<nrows; j++) rows[j] = j + rstart;
1679840c2264SHong Zhang 
16805cf7da58SHong Zhang       /* Set preallocation for conntected vertices */
1681d842c372SHong Zhang       ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr);
1682840c2264SHong Zhang       for (v=0; v<2; v++) {
1683840c2264SHong Zhang         ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr);
1684840c2264SHong Zhang 
16858675203cSHong Zhang         if (network->Je) {
1686840c2264SHong Zhang           Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */
16878675203cSHong Zhang         } else Juser = NULL;
1688840c2264SHong Zhang         ierr = DMNetworkIsGhostVertex(dm,cone[v],&ghost);CHKERRQ(ierr);
16895cf7da58SHong Zhang         ierr = MatSetPreallocationblock_private(Juser,nrows,rows,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr);
1690840c2264SHong Zhang       }
1691840c2264SHong Zhang 
169289898e50SHong Zhang       /* Set preallocation for edge self */
1693840c2264SHong Zhang       cstart = rstart;
16948675203cSHong Zhang       if (network->Je) {
1695840c2264SHong Zhang         Juser = network->Je[3*e]; /* Jacobian(e,e) */
16968675203cSHong Zhang       } else Juser = NULL;
16975cf7da58SHong Zhang       ierr = MatSetPreallocationblock_private(Juser,nrows,rows,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr);
1698840c2264SHong Zhang     }
1699840c2264SHong Zhang   }
1700840c2264SHong Zhang 
170189898e50SHong Zhang   /* Set preallocation for vertices */
170289898e50SHong Zhang   /*--------------------------------*/
1703840c2264SHong Zhang   ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr);
17048675203cSHong Zhang   if (vEnd - vStart) vptr = network->Jvptr;
1705840c2264SHong Zhang 
1706840c2264SHong Zhang   for (v=vStart; v<vEnd; v++) {
1707840c2264SHong Zhang     /* Get row indices */
1708840c2264SHong Zhang     ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr);
1709840c2264SHong Zhang     ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr);
1710840c2264SHong Zhang     if (!nrows) continue;
1711840c2264SHong Zhang 
1712bdcb62a2SHong Zhang     ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr);
1713bdcb62a2SHong Zhang     if (ghost) {
1714bdcb62a2SHong Zhang       ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr);
1715bdcb62a2SHong Zhang     } else {
1716bdcb62a2SHong Zhang       rows_v = rows;
1717bdcb62a2SHong Zhang     }
1718bdcb62a2SHong Zhang 
1719bdcb62a2SHong Zhang     for (j=0; j<nrows; j++) rows_v[j] = j + rstart;
1720840c2264SHong Zhang 
1721840c2264SHong Zhang     /* Get supporting edges and connected vertices */
1722840c2264SHong Zhang     ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr);
1723840c2264SHong Zhang 
1724840c2264SHong Zhang     for (e=0; e<nedges; e++) {
1725840c2264SHong Zhang       /* Supporting edges */
1726840c2264SHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr);
1727840c2264SHong Zhang       ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr);
1728840c2264SHong Zhang 
17298675203cSHong Zhang       if (network->Jv) {
1730840c2264SHong Zhang         Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */
17318675203cSHong Zhang       } else Juser = NULL;
1732bdcb62a2SHong Zhang       ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr);
1733840c2264SHong Zhang 
1734840c2264SHong Zhang       /* Connected vertices */
1735d842c372SHong Zhang       ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr);
1736840c2264SHong Zhang       vc = (v == cone[0]) ? cone[1]:cone[0];
1737840c2264SHong Zhang       ierr = DMNetworkIsGhostVertex(dm,vc,&ghost_vc);CHKERRQ(ierr);
1738840c2264SHong Zhang 
1739840c2264SHong Zhang       ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr);
1740840c2264SHong Zhang 
17418675203cSHong Zhang       if (network->Jv) {
1742840c2264SHong Zhang         Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */
17438675203cSHong Zhang       } else Juser = NULL;
1744e102a522SHong Zhang       if (ghost_vc||ghost) {
1745e102a522SHong Zhang         ghost2 = PETSC_TRUE;
1746e102a522SHong Zhang       } else {
1747e102a522SHong Zhang         ghost2 = PETSC_FALSE;
1748e102a522SHong Zhang       }
1749e102a522SHong Zhang       ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost2,vd_nz,vo_nz);CHKERRQ(ierr);
1750840c2264SHong Zhang     }
1751840c2264SHong Zhang 
175289898e50SHong Zhang     /* Set preallocation for vertex self */
1753840c2264SHong Zhang     ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr);
1754840c2264SHong Zhang     if (!ghost) {
1755840c2264SHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr);
17568675203cSHong Zhang       if (network->Jv) {
1757840c2264SHong Zhang         Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */
17588675203cSHong Zhang       } else Juser = NULL;
1759bdcb62a2SHong Zhang       ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr);
1760840c2264SHong Zhang     }
1761bdcb62a2SHong Zhang     if (ghost) {
1762bdcb62a2SHong Zhang       ierr = PetscFree(rows_v);CHKERRQ(ierr);
1763bdcb62a2SHong Zhang     }
1764840c2264SHong Zhang   }
1765840c2264SHong Zhang 
1766840c2264SHong Zhang   ierr = VecAssemblyBegin(vd_nz);CHKERRQ(ierr);
1767840c2264SHong Zhang   ierr = VecAssemblyBegin(vo_nz);CHKERRQ(ierr);
17685cf7da58SHong Zhang 
17695cf7da58SHong Zhang   ierr = PetscMalloc2(localSize,&dnnz,localSize,&onnz);CHKERRQ(ierr);
17705cf7da58SHong Zhang 
17715cf7da58SHong Zhang   ierr = VecAssemblyEnd(vd_nz);CHKERRQ(ierr);
1772840c2264SHong Zhang   ierr = VecAssemblyEnd(vo_nz);CHKERRQ(ierr);
1773840c2264SHong Zhang 
1774840c2264SHong Zhang   ierr = VecGetArray(vd_nz,&vdnz);CHKERRQ(ierr);
1775840c2264SHong Zhang   ierr = VecGetArray(vo_nz,&vonz);CHKERRQ(ierr);
1776840c2264SHong Zhang   for (j=0; j<localSize; j++) {
1777e102a522SHong Zhang     dnnz[j] = (PetscInt)PetscRealPart(vdnz[j]);
1778e102a522SHong Zhang     onnz[j] = (PetscInt)PetscRealPart(vonz[j]);
1779840c2264SHong Zhang   }
1780840c2264SHong Zhang   ierr = VecRestoreArray(vd_nz,&vdnz);CHKERRQ(ierr);
1781840c2264SHong Zhang   ierr = VecRestoreArray(vo_nz,&vonz);CHKERRQ(ierr);
1782840c2264SHong Zhang   ierr = VecDestroy(&vd_nz);CHKERRQ(ierr);
1783840c2264SHong Zhang   ierr = VecDestroy(&vo_nz);CHKERRQ(ierr);
1784840c2264SHong Zhang 
17855cf7da58SHong Zhang   ierr = MatSeqAIJSetPreallocation(*J,0,dnnz);CHKERRQ(ierr);
17865cf7da58SHong Zhang   ierr = MatMPIAIJSetPreallocation(*J,0,dnnz,0,onnz);CHKERRQ(ierr);
17875cf7da58SHong Zhang   ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
17885cf7da58SHong Zhang 
17895cf7da58SHong Zhang   ierr = PetscFree2(dnnz,onnz);CHKERRQ(ierr);
17905cf7da58SHong Zhang 
179189898e50SHong Zhang   /* (2) Set matrix entries for edges */
179289898e50SHong Zhang   /*----------------------------------*/
17931ad426b7SHong Zhang   for (e=eStart; e<eEnd; e++) {
1794bfbc38dcSHong Zhang     /* Get row indices */
17951ad426b7SHong Zhang     ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr);
179617df6e9eSHong Zhang     ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr);
17974b976069SHong Zhang     if (nrows) {
179817df6e9eSHong Zhang       for (j=0; j<nrows; j++) rows[j] = j + rstart;
17991ad426b7SHong Zhang 
1800bfbc38dcSHong Zhang       /* Set matrix entries for conntected vertices */
1801d842c372SHong Zhang       ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr);
1802bfbc38dcSHong Zhang       for (v=0; v<2; v++) {
1803bfbc38dcSHong Zhang         ierr = DMNetworkGetVariableGlobalOffset(dm,cone[v],&cstart);CHKERRQ(ierr);
1804883e35e8SHong Zhang         ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr);
18053e97b6e8SHong Zhang 
18068675203cSHong Zhang         if (network->Je) {
1807a4e85ca8SHong Zhang           Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */
18088675203cSHong Zhang         } else Juser = NULL;
1809a4e85ca8SHong Zhang         ierr = MatSetblock_private(Juser,nrows,rows,ncols,cstart,J);CHKERRQ(ierr);
1810bfbc38dcSHong Zhang       }
181117df6e9eSHong Zhang 
1812bfbc38dcSHong Zhang       /* Set matrix entries for edge self */
18133e97b6e8SHong Zhang       cstart = rstart;
18148675203cSHong Zhang       if (network->Je) {
1815a4e85ca8SHong Zhang         Juser = network->Je[3*e]; /* Jacobian(e,e) */
18168675203cSHong Zhang       } else Juser = NULL;
1817a4e85ca8SHong Zhang       ierr = MatSetblock_private(Juser,nrows,rows,nrows,cstart,J);CHKERRQ(ierr);
18181ad426b7SHong Zhang     }
18194b976069SHong Zhang   }
18201ad426b7SHong Zhang 
1821bfbc38dcSHong Zhang   /* Set matrix entries for vertices */
182283b2e829SHong Zhang   /*---------------------------------*/
18231ad426b7SHong Zhang   for (v=vStart; v<vEnd; v++) {
1824bfbc38dcSHong Zhang     /* Get row indices */
1825596e729fSHong Zhang     ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr);
1826596e729fSHong Zhang     ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr);
18274b976069SHong Zhang     if (!nrows) continue;
1828596e729fSHong Zhang 
1829bdcb62a2SHong Zhang     ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr);
1830bdcb62a2SHong Zhang     if (ghost) {
1831bdcb62a2SHong Zhang       ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr);
1832bdcb62a2SHong Zhang     } else {
1833bdcb62a2SHong Zhang       rows_v = rows;
1834bdcb62a2SHong Zhang     }
1835bdcb62a2SHong Zhang     for (j=0; j<nrows; j++) rows_v[j] = j + rstart;
1836596e729fSHong Zhang 
1837bfbc38dcSHong Zhang     /* Get supporting edges and connected vertices */
1838596e729fSHong Zhang     ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr);
1839596e729fSHong Zhang 
1840596e729fSHong Zhang     for (e=0; e<nedges; e++) {
1841bfbc38dcSHong Zhang       /* Supporting edges */
1842596e729fSHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr);
1843596e729fSHong Zhang       ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr);
1844596e729fSHong Zhang 
18458675203cSHong Zhang       if (network->Jv) {
1846a4e85ca8SHong Zhang         Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */
18478675203cSHong Zhang       } else Juser = NULL;
1848bdcb62a2SHong Zhang       ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr);
1849596e729fSHong Zhang 
1850bfbc38dcSHong Zhang       /* Connected vertices */
1851d842c372SHong Zhang       ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr);
18522a945128SHong Zhang       vc = (v == cone[0]) ? cone[1]:cone[0];
18532a945128SHong Zhang 
185444aca652SHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,vc,&cstart);CHKERRQ(ierr);
185544aca652SHong Zhang       ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr);
1856a4e85ca8SHong Zhang 
18578675203cSHong Zhang       if (network->Jv) {
1858a4e85ca8SHong Zhang         Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */
18598675203cSHong Zhang       } else Juser = NULL;
1860bdcb62a2SHong Zhang       ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr);
1861596e729fSHong Zhang     }
1862596e729fSHong Zhang 
1863bfbc38dcSHong Zhang     /* Set matrix entries for vertex self */
18641ad426b7SHong Zhang     if (!ghost) {
1865596e729fSHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr);
18668675203cSHong Zhang       if (network->Jv) {
1867a4e85ca8SHong Zhang         Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */
18688675203cSHong Zhang       } else Juser = NULL;
1869bdcb62a2SHong Zhang       ierr = MatSetblock_private(Juser,nrows,rows_v,nrows,cstart,J);CHKERRQ(ierr);
1870bdcb62a2SHong Zhang     }
1871bdcb62a2SHong Zhang     if (ghost) {
1872bdcb62a2SHong Zhang       ierr = PetscFree(rows_v);CHKERRQ(ierr);
1873bdcb62a2SHong Zhang     }
18741ad426b7SHong Zhang   }
1875a4e85ca8SHong Zhang   ierr = PetscFree(rows);CHKERRQ(ierr);
1876bdcb62a2SHong Zhang 
18771ad426b7SHong Zhang   ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18781ad426b7SHong Zhang   ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1879dd6f46cdSHong Zhang 
18805f2c45f1SShri Abhyankar   ierr = MatSetDM(*J,dm);CHKERRQ(ierr);
18815f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
18825f2c45f1SShri Abhyankar }
18835f2c45f1SShri Abhyankar 
18845f2c45f1SShri Abhyankar PetscErrorCode DMDestroy_Network(DM dm)
18855f2c45f1SShri Abhyankar {
18865f2c45f1SShri Abhyankar   PetscErrorCode ierr;
18875f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
18882727e31bSShri Abhyankar   PetscInt       j;
18895f2c45f1SShri Abhyankar 
18905f2c45f1SShri Abhyankar   PetscFunctionBegin;
18918415c774SShri Abhyankar   if (--network->refct > 0) PetscFunctionReturn(0);
189283b2e829SHong Zhang   if (network->Je) {
189383b2e829SHong Zhang     ierr = PetscFree(network->Je);CHKERRQ(ierr);
189483b2e829SHong Zhang   }
189583b2e829SHong Zhang   if (network->Jv) {
1896883e35e8SHong Zhang     ierr = PetscFree(network->Jvptr);CHKERRQ(ierr);
189783b2e829SHong Zhang     ierr = PetscFree(network->Jv);CHKERRQ(ierr);
18981ad426b7SHong Zhang   }
189913c2a604SAdrian Maldonado 
190013c2a604SAdrian Maldonado   ierr = ISLocalToGlobalMappingDestroy(&network->vertex.mapping);CHKERRQ(ierr);
190113c2a604SAdrian Maldonado   ierr = PetscSectionDestroy(&network->vertex.DofSection);CHKERRQ(ierr);
190213c2a604SAdrian Maldonado   ierr = PetscSectionDestroy(&network->vertex.GlobalDofSection);CHKERRQ(ierr);
190313c2a604SAdrian Maldonado   if (network->vertex.sf) {
190413c2a604SAdrian Maldonado     ierr = PetscSFDestroy(&network->vertex.sf);CHKERRQ(ierr);
190513c2a604SAdrian Maldonado   }
190613c2a604SAdrian Maldonado   /* edge */
190713c2a604SAdrian Maldonado   ierr = ISLocalToGlobalMappingDestroy(&network->edge.mapping);CHKERRQ(ierr);
190813c2a604SAdrian Maldonado   ierr = PetscSectionDestroy(&network->edge.DofSection);CHKERRQ(ierr);
190913c2a604SAdrian Maldonado   ierr = PetscSectionDestroy(&network->edge.GlobalDofSection);CHKERRQ(ierr);
191013c2a604SAdrian Maldonado   if (network->edge.sf) {
191113c2a604SAdrian Maldonado     ierr = PetscSFDestroy(&network->edge.sf);CHKERRQ(ierr);
191213c2a604SAdrian Maldonado   }
19135f2c45f1SShri Abhyankar   ierr = DMDestroy(&network->plex);CHKERRQ(ierr);
19145f2c45f1SShri Abhyankar   network->edges = NULL;
19155f2c45f1SShri Abhyankar   ierr = PetscSectionDestroy(&network->DataSection);CHKERRQ(ierr);
19165f2c45f1SShri Abhyankar   ierr = PetscSectionDestroy(&network->DofSection);CHKERRQ(ierr);
191783b2e829SHong Zhang 
19182727e31bSShri Abhyankar   for(j=0; j < network->nsubnet; j++) {
19192727e31bSShri Abhyankar     ierr = PetscFree(network->subnet[j].edges);CHKERRQ(ierr);
19202727e31bSShri Abhyankar     ierr = PetscFree(network->subnet[j].vertices);CHKERRQ(ierr);
19212727e31bSShri Abhyankar   }
1922e2aaf10cSShri Abhyankar   ierr = PetscFree(network->subnet);CHKERRQ(ierr);
19235f2c45f1SShri Abhyankar   ierr = PetscFree(network->componentdataarray);CHKERRQ(ierr);
19245f2c45f1SShri Abhyankar   ierr = PetscFree(network->cvalue);CHKERRQ(ierr);
19255f2c45f1SShri Abhyankar   ierr = PetscFree(network->header);CHKERRQ(ierr);
19265f2c45f1SShri Abhyankar   ierr = PetscFree(network);CHKERRQ(ierr);
19275f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
19285f2c45f1SShri Abhyankar }
19295f2c45f1SShri Abhyankar 
19305f2c45f1SShri Abhyankar PetscErrorCode DMView_Network(DM dm, PetscViewer viewer)
19315f2c45f1SShri Abhyankar {
19325f2c45f1SShri Abhyankar   PetscErrorCode ierr;
19335f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
19345f2c45f1SShri Abhyankar 
19355f2c45f1SShri Abhyankar   PetscFunctionBegin;
19365f2c45f1SShri Abhyankar   ierr = DMView(network->plex,viewer);CHKERRQ(ierr);
19375f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
19385f2c45f1SShri Abhyankar }
19395f2c45f1SShri Abhyankar 
19405f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l)
19415f2c45f1SShri Abhyankar {
19425f2c45f1SShri Abhyankar   PetscErrorCode ierr;
19435f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
19445f2c45f1SShri Abhyankar 
19455f2c45f1SShri Abhyankar   PetscFunctionBegin;
19465f2c45f1SShri Abhyankar   ierr = DMGlobalToLocalBegin(network->plex,g,mode,l);CHKERRQ(ierr);
19475f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
19485f2c45f1SShri Abhyankar }
19495f2c45f1SShri Abhyankar 
19505f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l)
19515f2c45f1SShri Abhyankar {
19525f2c45f1SShri Abhyankar   PetscErrorCode ierr;
19535f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
19545f2c45f1SShri Abhyankar 
19555f2c45f1SShri Abhyankar   PetscFunctionBegin;
19565f2c45f1SShri Abhyankar   ierr = DMGlobalToLocalEnd(network->plex,g,mode,l);CHKERRQ(ierr);
19575f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
19585f2c45f1SShri Abhyankar }
19595f2c45f1SShri Abhyankar 
19605f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g)
19615f2c45f1SShri Abhyankar {
19625f2c45f1SShri Abhyankar   PetscErrorCode ierr;
19635f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
19645f2c45f1SShri Abhyankar 
19655f2c45f1SShri Abhyankar   PetscFunctionBegin;
19665f2c45f1SShri Abhyankar   ierr = DMLocalToGlobalBegin(network->plex,l,mode,g);CHKERRQ(ierr);
19675f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
19685f2c45f1SShri Abhyankar }
19695f2c45f1SShri Abhyankar 
19705f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g)
19715f2c45f1SShri Abhyankar {
19725f2c45f1SShri Abhyankar   PetscErrorCode ierr;
19735f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
19745f2c45f1SShri Abhyankar 
19755f2c45f1SShri Abhyankar   PetscFunctionBegin;
19765f2c45f1SShri Abhyankar   ierr = DMLocalToGlobalEnd(network->plex,l,mode,g);CHKERRQ(ierr);
19775f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
19785f2c45f1SShri Abhyankar }
1979