Commit 5ba4824f authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

interpolation of expressions added

parent 43bf24b6
...@@ -14,6 +14,14 @@ namespace AMDiS ...@@ -14,6 +14,14 @@ namespace AMDiS
Geometry const& geometry; Geometry const& geometry;
LocalGeometry const& localGeometry; LocalGeometry const& localGeometry;
ContextGeometry(LocalContext const& localContext,
Geometry const& geometry,
LocalGeometry const& localGeometry)
: localContext(localContext)
, geometry(geometry)
, localGeometry(localGeometry)
{}
/// Coordinate `p` given in `localGeometry`, transformed to coordinate in `geometry`. /// Coordinate `p` given in `localGeometry`, transformed to coordinate in `geometry`.
template <class Coordinate> template <class Coordinate>
decltype(auto) position(Coordinate const& p) const decltype(auto) position(Coordinate const& p) const
......
...@@ -80,7 +80,7 @@ namespace AMDiS ...@@ -80,7 +80,7 @@ namespace AMDiS
{ {
using Dune::Functions::BasisBuilder::makeBasis; using Dune::Functions::BasisBuilder::makeBasis;
using Dune::Functions::BasisBuilder::lagrange; using Dune::Functions::BasisBuilder::lagrange;
auto fct = makeDiscreteFunction(basis_,treePath_,vector_); auto fct = makeDiscreteFunctionPtr(basis_,treePath_,vector_);
auto p1basis = makeBasis(basis_->gridView(), lagrange<1>()); auto p1basis = makeBasis(basis_->gridView(), lagrange<1>());
auto data = makeDOFVector(p1basis, name_); auto data = makeDOFVector(p1basis, name_);
...@@ -102,7 +102,7 @@ namespace AMDiS ...@@ -102,7 +102,7 @@ namespace AMDiS
using Dune::Functions::BasisBuilder::flatLexicographic; using Dune::Functions::BasisBuilder::flatLexicographic;
assert( C == dow ); assert( C == dow );
auto fct = makeDiscreteFunction(basis_,treePath_,vector_); auto fct = makeDiscreteFunctionPtr(basis_,treePath_,vector_);
auto p1basis = makeBasis(basis_->gridView(), power<C>(lagrange<1>(), flatLexicographic())); auto p1basis = makeBasis(basis_->gridView(), power<C>(lagrange<1>(), flatLexicographic()));
auto data = makeDOFVector(p1basis, name_); auto data = makeDOFVector(p1basis, name_);
......
...@@ -228,12 +228,12 @@ namespace AMDiS ...@@ -228,12 +228,12 @@ namespace AMDiS
std::shared_ptr<SystemVector> getSolution() { return solution; } std::shared_ptr<SystemVector> getSolution() { return solution; }
std::shared_ptr<SystemVector const> getSolution() const { return solution; } std::shared_ptr<SystemVector const> getSolution() const { return solution; }
/// Return a view to a solution component /// Return a view to a solution component (as shared_ptr)
template <class TreePath> template <class TreePath>
auto getSolution(TreePath path) const auto getSolution(TreePath path) const
{ {
auto tp = makeTreePath(path); auto tp = makeTreePath(path);
return makeDiscreteFunction(globalBasis, tp, solution); return makeDiscreteFunctionPtr(globalBasis, tp, solution);
} }
......
...@@ -5,21 +5,6 @@ ...@@ -5,21 +5,6 @@
// from http://stackoverflow.com/questions/17424477/implementation-c14-make-integer-sequence/17426611#17426611 // from http://stackoverflow.com/questions/17424477/implementation-c14-make-integer-sequence/17426611#17426611
namespace AMDiS namespace AMDiS
{ {
// template <std::size_t i, std::size_t j>
// constexpr index_<i+j> operator+(index_<i>, index_<j>) { return {}; }
// template <std::size_t i, std::size_t j>
// constexpr index_<i-j> operator-(index_<i>, index_<j>) { return {}; }
// template <std::size_t i, std::size_t j>
// constexpr index_<i*j> operator*(index_<i>, index_<j>) { return {}; }
// template <std::size_t i, std::size_t j>
// constexpr index_<i/j> operator/(index_<i>, index_<j>) { return {}; }
namespace Impl namespace Impl
{ {
template <std::size_t s, class S> template <std::size_t s, class S>
......
...@@ -8,10 +8,12 @@ namespace AMDiS ...@@ -8,10 +8,12 @@ namespace AMDiS
namespace traits namespace traits
{ {
template <class T> template <class T>
using is_integral = std::is_integral<std::decay_t<T>>; struct is_integral
: public std::is_integral<std::decay_t<T>> {};
template <class T> template <class T>
using is_arithmetic = std::is_arithmetic<std::decay_t<T>>; struct is_arithmetic
: public std::is_arithmetic<std::decay_t<T>> {};
} // end namespace traits } // end namespace traits
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include <type_traits> #include <type_traits>
#include <boost/numeric/mtl/matrix/compressed2D.hpp>
#include <boost/numeric/mtl/vector/dense_vector.hpp> #include <boost/numeric/mtl/vector/dense_vector.hpp>
#include <boost/numeric/mtl/matrix/dense2D.hpp> #include <boost/numeric/mtl/matrix/dense2D.hpp>
...@@ -17,26 +18,6 @@ namespace AMDiS ...@@ -17,26 +18,6 @@ namespace AMDiS
} // end namespace Impl } // end namespace Impl
enum FirstOrderType
{
GRD_PSI,
GRD_PHI
};
template <FirstOrderType type>
using FirstOrderType_t = std::integral_constant<FirstOrderType, type>;
template <FirstOrderType type>
constexpr FirstOrderType_t<type> FirstOrderType_ = {};
struct BoundaryType { int b; }; struct BoundaryType { int b; };
namespace tag
{
struct zot {};
struct fot_grd_phi {};
struct fot_grd_psi {};
struct sot {};
}
} // end namespace AMDiS } // end namespace AMDiS
...@@ -21,16 +21,22 @@ namespace AMDiS ...@@ -21,16 +21,22 @@ namespace AMDiS
namespace Impl namespace Impl
{ {
// workaround for MSVC (problems with alias templates in pack expansion) // workaround for MSVC (problems with alias templates in pack expansion)
template <class, class T> template <class, class T>
struct InvokeType { using type = T; }; struct InvokeType { using type = T; };
template <class, class, class T> template <class, class, class T>
struct InvokeType2 { using type = T; }; struct InvokeType2 { using type = T; };
template <class T>
struct ValueType
{
using type = typename InvokeType<T, typename T::value_type>::type;
};
} }
template <class T> template <class T>
using Value_t = typename Impl::InvokeType<T, typename T::value_type>::type; using Value_t = typename Impl::ValueType<T>::type;
template <class T> template <class T>
using Size_t = typename Impl::InvokeType<T, typename T::size_type>::type; using Size_t = typename Impl::InvokeType<T, typename T::size_type>::type;
...@@ -44,6 +50,24 @@ namespace AMDiS ...@@ -44,6 +50,24 @@ namespace AMDiS
template <class T1, class T2> template <class T1, class T2>
using Common_t = typename Impl::InvokeType2<T1, T2, typename std::common_type<T1,T2>::type>::type; using Common_t = typename Impl::InvokeType2<T1, T2, typename std::common_type<T1,T2>::type>::type;
namespace Impl
{
template <class T>
struct UnderlyingType
{
using type = T;
};
template <class T>
struct UnderlyingType<std::reference_wrapper<T>>
{
using type = T;
};
}
template <class T>
using Underlying_t = typename Impl::UnderlyingType<T>::type;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
......
...@@ -35,12 +35,6 @@ namespace AMDiS ...@@ -35,12 +35,6 @@ 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> >
{ {
...@@ -65,6 +59,12 @@ namespace AMDiS ...@@ -65,6 +59,12 @@ namespace AMDiS
using type = tag::scalar; using type = tag::scalar;
}; };
template <class T>
struct ValueCategory<std::reference_wrapper<T>>
{
using type = typename ValueCategory<T>::type;
};
namespace Category namespace Category
{ {
template <class T> template <class T>
......
...@@ -123,9 +123,9 @@ namespace AMDiS ...@@ -123,9 +123,9 @@ namespace AMDiS
/// \brief interpolate a function \p f to the basis \ref feSpace and store the /// \brief interpolate a function \p f to the basis \ref feSpace and store the
/// coefficients in \ref vector. /// coefficients in \ref vector.
template <class F> template <class F>
void interpol(F const& f) void interpol(F&& f)
{ {
Dune::Functions::interpolate(feSpace, *this, f); Dune::Functions::interpolate(feSpace, *this, std::forward<F>(f));
} }
/// Scale each DOFVector by the factor \p s. /// Scale each DOFVector by the factor \p s.
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <type_traits> #include <type_traits>
#include <dune/amdis/common/ScalarTypes.hpp> #include <dune/amdis/common/ScalarTypes.hpp>
#include <dune/amdis/common/Utility.hpp>
#include <dune/amdis/terms/ExpressionBase.hpp> #include <dune/amdis/terms/ExpressionBase.hpp>
namespace AMDiS namespace AMDiS
...@@ -19,44 +20,32 @@ namespace AMDiS ...@@ -19,44 +20,32 @@ namespace AMDiS
{ {
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 = T; using value_type = Underlying_t<T>;
explicit ConstantTerm(value_type const& value) explicit ConstantTerm(value_type const& value)
: ExpressionBase(0) : ExpressionBase(0)
, value_(value) , value_(value)
{} {}
value_type const& operator[](std::size_t iq) const template <class Context, class LocalCoordinate>
value_type const& local(Context const& /*context*/, LocalCoordinate const& /*lambda*/) const
{ {
return value_; return value_;
} }
private: template <class GlobalCoordinate>
value_type value_; value_type const& global(GlobalCoordinate const& /*x*/) const
}; {
return value_;
}
/// 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)
, ref_(ref)
{}
value_type const& operator[](std::size_t iq) const value_type const& operator[](std::size_t /*iq*/) const
{ {
return ref_; return value_;
} }
private: private:
std::reference_wrapper<value_type> ref_; value_type value_;
}; };
......
...@@ -64,7 +64,19 @@ namespace AMDiS ...@@ -64,7 +64,19 @@ namespace AMDiS
{ {
values_.resize(points.size()); values_.resize(points.size());
for (std::size_t iq = 0; iq < points.size(); ++iq) for (std::size_t iq = 0; iq < points.size(); ++iq)
values_[iq] = fct_(context.global(points[iq].position())); values_[iq] = local(context, points[iq].position());
}
template <class Context, class LocalCoordinate>
value_type local(Context const& context, LocalCoordinate const& lambda) const
{
return fct_(context.global(lambda));
}
template <class GlobalCoordinate>
value_type global(GlobalCoordinate const& x) const
{
return fct_(x);
} }
value_type const& operator[](std::size_t iq) const value_type const& operator[](std::size_t iq) const
...@@ -108,6 +120,18 @@ namespace AMDiS ...@@ -108,6 +120,18 @@ namespace AMDiS
values_[iq] = context.global( points[iq].position() ); values_[iq] = context.global( points[iq].position() );
} }
template <class Context, class LocalCoordinate>
value_type const& local(Context const& context, LocalCoordinate const& lambda) const
{
return context.global(lambda);
}
template <class GlobalCoordinate>
value_type const& global(GlobalCoordinate const& x) const
{
return x;
}
value_type const& operator[](std::size_t iq) const value_type const& operator[](std::size_t iq) const
{ {
return values_[iq]; return values_[iq];
......
...@@ -54,11 +54,24 @@ namespace AMDiS ...@@ -54,11 +54,24 @@ namespace AMDiS
} }
template <class Context, class PointList> template <class Context, class PointList>
void init(Context const& /*context*/, PointList const& points) void init(Context const& context, PointList const& points)
{ {
values_.resize(points.size()); values_.resize(points.size());
for (std::size_t iq = 0; iq < points.size(); ++iq) for (std::size_t iq = 0; iq < points.size(); ++iq)
values_[iq] = factor_ * localFunction_(points[iq].position()); values_[iq] = factor_ * local(context, points[iq].position());
}
template <class Context, class LocalCoordinate>
value_type local(Context const& /*context*/, LocalCoordinate const& lambda) const
{
return localFunction_(lambda);
}
template <class GlobalCoordinate>
value_type global(GlobalCoordinate const& x) const
{
error_exit("Not implemented.");
return value_type(0);
} }
value_type const& operator[](std::size_t iq) const value_type const& operator[](std::size_t iq) const
...@@ -86,10 +99,12 @@ namespace AMDiS ...@@ -86,10 +99,12 @@ namespace AMDiS
* an optional factor \p factor the value of the DOFVector at the quadrature * an optional factor \p factor the value of the DOFVector at the quadrature
* points are scaled with. * points are scaled with.
**/ **/
template <class DiscreteGlobalBasisFct> template <class... Args>
auto valueOf(std::shared_ptr<DiscreteGlobalBasisFct> const& vector, double factor = 1.0) auto valueOf(std::shared_ptr<Dune::Functions::DiscreteGlobalBasisFunction<Args...>> const& dofvector,
double factor = 1.0)
{ {
return DOFVectorTerm<DiscreteGlobalBasisFct>{vector, factor}; using DiscreteGlobalBasisFct = Dune::Functions::DiscreteGlobalBasisFunction<Args...>;
return DOFVectorTerm<DiscreteGlobalBasisFct>{dofvector, factor};
} }
......
...@@ -60,16 +60,31 @@ namespace AMDiS ...@@ -60,16 +60,31 @@ namespace AMDiS
}); });
} }
template <class Context, class LocalCoordinate>
value_type local(Context const& context, LocalCoordinate const& lambda) const
{
return eval([&context,&lambda](auto const& term) { return term.local(context, lambda); },
MakeSeq_t<sizeof...(Terms)>{});
}
template <class GlobalCoordinate>
value_type global(GlobalCoordinate const& x) const
{
return eval([&x](auto const& term) { return term.global(x); },
MakeSeq_t<sizeof...(Terms)>{});
}
auto operator[](std::size_t iq) const auto operator[](std::size_t iq) const
{ {
return eval(iq, MakeSeq_t<sizeof...(Terms)>{}); return eval([iq](auto const& term) { return term[iq]; },
MakeSeq_t<sizeof...(Terms)>{});
} }
private: private:
template <std::size_t... Is> template <class Op, std::size_t... Is>
auto eval(std::size_t iq, Indices<Is...>) const auto eval(Op op, Indices<Is...>) const
{ {
return fct_(std::get<Is>(terms_)[iq]...); return fct_(op(std::get<Is>(terms_))...);
} }
private: private:
......
#pragma once
#include <dune/functions/gridfunctions/gridviewentityset.hh>
#include <dune/amdis/Output.hpp>
#include <dune/amdis/terms/LocalExpression.hpp>
namespace AMDiS
{
template <class Expr, class GridView>
class GridViewExpression
{
using Element = typename GridView::template Codim<0>::Entity;
using Domain = typename Element::Geometry::GlobalCoordinate;
using Range = typename Expr::value_type;
using EntitySet = Dune::Functions::GridViewEntitySet<GridView, 0>;
using LocalExpr = LocalExpression<Expr, GridView>;
public:
GridViewExpression(Expr const& expr, GridView const& gridView)
: expr_(expr)
, entitySet_(gridView)
{}
Range operator()(Domain const& x) const
{
return expr_.global(x);
}
friend LocalExpr localFunction(GridViewExpression const& self)
{
return LocalExpr{self.expr_};
}
EntitySet const& entitySet() const
{
return entitySet_;
}
private:
Expr expr_;
EntitySet entitySet_;
};
template <class Expr, class GridView,
std::enable_if_t<std::is_base_of<ExpressionBase, Expr>::value, int> = 0>
auto makeGridViewExpression(Expr const& expr, GridView const& gridView)
{
return GridViewExpression<Expr, GridView>{expr, gridView};
}
} // end namespace AMDiS
#pragma once
#include <memory>
#include <dune/functions/functionspacebases/interpolate.hh>
#include <dune/functions/gridfunctions/discreteglobalbasisfunction.hh>
#include <dune/amdis/terms/GridViewExpression.hpp>
#include <dune/amdis/terms/TermGenerator.hpp>
namespace AMDiS
{
template <class... Args, class PreExpr>
auto operator<<(std::shared_ptr<Dune::Functions::DiscreteGlobalBasisFunction<Args...>> const& dofvector,
PreExpr&& preExpr)
{
using DiscreteGlobalBasisFct = Dune::Functions::DiscreteGlobalBasisFunction<Args...>;
typename ToTerm<PreExpr>::type expr = toTerm(std::forward<PreExpr>(preExpr));
using Vector = typename DiscreteGlobalBasisFct::Vector;
Vector vec(dofvector->basis(), "tmp");
auto gridViewExpr = makeGridViewExpression(expr, dofvector->basis().gridView());
Dune::Functions::interpolate(dofvector->basis(), dofvector->treePath(), vec, gridViewExpr);
const_cast<Vector&>(dofvector->dofs()).getVector() = vec.getVector();
return dofvector;
}
template <class... Args, class PreExpr>
auto& operator<<(Dune::Functions::DiscreteGlobalB