aimstil  5.0.5
Forces.h
Go to the documentation of this file.
1 #ifndef TIL_FORCES_H_
2 #define TIL_FORCES_H_
3 
4 // includes from STL
5 #include <cmath>
6 #include <vector>
7 
8 // includes from TIL
9 #include "til/til_declarations.h"
10 #include "til/is_traits.h"
11 #include "til/numeric_array.h"
12 #include "til/traits.h"
13 
14 // includes from TIL
15 //#include "declarations.h"
16 #include "globalTraits.h"
17 
18 namespace til
19 {
20  namespace functor
21  {
28 
29  template < typename TPoint3D, typename TVector3DRes >
31  {
32  enum { PerVertex = 1 };
33 
34  void
35  operator()(const TPoint3D & v, const TPoint3D &, TVector3DRes & res) const
36  {
37  res += v;
38  // add(res,v);
39  //NB: don't use this, as this cannot be overloaded (say between types)
40  //res += v;
41  }
42 
43  void
44  perVertex(const TPoint3D & v0, TVector3DRes & res, std::size_t n) const
45  {
46  res *= 1.0/n;
47  res -= v0;
48  //mul(res, 1.0/n);
49  //sub(res, v0);
50  //NB: don't use this, as this cannot be overloaded (say between types)
51  //res *= 1.0/n;
52  //res -= v0;
53  }
54 
55  void foo() {};
56  };
57 
58  struct SpringEnergy
59  {
60  template < typename TVector3D, typename TPrecision >
61  void operator()(const TVector3D & v, const TVector3D & v0, const TPrecision & l0, TPrecision & res) const
62  {
63  res += square(dist<TPrecision>(v, v0) - l0);
64  }
65  };
66 
68  template < typename TPoint3D, typename TVector3DRes >
70  {
71  // The precision of the computations (float, double...) is deduced fro,
72  // the precision of the returning force vector type.
74 
75  enum { PerVertex = 0 };
76 
79  /* template < typename TVector3D, typename TPrecision, typename TVector3DRes >
80  typename boost::enable_if_c<
81  til::is_3DVector<TVector3D>::value
82  >::type*/
83  void operator()(const TPoint3D & v, const TPoint3D & v0, const precision_t & l0, TVector3DRes & res) const
84  {
85  precision_t k = static_cast<precision_t>(
86  std::sqrt(norm2(v[0]-v0[0],
87  v[1]-v0[1],
88  v[2]-v0[2])));
89 
90  // v and v0 are too close to determine a force direction: return 0
91  if (k < 128 * std::numeric_limits<precision_t>::epsilon())
92  {
93  return;
94  }
95  k = (k-l0) / k;
96  //sub(v0, v, res);
97  //mul(res, k);
98 
99  res[0] += (v0[0]-v[0]) * k;
100  res[1] += (v0[1]-v[1]) * k;
101  res[2] += (v0[2]-v[2]) * k;
102  }
103  };
104  }
105 
106 
113  template < class TMesh, typename TForceVector >
115  {
116  public: // typedefs
117 
118  // The precision of the computations (float, double...) is deduced fro,
119  // the precision of the returning force vector type.
121 
122  public: // functions
123 
126  void initializeLengths(const TMesh & mesh)
127  {
128  getEdgeLengths(mesh, m_length0);
129  }
130 
133  void getForces
134  (
135  const TMesh & mesh,
136  //std::vector<std::vector<typename ChangePrecision<typename MeshTraits<TMesh>::Vertex, TPrecision>::type > > & forces
137  std::vector<TForceVector> & forces
138  )
139  {
140  if (size(m_length0) == 0)
141  {
142  std::runtime_error("SpringForce::length0 uninitialized");
143  }
144  // for all vertices
145  for_each_neighbors(mesh, m_length0, forces, functor::SpringForce<typename MeshTraits<TMesh>::Vertex, TForceVector>());
146  }
147 
148  public: // set & get
149 
150  const std::vector<std::vector<precision_t> > & getLengths() const { return m_length0; }
151 
152  private: // check
153 
154  // Check that TMesh has neighbor indices
155  typedef typename boost::enable_if_c<MeshTraits<TMesh>::has_neighbor_indices>::type CheckHasNeighborIndices;
156 
157  private: // data
158 
159  std::vector<std::vector<precision_t> > m_length0;
160  };
161 
162 
163  template < typename TForceVector, class TMesh >
164  void
165  laplacianForces(const TMesh & mesh, std::vector<TForceVector> & forces)
166  {
167  // The precision of the computations (float, double...) is deduced fro,
168  // the precision of the returning force vector type.
169  typedef typename til::precision<TForceVector>::type precision_t;
170 
171  // Allocate output with the same structure of neighbor indices of mesh
172  // if the main container has the wrong size.
173  if (size(forces) != size(getVertices(mesh)))
174  {
175  forces.resize(size(getVertices(mesh)));
176  }
177 
178  //functor::LaplacianForce<typename MeshTraits<TMesh>::Vertex, TForceVector> lf;
180  // for all vertices
184  typename std::vector<numeric_array<precision_t,3> >::iterator iC2 = forces.begin();
185  for (; iNic != getNeighborIndices(mesh).end(); ++iNic, ++iC2, ++iV)
186  {
187  // for all neighbors of current vertex
188  for (typename MeshTraits<TMesh>::NeighborIndex::const_iterator iNi = iNic->begin(); iNi != iNic->end(); ++iNi)
189  {
190  lf(getVertexNeighbor(mesh, *iNi), *iV, *iC2);
191  }
192  lf.perVertex(*iV, *iC2, iNic->size());
193  }
194  }
195 } // namespace til
196 
197 #endif //_FORCES_H_
const std::vector< std::vector< precision_t > > & getLengths() const
Definition: Forces.h:150
Numerical precision of the data for storage classes.
Definition: traits.h:48
Spring force functor.
Definition: Forces.h:69
TPrec norm2(const numeric_array< T, D > &a, prec< TPrec >)
Return the squared euclidean norm of a.
void perVertex(const TPoint3D &v0, TVector3DRes &res, std::size_t n) const
Definition: Forces.h:44
void sqrt(const TImage &in, TImage &out)
Definition: imageArith.h:326
til::value_type_of< TVector3DRes >::type precision_t
Definition: Forces.h:73
boost::enable_if_c< is_container< typename TContainer::value_type >::value >::type for_each_neighbors(const TMesh &mesh, TContainer &c1, TFunctor f)
Definition: meshUtils.h:585
MeshTraits< Mesh_N >::NeighborIndexCollection & getNeighborIndices(Mesh_N &mesh)
Definition: MeshTraits.h:380
Belongs to package Box Do not include directly, include til/Box.h instead.
Definition: Accumulator.h:10
Label class for Mesh neighborhood functors.
Definition: Forces.h:27
void laplacianForces(const TMesh &mesh, std::vector< TForceVector > &forces)
Definition: Forces.h:165
A class to compute spring forces on a mesh.
Definition: Forces.h:114
numeric_array< T, D > size(const Box< T, D > &box)
Return the size of a box.
Definition: boxTools.h:56
This file contains forward declarations of classes defined in the TIL library.
void operator()(const TVector3D &v, const TVector3D &v0, const TPrecision &l0, TPrecision &res) const
Definition: Forces.h:61
void operator()(const TPoint3D &v, const TPoint3D &v0, const precision_t &l0, TVector3DRes &res) const
Compute -(v-v0)/||v-v0|| * (||v-v0|| - l0)^2, store result in res.
Definition: Forces.h:83
til::value_type_of< TForceVector >::type precision_t
Definition: Forces.h:120
const MeshTraits< Mesh_N >::Vertex & getVertexNeighbor(const Mesh_N &mesh, const MeshTraits< Mesh_N >::NeighborIndex::value_type &iNi)
Returns the vertex neighbors of a mesh of type Mesh_N given by its index.
Definition: MeshTraits.h:513
Traits for meshes.
void square(const TImage &in, TImage &out)
Definition: imageArith.h:310
boost::enable_if_c< MeshTraits< TMesh >::has_neighbor_indices >::type getEdgeLengths(const TMesh &mesh, std::vector< std::vector< TPrecision > > &lengths)
Computes edge lengths of a mesh.
Definition: meshUtils.h:742
const MeshTraits< AimsSurface< D, T > >::VertexCollection & getVertices(const AimsSurface< D, T > &mesh)
Definition: aims_wrap.h:474
void operator()(const TPoint3D &v, const TPoint3D &, TVector3DRes &res) const
Definition: Forces.h:35
void initializeLengths(const TMesh &mesh)
Set the rest lengths of the springs as the length of the edges of the argument mesh.
Definition: Forces.h:126
T::value_type type
Definition: traits.h:200