xref: /petsc/src/dm/impls/plex/plexvtk.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
1552f7358SJed Brown #define PETSCDM_DLL
2af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h> /*I   "petscdmplex.h"   I*/
3552f7358SJed Brown #include <../src/sys/classes/viewer/impls/vtk/vtkvimpl.h>
4552f7358SJed Brown 
59371c9d4SSatish Balay PetscErrorCode DMPlexVTKGetCellType_Internal(DM dm, PetscInt dim, PetscInt corners, PetscInt *cellType) {
6552f7358SJed Brown   PetscFunctionBegin;
7552f7358SJed Brown   *cellType = -1;
8552f7358SJed Brown   switch (dim) {
9552f7358SJed Brown   case 0:
10552f7358SJed Brown     switch (corners) {
11552f7358SJed Brown     case 1:
12552f7358SJed Brown       *cellType = 1; /* VTK_VERTEX */
13552f7358SJed Brown       break;
149371c9d4SSatish Balay     default: break;
15552f7358SJed Brown     }
16552f7358SJed Brown     break;
17552f7358SJed Brown   case 1:
18552f7358SJed Brown     switch (corners) {
19552f7358SJed Brown     case 2:
20552f7358SJed Brown       *cellType = 3; /* VTK_LINE */
21552f7358SJed Brown       break;
22552f7358SJed Brown     case 3:
23552f7358SJed Brown       *cellType = 21; /* VTK_QUADRATIC_EDGE */
24552f7358SJed Brown       break;
259371c9d4SSatish Balay     default: break;
26552f7358SJed Brown     }
27552f7358SJed Brown     break;
28552f7358SJed Brown   case 2:
29552f7358SJed Brown     switch (corners) {
30552f7358SJed Brown     case 3:
31552f7358SJed Brown       *cellType = 5; /* VTK_TRIANGLE */
32552f7358SJed Brown       break;
33552f7358SJed Brown     case 4:
34552f7358SJed Brown       *cellType = 9; /* VTK_QUAD */
35552f7358SJed Brown       break;
36552f7358SJed Brown     case 6:
37552f7358SJed Brown       *cellType = 22; /* VTK_QUADRATIC_TRIANGLE */
38552f7358SJed Brown       break;
39552f7358SJed Brown     case 9:
40552f7358SJed Brown       *cellType = 23; /* VTK_QUADRATIC_QUAD */
41552f7358SJed Brown       break;
429371c9d4SSatish Balay     default: break;
43552f7358SJed Brown     }
44552f7358SJed Brown     break;
45552f7358SJed Brown   case 3:
46552f7358SJed Brown     switch (corners) {
47552f7358SJed Brown     case 4:
48552f7358SJed Brown       *cellType = 10; /* VTK_TETRA */
49552f7358SJed Brown       break;
50cf4edabeSMatthew G. Knepley     case 5:
51cf4edabeSMatthew G. Knepley       *cellType = 14; /* VTK_PYRAMID */
52cf4edabeSMatthew G. Knepley       break;
532f029394SStefano Zampini     case 6:
542f029394SStefano Zampini       *cellType = 13; /* VTK_WEDGE */
552f029394SStefano Zampini       break;
56552f7358SJed Brown     case 8:
57552f7358SJed Brown       *cellType = 12; /* VTK_HEXAHEDRON */
58552f7358SJed Brown       break;
59552f7358SJed Brown     case 10:
60552f7358SJed Brown       *cellType = 24; /* VTK_QUADRATIC_TETRA */
61552f7358SJed Brown       break;
62552f7358SJed Brown     case 27:
63552f7358SJed Brown       *cellType = 29; /* VTK_QUADRATIC_HEXAHEDRON */
64552f7358SJed Brown       break;
659371c9d4SSatish Balay     default: break;
66552f7358SJed Brown     }
67552f7358SJed Brown   }
68552f7358SJed Brown   PetscFunctionReturn(0);
69552f7358SJed Brown }
70552f7358SJed Brown 
719371c9d4SSatish Balay static PetscErrorCode DMPlexVTKWriteCells_ASCII(DM dm, FILE *fp, PetscInt *totalCells) {
7282f516ccSBarry Smith   MPI_Comm        comm;
7302281ff3SMatthew G. Knepley   DMLabel         label;
7402281ff3SMatthew G. Knepley   IS              globalVertexNumbers = NULL;
75552f7358SJed Brown   const PetscInt *gvertex;
76552f7358SJed Brown   PetscInt        dim;
77552f7358SJed Brown   PetscInt        numCorners = 0, totCorners = 0, maxCorners, *corners;
78552f7358SJed Brown   PetscInt        numCells = 0, totCells = 0, maxCells, cellHeight;
792f029394SStefano Zampini   PetscInt        numLabelCells, maxLabelCells, cStart, cEnd, c, vStart, vEnd, v;
809852e123SBarry Smith   PetscMPIInt     size, rank, proc, tag;
81552f7358SJed Brown 
82552f7358SJed Brown   PetscFunctionBegin;
839566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)dm, &comm));
849566063dSJacob Faibussowitsch   PetscCall(PetscCommGetNewTag(comm, &tag));
859566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
869566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
879566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
889566063dSJacob Faibussowitsch   PetscCall(DMPlexGetVTKCellHeight(dm, &cellHeight));
899566063dSJacob Faibussowitsch   PetscCall(DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd));
909566063dSJacob Faibussowitsch   PetscCall(DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd));
919566063dSJacob Faibussowitsch   PetscCall(DMGetLabel(dm, "vtk", &label));
929566063dSJacob Faibussowitsch   PetscCall(DMGetStratumSize(dm, "vtk", 1, &numLabelCells));
931c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(&numLabelCells, &maxLabelCells, 1, MPIU_INT, MPI_MAX, comm));
94452b7979SMatthew G. Knepley   if (!maxLabelCells) label = NULL;
95552f7358SJed Brown   for (c = cStart; c < cEnd; ++c) {
960298fd71SBarry Smith     PetscInt *closure = NULL;
9702281ff3SMatthew G. Knepley     PetscInt  closureSize, value;
98552f7358SJed Brown 
9902281ff3SMatthew G. Knepley     if (label) {
1009566063dSJacob Faibussowitsch       PetscCall(DMLabelGetValue(label, c, &value));
101552f7358SJed Brown       if (value != 1) continue;
102552f7358SJed Brown     }
1039566063dSJacob Faibussowitsch     PetscCall(DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure));
104552f7358SJed Brown     for (v = 0; v < closureSize * 2; v += 2) {
105552f7358SJed Brown       if ((closure[v] >= vStart) && (closure[v] < vEnd)) ++numCorners;
106552f7358SJed Brown     }
1079566063dSJacob Faibussowitsch     PetscCall(DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure));
108552f7358SJed Brown     ++numCells;
109552f7358SJed Brown   }
110552f7358SJed Brown   maxCells = numCells;
1119566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Reduce(&numCells, &totCells, 1, MPIU_INT, MPI_SUM, 0, comm));
1129566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Reduce(&numCells, &maxCells, 1, MPIU_INT, MPI_MAX, 0, comm));
1139566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Reduce(&numCorners, &totCorners, 1, MPIU_INT, MPI_SUM, 0, comm));
1149566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Reduce(&numCorners, &maxCorners, 1, MPIU_INT, MPI_MAX, 0, comm));
1159566063dSJacob Faibussowitsch   PetscCall(DMPlexGetVertexNumbering(dm, &globalVertexNumbers));
1169566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(globalVertexNumbers, &gvertex));
1179566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(maxCells, &corners));
11863a3b9bcSJacob Faibussowitsch   PetscCall(PetscFPrintf(comm, fp, "CELLS %" PetscInt_FMT " %" PetscInt_FMT "\n", totCells, totCorners + totCells));
119dd400576SPatrick Sanan   if (rank == 0) {
120a4a685f2SJacob Faibussowitsch     PetscInt *remoteVertices, *vertices;
121552f7358SJed Brown 
1229566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(maxCorners, &vertices));
123552f7358SJed Brown     for (c = cStart, numCells = 0; c < cEnd; ++c) {
1240298fd71SBarry Smith       PetscInt *closure = NULL;
12502281ff3SMatthew G. Knepley       PetscInt  closureSize, value, nC = 0;
126552f7358SJed Brown 
12702281ff3SMatthew G. Knepley       if (label) {
1289566063dSJacob Faibussowitsch         PetscCall(DMLabelGetValue(label, c, &value));
129552f7358SJed Brown         if (value != 1) continue;
130552f7358SJed Brown       }
1319566063dSJacob Faibussowitsch       PetscCall(DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure));
132552f7358SJed Brown       for (v = 0; v < closureSize * 2; v += 2) {
133552f7358SJed Brown         if ((closure[v] >= vStart) && (closure[v] < vEnd)) {
134552f7358SJed Brown           const PetscInt gv = gvertex[closure[v] - vStart];
1350dcf9c70SMatthew G. Knepley           vertices[nC++]    = gv < 0 ? -(gv + 1) : gv;
136552f7358SJed Brown         }
137552f7358SJed Brown       }
1389566063dSJacob Faibussowitsch       PetscCall(DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure));
1399566063dSJacob Faibussowitsch       PetscCall(DMPlexReorderCell(dm, c, vertices));
140552f7358SJed Brown       corners[numCells++] = nC;
14163a3b9bcSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm, fp, "%" PetscInt_FMT " ", nC));
142*48a46eb9SPierre Jolivet       for (v = 0; v < nC; ++v) PetscCall(PetscFPrintf(comm, fp, " %" PetscInt_FMT, vertices[v]));
1439566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm, fp, "\n"));
144552f7358SJed Brown     }
1459566063dSJacob Faibussowitsch     if (size > 1) PetscCall(PetscMalloc1(maxCorners + maxCells, &remoteVertices));
1469852e123SBarry Smith     for (proc = 1; proc < size; ++proc) {
147552f7358SJed Brown       MPI_Status status;
148552f7358SJed Brown 
1499566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Recv(&numCorners, 1, MPIU_INT, proc, tag, comm, &status));
1509566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Recv(remoteVertices, numCorners, MPIU_INT, proc, tag, comm, &status));
151552f7358SJed Brown       for (c = 0; c < numCorners;) {
152552f7358SJed Brown         PetscInt nC = remoteVertices[c++];
153552f7358SJed Brown 
1549371c9d4SSatish Balay         for (v = 0; v < nC; ++v, ++c) { vertices[v] = remoteVertices[c]; }
15563a3b9bcSJacob Faibussowitsch         PetscCall(PetscFPrintf(comm, fp, "%" PetscInt_FMT " ", nC));
156*48a46eb9SPierre Jolivet         for (v = 0; v < nC; ++v) PetscCall(PetscFPrintf(comm, fp, " %" PetscInt_FMT, vertices[v]));
1579566063dSJacob Faibussowitsch         PetscCall(PetscFPrintf(comm, fp, "\n"));
158552f7358SJed Brown       }
159552f7358SJed Brown     }
1609566063dSJacob Faibussowitsch     if (size > 1) PetscCall(PetscFree(remoteVertices));
1619566063dSJacob Faibussowitsch     PetscCall(PetscFree(vertices));
162552f7358SJed Brown   } else {
163552f7358SJed Brown     PetscInt *localVertices, numSend = numCells + numCorners, k = 0;
164552f7358SJed Brown 
1659566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(numSend, &localVertices));
166552f7358SJed Brown     for (c = cStart, numCells = 0; c < cEnd; ++c) {
1670298fd71SBarry Smith       PetscInt *closure = NULL;
16802281ff3SMatthew G. Knepley       PetscInt  closureSize, value, nC = 0;
169552f7358SJed Brown 
17002281ff3SMatthew G. Knepley       if (label) {
1719566063dSJacob Faibussowitsch         PetscCall(DMLabelGetValue(label, c, &value));
172552f7358SJed Brown         if (value != 1) continue;
173552f7358SJed Brown       }
1749566063dSJacob Faibussowitsch       PetscCall(DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure));
175552f7358SJed Brown       for (v = 0; v < closureSize * 2; v += 2) {
176552f7358SJed Brown         if ((closure[v] >= vStart) && (closure[v] < vEnd)) {
177552f7358SJed Brown           const PetscInt gv = gvertex[closure[v] - vStart];
178552f7358SJed Brown           closure[nC++]     = gv < 0 ? -(gv + 1) : gv;
179552f7358SJed Brown         }
180552f7358SJed Brown       }
181552f7358SJed Brown       corners[numCells++] = nC;
182552f7358SJed Brown       localVertices[k++]  = nC;
1839371c9d4SSatish Balay       for (v = 0; v < nC; ++v, ++k) { localVertices[k] = closure[v]; }
1849566063dSJacob Faibussowitsch       PetscCall(DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure));
1859566063dSJacob Faibussowitsch       PetscCall(DMPlexReorderCell(dm, c, localVertices + k - nC));
186552f7358SJed Brown     }
18763a3b9bcSJacob Faibussowitsch     PetscCheck(k == numSend, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid number of vertices to send %" PetscInt_FMT " should be %" PetscInt_FMT, k, numSend);
1889566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Send(&numSend, 1, MPIU_INT, 0, tag, comm));
1899566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Send(localVertices, numSend, MPIU_INT, 0, tag, comm));
1909566063dSJacob Faibussowitsch     PetscCall(PetscFree(localVertices));
191552f7358SJed Brown   }
1929566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(globalVertexNumbers, &gvertex));
19363a3b9bcSJacob Faibussowitsch   PetscCall(PetscFPrintf(comm, fp, "CELL_TYPES %" PetscInt_FMT "\n", totCells));
194dd400576SPatrick Sanan   if (rank == 0) {
195552f7358SJed Brown     PetscInt cellType;
196552f7358SJed Brown 
197552f7358SJed Brown     for (c = 0; c < numCells; ++c) {
1989566063dSJacob Faibussowitsch       PetscCall(DMPlexVTKGetCellType_Internal(dm, dim, corners[c], &cellType));
19963a3b9bcSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm, fp, "%" PetscInt_FMT "\n", cellType));
200552f7358SJed Brown     }
2019852e123SBarry Smith     for (proc = 1; proc < size; ++proc) {
202552f7358SJed Brown       MPI_Status status;
203552f7358SJed Brown 
2049566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Recv(&numCells, 1, MPIU_INT, proc, tag, comm, &status));
2059566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Recv(corners, numCells, MPIU_INT, proc, tag, comm, &status));
206552f7358SJed Brown       for (c = 0; c < numCells; ++c) {
2079566063dSJacob Faibussowitsch         PetscCall(DMPlexVTKGetCellType_Internal(dm, dim, corners[c], &cellType));
20863a3b9bcSJacob Faibussowitsch         PetscCall(PetscFPrintf(comm, fp, "%" PetscInt_FMT "\n", cellType));
209552f7358SJed Brown       }
210552f7358SJed Brown     }
211552f7358SJed Brown   } else {
2129566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Send(&numCells, 1, MPIU_INT, 0, tag, comm));
2139566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Send(corners, numCells, MPIU_INT, 0, tag, comm));
214552f7358SJed Brown   }
2159566063dSJacob Faibussowitsch   PetscCall(PetscFree(corners));
216552f7358SJed Brown   *totalCells = totCells;
217552f7358SJed Brown   PetscFunctionReturn(0);
218552f7358SJed Brown }
219552f7358SJed Brown 
2209371c9d4SSatish Balay static PetscErrorCode DMPlexVTKWritePartition_ASCII(DM dm, FILE *fp) {
221e8f6f0f6SMatthew G. Knepley   MPI_Comm    comm;
222e8f6f0f6SMatthew G. Knepley   PetscInt    numCells = 0, cellHeight;
2232f029394SStefano Zampini   PetscInt    numLabelCells, cStart, cEnd, c;
2249852e123SBarry Smith   PetscMPIInt size, rank, proc, tag;
225e8f6f0f6SMatthew G. Knepley   PetscBool   hasLabel;
226e8f6f0f6SMatthew G. Knepley 
227e8f6f0f6SMatthew G. Knepley   PetscFunctionBegin;
2289566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)dm, &comm));
2299566063dSJacob Faibussowitsch   PetscCall(PetscCommGetNewTag(comm, &tag));
2309566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
2319566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
2329566063dSJacob Faibussowitsch   PetscCall(DMPlexGetVTKCellHeight(dm, &cellHeight));
2339566063dSJacob Faibussowitsch   PetscCall(DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd));
2349566063dSJacob Faibussowitsch   PetscCall(DMGetStratumSize(dm, "vtk", 1, &numLabelCells));
235e8f6f0f6SMatthew G. Knepley   hasLabel = numLabelCells > 0 ? PETSC_TRUE : PETSC_FALSE;
236e8f6f0f6SMatthew G. Knepley   for (c = cStart; c < cEnd; ++c) {
237e8f6f0f6SMatthew G. Knepley     if (hasLabel) {
238e8f6f0f6SMatthew G. Knepley       PetscInt value;
239e8f6f0f6SMatthew G. Knepley 
2409566063dSJacob Faibussowitsch       PetscCall(DMGetLabelValue(dm, "vtk", c, &value));
241e8f6f0f6SMatthew G. Knepley       if (value != 1) continue;
242e8f6f0f6SMatthew G. Knepley     }
243e8f6f0f6SMatthew G. Knepley     ++numCells;
244e8f6f0f6SMatthew G. Knepley   }
245dd400576SPatrick Sanan   if (rank == 0) {
2469566063dSJacob Faibussowitsch     for (c = 0; c < numCells; ++c) PetscCall(PetscFPrintf(comm, fp, "%d\n", rank));
2479852e123SBarry Smith     for (proc = 1; proc < size; ++proc) {
248e8f6f0f6SMatthew G. Knepley       MPI_Status status;
249e8f6f0f6SMatthew G. Knepley 
2509566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Recv(&numCells, 1, MPIU_INT, proc, tag, comm, &status));
2519566063dSJacob Faibussowitsch       for (c = 0; c < numCells; ++c) PetscCall(PetscFPrintf(comm, fp, "%d\n", proc));
252e8f6f0f6SMatthew G. Knepley     }
253e8f6f0f6SMatthew G. Knepley   } else {
2549566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Send(&numCells, 1, MPIU_INT, 0, tag, comm));
255e8f6f0f6SMatthew G. Knepley   }
256e8f6f0f6SMatthew G. Knepley   PetscFunctionReturn(0);
257e8f6f0f6SMatthew G. Knepley }
258e8f6f0f6SMatthew G. Knepley 
25976b700caSToby Isaac #if defined(PETSC_USE_REAL_DOUBLE) || defined(PETSC_USE_REAL___FLOAT128)
26076b700caSToby Isaac typedef double PetscVTKReal;
26176b700caSToby Isaac #elif defined(PETSC_USE_REAL_SINGLE) || defined(PETSC_USE_REAL___FP16)
26276b700caSToby Isaac typedef float PetscVTKReal;
26376b700caSToby Isaac #else
26476b700caSToby Isaac typedef PetscReal PetscVTKReal;
26576b700caSToby Isaac #endif
26676b700caSToby Isaac 
2679371c9d4SSatish Balay static PetscErrorCode DMPlexVTKWriteSection_ASCII(DM dm, PetscSection section, PetscSection globalSection, Vec v, FILE *fp, PetscInt enforceDof, PetscInt precision, PetscReal scale, PetscInt imag) {
26882f516ccSBarry Smith   MPI_Comm           comm;
269552f7358SJed Brown   const MPI_Datatype mpiType = MPIU_SCALAR;
270552f7358SJed Brown   PetscScalar       *array;
271552f7358SJed Brown   PetscInt           numDof = 0, maxDof;
272412e9a14SMatthew G. Knepley   PetscInt           numLabelCells, cellHeight, cStart, cEnd, numLabelVertices, vStart, vEnd, pStart, pEnd, p;
2739852e123SBarry Smith   PetscMPIInt        size, rank, proc, tag;
274552f7358SJed Brown   PetscBool          hasLabel;
275552f7358SJed Brown 
276552f7358SJed Brown   PetscFunctionBegin;
2779566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)dm, &comm));
278552f7358SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
279552f7358SJed Brown   PetscValidHeaderSpecific(v, VEC_CLASSID, 4);
280552f7358SJed Brown   if (precision < 0) precision = 6;
2819566063dSJacob Faibussowitsch   PetscCall(PetscCommGetNewTag(comm, &tag));
2829566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
2839566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
2849566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetChart(section, &pStart, &pEnd));
285552f7358SJed Brown   /* VTK only wants the values at cells or vertices */
2869566063dSJacob Faibussowitsch   PetscCall(DMPlexGetVTKCellHeight(dm, &cellHeight));
2879566063dSJacob Faibussowitsch   PetscCall(DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd));
2889566063dSJacob Faibussowitsch   PetscCall(DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd));
289552f7358SJed Brown   pStart = PetscMax(PetscMin(cStart, vStart), pStart);
290552f7358SJed Brown   pEnd   = PetscMin(PetscMax(cEnd, vEnd), pEnd);
2919566063dSJacob Faibussowitsch   PetscCall(DMGetStratumSize(dm, "vtk", 1, &numLabelCells));
2929566063dSJacob Faibussowitsch   PetscCall(DMGetStratumSize(dm, "vtk", 2, &numLabelVertices));
293552f7358SJed Brown   hasLabel = numLabelCells > 0 || numLabelVertices > 0 ? PETSC_TRUE : PETSC_FALSE;
294552f7358SJed Brown   for (p = pStart; p < pEnd; ++p) {
295552f7358SJed Brown     /* Reject points not either cells or vertices */
296552f7358SJed Brown     if (((p < cStart) || (p >= cEnd)) && ((p < vStart) || (p >= vEnd))) continue;
297552f7358SJed Brown     if (hasLabel) {
298552f7358SJed Brown       PetscInt value;
299552f7358SJed Brown 
3009371c9d4SSatish Balay       if (((p >= cStart) && (p < cEnd) && numLabelCells) || ((p >= vStart) && (p < vEnd) && numLabelVertices)) {
3019566063dSJacob Faibussowitsch         PetscCall(DMGetLabelValue(dm, "vtk", p, &value));
302552f7358SJed Brown         if (value != 1) continue;
303552f7358SJed Brown       }
304552f7358SJed Brown     }
3059566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetDof(section, p, &numDof));
3068865f1eaSKarl Rupp     if (numDof) break;
307552f7358SJed Brown   }
3081c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(&numDof, &maxDof, 1, MPIU_INT, MPI_MAX, comm));
309552f7358SJed Brown   enforceDof = PetscMax(enforceDof, maxDof);
3109566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &array));
311dd400576SPatrick Sanan   if (rank == 0) {
31276b700caSToby Isaac     PetscVTKReal dval;
31376b700caSToby Isaac     PetscScalar  val;
314552f7358SJed Brown     char         formatString[8];
315552f7358SJed Brown 
31663a3b9bcSJacob Faibussowitsch     PetscCall(PetscSNPrintf(formatString, 8, "%%.%" PetscInt_FMT "e", precision));
317552f7358SJed Brown     for (p = pStart; p < pEnd; ++p) {
318552f7358SJed Brown       /* Here we lose a way to filter points by keeping them out of the Numbering */
319552f7358SJed Brown       PetscInt dof, off, goff, d;
320552f7358SJed Brown 
321552f7358SJed Brown       /* Reject points not either cells or vertices */
322552f7358SJed Brown       if (((p < cStart) || (p >= cEnd)) && ((p < vStart) || (p >= vEnd))) continue;
323552f7358SJed Brown       if (hasLabel) {
324552f7358SJed Brown         PetscInt value;
325552f7358SJed Brown 
3269371c9d4SSatish Balay         if (((p >= cStart) && (p < cEnd) && numLabelCells) || ((p >= vStart) && (p < vEnd) && numLabelVertices)) {
3279566063dSJacob Faibussowitsch           PetscCall(DMGetLabelValue(dm, "vtk", p, &value));
328552f7358SJed Brown           if (value != 1) continue;
329552f7358SJed Brown         }
330552f7358SJed Brown       }
3319566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetDof(section, p, &dof));
3329566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetOffset(section, p, &off));
3339566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetOffset(globalSection, p, &goff));
334552f7358SJed Brown       if (dof && goff >= 0) {
335552f7358SJed Brown         for (d = 0; d < dof; d++) {
336*48a46eb9SPierre Jolivet           if (d > 0) PetscCall(PetscFPrintf(comm, fp, " "));
33776b700caSToby Isaac           val  = array[off + d];
33876b700caSToby Isaac           dval = (PetscVTKReal)((imag ? PetscImaginaryPart(val) : PetscRealPart(val)) * scale);
3399566063dSJacob Faibussowitsch           PetscCall(PetscFPrintf(comm, fp, formatString, dval));
340552f7358SJed Brown         }
341*48a46eb9SPierre Jolivet         for (d = dof; d < enforceDof; d++) PetscCall(PetscFPrintf(comm, fp, " 0.0"));
3429566063dSJacob Faibussowitsch         PetscCall(PetscFPrintf(comm, fp, "\n"));
343552f7358SJed Brown       }
344552f7358SJed Brown     }
3459852e123SBarry Smith     for (proc = 1; proc < size; ++proc) {
346552f7358SJed Brown       PetscScalar *remoteValues;
347d892089bSMatthew G. Knepley       PetscInt     size = 0, d;
348552f7358SJed Brown       MPI_Status   status;
349552f7358SJed Brown 
3509566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Recv(&size, 1, MPIU_INT, proc, tag, comm, &status));
3519566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(size, &remoteValues));
3529566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Recv(remoteValues, size, mpiType, proc, tag, comm, &status));
353552f7358SJed Brown       for (p = 0; p < size / maxDof; ++p) {
354552f7358SJed Brown         for (d = 0; d < maxDof; ++d) {
355*48a46eb9SPierre Jolivet           if (d > 0) PetscCall(PetscFPrintf(comm, fp, " "));
35676b700caSToby Isaac           val  = remoteValues[p * maxDof + d];
35776b700caSToby Isaac           dval = (PetscVTKReal)((imag ? PetscImaginaryPart(val) : PetscRealPart(val)) * scale);
3589566063dSJacob Faibussowitsch           PetscCall(PetscFPrintf(comm, fp, formatString, dval));
359552f7358SJed Brown         }
360*48a46eb9SPierre Jolivet         for (d = maxDof; d < enforceDof; ++d) PetscCall(PetscFPrintf(comm, fp, " 0.0"));
3619566063dSJacob Faibussowitsch         PetscCall(PetscFPrintf(comm, fp, "\n"));
362552f7358SJed Brown       }
3639566063dSJacob Faibussowitsch       PetscCall(PetscFree(remoteValues));
364552f7358SJed Brown     }
365552f7358SJed Brown   } else {
366552f7358SJed Brown     PetscScalar *localValues;
367552f7358SJed Brown     PetscInt     size, k = 0;
368552f7358SJed Brown 
3699566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetStorageSize(section, &size));
3709566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(size, &localValues));
371552f7358SJed Brown     for (p = pStart; p < pEnd; ++p) {
372552f7358SJed Brown       PetscInt dof, off, goff, d;
373552f7358SJed Brown 
374552f7358SJed Brown       /* Reject points not either cells or vertices */
375552f7358SJed Brown       if (((p < cStart) || (p >= cEnd)) && ((p < vStart) || (p >= vEnd))) continue;
376552f7358SJed Brown       if (hasLabel) {
377552f7358SJed Brown         PetscInt value;
378552f7358SJed Brown 
3799371c9d4SSatish Balay         if (((p >= cStart) && (p < cEnd) && numLabelCells) || ((p >= vStart) && (p < vEnd) && numLabelVertices)) {
3809566063dSJacob Faibussowitsch           PetscCall(DMGetLabelValue(dm, "vtk", p, &value));
381552f7358SJed Brown           if (value != 1) continue;
382552f7358SJed Brown         }
383552f7358SJed Brown       }
3849566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetDof(section, p, &dof));
3859566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetOffset(section, p, &off));
3869566063dSJacob Faibussowitsch       PetscCall(PetscSectionGetOffset(globalSection, p, &goff));
387552f7358SJed Brown       if (goff >= 0) {
3889371c9d4SSatish Balay         for (d = 0; d < dof; ++d) { localValues[k++] = array[off + d]; }
389552f7358SJed Brown       }
390552f7358SJed Brown     }
3919566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Send(&k, 1, MPIU_INT, 0, tag, comm));
3929566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Send(localValues, k, mpiType, 0, tag, comm));
3939566063dSJacob Faibussowitsch     PetscCall(PetscFree(localValues));
394552f7358SJed Brown   }
3959566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &array));
396552f7358SJed Brown   PetscFunctionReturn(0);
397552f7358SJed Brown }
398552f7358SJed Brown 
3999371c9d4SSatish Balay static PetscErrorCode DMPlexVTKWriteField_ASCII(DM dm, PetscSection section, PetscSection globalSection, Vec field, const char name[], FILE *fp, PetscInt enforceDof, PetscInt precision, PetscReal scale, PetscBool nameComplex, PetscInt imag) {
40082f516ccSBarry Smith   MPI_Comm comm;
401552f7358SJed Brown   PetscInt numDof = 0, maxDof;
402552f7358SJed Brown   PetscInt pStart, pEnd, p;
403552f7358SJed Brown 
404552f7358SJed Brown   PetscFunctionBegin;
4059566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)dm, &comm));
4069566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetChart(section, &pStart, &pEnd));
407552f7358SJed Brown   for (p = pStart; p < pEnd; ++p) {
4089566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetDof(section, p, &numDof));
4098865f1eaSKarl Rupp     if (numDof) break;
410552f7358SJed Brown   }
411552f7358SJed Brown   numDof = PetscMax(numDof, enforceDof);
4121c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(&numDof, &maxDof, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm)));
413552f7358SJed Brown   if (!name) name = "Unknown";
414552f7358SJed Brown   if (maxDof == 3) {
41576b700caSToby Isaac     if (nameComplex) {
4169566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm, fp, "VECTORS %s.%s double\n", name, imag ? "Im" : "Re"));
41776b700caSToby Isaac     } else {
4189566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm, fp, "VECTORS %s double\n", name));
41976b700caSToby Isaac     }
42076b700caSToby Isaac   } else {
42176b700caSToby Isaac     if (nameComplex) {
42263a3b9bcSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm, fp, "SCALARS %s.%s double %" PetscInt_FMT "\n", name, imag ? "Im" : "Re", maxDof));
423552f7358SJed Brown     } else {
42463a3b9bcSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm, fp, "SCALARS %s double %" PetscInt_FMT "\n", name, maxDof));
42576b700caSToby Isaac     }
4269566063dSJacob Faibussowitsch     PetscCall(PetscFPrintf(comm, fp, "LOOKUP_TABLE default\n"));
427552f7358SJed Brown   }
4289566063dSJacob Faibussowitsch   PetscCall(DMPlexVTKWriteSection_ASCII(dm, section, globalSection, field, fp, enforceDof, precision, scale, imag));
429552f7358SJed Brown   PetscFunctionReturn(0);
430552f7358SJed Brown }
431552f7358SJed Brown 
4329371c9d4SSatish Balay static PetscErrorCode DMPlexVTKWriteAll_ASCII(DM dm, PetscViewer viewer) {
43382f516ccSBarry Smith   MPI_Comm                 comm;
434552f7358SJed Brown   PetscViewer_VTK         *vtk = (PetscViewer_VTK *)viewer->data;
435552f7358SJed Brown   FILE                    *fp;
436552f7358SJed Brown   PetscViewerVTKObjectLink link;
437412e9a14SMatthew G. Knepley   PetscInt                 totVertices, totCells = 0, loops_per_scalar, l;
43876b700caSToby Isaac   PetscBool                hasPoint = PETSC_FALSE, hasCell = PETSC_FALSE, writePartition = PETSC_FALSE, localized, writeComplex;
43952b05773SJed Brown   const char              *dmname;
440552f7358SJed Brown 
441552f7358SJed Brown   PetscFunctionBegin;
44276b700caSToby Isaac #if defined(PETSC_USE_COMPLEX)
44376b700caSToby Isaac   loops_per_scalar = 2;
44476b700caSToby Isaac   writeComplex     = PETSC_TRUE;
44576b700caSToby Isaac #else
44676b700caSToby Isaac   loops_per_scalar = 1;
44776b700caSToby Isaac   writeComplex     = PETSC_FALSE;
44876b700caSToby Isaac #endif
4499566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinatesLocalized(dm, &localized));
4509566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)dm, &comm));
4511dca8a05SBarry Smith   PetscCheck(!localized, comm, PETSC_ERR_SUP, "VTK output with localized coordinates not yet supported");
4529566063dSJacob Faibussowitsch   PetscCall(PetscFOpen(comm, vtk->filename, "wb", &fp));
4539566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetName((PetscObject)dm, &dmname));
4549566063dSJacob Faibussowitsch   PetscCall(PetscFPrintf(comm, fp, "# vtk DataFile Version 2.0\n"));
4559566063dSJacob Faibussowitsch   PetscCall(PetscFPrintf(comm, fp, "%s\n", dmname));
4569566063dSJacob Faibussowitsch   PetscCall(PetscFPrintf(comm, fp, "ASCII\n"));
4579566063dSJacob Faibussowitsch   PetscCall(PetscFPrintf(comm, fp, "DATASET UNSTRUCTURED_GRID\n"));
458552f7358SJed Brown   /* Vertices */
4599120ba30SVaclav Hapla   {
4609120ba30SVaclav Hapla     PetscSection section, coordSection, globalCoordSection;
4619120ba30SVaclav Hapla     Vec          coordinates;
4629120ba30SVaclav Hapla     PetscReal    lengthScale;
4639120ba30SVaclav Hapla     DMLabel      label;
4649120ba30SVaclav Hapla     IS           vStratumIS;
4659120ba30SVaclav Hapla     PetscLayout  vLayout;
4669120ba30SVaclav Hapla 
4679566063dSJacob Faibussowitsch     PetscCall(DMPlexGetScale(dm, PETSC_UNIT_LENGTH, &lengthScale));
4689566063dSJacob Faibussowitsch     PetscCall(DMGetCoordinatesLocal(dm, &coordinates));
4699566063dSJacob Faibussowitsch     PetscCall(DMPlexGetDepthLabel(dm, &label));
4709566063dSJacob Faibussowitsch     PetscCall(DMLabelGetStratumIS(label, 0, &vStratumIS));
4719566063dSJacob Faibussowitsch     PetscCall(DMGetCoordinateSection(dm, &section));                                   /* This section includes all points */
4726b57843cSMatthew G. Knepley     PetscCall(PetscSectionCreateSubdomainSection(section, vStratumIS, &coordSection)); /* This one includes just vertices */
4739566063dSJacob Faibussowitsch     PetscCall(PetscSectionCreateGlobalSection(coordSection, dm->sf, PETSC_FALSE, PETSC_FALSE, &globalCoordSection));
4749566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetPointLayout(comm, globalCoordSection, &vLayout));
4759566063dSJacob Faibussowitsch     PetscCall(PetscLayoutGetSize(vLayout, &totVertices));
47663a3b9bcSJacob Faibussowitsch     PetscCall(PetscFPrintf(comm, fp, "POINTS %" PetscInt_FMT " double\n", totVertices));
4779566063dSJacob Faibussowitsch     PetscCall(DMPlexVTKWriteSection_ASCII(dm, coordSection, globalCoordSection, coordinates, fp, 3, PETSC_DETERMINE, lengthScale, 0));
4789566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&vStratumIS));
4799566063dSJacob Faibussowitsch     PetscCall(PetscLayoutDestroy(&vLayout));
4809566063dSJacob Faibussowitsch     PetscCall(PetscSectionDestroy(&coordSection));
4819566063dSJacob Faibussowitsch     PetscCall(PetscSectionDestroy(&globalCoordSection));
4829120ba30SVaclav Hapla   }
483552f7358SJed Brown   /* Cells */
4849566063dSJacob Faibussowitsch   PetscCall(DMPlexVTKWriteCells_ASCII(dm, fp, &totCells));
485552f7358SJed Brown   /* Vertex fields */
486552f7358SJed Brown   for (link = vtk->link; link; link = link->next) {
487552f7358SJed Brown     if ((link->ft == PETSC_VTK_POINT_FIELD) || (link->ft == PETSC_VTK_POINT_VECTOR_FIELD)) hasPoint = PETSC_TRUE;
488552f7358SJed Brown     if ((link->ft == PETSC_VTK_CELL_FIELD) || (link->ft == PETSC_VTK_CELL_VECTOR_FIELD)) hasCell = PETSC_TRUE;
489552f7358SJed Brown   }
490552f7358SJed Brown   if (hasPoint) {
49163a3b9bcSJacob Faibussowitsch     PetscCall(PetscFPrintf(comm, fp, "POINT_DATA %" PetscInt_FMT "\n", totVertices));
492552f7358SJed Brown     for (link = vtk->link; link; link = link->next) {
493552f7358SJed Brown       Vec          X       = (Vec)link->vec;
494e630c359SToby Isaac       PetscSection section = NULL, globalSection, newSection = NULL;
495e630c359SToby Isaac       char         namebuf[256];
496552f7358SJed Brown       const char  *name;
497552f7358SJed Brown       PetscInt     enforceDof = PETSC_DETERMINE;
498552f7358SJed Brown 
499552f7358SJed Brown       if ((link->ft != PETSC_VTK_POINT_FIELD) && (link->ft != PETSC_VTK_POINT_VECTOR_FIELD)) continue;
500552f7358SJed Brown       if (link->ft == PETSC_VTK_POINT_VECTOR_FIELD) enforceDof = 3;
5019566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetName(link->vec, &name));
5029566063dSJacob Faibussowitsch       PetscCall(PetscObjectQuery(link->vec, "section", (PetscObject *)&section));
503e630c359SToby Isaac       if (!section) {
504e630c359SToby Isaac         DM dmX;
505e630c359SToby Isaac 
5069566063dSJacob Faibussowitsch         PetscCall(VecGetDM(X, &dmX));
507552f7358SJed Brown         if (dmX) {
508088580cfSMatthew G Knepley           DMLabel  subpointMap, subpointMapX;
509839dd189SMatthew G Knepley           PetscInt dim, dimX, pStart, pEnd, qStart, qEnd;
510839dd189SMatthew G Knepley 
5119566063dSJacob Faibussowitsch           PetscCall(DMGetLocalSection(dmX, &section));
512839dd189SMatthew G Knepley           /* Here is where we check whether dmX is a submesh of dm */
5139566063dSJacob Faibussowitsch           PetscCall(DMGetDimension(dm, &dim));
5149566063dSJacob Faibussowitsch           PetscCall(DMGetDimension(dmX, &dimX));
5159566063dSJacob Faibussowitsch           PetscCall(DMPlexGetChart(dm, &pStart, &pEnd));
5169566063dSJacob Faibussowitsch           PetscCall(DMPlexGetChart(dmX, &qStart, &qEnd));
5179566063dSJacob Faibussowitsch           PetscCall(DMPlexGetSubpointMap(dm, &subpointMap));
5189566063dSJacob Faibussowitsch           PetscCall(DMPlexGetSubpointMap(dmX, &subpointMapX));
519839dd189SMatthew G Knepley           if (((dim != dimX) || ((pEnd - pStart) < (qEnd - qStart))) && subpointMap && !subpointMapX) {
520434e42b5SMatthew G. Knepley             const PetscInt *ind = NULL;
521e6ccafaeSMatthew G Knepley             IS              subpointIS;
522434e42b5SMatthew G. Knepley             PetscInt        n = 0, q;
523839dd189SMatthew G Knepley 
5249566063dSJacob Faibussowitsch             PetscCall(PetscSectionGetChart(section, &qStart, &qEnd));
5259566063dSJacob Faibussowitsch             PetscCall(DMPlexGetSubpointIS(dm, &subpointIS));
526434e42b5SMatthew G. Knepley             if (subpointIS) {
5279566063dSJacob Faibussowitsch               PetscCall(ISGetLocalSize(subpointIS, &n));
5289566063dSJacob Faibussowitsch               PetscCall(ISGetIndices(subpointIS, &ind));
529434e42b5SMatthew G. Knepley             }
5309566063dSJacob Faibussowitsch             PetscCall(PetscSectionCreate(comm, &newSection));
5319566063dSJacob Faibussowitsch             PetscCall(PetscSectionSetChart(newSection, pStart, pEnd));
532839dd189SMatthew G Knepley             for (q = qStart; q < qEnd; ++q) {
533839dd189SMatthew G Knepley               PetscInt dof, off, p;
534839dd189SMatthew G Knepley 
5359566063dSJacob Faibussowitsch               PetscCall(PetscSectionGetDof(section, q, &dof));
536839dd189SMatthew G Knepley               if (dof) {
5379566063dSJacob Faibussowitsch                 PetscCall(PetscFindInt(q, n, ind, &p));
538839dd189SMatthew G Knepley                 if (p >= pStart) {
5399566063dSJacob Faibussowitsch                   PetscCall(PetscSectionSetDof(newSection, p, dof));
5409566063dSJacob Faibussowitsch                   PetscCall(PetscSectionGetOffset(section, q, &off));
5419566063dSJacob Faibussowitsch                   PetscCall(PetscSectionSetOffset(newSection, p, off));
542839dd189SMatthew G Knepley                 }
543839dd189SMatthew G Knepley               }
544839dd189SMatthew G Knepley             }
545*48a46eb9SPierre Jolivet             if (subpointIS) PetscCall(ISRestoreIndices(subpointIS, &ind));
546839dd189SMatthew G Knepley             /* No need to setup section */
547839dd189SMatthew G Knepley             section = newSection;
548839dd189SMatthew G Knepley           }
549552f7358SJed Brown         }
550e630c359SToby Isaac       }
55128b400f6SJacob Faibussowitsch       PetscCheck(section, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Vector %s had no PetscSection composed with it and could not create one from VecGetDM()", name);
552e630c359SToby Isaac       if (link->field >= 0) {
553e630c359SToby Isaac         const char *fieldname;
554e630c359SToby Isaac 
5559566063dSJacob Faibussowitsch         PetscCall(PetscSectionGetFieldName(section, link->field, &fieldname));
5569566063dSJacob Faibussowitsch         PetscCall(PetscSectionGetField(section, link->field, &section));
557e630c359SToby Isaac         if (fieldname) {
5589566063dSJacob Faibussowitsch           PetscCall(PetscSNPrintf(namebuf, sizeof(namebuf), "%s%s", name, fieldname));
559e630c359SToby Isaac         } else {
56063a3b9bcSJacob Faibussowitsch           PetscCall(PetscSNPrintf(namebuf, sizeof(namebuf), "%s%" PetscInt_FMT, name, link->field));
561e630c359SToby Isaac         }
5622fb742c9SToby Isaac       } else {
5639566063dSJacob Faibussowitsch         PetscCall(PetscSNPrintf(namebuf, sizeof(namebuf), "%s", name));
564e630c359SToby Isaac       }
5659566063dSJacob Faibussowitsch       PetscCall(PetscViewerVTKSanitizeName_Internal(namebuf, sizeof(namebuf)));
5669566063dSJacob Faibussowitsch       PetscCall(PetscSectionCreateGlobalSection(section, dm->sf, PETSC_FALSE, PETSC_FALSE, &globalSection));
567*48a46eb9SPierre Jolivet       for (l = 0; l < loops_per_scalar; l++) PetscCall(DMPlexVTKWriteField_ASCII(dm, section, globalSection, X, namebuf, fp, enforceDof, PETSC_DETERMINE, 1.0, writeComplex, l));
5689566063dSJacob Faibussowitsch       PetscCall(PetscSectionDestroy(&globalSection));
5699566063dSJacob Faibussowitsch       if (newSection) PetscCall(PetscSectionDestroy(&newSection));
570552f7358SJed Brown     }
571552f7358SJed Brown   }
572552f7358SJed Brown   /* Cell Fields */
5739566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(((PetscObject)dm)->options, ((PetscObject)dm)->prefix, "-dm_view_partition", &writePartition, NULL));
574e8f6f0f6SMatthew G. Knepley   if (hasCell || writePartition) {
57563a3b9bcSJacob Faibussowitsch     PetscCall(PetscFPrintf(comm, fp, "CELL_DATA %" PetscInt_FMT "\n", totCells));
576552f7358SJed Brown     for (link = vtk->link; link; link = link->next) {
577552f7358SJed Brown       Vec          X       = (Vec)link->vec;
578e630c359SToby Isaac       PetscSection section = NULL, globalSection;
5792fb742c9SToby Isaac       const char  *name    = "";
580e630c359SToby Isaac       char         namebuf[256];
581552f7358SJed Brown       PetscInt     enforceDof = PETSC_DETERMINE;
582552f7358SJed Brown 
583552f7358SJed Brown       if ((link->ft != PETSC_VTK_CELL_FIELD) && (link->ft != PETSC_VTK_CELL_VECTOR_FIELD)) continue;
584552f7358SJed Brown       if (link->ft == PETSC_VTK_CELL_VECTOR_FIELD) enforceDof = 3;
5859566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetName(link->vec, &name));
5869566063dSJacob Faibussowitsch       PetscCall(PetscObjectQuery(link->vec, "section", (PetscObject *)&section));
587e630c359SToby Isaac       if (!section) {
588e630c359SToby Isaac         DM dmX;
589e630c359SToby Isaac 
5909566063dSJacob Faibussowitsch         PetscCall(VecGetDM(X, &dmX));
591*48a46eb9SPierre Jolivet         if (dmX) PetscCall(DMGetLocalSection(dmX, &section));
592e630c359SToby Isaac       }
59328b400f6SJacob Faibussowitsch       PetscCheck(section, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Vector %s had no PetscSection composed with it and could not create one from VecGetDM()", name);
594e630c359SToby Isaac       if (link->field >= 0) {
595e630c359SToby Isaac         const char *fieldname;
596e630c359SToby Isaac 
5979566063dSJacob Faibussowitsch         PetscCall(PetscSectionGetFieldName(section, link->field, &fieldname));
5989566063dSJacob Faibussowitsch         PetscCall(PetscSectionGetField(section, link->field, &section));
599e630c359SToby Isaac         if (fieldname) {
6009566063dSJacob Faibussowitsch           PetscCall(PetscSNPrintf(namebuf, sizeof(namebuf), "%s%s", name, fieldname));
601e630c359SToby Isaac         } else {
60263a3b9bcSJacob Faibussowitsch           PetscCall(PetscSNPrintf(namebuf, sizeof(namebuf), "%s%" PetscInt_FMT, name, link->field));
603e630c359SToby Isaac         }
6042fb742c9SToby Isaac       } else {
6059566063dSJacob Faibussowitsch         PetscCall(PetscSNPrintf(namebuf, sizeof(namebuf), "%s", name));
606e630c359SToby Isaac       }
6079566063dSJacob Faibussowitsch       PetscCall(PetscViewerVTKSanitizeName_Internal(namebuf, sizeof(namebuf)));
6089566063dSJacob Faibussowitsch       PetscCall(PetscSectionCreateGlobalSection(section, dm->sf, PETSC_FALSE, PETSC_FALSE, &globalSection));
609*48a46eb9SPierre Jolivet       for (l = 0; l < loops_per_scalar; l++) PetscCall(DMPlexVTKWriteField_ASCII(dm, section, globalSection, X, namebuf, fp, enforceDof, PETSC_DETERMINE, 1.0, writeComplex, l));
6109566063dSJacob Faibussowitsch       PetscCall(PetscSectionDestroy(&globalSection));
611552f7358SJed Brown     }
612e8f6f0f6SMatthew G. Knepley     if (writePartition) {
6139566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm, fp, "SCALARS partition int 1\n"));
6149566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm, fp, "LOOKUP_TABLE default\n"));
6159566063dSJacob Faibussowitsch       PetscCall(DMPlexVTKWritePartition_ASCII(dm, fp));
616e8f6f0f6SMatthew G. Knepley     }
617552f7358SJed Brown   }
618552f7358SJed Brown   /* Cleanup */
6199566063dSJacob Faibussowitsch   PetscCall(PetscFClose(comm, fp));
620552f7358SJed Brown   PetscFunctionReturn(0);
621552f7358SJed Brown }
622552f7358SJed Brown 
623552f7358SJed Brown /*@C
624552f7358SJed Brown   DMPlexVTKWriteAll - Write a file containing all the fields that have been provided to the viewer
625552f7358SJed Brown 
626552f7358SJed Brown   Collective
627552f7358SJed Brown 
6284165533cSJose E. Roman   Input Parameters:
629552f7358SJed Brown + odm - The DMPlex specifying the mesh, passed as a PetscObject
630552f7358SJed Brown - viewer - viewer of type VTK
631552f7358SJed Brown 
632552f7358SJed Brown   Level: developer
633552f7358SJed Brown 
634552f7358SJed Brown   Note:
635552f7358SJed Brown   This function is a callback used by the VTK viewer to actually write the file.
636552f7358SJed Brown   The reason for this odd model is that the VTK file format does not provide any way to write one field at a time.
637552f7358SJed Brown   Instead, metadata for the entire file needs to be available up-front before you can start writing the file.
638552f7358SJed Brown 
639db781477SPatrick Sanan .seealso: `PETSCVIEWERVTK`
640552f7358SJed Brown @*/
6419371c9d4SSatish Balay PetscErrorCode DMPlexVTKWriteAll(PetscObject odm, PetscViewer viewer) {
642552f7358SJed Brown   DM        dm = (DM)odm;
643552f7358SJed Brown   PetscBool isvtk;
644552f7358SJed Brown 
645552f7358SJed Brown   PetscFunctionBegin;
646552f7358SJed Brown   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
647552f7358SJed Brown   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
6489566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK, &isvtk));
64928b400f6SJacob Faibussowitsch   PetscCheck(isvtk, PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_INCOMP, "Cannot use viewer type %s", ((PetscObject)viewer)->type_name);
650552f7358SJed Brown   switch (viewer->format) {
6519371c9d4SSatish Balay   case PETSC_VIEWER_ASCII_VTK_DEPRECATED: PetscCall(DMPlexVTKWriteAll_ASCII(dm, viewer)); break;
6529371c9d4SSatish Balay   case PETSC_VIEWER_VTK_VTU: PetscCall(DMPlexVTKWriteAll_VTU(dm, viewer)); break;
65398921bdaSJacob Faibussowitsch   default: SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "No support for format '%s'", PetscViewerFormats[viewer->format]);
654552f7358SJed Brown   }
655552f7358SJed Brown   PetscFunctionReturn(0);
656552f7358SJed Brown }
657