dune-common 2.9.0
Loading...
Searching...
No Matches
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 >
42 {
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 {
54 };
55
64 template<typename C, int SIZE>
66 {
71 constexpr static bool value = true;
72 };
73
74 template<typename T, int SIZE>
76 {
77 constexpr static bool value = true;
78 };
79
80 template<typename T, int SIZE, int SIZE1>
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
107
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>
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
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>
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>
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>>
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>>
616 return Dune::isUnordered(b[0],c[0]);
617 }
618 } //MathOverloads
619
622} // end namespace
623
624#endif
Type traits to determine the type of reals (when working with complex numbers)
Compute type of the result of an arithmetic operation involving two different number types.
Traits for type conversions and type information.
A few common exception classes.
Some useful basic math stuff.
Macro for wrapping boundary checks.
Implements the dense vector interface, with an exchangeable storage class.
#define DUNE_ASSERT_BOUNDS(cond)
If DUNE_CHECK_BOUNDS is defined: check if condition cond holds; otherwise, do nothing.
Definition boundschecking.hh:30
bigunsignedint< k > operator*(const bigunsignedint< k > &x, std::uintmax_t y)
Definition bigunsignedint.hh:549
bigunsignedint< k > operator/(const bigunsignedint< k > &x, std::uintmax_t y)
Definition bigunsignedint.hh:556
Dune namespace.
Definition alignedallocator.hh:13
bool isNaN(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Definition fvector.hh:604
bool isInf(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Definition fvector.hh:594
auto isFinite(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Definition fvector.hh:584
bool isUnordered(const FieldVector< K, 1 > &b, const FieldVector< K, 1 > &c, PriorityTag< 2 >, ADLTag)
Definition fvector.hh:614
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
Base::size_type size_type
Definition fvector.hh:102
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 FieldVector< T, N > &)=delete
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
static constexpr size_type size()
Definition fvector.hh:186
K & operator[](size_type i)
Definition fvector.hh:188
value_type & reference
The type used for references to the vector entry.
Definition fvector.hh:106
Base::value_type value_type
Definition fvector.hh:103
const K & operator[](size_type i) const
Definition fvector.hh:192
FieldVector & operator=(const FieldVector< T, N > &)=delete
FieldVector(const FieldVector &)=default
Copy constructor.
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
Definition ftraits.hh:26
T field_type
export the type representing the field
Definition ftraits.hh:28
T real_type
export the type representing the real type of the field
Definition ftraits.hh:30
std::array< K, SIZE > container_type
Definition fvector.hh:44
container_type::size_type size_type
Definition fvector.hh:46
FieldVector< K, SIZE > derived_type
Definition fvector.hh:43
FieldTraits< K >::real_type real_type
Definition fvector.hh:53
FieldTraits< K >::field_type field_type
Definition fvector.hh:52
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
Definition matvectraits.hh:31
Helper class for tagging priorities.
Definition typeutilities.hh:73