Dune Core Modules (2.9.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 // SPDX-FileCopyrightInfo: Copyright (C) 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 
122 #if __GNUC__ == 5 && !defined(__clang__)
123  // `... = default;` causes an internal compiler error on GCC 5.4 (Ubuntu 16.04)
125  FieldVector(const FieldVector& x) : _data(x._data) {}
126 #else
128  FieldVector (const FieldVector&) = default;
129 #endif
130 
132  FieldVector (std::initializer_list<K> const &l)
133  {
134  assert(l.size() == dimension);// Actually, this is not needed any more!
135  std::copy_n(l.begin(), std::min(static_cast<std::size_t>(dimension),
136  l.size()),
137  _data.begin());
138  }
139 
141  FieldVector& operator= (const FieldVector&) = default;
142 
143  template <typename T>
144  FieldVector& operator= (const FieldVector<T, SIZE>& x)
145  {
146  std::copy_n(x.begin(), SIZE, _data.begin());
147  return *this;
148  }
149 
150  template<typename T, int N>
151  FieldVector& operator=(const FieldVector<T, N>&) = delete;
152 
164  template<class C>
166  [[maybe_unused]] typename std::enable_if<IsFieldVectorSizeCorrect<C,SIZE>::value>::type* dummy=0)
167  {
168  // do a run-time size check, for the case that x is not a FieldVector
169  assert(x.size() == SIZE); // Actually this is not needed any more!
170  std::copy_n(x.begin(), std::min(static_cast<std::size_t>(SIZE),x.size()), _data.begin());
171  }
172 
174  template<class K1>
175  explicit FieldVector (const FieldVector<K1,SIZE> & x)
176  {
177  std::copy_n(x.begin(), SIZE, _data.begin());
178  }
179 
180  template<typename T, int N>
181  explicit FieldVector(const FieldVector<T, N>&) = delete;
182 
183  using Base::operator=;
184 
185  // make this thing a vector
186  static constexpr size_type size () { return SIZE; }
187 
188  K & operator[](size_type i) {
189  DUNE_ASSERT_BOUNDS(i < SIZE);
190  return _data[i];
191  }
192  const K & operator[](size_type i) const {
193  DUNE_ASSERT_BOUNDS(i < SIZE);
194  return _data[i];
195  }
196 
198  K* data() noexcept
199  {
200  return _data.data();
201  }
202 
204  const K* data() const noexcept
205  {
206  return _data.data();
207  }
208 
210  template <class Scalar,
211  std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
212  friend auto operator* ( const FieldVector& vector, Scalar scalar)
213  {
215 
216  for (size_type i = 0; i < vector.size(); ++i)
217  result[i] = vector[i] * scalar;
218 
219  return result;
220  }
221 
223  template <class Scalar,
224  std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
225  friend auto operator* ( Scalar scalar, const FieldVector& vector)
226  {
228 
229  for (size_type i = 0; i < vector.size(); ++i)
230  result[i] = scalar * vector[i];
231 
232  return result;
233  }
234 
236  template <class Scalar,
237  std::enable_if_t<IsNumber<Scalar>::value, int> = 0>
238  friend auto operator/ ( const FieldVector& vector, Scalar scalar)
239  {
241 
242  for (size_type i = 0; i < vector.size(); ++i)
243  result[i] = vector[i] / scalar;
244 
245  return result;
246  }
247 
248  };
249 
261  template<class K, int SIZE>
262  inline std::istream &operator>> ( std::istream &in,
264  {
266  for( typename FieldVector<K, SIZE>::size_type i = 0; i < SIZE; ++i )
267  in >> w[ i ];
268  if(in)
269  v = w;
270  return in;
271  }
272 
273 #ifndef DOXYGEN
274  template< class K >
275  struct DenseMatVecTraits< FieldVector<K,1> >
276  {
277  typedef FieldVector<K,1> derived_type;
278  typedef K container_type;
279  typedef K value_type;
280  typedef size_t size_type;
281  };
282 
285  template<class K>
286  class FieldVector<K, 1> :
287  public DenseVector< FieldVector<K,1> >
288  {
289  K _data;
290  typedef DenseVector< FieldVector<K,1> > Base;
291  public:
293  constexpr static int dimension = 1;
294 
295  typedef typename Base::size_type size_type;
296 
298  typedef K& reference;
299 
301  typedef const K& const_reference;
302 
303  //===== construction
304 
306  constexpr FieldVector ()
307  : _data()
308  {}
309 
311  template<typename T,
312  typename EnableIf = typename std::enable_if<
313  std::is_convertible<T, K>::value &&
314  ! std::is_base_of<DenseVector<typename FieldTraits<T>::field_type>, K
315  >::value
316  >::type
317  >
318  FieldVector (const T& k) : _data(k) {}
319 
321  template<class C,
322  std::enable_if_t<
323  std::is_assignable<K&, typename DenseVector<C>::value_type>::value, int> = 0>
324  FieldVector (const DenseVector<C> & x)
325  {
326  static_assert(((bool)IsFieldVectorSizeCorrect<C,1>::value), "FieldVectors do not match in dimension!");
327  assert(x.size() == 1);
328  _data = x[0];
329  }
330 
332  FieldVector(const FieldVector&) = default;
333 
335  FieldVector& operator=(const FieldVector&) = default;
336 
337  template <typename T>
338  FieldVector& operator= (const FieldVector<T, 1>& other)
339  {
340  _data = other[0];
341  return *this;
342  }
343 
344  template<typename T, int N>
345  FieldVector& operator=(const FieldVector<T, N>&) = delete;
346 
348  FieldVector (std::initializer_list<K> const &l)
349  {
350  assert(l.size() == 1);
351  _data = *l.begin();
352  }
353 
355  template<typename T,
356  typename EnableIf = typename std::enable_if<
357  std::is_assignable<K&, T>::value &&
358  ! std::is_base_of<DenseVector<typename FieldTraits<T>::field_type>, K
359  >::value
360  >::type
361  >
362  inline FieldVector& operator= (const T& k)
363  {
364  _data = k;
365  return *this;
366  }
367 
368  //===== forward methods to container
369  static constexpr size_type size () { return 1; }
370 
371  K & operator[]([[maybe_unused]] size_type i)
372  {
373  DUNE_ASSERT_BOUNDS(i == 0);
374  return _data;
375  }
376  const K & operator[]([[maybe_unused]] size_type i) const
377  {
378  DUNE_ASSERT_BOUNDS(i == 0);
379  return _data;
380  }
381 
383  K* data() noexcept
384  {
385  return &_data;
386  }
387 
389  const K* data() const noexcept
390  {
391  return &_data;
392  }
393 
394  //===== conversion operator
395 
397  operator K& () { return _data; }
398 
400  operator const K& () const { return _data; }
401  };
402 
403  /* ----- FV / FV ----- */
404  /* mostly not necessary as these operations are already covered via the cast operator */
405 
407  template<class K>
408  inline bool operator> (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
409  {
410  return a[0]>b[0];
411  }
412 
414  template<class K>
415  inline bool operator>= (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
416  {
417  return a[0]>=b[0];
418  }
419 
421  template<class K>
422  inline bool operator< (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
423  {
424  return a[0]<b[0];
425  }
426 
428  template<class K>
429  inline bool operator<= (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
430  {
431  return a[0]<=b[0];
432  }
433 
434  /* ----- FV / scalar ----- */
435 
437  template<class K>
438  inline FieldVector<K,1> operator+ (const FieldVector<K,1>& a, const K b)
439  {
440  return a[0]+b;
441  }
442 
444  template<class K>
445  inline FieldVector<K,1> operator- (const FieldVector<K,1>& a, const K b)
446  {
447  return a[0]-b;
448  }
449 
451  template<class K>
452  inline FieldVector<K,1> operator* (const FieldVector<K,1>& a, const K b)
453  {
454  return a[0]*b;
455  }
456 
458  template<class K>
459  inline FieldVector<K,1> operator/ (const FieldVector<K,1>& a, const K b)
460  {
461  return a[0]/b;
462  }
463 
465  template<class K>
466  inline bool operator> (const FieldVector<K,1>& a, const K b)
467  {
468  return a[0]>b;
469  }
470 
472  template<class K>
473  inline bool operator>= (const FieldVector<K,1>& a, const K b)
474  {
475  return a[0]>=b;
476  }
477 
479  template<class K>
480  inline bool operator< (const FieldVector<K,1>& a, const K b)
481  {
482  return a[0]<b;
483  }
484 
486  template<class K>
487  inline bool operator<= (const FieldVector<K,1>& a, const K b)
488  {
489  return a[0]<=b;
490  }
491 
493  template<class K>
494  inline bool operator== (const FieldVector<K,1>& a, const K b)
495  {
496  return a[0]==b;
497  }
498 
500  template<class K>
501  inline bool operator!= (const FieldVector<K,1>& a, const K b)
502  {
503  return a[0]!=b;
504  }
505 
506  /* ----- scalar / FV ------ */
507 
509  template<class K>
510  inline FieldVector<K,1> operator+ (const K a, const FieldVector<K,1>& b)
511  {
512  return a+b[0];
513  }
514 
516  template<class K>
517  inline FieldVector<K,1> operator- (const K a, const FieldVector<K,1>& b)
518  {
519  return a-b[0];
520  }
521 
523  template<class K>
524  inline FieldVector<K,1> operator* (const K a, const FieldVector<K,1>& b)
525  {
526  return a*b[0];
527  }
528 
530  template<class K>
531  inline FieldVector<K,1> operator/ (const K a, const FieldVector<K,1>& b)
532  {
533  return a/b[0];
534  }
535 
537  template<class K>
538  inline bool operator> (const K a, const FieldVector<K,1>& b)
539  {
540  return a>b[0];
541  }
542 
544  template<class K>
545  inline bool operator>= (const K a, const FieldVector<K,1>& b)
546  {
547  return a>=b[0];
548  }
549 
551  template<class K>
552  inline bool operator< (const K a, const FieldVector<K,1>& b)
553  {
554  return a<b[0];
555  }
556 
558  template<class K>
559  inline bool operator<= (const K a, const FieldVector<K,1>& b)
560  {
561  return a<=b[0];
562  }
563 
565  template<class K>
566  inline bool operator== (const K a, const FieldVector<K,1>& b)
567  {
568  return a==b[0];
569  }
570 
572  template<class K>
573  inline bool operator!= (const K a, const FieldVector<K,1>& b)
574  {
575  return a!=b[0];
576  }
577 #endif
578 
579  /* Overloads for common classification functions */
580  namespace MathOverloads {
581 
582  // ! Returns whether all entries are finite
583  template<class K, int SIZE>
584  auto isFinite(const FieldVector<K,SIZE> &b, PriorityTag<2>, ADLTag) {
585  bool out = true;
586  for(int i=0; i<SIZE; i++) {
587  out &= Dune::isFinite(b[i]);
588  }
589  return out;
590  }
591 
592  // ! Returns whether any entry is infinite
593  template<class K, int SIZE>
594  bool isInf(const FieldVector<K,SIZE> &b, PriorityTag<2>, ADLTag) {
595  bool out = false;
596  for(int i=0; i<SIZE; i++) {
597  out |= Dune::isInf(b[i]);
598  }
599  return out;
600  }
601 
602  // ! Returns whether any entry is NaN
603  template<class K, int SIZE, typename = std::enable_if_t<HasNaN<K>::value>>
604  bool isNaN(const FieldVector<K,SIZE> &b, PriorityTag<2>, ADLTag) {
605  bool out = false;
606  for(int i=0; i<SIZE; i++) {
607  out |= Dune::isNaN(b[i]);
608  }
609  return out;
610  }
611 
612  // ! Returns true if either b or c is NaN
613  template<class K, typename = std::enable_if_t<HasNaN<K>::value>>
614  bool isUnordered(const FieldVector<K,1> &b, const FieldVector<K,1> &c,
616  return Dune::isUnordered(b[0],c[0]);
617  }
618  } //MathOverloads
619 
622 } // end namespace
623 
624 #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:204
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(std::initializer_list< K > const &l)
Construct from a std::initializer_list.
Definition: fvector.hh:132
FieldVector(const FieldVector< K1, SIZE > &x)
Constructor making vector with identical coordinates.
Definition: fvector.hh:175
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:165
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:198
FieldVector(const FieldVector &)=default
Copy constructor.
Implements the dense vector interface, with an exchangeable storage class.
TypeTree-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:30
std::istream & operator>>(std::istream &in, DynamicVector< K, Allocator > &v)
Read a DynamicVector from an input stream.
Definition: dynvector.hh:189
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
auto min(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::min()
Definition: defaults.hh:89
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
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
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (Apr 26, 22:29, 2024)