Commit 601d4708 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Merge branch 'issue/grid_function_creator' into 'develop'

Issue/grid function creator

See merge request !12
parents 45abb132 d6701e47
Pipeline #1036 passed with stage
in 3 minutes and 16 seconds
......@@ -37,7 +37,7 @@
*
* 4. Integrate a GridFunction on a GridView:
* ```
* auto value = integrate(Expression, prob.leafGridView());
* auto value = integrate(Expression, prob.gridView());
* ```
*
* **Remarks:**
......@@ -51,7 +51,7 @@
* and arithmetic operator operator+, operator-, or operator*.
*
* If the polynomial order can not be deduced, the compiler gives an error.
* Then, these functions, accept an additional argument, to provide either the
* Then, these functions accept an additional argument, to provide either the
* polynomial degree of the expression, or a quadrature rule explicitly.
*
* *Examples:*
......@@ -67,47 +67,3 @@
#include <amdis/gridfunctions/DerivativeGridFunction.hpp>
#include <amdis/gridfunctions/FunctorGridFunction.hpp>
#include <amdis/gridfunctions/OperationsGridFunction.hpp>
namespace AMDiS
{
/// \brief Generator for Gridfunctions from Expressions (PreGridfunctions)
/**
* \ingroup GridFunctions
* Create an evaluable GridFunction from an expression that itself can not be
* evaluated. Therefore, it binds the GridFunction to a GridView.
*
* **Example:**
* ```
* ProblemStat<Traits> prob("name");
* prob.initialize(INIT_ALL);
*
* auto gridFct = makeGridFunction(Expression, prob.leafGridView());
*
* // eval GridFunction at GlobalCoordinates
* auto value = gridFct(Dune::FieldVector<double,2>{1.0, 2.0});
*
* auto localFct = localFunction(gridFct);
* for (auto const& element : elements(prob.leafGridView())) {
* localFct.bind(element);
* // eval LocalFunction at local coordinates
* auto x = localFct(element.geometry().center());
* localFct.unbind();
* }
* ```
*
* In contrast to Expressions, GridFunctions can be evaluated, and
* - have the free-function \ref localFunction() to obtain a LocalFunction
* - its LocalFunctions have the free-function \ref order() to obtain the
* polynomial order of the Expression (if available)
* - its LocalFunctions have the free-function \ref derivative() to
* differentiate the Expression with respect to global Coordinates.
* A derivative Expression can be created, using \ref gradientAtQP() that
* can be converted to a GridFunction afterwards.
**/
template <class PreGridFct, class GridView>
decltype(auto) makeGridFunction(PreGridFct&& preGridFct, GridView const& gridView)
{
return Impl::makeGridFunctionImpl(std::forward<PreGridFct>(preGridFct), gridView, Dune::PriorityTag<10>{});
}
} // end namespace AMDiS
......@@ -156,6 +156,17 @@ namespace AMDiS
template <class Function>
struct AnalyticPreGridFunction
{
using Self = AnalyticPreGridFunction;
struct Creator
{
template <class GridView>
static auto create(Self const& self, GridView const& gridView)
{
return AnalyticGridFunction<Function, GridView>{self.fct_, gridView};
}
};
Function fct_;
};
......@@ -185,22 +196,14 @@ namespace AMDiS
}
namespace Impl
template <class Function>
struct GridFunctionCreator<Function, std::enable_if_t<Concepts::CallableDomain<Function>>>
{
/// Generator function for \ref AnalyticGridFunction expressions from callable functions.
template <class Function, class GridView,
REQUIRES(Concepts::CallableDomain<Function>)>
auto makeGridFunctionImpl(Function const& f, GridView const& gridView, Dune::PriorityTag<3>)
template <class GridView>
static auto create(Function const& fct, GridView const& gridView)
{
return AnalyticGridFunction<Function, GridView>{f, gridView};
}
/// Generator function for \ref AnalyticGridFunction expressions from \ref AnalyticPreGridFunction.
template <class Function, class GridView>
auto makeGridFunctionImpl(AnalyticPreGridFunction<Function> const& pre, GridView const& gridView, Dune::PriorityTag<3>)
{
return AnalyticGridFunction<Function, GridView>{pre.fct_, gridView};
return AnalyticGridFunction<Function, GridView>{fct, gridView};
}
};
} // end namespace Impl
} // end namespace AMDiS
......@@ -166,15 +166,14 @@ namespace AMDiS
} // end namespace Concepts
namespace Impl
template <class Value>
struct GridFunctionCreator<Value, std::enable_if_t<Concepts::ConstantToGridFunction<Value>>>
{
/// Generator for a GridFunction representing a constant value
template <class T, class GridView,
REQUIRES(Concepts::ConstantToGridFunction<T>)>
auto makeGridFunctionImpl(T const& value, GridView const& gridView, Dune::PriorityTag<2>)
template <class GridView>
static auto create(Value const& value, GridView const& gridView)
{
return ConstantGridFunction<T,GridView>{value, gridView};
return ConstantGridFunction<Value,GridView>{value, gridView};
}
};
} // end namespace Impl
} // end namespace AMDiS
......@@ -5,6 +5,8 @@
#include <dune/common/diagonalmatrix.hh>
#include <dune/common/typeutilities.hh>
#include <amdis/gridfunctions/AnalyticGridFunction.hpp>
namespace AMDiS
{
namespace Operation
......@@ -16,13 +18,24 @@ namespace AMDiS
/// A functor that evaluates to the global coordinates
struct CoordsFunction
{
using Self = CoordsFunction;
struct Creator
{
template <class GridView>
static auto create(Self const& f, GridView const& gridView)
{
return AnalyticGridFunction<Self, GridView>{f, gridView};
}
};
template <class T, int N>
Dune::FieldVector<T, N> const& operator()(Dune::FieldVector<T, N> const& x) const
{
return x;
}
friend int order(CoordsFunction const& /*f*/, int /*d*/)
friend int order(Self const& /*f*/, int /*d*/)
{
return 1;
}
......@@ -45,6 +58,18 @@ namespace AMDiS
/// A functor that evaluates to a component of the global coordinates
struct CoordsCompFunction
{
using Self = CoordsCompFunction;
struct Creator
{
template <class GridView>
static auto create(Self const& f, GridView const& gridView)
{
return AnalyticGridFunction<Self, GridView>{f, gridView};
}
};
public:
/// Constructor. Stores the component `comp` of the coordinates.
explicit CoordsCompFunction(int comp)
: comp_(comp)
......@@ -56,7 +81,7 @@ namespace AMDiS
return x[comp_];
}
friend int order(CoordsCompFunction const& /*f*/, int /*d*/)
friend int order(Self const& /*f*/, int /*d*/)
{
return 1;
}
......@@ -80,7 +105,7 @@ namespace AMDiS
int comp_;
};
friend Derivative partial(CoordsCompFunction const& f, index_t<0>)
friend Derivative partial(Self const& f, index_t<0>)
{
return Derivative{f.comp_};
}
......@@ -116,21 +141,4 @@ namespace AMDiS
: std::true_type {};
}
namespace Impl
{
/// Generator for GridFunction from the pre-GridFunction \ref CoordsFunction
template <class GridView>
auto makeGridFunctionImpl(Operation::CoordsFunction const& f, GridView const& gridView, Dune::PriorityTag<1>)
{
return makeAnalyticGridFunction(f, gridView);
}
/// Generator for GridFunction from the pre-GridFunction \ref CoordsCompFunction
template <class GridView>
auto makeGridFunctionImpl(Operation::CoordsCompFunction const& f, GridView const& gridView, Dune::PriorityTag<1>)
{
return makeAnalyticGridFunction(f, gridView);
}
} // end namespace Impl
} // end namespace AMDiS
......@@ -88,7 +88,18 @@ namespace AMDiS
template <class Expr>
struct DerivativePreGridFunction
{
Expr expr;
using Self = DerivativePreGridFunction;
struct Creator
{
template <class GridView>
static auto create(Self const& self, GridView const& gridView)
{
return derivative(makeGridFunction(self.expr_, gridView));
}
};
Expr expr_;
};
namespace Traits
......@@ -116,14 +127,4 @@ namespace AMDiS
/** @} **/
namespace Impl
{
/// Generator function for \ref AnalyticGridFunction expressions from \ref AnalyticPreGridFunction.
template <class Expr, class GridView>
auto makeGridFunctionImpl(DerivativePreGridFunction<Expr> const& pre, GridView const& gridView, Dune::PriorityTag<3>)
{
return derivative(Impl::makeGridFunctionImpl(pre.expr, gridView, Dune::PriorityTag<10>{}));
}
} // end namespace Impl
} // end namespace AMDiS
......@@ -248,12 +248,27 @@ namespace AMDiS
template <class Functor, class... GridFunctions>
struct FunctorPreGridFunction
{
using Self = FunctorPreGridFunction;
struct Creator
{
template <class GridView>
static auto create(Self const& self, GridView const& gridView)
{
return Dune::Std::apply([&](auto const&... pgf) {
return makeFunctorGridFunction(self.fct_,
makeGridFunction(pgf, gridView)...);
}, self.gridFcts_);
}
};
template <class... GridFcts>
explicit FunctorPreGridFunction(Functor const& fct, GridFcts&&... gridFcts)
: fct_(fct)
, gridFcts_(std::forward<GridFcts>(gridFcts)...)
{}
private:
Functor fct_;
std::tuple<GridFunctions...> gridFcts_;
};
......@@ -284,19 +299,4 @@ namespace AMDiS
/** @} **/
namespace Impl
{
/// Generator function from a \ref FunctorPreGridFunction to a \ref FunctorGridFunction.
template <class Functor, class... GridFcts, class GridView>
auto makeGridFunctionImpl(FunctorPreGridFunction<Functor, GridFcts...> const& preGridFct,
GridView const& gridView,
Dune::PriorityTag<5>)
{
return Dune::Std::apply([&](auto const&... pgf) {
return makeFunctorGridFunction(preGridFct.fct_,
Impl::makeGridFunctionImpl(pgf, gridView, Dune::PriorityTag<10>{})...);
}, preGridFct.gridFcts_);
}
} // end namespace Impl
} // end namespace AMDiS
......@@ -136,15 +136,71 @@ namespace AMDiS
return valid;
}
#ifndef DOXYGEN
template <class PreGridFct, class = void>
struct GridFunctionCreator
: PreGridFct::Creator {};
namespace Impl
{
// Functions that forwards GridFunctions
template <class GridFct, class GridView,
REQUIRES(Concepts::GridFunction<GridFct>)>
auto const& makeGridFunctionImpl(GridFct const& gridFct, GridView const& /*gridView*/, Dune::PriorityTag<10>)
// Specialization for type that is already a GridFunction
template <class GridFct, class GridView>
GridFct const& makeGridFunctionImpl(GridFct const& gridFct, GridView const& /*gridView*/, std::true_type)
{
return gridFct;
}
} // end namespace Impl
// Use the \ref GridFunctionCreator to create a gridFunction from a preGridFunction
template <class PreGridFct, class GridView,
class Creator = GridFunctionCreator<PreGridFct>>
decltype(auto) makeGridFunctionImpl(PreGridFct const& preGridFct, GridView const& gridView, std::false_type)
{
return Creator::create(preGridFct, gridView);
}
}
#endif
/// \brief Generator for Gridfunctions from Expressions (PreGridfunctions)
/**
* \ingroup GridFunctions
* Create an evaluable GridFunction from an expression that itself can not be
* evaluated. Therefore, it binds the GridFunction to a GridView.
*
* **Example:**
* ```
* ProblemStat<Traits> prob("name");
* prob.initialize(INIT_ALL);
*
* auto gridFct = makeGridFunction(Expression, prob.leafGridView());
*
* // eval GridFunction at GlobalCoordinates
* auto value = gridFct(Dune::FieldVector<double,2>{1.0, 2.0});
*
* auto localFct = localFunction(gridFct);
* for (auto const& element : elements(prob.leafGridView())) {
* localFct.bind(element);
* // eval LocalFunction at local coordinates
* auto x = localFct(element.geometry().center());
* localFct.unbind();
* }
* ```
*
* In contrast to Expressions, GridFunctions can be evaluated and
* - have the free-function \ref localFunction() to obtain a LocalFunction
* - its LocalFunctions have the free-function \ref order() to obtain the
* polynomial order of the Expression (if available)
* - its LocalFunctions have the free-function \ref derivative() to
* differentiate the Expression with respect to global Coordinates.
* A derivative Expression can be created, using \ref gradientAtQP() that
* can be converted to a GridFunction afterwards.
**/
template <class PreGridFct, class GridView>
decltype(auto) makeGridFunction(PreGridFct const& preGridFct, GridView const& gridView)
{
using isGridFct = bool_t<Concepts::GridFunction<PreGridFct>>;
return Impl::makeGridFunctionImpl(preGridFct, gridView, isGridFct{});
}
} // end namespace AMDiS
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment