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

Update the implementation of LocalAnalyticGridFunction

parent a2f6d2e9
No related branches found
No related tags found
1 merge request!28Update the implementation of LocalAnalyticGridFunction
Pipeline #10463 failed
...@@ -11,36 +11,23 @@ ...@@ -11,36 +11,23 @@
namespace Dune { namespace Dune {
/// \brief LocalFunction associated to the \ref AnalyticGridFunction
/**
* \tparam LocalContext Context this localFunction can be bound to, e.g. a grid element
* \tparam F Type of a function that can be evaluated in global coordinates.
**/
template <class LocalContext, class F>
class LocalAnalyticGridFunction;
/// \brief Generator for \ref LocalAnalyticGridFunction /// \brief LocalFunction associated to the \ref LocalAnalyticGridFunction
/** /**
* \param ff Function that can be evaluated at global coordinates of the \ref LocalContext * \param LC The local context, e.g., element or intersection.
* \tparam LocalContext Context this localFunction can be bound to, e.g. a grid element * \param F Type of the function that can be evaluated in global coordinates.
**/ */
template <class LocalContext, class FF> template <class LC, class F>
auto localAnalyticGridFunction (FF&& ff)
{
using F = std::decay_t<FF>;
return LocalAnalyticGridFunction<LocalContext, F>{std::forward<FF>(ff)};
}
template <class LC, class Functor>
class LocalAnalyticGridFunction class LocalAnalyticGridFunction
{ {
public: public:
using LocalContext = LC; using LocalContext = LC;
using Geometry = typename LocalContext::Geometry; using Geometry = typename LocalContext::Geometry;
using Functor = F;
using Domain = typename Geometry::GlobalCoordinate; using Domain = typename Geometry::GlobalCoordinate;
using LocalDomain = typename Geometry::LocalCoordinate; using LocalDomain = typename Geometry::LocalCoordinate;
using Range = std::result_of_t<Functor(Domain)>; using Range = std::invoke_result_t<Functor,Domain>;
using Signature = Range(LocalDomain); using Signature = Range(LocalDomain);
public: public:
...@@ -51,10 +38,19 @@ public: ...@@ -51,10 +38,19 @@ public:
: f_(std::forward<FF>(f)) : f_(std::forward<FF>(f))
{} {}
/// \brief Constructor that copies the localContext and the geometry
LocalAnalyticGridFunction (const Functor& f,
const std::optional<LocalContext>& localContext,
const std::optional<Geometry>& geometry)
: f_(f)
, localContext_(localContext)
, geometry_(geometry)
{}
/// \brief bind the LocalFunction to the local context /// \brief bind the LocalFunction to the local context
/** /**
* Stores the localContext and its geometry in a cache variable * Stores the localContext and its geometry in a cache variable
**/ **/
void bind (const LocalContext& localContext) void bind (const LocalContext& localContext)
{ {
localContext_.emplace(localContext); localContext_.emplace(localContext);
...@@ -63,8 +59,8 @@ public: ...@@ -63,8 +59,8 @@ public:
/// \brief unbind the localContext from the localFunction /// \brief unbind the localContext from the localFunction
/** /**
* Reset the geometry * Reset the geometry
**/ **/
void unbind () void unbind ()
{ {
geometry_.reset(); geometry_.reset();
...@@ -73,9 +69,9 @@ public: ...@@ -73,9 +69,9 @@ public:
/// \brief evaluate the stored function in local coordinates /// \brief evaluate the stored function in local coordinates
/** /**
* Transform the local coordinates to global coordinates first, * Transform the local coordinates to global coordinates first,
* then evalute the stored functor. * then evaluate the stored functor.
**/ **/
Range operator() (const LocalDomain& x) const Range operator() (const LocalDomain& x) const
{ {
assert(!!geometry_); assert(!!geometry_);
...@@ -89,6 +85,13 @@ public: ...@@ -89,6 +85,13 @@ public:
return *localContext_; return *localContext_;
} }
/// \brief return the bound geometry.
const Geometry& geometry () const
{
assert(!!geometry_);
return *geometry_;
}
/// \brief obtain the functor /// \brief obtain the functor
const Functor& f () const const Functor& f () const
{ {
...@@ -103,56 +106,39 @@ private: ...@@ -103,56 +106,39 @@ private:
std::optional<Geometry> geometry_; std::optional<Geometry> geometry_;
}; };
/// \brief Derivative of a \ref LocalAnalyticGridFunction /// \brief Derivative of an \ref LocalAnalyticGridFunction
/** /**
* Participates in overload resolution only if the functor `F` is differentiable * Participates in overload resolution only if the functor `F` is differentiable
**/ **/
template <class LC, class F> template <class LC, class F,
auto derivative (const LocalAnalyticGridFunction<LC,F>& t) class DF = std::decay_t<decltype(derivative(std::declval<const F&>()))>>
-> decltype(localAnalyticGridFunction<LC>(derivative(t.f()))) auto derivative (const LocalAnalyticGridFunction<LC,F>& lf)
-> LocalAnalyticGridFunction<LC,DF>
{ {
return localAnalyticGridFunction<LC>(derivative(t.f())); return {derivative(lf.f()), lf.localContext(), lf.geometry()};
} }
/// \brief GridFunction associated to the mapping F
/**
* \tparam Grid The grid type with elements the corresponding LocalFunction can be bound to
* \tparam F Type of a function that can be evaluated in global coordinates.
**/
template <class Grid, class F>
class AnalyticGridFunction;
/// \brief Generator for \ref AnalyticGridFunction /// \brief GridFunction associated to the mapping F
/** /**
* \param ff Function that can be evaluated at global coordinates of the \ref Grid * \tparam G The grid type with elements the corresponding LocalFunction can be bound to
* \tparam Grid The grid type with elements the corresponding LocalFunction can be bound to * \tparam F Type of a function that can be evaluated in global coordinates.
**/ **/
template <class Grid, class FF> template <class G, class F>
auto analyticGridFunction (FF&& ff)
{
using F = std::decay_t<FF>;
return AnalyticGridFunction<Grid, F>{std::forward<FF>(ff)};
}
template <class FF, class Grid>
auto analyticGridFunction (FF&& ff, Grid const& /*grid*/)
{
using F = std::decay_t<FF>;
return AnalyticGridFunction<Grid, F>{std::forward<FF>(ff)};
}
template <class GridType, class Functor>
class AnalyticGridFunction class AnalyticGridFunction
{ {
public: public:
using Grid = GridType; using Grid = G;
using EntitySet = GridEntitySet<Grid,0>; using EntitySet = GridEntitySet<Grid,0>;
using Functor = F;
using Domain = typename EntitySet::GlobalCoordinate; using Domain = typename EntitySet::GlobalCoordinate;
using Range = std::result_of_t<Functor(Domain)>; using Range = std::invoke_result_t<Functor,Domain>;
using Signature = Range(Domain); using Signature = Range(Domain);
using LocalFunction = LocalAnalyticGridFunction<typename EntitySet::Element,Functor>;
public: public:
/// \brief Constructor. Stores the functor f by value /// \brief Constructor. Stores the functor f by value
template <class FF, template <class FF,
...@@ -168,10 +154,9 @@ public: ...@@ -168,10 +154,9 @@ public:
} }
/// \brief construct the \ref LocalAnalyticGridFunction /// \brief construct the \ref LocalAnalyticGridFunction
using LocalFunction = LocalAnalyticGridFunction<typename EntitySet::Element, Functor>;
friend LocalFunction localFunction (const AnalyticGridFunction& t) friend LocalFunction localFunction (const AnalyticGridFunction& t)
{ {
return LocalFunction(t.f_); return LocalFunction{t.f_};
} }
/// \brief obtain the stored \ref GridEntitySet /// \brief obtain the stored \ref GridEntitySet
...@@ -191,15 +176,36 @@ private: ...@@ -191,15 +176,36 @@ private:
EntitySet entitySet_; EntitySet entitySet_;
}; };
/// \brief Derivative of an \ref AnalyticGridFunction /// \brief Derivative of an \ref AnalyticGridFunction
/** /**
* Participates in overload resolution only if the functor `F` is differentiable * Participates in overload resolution only if the functor `F` is differentiable
**/ **/
template <class Grid, class F> template <class G, class F,
auto derivative (const AnalyticGridFunction<Grid,F>& t) class DF = std::decay_t<decltype(derivative(std::declval<const F&>()))>>
-> decltype(analyticGridFunction<Grid>(derivative(t.f()))) auto derivative (const AnalyticGridFunction<G,F>& gf)
-> AnalyticGridFunction<G,DF>
{
return {derivative(gf.f())};
}
/// \brief Generator for \ref AnalyticGridFunction
/**
* \param ff Function that can be evaluated at global coordinates of the \ref Grid
* \tparam Grid The grid type with elements the corresponding LocalFunction can be bound to
**/
template <class Grid, class FF>
auto analyticGridFunction (FF&& ff)
{
using F = std::decay_t<FF>;
return AnalyticGridFunction<Grid, F>{std::forward<FF>(ff)};
}
template <class FF, class Grid>
auto analyticGridFunction (FF&& ff, Grid const& /*grid*/)
{ {
return analyticGridFunction<Grid>(derivative(t.f())); using F = std::decay_t<FF>;
return AnalyticGridFunction<Grid, F>{std::forward<FF>(ff)};
} }
} // end namespace Dune } // end namespace Dune
......
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