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
28namespace 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 >
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>
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
K * data() noexcept
return pointer to underlying array
Definition: fvector.hh:192
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
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:159
FieldVector(const K &t)
Constructor making vector with identical coordinates.
Definition: fvector.hh:117
const K * data() const noexcept
return pointer to underlying array
Definition: fvector.hh:198
static constexpr int dimension
The size of this vector.
Definition: fvector.hh:100
FieldVector(const FieldVector< K1, SIZE > &x)
Constructor making vector with identical coordinates.
Definition: fvector.hh:169
value_type & reference
The type used for references to the vector entry.
Definition: fvector.hh:106
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 RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:638
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:684
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:661
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:238
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:706
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:260
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
static constexpr 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.111.3 (Jul 15, 22:36, 2024)