SCIRun  5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CurveMesh.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 #ifndef CORE_DATATYPES_CURVEMESH_H
30 #define CORE_DATATYPES_CURVEMESH_H 1
31 
32 /// Include what kind of support we want to have
33 /// Need to fix this and couple it sci-defs
35 
38 
43 
44 #include <Core/Basis/Locate.h>
47 #include <Core/Basis/CrvCubicHmt.h>
48 
49 #include <Core/Thread/Mutex.h>
50 
56 
58 
59 namespace SCIRun {
60 
61 /////////////////////////////////////////////////////
62 /// Declarations for virtual interface
63 
64 template <class Basis> class CurveMesh;
65 
66 /// make sure any other mesh other than the preinstantiate ones
67 /// returns no virtual interface. Altering this behavior will allow
68 /// for dynamically compiling the interface if needed.
69 template<class MESH>
70 VMesh* CreateVCurveMesh(MESH*) { return (0); }
71 
72 #if (SCIRUN_CURVE_SUPPORT > 0)
73 /// Declare that these can be found in a library that is already
74 /// precompiled. So dynamic compilation will not instantiate them again.
75 SCISHARE VMesh* CreateVCurveMesh(CurveMesh<Core::Basis::CrvLinearLgn<Core::Geometry::Point> >* mesh);
76 #if (SCIRUN_QUADRATIC_SUPPORT > 0)
77 SCISHARE VMesh* CreateVCurveMesh(CurveMesh<Core::Basis::CrvQuadraticLgn<Core::Geometry::Point> >* mesh);
78 #endif
79 #if (SCIRUN_CUBIC_SUPPORT > 0)
80 SCISHARE VMesh* CreateVCurveMesh(CurveMesh<Core::Basis::CrvCubicHmt<Core::Geometry::Point> >* mesh);
81 #endif
82 
83 #endif
84 /////////////////////////////////////////////////////
85 
86 /////////////////////////////////////////////////////
87 /// Declarations for CurveMesh class
88 
89 template <class Basis>
90 class CurveMesh : public Mesh
91 {
92 
93 /// Make sure the virtual interface has access
94 template<class MESH> friend class VCurveMesh;
95 template<class MESH> friend class VMeshShared;
96 template<class MESH> friend class VUnstructuredMesh;
97 
98 public:
99 
100  // Types that change depending on 32 or 64bits
105 
106  typedef boost::shared_ptr<CurveMesh<Basis> > handle_type;
107  typedef Basis basis_type;
108 
109  /// Index and Iterator types required for Mesh Concept.
110  struct Node {
115  };
116 
117  struct Edge {
121  typedef std::vector<index_type> array_type;
122  };
123 
124  /// For dynamic compilation to be compatible with
125  /// other mesh types
126  struct Face {
130  typedef std::vector<index_type> array_type;
131  };
132 
133  /// For dynamic compilation to be compatible with
134  /// other mesh types
135  struct Cell {
139  typedef std::vector<index_type> array_type;
140  };
141 
142  /// Elem refers to the most complex topological object
143  /// DElem refers to object just below Elem in the topological hierarchy
144 
145  typedef Edge Elem;
146  typedef Node DElem;
147 
148  /// Definition specific to this class (should at some point jsut
149  /// remove this and make it similar to the other classes)
150  typedef std::pair<typename Node::index_type,
152 
153 
154  /// Somehow the information of how to interpolate inside an element
155  /// ended up in a separate class, as they need to share information
156  /// this construction was created to transfer data.
157  /// Hopefully in the future this class will disappear again.
158  friend class ElemData;
159 
160  class ElemData
161  {
162  public:
164 
165  ElemData(const CurveMesh<Basis>& msh, const index_type idx) :
166  mesh_(msh),
167  index_(idx)
168  {}
169 
170  inline
172  return mesh_.edges_[2*index_];
173  }
174  inline
176  return mesh_.edges_[2*index_+1];
177  }
178 
179  inline
180  const Core::Geometry::Point &node0() const {
181  return mesh_.points_[mesh_.edges_[2*index_]];
182  }
183  inline
184  const Core::Geometry::Point &node1() const {
185  return mesh_.points_[mesh_.edges_[2*index_+1]];
186  }
187 
188  inline
190  {
191  return index_;
192  }
193 
194  private:
195  /// reference of the mesh
196  const CurveMesh<Basis> &mesh_;
197  /// copy of index
198  const index_type index_;
199  };
200 
201  //////////////////////////////////////////////////////////////////
202 
203  CurveMesh();
204 
205  /// Copy a mesh, needed for detaching the mesh from a field
206  CurveMesh(const CurveMesh &copy);
207 
208  /// Clone function for detaching the mesh and automatically generating
209  /// a new version if needed.
210  virtual CurveMesh *clone() const { return new CurveMesh(*this); }
211 
213  {
214  return boost::make_shared<Core::Datatypes::VirtualMeshFacade<VMesh>>(vmesh_);
215  }
216 
217  virtual ~CurveMesh();
218 
219  /// Obtain the virtual interface pointer
220  virtual VMesh* vmesh() { return (vmesh_.get()); }
221 
222  /// This one should go at some point, should be reroute through the
223  /// virtual interface
224  virtual int basis_order() { return (basis_.polynomial_order()); }
225 
226  /// Topological dimension
227  virtual int dimensionality() const { return 1; }
228 
229  /// What kind of mesh is this
230  /// structured = no connectivity data
231  /// regular = no node location data
232  virtual int topology_geometry() const
233  { return (Mesh::UNSTRUCTURED | Mesh::IRREGULAR); }
234 
235  /// Get the bounding box of the field
236  virtual Core::Geometry::BBox get_bounding_box() const;
237 
238  /// Return the transformation that takes a 0-1 space bounding box
239  /// to the current bounding box of this mesh.
240  virtual void get_canonical_transform(Core::Geometry::Transform &t) const;
241 
242  virtual void compute_bounding_box();
243 
244  /// Transform a field
245  virtual void transform(const Core::Geometry::Transform &t);
246 
247  /// Check whether mesh can be altered by adding nodes or elements
248  virtual bool is_editable() const { return (true); }
249 
250  /// Has this mesh normals.
251  virtual bool has_normals() const { return (false); }
252 
253  /// Compute tables for doing topology, these need to be synchronized
254  /// before doing a lot of operations.
255  virtual bool synchronize(mask_type sync);
256  virtual bool unsynchronize(mask_type sync);
257  bool clear_synchronization();
258 
259  /// Get the basis class
260  Basis& get_basis() { return basis_; }
261 
262  /// begin/end iterators
263  void begin(typename Node::iterator &) const;
264  void begin(typename Edge::iterator &) const;
265  void begin(typename Face::iterator &) const;
266  void begin(typename Cell::iterator &) const;
267 
268  void end(typename Node::iterator &) const;
269  void end(typename Edge::iterator &) const;
270  void end(typename Face::iterator &) const;
271  void end(typename Cell::iterator &) const;
272 
273  /// Get the iteration sizes
274  void size(typename Node::size_type &) const;
275  void size(typename Edge::size_type &) const;
276  void size(typename Face::size_type &) const;
277  void size(typename Cell::size_type &) const;
278 
279  /// These are here to convert indices to unsigned int
280  /// counters. Some how the decision was made to use multi
281  /// dimensional indices in some fields, these functions
282  /// should deal with different pointer types.
283  /// Use the virtual interface to avoid all this non sense.
284  inline void to_index(typename Node::index_type &index, index_type i) const
285  { index = i; }
286  inline void to_index(typename Edge::index_type &index, index_type i) const
287  { index = i; }
288  inline void to_index(typename Face::index_type&, index_type) const
289  { ASSERTFAIL("This mesh type does not have faces use \"elem\"."); }
290  inline void to_index(typename Cell::index_type&, index_type) const
291  { ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
292 
293 
294  /// Get the child elements of the given index.
295  void get_nodes(typename Node::array_type &array,
296  typename Node::index_type idx) const
297  { array.resize(1); array[0]= idx; }
298  void get_nodes(typename Node::array_type &array,
299  typename Edge::index_type idx) const
300  { get_nodes_from_edge(array,idx); }
301  void get_nodes(typename Node::array_type&,
302  typename Face::index_type) const
303  { ASSERTFAIL("This mesh type does not have faces use \"elem\"."); }
304  void get_nodes(typename Node::array_type&,
305  typename Cell::index_type) const
306  { ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
307 
308  void get_edges(typename Edge::array_type &array,
309  typename Node::index_type idx) const
310  { get_edges_from_node(array,idx); }
311  void get_edges(typename Edge::array_type &array,
312  typename Edge::index_type idx) const
313  { array.resize(1); array[0]= idx; }
314  void get_edges(typename Edge::array_type&,
315  typename Face::index_type) const
316  { ASSERTFAIL("This mesh type does not have faces use \"elem\"."); }
317  void get_edges(typename Edge::array_type&,
318  typename Cell::index_type) const
319  { ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
320 
321  void get_faces(typename Face::array_type&,
322  typename Node::index_type) const
323  { ASSERTFAIL("This mesh type does not have faces use \"elem\"."); }
324  void get_faces(typename Face::array_type&,
325  typename Edge::index_type) const
326  { ASSERTFAIL("This mesh type does not have faces use \"elem\"."); }
327  void get_faces(typename Face::array_type&,
328  typename Face::index_type) const
329  { ASSERTFAIL("This mesh type does not have faces use \"elem\"."); }
330  void get_faces(typename Face::array_type&,
331  typename Cell::index_type) const
332  { ASSERTFAIL("This mesh type does not have faces use \"elem\"."); }
333 
334  void get_cells(typename Cell::array_type&,
335  typename Node::index_type) const
336  { ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
337  void get_cells(typename Cell::array_type&,
338  typename Edge::index_type) const
339  { ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
340  void get_cells(typename Cell::array_type&,
341  typename Face::index_type) const
342  { ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
343  void get_cells(typename Cell::array_type&,
344  typename Cell::index_type) const
345  { ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
346 
347  void get_elems(typename Elem::array_type &array,
348  typename Node::index_type idx) const
349  { get_edges_from_node(array,idx); }
350  void get_elems(typename Elem::array_type &array,
351  typename Edge::index_type idx) const
352  { array.resize(1); array[0]= idx; }
353  void get_elems(typename Elem::array_type&,
354  typename Face::index_type) const
355  { ASSERTFAIL("This mesh type does not have faces use \"elem\"."); }
356  void get_elems(typename Face::array_type&,
357  typename Cell::index_type) const
358  { ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
359 
360  void get_delems(typename DElem::array_type &array,
361  typename Node::index_type idx) const
362  { array.resize(1); array[0]= idx; }
363  void get_delems(typename DElem::array_type &array,
364  typename Edge::index_type idx) const
365  { get_nodes_from_edge(array,idx); }
366  void get_delems(typename DElem::array_type&,
367  typename Face::index_type) const
368  { ASSERTFAIL("This mesh type does not have faces use \"elem\"."); }
369  void get_delems(typename DElem::array_type&,
370  typename Cell::index_type) const
371  { ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
372 
373 
374 
375  /// Generate the list of points that make up a sufficiently accurate
376  /// piecewise linear approximation of an edge.
377  template<class VECTOR>
378  void pwl_approx_edge(VECTOR &coords,
379  typename Elem::index_type,
380  unsigned int which_edge,
381  unsigned int div_per_unit) const
382  {
383  // only one edge in the unit edge.
384  basis_.approx_edge(which_edge, div_per_unit, coords);
385  }
386 
387  /// Generate the list of points that make up a sufficiently accurate
388  /// piecewise linear approximation of an face.
389  template<class VECTOR>
390  void pwl_approx_face(VECTOR& /*coords*/,
391  typename Elem::index_type /*ci*/,
392  typename Face::index_type /*fi*/,
393  unsigned int /*div_per_unit*/) const
394  {
395  ASSERTFAIL("CurveMesh: cannot approximate faces");
396  }
397 
398  /// get the center point (in object space) of an element
399  void get_center(Core::Geometry::Point &result, typename Node::index_type idx) const
400  { result = points_[idx]; }
401  void get_center(Core::Geometry::Point &, typename Edge::index_type) const;
403  { ASSERTFAIL("This mesh type does not have faces use \"elem\"."); }
405  { ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
406 
407  const Core::Geometry::Point &point(typename Node::index_type i) const { return points_[i]; }
408 
409  /// Get the size of an element (length, area, volume)
410  double get_size(typename Node::index_type /*idx*/) const
411  { return 0.0; }
412  double get_size(typename Edge::index_type idx) const;
413  double get_size(typename Face::index_type) const
414  { ASSERTFAIL("This mesh type does not have faces use \"elem\"."); }
415  double get_size(typename Cell::index_type) const
416  { ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
417 
418  /// More specific names for get_size
419  double get_length(typename Edge::index_type idx) const
420  { return get_size(idx); }
421  double get_area(typename Face::index_type) const
422  { ASSERTFAIL("This mesh type does not have faces use \"elem\"."); }
423  double get_volume(typename Cell::index_type) const
424  { ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
425 
426  /// Get neighbors of an element or a node
427  /// THIS ONE IS FLAWED AS IN 3D SPACE A NODE CAN BE CONNECTED TO
428  /// MANY ELEMENTS
429  bool get_neighbor(typename Elem::index_type &neighbor,
430  typename Elem::index_type edge,
431  typename DElem::index_type node) const
432  {
433  return(get_elem_neighbor(neighbor,edge,node));
434  }
435 
436  /// These are more general neighbor functions
437  void get_neighbors(std::vector<typename Node::index_type> &array,
438  typename Node::index_type idx) const
439  {
440  get_node_neighbors(array,idx);
441  }
442 
443  bool get_neighbors(std::vector<typename Elem::index_type> &array,
444  typename Elem::index_type edge,
445  typename DElem::index_type idx) const
446  {
447  return(get_elem_neighbors(array,edge,idx));
448  }
449 
450  void get_neighbors(std::vector<typename Elem::index_type> &array,
451  typename Elem::index_type idx) const
452  {
453  get_elem_neighbors(array,idx);
454  }
455 
456  /// Locate a point in a mesh, find which is the closest node
457  bool locate(typename Node::index_type &i, const Core::Geometry::Point &p) const
458  { return(locate_node(i,p)); }
459  bool locate(typename Edge::index_type &i, const Core::Geometry::Point &p) const
460  { return(locate_elem(i,p)); }
461  bool locate(typename Face::index_type &, const Core::Geometry::Point &) const
462  { ASSERTFAIL("This mesh type does not have faces use \"elem\"."); }
463  bool locate(typename Cell::index_type &, const Core::Geometry::Point &) const
464  { ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
465 
466 
467  /// These should become obsolete soon, they do not follow the concept
468  /// of the basis functions....
469  int get_weights(const Core::Geometry::Point &p, typename Node::array_type &l, double *w);
470  int get_weights(const Core::Geometry::Point &p, typename Edge::array_type &l, double *w);
471 
472  int get_weights(const Core::Geometry::Point &, typename Face::array_type &, double *)
473  { ASSERTFAIL("This mesh type does not have faces use \"elem\"."); }
474  int get_weights(const Core::Geometry::Point &, typename Cell::array_type &, double *)
475  { ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
476 
477  /// Access the nodes of the mesh
478  void get_point(Core::Geometry::Point &result, typename Node::index_type idx) const
479  { get_center(result,idx); }
481  { points_[index] = point; }
482  void get_random_point(Core::Geometry::Point &p, typename Elem::index_type i, FieldRNG &r) const;
483 
484  /// Normals for visualizations
486  { ASSERTFAIL("CurveMesh: This mesh type does not have node normals."); }
487 
488  template<class VECTOR, class INDEX1, class INDEX2>
489  void get_normal(Core::Geometry::Vector&, VECTOR&, INDEX1, INDEX2) const
490  { ASSERTFAIL("CurveMesh: This mesh type does not have element normals."); }
491 
492  /// use these to build up a new contour mesh
494  {
495  points_.push_back(p);
496  return static_cast<under_type>(points_.size() - 1);
497  }
498 
500  { return add_node(point); }
501 
503  typename Node::index_type i2)
504  {
505  edges_.push_back(i1);
506  edges_.push_back(i2);
507  return static_cast<index_type>((edges_.size()>>1)-1);
508  }
509 
510  template <class ARRAY>
511  typename Elem::index_type add_elem(ARRAY a)
512  {
513  ASSERTMSG(a.size() == 2, "Tried to add non-line element.");
514  edges_.push_back(static_cast<typename Node::index_type>(a[0]));
515  edges_.push_back(static_cast<typename Node::index_type>(a[1]));
516  return static_cast<index_type>((edges_.size()>>1)-1);
517  }
518 
519  /// Functions to improve memory management. Often one knows how many
520  /// nodes/elements one needs, prereserving memory is often possible.
521  void node_reserve(size_type s) { points_.reserve(static_cast<size_t>(s)); }
522  void elem_reserve(size_type s) { edges_.reserve(static_cast<size_t>(2*s)); }
523  void resize_nodes(size_type s) { points_.resize(static_cast<size_t>(s)); }
524  void resize_elems(size_type s) { edges_.resize(static_cast<size_t>(2*s)); }
525 
526  /// Get the local coordinates for a certain point within an element
527  /// This function uses a couple of newton iterations to find the local
528  /// coordinate of a point
529  template<class VECTOR, class INDEX>
530  bool get_coords(VECTOR &coords,const Core::Geometry::Point &p,INDEX idx) const
531  {
532  ElemData ed(*this, idx);
533  return basis_.get_coords(coords, p, ed);
534  }
535 
536  /// Find the location in the global coordinate system for a local coordinate
537  /// This function is the opposite of get_coords.
538  template<class VECTOR, class INDEX>
539  void interpolate(Core::Geometry::Point &pt, const VECTOR &coords, INDEX idx) const
540  {
541  ElemData ed(*this, idx);
542  pt = basis_.interpolate(coords, ed);
543  }
544 
545  /// Interpolate the derivate of the function, This infact will return the
546  /// jacobian of the local to global coordinate transformation. This function
547  /// is mainly intended for the non linear elements
548  template<class VECTOR1, class INDEX, class VECTOR2>
549  void derivate(const VECTOR1 &coords, INDEX idx, VECTOR2 &J) const
550  {
551  ElemData ed(*this, idx);
552  basis_.derivate(coords, ed, J);
553  }
554 
555  /// Get the determinant of the jacobian, which is the local volume of an element
556  /// and is intended to help with the integration of functions over an element.
557  template<class VECTOR, class INDEX>
558  double det_jacobian(const VECTOR& coords, INDEX idx) const
559  {
560  double J[9];
561  jacobian(coords,idx,J);
562  return (DetMatrix3x3(J));
563  }
564 
565  /// Get the jacobian of the transformation. In case one wants the non inverted
566  /// version of this matrix. This is currentl here for completeness of the
567  /// interface
568  template<class VECTOR, class INDEX>
569  void jacobian(const VECTOR& coords, INDEX idx, double* J) const
570  {
572  ElemData ed(*this,idx);
573  basis_.derivate(coords,ed,Jv);
574  Core::Geometry::Vector Jv1, Jv2;
575  Core::Geometry::Vector(Jv[0]).find_orthogonal(Jv1,Jv2);
576  J[0] = Jv[0].x();
577  J[1] = Jv[0].y();
578  J[2] = Jv[0].z();
579  J[3] = Jv1.x();
580  J[4] = Jv1.y();
581  J[5] = Jv1.z();
582  J[6] = Jv2.x();
583  J[7] = Jv2.y();
584  J[8] = Jv2.z();
585  }
586 
587  /// Get the inverse jacobian of the transformation. This one is needed to
588  /// translate local gradients into global gradients. Hence it is crucial for
589  /// calculating gradients of fields, or constructing finite elements.
590  template<class VECTOR, class INDEX>
591  double inverse_jacobian(const VECTOR& coords, INDEX idx, double* Ji) const
592  {
594  ElemData ed(*this,idx);
595  basis_.derivate(coords,ed,Jv);
596  double J[9];
597  Core::Geometry::Vector Jv1, Jv2;
598  Core::Geometry::Vector(Jv[0]).find_orthogonal(Jv1,Jv2);
599  J[0] = Jv[0].x();
600  J[1] = Jv[0].y();
601  J[2] = Jv[0].z();
602  J[3] = Jv1.x();
603  J[4] = Jv1.y();
604  J[5] = Jv1.z();
605  J[6] = Jv2.x();
606  J[7] = Jv2.y();
607  J[8] = Jv2.z();
608 
609  return (InverseMatrix3x3(J,Ji));
610  }
611 
612  template<class INDEX>
613  double scaled_jacobian_metric(INDEX idx) const
614  {
616  ElemData ed(*this,idx);
617 
618  double temp;
619 
620  basis_.derivate(basis_.unit_center,ed,Jv);
621  Jv.resize(3);
624  Jv[1] = v.asPoint();
625  Jv[2] = w.asPoint();
626  double min_jacobian = ScaledDetMatrix3P(Jv);
627 
628  size_type num_vertices = static_cast<size_type>(basis_.number_of_vertices());
629  for (size_type j=0;j < num_vertices;j++)
630  {
631  basis_.derivate(basis_.unit_vertices[j],ed,Jv);
632  Jv.resize(3);
634  Jv[1] = v.asPoint();
635  Jv[2] = w.asPoint();
636  temp = ScaledDetMatrix3P(Jv);
637  if(temp < min_jacobian) min_jacobian = temp;
638  }
639 
640  return (min_jacobian);
641  }
642 
643 
644  template<class INDEX>
645  double jacobian_metric(INDEX idx) const
646  {
648  ElemData ed(*this,idx);
649 
650  double temp;
651 
652  basis_.derivate(basis_.unit_center,ed,Jv);
653  Jv.resize(3);
656  Jv[1] = v.asPoint();
657  Jv[2] = w.asPoint();
658  double min_jacobian = DetMatrix3P(Jv);
659 
660  size_type num_vertices = static_cast<size_type>(basis_.number_of_vertices());
661  for (size_type j=0;j < num_vertices;j++)
662  {
663  basis_.derivate(basis_.unit_vertices[j],ed,Jv);
664  Jv.resize(3);
666  Jv[1] = v.asPoint();
667  Jv[2] = w.asPoint();
668  temp = DetMatrix3P(Jv);
669  if(temp < min_jacobian) min_jacobian = temp;
670  }
671 
672  return (min_jacobian);
673  }
674 
675 
676  template <class INDEX>
677  bool locate_node(INDEX &idx, const Core::Geometry::Point &p) const
678  {
679  typename Node::size_type sz; size(sz);
680 
681  typename Node::iterator ni; begin(ni);
682  typename Node::iterator nie; end(nie);
683 
684  /// If there are no nodes we cannot find a closest point
685  if (sz == 0) return (false);
686 
687  /// Check first guess
688  if (idx >= 0 && idx < sz)
689  {
690  if ((p - points_[idx]).length2() < epsilon2_) return (true);
691  }
692 
693  double mindist = DBL_MAX;
694 
695  while(ni != nie)
696  {
697  double dist = (p-points_[*ni]).length2();
698  if ( dist < mindist )
699  {
700  mindist = dist;
701  idx = static_cast<INDEX>(*ni);
702 
703  /// Exit if we cannot find one that is closer
704  if (mindist < epsilon2_ ) return (true);
705  }
706  ++ni;
707  }
708 
709  return (true);
710  }
711 
712 
713  template <class INDEX>
714  bool locate_elem(INDEX &idx, const Core::Geometry::Point &p) const
715  {
716  if (basis_.polynomial_order() > 1) return elem_locate(idx, *this, p);
717 
718  typename Elem::size_type sz; size(sz);
719 
720  /// If there are no nodes we cannot find a closest point
721  if (sz == 0) return (false);
722 
723  double alpha;
724 
725  /// Check whether the estimate given in idx is the point we are looking for
726  if (idx >= 0 && idx < sz)
727  {
728  if (inside2_p(idx,p,alpha)) return (true);
729  }
730 
731  /// Loop over all nodes to find one that is located inside
732  typename Elem::iterator ei; begin(ei);
733  typename Elem::iterator eie; end(eie);
734 
735  while (ei != eie)
736  {
737  if (inside2_p(*ei,p,alpha))
738  {
739  idx = static_cast<INDEX>(*ei);
740  return (true);
741  }
742  ++ei;
743  }
744 
745  return (false);
746  }
747 
748  template <class ARRAY>
749  bool locate_elems(ARRAY &array, const Core::Geometry::BBox &b) const
750  {
751  array.clear();
752 
753  /// Loop over all nodes to find one
754  typename Elem::iterator ei; begin(ei);
755  typename Elem::iterator eie; end(eie);
756  typename Node::array_type nodes;
757 
758  while (ei != eie)
759  {
760  get_nodes(nodes,*ei);
761  Core::Geometry::BBox be(points_[nodes[0]],points_[nodes[1]]);
763  {
764  size_t p=0;
765  for (;p<array.size();p++) if (array[p] == typename ARRAY::value_type(*ei)) break;
766  if (p == array.size()) array.push_back(typename ARRAY::value_type(*ei));
767  }
768  ++ei;
769  }
770 
771  return (array.size() > 0);
772  }
773 
774 
775 
776  template <class INDEX, class ARRAY>
777  bool locate_elem(INDEX &idx, ARRAY& coords, const Core::Geometry::Point &p) const
778  {
779  if (basis_.polynomial_order() > 1) return elem_locate(idx, *this, p);
780 
781  typename Elem::size_type sz; size(sz);
782 
783  /// If there are no nodes we cannot find a closest point
784  if (sz == 0) return (false);
785 
786  double alpha;
787  coords.resize(1);
788 
789  /// Check whether the estimate given in idx is the point we are looking for
790  if (idx >= 0 && idx < sz)
791  {
792  if (inside2_p(idx,p,coords[0])) return (true);
793  }
794 
795  /// Loop over all nodes to find one that finds
796  typename Elem::iterator ei; begin(ei);
797  typename Elem::iterator eie; end(eie);
798 
799  while (ei != eie)
800  {
801  if (inside2_p(*ei,p,alpha))
802  {
803  coords[0] = alpha;
804  idx = static_cast<INDEX>(*ei);
805  return (true);
806  }
807  ++ei;
808  }
809 
810  return (false);
811  }
812 
813 
814  /// Find the closest element to a point
815  template <class INDEX>
816  bool find_closest_node(double& pdist, Core::Geometry::Point &result,
817  INDEX &idx, const Core::Geometry::Point &point) const
818  {
819  return(find_closest_node(pdist,result,idx,point,-1.0));
820  }
821 
822  /// Find the closest element to a point
823  template <class INDEX>
824  bool find_closest_node(double& pdist, Core::Geometry::Point &result,
825  INDEX &idx, const Core::Geometry::Point &point,
826  double maxdist) const
827  {
828  if (maxdist < 0.0) maxdist = DBL_MAX; else maxdist = maxdist*maxdist;
829  typename Node::size_type sz; size(sz);
830 
831  /// If there are no nodes we cannot find the closest one
832  if (sz == 0) return (false);
833 
835  double dist;
836 
837  if (idx >= 0 && idx < sz)
838  {
839  r = points_[idx];
840  dist = (point-r).length2();
841 
842  if ( dist < epsilon2_ )
843  {
844  result = point;
845  pdist = sqrt(dist);
846  return (true);
847  }
848  }
849 
850  typename Node::iterator ni; begin(ni);
851  typename Node::iterator nie; end(nie);
852 
853  double mindist = maxdist;
854 
855  while(ni != nie)
856  {
857  r = points_[*ni];
858  dist = (point-r).length2();
859 
860  if ( dist < mindist )
861  {
862  mindist = dist;
863  idx = static_cast<INDEX>(*ni);
864  result = r;
865  if (mindist < epsilon2_)
866  {
867  pdist = sqrt(mindist);
868  return (true);
869  }
870  }
871  ++ni;
872  }
873 
874  if (mindist >= maxdist) return (false);
875 
876  pdist = sqrt(mindist);
877  return (true);
878  }
879 
880  template <class ARRAY>
881  bool find_closest_nodes(ARRAY &nodes, const Core::Geometry::Point &point, double maxdist) const
882  {
883  nodes.clear();
884  double maxdist2 = maxdist*maxdist;
885 
886  typename Node::iterator ni; begin(ni);
887  typename Node::iterator nie; end(nie);
888 
889  while(ni != nie)
890  {
891  double dist = (point-points_[*ni]).length2();
892 
893  if ( dist < maxdist2 )
894  {
895  nodes.push_back(static_cast<typename ARRAY::value_type>(*ni));
896  }
897  ++ni;
898  }
899 
900  return (nodes.size() > 0);
901  }
902 
903 
904  template <class ARRAY1, class ARRAY2>
905  bool find_closest_nodes(ARRAY1 &distances,
906  ARRAY2 &nodes,
907  const Core::Geometry::Point &point, double maxdist) const
908  {
909  distances.clear();
910  nodes.clear();
911  double maxdist2 = maxdist*maxdist;
912 
913  typename Node::iterator ni; begin(ni);
914  typename Node::iterator nie; end(nie);
915 
916  while(ni != nie)
917  {
918  double dist = (point-points_[*ni]).length2();
919 
920  if ( dist < maxdist2 )
921  {
922  nodes.push_back(static_cast<typename ARRAY2::value_type>(*ni));
923  distances.push_back(static_cast<typename ARRAY1::value_type>(dist));
924  }
925  ++ni;
926  }
927 
928  return (nodes.size() > 0);
929  }
930 
931  /// Find the closest element to a point
932  template <class INDEX, class ARRAY>
933  bool find_closest_elem(double &pdist,
934  Core::Geometry::Point &result,
935  ARRAY &coords,
936  INDEX &idx,
937  const Core::Geometry::Point &p) const
938  {
939  return (find_closest_elem(pdist,result,coords,idx,p,-1.0));
940  }
941 
942  /// Find the closest element to a point
943  template <class INDEX, class ARRAY>
944  bool find_closest_elem(double &pdist,
945  Core::Geometry::Point &result,
946  ARRAY &coords,
947  INDEX &idx,
948  const Core::Geometry::Point &p,
949  double maxdist) const
950  {
951  if (maxdist < 0.0) maxdist = DBL_MAX; else maxdist = maxdist*maxdist;
952 
953  typename Elem::size_type sz; size(sz);
954 
955  /// If there are no nodes we cannot find the closest one
956  if (sz == 0) return (false);
957 
958  double dist;
959 
960  coords.resize(1);
961  /// Test the one in idx
962  if (idx >= 0 && idx < sz)
963  {
964  double alpha;
965  dist = distance2_p(idx,p,result,alpha);
966  if ( dist < epsilon2_ )
967  {
968  coords[0] = alpha;
969  pdist = sqrt(dist);
970  return (true);
971  }
972  }
973 
974  double mindist = maxdist;
976 
977  typename Elem::iterator ni; begin(ni);
978  typename Elem::iterator nie; end(nie);
979 
980  while(ni != nie)
981  {
982  double alpha;
983  dist = distance2_p(*ni,p,res,alpha);
984  if ( dist < mindist )
985  {
986  coords[0] = alpha;
987  mindist = dist;
988  idx = static_cast<INDEX>(*ni);
989  result = res;
990  if (mindist < epsilon2_)
991  {
992  pdist = sqrt(mindist);
993  return (true);
994  }
995  }
996  ++ni;
997  }
998 
999  if (mindist == maxdist) return (false);
1000 
1001  pdist = sqrt(mindist);
1002  return (true);
1003  }
1004 
1005  template <class INDEX>
1006  bool find_closest_elem(double& pdist,
1007  Core::Geometry::Point &result,
1008  INDEX &elem,
1009  const Core::Geometry::Point &p) const
1010  {
1011  StackVector<double,1> coords;
1012  return(find_closest_elem(pdist,result,coords,elem,p,-1.0));
1013  }
1014 
1015  /// Find the closest elements to a point
1016  template<class ARRAY>
1017  bool find_closest_elems(double& pdist, Core::Geometry::Point &result,
1018  ARRAY &elems, const Core::Geometry::Point &p) const
1019  {
1020  elems.clear();
1021 
1022  typename Elem::size_type sz; size(sz);
1023 
1024  /// If there are no nodes we cannot find the closest one
1025  if (sz == 0) return (false);
1026 
1027  typename Elem::iterator ni; begin(ni);
1028  typename Elem::iterator nie; end(nie);
1029 
1030  double dist;
1031  double mindist = DBL_MAX;
1033 
1034  while(ni != nie)
1035  {
1036  double dummy;
1037  dist = distance2_p(*ni,p,res,dummy);
1038 
1039  if (dist < mindist - epsilon2_)
1040  {
1041  elems.clear();
1042  result = res;
1043  elems.push_back(static_cast<typename ARRAY::value_type>(*ni));
1044  mindist = dist;
1045  }
1046  else if (dist < mindist)
1047  {
1048  elems.push_back(static_cast<typename ARRAY::value_type>(*ni));
1049  }
1050  ++ni;
1051  }
1052 
1053  pdist = sqrt(mindist);
1054  return (true);
1055  }
1056 
1057  double get_epsilon() const
1058  { return (epsilon_); }
1059 
1060  /// Export this class using the old Pio system
1061  virtual void io(Piostream&);
1062 
1063  ///////////////////////////////////////////////////
1064  // STATIC VARIABLES AND FUNCTIONS
1065 
1066  /// These IDs are created as soon as this class will be instantiated
1067  /// The first one is for Pio and the second for the virtual interface
1068  /// These are currently different as they serve different needs.
1070 
1071  /// Core functionality for getting the name of a templated mesh class
1072  static const std::string type_name(int n = -1);
1073  virtual std::string dynamic_type_name() const { return curvemesh_typeid.type; }
1074 
1075  /// Type description, used for finding names of the mesh class for
1076  /// dynamic compilation purposes. Some of this should be obsolete
1077  virtual const TypeDescription *get_type_description() const;
1078  static const TypeDescription* node_type_description();
1079  static const TypeDescription* edge_type_description();
1080  static const TypeDescription* face_type_description();
1081  static const TypeDescription* cell_type_description();
1083  { return edge_type_description(); }
1084 
1085  /// This function returns a maker for Pio.
1086  static Persistent *maker() { return new CurveMesh<Basis>(); }
1087  /// This function returns a handle for the virtual interface.
1088  static MeshHandle mesh_maker() { return boost::make_shared<CurveMesh<Basis>>(); }
1089 
1090 
1091  /// Functions local to CurveMesh, the latter are not thread safe
1092  /// THESE ARE NOT WELL INTEGRATED YET
1094  {
1095  CHECKARRAYBOUNDS(static_cast<index_type>(i1),
1096  static_cast<index_type>(0),
1097  static_cast<index_type>(points_.size()));
1098 
1099  std::vector<Core::Geometry::Point>::iterator niter;
1100  niter = points_.begin() + i1;
1101  points_.erase(niter);
1102  return static_cast<typename Node::index_type>(points_.size() - 1);
1103  }
1104 
1106  typename Node::index_type i2)
1107  {
1108  CHECKARRAYBOUNDS(static_cast<index_type>(i1),
1109  static_cast<index_type>(0),
1110  static_cast<index_type>(points_.size()));
1111 
1112  CHECKARRAYBOUNDS(static_cast<index_type>(i2),
1113  static_cast<index_type>(0),
1114  static_cast<index_type>(points_.size()+1));
1115 
1116  std::vector<Core::Geometry::Point>::iterator niter1;
1117  niter1 = points_.begin() + i1;
1118 
1119  std::vector<Core::Geometry::Point>::iterator niter2;
1120  niter2 = points_.begin() + i2;
1121 
1122  points_.erase(niter1, niter2);
1123  return static_cast<typename Node::index_type>(points_.size() - 1);
1124  }
1125 
1127  {
1128  CHECKARRAYBOUNDS(static_cast<index_type>(i1),
1129  static_cast<index_type>(0),
1130  static_cast<index_type>(edges_.size()>>1));
1131 
1132  typename std::vector<index_type>::iterator niter1;
1133  niter1 = edges_.begin() + 2*i1;
1134 
1135  typename std::vector<index_type>::iterator niter2;
1136  niter2 = edges_.begin() + 2*i1+2;
1137 
1138  edges_.erase(niter1, niter2);
1139  return static_cast<typename Edge::index_type>((edges_.size()>>1) - 1);
1140  }
1141 
1143  typename Edge::index_type i2)
1144  {
1145  CHECKARRAYBOUNDS(static_cast<index_type>(i1),
1146  static_cast<index_type>(0),
1147  static_cast<index_type>(edges_.size()>>1));
1148 
1149  CHECKARRAYBOUNDS(static_cast<index_type>(i2),
1150  static_cast<index_type>(0),
1151  static_cast<index_type>((edges_.size()>>1)+1));
1152 
1153  typename std::vector<index_type>::iterator niter1;
1154  niter1 = edges_.begin() + 2*i1;
1155 
1156  typename std::vector<index_type>::iterator niter2;
1157  niter2 = edges_.begin() + 2*i2;
1158 
1159  edges_.erase(niter1, niter2);
1160 
1161  return static_cast<typename Edge::index_type>((edges_.size()>>1) - 1);
1162  }
1163 
1164 protected:
1165  //////////////////////////////////////////////////////////////
1166  // These functions are templates and are used to define the
1167  // dynamic compilation interface and the virtual interface
1168  // as they both use different datatypes as indices and arrays
1169  // the following functions have been templated and are inlined
1170  // at the places where they are needed.
1171  //
1172  // Secondly these templates allow for the use of the stack vector
1173  // as well as the STL vector. When an algorithm supports non linear
1174  // functions an STL vector is a better choice, in the other cases
1175  // often a StackVector is enough (The latter improves performance).
1176 
1177  template<class ARRAY, class INDEX>
1178  inline void get_nodes_from_edge(ARRAY& array, INDEX idx) const
1179  {
1180  array.resize(2);
1181  array[0] = static_cast<typename ARRAY::value_type>(edges_[2*idx]);
1182  array[1] = static_cast<typename ARRAY::value_type>(edges_[2*idx+1]);
1183  }
1184 
1185  template<class ARRAY, class INDEX>
1186  inline void get_edges_from_node(ARRAY& array, INDEX idx) const
1187  {
1189  "CurveMesh: Must call synchronize NODE_NEIGHBORS_E on CurveMesh first");
1190 
1191  array.resize(node_neighbors_[idx].size());
1192  for (typename NodeNeighborMap::size_type i = 0; i < node_neighbors_[idx].size(); ++i)
1193  array[i] =
1194  static_cast<typename ARRAY::value_type>(node_neighbors_[idx][i]);
1195  }
1196 
1197  template<class ARRAY, class INDEX>
1198  inline void get_nodes_from_elem(ARRAY& array, INDEX idx) const
1199  {
1200  get_nodes_from_edge(array,idx);
1201  }
1202 
1203  template<class ARRAY, class INDEX>
1204  inline void get_edges_from_elem(ARRAY& array, INDEX idx) const
1205  {
1206  array.resize(1); array[0] = typename ARRAY::value_type(idx);
1207  }
1208 
1209 
1210  template <class ARRAY, class INDEX>
1211  inline void set_nodes_by_elem(ARRAY &array, INDEX idx)
1212  {
1213  for (index_type n = 0; n < 2; ++n)
1214  edges_[idx * 2 + n] = static_cast<index_type>(array[n]);
1215  }
1216 
1217  template <class INDEX1, class INDEX2>
1218  bool
1219  get_elem_neighbor(INDEX1 &neighbor, INDEX1 edge,INDEX2 node) const
1220  {
1222  "Must call synchronize NODE_NEIGHBORS_E on CurveMesh first");
1223 
1224  if (node_neighbors_[node].size() > 1)
1225  {
1226  if (node_neighbors_[node][0] == edge)
1227  neighbor = static_cast<INDEX1>(node_neighbors_[node][1]);
1228  else neighbor = static_cast<INDEX1>(node_neighbors_[node][0]);
1229  return (true);
1230  }
1231  return (false);
1232  }
1233 
1234 
1235  template <class ARRAY, class INDEX>
1236  void
1237  get_node_neighbors(ARRAY &array, INDEX idx) const
1238  {
1240  "Must call synchronize NODE_NEIGHBORS_E on CurveMesh first");
1241  array.resize(node_neighbors_[idx].size());
1242  for (typename NodeNeighborMap::size_type p=0;p<node_neighbors_[idx].size();p++)
1243  {
1244  if (edges_[2*(node_neighbors_[idx][p])] == idx)
1245  array[p] = static_cast<typename ARRAY::value_type>(edges_[2*(node_neighbors_[idx][p])+1]);
1246  else
1247  array[p] = static_cast<typename ARRAY::value_type>(edges_[2*(node_neighbors_[idx][p])]);
1248  }
1249  }
1250 
1251 
1252  template <class ARRAY, class INDEX1, class INDEX2>
1253  bool
1254  get_elem_neighbors(ARRAY &array, INDEX1 /*edge*/, INDEX2 idx) const
1255  {
1257  "Must call synchronize NODE_NEIGHBORS_E on CurveMesh first");
1258 
1259  typename NodeNeighborMap::size_type sz = node_neighbors_[idx].size();
1260  if (sz < 1) return (false);
1261 
1262  array.clear();
1263  array.reserve(sz-1);
1264  for (typename NodeNeighborMap::size_type i=0; i<sz;i++)
1265  {
1266  if (node_neighbors_[idx][i] != static_cast<typename ARRAY::value_type>(idx))
1267  array.push_back(typename ARRAY::value_type(node_neighbors_[idx][i]));
1268  }
1269  return (true);
1270  }
1271 
1272  template <class ARRAY, class INDEX>
1273  void
1274  get_elem_neighbors(ARRAY &array, INDEX idx) const
1275 
1276  {
1278  "Must call synchronize NODE_NEIGHBORS_E on CurveMesh first");
1279  typename Node::index_type n1 = edges_[2*idx];
1280  typename Node::index_type n2 = edges_[2*idx+1];
1281 
1282  typename NodeNeighborMap::size_type s1 = node_neighbors_[n1].size();
1283  typename NodeNeighborMap::size_type s2 = node_neighbors_[n2].size();
1284 
1285  array.clear();
1286  array.reserve(s1+s2-2);
1287  for (typename NodeNeighborMap::size_type i=0; i<s1;i++)
1288  {
1289  if (node_neighbors_[n1][i] != idx)
1290  array.push_back(typename ARRAY::value_type(node_neighbors_[n1][i]));
1291  }
1292  for (typename NodeNeighborMap::size_type i=0; i<s2;i++)
1293  {
1294  if (node_neighbors_[n2][i] != idx)
1295  array.push_back(typename ARRAY::value_type(node_neighbors_[n2][i]));
1296  }
1297  }
1298 
1299  bool inside2_p(index_type idx, const Core::Geometry::Point &p, double& coord) const;
1300  double distance2_p(index_type idx, const Core::Geometry::Point &p,
1301  Core::Geometry::Point& projection, double& coord) const;
1302 
1303  void compute_node_neighbors();
1304 
1305  //////////////////////////////////////////////////////////////
1306  // Actual data stored in the mesh
1307 
1308  /// Vector with the node locations
1309  std::vector<Core::Geometry::Point> points_;
1310  /// Vector with connectivity data
1311  std::vector<index_type> edges_;
1312  /// The basis function, contains additional information on elements
1313  Basis basis_;
1314 
1315  /// Record which parts of the mesh are synchronized
1317  /// Lock to synchronize between threads
1319 
1320  /// Vector indicating which edges are conected to which
1321  /// node. This is the reverse of the connectivity data
1322  /// stored in the edges_ array.
1323  typedef std::vector<std::vector<typename Edge::index_type> > NodeNeighborMap;
1326  double epsilon_;
1327  double epsilon2_;
1328  double epsilon3_;
1329 
1330  /// Pointer to virtual interface
1331  /// This one is created as soon as the mesh is generated
1332  /// Put this one in a handle as we have a virtual destructor
1333  boost::shared_ptr<VMesh> vmesh_;
1334 };
1335 
1336 
1337 template<class Basis>
1339  synchronized_(ALL_ELEMENTS_E),
1340  synchronize_lock_("CurveMesh Lock"),
1341  epsilon_(0.0),
1342  epsilon2_(0.0)
1343 {
1344  DEBUG_CONSTRUCTOR("CurveMesh")
1345  /// Initialize the virtual interface when the mesh is created
1346  vmesh_.reset(CreateVCurveMesh(this));
1347 }
1348 
1349 template<class Basis>
1351  Mesh(copy),
1352  points_(copy.points_),
1353  edges_(copy.edges_),
1354  basis_(copy.basis_),
1355  synchronized_(copy.synchronized_),
1356  synchronize_lock_("CurveMesh Lock")
1357 {
1358  DEBUG_CONSTRUCTOR("CurveMesh")
1359 
1360  /// We need to lock before we can copy these as these
1361  /// structures are generate dynamically when they are
1362  /// needed.
1363  copy.synchronize_lock_.lock();
1364  node_neighbors_ = copy.node_neighbors_;
1365  synchronized_ |= copy.synchronized_ & NODE_NEIGHBORS_E;
1366 
1367  // Make sure we got the synchronized version
1368  epsilon_ = copy.epsilon_;
1369  epsilon2_ = copy.epsilon2_;
1370 
1371  copy.synchronize_lock_.unlock();
1372 
1373  /// Create a new virtual interface for this copy
1374  /// all pointers have changed hence create a new
1375  /// virtual interface class
1376  vmesh_.reset(CreateVCurveMesh(this));
1377 }
1378 
1379 template<class Basis>
1381 {
1382  DEBUG_DESTRUCTOR("CurveMesh")
1383 }
1384 
1385 
1386 
1387 template <class Basis>
1389 {
1390  static TypeDescription *td = 0;
1391  if (!td)
1392  {
1393  const TypeDescription *sub = get_type_description((Basis*)0);
1395  (*subs)[0] = sub;
1396  td = new TypeDescription("CurveMesh", subs,
1397  std::string(__FILE__),
1398  "SCIRun",
1400  }
1401  return td;
1402 }
1403 
1404 
1405 template <class Basis>
1406 const TypeDescription*
1408 {
1410 }
1411 
1412 
1413 template <class Basis>
1414 const TypeDescription*
1416 {
1417  static TypeDescription *td = 0;
1418  if (!td)
1419  {
1420  const TypeDescription *me =
1422  td = new TypeDescription(me->get_name() + "::Node",
1423  std::string(__FILE__),
1424  "SCIRun",
1426  }
1427  return td;
1428 }
1429 
1430 
1431 template <class Basis>
1432 const TypeDescription*
1434 {
1435  static TypeDescription *td = 0;
1436  if (!td)
1437  {
1438  const TypeDescription *me =
1440  td = new TypeDescription(me->get_name() + "::Edge",
1441  std::string(__FILE__),
1442  "SCIRun",
1444  }
1445  return td;
1446 }
1447 
1448 
1449 template <class Basis>
1450 const TypeDescription*
1452 {
1453  static TypeDescription *td = 0;
1454  if (!td)
1455  {
1456  const TypeDescription *me =
1458  td = new TypeDescription(me->get_name() + "::Face",
1459  std::string(__FILE__),
1460  "SCIRun",
1462  }
1463  return td;
1464 }
1465 
1466 
1467 template <class Basis>
1468 const TypeDescription*
1470 {
1471  static TypeDescription *td = 0;
1472  if (!td)
1473  {
1474  const TypeDescription *me =
1476  td = new TypeDescription(me->get_name() + "::Cell",
1477  std::string(__FILE__),
1478  "SCIRun",
1480  }
1481  return td;
1482 }
1483 
1484 
1485 /// Add an entry into the database for Pio
1486 template <class Basis>
1489 
1490 //////////////////////////////////////////////////////////////////////
1491 // Functions in the mesh
1492 
1493 template <class Basis>
1496 {
1497  Core::Geometry::BBox result;
1498 
1499  // Compute bounding box
1500  typename Node::iterator ni, nie;
1501  begin(ni);
1502  end(nie);
1503  while (ni != nie)
1504  {
1505  result.extend(points_[*ni]);
1506  ++ni;
1507  }
1508 
1509  return result;
1510 }
1511 
1512 template <class Basis>
1513 void
1515 {
1516  t.load_identity();
1517  Core::Geometry::BBox bbox = get_bounding_box();
1518  t.pre_scale(bbox.diagonal());
1520 }
1521 
1522 template <class Basis>
1523 void
1525 {
1526  bbox_.reset();
1527 
1528  // Compute bounding box
1529  typename Node::iterator ni, nie;
1530  begin(ni);
1531  end(nie);
1532  while (ni != nie)
1533  {
1534  bbox_.extend(points_[*ni]);
1535  ++ni;
1536  }
1537 
1538  // Compute epsilons associated with the bounding box
1539  epsilon_ = bbox_.diagonal().length()*1e-8;
1540  epsilon2_ = epsilon_*epsilon_;
1541  epsilon3_ = epsilon_*epsilon_*epsilon_;
1542 
1543  synchronize_lock_.lock();
1544  synchronized_ |= Mesh::BOUNDING_BOX_E;
1545  synchronize_lock_.unlock();
1546 }
1547 
1548 template <class Basis>
1549 void
1551 {
1552  auto itr = points_.begin();
1553  auto eitr = points_.end();
1554  while (itr != eitr)
1555  {
1556  *itr = t.project(*itr);
1557  ++itr;
1558  }
1559 
1560  /// If we have nodes on the edges they should be transformed in
1561  /// the same way
1562  size_type num_enodes = static_cast<size_type>(basis_.size_node_values());
1563  for (size_type i=0; i<num_enodes; i++)
1564  {
1566  basis_.get_node_value(p,i);
1567  p =t.project(p);
1568  basis_.set_node_value(p,i);
1569  }
1570 
1571  /// Projecting derivates is more difficult
1572 }
1573 
1574 
1575 
1576 template <class Basis>
1577 double
1579 {
1580  ElemData ed(*this, idx);
1581  std::vector<Core::Geometry::Point> pledge;
1582  std::vector<std::vector<double> > coords;
1583  // Perhaps there is a better choice for the number of divisions.
1584  pwl_approx_edge(coords, idx, 0, 5);
1585 
1586  double total = 0.0L;
1587  std::vector<std::vector<double> >::iterator iter = coords.begin();
1588  std::vector<std::vector<double> >::iterator last = coords.begin() + 1;
1589  while (last != coords.end())
1590  {
1591  std::vector<double> &c0 = *iter++;
1592  std::vector<double> &c1 = *last++;
1593  Core::Geometry::Point p0 = basis_.interpolate(c0, ed);
1594  Core::Geometry::Point p1 = basis_.interpolate(c1, ed);
1595  total += (p1 - p0).length();
1596  }
1597  return total;
1598 }
1599 
1600 
1601 template <class Basis>
1602 void
1604  typename Edge::index_type idx) const
1605 {
1606  ElemData cmcd(*this, idx);
1607  std::vector<double> coord(1,0.5L);
1608  result = basis_.interpolate(coord, cmcd);
1609 }
1610 
1611 
1612 template <class Basis>
1613 int
1615  double *w)
1616 {
1617  typename Edge::index_type idx;
1618  if (locate(idx, p))
1619  {
1620  get_nodes(l,idx);
1621  StackVector<double,1> coords(1);
1622  if (get_coords(coords, p, idx))
1623  {
1624  basis_.get_weights(coords, w);
1625  return basis_.dofs();
1626  }
1627  }
1628  return 0;
1629 }
1630 
1631 
1632 template <class Basis>
1633 int
1635  double *w)
1636 {
1637  typename Edge::index_type idx;
1638  if (locate(idx, p))
1639  {
1640  l.resize(1);
1641  l[0] = idx;
1642  w[0] = 1.0;
1643  return 1;
1644  }
1645  return 0;
1646 }
1647 
1648 
1649 template <class Basis>
1650 void
1652  typename Elem::index_type ei,
1653  FieldRNG &rng) const
1654 {
1655  const Core::Geometry::Point &p0 = points_[edges_[2*ei]];
1656  const Core::Geometry::Point &p1 = points_[edges_[2*ei+1]];
1657 
1658  p = p0 + (p1 - p0) * rng();
1659 }
1660 
1661 
1662 template <class Basis>
1663 bool
1665 {
1666  synchronize_lock_.lock();
1667 
1668  /// Test whether we need to synchronize for any of the neighor function
1669  /// calls. If so compute the node_neighbor_ array, which we can use
1670  /// for the element neighbors as well.
1671 
1673  && !(synchronized_ & Mesh::NODE_NEIGHBORS_E))
1674  {
1675  compute_node_neighbors();
1676  }
1677 
1678  if (sync & (Mesh::EPSILON_E|Mesh::LOCATE_E) && !(synchronized_ & Mesh::EPSILON_E))
1679  {
1680  if( points_.size() )
1681  epsilon_ = get_bounding_box().diagonal().length()*1e-8;
1682 
1683  epsilon2_ = epsilon_ * epsilon_;
1684  synchronized_ |= Mesh::EPSILON_E;
1685  synchronized_ |= Mesh::LOCATE_E;
1686  }
1687 
1688  synchronize_lock_.unlock();
1689  return (true);
1690 }
1691 
1692 
1693 template <class Basis>
1694 bool
1696 {
1697  return (true);
1698 }
1699 
1700 template <class Basis>
1701 bool
1703 {
1704  // Undo marking the synchronization
1705  synchronize_lock_.lock();
1706  synchronized_ = Mesh::NODES_E | Mesh::EDGES_E | Mesh::ELEMS_E;
1707  // Free memory where possible
1708  node_neighbors_.clear();
1709  synchronize_lock_.unlock();
1710  return (true);
1711 }
1712 
1713 /// Compute the inverse route of connectivity: from node to edge
1714 template <class Basis>
1715 void
1717 {
1718  node_neighbors_.clear();
1719  node_neighbors_.resize(points_.size());
1720  index_type i;
1721  size_type num_elems = (edges_.size()>>1);
1722  for (i = 0; i < num_elems; i++)
1723  {
1724  node_neighbors_[edges_[2*i]].push_back(i);
1725  node_neighbors_[edges_[2*i+1]].push_back(i);
1726  }
1727  synchronized_ |= Mesh::NODE_NEIGHBORS_E;
1728 }
1729 
1730 #define CURVE_MESH_VERSION 3
1731 
1732 template <class Basis>
1733 void
1735 {
1736  int version = stream.begin_class(type_name(-1), CURVE_MESH_VERSION);
1737 
1738  Mesh::io(stream);
1739 
1740  // IO data members, in order
1741  Pio(stream, points_);
1742  if (version < 3)
1743  {
1744  // NOTE: This one is unsigned int for backwards compatibility from before we
1745  // used index_type
1746  std::vector<std::pair<unsigned int,unsigned int> > tmp;
1747  Pio(stream,tmp);
1748  edges_.resize(tmp.size()*2);
1749  for (std::vector<std::pair<unsigned int,unsigned int> >::size_type j=0;j<tmp.size();j++)
1750  {
1751  edges_[2*j] = tmp[j].first;
1752  edges_[2*j+1] = tmp[j].second;
1753  }
1754  }
1755  else
1756  {
1757  Pio_index(stream, edges_);
1758  }
1759  if (version >= 2)
1760  {
1761  basis_.io(stream);
1762  }
1763  stream.end_class();
1764 
1765  if (stream.reading())
1766  vmesh_.reset(CreateVCurveMesh(this));
1767 }
1768 
1769 
1770 template <class Basis>
1771 const std::string
1773 {
1774  ASSERT((n >= -1) && n <= 1);
1775  if (n == -1)
1776  {
1777  static const std::string name = TypeNameGenerator::make_template_id(type_name(0), type_name(1));
1778  return name;
1779  }
1780  else if (n == 0)
1781  {
1782  static const std::string nm("CurveMesh");
1783  return nm;
1784  }
1785  else
1786  {
1787  return find_type_name((Basis *)0);
1788  }
1789 }
1790 
1791 
1792 template <class Basis>
1793 void
1795 {
1796  itr = 0;
1797 }
1798 
1799 
1800 template <class Basis>
1801 void
1803 {
1804  itr = static_cast<index_type>(points_.size());
1805 }
1806 
1807 
1808 template <class Basis>
1809 void
1811 {
1812  itr = 0;
1813 }
1814 
1815 
1816 template <class Basis>
1817 void
1819 {
1820  itr = static_cast<index_type>(edges_.size()>>1);
1821 }
1822 
1823 
1824 template <class Basis>
1825 void
1827 {
1828  itr = 0;
1829 }
1830 
1831 
1832 template <class Basis>
1833 void
1835 {
1836  itr = 0;
1837 }
1838 
1839 
1840 template <class Basis>
1841 void
1843 {
1844  itr = 0;
1845 }
1846 
1847 
1848 template <class Basis>
1849 void
1851 {
1852  itr = 0;
1853 }
1854 
1855 
1856 template <class Basis>
1857 void
1859 {
1860  s = static_cast<size_type>(points_.size());
1861 }
1862 
1863 
1864 template <class Basis>
1865 void
1867 {
1868  s = static_cast<size_type>(edges_.size()>>1);
1869 }
1870 
1871 
1872 template <class Basis>
1873 void
1875 {
1876  s = 0;
1877 }
1878 
1879 
1880 template <class Basis>
1881 void
1883 {
1884  s = 0;
1885 }
1886 
1887 
1888 template <class Basis>
1889 bool
1891 {
1892  const index_type j = 2*i;
1893  const Core::Geometry::Point &p0 = points_[edges_[j]];
1894  const Core::Geometry::Point &p1 = points_[edges_[j+1]];
1895 
1896  const Core::Geometry::Vector v = p0-p1;
1897  alpha = Dot(p0-p,v)/v.length2();
1898 
1899  Core::Geometry::Point point;
1900  if (alpha < 0.0) { point = p0; alpha = 0.0; }
1901  else if (alpha > 1.0) { point = p1; alpha = 1.0; }
1902  else { point = (alpha*p1 + (1.0-alpha)*p0).asPoint(); }
1903 
1904  if ((point - p).length2() < epsilon2_) return (true);
1905 
1906  return (false);
1907 }
1908 
1909 
1910 template <class Basis>
1911 double
1913  Core::Geometry::Point& result, double& alpha) const
1914 {
1915  const index_type j = 2*i;
1916  const Core::Geometry::Point &p0 = points_[edges_[j]];
1917  const Core::Geometry::Point &p1 = points_[edges_[j+1]];
1918 
1919  const Core::Geometry::Vector v = p0-p1;
1920  alpha = Dot(p0-p,v)/v.length2();
1921 
1922  if (alpha < 0.0) { result = p0; alpha = 0.0;}
1923  else if (alpha > 1.0) { result = p1; alpha = 1.0; }
1924  else { result = (alpha*p1 + (1.0-alpha)*p0).asPoint(); }
1925 
1926  double dist = (result - p).length2();
1927  return (dist);
1928 }
1929 
1930 } // namespace SCIRun
1931 
1932 #endif
void get_nodes(typename Node::array_type &array, typename Node::index_type idx) const
Get the child elements of the given index.
Definition: CurveMesh.h:295
void get_delems(typename DElem::array_type &, typename Cell::index_type) const
Definition: CurveMesh.h:369
static const TypeDescription * node_type_description()
Definition: CurveMesh.h:1415
virtual const TypeDescription * get_type_description() const
Definition: CurveMesh.h:1407
Interface to statically allocated std::vector class.
Definition: VUnstructuredMesh.h:41
void get_delems(typename DElem::array_type &array, typename Node::index_type idx) const
Definition: CurveMesh.h:360
void get_nodes_from_edge(ARRAY &array, INDEX idx) const
Definition: CurveMesh.h:1178
void jacobian(const VECTOR &coords, INDEX idx, double *J) const
Definition: CurveMesh.h:569
static const TypeDescription * cell_type_description()
Definition: CurveMesh.h:1469
void get_normal(Core::Geometry::Vector &, VECTOR &, INDEX1, INDEX2) const
Definition: CurveMesh.h:489
bool reading() const
Definition: Persistent.h:164
Distinct type for node FieldIterator.
Definition: FieldIterator.h:89
#define CURVE_MESH_VERSION
Definition: CurveMesh.h:1730
void interpolate(Core::Geometry::Point &pt, const VECTOR &coords, INDEX idx) const
Definition: CurveMesh.h:539
void get_edges(typename Edge::array_type &, typename Face::index_type) const
Definition: CurveMesh.h:314
Definition: FieldRNG.h:37
bool locate(typename Face::index_type &, const Core::Geometry::Point &) const
Definition: CurveMesh.h:461
std::string get_name(const std::string &type_sep_start="<", const std::string &type_sep_end="> ") const
Definition: TypeDescription.cc:135
Distinct type for face Iterator.
Definition: FieldIterator.h:121
CellIterator< under_type > iterator
Definition: CurveMesh.h:137
void get_normal(Core::Geometry::Vector &, typename Node::index_type) const
Normals for visualizations.
Definition: CurveMesh.h:485
int intersect(const BBox &b) const
Definition: BBox.h:213
void get_elem_neighbors(ARRAY &array, INDEX idx) const
Definition: CurveMesh.h:1274
Definition: Mesh.h:85
Vector project(const Vector &p) const
Definition: Transform.cc:425
Edge Elem
Definition: CurveMesh.h:145
void get_delems(typename DElem::array_type &array, typename Edge::index_type idx) const
Definition: CurveMesh.h:363
void get_nodes_from_elem(ARRAY &array, INDEX idx) const
Definition: CurveMesh.h:1198
virtual bool has_normals() const
Has this mesh normals.
Definition: CurveMesh.h:251
Definition: Mesh.h:64
friend class VCurveMesh
Make sure the virtual interface has access.
Definition: CurveMesh.h:94
bool find_closest_elem(double &pdist, Core::Geometry::Point &result, ARRAY &coords, INDEX &idx, const Core::Geometry::Point &p) const
Find the closest element to a point.
Definition: CurveMesh.h:933
#define ASSERTMSG(condition, message)
Definition: Exception.h:113
SCIRun::mask_type mask_type
Definition: CurveMesh.h:104
void to_index(typename Node::index_type &index, index_type i) const
Definition: CurveMesh.h:284
void get_cells(typename Cell::array_type &, typename Edge::index_type) const
Definition: CurveMesh.h:337
virtual bool synchronize(mask_type sync)
Definition: CurveMesh.h:1664
double get_size(typename Cell::index_type) const
Definition: CurveMesh.h:415
std::vector< std::vector< typename Edge::index_type > > NodeNeighborMap
Definition: CurveMesh.h:1323
Index and Iterator types required for Mesh Concept.
Definition: CurveMesh.h:110
bool get_elem_neighbor(INDEX1 &neighbor, INDEX1 edge, INDEX2 node) const
Definition: CurveMesh.h:1219
Definition: Persistent.h:89
void pre_scale(const Vector &)
Definition: Transform.cc:193
void get_nodes(typename Node::array_type &array, typename Edge::index_type idx) const
Definition: CurveMesh.h:298
void get_delems(typename DElem::array_type &, typename Face::index_type) const
Definition: CurveMesh.h:366
FaceIterator< under_type > iterator
Definition: CurveMesh.h:128
static const TypeDescription * elem_type_description()
Definition: CurveMesh.h:1082
void get_random_point(Core::Geometry::Point &p, typename Elem::index_type i, FieldRNG &r) const
Definition: CurveMesh.h:1651
double inverse_jacobian(const VECTOR &coords, INDEX idx, double *Ji) const
Definition: CurveMesh.h:591
void to_index(typename Edge::index_type &index, index_type i) const
Definition: CurveMesh.h:286
static Persistent * maker()
This function returns a maker for Pio.
Definition: CurveMesh.h:1086
void get_faces(typename Face::array_type &, typename Face::index_type) const
Definition: CurveMesh.h:327
Definition: CurveMesh.h:126
double epsilon2_
Definition: CurveMesh.h:1327
void get_center(Core::Geometry::Point &result, typename Node::index_type idx) const
get the center point (in object space) of an element
Definition: CurveMesh.h:399
SCIRun::index_type index_type
Definition: CurveMesh.h:102
void set_point(const Core::Geometry::Point &point, typename Node::index_type index)
Definition: CurveMesh.h:480
void get_neighbors(std::vector< typename Elem::index_type > &array, typename Elem::index_type idx) const
Definition: CurveMesh.h:450
Definition: Persistent.h:187
BBox & extend(const Point &p)
Expand the bounding box to include point p.
Definition: BBox.h:98
void get_faces(typename Face::array_type &, typename Cell::index_type) const
Definition: CurveMesh.h:330
static const TypeDescription * edge_type_description()
Definition: CurveMesh.h:1433
Definition: CurveMesh.h:160
Definition: TypeDescription.h:50
T Dot(const ColumnMatrixGeneric< T > &a, const ColumnMatrixGeneric< T > &b)
Definition: ColumnMatrixFunctions.h:155
bool locate(typename Cell::index_type &, const Core::Geometry::Point &) const
Definition: CurveMesh.h:463
void end(typename Node::iterator &) const
CellIndex< under_type > size_type
Definition: CurveMesh.h:138
double get_length(typename Edge::index_type idx) const
More specific names for get_size.
Definition: CurveMesh.h:419
FieldHandle mesh()
Definition: BuildTDCSMatrixTests.cc:56
bool get_coords(VECTOR &coords, const Core::Geometry::Point &p, INDEX idx) const
Definition: CurveMesh.h:530
Definition: Point.h:49
Node::index_type add_point(const Core::Geometry::Point &point)
Definition: CurveMesh.h:499
Definition: TypeDescription.h:45
#define SCISHARE
Definition: share.h:39
std::vector< const TypeDescription * > td_vec
Definition: TypeDescription.h:56
std::vector< index_type > array_type
Definition: CurveMesh.h:139
void get_nodes(typename Node::array_type &, typename Face::index_type) const
Definition: CurveMesh.h:301
Definition: Mesh.h:45
void node_reserve(size_type s)
Definition: CurveMesh.h:521
Definition: BBox.h:46
bool locate(typename Node::index_type &i, const Core::Geometry::Point &p) const
Locate a point in a mesh, find which is the closest node.
Definition: CurveMesh.h:457
boost::shared_ptr< Mesh > MeshHandle
Definition: DatatypeFwd.h:67
Definition: Mutex.h:43
Distinct type for cell Iterator.
Definition: FieldIterator.h:134
const Core::Geometry::Point & node1() const
Definition: CurveMesh.h:184
double det_jacobian(const VECTOR &coords, INDEX idx) const
Definition: CurveMesh.h:558
bool find_closest_node(double &pdist, Core::Geometry::Point &result, INDEX &idx, const Core::Geometry::Point &point, double maxdist) const
Find the closest element to a point.
Definition: CurveMesh.h:824
unsigned int mask_type
Definition: Types.h:45
double get_area(typename Face::index_type) const
Definition: CurveMesh.h:421
index_type edge0_index() const
Definition: CurveMesh.h:189
bool locate_node(INDEX &idx, const Core::Geometry::Point &p) const
Definition: CurveMesh.h:677
void set_nodes_by_elem(ARRAY &array, INDEX idx)
Definition: CurveMesh.h:1211
Edge::index_type delete_edges(typename Edge::index_type i1, typename Edge::index_type i2)
Definition: CurveMesh.h:1142
bool inside2_p(index_type idx, const Core::Geometry::Point &p, double &coord) const
Definition: CurveMesh.h:1890
Point & asPoint() const
Definition: Vector.h:457
std::vector< index_type > array_type
Definition: CurveMesh.h:121
Core::Geometry::BBox bbox_
Definition: CurveMesh.h:1325
#define ASSERT(condition)
Definition: Assert.h:110
virtual bool is_editable() const
Check whether mesh can be altered by adding nodes or elements.
Definition: CurveMesh.h:248
void get_elems(typename Elem::array_type &array, typename Edge::index_type idx) const
Definition: CurveMesh.h:350
void get_edges(typename Edge::array_type &, typename Cell::index_type) const
Definition: CurveMesh.h:317
EdgeIndex< under_type > index_type
Definition: CurveMesh.h:118
virtual int begin_class(const std::string &name, int current_version)
Definition: Persistent.cc:143
NodeIndex< under_type > index_type
Definition: CurveMesh.h:111
int get_weights(const Core::Geometry::Point &, typename Face::array_type &, double *)
Definition: CurveMesh.h:472
void to_index(typename Face::index_type &, index_type) const
Definition: CurveMesh.h:288
Definition: CurveMesh.h:135
void get_node_neighbors(ARRAY &array, INDEX idx) const
Definition: CurveMesh.h:1237
Definition: Vector.h:63
StackVector< index_type, 2 > array_type
Definition: CurveMesh.h:114
void begin(typename Node::iterator &) const
begin/end iterators
CurveMesh()
Definition: CurveMesh.h:1338
MeshFacadeHandle getFacade() const
Definition: CurveMesh.h:212
Definition: CurveMesh.h:117
double DetMatrix3P(const VectorOfPoints &p)
Inline templated determinant of matrix.
Definition: Locate.h:120
const string find_type_name(float *)
Definition: TypeName.cc:63
Definition: Mesh.h:72
double distance2_p(index_type idx, const Core::Geometry::Point &p, Core::Geometry::Point &projection, double &coord) const
Definition: CurveMesh.h:1912
double length2() const
Definition: Vector.h:248
void get_faces(typename Face::array_type &, typename Node::index_type) const
Definition: CurveMesh.h:321
boost::shared_ptr< VMesh > vmesh_
Definition: CurveMesh.h:1333
bool find_closest_nodes(ARRAY1 &distances, ARRAY2 &nodes, const Core::Geometry::Point &point, double maxdist) const
Definition: CurveMesh.h:905
T DetMatrix3x3(const T *p)
Definition: Locate.h:95
bool get_elem_neighbors(ARRAY &array, INDEX1, INDEX2 idx) const
Definition: CurveMesh.h:1254
virtual int dimensionality() const
Topological dimension.
Definition: CurveMesh.h:227
Definition: Mesh.h:86
Edge::index_type add_edge(typename Node::index_type i1, typename Node::index_type i2)
Definition: CurveMesh.h:502
Definition: Mesh.h:87
void get_nodes(typename Node::array_type &, typename Cell::index_type) const
Definition: CurveMesh.h:304
std::vector< Core::Geometry::Point > points_
Vector with the node locations.
Definition: CurveMesh.h:1309
Definition: VMeshShared.h:40
virtual void get_canonical_transform(Core::Geometry::Transform &t) const
Definition: CurveMesh.h:1514
bool find_closest_elems(double &pdist, Core::Geometry::Point &result, ARRAY &elems, const Core::Geometry::Point &p) const
Find the closest elements to a point.
Definition: CurveMesh.h:1017
double get_volume(typename Cell::index_type) const
Definition: CurveMesh.h:423
const char * name[]
Definition: BoostGraphExampleTests.cc:87
std::pair< typename Node::index_type, typename Node::index_type > index_pair_type
Definition: CurveMesh.h:151
virtual CurveMesh * clone() const
Definition: CurveMesh.h:210
void Pio_index(Piostream &stream, index_type *data, size_type size)
Definition: Persistent.cc:606
virtual void compute_bounding_box()
Definition: CurveMesh.h:1524
long long size_type
Definition: Types.h:40
Definition: StackVector.h:50
void get_elems(typename Elem::array_type &, typename Face::index_type) const
Definition: CurveMesh.h:353
#define CHECKARRAYBOUNDS(value, lower, upper)
Definition: Assert.h:90
CellIndex< under_type > index_type
Definition: CurveMesh.h:136
double ScaledDetMatrix3P(const VectorOfPoints &p)
Inline templated determinant of matrix.
Definition: Locate.h:132
SCISHARE void find_orthogonal(Vector &, Vector &) const
Definition: Vector.cc:59
index_type node0_index() const
Definition: CurveMesh.h:171
void get_faces(typename Face::array_type &, typename Edge::index_type) const
Definition: CurveMesh.h:324
Definition: Mesh.h:71
void get_center(Core::Geometry::Point &, typename Face::index_type) const
Definition: CurveMesh.h:402
virtual void io(Piostream &)
Export this class using the old Pio system.
Definition: CurveMesh.h:1734
Vector diagonal() const
Definition: BBox.h:198
Definition: Mesh.h:81
bool locate_elem(INDEX &idx, ARRAY &coords, const Core::Geometry::Point &p) const
Definition: CurveMesh.h:777
Declarations for virtual interface.
Definition: CurveMesh.h:64
int get_weights(const Core::Geometry::Point &, typename Cell::array_type &, double *)
Definition: CurveMesh.h:474
Persistent i/o for STL containers.
virtual int basis_order()
Definition: CurveMesh.h:224
void pwl_approx_edge(VECTOR &coords, typename Elem::index_type, unsigned int which_edge, unsigned int div_per_unit) const
Definition: CurveMesh.h:378
std::string type
Definition: Persistent.h:72
VMesh * CreateVCurveMesh(MESH *)
Definition: CurveMesh.h:70
virtual Core::Geometry::BBox get_bounding_box() const
Get the bounding box of the field.
Definition: CurveMesh.h:1495
SCIRun::index_type under_type
Definition: CurveMesh.h:101
Point min() const
Definition: BBox.h:192
Distinct type for face index.
Definition: FieldIndex.h:90
void get_edges(typename Edge::array_type &array, typename Edge::index_type idx) const
Definition: CurveMesh.h:311
Definition: Mesh.h:62
Definition: Transform.h:53
const Core::Geometry::Point & node0() const
Definition: CurveMesh.h:180
double jacobian_metric(INDEX idx) const
Definition: CurveMesh.h:645
void get_cells(typename Cell::array_type &, typename Face::index_type) const
Definition: CurveMesh.h:340
void resize_elems(size_type s)
Definition: CurveMesh.h:524
void x(double)
Definition: Vector.h:175
void derivate(const VECTOR1 &coords, INDEX idx, VECTOR2 &J) const
Definition: CurveMesh.h:549
Node::index_type delete_nodes(typename Node::index_type i1, typename Node::index_type i2)
Definition: CurveMesh.h:1105
void get_cells(typename Cell::array_type &, typename Cell::index_type) const
Definition: CurveMesh.h:343
bool locate_elem(INDEX &idx, const Core::Geometry::Point &p) const
Definition: CurveMesh.h:714
double scaled_jacobian_metric(INDEX idx) const
Definition: CurveMesh.h:613
index_type node1_index() const
Definition: CurveMesh.h:175
virtual ~CurveMesh()
Definition: CurveMesh.h:1380
bool locate(typename Edge::index_type &i, const Core::Geometry::Point &p) const
Definition: CurveMesh.h:459
static const std::string make_template_id(const std::string &templateName, const std::string &templateParam)
Definition: TypeName.h:62
bool find_closest_elem(double &pdist, Core::Geometry::Point &result, INDEX &elem, const Core::Geometry::Point &p) const
Definition: CurveMesh.h:1006
v
Definition: readAllFields.py:42
NodeNeighborMap node_neighbors_
Definition: CurveMesh.h:1324
ElemData(const CurveMesh< Basis > &msh, const index_type idx)
Definition: CurveMesh.h:165
void pre_translate(const Vector &)
Definition: Transform.cc:278
bool locate_elems(ARRAY &array, const Core::Geometry::BBox &b) const
Definition: CurveMesh.h:749
double get_epsilon() const
Definition: CurveMesh.h:1057
bool find_closest_elem(double &pdist, Core::Geometry::Point &result, ARRAY &coords, INDEX &idx, const Core::Geometry::Point &p, double maxdist) const
Find the closest element to a point.
Definition: CurveMesh.h:944
Core::Thread::Mutex synchronize_lock_
Lock to synchronize between threads.
Definition: CurveMesh.h:1318
void get_elems(typename Elem::array_type &array, typename Node::index_type idx) const
Definition: CurveMesh.h:347
void elem_reserve(size_type s)
Definition: CurveMesh.h:522
virtual std::string dynamic_type_name() const
Definition: CurveMesh.h:1073
void y(double)
Definition: Vector.h:185
Basis basis_
The basis function, contains additional information on elements.
Definition: CurveMesh.h:1313
bool clear_synchronization()
Definition: CurveMesh.h:1702
void get_edges_from_node(ARRAY &array, INDEX idx) const
Definition: CurveMesh.h:1186
Distinct type for edge Iterator.
Definition: FieldIterator.h:105
Definition: Mesh.h:75
#define ASSERTFAIL(string)
Definition: Assert.h:52
NodeIterator< under_type > iterator
Definition: CurveMesh.h:112
static PersistentTypeID curvemesh_typeid
Add an entry into the database for Pio.
Definition: CurveMesh.h:1069
void Pio(Piostream &stream, Array1< T > &array)
Definition: Array1.h:65
Some convenient simple iterators for fields.
void compute_node_neighbors()
Compute the inverse route of connectivity: from node to edge.
Definition: CurveMesh.h:1716
double get_size(typename Face::index_type) const
Definition: CurveMesh.h:413
bool find_closest_nodes(ARRAY &nodes, const Core::Geometry::Point &point, double maxdist) const
Definition: CurveMesh.h:881
double get_size(typename Node::index_type) const
Get the size of an element (length, area, volume)
Definition: CurveMesh.h:410
Edge::index_type delete_edge(typename Edge::index_type i1)
Definition: CurveMesh.h:1126
std::vector< index_type > edges_
Vector with connectivity data.
Definition: CurveMesh.h:1311
Definition: Mesh.h:80
virtual VMesh * vmesh()
Obtain the virtual interface pointer.
Definition: CurveMesh.h:220
virtual void end_class()
Definition: Persistent.cc:178
Node::index_type add_node(const Core::Geometry::Point &p)
use these to build up a new contour mesh
Definition: CurveMesh.h:493
virtual void transform(const Core::Geometry::Transform &t)
Transform a field.
Definition: CurveMesh.h:1550
void size(typename Node::size_type &) const
Get the iteration sizes.
void get_point(Core::Geometry::Point &result, typename Node::index_type idx) const
Access the nodes of the mesh.
Definition: CurveMesh.h:478
long long index_type
Definition: Types.h:39
void resize_nodes(size_type s)
Definition: CurveMesh.h:523
const Core::Geometry::Point & point(typename Node::index_type i) const
Definition: CurveMesh.h:407
void resize(size_t size, const value_type &val=value_type())
Definition: StackVector.h:61
Basis & get_basis()
Get the basis class.
Definition: CurveMesh.h:260
static MeshHandle mesh_maker()
This function returns a handle for the virtual interface.
Definition: CurveMesh.h:1088
void to_index(typename Cell::index_type &, index_type) const
Definition: CurveMesh.h:290
bool find_closest_node(double &pdist, Core::Geometry::Point &result, INDEX &idx, const Core::Geometry::Point &point) const
Find the closest element to a point.
Definition: CurveMesh.h:816
int get_weights(const Core::Geometry::Point &p, typename Node::array_type &l, double *w)
Definition: CurveMesh.h:1614
bool get_neighbor(typename Elem::index_type &neighbor, typename Elem::index_type edge, typename DElem::index_type node) const
Definition: CurveMesh.h:429
Definition: Persistent.h:64
void get_elems(typename Face::array_type &, typename Cell::index_type) const
Definition: CurveMesh.h:356
FaceIndex< under_type > index_type
Definition: CurveMesh.h:127
virtual int topology_geometry() const
Definition: CurveMesh.h:232
CurveMesh< Basis >::index_type index_type
Definition: CurveMesh.h:163
void get_center(Core::Geometry::Point &, typename Cell::index_type) const
Definition: CurveMesh.h:404
static const TypeDescription * face_type_description()
Definition: CurveMesh.h:1451
Distinct type for edge index.
Definition: FieldIndex.h:81
int n
Definition: eab.py:9
Basis basis_type
Definition: CurveMesh.h:107
virtual bool unsynchronize(mask_type sync)
Definition: CurveMesh.h:1695
double epsilon3_
Definition: CurveMesh.h:1328
T InverseMatrix3x3(const T *p, T *q)
Definition: Locate.h:47
void pwl_approx_face(VECTOR &, typename Elem::index_type, typename Face::index_type, unsigned int) const
Definition: CurveMesh.h:390
static const std::string type_name(int n=-1)
Core functionality for getting the name of a templated mesh class.
Definition: CurveMesh.h:1772
bool get_neighbors(std::vector< typename Elem::index_type > &array, typename Elem::index_type edge, typename DElem::index_type idx) const
Definition: CurveMesh.h:443
#define DEBUG_CONSTRUCTOR(type)
Definition: Debug.h:64
void io(Piostream &stream)
Persistent I/O.
Definition: Mesh.cc:387
Elem::index_type add_elem(ARRAY a)
Definition: CurveMesh.h:511
std::vector< index_type > array_type
Definition: CurveMesh.h:130
Node DElem
Definition: CurveMesh.h:146
double epsilon_
Definition: CurveMesh.h:1326
FaceIndex< under_type > size_type
Definition: CurveMesh.h:129
void z(double)
Definition: Vector.h:195
SCIRun::size_type size_type
Definition: CurveMesh.h:103
boost::shared_ptr< CurveMesh< Basis > > handle_type
Definition: CurveMesh.h:106
void get_neighbors(std::vector< typename Node::index_type > &array, typename Node::index_type idx) const
These are more general neighbor functions.
Definition: CurveMesh.h:437
boost::shared_ptr< MeshFacade< VMesh > > MeshFacadeHandle
Definition: MeshTraits.h:61
EdgeIndex< under_type > size_type
Definition: CurveMesh.h:120
Definition: VMesh.h:53
void get_edges(typename Edge::array_type &array, typename Node::index_type idx) const
Definition: CurveMesh.h:308
mask_type synchronized_
Record which parts of the mesh are synchronized.
Definition: CurveMesh.h:1316
void get_edges_from_elem(ARRAY &array, INDEX idx) const
Definition: CurveMesh.h:1204
NodeIndex< under_type > size_type
Definition: CurveMesh.h:113
#define DEBUG_DESTRUCTOR(type)
Definition: Debug.h:65
const TypeDescription * get_type_description(Core::Basis::ConstantBasis< T > *)
Definition: Constant.h:209
void get_cells(typename Cell::array_type &, typename Node::index_type) const
Definition: CurveMesh.h:334
EdgeIterator< under_type > iterator
Definition: CurveMesh.h:119
Node::index_type delete_node(typename Node::index_type i1)
Definition: CurveMesh.h:1093
bool elem_locate(INDEX &elem, MESH &msh, const Core::Geometry::Point &p)
General case locate, search each elem.
Definition: Mesh.h:188