Dune Core Modules (2.9.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// 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
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
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>
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
K * data() 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
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:165
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
const K * data() const noexcept
return pointer to underlying array
Definition: fvector.hh:204
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:175
value_type & reference
The type used for references to the vector entry.
Definition: fvector.hh:106
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
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 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:660
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 ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:259
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
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)