SCIRun  5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TetLinearLgn.h
Go to the documentation of this file.
1 //
2 // For more information, please see: http://software.sci.utah.edu
3 //
4 // The MIT License
5 //
6 // Copyright (c) 2009 Scientific Computing and Imaging Institute,
7 // University of Utah.
8 //
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 // DEALINGS IN THE SOFTWARE.
27 //
28 /// @file TetLinearLgn.h
29 /// @author Martin Cole, Frank B. Sachse
30 /// @date Dec 04 2004
31 
32 #ifndef CORE_BASIS_TETLINEARLGN_H
33 #define CORE_BASIS_TETLINEARLGN_H 1
34 
35 #include <cfloat>
36 
40 #include <Core/Basis/share.h>
41 
42 namespace SCIRun {
43 namespace Core {
44 namespace Basis {
45 
46 /// Class for describing unit geometry of TetLinearLgn
48 public:
49  /// Parametric coordinates of vertices of unit edge
50  static SCISHARE double unit_vertices[4][3];
51  /// References to vertices of unit edge
52  static SCISHARE int unit_edges[6][2];
53  /// References to vertices of unit face
54  static SCISHARE int unit_faces[4][3];
55  /// Normals of unit faces
56  static SCISHARE double unit_face_normals[4][3];
57  /// Precalculated area of faces
58  static SCISHARE double unit_face_areas[4];
59  /// Center of the unit element
60  static SCISHARE double unit_center[3];
61 
64 
65  /// return dimension of domain
66  static int domain_dimension()
67  { return 3; }
68 
69  /// return size of the domain
70  static double domain_size()
71  { return 1.0/6.0; }
72 
73  /// return number of vertices
74  static int number_of_vertices()
75  { return 4; }
76 
77  /// return number of vertices in mesh
79  { return 4; }
80 
81  /// return number of edges
82  static int number_of_edges()
83  { return 6; }
84 
85  /// return degrees of freedom
86  static int dofs()
87  { return 4; }
88 
89  /// return number of vertices per face
90  static int vertices_of_face()
91  { return 3; }
92 
93  /// return number of faces per cell
94  static int faces_of_cell()
95  { return 4; }
96 
97  static inline double length(int edge)
98  { ///< return length
99  const double *v0 = unit_vertices[unit_edges[edge][0]];
100  const double *v1 = unit_vertices[unit_edges[edge][1]];
101  const double dx = v1[0] - v0[0];
102  const double dy = v1[1] - v0[1];
103  const double dz = v1[2] - v0[2];
104  return sqrt(dx*dx+dy*dy+dz*dz);
105  }
106  static double area(int face) { return unit_face_areas[face]; } ///< return area
107  static double volume() { return 1./6.; } ///< return volume
108 };
109 
110 
111 /// Class for creating geometrical approximations of Tet meshes
112 class TetApprox {
113 public:
114 
116  virtual ~TetApprox() {}
117 
118  /// Approximate edge for element by piecewise linear segments
119  /// return: coords gives parametric coordinates of the approximation.
120  /// Use interpolate with coordinates to get the world coordinates.
121  template<class VECTOR>
122  void approx_edge(const unsigned edge,
123  const unsigned div_per_unit,
124  VECTOR &coords) const
125  {
126  typedef typename VECTOR::value_type VECTOR2;
127 
128  coords.resize(div_per_unit + 1);
129 
131  const double *v1 = TetLinearLgnUnitElement::unit_vertices[TetLinearLgnUnitElement::unit_edges[edge][1]];
132 
133  const double &p1x = v0[0];
134  const double &p1y = v0[1];
135  const double &p1z = v0[2];
136  const double dx = v1[0] - p1x;
137  const double dy = v1[1] - p1y;
138  const double dz = v1[2] - p1z;
139 
140  for(unsigned int i = 0; i <= div_per_unit; i++) {
141  const double d = (double)i / (double)div_per_unit;
142  typename VECTOR::value_type &tmp = coords[i];
143  tmp.resize(3);
144  tmp[0] = static_cast<typename VECTOR2::value_type>(p1x + d * dx);
145  tmp[1] = static_cast<typename VECTOR2::value_type>(p1y + d * dy);
146  tmp[2] = static_cast<typename VECTOR2::value_type>(p1z + d * dz);
147  }
148  }
149 
150  /// Approximate faces for element by piecewise linear elements
151  /// return number of vertices per face
152  virtual int get_approx_face_elements() const { return 3; }
153 
154 
155  /// Approximate faces for element by piecewise linear elements
156  /// return: coords gives parametric coordinates at the approximation point.
157  /// Use interpolate with coordinates to get the world coordinates.
158  template <class VECTOR>
159  void approx_face(const unsigned face,
160  const unsigned div_per_unit,
161  VECTOR &coords) const
162  {
163  typedef typename VECTOR::value_type VECTOR2;
164  typedef typename VECTOR2::value_type VECTOR3;
165 
167  const double *v1 = TetLinearLgnUnitElement::unit_vertices[TetLinearLgnUnitElement::unit_faces[face][1]];
168  const double *v2 = TetLinearLgnUnitElement::unit_vertices[TetLinearLgnUnitElement::unit_faces[face][2]];
169  coords.resize(div_per_unit);
170  const double d = 1. / div_per_unit;
171  for(unsigned int j = 0; j<div_per_unit; j++)
172  {
173  const double dj = (double)j / (double)div_per_unit;
174  unsigned int e = 0;
175  coords[j].resize((div_per_unit - j) * 2 + 1);
176  typename VECTOR2::value_type &tmp = coords[j][e++];
177  tmp.resize(3);
178  tmp[0] = static_cast<typename VECTOR3::value_type>(v0[0] + dj * (v2[0] - v0[0]));
179  tmp[1] = static_cast<typename VECTOR3::value_type>(v0[1] + dj * (v2[1] - v0[1]));
180  tmp[2] = static_cast<typename VECTOR3::value_type>(v0[2] + dj * (v2[2] - v0[2]));
181 
182  for(unsigned int i = 0; i<div_per_unit - j; i++)
183  {
184  const double di = (double)i / (double)div_per_unit;
185  typename VECTOR2::value_type &tmp1 = coords[j][e++];
186  tmp1.resize(3);
187  tmp1[0] = static_cast<typename VECTOR3::value_type>(v0[0] + (dj + d) * (v2[0] - v0[0]) + di * (v1[0] - v0[0]));
188  tmp1[1] = static_cast<typename VECTOR3::value_type>(v0[1] + (dj + d) * (v2[1] - v0[1]) + di * (v1[1] - v0[1]));
189  tmp1[2] = static_cast<typename VECTOR3::value_type>(v0[2] + (dj + d) * (v2[2] - v0[2]) + di * (v1[2] - v0[2]));
190 
191  typename VECTOR2::value_type &tmp2 = coords[j][e++];
192  tmp2.resize(3);
193  tmp2[0] = static_cast<typename VECTOR3::value_type>(v0[0] + dj * (v2[0] - v0[0]) + (di + d) * (v1[0] - v0[0]));
194  tmp2[1] = static_cast<typename VECTOR3::value_type>(v0[1] + dj * (v2[1] - v0[1]) + (di + d) * (v1[1] - v0[1]));
195  tmp2[2] = static_cast<typename VECTOR3::value_type>(v0[2] + dj * (v2[2] - v0[2]) + (di + d) * (v1[2] - v0[2]));
196  }
197  }
198  }
199 };
200 
201 /// Class for searching of parametric coordinates related to a
202 /// value in Tet meshes and fields
203 /// to do
204 template <class ElemBasis>
205 class TetLocate : public Dim3Locate<ElemBasis> {
206 public:
207  typedef typename ElemBasis::value_type T;
208 
210  virtual ~TetLocate() {}
211 
212  /// find coodinate in interpolation for given value
213  template <class ElemData, class VECTOR>
214  bool get_coords(const ElemBasis *pEB, VECTOR &coords,
215  const T& value, const ElemData &cd) const
216  {
217  initial_guess(pEB, value, cd, coords);
218  if (this->get_iterative(pEB, coords, value, cd))
219  return check_coords(coords);
220  return false;
221  }
222 
223 protected:
224  template <class VECTOR>
225  inline bool check_coords(const VECTOR &x) const
226  {
230  if (x[0]+x[1]+x[2]<=Dim3Locate<ElemBasis>::thresholdDist1)
231  return true;
232 
233  return false;
234  }
235 
236  /// find a reasonable initial guess
237  template <class ElemData, class VECTOR>
238  void initial_guess(const ElemBasis *pElem, const T &val, const ElemData &cd,
239  VECTOR & guess) const
240  {
241  double dist = DBL_MAX;
242 
243  VECTOR coord(3);
244  StackVector<T,3> derivs;
245  guess.resize(3);
246 
247  const int end = 3;
248  for (int x = 1; x < end; x++)
249  {
250  coord[0] = x / (double) end;
251  for (int y = 1; y < end; y++)
252  {
253  coord[1] = y / (double) end;
254  if (coord[0]+coord[1]>Dim3Locate<ElemBasis>::thresholdDist1)
255  break;
256  for (int z = 1; z < end; z++)
257  {
258  coord[2] = z / (double) end;
259  if (coord[0]+coord[1]+coord[2]>Dim3Locate<ElemBasis>::thresholdDist1)
260  break;
261 
262  double cur_d;
263  if (compare_distance(pElem->interpolate(coord, cd),
264  val, cur_d, dist))
265  {
266  pElem->derivate(coord, cd, derivs);
267  if (!check_zero(derivs))
268  {
269  dist = cur_d;
270  guess = coord;
271  }
272  }
273  }
274  }
275  }
276  }
277 };
278 
279 
280 
281 /// Class with weights and coordinates for 1nd order Gaussian integration
282 template <class T>
284 {
285 public:
286  static int GaussianNum;
287  static T GaussianPoints[1][3];
288  static T GaussianWeights[1];
289 };
290 
291 #ifdef _WIN32
292 // force the instantiation of TetGaussian1<double>
293 template class TetGaussian1<double>;
294 #endif
295 
296 template <class T>
298 
299 template <class T>
301  {1./4., 1./4., 1./4.}};
302 
303 template <class T>
305 
306 
307 /// Class with weights and coordinates for 2nd order Gaussian integration
308 template <class T>
310 {
311 public:
312  static int GaussianNum;
313  static T GaussianPoints[4][3];
314  static T GaussianWeights[4];
315 };
316 
317 #ifdef _WIN32
318 // force the instantiation of TetGaussian2<double>
319 template class TetGaussian2<double>;
320 #endif
321 
322 template <class T>
324 
325 template <class T>
327  {0.138196601125011, 0.138196601125011, 0.138196601125011},
328  {0.585410196624969, 0.138196601125011, 0.138196601125011},
329  {0.138196601125011, 0.585410196624969, 0.138196601125011},
330  {0.138196601125011, 0.138196601125011, 0.585410196624969}};
331 
332 // {1./6., 1./6., 1./6.}, {2./3., 1./6., 1./6.},
333 // {1./6., 2./3., 1./6.}, {1./6., 1./6., 2./3.}};
334 
335 template <class T>
336 T TetGaussian2<T>::GaussianWeights[] = {.25, .25, .25, .25};
337 
338 
339 /// Class with weights and coordinates for 3rd order Gaussian integration
340 template <class T>
342 {
343 public:
344  static int GaussianNum;
345  static T GaussianPoints[11][3];
346  static T GaussianWeights[11];
347 };
348 
349 template <class T>
351  {0.2500000, 0.2500000, 0.2500000},
352  {0.7857143, 0.07142857, 0.07142857},
353  {0.07142857, 0.7857143, 0.07142857},
354  {0.07142857, 0.07142857, 0.7857143},
355  {0.07142857, 0.07142857, 0.07142857},
356  {0.1005964, 0.1005964, 0.3994034},
357  {0.1005964, 0.3994034, 0.1005964},
358  {0.1005964, 0.3994034, 0.3994034},
359  {0.3994034, 0.1005964, 0.1005964},
360  {0.3994034, 0.1005964, 0.3994034},
361  {0.3994034, 0.3994034, 0.1005964}};
362 
363 template <class T>
364 T TetGaussian3<T>::GaussianWeights[] = {
365  -0.01315556,
366  0.007622222,
367  0.007622222,
368  0.007622222,
369  0.007622222,
370  0.02488889,
371  0.02488889,
372  0.02488889,
373  0.02488889,
374  0.02488889,
375  0.02488889};
376 
377 template <class T>
378 int TetGaussian3<T>::GaussianNum = 11;
379 
380 /// Class for handling of element of type tetrahedron with
381 /// linear lagrangian interpolation
382 template <class T>
383 class TetLinearLgn :
384  public BasisSimple<T>,
385  public TetApprox,
386  public TetGaussian1<double>,
387  public TetSamplingSchemes,
388  public TetLinearLgnUnitElement ,
389  public TetElementWeights
390 {
391 public:
392  typedef T value_type;
393 
395  virtual ~TetLinearLgn() {}
396 
397  static int polynomial_order() { return 1; }
398 
399  template<class VECTOR>
400  inline void get_weights(const VECTOR& coords, double *w) const
401  { get_linear_weights(coords,w); }
402 
403  template<class VECTOR>
404  inline void get_derivate_weights(const VECTOR& coords, double *w) const
405  { get_linear_derivate_weights(coords,w); }
406 
407 
408  /// get value at parametric coordinate
409  template <class ElemData, class VECTOR>
410  T interpolate(const VECTOR &coords, const ElemData &cd) const
411  {
412  double w[4];
413  get_linear_weights(coords, w);
414 
415  return (T)(w[0] * cd.node0() +
416  w[1] * cd.node1() +
417  w[2] * cd.node2() +
418  w[3] * cd.node3());
419  }
420 
421  /// get first derivative at parametric coordinate
422  template <class ElemData,class VECTOR1, class VECTOR2>
423  void derivate(const VECTOR1& /*coords*/, const ElemData &cd,
424  VECTOR2 &derivs) const
425  {
426  derivs.resize(3);
427 
428  derivs[0] = static_cast<typename VECTOR2::value_type>(-1. * cd.node0() + cd.node1());
429  derivs[1] = static_cast<typename VECTOR2::value_type>(-1. * cd.node0() + cd.node2());
430  derivs[2] = static_cast<typename VECTOR2::value_type>(-1. * cd.node0() + cd.node3());
431  }
432 
433  /// get parametric coordinate for value within the element
434  template <class ElemData, class VECTOR>
435  bool get_coords(VECTOR &coords, const T& value,
436  const ElemData &cd) const
437  {
439  return CL.get_coords(this, coords, value, cd);
440  }
441 
442  /// get arc length for edge
443  template <class ElemData>
444  double get_arc_length(const unsigned edge, const ElemData &cd) const
445  {
446  return get_arc3d_length<CrvGaussian1<double> >(this, edge, cd);
447  }
448 
449  /// get area
450  template <class ElemData>
451  double get_area(const unsigned face, const ElemData &cd) const
452  {
453  return get_area3<TriGaussian2<double> >(this, face, cd);
454  }
455 
456  /// get volume
457  template <class ElemData>
458  double get_volume(const ElemData & cd) const
459  {
460  return get_volume3(this, cd);
461  }
462 
463 
464  static const std::string type_name(int n = -1);
465 
466  virtual void io (Piostream& str);
467 
468 };
469 
470 
471 
472 
473 template <class T>
474 const std::string
476 {
477  ASSERT((n >= -1) && n <= 1);
478  if (n == -1)
479  {
480  static const std::string name = TypeNameGenerator::make_template_id(type_name(0), type_name(1));
481  return name;
482  }
483  else if (n == 0)
484  {
485  static const std::string nm("TetLinearLgn");
486  return nm;
487  } else {
488  return find_type_name((T *)0);
489  }
490 }
491 
492 
493 
494 
495 }}
496 
497 template <class T>
499 {
500  static TypeDescription* td = 0;
501  if(!td){
502  const TypeDescription *sub = get_type_description((T*)0);
504  (*subs)[0] = sub;
505  td = new TypeDescription("TetLinearLgn", subs,
506  std::string(__FILE__),
507  "SCIRun",
509  }
510  return td;
511 }
512 
513 const int TETLINEARLGN_VERSION = 1;
514 template <class T>
515 void
517 {
518  stream.begin_class(get_type_description(this)->get_name(),
520  stream.end_class();
521 }
522 }
523 
524 #endif
Class with weights and coordinates for 3rd order Gaussian integration.
Definition: TetLinearLgn.h:341
static int number_of_vertices()
return number of vertices
Definition: TetLinearLgn.h:74
T interpolate(const VECTOR &coords, const ElemData &cd) const
get value at parametric coordinate
Definition: TetLinearLgn.h:410
static const std::string type_name(int n=-1)
Definition: TetLinearLgn.h:475
double check_zero(const VECTOR &derivs, double epsilon=1e-7)
Definition: Locate.h:709
Class for describing unit geometry of TetLinearLgn.
Definition: TetLinearLgn.h:47
double get_arc_length(const unsigned edge, const ElemData &cd) const
get arc length for edge
Definition: TetLinearLgn.h:444
Definition: Persistent.h:89
static double area(int face)
return area
Definition: TetLinearLgn.h:106
static int number_of_mesh_vertices()
return number of vertices in mesh
Definition: TetLinearLgn.h:78
static int number_of_edges()
return number of edges
Definition: TetLinearLgn.h:82
Definition: TypeDescription.h:45
#define SCISHARE
Definition: share.h:39
std::vector< const TypeDescription * > td_vec
Definition: TypeDescription.h:56
static SCISHARE double unit_vertices[4][3]
Parametric coordinates of vertices of unit edge.
Definition: TetLinearLgn.h:50
Definition: TetElementWeights.h:36
ElemBasis::value_type T
Definition: Locate.h:549
static SCISHARE double unit_center[3]
Center of the unit element.
Definition: TetLinearLgn.h:60
#define ASSERT(condition)
Definition: Assert.h:110
Class for describing interfaces to basis elements.
Definition: Basis.h:48
double get_area(const unsigned face, const ElemData &cd) const
get area
Definition: TetLinearLgn.h:451
Definition: TetLinearLgn.h:205
virtual int begin_class(const std::string &name, int current_version)
Definition: Persistent.cc:143
void approx_face(const unsigned face, const unsigned div_per_unit, VECTOR &coords) const
Definition: TetLinearLgn.h:159
static double domain_size()
return size of the domain
Definition: TetLinearLgn.h:70
const string find_type_name(float *)
Definition: TypeName.cc:63
virtual void io(Piostream &str)
Definition: TetLinearLgn.h:516
bool check_coords(const VECTOR &x) const
Definition: TetLinearLgn.h:225
const char * name[]
Definition: BoostGraphExampleTests.cc:87
TetLinearLgn()
Definition: TetLinearLgn.h:394
static double length(int edge)
Definition: TetLinearLgn.h:97
static int vertices_of_face()
return number of vertices per face
Definition: TetLinearLgn.h:90
Class with weights and coordinates for 1nd order Gaussian integration.
Definition: TetLinearLgn.h:283
Definition: StackVector.h:50
double get_volume(const ElemData &cd) const
get volume
Definition: TetLinearLgn.h:458
T value_type
Definition: TetLinearLgn.h:392
bool get_coords(VECTOR &coords, const T &value, const ElemData &cd) const
get parametric coordinate for value within the element
Definition: TetLinearLgn.h:435
void initial_guess(const ElemBasis *pElem, const T &val, const ElemData &cd, VECTOR &guess) const
find a reasonable initial guess
Definition: TetLinearLgn.h:238
void get_derivate_weights(const VECTOR &coords, double *w) const
Definition: TetLinearLgn.h:404
Class for creating geometrical approximations of Tet meshes.
Definition: TetLinearLgn.h:112
static const std::string make_template_id(const std::string &templateName, const std::string &templateParam)
Definition: TypeName.h:62
virtual ~TetLocate()
Definition: TetLinearLgn.h:210
static T GaussianWeights[1]
Definition: TetLinearLgn.h:288
static int polynomial_order()
Definition: TetLinearLgn.h:397
TetLinearLgnUnitElement()
Definition: TetLinearLgn.h:62
const int TETLINEARLGN_VERSION
Definition: TetLinearLgn.h:513
Class with weights and coordinates for 2nd order Gaussian integration.
Definition: TetLinearLgn.h:309
static int GaussianNum
Definition: TetLinearLgn.h:286
Definition: TetSamplingSchemes.h:42
bool compare_distance(const T &interp, const T &val, double &cur_d, double dist)
Definition: Locate.h:667
static double volume()
return volume
Definition: TetLinearLgn.h:107
virtual void end_class()
Definition: Persistent.cc:178
virtual ~TetLinearLgnUnitElement()
Definition: TetLinearLgn.h:63
static SCISHARE double unit_face_areas[4]
Precalculated area of faces.
Definition: TetLinearLgn.h:58
TetApprox()
Definition: TetLinearLgn.h:115
void resize(size_t size, const value_type &val=value_type())
Definition: StackVector.h:61
ElemBasis::value_type T
Definition: TetLinearLgn.h:207
static SCISHARE double unit_face_normals[4][3]
Normals of unit faces.
Definition: TetLinearLgn.h:56
void get_weights(const VECTOR &coords, double *w) const
Definition: TetLinearLgn.h:400
Definition: Locate.h:547
Definition: TetLinearLgn.h:383
void approx_edge(const unsigned edge, const unsigned div_per_unit, VECTOR &coords) const
Definition: TetLinearLgn.h:122
static int GaussianNum
Definition: TetLinearLgn.h:312
virtual int get_approx_face_elements() const
Definition: TetLinearLgn.h:152
int n
Definition: eab.py:9
static SCISHARE int unit_edges[6][2]
References to vertices of unit edge.
Definition: TetLinearLgn.h:52
static int GaussianNum
Definition: TetLinearLgn.h:344
static int dofs()
return degrees of freedom
Definition: TetLinearLgn.h:86
bool get_iterative(const ElemBasis *pEB, VECTOR &x, const T &value, const ElemData &cd) const
find value in interpolation for given value
Definition: Locate.h:559
static SCISHARE int unit_faces[4][3]
References to vertices of unit face.
Definition: TetLinearLgn.h:54
TetLocate()
Definition: TetLinearLgn.h:209
double get_volume3(const ElemBasis *pEB, const ElemData &cd)
Definition: Locate.h:179
static int faces_of_cell()
return number of faces per cell
Definition: TetLinearLgn.h:94
void derivate(const VECTOR1 &, const ElemData &cd, VECTOR2 &derivs) const
get first derivative at parametric coordinate
Definition: TetLinearLgn.h:423
virtual ~TetApprox()
Definition: TetLinearLgn.h:116
bool get_coords(const ElemBasis *pEB, VECTOR &coords, const T &value, const ElemData &cd) const
find coodinate in interpolation for given value
Definition: TetLinearLgn.h:214
Definition: TypeDescription.h:49
const TypeDescription * get_type_description(Core::Basis::ConstantBasis< T > *)
Definition: Constant.h:209
virtual ~TetLinearLgn()
Definition: TetLinearLgn.h:395
static T GaussianPoints[1][3]
Definition: TetLinearLgn.h:287
static int domain_dimension()
return dimension of domain
Definition: TetLinearLgn.h:66