DUNE PDELab (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 : FieldVector()
117 {
118 std::fill(_data.begin(), _data.end(), k);
119 }
120
122 constexpr FieldVector (const std::initializer_list<K>& l)
123 : _data{}
124 {
125 assert(l.size() == dimension);
126 for (int i = 0; i < dimension; ++i)
127 _data[i] = std::data(l)[i];
128 }
129
131 template<class T,
132 std::enable_if_t<IsFieldVectorSizeCorrect<T,dimension>::value, int> = 0,
133 decltype(std::declval<K&>() = std::declval<const T&>()[0], bool{}) = true>
134 constexpr FieldVector (const DenseVector<T>& x)
135 : FieldVector()
136 {
137 assert(x.size() == dimension);
138 for (int i = 0; i < dimension; ++i)
139 _data[i] = x[i];
140 }
141
143 template<class T,
144 std::enable_if_t<std::is_assignable_v<K&, const T&>, int> = 0>
145 explicit constexpr FieldVector (const FieldVector<T, SIZE>& x)
146 noexcept(std::is_nothrow_assignable_v<K&, const T&>)
147 : FieldVector()
148 {
149 for (int i = 0; i < dimension; ++i)
150 _data[i] = x[i];
151 }
152
154 template<class K1, int SIZE1,
155 std::enable_if_t<(SIZE1 != SIZE), int> = 0>
156 explicit FieldVector (const FieldVector<K1, SIZE1>&) = delete;
157
159 constexpr FieldVector (const FieldVector&) = default;
160
161
163 template<class T,
164 std::enable_if_t<IsFieldVectorSizeCorrect<T,dimension>::value, int> = 0,
165 decltype(std::declval<K&>() = std::declval<const T&>()[0], bool{}) = true>
166 constexpr FieldVector& operator= (const DenseVector<T>& x)
167 {
168 assert(x.size() == dimension);
169 for (int i = 0; i < dimension; ++i)
170 _data[i] = x[i];
171 return *this;
172 }
173
175 template<class T,
176 std::enable_if_t<std::is_assignable_v<K&, const T&>, int> = 0>
178 noexcept(std::is_nothrow_assignable_v<K&, const T&>)
179 {
180 for (int i = 0; i < dimension; ++i)
181 _data[i] = x[i];
182 return *this;
183 }
184
186 template<class K1, int SIZE1,
187 std::enable_if_t<(SIZE1 != SIZE), int> = 0>
188 constexpr FieldVector& operator= (const FieldVector<K1, SIZE1>&) = delete;
189
191 constexpr FieldVector& operator= (const FieldVector&) = default;
192
193 using Base::operator=;
194
196 static constexpr size_type size () noexcept { return dimension; }
197
199 constexpr reference operator[] (size_type i)
200 {
202 return _data[i];
203 }
204
206 constexpr const_reference operator[] (size_type i) const
207 {
209 return _data[i];
210 }
211
213 constexpr K* data () noexcept
214 {
215 return _data.data();
216 }
217
219 constexpr const K* data () const noexcept
220 {
221 return _data.data();
222 }
223
225 template<class Scalar,
226 std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
227 friend constexpr auto operator* (const FieldVector& vector, Scalar scalar)
228 {
229 using T = typename PromotionTraits<value_type,Scalar>::PromotedType;
230 FieldVector<T,SIZE> result;
231
232 for (size_type i = 0; i < vector.size(); ++i)
233 result[i] = vector[i] * scalar;
234 return result;
235 }
236
238 template<class Scalar,
239 std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
240 friend constexpr auto operator* (Scalar scalar, const FieldVector& vector)
241 {
242 using T = typename PromotionTraits<value_type,Scalar>::PromotedType;
243 FieldVector<T,SIZE> result;
244
245 for (size_type i = 0; i < vector.size(); ++i)
246 result[i] = scalar * vector[i];
247 return result;
248 }
249
251 template<class Scalar,
252 std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
253 friend constexpr auto operator/ (const FieldVector& vector, Scalar scalar)
254 {
255 using T = typename PromotionTraits<value_type,Scalar>::PromotedType;
256 FieldVector<T,SIZE> result;
257
258 for (size_type i = 0; i < vector.size(); ++i)
259 result[i] = vector[i] / scalar;
260
261 return result;
262 }
263
264 };
265
277 template<class K, int SIZE>
278 std::istream &operator>> (std::istream& in, FieldVector<K, SIZE>& v)
279 {
281 for (int i = 0; i < SIZE; ++i)
282 in >> w[i];
283 if (in)
284 v = w;
285 return in;
286 }
287
288#ifndef DOXYGEN
289 template< class K >
290 struct DenseMatVecTraits< FieldVector<K,1> >
291 {
292 typedef FieldVector<K,1> derived_type;
293 typedef K container_type;
294 typedef K value_type;
295 typedef size_t size_type;
296 };
297
300 template<class K>
301 class FieldVector<K, 1> :
302 public DenseVector< FieldVector<K,1> >
303 {
304 K _data;
305 typedef DenseVector< FieldVector<K,1> > Base;
306 public:
308 constexpr static int dimension = 1;
309
310 typedef typename Base::size_type size_type;
311
313 typedef K& reference;
314
316 typedef const K& const_reference;
317
318 //===== construction
319
321 constexpr FieldVector () noexcept
322 : _data()
323 {}
324
326 template<class T,
327 std::enable_if_t<std::is_constructible_v<K,T>, int> = 0>
328 constexpr FieldVector (const T& k) noexcept
329 : _data(k)
330 {}
331
333 constexpr FieldVector (const std::initializer_list<K>& l)
334 {
335 assert(l.size() == 1);
336 _data = *l.begin();
337 }
338
340 template<class T,
341 std::enable_if_t<std::is_constructible_v<K,T>, int> = 0>
342 constexpr FieldVector (const FieldVector<T,1>& x) noexcept
343 : _data(x[0])
344 {}
345
347 template<class T,
348 std::enable_if_t<IsFieldVectorSizeCorrect<T,1>::value, int> = 0,
349 decltype(std::declval<K&>() = std::declval<const T&>()[0], bool{}) = true>
350 constexpr FieldVector (const DenseVector<T>& x)
351 {
352 assert(x.size() == 1);
353 _data = x[0];
354 }
355
357 constexpr FieldVector (const FieldVector&) = default;
358
360 constexpr FieldVector& operator= (const FieldVector&) = default;
361
363 template<class T,
364 decltype(std::declval<K&>() = std::declval<const T&>(), bool{}) = true>
365 constexpr FieldVector& operator= (const FieldVector<T,1>& other) noexcept
366 {
367 _data = other[0];
368 return *this;
369 }
370
372 template<class T,
373 std::enable_if_t<IsFieldVectorSizeCorrect<T,1>::value, int> = 0,
374 decltype(std::declval<K&>() = std::declval<const T&>()[0], bool{}) = true>
375 constexpr FieldVector& operator= (const DenseVector<T>& other)
376 {
377 assert(other.size() == 1);
378 _data = other[0];
379 return *this;
380 }
381
383 template<class T,
384 decltype(std::declval<K&>() = std::declval<const T&>(), bool{}) = true>
385 constexpr FieldVector& operator= (const T& k) noexcept
386 {
387 _data = k;
388 return *this;
389 }
390
391 //===== forward methods to container
392 static constexpr size_type size () noexcept { return 1; }
393
394 constexpr reference operator[] ([[maybe_unused]] size_type i)
395 {
396 DUNE_ASSERT_BOUNDS(i == 0);
397 return _data;
398 }
399 constexpr const_reference operator[] ([[maybe_unused]] size_type i) const
400 {
401 DUNE_ASSERT_BOUNDS(i == 0);
402 return _data;
403 }
404
406 constexpr K* data () noexcept
407 {
408 return &_data;
409 }
410
412 constexpr const K* data () const noexcept
413 {
414 return &_data;
415 }
416
417 //===== conversion operator
418
420 constexpr operator reference () noexcept { return _data; }
421
423 constexpr operator const_reference () const noexcept { return _data; }
424 };
425
426 /* ----- FV / FV ----- */
427 /* mostly not necessary as these operations are already covered via the cast operator */
428
430 template<class K>
431 constexpr bool operator> (const FieldVector<K,1>& a, const FieldVector<K,1>& b) noexcept
432 {
433 return a[0]>b[0];
434 }
435
437 template<class K>
438 constexpr bool operator>= (const FieldVector<K,1>& a, const FieldVector<K,1>& b) noexcept
439 {
440 return a[0]>=b[0];
441 }
442
444 template<class K>
445 constexpr bool operator< (const FieldVector<K,1>& a, const FieldVector<K,1>& b) noexcept
446 {
447 return a[0]<b[0];
448 }
449
451 template<class K>
452 constexpr bool operator<= (const FieldVector<K,1>& a, const FieldVector<K,1>& b) noexcept
453 {
454 return a[0]<=b[0];
455 }
456
457 /* ----- FV / scalar ----- */
458
460 template<class K>
461 constexpr FieldVector<K,1> operator+ (const FieldVector<K,1>& a, const K b) noexcept
462 {
463 return a[0]+b;
464 }
465
467 template<class K>
468 constexpr FieldVector<K,1> operator- (const FieldVector<K,1>& a, const K b) noexcept
469 {
470 return a[0]-b;
471 }
472
474 template<class K>
475 constexpr FieldVector<K,1> operator* (const FieldVector<K,1>& a, const K b) noexcept
476 {
477 return a[0]*b;
478 }
479
481 template<class K>
482 constexpr FieldVector<K,1> operator/ (const FieldVector<K,1>& a, const K b) noexcept
483 {
484 return a[0]/b;
485 }
486
488 template<class K>
489 constexpr bool operator> (const FieldVector<K,1>& a, const K b) noexcept
490 {
491 return a[0]>b;
492 }
493
495 template<class K>
496 constexpr bool operator>= (const FieldVector<K,1>& a, const K b) noexcept
497 {
498 return a[0]>=b;
499 }
500
502 template<class K>
503 constexpr bool operator< (const FieldVector<K,1>& a, const K b) noexcept
504 {
505 return a[0]<b;
506 }
507
509 template<class K>
510 constexpr bool operator<= (const FieldVector<K,1>& a, const K b) noexcept
511 {
512 return a[0]<=b;
513 }
514
516 template<class K>
517 constexpr bool operator== (const FieldVector<K,1>& a, const K b) noexcept
518 {
519 return a[0]==b;
520 }
521
523 template<class K>
524 constexpr bool operator!= (const FieldVector<K,1>& a, const K b) noexcept
525 {
526 return a[0]!=b;
527 }
528
529 /* ----- scalar / FV ------ */
530
532 template<class K>
533 constexpr FieldVector<K,1> operator+ (const K a, const FieldVector<K,1>& b) noexcept
534 {
535 return a+b[0];
536 }
537
539 template<class K>
540 constexpr FieldVector<K,1> operator- (const K a, const FieldVector<K,1>& b) noexcept
541 {
542 return a-b[0];
543 }
544
546 template<class K>
547 constexpr FieldVector<K,1> operator* (const K a, const FieldVector<K,1>& b) noexcept
548 {
549 return a*b[0];
550 }
551
553 template<class K>
554 constexpr FieldVector<K,1> operator/ (const K a, const FieldVector<K,1>& b) noexcept
555 {
556 return a/b[0];
557 }
558
560 template<class K>
561 constexpr bool operator> (const K a, const FieldVector<K,1>& b) noexcept
562 {
563 return a>b[0];
564 }
565
567 template<class K>
568 constexpr bool operator>= (const K a, const FieldVector<K,1>& b) noexcept
569 {
570 return a>=b[0];
571 }
572
574 template<class K>
575 constexpr bool operator< (const K a, const FieldVector<K,1>& b) noexcept
576 {
577 return a<b[0];
578 }
579
581 template<class K>
582 constexpr bool operator<= (const K a, const FieldVector<K,1>& b) noexcept
583 {
584 return a<=b[0];
585 }
586
588 template<class K>
589 constexpr bool operator== (const K a, const FieldVector<K,1>& b) noexcept
590 {
591 return a==b[0];
592 }
593
595 template<class K>
596 constexpr bool operator!= (const K a, const FieldVector<K,1>& b) noexcept
597 {
598 return a!=b[0];
599 }
600#endif
601
602 /* Overloads for common classification functions */
603 namespace MathOverloads {
604
606 template<class K, int SIZE>
608 {
609 bool out = true;
610 for (int i = 0; i < SIZE; ++i) {
611 out &= Dune::isFinite(b[i]);
612 }
613 return out;
614 }
615
617 template<class K, int SIZE>
619 {
620 bool out = false;
621 for (int i = 0; i < SIZE; ++i) {
622 out |= Dune::isInf(b[i]);
623 }
624 return out;
625 }
626
628 template<class K, int SIZE,
629 std::enable_if_t<HasNaN<K>::value, int> = 0>
631 {
632 bool out = false;
633 for (int i = 0; i < SIZE; ++i) {
634 out |= Dune::isNaN(b[i]);
635 }
636 return out;
637 }
638
640 template<class K,
641 std::enable_if_t<HasNaN<K>::value, int> = 0>
644 {
645 return Dune::isUnordered(b[0],c[0]);
646 }
647
648 } // end namespace MathOverloads
649
652} // end namespace Dune
653
654#endif // DUNE_COMMON_FVECTOR_HH
Macro for wrapping boundary checks.
Interface for a class of dense vectors over a given field.
Definition: densevector.hh:230
Traits::value_type value_type
export the type representing the field
Definition: densevector.hh:251
Traits::size_type size_type
The type used for the index access and size operation.
Definition: densevector.hh:260
constexpr size_type size() const
size method
Definition: densevector.hh:337
vector space out of a tensor product of fields.
Definition: fvector.hh:92
constexpr FieldVector(const FieldVector &)=default
Copy constructor with default behavior.
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:122
static constexpr size_type size() noexcept
Obtain the number of elements stored in the vector.
Definition: fvector.hh:196
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:253
friend constexpr auto operator*(const FieldVector &vector, Scalar scalar)
Vector space multiplication with scalar.
Definition: fvector.hh:227
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:145
constexpr const K * data() const noexcept
Return pointer to underlying array.
Definition: fvector.hh:219
constexpr FieldVector & operator=(const DenseVector< T > &x)
Assignment from another dense vector.
Definition: fvector.hh:166
constexpr reference operator[](size_type i)
Return a reference to the ith element.
Definition: fvector.hh:199
constexpr K * data() noexcept
Return pointer to underlying array.
Definition: fvector.hh:213
Implements the dense vector interface, with an exchangeable storage class.
Traits for type conversions and type information.
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
constexpr 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
constexpr 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
constexpr 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
constexpr 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
constexpr 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
constexpr 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
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:630
bool isInf(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Returns whether any entry is infinite.
Definition: fvector.hh:618
auto isFinite(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Returns whether all entries are finite.
Definition: fvector.hh:607
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:642
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
Utilities for type computations, constraining overloads, ...
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Feb 17, 23:30, 2025)