SPH
AntisymmetricTensor.h
Go to the documentation of this file.
1 #pragma once
2 
7 
8 
11 
13 
14 struct PseudoVectorTag {};
15 
17 
19 private:
20  Vector u;
21 
22 public:
23  AntisymmetricTensor() = default;
24 
27  explicit AntisymmetricTensor(const Vector& v)
28  : u(v) {}
29 
32  explicit AntisymmetricTensor(const PseudoVectorTag, const Vector& v)
33  : u(v[Z], -v[Y], v[X]) {}
34 
36  explicit AntisymmetricTensor(const Float v)
37  : u(v) {}
38 
41  return u;
42  }
43 
45  INLINE const Vector& components() const {
46  return u;
47  }
48 
50  Vector pseudovector() const {
51  return Vector(u[Z], -u[Y], u[X]);
52  }
53 
55  INLINE Vector operator[](const Size idx) const {
56  switch (idx) {
57  case 0:
58  return Vector(0._f, u[X], u[Y]);
59  case 1:
60  return Vector(-u[X], 0._f, u[Z]);
61  case 2:
62  return Vector(-u[Y], -u[Z], 0._f);
63  default:
64  STOP;
65  }
66  }
67 
69  INLINE Float operator()(const Size i, const Size j) const {
70  if (i == j) {
71  return 0._f;
72  } else if (i < j) {
73  return u[i + j - 1];
74  } else {
75  return -u[i + j - 1];
76  }
77  }
78 
79  INLINE static AntisymmetricTensor null() {
80  return AntisymmetricTensor(Vector(0._f));
81  }
82 
84  u += other.u;
85  return *this;
86  }
87 
89  u -= other.u;
90  return *this;
91  }
92 
94  return AntisymmetricTensor(-u);
95  }
96 
97  friend bool operator==(const AntisymmetricTensor& t1, const AntisymmetricTensor& t2) {
98  return t1.u == t2.u;
99  }
100 
102  return AntisymmetricTensor(t1.u + t2.u);
103  }
104 
106  return AntisymmetricTensor(t1.u - t2.u);
107  }
108 
110  return AntisymmetricTensor(t.u * v);
111  }
112 
114  return AntisymmetricTensor(t.u * v);
115  }
116 
118  return AntisymmetricTensor(t.u / v);
119  }
120 
121  friend std::ostream& operator<<(std::ostream& stream, const AntisymmetricTensor& t) {
122  stream << std::setprecision(6) << std::setw(20) << t.u[X] << std::setw(20) << t.u[Y] << std::setw(20)
123  << t.u[Z];
124  return stream;
125  }
126 };
127 
132  return AntisymmetricTensor(
133  0.5_f *
134  Vector(v1[X] * v2[Y] - v1[Y] * v2[X], v1[X] * v2[Z] - v1[Z] * v2[X], v1[Y] * v2[Z] - v1[Z] * v2[Y]));
135 }
136 
137 
139 INLINE bool almostEqual(const AntisymmetricTensor& t1, const AntisymmetricTensor& t2, const Float eps = EPS) {
140  return almostEqual(t1.components(), t2.components(), eps);
141 }
142 
145 template <>
147  return norm(t.components());
148 }
149 
151 template <>
153  return normSqr(t.components());
154 }
155 
157 template <>
159  return SymmetricTensor(Vector(0._f), abs(t.components()));
160 }
161 
163 template <>
165  return min(minElement(t.components()), minElement(-t.components()));
166 }
167 
169 template <>
171  return AntisymmetricTensor(min(t1.components(), t2.components()));
172 }
173 
175 template <>
177  return AntisymmetricTensor(max(t1.components(), t2.components()));
178 }
179 
181 template <>
183  SPH_ASSERT(range.contains(0._f));
184  const Float upper = max(-range.lower(), range.upper());
185  return AntisymmetricTensor(clamp(t.components(), Interval(-upper, upper)));
186 }
187 
188 template <>
190  return isReal(t.components());
191 }
192 
193 template <>
195  return AntisymmetricTensor(less(t1.components(), t2.components()));
196 }
197 
200  return 2._f * dot(t1.components(), t2.components());
201 }
202 
203 
INLINE bool isReal(const AntisymmetricTensor &t)
INLINE AntisymmetricTensor clamp(const AntisymmetricTensor &t, const Interval &range)
Clamping all components by range.
INLINE Float normSqr(const AntisymmetricTensor &t)
Arbitrary squared norm of the tensor.
INLINE AntisymmetricTensor max(const AntisymmetricTensor &t1, const AntisymmetricTensor &t2)
Component-wise maximum of two tensors.
INLINE auto abs(const AntisymmetricTensor &t)
Returns the tensor of absolute values. Resulting tensor is necessarily symmetric.
INLINE AntisymmetricTensor antisymmetricOuter(const Vector &v1, const Vector &v2)
INLINE Float norm(const AntisymmetricTensor &t)
INLINE bool almostEqual(const AntisymmetricTensor &t1, const AntisymmetricTensor &t2, const Float eps=EPS)
Checks if two tensors are equal to some given accuracy.
INLINE Float minElement(const AntisymmetricTensor &t)
Returns the minimal element of the tensor.
INLINE Float ddot(const AntisymmetricTensor &t1, const AntisymmetricTensor &t2)
Double-dot product t1 : t2 = sum_ij t1_ij t2_ij.
const PseudoVectorTag PSEUDOVECTOR
INLINE AntisymmetricTensor min(const AntisymmetricTensor &t1, const AntisymmetricTensor &t2)
Component-wise minimum of two tensors.
INLINE auto less(const AntisymmetricTensor &t1, const AntisymmetricTensor &t2)
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
#define STOP
Definition: Assert.h:106
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
uint32_t Size
Integral type used to index arrays (by default).
Definition: Globals.h:16
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
Definition: Globals.h:13
constexpr Float EPS
Definition: MathUtils.h:30
#define INLINE
Macros for conditional compilation based on selected compiler.
Definition: Object.h:31
#define NAMESPACE_SPH_END
Definition: Object.h:12
Basic algebra for symmetric 2nd order tensors.
BasicVector< Float > Vector
Definition: Vector.h:539
INLINE float dot(const BasicVector< float > &v1, const BasicVector< float > &v2)
Make sure the vector is trivially constructible and destructible, needed for fast initialization of a...
Definition: Vector.h:548
@ Y
Definition: Vector.h:23
@ X
Definition: Vector.h:22
@ Z
Definition: Vector.h:24
AntisymmetricTensor(const PseudoVectorTag, const Vector &v)
INLINE Float operator()(const Size i, const Size j) const
Returns element on given with given indices.
friend AntisymmetricTensor operator+(const AntisymmetricTensor &t1, const AntisymmetricTensor &t2)
Vector pseudovector() const
Returns the associated pseudovector.
INLINE Vector & components()
Returns the components above diagonal as vector.
AntisymmetricTensor()=default
friend AntisymmetricTensor operator*(const Float v, const AntisymmetricTensor &t)
friend bool operator==(const AntisymmetricTensor &t1, const AntisymmetricTensor &t2)
AntisymmetricTensor(const Vector &v)
friend std::ostream & operator<<(std::ostream &stream, const AntisymmetricTensor &t)
friend AntisymmetricTensor operator*(const AntisymmetricTensor &t, const Float v)
INLINE AntisymmetricTensor operator-() const
INLINE Vector operator[](const Size idx) const
Returns a row of the matrix.
INLINE const Vector & components() const
Returns the components above diagonal as vector.
INLINE AntisymmetricTensor operator+=(const AntisymmetricTensor &other)
friend AntisymmetricTensor operator/(const AntisymmetricTensor &t, const Float v)
friend AntisymmetricTensor operator-(const AntisymmetricTensor &t1, const AntisymmetricTensor &t2)
INLINE AntisymmetricTensor operator-=(const AntisymmetricTensor &other)
AntisymmetricTensor(const Float v)
Constructs an antisymmetric tensor by setting all components above the diagonal to the same value.
Object representing a 1D interval of real numbers.
Definition: Interval.h:17
INLINE Float lower() const
Returns lower bound of the interval.
Definition: Interval.h:74
INLINE Float upper() const
Returns upper bound of the interval.
Definition: Interval.h:79
INLINE bool contains(const Float &value) const
Checks whether value is inside the interval.
Definition: Interval.h:55
Symmetric tensor of 2nd order.