Commit e37c96cd authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Added LocalContext to template parameters of GridFunction

parent 4ec0e315
...@@ -32,6 +32,8 @@ int main(int argc, char** argv) ...@@ -32,6 +32,8 @@ int main(int argc, char** argv)
auto opForce = makeOperator(tag::test{}, [](auto const& x) { return -1.0; }, 0); auto opForce = makeOperator(tag::test{}, [](auto const& x) { return -1.0; }, 0);
prob.addVectorOperator(opForce, _0); prob.addVectorOperator(opForce, _0);
auto opForce2 = makeOperator(tag::test{}, [](auto const& x) { return -2.0; }, 0);
prob.addVectorOperator(BoundaryType{0}, opForce2, _0);
// set boundary condition // set boundary condition
auto predicate = [](auto const& x){ return x[0] < 1.e-8 || x[1] < 1.e-8; }; // define boundary auto predicate = [](auto const& x){ return x[0] < 1.e-8 || x[1] < 1.e-8; }; // define boundary
......
...@@ -151,7 +151,7 @@ namespace AMDiS ...@@ -151,7 +151,7 @@ namespace AMDiS
Geometry const* geometry_; Geometry const* geometry_;
// The localGeometry may be constructed only if needed // The localGeometry may be constructed only if needed
Dune::Std::optional<LocalGeometry> localGeometry_; mutable Dune::Std::optional<LocalGeometry> localGeometry_;
}; };
} // end namespace AMDiS } // end namespace AMDiS
...@@ -24,31 +24,29 @@ namespace AMDiS ...@@ -24,31 +24,29 @@ namespace AMDiS
* *
* The class is specialized, by deriving from it, in \ref GridFunctionOperator. * The class is specialized, by deriving from it, in \ref GridFunctionOperator.
* *
* \tparam LocalContext The Element or Intersection type
* \tparam GridFunction The GridFunction, a LocalFunction is created from, and * \tparam GridFunction The GridFunction, a LocalFunction is created from, and
* that is evaluated at quadrature points. * that is evaluated at quadrature points.
* \tparam QuadratureCreator A functor that provides a \ref Dune::QuadratureRule.
* *
* **Requirements:** * **Requirements:**
* - `LocalContext` models either Entity (of codim 0) or Intersection
* - `GridFunction` models the \ref Concepts::GridFunction * - `GridFunction` models the \ref Concepts::GridFunction
* - `QuadratureCreator` models \ref Concepts::Callable<Dune::GeometryType, LocalFunction, F>
* where `F` is a functor of the signature `int(int)` that calculates the
* degree of the (bi)linear-form. The argument passed to `F` is the polynomial
* order of the GridFunction.
**/ **/
template <class Derived, class GridFunction> template <class Derived, class LocalContext, class GridFunction>
class GridFunctionOperatorBase class GridFunctionOperatorBase
: public LocalOperator<Derived> : public LocalOperator<Derived, LocalContext>
{ {
using LocalFunction = decltype(localFunction(std::declval<GridFunction>())); using LocalFunction = decltype(localFunction(std::declval<GridFunction>()));
using Element = typename GridFunction::EntitySet::Element;
using Element = typename Impl::ContextTypes<LocalContext>::Entity;
using Geometry = typename Element::Geometry; using Geometry = typename Element::Geometry;
using LocalCoordinate = typename GridFunction::EntitySet::LocalCoordinate; using LocalCoordinate = typename GridFunction::EntitySet::LocalCoordinate;
using QuadFactory = QuadratureFactory<typename Geometry::ctype, Element::dimension, LocalFunction>; using QuadFactory = QuadratureFactory<typename Geometry::ctype, LocalContext::mydimension, LocalFunction>;
public: public:
/// \brief Constructor. Stores a copy of `expr`. /// \brief Constructor. Stores a copy of `gridFct`.
/** /**
* An expression operator takes an expression, following the interface of * An expression operator takes an expression, following the interface of
* \ref ExpressionBase, and stores a copy. Additionally, it gets the * \ref ExpressionBase, and stores a copy. Additionally, it gets the
...@@ -85,10 +83,8 @@ namespace AMDiS ...@@ -85,10 +83,8 @@ namespace AMDiS
void bind_impl(Element const& element, Geometry const& geometry) void bind_impl(Element const& element, Geometry const& geometry)
{ {
assert( bool(quadFactory_) ); assert( bool(quadFactory_) );
if (!this->bound_) { localFct_.bind(element);
localFct_.bind(element); quadFactory_->bind(localFct_);
quadFactory_->bind(localFct_);
}
} }
/// Unbinds operator from element. /// Unbinds operator from element.
...@@ -100,7 +96,7 @@ namespace AMDiS ...@@ -100,7 +96,7 @@ namespace AMDiS
template <class PreQuadFactory> template <class PreQuadFactory>
void setQuadFactory(PreQuadFactory const& pre) void setQuadFactory(PreQuadFactory const& pre)
{ {
quadFactory_ = makeQuadratureFactoryPtr<typename Geometry::ctype, Element::dimension, LocalFunction>(pre); quadFactory_ = makeQuadratureFactoryPtr<typename Geometry::ctype, LocalContext::mydimension, LocalFunction>(pre);
} }
protected: protected:
...@@ -131,13 +127,16 @@ namespace AMDiS ...@@ -131,13 +127,16 @@ namespace AMDiS
/// Assign each element type a quadrature rule /// Assign each element type a quadrature rule
std::shared_ptr<QuadFactory> quadFactory_ = std::make_shared<QuadFactory>(); std::shared_ptr<QuadFactory> quadFactory_ = std::make_shared<QuadFactory>();
int termOrder_ = 0; //< the derivative order of this operator /// the derivative order of this operator (in {0, 1, 2})
int termOrder_ = 0;
}; };
/// \brief The transposed operator, implemented in term of its transposed by
/// calling \ref getElementMatrix with inverted arguments.
template <class Derived, class Transposed> template <class Derived, class Transposed>
class GridFunctionOperatorTransposed class GridFunctionOperatorTransposed
: public LocalOperator<Derived> : public LocalOperator<Derived, typename Transposed::LocalContext>
{ {
template <class T, class... Args> template <class T, class... Args>
using Constructable = decltype( new T(std::declval<Args>()...) ); using Constructable = decltype( new T(std::declval<Args>()...) );
...@@ -152,12 +151,12 @@ namespace AMDiS ...@@ -152,12 +151,12 @@ namespace AMDiS
template <class Element, class Geometry> template <class Element, class Geometry>
void bind_impl(Element const& element, Geometry const& geometry) void bind_impl(Element const& element, Geometry const& geometry)
{ {
transposedOp_.bind(element, geometry); transposedOp_.bind_impl(element, geometry);
} }
void unbind_impl() void unbind_impl()
{ {
transposedOp_.unbind(); transposedOp_.unbind_impl();
} }
template <class PreQuadFactory> template <class PreQuadFactory>
...@@ -181,17 +180,6 @@ namespace AMDiS ...@@ -181,17 +180,6 @@ namespace AMDiS
Transposed transposedOp_; Transposed transposedOp_;
}; };
/// A default implementation of an GridFunctionOperator if no specialization is available.
/**
* An operator must implement either \ref getElementVector, or
* \ref getElementMatrix, if it is a vector or matrix operator,
* respectively.
**/
template <class Tag, class GridFct>
class GridFunctionOperator;
template <class Tag, class PreGridFct, class PreQuadFactory> template <class Tag, class PreGridFct, class PreQuadFactory>
struct PreGridFunctionOperator struct PreGridFunctionOperator
{ {
...@@ -200,7 +188,6 @@ namespace AMDiS ...@@ -200,7 +188,6 @@ namespace AMDiS
PreQuadFactory quadFactory; PreQuadFactory quadFactory;
}; };
/// Store tag and expression to create a \ref GridFunctionOperator /// Store tag and expression to create a \ref GridFunctionOperator
template <class Tag, class PreGridFct, class... QuadratureArgs> template <class Tag, class PreGridFct, class... QuadratureArgs>
auto makeOperator(Tag tag, PreGridFct const& expr, QuadratureArgs&&... args) auto makeOperator(Tag tag, PreGridFct const& expr, QuadratureArgs&&... args)
...@@ -213,24 +200,41 @@ namespace AMDiS ...@@ -213,24 +200,41 @@ namespace AMDiS
#ifndef DOXYGEN #ifndef DOXYGEN
/// The base-template for GridFunctionOperators
/**
* An operator can specialize this class, by deriving from \ref GridFunctionOperatorBase.
* With the generic function \ref makeLocalOperator, an instance is created. To
* distinguisch different GridFunction operators, a tag can be provided that has no
* other effect.
*
* \tparam Tag An Identifier for this GridFunctionOperator
* \tparam LocalContext An Element or Intersection the operator is evaluated on
* \tparam GridFct A GridFunction evaluated in local coordinates on the bound element
**/
template <class Tag, class LocalContext, class GridFct>
class GridFunctionOperator
: public GridFunctionOperatorBase<GridFunctionOperator<Tag, LocalContext, GridFct>, LocalContext, GridFct>
{};
/// Generate an \ref GridFunctionOperator from a PreOperator (tag, expr). /// Generate an \ref GridFunctionOperator from a PreOperator (tag, expr).
/// @{ /// @{
template <class Tag, class... Args, class GridView> template <class LocalContext, class Tag, class... Args, class GridView>
auto makeLocalOperator(PreGridFunctionOperator<Tag, Args...> const& op, GridView const& gridView) auto makeLocalOperator(PreGridFunctionOperator<Tag, Args...> const& op, GridView const& gridView)
{ {
auto gridFct = makeGridFunction(op.expr, gridView); auto gridFct = makeGridFunction(op.expr, gridView);
using GridFctOp = GridFunctionOperator<Tag, decltype(gridFct)>; using GridFctOp = GridFunctionOperator<Tag, LocalContext, decltype(gridFct)>;
GridFctOp localOperator{op.tag, gridFct}; GridFctOp localOperator{op.tag, gridFct};
localOperator.setQuadFactory(op.quadFactory); localOperator.setQuadFactory(op.quadFactory);
return localOperator; return localOperator;
} }
template <class Tag, class... Args, class GridView> template <class LocalContext, class Tag, class... Args, class GridView>
auto makeLocalOperator(std::reference_wrapper<PreGridFunctionOperator<Tag, Args...>> op, GridView const& gridView) auto makeLocalOperator(std::reference_wrapper<PreGridFunctionOperator<Tag, Args...>> op, GridView const& gridView)
{ {
PreGridFunctionOperator<Tag, Args...> const& op_ref = op; PreGridFunctionOperator<Tag, Args...> const& op_ref = op;
auto gridFct = makeGridFunction(std::ref(op_ref.expr), gridView); auto gridFct = makeGridFunction(std::ref(op_ref.expr), gridView);
using GridFctOp = GridFunctionOperator<Tag, decltype(gridFct)>; using GridFctOp = GridFunctionOperator<Tag, LocalContext, decltype(gridFct)>;
GridFctOp localOperator{op_ref.tag, gridFct}; GridFctOp localOperator{op_ref.tag, gridFct};
localOperator.setQuadFactory(op_ref.quadFactory); localOperator.setQuadFactory(op_ref.quadFactory);
return localOperator; return localOperator;
...@@ -240,22 +244,22 @@ namespace AMDiS ...@@ -240,22 +244,22 @@ namespace AMDiS
/// Generate a shared_ptr to \ref GridFunctionOperator from a PreOperator (tag, expr). /// Generate a shared_ptr to \ref GridFunctionOperator from a PreOperator (tag, expr).
/// @{ /// @{
template <class Tag, class... Args, class GridView> template <class LocalContext, class Tag, class... Args, class GridView>
auto makeLocalOperatorPtr(PreGridFunctionOperator<Tag, Args...> const& op, GridView const& gridView) auto makeLocalOperatorPtr(PreGridFunctionOperator<Tag, Args...> const& op, GridView const& gridView)
{ {
auto gridFct = makeGridFunction(op.expr, gridView); auto gridFct = makeGridFunction(op.expr, gridView);
using GridFctOp = GridFunctionOperator<Tag, decltype(gridFct)>; using GridFctOp = GridFunctionOperator<Tag, LocalContext, decltype(gridFct)>;
auto localOperator = std::make_shared<GridFctOp>(op.tag, gridFct); auto localOperator = std::make_shared<GridFctOp>(op.tag, gridFct);
localOperator->setQuadFactory(op.quadFactory); localOperator->setQuadFactory(op.quadFactory);
return localOperator; return localOperator;
} }
template <class Tag, class... Args, class GridView> template <class LocalContext, class Tag, class... Args, class GridView>
auto makeLocalOperatorPtr(std::reference_wrapper<PreGridFunctionOperator<Tag, Args...>> op, GridView const& gridView) auto makeLocalOperatorPtr(std::reference_wrapper<PreGridFunctionOperator<Tag, Args...>> op, GridView const& gridView)
{ {
PreGridFunctionOperator<Tag, Args...> const& op_ref = op; PreGridFunctionOperator<Tag, Args...> const& op_ref = op;
auto gridFct = makeGridFunction(std::ref(op_ref.expr), gridView); auto gridFct = makeGridFunction(std::ref(op_ref.expr), gridView);
using GridFctOp = GridFunctionOperator<Tag, decltype(gridFct)>; using GridFctOp = GridFunctionOperator<Tag, LocalContext, decltype(gridFct)>;
auto localOperator = std::make_shared<GridFctOp>(op_ref.tag, gridFct); auto localOperator = std::make_shared<GridFctOp>(op_ref.tag, gridFct);
localOperator->setQuadFactory(op_ref.quadFactory); localOperator->setQuadFactory(op_ref.quadFactory);
return localOperator; return localOperator;
......
...@@ -65,14 +65,13 @@ namespace AMDiS ...@@ -65,14 +65,13 @@ namespace AMDiS
/// Implementation of \ref LocalAssemblerBase::assemble /// Implementation of \ref LocalAssemblerBase::assemble
/** /**
* Stores geometry and localGeometry and a \ref ContextGeometry and calls * Stores geometry and localGeometry and calls
* \ref calculateElementVector or \ref calculateElementMatrix on the * \ref calculateElementVector or \ref calculateElementMatrix on the
* vector or matrix operator, respectively. * vector or matrix operator, respectively.
**/ **/
virtual void assemble( virtual void assemble(LocalContext const& localContext,
LocalContext const& localContext, Nodes const&... nodes,
Nodes const&... nodes, ElementMatrixVector& elementMatrixVector) final
ElementMatrixVector& elementMatrixVector) final
{ {
ContextGeometry<LocalContext> context{localContext, getElement(), getGeometry()}; ContextGeometry<LocalContext> context{localContext, getElement(), getGeometry()};
assembleImpl(context, nodes..., elementMatrixVector); assembleImpl(context, nodes..., elementMatrixVector);
...@@ -122,7 +121,8 @@ namespace AMDiS ...@@ -122,7 +121,8 @@ namespace AMDiS
private: private:
std::unique_ptr<Operator> storage_; //< the stored operator, implementing \ref GridFunctionOperatorBase /// the stored operator, implementing \ref GridFunctionOperatorBase
std::unique_ptr<Operator> storage_;
Operator& op_; Operator& op_;
Element const* element_ = nullptr; Element const* element_ = nullptr;
......
...@@ -16,12 +16,18 @@ namespace AMDiS ...@@ -16,12 +16,18 @@ namespace AMDiS
/// \brief The main implementation of an operator to be used in a \ref LocalAssembler. /// \brief The main implementation of an operator to be used in a \ref LocalAssembler.
/** /**
* An Operator that takes the element it is assembled on. * The CRTP Base class for local operators.
*
* \tparam Derived The class that derives from this base class
* \tparam LocalContextType The type of the element or intersection the operator is evaluated on
**/ **/
template <class Derived> template <class Derived, class LocalContextType>
class LocalOperator class LocalOperator
{ {
public: public:
using LocalContext = LocalContextType;
using Element = typename Impl::ContextTypes<LocalContext>::Entity;
using Geometry = typename Element::Geometry;
/// Initialize the local operator on the current gridView /// Initialize the local operator on the current gridView
template <class GridView> template <class GridView>
...@@ -38,7 +44,6 @@ namespace AMDiS ...@@ -38,7 +44,6 @@ namespace AMDiS
* *
* By default, it binds the \ref localFct_ to the `element`. * By default, it binds the \ref localFct_ to the `element`.
**/ **/
template <class Element, class Geometry>
void bind(Element const& element, Geometry const& geometry) void bind(Element const& element, Geometry const& geometry)
{ {
if (!bound_) { if (!bound_) {
...@@ -105,7 +110,7 @@ namespace AMDiS ...@@ -105,7 +110,7 @@ namespace AMDiS
// default implementation. Can be overridden in the derived classes // default implementation. Can be overridden in the derived classes
void unbind_impl() {} void unbind_impl() {}
// default implementation called by \ref calculateElementMatrix
template <class Context, class RowNode, class ColNode, class ElementMatrix> template <class Context, class RowNode, class ColNode, class ElementMatrix>
void getElementMatrix(Context const& context, void getElementMatrix(Context const& context,
RowNode const& rowNode, RowNode const& rowNode,
...@@ -115,8 +120,9 @@ namespace AMDiS ...@@ -115,8 +120,9 @@ namespace AMDiS
error_exit("Needs to be implemented by derived class!"); error_exit("Needs to be implemented by derived class!");
} }
// default implementation called by \ref calculateElementVector
template <class Context, class Node, class ElementVector> template <class Context, class Node, class ElementVector>
void getElementVector(Context const& contextGeometry, void getElementVector(Context const& context,
Node const& node, Node const& node,
ElementVector& elementVector) ElementVector& elementVector)
{ {
...@@ -181,15 +187,15 @@ namespace AMDiS ...@@ -181,15 +187,15 @@ namespace AMDiS
/// Generate an \ref GridFunctionOperator from a PreOperator. /// Generate an \ref GridFunctionOperator from a PreOperator.
template <class Derived, class GridView> template <class Derived, class LocalContext, class GridView>
auto makeLocalOperator(LocalOperator<Derived> const& localOp, GridView const& /*gridView*/) auto makeLocalOperator(LocalOperator<Derived, LocalContext> const& localOp, GridView const& /*gridView*/)
{ {
return localOp.derived(); return localOp.derived();
} }
/// Generate a shared_ptr to \ref GridFunctionOperator from a PreOperator. /// Generate a shared_ptr to \ref GridFunctionOperator from a PreOperator.
template <class Derived, class GridView> template <class Derived, class LocalContext, class GridView>
auto makeLocalOperatorPtr(LocalOperator<Derived> const& localOp, GridView const& /*gridView*/) auto makeLocalOperatorPtr(LocalOperator<Derived, LocalContext> const& localOp, GridView const& /*gridView*/)
{ {
return std::make_shared<Derived>(localOp.derived()); return std::make_shared<Derived>(localOp.derived());
} }
......
...@@ -176,7 +176,7 @@ void ProblemStat<Traits>::addMatrixOperator( ...@@ -176,7 +176,7 @@ void ProblemStat<Traits>::addMatrixOperator(
auto i = child(localView_->tree(), makeTreePath(row)); auto i = child(localView_->tree(), makeTreePath(row));
auto j = child(localView_->tree(), makeTreePath(col)); auto j = child(localView_->tree(), makeTreePath(col));
auto op = makeLocalOperator(preOp, globalBasis_->gridView()); auto op = makeLocalOperator<Element>(preOp, globalBasis_->gridView());
auto localAssembler = makeLocalAssemblerPtr<Element>(std::move(op), i, j); auto localAssembler = makeLocalAssemblerPtr<Element>(std::move(op), i, j);
matrixOperators_[i][j].element.push_back({localAssembler, factor, estFactor}); matrixOperators_[i][j].element.push_back({localAssembler, factor, estFactor});
...@@ -201,7 +201,7 @@ void ProblemStat<Traits>::addMatrixOperator( ...@@ -201,7 +201,7 @@ void ProblemStat<Traits>::addMatrixOperator(
auto j = child(localView_->tree(), makeTreePath(col)); auto j = child(localView_->tree(), makeTreePath(col));
using Intersection = typename GridView::Intersection; using Intersection = typename GridView::Intersection;
auto op = makeLocalOperator(preOp, globalBasis_->gridView()); auto op = makeLocalOperator<Intersection>(preOp, globalBasis_->gridView());
auto localAssembler = makeLocalAssemblerPtr<Intersection>(std::move(op), i, j); auto localAssembler = makeLocalAssemblerPtr<Intersection>(std::move(op), i, j);
matrixOperators_[i][j].boundary.push_back({localAssembler, factor, estFactor, b}); matrixOperators_[i][j].boundary.push_back({localAssembler, factor, estFactor, b});
...@@ -221,7 +221,7 @@ void ProblemStat<Traits>::addVectorOperator( ...@@ -221,7 +221,7 @@ void ProblemStat<Traits>::addVectorOperator(
auto i = child(localView_->tree(), makeTreePath(path)); auto i = child(localView_->tree(), makeTreePath(path));
auto op = makeLocalOperator(preOp, globalBasis_->gridView()); auto op = makeLocalOperator<Element>(preOp, globalBasis_->gridView());
auto localAssembler = makeLocalAssemblerPtr<Element>(std::move(op), i); auto localAssembler = makeLocalAssemblerPtr<Element>(std::move(op), i);
rhsOperators_[i].element.push_back({localAssembler, factor, estFactor}); rhsOperators_[i].element.push_back({localAssembler, factor, estFactor});
...@@ -243,7 +243,7 @@ void ProblemStat<Traits>::addVectorOperator( ...@@ -243,7 +243,7 @@ void ProblemStat<Traits>::addVectorOperator(
auto i = child(localView_->tree(), makeTreePath(path)); auto i = child(localView_->tree(), makeTreePath(path));
using Intersection = typename GridView::Intersection; using Intersection = typename GridView::Intersection;
auto op = makeLocalOperator(preOp, globalBasis_->gridView()); auto op = makeLocalOperator<Intersection>(preOp, globalBasis_->gridView());
auto localAssembler = makeLocalAssemblerPtr<Intersection>(std::move(op), i); auto localAssembler = makeLocalAssemblerPtr<Intersection>(std::move(op), i);
rhsOperators_[i].boundary.push_back({localAssembler, factor, estFactor, b}); rhsOperators_[i].boundary.push_back({localAssembler, factor, estFactor, b});
......
...@@ -17,9 +17,10 @@ namespace AMDiS ...@@ -17,9 +17,10 @@ namespace AMDiS
/// convection-diffusion operator /// convection-diffusion operator
/// <A*grad(u),grad(v)> - <b*u, grad(v)> + <c*u, v> = <f, v> (conserving) or /// <A*grad(u),grad(v)> - <b*u, grad(v)> + <c*u, v> = <f, v> (conserving) or
/// <A*grad(u),grad(v)> + <b*grad(u), v> + <c*u, v> = <f, v> (non conserving) /// <A*grad(u),grad(v)> + <b*grad(u), v> + <c*u, v> = <f, v> (non conserving)
template <class GridFctA, class GridFctB, class GridFctC, class GridFctF, bool conserving = true> template <class LocalContext, class GridFctA, class GridFctB, class GridFctC, class GridFctF, bool conserving = true>
class ConvectionDiffusionOperator class ConvectionDiffusionOperator
: public LocalOperatorBase<ConvectionDiffusionOperator<GridFctA, GridFctB, GridFctC, GridFctF, conserving>> : public LocalOperator<ConvectionDiffusionOperator<LocalContext, GridFctA, GridFctB, GridFctC, GridFctF, conserving>,
LocalContext>
{ {
using A_range_type = typename GridFctA::Range; using A_range_type = typename GridFctA::Range;
static_assert( Category::Scalar<A_range_type> || Category::Matrix<A_range_type>, static_assert( Category::Scalar<A_range_type> || Category::Matrix<A_range_type>,
...@@ -36,8 +37,7 @@ namespace AMDiS ...@@ -36,8 +37,7 @@ namespace AMDiS
public: public:
ConvectionDiffusionOperator(GridFctA const& gridFctA, GridFctB const& gridFctB, ConvectionDiffusionOperator(GridFctA const& gridFctA, GridFctB const& gridFctB,
GridFctC const& gridFctC, GridFctF const& gridFctF, GridFctC const& gridFctC, GridFctF const& gridFctF)
bool_t<conserving> = {})
: gridFctA_(gridFctA) : gridFctA_(gridFctA)
, gridFctB_(gridFctB) , gridFctB_(gridFctB)
, gridFctC_(gridFctC) , gridFctC_(gridFctC)
...@@ -193,13 +193,37 @@ namespace AMDiS ...@@ -193,13 +193,37 @@ namespace AMDiS
GridFctF gridFctF; GridFctF gridFctF;
}; };
template <class PreGridFctA, class PreGridFctB, class PreGridFctC, class PreGridFctF, bool conserving>
struct PreConvectionDiffusionOperator
{
PreGridFctA gridFctA;
PreGridFctB gridFctB;
PreGridFctC gridFctC;
PreGridFctF gridFctF;
};
template <class GridFctA, class GridFctB, class GridFctC, class GridFctF, bool conserving = true> template <class PreGridFctA, class PreGridFctB, class PreGridFctC, class PreGridFctF, bool conserving = true>
auto convectionDiffusion(GridFctA const& gridFctA, GridFctB const& gridFctB, auto convectionDiffusion(PreGridFctA const& gridFctA, PreGridFctB const& gridFctB,
GridFctC const& gridFctC, GridFctF const& gridFctF, PreGridFctC const& gridFctC, PreGridFctF const& gridFctF,
bool_t<conserving> = {}) bool_t<conserving> = {})
{ {
return ConvectionDiffusionOperator<GridFctA, GridFctB, GridFctC, GridFctF, conserving>{gridFctA, gridFctB, gridFctC, gridFctF}; using Pre = PreConvectionDiffusionOperator<PreGridFctA, PreGridFctB, PreGridFctC, PreGridFctF, conserving>;
return Pre{gridFctA, gridFctB, gridFctC, gridFctF};
}
template <class LocalContext, class... GrdFcts, bool conserving, class GridView>
auto makeLocalOperator(PreConvectionDiffusionOperator<GridFcts..., conserving> const& pre, GridView const& gridView)
{
auto gridFctA = makeGridFunction(pre.gridFctA, gridView);
auto gridFctB = makeGridFunction(pre.gridFctB, gridView);
auto gridFctC = makeGridFunction(pre.gridFctC, gridView);
auto gridFctF = makeGridFunction(pre.gridFctF, gridView);
using GridFctOp = ConvectionDiffusionOperator<LocalContext,
decltype(gridFctA), decltype(gridFctB), decltype(gridFctC), decltype(gridFctF), conserving>;
GridFctOp localOperator{gridFctA, gridFctB, gridFctC, gridFctF};
return localOperator;
} }
/** @} **/ /** @} **/
......
...@@ -18,13 +18,13 @@ namespace AMDiS ...@@ -18,13 +18,13 @@ namespace AMDiS
/// first-order operator \f$ \langle\nabla\cdot\Psi, c\,\phi\rangle \f$ /// first-order operator \f$ \langle\nabla\cdot\Psi, c\,\phi\rangle \f$
template <class GridFct> template <class LocalContext, class GridFct>
class GridFunctionOperator<tag::divtestvec_trial, GridFct> class GridFunctionOperator<tag::divtestvec_trial, LocalContext, GridFct>
: public GridFunctionOperatorTransposed<GridFunctionOperator<tag::divtestvec_trial, GridFct>, : public GridFunctionOperatorTransposed<GridFunctionOperator<tag::divtestvec_trial, LocalContext, GridFct>,
GridFunctionOperator<tag::test_divtrialvec, GridFct>> GridFunctionOperator<tag::test_divtrialvec, LocalContext, GridFct>>
{ {
using Self = GridFunctionOperator; using Self = GridFunctionOperator;
using Transposed = GridFunctionOperator<tag::test_divtrialvec, GridFct>; using Transposed = GridFunctionOperator<