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; }
193 if ((l = length[v_to_v(
indices[2],
indices[3])]) > L) { L = l; j = 5; }
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) { L = 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) { L = 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 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 mfem_error(const char *msg)
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.