Actual source code: network.c
petsc-3.6.1 2015-08-06
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,§iong);
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: }