Skip to content
Snippets Groups Projects
pdelabproduct.hh 5.98 KiB
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>
  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;

  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_;
}; // class DefaultProduct< ..., 1 >


} // namespace DG
} // namespace Spaces
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_PLAYGROUND_SPACES_DG_PDELABPRODUCT_HH