MFEM  v3.1
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
tetrahedron.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 // Implementation of class Tetrahedron
13 
14 #include "mesh_headers.hpp"
15 
16 namespace mfem
17 {
18 
19 const int Tetrahedron::edges[6][2] =
20 {{0, 1}, {0, 2}, {0, 3}, {1, 2}, {1, 3}, {2, 3}};
21 
22 void Tetrahedron::ParseRefinementFlag(int refinement_edges[2], int &type,
23  int &flag)
24 {
25  int i, f = refinement_flag;
26 
27  if (f == 0)
28  mfem_error("Tetrahedron::ParseRefinementFlag :"
29  " tetrahedron is not marked");
30 
31  for (i = 0; i < 2; i++)
32  {
33  refinement_edges[i] = f & 7;
34  f = f >> 3;
35  }
36  type = f & 7;
37  flag = (f >> 3);
38 }
39 
40 void Tetrahedron::CreateRefinementFlag(int refinement_edges[2], int type,
41  int flag)
42 {
43  // Check for correct type
44 #ifdef MFEM_DEBUG
45  int e1, e2;
46  e1 = refinement_edges[0];
47  e2 = refinement_edges[1];
48  // if (e1 > e2) e1 = e2, e2 = refinement_edges[0];
49  switch (type)
50  {
52  if (e1 == 2 && e2 == 1) { break; }
53  // if (e1 == 3 && e2 == 4) break;
54  mfem_error("Error in Tetrahedron::CreateRefinementFlag(...) #1");
55  break;
57  if (e1 == 3 && e2 == 1) { break; }
58  if (e1 == 2 && e2 == 4) { break; }
59  // if (flag == 0) // flag is assumed to be the generation
60  // if (e2 == 5)
61  // if (e1 >= 1 && e1 <= 5) break; // type is actually O or M
62  // // ==> ok for generation = 0
63  mfem_error("Error in Tetrahedron::CreateRefinementFlag(...) #2");
64  break;
66  if (flag > 0) // PF is ok only for generation > 0
67  {
68  if (e1 == 2 && e2 == 1) { break; }
69  // if (e1 == 3 && e2 == 4) break;
70  }
71  mfem_error("Error in Tetrahedron::CreateRefinementFlag(...) #3");
72  break;
74  if (flag == 0 && e1 == 5 && e2 == 5)
75  {
76  break;
77  }
78  mfem_error("Error in Tetrahedron::CreateRefinementFlag(...) #4");
79  break;
81  if (flag == 0)
82  {
83  if (e1 == 5 && e2 == 1) { break; }
84  if (e1 == 2 && e2 == 5) { break; }
85  }
86  mfem_error("Error in Tetrahedron::CreateRefinementFlag(...) #5");
87  break;
88  default:
89  mfem_error("Error in Tetrahedron::CreateRefinementFlag(...) #6");
90  break;
91  }
92 #endif
93 
94  refinement_flag = flag;
96 
99 
100  refinement_flag = refinement_flag | refinement_edges[1];
102 
103  refinement_flag = refinement_flag | refinement_edges[0];
104 }
105 
106 Tetrahedron::Tetrahedron(const int *ind, int attr)
107  : Element(Geometry::TETRAHEDRON)
108 {
109  attribute = attr;
110  for (int i = 0; i < 4; i++)
111  {
112  indices[i] = ind[i];
113  }
114  refinement_flag = 0;
115 }
116 
117 Tetrahedron::Tetrahedron(int ind1, int ind2, int ind3, int ind4, int attr)
118  : Element(Geometry::TETRAHEDRON)
119 {
120  attribute = attr;
121  indices[0] = ind1;
122  indices[1] = ind2;
123  indices[2] = ind3;
124  indices[3] = ind4;
125  refinement_flag = 0;
126 }
127 
128 int Tetrahedron::NeedRefinement(DSTable &v_to_v, int *middle) const
129 {
130  int m;
131 
132  if ((m = v_to_v(indices[0], indices[1])) != -1)
133  if (middle[m] != -1) { return 1; }
134  if ((m = v_to_v(indices[1], indices[2])) != -1)
135  if (middle[m] != -1) { return 1; }
136  if ((m = v_to_v(indices[2], indices[0])) != -1)
137  if (middle[m] != -1) { return 1; }
138  if ((m = v_to_v(indices[0], indices[3])) != -1)
139  if (middle[m] != -1) { return 1; }
140  if ((m = v_to_v(indices[1], indices[3])) != -1)
141  if (middle[m] != -1) { return 1; }
142  if ((m = v_to_v(indices[2], indices[3])) != -1)
143  if (middle[m] != -1) { return 1; }
144  return 0;
145 }
146 
147 void Tetrahedron::SetVertices(const int *ind)
148 {
149  for (int i = 0; i < 4; i++)
150  {
151  indices[i] = ind[i];
152  }
153 }
154 
155 void Tetrahedron::MarkEdge(const DSTable &v_to_v, const int *length)
156 {
157  int ind[4], i, j, l, L, type;
158 
159  // determine the longest edge
160  L = length[v_to_v(indices[0], indices[1])]; j = 0;
161  if ((l = length[v_to_v(indices[1], indices[2])]) > L) { L = l; j = 1; }
162  if ((l = length[v_to_v(indices[2], indices[0])]) > L) { L = l; j = 2; }
163  if ((l = length[v_to_v(indices[0], indices[3])]) > L) { L = l; j = 3; }
164  if ((l = length[v_to_v(indices[1], indices[3])]) > L) { L = l; j = 4; }
165  if ((l = length[v_to_v(indices[2], indices[3])]) > L) { L = l; j = 5; }
166 
167  for (i = 0; i < 4; i++)
168  {
169  ind[i] = indices[i];
170  }
171 
172  switch (j)
173  {
174  case 1:
175  indices[0] = ind[1]; indices[1] = ind[2];
176  indices[2] = ind[0]; indices[3] = ind[3];
177  break;
178  case 2:
179  indices[0] = ind[2]; indices[1] = ind[0];
180  indices[2] = ind[1]; indices[3] = ind[3];
181  break;
182  case 3:
183  indices[0] = ind[3]; indices[1] = ind[0];
184  indices[2] = ind[2]; indices[3] = ind[1];
185  break;
186  case 4:
187  indices[0] = ind[1]; indices[1] = ind[3];
188  indices[2] = ind[2]; indices[3] = ind[0];
189  break;
190  case 5:
191  indices[0] = ind[2]; indices[1] = ind[3];
192  indices[2] = ind[0]; indices[3] = ind[1];
193  break;
194  }
195 
196  // Determine the two longest edges for the other two faces and
197  // store them in ind[0] and ind[1]
198  ind[0] = 2; ind[1] = 1;
199  L = length[v_to_v(indices[0], indices[2])];
200  if ((l = length[v_to_v(indices[0], indices[3])]) > L) { L = l; ind[0] = 3; }
201  if ((l = length[v_to_v(indices[2], indices[3])]) > L) { L = l; ind[0] = 5; }
202 
203  L = length[v_to_v(indices[1], indices[2])];
204  if ((l = length[v_to_v(indices[1], indices[3])]) > L) { L = l; ind[1] = 4; }
205  if ((l = length[v_to_v(indices[2], indices[3])]) > L) { L = l; ind[1] = 5; }
206 
207  j = 0;
208  switch (ind[0])
209  {
210  case 2:
211  switch (ind[1])
212  {
213  case 1: type = Tetrahedron::TYPE_PU; break;
214  case 4: type = Tetrahedron::TYPE_A; break;
215  case 5:
216  default: type = Tetrahedron::TYPE_M;
217  }
218  break;
219  case 3:
220  switch (ind[1])
221  {
222  case 1: type = Tetrahedron::TYPE_A; break;
223  case 4: type = Tetrahedron::TYPE_PU;
224  j = 1; ind[0] = 2; ind[1] = 1; break;
225  case 5:
226  default: type = Tetrahedron::TYPE_M;
227  j = 1; ind[0] = 5; ind[1] = 1;
228  }
229  break;
230  case 5:
231  default:
232  switch (ind[1])
233  {
234  case 1: type = Tetrahedron::TYPE_M; break;
235  case 4: type = Tetrahedron::TYPE_M;
236  j = 1; ind[0] = 2; ind[1] = 5; break;
237  case 5:
238  default: type = Tetrahedron::TYPE_O;
239  }
240  }
241 
242  if (j)
243  {
244  j = indices[0]; indices[0] = indices[1]; indices[1] = j;
245  j = indices[2]; indices[2] = indices[3]; indices[3] = j;
246  }
247 
248  CreateRefinementFlag(ind, type);
249 }
250 
252 {
253  v.SetSize(4);
254  for (int i = 0; i < 4; i++)
255  {
256  v[i] = indices[i];
257  }
258 }
259 
261 {
262 #ifdef MFEM_USE_MEMALLOC
263  Tetrahedron *tet = m->TetMemory.Alloc();
264 #else
265  Tetrahedron *tet = new Tetrahedron;
266 #endif
267  tet->SetVertices(indices);
268  tet->SetAttribute(attribute);
270  return tet;
271 }
272 
274 
275 }
virtual void SetVertices(const int *ind)
Set the vertices according to the given input.
static const int edges[6][2]
Definition: tetrahedron.hpp:26
virtual Element * Duplicate(Mesh *m) const
void CreateRefinementFlag(int refinement_edges[2], int type, int flag=0)
Definition: tetrahedron.cpp:40
Class for linear FE on tetrahedron.
Definition: fe.hpp:655
Data type tetrahedron element.
Definition: tetrahedron.hpp:22
int attribute
Element&#39;s attribute (specifying material property, etc).
Definition: element.hpp:32
void mfem_error(const char *msg)
Definition: error.cpp:23
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
Definition: array.hpp:323
virtual void MarkEdge(DenseMatrix &pmat)
Mark the longest edge by assuming/changing the order of the vertices.
Definition: tetrahedron.hpp:65
Linear3DFiniteElement TetrahedronFE
virtual int * GetVertices()
Definition: tetrahedron.hpp:78
virtual int NeedRefinement(DSTable &v_to_v, int *middle) const
Return 1 if the element needs refinement in order to get conforming mesh.
void SetAttribute(const int attr)
Set element&#39;s attribute.
Definition: element.hpp:83
MemAlloc< Tetrahedron, 1024 > TetMemory
Definition: mesh.hpp:134
void SetRefinementFlag(int rf)
Definition: tetrahedron.hpp:56
void ParseRefinementFlag(int refinement_edges[2], int &type, int &flag)
Definition: tetrahedron.cpp:22
Abstract data type element.
Definition: element.hpp:27