5#ifndef DUNE_ISTL_MULTITYPEBLOCKVECTOR_HH
6#define DUNE_ISTL_MULTITYPEBLOCKVECTOR_HH
12#include <dune/common/dotproduct.hh>
13#include <dune/common/ftraits.hh>
14#include <dune/common/hybridutilities.hh>
15#include <dune/common/typetraits.hh>
16#include <dune/common/std/type_traits.hh>
22 template <
typename... Args >
23 class MultiTypeBlockVector;
41 template <
typename... Args>
56 template <
typename... Args >
58 :
public std::tuple<Args...>
61 typedef std::tuple<Args...> TupleType;
70 using TupleType::TupleType;
89 using real_type = Std::detected_t<std::common_type_t, typename FieldTraits< std::decay_t<Args> >
::real_type...>;
93 static_assert (
sizeof...(Args) == 0 or
94 not (std::is_same_v<field_type, Std::nonesuch> or std::is_same_v<real_type, Std::nonesuch>),
95 "No std::common_type implemented for the given field_type/real_type of the Args. Please provide an implementation and check that a FieldTraits class is present for your type.");
105 return sizeof...(Args);
112 return sizeof...(Args);
119 Hybrid::forEach(std::make_index_sequence<
N()>{},
120 [&](
auto i){result += std::get<i>(*this).dim();});
143 template<
size_type index >
144 typename std::tuple_element<index,TupleType>::type&
145 operator[] ([[maybe_unused]]
const std::integral_constant< size_type, index > indexVariable)
147 return std::get<index>(*
this);
155 template<
size_type index >
156 const typename std::tuple_element<index,TupleType>::type&
157 operator[] ([[maybe_unused]]
const std::integral_constant< size_type, index > indexVariable)
const
159 return std::get<index>(*
this);
166 Dune::Hybrid::forEach(*
this, [&](
auto&& entry) {
175 using namespace Dune::Hybrid;
176 forEach(integralRange(Hybrid::size(*
this)), [&](
auto&& i) {
177 (*this)[i] += newv[i];
185 using namespace Dune::Hybrid;
186 forEach(integralRange(Hybrid::size(*
this)), [&](
auto&& i) {
187 (*this)[i] -= newv[i];
193 std::enable_if_t< IsNumber<T>::value,
int> = 0>
195 Hybrid::forEach(*
this, [&](
auto&& entry) {
202 std::enable_if_t< IsNumber<T>::value,
int> = 0>
204 Hybrid::forEach(*
this, [&](
auto&& entry) {
210 using namespace Dune::Hybrid;
211 return accumulate(integralRange(Hybrid::size(*
this)),
field_type(0), [&](
auto&& a,
auto&& i) {
212 return a + (*this)[i]*newv[i];
217 using namespace Dune::Hybrid;
218 return accumulate(integralRange(Hybrid::size(*
this)),
field_type(0), [&](
auto&& a,
auto&& i) {
219 return a + (*this)[i].dot(newv[i]);
226 using namespace Dune::Hybrid;
227 return accumulate(*
this,
real_type(0), [&](
auto&& a,
auto&& entry) {
228 return a + entry.one_norm();
235 using namespace Dune::Hybrid;
236 return accumulate(*
this,
real_type(0), [&](
auto&& a,
auto&& entry) {
237 return a + entry.one_norm_real();
244 using namespace Dune::Hybrid;
245 return accumulate(*
this,
real_type(0), [&](
auto&& a,
auto&& entry) {
246 return a + entry.two_norm2();
258 using namespace Dune::Hybrid;
264 if constexpr (HasNaN<field_type>()) {
267 using namespace Dune::Hybrid;
268 forEach(*
this, [&](
auto&& entry) {
269 real_type entryNorm = entry.infinity_norm();
270 result = max(entryNorm, result);
271 nanTracker += entryNorm;
274 result *= (nanTracker / nanTracker);
276 using namespace Dune::Hybrid;
277 forEach(*
this, [&](
auto&& entry) {
278 result = max(entry.infinity_norm(), result);
288 using namespace Dune::Hybrid;
294 if constexpr (HasNaN<field_type>()) {
297 using namespace Dune::Hybrid;
298 forEach(*
this, [&](
auto&& entry) {
299 real_type entryNorm = entry.infinity_norm_real();
300 result = max(entryNorm, result);
301 nanTracker += entryNorm;
304 result *= (nanTracker / nanTracker);
306 using namespace Dune::Hybrid;
307 forEach(*
this, [&](
auto&& entry) {
308 result = max(entry.infinity_norm_real(), result);
318 template<
typename Ta>
320 using namespace Dune::Hybrid;
321 forEach(integralRange(Hybrid::size(*
this)), [&](
auto&& i) {
322 (*this)[i].axpy(a, y[i]);
332 template <
typename... Args>
334 using namespace Dune::Hybrid;
335 forEach(integralRange(Dune::Hybrid::size(v)), [&](
auto&& i) {
336 s <<
"\t(" << i <<
"):\n" << v[i] <<
"\n";
349 template <
size_t i,
typename... Args>
350 struct tuple_element<i,
Dune::MultiTypeBlockVector<Args...> >
352 using type =
typename std::tuple_element<i, std::tuple<Args...> >::type;
359 template <
typename... Args>
360 struct tuple_size<
Dune::MultiTypeBlockVector<Args...> >
361 : std::integral_constant<std::size_t, sizeof...(Args)>
Simple iterative methods like Jacobi, Gauss-Seidel, SOR, SSOR, etc. in a generic way.
void operator=(const T &newval)
Assignment operator.
Definition multitypeblockvector.hh:165
std::size_t size_type
Type used for vector sizes.
Definition multitypeblockvector.hh:65
static constexpr size_type N()
Number of elements.
Definition multitypeblockvector.hh:110
Std::detected_t< std::common_type_t, typename FieldTraits< std::decay_t< Args > >::field_type... > field_type
The type used for scalars.
Definition multitypeblockvector.hh:82
static constexpr size_type size()
Return the number of non-zero vector entries.
Definition multitypeblockvector.hh:103
std::tuple_element< index, TupleType >::type & operator[](const std::integral_constant< size_type, index > indexVariable)
Random-access operator.
Definition multitypeblockvector.hh:145
typename MultiTypeBlockVector< Args... >::field_type field_type
Definition multitypeblockvector.hh:44
size_type dim() const
Number of scalar elements.
Definition multitypeblockvector.hh:116
Std::detected_t< std::common_type_t, typename FieldTraits< std::decay_t< Args > >::real_type... > real_type
The type used for real values.
Definition multitypeblockvector.hh:89
field_type dot(const type &newv) const
Definition multitypeblockvector.hh:216
void operator*=(const T &w)
Multiplication with a scalar.
Definition multitypeblockvector.hh:194
void axpy(const Ta &a, const type &y)
Axpy operation on this vector (*this += a * y)
Definition multitypeblockvector.hh:319
real_type two_norm() const
Compute the Euclidean norm.
Definition multitypeblockvector.hh:252
void operator/=(const T &w)
Division by a scalar.
Definition multitypeblockvector.hh:203
MultiTypeBlockVector< Args... > type
Definition multitypeblockvector.hh:75
auto one_norm() const
Compute the 1-norm.
Definition multitypeblockvector.hh:225
real_type two_norm2() const
Compute the squared Euclidean norm.
Definition multitypeblockvector.hh:243
real_type infinity_norm_real() const
Compute the simplified maximum norm (uses 1-norm for complex values)
Definition multitypeblockvector.hh:286
void operator-=(const type &newv)
Definition multitypeblockvector.hh:184
real_type infinity_norm() const
Compute the maximum norm.
Definition multitypeblockvector.hh:256
field_type operator*(const type &newv) const
Definition multitypeblockvector.hh:209
void operator+=(const type &newv)
Definition multitypeblockvector.hh:174
typename std::tuple_element< i, std::tuple< Args... > >::type type
Definition multitypeblockvector.hh:352
auto one_norm_real() const
Compute the simplified 1-norm (uses 1-norm also for complex values)
Definition multitypeblockvector.hh:234
typename MultiTypeBlockVector< Args... >::real_type real_type
Definition multitypeblockvector.hh:45
Definition allocator.hh:11
std::ostream & operator<<(std::ostream &s, const BlockVector< K, A > &v)
Send BlockVector to an output stream.
Definition bvector.hh:583
A Vector class to support different block types.
Definition multitypeblockvector.hh:59