3#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_ISTLVECTORBACKEND_HH
4#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_ISTLVECTORBACKEND_HH
10#include <dune/common/std/type_traits.hh>
11#include <dune/common/indices.hh>
12#include <dune/common/hybridutilities.hh>
15#include <dune/functions/common/indexaccess.hh>
16#include <dune/functions/functionspacebases/concepts.hh>
25 std::enable_if_t<not Dune::models<Imp::Concept::HasStaticIndexAccess, V>() ,
int> = 0>
32 std::enable_if_t<Dune::models<Imp::Concept::HasStaticIndexAccess, V>(),
int> = 0>
35 if constexpr (Dune::models<Imp::Concept::HasDynamicIndexAccess<std::size_t>, V>())
36 return fieldTypes(v[std::size_t{0}]);
39 auto indexRange =
typename decltype(range(Hybrid::size(v)))::integer_sequence();
63constexpr auto fieldTypes()
65 return decltype(Impl::fieldTypes(std::declval<V>())){};
74constexpr bool hasUniqueFieldType()
76 return std::tuple_size<std::decay_t<decltype(fieldTypes<V>())>>::value==1;
101class ISTLVectorBackend
106 using dynamicIndexAccess_t =
decltype(std::declval<C>()[0]);
112 using resizeMethod_t =
decltype(std::declval<C>().resize(0));
130 using isStaticVector = Dune::Std::bool_constant<
131 Dune::Std::is_detected_v<staticIndexAccess_t, std::remove_reference_t<C>>
132 and not Dune::Std::is_detected_v<dynamicIndexAccess_t, std::remove_reference_t<C>>>;
135 using isScalar = Dune::Std::bool_constant<not Dune::Std::is_detected_v<staticIndexAccess_t, std::remove_reference_t<C>>>;
138 using isVector = Dune::Std::bool_constant<Dune::Std::is_detected_v<staticIndexAccess_t, std::remove_reference_t<C>>>;
142 template<
class... Args>
143 static void forwardToResize(Args&&... args)
145 resize(std::forward<Args>(args)...);
149 template<
class C,
class SizeProvider,
150 std::enable_if_t<hasResizeMethod<C>::value,
int> = 0>
151 static void resize(C&& c,
const SizeProvider& sizeProvider,
typename SizeProvider::SizePrefix prefix)
153 auto size = sizeProvider.size(prefix);
166 DUNE_THROW(RangeError,
"The vector entry v[" << prefix <<
"] should refer to a "
167 <<
"scalar coefficient, but is a dynamically sized vector of size==0");
176 for(std::size_t i=0; i<size; ++i)
179 resize(c[i], sizeProvider, prefix);
183 template<
class C,
class SizeProvider,
184 std::enable_if_t<not hasResizeMethod<C>::value,
int> = 0,
185 std::enable_if_t<isVector<C>::value,
int> = 0>
186 static void resize(C&& c,
const SizeProvider& sizeProvider,
typename SizeProvider::SizePrefix prefix)
188 auto size = sizeProvider.size(prefix);
203 if (c.size() != size)
204 DUNE_THROW(RangeError,
"Can't resize non-resizable entry v[" << prefix <<
"] of size " << c.size() <<
" to size(" << prefix <<
")=" << size);
207 using namespace Dune::Hybrid;
217 ISTLVectorBackend<V>::forwardToResize(c[i], sizeProvider, prefix);
221 template<
class C,
class SizeProvider,
222 std::enable_if_t<not hasResizeMethod<C>::value,
int> = 0,
223 std::enable_if_t<isScalar<C>::value,
int> = 0>
224 static void resize(C&&,
const SizeProvider& sizeProvider,
typename SizeProvider::SizePrefix prefix)
226 auto size = sizeProvider.size(prefix);
228 DUNE_THROW(
RangeError,
"Can't resize scalar vector entry v[" << prefix <<
"] to size(" << prefix <<
")=" << size);
231 template<
class C,
class T,
232 std::enable_if_t<std::is_assignable<C&,T>::value,
int> = 0>
233 void recursiveAssign(C& c,
const T& t)
238 template<
class C,
class T,
239 std::enable_if_t<not std::is_assignable<C&,T>::value,
int> = 0>
240 void recursiveAssign(C& c,
const T& t)
243 recursiveAssign(ci, t);
251 ISTLVectorBackend(Vector& vector) :
255 template<
class SizeProv
ider>
256 void resize(
const SizeProvider& sizeProvider)
258 auto prefix =
typename SizeProvider::SizePrefix();
260 resize(*vector_, sizeProvider, prefix);
263 template<
class MultiIndex>
264 decltype(
auto)
operator[](
const MultiIndex& index)
const
269 template<
class MultiIndex>
270 decltype(
auto)
operator[](
const MultiIndex& index)
284 void operator= (
const T& other)
286 recursiveAssign(vector(), other);
290 void operator= (
const ISTLVectorBackend<T>& other)
292 vector() = other.vector();
295 const Vector& vector()
const
345template<
class Vector>
348 static_assert(hasUniqueFieldType<Vector&>(),
"Vector type passed to istlVectorBackend() does not have a unique field type.");
349 return Impl::ISTLVectorBackend<Vector>(v);
383template<
class Vector>
386 static_assert(hasUniqueFieldType<const Vector&>(),
"Vector type passed to istlVectorBackend() does not have a unique field type.");
387 return Impl::ISTLVectorBackend<const Vector>(v);
Default exception class for range errors.
Definition: exceptions.hh:254
Infrastructure for concepts.
constexpr index_constant< 0 > _0
Compile time index with value 0.
Definition: indices.hh:53
decltype(auto) constexpr unpackIntegerSequence(F &&f, std::integer_sequence< I, i... > sequence)
Unpack an std::integer_sequence<I,i...> to std::integral_constant<I,i>...
Definition: indices.hh:125
typename detected_or< nonesuch, Op, Args... >::value_t is_detected
Detects whether Op<Args...> is valid.
Definition: type_traits.hh:141
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
auto istlVectorBackend(const Vector &v)
Return a vector backend wrapping const ISTL like containers.
Definition: istlvectorbackend.hh:384
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:268
constexpr auto integralRange(const Begin &begin, const End &end)
Create an integral range.
Definition: hybridutilities.hh:184
constexpr decltype(auto) resolveDynamicMultiIndex(C &&c, const MultiIndex &multiIndex, const IsFinal &isFinal)
Provide multi-index access by chaining operator[].
Definition: indexaccess.hh:354
Dune namespace.
Definition: alignedallocator.hh:13
constexpr auto uniqueTypeList(TypeList< T... > list)
Remove duplicates from a Dune::TypeList.
Definition: typelist.hh:236