DUNE-FEM (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.
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
Traits for type conversions and type information.
Utilities for type computations, constraining overloads, ...
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Apr 5, 23:02, 2025)