Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make is_prepared() more fine-grained #3759

Open
wants to merge 3 commits into
base: devel
Choose a base branch
from
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
178 changes: 156 additions & 22 deletions include/mesh/mesh_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class MeshBase : public ParallelObject
virtual ~MeshBase ();

/**
* A partitioner to use at each prepare_for_use()
* A partitioner to use at each partitioning
*/
virtual std::unique_ptr<Partitioner> & partitioner() { return _partitioner; }

Expand Down Expand Up @@ -178,25 +178,103 @@ class MeshBase : public ParallelObject
* No Node is removed from the mesh, however even NodeElem elements
* are deleted, so the remaining Nodes will be considered "unused"
* and cleared unless they are reconnected to new elements before
* the next \p prepare_for_use()
* the next preparation step.
*
* This does not affect BoundaryInfo data; any boundary information
* associated elements should already be cleared.
*/
virtual void clear_elems () = 0;

/**
* \returns \p true if the mesh has been prepared via a call
* to \p prepare_for_use, \p false otherwise.
* \returns \p true if the mesh has undergone all the preparation
* done in a call to \p prepare_for_use, \p false otherwise.
*/
bool is_prepared () const
{ return _is_prepared; }
{ return _preparation; }

/**
* Tells this we have done some operation where we should no longer consider ourself prepared
* Tells this we have done some operation where we should no longer
* consider ourself prepared. This is a very coarse setting; it may
* be preferable to mark finer-grained settings instead.
*/
void set_isnt_prepared()
{ _is_prepared = false; }
{ _preparation = false; }

/**
* Tells this we have done some operation creating unpartitioned
* elements.
*/
void set_isnt_partitioned()
{ _preparation.is_partitioned = false; }

/**
* Tells this we have done some operation (e.g. adding elements to a
* distributed mesh on one processor only) which can lose
* synchronization of id counts.
*/
void set_hasnt_synched_id_counts()
{ _preparation.has_synched_id_counts = false; }

/**
* Tells this we have done some operation (e.g. adding elements
* without setting their neighbor pointers) which requires neighbor
* pointers to be found later
*/
void set_hasnt_neighbor_ptrs()
{ _preparation.has_neighbor_ptrs = false; }

/**
* Tells this we have done some operation (e.g. adding elements with
* a new dimension or subdomain value) which may invalidate cached
* summaries of element data
*/
void set_hasnt_cached_elem_data()
{ _preparation.has_cached_elem_data = false; }

/**
* Tells this we have done some operation (e.g. refining elements
* with interior parents) which requires interior parent pointers to
* be found later
*/
void set_hasnt_interior_parent_ptrs()
{ _preparation.has_interior_parent_ptrs = false; }

/**
* Tells this we have done some operation (e.g. repartitioning)
* which may have left elements as ghosted which on a distributed
* mesh should be remote.
*
* User code should probably never need to use this; we can set it
* in Partitioner.
*/
void set_hasnt_removed_remote_elements()
{ _preparation.has_removed_remote_elements = false; }

/**
* Tells this we have done some operation (e.g. coarsening)
* which may have left orphaned nodes in need of removal.
*
* Most user code should probably never need to use this; we can set
* it in MeshRefinement.
*/
void set_hasnt_removed_orphaned_nodes()
{ _preparation.has_removed_orphaned_nodes = false; }

/**
* Tells this we have done some operation (e.g. adding or removing
* elements) which may require a reinit() of custom ghosting
* functors.
*/
void hasnt_reinit_ghosting_functors()
{ _preparation.has_reinit_ghosting_functors = false; }

/**
* Tells this we have done some operation (e.g. removing elements or
* adding new boundary entries) which may have invalidated our
* cached boundary id sets.
*/
void set_hasnt_boundary_id_sets()
{ _preparation.has_boundary_id_sets = false; }

/**
* \returns \p true if all elements and nodes of the mesh
Expand Down Expand Up @@ -244,7 +322,9 @@ class MeshBase : public ParallelObject
* except for "ghosts" which touch a local element, and deletes
* all nodes which are not part of a local or ghost element
*/
virtual void delete_remote_elements () {}
virtual void delete_remote_elements () {
_preparation.has_removed_remote_elements = true;
}

/**
* Loops over ghosting functors and calls mesh_reinit()
Expand Down Expand Up @@ -731,7 +811,7 @@ class MeshBase : public ParallelObject
* To ensure a specific element id, call e->set_id() before adding it;
* only do this in parallel if you are manually keeping ids consistent.
*
* Users should call MeshBase::prepare_for_use() after elements are
* Users should call MeshBase::complete_preparation() after elements are
* added to and/or deleted from the mesh.
*/
virtual Elem * add_elem (Elem * e) = 0;
Expand All @@ -750,7 +830,7 @@ class MeshBase : public ParallelObject
* Insert elem \p e to the element array, preserving its id
* and replacing/deleting any existing element with the same id.
*
* Users should call MeshBase::prepare_for_use() after elements are
* Users should call MeshBase::complete_preparation() after elements are
* added to and/or deleted from the mesh.
*/
virtual Elem * insert_elem (Elem * e) = 0;
Expand All @@ -769,8 +849,8 @@ class MeshBase : public ParallelObject
* Removes element \p e from the mesh. This method must be
* implemented in derived classes in such a way that it does not
* invalidate element iterators. Users should call
* MeshBase::prepare_for_use() after elements are added to and/or
* deleted from the mesh.
* MeshBase::complete_preparation() after elements are added to
* and/or deleted from the mesh.
*
* \note Calling this method may produce isolated nodes, i.e. nodes
* not connected to any element.
Expand Down Expand Up @@ -837,7 +917,7 @@ class MeshBase : public ParallelObject

/**
* Removes any orphaned nodes, nodes not connected to any elements.
* Typically done automatically in prepare_for_use
* Typically done automatically in a preparation step
*/
void remove_orphaned_nodes ();

Expand Down Expand Up @@ -1111,12 +1191,19 @@ class MeshBase : public ParallelObject
const std::vector<T> * default_values = nullptr);

/**
* Prepare a newly ecreated (or read) mesh for use.
* This involves 4 steps:
* 1.) call \p find_neighbors()
* 2.) call \p partition()
* 3.) call \p renumber_nodes_and_elements()
* 4.) call \p cache_elem_data()
* Prepare a newly created (or read) mesh for use.
* This involves several steps:
* 1.) renumbering (if enabled)
* 2.) removing any orphaned nodes
* 3.) updating parallel id counts
* 4.) finding neighbor links
* 5.) caching summarized element data
* 6.) finding interior parent links
* 7.) clearing any old point locator
* 8.) calling reinit() on ghosting functors
* 9.) repartitioning (if enabled)
* 10.) removing any remote elements (if enabled)
* 11.) regenerating summarized boundary id sets
*
* The argument to skip renumbering is now deprecated - to prevent a
* mesh from being renumbered, set allow_renumbering(false). The argument to skip
Expand All @@ -1131,6 +1218,15 @@ class MeshBase : public ParallelObject
void prepare_for_use (const bool skip_renumber_nodes_and_elements);
void prepare_for_use ();

/*
* Prepare a newly created or modified mesh for use.
*
* Unlike \p prepare_for_use(), \p complete_preparation() performs
* *only* those preparatory steps that have been marked as
* necessary in the MeshBase::Preparation state.
*/
void complete_preparation();

/**
* Call the default partitioner (currently \p metis_partition()).
*/
Expand Down Expand Up @@ -1835,9 +1931,47 @@ class MeshBase : public ParallelObject
unsigned char _default_mapping_data;

/**
* Flag indicating if the mesh has been prepared for use.
*/
bool _is_prepared;
* Flags indicating in what ways the mesh has been prepared for use.
*/
struct Preparation {
bool is_partitioned = false,
has_synched_id_counts = false,
has_neighbor_ptrs = false,
has_cached_elem_data = false,
has_interior_parent_ptrs = false,
has_removed_remote_elements = false,
has_removed_orphaned_nodes = false,
has_boundary_id_sets = false,
has_reinit_ghosting_functors = false;

operator bool() const {
return is_partitioned &&
has_synched_id_counts &&
has_neighbor_ptrs &&
has_cached_elem_data &&
has_interior_parent_ptrs &&
has_removed_remote_elements &&
has_removed_orphaned_nodes &&
has_reinit_ghosting_functors &&
has_boundary_id_sets;
}

Preparation & operator= (bool set_all) {
is_partitioned = set_all;
has_synched_id_counts = set_all;
has_neighbor_ptrs = set_all;
has_cached_elem_data = set_all;
has_interior_parent_ptrs = set_all;
has_removed_remote_elements = set_all;
has_removed_orphaned_nodes = set_all;
has_reinit_ghosting_functors = set_all;
has_boundary_id_sets = set_all;

return *this;
}
};

Preparation _preparation;

/**
* A \p PointLocator class for this mesh.
Expand Down
2 changes: 2 additions & 0 deletions src/mesh/boundary_info.C
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,8 @@ void BoundaryInfo::regenerate_id_sets()
_communicator.set_union(_es_id_to_name);
_communicator.set_union(_global_boundary_ids);
}

_mesh->_preparation.has_boundary_id_sets = true;
}


Expand Down
6 changes: 6 additions & 0 deletions src/mesh/distributed_mesh.C
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,8 @@ void DistributedMesh::update_parallel_id_counts()
((_next_unique_id + this->n_processors() - 1) / (this->n_processors() + 1) + 1) *
(this->n_processors() + 1) + this->processor_id();
#endif

this->_preparation.has_synched_id_counts = true;
}


Expand Down Expand Up @@ -1621,6 +1623,8 @@ void DistributedMesh::renumber_nodes_and_elements ()
}
}

this->_preparation.has_removed_orphaned_nodes = true;

if (_skip_renumber_nodes_and_elements)
{
this->update_parallel_id_counts();
Expand Down Expand Up @@ -1786,6 +1790,8 @@ void DistributedMesh::delete_remote_elements()
this->libmesh_assert_valid_parallel_ids();
this->libmesh_assert_valid_parallel_flags();
#endif

this->_preparation.has_removed_remote_elements = true;
}


Expand Down
Loading