Liebe Gitlab-Nutzerin, lieber Gitlab-Nutzer,
es ist nun möglich sich mittels des ZIH-Logins/LDAP an unserem Dienst anzumelden. Die Konten der externen Nutzer:innen sind über den Reiter "Standard" erreichbar.
Die Administratoren


Dear Gitlab user,
it is now possible to log in to our service using the ZIH login/LDAP. The accounts of external users can be accessed via the "Standard" tab.
The administrators

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

add extended TreeContainer implementation and replace TreeData

parent 1f3895e9
......@@ -57,8 +57,6 @@ namespace AMDiS
, colBasis_(colBasis)
, updatePattern_(true)
{
operators_.init(*rowBasis_, *colBasis_);
auto const rowSize = rowBasis_->localView().maxSize();
auto const colSize = colBasis_->localView().maxSize();
elementMatrix_.resize(rowSize, colSize);
......
......@@ -20,13 +20,15 @@ addOperator(ContextTag contextTag, Expr const& expr,
static_assert( Concepts::PreTreePath<ColTreePath>,
"col must be a valid treepath, or an integer/index-constant");
auto i = child(this->rowBasis()->localView().tree(), makeTreePath(row));
auto j = child(this->colBasis()->localView().tree(), makeTreePath(col));
auto i = makeTreePath(row);
auto node_i = child(this->rowBasis()->localView().tree(), i);
auto j = makeTreePath(col);
auto node_j = child(this->colBasis()->localView().tree(), j);
using LocalContext = typename ContextTag::type;
using Tr = DefaultAssemblerTraits<LocalContext, ElementMatrix>;
auto op = makeLocalOperator<LocalContext>(expr, this->rowBasis()->gridView());
auto localAssembler = makeUniquePtr(makeAssembler<Tr>(std::move(op), i, j));
auto localAssembler = makeUniquePtr(makeAssembler<Tr>(std::move(op), node_i, node_j));
operators_[i][j].push(contextTag, std::move(localAssembler));
updatePattern_ = true;
......@@ -47,9 +49,9 @@ assemble(RowLocalView const& rowLocalView, ColLocalView const& colLocalView)
auto const& element = rowLocalView.element();
auto geometry = element.geometry();
for_each_node(rowLocalView.tree(), [&](auto const& rowNode, auto) {
for_each_node(colLocalView.tree(), [&](auto const& colNode, auto) {
auto& matOp = operators_[rowNode][colNode];
for_each_node(rowLocalView.tree(), [&](auto const& rowNode, auto rowTp) {
for_each_node(colLocalView.tree(), [&](auto const& colNode, auto colTp) {
auto& matOp = operators_[rowTp][colTp];
if (matOp) {
matOp.bind(element, geometry);
assembleOperators(gv, element, matOp, makeMatrixAssembler(rowNode, colNode, elementMatrix_));
......
......@@ -3,7 +3,7 @@
#include <list>
#include <memory>
#include <amdis/typetree/TreeData.hpp>
#include <amdis/typetree/TreeContainer.hpp>
namespace AMDiS
{
......@@ -48,6 +48,8 @@ namespace AMDiS
/// Container for storing shared pointers to boundary conditions indexed by their position in
/// the basis tree, see \ref MatrixData.
template <class Mat, class Sol, class Rhs, class RB, class CB>
using BoundaryConditions = MatrixData<RB, CB, BCData<Mat, Sol, Rhs>::template type>;
using BoundaryConditions
= TreeMatrix<BCData<Mat, Sol, Rhs>::template type,
typename RB::LocalView::Tree, typename CB::LocalView::Tree>;
} // end namespace AMDiS
......@@ -44,8 +44,6 @@ namespace AMDiS
: Super(*basis)
, basis_(basis)
{
operators_.init(*basis);
auto const localSize = basis->localView().maxSize();
elementVector_.resize(localSize);
}
......
......@@ -18,12 +18,13 @@ addOperator(ContextTag contextTag, Expr const& expr, TreePath path)
static_assert( Concepts::PreTreePath<TreePath>,
"path must be a valid treepath, or an integer/index-constant");
auto i = child(this->basis()->localView().tree(), makeTreePath(path));
auto i = makeTreePath(path);
auto node = child(this->basis()->localView().tree(), i);
using LocalContext = typename ContextTag::type;
using Tr = DefaultAssemblerTraits<LocalContext, ElementVector>;
auto op = makeLocalOperator<LocalContext>(expr, this->basis()->gridView());
auto localAssembler = makeUniquePtr(makeAssembler<Tr>(std::move(op), i));
auto localAssembler = makeUniquePtr(makeAssembler<Tr>(std::move(op), node));
operators_[i].push(contextTag, std::move(localAssembler));
}
......@@ -41,8 +42,8 @@ assemble(LocalView const& localView)
auto const& element = localView.element();
auto geometry = element.geometry();
for_each_node(localView.tree(), [&](auto const& node, auto) {
auto& rhsOp = operators_[node];
for_each_node(localView.tree(), [&](auto const& node, auto tp) {
auto& rhsOp = operators_[tp];
if (rhsOp) {
rhsOp.bind(element, geometry);
assembleOperators(gv, element, rhsOp, makeVectorAssembler(node, elementVector_));
......
......@@ -5,7 +5,7 @@
#include <amdis/BoundarySubset.hpp>
#include <amdis/AssemblerInterface.hpp>
#include <amdis/typetree/TreeData.hpp>
#include <amdis/typetree/TreeContainer.hpp>
namespace AMDiS
{
......@@ -141,10 +141,15 @@ namespace AMDiS
template <class RowBasis, class ColBasis, class ElementMatrix>
using MatrixOperators
= MatrixData<RowBasis, ColBasis, OperatorLists<typename RowBasis::GridView,ElementMatrix>::template MatData>;
= TreeMatrix<
OperatorLists<typename RowBasis::GridView,ElementMatrix>::template MatData,
typename RowBasis::LocalView::Tree,
typename ColBasis::LocalView::Tree>;
template <class GlobalBasis, class ElementVector>
template <class Basis, class ElementVector>
using VectorOperators
= VectorData<GlobalBasis, OperatorLists<typename GlobalBasis::GridView,ElementVector>::template VecData>;
= TreeContainer<
OperatorLists<typename Basis::GridView,ElementVector>::template VecData,
typename Basis::LocalView::Tree>;
} // end namespace AMDiS
......@@ -197,7 +197,7 @@ auto PeriodicBC<Mat, Sol, Rhs, Basis, TP>::
coords(Node const& tree, std::vector<std::size_t> const& localIndices) const
{
std::vector<Domain> dofCoords(localIndices.size());
for_each_leaf_node(tree, [&](auto const& node, auto const& tp)
for_each_leaf_node(tree, [&](auto const& node, auto&&)
{
std::size_t size = node.finiteElement().size();
auto geometry = node.element().geometry();
......
......@@ -33,17 +33,12 @@
#include <amdis/ProblemStatBase.hpp>
#include <amdis/ProblemStatTraits.hpp>
#include <amdis/StandardProblemIteration.hpp>
#include <amdis/common/SharedPtr.hpp>
#include <amdis/common/TupleUtility.hpp>
#include <amdis/common/TypeTraits.hpp>
#include <amdis/GridFunctions.hpp>
#include <amdis/gridfunctions/DiscreteFunction.hpp>
#include <amdis/io/FileWriterBase.hpp>
#include <amdis/typetree/TreeData.hpp>
#include <amdis/typetree/TreePath.hpp>
namespace AMDiS
......@@ -305,7 +300,7 @@ namespace AMDiS
bool storeMatrixData = false) override;
/// Implementation of \ref ProblemStatBase::estimate.
void estimate(AdaptInfo& adaptInfo) override { /* do nothing. */ }
void estimate(AdaptInfo& /*adaptInfo*/) override { /* do nothing. */ }
/// Implementation of \ref ProblemStatBase::refineMesh.
Flag adaptGrid(AdaptInfo& adaptInfo) override;
......
......@@ -209,10 +209,7 @@ void ProblemStat<Traits>::createGlobalBasisImpl(std::false_type)
template <class Traits>
void ProblemStat<Traits>::initGlobalBasis()
{
boundaryConditions_.init(*globalBasis_, *globalBasis_);
}
void ProblemStat<Traits>::initGlobalBasis() {}
template <class Traits>
......@@ -227,7 +224,7 @@ void ProblemStat<Traits>::createMatricesAndVectors()
rhs_ = std::make_shared<SystemVector>(globalBasis_);
auto localView = globalBasis_->localView();
for_each_node(localView.tree(), [&,this](auto const& node, auto treePath) -> void
for_each_node(localView.tree(), [&,this](auto&&, auto treePath) -> void
{
std::string i = to_string(treePath);
estimates_[i].resize(globalBasis_->gridView().indexSet().size(0));
......@@ -255,7 +252,7 @@ void ProblemStat<Traits>::createMarker()
{
marker_.clear();
auto localView = globalBasis_->localView();
for_each_node(localView.tree(), [&,this](auto const& node, auto treePath) -> void
for_each_node(localView.tree(), [&,this](auto&&, auto treePath) -> void
{
std::string componentName = name_ + "->marker[" + to_string(treePath) + "]";
......@@ -358,7 +355,7 @@ addPeriodicBC(BoundaryType id, WorldMatrix const& matrix, WorldVector const& vec
template <class Traits>
void ProblemStat<Traits>::
solve(AdaptInfo& adaptInfo, bool createMatrixData, bool storeMatrixData)
solve(AdaptInfo& /*adaptInfo*/, bool createMatrixData, bool storeMatrixData)
{
Dune::Timer t;
......@@ -449,7 +446,7 @@ globalRefine(int n)
template <class Traits>
Flag ProblemStat<Traits>::
adaptGrid(AdaptInfo& adaptInfo)
adaptGrid(AdaptInfo& /*adaptInfo*/)
{
Dune::Timer t;
......@@ -470,9 +467,9 @@ buildAfterAdapt(AdaptInfo& /*adaptInfo*/, Flag /*flag*/, bool asmMatrix, bool as
Dune::Timer t2;
auto localView = globalBasis_->localView();
for_each_node(localView.tree(), [&,this](auto const& rowNode, auto rowTp) -> void {
for_each_node(localView.tree(), [&,this](auto const& colNode, auto colTp) -> void {
for (auto bc : boundaryConditions_[rowNode][colNode])
for_each_node(localView.tree(), [&](auto&&, auto rowTp) -> void {
for_each_node(localView.tree(), [&](auto&&, auto colTp) -> void {
for (auto bc : boundaryConditions_[rowTp][colTp])
bc->init();
});
});
......@@ -509,10 +506,10 @@ buildAfterAdapt(AdaptInfo& /*adaptInfo*/, Flag /*flag*/, bool asmMatrix, bool as
t2.reset();
solution_->resize(sizeInfo(*globalBasis_));
for_each_node(localView.tree(), [&,this](auto const& rowNode, auto row_tp) -> void {
for_each_node(localView.tree(), [&,this](auto const& colNode, auto col_tp) -> void {
for_each_node(localView.tree(), [&](auto&&, auto rowTp) -> void {
for_each_node(localView.tree(), [&](auto&&, auto colTp) -> void {
// finish boundary condition
for (auto bc : boundaryConditions_[rowNode][colNode])
for (auto bc : boundaryConditions_[rowTp][colTp])
bc->apply(*systemMatrix_, *solution_, *rhs_);
});
});
......
......@@ -5,6 +5,5 @@ install(FILES
RangeType.hpp
Traversal.hpp
TreeContainer.hpp
TreeData.hpp
TreePath.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/amdis/typetree)
......@@ -18,20 +18,217 @@
namespace AMDiS
{
/// \brief Vector data-structure with tree-path index access and hierarchic structure
/// given by the `Container` template type
/**
* This Vector container is parametrized with the actual container type that is stored
* internally. Access to the elements of the container is possible by using a tree-path
* index.
*
* The internal container is constructed by the \ref ContainerFactory, storing for each
* tree node a corresponding array or tuple plus a value. The data-structure to hold
* both, the value and the container is defined in \ref ValueAndContainer.
**/
template <class Container>
class TreeContainerStorage
{
using Self = TreeContainerStorage;
template <class C>
static constexpr decltype(auto)
accessByTreePath(C&& container, Dune::TypeTree::HybridTreePath<> const&)
{
return container.value();
}
template <class C, class... T>
static constexpr decltype(auto)
accessByTreePath(C&& container, Dune::TypeTree::HybridTreePath<T...> const& path)
{
auto head = Dune::TypeTree::treePathEntry(path,Dune::Indices::_0);
return accessByTreePath(container[head], pop_front(path));
}
public:
/// \brief Default-construct the tree-container
TreeContainerStorage()
: container_()
{}
TreeContainerStorage(Container const& container)
: container_(container)
{}
/// \brief Construct the tree-container from a given container storage
TreeContainerStorage(Container&& container)
: container_(std::move(container))
{}
/// \brief Access a (const) element of the container by treepath
template <class... T>
decltype(auto) operator[](Dune::TypeTree::HybridTreePath<T...> const& path) const
{
return accessByTreePath(container_, path);
}
/// \brief Access a (mutable) element of the container by treepath
template <class... T>
decltype(auto) operator[](Dune::TypeTree::HybridTreePath<T...> const& path)
{
return accessByTreePath(container_, path);
}
/// \brief Obtain the container (const)
Container const& data() const
{
return container_;
}
/// \brief Obtain the container (mutable)
Container& data()
{
return container_;
}
/// \brief Compare two containers for equality
bool operator==(TreeContainerStorage const& other) const
{
return container_ == other.container_;
}
/// \brief Compare two containers for inequality
bool operator!=(TreeContainerStorage const& other) const
{
return container_ != other.container_;
}
private:
Container container_;
};
namespace Impl
{
template <class Value, class Container>
class ValueAndContainer
{
public:
template <class V, class C>
ValueAndContainer(V&& value, C&& container)
: value_(FWD(value))
, container_(FWD(container))
{}
ValueAndContainer()
: value_()
, container_()
{}
template <class I>
auto& operator[](I const& i) { return container_[i]; }
template <class I>
auto const& operator[](I const& i) const { return container_[i]; }
Value& value() { return value_; }
Value const& value() const { return value_; }
Container& container() { return container_; }
Container const& container() const { return container_; }
bool operator==(ValueAndContainer const& other) const
{
return value_ == other.value_ && container_ == other.container_;
}
private:
Value value_;
Container container_;
};
template <class Value>
class ValueAndContainer<Value,void>
{
public:
template <class V, Dune::disableCopyMove<ValueAndContainer,V> = 0>
ValueAndContainer(V&& value)
: value_(FWD(value))
{}
ValueAndContainer()
: value_()
{}
Value& value() { return value_; }
Value const& value() const { return value_; }
bool operator==(ValueAndContainer const& other) const
{
return value_ == other.value_;
}
private:
Value value_;
};
struct Ignore{};
template <class Container>
class ValueAndContainer<Ignore,Container>
{
public:
template <class C>
ValueAndContainer(Ignore, C&& container)
: container_(FWD(container))
{}
ValueAndContainer()
: container_()
{}
template <class I>
auto& operator[](I const& i) { return container_[i]; }
template <class I>
auto const& operator[](I const& i) const { return container_[i]; }
Ignore value() { return {}; }
Ignore value() const { return {}; }
Container& container() { return container_; }
Container const& container() const { return container_; }
bool operator==(ValueAndContainer const& other) const
{
return container_ == other.container_;
}
private:
Container container_;
};
template <class Value, class Container>
ValueAndContainer(Value const&, Container const&)
-> ValueAndContainer<Value,Container>;
template <class Value>
ValueAndContainer(Value const&)
-> ValueAndContainer<Value,void>;
/// \brief A factory class creating a hybrid container compatible with a type tree
/**
*
* This class allows to create a nested hybrid container having the same structure
* as a given type tree. Power nodes are represented as std::array's while composite
* nodes are represented as Dune::TupleVector's. The stored values for the leaf nodes
* are creating using a given predicate. Once created, the factory provides an
* operator() creating the container for the tree given as argument.
*
* \tparam LeafToValue Type of a predicate that determines the stored values at the leafs
*/
template <class LeafToValue>
* This class allows to create a nested hybrid container having the same structure
* as a given type tree. Power nodes are represented as std::array's while composite
* nodes are represented as Dune::TupleVector's. The stored values for the leaf nodes
* are creating using a given predicate. Once created, the factory provides an
* operator() creating the container for the tree given as argument.
*
* \tparam NodeToValue Type of a predicate that determines the stored values at the
* leafs
**/
template <class NodeToValue, bool leafOnly = false>
class ContainerFactory
{
public:
......@@ -41,25 +238,29 @@ namespace AMDiS
*
* \param A predicate used to generate the stored values for the leaves
*/
ContainerFactory(LeafToValue leafToValue)
: leafToValue_(std::move(leafToValue))
ContainerFactory(NodeToValue nodeToValue)
: nodeToValue_(std::move(nodeToValue))
{}
/// \brief Return a container for storing the node content
template <class Node>
auto operator() (Node const& node) const
auto operator()(Node const& node) const
{
if constexpr (Node::isLeaf)
return leafToValue_(node);
return ValueAndContainer{value(node)};
else
if constexpr (Node::isPower) {
using TransformedChild = decltype((*this)(node.child(0)));
return std::array<TransformedChild, Node::degree()>();
return ValueAndContainer{
value(node),
std::array<TransformedChild, Node::degree()>()};
}
else
if constexpr (Node::isComposite) {
return Tools::apply_indices<Node::degree()>(
[&](auto... i) { return Dune::makeTupleVector((*this)(node.child(i))...); });
return ValueAndContainer{
value(node),
Tools::apply_indices<Node::degree()>(
[&](auto... i) { return Dune::makeTupleVector((*this)(node.child(i))...); })};
}
else {
static_assert(Node::isLeaf || Node::isPower || Node::isComposite,
......@@ -68,93 +269,23 @@ namespace AMDiS
}
}
private:
LeafToValue leafToValue_;
};
/// \brief Wrap nested container to provide a VectorBackend
template <class Container>
class TreeContainerVectorBackend
{
using Self = TreeContainerVectorBackend;
template <class C>
static constexpr decltype(auto) accessByTreePath(C&& container, Dune::TypeTree::HybridTreePath<> const& path)
{
return container;
}
template <class C, class... T>
static constexpr decltype(auto) accessByTreePath(C&& container, Dune::TypeTree::HybridTreePath<T...> const& path)
{
auto head = Dune::TypeTree::treePathEntry(path,Dune::Indices::_0);
return accessByTreePath(container[head], pop_front(path));
}
public:
/// \brief Default-construct the tree-container
TreeContainerVectorBackend()
: container_()
{}
/// \brief Construct the tree-container from a given container storage
TreeContainerVectorBackend(Container&& container)
: container_(std::move(container))
{}
/// \brief Access a (const) element of the container by treepath
template <class... T>
decltype(auto) operator[](Dune::TypeTree::HybridTreePath<T...> const& path) const
{
return accessByTreePath(container_, path);
}
/// \brief Access a (mutable) element of the container by treepath
template <class... T>
decltype(auto) operator[](Dune::TypeTree::HybridTreePath<T...> const& path)
{
return accessByTreePath(container_, path);
}
/// \brief Obtain the container (const)
Container const& data() const
{
return container_;
}
/// \brief Obtain the container (mutable)
Container& data()
{
return container_;
}
/// \brief Compare two containers for equality
bool operator==(TreeContainerVectorBackend const& other) const
{
return container_ == other.container_;
}
/// \brief Compare two containers for inequality
bool operator!=(TreeContainerVectorBackend const& other) const
template <class Node>
decltype(auto) value(Node const& node) const
{
return container_ != other.container_;
if constexpr(!Node::isLeaf && leafOnly)
return Ignore{};
else
return nodeToValue_(node);
}
private:
Container container_;
NodeToValue nodeToValue_;
};
template <class Container>
auto makeTreeContainerVectorBackend(Container&& container)
{
return TreeContainerVectorBackend<remove_cvref_t<Container>>(FWD(container));
}
} // end namespace Impl