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
**/
void setSymmetryStructure(SymmetryStructure symm)
{
updatePattern_ = (symmetry_ != symm);
updatePattern_ = updatePattern_ || (symmetry_ != symm);
symmetry_ = symm;
}
......
......@@ -38,17 +38,21 @@ void BiLinearForm<RB,CB,T,Traits>::
assemble(RowLocalView const& rowLocalView, ColLocalView const& colLocalView,
LocalOperators& localOperators)
{
assert(rowLocalView.isBound());
assert(colLocalView.isBound());
elementMatrix_.resize(rowLocalView.size(), colLocalView.size());
elementMatrix_ = 0;
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(colLocalView.treeCache(), [&](auto const& colNode, auto colTp) {
Traversal::forEachNode(rowLocalView.treeCache(), [&](auto const& rowCache, auto rowTp) {
Traversal::forEachNode(colLocalView.treeCache(), [&](auto const& colCache, auto colTp) {
auto& matOp = localOperators[rowTp][colTp];
matOp.bind(context.element());
matOp.assemble(context, rowNode, colNode, elementMatrix_);
matOp.bind(element);
matOp.assemble(context, rowCache, colCache, elementMatrix_);
matOp.unbind();
});
});
......
......@@ -64,6 +64,9 @@ namespace AMDiS
, geometry_(&geometry)
{}
// Prevent from storing pointer to rvalue-reference
ContextGeometry(LC const& localContext, Element const& element, Geometry&& geometry) = delete;
public:
/// Return the bound element (entity of codim 0)
Element const& element() const
......@@ -175,11 +178,11 @@ namespace AMDiS
};
/// Constructor. Stores a copy of gridView and a pointer to element and geometry.
GlobalContext(GV const& gridView, Element const& element,
Geometry const& geometry)
template <class E, class G>
GlobalContext(GV const& gridView, E&& element, G&& geometry)
: gridView_(gridView)
, element_(&element)
, geometry_(&geometry)
, element_(Dune::wrap_or_move(FWD(element)))
, geometry_(Dune::wrap_or_move(FWD(geometry)))
{}
public:
......@@ -203,8 +206,8 @@ namespace AMDiS
private:
GridView gridView_;
Element const* element_;
Geometry const* geometry_;
std::shared_ptr<Element const> element_;
std::shared_ptr<Geometry const> geometry_;
};
} // end namespace AMDiS
......@@ -32,15 +32,18 @@ template <class GB, class T, class Traits>
void LinearForm<GB,T,Traits>::
assemble(LocalView const& localView, LocalOperators& localOperators)
{
assert(localView.isBound());
elementVector_.resize(localView.size());
elementVector_ = 0;
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) {
auto& rhsOp = localOperators[tp];
rhsOp.bind(context.element());
rhsOp.bind(element);
rhsOp.assemble(context, node, elementVector_);
rhsOp.unbind();
});
......
......@@ -87,8 +87,7 @@ namespace AMDiS
return;
// create a context for the element
ContextGeometry elementContext{context.element(),
context.element(), context.geometry()};
ContextGeometry elementContext{context.element(), context.element(), context.geometry()};
// assemble element operators
for (auto const& op : element_)
......@@ -101,8 +100,7 @@ namespace AMDiS
for (auto const& is : intersections(context.gridView(), context.element()))
{
// create a context for the intersection
ContextGeometry intersectionContext{is,
context.element(), context.geometry()};
ContextGeometry intersectionContext{is, context.element(), context.geometry()};
if (is.boundary()) {
// assemble boundary operators
......
......@@ -134,6 +134,12 @@ namespace AMDiS
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
GlobalBasis const& rootBasis() const
{
......
......@@ -67,10 +67,10 @@ namespace AMDiS
// between members tree_ and treeCache_
LocalView (LocalView const& other)
: globalBasis_(other.globalBasis_)
, element_(other.element_)
, tree_(other.tree_)
, treeCache_(makeNodeCache(tree_))
, nodeIndexSet_(other.nodeIndexSet_)
, element_(other.element_)
, indices_(other.indices_)
{}
......@@ -78,11 +78,11 @@ namespace AMDiS
// NOTE: needs to be implemented manually, because of the reference dependency
// between members tree_ and treeCache_
LocalView (LocalView&& other)
: globalBasis_(std::move(other.globalBasis_))
: globalBasis_(other.globalBasis_)
, element_(other.element_)
, tree_(std::move(other.tree_))
, treeCache_(makeNodeCache(tree_))
, nodeIndexSet_(std::move(other.nodeIndexSet_))
, element_(std::move(other.element_))
, indices_(std::move(other.indices_))
{}
......@@ -94,27 +94,34 @@ namespace AMDiS
*/
void bind (Element const& element)
{
element_ = element;
bindTree(tree_, *element_);
element_ = &element;
bindTree(tree_, element);
nodeIndexSet_.bind(tree_);
indices_.resize(size());
indices_.resize(tree_.size());
if constexpr (Dune::Std::is_detected_v<hasIndices, NodeIndexSet, TYPEOF(indices_.begin())>)
nodeIndexSet_.indices(indices_.begin());
else
for (size_type i = 0; i < size(); ++i)
for (size_type i = 0; i < tree_.size(); ++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
bool isBound () const
{
return bool(element_);
return element_ != nullptr;
}
/// \brief Return the grid element that the view is bound to
Element const& element () const
{
assert(isBound());
return *element_;
}
......@@ -125,7 +132,7 @@ namespace AMDiS
void unbind ()
{
nodeIndexSet_.unbind();
element_.reset();
element_ = nullptr;
}
/// \brief Return the local ansatz tree associated to the bound entity
......@@ -143,6 +150,7 @@ namespace AMDiS
/// \brief Total number of degrees of freedom on this element
size_type size () const
{
assert(isBound());
return tree_.size();
}
......@@ -159,6 +167,7 @@ namespace AMDiS
/// in global basis
MultiIndex index (size_type i) const
{
assert(isBound());
return indices_[i];
}
......@@ -176,11 +185,10 @@ namespace AMDiS
protected:
GlobalBasis const* globalBasis_;
Element const* element_ = nullptr;
Tree tree_;
TreeCache treeCache_;
NodeIndexSet nodeIndexSet_;
std::optional<Element> element_;
std::vector<MultiIndex> indices_;
};
......
......@@ -205,7 +205,7 @@ namespace AMDiS
/// \brief Create a local function for this view on the DOFVector. \relates LocalFunction
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
......
#pragma once
#include <dune/common/rangeutilities.hh>
#include <dune/common/std/type_traits.hh>
#include <dune/typetree/nodetags.hh>
#include <dune/typetree/treepath.hh>
......@@ -12,30 +13,9 @@
namespace AMDiS {
namespace Traversal {
namespace Impl_ {
/// \brief Helper function that returns the degree of a Tree.
/**
* 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_
template <class Tree>
using HasDynamicChildAccess = decltype(std::declval<Tree>().child(0u));
/**
......@@ -51,16 +31,15 @@ void forEachNode(Tree&& tree, TreePath treePath, Pre&& preFunc, Leaf&& leafFunc,
leafFunc(tree, treePath);
} else {
preFunc(tree, treePath);
const auto degree = Impl_::traversalDegree(tree);
if constexpr (std::is_integral_v<TYPEOF(degree)>) {
if constexpr(Dune::Std::is_detected_v<HasDynamicChildAccess,TreeType>) {
// 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);
forEachNode(tree.child(i), childTreePath, preFunc, leafFunc, postFunc);
}
} else {
// 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) {
auto childTreePath = Dune::TypeTree::push_back(treePath, i);
forEachNode(tree.child(i), childTreePath, preFunc, leafFunc, postFunc);
......
......@@ -5,6 +5,9 @@ include(AddAmdisExecutable)
find_program(CCACHE_PROGRAM ccache)
if (CCACHE_PROGRAM)
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}")
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
add_compile_options("-fdiagnostics-color")
endif()
endif ()
if (NOT BACKEND)
......
# 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
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)
GridView gridView = basis.gridView();
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& node = Dune::TypeTree::child(tree, path);
......@@ -176,7 +177,8 @@ void test(Op& op, Basis const& basis, Row row, Col col)
GridView gridView = basis.gridView();
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& rowNode = Dune::TypeTree::child(tree, row);
......@@ -216,7 +218,8 @@ template <class Problem>
void test_problem_operators(Problem& prob)
{
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());
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