Skip to content
Snippets Groups Projects
Commit a23ecf47 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

added new type erasure for vtkfunctions

parent 5378fd5b
No related branches found
No related tags found
No related merge requests found
......@@ -4,13 +4,13 @@
#include <dune/common/std/type_traits.hh>
#include <dune/functions/common/signature.hh>
#include <dune/functions/common/typeerasure.hh>
#include <dune/grid/io/file/vtk/function.hh>
namespace Dune { namespace experimental
{
/// An abstract base class for LocalFunctions
template <class GridView>
class VTKLocalFunctionInterface
class VtkLocalFunctionInterface
{
public:
using Entity = typename GridView::template Codim<0>::Entity;
......@@ -26,140 +26,208 @@ namespace Dune { namespace experimental
virtual double evaluate (int comp, LocalCoordinate const& xi) const = 0;
/// Virtual destructor
virtual ~VTKLocalFunctionInterface () = default;
virtual ~VtkLocalFunctionInterface () = default;
};
template <class GridView>
struct VTKLocalFunctionImpl
/// Type erasure for dune-functions LocalFunction interface
template <class GridView, class LocalFunction>
class LocalFunctionWrapper
: public VtkLocalFunctionInterface<GridView>
{
template <class Wrapper>
class Model : public Wrapper
{
public:
using Wrapper::Wrapper;
using Function = typename Wrapper::Wrapped;
using Interface = VTKLocalFunctionInterface<GridView>;
using Entity = typename Interface::Entity;
using LocalCoordinate = typename Interface::LocalCoordinate;
template <class F, class D>
using Range = std::decay_t<decltype(std::declval<F>()(std::declval<D>()))>;
template <class F, class D>
using VectorValued = decltype(std::declval<Range<F,D>>()[0u]);
virtual void bind (Entity const& entity) override
{
this->get().bind(entity);
}
virtual void unbind () override
{
this->get().unbind();
}
virtual double evaluate (int comp, LocalCoordinate const& xi) const override
{
return evaluateImpl(comp, xi, Std::is_detected<VectorValued,Function,LocalCoordinate>{});
}
private:
// Evaluate a component of a vector valued data
double evaluateImpl (int comp, LocalCoordinate const& xi, std::true_type) const
{
auto y = this->get()(xi);
return comp < y.size() ? y[comp] : 0.0;
}
// Return the scalar values
double evaluateImpl (int comp, LocalCoordinate const& xi, std::false_type) const
{
assert(comp == 0);
return this->get()(xi);
}
};
using Self = LocalFunctionWrapper;
using Interface = VtkLocalFunctionInterface<GridView>;
using Entity = typename Interface::Entity;
using LocalCoordinate = typename Interface::LocalCoordinate;
template <class F, class D>
using Range = std::decay_t<decltype(std::declval<F>()(std::declval<D>()))>;
template <class F, class D>
using VectorValued = decltype(std::declval<Range<F,D>>()[0u]);
public:
template <class LocalFct, disableCopyMove<Self, LocalFct> = 0>
LocalFunctionWrapper (LocalFct&& localFct)
: localFct_(std::forward<LocalFct>(localFct))
{}
virtual void bind (Entity const& entity) override
{
localFct_.bind(entity);
}
virtual void unbind () override
{
localFct_.unbind();
}
virtual double evaluate (int comp, LocalCoordinate const& xi) const override
{
return evaluateImpl(comp, xi, Std::is_detected<VectorValued,LocalFunction,LocalCoordinate>{});
}
private:
// Evaluate a component of a vector valued data
double evaluateImpl (int comp, LocalCoordinate const& xi, std::true_type) const
{
auto y = localFct_(xi);
return comp < y.size() ? y[comp] : 0.0;
}
// Return the scalar values
double evaluateImpl (int comp, LocalCoordinate const& xi, std::false_type) const
{
assert(comp == 0);
return localFct_(xi);
}
private:
LocalFunction localFct_;
};
/// Type erasure for Legacy VTKFunction
template <class GridView>
class VTKLocalFunction
: public Functions::TypeErasureBase<VTKLocalFunctionInterface<GridView>,
VTKLocalFunctionImpl<GridView>::template Model>
class VTKLocalFunctionWrapper
: public VtkLocalFunctionInterface<GridView>
{
using Super = Functions::TypeErasureBase<VTKLocalFunctionInterface<GridView>,
VTKLocalFunctionImpl<GridView>::template Model>;
using Interface = VtkLocalFunctionInterface<GridView>;
using Entity = typename Interface::Entity;
using LocalCoordinate = typename Interface::LocalCoordinate;
public:
VTKLocalFunctionWrapper (std::shared_ptr<VTKFunction<GridView> const> const& fct)
: fct_(fct)
{}
virtual void bind (Entity const& entity) override
{
entity_ = &entity;
}
virtual void unbind () override
{
entity_ = nullptr;
}
virtual double evaluate (int comp, LocalCoordinate const& xi) const override
{
return fct_->evaluate(comp, *entity_, xi);
}
private:
std::shared_ptr<VTKFunction<GridView> const> fct_;
Entity const* entity_;
};
template <class GridView>
class VtkLocalFunction
{
using Self = VtkLocalFunction;
using Entity = typename GridView::template Codim<0>::Entity;
using LocalCoordinate = typename Entity::Geometry::LocalCoordinate;
template <class LF, class E>
using HasBind = decltype(std::declval<LF>().bind(std::declval<E>()));
public:
template <class F, disableCopyMove<VTKLocalFunction, F> = 0>
VTKLocalFunction (F&& f)
: Super(std::forward<F>(f))
// Store wrapper around dune-function LocalFunction
template <class LocalFct, disableCopyMove<Self, LocalFct> = 0,
std::enable_if_t<Std::is_detected<HasBind, LocalFct, Entity>::value,int> = 0>
VtkLocalFunction (LocalFct&& lf)
: localFct_(std::make_unique<LocalFunctionWrapper<GridView, std::decay_t<LocalFct>>>(std::forward<LocalFct>(lf)))
{}
// store wrapper around legacy VTKFunction
VtkLocalFunction (std::shared_ptr<VTKFunction<GridView> const> const& lf)
: localFct_(std::make_unique<VTKLocalFunctionWrapper<GridView>>(lf))
{}
VTKLocalFunction () = default;
VtkLocalFunction () = default;
/// Bind the function to the grid entity
void bind (Entity const& entity)
{
this->asInterface().bind(entity);
localFct_->bind(entity);
}
/// Unbind from the currently bound entity
void unbind ()
{
this->asInterface().unbind();
localFct_->unbind();
}
/// Evaluate the `comp` component of the Range value at local coordinate `xi`
double evaluate (int comp, LocalCoordinate const& xi) const
{
return this->asInterface().evaluate(comp, xi);
return localFct_->evaluate(comp, xi);
}
private:
std::shared_ptr<VtkLocalFunctionInterface<GridView>> localFct_;
};
// ---------------------------------------------------------------------------
/// An abstract base class for GlobalFunctions
template <class GridView>
class VTKFunctionInterface
class VtkFunctionInterface
{
public:
/// Create a local function
virtual VTKLocalFunction<GridView> makeLocalFunction () const = 0;
virtual VtkLocalFunction<GridView> makeLocalFunction () const = 0;
/// Virtual destructor
virtual ~VTKFunctionInterface () = default;
virtual ~VtkFunctionInterface () = default;
};
template <class GridView>
struct VTKFunctionImpl
template <class GridView, class GridViewFunction>
class GridViewFunctionWrapper
: public VtkFunctionInterface<GridView>
{
template <class Wrapper>
class Model : public Wrapper
{
public:
using Wrapper::Wrapper;
virtual VTKLocalFunction<GridView> makeLocalFunction () const override
{
return VTKLocalFunction<GridView>{localFunction(this->get())};
}
};
using Self = GridViewFunctionWrapper;
public:
template <class GVFct, disableCopyMove<Self, GVFct> = 0>
GridViewFunctionWrapper (GVFct&& gvFct)
: gvFct_(std::forward<GVFct>(gvFct))
{}
virtual VtkLocalFunction<GridView> makeLocalFunction () const override
{
return VtkLocalFunction<GridView>{localFunction(gvFct_)};
}
private:
GridViewFunction gvFct_;
};
template <class GridView>
class VTKFunction
: public Functions::TypeErasureBase<VTKFunctionInterface<GridView>,
VTKFunctionImpl<GridView>::template Model>
class VTKFunctionWrapper
: public VtkFunctionInterface<GridView>
{
using Super = Functions::TypeErasureBase<VTKFunctionInterface<GridView>,
VTKFunctionImpl<GridView>::template Model>;
public:
VTKFunctionWrapper (std::shared_ptr<VTKFunction<GridView> const> const& fct)
: fct_(fct)
{}
virtual VtkLocalFunction<GridView> makeLocalFunction () const override
{
return VtkLocalFunction<GridView>{fct_};
}
private:
std::shared_ptr<VTKFunction<GridView> const> fct_;
};
template <class GridView>
class VtkFunction
{
template <class F>
using HasLocalFunction = decltype(localFunction(std::declval<F>()));
......@@ -168,37 +236,42 @@ namespace Dune { namespace experimental
public:
template <class F,
std::enable_if_t<Std::is_detected<HasLocalFunction,F>::value, int> = 0,
class Range = typename Functions::SignatureTraits<Signature<F>>::Range>
VTKFunction (F&& f, std::string name, int ncomps = 1,
VtkFunction (F&& f, std::string name, int ncomps = 1,
Vtk::DataTypes type = Vtk::Map::type<Range>)
: Super(std::forward<F>(f))
: fct_(std::make_unique<GridViewFunctionWrapper<GridView,std::decay_t<F>>>(std::forward<F>(f)))
, name_(std::move(name))
, ncomps_(ncomps > 3 ? 9 : ncomps > 1 ? 3 : 1) // tensor, vector, or scalar
, type_(type)
{
static_assert(Std::is_detected<HasLocalFunction,F>::value,
"Requires A GridFunction to be passed to the VTKFunction.");
}
{}
template <class F,
std::enable_if_t<Std::is_detected<HasLocalFunction,F>::value, int> = 0,
std::enable_if_t<not Std::is_detected<Signature,F>::value,int> = 0>
VTKFunction (F&& f, std::string name, int ncomps = 1,
VtkFunction (F&& f, std::string name, int ncomps = 1,
Vtk::DataTypes type = Vtk::FLOAT32)
: Super(std::forward<F>(f))
: fct_(std::make_unique<GridViewFunctionWrapper<GridView,std::decay_t<F>>>(std::forward<F>(f)))
, name_(std::move(name))
, ncomps_(ncomps > 3 ? 9 : ncomps > 1 ? 3 : 1) // tensor, vector, or scalar
, type_(type)
{
static_assert(Std::is_detected<HasLocalFunction,F>::value,
"Requires A GridFunction to be passed to the VTKFunction.");
}
{}
VtkFunction (std::shared_ptr<VTKFunction<GridView> const> const& fct,
std::string name, int ncomps = 1,
Vtk::DataTypes type = Vtk::FLOAT32)
: fct_(std::make_unique<VTKFunctionWrapper<GridView>>(fct))
, name_(std::move(name))
, ncomps_(ncomps > 3 ? 9 : ncomps > 1 ? 3 : 1) // tensor, vector, or scalar
, type_(type)
{}
VTKFunction () = default;
VtkFunction () = default;
/// Create a LocalFunction
friend VTKLocalFunction<GridView> localFunction (VTKFunction const& self)
friend VtkLocalFunction<GridView> localFunction (VtkFunction const& self)
{
return self.asInterface().makeLocalFunction();
return self.fct_->makeLocalFunction();
}
/// Return a name associated with the function
......@@ -220,6 +293,7 @@ namespace Dune { namespace experimental
}
private:
std::shared_ptr<VtkFunctionInterface<GridView>> fct_;
std::string name_;
int ncomps_ = 1;
Vtk::DataTypes type_;
......
......@@ -21,8 +21,8 @@ namespace Dune { namespace experimental
protected:
static constexpr int dimension = GridView::dimension;
using GlobalFunction = VTKFunction<GridView>;
using LocalFunction = VTKLocalFunction<GridView>;
using GlobalFunction = VtkFunction<GridView>;
using LocalFunction = VtkLocalFunction<GridView>;
using pos_type = typename std::ostream::pos_type;
enum PositionTypes {
......
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