DUNE PDELab (git)

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 <array>
9#include <cmath>
10#include <cstdlib>
11#include <cstring>
12#include <type_traits>
13#include <utility>
14#include <initializer_list>
15
19#include <dune/common/math.hh>
23
24namespace Dune {
25
35 template< class K, int SIZE > class FieldVector;
36 template< class K, int SIZE >
37 struct DenseMatVecTraits< FieldVector<K,SIZE> >
38 {
39 typedef FieldVector<K,SIZE> derived_type;
40 typedef std::array<K,SIZE> container_type;
41 typedef K value_type;
42 typedef typename container_type::size_type size_type;
43 };
44
45 template< class K, int SIZE >
46 struct FieldTraits< FieldVector<K,SIZE> >
47 {
48 typedef typename FieldTraits<K>::field_type field_type;
49 typedef typename FieldTraits<K>::real_type real_type;
50 };
51
60 template<typename C, int SIZE>
62 {
67 constexpr static bool value = true;
68 };
69
70 template<typename T, int SIZE>
71 struct IsFieldVectorSizeCorrect<FieldVector<T,SIZE>,SIZE>
72 {
73 constexpr static bool value = true;
74 };
75
76 template<typename T, int SIZE, int SIZE1>
77 struct IsFieldVectorSizeCorrect<FieldVector<T,SIZE1>,SIZE>
78 {
79 constexpr static bool value = false;
80 };
81
82
88 template< class K, int SIZE >
90 public DenseVector< FieldVector<K,SIZE> >
91 {
92 std::array<K,SIZE> _data;
94 public:
96 constexpr static int dimension = SIZE;
97
98 typedef typename Base::size_type size_type;
99 typedef typename Base::value_type value_type;
100
102 typedef value_type& reference;
103
105 typedef const value_type& const_reference;
106
108 constexpr FieldVector () noexcept
109 : _data{}
110 {}
111
113 explicit constexpr FieldVector (const K& k)
114 noexcept(std::is_nothrow_copy_assignable_v<K>)
115 {
116 for (auto& d : _data)
117 d = 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:91
constexpr FieldVector(const K &k) noexcept(std::is_nothrow_copy_assignable_v< K >)
Constructor making vector with identical coordinates.
Definition: fvector.hh:113
const value_type & const_reference
The type used for const references to the vector entry.
Definition: fvector.hh:105
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:96
constexpr FieldVector() noexcept
Default constructor, making value-initialized vector with all components set to zero.
Definition: fvector.hh:108
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:102
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.
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
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:62
static constexpr bool value
True if C is not of type FieldVector or its dimension is not equal SIZE.
Definition: fvector.hh:67
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  |  generated with Hugo v0.111.3 (Nov 23, 23:29, 2024)