Dune Core Modules (unstable)

fvector.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
4// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
5#ifndef DUNE_COMMON_FVECTOR_HH
6#define DUNE_COMMON_FVECTOR_HH
7
8#include <algorithm>
9#include <array>
10#include <cmath>
11#include <cstdlib>
12#include <cstring>
13#include <type_traits>
14#include <utility>
15#include <initializer_list>
16
20#include <dune/common/math.hh>
24
25namespace Dune {
26
36 template< class K, int SIZE > class FieldVector;
37 template< class K, int SIZE >
38 struct DenseMatVecTraits< FieldVector<K,SIZE> >
39 {
40 typedef FieldVector<K,SIZE> derived_type;
41 typedef std::array<K,SIZE> container_type;
42 typedef K value_type;
43 typedef typename container_type::size_type size_type;
44 };
45
46 template< class K, int SIZE >
47 struct FieldTraits< FieldVector<K,SIZE> >
48 {
49 typedef typename FieldTraits<K>::field_type field_type;
50 typedef typename FieldTraits<K>::real_type real_type;
51 };
52
61 template<typename C, int SIZE>
63 {
68 constexpr static bool value = true;
69 };
70
71 template<typename T, int SIZE>
72 struct IsFieldVectorSizeCorrect<FieldVector<T,SIZE>,SIZE>
73 {
74 constexpr static bool value = true;
75 };
76
77 template<typename T, int SIZE, int SIZE1>
78 struct IsFieldVectorSizeCorrect<FieldVector<T,SIZE1>,SIZE>
79 {
80 constexpr static bool value = false;
81 };
82
83
89 template< class K, int SIZE >
91 public DenseVector< FieldVector<K,SIZE> >
92 {
93 std::array<K,SIZE> _data;
95 public:
97 constexpr static int dimension = SIZE;
98
99 typedef typename Base::size_type size_type;
100 typedef typename Base::value_type value_type;
101
103 typedef value_type& reference;
104
106 typedef const value_type& const_reference;
107
109 constexpr FieldVector () noexcept
110 : _data{}
111 {}
112
114 explicit constexpr FieldVector (const K& k)
115 noexcept(std::is_nothrow_copy_assignable_v<K>)
116 {
117 std::fill(_data.begin(), _data.end(), k);
118 }
119
121 constexpr FieldVector (const std::initializer_list<K>& l)
122 : _data{}
123 {
124 assert(l.size() == dimension);
125 for (int i = 0; i < dimension; ++i)
126 _data[i] = std::data(l)[i];
127 }
128
130 template<class T,
131 std::enable_if_t<IsFieldVectorSizeCorrect<T,dimension>::value, int> = 0,
132 decltype(std::declval<K&>() = std::declval<const T&>()[0], bool{}) = true>
134 {
135 assert(x.size() == dimension);
136 for (int i = 0; i < dimension; ++i)
137 _data[i] = x[i];
138 }
139
141 template<class T,
142 std::enable_if_t<std::is_assignable_v<K&, const T&>, int> = 0>
143 explicit constexpr FieldVector (const FieldVector<T, SIZE>& x)
144 noexcept(std::is_nothrow_assignable_v<K&, const T&>)
145 {
146 for (int i = 0; i < dimension; ++i)
147 _data[i] = x[i];
148 }
149
151 template<class K1, int SIZE1,
152 std::enable_if_t<(SIZE1 != SIZE), int> = 0>
153 explicit FieldVector (const FieldVector<K1, SIZE1>&) = delete;
154
156 FieldVector (const FieldVector&) = default;
157
158
160 template<class T,
161 std::enable_if_t<IsFieldVectorSizeCorrect<T,dimension>::value, int> = 0,
162 decltype(std::declval<K&>() = std::declval<const T&>()[0], bool{}) = true>
163 FieldVector& operator= (const DenseVector<T>& x)
164 {
165 assert(x.size() == dimension);
166 for (int i = 0; i < dimension; ++i)
167 _data[i] = x[i];
168 return *this;
169 }
170
172 template<class T,
173 std::enable_if_t<std::is_assignable_v<K&, const T&>, int> = 0>
175 noexcept(std::is_nothrow_assignable_v<K&, const T&>)
176 {
177 for (int i = 0; i < dimension; ++i)
178 _data[i] = x[i];
179 return *this;
180 }
181
183 template<class K1, int SIZE1,
184 std::enable_if_t<(SIZE1 != SIZE), int> = 0>
185 FieldVector& operator= (const FieldVector<K1, SIZE1>&) = delete;
186
188 constexpr FieldVector& operator= (const FieldVector&) = default;
189
190 using Base::operator=;
191
193 static constexpr size_type size () noexcept { return dimension; }
194
197 {
199 return _data[i];
200 }
201
203 const_reference operator[] (size_type i) const
204 {
206 return _data[i];
207 }
208
210 constexpr K* data () noexcept
211 {
212 return _data.data();
213 }
214
216 constexpr const K* data () const noexcept
217 {
218 return _data.data();
219 }
220
222 template<class Scalar,
223 std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
224 friend constexpr auto operator* (const FieldVector& vector, Scalar scalar)
225 {
226 using T = typename PromotionTraits<value_type,Scalar>::PromotedType;
227 FieldVector<T,SIZE> result;
228
229 for (size_type i = 0; i < vector.size(); ++i)
230 result[i] = vector[i] * scalar;
231 return result;
232 }
233
235 template<class Scalar,
236 std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
237 friend constexpr auto operator* (Scalar scalar, const FieldVector& vector)
238 {
239 using T = typename PromotionTraits<value_type,Scalar>::PromotedType;
240 FieldVector<T,SIZE> result;
241
242 for (size_type i = 0; i < vector.size(); ++i)
243 result[i] = scalar * vector[i];
244 return result;
245 }
246
248 template<class Scalar,
249 std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
250 friend constexpr auto operator/ (const FieldVector& vector, Scalar scalar)
251 {
252 using T = typename PromotionTraits<value_type,Scalar>::PromotedType;
253 FieldVector<T,SIZE> result;
254
255 for (size_type i = 0; i < vector.size(); ++i)
256 result[i] = vector[i] / scalar;
257
258 return result;
259 }
260
261 };
262
274 template<class K, int SIZE>
275 std::istream &operator>> (std::istream& in, FieldVector<K, SIZE>& v)
276 {
278 for (int i = 0; i < SIZE; ++i)
279 in >> w[i];
280 if (in)
281 v = w;
282 return in;
283 }
284
285#ifndef DOXYGEN
286 template< class K >
287 struct DenseMatVecTraits< FieldVector<K,1> >
288 {
289 typedef FieldVector<K,1> derived_type;
290 typedef K container_type;
291 typedef K value_type;
292 typedef size_t size_type;
293 };
294
297 template<class K>
298 class FieldVector<K, 1> :
299 public DenseVector< FieldVector<K,1> >
300 {
301 K _data;
302 typedef DenseVector< FieldVector<K,1> > Base;
303 public:
305 constexpr static int dimension = 1;
306
307 typedef typename Base::size_type size_type;
308
310 typedef K& reference;
311
313 typedef const K& const_reference;
314
315 //===== construction
316
318 constexpr FieldVector () noexcept
319 : _data()
320 {}
321
323 template<class T,
324 std::enable_if_t<std::is_constructible_v<K,T>, int> = 0>
325 constexpr FieldVector (const T& k) noexcept
326 : _data(k)
327 {}
328
330 constexpr FieldVector (const std::initializer_list<K>& l)
331 {
332 assert(l.size() == 1);
333 _data = *l.begin();
334 }
335
337 template<class T,
338 std::enable_if_t<std::is_constructible_v<K,T>, int> = 0>
339 constexpr FieldVector (const FieldVector<T,1>& x) noexcept
340 : _data(x[0])
341 {}
342
344 template<class T,
345 std::enable_if_t<IsFieldVectorSizeCorrect<T,1>::value, int> = 0,
346 decltype(std::declval<K&>() = std::declval<const T&>()[0], bool{}) = true>
347 FieldVector (const DenseVector<T>& x)
348 {
349 assert(x.size() == 1);
350 _data = x[0];
351 }
352
354 constexpr FieldVector (const FieldVector&) = default;
355
357 constexpr FieldVector& operator= (const FieldVector&) = default;
358
360 template<class T,
361 decltype(std::declval<K&>() = std::declval<const T&>(), bool{}) = true>
362 constexpr FieldVector& operator= (const FieldVector<T,1>& other) noexcept
363 {
364 _data = other[0];
365 return *this;
366 }
367
369 template<class T,
370 std::enable_if_t<IsFieldVectorSizeCorrect<T,1>::value, int> = 0,
371 decltype(std::declval<K&>() = std::declval<const T&>()[0], bool{}) = true>
372 FieldVector& operator= (const DenseVector<T>& other)
373 {
374 assert(other.size() == 1);
375 _data = other[0];
376 return *this;
377 }
378
380 template<class T,
381 decltype(std::declval<K&>() = std::declval<const T&>(), bool{}) = true>
382 constexpr FieldVector& operator= (const T& k) noexcept
383 {
384 _data = k;
385 return *this;
386 }
387
388 //===== forward methods to container
389 static constexpr size_type size () noexcept { return 1; }
390
391 reference operator[] ([[maybe_unused]] size_type i)
392 {
393 DUNE_ASSERT_BOUNDS(i == 0);
394 return _data;
395 }
396 const_reference operator[] ([[maybe_unused]] size_type i) const
397 {
398 DUNE_ASSERT_BOUNDS(i == 0);
399 return _data;
400 }
401
403 constexpr K* data () noexcept
404 {
405 return &_data;
406 }
407
409 constexpr const K* data () const noexcept
410 {
411 return &_data;
412 }
413
414 //===== conversion operator
415
417 constexpr operator reference () noexcept { return _data; }
418
420 constexpr operator const_reference () const noexcept { return _data; }
421 };
422
423 /* ----- FV / FV ----- */
424 /* mostly not necessary as these operations are already covered via the cast operator */
425
427 template<class K>
428 constexpr bool operator> (const FieldVector<K,1>& a, const FieldVector<K,1>& b) noexcept
429 {
430 return a[0]>b[0];
431 }
432
434 template<class K>
435 constexpr bool operator>= (const FieldVector<K,1>& a, const FieldVector<K,1>& b) noexcept
436 {
437 return a[0]>=b[0];
438 }
439
441 template<class K>
442 constexpr bool operator< (const FieldVector<K,1>& a, const FieldVector<K,1>& b) noexcept
443 {
444 return a[0]<b[0];
445 }
446
448 template<class K>
449 constexpr bool operator<= (const FieldVector<K,1>& a, const FieldVector<K,1>& b) noexcept
450 {
451 return a[0]<=b[0];
452 }
453
454 /* ----- FV / scalar ----- */
455
457 template<class K>
458 constexpr FieldVector<K,1> operator+ (const FieldVector<K,1>& a, const K b) noexcept
459 {
460 return a[0]+b;
461 }
462
464 template<class K>
465 constexpr FieldVector<K,1> operator- (const FieldVector<K,1>& a, const K b) noexcept
466 {
467 return a[0]-b;
468 }
469
471 template<class K>
472 constexpr FieldVector<K,1> operator* (const FieldVector<K,1>& a, const K b) noexcept
473 {
474 return a[0]*b;
475 }
476
478 template<class K>
479 constexpr FieldVector<K,1> operator/ (const FieldVector<K,1>& a, const K b) noexcept
480 {
481 return a[0]/b;
482 }
483
485 template<class K>
486 constexpr bool operator> (const FieldVector<K,1>& a, const K b) noexcept
487 {
488 return a[0]>b;
489 }
490
492 template<class K>
493 constexpr bool operator>= (const FieldVector<K,1>& a, const K b) noexcept
494 {
495 return a[0]>=b;
496 }
497
499 template<class K>
500 constexpr bool operator< (const FieldVector<K,1>& a, const K b) noexcept
501 {
502 return a[0]<b;
503 }
504
506 template<class K>
507 constexpr bool operator<= (const FieldVector<K,1>& a, const K b) noexcept
508 {
509 return a[0]<=b;
510 }
511
513 template<class K>
514 constexpr bool operator== (const FieldVector<K,1>& a, const K b) noexcept
515 {
516 return a[0]==b;
517 }
518
520 template<class K>
521 constexpr bool operator!= (const FieldVector<K,1>& a, const K b) noexcept
522 {
523 return a[0]!=b;
524 }
525
526 /* ----- scalar / FV ------ */
527
529 template<class K>
530 constexpr FieldVector<K,1> operator+ (const K a, const FieldVector<K,1>& b) noexcept
531 {
532 return a+b[0];
533 }
534
536 template<class K>
537 constexpr FieldVector<K,1> operator- (const K a, const FieldVector<K,1>& b) noexcept
538 {
539 return a-b[0];
540 }
541
543 template<class K>
544 constexpr FieldVector<K,1> operator* (const K a, const FieldVector<K,1>& b) noexcept
545 {
546 return a*b[0];
547 }
548
550 template<class K>
551 constexpr FieldVector<K,1> operator/ (const K a, const FieldVector<K,1>& b) noexcept
552 {
553 return a/b[0];
554 }
555
557 template<class K>
558 constexpr bool operator> (const K a, const FieldVector<K,1>& b) noexcept
559 {
560 return a>b[0];
561 }
562
564 template<class K>
565 constexpr bool operator>= (const K a, const FieldVector<K,1>& b) noexcept
566 {
567 return a>=b[0];
568 }
569
571 template<class K>
572 constexpr bool operator< (const K a, const FieldVector<K,1>& b) noexcept
573 {
574 return a<b[0];
575 }
576
578 template<class K>
579 constexpr bool operator<= (const K a, const FieldVector<K,1>& b) noexcept
580 {
581 return a<=b[0];
582 }
583
585 template<class K>
586 constexpr bool operator== (const K a, const FieldVector<K,1>& b) noexcept
587 {
588 return a==b[0];
589 }
590
592 template<class K>
593 constexpr bool operator!= (const K a, const FieldVector<K,1>& b) noexcept
594 {
595 return a!=b[0];
596 }
597#endif
598
599 /* Overloads for common classification functions */
600 namespace MathOverloads {
601
603 template<class K, int SIZE>
605 {
606 bool out = true;
607 for (int i = 0; i < SIZE; ++i) {
608 out &= Dune::isFinite(b[i]);
609 }
610 return out;
611 }
612
614 template<class K, int SIZE>
616 {
617 bool out = false;
618 for (int i = 0; i < SIZE; ++i) {
619 out |= Dune::isInf(b[i]);
620 }
621 return out;
622 }
623
625 template<class K, int SIZE,
626 std::enable_if_t<HasNaN<K>::value, int> = 0>
628 {
629 bool out = false;
630 for (int i = 0; i < SIZE; ++i) {
631 out |= Dune::isNaN(b[i]);
632 }
633 return out;
634 }
635
637 template<class K,
638 std::enable_if_t<HasNaN<K>::value, int> = 0>
641 {
642 return Dune::isUnordered(b[0],c[0]);
643 }
644
645 } // end namespace MathOverloads
646
649} // end namespace Dune
650
651#endif // DUNE_COMMON_FVECTOR_HH
Macro for wrapping boundary checks.
Interface for a class of dense vectors over a given field.
Definition: densevector.hh:229
Traits::value_type value_type
export the type representing the field
Definition: densevector.hh:250
size_type size() const
size method
Definition: densevector.hh:336
Traits::size_type size_type
The type used for the index access and size operation.
Definition: densevector.hh:259
vector space out of a tensor product of fields.
Definition: fvector.hh:92
constexpr FieldVector(const K &k) noexcept(std::is_nothrow_copy_assignable_v< K >)
Constructor making vector with identical coordinates.
Definition: fvector.hh:114
const value_type & const_reference
The type used for const references to the vector entry.
Definition: fvector.hh:106
constexpr FieldVector(const std::initializer_list< K > &l)
Construct from a std::initializer_list.
Definition: fvector.hh:121
static constexpr size_type size() noexcept
Obtain the number of elements stored in the vector.
Definition: fvector.hh:193
FieldVector & operator=(const DenseVector< T > &x)
Assignment from another dense vector.
Definition: fvector.hh:163
static constexpr int dimension
The size of this vector.
Definition: fvector.hh:97
constexpr FieldVector() noexcept
Default constructor, making value-initialized vector with all components set to zero.
Definition: fvector.hh:109
friend constexpr auto operator/(const FieldVector &vector, Scalar scalar)
Vector space division by scalar.
Definition: fvector.hh:250
friend constexpr auto operator*(const FieldVector &vector, Scalar scalar)
Vector space multiplication with scalar.
Definition: fvector.hh:224
value_type & reference
The type used for references to the vector entry.
Definition: fvector.hh:103
constexpr FieldVector(const FieldVector< T, SIZE > &x) noexcept(std::is_nothrow_assignable_v< K &, const T & >)
Converting constructor from FieldVector with different element type.
Definition: fvector.hh:143
constexpr const K * data() const noexcept
Return pointer to underlying array.
Definition: fvector.hh:216
FieldVector(const FieldVector &)=default
Copy constructor with default behavior.
reference operator[](size_type i)
Return a reference to the ith element.
Definition: fvector.hh:196
constexpr K * data() noexcept
Return pointer to underlying array.
Definition: fvector.hh:210
Implements the dense vector interface, with an exchangeable storage class.
Type traits to determine the type of reals (when working with complex numbers)
std::istream & operator>>(std::istream &stream, std::tuple< Ts... > &t)
Read a std::tuple.
Definition: streamoperators.hh:43
#define DUNE_ASSERT_BOUNDS(cond)
If DUNE_CHECK_BOUNDS is defined: check if condition cond holds; otherwise, do nothing.
Definition: boundschecking.hh:30
EnableIfInterOperable< T1, T2, bool >::type operator<(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:638
EnableIfInterOperable< T1, T2, bool >::type operator>(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:684
EnableIfInterOperable< T1, T2, bool >::type operator<=(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:661
EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:238
EnableIfInterOperable< T1, T2, bool >::type operator>=(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:706
EnableIfInterOperable< T1, T2, bool >::type operator!=(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:260
typename Overloads::ScalarType< std::decay_t< V > >::type Scalar
Element type of some SIMD type.
Definition: interface.hh:235
Some useful basic math stuff.
bool isNaN(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Returns whether any entry is NaN.
Definition: fvector.hh:627
bool isInf(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Returns whether any entry is infinite.
Definition: fvector.hh:615
auto isFinite(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Returns whether all entries are finite.
Definition: fvector.hh:604
bool isUnordered(const FieldVector< K, 1 > &b, const FieldVector< K, 1 > &c, PriorityTag< 2 >, ADLTag)
Returns true if either b or c is NaN.
Definition: fvector.hh:639
Dune namespace.
Definition: alignedallocator.hh:13
Compute type of the result of an arithmetic operation involving two different number types.
TMP to check the size of a DenseVectors statically, if possible.
Definition: fvector.hh:63
static constexpr bool value
True if C is not of type FieldVector or its dimension is not equal SIZE.
Definition: fvector.hh:68
Tag to make sure the functions in this namespace can be found by ADL.
Definition: math.hh:230
Helper class for tagging priorities.
Definition: typeutilities.hh:73
Traits for type conversions and type information.
Utilities for type computations, constraining overloads, ...
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Dec 21, 23:30, 2024)