From 00b09ad2d117c456f316d431c6210ddd01b9885f Mon Sep 17 00:00:00 2001 From: Simon Praetorius <simon.praetorius@tu-dresden.de> Date: Sat, 30 Dec 2017 02:07:11 +0100 Subject: [PATCH] allow to pass quadrature rule to makeOperator, cleanup of documentation --- doc/doxygen/Doxylocal | 17 +- dune/amdis/CreatorInterface.hpp | 2 +- dune/amdis/GridFunctionOperator.hpp | 210 +++++++++++++----- dune/amdis/GridFunctions.hpp | 96 +++++++- dune/amdis/LocalAssembler.hpp | 13 +- dune/amdis/Mesh.hpp | 20 +- dune/amdis/Operations.hpp | 10 + dune/amdis/Operators.hpp | 25 ++- .../assembler/FirstOrderDivTestvecTrial.hpp | 21 +- .../assembler/FirstOrderGradTestTrial.hpp | 21 +- .../assembler/FirstOrderGradTestTrialvec.hpp | 21 +- .../assembler/FirstOrderPartialTestTrial.hpp | 21 +- .../assembler/FirstOrderTestDivTrialvec.hpp | 21 +- .../assembler/FirstOrderTestGradTrial.hpp | 21 +- .../assembler/FirstOrderTestPartialTrial.hpp | 21 +- .../assembler/FirstOrderTestvecGradTrial.hpp | 21 +- .../SecondOrderDivTestvecDivTrialvec.hpp | 21 +- .../SecondOrderGradTestGradTrial.hpp | 21 +- .../SecondOrderPartialTestPartialTrial.hpp | 25 ++- dune/amdis/assembler/ZeroOrderTest.hpp | 21 +- dune/amdis/assembler/ZeroOrderTestTrial.hpp | 21 +- .../amdis/assembler/ZeroOrderTestTrialvec.hpp | 21 +- dune/amdis/assembler/ZeroOrderTestvec.hpp | 21 +- .../amdis/assembler/ZeroOrderTestvecTrial.hpp | 21 +- .../assembler/ZeroOrderTestvecTrialvec.hpp | 21 +- dune/amdis/common/Concepts.hpp | 26 +-- dune/amdis/common/ConceptsBase.hpp | 13 +- dune/amdis/common/Math.hpp | 8 +- dune/amdis/common/ScalarTypes.hpp | 10 +- dune/amdis/common/Utility.hpp | 24 -- .../gridfunctions/AnalyticGridFunction.hpp | 124 +++++------ .../gridfunctions/ConstantGridFunction.hpp | 30 +-- dune/amdis/gridfunctions/DOFVectorView.hpp | 17 +- .../gridfunctions/DerivativeGridFunction.hpp | 50 +++-- .../gridfunctions/FunctorGridFunction.hpp | 187 +++++++--------- .../gridfunctions/GridFunctionConcepts.hpp | 6 + .../gridfunctions/OperationsGridFunction.hpp | 78 +++++++ .../linear_algebra/mtl/Preconditioner.hpp | 6 +- dune/amdis/operations/Arithmetic.hpp | 65 ++++-- dune/amdis/operations/Basic.hpp | 50 ++++- dune/amdis/operations/CMath.hpp | 3 +- dune/amdis/operations/Composer.hpp | 4 + dune/amdis/operations/FieldMatVec.hpp | 5 +- 43 files changed, 980 insertions(+), 480 deletions(-) diff --git a/doc/doxygen/Doxylocal b/doc/doxygen/Doxylocal index 46c6ffc5..b014153b 100644 --- a/doc/doxygen/Doxylocal +++ b/doc/doxygen/Doxylocal @@ -10,25 +10,30 @@ INTERNAL_DOCS = NO MARKDOWN_SUPPORT = YES EXCLUDE_SYMBOLS = AMDiS::Impl \ - AMDiS::traits::Impl \ + AMDiS::Math::Impl_ \ + AMDiS::Concepts::Impl_ \ AMDiS::detail \ itl::details - + PREDEFINED += HAVE_UMFPACK \ HAVE_ALBERTA \ HAVE_UG \ AMDIS_BACKEND_MTL - + # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT += @top_srcdir@/dune/amdis \ + @top_srcdir@/dune/amdis/assembler \ @top_srcdir@/dune/amdis/common \ - @top_srcdir@/dune/amdis/utility \ + @top_srcdir@/dune/amdis/gridfunctions \ + @top_srcdir@/dune/amdis/io \ @top_srcdir@/dune/amdis/linear_algebra \ - @top_srcdir@/dune/amdis/linear_algebra/mtl + @top_srcdir@/dune/amdis/linear_algebra/mtl \ + @top_srcdir@/dune/amdis/operations \ + @top_srcdir@/dune/amdis/utility # see e.g. dune-grid for the examples of mainpage and modules #INPUT += @srcdir@/mainpage \ # @srcdir@/modules @@ -50,4 +55,4 @@ EXAMPLE_PATH += @top_srcdir@/src # directories that contain image that are included in the documentation (see # the \image command). -# IMAGE_PATH += @top_srcdir@/dune/amdis/pics +# IMAGE_PATH += @top_srcdir@/doc/pics diff --git a/dune/amdis/CreatorInterface.hpp b/dune/amdis/CreatorInterface.hpp index a52e7692..0400989f 100644 --- a/dune/amdis/CreatorInterface.hpp +++ b/dune/amdis/CreatorInterface.hpp @@ -30,7 +30,7 @@ namespace AMDiS * Must be implemented by sub classes of CreatorInterface. * Creates a new instance of the sub class of BaseClass. */ - virtual shared_ptr<BaseClass> create() = 0; + virtual std::shared_ptr<BaseClass> create() = 0; }; /** diff --git a/dune/amdis/GridFunctionOperator.hpp b/dune/amdis/GridFunctionOperator.hpp index 76ee06bb..2a2197f2 100644 --- a/dune/amdis/GridFunctionOperator.hpp +++ b/dune/amdis/GridFunctionOperator.hpp @@ -9,7 +9,31 @@ namespace AMDiS { - template <class GridFunction> + /** + * \addtogroup operators + * @{ + **/ + + /// \brief The main implementation of an operator to be used in a \ref LocalAssembler. + /** + * An Operator that takes a GridFunction as coefficient. + * Provides quadrature rules and handles the evaluation of the GridFunction at + * local coordinates. + * + * The class is specialized, by deriving from it, in \ref GridFunctionOperator. + * + * \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:** + * - `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 GridFunction, class QuadratureCreator> class GridFunctionOperatorBase { using LocalFunction = decltype(localFunction(std::declval<GridFunction>())); @@ -25,11 +49,11 @@ namespace AMDiS * \ref ExpressionBase, and stores a copy. Additionally, it gets the * differentiation order, to calculate the quadrature degree in \ref getDegree. **/ - GridFunctionOperatorBase(GridFunction const& gridFct, int order, int degree = -1) + GridFunctionOperatorBase(GridFunction const& gridFct, QuadratureCreator creator, int order) : gridFct_(gridFct) , localFct_(localFunction(gridFct_)) + , quadCreator_(creator) , order_(order) - , degree_(degree) {} /// \brief Binds operator to `element` and `geometry`. @@ -57,7 +81,7 @@ namespace AMDiS localFct_.unbind(); } - /// Return expressions iq'th value. Must be initialized in \ref init before. + /// Return expression value at LocalCoordinates auto coefficient(LocalCoordinate const& local) const { assert( bound_ ); @@ -65,6 +89,16 @@ namespace AMDiS } + /// Create a quadrature rule using the \ref QuadratureCreator by calculating the + /// quadrature order necessary to integrate the (bi)linear-form accurately. + template <class... Nodes> + decltype(auto) getQuadratureRule(Dune::GeometryType type, Nodes const&... nodes) const + { + auto degreeFunctor = [&,this](int order) -> int { return this->getDegree(order, nodes...); }; + return quadCreator_(type, localFct_, degreeFunctor); + } + + protected: /// \brief Return the quadrature degree for a vector operator. /** * The quadrature degree that is necessary, to integrate the expression @@ -72,12 +106,11 @@ namespace AMDiS * the order of derivatives, this operator implements. **/ template <class Node> - int getDegree(Node const& node) const + int getDegree(int coeffDegree, Node const& node) const { assert( bound_ ); int psiDegree = getPolynomialDegree(node); - int coeffDegree = getGridFctDegree(localFct_); int degree = psiDegree + coeffDegree; if (isSimplex_) @@ -96,13 +129,12 @@ namespace AMDiS * the order of derivatives, this operator implements. **/ template <class RowNode, class ColNode> - int getDegree(RowNode const& rowNode, ColNode const& colNode) const + int getDegree(int coeffDegree, RowNode const& rowNode, ColNode const& colNode) const { assert( bound_ ); int psiDegree = getPolynomialDegree(rowNode); int phiDegree = getPolynomialDegree(colNode); - int coeffDegree = getGridFctDegree(localFct_); int degree = psiDegree + phiDegree + coeffDegree; if (isSimplex_) @@ -113,27 +145,12 @@ namespace AMDiS return degree; } - protected: - template <class LocalFct, - REQUIRES(Concepts::HasOrder<LocalFct>)> - int getGridFctDegree(LocalFct const& localFct) const - { - return degree_ >= 0 ? degree_ : order(localFct_); - } - - template <class LocalFct, - REQUIRES(not Concepts::HasOrder<LocalFct>)> - int getGridFctDegree(LocalFct const& localFct) const - { - return degree_; - } - private: GridFunction gridFct_; LocalFunction localFct_; - int order_; //< the derivative order of this operator - int degree_; //< the polynomial order of the gridFunction + QuadratureCreator quadCreator_; //< a creator to provide a quadrature rule + int order_; //< the derivative order of this operator bool isSimplex_ = false; //< the bound element is a simplex bool isAffine_ = false; //< the bound geometry is affine @@ -147,13 +164,13 @@ namespace AMDiS * \ref calculateElementMatrix, if it is a vector or matrix operator, * respectively. **/ - template <class Tag, class GridFct> + template <class Tag, class GridFct, class QuadratureCreator> class GridFunctionOperator - : public GridFunctionOperatorBase<GridFct> + : public GridFunctionOperatorBase<GridFct, QuadratureCreator> { public: - GridFunctionOperator(Tag, GridFct const& gridFct) - : GridFunctionOperatorBase<GridFct>(gridFct, 0) + GridFunctionOperator(Tag, GridFct const& gridFct, QuadratureCreator const& quadCreator) + : GridFunctionOperatorBase<GridFct, QuadratureCreator>(gridFct, 0, quadCreator) {} /// Assemble a local element vector on the element that is bound. @@ -184,6 +201,8 @@ namespace AMDiS } }; + +#ifndef DOXYGEN namespace Concepts { namespace Definition @@ -202,66 +221,157 @@ namespace AMDiS } // end namespace Concepts + namespace tag + { + struct deduce {}; + struct order {}; + struct rule {}; + + } // end namespace tag + + + template <class Tag, class Expr, class QuadTag, class Rule = void> + struct ExpressionPreOperator; + template <class Tag, class Expr> - struct ExpressionPreOperator + struct ExpressionPreOperator<Tag, Expr, tag::deduce> + { + Tag tag; + Expr expr; + }; + + template <class Tag, class Expr> + struct ExpressionPreOperator<Tag, Expr, tag::order> + { + Tag tag; + Expr expr; + int order; + Dune::QuadratureType::Enum qt; + }; + + template <class Tag, class Expr, class Rule> + struct ExpressionPreOperator<Tag, Expr, tag::rule, Rule> { Tag tag; Expr expr; - int order = -1; + Rule const& rule; }; +#endif - /// Store tag and expression in struct + + /// Store tag and expression to create a \ref GridFunctionOperator template <class Tag, class Expr> auto makeOperator(Tag t, Expr const& expr) { using RawExpr = Underlying_t<Expr>; static_assert(Concepts::HasGridFunctionOrder<RawExpr>, - "Polynomial degree of expression can not be deduced. You need to provide an explicit value for polynomial order in `makeOperator()`."); + "Polynomial degree of expression can not be deduced. You need to provide an explicit value for polynomial order or a quadrature rule in `makeOperator()`."); - return ExpressionPreOperator<Tag, Expr>{t, expr}; + return ExpressionPreOperator<Tag, Expr, tag::deduce>{t, expr}; } + /// Store tag and expression and polynomial order of expression to create a \ref GridFunctionOperator template <class Tag, class Expr> - auto makeOperator(Tag t, Expr const& expr, int order) + auto makeOperator(Tag t, Expr const& expr, int order, + Dune::QuadratureType::Enum qt = Dune::QuadratureType::GaussLegendre) + { + return ExpressionPreOperator<Tag, Expr, tag::order>{t, expr, order, qt}; + } + + /// Store tag and expression and a quadrature rule to create a \ref GridFunctionOperator + template <class Tag, class Expr, class ctype, int dim> + auto makeOperator(Tag t, Expr const& expr, Dune::QuadratureRule<ctype,dim> const& rule) { - return ExpressionPreOperator<Tag, Expr>{t, expr, order}; + return ExpressionPreOperator<Tag, Expr, tag::rule, Dune::QuadratureRule<ctype,dim>>{t, expr, rule}; } + /** @} **/ + +#ifndef DOXYGEN + + namespace Impl + { + // Deduce polynomial order of expression automatically. Create standard quadrature rule with degree + // build up of operator derivative order, and polynomial degrees of trial/test functions. + template <class Tag, class Expr, class GridView> + auto makeQuadCreator(ExpressionPreOperator<Tag, Expr, tag::deduce> const& /*op*/, GridView const& /*gridView*/) + { + using QuadratureRules = Dune::QuadratureRules<typename GridView::ctype, GridView::dimension>; + return [](auto type, auto&& localFct, auto getDegree) -> auto const& + { + return QuadratureRules::rule(type, getDegree(order(localFct))); + }; + } + + // Provide polynomial order of expression explicitly + template <class Tag, class Expr, class GridView> + auto makeQuadCreator(ExpressionPreOperator<Tag, Expr, tag::order> const& op, GridView const& /*gridView*/) + { + using QuadratureRules = Dune::QuadratureRules<typename GridView::ctype, GridView::dimension>; + return [order=op.order,qt=op.qt](auto type, auto&& /*localFct*/, auto getDegree) -> auto const& + { + return QuadratureRules::rule(type, getDegree(order), qt); + }; + } + + // Provide quadrature rule explicitly + template <class Tag, class Expr, class Rule, class GridView> + auto makeQuadCreator(ExpressionPreOperator<Tag, Expr, tag::rule, Rule> const& op, GridView const& /*gridView*/) + { + return [&rule=op.rule](auto&&...) -> auto const& + { + return rule; + }; + } + + } // end namespace Impl + + /// Generate an \ref GridFunctionOperator from a PreOperator (tag, expr). /// @{ - template <class Tag, class Expr, class GridView> - auto makeGridOperator(ExpressionPreOperator<Tag, Expr> const& op, GridView const& gridView) + template <class Tag, class... Args, class GridView> + auto makeGridOperator(ExpressionPreOperator<Tag, Args...> const& op, GridView const& gridView) { auto gridFct = makeGridFunction(op.expr, gridView); - return GridFunctionOperator<Tag, decltype(gridFct)>{op.tag, gridFct, op.order}; + auto quadCreator = Impl::makeQuadCreator(op, gridView); + using GridFctOp = GridFunctionOperator<Tag, decltype(gridFct), decltype(quadCreator)>; + return GridFctOp{op.tag, gridFct, quadCreator}; } - template <class Tag, class Expr, class GridView> - auto makeGridOperator(std::reference_wrapper<ExpressionPreOperator<Tag, Expr>> op, GridView const& gridView) + template <class Tag, class... Args, class GridView> + auto makeGridOperator(std::reference_wrapper<ExpressionPreOperator<Tag, Args...>> op, GridView const& gridView) { - ExpressionPreOperator<Tag, Expr> const& op_ref = op; + ExpressionPreOperator<Tag, Args...> const& op_ref = op; auto gridFct = makeGridFunction(std::ref(op_ref.expr), gridView); - return GridFunctionOperator<Tag, decltype(gridFct)>{op_ref.tag, gridFct, op_ref.order}; + auto quadCreator = Impl::makeQuadCreator(op_ref, gridView); + using GridFctOp = GridFunctionOperator<Tag, decltype(gridFct), decltype(quadCreator)>; + return GridFctOp{op_ref.tag, gridFct, quadCreator}; } /// @} /// Generate a shared_ptr to \ref GridFunctionOperator from a PreOperator (tag, expr). /// @{ - template <class Tag, class Expr, class GridView> - auto makeGridOperatorPtr(ExpressionPreOperator<Tag, Expr> const& op, GridView const& gridView) + template <class Tag, class... Args, class GridView> + auto makeGridOperatorPtr(ExpressionPreOperator<Tag, Args...> const& op, GridView const& gridView) { auto gridFct = makeGridFunction(op.expr, gridView); - return std::make_shared<GridFunctionOperator<Tag, decltype(gridFct)>>(op.tag, gridFct, op.order); + auto quadCreator = Impl::makeQuadCreator(op, gridView); + using GridFctOp = GridFunctionOperator<Tag, decltype(gridFct), decltype(quadCreator)>; + return std::make_shared<GridFctOp>(op.tag, gridFct, quadCreator); } - template <class Tag, class Expr, class GridView> - auto makeGridOperatorPtr(std::reference_wrapper<ExpressionPreOperator<Tag, Expr>> op, GridView const& gridView) + template <class Tag, class... Args, class GridView> + auto makeGridOperatorPtr(std::reference_wrapper<ExpressionPreOperator<Tag, Args...>> op, GridView const& gridView) { - ExpressionPreOperator<Tag, Expr> const& op_ref = op; + ExpressionPreOperator<Tag, Args...> const& op_ref = op; auto gridFct = makeGridFunction(std::ref(op_ref.expr), gridView); - return std::make_shared<GridFunctionOperator<Tag, decltype(gridFct)>>(op_ref.tag, gridFct, op_ref.order); + auto quadCreator = Impl::makeQuadCreator(op_ref, gridView); + using GridFctOp = GridFunctionOperator<Tag, decltype(gridFct), decltype(quadCreator)>; + return std::make_shared<GridFctOp>(op_ref.tag, gridFct, quadCreator); } /// @} +#endif // DOXYGEN + } // end namespace AMDiS diff --git a/dune/amdis/GridFunctions.hpp b/dune/amdis/GridFunctions.hpp index 841feff2..2bcff0d1 100644 --- a/dune/amdis/GridFunctions.hpp +++ b/dune/amdis/GridFunctions.hpp @@ -1,5 +1,66 @@ #pragma once +/** + * \defgroup GridFunctions GridFunction module + * \brief Defines GridFunctions to be used in operators, boundary-conditions, + * interpolation and integration. + * + * GridFunctions are expressions build up of some elementary terms and can be + * used to construct a \ref GridFunctionOperator, can be interpolated to a + * \ref DOFVector, and can be integrated over a GridView. + * + * Thus, GridFunctions are an important incredient to formulate the bilinear + * and linear forms und to postprocess the solutions. + * + * **Examples:** + * 1. Usage of GridFunctions to build Operators: + * ``` + * ProblemStat<Traits> prob("name"); + * prob.initialize(INIT_ALL); + * + * auto opB = makeOperator(BiLinearForm, Expression); + * prob.addMatrixOperator(opB, Row, Col); + * + * auto opL = makeOperator(LinearForm, Expression); + * prob.addVectorOperator(opL, Row); + * ``` + * + * 2. Usage of GridFunctions in BoundaryConditions: + * ``` + * prob.addDirichletBC(Predicate, Row, Col, Expression); + * ``` + * + * 3. Interpolate a GridFunction to a DOFVector: + * ``` + * prob.getSolution(_0).interpol(Expression); + * ``` + * + * 4. Integrate a GridFunction on a GridView: + * ``` + * auto value = integrate(Expression, prob.leafGridView()); + * ``` + * + * **Remarks:** + * - An `Expression` is anything, a GridFunction can be created from, sometimes + * also called PreGridFunction. It includes constants, functors callable with + * GlobalCoordinates, and any combination of GridFunctions. + * - Anything that needs a quadrature formula, e.g., makeOperator() and + * integrate(), needs to determine the (approximative) polynomial degree of + * the GridFunctions. If the Gridfunction builds a polynomial expression, it + * can be deduced automatically, i.e. if it includes constants, DOFVectors, + * 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 + * polynomial degree of the expression, or a quadrature rule explicitly. + * + * *Examples:* + * + `auto op1 = makeOperator(B, 1.0 + pow<2>(prob.getSolution(_0)));` + * + `auto op2 = makeOperator(B, sin(X(0)), 4);` + * + `auto op3 = makeOperator(B, sin(X(0)), Dune::QuadratureRules(Dune::GeometryType::simplex, 4));` + * + `auto value1 = integrate(sin(X(0)), 4);` + **/ + #include <dune/amdis/gridfunctions/AnalyticGridFunction.hpp> #include <dune/amdis/gridfunctions/ConstantGridFunction.hpp> #include <dune/amdis/gridfunctions/CoordsGridFunction.hpp> @@ -9,7 +70,40 @@ namespace AMDiS { - // Generator for Gridfunctions from Pre-Gridfunctions + /// \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) { diff --git a/dune/amdis/LocalAssembler.hpp b/dune/amdis/LocalAssembler.hpp index 0519ed73..d49095b8 100644 --- a/dune/amdis/LocalAssembler.hpp +++ b/dune/amdis/LocalAssembler.hpp @@ -83,14 +83,11 @@ namespace AMDiS ElementMatrixVector& elementMatrixVector, Nodes const&... nodes) final { - decltype(auto) localGeometry = getLocalGeometry(localContext); - - using QuadratureRules = Dune::QuadratureRules<typename Geometry::ctype, LocalContext::mydimension>; - int degree = op_.getDegree(nodes...); - auto const& quad = QuadratureRules::rule(localGeometry.type(), degree); + auto&& localGeometry = getLocalGeometry(localContext); + auto&& quad = op_.getQuadratureRule(localGeometry.type(), nodes...); Context data{localContext, getGeometry(), localGeometry}; - assembleImpl(data, quad, elementMatrixVector, nodes...); + assembleImpl(data, std::forward<decltype(quad)>(quad), elementMatrixVector, nodes...); return true; } @@ -199,7 +196,7 @@ namespace AMDiS /// Generate a \ref LocalAssembler on a given `LocalContext` (element or intersection) template <class LocalContext, class Operator, class... Nodes, - std::enable_if_t<not traits::is_reference_wrapper<Operator>::value, int> = 0> + std::enable_if_t<not Traits::IsReferenceWrapper<Operator>::value, int> = 0> auto makeLocalAssembler(Operator const& op, Nodes const&...) { return LocalAssembler<LocalContext, Operator, Nodes...>{op}; @@ -213,7 +210,7 @@ namespace AMDiS /// Generate a shared_ptr to \ref LocalAssembler on a given `LocalContext` (element or intersection) template <class LocalContext, class Operator, class... Nodes, - std::enable_if_t<not traits::is_reference_wrapper<Operator>::value, int> = 0> + std::enable_if_t<not Traits::IsReferenceWrapper<Operator>::value, int> = 0> auto makeLocalAssemblerPtr(Operator const& op, Nodes const&...) { return std::make_shared<LocalAssembler<LocalContext, Operator, Nodes...>>(op); diff --git a/dune/amdis/Mesh.hpp b/dune/amdis/Mesh.hpp index 10c88b99..ea09a268 100644 --- a/dune/amdis/Mesh.hpp +++ b/dune/amdis/Mesh.hpp @@ -70,7 +70,7 @@ namespace AMDiS template <class Grid> class MeshCreator { - static unique_ptr<Grid> create(std::string meshName) + static std::unique_ptr<Grid> create(std::string meshName) { error_exit("Creator not yet implemented for this mesh type."); } @@ -82,7 +82,7 @@ namespace AMDiS { using Grid = Dune::AlbertaGrid<dim, dimworld>; - static unique_ptr<Grid> create(std::string meshName) + static std::unique_ptr<Grid> create(std::string meshName) { std::string macro_filename = ""; Parameters::get(meshName + "->macro file name", macro_filename); @@ -90,7 +90,7 @@ namespace AMDiS // TODO: if filename_extension is ".2d" or ".3d" read it directly from file // otherwise use a factory method - return make_unique<Grid>(macro_filename); + return std::make_unique<Grid>(macro_filename); } }; #endif @@ -102,7 +102,7 @@ namespace AMDiS { using Grid = Dune::UGGrid<dim>; - static unique_ptr<Grid> create(std::string meshName) + static std::unique_ptr<Grid> create(std::string meshName) { std::string filename = ""; @@ -117,12 +117,12 @@ namespace AMDiS Dune::GridFactory<Grid> factory; Dune::AlbertaReader<Grid> reader; reader.readGrid(filename, factory); - return unique_ptr<Grid>{factory.createGrid()}; + return std::unique_ptr<Grid>{factory.createGrid()}; } #endif if (ext == "msh") { Dune::GmshReader<Grid> reader; - return unique_ptr<Grid>{reader.read(filename)}; + return std::unique_ptr<Grid>{reader.read(filename)}; } } else { error_exit("Construction of UGGrid without filename not yet implemented!"); @@ -139,7 +139,7 @@ namespace AMDiS { using Grid = Dune::YaspGrid<dim, Dune::EquidistantCoordinates<T,dim>>; - static unique_ptr<Grid> create(std::string meshName) + static std::unique_ptr<Grid> create(std::string meshName) { Dune::FieldVector<double, dim> L; L = 1.0; // extension of the domain Parameters::get(meshName + "->dimension", L); @@ -151,7 +151,7 @@ namespace AMDiS // TODO: add more parameters for yasp-grid (see constructor) - return make_unique<Grid>(L, s); + return std::make_unique<Grid>(L, s); } }; @@ -161,7 +161,7 @@ namespace AMDiS { using Grid = Dune::YaspGrid<dim, Dune::EquidistantOffsetCoordinates<T, dim>>; - static unique_ptr<Grid> create(std::string meshName) + static std::unique_ptr<Grid> create(std::string meshName) { Dune::FieldVector<double, dim> lowerleft; lowerleft = 0.0; // Lower left corner of the domain Dune::FieldVector<double, dim> upperright; upperright = 1.0; // Upper right corner of the domain @@ -173,7 +173,7 @@ namespace AMDiS // TODO: add more parameters for yasp-grid (see constructor) - return make_unique<Grid>(lowerleft, upperright, s); + return std::make_unique<Grid>(lowerleft, upperright, s); } }; diff --git a/dune/amdis/Operations.hpp b/dune/amdis/Operations.hpp index d798bcbc..d3bfcd15 100644 --- a/dune/amdis/Operations.hpp +++ b/dune/amdis/Operations.hpp @@ -1,5 +1,15 @@ #pragma once +/** + * \defgroup operations Functor module + * \brief Collection of functor that can be used in Expression and + * in \ref FunctorGridFunction. + * + * Functors wrapping arithmetic and other mathematical operations + * with definition of polynomial order (if applicable) and partial + * derivatives w.r.t. the functor arguments. + **/ + #include <dune/amdis/operations/Arithmetic.hpp> #include <dune/amdis/operations/Basic.hpp> #include <dune/amdis/operations/CMath.hpp> diff --git a/dune/amdis/Operators.hpp b/dune/amdis/Operators.hpp index 6ab4d429..01092cfb 100644 --- a/dune/amdis/Operators.hpp +++ b/dune/amdis/Operators.hpp @@ -3,7 +3,7 @@ #include <dune/amdis/LocalAssembler.hpp> #include <dune/amdis/GridFunctionOperator.hpp> -/** +/* * In the following comments we use the notation * psi ... scalar testfunction * Psi ... vector testfunction @@ -14,6 +14,29 @@ * c ..... scalar coefficient */ + +/** + * \defgroup operators Operator module + * \brief Defines operators to be assembled in the matrix/vector + * + * An `Operator` is a class providing methods necessary for assembling: + * - `void bind(Element, Geometry)` and `void unbind()` for binding an unbinding the + * element to (from) an GridView entity of codim 0. Additionally the Geometry + * object of the element is provided. + * - `Dune::QuadratureRule<ctype,dim> getQuadratureRule(Nodes...)` factory for the + * quadrature rules used in assembling the operator on the element. `Nodes...` + * is either `{RowNode, ColNode}` for Matrix-Operators or `{Node}` for a + * Vector-Operator. + * - `void calculateElementVector(ContextGeometry, QuadratureRule, ElementVector, Node)` + * where the `ContextGeometry` provides a reference to the ElementGeometry and + * geometry of the LocalContext (that can be different), *or* + * - `void calculateElementMatrix(ContextGeometry, QuadratureRule, ElementMatrix, RowNode, ColNode, Flags...)` + * Same as for `calculateElementVector` but additionally two optimization flags + * are provided as `bool_t<...>` type: + * + `sameFE`: the FiniteElementSpace of `RowNode` and `ColNode` are the same. + * + `sameNode`: the nodes are the same in the GlobalBasis-tree. + **/ + // zero-order operators #include <dune/amdis/assembler/ZeroOrderTest.hpp> // <psi * c> #include <dune/amdis/assembler/ZeroOrderTestTrial.hpp> // <psi, c * phi> diff --git a/dune/amdis/assembler/FirstOrderDivTestvecTrial.hpp b/dune/amdis/assembler/FirstOrderDivTestvecTrial.hpp index 901ccbd9..2c6ee725 100644 --- a/dune/amdis/assembler/FirstOrderDivTestvecTrial.hpp +++ b/dune/amdis/assembler/FirstOrderDivTestvecTrial.hpp @@ -6,22 +6,27 @@ namespace AMDiS { + /** + * \addtogroup operators + * @{ + **/ + namespace tag { struct divtestvec_trial {}; } - // first-order operator <div(Psi), c*phi> - template <class GridFct> - class GridFunctionOperator<tag::divtestvec_trial, GridFct> - : public GridFunctionOperator<tag::test_divtrialvec, GridFct> + /// first-order operator \f$ \langle\nabla\cdot\Psi, c\,\phi\rangle \f$ + template <class GridFct, class QuadCreator> + class GridFunctionOperator<tag::divtestvec_trial, GridFct, QuadCreator> + : public GridFunctionOperator<tag::test_divtrialvec, GridFct, QuadCreator> { - using Transposed = GridFunctionOperator<tag::test_divtrialvec, GridFct>; + using Transposed = GridFunctionOperator<tag::test_divtrialvec, GridFct, QuadCreator>; public: - GridFunctionOperator(tag::divtestvec_trial, GridFct const& expr, int degree) - : Transposed(tag::test_divtrialvec{}, expr, degree) + GridFunctionOperator(tag::divtestvec_trial, GridFct const& expr, QuadCreator const& quadCreator) + : Transposed(tag::test_divtrialvec{}, expr, quadCreator) {} template <class Context, class QuadratureRule, @@ -43,4 +48,6 @@ namespace AMDiS } }; + /** @} **/ + } // end namespace AMDiS diff --git a/dune/amdis/assembler/FirstOrderGradTestTrial.hpp b/dune/amdis/assembler/FirstOrderGradTestTrial.hpp index 099ec710..453e7388 100644 --- a/dune/amdis/assembler/FirstOrderGradTestTrial.hpp +++ b/dune/amdis/assembler/FirstOrderGradTestTrial.hpp @@ -6,22 +6,27 @@ namespace AMDiS { + /** + * \addtogroup operators + * @{ + **/ + namespace tag { struct gradtest_trial {}; } - // first-order operator <grad(psi), b*phi> - template <class GridFct> - class GridFunctionOperator<tag::gradtest_trial, GridFct> - : public GridFunctionOperator<tag::test_gradtrial, GridFct> + /// first-order operator \f$ \langle\nabla\psi, \mathbf{b}\,\phi\rangle \f$ + template <class GridFct, class QuadCreator> + class GridFunctionOperator<tag::gradtest_trial, GridFct, QuadCreator> + : public GridFunctionOperator<tag::test_gradtrial, GridFct, QuadCreator> { - using Transposed = GridFunctionOperator<tag::test_gradtrial, GridFct>; + using Transposed = GridFunctionOperator<tag::test_gradtrial, GridFct, QuadCreator>; public: - GridFunctionOperator(tag::gradtest_trial, GridFct const& expr, int degree) - : Transposed(tag::test_gradtrial{}, expr, degree) + GridFunctionOperator(tag::gradtest_trial, GridFct const& expr, QuadCreator const& quadCreator) + : Transposed(tag::test_gradtrial{}, expr, quadCreator) {} template <class Context, class QuadratureRule, @@ -40,4 +45,6 @@ namespace AMDiS } }; + /** @} **/ + } // end namespace AMDiS diff --git a/dune/amdis/assembler/FirstOrderGradTestTrialvec.hpp b/dune/amdis/assembler/FirstOrderGradTestTrialvec.hpp index 0389e379..e74f0990 100644 --- a/dune/amdis/assembler/FirstOrderGradTestTrialvec.hpp +++ b/dune/amdis/assembler/FirstOrderGradTestTrialvec.hpp @@ -6,22 +6,27 @@ namespace AMDiS { + /** + * \addtogroup operators + * @{ + **/ + namespace tag { struct gradtest_trialvec {}; } - // first-order operator <grad(psi), c*Phi> - template <class GridFct> - class GridFunctionOperator<tag::gradtest_trialvec, GridFct> - : public GridFunctionOperator<tag::testvec_gradtrial, GridFct> + /// first-order operator \f$ \langle\nabla\psi, c\,\Phi\rangle \f$ + template <class GridFct, class QuadCreator> + class GridFunctionOperator<tag::gradtest_trialvec, GridFct, QuadCreator> + : public GridFunctionOperator<tag::testvec_gradtrial, GridFct, QuadCreator> { - using Transposed = GridFunctionOperator<tag::testvec_gradtrial, GridFct>; + using Transposed = GridFunctionOperator<tag::testvec_gradtrial, GridFct, QuadCreator>; public: - GridFunctionOperator(tag::gradtest_trialvec, GridFct const& expr, int degree) - : Transposed(tag::testvec_gradtrial{}, expr, degree) + GridFunctionOperator(tag::gradtest_trialvec, GridFct const& expr, QuadCreator const& quadCreator) + : Transposed(tag::testvec_gradtrial{}, expr, quadCreator) {} template <class Context, class QuadratureRule, @@ -40,4 +45,6 @@ namespace AMDiS } }; + /** @} **/ + } // end namespace AMDiS diff --git a/dune/amdis/assembler/FirstOrderPartialTestTrial.hpp b/dune/amdis/assembler/FirstOrderPartialTestTrial.hpp index 5dc71d5c..6a90d5c7 100644 --- a/dune/amdis/assembler/FirstOrderPartialTestTrial.hpp +++ b/dune/amdis/assembler/FirstOrderPartialTestTrial.hpp @@ -6,6 +6,11 @@ namespace AMDiS { + /** + * \addtogroup operators + * @{ + **/ + namespace tag { struct partialtest_trial @@ -15,16 +20,16 @@ namespace AMDiS } - // first-order operator <d_i(psi), c*phi> - template <class GridFct> - class GridFunctionOperator<tag::partialtest_trial, GridFct> - : public GridFunctionOperator<tag::test_partialtrial, GridFct> + /// first-order operator \f$ \langle\partial_i\psi, c\,\phi\rangle \f$ + template <class GridFct, class QuadCreator> + class GridFunctionOperator<tag::partialtest_trial, GridFct, QuadCreator> + : public GridFunctionOperator<tag::test_partialtrial, GridFct, QuadCreator> { - using Transposed = GridFunctionOperator<tag::test_partialtrial, GridFct>; + using Transposed = GridFunctionOperator<tag::test_partialtrial, GridFct, QuadCreator>; public: - GridFunctionOperator(tag::partialtest_trial tag, GridFct const& expr, int degree) - : Transposed(tag::test_partialtrial{tag.comp}, expr, degree) + GridFunctionOperator(tag::partialtest_trial tag, GridFct const& expr, QuadCreator const& quadCreator) + : Transposed(tag::test_partialtrial{tag.comp}, expr, quadCreator) {} template <class Context, class QuadratureRule, @@ -43,4 +48,6 @@ namespace AMDiS } }; + /** @} **/ + } // end namespace AMDiS diff --git a/dune/amdis/assembler/FirstOrderTestDivTrialvec.hpp b/dune/amdis/assembler/FirstOrderTestDivTrialvec.hpp index c4876307..448d4caf 100644 --- a/dune/amdis/assembler/FirstOrderTestDivTrialvec.hpp +++ b/dune/amdis/assembler/FirstOrderTestDivTrialvec.hpp @@ -8,24 +8,29 @@ namespace AMDiS { + /** + * \addtogroup operators + * @{ + **/ + namespace tag { struct test_divtrialvec {}; } - // first-order operator <psi, c*div(Phi)> - template <class GridFct> - class GridFunctionOperator<tag::test_divtrialvec, GridFct> - : public GridFunctionOperatorBase<GridFct> + /// first-order operator \f$ \langle\psi, c\,\nabla\cdot\Phi\rangle \f$ + template <class GridFct, class QuadCreator> + class GridFunctionOperator<tag::test_divtrialvec, GridFct, QuadCreator> + : public GridFunctionOperatorBase<GridFct, QuadCreator> { - using Super = GridFunctionOperatorBase<GridFct>; + using Super = GridFunctionOperatorBase<GridFct, QuadCreator>; static_assert( Category::Scalar<typename GridFct::Range>, "Expression must be of scalar type." ); public: - GridFunctionOperator(tag::test_divtrialvec, GridFct const& expr, int degree) - : Super(expr, 1, degree) + GridFunctionOperator(tag::test_divtrialvec, GridFct const& expr, QuadCreator const& quadCreator) + : Super(expr, quadCreator, 1) {} template <class Context, class QuadratureRule, @@ -88,4 +93,6 @@ namespace AMDiS std::vector<Dune::FieldVector<double,1>> rowShapeValues_; }; + /** @} **/ + } // end namespace AMDiS diff --git a/dune/amdis/assembler/FirstOrderTestGradTrial.hpp b/dune/amdis/assembler/FirstOrderTestGradTrial.hpp index bcf93f95..08981ff9 100644 --- a/dune/amdis/assembler/FirstOrderTestGradTrial.hpp +++ b/dune/amdis/assembler/FirstOrderTestGradTrial.hpp @@ -8,24 +8,29 @@ namespace AMDiS { + /** + * \addtogroup operators + * @{ + **/ + namespace tag { struct test_gradtrial {}; } - // first-order operator <psi, b*grad(phi)> - template <class GridFct> - class GridFunctionOperator<tag::test_gradtrial, GridFct> - : public GridFunctionOperatorBase<GridFct> + /// first-order operator \f$ \langle\psi, \mathbf{b}\cdot\nabla\phi\rangle \f$ + template <class GridFct, class QuadCreator> + class GridFunctionOperator<tag::test_gradtrial, GridFct, QuadCreator> + : public GridFunctionOperatorBase<GridFct, QuadCreator> { - using Super = GridFunctionOperatorBase<GridFct>; + using Super = GridFunctionOperatorBase<GridFct, QuadCreator>; static_assert( Category::Vector<typename GridFct::Range>, "Expression must be of vector type." ); public: - GridFunctionOperator(tag::test_gradtrial, GridFct const& expr, int degree) - : Super(expr, 1, degree) + GridFunctionOperator(tag::test_gradtrial, GridFct const& expr, QuadCreator const& quadCreator) + : Super(expr, quadCreator, 1) {} template <class Context, class QuadratureRule, @@ -84,4 +89,6 @@ namespace AMDiS std::vector<Dune::FieldVector<double,1>> rowShapeValues_; }; + /** @} **/ + } // end namespace AMDiS diff --git a/dune/amdis/assembler/FirstOrderTestPartialTrial.hpp b/dune/amdis/assembler/FirstOrderTestPartialTrial.hpp index 36b0ef9f..83357be7 100644 --- a/dune/amdis/assembler/FirstOrderTestPartialTrial.hpp +++ b/dune/amdis/assembler/FirstOrderTestPartialTrial.hpp @@ -8,6 +8,11 @@ namespace AMDiS { + /** + * \addtogroup operators + * @{ + **/ + namespace tag { struct test_partialtrial @@ -17,18 +22,18 @@ namespace AMDiS } - // first-order operator <psi, c*d_i(phi)> - template <class GridFct> - class GridFunctionOperator<tag::test_partialtrial, GridFct> - : public GridFunctionOperatorBase<GridFct> + /// first-order operator \f$ \langle\psi, c\,\partial_i\phi\rangle \f$ + template <class GridFct, class QuadCreator> + class GridFunctionOperator<tag::test_partialtrial, GridFct, QuadCreator> + : public GridFunctionOperatorBase<GridFct, QuadCreator> { - using Super = GridFunctionOperatorBase<GridFct>; + using Super = GridFunctionOperatorBase<GridFct, QuadCreator>; static_assert( Category::Scalar<typename GridFct::Range>, "Expression must be of scalar type." ); public: - GridFunctionOperator(tag::test_partialtrial tag, GridFct const& expr, int degree) - : Super(expr, 1, degree) + GridFunctionOperator(tag::test_partialtrial tag, GridFct const& expr, QuadCreator const& quadCreator) + : Super(expr, quadCreator, 1) , comp_(tag.comp) {} @@ -91,4 +96,6 @@ namespace AMDiS std::vector<Dune::FieldVector<double,1>> rowShapeValues_; }; + /** @} **/ + } // end namespace AMDiS diff --git a/dune/amdis/assembler/FirstOrderTestvecGradTrial.hpp b/dune/amdis/assembler/FirstOrderTestvecGradTrial.hpp index cb1cfd97..674d59a6 100644 --- a/dune/amdis/assembler/FirstOrderTestvecGradTrial.hpp +++ b/dune/amdis/assembler/FirstOrderTestvecGradTrial.hpp @@ -8,24 +8,29 @@ namespace AMDiS { + /** + * \addtogroup operators + * @{ + **/ + namespace tag { struct testvec_gradtrial {}; } - // first-order operator <Psi, c*grad(phi)> - template <class GridFct> - class GridFunctionOperator<tag::testvec_gradtrial, GridFct> - : public GridFunctionOperatorBase<GridFct> + /// first-order operator \f$ \langle\Psi, c\,\nabla\phi\rangle \f$ + template <class GridFct, class QuadCreator> + class GridFunctionOperator<tag::testvec_gradtrial, GridFct, QuadCreator> + : public GridFunctionOperatorBase<GridFct, QuadCreator> { - using Super = GridFunctionOperatorBase<GridFct>; + using Super = GridFunctionOperatorBase<GridFct, QuadCreator>; static_assert( Category::Scalar<typename GridFct::Range>, "Expression must be of scalar type." ); public: - GridFunctionOperator(tag::testvec_gradtrial, GridFct const& expr, int degree) - : Super(expr, 1, degree) + GridFunctionOperator(tag::testvec_gradtrial, GridFct const& expr, QuadCreator const& quadCreator) + : Super(expr, quadCreator, 1) {} template <class Context, class QuadratureRule, @@ -88,4 +93,6 @@ namespace AMDiS std::vector<Dune::FieldVector<double,1>> rowShapeValues_; }; + /** @} **/ + } // end namespace AMDiS diff --git a/dune/amdis/assembler/SecondOrderDivTestvecDivTrialvec.hpp b/dune/amdis/assembler/SecondOrderDivTestvecDivTrialvec.hpp index 726a2091..19f54ff6 100644 --- a/dune/amdis/assembler/SecondOrderDivTestvecDivTrialvec.hpp +++ b/dune/amdis/assembler/SecondOrderDivTestvecDivTrialvec.hpp @@ -8,24 +8,29 @@ namespace AMDiS { + /** + * \addtogroup operators + * @{ + **/ + namespace tag { struct divtestvec_divtrialvec {}; } - // second-order operator <div(Psi), c * div(Phi)> - template <class GridFct> - class GridFunctionOperator<tag::divtestvec_divtrialvec, GridFct> - : public GridFunctionOperatorBase<GridFct> + /// second-order operator \f$ \langle\nabla\cdot\Psi, c\,\nabla\cdot\Phi\rangle \f$ + template <class GridFct, class QuadCreator> + class GridFunctionOperator<tag::divtestvec_divtrialvec, GridFct, QuadCreator> + : public GridFunctionOperatorBase<GridFct, QuadCreator> { - using Super = GridFunctionOperatorBase<GridFct>; + using Super = GridFunctionOperatorBase<GridFct, QuadCreator>; static_assert( Category::Scalar<typename GridFct::Range>, "Expression must be of scalar type." ); public: - GridFunctionOperator(tag::divtestvec_divtrialvec, GridFct const& expr, int degree) - : Super(expr, 2, degree) + GridFunctionOperator(tag::divtestvec_divtrialvec, GridFct const& expr, QuadCreator const& quadCreator) + : Super(expr, quadCreator, 2) {} template <class Context, class QuadratureRule, @@ -142,4 +147,6 @@ namespace AMDiS } }; + /** @} **/ + } // end namespace AMDiS diff --git a/dune/amdis/assembler/SecondOrderGradTestGradTrial.hpp b/dune/amdis/assembler/SecondOrderGradTestGradTrial.hpp index d170b902..65c07e4b 100644 --- a/dune/amdis/assembler/SecondOrderGradTestGradTrial.hpp +++ b/dune/amdis/assembler/SecondOrderGradTestGradTrial.hpp @@ -8,26 +8,31 @@ namespace AMDiS { + /** + * \addtogroup operators + * @{ + **/ + namespace tag { struct gradtest_gradtrial {}; } - // second-order operator <grad(psi), c * grad(phi)>, or <grad(psi), A * grad(phi)> - template <class GridFct> - class GridFunctionOperator<tag::gradtest_gradtrial, GridFct> - : public GridFunctionOperatorBase<GridFct> + /// 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 QuadCreator> + class GridFunctionOperator<tag::gradtest_gradtrial, GridFct, QuadCreator> + : public GridFunctionOperatorBase<GridFct, QuadCreator> { - using Super = GridFunctionOperatorBase<GridFct>; + using Super = GridFunctionOperatorBase<GridFct, QuadCreator>; using expr_value_type = typename GridFct::Range; static_assert( Category::Scalar<expr_value_type> || Category::Matrix<expr_value_type>, "Expression must be of scalar or matrix type." ); public: - GridFunctionOperator(tag::gradtest_gradtrial, GridFct const& expr, int degree) - : Super(expr, 2, degree) + GridFunctionOperator(tag::gradtest_gradtrial, GridFct const& expr, QuadCreator const& quadCreator) + : Super(expr, quadCreator, 2) {} template <class Context, class QuadratureRule, @@ -206,4 +211,6 @@ namespace AMDiS } }; + /** @} **/ + } // end namespace AMDiS diff --git a/dune/amdis/assembler/SecondOrderPartialTestPartialTrial.hpp b/dune/amdis/assembler/SecondOrderPartialTestPartialTrial.hpp index 2f373404..50a722fb 100644 --- a/dune/amdis/assembler/SecondOrderPartialTestPartialTrial.hpp +++ b/dune/amdis/assembler/SecondOrderPartialTestPartialTrial.hpp @@ -8,28 +8,33 @@ namespace AMDiS { + /** + * \addtogroup operators + * @{ + **/ + namespace tag { struct partialtest_partialtrial { - int comp_test; - int comp_trial; + int comp_test; // i + int comp_trial; // j }; } - // second-order operator <d_i(psi), c * d_j(phi)> - template <class GridFct> - class GridFunctionOperator<tag::partialtest_partialtrial, GridFct> - : public GridFunctionOperatorBase<GridFct> + /// second-order operator \f$ \langle\partial_i\psi, c\,\partial_j\phi\rangle \f$ + template <class GridFct, class QuadCreator> + class GridFunctionOperator<tag::partialtest_partialtrial, GridFct, QuadCreator> + : public GridFunctionOperatorBase<GridFct, QuadCreator> { - using Super = GridFunctionOperatorBase<GridFct>; + using Super = GridFunctionOperatorBase<GridFct, QuadCreator>; static_assert( Category::Scalar<typename GridFct::Range>, "Expression must be of scalar type." ); public: - GridFunctionOperator(tag::partialtest_partialtrial tag, GridFct const& expr, int degree) - : Super(expr, 2, degree) + GridFunctionOperator(tag::partialtest_partialtrial tag, GridFct const& expr, QuadCreator const& quadCreator) + : Super(expr, quadCreator, 2) , compTest_(tag.comp_test) , compTrial_(tag.comp_trial) {} @@ -102,4 +107,6 @@ namespace AMDiS int compTrial_; }; + /** @} **/ + } // end namespace AMDiS diff --git a/dune/amdis/assembler/ZeroOrderTest.hpp b/dune/amdis/assembler/ZeroOrderTest.hpp index f6e2105a..416e9182 100644 --- a/dune/amdis/assembler/ZeroOrderTest.hpp +++ b/dune/amdis/assembler/ZeroOrderTest.hpp @@ -7,24 +7,29 @@ namespace AMDiS { + /** + * \addtogroup operators + * @{ + **/ + namespace tag { struct test {}; } - // zero-order vector-operator <c * psi> - template <class GridFct> - class GridFunctionOperator<tag::test, GridFct> - : public GridFunctionOperatorBase<GridFct> + /// zero-order vector-operator \f$ (c\, \psi) \f$ + template <class GridFct, class QuadCreator> + class GridFunctionOperator<tag::test, GridFct, QuadCreator> + : public GridFunctionOperatorBase<GridFct, QuadCreator> { - using Super = GridFunctionOperatorBase<GridFct>; + using Super = GridFunctionOperatorBase<GridFct, QuadCreator>; static_assert( Category::Scalar<typename GridFct::Range>, "Expression must be of scalar type." ); public: - GridFunctionOperator(tag::test, GridFct const& expr, int degree) - : Super(expr, 0, degree) + GridFunctionOperator(tag::test, GridFct const& expr, QuadCreator const& quadCreator) + : Super(expr, quadCreator, 0) {} template <class Context, class QuadratureRule, @@ -58,4 +63,6 @@ namespace AMDiS std::vector<Dune::FieldVector<double,1>> shapeValues_; }; + /** @} **/ + } // end namespace AMDiS diff --git a/dune/amdis/assembler/ZeroOrderTestTrial.hpp b/dune/amdis/assembler/ZeroOrderTestTrial.hpp index 6bf13a84..7cc42bb1 100644 --- a/dune/amdis/assembler/ZeroOrderTestTrial.hpp +++ b/dune/amdis/assembler/ZeroOrderTestTrial.hpp @@ -7,24 +7,29 @@ namespace AMDiS { + /** + * \addtogroup operators + * @{ + **/ + namespace tag { struct test_trial {}; } - // zero-order operator <psi, c * phi> - template <class GridFct> - class GridFunctionOperator<tag::test_trial, GridFct> - : public GridFunctionOperatorBase<GridFct> + /// zero-order operator \f$ \langle\psi, c\,\phi\rangle \f$ + template <class GridFct, class QuadCreator> + class GridFunctionOperator<tag::test_trial, GridFct, QuadCreator> + : public GridFunctionOperatorBase<GridFct, QuadCreator> { - using Super = GridFunctionOperatorBase<GridFct>; + using Super = GridFunctionOperatorBase<GridFct, QuadCreator>; static_assert( Category::Scalar<typename GridFct::Range>, "Expression must be of scalar type." ); public: - GridFunctionOperator(tag::test_trial, GridFct const& expr, int degree) - : Super(expr, 0, degree) + GridFunctionOperator(tag::test_trial, GridFct const& expr, QuadCreator const& quadCreator) + : Super(expr, quadCreator, 0) {} template <class Context, class QuadratureRule, @@ -116,4 +121,6 @@ namespace AMDiS std::vector<Dune::FieldVector<double,1>> colShapeValues_; }; + /** @} **/ + } // end namespace AMDiS diff --git a/dune/amdis/assembler/ZeroOrderTestTrialvec.hpp b/dune/amdis/assembler/ZeroOrderTestTrialvec.hpp index 88b4e344..d3481ef3 100644 --- a/dune/amdis/assembler/ZeroOrderTestTrialvec.hpp +++ b/dune/amdis/assembler/ZeroOrderTestTrialvec.hpp @@ -7,24 +7,29 @@ namespace AMDiS { + /** + * \addtogroup operators + * @{ + **/ + namespace tag { struct test_trialvec {}; } - // zero-order operator <psi, b * Phi> - template <class GridFct> - class GridFunctionOperator<tag::test_trialvec, GridFct> - : public GridFunctionOperatorBase<GridFct> + /// zero-order operator \f$ \langle\psi, \mathbf{b}\cdot\Phi\rangle \f$ + template <class GridFct, class QuadCreator> + class GridFunctionOperator<tag::test_trialvec, GridFct, QuadCreator> + : public GridFunctionOperatorBase<GridFct, QuadCreator> { - using Super = GridFunctionOperatorBase<GridFct>; + using Super = GridFunctionOperatorBase<GridFct, QuadCreator>; static_assert( Category::Vector<typename GridFct::Range>, "Expression must be of vector type." ); public: - GridFunctionOperator(tag::test_trialvec, GridFct const& expr, int degree) - : Super(expr, 0, degree) + GridFunctionOperator(tag::test_trialvec, GridFct const& expr, QuadCreator const& quadCreator) + : Super(expr, quadCreator, 0) {} template <class Context, class QuadratureRule, @@ -81,4 +86,6 @@ namespace AMDiS std::vector<Dune::FieldVector<double,1>> colShapeValues_; }; + /** @} **/ + } // end namespace AMDiS diff --git a/dune/amdis/assembler/ZeroOrderTestvec.hpp b/dune/amdis/assembler/ZeroOrderTestvec.hpp index 95803abc..8e9333ea 100644 --- a/dune/amdis/assembler/ZeroOrderTestvec.hpp +++ b/dune/amdis/assembler/ZeroOrderTestvec.hpp @@ -7,24 +7,29 @@ namespace AMDiS { + /** + * \addtogroup operators + * @{ + **/ + namespace tag { struct testvec {}; } - // zero-order vector-operator <b * Psi> - template <class GridFct> - class GridFunctionOperator<tag::testvec, GridFct> - : public GridFunctionOperatorBase<GridFct> + /// zero-order vector-operator \f$ (\mathbf{b}\cdot\Psi) \f$ + template <class GridFct, class QuadCreator> + class GridFunctionOperator<tag::testvec, GridFct, QuadCreator> + : public GridFunctionOperatorBase<GridFct, QuadCreator> { - using Super = GridFunctionOperatorBase<GridFct>; + using Super = GridFunctionOperatorBase<GridFct, QuadCreator>; static_assert( Category::Vector<typename GridFct::Range>, "Expression must be of vector type." ); public: - GridFunctionOperator(tag::testvec, GridFct const& expr, int degree) - : Super(expr, 0, degree) + GridFunctionOperator(tag::testvec, GridFct const& expr, QuadCreator const& quadCreator) + : Super(expr, quadCreator, 0) {} template <class Context, class QuadratureRule, @@ -65,4 +70,6 @@ namespace AMDiS std::vector<Dune::FieldVector<double,1>> shapeValues_; }; + /** @} **/ + } // end namespace AMDiS diff --git a/dune/amdis/assembler/ZeroOrderTestvecTrial.hpp b/dune/amdis/assembler/ZeroOrderTestvecTrial.hpp index a24b4e8e..3081f7fc 100644 --- a/dune/amdis/assembler/ZeroOrderTestvecTrial.hpp +++ b/dune/amdis/assembler/ZeroOrderTestvecTrial.hpp @@ -6,22 +6,27 @@ namespace AMDiS { + /** + * \addtogroup operators + * @{ + **/ + namespace tag { struct testvec_trial {}; } - // zero-order operator <Psi, b * phi> - template <class GridFct> - class GridFunctionOperator<tag::testvec_trial, GridFct> - : public GridFunctionOperator<tag::test_trialvec, GridFct> + /// zero-order operator \f$ \langle\Psi, \mathbf{b}\,\phi\rangle \f$ + template <class GridFct, class QuadCreator> + class GridFunctionOperator<tag::testvec_trial, GridFct, QuadCreator> + : public GridFunctionOperator<tag::test_trialvec, GridFct, QuadCreator> { - using Transposed = GridFunctionOperator<tag::test_trialvec, GridFct>; + using Transposed = GridFunctionOperator<tag::test_trialvec, GridFct, QuadCreator>; public: - GridFunctionOperator(tag::testvec_trial, GridFct const& expr, int degree) - : Transposed(tag::test_trialvec{}, expr, degree) + GridFunctionOperator(tag::testvec_trial, GridFct const& expr, QuadCreator const& quadCreator) + : Transposed(tag::test_trialvec{}, expr, quadCreator) {} template <class Context, class QuadratureRule, @@ -40,4 +45,6 @@ namespace AMDiS } }; + /** @} **/ + } // end namespace AMDiS diff --git a/dune/amdis/assembler/ZeroOrderTestvecTrialvec.hpp b/dune/amdis/assembler/ZeroOrderTestvecTrialvec.hpp index ea37c691..5a3dee57 100644 --- a/dune/amdis/assembler/ZeroOrderTestvecTrialvec.hpp +++ b/dune/amdis/assembler/ZeroOrderTestvecTrialvec.hpp @@ -7,26 +7,31 @@ namespace AMDiS { + /** + * \addtogroup operators + * @{ + **/ + namespace tag { struct testvec_trialvec {}; } - // zero-order operator <Psi, c * Phi>, or <Psi, A * Phi> - template <class GridFct> - class GridFunctionOperator<tag::testvec_trialvec, GridFct> - : public GridFunctionOperatorBase<GridFct> + /// zero-order operator \f$ \langle\Psi, c\,\Phi\rangle \f$, or \f$ \langle\Psi, A\,\Phi\rangle \f$ + template <class GridFct, class QuadCreator> + class GridFunctionOperator<tag::testvec_trialvec, GridFct, QuadCreator> + : public GridFunctionOperatorBase<GridFct, QuadCreator> { - using Super = GridFunctionOperatorBase<GridFct>; + using Super = GridFunctionOperatorBase<GridFct, QuadCreator>; using expr_value_type = typename GridFct::Range; static_assert( Category::Scalar<expr_value_type> || Category::Matrix<expr_value_type>, "Expression must be of scalar or matrix type." ); public: - GridFunctionOperator(tag::testvec_trialvec, GridFct const& expr, int degree) - : Super(expr, 0, degree) + GridFunctionOperator(tag::testvec_trialvec, GridFct const& expr, QuadCreator const& quadCreator) + : Super(expr, quadCreator, 0) {} template <class Context, class QuadratureRule, @@ -210,4 +215,6 @@ namespace AMDiS std::vector<Dune::FieldVector<double,1>> colShapeValues_; }; + /** @} **/ + } // end namespace AMDiS diff --git a/dune/amdis/common/Concepts.hpp b/dune/amdis/common/Concepts.hpp index 3c10a0e3..56eaf9cd 100644 --- a/dune/amdis/common/Concepts.hpp +++ b/dune/amdis/common/Concepts.hpp @@ -10,37 +10,37 @@ namespace AMDiS { /** - * \defgroup concept Concepts + * \defgroup Concepts Concepts * \brief Concept definitions * @{ **/ - namespace traits + namespace Traits { template <class A, class B> - struct is_compatible + struct IsSimilar : std::is_same<std::decay_t<A>, std::decay_t<B>> {}; template <class A, class B> - struct is_compatible<Types<A>, Types<B>> - : is_compatible<A,B> {}; + struct IsSimilar<Types<A>, Types<B>> + : IsSimilar<A,B> {}; template <> - struct is_compatible<Types<>, Types<>> : std::true_type {}; + struct IsSimilar<Types<>, Types<>> : std::true_type {}; template <class A0, class... As, class B0, class... Bs> - struct is_compatible<Types<A0,As...>, Types<B0,Bs...>> - : and_t<is_compatible<A0, B0>::value, is_compatible<Types<As...>, Types<Bs...>>::value> {}; + struct IsSimilar<Types<A0,As...>, Types<B0,Bs...>> + : and_t<IsSimilar<A0, B0>::value, IsSimilar<Types<As...>, Types<Bs...>>::value> {}; template <class T> - struct is_reference_wrapper + struct IsReferenceWrapper : std::false_type {}; template <class T> - struct is_reference_wrapper<std::reference_wrapper<T>> + struct IsReferenceWrapper<std::reference_wrapper<T>> : std::true_type {}; - } // end namespace traits + } // end namespace Traits namespace Concepts { @@ -111,13 +111,13 @@ namespace AMDiS #endif // DOXYGEN - /// \brief Argument `A` id (implicitly) convertible to arguemnt `B` and vice versa. + /// \brief Argument `A` is (implicitly) convertible to arguemnt `B` and vice versa. template <class A, class B > constexpr bool Convertible = std::is_convertible<A,B>::value && std::is_convertible<B,A>::value; /// Types are the same, up to decay of qualifiers template <class A, class B> - constexpr bool Compatible = traits::is_compatible<A, B>::value; + constexpr bool Similar = Traits::IsSimilar<A, B>::value; /// \brief Argument A is less-than comparable to type B, i.e. A < B is valid template <class A, class B = A> diff --git a/dune/amdis/common/ConceptsBase.hpp b/dune/amdis/common/ConceptsBase.hpp index 026ce0ba..acb6861a 100644 --- a/dune/amdis/common/ConceptsBase.hpp +++ b/dune/amdis/common/ConceptsBase.hpp @@ -2,7 +2,7 @@ #include <type_traits> -#if defined(DOXYGEN) +#ifdef DOXYGEN #define REQUIRES(...) #define CONCEPT constexpr #else @@ -25,7 +25,7 @@ namespace AMDiS namespace Concepts { - namespace _aux + namespace Impl_ { template <class Concept, class = Void_t<>> struct models @@ -48,12 +48,15 @@ namespace AMDiS #endif }; - } // end namespace _aux + } // end namespace Impl_ + +#ifndef DOXYGEN template <class Concept> - constexpr bool models = _aux::models<Concept>::value; + constexpr bool models = Impl_::models<Concept>::value; - constexpr _aux::valid_expr valid_expr = {}; + constexpr Impl_::valid_expr valid_expr = {}; +#endif // DOXYGEN } // end namespace Concepts diff --git a/dune/amdis/common/Math.hpp b/dune/amdis/common/Math.hpp index 5293b082..450ae037 100644 --- a/dune/amdis/common/Math.hpp +++ b/dune/amdis/common/Math.hpp @@ -27,8 +27,7 @@ namespace AMDiS } -#ifndef DOXYGEN - namespace _aux + namespace Impl_ { template <int> struct int_t {}; template <bool> struct bool_t {}; @@ -60,15 +59,14 @@ namespace AMDiS template <class T> constexpr T pow(int_t<0>, T v) { return T(1); } - } // end namespace _aux -#endif + } // end namespace Impl_ /// Implementation of the power \f$ v^p \f$ of arithmetic types `T`. template <int p, class T> constexpr auto pow(T v) { static_assert( p >= 0, "Exponent p in `pow<p>(v)` should be >= 0," ); - return _aux::pow(_aux::int_t<p>{}, v); + return Impl_::pow(Impl_::int_t<p>{}, v); } diff --git a/dune/amdis/common/ScalarTypes.hpp b/dune/amdis/common/ScalarTypes.hpp index 32502429..3f60c4cb 100644 --- a/dune/amdis/common/ScalarTypes.hpp +++ b/dune/amdis/common/ScalarTypes.hpp @@ -5,14 +5,14 @@ namespace AMDiS { - namespace traits + namespace Traits { template <class T> - struct is_integral + struct IsIntegral : public std::is_integral<std::decay_t<T>> {}; template <class T> - struct is_arithmetic + struct IsArithmetic : public std::is_arithmetic<std::decay_t<T>> {}; } // end namespace traits @@ -26,12 +26,12 @@ namespace AMDiS /// \brief The types following the std type-trait \ref std::is_integral are /// categorized as *integral types*. template <class T> - constexpr bool Integral = traits::is_integral<T>::value; + constexpr bool Integral = Traits::IsIntegral<T>::value; /// \brief The types following the std type-trait \ref std::is_arithmetic are /// categorized as *arithmetic types*. template <class T> - constexpr bool Arithmetic = traits::is_arithmetic<T>::value; + constexpr bool Arithmetic = Traits::IsArithmetic<T>::value; /** @} **/ diff --git a/dune/amdis/common/Utility.hpp b/dune/amdis/common/Utility.hpp index 4e31a99a..e2f01265 100644 --- a/dune/amdis/common/Utility.hpp +++ b/dune/amdis/common/Utility.hpp @@ -10,15 +10,6 @@ namespace AMDiS { - // pull in std implementations - using std::shared_ptr; - using std::make_shared; - - using std::unique_ptr; - using std::make_unique; - - // --------------------------------------------------------------------------- - namespace Impl { // workaround for MSVC (problems with alias templates in pack expansion) @@ -135,19 +126,4 @@ namespace AMDiS return vec[I]; } - - // --------------------------------------------------------------------------- - - - struct VectorComponent - { - std::size_t index; - }; - - struct MatrixComponent - { - std::size_t row; - std::size_t col; - }; - } // end namespace AMDiS diff --git a/dune/amdis/gridfunctions/AnalyticGridFunction.hpp b/dune/amdis/gridfunctions/AnalyticGridFunction.hpp index a07036d4..ab1d1108 100644 --- a/dune/amdis/gridfunctions/AnalyticGridFunction.hpp +++ b/dune/amdis/gridfunctions/AnalyticGridFunction.hpp @@ -9,17 +9,12 @@ #include <dune/amdis/Operations.hpp> #include <dune/amdis/gridfunctions/GridFunctionConcepts.hpp> -#define AMDIS_CALLABLE_DEFAULT_ORDER 4 - namespace AMDiS { - /** - * \addtogroup GridFunctions - * @{ - **/ - +#ifndef DOXYGEN template <class Signature, class LocalContext, class Function> class AnalyticLocalFunction; +#endif template <class R, class D, class LocalContext, class Function> class AnalyticLocalFunction<R(D), LocalContext, Function> @@ -50,6 +45,18 @@ namespace AMDiS return fct_(geometry_.value().global(local)); } + friend auto derivative(AnalyticLocalFunction const& lf) + { + static_assert(Concepts::HasPartial<Function>, + "No partial(_0,...) defined for Functor F of AnalyticLocalFunction."); + + auto df = partial(lf.fct(), index_<0>); + + using RawSignature = typename Dune::Functions::SignatureTraits<R(D)>::RawSignature; + using DerivativeSignature = typename Dune::Functions::DefaultDerivativeTraits<RawSignature>::Range(D); + return AnalyticLocalFunction<DerivativeSignature,LocalContext,decltype(df)>{df}; + } + Function const& fct() const { return fct_; @@ -60,22 +67,8 @@ namespace AMDiS Dune::Std::optional<Geometry> geometry_; }; - - template <class R, class D, class LC, class F> - auto derivative(AnalyticLocalFunction<R(D),LC,F> const& lf) - { - static_assert(Concepts::HasPartial<F>, - "No partial(_0,...) defined for Functor F of AnalyticLocalFunction."); - - auto df = partial(lf.fct(), index_<0>); - - using RawSignature = typename Dune::Functions::SignatureTraits<R(D)>::RawSignature; - using DerivativeSignature = typename Dune::Functions::DefaultDerivativeTraits<RawSignature>::Range(D); - return AnalyticLocalFunction<DerivativeSignature,LC,decltype(df)>{df}; - } - - /// Return the polynomial order of the function f, if a free function - /// order(f) exists, otherwise return a default value. + /// \brief Return the polynomial order of the function f, if a free function + /// order(f) exists, otherwise return a default value. \relates AnalyticLocalFunction template <class Sig, class LocalContext, class F, REQUIRES(Concepts::HasOrder<F>)> int order(AnalyticLocalFunction<Sig,LocalContext,F> const& lf) @@ -84,60 +77,61 @@ namespace AMDiS } -// #ifdef AMDIS_HAS_CXX_CONSTEXPR_IF -// template <class Sig, class LocalContext, class F> -// int order(AnalyticLocalFunction<Sig,LocalContext,F> const& lf) -// { -// if constexpr (Concepts::HasOrder<F>) -// return order(lf.fct(),1); -// else -// return AMDIS_CALLABLE_DEFAULT_ORDER; -// } -// #else -// template <class Sig, class LC, class F> -// int order(AnalyticLocalFunction<Sig,LC,F> const& lf) -// { -// return Dune::Hybrid::ifElse( bool_<Concepts::HasOrder<F>>, -// [&lf](auto id) { return id( order(lf.fct(),1) ); }, -// [] (auto id) { return AMDIS_CALLABLE_DEFAULT_ORDER; } -// ); -// } -// #endif - - - /// A Gridfunction that evaluates a function with global coordinates + /// \class AnalyticGridFunction + /// \brief A Gridfunction that evaluates a function with global coordinates. + /** + * \ingroup GridFunctions + * Implements a GridFunction that wraps a functor around global coordinates. + * + * \tparam Function The callable `f=f(x)` with `x in Domain == GlobalCoordinates` + * \tparam GridView A GridView that models `Dune::GridViewConcept`. + * + * **Requirements:** + * - Function models \ref Concepts::Callable<Domain> + **/ template <class Function, class GridView> class AnalyticGridFunction { public: using EntitySet = Dune::Functions::GridViewEntitySet<GridView, 0>; - using Element = typename EntitySet::Element; - using Domain = typename EntitySet::GlobalCoordinate; - using LocalDomain = typename EntitySet::LocalCoordinate; using Range = std::decay_t<std::result_of_t<Function(Domain)>>; - public: + private: + using Element = typename EntitySet::Element; + using LocalDomain = typename EntitySet::LocalCoordinate; using LocalFunction = AnalyticLocalFunction<Range(LocalDomain), Element, Function>; public: - /// Constructor. Stores the function `fct` and creates an `EntitySet`. + /// \brief Constructor. Stores the function `fct` and creates an `EntitySet`. AnalyticGridFunction(Function const& fct, GridView const& gridView) : fct_(fct) , entitySet_(gridView) {} - /// Return the evaluated functor at global coordinates + /// \brief Return the evaluated functor at global coordinates Range operator()(Domain const& x) const { return fct_(x); } + /// \brief Return the LocalFunction of the AnalyticGridFunction. friend auto localFunction(AnalyticGridFunction const& gf) { return LocalFunction{gf.fct_}; } + /// \brief Return a GridFunction representing the derivative of a functor. + // [expects: Functor f has free function derivative(f)] + friend auto derivative(AnalyticGridFunction const& gf) + { + static_assert(Concepts::HasPartial<Function>, + "No partial(_0,...) defined for Functor of AnalyticLocalFunction."); + + auto df = partial(gf.fct(), index_<0>); + return AnalyticGridFunction<decltype(df), GridView>{df, gf.entitySet().gridView()}; + } + EntitySet const& entitySet() const { return entitySet_; @@ -152,20 +146,8 @@ namespace AMDiS }; - /// Return a GridFunction representing the derivative of a functor. - /// [expects: Functor f has free function derivative(f)] - template <class F, class GV> - auto derivative(AnalyticGridFunction<F,GV> const& gf) - { - static_assert(Concepts::HasPartial<F>, - "No partial(_0,...) defined for Functor of AnalyticLocalFunction."); - - auto df = partial(gf.fct(), index_<0>); - return AnalyticGridFunction<decltype(df), GV>{df, gf.entitySet().gridView()}; - } - - - /// A pre-GridFunction that just stores the function +#ifndef DOXYGEN + // A pre-GridFunction that just stores the function template <class Function> struct AnalyticPreGridFunction { @@ -178,9 +160,18 @@ namespace AMDiS struct IsPreGridFunction<AnalyticPreGridFunction<Functor>> : std::true_type {}; } +#endif - /// Generator function for \ref AnalyticPreGridFunction + /// \fn evalAtQP \brief Generator function for AnalyticGridFunction. \relates AnalyticGridfunction + /** + * \ingroup GridFunctions + * Evaluate a functor at global coordinates. See \ref AnalyticGridFunction. + * + * **Examples:** + * - `evalAtQP([](Dune::FieldVector<double, 2> const& x) { return x[0]; })` + * - `evalAtQP(Operation::TwoNorm{})` + **/ template <class Function, REQUIRES(Concepts::CallableDomain<Function>)> auto evalAtQP(Function const& f) @@ -188,7 +179,6 @@ namespace AMDiS return AnalyticPreGridFunction<Function>{f}; } - /** @} **/ namespace Impl { diff --git a/dune/amdis/gridfunctions/ConstantGridFunction.hpp b/dune/amdis/gridfunctions/ConstantGridFunction.hpp index 9702fe6a..faca6ede 100644 --- a/dune/amdis/gridfunctions/ConstantGridFunction.hpp +++ b/dune/amdis/gridfunctions/ConstantGridFunction.hpp @@ -14,18 +14,7 @@ namespace AMDiS { - /** - * \addtogroup GridFunctions - * @{ - **/ - - /// \brief Gridfunction returning a constant value. - /** - * A stored constant is return in global and local evaluation of this functor. - * May be used with arithmetic types and vectors/matrices of arithmetic types. - * It is also allowed to pass a \ref std::reference_wrapper to allow to - * modify the value after construction. - **/ + /// \brief LocalFunction of a Gridfunction returning a constant value. template <class Signature, class LocalContext, class Function> class ConstantLocalFunction; @@ -52,11 +41,13 @@ namespace AMDiS return value_; } + /// \relates ConstantLocalFunction friend int order(ConstantLocalFunction const& /*lf*/) { return 0; } + /// \relates ConstantLocalFunction friend auto derivative(ConstantLocalFunction const& lf) { using RawSignature = typename Dune::Functions::SignatureTraits<R(D)>::RawSignature; @@ -70,7 +61,18 @@ namespace AMDiS }; - /// A Gridfunction that evaluates a function with global coordinates + /** + * \addtogroup GridFunctions + * @{ + **/ + + /// \brief Gridfunction returning a constant value. + /** + * A stored constant is return in global and local evaluation of this functor. + * May be used with arithmetic types and vectors/matrices of arithmetic types. + * It is also allowed to pass a \ref std::reference_wrapper to allow to + * modify the value after construction. + **/ template <class T, class GridView> class ConstantGridFunction { @@ -98,6 +100,7 @@ namespace AMDiS return value_; } + /// Return the LocalFunction of the \ref ConstantGridFunction. \relates ConstantGridFunction friend auto localFunction(ConstantGridFunction const& gf) { return LocalFunction{gf.value_}; @@ -155,6 +158,7 @@ namespace AMDiS } // end namespace Concepts + namespace Impl { /// Generator for a GridFunction representing a constant value diff --git a/dune/amdis/gridfunctions/DOFVectorView.hpp b/dune/amdis/gridfunctions/DOFVectorView.hpp index ee7555f2..a43158dc 100644 --- a/dune/amdis/gridfunctions/DOFVectorView.hpp +++ b/dune/amdis/gridfunctions/DOFVectorView.hpp @@ -15,8 +15,15 @@ namespace AMDiS { + /** + * \addtogroup GridFunctions + * @{ + **/ + +#ifndef DOXYGEN template <class GlobalBasisType, class TreePathType, bool isConst = true> class DOFVectorView; +#endif template <class GlobalBasisType, class TreePathType> class DOFVectorView<GlobalBasisType, TreePathType, true> @@ -49,6 +56,7 @@ namespace AMDiS public: // a local view on the gradients + /// A LocalFunction representing the derivative of the DOFVector class GradientLocalFunction { public: @@ -124,6 +132,7 @@ namespace AMDiS public: // a local view on the values + /// A LocalFunction, i.e., an element local view on the DOFVector class LocalFunction { public: @@ -169,7 +178,7 @@ namespace AMDiS /// Evaluate LocalFunction at bound element in local coordinates Range operator()(Domain const& x) const; - /// Create a LocalFunction representing the gradient + /// \brief Create a LocalFunction representing the gradient. \relates GradientLocalFunction friend GradientLocalFunction derivative(LocalFunction const& localFunction) { return GradientLocalFunction{*localFunction.globalFunction_}; @@ -216,7 +225,7 @@ namespace AMDiS return Range(0); } - /// Create a local function for this view on the DOFVector + /// \brief Create a local function for this view on the DOFVector. \relates LocalFunction friend LocalFunction localFunction(DOFVectorView const& self) { return LocalFunction{self}; @@ -300,7 +309,10 @@ namespace AMDiS DOFVector<GlobalBasis>* mutableDofVector_; }; + /** @} **/ + +#ifndef DOXYGEN // A Generator for a const \ref DOFVectorView. template <class GlobalBasis, class TreePath> auto makeDOFVectorView(DOFVector<GlobalBasis> const& dofVector, TreePath const& treePath) @@ -331,6 +343,7 @@ namespace AMDiS auto treePath = Dune::TypeTree::hybridTreePath(); return DOFVectorView<GlobalBasis, decltype(treePath), false>{dofVector, treePath}; } +#endif } // end namespace AMDiS diff --git a/dune/amdis/gridfunctions/DerivativeGridFunction.hpp b/dune/amdis/gridfunctions/DerivativeGridFunction.hpp index 73de4866..37c29c85 100644 --- a/dune/amdis/gridfunctions/DerivativeGridFunction.hpp +++ b/dune/amdis/gridfunctions/DerivativeGridFunction.hpp @@ -13,49 +13,65 @@ namespace AMDiS * @{ **/ - /// A Gridfunction that returns the derivative when calling localFunction - template <class GridFct> + /// \brief A Gridfunction that returns the derivative when calling localFunction. + /** + * Wrapps the GridFunction so that \ref localFunction returns a LocalFunction + * representing the derivative of the LocalFunction of the GridFunction. + * + * \tparam GridFunction The GridFunction that is wrapped. + * + * **Requirements:** + * - `GridFunction` models \ref Concepts::GridFunction and the LocalFunction has a derivative. + **/ + template <class GridFunction> class DerivativeGridFunction { - using GridFctRange = typename GridFct::Range; - using GridFctDomain = typename GridFct::Domain; + using GridFctRange = typename GridFunction::Range; + using GridFctDomain = typename GridFunction::Domain; + using RawSignature = typename Dune::Functions::SignatureTraits<GridFctRange(GridFctDomain)>::RawSignature; + using LocalFunction = std::decay_t<decltype(derivative(localFunction(std::declval<GridFunction>())))>; public: - using RawSignature = typename Dune::Functions::SignatureTraits<GridFctRange(GridFctDomain)>::RawSignature; + /// The Range of the derivative of the GridFunction using Range = typename Dune::Functions::DefaultDerivativeTraits<RawSignature>::Range; + /// The domain of the GridFunction using Domain = GridFctDomain; - using LocalFunction = std::decay_t<decltype(derivative(localFunction(std::declval<GridFct>())))>; - - using EntitySet = typename GridFct::EntitySet; + /// The EntitySet of the GridFunction + using EntitySet = typename GridFunction::EntitySet; public: - explicit DerivativeGridFunction(GridFct const& gridFct) + /// Constructor. Stores a copy of gridFct. + explicit DerivativeGridFunction(GridFunction const& gridFct) : gridFct_(gridFct) {} - /// no global derivative available + /// NOTE: no global derivative available Range operator()(Domain const& x) const { error_exit("Not implemented"); return Range(0); } + /// Return the derivative-localFunction of the GridFunction. friend LocalFunction localFunction(DerivativeGridFunction const& gf) { return derivative(localFunction(gf.gridFct_)); } + /// Return the \ref EntitySet of the \ref GridFunction. EntitySet const& entitySet() const { return gridFct_.entitySet(); } private: - GridFct gridFct_; + GridFunction gridFct_; }; + +#ifndef DOXYGEN template <class GridFct, - REQUIRES(not Concepts::HasDerivative<GridFct> && + REQUIRES(not Concepts::HasDerivative<GridFct> && Concepts::HasLocalFunctionDerivative<GridFct>)> auto derivative(GridFct const& gridFct) { @@ -75,9 +91,17 @@ namespace AMDiS struct IsPreGridFunction<DerivativePreGridFunction<Expr>> : std::true_type {}; } +#endif - /// Generator function for \ref DerivativeGridFunction expressions + /// \brief Generator function for DerivativeGridFunction expressions. \relates DerivativeGridFunction + /** + * Generates a derivative of a GridFunction. See \ref DerivativeGridFunction. + * + * **Examples:** + * - `gradientAtQP(prob.getSolution(_0))` + * - `gradientAtQP(X(0) + X(1) + prob.getSolution(_0))` + **/ template <class Expr> auto gradientAtQP(Expr const& expr) { diff --git a/dune/amdis/gridfunctions/FunctorGridFunction.hpp b/dune/amdis/gridfunctions/FunctorGridFunction.hpp index fc4040ae..c8d65e8b 100644 --- a/dune/amdis/gridfunctions/FunctorGridFunction.hpp +++ b/dune/amdis/gridfunctions/FunctorGridFunction.hpp @@ -11,15 +11,8 @@ #include <dune/amdis/common/Mpl.hpp> #include <dune/amdis/gridfunctions/GridFunctionConcepts.hpp> -#define AMDIS_FUNCTOR_DEFAULT_ORDER 4 - namespace AMDiS { - /** - * \addtogroup GridFunctions - * @{ - **/ - namespace Impl { template <class T0, class... Ts> @@ -40,6 +33,7 @@ namespace AMDiS } // end namespace Impl + template <class Signatur, class Functor, class... LocalFunctions> class FunctorLocalFunction; @@ -106,23 +100,85 @@ namespace AMDiS std::tuple<LocalFunctions...> localFcts_; }; + // Derivative of the LocalFunction of a FunctorGridFunction, utilizing + // the chain-rule. Only available of the functor provides partial derivatives. + /* + * \f$ d_x(f(lf(x)...)) = \sum_i d_i(f)[lf(x)...] * derivative(lf[i]) \f$ + */ + template <class Sig, class F, class... LFs, + REQUIRES(Concepts::HasPartial<F>)> + auto derivative(FunctorLocalFunction<Sig,F,LFs...> const& lf) + { + auto index_seq = std::make_index_sequence<sizeof...(LFs)>{}; + + // d_i(f)[lgfs...] * lgfs_i + auto term_i = [&](auto const _i) + { + auto di_f = Dune::Std::apply([&](auto const&... lgfs) { + return makeFunctorGridFunction(partial(lf.fct(), _i), lgfs...); + }, lf.localFcts()); + + auto const& lgfs_i = std::get<_i>(lf.localFcts()); + return makeFunctorGridFunction(Operation::Multiplies{}, di_f, derivative(lgfs_i)); + }; + + // sum_i [ d_i(f)[lgfs...] * derivative(lgfs_i) ] + auto gridFct = Dune::Std::apply([&](auto const... _i) + { + return makeFunctorGridFunction(Operation::Plus{}, term_i(_i)...); + }, index_seq); + + return localFunction(gridFct); + } + + + // Calculate the polynomial order for functors f providing a free functions + // order(f, degs...), where degs are the order of the LocalFunctions. + template <class Sig, class F, class... LFs, + REQUIRES(Concepts::HasFunctorOrder<F,sizeof...(LFs)> + && all_of_v<Concepts::HasOrder<LFs>...>)> + int order(FunctorLocalFunction<Sig,F,LFs...> const& lf) + { + return Dune::Std::apply([&lf](auto const&... gfs) { return order(lf.fct(), order(gfs)...); }, + lf.localFcts()); + } + + + /** + * \addtogroup GridFunctions + * @{ + **/ /// \brief A Gridfunction that applies a functor to the evaluated Gridfunctions + /** + * Composition of GridFunctions `g_i` by applying a functor `f` locally, i.e. locally it is evaluated + * \f$ f(g_0(x), g_1(x), ...) \f$ + * + * \tparam Functor The type of the outer functor `f` + * \tparam GridFunctions... The GridFunction types of `g_i` + * + * Requirements: + * - `arity(f) == sizeof...(GridFunctions)` + * - `arity(g_i) == arity(g_j) for i != j` + * - `g_i` models concept \ref GridFunction + **/ template <class Functor, class... GridFunctions> class FunctorGridFunction { public: + /// The result type of the functor when applied to the grid-functions using Range = typename std::result_of<Functor(typename GridFunctions::Range...)>::type; + /// The argument type that can be applied to the grid-functions using Domain = typename Impl::DomainType<GridFunctions...>::type; - + /// The set of entities this grid-function binds to using EntitySet = typename Impl::EntitySetType<GridFunctions...>::type; - using LocalDomain = typename EntitySet::LocalCoordinate; - public: + private: template <class GridFct> using LocalFct = std::decay_t<decltype(localFunction(std::declval<GridFct>()))>; using RawRange = std::decay_t<Range>; + using LocalDomain = typename EntitySet::LocalCoordinate; using LocalFunction = FunctorLocalFunction<RawRange(LocalDomain), Functor, LocalFct<GridFunctions>...>; public: @@ -133,14 +189,14 @@ namespace AMDiS , gridFcts_(std::forward<GridFcts>(gridFcts)...) {} - /// Applies the functor \ref fct_ to the evaluated gridfunctions + /// Applies the functor to the evaluated gridfunctions Range operator()(Domain const& x) const { return eval(fct_, [&x](auto const& gridFct) { return gridFct(x); }, MakeSeq_t<sizeof...(GridFunctions)>{}); } - /// Creates a LocalFunction from the LocalFunctions of the GridFunctions + /// \brief Creates a LocalFunction from the LocalFunctions of the GridFunctions. \relates FunctorLocalFunction friend LocalFunction localFunction(FunctorGridFunction const& gf) { return Dune::Std::apply([&gf](auto const&... gridFcts) @@ -150,7 +206,7 @@ namespace AMDiS gf.gridFcts_); } - /// Return the stored entityset of the first GridFunction + /// Return the stored \ref EntitySet of the first GridFunction EntitySet const& entitySet() const { return std::get<0>(gridFcts_).entitySet(); @@ -168,7 +224,9 @@ namespace AMDiS std::tuple<GridFunctions...> gridFcts_; }; - /// Generator function for \ref FunctorGridFunction expressions + +#ifndef DOXYGEN + // Generator function for FunctorGridFunction expressions template <class Functor, class... GridFcts> auto makeFunctorGridFunction(Functor const& f, GridFcts const&... gridFcts) { @@ -179,94 +237,7 @@ namespace AMDiS return FunctorGridFunction<Functor, GridFcts...>{f, gridFcts...}; } - - /// Derivative of the LocalFunction of a \ref FunctorGridFunction, utilizing - /// the chain-rule. Only available of the functor provides partial derivatives. - /* - * d_x(f(lf(x)...)) = sum_i d_i(f)[lf(x)...] * derivative(lf[i]) - */ - template <class Sig, class F, class... LFs, - REQUIRES(Concepts::HasPartial<F>)> - auto derivative(FunctorLocalFunction<Sig,F,LFs...> const& lf) - { - auto index_seq = std::make_index_sequence<sizeof...(LFs)>{}; - - // d_i(f)[lgfs...] * lgfs_i - auto term_i = [&](auto const _i) - { - auto di_f = Dune::Std::apply([&](auto const&... lgfs) { - return makeFunctorGridFunction(partial(lf.fct(), _i), lgfs...); - }, lf.localFcts()); - - auto const& lgfs_i = std::get<_i>(lf.localFcts()); - return makeFunctorGridFunction(Operation::Multiplies{}, di_f, derivative(lgfs_i)); - }; - - // sum_i [ d_i(f)[lgfs...] * derivative(lgfs_i) ] - auto gridFct = Dune::Std::apply([&](auto const... _i) - { - return makeFunctorGridFunction(Operation::Plus{}, term_i(_i)...); - }, index_seq); - - return localFunction(gridFct); - } - - -// #ifdef AMDIS_HAS_CXX_CONSTEXPR_IF - -// template <class Sig, class F, class... LFs> -// int order(FunctorLocalFunction<Sig,F,LFs...> const& lf) -// { -// if constexpr (Concepts::HasFunctorOrder<F,sizeof...(LFs)> && -// all_of_v<Concepts::HasOrder<LFs>...>) -// { -// return Dune::Std::apply([&lf](auto const&... lfs) { return order(lf.fct(), order(lfs)...); }, lf.localFcts()); -// } -// else if constexpr (not Concepts::HasFunctorOrder<F,sizeof...(LFs)> && -// all_of_v<Concepts::HasOrder<LFs>...>) -// { -// return Dune::Std::apply([](auto const&... lfs) { return Math::max(order(lfs)...); }, lf.localFcts()); -// } -// else { -// return AMDIS_FUNCTOR_DEFAULT_ORDER; -// } -// } - -// #else - /// Calculate the polynomial order for functors f providing a free functions - /// order(f, degs...), where degs are the order of the LocalFunctions - template <class Sig, class F, class... LFs, - REQUIRES(Concepts::HasFunctorOrder<F,sizeof...(LFs)> - && all_of_v<Concepts::HasOrder<LFs>...>)> - int order(FunctorLocalFunction<Sig,F,LFs...> const& lf) - { - return Dune::Std::apply([&lf](auto const&... gfs) { return order(lf.fct(), order(gfs)...); }, - lf.localFcts()); - } - -// /// Specialization for \ref order for functor not providing an order free function. -// /// Take the maximum of all provided LocalFunction orders -// template <class Sig, class F, class... LFs, -// REQUIRES(not Concepts::HasFunctorOrder<F,sizeof...(LFs)> -// && all_of_v<Concepts::HasOrder<LFs>...>)> -// int order(FunctorLocalFunction<Sig,F,LFs...> const& lf) -// { -// return Dune::Std::apply([](auto const&... gfs) { return Math::max(order(gfs)...); }, -// lf.localFcts()); -// } - -// /// Specialization for \ref order for functor not providing an order free function -// /// and some LocalFunctions do not provide an order function. Take a constant value. -// template <class F, class... LFs, -// REQUIRES(any_of_v<(not Concepts::HasOrder<LFs>)...>)> -// int order(FunctorLocalFunction<Sig,F,LFs...> const& /*lf*/) -// { -// return AMDIS_FUNCTOR_DEFAULT_ORDER; -// } -// #endif - - - /// PreGridFunction related to \ref FunctorGridFunction, \relates FunctorGridFunction + // PreGridFunction related to FunctorGridFunction. template <class Functor, class... GridFunctions> struct FunctorPreGridFunction { @@ -286,10 +257,18 @@ namespace AMDiS struct IsPreGridFunction<FunctorPreGridFunction<Functor, GridFunctions...>> : std::true_type {}; } +#endif - /// Generator function for \ref FunctorPreGridFunction, i.e., creates a - /// pre-GridFunction. \relates FunctorGridFunction + /// \brief Generator function for FunctorGridFunction. \relates FunctorGridFunction + /** + * Applies the functor `f` to the grid-functions `gridFcts...`. See \ref FunctorGridFunction. + * + * **Examples:** + * - `invokeAtQP([](Dune::FieldVector<double, 2> const& x) { return two_norm(x); }, X());` + * - `invokeAtQP([](double u, auto const& x) { return u + x[0]; }, 1.0, X());` + * - `invokeAtQP(Operation::Plus{}, X(0), X(1));` + **/ template <class Functor, class... GridFcts> auto invokeAtQP(Functor const& f, GridFcts const&... gridFcts) { diff --git a/dune/amdis/gridfunctions/GridFunctionConcepts.hpp b/dune/amdis/gridfunctions/GridFunctionConcepts.hpp index 8d47dea0..648bad47 100644 --- a/dune/amdis/gridfunctions/GridFunctionConcepts.hpp +++ b/dune/amdis/gridfunctions/GridFunctionConcepts.hpp @@ -17,6 +17,10 @@ namespace AMDiS namespace Concepts { + /** \addtogroup Concepts + * @{ + **/ + namespace Definition { struct HasLocalFunction @@ -109,6 +113,8 @@ namespace AMDiS any_of_v<GridFunction<std::decay_t<GFs>>...> || any_of_v<Traits::IsPreGridFunction<std::decay_t<GFs>>::value...>; + /** @} **/ + } // end namespace Concepts diff --git a/dune/amdis/gridfunctions/OperationsGridFunction.hpp b/dune/amdis/gridfunctions/OperationsGridFunction.hpp index 58087374..b564168c 100644 --- a/dune/amdis/gridfunctions/OperationsGridFunction.hpp +++ b/dune/amdis/gridfunctions/OperationsGridFunction.hpp @@ -7,6 +7,15 @@ namespace AMDiS { + /** + * \addtogroup GridFunctions + * @{ + **/ + + // scalar operations + // @{ + + /// \brief Applies \ref Operation::Negate to GridFunctions. \relates FunctorGridFunction template <class Lhs, class Rhs, REQUIRES(Concepts::AnyGridFunction<Lhs>)> auto operator-(Lhs&& lhs) @@ -14,6 +23,7 @@ namespace AMDiS return invokeAtQP(Operation::Negate{}, std::forward<Lhs>(lhs)); } + /// \brief Applies \ref Operation::Plus to GridFunctions. \relates FunctorGridFunction template <class Lhs, class Rhs, REQUIRES(Concepts::AnyGridFunction<Lhs,Rhs>)> auto operator+(Lhs&& lhs, Rhs&& rhs) @@ -21,6 +31,7 @@ namespace AMDiS return invokeAtQP(Operation::Plus{}, std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); } + /// \brief Applies \ref Operation::Minus to GridFunctions. \relates FunctorGridFunction template <class Lhs, class Rhs, REQUIRES(Concepts::AnyGridFunction<Lhs,Rhs>)> auto operator-(Lhs&& lhs, Rhs&& rhs) @@ -28,6 +39,7 @@ namespace AMDiS return invokeAtQP(Operation::Minus{}, std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); } + /// \brief Applies \ref Operation::Multiplies to GridFunctions. \relates FunctorGridFunction template <class Lhs, class Rhs, REQUIRES(Concepts::AnyGridFunction<Lhs,Rhs>)> auto operator*(Lhs&& lhs, Rhs&& rhs) @@ -35,6 +47,7 @@ namespace AMDiS return invokeAtQP(Operation::Multiplies{}, std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); } + /// \brief Applies \ref Operation::Divides to GridFunctions. \relates FunctorGridFunction template <class Lhs, class Rhs, REQUIRES(Concepts::AnyGridFunction<Lhs,Rhs>)> auto operator/(Lhs&& lhs, Rhs&& rhs) @@ -43,6 +56,7 @@ namespace AMDiS } + /// \brief Applies \ref Operation::Max to GridFunctions. \relates FunctorGridFunction template <class Lhs, class Rhs, REQUIRES(Concepts::AnyGridFunction<Lhs,Rhs>)> auto max(Lhs&& lhs, Rhs&& rhs) @@ -50,6 +64,7 @@ namespace AMDiS return invokeAtQP(Operation::Max{}, std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); } + /// \brief Applies \ref Operation::Min to GridFunctions. \relates FunctorGridFunction template <class Lhs, class Rhs, REQUIRES(Concepts::AnyGridFunction<Lhs,Rhs>)> auto min(Lhs&& lhs, Rhs&& rhs) @@ -57,6 +72,7 @@ namespace AMDiS return invokeAtQP(Operation::Min{}, std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); } + /// \brief Applies \ref Operation::AbsMax to GridFunctions. \relates FunctorGridFunction template <class Lhs, class Rhs, REQUIRES(Concepts::AnyGridFunction<Lhs,Rhs>)> auto abs_max(Lhs&& lhs, Rhs&& rhs) @@ -64,6 +80,7 @@ namespace AMDiS return invokeAtQP(Operation::AbsMax{}, std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); } + /// \brief Applies \ref Operation::AbsMin to GridFunctions. \relates FunctorGridFunction template <class Lhs, class Rhs, REQUIRES(Concepts::AnyGridFunction<Lhs,Rhs>)> auto abs_min(Lhs&& lhs, Rhs&& rhs) @@ -71,8 +88,52 @@ namespace AMDiS return invokeAtQP(Operation::AbsMin{}, std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); } + /// \brief Applies \ref Operation::Sqr to GridFunction. \relates FunctorGridFunction + template <class T, + REQUIRES(Concepts::AnyGridFunction<T>)> + auto sqr(T&& value) + { + return invokeAtQP(Operation::Sqr{}, std::forward<T>(value)); + } + + /// \brief Applies \ref Operation::Pow<p> to GridFunction. \relates FunctorGridFunction + template <int p, class T, + REQUIRES(Concepts::AnyGridFunction<T>)> + auto pow(T&& value) + { + return invokeAtQP(Operation::Pow<p>{}, std::forward<T>(value)); + } + + /// \brief Applies \ref Operation::Pow_ to GridFunction. \relates FunctorGridFunction + template <class T, + REQUIRES(Concepts::AnyGridFunction<T>)> + auto pow(T&& value, int p) + { + return invokeAtQP(Operation::Pow_{p}, std::forward<T>(value)); + } + + /// \brief Applies \ref Operation::Get<I> to GridFunction. \relates FunctorGridFunction + template <std::size_t I, class T, + REQUIRES(Concepts::AnyGridFunction<T>)> + auto get(T&& value) + { + return invokeAtQP(Operation::Get<I>{}, std::forward<T>(value)); + } + + /// \brief Applies \ref Operation::Get_ to GridFunction. \relates FunctorGridFunction + template <class T, + REQUIRES(Concepts::AnyGridFunction<T>)> + auto get(T&& value, std::size_t i) + { + return invokeAtQP(Operation::Get_{i}, std::forward<T>(value)); + } + + // @} + // unary vector operations + // @{ + /// \brief Applies a sum-functor to a vector-valued GridFunction. \relates FunctorGridFunction template <class Vec, REQUIRES(Concepts::AnyGridFunction<Vec>)> auto sum(Vec&& vec) @@ -80,6 +141,7 @@ namespace AMDiS return invokeAtQP([](auto const& v) { return sum(v); }, std::forward<Vec>(vec)); } + /// \brief Applies \ref Operation::UnaryDot to a vector-valued GridFunction. \relates FunctorGridFunction template <class Vec, REQUIRES(Concepts::AnyGridFunction<Vec>)> auto unary_dot(Vec&& vec) @@ -87,6 +149,7 @@ namespace AMDiS return invokeAtQP(Operation::UnaryDot{}, std::forward<Vec>(vec)); } + /// \brief Applies a one_norm-functor to a vector-valued GridFunction. \relates FunctorGridFunction template <class Vec, REQUIRES(Concepts::AnyGridFunction<Vec>)> auto one_norm(Vec&& vec) @@ -94,6 +157,7 @@ namespace AMDiS return invokeAtQP([](auto const& v) { return one_norm(v); }, std::forward<Vec>(vec)); } + /// \brief Applies \ref Operation::TwoNorm to a vector-valued GridFunction. \relates FunctorGridFunction template <class Vec, REQUIRES(Concepts::AnyGridFunction<Vec>)> auto two_norm(Vec&& vec) @@ -101,6 +165,7 @@ namespace AMDiS return invokeAtQP(Operation::TwoNorm{}, std::forward<Vec>(vec)); } + /// \brief Applies a p_norm-functor to a vector-valued GridFunction. \relates FunctorGridFunction template <int p, class Vec, REQUIRES(Concepts::AnyGridFunction<Vec>)> auto p_norm(Vec&& vec) @@ -108,6 +173,7 @@ namespace AMDiS return invokeAtQP([](auto const& v) { return p_norm<p>(v); }, std::forward<Vec>(vec)); } + /// \brief Applies a infty_norm-functor to a vector-valued GridFunction. \relates FunctorGridFunction template <class Vec, REQUIRES(Concepts::AnyGridFunction<Vec>)> auto infty_norm(Vec&& vec) @@ -115,6 +181,7 @@ namespace AMDiS return invokeAtQP([](auto const& v) { return infty_norm(v); }, std::forward<Vec>(vec)); } + /// \brief Applies a trans-functor to a matrix-valued GridFunction.\relates FunctorGridFunction template <class Mat, REQUIRES(Concepts::AnyGridFunction<Mat>)> auto trans(Mat&& mat) @@ -122,8 +189,13 @@ namespace AMDiS return invokeAtQP([](auto const& m) { return trans(m); }, std::forward<Mat>(mat)); } + // @} + + // binary vector operations + // @{ + /// \brief Applies \ref Operation::Dot to two vector-valued GridFunctions. \relates FunctorGridFunction template <class Lhs, class Rhs, REQUIRES(Concepts::AnyGridFunction<Lhs,Rhs>)> auto dot(Lhs&& lhs, Rhs&& rhs) @@ -132,6 +204,7 @@ namespace AMDiS std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); } + /// \brief Applies a distance-functor to two vector-valued GridFunctions.\relates FunctorGridFunction template <class Lhs, class Rhs, REQUIRES(Concepts::AnyGridFunction<Lhs,Rhs>)> auto distance(Lhs&& lhs, Rhs&& rhs) @@ -141,6 +214,7 @@ namespace AMDiS std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); } + /// \brief Applies an outer-functor to two vector-valued GridFunctions. \relates FunctorGridFunction template <class Lhs, class Rhs, REQUIRES(Concepts::AnyGridFunction<Lhs,Rhs>)> auto outer(Lhs&& lhs, Rhs&& rhs) @@ -149,4 +223,8 @@ namespace AMDiS std::forward<Lhs>(lhs), std::forward<Rhs>(rhs)); } + // @} + + /** @} **/ + } // end namespace AMDiS diff --git a/dune/amdis/linear_algebra/mtl/Preconditioner.hpp b/dune/amdis/linear_algebra/mtl/Preconditioner.hpp index fb83acd8..d7e9876a 100644 --- a/dune/amdis/linear_algebra/mtl/Preconditioner.hpp +++ b/dune/amdis/linear_algebra/mtl/Preconditioner.hpp @@ -21,9 +21,9 @@ namespace AMDiS /// A creator to be used instead of the constructor. struct Creator : CreatorInterface<Super> { - virtual shared_ptr<Super> create() override + virtual std::shared_ptr<Super> create() override { - return make_shared<Self>(); + return std::make_shared<Self>(); } }; @@ -55,7 +55,7 @@ namespace AMDiS } private: - shared_ptr<PreconRunner> precon; + std::shared_ptr<PreconRunner> precon; }; } // namespace AMDiS diff --git a/dune/amdis/operations/Arithmetic.hpp b/dune/amdis/operations/Arithmetic.hpp index 8159ef92..5f7a4568 100644 --- a/dune/amdis/operations/Arithmetic.hpp +++ b/dune/amdis/operations/Arithmetic.hpp @@ -15,7 +15,7 @@ namespace AMDiS * @{ **/ - /// Operation that represents A+B + /// Functor that represents A+B struct Plus { #ifdef AMDIS_HAS_CXX_FOLD_EXPRESSIONS @@ -39,12 +39,13 @@ namespace AMDiS #endif }; - // [0] + g + ... => g + ... +#ifndef DOXYGEN + // [0] + g => g template <class G> struct ComposerBuilder<Plus, Zero, G> : ComposerBuilder<Plus, G> {}; - // ...+ g + [0] => ... + g + // g + [0] => g template <class G> struct ComposerBuilder<Plus, G, Zero> : ComposerBuilder<Plus, G> {}; @@ -53,7 +54,7 @@ namespace AMDiS template <> struct ComposerBuilder<Plus, Zero, Zero> : ComposerBuilder<Id, Zero> {}; - +#endif template <class... Int> int order(Plus, Int... orders) @@ -70,7 +71,7 @@ namespace AMDiS // ------------------------------------------------------------------------- - /// Operation that represents A-B + /// Functor that represents A-B struct Minus { template <class T, class S> @@ -95,6 +96,7 @@ namespace AMDiS } }; +#ifndef DOXYGEN // [0] - g => -g // template <class G> // struct ComposerBuilder<Minus, Zero, G> @@ -109,11 +111,11 @@ namespace AMDiS template <> struct ComposerBuilder<Minus, Zero, Zero> : ComposerBuilder<Id, Zero> {}; - +#endif // ------------------------------------------------------------------------- - /// Operation that represents A*B + /// Functor that represents A*B struct Multiplies { #ifdef AMDIS_HAS_CXX_FOLD_EXPRESSIONS @@ -131,12 +133,14 @@ namespace AMDiS #endif }; - // [0] * g * ... => [0] + +#ifndef DOXYGEN + // [0] * g => [0] template <class G> struct ComposerBuilder<Multiplies, Zero, G> : ComposerBuilder<Id, Zero> {}; - // ...* g * [0] => [0] + // g * [0] => [0] template <class G> struct ComposerBuilder<Multiplies, G, Zero> : ComposerBuilder<Id, Zero> {}; @@ -145,6 +149,7 @@ namespace AMDiS template <> struct ComposerBuilder<Multiplies, Zero, Zero> : ComposerBuilder<Id, Zero> {}; +#endif template <class... Int> @@ -159,12 +164,12 @@ namespace AMDiS auto partial(Multiplies, index_t<I>) { static_assert((I < 2), "Derivatives of `Multiplies` only defined for the binary case."); - return Component<1-I>{}; + return Arg<1-I>{}; } // ------------------------------------------------------------------------- - /// Operation that represents x^p + /// Functor that represents x^p template <int p> struct Pow { @@ -197,9 +202,37 @@ namespace AMDiS struct Pow<0> : public Zero {}; + /// Functor that represents x^p + struct Pow_ + { + Pow_(int p) + : p_(p) + { + assert( p_ >= 0 ); + } + + template <class T> + auto operator()(T const& x) const + { + return std::pow(x, p_); + } + + friend int order(Pow_ P, int d) + { + return P.p_ * d; + } + + friend auto partial(Pow_ P, index_t<0>) + { + return compose(Multiplies{}, Constant<int>{P.p_}, Pow_{P.p_-1}); + } + + int p_; + }; + // ------------------------------------------------------------------------- - /// Operation that represents A/B + /// Functor that represents A/B struct Divides { template <class T, class S> @@ -211,20 +244,20 @@ namespace AMDiS // d_0 f(x,y) = 1 / y friend auto partial(Divides, index_t<0>) { - return compose(Divides{}, One{}, Component<1>{}); + return compose(Divides{}, One{}, Arg<1>{}); } // d_1 f(x,y) = (y - x)/y^2 friend auto partial(Divides, index_t<1>) { - return compose(Divides{}, compose(Minus{}, Component<1>{}, Component<0>{}), - compose(Pow<2>{}, Component<1>{})); + return compose(Divides{}, compose(Minus{}, Arg<1>{}, Arg<0>{}), + compose(Pow<2>{}, Arg<1>{})); } }; // ------------------------------------------------------------------------- - /// Operation that represents A-B + /// Functor that represents A-B struct Negate { template <class T> diff --git a/dune/amdis/operations/Basic.hpp b/dune/amdis/operations/Basic.hpp index 3d22d4e1..e37aed4b 100644 --- a/dune/amdis/operations/Basic.hpp +++ b/dune/amdis/operations/Basic.hpp @@ -25,8 +25,7 @@ namespace AMDiS namespace Operation { - /** \defgroup operations Operations - * \brief Functors, representing unary/binary operations used in expressions. + /** \addtogroup operations * @{ **/ @@ -45,7 +44,7 @@ namespace AMDiS using One = StaticConstant<int, 1>; template <class T, T value, class... Int> - constexpr int order(StaticConstant<T,value> const&, Int...) + constexpr int order(StaticConstant<T,value> const&, Int... /*orders*/) { return 0; } @@ -99,7 +98,7 @@ namespace AMDiS }; template <class T, class... Int> - constexpr int order(Constant<T> const&, Int...) + constexpr int order(Constant<T> const&, Int... /*orders*/) { return 0; } @@ -113,7 +112,7 @@ namespace AMDiS // ------------------------------------------------------------------------- template <std::size_t I> - struct Component + struct Arg { template <class... Ts> constexpr auto&& operator()(Ts&&... args) const @@ -123,19 +122,54 @@ namespace AMDiS }; template <std::size_t I, class... Int> - constexpr int order(Component<I> const&, Int... degrees) + constexpr int order(Arg<I> const&, Int... orders) { - return std::get<I>(std::tie(degrees...)); + return std::get<I>(std::tie(orders...)); } template <std::size_t I, std::size_t J> - constexpr auto partial(Component<I>, index_t<J>) + constexpr auto partial(Arg<I>, index_t<J>) { return StaticConstant<int,(I==J ? 1 : 0)>{}; } // ------------------------------------------------------------------------- + template <std::size_t I> + struct Get + { + template <class T, int N> + constexpr T const& operator()(Dune::FieldVector<T,N> const& vec) const + { + return vec[I]; + } + + friend constexpr int order(Get, int d) + { + return d; + } + }; + + struct Get_ + { + explicit constexpr Get_(std::size_t i) + : i_(i) + {} + + template <class T, int N> + constexpr T const& operator()(Dune::FieldVector<T,N> const& vec) const + { + return vec[i_]; + } + + friend constexpr int order(Get_, int d) + { + return d; + } + + std::size_t i_; + }; + /** @} **/ } // end namespace Operation diff --git a/dune/amdis/operations/CMath.hpp b/dune/amdis/operations/CMath.hpp index 21219256..5c2c83c0 100644 --- a/dune/amdis/operations/CMath.hpp +++ b/dune/amdis/operations/CMath.hpp @@ -61,6 +61,7 @@ namespace AMDiS // generated unary functors using a macro... // approximate polynomial order +#ifndef DXOYGEN AMDIS_MAKE_UNARY_FUNCTOR( Ceil, std::ceil(x), 0.0 ) AMDIS_MAKE_UNARY_FUNCTOR( Floor, std::floor(x), 0.0 ) AMDIS_MAKE_UNARY_FUNCTOR( Sqrt, std::sqrt(x), 1.0/(2.0 * std::sqrt(x)) ) @@ -78,7 +79,7 @@ namespace AMDiS AMDIS_MAKE_UNARY_FUNCTOR( Asinh, std::asinh(x), 1.0/std::sqrt(1.0 + Math::sqr(x)) ) AMDIS_MAKE_UNARY_FUNCTOR( Acosh, std::acosh(x), 1.0/std::sqrt(-1.0 + Math::sqr(x)) ) AMDIS_MAKE_UNARY_FUNCTOR( Atanh, std::atanh(x), 1.0/(1.0 - Math::sqr(x)) ) - +#endif /// Binary functor representing the cmath function std::atan2(v) struct Atan2 diff --git a/dune/amdis/operations/Composer.hpp b/dune/amdis/operations/Composer.hpp index c40d9473..2a1e987e 100644 --- a/dune/amdis/operations/Composer.hpp +++ b/dune/amdis/operations/Composer.hpp @@ -41,6 +41,7 @@ namespace AMDiS #endif +#ifndef DOXYGEN template <class F, class... Gs> struct ComposerBuilder { @@ -52,6 +53,7 @@ namespace AMDiS return type{std::forward<F_>(f), std::forward<Gs_>(gs)...}; } }; +#endif /// Generator function for \ref composer template <class F, class... Gs> @@ -101,6 +103,7 @@ namespace AMDiS } +#ifndef DOXYGEN // some specialization for the composer // id(g) => g @@ -115,6 +118,7 @@ namespace AMDiS return F{std::forward<F_>(f)}; } }; +#endif } // end namespace Operation } // end namespace AMDiS diff --git a/dune/amdis/operations/FieldMatVec.hpp b/dune/amdis/operations/FieldMatVec.hpp index 64e14c16..b2c4566a 100644 --- a/dune/amdis/operations/FieldMatVec.hpp +++ b/dune/amdis/operations/FieldMatVec.hpp @@ -30,12 +30,12 @@ namespace AMDiS friend constexpr auto partial(Dot, index_t<0>) { - return Component<1>{}; + return Arg<1>{}; } friend constexpr auto partial(Dot, index_t<1>) { - return Component<0>{}; + return Arg<0>{}; } }; @@ -81,5 +81,4 @@ namespace AMDiS /** @} **/ } // end namespace Operation - } // end namespace AMDiS -- GitLab