dune-common  2.8.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 #ifndef DUNE_FVECTOR_HH
4 #define DUNE_FVECTOR_HH
5 
6 #include <array>
7 #include <cmath>
8 #include <cstddef>
9 #include <cstdlib>
10 #include <complex>
11 #include <cstring>
12 #include <utility>
13 #include <initializer_list>
14 #include <algorithm>
15 
16 #include "typetraits.hh"
17 #include "exceptions.hh"
18 
19 #include "ftraits.hh"
20 #include "densevector.hh"
21 #include "boundschecking.hh"
22 
23 #include <dune/common/math.hh>
25 
26 namespace Dune {
27 
37  template< class K, int SIZE > class FieldVector;
38  template< class K, int SIZE >
39  struct DenseMatVecTraits< FieldVector<K,SIZE> >
40  {
42  typedef std::array<K,SIZE> container_type;
43  typedef K value_type;
44  typedef typename container_type::size_type size_type;
45  };
46 
47  template< class K, int SIZE >
48  struct FieldTraits< FieldVector<K,SIZE> >
49  {
52  };
53 
62  template<typename C, int SIZE>
64  {
65  enum {
70  value = true
71  };
72  };
73 
74  template<typename T, int SIZE>
76  {
77  enum {value = true};
78  };
79 
80  template<typename T, int SIZE, int SIZE1>
81  struct IsFieldVectorSizeCorrect<FieldVector<T,SIZE1>,SIZE>
82  {
83  enum {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  enum {
102  dimension = SIZE
103  };
104 
105  typedef typename Base::size_type size_type;
106  typedef typename Base::value_type value_type;
107 
110 
112  typedef const value_type& const_reference;
113 
115  constexpr FieldVector()
116  : _data{{}}
117  {}
118 
120  explicit FieldVector (const K& t)
121  {
122  std::fill(_data.begin(),_data.end(),t);
123  }
124 
125 #if __GNUC__ == 5 && !defined(__clang__)
126  // `... = default;` causes an internal compiler error on GCC 5.4 (Ubuntu 16.04)
128  FieldVector(const FieldVector& x) : _data(x._data) {}
129 #else
131  FieldVector (const FieldVector&) = default;
132 #endif
133 
135  FieldVector (std::initializer_list<K> const &l)
136  {
137  assert(l.size() == dimension);// Actually, this is not needed any more!
138  std::copy_n(l.begin(), std::min(static_cast<std::size_t>(dimension),
139  l.size()),
140  _data.begin());
141  }
142 
144  FieldVector& operator= (const FieldVector&) = default;
145 
146  template <typename T>
147  FieldVector& operator= (const FieldVector<T, SIZE>& x)
148  {
149  std::copy_n(x.begin(), SIZE, _data.begin());
150  return *this;
151  }
152 
153  template<typename T, int N>
155 
167  template<class C>
169  [[maybe_unused]] typename std::enable_if<IsFieldVectorSizeCorrect<C,SIZE>::value>::type* dummy=0)
170  {
171  // do a run-time size check, for the case that x is not a FieldVector
172  assert(x.size() == SIZE); // Actually this is not needed any more!
173  std::copy_n(x.begin(), std::min(static_cast<std::size_t>(SIZE),x.size()), _data.begin());
174  }
175 
177  template<class K1>
178  explicit FieldVector (const FieldVector<K1,SIZE> & x)
179  {
180  std::copy_n(x.begin(), SIZE, _data.begin());
181  }
182 
183  template<typename T, int N>
184  explicit FieldVector(const FieldVector<T, N>&) = delete;
185 
186  using Base::operator=;
187 
188  // make this thing a vector
189  static constexpr size_type size () { return SIZE; }
190 
192  DUNE_ASSERT_BOUNDS(i < SIZE);
193  return _data[i];
194  }
195  const K & operator[](size_type i) const {
196  DUNE_ASSERT_BOUNDS(i < SIZE);
197  return _data[i];
198  }
199 
201  K* data() noexcept
202  {
203  return _data.data();
204  }
205 
207  const K* data() const noexcept
208  {
209  return _data.data();
210  }
211 
213  template <class Scalar,
214  std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
215  friend auto operator* ( const FieldVector& vector, Scalar scalar)
216  {
218 
219  for (size_type i = 0; i < vector.size(); ++i)
220  result[i] = vector[i] * scalar;
221 
222  return result;
223  }
224 
226  template <class Scalar,
227  std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
228  friend auto operator* ( Scalar scalar, const FieldVector& vector)
229  {
231 
232  for (size_type i = 0; i < vector.size(); ++i)
233  result[i] = scalar * vector[i];
234 
235  return result;
236  }
237 
239  template <class Scalar,
240  std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
241  friend auto operator/ ( const FieldVector& vector, Scalar scalar)
242  {
244 
245  for (size_type i = 0; i < vector.size(); ++i)
246  result[i] = vector[i] / scalar;
247 
248  return result;
249  }
250 
251  };
252 
264  template<class K, int SIZE>
265  inline std::istream &operator>> ( std::istream &in,
267  {
269  for( typename FieldVector<K, SIZE>::size_type i = 0; i < SIZE; ++i )
270  in >> w[ i ];
271  if(in)
272  v = w;
273  return in;
274  }
275 
276 #ifndef DOXYGEN
277  template< class K >
278  struct DenseMatVecTraits< FieldVector<K,1> >
279  {
280  typedef FieldVector<K,1> derived_type;
281  typedef K container_type;
282  typedef K value_type;
283  typedef size_t size_type;
284  };
285 
288  template<class K>
289  class FieldVector<K, 1> :
290  public DenseVector< FieldVector<K,1> >
291  {
292  K _data;
293  typedef DenseVector< FieldVector<K,1> > Base;
294  public:
296  enum {
298  dimension = 1
299  };
300 
301  typedef typename Base::size_type size_type;
302 
304  typedef K& reference;
305 
307  typedef const K& const_reference;
308 
309  //===== construction
310 
312  constexpr FieldVector ()
313  : _data()
314  {}
315 
317  template<typename T,
318  typename EnableIf = typename std::enable_if<
319  std::is_convertible<T, K>::value &&
320  ! std::is_base_of<DenseVector<typename FieldTraits<T>::field_type>, K
321  >::value
322  >::type
323  >
324  FieldVector (const T& k) : _data(k) {}
325 
327  template<class C,
328  std::enable_if_t<
329  std::is_assignable<K&, typename DenseVector<C>::value_type>::value, int> = 0>
330  FieldVector (const DenseVector<C> & x)
331  {
332  static_assert(((bool)IsFieldVectorSizeCorrect<C,1>::value), "FieldVectors do not match in dimension!");
333  assert(x.size() == 1);
334  _data = x[0];
335  }
336 
338  FieldVector(const FieldVector&) = default;
339 
341  FieldVector& operator=(const FieldVector&) = default;
342 
343  template <typename T>
344  FieldVector& operator= (const FieldVector<T, 1>& other)
345  {
346  _data = other[0];
347  return *this;
348  }
349 
350  template<typename T, int N>
351  FieldVector& operator=(const FieldVector<T, N>&) = delete;
352 
354  FieldVector (std::initializer_list<K> const &l)
355  {
356  assert(l.size() == 1);
357  _data = *l.begin();
358  }
359 
361  template<typename T,
362  typename EnableIf = typename std::enable_if<
363  std::is_assignable<K&, T>::value &&
364  ! std::is_base_of<DenseVector<typename FieldTraits<T>::field_type>, K
365  >::value
366  >::type
367  >
368  inline FieldVector& operator= (const T& k)
369  {
370  _data = k;
371  return *this;
372  }
373 
374  //===== forward methods to container
375  static constexpr size_type size () { return 1; }
376 
377  K & operator[]([[maybe_unused]] size_type i)
378  {
379  DUNE_ASSERT_BOUNDS(i == 0);
380  return _data;
381  }
382  const K & operator[]([[maybe_unused]] size_type i) const
383  {
384  DUNE_ASSERT_BOUNDS(i == 0);
385  return _data;
386  }
387 
389  K* data() noexcept
390  {
391  return &_data;
392  }
393 
395  const K* data() const noexcept
396  {
397  return &_data;
398  }
399 
400  //===== conversion operator
401 
403  operator K& () { return _data; }
404 
406  operator const K& () const { return _data; }
407  };
408 
409  /* ----- FV / FV ----- */
410  /* mostly not necessary as these operations are already covered via the cast operator */
411 
413  template<class K>
414  inline bool operator> (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
415  {
416  return a[0]>b[0];
417  }
418 
420  template<class K>
421  inline bool operator>= (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
422  {
423  return a[0]>=b[0];
424  }
425 
427  template<class K>
428  inline bool operator< (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
429  {
430  return a[0]<b[0];
431  }
432 
434  template<class K>
435  inline bool operator<= (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
436  {
437  return a[0]<=b[0];
438  }
439 
440  /* ----- FV / scalar ----- */
441 
443  template<class K>
444  inline FieldVector<K,1> operator+ (const FieldVector<K,1>& a, const K b)
445  {
446  return a[0]+b;
447  }
448 
450  template<class K>
451  inline FieldVector<K,1> operator- (const FieldVector<K,1>& a, const K b)
452  {
453  return a[0]-b;
454  }
455 
457  template<class K>
458  inline FieldVector<K,1> operator* (const FieldVector<K,1>& a, const K b)
459  {
460  return a[0]*b;
461  }
462 
464  template<class K>
465  inline FieldVector<K,1> operator/ (const FieldVector<K,1>& a, const K b)
466  {
467  return a[0]/b;
468  }
469 
471  template<class K>
472  inline bool operator> (const FieldVector<K,1>& a, const K b)
473  {
474  return a[0]>b;
475  }
476 
478  template<class K>
479  inline bool operator>= (const FieldVector<K,1>& a, const K b)
480  {
481  return a[0]>=b;
482  }
483 
485  template<class K>
486  inline bool operator< (const FieldVector<K,1>& a, const K b)
487  {
488  return a[0]<b;
489  }
490 
492  template<class K>
493  inline bool operator<= (const FieldVector<K,1>& a, const K b)
494  {
495  return a[0]<=b;
496  }
497 
499  template<class K>
500  inline bool operator== (const FieldVector<K,1>& a, const K b)
501  {
502  return a[0]==b;
503  }
504 
506  template<class K>
507  inline bool operator!= (const FieldVector<K,1>& a, const K b)
508  {
509  return a[0]!=b;
510  }
511 
512  /* ----- scalar / FV ------ */
513 
515  template<class K>
516  inline FieldVector<K,1> operator+ (const K a, const FieldVector<K,1>& b)
517  {
518  return a+b[0];
519  }
520 
522  template<class K>
523  inline FieldVector<K,1> operator- (const K a, const FieldVector<K,1>& b)
524  {
525  return a-b[0];
526  }
527 
529  template<class K>
530  inline FieldVector<K,1> operator* (const K a, const FieldVector<K,1>& b)
531  {
532  return a*b[0];
533  }
534 
536  template<class K>
537  inline FieldVector<K,1> operator/ (const K a, const FieldVector<K,1>& b)
538  {
539  return a/b[0];
540  }
541 
543  template<class K>
544  inline bool operator> (const K a, const FieldVector<K,1>& b)
545  {
546  return a>b[0];
547  }
548 
550  template<class K>
551  inline bool operator>= (const K a, const FieldVector<K,1>& b)
552  {
553  return a>=b[0];
554  }
555 
557  template<class K>
558  inline bool operator< (const K a, const FieldVector<K,1>& b)
559  {
560  return a<b[0];
561  }
562 
564  template<class K>
565  inline bool operator<= (const K a, const FieldVector<K,1>& b)
566  {
567  return a<=b[0];
568  }
569 
571  template<class K>
572  inline bool operator== (const K a, const FieldVector<K,1>& b)
573  {
574  return a==b[0];
575  }
576 
578  template<class K>
579  inline bool operator!= (const K a, const FieldVector<K,1>& b)
580  {
581  return a!=b[0];
582  }
583 #endif
584 
585  /* Overloads for common classification functions */
586  namespace MathOverloads {
587 
588  // ! Returns whether all entries are finite
589  template<class K, int SIZE>
591  bool out = true;
592  for(int i=0; i<SIZE; i++) {
593  out &= Dune::isFinite(b[i]);
594  }
595  return out;
596  }
597 
598  // ! Returns whether any entry is infinite
599  template<class K, int SIZE>
601  bool out = false;
602  for(int i=0; i<SIZE; i++) {
603  out |= Dune::isInf(b[i]);
604  }
605  return out;
606  }
607 
608  // ! Returns whether any entry is NaN
609  template<class K, int SIZE, typename = std::enable_if_t<HasNaN<K>::value>>
611  bool out = false;
612  for(int i=0; i<SIZE; i++) {
613  out |= Dune::isNaN(b[i]);
614  }
615  return out;
616  }
617 
618  // ! Returns true if either b or c is NaN
619  template<class K, typename = std::enable_if_t<HasNaN<K>::value>>
622  return Dune::isUnordered(b[0],c[0]);
623  }
624  } //MathOverloads
625 
628 } // end namespace
629 
630 #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:28
bigunsignedint< k > operator+(const bigunsignedint< k > &x, std::uintmax_t y)
Definition: bigunsignedint.hh:530
bigunsignedint< k > operator*(const bigunsignedint< k > &x, std::uintmax_t y)
Definition: bigunsignedint.hh:544
bigunsignedint< k > operator-(const bigunsignedint< k > &x, std::uintmax_t y)
Definition: bigunsignedint.hh:537
bigunsignedint< k > operator/(const bigunsignedint< k > &x, std::uintmax_t y)
Definition: bigunsignedint.hh:551
std::istream & operator>>(std::istream &in, DynamicVector< K, Allocator > &v)
Read a DynamicVector from an input stream.
Definition: dynvector.hh:187
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:257
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:681
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:635
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:235
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:703
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:658
typename Overloads::ScalarType< std::decay_t< V > >::type Scalar
Element type of some SIMD type.
Definition: simd/interface.hh:233
Dune namespace.
Definition: alignedallocator.hh:11
auto min(const AlignedNumber< T, align > &a, const AlignedNumber< T, align > &b)
Definition: debugalign.hh:434
bool isNaN(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Definition: fvector.hh:610
bool isInf(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Definition: fvector.hh:600
auto isFinite(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Definition: fvector.hh:590
bool isUnordered(const FieldVector< K, 1 > &b, const FieldVector< K, 1 > &c, PriorityTag< 2 >, ADLTag)
Definition: fvector.hh:620
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:207
constexpr FieldVector()
Constructor making default-initialized vector.
Definition: fvector.hh:115
const value_type & const_reference
The type used for const references to the vector entry.
Definition: fvector.hh:112
Base::size_type size_type
Definition: fvector.hh:105
FieldVector(const FieldVector< T, N > &)=delete
FieldVector(const K &t)
Constructor making vector with identical coordinates.
Definition: fvector.hh:120
FieldVector(std::initializer_list< K > const &l)
Construct from a std::initializer_list.
Definition: fvector.hh:135
@ dimension
The size of this vector.
Definition: fvector.hh:102
FieldVector(const FieldVector< K1, SIZE > &x)
Constructor making vector with identical coordinates.
Definition: fvector.hh:178
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:168
static constexpr size_type size()
Definition: fvector.hh:189
const K & operator[](size_type i) const
Definition: fvector.hh:195
value_type & reference
The type used for references to the vector entry.
Definition: fvector.hh:109
K * data() noexcept
return pointer to underlying array
Definition: fvector.hh:201
Base::value_type value_type
Definition: fvector.hh:106
K & operator[](size_type i)
Definition: fvector.hh:191
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:227
Traits::value_type value_type
export the type representing the field
Definition: densevector.hh:248
Iterator begin()
begin iterator
Definition: densevector.hh:348
size_type size() const
size method
Definition: densevector.hh:337
Traits::size_type size_type
The type used for the index access and size operation.
Definition: densevector.hh:257
Definition: ftraits.hh:24
T field_type
export the type representing the field
Definition: ftraits.hh:26
T real_type
export the type representing the real type of the field
Definition: ftraits.hh:28
std::array< K, SIZE > container_type
Definition: fvector.hh:42
container_type::size_type size_type
Definition: fvector.hh:44
FieldVector< K, SIZE > derived_type
Definition: fvector.hh:41
FieldTraits< K >::real_type real_type
Definition: fvector.hh:51
FieldTraits< K >::field_type field_type
Definition: fvector.hh:50
TMP to check the size of a DenseVectors statically, if possible.
Definition: fvector.hh:64
@ value
Definition: fvector.hh:70
Tag to make sure the functions in this namespace can be found by ADL.
Definition: math.hh:227
Definition: matvectraits.hh:29
Helper class for tagging priorities.
Definition: typeutilities.hh:71