diff --git a/src/amdis/GridFunctionOperator.hpp b/src/amdis/GridFunctionOperator.hpp index 167892ffa6c2c05ef08667453d05cb9ed154e319..733befae6c2f17175f2480e626f9be4a9ca860bb 100644 --- a/src/amdis/GridFunctionOperator.hpp +++ b/src/amdis/GridFunctionOperator.hpp @@ -60,8 +60,9 @@ namespace AMDiS * differentiation order of the operator, to calculate the * quadrature degree in \ref getDegree. **/ - GridFunctionOperatorBase(GridFunction const& gridFct, int termOrder) - : gridFct_(gridFct) + template + GridFunctionOperatorBase(GF&& gridFct, int termOrder) + : gridFct_(std::forward(gridFct)) , termOrder_(termOrder) {} @@ -91,10 +92,11 @@ namespace AMDiS /// Create a quadrature factory from a PreQuadratureFactory, e.g. class derived from \ref QuadratureFactory template - void setQuadFactory(PreQuadFactory const& pre) + void setQuadFactory(PreQuadFactory&& pre) { using ctype = typename Geometry::ctype; - quadFactory_.emplace(makeQuadratureFactory(pre)); + quadFactory_.emplace( + makeQuadratureFactory(std::forward(pre))); } protected: @@ -161,9 +163,9 @@ namespace AMDiS /// Redirects the setQuadFactory call top the transposed operator template - void setQuadFactory(PreQuadFactory const& pre) + void setQuadFactory(PreQuadFactory&& pre) { - transposedOp_.setQuadFactory(pre); + transposedOp_.setQuadFactory(std::forward(pre)); } /// Apply the assembling to the transposed elementMatrix with interchanged row-/colNode @@ -182,6 +184,7 @@ namespace AMDiS Transposed transposedOp_; }; + template struct PreGridFunctionOperator { @@ -190,12 +193,13 @@ namespace AMDiS PreQuadFactory quadFactory; }; - /// Store tag and expression to create a \ref GridFunctionOperator - template - auto makeOperator(Tag tag, PreGridFct const& expr, QuadratureArgs&&... args) + /// Store tag and expression into a \ref PreGridFunctionOperator to create a \ref GridFunctionOperator + template + auto makeOperator(Tag tag, Expr&& expr, QuadratureArgs&&... args) { - auto preQuadFactory = makePreQuadratureFactory(std::forward(args)...); - return PreGridFunctionOperator{tag, expr, preQuadFactory}; + auto pqf = makePreQuadratureFactory(std::forward(args)...); + using PreGridFctOp = PreGridFunctionOperator, decltype(pqf)>; + return PreGridFctOp{tag, std::forward(expr), std::move(pqf)}; } /** @} **/ @@ -218,53 +222,31 @@ namespace AMDiS : public GridFunctionOperatorBase, LocalContext, GridFct> {}; - - /// Generate an \ref GridFunctionOperator from a PreOperator (tag, expr). - /// @{ - template - auto makeLocalOperator(PreGridFunctionOperator const& op, GridView const& gridView) + template + auto makeGridFunctionOperator(Tag tag, GF&& gf, QF&& qf) { - auto gridFct = makeGridFunction(op.expr, gridView); - using GridFctOp = GridFunctionOperator; - GridFctOp localOperator{op.tag, gridFct}; - localOperator.setQuadFactory(op.quadFactory); - return localOperator; + using GridFctOp = GridFunctionOperator>; + GridFctOp gfo{tag, std::forward(gf)}; + gfo.setQuadFactory(std::forward(qf)); + return gfo; } - template - auto makeLocalOperator(std::reference_wrapper> op, GridView const& gridView) - { - PreGridFunctionOperator const& op_ref = op; - auto gridFct = makeGridFunction(std::ref(op_ref.expr), gridView); - using GridFctOp = GridFunctionOperator; - GridFctOp localOperator{op_ref.tag, gridFct}; - localOperator.setQuadFactory(op_ref.quadFactory); - return localOperator; - } - /// @} - - /// Generate a shared_ptr to \ref GridFunctionOperator from a PreOperator (tag, expr). + /// Generate an \ref GridFunctionOperator from a PreOperator (tag, expr). /// @{ - template - auto makeLocalOperatorPtr(PreGridFunctionOperator const& op, GridView const& gridView) + template + auto makeLocalOperator(PreGridFunctionOperator op, GridView const& gridView) { - auto gridFct = makeGridFunction(op.expr, gridView); - using GridFctOp = GridFunctionOperator; - auto localOperator = std::make_shared(op.tag, gridFct); - localOperator->setQuadFactory(op.quadFactory); - return localOperator; + auto gf = makeGridFunction(std::move(op.expr), gridView); + return makeGridFunctionOperator(op.tag, std::move(gf), std::move(op.quadFactory)); } - template - auto makeLocalOperatorPtr(std::reference_wrapper> op, GridView const& gridView) + template + auto makeLocalOperator(std::reference_wrapper> op_ref, GridView const& gridView) { - PreGridFunctionOperator const& op_ref = op; - auto gridFct = makeGridFunction(std::ref(op_ref.expr), gridView); - using GridFctOp = GridFunctionOperator; - auto localOperator = std::make_shared(op_ref.tag, gridFct); - localOperator->setQuadFactory(op_ref.quadFactory); - return localOperator; + PreGridFunctionOperator const& op = op_ref; + auto gf = makeGridFunction(std::ref(op.expr), gridView); + return makeGridFunctionOperator(op.tag, std::move(gf), op.quadFactory); } /// @} diff --git a/src/amdis/LocalAssembler.hpp b/src/amdis/LocalAssembler.hpp index 477b29529ca46614d40f36462896048ea0adb12a..db3c56c486cbb627e5c541b3eaed65dee3e961b8 100644 --- a/src/amdis/LocalAssembler.hpp +++ b/src/amdis/LocalAssembler.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -30,13 +31,17 @@ namespace AMDiS /// Constructor. Stores a copy of operator `op`. explicit LocalAssembler(Operator const& op) - : storage_(std::make_unique(op)) - , op_(*storage_) + : op_(Dune::wrap_or_move(op)) + {} + + /// Constructor. Stores a copy of operator `op`. + explicit LocalAssembler(Operator&& op) + : op_(Dune::wrap_or_move(std::move(op))) {} /// Constructor. Stores the reference to the operator. - explicit LocalAssembler(std::reference_wrapper const& op) - : op_(op) + explicit LocalAssembler(std::reference_wrapper op) + : op_(Dune::wrap_or_move(op.get())) {} /// \brief Implementation of \ref LocalAssemblerBase::bind. @@ -48,7 +53,7 @@ namespace AMDiS { element_ = &element; geometry_ = &geometry; - op_.bind(element, geometry); + op_->bind(element, geometry); } /// \brief Implementation of \ref LocalAssemblerBase::unbind @@ -58,7 +63,7 @@ namespace AMDiS **/ virtual void unbind() final { - op_.unbind(); + op_->unbind(); geometry_ = nullptr; element_ = nullptr; } @@ -88,7 +93,7 @@ namespace AMDiS RowNode const& rowNode, ColNode const& colNode, ElementMatrix& elementMatrix) { - op_.calculateElementMatrix(context, rowNode, colNode, elementMatrix); + op_->calculateElementMatrix(context, rowNode, colNode, elementMatrix); } // vector assembling @@ -97,7 +102,7 @@ namespace AMDiS Node const& node, ElementVector& elementVector) { - op_.calculateElementVector(context, node, elementVector); + op_->calculateElementVector(context, node, elementVector); } #endif // DOXYGEN @@ -122,8 +127,7 @@ namespace AMDiS private: /// the stored operator, implementing \ref GridFunctionOperatorBase - std::unique_ptr storage_; - Operator& op_; + std::shared_ptr op_; Element const* element_ = nullptr; Geometry const* geometry_ = nullptr; @@ -131,31 +135,10 @@ namespace AMDiS /// Generate a \ref LocalAssembler on a given `LocalContext` (element or intersection) - template ::value, int> = 0> - auto makeLocalAssembler(Operator const& op, Nodes const&...) - { - return LocalAssembler{op}; - } - - template - auto makeLocalAssembler(std::reference_wrapper const& op, Nodes const&...) - { - return LocalAssembler{op}; - } - - /// Generate a shared_ptr to \ref LocalAssembler on a given `LocalContext` (element or intersection) - template ::value, int> = 0> - auto makeLocalAssemblerPtr(Operator const& op, Nodes const&...) - { - return std::make_unique>(op); - } - template - auto makeLocalAssemblerPtr(std::reference_wrapper const& op, Nodes const&...) + auto makeLocalAssembler(Operator&& op, Nodes const&...) { - return std::make_unique>(op); + return LocalAssembler, Nodes...>{std::forward(op)}; } } // end namespace AMDiS diff --git a/src/amdis/LocalOperator.hpp b/src/amdis/LocalOperator.hpp index 988707b6701f4f22f4ff86cea1515d124753b478..5083e070b321bdc5555cf32753ea6229ebb93b54 100644 --- a/src/amdis/LocalOperator.hpp +++ b/src/amdis/LocalOperator.hpp @@ -190,17 +190,10 @@ namespace AMDiS /// Generate a \ref LocalOperator from a PreOperator. - template - auto makeLocalOperator(LocalOperator const& localOp, GridView const& /*gridView*/) + template + auto makeLocalOperator(LocalOperator const& localOp, GridView const& /*gridView*/) { return localOp.derived(); } - /// Generate a shared_ptr to a \ref LocalOperator from a PreOperator. - template - auto makeLocalOperatorPtr(LocalOperator const& localOp, GridView const& /*gridView*/) - { - return std::make_unique(localOp.derived()); - } - } // end namespace AMDiS diff --git a/src/amdis/assembler/ConvectionDiffusionOperator.hpp b/src/amdis/assembler/ConvectionDiffusionOperator.hpp index ca49b35f03048d45555aeae9c4a1f99d57255a27..5350e5fdbc79c2100ab6f1d8b0d1aa3d8c2fc8df 100644 --- a/src/amdis/assembler/ConvectionDiffusionOperator.hpp +++ b/src/amdis/assembler/ConvectionDiffusionOperator.hpp @@ -220,19 +220,19 @@ namespace AMDiS return Pre{gridFctA, gridFctB, gridFctC, gridFctF}; } - template - auto makeLocalOperator(PreConvectionDiffusionOperator const& pre, GridView const& gridView) + template + auto makeLocalOperator(PreConvectionDiffusionOperator pre, GridView const& gridView) { using Pre = PreConvectionDiffusionOperator; - auto gridFctA = makeGridFunction(pre.gridFctA, gridView); - auto gridFctB = makeGridFunction(pre.gridFctB, gridView); - auto gridFctC = makeGridFunction(pre.gridFctC, gridView); - auto gridFctF = makeGridFunction(pre.gridFctF, gridView); + auto gridFctA = makeGridFunction(std::move(pre.gridFctA), gridView); + auto gridFctB = makeGridFunction(std::move(pre.gridFctB), gridView); + auto gridFctC = makeGridFunction(std::move(pre.gridFctC), gridView); + auto gridFctF = makeGridFunction(std::move(pre.gridFctF), gridView); - using GridFctOp = ConvectionDiffusionOperator; - GridFctOp localOperator{gridFctA, gridFctB, gridFctC, gridFctF}; + GridFctOp localOperator{std::move(gridFctA), std::move(gridFctB), std::move(gridFctC), std::move(gridFctF)}; return localOperator; } diff --git a/src/amdis/common/Utility.hpp b/src/amdis/common/Utility.hpp index 08f9683e07d22ad3440048b47f44bff570b8d876..ebcc6ebc0eea088b677e42118d8603c24d9df490 100644 --- a/src/amdis/common/Utility.hpp +++ b/src/amdis/common/Utility.hpp @@ -17,13 +17,13 @@ namespace AMDiS template struct UnderlyingType { - using type = T; + using type = std::decay_t; }; template struct UnderlyingType> { - using type = T; + using type = std::decay_t; }; } @@ -50,6 +50,13 @@ namespace AMDiS using CommonType_t = typename Impl::CommonType::type; + /// Create a unique_ptr by copy/move construction + template + auto makeUniquePtr(Obj&& obj) + { + return std::make_unique>(std::forward(obj)); + } + // --------------------------------------------------------------------------- // base template for tuple size, must implement a static value member diff --git a/src/amdis/linear_algebra/DOFMatrixBase.inc.hpp b/src/amdis/linear_algebra/DOFMatrixBase.inc.hpp index df86474c24a662e179c3cb0ba370ca74540a2279..9f5e6971866d4684d61f5447f7070bc30396f544 100644 --- a/src/amdis/linear_algebra/DOFMatrixBase.inc.hpp +++ b/src/amdis/linear_algebra/DOFMatrixBase.inc.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include namespace AMDiS { @@ -45,9 +46,9 @@ insert(RowLocalView const& rowLocalView, ColLocalView const& colLocalView, template - template + template void DOFMatrixBase:: -addOperator(ContextTag contextTag, Operator const& preOp, +addOperator(ContextTag contextTag, PreOperator const& preOp, RowTreePath row, ColTreePath col) { static_assert( Concepts::PreTreePath, @@ -60,7 +61,7 @@ addOperator(ContextTag contextTag, Operator const& preOp, using Context = typename ContextTag::type; auto op = makeLocalOperator(preOp, rowBasis_->gridView()); - auto localAssembler = makeLocalAssemblerPtr(std::move(op), i, j); + auto localAssembler = makeUniquePtr(makeLocalAssembler(std::move(op), i, j)); operators_[i][j].push(contextTag, std::move(localAssembler)); } diff --git a/src/amdis/linear_algebra/DOFVectorBase.inc.hpp b/src/amdis/linear_algebra/DOFVectorBase.inc.hpp index 32ad9b988952a4311774c6dd26df0ba1e6497323..884fad1d4e8dd668b17b66b350a0b8121989818a 100644 --- a/src/amdis/linear_algebra/DOFVectorBase.inc.hpp +++ b/src/amdis/linear_algebra/DOFVectorBase.inc.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include namespace AMDiS { @@ -40,9 +41,9 @@ insert(LocalView const& localView, ElementVector const& elementVector) template - template + template void DOFVectorBase:: -addOperator(ContextTag contextTag, Operator const& preOp, TreePath path) +addOperator(ContextTag contextTag, PreOperator const& preOp, TreePath path) { static_assert( Concepts::PreTreePath, "path must be a valid treepath, or an integer/index-constant"); @@ -51,7 +52,7 @@ addOperator(ContextTag contextTag, Operator const& preOp, TreePath path) using Context = typename ContextTag::type; auto op = makeLocalOperator(preOp, basis_->gridView()); - auto localAssembler = makeLocalAssemblerPtr(std::move(op), i); + auto localAssembler = makeUniquePtr(makeLocalAssembler(std::move(op), i)); operators_[i].push(contextTag, std::move(localAssembler)); }