Dune Core Modules (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  {
42  typedef FieldVector<K,SIZE> derived_type;
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  {
51  typedef typename FieldTraits<K>::field_type field_type;
52  typedef typename FieldTraits<K>::real_type real_type;
53  };
54 
63  template<typename C, int SIZE>
65  {
66  enum {
71  value = true
72  };
73  };
74 
75  template<typename T, int SIZE>
76  struct IsFieldVectorSizeCorrect<FieldVector<T,SIZE>,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 
110  typedef value_type& reference;
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>
155  FieldVector& operator=(const FieldVector<T, N>&) = delete;
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 
192  K & operator[](size_type i) {
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>
593  auto isFinite(const FieldVector<K,SIZE> &b, PriorityTag<2>, ADLTag) {
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>
603  bool isInf(const FieldVector<K,SIZE> &b, PriorityTag<2>, ADLTag) {
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>>
613  bool isNaN(const FieldVector<K,SIZE> &b, PriorityTag<2>, ADLTag) {
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>>
623  bool isUnordered(const FieldVector<K,1> &b, const FieldVector<K,1> &c,
625  return Dune::isUnordered(b[0],c[0]);
626  }
627  } //MathOverloads
628 
631 } // end namespace
632 
633 #endif
Macro for wrapping boundary checks.
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
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
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 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
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
FieldVector(const FieldVector &)=default
Copy constructor.
Implements the dense vector interface, with an exchangeable storage class.
Type traits to determine the type of reals (when working with complex numbers)
#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
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
auto min(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::min()
Definition: defaults.hh:87
typename Overloads::ScalarType< std::decay_t< V > >::type Scalar
Element type of some SIMD type.
Definition: interface.hh:233
Some useful basic math stuff.
Dune namespace.
Definition: alignedallocator.hh:14
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:65
@ value
Definition: fvector.hh:71
Tag to make sure the functions in this namespace can be found by ADL.
Definition: math.hh:227
Helper class for tagging priorities.
Definition: typeutilities.hh:71
Traits for type conversions and type information.
Definition of the DUNE_UNUSED macro for the case that config.h is not available.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 10, 22:30, 2024)