dune-common  2.9.0
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 (C) 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_FVECTOR_HH
6 #define DUNE_FVECTOR_HH
7 
8 #include <array>
9 #include <cmath>
10 #include <cstddef>
11 #include <cstdlib>
12 #include <complex>
13 #include <cstring>
14 #include <utility>
15 #include <initializer_list>
16 #include <algorithm>
17 
18 #include "typetraits.hh"
19 #include "exceptions.hh"
20 
21 #include "ftraits.hh"
22 #include "densevector.hh"
23 #include "boundschecking.hh"
24 
25 #include <dune/common/math.hh>
27 
28 namespace Dune {
29 
39  template< class K, int SIZE > class FieldVector;
40  template< class K, int SIZE >
41  struct DenseMatVecTraits< FieldVector<K,SIZE> >
42  {
44  typedef std::array<K,SIZE> container_type;
45  typedef K value_type;
46  typedef typename container_type::size_type size_type;
47  };
48 
49  template< class K, int SIZE >
50  struct FieldTraits< FieldVector<K,SIZE> >
51  {
54  };
55 
64  template<typename C, int SIZE>
66  {
71  constexpr static bool value = true;
72  };
73 
74  template<typename T, int SIZE>
76  {
77  constexpr static bool value = true;
78  };
79 
80  template<typename T, int SIZE, int SIZE1>
81  struct IsFieldVectorSizeCorrect<FieldVector<T,SIZE1>,SIZE>
82  {
83  constexpr static bool value = false;
84  };
85 
86 
92  template< class K, int SIZE >
93  class FieldVector :
94  public DenseVector< FieldVector<K,SIZE> >
95  {
96  std::array<K,SIZE> _data;
98  public:
100  constexpr static int dimension = SIZE;
101 
102  typedef typename Base::size_type size_type;
103  typedef typename Base::value_type value_type;
104 
107 
109  typedef const value_type& const_reference;
110 
112  constexpr FieldVector()
113  : _data{{}}
114  {}
115 
117  explicit FieldVector (const K& t)
118  {
119  std::fill(_data.begin(),_data.end(),t);
120  }
121 
122 #if __GNUC__ == 5 && !defined(__clang__)
123  // `... = default;` causes an internal compiler error on GCC 5.4 (Ubuntu 16.04)
125  FieldVector(const FieldVector& x) : _data(x._data) {}
126 #else
128  FieldVector (const FieldVector&) = default;
129 #endif
130 
132  FieldVector (std::initializer_list<K> const &l)
133  {
134  assert(l.size() == dimension);// Actually, this is not needed any more!
135  std::copy_n(l.begin(), std::min(static_cast<std::size_t>(dimension),
136  l.size()),
137  _data.begin());
138  }
139 
141  FieldVector& operator= (const FieldVector&) = default;
142 
143  template <typename T>
144  FieldVector& operator= (const FieldVector<T, SIZE>& x)
145  {
146  std::copy_n(x.begin(), SIZE, _data.begin());
147  return *this;
148  }
149 
150  template<typename T, int N>
152 
164  template<class C>
166  [[maybe_unused]] typename std::enable_if<IsFieldVectorSizeCorrect<C,SIZE>::value>::type* dummy=0)
167  {
168  // do a run-time size check, for the case that x is not a FieldVector
169  assert(x.size() == SIZE); // Actually this is not needed any more!
170  std::copy_n(x.begin(), std::min(static_cast<std::size_t>(SIZE),x.size()), _data.begin());
171  }
172 
174  template<class K1>
175  explicit FieldVector (const FieldVector<K1,SIZE> & x)
176  {
177  std::copy_n(x.begin(), SIZE, _data.begin());
178  }
179 
180  template<typename T, int N>
181  explicit FieldVector(const FieldVector<T, N>&) = delete;
182 
183  using Base::operator=;
184 
185  // make this thing a vector
186  static constexpr size_type size () { return SIZE; }
187 
189  DUNE_ASSERT_BOUNDS(i < SIZE);
190  return _data[i];
191  }
192  const K & operator[](size_type i) const {
193  DUNE_ASSERT_BOUNDS(i < SIZE);
194  return _data[i];
195  }
196 
198  K* data() noexcept
199  {
200  return _data.data();
201  }
202 
204  const K* data() const noexcept
205  {
206  return _data.data();
207  }
208 
210  template <class Scalar,
211  std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
212  friend auto operator* ( const FieldVector& vector, Scalar scalar)
213  {
215 
216  for (size_type i = 0; i < vector.size(); ++i)
217  result[i] = vector[i] * scalar;
218 
219  return result;
220  }
221 
223  template <class Scalar,
224  std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
225  friend auto operator* ( Scalar scalar, const FieldVector& vector)
226  {
228 
229  for (size_type i = 0; i < vector.size(); ++i)
230  result[i] = scalar * vector[i];
231 
232  return result;
233  }
234 
236  template <class Scalar,
237  std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
238  friend auto operator/ ( const FieldVector& vector, Scalar scalar)
239  {
241 
242  for (size_type i = 0; i < vector.size(); ++i)
243  result[i] = vector[i] / scalar;
244 
245  return result;
246  }
247 
248  };
249 
261  template<class K, int SIZE>
262  inline std::istream &operator>> ( std::istream &in,
264  {
266  for( typename FieldVector<K, SIZE>::size_type i = 0; i < SIZE; ++i )
267  in >> w[ i ];
268  if(in)
269  v = w;
270  return in;
271  }
272 
273 #ifndef DOXYGEN
274  template< class K >
275  struct DenseMatVecTraits< FieldVector<K,1> >
276  {
277  typedef FieldVector<K,1> derived_type;
278  typedef K container_type;
279  typedef K value_type;
280  typedef size_t size_type;
281  };
282 
285  template<class K>
286  class FieldVector<K, 1> :
287  public DenseVector< FieldVector<K,1> >
288  {
289  K _data;
290  typedef DenseVector< FieldVector<K,1> > Base;
291  public:
293  constexpr static int dimension = 1;
294 
295  typedef typename Base::size_type size_type;
296 
298  typedef K& reference;
299 
301  typedef const K& const_reference;
302 
303  //===== construction
304 
306  constexpr FieldVector ()
307  : _data()
308  {}
309 
311  template<typename T,
312  typename EnableIf = typename std::enable_if<
313  std::is_convertible<T, K>::value &&
314  ! std::is_base_of<DenseVector<typename FieldTraits<T>::field_type>, K
315  >::value
316  >::type
317  >
318  FieldVector (const T& k) : _data(k) {}
319 
321  template<class C,
322  std::enable_if_t<
323  std::is_assignable<K&, typename DenseVector<C>::value_type>::value, int> = 0>
324  FieldVector (const DenseVector<C> & x)
325  {
326  static_assert(((bool)IsFieldVectorSizeCorrect<C,1>::value), "FieldVectors do not match in dimension!");
327  assert(x.size() == 1);
328  _data = x[0];
329  }
330 
332  FieldVector(const FieldVector&) = default;
333 
335  FieldVector& operator=(const FieldVector&) = default;
336 
337  template <typename T>
338  FieldVector& operator= (const FieldVector<T, 1>& other)
339  {
340  _data = other[0];
341  return *this;
342  }
343 
344  template<typename T, int N>
345  FieldVector& operator=(const FieldVector<T, N>&) = delete;
346 
348  FieldVector (std::initializer_list<K> const &l)
349  {
350  assert(l.size() == 1);
351  _data = *l.begin();
352  }
353 
355  template<typename T,
356  typename EnableIf = typename std::enable_if<
357  std::is_assignable<K&, T>::value &&
358  ! std::is_base_of<DenseVector<typename FieldTraits<T>::field_type>, K
359  >::value
360  >::type
361  >
362  inline FieldVector& operator= (const T& k)
363  {
364  _data = k;
365  return *this;
366  }
367 
368  //===== forward methods to container
369  static constexpr size_type size () { return 1; }
370 
371  K & operator[]([[maybe_unused]] size_type i)
372  {
373  DUNE_ASSERT_BOUNDS(i == 0);
374  return _data;
375  }
376  const K & operator[]([[maybe_unused]] size_type i) const
377  {
378  DUNE_ASSERT_BOUNDS(i == 0);
379  return _data;
380  }
381 
383  K* data() noexcept
384  {
385  return &_data;
386  }
387 
389  const K* data() const noexcept
390  {
391  return &_data;
392  }
393 
394  //===== conversion operator
395 
397  operator K& () { return _data; }
398 
400  operator const K& () const { return _data; }
401  };
402 
403  /* ----- FV / FV ----- */
404  /* mostly not necessary as these operations are already covered via the cast operator */
405 
407  template<class K>
408  inline bool operator> (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
409  {
410  return a[0]>b[0];
411  }
412 
414  template<class K>
415  inline bool operator>= (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
416  {
417  return a[0]>=b[0];
418  }
419 
421  template<class K>
422  inline bool operator< (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
423  {
424  return a[0]<b[0];
425  }
426 
428  template<class K>
429  inline bool operator<= (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
430  {
431  return a[0]<=b[0];
432  }
433 
434  /* ----- FV / scalar ----- */
435 
437  template<class K>
438  inline FieldVector<K,1> operator+ (const FieldVector<K,1>& a, const K b)
439  {
440  return a[0]+b;
441  }
442 
444  template<class K>
445  inline FieldVector<K,1> operator- (const FieldVector<K,1>& a, const K b)
446  {
447  return a[0]-b;
448  }
449 
451  template<class K>
452  inline FieldVector<K,1> operator* (const FieldVector<K,1>& a, const K b)
453  {
454  return a[0]*b;
455  }
456 
458  template<class K>
459  inline FieldVector<K,1> operator/ (const FieldVector<K,1>& a, const K b)
460  {
461  return a[0]/b;
462  }
463 
465  template<class K>
466  inline bool operator> (const FieldVector<K,1>& a, const K b)
467  {
468  return a[0]>b;
469  }
470 
472  template<class K>
473  inline bool operator>= (const FieldVector<K,1>& a, const K b)
474  {
475  return a[0]>=b;
476  }
477 
479  template<class K>
480  inline bool operator< (const FieldVector<K,1>& a, const K b)
481  {
482  return a[0]<b;
483  }
484 
486  template<class K>
487  inline bool operator<= (const FieldVector<K,1>& a, const K b)
488  {
489  return a[0]<=b;
490  }
491 
493  template<class K>
494  inline bool operator== (const FieldVector<K,1>& a, const K b)
495  {
496  return a[0]==b;
497  }
498 
500  template<class K>
501  inline bool operator!= (const FieldVector<K,1>& a, const K b)
502  {
503  return a[0]!=b;
504  }
505 
506  /* ----- scalar / FV ------ */
507 
509  template<class K>
510  inline FieldVector<K,1> operator+ (const K a, const FieldVector<K,1>& b)
511  {
512  return a+b[0];
513  }
514 
516  template<class K>
517  inline FieldVector<K,1> operator- (const K a, const FieldVector<K,1>& b)
518  {
519  return a-b[0];
520  }
521 
523  template<class K>
524  inline FieldVector<K,1> operator* (const K a, const FieldVector<K,1>& b)
525  {
526  return a*b[0];
527  }
528 
530  template<class K>
531  inline FieldVector<K,1> operator/ (const K a, const FieldVector<K,1>& b)
532  {
533  return a/b[0];
534  }
535 
537  template<class K>
538  inline bool operator> (const K a, const FieldVector<K,1>& b)
539  {
540  return a>b[0];
541  }
542 
544  template<class K>
545  inline bool operator>= (const K a, const FieldVector<K,1>& b)
546  {
547  return a>=b[0];
548  }
549 
551  template<class K>
552  inline bool operator< (const K a, const FieldVector<K,1>& b)
553  {
554  return a<b[0];
555  }
556 
558  template<class K>
559  inline bool operator<= (const K a, const FieldVector<K,1>& b)
560  {
561  return a<=b[0];
562  }
563 
565  template<class K>
566  inline bool operator== (const K a, const FieldVector<K,1>& b)
567  {
568  return a==b[0];
569  }
570 
572  template<class K>
573  inline bool operator!= (const K a, const FieldVector<K,1>& b)
574  {
575  return a!=b[0];
576  }
577 #endif
578 
579  /* Overloads for common classification functions */
580  namespace MathOverloads {
581 
582  // ! Returns whether all entries are finite
583  template<class K, int SIZE>
585  bool out = true;
586  for(int i=0; i<SIZE; i++) {
587  out &= Dune::isFinite(b[i]);
588  }
589  return out;
590  }
591 
592  // ! Returns whether any entry is infinite
593  template<class K, int SIZE>
595  bool out = false;
596  for(int i=0; i<SIZE; i++) {
597  out |= Dune::isInf(b[i]);
598  }
599  return out;
600  }
601 
602  // ! Returns whether any entry is NaN
603  template<class K, int SIZE, typename = std::enable_if_t<HasNaN<K>::value>>
605  bool out = false;
606  for(int i=0; i<SIZE; i++) {
607  out |= Dune::isNaN(b[i]);
608  }
609  return out;
610  }
611 
612  // ! Returns true if either b or c is NaN
613  template<class K, typename = std::enable_if_t<HasNaN<K>::value>>
616  return Dune::isUnordered(b[0],c[0]);
617  }
618  } //MathOverloads
619 
622 } // end namespace
623 
624 #endif
Macro for wrapping boundary checks.
Implements the dense vector interface, with an exchangeable storage class.
A few common exception classes.
Type traits to determine the type of reals (when working with complex numbers)
Some useful basic math stuff.
Compute type of the result of an arithmetic operation involving two different number types.
Traits for type conversions and type information.
#define DUNE_ASSERT_BOUNDS(cond)
If DUNE_CHECK_BOUNDS is defined: check if condition cond holds; otherwise, do nothing.
Definition: boundschecking.hh:30
bigunsignedint< k > operator+(const bigunsignedint< k > &x, std::uintmax_t y)
Definition: bigunsignedint.hh:535
bigunsignedint< k > operator*(const bigunsignedint< k > &x, std::uintmax_t y)
Definition: bigunsignedint.hh:549
bigunsignedint< k > operator-(const bigunsignedint< k > &x, std::uintmax_t y)
Definition: bigunsignedint.hh:542
bigunsignedint< k > operator/(const bigunsignedint< k > &x, std::uintmax_t y)
Definition: bigunsignedint.hh:556
std::istream & operator>>(std::istream &in, DynamicVector< K, Allocator > &v)
Read a DynamicVector from an input stream.
Definition: dynvector.hh:189
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:259
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:683
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:637
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:237
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:705
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:660
typename Overloads::ScalarType< std::decay_t< V > >::type Scalar
Element type of some SIMD type.
Definition: simd/interface.hh:235
Dune namespace.
Definition: alignedallocator.hh:13
auto min(const AlignedNumber< T, align > &a, const AlignedNumber< T, align > &b)
Definition: debugalign.hh:447
bool isNaN(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Definition: fvector.hh:604
bool isInf(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Definition: fvector.hh:594
auto isFinite(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Definition: fvector.hh:584
bool isUnordered(const FieldVector< K, 1 > &b, const FieldVector< K, 1 > &c, PriorityTag< 2 >, ADLTag)
Definition: fvector.hh:614
vector space out of a tensor product of fields.
Definition: fvector.hh:95
const K * data() const noexcept
return pointer to underlying array
Definition: fvector.hh:204
constexpr FieldVector()
Constructor making default-initialized vector.
Definition: fvector.hh:112
const value_type & const_reference
The type used for const references to the vector entry.
Definition: fvector.hh:109
Base::size_type size_type
Definition: fvector.hh:102
constexpr static int dimension
The size of this vector.
Definition: fvector.hh:100
FieldVector(const FieldVector< T, N > &)=delete
FieldVector(const K &t)
Constructor making vector with identical coordinates.
Definition: fvector.hh:117
FieldVector(std::initializer_list< K > const &l)
Construct from a std::initializer_list.
Definition: fvector.hh:132
FieldVector(const FieldVector< K1, SIZE > &x)
Constructor making vector with identical coordinates.
Definition: fvector.hh:175
FieldVector(const DenseVector< C > &x, [[maybe_unused]] typename std::enable_if< IsFieldVectorSizeCorrect< C, SIZE >::value >::type *dummy=0)
Copy constructor from a second vector of possibly different type.
Definition: fvector.hh:165
static constexpr size_type size()
Definition: fvector.hh:186
const K & operator[](size_type i) const
Definition: fvector.hh:192
value_type & reference
The type used for references to the vector entry.
Definition: fvector.hh:106
K * data() noexcept
return pointer to underlying array
Definition: fvector.hh:198
Base::value_type value_type
Definition: fvector.hh:103
K & operator[](size_type i)
Definition: fvector.hh:188
FieldVector(const FieldVector &)=default
Copy constructor.
FieldVector & operator=(const FieldVector< T, N > &)=delete
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
Iterator begin()
begin iterator
Definition: densevector.hh:347
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
Definition: ftraits.hh:26
T field_type
export the type representing the field
Definition: ftraits.hh:28
T real_type
export the type representing the real type of the field
Definition: ftraits.hh:30
std::array< K, SIZE > container_type
Definition: fvector.hh:44
container_type::size_type size_type
Definition: fvector.hh:46
FieldVector< K, SIZE > derived_type
Definition: fvector.hh:43
FieldTraits< K >::real_type real_type
Definition: fvector.hh:53
FieldTraits< K >::field_type field_type
Definition: fvector.hh:52
TMP to check the size of a DenseVectors statically, if possible.
Definition: fvector.hh:66
constexpr static bool value
True if C is not of type FieldVector or its dimension is not equal SIZE.
Definition: fvector.hh:71
Tag to make sure the functions in this namespace can be found by ADL.
Definition: math.hh:230
Definition: matvectraits.hh:31
Helper class for tagging priorities.
Definition: typeutilities.hh:73