Commit 9f44e925 authored by Praetorius, Simon's avatar Praetorius, Simon

ConstantExpr with reference_wrapper argument, LocalAssembler accepts operator by reference_wrapper

parent 7e44b707
Pipeline #940 failed with stage
in 1 minute and 31 seconds
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include <dune/amdis/DirichletBC.hpp> #include <dune/amdis/DirichletBC.hpp>
#include <dune/amdis/LinearAlgebra.hpp> #include <dune/amdis/LinearAlgebra.hpp>
#include <dune/amdis/Operator.hpp> #include <dune/amdis/LocalAssemblerBase.hpp>
#include <dune/amdis/common/Mpl.hpp> #include <dune/amdis/common/Mpl.hpp>
#include <dune/amdis/common/TypeDefs.hpp> #include <dune/amdis/common/TypeDefs.hpp>
......
...@@ -42,7 +42,7 @@ void Assembler<Traits>::assemble( ...@@ -42,7 +42,7 @@ void Assembler<Traits>::assemble(
{ {
auto rowBasis = Dune::Functions::subspaceBasis(globalBasis_, rowTreePath); auto rowBasis = Dune::Functions::subspaceBasis(globalBasis_, rowTreePath);
auto rowLocalView = rowBasis.localView(); auto rowLocalView = rowBasis.localView();
rowLocalView.bind(element); // NOTE: Is this necessary rowLocalView.bind(element); // NOTE: Is this necessary?
auto& rhsOp = rhsOperators_[rowNode]; auto& rhsOp = rhsOperators_[rowNode];
if (rhsOp.assemble(asmVector) && !rhsOp.empty()) if (rhsOp.assemble(asmVector) && !rhsOp.empty())
...@@ -54,7 +54,7 @@ void Assembler<Traits>::assemble( ...@@ -54,7 +54,7 @@ void Assembler<Traits>::assemble(
if (matOp.assemble(asmMatrix) && !matOp.empty()) { if (matOp.assemble(asmMatrix) && !matOp.empty()) {
auto colBasis = Dune::Functions::subspaceBasis(globalBasis_, colTreePath); auto colBasis = Dune::Functions::subspaceBasis(globalBasis_, colTreePath);
auto colLocalView = colBasis.localView(); auto colLocalView = colBasis.localView();
colLocalView.bind(element); // NOTE: Is this necessary colLocalView.bind(element); // NOTE: Is this necessary?
assembleElementOperators(elementMatrix, matrix, matOp, geometry, rowLocalView, colLocalView); assembleElementOperators(elementMatrix, matrix, matOp, geometry, rowLocalView, colLocalView);
} }
...@@ -159,9 +159,7 @@ void Assembler<Traits>::initMatrixVector( ...@@ -159,9 +159,7 @@ void Assembler<Traits>::initMatrixVector(
{ {
auto colBasis = Dune::Functions::subspaceBasis(globalBasis_, colTreePath); auto colBasis = Dune::Functions::subspaceBasis(globalBasis_, colTreePath);
for (auto bc : constraints_[rowNode][colNode].scalar) for (auto bc : constraints_[rowNode][colNode])
bc->init(matrix, solution, rhs, rowBasis, colBasis);
for (auto bc : constraints_[rowNode][colNode].vector)
bc->init(matrix, solution, rhs, rowBasis, colBasis); bc->init(matrix, solution, rhs, rowBasis, colBasis);
}); });
}); });
...@@ -195,9 +193,7 @@ std::size_t Assembler<Traits>::finishMatrixVector( ...@@ -195,9 +193,7 @@ std::size_t Assembler<Traits>::finishMatrixVector(
matOp.assembled = true; matOp.assembled = true;
// finish boundary condition // finish boundary condition
for (auto bc : constraints_[rowNode][colNode].scalar) for (auto bc : constraints_[rowNode][colNode])
bc->finish(matrix, solution, rhs, rowBasis, colBasis);
for (auto bc : constraints_[rowNode][colNode].vector)
bc->finish(matrix, solution, rhs, rowBasis, colBasis); bc->finish(matrix, solution, rhs, rowBasis, colBasis);
}); });
}); });
......
...@@ -8,7 +8,7 @@ dune_add_library("duneamdis" NO_EXPORT ...@@ -8,7 +8,7 @@ dune_add_library("duneamdis" NO_EXPORT
AMDiS.cpp AMDiS.cpp
Initfile.cpp Initfile.cpp
ProblemInstatBase.cpp ProblemInstatBase.cpp
ProblemInstat.cpp # ProblemInstat.cpp
ProblemStat.cpp ProblemStat.cpp
StandardProblemIteration.cpp StandardProblemIteration.cpp
#linear_algebra/istl/SystemMatrix.cpp #linear_algebra/istl/SystemMatrix.cpp
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <dune/amdis/Output.hpp> #include <dune/amdis/Output.hpp>
#include <dune/amdis/common/Concepts.hpp> #include <dune/amdis/common/Concepts.hpp>
#include <dune/amdis/utility/RangeType.hpp>
#include <dune/amdis/utility/TreeData.hpp> #include <dune/amdis/utility/TreeData.hpp>
namespace AMDiS namespace AMDiS
...@@ -34,8 +35,8 @@ namespace AMDiS ...@@ -34,8 +35,8 @@ namespace AMDiS
REQUIRES(Concepts::Functor<Predicate, bool(Domain)> && REQUIRES(Concepts::Functor<Predicate, bool(Domain)> &&
Concepts::Functor<Values, Range(Domain)>) > Concepts::Functor<Values, Range(Domain)>) >
DirichletBC(Predicate&& predicate, Values&& values) DirichletBC(Predicate&& predicate, Values&& values)
: predicate(std::forward<Predicate>(predicate)) : predicate_(std::forward<Predicate>(predicate))
, values(std::forward<Values>(values)) , values_(std::forward<Values>(values))
{} {}
...@@ -78,11 +79,11 @@ namespace AMDiS ...@@ -78,11 +79,11 @@ namespace AMDiS
void initImpl(RB const&, RowNodeTag) {} void initImpl(RB const&, RowNodeTag) {}
private: private:
std::function<bool(Domain)> predicate; std::function<bool(Domain)> predicate_;
std::function<Range(Domain)> values; std::function<Range(Domain)> values_;
bool initialized = false; bool initialized_ = false;
std::vector<char> dirichletNodes; std::vector<char> dirichletNodes_;
}; };
...@@ -92,14 +93,14 @@ namespace AMDiS ...@@ -92,14 +93,14 @@ namespace AMDiS
using WorldVector = typename GlobalBasis::GridView::template Codim<0>::Geometry::GlobalCoordinate; using WorldVector = typename GlobalBasis::GridView::template Codim<0>::Geometry::GlobalCoordinate;
template <class RowNode, class ColNode> template <class RowNode, class ColNode>
struct type using type = std::list< std::shared_ptr<DirichletBC<WorldVector, RangeType<RowNode>>> >;
{ // {
std::list<std::shared_ptr<DirichletBC<WorldVector, double>>> scalar; // using Range = RangeType<RowNode>;
std::list<std::shared_ptr<DirichletBC<WorldVector, WorldVector>>> vector; // std::list<std::shared_ptr<DirichletBC<WorldVector, Range>>> bc;
void push_back(std::shared_ptr<DirichletBC<WorldVector, double>> const& bc) { scalar.push_back(bc); } // void push_back(std::shared_ptr<DirichletBC<WorldVector, double>> const& bc) { scalar.push_back(bc); }
void push_back(std::shared_ptr<DirichletBC<WorldVector, WorldVector>> const& bc) { vector.push_back(bc); } // void push_back(std::shared_ptr<DirichletBC<WorldVector, WorldVector>> const& bc) { vector.push_back(bc); }
}; // };
}; };
template <class GlobalBasis> template <class GlobalBasis>
......
...@@ -14,9 +14,9 @@ namespace AMDiS ...@@ -14,9 +14,9 @@ namespace AMDiS
{ {
using Dune::Functions::interpolate; using Dune::Functions::interpolate;
if (!initialized) { if (!initialized_) {
interpolate(rowBasis, hierarchicVectorWrapper(dirichletNodes), predicate); interpolate(rowBasis, hierarchicVectorWrapper(dirichletNodes_), predicate_);
initialized = true; initialized_ = true;
} }
} }
...@@ -27,13 +27,13 @@ namespace AMDiS ...@@ -27,13 +27,13 @@ namespace AMDiS
{ {
using Dune::Functions::interpolate; using Dune::Functions::interpolate;
if (!initialized) { if (!initialized_) {
auto tp = rowBasis.prefixPath(); auto tp = rowBasis.prefixPath();
auto const& basis = rowBasis.rootBasis(); auto const& basis = rowBasis.rootBasis();
for (std::size_t i = 0; i < degree(rowBasis.localView().tree()); ++i) for (std::size_t i = 0; i < degree(rowBasis.localView().tree()); ++i)
interpolate(Dune::Functions::subspaceBasis(basis, push_back(tp,i)), interpolate(Dune::Functions::subspaceBasis(basis, push_back(tp,i)),
hierarchicVectorWrapper(dirichletNodes), predicate); hierarchicVectorWrapper(dirichletNodes_), predicate_);
initialized = true; initialized_ = true;
} }
} }
...@@ -47,11 +47,13 @@ namespace AMDiS ...@@ -47,11 +47,13 @@ namespace AMDiS
{ {
using Dune::Functions::interpolate; using Dune::Functions::interpolate;
test_exit_dbg(initialized, "Boundary condition not initialized!"); test_exit_dbg(initialized_, "Boundary condition not initialized!");
auto columns = matrix.applyDirichletBC(dirichletNodes); auto columns = matrix.applyDirichletBC(dirichletNodes_);
interpolate(rowBasis, hierarchicVectorWrapper(rhs.getVector()), values, hierarchicVectorWrapper(dirichletNodes)); interpolate(rowBasis, hierarchicVectorWrapper(rhs.getVector()), values_,
interpolate(colBasis, hierarchicVectorWrapper(solution.getVector()), values, hierarchicVectorWrapper(dirichletNodes)); hierarchicVectorWrapper(dirichletNodes_));
interpolate(colBasis, hierarchicVectorWrapper(solution.getVector()), values_,
hierarchicVectorWrapper(dirichletNodes_));
// subtract columns of dirichlet nodes from rhs // subtract columns of dirichlet nodes from rhs
for (auto const& triplet : columns) for (auto const& triplet : columns)
......
...@@ -34,8 +34,8 @@ namespace AMDiS ...@@ -34,8 +34,8 @@ 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)
: opStorage_(std::make_unique<Operator>(op)) : storage_(std::make_unique<Operator>(op))
, op_(*opStorage_) , op_(*storage_)
{} {}
/// Constructor. Stores the reference to the operator. /// Constructor. Stores the reference to the operator.
...@@ -189,7 +189,7 @@ namespace AMDiS ...@@ -189,7 +189,7 @@ namespace AMDiS
private: private:
std::unique_ptr<Operator> opStorage_; //< the stored operator, implementing \ref ExpressionOperatorBase std::unique_ptr<Operator> storage_; //< the stored operator, implementing \ref ExpressionOperatorBase
Operator& op_; Operator& op_;
Element const* element_ = nullptr; Element const* element_ = nullptr;
......
...@@ -193,18 +193,18 @@ namespace AMDiS ...@@ -193,18 +193,18 @@ namespace AMDiS
/// Generate an \ref ExpressionOperator with a given tag `t` and pre-expression `epxr`. /// Generate an \ref ExpressionOperator with a given tag `t` and pre-expression `epxr`.
template <class Tag, class Expr_> template <class Tag, class PreExpr>
auto makeOperator(Tag t, Expr_ const& expr) auto makeOperator(Tag t, PreExpr const& expr)
{ {
using Expr = ToTerm_t<Expr_>; using Expr = ToTerm_t<PreExpr>;
return ExpressionOperator<Tag, Expr>{t, toTerm(expr)}; return ExpressionOperator<Tag, Expr>{t, toTerm(expr)};
} }
/// Generate a shared_ptr to \ref ExpressionOperator with a given tag `t` and pre-expression `epxr`. /// Generate a shared_ptr to \ref ExpressionOperator with a given tag `t` and pre-expression `epxr`.
template <class Tag, class Expr_> template <class Tag, class PreExpr>
auto makeOperatorPtr(Tag t, Expr_ const& expr) auto makeOperatorPtr(Tag t, PreExpr const& expr)
{ {
using Expr = ToTerm_t<Expr_>; using Expr = ToTerm_t<PreExpr>;
return std::make_shared<ExpressionOperator<Tag, Expr>>(t, toTerm(expr)); return std::make_shared<ExpressionOperator<Tag, Expr>>(t, toTerm(expr));
} }
......
...@@ -6,5 +6,5 @@ ...@@ -6,5 +6,5 @@
namespace AMDiS namespace AMDiS
{ {
// explicit template instatiation // explicit template instatiation
template class ProblemInstat<YaspGridBasis<2,1>>; // template class ProblemInstat<YaspGridBasis<2,1>>;
} // end namespace AMDiS } // end namespace AMDiS
...@@ -79,11 +79,6 @@ namespace AMDiS ...@@ -79,11 +79,6 @@ namespace AMDiS
std::unique_ptr<SystemVector> oldSolution; std::unique_ptr<SystemVector> oldSolution;
}; };
#ifndef AMDIS_NO_EXTERN_PROBLEMINSTAT
extern template class ProblemInstat<YaspGridBasis<2,1>>;
#endif
} // end namespace AMDiS } // end namespace AMDiS
#include "ProblemInstat.inc.hpp" #include "ProblemInstat.inc.hpp"
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include <dune/amdis/Initfile.hpp> #include <dune/amdis/Initfile.hpp>
#include <dune/amdis/LinearAlgebra.hpp> #include <dune/amdis/LinearAlgebra.hpp>
#include <dune/amdis/Mesh.hpp> #include <dune/amdis/Mesh.hpp>
#include <dune/amdis/Operator.hpp>
#include <dune/amdis/ProblemStatBase.hpp> #include <dune/amdis/ProblemStatBase.hpp>
#include <dune/amdis/ProblemStatTraits.hpp> #include <dune/amdis/ProblemStatTraits.hpp>
#include <dune/amdis/StandardProblemIteration.hpp> #include <dune/amdis/StandardProblemIteration.hpp>
...@@ -143,14 +142,22 @@ namespace AMDiS ...@@ -143,14 +142,22 @@ namespace AMDiS
RowTreePath row, ColTreePath col, RowTreePath row, ColTreePath col,
Values const& values); Values const& values);
template <class Predicate, class RowTreePath, class ColTreePath>
void addDirichletBC(Predicate const& predicate,
RowTreePath row, ColTreePath col,
double constant)
{
addDirichletBC(predicate, row, col, [constant](auto const&) { return constant; });
}
private: // implementation detail
template <class Predicate, class RowNode, class ColNode>
void addDirichletBCImpl(Predicate const& predicate,
RowNode const& rowNode, ColNode const& colNode,
RangeType<RowNode> const& value);
template <class Predicate, class RowNode, class ColNode, class Values>
std::enable_if_t<not std::is_convertible<Values, RangeType<RowNode>>::value>
addDirichletBCImpl(Predicate const& predicate,
RowNode const& rowNode, ColNode const& colNode,
Values const& values);
public:
/// Implementation of \ref ProblemStatBase::solve /// Implementation of \ref ProblemStatBase::solve
virtual void solve(AdaptInfo& adaptInfo, virtual void solve(AdaptInfo& adaptInfo,
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <dune/amdis/AdaptInfo.hpp> #include <dune/amdis/AdaptInfo.hpp>
#include <dune/amdis/Assembler.hpp> #include <dune/amdis/Assembler.hpp>
#include <dune/amdis/FileWriter.hpp> #include <dune/amdis/FileWriter.hpp>
#include <dune/amdis/LocalAssembler.hpp>
#include <dune/amdis/common/Loops.hpp> #include <dune/amdis/common/Loops.hpp>
#include <dune/amdis/common/Timer.hpp> #include <dune/amdis/common/Timer.hpp>
...@@ -205,19 +206,38 @@ void ProblemStat<Traits>:: ...@@ -205,19 +206,38 @@ void ProblemStat<Traits>::
addDirichletBC(Predicate const& predicate, RowTreePath row, ColTreePath col, Values const& values) addDirichletBC(Predicate const& predicate, RowTreePath row, ColTreePath col, Values const& values)
{ {
static_assert( Concepts::Functor<Predicate, bool(WorldVector)>, static_assert( Concepts::Functor<Predicate, bool(WorldVector)>,
"Function passed to addDirichletBC for predicate does not model the Functor<bool(WorldVector)> concept"); "Function passed to addDirichletBC for `predicate` does not model the Functor<bool(WorldVector)> concept");
static_assert( Concepts::Callable<Values, WorldVector>,
"Function passed to addDirichletBC for values does not model the Callable<WorldVector> concept");
auto i = child(globalBasis->localView().tree(), makeTreePath(row)); auto i = child(globalBasis->localView().tree(), makeTreePath(row));
auto j = child(globalBasis->localView().tree(), makeTreePath(col)); auto j = child(globalBasis->localView().tree(), makeTreePath(col));
using Range = decltype(values(std::declval<WorldVector>())); addDirichletBCImpl(predicate, i, j, values);
}
template <class Traits>
template <class Predicate, class RowNode, class ColNode>
void ProblemStat<Traits>::
addDirichletBCImpl(Predicate const& predicate, RowNode const& row, ColNode const& col, RangeType<RowNode> const& value)
{
using Range = RangeType<RowNode>;
using BcType = DirichletBC<WorldVector,Range>; using BcType = DirichletBC<WorldVector,Range>;
auto bc = std::make_shared<BcType>(predicate, [value](auto const&) { return value; });
constraints[row][col].push_back(bc);
}
template <class Traits>
template <class Predicate, class RowNode, class ColNode, class Values>
std::enable_if_t<not std::is_convertible<Values, RangeType<RowNode>>::value>
ProblemStat<Traits>::
addDirichletBCImpl(Predicate const& predicate, RowNode const& row, ColNode const& col, Values const& values)
{
using Range = RangeType<RowNode>;
static_assert( Concepts::Functor<Values, Range(WorldVector)>,
"Function passed to addDirichletBC for `values` does not model the Functor<Range(WorldVector)> concept");
using BcType = DirichletBC<WorldVector,Range>;
auto bc = std::make_shared<BcType>(predicate, values); auto bc = std::make_shared<BcType>(predicate, values);
constraints[i][i].push_back(bc); constraints[row][col].push_back(bc);
} }
...@@ -233,10 +253,6 @@ solve(AdaptInfo& adaptInfo, bool createMatrixData, bool storeMatrixData) ...@@ -233,10 +253,6 @@ solve(AdaptInfo& adaptInfo, bool createMatrixData, bool storeMatrixData)
solution->compress(); solution->compress();
msg("matrix: ",num_rows(systemMatrix->getMatrix()), " x ", num_cols(systemMatrix->getMatrix()));
msg("x: ",num_rows(solution->getVector()));
msg("rhs: ",num_rows(rhs->getVector()));
linearSolver->solve(systemMatrix->getMatrix(), linearSolver->solve(systemMatrix->getMatrix(),
solution->getVector(), rhs->getVector(), solution->getVector(), rhs->getVector(),
solverInfo); solverInfo);
......
#pragma once #pragma once
#include <functional>
#include <type_traits> #include <type_traits>
#include <dune/common/fmatrix.hh> #include <dune/common/fmatrix.hh>
...@@ -34,6 +35,12 @@ namespace AMDiS ...@@ -34,6 +35,12 @@ namespace AMDiS
using type = tag::scalar; using type = tag::scalar;
}; };
template <class T>
struct ValueCategory<std::reference_wrapper<T>, std::enable_if_t< std::is_arithmetic<T>::value >>
{
using type = tag::scalar;
};
template <class K, int SIZE> template <class K, int SIZE>
struct ValueCategory< Dune::FieldVector<K, SIZE> > struct ValueCategory< Dune::FieldVector<K, SIZE> >
{ {
......
...@@ -34,8 +34,9 @@ namespace AMDiS ...@@ -34,8 +34,9 @@ namespace AMDiS
std::integral_constant<bool, sameFE> flagSameFE, std::integral_constant<bool, sameFE> flagSameFE,
std::integral_constant<bool, sameNode> flagSameNode) std::integral_constant<bool, sameNode> flagSameNode)
{ {
auto elementMatrixTransposed = trans(elementMatrix);
Transposed::calculateElementMatrix( Transposed::calculateElementMatrix(
context, quad, elementMatrix, colNode, rowNode, flagSameFE, flagSameNode); context, quad, elementMatrixTransposed, colNode, rowNode, flagSameFE, flagSameNode);
} }
}; };
......
...@@ -34,8 +34,9 @@ namespace AMDiS ...@@ -34,8 +34,9 @@ namespace AMDiS
std::integral_constant<bool, sameFE> flagSameFE, std::integral_constant<bool, sameFE> flagSameFE,
std::integral_constant<bool, sameNode> flagSameNode) std::integral_constant<bool, sameNode> flagSameNode)
{ {
auto elementMatrixTransposed = trans(elementMatrix);
Transposed::calculateElementMatrix( Transposed::calculateElementMatrix(
context, quad, elementMatrix, colNode, rowNode, flagSameFE, flagSameNode); context, quad, elementMatrixTransposed, colNode, rowNode, flagSameFE, flagSameNode);
} }
}; };
......
...@@ -34,8 +34,9 @@ namespace AMDiS ...@@ -34,8 +34,9 @@ namespace AMDiS
std::integral_constant<bool, sameFE> flagSameFE, std::integral_constant<bool, sameFE> flagSameFE,
std::integral_constant<bool, sameNode> flagSameNode) std::integral_constant<bool, sameNode> flagSameNode)
{ {
auto elementMatrixTransposed = trans(elementMatrix);
Transposed::calculateElementMatrix( Transposed::calculateElementMatrix(
context, quad, elementMatrix, colNode, rowNode, flagSameFE, flagSameNode); context, quad, elementMatrixTransposed, colNode, rowNode, flagSameFE, flagSameNode);
} }
}; };
......
...@@ -37,8 +37,9 @@ namespace AMDiS ...@@ -37,8 +37,9 @@ namespace AMDiS
std::integral_constant<bool, sameFE> flagSameFE, std::integral_constant<bool, sameFE> flagSameFE,
std::integral_constant<bool, sameNode> flagSameNode) std::integral_constant<bool, sameNode> flagSameNode)
{ {
auto elementMatrixTransposed = trans(elementMatrix);
Transposed::calculateElementMatrix( Transposed::calculateElementMatrix(
context, quad, elementMatrix, colNode, rowNode, flagSameFE, flagSameNode); context, quad, elementMatrixTransposed, colNode, rowNode, flagSameFE, flagSameNode);
} }
}; };
......
...@@ -34,8 +34,9 @@ namespace AMDiS ...@@ -34,8 +34,9 @@ namespace AMDiS
std::integral_constant<bool, sameFE> flagSameFE, std::integral_constant<bool, sameFE> flagSameFE,
std::integral_constant<bool, sameNode> flagSameNode) std::integral_constant<bool, sameNode> flagSameNode)
{ {
auto elementMatrixTransposed = trans(elementMatrix);
Transposed::calculateElementMatrix( Transposed::calculateElementMatrix(
context, quad, elementMatrix, colNode, rowNode, flagSameFE, flagSameNode); context, quad, elementMatrixTransposed, colNode, rowNode, flagSameFE, flagSameNode);
} }
}; };
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
#include <type_traits> #include <type_traits>
#include <dune/amdis/OperatorTermBase.hpp>
#include <dune/amdis/common/ScalarTypes.hpp> #include <dune/amdis/common/ScalarTypes.hpp>
#include <dune/amdis/terms/ExpressionBase.hpp> #include <dune/amdis/terms/ExpressionBase.hpp>
...@@ -14,15 +13,15 @@ namespace AMDiS ...@@ -14,15 +13,15 @@ namespace AMDiS
**/ **/
/// An expression representing a constant (arithmetic) value, \see constant /// An expression representing a constant (arithmetic) value, \see constant
template <class ValueType> template <class T>
class ConstantTerm class ConstantTerm
: public ExpressionBase : public ExpressionBase
{ {
public: public:
// TODO: possibly convert to plain type, in case of expression templates. // TODO: possibly convert to plain type, in case of expression templates.
using value_type = ValueType; using value_type = T;
explicit ConstantTerm(value_type value) explicit ConstantTerm(value_type const& value)
: ExpressionBase(0) : ExpressionBase(0)
, value_(value) , value_(value)
{} {}
...@@ -37,9 +36,33 @@ namespace AMDiS ...@@ -37,9 +36,33 @@ namespace AMDiS
}; };
/// An expression representing a reference to a constant (arithmetic) value, \see constant
template <class T>
class ConstantTerm<std::reference_wrapper<T>>
: public ExpressionBase
{
public:
// TODO: possibly convert to plain type, in case of expression templates.
using value_type = T;
explicit ConstantTerm(std::reference_wrapper<value_type> const& ref)
: ExpressionBase(0)