Commit 803d5ee7 authored by Praetorius, Simon's avatar Praetorius, Simon

removed makeXXXPtr removed and factory functions restructured

parent 6f70e871
Pipeline #1613 passed with stage
in 20 minutes and 19 seconds
......@@ -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 <class GF>
GridFunctionOperatorBase(GF&& gridFct, int termOrder)
: gridFct_(std::forward<GF>(gridFct))
, termOrder_(termOrder)
{}
......@@ -91,10 +92,11 @@ namespace AMDiS
/// Create a quadrature factory from a PreQuadratureFactory, e.g. class derived from \ref QuadratureFactory
template <class PreQuadFactory>
void setQuadFactory(PreQuadFactory const& pre)
void setQuadFactory(PreQuadFactory&& pre)
{
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:
......@@ -161,9 +163,9 @@ namespace AMDiS
/// Redirects the setQuadFactory call top the transposed operator
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
......@@ -182,6 +184,7 @@ namespace AMDiS
Transposed transposedOp_;
};
template <class Tag, class PreGridFct, class PreQuadFactory>
struct PreGridFunctionOperator
{
......@@ -190,12 +193,13 @@ namespace AMDiS
PreQuadFactory quadFactory;
};
/// Store tag and expression to create a \ref GridFunctionOperator
template <class Tag, class PreGridFct, class... QuadratureArgs>
auto makeOperator(Tag tag, PreGridFct const& expr, QuadratureArgs&&... args)
/// Store tag and expression into a \ref PreGridFunctionOperator to create a \ref GridFunctionOperator
template <class Tag, class Expr, class... QuadratureArgs>
auto makeOperator(Tag tag, Expr&& expr, QuadratureArgs&&... args)
{
auto preQuadFactory = makePreQuadratureFactory(std::forward<QuadratureArgs>(args)...);
return PreGridFunctionOperator<Tag, PreGridFct, decltype(preQuadFactory)>{tag, expr, preQuadFactory};
auto pqf = makePreQuadratureFactory(std::forward<QuadratureArgs>(args)...);
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
: public GridFunctionOperatorBase<GridFunctionOperator<Tag, LocalContext, GridFct>, LocalContext, GridFct>
{};
/// Generate an \ref GridFunctionOperator from a PreOperator (tag, expr).
/// @{
template <class LocalContext, class Tag, class... Args, class GridView>
auto makeLocalOperator(PreGridFunctionOperator<Tag, Args...> const& op, GridView const& gridView)
template <class Context, class Tag, class GF, class QF>
auto makeGridFunctionOperator(Tag tag, GF&& gf, QF&& qf)
{
auto gridFct = makeGridFunction(op.expr, gridView);
using GridFctOp = GridFunctionOperator<Tag, LocalContext, decltype(gridFct)>;
GridFctOp localOperator{op.tag, gridFct};
localOperator.setQuadFactory(op.quadFactory);
return localOperator;
using GridFctOp = GridFunctionOperator<Tag, Context, std::decay_t<GF>>;
GridFctOp gfo{tag, std::forward<GF>(gf)};
gfo.setQuadFactory(std::forward<QF>(qf));
return gfo;
}
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 a shared_ptr to \ref GridFunctionOperator from a PreOperator (tag, expr).
/// Generate an \ref GridFunctionOperator from a PreOperator (tag, expr).
/// @{
template <class LocalContext, class Tag, class... Args, class GridView>
auto makeLocalOperatorPtr(PreGridFunctionOperator<Tag, Args...> const& op, GridView const& gridView)
template <class Context, class... Args, class GridView>
auto makeLocalOperator(PreGridFunctionOperator<Args...> op, GridView const& gridView)
{
auto gridFct = makeGridFunction(op.expr, gridView);
using GridFctOp = GridFunctionOperator<Tag, LocalContext, decltype(gridFct)>;
auto localOperator = std::make_shared<GridFctOp>(op.tag, gridFct);
localOperator->setQuadFactory(op.quadFactory);
return localOperator;
auto gf = makeGridFunction(std::move(op.expr), gridView);
return makeGridFunctionOperator<Context>(op.tag, std::move(gf), std::move(op.quadFactory));
}
template <class LocalContext, class Tag, class... Args, class GridView>
auto makeLocalOperatorPtr(std::reference_wrapper<PreGridFunctionOperator<Tag, Args...>> op, GridView const& gridView)
template <class Context, class... Args, class GridView>
auto makeLocalOperator(std::reference_wrapper<PreGridFunctionOperator<Args...>> op_ref, 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)>;
auto localOperator = std::make_shared<GridFctOp>(op_ref.tag, gridFct);
localOperator->setQuadFactory(op_ref.quadFactory);
return localOperator;
PreGridFunctionOperator<Args...> const& op = op_ref;
auto gf = makeGridFunction(std::ref(op.expr), gridView);
return makeGridFunctionOperator<Context>(op.tag, std::move(gf), op.quadFactory);
}
/// @}
......
......@@ -4,6 +4,7 @@
#include <memory>
#include <type_traits>
#include <dune/common/shared_ptr.hh>
#include <dune/geometry/quadraturerules.hh>
#include <amdis/ContextGeometry.hpp>
......@@ -30,13 +31,17 @@ namespace AMDiS
/// Constructor. Stores a copy of operator `op`.
explicit LocalAssembler(Operator const& op)
: storage_(std::make_unique<Operator>(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<Operator> const& op)
: op_(op)
explicit LocalAssembler(std::reference_wrapper<Operator> 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<Operator> storage_;
Operator& op_;
std::shared_ptr<Operator> 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 <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>
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
......@@ -190,17 +190,10 @@ namespace AMDiS
/// Generate a \ref LocalOperator from a PreOperator.
template <class Derived, class LocalContext, class GridView>
auto makeLocalOperator(LocalOperator<Derived, LocalContext> const& localOp, GridView const& /*gridView*/)
template <class Derived, class Context, class GridView>
auto makeLocalOperator(LocalOperator<Derived, Context> const& localOp, GridView const& /*gridView*/)
{
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
......@@ -220,19 +220,19 @@ namespace AMDiS
return Pre{gridFctA, gridFctB, gridFctC, gridFctF};
}
template <class LocalContext, class... T, class GridView>
auto makeLocalOperator(PreConvectionDiffusionOperator<T...> const& pre, GridView const& gridView)
template <class Context, class... T, class GridView>
auto makeLocalOperator(PreConvectionDiffusionOperator<T...> pre, GridView const& gridView)
{
using Pre = PreConvectionDiffusionOperator<T...>;
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<LocalContext,
using GridFctOp = ConvectionDiffusionOperator<Context,
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;
}
......
......@@ -17,13 +17,13 @@ namespace AMDiS
template <class T>
struct UnderlyingType
{
using type = T;
using type = std::decay_t<T>;
};
template <class T>
struct UnderlyingType<std::reference_wrapper<T>>
{
using type = T;
using type = std::decay_t<T>;
};
}
......@@ -50,6 +50,13 @@ namespace AMDiS
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
......
......@@ -3,6 +3,7 @@
#include <amdis/Assembler.hpp>
#include <amdis/LocalAssembler.hpp>
#include <amdis/LocalOperator.hpp>
#include <amdis/common/Utility.hpp>
#include <amdis/utility/Visitor.hpp>
namespace AMDiS {
......@@ -45,9 +46,9 @@ insert(RowLocalView const& rowLocalView, ColLocalView const& colLocalView,
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>::
addOperator(ContextTag contextTag, Operator const& preOp,
addOperator(ContextTag contextTag, PreOperator const& preOp,
RowTreePath row, ColTreePath col)
{
static_assert( Concepts::PreTreePath<RowTreePath>,
......@@ -60,7 +61,7 @@ addOperator(ContextTag contextTag, Operator const& preOp,
using Context = typename ContextTag::type;
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));
}
......
......@@ -3,6 +3,7 @@
#include <amdis/Assembler.hpp>
#include <amdis/LocalAssembler.hpp>
#include <amdis/LocalOperator.hpp>
#include <amdis/common/Utility.hpp>
#include <amdis/utility/Visitor.hpp>
namespace AMDiS {
......@@ -40,9 +41,9 @@ insert(LocalView const& localView, ElementVector const& elementVector)
template <class BS, class B>
template <class ContextTag, class Operator, class TreePath>
template <class ContextTag, class PreOperator, class TreePath>
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>,
"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<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));
}
......
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