MFEM  v3.0
 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.googlecode.com.
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  break;
76  mfem_error("Error in Tetrahedron::CreateRefinementFlag(...) #4");
77  break;
79  if (flag == 0)
80  {
81  if (e1 == 5 && e2 == 1) break;
82  if (e1 == 2 && e2 == 5) break;
83  }
84  mfem_error("Error in Tetrahedron::CreateRefinementFlag(...) #5");
85  break;
86  default:
87  mfem_error("Error in Tetrahedron::CreateRefinementFlag(...) #6");
88  break;
89  }
90 #endif
91 
92  refinement_flag = flag;
94 
97 
98  refinement_flag = refinement_flag | refinement_edges[1];
100 
101  refinement_flag = refinement_flag | refinement_edges[0];
102 }
103 
104 Tetrahedron::Tetrahedron(const int *ind, int attr)
105  : Element(Geometry::TETRAHEDRON)
106 {
107  attribute = attr;
108  for (int i = 0; i < 4; i++)
109  indices[i] = ind[i];
110  refinement_flag = 0;
111 }
112 
113 Tetrahedron::Tetrahedron(int ind1, int ind2, int ind3, int ind4, int attr)
114  : Element(Geometry::TETRAHEDRON)
115 {
116  attribute = attr;
117  indices[0] = ind1;
118  indices[1] = ind2;
119  indices[2] = ind3;
120  indices[3] = ind4;
121  refinement_flag = 0;
122 }
123 
124 int Tetrahedron::NeedRefinement(DSTable &v_to_v, int *middle) const
125 {
126  int m;
127 
128  if ((m = v_to_v(indices[0], indices[1])) != -1)
129  if (middle[m] != -1) return 1;
130  if ((m = v_to_v(indices[1], indices[2])) != -1)
131  if (middle[m] != -1) return 1;
132  if ((m = v_to_v(indices[2], indices[0])) != -1)
133  if (middle[m] != -1) return 1;
134  if ((m = v_to_v(indices[0], indices[3])) != -1)
135  if (middle[m] != -1) return 1;
136  if ((m = v_to_v(indices[1], indices[3])) != -1)
137  if (middle[m] != -1) return 1;
138  if ((m = v_to_v(indices[2], indices[3])) != -1)
139  if (middle[m] != -1) return 1;
140  return 0;
141 }
142 
143 void Tetrahedron::SetVertices(const int *ind)
144 {
145  for (int i = 0; i < 4; i++)
146  indices[i] = ind[i];
147 }
148 
149 void Tetrahedron::MarkEdge(const DSTable &v_to_v, const int *length)
150 {
151  int ind[4], i, j, l, L, type;
152 
153  // determine the longest edge
154  L = length[v_to_v(indices[0], indices[1])]; j = 0;
155  if ((l = length[v_to_v(indices[1], indices[2])]) > L) { L = l; j = 1; }
156  if ((l = length[v_to_v(indices[2], indices[0])]) > L) { L = l; j = 2; }
157  if ((l = length[v_to_v(indices[0], indices[3])]) > L) { L = l; j = 3; }
158  if ((l = length[v_to_v(indices[1], indices[3])]) > L) { L = l; j = 4; }
159  if ((l = length[v_to_v(indices[2], indices[3])]) > L) { L = l; j = 5; }
160 
161  for (i = 0; i < 4; i++)
162  ind[i] = indices[i];
163 
164  switch (j)
165  {
166  case 1:
167  indices[0] = ind[1]; indices[1] = ind[2];
168  indices[2] = ind[0]; indices[3] = ind[3];
169  break;
170  case 2:
171  indices[0] = ind[2]; indices[1] = ind[0];
172  indices[2] = ind[1]; indices[3] = ind[3];
173  break;
174  case 3:
175  indices[0] = ind[3]; indices[1] = ind[0];
176  indices[2] = ind[2]; indices[3] = ind[1];
177  break;
178  case 4:
179  indices[0] = ind[1]; indices[1] = ind[3];
180  indices[2] = ind[2]; indices[3] = ind[0];
181  break;
182  case 5:
183  indices[0] = ind[2]; indices[1] = ind[3];
184  indices[2] = ind[0]; indices[3] = ind[1];
185  break;
186  }
187 
188  // Determine the two longest edges for the other two faces and
189  // store them in ind[0] and ind[1]
190  ind[0] = 2; ind[1] = 1;
191  L = length[v_to_v(indices[0], indices[2])];
192  if ((l = length[v_to_v(indices[0], indices[3])]) > L) { L = l; ind[0] = 3; }
193  if ((l = length[v_to_v(indices[2], indices[3])]) > L) { L = l; ind[0] = 5; }
194 
195  L = length[v_to_v(indices[1], indices[2])];
196  if ((l = length[v_to_v(indices[1], indices[3])]) > L) { L = l; ind[1] = 4; }
197  if ((l = length[v_to_v(indices[2], indices[3])]) > L) { L = l; ind[1] = 5; }
198 
199  j = 0;
200  switch (ind[0])
201  {
202  case 2:
203  switch (ind[1])
204  {
205  case 1: type = Tetrahedron::TYPE_PU; break;
206  case 4: type = Tetrahedron::TYPE_A; break;
207  case 5:
208  default: type = Tetrahedron::TYPE_M;
209  }
210  break;
211  case 3:
212  switch (ind[1])
213  {
214  case 1: type = Tetrahedron::TYPE_A; break;
215  case 4: type = Tetrahedron::TYPE_PU;
216  j = 1; ind[0] = 2; ind[1] = 1; break;
217  case 5:
218  default: type = Tetrahedron::TYPE_M;
219  j = 1; ind[0] = 5; ind[1] = 1;
220  }
221  break;
222  case 5:
223  default:
224  switch (ind[1])
225  {
226  case 1: type = Tetrahedron::TYPE_M; break;
227  case 4: type = Tetrahedron::TYPE_M;
228  j = 1; ind[0] = 2; ind[1] = 5; break;
229  case 5:
230  default: type = Tetrahedron::TYPE_O;
231  }
232  }
233 
234  if (j)
235  {
236  j = indices[0]; indices[0] = indices[1]; indices[1] = j;
237  j = indices[2]; indices[2] = indices[3]; indices[3] = j;
238  }
239 
240  CreateRefinementFlag(ind, type);
241 }
242 
244 {
245  v.SetSize(4);
246  for (int i = 0; i < 4; i++)
247  {
248  v[i] = indices[i];
249  }
250 }
251 
253 {
254 #ifdef MFEM_USE_MEMALLOC
255  Tetrahedron *tet = m->TetMemory.Alloc();
256 #else
257  Tetrahedron *tet = new Tetrahedron;
258 #endif
259  tet->SetVertices(indices);
260  tet->SetAttribute(attribute);
262  return tet;
263 }
264 
266 
267 }
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:643
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:293
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:82
MemAlloc< Tetrahedron, 1024 > TetMemory
Definition: mesh.hpp:111
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