Commit a4aeae1d authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

renamed DOFVectorConstView into DiscreteFunction and added some more interpolation methods

parent c27b2e73
Pipeline #1345 passed with stage
in 20 minutes and 37 seconds
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include <amdis/Initfile.hpp> #include <amdis/Initfile.hpp>
#include <amdis/common/Size.hpp> #include <amdis/common/Size.hpp>
#include <amdis/common/ValueCategory.hpp> #include <amdis/common/ValueCategory.hpp>
#include <amdis/gridfunctions/DOFVectorView.hpp> #include <amdis/gridfunctions/DiscreteFunction.hpp>
#include <amdis/io/FileWriterInterface.hpp> #include <amdis/io/FileWriterInterface.hpp>
#include <amdis/utility/Filesystem.hpp> #include <amdis/utility/Filesystem.hpp>
...@@ -49,8 +49,8 @@ namespace AMDiS ...@@ -49,8 +49,8 @@ namespace AMDiS
{ {
private: // typedefs and static constants private: // typedefs and static constants
using GridView = typename GlobalBasis::GridView; using GridView = typename GlobalBasis::GridView;
using Vector = DOFVectorConstView<GlobalBasis,RangeType,TreePath>; using DiscreteFunction = AMDiS::DiscreteFunction<GlobalBasis,RangeType,TreePath>;
using Range = typename Vector::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;
...@@ -61,9 +61,9 @@ namespace AMDiS ...@@ -61,9 +61,9 @@ namespace AMDiS
public: public:
/// Constructor. /// Constructor.
FileWriter(std::string const& baseName, FileWriter(std::string const& baseName,
Vector const& dofvector) DiscreteFunction const& discreteFct)
: FileWriterInterface(baseName) : FileWriterInterface(baseName)
, dofvector_(dofvector) , discreteFct_(discreteFct)
, animation_(false) , animation_(false)
{ {
Parameters::get(baseName + "->ParaView animation", animation_); Parameters::get(baseName + "->ParaView animation", animation_);
...@@ -86,7 +86,7 @@ namespace AMDiS ...@@ -86,7 +86,7 @@ namespace AMDiS
if (animation_) if (animation_)
vtkSeqWriter_ = std::make_shared<Dune::VTKSequenceWriter<GridView>>(vtkWriter_, filename_, dir_, ""); vtkSeqWriter_ = std::make_shared<Dune::VTKSequenceWriter<GridView>>(vtkWriter_, filename_, dir_, "");
vtkWriter_->addVertexData(dofvector_, Dune::VTK::FieldInfo(name_, VTKFieldType<Range>, VTKFieldSize<Range>)); vtkWriter_->addVertexData(discreteFct_, Dune::VTK::FieldInfo(name_, VTKFieldType<Range>, VTKFieldSize<Range>));
} }
void init(std::string const&, tag::unknown) {} void init(std::string const&, tag::unknown) {}
...@@ -105,11 +105,11 @@ namespace AMDiS ...@@ -105,11 +105,11 @@ namespace AMDiS
protected: protected:
GridView const& gridView() const GridView const& gridView() const
{ {
return dofvector_.basis().gridView(); return discreteFct_.basis().gridView();
} }
private: private:
Vector dofvector_; DiscreteFunction 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_;
...@@ -125,9 +125,9 @@ namespace AMDiS ...@@ -125,9 +125,9 @@ namespace AMDiS
template <class GlobalBasis, class Range, class TreePath> template <class GlobalBasis, class Range, class TreePath>
std::shared_ptr<FileWriter<GlobalBasis,Range,TreePath>> std::shared_ptr<FileWriter<GlobalBasis,Range,TreePath>>
makeFileWriterPtr(std::string baseName, makeFileWriterPtr(std::string baseName,
DOFVectorConstView<GlobalBasis,Range,TreePath> const& dofvector) DiscreteFunction<GlobalBasis,Range,TreePath> const& discreteFct)
{ {
return std::make_shared<FileWriter<GlobalBasis,Range,TreePath>>(baseName, dofvector); return std::make_shared<FileWriter<GlobalBasis,Range,TreePath>>(baseName, discreteFct);
} }
} // end namespace AMDiS } // end namespace AMDiS
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <amdis/common/Utility.hpp> #include <amdis/common/Utility.hpp>
#include <amdis/GridFunctions.hpp> #include <amdis/GridFunctions.hpp>
#include <amdis/gridfunctions/DiscreteFunction.hpp>
#include <amdis/gridfunctions/DOFVectorView.hpp> #include <amdis/gridfunctions/DOFVectorView.hpp>
#include <amdis/io/FileWriterInterface.hpp> #include <amdis/io/FileWriterInterface.hpp>
...@@ -198,7 +199,7 @@ namespace AMDiS ...@@ -198,7 +199,7 @@ namespace AMDiS
auto getSolution(TreePath const& path = {}) const auto getSolution(TreePath const& path = {}) const
{ {
auto&& tp = makeTreePath(path); auto&& tp = makeTreePath(path);
return makeDOFVectorView(*solution_, tp); return makeDiscreteFunction(*solution_, tp);
} }
......
...@@ -5,8 +5,9 @@ install(FILES ...@@ -5,8 +5,9 @@ install(FILES
ConstantGridFunction.hpp ConstantGridFunction.hpp
CoordsGridFunction.hpp CoordsGridFunction.hpp
DerivativeGridFunction.hpp DerivativeGridFunction.hpp
DiscreteFunction.hpp
DiscreteFunction.inc.hpp
DOFVectorView.hpp DOFVectorView.hpp
DOFVectorView.inc.hpp
FunctorGridFunction.hpp FunctorGridFunction.hpp
GridFunctionConcepts.hpp GridFunctionConcepts.hpp
Integrate.hpp Integrate.hpp
......
#pragma once #pragma once
#include <vector>
#include <dune/common/std/optional.hh>
#include <dune/functions/common/defaultderivativetraits.hh>
#include <dune/functions/common/treedata.hh>
#include <dune/functions/functionspacebases/defaultnodetorangemap.hh>
#include <dune/functions/functionspacebases/flatvectorview.hh>
#include <dune/functions/gridfunctions/gridviewentityset.hh>
#include <dune/typetree/childextraction.hh>
#include <amdis/GridFunctions.hpp> #include <amdis/GridFunctions.hpp>
#include <amdis/utility/FiniteElementType.hpp> #include <amdis/gridfunctions/DiscreteFunction.hpp>
namespace AMDiS namespace AMDiS
{ {
/** /// A mutable view on the subspace of a DOFVector, \relates DiscreteFunction
* \addtogroup GridFunctions
* @{
**/
template <class GlobalBasisType, class RangeType, class TreePathType> template <class GlobalBasisType, class RangeType, class TreePathType>
class DOFVectorConstView class DOFVectorView
: public DiscreteFunction<GlobalBasisType, RangeType, TreePathType>
{ {
public: using Self = DOFVectorView;
using Super = DiscreteFunction<GlobalBasisType, RangeType, TreePathType>;
using GlobalBasis = GlobalBasisType; using GlobalBasis = GlobalBasisType;
using TreePath = TreePathType; using TreePath = TreePathType;
using Tree = typename GlobalBasis::LocalView::Tree;
using SubTree = typename Dune::TypeTree::ChildForTreePath<Tree, TreePath>;
using NodeToRangeEntry = Dune::Functions::DefaultNodeToRangeMap<SubTree>;
using GridView = typename GlobalBasis::GridView;
using EntitySet = Dune::Functions::GridViewEntitySet<GridView, 0>;
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;
using Element = typename EntitySet::Element;
using Geometry = typename Element::Geometry;
enum { hasDerivative = false };
public: // a local view on the gradients
/// A LocalFunction representing the derivative of the DOFVector
class GradientLocalFunction
{
public:
using Domain = LocalDomain;
using Range = DerivativeRange;
enum { hasDerivative = false };
private:
using LocalView = typename GlobalBasis::LocalView;
template <class LeafNode>
using LocalBasisJacobian = typename LeafNode::FiniteElement::Traits::LocalBasisType::Traits::JacobianType;
template <class Node>
using NodeData = typename std::vector<LocalBasisJacobian<Node>>;
using ReferenceGradientContainer = Dune::Functions::TreeData<SubTree, NodeData, true>;
public:
GradientLocalFunction(DOFVectorConstView const& globalFunction)
: globalFunction_(&globalFunction)
, localView_(globalFunction_->basis().localView())
, subTree_(&Dune::TypeTree::child(localView_.tree(), globalFunction_->treePath()))
{
referenceGradientContainer_.init(*subTree_);
}
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:
DOFVectorConstView const* globalFunction_;
LocalView localView_;
SubTree const* subTree_;
mutable ReferenceGradientContainer referenceGradientContainer_;
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 DOFVectorConstView::LocalDomain;
using Range = typename DOFVectorConstView::Range;
enum { hasDerivative = true };
private:
using LocalView = typename GlobalBasis::LocalView;
template <class LeafNode>
using LocalBasisRange = RangeType_t<LeafNode>;
// = typename LeafNode::FiniteElement::Traits::LocalBasisType::Traits::RangeType;
template <class Node>
using NodeData = typename std::vector<LocalBasisRange<Node>>;
using ShapeFunctionValueContainer = Dune::Functions::TreeData<SubTree, NodeData, true>;
public:
LocalFunction(DOFVectorConstView const& globalFunction)
: globalFunction_(&globalFunction)
, localView_(globalFunction_->basis().localView())
, subTree_(&Dune::TypeTree::child(localView_.tree(), globalFunction_->treePath()))
{
shapeFunctionValueContainer_.init(*subTree_);
}
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:
DOFVectorConstView const* globalFunction_;
LocalView localView_;
SubTree const* subTree_;
mutable ShapeFunctionValueContainer shapeFunctionValueContainer_;
bool bound_ = false;
};
public: public:
/// Constructor. Stores a pointer to the dofVector and a copy of the treePath. /// Constructor. Stores a pointer to the mutable `dofvector`.
DOFVectorConstView(DOFVector<GlobalBasis,RangeType> const& dofVector, TreePath const& treePath) DOFVectorView(DOFVector<GlobalBasis,RangeType>& dofVector, TreePath const& treePath)
: dofVector_(&dofVector) : Super(dofVector, treePath)
, treePath_(treePath) , mutableDofVector_(&dofVector)
, entitySet_(dofVector.basis().gridView())
, nodeToRangeEntry_(Dune::Functions::makeDefaultNodeToRangeMap(dofVector.basis(), treePath))
{} {}
/// Evaluate the view on this DOFVector in global coordinates public:
Range operator()(Domain const& x) const /// \brief Interpolation of GridFunction to DOFVector, assuming that there is no
/// reference to this DOFVector in the expression.
template <class Expr>
void interpolate_noalias(Expr&& expr)
{ {
error_exit("Not implemented."); auto const& basis = this->basis();
return Range(0); auto const& treePath = this->treePath();
}
/// \brief Create a local function for this view on the DOFVector. \relates LocalFunction auto&& gridFct = makeGridFunction(std::forward<Expr>(expr), basis.gridView());
friend LocalFunction localFunction(DOFVectorConstView const& self)
{
return LocalFunction{self};
}
EntitySet const& entitySet() const Dune::Functions::interpolate(basis, treePath, coefficients(), std::forward<decltype(gridFct)>(gridFct));
{
return entitySet_;
} }
public: /// Interpolation of GridFunction to DOFVector
/// Return global basis template <class Expr>
GlobalBasis const& basis() const void interpolate(Expr&& expr)
{ {
return dofVector_->basis(); // create temporary copy of data
} DOFVector<GlobalBasis,RangeType> tmp(coefficients());
Self tmpView{tmp, this->treePath()};
tmpView.interpolate_noalias(std::forward<Expr>(expr));
/// Return treePath associated with this view // move data from temporary vector into stored DOFVector
TreePath const& treePath() const coefficients().vector() = std::move(tmp.vector());
{
return treePath_;
} }
/// Return const coefficient vector /// \brief Interpolation of GridFunction to DOFVector, alias to \ref interpolate()
DOFVector<GlobalBasis,RangeType> const& coefficients() const template <class Expr>
DOFVectorView& operator<<(Expr&& expr)
{ {
return *dofVector_; interpolate(expr);
return *this;
} }
protected:
DOFVector<GlobalBasis,RangeType> const* dofVector_;
TreePath const treePath_;
EntitySet entitySet_;
NodeToRangeEntry nodeToRangeEntry_;
};
// A mutable version of DOFVectorView
template <class GlobalBasisType, class RangeType, class TreePathType>
class DOFVectorMutableView
: public DOFVectorConstView<GlobalBasisType, RangeType, TreePathType>
{
using Super = DOFVectorConstView<GlobalBasisType, RangeType, TreePathType>;
using GlobalBasis = GlobalBasisType;
using TreePath = TreePathType;
public:
/// Constructor. Stores a pointer to the mutable `dofvector`.
DOFVectorMutableView(DOFVector<GlobalBasis,RangeType>& dofVector, TreePath const& treePath)
: Super(dofVector, treePath)
, mutableDofVector_(&dofVector)
{}
public:
/// Interpolation of GridFunction to DOFVector
template <class Expr> template <class Expr>
DOFVectorMutableView& interpolate(Expr&& expr) DOFVectorView& operator+=(Expr&& expr)
{ {
auto const& basis = Super::basis(); interpolate((*this) + expr);
auto const& treePath = Super::treePath();
auto&& gridFct = makeGridFunction(std::forward<Expr>(expr), basis.gridView());
DOFVector<GlobalBasis,RangeType> tmp(*mutableDofVector_);
Dune::Functions::interpolate(basis, treePath, tmp, std::forward<decltype(gridFct)>(gridFct));
// move data from temporary vector into stored DOFVector
mutableDofVector_->vector() = std::move(tmp.vector());
return *this; return *this;
} }
template <class Expr> template <class Expr>
DOFVectorMutableView& operator<<(Expr&& expr) DOFVectorView& operator-=(Expr&& expr)
{ {
return interpolate(expr); interpolate((*this) - expr);
return *this;
} }
...@@ -307,42 +83,20 @@ namespace AMDiS ...@@ -307,42 +83,20 @@ namespace AMDiS
DOFVector<GlobalBasis,RangeType>* mutableDofVector_; DOFVector<GlobalBasis,RangeType>* mutableDofVector_;
}; };
/** @} **/
/// A Generator for a mutable \ref DOFVectorView
#ifndef DOXYGEN
// A Generator for a const \ref DOFVectorView.
template <class GlobalBasis, class RangeType, class TreePath>
auto makeDOFVectorView(DOFVector<GlobalBasis, RangeType> const& dofVector, TreePath const& treePath)
{
return DOFVectorConstView<GlobalBasis, RangeType, TreePath>{dofVector, treePath};
}
// A Generator for a mutable \ref DOFVectorView.
template <class GlobalBasis, class RangeType, class TreePath> template <class GlobalBasis, class RangeType, class TreePath>
auto makeDOFVectorView(DOFVector<GlobalBasis, RangeType>& dofVector, TreePath const& treePath) auto makeDOFVectorView(DOFVector<GlobalBasis, RangeType>& dofVector, TreePath const& treePath)
{ {
return DOFVectorMutableView<GlobalBasis, RangeType, TreePath>{dofVector, treePath}; return DOFVectorView<GlobalBasis, RangeType, TreePath>{dofVector, treePath};
}
// A Generator for a const \ref DOFVectorView.
template <class GlobalBasis, class RangeType>
auto makeDOFVectorView(DOFVector<GlobalBasis, RangeType> const& dofVector)
{
auto treePath = Dune::TypeTree::hybridTreePath();
return DOFVectorConstView<GlobalBasis, RangeType, decltype(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 RangeType>
auto makeDOFVectorView(DOFVector<GlobalBasis, RangeType>& dofVector) auto makeDOFVectorView(DOFVector<GlobalBasis, RangeType>& dofVector)
{ {
auto treePath = Dune::TypeTree::hybridTreePath(); auto treePath = Dune::TypeTree::hybridTreePath();
return DOFVectorMutableView<GlobalBasis, RangeType, decltype(treePath)>{dofVector, treePath}; return DOFVectorView<GlobalBasis, RangeType, decltype(treePath)>{dofVector, treePath};
} }
#endif
} // end namespace AMDiS } // end namespace AMDiS
#include "DOFVectorView.inc.hpp"
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <type_traits> #include <type_traits>
#include <dune/functions/common/defaultderivativetraits.hh> #include <dune/functions/common/defaultderivativetraits.hh>
#include <dune/grid/utility/hierarchicsearch.hh>
#include <amdis/gridfunctions/GridFunctionConcepts.hpp> #include <amdis/gridfunctions/GridFunctionConcepts.hpp>
...@@ -52,11 +53,22 @@ namespace AMDiS ...@@ -52,11 +53,22 @@ namespace AMDiS
static_assert(isValidRange<DerivativeTraits>(), "Derivative of GridFunction not defined"); static_assert(isValidRange<DerivativeTraits>(), "Derivative of GridFunction not defined");
} }
/// NOTE: no global derivative available /// Evaluate derivative in global coordinates. NOTE: expensive
Range operator()(Domain const& x) const Range operator()(Domain const& x) const
{ {
error_exit("Not implemented"); auto gv = entitySet().gridView();
return Range(0);
using GridView = decltype(gv);
using Grid = typename GridView::Grid;
using IS = typename GridView::IndexSet;
Dune::HierarchicSearch<Grid,IS> hsearch{gv.grid(), gv.indexSet()};
auto element = hsearch.findEntity(x);
auto geometry = element.geometry();
auto localFct = derivative(localFunction(gridFct_));
localFct.bind(element);
return localFct(geometry.local(x));
} }
/// Return the derivative-localFunction of the GridFunction. /// Return the derivative-localFunction of the GridFunction.
......