SCIRun  5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
QuadBilinearLgn.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 QuadBilinearLgn.h
29 /// @author Martin Cole, Frank B. Sachse
30 /// @date Dec 04 2004
31 
32 #ifndef CORE_BASIS_QUADBILINEARLGN_H
33 #define CORE_BASIS_QUADBILINEARLGN_H 1
34 
35 #include <float.h>
36 
40 
41 namespace SCIRun {
42 namespace Core {
43 namespace Basis {
44 
45 /// Class for describing unit geometry of QuadBilinearLgn
47 public:
48  /// Parametric coordinates of vertices of unit edge
49  static SCISHARE double unit_vertices[4][2];
50  /// References to vertices of unit edge
51  static SCISHARE int unit_edges[4][2];
52  /// References to vertices of unit face
53  static SCISHARE int unit_faces[1][4];
54  /// References to normal of unit face
55  static SCISHARE double unit_face_normals[1][3];
56  /// Center of the unit element
57  static SCISHARE double unit_center[2];
58 
61  /// return dimension of domain
62  static int domain_dimension()
63  { return 2; }
64 
65  /// return size of the domain
66  static double domain_size()
67  { return 1.0; }
68 
69  /// return number of vertices
70  static int number_of_vertices()
71  { return 4; }
72 
73  /// return number of vertices in mesh
75  { return 4; }
76 
77  /// return degrees of freedom
78  static int dofs()
79  { return 4; }
80 
81  /// return number of edges
82  static int number_of_edges()
83  { return 4; }
84 
85  /// return number of vertices per face
86  static int vertices_of_face()
87  { return 4; }
88 
89  /// return number of faces per cell
90  static int faces_of_cell()
91  { return 1; }
92 
93  static inline double length(int edge)
94  { ///< return length
95  const double *v0 = unit_vertices[unit_edges[edge][0]];
96  const double *v1 = unit_vertices[unit_edges[edge][1]];
97  const double dx = v1[0] - v0[0];
98  const double dy = v1[1] - v0[1];
99  return sqrt(dx*dx+dy*dy);
100  }
101 
102  static double area(int /* face */) { return 1; } ///< return area
103  static double volume() { return 0.; } ///< return volume
104 };
105 
106 
107 /// Class for creating geometrical approximations of Quad meshes
108 class QuadApprox {
109 public:
111  virtual ~QuadApprox() {}
112 
113  /// Approximate edge for element by piecewise linear segments
114  /// return: coords gives parametric coordinates of the approximation.
115  /// Use interpolate with coordinates to get the world coordinates.
116  template<class VECTOR>
117  void approx_edge(const unsigned edge,
118  const unsigned div_per_unit,
119  VECTOR &coords) const
120  {
121  typedef typename VECTOR::value_type VECTOR2;
122  coords.resize(div_per_unit + 1);
123 
125  const double p1y = QuadBilinearLgnUnitElement::unit_vertices[QuadBilinearLgnUnitElement::unit_edges[edge][0]][1];
126  const double dx = QuadBilinearLgnUnitElement::unit_vertices[QuadBilinearLgnUnitElement::unit_edges[edge][1]][0] - p1x;
127  const double dy = QuadBilinearLgnUnitElement::unit_vertices[QuadBilinearLgnUnitElement::unit_edges[edge][1]][1] - p1y;
128 
129  for(unsigned i = 0; i <= div_per_unit; i ++)
130  {
131  const double d = (double)i / (double)div_per_unit;
132  typename VECTOR::value_type &tmp = coords[i];
133  tmp.resize(2);
134  tmp[0] = static_cast<typename VECTOR2::value_type>(p1x + d * dx);
135  tmp[1] = static_cast<typename VECTOR2::value_type>(p1y + d * dy);
136  }
137  }
138 
139  /// Approximate faces for element by piecewise linear elements
140  /// return: coords gives parametric coordinates at the approximation point.
141  /// Use interpolate with coordinates to get the world coordinates.
142  template<class VECTOR>
143  void approx_face(const unsigned /* face */,
144  const unsigned div_per_unit,
145  VECTOR &coords) const
146  {
147  typedef typename VECTOR::value_type VECTOR2;
148  typedef typename VECTOR2::value_type VECTOR3;
149 
150  coords.resize(div_per_unit);
151  double d = 1. / div_per_unit;
152  for(unsigned j = 0; j < div_per_unit; j++)
153  {
154  coords[j].resize(2 * (div_per_unit + 1));
155  unsigned e = 0;
156  for(unsigned i = 0; i <= div_per_unit; i++)
157  {
158  typename VECTOR2::value_type &e1 = coords[j][e++];
159  e1.resize(2);
160  e1[0] = static_cast<typename VECTOR3::value_type>((double)i / (double)div_per_unit);
161  e1[1] = static_cast<typename VECTOR3::value_type>((double)j / (double)div_per_unit);
162  typename VECTOR2::value_type &e2 = coords[j][e++];
163  e2.resize(2);
164  e2[0] = e1[0];
165  e2[1] = static_cast<typename VECTOR3::value_type>((double)j / (double)div_per_unit + d);
166  }
167  }
168  }
169 };
170 
171 /// Class for searching of parametric coordinates related to a
172 /// value in Quad meshes and fields
173 /// to do
174 template <class ElemBasis>
175 class QuadLocate : public Dim2Locate<ElemBasis> {
176 public:
177  typedef typename ElemBasis::value_type T;
178 
180  virtual ~QuadLocate() {}
181 
182  /// find value in interpolation for given value
183  template <class ElemData, class VECTOR>
184  bool get_coords(const ElemBasis *pEB, VECTOR &coords,
185  const T& value, const ElemData &cd) const
186  {
187  initial_guess(pEB, value, cd, coords);
188  if (this->get_iterative(pEB, coords, value, cd))
189  return check_coords(coords);
190  return false;
191  }
192 
193  template <class VECTOR>
194  inline bool check_coords(const VECTOR &x) const
195  {
200  return true;
201 
202  return false;
203  }
204 
205 protected:
206  /// find a reasonable initial guess
207  template <class ElemData, class VECTOR>
208  void initial_guess(const ElemBasis *pElem, const T &val, const ElemData &cd,
209  VECTOR & guess) const
210  {
211  double dist = DBL_MAX;
212 
213  VECTOR coord(2);
214  StackVector<T,2> derivs;
215  guess.resize(2);
216 
217  const int end = 3;
218  for (int x = 1; x < end; x++)
219  {
220  coord[0] = x / (double) end;
221  for (int y = 1; y < end; y++)
222  {
223  coord[1] = y / (double) end;
224  double cur_d;
225  if (compare_distance(pElem->interpolate(coord, cd),
226  val, cur_d, dist))
227  {
228  pElem->derivate(coord, cd, derivs);
229  if (!check_zero(derivs))
230  {
231  dist = cur_d;
232  guess = coord;
233  }
234  }
235  }
236  }
237  }
238 };
239 
240 
241 /// Class with weights and coordinates for 2nd order Gaussian integration
242 template <class T>
244 {
245 public:
246  static int GaussianNum;
247  static T GaussianPoints[1][2];
248  static T GaussianWeights[1];
249 };
250 
251 template <class T>
253 
254 template <class T>
256  {0.5, 0.5}};
257 
258 template <class T>
260 
261 
262 /// Class with weights and coordinates for 2nd order Gaussian integration
263 template <class T>
265 {
266 public:
267  static int GaussianNum;
268  static T GaussianPoints[4][2];
269  static T GaussianWeights[4];
270 };
271 
272 template <class T>
274 
275 template <class T>
277  {0.211324865405, 0.211324865405},
278  {0.788675134595, 0.211324865405},
279  {0.788675134595, 0.788675134595},
280  {0.211324865405, 0.788675134595}};
281 
282 template <class T>
283 T QuadGaussian2<T>::GaussianWeights[4] = {.25, .25, .25, .25};
284 
285 /// Class with weights and coordinates for 3rd order Gaussian integration
286 template <class T>
288 {
289 public:
290  static int GaussianNum;
291  static T GaussianPoints[9][2];
292  static T GaussianWeights[9];
293 };
294 
295 template <class T>
297 
298 template <class T>
300  {0.11270166537950, 0.11270166537950}, {0.5, 0.11270166537950}, {0.88729833462050, 0.11270166537950},
301  {0.11270166537950, 0.5}, {0.5, 0.5}, {0.88729833462050, 0.5},
302  {0.11270166537950, 0.88729833462050}, {0.5, 0.88729833462050}, {0.88729833462050, 0.88729833462050}
303 };
304 
305 template <class T>
306 T QuadGaussian3<T>::GaussianWeights[9] = {
307  0.07716049378395, 0.12345679007654, 0.07716049378395,
308  0.12345679007654, 0.19753086415802, 0.12345679007654,
309  0.07716049378395, 0.12345679007654, 0.07716049378395
310 };
311 
312 
313 /// Class for handling of element of type quad with
314 /// bilinear lagrangian interpolation
315 template <class T>
317  public BasisSimple<T>,
318  public QuadApprox,
319  public QuadGaussian3<double>,
320  public QuadSamplingSchemes,
322  public QuadElementWeights
323 {
324 public:
325  typedef T value_type;
326 
328  virtual ~QuadBilinearLgn() {}
329 
330  static int polynomial_order() { return 1; }
331 
332  template<class VECTOR>
333  inline void get_weights(const VECTOR& coords, double *w) const
334  { get_linear_weights(coords,w); }
335 
336  template<class VECTOR>
337  inline void get_derivate_weights(const VECTOR& coords, double *w) const
338  { get_linear_derivate_weights(coords,w); }
339 
340  /// get value at parametric coordinate
341  template <class ElemData, class VECTOR>
342  T interpolate(const VECTOR &coords, const ElemData &cd) const
343  {
344  double w[4];
345  get_linear_weights(coords, w);
346 
347  return (T)(w[0] * cd.node0() +
348  w[1] * cd.node1() +
349  w[2] * cd.node2() +
350  w[3] * cd.node3());
351  }
352 
353 
354  /// get first derivative at parametric coordinate
355  template <class ElemData, class VECTOR1, class VECTOR2>
356  void derivate(const VECTOR1 &coords, const ElemData &cd,
357  VECTOR2 &derivs) const
358  {
359  double w[12];
360  get_linear_derivate_weights(coords, w);
361 
362  derivs.resize(2);
363 
364  derivs[0] = static_cast<typename VECTOR2::value_type>(
365  w[0] * cd.node0() +
366  w[1] * cd.node1() +
367  w[2] * cd.node2() +
368  w[3] * cd.node3());
369 
370  derivs[1] = static_cast<typename VECTOR2::value_type>(
371  w[4] * cd.node0() +
372  w[5] * cd.node1() +
373  w[6] * cd.node2() +
374  w[7] * cd.node3());
375  }
376 
377  /// get parametric coordinate for value within the element
378  template <class ElemData, class VECTOR>
379  bool get_coords(VECTOR &coords, const T& value,
380  const ElemData &cd) const
381  {
383  return CL.get_coords(this, coords, value, cd);
384  }
385 
386  /// get arc length for edge
387  template <class ElemData>
388  double get_arc_length(const unsigned edge, const ElemData &cd) const
389  {
390  return get_arc2d_length<CrvGaussian1<double> >(this, edge, cd);
391  }
392 
393  /// get area
394  template <class ElemData>
395  double get_area(const unsigned face, const ElemData &cd) const
396  {
397  return get_area2<QuadGaussian2<double> >(this, face, cd);
398  }
399 
400  /// get volume
401  template <class ElemData>
402  double get_volume(const ElemData & /* cd */) const
403  {
404  return 0.;
405  }
406 
407 
408  static const std::string type_name(int n = -1);
409 
410  virtual void io (Piostream& str);
411 
412 };
413 
414 
415 
416 
417 
418 template <class T>
419 const std::string
421 {
422  ASSERT((n >= -1) && n <= 1);
423  if (n == -1)
424  {
425  static const std::string name = TypeNameGenerator::make_template_id(type_name(0), type_name(1));
426  return name;
427  }
428  else if (n == 0)
429  {
430  static const std::string nm("QuadBilinearLgn");
431  return nm;
432  } else {
433  return find_type_name((T *)0);
434  }
435 }
436 
437 
438 
439 
440 }}
441 template <class T>
443 {
444  static TypeDescription* td = 0;
445  if(!td){
446  const TypeDescription *sub = get_type_description((T*)0);
448  (*subs)[0] = sub;
449  td = new TypeDescription("QuadBilinearLgn", subs,
450  std::string(__FILE__),
451  "SCIRun",
453  }
454  return td;
455 }
456 
458 template <class T>
459 void
461 {
462  stream.begin_class(get_type_description(this)->get_name(),
464  stream.end_class();
465 }
466 }
467 
468 #endif
static int vertices_of_face()
return number of vertices per face
Definition: QuadBilinearLgn.h:86
static SCISHARE int unit_edges[4][2]
References to vertices of unit edge.
Definition: QuadBilinearLgn.h:51
static const std::string type_name(int n=-1)
Definition: QuadBilinearLgn.h:420
static T GaussianWeights[1]
Definition: QuadBilinearLgn.h:248
void approx_edge(const unsigned edge, const unsigned div_per_unit, VECTOR &coords) const
Definition: QuadBilinearLgn.h:117
static T GaussianPoints[1][2]
Definition: QuadBilinearLgn.h:247
static int domain_dimension()
return dimension of domain
Definition: QuadBilinearLgn.h:62
static int GaussianNum
Definition: QuadBilinearLgn.h:290
static T GaussianPoints[4][2]
Definition: QuadBilinearLgn.h:268
double check_zero(const VECTOR &derivs, double epsilon=1e-7)
Definition: Locate.h:709
bool check_coords(const VECTOR &x) const
Definition: QuadBilinearLgn.h:194
Class with weights and coordinates for 2nd order Gaussian integration.
Definition: QuadBilinearLgn.h:264
Definition: Persistent.h:89
T interpolate(const VECTOR &coords, const ElemData &cd) const
get value at parametric coordinate
Definition: QuadBilinearLgn.h:342
static int polynomial_order()
Definition: QuadBilinearLgn.h:330
void approx_face(const unsigned, const unsigned div_per_unit, VECTOR &coords) const
Definition: QuadBilinearLgn.h:143
static int GaussianNum
Definition: QuadBilinearLgn.h:246
static int dofs()
return degrees of freedom
Definition: QuadBilinearLgn.h:78
Definition: TypeDescription.h:45
#define SCISHARE
Definition: share.h:39
std::vector< const TypeDescription * > td_vec
Definition: TypeDescription.h:56
QuadLocate()
Definition: QuadBilinearLgn.h:179
Definition: QuadBilinearLgn.h:316
bool get_coords(VECTOR &coords, const T &value, const ElemData &cd) const
get parametric coordinate for value within the element
Definition: QuadBilinearLgn.h:379
static int faces_of_cell()
return number of faces per cell
Definition: QuadBilinearLgn.h:90
#define ASSERT(condition)
Definition: Assert.h:110
Class for describing interfaces to basis elements.
Definition: Basis.h:48
Definition: QuadElementWeights.h:36
virtual int begin_class(const std::string &name, int current_version)
Definition: Persistent.cc:143
static int number_of_edges()
return number of edges
Definition: QuadBilinearLgn.h:82
ElemBasis::value_type T
Definition: Locate.h:587
static SCISHARE double unit_face_normals[1][3]
References to normal of unit face.
Definition: QuadBilinearLgn.h:55
const string find_type_name(float *)
Definition: TypeName.cc:63
void get_linear_derivate_weights(const VECTOR &coords, double *w) const
get derivative weight factors at parametric coordinate
Definition: QuadElementWeights.h:51
ElemBasis::value_type T
Definition: QuadBilinearLgn.h:177
double get_area(const unsigned face, const ElemData &cd) const
get area
Definition: QuadBilinearLgn.h:395
Definition: QuadSamplingSchemes.h:42
static T GaussianPoints[9][2]
Definition: QuadBilinearLgn.h:291
const char * name[]
Definition: BoostGraphExampleTests.cc:87
QuadApprox()
Definition: QuadBilinearLgn.h:110
Definition: StackVector.h:50
virtual ~QuadBilinearLgnUnitElement()
Definition: QuadBilinearLgn.h:60
Definition: QuadBilinearLgn.h:175
Definition: Locate.h:585
static T GaussianWeights[9]
Definition: QuadBilinearLgn.h:292
Class for describing unit geometry of QuadBilinearLgn.
Definition: QuadBilinearLgn.h:46
double get_arc_length(const unsigned edge, const ElemData &cd) const
get arc length for edge
Definition: QuadBilinearLgn.h:388
bool get_coords(const ElemBasis *pEB, VECTOR &coords, const T &value, const ElemData &cd) const
find value in interpolation for given value
Definition: QuadBilinearLgn.h:184
QuadBilinearLgn()
Definition: QuadBilinearLgn.h:327
static double domain_size()
return size of the domain
Definition: QuadBilinearLgn.h:66
virtual ~QuadApprox()
Definition: QuadBilinearLgn.h:111
static const std::string make_template_id(const std::string &templateName, const std::string &templateParam)
Definition: TypeName.h:62
static int GaussianNum
Definition: QuadBilinearLgn.h:267
virtual ~QuadBilinearLgn()
Definition: QuadBilinearLgn.h:328
QuadBilinearLgnUnitElement()
Definition: QuadBilinearLgn.h:59
static double length(int edge)
Definition: QuadBilinearLgn.h:93
static SCISHARE double unit_center[2]
Center of the unit element.
Definition: QuadBilinearLgn.h:57
void get_weights(const VECTOR &coords, double *w) const
Definition: QuadBilinearLgn.h:333
bool compare_distance(const T &interp, const T &val, double &cur_d, double dist)
Definition: Locate.h:667
double get_volume(const ElemData &) const
get volume
Definition: QuadBilinearLgn.h:402
virtual void end_class()
Definition: Persistent.cc:178
static SCISHARE double unit_vertices[4][2]
Parametric coordinates of vertices of unit edge.
Definition: QuadBilinearLgn.h:49
static double volume()
return volume
Definition: QuadBilinearLgn.h:103
static int number_of_vertices()
return number of vertices
Definition: QuadBilinearLgn.h:70
void resize(size_t size, const value_type &val=value_type())
Definition: StackVector.h:61
void get_derivate_weights(const VECTOR &coords, double *w) const
Definition: QuadBilinearLgn.h:337
static T GaussianWeights[4]
Definition: QuadBilinearLgn.h:269
virtual void io(Piostream &str)
Definition: QuadBilinearLgn.h:460
Class for creating geometrical approximations of Quad meshes.
Definition: QuadBilinearLgn.h:108
static SCISHARE int unit_faces[1][4]
References to vertices of unit face.
Definition: QuadBilinearLgn.h:53
static double area(int)
return area
Definition: QuadBilinearLgn.h:102
int n
Definition: eab.py:9
void get_linear_weights(const VECTOR &coords, double *w) const
Definition: QuadElementWeights.h:40
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:597
virtual ~QuadLocate()
Definition: QuadBilinearLgn.h:180
void initial_guess(const ElemBasis *pElem, const T &val, const ElemData &cd, VECTOR &guess) const
find a reasonable initial guess
Definition: QuadBilinearLgn.h:208
static int number_of_mesh_vertices()
return number of vertices in mesh
Definition: QuadBilinearLgn.h:74
Class with weights and coordinates for 3rd order Gaussian integration.
Definition: QuadBilinearLgn.h:287
void derivate(const VECTOR1 &coords, const ElemData &cd, VECTOR2 &derivs) const
get first derivative at parametric coordinate
Definition: QuadBilinearLgn.h:356
Class with weights and coordinates for 2nd order Gaussian integration.
Definition: QuadBilinearLgn.h:243
const int QUADBILINEARLGN_VERSION
Definition: QuadBilinearLgn.h:457
T value_type
Definition: QuadBilinearLgn.h:325
Definition: TypeDescription.h:49
const TypeDescription * get_type_description(Core::Basis::ConstantBasis< T > *)
Definition: Constant.h:209