Skip to content
Snippets Groups Projects
Commit 609343cf authored by Tobias Leibner's avatar Tobias Leibner
Browse files

[playground.spaces/mapper] add Pdelab-based product space

parent e7d24818
No related branches found
No related tags found
No related merge requests found
// 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_PLAYGROUND_MAPPER_PRODUCTDGPDELAB_HH
#define DUNE_GDT_PLAYGROUND_MAPPER_PRODUCTDGPDELAB_HH
#include <dune/common/dynvector.hh>
#include <dune/stuff/common/debug.hh>
#include <dune/stuff/common/type_utils.hh>
#include <dune/gdt/mapper/interface.hh>
#include <dune/gdt/mapper/pdelab.hh>
namespace Dune {
namespace GDT {
namespace Mapper {
// forward
template <class PdelabSpaceImp, size_t rangeDim = 1, size_t rangeDimCols = 1>
class ProductDG
{
static_assert(AlwaysFalse<PdelabSpaceImp>::value, "Not available for these dimensions!");
};
namespace internal {
template <class PdelabSpaceImp, size_t rangeDim, size_t rangeDimCols>
class ProductDGTraits
{
static_assert(rangeDim >= 1, "Really?");
static_assert(rangeDimCols >= 1, "Really?");
public:
typedef ProductDG<PdelabSpaceImp, rangeDim, rangeDimCols> derived_type;
typedef PdelabSpaceImp BackendType;
typedef typename BackendType::Element EntityType;
};
} // namespace internal
template <class PdelabSpaceImp, size_t rangeDim>
class ProductDG<PdelabSpaceImp, rangeDim, 1>
: public ProductMapperInterface<internal::ProductDGTraits<PdelabSpaceImp, rangeDim, 1>>
{
typedef ProductMapperInterface<internal::ProductDGTraits<PdelabSpaceImp, rangeDim, 1>> InterfaceType;
static const size_t dimRange = rangeDim;
public:
typedef internal::ProductDGTraits<PdelabSpaceImp, rangeDim, 1> Traits;
typedef typename Traits::BackendType BackendType;
typedef DiscontinuousPdelabWrapper<BackendType> FactorMapperType;
typedef typename Traits::EntityType EntityType;
ProductDG(const BackendType& pdelab_space)
: backend_(pdelab_space)
, factor_mapper_(pdelab_space)
{
}
const BackendType& backend() const
{
return backend_;
}
size_t size() const
{
return factor_mapper_.size() * dimRange;
}
size_t numDofs(const EntityType& entity) const
{
return dimRange * factor_mapper_.numDofs(entity);
}
size_t maxNumDofs() const
{
return dimRange * factor_mapper_.maxNumDofs();
}
void globalIndices(const EntityType& entity, Dune::DynamicVector<size_t>& ret) const
{
if (ret.size() < numDofs(entity))
ret.resize(numDofs(entity));
const auto factor_num_dofs = factor_mapper_.numDofs(entity);
const auto factor_mapper_size = factor_mapper_.size();
const auto factor_global_indices = factor_mapper_.globalIndices(entity);
for (size_t ii = 0; ii < dimRange; ++ii) {
const auto factor_num_dofs_times_ii = factor_num_dofs * ii;
const auto factor_mapper_size_times_ii = factor_mapper_size * ii;
for (size_t jj = 0; jj < factor_num_dofs; ++jj) {
ret[factor_num_dofs_times_ii + jj] = factor_global_indices[jj] + factor_mapper_size_times_ii;
}
}
} // ... globalIndices(...)
using InterfaceType::globalIndices;
void globalIndices(const size_t factor_index, const EntityType& entity, Dune::DynamicVector<size_t>& ret) const
{
assert(factor_index < dimRange);
const auto factor_mapper_num_dofs = factor_mapper_.numDofs(entity);
if (ret.size() < factor_mapper_num_dofs)
ret.resize(factor_mapper_num_dofs);
const auto factor_mapper_size_times_factor_index = factor_mapper_.size() * factor_index;
const auto factor_mapper_global_indices = factor_mapper_.globalIndices(entity);
for (size_t jj = 0; jj < factor_mapper_num_dofs; ++jj)
ret[jj] = factor_mapper_global_indices[jj] + factor_mapper_size_times_factor_index;
} // ... globalIndices(...)
Dune::DynamicVector<size_t> globalIndices(const size_t factor_index, const EntityType& entity) const
{
Dune::DynamicVector<size_t> ret(factor_mapper_.numDofs(entity), 0);
globalIndices(factor_index, entity, ret);
return ret;
}
size_t mapToGlobal(const EntityType& entity, const size_t& localIndex) const
{
assert(localIndex < numDofs(entity));
size_t factor_index = 0;
const auto factor_mapper_num_dofs = factor_mapper_.numDofs(entity);
while (localIndex >= factor_mapper_num_dofs) {
localIndex -= factor_mapper_num_dofs;
++factor_index;
}
return factor_mapper_.mapToGlobal(entity, localIndex) + factor_index * factor_mapper_.size();
}
size_t mapToGlobal(const size_t factor_index, const EntityType& entity, const size_t& localIndex) const
{
assert(localIndex < factor_mapper_.numDofs(entity));
assert(factor_index < dimRange);
return factor_mapper_.mapToGlobal(entity, localIndex) + factor_index * factor_mapper_.size();
}
private:
const BackendType& backend_;
const FactorMapperType factor_mapper_;
}; // class ProductFiniteVolume< ..., rangeDim, 1 >
} // namespace Mapper
} // namespace GDT
} // namespace Dune
#endif // DUNE_GDT_PLAYGROUND_MAPPER_PRODUCTDGPDELAB_HH
// 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)
//
// Contributors: Tobias Leibner
#ifndef DUNE_GDT_PLAYGROUND_SPACES_DG_PDELABPRODUCT_HH
#define DUNE_GDT_PLAYGROUND_SPACES_DG_PDELABPRODUCT_HH
#include <tuple>
#include <dune/gdt/playground/mapper/productdgpdelab.hh>
#include <dune/gdt/spaces/interface.hh>
#include <dune/gdt/spaces/dg/interface.hh>
#include <dune/gdt/playground/spaces/dg/pdelab.hh>
namespace Dune {
namespace GDT {
namespace Spaces {
namespace DG {
// forward, to be used in the traits and to allow for specialization
template <class GridViewImp, int polynomialOrder, class RangeFieldImp, size_t rangeDim, size_t rangeDimCols = 1>
class PdelabBasedProduct
{
static_assert(Dune::AlwaysFalse<GridViewImp>::value, "Untested for these dimensions!");
};
namespace internal {
// from
// https://stackoverflow.com/questions/16853552/how-to-create-a-type-list-for-variadic-templates-that-contains-n-times-the-sam
// in the end, we would like to have something like indices< 1, 2, 3 > for N = 3
template <std::size_t...>
struct indices
{
};
// we want to call this with empty Indices, i.e. create_indices< N >::type == indices< 1, 2, 3 > for N = 3
template <std::size_t N, std::size_t... Indices>
struct create_indices : create_indices<N - 1, N - 1, Indices...>
{
};
// terminating template
template <std::size_t... Indices>
struct create_indices<0, Indices...>
{
typedef indices<Indices...> type;
};
// T_aliased< T, Index > is always the type T, no matter what Index is
template <typename T, std::size_t index>
using T_aliased = T;
// make_identical_tuple< T, N >::type is a std::tuple< T, ... , T > with a length of N
template <typename T, std::size_t N, typename I = typename create_indices<N>::type>
struct make_identical_tuple;
template <typename T, std::size_t N, std::size_t... Indices>
struct make_identical_tuple<T, N, indices<Indices...>>
{
using type = std::tuple<T_aliased<T, Indices>...>;
};
template <class GridViewImp, int polynomialOrder, class RangeFieldImp, size_t rangeDim, size_t rangeDimCols>
class PdelabBasedProductTraits
: public PdelabBasedTraits<GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, rangeDimCols>
{
typedef PdelabBasedTraits<GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, rangeDimCols> BaseType;
public:
typedef PdelabBasedProduct<GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, rangeDimCols> derived_type;
using typename BaseType::GridViewType;
static const int polOrder = BaseType::polOrder;
using typename BaseType::BackendType;
using typename BaseType::EntityType;
using typename BaseType::RangeFieldType;
typedef Mapper::ProductDG<BackendType, rangeDim, rangeDimCols> MapperType;
using BaseType::part_view_type;
using BaseType::needs_grid_view;
typedef typename Dune::GDT::Spaces::DG::PdelabBased<GridViewType, polOrder, RangeFieldType, 1, rangeDimCols>
FactorSpaceType;
typedef typename make_identical_tuple<FactorSpaceType, rangeDim>::type SpaceTupleType;
};
} // namespace internal
template <class GridViewImp, int polynomialOrder, class RangeFieldImp, size_t rangeDim>
class PdelabBasedProduct<GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, 1>
: public Dune::GDT::ProductSpaceInterface<internal::PdelabBasedProductTraits<GridViewImp, polynomialOrder,
RangeFieldImp, rangeDim, 1>,
GridViewImp::dimension, rangeDim, 1>,
public PdelabBased<GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, rangeDimCols>
{
typedef PdelabBasedProduct<GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, 1> ThisType;
typedef typename Dune::GDT::ProductSpaceInterface<internal::PdelabBasedProductTraits<GridViewImp, polynomialOrder,
RangeFieldImp, rangeDim, 1>,
GridViewImp::dimension, rangeDim, 1> InterfaceType;
typedef PdelabBased<GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, rangeDimCols> BaseType;
public:
using typename InterfaceType::Traits;
using typename InterfaceType::GridViewType;
using typename InterfaceType::EntityType;
using typename InterfaceType::BaseFunctionSetType;
using typename InterfaceType::MapperType;
using typename InterfaceType::CommunicatorType;
using typename InterfaceType::BackendType;
using InterfaceType::dimDomain;
using InterfaceType::dimRange;
using InterfaceType::dimRangeCols;
typedef typename Traits::SpaceTupleType SpaceTupleType;
typedef typename Traits::FactorSpaceType FactorSpaceType;
PdelabBasedProduct(GridViewType gv)
: BaseType(gv)
, factor_space_(gv)
{
}
PdelabBasedProduct(const ThisType& other)
: BaseType(other)
, factor_space_(other.factor_space_)
{
}
PdelabBasedProduct(ThisType&& source) = default;
ThisType& operator=(const ThisType& other) = delete;
ThisType& operator=(ThisType&& source) = delete;
template <size_t ii>
const FactorSpaceType& factor() const
{
return factor_space_;
}
private:
const FactorSpaceType factor_space_;
}; // class DefaultProduct< ..., 1 >
} // namespace DG
} // namespace Spaces
} // namespace GDT
} // namespace Dune
#endif // DUNE_GDT_PLAYGROUND_SPACES_DG_PDELABPRODUCT_HH
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment