DUNE PDELab (2.8)

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  {
41  typedef FieldVector<K,SIZE> derived_type;
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  {
50  typedef typename FieldTraits<K>::field_type field_type;
51  typedef typename FieldTraits<K>::real_type real_type;
52  };
53 
62  template<typename C, int SIZE>
64  {
65  enum {
70  value = true
71  };
72  };
73 
74  template<typename T, int SIZE>
75  struct IsFieldVectorSizeCorrect<FieldVector<T,SIZE>,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 
109  typedef value_type& reference;
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>
154  FieldVector& operator=(const FieldVector<T, N>&) = delete;
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 
191  K & operator[](size_type i) {
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>
590  auto isFinite(const FieldVector<K,SIZE> &b, PriorityTag<2>, ADLTag) {
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>
600  bool isInf(const FieldVector<K,SIZE> &b, PriorityTag<2>, ADLTag) {
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>>
610  bool isNaN(const FieldVector<K,SIZE> &b, PriorityTag<2>, ADLTag) {
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>>
620  bool isUnordered(const FieldVector<K,1> &b, const FieldVector<K,1> &c,
622  return Dune::isUnordered(b[0],c[0]);
623  }
624  } //MathOverloads
625 
628 } // end namespace
629 
630 #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: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
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
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
FieldVector(const FieldVector &)=default
Copy constructor.
Implements the dense vector interface, with an exchangeable storage class.
PDELab-specific exceptions.
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
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:11
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:64
@ value
Definition: fvector.hh:70
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
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 10, 22:30, 2024)