xref: /petsc/src/dm/impls/network/network.c (revision c3b11c7cc4acca4e9673a50a1eff0a14c056f9a3)
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;
149e2aaf10cSShri Abhyankar 
1506fefedf4SHong Zhang   if (network->nVertices) {
1516fefedf4SHong Zhang     ierr = PetscCalloc1(numCorners*network->nVertices,&vertexcoords);CHKERRQ(ierr);
1525f2c45f1SShri Abhyankar   }
153e2aaf10cSShri Abhyankar 
154e2aaf10cSShri Abhyankar   /* Create the edgelist for the network by concatenating edgelists of the subnetworks */
155e2aaf10cSShri Abhyankar   ierr = PetscCalloc1(2*network->nEdges,&network->edges);CHKERRQ(ierr);
156e2aaf10cSShri Abhyankar   for(i=0; i < network->nsubnet; i++) {
157e2aaf10cSShri Abhyankar     for(j = 0; j < network->subnet[i].nedge; j++) {
158e2aaf10cSShri Abhyankar       network->edges[2*ctr] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j];
159e2aaf10cSShri Abhyankar       network->edges[2*ctr+1] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j+1];
160e2aaf10cSShri Abhyankar       ctr++;
161e2aaf10cSShri Abhyankar     }
162e2aaf10cSShri Abhyankar   }
163e2aaf10cSShri Abhyankar 
164e2aaf10cSShri Abhyankar #if 0
165e2aaf10cSShri Abhyankar   for(i=0; i < network->nEdges; i++) {
166e2aaf10cSShri Abhyankar     ierr = PetscPrintf(PETSC_COMM_SELF,"[%D %D]",network->edges[2*i],network->edges[2*i+1]);CHKERRQ(ierr);
167e2aaf10cSShri Abhyankar   }
168e2aaf10cSShri Abhyankar #endif
169e2aaf10cSShri Abhyankar 
1706fefedf4SHong Zhang   ierr = DMPlexCreateFromCellList(PetscObjectComm((PetscObject)dm),dim,network->nEdges,network->nVertices,numCorners,PETSC_FALSE,network->edges,spacedim,vertexcoords,&network->plex);CHKERRQ(ierr);
1716fefedf4SHong Zhang   if (network->nVertices) {
1725f2c45f1SShri Abhyankar     ierr = PetscFree(vertexcoords);CHKERRQ(ierr);
1735f2c45f1SShri Abhyankar   }
174e2aaf10cSShri Abhyankar   ierr = PetscFree(network->edges);CHKERRQ(ierr);
175e2aaf10cSShri Abhyankar 
1765f2c45f1SShri Abhyankar   ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr);
1775f2c45f1SShri Abhyankar   ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr);
1785f2c45f1SShri Abhyankar   ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr);
1795f2c45f1SShri Abhyankar 
1805f2c45f1SShri Abhyankar   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm),&network->DataSection);CHKERRQ(ierr);
1815f2c45f1SShri Abhyankar   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm),&network->DofSection);CHKERRQ(ierr);
1825f2c45f1SShri Abhyankar   ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr);
1835f2c45f1SShri Abhyankar   ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr);
1845f2c45f1SShri Abhyankar 
1852727e31bSShri Abhyankar   /* Create vertices and edges array for the subnetworks */
1862727e31bSShri Abhyankar   for(j=0; j < network->nsubnet; j++) {
1872727e31bSShri Abhyankar     ierr = PetscCalloc1(network->subnet[j].nedge,&network->subnet[j].edges);CHKERRQ(ierr);
1882727e31bSShri Abhyankar     ierr = PetscCalloc1(network->subnet[j].nvtx,&network->subnet[j].vertices);CHKERRQ(ierr);
1892727e31bSShri Abhyankar     /* Temporarily setting nvtx and nedge to 0 so we can use them as counters in the below for loop.
1902727e31bSShri Abhyankar        These get updated when the vertices and edges are added. */
1912727e31bSShri Abhyankar     network->subnet[j].nvtx = network->subnet[j].nedge = 0;
1922727e31bSShri Abhyankar   }
1932727e31bSShri Abhyankar 
1945f2c45f1SShri Abhyankar   network->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType);
1956caa05f4SBarry Smith   ierr = PetscCalloc1(network->pEnd-network->pStart,&network->header);CHKERRQ(ierr);
196e2aaf10cSShri Abhyankar   for(i=network->eStart; i < network->eEnd; i++) {
197e2aaf10cSShri Abhyankar     network->header[i].index = i;   /* Global edge number */
198e2aaf10cSShri Abhyankar     for(j=0; j < network->nsubnet; j++) {
199e2aaf10cSShri Abhyankar       if((network->subnet[j].eStart <= i) && (i < network->subnet[j].eEnd)) {
200e2aaf10cSShri Abhyankar 	network->header[i].subnetid = j; /* Subnetwork id */
2012727e31bSShri Abhyankar 	network->subnet[j].edges[network->subnet[j].nedge++] = i;
202e2aaf10cSShri Abhyankar 	break;
203e2aaf10cSShri Abhyankar       }
2047b6afd5bSHong Zhang     }
2055f2c45f1SShri Abhyankar     network->header[i].ndata = 0;
2065f2c45f1SShri Abhyankar     ndata = network->header[i].ndata;
2075f2c45f1SShri Abhyankar     ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr);
2085f2c45f1SShri Abhyankar     network->header[i].offset[ndata] = 0;
2095f2c45f1SShri Abhyankar   }
210e2aaf10cSShri Abhyankar 
211e2aaf10cSShri Abhyankar   for(i=network->vStart; i < network->vEnd; i++) {
212e2aaf10cSShri Abhyankar     network->header[i].index = i - network->vStart;
213e2aaf10cSShri Abhyankar     for(j=0; j < network->nsubnet; j++) {
214e2aaf10cSShri Abhyankar       if((network->subnet[j].vStart <= i-network->vStart) && (i-network->vStart < network->subnet[j].vEnd)) {
215e2aaf10cSShri Abhyankar 	network->header[i].subnetid = j;
2162727e31bSShri Abhyankar 	network->subnet[j].vertices[network->subnet[j].nvtx++] = i;
217e2aaf10cSShri Abhyankar 	break;
218e2aaf10cSShri Abhyankar       }
219e2aaf10cSShri Abhyankar     }
220e2aaf10cSShri Abhyankar     network->header[i].ndata = 0;
221e2aaf10cSShri Abhyankar     ndata = network->header[i].ndata;
222e2aaf10cSShri Abhyankar     ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr);
223e2aaf10cSShri Abhyankar     network->header[i].offset[ndata] = 0;
224e2aaf10cSShri Abhyankar   }
225e2aaf10cSShri Abhyankar 
226854ce69bSBarry Smith   ierr = PetscMalloc1(network->pEnd-network->pStart,&network->cvalue);CHKERRQ(ierr);
227e2aaf10cSShri Abhyankar 
2285f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
2295f2c45f1SShri Abhyankar }
2305f2c45f1SShri Abhyankar 
23194ef8ddeSSatish Balay /*@C
2322727e31bSShri Abhyankar   DMNetworkGetSubnetworkInfo - Returns the info for the subnetwork
2332727e31bSShri Abhyankar 
2342727e31bSShri Abhyankar   Input Parameters
2352727e31bSShri Abhyankar + dm   - the number object
2362727e31bSShri Abhyankar - id   - the ID (integer) of the subnetwork
2372727e31bSShri Abhyankar 
2382727e31bSShri Abhyankar   Output Parameters
2392727e31bSShri Abhyankar + nv    - number of vertices (local)
2402727e31bSShri Abhyankar . ne    - number of edges (local)
2412727e31bSShri Abhyankar . vtx   - local vertices for this subnetwork
2422727e31bSShri Abhyankar . edge  - local edges for this subnetwork
2432727e31bSShri Abhyankar 
2442727e31bSShri Abhyankar   Notes:
2452727e31bSShri Abhyankar   Cannot call this routine before DMNetworkLayoutSetup()
2462727e31bSShri Abhyankar 
2472727e31bSShri Abhyankar .seealso: DMNetworkLayoutSetUp, DMNetworkCreate
2482727e31bSShri Abhyankar @*/
2492727e31bSShri Abhyankar PetscErrorCode DMNetworkGetSubnetworkInfo(DM netdm,PetscInt id,PetscInt *nv, PetscInt *ne,const PetscInt **vtx, const PetscInt **edge)
2502727e31bSShri Abhyankar {
2512727e31bSShri Abhyankar   DM_Network     *network = (DM_Network*) netdm->data;
2522727e31bSShri Abhyankar 
2532727e31bSShri Abhyankar   PetscFunctionBegin;
2542727e31bSShri Abhyankar   *nv = network->subnet[id].nvtx;
2552727e31bSShri Abhyankar   *ne = network->subnet[id].nedge;
2562727e31bSShri Abhyankar   *vtx = network->subnet[id].vertices;
2572727e31bSShri Abhyankar   *edge = network->subnet[id].edges;
2582727e31bSShri Abhyankar   PetscFunctionReturn(0);
2592727e31bSShri Abhyankar }
2602727e31bSShri Abhyankar 
2612727e31bSShri Abhyankar /*@C
2625f2c45f1SShri Abhyankar   DMNetworkRegisterComponent - Registers the network component
2635f2c45f1SShri Abhyankar 
2645f2c45f1SShri Abhyankar   Logically collective on DM
2655f2c45f1SShri Abhyankar 
2665f2c45f1SShri Abhyankar   Input Parameters
2675f2c45f1SShri Abhyankar + dm   - the network object
2685f2c45f1SShri Abhyankar . name - the component name
2695f2c45f1SShri Abhyankar - size - the storage size in bytes for this component data
2705f2c45f1SShri Abhyankar 
2715f2c45f1SShri Abhyankar    Output Parameters
2725f2c45f1SShri Abhyankar .   key - an integer key that defines the component
2735f2c45f1SShri Abhyankar 
2745f2c45f1SShri Abhyankar    Notes
2755f2c45f1SShri Abhyankar    This routine should be called by all processors before calling DMNetworkLayoutSetup().
2765f2c45f1SShri Abhyankar 
2775f2c45f1SShri Abhyankar    Level: intermediate
2785f2c45f1SShri Abhyankar 
2795f2c45f1SShri Abhyankar .seealso: DMNetworkLayoutSetUp, DMNetworkCreate
2805f2c45f1SShri Abhyankar @*/
2815f2c45f1SShri Abhyankar PetscErrorCode DMNetworkRegisterComponent(DM dm,const char *name,PetscInt size,PetscInt *key)
2825f2c45f1SShri Abhyankar {
2835f2c45f1SShri Abhyankar   PetscErrorCode        ierr;
2845f2c45f1SShri Abhyankar   DM_Network            *network = (DM_Network*) dm->data;
2855f2c45f1SShri Abhyankar   DMNetworkComponent    *component=&network->component[network->ncomponent];
2865f2c45f1SShri Abhyankar   PetscBool             flg=PETSC_FALSE;
2875f2c45f1SShri Abhyankar   PetscInt              i;
2885f2c45f1SShri Abhyankar 
2895f2c45f1SShri Abhyankar   PetscFunctionBegin;
2905f2c45f1SShri Abhyankar 
2915f2c45f1SShri Abhyankar   for (i=0; i < network->ncomponent; i++) {
2925f2c45f1SShri Abhyankar     ierr = PetscStrcmp(component->name,name,&flg);CHKERRQ(ierr);
2935f2c45f1SShri Abhyankar     if (flg) {
2945f2c45f1SShri Abhyankar       *key = i;
2955f2c45f1SShri Abhyankar       PetscFunctionReturn(0);
2965f2c45f1SShri Abhyankar     }
2975f2c45f1SShri Abhyankar   }
2985f2c45f1SShri Abhyankar 
2995f2c45f1SShri Abhyankar   ierr = PetscStrcpy(component->name,name);CHKERRQ(ierr);
3005f2c45f1SShri Abhyankar   component->size = size/sizeof(DMNetworkComponentGenericDataType);
3015f2c45f1SShri Abhyankar   *key = network->ncomponent;
3025f2c45f1SShri Abhyankar   network->ncomponent++;
3035f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
3045f2c45f1SShri Abhyankar }
3055f2c45f1SShri Abhyankar 
3065f2c45f1SShri Abhyankar /*@
3075f2c45f1SShri Abhyankar   DMNetworkGetVertexRange - Get the bounds [start, end) for the vertices.
3085f2c45f1SShri Abhyankar 
3095f2c45f1SShri Abhyankar   Not Collective
3105f2c45f1SShri Abhyankar 
3115f2c45f1SShri Abhyankar   Input Parameters:
3125f2c45f1SShri Abhyankar + dm - The DMNetwork object
3135f2c45f1SShri Abhyankar 
3145f2c45f1SShri Abhyankar   Output Paramters:
3155f2c45f1SShri Abhyankar + vStart - The first vertex point
3165f2c45f1SShri Abhyankar - vEnd   - One beyond the last vertex point
3175f2c45f1SShri Abhyankar 
3185f2c45f1SShri Abhyankar   Level: intermediate
3195f2c45f1SShri Abhyankar 
3205f2c45f1SShri Abhyankar .seealso: DMNetworkGetEdgeRange
3215f2c45f1SShri Abhyankar @*/
3225f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVertexRange(DM dm,PetscInt *vStart,PetscInt *vEnd)
3235f2c45f1SShri Abhyankar {
3245f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
3255f2c45f1SShri Abhyankar 
3265f2c45f1SShri Abhyankar   PetscFunctionBegin;
3275f2c45f1SShri Abhyankar   if (vStart) *vStart = network->vStart;
3285f2c45f1SShri Abhyankar   if (vEnd) *vEnd = network->vEnd;
3295f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
3305f2c45f1SShri Abhyankar }
3315f2c45f1SShri Abhyankar 
3325f2c45f1SShri Abhyankar /*@
3335f2c45f1SShri Abhyankar   DMNetworkGetEdgeRange - Get the bounds [start, end) for the edges.
3345f2c45f1SShri Abhyankar 
3355f2c45f1SShri Abhyankar   Not Collective
3365f2c45f1SShri Abhyankar 
3375f2c45f1SShri Abhyankar   Input Parameters:
3385f2c45f1SShri Abhyankar + dm - The DMNetwork object
3395f2c45f1SShri Abhyankar 
3405f2c45f1SShri Abhyankar   Output Paramters:
3415f2c45f1SShri Abhyankar + eStart - The first edge point
3425f2c45f1SShri Abhyankar - eEnd   - One beyond the last edge point
3435f2c45f1SShri Abhyankar 
3445f2c45f1SShri Abhyankar   Level: intermediate
3455f2c45f1SShri Abhyankar 
3465f2c45f1SShri Abhyankar .seealso: DMNetworkGetVertexRange
3475f2c45f1SShri Abhyankar @*/
3485f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetEdgeRange(DM dm,PetscInt *eStart,PetscInt *eEnd)
3495f2c45f1SShri Abhyankar {
3505f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
3515f2c45f1SShri Abhyankar 
3525f2c45f1SShri Abhyankar   PetscFunctionBegin;
3535f2c45f1SShri Abhyankar   if (eStart) *eStart = network->eStart;
3545f2c45f1SShri Abhyankar   if (eEnd) *eEnd = network->eEnd;
3555f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
3565f2c45f1SShri Abhyankar }
3575f2c45f1SShri Abhyankar 
3587b6afd5bSHong Zhang /*@
359e85e6aecSHong Zhang   DMNetworkGetGlobalEdgeIndex - Get the user global numbering for the edge.
3607b6afd5bSHong Zhang 
3617b6afd5bSHong Zhang   Not Collective
3627b6afd5bSHong Zhang 
3637b6afd5bSHong Zhang   Input Parameters:
3647b6afd5bSHong Zhang + dm - DMNetwork object
365e85e6aecSHong Zhang - p  - edge point
3667b6afd5bSHong Zhang 
3677b6afd5bSHong Zhang   Output Paramters:
368e85e6aecSHong Zhang . index - user global numbering for the edge
3697b6afd5bSHong Zhang 
3707b6afd5bSHong Zhang   Level: intermediate
3717b6afd5bSHong Zhang 
372e85e6aecSHong Zhang .seealso: DMNetworkGetGlobalVertexIndex
3737b6afd5bSHong Zhang @*/
374e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalEdgeIndex(DM dm,PetscInt p,PetscInt *index)
3757b6afd5bSHong Zhang {
3767b6afd5bSHong Zhang   PetscErrorCode    ierr;
3777b6afd5bSHong Zhang   DM_Network        *network = (DM_Network*)dm->data;
3787b6afd5bSHong Zhang   PetscInt          offsetp;
3797b6afd5bSHong Zhang   DMNetworkComponentHeader header;
3807b6afd5bSHong Zhang 
3817b6afd5bSHong Zhang   PetscFunctionBegin;
3827b6afd5bSHong Zhang   ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr);
3837b6afd5bSHong Zhang   header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp);
384e85e6aecSHong Zhang   *index = header->index;
3857b6afd5bSHong Zhang   PetscFunctionReturn(0);
3867b6afd5bSHong Zhang }
3877b6afd5bSHong Zhang 
3885f2c45f1SShri Abhyankar /*@
389e85e6aecSHong Zhang   DMNetworkGetGlobalVertexIndex - Get the user global numbering for the vertex.
390e85e6aecSHong Zhang 
391e85e6aecSHong Zhang   Not Collective
392e85e6aecSHong Zhang 
393e85e6aecSHong Zhang   Input Parameters:
394e85e6aecSHong Zhang + dm - DMNetwork object
395e85e6aecSHong Zhang - p  - vertex point
396e85e6aecSHong Zhang 
397e85e6aecSHong Zhang   Output Paramters:
398e85e6aecSHong Zhang . index - user global numbering for the vertex
399e85e6aecSHong Zhang 
400e85e6aecSHong Zhang   Level: intermediate
401e85e6aecSHong Zhang 
402e85e6aecSHong Zhang .seealso: DMNetworkGetGlobalEdgeIndex
403e85e6aecSHong Zhang @*/
404e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalVertexIndex(DM dm,PetscInt p,PetscInt *index)
405e85e6aecSHong Zhang {
406e85e6aecSHong Zhang   PetscErrorCode    ierr;
407e85e6aecSHong Zhang   DM_Network        *network = (DM_Network*)dm->data;
408e85e6aecSHong Zhang   PetscInt          offsetp;
409e85e6aecSHong Zhang   DMNetworkComponentHeader header;
410e85e6aecSHong Zhang 
411e85e6aecSHong Zhang   PetscFunctionBegin;
412e85e6aecSHong Zhang   ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr);
413e85e6aecSHong Zhang   header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp);
414e85e6aecSHong Zhang   *index = header->index;
415e85e6aecSHong Zhang   PetscFunctionReturn(0);
416e85e6aecSHong Zhang }
417e85e6aecSHong Zhang 
418*c3b11c7cSShri Abhyankar /*
419*c3b11c7cSShri Abhyankar   DMNetworkGetComponentKeyOffset - Gets the type along with the offset for indexing the
420*c3b11c7cSShri Abhyankar                                     component value from the component data array
421*c3b11c7cSShri Abhyankar 
422*c3b11c7cSShri Abhyankar   Not Collective
423*c3b11c7cSShri Abhyankar 
424*c3b11c7cSShri Abhyankar   Input Parameters:
425*c3b11c7cSShri Abhyankar + dm      - The DMNetwork object
426*c3b11c7cSShri Abhyankar . p       - vertex/edge point
427*c3b11c7cSShri Abhyankar - compnum - component number
428*c3b11c7cSShri Abhyankar 
429*c3b11c7cSShri Abhyankar   Output Parameters:
430*c3b11c7cSShri Abhyankar + compkey - the key obtained when registering the component
431*c3b11c7cSShri Abhyankar - offset  - offset into the component data array associated with the vertex/edge point
432*c3b11c7cSShri Abhyankar 
433*c3b11c7cSShri Abhyankar   Notes:
434*c3b11c7cSShri Abhyankar   Typical usage:
435*c3b11c7cSShri Abhyankar 
436*c3b11c7cSShri Abhyankar   DMNetworkGetComponentDataArray(dm, &arr);
437*c3b11c7cSShri Abhyankar   DMNetworkGetVertex/EdgeRange(dm,&Start,&End);
438*c3b11c7cSShri Abhyankar   Loop over vertices or edges
439*c3b11c7cSShri Abhyankar     DMNetworkGetNumComponents(dm,v,&numcomps);
440*c3b11c7cSShri Abhyankar     Loop over numcomps
441*c3b11c7cSShri Abhyankar       DMNetworkGetComponentKeyOffset(dm,v,compnum,&key,&offset);
442*c3b11c7cSShri Abhyankar       compdata = (UserCompDataType)(arr+offset);
443*c3b11c7cSShri Abhyankar 
444*c3b11c7cSShri Abhyankar   Level: intermediate
445*c3b11c7cSShri Abhyankar 
446*c3b11c7cSShri Abhyankar .seealso: DMNetworkGetNumComponents, DMNetworkGetComponentDataArray,
447*c3b11c7cSShri Abhyankar */
448*c3b11c7cSShri Abhyankar PetscErrorCode DMNetworkGetComponentKeyOffset(DM dm,PetscInt p, PetscInt compnum, PetscInt *compkey, PetscInt *offset)
449*c3b11c7cSShri Abhyankar {
450*c3b11c7cSShri Abhyankar   PetscErrorCode           ierr;
451*c3b11c7cSShri Abhyankar   PetscInt                 offsetp;
452*c3b11c7cSShri Abhyankar   DMNetworkComponentHeader header;
453*c3b11c7cSShri Abhyankar   DM_Network               *network = (DM_Network*)dm->data;
454*c3b11c7cSShri Abhyankar 
455*c3b11c7cSShri Abhyankar   PetscFunctionBegin;
456*c3b11c7cSShri Abhyankar   ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr);
457*c3b11c7cSShri Abhyankar   header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp);
458*c3b11c7cSShri Abhyankar   if (compkey) *compkey = header->key[compnum];
459*c3b11c7cSShri Abhyankar   if (offset) *offset  = offsetp+network->dataheadersize+header->offset[compnum];
460*c3b11c7cSShri Abhyankar   PetscFunctionReturn(0);
461*c3b11c7cSShri Abhyankar }
462*c3b11c7cSShri Abhyankar 
463*c3b11c7cSShri Abhyankar /*@
464*c3b11c7cSShri Abhyankar   DMNetworkGetComponent - Returns the network component and its key
465*c3b11c7cSShri Abhyankar 
466*c3b11c7cSShri Abhyankar   Not Collective
467*c3b11c7cSShri Abhyankar 
468*c3b11c7cSShri Abhyankar   Input Parameters
469*c3b11c7cSShri Abhyankar + dm - DMNetwork object
470*c3b11c7cSShri Abhyankar . p  - edge or vertex point
471*c3b11c7cSShri Abhyankar - compnum - component number
472*c3b11c7cSShri Abhyankar 
473*c3b11c7cSShri Abhyankar   Output Parameters:
474*c3b11c7cSShri Abhyankar + compkey - the key set for this computing during registration
475*c3b11c7cSShri Abhyankar - component - the component data
476*c3b11c7cSShri Abhyankar 
477*c3b11c7cSShri Abhyankar   Notes:
478*c3b11c7cSShri Abhyankar   Typical usage:
479*c3b11c7cSShri Abhyankar 
480*c3b11c7cSShri Abhyankar   DMNetworkGetVertex/EdgeRange(dm,&Start,&End);
481*c3b11c7cSShri Abhyankar   Loop over vertices or edges
482*c3b11c7cSShri Abhyankar     DMNetworkGetNumComponents(dm,v,&numcomps);
483*c3b11c7cSShri Abhyankar     Loop over numcomps
484*c3b11c7cSShri Abhyankar       DMNetworkGetComponent(dm,v,compnum,&key,&component);
485*c3b11c7cSShri Abhyankar 
486*c3b11c7cSShri Abhyankar   Level: intermediate
487*c3b11c7cSShri Abhyankar 
488*c3b11c7cSShri Abhyankar .seealso: DMNetworkGetNumComponents, DMNetworkGetVariableOffset
489*c3b11c7cSShri Abhyankar @*/
490*c3b11c7cSShri Abhyankar PetscErrorCode DMNetworkGetComponent(DM dm, PetscInt p, PetscInt compnum, PetscInt *key, void **component)
491*c3b11c7cSShri Abhyankar {
492*c3b11c7cSShri Abhyankar   PetscErrorCode ierr;
493*c3b11c7cSShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
494*c3b11c7cSShri Abhyankar   PetscInt       offsetd;
495*c3b11c7cSShri Abhyankar 
496*c3b11c7cSShri Abhyankar   PetscFunctionBegin;
497*c3b11c7cSShri Abhyankar 
498*c3b11c7cSShri Abhyankar   ierr = DMNetworkGetComponentKeyOffset(dm,p,compnum,key,&offsetd);CHKERRQ(ierr);
499*c3b11c7cSShri Abhyankar   *component = network->componentdataarray+offsetd;
500*c3b11c7cSShri Abhyankar 
501*c3b11c7cSShri Abhyankar   PetscFunctionReturn(0);
502*c3b11c7cSShri Abhyankar }
503*c3b11c7cSShri Abhyankar 
504e85e6aecSHong Zhang /*@
505325661f6SSatish Balay   DMNetworkAddComponent - Adds a network component at the given point (vertex/edge)
5065f2c45f1SShri Abhyankar 
5075f2c45f1SShri Abhyankar   Not Collective
5085f2c45f1SShri Abhyankar 
5095f2c45f1SShri Abhyankar   Input Parameters:
5105f2c45f1SShri Abhyankar + dm           - The DMNetwork object
5115f2c45f1SShri Abhyankar . p            - vertex/edge point
5125f2c45f1SShri Abhyankar . componentkey - component key returned while registering the component
5135f2c45f1SShri Abhyankar - compvalue    - pointer to the data structure for the component
5145f2c45f1SShri Abhyankar 
5155f2c45f1SShri Abhyankar   Level: intermediate
5165f2c45f1SShri Abhyankar 
5175f2c45f1SShri Abhyankar .seealso: DMNetworkGetVertexRange, DMNetworkGetEdgeRange, DMNetworkRegisterComponent
5185f2c45f1SShri Abhyankar @*/
5195f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddComponent(DM dm, PetscInt p,PetscInt componentkey,void* compvalue)
5205f2c45f1SShri Abhyankar {
5215f2c45f1SShri Abhyankar   DM_Network               *network = (DM_Network*)dm->data;
52243a39a44SBarry Smith   DMNetworkComponent       *component = &network->component[componentkey];
5235f2c45f1SShri Abhyankar   DMNetworkComponentHeader header = &network->header[p];
5245f2c45f1SShri Abhyankar   DMNetworkComponentValue  cvalue = &network->cvalue[p];
5255f2c45f1SShri Abhyankar   PetscErrorCode           ierr;
5265f2c45f1SShri Abhyankar 
5275f2c45f1SShri Abhyankar   PetscFunctionBegin;
528fa58f0a9SHong 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);
529fa58f0a9SHong Zhang 
53043a39a44SBarry Smith   header->size[header->ndata] = component->size;
53143a39a44SBarry Smith   ierr = PetscSectionAddDof(network->DataSection,p,component->size);CHKERRQ(ierr);
5325f2c45f1SShri Abhyankar   header->key[header->ndata] = componentkey;
5335f2c45f1SShri Abhyankar   if (header->ndata != 0) header->offset[header->ndata] = header->offset[header->ndata-1] + header->size[header->ndata-1];
5345f2c45f1SShri Abhyankar 
5355f2c45f1SShri Abhyankar   cvalue->data[header->ndata] = (void*)compvalue;
5365f2c45f1SShri Abhyankar   header->ndata++;
5375f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
5385f2c45f1SShri Abhyankar }
5395f2c45f1SShri Abhyankar 
5405f2c45f1SShri Abhyankar /*@
5415f2c45f1SShri Abhyankar   DMNetworkGetNumComponents - Get the number of components at a vertex/edge
5425f2c45f1SShri Abhyankar 
5435f2c45f1SShri Abhyankar   Not Collective
5445f2c45f1SShri Abhyankar 
5455f2c45f1SShri Abhyankar   Input Parameters:
5465f2c45f1SShri Abhyankar + dm - The DMNetwork object
5475f2c45f1SShri Abhyankar . p  - vertex/edge point
5485f2c45f1SShri Abhyankar 
5495f2c45f1SShri Abhyankar   Output Parameters:
5505f2c45f1SShri Abhyankar . numcomponents - Number of components at the vertex/edge
5515f2c45f1SShri Abhyankar 
5525f2c45f1SShri Abhyankar   Level: intermediate
5535f2c45f1SShri Abhyankar 
5545f2c45f1SShri Abhyankar .seealso: DMNetworkRegisterComponent, DMNetworkAddComponent
5555f2c45f1SShri Abhyankar @*/
5565f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetNumComponents(DM dm,PetscInt p,PetscInt *numcomponents)
5575f2c45f1SShri Abhyankar {
5585f2c45f1SShri Abhyankar   PetscErrorCode ierr;
5595f2c45f1SShri Abhyankar   PetscInt       offset;
5605f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
5615f2c45f1SShri Abhyankar 
5625f2c45f1SShri Abhyankar   PetscFunctionBegin;
5635f2c45f1SShri Abhyankar   ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr);
5645f2c45f1SShri Abhyankar   *numcomponents = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata;
5655f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
5665f2c45f1SShri Abhyankar }
5675f2c45f1SShri Abhyankar 
5685f2c45f1SShri Abhyankar /*@
5695f2c45f1SShri Abhyankar   DMNetworkGetVariableOffset - Get the offset for accessing the variable associated with the given vertex/edge from the local vector.
5705f2c45f1SShri Abhyankar 
5715f2c45f1SShri Abhyankar   Not Collective
5725f2c45f1SShri Abhyankar 
5735f2c45f1SShri Abhyankar   Input Parameters:
5745f2c45f1SShri Abhyankar + dm     - The DMNetwork object
5755f2c45f1SShri Abhyankar - p      - the edge/vertex point
5765f2c45f1SShri Abhyankar 
5775f2c45f1SShri Abhyankar   Output Parameters:
5785f2c45f1SShri Abhyankar . offset - the offset
5795f2c45f1SShri Abhyankar 
5805f2c45f1SShri Abhyankar   Level: intermediate
5815f2c45f1SShri Abhyankar 
5825f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector
5835f2c45f1SShri Abhyankar @*/
5845f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableOffset(DM dm,PetscInt p,PetscInt *offset)
5855f2c45f1SShri Abhyankar {
5865f2c45f1SShri Abhyankar   PetscErrorCode ierr;
5875f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
5885f2c45f1SShri Abhyankar 
5895f2c45f1SShri Abhyankar   PetscFunctionBegin;
5905f78ed8bSShri Abhyankar   ierr = PetscSectionGetOffset(network->plex->defaultSection,p,offset);CHKERRQ(ierr);
5915f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
5925f2c45f1SShri Abhyankar }
5935f2c45f1SShri Abhyankar 
5945f2c45f1SShri Abhyankar /*@
5955f2c45f1SShri Abhyankar   DMNetworkGetVariableGlobalOffset - Get the global offset for the variable associated with the given vertex/edge from the global vector.
5965f2c45f1SShri Abhyankar 
5975f2c45f1SShri Abhyankar   Not Collective
5985f2c45f1SShri Abhyankar 
5995f2c45f1SShri Abhyankar   Input Parameters:
6005f2c45f1SShri Abhyankar + dm      - The DMNetwork object
6015f2c45f1SShri Abhyankar - p       - the edge/vertex point
6025f2c45f1SShri Abhyankar 
6035f2c45f1SShri Abhyankar   Output Parameters:
6045f2c45f1SShri Abhyankar . offsetg - the offset
6055f2c45f1SShri Abhyankar 
6065f2c45f1SShri Abhyankar   Level: intermediate
6075f2c45f1SShri Abhyankar 
6085f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableOffset, DMGetLocalVector
6095f2c45f1SShri Abhyankar @*/
6105f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableGlobalOffset(DM dm,PetscInt p,PetscInt *offsetg)
6115f2c45f1SShri Abhyankar {
6125f2c45f1SShri Abhyankar   PetscErrorCode ierr;
6135f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
6145f2c45f1SShri Abhyankar 
6155f2c45f1SShri Abhyankar   PetscFunctionBegin;
6165f78ed8bSShri Abhyankar   ierr = PetscSectionGetOffset(network->plex->defaultGlobalSection,p,offsetg);CHKERRQ(ierr);
6176fefedf4SHong Zhang   if (*offsetg < 0) *offsetg = -(*offsetg + 1); /* Convert to actual global offset for ghost vertex */
6185f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
6195f2c45f1SShri Abhyankar }
6205f2c45f1SShri Abhyankar 
62124121865SAdrian Maldonado /*@
62224121865SAdrian Maldonado   DMNetworkGetEdgeOffset - Get the offset for accessing the variable associated with the given edge from the local subvector.
62324121865SAdrian Maldonado 
62424121865SAdrian Maldonado   Not Collective
62524121865SAdrian Maldonado 
62624121865SAdrian Maldonado   Input Parameters:
62724121865SAdrian Maldonado + dm     - The DMNetwork object
62824121865SAdrian Maldonado - p      - the edge point
62924121865SAdrian Maldonado 
63024121865SAdrian Maldonado   Output Parameters:
63124121865SAdrian Maldonado . offset - the offset
63224121865SAdrian Maldonado 
63324121865SAdrian Maldonado   Level: intermediate
63424121865SAdrian Maldonado 
63524121865SAdrian Maldonado .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector
63624121865SAdrian Maldonado @*/
63724121865SAdrian Maldonado PetscErrorCode DMNetworkGetEdgeOffset(DM dm,PetscInt p,PetscInt *offset)
63824121865SAdrian Maldonado {
63924121865SAdrian Maldonado   PetscErrorCode ierr;
64024121865SAdrian Maldonado   DM_Network     *network = (DM_Network*)dm->data;
64124121865SAdrian Maldonado 
64224121865SAdrian Maldonado   PetscFunctionBegin;
64324121865SAdrian Maldonado 
64424121865SAdrian Maldonado   ierr = PetscSectionGetOffset(network->edge.DofSection,p,offset);CHKERRQ(ierr);
64524121865SAdrian Maldonado   PetscFunctionReturn(0);
64624121865SAdrian Maldonado }
64724121865SAdrian Maldonado 
64824121865SAdrian Maldonado /*@
64924121865SAdrian Maldonado   DMNetworkGetVertexOffset - Get the offset for accessing the variable associated with the given vertex from the local subvector.
65024121865SAdrian Maldonado 
65124121865SAdrian Maldonado   Not Collective
65224121865SAdrian Maldonado 
65324121865SAdrian Maldonado   Input Parameters:
65424121865SAdrian Maldonado + dm     - The DMNetwork object
65524121865SAdrian Maldonado - p      - the vertex point
65624121865SAdrian Maldonado 
65724121865SAdrian Maldonado   Output Parameters:
65824121865SAdrian Maldonado . offset - the offset
65924121865SAdrian Maldonado 
66024121865SAdrian Maldonado   Level: intermediate
66124121865SAdrian Maldonado 
66224121865SAdrian Maldonado .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector
66324121865SAdrian Maldonado @*/
66424121865SAdrian Maldonado PetscErrorCode DMNetworkGetVertexOffset(DM dm,PetscInt p,PetscInt *offset)
66524121865SAdrian Maldonado {
66624121865SAdrian Maldonado   PetscErrorCode ierr;
66724121865SAdrian Maldonado   DM_Network     *network = (DM_Network*)dm->data;
66824121865SAdrian Maldonado 
66924121865SAdrian Maldonado   PetscFunctionBegin;
67024121865SAdrian Maldonado 
67124121865SAdrian Maldonado   p -= network->vStart;
67224121865SAdrian Maldonado 
67324121865SAdrian Maldonado   ierr = PetscSectionGetOffset(network->vertex.DofSection,p,offset);CHKERRQ(ierr);
67424121865SAdrian Maldonado   PetscFunctionReturn(0);
67524121865SAdrian Maldonado }
6765f2c45f1SShri Abhyankar /*@
6775f2c45f1SShri Abhyankar   DMNetworkAddNumVariables - Add number of variables associated with a given point.
6785f2c45f1SShri Abhyankar 
6795f2c45f1SShri Abhyankar   Not Collective
6805f2c45f1SShri Abhyankar 
6815f2c45f1SShri Abhyankar   Input Parameters:
6825f2c45f1SShri Abhyankar + dm   - The DMNetworkObject
6835f2c45f1SShri Abhyankar . p    - the vertex/edge point
6845f2c45f1SShri Abhyankar - nvar - number of additional variables
6855f2c45f1SShri Abhyankar 
6865f2c45f1SShri Abhyankar   Level: intermediate
6875f2c45f1SShri Abhyankar 
6885f2c45f1SShri Abhyankar .seealso: DMNetworkSetNumVariables
6895f2c45f1SShri Abhyankar @*/
6905f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddNumVariables(DM dm,PetscInt p,PetscInt nvar)
6915f2c45f1SShri Abhyankar {
6925f2c45f1SShri Abhyankar   PetscErrorCode ierr;
6935f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
6945f2c45f1SShri Abhyankar 
6955f2c45f1SShri Abhyankar   PetscFunctionBegin;
6965f2c45f1SShri Abhyankar   ierr = PetscSectionAddDof(network->DofSection,p,nvar);CHKERRQ(ierr);
6975f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
6985f2c45f1SShri Abhyankar }
6995f2c45f1SShri Abhyankar 
70027f51fceSHong Zhang /*@
70127f51fceSHong Zhang   DMNetworkGetNumVariables - Gets number of variables for a vertex/edge point.
70227f51fceSHong Zhang 
70327f51fceSHong Zhang   Not Collective
70427f51fceSHong Zhang 
70527f51fceSHong Zhang   Input Parameters:
70627f51fceSHong Zhang + dm   - The DMNetworkObject
70727f51fceSHong Zhang - p    - the vertex/edge point
70827f51fceSHong Zhang 
70927f51fceSHong Zhang   Output Parameters:
71027f51fceSHong Zhang . nvar - number of variables
71127f51fceSHong Zhang 
71227f51fceSHong Zhang   Level: intermediate
71327f51fceSHong Zhang 
71427f51fceSHong Zhang .seealso: DMNetworkAddNumVariables, DMNetworkSddNumVariables
71527f51fceSHong Zhang @*/
71627f51fceSHong Zhang PetscErrorCode DMNetworkGetNumVariables(DM dm,PetscInt p,PetscInt *nvar)
71727f51fceSHong Zhang {
71827f51fceSHong Zhang   PetscErrorCode ierr;
71927f51fceSHong Zhang   DM_Network     *network = (DM_Network*)dm->data;
72027f51fceSHong Zhang 
72127f51fceSHong Zhang   PetscFunctionBegin;
72227f51fceSHong Zhang   ierr = PetscSectionGetDof(network->DofSection,p,nvar);CHKERRQ(ierr);
72327f51fceSHong Zhang   PetscFunctionReturn(0);
72427f51fceSHong Zhang }
72527f51fceSHong Zhang 
7265f2c45f1SShri Abhyankar /*@
7275f2c45f1SShri Abhyankar   DMNetworkSetNumVariables - Sets number of variables for a vertex/edge point.
7285f2c45f1SShri Abhyankar 
7295f2c45f1SShri Abhyankar   Not Collective
7305f2c45f1SShri Abhyankar 
7315f2c45f1SShri Abhyankar   Input Parameters:
7325f2c45f1SShri Abhyankar + dm   - The DMNetworkObject
7335f2c45f1SShri Abhyankar . p    - the vertex/edge point
7345f2c45f1SShri Abhyankar - nvar - number of variables
7355f2c45f1SShri Abhyankar 
7365f2c45f1SShri Abhyankar   Level: intermediate
7375f2c45f1SShri Abhyankar 
7385f2c45f1SShri Abhyankar .seealso: DMNetworkAddNumVariables
7395f2c45f1SShri Abhyankar @*/
7405f2c45f1SShri Abhyankar PetscErrorCode DMNetworkSetNumVariables(DM dm,PetscInt p,PetscInt nvar)
7415f2c45f1SShri Abhyankar {
7425f2c45f1SShri Abhyankar   PetscErrorCode ierr;
7435f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
7445f2c45f1SShri Abhyankar 
7455f2c45f1SShri Abhyankar   PetscFunctionBegin;
7465f2c45f1SShri Abhyankar   ierr = PetscSectionSetDof(network->DofSection,p,nvar);CHKERRQ(ierr);
7475f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
7485f2c45f1SShri Abhyankar }
7495f2c45f1SShri Abhyankar 
7505f2c45f1SShri Abhyankar /* Sets up the array that holds the data for all components and its associated section. This
7515f2c45f1SShri Abhyankar    function is called during DMSetUp() */
7525f2c45f1SShri Abhyankar PetscErrorCode DMNetworkComponentSetUp(DM dm)
7535f2c45f1SShri Abhyankar {
7545f2c45f1SShri Abhyankar   PetscErrorCode              ierr;
7555f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
7565f2c45f1SShri Abhyankar   PetscInt                    arr_size;
7575f2c45f1SShri Abhyankar   PetscInt                    p,offset,offsetp;
7585f2c45f1SShri Abhyankar   DMNetworkComponentHeader header;
7595f2c45f1SShri Abhyankar   DMNetworkComponentValue  cvalue;
7605f2c45f1SShri Abhyankar   DMNetworkComponentGenericDataType      *componentdataarray;
7615f2c45f1SShri Abhyankar   PetscInt ncomp, i;
7625f2c45f1SShri Abhyankar 
7635f2c45f1SShri Abhyankar   PetscFunctionBegin;
7645f2c45f1SShri Abhyankar   ierr = PetscSectionSetUp(network->DataSection);CHKERRQ(ierr);
7655f2c45f1SShri Abhyankar   ierr = PetscSectionGetStorageSize(network->DataSection,&arr_size);CHKERRQ(ierr);
76675b160a0SShri Abhyankar   ierr = PetscMalloc1(arr_size,&network->componentdataarray);CHKERRQ(ierr);
7675f2c45f1SShri Abhyankar   componentdataarray = network->componentdataarray;
7685f2c45f1SShri Abhyankar   for (p = network->pStart; p < network->pEnd; p++) {
7695f2c45f1SShri Abhyankar     ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr);
7705f2c45f1SShri Abhyankar     /* Copy header */
7715f2c45f1SShri Abhyankar     header = &network->header[p];
772302440fdSBarry Smith     ierr = PetscMemcpy(componentdataarray+offsetp,header,network->dataheadersize*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr);
7735f2c45f1SShri Abhyankar     /* Copy data */
7745f2c45f1SShri Abhyankar     cvalue = &network->cvalue[p];
7755f2c45f1SShri Abhyankar     ncomp = header->ndata;
7765f2c45f1SShri Abhyankar     for (i = 0; i < ncomp; i++) {
7775f2c45f1SShri Abhyankar       offset = offsetp + network->dataheadersize + header->offset[i];
778302440fdSBarry Smith       ierr = PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr);
7795f2c45f1SShri Abhyankar     }
7805f2c45f1SShri Abhyankar   }
7815f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
7825f2c45f1SShri Abhyankar }
7835f2c45f1SShri Abhyankar 
7845f2c45f1SShri Abhyankar /* Sets up the section for dofs. This routine is called during DMSetUp() */
7855f2c45f1SShri Abhyankar PetscErrorCode DMNetworkVariablesSetUp(DM dm)
7865f2c45f1SShri Abhyankar {
7875f2c45f1SShri Abhyankar   PetscErrorCode ierr;
7885f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
7895f2c45f1SShri Abhyankar 
7905f2c45f1SShri Abhyankar   PetscFunctionBegin;
7915f2c45f1SShri Abhyankar   ierr = PetscSectionSetUp(network->DofSection);CHKERRQ(ierr);
7925f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
7935f2c45f1SShri Abhyankar }
7945f2c45f1SShri Abhyankar 
7955f2c45f1SShri Abhyankar /*@C
7965f2c45f1SShri Abhyankar   DMNetworkGetComponentDataArray - Returns the component data array
7975f2c45f1SShri Abhyankar 
7985f2c45f1SShri Abhyankar   Not Collective
7995f2c45f1SShri Abhyankar 
8005f2c45f1SShri Abhyankar   Input Parameters:
8015f2c45f1SShri Abhyankar . dm - The DMNetwork Object
8025f2c45f1SShri Abhyankar 
8035f2c45f1SShri Abhyankar   Output Parameters:
8045f2c45f1SShri Abhyankar . componentdataarray - array that holds data for all components
8055f2c45f1SShri Abhyankar 
8065f2c45f1SShri Abhyankar   Level: intermediate
8075f2c45f1SShri Abhyankar 
808a730d845SHong Zhang .seealso: DMNetworkGetComponentKeyOffset, DMNetworkGetNumComponents
8095f2c45f1SShri Abhyankar @*/
8105f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetComponentDataArray(DM dm,DMNetworkComponentGenericDataType **componentdataarray)
8115f2c45f1SShri Abhyankar {
8125f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
8135f2c45f1SShri Abhyankar 
8145f2c45f1SShri Abhyankar   PetscFunctionBegin;
8155f2c45f1SShri Abhyankar   *componentdataarray = network->componentdataarray;
8165f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
8175f2c45f1SShri Abhyankar }
8185f2c45f1SShri Abhyankar 
81924121865SAdrian Maldonado /* Get a subsection from a range of points */
82024121865SAdrian Maldonado PetscErrorCode DMNetworkGetSubSection_private(PetscSection master, PetscInt pstart, PetscInt pend,PetscSection *subsection)
82124121865SAdrian Maldonado {
82224121865SAdrian Maldonado   PetscErrorCode ierr;
82324121865SAdrian Maldonado   PetscInt       i, nvar;
82424121865SAdrian Maldonado 
82524121865SAdrian Maldonado   PetscFunctionBegin;
82624121865SAdrian Maldonado   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)master), subsection);CHKERRQ(ierr);
82724121865SAdrian Maldonado   ierr = PetscSectionSetChart(*subsection, 0, pend - pstart);CHKERRQ(ierr);
82824121865SAdrian Maldonado   for (i = pstart; i < pend; i++) {
82924121865SAdrian Maldonado     ierr = PetscSectionGetDof(master,i,&nvar);CHKERRQ(ierr);
83024121865SAdrian Maldonado     ierr = PetscSectionSetDof(*subsection, i - pstart, nvar);CHKERRQ(ierr);
83124121865SAdrian Maldonado   }
83224121865SAdrian Maldonado 
83324121865SAdrian Maldonado   ierr = PetscSectionSetUp(*subsection);CHKERRQ(ierr);
83424121865SAdrian Maldonado   PetscFunctionReturn(0);
83524121865SAdrian Maldonado }
83624121865SAdrian Maldonado 
83724121865SAdrian Maldonado /* Create a submap of points with a GlobalToLocal structure */
83824121865SAdrian Maldonado PetscErrorCode DMNetworkSetSubMap_private(PetscInt pstart, PetscInt pend, ISLocalToGlobalMapping *map)
83924121865SAdrian Maldonado {
84024121865SAdrian Maldonado   PetscErrorCode ierr;
84124121865SAdrian Maldonado   PetscInt       i, *subpoints;
84224121865SAdrian Maldonado 
84324121865SAdrian Maldonado   PetscFunctionBegin;
84424121865SAdrian Maldonado   /* Create index sets to map from "points" to "subpoints" */
84524121865SAdrian Maldonado   ierr = PetscMalloc1(pend - pstart, &subpoints);CHKERRQ(ierr);
84624121865SAdrian Maldonado   for (i = pstart; i < pend; i++) {
84724121865SAdrian Maldonado     subpoints[i - pstart] = i;
84824121865SAdrian Maldonado   }
849459726d8SSatish Balay   ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,pend-pstart,subpoints,PETSC_COPY_VALUES,map);CHKERRQ(ierr);
85024121865SAdrian Maldonado   ierr = PetscFree(subpoints);CHKERRQ(ierr);
85124121865SAdrian Maldonado   PetscFunctionReturn(0);
85224121865SAdrian Maldonado }
85324121865SAdrian Maldonado 
85424121865SAdrian Maldonado /*@
85524121865SAdrian Maldonado   DMNetworkAssembleGraphStructures - Assembles vertex and edge data structures. Must be called after DMNetworkDistribute.
85624121865SAdrian Maldonado 
85724121865SAdrian Maldonado   Collective
85824121865SAdrian Maldonado 
85924121865SAdrian Maldonado   Input Parameters:
86024121865SAdrian Maldonado . dm   - The DMNetworkObject
86124121865SAdrian Maldonado 
86224121865SAdrian Maldonado   Note: the routine will create alternative orderings for the vertices and edges. Assume global network points are:
86324121865SAdrian Maldonado 
86424121865SAdrian Maldonado   points = [0 1 2 3 4 5 6]
86524121865SAdrian Maldonado 
86624121865SAdrian Maldonado   where edges = [0, 3] and vertices = [4, 6]. The new orderings will be specific to the subset (i.e vertices = [0, 2]).
86724121865SAdrian Maldonado 
86824121865SAdrian Maldonado   With this new ordering a local PetscSection, global PetscSection and PetscSF will be created specific to the subset.
86924121865SAdrian Maldonado 
87024121865SAdrian Maldonado   Level: intermediate
87124121865SAdrian Maldonado 
87224121865SAdrian Maldonado @*/
87324121865SAdrian Maldonado PetscErrorCode DMNetworkAssembleGraphStructures(DM dm)
87424121865SAdrian Maldonado {
87524121865SAdrian Maldonado   PetscErrorCode ierr;
87624121865SAdrian Maldonado   MPI_Comm       comm;
8779852e123SBarry Smith   PetscMPIInt    rank, size;
87824121865SAdrian Maldonado   DM_Network     *network = (DM_Network*)dm->data;
87924121865SAdrian Maldonado 
880eab1376dSHong Zhang   PetscFunctionBegin;
88124121865SAdrian Maldonado   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
88224121865SAdrian Maldonado   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
8839852e123SBarry Smith   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
88424121865SAdrian Maldonado 
88524121865SAdrian Maldonado   /* Create maps for vertices and edges */
88624121865SAdrian Maldonado   ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr);
88724121865SAdrian Maldonado   ierr = DMNetworkSetSubMap_private(network->eStart,network->eEnd,&network->edge.mapping);CHKERRQ(ierr);
88824121865SAdrian Maldonado 
88924121865SAdrian Maldonado   /* Create local sub-sections */
89024121865SAdrian Maldonado   ierr = DMNetworkGetSubSection_private(network->DofSection,network->vStart,network->vEnd,&network->vertex.DofSection);CHKERRQ(ierr);
89124121865SAdrian Maldonado   ierr = DMNetworkGetSubSection_private(network->DofSection,network->eStart,network->eEnd,&network->edge.DofSection);CHKERRQ(ierr);
89224121865SAdrian Maldonado 
8939852e123SBarry Smith   if (size > 1) {
89424121865SAdrian Maldonado     ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr);
89524121865SAdrian Maldonado     ierr = PetscSectionCreateGlobalSection(network->vertex.DofSection, network->vertex.sf, PETSC_FALSE, PETSC_FALSE, &network->vertex.GlobalDofSection);CHKERRQ(ierr);
89624121865SAdrian Maldonado   ierr = PetscSFGetSubSF(network->plex->sf, network->edge.mapping, &network->edge.sf);CHKERRQ(ierr);
89724121865SAdrian Maldonado   ierr = PetscSectionCreateGlobalSection(network->edge.DofSection, network->edge.sf, PETSC_FALSE, PETSC_FALSE, &network->edge.GlobalDofSection);CHKERRQ(ierr);
89824121865SAdrian Maldonado   } else {
89924121865SAdrian Maldonado   /* create structures for vertex */
90024121865SAdrian Maldonado   ierr = PetscSectionClone(network->vertex.DofSection,&network->vertex.GlobalDofSection);CHKERRQ(ierr);
90124121865SAdrian Maldonado   /* create structures for edge */
90224121865SAdrian Maldonado   ierr = PetscSectionClone(network->edge.DofSection,&network->edge.GlobalDofSection);CHKERRQ(ierr);
90324121865SAdrian Maldonado   }
90424121865SAdrian Maldonado 
90524121865SAdrian Maldonado 
90624121865SAdrian Maldonado   /* Add viewers */
90724121865SAdrian Maldonado   ierr = PetscObjectSetName((PetscObject)network->edge.GlobalDofSection,"Global edge dof section");CHKERRQ(ierr);
90824121865SAdrian Maldonado   ierr = PetscObjectSetName((PetscObject)network->vertex.GlobalDofSection,"Global vertex dof section");CHKERRQ(ierr);
90924121865SAdrian Maldonado   ierr = PetscSectionViewFromOptions(network->edge.GlobalDofSection, NULL, "-edge_global_section_view");CHKERRQ(ierr);
91024121865SAdrian Maldonado   ierr = PetscSectionViewFromOptions(network->vertex.GlobalDofSection, NULL, "-vertex_global_section_view");CHKERRQ(ierr);
91124121865SAdrian Maldonado 
91224121865SAdrian Maldonado   PetscFunctionReturn(0);
91324121865SAdrian Maldonado }
9147b6afd5bSHong Zhang 
9155f2c45f1SShri Abhyankar /*@
9165f2c45f1SShri Abhyankar   DMNetworkDistribute - Distributes the network and moves associated component data.
9175f2c45f1SShri Abhyankar 
9185f2c45f1SShri Abhyankar   Collective
9195f2c45f1SShri Abhyankar 
9205f2c45f1SShri Abhyankar   Input Parameter:
921d3464fd4SAdrian Maldonado + DM - the DMNetwork object
9225f2c45f1SShri Abhyankar - overlap - The overlap of partitions, 0 is the default
9235f2c45f1SShri Abhyankar 
9245f2c45f1SShri Abhyankar   Notes:
9258b171c8eSHong Zhang   Distributes the network with <overlap>-overlapping partitioning of the edges.
9265f2c45f1SShri Abhyankar 
9275f2c45f1SShri Abhyankar   Level: intermediate
9285f2c45f1SShri Abhyankar 
9295f2c45f1SShri Abhyankar .seealso: DMNetworkCreate
9305f2c45f1SShri Abhyankar @*/
931d3464fd4SAdrian Maldonado PetscErrorCode DMNetworkDistribute(DM *dm,PetscInt overlap)
9325f2c45f1SShri Abhyankar {
933d3464fd4SAdrian Maldonado   MPI_Comm       comm;
9345f2c45f1SShri Abhyankar   PetscErrorCode ierr;
935d3464fd4SAdrian Maldonado   PetscMPIInt    size;
936d3464fd4SAdrian Maldonado   DM_Network     *oldDMnetwork = (DM_Network*)((*dm)->data);
937d3464fd4SAdrian Maldonado   DM_Network     *newDMnetwork;
9385f2c45f1SShri Abhyankar   PetscSF        pointsf;
9395f2c45f1SShri Abhyankar   DM             newDM;
94051ac5effSHong Zhang   PetscPartitioner part;
941b9c6e19dSShri Abhyankar   PetscInt         j,e,v,offset;
942b9c6e19dSShri Abhyankar   DMNetworkComponentHeader header;
9435f2c45f1SShri Abhyankar 
9445f2c45f1SShri Abhyankar   PetscFunctionBegin;
945d3464fd4SAdrian Maldonado 
946d3464fd4SAdrian Maldonado   ierr = PetscObjectGetComm((PetscObject)*dm,&comm);CHKERRQ(ierr);
947d3464fd4SAdrian Maldonado   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
948d3464fd4SAdrian Maldonado   if (size == 1) PetscFunctionReturn(0);
949d3464fd4SAdrian Maldonado 
950d3464fd4SAdrian Maldonado   ierr = DMNetworkCreate(PetscObjectComm((PetscObject)*dm),&newDM);CHKERRQ(ierr);
9515f2c45f1SShri Abhyankar   newDMnetwork = (DM_Network*)newDM->data;
9525f2c45f1SShri Abhyankar   newDMnetwork->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType);
95351ac5effSHong Zhang 
95451ac5effSHong Zhang   /* Enable runtime options for petscpartitioner */
95551ac5effSHong Zhang   ierr = DMPlexGetPartitioner(oldDMnetwork->plex,&part);CHKERRQ(ierr);
95651ac5effSHong Zhang   ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr);
95751ac5effSHong Zhang 
9585f2c45f1SShri Abhyankar   /* Distribute plex dm and dof section */
95980cf41d5SMatthew G. Knepley   ierr = DMPlexDistribute(oldDMnetwork->plex,overlap,&pointsf,&newDMnetwork->plex);CHKERRQ(ierr);
96051ac5effSHong Zhang 
9615f2c45f1SShri Abhyankar   /* Distribute dof section */
962d3464fd4SAdrian Maldonado   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)*dm),&newDMnetwork->DofSection);CHKERRQ(ierr);
9635f2c45f1SShri Abhyankar   ierr = PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);CHKERRQ(ierr);
964d3464fd4SAdrian Maldonado   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)*dm),&newDMnetwork->DataSection);CHKERRQ(ierr);
96551ac5effSHong Zhang 
9665f2c45f1SShri Abhyankar   /* Distribute data and associated section */
96731da1fc8SHong Zhang   ierr = DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPIU_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);CHKERRQ(ierr);
96824121865SAdrian Maldonado 
9695f2c45f1SShri Abhyankar   ierr = PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);CHKERRQ(ierr);
9705f2c45f1SShri Abhyankar   ierr = DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);CHKERRQ(ierr);
9715f2c45f1SShri Abhyankar   ierr = DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);CHKERRQ(ierr);
9725f2c45f1SShri Abhyankar   newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart;
9736fefedf4SHong Zhang   newDMnetwork->nVertices = newDMnetwork->vEnd - newDMnetwork->vStart;
9746fefedf4SHong Zhang   newDMnetwork->NVertices = oldDMnetwork->NVertices;
9755f2c45f1SShri Abhyankar   newDMnetwork->NEdges = oldDMnetwork->NEdges;
97624121865SAdrian Maldonado 
9775f2c45f1SShri Abhyankar   /* Set Dof section as the default section for dm */
9785f2c45f1SShri Abhyankar   ierr = DMSetDefaultSection(newDMnetwork->plex,newDMnetwork->DofSection);CHKERRQ(ierr);
9795f2c45f1SShri Abhyankar   ierr = DMGetDefaultGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);CHKERRQ(ierr);
9805f2c45f1SShri Abhyankar 
981b9c6e19dSShri Abhyankar   /* Set up subnetwork info in the newDM */
982b9c6e19dSShri Abhyankar   newDMnetwork->nsubnet = oldDMnetwork->nsubnet;
983b9c6e19dSShri Abhyankar   ierr = PetscCalloc1(newDMnetwork->nsubnet,&newDMnetwork->subnet);CHKERRQ(ierr);
984b9c6e19dSShri Abhyankar   /* Copy over the global number of vertices and edges in each subnetwork. Note that these are already
985b9c6e19dSShri Abhyankar      calculated in DMNetworkLayoutSetUp()
986b9c6e19dSShri Abhyankar   */
987b9c6e19dSShri Abhyankar   for(j=0; j < newDMnetwork->nsubnet; j++) {
988b9c6e19dSShri Abhyankar     newDMnetwork->subnet[j].Nvtx = oldDMnetwork->subnet[j].Nvtx;
989b9c6e19dSShri Abhyankar     newDMnetwork->subnet[j].Nedge = oldDMnetwork->subnet[j].Nedge;
990b9c6e19dSShri Abhyankar   }
991b9c6e19dSShri Abhyankar 
992b9c6e19dSShri Abhyankar   for(e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++ ) {
993b9c6e19dSShri Abhyankar     ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr);
994b9c6e19dSShri Abhyankar     header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr);
995b9c6e19dSShri Abhyankar     newDMnetwork->subnet[header->subnetid].nedge++;
996b9c6e19dSShri Abhyankar   }
997b9c6e19dSShri Abhyankar 
998b9c6e19dSShri Abhyankar   for(v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++ ) {
999b9c6e19dSShri Abhyankar     ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr);
1000b9c6e19dSShri Abhyankar     header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr);
1001b9c6e19dSShri Abhyankar     newDMnetwork->subnet[header->subnetid].nvtx++;
1002b9c6e19dSShri Abhyankar   }
1003b9c6e19dSShri Abhyankar 
1004b9c6e19dSShri Abhyankar   /* Now create the vertices and edge arrays for the subnetworks */
1005b9c6e19dSShri Abhyankar   for(j=0; j < newDMnetwork->nsubnet; j++) {
1006b9c6e19dSShri Abhyankar     ierr = PetscCalloc1(newDMnetwork->subnet[j].nedge,&newDMnetwork->subnet[j].edges);CHKERRQ(ierr);
1007b9c6e19dSShri Abhyankar     ierr = PetscCalloc1(newDMnetwork->subnet[j].nvtx,&newDMnetwork->subnet[j].vertices);CHKERRQ(ierr);
1008b9c6e19dSShri Abhyankar     /* Temporarily setting nvtx and nedge to 0 so we can use them as counters in the below for loop.
1009b9c6e19dSShri Abhyankar        These get updated when the vertices and edges are added. */
1010b9c6e19dSShri Abhyankar     newDMnetwork->subnet[j].nvtx = newDMnetwork->subnet[j].nedge = 0;
1011b9c6e19dSShri Abhyankar   }
1012b9c6e19dSShri Abhyankar 
1013b9c6e19dSShri Abhyankar   /* Set the vertices and edges in each subnetwork */
1014b9c6e19dSShri Abhyankar   for(e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++ ) {
1015b9c6e19dSShri Abhyankar     ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr);
1016b9c6e19dSShri Abhyankar     header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr);
1017b9c6e19dSShri Abhyankar     newDMnetwork->subnet[header->subnetid].edges[newDMnetwork->subnet[header->subnetid].nedge++]  = e;
1018b9c6e19dSShri Abhyankar   }
1019b9c6e19dSShri Abhyankar 
1020b9c6e19dSShri Abhyankar   for(v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++ ) {
1021b9c6e19dSShri Abhyankar     ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr);
1022b9c6e19dSShri Abhyankar     header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr);
1023b9c6e19dSShri Abhyankar     newDMnetwork->subnet[header->subnetid].vertices[newDMnetwork->subnet[header->subnetid].nvtx++]  = v;
1024b9c6e19dSShri Abhyankar   }
1025b9c6e19dSShri Abhyankar 
102624121865SAdrian Maldonado   /* Destroy point SF */
102724121865SAdrian Maldonado   ierr = PetscSFDestroy(&pointsf);CHKERRQ(ierr);
102824121865SAdrian Maldonado 
1029d3464fd4SAdrian Maldonado   ierr = DMDestroy(dm);CHKERRQ(ierr);
1030d3464fd4SAdrian Maldonado   *dm  = newDM;
10315f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
10325f2c45f1SShri Abhyankar }
10335f2c45f1SShri Abhyankar 
103424121865SAdrian Maldonado /*@C
103524121865SAdrian Maldonado   PetscSFGetSubSF - Returns an SF for a specific subset of points. Leaves are re-numbered to reflect the new ordering.
103624121865SAdrian Maldonado 
103724121865SAdrian Maldonado   Input Parameters:
103824121865SAdrian Maldonado + masterSF - the original SF structure
103924121865SAdrian Maldonado - map      - a ISLocalToGlobal mapping that contains the subset of points
104024121865SAdrian Maldonado 
104124121865SAdrian Maldonado   Output Parameters:
104224121865SAdrian Maldonado . subSF    - a subset of the masterSF for the desired subset.
104324121865SAdrian Maldonado */
104424121865SAdrian Maldonado 
104524121865SAdrian Maldonado PetscErrorCode PetscSFGetSubSF(PetscSF mastersf, ISLocalToGlobalMapping map, PetscSF *subSF) {
104624121865SAdrian Maldonado 
104724121865SAdrian Maldonado   PetscErrorCode        ierr;
104824121865SAdrian Maldonado   PetscInt              nroots, nleaves, *ilocal_sub;
104924121865SAdrian Maldonado   PetscInt              i, *ilocal_map, nroots_sub, nleaves_sub = 0;
105024121865SAdrian Maldonado   PetscInt              *local_points, *remote_points;
105124121865SAdrian Maldonado   PetscSFNode           *iremote_sub;
105224121865SAdrian Maldonado   const PetscInt        *ilocal;
105324121865SAdrian Maldonado   const PetscSFNode     *iremote;
105424121865SAdrian Maldonado 
105524121865SAdrian Maldonado   PetscFunctionBegin;
105624121865SAdrian Maldonado   ierr = PetscSFGetGraph(mastersf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr);
105724121865SAdrian Maldonado 
105824121865SAdrian Maldonado   /* Look for leaves that pertain to the subset of points. Get the local ordering */
105924121865SAdrian Maldonado   ierr = PetscMalloc1(nleaves,&ilocal_map);CHKERRQ(ierr);
106024121865SAdrian Maldonado   ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nleaves,ilocal,NULL,ilocal_map);CHKERRQ(ierr);
106124121865SAdrian Maldonado   for (i = 0; i < nleaves; i++) {
106224121865SAdrian Maldonado     if (ilocal_map[i] != -1) nleaves_sub += 1;
106324121865SAdrian Maldonado   }
106424121865SAdrian Maldonado   /* Re-number ilocal with subset numbering. Need information from roots */
106524121865SAdrian Maldonado   ierr = PetscMalloc2(nroots,&local_points,nroots,&remote_points);CHKERRQ(ierr);
106624121865SAdrian Maldonado   for (i = 0; i < nroots; i++) local_points[i] = i;
106724121865SAdrian Maldonado   ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nroots,local_points,NULL,local_points);CHKERRQ(ierr);
106824121865SAdrian Maldonado   ierr = PetscSFBcastBegin(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr);
106924121865SAdrian Maldonado   ierr = PetscSFBcastEnd(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr);
107024121865SAdrian Maldonado   /* Fill up graph using local (that is, local to the subset) numbering. */
10714b70a8deSAdrian Maldonado   ierr = PetscMalloc1(nleaves_sub,&ilocal_sub);CHKERRQ(ierr);
10724b70a8deSAdrian Maldonado   ierr = PetscMalloc1(nleaves_sub,&iremote_sub);CHKERRQ(ierr);
107324121865SAdrian Maldonado   nleaves_sub = 0;
107424121865SAdrian Maldonado   for (i = 0; i < nleaves; i++) {
107524121865SAdrian Maldonado     if (ilocal_map[i] != -1) {
107624121865SAdrian Maldonado       ilocal_sub[nleaves_sub] = ilocal_map[i];
10774b70a8deSAdrian Maldonado       iremote_sub[nleaves_sub].rank = iremote[i].rank;
107824121865SAdrian Maldonado       iremote_sub[nleaves_sub].index = remote_points[ilocal[i]];
107924121865SAdrian Maldonado       nleaves_sub += 1;
108024121865SAdrian Maldonado     }
108124121865SAdrian Maldonado   }
108224121865SAdrian Maldonado   ierr = PetscFree2(local_points,remote_points);CHKERRQ(ierr);
108324121865SAdrian Maldonado   ierr = ISLocalToGlobalMappingGetSize(map,&nroots_sub);CHKERRQ(ierr);
108424121865SAdrian Maldonado 
108524121865SAdrian Maldonado   /* Create new subSF */
108624121865SAdrian Maldonado   ierr = PetscSFCreate(PETSC_COMM_WORLD,subSF);CHKERRQ(ierr);
108724121865SAdrian Maldonado   ierr = PetscSFSetFromOptions(*subSF);CHKERRQ(ierr);
10884b70a8deSAdrian Maldonado   ierr = PetscSFSetGraph(*subSF,nroots_sub,nleaves_sub,ilocal_sub,PETSC_OWN_POINTER,iremote_sub,PETSC_COPY_VALUES);CHKERRQ(ierr);
108924121865SAdrian Maldonado   ierr = PetscFree(ilocal_map);CHKERRQ(ierr);
10904b70a8deSAdrian Maldonado   ierr = PetscFree(iremote_sub);CHKERRQ(ierr);
109124121865SAdrian Maldonado   PetscFunctionReturn(0);
109224121865SAdrian Maldonado }
109324121865SAdrian Maldonado 
10945f2c45f1SShri Abhyankar /*@C
10955f2c45f1SShri Abhyankar   DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point
10965f2c45f1SShri Abhyankar 
10975f2c45f1SShri Abhyankar   Not Collective
10985f2c45f1SShri Abhyankar 
10995f2c45f1SShri Abhyankar   Input Parameters:
11005f2c45f1SShri Abhyankar + dm - The DMNetwork object
11015f2c45f1SShri Abhyankar - p  - the vertex point
11025f2c45f1SShri Abhyankar 
11035f2c45f1SShri Abhyankar   Output Paramters:
11045f2c45f1SShri Abhyankar + nedges - number of edges connected to this vertex point
11055f2c45f1SShri Abhyankar - edges  - List of edge points
11065f2c45f1SShri Abhyankar 
11075f2c45f1SShri Abhyankar   Level: intermediate
11085f2c45f1SShri Abhyankar 
11095f2c45f1SShri Abhyankar   Fortran Notes:
11105f2c45f1SShri Abhyankar   Since it returns an array, this routine is only available in Fortran 90, and you must
11115f2c45f1SShri Abhyankar   include petsc.h90 in your code.
11125f2c45f1SShri Abhyankar 
1113d842c372SHong Zhang .seealso: DMNetworkCreate, DMNetworkGetConnectedVertices
11145f2c45f1SShri Abhyankar @*/
11155f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[])
11165f2c45f1SShri Abhyankar {
11175f2c45f1SShri Abhyankar   PetscErrorCode ierr;
11185f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
11195f2c45f1SShri Abhyankar 
11205f2c45f1SShri Abhyankar   PetscFunctionBegin;
11215f2c45f1SShri Abhyankar   ierr = DMPlexGetSupportSize(network->plex,vertex,nedges);CHKERRQ(ierr);
11225f2c45f1SShri Abhyankar   ierr = DMPlexGetSupport(network->plex,vertex,edges);CHKERRQ(ierr);
11235f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
11245f2c45f1SShri Abhyankar }
11255f2c45f1SShri Abhyankar 
11265f2c45f1SShri Abhyankar /*@C
1127d842c372SHong Zhang   DMNetworkGetConnectedVertices - Return the connected vertices for this edge point
11285f2c45f1SShri Abhyankar 
11295f2c45f1SShri Abhyankar   Not Collective
11305f2c45f1SShri Abhyankar 
11315f2c45f1SShri Abhyankar   Input Parameters:
11325f2c45f1SShri Abhyankar + dm - The DMNetwork object
11335f2c45f1SShri Abhyankar - p  - the edge point
11345f2c45f1SShri Abhyankar 
11355f2c45f1SShri Abhyankar   Output Paramters:
11365f2c45f1SShri Abhyankar . vertices  - vertices connected to this edge
11375f2c45f1SShri Abhyankar 
11385f2c45f1SShri Abhyankar   Level: intermediate
11395f2c45f1SShri Abhyankar 
11405f2c45f1SShri Abhyankar   Fortran Notes:
11415f2c45f1SShri Abhyankar   Since it returns an array, this routine is only available in Fortran 90, and you must
11425f2c45f1SShri Abhyankar   include petsc.h90 in your code.
11435f2c45f1SShri Abhyankar 
11445f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkGetSupportingEdges
11455f2c45f1SShri Abhyankar @*/
1146d842c372SHong Zhang PetscErrorCode DMNetworkGetConnectedVertices(DM dm,PetscInt edge,const PetscInt *vertices[])
11475f2c45f1SShri Abhyankar {
11485f2c45f1SShri Abhyankar   PetscErrorCode ierr;
11495f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
11505f2c45f1SShri Abhyankar 
11515f2c45f1SShri Abhyankar   PetscFunctionBegin;
11525f2c45f1SShri Abhyankar   ierr = DMPlexGetCone(network->plex,edge,vertices);CHKERRQ(ierr);
11535f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
11545f2c45f1SShri Abhyankar }
11555f2c45f1SShri Abhyankar 
11565f2c45f1SShri Abhyankar /*@
11575f2c45f1SShri Abhyankar   DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex
11585f2c45f1SShri Abhyankar 
11595f2c45f1SShri Abhyankar   Not Collective
11605f2c45f1SShri Abhyankar 
11615f2c45f1SShri Abhyankar   Input Parameters:
11625f2c45f1SShri Abhyankar + dm - The DMNetwork object
11635f2c45f1SShri Abhyankar . p  - the vertex point
11645f2c45f1SShri Abhyankar 
11655f2c45f1SShri Abhyankar   Output Parameter:
11665f2c45f1SShri Abhyankar . isghost - TRUE if the vertex is a ghost point
11675f2c45f1SShri Abhyankar 
11685f2c45f1SShri Abhyankar   Level: intermediate
11695f2c45f1SShri Abhyankar 
1170d842c372SHong Zhang .seealso: DMNetworkCreate, DMNetworkGetConnectedVertices, DMNetworkGetVertexRange
11715f2c45f1SShri Abhyankar @*/
11725f2c45f1SShri Abhyankar PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost)
11735f2c45f1SShri Abhyankar {
11745f2c45f1SShri Abhyankar   PetscErrorCode ierr;
11755f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
11765f2c45f1SShri Abhyankar   PetscInt       offsetg;
11775f2c45f1SShri Abhyankar   PetscSection   sectiong;
11785f2c45f1SShri Abhyankar 
11795f2c45f1SShri Abhyankar   PetscFunctionBegin;
11805f2c45f1SShri Abhyankar   *isghost = PETSC_FALSE;
11815f2c45f1SShri Abhyankar   ierr = DMGetDefaultGlobalSection(network->plex,&sectiong);CHKERRQ(ierr);
11825f2c45f1SShri Abhyankar   ierr = PetscSectionGetOffset(sectiong,p,&offsetg);CHKERRQ(ierr);
11835f2c45f1SShri Abhyankar   if (offsetg < 0) *isghost = PETSC_TRUE;
11845f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
11855f2c45f1SShri Abhyankar }
11865f2c45f1SShri Abhyankar 
11875f2c45f1SShri Abhyankar PetscErrorCode DMSetUp_Network(DM dm)
11885f2c45f1SShri Abhyankar {
11895f2c45f1SShri Abhyankar   PetscErrorCode ierr;
11905f2c45f1SShri Abhyankar   DM_Network     *network=(DM_Network*)dm->data;
11915f2c45f1SShri Abhyankar 
11925f2c45f1SShri Abhyankar   PetscFunctionBegin;
11935f2c45f1SShri Abhyankar   ierr = DMNetworkComponentSetUp(dm);CHKERRQ(ierr);
11945f2c45f1SShri Abhyankar   ierr = DMNetworkVariablesSetUp(dm);CHKERRQ(ierr);
11955f2c45f1SShri Abhyankar 
11965f2c45f1SShri Abhyankar   ierr = DMSetDefaultSection(network->plex,network->DofSection);CHKERRQ(ierr);
11975f2c45f1SShri Abhyankar   ierr = DMGetDefaultGlobalSection(network->plex,&network->GlobalDofSection);CHKERRQ(ierr);
11985f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
11995f2c45f1SShri Abhyankar }
12005f2c45f1SShri Abhyankar 
12011ad426b7SHong Zhang /*@
120217df6e9eSHong Zhang     DMNetworkHasJacobian - Sets global flag for using user's sub Jacobian matrices
12031ad426b7SHong Zhang                             -- replaced by DMNetworkSetOption(network,userjacobian,PETSC_TURE)?
12041ad426b7SHong Zhang 
12051ad426b7SHong Zhang     Collective
12061ad426b7SHong Zhang 
12071ad426b7SHong Zhang     Input Parameters:
120883b2e829SHong Zhang +   dm - The DMNetwork object
120983b2e829SHong Zhang .   eflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for edges
121083b2e829SHong Zhang -   vflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for vertices
12111ad426b7SHong Zhang 
12121ad426b7SHong Zhang     Level: intermediate
12131ad426b7SHong Zhang 
12141ad426b7SHong Zhang @*/
121583b2e829SHong Zhang PetscErrorCode DMNetworkHasJacobian(DM dm,PetscBool eflg,PetscBool vflg)
12161ad426b7SHong Zhang {
12171ad426b7SHong Zhang   DM_Network     *network=(DM_Network*)dm->data;
12188675203cSHong Zhang   PetscErrorCode ierr;
12191ad426b7SHong Zhang 
12201ad426b7SHong Zhang   PetscFunctionBegin;
122183b2e829SHong Zhang   network->userEdgeJacobian   = eflg;
122283b2e829SHong Zhang   network->userVertexJacobian = vflg;
12238675203cSHong Zhang 
12248675203cSHong Zhang   if (eflg && !network->Je) {
12258675203cSHong Zhang     ierr = PetscCalloc1(3*network->nEdges,&network->Je);CHKERRQ(ierr);
12268675203cSHong Zhang   }
12278675203cSHong Zhang 
12288675203cSHong Zhang   if (vflg && !network->Jv) {
12298675203cSHong Zhang     PetscInt       i,*vptr,nedges,vStart=network->vStart;
12308675203cSHong Zhang     PetscInt       nVertices = network->nVertices,nedges_total;
12318675203cSHong Zhang     const PetscInt *edges;
12328675203cSHong Zhang 
12338675203cSHong Zhang     /* count nvertex_total */
12348675203cSHong Zhang     nedges_total = 0;
12358675203cSHong Zhang     ierr = PetscMalloc1(nVertices+1,&vptr);CHKERRQ(ierr);
12368675203cSHong Zhang 
12378675203cSHong Zhang     vptr[0] = 0;
12388675203cSHong Zhang     for (i=0; i<nVertices; i++) {
12398675203cSHong Zhang       ierr = DMNetworkGetSupportingEdges(dm,i+vStart,&nedges,&edges);CHKERRQ(ierr);
12408675203cSHong Zhang       nedges_total += nedges;
12418675203cSHong Zhang       vptr[i+1] = vptr[i] + 2*nedges + 1;
12428675203cSHong Zhang     }
12438675203cSHong Zhang 
12448675203cSHong Zhang     ierr = PetscCalloc1(2*nedges_total+nVertices,&network->Jv);CHKERRQ(ierr);
12458675203cSHong Zhang     network->Jvptr = vptr;
12468675203cSHong Zhang   }
12471ad426b7SHong Zhang   PetscFunctionReturn(0);
12481ad426b7SHong Zhang }
12491ad426b7SHong Zhang 
12501ad426b7SHong Zhang /*@
125183b2e829SHong Zhang     DMNetworkEdgeSetMatrix - Sets user-provided Jacobian matrices for this edge to the network
125283b2e829SHong Zhang 
125383b2e829SHong Zhang     Not Collective
125483b2e829SHong Zhang 
125583b2e829SHong Zhang     Input Parameters:
125683b2e829SHong Zhang +   dm - The DMNetwork object
125783b2e829SHong Zhang .   p  - the edge point
12583e97b6e8SHong Zhang -   J - array (size = 3) of Jacobian submatrices for this edge point:
12593e97b6e8SHong Zhang         J[0]: this edge
1260d842c372SHong Zhang         J[1] and J[2]: connected vertices, obtained by calling DMNetworkGetConnectedVertices()
126183b2e829SHong Zhang 
126283b2e829SHong Zhang     Level: intermediate
126383b2e829SHong Zhang 
126483b2e829SHong Zhang .seealso: DMNetworkVertexSetMatrix
126583b2e829SHong Zhang @*/
126683b2e829SHong Zhang PetscErrorCode DMNetworkEdgeSetMatrix(DM dm,PetscInt p,Mat J[])
126783b2e829SHong Zhang {
126883b2e829SHong Zhang   DM_Network     *network=(DM_Network*)dm->data;
126983b2e829SHong Zhang 
127083b2e829SHong Zhang   PetscFunctionBegin;
12718675203cSHong Zhang   if (!network->Je) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkEdgeSetMatrix");
12728675203cSHong Zhang 
12738675203cSHong Zhang   if (J) {
1274883e35e8SHong Zhang     network->Je[3*p]   = J[0];
1275883e35e8SHong Zhang     network->Je[3*p+1] = J[1];
1276883e35e8SHong Zhang     network->Je[3*p+2] = J[2];
12778675203cSHong Zhang   }
127883b2e829SHong Zhang   PetscFunctionReturn(0);
127983b2e829SHong Zhang }
128083b2e829SHong Zhang 
128183b2e829SHong Zhang /*@
128276ddfea5SHong Zhang     DMNetworkVertexSetMatrix - Sets user-provided Jacobian matrix for this vertex to the network
12831ad426b7SHong Zhang 
12841ad426b7SHong Zhang     Not Collective
12851ad426b7SHong Zhang 
12861ad426b7SHong Zhang     Input Parameters:
12871ad426b7SHong Zhang +   dm - The DMNetwork object
12881ad426b7SHong Zhang .   p  - the vertex point
12893e97b6e8SHong Zhang -   J - array of Jacobian (size = 2*(num of supporting edges) + 1) submatrices for this vertex point:
12903e97b6e8SHong Zhang         J[0]:       this vertex
12913e97b6e8SHong Zhang         J[1+2*i]:   i-th supporting edge
12923e97b6e8SHong Zhang         J[1+2*i+1]: i-th connected vertex
12931ad426b7SHong Zhang 
12941ad426b7SHong Zhang     Level: intermediate
12951ad426b7SHong Zhang 
129683b2e829SHong Zhang .seealso: DMNetworkEdgeSetMatrix
12971ad426b7SHong Zhang @*/
1298883e35e8SHong Zhang PetscErrorCode DMNetworkVertexSetMatrix(DM dm,PetscInt p,Mat J[])
12995f2c45f1SShri Abhyankar {
13005f2c45f1SShri Abhyankar   PetscErrorCode ierr;
13015f2c45f1SShri Abhyankar   DM_Network     *network=(DM_Network*)dm->data;
13028675203cSHong Zhang   PetscInt       i,*vptr,nedges,vStart=network->vStart;
1303883e35e8SHong Zhang   const PetscInt *edges;
13045f2c45f1SShri Abhyankar 
13055f2c45f1SShri Abhyankar   PetscFunctionBegin;
13068675203cSHong Zhang   if (!network->Jv) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkVertexSetMatrix");
1307883e35e8SHong Zhang 
13088675203cSHong Zhang   if (J) {
1309883e35e8SHong Zhang     vptr = network->Jvptr;
13103e97b6e8SHong Zhang     network->Jv[vptr[p-vStart]] = J[0]; /* Set Jacobian for this vertex */
13113e97b6e8SHong Zhang 
13123e97b6e8SHong Zhang     /* Set Jacobian for each supporting edge and connected vertex */
1313883e35e8SHong Zhang     ierr = DMNetworkGetSupportingEdges(dm,p,&nedges,&edges);CHKERRQ(ierr);
1314883e35e8SHong Zhang     for (i=1; i<=2*nedges; i++) network->Jv[vptr[p-vStart]+i] = J[i];
13158675203cSHong Zhang   }
1316883e35e8SHong Zhang   PetscFunctionReturn(0);
1317883e35e8SHong Zhang }
1318883e35e8SHong Zhang 
1319e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz)
13205cf7da58SHong Zhang {
13215cf7da58SHong Zhang   PetscErrorCode ierr;
13225cf7da58SHong Zhang   PetscInt       j;
13235cf7da58SHong Zhang   PetscScalar    val=(PetscScalar)ncols;
13245cf7da58SHong Zhang 
13255cf7da58SHong Zhang   PetscFunctionBegin;
13265cf7da58SHong Zhang   if (!ghost) {
13275cf7da58SHong Zhang     for (j=0; j<nrows; j++) {
13285cf7da58SHong Zhang       ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr);
13295cf7da58SHong Zhang     }
13305cf7da58SHong Zhang   } else {
13315cf7da58SHong Zhang     for (j=0; j<nrows; j++) {
13325cf7da58SHong Zhang       ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr);
13335cf7da58SHong Zhang     }
13345cf7da58SHong Zhang   }
13355cf7da58SHong Zhang   PetscFunctionReturn(0);
13365cf7da58SHong Zhang }
13375cf7da58SHong Zhang 
1338e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz)
13395cf7da58SHong Zhang {
13405cf7da58SHong Zhang   PetscErrorCode ierr;
13415cf7da58SHong Zhang   PetscInt       j,ncols_u;
13425cf7da58SHong Zhang   PetscScalar    val;
13435cf7da58SHong Zhang 
13445cf7da58SHong Zhang   PetscFunctionBegin;
13455cf7da58SHong Zhang   if (!ghost) {
13465cf7da58SHong Zhang     for (j=0; j<nrows; j++) {
13475cf7da58SHong Zhang       ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr);
13485cf7da58SHong Zhang       val = (PetscScalar)ncols_u;
13495cf7da58SHong Zhang       ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr);
13505cf7da58SHong Zhang       ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr);
13515cf7da58SHong Zhang     }
13525cf7da58SHong Zhang   } else {
13535cf7da58SHong Zhang     for (j=0; j<nrows; j++) {
13545cf7da58SHong Zhang       ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr);
13555cf7da58SHong Zhang       val = (PetscScalar)ncols_u;
13565cf7da58SHong Zhang       ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr);
13575cf7da58SHong Zhang       ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr);
13585cf7da58SHong Zhang     }
13595cf7da58SHong Zhang   }
13605cf7da58SHong Zhang   PetscFunctionReturn(0);
13615cf7da58SHong Zhang }
13625cf7da58SHong Zhang 
1363e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz)
13645cf7da58SHong Zhang {
13655cf7da58SHong Zhang   PetscErrorCode ierr;
13665cf7da58SHong Zhang 
13675cf7da58SHong Zhang   PetscFunctionBegin;
13685cf7da58SHong Zhang   if (Ju) {
13695cf7da58SHong Zhang     ierr = MatSetPreallocationUserblock_private(Ju,nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr);
13705cf7da58SHong Zhang   } else {
13715cf7da58SHong Zhang     ierr = MatSetPreallocationDenseblock_private(nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr);
13725cf7da58SHong Zhang   }
13735cf7da58SHong Zhang   PetscFunctionReturn(0);
13745cf7da58SHong Zhang }
13755cf7da58SHong Zhang 
1376e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J)
1377883e35e8SHong Zhang {
1378883e35e8SHong Zhang   PetscErrorCode ierr;
1379883e35e8SHong Zhang   PetscInt       j,*cols;
1380883e35e8SHong Zhang   PetscScalar    *zeros;
1381883e35e8SHong Zhang 
1382883e35e8SHong Zhang   PetscFunctionBegin;
1383883e35e8SHong Zhang   ierr = PetscCalloc2(ncols,&cols,nrows*ncols,&zeros);CHKERRQ(ierr);
1384883e35e8SHong Zhang   for (j=0; j<ncols; j++) cols[j] = j+ cstart;
1385883e35e8SHong Zhang   ierr = MatSetValues(*J,nrows,rows,ncols,cols,zeros,INSERT_VALUES);CHKERRQ(ierr);
1386883e35e8SHong Zhang   ierr = PetscFree2(cols,zeros);CHKERRQ(ierr);
13871ad426b7SHong Zhang   PetscFunctionReturn(0);
13881ad426b7SHong Zhang }
1389a4e85ca8SHong Zhang 
1390e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J)
13913e97b6e8SHong Zhang {
13923e97b6e8SHong Zhang   PetscErrorCode ierr;
13933e97b6e8SHong Zhang   PetscInt       j,M,N,row,col,ncols_u;
13943e97b6e8SHong Zhang   const PetscInt *cols;
13953e97b6e8SHong Zhang   PetscScalar    zero=0.0;
13963e97b6e8SHong Zhang 
13973e97b6e8SHong Zhang   PetscFunctionBegin;
13983e97b6e8SHong Zhang   ierr = MatGetSize(Ju,&M,&N);CHKERRQ(ierr);
13993e97b6e8SHong 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);
14003e97b6e8SHong Zhang 
14013e97b6e8SHong Zhang   for (row=0; row<nrows; row++) {
14023e97b6e8SHong Zhang     ierr = MatGetRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr);
14033e97b6e8SHong Zhang     for (j=0; j<ncols_u; j++) {
14043e97b6e8SHong Zhang       col = cols[j] + cstart;
14053e97b6e8SHong Zhang       ierr = MatSetValues(*J,1,&rows[row],1,&col,&zero,INSERT_VALUES);CHKERRQ(ierr);
14063e97b6e8SHong Zhang     }
14073e97b6e8SHong Zhang     ierr = MatRestoreRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr);
14083e97b6e8SHong Zhang   }
14093e97b6e8SHong Zhang   PetscFunctionReturn(0);
14103e97b6e8SHong Zhang }
14111ad426b7SHong Zhang 
1412e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J)
1413a4e85ca8SHong Zhang {
1414a4e85ca8SHong Zhang   PetscErrorCode ierr;
1415f4431b8cSHong Zhang 
1416a4e85ca8SHong Zhang   PetscFunctionBegin;
1417a4e85ca8SHong Zhang   if (Ju) {
1418a4e85ca8SHong Zhang     ierr = MatSetUserblock_private(Ju,nrows,rows,ncols,cstart,J);CHKERRQ(ierr);
1419a4e85ca8SHong Zhang   } else {
1420a4e85ca8SHong Zhang     ierr = MatSetDenseblock_private(nrows,rows,ncols,cstart,J);CHKERRQ(ierr);
1421a4e85ca8SHong Zhang   }
1422a4e85ca8SHong Zhang   PetscFunctionReturn(0);
1423a4e85ca8SHong Zhang }
1424a4e85ca8SHong Zhang 
142524121865SAdrian 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.
142624121865SAdrian Maldonado */
142724121865SAdrian Maldonado PetscErrorCode CreateSubGlobalToLocalMapping_private(PetscSection globalsec, PetscSection localsec, ISLocalToGlobalMapping *ltog)
142824121865SAdrian Maldonado {
142924121865SAdrian Maldonado   PetscErrorCode ierr;
143024121865SAdrian Maldonado   PetscInt       i, size, dof;
143124121865SAdrian Maldonado   PetscInt       *glob2loc;
143224121865SAdrian Maldonado 
143324121865SAdrian Maldonado   PetscFunctionBegin;
143424121865SAdrian Maldonado   ierr = PetscSectionGetStorageSize(localsec,&size);CHKERRQ(ierr);
143524121865SAdrian Maldonado   ierr = PetscMalloc1(size,&glob2loc);CHKERRQ(ierr);
143624121865SAdrian Maldonado 
143724121865SAdrian Maldonado   for (i = 0; i < size; i++) {
143824121865SAdrian Maldonado     ierr = PetscSectionGetOffset(globalsec,i,&dof);CHKERRQ(ierr);
143924121865SAdrian Maldonado     dof = (dof >= 0) ? dof : -(dof + 1);
144024121865SAdrian Maldonado     glob2loc[i] = dof;
144124121865SAdrian Maldonado   }
144224121865SAdrian Maldonado 
144324121865SAdrian Maldonado   ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,size,glob2loc,PETSC_OWN_POINTER,ltog);CHKERRQ(ierr);
144424121865SAdrian Maldonado #if 0
144524121865SAdrian Maldonado   ierr = PetscIntView(size,glob2loc,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
144624121865SAdrian Maldonado #endif
144724121865SAdrian Maldonado   PetscFunctionReturn(0);
144824121865SAdrian Maldonado }
144924121865SAdrian Maldonado 
145001ad2aeeSHong Zhang #include <petsc/private/matimpl.h>
14511ad426b7SHong Zhang PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J)
14521ad426b7SHong Zhang {
14531ad426b7SHong Zhang   PetscErrorCode ierr;
145424121865SAdrian Maldonado   PetscMPIInt    rank, size;
14551ad426b7SHong Zhang   DM_Network     *network = (DM_Network*) dm->data;
1456a4e85ca8SHong Zhang   PetscInt       eStart,eEnd,vStart,vEnd,rstart,nrows,*rows,localSize;
1457840c2264SHong Zhang   PetscInt       cstart,ncols,j,e,v;
145824121865SAdrian Maldonado   PetscBool      ghost,ghost_vc,ghost2,isNest;
1459a4e85ca8SHong Zhang   Mat            Juser;
1460bfbc38dcSHong Zhang   PetscSection   sectionGlobal;
1461447d78afSSatish Balay   PetscInt       nedges,*vptr=NULL,vc,*rows_v; /* suppress maybe-uninitialized warning */
1462a4e85ca8SHong Zhang   const PetscInt *edges,*cone;
14635cf7da58SHong Zhang   MPI_Comm       comm;
146424121865SAdrian Maldonado   MatType        mtype;
14655cf7da58SHong Zhang   Vec            vd_nz,vo_nz;
14665cf7da58SHong Zhang   PetscInt       *dnnz,*onnz;
14675cf7da58SHong Zhang   PetscScalar    *vdnz,*vonz;
14681ad426b7SHong Zhang 
14691ad426b7SHong Zhang   PetscFunctionBegin;
147024121865SAdrian Maldonado   mtype = dm->mattype;
147124121865SAdrian Maldonado   ierr = PetscStrcmp(mtype, MATNEST, &isNest);CHKERRQ(ierr);
147224121865SAdrian Maldonado 
147324121865SAdrian Maldonado   if (isNest) {
14740731d606SHong Zhang     /* ierr = DMCreateMatrix_Network_Nest(); */
147524121865SAdrian Maldonado     PetscInt   eDof, vDof;
147624121865SAdrian Maldonado     Mat        j11, j12, j21, j22, bA[2][2];
147724121865SAdrian Maldonado     ISLocalToGlobalMapping eISMap, vISMap;
147824121865SAdrian Maldonado 
147924121865SAdrian Maldonado     ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
148024121865SAdrian Maldonado     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
148124121865SAdrian Maldonado     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
148224121865SAdrian Maldonado 
148324121865SAdrian Maldonado     ierr = PetscSectionGetConstrainedStorageSize(network->edge.GlobalDofSection,&eDof);CHKERRQ(ierr);
148424121865SAdrian Maldonado     ierr = PetscSectionGetConstrainedStorageSize(network->vertex.GlobalDofSection,&vDof);CHKERRQ(ierr);
148524121865SAdrian Maldonado 
148601ad2aeeSHong Zhang     ierr = MatCreate(comm, &j11);CHKERRQ(ierr);
148724121865SAdrian Maldonado     ierr = MatSetSizes(j11, eDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
148824121865SAdrian Maldonado     ierr = MatSetType(j11, MATMPIAIJ);CHKERRQ(ierr);
148924121865SAdrian Maldonado 
149001ad2aeeSHong Zhang     ierr = MatCreate(comm, &j12);CHKERRQ(ierr);
149124121865SAdrian Maldonado     ierr = MatSetSizes(j12, eDof, vDof, PETSC_DETERMINE ,PETSC_DETERMINE);CHKERRQ(ierr);
149224121865SAdrian Maldonado     ierr = MatSetType(j12, MATMPIAIJ);CHKERRQ(ierr);
149324121865SAdrian Maldonado 
149401ad2aeeSHong Zhang     ierr = MatCreate(comm, &j21);CHKERRQ(ierr);
149524121865SAdrian Maldonado     ierr = MatSetSizes(j21, vDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
149624121865SAdrian Maldonado     ierr = MatSetType(j21, MATMPIAIJ);CHKERRQ(ierr);
149724121865SAdrian Maldonado 
149801ad2aeeSHong Zhang     ierr = MatCreate(comm, &j22);CHKERRQ(ierr);
149924121865SAdrian Maldonado     ierr = MatSetSizes(j22, vDof, vDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
150024121865SAdrian Maldonado     ierr = MatSetType(j22, MATMPIAIJ);CHKERRQ(ierr);
150124121865SAdrian Maldonado 
15023f6a6bdaSHong Zhang     bA[0][0] = j11;
15033f6a6bdaSHong Zhang     bA[0][1] = j12;
15043f6a6bdaSHong Zhang     bA[1][0] = j21;
15053f6a6bdaSHong Zhang     bA[1][1] = j22;
150624121865SAdrian Maldonado 
150724121865SAdrian Maldonado     ierr = CreateSubGlobalToLocalMapping_private(network->edge.GlobalDofSection,network->edge.DofSection,&eISMap);CHKERRQ(ierr);
150824121865SAdrian Maldonado     ierr = CreateSubGlobalToLocalMapping_private(network->vertex.GlobalDofSection,network->vertex.DofSection,&vISMap);CHKERRQ(ierr);
150924121865SAdrian Maldonado 
151024121865SAdrian Maldonado     ierr = MatSetLocalToGlobalMapping(j11,eISMap,eISMap);CHKERRQ(ierr);
151124121865SAdrian Maldonado     ierr = MatSetLocalToGlobalMapping(j12,eISMap,vISMap);CHKERRQ(ierr);
151224121865SAdrian Maldonado     ierr = MatSetLocalToGlobalMapping(j21,vISMap,eISMap);CHKERRQ(ierr);
151324121865SAdrian Maldonado     ierr = MatSetLocalToGlobalMapping(j22,vISMap,vISMap);CHKERRQ(ierr);
151424121865SAdrian Maldonado 
151524121865SAdrian Maldonado     ierr = MatSetUp(j11);CHKERRQ(ierr);
151624121865SAdrian Maldonado     ierr = MatSetUp(j12);CHKERRQ(ierr);
151724121865SAdrian Maldonado     ierr = MatSetUp(j21);CHKERRQ(ierr);
151824121865SAdrian Maldonado     ierr = MatSetUp(j22);CHKERRQ(ierr);
151924121865SAdrian Maldonado 
152001ad2aeeSHong Zhang     ierr = MatCreateNest(comm,2,NULL,2,NULL,&bA[0][0],J);CHKERRQ(ierr);
152124121865SAdrian Maldonado     ierr = MatSetUp(*J);CHKERRQ(ierr);
152224121865SAdrian Maldonado     ierr = MatNestSetVecType(*J,VECNEST);CHKERRQ(ierr);
152324121865SAdrian Maldonado     ierr = MatDestroy(&j11);CHKERRQ(ierr);
152424121865SAdrian Maldonado     ierr = MatDestroy(&j12);CHKERRQ(ierr);
152524121865SAdrian Maldonado     ierr = MatDestroy(&j21);CHKERRQ(ierr);
152624121865SAdrian Maldonado     ierr = MatDestroy(&j22);CHKERRQ(ierr);
152724121865SAdrian Maldonado 
152824121865SAdrian Maldonado     ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
152924121865SAdrian Maldonado     ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
153024121865SAdrian Maldonado 
153124121865SAdrian Maldonado     /* Free structures */
153224121865SAdrian Maldonado     ierr = ISLocalToGlobalMappingDestroy(&eISMap);CHKERRQ(ierr);
153324121865SAdrian Maldonado     ierr = ISLocalToGlobalMappingDestroy(&vISMap);CHKERRQ(ierr);
153424121865SAdrian Maldonado 
153524121865SAdrian Maldonado     PetscFunctionReturn(0);
153624121865SAdrian Maldonado   } else if (!network->userEdgeJacobian && !network->userVertexJacobian) {
1537a4e85ca8SHong Zhang     /* user does not provide Jacobian blocks */
1538bfbc38dcSHong Zhang     ierr = DMCreateMatrix(network->plex,J);CHKERRQ(ierr);
1539bfbc38dcSHong Zhang     ierr = MatSetDM(*J,dm);CHKERRQ(ierr);
15401ad426b7SHong Zhang     PetscFunctionReturn(0);
15411ad426b7SHong Zhang   }
15421ad426b7SHong Zhang 
1543bfbc38dcSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)dm),J);CHKERRQ(ierr);
15442a945128SHong Zhang   ierr = DMGetDefaultGlobalSection(network->plex,&sectionGlobal);CHKERRQ(ierr);
1545bfbc38dcSHong Zhang   ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal,&localSize);CHKERRQ(ierr);
1546bfbc38dcSHong Zhang   ierr = MatSetSizes(*J,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
15472a945128SHong Zhang 
15482a945128SHong Zhang   ierr = MatSetType(*J,MATAIJ);CHKERRQ(ierr);
15492a945128SHong Zhang   ierr = MatSetFromOptions(*J);CHKERRQ(ierr);
155089898e50SHong Zhang 
155189898e50SHong Zhang   /* (1) Set matrix preallocation */
155289898e50SHong Zhang   /*------------------------------*/
1553840c2264SHong Zhang   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
1554840c2264SHong Zhang   ierr = VecCreate(comm,&vd_nz);CHKERRQ(ierr);
1555840c2264SHong Zhang   ierr = VecSetSizes(vd_nz,localSize,PETSC_DECIDE);CHKERRQ(ierr);
1556840c2264SHong Zhang   ierr = VecSetFromOptions(vd_nz);CHKERRQ(ierr);
1557840c2264SHong Zhang   ierr = VecSet(vd_nz,0.0);CHKERRQ(ierr);
1558840c2264SHong Zhang   ierr = VecDuplicate(vd_nz,&vo_nz);CHKERRQ(ierr);
1559840c2264SHong Zhang 
156089898e50SHong Zhang   /* Set preallocation for edges */
156189898e50SHong Zhang   /*-----------------------------*/
1562840c2264SHong Zhang   ierr = DMNetworkGetEdgeRange(dm,&eStart,&eEnd);CHKERRQ(ierr);
1563840c2264SHong Zhang 
1564bdcb62a2SHong Zhang   ierr = PetscMalloc1(localSize,&rows);CHKERRQ(ierr);
1565840c2264SHong Zhang   for (e=eStart; e<eEnd; e++) {
1566840c2264SHong Zhang     /* Get row indices */
1567840c2264SHong Zhang     ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr);
1568840c2264SHong Zhang     ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr);
1569840c2264SHong Zhang     if (nrows) {
1570840c2264SHong Zhang       for (j=0; j<nrows; j++) rows[j] = j + rstart;
1571840c2264SHong Zhang 
15725cf7da58SHong Zhang       /* Set preallocation for conntected vertices */
1573d842c372SHong Zhang       ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr);
1574840c2264SHong Zhang       for (v=0; v<2; v++) {
1575840c2264SHong Zhang         ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr);
1576840c2264SHong Zhang 
15778675203cSHong Zhang         if (network->Je) {
1578840c2264SHong Zhang           Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */
15798675203cSHong Zhang         } else Juser = NULL;
1580840c2264SHong Zhang         ierr = DMNetworkIsGhostVertex(dm,cone[v],&ghost);CHKERRQ(ierr);
15815cf7da58SHong Zhang         ierr = MatSetPreallocationblock_private(Juser,nrows,rows,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr);
1582840c2264SHong Zhang       }
1583840c2264SHong Zhang 
158489898e50SHong Zhang       /* Set preallocation for edge self */
1585840c2264SHong Zhang       cstart = rstart;
15868675203cSHong Zhang       if (network->Je) {
1587840c2264SHong Zhang         Juser = network->Je[3*e]; /* Jacobian(e,e) */
15888675203cSHong Zhang       } else Juser = NULL;
15895cf7da58SHong Zhang       ierr = MatSetPreallocationblock_private(Juser,nrows,rows,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr);
1590840c2264SHong Zhang     }
1591840c2264SHong Zhang   }
1592840c2264SHong Zhang 
159389898e50SHong Zhang   /* Set preallocation for vertices */
159489898e50SHong Zhang   /*--------------------------------*/
1595840c2264SHong Zhang   ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr);
15968675203cSHong Zhang   if (vEnd - vStart) vptr = network->Jvptr;
1597840c2264SHong Zhang 
1598840c2264SHong Zhang   for (v=vStart; v<vEnd; v++) {
1599840c2264SHong Zhang     /* Get row indices */
1600840c2264SHong Zhang     ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr);
1601840c2264SHong Zhang     ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr);
1602840c2264SHong Zhang     if (!nrows) continue;
1603840c2264SHong Zhang 
1604bdcb62a2SHong Zhang     ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr);
1605bdcb62a2SHong Zhang     if (ghost) {
1606bdcb62a2SHong Zhang       ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr);
1607bdcb62a2SHong Zhang     } else {
1608bdcb62a2SHong Zhang       rows_v = rows;
1609bdcb62a2SHong Zhang     }
1610bdcb62a2SHong Zhang 
1611bdcb62a2SHong Zhang     for (j=0; j<nrows; j++) rows_v[j] = j + rstart;
1612840c2264SHong Zhang 
1613840c2264SHong Zhang     /* Get supporting edges and connected vertices */
1614840c2264SHong Zhang     ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr);
1615840c2264SHong Zhang 
1616840c2264SHong Zhang     for (e=0; e<nedges; e++) {
1617840c2264SHong Zhang       /* Supporting edges */
1618840c2264SHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr);
1619840c2264SHong Zhang       ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr);
1620840c2264SHong Zhang 
16218675203cSHong Zhang       if (network->Jv) {
1622840c2264SHong Zhang         Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */
16238675203cSHong Zhang       } else Juser = NULL;
1624bdcb62a2SHong Zhang       ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr);
1625840c2264SHong Zhang 
1626840c2264SHong Zhang       /* Connected vertices */
1627d842c372SHong Zhang       ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr);
1628840c2264SHong Zhang       vc = (v == cone[0]) ? cone[1]:cone[0];
1629840c2264SHong Zhang       ierr = DMNetworkIsGhostVertex(dm,vc,&ghost_vc);CHKERRQ(ierr);
1630840c2264SHong Zhang 
1631840c2264SHong Zhang       ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr);
1632840c2264SHong Zhang 
16338675203cSHong Zhang       if (network->Jv) {
1634840c2264SHong Zhang         Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */
16358675203cSHong Zhang       } else Juser = NULL;
1636e102a522SHong Zhang       if (ghost_vc||ghost) {
1637e102a522SHong Zhang         ghost2 = PETSC_TRUE;
1638e102a522SHong Zhang       } else {
1639e102a522SHong Zhang         ghost2 = PETSC_FALSE;
1640e102a522SHong Zhang       }
1641e102a522SHong Zhang       ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost2,vd_nz,vo_nz);CHKERRQ(ierr);
1642840c2264SHong Zhang     }
1643840c2264SHong Zhang 
164489898e50SHong Zhang     /* Set preallocation for vertex self */
1645840c2264SHong Zhang     ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr);
1646840c2264SHong Zhang     if (!ghost) {
1647840c2264SHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr);
16488675203cSHong Zhang       if (network->Jv) {
1649840c2264SHong Zhang         Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */
16508675203cSHong Zhang       } else Juser = NULL;
1651bdcb62a2SHong Zhang       ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr);
1652840c2264SHong Zhang     }
1653bdcb62a2SHong Zhang     if (ghost) {
1654bdcb62a2SHong Zhang       ierr = PetscFree(rows_v);CHKERRQ(ierr);
1655bdcb62a2SHong Zhang     }
1656840c2264SHong Zhang   }
1657840c2264SHong Zhang 
1658840c2264SHong Zhang   ierr = VecAssemblyBegin(vd_nz);CHKERRQ(ierr);
1659840c2264SHong Zhang   ierr = VecAssemblyBegin(vo_nz);CHKERRQ(ierr);
16605cf7da58SHong Zhang 
16615cf7da58SHong Zhang   ierr = PetscMalloc2(localSize,&dnnz,localSize,&onnz);CHKERRQ(ierr);
16625cf7da58SHong Zhang 
16635cf7da58SHong Zhang   ierr = VecAssemblyEnd(vd_nz);CHKERRQ(ierr);
1664840c2264SHong Zhang   ierr = VecAssemblyEnd(vo_nz);CHKERRQ(ierr);
1665840c2264SHong Zhang 
1666840c2264SHong Zhang   ierr = VecGetArray(vd_nz,&vdnz);CHKERRQ(ierr);
1667840c2264SHong Zhang   ierr = VecGetArray(vo_nz,&vonz);CHKERRQ(ierr);
1668840c2264SHong Zhang   for (j=0; j<localSize; j++) {
1669e102a522SHong Zhang     dnnz[j] = (PetscInt)PetscRealPart(vdnz[j]);
1670e102a522SHong Zhang     onnz[j] = (PetscInt)PetscRealPart(vonz[j]);
1671840c2264SHong Zhang   }
1672840c2264SHong Zhang   ierr = VecRestoreArray(vd_nz,&vdnz);CHKERRQ(ierr);
1673840c2264SHong Zhang   ierr = VecRestoreArray(vo_nz,&vonz);CHKERRQ(ierr);
1674840c2264SHong Zhang   ierr = VecDestroy(&vd_nz);CHKERRQ(ierr);
1675840c2264SHong Zhang   ierr = VecDestroy(&vo_nz);CHKERRQ(ierr);
1676840c2264SHong Zhang 
16775cf7da58SHong Zhang   ierr = MatSeqAIJSetPreallocation(*J,0,dnnz);CHKERRQ(ierr);
16785cf7da58SHong Zhang   ierr = MatMPIAIJSetPreallocation(*J,0,dnnz,0,onnz);CHKERRQ(ierr);
16795cf7da58SHong Zhang   ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
16805cf7da58SHong Zhang 
16815cf7da58SHong Zhang   ierr = PetscFree2(dnnz,onnz);CHKERRQ(ierr);
16825cf7da58SHong Zhang 
168389898e50SHong Zhang   /* (2) Set matrix entries for edges */
168489898e50SHong Zhang   /*----------------------------------*/
16851ad426b7SHong Zhang   for (e=eStart; e<eEnd; e++) {
1686bfbc38dcSHong Zhang     /* Get row indices */
16871ad426b7SHong Zhang     ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr);
168817df6e9eSHong Zhang     ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr);
16894b976069SHong Zhang     if (nrows) {
169017df6e9eSHong Zhang       for (j=0; j<nrows; j++) rows[j] = j + rstart;
16911ad426b7SHong Zhang 
1692bfbc38dcSHong Zhang       /* Set matrix entries for conntected vertices */
1693d842c372SHong Zhang       ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr);
1694bfbc38dcSHong Zhang       for (v=0; v<2; v++) {
1695bfbc38dcSHong Zhang         ierr = DMNetworkGetVariableGlobalOffset(dm,cone[v],&cstart);CHKERRQ(ierr);
1696883e35e8SHong Zhang         ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr);
16973e97b6e8SHong Zhang 
16988675203cSHong Zhang         if (network->Je) {
1699a4e85ca8SHong Zhang           Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */
17008675203cSHong Zhang         } else Juser = NULL;
1701a4e85ca8SHong Zhang         ierr = MatSetblock_private(Juser,nrows,rows,ncols,cstart,J);CHKERRQ(ierr);
1702bfbc38dcSHong Zhang       }
170317df6e9eSHong Zhang 
1704bfbc38dcSHong Zhang       /* Set matrix entries for edge self */
17053e97b6e8SHong Zhang       cstart = rstart;
17068675203cSHong Zhang       if (network->Je) {
1707a4e85ca8SHong Zhang         Juser = network->Je[3*e]; /* Jacobian(e,e) */
17088675203cSHong Zhang       } else Juser = NULL;
1709a4e85ca8SHong Zhang       ierr = MatSetblock_private(Juser,nrows,rows,nrows,cstart,J);CHKERRQ(ierr);
17101ad426b7SHong Zhang     }
17114b976069SHong Zhang   }
17121ad426b7SHong Zhang 
1713bfbc38dcSHong Zhang   /* Set matrix entries for vertices */
171483b2e829SHong Zhang   /*---------------------------------*/
17151ad426b7SHong Zhang   for (v=vStart; v<vEnd; v++) {
1716bfbc38dcSHong Zhang     /* Get row indices */
1717596e729fSHong Zhang     ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr);
1718596e729fSHong Zhang     ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr);
17194b976069SHong Zhang     if (!nrows) continue;
1720596e729fSHong Zhang 
1721bdcb62a2SHong Zhang     ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr);
1722bdcb62a2SHong Zhang     if (ghost) {
1723bdcb62a2SHong Zhang       ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr);
1724bdcb62a2SHong Zhang     } else {
1725bdcb62a2SHong Zhang       rows_v = rows;
1726bdcb62a2SHong Zhang     }
1727bdcb62a2SHong Zhang     for (j=0; j<nrows; j++) rows_v[j] = j + rstart;
1728596e729fSHong Zhang 
1729bfbc38dcSHong Zhang     /* Get supporting edges and connected vertices */
1730596e729fSHong Zhang     ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr);
1731596e729fSHong Zhang 
1732596e729fSHong Zhang     for (e=0; e<nedges; e++) {
1733bfbc38dcSHong Zhang       /* Supporting edges */
1734596e729fSHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr);
1735596e729fSHong Zhang       ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr);
1736596e729fSHong Zhang 
17378675203cSHong Zhang       if (network->Jv) {
1738a4e85ca8SHong Zhang         Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */
17398675203cSHong Zhang       } else Juser = NULL;
1740bdcb62a2SHong Zhang       ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr);
1741596e729fSHong Zhang 
1742bfbc38dcSHong Zhang       /* Connected vertices */
1743d842c372SHong Zhang       ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr);
17442a945128SHong Zhang       vc = (v == cone[0]) ? cone[1]:cone[0];
17452a945128SHong Zhang 
174644aca652SHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,vc,&cstart);CHKERRQ(ierr);
174744aca652SHong Zhang       ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr);
1748a4e85ca8SHong Zhang 
17498675203cSHong Zhang       if (network->Jv) {
1750a4e85ca8SHong Zhang         Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */
17518675203cSHong Zhang       } else Juser = NULL;
1752bdcb62a2SHong Zhang       ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr);
1753596e729fSHong Zhang     }
1754596e729fSHong Zhang 
1755bfbc38dcSHong Zhang     /* Set matrix entries for vertex self */
17561ad426b7SHong Zhang     if (!ghost) {
1757596e729fSHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr);
17588675203cSHong Zhang       if (network->Jv) {
1759a4e85ca8SHong Zhang         Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */
17608675203cSHong Zhang       } else Juser = NULL;
1761bdcb62a2SHong Zhang       ierr = MatSetblock_private(Juser,nrows,rows_v,nrows,cstart,J);CHKERRQ(ierr);
1762bdcb62a2SHong Zhang     }
1763bdcb62a2SHong Zhang     if (ghost) {
1764bdcb62a2SHong Zhang       ierr = PetscFree(rows_v);CHKERRQ(ierr);
1765bdcb62a2SHong Zhang     }
17661ad426b7SHong Zhang   }
1767a4e85ca8SHong Zhang   ierr = PetscFree(rows);CHKERRQ(ierr);
1768bdcb62a2SHong Zhang 
17691ad426b7SHong Zhang   ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17701ad426b7SHong Zhang   ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1771dd6f46cdSHong Zhang 
17725f2c45f1SShri Abhyankar   ierr = MatSetDM(*J,dm);CHKERRQ(ierr);
17735f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
17745f2c45f1SShri Abhyankar }
17755f2c45f1SShri Abhyankar 
17765f2c45f1SShri Abhyankar PetscErrorCode DMDestroy_Network(DM dm)
17775f2c45f1SShri Abhyankar {
17785f2c45f1SShri Abhyankar   PetscErrorCode ierr;
17795f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
17802727e31bSShri Abhyankar   PetscInt       j;
17815f2c45f1SShri Abhyankar 
17825f2c45f1SShri Abhyankar   PetscFunctionBegin;
17838415c774SShri Abhyankar   if (--network->refct > 0) PetscFunctionReturn(0);
178483b2e829SHong Zhang   if (network->Je) {
178583b2e829SHong Zhang     ierr = PetscFree(network->Je);CHKERRQ(ierr);
178683b2e829SHong Zhang   }
178783b2e829SHong Zhang   if (network->Jv) {
1788883e35e8SHong Zhang     ierr = PetscFree(network->Jvptr);CHKERRQ(ierr);
178983b2e829SHong Zhang     ierr = PetscFree(network->Jv);CHKERRQ(ierr);
17901ad426b7SHong Zhang   }
179113c2a604SAdrian Maldonado 
179213c2a604SAdrian Maldonado   ierr = ISLocalToGlobalMappingDestroy(&network->vertex.mapping);CHKERRQ(ierr);
179313c2a604SAdrian Maldonado   ierr = PetscSectionDestroy(&network->vertex.DofSection);CHKERRQ(ierr);
179413c2a604SAdrian Maldonado   ierr = PetscSectionDestroy(&network->vertex.GlobalDofSection);CHKERRQ(ierr);
179513c2a604SAdrian Maldonado   if (network->vertex.sf) {
179613c2a604SAdrian Maldonado     ierr = PetscSFDestroy(&network->vertex.sf);CHKERRQ(ierr);
179713c2a604SAdrian Maldonado   }
179813c2a604SAdrian Maldonado   /* edge */
179913c2a604SAdrian Maldonado   ierr = ISLocalToGlobalMappingDestroy(&network->edge.mapping);CHKERRQ(ierr);
180013c2a604SAdrian Maldonado   ierr = PetscSectionDestroy(&network->edge.DofSection);CHKERRQ(ierr);
180113c2a604SAdrian Maldonado   ierr = PetscSectionDestroy(&network->edge.GlobalDofSection);CHKERRQ(ierr);
180213c2a604SAdrian Maldonado   if (network->edge.sf) {
180313c2a604SAdrian Maldonado     ierr = PetscSFDestroy(&network->edge.sf);CHKERRQ(ierr);
180413c2a604SAdrian Maldonado   }
18055f2c45f1SShri Abhyankar   ierr = DMDestroy(&network->plex);CHKERRQ(ierr);
18065f2c45f1SShri Abhyankar   network->edges = NULL;
18075f2c45f1SShri Abhyankar   ierr = PetscSectionDestroy(&network->DataSection);CHKERRQ(ierr);
18085f2c45f1SShri Abhyankar   ierr = PetscSectionDestroy(&network->DofSection);CHKERRQ(ierr);
180983b2e829SHong Zhang 
18102727e31bSShri Abhyankar   for(j=0; j < network->nsubnet; j++) {
18112727e31bSShri Abhyankar     ierr = PetscFree(network->subnet[j].edges);CHKERRQ(ierr);
18122727e31bSShri Abhyankar     ierr = PetscFree(network->subnet[j].vertices);CHKERRQ(ierr);
18132727e31bSShri Abhyankar   }
1814e2aaf10cSShri Abhyankar   ierr = PetscFree(network->subnet);CHKERRQ(ierr);
18155f2c45f1SShri Abhyankar   ierr = PetscFree(network->componentdataarray);CHKERRQ(ierr);
18165f2c45f1SShri Abhyankar   ierr = PetscFree(network->cvalue);CHKERRQ(ierr);
18175f2c45f1SShri Abhyankar   ierr = PetscFree(network->header);CHKERRQ(ierr);
18185f2c45f1SShri Abhyankar   ierr = PetscFree(network);CHKERRQ(ierr);
18195f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
18205f2c45f1SShri Abhyankar }
18215f2c45f1SShri Abhyankar 
18225f2c45f1SShri Abhyankar PetscErrorCode DMView_Network(DM dm, PetscViewer viewer)
18235f2c45f1SShri Abhyankar {
18245f2c45f1SShri Abhyankar   PetscErrorCode ierr;
18255f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
18265f2c45f1SShri Abhyankar 
18275f2c45f1SShri Abhyankar   PetscFunctionBegin;
18285f2c45f1SShri Abhyankar   ierr = DMView(network->plex,viewer);CHKERRQ(ierr);
18295f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
18305f2c45f1SShri Abhyankar }
18315f2c45f1SShri Abhyankar 
18325f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l)
18335f2c45f1SShri Abhyankar {
18345f2c45f1SShri Abhyankar   PetscErrorCode ierr;
18355f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
18365f2c45f1SShri Abhyankar 
18375f2c45f1SShri Abhyankar   PetscFunctionBegin;
18385f2c45f1SShri Abhyankar   ierr = DMGlobalToLocalBegin(network->plex,g,mode,l);CHKERRQ(ierr);
18395f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
18405f2c45f1SShri Abhyankar }
18415f2c45f1SShri Abhyankar 
18425f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l)
18435f2c45f1SShri Abhyankar {
18445f2c45f1SShri Abhyankar   PetscErrorCode ierr;
18455f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
18465f2c45f1SShri Abhyankar 
18475f2c45f1SShri Abhyankar   PetscFunctionBegin;
18485f2c45f1SShri Abhyankar   ierr = DMGlobalToLocalEnd(network->plex,g,mode,l);CHKERRQ(ierr);
18495f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
18505f2c45f1SShri Abhyankar }
18515f2c45f1SShri Abhyankar 
18525f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g)
18535f2c45f1SShri Abhyankar {
18545f2c45f1SShri Abhyankar   PetscErrorCode ierr;
18555f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
18565f2c45f1SShri Abhyankar 
18575f2c45f1SShri Abhyankar   PetscFunctionBegin;
18585f2c45f1SShri Abhyankar   ierr = DMLocalToGlobalBegin(network->plex,l,mode,g);CHKERRQ(ierr);
18595f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
18605f2c45f1SShri Abhyankar }
18615f2c45f1SShri Abhyankar 
18625f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g)
18635f2c45f1SShri Abhyankar {
18645f2c45f1SShri Abhyankar   PetscErrorCode ierr;
18655f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
18665f2c45f1SShri Abhyankar 
18675f2c45f1SShri Abhyankar   PetscFunctionBegin;
18685f2c45f1SShri Abhyankar   ierr = DMLocalToGlobalEnd(network->plex,l,mode,g);CHKERRQ(ierr);
18695f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
18705f2c45f1SShri Abhyankar }
1871