mantaflow  0.10
A framework for fluid simulation
vector4d.h
Go to the documentation of this file.
1 
2 /******************************************************************************
3  *
4  * MantaFlow fluid solver framework
5  * Copyright 2011 Tobias Pfaff, Nils Thuerey
6  *
7  * This program is free software, distributed under the terms of the
8  * GNU General Public License (GPL)
9  * http://www.gnu.org/licenses
10  *
11  * 4D vector class
12  *
13  ******************************************************************************/
14 
15 #ifndef _VECTOR4D_H
16 #define _VECTOR4D_H
17 
18 #include "vectorbase.h"
19 
20 
21 namespace Manta
22 {
23 
25 template<class S>
26 class Vector4D
27 {
28 public:
30  inline Vector4D() : x(0),y(0),z(0),t(0) {}
31 
33  inline Vector4D ( const Vector4D<S> &v ) : x(v.x), y(v.y), z(v.z),t(v.t) {}
34 
36  inline Vector4D ( const float * v) : x((S)v[0]), y((S)v[1]), z((S)v[2]), t((S)v[3]) {}
37 
39  inline Vector4D ( const double * v) : x((S)v[0]), y((S)v[1]), z((S)v[2]), t((S)v[3]) {}
40 
42  inline Vector4D ( S v) : x(v), y(v), z(v), t(v) {}
43 
45  inline Vector4D ( S vx, S vy, S vz, S vw) : x(vx), y(vy), z(vz), t(vw) {}
46 
47  // Operators
48 
50  inline const Vector4D<S>& operator= ( const Vector4D<S>& v ) {
51  x = v.x;
52  y = v.y;
53  z = v.z;
54  t = v.t;
55  return *this;
56  }
58  inline const Vector4D<S>& operator= ( S s ) {
59  x = y = z = t = s;
60  return *this;
61  }
63  inline const Vector4D<S>& operator+= ( const Vector4D<S>& v ) {
64  x += v.x;
65  y += v.y;
66  z += v.z;
67  t += v.t;
68  return *this;
69  }
71  inline const Vector4D<S>& operator+= ( S s ) {
72  x += s;
73  y += s;
74  z += s;
75  t += s;
76  return *this;
77  }
79  inline const Vector4D<S>& operator-= ( const Vector4D<S>& v ) {
80  x -= v.x;
81  y -= v.y;
82  z -= v.z;
83  t -= v.t;
84  return *this;
85  }
87  inline const Vector4D<S>& operator-= ( S s ) {
88  x -= s;
89  y -= s;
90  z -= s;
91  t -= s;
92  return *this;
93  }
95  inline const Vector4D<S>& operator*= ( const Vector4D<S>& v ) {
96  x *= v.x;
97  y *= v.y;
98  z *= v.z;
99  t *= v.t;
100  return *this;
101  }
103  inline const Vector4D<S>& operator*= ( S s ) {
104  x *= s;
105  y *= s;
106  z *= s;
107  t *= s;
108  return *this;
109  }
111  inline const Vector4D<S>& operator/= ( const Vector4D<S>& v ) {
112  x /= v.x;
113  y /= v.y;
114  z /= v.z;
115  t /= v.t;
116  return *this;
117  }
119  inline const Vector4D<S>& operator/= ( S s ) {
120  x /= s;
121  y /= s;
122  z /= s;
123  t /= s;
124  return *this;
125  }
127  inline Vector4D<S> operator- () const {
128  return Vector4D<S> (-x, -y, -z, -t);
129  }
130 
132  //inline S min() const { return ( x<y ) ? ( ( x<z ) ? x:z ) : ( ( y<z ) ? y:z ); }
134  //inline S max() const { return ( x>y ) ? ( ( x>z ) ? x:z ) : ( ( y>z ) ? y:z ); }
135 
137  inline bool empty() {
138  return x==0 && y==0 && z==0 && t==0;
139  }
140 
142  inline S& operator[] ( unsigned int i ) {
143  return value[i];
144  }
146  inline const S& operator[] ( unsigned int i ) const {
147  return value[i];
148  }
149 
151  std::string toString() const;
152 
154  bool isValid() const;
155 
157  union {
158  S value[4];
159  struct {
160  S x;
161  S y;
162  S z;
163  S t;
164  };
165  struct {
166  S X;
167  S Y;
168  S Z;
169  S T;
170  };
171  };
172 
173  // zero element
174  static const Vector4D<S> Zero, Invalid;
175 
176 protected:
177 
178 };
179 
180 //************************************************************************
181 // Additional operators
182 //************************************************************************
183 
185 template<class S>
186 inline Vector4D<S> operator+ ( const Vector4D<S> &v1, const Vector4D<S> &v2 ) {
187  return Vector4D<S> ( v1.x+v2.x, v1.y+v2.y, v1.z+v2.z, v1.t+v2.t );
188 }
190 template<class S, class S2>
191 inline Vector4D<S> operator+ ( const Vector4D<S>& v, S2 s ) {
192  return Vector4D<S> ( v.x+s, v.y+s, v.z+s, v.t+s );
193 }
195 template<class S, class S2>
196 inline Vector4D<S> operator+ ( S2 s, const Vector4D<S>& v ) {
197  return Vector4D<S> ( v.x+s, v.y+s, v.z+s, v.t+s );
198 }
199 
201 template<class S>
202 inline Vector4D<S> operator- ( const Vector4D<S> &v1, const Vector4D<S> &v2 ) {
203  return Vector4D<S> ( v1.x-v2.x, v1.y-v2.y, v1.z-v2.z, v1.t-v2.t );
204 }
206 template<class S, class S2>
207 inline Vector4D<S> operator- ( const Vector4D<S>& v, S2 s ) {
208  return Vector4D<S> ( v.x-s, v.y-s, v.z-s, v.t-s );
209 }
211 template<class S, class S2>
212 inline Vector4D<S> operator- ( S2 s, const Vector4D<S>& v ) {
213  return Vector4D<S> ( s-v.x, s-v.y, s-v.z, s-v.t );
214 }
215 
217 template<class S>
218 inline Vector4D<S> operator* ( const Vector4D<S> &v1, const Vector4D<S> &v2 ) {
219  return Vector4D<S> ( v1.x*v2.x, v1.y*v2.y, v1.z*v2.z, v1.t*v2.t );
220 }
222 template<class S, class S2>
223 inline Vector4D<S> operator* ( const Vector4D<S>& v, S2 s ) {
224  return Vector4D<S> ( v.x*s, v.y*s, v.z*s , v.t*s );
225 }
227 template<class S, class S2>
228 inline Vector4D<S> operator* ( S2 s, const Vector4D<S>& v ) {
229  return Vector4D<S> ( s*v.x, s*v.y, s*v.z, s*v.t );
230 }
231 
233 template<class S>
234 inline Vector4D<S> operator/ ( const Vector4D<S> &v1, const Vector4D<S> &v2 ) {
235  return Vector4D<S> ( v1.x/v2.x, v1.y/v2.y, v1.z/v2.z, v1.t/v2.t );
236 }
238 template<class S, class S2>
239 inline Vector4D<S> operator/ ( const Vector4D<S>& v, S2 s ) {
240  return Vector4D<S> ( v.x/s, v.y/s, v.z/s, v.t/s );
241 }
243 template<class S, class S2>
244 inline Vector4D<S> operator/ ( S2 s, const Vector4D<S>& v ) {
245  return Vector4D<S> ( s/v.x, s/v.y, s/v.z, s/v.t );
246 }
247 
249 template<class S>
250 inline bool operator== (const Vector4D<S>& s1, const Vector4D<S>& s2) {
251  return s1.x == s2.x && s1.y == s2.y && s1.z == s2.z && s1.t == s2.t;
252 }
253 
255 template<class S>
256 inline bool operator!= (const Vector4D<S>& s1, const Vector4D<S>& s2) {
257  return s1.x != s2.x || s1.y != s2.y || s1.z != s2.z || s1.t != s2.t;
258 }
259 
260 //************************************************************************
261 // External functions
262 //************************************************************************
263 
265 template<class S>
266 inline S dot ( const Vector4D<S> &t, const Vector4D<S> &v ) {
267  return t.x*v.x + t.y*v.y + t.z*v.z + t.t*v.t;
268 }
269 
271 /*template<class S>
272 inline Vector4D<S> cross ( const Vector4D<S> &t, const Vector4D<S> &v ) {
273  NYI Vector4D<S> cp (
274  ( ( t.y*v.z ) - ( t.z*v.y ) ),
275  ( ( t.z*v.x ) - ( t.x*v.z ) ),
276  ( ( t.x*v.y ) - ( t.y*v.x ) ) );
277  return cp;
278 }*/
279 
280 
282 template<class S>
283 inline S norm ( const Vector4D<S>& v ) {
284  S l = v.x*v.x + v.y*v.y + v.z*v.z + v.t*v.t;
285  return ( fabs ( l-1. ) < VECTOR_EPSILON*VECTOR_EPSILON ) ? 1. : sqrt ( l );
286 }
287 
289 template<class S>
290 inline S normSquare ( const Vector4D<S>& v ) {
291  return v.x*v.x + v.y*v.y + v.z*v.z + v.t*v.t;
292 }
293 
295 template<class S>
296 inline Vector4D<S> getNormalized ( const Vector4D<S>& v ) {
297  S l = v.x*v.x + v.y*v.y + v.z*v.z + v.t*v.t;
298  if ( fabs ( l-1. ) < VECTOR_EPSILON*VECTOR_EPSILON )
299  return v; /* normalized "enough"... */
300  else if ( l > VECTOR_EPSILON*VECTOR_EPSILON )
301  {
302  S fac = 1./sqrt ( l );
303  return Vector4D<S> ( v.x*fac, v.y*fac, v.z*fac , v.t*fac );
304  }
305  else
306  return Vector4D<S> ( ( S ) 0 );
307 }
308 
310 
311 template<class S>
312 inline S normalize ( Vector4D<S> &v ) {
313  S norm;
314  S l = v.x*v.x + v.y*v.y + v.z*v.z + v.t*v.t;
315  if ( fabs ( l-1. ) < VECTOR_EPSILON*VECTOR_EPSILON ) {
316  norm = 1.;
317  } else if ( l > VECTOR_EPSILON*VECTOR_EPSILON ) {
318  norm = sqrt ( l );
319  v *= 1./norm;
320  } else {
321  v = Vector4D<S>::Zero;
322  norm = 0.;
323  }
324  return ( S ) norm;
325 }
326 
327 
329 template<class S> std::string Vector4D<S>::toString() const {
330  char buf[256];
331  snprintf ( buf,256,"[%+4.6f,%+4.6f,%+4.6f,%+4.6f]", ( double ) ( *this ) [0], ( double ) ( *this ) [1], ( double ) ( *this ) [2] , ( double ) ( *this ) [3] );
332  // for debugging, optionally increase precision:
333  //snprintf ( buf,256,"[%+4.16f,%+4.16f,%+4.16f,%+4.16f]", ( double ) ( *this ) [0], ( double ) ( *this ) [1], ( double ) ( *this ) [2], ( double ) ( *this ) [3] );
334  return std::string ( buf );
335 }
336 
337 template<> std::string Vector4D<int>::toString() const;
338 
339 
341 template<class S>
342 std::ostream& operator<< ( std::ostream& os, const Vector4D<S>& i ) {
343  os << i.toString();
344  return os;
345 }
346 
348 template<class S>
349 std::istream& operator>> ( std::istream& is, Vector4D<S>& i ) {
350  char c;
351  char dummy[4];
352  is >> c >> i[0] >> dummy >> i[1] >> dummy >> i[2] >> dummy >> i[3] >> c;
353  return is;
354 }
355 
356 /**************************************************************************/
357 // Define default vector alias
358 /**************************************************************************/
359 
362 
365 
367 template<class T> inline Vec4 toVec4 ( T v ) {
368  return Vec4 ( v[0],v[1],v[2],v[3] );
369 }
370 template<class T> inline Vec4i toVec4i ( T v ) {
371  return Vec4i( v[0],v[1],v[2],v[3] );
372 }
373 
374 
375 /**************************************************************************/
376 // Specializations for common math functions
377 /**************************************************************************/
378 
379 template<> inline Vec4 clamp<Vec4>(const Vec4& a, const Vec4& b, const Vec4& c) {
380  return Vec4 ( clamp(a.x, b.x, c.x),
381  clamp(a.y, b.y, c.y),
382  clamp(a.z, b.z, c.z),
383  clamp(a.t, b.t, c.t) );
384 }
385 template<> inline Vec4 safeDivide<Vec4>(const Vec4 &a, const Vec4& b) {
386  return Vec4(safeDivide(a.x,b.x), safeDivide(a.y,b.y), safeDivide(a.z,b.z), safeDivide(a.t,b.t));
387 }
388 template<> inline Vec4 nmod<Vec4>(const Vec4& a, const Vec4& b) {
389  return Vec4(nmod(a.x,b.x),nmod(a.y,b.y),nmod(a.z,b.z) ,nmod(a.t,b.t) );
390 }
391 
392 
393 /**************************************************************************/
394 // 4d interpolation (note only 4d here, 2d/3d interpolations are in interpol.h)
395 /**************************************************************************/
396 
397 #define BUILD_INDEX_4D \
398  Real px=pos.x-0.5f, py=pos.y-0.5f, pz=pos.z-0.5f, pt=pos.t-0.5f; \
399  int xi = (int)px; \
400  int yi = (int)py; \
401  int zi = (int)pz; \
402  int ti = (int)pt; \
403  Real s1 = px-(Real)xi, s0 = 1.-s1; \
404  Real t1 = py-(Real)yi, t0 = 1.-t1; \
405  Real f1 = pz-(Real)zi, f0 = 1.-f1; \
406  Real g1 = pt-(Real)ti, g0 = 1.-g1; \
407  /* clamp to border */ \
408  if (px < 0.) { xi = 0; s0 = 1.0; s1 = 0.0; } \
409  if (py < 0.) { yi = 0; t0 = 1.0; t1 = 0.0; } \
410  if (pz < 0.) { zi = 0; f0 = 1.0; f1 = 0.0; } \
411  if (pt < 0.) { ti = 0; g0 = 1.0; g1 = 0.0; } \
412  if (xi >= size.x-1) { xi = size.x-2; s0 = 0.0; s1 = 1.0; } \
413  if (yi >= size.y-1) { yi = size.y-2; t0 = 0.0; t1 = 1.0; } \
414  if (zi >= size.z-1) { zi = size.z-2; f0 = 0.0; f1 = 1.0; } \
415  if (ti >= size.t-1) { ti = size.t-2; g0 = 0.0; g1 = 1.0; } \
416  const int sX = 1; \
417  const int sY = size.x;
418 
419 static inline void checkIndexInterpol4d(const Vec4i& size, int idx) {
420  if (idx<0 || idx > size.x * size.y * size.z * size.t) {
421  std::ostringstream s;
422  s << "Grid interpol4d dim " << size << " : index " << idx << " out of bound ";
423  errMsg(s.str());
424  }
425 }
426 
427 template <class T>
428 inline T interpol4d(const T* data, const Vec4i& size, const IndexInt sZ, const IndexInt sT, const Vec4& pos) {
429  BUILD_INDEX_4D
430  IndexInt idx = (IndexInt)xi + sY * (IndexInt)yi + sZ * (IndexInt)zi + sT * (IndexInt)ti;
431  DEBUG_ONLY(checkIndexInterpol4d(size,idx));
432  DEBUG_ONLY(checkIndexInterpol4d(size,idx+sX+sY+sZ+sT));
433 
434  return( ((data[idx] *t0 + data[idx+sY] *t1) * s0
435  + (data[idx+sX] *t0 + data[idx+sX+sY] *t1) * s1) * f0
436  +((data[idx+sZ] *t0 + data[idx+sY+sZ] *t1) * s0
437  + (data[idx+sX+sZ]*t0 + data[idx+sX+sY+sZ]*t1) * s1) * f1 ) * g0
438  +
439  ( ((data[idx+sT] *t0 + data[idx+sT+sY] *t1) * s0
440  + (data[idx+sT+sX] *t0 + data[idx+sT+sX+sY] *t1) * s1) * f0
441  +((data[idx+sT+sZ] *t0 + data[idx+sT+sY+sZ] *t1) * s0
442  + (data[idx+sT+sX+sZ]*t0 + data[idx+sT+sX+sY+sZ]*t1) * s1) * f1 ) * g1 ;
443 }
444 
445 }; // namespace
446 
447 
448 #endif
449 
450 
Definition: commonkernels.h:22
Vector4D(const double *v)
Copy-Constructor.
Definition: vector4d.h:39
const Vector4D< S > & operator-=(const Vector4D< S > &v)
Assign and sub operator.
Definition: vector4d.h:79
Vector4D()
Constructor.
Definition: vector4d.h:30
Vector4D< S > operator-() const
Negation operator.
Definition: vector4d.h:127
bool isValid() const
test if nans are present
Vector4D(S vx, S vy, S vz, S vw)
Construct a vector from three Ss.
Definition: vector4d.h:45
Vec4 toVec4(T v)
convert to Real Vector
Definition: vector4d.h:367
const Vector4D< S > & operator=(const Vector4D< S > &v)
Assignment operator.
Definition: vector4d.h:50
const Vector4D< S > & operator/=(const Vector4D< S > &v)
Assign and div operator.
Definition: vector4d.h:111
std::string toString() const
debug output vector to a string
Definition: vector4d.h:329
S & operator[](unsigned int i)
access operator
Definition: vector4d.h:142
Basic inlined vector class.
Definition: vector4d.h:26
const Vector4D< S > & operator*=(const Vector4D< S > &v)
Assign and mult operator.
Definition: vector4d.h:95
Vector4D(const float *v)
Copy-Constructor.
Definition: vector4d.h:36
bool empty()
Get smallest component.
Definition: vector4d.h:137
Vector4D(const Vector4D< S > &v)
Copy-Constructor.
Definition: vector4d.h:33
Vector4D(S v)
Construct a vector from one S.
Definition: vector4d.h:42
const Vector4D< S > & operator+=(const Vector4D< S > &v)
Assign and add operator.
Definition: vector4d.h:63