Actual source code: ex1.c
1: #include <petscfe.h>
2: #include <petscdmplex.h>
3: #include <petsc/private/hashmap.h>
4: #include <petsc/private/dmpleximpl.h>
5: #include <petsc/private/petscfeimpl.h>
7: const char help[] = "Test PETSCDUALSPACELAGRANGE\n";
9: typedef struct _PetscHashLagKey {
10: PetscInt dim;
11: PetscInt order;
12: PetscInt formDegree;
13: PetscBool trimmed;
14: PetscInt tensor;
15: PetscBool continuous;
16: } PetscHashLagKey;
18: #define PetscHashLagKeyHash(key) \
19: PetscHashCombine(PetscHashCombine(PetscHashCombine(PetscHashInt((key).dim), PetscHashInt((key).order)), PetscHashInt((key).formDegree)), PetscHashCombine(PetscHashCombine(PetscHashInt((key).trimmed), PetscHashInt((key).tensor)), PetscHashInt((key).continuous)))
21: #define PetscHashLagKeyEqual(k1, k2) \
22: (((k1).dim == (k2).dim) ? ((k1).order == (k2).order) ? ((k1).formDegree == (k2).formDegree) ? ((k1).trimmed == (k2).trimmed) ? ((k1).tensor == (k2).tensor) ? ((k1).continuous == (k2).continuous) : 0 : 0 : 0 : 0 : 0)
24: PETSC_HASH_MAP(HashLag, PetscHashLagKey, PetscInt, PetscHashLagKeyHash, PetscHashLagKeyEqual, 0)
26: static PetscErrorCode ExpectedNumDofs_Total(PetscInt dim, PetscInt order, PetscInt formDegree, PetscBool trimmed, PetscInt tensor, PetscInt nCopies, PetscInt *nDofs);
27: static PetscErrorCode ExpectedNumDofs_Interior(PetscInt dim, PetscInt order, PetscInt formDegree, PetscBool trimmed, PetscInt tensor, PetscInt nCopies, PetscInt *nDofs);
29: static PetscErrorCode ExpectedNumDofs_Total(PetscInt dim, PetscInt order, PetscInt formDegree, PetscBool trimmed, PetscInt tensor, PetscInt nCopies, PetscInt *nDofs)
30: {
31: PetscFunctionBegin;
32: formDegree = PetscAbsInt(formDegree);
33: /* see femtable.org for the source of most of these values */
34: *nDofs = -1;
35: if (tensor == 0) { /* simplex spaces */
36: if (trimmed) {
37: PetscInt rnchooserk;
38: PetscInt rkm1choosek;
40: PetscCall(PetscDTBinomialInt(order + dim, order + formDegree, &rnchooserk));
41: PetscCall(PetscDTBinomialInt(order + formDegree - 1, formDegree, &rkm1choosek));
42: *nDofs = rnchooserk * rkm1choosek * nCopies;
43: } else {
44: PetscInt rnchooserk;
45: PetscInt rkchoosek;
47: PetscCall(PetscDTBinomialInt(order + dim, order + formDegree, &rnchooserk));
48: PetscCall(PetscDTBinomialInt(order + formDegree, formDegree, &rkchoosek));
49: *nDofs = rnchooserk * rkchoosek * nCopies;
50: }
51: } else if (tensor == 1) { /* hypercubes */
52: if (trimmed) {
53: PetscInt nchoosek;
54: PetscInt rpowk, rp1pownmk;
56: PetscCall(PetscDTBinomialInt(dim, formDegree, &nchoosek));
57: rpowk = PetscPowInt(order, formDegree);
58: rp1pownmk = PetscPowInt(order + 1, dim - formDegree);
59: *nDofs = nchoosek * rpowk * rp1pownmk * nCopies;
60: } else {
61: PetscInt nchoosek;
62: PetscInt rp1pown;
64: PetscCall(PetscDTBinomialInt(dim, formDegree, &nchoosek));
65: rp1pown = PetscPowInt(order + 1, dim);
66: *nDofs = nchoosek * rp1pown * nCopies;
67: }
68: } else { /* prism */
69: PetscInt tracek = 0;
70: PetscInt tracekm1 = 0;
71: PetscInt fiber0 = 0;
72: PetscInt fiber1 = 0;
74: if (formDegree < dim) {
75: PetscCall(ExpectedNumDofs_Total(dim - 1, order, formDegree, trimmed, 0, 1, &tracek));
76: PetscCall(ExpectedNumDofs_Total(1, order, 0, trimmed, 0, 1, &fiber0));
77: }
78: if (formDegree > 0) {
79: PetscCall(ExpectedNumDofs_Total(dim - 1, order, formDegree - 1, trimmed, 0, 1, &tracekm1));
80: PetscCall(ExpectedNumDofs_Total(1, order, 1, trimmed, 0, 1, &fiber1));
81: }
82: *nDofs = (tracek * fiber0 + tracekm1 * fiber1) * nCopies;
83: }
84: PetscFunctionReturn(PETSC_SUCCESS);
85: }
87: static PetscErrorCode ExpectedNumDofs_Interior(PetscInt dim, PetscInt order, PetscInt formDegree, PetscBool trimmed, PetscInt tensor, PetscInt nCopies, PetscInt *nDofs)
88: {
89: PetscFunctionBegin;
90: formDegree = PetscAbsInt(formDegree);
91: /* see femtable.org for the source of most of these values */
92: *nDofs = -1;
93: if (tensor == 0) { /* simplex spaces */
94: if (trimmed) {
95: if (order + formDegree > dim) {
96: PetscInt eorder = order + formDegree - dim - 1;
97: PetscInt eformDegree = dim - formDegree;
98: PetscInt rnchooserk;
99: PetscInt rkchoosek;
101: PetscCall(PetscDTBinomialInt(eorder + dim, eorder + eformDegree, &rnchooserk));
102: PetscCall(PetscDTBinomialInt(eorder + eformDegree, eformDegree, &rkchoosek));
103: *nDofs = rnchooserk * rkchoosek * nCopies;
104: } else {
105: *nDofs = 0;
106: }
108: } else {
109: if (order + formDegree > dim) {
110: PetscInt eorder = order + formDegree - dim;
111: PetscInt eformDegree = dim - formDegree;
112: PetscInt rnchooserk;
113: PetscInt rkm1choosek;
115: PetscCall(PetscDTBinomialInt(eorder + dim, eorder + eformDegree, &rnchooserk));
116: PetscCall(PetscDTBinomialInt(eorder + eformDegree - 1, eformDegree, &rkm1choosek));
117: *nDofs = rnchooserk * rkm1choosek * nCopies;
118: } else {
119: *nDofs = 0;
120: }
121: }
122: } else if (tensor == 1) { /* hypercubes */
123: if (dim < 2) {
124: PetscCall(ExpectedNumDofs_Interior(dim, order, formDegree, trimmed, 0, nCopies, nDofs));
125: } else {
126: PetscInt tracek = 0;
127: PetscInt tracekm1 = 0;
128: PetscInt fiber0 = 0;
129: PetscInt fiber1 = 0;
131: if (formDegree < dim) {
132: PetscCall(ExpectedNumDofs_Interior(dim - 1, order, formDegree, trimmed, dim > 2 ? 1 : 0, 1, &tracek));
133: PetscCall(ExpectedNumDofs_Interior(1, order, 0, trimmed, 0, 1, &fiber0));
134: }
135: if (formDegree > 0) {
136: PetscCall(ExpectedNumDofs_Interior(dim - 1, order, formDegree - 1, trimmed, dim > 2 ? 1 : 0, 1, &tracekm1));
137: PetscCall(ExpectedNumDofs_Interior(1, order, 1, trimmed, 0, 1, &fiber1));
138: }
139: *nDofs = (tracek * fiber0 + tracekm1 * fiber1) * nCopies;
140: }
141: } else { /* prism */
142: PetscInt tracek = 0;
143: PetscInt tracekm1 = 0;
144: PetscInt fiber0 = 0;
145: PetscInt fiber1 = 0;
147: if (formDegree < dim) {
148: PetscCall(ExpectedNumDofs_Interior(dim - 1, order, formDegree, trimmed, 0, 1, &tracek));
149: PetscCall(ExpectedNumDofs_Interior(1, order, 0, trimmed, 0, 1, &fiber0));
150: }
151: if (formDegree > 0) {
152: PetscCall(ExpectedNumDofs_Interior(dim - 1, order, formDegree - 1, trimmed, 0, 1, &tracekm1));
153: PetscCall(ExpectedNumDofs_Interior(1, order, 1, trimmed, 0, 1, &fiber1));
154: }
155: *nDofs = (tracek * fiber0 + tracekm1 * fiber1) * nCopies;
156: }
157: PetscFunctionReturn(PETSC_SUCCESS);
158: }
160: PetscErrorCode testLagrange(PetscHashLag lagTable, DM K, PetscInt dim, PetscInt order, PetscInt formDegree, PetscBool trimmed, PetscInt tensor, PetscBool continuous, PetscInt nCopies)
161: {
162: PetscDualSpace sp;
163: MPI_Comm comm = PETSC_COMM_SELF;
164: PetscInt Nk;
165: PetscHashLagKey key;
166: PetscHashIter iter;
167: PetscBool missing;
168: PetscInt spdim, spintdim, exspdim, exspintdim;
170: PetscFunctionBegin;
171: PetscCall(PetscDTBinomialInt(dim, PetscAbsInt(formDegree), &Nk));
172: PetscCall(PetscDualSpaceCreate(comm, &sp));
173: PetscCall(PetscDualSpaceSetType(sp, PETSCDUALSPACELAGRANGE));
174: PetscCall(PetscDualSpaceSetDM(sp, K));
175: PetscCall(PetscDualSpaceSetOrder(sp, order));
176: PetscCall(PetscDualSpaceSetFormDegree(sp, formDegree));
177: PetscCall(PetscDualSpaceSetNumComponents(sp, nCopies * Nk));
178: PetscCall(PetscDualSpaceLagrangeSetContinuity(sp, continuous));
179: PetscCall(PetscDualSpaceLagrangeSetTensor(sp, (PetscBool)tensor));
180: PetscCall(PetscDualSpaceLagrangeSetTrimmed(sp, trimmed));
181: PetscCall(PetscInfo(NULL, "Input: dim %" PetscInt_FMT ", order %" PetscInt_FMT ", trimmed %" PetscInt_FMT ", tensor %" PetscInt_FMT ", continuous %" PetscInt_FMT ", formDegree %" PetscInt_FMT ", nCopies %" PetscInt_FMT "\n", dim, order, (PetscInt)trimmed, tensor, (PetscInt)continuous, formDegree, nCopies));
182: PetscCall(ExpectedNumDofs_Total(dim, order, formDegree, trimmed, tensor, nCopies, &exspdim));
183: if (continuous && dim > 0 && order > 0) {
184: PetscCall(ExpectedNumDofs_Interior(dim, order, formDegree, trimmed, tensor, nCopies, &exspintdim));
185: } else {
186: exspintdim = exspdim;
187: }
188: PetscCall(PetscDualSpaceSetUp(sp));
189: PetscCall(PetscDualSpaceGetDimension(sp, &spdim));
190: PetscCall(PetscDualSpaceGetInteriorDimension(sp, &spintdim));
191: PetscCheck(spdim == exspdim, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Expected dual space dimension %" PetscInt_FMT ", got %" PetscInt_FMT, exspdim, spdim);
192: PetscCheck(spintdim == exspintdim, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Expected dual space interior dimension %" PetscInt_FMT ", got %" PetscInt_FMT, exspintdim, spintdim);
193: key.dim = dim;
194: key.formDegree = formDegree;
195: PetscCall(PetscDualSpaceGetOrder(sp, &key.order));
196: PetscCall(PetscDualSpaceLagrangeGetContinuity(sp, &key.continuous));
197: if (tensor == 2) {
198: key.tensor = 2;
199: } else {
200: PetscBool bTensor;
202: PetscCall(PetscDualSpaceLagrangeGetTensor(sp, &bTensor));
203: key.tensor = bTensor;
204: }
205: PetscCall(PetscDualSpaceLagrangeGetTrimmed(sp, &key.trimmed));
206: PetscCall(PetscInfo(NULL, "After setup: order %" PetscInt_FMT ", trimmed %" PetscInt_FMT ", tensor %" PetscInt_FMT ", continuous %" PetscInt_FMT "\n", key.order, (PetscInt)key.trimmed, key.tensor, (PetscInt)key.continuous));
207: PetscCall(PetscHashLagPut(lagTable, key, &iter, &missing));
208: if (missing) {
209: DMPolytopeType type;
211: PetscCall(DMPlexGetCellType(K, 0, &type));
212: PetscCall(PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_SELF, "New space: %s, order %" PetscInt_FMT ", trimmed %" PetscInt_FMT ", tensor %" PetscInt_FMT ", continuous %" PetscInt_FMT ", form degree %" PetscInt_FMT "\n", DMPolytopeTypes[type], order, (PetscInt)trimmed, tensor, (PetscInt)continuous, formDegree));
213: PetscCall(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_SELF));
214: {
215: PetscQuadrature intNodes, allNodes;
216: Mat intMat, allMat;
217: MatInfo info;
218: PetscInt i, j, nodeIdxDim, nodeVecDim, nNodes;
219: const PetscInt *nodeIdx;
220: const PetscReal *nodeVec;
222: PetscDualSpace_Lag *lag = (PetscDualSpace_Lag *)sp->data;
224: PetscCall(PetscLagNodeIndicesGetData_Internal(lag->allNodeIndices, &nodeIdxDim, &nodeVecDim, &nNodes, &nodeIdx, &nodeVec));
225: PetscCheck(nodeVecDim == Nk, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Incorrect nodeVecDim");
226: PetscCheck(nNodes == spdim, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Incorrect nNodes");
228: PetscCall(PetscDualSpaceGetAllData(sp, &allNodes, &allMat));
230: PetscCall(PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_SELF, "All nodes:\n"));
231: PetscCall(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_SELF));
232: PetscCall(PetscQuadratureView(allNodes, PETSC_VIEWER_STDOUT_SELF));
233: PetscCall(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_SELF));
234: PetscCall(PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_SELF, "All node indices:\n"));
235: for (i = 0; i < spdim; i++) {
236: PetscCall(PetscPrintf(PETSC_COMM_SELF, "("));
237: for (j = 0; j < nodeIdxDim; j++) PetscCall(PetscPrintf(PETSC_COMM_SELF, " %" PetscInt_FMT ",", nodeIdx[i * nodeIdxDim + j]));
238: PetscCall(PetscPrintf(PETSC_COMM_SELF, "): ["));
239: for (j = 0; j < nodeVecDim; j++) PetscCall(PetscPrintf(PETSC_COMM_SELF, " %g,", (double)nodeVec[i * nodeVecDim + j]));
240: PetscCall(PetscPrintf(PETSC_COMM_SELF, "]\n"));
241: }
243: PetscCall(MatGetInfo(allMat, MAT_LOCAL, &info));
244: PetscCall(PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_SELF, "All matrix: %" PetscInt_FMT " nonzeros\n", (PetscInt)info.nz_used));
246: PetscCall(PetscDualSpaceGetInteriorData(sp, &intNodes, &intMat));
247: if (intMat && intMat != allMat) {
248: PetscInt intNodeIdxDim, intNodeVecDim, intNnodes;
249: const PetscInt *intNodeIdx;
250: const PetscReal *intNodeVec;
251: PetscBool same;
253: PetscCall(PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_SELF, "Interior nodes:\n"));
254: PetscCall(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_SELF));
255: PetscCall(PetscQuadratureView(intNodes, PETSC_VIEWER_STDOUT_SELF));
256: PetscCall(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_SELF));
258: PetscCall(MatGetInfo(intMat, MAT_LOCAL, &info));
259: PetscCall(PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_SELF, "Interior matrix: %" PetscInt_FMT " nonzeros\n", (PetscInt)info.nz_used));
260: PetscCall(PetscLagNodeIndicesGetData_Internal(lag->intNodeIndices, &intNodeIdxDim, &intNodeVecDim, &intNnodes, &intNodeIdx, &intNodeVec));
261: PetscCheck(intNodeIdxDim == nodeIdxDim && intNodeVecDim == nodeVecDim, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Interior node indices not the same shale as all node indices");
262: PetscCheck(intNnodes == spintdim, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Incorrect interior nNodes");
263: PetscCall(PetscArraycmp(intNodeIdx, nodeIdx, nodeIdxDim * intNnodes, &same));
264: PetscCheck(same, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Interior node indices not the same as start of all node indices");
265: PetscCall(PetscArraycmp(intNodeVec, nodeVec, nodeVecDim * intNnodes, &same));
266: PetscCheck(same, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Interior node vectors not the same as start of all node vectors");
267: } else if (intMat) {
268: PetscCall(PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_SELF, "Interior data is the same as all data\n"));
269: PetscCheck(intNodes == allNodes, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Interior nodes should be the same as all nodes");
270: PetscCheck(lag->intNodeIndices == lag->allNodeIndices, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Interior node indices should be the same as all node indices");
271: }
272: }
273: if (dim <= 2 && spintdim) {
274: PetscInt numFaces, o;
276: {
277: DMPolytopeType ct;
278: /* The number of arrangements is no longer based on the number of faces */
279: PetscCall(DMPlexGetCellType(K, 0, &ct));
280: numFaces = DMPolytopeTypeGetNumArrangments(ct) / 2;
281: }
282: for (o = -numFaces; o < numFaces; ++o) {
283: Mat symMat;
285: PetscCall(PetscDualSpaceCreateInteriorSymmetryMatrix_Lagrange(sp, o, &symMat));
286: PetscCall(PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_SELF, "Interior node symmetry matrix for orientation %" PetscInt_FMT ":\n", o));
287: PetscCall(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_SELF));
288: PetscCall(MatView(symMat, PETSC_VIEWER_STDOUT_SELF));
289: PetscCall(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_SELF));
290: PetscCall(MatDestroy(&symMat));
291: }
292: }
293: PetscCall(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_SELF));
294: }
295: PetscCall(PetscDualSpaceDestroy(&sp));
296: PetscFunctionReturn(PETSC_SUCCESS);
297: }
299: int main(int argc, char **argv)
300: {
301: PetscInt dim;
302: PetscHashLag lagTable;
303: PetscInt tensorCell;
304: PetscInt order, ordermin, ordermax;
305: PetscBool continuous;
306: PetscBool trimmed;
307: DM dm;
309: PetscFunctionBeginUser;
310: PetscCall(PetscInitialize(&argc, &argv, NULL, help));
311: dim = 3;
312: tensorCell = 0;
313: continuous = PETSC_FALSE;
314: trimmed = PETSC_FALSE;
315: PetscOptionsBegin(PETSC_COMM_WORLD, "", "Options for PETSCDUALSPACELAGRANGE test", "none");
316: PetscCall(PetscOptionsRangeInt("-dim", "The spatial dimension", "ex1.c", dim, &dim, NULL, 0, 3));
317: PetscCall(PetscOptionsRangeInt("-tensor", "(0) simplex (1) hypercube (2) wedge", "ex1.c", tensorCell, &tensorCell, NULL, 0, 2));
318: PetscCall(PetscOptionsBool("-continuous", "Whether the dual space has continuity", "ex1.c", continuous, &continuous, NULL));
319: PetscCall(PetscOptionsBool("-trimmed", "Whether the dual space matches a trimmed polynomial space", "ex1.c", trimmed, &trimmed, NULL));
320: PetscOptionsEnd();
321: PetscCall(PetscHashLagCreate(&lagTable));
323: if (tensorCell < 2) {
324: PetscCall(DMPlexCreateReferenceCell(PETSC_COMM_SELF, DMPolytopeTypeSimpleShape(dim, (PetscBool)!tensorCell), &dm));
325: } else {
326: PetscCall(DMPlexCreateReferenceCell(PETSC_COMM_SELF, DM_POLYTOPE_TRI_PRISM, &dm));
327: }
328: ordermin = trimmed ? 1 : 0;
329: ordermax = tensorCell == 2 ? 4 : tensorCell == 1 ? 3 : dim + 2;
330: for (order = ordermin; order <= ordermax; order++) {
331: PetscInt formDegree;
333: for (formDegree = PetscMin(0, -dim + 1); formDegree <= dim; formDegree++) {
334: PetscInt nCopies;
336: for (nCopies = 1; nCopies <= 3; nCopies++) PetscCall(testLagrange(lagTable, dm, dim, order, formDegree, trimmed, (PetscBool)tensorCell, continuous, nCopies));
337: }
338: }
339: PetscCall(DMDestroy(&dm));
340: PetscCall(PetscHashLagDestroy(&lagTable));
341: PetscCall(PetscFinalize());
342: return 0;
343: }
345: /*TEST
347: test:
348: suffix: 0
349: args: -dim 0
351: test:
352: suffix: 1_discontinuous_full
353: args: -dim 1 -continuous 0 -trimmed 0
355: test:
356: suffix: 1_continuous_full
357: args: -dim 1 -continuous 1 -trimmed 0
359: test:
360: suffix: 2_simplex_discontinuous_full
361: args: -dim 2 -tensor 0 -continuous 0 -trimmed 0
363: test:
364: suffix: 2_simplex_continuous_full
365: args: -dim 2 -tensor 0 -continuous 1 -trimmed 0
367: test:
368: suffix: 2_tensor_discontinuous_full
369: args: -dim 2 -tensor 1 -continuous 0 -trimmed 0
371: test:
372: suffix: 2_tensor_continuous_full
373: args: -dim 2 -tensor 1 -continuous 1 -trimmed 0
375: test:
376: suffix: 3_simplex_discontinuous_full
377: args: -dim 3 -tensor 0 -continuous 0 -trimmed 0
379: test:
380: suffix: 3_simplex_continuous_full
381: args: -dim 3 -tensor 0 -continuous 1 -trimmed 0
383: test:
384: suffix: 3_tensor_discontinuous_full
385: args: -dim 3 -tensor 1 -continuous 0 -trimmed 0
387: test:
388: suffix: 3_tensor_continuous_full
389: args: -dim 3 -tensor 1 -continuous 1 -trimmed 0
391: test:
392: suffix: 3_wedge_discontinuous_full
393: args: -dim 3 -tensor 2 -continuous 0 -trimmed 0
395: test:
396: suffix: 3_wedge_continuous_full
397: args: -dim 3 -tensor 2 -continuous 1 -trimmed 0
399: test:
400: suffix: 1_discontinuous_trimmed
401: args: -dim 1 -continuous 0 -trimmed 1
403: test:
404: suffix: 1_continuous_trimmed
405: args: -dim 1 -continuous 1 -trimmed 1
407: test:
408: suffix: 2_simplex_discontinuous_trimmed
409: args: -dim 2 -tensor 0 -continuous 0 -trimmed 1
411: test:
412: suffix: 2_simplex_continuous_trimmed
413: args: -dim 2 -tensor 0 -continuous 1 -trimmed 1
415: test:
416: suffix: 2_tensor_discontinuous_trimmed
417: args: -dim 2 -tensor 1 -continuous 0 -trimmed 1
419: test:
420: suffix: 2_tensor_continuous_trimmed
421: args: -dim 2 -tensor 1 -continuous 1 -trimmed 1
423: test:
424: suffix: 3_simplex_discontinuous_trimmed
425: args: -dim 3 -tensor 0 -continuous 0 -trimmed 1
427: test:
428: suffix: 3_simplex_continuous_trimmed
429: args: -dim 3 -tensor 0 -continuous 1 -trimmed 1
431: test:
432: suffix: 3_tensor_discontinuous_trimmed
433: args: -dim 3 -tensor 1 -continuous 0 -trimmed 1
435: test:
436: suffix: 3_tensor_continuous_trimmed
437: args: -dim 3 -tensor 1 -continuous 1 -trimmed 1
439: test:
440: suffix: 3_wedge_discontinuous_trimmed
441: args: -dim 3 -tensor 2 -continuous 0 -trimmed 1
443: test:
444: suffix: 3_wedge_continuous_trimmed
445: args: -dim 3 -tensor 2 -continuous 1 -trimmed 1
447: TEST*/