Actual source code: swarmpic_view.c

  1: #include <petscdm.h>
  2: #include <petscdmda.h>
  3: #include <petscdmswarm.h>
  4: #include <petsc/private/dmswarmimpl.h>
  5: #include "../src/dm/impls/swarm/data_bucket.h"

  7: static PetscErrorCode private_PetscViewerCreate_XDMF(MPI_Comm comm, const char filename[], PetscViewer *v)
  8: {
  9:   long int      *bytes;
 10:   PetscContainer container;
 11:   PetscViewer    viewer;

 13:   PetscFunctionBegin;
 14:   PetscCall(PetscViewerCreate(comm, &viewer));
 15:   PetscCall(PetscViewerSetType(viewer, PETSCVIEWERASCII));
 16:   PetscCall(PetscViewerFileSetMode(viewer, FILE_MODE_WRITE));
 17:   PetscCall(PetscViewerFileSetName(viewer, filename));

 19:   PetscCall(PetscMalloc1(1, &bytes));
 20:   bytes[0] = 0;
 21:   PetscCall(PetscContainerCreate(comm, &container));
 22:   PetscCall(PetscContainerSetPointer(container, (void *)bytes));
 23:   PetscCall(PetscObjectCompose((PetscObject)viewer, "XDMFViewerContext", (PetscObject)container));

 25:   /* write xdmf header */
 26:   PetscCall(PetscViewerASCIIPrintf(viewer, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"));
 27:   PetscCall(PetscViewerASCIIPrintf(viewer, "<Xdmf xmlns:xi=\"http://www.w3.org/2001/XInclude/\" Version=\"2.99\">\n"));
 28:   /* write xdmf domain */
 29:   PetscCall(PetscViewerASCIIPushTab(viewer));
 30:   PetscCall(PetscViewerASCIIPrintf(viewer, "<Domain>\n"));
 31:   *v = viewer;
 32:   PetscFunctionReturn(PETSC_SUCCESS);
 33: }

 35: static PetscErrorCode private_PetscViewerDestroy_XDMF(PetscViewer *v)
 36: {
 37:   PetscViewer    viewer;
 38:   DM             dm = NULL;
 39:   long int      *bytes;
 40:   PetscContainer container = NULL;

 42:   PetscFunctionBegin;
 43:   if (!v) PetscFunctionReturn(PETSC_SUCCESS);
 44:   viewer = *v;

 46:   PetscCall(PetscObjectQuery((PetscObject)viewer, "DMSwarm", (PetscObject *)&dm));
 47:   if (dm) {
 48:     PetscCall(PetscViewerASCIIPrintf(viewer, "</Grid>\n"));
 49:     PetscCall(PetscViewerASCIIPopTab(viewer));
 50:   }

 52:   /* close xdmf header */
 53:   PetscCall(PetscViewerASCIIPrintf(viewer, "</Domain>\n"));
 54:   PetscCall(PetscViewerASCIIPopTab(viewer));
 55:   PetscCall(PetscViewerASCIIPrintf(viewer, "</Xdmf>\n"));

 57:   PetscCall(PetscObjectQuery((PetscObject)viewer, "XDMFViewerContext", (PetscObject *)&container));
 58:   if (container) {
 59:     PetscCall(PetscContainerGetPointer(container, (void **)&bytes));
 60:     PetscCall(PetscFree(bytes));
 61:     PetscCall(PetscContainerDestroy(&container));
 62:   }
 63:   PetscCall(PetscViewerDestroy(&viewer));
 64:   *v = NULL;
 65:   PetscFunctionReturn(PETSC_SUCCESS);
 66: }

 68: static PetscErrorCode private_CreateDataFileNameXDMF(const char filename[], char dfilename[])
 69: {
 70:   const char dot_xmf[] = ".xmf";
 71:   size_t     len;
 72:   char       viewername_minus_ext[PETSC_MAX_PATH_LEN];
 73:   PetscBool  flg;

 75:   PetscFunctionBegin;
 76:   PetscCall(PetscStrendswith(filename, dot_xmf, &flg));
 77:   PetscCheck(flg, PETSC_COMM_SELF, PETSC_ERR_SUP, "File extension must be %s", dot_xmf);
 78:   PetscCall(PetscStrncpy(viewername_minus_ext, filename, sizeof(viewername_minus_ext)));
 79:   PetscCall(PetscStrlen(filename, &len));
 80:   len -= sizeof(dot_xmf) - 1;
 81:   if (sizeof(viewername_minus_ext) > len) viewername_minus_ext[len] = '\0';
 82:   PetscCall(PetscSNPrintf(dfilename, PETSC_MAX_PATH_LEN - 1, "%s_swarm_fields.pbin", viewername_minus_ext));
 83:   PetscFunctionReturn(PETSC_SUCCESS);
 84: }

 86: static PetscErrorCode private_DMSwarmView_XDMF(DM dm, PetscViewer viewer)
 87: {
 88:   PetscBool      isswarm = PETSC_FALSE;
 89:   const char    *viewername;
 90:   char           datafile[PETSC_MAX_PATH_LEN];
 91:   char          *datafilename;
 92:   PetscViewer    fviewer;
 93:   PetscInt       k, ng, dim;
 94:   Vec            dvec;
 95:   long int      *bytes     = NULL;
 96:   PetscContainer container = NULL;
 97:   const char    *dmname;

 99:   PetscFunctionBegin;
100:   PetscCall(PetscObjectQuery((PetscObject)viewer, "XDMFViewerContext", (PetscObject *)&container));
101:   if (container) {
102:     PetscCall(PetscContainerGetPointer(container, (void **)&bytes));
103:   } else SETERRQ(PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Valid to find attached data XDMFViewerContext");

105:   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSWARM, &isswarm));
106:   PetscCheck(isswarm, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Only valid for DMSwarm");

108:   PetscCall(PetscObjectCompose((PetscObject)viewer, "DMSwarm", (PetscObject)dm));

110:   PetscCall(PetscViewerASCIIPushTab(viewer));
111:   PetscCall(PetscObjectGetName((PetscObject)dm, &dmname));
112:   if (!dmname) PetscCall(DMGetOptionsPrefix(dm, &dmname));
113:   if (!dmname) {
114:     PetscCall(PetscViewerASCIIPrintf(viewer, "<Grid Name=\"DMSwarm\" GridType=\"Uniform\">\n"));
115:   } else {
116:     PetscCall(PetscViewerASCIIPrintf(viewer, "<Grid Name=\"DMSwarm[%s]\" GridType=\"Uniform\">\n", dmname));
117:   }

119:   /* create a sub-viewer for topology, geometry and all data fields */
120:   /* name is viewer.name + "_swarm_fields.pbin" */
121:   PetscCall(PetscViewerCreate(PetscObjectComm((PetscObject)viewer), &fviewer));
122:   PetscCall(PetscViewerSetType(fviewer, PETSCVIEWERBINARY));
123:   PetscCall(PetscViewerBinarySetSkipHeader(fviewer, PETSC_TRUE));
124:   PetscCall(PetscViewerBinarySetSkipInfo(fviewer, PETSC_TRUE));
125:   PetscCall(PetscViewerFileSetMode(fviewer, FILE_MODE_WRITE));

127:   PetscCall(PetscViewerFileGetName(viewer, &viewername));
128:   PetscCall(private_CreateDataFileNameXDMF(viewername, datafile));
129:   PetscCall(PetscViewerFileSetName(fviewer, datafile));
130:   PetscCall(PetscStrrchr(datafile, '/', &datafilename));

132:   PetscCall(DMSwarmGetSize(dm, &ng));

134:   /* write topology header */
135:   PetscCall(PetscViewerASCIIPushTab(viewer));
136:   PetscCall(PetscViewerASCIIPrintf(viewer, "<Topology Dimensions=\"%" PetscInt_FMT "\" TopologyType=\"Mixed\">\n", ng));
137:   PetscCall(PetscViewerASCIIPushTab(viewer));
138:   PetscCall(PetscViewerASCIIPrintf(viewer, "<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Int\" Dimensions=\"%" PetscInt_FMT "\" Seek=\"%ld\">\n", ng * 3, bytes[0]));
139:   PetscCall(PetscViewerASCIIPushTab(viewer));
140:   PetscCall(PetscViewerASCIIPrintf(viewer, "%s\n", datafilename));
141:   PetscCall(PetscViewerASCIIPopTab(viewer));
142:   PetscCall(PetscViewerASCIIPrintf(viewer, "</DataItem>\n"));
143:   PetscCall(PetscViewerASCIIPopTab(viewer));
144:   PetscCall(PetscViewerASCIIPrintf(viewer, "</Topology>\n"));
145:   PetscCall(PetscViewerASCIIPopTab(viewer));

147:   /* write topology data */
148:   for (k = 0; k < ng; k++) {
149:     PetscInt pvertex[3];

151:     pvertex[0] = 1;
152:     pvertex[1] = 1;
153:     pvertex[2] = k;
154:     PetscCall(PetscViewerBinaryWrite(fviewer, pvertex, 3, PETSC_INT));
155:   }
156:   bytes[0] += sizeof(PetscInt) * ng * 3;

158:   /* write geometry header */
159:   PetscCall(PetscViewerASCIIPushTab(viewer));
160:   PetscCall(DMGetDimension(dm, &dim));
161:   switch (dim) {
162:   case 1:
163:     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for 1D");
164:   case 2:
165:     PetscCall(PetscViewerASCIIPrintf(viewer, "<Geometry Type=\"XY\">\n"));
166:     break;
167:   case 3:
168:     PetscCall(PetscViewerASCIIPrintf(viewer, "<Geometry Type=\"XYZ\">\n"));
169:     break;
170:   }
171:   PetscCall(PetscViewerASCIIPushTab(viewer));
172:   PetscCall(PetscViewerASCIIPrintf(viewer, "<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Float\" Precision=\"8\" Dimensions=\"%" PetscInt_FMT " %" PetscInt_FMT "\" Seek=\"%ld\">\n", ng, dim, bytes[0]));
173:   PetscCall(PetscViewerASCIIPushTab(viewer));
174:   PetscCall(PetscViewerASCIIPrintf(viewer, "%s\n", datafilename));
175:   PetscCall(PetscViewerASCIIPopTab(viewer));
176:   PetscCall(PetscViewerASCIIPrintf(viewer, "</DataItem>\n"));
177:   PetscCall(PetscViewerASCIIPopTab(viewer));
178:   PetscCall(PetscViewerASCIIPrintf(viewer, "</Geometry>\n"));
179:   PetscCall(PetscViewerASCIIPopTab(viewer));

181:   /* write geometry data */
182:   PetscCall(DMSwarmCreateGlobalVectorFromField(dm, DMSwarmPICField_coor, &dvec));
183:   PetscCall(VecView(dvec, fviewer));
184:   PetscCall(DMSwarmDestroyGlobalVectorFromField(dm, DMSwarmPICField_coor, &dvec));
185:   bytes[0] += sizeof(PetscReal) * ng * dim;

187:   PetscCall(PetscViewerDestroy(&fviewer));
188:   PetscFunctionReturn(PETSC_SUCCESS);
189: }

191: static PetscErrorCode private_VecView_Swarm_XDMF(Vec x, PetscViewer viewer)
192: {
193:   long int      *bytes     = NULL;
194:   PetscContainer container = NULL;
195:   const char    *viewername;
196:   char           datafile[PETSC_MAX_PATH_LEN];
197:   char          *datafilename;
198:   PetscViewer    fviewer;
199:   PetscInt       N, bs;
200:   const char    *vecname;
201:   char           fieldname[PETSC_MAX_PATH_LEN];

203:   PetscFunctionBegin;
204:   PetscCall(PetscObjectQuery((PetscObject)viewer, "XDMFViewerContext", (PetscObject *)&container));
205:   PetscCheck(container, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Unable to find attached data XDMFViewerContext");
206:   PetscCall(PetscContainerGetPointer(container, (void **)&bytes));
207:   PetscCall(PetscViewerFileGetName(viewer, &viewername));
208:   PetscCall(private_CreateDataFileNameXDMF(viewername, datafile));

210:   /* re-open a sub-viewer for all data fields */
211:   /* name is viewer.name + "_swarm_fields.pbin" */
212:   PetscCall(PetscViewerCreate(PetscObjectComm((PetscObject)viewer), &fviewer));
213:   PetscCall(PetscViewerSetType(fviewer, PETSCVIEWERBINARY));
214:   PetscCall(PetscViewerBinarySetSkipHeader(fviewer, PETSC_TRUE));
215:   PetscCall(PetscViewerBinarySetSkipInfo(fviewer, PETSC_TRUE));
216:   PetscCall(PetscViewerFileSetMode(fviewer, FILE_MODE_APPEND));
217:   PetscCall(PetscViewerFileSetName(fviewer, datafile));
218:   PetscCall(PetscStrrchr(datafile, '/', &datafilename));

220:   PetscCall(VecGetSize(x, &N));
221:   PetscCall(VecGetBlockSize(x, &bs));
222:   N = N / bs;
223:   PetscCall(PetscObjectGetName((PetscObject)x, &vecname));
224:   if (!vecname) {
225:     PetscCall(PetscSNPrintf(fieldname, PETSC_MAX_PATH_LEN - 1, "swarmfield_%d", ((PetscObject)x)->tag));
226:   } else {
227:     PetscCall(PetscSNPrintf(fieldname, PETSC_MAX_PATH_LEN - 1, "%s", vecname));
228:   }

230:   /* write data header */
231:   PetscCall(PetscViewerASCIIPushTab(viewer));
232:   PetscCall(PetscViewerASCIIPrintf(viewer, "<Attribute Center=\"Node\" Name=\"%s\" Type=\"None\">\n", fieldname));
233:   PetscCall(PetscViewerASCIIPushTab(viewer));
234:   if (bs == 1) {
235:     PetscCall(PetscViewerASCIIPrintf(viewer, "<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Float\" Precision=\"8\" Dimensions=\"%" PetscInt_FMT "\" Seek=\"%ld\">\n", N, bytes[0]));
236:   } else {
237:     PetscCall(PetscViewerASCIIPrintf(viewer, "<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Float\" Precision=\"8\" Dimensions=\"%" PetscInt_FMT " %" PetscInt_FMT "\" Seek=\"%ld\">\n", N, bs, bytes[0]));
238:   }
239:   PetscCall(PetscViewerASCIIPushTab(viewer));
240:   PetscCall(PetscViewerASCIIPrintf(viewer, "%s\n", datafilename));
241:   PetscCall(PetscViewerASCIIPopTab(viewer));
242:   PetscCall(PetscViewerASCIIPrintf(viewer, "</DataItem>\n"));
243:   PetscCall(PetscViewerASCIIPopTab(viewer));
244:   PetscCall(PetscViewerASCIIPrintf(viewer, "</Attribute>\n"));
245:   PetscCall(PetscViewerASCIIPopTab(viewer));

247:   /* write data */
248:   PetscCall(VecView(x, fviewer));
249:   bytes[0] += sizeof(PetscReal) * N * bs;

251:   PetscCall(PetscViewerDestroy(&fviewer));
252:   PetscFunctionReturn(PETSC_SUCCESS);
253: }

255: static PetscErrorCode private_ISView_Swarm_XDMF(IS is, PetscViewer viewer)
256: {
257:   long int      *bytes     = NULL;
258:   PetscContainer container = NULL;
259:   const char    *viewername;
260:   char           datafile[PETSC_MAX_PATH_LEN];
261:   char          *datafilename;
262:   PetscViewer    fviewer;
263:   PetscInt       N, bs;
264:   const char    *vecname;
265:   char           fieldname[PETSC_MAX_PATH_LEN];

267:   PetscFunctionBegin;
268:   PetscCall(PetscObjectQuery((PetscObject)viewer, "XDMFViewerContext", (PetscObject *)&container));
269:   PetscCheck(container, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Unable to find attached data XDMFViewerContext");
270:   PetscCall(PetscContainerGetPointer(container, (void **)&bytes));
271:   PetscCall(PetscViewerFileGetName(viewer, &viewername));
272:   PetscCall(private_CreateDataFileNameXDMF(viewername, datafile));

274:   /* re-open a sub-viewer for all data fields */
275:   /* name is viewer.name + "_swarm_fields.pbin" */
276:   PetscCall(PetscViewerCreate(PetscObjectComm((PetscObject)viewer), &fviewer));
277:   PetscCall(PetscViewerSetType(fviewer, PETSCVIEWERBINARY));
278:   PetscCall(PetscViewerBinarySetSkipHeader(fviewer, PETSC_TRUE));
279:   PetscCall(PetscViewerBinarySetSkipInfo(fviewer, PETSC_TRUE));
280:   PetscCall(PetscViewerFileSetMode(fviewer, FILE_MODE_APPEND));
281:   PetscCall(PetscViewerFileSetName(fviewer, datafile));
282:   PetscCall(PetscStrrchr(datafile, '/', &datafilename));

284:   PetscCall(ISGetSize(is, &N));
285:   PetscCall(ISGetBlockSize(is, &bs));
286:   N = N / bs;
287:   PetscCall(PetscObjectGetName((PetscObject)is, &vecname));
288:   if (!vecname) {
289:     PetscCall(PetscSNPrintf(fieldname, PETSC_MAX_PATH_LEN - 1, "swarmfield_%d", ((PetscObject)is)->tag));
290:   } else {
291:     PetscCall(PetscSNPrintf(fieldname, PETSC_MAX_PATH_LEN - 1, "%s", vecname));
292:   }

294:   /* write data header */
295:   PetscCall(PetscViewerASCIIPushTab(viewer));
296:   PetscCall(PetscViewerASCIIPrintf(viewer, "<Attribute Center=\"Node\" Name=\"%s\" Type=\"None\">\n", fieldname));
297:   PetscCall(PetscViewerASCIIPushTab(viewer));
298:   if (bs == 1) {
299:     PetscCall(PetscViewerASCIIPrintf(viewer, "<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Int\" Precision=\"4\" Dimensions=\"%" PetscInt_FMT "\" Seek=\"%ld\">\n", N, bytes[0]));
300:   } else {
301:     PetscCall(PetscViewerASCIIPrintf(viewer, "<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Int\" Precision=\"4\" Dimensions=\"%" PetscInt_FMT " %" PetscInt_FMT "\" Seek=\"%ld\">\n", N, bs, bytes[0]));
302:   }
303:   PetscCall(PetscViewerASCIIPushTab(viewer));
304:   PetscCall(PetscViewerASCIIPrintf(viewer, "%s\n", datafilename));
305:   PetscCall(PetscViewerASCIIPopTab(viewer));
306:   PetscCall(PetscViewerASCIIPrintf(viewer, "</DataItem>\n"));
307:   PetscCall(PetscViewerASCIIPopTab(viewer));
308:   PetscCall(PetscViewerASCIIPrintf(viewer, "</Attribute>\n"));
309:   PetscCall(PetscViewerASCIIPopTab(viewer));

311:   /* write data */
312:   PetscCall(ISView(is, fviewer));
313:   bytes[0] += sizeof(PetscInt) * N * bs;

315:   PetscCall(PetscViewerDestroy(&fviewer));
316:   PetscFunctionReturn(PETSC_SUCCESS);
317: }

319: /*@C
320:   DMSwarmViewFieldsXDMF - Write a selection of DMSwarm fields to an XDMF3 file

322:   Collective

324:   Input Parameters:
325: + dm              - the `DMSWARM`
326: . filename        - the file name of the XDMF file (must have the extension .xmf)
327: . nfields         - the number of fields to write into the XDMF file
328: - field_name_list - array of length nfields containing the textual name of fields to write

330:   Level: beginner

332:   Note:
333:   Only fields registered with data type `PETSC_DOUBLE` or `PETSC_INT` can be written into the file

335: .seealso: `DM`, `DMSWARM`, `DMSwarmViewXDMF()`
336: @*/
337: PETSC_EXTERN PetscErrorCode DMSwarmViewFieldsXDMF(DM dm, const char filename[], PetscInt nfields, const char *field_name_list[])
338: {
339:   Vec         dvec;
340:   PetscInt    f, N;
341:   PetscViewer viewer;

343:   PetscFunctionBegin;
344:   PetscCall(private_PetscViewerCreate_XDMF(PetscObjectComm((PetscObject)dm), filename, &viewer));
345:   PetscCall(private_DMSwarmView_XDMF(dm, viewer));
346:   PetscCall(DMSwarmGetLocalSize(dm, &N));
347:   for (f = 0; f < nfields; f++) {
348:     void         *data;
349:     PetscDataType type;

351:     PetscCall(DMSwarmGetField(dm, field_name_list[f], NULL, &type, &data));
352:     PetscCall(DMSwarmRestoreField(dm, field_name_list[f], NULL, &type, &data));
353:     if (type == PETSC_DOUBLE) {
354:       PetscCall(DMSwarmCreateGlobalVectorFromField(dm, field_name_list[f], &dvec));
355:       PetscCall(PetscObjectSetName((PetscObject)dvec, field_name_list[f]));
356:       PetscCall(private_VecView_Swarm_XDMF(dvec, viewer));
357:       PetscCall(DMSwarmDestroyGlobalVectorFromField(dm, field_name_list[f], &dvec));
358:     } else if (type == PETSC_INT) {
359:       IS              is;
360:       const PetscInt *idx;

362:       PetscCall(DMSwarmGetField(dm, field_name_list[f], NULL, &type, &data));
363:       idx = (const PetscInt *)data;

365:       PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)dm), N, idx, PETSC_USE_POINTER, &is));
366:       PetscCall(PetscObjectSetName((PetscObject)is, field_name_list[f]));
367:       PetscCall(private_ISView_Swarm_XDMF(is, viewer));
368:       PetscCall(ISDestroy(&is));
369:       PetscCall(DMSwarmRestoreField(dm, field_name_list[f], NULL, &type, &data));
370:     } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only write PETSC_INT and PETSC_DOUBLE");
371:   }
372:   PetscCall(private_PetscViewerDestroy_XDMF(&viewer));
373:   PetscFunctionReturn(PETSC_SUCCESS);
374: }

376: /*@C
377:   DMSwarmViewXDMF - Write `DMSWARM` fields to an XDMF3 file

379:   Collective

381:   Input Parameters:
382: + dm       - the `DMSWARM`
383: - filename - the file name of the XDMF file (must have the extension .xmf)

385:   Level: beginner

387:   Note:
388:   Only fields user registered with data type `PETSC_DOUBLE` or `PETSC_INT` will be written into the file

390:   Developer Note:
391:   This should be removed and replaced with the standard use of `PetscViewer`

393: .seealso: `DM`, `DMSWARM`, `DMSwarmViewFieldsXDMF()`
394: @*/
395: PETSC_EXTERN PetscErrorCode DMSwarmViewXDMF(DM dm, const char filename[])
396: {
397:   DM_Swarm   *swarm = (DM_Swarm *)dm->data;
398:   Vec         dvec;
399:   PetscInt    f;
400:   PetscViewer viewer;

402:   PetscFunctionBegin;
403:   PetscCall(private_PetscViewerCreate_XDMF(PetscObjectComm((PetscObject)dm), filename, &viewer));
404:   PetscCall(private_DMSwarmView_XDMF(dm, viewer));
405:   for (f = 4; f < swarm->db->nfields; f++) { /* only examine user defined fields - the first 4 are internally created by DMSwarmPIC */
406:     DMSwarmDataField field;

408:     /* query field type - accept all those of type PETSC_DOUBLE */
409:     field = swarm->db->field[f];
410:     if (field->petsc_type == PETSC_DOUBLE) {
411:       PetscCall(DMSwarmCreateGlobalVectorFromField(dm, field->name, &dvec));
412:       PetscCall(PetscObjectSetName((PetscObject)dvec, field->name));
413:       PetscCall(private_VecView_Swarm_XDMF(dvec, viewer));
414:       PetscCall(DMSwarmDestroyGlobalVectorFromField(dm, field->name, &dvec));
415:     } else if (field->petsc_type == PETSC_INT) {
416:       IS              is;
417:       PetscInt        N;
418:       const PetscInt *idx;
419:       void           *data;

421:       PetscCall(DMSwarmGetLocalSize(dm, &N));
422:       PetscCall(DMSwarmGetField(dm, field->name, NULL, NULL, &data));
423:       idx = (const PetscInt *)data;

425:       PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)dm), N, idx, PETSC_USE_POINTER, &is));
426:       PetscCall(PetscObjectSetName((PetscObject)is, field->name));
427:       PetscCall(private_ISView_Swarm_XDMF(is, viewer));
428:       PetscCall(ISDestroy(&is));
429:       PetscCall(DMSwarmRestoreField(dm, field->name, NULL, NULL, &data));
430:     }
431:   }
432:   PetscCall(private_PetscViewerDestroy_XDMF(&viewer));
433:   PetscFunctionReturn(PETSC_SUCCESS);
434: }