Skip to content
Open
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
17 changes: 15 additions & 2 deletions include/mesh/mesh_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,16 @@ class MeshBase : public ParallelObject
void unset_has_boundary_id_sets()
{ _preparation.has_boundary_id_sets = false; }

/**
* Tells this we have done some operation which may have left the
* subdomain id to name map inconsistent across processors.
*
* User code which adds or changes subdomain names should call this
* method.
*/
void unset_has_synched_subdomain_name_map()
{ _preparation.has_synched_subdomain_name_map = false; }

/**
* \returns \p true if all elements and nodes of the mesh
* exist on the current processor, \p false otherwise
Expand Down Expand Up @@ -1892,7 +1902,7 @@ class MeshBase : public ParallelObject
* \returns A writable reference to the whole subdomain name map
*/
std::map<subdomain_id_type, std::string> & set_subdomain_name_map ()
{ return _block_id_to_name; }
{ this->unset_has_synched_subdomain_name_map(); return _block_id_to_name; }
const std::map<subdomain_id_type, std::string> & get_subdomain_name_map () const
{ return _block_id_to_name; }

Expand Down Expand Up @@ -1988,7 +1998,9 @@ class MeshBase : public ParallelObject
* subdomain ids, but distributed mesh generators may only know
* about part of a mesh when creating names. This method can
* synchronize the subdomain id to name map across processors,
* assuming no conflicts exist.
* assuming no conflicts exist. It is called automatically during
* complete_preparation() unless the map is already known to be
* synchronized.
*/
void sync_subdomain_name_map();

Expand Down Expand Up @@ -2077,6 +2089,7 @@ class MeshBase : public ParallelObject
bool has_removed_orphaned_nodes;
bool has_boundary_id_sets;
bool has_reinit_ghosting_functors;
bool has_synched_subdomain_name_map;
};

protected:
Expand Down
4 changes: 2 additions & 2 deletions src/mesh/distributed_mesh.C
Original file line number Diff line number Diff line change
Expand Up @@ -202,15 +202,15 @@ DistributedMesh::DistributedMesh (const MeshBase & other_mesh) :

this->copy_constraint_rows(other_mesh);

this->_preparation = other_mesh.preparation();

auto & this_boundary_info = this->get_boundary_info();
const auto & other_boundary_info = other_mesh.get_boundary_info();

this_boundary_info = other_boundary_info;

this->set_subdomain_name_map() = other_mesh.get_subdomain_name_map();

this->_preparation = other_mesh.preparation();

#ifdef LIBMESH_ENABLE_UNIQUE_ID
_next_unique_id = other_mesh.parallel_max_unique_id() +
this->processor_id();
Expand Down
19 changes: 17 additions & 2 deletions src/mesh/mesh_base.C
Original file line number Diff line number Diff line change
Expand Up @@ -938,6 +938,13 @@ void MeshBase::complete_preparation()
if (!_preparation.has_cached_elem_data)
this->cache_elem_data();

// libMesh expects every processor to know about every subdomain
// name, but distributed mesh generators may only have set names for
// the part of the mesh they know about, so make sure the map is
// consistent everywhere.
if (!_preparation.has_synched_subdomain_name_map)
this->sync_subdomain_name_map();

// Search the mesh for elements that have a neighboring element
// of dim+1 and set that element as the interior parent
if (!_preparation.has_interior_parent_ptrs)
Expand Down Expand Up @@ -1879,6 +1886,7 @@ bool MeshBase::get_count_lower_dim_elems_in_point_locator() const

std::string & MeshBase::subdomain_name(subdomain_id_type id)
{
this->unset_has_synched_subdomain_name_map();
return _block_id_to_name[id];
}

Expand Down Expand Up @@ -2043,6 +2051,8 @@ void MeshBase::sync_subdomain_name_map()
parallel_object_only();

this->comm().set_union(_block_id_to_name);

_preparation.has_synched_subdomain_name_map = true;
}


Expand Down Expand Up @@ -2809,7 +2819,8 @@ MeshBase::Preparation::Preparation() :
has_removed_remote_elements(false),
has_removed_orphaned_nodes(false),
has_boundary_id_sets(false),
has_reinit_ghosting_functors(false)
has_reinit_ghosting_functors(false),
has_synched_subdomain_name_map(false)
{}

MeshBase::Preparation::operator bool() const
Expand All @@ -2822,7 +2833,8 @@ MeshBase::Preparation::operator bool() const
has_removed_remote_elements &&
has_removed_orphaned_nodes &&
has_reinit_ghosting_functors &&
has_boundary_id_sets;
has_boundary_id_sets &&
has_synched_subdomain_name_map;
}

MeshBase::Preparation &
Expand All @@ -2837,6 +2849,7 @@ MeshBase::Preparation::operator= (bool set_all)
has_removed_orphaned_nodes = set_all;
has_reinit_ghosting_functors = set_all;
has_boundary_id_sets = set_all;
has_synched_subdomain_name_map = set_all;

return *this;
}
Expand All @@ -2862,6 +2875,8 @@ MeshBase::Preparation::operator== (const Preparation & other) const
return false;
if (has_boundary_id_sets != other.has_boundary_id_sets)
return false;
if (has_synched_subdomain_name_map != other.has_synched_subdomain_name_map)
return false;

return true;
}
Expand Down
4 changes: 2 additions & 2 deletions src/mesh/replicated_mesh.C
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,15 @@ ReplicatedMesh::ReplicatedMesh (const MeshBase & other_mesh) :

this->copy_constraint_rows(other_mesh);

this->_preparation = other_mesh.preparation();

auto & this_boundary_info = this->get_boundary_info();
const auto & other_boundary_info = other_mesh.get_boundary_info();

this_boundary_info = other_boundary_info;

this->set_subdomain_name_map() = other_mesh.get_subdomain_name_map();

this->_preparation = other_mesh.preparation();

// If other_mesh is distributed, then we've got parts of it on each
// processor but we're not replicated yet; fix that.
if (!other_mesh.is_serial())
Expand Down