Dune Core Modules (2.5.0)

multitypeblockvector.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_ISTL_MULTITYPEBLOCKVECTOR_HH
4#define DUNE_ISTL_MULTITYPEBLOCKVECTOR_HH
5
6#include <cmath>
7#include <iostream>
8#include <tuple>
9
12#include <dune/common/hybridutilities.hh>
13
14#include "istlexception.hh"
15
16// forward declaration
17namespace Dune {
18 template < typename... Args >
19 class MultiTypeBlockVector;
20}
21
22#include "gsetc.hh"
23
24namespace Dune {
25
37 template <typename Arg0, typename... Args>
38 struct FieldTraits< MultiTypeBlockVector<Arg0, Args...> >
39 {
40 typedef typename FieldTraits<Arg0>::field_type field_type;
41 typedef typename FieldTraits<Arg0>::real_type real_type;
42 };
52 template < typename... Args >
54 : public std::tuple<Args...>
55 {
57 typedef std::tuple<Args...> tupleType;
58 public:
59
63 typedef MultiTypeBlockVector<Args...> type;
64
72 typedef double field_type;
73
75 static constexpr std::size_t size()
76 {
77 return sizeof...(Args);
78 }
79
83 int count()
84 {
85 return sizeof...(Args);
86 }
87
106 template< std::size_t index >
107 typename std::tuple_element<index,tupleType>::type&
108 operator[] ( const std::integral_constant< std::size_t, index > indexVariable )
109 {
110 DUNE_UNUSED_PARAMETER(indexVariable);
111 return std::get<index>(*this);
112 }
113
119 template< std::size_t index >
120 const typename std::tuple_element<index,tupleType>::type&
121 operator[] ( const std::integral_constant< std::size_t, index > indexVariable ) const
122 {
123 DUNE_UNUSED_PARAMETER(indexVariable);
124 return std::get<index>(*this);
125 }
126
129 template<typename T>
130 void operator= (const T& newval) {
131 Dune::Hybrid::forEach(*this, [&](auto&& entry) {
132 entry = newval;
133 });
134 }
135
139 void operator+= (const type& newv) {
140 using namespace Dune::Hybrid;
141 forEach(integralRange(Hybrid::size(*this)), [&](auto&& i) {
142 (*this)[i] += newv[i];
143 });
144 }
145
149 void operator-= (const type& newv) {
150 using namespace Dune::Hybrid;
151 forEach(integralRange(Hybrid::size(*this)), [&](auto&& i) {
152 (*this)[i] -= newv[i];
153 });
154 }
155
156 // Once we have the IsNumber traits class the following
157 // three implementations could be replaced by:
158 //
159 // template<class T,
160 // std::enable_if_t< IsNumber<T>::value, int> = 0>
161 // void operator*= (const T& w) {
162 // Dune::Hybrid::forEach(*this, [&](auto&& entry) {
163 // entry *= w;
164 // });
165 // }
166
167 void operator*= (const int& w) {
168 Dune::Hybrid::forEach(*this, [&](auto&& entry) {
169 entry *= w;
170 });
171 }
172
173 void operator*= (const float& w) {
174 Dune::Hybrid::forEach(*this, [&](auto&& entry) {
175 entry *= w;
176 });
177 }
178
179 void operator*= (const double& w) {
180 Dune::Hybrid::forEach(*this, [&](auto&& entry) {
181 entry *= w;
182 });
183 }
184
185 field_type operator* (const type& newv) const {
186 using namespace Dune::Hybrid;
187 return accumulate(integralRange(Hybrid::size(*this)), field_type(0), [&](auto&& a, auto&& i) {
188 return a + (*this)[i]*newv[i];
189 });
190 }
191
192 field_type dot (const type& newv) const {
193 using namespace Dune::Hybrid;
194 return accumulate(integralRange(Hybrid::size(*this)), field_type(0), [&](auto&& a, auto&& i) {
195 return a + (*this)[i].dot(newv[i]);
196 });
197 }
198
201 typename FieldTraits<field_type>::real_type two_norm2() const {
202 using namespace Dune::Hybrid;
203 return accumulate(*this, typename FieldTraits<field_type>::real_type(0), [&](auto&& a, auto&& entry) {
204 return a + entry.two_norm2();
205 });
206 }
207
210 typename FieldTraits<field_type>::real_type two_norm() const {return sqrt(this->two_norm2());}
211
214 typename FieldTraits<field_type>::real_type infinity_norm() const
215 {
216 using namespace Dune::Hybrid;
217 using std::max;
218 using real_type = typename FieldTraits<field_type>::real_type;
219
220 real_type result = 0.0;
221 // Compute max norm tracking appearing nan values
222 // if the field type supports nan.
223 ifElse(has_nan<field_type>(), [&](auto&& id) {
224 // This variable will preserve any nan value
225 real_type nanTracker = 1.0;
226 forEach(*this, [&](auto&& entry) {
227 real_type entryNorm = entry.infinity_norm();
228 result = max(entryNorm, result);
229 nanTracker += entryNorm;
230 });
231 // Incorporate possible nan value into result
232 result *= (nanTracker / nanTracker);
233 }, [&](auto&& id) {
234 forEach(*this, [&](auto&& entry) {
235 result = max(entry.infinity_norm(), result);
236 });
237 });
238 return result;
239 }
240
245 template<typename Ta>
246 void axpy (const Ta& a, const type& y) {
247 using namespace Dune::Hybrid;
248 forEach(integralRange(Hybrid::size(*this)), [&](auto&& i) {
249 (*this)[i].axpy(a, y[i]);
250 });
251 }
252
253 };
254
255
256
259 template <typename... Args>
260 std::ostream& operator<< (std::ostream& s, const MultiTypeBlockVector<Args...>& v) {
261 using namespace Dune::Hybrid;
262 forEach(integralRange(size(v)), [&](auto&& i) {
263 s << "\t(" << i << "):\n" << v[i] << "\n";
264 });
265 return s;
266 }
267
268
269
270} // end namespace
271
272#endif
A Vector class to support different block types.
Definition: multitypeblockvector.hh:55
Provides the functions dot(a,b) := and dotT(a,b) := .
Type traits to determine the type of reals (when working with complex numbers)
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:314
T accumulate(Range &&range, T value, F &&f)
Accumulate values.
Definition: hybridutilities.hh:337
decltype(auto) ifElse(const Condition &condition, IfFunc &&ifFunc, ElseFunc &&elseFunc)
A conditional expression.
Definition: hybridutilities.hh:395
constexpr auto integralRange(const Begin &begin, const End &end)
Create an integral range.
Definition: hybridutilities.hh:227
void operator=(const T &newval)
Assignment operator.
Definition: multitypeblockvector.hh:130
FieldTraits< field_type >::real_type two_norm() const
Compute the Euclidean norm.
Definition: multitypeblockvector.hh:210
static constexpr std::size_t size()
Return the number of vector entries.
Definition: multitypeblockvector.hh:75
void axpy(const Ta &a, const type &y)
Axpy operation on this vector (*this += a * y)
Definition: multitypeblockvector.hh:246
std::tuple_element< index, tupleType >::type & operator[](const std::integral_constant< std::size_t, index > indexVariable)
Random-access operator.
Definition: multitypeblockvector.hh:108
MultiTypeBlockVector< Args... > type
Definition: multitypeblockvector.hh:63
void operator-=(const type &newv)
Definition: multitypeblockvector.hh:149
int count()
Definition: multitypeblockvector.hh:83
void operator+=(const type &newv)
Definition: multitypeblockvector.hh:139
FieldTraits< field_type >::real_type infinity_norm() const
Compute the maximum norm.
Definition: multitypeblockvector.hh:214
double field_type
The type used for scalars.
Definition: multitypeblockvector.hh:72
FieldTraits< field_type >::real_type two_norm2() const
Compute the squared Euclidean norm.
Definition: multitypeblockvector.hh:201
Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way.
Dune namespace.
Definition: alignment.hh:11
#define DUNE_UNUSED_PARAMETER(parm)
A macro to mark intentionally unused function parameters with.
Definition: unused.hh:18
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)