xref: /petsc/src/dm/impls/network/network.c (revision 24121865099348bf22d6aa73d513ff7b2ea689d2)
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 #undef __FUNCT__
65f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkSetSizes"
75f2c45f1SShri Abhyankar /*@
85f2c45f1SShri Abhyankar   DMNetworkSetSizes - Sets the local and global vertices and edges.
95f2c45f1SShri Abhyankar 
105f2c45f1SShri Abhyankar   Collective on DM
115f2c45f1SShri Abhyankar 
125f2c45f1SShri Abhyankar   Input Parameters:
135f2c45f1SShri Abhyankar + dm - the dm object
145f2c45f1SShri Abhyankar . nV - number of local vertices
155f2c45f1SShri Abhyankar . nE - number of local edges
165f2c45f1SShri Abhyankar . NV - number of global vertices (or PETSC_DETERMINE)
175f2c45f1SShri Abhyankar - NE - number of global edges (or PETSC_DETERMINE)
185f2c45f1SShri Abhyankar 
195f2c45f1SShri Abhyankar    Notes
205f2c45f1SShri Abhyankar    If one processor calls this with NV (NE) of PETSC_DECIDE then all processors must, otherwise the prgram will hang.
215f2c45f1SShri Abhyankar 
225f2c45f1SShri Abhyankar    You cannot change the sizes once they have been set
235f2c45f1SShri Abhyankar 
245f2c45f1SShri Abhyankar .seealso: DMNetworkCreate
255f2c45f1SShri Abhyankar @*/
265f2c45f1SShri Abhyankar PetscErrorCode DMNetworkSetSizes(DM dm, PetscInt nV, PetscInt nE, PetscInt NV, PetscInt NE)
275f2c45f1SShri Abhyankar {
285f2c45f1SShri Abhyankar   PetscErrorCode ierr;
295f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
305f2c45f1SShri Abhyankar   PetscInt       a[2],b[2];
315f2c45f1SShri Abhyankar 
325f2c45f1SShri Abhyankar   PetscFunctionBegin;
335f2c45f1SShri Abhyankar   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
345f2c45f1SShri Abhyankar   if (NV > 0) PetscValidLogicalCollectiveInt(dm,NV,4);
355f2c45f1SShri Abhyankar   if (NE > 0) PetscValidLogicalCollectiveInt(dm,NE,5);
365f2c45f1SShri Abhyankar   if (NV > 0 && nV > NV) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local vertex size %D cannot be larger than global vertex size %D",nV,NV);
375f2c45f1SShri Abhyankar   if (NE > 0 && nE > NE) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local edge size %D cannot be larger than global edge size %D",nE,NE);
385f2c45f1SShri Abhyankar   if ((network->nNodes >= 0 || network->NNodes >= 0) && (network->nNodes != nV || network->NNodes != NV)) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot change/reset vertex sizes to %D local %D global after previously setting them to %D local %D global",nV,NV,network->nNodes,network->NNodes);
395f2c45f1SShri Abhyankar   if ((network->nEdges >= 0 || network->NEdges >= 0) && (network->nEdges != nE || network->NEdges != NE)) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot change/reset edge sizes to %D local %D global after previously setting them to %D local %D global",nE,NE,network->nEdges,network->NEdges);
405f2c45f1SShri Abhyankar   if (NE < 0 || NV < 0) {
415f2c45f1SShri Abhyankar     a[0] = nV; a[1] = nE;
42b2566f29SBarry Smith     ierr = MPIU_Allreduce(a,b,2,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
435f2c45f1SShri Abhyankar     NV = b[0]; NE = b[1];
445f2c45f1SShri Abhyankar   }
455f2c45f1SShri Abhyankar   network->nNodes = nV;
465f2c45f1SShri Abhyankar   network->NNodes = NV;
475f2c45f1SShri Abhyankar   network->nEdges = nE;
485f2c45f1SShri Abhyankar   network->NEdges = NE;
495f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
505f2c45f1SShri Abhyankar }
515f2c45f1SShri Abhyankar 
525f2c45f1SShri Abhyankar #undef __FUNCT__
535f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkSetEdgeList"
545f2c45f1SShri Abhyankar /*@
555f2c45f1SShri Abhyankar   DMNetworkSetEdgeList - Sets the list of local edges (vertex connectivity) for the network
565f2c45f1SShri Abhyankar 
575f2c45f1SShri Abhyankar   Logically collective on DM
585f2c45f1SShri Abhyankar 
595f2c45f1SShri Abhyankar   Input Parameters:
605f2c45f1SShri Abhyankar . edges - list of edges
615f2c45f1SShri Abhyankar 
625f2c45f1SShri Abhyankar   Notes:
635f2c45f1SShri Abhyankar   There is no copy involved in this operation, only the pointer is referenced. The edgelist should
645f2c45f1SShri Abhyankar   not be destroyed before the call to DMNetworkLayoutSetUp
655f2c45f1SShri Abhyankar 
665f2c45f1SShri Abhyankar   Level: intermediate
675f2c45f1SShri Abhyankar 
685f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkSetSizes
695f2c45f1SShri Abhyankar @*/
705f2c45f1SShri Abhyankar PetscErrorCode DMNetworkSetEdgeList(DM dm, int edgelist[])
715f2c45f1SShri Abhyankar {
725f2c45f1SShri Abhyankar   DM_Network *network = (DM_Network*) dm->data;
735f2c45f1SShri Abhyankar 
745f2c45f1SShri Abhyankar   PetscFunctionBegin;
755f2c45f1SShri Abhyankar   network->edges = edgelist;
765f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
775f2c45f1SShri Abhyankar }
785f2c45f1SShri Abhyankar 
795f2c45f1SShri Abhyankar #undef __FUNCT__
805f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkLayoutSetUp"
815f2c45f1SShri Abhyankar /*@
825f2c45f1SShri Abhyankar   DMNetworkLayoutSetUp - Sets up the bare layout (graph) for the network
835f2c45f1SShri Abhyankar 
845f2c45f1SShri Abhyankar   Collective on DM
855f2c45f1SShri Abhyankar 
865f2c45f1SShri Abhyankar   Input Parameters
875f2c45f1SShri Abhyankar . DM - the dmnetwork object
885f2c45f1SShri Abhyankar 
895f2c45f1SShri Abhyankar   Notes:
905f2c45f1SShri Abhyankar   This routine should be called after the network sizes and edgelists have been provided. It creates
915f2c45f1SShri Abhyankar   the bare layout of the network and sets up the network to begin insertion of components.
925f2c45f1SShri Abhyankar 
935f2c45f1SShri Abhyankar   All the components should be registered before calling this routine.
945f2c45f1SShri Abhyankar 
955f2c45f1SShri Abhyankar   Level: intermediate
965f2c45f1SShri Abhyankar 
975f2c45f1SShri Abhyankar .seealso: DMNetworkSetSizes, DMNetworkSetEdgeList
985f2c45f1SShri Abhyankar @*/
995f2c45f1SShri Abhyankar PetscErrorCode DMNetworkLayoutSetUp(DM dm)
1005f2c45f1SShri Abhyankar {
1015f2c45f1SShri Abhyankar   PetscErrorCode ierr;
1025f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
1035f2c45f1SShri Abhyankar   PetscInt       dim = 1; /* One dimensional network */
1045f2c45f1SShri Abhyankar   PetscInt       numCorners=2;
1055f2c45f1SShri Abhyankar   PetscInt       spacedim=2;
1065f2c45f1SShri Abhyankar   double         *vertexcoords=NULL;
1075f2c45f1SShri Abhyankar   PetscInt       i;
1085f2c45f1SShri Abhyankar   PetscInt       ndata;
1095f2c45f1SShri Abhyankar 
1105f2c45f1SShri Abhyankar   PetscFunctionBegin;
1115f2c45f1SShri Abhyankar   if (network->nNodes) {
1129045477aSSatish Balay     ierr = PetscCalloc1(numCorners*network->nNodes,&vertexcoords);CHKERRQ(ierr);
1135f2c45f1SShri Abhyankar   }
1145f2c45f1SShri Abhyankar   ierr = DMPlexCreateFromCellList(PetscObjectComm((PetscObject)dm),dim,network->nEdges,network->nNodes,numCorners,PETSC_FALSE,network->edges,spacedim,vertexcoords,&network->plex);CHKERRQ(ierr);
1155f2c45f1SShri Abhyankar   if (network->nNodes) {
1165f2c45f1SShri Abhyankar     ierr = PetscFree(vertexcoords);CHKERRQ(ierr);
1175f2c45f1SShri Abhyankar   }
1185f2c45f1SShri Abhyankar   ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr);
1195f2c45f1SShri Abhyankar   ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr);
1205f2c45f1SShri Abhyankar   ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr);
1215f2c45f1SShri Abhyankar 
1225f2c45f1SShri Abhyankar   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm),&network->DataSection);CHKERRQ(ierr);
1235f2c45f1SShri Abhyankar   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm),&network->DofSection);CHKERRQ(ierr);
1245f2c45f1SShri Abhyankar   ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr);
1255f2c45f1SShri Abhyankar   ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr);
1265f2c45f1SShri Abhyankar 
127*24121865SAdrian Maldonado 
128*24121865SAdrian Maldonado 
1295f2c45f1SShri Abhyankar   network->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType);
1306caa05f4SBarry Smith   ierr = PetscCalloc1(network->pEnd-network->pStart,&network->header);CHKERRQ(ierr);
1315f2c45f1SShri Abhyankar   for (i = network->pStart; i < network->pEnd; i++) {
1325f2c45f1SShri Abhyankar     network->header[i].ndata = 0;
1335f2c45f1SShri Abhyankar     ndata = network->header[i].ndata;
1345f2c45f1SShri Abhyankar     ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr);
1355f2c45f1SShri Abhyankar     network->header[i].offset[ndata] = 0;
1365f2c45f1SShri Abhyankar   }
137854ce69bSBarry Smith   ierr = PetscMalloc1(network->pEnd-network->pStart,&network->cvalue);CHKERRQ(ierr);
1385f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
1395f2c45f1SShri Abhyankar }
1405f2c45f1SShri Abhyankar 
1415f2c45f1SShri Abhyankar #undef __FUNCT__
1425f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkRegisterComponent"
1435f2c45f1SShri Abhyankar /*@
1445f2c45f1SShri Abhyankar   DMNetworkRegisterComponent - Registers the network component
1455f2c45f1SShri Abhyankar 
1465f2c45f1SShri Abhyankar   Logically collective on DM
1475f2c45f1SShri Abhyankar 
1485f2c45f1SShri Abhyankar   Input Parameters
1495f2c45f1SShri Abhyankar + dm   - the network object
1505f2c45f1SShri Abhyankar . name - the component name
1515f2c45f1SShri Abhyankar - size - the storage size in bytes for this component data
1525f2c45f1SShri Abhyankar 
1535f2c45f1SShri Abhyankar    Output Parameters
1545f2c45f1SShri Abhyankar .   key - an integer key that defines the component
1555f2c45f1SShri Abhyankar 
1565f2c45f1SShri Abhyankar    Notes
1575f2c45f1SShri Abhyankar    This routine should be called by all processors before calling DMNetworkLayoutSetup().
1585f2c45f1SShri Abhyankar 
1595f2c45f1SShri Abhyankar    Level: intermediate
1605f2c45f1SShri Abhyankar 
1615f2c45f1SShri Abhyankar .seealso: DMNetworkLayoutSetUp, DMNetworkCreate
1625f2c45f1SShri Abhyankar @*/
1635f2c45f1SShri Abhyankar PetscErrorCode DMNetworkRegisterComponent(DM dm,const char *name,PetscInt size,PetscInt *key)
1645f2c45f1SShri Abhyankar {
1655f2c45f1SShri Abhyankar   PetscErrorCode        ierr;
1665f2c45f1SShri Abhyankar   DM_Network            *network = (DM_Network*) dm->data;
1675f2c45f1SShri Abhyankar   DMNetworkComponent    *component=&network->component[network->ncomponent];
1685f2c45f1SShri Abhyankar   PetscBool             flg=PETSC_FALSE;
1695f2c45f1SShri Abhyankar   PetscInt              i;
1705f2c45f1SShri Abhyankar 
1715f2c45f1SShri Abhyankar   PetscFunctionBegin;
1725f2c45f1SShri Abhyankar 
1735f2c45f1SShri Abhyankar   for (i=0; i < network->ncomponent; i++) {
1745f2c45f1SShri Abhyankar     ierr = PetscStrcmp(component->name,name,&flg);CHKERRQ(ierr);
1755f2c45f1SShri Abhyankar     if (flg) {
1765f2c45f1SShri Abhyankar       *key = i;
1775f2c45f1SShri Abhyankar       PetscFunctionReturn(0);
1785f2c45f1SShri Abhyankar     }
1795f2c45f1SShri Abhyankar   }
1805f2c45f1SShri Abhyankar 
1815f2c45f1SShri Abhyankar   ierr = PetscStrcpy(component->name,name);CHKERRQ(ierr);
1825f2c45f1SShri Abhyankar   component->size = size/sizeof(DMNetworkComponentGenericDataType);
1835f2c45f1SShri Abhyankar   *key = network->ncomponent;
1845f2c45f1SShri Abhyankar   network->ncomponent++;
1855f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
1865f2c45f1SShri Abhyankar }
1875f2c45f1SShri Abhyankar 
1885f2c45f1SShri Abhyankar #undef __FUNCT__
1895f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetVertexRange"
1905f2c45f1SShri Abhyankar /*@
1915f2c45f1SShri Abhyankar   DMNetworkGetVertexRange - Get the bounds [start, end) for the vertices.
1925f2c45f1SShri Abhyankar 
1935f2c45f1SShri Abhyankar   Not Collective
1945f2c45f1SShri Abhyankar 
1955f2c45f1SShri Abhyankar   Input Parameters:
1965f2c45f1SShri Abhyankar + dm - The DMNetwork object
1975f2c45f1SShri Abhyankar 
1985f2c45f1SShri Abhyankar   Output Paramters:
1995f2c45f1SShri Abhyankar + vStart - The first vertex point
2005f2c45f1SShri Abhyankar - vEnd   - One beyond the last vertex point
2015f2c45f1SShri Abhyankar 
2025f2c45f1SShri Abhyankar   Level: intermediate
2035f2c45f1SShri Abhyankar 
2045f2c45f1SShri Abhyankar .seealso: DMNetworkGetEdgeRange
2055f2c45f1SShri Abhyankar @*/
2065f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVertexRange(DM dm,PetscInt *vStart,PetscInt *vEnd)
2075f2c45f1SShri Abhyankar {
2085f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
2095f2c45f1SShri Abhyankar 
2105f2c45f1SShri Abhyankar   PetscFunctionBegin;
2115f2c45f1SShri Abhyankar   if (vStart) *vStart = network->vStart;
2125f2c45f1SShri Abhyankar   if (vEnd) *vEnd = network->vEnd;
2135f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
2145f2c45f1SShri Abhyankar }
2155f2c45f1SShri Abhyankar 
2165f2c45f1SShri Abhyankar #undef __FUNCT__
2175f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetEdgeRange"
2185f2c45f1SShri Abhyankar /*@
2195f2c45f1SShri Abhyankar   DMNetworkGetEdgeRange - Get the bounds [start, end) for the edges.
2205f2c45f1SShri Abhyankar 
2215f2c45f1SShri Abhyankar   Not Collective
2225f2c45f1SShri Abhyankar 
2235f2c45f1SShri Abhyankar   Input Parameters:
2245f2c45f1SShri Abhyankar + dm - The DMNetwork object
2255f2c45f1SShri Abhyankar 
2265f2c45f1SShri Abhyankar   Output Paramters:
2275f2c45f1SShri Abhyankar + eStart - The first edge point
2285f2c45f1SShri Abhyankar - eEnd   - One beyond the last edge point
2295f2c45f1SShri Abhyankar 
2305f2c45f1SShri Abhyankar   Level: intermediate
2315f2c45f1SShri Abhyankar 
2325f2c45f1SShri Abhyankar .seealso: DMNetworkGetVertexRange
2335f2c45f1SShri Abhyankar @*/
2345f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetEdgeRange(DM dm,PetscInt *eStart,PetscInt *eEnd)
2355f2c45f1SShri Abhyankar {
2365f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
2375f2c45f1SShri Abhyankar 
2385f2c45f1SShri Abhyankar   PetscFunctionBegin;
2395f2c45f1SShri Abhyankar   if (eStart) *eStart = network->eStart;
2405f2c45f1SShri Abhyankar   if (eEnd) *eEnd = network->eEnd;
2415f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
2425f2c45f1SShri Abhyankar }
2435f2c45f1SShri Abhyankar 
2445f2c45f1SShri Abhyankar #undef __FUNCT__
2455f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkAddComponent"
2465f2c45f1SShri Abhyankar /*@
2475f2c45f1SShri Abhyankar   DMNetworkAddComponent - Adds a network component at the given point (vertex/edge)
2485f2c45f1SShri Abhyankar 
2495f2c45f1SShri Abhyankar   Not Collective
2505f2c45f1SShri Abhyankar 
2515f2c45f1SShri Abhyankar   Input Parameters:
2525f2c45f1SShri Abhyankar + dm           - The DMNetwork object
2535f2c45f1SShri Abhyankar . p            - vertex/edge point
2545f2c45f1SShri Abhyankar . componentkey - component key returned while registering the component
2555f2c45f1SShri Abhyankar - compvalue    - pointer to the data structure for the component
2565f2c45f1SShri Abhyankar 
2575f2c45f1SShri Abhyankar   Level: intermediate
2585f2c45f1SShri Abhyankar 
2595f2c45f1SShri Abhyankar .seealso: DMNetworkGetVertexRange, DMNetworkGetEdgeRange, DMNetworkRegisterComponent
2605f2c45f1SShri Abhyankar @*/
2615f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddComponent(DM dm, PetscInt p,PetscInt componentkey,void* compvalue)
2625f2c45f1SShri Abhyankar {
2635f2c45f1SShri Abhyankar   DM_Network               *network = (DM_Network*)dm->data;
26443a39a44SBarry Smith   DMNetworkComponent       *component = &network->component[componentkey];
2655f2c45f1SShri Abhyankar   DMNetworkComponentHeader header = &network->header[p];
2665f2c45f1SShri Abhyankar   DMNetworkComponentValue  cvalue = &network->cvalue[p];
2675f2c45f1SShri Abhyankar   PetscErrorCode           ierr;
2685f2c45f1SShri Abhyankar 
2695f2c45f1SShri Abhyankar   PetscFunctionBegin;
270fa58f0a9SHong 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);
271fa58f0a9SHong Zhang 
27243a39a44SBarry Smith   header->size[header->ndata] = component->size;
27343a39a44SBarry Smith   ierr = PetscSectionAddDof(network->DataSection,p,component->size);CHKERRQ(ierr);
2745f2c45f1SShri Abhyankar   header->key[header->ndata] = componentkey;
2755f2c45f1SShri Abhyankar   if (header->ndata != 0) header->offset[header->ndata] = header->offset[header->ndata-1] + header->size[header->ndata-1];
2765f2c45f1SShri Abhyankar 
2775f2c45f1SShri Abhyankar   cvalue->data[header->ndata] = (void*)compvalue;
2785f2c45f1SShri Abhyankar   header->ndata++;
2795f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
2805f2c45f1SShri Abhyankar }
2815f2c45f1SShri Abhyankar 
2825f2c45f1SShri Abhyankar #undef __FUNCT__
2835f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetNumComponents"
2845f2c45f1SShri Abhyankar /*@
2855f2c45f1SShri Abhyankar   DMNetworkGetNumComponents - Get the number of components at a vertex/edge
2865f2c45f1SShri Abhyankar 
2875f2c45f1SShri Abhyankar   Not Collective
2885f2c45f1SShri Abhyankar 
2895f2c45f1SShri Abhyankar   Input Parameters:
2905f2c45f1SShri Abhyankar + dm - The DMNetwork object
2915f2c45f1SShri Abhyankar . p  - vertex/edge point
2925f2c45f1SShri Abhyankar 
2935f2c45f1SShri Abhyankar   Output Parameters:
2945f2c45f1SShri Abhyankar . numcomponents - Number of components at the vertex/edge
2955f2c45f1SShri Abhyankar 
2965f2c45f1SShri Abhyankar   Level: intermediate
2975f2c45f1SShri Abhyankar 
2985f2c45f1SShri Abhyankar .seealso: DMNetworkRegisterComponent, DMNetworkAddComponent
2995f2c45f1SShri Abhyankar @*/
3005f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetNumComponents(DM dm,PetscInt p,PetscInt *numcomponents)
3015f2c45f1SShri Abhyankar {
3025f2c45f1SShri Abhyankar   PetscErrorCode ierr;
3035f2c45f1SShri Abhyankar   PetscInt       offset;
3045f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
3055f2c45f1SShri Abhyankar 
3065f2c45f1SShri Abhyankar   PetscFunctionBegin;
3075f2c45f1SShri Abhyankar   ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr);
3085f2c45f1SShri Abhyankar   *numcomponents = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata;
3095f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
3105f2c45f1SShri Abhyankar }
3115f2c45f1SShri Abhyankar 
3125f2c45f1SShri Abhyankar #undef __FUNCT__
3135f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetComponentTypeOffset"
3145f2c45f1SShri Abhyankar /*@
3155f2c45f1SShri Abhyankar   DMNetworkGetComponentTypeOffset - Gets the type along with the offset for indexing the
3165f2c45f1SShri Abhyankar                                     component value from the component data array
3175f2c45f1SShri Abhyankar 
3185f2c45f1SShri Abhyankar   Not Collective
3195f2c45f1SShri Abhyankar 
3205f2c45f1SShri Abhyankar   Input Parameters:
3215f2c45f1SShri Abhyankar + dm      - The DMNetwork object
3225f2c45f1SShri Abhyankar . p       - vertex/edge point
3235f2c45f1SShri Abhyankar - compnum - component number
3245f2c45f1SShri Abhyankar 
3255f2c45f1SShri Abhyankar   Output Parameters:
3265f2c45f1SShri Abhyankar + compkey - the key obtained when registering the component
3275f2c45f1SShri Abhyankar - offset  - offset into the component data array associated with the vertex/edge point
3285f2c45f1SShri Abhyankar 
3295f2c45f1SShri Abhyankar   Notes:
3305f2c45f1SShri Abhyankar   Typical usage:
3315f2c45f1SShri Abhyankar 
3325f2c45f1SShri Abhyankar   DMNetworkGetComponentDataArray(dm, &arr);
3335f2c45f1SShri Abhyankar   DMNetworkGetVertex/EdgeRange(dm,&Start,&End);
3345f2c45f1SShri Abhyankar   Loop over vertices or edges
3355f2c45f1SShri Abhyankar     DMNetworkGetNumComponents(dm,v,&numcomps);
3365f2c45f1SShri Abhyankar     Loop over numcomps
3375f2c45f1SShri Abhyankar       DMNetworkGetComponentTypeOffset(dm,v,compnum,&key,&offset);
3385f2c45f1SShri Abhyankar       compdata = (UserCompDataType)(arr+offset);
3395f2c45f1SShri Abhyankar 
3405f2c45f1SShri Abhyankar   Level: intermediate
3415f2c45f1SShri Abhyankar 
3425f2c45f1SShri Abhyankar .seealso: DMNetworkGetNumComponents, DMNetworkGetComponentDataArray,
3435f2c45f1SShri Abhyankar @*/
3445f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetComponentTypeOffset(DM dm,PetscInt p, PetscInt compnum, PetscInt *compkey, PetscInt *offset)
3455f2c45f1SShri Abhyankar {
3465f2c45f1SShri Abhyankar   PetscErrorCode           ierr;
3475f2c45f1SShri Abhyankar   PetscInt                 offsetp;
3485f2c45f1SShri Abhyankar   DMNetworkComponentHeader header;
3495f2c45f1SShri Abhyankar   DM_Network               *network = (DM_Network*)dm->data;
3505f2c45f1SShri Abhyankar 
3515f2c45f1SShri Abhyankar   PetscFunctionBegin;
3525f2c45f1SShri Abhyankar   ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr);
3535f2c45f1SShri Abhyankar   header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp);
354d36f4e81SHong Zhang   if (compkey) *compkey = header->key[compnum];
355d36f4e81SHong Zhang   if (offset) *offset  = offsetp+network->dataheadersize+header->offset[compnum];
3565f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
3575f2c45f1SShri Abhyankar }
3585f2c45f1SShri Abhyankar 
3595f2c45f1SShri Abhyankar #undef __FUNCT__
3605f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetVariableOffset"
3615f2c45f1SShri Abhyankar /*@
3625f2c45f1SShri Abhyankar   DMNetworkGetVariableOffset - Get the offset for accessing the variable associated with the given vertex/edge from the local vector.
3635f2c45f1SShri Abhyankar 
3645f2c45f1SShri Abhyankar   Not Collective
3655f2c45f1SShri Abhyankar 
3665f2c45f1SShri Abhyankar   Input Parameters:
3675f2c45f1SShri Abhyankar + dm     - The DMNetwork object
3685f2c45f1SShri Abhyankar - p      - the edge/vertex point
3695f2c45f1SShri Abhyankar 
3705f2c45f1SShri Abhyankar   Output Parameters:
3715f2c45f1SShri Abhyankar . offset - the offset
3725f2c45f1SShri Abhyankar 
3735f2c45f1SShri Abhyankar   Level: intermediate
3745f2c45f1SShri Abhyankar 
3755f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector
3765f2c45f1SShri Abhyankar @*/
3775f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableOffset(DM dm,PetscInt p,PetscInt *offset)
3785f2c45f1SShri Abhyankar {
3795f2c45f1SShri Abhyankar   PetscErrorCode ierr;
3805f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
3815f2c45f1SShri Abhyankar 
3825f2c45f1SShri Abhyankar   PetscFunctionBegin;
3835f2c45f1SShri Abhyankar   ierr = PetscSectionGetOffset(network->DofSection,p,offset);CHKERRQ(ierr);
3845f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
3855f2c45f1SShri Abhyankar }
3865f2c45f1SShri Abhyankar 
3875f2c45f1SShri Abhyankar #undef __FUNCT__
3885f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetVariableGlobalOffset"
3895f2c45f1SShri Abhyankar /*@
3905f2c45f1SShri Abhyankar   DMNetworkGetVariableGlobalOffset - Get the global offset for the variable associated with the given vertex/edge from the global vector.
3915f2c45f1SShri Abhyankar 
3925f2c45f1SShri Abhyankar   Not Collective
3935f2c45f1SShri Abhyankar 
3945f2c45f1SShri Abhyankar   Input Parameters:
3955f2c45f1SShri Abhyankar + dm      - The DMNetwork object
3965f2c45f1SShri Abhyankar - p       - the edge/vertex point
3975f2c45f1SShri Abhyankar 
3985f2c45f1SShri Abhyankar   Output Parameters:
3995f2c45f1SShri Abhyankar . offsetg - the offset
4005f2c45f1SShri Abhyankar 
4015f2c45f1SShri Abhyankar   Level: intermediate
4025f2c45f1SShri Abhyankar 
4035f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableOffset, DMGetLocalVector
4045f2c45f1SShri Abhyankar @*/
4055f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableGlobalOffset(DM dm,PetscInt p,PetscInt *offsetg)
4065f2c45f1SShri Abhyankar {
4075f2c45f1SShri Abhyankar   PetscErrorCode ierr;
4085f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
4095f2c45f1SShri Abhyankar 
4105f2c45f1SShri Abhyankar   PetscFunctionBegin;
4115f2c45f1SShri Abhyankar   ierr = PetscSectionGetOffset(network->GlobalDofSection,p,offsetg);CHKERRQ(ierr);
412dd6f46cdSHong Zhang   if (*offsetg < 0) *offsetg = -(*offsetg + 1); /* Convert to actual global offset for ghost node */
4135f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
4145f2c45f1SShri Abhyankar }
4155f2c45f1SShri Abhyankar 
4165f2c45f1SShri Abhyankar #undef __FUNCT__
417*24121865SAdrian Maldonado #define __FUNCT__ "DMNetworkGetEdgeOffset"
418*24121865SAdrian Maldonado /*@
419*24121865SAdrian Maldonado   DMNetworkGetEdgeOffset - Get the offset for accessing the variable associated with the given edge from the local subvector.
420*24121865SAdrian Maldonado 
421*24121865SAdrian Maldonado   Not Collective
422*24121865SAdrian Maldonado 
423*24121865SAdrian Maldonado   Input Parameters:
424*24121865SAdrian Maldonado + dm     - The DMNetwork object
425*24121865SAdrian Maldonado - p      - the edge point
426*24121865SAdrian Maldonado 
427*24121865SAdrian Maldonado   Output Parameters:
428*24121865SAdrian Maldonado . offset - the offset
429*24121865SAdrian Maldonado 
430*24121865SAdrian Maldonado   Level: intermediate
431*24121865SAdrian Maldonado 
432*24121865SAdrian Maldonado .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector
433*24121865SAdrian Maldonado @*/
434*24121865SAdrian Maldonado PetscErrorCode DMNetworkGetEdgeOffset(DM dm,PetscInt p,PetscInt *offset)
435*24121865SAdrian Maldonado {
436*24121865SAdrian Maldonado   PetscErrorCode ierr;
437*24121865SAdrian Maldonado   DM_Network     *network = (DM_Network*)dm->data;
438*24121865SAdrian Maldonado 
439*24121865SAdrian Maldonado   PetscFunctionBegin;
440*24121865SAdrian Maldonado 
441*24121865SAdrian Maldonado   ierr = PetscSectionGetOffset(network->edge.DofSection,p,offset);CHKERRQ(ierr);
442*24121865SAdrian Maldonado   PetscFunctionReturn(0);
443*24121865SAdrian Maldonado }
444*24121865SAdrian Maldonado 
445*24121865SAdrian Maldonado #undef __FUNCT__
446*24121865SAdrian Maldonado #define __FUNCT__ "DMNetworkGetVertexOffset"
447*24121865SAdrian Maldonado /*@
448*24121865SAdrian Maldonado   DMNetworkGetVertexOffset - Get the offset for accessing the variable associated with the given vertex from the local subvector.
449*24121865SAdrian Maldonado 
450*24121865SAdrian Maldonado   Not Collective
451*24121865SAdrian Maldonado 
452*24121865SAdrian Maldonado   Input Parameters:
453*24121865SAdrian Maldonado + dm     - The DMNetwork object
454*24121865SAdrian Maldonado - p      - the vertex point
455*24121865SAdrian Maldonado 
456*24121865SAdrian Maldonado   Output Parameters:
457*24121865SAdrian Maldonado . offset - the offset
458*24121865SAdrian Maldonado 
459*24121865SAdrian Maldonado   Level: intermediate
460*24121865SAdrian Maldonado 
461*24121865SAdrian Maldonado .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector
462*24121865SAdrian Maldonado @*/
463*24121865SAdrian Maldonado PetscErrorCode DMNetworkGetVertexOffset(DM dm,PetscInt p,PetscInt *offset)
464*24121865SAdrian Maldonado {
465*24121865SAdrian Maldonado   PetscErrorCode ierr;
466*24121865SAdrian Maldonado   DM_Network     *network = (DM_Network*)dm->data;
467*24121865SAdrian Maldonado 
468*24121865SAdrian Maldonado   PetscFunctionBegin;
469*24121865SAdrian Maldonado 
470*24121865SAdrian Maldonado   p -= network->vStart;
471*24121865SAdrian Maldonado 
472*24121865SAdrian Maldonado   ierr = PetscSectionGetOffset(network->vertex.DofSection,p,offset);CHKERRQ(ierr);
473*24121865SAdrian Maldonado   PetscFunctionReturn(0);
474*24121865SAdrian Maldonado }
475*24121865SAdrian Maldonado #undef __FUNCT__
4765f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkAddNumVariables"
4775f2c45f1SShri Abhyankar /*@
4785f2c45f1SShri Abhyankar   DMNetworkAddNumVariables - Add number of variables associated with a given point.
4795f2c45f1SShri Abhyankar 
4805f2c45f1SShri Abhyankar   Not Collective
4815f2c45f1SShri Abhyankar 
4825f2c45f1SShri Abhyankar   Input Parameters:
4835f2c45f1SShri Abhyankar + dm   - The DMNetworkObject
4845f2c45f1SShri Abhyankar . p    - the vertex/edge point
4855f2c45f1SShri Abhyankar - nvar - number of additional variables
4865f2c45f1SShri Abhyankar 
4875f2c45f1SShri Abhyankar   Level: intermediate
4885f2c45f1SShri Abhyankar 
4895f2c45f1SShri Abhyankar .seealso: DMNetworkSetNumVariables
4905f2c45f1SShri Abhyankar @*/
4915f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddNumVariables(DM dm,PetscInt p,PetscInt nvar)
4925f2c45f1SShri Abhyankar {
4935f2c45f1SShri Abhyankar   PetscErrorCode ierr;
4945f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
4955f2c45f1SShri Abhyankar 
4965f2c45f1SShri Abhyankar   PetscFunctionBegin;
4975f2c45f1SShri Abhyankar   ierr = PetscSectionAddDof(network->DofSection,p,nvar);CHKERRQ(ierr);
4985f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
4995f2c45f1SShri Abhyankar }
5005f2c45f1SShri Abhyankar 
5015f2c45f1SShri Abhyankar #undef __FUNCT__
50227f51fceSHong Zhang #define __FUNCT__ "DMNetworkGetNumVariables"
50327f51fceSHong Zhang /*@
50427f51fceSHong Zhang   DMNetworkGetNumVariables - Gets number of variables for a vertex/edge point.
50527f51fceSHong Zhang 
50627f51fceSHong Zhang   Not Collective
50727f51fceSHong Zhang 
50827f51fceSHong Zhang   Input Parameters:
50927f51fceSHong Zhang + dm   - The DMNetworkObject
51027f51fceSHong Zhang - p    - the vertex/edge point
51127f51fceSHong Zhang 
51227f51fceSHong Zhang   Output Parameters:
51327f51fceSHong Zhang . nvar - number of variables
51427f51fceSHong Zhang 
51527f51fceSHong Zhang   Level: intermediate
51627f51fceSHong Zhang 
51727f51fceSHong Zhang .seealso: DMNetworkAddNumVariables, DMNetworkSddNumVariables
51827f51fceSHong Zhang @*/
51927f51fceSHong Zhang PetscErrorCode DMNetworkGetNumVariables(DM dm,PetscInt p,PetscInt *nvar)
52027f51fceSHong Zhang {
52127f51fceSHong Zhang   PetscErrorCode ierr;
52227f51fceSHong Zhang   DM_Network     *network = (DM_Network*)dm->data;
52327f51fceSHong Zhang 
52427f51fceSHong Zhang   PetscFunctionBegin;
52527f51fceSHong Zhang   ierr = PetscSectionGetDof(network->DofSection,p,nvar);CHKERRQ(ierr);
52627f51fceSHong Zhang   PetscFunctionReturn(0);
52727f51fceSHong Zhang }
52827f51fceSHong Zhang 
52927f51fceSHong Zhang #undef __FUNCT__
530662b5b01SHong Zhang #define __FUNCT__ "DMNetworkSetNumVariables"
5315f2c45f1SShri Abhyankar /*@
5325f2c45f1SShri Abhyankar   DMNetworkSetNumVariables - Sets number of variables for a vertex/edge point.
5335f2c45f1SShri Abhyankar 
5345f2c45f1SShri Abhyankar   Not Collective
5355f2c45f1SShri Abhyankar 
5365f2c45f1SShri Abhyankar   Input Parameters:
5375f2c45f1SShri Abhyankar + dm   - The DMNetworkObject
5385f2c45f1SShri Abhyankar . p    - the vertex/edge point
5395f2c45f1SShri Abhyankar - nvar - number of variables
5405f2c45f1SShri Abhyankar 
5415f2c45f1SShri Abhyankar   Level: intermediate
5425f2c45f1SShri Abhyankar 
5435f2c45f1SShri Abhyankar .seealso: DMNetworkAddNumVariables
5445f2c45f1SShri Abhyankar @*/
5455f2c45f1SShri Abhyankar PetscErrorCode DMNetworkSetNumVariables(DM dm,PetscInt p,PetscInt nvar)
5465f2c45f1SShri Abhyankar {
5475f2c45f1SShri Abhyankar   PetscErrorCode ierr;
5485f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
5495f2c45f1SShri Abhyankar 
5505f2c45f1SShri Abhyankar   PetscFunctionBegin;
5515f2c45f1SShri Abhyankar   ierr = PetscSectionSetDof(network->DofSection,p,nvar);CHKERRQ(ierr);
5525f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
5535f2c45f1SShri Abhyankar }
5545f2c45f1SShri Abhyankar 
5555f2c45f1SShri Abhyankar /* Sets up the array that holds the data for all components and its associated section. This
5565f2c45f1SShri Abhyankar    function is called during DMSetUp() */
5575f2c45f1SShri Abhyankar #undef __FUNCT__
5585f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkComponentSetUp"
5595f2c45f1SShri Abhyankar PetscErrorCode DMNetworkComponentSetUp(DM dm)
5605f2c45f1SShri Abhyankar {
5615f2c45f1SShri Abhyankar   PetscErrorCode              ierr;
5625f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
5635f2c45f1SShri Abhyankar   PetscInt                    arr_size;
5645f2c45f1SShri Abhyankar   PetscInt                    p,offset,offsetp;
5655f2c45f1SShri Abhyankar   DMNetworkComponentHeader header;
5665f2c45f1SShri Abhyankar   DMNetworkComponentValue  cvalue;
5675f2c45f1SShri Abhyankar   DMNetworkComponentGenericDataType      *componentdataarray;
5685f2c45f1SShri Abhyankar   PetscInt ncomp, i;
5695f2c45f1SShri Abhyankar 
5705f2c45f1SShri Abhyankar   PetscFunctionBegin;
5715f2c45f1SShri Abhyankar   ierr = PetscSectionSetUp(network->DataSection);CHKERRQ(ierr);
5725f2c45f1SShri Abhyankar   ierr = PetscSectionGetStorageSize(network->DataSection,&arr_size);CHKERRQ(ierr);
57375b160a0SShri Abhyankar   ierr = PetscMalloc1(arr_size,&network->componentdataarray);CHKERRQ(ierr);
5745f2c45f1SShri Abhyankar   componentdataarray = network->componentdataarray;
5755f2c45f1SShri Abhyankar   for (p = network->pStart; p < network->pEnd; p++) {
5765f2c45f1SShri Abhyankar     ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr);
5775f2c45f1SShri Abhyankar     /* Copy header */
5785f2c45f1SShri Abhyankar     header = &network->header[p];
579302440fdSBarry Smith     ierr = PetscMemcpy(componentdataarray+offsetp,header,network->dataheadersize*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr);
5805f2c45f1SShri Abhyankar     /* Copy data */
5815f2c45f1SShri Abhyankar     cvalue = &network->cvalue[p];
5825f2c45f1SShri Abhyankar     ncomp = header->ndata;
5835f2c45f1SShri Abhyankar     for (i = 0; i < ncomp; i++) {
5845f2c45f1SShri Abhyankar       offset = offsetp + network->dataheadersize + header->offset[i];
585302440fdSBarry Smith       ierr = PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr);
5865f2c45f1SShri Abhyankar     }
5875f2c45f1SShri Abhyankar   }
5885f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
5895f2c45f1SShri Abhyankar }
5905f2c45f1SShri Abhyankar 
5915f2c45f1SShri Abhyankar /* Sets up the section for dofs. This routine is called during DMSetUp() */
5925f2c45f1SShri Abhyankar #undef __FUNCT__
5935f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkVariablesSetUp"
5945f2c45f1SShri Abhyankar PetscErrorCode DMNetworkVariablesSetUp(DM dm)
5955f2c45f1SShri Abhyankar {
5965f2c45f1SShri Abhyankar   PetscErrorCode ierr;
5975f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
5985f2c45f1SShri Abhyankar 
5995f2c45f1SShri Abhyankar   PetscFunctionBegin;
6005f2c45f1SShri Abhyankar   ierr = PetscSectionSetUp(network->DofSection);CHKERRQ(ierr);
6015f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
6025f2c45f1SShri Abhyankar }
6035f2c45f1SShri Abhyankar 
6045f2c45f1SShri Abhyankar #undef __FUNCT__
6055f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetComponentDataArray"
6065f2c45f1SShri Abhyankar /*@C
6075f2c45f1SShri Abhyankar   DMNetworkGetComponentDataArray - Returns the component data array
6085f2c45f1SShri Abhyankar 
6095f2c45f1SShri Abhyankar   Not Collective
6105f2c45f1SShri Abhyankar 
6115f2c45f1SShri Abhyankar   Input Parameters:
6125f2c45f1SShri Abhyankar . dm - The DMNetwork Object
6135f2c45f1SShri Abhyankar 
6145f2c45f1SShri Abhyankar   Output Parameters:
6155f2c45f1SShri Abhyankar . componentdataarray - array that holds data for all components
6165f2c45f1SShri Abhyankar 
6175f2c45f1SShri Abhyankar   Level: intermediate
6185f2c45f1SShri Abhyankar 
6195f2c45f1SShri Abhyankar .seealso: DMNetworkGetComponentTypeOffset, DMNetworkGetNumComponents
6205f2c45f1SShri Abhyankar @*/
6215f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetComponentDataArray(DM dm,DMNetworkComponentGenericDataType **componentdataarray)
6225f2c45f1SShri Abhyankar {
6235f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
6245f2c45f1SShri Abhyankar 
6255f2c45f1SShri Abhyankar   PetscFunctionBegin;
6265f2c45f1SShri Abhyankar   *componentdataarray = network->componentdataarray;
6275f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
6285f2c45f1SShri Abhyankar }
6295f2c45f1SShri Abhyankar 
6305f2c45f1SShri Abhyankar #undef __FUNCT__
631*24121865SAdrian Maldonado #define __FUNCT__ "DMNetworkGetSubSection_private"
632*24121865SAdrian Maldonado /* Get a subsection from a range of points */
633*24121865SAdrian Maldonado PetscErrorCode DMNetworkGetSubSection_private(PetscSection master, PetscInt pstart, PetscInt pend,PetscSection *subsection)
634*24121865SAdrian Maldonado {
635*24121865SAdrian Maldonado   PetscErrorCode ierr;
636*24121865SAdrian Maldonado   PetscInt       i, nvar;
637*24121865SAdrian Maldonado 
638*24121865SAdrian Maldonado   PetscFunctionBegin;
639*24121865SAdrian Maldonado   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)master), subsection);CHKERRQ(ierr);
640*24121865SAdrian Maldonado   ierr = PetscSectionSetChart(*subsection, 0, pend - pstart);CHKERRQ(ierr);
641*24121865SAdrian Maldonado   for (i = pstart; i < pend; i++) {
642*24121865SAdrian Maldonado     ierr = PetscSectionGetDof(master,i,&nvar);CHKERRQ(ierr);
643*24121865SAdrian Maldonado     ierr = PetscSectionSetDof(*subsection, i - pstart, nvar);CHKERRQ(ierr);
644*24121865SAdrian Maldonado   }
645*24121865SAdrian Maldonado 
646*24121865SAdrian Maldonado   ierr = PetscSectionSetUp(*subsection);CHKERRQ(ierr);
647*24121865SAdrian Maldonado   PetscFunctionReturn(0);
648*24121865SAdrian Maldonado }
649*24121865SAdrian Maldonado 
650*24121865SAdrian Maldonado #undef __FUNCT__
651*24121865SAdrian Maldonado #define __FUNCT__ "DMNetworkSetSubMap_private"
652*24121865SAdrian Maldonado /* Create a submap of points with a GlobalToLocal structure */
653*24121865SAdrian Maldonado PetscErrorCode DMNetworkSetSubMap_private(PetscInt pstart, PetscInt pend, ISLocalToGlobalMapping *map)
654*24121865SAdrian Maldonado {
655*24121865SAdrian Maldonado   PetscErrorCode ierr;
656*24121865SAdrian Maldonado   PetscInt       i, *subpoints;
657*24121865SAdrian Maldonado 
658*24121865SAdrian Maldonado   PetscFunctionBegin;
659*24121865SAdrian Maldonado   /* Create index sets to map from "points" to "subpoints" */
660*24121865SAdrian Maldonado   ierr = PetscMalloc1(pend - pstart, &subpoints);CHKERRQ(ierr);
661*24121865SAdrian Maldonado   for (i = pstart; i < pend; i++) {
662*24121865SAdrian Maldonado     subpoints[i - pstart] = i;
663*24121865SAdrian Maldonado   }
664*24121865SAdrian Maldonado   ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,pend-pstart,subpoints,PETSC_COPY_VALUES,map);
665*24121865SAdrian Maldonado   ierr = PetscFree(subpoints);CHKERRQ(ierr);
666*24121865SAdrian Maldonado 
667*24121865SAdrian Maldonado   PetscFunctionReturn(0);
668*24121865SAdrian Maldonado }
669*24121865SAdrian Maldonado 
670*24121865SAdrian Maldonado #undef __FUNCT__
671*24121865SAdrian Maldonado #define __FUNCT__ "DMNetworkAssembleGraphStructures"
672*24121865SAdrian Maldonado /*@
673*24121865SAdrian Maldonado   DMNetworkAssembleGraphStructures - Assembles vertex and edge data structures. Must be called after DMNetworkDistribute.
674*24121865SAdrian Maldonado 
675*24121865SAdrian Maldonado   Collective
676*24121865SAdrian Maldonado 
677*24121865SAdrian Maldonado   Input Parameters:
678*24121865SAdrian Maldonado . dm   - The DMNetworkObject
679*24121865SAdrian Maldonado 
680*24121865SAdrian Maldonado   Note: the routine will create alternative orderings for the vertices and edges. Assume global network points are:
681*24121865SAdrian Maldonado 
682*24121865SAdrian Maldonado   points = [0 1 2 3 4 5 6]
683*24121865SAdrian Maldonado 
684*24121865SAdrian Maldonado   where edges = [0, 3] and vertices = [4, 6]. The new orderings will be specific to the subset (i.e vertices = [0, 2]).
685*24121865SAdrian Maldonado 
686*24121865SAdrian Maldonado   With this new ordering a local PetscSection, global PetscSection and PetscSF will be created specific to the subset.
687*24121865SAdrian Maldonado 
688*24121865SAdrian Maldonado   Level: intermediate
689*24121865SAdrian Maldonado 
690*24121865SAdrian Maldonado @*/
691*24121865SAdrian Maldonado PetscErrorCode DMNetworkAssembleGraphStructures(DM dm)
692*24121865SAdrian Maldonado {
693*24121865SAdrian Maldonado   PetscErrorCode ierr;
694*24121865SAdrian Maldonado   MPI_Comm               comm;
695*24121865SAdrian Maldonado   PetscMPIInt            rank, numProcs;
696*24121865SAdrian Maldonado   DM_Network     *network = (DM_Network*)dm->data;
697*24121865SAdrian Maldonado   PetscFunctionBegin;
698*24121865SAdrian Maldonado 
699*24121865SAdrian Maldonado   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
700*24121865SAdrian Maldonado   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
701*24121865SAdrian Maldonado   ierr = MPI_Comm_size(comm, &numProcs);CHKERRQ(ierr);
702*24121865SAdrian Maldonado 
703*24121865SAdrian Maldonado   /* Create maps for vertices and edges */
704*24121865SAdrian Maldonado   ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr);
705*24121865SAdrian Maldonado   ierr = DMNetworkSetSubMap_private(network->eStart,network->eEnd,&network->edge.mapping);CHKERRQ(ierr);
706*24121865SAdrian Maldonado 
707*24121865SAdrian Maldonado   /* Create local sub-sections */
708*24121865SAdrian Maldonado   ierr = DMNetworkGetSubSection_private(network->DofSection,network->vStart,network->vEnd,&network->vertex.DofSection);CHKERRQ(ierr);
709*24121865SAdrian Maldonado   ierr = DMNetworkGetSubSection_private(network->DofSection,network->eStart,network->eEnd,&network->edge.DofSection);CHKERRQ(ierr);
710*24121865SAdrian Maldonado 
711*24121865SAdrian Maldonado   if (numProcs > 1) {
712*24121865SAdrian Maldonado     ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr);
713*24121865SAdrian Maldonado     ierr = PetscSectionCreateGlobalSection(network->vertex.DofSection, network->vertex.sf, PETSC_FALSE, PETSC_FALSE, &network->vertex.GlobalDofSection);CHKERRQ(ierr);
714*24121865SAdrian Maldonado   ierr = PetscSFGetSubSF(network->plex->sf, network->edge.mapping, &network->edge.sf);CHKERRQ(ierr);
715*24121865SAdrian Maldonado   ierr = PetscSectionCreateGlobalSection(network->edge.DofSection, network->edge.sf, PETSC_FALSE, PETSC_FALSE, &network->edge.GlobalDofSection);CHKERRQ(ierr);
716*24121865SAdrian Maldonado   } else {
717*24121865SAdrian Maldonado   /* create structures for vertex */
718*24121865SAdrian Maldonado   ierr = PetscSectionClone(network->vertex.DofSection,&network->vertex.GlobalDofSection);CHKERRQ(ierr);
719*24121865SAdrian Maldonado   /* create structures for edge */
720*24121865SAdrian Maldonado   ierr = PetscSectionClone(network->edge.DofSection,&network->edge.GlobalDofSection);CHKERRQ(ierr);
721*24121865SAdrian Maldonado   }
722*24121865SAdrian Maldonado 
723*24121865SAdrian Maldonado 
724*24121865SAdrian Maldonado   /* Add viewers */
725*24121865SAdrian Maldonado   ierr = PetscObjectSetName((PetscObject)network->edge.GlobalDofSection,"Global edge dof section");CHKERRQ(ierr);
726*24121865SAdrian Maldonado   ierr = PetscObjectSetName((PetscObject)network->vertex.GlobalDofSection,"Global vertex dof section");CHKERRQ(ierr);
727*24121865SAdrian Maldonado   ierr = PetscSectionViewFromOptions(network->edge.GlobalDofSection, NULL, "-edge_global_section_view");CHKERRQ(ierr);
728*24121865SAdrian Maldonado   ierr = PetscSectionViewFromOptions(network->vertex.GlobalDofSection, NULL, "-vertex_global_section_view");CHKERRQ(ierr);
729*24121865SAdrian Maldonado 
730*24121865SAdrian Maldonado   PetscFunctionReturn(0);
731*24121865SAdrian Maldonado }
732*24121865SAdrian Maldonado #undef __FUNCT__
7335f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkDistribute"
7345f2c45f1SShri Abhyankar /*@
7355f2c45f1SShri Abhyankar   DMNetworkDistribute - Distributes the network and moves associated component data.
7365f2c45f1SShri Abhyankar 
7375f2c45f1SShri Abhyankar   Collective
7385f2c45f1SShri Abhyankar 
7395f2c45f1SShri Abhyankar   Input Parameter:
7405f2c45f1SShri Abhyankar + oldDM - the original DMNetwork object
7415f2c45f1SShri Abhyankar - overlap - The overlap of partitions, 0 is the default
7425f2c45f1SShri Abhyankar 
7435f2c45f1SShri Abhyankar   Output Parameter:
7445f2c45f1SShri Abhyankar . distDM - the distributed DMNetwork object
7455f2c45f1SShri Abhyankar 
7465f2c45f1SShri Abhyankar   Notes:
7475f2c45f1SShri Abhyankar   This routine should be called only when using multiple processors.
7485f2c45f1SShri Abhyankar 
7498b171c8eSHong Zhang   Distributes the network with <overlap>-overlapping partitioning of the edges.
7505f2c45f1SShri Abhyankar 
7515f2c45f1SShri Abhyankar   Level: intermediate
7525f2c45f1SShri Abhyankar 
7535f2c45f1SShri Abhyankar .seealso: DMNetworkCreate
7545f2c45f1SShri Abhyankar @*/
75580cf41d5SMatthew G. Knepley PetscErrorCode DMNetworkDistribute(DM oldDM, PetscInt overlap,DM *distDM)
7565f2c45f1SShri Abhyankar {
7575f2c45f1SShri Abhyankar   PetscErrorCode ierr;
7585f2c45f1SShri Abhyankar   DM_Network     *oldDMnetwork = (DM_Network*)oldDM->data;
7595f2c45f1SShri Abhyankar   PetscSF        pointsf;
7605f2c45f1SShri Abhyankar   DM             newDM;
7615f2c45f1SShri Abhyankar   DM_Network     *newDMnetwork;
7625f2c45f1SShri Abhyankar 
7635f2c45f1SShri Abhyankar   PetscFunctionBegin;
7645f2c45f1SShri Abhyankar   ierr = DMNetworkCreate(PetscObjectComm((PetscObject)oldDM),&newDM);CHKERRQ(ierr);
7655f2c45f1SShri Abhyankar   newDMnetwork = (DM_Network*)newDM->data;
7665f2c45f1SShri Abhyankar   newDMnetwork->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType);
7675f2c45f1SShri Abhyankar   /* Distribute plex dm and dof section */
76880cf41d5SMatthew G. Knepley   ierr = DMPlexDistribute(oldDMnetwork->plex,overlap,&pointsf,&newDMnetwork->plex);CHKERRQ(ierr);
7695f2c45f1SShri Abhyankar   /* Distribute dof section */
7705f2c45f1SShri Abhyankar   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)oldDM),&newDMnetwork->DofSection);CHKERRQ(ierr);
7715f2c45f1SShri Abhyankar   ierr = PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);CHKERRQ(ierr);
7725f2c45f1SShri Abhyankar   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)oldDM),&newDMnetwork->DataSection);CHKERRQ(ierr);
7735f2c45f1SShri Abhyankar   /* Distribute data and associated section */
77431da1fc8SHong Zhang   ierr = DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPIU_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);CHKERRQ(ierr);
775*24121865SAdrian Maldonado 
7765f2c45f1SShri Abhyankar 
7775f2c45f1SShri Abhyankar   ierr = PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);CHKERRQ(ierr);
7785f2c45f1SShri Abhyankar   ierr = DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);CHKERRQ(ierr);
7795f2c45f1SShri Abhyankar   ierr = DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);CHKERRQ(ierr);
7805f2c45f1SShri Abhyankar   newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart;
7815f2c45f1SShri Abhyankar   newDMnetwork->nNodes = newDMnetwork->vEnd - newDMnetwork->vStart;
7825f2c45f1SShri Abhyankar   newDMnetwork->NNodes = oldDMnetwork->NNodes;
7835f2c45f1SShri Abhyankar   newDMnetwork->NEdges = oldDMnetwork->NEdges;
784*24121865SAdrian Maldonado 
7855f2c45f1SShri Abhyankar   /* Set Dof section as the default section for dm */
7865f2c45f1SShri Abhyankar   ierr = DMSetDefaultSection(newDMnetwork->plex,newDMnetwork->DofSection);CHKERRQ(ierr);
7875f2c45f1SShri Abhyankar   ierr = DMGetDefaultGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);CHKERRQ(ierr);
7885f2c45f1SShri Abhyankar 
789*24121865SAdrian Maldonado   /* Destroy point SF */
790*24121865SAdrian Maldonado   ierr = PetscSFDestroy(&pointsf);CHKERRQ(ierr);
791*24121865SAdrian Maldonado 
7925f2c45f1SShri Abhyankar   *distDM = newDM;
7935f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
7945f2c45f1SShri Abhyankar }
7955f2c45f1SShri Abhyankar 
7965f2c45f1SShri Abhyankar #undef __FUNCT__
797*24121865SAdrian Maldonado #define __FUNCT__ "PetscSFGetSubSF"
798*24121865SAdrian Maldonado /*@C
799*24121865SAdrian Maldonado   PetscSFGetSubSF - Returns an SF for a specific subset of points. Leaves are re-numbered to reflect the new ordering.
800*24121865SAdrian Maldonado 
801*24121865SAdrian Maldonado   Input Parameters:
802*24121865SAdrian Maldonado + masterSF - the original SF structure
803*24121865SAdrian Maldonado - map      - a ISLocalToGlobal mapping that contains the subset of points
804*24121865SAdrian Maldonado 
805*24121865SAdrian Maldonado   Output Parameters:
806*24121865SAdrian Maldonado . subSF    - a subset of the masterSF for the desired subset.
807*24121865SAdrian Maldonado */
808*24121865SAdrian Maldonado 
809*24121865SAdrian Maldonado PetscErrorCode PetscSFGetSubSF(PetscSF mastersf, ISLocalToGlobalMapping map, PetscSF *subSF) {
810*24121865SAdrian Maldonado 
811*24121865SAdrian Maldonado   PetscErrorCode        ierr;
812*24121865SAdrian Maldonado   PetscInt              nroots, nleaves, *ilocal_sub;
813*24121865SAdrian Maldonado   PetscInt              i, *ilocal_map, nroots_sub, nleaves_sub = 0;
814*24121865SAdrian Maldonado   PetscInt              *local_points, *remote_points;
815*24121865SAdrian Maldonado   PetscSFNode           *iremote_sub;
816*24121865SAdrian Maldonado   const PetscInt        *ilocal;
817*24121865SAdrian Maldonado   const PetscSFNode     *iremote;
818*24121865SAdrian Maldonado 
819*24121865SAdrian Maldonado   PetscFunctionBegin;
820*24121865SAdrian Maldonado   ierr = PetscSFGetGraph(mastersf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr);
821*24121865SAdrian Maldonado 
822*24121865SAdrian Maldonado   /* Look for leaves that pertain to the subset of points. Get the local ordering */
823*24121865SAdrian Maldonado   ierr = PetscMalloc1(nleaves,&ilocal_map);CHKERRQ(ierr);
824*24121865SAdrian Maldonado   ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nleaves,ilocal,NULL,ilocal_map);CHKERRQ(ierr);
825*24121865SAdrian Maldonado   for (i = 0; i < nleaves; i++) {
826*24121865SAdrian Maldonado     if (ilocal_map[i] != -1) nleaves_sub += 1;
827*24121865SAdrian Maldonado   }
828*24121865SAdrian Maldonado   /* Re-number ilocal with subset numbering. Need information from roots */
829*24121865SAdrian Maldonado   ierr = PetscMalloc2(nroots,&local_points,nroots,&remote_points);CHKERRQ(ierr);
830*24121865SAdrian Maldonado   for (i = 0; i < nroots; i++) local_points[i] = i;
831*24121865SAdrian Maldonado   ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nroots,local_points,NULL,local_points);CHKERRQ(ierr);
832*24121865SAdrian Maldonado   ierr = PetscSFBcastBegin(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr);
833*24121865SAdrian Maldonado   ierr = PetscSFBcastEnd(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr);
834*24121865SAdrian Maldonado   /* Fill up graph using local (that is, local to the subset) numbering. */
835*24121865SAdrian Maldonado   ierr = PetscMalloc2(nleaves_sub,&ilocal_sub,nleaves_sub,&iremote_sub);CHKERRQ(ierr);
836*24121865SAdrian Maldonado   nleaves_sub = 0;
837*24121865SAdrian Maldonado   for (i = 0; i < nleaves; i++) {
838*24121865SAdrian Maldonado     if (ilocal_map[i] != -1) {
839*24121865SAdrian Maldonado       ilocal_sub[nleaves_sub] = ilocal_map[i];
840*24121865SAdrian Maldonado       iremote_sub[nleaves_sub] = iremote[i];
841*24121865SAdrian Maldonado       iremote_sub[nleaves_sub].index = remote_points[ilocal[i]];
842*24121865SAdrian Maldonado       nleaves_sub += 1;
843*24121865SAdrian Maldonado     }
844*24121865SAdrian Maldonado   }
845*24121865SAdrian Maldonado   ierr = PetscFree2(local_points,remote_points);CHKERRQ(ierr);
846*24121865SAdrian Maldonado   ierr = ISLocalToGlobalMappingGetSize(map,&nroots_sub);CHKERRQ(ierr);
847*24121865SAdrian Maldonado 
848*24121865SAdrian Maldonado   /* Create new subSF */
849*24121865SAdrian Maldonado   ierr = PetscSFCreate(PETSC_COMM_WORLD,subSF);CHKERRQ(ierr);
850*24121865SAdrian Maldonado   ierr = PetscSFSetFromOptions(*subSF);CHKERRQ(ierr);
851*24121865SAdrian Maldonado   ierr = PetscSFSetGraph(*subSF,nroots_sub,nleaves_sub,ilocal_sub,PETSC_OWN_POINTER,iremote_sub,PETSC_OWN_POINTER);CHKERRQ(ierr);
852*24121865SAdrian Maldonado   ierr = PetscFree(ilocal_map);CHKERRQ(ierr);
853*24121865SAdrian Maldonado 
854*24121865SAdrian Maldonado   PetscFunctionReturn(0);
855*24121865SAdrian Maldonado }
856*24121865SAdrian Maldonado 
857*24121865SAdrian Maldonado 
858*24121865SAdrian Maldonado #undef __FUNCT__
8595f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetSupportingEdges"
8605f2c45f1SShri Abhyankar /*@C
8615f2c45f1SShri Abhyankar   DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point
8625f2c45f1SShri Abhyankar 
8635f2c45f1SShri Abhyankar   Not Collective
8645f2c45f1SShri Abhyankar 
8655f2c45f1SShri Abhyankar   Input Parameters:
8665f2c45f1SShri Abhyankar + dm - The DMNetwork object
8675f2c45f1SShri Abhyankar - p  - the vertex point
8685f2c45f1SShri Abhyankar 
8695f2c45f1SShri Abhyankar   Output Paramters:
8705f2c45f1SShri Abhyankar + nedges - number of edges connected to this vertex point
8715f2c45f1SShri Abhyankar - edges  - List of edge points
8725f2c45f1SShri Abhyankar 
8735f2c45f1SShri Abhyankar   Level: intermediate
8745f2c45f1SShri Abhyankar 
8755f2c45f1SShri Abhyankar   Fortran Notes:
8765f2c45f1SShri Abhyankar   Since it returns an array, this routine is only available in Fortran 90, and you must
8775f2c45f1SShri Abhyankar   include petsc.h90 in your code.
8785f2c45f1SShri Abhyankar 
8795f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkGetConnectedNodes
8805f2c45f1SShri Abhyankar @*/
8815f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[])
8825f2c45f1SShri Abhyankar {
8835f2c45f1SShri Abhyankar   PetscErrorCode ierr;
8845f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
8855f2c45f1SShri Abhyankar 
8865f2c45f1SShri Abhyankar   PetscFunctionBegin;
8875f2c45f1SShri Abhyankar   ierr = DMPlexGetSupportSize(network->plex,vertex,nedges);CHKERRQ(ierr);
8885f2c45f1SShri Abhyankar   ierr = DMPlexGetSupport(network->plex,vertex,edges);CHKERRQ(ierr);
8895f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
8905f2c45f1SShri Abhyankar }
8915f2c45f1SShri Abhyankar 
8925f2c45f1SShri Abhyankar #undef __FUNCT__
8935f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetConnectedNodes"
8945f2c45f1SShri Abhyankar /*@C
895596e729fSHong Zhang   DMNetworkGetConnectedNodes - Return the connected vertices for this edge point
8965f2c45f1SShri Abhyankar 
8975f2c45f1SShri Abhyankar   Not Collective
8985f2c45f1SShri Abhyankar 
8995f2c45f1SShri Abhyankar   Input Parameters:
9005f2c45f1SShri Abhyankar + dm - The DMNetwork object
9015f2c45f1SShri Abhyankar - p  - the edge point
9025f2c45f1SShri Abhyankar 
9035f2c45f1SShri Abhyankar   Output Paramters:
9045f2c45f1SShri Abhyankar . vertices  - vertices connected to this edge
9055f2c45f1SShri Abhyankar 
9065f2c45f1SShri Abhyankar   Level: intermediate
9075f2c45f1SShri Abhyankar 
9085f2c45f1SShri Abhyankar   Fortran Notes:
9095f2c45f1SShri Abhyankar   Since it returns an array, this routine is only available in Fortran 90, and you must
9105f2c45f1SShri Abhyankar   include petsc.h90 in your code.
9115f2c45f1SShri Abhyankar 
9125f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkGetSupportingEdges
9135f2c45f1SShri Abhyankar @*/
9145f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetConnectedNodes(DM dm,PetscInt edge,const PetscInt *vertices[])
9155f2c45f1SShri Abhyankar {
9165f2c45f1SShri Abhyankar   PetscErrorCode ierr;
9175f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
9185f2c45f1SShri Abhyankar 
9195f2c45f1SShri Abhyankar   PetscFunctionBegin;
9205f2c45f1SShri Abhyankar   ierr = DMPlexGetCone(network->plex,edge,vertices);CHKERRQ(ierr);
9215f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
9225f2c45f1SShri Abhyankar }
9235f2c45f1SShri Abhyankar 
9245f2c45f1SShri Abhyankar #undef __FUNCT__
9255f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkIsGhostVertex"
9265f2c45f1SShri Abhyankar /*@
9275f2c45f1SShri Abhyankar   DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex
9285f2c45f1SShri Abhyankar 
9295f2c45f1SShri Abhyankar   Not Collective
9305f2c45f1SShri Abhyankar 
9315f2c45f1SShri Abhyankar   Input Parameters:
9325f2c45f1SShri Abhyankar + dm - The DMNetwork object
9335f2c45f1SShri Abhyankar . p  - the vertex point
9345f2c45f1SShri Abhyankar 
9355f2c45f1SShri Abhyankar   Output Parameter:
9365f2c45f1SShri Abhyankar . isghost - TRUE if the vertex is a ghost point
9375f2c45f1SShri Abhyankar 
9385f2c45f1SShri Abhyankar   Level: intermediate
9395f2c45f1SShri Abhyankar 
9405f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkGetConnectedNodes, DMNetworkGetVertexRange
9415f2c45f1SShri Abhyankar @*/
9425f2c45f1SShri Abhyankar PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost)
9435f2c45f1SShri Abhyankar {
9445f2c45f1SShri Abhyankar   PetscErrorCode ierr;
9455f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
9465f2c45f1SShri Abhyankar   PetscInt       offsetg;
9475f2c45f1SShri Abhyankar   PetscSection   sectiong;
9485f2c45f1SShri Abhyankar 
9495f2c45f1SShri Abhyankar   PetscFunctionBegin;
9505f2c45f1SShri Abhyankar   *isghost = PETSC_FALSE;
9515f2c45f1SShri Abhyankar   ierr = DMGetDefaultGlobalSection(network->plex,&sectiong);CHKERRQ(ierr);
9525f2c45f1SShri Abhyankar   ierr = PetscSectionGetOffset(sectiong,p,&offsetg);CHKERRQ(ierr);
9535f2c45f1SShri Abhyankar   if (offsetg < 0) *isghost = PETSC_TRUE;
9545f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
9555f2c45f1SShri Abhyankar }
9565f2c45f1SShri Abhyankar 
9575f2c45f1SShri Abhyankar #undef __FUNCT__
9585f2c45f1SShri Abhyankar #define __FUNCT__ "DMSetUp_Network"
9595f2c45f1SShri Abhyankar PetscErrorCode DMSetUp_Network(DM dm)
9605f2c45f1SShri Abhyankar {
9615f2c45f1SShri Abhyankar   PetscErrorCode ierr;
9625f2c45f1SShri Abhyankar   DM_Network     *network=(DM_Network*)dm->data;
9635f2c45f1SShri Abhyankar 
9645f2c45f1SShri Abhyankar   PetscFunctionBegin;
9655f2c45f1SShri Abhyankar   ierr = DMNetworkComponentSetUp(dm);CHKERRQ(ierr);
9665f2c45f1SShri Abhyankar   ierr = DMNetworkVariablesSetUp(dm);CHKERRQ(ierr);
9675f2c45f1SShri Abhyankar 
9685f2c45f1SShri Abhyankar   ierr = DMSetDefaultSection(network->plex,network->DofSection);CHKERRQ(ierr);
9695f2c45f1SShri Abhyankar   ierr = DMGetDefaultGlobalSection(network->plex,&network->GlobalDofSection);CHKERRQ(ierr);
9705f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
9715f2c45f1SShri Abhyankar }
9725f2c45f1SShri Abhyankar 
9735f2c45f1SShri Abhyankar #undef __FUNCT__
97417df6e9eSHong Zhang #define __FUNCT__ "DMNetworkHasJacobian"
9751ad426b7SHong Zhang /*@
97617df6e9eSHong Zhang     DMNetworkHasJacobian - Sets global flag for using user's sub Jacobian matrices
9771ad426b7SHong Zhang                             -- replaced by DMNetworkSetOption(network,userjacobian,PETSC_TURE)?
9781ad426b7SHong Zhang 
9791ad426b7SHong Zhang     Collective
9801ad426b7SHong Zhang 
9811ad426b7SHong Zhang     Input Parameters:
98283b2e829SHong Zhang +   dm - The DMNetwork object
98383b2e829SHong Zhang .   eflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for edges
98483b2e829SHong Zhang -   vflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for vertices
9851ad426b7SHong Zhang 
9861ad426b7SHong Zhang     Level: intermediate
9871ad426b7SHong Zhang 
9881ad426b7SHong Zhang @*/
98983b2e829SHong Zhang PetscErrorCode DMNetworkHasJacobian(DM dm,PetscBool eflg,PetscBool vflg)
9901ad426b7SHong Zhang {
9911ad426b7SHong Zhang   DM_Network     *network=(DM_Network*)dm->data;
9921ad426b7SHong Zhang 
9931ad426b7SHong Zhang   PetscFunctionBegin;
99483b2e829SHong Zhang   network->userEdgeJacobian   = eflg;
99583b2e829SHong Zhang   network->userVertexJacobian = vflg;
9961ad426b7SHong Zhang   PetscFunctionReturn(0);
9971ad426b7SHong Zhang }
9981ad426b7SHong Zhang 
9991ad426b7SHong Zhang #undef __FUNCT__
100083b2e829SHong Zhang #define __FUNCT__ "DMNetworkEdgeSetMatrix"
10011ad426b7SHong Zhang /*@
100283b2e829SHong Zhang     DMNetworkEdgeSetMatrix - Sets user-provided Jacobian matrices for this edge to the network
100383b2e829SHong Zhang 
100483b2e829SHong Zhang     Not Collective
100583b2e829SHong Zhang 
100683b2e829SHong Zhang     Input Parameters:
100783b2e829SHong Zhang +   dm - The DMNetwork object
100883b2e829SHong Zhang .   p  - the edge point
10093e97b6e8SHong Zhang -   J - array (size = 3) of Jacobian submatrices for this edge point:
10103e97b6e8SHong Zhang         J[0]: this edge
10113e97b6e8SHong Zhang         J[1] and J[2]: connected vertices, obtained by calling DMNetworkGetConnectedNodes()
101283b2e829SHong Zhang 
101383b2e829SHong Zhang     Level: intermediate
101483b2e829SHong Zhang 
101583b2e829SHong Zhang .seealso: DMNetworkVertexSetMatrix
101683b2e829SHong Zhang @*/
101783b2e829SHong Zhang PetscErrorCode DMNetworkEdgeSetMatrix(DM dm,PetscInt p,Mat J[])
101883b2e829SHong Zhang {
101983b2e829SHong Zhang   PetscErrorCode ierr;
102083b2e829SHong Zhang   DM_Network     *network=(DM_Network*)dm->data;
102183b2e829SHong Zhang 
102283b2e829SHong Zhang   PetscFunctionBegin;
1023883e35e8SHong Zhang   if (!network->userEdgeJacobian) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkEdgeSetMatrix");
102483b2e829SHong Zhang   if (!network->Je) {
1025883e35e8SHong Zhang     ierr = PetscCalloc1(3*network->nEdges,&network->Je);CHKERRQ(ierr);
102683b2e829SHong Zhang   }
1027883e35e8SHong Zhang   network->Je[3*p]   = J[0];
1028883e35e8SHong Zhang   network->Je[3*p+1] = J[1];
1029883e35e8SHong Zhang   network->Je[3*p+2] = J[2];
103083b2e829SHong Zhang   PetscFunctionReturn(0);
103183b2e829SHong Zhang }
103283b2e829SHong Zhang 
103383b2e829SHong Zhang #undef __FUNCT__
1034883e35e8SHong Zhang #define __FUNCT__ "DMNetworkVertexSetMatrix"
103583b2e829SHong Zhang /*@
103676ddfea5SHong Zhang     DMNetworkVertexSetMatrix - Sets user-provided Jacobian matrix for this vertex to the network
10371ad426b7SHong Zhang 
10381ad426b7SHong Zhang     Not Collective
10391ad426b7SHong Zhang 
10401ad426b7SHong Zhang     Input Parameters:
10411ad426b7SHong Zhang +   dm - The DMNetwork object
10421ad426b7SHong Zhang .   p  - the vertex point
10433e97b6e8SHong Zhang -   J - array of Jacobian (size = 2*(num of supporting edges) + 1) submatrices for this vertex point:
10443e97b6e8SHong Zhang         J[0]:       this vertex
10453e97b6e8SHong Zhang         J[1+2*i]:   i-th supporting edge
10463e97b6e8SHong Zhang         J[1+2*i+1]: i-th connected vertex
10471ad426b7SHong Zhang 
10481ad426b7SHong Zhang     Level: intermediate
10491ad426b7SHong Zhang 
105083b2e829SHong Zhang .seealso: DMNetworkEdgeSetMatrix
10511ad426b7SHong Zhang @*/
1052883e35e8SHong Zhang PetscErrorCode DMNetworkVertexSetMatrix(DM dm,PetscInt p,Mat J[])
10535f2c45f1SShri Abhyankar {
10545f2c45f1SShri Abhyankar   PetscErrorCode ierr;
10555f2c45f1SShri Abhyankar   DM_Network     *network=(DM_Network*)dm->data;
1056f4431b8cSHong Zhang   PetscInt       i,*vptr,nedges,vStart,vEnd;
1057883e35e8SHong Zhang   const PetscInt *edges;
10585f2c45f1SShri Abhyankar 
10595f2c45f1SShri Abhyankar   PetscFunctionBegin;
1060883e35e8SHong Zhang   if (!network->userVertexJacobian) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkVertexSetMatrix");
1061883e35e8SHong Zhang 
1062883e35e8SHong Zhang   ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr);
1063f4431b8cSHong Zhang 
106483b2e829SHong Zhang   if (!network->Jv) {
1065f4431b8cSHong Zhang     PetscInt nNodes = network->nNodes,nedges_total;
1066883e35e8SHong Zhang     /* count nvertex_total */
10673e97b6e8SHong Zhang     nedges_total = 0;
1068883e35e8SHong Zhang     ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr);
1069f4431b8cSHong Zhang     ierr = PetscMalloc1(nNodes+1,&vptr);CHKERRQ(ierr);
1070f4431b8cSHong Zhang 
1071883e35e8SHong Zhang     vptr[0] = 0;
1072f4431b8cSHong Zhang     for (i=0; i<nNodes; i++) {
1073f4431b8cSHong Zhang       ierr = DMNetworkGetSupportingEdges(dm,i+vStart,&nedges,&edges);CHKERRQ(ierr);
1074883e35e8SHong Zhang       nedges_total += nedges;
1075f4431b8cSHong Zhang       vptr[i+1] = vptr[i] + 2*nedges + 1;
10761ad426b7SHong Zhang     }
10773e97b6e8SHong Zhang 
1078f4431b8cSHong Zhang     ierr = PetscCalloc1(2*nedges_total+nNodes,&network->Jv);CHKERRQ(ierr);
1079883e35e8SHong Zhang     network->Jvptr = vptr;
1080883e35e8SHong Zhang   }
1081883e35e8SHong Zhang 
1082883e35e8SHong Zhang   vptr = network->Jvptr;
10833e97b6e8SHong Zhang   network->Jv[vptr[p-vStart]] = J[0]; /* Set Jacobian for this vertex */
10843e97b6e8SHong Zhang 
10853e97b6e8SHong Zhang   /* Set Jacobian for each supporting edge and connected vertex */
1086883e35e8SHong Zhang   ierr = DMNetworkGetSupportingEdges(dm,p,&nedges,&edges);CHKERRQ(ierr);
1087883e35e8SHong Zhang   for (i=1; i<=2*nedges; i++) network->Jv[vptr[p-vStart]+i] = J[i];
1088883e35e8SHong Zhang   PetscFunctionReturn(0);
1089883e35e8SHong Zhang }
1090883e35e8SHong Zhang 
1091883e35e8SHong Zhang #undef __FUNCT__
10925cf7da58SHong Zhang #define __FUNCT__ "MatSetPreallocationDenseblock_private"
1093e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz)
10945cf7da58SHong Zhang {
10955cf7da58SHong Zhang   PetscErrorCode ierr;
10965cf7da58SHong Zhang   PetscInt       j;
10975cf7da58SHong Zhang   PetscScalar    val=(PetscScalar)ncols;
10985cf7da58SHong Zhang 
10995cf7da58SHong Zhang   PetscFunctionBegin;
11005cf7da58SHong Zhang   if (!ghost) {
11015cf7da58SHong Zhang     for (j=0; j<nrows; j++) {
11025cf7da58SHong Zhang       ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr);
11035cf7da58SHong Zhang     }
11045cf7da58SHong Zhang   } else {
11055cf7da58SHong Zhang     for (j=0; j<nrows; j++) {
11065cf7da58SHong Zhang       ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr);
11075cf7da58SHong Zhang     }
11085cf7da58SHong Zhang   }
11095cf7da58SHong Zhang   PetscFunctionReturn(0);
11105cf7da58SHong Zhang }
11115cf7da58SHong Zhang 
11125cf7da58SHong Zhang #undef __FUNCT__
11135cf7da58SHong Zhang #define __FUNCT__ "MatSetPreallocationUserblock_private"
1114e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz)
11155cf7da58SHong Zhang {
11165cf7da58SHong Zhang   PetscErrorCode ierr;
11175cf7da58SHong Zhang   PetscInt       j,ncols_u;
11185cf7da58SHong Zhang   PetscScalar    val;
11195cf7da58SHong Zhang 
11205cf7da58SHong Zhang   PetscFunctionBegin;
11215cf7da58SHong Zhang   if (!ghost) {
11225cf7da58SHong Zhang     for (j=0; j<nrows; j++) {
11235cf7da58SHong Zhang       ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr);
11245cf7da58SHong Zhang       val = (PetscScalar)ncols_u;
11255cf7da58SHong Zhang       ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr);
11265cf7da58SHong Zhang       ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr);
11275cf7da58SHong Zhang     }
11285cf7da58SHong Zhang   } else {
11295cf7da58SHong Zhang     for (j=0; j<nrows; j++) {
11305cf7da58SHong Zhang       ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr);
11315cf7da58SHong Zhang       val = (PetscScalar)ncols_u;
11325cf7da58SHong Zhang       ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr);
11335cf7da58SHong Zhang       ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr);
11345cf7da58SHong Zhang     }
11355cf7da58SHong Zhang   }
11365cf7da58SHong Zhang   PetscFunctionReturn(0);
11375cf7da58SHong Zhang }
11385cf7da58SHong Zhang 
11395cf7da58SHong Zhang #undef __FUNCT__
11405cf7da58SHong Zhang #define __FUNCT__ "MatSetPreallocationblock_private"
1141e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz)
11425cf7da58SHong Zhang {
11435cf7da58SHong Zhang   PetscErrorCode ierr;
11445cf7da58SHong Zhang 
11455cf7da58SHong Zhang   PetscFunctionBegin;
11465cf7da58SHong Zhang   if (Ju) {
11475cf7da58SHong Zhang     ierr = MatSetPreallocationUserblock_private(Ju,nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr);
11485cf7da58SHong Zhang   } else {
11495cf7da58SHong Zhang     ierr = MatSetPreallocationDenseblock_private(nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr);
11505cf7da58SHong Zhang   }
11515cf7da58SHong Zhang   PetscFunctionReturn(0);
11525cf7da58SHong Zhang }
11535cf7da58SHong Zhang 
11545cf7da58SHong Zhang #undef __FUNCT__
1155883e35e8SHong Zhang #define __FUNCT__ "MatSetDenseblock_private"
1156e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J)
1157883e35e8SHong Zhang {
1158883e35e8SHong Zhang   PetscErrorCode ierr;
1159883e35e8SHong Zhang   PetscInt       j,*cols;
1160883e35e8SHong Zhang   PetscScalar    *zeros;
1161883e35e8SHong Zhang 
1162883e35e8SHong Zhang   PetscFunctionBegin;
1163883e35e8SHong Zhang   ierr = PetscCalloc2(ncols,&cols,nrows*ncols,&zeros);CHKERRQ(ierr);
1164883e35e8SHong Zhang   for (j=0; j<ncols; j++) cols[j] = j+ cstart;
1165883e35e8SHong Zhang   ierr = MatSetValues(*J,nrows,rows,ncols,cols,zeros,INSERT_VALUES);CHKERRQ(ierr);
1166883e35e8SHong Zhang   ierr = PetscFree2(cols,zeros);CHKERRQ(ierr);
11671ad426b7SHong Zhang   PetscFunctionReturn(0);
11681ad426b7SHong Zhang }
1169a4e85ca8SHong Zhang 
11703e97b6e8SHong Zhang #undef __FUNCT__
11713e97b6e8SHong Zhang #define __FUNCT__ "MatSetUserblock_private"
1172e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J)
11733e97b6e8SHong Zhang {
11743e97b6e8SHong Zhang   PetscErrorCode ierr;
11753e97b6e8SHong Zhang   PetscInt       j,M,N,row,col,ncols_u;
11763e97b6e8SHong Zhang   const PetscInt *cols;
11773e97b6e8SHong Zhang   PetscScalar    zero=0.0;
11783e97b6e8SHong Zhang 
11793e97b6e8SHong Zhang   PetscFunctionBegin;
11803e97b6e8SHong Zhang   ierr = MatGetSize(Ju,&M,&N);CHKERRQ(ierr);
11813e97b6e8SHong 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);
11823e97b6e8SHong Zhang 
11833e97b6e8SHong Zhang   for (row=0; row<nrows; row++) {
11843e97b6e8SHong Zhang     ierr = MatGetRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr);
11853e97b6e8SHong Zhang     for (j=0; j<ncols_u; j++) {
11863e97b6e8SHong Zhang       col = cols[j] + cstart;
11873e97b6e8SHong Zhang       ierr = MatSetValues(*J,1,&rows[row],1,&col,&zero,INSERT_VALUES);CHKERRQ(ierr);
11883e97b6e8SHong Zhang     }
11893e97b6e8SHong Zhang     ierr = MatRestoreRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr);
11903e97b6e8SHong Zhang   }
11913e97b6e8SHong Zhang   PetscFunctionReturn(0);
11923e97b6e8SHong Zhang }
11931ad426b7SHong Zhang 
11941ad426b7SHong Zhang #undef __FUNCT__
1195a4e85ca8SHong Zhang #define __FUNCT__ "MatSetblock_private"
1196e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J)
1197a4e85ca8SHong Zhang {
1198a4e85ca8SHong Zhang   PetscErrorCode ierr;
1199f4431b8cSHong Zhang 
1200a4e85ca8SHong Zhang   PetscFunctionBegin;
1201a4e85ca8SHong Zhang   if (Ju) {
1202a4e85ca8SHong Zhang     ierr = MatSetUserblock_private(Ju,nrows,rows,ncols,cstart,J);CHKERRQ(ierr);
1203a4e85ca8SHong Zhang   } else {
1204a4e85ca8SHong Zhang     ierr = MatSetDenseblock_private(nrows,rows,ncols,cstart,J);CHKERRQ(ierr);
1205a4e85ca8SHong Zhang   }
1206a4e85ca8SHong Zhang   PetscFunctionReturn(0);
1207a4e85ca8SHong Zhang }
1208a4e85ca8SHong Zhang 
1209*24121865SAdrian Maldonado 
1210*24121865SAdrian Maldonado #undef __FUNCT__
1211*24121865SAdrian Maldonado #define __FUNCT__ "CreateSubGlobalToLocalMapping_private"
1212*24121865SAdrian 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.
1213*24121865SAdrian Maldonado */
1214*24121865SAdrian Maldonado PetscErrorCode CreateSubGlobalToLocalMapping_private(PetscSection globalsec, PetscSection localsec, ISLocalToGlobalMapping *ltog)
1215*24121865SAdrian Maldonado {
1216*24121865SAdrian Maldonado   PetscErrorCode ierr;
1217*24121865SAdrian Maldonado   PetscInt       i, size, dof;
1218*24121865SAdrian Maldonado   PetscInt       *glob2loc;
1219*24121865SAdrian Maldonado 
1220*24121865SAdrian Maldonado   PetscFunctionBegin;
1221*24121865SAdrian Maldonado   ierr = PetscSectionGetStorageSize(localsec,&size);CHKERRQ(ierr);
1222*24121865SAdrian Maldonado   ierr = PetscMalloc1(size,&glob2loc);CHKERRQ(ierr);
1223*24121865SAdrian Maldonado 
1224*24121865SAdrian Maldonado   for (i = 0; i < size; i++) {
1225*24121865SAdrian Maldonado     ierr = PetscSectionGetOffset(globalsec,i,&dof);CHKERRQ(ierr);
1226*24121865SAdrian Maldonado     dof = (dof >= 0) ? dof : -(dof + 1);
1227*24121865SAdrian Maldonado     glob2loc[i] = dof;
1228*24121865SAdrian Maldonado   }
1229*24121865SAdrian Maldonado 
1230*24121865SAdrian Maldonado   ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,size,glob2loc,PETSC_OWN_POINTER,ltog);CHKERRQ(ierr);
1231*24121865SAdrian Maldonado #if 0
1232*24121865SAdrian Maldonado   ierr = PetscIntView(size,glob2loc,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
1233*24121865SAdrian Maldonado #endif
1234*24121865SAdrian Maldonado   PetscFunctionReturn(0);
1235*24121865SAdrian Maldonado }
1236*24121865SAdrian Maldonado 
1237a4e85ca8SHong Zhang #undef __FUNCT__
12381ad426b7SHong Zhang #define __FUNCT__ "DMCreateMatrix_Network"
12391ad426b7SHong Zhang PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J)
12401ad426b7SHong Zhang {
12411ad426b7SHong Zhang   PetscErrorCode ierr;
1242*24121865SAdrian Maldonado   PetscMPIInt    rank, size;
12431ad426b7SHong Zhang   DM_Network     *network = (DM_Network*) dm->data;
1244a4e85ca8SHong Zhang   PetscInt       eStart,eEnd,vStart,vEnd,rstart,nrows,*rows,localSize;
1245840c2264SHong Zhang   PetscInt       cstart,ncols,j,e,v;
1246*24121865SAdrian Maldonado   PetscBool      ghost,ghost_vc,ghost2,isNest;
1247a4e85ca8SHong Zhang   Mat            Juser;
1248bfbc38dcSHong Zhang   PetscSection   sectionGlobal;
1249bdcb62a2SHong Zhang   PetscInt       nedges,*vptr=NULL,vc,*rows_v;
1250a4e85ca8SHong Zhang   const PetscInt *edges,*cone;
12515cf7da58SHong Zhang   MPI_Comm       comm;
1252*24121865SAdrian Maldonado   MatType        mtype;
12535cf7da58SHong Zhang   Vec            vd_nz,vo_nz;
12545cf7da58SHong Zhang   PetscInt       *dnnz,*onnz;
12555cf7da58SHong Zhang   PetscScalar    *vdnz,*vonz;
12561ad426b7SHong Zhang 
12571ad426b7SHong Zhang   PetscFunctionBegin;
1258*24121865SAdrian Maldonado   mtype = dm->mattype;
1259*24121865SAdrian Maldonado   ierr = PetscStrcmp(mtype, MATNEST, &isNest);CHKERRQ(ierr);
1260*24121865SAdrian Maldonado 
1261*24121865SAdrian Maldonado   if (isNest) {
1262*24121865SAdrian Maldonado 
1263*24121865SAdrian Maldonado     PetscInt   eDof, vDof;
1264*24121865SAdrian Maldonado     Mat        j11, j12, j21, j22, bA[2][2];
1265*24121865SAdrian Maldonado     ISLocalToGlobalMapping eISMap, vISMap;
1266*24121865SAdrian Maldonado 
1267*24121865SAdrian Maldonado     ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
1268*24121865SAdrian Maldonado     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
1269*24121865SAdrian Maldonado     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1270*24121865SAdrian Maldonado 
1271*24121865SAdrian Maldonado     ierr = PetscSectionGetConstrainedStorageSize(network->edge.GlobalDofSection,&eDof);CHKERRQ(ierr);
1272*24121865SAdrian Maldonado     ierr = PetscSectionGetConstrainedStorageSize(network->vertex.GlobalDofSection,&vDof);CHKERRQ(ierr);
1273*24121865SAdrian Maldonado 
1274*24121865SAdrian Maldonado #if 0
1275*24121865SAdrian Maldonado     printf("rank[%d] vdof = %d. edof = %d\n", rank, vDof, eDof);
1276*24121865SAdrian Maldonado #endif
1277*24121865SAdrian Maldonado 
1278*24121865SAdrian Maldonado     ierr = MatCreate(PETSC_COMM_WORLD, &j11);CHKERRQ(ierr);
1279*24121865SAdrian Maldonado     ierr = MatSetSizes(j11, eDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
1280*24121865SAdrian Maldonado     ierr = MatSetType(j11, MATMPIAIJ);CHKERRQ(ierr);
1281*24121865SAdrian Maldonado 
1282*24121865SAdrian Maldonado     ierr = MatCreate(PETSC_COMM_WORLD, &j12);CHKERRQ(ierr);
1283*24121865SAdrian Maldonado     ierr = MatSetSizes(j12, eDof, vDof, PETSC_DETERMINE ,PETSC_DETERMINE);CHKERRQ(ierr);
1284*24121865SAdrian Maldonado     ierr = MatSetType(j12, MATMPIAIJ);CHKERRQ(ierr);
1285*24121865SAdrian Maldonado 
1286*24121865SAdrian Maldonado     ierr = MatCreate(PETSC_COMM_WORLD, &j21);CHKERRQ(ierr);
1287*24121865SAdrian Maldonado     ierr = MatSetSizes(j21, vDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
1288*24121865SAdrian Maldonado     ierr = MatSetType(j21, MATMPIAIJ);CHKERRQ(ierr);
1289*24121865SAdrian Maldonado 
1290*24121865SAdrian Maldonado     ierr = MatCreate(PETSC_COMM_WORLD, &j22);CHKERRQ(ierr);
1291*24121865SAdrian Maldonado     ierr = MatSetSizes(j22, vDof, vDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
1292*24121865SAdrian Maldonado     ierr = MatSetType(j22, MATMPIAIJ);CHKERRQ(ierr);
1293*24121865SAdrian Maldonado 
1294*24121865SAdrian Maldonado     bA[0][0] = j11;
1295*24121865SAdrian Maldonado     bA[0][1] = j12;
1296*24121865SAdrian Maldonado     bA[1][0] = j21;
1297*24121865SAdrian Maldonado     bA[1][1] = j22;
1298*24121865SAdrian Maldonado 
1299*24121865SAdrian Maldonado     ierr = CreateSubGlobalToLocalMapping_private(network->edge.GlobalDofSection,network->edge.DofSection,&eISMap);CHKERRQ(ierr);
1300*24121865SAdrian Maldonado     ierr = CreateSubGlobalToLocalMapping_private(network->vertex.GlobalDofSection,network->vertex.DofSection,&vISMap);CHKERRQ(ierr);
1301*24121865SAdrian Maldonado 
1302*24121865SAdrian Maldonado 
1303*24121865SAdrian Maldonado     ierr = MatSetLocalToGlobalMapping(j11,eISMap,eISMap);CHKERRQ(ierr);
1304*24121865SAdrian Maldonado     ierr = MatSetLocalToGlobalMapping(j12,eISMap,vISMap);CHKERRQ(ierr);
1305*24121865SAdrian Maldonado     ierr = MatSetLocalToGlobalMapping(j21,vISMap,eISMap);CHKERRQ(ierr);
1306*24121865SAdrian Maldonado     ierr = MatSetLocalToGlobalMapping(j22,vISMap,vISMap);CHKERRQ(ierr);
1307*24121865SAdrian Maldonado 
1308*24121865SAdrian Maldonado     ierr = MatSetUp(j11);CHKERRQ(ierr);
1309*24121865SAdrian Maldonado     ierr = MatSetUp(j12);CHKERRQ(ierr);
1310*24121865SAdrian Maldonado     ierr = MatSetUp(j21);CHKERRQ(ierr);
1311*24121865SAdrian Maldonado     ierr = MatSetUp(j22);CHKERRQ(ierr);
1312*24121865SAdrian Maldonado 
1313*24121865SAdrian Maldonado     ierr = MatCreateNest(PETSC_COMM_WORLD,2,NULL,2,NULL,&bA[0][0],J);CHKERRQ(ierr);
1314*24121865SAdrian Maldonado     ierr = MatSetUp(*J);CHKERRQ(ierr);
1315*24121865SAdrian Maldonado     ierr = MatNestSetVecType(*J,VECNEST);CHKERRQ(ierr);
1316*24121865SAdrian Maldonado     ierr = MatDestroy(&j11);CHKERRQ(ierr);
1317*24121865SAdrian Maldonado     ierr = MatDestroy(&j12);CHKERRQ(ierr);
1318*24121865SAdrian Maldonado     ierr = MatDestroy(&j21);CHKERRQ(ierr);
1319*24121865SAdrian Maldonado     ierr = MatDestroy(&j22);CHKERRQ(ierr);
1320*24121865SAdrian Maldonado 
1321*24121865SAdrian Maldonado     ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1322*24121865SAdrian Maldonado     ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1323*24121865SAdrian Maldonado 
1324*24121865SAdrian Maldonado     /* Free structures */
1325*24121865SAdrian Maldonado     ierr = ISLocalToGlobalMappingDestroy(&eISMap);CHKERRQ(ierr);
1326*24121865SAdrian Maldonado     ierr = ISLocalToGlobalMappingDestroy(&vISMap);CHKERRQ(ierr);
1327*24121865SAdrian Maldonado 
1328*24121865SAdrian Maldonado     PetscFunctionReturn(0);
1329*24121865SAdrian Maldonado 
1330*24121865SAdrian Maldonado   } else if (!network->userEdgeJacobian && !network->userVertexJacobian) {
1331a4e85ca8SHong Zhang     /* user does not provide Jacobian blocks */
1332bfbc38dcSHong Zhang     ierr = DMCreateMatrix(network->plex,J);CHKERRQ(ierr);
1333bfbc38dcSHong Zhang     ierr = MatSetDM(*J,dm);CHKERRQ(ierr);
13341ad426b7SHong Zhang     PetscFunctionReturn(0);
13351ad426b7SHong Zhang   }
13361ad426b7SHong Zhang 
1337bfbc38dcSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)dm),J);CHKERRQ(ierr);
13382a945128SHong Zhang   ierr = DMGetDefaultGlobalSection(network->plex,&sectionGlobal);CHKERRQ(ierr);
1339bfbc38dcSHong Zhang   ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal,&localSize);CHKERRQ(ierr);
1340bfbc38dcSHong Zhang   ierr = MatSetSizes(*J,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
13412a945128SHong Zhang 
13422a945128SHong Zhang   ierr = MatSetType(*J,MATAIJ);CHKERRQ(ierr);
13432a945128SHong Zhang   ierr = MatSetFromOptions(*J);CHKERRQ(ierr);
134489898e50SHong Zhang 
134589898e50SHong Zhang   /* (1) Set matrix preallocation */
134689898e50SHong Zhang   /*------------------------------*/
1347840c2264SHong Zhang   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
1348840c2264SHong Zhang   ierr = VecCreate(comm,&vd_nz);CHKERRQ(ierr);
1349840c2264SHong Zhang   ierr = VecSetSizes(vd_nz,localSize,PETSC_DECIDE);CHKERRQ(ierr);
1350840c2264SHong Zhang   ierr = VecSetFromOptions(vd_nz);CHKERRQ(ierr);
1351840c2264SHong Zhang   ierr = VecSet(vd_nz,0.0);CHKERRQ(ierr);
1352840c2264SHong Zhang   ierr = VecDuplicate(vd_nz,&vo_nz);CHKERRQ(ierr);
1353840c2264SHong Zhang 
135489898e50SHong Zhang   /* Set preallocation for edges */
135589898e50SHong Zhang   /*-----------------------------*/
1356840c2264SHong Zhang   ierr = DMNetworkGetEdgeRange(dm,&eStart,&eEnd);CHKERRQ(ierr);
1357840c2264SHong Zhang 
1358bdcb62a2SHong Zhang   ierr = PetscMalloc1(localSize,&rows);CHKERRQ(ierr);
1359840c2264SHong Zhang   for (e=eStart; e<eEnd; e++) {
1360840c2264SHong Zhang     /* Get row indices */
1361840c2264SHong Zhang     ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr);
1362840c2264SHong Zhang     ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr);
1363840c2264SHong Zhang     if (nrows) {
1364840c2264SHong Zhang       if (!network->Je) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Uer must provide Je");
1365840c2264SHong Zhang       for (j=0; j<nrows; j++) rows[j] = j + rstart;
1366840c2264SHong Zhang 
13675cf7da58SHong Zhang       /* Set preallocation for conntected vertices */
1368840c2264SHong Zhang       ierr = DMNetworkGetConnectedNodes(dm,e,&cone);CHKERRQ(ierr);
1369840c2264SHong Zhang       for (v=0; v<2; v++) {
1370840c2264SHong Zhang         ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr);
1371840c2264SHong Zhang 
1372840c2264SHong Zhang         Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */
1373840c2264SHong Zhang         ierr = DMNetworkIsGhostVertex(dm,cone[v],&ghost);CHKERRQ(ierr);
13745cf7da58SHong Zhang         ierr = MatSetPreallocationblock_private(Juser,nrows,rows,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr);
1375840c2264SHong Zhang       }
1376840c2264SHong Zhang 
137789898e50SHong Zhang       /* Set preallocation for edge self */
1378840c2264SHong Zhang       cstart = rstart;
1379840c2264SHong Zhang       Juser = network->Je[3*e]; /* Jacobian(e,e) */
13805cf7da58SHong Zhang       ierr = MatSetPreallocationblock_private(Juser,nrows,rows,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr);
1381840c2264SHong Zhang     }
1382840c2264SHong Zhang   }
1383840c2264SHong Zhang 
138489898e50SHong Zhang   /* Set preallocation for vertices */
138589898e50SHong Zhang   /*--------------------------------*/
1386840c2264SHong Zhang   ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr);
1387840c2264SHong Zhang   if (vEnd - vStart) {
1388840c2264SHong Zhang     if (!network->Jv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Uer must provide Jv");
1389840c2264SHong Zhang     vptr = network->Jvptr;
1390840c2264SHong Zhang     if (!vptr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Uer must provide vptr");
1391840c2264SHong Zhang   }
1392840c2264SHong Zhang 
1393840c2264SHong Zhang   for (v=vStart; v<vEnd; v++) {
1394840c2264SHong Zhang     /* Get row indices */
1395840c2264SHong Zhang     ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr);
1396840c2264SHong Zhang     ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr);
1397840c2264SHong Zhang     if (!nrows) continue;
1398840c2264SHong Zhang 
1399bdcb62a2SHong Zhang     ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr);
1400bdcb62a2SHong Zhang     if (ghost) {
1401bdcb62a2SHong Zhang       ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr);
1402bdcb62a2SHong Zhang     } else {
1403bdcb62a2SHong Zhang       rows_v = rows;
1404bdcb62a2SHong Zhang     }
1405bdcb62a2SHong Zhang 
1406bdcb62a2SHong Zhang     for (j=0; j<nrows; j++) rows_v[j] = j + rstart;
1407840c2264SHong Zhang 
1408840c2264SHong Zhang     /* Get supporting edges and connected vertices */
1409840c2264SHong Zhang     ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr);
1410840c2264SHong Zhang 
1411840c2264SHong Zhang     for (e=0; e<nedges; e++) {
1412840c2264SHong Zhang       /* Supporting edges */
1413840c2264SHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr);
1414840c2264SHong Zhang       ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr);
1415840c2264SHong Zhang 
1416840c2264SHong Zhang       Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */
1417bdcb62a2SHong Zhang       ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr);
1418840c2264SHong Zhang 
1419840c2264SHong Zhang       /* Connected vertices */
1420840c2264SHong Zhang       ierr = DMNetworkGetConnectedNodes(dm,edges[e],&cone);CHKERRQ(ierr);
1421840c2264SHong Zhang       vc = (v == cone[0]) ? cone[1]:cone[0];
1422840c2264SHong Zhang       ierr = DMNetworkIsGhostVertex(dm,vc,&ghost_vc);CHKERRQ(ierr);
1423840c2264SHong Zhang 
1424840c2264SHong Zhang       ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr);
1425840c2264SHong Zhang 
1426840c2264SHong Zhang       Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */
1427e102a522SHong Zhang       if (ghost_vc||ghost) {
1428e102a522SHong Zhang         ghost2 = PETSC_TRUE;
1429e102a522SHong Zhang       } else {
1430e102a522SHong Zhang         ghost2 = PETSC_FALSE;
1431e102a522SHong Zhang       }
1432e102a522SHong Zhang       ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost2,vd_nz,vo_nz);CHKERRQ(ierr);
1433840c2264SHong Zhang     }
1434840c2264SHong Zhang 
143589898e50SHong Zhang     /* Set preallocation for vertex self */
1436840c2264SHong Zhang     ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr);
1437840c2264SHong Zhang     if (!ghost) {
1438840c2264SHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr);
1439840c2264SHong Zhang       Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */
1440bdcb62a2SHong Zhang       ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr);
1441840c2264SHong Zhang     }
1442bdcb62a2SHong Zhang     if (ghost) {
1443bdcb62a2SHong Zhang       ierr = PetscFree(rows_v);CHKERRQ(ierr);
1444bdcb62a2SHong Zhang     }
1445840c2264SHong Zhang   }
1446840c2264SHong Zhang 
1447840c2264SHong Zhang   ierr = VecAssemblyBegin(vd_nz);CHKERRQ(ierr);
1448840c2264SHong Zhang   ierr = VecAssemblyBegin(vo_nz);CHKERRQ(ierr);
14495cf7da58SHong Zhang 
14505cf7da58SHong Zhang   ierr = PetscMalloc2(localSize,&dnnz,localSize,&onnz);CHKERRQ(ierr);
14515cf7da58SHong Zhang 
14525cf7da58SHong Zhang   ierr = VecAssemblyEnd(vd_nz);CHKERRQ(ierr);
1453840c2264SHong Zhang   ierr = VecAssemblyEnd(vo_nz);CHKERRQ(ierr);
1454840c2264SHong Zhang 
1455840c2264SHong Zhang   ierr = VecGetArray(vd_nz,&vdnz);CHKERRQ(ierr);
1456840c2264SHong Zhang   ierr = VecGetArray(vo_nz,&vonz);CHKERRQ(ierr);
1457840c2264SHong Zhang   for (j=0; j<localSize; j++) {
1458e102a522SHong Zhang     dnnz[j] = (PetscInt)PetscRealPart(vdnz[j]);
1459e102a522SHong Zhang     onnz[j] = (PetscInt)PetscRealPart(vonz[j]);
1460840c2264SHong Zhang   }
1461840c2264SHong Zhang   ierr = VecRestoreArray(vd_nz,&vdnz);CHKERRQ(ierr);
1462840c2264SHong Zhang   ierr = VecRestoreArray(vo_nz,&vonz);CHKERRQ(ierr);
1463840c2264SHong Zhang   ierr = VecDestroy(&vd_nz);CHKERRQ(ierr);
1464840c2264SHong Zhang   ierr = VecDestroy(&vo_nz);CHKERRQ(ierr);
1465840c2264SHong Zhang 
14665cf7da58SHong Zhang   ierr = MatSeqAIJSetPreallocation(*J,0,dnnz);CHKERRQ(ierr);
14675cf7da58SHong Zhang   ierr = MatMPIAIJSetPreallocation(*J,0,dnnz,0,onnz);CHKERRQ(ierr);
14685cf7da58SHong Zhang   ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
14695cf7da58SHong Zhang 
14705cf7da58SHong Zhang   ierr = PetscFree2(dnnz,onnz);CHKERRQ(ierr);
14715cf7da58SHong Zhang 
147289898e50SHong Zhang   /* (2) Set matrix entries for edges */
147389898e50SHong Zhang   /*----------------------------------*/
14741ad426b7SHong Zhang   for (e=eStart; e<eEnd; e++) {
1475bfbc38dcSHong Zhang     /* Get row indices */
14761ad426b7SHong Zhang     ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr);
147717df6e9eSHong Zhang     ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr);
14784b976069SHong Zhang     if (nrows) {
14794b976069SHong Zhang       if (!network->Je) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Uer must provide Je");
1480bdcb62a2SHong Zhang 
148117df6e9eSHong Zhang       for (j=0; j<nrows; j++) rows[j] = j + rstart;
14821ad426b7SHong Zhang 
1483bfbc38dcSHong Zhang       /* Set matrix entries for conntected vertices */
148417df6e9eSHong Zhang       ierr = DMNetworkGetConnectedNodes(dm,e,&cone);CHKERRQ(ierr);
1485bfbc38dcSHong Zhang       for (v=0; v<2; v++) {
1486bfbc38dcSHong Zhang         ierr = DMNetworkGetVariableGlobalOffset(dm,cone[v],&cstart);CHKERRQ(ierr);
1487883e35e8SHong Zhang         ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr);
14883e97b6e8SHong Zhang 
1489a4e85ca8SHong Zhang         Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */
1490a4e85ca8SHong Zhang         ierr = MatSetblock_private(Juser,nrows,rows,ncols,cstart,J);CHKERRQ(ierr);
1491bfbc38dcSHong Zhang       }
149217df6e9eSHong Zhang 
1493bfbc38dcSHong Zhang       /* Set matrix entries for edge self */
14943e97b6e8SHong Zhang       cstart = rstart;
1495a4e85ca8SHong Zhang       Juser = network->Je[3*e]; /* Jacobian(e,e) */
1496a4e85ca8SHong Zhang       ierr = MatSetblock_private(Juser,nrows,rows,nrows,cstart,J);CHKERRQ(ierr);
14971ad426b7SHong Zhang     }
14984b976069SHong Zhang   }
14991ad426b7SHong Zhang 
1500bfbc38dcSHong Zhang   /* Set matrix entries for vertices */
150183b2e829SHong Zhang   /*---------------------------------*/
15021ad426b7SHong Zhang     for (v=vStart; v<vEnd; v++) {
1503bfbc38dcSHong Zhang       /* Get row indices */
1504596e729fSHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr);
1505596e729fSHong Zhang       ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr);
15064b976069SHong Zhang       if (!nrows) continue;
1507596e729fSHong Zhang 
1508bdcb62a2SHong Zhang     ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr);
1509bdcb62a2SHong Zhang     if (ghost) {
1510bdcb62a2SHong Zhang       ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr);
1511bdcb62a2SHong Zhang     } else {
1512bdcb62a2SHong Zhang       rows_v = rows;
1513bdcb62a2SHong Zhang     }
1514bdcb62a2SHong Zhang     for (j=0; j<nrows; j++) rows_v[j] = j + rstart;
1515596e729fSHong Zhang 
1516bfbc38dcSHong Zhang       /* Get supporting edges and connected vertices */
1517596e729fSHong Zhang       ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr);
1518596e729fSHong Zhang 
1519596e729fSHong Zhang       for (e=0; e<nedges; e++) {
1520bfbc38dcSHong Zhang         /* Supporting edges */
1521596e729fSHong Zhang         ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr);
1522596e729fSHong Zhang         ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr);
1523596e729fSHong Zhang 
1524a4e85ca8SHong Zhang         Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */
1525bdcb62a2SHong Zhang       ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr);
1526596e729fSHong Zhang 
1527bfbc38dcSHong Zhang         /* Connected vertices */
152844aca652SHong Zhang         ierr = DMNetworkGetConnectedNodes(dm,edges[e],&cone);CHKERRQ(ierr);
15292a945128SHong Zhang         vc = (v == cone[0]) ? cone[1]:cone[0];
15302a945128SHong Zhang 
153144aca652SHong Zhang         ierr = DMNetworkGetVariableGlobalOffset(dm,vc,&cstart);CHKERRQ(ierr);
153244aca652SHong Zhang         ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr);
1533a4e85ca8SHong Zhang 
1534a4e85ca8SHong Zhang         Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */
1535bdcb62a2SHong Zhang       ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr);
1536596e729fSHong Zhang       }
1537596e729fSHong Zhang 
1538bfbc38dcSHong Zhang       /* Set matrix entries for vertex self */
15391ad426b7SHong Zhang       if (!ghost) {
1540596e729fSHong Zhang         ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr);
1541a4e85ca8SHong Zhang         Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */
1542bdcb62a2SHong Zhang       ierr = MatSetblock_private(Juser,nrows,rows_v,nrows,cstart,J);CHKERRQ(ierr);
1543bdcb62a2SHong Zhang       }
1544bdcb62a2SHong Zhang     if (ghost) {
1545bdcb62a2SHong Zhang       ierr = PetscFree(rows_v);CHKERRQ(ierr);
1546bdcb62a2SHong Zhang     }
15471ad426b7SHong Zhang   }
1548a4e85ca8SHong Zhang   ierr = PetscFree(rows);CHKERRQ(ierr);
1549bdcb62a2SHong Zhang 
15501ad426b7SHong Zhang   ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15511ad426b7SHong Zhang   ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1552dd6f46cdSHong Zhang 
15535f2c45f1SShri Abhyankar   ierr = MatSetDM(*J,dm);CHKERRQ(ierr);
15545f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
15555f2c45f1SShri Abhyankar }
15565f2c45f1SShri Abhyankar 
15575f2c45f1SShri Abhyankar #undef __FUNCT__
15585f2c45f1SShri Abhyankar #define __FUNCT__ "DMDestroy_Network"
15595f2c45f1SShri Abhyankar PetscErrorCode DMDestroy_Network(DM dm)
15605f2c45f1SShri Abhyankar {
15615f2c45f1SShri Abhyankar   PetscErrorCode ierr;
15625f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
15635f2c45f1SShri Abhyankar 
15645f2c45f1SShri Abhyankar   PetscFunctionBegin;
1565*24121865SAdrian Maldonado   /* vertex */
1566*24121865SAdrian Maldonado   ierr = ISLocalToGlobalMappingDestroy(&network->vertex.mapping);CHKERRQ(ierr);
1567*24121865SAdrian Maldonado   ierr = PetscSectionDestroy(&network->vertex.DofSection);CHKERRQ(ierr);
1568*24121865SAdrian Maldonado   ierr = PetscSectionDestroy(&network->vertex.GlobalDofSection);CHKERRQ(ierr);
1569*24121865SAdrian Maldonado   if (network->vertex.sf) {
1570*24121865SAdrian Maldonado     ierr = PetscSFDestroy(&network->vertex.sf);CHKERRQ(ierr);
1571*24121865SAdrian Maldonado   }
1572*24121865SAdrian Maldonado   /* edge */
1573*24121865SAdrian Maldonado   ierr = ISLocalToGlobalMappingDestroy(&network->edge.mapping);CHKERRQ(ierr);
1574*24121865SAdrian Maldonado   ierr = PetscSectionDestroy(&network->edge.DofSection);CHKERRQ(ierr);
1575*24121865SAdrian Maldonado   ierr = PetscSectionDestroy(&network->edge.GlobalDofSection);CHKERRQ(ierr);
1576*24121865SAdrian Maldonado   if (network->edge.sf) {
1577*24121865SAdrian Maldonado     ierr = PetscSFDestroy(&network->edge.sf);CHKERRQ(ierr);
1578*24121865SAdrian Maldonado   }
15798415c774SShri Abhyankar   if (--network->refct > 0) PetscFunctionReturn(0);
158083b2e829SHong Zhang   if (network->Je) {
158183b2e829SHong Zhang     ierr = PetscFree(network->Je);CHKERRQ(ierr);
158283b2e829SHong Zhang   }
158383b2e829SHong Zhang   if (network->Jv) {
1584883e35e8SHong Zhang     ierr = PetscFree(network->Jvptr);CHKERRQ(ierr);
158583b2e829SHong Zhang     ierr = PetscFree(network->Jv);CHKERRQ(ierr);
15861ad426b7SHong Zhang   }
15875f2c45f1SShri Abhyankar   ierr = DMDestroy(&network->plex);CHKERRQ(ierr);
15885f2c45f1SShri Abhyankar   network->edges = NULL;
15895f2c45f1SShri Abhyankar   ierr = PetscSectionDestroy(&network->DataSection);CHKERRQ(ierr);
15905f2c45f1SShri Abhyankar   ierr = PetscSectionDestroy(&network->DofSection);CHKERRQ(ierr);
159183b2e829SHong Zhang 
15925f2c45f1SShri Abhyankar   ierr = PetscFree(network->componentdataarray);CHKERRQ(ierr);
15935f2c45f1SShri Abhyankar   ierr = PetscFree(network->cvalue);CHKERRQ(ierr);
15945f2c45f1SShri Abhyankar   ierr = PetscFree(network->header);CHKERRQ(ierr);
15955f2c45f1SShri Abhyankar   ierr = PetscFree(network);CHKERRQ(ierr);
1596*24121865SAdrian Maldonado 
1597*24121865SAdrian Maldonado 
15985f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
15995f2c45f1SShri Abhyankar }
16005f2c45f1SShri Abhyankar 
16015f2c45f1SShri Abhyankar #undef __FUNCT__
16025f2c45f1SShri Abhyankar #define __FUNCT__ "DMView_Network"
16035f2c45f1SShri Abhyankar PetscErrorCode DMView_Network(DM dm, PetscViewer viewer)
16045f2c45f1SShri Abhyankar {
16055f2c45f1SShri Abhyankar   PetscErrorCode ierr;
16065f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
16075f2c45f1SShri Abhyankar 
16085f2c45f1SShri Abhyankar   PetscFunctionBegin;
16095f2c45f1SShri Abhyankar   ierr = DMView(network->plex,viewer);CHKERRQ(ierr);
16105f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
16115f2c45f1SShri Abhyankar }
16125f2c45f1SShri Abhyankar 
16135f2c45f1SShri Abhyankar #undef __FUNCT__
16145f2c45f1SShri Abhyankar #define __FUNCT__ "DMGlobalToLocalBegin_Network"
16155f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l)
16165f2c45f1SShri Abhyankar {
16175f2c45f1SShri Abhyankar   PetscErrorCode ierr;
16185f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
16195f2c45f1SShri Abhyankar 
16205f2c45f1SShri Abhyankar   PetscFunctionBegin;
16215f2c45f1SShri Abhyankar   ierr = DMGlobalToLocalBegin(network->plex,g,mode,l);CHKERRQ(ierr);
16225f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
16235f2c45f1SShri Abhyankar }
16245f2c45f1SShri Abhyankar 
16255f2c45f1SShri Abhyankar #undef __FUNCT__
16265f2c45f1SShri Abhyankar #define __FUNCT__ "DMGlobalToLocalEnd_Network"
16275f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l)
16285f2c45f1SShri Abhyankar {
16295f2c45f1SShri Abhyankar   PetscErrorCode ierr;
16305f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
16315f2c45f1SShri Abhyankar 
16325f2c45f1SShri Abhyankar   PetscFunctionBegin;
16335f2c45f1SShri Abhyankar   ierr = DMGlobalToLocalEnd(network->plex,g,mode,l);CHKERRQ(ierr);
16345f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
16355f2c45f1SShri Abhyankar }
16365f2c45f1SShri Abhyankar 
16375f2c45f1SShri Abhyankar #undef __FUNCT__
16385f2c45f1SShri Abhyankar #define __FUNCT__ "DMLocalToGlobalBegin_Network"
16395f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g)
16405f2c45f1SShri Abhyankar {
16415f2c45f1SShri Abhyankar   PetscErrorCode ierr;
16425f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
16435f2c45f1SShri Abhyankar 
16445f2c45f1SShri Abhyankar   PetscFunctionBegin;
16455f2c45f1SShri Abhyankar   ierr = DMLocalToGlobalBegin(network->plex,l,mode,g);CHKERRQ(ierr);
16465f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
16475f2c45f1SShri Abhyankar }
16485f2c45f1SShri Abhyankar 
16495f2c45f1SShri Abhyankar #undef __FUNCT__
16505f2c45f1SShri Abhyankar #define __FUNCT__ "DMLocalToGlobalEnd_Network"
16515f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g)
16525f2c45f1SShri Abhyankar {
16535f2c45f1SShri Abhyankar   PetscErrorCode ierr;
16545f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
16555f2c45f1SShri Abhyankar 
16565f2c45f1SShri Abhyankar   PetscFunctionBegin;
16575f2c45f1SShri Abhyankar   ierr = DMLocalToGlobalEnd(network->plex,l,mode,g);CHKERRQ(ierr);
16585f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
16595f2c45f1SShri Abhyankar }
1660