From e37c96cdfaf62b996ddd4a3a76b30f2a230cc09b Mon Sep 17 00:00:00 2001 From: Simon Praetorius <simon.praetorius@tu-dresden.de> Date: Mon, 2 Jul 2018 00:01:41 +0200 Subject: [PATCH] Added LocalContext to template parameters of GridFunction --- examples/ellipt.cc | 2 + src/amdis/ContextGeometry.hpp | 2 +- src/amdis/GridFunctionOperator.hpp | 82 ++++++++++--------- src/amdis/LocalAssembler.hpp | 12 +-- src/amdis/LocalOperator.hpp | 24 ++++-- src/amdis/ProblemStat.inc.hpp | 8 +- .../assembler/ConvectionDiffusionOperator.hpp | 40 +++++++-- .../assembler/FirstOrderDivTestvecTrial.hpp | 10 +-- .../assembler/FirstOrderGradTestTrial.hpp | 10 +-- .../assembler/FirstOrderGradTestTrialvec.hpp | 10 +-- .../assembler/FirstOrderPartialTestTrial.hpp | 10 +-- .../assembler/FirstOrderTestDivTrialvec.hpp | 9 +- .../assembler/FirstOrderTestGradTrial.hpp | 9 +- .../assembler/FirstOrderTestPartialTrial.hpp | 9 +- .../assembler/FirstOrderTestvecGradTrial.hpp | 9 +- .../SecondOrderDivTestvecDivTrialvec.hpp | 9 +- .../SecondOrderGradTestGradTrial.hpp | 9 +- .../SecondOrderPartialTestPartialTrial.hpp | 9 +- src/amdis/assembler/StokesOperator.hpp | 9 +- src/amdis/assembler/ZeroOrderTest.hpp | 9 +- src/amdis/assembler/ZeroOrderTestTrial.hpp | 9 +- src/amdis/assembler/ZeroOrderTestTrialvec.hpp | 9 +- src/amdis/assembler/ZeroOrderTestvec.hpp | 9 +- src/amdis/assembler/ZeroOrderTestvecTrial.hpp | 10 +-- .../assembler/ZeroOrderTestvecTrialvec.hpp | 9 +- .../gridfunctions/AnalyticGridFunction.hpp | 1 + src/amdis/utility/Tuple.hpp | 33 +++++--- 27 files changed, 214 insertions(+), 157 deletions(-) diff --git a/examples/ellipt.cc b/examples/ellipt.cc index ddaad29b..6baf47bf 100644 --- a/examples/ellipt.cc +++ b/examples/ellipt.cc @@ -32,6 +32,8 @@ int main(int argc, char** argv) auto opForce = makeOperator(tag::test{}, [](auto const& x) { return -1.0; }, 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 auto predicate = [](auto const& x){ return x[0] < 1.e-8 || x[1] < 1.e-8; }; // define boundary diff --git a/src/amdis/ContextGeometry.hpp b/src/amdis/ContextGeometry.hpp index 0d5659bc..6307603e 100644 --- a/src/amdis/ContextGeometry.hpp +++ b/src/amdis/ContextGeometry.hpp @@ -151,7 +151,7 @@ namespace AMDiS Geometry const* geometry_; // The localGeometry may be constructed only if needed - Dune::Std::optional<LocalGeometry> localGeometry_; + mutable Dune::Std::optional<LocalGeometry> localGeometry_; }; } // end namespace AMDiS diff --git a/src/amdis/GridFunctionOperator.hpp b/src/amdis/GridFunctionOperator.hpp index 61c7e019..1cda525f 100644 --- a/src/amdis/GridFunctionOperator.hpp +++ b/src/amdis/GridFunctionOperator.hpp @@ -24,31 +24,29 @@ namespace AMDiS * * 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 * that is evaluated at quadrature points. - * \tparam QuadratureCreator A functor that provides a \ref Dune::QuadratureRule. * * **Requirements:** + * - `LocalContext` models either Entity (of codim 0) or Intersection * - `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 - : public LocalOperator<Derived> + : public LocalOperator<Derived, LocalContext> { 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 LocalCoordinate = typename GridFunction::EntitySet::LocalCoordinate; - using QuadFactory = QuadratureFactory<typename Geometry::ctype, Element::dimension, LocalFunction>; + using QuadFactory = QuadratureFactory<typename Geometry::ctype, LocalContext::mydimension, LocalFunction>; 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 * \ref ExpressionBase, and stores a copy. Additionally, it gets the @@ -85,10 +83,8 @@ namespace AMDiS void bind_impl(Element const& element, Geometry const& geometry) { assert( bool(quadFactory_) ); - if (!this->bound_) { - localFct_.bind(element); - quadFactory_->bind(localFct_); - } + localFct_.bind(element); + quadFactory_->bind(localFct_); } /// Unbinds operator from element. @@ -100,7 +96,7 @@ namespace AMDiS template <class PreQuadFactory> void setQuadFactory(PreQuadFactory const& pre) { - quadFactory_ = makeQuadratureFactoryPtr<typename Geometry::ctype, Element::dimension, LocalFunction>(pre); + quadFactory_ = makeQuadratureFactoryPtr<typename Geometry::ctype, LocalContext::mydimension, LocalFunction>(pre); } protected: @@ -131,13 +127,16 @@ namespace AMDiS /// Assign each element type a quadrature rule 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> class GridFunctionOperatorTransposed - : public LocalOperator<Derived> + : public LocalOperator<Derived, typename Transposed::LocalContext> { template <class T, class... Args> using Constructable = decltype( new T(std::declval<Args>()...) ); @@ -152,12 +151,12 @@ namespace AMDiS template <class Element, class Geometry> void bind_impl(Element const& element, Geometry const& geometry) { - transposedOp_.bind(element, geometry); + transposedOp_.bind_impl(element, geometry); } void unbind_impl() { - transposedOp_.unbind(); + transposedOp_.unbind_impl(); } template <class PreQuadFactory> @@ -181,17 +180,6 @@ namespace AMDiS 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> struct PreGridFunctionOperator { @@ -200,7 +188,6 @@ namespace AMDiS PreQuadFactory quadFactory; }; - /// Store tag and expression to create a \ref GridFunctionOperator template <class Tag, class PreGridFct, class... QuadratureArgs> auto makeOperator(Tag tag, PreGridFct const& expr, QuadratureArgs&&... args) @@ -213,24 +200,41 @@ namespace AMDiS #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). /// @{ - 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 gridFct = makeGridFunction(op.expr, gridView); - using GridFctOp = GridFunctionOperator<Tag, decltype(gridFct)>; + using GridFctOp = GridFunctionOperator<Tag, LocalContext, decltype(gridFct)>; GridFctOp localOperator{op.tag, gridFct}; localOperator.setQuadFactory(op.quadFactory); 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) { PreGridFunctionOperator<Tag, Args...> const& op_ref = op; 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}; localOperator.setQuadFactory(op_ref.quadFactory); return localOperator; @@ -240,22 +244,22 @@ namespace AMDiS /// 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 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); localOperator->setQuadFactory(op.quadFactory); 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) { PreGridFunctionOperator<Tag, Args...> const& op_ref = op; 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); localOperator->setQuadFactory(op_ref.quadFactory); return localOperator; diff --git a/src/amdis/LocalAssembler.hpp b/src/amdis/LocalAssembler.hpp index 85a1db5a..1d47532d 100644 --- a/src/amdis/LocalAssembler.hpp +++ b/src/amdis/LocalAssembler.hpp @@ -65,14 +65,13 @@ namespace AMDiS /// 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 * vector or matrix operator, respectively. **/ - virtual void assemble( - LocalContext const& localContext, - Nodes const&... nodes, - ElementMatrixVector& elementMatrixVector) final + virtual void assemble(LocalContext const& localContext, + Nodes const&... nodes, + ElementMatrixVector& elementMatrixVector) final { ContextGeometry<LocalContext> context{localContext, getElement(), getGeometry()}; assembleImpl(context, nodes..., elementMatrixVector); @@ -122,7 +121,8 @@ namespace AMDiS 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_; Element const* element_ = nullptr; diff --git a/src/amdis/LocalOperator.hpp b/src/amdis/LocalOperator.hpp index 5f4ac34c..87d2f3d3 100644 --- a/src/amdis/LocalOperator.hpp +++ b/src/amdis/LocalOperator.hpp @@ -16,12 +16,18 @@ namespace AMDiS /// \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 { public: + using LocalContext = LocalContextType; + using Element = typename Impl::ContextTypes<LocalContext>::Entity; + using Geometry = typename Element::Geometry; /// Initialize the local operator on the current gridView template <class GridView> @@ -38,7 +44,6 @@ namespace AMDiS * * By default, it binds the \ref localFct_ to the `element`. **/ - template <class Element, class Geometry> void bind(Element const& element, Geometry const& geometry) { if (!bound_) { @@ -105,7 +110,7 @@ namespace AMDiS // default implementation. Can be overridden in the derived classes void unbind_impl() {} - + // default implementation called by \ref calculateElementMatrix template <class Context, class RowNode, class ColNode, class ElementMatrix> void getElementMatrix(Context const& context, RowNode const& rowNode, @@ -115,8 +120,9 @@ namespace AMDiS error_exit("Needs to be implemented by derived class!"); } + // default implementation called by \ref calculateElementVector template <class Context, class Node, class ElementVector> - void getElementVector(Context const& contextGeometry, + void getElementVector(Context const& context, Node const& node, ElementVector& elementVector) { @@ -181,15 +187,15 @@ namespace AMDiS /// Generate an \ref GridFunctionOperator from a PreOperator. - template <class Derived, class GridView> - auto makeLocalOperator(LocalOperator<Derived> const& localOp, GridView const& /*gridView*/) + template <class Derived, class LocalContext, class GridView> + auto makeLocalOperator(LocalOperator<Derived, LocalContext> const& localOp, GridView const& /*gridView*/) { return localOp.derived(); } /// Generate a shared_ptr to \ref GridFunctionOperator from a PreOperator. - template <class Derived, class GridView> - auto makeLocalOperatorPtr(LocalOperator<Derived> const& localOp, GridView const& /*gridView*/) + template <class Derived, class LocalContext, class GridView> + auto makeLocalOperatorPtr(LocalOperator<Derived, LocalContext> const& localOp, GridView const& /*gridView*/) { return std::make_shared<Derived>(localOp.derived()); } diff --git a/src/amdis/ProblemStat.inc.hpp b/src/amdis/ProblemStat.inc.hpp index 37d72c94..4f08455f 100644 --- a/src/amdis/ProblemStat.inc.hpp +++ b/src/amdis/ProblemStat.inc.hpp @@ -176,7 +176,7 @@ void ProblemStat<Traits>::addMatrixOperator( auto i = child(localView_->tree(), makeTreePath(row)); 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); matrixOperators_[i][j].element.push_back({localAssembler, factor, estFactor}); @@ -201,7 +201,7 @@ void ProblemStat<Traits>::addMatrixOperator( auto j = child(localView_->tree(), makeTreePath(col)); 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); matrixOperators_[i][j].boundary.push_back({localAssembler, factor, estFactor, b}); @@ -221,7 +221,7 @@ void ProblemStat<Traits>::addVectorOperator( 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); rhsOperators_[i].element.push_back({localAssembler, factor, estFactor}); @@ -243,7 +243,7 @@ void ProblemStat<Traits>::addVectorOperator( auto i = child(localView_->tree(), makeTreePath(path)); 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); rhsOperators_[i].boundary.push_back({localAssembler, factor, estFactor, b}); diff --git a/src/amdis/assembler/ConvectionDiffusionOperator.hpp b/src/amdis/assembler/ConvectionDiffusionOperator.hpp index 78477656..a2f938e7 100644 --- a/src/amdis/assembler/ConvectionDiffusionOperator.hpp +++ b/src/amdis/assembler/ConvectionDiffusionOperator.hpp @@ -17,9 +17,10 @@ namespace AMDiS /// 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*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 - : 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; static_assert( Category::Scalar<A_range_type> || Category::Matrix<A_range_type>, @@ -36,8 +37,7 @@ namespace AMDiS public: ConvectionDiffusionOperator(GridFctA const& gridFctA, GridFctB const& gridFctB, - GridFctC const& gridFctC, GridFctF const& gridFctF, - bool_t<conserving> = {}) + GridFctC const& gridFctC, GridFctF const& gridFctF) : gridFctA_(gridFctA) , gridFctB_(gridFctB) , gridFctC_(gridFctC) @@ -193,13 +193,37 @@ namespace AMDiS 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> - auto convectionDiffusion(GridFctA const& gridFctA, GridFctB const& gridFctB, - GridFctC const& gridFctC, GridFctF const& gridFctF, + template <class PreGridFctA, class PreGridFctB, class PreGridFctC, class PreGridFctF, bool conserving = true> + auto convectionDiffusion(PreGridFctA const& gridFctA, PreGridFctB const& gridFctB, + PreGridFctC const& gridFctC, PreGridFctF const& gridFctF, 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; } /** @} **/ diff --git a/src/amdis/assembler/FirstOrderDivTestvecTrial.hpp b/src/amdis/assembler/FirstOrderDivTestvecTrial.hpp index f4524fd0..dc49905d 100644 --- a/src/amdis/assembler/FirstOrderDivTestvecTrial.hpp +++ b/src/amdis/assembler/FirstOrderDivTestvecTrial.hpp @@ -18,13 +18,13 @@ namespace AMDiS /// first-order operator \f$ \langle\nabla\cdot\Psi, c\,\phi\rangle \f$ - template <class GridFct> - class GridFunctionOperator<tag::divtestvec_trial, GridFct> - : public GridFunctionOperatorTransposed<GridFunctionOperator<tag::divtestvec_trial, GridFct>, - GridFunctionOperator<tag::test_divtrialvec, GridFct>> + template <class LocalContext, class GridFct> + class GridFunctionOperator<tag::divtestvec_trial, LocalContext, GridFct> + : public GridFunctionOperatorTransposed<GridFunctionOperator<tag::divtestvec_trial, LocalContext, GridFct>, + GridFunctionOperator<tag::test_divtrialvec, LocalContext, GridFct>> { using Self = GridFunctionOperator; - using Transposed = GridFunctionOperator<tag::test_divtrialvec, GridFct>; + using Transposed = GridFunctionOperator<tag::test_divtrialvec, LocalContext, GridFct>; using Super = GridFunctionOperatorTransposed<Self, Transposed>; public: diff --git a/src/amdis/assembler/FirstOrderGradTestTrial.hpp b/src/amdis/assembler/FirstOrderGradTestTrial.hpp index eee21e9d..6808103e 100644 --- a/src/amdis/assembler/FirstOrderGradTestTrial.hpp +++ b/src/amdis/assembler/FirstOrderGradTestTrial.hpp @@ -18,13 +18,13 @@ namespace AMDiS /// first-order operator \f$ \langle\nabla\psi, \mathbf{b}\,\phi\rangle \f$ - template <class GridFct> - class GridFunctionOperator<tag::gradtest_trial, GridFct> - : public GridFunctionOperatorTransposed<GridFunctionOperator<tag::gradtest_trial, GridFct>, - GridFunctionOperator<tag::test_gradtrial, GridFct>> + template <class LocalContext, class GridFct> + class GridFunctionOperator<tag::gradtest_trial, LocalContext, GridFct> + : public GridFunctionOperatorTransposed<GridFunctionOperator<tag::gradtest_trial, LocalContext, GridFct>, + GridFunctionOperator<tag::test_gradtrial, LocalContext, GridFct>> { using Self = GridFunctionOperator; - using Transposed = GridFunctionOperator<tag::test_gradtrial, GridFct>; + using Transposed = GridFunctionOperator<tag::test_gradtrial, LocalContext, GridFct>; using Super = GridFunctionOperatorTransposed<Self, Transposed>; public: diff --git a/src/amdis/assembler/FirstOrderGradTestTrialvec.hpp b/src/amdis/assembler/FirstOrderGradTestTrialvec.hpp index e1cf8d08..83c6c9e8 100644 --- a/src/amdis/assembler/FirstOrderGradTestTrialvec.hpp +++ b/src/amdis/assembler/FirstOrderGradTestTrialvec.hpp @@ -18,13 +18,13 @@ namespace AMDiS /// first-order operator \f$ \langle\nabla\psi, c\,\Phi\rangle \f$ - template <class GridFct> - class GridFunctionOperator<tag::gradtest_trialvec, GridFct> - : public GridFunctionOperatorTransposed<GridFunctionOperator<tag::gradtest_trialvec, GridFct>, - GridFunctionOperator<tag::testvec_gradtrial, GridFct>> + template <class LocalContext, class GridFct> + class GridFunctionOperator<tag::gradtest_trialvec, LocalContext, GridFct> + : public GridFunctionOperatorTransposed<GridFunctionOperator<tag::gradtest_trialvec, LocalContext, GridFct>, + GridFunctionOperator<tag::testvec_gradtrial, LocalContext, GridFct>> { using Self = GridFunctionOperator; - using Transposed = GridFunctionOperator<tag::testvec_gradtrial, GridFct>; + using Transposed = GridFunctionOperator<tag::testvec_gradtrial, LocalContext, GridFct>; using Super = GridFunctionOperatorTransposed<Self, Transposed>; public: diff --git a/src/amdis/assembler/FirstOrderPartialTestTrial.hpp b/src/amdis/assembler/FirstOrderPartialTestTrial.hpp index 14f9a892..0c9435f8 100644 --- a/src/amdis/assembler/FirstOrderPartialTestTrial.hpp +++ b/src/amdis/assembler/FirstOrderPartialTestTrial.hpp @@ -21,13 +21,13 @@ namespace AMDiS /// first-order operator \f$ \langle\partial_i\psi, c\,\phi\rangle \f$ - template <class GridFct> - class GridFunctionOperator<tag::partialtest_trial, GridFct> - : public GridFunctionOperatorTransposed<GridFunctionOperator<tag::partialtest_trial, GridFct>, - GridFunctionOperator<tag::test_partialtrial, GridFct>> + template <class LocalContext, class GridFct> + class GridFunctionOperator<tag::partialtest_trial, LocalContext, GridFct> + : public GridFunctionOperatorTransposed<GridFunctionOperator<tag::partialtest_trial, LocalContext, GridFct>, + GridFunctionOperator<tag::test_partialtrial, LocalContext, GridFct>> { using Self = GridFunctionOperator; - using Transposed = GridFunctionOperator<tag::test_partialtrial, GridFct>; + using Transposed = GridFunctionOperator<tag::test_partialtrial, LocalContext, GridFct>; using Super = GridFunctionOperatorTransposed<Self, Transposed>; public: diff --git a/src/amdis/assembler/FirstOrderTestDivTrialvec.hpp b/src/amdis/assembler/FirstOrderTestDivTrialvec.hpp index 8c067d84..5cdbeab3 100644 --- a/src/amdis/assembler/FirstOrderTestDivTrialvec.hpp +++ b/src/amdis/assembler/FirstOrderTestDivTrialvec.hpp @@ -20,12 +20,13 @@ namespace AMDiS /// first-order operator \f$ \langle\psi, c\,\nabla\cdot\Phi\rangle \f$ - template <class GridFct> - class GridFunctionOperator<tag::test_divtrialvec, GridFct> - : public GridFunctionOperatorBase<GridFunctionOperator<tag::test_divtrialvec, GridFct>, GridFct> + template <class LocalContext, class GridFct> + class GridFunctionOperator<tag::test_divtrialvec, LocalContext, GridFct> + : public GridFunctionOperatorBase<GridFunctionOperator<tag::test_divtrialvec, LocalContext, GridFct>, + LocalContext, GridFct> { using Self = GridFunctionOperator; - using Super = GridFunctionOperatorBase<Self, GridFct>; + using Super = GridFunctionOperatorBase<Self, LocalContext, GridFct>; static_assert( Category::Scalar<typename GridFct::Range>, "Expression must be of scalar type." ); diff --git a/src/amdis/assembler/FirstOrderTestGradTrial.hpp b/src/amdis/assembler/FirstOrderTestGradTrial.hpp index 017f6934..bccf890d 100644 --- a/src/amdis/assembler/FirstOrderTestGradTrial.hpp +++ b/src/amdis/assembler/FirstOrderTestGradTrial.hpp @@ -20,12 +20,13 @@ namespace AMDiS /// first-order operator \f$ \langle\psi, \mathbf{b}\cdot\nabla\phi\rangle \f$ - template <class GridFct> - class GridFunctionOperator<tag::test_gradtrial, GridFct> - : public GridFunctionOperatorBase<GridFunctionOperator<tag::test_gradtrial, GridFct>, GridFct> + template <class LocalContext, class GridFct> + class GridFunctionOperator<tag::test_gradtrial, LocalContext, GridFct> + : public GridFunctionOperatorBase<GridFunctionOperator<tag::test_gradtrial, LocalContext, GridFct>, + LocalContext, GridFct> { using Self = GridFunctionOperator; - using Super = GridFunctionOperatorBase<Self, GridFct>; + using Super = GridFunctionOperatorBase<Self, LocalContext, GridFct>; static_assert( Category::Vector<typename GridFct::Range>, "Expression must be of vector type." ); diff --git a/src/amdis/assembler/FirstOrderTestPartialTrial.hpp b/src/amdis/assembler/FirstOrderTestPartialTrial.hpp index 6595956a..d69dcb68 100644 --- a/src/amdis/assembler/FirstOrderTestPartialTrial.hpp +++ b/src/amdis/assembler/FirstOrderTestPartialTrial.hpp @@ -23,12 +23,13 @@ namespace AMDiS /// first-order operator \f$ \langle\psi, c\,\partial_i\phi\rangle \f$ - template <class GridFct> - class GridFunctionOperator<tag::test_partialtrial, GridFct> - : public GridFunctionOperatorBase<GridFunctionOperator<tag::test_partialtrial, GridFct>, GridFct> + template <class LocalContext, class GridFct> + class GridFunctionOperator<tag::test_partialtrial, LocalContext, GridFct> + : public GridFunctionOperatorBase<GridFunctionOperator<tag::test_partialtrial, LocalContext, GridFct>, + LocalContext, GridFct> { using Self = GridFunctionOperator; - using Super = GridFunctionOperatorBase<Self, GridFct>; + using Super = GridFunctionOperatorBase<Self, LocalContext, GridFct>; static_assert( Category::Scalar<typename GridFct::Range>, "Expression must be of scalar type." ); diff --git a/src/amdis/assembler/FirstOrderTestvecGradTrial.hpp b/src/amdis/assembler/FirstOrderTestvecGradTrial.hpp index 729edec4..d06a44db 100644 --- a/src/amdis/assembler/FirstOrderTestvecGradTrial.hpp +++ b/src/amdis/assembler/FirstOrderTestvecGradTrial.hpp @@ -20,12 +20,13 @@ namespace AMDiS /// first-order operator \f$ \langle\Psi, c\,\nabla\phi\rangle \f$ - template <class GridFct> - class GridFunctionOperator<tag::testvec_gradtrial, GridFct> - : public GridFunctionOperatorBase<GridFunctionOperator<tag::testvec_gradtrial, GridFct>, GridFct> + template <class LocalContext, class GridFct> + class GridFunctionOperator<tag::testvec_gradtrial, LocalContext, GridFct> + : public GridFunctionOperatorBase<GridFunctionOperator<tag::testvec_gradtrial, LocalContext, GridFct>, + LocalContext, GridFct> { using Self = GridFunctionOperator; - using Super = GridFunctionOperatorBase<Self, GridFct>; + using Super = GridFunctionOperatorBase<Self, LocalContext, GridFct>; static_assert( Category::Scalar<typename GridFct::Range>, "Expression must be of scalar type." ); diff --git a/src/amdis/assembler/SecondOrderDivTestvecDivTrialvec.hpp b/src/amdis/assembler/SecondOrderDivTestvecDivTrialvec.hpp index 350bc58f..0e841d53 100644 --- a/src/amdis/assembler/SecondOrderDivTestvecDivTrialvec.hpp +++ b/src/amdis/assembler/SecondOrderDivTestvecDivTrialvec.hpp @@ -20,12 +20,13 @@ namespace AMDiS /// second-order operator \f$ \langle\nabla\cdot\Psi, c\,\nabla\cdot\Phi\rangle \f$ - template <class GridFct> - class GridFunctionOperator<tag::divtestvec_divtrialvec, GridFct> - : public GridFunctionOperatorBase<GridFunctionOperator<tag::divtestvec_divtrialvec, GridFct>, GridFct> + template <class LocalContext, class GridFct> + class GridFunctionOperator<tag::divtestvec_divtrialvec, LocalContext, GridFct> + : public GridFunctionOperatorBase<GridFunctionOperator<tag::divtestvec_divtrialvec, LocalContext, GridFct>, + LocalContext, GridFct> { using Self = GridFunctionOperator; - using Super = GridFunctionOperatorBase<Self, GridFct>; + using Super = GridFunctionOperatorBase<Self, LocalContext, GridFct>; static_assert( Category::Scalar<typename GridFct::Range>, "Expression must be of scalar type." ); diff --git a/src/amdis/assembler/SecondOrderGradTestGradTrial.hpp b/src/amdis/assembler/SecondOrderGradTestGradTrial.hpp index 30c46b1b..d8f6ea1d 100644 --- a/src/amdis/assembler/SecondOrderGradTestGradTrial.hpp +++ b/src/amdis/assembler/SecondOrderGradTestGradTrial.hpp @@ -20,12 +20,13 @@ namespace AMDiS /// second-order operator \f$ \langle\nabla\psi, c\,\nabla\phi\rangle \f$, or \f$ \langle\nabla\psi, A\,\nabla\phi\rangle \f$ - template <class GridFct> - class GridFunctionOperator<tag::gradtest_gradtrial, GridFct> - : public GridFunctionOperatorBase<GridFunctionOperator<tag::gradtest_gradtrial, GridFct>, GridFct> + template <class LocalContext, class GridFct> + class GridFunctionOperator<tag::gradtest_gradtrial, LocalContext, GridFct> + : public GridFunctionOperatorBase<GridFunctionOperator<tag::gradtest_gradtrial, LocalContext, GridFct>, + LocalContext, GridFct> { using Self = GridFunctionOperator; - using Super = GridFunctionOperatorBase<Self, GridFct>; + using Super = GridFunctionOperatorBase<Self, LocalContext, GridFct>; using expr_value_type = typename GridFct::Range; static_assert( Category::Scalar<expr_value_type> || Category::Matrix<expr_value_type>, diff --git a/src/amdis/assembler/SecondOrderPartialTestPartialTrial.hpp b/src/amdis/assembler/SecondOrderPartialTestPartialTrial.hpp index bf964bbc..6539acf8 100644 --- a/src/amdis/assembler/SecondOrderPartialTestPartialTrial.hpp +++ b/src/amdis/assembler/SecondOrderPartialTestPartialTrial.hpp @@ -24,12 +24,13 @@ namespace AMDiS /// second-order operator \f$ \langle\partial_i\psi, c\,\partial_j\phi\rangle \f$ - template <class GridFct> - class GridFunctionOperator<tag::partialtest_partialtrial, GridFct> - : public GridFunctionOperatorBase<GridFunctionOperator<tag::partialtest_partialtrial, GridFct>, GridFct> + template <class LocalContext, class GridFct> + class GridFunctionOperator<tag::partialtest_partialtrial, LocalContext, GridFct> + : public GridFunctionOperatorBase<GridFunctionOperator<tag::partialtest_partialtrial, LocalContext, GridFct>, + LocalContext, GridFct> { using Self = GridFunctionOperator; - using Super = GridFunctionOperatorBase<Self, GridFct>; + using Super = GridFunctionOperatorBase<Self, LocalContext, GridFct>; static_assert( Category::Scalar<typename GridFct::Range>, "Expression must be of scalar type." ); diff --git a/src/amdis/assembler/StokesOperator.hpp b/src/amdis/assembler/StokesOperator.hpp index 8b6aa6a5..b9dd5032 100644 --- a/src/amdis/assembler/StokesOperator.hpp +++ b/src/amdis/assembler/StokesOperator.hpp @@ -20,12 +20,13 @@ namespace AMDiS /// Stokes operator \f$ \langle\nabla\mathbf{v}, \nu \nabla\mathbf{u}\rangle + \langle\nabla\cdot\mathbf{v}, p\rangle + \langle q, \langle\nabla\cdot\mathbf{u}\rangle \f$ - template <class ViscosityExpr> - class GridFunctionOperator<tag::stokes, ViscosityExpr> - : public GridFunctionOperatorBase<GridFunctionOperator<tag::stokes, ViscosityExpr>, ViscosityExpr> + template <class LocalContext, class ViscosityExpr> + class GridFunctionOperator<tag::stokes, LocalContext, ViscosityExpr> + : public GridFunctionOperatorBase<GridFunctionOperator<tag::stokes, LocalContext, ViscosityExpr>, + LocalContext, ViscosityExpr> { using Self = GridFunctionOperator; - using Super = GridFunctionOperatorBase<Self, ViscosityExpr>; + using Super = GridFunctionOperatorBase<Self, LocalContext, ViscosityExpr>; static_assert( Category::Scalar<typename ViscosityExpr::Range>, "Viscosity must be of scalar type." ); diff --git a/src/amdis/assembler/ZeroOrderTest.hpp b/src/amdis/assembler/ZeroOrderTest.hpp index 39dbdb1f..5639f0c5 100644 --- a/src/amdis/assembler/ZeroOrderTest.hpp +++ b/src/amdis/assembler/ZeroOrderTest.hpp @@ -19,12 +19,13 @@ namespace AMDiS /// zero-order vector-operator \f$ (c\, \psi) \f$ - template <class GridFct> - class GridFunctionOperator<tag::test, GridFct> - : public GridFunctionOperatorBase<GridFunctionOperator<tag::test, GridFct>, GridFct> + template <class LocalContext, class GridFct> + class GridFunctionOperator<tag::test, LocalContext, GridFct> + : public GridFunctionOperatorBase<GridFunctionOperator<tag::test, LocalContext, GridFct>, + LocalContext, GridFct> { using Self = GridFunctionOperator; - using Super = GridFunctionOperatorBase<Self, GridFct>; + using Super = GridFunctionOperatorBase<Self, LocalContext, GridFct>; static_assert( Category::Scalar<typename GridFct::Range>, "Expression must be of scalar type." ); diff --git a/src/amdis/assembler/ZeroOrderTestTrial.hpp b/src/amdis/assembler/ZeroOrderTestTrial.hpp index 2315ea92..47b0e4d3 100644 --- a/src/amdis/assembler/ZeroOrderTestTrial.hpp +++ b/src/amdis/assembler/ZeroOrderTestTrial.hpp @@ -19,12 +19,13 @@ namespace AMDiS /// zero-order operator \f$ \langle\psi, c\,\phi\rangle \f$ - template <class GridFct> - class GridFunctionOperator<tag::test_trial, GridFct> - : public GridFunctionOperatorBase<GridFunctionOperator<tag::test_trial, GridFct>, GridFct> + template <class LocalContext, class GridFct> + class GridFunctionOperator<tag::test_trial, LocalContext, GridFct> + : public GridFunctionOperatorBase<GridFunctionOperator<tag::test_trial, LocalContext, GridFct>, + LocalContext, GridFct> { using Self = GridFunctionOperator; - using Super = GridFunctionOperatorBase<Self, GridFct>; + using Super = GridFunctionOperatorBase<Self, LocalContext, GridFct>; static_assert( Category::Scalar<typename GridFct::Range>, "Expression must be of scalar type." ); diff --git a/src/amdis/assembler/ZeroOrderTestTrialvec.hpp b/src/amdis/assembler/ZeroOrderTestTrialvec.hpp index a4dbec12..352cacfc 100644 --- a/src/amdis/assembler/ZeroOrderTestTrialvec.hpp +++ b/src/amdis/assembler/ZeroOrderTestTrialvec.hpp @@ -19,12 +19,13 @@ namespace AMDiS /// zero-order operator \f$ \langle\psi, \mathbf{b}\cdot\Phi\rangle \f$ - template <class GridFct> - class GridFunctionOperator<tag::test_trialvec, GridFct> - : public GridFunctionOperatorBase<GridFunctionOperator<tag::test_trialvec, GridFct>, GridFct> + template <class LocalContext, class GridFct> + class GridFunctionOperator<tag::test_trialvec, LocalContext, GridFct> + : public GridFunctionOperatorBase<GridFunctionOperator<tag::test_trialvec, LocalContext, GridFct>, + LocalContext, GridFct> { using Self = GridFunctionOperator; - using Super = GridFunctionOperatorBase<Self, GridFct>; + using Super = GridFunctionOperatorBase<Self, LocalContext, GridFct>; static_assert( Category::Vector<typename GridFct::Range>, "Expression must be of vector type." ); diff --git a/src/amdis/assembler/ZeroOrderTestvec.hpp b/src/amdis/assembler/ZeroOrderTestvec.hpp index 68a3fe3f..0a6c876c 100644 --- a/src/amdis/assembler/ZeroOrderTestvec.hpp +++ b/src/amdis/assembler/ZeroOrderTestvec.hpp @@ -19,12 +19,13 @@ namespace AMDiS /// zero-order vector-operator \f$ (\mathbf{b}\cdot\Psi) \f$ - template <class GridFct> - class GridFunctionOperator<tag::testvec, GridFct> - : public GridFunctionOperatorBase<GridFunctionOperator<tag::testvec, GridFct>, GridFct> + template <class LocalContext, class GridFct> + class GridFunctionOperator<tag::testvec, LocalContext, GridFct> + : public GridFunctionOperatorBase<GridFunctionOperator<tag::testvec, LocalContext, GridFct>, + LocalContext, GridFct> { using Self = GridFunctionOperator; - using Super = GridFunctionOperatorBase<Self, GridFct>; + using Super = GridFunctionOperatorBase<Self, LocalContext, GridFct>; static_assert( Category::Vector<typename GridFct::Range>, "Expression must be of vector type." ); diff --git a/src/amdis/assembler/ZeroOrderTestvecTrial.hpp b/src/amdis/assembler/ZeroOrderTestvecTrial.hpp index ad67fa57..f37c6aa4 100644 --- a/src/amdis/assembler/ZeroOrderTestvecTrial.hpp +++ b/src/amdis/assembler/ZeroOrderTestvecTrial.hpp @@ -18,13 +18,13 @@ namespace AMDiS /// zero-order operator \f$ \langle\Psi, \mathbf{b}\,\phi\rangle \f$ - template <class GridFct> - class GridFunctionOperator<tag::testvec_trial, GridFct> - : public GridFunctionOperatorTransposed<GridFunctionOperator<tag::testvec_trial, GridFct>, - GridFunctionOperator<tag::test_trialvec, GridFct>> + template <class LocalContext, class GridFct> + class GridFunctionOperator<tag::testvec_trial, LocalContext, GridFct> + : public GridFunctionOperatorTransposed<GridFunctionOperator<tag::testvec_trial, LocalContext, GridFct>, + GridFunctionOperator<tag::test_trialvec, LocalContext, GridFct>> { using Self = GridFunctionOperator; - using Transposed = GridFunctionOperator<tag::test_trialvec, GridFct>; + using Transposed = GridFunctionOperator<tag::test_trialvec, LocalContext, GridFct>; using Super = GridFunctionOperatorTransposed<Self, Transposed>; public: diff --git a/src/amdis/assembler/ZeroOrderTestvecTrialvec.hpp b/src/amdis/assembler/ZeroOrderTestvecTrialvec.hpp index fefccfbe..f8028777 100644 --- a/src/amdis/assembler/ZeroOrderTestvecTrialvec.hpp +++ b/src/amdis/assembler/ZeroOrderTestvecTrialvec.hpp @@ -19,12 +19,13 @@ namespace AMDiS /// zero-order operator \f$ \langle\Psi, c\,\Phi\rangle \f$, or \f$ \langle\Psi, A\,\Phi\rangle \f$ - template <class GridFct> - class GridFunctionOperator<tag::testvec_trialvec, GridFct> - : public GridFunctionOperatorBase<GridFunctionOperator<tag::testvec_trialvec, GridFct>, GridFct> + template <class LocalContext, class GridFct> + class GridFunctionOperator<tag::testvec_trialvec, LocalContext, GridFct> + : public GridFunctionOperatorBase<GridFunctionOperator<tag::testvec_trialvec, LocalContext, GridFct>, + LocalContext, GridFct> { using Self = GridFunctionOperator; - using Super = GridFunctionOperatorBase<Self, GridFct>; + using Super = GridFunctionOperatorBase<Self, LocalContext, GridFct>; using expr_value_type = typename GridFct::Range; static_assert( Category::Scalar<expr_value_type> || Category::Matrix<expr_value_type>, diff --git a/src/amdis/gridfunctions/AnalyticGridFunction.hpp b/src/amdis/gridfunctions/AnalyticGridFunction.hpp index 0faaa28d..055bfff1 100644 --- a/src/amdis/gridfunctions/AnalyticGridFunction.hpp +++ b/src/amdis/gridfunctions/AnalyticGridFunction.hpp @@ -42,6 +42,7 @@ namespace AMDiS Range operator()(Domain const& local) const { + assert(geometry_.has_value()); return fct_(geometry_.value().global(local)); } diff --git a/src/amdis/utility/Tuple.hpp b/src/amdis/utility/Tuple.hpp index 68e47efc..e6b946de 100644 --- a/src/amdis/utility/Tuple.hpp +++ b/src/amdis/utility/Tuple.hpp @@ -29,7 +29,7 @@ namespace AMDiS // create value through a map of arguments template <class Map, class... Args> - TupleEntry(tag::mapped_arg, Map const& map, Args&&... args) + TupleEntry(tag::mapped_arg, Map&& map, Args&&... args) : value_(map(std::forward<Args>(args)...)) {} @@ -52,7 +52,7 @@ namespace AMDiS { TupleImpl() = default; - /// constructor from sequence of types, disabling this for copy and move constructor + // constructor from sequence of types, disabling this for copy and move constructor template <class... OtherTypes, std::enable_if_t<(sizeof...(OtherTypes) == sizeof...(Types)), int> = 0, std::enable_if_t<none_of_v<IsTupleImpl<std::decay_t<OtherTypes>>::value...>, int> = 0> @@ -60,10 +60,11 @@ namespace AMDiS : TupleEntry<Indices, Types>{std::forward<OtherTypes>(other)}... {} + // constructor using a map to build the elements template <class Map, class... OtherTypes, std::enable_if_t<(sizeof...(OtherTypes) == sizeof...(Types)), int> = 0> - TupleImpl(tag::mapped_arg, Map const& map, OtherTypes&&... other) - : TupleEntry<Indices, Types>{tag::mapped_arg{}, map, std::forward<OtherTypes>(other)}... + TupleImpl(tag::mapped_arg, Map&& map, OtherTypes&&... other) + : TupleEntry<Indices, Types>{tag::mapped_arg{}, std::forward<Map>(map), std::forward<OtherTypes>(other)}... {} }; @@ -77,38 +78,39 @@ namespace AMDiS using Super = Impl::TupleImpl<std::index_sequence_for<Types...>, Types...>; public: + // some default constructors Tuple() = default; Tuple(Tuple const&) = default; Tuple(Tuple&&) = default; Tuple& operator=(Tuple const&) = default; Tuple& operator=(Tuple&&) = default; - // construct from types different from Types, but convertible + /// Construct from types different from Types, but convertible template <class... OtherTypes, std::enable_if_t<(sizeof...(OtherTypes) == sizeof...(Types)), int> = 0> explicit Tuple(OtherTypes&&... other) : Super{std::forward<OtherTypes>(other)...} {} - // constructor from tuple of possibly other types + /// Constructor from tuple of possibly other types template <class... OtherTypes, std::enable_if_t<(sizeof...(OtherTypes) == sizeof...(Types)), int> = 0> explicit Tuple(Tuple<OtherTypes...> const& that) : Super{that} {} - // constructor from tuple of possibly other types + /// Constructor from tuple of possibly other types template <class... OtherTypes, std::enable_if_t<(sizeof...(OtherTypes) == sizeof...(Types)), int> = 0> explicit Tuple(Tuple<OtherTypes...>&& that) : Super{std::move(that)} {} - // constructor using a map to build the elements + /// Constructor using a map to build the elements template <class Map, class... OtherTypes, std::enable_if_t<(sizeof...(OtherTypes) == sizeof...(Types)), int> = 0> - Tuple(tag::mapped_arg, Map const& map, OtherTypes&&... other) - : Super{tag::mapped_arg{}, map, std::forward<OtherTypes>(other)...} + Tuple(tag::mapped_arg, Map&& map, OtherTypes&&... other) + : Super{tag::mapped_arg{}, std::forward<Map>(map), std::forward<OtherTypes>(other)...} {} /// Get the I'th tuple element by reference @@ -126,6 +128,12 @@ namespace AMDiS Impl::TupleEntry<I, TupleElement_t<I, AMDiS::Types<Types...>>> const& base = *this; return base.value_; } + + /// Return the number of elements in this tuple + constexpr std::size_t size() const + { + return sizeof...(Types); + } }; @@ -233,8 +241,7 @@ namespace Dune { namespace Std { -#if ! DUNE_HAVE_CXX_APPLY && ! DUNE_HAVE_CXX_EXPERIMENTAL_APPLY - using AMDiS::Impl::apply; -#endif + using AMDiS::Impl::apply; + } // end namespace Std } // end namespace Dune -- GitLab