SCIRun  5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CrvLinearLgn.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 CrvLinearLgn.h
29 /// @author Martin Cole, Frank B. Sachse
30 /// @date Dec 03 2004
31 
32 #ifndef CORE_BASIS_CRVLINEARLGN_H
33 #define CORE_BASIS_CRVLINEARLGN_H 1
34 
35 #include <cfloat>
36 
37 #include <Core/Basis/Basis.h>
40 #include <Core/Basis/Locate.h>
43 #include <Core/Basis/share.h>
44 
45 namespace SCIRun {
46 namespace Core {
47 namespace Basis {
48 
49 /// Class for describing unit geometry of CrvLinearLgn
51 public:
52  static SCISHARE double unit_vertices[2][1]; ///< Parametric coordinates of vertices
53  static SCISHARE int unit_edges[1][2]; ///< References to vertices of unit edge
54  static SCISHARE double unit_center[1];
55 
58 
59  /// return dimension of domain
60  static int domain_dimension()
61  { return 1; }
62 
63  /// return size of the domain
64  static double domain_size()
65  { return 1.0; }
66 
67  /// return number of vertices
68  static int number_of_vertices()
69  { return 2; }
70 
71  /// return number of vertices in mesh
73  { return 2; }
74 
75  /// return degrees of freedom
76  static int dofs()
77  { return 2; }
78 
79  /// return number of edges
80  static int number_of_edges()
81  { return 1; }
82 
83  /// return number of vertices per face
84  static int vertices_of_face()
85  { return 0; }
86 
87  /// return number of faces per cell
88  static int faces_of_cell()
89  { return 0; }
90 
91  static double length(int /* edge */) { return 1.; } ///< return length
92  static double area(int /* face */) { return 0.; } ///< return area
93  static double volume() { return 0.; } ///< return volume
94 
95 };
96 
97 
98 /// Class for creating geometrical approximations of Crv meshes
99 class CrvApprox {
100 public:
102  virtual ~CrvApprox() {}
103 
104  /// Approximate edge for element by piecewise linear segments
105  /// return: coords gives parametric coordinates of the approximation.
106  /// Use interpolate with coordinates to get the world coordinates.
107  template<class VECTOR>
108  void approx_edge(const unsigned /*edge*/,
109  const unsigned div_per_unit,
110  VECTOR& coords) const
111  {
112  typedef typename VECTOR::value_type VECTOR2;
113  coords.resize(div_per_unit + 1);
114  for(unsigned i = 0; i <= div_per_unit; i++)
115  {
116  coords[i].resize(1);
117  coords[i][0] = static_cast<typename VECTOR2::value_type>(
118  (double)i / (double)div_per_unit);
119  }
120  }
121 
122  /// Approximate faces for element by piecewise linear elements
123  /// return: coords gives parametric coordinates at the approximation point.
124  /// Use interpolate with coordinates to get the world coordinates.
125  template<class VECTOR>
126  void approx_face(const unsigned /*face*/,
127  const unsigned /*div_per_unit*/,
128  VECTOR& coords) const
129  {
130  coords.resize(0);
131  }
132 
133 };
134 
135 
136 /// Class for searching of parametric coordinates related to a
137 /// value in Crv meshes and fields
138 template <class ElemBasis>
139 class CrvLocate : public Dim1Locate<ElemBasis> {
140 public:
141  typedef typename ElemBasis::value_type T;
142 
144  virtual ~CrvLocate() {}
145 
146  /// find coordinate in interpolation for given value
147  template <class ElemData, class VECTOR>
148  bool get_coords(const ElemBasis *pEB, VECTOR &coords,
149  const T& value, const ElemData &cd) const
150  {
151  initial_guess(pEB, value, cd, coords);
152  if (this->get_iterative(pEB, coords, value, cd))
153  return check_coords(coords);
154  return false;
155  }
156 
157  template<class VECTOR>
158  inline bool check_coords(const VECTOR &x) const
159  {
162  return true;
163 
164  return false;
165  }
166 
167 protected:
168  /// find a reasonable initial guess for starting Newton iteration.
169  /// Reasonable means near and with a derivative!=0
170  template <class ElemData, class VECTOR>
171  void initial_guess(const ElemBasis *pElem, const T &val,
172  const ElemData &cd, VECTOR &guess) const
173  {
174  double dist = DBL_MAX;
175 
176  VECTOR coord(1);
177  StackVector<T,1> derivs;
178  guess.resize(1);
179 
180  const int end = 3;
181  for (int x = 1; x < end; x++) {
182  coord[0] = x / (double) end;
183  double cur_d;
184  if (compare_distance(pElem->interpolate(coord, cd), val, cur_d, dist))
185  {
186  pElem->derivate(coord, cd, derivs);
187  if (!check_zero(derivs))
188  {
189  dist = cur_d;
190  guess = coord;
191  }
192  }
193  }
194  }
195 };
196 
197 /// Class with weights and coordinates for 1st order Gaussian integration
198 template <class T>
200 {
201 public:
202  static int GaussianNum;
203  static T GaussianPoints[1][1];
204  static T GaussianWeights[1];
205 };
206 
207 template <class T>
209 
210 template <class T>
211 T CrvGaussian1<T>::GaussianPoints[1][1] = {{0.5}};
212 
213 template <class T>
215 
216 /// Class with weights and coordinates for 2nd order Gaussian integration
217 template <class T>
219 {
220 public:
221  static int GaussianNum;
222  static T GaussianPoints[2][1];
223  static T GaussianWeights[2];
224 };
225 
226 template <class T>
228 
229 template <class T>
230 T CrvGaussian2<T>::GaussianPoints[2][1] = {{0.211324865405}, {0.788675134595}};
231 
232 template <class T>
233 T CrvGaussian2<T>::GaussianWeights[2] = {.5, .5};
234 
235 /// Class with weights and coordinates for 3rd order Gaussian integration
236 template <class T>
238 {
239 public:
240  static int GaussianNum;
241  static T GaussianPoints[3][1];
242  static T GaussianWeights[3];
243 };
244 
245 template <class T>
247 
248 template <class T>
250  {{0.11270166537950}, {0.5}, {0.88729833462050}};
251 
252 template <class T>
253 T CrvGaussian3<T>::GaussianWeights[3] =
254  {.2777777777, .4444444444, .2777777777};
255 
256 
257 
258 /// Class for handling of element of type curve with
259 /// linear lagrangian interpolation
260 template <class T>
261 class CrvLinearLgn :
262  public BasisSimple<T>,
263  public CrvApprox,
264  public CrvGaussian1<double>,
265  public CrvSamplingSchemes,
267  public CrvElementWeights
268 {
269 public:
270  typedef T value_type;
271 
273  virtual ~CrvLinearLgn() {}
274 
275 
276  static int polynomial_order() { return 1; }
277 
278  template<class VECTOR>
279  inline void get_weights(const VECTOR& coords, double *w) const
280  { get_linear_weights(coords,w); }
281 
282  template<class VECTOR>
283  inline void get_derivate_weights(const VECTOR& coords, double *w) const
284  { get_linear_derivate_weights(coords,w); }
285 
286 
287  /// get value at parametric coordinate
288  template <class ElemData, class VECTOR>
289  T interpolate(const VECTOR &coords, const ElemData &cd) const
290  {
291  double w[2];
292  get_linear_weights(coords, w);
293  return (T)(w[0] * cd.node0() + w[1] * cd.node1());
294  }
295 
296  /// get first derivative at parametric coordinate
297  template <class ElemData, class VECTOR1, class VECTOR2>
298  void derivate(const VECTOR1& /*coords*/, const ElemData &cd,
299  VECTOR2 &derivs) const
300  {
301  derivs.resize(1);
302  derivs[0] = static_cast<typename VECTOR2::value_type>(cd.node1()-cd.node0());
303  }
304 
305  /// get parametric coordinate for value within the element
306  template <class ElemData, class VECTOR>
307  bool get_coords(VECTOR &coords, const T& value,
308  const ElemData &cd) const
309  {
311  return CL.get_coords(this, coords, value, cd);
312  }
313 
314  /// get arc length for edge
315  template <class ElemData>
316  double get_arc_length(const unsigned edge, const ElemData &cd) const
317  {
318  return get_arc1d_length<CrvGaussian1<double> >(this, edge, cd);
319  }
320 
321  /// get area
322  template <class ElemData>
323  double get_area(const unsigned /* face */, const ElemData & /* cd */) const
324  {
325  return 0.;
326  }
327 
328  /// get volume
329  template <class ElemData>
330  double get_volume(const ElemData & /* cd */) const
331  {
332  return 0.;
333  }
334 
335  template <class VECTOR>
336  void approx_edge(const unsigned /*edge*/,
337  const unsigned /*div_per_unit*/,
338  std::vector<VECTOR> &coords) const
339  {
340  coords.resize(2);
341  VECTOR &tmp = coords[0];
342  tmp.resize(1);
343  tmp[0] = 0.0;
344  VECTOR &tmp1 = coords[1];
345  tmp1.resize(1);
346  tmp[0] = 1.0;
347  }
348 
349  static const std::string type_name(int n = -1);
350 
351  virtual void io (Piostream& str);
352 
353 };
354 
355 
356 
357 template <class T>
358 const std::string
360 {
361  ASSERT((n >= -1) && n <= 1);
362  if (n == -1)
363  {
364  static const std::string name = TypeNameGenerator::make_template_id(type_name(0), type_name(1));
365  return name;
366  }
367  else if (n == 0)
368  {
369  static const std::string nm("CrvLinearLgn");
370  return nm;
371  } else {
372  return find_type_name((T *)0);
373  }
374 }
375 
376 
377 
378 
379 
380 }}
381 
382 template <class T>
384 {
385  static TypeDescription* td = 0;
386  if(!td){
387  const TypeDescription *sub = get_type_description((T*)0);
389  (*subs)[0] = sub;
390  td = new TypeDescription("CrvLinearLgn", subs,
391  std::string(__FILE__),
392  "SCIRun",
394  }
395  return td;
396 }
397 const int CRVLINEARLGN_VERSION = 1;
398 template <class T>
399 void
401 {
402  stream.begin_class(get_type_description(this)->get_name(),
404  stream.end_class();
405 }
406 }
407 
408 #endif
static int number_of_edges()
return number of edges
Definition: CrvLinearLgn.h:80
CrvLocate()
Definition: CrvLinearLgn.h:143
ElemBasis::value_type T
Definition: CrvLinearLgn.h:141
double get_arc_length(const unsigned edge, const ElemData &cd) const
get arc length for edge
Definition: CrvLinearLgn.h:316
void get_linear_derivate_weights(const VECTOR &, double *w) const
get derivative weight factors at parametric coordinate
Definition: CrvElementWeights.h:51
Definition: CrvSamplingSchemes.h:43
double check_zero(const VECTOR &derivs, double epsilon=1e-7)
Definition: Locate.h:709
Definition: CrvElementWeights.h:38
specializations of template&lt;class T&gt; find_type_name() function for build-in and simple types not deri...
static T GaussianWeights[3]
Definition: CrvLinearLgn.h:242
static int polynomial_order()
Definition: CrvLinearLgn.h:276
Definition: Persistent.h:89
static int number_of_mesh_vertices()
return number of vertices in mesh
Definition: CrvLinearLgn.h:72
bool get_coords(VECTOR &coords, const T &value, const ElemData &cd) const
get parametric coordinate for value within the element
Definition: CrvLinearLgn.h:307
CrvLinearLgn()
Definition: CrvLinearLgn.h:272
static SCISHARE double unit_vertices[2][1]
Parametric coordinates of vertices.
Definition: CrvLinearLgn.h:52
void approx_face(const unsigned, const unsigned, VECTOR &coords) const
Definition: CrvLinearLgn.h:126
static int number_of_vertices()
return number of vertices
Definition: CrvLinearLgn.h:68
bool check_coords(const VECTOR &x) const
Definition: CrvLinearLgn.h:158
static T GaussianWeights[2]
Definition: CrvLinearLgn.h:223
Definition: TypeDescription.h:45
#define SCISHARE
Definition: share.h:39
std::vector< const TypeDescription * > td_vec
Definition: TypeDescription.h:56
Definition: Locate.h:625
#define ASSERT(condition)
Definition: Assert.h:110
Class for describing interfaces to basis elements.
Definition: Basis.h:48
Class for describing unit geometry of CrvLinearLgn.
Definition: CrvLinearLgn.h:50
static int faces_of_cell()
return number of faces per cell
Definition: CrvLinearLgn.h:88
virtual int begin_class(const std::string &name, int current_version)
Definition: Persistent.cc:143
T interpolate(const VECTOR &coords, const ElemData &cd) const
get value at parametric coordinate
Definition: CrvLinearLgn.h:289
const string find_type_name(float *)
Definition: TypeName.cc:63
Class with weights and coordinates for 1st order Gaussian integration.
Definition: CrvLinearLgn.h:199
static SCISHARE int unit_edges[1][2]
References to vertices of unit edge.
Definition: CrvLinearLgn.h:53
static T GaussianPoints[1][1]
Definition: CrvLinearLgn.h:203
void get_derivate_weights(const VECTOR &coords, double *w) const
Definition: CrvLinearLgn.h:283
static int domain_dimension()
return dimension of domain
Definition: CrvLinearLgn.h:60
static const std::string type_name(int n=-1)
Definition: CrvLinearLgn.h:359
Definition: CrvLinearLgn.h:139
Class for creating geometrical approximations of Crv meshes.
Definition: CrvLinearLgn.h:99
const char * name[]
Definition: BoostGraphExampleTests.cc:87
void get_weights(const VECTOR &coords, double *w) const
Definition: CrvLinearLgn.h:279
Definition: StackVector.h:50
static double area(int)
return area
Definition: CrvLinearLgn.h:92
CrvApprox()
Definition: CrvLinearLgn.h:101
static int GaussianNum
Definition: CrvLinearLgn.h:202
bool get_coords(const ElemBasis *pEB, VECTOR &coords, const T &value, const ElemData &cd) const
find coordinate in interpolation for given value
Definition: CrvLinearLgn.h:148
static T GaussianPoints[2][1]
Definition: CrvLinearLgn.h:222
double get_volume(const ElemData &) const
get volume
Definition: CrvLinearLgn.h:330
static double length(int)
return length
Definition: CrvLinearLgn.h:91
virtual void io(Piostream &str)
Definition: CrvLinearLgn.h:400
static T GaussianPoints[3][1]
Definition: CrvLinearLgn.h:241
T value_type
Definition: CrvLinearLgn.h:270
Class with weights and coordinates for 2nd order Gaussian integration.
Definition: CrvLinearLgn.h:218
static double domain_size()
return size of the domain
Definition: CrvLinearLgn.h:64
static const std::string make_template_id(const std::string &templateName, const std::string &templateParam)
Definition: TypeName.h:62
static int dofs()
return degrees of freedom
Definition: CrvLinearLgn.h:76
static int GaussianNum
Definition: CrvLinearLgn.h:221
static double volume()
return volume
Definition: CrvLinearLgn.h:93
static int GaussianNum
Definition: CrvLinearLgn.h:240
bool compare_distance(const T &interp, const T &val, double &cur_d, double dist)
Definition: Locate.h:667
virtual void end_class()
Definition: Persistent.cc:178
bool get_iterative(const ElemBasis *pElem, VECTOR &x, const T &value, const ElemData &cd) const
find value in interpolation for given value
Definition: Locate.h:638
const int CRVLINEARLGN_VERSION
Definition: CrvLinearLgn.h:397
virtual ~CrvLinearLgnUnitElement()
Definition: CrvLinearLgn.h:57
void initial_guess(const ElemBasis *pElem, const T &val, const ElemData &cd, VECTOR &guess) const
Definition: CrvLinearLgn.h:171
Definition: CrvLinearLgn.h:261
void resize(size_t size, const value_type &val=value_type())
Definition: StackVector.h:61
Definition: Locate.h:547
void approx_edge(const unsigned, const unsigned, std::vector< VECTOR > &coords) const
Definition: CrvLinearLgn.h:336
virtual ~CrvLocate()
Definition: CrvLinearLgn.h:144
static SCISHARE double unit_center[1]
Definition: CrvLinearLgn.h:54
void approx_edge(const unsigned, const unsigned div_per_unit, VECTOR &coords) const
Definition: CrvLinearLgn.h:108
int n
Definition: eab.py:9
virtual ~CrvLinearLgn()
Definition: CrvLinearLgn.h:273
CrvLinearLgnUnitElement()
Definition: CrvLinearLgn.h:56
static int vertices_of_face()
return number of vertices per face
Definition: CrvLinearLgn.h:84
void get_linear_weights(const VECTOR &coords, double *w) const
Definition: CrvElementWeights.h:42
double get_area(const unsigned, const ElemData &) const
get area
Definition: CrvLinearLgn.h:323
Class with weights and coordinates for 3rd order Gaussian integration.
Definition: CrvLinearLgn.h:237
virtual ~CrvApprox()
Definition: CrvLinearLgn.h:102
Definition: TypeDescription.h:49
static T GaussianWeights[1]
Definition: CrvLinearLgn.h:204
void derivate(const VECTOR1 &, const ElemData &cd, VECTOR2 &derivs) const
get first derivative at parametric coordinate
Definition: CrvLinearLgn.h:298
const TypeDescription * get_type_description(Core::Basis::ConstantBasis< T > *)
Definition: Constant.h:209