Dune Core Modules (2.6.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 
11 #include <dune/common/ftraits.hh>
12 #include <dune/common/hybridutilities.hh>
13 
14 #include "istlexception.hh"
15 
16 // forward declaration
17 namespace Dune {
18  template < typename... Args >
19  class MultiTypeBlockVector;
20 }
21 
22 #include "gsetc.hh"
23 
24 namespace 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(Dune::Hybrid::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)
#define DUNE_UNUSED_PARAMETER(parm)
A macro to mark intentionally unused function parameters with.
Definition: unused.hh:25
constexpr auto size(const T &t)
Size query.
Definition: hybridutilities.hh:80
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:308
T accumulate(Range &&range, T value, F &&f)
Accumulate values.
Definition: hybridutilities.hh:331
decltype(auto) ifElse(const Condition &condition, IfFunc &&ifFunc, ElseFunc &&elseFunc)
A conditional expression.
Definition: hybridutilities.hh:389
constexpr auto integralRange(const Begin &begin, const End &end)
Create an integral range.
Definition: hybridutilities.hh:221
void operator=(const T &newval)
Assignment operator.
Definition: multitypeblockvector.hh:130
static constexpr std::size_t size()
Return the number of vector entries.
Definition: multitypeblockvector.hh:75
std::tuple_element< index, tupleType >::type & operator[](const std::integral_constant< std::size_t, index > indexVariable)
Random-access operator.
Definition: multitypeblockvector.hh:108
void axpy(const Ta &a, const type &y)
Axpy operation on this vector (*this += a * y)
Definition: multitypeblockvector.hh:246
MultiTypeBlockVector< Args... > type
Definition: multitypeblockvector.hh:63
void operator-=(const type &newv)
Definition: multitypeblockvector.hh:149
int count()
Definition: multitypeblockvector.hh:83
FieldTraits< field_type >::real_type infinity_norm() const
Compute the maximum norm.
Definition: multitypeblockvector.hh:214
void operator+=(const type &newv)
Definition: multitypeblockvector.hh:139
FieldTraits< field_type >::real_type two_norm2() const
Compute the squared Euclidean norm.
Definition: multitypeblockvector.hh:201
FieldTraits< field_type >::real_type two_norm() const
Compute the Euclidean norm.
Definition: multitypeblockvector.hh:210
double field_type
The type used for scalars.
Definition: multitypeblockvector.hh:72
Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way.
Dune namespace.
Definition: alignedallocator.hh:10
Whether this type has a value of NaN.
Definition: typetraits.hh:181
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 6, 22:30, 2024)