Actual source code: ex9.c
1: static char help[] = "Performance tests for DMPlex query operations\n\n";
3: #include <petscdmplex.h>
5: typedef struct {
6: PetscInt dim; /* The topological mesh dimension */
7: PetscBool cellSimplex; /* Flag for simplices */
8: PetscBool spectral; /* Flag for spectral element layout */
9: PetscBool interpolate; /* Flag for mesh interpolation */
10: PetscReal refinementLimit; /* Maximum volume of a refined cell */
11: PetscInt numFields; /* The number of section fields */
12: PetscInt *numComponents; /* The number of field components */
13: PetscInt *numDof; /* The dof signature for the section */
14: PetscBool reuseArray; /* Pass in user allocated array to VecGetClosure() */
15: /* Test data */
16: PetscBool errors; /* Treat failures as errors */
17: PetscInt iterations; /* The number of iterations for a query */
18: PetscReal maxConeTime; /* Max time per run for DMPlexGetCone() */
19: PetscReal maxClosureTime; /* Max time per run for DMPlexGetTransitiveClosure() */
20: PetscReal maxVecClosureTime; /* Max time per run for DMPlexVecGetClosure() */
21: PetscBool printTimes; /* Print total times, do not check limits */
22: } AppCtx;
24: static PetscErrorCode ProcessOptions(AppCtx *options)
25: {
26: PetscInt len;
27: PetscBool flg;
29: options->dim = 2;
30: options->cellSimplex = PETSC_TRUE;
31: options->spectral = PETSC_FALSE;
32: options->interpolate = PETSC_FALSE;
33: options->refinementLimit = 0.0;
34: options->numFields = 0;
35: options->numComponents = NULL;
36: options->numDof = NULL;
37: options->reuseArray = PETSC_FALSE;
38: options->errors = PETSC_FALSE;
39: options->iterations = 1;
40: options->maxConeTime = 0.0;
41: options->maxClosureTime = 0.0;
42: options->maxVecClosureTime = 0.0;
43: options->printTimes = PETSC_FALSE;
45: PetscOptionsBegin(PETSC_COMM_SELF, "", "Meshing Problem Options", "DMPLEX");
46: PetscOptionsRangeInt("-dim", "The topological mesh dimension", "ex9.c", options->dim, &options->dim, NULL, 1, 3);
47: PetscOptionsBool("-cellSimplex", "Flag for simplices", "ex9.c", options->cellSimplex, &options->cellSimplex, NULL);
48: PetscOptionsBool("-spectral", "Flag for spectral element layout", "ex9.c", options->spectral, &options->spectral, NULL);
49: PetscOptionsBool("-interpolate", "Flag for mesh interpolation", "ex9.c", options->interpolate, &options->interpolate, NULL);
50: PetscOptionsReal("-refinement_limit", "The maximum volume of a refined cell", "ex9.c", options->refinementLimit, &options->refinementLimit, NULL);
51: PetscOptionsBoundedInt("-num_fields", "The number of section fields", "ex9.c", options->numFields, &options->numFields, NULL, 0);
52: if (options->numFields) {
53: len = options->numFields;
54: PetscMalloc1(len, &options->numComponents);
55: PetscOptionsIntArray("-num_components", "The number of components per field", "ex9.c", options->numComponents, &len, &flg);
57: }
58: len = (options->dim + 1) * PetscMax(1, options->numFields);
59: PetscMalloc1(len, &options->numDof);
60: PetscOptionsIntArray("-num_dof", "The dof signature for the section", "ex9.c", options->numDof, &len, &flg);
63: /* We are specifying the scalar dof, so augment it for multiple components */
64: {
65: PetscInt f, d;
67: for (f = 0; f < options->numFields; ++f) {
68: for (d = 0; d <= options->dim; ++d) options->numDof[f * (options->dim + 1) + d] *= options->numComponents[f];
69: }
70: }
72: PetscOptionsBool("-reuse_array", "Pass in user allocated array to VecGetClosure()", "ex9.c", options->reuseArray, &options->reuseArray, NULL);
73: PetscOptionsBool("-errors", "Treat failures as errors", "ex9.c", options->errors, &options->errors, NULL);
74: PetscOptionsBoundedInt("-iterations", "The number of iterations for a query", "ex9.c", options->iterations, &options->iterations, NULL, 0);
75: PetscOptionsReal("-max_cone_time", "The maximum time per run for DMPlexGetCone()", "ex9.c", options->maxConeTime, &options->maxConeTime, NULL);
76: PetscOptionsReal("-max_closure_time", "The maximum time per run for DMPlexGetTransitiveClosure()", "ex9.c", options->maxClosureTime, &options->maxClosureTime, NULL);
77: PetscOptionsReal("-max_vec_closure_time", "The maximum time per run for DMPlexVecGetClosure()", "ex9.c", options->maxVecClosureTime, &options->maxVecClosureTime, NULL);
78: PetscOptionsBool("-print_times", "Print total times, do not check limits", "ex9.c", options->printTimes, &options->printTimes, NULL);
79: PetscOptionsEnd();
80: return 0;
81: }
83: static PetscErrorCode CreateSimplex_2D(MPI_Comm comm, DM *newdm)
84: {
85: DM dm;
86: PetscInt numPoints[2] = {4, 2};
87: PetscInt coneSize[6] = {3, 3, 0, 0, 0, 0};
88: PetscInt cones[6] = {2, 3, 4, 5, 4, 3};
89: PetscInt coneOrientations[6] = {0, 0, 0, 0, 0, 0};
90: PetscScalar vertexCoords[8] = {-0.5, 0.5, 0.0, 0.0, 0.0, 1.0, 0.5, 0.5};
91: PetscInt markerPoints[8] = {2, 1, 3, 1, 4, 1, 5, 1};
92: PetscInt dim = 2, depth = 1, p;
94: DMCreate(comm, &dm);
95: PetscObjectSetName((PetscObject)dm, "triangular");
96: DMSetType(dm, DMPLEX);
97: DMSetDimension(dm, dim);
98: DMPlexCreateFromDAG(dm, depth, numPoints, coneSize, cones, coneOrientations, vertexCoords);
99: for (p = 0; p < 4; ++p) DMSetLabelValue(dm, "marker", markerPoints[p * 2], markerPoints[p * 2 + 1]);
100: *newdm = dm;
101: return 0;
102: }
104: static PetscErrorCode CreateSimplex_3D(MPI_Comm comm, DM *newdm)
105: {
106: DM dm;
107: PetscInt numPoints[2] = {5, 2};
108: PetscInt coneSize[23] = {4, 4, 0, 0, 0, 0, 0};
109: PetscInt cones[8] = {2, 4, 3, 5, 3, 4, 6, 5};
110: PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0};
111: PetscScalar vertexCoords[15] = {0.0, 0.0, -0.5, 0.0, -0.5, 0.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5};
112: PetscInt markerPoints[10] = {2, 1, 3, 1, 4, 1, 5, 1, 6, 1};
113: PetscInt dim = 3, depth = 1, p;
115: DMCreate(comm, &dm);
116: PetscObjectSetName((PetscObject)dm, "tetrahedral");
117: DMSetType(dm, DMPLEX);
118: DMSetDimension(dm, dim);
119: DMPlexCreateFromDAG(dm, depth, numPoints, coneSize, cones, coneOrientations, vertexCoords);
120: for (p = 0; p < 5; ++p) DMSetLabelValue(dm, "marker", markerPoints[p * 2], markerPoints[p * 2 + 1]);
121: *newdm = dm;
122: return 0;
123: }
125: static PetscErrorCode CreateQuad_2D(MPI_Comm comm, DM *newdm)
126: {
127: DM dm;
128: PetscInt numPoints[2] = {6, 2};
129: PetscInt coneSize[8] = {4, 4, 0, 0, 0, 0, 0, 0};
130: PetscInt cones[8] = {2, 3, 4, 5, 3, 6, 7, 4};
131: PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0};
132: PetscScalar vertexCoords[12] = {-0.5, 0.0, 0.0, 0.0, 0.0, 1.0, -0.5, 1.0, 0.5, 0.0, 0.5, 1.0};
133: PetscInt markerPoints[12] = {2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1};
134: PetscInt dim = 2, depth = 1, p;
136: DMCreate(comm, &dm);
137: PetscObjectSetName((PetscObject)dm, "quadrilateral");
138: DMSetType(dm, DMPLEX);
139: DMSetDimension(dm, dim);
140: DMPlexCreateFromDAG(dm, depth, numPoints, coneSize, cones, coneOrientations, vertexCoords);
141: for (p = 0; p < 6; ++p) DMSetLabelValue(dm, "marker", markerPoints[p * 2], markerPoints[p * 2 + 1]);
142: *newdm = dm;
143: return 0;
144: }
146: static PetscErrorCode CreateHex_3D(MPI_Comm comm, DM *newdm)
147: {
148: DM dm;
149: PetscInt numPoints[2] = {12, 2};
150: PetscInt coneSize[14] = {8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
151: PetscInt cones[16] = {2, 5, 4, 3, 6, 7, 8, 9, 3, 4, 11, 10, 7, 12, 13, 8};
152: PetscInt coneOrientations[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
153: PetscScalar vertexCoords[36] = {-0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -0.5, 1.0, 0.0, -0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, -0.5, 1.0, 1.0, 0.5, 0.0, 0.0, 0.5, 1.0, 0.0, 0.5, 0.0, 1.0, 0.5, 1.0, 1.0};
154: PetscInt markerPoints[24] = {2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 9, 1, 10, 1, 11, 1, 12, 1, 13, 1};
155: PetscInt dim = 3, depth = 1, p;
157: DMCreate(comm, &dm);
158: PetscObjectSetName((PetscObject)dm, "hexahedral");
159: DMSetType(dm, DMPLEX);
160: DMSetDimension(dm, dim);
161: DMPlexCreateFromDAG(dm, depth, numPoints, coneSize, cones, coneOrientations, vertexCoords);
162: for (p = 0; p < 12; ++p) DMSetLabelValue(dm, "marker", markerPoints[p * 2], markerPoints[p * 2 + 1]);
163: *newdm = dm;
164: return 0;
165: }
167: static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *newdm)
168: {
169: PetscInt dim = user->dim;
170: PetscBool cellSimplex = user->cellSimplex;
172: switch (dim) {
173: case 2:
174: if (cellSimplex) {
175: CreateSimplex_2D(comm, newdm);
176: } else {
177: CreateQuad_2D(comm, newdm);
178: }
179: break;
180: case 3:
181: if (cellSimplex) {
182: CreateSimplex_3D(comm, newdm);
183: } else {
184: CreateHex_3D(comm, newdm);
185: }
186: break;
187: default:
188: SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot make meshes for dimension %" PetscInt_FMT, dim);
189: }
190: if (user->refinementLimit > 0.0) {
191: DM rdm;
192: const char *name;
194: DMPlexSetRefinementUniform(*newdm, PETSC_FALSE);
195: DMPlexSetRefinementLimit(*newdm, user->refinementLimit);
196: DMRefine(*newdm, PETSC_COMM_SELF, &rdm);
197: PetscObjectGetName((PetscObject)*newdm, &name);
198: PetscObjectSetName((PetscObject)rdm, name);
199: DMDestroy(newdm);
200: *newdm = rdm;
201: }
202: if (user->interpolate) {
203: DM idm;
205: DMPlexInterpolate(*newdm, &idm);
206: DMDestroy(newdm);
207: *newdm = idm;
208: }
209: DMSetFromOptions(*newdm);
210: return 0;
211: }
213: static PetscErrorCode TestCone(DM dm, AppCtx *user)
214: {
215: PetscInt numRuns, cStart, cEnd, c, i;
216: PetscReal maxTimePerRun = user->maxConeTime;
217: PetscLogStage stage;
218: PetscLogEvent event;
219: PetscEventPerfInfo eventInfo;
220: MPI_Comm comm;
221: PetscMPIInt rank;
223: PetscObjectGetComm((PetscObject)dm, &comm);
224: MPI_Comm_rank(comm, &rank);
225: PetscLogStageRegister("DMPlex Cone Test", &stage);
226: PetscLogEventRegister("Cone", PETSC_OBJECT_CLASSID, &event);
227: PetscLogStagePush(stage);
228: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
229: PetscLogEventBegin(event, 0, 0, 0, 0);
230: for (i = 0; i < user->iterations; ++i) {
231: for (c = cStart; c < cEnd; ++c) {
232: const PetscInt *cone;
234: DMPlexGetCone(dm, c, &cone);
235: }
236: }
237: PetscLogEventEnd(event, 0, 0, 0, 0);
238: PetscLogStagePop();
240: PetscLogEventGetPerfInfo(stage, event, &eventInfo);
241: numRuns = (cEnd - cStart) * user->iterations;
244: if (user->printTimes) {
245: PetscSynchronizedPrintf(comm, "[%d] Cones: %" PetscInt_FMT " Total time: %.3es Average time per cone: %.3es\n", rank, numRuns, eventInfo.time, eventInfo.time / numRuns);
246: PetscSynchronizedFlush(comm, PETSC_STDOUT);
247: } else if (eventInfo.time > maxTimePerRun * numRuns) {
248: PetscSynchronizedPrintf(comm, "[%d] Cones: %" PetscInt_FMT " Average time per cone: %gs standard: %gs\n", rank, numRuns, (double)(eventInfo.time / numRuns), (double)maxTimePerRun);
249: PetscSynchronizedFlush(comm, PETSC_STDOUT);
251: }
252: return 0;
253: }
255: static PetscErrorCode TestTransitiveClosure(DM dm, AppCtx *user)
256: {
257: PetscInt numRuns, cStart, cEnd, c, i;
258: PetscReal maxTimePerRun = user->maxClosureTime;
259: PetscLogStage stage;
260: PetscLogEvent event;
261: PetscEventPerfInfo eventInfo;
262: MPI_Comm comm;
263: PetscMPIInt rank;
265: PetscObjectGetComm((PetscObject)dm, &comm);
266: MPI_Comm_rank(comm, &rank);
267: PetscLogStageRegister("DMPlex Transitive Closure Test", &stage);
268: PetscLogEventRegister("TransitiveClosure", PETSC_OBJECT_CLASSID, &event);
269: PetscLogStagePush(stage);
270: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
271: PetscLogEventBegin(event, 0, 0, 0, 0);
272: for (i = 0; i < user->iterations; ++i) {
273: for (c = cStart; c < cEnd; ++c) {
274: PetscInt *closure = NULL;
275: PetscInt closureSize;
277: DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);
278: DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);
279: }
280: }
281: PetscLogEventEnd(event, 0, 0, 0, 0);
282: PetscLogStagePop();
284: PetscLogEventGetPerfInfo(stage, event, &eventInfo);
285: numRuns = (cEnd - cStart) * user->iterations;
288: if (user->printTimes) {
289: PetscSynchronizedPrintf(comm, "[%d] Closures: %" PetscInt_FMT " Total time: %.3es Average time per cone: %.3es\n", rank, numRuns, eventInfo.time, eventInfo.time / numRuns);
290: PetscSynchronizedFlush(comm, PETSC_STDOUT);
291: } else if (eventInfo.time > maxTimePerRun * numRuns) {
292: PetscSynchronizedPrintf(comm, "[%d] Closures: %" PetscInt_FMT " Average time per cone: %gs standard: %gs\n", rank, numRuns, (double)(eventInfo.time / numRuns), (double)maxTimePerRun);
293: PetscSynchronizedFlush(comm, PETSC_STDOUT);
295: }
296: return 0;
297: }
299: static PetscErrorCode TestVecClosure(DM dm, PetscBool useIndex, PetscBool useSpectral, AppCtx *user)
300: {
301: PetscSection s;
302: Vec v;
303: PetscInt numRuns, cStart, cEnd, c, i;
304: PetscScalar tmpArray[64];
305: PetscScalar *userArray = user->reuseArray ? tmpArray : NULL;
306: PetscReal maxTimePerRun = user->maxVecClosureTime;
307: PetscLogStage stage;
308: PetscLogEvent event;
309: PetscEventPerfInfo eventInfo;
310: MPI_Comm comm;
311: PetscMPIInt rank;
313: PetscObjectGetComm((PetscObject)dm, &comm);
314: MPI_Comm_rank(comm, &rank);
315: if (useIndex) {
316: if (useSpectral) {
317: PetscLogStageRegister("DMPlex Vector Closure with Index Test", &stage);
318: PetscLogEventRegister("VecClosureInd", PETSC_OBJECT_CLASSID, &event);
319: } else {
320: PetscLogStageRegister("DMPlex Vector Spectral Closure with Index Test", &stage);
321: PetscLogEventRegister("VecClosureSpecInd", PETSC_OBJECT_CLASSID, &event);
322: }
323: } else {
324: if (useSpectral) {
325: PetscLogStageRegister("DMPlex Vector Spectral Closure Test", &stage);
326: PetscLogEventRegister("VecClosureSpec", PETSC_OBJECT_CLASSID, &event);
327: } else {
328: PetscLogStageRegister("DMPlex Vector Closure Test", &stage);
329: PetscLogEventRegister("VecClosure", PETSC_OBJECT_CLASSID, &event);
330: }
331: }
332: PetscLogStagePush(stage);
333: DMSetNumFields(dm, user->numFields);
334: DMPlexCreateSection(dm, NULL, user->numComponents, user->numDof, 0, NULL, NULL, NULL, NULL, &s);
335: DMSetLocalSection(dm, s);
336: if (useIndex) DMPlexCreateClosureIndex(dm, s);
337: if (useSpectral) DMPlexSetClosurePermutationTensor(dm, PETSC_DETERMINE, s);
338: PetscSectionDestroy(&s);
339: DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);
340: DMGetLocalVector(dm, &v);
341: PetscLogEventBegin(event, 0, 0, 0, 0);
342: for (i = 0; i < user->iterations; ++i) {
343: for (c = cStart; c < cEnd; ++c) {
344: PetscScalar *closure = userArray;
345: PetscInt closureSize = 64;
347: DMPlexVecGetClosure(dm, s, v, c, &closureSize, &closure);
348: if (!user->reuseArray) DMPlexVecRestoreClosure(dm, s, v, c, &closureSize, &closure);
349: }
350: }
351: PetscLogEventEnd(event, 0, 0, 0, 0);
352: DMRestoreLocalVector(dm, &v);
353: PetscLogStagePop();
355: PetscLogEventGetPerfInfo(stage, event, &eventInfo);
356: numRuns = (cEnd - cStart) * user->iterations;
359: if (user->printTimes || eventInfo.time > maxTimePerRun * numRuns) {
360: const char *title = "VecClosures";
361: const char *titleIndex = "VecClosures with Index";
362: const char *titleSpec = "VecClosures Spectral";
363: const char *titleSpecIndex = "VecClosures Spectral with Index";
365: if (user->printTimes) {
366: PetscCall(PetscSynchronizedPrintf(comm, "[%d] %s: %" PetscInt_FMT " Total time: %.3es Average time per vector closure: %.3es\n", rank, useIndex ? (useSpectral ? titleSpecIndex : titleIndex) : (useSpectral ? titleSpec : title), numRuns,
367: eventInfo.time, eventInfo.time / numRuns));
368: PetscSynchronizedFlush(comm, PETSC_STDOUT);
369: } else {
370: PetscCall(
371: PetscSynchronizedPrintf(comm, "[%d] %s: %" PetscInt_FMT " Average time per vector closure: %gs standard: %gs\n", rank, useIndex ? (useSpectral ? titleSpecIndex : titleIndex) : (useSpectral ? titleSpec : title), numRuns, (double)(eventInfo.time / numRuns), (double)maxTimePerRun));
372: PetscSynchronizedFlush(comm, PETSC_STDOUT);
374: }
375: }
376: return 0;
377: }
379: static PetscErrorCode CleanupContext(AppCtx *user)
380: {
381: PetscFree(user->numComponents);
382: PetscFree(user->numDof);
383: return 0;
384: }
386: int main(int argc, char **argv)
387: {
388: DM dm;
389: AppCtx user;
392: PetscInitialize(&argc, &argv, NULL, help);
393: ProcessOptions(&user);
394: PetscLogDefaultBegin();
395: CreateMesh(PETSC_COMM_WORLD, &user, &dm);
396: TestCone(dm, &user);
397: TestTransitiveClosure(dm, &user);
398: TestVecClosure(dm, PETSC_FALSE, PETSC_FALSE, &user);
399: TestVecClosure(dm, PETSC_TRUE, PETSC_FALSE, &user);
400: if (!user.cellSimplex && user.spectral) {
401: TestVecClosure(dm, PETSC_FALSE, PETSC_TRUE, &user);
402: TestVecClosure(dm, PETSC_TRUE, PETSC_TRUE, &user);
403: }
404: DMDestroy(&dm);
405: CleanupContext(&user);
406: PetscFinalize();
407: return 0;
408: }
410: /*TEST
412: build:
413: requires: defined(PETSC_USE_LOG)
415: # 2D Simplex P_1 scalar tests
416: testset:
417: args: -num_dof 1,0,0 -iterations 2 -print_times
418: test:
419: suffix: correctness_0
420: test:
421: suffix: correctness_1
422: args: -interpolate -dm_refine 2
423: test:
424: suffix: correctness_2
425: requires: triangle
426: args: -interpolate -refinement_limit 1.0e-5
427: test:
428: suffix: 0
429: TODO: Only for performance testing
430: args: -num_dof 1,0,0 -iterations 10000 -max_cone_time 1.1e-8 -max_closure_time 1.3e-7 -max_vec_closure_time 3.6e-7
431: test:
432: suffix: 1
433: requires: triangle
434: TODO: Only for performance testing
435: args: -refinement_limit 1.0e-5 -num_dof 1,0,0 -iterations 2 -max_cone_time 2.1e-8 -max_closure_time 1.5e-7 -max_vec_closure_time 3.6e-7
436: test:
437: suffix: 2
438: TODO: Only for performance testing
439: args: -num_fields 1 -num_components 1 -num_dof 1,0,0 -iterations 10000 -max_cone_time 1.1e-8 -max_closure_time 1.3e-7 -max_vec_closure_time 4.5e-7
440: test:
441: suffix: 3
442: requires: triangle
443: TODO: Only for performance testing
444: args: -refinement_limit 1.0e-5 -num_fields 1 -num_components 1 -num_dof 1,0,0 -iterations 2 -max_cone_time 2.1e-8 -max_closure_time 1.5e-7 -max_vec_closure_time 4.7e-7
445: test:
446: suffix: 4
447: TODO: Only for performance testing
448: args: -interpolate -num_dof 1,0,0 -iterations 10000 -max_cone_time 1.1e-8 -max_closure_time 6.5e-7 -max_vec_closure_time 1.0e-6
449: test:
450: suffix: 5
451: requires: triangle
452: TODO: Only for performance testing
453: args: -interpolate -refinement_limit 1.0e-4 -num_dof 1,0,0 -iterations 2 -max_cone_time 2.1e-8 -max_closure_time 6.5e-7 -max_vec_closure_time 1.0e-6
454: test:
455: suffix: 6
456: TODO: Only for performance testing
457: args: -interpolate -num_fields 1 -num_components 1 -num_dof 1,0,0 -iterations 10000 -max_cone_time 1.1e-8 -max_closure_time 6.5e-7 -max_vec_closure_time 1.1e-6
458: test:
459: suffix: 7
460: requires: triangle
461: TODO: Only for performance testing
462: args: -interpolate -refinement_limit 1.0e-4 -num_fields 1 -num_components 1 -num_dof 1,0,0 -iterations 2 -max_cone_time 2.1e-8 -max_closure_time 6.5e-7 -max_vec_closure_time 1.2e-6
464: # 2D Simplex P_1 vector tests
465: # 2D Simplex P_2 scalar tests
466: # 2D Simplex P_2 vector tests
467: # 2D Simplex P_2/P_1 vector/scalar tests
468: # 2D Quad P_1 scalar tests
469: # 2D Quad P_1 vector tests
470: # 2D Quad P_2 scalar tests
471: # 2D Quad P_2 vector tests
472: # 3D Simplex P_1 scalar tests
473: # 3D Simplex P_1 vector tests
474: # 3D Simplex P_2 scalar tests
475: # 3D Simplex P_2 vector tests
476: # 3D Hex P_1 scalar tests
477: # 3D Hex P_1 vector tests
478: # 3D Hex P_2 scalar tests
479: # 3D Hex P_2 vector tests
481: TEST*/