Skip to content
Snippets Groups Projects
Commit e23967f7 authored by Timo Koch's avatar Timo Koch
Browse files

[bugfix][gridgeometry] Always construct bboxtree and element map

A thread-safe implementation with double-checked lock needs atomic load/store
operations to update the pointer to be thread-safe. Alternatively, a lock
has to be acquired every time when the function is called. Both implementations
impair the scalability of the multihreaded assembly (in the case of tpfa, or
any simulation that uses element maps or bounding box tree on an element level).

This changes the beahviour to always build the tree and the element map. This
usually occurs little runtime overhead in cases where the features are unused.
It is the most performant version as soon as one of the features is used.
There is however some memory overhead in the order of one or more ints per
element (seeds) and a bounding box hierarchy.
parent 0528733e
No related branches found
No related tags found
1 merge request!3095[bugfix][gridgeometry] Always construct bboxtree and element map
Pipeline #16029 passed
+2
......@@ -26,7 +26,6 @@
#include <utility>
#include <type_traits>
#include <mutex>
#include <dune/grid/common/mcmgmapper.hh>
......@@ -149,34 +148,13 @@ public:
* \brief Returns the bounding box tree of the grid
*/
const BoundingBoxTree& boundingBoxTree() const
{
if (!boundingBoxTree_)
{
std::scoped_lock{ boundingBoxTreeMutex_ };
if (!boundingBoxTree_)
elementMap(); // make sure the element map is built
boundingBoxTree_ = std::make_unique<BoundingBoxTree>(
std::make_shared<ElementSet>(gridView_, elementMapper(), elementMap_)
);
}
return *boundingBoxTree_;
}
{ return *boundingBoxTree_; }
/*!
* \brief Returns the element index to element map
*/
const ElementMap& elementMap() const
{
if (!elementMap_)
{
std::scoped_lock{ elementMapMutex_ };
if (!elementMap_)
elementMap_ = std::make_shared<ElementMap>(gridView_.grid(), elementMapper_);
}
return *elementMap_;
}
{ return *elementMap_; }
/*!
* \brief Get an element from a global element index
......@@ -258,7 +236,7 @@ private:
void update_()
{
//! Update the mappers
// Update the mappers
if constexpr (Deprecated::hasUpdateGridView<ElementMapper, GridView>())
elementMapper_.update(gridView_);
else
......@@ -269,12 +247,17 @@ private:
else
Deprecated::update(vertexMapper_);
//! Compute the bounding box of the entire domain, for e.g. setting boundary conditions
// Compute the bounding box of the entire domain, for e.g. setting boundary conditions
computeGlobalBoundingBox_();
//! reset bounding box tree and the element map until requested the next time
boundingBoxTree_.release();
elementMap_.reset();
// update element map and bounding box tree
// always building these comes at a memory overhead but improved
// performance and thread-safe element level access (e.g. during assembly)
// for all simulation that use these features
elementMap_ = std::make_shared<ElementMap>(gridView_.grid(), elementMapper_);
boundingBoxTree_ = std::make_unique<BoundingBoxTree>(
std::make_shared<ElementSet>(gridView_, elementMapper(), elementMap_)
);
}
//! the process grid view
......@@ -285,12 +268,10 @@ private:
VertexMapper vertexMapper_;
//! the bounding box tree of the grid view for efficient element intersections
mutable std::unique_ptr<BoundingBoxTree> boundingBoxTree_;
mutable std::mutex boundingBoxTreeMutex_;
std::unique_ptr<const BoundingBoxTree> boundingBoxTree_;
//! a map from element index to elements (needed in the bounding box tree and for assembling cell-centered discretization)
mutable std::shared_ptr<ElementMap> elementMap_;
mutable std::mutex elementMapMutex_;
//! a map from element index to elements
std::shared_ptr<const ElementMap> elementMap_;
//! the bounding box of the whole domain
GlobalCoordinate bBoxMin_;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment