Actual source code: ex56.c
1: #include <petscdmplex.h>
2: #include <petscviewerhdf5.h>
3: #include <petscsf.h>
5: static const char help[] = "Test DMLabel I/O with PETSc native HDF5 mesh format\n\n";
6: static const char EX[] = "ex56.c";
7: typedef struct {
8: MPI_Comm comm;
9: const char *meshname; /* Mesh name */
10: PetscInt num_labels; /* Asserted number of labels in loaded mesh */
11: PetscBool compare; /* Compare the meshes using DMPlexEqual() and DMCompareLabels() */
12: PetscBool compare_labels; /* Compare labels in the meshes using DMCompareLabels() */
13: PetscBool compare_boundary; /* Check label I/O via boundary vertex coordinates */
14: PetscBool compare_pre_post; /* Compare labels loaded before distribution with those loaded after distribution */
15: char outfile[PETSC_MAX_PATH_LEN]; /* Output file */
16: PetscBool use_low_level_functions; /* Use low level functions for viewing and loading */
17: //TODO This is meant as temporary option; can be removed once we have full parallel loading in place
18: PetscBool distribute_after_topo_load; /* Distribute topology right after DMPlexTopologyLoad(), if use_low_level_functions=true */
19: PetscInt verbose;
20: } AppCtx;
22: static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
23: {
24: PetscFunctionBeginUser;
25: options->comm = comm;
26: options->num_labels = -1;
27: options->compare = PETSC_FALSE;
28: options->compare_labels = PETSC_FALSE;
29: options->compare_boundary = PETSC_FALSE;
30: options->compare_pre_post = PETSC_FALSE;
31: options->outfile[0] = '\0';
32: options->use_low_level_functions = PETSC_FALSE;
33: options->distribute_after_topo_load = PETSC_FALSE;
34: options->verbose = 0;
36: PetscOptionsBegin(comm, "", "Meshing Problem Options", "DMPLEX");
37: PetscCall(PetscOptionsInt("-num_labels", "Asserted number of labels in meshfile; don't count depth and celltype; -1 to deactivate", EX, options->num_labels, &options->num_labels, NULL));
38: PetscCall(PetscOptionsBool("-compare", "Compare the meshes using DMPlexEqual() and DMCompareLabels()", EX, options->compare, &options->compare, NULL));
39: PetscCall(PetscOptionsBool("-compare_labels", "Compare labels in the meshes using DMCompareLabels()", "ex55.c", options->compare_labels, &options->compare_labels, NULL));
40: PetscCall(PetscOptionsBool("-compare_boundary", "Check label I/O via boundary vertex coordinates", "ex55.c", options->compare_boundary, &options->compare_boundary, NULL));
41: PetscCall(PetscOptionsBool("-compare_pre_post", "Compare labels loaded before distribution with those loaded after distribution", "ex55.c", options->compare_pre_post, &options->compare_pre_post, NULL));
42: PetscCall(PetscOptionsString("-outfile", "Output mesh file", EX, options->outfile, options->outfile, sizeof(options->outfile), NULL));
43: PetscCall(PetscOptionsBool("-use_low_level_functions", "Use low level functions for viewing and loading", EX, options->use_low_level_functions, &options->use_low_level_functions, NULL));
44: PetscCall(PetscOptionsBool("-distribute_after_topo_load", "Distribute topology right after DMPlexTopologyLoad(), if use_low_level_functions=true", EX, options->distribute_after_topo_load, &options->distribute_after_topo_load, NULL));
45: PetscCall(PetscOptionsInt("-verbose", "Verbosity level", EX, options->verbose, &options->verbose, NULL));
46: PetscOptionsEnd();
47: PetscFunctionReturn(PETSC_SUCCESS);
48: }
50: static PetscErrorCode CreateMesh(AppCtx *options, DM *newdm)
51: {
52: DM dm;
54: PetscFunctionBeginUser;
55: PetscCall(DMCreate(options->comm, &dm));
56: PetscCall(DMSetType(dm, DMPLEX));
57: PetscCall(DMSetFromOptions(dm));
58: PetscCall(PetscObjectGetName((PetscObject)dm, &options->meshname));
59: PetscCall(DMViewFromOptions(dm, NULL, "-dm_view"));
60: *newdm = dm;
61: PetscFunctionReturn(PETSC_SUCCESS);
62: }
64: static PetscErrorCode SaveMesh(AppCtx *options, DM dm)
65: {
66: PetscViewer v;
68: PetscFunctionBeginUser;
69: PetscCall(PetscViewerHDF5Open(PetscObjectComm((PetscObject)dm), options->outfile, FILE_MODE_WRITE, &v));
70: if (options->use_low_level_functions) {
71: PetscCall(DMPlexTopologyView(dm, v));
72: PetscCall(DMPlexCoordinatesView(dm, v));
73: PetscCall(DMPlexLabelsView(dm, v));
74: } else {
75: PetscCall(DMView(dm, v));
76: }
77: PetscCall(PetscViewerDestroy(&v));
78: PetscFunctionReturn(PETSC_SUCCESS);
79: }
81: typedef enum {
82: NONE = 0,
83: PRE_DIST = 1,
84: POST_DIST = 2
85: } AuxObjLoadMode;
87: static PetscErrorCode LoadMeshLowLevel(AppCtx *options, PetscViewer v, PetscBool explicitDistribute, AuxObjLoadMode mode, DM *newdm)
88: {
89: DM dm;
90: PetscSF sfXC;
92: PetscFunctionBeginUser;
93: PetscCall(DMCreate(options->comm, &dm));
94: PetscCall(DMSetType(dm, DMPLEX));
95: PetscCall(PetscObjectSetName((PetscObject)dm, options->meshname));
96: PetscCall(DMPlexTopologyLoad(dm, v, &sfXC));
97: if (mode == PRE_DIST) {
98: PetscCall(DMPlexCoordinatesLoad(dm, v, sfXC));
99: PetscCall(DMPlexLabelsLoad(dm, v, sfXC));
100: }
101: if (explicitDistribute) {
102: DM dmdist;
103: PetscSF sfXB = sfXC, sfBC;
104: PetscPartitioner part;
106: PetscCall(DMPlexGetPartitioner(dm, &part));
107: PetscCall(PetscPartitionerSetFromOptions(part));
108: PetscCall(DMPlexDistribute(dm, 0, &sfBC, &dmdist));
109: if (dmdist) {
110: const char *name;
112: PetscCall(PetscObjectGetName((PetscObject)dm, &name));
113: PetscCall(PetscObjectSetName((PetscObject)dmdist, name));
114: PetscCall(PetscSFCompose(sfXB, sfBC, &sfXC));
115: PetscCall(PetscSFDestroy(&sfXB));
116: PetscCall(PetscSFDestroy(&sfBC));
117: PetscCall(DMDestroy(&dm));
118: dm = dmdist;
119: }
120: }
121: if (mode == POST_DIST) {
122: PetscCall(DMPlexLabelsLoad(dm, v, sfXC));
123: PetscCall(DMPlexCoordinatesLoad(dm, v, sfXC));
124: }
125: PetscCall(PetscSFDestroy(&sfXC));
126: *newdm = dm;
127: PetscFunctionReturn(PETSC_SUCCESS);
128: }
130: static PetscErrorCode LoadMesh(AppCtx *options, DM *dmnew)
131: {
132: DM dm;
133: PetscViewer v;
135: PetscFunctionBeginUser;
136: PetscCall(PetscViewerHDF5Open(options->comm, options->outfile, FILE_MODE_READ, &v));
137: if (options->use_low_level_functions) {
138: if (options->compare_pre_post) {
139: DM dm0;
141: PetscCall(LoadMeshLowLevel(options, v, PETSC_TRUE, PRE_DIST, &dm0));
142: PetscCall(LoadMeshLowLevel(options, v, PETSC_TRUE, POST_DIST, &dm));
143: PetscCall(DMCompareLabels(dm0, dm, NULL, NULL));
144: PetscCall(DMDestroy(&dm0));
145: } else {
146: PetscCall(LoadMeshLowLevel(options, v, options->distribute_after_topo_load, POST_DIST, &dm));
147: }
148: } else {
149: PetscCall(DMCreate(options->comm, &dm));
150: PetscCall(DMSetType(dm, DMPLEX));
151: PetscCall(PetscObjectSetName((PetscObject)dm, options->meshname));
152: PetscCall(DMLoad(dm, v));
153: }
154: PetscCall(PetscViewerDestroy(&v));
155: DMLabel celltypes;
156: PetscCall(DMPlexGetCellTypeLabel(dm, &celltypes));
158: PetscCall(DMSetOptionsPrefix(dm, "load_"));
159: PetscCall(DMSetFromOptions(dm));
160: PetscCall(DMViewFromOptions(dm, NULL, "-dm_view"));
161: *dmnew = dm;
162: PetscFunctionReturn(PETSC_SUCCESS);
163: }
165: static PetscErrorCode CompareMeshes(AppCtx *options, DM dm0, DM dm1)
166: {
167: PetscBool flg;
169: PetscFunctionBeginUser;
170: if (options->compare) {
171: PetscCall(DMPlexEqual(dm0, dm1, &flg));
172: PetscCheck(flg, options->comm, PETSC_ERR_ARG_INCOMP, "DMs are not equal");
173: PetscCall(PetscPrintf(options->comm, "DMs equal\n"));
174: }
175: if (options->compare_labels) {
176: PetscCall(DMCompareLabels(dm0, dm1, NULL, NULL));
177: PetscCall(PetscPrintf(options->comm, "DMLabels equal\n"));
178: }
179: PetscFunctionReturn(PETSC_SUCCESS);
180: }
182: static PetscErrorCode MarkBoundary(DM dm, const char name[], PetscInt value, PetscBool verticesOnly, DMLabel *label)
183: {
184: DMLabel l;
186: PetscFunctionBeginUser;
187: PetscCall(DMLabelCreate(PetscObjectComm((PetscObject)dm), name, &l));
188: PetscCall(DMAddLabel(dm, l));
189: PetscCall(DMPlexMarkBoundaryFaces(dm, value, l));
190: PetscCall(DMPlexLabelComplete(dm, l));
191: if (verticesOnly) {
192: IS points;
193: const PetscInt *idx;
194: PetscInt i, n = 0;
196: PetscCall(DMLabelGetStratumIS(l, value, &points));
197: if (points) {
198: PetscCall(ISGetLocalSize(points, &n));
199: PetscCall(ISGetIndices(points, &idx));
200: }
201: for (i = 0; i < n; i++) {
202: const PetscInt p = idx[i];
203: PetscInt d;
205: PetscCall(DMPlexGetPointDepth(dm, p, &d));
206: if (d != 0) PetscCall(DMLabelClearValue(l, p, value));
207: }
208: if (points) PetscCall(ISRestoreIndices(points, &idx));
209: PetscCall(ISDestroy(&points));
210: }
211: if (label) *label = l;
212: else PetscCall(DMLabelDestroy(&l));
213: PetscFunctionReturn(PETSC_SUCCESS);
214: }
216: static PetscErrorCode VertexCoordinatesToAll(DM dm, IS vertices, Vec *allCoords)
217: {
218: Vec coords, allCoords_;
219: VecScatter sc;
220: MPI_Comm comm;
222: PetscFunctionBeginUser;
223: PetscCall(PetscObjectGetComm((PetscObject)dm, &comm));
224: PetscCall(DMGetCoordinatesLocalSetUp(dm));
225: if (vertices) {
226: PetscCall(DMGetCoordinatesLocalTuple(dm, vertices, NULL, &coords));
227: } else {
228: PetscCall(VecCreateFromOptions(PETSC_COMM_SELF, NULL, 1, 0, 0, &coords));
229: }
230: {
231: PetscInt n;
232: Vec mpivec;
234: PetscCall(VecGetLocalSize(coords, &n));
235: PetscCall(VecCreateFromOptions(comm, NULL, 1, n, PETSC_DECIDE, &mpivec));
236: PetscCall(VecCopy(coords, mpivec));
237: PetscCall(VecDestroy(&coords));
238: coords = mpivec;
239: }
241: PetscCall(VecScatterCreateToAll(coords, &sc, &allCoords_));
242: PetscCall(VecScatterBegin(sc, coords, allCoords_, INSERT_VALUES, SCATTER_FORWARD));
243: PetscCall(VecScatterEnd(sc, coords, allCoords_, INSERT_VALUES, SCATTER_FORWARD));
244: PetscCall(VecScatterDestroy(&sc));
245: PetscCall(VecDestroy(&coords));
246: *allCoords = allCoords_;
247: PetscFunctionReturn(PETSC_SUCCESS);
248: }
250: static PetscErrorCode DMLabelGetCoordinateRepresentation(DM dm, DMLabel label, PetscInt value, Vec *allCoords)
251: {
252: IS vertices;
254: PetscFunctionBeginUser;
255: PetscCall(DMLabelGetStratumIS(label, value, &vertices));
256: PetscCall(VertexCoordinatesToAll(dm, vertices, allCoords));
257: PetscCall(ISDestroy(&vertices));
258: PetscFunctionReturn(PETSC_SUCCESS);
259: }
261: static PetscErrorCode DMLabelCompareWithCoordinateRepresentation(DM dm, DMLabel label, PetscInt value, Vec allCoords, PetscInt verbose)
262: {
263: const char *labelName;
264: IS pointsIS;
265: const PetscInt *points;
266: PetscInt n;
267: PetscBool fail = PETSC_FALSE;
268: MPI_Comm comm;
269: PetscMPIInt rank;
271: PetscFunctionBeginUser;
272: PetscCheck(label, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Label not loaded");
273: PetscCall(PetscObjectGetComm((PetscObject)dm, &comm));
274: PetscCall(PetscObjectGetName((PetscObject)label, &labelName));
275: PetscCallMPI(MPI_Comm_rank(comm, &rank));
276: {
277: PetscInt pStart, pEnd;
279: PetscCall(DMPlexGetChart(dm, &pStart, &pEnd));
280: PetscCall(DMLabelCreateIndex(label, pStart, pEnd));
281: }
282: PetscCall(DMPlexFindVertices(dm, allCoords, 0.0, &pointsIS));
283: PetscCall(ISGetIndices(pointsIS, &points));
284: PetscCall(ISGetLocalSize(pointsIS, &n));
285: if (verbose > 1) PetscCall(DMLabelView(label, PETSC_VIEWER_STDOUT_(comm)));
286: for (PetscInt i = 0; i < n; i++) {
287: const PetscInt p = points[i];
288: PetscBool has;
289: PetscInt v;
291: if (p < 0) continue;
292: PetscCall(DMLabelHasPoint(label, p, &has));
293: if (!has) {
294: if (verbose) PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] Label \"%s\" does not have point %" PetscInt_FMT "\n", rank, labelName, p));
295: fail = PETSC_TRUE;
296: continue;
297: }
298: PetscCall(DMLabelGetValue(label, p, &v));
299: if (v != value) {
300: if (verbose) PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "Point %" PetscInt_FMT " has bad value %" PetscInt_FMT " in label \"%s\"", p, v, labelName));
301: fail = PETSC_TRUE;
302: continue;
303: }
304: if (verbose > 1) PetscCall(PetscSynchronizedPrintf(comm, "[%d] OK point %" PetscInt_FMT "\n", rank, p));
305: }
306: PetscCall(PetscSynchronizedFlush(comm, PETSC_STDOUT));
307: PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR));
308: PetscCall(ISRestoreIndices(pointsIS, &points));
309: PetscCall(ISDestroy(&pointsIS));
310: PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, &fail, 1, MPI_C_BOOL, MPI_LOR, comm));
311: PetscCheck(!fail, comm, PETSC_ERR_PLIB, "Label \"%s\" was not loaded correctly%s", labelName, verbose ? " - see details above" : "");
312: PetscFunctionReturn(PETSC_SUCCESS);
313: }
315: static PetscErrorCode CheckNumLabels(DM dm, AppCtx *ctx)
316: {
317: PetscInt actualNum;
318: PetscBool fail = PETSC_FALSE;
319: MPI_Comm comm;
320: PetscMPIInt rank;
322: PetscFunctionBeginUser;
323: if (ctx->num_labels < 0) PetscFunctionReturn(PETSC_SUCCESS);
324: PetscCall(PetscObjectGetComm((PetscObject)dm, &comm));
325: PetscCallMPI(MPI_Comm_rank(comm, &rank));
326: PetscCall(DMGetNumLabels(dm, &actualNum));
327: if (ctx->num_labels != actualNum) {
328: fail = PETSC_TRUE;
329: if (ctx->verbose) {
330: PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] Asserted number of labels: %" PetscInt_FMT ", actual: %" PetscInt_FMT "\n", rank, ctx->num_labels, actualNum));
331: for (PetscInt i = 0; i < actualNum; i++) {
332: DMLabel label;
333: const char *name;
335: PetscCall(DMGetLabelByNum(dm, i, &label));
336: PetscCall(PetscObjectGetName((PetscObject)label, &name));
337: PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] Label %" PetscInt_FMT " \"%s\"\n", rank, i, name));
338: }
339: PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR));
340: }
341: }
342: PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, &fail, 1, MPI_C_BOOL, MPI_LOR, comm));
343: PetscCheck(!fail, comm, PETSC_ERR_PLIB, "Wrong number of labels%s", ctx->verbose ? " - see details above" : "");
344: PetscFunctionReturn(PETSC_SUCCESS);
345: }
347: static inline PetscErrorCode IncrementNumLabels(AppCtx *ctx)
348: {
349: PetscFunctionBeginUser;
350: if (ctx->num_labels >= 0) ctx->num_labels++;
351: PetscFunctionReturn(PETSC_SUCCESS);
352: }
354: int main(int argc, char **argv)
355: {
356: const char BOUNDARY_NAME[] = "Boundary";
357: const char BOUNDARY_VERTICES_NAME[] = "BoundaryVertices";
358: const PetscInt BOUNDARY_VALUE = 12345;
359: const PetscInt BOUNDARY_VERTICES_VALUE = 6789;
360: DM dm, dmnew;
361: AppCtx user;
362: Vec allCoords = NULL;
364: PetscFunctionBeginUser;
365: PetscCall(PetscInitialize(&argc, &argv, NULL, help));
366: PetscCall(ProcessOptions(PETSC_COMM_WORLD, &user));
367: PetscCall(CreateMesh(&user, &dm));
368: PetscCall(MarkBoundary(dm, BOUNDARY_NAME, BOUNDARY_VALUE, PETSC_FALSE, NULL));
369: PetscCall(IncrementNumLabels(&user));
370: if (user.compare_boundary) {
371: DMLabel label;
373: PetscCall(MarkBoundary(dm, BOUNDARY_VERTICES_NAME, BOUNDARY_VERTICES_VALUE, PETSC_TRUE, &label));
374: PetscCall(IncrementNumLabels(&user));
375: PetscCall(DMLabelGetCoordinateRepresentation(dm, label, BOUNDARY_VERTICES_VALUE, &allCoords));
376: PetscCall(DMLabelDestroy(&label));
377: }
378: PetscCall(SaveMesh(&user, dm));
380: PetscCall(LoadMesh(&user, &dmnew));
381: PetscCall(IncrementNumLabels(&user)); /* account for depth label */
382: PetscCall(IncrementNumLabels(&user)); /* account for celltype label */
383: PetscCall(CheckNumLabels(dm, &user));
384: PetscCall(CompareMeshes(&user, dm, dmnew));
385: if (user.compare_boundary) {
386: DMLabel label;
388: PetscCall(DMGetLabel(dmnew, BOUNDARY_VERTICES_NAME, &label));
389: PetscCall(DMLabelCompareWithCoordinateRepresentation(dmnew, label, BOUNDARY_VERTICES_VALUE, allCoords, user.verbose));
390: }
391: PetscCall(DMDestroy(&dm));
392: PetscCall(DMDestroy(&dmnew));
393: PetscCall(VecDestroy(&allCoords));
394: PetscCall(PetscFinalize());
395: return 0;
396: }
398: //TODO we can -compare once the new parallel topology format is in place
399: /*TEST
400: build:
401: requires: hdf5
403: # load old format, save in new format, reload, distribute
404: testset:
405: suffix: 1
406: requires: !complex datafilespath
407: args: -dm_plex_name plex
408: args: -dm_plex_check_all -dm_plex_view_hdf5_storage_version 2.0.0
409: args: -dm_plex_interpolate -petscpartitioner_type simple
410: args: -load_dm_plex_check_all
411: args: -use_low_level_functions {{0 1}} -compare_boundary
412: args: -num_labels 1
413: args: -outfile ex56_1.h5
414: nsize: {{1 3}}
415: output_file: output/empty.out
416: test:
417: suffix: a
418: args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/annulus-20.h5
419: test:
420: suffix: b
421: TODO: broken
422: args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/barycentricallyrefinedcube.h5
423: test:
424: suffix: c
425: args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/blockcylinder-50.h5
426: test:
427: suffix: d
428: args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/cube-hexahedra-refined.h5 -num_labels 0
429: test:
430: suffix: e
431: args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/hybrid_hexwedge.h5
432: test:
433: suffix: f
434: args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/square.h5
436: # load old format, save in new format, reload topology, distribute, load geometry and labels
437: testset:
438: suffix: 2
439: requires: !complex datafilespath
440: args: -dm_plex_name plex
441: args: -dm_plex_check_all -dm_plex_view_hdf5_storage_version 2.0.0
442: args: -dm_plex_interpolate -petscpartitioner_type simple
443: args: -load_dm_plex_check_all
444: args: -use_low_level_functions -load_dm_distribute 0 -distribute_after_topo_load -compare_boundary
445: args: -num_labels 1
446: args: -outfile ex56_2.h5
447: nsize: 3
448: output_file: output/empty.out
449: test:
450: suffix: a
451: args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/annulus-20.h5
452: test:
453: suffix: b
454: TODO: broken
455: args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/barycentricallyrefinedcube.h5
456: test:
457: suffix: c
458: args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/blockcylinder-50.h5
459: test:
460: suffix: d
461: args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/cube-hexahedra-refined.h5 -num_labels 0
462: test:
463: suffix: e
464: args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/hybrid_hexwedge.h5
465: test:
466: suffix: f
467: args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/square.h5
469: # load old format, save in new format, reload topology, distribute, load geometry and labels
470: testset:
471: suffix: 3
472: requires: !complex datafilespath
473: args: -dm_plex_name plex
474: args: -dm_plex_view_hdf5_storage_version 2.0.0
475: args: -dm_plex_interpolate -load_dm_distribute 0 -petscpartitioner_type simple
476: args: -use_low_level_functions -compare_pre_post
477: args: -num_labels 1
478: args: -outfile ex56_3.h5
479: nsize: 3
480: output_file: output/empty.out
481: test:
482: suffix: a
483: args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/annulus-20.h5
484: test:
485: suffix: b
486: TODO: broken
487: args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/barycentricallyrefinedcube.h5
488: test:
489: suffix: c
490: args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/blockcylinder-50.h5
491: test:
492: suffix: d
493: args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/cube-hexahedra-refined.h5 -num_labels 0
494: test:
495: suffix: e
496: args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/hybrid_hexwedge.h5
497: test:
498: suffix: f
499: args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/square.h5
500: TEST*/