Skip to content

Commit

Permalink
Use MeshBase data to inform us when we should prepare
Browse files Browse the repository at this point in the history
We also can signal to the `MeshBase` object if we've done some
operation that renders the mesh unprepared. If we do this meticulously
then we can trust checks of the `is_prepared` flag to tell us when we
need to `prepare_for_use` or not

Closes idaholab#15944 idaholab#15936 idaholab#15823
  • Loading branch information
lindsayad committed Dec 28, 2020
1 parent 3abace8 commit 2cffa53
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 52 deletions.
3 changes: 0 additions & 3 deletions framework/include/actions/SetupMeshCompleteAction.h
Expand Up @@ -23,10 +23,7 @@ class SetupMeshCompleteAction : public Action

SetupMeshCompleteAction(InputParameters params);

bool completeSetup(MooseMesh * mesh);

virtual void act() override;

PerfID _uniform_refine_timer;
};

14 changes: 6 additions & 8 deletions framework/include/mesh/MooseMesh.h
Expand Up @@ -327,7 +327,7 @@ class MooseMesh : public MooseObject, public Restartable, public PerfGraphInterf
virtual const Elem * queryElemPtr(const dof_id_type i) const;

/**
* Setter/getter for the _is_prepared flag.
* Setter/getter for whether the mesh is prepared
*/
bool prepared() const;
virtual void prepared(bool state);
Expand Down Expand Up @@ -460,10 +460,11 @@ class MooseMesh : public MooseObject, public Restartable, public PerfGraphInterf
const RealVectorValue & getNormalByBoundaryID(BoundaryID id) const;

/**
* Calls prepare_for_use() if force=true on the underlying Mesh object, then communicates various
* boundary information on parallel meshes. Also calls update() internally.
* Calls prepare_for_use() if the underlying MeshBase object isn't prepared, then communicates
* various boundary information on parallel meshes. Also calls update() internally. We maintain
* the boolean parameter in order to maintain backwards compatability but it doesn't do anything
*/
void prepare(bool force = false);
void prepare(bool = false);

/**
* Calls buildNodeListFromSideList(), buildNodeList(), and buildBndElemList().
Expand Down Expand Up @@ -1121,10 +1122,7 @@ class MooseMesh : public MooseObject, public Restartable, public PerfGraphInterf
bool _is_nemesis;

/// True if prepare has been called on the mesh
bool _is_prepared;

/// True if prepare_for_use should be called when Mesh is prepared
bool _needs_prepare_for_use;
bool _moose_mesh_prepared = false;

/// The elements that were just refined.
std::unique_ptr<ConstElemPointerRange> _refined_elements;
Expand Down
15 changes: 2 additions & 13 deletions framework/src/actions/SetupMeshCompleteAction.C
Expand Up @@ -39,17 +39,6 @@ SetupMeshCompleteAction::SetupMeshCompleteAction(InputParameters params)
{
}

bool
SetupMeshCompleteAction::completeSetup(MooseMesh * mesh)
{
bool prepared = mesh->prepared();

if (!prepared)
mesh->prepare();

return prepared;
}

void
SetupMeshCompleteAction::act()
{
Expand Down Expand Up @@ -116,9 +105,9 @@ SetupMeshCompleteAction::act()
else
{
// Prepare the mesh (may occur multiple times)
completeSetup(_mesh.get());
_mesh->prepare();

if (_displaced_mesh)
completeSetup(_displaced_mesh.get());
_displaced_mesh->prepare();
}
}
51 changes: 23 additions & 28 deletions framework/src/mesh/MooseMesh.C
Expand Up @@ -169,8 +169,6 @@ MooseMesh::MooseMesh(const InputParameters & parameters)
_custom_partitioner_requested(false),
_uniform_refine_level(0),
_is_nemesis(getParam<bool>("nemesis")),
_is_prepared(false),
_needs_prepare_for_use(false),
_node_to_elem_map_built(false),
_node_to_active_semilocal_elem_map_built(false),
_patch_size(getParam<unsigned int>("patch_size")),
Expand Down Expand Up @@ -239,8 +237,6 @@ MooseMesh::MooseMesh(const MooseMesh & other_mesh)
_custom_partitioner_requested(other_mesh._custom_partitioner_requested),
_uniform_refine_level(other_mesh.uniformRefineLevel()),
_is_nemesis(false),
_is_prepared(false),
_needs_prepare_for_use(other_mesh._needs_prepare_for_use),
_node_to_elem_map_built(false),
_node_to_active_semilocal_elem_map_built(false),
_patch_size(other_mesh._patch_size),
Expand Down Expand Up @@ -358,33 +354,28 @@ MooseMesh::freeBndElems()
}

void
MooseMesh::prepare(bool force)
MooseMesh::prepare(bool)
{
TIME_SECTION(_prepare_timer);

mooseAssert(_mesh, "The MeshBase has not been constructed");

if (dynamic_cast<DistributedMesh *>(&getMesh()) && !_is_nemesis)
{
// Call prepare_for_use() and don't mess with the renumbering
// setting
if (force || _needs_prepare_for_use)
{
CONSOLE_TIMED_PRINT("Preparing for use");
if (!dynamic_cast<DistributedMesh *>(&getMesh()) || _is_nemesis)
// For whatever reason we do not want to allow renumbering here nor ever in the future?
getMesh().allow_renumbering(false);

getMesh().prepare_for_use();
}
}
else
if (!_mesh->is_prepared())
{
CONSOLE_TIMED_PRINT("Preparing for use");

// Call prepare_for_use() and DO NOT allow renumbering
getMesh().allow_renumbering(false);
if (force || _needs_prepare_for_use)
getMesh().prepare_for_use();
_mesh->prepare_for_use();

_moose_mesh_prepared = false;
}

if (_moose_mesh_prepared)
return;

// Collect (local) subdomain IDs
_mesh_subdomains.clear();
for (const auto & elem : getMesh().element_ptr_range())
Expand Down Expand Up @@ -418,9 +409,7 @@ MooseMesh::prepare(bool force)

update();

// Prepared has been called
_is_prepared = true;
_needs_prepare_for_use = false;
_moose_mesh_prepared = true;
}

void
Expand Down Expand Up @@ -2511,26 +2500,32 @@ MooseMesh::queryElemPtr(const dof_id_type i) const
bool
MooseMesh::prepared() const
{
return _is_prepared;
return _mesh->is_prepared() && _moose_mesh_prepared;
}

void
MooseMesh::prepared(bool state)
{
_is_prepared = state;
if (state)
mooseError("We don't have any right to tell the libmesh mesh that it *is* prepared. Only a "
"call to prepare_for_use should tell us that");

_mesh->set_isnt_prepared();

// If the libMesh mesh isn't preparead, then our MooseMesh wrapper is also no longer prepared
_moose_mesh_prepared = false;

/**
* If we are explicitly setting the mesh to not prepared, then we've likely modified the mesh
* and can no longer make assumptions about orthogonality. We really should recheck.
*/
if (!state)
_regular_orthogonal_mesh = false;
_regular_orthogonal_mesh = false;
}

void
MooseMesh::needsPrepareForUse()
{
_needs_prepare_for_use = true;
prepared(false);
}

const std::set<SubdomainID> &
Expand Down
2 changes: 2 additions & 0 deletions framework/src/meshgenerators/FancyExtruderGenerator.C
Expand Up @@ -562,5 +562,7 @@ FancyExtruderGenerator::generate()
}
}

mesh->set_isnt_prepared();

return mesh;
}
10 changes: 10 additions & 0 deletions framework/src/meshgenerators/SideSetsGeneratorBase.C
Expand Up @@ -64,6 +64,16 @@ SideSetsGeneratorBase::setup(MeshBase & mesh)
_fe_face = FEBase::build(dim, fe_type);
_qface = libmesh_make_unique<QGauss>(dim - 1, FIRST);
_fe_face->attach_quadrature_rule(_qface.get());

// Change this when we have more fine-grained control over advertising what we need need and how
// we satisfy those needs. For now we know we need to have neighbors...and we do have an explicit
// `find_neighbors` call...but we don't have a `neighbors_found` API and it seems off to do:
//
// if (!mesh.is_prepared())
// mesh.find_neighbors()

if (!mesh.is_prepared())
mesh.prepare_for_use();
}

void
Expand Down

0 comments on commit 2cffa53

Please sign in to comment.