23 for (
int i = 0; i < 4; i++)
48 MFEM_VERIFY(f != 0,
"tetrahedron is not marked");
50 for (i = 0; i < 2; i++)
52 refinement_edges[i] = f & 7;
65 e1 = refinement_edges[0];
66 e2 = refinement_edges[1];
71 if (e1 == 2 && e2 == 1) {
break; }
73 mfem_error(
"Error in Tetrahedron::CreateRefinementFlag(...) #1");
76 if (e1 == 3 && e2 == 1) {
break; }
77 if (e1 == 2 && e2 == 4) {
break; }
82 mfem_error(
"Error in Tetrahedron::CreateRefinementFlag(...) #2");
87 if (e1 == 2 && e2 == 1) {
break; }
90 mfem_error(
"Error in Tetrahedron::CreateRefinementFlag(...) #3");
93 if (flag == 0 && e1 == 5 && e2 == 5)
97 mfem_error(
"Error in Tetrahedron::CreateRefinementFlag(...) #4");
102 if (e1 == 5 && e2 == 1) {
break; }
103 if (e1 == 2 && e2 == 5) {
break; }
105 mfem_error(
"Error in Tetrahedron::CreateRefinementFlag(...) #5");
108 mfem_error(
"Error in Tetrahedron::CreateRefinementFlag(...) #6");
127 int re[2], type, flag, *tv = this->
indices;
134 case 1: fv[0] = tv[1]; fv[1] = tv[2]; fv[2] = tv[3];
break;
135 case 4: fv[0] = tv[3]; fv[1] = tv[1]; fv[2] = tv[2];
break;
136 case 5: fv[0] = tv[2]; fv[1] = tv[3]; fv[2] = tv[1];
break;
142 case 2: fv[0] = tv[2]; fv[1] = tv[0]; fv[2] = tv[3];
break;
143 case 3: fv[0] = tv[0]; fv[1] = tv[3]; fv[2] = tv[2];
break;
144 case 5: fv[0] = tv[3]; fv[1] = tv[2]; fv[2] = tv[0];
break;
148 fv[0] = tv[0]; fv[1] = tv[1]; fv[2] = tv[3];
151 fv[0] = tv[1]; fv[1] = tv[0]; fv[2] = tv[2];
161 if (middle[m] != -1) {
return 1; }
163 if (middle[m] != -1) {
return 1; }
165 if (middle[m] != -1) {
return 1; }
167 if (middle[m] != -1) {
return 1; }
169 if (middle[m] != -1) {
return 1; }
171 if (middle[m] != -1) {
return 1; }
177 for (
int i = 0; i < 4; i++)
185 int ind[4], i, j, l, L, type;
189 if ((l = length[v_to_v(
indices[1],
indices[2])]) > L) { L = l; j = 1; }
190 if ((l = length[v_to_v(
indices[2],
indices[0])]) > L) { L = l; j = 2; }
191 if ((l = length[v_to_v(
indices[0],
indices[3])]) > L) { L = l; j = 3; }
192 if ((l = length[v_to_v(
indices[1],
indices[3])]) > L) { L = l; j = 4; }
195 for (i = 0; i < 4; i++)
226 ind[0] = 2; ind[1] = 1;
228 if ((l = length[v_to_v(
indices[0],
indices[3])]) > L) { L = l; ind[0] = 3; }
229 if ((l = length[v_to_v(
indices[2],
indices[3])]) > L) { ind[0] = 5; }
232 if ((l = length[v_to_v(
indices[1],
indices[3])]) > L) { L = l; ind[1] = 4; }
233 if ((l = length[v_to_v(
indices[2],
indices[3])]) > L) { ind[1] = 5; }
252 j = 1; ind[0] = 2; ind[1] = 1;
break;
255 j = 1; ind[0] = 5; ind[1] = 1;
264 j = 1; ind[0] = 2; ind[1] = 5;
break;
282 double *a = &pm(0,0), *b = &pm(0,1), *c = &pm(0,2), *d = &pm(0,3);
285 a[0] = 0.0, a[1] = 0.0, a[2] = 0.0;
286 b[0] = 1.0, b[1] = 0.0, b[2] = 0.0;
287 c[0] = 0.0, c[1] = 1.0, c[2] = 0.0;
288 d[0] = 0.0, d[1] = 0.0, d[2] = 1.0;
290 int chain[12], n = 0;
293 chain[n++] = (transform & 7) - 1;
301 #define ASGN(a, b) (a[0] = b[0], a[1] = b[1], a[2] = b[2])
302 #define SWAP(a, b) for (int i = 0; i < 3; i++) { std::swap(a[i], b[i]); }
303 #define AVG(a, b, c) for (int i = 0; i < 3; i++) { a[i] = (b[i]+c[i])*0.5; }
309 case 0: ASGN(b, c); ASGN(c, d);
break;
310 case 1: ASGN(a, c); ASGN(c, d);
break;
311 case 2: ASGN(b, a); ASGN(a, d);
break;
312 case 3: ASGN(a, b); ASGN(b, d);
break;
313 case 4: SWAP(a, c); ASGN(b, d);
break;
314 case 5: SWAP(b, c); ASGN(a, d);
break;
316 MFEM_ABORT(
"Invalid transform.");
325 for (
int i = 0; i < 4; i++)
333 #ifdef MFEM_USE_MEMALLOC
Data type dense matrix using column-major storage.
virtual void SetVertices(const int *ind)
Set the vertices according to the given input.
virtual Element * Duplicate(Mesh *m) const
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
void CreateRefinementFlag(int refinement_edges[2], int type, int flag=0)
Class for linear FE on tetrahedron.
Data type tetrahedron element.
int attribute
Element's attribute (specifying material property, etc).
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
virtual void MarkEdge(DenseMatrix &pmat)
Mark the longest edge by assuming/changing the order of the vertices.
Linear3DFiniteElement TetrahedronFE
virtual int * GetVertices()
virtual int NeedRefinement(DSTable &v_to_v, int *middle) const
Return 1 if the element needs refinement in order to get conforming mesh.
static void GetPointMatrix(unsigned transform, DenseMatrix &pm)
Calculate point matrix corresponding to a chain of transformations.
void SetAttribute(const int attr)
Set element's attribute.
void GetMarkedFace(const int face, int *fv)
MemAlloc< Tetrahedron, 1024 > TetMemory
void SetRefinementFlag(int rf)
void ParseRefinementFlag(int refinement_edges[2], int &type, int &flag)
Abstract data type element.