xref: /petsc/src/dm/impls/network/network.c (revision e53b5ba379170bf02745d4f34326577473539191)
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
35f025b11dSHong Zhang . NsubnetCouple - number of coupling subnetworks
36f025b11dSHong Zhang . nV - number of local vertices for each subnetwork and coupling subnetwork
37f025b11dSHong Zhang . nE - number of local edges for each subnetwork and coupling subnetwork
38f025b11dSHong Zhang . NV - number of global vertices (or PETSC_DETERMINE) for each subnetwork and coupling subnetwork
39f025b11dSHong Zhang - NE - number of global edges (or PETSC_DETERMINE) for each subnetwork and coupling subnetwork
405f2c45f1SShri Abhyankar 
415f2c45f1SShri Abhyankar    Notes
425f2c45f1SShri Abhyankar    If one processor calls this with NV (NE) of PETSC_DECIDE then all processors must, otherwise the prgram will hang.
435f2c45f1SShri Abhyankar 
44f025b11dSHong Zhang    You cannot change the sizes once they have been set. nV, nE, NV and NE are arrays of length Nsubnet+NsubnetCouple.
455f2c45f1SShri Abhyankar 
461b266c99SBarry Smith    Level: intermediate
471b266c99SBarry Smith 
481b266c99SBarry Smith .seealso: DMNetworkCreate()
495f2c45f1SShri Abhyankar @*/
50f025b11dSHong Zhang PetscErrorCode DMNetworkSetSizes(DM dm,PetscInt Nsubnet,PetscInt NsubnetCouple,PetscInt nV[], PetscInt nE[], PetscInt NV[], PetscInt NE[])
515f2c45f1SShri Abhyankar {
525f2c45f1SShri Abhyankar   PetscErrorCode ierr;
535f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
54e2aaf10cSShri Abhyankar   PetscInt       a[2],b[2],i;
555f2c45f1SShri Abhyankar 
565f2c45f1SShri Abhyankar   PetscFunctionBegin;
575f2c45f1SShri Abhyankar   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
58e2aaf10cSShri Abhyankar   if (Nsubnet <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of subnetworks %D cannot be less than 1",Nsubnet);
597765340cSHong Zhang   if (NsubnetCouple < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of coupling subnetworks %D cannot be less than 0",NsubnetCouple);
607765340cSHong Zhang 
617765340cSHong Zhang   if (Nsubnet > 0) PetscValidLogicalCollectiveInt(dm,Nsubnet,2);
627765340cSHong Zhang   if (network->nsubnet != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Network sizes alread set, cannot resize the network");
637765340cSHong Zhang 
647765340cSHong Zhang   network->nsubnet  = Nsubnet + NsubnetCouple;
657765340cSHong Zhang   Nsubnet          += NsubnetCouple;
667765340cSHong Zhang   network->ncsubnet = NsubnetCouple;
677765340cSHong Zhang   ierr = PetscCalloc1(Nsubnet,&network->subnet);CHKERRQ(ierr);
687765340cSHong Zhang   for(i=0; i < Nsubnet; i++) {
69f025b11dSHong Zhang     if (NV) {
707765340cSHong Zhang       if (NV[i] > 0) PetscValidLogicalCollectiveInt(dm,NV[i],6);
717765340cSHong Zhang       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]);
72f025b11dSHong Zhang     }
73f025b11dSHong Zhang     if (NE) {
74f025b11dSHong Zhang       if (NE[i] > 0) PetscValidLogicalCollectiveInt(dm,NE[i],7);
757765340cSHong Zhang       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]);
76f025b11dSHong Zhang     }
77f025b11dSHong Zhang 
787765340cSHong Zhang     a[0] = nV[i]; a[1] = nE[i];
797765340cSHong Zhang     ierr = MPIU_Allreduce(a,b,2,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
807765340cSHong Zhang     network->subnet[i].Nvtx = b[0]; network->subnet[i].Nedge = b[1];
817765340cSHong Zhang 
827765340cSHong Zhang     network->subnet[i].id = i;
837765340cSHong Zhang 
847765340cSHong Zhang     network->subnet[i].nvtx = nV[i];
857765340cSHong Zhang     network->subnet[i].vStart = network->nVertices;
867765340cSHong Zhang     network->subnet[i].vEnd   = network->subnet[i].vStart + network->subnet[i].Nvtx;
877765340cSHong Zhang     network->nVertices += network->subnet[i].nvtx;
887765340cSHong Zhang     network->NVertices += network->subnet[i].Nvtx;
897765340cSHong Zhang 
907765340cSHong Zhang     network->subnet[i].nedge = nE[i];
917765340cSHong Zhang     network->subnet[i].eStart = network->nEdges;
927765340cSHong Zhang     network->subnet[i].eEnd = network->subnet[i].eStart + network->subnet[i].Nedge;
937765340cSHong Zhang     network->nEdges += network->subnet[i].nedge;
947765340cSHong Zhang     network->NEdges += network->subnet[i].Nedge;
957765340cSHong Zhang   }
967765340cSHong Zhang   PetscFunctionReturn(0);
977765340cSHong Zhang }
987765340cSHong Zhang 
995f2c45f1SShri Abhyankar /*@
1005f2c45f1SShri Abhyankar   DMNetworkSetEdgeList - Sets the list of local edges (vertex connectivity) for the network
1015f2c45f1SShri Abhyankar 
1025f2c45f1SShri Abhyankar   Logically collective on DM
1035f2c45f1SShri Abhyankar 
1045f2c45f1SShri Abhyankar   Input Parameters:
105e3e68989SHong Zhang + dm - the dm object
106e3e68989SHong Zhang . edgelist - list of edges for each subnetwork
107e3e68989SHong Zhang - edgelistCouple - list of edges for each coupling subnetwork
1085f2c45f1SShri Abhyankar 
1095f2c45f1SShri Abhyankar   Notes:
1105f2c45f1SShri Abhyankar   There is no copy involved in this operation, only the pointer is referenced. The edgelist should
1115f2c45f1SShri Abhyankar   not be destroyed before the call to DMNetworkLayoutSetUp
1125f2c45f1SShri Abhyankar 
1135f2c45f1SShri Abhyankar   Level: intermediate
1145f2c45f1SShri Abhyankar 
115e3e68989SHong Zhang   Example usage:
116e3e68989SHong Zhang   Consider the following 2 separate networks and a coupling network:
117e3e68989SHong Zhang 
118e3e68989SHong Zhang .vb
119e3e68989SHong Zhang  network 0: v0 -> v1 -> v2 -> v3
120e3e68989SHong Zhang  network 1: v1 -> v2 -> v0
121e3e68989SHong Zhang  coupling network: network 1: v2 -> network 0: v0
122e3e68989SHong Zhang .ve
123e3e68989SHong Zhang 
124e3e68989SHong Zhang  The resulting input
125e3e68989SHong Zhang    edgelist[0] = [0 1 | 1 2 | 2 3];
126e3e68989SHong Zhang    edgelist[1] = [1 2 | 2 0]
127e3e68989SHong Zhang    edgelistCouple[0] = [(network)1 (v)2 (network)0 (v)0].
128e3e68989SHong Zhang 
1295f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkSetSizes
1305f2c45f1SShri Abhyankar @*/
131e3e68989SHong Zhang PetscErrorCode DMNetworkSetEdgeList(DM dm,int *edgelist[],int *edgelistCouple[])
1325f2c45f1SShri Abhyankar {
1335f2c45f1SShri Abhyankar   DM_Network *network = (DM_Network*) dm->data;
134e3e68989SHong Zhang   PetscInt   i,nsubnet,ncsubnet=network->ncsubnet;
1355f2c45f1SShri Abhyankar 
1365f2c45f1SShri Abhyankar   PetscFunctionBegin;
137e3e68989SHong Zhang   nsubnet = network->nsubnet - ncsubnet;
138e3e68989SHong Zhang   for(i=0; i < nsubnet; i++) {
139e2aaf10cSShri Abhyankar     network->subnet[i].edgelist = edgelist[i];
140e2aaf10cSShri Abhyankar   }
141e3e68989SHong Zhang   if (edgelistCouple) {
142e3e68989SHong Zhang     PetscInt j;
143e3e68989SHong Zhang     j = 0;
144e3e68989SHong Zhang     nsubnet = network->nsubnet;
145e3e68989SHong Zhang     while (i < nsubnet) network->subnet[i++].edgelist = edgelistCouple[j++];
146e3e68989SHong Zhang   }
1475f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
1485f2c45f1SShri Abhyankar }
1495f2c45f1SShri Abhyankar 
1505f2c45f1SShri Abhyankar /*@
1515f2c45f1SShri Abhyankar   DMNetworkLayoutSetUp - Sets up the bare layout (graph) for the network
1525f2c45f1SShri Abhyankar 
1535f2c45f1SShri Abhyankar   Collective on DM
1545f2c45f1SShri Abhyankar 
1555f2c45f1SShri Abhyankar   Input Parameters
1565f2c45f1SShri Abhyankar . DM - the dmnetwork object
1575f2c45f1SShri Abhyankar 
1585f2c45f1SShri Abhyankar   Notes:
1595f2c45f1SShri Abhyankar   This routine should be called after the network sizes and edgelists have been provided. It creates
1605f2c45f1SShri Abhyankar   the bare layout of the network and sets up the network to begin insertion of components.
1615f2c45f1SShri Abhyankar 
1625f2c45f1SShri Abhyankar   All the components should be registered before calling this routine.
1635f2c45f1SShri Abhyankar 
1645f2c45f1SShri Abhyankar   Level: intermediate
1655f2c45f1SShri Abhyankar 
1665f2c45f1SShri Abhyankar .seealso: DMNetworkSetSizes, DMNetworkSetEdgeList
1675f2c45f1SShri Abhyankar @*/
1685f2c45f1SShri Abhyankar PetscErrorCode DMNetworkLayoutSetUp(DM dm)
1695f2c45f1SShri Abhyankar {
1705f2c45f1SShri Abhyankar   PetscErrorCode ierr;
1715f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
1725f2c45f1SShri Abhyankar   PetscInt       dim = 1; /* One dimensional network */
173991cf414SHong Zhang   PetscInt       numCorners=2,spacedim=2;
1746500d4abSHong Zhang   double         *vertexcoords=NULL;
1757765340cSHong Zhang   PetscInt       i,j,ndata,ctr=0,nsubnet;
176991cf414SHong Zhang   PetscInt       *edgelist_couple=NULL,k,netid,vid;
1776500d4abSHong Zhang 
1786500d4abSHong Zhang   PetscFunctionBegin;
1796500d4abSHong Zhang   if (network->nVertices) {
1806500d4abSHong Zhang     ierr = PetscCalloc1(numCorners*network->nVertices,&vertexcoords);CHKERRQ(ierr);
1816500d4abSHong Zhang   }
1826500d4abSHong Zhang 
1836500d4abSHong Zhang   /* Create the edgelist for the network by concatenating edgelists of the subnetworks */
1847765340cSHong Zhang   nsubnet = network->nsubnet - network->ncsubnet;
1856500d4abSHong Zhang   ierr = PetscCalloc1(2*network->nEdges,&network->edges);CHKERRQ(ierr);
1867765340cSHong Zhang   for (i=0; i < nsubnet; i++) {
1876500d4abSHong Zhang     for (j = 0; j < network->subnet[i].nedge; j++) {
1886500d4abSHong Zhang       network->edges[2*ctr] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j];
1896500d4abSHong Zhang       network->edges[2*ctr+1] = network->subnet[i].vStart + network->subnet[i].edgelist[2*j+1];
1906500d4abSHong Zhang       ctr++;
1916500d4abSHong Zhang     }
1926500d4abSHong Zhang   }
1937765340cSHong Zhang 
1947765340cSHong Zhang   i       = nsubnet; /* netid of coupling subnet */
1957765340cSHong Zhang   nsubnet = network->nsubnet;
1967765340cSHong Zhang   while (i < nsubnet) {
197991cf414SHong Zhang     edgelist_couple = network->subnet[i].edgelist;
1986500d4abSHong Zhang     k = 0;
1996500d4abSHong Zhang     for (j = 0; j < network->subnet[i].nedge; j++) {
2006500d4abSHong Zhang       netid = edgelist_couple[k]; vid = edgelist_couple[k+1];
2016500d4abSHong Zhang       network->edges[2*ctr] = network->subnet[netid].vStart + vid; k += 2;
2026500d4abSHong Zhang 
2036500d4abSHong Zhang       netid = edgelist_couple[k]; vid = edgelist_couple[k+1];
204991cf414SHong Zhang       network->edges[2*ctr+1] = network->subnet[netid].vStart + vid; k+=2;
2056500d4abSHong Zhang       ctr++;
2066500d4abSHong Zhang     }
2077765340cSHong Zhang     i++;
2087765340cSHong Zhang   }
2096500d4abSHong Zhang 
21034bd1bf5SHong Zhang #if 0
2116500d4abSHong Zhang   for(i=0; i < network->nEdges; i++) {
2126500d4abSHong Zhang     ierr = PetscPrintf(PETSC_COMM_SELF,"[%D %D]",network->edges[2*i],network->edges[2*i+1]);CHKERRQ(ierr);
2136500d4abSHong Zhang     printf("\n");
2146500d4abSHong Zhang   }
2156500d4abSHong Zhang #endif
2166500d4abSHong Zhang 
2176500d4abSHong Zhang   ierr = DMPlexCreateFromCellList(PetscObjectComm((PetscObject)dm),dim,network->nEdges,network->nVertices,numCorners,PETSC_FALSE,network->edges,spacedim,vertexcoords,&network->plex);CHKERRQ(ierr);
2186500d4abSHong Zhang   if (network->nVertices) {
2196500d4abSHong Zhang     ierr = PetscFree(vertexcoords);CHKERRQ(ierr);
2206500d4abSHong Zhang   }
2216500d4abSHong Zhang   ierr = PetscFree(network->edges);CHKERRQ(ierr);
2226500d4abSHong Zhang 
2236500d4abSHong Zhang   ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr);
2246500d4abSHong Zhang   ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr);
2256500d4abSHong Zhang   ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr);
2266500d4abSHong Zhang 
2276500d4abSHong Zhang   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm),&network->DataSection);CHKERRQ(ierr);
2286500d4abSHong Zhang   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm),&network->DofSection);CHKERRQ(ierr);
2296500d4abSHong Zhang   ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr);
2306500d4abSHong Zhang   ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr);
2316500d4abSHong Zhang 
2326500d4abSHong Zhang   /* Create vertices and edges array for the subnetworks */
2336500d4abSHong Zhang   for (j=0; j < network->nsubnet; j++) {
2346500d4abSHong Zhang     ierr = PetscCalloc1(network->subnet[j].nedge,&network->subnet[j].edges);CHKERRQ(ierr);
2356500d4abSHong Zhang     ierr = PetscCalloc1(network->subnet[j].nvtx,&network->subnet[j].vertices);CHKERRQ(ierr);
2366500d4abSHong Zhang     /* Temporarily setting nvtx and nedge to 0 so we can use them as counters in the below for loop.
2376500d4abSHong Zhang        These get updated when the vertices and edges are added. */
2386500d4abSHong Zhang     network->subnet[j].nvtx = network->subnet[j].nedge = 0;
2396500d4abSHong Zhang   }
2406500d4abSHong Zhang 
2416500d4abSHong Zhang   network->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType);
2426500d4abSHong Zhang   ierr = PetscCalloc1(network->pEnd-network->pStart,&network->header);CHKERRQ(ierr);
2436500d4abSHong Zhang   for (i=network->eStart; i < network->eEnd; i++) {
2446500d4abSHong Zhang     network->header[i].index = i;   /* Global edge number */
2456500d4abSHong Zhang     for (j=0; j < network->nsubnet; j++) {
2466500d4abSHong Zhang       if((network->subnet[j].eStart <= i) && (i < network->subnet[j].eEnd)) {
2476500d4abSHong Zhang 	network->header[i].subnetid = j; /* Subnetwork id */
2486500d4abSHong Zhang 	network->subnet[j].edges[network->subnet[j].nedge++] = i;
2496500d4abSHong Zhang 	break;
2506500d4abSHong Zhang       }
2516500d4abSHong Zhang     }
2526500d4abSHong Zhang     network->header[i].ndata = 0;
2536500d4abSHong Zhang     ndata = network->header[i].ndata;
2546500d4abSHong Zhang     ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr);
2556500d4abSHong Zhang     network->header[i].offset[ndata] = 0;
2566500d4abSHong Zhang   }
2576500d4abSHong Zhang 
2586500d4abSHong Zhang   for(i=network->vStart; i < network->vEnd; i++) {
2596500d4abSHong Zhang     network->header[i].index = i - network->vStart;
2606500d4abSHong Zhang     for (j=0; j < network->nsubnet; j++) {
2616500d4abSHong Zhang       if ((network->subnet[j].vStart <= i-network->vStart) && (i-network->vStart < network->subnet[j].vEnd)) {
2626500d4abSHong Zhang 	network->header[i].subnetid = j;
2636500d4abSHong Zhang 	network->subnet[j].vertices[network->subnet[j].nvtx++] = i;
2646500d4abSHong Zhang 	break;
2656500d4abSHong Zhang       }
2666500d4abSHong Zhang     }
2676500d4abSHong Zhang     network->header[i].ndata = 0;
2686500d4abSHong Zhang     ndata = network->header[i].ndata;
2696500d4abSHong Zhang     ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr);
2706500d4abSHong Zhang     network->header[i].offset[ndata] = 0;
2716500d4abSHong Zhang   }
2726500d4abSHong Zhang 
2736500d4abSHong Zhang   ierr = PetscMalloc1(network->pEnd-network->pStart,&network->cvalue);CHKERRQ(ierr);
2745f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
2755f2c45f1SShri Abhyankar }
2765f2c45f1SShri Abhyankar 
27794ef8ddeSSatish Balay /*@C
2782727e31bSShri Abhyankar   DMNetworkGetSubnetworkInfo - Returns the info for the subnetwork
2792727e31bSShri Abhyankar 
2802727e31bSShri Abhyankar   Input Parameters
2812727e31bSShri Abhyankar + dm   - the number object
2822727e31bSShri Abhyankar - id   - the ID (integer) of the subnetwork
2832727e31bSShri Abhyankar 
2842727e31bSShri Abhyankar   Output Parameters
2852727e31bSShri Abhyankar + nv    - number of vertices (local)
2862727e31bSShri Abhyankar . ne    - number of edges (local)
2872727e31bSShri Abhyankar . vtx   - local vertices for this subnetwork
2882727e31bSShri Abhyankar . edge  - local edges for this subnetwork
2892727e31bSShri Abhyankar 
2902727e31bSShri Abhyankar   Notes:
2912727e31bSShri Abhyankar   Cannot call this routine before DMNetworkLayoutSetup()
2922727e31bSShri Abhyankar 
2932727e31bSShri Abhyankar .seealso: DMNetworkLayoutSetUp, DMNetworkCreate
2942727e31bSShri Abhyankar @*/
2952727e31bSShri Abhyankar PetscErrorCode DMNetworkGetSubnetworkInfo(DM netdm,PetscInt id,PetscInt *nv, PetscInt *ne,const PetscInt **vtx, const PetscInt **edge)
2962727e31bSShri Abhyankar {
2972727e31bSShri Abhyankar   DM_Network     *network = (DM_Network*) netdm->data;
2982727e31bSShri Abhyankar 
2992727e31bSShri Abhyankar   PetscFunctionBegin;
3002727e31bSShri Abhyankar   *nv = network->subnet[id].nvtx;
3012727e31bSShri Abhyankar   *ne = network->subnet[id].nedge;
3022727e31bSShri Abhyankar   *vtx = network->subnet[id].vertices;
3032727e31bSShri Abhyankar   *edge = network->subnet[id].edges;
3042727e31bSShri Abhyankar   PetscFunctionReturn(0);
3052727e31bSShri Abhyankar }
3062727e31bSShri Abhyankar 
3072727e31bSShri Abhyankar /*@C
3085f2c45f1SShri Abhyankar   DMNetworkRegisterComponent - Registers the network component
3095f2c45f1SShri Abhyankar 
3105f2c45f1SShri Abhyankar   Logically collective on DM
3115f2c45f1SShri Abhyankar 
3125f2c45f1SShri Abhyankar   Input Parameters
3135f2c45f1SShri Abhyankar + dm   - the network object
3145f2c45f1SShri Abhyankar . name - the component name
3155f2c45f1SShri Abhyankar - size - the storage size in bytes for this component data
3165f2c45f1SShri Abhyankar 
3175f2c45f1SShri Abhyankar    Output Parameters
3185f2c45f1SShri Abhyankar .   key - an integer key that defines the component
3195f2c45f1SShri Abhyankar 
3205f2c45f1SShri Abhyankar    Notes
3215f2c45f1SShri Abhyankar    This routine should be called by all processors before calling DMNetworkLayoutSetup().
3225f2c45f1SShri Abhyankar 
3235f2c45f1SShri Abhyankar    Level: intermediate
3245f2c45f1SShri Abhyankar 
3255f2c45f1SShri Abhyankar .seealso: DMNetworkLayoutSetUp, DMNetworkCreate
3265f2c45f1SShri Abhyankar @*/
3275f2c45f1SShri Abhyankar PetscErrorCode DMNetworkRegisterComponent(DM dm,const char *name,PetscInt size,PetscInt *key)
3285f2c45f1SShri Abhyankar {
3295f2c45f1SShri Abhyankar   PetscErrorCode        ierr;
3305f2c45f1SShri Abhyankar   DM_Network            *network = (DM_Network*) dm->data;
3315f2c45f1SShri Abhyankar   DMNetworkComponent    *component=&network->component[network->ncomponent];
3325f2c45f1SShri Abhyankar   PetscBool             flg=PETSC_FALSE;
3335f2c45f1SShri Abhyankar   PetscInt              i;
3345f2c45f1SShri Abhyankar 
3355f2c45f1SShri Abhyankar   PetscFunctionBegin;
3365f2c45f1SShri Abhyankar   for (i=0; i < network->ncomponent; i++) {
3375f2c45f1SShri Abhyankar     ierr = PetscStrcmp(component->name,name,&flg);CHKERRQ(ierr);
3385f2c45f1SShri Abhyankar     if (flg) {
3395f2c45f1SShri Abhyankar       *key = i;
3405f2c45f1SShri Abhyankar       PetscFunctionReturn(0);
3415f2c45f1SShri Abhyankar     }
3426d64e262SShri Abhyankar   }
3436d64e262SShri Abhyankar   if(network->ncomponent == MAX_COMPONENTS) {
3446d64e262SShri Abhyankar     SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Number of components registered exceeds the max %D",MAX_COMPONENTS);
3455f2c45f1SShri Abhyankar   }
3465f2c45f1SShri Abhyankar 
3475f2c45f1SShri Abhyankar   ierr = PetscStrcpy(component->name,name);CHKERRQ(ierr);
3485f2c45f1SShri Abhyankar   component->size = size/sizeof(DMNetworkComponentGenericDataType);
3495f2c45f1SShri Abhyankar   *key = network->ncomponent;
3505f2c45f1SShri Abhyankar   network->ncomponent++;
3515f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
3525f2c45f1SShri Abhyankar }
3535f2c45f1SShri Abhyankar 
3545f2c45f1SShri Abhyankar /*@
3555f2c45f1SShri Abhyankar   DMNetworkGetVertexRange - Get the bounds [start, end) for the vertices.
3565f2c45f1SShri Abhyankar 
3575f2c45f1SShri Abhyankar   Not Collective
3585f2c45f1SShri Abhyankar 
3595f2c45f1SShri Abhyankar   Input Parameters:
3605f2c45f1SShri Abhyankar + dm - The DMNetwork object
3615f2c45f1SShri Abhyankar 
3625f2c45f1SShri Abhyankar   Output Paramters:
3635f2c45f1SShri Abhyankar + vStart - The first vertex point
3645f2c45f1SShri Abhyankar - vEnd   - One beyond the last vertex point
3655f2c45f1SShri Abhyankar 
3665f2c45f1SShri Abhyankar   Level: intermediate
3675f2c45f1SShri Abhyankar 
3685f2c45f1SShri Abhyankar .seealso: DMNetworkGetEdgeRange
3695f2c45f1SShri Abhyankar @*/
3705f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVertexRange(DM dm,PetscInt *vStart,PetscInt *vEnd)
3715f2c45f1SShri Abhyankar {
3725f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
3735f2c45f1SShri Abhyankar 
3745f2c45f1SShri Abhyankar   PetscFunctionBegin;
3755f2c45f1SShri Abhyankar   if (vStart) *vStart = network->vStart;
3765f2c45f1SShri Abhyankar   if (vEnd) *vEnd = network->vEnd;
3775f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
3785f2c45f1SShri Abhyankar }
3795f2c45f1SShri Abhyankar 
3805f2c45f1SShri Abhyankar /*@
3815f2c45f1SShri Abhyankar   DMNetworkGetEdgeRange - Get the bounds [start, end) for the edges.
3825f2c45f1SShri Abhyankar 
3835f2c45f1SShri Abhyankar   Not Collective
3845f2c45f1SShri Abhyankar 
3855f2c45f1SShri Abhyankar   Input Parameters:
3865f2c45f1SShri Abhyankar + dm - The DMNetwork object
3875f2c45f1SShri Abhyankar 
3885f2c45f1SShri Abhyankar   Output Paramters:
3895f2c45f1SShri Abhyankar + eStart - The first edge point
3905f2c45f1SShri Abhyankar - eEnd   - One beyond the last edge point
3915f2c45f1SShri Abhyankar 
3925f2c45f1SShri Abhyankar   Level: intermediate
3935f2c45f1SShri Abhyankar 
3945f2c45f1SShri Abhyankar .seealso: DMNetworkGetVertexRange
3955f2c45f1SShri Abhyankar @*/
3965f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetEdgeRange(DM dm,PetscInt *eStart,PetscInt *eEnd)
3975f2c45f1SShri Abhyankar {
3985f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
3995f2c45f1SShri Abhyankar 
4005f2c45f1SShri Abhyankar   PetscFunctionBegin;
4015f2c45f1SShri Abhyankar   if (eStart) *eStart = network->eStart;
4025f2c45f1SShri Abhyankar   if (eEnd) *eEnd = network->eEnd;
4035f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
4045f2c45f1SShri Abhyankar }
4055f2c45f1SShri Abhyankar 
4067b6afd5bSHong Zhang /*@
407e85e6aecSHong Zhang   DMNetworkGetGlobalEdgeIndex - Get the user global numbering for the edge.
4087b6afd5bSHong Zhang 
4097b6afd5bSHong Zhang   Not Collective
4107b6afd5bSHong Zhang 
4117b6afd5bSHong Zhang   Input Parameters:
4127b6afd5bSHong Zhang + dm - DMNetwork object
413e85e6aecSHong Zhang - p  - edge point
4147b6afd5bSHong Zhang 
4157b6afd5bSHong Zhang   Output Paramters:
416e85e6aecSHong Zhang . index - user global numbering for the edge
4177b6afd5bSHong Zhang 
4187b6afd5bSHong Zhang   Level: intermediate
4197b6afd5bSHong Zhang 
420e85e6aecSHong Zhang .seealso: DMNetworkGetGlobalVertexIndex
4217b6afd5bSHong Zhang @*/
422e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalEdgeIndex(DM dm,PetscInt p,PetscInt *index)
4237b6afd5bSHong Zhang {
4247b6afd5bSHong Zhang   PetscErrorCode    ierr;
4257b6afd5bSHong Zhang   DM_Network        *network = (DM_Network*)dm->data;
4267b6afd5bSHong Zhang   PetscInt          offsetp;
4277b6afd5bSHong Zhang   DMNetworkComponentHeader header;
4287b6afd5bSHong Zhang 
4297b6afd5bSHong Zhang   PetscFunctionBegin;
4307b6afd5bSHong Zhang   ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr);
4317b6afd5bSHong Zhang   header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp);
432e85e6aecSHong Zhang   *index = header->index;
4337b6afd5bSHong Zhang   PetscFunctionReturn(0);
4347b6afd5bSHong Zhang }
4357b6afd5bSHong Zhang 
4365f2c45f1SShri Abhyankar /*@
437e85e6aecSHong Zhang   DMNetworkGetGlobalVertexIndex - Get the user global numbering for the vertex.
438e85e6aecSHong Zhang 
439e85e6aecSHong Zhang   Not Collective
440e85e6aecSHong Zhang 
441e85e6aecSHong Zhang   Input Parameters:
442e85e6aecSHong Zhang + dm - DMNetwork object
443e85e6aecSHong Zhang - p  - vertex point
444e85e6aecSHong Zhang 
445e85e6aecSHong Zhang   Output Paramters:
446e85e6aecSHong Zhang . index - user global numbering for the vertex
447e85e6aecSHong Zhang 
448e85e6aecSHong Zhang   Level: intermediate
449e85e6aecSHong Zhang 
450e85e6aecSHong Zhang .seealso: DMNetworkGetGlobalEdgeIndex
451e85e6aecSHong Zhang @*/
452e85e6aecSHong Zhang PetscErrorCode DMNetworkGetGlobalVertexIndex(DM dm,PetscInt p,PetscInt *index)
453e85e6aecSHong Zhang {
454e85e6aecSHong Zhang   PetscErrorCode    ierr;
455e85e6aecSHong Zhang   DM_Network        *network = (DM_Network*)dm->data;
456e85e6aecSHong Zhang   PetscInt          offsetp;
457e85e6aecSHong Zhang   DMNetworkComponentHeader header;
458e85e6aecSHong Zhang 
459e85e6aecSHong Zhang   PetscFunctionBegin;
460e85e6aecSHong Zhang   ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr);
461e85e6aecSHong Zhang   header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp);
462e85e6aecSHong Zhang   *index = header->index;
463e85e6aecSHong Zhang   PetscFunctionReturn(0);
464e85e6aecSHong Zhang }
465e85e6aecSHong Zhang 
466c3b11c7cSShri Abhyankar /*
467c3b11c7cSShri Abhyankar   DMNetworkGetComponentKeyOffset - Gets the type along with the offset for indexing the
468c3b11c7cSShri Abhyankar                                     component value from the component data array
469c3b11c7cSShri Abhyankar 
470c3b11c7cSShri Abhyankar   Not Collective
471c3b11c7cSShri Abhyankar 
472c3b11c7cSShri Abhyankar   Input Parameters:
473c3b11c7cSShri Abhyankar + dm      - The DMNetwork object
474c3b11c7cSShri Abhyankar . p       - vertex/edge point
475c3b11c7cSShri Abhyankar - compnum - component number
476c3b11c7cSShri Abhyankar 
477c3b11c7cSShri Abhyankar   Output Parameters:
478c3b11c7cSShri Abhyankar + compkey - the key obtained when registering the component
479c3b11c7cSShri Abhyankar - offset  - offset into the component data array associated with the vertex/edge point
480c3b11c7cSShri Abhyankar 
481c3b11c7cSShri Abhyankar   Notes:
482c3b11c7cSShri Abhyankar   Typical usage:
483c3b11c7cSShri Abhyankar 
484c3b11c7cSShri Abhyankar   DMNetworkGetComponentDataArray(dm, &arr);
485c3b11c7cSShri Abhyankar   DMNetworkGetVertex/EdgeRange(dm,&Start,&End);
486c3b11c7cSShri Abhyankar   Loop over vertices or edges
487c3b11c7cSShri Abhyankar     DMNetworkGetNumComponents(dm,v,&numcomps);
488c3b11c7cSShri Abhyankar     Loop over numcomps
489c3b11c7cSShri Abhyankar       DMNetworkGetComponentKeyOffset(dm,v,compnum,&key,&offset);
490c3b11c7cSShri Abhyankar       compdata = (UserCompDataType)(arr+offset);
491c3b11c7cSShri Abhyankar 
492c3b11c7cSShri Abhyankar   Level: intermediate
493c3b11c7cSShri Abhyankar 
494c3b11c7cSShri Abhyankar .seealso: DMNetworkGetNumComponents, DMNetworkGetComponentDataArray,
495c3b11c7cSShri Abhyankar */
496c3b11c7cSShri Abhyankar PetscErrorCode DMNetworkGetComponentKeyOffset(DM dm,PetscInt p, PetscInt compnum, PetscInt *compkey, PetscInt *offset)
497c3b11c7cSShri Abhyankar {
498c3b11c7cSShri Abhyankar   PetscErrorCode           ierr;
499c3b11c7cSShri Abhyankar   PetscInt                 offsetp;
500c3b11c7cSShri Abhyankar   DMNetworkComponentHeader header;
501c3b11c7cSShri Abhyankar   DM_Network               *network = (DM_Network*)dm->data;
502c3b11c7cSShri Abhyankar 
503c3b11c7cSShri Abhyankar   PetscFunctionBegin;
504c3b11c7cSShri Abhyankar   ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr);
505c3b11c7cSShri Abhyankar   header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp);
506c3b11c7cSShri Abhyankar   if (compkey) *compkey = header->key[compnum];
507c3b11c7cSShri Abhyankar   if (offset) *offset  = offsetp+network->dataheadersize+header->offset[compnum];
508c3b11c7cSShri Abhyankar   PetscFunctionReturn(0);
509c3b11c7cSShri Abhyankar }
510c3b11c7cSShri Abhyankar 
511c3b11c7cSShri Abhyankar /*@
512c3b11c7cSShri Abhyankar   DMNetworkGetComponent - Returns the network component and its key
513c3b11c7cSShri Abhyankar 
514c3b11c7cSShri Abhyankar   Not Collective
515c3b11c7cSShri Abhyankar 
516c3b11c7cSShri Abhyankar   Input Parameters
517c3b11c7cSShri Abhyankar + dm - DMNetwork object
518c3b11c7cSShri Abhyankar . p  - edge or vertex point
519c3b11c7cSShri Abhyankar - compnum - component number
520c3b11c7cSShri Abhyankar 
521c3b11c7cSShri Abhyankar   Output Parameters:
522c3b11c7cSShri Abhyankar + compkey - the key set for this computing during registration
523c3b11c7cSShri Abhyankar - component - the component data
524c3b11c7cSShri Abhyankar 
525c3b11c7cSShri Abhyankar   Notes:
526c3b11c7cSShri Abhyankar   Typical usage:
527c3b11c7cSShri Abhyankar 
528c3b11c7cSShri Abhyankar   DMNetworkGetVertex/EdgeRange(dm,&Start,&End);
529c3b11c7cSShri Abhyankar   Loop over vertices or edges
530c3b11c7cSShri Abhyankar     DMNetworkGetNumComponents(dm,v,&numcomps);
531c3b11c7cSShri Abhyankar     Loop over numcomps
532c3b11c7cSShri Abhyankar       DMNetworkGetComponent(dm,v,compnum,&key,&component);
533c3b11c7cSShri Abhyankar 
534c3b11c7cSShri Abhyankar   Level: intermediate
535c3b11c7cSShri Abhyankar 
536c3b11c7cSShri Abhyankar .seealso: DMNetworkGetNumComponents, DMNetworkGetVariableOffset
537c3b11c7cSShri Abhyankar @*/
538c3b11c7cSShri Abhyankar PetscErrorCode DMNetworkGetComponent(DM dm, PetscInt p, PetscInt compnum, PetscInt *key, void **component)
539c3b11c7cSShri Abhyankar {
540c3b11c7cSShri Abhyankar   PetscErrorCode ierr;
541c3b11c7cSShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
542c3b11c7cSShri Abhyankar   PetscInt       offsetd;
543c3b11c7cSShri Abhyankar 
544c3b11c7cSShri Abhyankar   PetscFunctionBegin;
545c3b11c7cSShri Abhyankar 
546c3b11c7cSShri Abhyankar   ierr = DMNetworkGetComponentKeyOffset(dm,p,compnum,key,&offsetd);CHKERRQ(ierr);
547c3b11c7cSShri Abhyankar   *component = network->componentdataarray+offsetd;
548c3b11c7cSShri Abhyankar 
549c3b11c7cSShri Abhyankar   PetscFunctionReturn(0);
550c3b11c7cSShri Abhyankar }
551c3b11c7cSShri Abhyankar 
552e85e6aecSHong Zhang /*@
553325661f6SSatish Balay   DMNetworkAddComponent - Adds a network component at the given point (vertex/edge)
5545f2c45f1SShri Abhyankar 
5555f2c45f1SShri Abhyankar   Not Collective
5565f2c45f1SShri Abhyankar 
5575f2c45f1SShri Abhyankar   Input Parameters:
5585f2c45f1SShri Abhyankar + dm           - The DMNetwork object
5595f2c45f1SShri Abhyankar . p            - vertex/edge point
5605f2c45f1SShri Abhyankar . componentkey - component key returned while registering the component
5615f2c45f1SShri Abhyankar - compvalue    - pointer to the data structure for the component
5625f2c45f1SShri Abhyankar 
5635f2c45f1SShri Abhyankar   Level: intermediate
5645f2c45f1SShri Abhyankar 
5655f2c45f1SShri Abhyankar .seealso: DMNetworkGetVertexRange, DMNetworkGetEdgeRange, DMNetworkRegisterComponent
5665f2c45f1SShri Abhyankar @*/
5675f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddComponent(DM dm, PetscInt p,PetscInt componentkey,void* compvalue)
5685f2c45f1SShri Abhyankar {
5695f2c45f1SShri Abhyankar   DM_Network               *network = (DM_Network*)dm->data;
57043a39a44SBarry Smith   DMNetworkComponent       *component = &network->component[componentkey];
5715f2c45f1SShri Abhyankar   DMNetworkComponentHeader header = &network->header[p];
5725f2c45f1SShri Abhyankar   DMNetworkComponentValue  cvalue = &network->cvalue[p];
5735f2c45f1SShri Abhyankar   PetscErrorCode           ierr;
5745f2c45f1SShri Abhyankar 
5755f2c45f1SShri Abhyankar   PetscFunctionBegin;
576fa58f0a9SHong 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);
577fa58f0a9SHong Zhang 
57843a39a44SBarry Smith   header->size[header->ndata] = component->size;
57943a39a44SBarry Smith   ierr = PetscSectionAddDof(network->DataSection,p,component->size);CHKERRQ(ierr);
5805f2c45f1SShri Abhyankar   header->key[header->ndata] = componentkey;
5815f2c45f1SShri Abhyankar   if (header->ndata != 0) header->offset[header->ndata] = header->offset[header->ndata-1] + header->size[header->ndata-1];
5825f2c45f1SShri Abhyankar 
5835f2c45f1SShri Abhyankar   cvalue->data[header->ndata] = (void*)compvalue;
5845f2c45f1SShri Abhyankar   header->ndata++;
5855f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
5865f2c45f1SShri Abhyankar }
5875f2c45f1SShri Abhyankar 
5885f2c45f1SShri Abhyankar /*@
5895f2c45f1SShri Abhyankar   DMNetworkGetNumComponents - Get the number of components at a vertex/edge
5905f2c45f1SShri Abhyankar 
5915f2c45f1SShri Abhyankar   Not Collective
5925f2c45f1SShri Abhyankar 
5935f2c45f1SShri Abhyankar   Input Parameters:
5945f2c45f1SShri Abhyankar + dm - The DMNetwork object
5955f2c45f1SShri Abhyankar . p  - vertex/edge point
5965f2c45f1SShri Abhyankar 
5975f2c45f1SShri Abhyankar   Output Parameters:
5985f2c45f1SShri Abhyankar . numcomponents - Number of components at the vertex/edge
5995f2c45f1SShri Abhyankar 
6005f2c45f1SShri Abhyankar   Level: intermediate
6015f2c45f1SShri Abhyankar 
6025f2c45f1SShri Abhyankar .seealso: DMNetworkRegisterComponent, DMNetworkAddComponent
6035f2c45f1SShri Abhyankar @*/
6045f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetNumComponents(DM dm,PetscInt p,PetscInt *numcomponents)
6055f2c45f1SShri Abhyankar {
6065f2c45f1SShri Abhyankar   PetscErrorCode ierr;
6075f2c45f1SShri Abhyankar   PetscInt       offset;
6085f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
6095f2c45f1SShri Abhyankar 
6105f2c45f1SShri Abhyankar   PetscFunctionBegin;
6115f2c45f1SShri Abhyankar   ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr);
6125f2c45f1SShri Abhyankar   *numcomponents = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata;
6135f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
6145f2c45f1SShri Abhyankar }
6155f2c45f1SShri Abhyankar 
6165f2c45f1SShri Abhyankar /*@
6175f2c45f1SShri Abhyankar   DMNetworkGetVariableOffset - Get the offset for accessing the variable associated with the given vertex/edge from the local vector.
6185f2c45f1SShri Abhyankar 
6195f2c45f1SShri Abhyankar   Not Collective
6205f2c45f1SShri Abhyankar 
6215f2c45f1SShri Abhyankar   Input Parameters:
6225f2c45f1SShri Abhyankar + dm     - The DMNetwork object
6235f2c45f1SShri Abhyankar - p      - the edge/vertex point
6245f2c45f1SShri Abhyankar 
6255f2c45f1SShri Abhyankar   Output Parameters:
6265f2c45f1SShri Abhyankar . offset - the offset
6275f2c45f1SShri Abhyankar 
6285f2c45f1SShri Abhyankar   Level: intermediate
6295f2c45f1SShri Abhyankar 
6305f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector
6315f2c45f1SShri Abhyankar @*/
6325f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableOffset(DM dm,PetscInt p,PetscInt *offset)
6335f2c45f1SShri Abhyankar {
6345f2c45f1SShri Abhyankar   PetscErrorCode ierr;
6355f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
6365f2c45f1SShri Abhyankar 
6375f2c45f1SShri Abhyankar   PetscFunctionBegin;
6385f78ed8bSShri Abhyankar   ierr = PetscSectionGetOffset(network->plex->defaultSection,p,offset);CHKERRQ(ierr);
6395f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
6405f2c45f1SShri Abhyankar }
6415f2c45f1SShri Abhyankar 
6425f2c45f1SShri Abhyankar /*@
6435f2c45f1SShri Abhyankar   DMNetworkGetVariableGlobalOffset - Get the global offset for the variable associated with the given vertex/edge from the global vector.
6445f2c45f1SShri Abhyankar 
6455f2c45f1SShri Abhyankar   Not Collective
6465f2c45f1SShri Abhyankar 
6475f2c45f1SShri Abhyankar   Input Parameters:
6485f2c45f1SShri Abhyankar + dm      - The DMNetwork object
6495f2c45f1SShri Abhyankar - p       - the edge/vertex point
6505f2c45f1SShri Abhyankar 
6515f2c45f1SShri Abhyankar   Output Parameters:
6525f2c45f1SShri Abhyankar . offsetg - the offset
6535f2c45f1SShri Abhyankar 
6545f2c45f1SShri Abhyankar   Level: intermediate
6555f2c45f1SShri Abhyankar 
6565f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableOffset, DMGetLocalVector
6575f2c45f1SShri Abhyankar @*/
6585f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableGlobalOffset(DM dm,PetscInt p,PetscInt *offsetg)
6595f2c45f1SShri Abhyankar {
6605f2c45f1SShri Abhyankar   PetscErrorCode ierr;
6615f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
6625f2c45f1SShri Abhyankar 
6635f2c45f1SShri Abhyankar   PetscFunctionBegin;
6645f78ed8bSShri Abhyankar   ierr = PetscSectionGetOffset(network->plex->defaultGlobalSection,p,offsetg);CHKERRQ(ierr);
6656fefedf4SHong Zhang   if (*offsetg < 0) *offsetg = -(*offsetg + 1); /* Convert to actual global offset for ghost vertex */
6665f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
6675f2c45f1SShri Abhyankar }
6685f2c45f1SShri Abhyankar 
66924121865SAdrian Maldonado /*@
67024121865SAdrian Maldonado   DMNetworkGetEdgeOffset - Get the offset for accessing the variable associated with the given edge from the local subvector.
67124121865SAdrian Maldonado 
67224121865SAdrian Maldonado   Not Collective
67324121865SAdrian Maldonado 
67424121865SAdrian Maldonado   Input Parameters:
67524121865SAdrian Maldonado + dm     - The DMNetwork object
67624121865SAdrian Maldonado - p      - the edge point
67724121865SAdrian Maldonado 
67824121865SAdrian Maldonado   Output Parameters:
67924121865SAdrian Maldonado . offset - the offset
68024121865SAdrian Maldonado 
68124121865SAdrian Maldonado   Level: intermediate
68224121865SAdrian Maldonado 
68324121865SAdrian Maldonado .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector
68424121865SAdrian Maldonado @*/
68524121865SAdrian Maldonado PetscErrorCode DMNetworkGetEdgeOffset(DM dm,PetscInt p,PetscInt *offset)
68624121865SAdrian Maldonado {
68724121865SAdrian Maldonado   PetscErrorCode ierr;
68824121865SAdrian Maldonado   DM_Network     *network = (DM_Network*)dm->data;
68924121865SAdrian Maldonado 
69024121865SAdrian Maldonado   PetscFunctionBegin;
69124121865SAdrian Maldonado 
69224121865SAdrian Maldonado   ierr = PetscSectionGetOffset(network->edge.DofSection,p,offset);CHKERRQ(ierr);
69324121865SAdrian Maldonado   PetscFunctionReturn(0);
69424121865SAdrian Maldonado }
69524121865SAdrian Maldonado 
69624121865SAdrian Maldonado /*@
69724121865SAdrian Maldonado   DMNetworkGetVertexOffset - Get the offset for accessing the variable associated with the given vertex from the local subvector.
69824121865SAdrian Maldonado 
69924121865SAdrian Maldonado   Not Collective
70024121865SAdrian Maldonado 
70124121865SAdrian Maldonado   Input Parameters:
70224121865SAdrian Maldonado + dm     - The DMNetwork object
70324121865SAdrian Maldonado - p      - the vertex point
70424121865SAdrian Maldonado 
70524121865SAdrian Maldonado   Output Parameters:
70624121865SAdrian Maldonado . offset - the offset
70724121865SAdrian Maldonado 
70824121865SAdrian Maldonado   Level: intermediate
70924121865SAdrian Maldonado 
71024121865SAdrian Maldonado .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector
71124121865SAdrian Maldonado @*/
71224121865SAdrian Maldonado PetscErrorCode DMNetworkGetVertexOffset(DM dm,PetscInt p,PetscInt *offset)
71324121865SAdrian Maldonado {
71424121865SAdrian Maldonado   PetscErrorCode ierr;
71524121865SAdrian Maldonado   DM_Network     *network = (DM_Network*)dm->data;
71624121865SAdrian Maldonado 
71724121865SAdrian Maldonado   PetscFunctionBegin;
71824121865SAdrian Maldonado 
71924121865SAdrian Maldonado   p -= network->vStart;
72024121865SAdrian Maldonado 
72124121865SAdrian Maldonado   ierr = PetscSectionGetOffset(network->vertex.DofSection,p,offset);CHKERRQ(ierr);
72224121865SAdrian Maldonado   PetscFunctionReturn(0);
72324121865SAdrian Maldonado }
7245f2c45f1SShri Abhyankar /*@
7255f2c45f1SShri Abhyankar   DMNetworkAddNumVariables - Add number of variables associated with a given point.
7265f2c45f1SShri Abhyankar 
7275f2c45f1SShri Abhyankar   Not Collective
7285f2c45f1SShri Abhyankar 
7295f2c45f1SShri Abhyankar   Input Parameters:
7305f2c45f1SShri Abhyankar + dm   - The DMNetworkObject
7315f2c45f1SShri Abhyankar . p    - the vertex/edge point
7325f2c45f1SShri Abhyankar - nvar - number of additional variables
7335f2c45f1SShri Abhyankar 
7345f2c45f1SShri Abhyankar   Level: intermediate
7355f2c45f1SShri Abhyankar 
7365f2c45f1SShri Abhyankar .seealso: DMNetworkSetNumVariables
7375f2c45f1SShri Abhyankar @*/
7385f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddNumVariables(DM dm,PetscInt p,PetscInt nvar)
7395f2c45f1SShri Abhyankar {
7405f2c45f1SShri Abhyankar   PetscErrorCode ierr;
7415f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
7425f2c45f1SShri Abhyankar 
7435f2c45f1SShri Abhyankar   PetscFunctionBegin;
7445f2c45f1SShri Abhyankar   ierr = PetscSectionAddDof(network->DofSection,p,nvar);CHKERRQ(ierr);
7455f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
7465f2c45f1SShri Abhyankar }
7475f2c45f1SShri Abhyankar 
74827f51fceSHong Zhang /*@
74927f51fceSHong Zhang   DMNetworkGetNumVariables - Gets number of variables for a vertex/edge point.
75027f51fceSHong Zhang 
75127f51fceSHong Zhang   Not Collective
75227f51fceSHong Zhang 
75327f51fceSHong Zhang   Input Parameters:
75427f51fceSHong Zhang + dm   - The DMNetworkObject
75527f51fceSHong Zhang - p    - the vertex/edge point
75627f51fceSHong Zhang 
75727f51fceSHong Zhang   Output Parameters:
75827f51fceSHong Zhang . nvar - number of variables
75927f51fceSHong Zhang 
76027f51fceSHong Zhang   Level: intermediate
76127f51fceSHong Zhang 
76227f51fceSHong Zhang .seealso: DMNetworkAddNumVariables, DMNetworkSddNumVariables
76327f51fceSHong Zhang @*/
76427f51fceSHong Zhang PetscErrorCode DMNetworkGetNumVariables(DM dm,PetscInt p,PetscInt *nvar)
76527f51fceSHong Zhang {
76627f51fceSHong Zhang   PetscErrorCode ierr;
76727f51fceSHong Zhang   DM_Network     *network = (DM_Network*)dm->data;
76827f51fceSHong Zhang 
76927f51fceSHong Zhang   PetscFunctionBegin;
77027f51fceSHong Zhang   ierr = PetscSectionGetDof(network->DofSection,p,nvar);CHKERRQ(ierr);
77127f51fceSHong Zhang   PetscFunctionReturn(0);
77227f51fceSHong Zhang }
77327f51fceSHong Zhang 
7745f2c45f1SShri Abhyankar /*@
7755f2c45f1SShri Abhyankar   DMNetworkSetNumVariables - Sets number of variables for a vertex/edge point.
7765f2c45f1SShri Abhyankar 
7775f2c45f1SShri Abhyankar   Not Collective
7785f2c45f1SShri Abhyankar 
7795f2c45f1SShri Abhyankar   Input Parameters:
7805f2c45f1SShri Abhyankar + dm   - The DMNetworkObject
7815f2c45f1SShri Abhyankar . p    - the vertex/edge point
7825f2c45f1SShri Abhyankar - nvar - number of variables
7835f2c45f1SShri Abhyankar 
7845f2c45f1SShri Abhyankar   Level: intermediate
7855f2c45f1SShri Abhyankar 
7865f2c45f1SShri Abhyankar .seealso: DMNetworkAddNumVariables
7875f2c45f1SShri Abhyankar @*/
7885f2c45f1SShri Abhyankar PetscErrorCode DMNetworkSetNumVariables(DM dm,PetscInt p,PetscInt nvar)
7895f2c45f1SShri Abhyankar {
7905f2c45f1SShri Abhyankar   PetscErrorCode ierr;
7915f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
7925f2c45f1SShri Abhyankar 
7935f2c45f1SShri Abhyankar   PetscFunctionBegin;
7945f2c45f1SShri Abhyankar   ierr = PetscSectionSetDof(network->DofSection,p,nvar);CHKERRQ(ierr);
7955f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
7965f2c45f1SShri Abhyankar }
7975f2c45f1SShri Abhyankar 
7985f2c45f1SShri Abhyankar /* Sets up the array that holds the data for all components and its associated section. This
7995f2c45f1SShri Abhyankar    function is called during DMSetUp() */
8005f2c45f1SShri Abhyankar PetscErrorCode DMNetworkComponentSetUp(DM dm)
8015f2c45f1SShri Abhyankar {
8025f2c45f1SShri Abhyankar   PetscErrorCode           ierr;
8035f2c45f1SShri Abhyankar   DM_Network               *network = (DM_Network*)dm->data;
804*e53b5ba3SHong Zhang   PetscInt                 arr_size,p,offset,offsetp,ncomp,i;
8055f2c45f1SShri Abhyankar   DMNetworkComponentHeader header;
8065f2c45f1SShri Abhyankar   DMNetworkComponentValue  cvalue;
8075f2c45f1SShri Abhyankar   DMNetworkComponentGenericDataType *componentdataarray;
8085f2c45f1SShri Abhyankar 
8095f2c45f1SShri Abhyankar   PetscFunctionBegin;
8105f2c45f1SShri Abhyankar   ierr = PetscSectionSetUp(network->DataSection);CHKERRQ(ierr);
8115f2c45f1SShri Abhyankar   ierr = PetscSectionGetStorageSize(network->DataSection,&arr_size);CHKERRQ(ierr);
81275b160a0SShri Abhyankar   ierr = PetscMalloc1(arr_size,&network->componentdataarray);CHKERRQ(ierr);
8135f2c45f1SShri Abhyankar   componentdataarray = network->componentdataarray;
8145f2c45f1SShri Abhyankar   for (p = network->pStart; p < network->pEnd; p++) {
8155f2c45f1SShri Abhyankar     ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr);
8165f2c45f1SShri Abhyankar     /* Copy header */
8175f2c45f1SShri Abhyankar     header = &network->header[p];
818302440fdSBarry Smith     ierr = PetscMemcpy(componentdataarray+offsetp,header,network->dataheadersize*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr);
8195f2c45f1SShri Abhyankar     /* Copy data */
8205f2c45f1SShri Abhyankar     cvalue = &network->cvalue[p];
8215f2c45f1SShri Abhyankar     ncomp = header->ndata;
8225f2c45f1SShri Abhyankar     for (i = 0; i < ncomp; i++) {
8235f2c45f1SShri Abhyankar       offset = offsetp + network->dataheadersize + header->offset[i];
824302440fdSBarry Smith       ierr = PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr);
8255f2c45f1SShri Abhyankar     }
8265f2c45f1SShri Abhyankar   }
8275f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
8285f2c45f1SShri Abhyankar }
8295f2c45f1SShri Abhyankar 
8305f2c45f1SShri Abhyankar /* Sets up the section for dofs. This routine is called during DMSetUp() */
8315f2c45f1SShri Abhyankar PetscErrorCode DMNetworkVariablesSetUp(DM dm)
8325f2c45f1SShri Abhyankar {
8335f2c45f1SShri Abhyankar   PetscErrorCode ierr;
8345f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
8355f2c45f1SShri Abhyankar 
8365f2c45f1SShri Abhyankar   PetscFunctionBegin;
8375f2c45f1SShri Abhyankar   ierr = PetscSectionSetUp(network->DofSection);CHKERRQ(ierr);
8385f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
8395f2c45f1SShri Abhyankar }
8405f2c45f1SShri Abhyankar 
8415f2c45f1SShri Abhyankar /*@C
8425f2c45f1SShri Abhyankar   DMNetworkGetComponentDataArray - Returns the component data array
8435f2c45f1SShri Abhyankar 
8445f2c45f1SShri Abhyankar   Not Collective
8455f2c45f1SShri Abhyankar 
8465f2c45f1SShri Abhyankar   Input Parameters:
8475f2c45f1SShri Abhyankar . dm - The DMNetwork Object
8485f2c45f1SShri Abhyankar 
8495f2c45f1SShri Abhyankar   Output Parameters:
8505f2c45f1SShri Abhyankar . componentdataarray - array that holds data for all components
8515f2c45f1SShri Abhyankar 
8525f2c45f1SShri Abhyankar   Level: intermediate
8535f2c45f1SShri Abhyankar 
854a730d845SHong Zhang .seealso: DMNetworkGetComponentKeyOffset, DMNetworkGetNumComponents
8555f2c45f1SShri Abhyankar @*/
8565f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetComponentDataArray(DM dm,DMNetworkComponentGenericDataType **componentdataarray)
8575f2c45f1SShri Abhyankar {
8585f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
8595f2c45f1SShri Abhyankar 
8605f2c45f1SShri Abhyankar   PetscFunctionBegin;
8615f2c45f1SShri Abhyankar   *componentdataarray = network->componentdataarray;
8625f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
8635f2c45f1SShri Abhyankar }
8645f2c45f1SShri Abhyankar 
86524121865SAdrian Maldonado /* Get a subsection from a range of points */
86624121865SAdrian Maldonado PetscErrorCode DMNetworkGetSubSection_private(PetscSection master, PetscInt pstart, PetscInt pend,PetscSection *subsection)
86724121865SAdrian Maldonado {
86824121865SAdrian Maldonado   PetscErrorCode ierr;
86924121865SAdrian Maldonado   PetscInt       i, nvar;
87024121865SAdrian Maldonado 
87124121865SAdrian Maldonado   PetscFunctionBegin;
87224121865SAdrian Maldonado   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)master), subsection);CHKERRQ(ierr);
87324121865SAdrian Maldonado   ierr = PetscSectionSetChart(*subsection, 0, pend - pstart);CHKERRQ(ierr);
87424121865SAdrian Maldonado   for (i = pstart; i < pend; i++) {
87524121865SAdrian Maldonado     ierr = PetscSectionGetDof(master,i,&nvar);CHKERRQ(ierr);
87624121865SAdrian Maldonado     ierr = PetscSectionSetDof(*subsection, i - pstart, nvar);CHKERRQ(ierr);
87724121865SAdrian Maldonado   }
87824121865SAdrian Maldonado 
87924121865SAdrian Maldonado   ierr = PetscSectionSetUp(*subsection);CHKERRQ(ierr);
88024121865SAdrian Maldonado   PetscFunctionReturn(0);
88124121865SAdrian Maldonado }
88224121865SAdrian Maldonado 
88324121865SAdrian Maldonado /* Create a submap of points with a GlobalToLocal structure */
88424121865SAdrian Maldonado PetscErrorCode DMNetworkSetSubMap_private(PetscInt pstart, PetscInt pend, ISLocalToGlobalMapping *map)
88524121865SAdrian Maldonado {
88624121865SAdrian Maldonado   PetscErrorCode ierr;
88724121865SAdrian Maldonado   PetscInt       i, *subpoints;
88824121865SAdrian Maldonado 
88924121865SAdrian Maldonado   PetscFunctionBegin;
89024121865SAdrian Maldonado   /* Create index sets to map from "points" to "subpoints" */
89124121865SAdrian Maldonado   ierr = PetscMalloc1(pend - pstart, &subpoints);CHKERRQ(ierr);
89224121865SAdrian Maldonado   for (i = pstart; i < pend; i++) {
89324121865SAdrian Maldonado     subpoints[i - pstart] = i;
89424121865SAdrian Maldonado   }
895459726d8SSatish Balay   ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,pend-pstart,subpoints,PETSC_COPY_VALUES,map);CHKERRQ(ierr);
89624121865SAdrian Maldonado   ierr = PetscFree(subpoints);CHKERRQ(ierr);
89724121865SAdrian Maldonado   PetscFunctionReturn(0);
89824121865SAdrian Maldonado }
89924121865SAdrian Maldonado 
90024121865SAdrian Maldonado /*@
90124121865SAdrian Maldonado   DMNetworkAssembleGraphStructures - Assembles vertex and edge data structures. Must be called after DMNetworkDistribute.
90224121865SAdrian Maldonado 
90324121865SAdrian Maldonado   Collective
90424121865SAdrian Maldonado 
90524121865SAdrian Maldonado   Input Parameters:
90624121865SAdrian Maldonado . dm   - The DMNetworkObject
90724121865SAdrian Maldonado 
90824121865SAdrian Maldonado   Note: the routine will create alternative orderings for the vertices and edges. Assume global network points are:
90924121865SAdrian Maldonado 
91024121865SAdrian Maldonado   points = [0 1 2 3 4 5 6]
91124121865SAdrian Maldonado 
91224121865SAdrian Maldonado   where edges = [0, 3] and vertices = [4, 6]. The new orderings will be specific to the subset (i.e vertices = [0, 2]).
91324121865SAdrian Maldonado 
91424121865SAdrian Maldonado   With this new ordering a local PetscSection, global PetscSection and PetscSF will be created specific to the subset.
91524121865SAdrian Maldonado 
91624121865SAdrian Maldonado   Level: intermediate
91724121865SAdrian Maldonado 
91824121865SAdrian Maldonado @*/
91924121865SAdrian Maldonado PetscErrorCode DMNetworkAssembleGraphStructures(DM dm)
92024121865SAdrian Maldonado {
92124121865SAdrian Maldonado   PetscErrorCode ierr;
92224121865SAdrian Maldonado   MPI_Comm       comm;
9239852e123SBarry Smith   PetscMPIInt    rank, size;
92424121865SAdrian Maldonado   DM_Network     *network = (DM_Network*)dm->data;
92524121865SAdrian Maldonado 
926eab1376dSHong Zhang   PetscFunctionBegin;
92724121865SAdrian Maldonado   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
92824121865SAdrian Maldonado   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
9299852e123SBarry Smith   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
93024121865SAdrian Maldonado 
93124121865SAdrian Maldonado   /* Create maps for vertices and edges */
93224121865SAdrian Maldonado   ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr);
93324121865SAdrian Maldonado   ierr = DMNetworkSetSubMap_private(network->eStart,network->eEnd,&network->edge.mapping);CHKERRQ(ierr);
93424121865SAdrian Maldonado 
93524121865SAdrian Maldonado   /* Create local sub-sections */
93624121865SAdrian Maldonado   ierr = DMNetworkGetSubSection_private(network->DofSection,network->vStart,network->vEnd,&network->vertex.DofSection);CHKERRQ(ierr);
93724121865SAdrian Maldonado   ierr = DMNetworkGetSubSection_private(network->DofSection,network->eStart,network->eEnd,&network->edge.DofSection);CHKERRQ(ierr);
93824121865SAdrian Maldonado 
9399852e123SBarry Smith   if (size > 1) {
94024121865SAdrian Maldonado     ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr);
94124121865SAdrian Maldonado     ierr = PetscSectionCreateGlobalSection(network->vertex.DofSection, network->vertex.sf, PETSC_FALSE, PETSC_FALSE, &network->vertex.GlobalDofSection);CHKERRQ(ierr);
94224121865SAdrian Maldonado   ierr = PetscSFGetSubSF(network->plex->sf, network->edge.mapping, &network->edge.sf);CHKERRQ(ierr);
94324121865SAdrian Maldonado   ierr = PetscSectionCreateGlobalSection(network->edge.DofSection, network->edge.sf, PETSC_FALSE, PETSC_FALSE, &network->edge.GlobalDofSection);CHKERRQ(ierr);
94424121865SAdrian Maldonado   } else {
94524121865SAdrian Maldonado   /* create structures for vertex */
94624121865SAdrian Maldonado   ierr = PetscSectionClone(network->vertex.DofSection,&network->vertex.GlobalDofSection);CHKERRQ(ierr);
94724121865SAdrian Maldonado   /* create structures for edge */
94824121865SAdrian Maldonado   ierr = PetscSectionClone(network->edge.DofSection,&network->edge.GlobalDofSection);CHKERRQ(ierr);
94924121865SAdrian Maldonado   }
95024121865SAdrian Maldonado 
95124121865SAdrian Maldonado 
95224121865SAdrian Maldonado   /* Add viewers */
95324121865SAdrian Maldonado   ierr = PetscObjectSetName((PetscObject)network->edge.GlobalDofSection,"Global edge dof section");CHKERRQ(ierr);
95424121865SAdrian Maldonado   ierr = PetscObjectSetName((PetscObject)network->vertex.GlobalDofSection,"Global vertex dof section");CHKERRQ(ierr);
95524121865SAdrian Maldonado   ierr = PetscSectionViewFromOptions(network->edge.GlobalDofSection, NULL, "-edge_global_section_view");CHKERRQ(ierr);
95624121865SAdrian Maldonado   ierr = PetscSectionViewFromOptions(network->vertex.GlobalDofSection, NULL, "-vertex_global_section_view");CHKERRQ(ierr);
95724121865SAdrian Maldonado 
95824121865SAdrian Maldonado   PetscFunctionReturn(0);
95924121865SAdrian Maldonado }
9607b6afd5bSHong Zhang 
9615f2c45f1SShri Abhyankar /*@
9625f2c45f1SShri Abhyankar   DMNetworkDistribute - Distributes the network and moves associated component data.
9635f2c45f1SShri Abhyankar 
9645f2c45f1SShri Abhyankar   Collective
9655f2c45f1SShri Abhyankar 
9665f2c45f1SShri Abhyankar   Input Parameter:
967d3464fd4SAdrian Maldonado + DM - the DMNetwork object
9685f2c45f1SShri Abhyankar - overlap - The overlap of partitions, 0 is the default
9695f2c45f1SShri Abhyankar 
9705f2c45f1SShri Abhyankar   Notes:
9718b171c8eSHong Zhang   Distributes the network with <overlap>-overlapping partitioning of the edges.
9725f2c45f1SShri Abhyankar 
9735f2c45f1SShri Abhyankar   Level: intermediate
9745f2c45f1SShri Abhyankar 
9755f2c45f1SShri Abhyankar .seealso: DMNetworkCreate
9765f2c45f1SShri Abhyankar @*/
977d3464fd4SAdrian Maldonado PetscErrorCode DMNetworkDistribute(DM *dm,PetscInt overlap)
9785f2c45f1SShri Abhyankar {
979d3464fd4SAdrian Maldonado   MPI_Comm       comm;
9805f2c45f1SShri Abhyankar   PetscErrorCode ierr;
981d3464fd4SAdrian Maldonado   PetscMPIInt    size;
982d3464fd4SAdrian Maldonado   DM_Network     *oldDMnetwork = (DM_Network*)((*dm)->data);
983d3464fd4SAdrian Maldonado   DM_Network     *newDMnetwork;
9845f2c45f1SShri Abhyankar   PetscSF        pointsf;
9855f2c45f1SShri Abhyankar   DM             newDM;
98651ac5effSHong Zhang   PetscPartitioner part;
987b9c6e19dSShri Abhyankar   PetscInt         j,e,v,offset;
988b9c6e19dSShri Abhyankar   DMNetworkComponentHeader header;
9895f2c45f1SShri Abhyankar 
9905f2c45f1SShri Abhyankar   PetscFunctionBegin;
991d3464fd4SAdrian Maldonado 
992d3464fd4SAdrian Maldonado   ierr = PetscObjectGetComm((PetscObject)*dm,&comm);CHKERRQ(ierr);
993d3464fd4SAdrian Maldonado   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
994d3464fd4SAdrian Maldonado   if (size == 1) PetscFunctionReturn(0);
995d3464fd4SAdrian Maldonado 
996d3464fd4SAdrian Maldonado   ierr = DMNetworkCreate(PetscObjectComm((PetscObject)*dm),&newDM);CHKERRQ(ierr);
9975f2c45f1SShri Abhyankar   newDMnetwork = (DM_Network*)newDM->data;
9985f2c45f1SShri Abhyankar   newDMnetwork->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType);
99951ac5effSHong Zhang 
100051ac5effSHong Zhang   /* Enable runtime options for petscpartitioner */
100151ac5effSHong Zhang   ierr = DMPlexGetPartitioner(oldDMnetwork->plex,&part);CHKERRQ(ierr);
100251ac5effSHong Zhang   ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr);
100351ac5effSHong Zhang 
10045f2c45f1SShri Abhyankar   /* Distribute plex dm and dof section */
100580cf41d5SMatthew G. Knepley   ierr = DMPlexDistribute(oldDMnetwork->plex,overlap,&pointsf,&newDMnetwork->plex);CHKERRQ(ierr);
100651ac5effSHong Zhang 
10075f2c45f1SShri Abhyankar   /* Distribute dof section */
1008d3464fd4SAdrian Maldonado   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)*dm),&newDMnetwork->DofSection);CHKERRQ(ierr);
10095f2c45f1SShri Abhyankar   ierr = PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);CHKERRQ(ierr);
1010d3464fd4SAdrian Maldonado   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)*dm),&newDMnetwork->DataSection);CHKERRQ(ierr);
101151ac5effSHong Zhang 
10125f2c45f1SShri Abhyankar   /* Distribute data and associated section */
101331da1fc8SHong Zhang   ierr = DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPIU_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);CHKERRQ(ierr);
101424121865SAdrian Maldonado 
10155f2c45f1SShri Abhyankar   ierr = PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);CHKERRQ(ierr);
10165f2c45f1SShri Abhyankar   ierr = DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);CHKERRQ(ierr);
10175f2c45f1SShri Abhyankar   ierr = DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);CHKERRQ(ierr);
10185f2c45f1SShri Abhyankar   newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart;
10196fefedf4SHong Zhang   newDMnetwork->nVertices = newDMnetwork->vEnd - newDMnetwork->vStart;
10206fefedf4SHong Zhang   newDMnetwork->NVertices = oldDMnetwork->NVertices;
10215f2c45f1SShri Abhyankar   newDMnetwork->NEdges = oldDMnetwork->NEdges;
102224121865SAdrian Maldonado 
10235f2c45f1SShri Abhyankar   /* Set Dof section as the default section for dm */
10245f2c45f1SShri Abhyankar   ierr = DMSetDefaultSection(newDMnetwork->plex,newDMnetwork->DofSection);CHKERRQ(ierr);
10255f2c45f1SShri Abhyankar   ierr = DMGetDefaultGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);CHKERRQ(ierr);
10265f2c45f1SShri Abhyankar 
1027b9c6e19dSShri Abhyankar   /* Set up subnetwork info in the newDM */
1028b9c6e19dSShri Abhyankar   newDMnetwork->nsubnet = oldDMnetwork->nsubnet;
1029b9c6e19dSShri Abhyankar   ierr = PetscCalloc1(newDMnetwork->nsubnet,&newDMnetwork->subnet);CHKERRQ(ierr);
1030b9c6e19dSShri Abhyankar   /* Copy over the global number of vertices and edges in each subnetwork. Note that these are already
1031b9c6e19dSShri Abhyankar      calculated in DMNetworkLayoutSetUp()
1032b9c6e19dSShri Abhyankar   */
1033b9c6e19dSShri Abhyankar   for(j=0; j < newDMnetwork->nsubnet; j++) {
1034b9c6e19dSShri Abhyankar     newDMnetwork->subnet[j].Nvtx = oldDMnetwork->subnet[j].Nvtx;
1035b9c6e19dSShri Abhyankar     newDMnetwork->subnet[j].Nedge = oldDMnetwork->subnet[j].Nedge;
1036b9c6e19dSShri Abhyankar   }
1037b9c6e19dSShri Abhyankar 
1038b9c6e19dSShri Abhyankar   for(e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++ ) {
1039b9c6e19dSShri Abhyankar     ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr);
1040b9c6e19dSShri Abhyankar     header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr);
1041b9c6e19dSShri Abhyankar     newDMnetwork->subnet[header->subnetid].nedge++;
1042b9c6e19dSShri Abhyankar   }
1043b9c6e19dSShri Abhyankar 
1044b9c6e19dSShri Abhyankar   for(v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++ ) {
1045b9c6e19dSShri Abhyankar     ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr);
1046b9c6e19dSShri Abhyankar     header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr);
1047b9c6e19dSShri Abhyankar     newDMnetwork->subnet[header->subnetid].nvtx++;
1048b9c6e19dSShri Abhyankar   }
1049b9c6e19dSShri Abhyankar 
1050b9c6e19dSShri Abhyankar   /* Now create the vertices and edge arrays for the subnetworks */
1051b9c6e19dSShri Abhyankar   for(j=0; j < newDMnetwork->nsubnet; j++) {
1052b9c6e19dSShri Abhyankar     ierr = PetscCalloc1(newDMnetwork->subnet[j].nedge,&newDMnetwork->subnet[j].edges);CHKERRQ(ierr);
1053b9c6e19dSShri Abhyankar     ierr = PetscCalloc1(newDMnetwork->subnet[j].nvtx,&newDMnetwork->subnet[j].vertices);CHKERRQ(ierr);
1054b9c6e19dSShri Abhyankar     /* Temporarily setting nvtx and nedge to 0 so we can use them as counters in the below for loop.
1055b9c6e19dSShri Abhyankar        These get updated when the vertices and edges are added. */
1056b9c6e19dSShri Abhyankar     newDMnetwork->subnet[j].nvtx = newDMnetwork->subnet[j].nedge = 0;
1057b9c6e19dSShri Abhyankar   }
1058b9c6e19dSShri Abhyankar 
1059b9c6e19dSShri Abhyankar   /* Set the vertices and edges in each subnetwork */
1060b9c6e19dSShri Abhyankar   for(e = newDMnetwork->eStart; e < newDMnetwork->eEnd; e++ ) {
1061b9c6e19dSShri Abhyankar     ierr = PetscSectionGetOffset(newDMnetwork->DataSection,e,&offset);CHKERRQ(ierr);
1062b9c6e19dSShri Abhyankar     header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr);
1063b9c6e19dSShri Abhyankar     newDMnetwork->subnet[header->subnetid].edges[newDMnetwork->subnet[header->subnetid].nedge++]  = e;
1064b9c6e19dSShri Abhyankar   }
1065b9c6e19dSShri Abhyankar 
1066b9c6e19dSShri Abhyankar   for(v = newDMnetwork->vStart; v < newDMnetwork->vEnd; v++ ) {
1067b9c6e19dSShri Abhyankar     ierr = PetscSectionGetOffset(newDMnetwork->DataSection,v,&offset);CHKERRQ(ierr);
1068b9c6e19dSShri Abhyankar     header = (DMNetworkComponentHeader)(newDMnetwork->componentdataarray+offset);CHKERRQ(ierr);
1069b9c6e19dSShri Abhyankar     newDMnetwork->subnet[header->subnetid].vertices[newDMnetwork->subnet[header->subnetid].nvtx++]  = v;
1070b9c6e19dSShri Abhyankar   }
1071b9c6e19dSShri Abhyankar 
107224121865SAdrian Maldonado   /* Destroy point SF */
107324121865SAdrian Maldonado   ierr = PetscSFDestroy(&pointsf);CHKERRQ(ierr);
107424121865SAdrian Maldonado 
1075d3464fd4SAdrian Maldonado   ierr = DMDestroy(dm);CHKERRQ(ierr);
1076d3464fd4SAdrian Maldonado   *dm  = newDM;
10775f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
10785f2c45f1SShri Abhyankar }
10795f2c45f1SShri Abhyankar 
108024121865SAdrian Maldonado /*@C
108124121865SAdrian Maldonado   PetscSFGetSubSF - Returns an SF for a specific subset of points. Leaves are re-numbered to reflect the new ordering.
108224121865SAdrian Maldonado 
108324121865SAdrian Maldonado   Input Parameters:
108424121865SAdrian Maldonado + masterSF - the original SF structure
108524121865SAdrian Maldonado - map      - a ISLocalToGlobal mapping that contains the subset of points
108624121865SAdrian Maldonado 
108724121865SAdrian Maldonado   Output Parameters:
108824121865SAdrian Maldonado . subSF    - a subset of the masterSF for the desired subset.
108924121865SAdrian Maldonado */
109024121865SAdrian Maldonado 
109124121865SAdrian Maldonado PetscErrorCode PetscSFGetSubSF(PetscSF mastersf, ISLocalToGlobalMapping map, PetscSF *subSF) {
109224121865SAdrian Maldonado 
109324121865SAdrian Maldonado   PetscErrorCode        ierr;
109424121865SAdrian Maldonado   PetscInt              nroots, nleaves, *ilocal_sub;
109524121865SAdrian Maldonado   PetscInt              i, *ilocal_map, nroots_sub, nleaves_sub = 0;
109624121865SAdrian Maldonado   PetscInt              *local_points, *remote_points;
109724121865SAdrian Maldonado   PetscSFNode           *iremote_sub;
109824121865SAdrian Maldonado   const PetscInt        *ilocal;
109924121865SAdrian Maldonado   const PetscSFNode     *iremote;
110024121865SAdrian Maldonado 
110124121865SAdrian Maldonado   PetscFunctionBegin;
110224121865SAdrian Maldonado   ierr = PetscSFGetGraph(mastersf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr);
110324121865SAdrian Maldonado 
110424121865SAdrian Maldonado   /* Look for leaves that pertain to the subset of points. Get the local ordering */
110524121865SAdrian Maldonado   ierr = PetscMalloc1(nleaves,&ilocal_map);CHKERRQ(ierr);
110624121865SAdrian Maldonado   ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nleaves,ilocal,NULL,ilocal_map);CHKERRQ(ierr);
110724121865SAdrian Maldonado   for (i = 0; i < nleaves; i++) {
110824121865SAdrian Maldonado     if (ilocal_map[i] != -1) nleaves_sub += 1;
110924121865SAdrian Maldonado   }
111024121865SAdrian Maldonado   /* Re-number ilocal with subset numbering. Need information from roots */
111124121865SAdrian Maldonado   ierr = PetscMalloc2(nroots,&local_points,nroots,&remote_points);CHKERRQ(ierr);
111224121865SAdrian Maldonado   for (i = 0; i < nroots; i++) local_points[i] = i;
111324121865SAdrian Maldonado   ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nroots,local_points,NULL,local_points);CHKERRQ(ierr);
111424121865SAdrian Maldonado   ierr = PetscSFBcastBegin(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr);
111524121865SAdrian Maldonado   ierr = PetscSFBcastEnd(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr);
111624121865SAdrian Maldonado   /* Fill up graph using local (that is, local to the subset) numbering. */
11174b70a8deSAdrian Maldonado   ierr = PetscMalloc1(nleaves_sub,&ilocal_sub);CHKERRQ(ierr);
11184b70a8deSAdrian Maldonado   ierr = PetscMalloc1(nleaves_sub,&iremote_sub);CHKERRQ(ierr);
111924121865SAdrian Maldonado   nleaves_sub = 0;
112024121865SAdrian Maldonado   for (i = 0; i < nleaves; i++) {
112124121865SAdrian Maldonado     if (ilocal_map[i] != -1) {
112224121865SAdrian Maldonado       ilocal_sub[nleaves_sub] = ilocal_map[i];
11234b70a8deSAdrian Maldonado       iremote_sub[nleaves_sub].rank = iremote[i].rank;
112424121865SAdrian Maldonado       iremote_sub[nleaves_sub].index = remote_points[ilocal[i]];
112524121865SAdrian Maldonado       nleaves_sub += 1;
112624121865SAdrian Maldonado     }
112724121865SAdrian Maldonado   }
112824121865SAdrian Maldonado   ierr = PetscFree2(local_points,remote_points);CHKERRQ(ierr);
112924121865SAdrian Maldonado   ierr = ISLocalToGlobalMappingGetSize(map,&nroots_sub);CHKERRQ(ierr);
113024121865SAdrian Maldonado 
113124121865SAdrian Maldonado   /* Create new subSF */
113224121865SAdrian Maldonado   ierr = PetscSFCreate(PETSC_COMM_WORLD,subSF);CHKERRQ(ierr);
113324121865SAdrian Maldonado   ierr = PetscSFSetFromOptions(*subSF);CHKERRQ(ierr);
11344b70a8deSAdrian Maldonado   ierr = PetscSFSetGraph(*subSF,nroots_sub,nleaves_sub,ilocal_sub,PETSC_OWN_POINTER,iremote_sub,PETSC_COPY_VALUES);CHKERRQ(ierr);
113524121865SAdrian Maldonado   ierr = PetscFree(ilocal_map);CHKERRQ(ierr);
11364b70a8deSAdrian Maldonado   ierr = PetscFree(iremote_sub);CHKERRQ(ierr);
113724121865SAdrian Maldonado   PetscFunctionReturn(0);
113824121865SAdrian Maldonado }
113924121865SAdrian Maldonado 
11405f2c45f1SShri Abhyankar /*@C
11415f2c45f1SShri Abhyankar   DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point
11425f2c45f1SShri Abhyankar 
11435f2c45f1SShri Abhyankar   Not Collective
11445f2c45f1SShri Abhyankar 
11455f2c45f1SShri Abhyankar   Input Parameters:
11465f2c45f1SShri Abhyankar + dm - The DMNetwork object
11475f2c45f1SShri Abhyankar - p  - the vertex point
11485f2c45f1SShri Abhyankar 
11495f2c45f1SShri Abhyankar   Output Paramters:
11505f2c45f1SShri Abhyankar + nedges - number of edges connected to this vertex point
11515f2c45f1SShri Abhyankar - edges  - List of edge points
11525f2c45f1SShri Abhyankar 
11535f2c45f1SShri Abhyankar   Level: intermediate
11545f2c45f1SShri Abhyankar 
11555f2c45f1SShri Abhyankar   Fortran Notes:
11565f2c45f1SShri Abhyankar   Since it returns an array, this routine is only available in Fortran 90, and you must
11575f2c45f1SShri Abhyankar   include petsc.h90 in your code.
11585f2c45f1SShri Abhyankar 
1159d842c372SHong Zhang .seealso: DMNetworkCreate, DMNetworkGetConnectedVertices
11605f2c45f1SShri Abhyankar @*/
11615f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[])
11625f2c45f1SShri Abhyankar {
11635f2c45f1SShri Abhyankar   PetscErrorCode ierr;
11645f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
11655f2c45f1SShri Abhyankar 
11665f2c45f1SShri Abhyankar   PetscFunctionBegin;
11675f2c45f1SShri Abhyankar   ierr = DMPlexGetSupportSize(network->plex,vertex,nedges);CHKERRQ(ierr);
11685f2c45f1SShri Abhyankar   ierr = DMPlexGetSupport(network->plex,vertex,edges);CHKERRQ(ierr);
11695f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
11705f2c45f1SShri Abhyankar }
11715f2c45f1SShri Abhyankar 
11725f2c45f1SShri Abhyankar /*@C
1173d842c372SHong Zhang   DMNetworkGetConnectedVertices - Return the connected vertices for this edge point
11745f2c45f1SShri Abhyankar 
11755f2c45f1SShri Abhyankar   Not Collective
11765f2c45f1SShri Abhyankar 
11775f2c45f1SShri Abhyankar   Input Parameters:
11785f2c45f1SShri Abhyankar + dm - The DMNetwork object
11795f2c45f1SShri Abhyankar - p  - the edge point
11805f2c45f1SShri Abhyankar 
11815f2c45f1SShri Abhyankar   Output Paramters:
11825f2c45f1SShri Abhyankar . vertices  - vertices connected to this edge
11835f2c45f1SShri Abhyankar 
11845f2c45f1SShri Abhyankar   Level: intermediate
11855f2c45f1SShri Abhyankar 
11865f2c45f1SShri Abhyankar   Fortran Notes:
11875f2c45f1SShri Abhyankar   Since it returns an array, this routine is only available in Fortran 90, and you must
11885f2c45f1SShri Abhyankar   include petsc.h90 in your code.
11895f2c45f1SShri Abhyankar 
11905f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkGetSupportingEdges
11915f2c45f1SShri Abhyankar @*/
1192d842c372SHong Zhang PetscErrorCode DMNetworkGetConnectedVertices(DM dm,PetscInt edge,const PetscInt *vertices[])
11935f2c45f1SShri Abhyankar {
11945f2c45f1SShri Abhyankar   PetscErrorCode ierr;
11955f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
11965f2c45f1SShri Abhyankar 
11975f2c45f1SShri Abhyankar   PetscFunctionBegin;
11985f2c45f1SShri Abhyankar   ierr = DMPlexGetCone(network->plex,edge,vertices);CHKERRQ(ierr);
11995f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
12005f2c45f1SShri Abhyankar }
12015f2c45f1SShri Abhyankar 
12025f2c45f1SShri Abhyankar /*@
12035f2c45f1SShri Abhyankar   DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex
12045f2c45f1SShri Abhyankar 
12055f2c45f1SShri Abhyankar   Not Collective
12065f2c45f1SShri Abhyankar 
12075f2c45f1SShri Abhyankar   Input Parameters:
12085f2c45f1SShri Abhyankar + dm - The DMNetwork object
12095f2c45f1SShri Abhyankar . p  - the vertex point
12105f2c45f1SShri Abhyankar 
12115f2c45f1SShri Abhyankar   Output Parameter:
12125f2c45f1SShri Abhyankar . isghost - TRUE if the vertex is a ghost point
12135f2c45f1SShri Abhyankar 
12145f2c45f1SShri Abhyankar   Level: intermediate
12155f2c45f1SShri Abhyankar 
1216d842c372SHong Zhang .seealso: DMNetworkCreate, DMNetworkGetConnectedVertices, DMNetworkGetVertexRange
12175f2c45f1SShri Abhyankar @*/
12185f2c45f1SShri Abhyankar PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost)
12195f2c45f1SShri Abhyankar {
12205f2c45f1SShri Abhyankar   PetscErrorCode ierr;
12215f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
12225f2c45f1SShri Abhyankar   PetscInt       offsetg;
12235f2c45f1SShri Abhyankar   PetscSection   sectiong;
12245f2c45f1SShri Abhyankar 
12255f2c45f1SShri Abhyankar   PetscFunctionBegin;
12265f2c45f1SShri Abhyankar   *isghost = PETSC_FALSE;
12275f2c45f1SShri Abhyankar   ierr = DMGetDefaultGlobalSection(network->plex,&sectiong);CHKERRQ(ierr);
12285f2c45f1SShri Abhyankar   ierr = PetscSectionGetOffset(sectiong,p,&offsetg);CHKERRQ(ierr);
12295f2c45f1SShri Abhyankar   if (offsetg < 0) *isghost = PETSC_TRUE;
12305f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
12315f2c45f1SShri Abhyankar }
12325f2c45f1SShri Abhyankar 
12335f2c45f1SShri Abhyankar PetscErrorCode DMSetUp_Network(DM dm)
12345f2c45f1SShri Abhyankar {
12355f2c45f1SShri Abhyankar   PetscErrorCode ierr;
12365f2c45f1SShri Abhyankar   DM_Network     *network=(DM_Network*)dm->data;
12375f2c45f1SShri Abhyankar 
12385f2c45f1SShri Abhyankar   PetscFunctionBegin;
12395f2c45f1SShri Abhyankar   ierr = DMNetworkComponentSetUp(dm);CHKERRQ(ierr);
12405f2c45f1SShri Abhyankar   ierr = DMNetworkVariablesSetUp(dm);CHKERRQ(ierr);
12415f2c45f1SShri Abhyankar 
12425f2c45f1SShri Abhyankar   ierr = DMSetDefaultSection(network->plex,network->DofSection);CHKERRQ(ierr);
12435f2c45f1SShri Abhyankar   ierr = DMGetDefaultGlobalSection(network->plex,&network->GlobalDofSection);CHKERRQ(ierr);
12445f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
12455f2c45f1SShri Abhyankar }
12465f2c45f1SShri Abhyankar 
12471ad426b7SHong Zhang /*@
124817df6e9eSHong Zhang     DMNetworkHasJacobian - Sets global flag for using user's sub Jacobian matrices
12491ad426b7SHong Zhang                             -- replaced by DMNetworkSetOption(network,userjacobian,PETSC_TURE)?
12501ad426b7SHong Zhang 
12511ad426b7SHong Zhang     Collective
12521ad426b7SHong Zhang 
12531ad426b7SHong Zhang     Input Parameters:
125483b2e829SHong Zhang +   dm - The DMNetwork object
125583b2e829SHong Zhang .   eflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for edges
125683b2e829SHong Zhang -   vflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for vertices
12571ad426b7SHong Zhang 
12581ad426b7SHong Zhang     Level: intermediate
12591ad426b7SHong Zhang 
12601ad426b7SHong Zhang @*/
126183b2e829SHong Zhang PetscErrorCode DMNetworkHasJacobian(DM dm,PetscBool eflg,PetscBool vflg)
12621ad426b7SHong Zhang {
12631ad426b7SHong Zhang   DM_Network     *network=(DM_Network*)dm->data;
12648675203cSHong Zhang   PetscErrorCode ierr;
12651ad426b7SHong Zhang 
12661ad426b7SHong Zhang   PetscFunctionBegin;
126783b2e829SHong Zhang   network->userEdgeJacobian   = eflg;
126883b2e829SHong Zhang   network->userVertexJacobian = vflg;
12698675203cSHong Zhang 
12708675203cSHong Zhang   if (eflg && !network->Je) {
12718675203cSHong Zhang     ierr = PetscCalloc1(3*network->nEdges,&network->Je);CHKERRQ(ierr);
12728675203cSHong Zhang   }
12738675203cSHong Zhang 
12748675203cSHong Zhang   if (vflg && !network->Jv) {
12758675203cSHong Zhang     PetscInt       i,*vptr,nedges,vStart=network->vStart;
12768675203cSHong Zhang     PetscInt       nVertices = network->nVertices,nedges_total;
12778675203cSHong Zhang     const PetscInt *edges;
12788675203cSHong Zhang 
12798675203cSHong Zhang     /* count nvertex_total */
12808675203cSHong Zhang     nedges_total = 0;
12818675203cSHong Zhang     ierr = PetscMalloc1(nVertices+1,&vptr);CHKERRQ(ierr);
12828675203cSHong Zhang 
12838675203cSHong Zhang     vptr[0] = 0;
12848675203cSHong Zhang     for (i=0; i<nVertices; i++) {
12858675203cSHong Zhang       ierr = DMNetworkGetSupportingEdges(dm,i+vStart,&nedges,&edges);CHKERRQ(ierr);
12868675203cSHong Zhang       nedges_total += nedges;
12878675203cSHong Zhang       vptr[i+1] = vptr[i] + 2*nedges + 1;
12888675203cSHong Zhang     }
12898675203cSHong Zhang 
12908675203cSHong Zhang     ierr = PetscCalloc1(2*nedges_total+nVertices,&network->Jv);CHKERRQ(ierr);
12918675203cSHong Zhang     network->Jvptr = vptr;
12928675203cSHong Zhang   }
12931ad426b7SHong Zhang   PetscFunctionReturn(0);
12941ad426b7SHong Zhang }
12951ad426b7SHong Zhang 
12961ad426b7SHong Zhang /*@
129783b2e829SHong Zhang     DMNetworkEdgeSetMatrix - Sets user-provided Jacobian matrices for this edge to the network
129883b2e829SHong Zhang 
129983b2e829SHong Zhang     Not Collective
130083b2e829SHong Zhang 
130183b2e829SHong Zhang     Input Parameters:
130283b2e829SHong Zhang +   dm - The DMNetwork object
130383b2e829SHong Zhang .   p  - the edge point
13043e97b6e8SHong Zhang -   J - array (size = 3) of Jacobian submatrices for this edge point:
13053e97b6e8SHong Zhang         J[0]: this edge
1306d842c372SHong Zhang         J[1] and J[2]: connected vertices, obtained by calling DMNetworkGetConnectedVertices()
130783b2e829SHong Zhang 
130883b2e829SHong Zhang     Level: intermediate
130983b2e829SHong Zhang 
131083b2e829SHong Zhang .seealso: DMNetworkVertexSetMatrix
131183b2e829SHong Zhang @*/
131283b2e829SHong Zhang PetscErrorCode DMNetworkEdgeSetMatrix(DM dm,PetscInt p,Mat J[])
131383b2e829SHong Zhang {
131483b2e829SHong Zhang   DM_Network     *network=(DM_Network*)dm->data;
131583b2e829SHong Zhang 
131683b2e829SHong Zhang   PetscFunctionBegin;
13178675203cSHong Zhang   if (!network->Je) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkEdgeSetMatrix");
13188675203cSHong Zhang 
13198675203cSHong Zhang   if (J) {
1320883e35e8SHong Zhang     network->Je[3*p]   = J[0];
1321883e35e8SHong Zhang     network->Je[3*p+1] = J[1];
1322883e35e8SHong Zhang     network->Je[3*p+2] = J[2];
13238675203cSHong Zhang   }
132483b2e829SHong Zhang   PetscFunctionReturn(0);
132583b2e829SHong Zhang }
132683b2e829SHong Zhang 
132783b2e829SHong Zhang /*@
132876ddfea5SHong Zhang     DMNetworkVertexSetMatrix - Sets user-provided Jacobian matrix for this vertex to the network
13291ad426b7SHong Zhang 
13301ad426b7SHong Zhang     Not Collective
13311ad426b7SHong Zhang 
13321ad426b7SHong Zhang     Input Parameters:
13331ad426b7SHong Zhang +   dm - The DMNetwork object
13341ad426b7SHong Zhang .   p  - the vertex point
13353e97b6e8SHong Zhang -   J - array of Jacobian (size = 2*(num of supporting edges) + 1) submatrices for this vertex point:
13363e97b6e8SHong Zhang         J[0]:       this vertex
13373e97b6e8SHong Zhang         J[1+2*i]:   i-th supporting edge
13383e97b6e8SHong Zhang         J[1+2*i+1]: i-th connected vertex
13391ad426b7SHong Zhang 
13401ad426b7SHong Zhang     Level: intermediate
13411ad426b7SHong Zhang 
134283b2e829SHong Zhang .seealso: DMNetworkEdgeSetMatrix
13431ad426b7SHong Zhang @*/
1344883e35e8SHong Zhang PetscErrorCode DMNetworkVertexSetMatrix(DM dm,PetscInt p,Mat J[])
13455f2c45f1SShri Abhyankar {
13465f2c45f1SShri Abhyankar   PetscErrorCode ierr;
13475f2c45f1SShri Abhyankar   DM_Network     *network=(DM_Network*)dm->data;
13488675203cSHong Zhang   PetscInt       i,*vptr,nedges,vStart=network->vStart;
1349883e35e8SHong Zhang   const PetscInt *edges;
13505f2c45f1SShri Abhyankar 
13515f2c45f1SShri Abhyankar   PetscFunctionBegin;
13528675203cSHong Zhang   if (!network->Jv) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkVertexSetMatrix");
1353883e35e8SHong Zhang 
13548675203cSHong Zhang   if (J) {
1355883e35e8SHong Zhang     vptr = network->Jvptr;
13563e97b6e8SHong Zhang     network->Jv[vptr[p-vStart]] = J[0]; /* Set Jacobian for this vertex */
13573e97b6e8SHong Zhang 
13583e97b6e8SHong Zhang     /* Set Jacobian for each supporting edge and connected vertex */
1359883e35e8SHong Zhang     ierr = DMNetworkGetSupportingEdges(dm,p,&nedges,&edges);CHKERRQ(ierr);
1360883e35e8SHong Zhang     for (i=1; i<=2*nedges; i++) network->Jv[vptr[p-vStart]+i] = J[i];
13618675203cSHong Zhang   }
1362883e35e8SHong Zhang   PetscFunctionReturn(0);
1363883e35e8SHong Zhang }
1364883e35e8SHong Zhang 
1365e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz)
13665cf7da58SHong Zhang {
13675cf7da58SHong Zhang   PetscErrorCode ierr;
13685cf7da58SHong Zhang   PetscInt       j;
13695cf7da58SHong Zhang   PetscScalar    val=(PetscScalar)ncols;
13705cf7da58SHong Zhang 
13715cf7da58SHong Zhang   PetscFunctionBegin;
13725cf7da58SHong Zhang   if (!ghost) {
13735cf7da58SHong Zhang     for (j=0; j<nrows; j++) {
13745cf7da58SHong Zhang       ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr);
13755cf7da58SHong Zhang     }
13765cf7da58SHong Zhang   } else {
13775cf7da58SHong Zhang     for (j=0; j<nrows; j++) {
13785cf7da58SHong Zhang       ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr);
13795cf7da58SHong Zhang     }
13805cf7da58SHong Zhang   }
13815cf7da58SHong Zhang   PetscFunctionReturn(0);
13825cf7da58SHong Zhang }
13835cf7da58SHong Zhang 
1384e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz)
13855cf7da58SHong Zhang {
13865cf7da58SHong Zhang   PetscErrorCode ierr;
13875cf7da58SHong Zhang   PetscInt       j,ncols_u;
13885cf7da58SHong Zhang   PetscScalar    val;
13895cf7da58SHong Zhang 
13905cf7da58SHong Zhang   PetscFunctionBegin;
13915cf7da58SHong Zhang   if (!ghost) {
13925cf7da58SHong Zhang     for (j=0; j<nrows; j++) {
13935cf7da58SHong Zhang       ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr);
13945cf7da58SHong Zhang       val = (PetscScalar)ncols_u;
13955cf7da58SHong Zhang       ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr);
13965cf7da58SHong Zhang       ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr);
13975cf7da58SHong Zhang     }
13985cf7da58SHong Zhang   } else {
13995cf7da58SHong Zhang     for (j=0; j<nrows; j++) {
14005cf7da58SHong Zhang       ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr);
14015cf7da58SHong Zhang       val = (PetscScalar)ncols_u;
14025cf7da58SHong Zhang       ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr);
14035cf7da58SHong Zhang       ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr);
14045cf7da58SHong Zhang     }
14055cf7da58SHong Zhang   }
14065cf7da58SHong Zhang   PetscFunctionReturn(0);
14075cf7da58SHong Zhang }
14085cf7da58SHong Zhang 
1409e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz)
14105cf7da58SHong Zhang {
14115cf7da58SHong Zhang   PetscErrorCode ierr;
14125cf7da58SHong Zhang 
14135cf7da58SHong Zhang   PetscFunctionBegin;
14145cf7da58SHong Zhang   if (Ju) {
14155cf7da58SHong Zhang     ierr = MatSetPreallocationUserblock_private(Ju,nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr);
14165cf7da58SHong Zhang   } else {
14175cf7da58SHong Zhang     ierr = MatSetPreallocationDenseblock_private(nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr);
14185cf7da58SHong Zhang   }
14195cf7da58SHong Zhang   PetscFunctionReturn(0);
14205cf7da58SHong Zhang }
14215cf7da58SHong Zhang 
1422e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J)
1423883e35e8SHong Zhang {
1424883e35e8SHong Zhang   PetscErrorCode ierr;
1425883e35e8SHong Zhang   PetscInt       j,*cols;
1426883e35e8SHong Zhang   PetscScalar    *zeros;
1427883e35e8SHong Zhang 
1428883e35e8SHong Zhang   PetscFunctionBegin;
1429883e35e8SHong Zhang   ierr = PetscCalloc2(ncols,&cols,nrows*ncols,&zeros);CHKERRQ(ierr);
1430883e35e8SHong Zhang   for (j=0; j<ncols; j++) cols[j] = j+ cstart;
1431883e35e8SHong Zhang   ierr = MatSetValues(*J,nrows,rows,ncols,cols,zeros,INSERT_VALUES);CHKERRQ(ierr);
1432883e35e8SHong Zhang   ierr = PetscFree2(cols,zeros);CHKERRQ(ierr);
14331ad426b7SHong Zhang   PetscFunctionReturn(0);
14341ad426b7SHong Zhang }
1435a4e85ca8SHong Zhang 
1436e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J)
14373e97b6e8SHong Zhang {
14383e97b6e8SHong Zhang   PetscErrorCode ierr;
14393e97b6e8SHong Zhang   PetscInt       j,M,N,row,col,ncols_u;
14403e97b6e8SHong Zhang   const PetscInt *cols;
14413e97b6e8SHong Zhang   PetscScalar    zero=0.0;
14423e97b6e8SHong Zhang 
14433e97b6e8SHong Zhang   PetscFunctionBegin;
14443e97b6e8SHong Zhang   ierr = MatGetSize(Ju,&M,&N);CHKERRQ(ierr);
14453e97b6e8SHong 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);
14463e97b6e8SHong Zhang 
14473e97b6e8SHong Zhang   for (row=0; row<nrows; row++) {
14483e97b6e8SHong Zhang     ierr = MatGetRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr);
14493e97b6e8SHong Zhang     for (j=0; j<ncols_u; j++) {
14503e97b6e8SHong Zhang       col = cols[j] + cstart;
14513e97b6e8SHong Zhang       ierr = MatSetValues(*J,1,&rows[row],1,&col,&zero,INSERT_VALUES);CHKERRQ(ierr);
14523e97b6e8SHong Zhang     }
14533e97b6e8SHong Zhang     ierr = MatRestoreRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr);
14543e97b6e8SHong Zhang   }
14553e97b6e8SHong Zhang   PetscFunctionReturn(0);
14563e97b6e8SHong Zhang }
14571ad426b7SHong Zhang 
1458e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J)
1459a4e85ca8SHong Zhang {
1460a4e85ca8SHong Zhang   PetscErrorCode ierr;
1461f4431b8cSHong Zhang 
1462a4e85ca8SHong Zhang   PetscFunctionBegin;
1463a4e85ca8SHong Zhang   if (Ju) {
1464a4e85ca8SHong Zhang     ierr = MatSetUserblock_private(Ju,nrows,rows,ncols,cstart,J);CHKERRQ(ierr);
1465a4e85ca8SHong Zhang   } else {
1466a4e85ca8SHong Zhang     ierr = MatSetDenseblock_private(nrows,rows,ncols,cstart,J);CHKERRQ(ierr);
1467a4e85ca8SHong Zhang   }
1468a4e85ca8SHong Zhang   PetscFunctionReturn(0);
1469a4e85ca8SHong Zhang }
1470a4e85ca8SHong Zhang 
147124121865SAdrian 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.
147224121865SAdrian Maldonado */
147324121865SAdrian Maldonado PetscErrorCode CreateSubGlobalToLocalMapping_private(PetscSection globalsec, PetscSection localsec, ISLocalToGlobalMapping *ltog)
147424121865SAdrian Maldonado {
147524121865SAdrian Maldonado   PetscErrorCode ierr;
147624121865SAdrian Maldonado   PetscInt       i, size, dof;
147724121865SAdrian Maldonado   PetscInt       *glob2loc;
147824121865SAdrian Maldonado 
147924121865SAdrian Maldonado   PetscFunctionBegin;
148024121865SAdrian Maldonado   ierr = PetscSectionGetStorageSize(localsec,&size);CHKERRQ(ierr);
148124121865SAdrian Maldonado   ierr = PetscMalloc1(size,&glob2loc);CHKERRQ(ierr);
148224121865SAdrian Maldonado 
148324121865SAdrian Maldonado   for (i = 0; i < size; i++) {
148424121865SAdrian Maldonado     ierr = PetscSectionGetOffset(globalsec,i,&dof);CHKERRQ(ierr);
148524121865SAdrian Maldonado     dof = (dof >= 0) ? dof : -(dof + 1);
148624121865SAdrian Maldonado     glob2loc[i] = dof;
148724121865SAdrian Maldonado   }
148824121865SAdrian Maldonado 
148924121865SAdrian Maldonado   ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,size,glob2loc,PETSC_OWN_POINTER,ltog);CHKERRQ(ierr);
149024121865SAdrian Maldonado #if 0
149124121865SAdrian Maldonado   ierr = PetscIntView(size,glob2loc,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
149224121865SAdrian Maldonado #endif
149324121865SAdrian Maldonado   PetscFunctionReturn(0);
149424121865SAdrian Maldonado }
149524121865SAdrian Maldonado 
149601ad2aeeSHong Zhang #include <petsc/private/matimpl.h>
14971ad426b7SHong Zhang PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J)
14981ad426b7SHong Zhang {
14991ad426b7SHong Zhang   PetscErrorCode ierr;
150024121865SAdrian Maldonado   PetscMPIInt    rank, size;
15011ad426b7SHong Zhang   DM_Network     *network = (DM_Network*)dm->data;
1502a4e85ca8SHong Zhang   PetscInt       eStart,eEnd,vStart,vEnd,rstart,nrows,*rows,localSize;
1503840c2264SHong Zhang   PetscInt       cstart,ncols,j,e,v;
150424121865SAdrian Maldonado   PetscBool      ghost,ghost_vc,ghost2,isNest;
1505a4e85ca8SHong Zhang   Mat            Juser;
1506bfbc38dcSHong Zhang   PetscSection   sectionGlobal;
1507447d78afSSatish Balay   PetscInt       nedges,*vptr=NULL,vc,*rows_v; /* suppress maybe-uninitialized warning */
1508a4e85ca8SHong Zhang   const PetscInt *edges,*cone;
15095cf7da58SHong Zhang   MPI_Comm       comm;
151024121865SAdrian Maldonado   MatType        mtype;
15115cf7da58SHong Zhang   Vec            vd_nz,vo_nz;
15125cf7da58SHong Zhang   PetscInt       *dnnz,*onnz;
15135cf7da58SHong Zhang   PetscScalar    *vdnz,*vonz;
15141ad426b7SHong Zhang 
15151ad426b7SHong Zhang   PetscFunctionBegin;
151624121865SAdrian Maldonado   mtype = dm->mattype;
151724121865SAdrian Maldonado   ierr = PetscStrcmp(mtype, MATNEST, &isNest);CHKERRQ(ierr);
151824121865SAdrian Maldonado 
151924121865SAdrian Maldonado   if (isNest) {
15200731d606SHong Zhang     /* ierr = DMCreateMatrix_Network_Nest(); */
152124121865SAdrian Maldonado     PetscInt   eDof, vDof;
152224121865SAdrian Maldonado     Mat        j11, j12, j21, j22, bA[2][2];
152324121865SAdrian Maldonado     ISLocalToGlobalMapping eISMap, vISMap;
152424121865SAdrian Maldonado 
152524121865SAdrian Maldonado     ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
152624121865SAdrian Maldonado     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
152724121865SAdrian Maldonado     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
152824121865SAdrian Maldonado 
152924121865SAdrian Maldonado     ierr = PetscSectionGetConstrainedStorageSize(network->edge.GlobalDofSection,&eDof);CHKERRQ(ierr);
153024121865SAdrian Maldonado     ierr = PetscSectionGetConstrainedStorageSize(network->vertex.GlobalDofSection,&vDof);CHKERRQ(ierr);
153124121865SAdrian Maldonado 
153201ad2aeeSHong Zhang     ierr = MatCreate(comm, &j11);CHKERRQ(ierr);
153324121865SAdrian Maldonado     ierr = MatSetSizes(j11, eDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
153424121865SAdrian Maldonado     ierr = MatSetType(j11, MATMPIAIJ);CHKERRQ(ierr);
153524121865SAdrian Maldonado 
153601ad2aeeSHong Zhang     ierr = MatCreate(comm, &j12);CHKERRQ(ierr);
153724121865SAdrian Maldonado     ierr = MatSetSizes(j12, eDof, vDof, PETSC_DETERMINE ,PETSC_DETERMINE);CHKERRQ(ierr);
153824121865SAdrian Maldonado     ierr = MatSetType(j12, MATMPIAIJ);CHKERRQ(ierr);
153924121865SAdrian Maldonado 
154001ad2aeeSHong Zhang     ierr = MatCreate(comm, &j21);CHKERRQ(ierr);
154124121865SAdrian Maldonado     ierr = MatSetSizes(j21, vDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
154224121865SAdrian Maldonado     ierr = MatSetType(j21, MATMPIAIJ);CHKERRQ(ierr);
154324121865SAdrian Maldonado 
154401ad2aeeSHong Zhang     ierr = MatCreate(comm, &j22);CHKERRQ(ierr);
154524121865SAdrian Maldonado     ierr = MatSetSizes(j22, vDof, vDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
154624121865SAdrian Maldonado     ierr = MatSetType(j22, MATMPIAIJ);CHKERRQ(ierr);
154724121865SAdrian Maldonado 
15483f6a6bdaSHong Zhang     bA[0][0] = j11;
15493f6a6bdaSHong Zhang     bA[0][1] = j12;
15503f6a6bdaSHong Zhang     bA[1][0] = j21;
15513f6a6bdaSHong Zhang     bA[1][1] = j22;
155224121865SAdrian Maldonado 
155324121865SAdrian Maldonado     ierr = CreateSubGlobalToLocalMapping_private(network->edge.GlobalDofSection,network->edge.DofSection,&eISMap);CHKERRQ(ierr);
155424121865SAdrian Maldonado     ierr = CreateSubGlobalToLocalMapping_private(network->vertex.GlobalDofSection,network->vertex.DofSection,&vISMap);CHKERRQ(ierr);
155524121865SAdrian Maldonado 
155624121865SAdrian Maldonado     ierr = MatSetLocalToGlobalMapping(j11,eISMap,eISMap);CHKERRQ(ierr);
155724121865SAdrian Maldonado     ierr = MatSetLocalToGlobalMapping(j12,eISMap,vISMap);CHKERRQ(ierr);
155824121865SAdrian Maldonado     ierr = MatSetLocalToGlobalMapping(j21,vISMap,eISMap);CHKERRQ(ierr);
155924121865SAdrian Maldonado     ierr = MatSetLocalToGlobalMapping(j22,vISMap,vISMap);CHKERRQ(ierr);
156024121865SAdrian Maldonado 
156124121865SAdrian Maldonado     ierr = MatSetUp(j11);CHKERRQ(ierr);
156224121865SAdrian Maldonado     ierr = MatSetUp(j12);CHKERRQ(ierr);
156324121865SAdrian Maldonado     ierr = MatSetUp(j21);CHKERRQ(ierr);
156424121865SAdrian Maldonado     ierr = MatSetUp(j22);CHKERRQ(ierr);
156524121865SAdrian Maldonado 
156601ad2aeeSHong Zhang     ierr = MatCreateNest(comm,2,NULL,2,NULL,&bA[0][0],J);CHKERRQ(ierr);
156724121865SAdrian Maldonado     ierr = MatSetUp(*J);CHKERRQ(ierr);
156824121865SAdrian Maldonado     ierr = MatNestSetVecType(*J,VECNEST);CHKERRQ(ierr);
156924121865SAdrian Maldonado     ierr = MatDestroy(&j11);CHKERRQ(ierr);
157024121865SAdrian Maldonado     ierr = MatDestroy(&j12);CHKERRQ(ierr);
157124121865SAdrian Maldonado     ierr = MatDestroy(&j21);CHKERRQ(ierr);
157224121865SAdrian Maldonado     ierr = MatDestroy(&j22);CHKERRQ(ierr);
157324121865SAdrian Maldonado 
157424121865SAdrian Maldonado     ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
157524121865SAdrian Maldonado     ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
157624121865SAdrian Maldonado 
157724121865SAdrian Maldonado     /* Free structures */
157824121865SAdrian Maldonado     ierr = ISLocalToGlobalMappingDestroy(&eISMap);CHKERRQ(ierr);
157924121865SAdrian Maldonado     ierr = ISLocalToGlobalMappingDestroy(&vISMap);CHKERRQ(ierr);
158024121865SAdrian Maldonado 
158124121865SAdrian Maldonado     PetscFunctionReturn(0);
158224121865SAdrian Maldonado   } else if (!network->userEdgeJacobian && !network->userVertexJacobian) {
1583a4e85ca8SHong Zhang     /* user does not provide Jacobian blocks */
1584bfbc38dcSHong Zhang     ierr = DMCreateMatrix(network->plex,J);CHKERRQ(ierr);
1585bfbc38dcSHong Zhang     ierr = MatSetDM(*J,dm);CHKERRQ(ierr);
15861ad426b7SHong Zhang     PetscFunctionReturn(0);
15871ad426b7SHong Zhang   }
15881ad426b7SHong Zhang 
1589bfbc38dcSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)dm),J);CHKERRQ(ierr);
15902a945128SHong Zhang   ierr = DMGetDefaultGlobalSection(network->plex,&sectionGlobal);CHKERRQ(ierr);
1591bfbc38dcSHong Zhang   ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal,&localSize);CHKERRQ(ierr);
1592bfbc38dcSHong Zhang   ierr = MatSetSizes(*J,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
15932a945128SHong Zhang 
15942a945128SHong Zhang   ierr = MatSetType(*J,MATAIJ);CHKERRQ(ierr);
15952a945128SHong Zhang   ierr = MatSetFromOptions(*J);CHKERRQ(ierr);
159689898e50SHong Zhang 
159789898e50SHong Zhang   /* (1) Set matrix preallocation */
159889898e50SHong Zhang   /*------------------------------*/
1599840c2264SHong Zhang   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
1600840c2264SHong Zhang   ierr = VecCreate(comm,&vd_nz);CHKERRQ(ierr);
1601840c2264SHong Zhang   ierr = VecSetSizes(vd_nz,localSize,PETSC_DECIDE);CHKERRQ(ierr);
1602840c2264SHong Zhang   ierr = VecSetFromOptions(vd_nz);CHKERRQ(ierr);
1603840c2264SHong Zhang   ierr = VecSet(vd_nz,0.0);CHKERRQ(ierr);
1604840c2264SHong Zhang   ierr = VecDuplicate(vd_nz,&vo_nz);CHKERRQ(ierr);
1605840c2264SHong Zhang 
160689898e50SHong Zhang   /* Set preallocation for edges */
160789898e50SHong Zhang   /*-----------------------------*/
1608840c2264SHong Zhang   ierr = DMNetworkGetEdgeRange(dm,&eStart,&eEnd);CHKERRQ(ierr);
1609840c2264SHong Zhang 
1610bdcb62a2SHong Zhang   ierr = PetscMalloc1(localSize,&rows);CHKERRQ(ierr);
1611840c2264SHong Zhang   for (e=eStart; e<eEnd; e++) {
1612840c2264SHong Zhang     /* Get row indices */
1613840c2264SHong Zhang     ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr);
1614840c2264SHong Zhang     ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr);
1615840c2264SHong Zhang     if (nrows) {
1616840c2264SHong Zhang       for (j=0; j<nrows; j++) rows[j] = j + rstart;
1617840c2264SHong Zhang 
16185cf7da58SHong Zhang       /* Set preallocation for conntected vertices */
1619d842c372SHong Zhang       ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr);
1620840c2264SHong Zhang       for (v=0; v<2; v++) {
1621840c2264SHong Zhang         ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr);
1622840c2264SHong Zhang 
16238675203cSHong Zhang         if (network->Je) {
1624840c2264SHong Zhang           Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */
16258675203cSHong Zhang         } else Juser = NULL;
1626840c2264SHong Zhang         ierr = DMNetworkIsGhostVertex(dm,cone[v],&ghost);CHKERRQ(ierr);
16275cf7da58SHong Zhang         ierr = MatSetPreallocationblock_private(Juser,nrows,rows,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr);
1628840c2264SHong Zhang       }
1629840c2264SHong Zhang 
163089898e50SHong Zhang       /* Set preallocation for edge self */
1631840c2264SHong Zhang       cstart = rstart;
16328675203cSHong Zhang       if (network->Je) {
1633840c2264SHong Zhang         Juser = network->Je[3*e]; /* Jacobian(e,e) */
16348675203cSHong Zhang       } else Juser = NULL;
16355cf7da58SHong Zhang       ierr = MatSetPreallocationblock_private(Juser,nrows,rows,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr);
1636840c2264SHong Zhang     }
1637840c2264SHong Zhang   }
1638840c2264SHong Zhang 
163989898e50SHong Zhang   /* Set preallocation for vertices */
164089898e50SHong Zhang   /*--------------------------------*/
1641840c2264SHong Zhang   ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr);
16428675203cSHong Zhang   if (vEnd - vStart) vptr = network->Jvptr;
1643840c2264SHong Zhang 
1644840c2264SHong Zhang   for (v=vStart; v<vEnd; v++) {
1645840c2264SHong Zhang     /* Get row indices */
1646840c2264SHong Zhang     ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr);
1647840c2264SHong Zhang     ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr);
1648840c2264SHong Zhang     if (!nrows) continue;
1649840c2264SHong Zhang 
1650bdcb62a2SHong Zhang     ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr);
1651bdcb62a2SHong Zhang     if (ghost) {
1652bdcb62a2SHong Zhang       ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr);
1653bdcb62a2SHong Zhang     } else {
1654bdcb62a2SHong Zhang       rows_v = rows;
1655bdcb62a2SHong Zhang     }
1656bdcb62a2SHong Zhang 
1657bdcb62a2SHong Zhang     for (j=0; j<nrows; j++) rows_v[j] = j + rstart;
1658840c2264SHong Zhang 
1659840c2264SHong Zhang     /* Get supporting edges and connected vertices */
1660840c2264SHong Zhang     ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr);
1661840c2264SHong Zhang 
1662840c2264SHong Zhang     for (e=0; e<nedges; e++) {
1663840c2264SHong Zhang       /* Supporting edges */
1664840c2264SHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr);
1665840c2264SHong Zhang       ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr);
1666840c2264SHong Zhang 
16678675203cSHong Zhang       if (network->Jv) {
1668840c2264SHong Zhang         Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */
16698675203cSHong Zhang       } else Juser = NULL;
1670bdcb62a2SHong Zhang       ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr);
1671840c2264SHong Zhang 
1672840c2264SHong Zhang       /* Connected vertices */
1673d842c372SHong Zhang       ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr);
1674840c2264SHong Zhang       vc = (v == cone[0]) ? cone[1]:cone[0];
1675840c2264SHong Zhang       ierr = DMNetworkIsGhostVertex(dm,vc,&ghost_vc);CHKERRQ(ierr);
1676840c2264SHong Zhang 
1677840c2264SHong Zhang       ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr);
1678840c2264SHong Zhang 
16798675203cSHong Zhang       if (network->Jv) {
1680840c2264SHong Zhang         Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */
16818675203cSHong Zhang       } else Juser = NULL;
1682e102a522SHong Zhang       if (ghost_vc||ghost) {
1683e102a522SHong Zhang         ghost2 = PETSC_TRUE;
1684e102a522SHong Zhang       } else {
1685e102a522SHong Zhang         ghost2 = PETSC_FALSE;
1686e102a522SHong Zhang       }
1687e102a522SHong Zhang       ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost2,vd_nz,vo_nz);CHKERRQ(ierr);
1688840c2264SHong Zhang     }
1689840c2264SHong Zhang 
169089898e50SHong Zhang     /* Set preallocation for vertex self */
1691840c2264SHong Zhang     ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr);
1692840c2264SHong Zhang     if (!ghost) {
1693840c2264SHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr);
16948675203cSHong Zhang       if (network->Jv) {
1695840c2264SHong Zhang         Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */
16968675203cSHong Zhang       } else Juser = NULL;
1697bdcb62a2SHong Zhang       ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr);
1698840c2264SHong Zhang     }
1699bdcb62a2SHong Zhang     if (ghost) {
1700bdcb62a2SHong Zhang       ierr = PetscFree(rows_v);CHKERRQ(ierr);
1701bdcb62a2SHong Zhang     }
1702840c2264SHong Zhang   }
1703840c2264SHong Zhang 
1704840c2264SHong Zhang   ierr = VecAssemblyBegin(vd_nz);CHKERRQ(ierr);
1705840c2264SHong Zhang   ierr = VecAssemblyBegin(vo_nz);CHKERRQ(ierr);
17065cf7da58SHong Zhang 
17075cf7da58SHong Zhang   ierr = PetscMalloc2(localSize,&dnnz,localSize,&onnz);CHKERRQ(ierr);
17085cf7da58SHong Zhang 
17095cf7da58SHong Zhang   ierr = VecAssemblyEnd(vd_nz);CHKERRQ(ierr);
1710840c2264SHong Zhang   ierr = VecAssemblyEnd(vo_nz);CHKERRQ(ierr);
1711840c2264SHong Zhang 
1712840c2264SHong Zhang   ierr = VecGetArray(vd_nz,&vdnz);CHKERRQ(ierr);
1713840c2264SHong Zhang   ierr = VecGetArray(vo_nz,&vonz);CHKERRQ(ierr);
1714840c2264SHong Zhang   for (j=0; j<localSize; j++) {
1715e102a522SHong Zhang     dnnz[j] = (PetscInt)PetscRealPart(vdnz[j]);
1716e102a522SHong Zhang     onnz[j] = (PetscInt)PetscRealPart(vonz[j]);
1717840c2264SHong Zhang   }
1718840c2264SHong Zhang   ierr = VecRestoreArray(vd_nz,&vdnz);CHKERRQ(ierr);
1719840c2264SHong Zhang   ierr = VecRestoreArray(vo_nz,&vonz);CHKERRQ(ierr);
1720840c2264SHong Zhang   ierr = VecDestroy(&vd_nz);CHKERRQ(ierr);
1721840c2264SHong Zhang   ierr = VecDestroy(&vo_nz);CHKERRQ(ierr);
1722840c2264SHong Zhang 
17235cf7da58SHong Zhang   ierr = MatSeqAIJSetPreallocation(*J,0,dnnz);CHKERRQ(ierr);
17245cf7da58SHong Zhang   ierr = MatMPIAIJSetPreallocation(*J,0,dnnz,0,onnz);CHKERRQ(ierr);
17255cf7da58SHong Zhang   ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
17265cf7da58SHong Zhang 
17275cf7da58SHong Zhang   ierr = PetscFree2(dnnz,onnz);CHKERRQ(ierr);
17285cf7da58SHong Zhang 
172989898e50SHong Zhang   /* (2) Set matrix entries for edges */
173089898e50SHong Zhang   /*----------------------------------*/
17311ad426b7SHong Zhang   for (e=eStart; e<eEnd; e++) {
1732bfbc38dcSHong Zhang     /* Get row indices */
17331ad426b7SHong Zhang     ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr);
173417df6e9eSHong Zhang     ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr);
17354b976069SHong Zhang     if (nrows) {
173617df6e9eSHong Zhang       for (j=0; j<nrows; j++) rows[j] = j + rstart;
17371ad426b7SHong Zhang 
1738bfbc38dcSHong Zhang       /* Set matrix entries for conntected vertices */
1739d842c372SHong Zhang       ierr = DMNetworkGetConnectedVertices(dm,e,&cone);CHKERRQ(ierr);
1740bfbc38dcSHong Zhang       for (v=0; v<2; v++) {
1741bfbc38dcSHong Zhang         ierr = DMNetworkGetVariableGlobalOffset(dm,cone[v],&cstart);CHKERRQ(ierr);
1742883e35e8SHong Zhang         ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr);
17433e97b6e8SHong Zhang 
17448675203cSHong Zhang         if (network->Je) {
1745a4e85ca8SHong Zhang           Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */
17468675203cSHong Zhang         } else Juser = NULL;
1747a4e85ca8SHong Zhang         ierr = MatSetblock_private(Juser,nrows,rows,ncols,cstart,J);CHKERRQ(ierr);
1748bfbc38dcSHong Zhang       }
174917df6e9eSHong Zhang 
1750bfbc38dcSHong Zhang       /* Set matrix entries for edge self */
17513e97b6e8SHong Zhang       cstart = rstart;
17528675203cSHong Zhang       if (network->Je) {
1753a4e85ca8SHong Zhang         Juser = network->Je[3*e]; /* Jacobian(e,e) */
17548675203cSHong Zhang       } else Juser = NULL;
1755a4e85ca8SHong Zhang       ierr = MatSetblock_private(Juser,nrows,rows,nrows,cstart,J);CHKERRQ(ierr);
17561ad426b7SHong Zhang     }
17574b976069SHong Zhang   }
17581ad426b7SHong Zhang 
1759bfbc38dcSHong Zhang   /* Set matrix entries for vertices */
176083b2e829SHong Zhang   /*---------------------------------*/
17611ad426b7SHong Zhang   for (v=vStart; v<vEnd; v++) {
1762bfbc38dcSHong Zhang     /* Get row indices */
1763596e729fSHong Zhang     ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr);
1764596e729fSHong Zhang     ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr);
17654b976069SHong Zhang     if (!nrows) continue;
1766596e729fSHong Zhang 
1767bdcb62a2SHong Zhang     ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr);
1768bdcb62a2SHong Zhang     if (ghost) {
1769bdcb62a2SHong Zhang       ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr);
1770bdcb62a2SHong Zhang     } else {
1771bdcb62a2SHong Zhang       rows_v = rows;
1772bdcb62a2SHong Zhang     }
1773bdcb62a2SHong Zhang     for (j=0; j<nrows; j++) rows_v[j] = j + rstart;
1774596e729fSHong Zhang 
1775bfbc38dcSHong Zhang     /* Get supporting edges and connected vertices */
1776596e729fSHong Zhang     ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr);
1777596e729fSHong Zhang 
1778596e729fSHong Zhang     for (e=0; e<nedges; e++) {
1779bfbc38dcSHong Zhang       /* Supporting edges */
1780596e729fSHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr);
1781596e729fSHong Zhang       ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr);
1782596e729fSHong Zhang 
17838675203cSHong Zhang       if (network->Jv) {
1784a4e85ca8SHong Zhang         Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */
17858675203cSHong Zhang       } else Juser = NULL;
1786bdcb62a2SHong Zhang       ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr);
1787596e729fSHong Zhang 
1788bfbc38dcSHong Zhang       /* Connected vertices */
1789d842c372SHong Zhang       ierr = DMNetworkGetConnectedVertices(dm,edges[e],&cone);CHKERRQ(ierr);
17902a945128SHong Zhang       vc = (v == cone[0]) ? cone[1]:cone[0];
17912a945128SHong Zhang 
179244aca652SHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,vc,&cstart);CHKERRQ(ierr);
179344aca652SHong Zhang       ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr);
1794a4e85ca8SHong Zhang 
17958675203cSHong Zhang       if (network->Jv) {
1796a4e85ca8SHong Zhang         Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */
17978675203cSHong Zhang       } else Juser = NULL;
1798bdcb62a2SHong Zhang       ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr);
1799596e729fSHong Zhang     }
1800596e729fSHong Zhang 
1801bfbc38dcSHong Zhang     /* Set matrix entries for vertex self */
18021ad426b7SHong Zhang     if (!ghost) {
1803596e729fSHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr);
18048675203cSHong Zhang       if (network->Jv) {
1805a4e85ca8SHong Zhang         Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */
18068675203cSHong Zhang       } else Juser = NULL;
1807bdcb62a2SHong Zhang       ierr = MatSetblock_private(Juser,nrows,rows_v,nrows,cstart,J);CHKERRQ(ierr);
1808bdcb62a2SHong Zhang     }
1809bdcb62a2SHong Zhang     if (ghost) {
1810bdcb62a2SHong Zhang       ierr = PetscFree(rows_v);CHKERRQ(ierr);
1811bdcb62a2SHong Zhang     }
18121ad426b7SHong Zhang   }
1813a4e85ca8SHong Zhang   ierr = PetscFree(rows);CHKERRQ(ierr);
1814bdcb62a2SHong Zhang 
18151ad426b7SHong Zhang   ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18161ad426b7SHong Zhang   ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1817dd6f46cdSHong Zhang 
18185f2c45f1SShri Abhyankar   ierr = MatSetDM(*J,dm);CHKERRQ(ierr);
18195f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
18205f2c45f1SShri Abhyankar }
18215f2c45f1SShri Abhyankar 
18225f2c45f1SShri Abhyankar PetscErrorCode DMDestroy_Network(DM dm)
18235f2c45f1SShri Abhyankar {
18245f2c45f1SShri Abhyankar   PetscErrorCode ierr;
18255f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
18262727e31bSShri Abhyankar   PetscInt       j;
18275f2c45f1SShri Abhyankar 
18285f2c45f1SShri Abhyankar   PetscFunctionBegin;
18298415c774SShri Abhyankar   if (--network->refct > 0) PetscFunctionReturn(0);
183083b2e829SHong Zhang   if (network->Je) {
183183b2e829SHong Zhang     ierr = PetscFree(network->Je);CHKERRQ(ierr);
183283b2e829SHong Zhang   }
183383b2e829SHong Zhang   if (network->Jv) {
1834883e35e8SHong Zhang     ierr = PetscFree(network->Jvptr);CHKERRQ(ierr);
183583b2e829SHong Zhang     ierr = PetscFree(network->Jv);CHKERRQ(ierr);
18361ad426b7SHong Zhang   }
183713c2a604SAdrian Maldonado 
183813c2a604SAdrian Maldonado   ierr = ISLocalToGlobalMappingDestroy(&network->vertex.mapping);CHKERRQ(ierr);
183913c2a604SAdrian Maldonado   ierr = PetscSectionDestroy(&network->vertex.DofSection);CHKERRQ(ierr);
184013c2a604SAdrian Maldonado   ierr = PetscSectionDestroy(&network->vertex.GlobalDofSection);CHKERRQ(ierr);
184113c2a604SAdrian Maldonado   if (network->vertex.sf) {
184213c2a604SAdrian Maldonado     ierr = PetscSFDestroy(&network->vertex.sf);CHKERRQ(ierr);
184313c2a604SAdrian Maldonado   }
184413c2a604SAdrian Maldonado   /* edge */
184513c2a604SAdrian Maldonado   ierr = ISLocalToGlobalMappingDestroy(&network->edge.mapping);CHKERRQ(ierr);
184613c2a604SAdrian Maldonado   ierr = PetscSectionDestroy(&network->edge.DofSection);CHKERRQ(ierr);
184713c2a604SAdrian Maldonado   ierr = PetscSectionDestroy(&network->edge.GlobalDofSection);CHKERRQ(ierr);
184813c2a604SAdrian Maldonado   if (network->edge.sf) {
184913c2a604SAdrian Maldonado     ierr = PetscSFDestroy(&network->edge.sf);CHKERRQ(ierr);
185013c2a604SAdrian Maldonado   }
18515f2c45f1SShri Abhyankar   ierr = DMDestroy(&network->plex);CHKERRQ(ierr);
18525f2c45f1SShri Abhyankar   network->edges = NULL;
18535f2c45f1SShri Abhyankar   ierr = PetscSectionDestroy(&network->DataSection);CHKERRQ(ierr);
18545f2c45f1SShri Abhyankar   ierr = PetscSectionDestroy(&network->DofSection);CHKERRQ(ierr);
185583b2e829SHong Zhang 
18562727e31bSShri Abhyankar   for(j=0; j < network->nsubnet; j++) {
18572727e31bSShri Abhyankar     ierr = PetscFree(network->subnet[j].edges);CHKERRQ(ierr);
18582727e31bSShri Abhyankar     ierr = PetscFree(network->subnet[j].vertices);CHKERRQ(ierr);
18592727e31bSShri Abhyankar   }
1860e2aaf10cSShri Abhyankar   ierr = PetscFree(network->subnet);CHKERRQ(ierr);
18615f2c45f1SShri Abhyankar   ierr = PetscFree(network->componentdataarray);CHKERRQ(ierr);
18625f2c45f1SShri Abhyankar   ierr = PetscFree(network->cvalue);CHKERRQ(ierr);
18635f2c45f1SShri Abhyankar   ierr = PetscFree(network->header);CHKERRQ(ierr);
18645f2c45f1SShri Abhyankar   ierr = PetscFree(network);CHKERRQ(ierr);
18655f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
18665f2c45f1SShri Abhyankar }
18675f2c45f1SShri Abhyankar 
18685f2c45f1SShri Abhyankar PetscErrorCode DMView_Network(DM dm,PetscViewer viewer)
18695f2c45f1SShri Abhyankar {
18705f2c45f1SShri Abhyankar   PetscErrorCode ierr;
18715f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
18725f2c45f1SShri Abhyankar 
18735f2c45f1SShri Abhyankar   PetscFunctionBegin;
18745f2c45f1SShri Abhyankar   ierr = DMView(network->plex,viewer);CHKERRQ(ierr);
18755f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
18765f2c45f1SShri Abhyankar }
18775f2c45f1SShri Abhyankar 
18785f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l)
18795f2c45f1SShri Abhyankar {
18805f2c45f1SShri Abhyankar   PetscErrorCode ierr;
18815f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
18825f2c45f1SShri Abhyankar 
18835f2c45f1SShri Abhyankar   PetscFunctionBegin;
18845f2c45f1SShri Abhyankar   ierr = DMGlobalToLocalBegin(network->plex,g,mode,l);CHKERRQ(ierr);
18855f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
18865f2c45f1SShri Abhyankar }
18875f2c45f1SShri Abhyankar 
18885f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l)
18895f2c45f1SShri Abhyankar {
18905f2c45f1SShri Abhyankar   PetscErrorCode ierr;
18915f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
18925f2c45f1SShri Abhyankar 
18935f2c45f1SShri Abhyankar   PetscFunctionBegin;
18945f2c45f1SShri Abhyankar   ierr = DMGlobalToLocalEnd(network->plex,g,mode,l);CHKERRQ(ierr);
18955f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
18965f2c45f1SShri Abhyankar }
18975f2c45f1SShri Abhyankar 
18985f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g)
18995f2c45f1SShri Abhyankar {
19005f2c45f1SShri Abhyankar   PetscErrorCode ierr;
19015f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
19025f2c45f1SShri Abhyankar 
19035f2c45f1SShri Abhyankar   PetscFunctionBegin;
19045f2c45f1SShri Abhyankar   ierr = DMLocalToGlobalBegin(network->plex,l,mode,g);CHKERRQ(ierr);
19055f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
19065f2c45f1SShri Abhyankar }
19075f2c45f1SShri Abhyankar 
19085f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g)
19095f2c45f1SShri Abhyankar {
19105f2c45f1SShri Abhyankar   PetscErrorCode ierr;
19115f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
19125f2c45f1SShri Abhyankar 
19135f2c45f1SShri Abhyankar   PetscFunctionBegin;
19145f2c45f1SShri Abhyankar   ierr = DMLocalToGlobalEnd(network->plex,l,mode,g);CHKERRQ(ierr);
19155f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
19165f2c45f1SShri Abhyankar }
1917