SPHinXsys  alpha version
base_data_type.h
1 /* -------------------------------------------------------------------------*
2  * SPHinXsys *
3  * --------------------------------------------------------------------------*
4  * SPHinXsys (pronunciation: s'finksis) is an acronym from Smoothed Particle *
5  * Hydrodynamics for industrial compleX systems. It provides C++ APIs for *
6  * physical accurate simulation and aims to model coupled industrial dynamic *
7  * systems including fluid, solid, multi-body dynamics and beyond with SPH *
8  * (smoothed particle hydrodynamics), a meshless computational method using *
9  * particle discretization. *
10  * *
11  * SPHinXsys is partially funded by German Research Foundation *
12  * (Deutsche Forschungsgemeinschaft) DFG HU1527/6-1, HU1527/10-1 *
13  * and HU1527/12-1. *
14  * *
15  * Portions copyright (c) 2017-2020 Technical University of Munich and *
16  * the authors' affiliations. *
17  * *
18  * Licensed under the Apache License, Version 2.0 (the "License"); you may *
19  * not use this file except in compliance with the License. You may obtain a *
20  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
21  * *
22  * --------------------------------------------------------------------------*/
23 #ifndef BASE_DATA_TYPE_H
24 #define BASE_DATA_TYPE_H
25 
26 #include "Simbody.h"
27 #include "SimTKcommon.h"
28 #include "SimTKmath.h"
29 #include "scalar_functions.h"
30 
31 #include <cmath>
32 #include <iostream>
33 #include <cassert>
34 #include <climits>
35 #include <algorithm>
36 #include <vector>
37 #include <map>
38 
39 namespace SPH
40 {
41 
42  template <int N, class T>
43  class SVec
44  {
45  private:
46  T v[N];
47 
48  public:
49  SVec<N, T>()
50  {
51  for (int i = 0; i < N; ++i)
52  v[i] = (T)0;
53  }
54 
55  explicit SVec<N, T>(T value_for_all)
56  {
57  for (int i = 0; i < N; ++i)
58  v[i] = value_for_all;
59  }
60 
61  template <class S>
62  explicit SVec<N, T>(const S *source)
63  {
64  for (int i = 0; i < N; ++i)
65  v[i] = (T)source[i];
66  }
67 
68  template <class S>
69  explicit SVec<N, T>(const SVec<N, S> &source)
70  {
71  for (int i = 0; i < N; ++i)
72  v[i] = (T)source[i];
73  }
74 
75  template <class S>
76  explicit SVec<N, T>(const SimTK::Vec<N, S> &source)
77  {
78  for (int i = 0; i < N; ++i)
79  v[i] = (T)source[i];
80  }
81 
82  SVec<N, T>(T v0, T v1)
83  {
84  v[0] = v0;
85  v[1] = v1;
86  }
87 
88  SVec<N, T>(T v0, T v1, T v2)
89  {
90  v[0] = v0;
91  v[1] = v1;
92  v[2] = v2;
93  }
94 
95  T &operator[](int index)
96  {
97  assert(index >= 0 && index < N);
98  return v[index];
99  }
100 
101  const T &operator[](int index) const
102  {
103  assert(index >= 0 && index < N);
104  return v[index];
105  }
106 
107  bool nonzero(void) const
108  {
109  for (int i = 0; i < N; ++i)
110  if (v[i])
111  return true;
112  return false;
113  }
114 
115  bool operator==(const SVec<N, T> &b) const
116  {
117  bool res = true;
118  for (int i = 0; i < N; ++i)
119  res = res && (v[i] == b[i]);
120  return res;
121  }
122 
123  bool operator!=(const SVec<N, T> &b) const
124  {
125  bool res = false;
126  for (int i = 0; i < N; ++i)
127  res = res || (v[i] != b[i]);
128  return res;
129  }
130 
131  // Arithmetic operators
132  SVec<N, T> operator=(const SVec<N, T> &b)
133  {
134  for (int i = 0; i < N; ++i)
135  v[i] = b.v[i];
136  return *this;
137  }
138 
139  SVec<N, T> operator+(void) const
140  {
141  return SVec(*this);
142  }
143 
144  SVec<N, T> operator+=(T a)
145  {
146  for (int i = 0; i < N; ++i)
147  v[i] += a;
148  return *this;
149  }
150 
151  SVec<N, T> operator+(T a) const
152  {
153  SVec<N, T> w(*this);
154  w += a;
155  return w;
156  }
157 
158  SVec<N, T> operator+=(const SVec<N, T> &w)
159  {
160  for (int i = 0; i < N; ++i)
161  v[i] += w[i];
162  return *this;
163  }
164 
165  SVec<N, T> operator+(const SVec<N, T> &w) const
166  {
167  SVec<N, T> sum(*this);
168  sum += w;
169  return sum;
170  }
171 
172  SVec<N, T> operator-=(T a)
173  {
174  for (int i = 0; i < N; ++i)
175  v[i] -= a;
176  return *this;
177  }
178 
179  SVec<N, T> operator-(T a) const
180  {
181  SVec<N, T> w(*this);
182  w -= a;
183  return w;
184  }
185 
186  SVec<N, T> operator-=(const SVec<N, T> &w)
187  {
188  for (int i = 0; i < N; ++i)
189  v[i] -= w[i];
190  return *this;
191  }
192 
193  // unary minus
194  SVec<N, T> operator-(void) const
195  {
196  SVec<N, T> negative;
197  for (int i = 0; i < N; ++i)
198  negative.v[i] = -v[i];
199  return negative;
200  }
201 
202  // minus
203  SVec<N, T> operator-(const SVec<N, T> &w) const
204  {
205  SVec<N, T> diff(*this);
206  diff -= w;
207  return diff;
208  }
209 
210  // scalar product
211  SVec<N, T> operator*=(T a)
212  {
213  for (int i = 0; i < N; ++i)
214  v[i] *= a;
215  return *this;
216  }
217 
218  SVec<N, T> operator*(T a) const
219  {
220  SVec<N, T> w(*this);
221  w *= a;
222  return w;
223  }
224 
225  SVec<N, T> operator*=(const SVec<N, T> &w)
226  {
227  for (int i = 0; i < N; ++i)
228  v[i] *= w.v[i];
229  return *this;
230  }
231 
232  SVec<N, T> operator*(const SVec<N, T> &w) const
233  {
234  SVec<N, T> componentwise_product;
235  for (int i = 0; i < N; ++i)
236  componentwise_product[i] = v[i] * w.v[i];
237  return componentwise_product;
238  }
239 
240  SVec<N, T> operator/=(T a)
241  {
242  for (int i = 0; i < N; ++i)
243  v[i] /= a;
244  return *this;
245  }
246 
247  SVec<N, T> operator/(T a) const
248  {
249  SVec<N, T> w(*this);
250  w /= a;
251  return w;
252  }
253 
254  SVec<N, T> operator/=(const SVec<N, T> &w)
255  {
256  for (int i = 0; i < N; ++i)
257  v[i] /= w.v[i];
258  return *this;
259  }
260 
261  SVec<N, T> operator/(const SVec<N, T> &w) const
262  {
263  SVec<N, T> componentwise_divide;
264  for (int i = 0; i < N; ++i)
265  componentwise_divide[i] = v[i] / w.v[i];
266  return componentwise_divide;
267  }
268  };
269 
270  template <int N, class T>
271  std::ostream &operator<<(std::ostream &out, const SVec<N, T> &v)
272  {
273  out << '[' << v[0];
274  for (int i = 1; i < N; ++i)
275  out << ' ' << v[i];
276  out << ']';
277  return out;
278  }
279 
280  template <int N, class T>
281  std::istream &operator>>(std::istream &in, SVec<N, T> &v)
282  {
283  in >> v[0];
284  for (int i = 1; i < N; ++i)
285  in >> v[i];
286  return in;
287  }
288 
289  // vector with integers
290  using Vec2i = SVec<2, int>;
291  using Vec3i = SVec<3, int>;
292 
293  // vector with unsigned int
294  using Vec2u = SVec<2, size_t>;
295  using Vec3u = SVec<3, size_t>;
296 
297  // float point number
298  using Real = SimTK::Real;
299 
300  // useful float point constants s
301  const Real Pi = Real(M_PI);
302  using SimTK::Eps;
303  using SimTK::Infinity;
304  using SimTK::TinyReal;
305  constexpr size_t MaxSize_t = std::numeric_limits<size_t>::max();
306 
307  // vector with float point number
308  using Vec2d = SimTK::Vec2;
309  using Vec3d = SimTK::Vec3;
310 
311  // small matrix with float point number
312  using Mat2d = SimTK::Mat22;
313  using Mat3d = SimTK::Mat33;
314  // small symmetric matrix with float point number
315  using SymMat2d = SimTK::SymMat22;
316  using SymMat3d = SimTK::SymMat33;
317 
318  // type trait for data type index
319  template <typename T>
321  {
322  static constexpr int value = std::numeric_limits<int>::max();
323  };
324  template <>
325  struct DataTypeIndex<Real>
326  {
327  static constexpr int value = 0;
328  };
329  template <>
330  struct DataTypeIndex<Vec2d>
331  {
332  static constexpr int value = 1;
333  };
334  template <>
335  struct DataTypeIndex<Vec3d>
336  {
337  static constexpr int value = 1;
338  };
339  template <>
340  struct DataTypeIndex<Mat2d>
341  {
342  static constexpr int value = 2;
343  };
344  template <>
345  struct DataTypeIndex<Mat3d>
346  {
347  static constexpr int value = 2;
348  };
349  template <>
350  struct DataTypeIndex<int>
351  {
352  static constexpr int value = 3;
353  };
354 
355  // verbal boolean for positive and negative axis directions
356  const int xAxis = 0;
357  const int yAxis = 1;
358  const int zAxis = 2;
359  const bool positiveDirection = true;
360  const bool negativeDirection = false;
361 
363  template <typename VecType>
365  {
366  public:
367  VecType first, second;
368  int dimension_;
369 
370  BaseBoundingBox() : first(VecType(0)), second(VecType(0)), dimension_(VecType(0).size()){};
371  BaseBoundingBox(const VecType &lower_bound, const VecType &upper_bound)
372  : first(lower_bound), second(upper_bound),
373  dimension_(lower_bound.size()){};
374 
375  bool checkContain(const VecType &point)
376  {
377  bool is_contain = true;
378  for (int i = 0; i < dimension_; ++i)
379  {
380  if (point[i] < first[i] || point[i] > second[i])
381  {
382  is_contain = false;
383  break;
384  }
385  }
386  return is_contain;
387  };
388  };
389 
390  template <class T>
391  bool operator==(const BaseBoundingBox<T> &bb1, const BaseBoundingBox<T> &bb2)
392  {
393  return bb1.first == bb2.first && bb1.second == bb2.second ? true : false;
394  };
395 
396  template <class BoundingBoxType>
397  BoundingBoxType getIntersectionOfBoundingBoxes(const BoundingBoxType &bb1, const BoundingBoxType &bb2)
398  {
399  // check that the inputs are correct
400  int dimension = bb1.dimension_;
401  // Get the Bounding Box of the intersection of the two meshes
402  BoundingBoxType bb(bb1);
403  // #1 check that there is overlap, if not, exception
404  for (int i = 0; i < dimension; ++i)
405  if (bb2.first[i] > bb1.second[i] || bb2.second[i] < bb1.first[i])
406  std::runtime_error("getIntersectionOfBoundingBoxes: no overlap!");
407  // #2 otherwise modify the first one to get the intersection
408  for (int i = 0; i < dimension; ++i)
409  {
410  // if the lower limit is inside change the lower limit
411  if (bb1.first[i] < bb2.first[i] && bb2.first[i] < bb1.second[i])
412  bb.first[i] = bb2.first[i];
413  // if the upper limit is inside, change the upper limit
414  if (bb1.second[i] > bb2.second[i] && bb2.second[i] > bb1.first[i])
415  bb.second[i] = bb2.second[i];
416  }
417  return bb;
418  }
419 
426  {
427  Real angle_, cosine_angle_, sine_angle_;
428 
429  public:
430  explicit Rotation2d(SimTK::Real angle)
431  : angle_(angle), cosine_angle_(std::cos(angle)), sine_angle_(std::sin(angle)){};
432  virtual ~Rotation2d(){};
433 
435  Vec2d xformFrameVecToBase(const Vec2d &origin)
436  {
437  return Vec2d(origin[0] * cosine_angle_ - origin[1] * sine_angle_,
438  origin[1] * cosine_angle_ + origin[0] * sine_angle_);
439  };
441  Vec2d xformBaseVecToFrame(const Vec2d &target)
442  {
443  return Vec2d(target[0] * cosine_angle_ + target[1] * sine_angle_,
444  target[1] * cosine_angle_ - target[0] * sine_angle_);
445  };
446  };
447 
454  {
455  private:
456  Rotation2d rotation_;
457  Vec2d translation_;
458 
459  public:
460  Transform2d() : rotation_(Rotation2d(0)), translation_(Vec2d(0)){};
461  explicit Transform2d(const Vec2d &translation) : rotation_(Rotation2d(0)), translation_(translation){};
462  explicit Transform2d(const Rotation2d &rotation, const Vec2d &translation = Vec2d(0))
463  : rotation_(rotation), translation_(translation){};
464 
466  Vec2d xformFrameVecToBase(const Vec2d &origin)
467  {
468  return rotation_.xformFrameVecToBase(origin);
469  };
470 
472  Vec2d shiftFrameStationToBase(const Vec2d &origin)
473  {
474  return translation_ + xformFrameVecToBase(origin);
475  };
476 
478  Vec2d xformBaseVecToFrame(const Vec2d &target)
479  {
480  return rotation_.xformBaseVecToFrame(target);
481  };
482 
484  Vec2d shiftBaseStationToFrame(const Vec2d &target)
485  {
486  return xformBaseVecToFrame(target - translation_);
487  };
488  };
489 
494  using Transform3d = SimTK::Transform;
495 }
496 
497 #endif // BASE_DATA_TYPE_H
Definition: base_data_type.h:43
Coordinate transform in 3D from SimTK.
Rotation Coordinate transform (around the origin) in 2D with an angle.
Definition: base_data_type.h:425
Vec2d xformBaseVecToFrame(const Vec2d &target)
Definition: base_data_type.h:478
Vec2d xformFrameVecToBase(const Vec2d &origin)
Definition: base_data_type.h:435
Vec2d xformFrameVecToBase(const Vec2d &origin)
Definition: base_data_type.h:466
Vec2d shiftBaseStationToFrame(const Vec2d &target)
Definition: base_data_type.h:484
Coordinate transform in 2D Note that the rotation is around the frame (or local) origin.
Definition: base_data_type.h:453
Vec2d xformBaseVecToFrame(const Vec2d &target)
Definition: base_data_type.h:441
Definition: base_data_type.h:364
Definition: base_data_type.h:320
Vec2d shiftFrameStationToBase(const Vec2d &origin)
Definition: base_data_type.h:472
Definition: solid_body_supplementary.cpp:9