xref: /petsc/src/dm/impls/plex/plexvtu.c (revision 552f735842aa6127d09b62f740a903cdd0631614)
1*552f7358SJed Brown #include <petsc-private/pleximpl.h>
2*552f7358SJed Brown #include <../src/sys/classes/viewer/impls/vtk/vtkvimpl.h>
3*552f7358SJed Brown 
4*552f7358SJed Brown typedef struct {
5*552f7358SJed Brown   PetscInt nvertices;
6*552f7358SJed Brown   PetscInt ncells;
7*552f7358SJed Brown   PetscInt nconn;               /* number of entries in cell->vertex connectivity array */
8*552f7358SJed Brown } PieceInfo;
9*552f7358SJed Brown 
10*552f7358SJed Brown #if defined(PETSC_USE_REAL_SINGLE)
11*552f7358SJed Brown   static const char precision[]  = "Float32";
12*552f7358SJed Brown #elif defined(PETSC_USE_REAL_DOUBLE)
13*552f7358SJed Brown   static const char precision[]  = "Float64";
14*552f7358SJed Brown #else
15*552f7358SJed Brown   static const char precision[]  = "UnknownPrecision";
16*552f7358SJed Brown #endif
17*552f7358SJed Brown 
18*552f7358SJed Brown #undef __FUNCT__
19*552f7358SJed Brown #define __FUNCT__ "TransferWrite"
20*552f7358SJed Brown static PetscErrorCode TransferWrite(PetscViewer viewer,FILE *fp,PetscMPIInt srank,PetscMPIInt root,const void *send,void *recv,PetscMPIInt count,PetscDataType datatype,PetscMPIInt tag)
21*552f7358SJed Brown {
22*552f7358SJed Brown   PetscMPIInt rank;
23*552f7358SJed Brown   PetscErrorCode ierr;
24*552f7358SJed Brown   MPI_Comm comm = ((PetscObject)viewer)->comm;
25*552f7358SJed Brown   MPI_Datatype mpidatatype;
26*552f7358SJed Brown 
27*552f7358SJed Brown   PetscFunctionBegin;
28*552f7358SJed Brown   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
29*552f7358SJed Brown   ierr = PetscDataTypeToMPIDataType(datatype,&mpidatatype);CHKERRQ(ierr);
30*552f7358SJed Brown 
31*552f7358SJed Brown   if (rank == srank && rank != root) {
32*552f7358SJed Brown     ierr = MPI_Send((void*)send,count,mpidatatype,root,tag,comm);CHKERRQ(ierr);
33*552f7358SJed Brown   } else if (rank == root) {
34*552f7358SJed Brown     const void *buffer;
35*552f7358SJed Brown     if (root == srank) {        /* self */
36*552f7358SJed Brown       buffer = send;
37*552f7358SJed Brown     } else {
38*552f7358SJed Brown       MPI_Status status;
39*552f7358SJed Brown       PetscMPIInt nrecv;
40*552f7358SJed Brown       ierr = MPI_Recv(recv,count,mpidatatype,srank,tag,comm,&status);CHKERRQ(ierr);
41*552f7358SJed Brown       ierr = MPI_Get_count(&status,mpidatatype,&nrecv);CHKERRQ(ierr);
42*552f7358SJed Brown       if (count != nrecv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Array size mismatch");
43*552f7358SJed Brown       buffer = recv;
44*552f7358SJed Brown     }
45*552f7358SJed Brown     ierr = PetscViewerVTKFWrite(viewer,fp,buffer,count,datatype);CHKERRQ(ierr);
46*552f7358SJed Brown   }
47*552f7358SJed Brown   PetscFunctionReturn(0);
48*552f7358SJed Brown }
49*552f7358SJed Brown 
50*552f7358SJed Brown #undef __FUNCT__
51*552f7358SJed Brown #define __FUNCT__ "DMPlexGetVTKConnectivity"
52*552f7358SJed Brown static PetscErrorCode DMPlexGetVTKConnectivity(DM dm,PieceInfo *piece,PetscVTKInt **oconn,PetscVTKInt **ooffsets,PetscVTKType **otypes)
53*552f7358SJed Brown {
54*552f7358SJed Brown   PetscErrorCode ierr;
55*552f7358SJed Brown   PetscVTKInt *conn,*offsets;
56*552f7358SJed Brown   PetscVTKType *types;
57*552f7358SJed Brown   PetscInt dim,vStart,vEnd,cStart,cEnd,pStart,pEnd,cellHeight,cMax,numLabelCells,hasLabel,c,v,countcell,countconn;
58*552f7358SJed Brown 
59*552f7358SJed Brown   PetscFunctionBegin;
60*552f7358SJed Brown   ierr = PetscMalloc3(piece->nconn,PetscVTKInt,&conn,piece->ncells,PetscVTKInt,&offsets,piece->ncells,PetscVTKType,&types);CHKERRQ(ierr);
61*552f7358SJed Brown 
62*552f7358SJed Brown   ierr = DMPlexGetDimension(dm,&dim);CHKERRQ(ierr);
63*552f7358SJed Brown   ierr = DMPlexGetChart(dm,&pStart,&pEnd);CHKERRQ(ierr);
64*552f7358SJed Brown   ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr);
65*552f7358SJed Brown   ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr);
66*552f7358SJed Brown   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
67*552f7358SJed Brown   ierr = DMPlexGetVTKBounds(dm, &cMax, PETSC_NULL);CHKERRQ(ierr);
68*552f7358SJed Brown   if (cMax >= 0) {cEnd = PetscMin(cEnd, cMax);}
69*552f7358SJed Brown   ierr = DMPlexGetStratumSize(dm, "vtk", 1, &numLabelCells);CHKERRQ(ierr);
70*552f7358SJed Brown   hasLabel = numLabelCells > 0 ? PETSC_TRUE : PETSC_FALSE;
71*552f7358SJed Brown 
72*552f7358SJed Brown   countcell = 0;
73*552f7358SJed Brown   countconn = 0;
74*552f7358SJed Brown   for (c = cStart; c < cEnd; ++c) {
75*552f7358SJed Brown     PetscInt *closure = PETSC_NULL;
76*552f7358SJed Brown     PetscInt  closureSize,nverts,celltype,startoffset;
77*552f7358SJed Brown 
78*552f7358SJed Brown     if (hasLabel) {
79*552f7358SJed Brown       PetscInt value;
80*552f7358SJed Brown 
81*552f7358SJed Brown       ierr = DMPlexGetLabelValue(dm, "vtk", c, &value);CHKERRQ(ierr);
82*552f7358SJed Brown       if (value != 1) continue;
83*552f7358SJed Brown     }
84*552f7358SJed Brown     startoffset = countconn;
85*552f7358SJed Brown     ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr);
86*552f7358SJed Brown     for (v = 0; v < closureSize*2; v += 2) {
87*552f7358SJed Brown       if ((closure[v] >= vStart) && (closure[v] < vEnd)) {
88*552f7358SJed Brown         conn[countconn++] = closure[v] - vStart;
89*552f7358SJed Brown       }
90*552f7358SJed Brown     }
91*552f7358SJed Brown     ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr);
92*552f7358SJed Brown     offsets[countcell] = countconn;
93*552f7358SJed Brown     nverts = countconn - startoffset;
94*552f7358SJed Brown     ierr = DMPlexVTKGetCellType(dm,dim,nverts,&celltype);CHKERRQ(ierr);
95*552f7358SJed Brown     types[countcell] = celltype;
96*552f7358SJed Brown     countcell++;
97*552f7358SJed Brown   }
98*552f7358SJed Brown   if (countcell != piece->ncells) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Inconsistent cell count");
99*552f7358SJed Brown   if (countconn != piece->nconn) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Inconsistent connectivity count");
100*552f7358SJed Brown   *oconn = conn;
101*552f7358SJed Brown   *ooffsets = offsets;
102*552f7358SJed Brown   *otypes = types;
103*552f7358SJed Brown   PetscFunctionReturn(0);
104*552f7358SJed Brown }
105*552f7358SJed Brown 
106*552f7358SJed Brown #undef __FUNCT__
107*552f7358SJed Brown #define __FUNCT__ "DMPlexVTKWriteAll_VTU"
108*552f7358SJed Brown /*
109*552f7358SJed Brown   Write all fields that have been provided to the viewer
110*552f7358SJed Brown   Multi-block XML format with binary appended data.
111*552f7358SJed Brown */
112*552f7358SJed Brown PetscErrorCode DMPlexVTKWriteAll_VTU(DM dm,PetscViewer viewer)
113*552f7358SJed Brown {
114*552f7358SJed Brown   MPI_Comm comm = ((PetscObject)dm)->comm;
115*552f7358SJed Brown   PetscViewer_VTK          *vtk = (PetscViewer_VTK*)viewer->data;
116*552f7358SJed Brown   PetscViewerVTKObjectLink link;
117*552f7358SJed Brown   FILE                     *fp;
118*552f7358SJed Brown   PetscMPIInt              rank,size,tag;
119*552f7358SJed Brown   PetscErrorCode ierr;
120*552f7358SJed Brown   PetscInt                 dim,cellHeight,cStart,cEnd,vStart,vEnd,cMax,numLabelCells,hasLabel,c,v,r,i;
121*552f7358SJed Brown   PieceInfo                piece,*gpiece = PETSC_NULL;
122*552f7358SJed Brown   void                     *buffer = PETSC_NULL;
123*552f7358SJed Brown 
124*552f7358SJed Brown   PetscFunctionBegin;
125*552f7358SJed Brown #if defined(PETSC_USE_COMPLEX)
126*552f7358SJed Brown   SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Complex values not supported");
127*552f7358SJed Brown #endif
128*552f7358SJed Brown   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
129*552f7358SJed Brown   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
130*552f7358SJed Brown   tag = ((PetscObject)viewer)->tag;
131*552f7358SJed Brown 
132*552f7358SJed Brown   ierr = PetscFOpen(comm,vtk->filename,"wb",&fp);CHKERRQ(ierr);
133*552f7358SJed Brown   ierr = PetscFPrintf(comm,fp,"<?xml version=\"1.0\"?>\n");CHKERRQ(ierr);
134*552f7358SJed Brown #ifdef PETSC_WORDS_BIGENDIAN
135*552f7358SJed Brown   ierr = PetscFPrintf(comm,fp,"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"BigEndian\">\n");CHKERRQ(ierr);
136*552f7358SJed Brown #else
137*552f7358SJed Brown   ierr = PetscFPrintf(comm,fp,"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n");CHKERRQ(ierr);
138*552f7358SJed Brown #endif
139*552f7358SJed Brown   ierr = PetscFPrintf(comm,fp,"  <UnstructuredGrid>\n");CHKERRQ(ierr);
140*552f7358SJed Brown 
141*552f7358SJed Brown   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
142*552f7358SJed Brown   ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr);
143*552f7358SJed Brown   ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr);
144*552f7358SJed Brown   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
145*552f7358SJed Brown   ierr = DMPlexGetVTKBounds(dm, &cMax, PETSC_NULL);CHKERRQ(ierr);
146*552f7358SJed Brown   if (cMax >= 0) {cEnd = PetscMin(cEnd, cMax);}
147*552f7358SJed Brown   ierr = DMPlexGetStratumSize(dm, "vtk", 1, &numLabelCells);CHKERRQ(ierr);
148*552f7358SJed Brown   hasLabel = numLabelCells > 0 ? PETSC_TRUE : PETSC_FALSE;
149*552f7358SJed Brown   piece.nvertices = vEnd - vStart;
150*552f7358SJed Brown   piece.ncells = 0;
151*552f7358SJed Brown   piece.nconn = 0;
152*552f7358SJed Brown   for (c = cStart; c < cEnd; ++c) {
153*552f7358SJed Brown     PetscInt *closure = PETSC_NULL;
154*552f7358SJed Brown     PetscInt  closureSize;
155*552f7358SJed Brown 
156*552f7358SJed Brown     if (hasLabel) {
157*552f7358SJed Brown       PetscInt value;
158*552f7358SJed Brown 
159*552f7358SJed Brown       ierr = DMPlexGetLabelValue(dm, "vtk", c, &value);CHKERRQ(ierr);
160*552f7358SJed Brown       if (value != 1) continue;
161*552f7358SJed Brown     }
162*552f7358SJed Brown     ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr);
163*552f7358SJed Brown     for (v = 0; v < closureSize*2; v += 2) {
164*552f7358SJed Brown       if ((closure[v] >= vStart) && (closure[v] < vEnd)) piece.nconn++;
165*552f7358SJed Brown     }
166*552f7358SJed Brown     ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr);
167*552f7358SJed Brown     piece.ncells++;
168*552f7358SJed Brown   }
169*552f7358SJed Brown   if (!rank) {ierr = PetscMalloc(size*sizeof(piece),&gpiece);CHKERRQ(ierr);}
170*552f7358SJed Brown   ierr = MPI_Gather((PetscInt*)&piece,sizeof(piece)/sizeof(PetscInt),MPIU_INT,(PetscInt*)gpiece,sizeof(piece)/sizeof(PetscInt),MPIU_INT,0,comm);CHKERRQ(ierr);
171*552f7358SJed Brown 
172*552f7358SJed Brown   /*
173*552f7358SJed Brown    * Write file header
174*552f7358SJed Brown    */
175*552f7358SJed Brown   if (!rank) {
176*552f7358SJed Brown     PetscInt boffset = 0;
177*552f7358SJed Brown 
178*552f7358SJed Brown     for (r=0; r<size; r++) {
179*552f7358SJed Brown       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"    <Piece NumberOfPoints=\"%D\" NumberOfCells=\"%D\">\n",gpiece[r].nvertices,gpiece[r].ncells);CHKERRQ(ierr);
180*552f7358SJed Brown       /* Coordinate positions */
181*552f7358SJed Brown       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"      <Points>\n");CHKERRQ(ierr);
182*552f7358SJed Brown       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"        <DataArray type=\"%s\" Name=\"Position\" NumberOfComponents=\"3\" format=\"appended\" offset=\"%D\" />\n",precision,boffset);CHKERRQ(ierr);
183*552f7358SJed Brown       boffset += gpiece[r].nvertices*3*sizeof(PetscScalar) + sizeof(int);
184*552f7358SJed Brown       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"      </Points>\n");CHKERRQ(ierr);
185*552f7358SJed Brown       /* Cell connectivity */
186*552f7358SJed Brown       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"      <Cells>\n");CHKERRQ(ierr);
187*552f7358SJed Brown       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"        <DataArray type=\"Int32\" Name=\"connectivity\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%D\" />\n",boffset);CHKERRQ(ierr);
188*552f7358SJed Brown       boffset += gpiece[r].nconn*sizeof(PetscInt) + sizeof(int);
189*552f7358SJed Brown       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"        <DataArray type=\"Int32\" Name=\"offsets\"      NumberOfComponents=\"1\" format=\"appended\" offset=\"%D\" />\n",boffset);CHKERRQ(ierr);
190*552f7358SJed Brown       boffset += gpiece[r].ncells*sizeof(PetscInt) + sizeof(int);
191*552f7358SJed Brown       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"        <DataArray type=\"UInt8\" Name=\"types\"        NumberOfComponents=\"1\" format=\"appended\" offset=\"%D\" />\n",boffset);CHKERRQ(ierr);
192*552f7358SJed Brown       boffset += gpiece[r].ncells*sizeof(unsigned char) + sizeof(int);
193*552f7358SJed Brown       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"      </Cells>\n");CHKERRQ(ierr);
194*552f7358SJed Brown 
195*552f7358SJed Brown       /*
196*552f7358SJed Brown        * Cell Data headers
197*552f7358SJed Brown        */
198*552f7358SJed Brown       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"      <CellData>\n");CHKERRQ(ierr);
199*552f7358SJed Brown       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"        <DataArray type=\"Int32\" Name=\"Rank\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%D\" />\n",boffset);CHKERRQ(ierr);
200*552f7358SJed Brown       boffset += gpiece[r].ncells*sizeof(int) + sizeof(int);
201*552f7358SJed Brown       /* all the vectors */
202*552f7358SJed Brown       for (link=vtk->link; link; link=link->next) {
203*552f7358SJed Brown         Vec X = (Vec)link->vec;
204*552f7358SJed Brown         PetscInt bs;
205*552f7358SJed Brown         const char *vecname = "";
206*552f7358SJed Brown         if ((link->ft != PETSC_VTK_CELL_FIELD) && (link->ft != PETSC_VTK_CELL_VECTOR_FIELD)) continue;
207*552f7358SJed Brown         if (((PetscObject)X)->name || link != vtk->link) { /* If the object is already named, use it. If it is past the first link, name it to disambiguate. */
208*552f7358SJed Brown           ierr = PetscObjectGetName((PetscObject)X,&vecname);CHKERRQ(ierr);
209*552f7358SJed Brown         }
210*552f7358SJed Brown         ierr = PetscSectionGetDof(dm->defaultSection,cStart,&bs);CHKERRQ(ierr);
211*552f7358SJed Brown         for (i=0; i<bs; i++) {
212*552f7358SJed Brown           char buf[256];
213*552f7358SJed Brown           const char *fieldname = PETSC_NULL;
214*552f7358SJed Brown           /* ierr = DMDAGetFieldName(da,i,&fieldname);CHKERRQ(ierr); */
215*552f7358SJed Brown           if (!fieldname) {
216*552f7358SJed Brown             ierr = PetscSNPrintf(buf,sizeof(buf),"Unnamed%D",i);CHKERRQ(ierr);
217*552f7358SJed Brown             fieldname = buf;
218*552f7358SJed Brown           }
219*552f7358SJed Brown           ierr = PetscFPrintf(comm,fp,"        <DataArray type=\"%s\" Name=\"%s%s\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%D\" />\n",precision,vecname,fieldname,boffset);CHKERRQ(ierr);
220*552f7358SJed Brown           boffset += gpiece[r].ncells*sizeof(PetscScalar) + sizeof(int);
221*552f7358SJed Brown         }
222*552f7358SJed Brown       }
223*552f7358SJed Brown       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"      </CellData>\n");CHKERRQ(ierr);
224*552f7358SJed Brown 
225*552f7358SJed Brown       /*
226*552f7358SJed Brown        * Point Data headers
227*552f7358SJed Brown        */
228*552f7358SJed Brown       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"      <PointData>\n");CHKERRQ(ierr);
229*552f7358SJed Brown       for (link=vtk->link; link; link=link->next) {
230*552f7358SJed Brown         Vec X = (Vec)link->vec;
231*552f7358SJed Brown         PetscInt bs;
232*552f7358SJed Brown         const char *vecname = "";
233*552f7358SJed Brown         if ((link->ft != PETSC_VTK_POINT_FIELD) && (link->ft != PETSC_VTK_POINT_VECTOR_FIELD)) continue;
234*552f7358SJed Brown         if (((PetscObject)X)->name || link != vtk->link) { /* If the object is already named, use it. If it is past the first link, name it to disambiguate. */
235*552f7358SJed Brown           ierr = PetscObjectGetName((PetscObject)X,&vecname);CHKERRQ(ierr);
236*552f7358SJed Brown         }
237*552f7358SJed Brown         ierr = PetscSectionGetDof(dm->defaultSection,vStart,&bs);CHKERRQ(ierr);
238*552f7358SJed Brown         for (i=0; i<bs; i++) {
239*552f7358SJed Brown           char fieldname[256];
240*552f7358SJed Brown           ierr = PetscSNPrintf(fieldname,sizeof(fieldname),"Point%D",i);CHKERRQ(ierr);
241*552f7358SJed Brown           ierr = PetscFPrintf(comm,fp,"        <DataArray type=\"%s\" Name=\"%s%s\" NumberOfComponents=\"1\" format=\"appended\" offset=\"%D\" />\n",precision,vecname,fieldname,boffset);CHKERRQ(ierr);
242*552f7358SJed Brown           boffset += gpiece[r].nvertices*sizeof(PetscScalar) + sizeof(int);
243*552f7358SJed Brown         }
244*552f7358SJed Brown       }
245*552f7358SJed Brown       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"      </PointData>\n");CHKERRQ(ierr);
246*552f7358SJed Brown 
247*552f7358SJed Brown       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"    </Piece>\n");CHKERRQ(ierr);
248*552f7358SJed Brown     }
249*552f7358SJed Brown   }
250*552f7358SJed Brown 
251*552f7358SJed Brown   ierr = PetscFPrintf(comm,fp,"  </UnstructuredGrid>\n");CHKERRQ(ierr);
252*552f7358SJed Brown   ierr = PetscFPrintf(comm,fp,"  <AppendedData encoding=\"raw\">\n");CHKERRQ(ierr);
253*552f7358SJed Brown   ierr = PetscFPrintf(comm,fp,"_");CHKERRQ(ierr);
254*552f7358SJed Brown 
255*552f7358SJed Brown   if (!rank) {
256*552f7358SJed Brown     PetscInt maxsize = 0;
257*552f7358SJed Brown     for (r=0; r<size; r++) {
258*552f7358SJed Brown       maxsize = PetscMax(maxsize, (PetscInt) (gpiece[r].nvertices*3*sizeof(PetscScalar)));
259*552f7358SJed Brown       maxsize = PetscMax(maxsize, (PetscInt) (gpiece[r].ncells*sizeof(PetscScalar)));
260*552f7358SJed Brown       maxsize = PetscMax(maxsize, (PetscInt) (gpiece[r].nconn*sizeof(PetscVTKInt)));
261*552f7358SJed Brown     }
262*552f7358SJed Brown     ierr = PetscMalloc(maxsize,&buffer);CHKERRQ(ierr);
263*552f7358SJed Brown   }
264*552f7358SJed Brown   for (r=0; r<size; r++) {
265*552f7358SJed Brown     if (r == rank) {
266*552f7358SJed Brown       PetscInt nsend;
267*552f7358SJed Brown       {                         /* Position */
268*552f7358SJed Brown         const PetscScalar *x;
269*552f7358SJed Brown         PetscScalar *y = PETSC_NULL;
270*552f7358SJed Brown         Vec coords;
271*552f7358SJed Brown         nsend = piece.nvertices*3;
272*552f7358SJed Brown         ierr = DMGetCoordinatesLocal(dm,&coords);CHKERRQ(ierr);
273*552f7358SJed Brown         ierr = VecGetArrayRead(coords,&x);CHKERRQ(ierr);
274*552f7358SJed Brown         if (dim != 3) {
275*552f7358SJed Brown           ierr = PetscMalloc(piece.nvertices*3*sizeof(PetscScalar),&y);CHKERRQ(ierr);
276*552f7358SJed Brown           for (i=0; i<piece.nvertices; i++) {
277*552f7358SJed Brown             y[i*3+0] = x[i*dim+0];
278*552f7358SJed Brown             y[i*3+1] = (dim > 1) ? x[i*dim+1] : 0;
279*552f7358SJed Brown             y[i*3+2] = 0;
280*552f7358SJed Brown           }
281*552f7358SJed Brown         }
282*552f7358SJed Brown         ierr = TransferWrite(viewer,fp,r,0,y?y:x,buffer,nsend,PETSC_SCALAR,tag);CHKERRQ(ierr);
283*552f7358SJed Brown         ierr = PetscFree(y);CHKERRQ(ierr);
284*552f7358SJed Brown         ierr = VecRestoreArrayRead(coords,&x);CHKERRQ(ierr);
285*552f7358SJed Brown       }
286*552f7358SJed Brown       {                           /* Connectivity, offsets, types */
287*552f7358SJed Brown         PetscVTKInt *connectivity,*offsets;
288*552f7358SJed Brown         PetscVTKType *types;
289*552f7358SJed Brown         ierr = DMPlexGetVTKConnectivity(dm,&piece,&connectivity,&offsets,&types);CHKERRQ(ierr);
290*552f7358SJed Brown         ierr = TransferWrite(viewer,fp,r,0,connectivity,buffer,piece.nconn,PETSC_INT32,tag);CHKERRQ(ierr);
291*552f7358SJed Brown         ierr = TransferWrite(viewer,fp,r,0,offsets,buffer,piece.ncells,PETSC_INT32,tag);CHKERRQ(ierr);
292*552f7358SJed Brown         ierr = TransferWrite(viewer,fp,r,0,types,buffer,piece.ncells,PETSC_UINT8,tag);CHKERRQ(ierr);
293*552f7358SJed Brown         ierr = PetscFree3(connectivity,offsets,types);CHKERRQ(ierr);
294*552f7358SJed Brown       }
295*552f7358SJed Brown       {                         /* Owners (cell data) */
296*552f7358SJed Brown         PetscVTKInt *owners;
297*552f7358SJed Brown         ierr = PetscMalloc(piece.ncells*sizeof(PetscVTKInt),&owners);CHKERRQ(ierr);
298*552f7358SJed Brown         for (i=0; i<piece.ncells; i++) owners[i] = rank;
299*552f7358SJed Brown         ierr = TransferWrite(viewer,fp,r,0,owners,buffer,piece.ncells,PETSC_INT32,tag);CHKERRQ(ierr);
300*552f7358SJed Brown         ierr = PetscFree(owners);CHKERRQ(ierr);
301*552f7358SJed Brown       }
302*552f7358SJed Brown                                 /* Cell data */
303*552f7358SJed Brown       for (link=vtk->link; link; link=link->next) {
304*552f7358SJed Brown         Vec X = (Vec)link->vec;
305*552f7358SJed Brown         const PetscScalar *x;
306*552f7358SJed Brown         PetscScalar *y;
307*552f7358SJed Brown         PetscInt bs;
308*552f7358SJed Brown         if ((link->ft != PETSC_VTK_CELL_FIELD) && (link->ft != PETSC_VTK_CELL_VECTOR_FIELD)) continue;
309*552f7358SJed Brown         ierr = PetscSectionGetDof(dm->defaultSection,cStart,&bs);CHKERRQ(ierr);
310*552f7358SJed Brown         ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr);
311*552f7358SJed Brown         ierr = PetscMalloc(piece.ncells*sizeof(PetscScalar),&y);CHKERRQ(ierr);
312*552f7358SJed Brown         for (i=0; i<bs; i++) {
313*552f7358SJed Brown           PetscInt cnt;
314*552f7358SJed Brown           for (c=cStart,cnt=0; c<cEnd; c++) {
315*552f7358SJed Brown             const PetscScalar *xpoint;
316*552f7358SJed Brown             if (hasLabel) {     /* Ignore some cells */
317*552f7358SJed Brown               PetscInt value;
318*552f7358SJed Brown               ierr = DMPlexGetLabelValue(dm, "vtk", c, &value);CHKERRQ(ierr);
319*552f7358SJed Brown               if (value != 1) continue;
320*552f7358SJed Brown             }
321*552f7358SJed Brown             ierr = DMPlexPointLocalRead(dm,c,x,&xpoint);CHKERRQ(ierr);
322*552f7358SJed Brown             y[cnt++] = xpoint[i];
323*552f7358SJed Brown           }
324*552f7358SJed Brown           if (cnt != piece.ncells) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Count does not match");
325*552f7358SJed Brown           ierr = TransferWrite(viewer,fp,r,0,y,buffer,piece.ncells,PETSC_SCALAR,tag);CHKERRQ(ierr);
326*552f7358SJed Brown         }
327*552f7358SJed Brown         ierr = PetscFree(y);CHKERRQ(ierr);
328*552f7358SJed Brown         ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr);
329*552f7358SJed Brown       }
330*552f7358SJed Brown 
331*552f7358SJed Brown       for (link=vtk->link; link; link=link->next) {
332*552f7358SJed Brown         Vec X = (Vec)link->vec;
333*552f7358SJed Brown         const PetscScalar *x;
334*552f7358SJed Brown         PetscScalar *y;
335*552f7358SJed Brown         PetscInt bs;
336*552f7358SJed Brown         if ((link->ft != PETSC_VTK_POINT_FIELD) && (link->ft != PETSC_VTK_POINT_VECTOR_FIELD)) continue;
337*552f7358SJed Brown         ierr = PetscSectionGetDof(dm->defaultSection,vStart,&bs);CHKERRQ(ierr);
338*552f7358SJed Brown         ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr);
339*552f7358SJed Brown         ierr = PetscMalloc(piece.nvertices*sizeof(PetscScalar),&y);CHKERRQ(ierr);
340*552f7358SJed Brown         for (i=0; i<bs; i++) {
341*552f7358SJed Brown           PetscInt cnt;
342*552f7358SJed Brown           for (v=vStart,cnt=0; v<vEnd; v++) {
343*552f7358SJed Brown             const PetscScalar *xpoint;
344*552f7358SJed Brown             ierr = DMPlexPointLocalRead(dm,c,x,&xpoint);CHKERRQ(ierr);
345*552f7358SJed Brown             y[cnt++] = xpoint[i];
346*552f7358SJed Brown           }
347*552f7358SJed Brown           if (cnt != piece.nvertices) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Count does not match");
348*552f7358SJed Brown           ierr = TransferWrite(viewer,fp,r,0,y,buffer,piece.nvertices,PETSC_SCALAR,tag);CHKERRQ(ierr);
349*552f7358SJed Brown         }
350*552f7358SJed Brown         ierr = PetscFree(y);CHKERRQ(ierr);
351*552f7358SJed Brown         ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr);
352*552f7358SJed Brown       }
353*552f7358SJed Brown     } else if (!rank) {
354*552f7358SJed Brown       ierr = TransferWrite(viewer,fp,r,0,PETSC_NULL,buffer,gpiece[r].nvertices*3,PETSC_SCALAR,tag);CHKERRQ(ierr); /* positions */
355*552f7358SJed Brown       ierr = TransferWrite(viewer,fp,r,0,PETSC_NULL,buffer,gpiece[r].nconn,PETSC_INT32,tag);CHKERRQ(ierr); /* connectivity */
356*552f7358SJed Brown       ierr = TransferWrite(viewer,fp,r,0,PETSC_NULL,buffer,gpiece[r].ncells,PETSC_INT32,tag);CHKERRQ(ierr); /* offsets */
357*552f7358SJed Brown       ierr = TransferWrite(viewer,fp,r,0,PETSC_NULL,buffer,gpiece[r].ncells,PETSC_UINT8,tag);CHKERRQ(ierr); /* types */
358*552f7358SJed Brown       ierr = TransferWrite(viewer,fp,r,0,PETSC_NULL,buffer,gpiece[r].ncells,PETSC_INT32,tag);CHKERRQ(ierr); /* owner rank (cells) */
359*552f7358SJed Brown       /* all cell data */
360*552f7358SJed Brown       for (link=vtk->link; link; link=link->next) {
361*552f7358SJed Brown         PetscInt bs;
362*552f7358SJed Brown         if ((link->ft != PETSC_VTK_CELL_FIELD) && (link->ft != PETSC_VTK_CELL_VECTOR_FIELD)) continue;
363*552f7358SJed Brown         ierr = PetscSectionGetDof(dm->defaultSection,vStart,&bs);CHKERRQ(ierr);
364*552f7358SJed Brown         for (i=0; i<bs; i++) {
365*552f7358SJed Brown           ierr = TransferWrite(viewer,fp,r,0,PETSC_NULL,buffer,gpiece[r].ncells,PETSC_SCALAR,tag);CHKERRQ(ierr);
366*552f7358SJed Brown         }
367*552f7358SJed Brown       }
368*552f7358SJed Brown       /* all point data */
369*552f7358SJed Brown       for (link=vtk->link; link; link=link->next) {
370*552f7358SJed Brown         PetscInt bs;
371*552f7358SJed Brown         if ((link->ft != PETSC_VTK_POINT_FIELD) && (link->ft != PETSC_VTK_POINT_VECTOR_FIELD)) continue;
372*552f7358SJed Brown         ierr = PetscSectionGetDof(dm->defaultSection,vStart,&bs);CHKERRQ(ierr);
373*552f7358SJed Brown         for (i=0; i<bs; i++) {
374*552f7358SJed Brown           ierr = TransferWrite(viewer,fp,r,0,PETSC_NULL,buffer,gpiece[r].nvertices,PETSC_SCALAR,tag);CHKERRQ(ierr);
375*552f7358SJed Brown         }
376*552f7358SJed Brown       }
377*552f7358SJed Brown     }
378*552f7358SJed Brown   }
379*552f7358SJed Brown   ierr = PetscFree(gpiece);CHKERRQ(ierr);
380*552f7358SJed Brown   ierr = PetscFree(buffer);CHKERRQ(ierr);
381*552f7358SJed Brown   ierr = PetscFPrintf(comm,fp,"\n  </AppendedData>\n");CHKERRQ(ierr);
382*552f7358SJed Brown   ierr = PetscFPrintf(comm,fp,"</VTKFile>\n");CHKERRQ(ierr);
383*552f7358SJed Brown   PetscFunctionReturn(0);
384*552f7358SJed Brown }
385