Dune Core Modules (unstable)

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 © 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  {
43  typedef FieldVector<K,SIZE> derived_type;
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  {
52  typedef typename FieldTraits<K>::field_type field_type;
53  typedef typename FieldTraits<K>::real_type real_type;
54  };
55 
64  template<typename C, int SIZE>
66  {
71  constexpr static bool value = true;
72  };
73 
74  template<typename T, int SIZE>
75  struct IsFieldVectorSizeCorrect<FieldVector<T,SIZE>,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 
106  typedef value_type& reference;
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 
123  FieldVector (const FieldVector&) = default;
124 
126  constexpr FieldVector (std::initializer_list<K> const &l)
127  : _data{}
128  {
129  assert(l.size() == dimension);// Actually, this is not needed any more!
130  for(std::size_t i=0; i<std::min(static_cast<std::size_t>(dimension), l.size()); ++i)
131  _data[i] = std::data(l)[i];
132  }
133 
135  FieldVector& operator= (const FieldVector&) = default;
136 
137  template <typename T>
138  FieldVector& operator= (const FieldVector<T, SIZE>& x)
139  {
140  std::copy_n(x.begin(), SIZE, _data.begin());
141  return *this;
142  }
143 
144  template<typename T, int N>
145  FieldVector& operator=(const FieldVector<T, N>&) = delete;
146 
158  template<class C>
160  [[maybe_unused]] typename std::enable_if<IsFieldVectorSizeCorrect<C,SIZE>::value>::type* dummy=0)
161  {
162  // do a run-time size check, for the case that x is not a FieldVector
163  assert(x.size() == SIZE); // Actually this is not needed any more!
164  std::copy_n(x.begin(), std::min(static_cast<std::size_t>(SIZE),x.size()), _data.begin());
165  }
166 
168  template<class K1>
169  explicit FieldVector (const FieldVector<K1,SIZE> & x)
170  {
171  std::copy_n(x.begin(), SIZE, _data.begin());
172  }
173 
174  template<typename T, int N>
175  explicit FieldVector(const FieldVector<T, N>&) = delete;
176 
177  using Base::operator=;
178 
179  // make this thing a vector
180  static constexpr size_type size () { return SIZE; }
181 
182  K & operator[](size_type i) {
183  DUNE_ASSERT_BOUNDS(i < SIZE);
184  return _data[i];
185  }
186  const K & operator[](size_type i) const {
187  DUNE_ASSERT_BOUNDS(i < SIZE);
188  return _data[i];
189  }
190 
192  K* data() noexcept
193  {
194  return _data.data();
195  }
196 
198  const K* data() const noexcept
199  {
200  return _data.data();
201  }
202 
204  template <class Scalar,
205  std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
206  friend auto operator* ( const FieldVector& vector, Scalar scalar)
207  {
209 
210  for (size_type i = 0; i < vector.size(); ++i)
211  result[i] = vector[i] * scalar;
212 
213  return result;
214  }
215 
217  template <class Scalar,
218  std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
219  friend auto operator* ( Scalar scalar, const FieldVector& vector)
220  {
222 
223  for (size_type i = 0; i < vector.size(); ++i)
224  result[i] = scalar * vector[i];
225 
226  return result;
227  }
228 
230  template <class Scalar,
231  std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
232  friend auto operator/ ( const FieldVector& vector, Scalar scalar)
233  {
235 
236  for (size_type i = 0; i < vector.size(); ++i)
237  result[i] = vector[i] / scalar;
238 
239  return result;
240  }
241 
242  };
243 
255  template<class K, int SIZE>
256  inline std::istream &operator>> ( std::istream &in,
258  {
260  for( typename FieldVector<K, SIZE>::size_type i = 0; i < SIZE; ++i )
261  in >> w[ i ];
262  if(in)
263  v = w;
264  return in;
265  }
266 
267 #ifndef DOXYGEN
268  template< class K >
269  struct DenseMatVecTraits< FieldVector<K,1> >
270  {
271  typedef FieldVector<K,1> derived_type;
272  typedef K container_type;
273  typedef K value_type;
274  typedef size_t size_type;
275  };
276 
279  template<class K>
280  class FieldVector<K, 1> :
281  public DenseVector< FieldVector<K,1> >
282  {
283  K _data;
284  typedef DenseVector< FieldVector<K,1> > Base;
285  public:
287  constexpr static int dimension = 1;
288 
289  typedef typename Base::size_type size_type;
290 
292  typedef K& reference;
293 
295  typedef const K& const_reference;
296 
297  //===== construction
298 
300  constexpr FieldVector ()
301  : _data()
302  {}
303 
305  template<typename T,
306  typename EnableIf = typename std::enable_if<
307  std::is_convertible<T, K>::value &&
308  ! std::is_base_of<DenseVector<typename FieldTraits<T>::field_type>, K
309  >::value
310  >::type
311  >
312  FieldVector (const T& k) : _data(k) {}
313 
315  template<class C,
316  std::enable_if_t<
317  std::is_assignable<K&, typename DenseVector<C>::value_type>::value, int> = 0>
318  FieldVector (const DenseVector<C> & x)
319  {
320  static_assert(((bool)IsFieldVectorSizeCorrect<C,1>::value), "FieldVectors do not match in dimension!");
321  assert(x.size() == 1);
322  _data = x[0];
323  }
324 
326  FieldVector(const FieldVector&) = default;
327 
329  FieldVector& operator=(const FieldVector&) = default;
330 
331  template <typename T>
332  FieldVector& operator= (const FieldVector<T, 1>& other)
333  {
334  _data = other[0];
335  return *this;
336  }
337 
338  template<typename T, int N>
339  FieldVector& operator=(const FieldVector<T, N>&) = delete;
340 
342  FieldVector (std::initializer_list<K> const &l)
343  {
344  assert(l.size() == 1);
345  _data = *l.begin();
346  }
347 
349  template<typename T,
350  typename EnableIf = typename std::enable_if<
351  std::is_assignable<K&, T>::value &&
352  ! std::is_base_of<DenseVector<typename FieldTraits<T>::field_type>, K
353  >::value
354  >::type
355  >
356  inline FieldVector& operator= (const T& k)
357  {
358  _data = k;
359  return *this;
360  }
361 
362  //===== forward methods to container
363  static constexpr size_type size () { return 1; }
364 
365  K & operator[]([[maybe_unused]] size_type i)
366  {
367  DUNE_ASSERT_BOUNDS(i == 0);
368  return _data;
369  }
370  const K & operator[]([[maybe_unused]] size_type i) const
371  {
372  DUNE_ASSERT_BOUNDS(i == 0);
373  return _data;
374  }
375 
377  K* data() noexcept
378  {
379  return &_data;
380  }
381 
383  const K* data() const noexcept
384  {
385  return &_data;
386  }
387 
388  //===== conversion operator
389 
391  operator K& () { return _data; }
392 
394  operator const K& () const { return _data; }
395  };
396 
397  /* ----- FV / FV ----- */
398  /* mostly not necessary as these operations are already covered via the cast operator */
399 
401  template<class K>
402  inline bool operator> (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
403  {
404  return a[0]>b[0];
405  }
406 
408  template<class K>
409  inline bool operator>= (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
410  {
411  return a[0]>=b[0];
412  }
413 
415  template<class K>
416  inline bool operator< (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
417  {
418  return a[0]<b[0];
419  }
420 
422  template<class K>
423  inline bool operator<= (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
424  {
425  return a[0]<=b[0];
426  }
427 
428  /* ----- FV / scalar ----- */
429 
431  template<class K>
432  inline FieldVector<K,1> operator+ (const FieldVector<K,1>& a, const K b)
433  {
434  return a[0]+b;
435  }
436 
438  template<class K>
439  inline FieldVector<K,1> operator- (const FieldVector<K,1>& a, const K b)
440  {
441  return a[0]-b;
442  }
443 
445  template<class K>
446  inline FieldVector<K,1> operator* (const FieldVector<K,1>& a, const K b)
447  {
448  return a[0]*b;
449  }
450 
452  template<class K>
453  inline FieldVector<K,1> operator/ (const FieldVector<K,1>& a, const K b)
454  {
455  return a[0]/b;
456  }
457 
459  template<class K>
460  inline bool operator> (const FieldVector<K,1>& a, const K b)
461  {
462  return a[0]>b;
463  }
464 
466  template<class K>
467  inline bool operator>= (const FieldVector<K,1>& a, const K b)
468  {
469  return a[0]>=b;
470  }
471 
473  template<class K>
474  inline bool operator< (const FieldVector<K,1>& a, const K b)
475  {
476  return a[0]<b;
477  }
478 
480  template<class K>
481  inline bool operator<= (const FieldVector<K,1>& a, const K b)
482  {
483  return a[0]<=b;
484  }
485 
487  template<class K>
488  inline bool operator== (const FieldVector<K,1>& a, const K b)
489  {
490  return a[0]==b;
491  }
492 
494  template<class K>
495  inline bool operator!= (const FieldVector<K,1>& a, const K b)
496  {
497  return a[0]!=b;
498  }
499 
500  /* ----- scalar / FV ------ */
501 
503  template<class K>
504  inline FieldVector<K,1> operator+ (const K a, const FieldVector<K,1>& b)
505  {
506  return a+b[0];
507  }
508 
510  template<class K>
511  inline FieldVector<K,1> operator- (const K a, const FieldVector<K,1>& b)
512  {
513  return a-b[0];
514  }
515 
517  template<class K>
518  inline FieldVector<K,1> operator* (const K a, const FieldVector<K,1>& b)
519  {
520  return a*b[0];
521  }
522 
524  template<class K>
525  inline FieldVector<K,1> operator/ (const K a, const FieldVector<K,1>& b)
526  {
527  return a/b[0];
528  }
529 
531  template<class K>
532  inline bool operator> (const K a, const FieldVector<K,1>& b)
533  {
534  return a>b[0];
535  }
536 
538  template<class K>
539  inline bool operator>= (const K a, const FieldVector<K,1>& b)
540  {
541  return a>=b[0];
542  }
543 
545  template<class K>
546  inline bool operator< (const K a, const FieldVector<K,1>& b)
547  {
548  return a<b[0];
549  }
550 
552  template<class K>
553  inline bool operator<= (const K a, const FieldVector<K,1>& b)
554  {
555  return a<=b[0];
556  }
557 
559  template<class K>
560  inline bool operator== (const K a, const FieldVector<K,1>& b)
561  {
562  return a==b[0];
563  }
564 
566  template<class K>
567  inline bool operator!= (const K a, const FieldVector<K,1>& b)
568  {
569  return a!=b[0];
570  }
571 #endif
572 
573  /* Overloads for common classification functions */
574  namespace MathOverloads {
575 
576  // ! Returns whether all entries are finite
577  template<class K, int SIZE>
578  auto isFinite(const FieldVector<K,SIZE> &b, PriorityTag<2>, ADLTag) {
579  bool out = true;
580  for(int i=0; i<SIZE; i++) {
581  out &= Dune::isFinite(b[i]);
582  }
583  return out;
584  }
585 
586  // ! Returns whether any entry is infinite
587  template<class K, int SIZE>
588  bool isInf(const FieldVector<K,SIZE> &b, PriorityTag<2>, ADLTag) {
589  bool out = false;
590  for(int i=0; i<SIZE; i++) {
591  out |= Dune::isInf(b[i]);
592  }
593  return out;
594  }
595 
596  // ! Returns whether any entry is NaN
597  template<class K, int SIZE, typename = std::enable_if_t<HasNaN<K>::value>>
598  bool isNaN(const FieldVector<K,SIZE> &b, PriorityTag<2>, ADLTag) {
599  bool out = false;
600  for(int i=0; i<SIZE; i++) {
601  out |= Dune::isNaN(b[i]);
602  }
603  return out;
604  }
605 
606  // ! Returns true if either b or c is NaN
607  template<class K, typename = std::enable_if_t<HasNaN<K>::value>>
608  bool isUnordered(const FieldVector<K,1> &b, const FieldVector<K,1> &c,
610  return Dune::isUnordered(b[0],c[0]);
611  }
612  } //MathOverloads
613 
616 } // end namespace
617 
618 #endif
Macro for wrapping boundary checks.
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
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:198
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
constexpr static int dimension
The size of this vector.
Definition: fvector.hh:100
FieldVector(const K &t)
Constructor making vector with identical coordinates.
Definition: fvector.hh:117
FieldVector(const FieldVector< K1, SIZE > &x)
Constructor making vector with identical coordinates.
Definition: fvector.hh:169
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:159
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:192
constexpr FieldVector(std::initializer_list< K > const &l)
Construct from a std::initializer_list.
Definition: fvector.hh:126
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:30
std::istream & operator>>(std::istream &in, DynamicVector< K, Allocator > &v)
Read a DynamicVector from an input stream.
Definition: dynvector.hh:189
constexpr auto min
Function object that returns the smaller of the given values.
Definition: hybridutilities.hh:506
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: interface.hh:235
Some useful basic math stuff.
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
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: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
Helper class for tagging priorities.
Definition: typeutilities.hh:73
Traits for type conversions and type information.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (Apr 21, 22:30, 2024)