Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ framework/contrib/asio/
*.cpr
*.cpa.gz-*
*.cpr-*
*_cp/

# Ignore petsc arch
petsc/arch-*/*
Expand Down
2 changes: 1 addition & 1 deletion framework/include/constraints/NodeElemConstraintBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class NodeElemConstraintBase
const VariableTestValue & _test_primary;

/// MooseMesh map of current nodes to the connected elements
const std::map<dof_id_type, std::vector<dof_id_type>> & _node_to_elem_map;
const std::unordered_map<dof_id_type, std::vector<dof_id_type>> & _node_to_elem_map;

/// maps secondary node ids to primary element ids
std::map<dof_id_type, dof_id_type> _secondary_to_primary_map;
Expand Down
2 changes: 1 addition & 1 deletion framework/include/constraints/NodeFaceConstraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ class NodeFaceConstraint : public Constraint,
/// DOF map
const DofMap & _dof_map;

const std::map<dof_id_type, std::vector<dof_id_type>> & _node_to_elem_map;
const std::unordered_map<dof_id_type, std::vector<dof_id_type>> & _node_to_elem_map;

/**
* Whether or not the secondary's residual should be overwritten.
Expand Down
35 changes: 18 additions & 17 deletions framework/include/geomsearch/PenetrationThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,23 @@ typedef MooseVariableFE<libMesh::VectorValue<Real>> VectorMooseVariable;
class PenetrationThread
{
public:
PenetrationThread(SubProblem & subproblem,
const MooseMesh & mesh,
BoundaryID primary_boundary,
BoundaryID secondary_boundary,
std::map<dof_id_type, PenetrationInfo *> & penetration_info,
bool check_whether_reasonable,
bool update_location,
Real tangential_tolerance,
bool do_normal_smoothing,
Real normal_smoothing_distance,
PenetrationLocator::NORMAL_SMOOTHING_METHOD normal_smoothing_method,
bool use_point_locator,
std::vector<std::vector<libMesh::FEBase *>> & fes,
libMesh::FEType & fe_type,
NearestNodeLocator & nearest_node,
const std::map<dof_id_type, std::vector<dof_id_type>> & node_to_elem_map);
PenetrationThread(
SubProblem & subproblem,
const MooseMesh & mesh,
BoundaryID primary_boundary,
BoundaryID secondary_boundary,
std::map<dof_id_type, PenetrationInfo *> & penetration_info,
bool check_whether_reasonable,
bool update_location,
Real tangential_tolerance,
bool do_normal_smoothing,
Real normal_smoothing_distance,
PenetrationLocator::NORMAL_SMOOTHING_METHOD normal_smoothing_method,
bool use_point_locator,
std::vector<std::vector<libMesh::FEBase *>> & fes,
libMesh::FEType & fe_type,
NearestNodeLocator & nearest_node,
const std::unordered_map<dof_id_type, std::vector<dof_id_type>> & node_to_elem_map);

// Splitting Constructor
PenetrationThread(PenetrationThread & x, Threads::split split);
Expand Down Expand Up @@ -78,7 +79,7 @@ class PenetrationThread

NearestNodeLocator & _nearest_node;

const std::map<dof_id_type, std::vector<dof_id_type>> & _node_to_elem_map;
const std::unordered_map<dof_id_type, std::vector<dof_id_type>> & _node_to_elem_map;

THREAD_ID _tid;

Expand Down
4 changes: 2 additions & 2 deletions framework/include/geomsearch/SecondaryNeighborhoodThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class SecondaryNeighborhoodThread
SecondaryNeighborhoodThread(
const MooseMesh & mesh,
const std::vector<dof_id_type> & trial_primary_nodes,
const std::map<dof_id_type, std::vector<dof_id_type>> & node_to_elem_map,
const std::unordered_map<dof_id_type, std::vector<dof_id_type>> & node_to_elem_map,
const unsigned int patch_size,
KDTree & _kd_tree);

Expand Down Expand Up @@ -55,7 +55,7 @@ class SecondaryNeighborhoodThread
const std::vector<dof_id_type> & _trial_primary_nodes;

/// Node to elem map
const std::map<dof_id_type, std::vector<dof_id_type>> & _node_to_elem_map;
const std::unordered_map<dof_id_type, std::vector<dof_id_type>> & _node_to_elem_map;

/// The number of nodes to keep
unsigned int _patch_size;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,5 @@ class BoundaryNodeIntegrityCheckThread
const TheWarehouse::Query & _query;

/// Node to element map. Used for determining vertex vs. non-vertex nodes
const std::map<dof_id_type, std::vector<dof_id_type>> _node_to_elem_map;
const std::unordered_map<dof_id_type, std::vector<dof_id_type>> _node_to_elem_map;
};
25 changes: 10 additions & 15 deletions framework/include/mesh/MooseMesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,16 +251,7 @@ class MooseMesh : public MooseObject, public Restartable, public PerfGraphInterf
* If not already created, creates a map from every node to all
* elements to which they are connected.
*/
const std::map<dof_id_type, std::vector<dof_id_type>> & nodeToElemMap();

/**
* If not already created, creates a map from every node to all
* _active_ _semilocal_ elements to which they are connected.
* Semilocal elements include local elements and elements that share at least
* one node with a local element.
* \note Extra ghosted elements are not included in this map!
*/
const std::map<dof_id_type, std::vector<dof_id_type>> & nodeToActiveSemilocalElemMap();
const std::unordered_map<dof_id_type, std::vector<dof_id_type>> & nodeToElemMap();

/**
* These structs are required so that the bndNodes{Begin,End} and
Expand Down Expand Up @@ -1655,12 +1646,10 @@ class MooseMesh : public MooseObject, public Restartable, public PerfGraphInterf
_bnd_elem_range;

/// A map of all of the current nodes to the elements that they are connected to.
std::map<dof_id_type, std::vector<dof_id_type>> _node_to_elem_map;
bool _node_to_elem_map_built;
std::unordered_map<dof_id_type, std::vector<dof_id_type>> _node_to_elem_map;

/// A map of all of the current nodes to the active elements that they are connected to.
std::map<dof_id_type, std::vector<dof_id_type>> _node_to_active_semilocal_elem_map;
bool _node_to_active_semilocal_elem_map_built;
/// Whether @p _node_to_elem_map has been built.
bool _node_to_elem_map_built = false;

/**
* A set of subdomain IDs currently present in the mesh. For parallel meshes, includes
Expand Down Expand Up @@ -1744,6 +1733,12 @@ class MooseMesh : public MooseObject, public Restartable, public PerfGraphInterf
void setPartitionerHelper(MeshBase * mesh = nullptr);

private:
/**
* If not already created, creates a map from every node to all
* elements to which they are connected.
*/
std::unordered_map<dof_id_type, std::vector<dof_id_type>> & internalNodeToElemMap();

/// Map connecting elems with their corresponding ElemInfo, we use the element ID as
/// the key
mutable std::unordered_map<dof_id_type, ElemInfo> _elem_to_elem_info;
Expand Down
2 changes: 1 addition & 1 deletion framework/src/auxkernels/NodalPatchRecovery.C
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ NodalPatchRecovery::compute()
reinitPatch();

// get node-to-conneted-elem map
const std::map<dof_id_type, std::vector<dof_id_type>> & node_to_elem_map = _mesh.nodeToElemMap();
const auto & node_to_elem_map = _mesh.nodeToElemMap();
auto node_to_elem_pair = node_to_elem_map.find(_current_node->id());
mooseAssert(node_to_elem_pair != node_to_elem_map.end(), "Missing entry in node to elem map");
std::vector<dof_id_type> elem_ids = node_to_elem_pair->second;
Expand Down
7 changes: 2 additions & 5 deletions framework/src/geomsearch/NearestNodeLocator.C
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,6 @@ NearestNodeLocator::NearestNodeLocator(SubProblem & subproblem,
mooseError("NearestNodeLocator being created for boundaries ", _boundary1, " and ", _boundary2,
", but boundary ", _boundary2, " does not exist");
*/

// Request the nodeToElem map upfront
_mesh.nodeToElemMap();
}

NearestNodeLocator::~NearestNodeLocator() = default;
Expand All @@ -71,7 +68,7 @@ NearestNodeLocator::findNodes()
* If this is the first time through we're going to build up a "neighborhood" of nodes
* surrounding each of the secondary nodes. This will speed searching later.
*/
const std::map<dof_id_type, std::vector<dof_id_type>> & node_to_elem_map = _mesh.nodeToElemMap();
const auto & node_to_elem_map = _mesh.nodeToElemMap();

if (_first || (_reinit_iteration && _patch_update_strategy == Moose::Iteration))
{
Expand Down Expand Up @@ -294,7 +291,7 @@ NearestNodeLocator::updatePatch(std::vector<dof_id_type> & secondary_nodes)
primary_points[i] = node;
}

const std::map<dof_id_type, std::vector<dof_id_type>> & node_to_elem_map = _mesh.nodeToElemMap();
const auto & node_to_elem_map = _mesh.nodeToElemMap();

// Create object kd_tree of class KDTree using the coordinates of trial
// primary nodes.
Expand Down
3 changes: 0 additions & 3 deletions framework/src/geomsearch/PenetrationLocator.C
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,6 @@ PenetrationLocator::PenetrationLocator(SubProblem & subproblem,
"nodal_normal_z variables must exist. Are you missing the \\[NodalNormals\\] block?");
}
}

// Request the nodeToElem map upfront
_mesh.nodeToElemMap();
}

PenetrationLocator::~PenetrationLocator()
Expand Down
2 changes: 1 addition & 1 deletion framework/src/geomsearch/PenetrationThread.C
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ PenetrationThread::PenetrationThread(
std::vector<std::vector<FEBase *>> & fes,
FEType & fe_type,
NearestNodeLocator & nearest_node,
const std::map<dof_id_type, std::vector<dof_id_type>> & node_to_elem_map)
const std::unordered_map<dof_id_type, std::vector<dof_id_type>> & node_to_elem_map)
: _subproblem(subproblem),
_mesh(mesh),
_primary_boundary(primary_boundary),
Expand Down
2 changes: 1 addition & 1 deletion framework/src/geomsearch/SecondaryNeighborhoodThread.C
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
SecondaryNeighborhoodThread::SecondaryNeighborhoodThread(
const MooseMesh & mesh,
const std::vector<dof_id_type> & trial_primary_nodes,
const std::map<dof_id_type, std::vector<dof_id_type>> & node_to_elem_map,
const std::unordered_map<dof_id_type, std::vector<dof_id_type>> & node_to_elem_map,
const unsigned int patch_size,
KDTree & kd_tree)
: _kd_tree(kd_tree),
Expand Down
2 changes: 1 addition & 1 deletion framework/src/loops/BoundaryNodeIntegrityCheckThread.C
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ BoundaryNodeIntegrityCheckThread::BoundaryNodeIntegrityCheckThread(
_nodal_vec_aux(_aux_sys.nodalVectorAuxWarehouse()),
_nodal_array_aux(_aux_sys.nodalArrayAuxWarehouse()),
_query(query),
_node_to_elem_map(fe_problem.mesh().nodeToActiveSemilocalElemMap())
_node_to_elem_map(fe_problem.mesh().nodeToElemMap())
{
}

Expand Down
72 changes: 16 additions & 56 deletions framework/src/mesh/MooseMesh.C
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,6 @@ MooseMesh::MooseMesh(const InputParameters & parameters)
_skip_refine_when_use_split(getParam<bool>("skip_refine_when_use_split")),
_skip_deletion_repartition_after_refine(false),
_is_nemesis(false),
_node_to_elem_map_built(false),
_node_to_active_semilocal_elem_map_built(false),
_patch_size(getParam<unsigned int>("patch_size")),
_ghosting_patch_size(isParamValid("ghosting_patch_size")
? getParam<unsigned int>("ghosting_patch_size")
Expand Down Expand Up @@ -309,8 +307,6 @@ MooseMesh::MooseMesh(const MooseMesh & other_mesh)
_skip_refine_when_use_split(other_mesh._skip_refine_when_use_split),
_skip_deletion_repartition_after_refine(other_mesh._skip_deletion_repartition_after_refine),
_is_nemesis(other_mesh._is_nemesis),
_node_to_elem_map_built(false),
_node_to_active_semilocal_elem_map_built(false),
_patch_size(other_mesh._patch_size),
_ghosting_patch_size(other_mesh._ghosting_patch_size),
_max_leaf_size(other_mesh._max_leaf_size),
Expand Down Expand Up @@ -633,9 +629,13 @@ MooseMesh::update()
// Rebuild the boundary conditions
buildNodeListFromSideList();

// Clear the node to elem maps
// Capture whether the map needs rebuilding, then invalidate the stale data.
// We use clear() rather than destroying the container so that any stored references
// to _node_to_elem_map (e.g. in NodeFaceConstraint) remain valid through the window
// between the clear and the rebuild at the end of this function.
const bool rebuild_node_to_elem_map = _node_to_elem_map_built;
_node_to_elem_map.clear();
_node_to_active_semilocal_elem_map.clear();
_node_to_elem_map_built = false;

buildNodeList();
buildBndElemList();
Expand Down Expand Up @@ -669,19 +669,10 @@ MooseMesh::update()

_finite_volume_info_dirty = true;

// Rebuild the node to elem maps, in case the object(s) who got references to the maps
// actually do need to use them
if (_node_to_elem_map_built)
{
// it won't stay false
_node_to_elem_map_built = false;
// Rebuild the node to elem map, in case the object(s) who got references to the map
// actually do need to use it
if (rebuild_node_to_elem_map)
nodeToElemMap();
}
if (_node_to_active_semilocal_elem_map_built)
{
_node_to_active_semilocal_elem_map_built = false;
nodeToActiveSemilocalElemMap();
}
}

void
Expand Down Expand Up @@ -1227,8 +1218,8 @@ MooseMesh::buildBndElemList()
}
}

const std::map<dof_id_type, std::vector<dof_id_type>> &
MooseMesh::nodeToElemMap()
std::unordered_map<dof_id_type, std::vector<dof_id_type>> &
MooseMesh::internalNodeToElemMap()
{
if (!_node_to_elem_map_built) // Guard the creation with a double checked lock
{
Expand All @@ -1245,6 +1236,7 @@ MooseMesh::nodeToElemMap()
TIME_SECTION("nodeToElemMap", 5, "Building Node To Elem Map");
Threads::in_threads = in_threads;

mooseAssert(_node_to_elem_map.empty(), "Expected empty map before building");
for (const auto & elem : getMesh().active_element_ptr_range())
for (unsigned int n = 0; n < elem->n_nodes(); n++)
_node_to_elem_map[elem->node_id(n)].push_back(elem->id());
Expand All @@ -1255,36 +1247,10 @@ MooseMesh::nodeToElemMap()
return _node_to_elem_map;
}

const std::map<dof_id_type, std::vector<dof_id_type>> &
MooseMesh::nodeToActiveSemilocalElemMap()
const std::unordered_map<dof_id_type, std::vector<dof_id_type>> &
MooseMesh::nodeToElemMap()
{
if (!_node_to_active_semilocal_elem_map_built) // Guard the creation with a double checked lock
{
Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);

// This is allowing the timing to be run even with threads
// This is safe because all threads will be waiting on this section when it runs
// NOTE: Do not copy this construction to other places without thinking REALLY hard about it
// The PerfGraph is NOT threadsafe and will cause all kinds of havok if care isn't taken
auto in_threads = Threads::in_threads;
Threads::in_threads = false;
TIME_SECTION("nodeToActiveSemilocalElemMap", 5, "Building SemiLocalElemMap");
Threads::in_threads = in_threads;

if (!_node_to_active_semilocal_elem_map_built)
{
for (const auto & elem :
as_range(getMesh().semilocal_elements_begin(), getMesh().semilocal_elements_end()))
if (elem->active())
for (unsigned int n = 0; n < elem->n_nodes(); n++)
_node_to_active_semilocal_elem_map[elem->node_id(n)].push_back(elem->id());

_node_to_active_semilocal_elem_map_built =
true; // MUST be set at the end for double-checked locking to work!
}
}

return _node_to_active_semilocal_elem_map;
return internalNodeToElemMap();
}

ConstElemRange *
Expand Down Expand Up @@ -1687,13 +1653,7 @@ MooseMesh::addQuadratureNode(const Elem * elem,
_elem_to_side_to_qp_to_quadrature_nodes[elem->id()][side][qp] = qnode;

if (elem->active())
{
// If they have not been built, no need to start building an incomplete one
if (_node_to_elem_map_built)
_node_to_elem_map[new_id].push_back(elem->id());
if (_node_to_active_semilocal_elem_map_built)
_node_to_active_semilocal_elem_map[new_id].push_back(elem->id());
}
internalNodeToElemMap()[new_id].push_back(elem->id());
}
else
qnode = _elem_to_side_to_qp_to_quadrature_nodes[elem->id()][side][qp];
Expand Down
2 changes: 1 addition & 1 deletion framework/src/problems/FEProblemBase.C
Original file line number Diff line number Diff line change
Expand Up @@ -1415,7 +1415,7 @@ FEProblemBase::initialSetup()
Threads::parallel_reduce(bnd_nodes, bnict);

// Nodal bcs aren't threaded
const auto & node_to_elem_map = _mesh.nodeToActiveSemilocalElemMap();
const auto & node_to_elem_map = _mesh.nodeToElemMap();
for (const auto & bnode : bnd_nodes)
{
const auto boundary_id = bnode->_bnd_id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1497,7 +1497,7 @@ FeatureFloodCount::isNewFeatureOrConnectedRegion(const DofObject * dof_object,
void
FeatureFloodCount::expandPointHalos()
{
const auto & node_to_elem_map = _mesh.nodeToActiveSemilocalElemMap();
const auto & node_to_elem_map = _mesh.nodeToElemMap();
FeatureData::container_type expanded_local_ids;
auto my_processor_id = processor_id();

Expand Down
3 changes: 1 addition & 2 deletions modules/phase_field/src/userobjects/EBSDReader.C
Original file line number Diff line number Diff line change
Expand Up @@ -468,8 +468,7 @@ EBSDReader::buildNodeWeightMaps()
// Import nodeToElemMap from MooseMesh for current node
// This map consists of the node index followed by a vector of element indices that are associated
// with that node
const std::map<dof_id_type, std::vector<dof_id_type>> & node_to_elem_map =
_mesh.nodeToActiveSemilocalElemMap();
const auto & node_to_elem_map = _mesh.nodeToElemMap();
libMesh::MeshBase & mesh = _mesh.getMesh();

// Loop through each node in mesh and calculate eta values for each grain associated with the node
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -488,8 +488,7 @@ CrackFrontDefinition::orderCrackFrontNodes(std::set<dof_id_type> & nodes)
// set_intersection.
// The original map contains vectors, and we can't sort them, so we create sets in the local
// map.
const std::map<dof_id_type, std::vector<dof_id_type>> & node_to_elem_map =
_mesh.nodeToElemMap();
const auto & node_to_elem_map = _mesh.nodeToElemMap();
std::map<dof_id_type, std::set<dof_id_type>> crack_front_node_to_elem_map;

for (const auto & node_id : nodes)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Component1DJunction::setupMesh()
// name the sideset corresponding to the sides of all connected component ends
boundary_info.sideset_name(boundary_id) = name();

const std::map<dof_id_type, std::vector<dof_id_type>> & node_to_elem = mesh().nodeToElemMap();
const auto & node_to_elem = mesh().nodeToElemMap();
for (auto & nid : _nodes)
{
const auto & it = node_to_elem.find(nid);
Expand Down
Loading