dune-common  2.11
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 <concepts>
12 #include <cstdlib>
13 #include <cstring>
14 #include <type_traits>
15 #include <utility>
16 #include <initializer_list>
17 
21 #include <dune/common/ftraits.hh>
22 #include <dune/common/math.hh>
29 
30 namespace Dune {
31 
41  template< class K, int SIZE > class FieldVector;
42  template< class K, int SIZE >
43  struct DenseMatVecTraits< FieldVector<K,SIZE> >
44  {
46  typedef std::array<K,SIZE> container_type;
47  typedef K value_type;
48  typedef typename container_type::size_type size_type;
49  };
50 
51  template< class K, int SIZE >
52  struct FieldTraits< FieldVector<K,SIZE> >
53  {
56  };
57 
66  template<typename C, int SIZE>
68  {
73  constexpr static bool value = true;
74  };
75 
76  template<typename T, int SIZE>
78  {
79  constexpr static bool value = true;
80  };
81 
82  template<typename T, int SIZE, int SIZE1>
83  struct IsFieldVectorSizeCorrect<FieldVector<T,SIZE1>,SIZE>
84  {
85  constexpr static bool value = false;
86  };
87 
88 
94  template< class K, int SIZE >
95  class FieldVector :
96  public DenseVector< FieldVector<K,SIZE> >
97  {
98  using Base = DenseVector< FieldVector<K,SIZE> >;
99 
101  std::array<K,SIZE> _data;
102 
103  public:
104 
106  static constexpr int dimension = SIZE;
107 
109  using size_type = typename Base::size_type;
110 
112  using value_type = typename Base::value_type;
113 
116 
118  using const_reference = const value_type&;
119 
120  public:
121 
123  constexpr FieldVector ()
124  noexcept(std::is_nothrow_default_constructible_v<K>)
125  : _data{}
126  {}
127 
129  explicit(SIZE != 1)
130  constexpr FieldVector (const value_type& value) noexcept
131  : _data{filledArray<SIZE>(value)}
132  {}
133 
135  template<Concept::Number S>
136  requires (std::constructible_from<K,S>)
137  explicit(SIZE != 1)
138  constexpr FieldVector (const S& scalar)
139  noexcept(std::is_nothrow_constructible_v<K,S>)
140  : _data{filledArray<SIZE,K>(K(scalar))}
141  {}
142 
144  constexpr FieldVector (const std::initializer_list<K>& l)
145  : _data{}
146  {
147  assert(l.size() == size());
148  for (size_type i = 0; i < size(); ++i)
149  _data[i] = std::data(l)[i];
150  }
151 
153  template<class V>
155  std::is_assignable_v<K&, decltype(std::declval<const V&>()[0])>)
156  constexpr FieldVector (const DenseVector<V>& x)
157  {
158  assert(x.size() == size());
159  for (size_type i = 0; i < size(); ++i)
160  _data[i] = x[i];
161  }
162 
164  template<class OtherK>
165  requires (std::is_assignable_v<K&, const OtherK&>)
166  explicit constexpr FieldVector (const FieldVector<OtherK, SIZE>& x)
167  noexcept(std::is_nothrow_assignable_v<K&, const OtherK&>)
168  {
169  for (size_type i = 0; i < size(); ++i)
170  _data[i] = x[i];
171  }
172 
174  constexpr FieldVector (const FieldVector&) = default;
175 
176 
178  template<class V>
180  std::is_assignable_v<K&, decltype(std::declval<const V&>()[0])>)
181  constexpr FieldVector& operator= (const DenseVector<V>& x)
182  {
183  assert(x.size() == size());
184  for (size_type i = 0; i < size(); ++i)
185  _data[i] = x[i];
186  return *this;
187  }
188 
190  template<Concept::Number S>
191  requires std::constructible_from<K,S>
192  constexpr FieldVector& operator= (const S& scalar)
193  noexcept(std::is_nothrow_constructible_v<K,S>)
194  {
195  _data.fill(K(scalar));
196  return *this;
197  }
198 
200  template<class OtherK>
201  requires (std::is_assignable_v<K&, const OtherK&>)
202  constexpr FieldVector& operator= (const FieldVector<OtherK, SIZE>& x)
203  noexcept(std::is_nothrow_assignable_v<K&, const OtherK&>)
204  {
205  for (size_type i = 0; i < size(); ++i)
206  _data[i] = x[i];
207  return *this;
208  }
209 
211  constexpr FieldVector& operator= (const FieldVector&) = default;
212 
213 
216 
218  static constexpr size_type size () noexcept { return SIZE; }
219 
221 
222 
225 
231  {
233  return _data[i];
234  }
235 
241  {
243  return _data[i];
244  }
245 
247  constexpr K* data () noexcept
248  {
249  return _data.data();
250  }
251 
253  constexpr const K* data () const noexcept
254  {
255  return _data.data();
256  }
257 
259  constexpr operator const_reference () const noexcept
260  requires(SIZE == 1)
261  {
262  return _data[0];
263  }
264 
266  constexpr operator reference () noexcept
267  requires(SIZE == 1)
268  {
269  return _data[0];
270  }
271 
273 
274 
277 
279  template<Concept::Number S>
280  friend constexpr bool operator== (const FieldVector& a, const S& b) noexcept
281  requires(SIZE == 1)
282  {
283  return a._data[0] == b;
284  }
285 
287  template<Concept::Number S>
288  friend constexpr bool operator== (const S& a, const FieldVector& b) noexcept
289  requires(SIZE == 1)
290  {
291  return a == b._data[0];
292  }
293 
295  template<class T>
296  requires (Std::three_way_comparable_with<K,T>)
297  friend constexpr auto operator<=> (const FieldVector& a, const FieldVector<T,SIZE>& b) noexcept
298  {
299 #if __cpp_lib_three_way_comparison
300  return a._data <=> b._data;
301 #else
302  return Std::lexicographical_compare_three_way(a.begin(), a.end(), b.begin(), b.end());
303 #endif
304  }
305 
307  template<Concept::Number S>
308  friend constexpr auto operator<=> (const FieldVector& a, const S& b) noexcept
309  requires(SIZE == 1)
310  {
311  return a._data[0] <=> b;
312  }
313 
315  template<Concept::Number S>
316  friend constexpr auto operator<=> (const S& a, const FieldVector& b) noexcept
317  requires(SIZE == 1)
318  {
319  return a <=> b._data[0];
320  }
321 
323 
324 
327 
329  template<Concept::Number S>
330  friend constexpr auto operator* (const FieldVector& a, const S& b) noexcept
331  {
332  using ResultValueType = typename PromotionTraits<K,S>::PromotedType;
333  FieldVector<ResultValueType,dimension> result;
334  for (size_type i = 0; i < size(); ++i)
335  result[i] = a[i] * b;
336  return result;
337  }
338 
340  template<Concept::Number S>
341  friend constexpr auto operator* (const S& a, const FieldVector& b) noexcept
342  {
343  using ResultValueType = typename PromotionTraits<K,S>::PromotedType;
344  FieldVector<ResultValueType,dimension> result;
345  for (size_type i = 0; i < size(); ++i)
346  result[i] = a * b[i];
347  return result;
348  }
349 
351  template<Concept::Number S>
352  friend constexpr auto operator/ (const FieldVector& a, const S& b) noexcept
353  {
354  using ResultValueType = typename PromotionTraits<K,S>::PromotedType;
355  FieldVector<ResultValueType,dimension> result;
356  for (size_type i = 0; i < size(); ++i)
357  result[i] = a[i] / b;
358  return result;
359  }
360 
362  template<Concept::Number S>
363  friend constexpr FieldVector operator/ (const S& a, const FieldVector& b) noexcept
364  requires(SIZE == 1)
365  {
366  return FieldVector{a / b[0]};
367  }
368 
370  template<Concept::Number S>
371  friend constexpr auto operator+ (const FieldVector& a, const S& b) noexcept
372  requires(SIZE == 1)
373  {
374  using ResultValueType = typename PromotionTraits<K,S>::PromotedType;
375  return FieldVector<ResultValueType,dimension>{a[0] + b};
376  }
377 
379  template<Concept::Number S>
380  friend constexpr auto operator+ (const S& a, const FieldVector& b) noexcept
381  requires(SIZE == 1)
382  {
383  using ResultValueType = typename PromotionTraits<K,S>::PromotedType;
384  return FieldVector<ResultValueType,dimension>{a + b[0]};
385  }
386 
388  template<Concept::Number S>
389  friend constexpr auto operator- (const FieldVector& a, const S& b) noexcept
390  requires(SIZE == 1)
391  {
392  using ResultValueType = typename PromotionTraits<K,S>::PromotedType;
393  return FieldVector<ResultValueType,dimension>{a[0] - b};
394  }
395 
397  template<Concept::Number S>
398  friend constexpr auto operator- (const S& a, const FieldVector& b) noexcept
399  requires(SIZE == 1)
400  {
401  using ResultValueType = typename PromotionTraits<K,S>::PromotedType;
402  return FieldVector<ResultValueType,dimension>{a - b[0]};
403  }
404 
406  };
407 
419  template<class K, int SIZE>
420  std::istream& operator>> (std::istream& in, FieldVector<K, SIZE>& v)
421  {
423  for (int i = 0; i < SIZE; ++i)
424  in >> w[i];
425  if (in)
426  v = w;
427  return in;
428  }
429 
430  /* Overloads for common classification functions */
431  namespace MathOverloads {
432 
434  template<class K, int SIZE>
436  {
437  bool out = true;
438  for (int i = 0; i < SIZE; ++i) {
439  out &= Dune::isFinite(b[i]);
440  }
441  return out;
442  }
443 
445  template<class K, int SIZE>
447  {
448  bool out = false;
449  for (int i = 0; i < SIZE; ++i) {
450  out |= Dune::isInf(b[i]);
451  }
452  return out;
453  }
454 
456  template<class K, int SIZE,
457  std::enable_if_t<HasNaN<K>::value, int> = 0>
459  {
460  bool out = false;
461  for (int i = 0; i < SIZE; ++i) {
462  out |= Dune::isNaN(b[i]);
463  }
464  return out;
465  }
466 
468  template<class K,
469  std::enable_if_t<HasNaN<K>::value, int> = 0>
472  {
473  return Dune::isUnordered(b[0],c[0]);
474  }
475 
476  } // end namespace MathOverloads
477 
480 } // end namespace Dune
481 
482 #endif // DUNE_COMMON_FVECTOR_HH
constexpr bool operator==(const DenseVector< Other > &x) const
Binary vector comparison.
Definition: densevector.hh:570
Type traits to determine the type of reals (when working with complex numbers)
Implements the dense vector interface, with an exchangeable storage class.
auto isFinite(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Returns whether all entries are finite.
Definition: fvector.hh:435
decltype(std::declval< T1 >()+std::declval< T2 >()) typedef PromotedType
Definition: promotiontraits.hh:28
bool isNaN(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Returns whether any entry is NaN.
Definition: fvector.hh:458
Utility to generate an array with a certain value.
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:470
This file provides some concepts introduced in the C++20 standard library <compare> and <concepts> no...
Some useful basic math stuff.
std::istream & operator>>(std::istream &stream, std::tuple< Ts... > &t)
Read a std::tuple.
Definition: streamoperators.hh:43
constexpr auto lexicographical_compare_three_way(I1 f1, I1 l1, I2 f2, I2 l2, Cmp comp={}) -> decltype(comp(*f1, *f2))
Lexicographically compares two ranges [first1, last1) and [first2, last2) using three-way comparison ...
Definition: algorithm.hh:37
constexpr derived_type operator+(const DenseVector< Other > &b) const
Binary vector addition.
Definition: densevector.hh:454
constexpr FieldVector() noexcept(std::is_nothrow_default_constructible_v< K >)
Default constructor, making value-initialized vector with all components set to zero.
Definition: fvector.hh:123
value_type & reference
The type used for references to the vector entries.
Definition: fvector.hh:115
container_type::size_type size_type
Definition: fvector.hh:48
#define DUNE_ASSERT_BOUNDS(cond)
If DUNE_CHECK_BOUNDS is defined: check if condition cond holds; otherwise, do nothing.
Definition: boundschecking.hh:30
Definition: matvectraits.hh:31
static constexpr int dimension
The size of this vector.
Definition: fvector.hh:106
constexpr PromotionTraits< field_type, typename DenseVector< Other >::field_type >::PromotedType operator*(const DenseVector< Other > &x) const
indefinite vector dot product which corresponds to Petsc&#39;s VecTDot
Definition: densevector.hh:606
I i
Definition: hybridmultiindex.hh:328
T real_type
export the type representing the real type of the field
Definition: ftraits.hh:30
typename Base::value_type value_type
The type of the elements stored in the vector.
Definition: fvector.hh:112
static constexpr bool value
True if C is not of type FieldVector or its dimension is not equal SIZE.
Definition: fvector.hh:73
Macro for wrapping boundary checks.
FieldTraits< K >::real_type real_type
Definition: fvector.hh:55
std::array< K, SIZE > container_type
Definition: fvector.hh:46
FieldVector< K, SIZE > derived_type
Definition: fvector.hh:45
Tag to make sure the functions in this namespace can be found by ADL.
Definition: math.hh:212
Dune namespace
Definition: alignedallocator.hh:12
Traits::size_type size_type
The type used for the index access and size operation.
Definition: densevector.hh:274
Utilities for type computations, constraining overloads, ...
Interface for a class of dense vectors over a given field.
Definition: densevector.hh:23
const value_type & const_reference
The type used for const references to the vector entries.
Definition: fvector.hh:118
vector space out of a tensor product of fields.
Definition: densematrix.hh:40
bigunsignedint< k > operator/(const bigunsignedint< k > &x, std::uintmax_t y)
Definition: bigunsignedint.hh:579
Compute type of the result of an arithmetic operation involving two different number types...
Definition: ftraits.hh:25
constexpr derived_type & operator=(const value_type &k)
Assignment operator for scalar.
Definition: densevector.hh:281
bool isInf(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Returns whether any entry is infinite.
Definition: fvector.hh:446
Helper class for tagging priorities.
Definition: typeutilities.hh:72
T field_type
export the type representing the field
Definition: ftraits.hh:28
constexpr K * data() noexcept
Return pointer to underlying array.
Definition: fvector.hh:247
STL namespace.
constexpr derived_type operator-() const
Vector negation.
Definition: densevector.hh:469
TMP to check the size of a DenseVectors statically, if possible.
Definition: fvector.hh:67
Traits for type conversions and type information.
Traits::value_type value_type
export the type representing the field
Definition: densevector.hh:265
typename Base::size_type size_type
The type used for the index access and size operation.
Definition: fvector.hh:109
constexpr const K * data() const noexcept
Return pointer to underlying array.
Definition: fvector.hh:253
requires(std::constructible_from< K, S >) explicit(SIZE !
Constructor with a given scalar initializing all entries to this value.
FieldTraits< K >::field_type field_type
Definition: fvector.hh:54
static constexpr size_type size() noexcept
Obtain the number of elements stored in the vector.
Definition: fvector.hh:218
constexpr reference operator[](size_type i)
Return a reference to the ith element.
Definition: fvector.hh:230