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