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

Merge branch 'issue/cleanup_errors' into 'master'

Cleanup errors after LocalOperator merge

See merge request !266
parents 36bc6c97 531fda22
...@@ -134,7 +134,7 @@ namespace AMDiS ...@@ -134,7 +134,7 @@ namespace AMDiS
**/ **/
void setSymmetryStructure(SymmetryStructure symm) void setSymmetryStructure(SymmetryStructure symm)
{ {
updatePattern_ = (symmetry_ != symm); updatePattern_ = updatePattern_ || (symmetry_ != symm);
symmetry_ = symm; symmetry_ = symm;
} }
......
...@@ -38,17 +38,21 @@ void BiLinearForm<RB,CB,T,Traits>:: ...@@ -38,17 +38,21 @@ void BiLinearForm<RB,CB,T,Traits>::
assemble(RowLocalView const& rowLocalView, ColLocalView const& colLocalView, assemble(RowLocalView const& rowLocalView, ColLocalView const& colLocalView,
LocalOperators& localOperators) LocalOperators& localOperators)
{ {
assert(rowLocalView.isBound());
assert(colLocalView.isBound());
elementMatrix_.resize(rowLocalView.size(), colLocalView.size()); elementMatrix_.resize(rowLocalView.size(), colLocalView.size());
elementMatrix_ = 0; elementMatrix_ = 0;
auto const& gv = this->rowBasis().gridView(); auto const& gv = this->rowBasis().gridView();
GlobalContext<TYPEOF(gv)> context{gv, rowLocalView.element(), rowLocalView.element().geometry()}; auto const& element = rowLocalView.element();
GlobalContext<TYPEOF(gv)> context{gv, element, element.geometry()};
Traversal::forEachNode(rowLocalView.treeCache(), [&](auto const& rowNode, auto rowTp) { Traversal::forEachNode(rowLocalView.treeCache(), [&](auto const& rowCache, auto rowTp) {
Traversal::forEachNode(colLocalView.treeCache(), [&](auto const& colNode, auto colTp) { Traversal::forEachNode(colLocalView.treeCache(), [&](auto const& colCache, auto colTp) {
auto& matOp = localOperators[rowTp][colTp]; auto& matOp = localOperators[rowTp][colTp];
matOp.bind(context.element()); matOp.bind(element);
matOp.assemble(context, rowNode, colNode, elementMatrix_); matOp.assemble(context, rowCache, colCache, elementMatrix_);
matOp.unbind(); matOp.unbind();
}); });
}); });
......
...@@ -64,6 +64,9 @@ namespace AMDiS ...@@ -64,6 +64,9 @@ namespace AMDiS
, geometry_(&geometry) , geometry_(&geometry)
{} {}
// Prevent from storing pointer to rvalue-reference
ContextGeometry(LC const& localContext, Element const& element, Geometry&& geometry) = delete;
public: public:
/// Return the bound element (entity of codim 0) /// Return the bound element (entity of codim 0)
Element const& element() const Element const& element() const
...@@ -175,11 +178,11 @@ namespace AMDiS ...@@ -175,11 +178,11 @@ namespace AMDiS
}; };
/// Constructor. Stores a copy of gridView and a pointer to element and geometry. /// Constructor. Stores a copy of gridView and a pointer to element and geometry.
GlobalContext(GV const& gridView, Element const& element, template <class E, class G>
Geometry const& geometry) GlobalContext(GV const& gridView, E&& element, G&& geometry)
: gridView_(gridView) : gridView_(gridView)
, element_(&element) , element_(Dune::wrap_or_move(FWD(element)))
, geometry_(&geometry) , geometry_(Dune::wrap_or_move(FWD(geometry)))
{} {}
public: public:
...@@ -203,8 +206,8 @@ namespace AMDiS ...@@ -203,8 +206,8 @@ namespace AMDiS
private: private:
GridView gridView_; GridView gridView_;
Element const* element_; std::shared_ptr<Element const> element_;
Geometry const* geometry_; std::shared_ptr<Geometry const> geometry_;
}; };
} // end namespace AMDiS } // end namespace AMDiS
...@@ -32,15 +32,18 @@ template <class GB, class T, class Traits> ...@@ -32,15 +32,18 @@ template <class GB, class T, class Traits>
void LinearForm<GB,T,Traits>:: void LinearForm<GB,T,Traits>::
assemble(LocalView const& localView, LocalOperators& localOperators) assemble(LocalView const& localView, LocalOperators& localOperators)
{ {
assert(localView.isBound());
elementVector_.resize(localView.size()); elementVector_.resize(localView.size());
elementVector_ = 0; elementVector_ = 0;
auto const& gv = this->basis().gridView(); auto const& gv = this->basis().gridView();
GlobalContext<TYPEOF(gv)> context{gv, localView.element(), localView.element().geometry()}; auto const& element = localView.element();
GlobalContext<TYPEOF(gv)> context{gv, element, element.geometry()};
Traversal::forEachNode(localView.treeCache(), [&](auto const& node, auto tp) { Traversal::forEachNode(localView.treeCache(), [&](auto const& node, auto tp) {
auto& rhsOp = localOperators[tp]; auto& rhsOp = localOperators[tp];
rhsOp.bind(context.element()); rhsOp.bind(element);
rhsOp.assemble(context, node, elementVector_); rhsOp.assemble(context, node, elementVector_);
rhsOp.unbind(); rhsOp.unbind();
}); });
......
...@@ -87,8 +87,7 @@ namespace AMDiS ...@@ -87,8 +87,7 @@ namespace AMDiS
return; return;
// create a context for the element // create a context for the element
ContextGeometry elementContext{context.element(), ContextGeometry elementContext{context.element(), context.element(), context.geometry()};
context.element(), context.geometry()};
// assemble element operators // assemble element operators
for (auto const& op : element_) for (auto const& op : element_)
...@@ -101,8 +100,7 @@ namespace AMDiS ...@@ -101,8 +100,7 @@ namespace AMDiS
for (auto const& is : intersections(context.gridView(), context.element())) for (auto const& is : intersections(context.gridView(), context.element()))
{ {
// create a context for the intersection // create a context for the intersection
ContextGeometry intersectionContext{is, ContextGeometry intersectionContext{is, context.element(), context.geometry()};
context.element(), context.geometry()};
if (is.boundary()) { if (is.boundary()) {
// assemble boundary operators // assemble boundary operators
......
...@@ -134,6 +134,12 @@ namespace AMDiS ...@@ -134,6 +134,12 @@ namespace AMDiS
return LocalView(*this); return LocalView(*this);
} }
/// Return local view as shared_ptr to prevent from copy construction
std::shared_ptr<LocalView> localViewPtr() const
{
return std::make_shared<LocalView>(*this);
}
/// Return *this because we are not embedded in a larger basis /// Return *this because we are not embedded in a larger basis
GlobalBasis const& rootBasis() const GlobalBasis const& rootBasis() const
{ {
......
...@@ -67,10 +67,10 @@ namespace AMDiS ...@@ -67,10 +67,10 @@ namespace AMDiS
// between members tree_ and treeCache_ // between members tree_ and treeCache_
LocalView (LocalView const& other) LocalView (LocalView const& other)
: globalBasis_(other.globalBasis_) : globalBasis_(other.globalBasis_)
, element_(other.element_)
, tree_(other.tree_) , tree_(other.tree_)
, treeCache_(makeNodeCache(tree_)) , treeCache_(makeNodeCache(tree_))
, nodeIndexSet_(other.nodeIndexSet_) , nodeIndexSet_(other.nodeIndexSet_)
, element_(other.element_)
, indices_(other.indices_) , indices_(other.indices_)
{} {}
...@@ -78,11 +78,11 @@ namespace AMDiS ...@@ -78,11 +78,11 @@ namespace AMDiS
// NOTE: needs to be implemented manually, because of the reference dependency // NOTE: needs to be implemented manually, because of the reference dependency
// between members tree_ and treeCache_ // between members tree_ and treeCache_
LocalView (LocalView&& other) LocalView (LocalView&& other)
: globalBasis_(std::move(other.globalBasis_)) : globalBasis_(other.globalBasis_)
, element_(other.element_)
, tree_(std::move(other.tree_)) , tree_(std::move(other.tree_))
, treeCache_(makeNodeCache(tree_)) , treeCache_(makeNodeCache(tree_))
, nodeIndexSet_(std::move(other.nodeIndexSet_)) , nodeIndexSet_(std::move(other.nodeIndexSet_))
, element_(std::move(other.element_))
, indices_(std::move(other.indices_)) , indices_(std::move(other.indices_))
{} {}
...@@ -94,27 +94,34 @@ namespace AMDiS ...@@ -94,27 +94,34 @@ namespace AMDiS
*/ */
void bind (Element const& element) void bind (Element const& element)
{ {
element_ = element; element_ = &element;
bindTree(tree_, *element_); bindTree(tree_, element);
nodeIndexSet_.bind(tree_); nodeIndexSet_.bind(tree_);
indices_.resize(size()); indices_.resize(tree_.size());
if constexpr (Dune::Std::is_detected_v<hasIndices, NodeIndexSet, TYPEOF(indices_.begin())>) if constexpr (Dune::Std::is_detected_v<hasIndices, NodeIndexSet, TYPEOF(indices_.begin())>)
nodeIndexSet_.indices(indices_.begin()); nodeIndexSet_.indices(indices_.begin());
else else
for (size_type i = 0; i < size(); ++i) for (size_type i = 0; i < tree_.size(); ++i)
indices_[i] = nodeIndexSet_.index(i); indices_[i] = nodeIndexSet_.index(i);
} }
// do not bind an rvalue-reference
void bind (Element&& element)
{
static_assert(not std::is_rvalue_reference_v<Element&&>);
}
/// \brief Return if the view is bound to a grid element /// \brief Return if the view is bound to a grid element
bool isBound () const bool isBound () const
{ {
return bool(element_); return element_ != nullptr;
} }
/// \brief Return the grid element that the view is bound to /// \brief Return the grid element that the view is bound to
Element const& element () const Element const& element () const
{ {
assert(isBound());
return *element_; return *element_;
} }
...@@ -125,7 +132,7 @@ namespace AMDiS ...@@ -125,7 +132,7 @@ namespace AMDiS
void unbind () void unbind ()
{ {
nodeIndexSet_.unbind(); nodeIndexSet_.unbind();
element_.reset(); element_ = nullptr;
} }
/// \brief Return the local ansatz tree associated to the bound entity /// \brief Return the local ansatz tree associated to the bound entity
...@@ -143,6 +150,7 @@ namespace AMDiS ...@@ -143,6 +150,7 @@ namespace AMDiS
/// \brief Total number of degrees of freedom on this element /// \brief Total number of degrees of freedom on this element
size_type size () const size_type size () const
{ {
assert(isBound());
return tree_.size(); return tree_.size();
} }
...@@ -159,6 +167,7 @@ namespace AMDiS ...@@ -159,6 +167,7 @@ namespace AMDiS
/// in global basis /// in global basis
MultiIndex index (size_type i) const MultiIndex index (size_type i) const
{ {
assert(isBound());
return indices_[i]; return indices_[i];
} }
...@@ -176,11 +185,10 @@ namespace AMDiS ...@@ -176,11 +185,10 @@ namespace AMDiS
protected: protected:
GlobalBasis const* globalBasis_; GlobalBasis const* globalBasis_;
Element const* element_ = nullptr;
Tree tree_; Tree tree_;
TreeCache treeCache_; TreeCache treeCache_;
NodeIndexSet nodeIndexSet_; NodeIndexSet nodeIndexSet_;
std::optional<Element> element_;
std::vector<MultiIndex> indices_; std::vector<MultiIndex> indices_;
}; };
......
...@@ -205,7 +205,7 @@ namespace AMDiS ...@@ -205,7 +205,7 @@ namespace AMDiS
/// \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
LocalFunction<tag::value> makeLocalFunction() const LocalFunction<tag::value> makeLocalFunction() const
{ {
return {std::make_shared<LocalView>(basis().localView()), treePath(), coefficients(), tag::value{}}; return {basis().localViewPtr(), treePath(), coefficients(), tag::value{}};
} }
/// \brief Return a \ref Dune::Functions::GridViewEntitySet /// \brief Return a \ref Dune::Functions::GridViewEntitySet
......
#pragma once #pragma once
#include <dune/common/rangeutilities.hh> #include <dune/common/rangeutilities.hh>
#include <dune/common/std/type_traits.hh>
#include <dune/typetree/nodetags.hh> #include <dune/typetree/nodetags.hh>
#include <dune/typetree/treepath.hh> #include <dune/typetree/treepath.hh>
...@@ -12,30 +13,9 @@ ...@@ -12,30 +13,9 @@
namespace AMDiS { namespace AMDiS {
namespace Traversal { namespace Traversal {
namespace Impl_ {
/// \brief Helper function that returns the degree of a Tree. template <class Tree>
/** using HasDynamicChildAccess = decltype(std::declval<Tree>().child(0u));
* The return type is either `size_t` if it is a dynamic tree or the flag `dynamic`
* is set to `true`, or as the type returned by the `degree()` member function of the
* tree.
*
* This function allows to change the tree traversal from static to dynamic in case
* of power nodes and uses static traversal for composite and dynamic traversal for
* all dynamic nodes.
**/
template <bool dynamic = true, class Tree>
auto traversalDegree(Tree const& tree)
{
if constexpr (dynamic && Tree::isPower)
return std::size_t(tree.degree());
else if constexpr (Tree::isPower || Tree::isComposite)
return std::integral_constant<std::size_t, Tree::degree()>{};
else
return tree.degree();
}
} // end namespace Impl_
/** /**
...@@ -51,16 +31,15 @@ void forEachNode(Tree&& tree, TreePath treePath, Pre&& preFunc, Leaf&& leafFunc, ...@@ -51,16 +31,15 @@ void forEachNode(Tree&& tree, TreePath treePath, Pre&& preFunc, Leaf&& leafFunc,
leafFunc(tree, treePath); leafFunc(tree, treePath);
} else { } else {
preFunc(tree, treePath); preFunc(tree, treePath);
const auto degree = Impl_::traversalDegree(tree); if constexpr(Dune::Std::is_detected_v<HasDynamicChildAccess,TreeType>) {
if constexpr (std::is_integral_v<TYPEOF(degree)>) {
// Specialization for dynamic traversal // Specialization for dynamic traversal
for (std::size_t i = 0; i < std::size_t(degree); ++i) { for (std::size_t i = 0; i < tree.degree(); ++i) {
auto childTreePath = Dune::TypeTree::push_back(treePath, i); auto childTreePath = Dune::TypeTree::push_back(treePath, i);
forEachNode(tree.child(i), childTreePath, preFunc, leafFunc, postFunc); forEachNode(tree.child(i), childTreePath, preFunc, leafFunc, postFunc);
} }
} else { } else {
// Specialization for static traversal // Specialization for static traversal
const auto indices = std::make_index_sequence<VALUE(degree)>{}; const auto indices = std::make_index_sequence<TreeType::degree()>{};
Ranges::forIndices(indices, [&](auto i) { Ranges::forIndices(indices, [&](auto i) {
auto childTreePath = Dune::TypeTree::push_back(treePath, i); auto childTreePath = Dune::TypeTree::push_back(treePath, i);
forEachNode(tree.child(i), childTreePath, preFunc, leafFunc, postFunc); forEachNode(tree.child(i), childTreePath, preFunc, leafFunc, postFunc);
......
...@@ -5,6 +5,9 @@ include(AddAmdisExecutable) ...@@ -5,6 +5,9 @@ include(AddAmdisExecutable)
find_program(CCACHE_PROGRAM ccache) find_program(CCACHE_PROGRAM ccache)
if (CCACHE_PROGRAM) if (CCACHE_PROGRAM)
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}")
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
add_compile_options("-fdiagnostics-color")
endif()
endif () endif ()
if (NOT BACKEND) if (NOT BACKEND)
......
# set(DUNE_MAX_TEST_CORES 4) # set(DUNE_MAX_TEST_CORES 4)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_COMMAND} -E time") set_property(DIRECTORY PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_COMMAND} -E time")
# additional compiler option for CMAKE_BUILD_TYPE=RelWithDebInfo only for gcc # additional compiler option for CMAKE_BUILD_TYPE=RelWithDebInfo only for gcc
set(NoVarTrackingAssignments $<$<AND:$<CONFIG:RelWithDebInfo>,$<CXX_COMPILER_ID:GNU>>:-fno-var-tracking-assignments>) set(NoVarTrackingAssignments $<$<AND:$<CONFIG:RelWithDebInfo>,$<CXX_COMPILER_ID:GNU>>:-fno-var-tracking-assignments>)
......
...@@ -130,7 +130,8 @@ void test(Op& op, Basis const& basis, Path path) ...@@ -130,7 +130,8 @@ void test(Op& op, Basis const& basis, Path path)
GridView gridView = basis.gridView(); GridView gridView = basis.gridView();
auto localView = basis.localView(); auto localView = basis.localView();
localView.bind(*gridView.template begin<0>()); auto element = *gridView.template begin<0>();
localView.bind(element);
auto const& tree = localView.treeCache(); auto const& tree = localView.treeCache();
auto const& node = Dune::TypeTree::child(tree, path); auto const& node = Dune::TypeTree::child(tree, path);
...@@ -176,7 +177,8 @@ void test(Op& op, Basis const& basis, Row row, Col col) ...@@ -176,7 +177,8 @@ void test(Op& op, Basis const& basis, Row row, Col col)
GridView gridView = basis.gridView(); GridView gridView = basis.gridView();
auto localView = basis.localView(); auto localView = basis.localView();
localView.bind(*gridView.template begin<0>()); auto element = *gridView.template begin<0>();
localView.bind(element);
auto const& tree = localView.treeCache(); auto const& tree = localView.treeCache();
auto const& rowNode = Dune::TypeTree::child(tree, row); auto const& rowNode = Dune::TypeTree::child(tree, row);
...@@ -216,7 +218,8 @@ template <class Problem> ...@@ -216,7 +218,8 @@ template <class Problem>
void test_problem_operators(Problem& prob) void test_problem_operators(Problem& prob)
{ {
auto localView = prob.globalBasis()->localView(); auto localView = prob.globalBasis()->localView();
localView.bind(*prob.gridView().template begin<0>()); auto element = *prob.gridView().template begin<0>();
localView.bind(element);
FlatVector<T> elementVec(localView.size()); FlatVector<T> elementVec(localView.size());
FlatMatrix<T> elementMat(localView.size(), localView.size()); FlatMatrix<T> elementMat(localView.size(), localView.size());
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment