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 Oct 27, 2020
1 parent 2ef08d8 commit c4f5876
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 64 deletions.
21 changes: 4 additions & 17 deletions framework/include/mesh/MooseMesh.h
Expand Up @@ -327,18 +327,11 @@ 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);

/**
* If this method is called, we will call libMesh's prepare_for_use method when we
* call Moose's prepare method. This should only be set when the mesh structure is changed
* by MeshGenerators (i.e. Element deletion).
*/
void needsPrepareForUse();

/**
* Declares that the MooseMesh has changed, invalidates cached data
* and rebuilds caches. Sets a flag so that clients of the
Expand Down Expand Up @@ -460,10 +453,10 @@ 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.
*/
void prepare(bool force = false);
void prepare();

/**
* Calls buildNodeListFromSideList(), buildNodeList(), and buildBndElemList().
Expand Down Expand Up @@ -1120,12 +1113,6 @@ class MooseMesh : public MooseObject, public Restartable, public PerfGraphInterf
/// True if a Nemesis Mesh was read in
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;

/// The elements that were just refined.
std::unique_ptr<ConstElemPointerRange> _refined_elements;

Expand Down
7 changes: 2 additions & 5 deletions framework/src/actions/SetupMeshCompleteAction.C
Expand Up @@ -41,12 +41,9 @@ SetupMeshCompleteAction::SetupMeshCompleteAction(InputParameters params)
bool
SetupMeshCompleteAction::completeSetup(MooseMesh * mesh)
{
bool prepared = mesh->prepared();
mesh->prepare();

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

return prepared;
return true;
}

void
Expand Down
56 changes: 14 additions & 42 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,32 +354,14 @@ MooseMesh::freeBndElems()
}

void
MooseMesh::prepare(bool force)
MooseMesh::prepare()
{
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");

getMesh().prepare_for_use();
}
}
else
{
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();
}
if (!_mesh->is_prepared())
_mesh->prepare_for_use();

// Collect (local) subdomain IDs
_mesh_subdomains.clear();
Expand Down Expand Up @@ -417,10 +395,6 @@ MooseMesh::prepare(bool force)
detectOrthogonalDimRanges();

update();

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

void
Expand Down Expand Up @@ -2499,26 +2473,24 @@ MooseMesh::queryElemPtr(const dof_id_type i) const
bool
MooseMesh::prepared() const
{
return _is_prepared;
return _mesh->is_prepared();
}

void
MooseMesh::prepared(bool state)
{
_is_prepared = state;

/**
* 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;
}
{
_mesh->set_isnt_prepared();

void
MooseMesh::needsPrepareForUse()
{
_needs_prepare_for_use = true;
/**
* 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.
*/
_regular_orthogonal_mesh = false;
}
// Else 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
}

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 c4f5876

Please sign in to comment.