Newer
Older
// This file is part of the dune-gdt project:
// http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
#ifndef DUNE_GDT_SPACES_MAPPER_PRODUCT_HH
#define DUNE_GDT_SPACES_MAPPER_PRODUCT_HH
#include <dune/common/dynvector.hh>
#include <dune/stuff/common/debug.hh>
#include <dune/stuff/common/type_utils.hh>
#include <dune/gdt/spaces/basefunctionset/product.hh>
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
namespace Dune {
namespace GDT {
// forward
template <class GridViewImp, class... MapperTypes>
class DefaultProductMapper;
namespace internal {
template <size_t I = 0>
struct DynamicTupleGetter
{
template <class EntityType, typename... TupleArgs>
static typename std::enable_if<I == sizeof...(TupleArgs), size_t>::type
numDofs(const std::tuple<TupleArgs...>& /*tuple*/, const size_t /*factor_index*/, const EntityType& /*entity*/)
{
return 0;
}
template <class EntityType, typename... TupleArgs>
static typename std::enable_if
< I<sizeof...(TupleArgs), size_t>::type numDofs(const std::tuple<TupleArgs...>& tuple, const size_t factor_index,
const EntityType& entity)
{
if (factor_index == 0)
return std::get<I>(tuple).numDofs(entity);
return DynamicTupleGetter<I + 1>::numDofs(tuple, factor_index - 1, entity);
}
template <typename... TupleArgs>
static typename std::enable_if<I == sizeof...(TupleArgs), size_t>::type
maxNumDofs(const std::tuple<TupleArgs...>& /*tuple*/, const size_t /*factor_index*/)
{
return 0;
}
template <typename... TupleArgs>
static typename std::enable_if < I<sizeof...(TupleArgs), size_t>::type
maxNumDofs(const std::tuple<TupleArgs...>& tuple, const size_t factor_index)
{
if (factor_index == 0)
return std::get<I>(tuple).maxNumDofs();
return DynamicTupleGetter<I + 1>::maxNumDofs(tuple, factor_index - 1);
}
template <typename... TupleArgs>
static typename std::enable_if<I == sizeof...(TupleArgs), size_t>::type
size(const std::tuple<TupleArgs...>& /*tuple*/, const size_t /*factor_index*/)
{
return 0;
}
template <typename... TupleArgs>
static typename std::enable_if
< I<sizeof...(TupleArgs), size_t>::type size(const std::tuple<TupleArgs...>& tuple, const size_t factor_index)
{
if (factor_index == 0)
return std::get<I>(tuple).size();
return DynamicTupleGetter<I + 1>::size(tuple, factor_index - 1);
}
template <class EntityType, typename... TupleArgs>
static typename std::enable_if<I == sizeof...(TupleArgs), size_t>::type
mapToGlobal(const std::tuple<TupleArgs...>& /*tuple*/, const size_t /*factor_index*/, const EntityType& /*entity*/,
const size_t& /*local_index_in_factor*/)
{
return 0;
}
template <class EntityType, typename... TupleArgs>
static typename std::enable_if
< I<sizeof...(TupleArgs), size_t>::type mapToGlobal(const std::tuple<TupleArgs...>& tuple,
const size_t factor_index, const EntityType& entity,
const size_t& local_index_in_factor)
{
if (factor_index == 0)
return std::get<I>(tuple).mapToGlobal(entity, local_index_in_factor);
return DynamicTupleGetter<I + 1>::mapToGlobal(tuple, factor_index - 1, entity, local_index_in_factor);
}
};
template <size_t I, class... SpaceTypes>
struct MapperTuplefromSpaceTupleCreator
{
template <class... MapperTypes>
static typename std::enable_if<sizeof...(MapperTypes) == sizeof...(SpaceTypes),
typename std::tuple<MapperTypes...>>::type
create(const std::tuple<SpaceTypes...>& /*spaces*/, const std::tuple<MapperTypes...>& mappers)
{
return mappers;
}
template <class... MapperTypes>
static typename std::enable_if<sizeof...(MapperTypes) < sizeof...(SpaceTypes),
typename std::tuple<typename SpaceTypes::MapperType...>>::type
create(const std::tuple<SpaceTypes...>& spaces, const std::tuple<MapperTypes...>& mappers)
{
const auto new_mappers = std::tuple_cat(mappers, std::make_tuple(std::get<I>(spaces).mapper()));
return MapperTuplefromSpaceTupleCreator<I + 1, SpaceTypes...>::create(spaces, new_mappers);
}
};
template <class GridViewImp, class... MapperTypes>
class DefaultProductMapperTraits
{
public:
typedef GridViewImp GridViewType;
typedef DefaultProductMapper<GridViewType, MapperTypes...> derived_type;
static const size_t dimRange = GDT::BaseFunctionSet::internal::SumDimRange<MapperTypes...>::dimRange;
typedef typename GridViewType::IndexSet BackendType;
typedef typename GridViewType::template Codim<0>::Entity EntityType;
};
} // namespace internal
template <class GridViewImp, class TupleType>
struct DefaultProductMapperFromTuple;
template <class GridViewImp, class... MapperTypes>
struct DefaultProductMapperFromTuple<GridViewImp, std::tuple<MapperTypes...>>
{
typedef DefaultProductMapper<GridViewImp, MapperTypes...> type;
};
template <class GridViewImp, class... MapperTypes>
class DefaultProductMapper
: public ProductMapperInterface<internal::DefaultProductMapperTraits<GridViewImp, MapperTypes...>>
{
typedef ProductMapperInterface<internal::DefaultProductMapperTraits<GridViewImp, MapperTypes...>> BaseType;
public:
typedef internal::DefaultProductMapperTraits<GridViewImp, MapperTypes...> Traits;
typedef typename Traits::GridViewType GridViewType;
static const size_t dimRange = Traits::dimRange;
using typename BaseType::EntityType;
using typename BaseType::BackendType;
DefaultProductMapper(const GridViewType& grid_view, const MapperTypes&... mappers)
: mappers_(std::make_tuple(mappers...))
, grid_view_(grid_view)
{
}
DefaultProductMapper(const GridViewType& grid_view, const std::tuple<MapperTypes...>& mappers)
: mappers_(mappers)
, grid_view_(grid_view)
{
}
template <class... SpaceTypes>
DefaultProductMapper(const std::tuple<SpaceTypes...>& spaces)
: DefaultProductMapper(std::get<0>(spaces).grid_view(),
internal::MapperTuplefromSpaceTupleCreator<0, SpaceTypes...>::create(spaces, std::tuple<>()))
{
}
// These methods are required by the ProductMapperInterface
size_t numDofs(const size_t factor_index, const EntityType& entity) const
{
return internal::DynamicTupleGetter<0>::numDofs(mappers_, factor_index, entity);
}
size_t maxNumDofs(const size_t factor_index) const
{
return internal::DynamicTupleGetter<0>::maxNumDofs(mappers_, factor_index);
}
void globalIndices(const size_t factor_index, const EntityType& entity, Dune::DynamicVector<size_t>& ret) const
{
const size_t num_dofs_entity = numDofs(factor_index, entity);
if (ret.size() != num_dofs_entity)
ret.resize(num_dofs_entity);
for (size_t ii = 0; ii < num_dofs_entity; ++ii)
ret[ii] = mapToGlobal(factor_index, entity, ii);
}
size_t mapToGlobal(const size_t factor_index, const EntityType& entity, const size_t& local_index_in_factor) const
{
size_t first_global_index_of_factor = 0;
for (size_t ii = 0; ii < factor_index; ++ii)
first_global_index_of_factor += size(ii);
return first_global_index_of_factor
+ internal::DynamicTupleGetter<0>::mapToGlobal(mappers_, factor_index, entity, local_index_in_factor);
}
size_t mapToLocal(const size_t factor_index, const EntityType& entity, const size_t& local_index_in_factor) const
{
size_t first_local_index_of_factor = 0;
for (size_t ii = 0; ii < factor_index; ++ii)
first_local_index_of_factor += numDofs(ii, entity);
return first_local_index_of_factor + local_index_in_factor;
}
const BackendType& backend() const
{
return BackendType();
}
size_t size(const size_t factor_index) const
{
return internal::DynamicTupleGetter<0>::size(mappers_, factor_index);
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
}
size_t size() const
{
size_t ret = 0;
for (size_t ii = 0; ii < sizeof...(MapperTypes); ++ii)
ret += size(ii);
return ret;
}
size_t numDofs(const EntityType& entity) const
{
size_t ret = 0;
for (size_t ii = 0; ii < sizeof...(MapperTypes); ++ii)
ret += numDofs(ii, entity);
return ret;
}
size_t maxNumDofs() const
{
size_t max_num_dofs = 0;
const auto it_end = grid_view_.template end<0>();
for (auto it = grid_view_.template begin<0>(); it != it_end; ++it) {
const auto& entity = *it;
if (max_num_dofs < numDofs(entity))
max_num_dofs = numDofs(entity);
}
return max_num_dofs;
}
void globalIndices(const EntityType& entity, Dune::DynamicVector<size_t>& ret) const
{
const size_t num_dofs_entity = numDofs(entity);
if (ret.size() != num_dofs_entity)
ret.resize(num_dofs_entity);
for (size_t ii = 0; ii < num_dofs_entity; ++ii)
ret[ii] = mapToGlobal(entity, ii);
} // ... globalIndices(...)
using BaseType::globalIndices;
size_t mapToGlobal(const EntityType& entity, const size_t& localIndex) const
{
size_t factor_index = 0;
size_t local_index_in_factor = localIndex;
while (local_index_in_factor >= numDofs(factor_index, entity)) {
local_index_in_factor -= numDofs(factor_index, entity);
++factor_index;
}
return mapToGlobal(factor_index, entity, local_index_in_factor);
}
private:
const std::tuple<MapperTypes...> mappers_;
const GridViewType& grid_view_;
}; // class DefaultProductMapper
} // namespace GDT
} // namespace Dune
#endif // DUNE_GDT_SPACES_MAPPER_PRODUCT_HH