OpenLB 1.8.1
Loading...
Searching...
No Matches
vector.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2015 Asher Zarth, Mathias J. Krause, Albert Mink
4 * 2020 Adrian Kummerlaender
5 * E-mail contact: info@openlb.net
6 * The most recent release of OpenLB can be downloaded at
7 * <http://www.openlb.net/>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public
20 * License along with this program; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23*/
24
25
30#ifndef VECTOR_H
31#define VECTOR_H
32
33#include <cstring>
34#include <type_traits>
35#include <array>
36
37#include "scalarVector.h"
38#include "utilities/omath.h"
40
41#include "olbDebug.h"
42
43namespace olb {
44
45
47template <typename T, unsigned D>
48class Vector : public ScalarVector<T,D,Vector<T,D>> {
49private:
50 std::array<T,D> _data;
51
53
54protected:
55
56public:
57 using value_t = T;
58
59 constexpr Vector() any_platform:
60 _data{}
61 { }
62
63 constexpr Vector(const Vector& rhs) any_platform:
64 _data(rhs._data)
65 { }
66
67 constexpr Vector(Vector&& rhs) any_platform:
68 _data(rhs._data)
69 { }
70
71 template <typename W, typename IMPL>
73 {
74 for (unsigned iDim=0; iDim < D; ++iDim) {
75 _data[iDim] = rhs[iDim];
76 }
77 }
78
79 template <typename... I,
80 typename std::enable_if_t< (sizeof...(I) > 1
82 && sizeof...(I) == D), int> = 0>
83 constexpr Vector(I... indexes) any_platform:
84 _data{T(indexes)...}
85 { }
86
88 template <typename U>
89 constexpr Vector(const U* v) any_platform
90 {
91 for (unsigned iDim=0; iDim < D; ++iDim) {
92 _data[iDim] = static_cast<T>(v[iDim]);
93 }
94 }
95
97 constexpr explicit Vector(const Vector<T*,D>& ref, std::size_t idx) any_platform
98 {
99 for (unsigned iDim=0; iDim < D; ++iDim) {
100 _data[iDim] = ref[iDim][idx];
101 }
102 }
103
104 // Should be declared explicit
105 constexpr Vector(const std::vector<T>& v)
106 {
107 OLB_PRECONDITION(v.size() == D);
108 for (unsigned iDim=0; iDim < D; ++iDim) {
109 _data[iDim] = v[iDim];
110 }
111 }
112
113 #ifndef __CUDA_ARCH__
114 constexpr Vector(std::initializer_list<T> v)
115 {
116 OLB_PRECONDITION(v.size() == D);
117 std::copy(v.begin(), v.end(), _data.begin());
118 }
119 #endif
120
121 constexpr Vector(T scalar) any_platform
122 {
123 for (unsigned iDim=0; iDim < D; ++iDim) {
124 _data[iDim] = scalar;
125 }
126 }
127
129 template <typename F, typename = decltype(std::declval<F&>()(std::size_t{0}))>
130 constexpr Vector(F&& f) any_platform
131 {
132 for (unsigned iDim=0; iDim < D; ++iDim) {
133 _data[iDim] = f(iDim);
134 }
135 }
136
137 constexpr const T* getComponentPointer(unsigned iDim) const any_platform
138 {
139 return &_data[iDim];
140 }
141
142 constexpr T* getComponentPointer(unsigned iDim) any_platform
143 {
144 return &_data[iDim];
145 }
146
147 template <typename U, typename IMPL_>
149 {
150 for (unsigned iDim=0; iDim < D; ++iDim) {
151 this->operator[](iDim) = rhs[iDim];
152 }
153 return *this;
154 }
155
156 constexpr Vector& operator = (const Vector& rhs) any_platform
157 {
158 for (unsigned iDim=0; iDim < D; ++iDim) {
159 _data[iDim] = rhs[iDim];
160 }
161 return *this;
162 }
163
164 constexpr Vector& operator = (const Vector&& rhs) any_platform
165 {
166 for (unsigned iDim=0; iDim < D; ++iDim) {
167 _data[iDim] = rhs[iDim];
168 }
169 return *this;
170 }
171
172 constexpr const T* data() const any_platform
173 {
174 return _data.data();
175 }
176
177 constexpr T* data() any_platform
178 {
179 return _data.data();
180 }
181
182 constexpr auto begin()
183 {
184 return _data.begin();
185 }
186
187 constexpr auto end()
188 {
189 return _data.end();
190 }
191
192 constexpr int getDim() const any_platform
193 {
194 return D;
195 }
196
198 constexpr Vector<T,D+1> withPrefix(T prefix) const any_platform
199 {
200 Vector<T,D+1> tmp;
201 tmp[0] = prefix;
202 for (unsigned iDim=0; iDim < D; ++iDim) {
203 tmp[iDim+1] = _data[iDim];
204 }
205 return tmp;
206 }
207
209 constexpr Vector<T,D-1> withoutPrefix() const requires (D > 1) any_platform
210 {
211 Vector<T,D-1> tmp{};
212 for (unsigned iDim=1; iDim < D; ++iDim) {
213 tmp[iDim-1] = _data[iDim];
214 }
215 return tmp;
216 }
217
219 template <unsigned E>
220 constexpr Vector<T,D+E> append(const Vector<T,E>& rhs) const any_platform
221 {
222 Vector<T,D+E> tmp;
223 for (unsigned iDim=0; iDim < D; ++iDim) {
224 tmp[iDim] = _data[iDim];
225 }
226 for (unsigned iDim=0; iDim < E; ++iDim) {
227 tmp[iDim+D] = rhs[iDim];
228 }
229 return tmp;
230 }
231
232 constexpr std::size_t getNblock() const { return 1; }
233 constexpr std::size_t getSerializableSize() const
234 {
235 return D * sizeof(T);
236 };
237 bool* getBlock(std::size_t iBlock, std::size_t& sizeBlock, bool loadingMode)
238 {
239 std::size_t currentBlock = 0;
240 bool* dataPtr = nullptr;
241 //registerVar(iBlock, sizeBlock, currentBlock, dataPtr, *_data.data(), D);
242 if (iBlock == currentBlock) {
243 sizeBlock = sizeof(T) * D;
244 dataPtr = (bool*) _data.data();
245 }
246 currentBlock++;
247 return dataPtr;
248 }
249
250};
251
252template <typename T, typename... Ts>
253Vector(T&& t, Ts&&... ts) -> Vector<std::remove_cvref_t<T>,1+sizeof...(Ts)>;
254
255template <typename T, typename IMPL, typename IMPL_>
256constexpr T crossProduct2D(
258{
259 return (a[0]*b[1] - a[1]*b[0]);
260}
261
262template <typename T, typename IMPL, typename IMPL_>
265{
266 return Vector<T,3>(
267 a[1]*b[2] - a[2]*b[1],
268 a[2]*b[0] - a[0]*b[2],
269 a[0]*b[1] - a[1]*b[0]
270 );
271}
272
273template <typename T, unsigned D, typename IMPL, typename IMPL_>
275 static_assert((D==2 || D==3), "ERROR: Unknown dimension!");
276 if constexpr (D==2){
277 return crossProduct2D(a,b);
278 } else {
279 return crossProduct3D(a,b);
280 }
281}
282
283template <typename T, unsigned D, typename IMPL>
284constexpr Vector<T,D> normalize(const ScalarVector<T,D,IMPL>& a, T scale = T{1})
285{
286 T invScale (scale / norm(a));
287 return Vector<T,D>([invScale,&a](unsigned iDim) -> T {
288 return a[iDim] * invScale;
289 });
290}
291
292template <typename T, unsigned D, typename IMPL>
294{
295 using namespace util;
296 return Vector<T,D>([&a](unsigned iDim) -> T {
297 return abs(a[iDim]);
298 });
299}
300
301template <typename T, unsigned D, typename IMPL>
303{
304 return Vector<T,D>([&a](unsigned iDim) -> T {
305 return util::round(a[iDim]);
306 });
307}
308
309template <typename T, unsigned D, typename U, typename IMPL>
312{
313 return Vector<T,D>(b) += a;
314}
315
316template <typename T, unsigned D, typename U, typename IMPL>
319{
320 return Vector<T,D>(a) += b;
321}
322
323template <typename T, unsigned D, typename IMPL, typename IMPL_>
326{
327 return Vector<T,D>(a) += b;
328}
329
330template <typename T, typename W, unsigned D, typename IMPL, typename IMPL_>
331constexpr Vector<decltype(T{}+W{}),D> operator+ (
332 const ScalarVector<T,D,IMPL>& a, const ScalarVector<W,D,IMPL_>& b) any_platform
333{
334 Vector<decltype(T{}+W{}),D> result;
335 for (unsigned iDim=0; iDim < D; ++iDim) {
336 result[iDim] = a[iDim] + b[iDim];
337 }
338 return result;
339}
340
341template <typename T, unsigned D, typename U, typename IMPL>
344{
345 return Vector<T,D>(a) - b;
346}
347
348template <typename T, unsigned D, typename U, typename IMPL>
351{
352 return Vector<T,D>(a) -= b;
353}
354
355template <typename T, unsigned D, typename IMPL, typename IMPL_>
358{
359 return Vector<T,D>(a) -= b;
360}
361
362template <typename T, typename W, unsigned D, typename IMPL, typename IMPL_>
363constexpr Vector<decltype(T{}-W{}),D> operator- (
364 const ScalarVector<T,D,IMPL>& a, const ScalarVector<W,D,IMPL_>& b) any_platform
365{
366 Vector<decltype(T{}-W{}),D> result;
367 for (unsigned iDim=0; iDim < D; ++iDim) {
368 result[iDim] = a[iDim] - b[iDim];
369 }
370 return result;
371}
372
373template <typename T, unsigned D, typename U, typename IMPL>
374constexpr meta::enable_if_arithmetic_t<U, Vector<decltype(T{}*U{}),D>>
375operator* (U a, const ScalarVector<T,D,IMPL>& b) any_platform
376{
377 Vector<decltype(T{}*U{}),D> result(b);
378 return result *= a;
379}
380
381template <typename T, unsigned D, typename U, typename IMPL>
382constexpr meta::enable_if_arithmetic_t<U, Vector<decltype(T{}*U{}),D>>
383operator* (const ScalarVector<T,D,IMPL>& a, U b) any_platform
384{
385 Vector<decltype(T{}*U{}),D> result(a);
386 return result *= b;
387}
388
390template <typename T, typename U, unsigned D, typename IMPL, typename IMPL_>
391constexpr auto operator* (
393{
394 decltype(T{}*U{}) scalarProduct{};
395 for (unsigned iDim=0; iDim < D; ++iDim) {
396 scalarProduct += a[iDim] * b[iDim];
397 }
398 return scalarProduct;
399}
400
401template <typename T, unsigned D, typename U, typename IMPL>
404{
405 return Vector<T,D>(a) /= b;
406}
407
408template <typename T, unsigned D, typename U, typename IMPL>
411{
412 Vector<T,D> r;
413 for (unsigned iDim=0; iDim < D; ++iDim) {
414 r[iDim] = a[iDim] % b;
415 }
416 return r;
417}
418
419template<typename T, unsigned D, typename U, typename IMPL>
422{
423 return Vector<U,D>(lhs) < rhs;
424}
425
426template<typename T, unsigned D, typename U, typename IMPL>
429{
430 return lhs > Vector<U,D>(rhs);
431}
432
433template<typename T, unsigned D, typename U, typename IMPL>
436{
437 return Vector<U,D>(lhs) <= rhs;
438}
439
440template<typename T, unsigned D, typename U, typename IMPL>
443{
444 return lhs >= Vector<U,D>(rhs);
445}
446
447template <typename T, unsigned D, typename IMPL, typename IMPL_>
450{
451 return Vector<T,D>([&v,&w](unsigned iDim) -> T {
452 return util::min(v[iDim], w[iDim]);
453 });
454}
455
456template <typename T, unsigned D, typename IMPL, typename IMPL_>
459{
460 return Vector<T,D>([&v,&w](unsigned iDim) -> T {
461 return util::max(v[iDim], w[iDim]);
462 });
463}
464
465template <typename T, unsigned D, typename IMPL>
466constexpr T max(const ScalarVector<T,D,IMPL>& v)
467{
468 T max = v[0];
469 for (unsigned iD=1; iD < D; ++iD) {
470 if (v[iD] > max) {
471 max = v[iD];
472 }
473 }
474 return max;
475}
476
477
479template<typename T, typename DESCRIPTOR, typename FIELD>
481 typename FIELD::template value_type<T>,
482 DESCRIPTOR::template size<FIELD>()
483>;
484
485} // end namespace olb
486
487#endif
Plain old scalar vector.
constexpr int getDim() const any_platform
Definition vector.h:192
constexpr Vector(const std::vector< T > &v)
Definition vector.h:105
constexpr Vector & operator=(const GenericVector< U, D, IMPL_ > &rhs) any_platform
Definition vector.h:148
constexpr Vector(const ScalarVector< W, D, IMPL > &rhs) any_platform
Definition vector.h:72
constexpr const T * data() const any_platform
Definition vector.h:172
constexpr Vector(const Vector< T *, D > &ref, std::size_t idx) any_platform
Construct from Structure-of-Arrays addresses given by ref and index idx.
Definition vector.h:97
constexpr const T * getComponentPointer(unsigned iDim) const any_platform
Definition vector.h:137
constexpr std::size_t getSerializableSize() const
Definition vector.h:233
constexpr auto begin()
Definition vector.h:182
constexpr Vector(F &&f) any_platform
Construct with entries given by a lambda expression.
Definition vector.h:130
constexpr Vector(Vector &&rhs) any_platform
Definition vector.h:67
constexpr std::size_t getNblock() const
Definition vector.h:232
constexpr Vector(I... indexes) any_platform
Definition vector.h:83
constexpr Vector() any_platform
Definition vector.h:59
constexpr auto end()
Definition vector.h:187
bool * getBlock(std::size_t iBlock, std::size_t &sizeBlock, bool loadingMode)
Definition vector.h:237
constexpr Vector(std::initializer_list< T > v)
Definition vector.h:114
constexpr Vector< T, D+E > append(const Vector< T, E > &rhs) const any_platform
Return new (this..., rhs...) vector.
Definition vector.h:220
constexpr Vector(const Vector &rhs) any_platform
Definition vector.h:63
constexpr Vector(T scalar) any_platform
Definition vector.h:121
constexpr Vector(const U *v) any_platform
Construct from Array-of-Structures element at v.
Definition vector.h:89
constexpr Vector< T, D+1 > withPrefix(T prefix) const any_platform
Return new (prefix,this...) vector.
Definition vector.h:198
constexpr T * data() any_platform
Definition vector.h:177
constexpr T * getComponentPointer(unsigned iDim) any_platform
Definition vector.h:142
constexpr Vector< T, D-1 > withoutPrefix() const any_platform
Return vector without first element.
Definition vector.h:209
typename std::integral_constant< bool, std::is_base_of_v< AD, T >||std::is_base_of_v< SimdBase, T >||std::is_base_of_v< ExprBase, T >||std::is_arithmetic_v< T >||std::is_pointer_v< T >||std::is_enum_v< T > > is_arithmetic
Checks whether T can be used as a scalar arithmetic type.
Definition meta.h:109
std::enable_if_t< is_arithmetic< T >::type::value, U > enable_if_arithmetic_t
Definition meta.h:121
Expr min(Expr a, Expr b)
Definition expr.cpp:249
Expr max(Expr a, Expr b)
Definition expr.cpp:245
ADf< T, DIM > round(const ADf< T, DIM > &a)
Definition aDiff.h:928
Top level namespace for all of OpenLB.
constexpr Vector< T, D > minv(const ScalarVector< T, D, IMPL > &v, const ScalarVector< T, D, IMPL_ > &w)
Definition vector.h:448
bool operator>=(const Expr &rhs, const Expr &lhs)
Definition expr.cpp:215
Expr operator/(Expr lhs, Expr rhs)
Definition expr.cpp:186
bool operator>(const Expr &rhs, const Expr &lhs)
Definition expr.cpp:207
bool operator<=(const Expr &rhs, const Expr &lhs)
Definition expr.cpp:219
Vector(T &&t, Ts &&... ts) -> Vector< std::remove_cvref_t< T >, 1+sizeof...(Ts)>
constexpr T max(const ScalarVector< T, D, IMPL > &v)
Definition vector.h:466
Expr operator*(Expr lhs, Expr rhs)
Definition expr.cpp:181
Expr operator%(Expr lhs, int rhs)
Definition expr.cpp:195
constexpr Vector< T, D > maxv(const ScalarVector< T, D, IMPL > &v, const ScalarVector< T, D, IMPL_ > &w)
Definition vector.h:457
Expr operator+(Expr lhs, Expr rhs)
Definition expr.cpp:171
constexpr T crossProduct2D(const ScalarVector< T, 2, IMPL > &a, const ScalarVector< T, 2, IMPL_ > &b)
Definition vector.h:256
constexpr Vector< T, D > round(const ScalarVector< T, D, IMPL > &a) any_platform
Definition vector.h:302
std::enable_if_t< std::is_arithmetic< T >::type::value, T > abs(T x) any_platform
Definition util.h:464
Expr operator-(Expr lhs, Expr rhs)
Definition expr.cpp:176
auto crossProduct(const ScalarVector< T, D, IMPL > &a, const ScalarVector< T, D, IMPL_ > &b) any_platform
Definition vector.h:274
constexpr T norm(const ScalarVector< T, D, IMPL > &a) any_platform
Euclidean vector norm.
bool operator<(const Expr &rhs, const Expr &lhs)
Definition expr.cpp:211
constexpr Vector< T, 3 > crossProduct3D(const ScalarVector< T, 3, IMPL > &a, const ScalarVector< T, 3, IMPL_ > &b) any_platform
Definition vector.h:263
constexpr Vector< T, D > normalize(const ScalarVector< T, D, IMPL > &a, T scale=T{1})
Definition vector.h:284
#define OLB_PRECONDITION(COND)
Definition olbDebug.h:46
#define any_platform
Define preprocessor macros for device-side functions, constant storage.
Definition platform.h:77
Generic vector of values supporting basic arithmetic.
constexpr const T & operator[](unsigned iDim) const any_platform
Vector of scalars.
GenericVector< T, D, Vector< T, D > > type