SCIRun  5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Locate.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 Locate.h
29 /// @author Martin Cole, Frank B. Sachse
30 /// @date Oct 08 2005
31 
32 #ifndef CORE_BASIS_LOCATE_H
33 #define CORE_BASIS_LOCATE_H 1
34 
35 #include <cmath>
36 
40 #include <Core/Utils/Exception.h>
41 
42 #include <Core/Basis/share.h>
43 
44 namespace SCIRun {
45 
46  template<class T>
47  inline T InverseMatrix3x3(const T *p, T *q)
48  {
49  const T a=p[0], b=p[1], c=p[2];
50  const T d=p[3], e=p[4], f=p[5];
51  const T g=p[6], h=p[7], i=p[8];
52 
53  const T detp=a*e*i-c*e*g+b*f*g+c*d*h-a*f*h-b*d*i;
54  const T detinvp=(detp ? 1.0/detp : 0);
55 
56  q[0]=(e*i-f*h)*detinvp;
57  q[1]=(c*h-b*i)*detinvp;
58  q[2]=(b*f-c*e)*detinvp;
59  q[3]=(f*g-d*i)*detinvp;
60  q[4]=(a*i-c*g)*detinvp;
61  q[5]=(c*d-a*f)*detinvp;
62  q[6]=(d*h-e*g)*detinvp;
63  q[7]=(b*g-a*h)*detinvp;
64  q[8]=(a*e-b*d)*detinvp;
65 
66  return detp;
67  }
68 
69 
70  /// Inline templated inverse matrix
71  template <class PointVector>
72  double InverseMatrix3P(const PointVector& p, double *q)
73  {
74  const double a=p[0].x(), b=p[0].y(), c=p[0].z();
75  const double d=p[1].x(), e=p[1].y(), f=p[1].z();
76  const double g=p[2].x(), h=p[2].y(), i=p[2].z();
77 
78  const double detp=a*e*i-c*e*g+b*f*g+c*d*h-a*f*h-b*d*i;
79  const double detinvp=(detp ? 1.0/detp : 0);
80 
81  q[0]=(e*i-f*h)*detinvp;
82  q[1]=(c*h-b*i)*detinvp;
83  q[2]=(b*f-c*e)*detinvp;
84  q[3]=(f*g-d*i)*detinvp;
85  q[4]=(a*i-c*g)*detinvp;
86  q[5]=(c*d-a*f)*detinvp;
87  q[6]=(d*h-e*g)*detinvp;
88  q[7]=(b*g-a*h)*detinvp;
89  q[8]=(a*e-b*d)*detinvp;
90 
91  return detp;
92  }
93 
94  template<class T>
95  inline T DetMatrix3x3(const T *p)
96  {
97  const T a=p[0], b=p[1], c=p[2];
98  const T d=p[3], e=p[4], f=p[5];
99  const T g=p[6], h=p[7], i=p[8];
100 
101  const T detp=a*e*i-c*e*g+b*f*g+c*d*h-a*f*h-b*d*i;
102  return detp;
103  }
104 
105  template<class T>
106  inline T ScaledDetMatrix3x3(const T *p)
107  {
108  const T a=p[0], b=p[1], c=p[2];
109  const T d=p[3], e=p[4], f=p[5];
110  const T g=p[6], h=p[7], i=p[8];
111 
112  const T detp=a*e*i-c*e*g+b*f*g+c*d*h-a*f*h-b*d*i;
113  const T s = sqrt((a*a+b*b+c*c)*(d*d+e*e+f*f)*(g*g+h*h+i*i));
114  return (detp/s);
115  }
116 
117 
118  /// Inline templated determinant of matrix
119  template <class VectorOfPoints>
120  double DetMatrix3P(const VectorOfPoints& p)
121  {
122  const double a=p[0].x(), b=p[0].y(), c=p[0].z();
123  const double d=p[1].x(), e=p[1].y(), f=p[1].z();
124  const double g=p[2].x(), h=p[2].y(), i=p[2].z();
125 
126  const double detp=a*e*i-c*e*g+b*f*g+c*d*h-a*f*h-b*d*i;
127  return detp;
128  }
129 
130  /// Inline templated determinant of matrix
131  template <class VectorOfPoints>
132  double ScaledDetMatrix3P(const VectorOfPoints& p)
133  {
134  const double a=p[0].x(), b=p[0].y(), c=p[0].z();
135  const double d=p[1].x(), e=p[1].y(), f=p[1].z();
136  const double g=p[2].x(), h=p[2].y(), i=p[2].z();
137 
138  const double detp=a*e*i-c*e*g+b*f*g+c*d*h-a*f*h-b*d*i;
139  const double s = std::sqrt((a*a+b*b+c*c)*(d*d+e*e+f*f)*(g*g+h*h+i*i));
140  return (detp/s);
141  }
142 
143  namespace Core {
144  namespace Basis {
145 
146  /// default case for volume calculation - currently not needed
147  template <class VECTOR, class T>
148  inline double d_volume_type(const VECTOR& /*derivs*/, T* /*type*/)
149  {
150  return (0.0);
151  }
152 
153  /// Specific implementation for Point
154  template<class VECTOR>
155  inline double d_volume_type(const VECTOR& derivs, Geometry::Point* /*type*/)
156  {
157  double J[9];
158  J[0]=derivs[0].x();
159  J[3]=derivs[0].y();
160  J[6]=derivs[0].z();
161  J[1]=derivs[1].x();
162  J[4]=derivs[1].y();
163  J[7]=derivs[1].z();
164  J[2]=derivs[2].x();
165  J[5]=derivs[2].y();
166  J[8]=derivs[2].z();
167 
168  return DetMatrix3x3(J);
169  }
170 
171  /// calculate volume
172  template <class VECTOR>
173  inline double d_volume(const VECTOR& derivs)
174  {
175  return(d_volume_type(derivs,static_cast<typename VECTOR::value_type*>(0)));
176  }
177 
178  template <class ElemBasis, class ElemData>
179  double get_volume3(const ElemBasis *pEB, const ElemData &cd)
180  {
181  double volume=0.0;
182 
183  /// impelementation that is pure on stack
184  StackVector<double,3> coords;
185  for(int i=0; i<ElemBasis::GaussianNum; i++)
186  {
187  coords[0]=ElemBasis::GaussianPoints[i][0];
188  coords[1]=ElemBasis::GaussianPoints[i][1];
189  coords[2]=ElemBasis::GaussianPoints[i][2];
190 
192  pEB->derivate(coords, cd, derivs);
193  volume+=ElemBasis::GaussianWeights[i]*d_volume(derivs);
194  }
195  return volume*pEB->volume();
196  }
197 
198  /// area calculation on points
199  template <class VECTOR1, class VECTOR2>
200  inline double d_area_type(const VECTOR1& derivs, const VECTOR2& dv0, const VECTOR2& dv1, Geometry::Point* type)
201  {
202  const unsigned int dvsize = derivs.size();
203 
204  ENSURE_DIMENSIONS_MATCH(dv0.size(), dvsize, "Vector dv0 size not equal to derivs Vector size");
205  ENSURE_DIMENSIONS_MATCH(dv1.size(), dvsize, "Vector dv0 size not equal to derivs Vector size");
206 
207  Geometry::Vector Jdv0(0,0,0), Jdv1(0,0,0);
208  for(unsigned int i = 0; i<dvsize; i++) {
209  Jdv0+=dv0[i]*Geometry::Vector(derivs[i].x(), derivs[i].y(), derivs[i].z());
210  Jdv1+=dv1[i]*Geometry::Vector(derivs[i].x(), derivs[i].y(), derivs[i].z());
211  }
212 
213  return Cross(Jdv0, Jdv1).length();
214  }
215 
216  /// General template for any type of combination of containers
217  template<class VECTOR1, class VECTOR2>
218  inline double d_area(const VECTOR1& derivs, const VECTOR2& dv0, const VECTOR2& dv1)
219  {
220  return(d_area_type(derivs,dv0,dv1,static_cast<typename VECTOR1::value_type*>(0)));
221  }
222 
223 
224 
225  template <class NumApprox, class ElemBasis, class ElemData>
226  double get_area2(const ElemBasis *pEB, const unsigned face,
227  const ElemData &cd)
228  {
229  const double *v0 = pEB->unit_vertices[pEB->unit_faces[face][0]];
230  const double *v1 = pEB->unit_vertices[pEB->unit_faces[face][1]];
231  const double *v2 = pEB->unit_vertices[pEB->unit_faces[face][2]];
232 
235 
236  d0[0]=v1[0]-v0[0];
237  d0[1]=v1[1]-v0[1];
238  d1[0]=v2[0]-v0[0];
239  d1[1]=v2[1]-v0[1];
240  double area=0.;
241 
242  StackVector<double,2> coords;
243  for(int i=0; i<NumApprox::GaussianNum; i++) {
244  coords[0]=v0[0]+NumApprox::GaussianPoints[i][0]*d0[0]+NumApprox::GaussianPoints[i][1]*d1[0];
245  coords[1]=v0[1]+NumApprox::GaussianPoints[i][0]*d0[1]+NumApprox::GaussianPoints[i][1]*d1[1];
246 
248  pEB->derivate(coords, cd, derivs);
249  area+=NumApprox::GaussianWeights[i]*d_area(derivs, d0, d1);
250  }
251  return (area*pEB->area(face));
252  }
253 
254 
255 
256  template <class NumApprox, class ElemBasis, class ElemData>
257  double get_area3(const ElemBasis *pEB, const unsigned face,
258  const ElemData &cd)
259  {
260  const double *v0 = pEB->unit_vertices[pEB->unit_faces[face][0]];
261  const double *v1 = pEB->unit_vertices[pEB->unit_faces[face][1]];
262  const double *v2 = pEB->unit_vertices[pEB->unit_faces[face][2]];
263 
266  d0[0]=v1[0]-v0[0];
267  d0[1]=v1[1]-v0[1];
268  d0[2]=v1[2]-v0[2];
269  d1[0]=v2[0]-v0[0];
270  d1[1]=v2[1]-v0[1];
271  d1[2]=v2[2]-v0[2];
272  double area=0.;
273 
274  StackVector<double,3> coords;
275  for(int i=0; i<NumApprox::GaussianNum; i++) {
276  coords[0]=v0[0]+NumApprox::GaussianPoints[i][0]*d0[0]+NumApprox::GaussianPoints[i][1]*d1[0];
277  coords[1]=v0[1]+NumApprox::GaussianPoints[i][0]*d0[1]+NumApprox::GaussianPoints[i][1]*d1[1];
278  coords[2]=v0[2]+NumApprox::GaussianPoints[i][0]*d0[2]+NumApprox::GaussianPoints[i][1]*d1[2];
279 
281  pEB->derivate(coords, cd, derivs);
282 
283  area+=NumApprox::GaussianWeights[i]*d_area(derivs, d0, d1);
284  }
285  return (area*pEB->area(face));
286  }
287 
288  /// arc length calculation on points
289  template <class VECTOR1, class VECTOR2>
290  inline double d_arc_length(const VECTOR1& derivs, const VECTOR2& dv, Geometry::Point* type)
291  {
292  const unsigned int dvsize = dv.size();
293 
294  ENSURE_DIMENSIONS_MATCH(derivs.size(), dvsize, "Vector dv0 size not equal to derivs Vector size");
295 
296  double Jdv[3];
297  Jdv[0] = Jdv[1] = Jdv[2] = 0.;
298  for(unsigned int i = 0; i<dvsize; i++) {
299  Jdv[0]+=dv[i]*derivs[i].x();
300  Jdv[1]+=dv[i]*derivs[i].y();
301  Jdv[2]+=dv[i]*derivs[i].z();
302  }
303 
304  return sqrt(Jdv[0]*Jdv[0]+Jdv[1]*Jdv[1]+Jdv[2]*Jdv[2]);
305  }
306 
307 
308  template <class VECTOR1, class VECTOR2>
309  inline double d_arc_length(const VECTOR1& derivs, const VECTOR2& dv)
310  {
311  return(d_arc_length_type(derivs,dv,static_cast<typename VECTOR1::value_type*>(0)));
312  }
313 
314 
315  template <class NumApprox, class ElemBasis, class ElemData>
316  double get_arc1d_length(const ElemBasis *pEB, const unsigned edge,
317  const ElemData &cd)
318  {
319  const double *v0 = pEB->unit_vertices[pEB->unit_edges[edge][0]];
320  const double *v1 = pEB->unit_vertices[pEB->unit_edges[edge][1]];
322  dv[0]=v1[0]-v0[0];
323  double arc_length=0.;
324 
325  StackVector<double,1> coords;
326  for(int i=0; i<NumApprox::GaussianNum; i++) {
327  coords[0]=v0[0]+NumApprox::GaussianPoints[i][0]*dv[0];
329  pEB->derivate(coords, cd, derivs);
330 
331  arc_length+=NumApprox::GaussianWeights[i]*d_arc_length(derivs, dv);
332  }
333  return arc_length;
334  }
335 
336 
337  template <class NumApprox, class ElemBasis, class ElemData>
338  double get_arc2d_length(const ElemBasis *pEB, const unsigned edge,
339  const ElemData &cd)
340  {
341  const double *v0 = pEB->unit_vertices[pEB->unit_edges[edge][0]];
342  const double *v1 = pEB->unit_vertices[pEB->unit_edges[edge][1]];
344  dv[0]=v1[0]-v0[0];
345  dv[1]=v1[1]-v0[1];
346  double arc_length=0.;
347 
348  StackVector<double,2> coords;
349  for(int i=0; i<NumApprox::GaussianNum; i++) {
350  coords[0]=v0[0]+NumApprox::GaussianPoints[i][0]*dv[0];
351  coords[1]=v0[1]+NumApprox::GaussianPoints[i][0]*dv[1];
353  pEB->derivate(coords, cd, derivs);
354  arc_length+=NumApprox::GaussianWeights[i]*d_arc_length(derivs, dv);
355  }
356  return arc_length;
357  }
358 
359 
360  template <class NumApprox, class ElemBasis, class ElemData>
361  double get_arc3d_length(const ElemBasis *pEB, const unsigned edge,
362  const ElemData &cd)
363  {
364  const double *v0 = pEB->unit_vertices[pEB->unit_edges[edge][0]];
365  const double *v1 = pEB->unit_vertices[pEB->unit_edges[edge][1]];
367  dv[0]=v1[0]-v0[0];
368  dv[1]=v1[1]-v0[1];
369  dv[2]=v1[2]-v0[2];
370  double arc_length=0.;
371 
372  StackVector<double,3> coords;
373  for(int i=0; i<NumApprox::GaussianNum; i++) {
374  coords[0]=v0[0]+NumApprox::GaussianPoints[i][0]*dv[0];
375  coords[1]=v0[1]+NumApprox::GaussianPoints[i][0]*dv[1];
376  coords[2]=v0[2]+NumApprox::GaussianPoints[i][0]*dv[2];
378  pEB->derivate(coords, cd, derivs);
379  arc_length+=NumApprox::GaussianWeights[i]*d_arc_length(derivs, dv);
380  }
381  return arc_length;
382  }
383 
384 
385  //default case
386  template <class T>
387  inline T difference(const T& interp, const T& value)
388  {
389  return interp - value;
390  }
391 
392  template <>
393  inline Geometry::Point difference(const Geometry::Point& interp, const Geometry::Point& value)
394  {
395  return (interp - value).point();
396  }
397 
398 
399  template <class VECTOR1, class VECTOR2, class T>
400  inline double getnextx1(VECTOR1 &x,
401  const T& y, const VECTOR2& yd)
402  {
403  double dx;
404  if (yd[0])
405  {
406  dx = y/yd[0];
407  x[0] -= dx;
408  }
409  else
410  dx = 0;
411  return sqrt(dx*dx);
412  }
413 
414  template <class VECTOR1, class VECTOR2>
415  inline double getnextx1(VECTOR1 &x,
416  const Geometry::Point& y, const VECTOR2& yd)
417  {
418  const Geometry::Point &yd0 = yd[0];
419 
420  const double dx = ((yd0.x() ? y.x()/yd0.x() : 0)+(yd0.y() ? y.y()/yd0.y() : 0)+(yd0.z() ? y.z()/yd0.z() : 0))/3.0;
421  x[0] -= dx;
422 
423  return sqrt(dx*dx);
424  }
425 
426 
427  template <class VECTOR1, class VECTOR2, class T>
428  double getnextx2(VECTOR1 &x,
429  const T& y, const VECTOR2& yd)
430  {
431  double dx, dy;
432  if (yd[0]) {
433  dx = y/yd[0];
434  x[0] -= dx;
435  }
436  else
437  dx = 0;
438 
439  if (yd[1]) {
440  dy = y/yd[1];
441  x[1] -= dy;
442  }
443  else
444  dy = 0;
445 
446  return sqrt(dx*dx+dy*dy);
447  }
448 
449  template <class VECTOR1, class VECTOR2>
450  double getnextx2(VECTOR1 &x,
451  const Geometry::Point& y, const VECTOR2& yd)
452  {
453  const double J00=yd[0].x();
454  const double J10=yd[0].y();
455  const double J20=yd[0].z();
456  const double J01=yd[1].x();
457  const double J11=yd[1].y();
458  const double J21=yd[1].z();
459  const double detJ=-J10*J01+J10*J21-J00*J21-J11*J20+J11*J00+J01*J20;
460  const double F1=y.x();
461  const double F2=y.y();
462  const double F3=y.z();
463 
464  if (detJ) {
465  double dx=(F2*J01-F2*J21+J21*F1-J11*F1+F3*J11-J01*F3)/detJ;
466  double dy=-(-J20*F2+J20*F1+J00*F2+F3*J10-F3*J00-F1*J10)/detJ;
467 
468  x[0] += dx;
469  x[1] += dy;
470  return sqrt(dx*dx+dy*dy);
471  }
472  else
473  return 0;
474  }
475 
476 
477  template <class VECTOR1, class VECTOR2, class T>
478  double getnextx3(VECTOR1 &x,
479  const T& y, const VECTOR2& yd)
480  {
481  double dx, dy, dz;
482  if (yd[0]) {
483  dx = y/yd[0];
484  x[0] -= dx;
485  }
486  else
487  dx = 0;
488 
489  if (yd[1]) {
490  dy = y/yd[1];
491  x[1] -= dy;
492  }
493  else
494  dy = 0;
495 
496  if (yd[2]) {
497  dz = y/yd[2];
498  x[2] -= dz;
499  }
500  else
501  dz = 0;
502 
503  return sqrt(dx*dx+dy*dy+dz*dz);
504  }
505 
506 
507  template <class VECTOR1, class VECTOR2>
508  double getnextx3(VECTOR1 &x,
509  const Geometry::Point& y, const VECTOR2& yd)
510  {
511  double J[9], JInv[9];
512 
513  J[0]=yd[0].x();
514  J[3]=yd[0].y();
515  J[6]=yd[0].z();
516  J[1]=yd[1].x();
517  J[4]=yd[1].y();
518  J[7]=yd[1].z();
519  J[2]=yd[2].x();
520  J[5]=yd[2].y();
521  J[8]=yd[2].z();
522 
523  InverseMatrix3x3(J, JInv);
524 
525  const double dx= JInv[0]*y.x()+JInv[1]*y.y()+JInv[2]*y.z();
526  const double dy= JInv[3]*y.x()+JInv[4]*y.y()+JInv[5]*y.z();
527  const double dz= JInv[6]*y.x()+JInv[7]*y.y()+JInv[8]*y.z();
528 
529  x[0] -= dx;
530  x[1] -= dy;
531  x[2] -= dz;
532 
533  return sqrt(dx*dx+dy*dy+dz*dz);
534  }
535 
536 
537  /// Class for searching of parametric coordinates related to a
538  /// value in 3d meshes and fields
539  /// More general function: find value in interpolation for given value
540  /// Step 1: get a good guess on the domain, evaluate equally spaced points
541  /// on the domain and use the closest as our starting point for
542  /// Newton iteration. (implemented in derived class)
543  /// Step 2: Newton iteration.
544  /// x_n+1 =x_n + y(x_n) * y'(x_n)^-1
545 
546  template <class ElemBasis>
547  class Dim3Locate {
548  public:
549  typedef typename ElemBasis::value_type T;
550  static const double thresholdDist; ///< Thresholds for coordinates checks
551  static const double thresholdDist1; ///< 1+thresholdDist
552  static const int maxsteps; ///< maximal steps for Newton search
553 
555  virtual ~Dim3Locate() {}
556 
557  /// find value in interpolation for given value
558  template <class ElemData, class VECTOR>
559  bool get_iterative(const ElemBasis *pEB, VECTOR &x,
560  const T& value, const ElemData &cd) const
561  {
562  StackVector<T,3> yd;
563  for (int steps=0; steps<maxsteps; steps++)
564  {
565  T y = difference(pEB->interpolate(x, cd), value);
566  pEB->derivate(x, cd, yd);
567  double dist=getnextx3(x, y, yd);
568  if (dist < thresholdDist)
569  return true;
570  }
571  return false;
572  }
573  };
574 
575  template<class ElemBasis>
576  const double Dim3Locate<ElemBasis>::thresholdDist=1e-7;
577  template<class ElemBasis>
579  template<class ElemBasis>
580  const int Dim3Locate<ElemBasis>::maxsteps=100;
581 
582  /// Class for searching of parametric coordinates related to a
583  /// value in 2d meshes and fields
584  template <class ElemBasis>
585  class Dim2Locate {
586  public:
587  typedef typename ElemBasis::value_type T;
588  static const double thresholdDist; ///< Thresholds for coordinates checks
589  static const double thresholdDist1; ///< 1+thresholdDist
590  static const int maxsteps; ///< maximal steps for Newton search
591 
593  virtual ~Dim2Locate() {}
594 
595  /// find value in interpolation for given value
596  template <class ElemData, class VECTOR>
597  bool get_iterative(const ElemBasis *pEB, VECTOR &x,
598  const T& value, const ElemData &cd) const
599  {
600  StackVector<T,2> yd;
601  for (int steps=0; steps<maxsteps; steps++)
602  {
603  T y = difference(pEB->interpolate(x, cd), value);
604  pEB->derivate(x, cd, yd);
605  double dist=getnextx2(x, y, yd);
606  if (dist < thresholdDist)
607  return true;
608  }
609  return false;
610  }
611  };
612 
613  template<class ElemBasis>
614  const double Dim2Locate<ElemBasis>::thresholdDist=1e-7;
615  template<class ElemBasis>
618  template<class ElemBasis>
619  const int Dim2Locate<ElemBasis>::maxsteps=100;
620 
621 
622  /// Class for searching of parametric coordinates related to a
623  /// value in 1d meshes and fields
624  template <class ElemBasis>
625  class Dim1Locate {
626  public:
627 
628  typedef typename ElemBasis::value_type T;
629  static const double thresholdDist; ///< Thresholds for coordinates checks
630  static const double thresholdDist1; ///< 1+thresholdDist
631  static const int maxsteps; ///< maximal steps for Newton search
632 
634  virtual ~Dim1Locate() {}
635 
636  /// find value in interpolation for given value
637  template <class ElemData, class VECTOR>
638  bool get_iterative(const ElemBasis *pElem, VECTOR &x,
639  const T& value, const ElemData &cd) const
640  {
641  StackVector<T,1> yd;
642 
643  for (int steps=0; steps<maxsteps; steps++)
644  {
645  T y = difference(pElem->interpolate(x, cd), value);
646  pElem->derivate(x, cd, yd);
647  double dist=getnextx1(x, y, yd);
648  if (dist < thresholdDist)
649  return true;
650  }
651  return false;
652  }
653  };
654 
655  template<class ElemBasis>
656  const double Dim1Locate<ElemBasis>::thresholdDist=1e-7;
657  template<class ElemBasis>
659  template<class ElemBasis>
660  const int Dim1Locate<ElemBasis>::maxsteps=100;
661 
662 
663 
664 
665  // default case compiles for scalar types
666  template <class T>
667  inline bool compare_distance(const T &interp, const T &val,
668  double &cur_d, double dist)
669  {
670  double dv = interp - val;
671  cur_d = sqrt(dv*dv);
672  return cur_d < dist;
673  }
674 
675  inline bool compare_distance(const Geometry::Point &interp, const Geometry::Point &val,
676  double &cur_d, double dist)
677  {
678  Geometry::Vector v = interp - val;
679  cur_d = v.length();
680  return cur_d < dist;
681  }
682 
683  template <class VECTOR, class T>
684  inline bool check_zero_type(const VECTOR &val, T* /*type*/,double epsilon)
685  {
686  typename VECTOR::const_iterator iter = val.begin();
687  while(iter != val.end())
688  {
689  const T &v=*iter++;
690  if (fabs(v)>epsilon) return false;
691  }
692  return true;
693  }
694 
695  template <class VECTOR>
696  inline bool check_zero_type(const VECTOR &val, Geometry::Point* /*type*/, double epsilon)
697  {
698  typename VECTOR::const_iterator iter = val.begin();
699  while(iter != val.end())
700  {
701  const Geometry::Point &v=*iter++;
702  if (fabs(v.x())>epsilon || fabs(v.y())>epsilon || fabs(v.z())>epsilon)
703  return false;
704  }
705  return true;
706  }
707 
708  template <class VECTOR>
709  inline double check_zero(const VECTOR& derivs,double epsilon = 1e-7)
710  {
711  return(check_zero_type(derivs,static_cast<typename VECTOR::value_type*>(0),epsilon));
712  }
713 
714 }}}
715 
716 #endif
virtual ~Dim2Locate()
Definition: Locate.h:593
Interface to statically allocated std::vector class.
double getnextx1(VECTOR1 &x, const T &y, const VECTOR2 &yd)
Definition: Locate.h:400
double d_area(const VECTOR1 &derivs, const VECTOR2 &dv0, const VECTOR2 &dv1)
General template for any type of combination of containers.
Definition: Locate.h:218
static const int maxsteps
maximal steps for Newton search
Definition: Locate.h:631
double check_zero(const VECTOR &derivs, double epsilon=1e-7)
Definition: Locate.h:709
static const int maxsteps
maximal steps for Newton search
Definition: Locate.h:590
double get_arc1d_length(const ElemBasis *pEB, const unsigned edge, const ElemData &cd)
Definition: Locate.h:316
double get_area2(const ElemBasis *pEB, const unsigned face, const ElemData &cd)
Definition: Locate.h:226
double InverseMatrix3P(const PointVector &p, double *q)
Inline templated inverse matrix.
Definition: Locate.h:72
void y(const double)
Definition: Point.h:135
double d_arc_length(const VECTOR1 &derivs, const VECTOR2 &dv, Geometry::Point *type)
arc length calculation on points
Definition: Locate.h:290
bool check_zero_type(const VECTOR &val, T *, double epsilon)
Definition: Locate.h:684
Definition: Point.h:49
double getnextx2(VECTOR1 &x, const T &y, const VECTOR2 &yd)
Definition: Locate.h:428
static const double thresholdDist
Thresholds for coordinates checks.
Definition: Locate.h:550
T difference(const T &interp, const T &value)
Definition: Locate.h:387
Definition: Locate.h:625
ElemBasis::value_type T
Definition: Locate.h:549
static const double thresholdDist
Thresholds for coordinates checks.
Definition: Locate.h:629
ElemBasis::value_type T
Definition: Locate.h:587
Definition: Vector.h:63
Dim2Locate()
Definition: Locate.h:592
double DetMatrix3P(const VectorOfPoints &p)
Inline templated determinant of matrix.
Definition: Locate.h:120
void z(const double)
Definition: Point.h:145
virtual ~Dim3Locate()
Definition: Locate.h:555
static const int maxsteps
maximal steps for Newton search
Definition: Locate.h:552
T DetMatrix3x3(const T *p)
Definition: Locate.h:95
double d_volume(const VECTOR &derivs)
calculate volume
Definition: Locate.h:173
void x(const double)
Definition: Point.h:125
virtual ~Dim1Locate()
Definition: Locate.h:634
double get_area3(const ElemBasis *pEB, const unsigned face, const ElemData &cd)
Definition: Locate.h:257
Vector Cross(const Vector &v1, const Vector &v2)
Definition: Vector.h:378
static const double thresholdDist
Thresholds for coordinates checks.
Definition: Locate.h:588
double ScaledDetMatrix3P(const VectorOfPoints &p)
Inline templated determinant of matrix.
Definition: Locate.h:132
Definition: Locate.h:585
double d_volume_type(const VECTOR &, T *)
default case for volume calculation - currently not needed
Definition: Locate.h:148
double get_arc2d_length(const ElemBasis *pEB, const unsigned edge, const ElemData &cd)
Definition: Locate.h:338
v
Definition: readAllFields.py:42
#define ENSURE_DIMENSIONS_MATCH(var1, var2, message)
Definition: Exception.h:93
Dim1Locate()
Definition: Locate.h:633
bool compare_distance(const T &interp, const T &val, double &cur_d, double dist)
Definition: Locate.h:667
double length() const
Definition: Vector.h:365
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
T ScaledDetMatrix3x3(const T *p)
Definition: Locate.h:106
static const double thresholdDist1
1+thresholdDist
Definition: Locate.h:551
Definition: Locate.h:547
double getnextx3(VECTOR1 &x, const T &y, const VECTOR2 &yd)
Definition: Locate.h:478
static const double thresholdDist1
1+thresholdDist
Definition: Locate.h:589
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
T InverseMatrix3x3(const T *p, T *q)
Definition: Locate.h:47
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 const double thresholdDist1
1+thresholdDist
Definition: Locate.h:630
double get_volume3(const ElemBasis *pEB, const ElemData &cd)
Definition: Locate.h:179
double get_arc3d_length(const ElemBasis *pEB, const unsigned edge, const ElemData &cd)
Definition: Locate.h:361
Dim3Locate()
Definition: Locate.h:554
double d_area_type(const VECTOR1 &derivs, const VECTOR2 &dv0, const VECTOR2 &dv1, Geometry::Point *type)
area calculation on points
Definition: Locate.h:200
ElemBasis::value_type T
Definition: Locate.h:628