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