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)
//
// Contributors: Tobias Leibner
#ifndef DUNE_GDT_PLAYGROUND_SPACES_DG_PDELABPRODUCT_HH
#define DUNE_GDT_PLAYGROUND_SPACES_DG_PDELABPRODUCT_HH
#include <tuple>
#include <dune/stuff/common/tuple.hh>
#include <dune/gdt/spaces/interface.hh>
#include <dune/gdt/spaces/dg/interface.hh>
#include <dune/gdt/playground/spaces/dg/dune-pdelab-wrapper.hh>
#include <dune/gdt/playground/spaces/mapper/dune-pdelab-wrapper.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 {
template <class GridViewImp, int polynomialOrder, class RangeFieldImp, size_t rangeDim, size_t rangeDimCols>
class PdelabBasedProductTraits
: public DunePdelabDgSpaceWrapperTraits<GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, rangeDimCols>
typedef DunePdelabDgSpaceWrapperTraits<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;
static const size_t dimDomain = GridViewType::dimension;
static const size_t dimRange = rangeDim;
static const size_t dimRangeCols = rangeDimCols;
using typename BaseType::BackendType;
using typename BaseType::EntityType;
using typename BaseType::RangeFieldType;
typedef ProductDgMapper<BackendType, rangeDim, rangeDimCols> MapperType;
using BaseType::part_view_type;
using BaseType::needs_grid_view;
typedef typename Dune::GDT::DunePdelabDgSpaceWrapper<GridViewType, polOrder, RangeFieldType, 1, dimRangeCols>
FactorSpaceType;
typedef typename DSC::make_identical_tuple<FactorSpaceType, dimRange>::type SpaceTupleType;
};
} // namespace internal
template <class GridViewImp, int polynomialOrder, class RangeFieldImp, size_t rangeDim>
class PdelabBasedProduct<GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, 1>
: public Dune::GDT::SpaceInterface<internal::PdelabBasedProductTraits<GridViewImp, polynomialOrder, RangeFieldImp,
rangeDim, 1>,
GridViewImp::dimension, rangeDim, 1>,
public Dune::GDT::ProductSpaceInterface<internal::PdelabBasedProductTraits<GridViewImp, polynomialOrder,
RangeFieldImp, rangeDim, 1>,
GridViewImp::dimension, rangeDim, 1>
{
typedef PdelabBasedProduct<GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, 1> ThisType;
typedef typename Dune::GDT::SpaceInterface<internal::PdelabBasedProductTraits<GridViewImp, polynomialOrder,
RangeFieldImp, rangeDim, 1>,
GridViewImp::dimension, rangeDim, 1> BaseType;
typedef typename internal::PdelabBasedProductTraits<GridViewImp, polynomialOrder, RangeFieldImp, rangeDim, 1> Traits;
using typename BaseType::GridViewType;
using typename BaseType::EntityType;
using typename BaseType::BaseFunctionSetType;
using typename BaseType::MapperType;
using typename BaseType::CommunicatorType;
using typename BaseType::BackendType;
using BaseType::dimDomain;
using BaseType::dimRange;
using BaseType::dimRangeCols;
typedef typename Traits::SpaceTupleType SpaceTupleType;
typedef typename Traits::FactorSpaceType FactorSpaceType;
PdelabBasedProduct(GridViewType gv)
: grid_view_(gv)
, factor_space_(grid_view_)
, factor_mapper_(factor_space_.backend())
, communicator_(CommunicationChooser<GridViewImp>::create(grid_view_))
, communicator_prepared_(false)
{
}
PdelabBasedProduct(const ThisType& other)
: grid_view_(other.grid_view_)
, factor_space_(other.factor_space_)
, factor_mapper_(other.factor_mapper_)
, communicator_(CommunicationChooser<GridViewImp>::create(grid_view_))
, communicator_prepared_(false)
// make sure our new communicator is prepared if other's was
if (other.communicator_prepared_)
const auto& DUNE_UNUSED(comm) = this->communicator();
}
PdelabBasedProduct(ThisType&& source) = default;
ThisType& operator=(const ThisType& other) = delete;
ThisType& operator=(ThisType&& source) = delete;
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
const GridViewType& grid_view() const
{
return grid_view_;
}
const BackendType& backend() const
{
return factor_space_.backend();
}
const MapperType& mapper() const
{
return factor_mapper_;
}
BaseFunctionSetType base_function_set(const EntityType& entity) const
{
return BaseFunctionSetType(backend(), entity);
}
CommunicatorType& communicator() const
{
std::lock_guard<std::mutex> DUNE_UNUSED(gg)(communicator_mutex_);
if (!communicator_prepared_)
communicator_prepared_ = CommunicationChooser<GridViewType>::prepare(*this, *communicator_);
return *communicator_;
} // ... communicator(...)
template <size_t ii>
const FactorSpaceType& factor() const
{
return factor_space_;
}
private:
const GridViewType grid_view_;
const FactorSpaceType factor_space_;
const MapperType factor_mapper_;
mutable std::unique_ptr<CommunicatorType> communicator_;
mutable bool communicator_prepared_;
mutable std::mutex communicator_mutex_;