Commit 276cfed9 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

removed nested LocalFunction and GradientLocalFunction from inline implementation

parent a4aeae1d
...@@ -43,14 +43,17 @@ namespace AMDiS ...@@ -43,14 +43,17 @@ namespace AMDiS
constexpr std::size_t VTKFieldSize = Size<Range>; constexpr std::size_t VTKFieldSize = Size<Range>;
template <class GlobalBasis, class RangeType, class TreePath> template <class GB, class VT, class TP>
class FileWriter class FileWriter
: public FileWriterInterface : public FileWriterInterface
{ {
private: // typedefs and static constants using GlobalBasis = GB;
using ValueType = VT;
using TreePath = TP;
private:
using GridView = typename GlobalBasis::GridView; using GridView = typename GlobalBasis::GridView;
using DiscreteFunction = AMDiS::DiscreteFunction<GlobalBasis,RangeType,TreePath>; using Range = typename DiscreteFunction<GB,VT,TP>::Range;
using Range = typename DiscreteFunction::Range;
/// Dimension of the mesh /// Dimension of the mesh
static constexpr int dim = GridView::dimension; static constexpr int dim = GridView::dimension;
...@@ -60,26 +63,25 @@ namespace AMDiS ...@@ -60,26 +63,25 @@ namespace AMDiS
public: public:
/// Constructor. /// Constructor.
FileWriter(std::string const& baseName, FileWriter(std::string const& name, DiscreteFunction<GB,VT,TP> const& discreteFct)
DiscreteFunction const& discreteFct) : FileWriterInterface(name)
: FileWriterInterface(baseName)
, discreteFct_(discreteFct) , discreteFct_(discreteFct)
, animation_(false) , animation_(false)
{ {
Parameters::get(baseName + "->ParaView animation", animation_); Parameters::get(name + "->ParaView animation", animation_);
int m = Parameters::get<int>(baseName + "->ParaView mode").value_or(0); int m = Parameters::get<int>(name + "->ParaView mode").value_or(0);
mode_ = (m == 0 ? Dune::VTK::ascii : Dune::VTK::appendedraw); mode_ = (m == 0 ? Dune::VTK::ascii : Dune::VTK::appendedraw);
init(baseName, ValueCategory_t<Range>{}); init(name, ValueCategory_t<Range>{});
} }
template <class ValueCat> template <class ValueCat>
void init(std::string const& baseName, ValueCat) void init(std::string const& baseName, ValueCat)
{ {
int subSampling = Parameters::get<int>(baseName + "->subsampling").value_or(0); auto subSampling = Parameters::get<int>(baseName + "->subsampling");
if (subSampling > 0) if (subSampling)
vtkWriter_ = std::make_shared<Dune::SubsamplingVTKWriter<GridView>>(gridView(), subSampling); vtkWriter_ = std::make_shared<Dune::SubsamplingVTKWriter<GridView>>(gridView(), subSampling.value());
else else
vtkWriter_ = std::make_shared<Dune::VTKWriter<GridView>>(gridView()); vtkWriter_ = std::make_shared<Dune::VTKWriter<GridView>>(gridView());
...@@ -109,7 +111,7 @@ namespace AMDiS ...@@ -109,7 +111,7 @@ namespace AMDiS
} }
private: private:
DiscreteFunction discreteFct_; DiscreteFunction<GB,VT,TP> discreteFct_;
std::shared_ptr<Dune::VTKWriter<GridView>> vtkWriter_; std::shared_ptr<Dune::VTKWriter<GridView>> vtkWriter_;
std::shared_ptr<Dune::VTKSequenceWriter<GridView>> vtkSeqWriter_; std::shared_ptr<Dune::VTKSequenceWriter<GridView>> vtkSeqWriter_;
...@@ -122,12 +124,12 @@ namespace AMDiS ...@@ -122,12 +124,12 @@ namespace AMDiS
}; };
template <class GlobalBasis, class Range, class TreePath> template <class GlobalBasis, class ValueType, class TreePath>
std::shared_ptr<FileWriter<GlobalBasis,Range,TreePath>> std::shared_ptr<FileWriter<GlobalBasis,ValueType,TreePath>>
makeFileWriterPtr(std::string baseName, makeFileWriterPtr(std::string const& name,
DiscreteFunction<GlobalBasis,Range,TreePath> const& discreteFct) DiscreteFunction<GlobalBasis,ValueType,TreePath> const& discreteFct)
{ {
return std::make_shared<FileWriter<GlobalBasis,Range,TreePath>>(baseName, discreteFct); return std::make_shared<FileWriter<GlobalBasis,ValueType,TreePath>>(name, discreteFct);
} }
} // end namespace AMDiS } // end namespace AMDiS
...@@ -6,19 +6,24 @@ ...@@ -6,19 +6,24 @@
namespace AMDiS namespace AMDiS
{ {
/// A mutable view on the subspace of a DOFVector, \relates DiscreteFunction /// A mutable view on the subspace of a DOFVector, \relates DiscreteFunction
template <class GlobalBasisType, class RangeType, class TreePathType> template <class GB, class VT, class TP>
class DOFVectorView class DOFVectorView
: public DiscreteFunction<GlobalBasisType, RangeType, TreePathType> : public DiscreteFunction<GB, VT, TP>
{ {
using Self = DOFVectorView; using Self = DOFVectorView;
using Super = DiscreteFunction<GlobalBasisType, RangeType, TreePathType>; using Super = DiscreteFunction<GB, VT, TP>;
using GlobalBasis = GlobalBasisType; using GlobalBasis = GB;
using TreePath = TreePathType; using TreePath = TP;
public: public:
/// Constructor forwards to the treePath constructor, with empty TreePath
DOFVectorView(DOFVector<GB,VT>& dofVector)
: DOFVectorView{dofVector, Dune::TypeTree::hybridTreePath()}
{}
/// Constructor. Stores a pointer to the mutable `dofvector`. /// Constructor. Stores a pointer to the mutable `dofvector`.
DOFVectorView(DOFVector<GlobalBasis,RangeType>& dofVector, TreePath const& treePath) DOFVectorView(DOFVector<GB,VT>& dofVector, TP const& treePath)
: Super(dofVector, treePath) : Super(dofVector, treePath)
, mutableDofVector_(&dofVector) , mutableDofVector_(&dofVector)
{} {}
...@@ -26,6 +31,13 @@ namespace AMDiS ...@@ -26,6 +31,13 @@ namespace AMDiS
public: public:
/// \brief Interpolation of GridFunction to DOFVector, assuming that there is no /// \brief Interpolation of GridFunction to DOFVector, assuming that there is no
/// reference to this DOFVector in the expression. /// reference to this DOFVector in the expression.
/**
* **Example:**
* ```
* auto v = makeDOFVectorView(prob.getSolutionVector(),0);
* v.interpolate([](auto const& x) { return x[0]; });
* ```
**/
template <class Expr> template <class Expr>
void interpolate_noalias(Expr&& expr) void interpolate_noalias(Expr&& expr)
{ {
...@@ -34,15 +46,25 @@ namespace AMDiS ...@@ -34,15 +46,25 @@ namespace AMDiS
auto&& gridFct = makeGridFunction(std::forward<Expr>(expr), basis.gridView()); auto&& gridFct = makeGridFunction(std::forward<Expr>(expr), basis.gridView());
Dune::Functions::interpolate(basis, treePath, coefficients(), std::forward<decltype(gridFct)>(gridFct)); Dune::Functions::interpolate(basis, treePath, coefficients(),
std::forward<decltype(gridFct)>(gridFct));
} }
/// Interpolation of GridFunction to DOFVector /// \brief Interpolation of GridFunction to DOFVector
/**
* **Example:**
* ```
* auto v = makeDOFVectorView(prob.getSolutionVector(),0);
* v.interpolate(v + [](auto const& x) { return x[0]; });
* ```
* Allows to have a reference to the DOFVector in the expression, e.g. as
* \ref DiscreteFunction or \ref gradientAtQP() of a DiscreteFunction.
**/
template <class Expr> template <class Expr>
void interpolate(Expr&& expr) void interpolate(Expr&& expr)
{ {
// create temporary copy of data // create temporary copy of data
DOFVector<GlobalBasis,RangeType> tmp(coefficients()); DOFVector<GB,VT> tmp(coefficients());
Self tmpView{tmp, this->treePath()}; Self tmpView{tmp, this->treePath()};
tmpView.interpolate_noalias(std::forward<Expr>(expr)); tmpView.interpolate_noalias(std::forward<Expr>(expr));
...@@ -58,6 +80,7 @@ namespace AMDiS ...@@ -58,6 +80,7 @@ namespace AMDiS
return *this; return *this;
} }
/// \brief interpolate `(*this) + expr` to DOFVector
template <class Expr> template <class Expr>
DOFVectorView& operator+=(Expr&& expr) DOFVectorView& operator+=(Expr&& expr)
{ {
...@@ -65,6 +88,7 @@ namespace AMDiS ...@@ -65,6 +88,7 @@ namespace AMDiS
return *this; return *this;
} }
/// \brief interpolate `(*this) - expr` to DOFVector
template <class Expr> template <class Expr>
DOFVectorView& operator-=(Expr&& expr) DOFVectorView& operator-=(Expr&& expr)
{ {
...@@ -72,31 +96,37 @@ namespace AMDiS ...@@ -72,31 +96,37 @@ namespace AMDiS
return *this; return *this;
} }
/// Return the mutable DOFVector /// Return the mutable DOFVector
DOFVector<GlobalBasis,RangeType>& coefficients() { return *mutableDofVector_; } DOFVector<GB,VT>& coefficients() { return *mutableDofVector_; }
/// Return the const DOFVector /// Return the const DOFVector
using Super::coefficients; using Super::coefficients;
protected: protected:
DOFVector<GlobalBasis,RangeType>* mutableDofVector_; DOFVector<GB,VT>* mutableDofVector_;
}; };
#if DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
// Deduction guide for DOFVectorView class
template <class GlobalBasis, class ValueType>
DOFVectorView(DOFVector<GlobalBasis, ValueType>& dofVector)
-> DOFVectorView<GlobalBasis, ValueType, Dune::TypeTree::HybridTreePath<>>;
#endif
/// A Generator for a mutable \ref DOFVectorView /// A Generator for a mutable \ref DOFVectorView
template <class GlobalBasis, class RangeType, class TreePath> template <class GlobalBasis, class ValueType, class TreePath>
auto makeDOFVectorView(DOFVector<GlobalBasis, RangeType>& dofVector, TreePath const& treePath) auto makeDOFVectorView(DOFVector<GlobalBasis, ValueType>& dofVector, TreePath const& treePath)
{ {
return DOFVectorView<GlobalBasis, RangeType, TreePath>{dofVector, treePath}; return DOFVectorView<GlobalBasis, ValueType, TreePath>{dofVector, treePath};
} }
/// A Generator for a mutable \ref DOFVectorView /// A Generator for a mutable \ref DOFVectorView
template <class GlobalBasis, class RangeType> template <class GlobalBasis, class ValueType>
auto makeDOFVectorView(DOFVector<GlobalBasis, RangeType>& dofVector) auto makeDOFVectorView(DOFVector<GlobalBasis, ValueType>& dofVector)
{ {
auto treePath = Dune::TypeTree::hybridTreePath(); auto treePath = Dune::TypeTree::hybridTreePath();
return DOFVectorView<GlobalBasis, RangeType, decltype(treePath)>{dofVector, treePath}; return DOFVectorView<GlobalBasis, ValueType, Dune::TypeTree::HybridTreePath<>>{dofVector, treePath};
} }
} // end namespace AMDiS } // end namespace AMDiS
...@@ -17,13 +17,19 @@ namespace AMDiS ...@@ -17,13 +17,19 @@ namespace AMDiS
/// \brief A view on a subspace of a \ref DOFVector /// \brief A view on a subspace of a \ref DOFVector
/** /**
* \ingroup GridFunctions * \ingroup GridFunctions
*
* \tparam GB GlobalBasis type that models \ref Dune::Functions::Concept::GlobalBasis
* \tparam VT Coefficient type of the DOFVector
* \tparam TP TreePath type a realization of \ref Dune::TypeTree::HybridTreePath
**/ **/
template <class GlobalBasisType, class RangeType, class TreePathType> template <class GB, class VT, class TP>
class DiscreteFunction class DiscreteFunction
{ {
public: static_assert(std::is_arithmetic<VT>::value, "");
using GlobalBasis = GlobalBasisType;
using TreePath = TreePathType; private:
using GlobalBasis = GB;
using TreePath = TP;
using Tree = typename GlobalBasis::LocalView::Tree; using Tree = typename GlobalBasis::LocalView::Tree;
using SubTree = typename Dune::TypeTree::ChildForTreePath<Tree, TreePath>; using SubTree = typename Dune::TypeTree::ChildForTreePath<Tree, TreePath>;
...@@ -32,159 +38,39 @@ namespace AMDiS ...@@ -32,159 +38,39 @@ namespace AMDiS
using GridView = typename GlobalBasis::GridView; using GridView = typename GlobalBasis::GridView;
using EntitySet = Dune::Functions::GridViewEntitySet<GridView, 0>; using EntitySet = Dune::Functions::GridViewEntitySet<GridView, 0>;
public:
/// Global coordinates of the EntitySet
using Domain = typename EntitySet::GlobalCoordinate; using Domain = typename EntitySet::GlobalCoordinate;
using Range = RangeType_t<SubTree>;
static_assert(std::is_arithmetic<RangeType>::value, "");
// Don't know how to determine Range with non-trivial RangeType
using RawSignature = typename Dune::Functions::SignatureTraits<Range(Domain)>::RawSignature;
using DerivativeTraits = Dune::Functions::DefaultDerivativeTraits<RawSignature>;
using DerivativeRange = typename DerivativeTraits::Range;
using LocalDomain = typename EntitySet::LocalCoordinate; /// Range type of this DiscreteFunction
using Element = typename EntitySet::Element; using Range = RangeType_t<SubTree,VT>;
using Geometry = typename Element::Geometry;
/// \brief This GridFunction has no derivative function, it can be created
/// by \ref DiscreteGridFunction.
enum { hasDerivative = false }; enum { hasDerivative = false };
public: // a local view on the gradients public:
/// A LocalFunction representing the derivative of the DOFVector on a bound element
/// A LocalFunction representing the derivative of the DOFVector class GradientLocalFunction;
class GradientLocalFunction
{
public:
using Domain = LocalDomain;
using Range = DerivativeRange;
enum { hasDerivative = false };
private:
using LocalView = typename GlobalBasis::LocalView;
public:
GradientLocalFunction(DiscreteFunction const& globalFunction)
: globalFunction_(&globalFunction)
, localView_(globalFunction_->basis().localView())
, subTree_(&child(localView_.tree(), globalFunction_->treePath()))
{}
void bind(Element const& element)
{
localView_.bind(element);
geometry_.emplace(element.geometry());
bound_ = true;
}
void unbind()
{
localView_.unbind();
geometry_.reset();
bound_ = false;
}
/// Evaluate Gradient at bound element in local coordinates
Range operator()(Domain const& x) const;
friend int order(GradientLocalFunction const& self)
{
assert( self.bound_ );
return std::max(0, polynomialDegree(*self.subTree_)-1);
}
/// Return the bound element
Element const& localContext() const
{
assert( bound_ );
return localView_.element();
}
private:
DiscreteFunction const* globalFunction_;
LocalView localView_;
SubTree const* subTree_;
Dune::Std::optional<Geometry> geometry_;
bool bound_ = false;
};
public: // a local view on the values
/// A LocalFunction, i.e., an element local view on the DOFVector
class LocalFunction
{
public:
using Domain = typename DiscreteFunction::LocalDomain;
using Range = typename DiscreteFunction::Range;
enum { hasDerivative = true };
private:
using LocalView = typename GlobalBasis::LocalView;
public:
LocalFunction(DiscreteFunction const& globalFunction)
: globalFunction_(&globalFunction)
, localView_(globalFunction_->basis().localView())
, subTree_(&child(localView_.tree(), globalFunction_->treePath()))
{}
void bind(Element const& element)
{
localView_.bind(element);
bound_ = true;
}
void unbind()
{
localView_.unbind();
bound_ = false;
}
/// Evaluate LocalFunction at bound element in local coordinates
Range operator()(Domain const& x) const;
/// \brief Create a LocalFunction representing the gradient. \relates GradientLocalFunction
friend GradientLocalFunction derivative(LocalFunction const& localFunction)
{
static_assert(isValidRange<DerivativeTraits>(),
"Derivative of DOFVector not defined.");
return GradientLocalFunction{*localFunction.globalFunction_};
}
friend int order(LocalFunction const& self)
{
assert( self.bound_ );
return polynomialDegree(*self.subTree_);
}
/// Return the bound element
Element const& localContext() const
{
assert( bound_ );
return localView_.element();
}
private:
DiscreteFunction const* globalFunction_;
LocalView localView_;
SubTree const* subTree_;
bool bound_ = false;
};
/// A LocalFunction representign the value the DOFVector on a bound element
class LocalFunction;
public: public:
/// Constructor forwards to the treePath constructor, with empty TreePath
DiscreteFunction(DOFVector<GB,VT> const& dofVector)
: DiscreteFunction{dofVector, Dune::TypeTree::hybridTreePath()}
{}
/// Constructor. Stores a pointer to the dofVector and a copy of the treePath. /// Constructor. Stores a pointer to the dofVector and a copy of the treePath.
DiscreteFunction(DOFVector<GlobalBasis,RangeType> const& dofVector, TreePath const& treePath) DiscreteFunction(DOFVector<GB,VT> const& dofVector, TP const& treePath)
: dofVector_(&dofVector) : dofVector_(&dofVector)
, treePath_(treePath) , treePath_(treePath)
, entitySet_(dofVector.basis().gridView()) , entitySet_(dofVector.basis().gridView())
, nodeToRangeEntry_(Dune::Functions::makeDefaultNodeToRangeMap(dofVector.basis(), treePath)) , nodeToRangeEntry_(Dune::Functions::makeDefaultNodeToRangeMap(dofVector.basis(), treePath))
{} {}
/// Evaluate DiscreteFunction in global coordinates. NOTE: expensive /// \brief Evaluate DiscreteFunction in global coordinates. NOTE: expensive
Range operator()(Domain const& x) const; Range operator()(Domain const& x) const;
/// \brief Create a local function for this view on the DOFVector. \relates LocalFunction /// \brief Create a local function for this view on the DOFVector. \relates LocalFunction
...@@ -193,51 +79,59 @@ namespace AMDiS ...@@ -193,51 +79,59 @@ namespace AMDiS
return LocalFunction{self}; return LocalFunction{self};
} }
/// \brief Return a \ref Dune::Functions::GridViewEntitySet
EntitySet const& entitySet() const EntitySet const& entitySet() const
{ {
return entitySet_; return entitySet_;
} }
public: public:
/// Return global basis /// \brief Return global basis bound to the DOFVector
GlobalBasis const& basis() const GlobalBasis const& basis() const
{ {
return dofVector_->basis(); return dofVector_->basis();
} }
/// Return treePath associated with this view /// \brief Return treePath associated with this discrete function
TreePath const& treePath() const TreePath const& treePath() const
{ {
return treePath_; return treePath_;
} }
/// Return const coefficient vector /// \brief Return const coefficient vector
DOFVector<GlobalBasis,RangeType> const& coefficients() const DOFVector<GB,VT> const& coefficients() const
{ {
return *dofVector_; return *dofVector_;
} }
protected: protected:
DOFVector<GlobalBasis,RangeType> const* dofVector_; DOFVector<GB,VT> const* dofVector_;
TreePath const treePath_; TreePath treePath_;
EntitySet entitySet_; EntitySet entitySet_;
NodeToRangeEntry nodeToRangeEntry_; NodeToRangeEntry nodeToRangeEntry_;
}; };
#if DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
// Deduction guide for DiscreteFunction class
template <class GlobalBasis, class ValueType>
DiscreteFunction(DOFVector<GlobalBasis, ValueType> const& dofVector)
-> DiscreteFunction<GlobalBasis, ValueType, Dune::TypeTree::HybridTreePath<>>;
#endif
/// A Generator for a \ref DiscreteFunction /// A Generator for a \ref DiscreteFunction
template <class GlobalBasis, class RangeType, class TreePath> template <class GlobalBasis, class ValueType, class TreePath>
auto makeDiscreteFunction(DOFVector<GlobalBasis, RangeType> const& dofVector, TreePath const& treePath) auto makeDiscreteFunction(DOFVector<GlobalBasis, ValueType> const& dofVector, TreePath const& treePath)
{ {
return DiscreteFunction<GlobalBasis, RangeType, TreePath>{dofVector, treePath}; return DiscreteFunction<GlobalBasis, ValueType, TreePath>{dofVector, treePath};
} }
/// A Generator for a \ref DiscreteFunction /// A Generator for a \ref DiscreteFunction
template <class GlobalBasis, <