xref: /petsc/src/dm/impls/swarm/swarmpic_view.c (revision 19307e5cf369b208f3c5d721c42c941e418b5101)
1cc4c1da9SBarry Smith #include <petscdmda.h>                 /*I  "petscdmda.h"  I*/
2cc4c1da9SBarry Smith #include <petsc/private/dmswarmimpl.h> /*I  "petscdmswarm.h"  I*/
3279f676cSBarry Smith #include "../src/dm/impls/swarm/data_bucket.h"
40e2ec84fSDave May 
566976f2fSJacob Faibussowitsch static PetscErrorCode private_PetscViewerCreate_XDMF(MPI_Comm comm, const char filename[], PetscViewer *v)
6d71ae5a4SJacob Faibussowitsch {
70e2ec84fSDave May   long int      *bytes;
80e2ec84fSDave May   PetscContainer container;
90e2ec84fSDave May   PetscViewer    viewer;
100e2ec84fSDave May 
110e2ec84fSDave May   PetscFunctionBegin;
129566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(comm, &viewer));
139566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(viewer, PETSCVIEWERASCII));
149566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileSetMode(viewer, FILE_MODE_WRITE));
159566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileSetName(viewer, filename));
160e2ec84fSDave May 
179566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(1, &bytes));
180e2ec84fSDave May   bytes[0] = 0;
199566063dSJacob Faibussowitsch   PetscCall(PetscContainerCreate(comm, &container));
209566063dSJacob Faibussowitsch   PetscCall(PetscContainerSetPointer(container, (void *)bytes));
219566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)viewer, "XDMFViewerContext", (PetscObject)container));
220e2ec84fSDave May 
230e2ec84fSDave May   /* write xdmf header */
249566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"));
259566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "<Xdmf xmlns:xi=\"http://www.w3.org/2001/XInclude/\" Version=\"2.99\">\n"));
260e2ec84fSDave May   /* write xdmf domain */
279566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
289566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "<Domain>\n"));
290e2ec84fSDave May   *v = viewer;
303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
310e2ec84fSDave May }
320e2ec84fSDave May 
3366976f2fSJacob Faibussowitsch static PetscErrorCode private_PetscViewerDestroy_XDMF(PetscViewer *v)
34d71ae5a4SJacob Faibussowitsch {
350e2ec84fSDave May   PetscViewer    viewer;
360e2ec84fSDave May   DM             dm = NULL;
370e2ec84fSDave May   long int      *bytes;
380e2ec84fSDave May   PetscContainer container = NULL;
390e2ec84fSDave May 
400e2ec84fSDave May   PetscFunctionBegin;
413ba16761SJacob Faibussowitsch   if (!v) PetscFunctionReturn(PETSC_SUCCESS);
420e2ec84fSDave May   viewer = *v;
430e2ec84fSDave May 
449566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)viewer, "DMSwarm", (PetscObject *)&dm));
450e2ec84fSDave May   if (dm) {
469566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "</Grid>\n"));
479566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
480e2ec84fSDave May   }
490e2ec84fSDave May 
500e2ec84fSDave May   /* close xdmf header */
519566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "</Domain>\n"));
529566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
539566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "</Xdmf>\n"));
540e2ec84fSDave May 
559566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)viewer, "XDMFViewerContext", (PetscObject *)&container));
560e2ec84fSDave May   if (container) {
579566063dSJacob Faibussowitsch     PetscCall(PetscContainerGetPointer(container, (void **)&bytes));
589566063dSJacob Faibussowitsch     PetscCall(PetscFree(bytes));
599566063dSJacob Faibussowitsch     PetscCall(PetscContainerDestroy(&container));
600e2ec84fSDave May   }
619566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&viewer));
620e2ec84fSDave May   *v = NULL;
633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
640e2ec84fSDave May }
650e2ec84fSDave May 
6666976f2fSJacob Faibussowitsch static PetscErrorCode private_CreateDataFileNameXDMF(const char filename[], char dfilename[])
67d71ae5a4SJacob Faibussowitsch {
689b15cf9aSJacob Faibussowitsch   const char dot_xmf[] = ".xmf";
699b15cf9aSJacob Faibussowitsch   size_t     len;
709b15cf9aSJacob Faibussowitsch   char       viewername_minus_ext[PETSC_MAX_PATH_LEN];
710e2ec84fSDave May   PetscBool  flg;
720e2ec84fSDave May 
730e2ec84fSDave May   PetscFunctionBegin;
749b15cf9aSJacob Faibussowitsch   PetscCall(PetscStrendswith(filename, dot_xmf, &flg));
759b15cf9aSJacob Faibussowitsch   PetscCheck(flg, PETSC_COMM_SELF, PETSC_ERR_SUP, "File extension must be %s", dot_xmf);
769b15cf9aSJacob Faibussowitsch   PetscCall(PetscStrncpy(viewername_minus_ext, filename, sizeof(viewername_minus_ext)));
779566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(filename, &len));
789b15cf9aSJacob Faibussowitsch   len -= sizeof(dot_xmf) - 1;
799b15cf9aSJacob Faibussowitsch   if (sizeof(viewername_minus_ext) > len) viewername_minus_ext[len] = '\0';
809566063dSJacob Faibussowitsch   PetscCall(PetscSNPrintf(dfilename, PETSC_MAX_PATH_LEN - 1, "%s_swarm_fields.pbin", viewername_minus_ext));
813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
820e2ec84fSDave May }
830e2ec84fSDave May 
8466976f2fSJacob Faibussowitsch static PetscErrorCode private_DMSwarmView_XDMF(DM dm, PetscViewer viewer)
85d71ae5a4SJacob Faibussowitsch {
86*19307e5cSMatthew G. Knepley   DMSwarmCellDM  celldm;
870e2ec84fSDave May   PetscBool      isswarm = PETSC_FALSE;
880e2ec84fSDave May   const char    *viewername;
890e2ec84fSDave May   char           datafile[PETSC_MAX_PATH_LEN];
903249a2ebSMara Arts   char          *datafilename;
910e2ec84fSDave May   PetscViewer    fviewer;
92*19307e5cSMatthew G. Knepley   PetscInt       k, ng, dim, Nfc;
930e2ec84fSDave May   Vec            dvec;
940e2ec84fSDave May   long int      *bytes     = NULL;
950e2ec84fSDave May   PetscContainer container = NULL;
96*19307e5cSMatthew G. Knepley   const char    *dmname, **coordFields;
970e2ec84fSDave May 
980e2ec84fSDave May   PetscFunctionBegin;
999566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)viewer, "XDMFViewerContext", (PetscObject *)&container));
1000e2ec84fSDave May   if (container) {
1019566063dSJacob Faibussowitsch     PetscCall(PetscContainerGetPointer(container, (void **)&bytes));
1020e2ec84fSDave May   } else SETERRQ(PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Valid to find attached data XDMFViewerContext");
1030e2ec84fSDave May 
1049566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSWARM, &isswarm));
10528b400f6SJacob Faibussowitsch   PetscCheck(isswarm, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Only valid for DMSwarm");
1060e2ec84fSDave May 
1079566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)viewer, "DMSwarm", (PetscObject)dm));
1080e2ec84fSDave May 
1099566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
1109566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetName((PetscObject)dm, &dmname));
11148a46eb9SPierre Jolivet   if (!dmname) PetscCall(DMGetOptionsPrefix(dm, &dmname));
1120e2ec84fSDave May   if (!dmname) {
1139566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "<Grid Name=\"DMSwarm\" GridType=\"Uniform\">\n"));
1140e2ec84fSDave May   } else {
1159566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "<Grid Name=\"DMSwarm[%s]\" GridType=\"Uniform\">\n", dmname));
1160e2ec84fSDave May   }
1170e2ec84fSDave May 
1180e2ec84fSDave May   /* create a sub-viewer for topology, geometry and all data fields */
1190e2ec84fSDave May   /* name is viewer.name + "_swarm_fields.pbin" */
1209566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(PetscObjectComm((PetscObject)viewer), &fviewer));
1219566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(fviewer, PETSCVIEWERBINARY));
1229566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinarySetSkipHeader(fviewer, PETSC_TRUE));
1239566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinarySetSkipInfo(fviewer, PETSC_TRUE));
1249566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileSetMode(fviewer, FILE_MODE_WRITE));
1250e2ec84fSDave May 
1269566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileGetName(viewer, &viewername));
1279566063dSJacob Faibussowitsch   PetscCall(private_CreateDataFileNameXDMF(viewername, datafile));
1289566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileSetName(fviewer, datafile));
1299566063dSJacob Faibussowitsch   PetscCall(PetscStrrchr(datafile, '/', &datafilename));
1300e2ec84fSDave May 
1319566063dSJacob Faibussowitsch   PetscCall(DMSwarmGetSize(dm, &ng));
1320e2ec84fSDave May 
1330e2ec84fSDave May   /* write topology header */
1349566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
13563a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "<Topology Dimensions=\"%" PetscInt_FMT "\" TopologyType=\"Mixed\">\n", ng));
1369566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
13763a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Int\" Dimensions=\"%" PetscInt_FMT "\" Seek=\"%ld\">\n", ng * 3, bytes[0]));
1389566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
1399566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "%s\n", datafilename));
1409566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
1419566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "</DataItem>\n"));
1429566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
1439566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "</Topology>\n"));
1449566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
1450e2ec84fSDave May 
1460e2ec84fSDave May   /* write topology data */
1470e2ec84fSDave May   for (k = 0; k < ng; k++) {
1480e2ec84fSDave May     PetscInt pvertex[3];
1490e2ec84fSDave May 
1500e2ec84fSDave May     pvertex[0] = 1;
1510e2ec84fSDave May     pvertex[1] = 1;
1520e2ec84fSDave May     pvertex[2] = k;
1539566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(fviewer, pvertex, 3, PETSC_INT));
1540e2ec84fSDave May   }
1550e2ec84fSDave May   bytes[0] += sizeof(PetscInt) * ng * 3;
1560e2ec84fSDave May 
1570e2ec84fSDave May   /* write geometry header */
1589566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
1599566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
1600e2ec84fSDave May   switch (dim) {
161d71ae5a4SJacob Faibussowitsch   case 1:
162d71ae5a4SJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for 1D");
163d71ae5a4SJacob Faibussowitsch   case 2:
164d71ae5a4SJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "<Geometry Type=\"XY\">\n"));
165d71ae5a4SJacob Faibussowitsch     break;
166d71ae5a4SJacob Faibussowitsch   case 3:
167d71ae5a4SJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "<Geometry Type=\"XYZ\">\n"));
168d71ae5a4SJacob Faibussowitsch     break;
1690e2ec84fSDave May   }
1709566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
17163a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Float\" Precision=\"8\" Dimensions=\"%" PetscInt_FMT " %" PetscInt_FMT "\" Seek=\"%ld\">\n", ng, dim, bytes[0]));
1729566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
1739566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "%s\n", datafilename));
1749566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
1759566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "</DataItem>\n"));
1769566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
1779566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "</Geometry>\n"));
1789566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
1790e2ec84fSDave May 
180*19307e5cSMatthew G. Knepley   PetscCall(DMSwarmGetCellDMActive(dm, &celldm));
181*19307e5cSMatthew G. Knepley   PetscCall(DMSwarmCellDMGetCoordinateFields(celldm, &Nfc, &coordFields));
182*19307e5cSMatthew G. Knepley   PetscCheck(Nfc == 1, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "We only support a single coordinate field right now, not %" PetscInt_FMT, Nfc);
183*19307e5cSMatthew G. Knepley 
1840e2ec84fSDave May   /* write geometry data */
185*19307e5cSMatthew G. Knepley   PetscCall(DMSwarmCreateGlobalVectorFromField(dm, coordFields[0], &dvec));
1869566063dSJacob Faibussowitsch   PetscCall(VecView(dvec, fviewer));
187*19307e5cSMatthew G. Knepley   PetscCall(DMSwarmDestroyGlobalVectorFromField(dm, coordFields[0], &dvec));
1880e2ec84fSDave May   bytes[0] += sizeof(PetscReal) * ng * dim;
1890e2ec84fSDave May 
1909566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&fviewer));
1913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1920e2ec84fSDave May }
1930e2ec84fSDave May 
19466976f2fSJacob Faibussowitsch static PetscErrorCode private_VecView_Swarm_XDMF(Vec x, PetscViewer viewer)
195d71ae5a4SJacob Faibussowitsch {
1960e2ec84fSDave May   long int      *bytes     = NULL;
1970e2ec84fSDave May   PetscContainer container = NULL;
1980e2ec84fSDave May   const char    *viewername;
1990e2ec84fSDave May   char           datafile[PETSC_MAX_PATH_LEN];
2003249a2ebSMara Arts   char          *datafilename;
2010e2ec84fSDave May   PetscViewer    fviewer;
2020e2ec84fSDave May   PetscInt       N, bs;
2030e2ec84fSDave May   const char    *vecname;
2040e2ec84fSDave May   char           fieldname[PETSC_MAX_PATH_LEN];
2050e2ec84fSDave May 
2060e2ec84fSDave May   PetscFunctionBegin;
2079566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)viewer, "XDMFViewerContext", (PetscObject *)&container));
20828b400f6SJacob Faibussowitsch   PetscCheck(container, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Unable to find attached data XDMFViewerContext");
2099566063dSJacob Faibussowitsch   PetscCall(PetscContainerGetPointer(container, (void **)&bytes));
2109566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileGetName(viewer, &viewername));
2119566063dSJacob Faibussowitsch   PetscCall(private_CreateDataFileNameXDMF(viewername, datafile));
2120e2ec84fSDave May 
2130e2ec84fSDave May   /* re-open a sub-viewer for all data fields */
2140e2ec84fSDave May   /* name is viewer.name + "_swarm_fields.pbin" */
2159566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(PetscObjectComm((PetscObject)viewer), &fviewer));
2169566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(fviewer, PETSCVIEWERBINARY));
2179566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinarySetSkipHeader(fviewer, PETSC_TRUE));
2189566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinarySetSkipInfo(fviewer, PETSC_TRUE));
2199566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileSetMode(fviewer, FILE_MODE_APPEND));
2209566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileSetName(fviewer, datafile));
2219566063dSJacob Faibussowitsch   PetscCall(PetscStrrchr(datafile, '/', &datafilename));
2220e2ec84fSDave May 
2239566063dSJacob Faibussowitsch   PetscCall(VecGetSize(x, &N));
2249566063dSJacob Faibussowitsch   PetscCall(VecGetBlockSize(x, &bs));
2250e2ec84fSDave May   N = N / bs;
2269566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetName((PetscObject)x, &vecname));
2270e2ec84fSDave May   if (!vecname) {
22863a3b9bcSJacob Faibussowitsch     PetscCall(PetscSNPrintf(fieldname, PETSC_MAX_PATH_LEN - 1, "swarmfield_%d", ((PetscObject)x)->tag));
2290e2ec84fSDave May   } else {
2309566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(fieldname, PETSC_MAX_PATH_LEN - 1, "%s", vecname));
2310e2ec84fSDave May   }
2320e2ec84fSDave May 
2330e2ec84fSDave May   /* write data header */
2349566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
2359566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "<Attribute Center=\"Node\" Name=\"%s\" Type=\"None\">\n", fieldname));
2369566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
2370e2ec84fSDave May   if (bs == 1) {
23863a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Float\" Precision=\"8\" Dimensions=\"%" PetscInt_FMT "\" Seek=\"%ld\">\n", N, bytes[0]));
2390e2ec84fSDave May   } else {
24063a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Float\" Precision=\"8\" Dimensions=\"%" PetscInt_FMT " %" PetscInt_FMT "\" Seek=\"%ld\">\n", N, bs, bytes[0]));
2410e2ec84fSDave May   }
2429566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
2439566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "%s\n", datafilename));
2449566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
2459566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "</DataItem>\n"));
2469566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
2479566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "</Attribute>\n"));
2489566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
2490e2ec84fSDave May 
2500e2ec84fSDave May   /* write data */
2519566063dSJacob Faibussowitsch   PetscCall(VecView(x, fviewer));
2520e2ec84fSDave May   bytes[0] += sizeof(PetscReal) * N * bs;
2530e2ec84fSDave May 
2549566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&fviewer));
2553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2560e2ec84fSDave May }
2570e2ec84fSDave May 
25866976f2fSJacob Faibussowitsch static PetscErrorCode private_ISView_Swarm_XDMF(IS is, PetscViewer viewer)
259d71ae5a4SJacob Faibussowitsch {
260c14f9142SDave May   long int      *bytes     = NULL;
261c14f9142SDave May   PetscContainer container = NULL;
262c14f9142SDave May   const char    *viewername;
263c14f9142SDave May   char           datafile[PETSC_MAX_PATH_LEN];
2643249a2ebSMara Arts   char          *datafilename;
265c14f9142SDave May   PetscViewer    fviewer;
266c14f9142SDave May   PetscInt       N, bs;
267c14f9142SDave May   const char    *vecname;
268c14f9142SDave May   char           fieldname[PETSC_MAX_PATH_LEN];
269c14f9142SDave May 
270c14f9142SDave May   PetscFunctionBegin;
2719566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)viewer, "XDMFViewerContext", (PetscObject *)&container));
27228b400f6SJacob Faibussowitsch   PetscCheck(container, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Unable to find attached data XDMFViewerContext");
2739566063dSJacob Faibussowitsch   PetscCall(PetscContainerGetPointer(container, (void **)&bytes));
2749566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileGetName(viewer, &viewername));
2759566063dSJacob Faibussowitsch   PetscCall(private_CreateDataFileNameXDMF(viewername, datafile));
276c14f9142SDave May 
277c14f9142SDave May   /* re-open a sub-viewer for all data fields */
278c14f9142SDave May   /* name is viewer.name + "_swarm_fields.pbin" */
2799566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(PetscObjectComm((PetscObject)viewer), &fviewer));
2809566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(fviewer, PETSCVIEWERBINARY));
2819566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinarySetSkipHeader(fviewer, PETSC_TRUE));
2829566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinarySetSkipInfo(fviewer, PETSC_TRUE));
2839566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileSetMode(fviewer, FILE_MODE_APPEND));
2849566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileSetName(fviewer, datafile));
2859566063dSJacob Faibussowitsch   PetscCall(PetscStrrchr(datafile, '/', &datafilename));
286c14f9142SDave May 
2879566063dSJacob Faibussowitsch   PetscCall(ISGetSize(is, &N));
2889566063dSJacob Faibussowitsch   PetscCall(ISGetBlockSize(is, &bs));
289c14f9142SDave May   N = N / bs;
2909566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetName((PetscObject)is, &vecname));
291c14f9142SDave May   if (!vecname) {
29263a3b9bcSJacob Faibussowitsch     PetscCall(PetscSNPrintf(fieldname, PETSC_MAX_PATH_LEN - 1, "swarmfield_%d", ((PetscObject)is)->tag));
293c14f9142SDave May   } else {
2949566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(fieldname, PETSC_MAX_PATH_LEN - 1, "%s", vecname));
295c14f9142SDave May   }
296c14f9142SDave May 
297c14f9142SDave May   /* write data header */
2989566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
2999566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "<Attribute Center=\"Node\" Name=\"%s\" Type=\"None\">\n", fieldname));
3009566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
301c14f9142SDave May   if (bs == 1) {
30263a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Int\" Precision=\"4\" Dimensions=\"%" PetscInt_FMT "\" Seek=\"%ld\">\n", N, bytes[0]));
303c14f9142SDave May   } else {
30463a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Int\" Precision=\"4\" Dimensions=\"%" PetscInt_FMT " %" PetscInt_FMT "\" Seek=\"%ld\">\n", N, bs, bytes[0]));
305c14f9142SDave May   }
3069566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
3079566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "%s\n", datafilename));
3089566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
3099566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "</DataItem>\n"));
3109566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
3119566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "</Attribute>\n"));
3129566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
313c14f9142SDave May 
314c14f9142SDave May   /* write data */
3159566063dSJacob Faibussowitsch   PetscCall(ISView(is, fviewer));
316c14f9142SDave May   bytes[0] += sizeof(PetscInt) * N * bs;
317c14f9142SDave May 
3189566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&fviewer));
3193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
320c14f9142SDave May }
321c14f9142SDave May 
322acf7c82dSDave May /*@C
323acf7c82dSDave May   DMSwarmViewFieldsXDMF - Write a selection of DMSwarm fields to an XDMF3 file
324acf7c82dSDave May 
32520f4b53cSBarry Smith   Collective
326acf7c82dSDave May 
32760225df5SJacob Faibussowitsch   Input Parameters:
32820f4b53cSBarry Smith + dm              - the `DMSWARM`
329acf7c82dSDave May . filename        - the file name of the XDMF file (must have the extension .xmf)
330acf7c82dSDave May . nfields         - the number of fields to write into the XDMF file
331acf7c82dSDave May - field_name_list - array of length nfields containing the textual name of fields to write
332acf7c82dSDave May 
333acf7c82dSDave May   Level: beginner
334acf7c82dSDave May 
33520f4b53cSBarry Smith   Note:
33620f4b53cSBarry Smith   Only fields registered with data type `PETSC_DOUBLE` or `PETSC_INT` can be written into the file
337acf7c82dSDave May 
33820f4b53cSBarry Smith .seealso: `DM`, `DMSWARM`, `DMSwarmViewXDMF()`
339acf7c82dSDave May @*/
340cc4c1da9SBarry Smith PetscErrorCode DMSwarmViewFieldsXDMF(DM dm, const char filename[], PetscInt nfields, const char *field_name_list[])
341d71ae5a4SJacob Faibussowitsch {
3420e2ec84fSDave May   Vec         dvec;
343c14f9142SDave May   PetscInt    f, N;
3440e2ec84fSDave May   PetscViewer viewer;
3450e2ec84fSDave May 
3460e2ec84fSDave May   PetscFunctionBegin;
3479566063dSJacob Faibussowitsch   PetscCall(private_PetscViewerCreate_XDMF(PetscObjectComm((PetscObject)dm), filename, &viewer));
3489566063dSJacob Faibussowitsch   PetscCall(private_DMSwarmView_XDMF(dm, viewer));
3499566063dSJacob Faibussowitsch   PetscCall(DMSwarmGetLocalSize(dm, &N));
3500e2ec84fSDave May   for (f = 0; f < nfields; f++) {
351c14f9142SDave May     void         *data;
352c14f9142SDave May     PetscDataType type;
353c14f9142SDave May 
3549566063dSJacob Faibussowitsch     PetscCall(DMSwarmGetField(dm, field_name_list[f], NULL, &type, &data));
3559566063dSJacob Faibussowitsch     PetscCall(DMSwarmRestoreField(dm, field_name_list[f], NULL, &type, &data));
356c14f9142SDave May     if (type == PETSC_DOUBLE) {
3579566063dSJacob Faibussowitsch       PetscCall(DMSwarmCreateGlobalVectorFromField(dm, field_name_list[f], &dvec));
3589566063dSJacob Faibussowitsch       PetscCall(PetscObjectSetName((PetscObject)dvec, field_name_list[f]));
3599566063dSJacob Faibussowitsch       PetscCall(private_VecView_Swarm_XDMF(dvec, viewer));
3609566063dSJacob Faibussowitsch       PetscCall(DMSwarmDestroyGlobalVectorFromField(dm, field_name_list[f], &dvec));
361c14f9142SDave May     } else if (type == PETSC_INT) {
362c14f9142SDave May       IS              is;
363c14f9142SDave May       const PetscInt *idx;
364c14f9142SDave May 
3659566063dSJacob Faibussowitsch       PetscCall(DMSwarmGetField(dm, field_name_list[f], NULL, &type, &data));
366c14f9142SDave May       idx = (const PetscInt *)data;
367c14f9142SDave May 
3689566063dSJacob Faibussowitsch       PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)dm), N, idx, PETSC_USE_POINTER, &is));
3699566063dSJacob Faibussowitsch       PetscCall(PetscObjectSetName((PetscObject)is, field_name_list[f]));
3709566063dSJacob Faibussowitsch       PetscCall(private_ISView_Swarm_XDMF(is, viewer));
3719566063dSJacob Faibussowitsch       PetscCall(ISDestroy(&is));
3729566063dSJacob Faibussowitsch       PetscCall(DMSwarmRestoreField(dm, field_name_list[f], NULL, &type, &data));
373c14f9142SDave May     } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only write PETSC_INT and PETSC_DOUBLE");
3740e2ec84fSDave May   }
3759566063dSJacob Faibussowitsch   PetscCall(private_PetscViewerDestroy_XDMF(&viewer));
3763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3770e2ec84fSDave May }
3780e2ec84fSDave May 
379cc4c1da9SBarry Smith /*@
38020f4b53cSBarry Smith   DMSwarmViewXDMF - Write `DMSWARM` fields to an XDMF3 file
381acf7c82dSDave May 
38220f4b53cSBarry Smith   Collective
383acf7c82dSDave May 
38460225df5SJacob Faibussowitsch   Input Parameters:
38520f4b53cSBarry Smith + dm       - the `DMSWARM`
386acf7c82dSDave May - filename - the file name of the XDMF file (must have the extension .xmf)
387acf7c82dSDave May 
388acf7c82dSDave May   Level: beginner
389acf7c82dSDave May 
39020f4b53cSBarry Smith   Note:
39120f4b53cSBarry Smith   Only fields user registered with data type `PETSC_DOUBLE` or `PETSC_INT` will be written into the file
392acf7c82dSDave May 
393a3b724e8SBarry Smith   Developer Note:
39420f4b53cSBarry Smith   This should be removed and replaced with the standard use of `PetscViewer`
3955627991aSBarry Smith 
39620f4b53cSBarry Smith .seealso: `DM`, `DMSWARM`, `DMSwarmViewFieldsXDMF()`
397acf7c82dSDave May @*/
398cc4c1da9SBarry Smith PetscErrorCode DMSwarmViewXDMF(DM dm, const char filename[])
399d71ae5a4SJacob Faibussowitsch {
4000e2ec84fSDave May   DM_Swarm   *swarm = (DM_Swarm *)dm->data;
4010e2ec84fSDave May   Vec         dvec;
4020e2ec84fSDave May   PetscInt    f;
4030e2ec84fSDave May   PetscViewer viewer;
4040e2ec84fSDave May 
4050e2ec84fSDave May   PetscFunctionBegin;
4069566063dSJacob Faibussowitsch   PetscCall(private_PetscViewerCreate_XDMF(PetscObjectComm((PetscObject)dm), filename, &viewer));
4079566063dSJacob Faibussowitsch   PetscCall(private_DMSwarmView_XDMF(dm, viewer));
4080e2ec84fSDave May   for (f = 4; f < swarm->db->nfields; f++) { /* only examine user defined fields - the first 4 are internally created by DMSwarmPIC */
40977048351SPatrick Sanan     DMSwarmDataField field;
4100e2ec84fSDave May 
4110e2ec84fSDave May     /* query field type - accept all those of type PETSC_DOUBLE */
4120e2ec84fSDave May     field = swarm->db->field[f];
413c14f9142SDave May     if (field->petsc_type == PETSC_DOUBLE) {
4149566063dSJacob Faibussowitsch       PetscCall(DMSwarmCreateGlobalVectorFromField(dm, field->name, &dvec));
4159566063dSJacob Faibussowitsch       PetscCall(PetscObjectSetName((PetscObject)dvec, field->name));
4169566063dSJacob Faibussowitsch       PetscCall(private_VecView_Swarm_XDMF(dvec, viewer));
4179566063dSJacob Faibussowitsch       PetscCall(DMSwarmDestroyGlobalVectorFromField(dm, field->name, &dvec));
418c14f9142SDave May     } else if (field->petsc_type == PETSC_INT) {
419c14f9142SDave May       IS              is;
420c14f9142SDave May       PetscInt        N;
421c14f9142SDave May       const PetscInt *idx;
422c14f9142SDave May       void           *data;
423c14f9142SDave May 
4249566063dSJacob Faibussowitsch       PetscCall(DMSwarmGetLocalSize(dm, &N));
4259566063dSJacob Faibussowitsch       PetscCall(DMSwarmGetField(dm, field->name, NULL, NULL, &data));
426c14f9142SDave May       idx = (const PetscInt *)data;
427c14f9142SDave May 
4289566063dSJacob Faibussowitsch       PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)dm), N, idx, PETSC_USE_POINTER, &is));
4299566063dSJacob Faibussowitsch       PetscCall(PetscObjectSetName((PetscObject)is, field->name));
4309566063dSJacob Faibussowitsch       PetscCall(private_ISView_Swarm_XDMF(is, viewer));
4319566063dSJacob Faibussowitsch       PetscCall(ISDestroy(&is));
4329566063dSJacob Faibussowitsch       PetscCall(DMSwarmRestoreField(dm, field->name, NULL, NULL, &data));
433c14f9142SDave May     }
4340e2ec84fSDave May   }
4359566063dSJacob Faibussowitsch   PetscCall(private_PetscViewerDestroy_XDMF(&viewer));
4363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4370e2ec84fSDave May }
438