xref: /petsc/src/dm/impls/network/network.c (revision 459726d8c7c3a7b753ebf4288f90b12337f2ef69)
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 
241b266c99SBarry Smith    Level: intermediate
251b266c99SBarry Smith 
261b266c99SBarry Smith .seealso: DMNetworkCreate()
275f2c45f1SShri Abhyankar @*/
285f2c45f1SShri Abhyankar PetscErrorCode DMNetworkSetSizes(DM dm, PetscInt nV, PetscInt nE, PetscInt NV, PetscInt NE)
295f2c45f1SShri Abhyankar {
305f2c45f1SShri Abhyankar   PetscErrorCode ierr;
315f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
325f2c45f1SShri Abhyankar   PetscInt       a[2],b[2];
335f2c45f1SShri Abhyankar 
345f2c45f1SShri Abhyankar   PetscFunctionBegin;
355f2c45f1SShri Abhyankar   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
365f2c45f1SShri Abhyankar   if (NV > 0) PetscValidLogicalCollectiveInt(dm,NV,4);
375f2c45f1SShri Abhyankar   if (NE > 0) PetscValidLogicalCollectiveInt(dm,NE,5);
385f2c45f1SShri 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);
395f2c45f1SShri 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);
405f2c45f1SShri 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);
415f2c45f1SShri 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);
425f2c45f1SShri Abhyankar   if (NE < 0 || NV < 0) {
435f2c45f1SShri Abhyankar     a[0] = nV; a[1] = nE;
44b2566f29SBarry Smith     ierr = MPIU_Allreduce(a,b,2,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
455f2c45f1SShri Abhyankar     NV = b[0]; NE = b[1];
465f2c45f1SShri Abhyankar   }
475f2c45f1SShri Abhyankar   network->nNodes = nV;
485f2c45f1SShri Abhyankar   network->NNodes = NV;
495f2c45f1SShri Abhyankar   network->nEdges = nE;
505f2c45f1SShri Abhyankar   network->NEdges = NE;
515f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
525f2c45f1SShri Abhyankar }
535f2c45f1SShri Abhyankar 
545f2c45f1SShri Abhyankar #undef __FUNCT__
555f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkSetEdgeList"
565f2c45f1SShri Abhyankar /*@
575f2c45f1SShri Abhyankar   DMNetworkSetEdgeList - Sets the list of local edges (vertex connectivity) for the network
585f2c45f1SShri Abhyankar 
595f2c45f1SShri Abhyankar   Logically collective on DM
605f2c45f1SShri Abhyankar 
615f2c45f1SShri Abhyankar   Input Parameters:
625f2c45f1SShri Abhyankar . edges - list of edges
635f2c45f1SShri Abhyankar 
645f2c45f1SShri Abhyankar   Notes:
655f2c45f1SShri Abhyankar   There is no copy involved in this operation, only the pointer is referenced. The edgelist should
665f2c45f1SShri Abhyankar   not be destroyed before the call to DMNetworkLayoutSetUp
675f2c45f1SShri Abhyankar 
685f2c45f1SShri Abhyankar   Level: intermediate
695f2c45f1SShri Abhyankar 
705f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkSetSizes
715f2c45f1SShri Abhyankar @*/
725f2c45f1SShri Abhyankar PetscErrorCode DMNetworkSetEdgeList(DM dm, int edgelist[])
735f2c45f1SShri Abhyankar {
745f2c45f1SShri Abhyankar   DM_Network *network = (DM_Network*) dm->data;
755f2c45f1SShri Abhyankar 
765f2c45f1SShri Abhyankar   PetscFunctionBegin;
775f2c45f1SShri Abhyankar   network->edges = edgelist;
785f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
795f2c45f1SShri Abhyankar }
805f2c45f1SShri Abhyankar 
815f2c45f1SShri Abhyankar #undef __FUNCT__
825f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkLayoutSetUp"
835f2c45f1SShri Abhyankar /*@
845f2c45f1SShri Abhyankar   DMNetworkLayoutSetUp - Sets up the bare layout (graph) for the network
855f2c45f1SShri Abhyankar 
865f2c45f1SShri Abhyankar   Collective on DM
875f2c45f1SShri Abhyankar 
885f2c45f1SShri Abhyankar   Input Parameters
895f2c45f1SShri Abhyankar . DM - the dmnetwork object
905f2c45f1SShri Abhyankar 
915f2c45f1SShri Abhyankar   Notes:
925f2c45f1SShri Abhyankar   This routine should be called after the network sizes and edgelists have been provided. It creates
935f2c45f1SShri Abhyankar   the bare layout of the network and sets up the network to begin insertion of components.
945f2c45f1SShri Abhyankar 
955f2c45f1SShri Abhyankar   All the components should be registered before calling this routine.
965f2c45f1SShri Abhyankar 
975f2c45f1SShri Abhyankar   Level: intermediate
985f2c45f1SShri Abhyankar 
995f2c45f1SShri Abhyankar .seealso: DMNetworkSetSizes, DMNetworkSetEdgeList
1005f2c45f1SShri Abhyankar @*/
1015f2c45f1SShri Abhyankar PetscErrorCode DMNetworkLayoutSetUp(DM dm)
1025f2c45f1SShri Abhyankar {
1035f2c45f1SShri Abhyankar   PetscErrorCode ierr;
1045f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
1055f2c45f1SShri Abhyankar   PetscInt       dim = 1; /* One dimensional network */
1065f2c45f1SShri Abhyankar   PetscInt       numCorners=2;
1075f2c45f1SShri Abhyankar   PetscInt       spacedim=2;
1085f2c45f1SShri Abhyankar   double         *vertexcoords=NULL;
1095f2c45f1SShri Abhyankar   PetscInt       i;
1105f2c45f1SShri Abhyankar   PetscInt       ndata;
1115f2c45f1SShri Abhyankar 
1125f2c45f1SShri Abhyankar   PetscFunctionBegin;
1135f2c45f1SShri Abhyankar   if (network->nNodes) {
1149045477aSSatish Balay     ierr = PetscCalloc1(numCorners*network->nNodes,&vertexcoords);CHKERRQ(ierr);
1155f2c45f1SShri Abhyankar   }
1165f2c45f1SShri Abhyankar   ierr = DMPlexCreateFromCellList(PetscObjectComm((PetscObject)dm),dim,network->nEdges,network->nNodes,numCorners,PETSC_FALSE,network->edges,spacedim,vertexcoords,&network->plex);CHKERRQ(ierr);
1175f2c45f1SShri Abhyankar   if (network->nNodes) {
1185f2c45f1SShri Abhyankar     ierr = PetscFree(vertexcoords);CHKERRQ(ierr);
1195f2c45f1SShri Abhyankar   }
1205f2c45f1SShri Abhyankar   ierr = DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);CHKERRQ(ierr);
1215f2c45f1SShri Abhyankar   ierr = DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);CHKERRQ(ierr);
1225f2c45f1SShri Abhyankar   ierr = DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);CHKERRQ(ierr);
1235f2c45f1SShri Abhyankar 
1245f2c45f1SShri Abhyankar   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm),&network->DataSection);CHKERRQ(ierr);
1255f2c45f1SShri Abhyankar   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm),&network->DofSection);CHKERRQ(ierr);
1265f2c45f1SShri Abhyankar   ierr = PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);CHKERRQ(ierr);
1275f2c45f1SShri Abhyankar   ierr = PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);CHKERRQ(ierr);
1285f2c45f1SShri Abhyankar 
12924121865SAdrian Maldonado 
13024121865SAdrian Maldonado 
1315f2c45f1SShri Abhyankar   network->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType);
1326caa05f4SBarry Smith   ierr = PetscCalloc1(network->pEnd-network->pStart,&network->header);CHKERRQ(ierr);
1335f2c45f1SShri Abhyankar   for (i = network->pStart; i < network->pEnd; i++) {
1345f2c45f1SShri Abhyankar     network->header[i].ndata = 0;
1355f2c45f1SShri Abhyankar     ndata = network->header[i].ndata;
1365f2c45f1SShri Abhyankar     ierr = PetscSectionAddDof(network->DataSection,i,network->dataheadersize);CHKERRQ(ierr);
1375f2c45f1SShri Abhyankar     network->header[i].offset[ndata] = 0;
1385f2c45f1SShri Abhyankar   }
139854ce69bSBarry Smith   ierr = PetscMalloc1(network->pEnd-network->pStart,&network->cvalue);CHKERRQ(ierr);
1405f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
1415f2c45f1SShri Abhyankar }
1425f2c45f1SShri Abhyankar 
1435f2c45f1SShri Abhyankar #undef __FUNCT__
1445f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkRegisterComponent"
1455f2c45f1SShri Abhyankar /*@
1465f2c45f1SShri Abhyankar   DMNetworkRegisterComponent - Registers the network component
1475f2c45f1SShri Abhyankar 
1485f2c45f1SShri Abhyankar   Logically collective on DM
1495f2c45f1SShri Abhyankar 
1505f2c45f1SShri Abhyankar   Input Parameters
1515f2c45f1SShri Abhyankar + dm   - the network object
1525f2c45f1SShri Abhyankar . name - the component name
1535f2c45f1SShri Abhyankar - size - the storage size in bytes for this component data
1545f2c45f1SShri Abhyankar 
1555f2c45f1SShri Abhyankar    Output Parameters
1565f2c45f1SShri Abhyankar .   key - an integer key that defines the component
1575f2c45f1SShri Abhyankar 
1585f2c45f1SShri Abhyankar    Notes
1595f2c45f1SShri Abhyankar    This routine should be called by all processors before calling DMNetworkLayoutSetup().
1605f2c45f1SShri Abhyankar 
1615f2c45f1SShri Abhyankar    Level: intermediate
1625f2c45f1SShri Abhyankar 
1635f2c45f1SShri Abhyankar .seealso: DMNetworkLayoutSetUp, DMNetworkCreate
1645f2c45f1SShri Abhyankar @*/
1655f2c45f1SShri Abhyankar PetscErrorCode DMNetworkRegisterComponent(DM dm,const char *name,PetscInt size,PetscInt *key)
1665f2c45f1SShri Abhyankar {
1675f2c45f1SShri Abhyankar   PetscErrorCode        ierr;
1685f2c45f1SShri Abhyankar   DM_Network            *network = (DM_Network*) dm->data;
1695f2c45f1SShri Abhyankar   DMNetworkComponent    *component=&network->component[network->ncomponent];
1705f2c45f1SShri Abhyankar   PetscBool             flg=PETSC_FALSE;
1715f2c45f1SShri Abhyankar   PetscInt              i;
1725f2c45f1SShri Abhyankar 
1735f2c45f1SShri Abhyankar   PetscFunctionBegin;
1745f2c45f1SShri Abhyankar 
1755f2c45f1SShri Abhyankar   for (i=0; i < network->ncomponent; i++) {
1765f2c45f1SShri Abhyankar     ierr = PetscStrcmp(component->name,name,&flg);CHKERRQ(ierr);
1775f2c45f1SShri Abhyankar     if (flg) {
1785f2c45f1SShri Abhyankar       *key = i;
1795f2c45f1SShri Abhyankar       PetscFunctionReturn(0);
1805f2c45f1SShri Abhyankar     }
1815f2c45f1SShri Abhyankar   }
1825f2c45f1SShri Abhyankar 
1835f2c45f1SShri Abhyankar   ierr = PetscStrcpy(component->name,name);CHKERRQ(ierr);
1845f2c45f1SShri Abhyankar   component->size = size/sizeof(DMNetworkComponentGenericDataType);
1855f2c45f1SShri Abhyankar   *key = network->ncomponent;
1865f2c45f1SShri Abhyankar   network->ncomponent++;
1875f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
1885f2c45f1SShri Abhyankar }
1895f2c45f1SShri Abhyankar 
1905f2c45f1SShri Abhyankar #undef __FUNCT__
1915f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetVertexRange"
1925f2c45f1SShri Abhyankar /*@
1935f2c45f1SShri Abhyankar   DMNetworkGetVertexRange - Get the bounds [start, end) for the vertices.
1945f2c45f1SShri Abhyankar 
1955f2c45f1SShri Abhyankar   Not Collective
1965f2c45f1SShri Abhyankar 
1975f2c45f1SShri Abhyankar   Input Parameters:
1985f2c45f1SShri Abhyankar + dm - The DMNetwork object
1995f2c45f1SShri Abhyankar 
2005f2c45f1SShri Abhyankar   Output Paramters:
2015f2c45f1SShri Abhyankar + vStart - The first vertex point
2025f2c45f1SShri Abhyankar - vEnd   - One beyond the last vertex point
2035f2c45f1SShri Abhyankar 
2045f2c45f1SShri Abhyankar   Level: intermediate
2055f2c45f1SShri Abhyankar 
2065f2c45f1SShri Abhyankar .seealso: DMNetworkGetEdgeRange
2075f2c45f1SShri Abhyankar @*/
2085f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVertexRange(DM dm,PetscInt *vStart,PetscInt *vEnd)
2095f2c45f1SShri Abhyankar {
2105f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
2115f2c45f1SShri Abhyankar 
2125f2c45f1SShri Abhyankar   PetscFunctionBegin;
2135f2c45f1SShri Abhyankar   if (vStart) *vStart = network->vStart;
2145f2c45f1SShri Abhyankar   if (vEnd) *vEnd = network->vEnd;
2155f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
2165f2c45f1SShri Abhyankar }
2175f2c45f1SShri Abhyankar 
2185f2c45f1SShri Abhyankar #undef __FUNCT__
2195f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetEdgeRange"
2205f2c45f1SShri Abhyankar /*@
2215f2c45f1SShri Abhyankar   DMNetworkGetEdgeRange - Get the bounds [start, end) for the edges.
2225f2c45f1SShri Abhyankar 
2235f2c45f1SShri Abhyankar   Not Collective
2245f2c45f1SShri Abhyankar 
2255f2c45f1SShri Abhyankar   Input Parameters:
2265f2c45f1SShri Abhyankar + dm - The DMNetwork object
2275f2c45f1SShri Abhyankar 
2285f2c45f1SShri Abhyankar   Output Paramters:
2295f2c45f1SShri Abhyankar + eStart - The first edge point
2305f2c45f1SShri Abhyankar - eEnd   - One beyond the last edge point
2315f2c45f1SShri Abhyankar 
2325f2c45f1SShri Abhyankar   Level: intermediate
2335f2c45f1SShri Abhyankar 
2345f2c45f1SShri Abhyankar .seealso: DMNetworkGetVertexRange
2355f2c45f1SShri Abhyankar @*/
2365f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetEdgeRange(DM dm,PetscInt *eStart,PetscInt *eEnd)
2375f2c45f1SShri Abhyankar {
2385f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
2395f2c45f1SShri Abhyankar 
2405f2c45f1SShri Abhyankar   PetscFunctionBegin;
2415f2c45f1SShri Abhyankar   if (eStart) *eStart = network->eStart;
2425f2c45f1SShri Abhyankar   if (eEnd) *eEnd = network->eEnd;
2435f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
2445f2c45f1SShri Abhyankar }
2455f2c45f1SShri Abhyankar 
2465f2c45f1SShri Abhyankar #undef __FUNCT__
2475f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkAddComponent"
2485f2c45f1SShri Abhyankar /*@
2495f2c45f1SShri Abhyankar   DMNetworkAddComponent - Adds a network component at the given point (vertex/edge)
2505f2c45f1SShri Abhyankar 
2515f2c45f1SShri Abhyankar   Not Collective
2525f2c45f1SShri Abhyankar 
2535f2c45f1SShri Abhyankar   Input Parameters:
2545f2c45f1SShri Abhyankar + dm           - The DMNetwork object
2555f2c45f1SShri Abhyankar . p            - vertex/edge point
2565f2c45f1SShri Abhyankar . componentkey - component key returned while registering the component
2575f2c45f1SShri Abhyankar - compvalue    - pointer to the data structure for the component
2585f2c45f1SShri Abhyankar 
2595f2c45f1SShri Abhyankar   Level: intermediate
2605f2c45f1SShri Abhyankar 
2615f2c45f1SShri Abhyankar .seealso: DMNetworkGetVertexRange, DMNetworkGetEdgeRange, DMNetworkRegisterComponent
2625f2c45f1SShri Abhyankar @*/
2635f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddComponent(DM dm, PetscInt p,PetscInt componentkey,void* compvalue)
2645f2c45f1SShri Abhyankar {
2655f2c45f1SShri Abhyankar   DM_Network               *network = (DM_Network*)dm->data;
26643a39a44SBarry Smith   DMNetworkComponent       *component = &network->component[componentkey];
2675f2c45f1SShri Abhyankar   DMNetworkComponentHeader header = &network->header[p];
2685f2c45f1SShri Abhyankar   DMNetworkComponentValue  cvalue = &network->cvalue[p];
2695f2c45f1SShri Abhyankar   PetscErrorCode           ierr;
2705f2c45f1SShri Abhyankar 
2715f2c45f1SShri Abhyankar   PetscFunctionBegin;
272fa58f0a9SHong 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);
273fa58f0a9SHong Zhang 
27443a39a44SBarry Smith   header->size[header->ndata] = component->size;
27543a39a44SBarry Smith   ierr = PetscSectionAddDof(network->DataSection,p,component->size);CHKERRQ(ierr);
2765f2c45f1SShri Abhyankar   header->key[header->ndata] = componentkey;
2775f2c45f1SShri Abhyankar   if (header->ndata != 0) header->offset[header->ndata] = header->offset[header->ndata-1] + header->size[header->ndata-1];
2785f2c45f1SShri Abhyankar 
2795f2c45f1SShri Abhyankar   cvalue->data[header->ndata] = (void*)compvalue;
2805f2c45f1SShri Abhyankar   header->ndata++;
2815f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
2825f2c45f1SShri Abhyankar }
2835f2c45f1SShri Abhyankar 
2845f2c45f1SShri Abhyankar #undef __FUNCT__
2855f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetNumComponents"
2865f2c45f1SShri Abhyankar /*@
2875f2c45f1SShri Abhyankar   DMNetworkGetNumComponents - Get the number of components at a vertex/edge
2885f2c45f1SShri Abhyankar 
2895f2c45f1SShri Abhyankar   Not Collective
2905f2c45f1SShri Abhyankar 
2915f2c45f1SShri Abhyankar   Input Parameters:
2925f2c45f1SShri Abhyankar + dm - The DMNetwork object
2935f2c45f1SShri Abhyankar . p  - vertex/edge point
2945f2c45f1SShri Abhyankar 
2955f2c45f1SShri Abhyankar   Output Parameters:
2965f2c45f1SShri Abhyankar . numcomponents - Number of components at the vertex/edge
2975f2c45f1SShri Abhyankar 
2985f2c45f1SShri Abhyankar   Level: intermediate
2995f2c45f1SShri Abhyankar 
3005f2c45f1SShri Abhyankar .seealso: DMNetworkRegisterComponent, DMNetworkAddComponent
3015f2c45f1SShri Abhyankar @*/
3025f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetNumComponents(DM dm,PetscInt p,PetscInt *numcomponents)
3035f2c45f1SShri Abhyankar {
3045f2c45f1SShri Abhyankar   PetscErrorCode ierr;
3055f2c45f1SShri Abhyankar   PetscInt       offset;
3065f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
3075f2c45f1SShri Abhyankar 
3085f2c45f1SShri Abhyankar   PetscFunctionBegin;
3095f2c45f1SShri Abhyankar   ierr = PetscSectionGetOffset(network->DataSection,p,&offset);CHKERRQ(ierr);
3105f2c45f1SShri Abhyankar   *numcomponents = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata;
3115f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
3125f2c45f1SShri Abhyankar }
3135f2c45f1SShri Abhyankar 
3145f2c45f1SShri Abhyankar #undef __FUNCT__
3155f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetComponentTypeOffset"
3165f2c45f1SShri Abhyankar /*@
3175f2c45f1SShri Abhyankar   DMNetworkGetComponentTypeOffset - Gets the type along with the offset for indexing the
3185f2c45f1SShri Abhyankar                                     component value from the component data array
3195f2c45f1SShri Abhyankar 
3205f2c45f1SShri Abhyankar   Not Collective
3215f2c45f1SShri Abhyankar 
3225f2c45f1SShri Abhyankar   Input Parameters:
3235f2c45f1SShri Abhyankar + dm      - The DMNetwork object
3245f2c45f1SShri Abhyankar . p       - vertex/edge point
3255f2c45f1SShri Abhyankar - compnum - component number
3265f2c45f1SShri Abhyankar 
3275f2c45f1SShri Abhyankar   Output Parameters:
3285f2c45f1SShri Abhyankar + compkey - the key obtained when registering the component
3295f2c45f1SShri Abhyankar - offset  - offset into the component data array associated with the vertex/edge point
3305f2c45f1SShri Abhyankar 
3315f2c45f1SShri Abhyankar   Notes:
3325f2c45f1SShri Abhyankar   Typical usage:
3335f2c45f1SShri Abhyankar 
3345f2c45f1SShri Abhyankar   DMNetworkGetComponentDataArray(dm, &arr);
3355f2c45f1SShri Abhyankar   DMNetworkGetVertex/EdgeRange(dm,&Start,&End);
3365f2c45f1SShri Abhyankar   Loop over vertices or edges
3375f2c45f1SShri Abhyankar     DMNetworkGetNumComponents(dm,v,&numcomps);
3385f2c45f1SShri Abhyankar     Loop over numcomps
3395f2c45f1SShri Abhyankar       DMNetworkGetComponentTypeOffset(dm,v,compnum,&key,&offset);
3405f2c45f1SShri Abhyankar       compdata = (UserCompDataType)(arr+offset);
3415f2c45f1SShri Abhyankar 
3425f2c45f1SShri Abhyankar   Level: intermediate
3435f2c45f1SShri Abhyankar 
3445f2c45f1SShri Abhyankar .seealso: DMNetworkGetNumComponents, DMNetworkGetComponentDataArray,
3455f2c45f1SShri Abhyankar @*/
3465f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetComponentTypeOffset(DM dm,PetscInt p, PetscInt compnum, PetscInt *compkey, PetscInt *offset)
3475f2c45f1SShri Abhyankar {
3485f2c45f1SShri Abhyankar   PetscErrorCode           ierr;
3495f2c45f1SShri Abhyankar   PetscInt                 offsetp;
3505f2c45f1SShri Abhyankar   DMNetworkComponentHeader header;
3515f2c45f1SShri Abhyankar   DM_Network               *network = (DM_Network*)dm->data;
3525f2c45f1SShri Abhyankar 
3535f2c45f1SShri Abhyankar   PetscFunctionBegin;
3545f2c45f1SShri Abhyankar   ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr);
3555f2c45f1SShri Abhyankar   header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp);
356d36f4e81SHong Zhang   if (compkey) *compkey = header->key[compnum];
357d36f4e81SHong Zhang   if (offset) *offset  = offsetp+network->dataheadersize+header->offset[compnum];
3585f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
3595f2c45f1SShri Abhyankar }
3605f2c45f1SShri Abhyankar 
3615f2c45f1SShri Abhyankar #undef __FUNCT__
3625f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetVariableOffset"
3635f2c45f1SShri Abhyankar /*@
3645f2c45f1SShri Abhyankar   DMNetworkGetVariableOffset - Get the offset for accessing the variable associated with the given vertex/edge from the local vector.
3655f2c45f1SShri Abhyankar 
3665f2c45f1SShri Abhyankar   Not Collective
3675f2c45f1SShri Abhyankar 
3685f2c45f1SShri Abhyankar   Input Parameters:
3695f2c45f1SShri Abhyankar + dm     - The DMNetwork object
3705f2c45f1SShri Abhyankar - p      - the edge/vertex point
3715f2c45f1SShri Abhyankar 
3725f2c45f1SShri Abhyankar   Output Parameters:
3735f2c45f1SShri Abhyankar . offset - the offset
3745f2c45f1SShri Abhyankar 
3755f2c45f1SShri Abhyankar   Level: intermediate
3765f2c45f1SShri Abhyankar 
3775f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector
3785f2c45f1SShri Abhyankar @*/
3795f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableOffset(DM dm,PetscInt p,PetscInt *offset)
3805f2c45f1SShri Abhyankar {
3815f2c45f1SShri Abhyankar   PetscErrorCode ierr;
3825f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
3835f2c45f1SShri Abhyankar 
3845f2c45f1SShri Abhyankar   PetscFunctionBegin;
3855f2c45f1SShri Abhyankar   ierr = PetscSectionGetOffset(network->DofSection,p,offset);CHKERRQ(ierr);
3865f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
3875f2c45f1SShri Abhyankar }
3885f2c45f1SShri Abhyankar 
3895f2c45f1SShri Abhyankar #undef __FUNCT__
3905f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetVariableGlobalOffset"
3915f2c45f1SShri Abhyankar /*@
3925f2c45f1SShri Abhyankar   DMNetworkGetVariableGlobalOffset - Get the global offset for the variable associated with the given vertex/edge from the global vector.
3935f2c45f1SShri Abhyankar 
3945f2c45f1SShri Abhyankar   Not Collective
3955f2c45f1SShri Abhyankar 
3965f2c45f1SShri Abhyankar   Input Parameters:
3975f2c45f1SShri Abhyankar + dm      - The DMNetwork object
3985f2c45f1SShri Abhyankar - p       - the edge/vertex point
3995f2c45f1SShri Abhyankar 
4005f2c45f1SShri Abhyankar   Output Parameters:
4015f2c45f1SShri Abhyankar . offsetg - the offset
4025f2c45f1SShri Abhyankar 
4035f2c45f1SShri Abhyankar   Level: intermediate
4045f2c45f1SShri Abhyankar 
4055f2c45f1SShri Abhyankar .seealso: DMNetworkGetVariableOffset, DMGetLocalVector
4065f2c45f1SShri Abhyankar @*/
4075f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetVariableGlobalOffset(DM dm,PetscInt p,PetscInt *offsetg)
4085f2c45f1SShri Abhyankar {
4095f2c45f1SShri Abhyankar   PetscErrorCode ierr;
4105f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
4115f2c45f1SShri Abhyankar 
4125f2c45f1SShri Abhyankar   PetscFunctionBegin;
4135f2c45f1SShri Abhyankar   ierr = PetscSectionGetOffset(network->GlobalDofSection,p,offsetg);CHKERRQ(ierr);
414dd6f46cdSHong Zhang   if (*offsetg < 0) *offsetg = -(*offsetg + 1); /* Convert to actual global offset for ghost node */
4155f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
4165f2c45f1SShri Abhyankar }
4175f2c45f1SShri Abhyankar 
4185f2c45f1SShri Abhyankar #undef __FUNCT__
41924121865SAdrian Maldonado #define __FUNCT__ "DMNetworkGetEdgeOffset"
42024121865SAdrian Maldonado /*@
42124121865SAdrian Maldonado   DMNetworkGetEdgeOffset - Get the offset for accessing the variable associated with the given edge from the local subvector.
42224121865SAdrian Maldonado 
42324121865SAdrian Maldonado   Not Collective
42424121865SAdrian Maldonado 
42524121865SAdrian Maldonado   Input Parameters:
42624121865SAdrian Maldonado + dm     - The DMNetwork object
42724121865SAdrian Maldonado - p      - the edge point
42824121865SAdrian Maldonado 
42924121865SAdrian Maldonado   Output Parameters:
43024121865SAdrian Maldonado . offset - the offset
43124121865SAdrian Maldonado 
43224121865SAdrian Maldonado   Level: intermediate
43324121865SAdrian Maldonado 
43424121865SAdrian Maldonado .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector
43524121865SAdrian Maldonado @*/
43624121865SAdrian Maldonado PetscErrorCode DMNetworkGetEdgeOffset(DM dm,PetscInt p,PetscInt *offset)
43724121865SAdrian Maldonado {
43824121865SAdrian Maldonado   PetscErrorCode ierr;
43924121865SAdrian Maldonado   DM_Network     *network = (DM_Network*)dm->data;
44024121865SAdrian Maldonado 
44124121865SAdrian Maldonado   PetscFunctionBegin;
44224121865SAdrian Maldonado 
44324121865SAdrian Maldonado   ierr = PetscSectionGetOffset(network->edge.DofSection,p,offset);CHKERRQ(ierr);
44424121865SAdrian Maldonado   PetscFunctionReturn(0);
44524121865SAdrian Maldonado }
44624121865SAdrian Maldonado 
44724121865SAdrian Maldonado #undef __FUNCT__
44824121865SAdrian Maldonado #define __FUNCT__ "DMNetworkGetVertexOffset"
44924121865SAdrian Maldonado /*@
45024121865SAdrian Maldonado   DMNetworkGetVertexOffset - Get the offset for accessing the variable associated with the given vertex from the local subvector.
45124121865SAdrian Maldonado 
45224121865SAdrian Maldonado   Not Collective
45324121865SAdrian Maldonado 
45424121865SAdrian Maldonado   Input Parameters:
45524121865SAdrian Maldonado + dm     - The DMNetwork object
45624121865SAdrian Maldonado - p      - the vertex point
45724121865SAdrian Maldonado 
45824121865SAdrian Maldonado   Output Parameters:
45924121865SAdrian Maldonado . offset - the offset
46024121865SAdrian Maldonado 
46124121865SAdrian Maldonado   Level: intermediate
46224121865SAdrian Maldonado 
46324121865SAdrian Maldonado .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector
46424121865SAdrian Maldonado @*/
46524121865SAdrian Maldonado PetscErrorCode DMNetworkGetVertexOffset(DM dm,PetscInt p,PetscInt *offset)
46624121865SAdrian Maldonado {
46724121865SAdrian Maldonado   PetscErrorCode ierr;
46824121865SAdrian Maldonado   DM_Network     *network = (DM_Network*)dm->data;
46924121865SAdrian Maldonado 
47024121865SAdrian Maldonado   PetscFunctionBegin;
47124121865SAdrian Maldonado 
47224121865SAdrian Maldonado   p -= network->vStart;
47324121865SAdrian Maldonado 
47424121865SAdrian Maldonado   ierr = PetscSectionGetOffset(network->vertex.DofSection,p,offset);CHKERRQ(ierr);
47524121865SAdrian Maldonado   PetscFunctionReturn(0);
47624121865SAdrian Maldonado }
47724121865SAdrian Maldonado #undef __FUNCT__
4785f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkAddNumVariables"
4795f2c45f1SShri Abhyankar /*@
4805f2c45f1SShri Abhyankar   DMNetworkAddNumVariables - Add number of variables associated with a given point.
4815f2c45f1SShri Abhyankar 
4825f2c45f1SShri Abhyankar   Not Collective
4835f2c45f1SShri Abhyankar 
4845f2c45f1SShri Abhyankar   Input Parameters:
4855f2c45f1SShri Abhyankar + dm   - The DMNetworkObject
4865f2c45f1SShri Abhyankar . p    - the vertex/edge point
4875f2c45f1SShri Abhyankar - nvar - number of additional variables
4885f2c45f1SShri Abhyankar 
4895f2c45f1SShri Abhyankar   Level: intermediate
4905f2c45f1SShri Abhyankar 
4915f2c45f1SShri Abhyankar .seealso: DMNetworkSetNumVariables
4925f2c45f1SShri Abhyankar @*/
4935f2c45f1SShri Abhyankar PetscErrorCode DMNetworkAddNumVariables(DM dm,PetscInt p,PetscInt nvar)
4945f2c45f1SShri Abhyankar {
4955f2c45f1SShri Abhyankar   PetscErrorCode ierr;
4965f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
4975f2c45f1SShri Abhyankar 
4985f2c45f1SShri Abhyankar   PetscFunctionBegin;
4995f2c45f1SShri Abhyankar   ierr = PetscSectionAddDof(network->DofSection,p,nvar);CHKERRQ(ierr);
5005f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
5015f2c45f1SShri Abhyankar }
5025f2c45f1SShri Abhyankar 
5035f2c45f1SShri Abhyankar #undef __FUNCT__
50427f51fceSHong Zhang #define __FUNCT__ "DMNetworkGetNumVariables"
50527f51fceSHong Zhang /*@
50627f51fceSHong Zhang   DMNetworkGetNumVariables - Gets number of variables for a vertex/edge point.
50727f51fceSHong Zhang 
50827f51fceSHong Zhang   Not Collective
50927f51fceSHong Zhang 
51027f51fceSHong Zhang   Input Parameters:
51127f51fceSHong Zhang + dm   - The DMNetworkObject
51227f51fceSHong Zhang - p    - the vertex/edge point
51327f51fceSHong Zhang 
51427f51fceSHong Zhang   Output Parameters:
51527f51fceSHong Zhang . nvar - number of variables
51627f51fceSHong Zhang 
51727f51fceSHong Zhang   Level: intermediate
51827f51fceSHong Zhang 
51927f51fceSHong Zhang .seealso: DMNetworkAddNumVariables, DMNetworkSddNumVariables
52027f51fceSHong Zhang @*/
52127f51fceSHong Zhang PetscErrorCode DMNetworkGetNumVariables(DM dm,PetscInt p,PetscInt *nvar)
52227f51fceSHong Zhang {
52327f51fceSHong Zhang   PetscErrorCode ierr;
52427f51fceSHong Zhang   DM_Network     *network = (DM_Network*)dm->data;
52527f51fceSHong Zhang 
52627f51fceSHong Zhang   PetscFunctionBegin;
52727f51fceSHong Zhang   ierr = PetscSectionGetDof(network->DofSection,p,nvar);CHKERRQ(ierr);
52827f51fceSHong Zhang   PetscFunctionReturn(0);
52927f51fceSHong Zhang }
53027f51fceSHong Zhang 
53127f51fceSHong Zhang #undef __FUNCT__
532662b5b01SHong Zhang #define __FUNCT__ "DMNetworkSetNumVariables"
5335f2c45f1SShri Abhyankar /*@
5345f2c45f1SShri Abhyankar   DMNetworkSetNumVariables - Sets number of variables for a vertex/edge point.
5355f2c45f1SShri Abhyankar 
5365f2c45f1SShri Abhyankar   Not Collective
5375f2c45f1SShri Abhyankar 
5385f2c45f1SShri Abhyankar   Input Parameters:
5395f2c45f1SShri Abhyankar + dm   - The DMNetworkObject
5405f2c45f1SShri Abhyankar . p    - the vertex/edge point
5415f2c45f1SShri Abhyankar - nvar - number of variables
5425f2c45f1SShri Abhyankar 
5435f2c45f1SShri Abhyankar   Level: intermediate
5445f2c45f1SShri Abhyankar 
5455f2c45f1SShri Abhyankar .seealso: DMNetworkAddNumVariables
5465f2c45f1SShri Abhyankar @*/
5475f2c45f1SShri Abhyankar PetscErrorCode DMNetworkSetNumVariables(DM dm,PetscInt p,PetscInt nvar)
5485f2c45f1SShri Abhyankar {
5495f2c45f1SShri Abhyankar   PetscErrorCode ierr;
5505f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
5515f2c45f1SShri Abhyankar 
5525f2c45f1SShri Abhyankar   PetscFunctionBegin;
5535f2c45f1SShri Abhyankar   ierr = PetscSectionSetDof(network->DofSection,p,nvar);CHKERRQ(ierr);
5545f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
5555f2c45f1SShri Abhyankar }
5565f2c45f1SShri Abhyankar 
5575f2c45f1SShri Abhyankar /* Sets up the array that holds the data for all components and its associated section. This
5585f2c45f1SShri Abhyankar    function is called during DMSetUp() */
5595f2c45f1SShri Abhyankar #undef __FUNCT__
5605f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkComponentSetUp"
5615f2c45f1SShri Abhyankar PetscErrorCode DMNetworkComponentSetUp(DM dm)
5625f2c45f1SShri Abhyankar {
5635f2c45f1SShri Abhyankar   PetscErrorCode              ierr;
5645f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
5655f2c45f1SShri Abhyankar   PetscInt                    arr_size;
5665f2c45f1SShri Abhyankar   PetscInt                    p,offset,offsetp;
5675f2c45f1SShri Abhyankar   DMNetworkComponentHeader header;
5685f2c45f1SShri Abhyankar   DMNetworkComponentValue  cvalue;
5695f2c45f1SShri Abhyankar   DMNetworkComponentGenericDataType      *componentdataarray;
5705f2c45f1SShri Abhyankar   PetscInt ncomp, i;
5715f2c45f1SShri Abhyankar 
5725f2c45f1SShri Abhyankar   PetscFunctionBegin;
5735f2c45f1SShri Abhyankar   ierr = PetscSectionSetUp(network->DataSection);CHKERRQ(ierr);
5745f2c45f1SShri Abhyankar   ierr = PetscSectionGetStorageSize(network->DataSection,&arr_size);CHKERRQ(ierr);
57575b160a0SShri Abhyankar   ierr = PetscMalloc1(arr_size,&network->componentdataarray);CHKERRQ(ierr);
5765f2c45f1SShri Abhyankar   componentdataarray = network->componentdataarray;
5775f2c45f1SShri Abhyankar   for (p = network->pStart; p < network->pEnd; p++) {
5785f2c45f1SShri Abhyankar     ierr = PetscSectionGetOffset(network->DataSection,p,&offsetp);CHKERRQ(ierr);
5795f2c45f1SShri Abhyankar     /* Copy header */
5805f2c45f1SShri Abhyankar     header = &network->header[p];
581302440fdSBarry Smith     ierr = PetscMemcpy(componentdataarray+offsetp,header,network->dataheadersize*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr);
5825f2c45f1SShri Abhyankar     /* Copy data */
5835f2c45f1SShri Abhyankar     cvalue = &network->cvalue[p];
5845f2c45f1SShri Abhyankar     ncomp = header->ndata;
5855f2c45f1SShri Abhyankar     for (i = 0; i < ncomp; i++) {
5865f2c45f1SShri Abhyankar       offset = offsetp + network->dataheadersize + header->offset[i];
587302440fdSBarry Smith       ierr = PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType));CHKERRQ(ierr);
5885f2c45f1SShri Abhyankar     }
5895f2c45f1SShri Abhyankar   }
5905f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
5915f2c45f1SShri Abhyankar }
5925f2c45f1SShri Abhyankar 
5935f2c45f1SShri Abhyankar /* Sets up the section for dofs. This routine is called during DMSetUp() */
5945f2c45f1SShri Abhyankar #undef __FUNCT__
5955f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkVariablesSetUp"
5965f2c45f1SShri Abhyankar PetscErrorCode DMNetworkVariablesSetUp(DM dm)
5975f2c45f1SShri Abhyankar {
5985f2c45f1SShri Abhyankar   PetscErrorCode ierr;
5995f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
6005f2c45f1SShri Abhyankar 
6015f2c45f1SShri Abhyankar   PetscFunctionBegin;
6025f2c45f1SShri Abhyankar   ierr = PetscSectionSetUp(network->DofSection);CHKERRQ(ierr);
6035f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
6045f2c45f1SShri Abhyankar }
6055f2c45f1SShri Abhyankar 
6065f2c45f1SShri Abhyankar #undef __FUNCT__
6075f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetComponentDataArray"
6085f2c45f1SShri Abhyankar /*@C
6095f2c45f1SShri Abhyankar   DMNetworkGetComponentDataArray - Returns the component data array
6105f2c45f1SShri Abhyankar 
6115f2c45f1SShri Abhyankar   Not Collective
6125f2c45f1SShri Abhyankar 
6135f2c45f1SShri Abhyankar   Input Parameters:
6145f2c45f1SShri Abhyankar . dm - The DMNetwork Object
6155f2c45f1SShri Abhyankar 
6165f2c45f1SShri Abhyankar   Output Parameters:
6175f2c45f1SShri Abhyankar . componentdataarray - array that holds data for all components
6185f2c45f1SShri Abhyankar 
6195f2c45f1SShri Abhyankar   Level: intermediate
6205f2c45f1SShri Abhyankar 
6215f2c45f1SShri Abhyankar .seealso: DMNetworkGetComponentTypeOffset, DMNetworkGetNumComponents
6225f2c45f1SShri Abhyankar @*/
6235f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetComponentDataArray(DM dm,DMNetworkComponentGenericDataType **componentdataarray)
6245f2c45f1SShri Abhyankar {
6255f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
6265f2c45f1SShri Abhyankar 
6275f2c45f1SShri Abhyankar   PetscFunctionBegin;
6285f2c45f1SShri Abhyankar   *componentdataarray = network->componentdataarray;
6295f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
6305f2c45f1SShri Abhyankar }
6315f2c45f1SShri Abhyankar 
6325f2c45f1SShri Abhyankar #undef __FUNCT__
63324121865SAdrian Maldonado #define __FUNCT__ "DMNetworkGetSubSection_private"
63424121865SAdrian Maldonado /* Get a subsection from a range of points */
63524121865SAdrian Maldonado PetscErrorCode DMNetworkGetSubSection_private(PetscSection master, PetscInt pstart, PetscInt pend,PetscSection *subsection)
63624121865SAdrian Maldonado {
63724121865SAdrian Maldonado   PetscErrorCode ierr;
63824121865SAdrian Maldonado   PetscInt       i, nvar;
63924121865SAdrian Maldonado 
64024121865SAdrian Maldonado   PetscFunctionBegin;
64124121865SAdrian Maldonado   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)master), subsection);CHKERRQ(ierr);
64224121865SAdrian Maldonado   ierr = PetscSectionSetChart(*subsection, 0, pend - pstart);CHKERRQ(ierr);
64324121865SAdrian Maldonado   for (i = pstart; i < pend; i++) {
64424121865SAdrian Maldonado     ierr = PetscSectionGetDof(master,i,&nvar);CHKERRQ(ierr);
64524121865SAdrian Maldonado     ierr = PetscSectionSetDof(*subsection, i - pstart, nvar);CHKERRQ(ierr);
64624121865SAdrian Maldonado   }
64724121865SAdrian Maldonado 
64824121865SAdrian Maldonado   ierr = PetscSectionSetUp(*subsection);CHKERRQ(ierr);
64924121865SAdrian Maldonado   PetscFunctionReturn(0);
65024121865SAdrian Maldonado }
65124121865SAdrian Maldonado 
65224121865SAdrian Maldonado #undef __FUNCT__
65324121865SAdrian Maldonado #define __FUNCT__ "DMNetworkSetSubMap_private"
65424121865SAdrian Maldonado /* Create a submap of points with a GlobalToLocal structure */
65524121865SAdrian Maldonado PetscErrorCode DMNetworkSetSubMap_private(PetscInt pstart, PetscInt pend, ISLocalToGlobalMapping *map)
65624121865SAdrian Maldonado {
65724121865SAdrian Maldonado   PetscErrorCode ierr;
65824121865SAdrian Maldonado   PetscInt       i, *subpoints;
65924121865SAdrian Maldonado 
66024121865SAdrian Maldonado   PetscFunctionBegin;
66124121865SAdrian Maldonado   /* Create index sets to map from "points" to "subpoints" */
66224121865SAdrian Maldonado   ierr = PetscMalloc1(pend - pstart, &subpoints);CHKERRQ(ierr);
66324121865SAdrian Maldonado   for (i = pstart; i < pend; i++) {
66424121865SAdrian Maldonado     subpoints[i - pstart] = i;
66524121865SAdrian Maldonado   }
666*459726d8SSatish Balay   ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,pend-pstart,subpoints,PETSC_COPY_VALUES,map);CHKERRQ(ierr);
66724121865SAdrian Maldonado   ierr = PetscFree(subpoints);CHKERRQ(ierr);
66824121865SAdrian Maldonado   PetscFunctionReturn(0);
66924121865SAdrian Maldonado }
67024121865SAdrian Maldonado 
67124121865SAdrian Maldonado #undef __FUNCT__
67224121865SAdrian Maldonado #define __FUNCT__ "DMNetworkAssembleGraphStructures"
67324121865SAdrian Maldonado /*@
67424121865SAdrian Maldonado   DMNetworkAssembleGraphStructures - Assembles vertex and edge data structures. Must be called after DMNetworkDistribute.
67524121865SAdrian Maldonado 
67624121865SAdrian Maldonado   Collective
67724121865SAdrian Maldonado 
67824121865SAdrian Maldonado   Input Parameters:
67924121865SAdrian Maldonado . dm   - The DMNetworkObject
68024121865SAdrian Maldonado 
68124121865SAdrian Maldonado   Note: the routine will create alternative orderings for the vertices and edges. Assume global network points are:
68224121865SAdrian Maldonado 
68324121865SAdrian Maldonado   points = [0 1 2 3 4 5 6]
68424121865SAdrian Maldonado 
68524121865SAdrian Maldonado   where edges = [0, 3] and vertices = [4, 6]. The new orderings will be specific to the subset (i.e vertices = [0, 2]).
68624121865SAdrian Maldonado 
68724121865SAdrian Maldonado   With this new ordering a local PetscSection, global PetscSection and PetscSF will be created specific to the subset.
68824121865SAdrian Maldonado 
68924121865SAdrian Maldonado   Level: intermediate
69024121865SAdrian Maldonado 
69124121865SAdrian Maldonado @*/
69224121865SAdrian Maldonado PetscErrorCode DMNetworkAssembleGraphStructures(DM dm)
69324121865SAdrian Maldonado {
69424121865SAdrian Maldonado   PetscErrorCode ierr;
69524121865SAdrian Maldonado   MPI_Comm       comm;
69624121865SAdrian Maldonado   PetscMPIInt    rank, numProcs;
69724121865SAdrian Maldonado   DM_Network     *network = (DM_Network*)dm->data;
69824121865SAdrian Maldonado 
699eab1376dSHong Zhang   PetscFunctionBegin;
70024121865SAdrian Maldonado   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
70124121865SAdrian Maldonado   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
70224121865SAdrian Maldonado   ierr = MPI_Comm_size(comm, &numProcs);CHKERRQ(ierr);
70324121865SAdrian Maldonado 
70424121865SAdrian Maldonado   /* Create maps for vertices and edges */
70524121865SAdrian Maldonado   ierr = DMNetworkSetSubMap_private(network->vStart,network->vEnd,&network->vertex.mapping);CHKERRQ(ierr);
70624121865SAdrian Maldonado   ierr = DMNetworkSetSubMap_private(network->eStart,network->eEnd,&network->edge.mapping);CHKERRQ(ierr);
70724121865SAdrian Maldonado 
70824121865SAdrian Maldonado   /* Create local sub-sections */
70924121865SAdrian Maldonado   ierr = DMNetworkGetSubSection_private(network->DofSection,network->vStart,network->vEnd,&network->vertex.DofSection);CHKERRQ(ierr);
71024121865SAdrian Maldonado   ierr = DMNetworkGetSubSection_private(network->DofSection,network->eStart,network->eEnd,&network->edge.DofSection);CHKERRQ(ierr);
71124121865SAdrian Maldonado 
71224121865SAdrian Maldonado   if (numProcs > 1) {
71324121865SAdrian Maldonado     ierr = PetscSFGetSubSF(network->plex->sf, network->vertex.mapping, &network->vertex.sf);CHKERRQ(ierr);
71424121865SAdrian Maldonado     ierr = PetscSectionCreateGlobalSection(network->vertex.DofSection, network->vertex.sf, PETSC_FALSE, PETSC_FALSE, &network->vertex.GlobalDofSection);CHKERRQ(ierr);
71524121865SAdrian Maldonado   ierr = PetscSFGetSubSF(network->plex->sf, network->edge.mapping, &network->edge.sf);CHKERRQ(ierr);
71624121865SAdrian Maldonado   ierr = PetscSectionCreateGlobalSection(network->edge.DofSection, network->edge.sf, PETSC_FALSE, PETSC_FALSE, &network->edge.GlobalDofSection);CHKERRQ(ierr);
71724121865SAdrian Maldonado   } else {
71824121865SAdrian Maldonado   /* create structures for vertex */
71924121865SAdrian Maldonado   ierr = PetscSectionClone(network->vertex.DofSection,&network->vertex.GlobalDofSection);CHKERRQ(ierr);
72024121865SAdrian Maldonado   /* create structures for edge */
72124121865SAdrian Maldonado   ierr = PetscSectionClone(network->edge.DofSection,&network->edge.GlobalDofSection);CHKERRQ(ierr);
72224121865SAdrian Maldonado   }
72324121865SAdrian Maldonado 
72424121865SAdrian Maldonado 
72524121865SAdrian Maldonado   /* Add viewers */
72624121865SAdrian Maldonado   ierr = PetscObjectSetName((PetscObject)network->edge.GlobalDofSection,"Global edge dof section");CHKERRQ(ierr);
72724121865SAdrian Maldonado   ierr = PetscObjectSetName((PetscObject)network->vertex.GlobalDofSection,"Global vertex dof section");CHKERRQ(ierr);
72824121865SAdrian Maldonado   ierr = PetscSectionViewFromOptions(network->edge.GlobalDofSection, NULL, "-edge_global_section_view");CHKERRQ(ierr);
72924121865SAdrian Maldonado   ierr = PetscSectionViewFromOptions(network->vertex.GlobalDofSection, NULL, "-vertex_global_section_view");CHKERRQ(ierr);
73024121865SAdrian Maldonado 
73124121865SAdrian Maldonado   PetscFunctionReturn(0);
73224121865SAdrian Maldonado }
73324121865SAdrian Maldonado #undef __FUNCT__
7345f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkDistribute"
7355f2c45f1SShri Abhyankar /*@
7365f2c45f1SShri Abhyankar   DMNetworkDistribute - Distributes the network and moves associated component data.
7375f2c45f1SShri Abhyankar 
7385f2c45f1SShri Abhyankar   Collective
7395f2c45f1SShri Abhyankar 
7405f2c45f1SShri Abhyankar   Input Parameter:
7415f2c45f1SShri Abhyankar + oldDM - the original DMNetwork object
7425f2c45f1SShri Abhyankar - overlap - The overlap of partitions, 0 is the default
7435f2c45f1SShri Abhyankar 
7445f2c45f1SShri Abhyankar   Output Parameter:
7455f2c45f1SShri Abhyankar . distDM - the distributed DMNetwork object
7465f2c45f1SShri Abhyankar 
7475f2c45f1SShri Abhyankar   Notes:
7485f2c45f1SShri Abhyankar   This routine should be called only when using multiple processors.
7495f2c45f1SShri Abhyankar 
7508b171c8eSHong Zhang   Distributes the network with <overlap>-overlapping partitioning of the edges.
7515f2c45f1SShri Abhyankar 
7525f2c45f1SShri Abhyankar   Level: intermediate
7535f2c45f1SShri Abhyankar 
7545f2c45f1SShri Abhyankar .seealso: DMNetworkCreate
7555f2c45f1SShri Abhyankar @*/
75680cf41d5SMatthew G. Knepley PetscErrorCode DMNetworkDistribute(DM oldDM, PetscInt overlap,DM *distDM)
7575f2c45f1SShri Abhyankar {
7585f2c45f1SShri Abhyankar   PetscErrorCode ierr;
7595f2c45f1SShri Abhyankar   DM_Network     *oldDMnetwork = (DM_Network*)oldDM->data;
7605f2c45f1SShri Abhyankar   PetscSF        pointsf;
7615f2c45f1SShri Abhyankar   DM             newDM;
7625f2c45f1SShri Abhyankar   DM_Network     *newDMnetwork;
7635f2c45f1SShri Abhyankar 
7645f2c45f1SShri Abhyankar   PetscFunctionBegin;
7655f2c45f1SShri Abhyankar   ierr = DMNetworkCreate(PetscObjectComm((PetscObject)oldDM),&newDM);CHKERRQ(ierr);
7665f2c45f1SShri Abhyankar   newDMnetwork = (DM_Network*)newDM->data;
7675f2c45f1SShri Abhyankar   newDMnetwork->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType);
7685f2c45f1SShri Abhyankar   /* Distribute plex dm and dof section */
76980cf41d5SMatthew G. Knepley   ierr = DMPlexDistribute(oldDMnetwork->plex,overlap,&pointsf,&newDMnetwork->plex);CHKERRQ(ierr);
7705f2c45f1SShri Abhyankar   /* Distribute dof section */
7715f2c45f1SShri Abhyankar   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)oldDM),&newDMnetwork->DofSection);CHKERRQ(ierr);
7725f2c45f1SShri Abhyankar   ierr = PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);CHKERRQ(ierr);
7735f2c45f1SShri Abhyankar   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)oldDM),&newDMnetwork->DataSection);CHKERRQ(ierr);
7745f2c45f1SShri Abhyankar   /* Distribute data and associated section */
77531da1fc8SHong Zhang   ierr = DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPIU_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);CHKERRQ(ierr);
77624121865SAdrian Maldonado 
7775f2c45f1SShri Abhyankar 
7785f2c45f1SShri Abhyankar   ierr = PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);CHKERRQ(ierr);
7795f2c45f1SShri Abhyankar   ierr = DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);CHKERRQ(ierr);
7805f2c45f1SShri Abhyankar   ierr = DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);CHKERRQ(ierr);
7815f2c45f1SShri Abhyankar   newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart;
7825f2c45f1SShri Abhyankar   newDMnetwork->nNodes = newDMnetwork->vEnd - newDMnetwork->vStart;
7835f2c45f1SShri Abhyankar   newDMnetwork->NNodes = oldDMnetwork->NNodes;
7845f2c45f1SShri Abhyankar   newDMnetwork->NEdges = oldDMnetwork->NEdges;
78524121865SAdrian Maldonado 
7865f2c45f1SShri Abhyankar   /* Set Dof section as the default section for dm */
7875f2c45f1SShri Abhyankar   ierr = DMSetDefaultSection(newDMnetwork->plex,newDMnetwork->DofSection);CHKERRQ(ierr);
7885f2c45f1SShri Abhyankar   ierr = DMGetDefaultGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);CHKERRQ(ierr);
7895f2c45f1SShri Abhyankar 
79024121865SAdrian Maldonado   /* Destroy point SF */
79124121865SAdrian Maldonado   ierr = PetscSFDestroy(&pointsf);CHKERRQ(ierr);
79224121865SAdrian Maldonado 
7935f2c45f1SShri Abhyankar   *distDM = newDM;
7945f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
7955f2c45f1SShri Abhyankar }
7965f2c45f1SShri Abhyankar 
7975f2c45f1SShri Abhyankar #undef __FUNCT__
79824121865SAdrian Maldonado #define __FUNCT__ "PetscSFGetSubSF"
79924121865SAdrian Maldonado /*@C
80024121865SAdrian Maldonado   PetscSFGetSubSF - Returns an SF for a specific subset of points. Leaves are re-numbered to reflect the new ordering.
80124121865SAdrian Maldonado 
80224121865SAdrian Maldonado   Input Parameters:
80324121865SAdrian Maldonado + masterSF - the original SF structure
80424121865SAdrian Maldonado - map      - a ISLocalToGlobal mapping that contains the subset of points
80524121865SAdrian Maldonado 
80624121865SAdrian Maldonado   Output Parameters:
80724121865SAdrian Maldonado . subSF    - a subset of the masterSF for the desired subset.
80824121865SAdrian Maldonado */
80924121865SAdrian Maldonado 
81024121865SAdrian Maldonado PetscErrorCode PetscSFGetSubSF(PetscSF mastersf, ISLocalToGlobalMapping map, PetscSF *subSF) {
81124121865SAdrian Maldonado 
81224121865SAdrian Maldonado   PetscErrorCode        ierr;
81324121865SAdrian Maldonado   PetscInt              nroots, nleaves, *ilocal_sub;
81424121865SAdrian Maldonado   PetscInt              i, *ilocal_map, nroots_sub, nleaves_sub = 0;
81524121865SAdrian Maldonado   PetscInt              *local_points, *remote_points;
81624121865SAdrian Maldonado   PetscSFNode           *iremote_sub;
81724121865SAdrian Maldonado   const PetscInt        *ilocal;
81824121865SAdrian Maldonado   const PetscSFNode     *iremote;
81924121865SAdrian Maldonado 
82024121865SAdrian Maldonado   PetscFunctionBegin;
82124121865SAdrian Maldonado   ierr = PetscSFGetGraph(mastersf,&nroots,&nleaves,&ilocal,&iremote);CHKERRQ(ierr);
82224121865SAdrian Maldonado 
82324121865SAdrian Maldonado   /* Look for leaves that pertain to the subset of points. Get the local ordering */
82424121865SAdrian Maldonado   ierr = PetscMalloc1(nleaves,&ilocal_map);CHKERRQ(ierr);
82524121865SAdrian Maldonado   ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nleaves,ilocal,NULL,ilocal_map);CHKERRQ(ierr);
82624121865SAdrian Maldonado   for (i = 0; i < nleaves; i++) {
82724121865SAdrian Maldonado     if (ilocal_map[i] != -1) nleaves_sub += 1;
82824121865SAdrian Maldonado   }
82924121865SAdrian Maldonado   /* Re-number ilocal with subset numbering. Need information from roots */
83024121865SAdrian Maldonado   ierr = PetscMalloc2(nroots,&local_points,nroots,&remote_points);CHKERRQ(ierr);
83124121865SAdrian Maldonado   for (i = 0; i < nroots; i++) local_points[i] = i;
83224121865SAdrian Maldonado   ierr = ISGlobalToLocalMappingApply(map,IS_GTOLM_MASK,nroots,local_points,NULL,local_points);CHKERRQ(ierr);
83324121865SAdrian Maldonado   ierr = PetscSFBcastBegin(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr);
83424121865SAdrian Maldonado   ierr = PetscSFBcastEnd(mastersf, MPIU_INT, local_points, remote_points);CHKERRQ(ierr);
83524121865SAdrian Maldonado   /* Fill up graph using local (that is, local to the subset) numbering. */
8364b70a8deSAdrian Maldonado   ierr = PetscMalloc1(nleaves_sub,&ilocal_sub);CHKERRQ(ierr);
8374b70a8deSAdrian Maldonado   ierr = PetscMalloc1(nleaves_sub,&iremote_sub);CHKERRQ(ierr);
83824121865SAdrian Maldonado   nleaves_sub = 0;
83924121865SAdrian Maldonado   for (i = 0; i < nleaves; i++) {
84024121865SAdrian Maldonado     if (ilocal_map[i] != -1) {
84124121865SAdrian Maldonado       ilocal_sub[nleaves_sub] = ilocal_map[i];
8424b70a8deSAdrian Maldonado       iremote_sub[nleaves_sub].rank = iremote[i].rank;
84324121865SAdrian Maldonado       iremote_sub[nleaves_sub].index = remote_points[ilocal[i]];
84424121865SAdrian Maldonado       nleaves_sub += 1;
84524121865SAdrian Maldonado     }
84624121865SAdrian Maldonado   }
84724121865SAdrian Maldonado   ierr = PetscFree2(local_points,remote_points);CHKERRQ(ierr);
84824121865SAdrian Maldonado   ierr = ISLocalToGlobalMappingGetSize(map,&nroots_sub);CHKERRQ(ierr);
84924121865SAdrian Maldonado 
85024121865SAdrian Maldonado   /* Create new subSF */
85124121865SAdrian Maldonado   ierr = PetscSFCreate(PETSC_COMM_WORLD,subSF);CHKERRQ(ierr);
85224121865SAdrian Maldonado   ierr = PetscSFSetFromOptions(*subSF);CHKERRQ(ierr);
8534b70a8deSAdrian Maldonado   ierr = PetscSFSetGraph(*subSF,nroots_sub,nleaves_sub,ilocal_sub,PETSC_OWN_POINTER,iremote_sub,PETSC_COPY_VALUES);CHKERRQ(ierr);
85424121865SAdrian Maldonado   ierr = PetscFree(ilocal_map);CHKERRQ(ierr);
8554b70a8deSAdrian Maldonado   ierr = PetscFree(iremote_sub);CHKERRQ(ierr);
85624121865SAdrian Maldonado 
85724121865SAdrian Maldonado   PetscFunctionReturn(0);
85824121865SAdrian Maldonado }
85924121865SAdrian Maldonado 
86024121865SAdrian Maldonado 
86124121865SAdrian Maldonado #undef __FUNCT__
8625f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetSupportingEdges"
8635f2c45f1SShri Abhyankar /*@C
8645f2c45f1SShri Abhyankar   DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point
8655f2c45f1SShri Abhyankar 
8665f2c45f1SShri Abhyankar   Not Collective
8675f2c45f1SShri Abhyankar 
8685f2c45f1SShri Abhyankar   Input Parameters:
8695f2c45f1SShri Abhyankar + dm - The DMNetwork object
8705f2c45f1SShri Abhyankar - p  - the vertex point
8715f2c45f1SShri Abhyankar 
8725f2c45f1SShri Abhyankar   Output Paramters:
8735f2c45f1SShri Abhyankar + nedges - number of edges connected to this vertex point
8745f2c45f1SShri Abhyankar - edges  - List of edge points
8755f2c45f1SShri Abhyankar 
8765f2c45f1SShri Abhyankar   Level: intermediate
8775f2c45f1SShri Abhyankar 
8785f2c45f1SShri Abhyankar   Fortran Notes:
8795f2c45f1SShri Abhyankar   Since it returns an array, this routine is only available in Fortran 90, and you must
8805f2c45f1SShri Abhyankar   include petsc.h90 in your code.
8815f2c45f1SShri Abhyankar 
8825f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkGetConnectedNodes
8835f2c45f1SShri Abhyankar @*/
8845f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[])
8855f2c45f1SShri Abhyankar {
8865f2c45f1SShri Abhyankar   PetscErrorCode ierr;
8875f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
8885f2c45f1SShri Abhyankar 
8895f2c45f1SShri Abhyankar   PetscFunctionBegin;
8905f2c45f1SShri Abhyankar   ierr = DMPlexGetSupportSize(network->plex,vertex,nedges);CHKERRQ(ierr);
8915f2c45f1SShri Abhyankar   ierr = DMPlexGetSupport(network->plex,vertex,edges);CHKERRQ(ierr);
8925f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
8935f2c45f1SShri Abhyankar }
8945f2c45f1SShri Abhyankar 
8955f2c45f1SShri Abhyankar #undef __FUNCT__
8965f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkGetConnectedNodes"
8975f2c45f1SShri Abhyankar /*@C
898596e729fSHong Zhang   DMNetworkGetConnectedNodes - Return the connected vertices for this edge point
8995f2c45f1SShri Abhyankar 
9005f2c45f1SShri Abhyankar   Not Collective
9015f2c45f1SShri Abhyankar 
9025f2c45f1SShri Abhyankar   Input Parameters:
9035f2c45f1SShri Abhyankar + dm - The DMNetwork object
9045f2c45f1SShri Abhyankar - p  - the edge point
9055f2c45f1SShri Abhyankar 
9065f2c45f1SShri Abhyankar   Output Paramters:
9075f2c45f1SShri Abhyankar . vertices  - vertices connected to this edge
9085f2c45f1SShri Abhyankar 
9095f2c45f1SShri Abhyankar   Level: intermediate
9105f2c45f1SShri Abhyankar 
9115f2c45f1SShri Abhyankar   Fortran Notes:
9125f2c45f1SShri Abhyankar   Since it returns an array, this routine is only available in Fortran 90, and you must
9135f2c45f1SShri Abhyankar   include petsc.h90 in your code.
9145f2c45f1SShri Abhyankar 
9155f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkGetSupportingEdges
9165f2c45f1SShri Abhyankar @*/
9175f2c45f1SShri Abhyankar PetscErrorCode DMNetworkGetConnectedNodes(DM dm,PetscInt edge,const PetscInt *vertices[])
9185f2c45f1SShri Abhyankar {
9195f2c45f1SShri Abhyankar   PetscErrorCode ierr;
9205f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
9215f2c45f1SShri Abhyankar 
9225f2c45f1SShri Abhyankar   PetscFunctionBegin;
9235f2c45f1SShri Abhyankar   ierr = DMPlexGetCone(network->plex,edge,vertices);CHKERRQ(ierr);
9245f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
9255f2c45f1SShri Abhyankar }
9265f2c45f1SShri Abhyankar 
9275f2c45f1SShri Abhyankar #undef __FUNCT__
9285f2c45f1SShri Abhyankar #define __FUNCT__ "DMNetworkIsGhostVertex"
9295f2c45f1SShri Abhyankar /*@
9305f2c45f1SShri Abhyankar   DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex
9315f2c45f1SShri Abhyankar 
9325f2c45f1SShri Abhyankar   Not Collective
9335f2c45f1SShri Abhyankar 
9345f2c45f1SShri Abhyankar   Input Parameters:
9355f2c45f1SShri Abhyankar + dm - The DMNetwork object
9365f2c45f1SShri Abhyankar . p  - the vertex point
9375f2c45f1SShri Abhyankar 
9385f2c45f1SShri Abhyankar   Output Parameter:
9395f2c45f1SShri Abhyankar . isghost - TRUE if the vertex is a ghost point
9405f2c45f1SShri Abhyankar 
9415f2c45f1SShri Abhyankar   Level: intermediate
9425f2c45f1SShri Abhyankar 
9435f2c45f1SShri Abhyankar .seealso: DMNetworkCreate, DMNetworkGetConnectedNodes, DMNetworkGetVertexRange
9445f2c45f1SShri Abhyankar @*/
9455f2c45f1SShri Abhyankar PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost)
9465f2c45f1SShri Abhyankar {
9475f2c45f1SShri Abhyankar   PetscErrorCode ierr;
9485f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*)dm->data;
9495f2c45f1SShri Abhyankar   PetscInt       offsetg;
9505f2c45f1SShri Abhyankar   PetscSection   sectiong;
9515f2c45f1SShri Abhyankar 
9525f2c45f1SShri Abhyankar   PetscFunctionBegin;
9535f2c45f1SShri Abhyankar   *isghost = PETSC_FALSE;
9545f2c45f1SShri Abhyankar   ierr = DMGetDefaultGlobalSection(network->plex,&sectiong);CHKERRQ(ierr);
9555f2c45f1SShri Abhyankar   ierr = PetscSectionGetOffset(sectiong,p,&offsetg);CHKERRQ(ierr);
9565f2c45f1SShri Abhyankar   if (offsetg < 0) *isghost = PETSC_TRUE;
9575f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
9585f2c45f1SShri Abhyankar }
9595f2c45f1SShri Abhyankar 
9605f2c45f1SShri Abhyankar #undef __FUNCT__
9615f2c45f1SShri Abhyankar #define __FUNCT__ "DMSetUp_Network"
9625f2c45f1SShri Abhyankar PetscErrorCode DMSetUp_Network(DM dm)
9635f2c45f1SShri Abhyankar {
9645f2c45f1SShri Abhyankar   PetscErrorCode ierr;
9655f2c45f1SShri Abhyankar   DM_Network     *network=(DM_Network*)dm->data;
9665f2c45f1SShri Abhyankar 
9675f2c45f1SShri Abhyankar   PetscFunctionBegin;
9685f2c45f1SShri Abhyankar   ierr = DMNetworkComponentSetUp(dm);CHKERRQ(ierr);
9695f2c45f1SShri Abhyankar   ierr = DMNetworkVariablesSetUp(dm);CHKERRQ(ierr);
9705f2c45f1SShri Abhyankar 
9715f2c45f1SShri Abhyankar   ierr = DMSetDefaultSection(network->plex,network->DofSection);CHKERRQ(ierr);
9725f2c45f1SShri Abhyankar   ierr = DMGetDefaultGlobalSection(network->plex,&network->GlobalDofSection);CHKERRQ(ierr);
9735f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
9745f2c45f1SShri Abhyankar }
9755f2c45f1SShri Abhyankar 
9765f2c45f1SShri Abhyankar #undef __FUNCT__
97717df6e9eSHong Zhang #define __FUNCT__ "DMNetworkHasJacobian"
9781ad426b7SHong Zhang /*@
97917df6e9eSHong Zhang     DMNetworkHasJacobian - Sets global flag for using user's sub Jacobian matrices
9801ad426b7SHong Zhang                             -- replaced by DMNetworkSetOption(network,userjacobian,PETSC_TURE)?
9811ad426b7SHong Zhang 
9821ad426b7SHong Zhang     Collective
9831ad426b7SHong Zhang 
9841ad426b7SHong Zhang     Input Parameters:
98583b2e829SHong Zhang +   dm - The DMNetwork object
98683b2e829SHong Zhang .   eflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for edges
98783b2e829SHong Zhang -   vflg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) if user provides Jacobian for vertices
9881ad426b7SHong Zhang 
9891ad426b7SHong Zhang     Level: intermediate
9901ad426b7SHong Zhang 
9911ad426b7SHong Zhang @*/
99283b2e829SHong Zhang PetscErrorCode DMNetworkHasJacobian(DM dm,PetscBool eflg,PetscBool vflg)
9931ad426b7SHong Zhang {
9941ad426b7SHong Zhang   DM_Network     *network=(DM_Network*)dm->data;
9951ad426b7SHong Zhang 
9961ad426b7SHong Zhang   PetscFunctionBegin;
99783b2e829SHong Zhang   network->userEdgeJacobian   = eflg;
99883b2e829SHong Zhang   network->userVertexJacobian = vflg;
9991ad426b7SHong Zhang   PetscFunctionReturn(0);
10001ad426b7SHong Zhang }
10011ad426b7SHong Zhang 
10021ad426b7SHong Zhang #undef __FUNCT__
100383b2e829SHong Zhang #define __FUNCT__ "DMNetworkEdgeSetMatrix"
10041ad426b7SHong Zhang /*@
100583b2e829SHong Zhang     DMNetworkEdgeSetMatrix - Sets user-provided Jacobian matrices for this edge to the network
100683b2e829SHong Zhang 
100783b2e829SHong Zhang     Not Collective
100883b2e829SHong Zhang 
100983b2e829SHong Zhang     Input Parameters:
101083b2e829SHong Zhang +   dm - The DMNetwork object
101183b2e829SHong Zhang .   p  - the edge point
10123e97b6e8SHong Zhang -   J - array (size = 3) of Jacobian submatrices for this edge point:
10133e97b6e8SHong Zhang         J[0]: this edge
10143e97b6e8SHong Zhang         J[1] and J[2]: connected vertices, obtained by calling DMNetworkGetConnectedNodes()
101583b2e829SHong Zhang 
101683b2e829SHong Zhang     Level: intermediate
101783b2e829SHong Zhang 
101883b2e829SHong Zhang .seealso: DMNetworkVertexSetMatrix
101983b2e829SHong Zhang @*/
102083b2e829SHong Zhang PetscErrorCode DMNetworkEdgeSetMatrix(DM dm,PetscInt p,Mat J[])
102183b2e829SHong Zhang {
102283b2e829SHong Zhang   PetscErrorCode ierr;
102383b2e829SHong Zhang   DM_Network     *network=(DM_Network*)dm->data;
102483b2e829SHong Zhang 
102583b2e829SHong Zhang   PetscFunctionBegin;
1026883e35e8SHong Zhang   if (!network->userEdgeJacobian) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkEdgeSetMatrix");
102783b2e829SHong Zhang   if (!network->Je) {
1028883e35e8SHong Zhang     ierr = PetscCalloc1(3*network->nEdges,&network->Je);CHKERRQ(ierr);
102983b2e829SHong Zhang   }
1030883e35e8SHong Zhang   network->Je[3*p]   = J[0];
1031883e35e8SHong Zhang   network->Je[3*p+1] = J[1];
1032883e35e8SHong Zhang   network->Je[3*p+2] = J[2];
103383b2e829SHong Zhang   PetscFunctionReturn(0);
103483b2e829SHong Zhang }
103583b2e829SHong Zhang 
103683b2e829SHong Zhang #undef __FUNCT__
1037883e35e8SHong Zhang #define __FUNCT__ "DMNetworkVertexSetMatrix"
103883b2e829SHong Zhang /*@
103976ddfea5SHong Zhang     DMNetworkVertexSetMatrix - Sets user-provided Jacobian matrix for this vertex to the network
10401ad426b7SHong Zhang 
10411ad426b7SHong Zhang     Not Collective
10421ad426b7SHong Zhang 
10431ad426b7SHong Zhang     Input Parameters:
10441ad426b7SHong Zhang +   dm - The DMNetwork object
10451ad426b7SHong Zhang .   p  - the vertex point
10463e97b6e8SHong Zhang -   J - array of Jacobian (size = 2*(num of supporting edges) + 1) submatrices for this vertex point:
10473e97b6e8SHong Zhang         J[0]:       this vertex
10483e97b6e8SHong Zhang         J[1+2*i]:   i-th supporting edge
10493e97b6e8SHong Zhang         J[1+2*i+1]: i-th connected vertex
10501ad426b7SHong Zhang 
10511ad426b7SHong Zhang     Level: intermediate
10521ad426b7SHong Zhang 
105383b2e829SHong Zhang .seealso: DMNetworkEdgeSetMatrix
10541ad426b7SHong Zhang @*/
1055883e35e8SHong Zhang PetscErrorCode DMNetworkVertexSetMatrix(DM dm,PetscInt p,Mat J[])
10565f2c45f1SShri Abhyankar {
10575f2c45f1SShri Abhyankar   PetscErrorCode ierr;
10585f2c45f1SShri Abhyankar   DM_Network     *network=(DM_Network*)dm->data;
1059f4431b8cSHong Zhang   PetscInt       i,*vptr,nedges,vStart,vEnd;
1060883e35e8SHong Zhang   const PetscInt *edges;
10615f2c45f1SShri Abhyankar 
10625f2c45f1SShri Abhyankar   PetscFunctionBegin;
1063883e35e8SHong Zhang   if (!network->userVertexJacobian) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"Must call DMNetworkHasJacobian() collectively before calling DMNetworkVertexSetMatrix");
1064883e35e8SHong Zhang 
1065883e35e8SHong Zhang   ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr);
1066f4431b8cSHong Zhang 
106783b2e829SHong Zhang   if (!network->Jv) {
1068f4431b8cSHong Zhang     PetscInt nNodes = network->nNodes,nedges_total;
1069883e35e8SHong Zhang     /* count nvertex_total */
10703e97b6e8SHong Zhang     nedges_total = 0;
1071883e35e8SHong Zhang     ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr);
1072f4431b8cSHong Zhang     ierr = PetscMalloc1(nNodes+1,&vptr);CHKERRQ(ierr);
1073f4431b8cSHong Zhang 
1074883e35e8SHong Zhang     vptr[0] = 0;
1075f4431b8cSHong Zhang     for (i=0; i<nNodes; i++) {
1076f4431b8cSHong Zhang       ierr = DMNetworkGetSupportingEdges(dm,i+vStart,&nedges,&edges);CHKERRQ(ierr);
1077883e35e8SHong Zhang       nedges_total += nedges;
1078f4431b8cSHong Zhang       vptr[i+1] = vptr[i] + 2*nedges + 1;
10791ad426b7SHong Zhang     }
10803e97b6e8SHong Zhang 
1081f4431b8cSHong Zhang     ierr = PetscCalloc1(2*nedges_total+nNodes,&network->Jv);CHKERRQ(ierr);
1082883e35e8SHong Zhang     network->Jvptr = vptr;
1083883e35e8SHong Zhang   }
1084883e35e8SHong Zhang 
1085883e35e8SHong Zhang   vptr = network->Jvptr;
10863e97b6e8SHong Zhang   network->Jv[vptr[p-vStart]] = J[0]; /* Set Jacobian for this vertex */
10873e97b6e8SHong Zhang 
10883e97b6e8SHong Zhang   /* Set Jacobian for each supporting edge and connected vertex */
1089883e35e8SHong Zhang   ierr = DMNetworkGetSupportingEdges(dm,p,&nedges,&edges);CHKERRQ(ierr);
1090883e35e8SHong Zhang   for (i=1; i<=2*nedges; i++) network->Jv[vptr[p-vStart]+i] = J[i];
1091883e35e8SHong Zhang   PetscFunctionReturn(0);
1092883e35e8SHong Zhang }
1093883e35e8SHong Zhang 
1094883e35e8SHong Zhang #undef __FUNCT__
10955cf7da58SHong Zhang #define __FUNCT__ "MatSetPreallocationDenseblock_private"
1096e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz)
10975cf7da58SHong Zhang {
10985cf7da58SHong Zhang   PetscErrorCode ierr;
10995cf7da58SHong Zhang   PetscInt       j;
11005cf7da58SHong Zhang   PetscScalar    val=(PetscScalar)ncols;
11015cf7da58SHong Zhang 
11025cf7da58SHong Zhang   PetscFunctionBegin;
11035cf7da58SHong Zhang   if (!ghost) {
11045cf7da58SHong Zhang     for (j=0; j<nrows; j++) {
11055cf7da58SHong Zhang       ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr);
11065cf7da58SHong Zhang     }
11075cf7da58SHong Zhang   } else {
11085cf7da58SHong Zhang     for (j=0; j<nrows; j++) {
11095cf7da58SHong Zhang       ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr);
11105cf7da58SHong Zhang     }
11115cf7da58SHong Zhang   }
11125cf7da58SHong Zhang   PetscFunctionReturn(0);
11135cf7da58SHong Zhang }
11145cf7da58SHong Zhang 
11155cf7da58SHong Zhang #undef __FUNCT__
11165cf7da58SHong Zhang #define __FUNCT__ "MatSetPreallocationUserblock_private"
1117e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz)
11185cf7da58SHong Zhang {
11195cf7da58SHong Zhang   PetscErrorCode ierr;
11205cf7da58SHong Zhang   PetscInt       j,ncols_u;
11215cf7da58SHong Zhang   PetscScalar    val;
11225cf7da58SHong Zhang 
11235cf7da58SHong Zhang   PetscFunctionBegin;
11245cf7da58SHong Zhang   if (!ghost) {
11255cf7da58SHong Zhang     for (j=0; j<nrows; j++) {
11265cf7da58SHong Zhang       ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr);
11275cf7da58SHong Zhang       val = (PetscScalar)ncols_u;
11285cf7da58SHong Zhang       ierr = VecSetValues(vdnz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr);
11295cf7da58SHong Zhang       ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr);
11305cf7da58SHong Zhang     }
11315cf7da58SHong Zhang   } else {
11325cf7da58SHong Zhang     for (j=0; j<nrows; j++) {
11335cf7da58SHong Zhang       ierr = MatGetRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr);
11345cf7da58SHong Zhang       val = (PetscScalar)ncols_u;
11355cf7da58SHong Zhang       ierr = VecSetValues(vonz,1,&rows[j],&val,ADD_VALUES);CHKERRQ(ierr);
11365cf7da58SHong Zhang       ierr = MatRestoreRow(Ju,j,&ncols_u,NULL,NULL);CHKERRQ(ierr);
11375cf7da58SHong Zhang     }
11385cf7da58SHong Zhang   }
11395cf7da58SHong Zhang   PetscFunctionReturn(0);
11405cf7da58SHong Zhang }
11415cf7da58SHong Zhang 
11425cf7da58SHong Zhang #undef __FUNCT__
11435cf7da58SHong Zhang #define __FUNCT__ "MatSetPreallocationblock_private"
1144e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetPreallocationblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscBool ghost,Vec vdnz,Vec vonz)
11455cf7da58SHong Zhang {
11465cf7da58SHong Zhang   PetscErrorCode ierr;
11475cf7da58SHong Zhang 
11485cf7da58SHong Zhang   PetscFunctionBegin;
11495cf7da58SHong Zhang   if (Ju) {
11505cf7da58SHong Zhang     ierr = MatSetPreallocationUserblock_private(Ju,nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr);
11515cf7da58SHong Zhang   } else {
11525cf7da58SHong Zhang     ierr = MatSetPreallocationDenseblock_private(nrows,rows,ncols,ghost,vdnz,vonz);CHKERRQ(ierr);
11535cf7da58SHong Zhang   }
11545cf7da58SHong Zhang   PetscFunctionReturn(0);
11555cf7da58SHong Zhang }
11565cf7da58SHong Zhang 
11575cf7da58SHong Zhang #undef __FUNCT__
1158883e35e8SHong Zhang #define __FUNCT__ "MatSetDenseblock_private"
1159e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetDenseblock_private(PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J)
1160883e35e8SHong Zhang {
1161883e35e8SHong Zhang   PetscErrorCode ierr;
1162883e35e8SHong Zhang   PetscInt       j,*cols;
1163883e35e8SHong Zhang   PetscScalar    *zeros;
1164883e35e8SHong Zhang 
1165883e35e8SHong Zhang   PetscFunctionBegin;
1166883e35e8SHong Zhang   ierr = PetscCalloc2(ncols,&cols,nrows*ncols,&zeros);CHKERRQ(ierr);
1167883e35e8SHong Zhang   for (j=0; j<ncols; j++) cols[j] = j+ cstart;
1168883e35e8SHong Zhang   ierr = MatSetValues(*J,nrows,rows,ncols,cols,zeros,INSERT_VALUES);CHKERRQ(ierr);
1169883e35e8SHong Zhang   ierr = PetscFree2(cols,zeros);CHKERRQ(ierr);
11701ad426b7SHong Zhang   PetscFunctionReturn(0);
11711ad426b7SHong Zhang }
1172a4e85ca8SHong Zhang 
11733e97b6e8SHong Zhang #undef __FUNCT__
11743e97b6e8SHong Zhang #define __FUNCT__ "MatSetUserblock_private"
1175e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetUserblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J)
11763e97b6e8SHong Zhang {
11773e97b6e8SHong Zhang   PetscErrorCode ierr;
11783e97b6e8SHong Zhang   PetscInt       j,M,N,row,col,ncols_u;
11793e97b6e8SHong Zhang   const PetscInt *cols;
11803e97b6e8SHong Zhang   PetscScalar    zero=0.0;
11813e97b6e8SHong Zhang 
11823e97b6e8SHong Zhang   PetscFunctionBegin;
11833e97b6e8SHong Zhang   ierr = MatGetSize(Ju,&M,&N);CHKERRQ(ierr);
11843e97b6e8SHong 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);
11853e97b6e8SHong Zhang 
11863e97b6e8SHong Zhang   for (row=0; row<nrows; row++) {
11873e97b6e8SHong Zhang     ierr = MatGetRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr);
11883e97b6e8SHong Zhang     for (j=0; j<ncols_u; j++) {
11893e97b6e8SHong Zhang       col = cols[j] + cstart;
11903e97b6e8SHong Zhang       ierr = MatSetValues(*J,1,&rows[row],1,&col,&zero,INSERT_VALUES);CHKERRQ(ierr);
11913e97b6e8SHong Zhang     }
11923e97b6e8SHong Zhang     ierr = MatRestoreRow(Ju,row,&ncols_u,&cols,NULL);CHKERRQ(ierr);
11933e97b6e8SHong Zhang   }
11943e97b6e8SHong Zhang   PetscFunctionReturn(0);
11953e97b6e8SHong Zhang }
11961ad426b7SHong Zhang 
11971ad426b7SHong Zhang #undef __FUNCT__
1198a4e85ca8SHong Zhang #define __FUNCT__ "MatSetblock_private"
1199e0f69777SHong Zhang PETSC_STATIC_INLINE PetscErrorCode MatSetblock_private(Mat Ju,PetscInt nrows,PetscInt *rows,PetscInt ncols,PetscInt cstart,Mat *J)
1200a4e85ca8SHong Zhang {
1201a4e85ca8SHong Zhang   PetscErrorCode ierr;
1202f4431b8cSHong Zhang 
1203a4e85ca8SHong Zhang   PetscFunctionBegin;
1204a4e85ca8SHong Zhang   if (Ju) {
1205a4e85ca8SHong Zhang     ierr = MatSetUserblock_private(Ju,nrows,rows,ncols,cstart,J);CHKERRQ(ierr);
1206a4e85ca8SHong Zhang   } else {
1207a4e85ca8SHong Zhang     ierr = MatSetDenseblock_private(nrows,rows,ncols,cstart,J);CHKERRQ(ierr);
1208a4e85ca8SHong Zhang   }
1209a4e85ca8SHong Zhang   PetscFunctionReturn(0);
1210a4e85ca8SHong Zhang }
1211a4e85ca8SHong Zhang 
121224121865SAdrian Maldonado 
121324121865SAdrian Maldonado #undef __FUNCT__
121424121865SAdrian Maldonado #define __FUNCT__ "CreateSubGlobalToLocalMapping_private"
121524121865SAdrian 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.
121624121865SAdrian Maldonado */
121724121865SAdrian Maldonado PetscErrorCode CreateSubGlobalToLocalMapping_private(PetscSection globalsec, PetscSection localsec, ISLocalToGlobalMapping *ltog)
121824121865SAdrian Maldonado {
121924121865SAdrian Maldonado   PetscErrorCode ierr;
122024121865SAdrian Maldonado   PetscInt       i, size, dof;
122124121865SAdrian Maldonado   PetscInt       *glob2loc;
122224121865SAdrian Maldonado 
122324121865SAdrian Maldonado   PetscFunctionBegin;
122424121865SAdrian Maldonado   ierr = PetscSectionGetStorageSize(localsec,&size);CHKERRQ(ierr);
122524121865SAdrian Maldonado   ierr = PetscMalloc1(size,&glob2loc);CHKERRQ(ierr);
122624121865SAdrian Maldonado 
122724121865SAdrian Maldonado   for (i = 0; i < size; i++) {
122824121865SAdrian Maldonado     ierr = PetscSectionGetOffset(globalsec,i,&dof);CHKERRQ(ierr);
122924121865SAdrian Maldonado     dof = (dof >= 0) ? dof : -(dof + 1);
123024121865SAdrian Maldonado     glob2loc[i] = dof;
123124121865SAdrian Maldonado   }
123224121865SAdrian Maldonado 
123324121865SAdrian Maldonado   ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_WORLD,1,size,glob2loc,PETSC_OWN_POINTER,ltog);CHKERRQ(ierr);
123424121865SAdrian Maldonado #if 0
123524121865SAdrian Maldonado   ierr = PetscIntView(size,glob2loc,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
123624121865SAdrian Maldonado #endif
123724121865SAdrian Maldonado   PetscFunctionReturn(0);
123824121865SAdrian Maldonado }
123924121865SAdrian Maldonado 
1240a4e85ca8SHong Zhang #undef __FUNCT__
12411ad426b7SHong Zhang #define __FUNCT__ "DMCreateMatrix_Network"
12421ad426b7SHong Zhang PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J)
12431ad426b7SHong Zhang {
12441ad426b7SHong Zhang   PetscErrorCode ierr;
124524121865SAdrian Maldonado   PetscMPIInt    rank, size;
12461ad426b7SHong Zhang   DM_Network     *network = (DM_Network*) dm->data;
1247a4e85ca8SHong Zhang   PetscInt       eStart,eEnd,vStart,vEnd,rstart,nrows,*rows,localSize;
1248840c2264SHong Zhang   PetscInt       cstart,ncols,j,e,v;
124924121865SAdrian Maldonado   PetscBool      ghost,ghost_vc,ghost2,isNest;
1250a4e85ca8SHong Zhang   Mat            Juser;
1251bfbc38dcSHong Zhang   PetscSection   sectionGlobal;
1252447d78afSSatish Balay   PetscInt       nedges,*vptr=NULL,vc,*rows_v; /* suppress maybe-uninitialized warning */
1253a4e85ca8SHong Zhang   const PetscInt *edges,*cone;
12545cf7da58SHong Zhang   MPI_Comm       comm;
125524121865SAdrian Maldonado   MatType        mtype;
12565cf7da58SHong Zhang   Vec            vd_nz,vo_nz;
12575cf7da58SHong Zhang   PetscInt       *dnnz,*onnz;
12585cf7da58SHong Zhang   PetscScalar    *vdnz,*vonz;
12591ad426b7SHong Zhang 
12601ad426b7SHong Zhang   PetscFunctionBegin;
126124121865SAdrian Maldonado   mtype = dm->mattype;
126224121865SAdrian Maldonado   ierr = PetscStrcmp(mtype, MATNEST, &isNest);CHKERRQ(ierr);
126324121865SAdrian Maldonado 
126424121865SAdrian Maldonado   if (isNest) {
12650731d606SHong Zhang     /* ierr = DMCreateMatrix_Network_Nest(); */
126624121865SAdrian Maldonado     PetscInt   eDof, vDof;
126724121865SAdrian Maldonado     Mat        j11, j12, j21, j22, bA[2][2];
126824121865SAdrian Maldonado     ISLocalToGlobalMapping eISMap, vISMap;
126924121865SAdrian Maldonado 
127024121865SAdrian Maldonado     ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
127124121865SAdrian Maldonado     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
127224121865SAdrian Maldonado     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
127324121865SAdrian Maldonado 
127424121865SAdrian Maldonado     ierr = PetscSectionGetConstrainedStorageSize(network->edge.GlobalDofSection,&eDof);CHKERRQ(ierr);
127524121865SAdrian Maldonado     ierr = PetscSectionGetConstrainedStorageSize(network->vertex.GlobalDofSection,&vDof);CHKERRQ(ierr);
127624121865SAdrian Maldonado 
127724121865SAdrian Maldonado #if 0
127824121865SAdrian Maldonado     printf("rank[%d] vdof = %d. edof = %d\n", rank, vDof, eDof);
127924121865SAdrian Maldonado #endif
128024121865SAdrian Maldonado 
128124121865SAdrian Maldonado     ierr = MatCreate(PETSC_COMM_WORLD, &j11);CHKERRQ(ierr);
128224121865SAdrian Maldonado     ierr = MatSetSizes(j11, eDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
128324121865SAdrian Maldonado     ierr = MatSetType(j11, MATMPIAIJ);CHKERRQ(ierr);
128424121865SAdrian Maldonado 
128524121865SAdrian Maldonado     ierr = MatCreate(PETSC_COMM_WORLD, &j12);CHKERRQ(ierr);
128624121865SAdrian Maldonado     ierr = MatSetSizes(j12, eDof, vDof, PETSC_DETERMINE ,PETSC_DETERMINE);CHKERRQ(ierr);
128724121865SAdrian Maldonado     ierr = MatSetType(j12, MATMPIAIJ);CHKERRQ(ierr);
128824121865SAdrian Maldonado 
128924121865SAdrian Maldonado     ierr = MatCreate(PETSC_COMM_WORLD, &j21);CHKERRQ(ierr);
129024121865SAdrian Maldonado     ierr = MatSetSizes(j21, vDof, eDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
129124121865SAdrian Maldonado     ierr = MatSetType(j21, MATMPIAIJ);CHKERRQ(ierr);
129224121865SAdrian Maldonado 
129324121865SAdrian Maldonado     ierr = MatCreate(PETSC_COMM_WORLD, &j22);CHKERRQ(ierr);
129424121865SAdrian Maldonado     ierr = MatSetSizes(j22, vDof, vDof, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
129524121865SAdrian Maldonado     ierr = MatSetType(j22, MATMPIAIJ);CHKERRQ(ierr);
129624121865SAdrian Maldonado 
129724121865SAdrian Maldonado     bA[0][0] = j11;
129824121865SAdrian Maldonado     bA[0][1] = j12;
129924121865SAdrian Maldonado     bA[1][0] = j21;
130024121865SAdrian Maldonado     bA[1][1] = j22;
130124121865SAdrian Maldonado 
130224121865SAdrian Maldonado     ierr = CreateSubGlobalToLocalMapping_private(network->edge.GlobalDofSection,network->edge.DofSection,&eISMap);CHKERRQ(ierr);
130324121865SAdrian Maldonado     ierr = CreateSubGlobalToLocalMapping_private(network->vertex.GlobalDofSection,network->vertex.DofSection,&vISMap);CHKERRQ(ierr);
130424121865SAdrian Maldonado 
130524121865SAdrian Maldonado     ierr = MatSetLocalToGlobalMapping(j11,eISMap,eISMap);CHKERRQ(ierr);
130624121865SAdrian Maldonado     ierr = MatSetLocalToGlobalMapping(j12,eISMap,vISMap);CHKERRQ(ierr);
130724121865SAdrian Maldonado     ierr = MatSetLocalToGlobalMapping(j21,vISMap,eISMap);CHKERRQ(ierr);
130824121865SAdrian Maldonado     ierr = MatSetLocalToGlobalMapping(j22,vISMap,vISMap);CHKERRQ(ierr);
130924121865SAdrian Maldonado 
131024121865SAdrian Maldonado     ierr = MatSetUp(j11);CHKERRQ(ierr);
131124121865SAdrian Maldonado     ierr = MatSetUp(j12);CHKERRQ(ierr);
131224121865SAdrian Maldonado     ierr = MatSetUp(j21);CHKERRQ(ierr);
131324121865SAdrian Maldonado     ierr = MatSetUp(j22);CHKERRQ(ierr);
131424121865SAdrian Maldonado 
131524121865SAdrian Maldonado     ierr = MatCreateNest(PETSC_COMM_WORLD,2,NULL,2,NULL,&bA[0][0],J);CHKERRQ(ierr);
131624121865SAdrian Maldonado     ierr = MatSetUp(*J);CHKERRQ(ierr);
131724121865SAdrian Maldonado     ierr = MatNestSetVecType(*J,VECNEST);CHKERRQ(ierr);
131824121865SAdrian Maldonado     ierr = MatDestroy(&j11);CHKERRQ(ierr);
131924121865SAdrian Maldonado     ierr = MatDestroy(&j12);CHKERRQ(ierr);
132024121865SAdrian Maldonado     ierr = MatDestroy(&j21);CHKERRQ(ierr);
132124121865SAdrian Maldonado     ierr = MatDestroy(&j22);CHKERRQ(ierr);
132224121865SAdrian Maldonado 
132324121865SAdrian Maldonado     ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
132424121865SAdrian Maldonado     ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
132524121865SAdrian Maldonado 
132624121865SAdrian Maldonado     /* Free structures */
132724121865SAdrian Maldonado     ierr = ISLocalToGlobalMappingDestroy(&eISMap);CHKERRQ(ierr);
132824121865SAdrian Maldonado     ierr = ISLocalToGlobalMappingDestroy(&vISMap);CHKERRQ(ierr);
132924121865SAdrian Maldonado 
133024121865SAdrian Maldonado     PetscFunctionReturn(0);
133124121865SAdrian Maldonado   } else if (!network->userEdgeJacobian && !network->userVertexJacobian) {
1332a4e85ca8SHong Zhang     /* user does not provide Jacobian blocks */
1333bfbc38dcSHong Zhang     ierr = DMCreateMatrix(network->plex,J);CHKERRQ(ierr);
1334bfbc38dcSHong Zhang     ierr = MatSetDM(*J,dm);CHKERRQ(ierr);
13351ad426b7SHong Zhang     PetscFunctionReturn(0);
13361ad426b7SHong Zhang   }
13371ad426b7SHong Zhang 
1338bfbc38dcSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)dm),J);CHKERRQ(ierr);
13392a945128SHong Zhang   ierr = DMGetDefaultGlobalSection(network->plex,&sectionGlobal);CHKERRQ(ierr);
1340bfbc38dcSHong Zhang   ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal,&localSize);CHKERRQ(ierr);
1341bfbc38dcSHong Zhang   ierr = MatSetSizes(*J,localSize,localSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
13422a945128SHong Zhang 
13432a945128SHong Zhang   ierr = MatSetType(*J,MATAIJ);CHKERRQ(ierr);
13442a945128SHong Zhang   ierr = MatSetFromOptions(*J);CHKERRQ(ierr);
134589898e50SHong Zhang 
134689898e50SHong Zhang   /* (1) Set matrix preallocation */
134789898e50SHong Zhang   /*------------------------------*/
1348840c2264SHong Zhang   ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr);
1349840c2264SHong Zhang   ierr = VecCreate(comm,&vd_nz);CHKERRQ(ierr);
1350840c2264SHong Zhang   ierr = VecSetSizes(vd_nz,localSize,PETSC_DECIDE);CHKERRQ(ierr);
1351840c2264SHong Zhang   ierr = VecSetFromOptions(vd_nz);CHKERRQ(ierr);
1352840c2264SHong Zhang   ierr = VecSet(vd_nz,0.0);CHKERRQ(ierr);
1353840c2264SHong Zhang   ierr = VecDuplicate(vd_nz,&vo_nz);CHKERRQ(ierr);
1354840c2264SHong Zhang 
135589898e50SHong Zhang   /* Set preallocation for edges */
135689898e50SHong Zhang   /*-----------------------------*/
1357840c2264SHong Zhang   ierr = DMNetworkGetEdgeRange(dm,&eStart,&eEnd);CHKERRQ(ierr);
1358840c2264SHong Zhang 
1359bdcb62a2SHong Zhang   ierr = PetscMalloc1(localSize,&rows);CHKERRQ(ierr);
1360840c2264SHong Zhang   for (e=eStart; e<eEnd; e++) {
1361840c2264SHong Zhang     /* Get row indices */
1362840c2264SHong Zhang     ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr);
1363840c2264SHong Zhang     ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr);
1364840c2264SHong Zhang     if (nrows) {
1365840c2264SHong Zhang       if (!network->Je) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Uer must provide Je");
1366840c2264SHong Zhang       for (j=0; j<nrows; j++) rows[j] = j + rstart;
1367840c2264SHong Zhang 
13685cf7da58SHong Zhang       /* Set preallocation for conntected vertices */
1369840c2264SHong Zhang       ierr = DMNetworkGetConnectedNodes(dm,e,&cone);CHKERRQ(ierr);
1370840c2264SHong Zhang       for (v=0; v<2; v++) {
1371840c2264SHong Zhang         ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr);
1372840c2264SHong Zhang 
1373840c2264SHong Zhang         Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */
1374840c2264SHong Zhang         ierr = DMNetworkIsGhostVertex(dm,cone[v],&ghost);CHKERRQ(ierr);
13755cf7da58SHong Zhang         ierr = MatSetPreallocationblock_private(Juser,nrows,rows,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr);
1376840c2264SHong Zhang       }
1377840c2264SHong Zhang 
137889898e50SHong Zhang       /* Set preallocation for edge self */
1379840c2264SHong Zhang       cstart = rstart;
1380840c2264SHong Zhang       Juser = network->Je[3*e]; /* Jacobian(e,e) */
13815cf7da58SHong Zhang       ierr = MatSetPreallocationblock_private(Juser,nrows,rows,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr);
1382840c2264SHong Zhang     }
1383840c2264SHong Zhang   }
1384840c2264SHong Zhang 
138589898e50SHong Zhang   /* Set preallocation for vertices */
138689898e50SHong Zhang   /*--------------------------------*/
1387840c2264SHong Zhang   ierr = DMNetworkGetVertexRange(dm,&vStart,&vEnd);CHKERRQ(ierr);
1388840c2264SHong Zhang   if (vEnd - vStart) {
1389840c2264SHong Zhang     if (!network->Jv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Uer must provide Jv");
1390840c2264SHong Zhang     vptr = network->Jvptr;
1391840c2264SHong Zhang     if (!vptr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Uer must provide vptr");
1392840c2264SHong Zhang   }
1393840c2264SHong Zhang 
1394840c2264SHong Zhang   for (v=vStart; v<vEnd; v++) {
1395840c2264SHong Zhang     /* Get row indices */
1396840c2264SHong Zhang     ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr);
1397840c2264SHong Zhang     ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr);
1398840c2264SHong Zhang     if (!nrows) continue;
1399840c2264SHong Zhang 
1400bdcb62a2SHong Zhang     ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr);
1401bdcb62a2SHong Zhang     if (ghost) {
1402bdcb62a2SHong Zhang       ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr);
1403bdcb62a2SHong Zhang     } else {
1404bdcb62a2SHong Zhang       rows_v = rows;
1405bdcb62a2SHong Zhang     }
1406bdcb62a2SHong Zhang 
1407bdcb62a2SHong Zhang     for (j=0; j<nrows; j++) rows_v[j] = j + rstart;
1408840c2264SHong Zhang 
1409840c2264SHong Zhang     /* Get supporting edges and connected vertices */
1410840c2264SHong Zhang     ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr);
1411840c2264SHong Zhang 
1412840c2264SHong Zhang     for (e=0; e<nedges; e++) {
1413840c2264SHong Zhang       /* Supporting edges */
1414840c2264SHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr);
1415840c2264SHong Zhang       ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr);
1416840c2264SHong Zhang 
1417840c2264SHong Zhang       Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */
1418bdcb62a2SHong Zhang       ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost,vd_nz,vo_nz);CHKERRQ(ierr);
1419840c2264SHong Zhang 
1420840c2264SHong Zhang       /* Connected vertices */
1421840c2264SHong Zhang       ierr = DMNetworkGetConnectedNodes(dm,edges[e],&cone);CHKERRQ(ierr);
1422840c2264SHong Zhang       vc = (v == cone[0]) ? cone[1]:cone[0];
1423840c2264SHong Zhang       ierr = DMNetworkIsGhostVertex(dm,vc,&ghost_vc);CHKERRQ(ierr);
1424840c2264SHong Zhang 
1425840c2264SHong Zhang       ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr);
1426840c2264SHong Zhang 
1427840c2264SHong Zhang       Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */
1428e102a522SHong Zhang       if (ghost_vc||ghost) {
1429e102a522SHong Zhang         ghost2 = PETSC_TRUE;
1430e102a522SHong Zhang       } else {
1431e102a522SHong Zhang         ghost2 = PETSC_FALSE;
1432e102a522SHong Zhang       }
1433e102a522SHong Zhang       ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,ncols,ghost2,vd_nz,vo_nz);CHKERRQ(ierr);
1434840c2264SHong Zhang     }
1435840c2264SHong Zhang 
143689898e50SHong Zhang     /* Set preallocation for vertex self */
1437840c2264SHong Zhang     ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr);
1438840c2264SHong Zhang     if (!ghost) {
1439840c2264SHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr);
1440840c2264SHong Zhang       Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */
1441bdcb62a2SHong Zhang       ierr = MatSetPreallocationblock_private(Juser,nrows,rows_v,nrows,PETSC_FALSE,vd_nz,vo_nz);CHKERRQ(ierr);
1442840c2264SHong Zhang     }
1443bdcb62a2SHong Zhang     if (ghost) {
1444bdcb62a2SHong Zhang       ierr = PetscFree(rows_v);CHKERRQ(ierr);
1445bdcb62a2SHong Zhang     }
1446840c2264SHong Zhang   }
1447840c2264SHong Zhang 
1448840c2264SHong Zhang   ierr = VecAssemblyBegin(vd_nz);CHKERRQ(ierr);
1449840c2264SHong Zhang   ierr = VecAssemblyBegin(vo_nz);CHKERRQ(ierr);
14505cf7da58SHong Zhang 
14515cf7da58SHong Zhang   ierr = PetscMalloc2(localSize,&dnnz,localSize,&onnz);CHKERRQ(ierr);
14525cf7da58SHong Zhang 
14535cf7da58SHong Zhang   ierr = VecAssemblyEnd(vd_nz);CHKERRQ(ierr);
1454840c2264SHong Zhang   ierr = VecAssemblyEnd(vo_nz);CHKERRQ(ierr);
1455840c2264SHong Zhang 
1456840c2264SHong Zhang   ierr = VecGetArray(vd_nz,&vdnz);CHKERRQ(ierr);
1457840c2264SHong Zhang   ierr = VecGetArray(vo_nz,&vonz);CHKERRQ(ierr);
1458840c2264SHong Zhang   for (j=0; j<localSize; j++) {
1459e102a522SHong Zhang     dnnz[j] = (PetscInt)PetscRealPart(vdnz[j]);
1460e102a522SHong Zhang     onnz[j] = (PetscInt)PetscRealPart(vonz[j]);
1461840c2264SHong Zhang   }
1462840c2264SHong Zhang   ierr = VecRestoreArray(vd_nz,&vdnz);CHKERRQ(ierr);
1463840c2264SHong Zhang   ierr = VecRestoreArray(vo_nz,&vonz);CHKERRQ(ierr);
1464840c2264SHong Zhang   ierr = VecDestroy(&vd_nz);CHKERRQ(ierr);
1465840c2264SHong Zhang   ierr = VecDestroy(&vo_nz);CHKERRQ(ierr);
1466840c2264SHong Zhang 
14675cf7da58SHong Zhang   ierr = MatSeqAIJSetPreallocation(*J,0,dnnz);CHKERRQ(ierr);
14685cf7da58SHong Zhang   ierr = MatMPIAIJSetPreallocation(*J,0,dnnz,0,onnz);CHKERRQ(ierr);
14695cf7da58SHong Zhang   ierr = MatSetOption(*J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);
14705cf7da58SHong Zhang 
14715cf7da58SHong Zhang   ierr = PetscFree2(dnnz,onnz);CHKERRQ(ierr);
14725cf7da58SHong Zhang 
147389898e50SHong Zhang   /* (2) Set matrix entries for edges */
147489898e50SHong Zhang   /*----------------------------------*/
14751ad426b7SHong Zhang   for (e=eStart; e<eEnd; e++) {
1476bfbc38dcSHong Zhang     /* Get row indices */
14771ad426b7SHong Zhang     ierr = DMNetworkGetVariableGlobalOffset(dm,e,&rstart);CHKERRQ(ierr);
147817df6e9eSHong Zhang     ierr = DMNetworkGetNumVariables(dm,e,&nrows);CHKERRQ(ierr);
14794b976069SHong Zhang     if (nrows) {
14804b976069SHong Zhang       if (!network->Je) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Uer must provide Je");
1481bdcb62a2SHong Zhang 
148217df6e9eSHong Zhang       for (j=0; j<nrows; j++) rows[j] = j + rstart;
14831ad426b7SHong Zhang 
1484bfbc38dcSHong Zhang       /* Set matrix entries for conntected vertices */
148517df6e9eSHong Zhang       ierr = DMNetworkGetConnectedNodes(dm,e,&cone);CHKERRQ(ierr);
1486bfbc38dcSHong Zhang       for (v=0; v<2; v++) {
1487bfbc38dcSHong Zhang         ierr = DMNetworkGetVariableGlobalOffset(dm,cone[v],&cstart);CHKERRQ(ierr);
1488883e35e8SHong Zhang         ierr = DMNetworkGetNumVariables(dm,cone[v],&ncols);CHKERRQ(ierr);
14893e97b6e8SHong Zhang 
1490a4e85ca8SHong Zhang         Juser = network->Je[3*e+1+v]; /* Jacobian(e,v) */
1491a4e85ca8SHong Zhang         ierr = MatSetblock_private(Juser,nrows,rows,ncols,cstart,J);CHKERRQ(ierr);
1492bfbc38dcSHong Zhang       }
149317df6e9eSHong Zhang 
1494bfbc38dcSHong Zhang       /* Set matrix entries for edge self */
14953e97b6e8SHong Zhang       cstart = rstart;
1496a4e85ca8SHong Zhang       Juser = network->Je[3*e]; /* Jacobian(e,e) */
1497a4e85ca8SHong Zhang       ierr = MatSetblock_private(Juser,nrows,rows,nrows,cstart,J);CHKERRQ(ierr);
14981ad426b7SHong Zhang     }
14994b976069SHong Zhang   }
15001ad426b7SHong Zhang 
1501bfbc38dcSHong Zhang   /* Set matrix entries for vertices */
150283b2e829SHong Zhang   /*---------------------------------*/
15031ad426b7SHong Zhang   for (v=vStart; v<vEnd; v++) {
1504bfbc38dcSHong Zhang     /* Get row indices */
1505596e729fSHong Zhang     ierr = DMNetworkGetVariableGlobalOffset(dm,v,&rstart);CHKERRQ(ierr);
1506596e729fSHong Zhang     ierr = DMNetworkGetNumVariables(dm,v,&nrows);CHKERRQ(ierr);
15074b976069SHong Zhang     if (!nrows) continue;
1508596e729fSHong Zhang 
1509bdcb62a2SHong Zhang     ierr = DMNetworkIsGhostVertex(dm,v,&ghost);CHKERRQ(ierr);
1510bdcb62a2SHong Zhang     if (ghost) {
1511bdcb62a2SHong Zhang       ierr = PetscMalloc1(nrows,&rows_v);CHKERRQ(ierr);
1512bdcb62a2SHong Zhang     } else {
1513bdcb62a2SHong Zhang       rows_v = rows;
1514bdcb62a2SHong Zhang     }
1515bdcb62a2SHong Zhang     for (j=0; j<nrows; j++) rows_v[j] = j + rstart;
1516596e729fSHong Zhang 
1517bfbc38dcSHong Zhang     /* Get supporting edges and connected vertices */
1518596e729fSHong Zhang     ierr = DMNetworkGetSupportingEdges(dm,v,&nedges,&edges);CHKERRQ(ierr);
1519596e729fSHong Zhang 
1520596e729fSHong Zhang     for (e=0; e<nedges; e++) {
1521bfbc38dcSHong Zhang       /* Supporting edges */
1522596e729fSHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,edges[e],&cstart);CHKERRQ(ierr);
1523596e729fSHong Zhang       ierr = DMNetworkGetNumVariables(dm,edges[e],&ncols);CHKERRQ(ierr);
1524596e729fSHong Zhang 
1525a4e85ca8SHong Zhang       Juser = network->Jv[vptr[v-vStart]+2*e+1]; /* Jacobian(v,e) */
1526bdcb62a2SHong Zhang       ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr);
1527596e729fSHong Zhang 
1528bfbc38dcSHong Zhang       /* Connected vertices */
152944aca652SHong Zhang       ierr = DMNetworkGetConnectedNodes(dm,edges[e],&cone);CHKERRQ(ierr);
15302a945128SHong Zhang       vc = (v == cone[0]) ? cone[1]:cone[0];
15312a945128SHong Zhang 
153244aca652SHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,vc,&cstart);CHKERRQ(ierr);
153344aca652SHong Zhang       ierr = DMNetworkGetNumVariables(dm,vc,&ncols);CHKERRQ(ierr);
1534a4e85ca8SHong Zhang 
1535a4e85ca8SHong Zhang       Juser = network->Jv[vptr[v-vStart]+2*e+2]; /* Jacobian(v,vc) */
1536bdcb62a2SHong Zhang       ierr = MatSetblock_private(Juser,nrows,rows_v,ncols,cstart,J);CHKERRQ(ierr);
1537596e729fSHong Zhang     }
1538596e729fSHong Zhang 
1539bfbc38dcSHong Zhang     /* Set matrix entries for vertex self */
15401ad426b7SHong Zhang     if (!ghost) {
1541596e729fSHong Zhang       ierr = DMNetworkGetVariableGlobalOffset(dm,v,&cstart);CHKERRQ(ierr);
1542a4e85ca8SHong Zhang       Juser = network->Jv[vptr[v-vStart]]; /* Jacobian(v,v) */
1543bdcb62a2SHong Zhang       ierr = MatSetblock_private(Juser,nrows,rows_v,nrows,cstart,J);CHKERRQ(ierr);
1544bdcb62a2SHong Zhang     }
1545bdcb62a2SHong Zhang     if (ghost) {
1546bdcb62a2SHong Zhang       ierr = PetscFree(rows_v);CHKERRQ(ierr);
1547bdcb62a2SHong Zhang     }
15481ad426b7SHong Zhang   }
1549a4e85ca8SHong Zhang   ierr = PetscFree(rows);CHKERRQ(ierr);
1550bdcb62a2SHong Zhang 
15511ad426b7SHong Zhang   ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15521ad426b7SHong Zhang   ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1553dd6f46cdSHong Zhang 
15545f2c45f1SShri Abhyankar   ierr = MatSetDM(*J,dm);CHKERRQ(ierr);
15555f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
15565f2c45f1SShri Abhyankar }
15575f2c45f1SShri Abhyankar 
15585f2c45f1SShri Abhyankar #undef __FUNCT__
15595f2c45f1SShri Abhyankar #define __FUNCT__ "DMDestroy_Network"
15605f2c45f1SShri Abhyankar PetscErrorCode DMDestroy_Network(DM dm)
15615f2c45f1SShri Abhyankar {
15625f2c45f1SShri Abhyankar   PetscErrorCode ierr;
15635f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
15645f2c45f1SShri Abhyankar 
15655f2c45f1SShri Abhyankar   PetscFunctionBegin;
15668415c774SShri Abhyankar   if (--network->refct > 0) PetscFunctionReturn(0);
156783b2e829SHong Zhang   if (network->Je) {
156883b2e829SHong Zhang     ierr = PetscFree(network->Je);CHKERRQ(ierr);
156983b2e829SHong Zhang   }
157083b2e829SHong Zhang   if (network->Jv) {
1571883e35e8SHong Zhang     ierr = PetscFree(network->Jvptr);CHKERRQ(ierr);
157283b2e829SHong Zhang     ierr = PetscFree(network->Jv);CHKERRQ(ierr);
15731ad426b7SHong Zhang   }
157413c2a604SAdrian Maldonado 
157513c2a604SAdrian Maldonado   ierr = ISLocalToGlobalMappingDestroy(&network->vertex.mapping);CHKERRQ(ierr);
157613c2a604SAdrian Maldonado   ierr = PetscSectionDestroy(&network->vertex.DofSection);CHKERRQ(ierr);
157713c2a604SAdrian Maldonado   ierr = PetscSectionDestroy(&network->vertex.GlobalDofSection);CHKERRQ(ierr);
157813c2a604SAdrian Maldonado   if (network->vertex.sf) {
157913c2a604SAdrian Maldonado     ierr = PetscSFDestroy(&network->vertex.sf);CHKERRQ(ierr);
158013c2a604SAdrian Maldonado   }
158113c2a604SAdrian Maldonado   /* edge */
158213c2a604SAdrian Maldonado   ierr = ISLocalToGlobalMappingDestroy(&network->edge.mapping);CHKERRQ(ierr);
158313c2a604SAdrian Maldonado   ierr = PetscSectionDestroy(&network->edge.DofSection);CHKERRQ(ierr);
158413c2a604SAdrian Maldonado   ierr = PetscSectionDestroy(&network->edge.GlobalDofSection);CHKERRQ(ierr);
158513c2a604SAdrian Maldonado   if (network->edge.sf) {
158613c2a604SAdrian Maldonado     ierr = PetscSFDestroy(&network->edge.sf);CHKERRQ(ierr);
158713c2a604SAdrian Maldonado   }
15885f2c45f1SShri Abhyankar   ierr = DMDestroy(&network->plex);CHKERRQ(ierr);
15895f2c45f1SShri Abhyankar   network->edges = NULL;
15905f2c45f1SShri Abhyankar   ierr = PetscSectionDestroy(&network->DataSection);CHKERRQ(ierr);
15915f2c45f1SShri Abhyankar   ierr = PetscSectionDestroy(&network->DofSection);CHKERRQ(ierr);
159283b2e829SHong Zhang 
15935f2c45f1SShri Abhyankar   ierr = PetscFree(network->componentdataarray);CHKERRQ(ierr);
15945f2c45f1SShri Abhyankar   ierr = PetscFree(network->cvalue);CHKERRQ(ierr);
15955f2c45f1SShri Abhyankar   ierr = PetscFree(network->header);CHKERRQ(ierr);
15965f2c45f1SShri Abhyankar   ierr = PetscFree(network);CHKERRQ(ierr);
15975f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
15985f2c45f1SShri Abhyankar }
15995f2c45f1SShri Abhyankar 
16005f2c45f1SShri Abhyankar #undef __FUNCT__
16015f2c45f1SShri Abhyankar #define __FUNCT__ "DMView_Network"
16025f2c45f1SShri Abhyankar PetscErrorCode DMView_Network(DM dm, PetscViewer viewer)
16035f2c45f1SShri Abhyankar {
16045f2c45f1SShri Abhyankar   PetscErrorCode ierr;
16055f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
16065f2c45f1SShri Abhyankar 
16075f2c45f1SShri Abhyankar   PetscFunctionBegin;
16085f2c45f1SShri Abhyankar   ierr = DMView(network->plex,viewer);CHKERRQ(ierr);
16095f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
16105f2c45f1SShri Abhyankar }
16115f2c45f1SShri Abhyankar 
16125f2c45f1SShri Abhyankar #undef __FUNCT__
16135f2c45f1SShri Abhyankar #define __FUNCT__ "DMGlobalToLocalBegin_Network"
16145f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l)
16155f2c45f1SShri Abhyankar {
16165f2c45f1SShri Abhyankar   PetscErrorCode ierr;
16175f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
16185f2c45f1SShri Abhyankar 
16195f2c45f1SShri Abhyankar   PetscFunctionBegin;
16205f2c45f1SShri Abhyankar   ierr = DMGlobalToLocalBegin(network->plex,g,mode,l);CHKERRQ(ierr);
16215f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
16225f2c45f1SShri Abhyankar }
16235f2c45f1SShri Abhyankar 
16245f2c45f1SShri Abhyankar #undef __FUNCT__
16255f2c45f1SShri Abhyankar #define __FUNCT__ "DMGlobalToLocalEnd_Network"
16265f2c45f1SShri Abhyankar PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l)
16275f2c45f1SShri Abhyankar {
16285f2c45f1SShri Abhyankar   PetscErrorCode ierr;
16295f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
16305f2c45f1SShri Abhyankar 
16315f2c45f1SShri Abhyankar   PetscFunctionBegin;
16325f2c45f1SShri Abhyankar   ierr = DMGlobalToLocalEnd(network->plex,g,mode,l);CHKERRQ(ierr);
16335f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
16345f2c45f1SShri Abhyankar }
16355f2c45f1SShri Abhyankar 
16365f2c45f1SShri Abhyankar #undef __FUNCT__
16375f2c45f1SShri Abhyankar #define __FUNCT__ "DMLocalToGlobalBegin_Network"
16385f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g)
16395f2c45f1SShri Abhyankar {
16405f2c45f1SShri Abhyankar   PetscErrorCode ierr;
16415f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
16425f2c45f1SShri Abhyankar 
16435f2c45f1SShri Abhyankar   PetscFunctionBegin;
16445f2c45f1SShri Abhyankar   ierr = DMLocalToGlobalBegin(network->plex,l,mode,g);CHKERRQ(ierr);
16455f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
16465f2c45f1SShri Abhyankar }
16475f2c45f1SShri Abhyankar 
16485f2c45f1SShri Abhyankar #undef __FUNCT__
16495f2c45f1SShri Abhyankar #define __FUNCT__ "DMLocalToGlobalEnd_Network"
16505f2c45f1SShri Abhyankar PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g)
16515f2c45f1SShri Abhyankar {
16525f2c45f1SShri Abhyankar   PetscErrorCode ierr;
16535f2c45f1SShri Abhyankar   DM_Network     *network = (DM_Network*) dm->data;
16545f2c45f1SShri Abhyankar 
16555f2c45f1SShri Abhyankar   PetscFunctionBegin;
16565f2c45f1SShri Abhyankar   ierr = DMLocalToGlobalEnd(network->plex,l,mode,g);CHKERRQ(ierr);
16575f2c45f1SShri Abhyankar   PetscFunctionReturn(0);
16585f2c45f1SShri Abhyankar }
1659