dune-common  2.7.1
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 "unused.hh"
22 #include "boundschecking.hh"
23 
24 #include <dune/common/math.hh>
26 
27 namespace Dune {
28 
38  template< class K, int SIZE > class FieldVector;
39  template< class K, int SIZE >
40  struct DenseMatVecTraits< FieldVector<K,SIZE> >
41  {
43  typedef std::array<K,SIZE> container_type;
44  typedef K value_type;
45  typedef typename container_type::size_type size_type;
46  };
47 
48  template< class K, int SIZE >
49  struct FieldTraits< FieldVector<K,SIZE> >
50  {
53  };
54 
63  template<typename C, int SIZE>
65  {
66  enum {
71  value = true
72  };
73  };
74 
75  template<typename T, int SIZE>
77  {
78  enum {value = true};
79  };
80 
81  template<typename T, int SIZE, int SIZE1>
82  struct IsFieldVectorSizeCorrect<FieldVector<T,SIZE1>,SIZE>
83  {
84  enum {value = false};
85  };
86 
87 
93  template< class K, int SIZE >
94  class FieldVector :
95  public DenseVector< FieldVector<K,SIZE> >
96  {
97  std::array<K,SIZE> _data;
99  public:
101  enum {
103  dimension = SIZE
104  };
105 
106  typedef typename Base::size_type size_type;
107  typedef typename Base::value_type value_type;
108 
111 
113  typedef const value_type& const_reference;
114 
116  constexpr FieldVector()
117  : _data{{}}
118  {}
119 
121  explicit FieldVector (const K& t)
122  {
123  std::fill(_data.begin(),_data.end(),t);
124  }
125 
126 #if __GNUC__ == 5 && !defined(__clang__)
127  // `... = default;` causes an internal compiler error on GCC 5.4 (Ubuntu 16.04)
129  FieldVector(const FieldVector& x) : _data(x._data) {}
130 #else
132  FieldVector (const FieldVector&) = default;
133 #endif
134 
136  FieldVector (std::initializer_list<K> const &l)
137  {
138  assert(l.size() == dimension);// Actually, this is not needed any more!
139  std::copy_n(l.begin(), std::min(static_cast<std::size_t>(dimension),
140  l.size()),
141  _data.begin());
142  }
143 
145  FieldVector& operator= (const FieldVector&) = default;
146 
147  template <typename T>
148  FieldVector& operator= (const FieldVector<T, SIZE>& x)
149  {
150  std::copy_n(x.begin(), SIZE, _data.begin());
151  return *this;
152  }
153 
154  template<typename T, int N>
156 
168  template<class C>
169  FieldVector (const DenseVector<C> & x, typename std::enable_if<IsFieldVectorSizeCorrect<C,SIZE>::value>::type* dummy=0 )
170  {
171  DUNE_UNUSED_PARAMETER(dummy);
172  // do a run-time size check, for the case that x is not a FieldVector
173  assert(x.size() == SIZE); // Actually this is not needed any more!
174  std::copy_n(x.begin(), std::min(static_cast<std::size_t>(SIZE),x.size()), _data.begin());
175  }
176 
178  template<class K1>
179  explicit FieldVector (const FieldVector<K1,SIZE> & x)
180  {
181  std::copy_n(x.begin(), SIZE, _data.begin());
182  }
183 
184  template<typename T, int N>
185  explicit FieldVector(const FieldVector<T, N>&) = delete;
186 
187  using Base::operator=;
188 
189  // make this thing a vector
190  static constexpr size_type size () { return SIZE; }
191 
193  DUNE_ASSERT_BOUNDS(i < SIZE);
194  return _data[i];
195  }
196  const K & operator[](size_type i) const {
197  DUNE_ASSERT_BOUNDS(i < SIZE);
198  return _data[i];
199  }
200 
202  K* data() noexcept
203  {
204  return _data.data();
205  }
206 
208  const K* data() const noexcept
209  {
210  return _data.data();
211  }
212 
214  template <class Scalar,
215  std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
216  friend auto operator* ( const FieldVector& vector, Scalar scalar)
217  {
219 
220  for (size_type i = 0; i < vector.size(); ++i)
221  result[i] = vector[i] * scalar;
222 
223  return result;
224  }
225 
227  template <class Scalar,
228  std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
229  friend auto operator* ( Scalar scalar, const FieldVector& vector)
230  {
232 
233  for (size_type i = 0; i < vector.size(); ++i)
234  result[i] = scalar * vector[i];
235 
236  return result;
237  }
238 
240  template <class Scalar,
241  std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
242  friend auto operator/ ( const FieldVector& vector, Scalar scalar)
243  {
245 
246  for (size_type i = 0; i < vector.size(); ++i)
247  result[i] = vector[i] / scalar;
248 
249  return result;
250  }
251 
252  };
253 
265  template<class K, int SIZE>
266  inline std::istream &operator>> ( std::istream &in,
268  {
270  for( typename FieldVector<K, SIZE>::size_type i = 0; i < SIZE; ++i )
271  in >> w[ i ];
272  if(in)
273  v = w;
274  return in;
275  }
276 
277 #ifndef DOXYGEN
278  template< class K >
279  struct DenseMatVecTraits< FieldVector<K,1> >
280  {
281  typedef FieldVector<K,1> derived_type;
282  typedef K container_type;
283  typedef K value_type;
284  typedef size_t size_type;
285  };
286 
289  template<class K>
290  class FieldVector<K, 1> :
291  public DenseVector< FieldVector<K,1> >
292  {
293  K _data;
294  typedef DenseVector< FieldVector<K,1> > Base;
295  public:
297  enum {
299  dimension = 1
300  };
301 
302  typedef typename Base::size_type size_type;
303 
305  typedef K& reference;
306 
308  typedef const K& const_reference;
309 
310  //===== construction
311 
313  constexpr FieldVector ()
314  : _data()
315  {}
316 
318  template<typename T,
319  typename EnableIf = typename std::enable_if<
320  std::is_convertible<T, K>::value &&
321  ! std::is_base_of<DenseVector<typename FieldTraits<T>::field_type>, K
322  >::value
323  >::type
324  >
325  FieldVector (const T& k) : _data(k) {}
326 
328  template<class C,
329  std::enable_if_t<
330  std::is_assignable<K&, typename DenseVector<C>::value_type>::value, int> = 0>
331  FieldVector (const DenseVector<C> & x)
332  {
333  static_assert(((bool)IsFieldVectorSizeCorrect<C,1>::value), "FieldVectors do not match in dimension!");
334  assert(x.size() == 1);
335  _data = x[0];
336  }
337 
339  FieldVector(const FieldVector&) = default;
340 
342  FieldVector& operator=(const FieldVector&) = default;
343 
344  template <typename T>
345  FieldVector& operator= (const FieldVector<T, 1>& other)
346  {
347  _data = other[0];
348  return *this;
349  }
350 
351  template<typename T, int N>
352  FieldVector& operator=(const FieldVector<T, N>&) = delete;
353 
355  FieldVector (std::initializer_list<K> const &l)
356  {
357  assert(l.size() == 1);
358  _data = *l.begin();
359  }
360 
362  template<typename T,
363  typename EnableIf = typename std::enable_if<
364  std::is_assignable<K&, T>::value &&
365  ! std::is_base_of<DenseVector<typename FieldTraits<T>::field_type>, K
366  >::value
367  >::type
368  >
369  inline FieldVector& operator= (const T& k)
370  {
371  _data = k;
372  return *this;
373  }
374 
375  //===== forward methods to container
376  static constexpr size_type size () { return 1; }
377 
378  K & operator[](size_type i)
379  {
381  DUNE_ASSERT_BOUNDS(i == 0);
382  return _data;
383  }
384  const K & operator[](size_type i) const
385  {
387  DUNE_ASSERT_BOUNDS(i == 0);
388  return _data;
389  }
390 
392  K* data() noexcept
393  {
394  return &_data;
395  }
396 
398  const K* data() const noexcept
399  {
400  return &_data;
401  }
402 
403  //===== conversion operator
404 
406  operator K& () { return _data; }
407 
409  operator const K& () const { return _data; }
410  };
411 
412  /* ----- FV / FV ----- */
413  /* mostly not necessary as these operations are already covered via the cast operator */
414 
416  template<class K>
417  inline bool operator> (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
418  {
419  return a[0]>b[0];
420  }
421 
423  template<class K>
424  inline bool operator>= (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
425  {
426  return a[0]>=b[0];
427  }
428 
430  template<class K>
431  inline bool operator< (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
432  {
433  return a[0]<b[0];
434  }
435 
437  template<class K>
438  inline bool operator<= (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
439  {
440  return a[0]<=b[0];
441  }
442 
443  /* ----- FV / scalar ----- */
444 
446  template<class K>
447  inline FieldVector<K,1> operator+ (const FieldVector<K,1>& a, const K b)
448  {
449  return a[0]+b;
450  }
451 
453  template<class K>
454  inline FieldVector<K,1> operator- (const FieldVector<K,1>& a, const K b)
455  {
456  return a[0]-b;
457  }
458 
460  template<class K>
461  inline FieldVector<K,1> operator* (const FieldVector<K,1>& a, const K b)
462  {
463  return a[0]*b;
464  }
465 
467  template<class K>
468  inline FieldVector<K,1> operator/ (const FieldVector<K,1>& a, const K b)
469  {
470  return a[0]/b;
471  }
472 
474  template<class K>
475  inline bool operator> (const FieldVector<K,1>& a, const K b)
476  {
477  return a[0]>b;
478  }
479 
481  template<class K>
482  inline bool operator>= (const FieldVector<K,1>& a, const K b)
483  {
484  return a[0]>=b;
485  }
486 
488  template<class K>
489  inline bool operator< (const FieldVector<K,1>& a, const K b)
490  {
491  return a[0]<b;
492  }
493 
495  template<class K>
496  inline bool operator<= (const FieldVector<K,1>& a, const K b)
497  {
498  return a[0]<=b;
499  }
500 
502  template<class K>
503  inline bool operator== (const FieldVector<K,1>& a, const K b)
504  {
505  return a[0]==b;
506  }
507 
509  template<class K>
510  inline bool operator!= (const FieldVector<K,1>& a, const K b)
511  {
512  return a[0]!=b;
513  }
514 
515  /* ----- scalar / FV ------ */
516 
518  template<class K>
519  inline FieldVector<K,1> operator+ (const K a, const FieldVector<K,1>& b)
520  {
521  return a+b[0];
522  }
523 
525  template<class K>
526  inline FieldVector<K,1> operator- (const K a, const FieldVector<K,1>& b)
527  {
528  return a-b[0];
529  }
530 
532  template<class K>
533  inline FieldVector<K,1> operator* (const K a, const FieldVector<K,1>& b)
534  {
535  return a*b[0];
536  }
537 
539  template<class K>
540  inline FieldVector<K,1> operator/ (const K a, const FieldVector<K,1>& b)
541  {
542  return a/b[0];
543  }
544 
546  template<class K>
547  inline bool operator> (const K a, const FieldVector<K,1>& b)
548  {
549  return a>b[0];
550  }
551 
553  template<class K>
554  inline bool operator>= (const K a, const FieldVector<K,1>& b)
555  {
556  return a>=b[0];
557  }
558 
560  template<class K>
561  inline bool operator< (const K a, const FieldVector<K,1>& b)
562  {
563  return a<b[0];
564  }
565 
567  template<class K>
568  inline bool operator<= (const K a, const FieldVector<K,1>& b)
569  {
570  return a<=b[0];
571  }
572 
574  template<class K>
575  inline bool operator== (const K a, const FieldVector<K,1>& b)
576  {
577  return a==b[0];
578  }
579 
581  template<class K>
582  inline bool operator!= (const K a, const FieldVector<K,1>& b)
583  {
584  return a!=b[0];
585  }
586 #endif
587 
588  /* Overloads for common classification functions */
589  namespace MathOverloads {
590 
591  // ! Returns whether all entries are finite
592  template<class K, int SIZE>
594  bool out = true;
595  for(int i=0; i<SIZE; i++) {
596  out &= Dune::isFinite(b[i]);
597  }
598  return out;
599  }
600 
601  // ! Returns whether any entry is infinite
602  template<class K, int SIZE>
604  bool out = false;
605  for(int i=0; i<SIZE; i++) {
606  out |= Dune::isInf(b[i]);
607  }
608  return out;
609  }
610 
611  // ! Returns whether any entry is NaN
612  template<class K, int SIZE, typename = std::enable_if_t<HasNaN<K>::value>>
614  bool out = false;
615  for(int i=0; i<SIZE; i++) {
616  out |= Dune::isNaN(b[i]);
617  }
618  return out;
619  }
620 
621  // ! Returns true if either b or c is NaN
622  template<class K, typename = std::enable_if_t<HasNaN<K>::value>>
625  return Dune::isUnordered(b[0],c[0]);
626  }
627  } //MathOverloads
628 
631 } // end namespace
632 
633 #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.
Definition of the DUNE_UNUSED macro for the case that config.h is not available.
#define DUNE_ASSERT_BOUNDS(cond)
If DUNE_CHECK_BOUNDS is defined: check if condition cond holds; otherwise, do nothing.
Definition: boundschecking.hh:28
#define DUNE_UNUSED_PARAMETER(parm)
A macro to mark intentionally unused function parameters with.
Definition: unused.hh:25
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 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 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:14
constexpr bool operator!=(const DebugAllocator< T > &, const DebugAllocator< T > &)
check whether allocators are not equivalent
Definition: debugallocator.hh:318
constexpr bool operator==(const DebugAllocator< T > &, const DebugAllocator< T > &)
check whether allocators are equivalent
Definition: debugallocator.hh:310
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:613
bool isInf(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Definition: fvector.hh:603
auto isFinite(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Definition: fvector.hh:593
bool isUnordered(const FieldVector< K, 1 > &b, const FieldVector< K, 1 > &c, PriorityTag< 2 >, ADLTag)
Definition: fvector.hh:623
vector space out of a tensor product of fields.
Definition: fvector.hh:96
const K * data() const noexcept
return pointer to underlying array
Definition: fvector.hh:208
constexpr FieldVector()
Constructor making default-initialized vector.
Definition: fvector.hh:116
const value_type & const_reference
The type used for const references to the vector entry.
Definition: fvector.hh:113
Base::size_type size_type
Definition: fvector.hh:106
FieldVector(const DenseVector< C > &x, typename std::enable_if< IsFieldVectorSizeCorrect< C, SIZE >::value >::type *dummy=0)
Copy constructor from a second vector of possibly different type.
Definition: fvector.hh:169
FieldVector(const FieldVector< T, N > &)=delete
FieldVector(const K &t)
Constructor making vector with identical coordinates.
Definition: fvector.hh:121
FieldVector(std::initializer_list< K > const &l)
Construct from a std::initializer_list.
Definition: fvector.hh:136
@ dimension
The size of this vector.
Definition: fvector.hh:103
FieldVector(const FieldVector< K1, SIZE > &x)
Constructor making vector with identical coordinates.
Definition: fvector.hh:179
static constexpr size_type size()
Definition: fvector.hh:190
const K & operator[](size_type i) const
Definition: fvector.hh:196
value_type & reference
The type used for references to the vector entry.
Definition: fvector.hh:110
K * data() noexcept
return pointer to underlying array
Definition: fvector.hh:202
Base::value_type value_type
Definition: fvector.hh:107
K & operator[](size_type i)
Definition: fvector.hh:192
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:43
container_type::size_type size_type
Definition: fvector.hh:45
FieldVector< K, SIZE > derived_type
Definition: fvector.hh:42
FieldTraits< K >::real_type real_type
Definition: fvector.hh:52
FieldTraits< K >::field_type field_type
Definition: fvector.hh:51
TMP to check the size of a DenseVectors statically, if possible.
Definition: fvector.hh:65
@ value
Definition: fvector.hh:71
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