SCIRun  5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
StructHexVolMesh.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 
29 ///@details
30 /// A structured grid is a dataset with regular topology but with irregular
31 /// geometry.
32 ///
33 /// The grid may have any shape but can not be overlapping or
34 /// self-intersecting.
35 ///
36 /// The topology of a structured grid is represented using 2D, or 3D vector
37 /// with the points being stored in an index based array. The faces
38 /// (quadrilaterals) and cells (Hexahedron) are implicitly define based
39 /// based upon their indexing.
40 ///
41 /// Structured grids are typically used in finite difference analysis.
42 ///
43 /// For more information on datatypes see Schroeder, Martin, and Lorensen,
44 /// "The Visualization Toolkit", Prentice Hall, 1998.
45 ///
46 
47 
48 #ifndef CORE_DATATYPES_STRUCTHEXVOLMESH_H
49 #define CORE_DATATYPES_STRUCTHEXVOLMESH_H 1
50 
51 /// Include what kind of support we want to have
52 /// Need to fix this and couple it to sci-defs
54 
55 #include <Core/Thread/Mutex.h>
56 #include <Core/Containers/Array3.h>
58 
61 
63 
64 /// Incude needed for Windows: declares SCISHARE
66 
67 namespace SCIRun {
68 
69 /// Declarations for virtual interface
70 
71 
72 /// Functions for creating the virtual interface
73 /// Declare the functions that instantiate the virtual interface
74 template <class Basis>
76 
77 /// make sure any other mesh other than the preinstantiate ones
78 /// returns no virtual interface. Altering this behavior will allow
79 /// for dynamically compiling the interface if needed.
80 template<class MESH>
81 VMesh* CreateVStructHexVolMesh(MESH* mesh) { return (0); }
82 
83 /// These declarations are needed for a combined dynamic compilation as
84 /// as well as virtual functions solution.
85 /// Declare that these can be found in a library that is already
86 /// precompiled. So dynamic compilation will not instantiate them again.
87 
88 #if (SCIRUN_STRUCTHEXVOL_SUPPORT > 0)
89 
90 SCISHARE VMesh* CreateVStructHexVolMesh(StructHexVolMesh<Core::Basis::HexTrilinearLgn<Core::Geometry::Point> >* mesh);
91 
92 #endif
93 
94 
95 template <class Basis>
96 class StructHexVolMesh : public LatVolMesh<Basis>
97 {
98 
99 template <class MESH>
100 friend class VStructHexVolMesh;
101 
102 public:
103  /// Types that change depending on 32 or 64bits
108 
109  typedef boost::shared_ptr<StructHexVolMesh<Basis> > handle_type;
110 
114  virtual StructHexVolMesh *clone() const { return new StructHexVolMesh<Basis>(*this); }
115  virtual ~StructHexVolMesh()
116  {
117  DEBUG_DESTRUCTOR("StructHexVolMesh")
118  }
119 
120  class ElemData
121  {
122  public:
124 
126  const typename LatVolMesh<Basis>::Cell::index_type ind) :
127  mesh_(msh),
128  index_(ind)
129  {}
130 
131  /// the following designed to coordinate with ::get_nodes
132  inline
134  return (index_.i_ + mesh_.get_ni()*index_.j_ +
135  mesh_.get_ni()*mesh_.get_nj()*index_.k_);
136  }
137  inline
139  return (index_.i_+ 1 + mesh_.get_ni()*index_.j_ +
140  mesh_.get_ni()*mesh_.get_nj()*index_.k_);
141  }
142  inline
144  return (index_.i_ + 1 + mesh_.get_ni()*(index_.j_ + 1) +
145  mesh_.get_ni()*mesh_.get_nj()*index_.k_);
146 
147  }
148  inline
150  return (index_.i_ + mesh_.get_ni()*(index_.j_ + 1) +
151  mesh_.get_ni()*mesh_.get_nj()*index_.k_);
152  }
153  inline
155  return (index_.i_ + mesh_.get_ni()*index_.j_ +
156  mesh_.get_ni()*mesh_.get_nj()*(index_.k_ + 1));
157  }
158  inline
160  return (index_.i_ + 1 + mesh_.get_ni()*index_.j_ +
161  mesh_.get_ni()*mesh_.get_nj()*(index_.k_ + 1));
162  }
163 
164  inline
166  return (index_.i_ + 1 + mesh_.get_ni()*(index_.j_ + 1) +
167  mesh_.get_ni()*mesh_.get_nj()*(index_.k_ + 1));
168  }
169  inline
171  return (index_.i_ + mesh_.get_ni()*(index_.j_ + 1) +
172  mesh_.get_ni()*mesh_.get_nj()*(index_.k_ + 1));
173  }
174 
175  inline
176  const Core::Geometry::Point &node0() const {
177  return mesh_.points_(index_.k_, index_.j_, index_.i_);
178  }
179  inline
180  const Core::Geometry::Point &node1() const {
181  return mesh_.points_(index_.k_, index_.j_, index_.i_+1);
182  }
183  inline
184  const Core::Geometry::Point &node2() const {
185  return mesh_.points_(index_.k_, index_.j_+1, index_.i_+1);
186  }
187  inline
188  const Core::Geometry::Point &node3() const {
189  return mesh_.points_(index_.k_, index_.j_+1, index_.i_);
190  }
191  inline
192  const Core::Geometry::Point &node4() const {
193  return mesh_.points_(index_.k_+1, index_.j_, index_.i_);
194  }
195  inline
196  const Core::Geometry::Point &node5() const {
197  return mesh_.points_(index_.k_+1, index_.j_, index_.i_+1);
198  }
199  inline
200  const Core::Geometry::Point &node6() const {
201  return mesh_.points_(index_.k_+1, index_.j_+1, index_.i_+1);
202  }
203  inline
204  const Core::Geometry::Point &node7() const {
205  return mesh_.points_(index_.k_+1, index_.j_+1, index_.i_);
206  }
207 
208  private:
209  const StructHexVolMesh<Basis> &mesh_;
210  const typename LatVolMesh<Basis>::Cell::index_type index_;
211 
212  };
213 
214  friend class ElemData;
215 
216  /// get the mesh statistics
217  virtual Core::Geometry::BBox get_bounding_box() const;
218  virtual void transform(const Core::Geometry::Transform &t);
219 
220  virtual bool get_dim(std::vector<size_type>&) const;
221  virtual void set_dim(const std::vector<size_type>& dims) {
222  LatVolMesh<Basis>::ni_ = dims[0];
223  LatVolMesh<Basis>::nj_ = dims[1];
224  LatVolMesh<Basis>::nk_ = dims[2];
225 
226  points_.resize(dims[2], dims[1], dims[0]);
227 
228  /// Create a new virtual interface for this copy
229  /// all pointers have changed hence create a new
230  /// virtual interface class
232  }
233 
234  virtual int topology_geometry() const
235  {
237  }
238 
239  /// get the center point (in object space) of an element
241  const typename LatVolMesh<Basis>::Node::index_type &) const;
245  const typename LatVolMesh<Basis>::Cell::index_type &) const;
246 
247  double get_size(const typename LatVolMesh<Basis>::Node::index_type &idx) const;
248  double get_size(typename LatVolMesh<Basis>::Edge::index_type idx) const;
249  double get_size(typename LatVolMesh<Basis>::Face::index_type idx) const;
250  double get_size(
251  const typename LatVolMesh<Basis>::Cell::index_type &idx) const;
253  { return get_size(idx); };
255  { return get_size(idx); };
256  double get_volume(const
257  typename LatVolMesh<Basis>::Cell::index_type &i) const
258  { return get_size(i); };
259 
261  const Core::Geometry::Point &p) const
262  { return (locate_node(node,p)); }
263 
265  const Core::Geometry::Point &) const
266  { return false; }
268  const Core::Geometry::Point&) const
269  { return false; }
271  const Core::Geometry::Point &p) const
272  { return (locate_elem(elem,p)); }
273 
275  std::vector<double>& coords,
276  const Core::Geometry::Point &p) const
277  { return (locate_elem(elem,coords,p)); }
278 
279  bool find_closest_node(double& pdist, Core::Geometry::Point &result,
280  typename LatVolMesh<Basis>::Node::index_type &node,
281  const Core::Geometry::Point &p) const
282  { return (find_closest_node(pdist,result,node,p,-1.0)); }
283 
284  bool find_closest_node(double& pdist, Core::Geometry::Point &result,
285  typename LatVolMesh<Basis>::Node::index_type &node,
286  const Core::Geometry::Point &p, double maxdist) const;
287 
288  template<class INDEX>
289  bool find_closest_elem(double& pdist,
290  Core::Geometry::Point& result,
291  INDEX& elem,
292  const Core::Geometry::Point& p) const
293  {
294  StackVector<double,3> coords;
295  return(find_closest_elem(pdist,result,coords,elem,p,-1.0));
296  }
297 
298  template<class INDEX, class ARRAY>
299  bool find_closest_elem(double& pdist,
300  Core::Geometry::Point& result,
301  ARRAY& coords,
302  INDEX& elem,
303  const Core::Geometry::Point& p) const
304  {
305  return(find_closest_elem(pdist,result,coords,elem,p,-1.0));
306  }
307 
308  template<class INDEX, class ARRAY>
309  bool find_closest_elem(double& pdist,
310  Core::Geometry::Point& result,
311  ARRAY& coords,
312  INDEX& elem,
313  const Core::Geometry::Point& p,
314  double maxdist) const
315  {
316  /// @todo: Generate bounding boxes for elements and integrate this into the
317  // basis function code.
318 
319  /// If there are no nodes we cannot find a closest point
320  if (this->ni_ == 0 || this->nj_ == 0 || this->nk_ == 0) return (false);
321 
322  if (maxdist < 0.0) maxdist = DBL_MAX; else maxdist = maxdist*maxdist;
323 
324  /// Check whether the estimate given in idx is the point we are looking for
325  if (elem.i_ >= 0 && elem.i_ < (this->ni_-1) &&
326  elem.j_ >= 0 && elem.j_ < (this->nj_-1) &&
327  elem.k_ >= 0 && elem.k_ < (this->nk_-1))
328  {
329  elem.mesh_ = this;
330  if (inside(elem,p))
331  {
332  ElemData ed(*this,elem);
333  this->basis_.get_coords(coords,p,ed);
334  pdist = 0.0;
335  result = p;
336  return (true);
337  }
338  }
339 
340  ASSERTMSG(synchronized_ & Mesh::ELEM_LOCATE_E,
341  "StructHexVolMesh: need to synchronize ELEM_LOCATE_E first");
342 
343 // Find whether we are inside an element
345  if (elem_grid_->lookup(it, eit, p))
346  {
347  while (it != eit)
348  {
349  if (inside(*it, p))
350  {
351  elem = INDEX(*it);
352  ElemData ed(*this,elem);
353  this->basis_.get_coords(coords,p,ed);
354  pdist = 0.0;
355  result = p;
356  return (true);
357  }
358  ++it;
359  }
360  }
361 
362  // Find where we are in terms of boundary elements
363 
364  // If not start searching for the closest outer boundary
365  // get grid sizes
366  const size_type ni = elem_grid_->get_ni()-1;
367  const size_type nj = elem_grid_->get_nj()-1;
368  const size_type nk = elem_grid_->get_nk()-1;
369 
370  // Convert to grid coordinates.
371  index_type bi, ei, bj, ej, bk, ek;
372  elem_grid_->unsafe_locate(bi, bj, bk, p);
373 
374  // Clamp to closest point on the grid.
375  if (bi > ni) bi = ni; if (bi < 0) bi = 0;
376  if (bj > nj) bj = nj; if (bj < 0) bj = 0;
377  if (bk > nk) bk = nk; if (bk < 0) bk = 0;
378 
379  ei = bi; ej = bj; ek = bk;
380 
381  double dmin = maxdist;
382  bool found = true;
383  bool found_one = false;
384 
385  do
386  {
387  found = true;
388  /// We need to do a full shell without any elements that are closer
389  /// to make sure there no closer elements in neighboring searchgrid cells
390  for (index_type i = bi; i <= ei; i++)
391  {
392  if (i < 0 || i > ni) continue;
393  for (index_type j = bj; j <= ej; j++)
394  {
395  if (j < 0 || j > nj) continue;
396  for (index_type k = bk; k <= ek; k++)
397  {
398  if (k < 0 || k > nk) continue;
399  if (i == bi || i == ei || j == bj || j == ej || k == bk || k == ek)
400  {
401  if (elem_grid_->min_distance_squared(p, i, j, k) < dmin)
402  {
403  found = false;
405  elem_grid_->lookup_ijk(it,eit, i, j, k);
406 
407  while (it != eit)
408  {
410  typename LatVolMesh<Basis>::Cell::index_type cidx = (*it);
411 
412  const index_type ii = (*it).i_;
413  const index_type jj = (*it).j_;
414  const index_type kk = (*it).k_;
415  if (ii == 0)
416  {
418  points_(kk,jj,ii),
419  points_(kk,jj+1,ii),
420  points_(kk+1,jj+1,ii),
421  points_(kk+1,jj,ii));
422  const double dtmp = (p - r).length2();
423  if (dtmp < dmin)
424  {
425  found_one = true;
426  result = r;
427  elem = INDEX(cidx);
428  dmin = dtmp;
429 
430  if (dmin < epsilon2_)
431  {
432  ElemData ed(*this,elem);
433  this->basis_.get_coords(coords,result,ed);
434 
435  result = this->basis_.interpolate(coords,ed);
436  pdist = sqrt((result-p).length2());
437  return (true);
438  }
439  }
440  }
441 
442  if (ii == this->ni_-2)
443  {
445  points_(kk,jj,ii+1),
446  points_(kk,jj+1,ii+1),
447  points_(kk+1,jj+1,ii+1),
448  points_(kk+1,jj,ii+1));
449  const double dtmp = (p - r).length2();
450  if (dtmp < dmin)
451  {
452  found_one = true;
453  result = r;
454  elem = INDEX(cidx);
455  dmin = dtmp;
456 
457  if (dmin < epsilon2_)
458  {
459  ElemData ed(*this,elem);
460  this->basis_.get_coords(coords,result,ed);
461 
462  result = this->basis_.interpolate(coords,ed);
463  pdist = sqrt((result-p).length2());
464  return (true);
465  }
466  }
467  }
468 
469  if (jj == 0)
470  {
472  points_(kk,jj,ii),
473  points_(kk,jj,ii+1),
474  points_(kk+1,jj,ii+1),
475  points_(kk+1,jj,ii));
476  const double dtmp = (p - r).length2();
477  if (dtmp < dmin)
478  {
479  found_one = true;
480  result = r;
481  elem = INDEX(cidx);
482  dmin = dtmp;
483 
484  if (dmin < epsilon2_)
485  {
486  ElemData ed(*this,elem);
487  this->basis_.get_coords(coords,result,ed);
488 
489  result = this->basis_.interpolate(coords,ed);
490  pdist = sqrt((result-p).length2());
491  return (true);
492  }
493  }
494  }
495 
496  if (jj == this->nj_-2)
497  {
499  points_(kk,jj+1,ii),
500  points_(kk,jj+1,ii+1),
501  points_(kk+1,jj+1,ii+1),
502  points_(kk+1,jj+1,ii));
503  const double dtmp = (p - r).length2();
504  if (dtmp < dmin)
505  {
506  found_one = true;
507  result = r;
508  elem = INDEX(cidx);
509  dmin = dtmp;
510 
511  if (dmin < epsilon2_)
512  {
513  ElemData ed(*this,elem);
514  this->basis_.get_coords(coords,result,ed);
515 
516  result = this->basis_.interpolate(coords,ed);
517  pdist = sqrt((result-p).length2());
518  return (true);
519  }
520  }
521  }
522 
523  if (kk == 0)
524  {
526  points_(kk,jj,ii),
527  points_(kk,jj,ii+1),
528  points_(kk,jj+1,ii+1),
529  points_(kk,jj+1,ii));
530  const double dtmp = (p - r).length2();
531  if (dtmp < dmin)
532  {
533  found_one = true;
534  result = r;
535  elem = INDEX(cidx);
536  dmin = dtmp;
537 
538  if (dmin < epsilon2_)
539  {
540  ElemData ed(*this,elem);
541  this->basis_.get_coords(coords,result,ed);
542 
543  result = this->basis_.interpolate(coords,ed);
544  pdist = sqrt((result-p).length2());
545  return (true);
546  }
547  }
548  }
549 
550  if (kk == this->nk_-2)
551  {
553  points_(kk+1,jj,ii),
554  points_(kk+1,jj,ii+1),
555  points_(kk+1,jj+1,ii+1),
556  points_(kk+1,jj+1,ii));
557  const double dtmp = (p - r).length2();
558  if (dtmp < dmin)
559  {
560  found_one = true;
561  result = r;
562  elem = INDEX(cidx);
563  dmin = dtmp;
564 
565  if (dmin < epsilon2_)
566  {
567  ElemData ed(*this,elem);
568  this->basis_.get_coords(coords,result,ed);
569 
570  result = this->basis_.interpolate(coords,ed);
571  pdist = sqrt((result-p).length2());
572  return (true);
573  }
574  }
575  }
576 
577  ++it;
578  }
579  }
580  }
581  }
582  }
583  }
584  bi--;ei++;
585  bj--;ej++;
586  bk--;ek++;
587  }
588  while (!found) ;
589 
590  if (!found_one) return (false);
591 
592  ElemData ed(*this,elem);
593  this->basis_.get_coords(coords,result,ed);
594 
595  result = this->basis_.interpolate(coords,ed);
596  dmin = (result-p).length2();
597  pdist = sqrt(dmin);
598  return (true);
599  }
600 
601 
602  bool find_closest_elems(double& pdist, Core::Geometry::Point &result,
603  std::vector<typename LatVolMesh<Basis>::Elem::index_type> &elems,
604  const Core::Geometry::Point &p) const;
605 
607  typename LatVolMesh<Basis>::Node::array_type &, double *);
609  typename LatVolMesh<Basis>::Edge::array_type &, double *)
610  { ASSERTFAIL("StructHexVolMesh::get_weights for edges isn't supported"); }
612  typename LatVolMesh<Basis>::Face::array_type &, double *)
613  { ASSERTFAIL("StructHexVolMesh::get_weights for faces isn't supported"); }
615  typename LatVolMesh<Basis>::Cell::array_type &, double *);
616 
618  const typename LatVolMesh<Basis>::Node::index_type &index) const
619  { get_center(point, index); }
620  void set_point(const Core::Geometry::Point &point,
621  const typename LatVolMesh<Basis>::Node::index_type &index);
622 
623 
625  const typename LatVolMesh<Basis>::Elem::index_type & i,
626  FieldRNG &rng) const;
627 
628  /// Get the local coordinates for a certain point within an element
629  /// This function uses a couple of newton iterations to find the local
630  /// coordinate of a point
631  template<class VECTOR>
632  bool get_coords(VECTOR &coords, const Core::Geometry::Point &p,
633  typename LatVolMesh<Basis>::Elem::index_type idx) const
634  {
635  ElemData ed(*this, idx);
636  return this->basis_.get_coords(coords, p, ed);
637  }
638 
639  /// Find the location in the global coordinate system for a local
640  /// coordinate ! This function is the opposite of get_coords.
641  template<class VECTOR>
642  void interpolate(Core::Geometry::Point &pt, const VECTOR &coords,
643  typename LatVolMesh<Basis>::Elem::index_type idx) const
644  {
645  ElemData ed(*this, idx);
646  pt = this->basis_.interpolate(coords, ed);
647  }
648 
649  /// Interpolate the derivate of the function, This infact will
650  /// return the jacobian of the local to global coordinate
651  /// transformation. This function is mainly intended for the non
652  /// linear elements
653  template<class VECTOR1, class VECTOR2>
654  void derivate(const VECTOR1 &coords,
656  VECTOR2 &J) const
657  {
658  ElemData ed(*this, idx);
659  this->basis_.derivate(coords, ed, J);
660  }
661 
662  /// Get the determinant of the jacobian, which is the local volume
663  /// of an element and is intended to help with the integration of
664  /// functions over an element.
665  template<class VECTOR>
666  double det_jacobian(const VECTOR& coords,
667  typename LatVolMesh<Basis>::Elem::index_type idx) const
668  {
669  double J[9];
670  jacobian(coords,idx,J);
671  return (DetMatrix3x3(J));
672  }
673 
674  /// Get the jacobian of the transformation. In case one wants the
675  /// non inverted version of this matrix. This is currentl here for
676  /// completeness of the interface
677  template<class VECTOR>
678  void jacobian(const VECTOR& coords,
680  double* J) const
681  {
683  ElemData ed(*this,idx);
684  this->basis_.derivate(coords,ed,Jv);
685  J[0] = Jv[0].x();
686  J[1] = Jv[0].y();
687  J[2] = Jv[0].z();
688  J[3] = Jv[1].x();
689  J[4] = Jv[1].y();
690  J[5] = Jv[1].z();
691  J[6] = Jv[2].x();
692  J[7] = Jv[2].y();
693  J[8] = Jv[2].z();
694  }
695 
696  /// Get the inverse jacobian of the transformation. This one is
697  /// needed to translate local gradients into global gradients. Hence
698  /// it is crucial for calculating gradients of fields, or
699  /// constructing finite elements.
700  template<class VECTOR>
701  double inverse_jacobian(const VECTOR& coords,
703  double* Ji) const
704  {
706  ElemData ed(*this,idx);
707  this->basis_.derivate(coords,ed,Jv);
708  double J[9];
709  J[0] = Jv[0].x();
710  J[1] = Jv[0].y();
711  J[2] = Jv[0].z();
712  J[3] = Jv[1].x();
713  J[4] = Jv[1].y();
714  J[5] = Jv[1].z();
715  J[6] = Jv[2].x();
716  J[7] = Jv[2].y();
717  J[8] = Jv[2].z();
718 
719  return (InverseMatrix3x3(J,Ji));
720  }
721 
723  {
725  ElemData ed(*this,idx);
726 
727  double temp;
728  this->basis_.derivate(this->basis_.unit_center,ed,Jv);
729  double min_jacobian = ScaledDetMatrix3P(Jv);
730 
731  size_t num_vertices = this->basis_.number_of_vertices();
732  for (size_t j=0;j < num_vertices;j++)
733  {
734  this->basis_.derivate(this->basis_.unit_vertices[j],ed,Jv);
735  temp = ScaledDetMatrix3P(Jv);
736  if(temp < min_jacobian) min_jacobian = temp;
737  }
738 
739  return (min_jacobian);
740  }
741 
743  {
745  ElemData ed(*this,idx);
746 
747  double temp;
748  this->basis_.derivate(this->basis_.unit_center,ed,Jv);
749  double min_jacobian = DetMatrix3P(Jv);
750 
751  size_t num_vertices = this->basis_.number_of_vertices();
752  for (size_t j=0;j < num_vertices;j++)
753  {
754  this->basis_.derivate(this->basis_.unit_vertices[j],ed,Jv);
755  temp = DetMatrix3P(Jv);
756  if(temp < min_jacobian) min_jacobian = temp;
757  }
758 
759  return (min_jacobian);
760  }
761 
762 
763  double get_epsilon() const
764  { return (epsilon_); }
765 
766  virtual bool synchronize(mask_type);
767  virtual bool unsynchronize(mask_type);
768  bool clear_synchronization();
769 
770  /// Export this class using the old Pio system
771  virtual void io(Piostream&);
773  /// Core functionality for getting the name of a templated mesh class
774  static const std::string type_name(int n = -1);
775 
776  /// Type description, used for finding names of the mesh class for
777  /// dynamic compilation purposes. Soem of this should be obsolete
778  virtual const TypeDescription *get_type_description() const;
779  static const TypeDescription* node_type_description();
780  static const TypeDescription* edge_type_description();
781  static const TypeDescription* face_type_description();
782  static const TypeDescription* cell_type_description();
784  { return cell_type_description(); }
785 
786  /// This function returns a maker for Pio.
787  static Persistent *maker() { return new StructHexVolMesh<Basis>(); }
788  /// This function returns a handle for the virtual interface.
789  static MeshHandle mesh_maker() { return boost::make_shared<StructHexVolMesh<Basis>>(); }
790  /// This function returns a handle for the virtual interface.
792  size_type y,
793  size_type z)
794  {
795  return boost::make_shared<StructHexVolMesh<Basis>>(x,y,z);
796  }
797 
798  Array3<Core::Geometry::Point>& get_points() { return (points_); }
799 
801  const Core::Geometry::Point &p) const
802  {
803  // rewrote this function to more accurately deal with hexes that do not have
804  // face aligned with the axes of the coordinate system
805 
806  // First a fast test to see whether we are inside the bounding box
807  // (this code could be faster, by testing axis by axis)
808  // Then if it is inside a tight bounding box compute the local coordinates
809  // using the Newton search, this way we account for not planar surfaces of
810  // the hexes.
811 
813  this->get_nodes(nodes,idx);
814 
816  bbox.extend(points_(nodes[0].k_,nodes[0].j_,nodes[0].i_));
817  bbox.extend(points_(nodes[1].k_,nodes[1].j_,nodes[1].i_));
818  bbox.extend(points_(nodes[2].k_,nodes[2].j_,nodes[2].i_));
819  bbox.extend(points_(nodes[3].k_,nodes[3].j_,nodes[3].i_));
820  bbox.extend(points_(nodes[4].k_,nodes[4].j_,nodes[4].i_));
821  bbox.extend(points_(nodes[5].k_,nodes[5].j_,nodes[5].i_));
822  bbox.extend(points_(nodes[6].k_,nodes[6].j_,nodes[6].i_));
823  bbox.extend(points_(nodes[7].k_,nodes[7].j_,nodes[7].i_));
824  bbox.extend(epsilon_);
825 
826  if (bbox.inside(p))
827  {
828  StackVector<double,3> coords;
829  ElemData ed(*this, idx);
830  if(this->basis_.get_coords(coords, p, ed)) return (true);
831  }
832 
833  return (false);
834  }
835 
836 
837 
838  template <class INDEX>
839  inline bool locate_elem(INDEX &elem, const Core::Geometry::Point &p) const
840  {
841  /// @todo: Generate bounding boxes for elements and integrate this into the
842  // basis function code.
843  if (this->basis_.polynomial_order() > 1) return elem_locate(elem, *this, p);
844 
845  /// If there are no nodes we cannot find a closest point
846  if (this->ni_ == 0 || this->nj_ == 0 || this->nk_ == 0) return (false);
847 
848  /// Check whether the estimate given in idx is the point we are looking for
849  if (elem.i_ >= 0 && elem.i_ < (this->ni_-1) &&
850  elem.j_ >= 0 && elem.j_ < (this->nj_-1) &&
851  elem.k_ >= 0 && elem.k_ < (this->nk_-1))
852  {
853  elem.mesh_ = this;
854  if (inside(elem,p)) return (true);
855  }
856 
857  ASSERTMSG(synchronized_ & Mesh::ELEM_LOCATE_E,
858  "StructHexVolMesh: need to synchronize ELEM_LOCATE_E first");
859 
861  if (elem_grid_->lookup(it, eit, p))
862  {
863  while (it != eit)
864  {
865  if (inside(*it, p))
866  {
867  elem = INDEX(*it);
868  return (true);
869  }
870  ++it;
871  }
872  }
873  return (false);
874  }
875 
876  template <class ARRAY>
877  inline bool locate_elems(ARRAY &array, const Core::Geometry::BBox &b) const
878  {
879 
880  ASSERTMSG(synchronized_ & Mesh::ELEM_LOCATE_E,
881  "StructHexVolMesh::locate_elems requires synchronize(ELEM_LOCATE_E).")
882 
883  array.clear();
884  index_type is,js,ks;
885  index_type ie,je,ke;
886  elem_grid_->locate_clamp(is,js,ks,b.min());
887  elem_grid_->locate_clamp(ie,je,ke,b.max());
888  for (index_type i=is; i<=ie;i++)
889  for (index_type j=js; j<je;j++)
890  for (index_type k=ks; k<ke; k++)
891  {
893  elem_grid_->lookup_ijk(it, eit, i, j, k);
894  while (it != eit)
895  {
896  size_t p=0;
897  for (;p<array.size();p++) if (array[p] == typename ARRAY::value_type(*it)) break;
898  if (p == array.size()) array.push_back(typename ARRAY::value_type(*it));
899  ++it;
900  }
901  }
902 
903  return (array.size() > 0);
904  }
905 
906 
907  template <class INDEX, class ARRAY>
908  inline bool locate_elem(INDEX &elem, ARRAY& coords, const Core::Geometry::Point &p) const
909  {
910  /// @todo: Generate bounding boxes for elements and integrate this into the
911  // basis function code.
912  if (this->basis_.polynomial_order() > 1) return elem_locate(elem, *this, p);
913 
914  /// If there are no nodes we cannot find a closest point
915  if (this->ni_ == 0 || this->nj_ == 0 || this->nk_ == 0) return (false);
916 
917  /// Check whether the estimate given in idx is the point we are looking for
918  if (elem.i_ >= 0 && elem.i_ < (this->ni_-1) &&
919  elem.j_ >= 0 && elem.j_ < (this->nj_-1) &&
920  elem.k_ >= 0 && elem.k_ < (this->nk_-1))
921  {
922  elem.mesh_ = this;
923  if (inside(elem,p))
924  {
925  ElemData ed(*this,elem);
926  this->basis_.get_coords(coords,p,ed);
927  return (true);
928  }
929  }
930 
931  ASSERTMSG(synchronized_ & Mesh::ELEM_LOCATE_E,
932  "StructHexVolMesh: need to synchronize ELEM_LOCATE_E first");
933 
935  if (elem_grid_->lookup(it, eit, p))
936  {
937  while (it != eit)
938  {
939  if (inside(*it, p))
940  {
941  elem = INDEX(*it);
942  ElemData ed(*this,elem);
943  this->basis_.get_coords(coords,p,ed);
944  return (true);
945  }
946  ++it;
947  }
948  }
949  return (false);
950  }
951 
952 
953  template <class INDEX>
954  bool inline locate_node(INDEX &node, const Core::Geometry::Point &p) const
955  {
956  /// If there are no nodes we cannot find a closest point
957  if (this->ni_ == 0 || this->nj_ == 0 || this->nk_ == 0) return (false);
958 
959  /// Check first guess
960  if (node.i_ >= 0 && node.i_ < this->ni_ &&
961  node.j_ >= 0 && node.j_ < this->nj_ &&
962  node.k_ >= 0 && node.k_ < this->nk_)
963  {
964  node.mesh_ = this;
965  if ((p - points_(node.k_,node.j_,node.i_)).length2() < epsilon2_)
966  return (true);
967  }
968 
969  ASSERTMSG(synchronized_ & Mesh::NODE_LOCATE_E,
970  "StructHexVolMesh::locate_node requires synchronize(NODE_LOCATE_E).")
971 
972  // get grid sizes
973  const size_type ni = node_grid_->get_ni()-1;
974  const size_type nj = node_grid_->get_nj()-1;
975  const size_type nk = node_grid_->get_nk()-1;
976 
977  // Convert to grid coordinates.
978  index_type bi, bj, bk, ei, ej, ek;
979  node_grid_->unsafe_locate(bi, bj, bk, p);
980 
981  // Clamp to l;..;,closest point on the grid.
982  if (bi > ni) bi =ni; if (bi < 0) bi = 0;
983  if (bj > nj) bj =nj; if (bj < 0) bj = 0;
984  if (bk > nk) bk =nk; if (bk < 0) bk = 0;
985 
986  ei = bi;
987  ej = bj;
988  ek = bk;
989 
990  double dmin = DBL_MAX;
991  bool found = true;
992  do
993  {
994  found = true;
995  /// We need to do a full shell without any elements that are closer
996  /// to make sure there no closer elements in neighboring searchgrid cells
997 
998  for (index_type i = bi; i <= ei; i++)
999  {
1000  if (i < 0 || i > ni) continue;
1001  for (index_type j = bj; j <= ej; j++)
1002  {
1003  if (j < 0 || j > nj) continue;
1004  for (index_type k = bk; k <= ek; k++)
1005  {
1006  if (k < 0 || k > nk) continue;
1007  if (i == bi || i == ei || j == bj || j == ej || k == bk || k == ek)
1008  {
1009  if (node_grid_->min_distance_squared(p, i, j, k) < dmin)
1010  {
1011  found = false;
1013  node_grid_->lookup_ijk(it, eit, i, j, k);
1014 
1015  while (it != eit)
1016  {
1017  const typename LatVolMesh<Basis>::Node::index_type idx = *it;
1018  const Core::Geometry::Point point = points_(idx.k_,idx.j_,idx.i_);
1019  const double dist = (p-point).length2();
1020 
1021  if (dist < dmin)
1022  {
1023  node = idx;
1024  dmin = dist;
1025 
1026  if (dist < epsilon2_) return (true);
1027  }
1028  ++it;
1029  }
1030  }
1031  }
1032  }
1033  }
1034  }
1035  bi--;ei++;
1036  bj--;ej++;
1037  bk--;ek++;
1038  }
1039  while ((!found)||(dmin == DBL_MAX)) ;
1040 
1041  return (true);
1042  }
1043 
1044 
1045 
1046 
1047 private:
1048 
1049  void insert_elem_into_grid(typename LatVolMesh<Basis>::Elem::index_type idx);
1050  void remove_elem_from_grid(typename LatVolMesh<Basis>::Elem::index_type idx);
1051  void insert_node_into_grid(typename LatVolMesh<Basis>::Node::index_type idx);
1052  void remove_node_from_grid(typename LatVolMesh<Basis>::Node::index_type idx);
1053 
1054  void compute_node_grid(Core::Geometry::BBox& bb);
1055  void compute_elem_grid(Core::Geometry::BBox& bb);
1056  void compute_epsilon(Core::Geometry::BBox& bb);
1057 
1058  double polygon_area(const typename LatVolMesh<Basis>::Node::array_type &,
1059  const Core::Geometry::Vector) const;
1060  const Core::Geometry::Point &point(
1061  const typename LatVolMesh<Basis>::Node::index_type &idx) const
1062  { return points_(idx.k_, idx.j_, idx.i_); }
1063 
1064 
1065  Array3<Core::Geometry::Point> points_;
1066 
1069 
1070  mutable Core::Thread::Mutex synchronize_lock_;
1071  mask_type synchronized_;
1072  double epsilon_;
1073  double epsilon2_;
1074  double epsilon3_; /// for volumetric comparison
1075 };
1076 
1077 template <class Basis>
1078 PersistentTypeID
1079 StructHexVolMesh<Basis>::structhexvol_typeid(StructHexVolMesh<Basis>::type_name(-1),
1080  "Mesh", maker);
1081 
1082 template <class Basis>
1084  synchronize_lock_("Synchronize lock"),
1085  synchronized_(Mesh::ALL_ELEMENTS_E),
1086  epsilon_(0.0),
1087  epsilon2_(0.0),
1088  epsilon3_(0.0)
1089 {
1090  DEBUG_CONSTRUCTOR("StructHexVolMesh")
1091 
1092  /// Create a new virtual interface for this copy
1093  /// all pointers have changed hence create a new
1094  /// virtual interface class
1095  this->vmesh_.reset(CreateVStructHexVolMesh(this));
1096 }
1097 
1098 template <class Basis>
1100  size_type j,
1101  size_type k) :
1102  LatVolMesh<Basis>(i, j, k, Core::Geometry::Point(0.0, 0.0, 0.0), Core::Geometry::Point(1.0, 1.0, 1.0)),
1103  points_(k, j, i),
1104  synchronize_lock_("Synchronize lock"),
1105  synchronized_(Mesh::ALL_ELEMENTS_E),
1106  epsilon_(0.0),
1107  epsilon2_(0.0),
1108  epsilon3_(0.0)
1109 {
1110  DEBUG_CONSTRUCTOR("StructHexVolMesh")
1111 
1112  /// Create a new virtual interface for this copy
1113  /// all pointers have changed hence create a new
1114  /// virtual interface class
1115  this->vmesh_.reset(CreateVStructHexVolMesh(this));
1116 }
1117 
1118 template <class Basis>
1120  LatVolMesh<Basis>(copy),
1121  synchronize_lock_("Synchronize lock"),
1122  synchronized_(Mesh::ALL_ELEMENTS_E),
1123  epsilon_(0.0),
1124  epsilon2_(0.0),
1125  epsilon3_(0.0)
1126 {
1127  DEBUG_CONSTRUCTOR("StructHexVolMesh")
1128 
1129  copy.synchronize_lock_.lock();
1130 
1131  points_ = copy.points_;
1132 
1133  // Epsilon does not require much space, hence copy those
1134  synchronized_ |= copy.synchronized_ & Mesh::EPSILON_E;
1135  epsilon_ = copy.epsilon_;
1136  epsilon2_ = copy.epsilon2_;
1137  epsilon3_ = copy.epsilon3_;
1138 
1139  copy.synchronize_lock_.unlock();
1140 
1141  /// Create a new virtual interface for this copy
1142  /// all pointers have changed hence create a new
1143  /// virtual interface class
1144  this->vmesh_.reset(CreateVStructHexVolMesh(this));
1145 }
1146 
1147 
1148 template <class Basis>
1149 bool
1150 StructHexVolMesh<Basis>::get_dim(std::vector<size_type> &array) const
1151 {
1152  array.resize(3);
1153  array.clear();
1154 
1155  array.push_back(this->ni_);
1156  array.push_back(this->nj_);
1157  array.push_back(this->nk_);
1158 
1159  return true;
1160 }
1161 
1162 
1163 template <class Basis>
1166 {
1167  Core::Geometry::BBox result;
1168 
1169  typename LatVolMesh<Basis>::Node::iterator ni, nie;
1170  this->begin(ni);
1171  this->end(nie);
1172  while (ni != nie)
1173  {
1175  get_center(p, *ni);
1176  result.extend(p);
1177  ++ni;
1178  }
1179  return result;
1180 }
1181 
1182 template <class Basis>
1183 void
1185 {
1186  typename LatVolMesh<Basis>::Node::iterator i, ie;
1187  this->begin(i);
1188  this->end(ie);
1189 
1190  while (i != ie)
1191  {
1192  points_((*i).k_,(*i).j_,(*i).i_) =
1193  t.project(points_((*i).k_,(*i).j_,(*i).i_));
1194 
1195  ++i;
1196  }
1197 
1198  synchronize_lock_.lock();
1199  if (node_grid_) { node_grid_->transform(t); }
1200  if (elem_grid_) { elem_grid_->transform(t); }
1201  synchronize_lock_.unlock();
1202 
1203 }
1204 
1205 
1206 template <class Basis>
1207 void
1209  const typename LatVolMesh<Basis>::Node::index_type &idx) const
1210 {
1211  result = points_(idx.k_, idx.j_, idx.i_);
1212 }
1213 
1214 template <class Basis>
1215 void
1217  typename LatVolMesh<Basis>::Edge::index_type idx) const
1218 {
1220  this->get_nodes(arr, idx);
1222  get_center(result, arr[0]);
1223  get_center(p1, arr[1]);
1224 
1225  result += p1;
1226  result *= 0.5;
1227 }
1228 
1229 
1230 template <class Basis>
1231 void
1233  typename LatVolMesh<Basis>::Face::index_type idx) const
1234 {
1235  typename LatVolMesh<Basis>::Node::array_type nodes;
1236  this->get_nodes(nodes, idx);
1237  ASSERT(nodes.size() == 4);
1238  typename LatVolMesh<Basis>::Node::array_type::iterator nai = nodes.begin();
1239  get_point(result, *nai);
1240  ++nai;
1242  while (nai != nodes.end())
1243  {
1244  get_point(pp, *nai);
1245  result += pp;
1246  ++nai;
1247  }
1248  result *= (1.0 / 4.0);
1249 }
1250 
1251 
1252 template <class Basis>
1253 void
1255  const typename LatVolMesh<Basis>::Cell::index_type &idx) const
1256 {
1257  typename LatVolMesh<Basis>::Node::array_type nodes;
1258  this->get_nodes(nodes, idx);
1259  ASSERT(nodes.size() == 8);
1260  typename LatVolMesh<Basis>::Node::array_type::iterator nai = nodes.begin();
1261  get_point(result, *nai);
1262  ++nai;
1264  while (nai != nodes.end())
1265  {
1266  get_point(pp, *nai);
1267  result += pp;
1268  ++nai;
1269  }
1270  result *= (1.0 / 8.0);
1271 }
1272 
1273 template <class Basis>
1274 bool
1277  double maxdist) const
1278 {
1279  /// If there are no nodes we cannot find a closest point
1280  if (this->ni_ == 0 || this->nj_ == 0 || this->nk_ == 0) return (false);
1281 
1282  if (maxdist < 0.0) maxdist = DBL_MAX; else maxdist = maxdist*maxdist;
1283 
1284  /// Check first guess
1285  if (node.i_ >= 0 && node.i_ < this->ni_ &&
1286  node.j_ >= 0 && node.j_ < this->nj_ &&
1287  node.k_ >= 0 && node.k_ < this->nk_)
1288  {
1289  node.mesh_ = this;
1290  Core::Geometry::Point point = points_(node.k_,node.j_,node.i_);
1291  double dist = (point-p).length2();
1292 
1293  if ( dist < epsilon2_ )
1294  {
1295  result = point;
1296  pdist = sqrt(dist);
1297  return (true);
1298  }
1299  }
1300 
1301  ASSERTMSG(synchronized_ & Mesh::NODE_LOCATE_E,
1302  "StructHexVolMesh::find_closest_node requires synchronize(NODE_LOCATE_E).")
1303 
1304  // get grid sizes
1305  const size_type ni = node_grid_->get_ni()-1;
1306  const size_type nj = node_grid_->get_nj()-1;
1307  const size_type nk = node_grid_->get_nk()-1;
1308 
1309  // Convert to grid coordinates.
1310  index_type bi, bj, bk, ei, ej, ek;
1311  node_grid_->unsafe_locate(bi, bj, bk, p);
1312 
1313  // Clamp to closest point on the grid.
1314  if (bi > ni) bi = ni; if (bi < 0) bi = 0;
1315  if (bj > nj) bj = nj; if (bj < 0) bj = 0;
1316  if (bk > nk) bk = nk; if (bk < 0) bk = 0;
1317 
1318  ei = bi; ej = bj; ek = bk;
1319 
1320  double dmin = maxdist;
1321  bool found = true;
1322  bool found_one = false;
1323 
1324  do
1325  {
1326  found = true;
1327  /// We need to do a full shell without any elements that are closer
1328  /// to make sure there no closer elements in neighboring searchgrid cells
1329 
1330  for (index_type i = bi; i <= ei; i++)
1331  {
1332  if (i < 0 || i > ni) continue;
1333  for (index_type j = bj; j <= ej; j++)
1334  {
1335  if (j < 0 || j > nj) continue;
1336  for (index_type k = bk; k <= ek; k++)
1337  {
1338  if (k < 0 || k > nk) continue;
1339  if (i == bi || i == ei || j == bj || j == ej || k == bk || k == ek)
1340  {
1341  if (node_grid_->min_distance_squared(p, i, j, k) < dmin)
1342  {
1344  found = false;
1345  node_grid_->lookup_ijk(it,eit, i, j, k);
1346 
1347  while (it != eit)
1348  {
1349  const typename LatVolMesh<Basis>::Node::index_type idx = *it;
1350  const Core::Geometry::Point point = points_(idx.k_,idx.j_,idx.i_);
1351  const double dist = (p-point).length2();
1352 
1353  if (dist < dmin)
1354  {
1355  found_one = true;
1356  result = point;
1357  node = idx;
1358  dmin = dist;
1359  /// If we are closer than eps^2 we found a node close enough
1360  if (dmin < epsilon2_)
1361  {
1362  pdist = sqrt(dmin);
1363  return (true);
1364  }
1365  }
1366  ++it;
1367  }
1368  }
1369  }
1370  }
1371  }
1372  }
1373  bi--;ei++;
1374  bj--;ej++;
1375  bk--;ek++;
1376  }
1377  while ((!found)||(dmin == DBL_MAX)) ;
1378 
1379  if (!found_one) return (false);
1380 
1381  pdist = sqrt(dmin);
1382  return (true);
1383 }
1384 
1385  /// Find the closest elements to a point
1386 template<class Basis>
1387 bool
1389  std::vector<typename LatVolMesh<Basis>::Elem::index_type>& /*elems*/,
1390  const Core::Geometry::Point& /*p*/) const
1391 {
1392  ASSERTFAIL("StructHexVolMesh: Find closest element has not yet been implemented.");
1393  return (false);
1394 }
1395 
1396 
1397 
1398 template <class Basis>
1399 int
1402  double *w)
1403 {
1405  if (locate_elem(idx, p))
1406  {
1407  this->get_nodes(l,idx);
1408  std::vector<double> coords(3);
1409  if (get_coords(coords, p, idx))
1410  {
1411  this->basis_.get_weights(coords, w);
1412  return this->basis_.dofs();
1413  }
1414  }
1415  return 0;
1416 }
1417 
1418 
1419 template <class Basis>
1420 int
1423  double *w)
1424 {
1426  if (locate_elem(idx, p))
1427  {
1428  l.resize(1);
1429  l[0] = idx;
1430  w[0] = 1.0;
1431  return 1;
1432  }
1433  return 0;
1434 }
1435 
1436 
1437 /// ===================================================================
1438 /// area3D_Polygon(): computes the area of a 3D planar polygon
1439 /// Input: int n = the number of vertices in the polygon
1440 /// Core::Geometry::Point* V = an array of n+2 vertices in a plane
1441 /// with V[n]=V[0] and V[n+1]=V[1]
1442 /// Core::Geometry::Point N = unit normal vector of the polygon's plane
1443 /// Return: the (float) area of the polygon
1444 
1445 /// Copyright 2009, softSurfer (www.softsurfer.com)
1446 /// This code may be freely used and modified for any purpose
1447 /// providing that this copyright notice is included with it.
1448 /// SoftSurfer makes no warranty for this code, and cannot be held
1449 /// liable for any real or imagined damage resulting from its use.
1450 /// Users of this code must verify correctness for their application.
1451 
1452 template <class Basis>
1453 double
1455  const Core::Geometry::Vector N) const
1456 {
1457  double area = 0;
1458  double an, ax, ay, az; /// abs value of normal and its coords
1459  int coord; // coord to ignore: 1=x, 2=y, 3=z
1460  index_type i, j, k; /// loop indices
1461  const size_type n = ni.size();
1462 
1463  /// select largest abs coordinate to ignore for projection
1464  ax = (N.x()>0 ? N.x() : -N.x()); /// abs x-coord
1465  ay = (N.y()>0 ? N.y() : -N.y()); /// abs y-coord
1466  az = (N.z()>0 ? N.z() : -N.z()); /// abs z-coord
1467 
1468  coord = 3; /// ignore z-coord
1469  if (ax > ay)
1470  {
1471  if (ax > az) coord = 1; /// ignore x-coord
1472  }
1473  else if (ay > az) coord = 2; /// ignore y-coord
1474 
1475  /// compute area of the 2D projection
1476  for (i=1, j=2, k=0; i<=n; i++, j++, k++)
1477  switch (coord)
1478  {
1479  case 1:
1480  area += (point(ni[i%n]).y() *
1481  (point(ni[j%n]).z() - point(ni[k%n]).z()));
1482  continue;
1483  case 2:
1484  area += (point(ni[i%n]).x() *
1485  (point(ni[j%n]).z() - point(ni[k%n]).z()));
1486  continue;
1487  case 3:
1488  area += (point(ni[i%n]).x() *
1489  (point(ni[j%n]).y() - point(ni[k%n]).y()));
1490  continue;
1491  }
1492 
1493  /// scale to get area before projection
1494  an = sqrt( ax*ax + ay*ay + az*az); /// length of normal vector
1495  switch (coord)
1496  {
1497  case 1:
1498  area *= (an / (2*ax));
1499  break;
1500  case 2:
1501  area *= (an / (2*ay));
1502  break;
1503  case 3:
1504  area *= (an / (2*az));
1505  }
1506  return area;
1507 }
1508 
1509 
1511 {
1512  return (0.5*Cross((a-b),(b-c)).length());
1513 }
1514 
1515 template <class Basis>
1516 double
1518 {
1519  return 0.0;
1520 }
1521 
1522 
1523 template <class Basis>
1524 double
1526 {
1528  this->get_nodes(arr, idx);
1529  Core::Geometry::Point p0, p1;
1530  get_center(p0, arr[0]);
1531  get_center(p1, arr[1]);
1532 
1533  return (p1 - p0).length();
1534 }
1535 
1536 
1537 template <class Basis>
1538 double
1540 {
1541  typename LatVolMesh<Basis>::Node::array_type nodes;
1542  this->get_nodes(nodes, idx);
1543  Core::Geometry::Point p0, p1, p2, p3;
1544  get_point(p0, nodes[0]);
1545  get_point(p1, nodes[1]);
1546  get_point(p2, nodes[2]);
1547  get_point(p3, nodes[3]);
1548 
1549  return ((Cross(p0-p1,p2-p0)).length()+(Cross(p0-p3,p2-p0)).length())*0.5;
1550 }
1551 
1552 
1553 template <class Basis>
1554 double
1556 {
1557  typename LatVolMesh<Basis>::Node::array_type nodes;
1558  this->get_nodes(nodes, idx);
1559  Core::Geometry::Point p0, p1, p2, p3, p4, p5, p6, p7;
1560  get_point(p0, nodes[0]);
1561  get_point(p1, nodes[1]);
1562  get_point(p2, nodes[2]);
1563  get_point(p3, nodes[3]);
1564  get_point(p4, nodes[4]);
1565  get_point(p5, nodes[5]);
1566  get_point(p6, nodes[6]);
1567  get_point(p7, nodes[7]);
1568 
1569  const double a0 = tetrahedra_volume(p0, p1, p2, p5);
1570  const double a1 = tetrahedra_volume(p0, p2, p3, p7);
1571  const double a2 = tetrahedra_volume(p0, p5, p2, p7);
1572  const double a3 = tetrahedra_volume(p0, p5, p7, p4);
1573  const double a4 = tetrahedra_volume(p5, p2, p7, p6);
1574 
1575  return (a0 + a1 + a2 + a3 + a4);
1576 }
1577 
1578 
1579 template <class Basis>
1580 void
1582  const typename LatVolMesh<Basis>::Node::index_type &idx)
1583 {
1584  points_(idx.k_, idx.j_, idx.i_) = p;
1585 }
1586 
1587 template<class Basis>
1588 void
1590  const typename LatVolMesh<Basis>::Elem::index_type &ei,
1591  FieldRNG &rng) const
1592 {
1593  const Core::Geometry::Point &p0 = points_(ei.k_+0, ei.j_+0, ei.i_+0);
1594  const Core::Geometry::Point &p1 = points_(ei.k_+0, ei.j_+0, ei.i_+1);
1595  const Core::Geometry::Point &p2 = points_(ei.k_+0, ei.j_+1, ei.i_+1);
1596  const Core::Geometry::Point &p3 = points_(ei.k_+0, ei.j_+1, ei.i_+0);
1597  const Core::Geometry::Point &p4 = points_(ei.k_+1, ei.j_+0, ei.i_+0);
1598  const Core::Geometry::Point &p5 = points_(ei.k_+1, ei.j_+0, ei.i_+1);
1599  const Core::Geometry::Point &p6 = points_(ei.k_+1, ei.j_+1, ei.i_+1);
1600  const Core::Geometry::Point &p7 = points_(ei.k_+1, ei.j_+1, ei.i_+0);
1601 
1602  const double a0 = tetrahedra_volume(p0, p1, p2, p5);
1603  const double a1 = tetrahedra_volume(p0, p2, p3, p7);
1604  const double a2 = tetrahedra_volume(p0, p5, p2, p7);
1605  const double a3 = tetrahedra_volume(p0, p5, p7, p4);
1606  const double a4 = tetrahedra_volume(p5, p2, p7, p6);
1607 
1608  const double w = rng() * (a0 + a1 + a2 + a3 + a4);
1609 
1610  double t = rng();
1611  double u = rng();
1612  double v = rng();
1613 
1614  /// Fold cube into prism.
1615  if (t + u > 1.0)
1616  {
1617  t = 1.0 - t;
1618  u = 1.0 - u;
1619  }
1620 
1621  /// Fold prism into tet.
1622  if (u + v > 1.0)
1623  {
1624  const double tmp = v;
1625  v = 1.0 - t - u;
1626  u = 1.0 - tmp;
1627  }
1628  else if (t + u + v > 1.0)
1629  {
1630  const double tmp = v;
1631  v = t + u + v - 1.0;
1632  t = 1.0 - u - tmp;
1633  }
1634 
1635  /// Convert to Barycentric and compute new point.
1636  const double a = 1.0 - t - u - v;
1637 
1638  if (w > (a0 + a1 + a2 + a3))
1639  {
1640  p = Core::Geometry::Point(p5*a + p2*t + p7*u + p6*v);
1641  }
1642  else if (w > (a0 + a1 + a2))
1643  {
1644  p = Core::Geometry::Point(p0*a + p5*t + p7*u + p5*v);
1645  }
1646  else if (w > (a0 + a1))
1647  {
1648  p = Core::Geometry::Point(p0*a + p5*t + p2*u + p7*v);
1649  }
1650  else if (w > a0)
1651  {
1652  p = Core::Geometry::Point(p0*a + p2*t + p3*u + p7*v);
1653  }
1654  else
1655  {
1656  p = Core::Geometry::Point(p0*a + p1*t + p2*u + p5*v);
1657  }
1658 }
1659 
1660 template <class Basis>
1661 bool
1663 {
1664  synchronize_lock_.lock();
1665 
1668  ( !(synchronized_ & Mesh::NODE_LOCATE_E) ||
1669  !(synchronized_ & Mesh::ELEM_LOCATE_E) ||
1670  !(synchronized_ & Mesh::EPSILON_E) ))
1671  {
1672  /// These computations share the evaluation of the bounding box
1673  Core::Geometry::BBox bb = get_bounding_box();
1674 
1675  /// Compute the epsilon for geometrical closeness comparisons
1676  /// Mainly used by the grid lookup tables
1677  if (sync & (Mesh::EPSILON_E|Mesh::LOCATE_E|Mesh::FIND_CLOSEST_E) &&
1678  !(synchronized_ & Mesh::EPSILON_E))
1679  {
1680  compute_epsilon(bb);
1681  }
1682 
1683  /// Table for finding nodes in space
1684  if (sync & (Mesh::NODE_LOCATE_E|Mesh::FIND_CLOSEST_NODE_E) &&
1685  !(synchronized_ & Mesh::NODE_LOCATE_E))
1686  {
1687  compute_node_grid(bb);
1688  }
1689 
1690  /// Table for finding elements in space
1691  if (sync & (Mesh::ELEM_LOCATE_E|Mesh::FIND_CLOSEST_ELEM_E) &&
1692  !(synchronized_ & Mesh::ELEM_LOCATE_E))
1693  {
1694  compute_elem_grid(bb);
1695  }
1696  }
1697 
1698  synchronize_lock_.unlock();
1699 
1700  return (true);
1701 }
1702 
1703 template <class Basis>
1704 bool
1706 {
1707  return (true);
1708 }
1709 
1710 template <class Basis>
1711 bool
1713 {
1714  synchronize_lock_.lock();
1715 
1716  // Undo marking the synchronization
1717  synchronized_ = Mesh::NODES_E | Mesh::ELEMS_E | Mesh::CELLS_E;
1718 
1719  // Free memory where possible
1720 
1721  node_grid_.reset();
1722  elem_grid_.reset();
1723 
1724  synchronize_lock_.unlock();
1725 
1726  return (true);
1727 }
1728 
1729 template <class Basis>
1730 void
1732 {
1733  /// @todo: This can crash if you insert a new cell outside of the grid.
1734  // Need to recompute grid at that point.
1735 
1737  box.extend(points_(idx.k_,idx.j_,idx.i_));
1738  box.extend(points_(idx.k_+1,idx.j_,idx.i_));
1739  box.extend(points_(idx.k_,idx.j_+1,idx.i_));
1740  box.extend(points_(idx.k_+1,idx.j_+1,idx.i_));
1741  box.extend(points_(idx.k_,idx.j_,idx.i_+1));
1742  box.extend(points_(idx.k_+1,idx.j_,idx.i_+1));
1743  box.extend(points_(idx.k_,idx.j_+1,idx.i_+1));
1744  box.extend(points_(idx.k_+1,idx.j_+1,idx.i_+1));
1745  box.extend(epsilon_);
1746  elem_grid_->insert(idx, box);
1747 }
1748 
1749 
1750 template <class Basis>
1751 void
1752 StructHexVolMesh<Basis>::remove_elem_from_grid(typename LatVolMesh<Basis>::Elem::index_type idx)
1753 {
1754  Core::Geometry::BBox box;
1755  box.extend(points_(idx.k_,idx.j_,idx.i_));
1756  box.extend(points_(idx.k_+1,idx.j_,idx.i_));
1757  box.extend(points_(idx.k_,idx.j_+1,idx.i_));
1758  box.extend(points_(idx.k_+1,idx.j_+1,idx.i_));
1759  box.extend(points_(idx.k_,idx.j_,idx.i_+1));
1760  box.extend(points_(idx.k_+1,idx.j_,idx.i_+1));
1761  box.extend(points_(idx.k_,idx.j_+1,idx.i_+1));
1762  box.extend(points_(idx.k_+1,idx.j_+1,idx.i_+1));
1763  box.extend(epsilon_);
1764  elem_grid_->remove(idx, box);
1765 }
1766 
1767 template <class Basis>
1768 void
1769 StructHexVolMesh<Basis>::insert_node_into_grid(typename LatVolMesh<Basis>::Node::index_type ni)
1770 {
1771  /// @todo: This can crash if you insert a new cell outside of the grid.
1772  // Need to recompute grid at that point.
1773  node_grid_->insert(ni,points_[ni]);
1774 }
1775 
1776 
1777 template <class Basis>
1778 void
1779 StructHexVolMesh<Basis>::remove_node_from_grid(typename LatVolMesh<Basis>::Node::index_type ni)
1780 {
1781  node_grid_->remove(ni,points_[ni]);
1782 }
1783 
1784 template <class Basis>
1785 void
1786 StructHexVolMesh<Basis>::compute_elem_grid(Core::Geometry::BBox& bb)
1787 {
1788  if (bb.valid())
1789  {
1790  // Cubed root of number of cells to get a subdivision ballpark.
1791 
1792  const size_type esz = (this->ni_-1)*(this->nj_-1)*(this->nk_-1);
1793 
1794  const size_type s =
1795  3*static_cast<size_type>((ceil(pow(static_cast<double>(esz) , (1.0/3.0))))/2.0 + 1.0);
1796 
1797  Core::Geometry::Vector diag = bb.diagonal();
1798  double trace = (diag.x()+diag.y()+diag.z());
1799  size_type sx = static_cast<size_type>(ceil(diag.x()/trace*s));
1800  size_type sy = static_cast<size_type>(ceil(diag.y()/trace*s));
1801  size_type sz = static_cast<size_type>(ceil(diag.z()/trace*s));
1802 
1803  Core::Geometry::BBox b = bb; b.extend(10*epsilon_);
1804  elem_grid_.reset(new SearchGridT<typename LatVolMesh<Basis>::Elem::index_type>(sx, sy, sz, b.min(), b.max()));
1805 
1806  typename LatVolMesh<Basis>::Elem::iterator ci, cie;
1807  this->begin(ci);
1808  this->end(cie);
1809  while(ci != cie)
1810  {
1811  insert_elem_into_grid(*ci);
1812  ++ci;
1813  }
1814  }
1815 
1816  synchronized_ |= Mesh::ELEM_LOCATE_E;
1817 }
1818 
1819 template <class Basis>
1820 void
1821 StructHexVolMesh<Basis>::compute_node_grid(Core::Geometry::BBox& bb)
1822 {
1823  if (bb.valid())
1824  {
1825  // Cubed root of number of cells to get a subdivision ballpark.
1826 
1827  const size_type esz = (this->ni_)*(this->nj_)*(this->nk_);
1828 
1829  const size_type s = 3*static_cast<size_type>
1830  ((ceil(pow(static_cast<double>(esz) , (1.0/3.0))))/2.0 + 1.0);
1831 
1832  Core::Geometry::Vector diag = bb.diagonal();
1833  double trace = (diag.x()+diag.y()+diag.z());
1834  size_type sx = static_cast<size_type>(ceil(diag.x()/trace*s));
1835  size_type sy = static_cast<size_type>(ceil(diag.y()/trace*s));
1836  size_type sz = static_cast<size_type>(ceil(diag.z()/trace*s));
1837 
1838  Core::Geometry::BBox b = bb; b.extend(10*epsilon_);
1839  node_grid_.reset(new SearchGridT<typename LatVolMesh<Basis>::Node::index_type>(sx, sy, sz, b.min(), b.max()));
1840 
1841  typename LatVolMesh<Basis>::Node::iterator ni, nie;
1842  this->begin(ni);
1843  this->end(nie);
1844  while(ni != nie)
1845  {
1846  insert_node_into_grid(*ni);
1847  ++ni;
1848  }
1849  }
1850 
1851  synchronized_ |= Mesh::NODE_LOCATE_E;
1852 }
1853 
1854 
1855 
1856 template <class Basis>
1857 void
1858 StructHexVolMesh<Basis>::compute_epsilon(Core::Geometry::BBox& bb)
1859 {
1860  epsilon_ = bb.diagonal().length()*1e-8;
1861  epsilon2_ = epsilon_*epsilon_;
1862  epsilon3_ = epsilon_*epsilon_*epsilon_;
1863  synchronized_ |= Mesh::EPSILON_E;
1864 }
1865 
1866 #define STRUCT_HEX_VOL_MESH_VERSION 2
1867 
1868 template <class Basis>
1869 void
1871 {
1872  int version = stream.begin_class(type_name(-1), STRUCT_HEX_VOL_MESH_VERSION);
1873  LatVolMesh<Basis>::io(stream);
1874  /// IO data members, in order
1875 
1876  if (version == 1)
1877  {
1878  /// The dimensions of this array were swapped
1880  Pio(stream, tpoints);
1881 
1882  size_type dim1 = tpoints.dim1();
1883  size_type dim2 = tpoints.dim2();
1884  size_type dim3 = tpoints.dim3();
1885 
1886  points_.resize(dim3,dim2,dim1);
1887  for (size_type i=0; i<dim1; i++)
1888  for (size_type j=0; j<dim2; j++)
1889  for (size_type k=0; k<dim3; k++)
1890  points_(k,j,i) = tpoints(i,j,k);
1891  }
1892  else
1893  {
1894  Pio(stream, points_);
1895  }
1896  stream.end_class();
1897 
1898  if (stream.reading())
1899  this->vmesh_.reset(CreateVStructHexVolMesh(this));
1900 }
1901 
1902 template <class Basis>
1903 const std::string
1905 {
1906  ASSERT((n >= -1) && n <= 1);
1907  if (n == -1)
1908  {
1909  static const std::string name = TypeNameGenerator::make_template_id(type_name(0), type_name(1));
1910  return name;
1911  }
1912  else if (n == 0)
1913  {
1914  static const std::string nm("StructHexVolMesh");
1915  return nm;
1916  }
1917  else
1918  {
1919  return find_type_name((Basis *)0);
1920  }
1921 }
1922 
1923 template <class Basis>
1924 const TypeDescription*
1926 {
1927  static TypeDescription *td = 0;
1928  if (!td)
1929  {
1930  const TypeDescription *sub = get_type_description((Basis*)0);
1932  (*subs)[0] = sub;
1933  td = new TypeDescription("StructHexVolMesh", subs,
1934  std::string(__FILE__),
1935  "SCIRun",
1937  }
1938  return td;
1939 }
1940 
1941 
1942 template <class Basis>
1943 const TypeDescription*
1945 {
1947 }
1948 
1949 
1950 template <class Basis>
1951 const TypeDescription*
1953 {
1954  static TypeDescription *td = 0;
1955  if (!td)
1956  {
1957  const TypeDescription *me =
1959  td = new TypeDescription(me->get_name() + "::Node",
1960  std::string(__FILE__),
1961  "SCIRun",
1963  }
1964  return td;
1965 }
1966 
1967 
1968 template <class Basis>
1969 const TypeDescription*
1971 {
1972  static TypeDescription *td = 0;
1973  if (!td)
1974  {
1975  const TypeDescription *me =
1977  td = new TypeDescription(me->get_name() + "::Edge",
1978  std::string(__FILE__),
1979  "SCIRun",
1981  }
1982  return td;
1983 }
1984 
1985 
1986 template <class Basis>
1987 const TypeDescription*
1989 {
1990  static TypeDescription *td = 0;
1991  if (!td)
1992  {
1993  const TypeDescription *me =
1995  td = new TypeDescription(me->get_name() + "::Face",
1996  std::string(__FILE__),
1997  "SCIRun",
1999  }
2000  return td;
2001 }
2002 
2003 
2004 template <class Basis>
2005 const TypeDescription*
2007 {
2008  static TypeDescription *td = 0;
2009  if (!td)
2010  {
2011  const TypeDescription *me =
2013  td = new TypeDescription(me->get_name() + "::Cell",
2014  std::string(__FILE__),
2015  "SCIRun",
2017  }
2018  return td;
2019 }
2020 
2021 } /// namespace SCIRun
2022 
2023 #endif /// SCI_project_StructHexVolMesh_h
NodeIter iterator
Definition: LatVolMesh.h:425
bool find_closest_elem(double &pdist, Core::Geometry::Point &result, ARRAY &coords, INDEX &elem, const Core::Geometry::Point &p) const
Definition: StructHexVolMesh.h:299
double get_epsilon() const
Definition: StructHexVolMesh.h:763
bool reading() const
Definition: Persistent.h:164
index_type i_
Definition: LatVolMesh.h:127
std::vector< index_type > array_type
Definition: LatVolMesh.h:449
index_type node4_index() const
Definition: StructHexVolMesh.h:154
int get_weights(const Core::Geometry::Point &, typename LatVolMesh< Basis >::Edge::array_type &, double *)
Definition: StructHexVolMesh.h:608
Definition: FieldRNG.h:37
virtual void io(Piostream &)
Export this class using the old Pio system.
Definition: StructHexVolMesh.h:1870
SCIRun::mask_type mask_type
Definition: StructHexVolMesh.h:107
size_type nj_
Definition: LatVolMesh.h:1111
std::string get_name(const std::string &type_sep_start="<", const std::string &type_sep_end="> ") const
Definition: TypeDescription.cc:135
static MeshHandle structhexvol_maker(size_type x, size_type y, size_type z)
This function returns a handle for the virtual interface.
Definition: StructHexVolMesh.h:791
static const TypeDescription * node_type_description()
Definition: StructHexVolMesh.h:1952
Definition: Mesh.h:85
StructHexVolMesh()
Definition: StructHexVolMesh.h:1083
Vector project(const Vector &p) const
Definition: Transform.cc:425
double get_length(typename LatVolMesh< Basis >::Edge::index_type idx) const
Definition: StructHexVolMesh.h:252
Definition: Mesh.h:64
Point max() const
Definition: BBox.h:195
ElemData(const StructHexVolMesh< Basis > &msh, const typename LatVolMesh< Basis >::Cell::index_type ind)
Definition: StructHexVolMesh.h:125
#define ASSERTMSG(condition, message)
Definition: Exception.h:113
Array3< Core::Geometry::Point > & get_points()
Definition: StructHexVolMesh.h:798
virtual void transform(const Core::Geometry::Transform &t)
Definition: StructHexVolMesh.h:1184
const Core::Geometry::Point & node3() const
Definition: StructHexVolMesh.h:188
bool locate(typename LatVolMesh< Basis >::Node::index_type &node, const Core::Geometry::Point &p) const
Definition: StructHexVolMesh.h:260
static const TypeDescription * elem_type_description()
Definition: StructHexVolMesh.h:783
bool locate(typename LatVolMesh< Basis >::Cell::index_type &elem, std::vector< double > &coords, const Core::Geometry::Point &p) const
Definition: StructHexVolMesh.h:274
Definition: LatVolMesh.h:63
Definition: Mesh.h:90
Definition: Persistent.h:89
StructHexVolMesh< Basis >::index_type index_type
Definition: StructHexVolMesh.h:123
bool locate(typename LatVolMesh< Basis >::Edge::index_type &, const Core::Geometry::Point &) const
Definition: StructHexVolMesh.h:264
index_type node5_index() const
Definition: StructHexVolMesh.h:159
size_t dim2() const
Definition: Array3.h:109
Definition: Persistent.h:187
void lookup_ijk(iterator &begin, iterator &end, size_type i, size_type j, size_type k)
Definition: SearchGridT.h:207
BBox & extend(const Point &p)
Expand the bounding box to include point p.
Definition: BBox.h:98
void get_random_point(Core::Geometry::Point &p, const typename LatVolMesh< Basis >::Elem::index_type &i, FieldRNG &rng) const
Definition: StructHexVolMesh.h:1589
Definition: TypeDescription.h:50
bool find_closest_elem(double &pdist, Core::Geometry::Point &result, INDEX &elem, const Core::Geometry::Point &p) const
Definition: StructHexVolMesh.h:289
int get_weights(const Core::Geometry::Point &, typename LatVolMesh< Basis >::Face::array_type &, double *)
Definition: StructHexVolMesh.h:611
FieldHandle mesh()
Definition: BuildTDCSMatrixTests.cc:56
static PersistentTypeID structhexvol_typeid
Definition: StructHexVolMesh.h:772
Definition: Mesh.h:84
Definition: Point.h:49
Definition: TypeDescription.h:45
#define SCISHARE
Definition: share.h:39
std::vector< const TypeDescription * > td_vec
Definition: TypeDescription.h:56
bool get_coords(VECTOR &coords, const Core::Geometry::Point &p, typename LatVolMesh< Basis >::Elem::index_type idx) const
Definition: StructHexVolMesh.h:632
size_type nk_
Definition: LatVolMesh.h:1111
double tetrahedra_volume(const Point &p0, const Point &p1, const Point &p2, const Point &p3)
Definition: CompGeom.cc:389
Definition: Mesh.h:45
Definition: BBox.h:46
virtual int topology_geometry() const
Definition: StructHexVolMesh.h:234
boost::shared_ptr< Mesh > MeshHandle
Definition: DatatypeFwd.h:67
Definition: Mesh.h:61
NodeIndex index_type
Definition: LatVolMesh.h:424
unsigned int mask_type
Definition: Types.h:45
bool find_closest_elems(double &pdist, Core::Geometry::Point &result, std::vector< typename LatVolMesh< Basis >::Elem::index_type > &elems, const Core::Geometry::Point &p) const
Find the closest elements to a point.
Definition: StructHexVolMesh.h:1388
SCIRun::size_type size_type
Definition: StructHexVolMesh.h:106
#define ASSERT(condition)
Definition: Assert.h:110
const Core::Geometry::Point & node5() const
Definition: StructHexVolMesh.h:196
size_t dim3() const
Definition: Array3.h:110
const Core::Geometry::Point & node6() const
Definition: StructHexVolMesh.h:200
Declarations for virtual interface.
Definition: StructHexVolMesh.h:75
virtual int begin_class(const std::string &name, int current_version)
Definition: Persistent.cc:143
bool inside(typename LatVolMesh< Basis >::Elem::index_type idx, const Core::Geometry::Point &p) const
Definition: StructHexVolMesh.h:800
bool locate(typename LatVolMesh< Basis >::Face::index_type &, const Core::Geometry::Point &) const
Definition: StructHexVolMesh.h:267
Definition: Vector.h:63
Definition: BoostGraphExampleTests.cc:86
virtual void set_dim(const std::vector< size_type > &dims)
Definition: StructHexVolMesh.h:221
double DetMatrix3P(const VectorOfPoints &p)
Inline templated determinant of matrix.
Definition: Locate.h:120
index_type j_
Definition: LatVolMesh.h:127
const string find_type_name(float *)
Definition: TypeName.cc:63
size_type ni_
Definition: LatVolMesh.h:1111
virtual ~StructHexVolMesh()
Definition: StructHexVolMesh.h:115
const Core::Geometry::Point & node2() const
Definition: StructHexVolMesh.h:184
bool locate(typename LatVolMesh< Basis >::Cell::index_type &elem, const Core::Geometry::Point &p) const
Definition: StructHexVolMesh.h:270
virtual Core::Geometry::BBox get_bounding_box() const
get the mesh statistics
Definition: StructHexVolMesh.h:1165
T DetMatrix3x3(const T *p)
Definition: Locate.h:95
index_type node7_index() const
Definition: StructHexVolMesh.h:170
VMesh * CreateVStructHexVolMesh(MESH *mesh)
Definition: StructHexVolMesh.h:81
double inverse_jacobian(const VECTOR &coords, typename LatVolMesh< Basis >::Elem::index_type idx, double *Ji) const
Definition: StructHexVolMesh.h:701
Definition: Mesh.h:86
static Persistent * maker()
This function returns a maker for Pio.
Definition: StructHexVolMesh.h:787
const Core::Geometry::Point & node7() const
Definition: StructHexVolMesh.h:204
Definition: SearchGridT.h:47
const char * name[]
Definition: BoostGraphExampleTests.cc:87
double scaled_jacobian_metric(typename LatVolMesh< Basis >::Elem::index_type idx) const
Definition: StructHexVolMesh.h:722
void est_closest_point_on_quad(Point &result, const Point &orig, const Point &p0, const Point &p1, const Point &p2, const Point &p3, const double epsilon)
Definition: CompGeom.cc:226
index_type node6_index() const
Definition: StructHexVolMesh.h:165
long long size_type
Definition: Types.h:40
static const std::string type_name(int n=-1)
Core functionality for getting the name of a templated mesh class.
Definition: StructHexVolMesh.h:1904
Vector Cross(const Vector &v1, const Vector &v2)
Definition: Vector.h:378
double ScaledDetMatrix3P(const VectorOfPoints &p)
Inline templated determinant of matrix.
Definition: Locate.h:132
Definition: Mesh.h:71
void jacobian(const VECTOR &coords, typename LatVolMesh< Basis >::Elem::index_type idx, double *J) const
Definition: StructHexVolMesh.h:678
Definition: LatVolMesh.h:208
double det_jacobian(const VECTOR &coords, typename LatVolMesh< Basis >::Elem::index_type idx) const
Definition: StructHexVolMesh.h:666
Definition: Mesh.h:74
const Core::Geometry::Point & node1() const
Definition: StructHexVolMesh.h:180
virtual bool get_dim(std::vector< size_type > &) const
Definition: StructHexVolMesh.h:1150
bool find_closest_node(double &pdist, Core::Geometry::Point &result, typename LatVolMesh< Basis >::Node::index_type &node, const Core::Geometry::Point &p) const
Definition: StructHexVolMesh.h:279
double get_size(const typename LatVolMesh< Basis >::Node::index_type &idx) const
Definition: StructHexVolMesh.h:1517
index_type node1_index() const
Definition: StructHexVolMesh.h:138
Point min() const
Definition: BBox.h:192
Distinct type for face index.
Definition: FieldIndex.h:90
void get_point(Core::Geometry::Point &point, const typename LatVolMesh< Basis >::Node::index_type &index) const
Definition: StructHexVolMesh.h:617
Definition: Transform.h:53
void x(double)
Definition: Vector.h:175
Basis basis_
Definition: LatVolMesh.h:1114
virtual const TypeDescription * get_type_description() const
Definition: StructHexVolMesh.h:1944
double tri_area(const Core::Geometry::Point &a, const Core::Geometry::Point &b, const Core::Geometry::Point &c)
Definition: StructHexVolMesh.h:1510
virtual bool unsynchronize(mask_type)
Definition: StructHexVolMesh.h:1705
std::vector< index_type > array_type
Definition: LatVolMesh.h:435
static const std::string make_template_id(const std::string &templateName, const std::string &templateParam)
Definition: TypeName.h:62
bool inside(const Point &p) const
Definition: BBox.h:205
static const TypeDescription * cell_type_description()
Definition: StructHexVolMesh.h:2006
v
Definition: readAllFields.py:42
Definition: LatVolMesh.h:146
bool locate_node(INDEX &node, const Core::Geometry::Point &p) const
Definition: StructHexVolMesh.h:954
double get_area(typename LatVolMesh< Basis >::Face::index_type idx) const
Definition: StructHexVolMesh.h:254
std::vector< index_type > array_type
Definition: LatVolMesh.h:442
SCIRun::index_type under_type
Types that change depending on 32 or 64bits.
Definition: StructHexVolMesh.h:104
void y(double)
Definition: Vector.h:185
Definition: Mesh.h:75
#define ASSERTFAIL(string)
Definition: Assert.h:52
void Pio(Piostream &stream, Array1< T > &array)
Definition: Array1.h:65
size_t dim1() const
Definition: Array3.h:108
double jacobian_metric(typename LatVolMesh< Basis >::Elem::index_type idx) const
Definition: StructHexVolMesh.h:742
bool clear_synchronization()
Definition: StructHexVolMesh.h:1712
bool find_closest_elem(double &pdist, Core::Geometry::Point &result, ARRAY &coords, INDEX &elem, const Core::Geometry::Point &p, double maxdist) const
Definition: StructHexVolMesh.h:309
void get_center(Core::Geometry::Point &, const typename LatVolMesh< Basis >::Node::index_type &) const
get the center point (in object space) of an element
Definition: StructHexVolMesh.h:1208
friend class VStructHexVolMesh
Definition: StructHexVolMesh.h:100
CellIndex index_type
Definition: LatVolMesh.h:446
virtual void end_class()
Definition: Persistent.cc:178
CellIter iterator
Definition: LatVolMesh.h:447
Definition: StructHexVolMesh.h:120
int get_weights(const Core::Geometry::Point &, typename LatVolMesh< Basis >::Node::array_type &, double *)
Definition: StructHexVolMesh.h:1400
long long index_type
Definition: Types.h:39
const Core::Geometry::Point & node4() const
Definition: StructHexVolMesh.h:192
#define STRUCT_HEX_VOL_MESH_VERSION
Definition: StructHexVolMesh.h:1866
Definition: Mesh.h:83
void interpolate(Core::Geometry::Point &pt, const VECTOR &coords, typename LatVolMesh< Basis >::Elem::index_type idx) const
Definition: StructHexVolMesh.h:642
boost::shared_ptr< StructHexVolMesh< Basis > > handle_type
Definition: StructHexVolMesh.h:109
Definition: LatVolMesh.h:133
virtual bool synchronize(mask_type)
Definition: StructHexVolMesh.h:1662
Definition: Persistent.h:64
static const TypeDescription * edge_type_description()
Definition: StructHexVolMesh.h:1970
Distinct type for edge index.
Definition: FieldIndex.h:81
int n
Definition: eab.py:9
SCIRun::mask_type mask_type
Definition: LatVolMesh.h:96
static MeshHandle mesh_maker()
This function returns a handle for the virtual interface.
Definition: StructHexVolMesh.h:789
T InverseMatrix3x3(const T *p, T *q)
Definition: Locate.h:47
void set_point(const Core::Geometry::Point &point, const typename LatVolMesh< Basis >::Node::index_type &index)
Definition: StructHexVolMesh.h:1581
Interface to dynamic 3D array class.
virtual void io(Piostream &)
Export this class using the old Pio system.
Definition: LatVolMesh.h:2378
static const TypeDescription * face_type_description()
Definition: StructHexVolMesh.h:1988
#define DEBUG_CONSTRUCTOR(type)
Definition: Debug.h:64
const LatVolMesh * mesh_
Definition: LatVolMesh.h:130
SCIRun::size_type size_type
Definition: LatVolMesh.h:95
boost::shared_ptr< VMesh > vmesh_
Definition: LatVolMesh.h:1125
Definition: Array3.h:64
void z(double)
Definition: Vector.h:195
Definition: VMesh.h:53
SCIRun::index_type index_type
Definition: StructHexVolMesh.h:105
index_type k_
Definition: LatVolMesh.h:127
double get_volume(const typename LatVolMesh< Basis >::Cell::index_type &i) const
Definition: StructHexVolMesh.h:256
boost::mutex Mutex
Definition: SchedulingWithBoostGraph.cc:434
bool locate_elem(INDEX &elem, ARRAY &coords, const Core::Geometry::Point &p) const
Definition: StructHexVolMesh.h:908
index_type node3_index() const
Definition: StructHexVolMesh.h:149
void derivate(const VECTOR1 &coords, typename LatVolMesh< Basis >::Elem::index_type idx, VECTOR2 &J) const
Definition: StructHexVolMesh.h:654
virtual StructHexVolMesh * clone() const
Definition: StructHexVolMesh.h:114
index_type node2_index() const
Definition: StructHexVolMesh.h:143
bool locate_elem(INDEX &elem, const Core::Geometry::Point &p) const
Definition: StructHexVolMesh.h:839
void get_nodes(typename Node::array_type &, typename Edge::index_type) const
get the child elements of the given index
Definition: LatVolMesh.h:1386
const Core::Geometry::Point & node0() const
Definition: StructHexVolMesh.h:176
bool locate_elems(ARRAY &array, const Core::Geometry::BBox &b) const
Definition: StructHexVolMesh.h:877
#define DEBUG_DESTRUCTOR(type)
Definition: Debug.h:65
const TypeDescription * get_type_description(Core::Basis::ConstantBasis< T > *)
Definition: Constant.h:209
index_type node0_index() const
the following designed to coordinate with ::get_nodes
Definition: StructHexVolMesh.h:133
bool elem_locate(INDEX &elem, MESH &msh, const Core::Geometry::Point &p)
General case locate, search each elem.
Definition: Mesh.h:188