Commit 4fddde92 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Merge branch 'issue/restructure_structure_functions' into develop

parents 4594aaca 4ecfaaf8
Pipeline #1618 passed with stage
in 20 minutes and 25 seconds
...@@ -60,8 +60,9 @@ namespace AMDiS ...@@ -60,8 +60,9 @@ namespace AMDiS
* differentiation order of the operator, to calculate the * differentiation order of the operator, to calculate the
* quadrature degree in \ref getDegree. * quadrature degree in \ref getDegree.
**/ **/
GridFunctionOperatorBase(GridFunction const& gridFct, int termOrder) template <class GF>
: gridFct_(gridFct) GridFunctionOperatorBase(GF&& gridFct, int termOrder)
: gridFct_(std::forward<GF>(gridFct))
, termOrder_(termOrder) , termOrder_(termOrder)
{} {}
...@@ -91,10 +92,11 @@ namespace AMDiS ...@@ -91,10 +92,11 @@ namespace AMDiS
/// Create a quadrature factory from a PreQuadratureFactory, e.g. class derived from \ref QuadratureFactory /// Create a quadrature factory from a PreQuadratureFactory, e.g. class derived from \ref QuadratureFactory
template <class PreQuadFactory> template <class PreQuadFactory>
void setQuadFactory(PreQuadFactory const& pre) void setQuadFactory(PreQuadFactory&& pre)
{ {
using ctype = typename Geometry::ctype; using ctype = typename Geometry::ctype;
quadFactory_.emplace(makeQuadratureFactory<ctype, LocalContext::mydimension, LocalFunction>(pre)); quadFactory_.emplace(
makeQuadratureFactory<ctype, LocalContext::mydimension, LocalFunction>(std::forward<PreQuadFactory>(pre)));
} }
protected: protected:
...@@ -161,9 +163,9 @@ namespace AMDiS ...@@ -161,9 +163,9 @@ namespace AMDiS
/// Redirects the setQuadFactory call top the transposed operator /// Redirects the setQuadFactory call top the transposed operator
template <class PreQuadFactory> template <class PreQuadFactory>
void setQuadFactory(PreQuadFactory const& pre) void setQuadFactory(PreQuadFactory&& pre)
{ {
transposedOp_.setQuadFactory(pre); transposedOp_.setQuadFactory(std::forward<PreQuadFactory>(pre));
} }
/// Apply the assembling to the transposed elementMatrix with interchanged row-/colNode /// Apply the assembling to the transposed elementMatrix with interchanged row-/colNode
...@@ -182,6 +184,7 @@ namespace AMDiS ...@@ -182,6 +184,7 @@ namespace AMDiS
Transposed transposedOp_; Transposed transposedOp_;
}; };
template <class Tag, class PreGridFct, class PreQuadFactory> template <class Tag, class PreGridFct, class PreQuadFactory>
struct PreGridFunctionOperator struct PreGridFunctionOperator
{ {
...@@ -190,12 +193,13 @@ namespace AMDiS ...@@ -190,12 +193,13 @@ namespace AMDiS
PreQuadFactory quadFactory; PreQuadFactory quadFactory;
}; };
/// Store tag and expression to create a \ref GridFunctionOperator /// Store tag and expression into a \ref PreGridFunctionOperator to create a \ref GridFunctionOperator
template <class Tag, class PreGridFct, class... QuadratureArgs> template <class Tag, class Expr, class... QuadratureArgs>
auto makeOperator(Tag tag, PreGridFct const& expr, QuadratureArgs&&... args) auto makeOperator(Tag tag, Expr&& expr, QuadratureArgs&&... args)
{ {
auto preQuadFactory = makePreQuadratureFactory(std::forward<QuadratureArgs>(args)...); auto pqf = makePreQuadratureFactory(std::forward<QuadratureArgs>(args)...);
return PreGridFunctionOperator<Tag, PreGridFct, decltype(preQuadFactory)>{tag, expr, preQuadFactory}; using PreGridFctOp = PreGridFunctionOperator<Tag, std::decay_t<Expr>, decltype(pqf)>;
return PreGridFctOp{tag, std::forward<Expr>(expr), std::move(pqf)};
} }
/** @} **/ /** @} **/
...@@ -218,53 +222,31 @@ namespace AMDiS ...@@ -218,53 +222,31 @@ namespace AMDiS
: public GridFunctionOperatorBase<GridFunctionOperator<Tag, LocalContext, GridFct>, LocalContext, GridFct> : public GridFunctionOperatorBase<GridFunctionOperator<Tag, LocalContext, GridFct>, LocalContext, GridFct>
{}; {};
template <class Context, class Tag, class GF, class QF>
/// Generate an \ref GridFunctionOperator from a PreOperator (tag, expr). auto makeGridFunctionOperator(Tag tag, GF&& gf, QF&& qf)
/// @{
template <class LocalContext, class Tag, class... Args, class GridView>
auto makeLocalOperator(PreGridFunctionOperator<Tag, Args...> const& op, GridView const& gridView)
{ {
auto gridFct = makeGridFunction(op.expr, gridView); using GridFctOp = GridFunctionOperator<Tag, Context, std::decay_t<GF>>;
using GridFctOp = GridFunctionOperator<Tag, LocalContext, decltype(gridFct)>; GridFctOp gfo{tag, std::forward<GF>(gf)};
GridFctOp localOperator{op.tag, gridFct}; gfo.setQuadFactory(std::forward<QF>(qf));
localOperator.setQuadFactory(op.quadFactory); return gfo;
return localOperator;
} }
template <class LocalContext, class Tag, class... Args, class GridView>
auto makeLocalOperator(std::reference_wrapper<PreGridFunctionOperator<Tag, Args...>> op, GridView const& gridView)
{
PreGridFunctionOperator<Tag, Args...> const& op_ref = op;
auto gridFct = makeGridFunction(std::ref(op_ref.expr), gridView);
using GridFctOp = GridFunctionOperator<Tag, LocalContext, decltype(gridFct)>;
GridFctOp localOperator{op_ref.tag, gridFct};
localOperator.setQuadFactory(op_ref.quadFactory);
return localOperator;
}
/// @}
/// Generate an \ref GridFunctionOperator from a PreOperator (tag, expr).
/// Generate a shared_ptr to \ref GridFunctionOperator from a PreOperator (tag, expr).
/// @{ /// @{
template <class LocalContext, class Tag, class... Args, class GridView> template <class Context, class... Args, class GridView>
auto makeLocalOperatorPtr(PreGridFunctionOperator<Tag, Args...> const& op, GridView const& gridView) auto makeLocalOperator(PreGridFunctionOperator<Args...> op, GridView const& gridView)
{ {
auto gridFct = makeGridFunction(op.expr, gridView); auto gf = makeGridFunction(std::move(op.expr), gridView);
using GridFctOp = GridFunctionOperator<Tag, LocalContext, decltype(gridFct)>; return makeGridFunctionOperator<Context>(op.tag, std::move(gf), std::move(op.quadFactory));
auto localOperator = std::make_shared<GridFctOp>(op.tag, gridFct);
localOperator->setQuadFactory(op.quadFactory);
return localOperator;
} }
template <class LocalContext, class Tag, class... Args, class GridView> template <class Context, class... Args, class GridView>
auto makeLocalOperatorPtr(std::reference_wrapper<PreGridFunctionOperator<Tag, Args...>> op, GridView const& gridView) auto makeLocalOperator(std::reference_wrapper<PreGridFunctionOperator<Args...>> op_ref, GridView const& gridView)
{ {
PreGridFunctionOperator<Tag, Args...> const& op_ref = op; PreGridFunctionOperator<Args...> const& op = op_ref;
auto gridFct = makeGridFunction(std::ref(op_ref.expr), gridView); auto gf = makeGridFunction(std::ref(op.expr), gridView);
using GridFctOp = GridFunctionOperator<Tag, LocalContext, decltype(gridFct)>; return makeGridFunctionOperator<Context>(op.tag, std::move(gf), op.quadFactory);
auto localOperator = std::make_shared<GridFctOp>(op_ref.tag, gridFct);
localOperator->setQuadFactory(op_ref.quadFactory);
return localOperator;
} }
/// @} /// @}
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <memory> #include <memory>
#include <type_traits> #include <type_traits>
#include <dune/common/shared_ptr.hh>
#include <dune/geometry/quadraturerules.hh> #include <dune/geometry/quadraturerules.hh>
#include <amdis/ContextGeometry.hpp> #include <amdis/ContextGeometry.hpp>
...@@ -30,13 +31,17 @@ namespace AMDiS ...@@ -30,13 +31,17 @@ namespace AMDiS
/// Constructor. Stores a copy of operator `op`. /// Constructor. Stores a copy of operator `op`.
explicit LocalAssembler(Operator const& op) explicit LocalAssembler(Operator const& op)
: storage_(std::make_unique<Operator>(op)) : op_(Dune::wrap_or_move(op))
, op_(*storage_) {}
/// 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. /// Constructor. Stores the reference to the operator.
explicit LocalAssembler(std::reference_wrapper<Operator> const& op) explicit LocalAssembler(std::reference_wrapper<Operator> op)
: op_(op) : op_(Dune::wrap_or_move(op.get()))
{} {}
/// \brief Implementation of \ref LocalAssemblerBase::bind. /// \brief Implementation of \ref LocalAssemblerBase::bind.
...@@ -48,7 +53,7 @@ namespace AMDiS ...@@ -48,7 +53,7 @@ namespace AMDiS
{ {
element_ = &element; element_ = &element;
geometry_ = &geometry; geometry_ = &geometry;
op_.bind(element, geometry); op_->bind(element, geometry);
} }
/// \brief Implementation of \ref LocalAssemblerBase::unbind /// \brief Implementation of \ref LocalAssemblerBase::unbind
...@@ -58,7 +63,7 @@ namespace AMDiS ...@@ -58,7 +63,7 @@ namespace AMDiS
**/ **/
virtual void unbind() final virtual void unbind() final
{ {
op_.unbind(); op_->unbind();
geometry_ = nullptr; geometry_ = nullptr;
element_ = nullptr; element_ = nullptr;
} }
...@@ -88,7 +93,7 @@ namespace AMDiS ...@@ -88,7 +93,7 @@ namespace AMDiS
RowNode const& rowNode, ColNode const& colNode, RowNode const& rowNode, ColNode const& colNode,
ElementMatrix& elementMatrix) ElementMatrix& elementMatrix)
{ {
op_.calculateElementMatrix(context, rowNode, colNode, elementMatrix); op_->calculateElementMatrix(context, rowNode, colNode, elementMatrix);
} }
// vector assembling // vector assembling
...@@ -97,7 +102,7 @@ namespace AMDiS ...@@ -97,7 +102,7 @@ namespace AMDiS
Node const& node, Node const& node,
ElementVector& elementVector) ElementVector& elementVector)
{ {
op_.calculateElementVector(context, node, elementVector); op_->calculateElementVector(context, node, elementVector);
} }
#endif // DOXYGEN #endif // DOXYGEN
...@@ -122,8 +127,7 @@ namespace AMDiS ...@@ -122,8 +127,7 @@ namespace AMDiS
private: private:
/// the stored operator, implementing \ref GridFunctionOperatorBase /// the stored operator, implementing \ref GridFunctionOperatorBase
std::unique_ptr<Operator> storage_; std::shared_ptr<Operator> op_;
Operator& op_;
Element const* element_ = nullptr; Element const* element_ = nullptr;
Geometry const* geometry_ = nullptr; Geometry const* geometry_ = nullptr;
...@@ -131,31 +135,10 @@ namespace AMDiS ...@@ -131,31 +135,10 @@ namespace AMDiS
/// Generate a \ref LocalAssembler on a given `LocalContext` (element or intersection) /// Generate a \ref LocalAssembler on a given `LocalContext` (element or intersection)
template <class LocalContext, class Operator, class... Nodes,
std::enable_if_t<not Traits::IsReferenceWrapper<Operator>::value, int> = 0>
auto makeLocalAssembler(Operator const& op, Nodes const&...)
{
return LocalAssembler<LocalContext, Operator, Nodes...>{op};
}
template <class LocalContext, class Operator, class... Nodes>
auto makeLocalAssembler(std::reference_wrapper<Operator> const& op, Nodes const&...)
{
return LocalAssembler<LocalContext, Operator, Nodes...>{op};
}
/// 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::IsReferenceWrapper<Operator>::value, int> = 0>
auto makeLocalAssemblerPtr(Operator const& op, Nodes const&...)
{
return std::make_unique<LocalAssembler<LocalContext, Operator, Nodes...>>(op);
}
template <class LocalContext, class Operator, class... Nodes> template <class LocalContext, class Operator, class... Nodes>
auto makeLocalAssemblerPtr(std::reference_wrapper<Operator> const& op, Nodes const&...) auto makeLocalAssembler(Operator&& op, Nodes const&...)
{ {
return std::make_unique<LocalAssembler<LocalContext, Operator, Nodes...>>(op); return LocalAssembler<LocalContext, Underlying_t<Operator>, Nodes...>{std::forward<Operator>(op)};
} }
} // end namespace AMDiS } // end namespace AMDiS
...@@ -190,17 +190,10 @@ namespace AMDiS ...@@ -190,17 +190,10 @@ namespace AMDiS
/// Generate a \ref LocalOperator from a PreOperator. /// Generate a \ref LocalOperator from a PreOperator.
template <class Derived, class LocalContext, class GridView> template <class Derived, class Context, class GridView>
auto makeLocalOperator(LocalOperator<Derived, LocalContext> const& localOp, GridView const& /*gridView*/) auto makeLocalOperator(LocalOperator<Derived, Context> const& localOp, GridView const& /*gridView*/)
{ {
return localOp.derived(); return localOp.derived();
} }
/// Generate a shared_ptr to a \ref LocalOperator from a PreOperator.
template <class Derived, class LocalContext, class GridView>
auto makeLocalOperatorPtr(LocalOperator<Derived, LocalContext> const& localOp, GridView const& /*gridView*/)
{
return std::make_unique<Derived>(localOp.derived());
}
} // end namespace AMDiS } // end namespace AMDiS
...@@ -220,19 +220,19 @@ namespace AMDiS ...@@ -220,19 +220,19 @@ namespace AMDiS
return Pre{gridFctA, gridFctB, gridFctC, gridFctF}; return Pre{gridFctA, gridFctB, gridFctC, gridFctF};
} }
template <class LocalContext, class... T, class GridView> template <class Context, class... T, class GridView>
auto makeLocalOperator(PreConvectionDiffusionOperator<T...> const& pre, GridView const& gridView) auto makeLocalOperator(PreConvectionDiffusionOperator<T...> pre, GridView const& gridView)
{ {
using Pre = PreConvectionDiffusionOperator<T...>; using Pre = PreConvectionDiffusionOperator<T...>;
auto gridFctA = makeGridFunction(pre.gridFctA, gridView); auto gridFctA = makeGridFunction(std::move(pre.gridFctA), gridView);
auto gridFctB = makeGridFunction(pre.gridFctB, gridView); auto gridFctB = makeGridFunction(std::move(pre.gridFctB), gridView);
auto gridFctC = makeGridFunction(pre.gridFctC, gridView); auto gridFctC = makeGridFunction(std::move(pre.gridFctC), gridView);
auto gridFctF = makeGridFunction(pre.gridFctF, gridView); auto gridFctF = makeGridFunction(std::move(pre.gridFctF), gridView);
using GridFctOp = ConvectionDiffusionOperator<LocalContext, using GridFctOp = ConvectionDiffusionOperator<Context,
decltype(gridFctA), decltype(gridFctB), decltype(gridFctC), decltype(gridFctF), Pre::conserving>; decltype(gridFctA), decltype(gridFctB), decltype(gridFctC), decltype(gridFctF), Pre::conserving>;
GridFctOp localOperator{gridFctA, gridFctB, gridFctC, gridFctF}; GridFctOp localOperator{std::move(gridFctA), std::move(gridFctB), std::move(gridFctC), std::move(gridFctF)};
return localOperator; return localOperator;
} }
......
...@@ -17,13 +17,13 @@ namespace AMDiS ...@@ -17,13 +17,13 @@ namespace AMDiS
template <class T> template <class T>
struct UnderlyingType struct UnderlyingType
{ {
using type = T; using type = std::decay_t<T>;
}; };
template <class T> template <class T>
struct UnderlyingType<std::reference_wrapper<T>> struct UnderlyingType<std::reference_wrapper<T>>
{ {
using type = T; using type = std::decay_t<T>;
}; };
} }
...@@ -50,6 +50,13 @@ namespace AMDiS ...@@ -50,6 +50,13 @@ namespace AMDiS
using CommonType_t = typename Impl::CommonType<T...>::type; using CommonType_t = typename Impl::CommonType<T...>::type;
/// Create a unique_ptr by copy/move construction
template <class Obj>
auto makeUniquePtr(Obj&& obj)
{
return std::make_unique<std::decay_t<Obj>>(std::forward<Obj>(obj));
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// base template for tuple size, must implement a static value member // base template for tuple size, must implement a static value member
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <amdis/Assembler.hpp> #include <amdis/Assembler.hpp>
#include <amdis/LocalAssembler.hpp> #include <amdis/LocalAssembler.hpp>
#include <amdis/LocalOperator.hpp> #include <amdis/LocalOperator.hpp>
#include <amdis/common/Utility.hpp>
#include <amdis/utility/Visitor.hpp> #include <amdis/utility/Visitor.hpp>
namespace AMDiS { namespace AMDiS {
...@@ -45,9 +46,9 @@ insert(RowLocalView const& rowLocalView, ColLocalView const& colLocalView, ...@@ -45,9 +46,9 @@ insert(RowLocalView const& rowLocalView, ColLocalView const& colLocalView,
template <class RB, class CB, class B> template <class RB, class CB, class B>
template <class ContextTag, class Operator, class RowTreePath, class ColTreePath> template <class ContextTag, class PreOperator, class RowTreePath, class ColTreePath>
void DOFMatrixBase<RB,CB,B>:: void DOFMatrixBase<RB,CB,B>::
addOperator(ContextTag contextTag, Operator const& preOp, addOperator(ContextTag contextTag, PreOperator const& preOp,
RowTreePath row, ColTreePath col) RowTreePath row, ColTreePath col)
{ {
static_assert( Concepts::PreTreePath<RowTreePath>, static_assert( Concepts::PreTreePath<RowTreePath>,
...@@ -60,7 +61,7 @@ addOperator(ContextTag contextTag, Operator const& preOp, ...@@ -60,7 +61,7 @@ addOperator(ContextTag contextTag, Operator const& preOp,
using Context = typename ContextTag::type; using Context = typename ContextTag::type;
auto op = makeLocalOperator<Context>(preOp, rowBasis_->gridView()); auto op = makeLocalOperator<Context>(preOp, rowBasis_->gridView());
auto localAssembler = makeLocalAssemblerPtr<Context>(std::move(op), i, j); auto localAssembler = makeUniquePtr(makeLocalAssembler<Context>(std::move(op), i, j));
operators_[i][j].push(contextTag, std::move(localAssembler)); operators_[i][j].push(contextTag, std::move(localAssembler));
} }
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <amdis/Assembler.hpp> #include <amdis/Assembler.hpp>
#include <amdis/LocalAssembler.hpp> #include <amdis/LocalAssembler.hpp>
#include <amdis/LocalOperator.hpp> #include <amdis/LocalOperator.hpp>
#include <amdis/common/Utility.hpp>
#include <amdis/utility/Visitor.hpp> #include <amdis/utility/Visitor.hpp>
namespace AMDiS { namespace AMDiS {
...@@ -40,9 +41,9 @@ insert(LocalView const& localView, ElementVector const& elementVector) ...@@ -40,9 +41,9 @@ insert(LocalView const& localView, ElementVector const& elementVector)
template <class BS, class B> template <class BS, class B>
template <class ContextTag, class Operator, class TreePath> template <class ContextTag, class PreOperator, class TreePath>
void DOFVectorBase<BS,B>:: void DOFVectorBase<BS,B>::
addOperator(ContextTag contextTag, Operator const& preOp, TreePath path) addOperator(ContextTag contextTag, PreOperator const& preOp, TreePath path)
{ {
static_assert( Concepts::PreTreePath<TreePath>, static_assert( Concepts::PreTreePath<TreePath>,
"path must be a valid treepath, or an integer/index-constant"); "path must be a valid treepath, or an integer/index-constant");
...@@ -51,7 +52,7 @@ addOperator(ContextTag contextTag, Operator const& preOp, TreePath path) ...@@ -51,7 +52,7 @@ addOperator(ContextTag contextTag, Operator const& preOp, TreePath path)
using Context = typename ContextTag::type; using Context = typename ContextTag::type;
auto op = makeLocalOperator<Context>(preOp, basis_->gridView()); auto op = makeLocalOperator<Context>(preOp, basis_->gridView());
auto localAssembler = makeLocalAssemblerPtr<Context>(std::move(op), i); auto localAssembler = makeUniquePtr(makeLocalAssembler<Context>(std::move(op), i));
operators_[i].push(contextTag, std::move(localAssembler)); operators_[i].push(contextTag, std::move(localAssembler));
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment