Date: 2015-10-02T22:16:20+00:00

Actual source code: network.c
petsc-3.6.2 2015-10-02
Report Typos and Errors

      1: #include <petsc/private/dmnetworkimpl.h>  /*I  "petscdmnetwork.h"  I*/
      2: #include <petscdmplex.h>
      3: #include <petscsf.h>

      7: /*@
      8:   DMNetworkSetSizes - Sets the local and global vertices and edges.

     10:   Collective on DM
     11:
     12:   Input Parameters:
     13: + dm - the dm object
     14: . nV - number of local vertices
     15: . nE - number of local edges
     16: . NV - number of global vertices (or PETSC_DETERMINE)
     17: - NE - number of global edges (or PETSC_DETERMINE)

     19:    Notes
     20:    If one processor calls this with NV (NE) of PETSC_DECIDE then all processors must, otherwise the prgram will hang.

     22:    You cannot change the sizes once they have been set

     24:    Level: intermediate

     26: .seealso: DMNetworkCreate
     27: @*/
     28: PetscErrorCode DMNetworkSetSizes(DM dm, PetscInt nV, PetscInt nE, PetscInt NV, PetscInt NE)
     29: {
     31:   DM_Network     *network = (DM_Network*) dm->data;
     32:   PetscInt       a[2],b[2];

     38:   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);
     39:   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);
     40:   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);
     41:   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);
     42:   if (NE < 0 || NV < 0) {
     43:     a[0] = nV; a[1] = nE;
     44:     MPI_Allreduce(a,b,2,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));
     45:     NV = b[0]; NE = b[1];
     46:   }
     47:   network->nNodes = nV;
     48:   network->NNodes = NV;
     49:   network->nEdges = nE;
     50:   network->NEdges = NE;
     51:   return(0);
     52: }

     56: /*@
     57:   DMNetworkSetEdgeList - Sets the list of local edges (vertex connectivity) for the network

     59:   Logically collective on DM

     61:   Input Parameters:
     62: . edges - list of edges

     64:   Notes:
     65:   There is no copy involved in this operation, only the pointer is referenced. The edgelist should
     66:   not be destroyed before the call to DMNetworkLayoutSetUp

     68:   Level: intermediate

     70: .seealso: DMNetworkCreate, DMNetworkSetSizes
     71: @*/
     72: PetscErrorCode DMNetworkSetEdgeList(DM dm, int edgelist[])
     73: {
     74:   DM_Network *network = (DM_Network*) dm->data;
     75:
     77:   network->edges = edgelist;
     78:   return(0);
     79: }

     83: /*@
     84:   DMNetworkLayoutSetUp - Sets up the bare layout (graph) for the network

     86:   Collective on DM

     88:   Input Parameters
     89: . DM - the dmnetwork object

     91:   Notes:
     92:   This routine should be called after the network sizes and edgelists have been provided. It creates
     93:   the bare layout of the network and sets up the network to begin insertion of components.

     95:   All the components should be registered before calling this routine.

     97:   Level: intermediate

     99: .seealso: DMNetworkSetSizes, DMNetworkSetEdgeList
    100: @*/
    101: PetscErrorCode DMNetworkLayoutSetUp(DM dm)
    102: {
    104:   DM_Network     *network = (DM_Network*) dm->data;
    105:   PetscInt       dim = 1; /* One dimensional network */
    106:   PetscInt       numCorners=2;
    107:   PetscInt       spacedim=2;
    108:   double         *vertexcoords=NULL;
    109:   PetscInt       i;
    110:   PetscInt       ndata;

    113:   if (network->nNodes) {
    114:     PetscMalloc1(numCorners*network->nNodes,&vertexcoords);
    115:   }
    116:   DMPlexCreateFromCellList(PetscObjectComm((PetscObject)dm),dim,network->nEdges,network->nNodes,numCorners,PETSC_FALSE,network->edges,spacedim,vertexcoords,&network->plex);
    117:   if (network->nNodes) {
    118:     PetscFree(vertexcoords);
    119:   }
    120:   DMPlexGetChart(network->plex,&network->pStart,&network->pEnd);
    121:   DMPlexGetHeightStratum(network->plex,0,&network->eStart,&network->eEnd);
    122:   DMPlexGetHeightStratum(network->plex,1,&network->vStart,&network->vEnd);

    124:   PetscSectionCreate(PetscObjectComm((PetscObject)dm),&network->DataSection);
    125:   PetscSectionCreate(PetscObjectComm((PetscObject)dm),&network->DofSection);
    126:   PetscSectionSetChart(network->DataSection,network->pStart,network->pEnd);
    127:   PetscSectionSetChart(network->DofSection,network->pStart,network->pEnd);

    129:   network->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType);
    130:   PetscMalloc1(network->pEnd-network->pStart,&network->header);
    131:   for (i = network->pStart; i < network->pEnd; i++) {
    132:     network->header[i].ndata = 0;
    133:     ndata = network->header[i].ndata;
    134:     PetscSectionAddDof(network->DataSection,i,network->dataheadersize);
    135:     network->header[i].offset[ndata] = 0;
    136:   }
    137:   PetscMalloc1(network->pEnd-network->pStart,&network->cvalue);
    138:   return(0);
    139: }

    143: /*@
    144:   DMNetworkRegisterComponent - Registers the network component

    146:   Logically collective on DM

    148:   Input Parameters
    149: + dm   - the network object
    150: . name - the component name
    151: - size - the storage size in bytes for this component data

    153:    Output Parameters
    154: .   key - an integer key that defines the component

    156:    Notes
    157:    This routine should be called by all processors before calling DMNetworkLayoutSetup().

    159:    Level: intermediate

    161: .seealso: DMNetworkLayoutSetUp, DMNetworkCreate
    162: @*/
    163: PetscErrorCode DMNetworkRegisterComponent(DM dm,const char *name,PetscInt size,PetscInt *key)
    164: {
    165:   PetscErrorCode        ierr;
    166:   DM_Network            *network = (DM_Network*) dm->data;
    167:   DMNetworkComponent    *component=&network->component[network->ncomponent];
    168:   PetscBool             flg=PETSC_FALSE;
    169:   PetscInt              i;

    173:   for (i=0; i < network->ncomponent; i++) {
    174:     PetscStrcmp(component->name,name,&flg);
    175:     if (flg) {
    176:       *key = i;
    177:       return(0);
    178:     }
    179:   }
    180:
    181:   PetscStrcpy(component->name,name);
    182:   component->size = size/sizeof(DMNetworkComponentGenericDataType);
    183:   *key = network->ncomponent;
    184:   network->ncomponent++;
    185:   return(0);
    186: }

    190: /*@
    191:   DMNetworkGetVertexRange - Get the bounds [start, end) for the vertices.

    193:   Not Collective

    195:   Input Parameters:
    196: + dm - The DMNetwork object

    198:   Output Paramters:
    199: + vStart - The first vertex point
    200: - vEnd   - One beyond the last vertex point

    202:   Level: intermediate

    204: .seealso: DMNetworkGetEdgeRange
    205: @*/
    206: PetscErrorCode DMNetworkGetVertexRange(DM dm,PetscInt *vStart,PetscInt *vEnd)
    207: {
    208:   DM_Network     *network = (DM_Network*)dm->data;

    211:   if (vStart) *vStart = network->vStart;
    212:   if (vEnd) *vEnd = network->vEnd;
    213:   return(0);
    214: }

    218: /*@
    219:   DMNetworkGetEdgeRange - Get the bounds [start, end) for the edges.

    221:   Not Collective

    223:   Input Parameters:
    224: + dm - The DMNetwork object

    226:   Output Paramters:
    227: + eStart - The first edge point
    228: - eEnd   - One beyond the last edge point

    230:   Level: intermediate

    232: .seealso: DMNetworkGetVertexRange
    233: @*/
    234: PetscErrorCode DMNetworkGetEdgeRange(DM dm,PetscInt *eStart,PetscInt *eEnd)
    235: {
    236:   DM_Network     *network = (DM_Network*)dm->data;

    239:   if (eStart) *eStart = network->eStart;
    240:   if (eEnd) *eEnd = network->eEnd;
    241:   return(0);
    242: }

    246: /*@
    247:   DMNetworkAddComponent - Adds a network component at the given point (vertex/edge)

    249:   Not Collective

    251:   Input Parameters:
    252: + dm           - The DMNetwork object
    253: . p            - vertex/edge point
    254: . componentkey - component key returned while registering the component
    255: - compvalue    - pointer to the data structure for the component

    257:   Level: intermediate

    259: .seealso: DMNetworkGetVertexRange, DMNetworkGetEdgeRange, DMNetworkRegisterComponent
    260: @*/
    261: PetscErrorCode DMNetworkAddComponent(DM dm, PetscInt p,PetscInt componentkey,void* compvalue)
    262: {
    263:   DM_Network     *network = (DM_Network*)dm->data;
    264:   DMNetworkComponent component=network->component[componentkey];
    265:   DMNetworkComponentHeader header=&network->header[p];
    266:   DMNetworkComponentValue  cvalue=&network->cvalue[p];
    267:   PetscErrorCode         ierr;
    268:
    270:   header->size[header->ndata] = component.size;
    271:   PetscSectionAddDof(network->DataSection,p,component.size);
    272:   header->key[header->ndata] = componentkey;
    273:   if (header->ndata != 0) header->offset[header->ndata] = header->offset[header->ndata-1] + header->size[header->ndata-1];

    275:   cvalue->data[header->ndata] = (void*)compvalue;
    276:   header->ndata++;
    277:   return(0);
    278: }

    282: /*@
    283:   DMNetworkGetNumComponents - Get the number of components at a vertex/edge

    285:   Not Collective

    287:   Input Parameters:
    288: + dm - The DMNetwork object
    289: . p  - vertex/edge point

    291:   Output Parameters:
    292: . numcomponents - Number of components at the vertex/edge

    294:   Level: intermediate

    296: .seealso: DMNetworkRegisterComponent, DMNetworkAddComponent
    297: @*/
    298: PetscErrorCode DMNetworkGetNumComponents(DM dm,PetscInt p,PetscInt *numcomponents)
    299: {
    301:   PetscInt       offset;
    302:   DM_Network     *network = (DM_Network*)dm->data;

    305:   PetscSectionGetOffset(network->DataSection,p,&offset);
    306:   *numcomponents = ((DMNetworkComponentHeader)(network->componentdataarray+offset))->ndata;
    307:   return(0);
    308: }

    312: /*@
    313:   DMNetworkGetComponentTypeOffset - Gets the type along with the offset for indexing the
    314:                                     component value from the component data array

    316:   Not Collective

    318:   Input Parameters:
    319: + dm      - The DMNetwork object
    320: . p       - vertex/edge point
    321: - compnum - component number
    322:
    323:   Output Parameters:
    324: + compkey - the key obtained when registering the component
    325: - offset  - offset into the component data array associated with the vertex/edge point

    327:   Notes:
    328:   Typical usage:

    330:   DMNetworkGetComponentDataArray(dm, &arr);
    331:   DMNetworkGetVertex/EdgeRange(dm,&Start,&End);
    332:   Loop over vertices or edges
    333:     DMNetworkGetNumComponents(dm,v,&numcomps);
    334:     Loop over numcomps
    335:       DMNetworkGetComponentTypeOffset(dm,v,compnum,&key,&offset);
    336:       compdata = (UserCompDataType)(arr+offset);
    337:
    338:   Level: intermediate

    340: .seealso: DMNetworkGetNumComponents, DMNetworkGetComponentDataArray,
    341: @*/
    342: PetscErrorCode DMNetworkGetComponentTypeOffset(DM dm,PetscInt p, PetscInt compnum, PetscInt *compkey, PetscInt *offset)
    343: {
    345:   PetscInt       offsetp;
    346:   DMNetworkComponentHeader header;
    347:   DM_Network     *network = (DM_Network*)dm->data;

    350:   PetscSectionGetOffset(network->DataSection,p,&offsetp);
    351:   header = (DMNetworkComponentHeader)(network->componentdataarray+offsetp);
    352:   *compkey = header->key[compnum];
    353:   *offset  = offsetp+network->dataheadersize+header->offset[compnum];
    354:   return(0);
    355: }

    359: /*@
    360:   DMNetworkGetVariableOffset - Get the offset for accessing the variable associated with the given vertex/edge from the local vector.

    362:   Not Collective

    364:   Input Parameters:
    365: + dm     - The DMNetwork object
    366: - p      - the edge/vertex point

    368:   Output Parameters:
    369: . offset - the offset

    371:   Level: intermediate

    373: .seealso: DMNetworkGetVariableGlobalOffset, DMGetLocalVector
    374: @*/
    375: PetscErrorCode DMNetworkGetVariableOffset(DM dm,PetscInt p,PetscInt *offset)
    376: {
    378:   DM_Network     *network = (DM_Network*)dm->data;

    381:   PetscSectionGetOffset(network->DofSection,p,offset);
    382:   return(0);
    383: }

    387: /*@
    388:   DMNetworkGetVariableGlobalOffset - Get the global offset for the variable associated with the given vertex/edge from the global vector.

    390:   Not Collective

    392:   Input Parameters:
    393: + dm      - The DMNetwork object
    394: - p       - the edge/vertex point

    396:   Output Parameters:
    397: . offsetg - the offset

    399:   Level: intermediate

    401: .seealso: DMNetworkGetVariableOffset, DMGetLocalVector
    402: @*/
    403: PetscErrorCode DMNetworkGetVariableGlobalOffset(DM dm,PetscInt p,PetscInt *offsetg)
    404: {
    406:   DM_Network     *network = (DM_Network*)dm->data;

    409:   PetscSectionGetOffset(network->GlobalDofSection,p,offsetg);
    410:   return(0);
    411: }

    415: /*@
    416:   DMNetworkAddNumVariables - Add number of variables associated with a given point.

    418:   Not Collective

    420:   Input Parameters:
    421: + dm   - The DMNetworkObject
    422: . p    - the vertex/edge point
    423: - nvar - number of additional variables

    425:   Level: intermediate

    427: .seealso: DMNetworkSetNumVariables
    428: @*/
    429: PetscErrorCode DMNetworkAddNumVariables(DM dm,PetscInt p,PetscInt nvar)
    430: {
    432:   DM_Network     *network = (DM_Network*)dm->data;

    435:   PetscSectionAddDof(network->DofSection,p,nvar);
    436:   return(0);
    437: }

    441: /*@
    442:   DMNetworkSetNumVariables - Sets number of variables for a vertex/edge point.

    444:   Not Collective

    446:   Input Parameters:
    447: + dm   - The DMNetworkObject
    448: . p    - the vertex/edge point
    449: - nvar - number of variables

    451:   Level: intermediate

    453: .seealso: DMNetworkAddNumVariables
    454: @*/
    455: PetscErrorCode DMNetworkSetNumVariables(DM dm,PetscInt p,PetscInt nvar)
    456: {
    458:   DM_Network     *network = (DM_Network*)dm->data;

    461:   PetscSectionSetDof(network->DofSection,p,nvar);
    462:   return(0);
    463: }

    465: /* Sets up the array that holds the data for all components and its associated section. This
    466:    function is called during DMSetUp() */
    469: PetscErrorCode DMNetworkComponentSetUp(DM dm)
    470: {
    471:   PetscErrorCode              ierr;
    472:   DM_Network     *network = (DM_Network*)dm->data;
    473:   PetscInt                    arr_size;
    474:   PetscInt                    p,offset,offsetp;
    475:   DMNetworkComponentHeader header;
    476:   DMNetworkComponentValue  cvalue;
    477:   DMNetworkComponentGenericDataType      *componentdataarray;
    478:   PetscInt ncomp, i;

    481:   PetscSectionSetUp(network->DataSection);
    482:   PetscSectionGetStorageSize(network->DataSection,&arr_size);
    483:   PetscMalloc1(arr_size,&network->componentdataarray);
    484:   componentdataarray = network->componentdataarray;
    485:   for (p = network->pStart; p < network->pEnd; p++) {
    486:     PetscSectionGetOffset(network->DataSection,p,&offsetp);
    487:     /* Copy header */
    488:     header = &network->header[p];
    489:     PetscMemcpy(componentdataarray+offsetp,header,network->dataheadersize*sizeof(DMNetworkComponentGenericDataType));
    490:     /* Copy data */
    491:     cvalue = &network->cvalue[p];
    492:     ncomp = header->ndata;
    493:     for (i = 0; i < ncomp; i++) {
    494:       offset = offsetp + network->dataheadersize + header->offset[i];
    495:       PetscMemcpy(componentdataarray+offset,cvalue->data[i],header->size[i]*sizeof(DMNetworkComponentGenericDataType));
    496:     }
    497:   }
    498:   return(0);
    499: }

    501: /* Sets up the section for dofs. This routine is called during DMSetUp() */
    504: PetscErrorCode DMNetworkVariablesSetUp(DM dm)
    505: {
    507:   DM_Network     *network = (DM_Network*)dm->data;

    510:   PetscSectionSetUp(network->DofSection);
    511:   return(0);
    512: }

    516: /*@C
    517:   DMNetworkGetComponentDataArray - Returns the component data array

    519:   Not Collective

    521:   Input Parameters:
    522: . dm - The DMNetwork Object

    524:   Output Parameters:
    525: . componentdataarray - array that holds data for all components

    527:   Level: intermediate

    529: .seealso: DMNetworkGetComponentTypeOffset, DMNetworkGetNumComponents
    530: @*/
    531: PetscErrorCode DMNetworkGetComponentDataArray(DM dm,DMNetworkComponentGenericDataType **componentdataarray)
    532: {
    533:   DM_Network     *network = (DM_Network*)dm->data;

    536:   *componentdataarray = network->componentdataarray;
    537:   return(0);
    538: }

    542: /*@
    543:   DMNetworkDistribute - Distributes the network and moves associated component data.

    545:   Collective

    547:   Input Parameter:
    548: + oldDM - the original DMNetwork object
    549: - overlap - The overlap of partitions, 0 is the default

    551:   Output Parameter:
    552: . distDM - the distributed DMNetwork object

    554:   Notes:
    555:   This routine should be called only when using multiple processors.

    557:   Distributes the network with a non-overlapping partitioning of the edges.

    559:   Level: intermediate

    561: .seealso: DMNetworkCreate
    562: @*/
    563: PetscErrorCode DMNetworkDistribute(DM oldDM, PetscInt overlap,DM *distDM)
    564: {
    566:   DM_Network     *oldDMnetwork = (DM_Network*)oldDM->data;
    567:   PetscSF        pointsf;
    568:   DM             newDM;
    569:   DM_Network     *newDMnetwork;

    572:   DMNetworkCreate(PetscObjectComm((PetscObject)oldDM),&newDM);
    573:   newDMnetwork = (DM_Network*)newDM->data;
    574:   newDMnetwork->dataheadersize = sizeof(struct _p_DMNetworkComponentHeader)/sizeof(DMNetworkComponentGenericDataType);
    575:   /* Distribute plex dm and dof section */
    576:   DMPlexDistribute(oldDMnetwork->plex,overlap,&pointsf,&newDMnetwork->plex);
    577:   /* Distribute dof section */
    578:   PetscSectionCreate(PetscObjectComm((PetscObject)oldDM),&newDMnetwork->DofSection);
    579:   PetscSFDistributeSection(pointsf,oldDMnetwork->DofSection,NULL,newDMnetwork->DofSection);
    580:   PetscSectionCreate(PetscObjectComm((PetscObject)oldDM),&newDMnetwork->DataSection);
    581:   /* Distribute data and associated section */
    582:   DMPlexDistributeData(newDMnetwork->plex,pointsf,oldDMnetwork->DataSection,MPI_INT,(void*)oldDMnetwork->componentdataarray,newDMnetwork->DataSection,(void**)&newDMnetwork->componentdataarray);
    583:   /* Destroy point SF */
    584:   PetscSFDestroy(&pointsf);
    585:
    586:   PetscSectionGetChart(newDMnetwork->DataSection,&newDMnetwork->pStart,&newDMnetwork->pEnd);
    587:   DMPlexGetHeightStratum(newDMnetwork->plex,0, &newDMnetwork->eStart,&newDMnetwork->eEnd);
    588:   DMPlexGetHeightStratum(newDMnetwork->plex,1,&newDMnetwork->vStart,&newDMnetwork->vEnd);
    589:   newDMnetwork->nEdges = newDMnetwork->eEnd - newDMnetwork->eStart;
    590:   newDMnetwork->nNodes = newDMnetwork->vEnd - newDMnetwork->vStart;
    591:   newDMnetwork->NNodes = oldDMnetwork->NNodes;
    592:   newDMnetwork->NEdges = oldDMnetwork->NEdges;
    593:   /* Set Dof section as the default section for dm */
    594:   DMSetDefaultSection(newDMnetwork->plex,newDMnetwork->DofSection);
    595:   DMGetDefaultGlobalSection(newDMnetwork->plex,&newDMnetwork->GlobalDofSection);

    597:   *distDM = newDM;
    598:   return(0);
    599: }

    603: /*@C
    604:   DMNetworkGetSupportingEdges - Return the supporting edges for this vertex point

    606:   Not Collective

    608:   Input Parameters:
    609: + dm - The DMNetwork object
    610: - p  - the vertex point

    612:   Output Paramters:
    613: + nedges - number of edges connected to this vertex point
    614: - edges  - List of edge points

    616:   Level: intermediate

    618:   Fortran Notes:
    619:   Since it returns an array, this routine is only available in Fortran 90, and you must
    620:   include petsc.h90 in your code.

    622: .seealso: DMNetworkCreate, DMNetworkGetConnectedNodes
    623: @*/
    624: PetscErrorCode DMNetworkGetSupportingEdges(DM dm,PetscInt vertex,PetscInt *nedges,const PetscInt *edges[])
    625: {
    627:   DM_Network     *network = (DM_Network*)dm->data;

    630:   DMPlexGetSupportSize(network->plex,vertex,nedges);
    631:   DMPlexGetSupport(network->plex,vertex,edges);
    632:   return(0);
    633: }

    637: /*@C
    638:   DMNetworkGetConnectedNodes - Return the connected edges for this edge point

    640:   Not Collective

    642:   Input Parameters:
    643: + dm - The DMNetwork object
    644: - p  - the edge point

    646:   Output Paramters:
    647: . vertices  - vertices connected to this edge

    649:   Level: intermediate

    651:   Fortran Notes:
    652:   Since it returns an array, this routine is only available in Fortran 90, and you must
    653:   include petsc.h90 in your code.

    655: .seealso: DMNetworkCreate, DMNetworkGetSupportingEdges
    656: @*/
    657: PetscErrorCode DMNetworkGetConnectedNodes(DM dm,PetscInt edge,const PetscInt *vertices[])
    658: {
    660:   DM_Network     *network = (DM_Network*)dm->data;

    663:   DMPlexGetCone(network->plex,edge,vertices);
    664:   return(0);
    665: }

    669: /*@
    670:   DMNetworkIsGhostVertex - Returns TRUE if the vertex is a ghost vertex

    672:   Not Collective

    674:   Input Parameters:
    675: + dm - The DMNetwork object
    676: . p  - the vertex point

    678:   Output Parameter:
    679: . isghost - TRUE if the vertex is a ghost point

    681:   Level: intermediate

    683: .seealso: DMNetworkCreate, DMNetworkGetConnectedNodes, DMNetworkGetVertexRange
    684: @*/
    685: PetscErrorCode DMNetworkIsGhostVertex(DM dm,PetscInt p,PetscBool *isghost)
    686: {
    688:   DM_Network     *network = (DM_Network*)dm->data;
    689:   PetscInt       offsetg;
    690:   PetscSection   sectiong;

    693:   *isghost = PETSC_FALSE;
    694:   DMGetDefaultGlobalSection(network->plex,&sectiong);
    695:   PetscSectionGetOffset(sectiong,p,&offsetg);
    696:   if (offsetg < 0) *isghost = PETSC_TRUE;
    697:   return(0);
    698: }

    702: PetscErrorCode DMSetUp_Network(DM dm)
    703: {
    705:   DM_Network     *network=(DM_Network*)dm->data;

    708:   DMNetworkComponentSetUp(dm);
    709:   DMNetworkVariablesSetUp(dm);

    711:   DMSetDefaultSection(network->plex,network->DofSection);
    712:   DMGetDefaultGlobalSection(network->plex,&network->GlobalDofSection);
    713:   return(0);
    714: }

    718: PetscErrorCode DMCreateMatrix_Network(DM dm,Mat *J)
    719: {
    721:   DM_Network     *network = (DM_Network*) dm->data;

    724:   DMCreateMatrix(network->plex,J);
    725:   MatSetDM(*J,dm);
    726:   return(0);
    727: }

    731: PetscErrorCode DMDestroy_Network(DM dm)
    732: {
    734:   DM_Network     *network = (DM_Network*) dm->data;

    737:   if (--network->refct > 0) return(0);
    738:   DMDestroy(&network->plex);
    739:   network->edges = NULL;
    740:   PetscSectionDestroy(&network->DataSection);
    741:   PetscSectionDestroy(&network->DofSection);
    742:   /*  PetscSectionDestroy(&network->GlobalDofSection); */
    743:   PetscFree(network->componentdataarray);
    744:   PetscFree(network->cvalue);
    745:   PetscFree(network->header);
    746:   PetscFree(network);
    747:   return(0);
    748: }

    752: PetscErrorCode DMView_Network(DM dm, PetscViewer viewer)
    753: {
    755:   DM_Network     *network = (DM_Network*) dm->data;

    758:   DMView(network->plex,viewer);
    759:   return(0);
    760: }

    764: PetscErrorCode DMGlobalToLocalBegin_Network(DM dm, Vec g, InsertMode mode, Vec l)
    765: {
    767:   DM_Network     *network = (DM_Network*) dm->data;

    770:   DMGlobalToLocalBegin(network->plex,g,mode,l);
    771:   return(0);
    772: }

    776: PetscErrorCode DMGlobalToLocalEnd_Network(DM dm, Vec g, InsertMode mode, Vec l)
    777: {
    779:   DM_Network     *network = (DM_Network*) dm->data;

    782:   DMGlobalToLocalEnd(network->plex,g,mode,l);
    783:   return(0);
    784: }

    788: PetscErrorCode DMLocalToGlobalBegin_Network(DM dm, Vec l, InsertMode mode, Vec g)
    789: {
    791:   DM_Network     *network = (DM_Network*) dm->data;

    794:   DMLocalToGlobalBegin(network->plex,l,mode,g);
    795:   return(0);
    796: }

    800: PetscErrorCode DMLocalToGlobalEnd_Network(DM dm, Vec l, InsertMode mode, Vec g)
    801: {
    803:   DM_Network     *network = (DM_Network*) dm->data;

    806:   DMLocalToGlobalEnd(network->plex,l,mode,g);
    807:   return(0);
    808: }