Skip to content

Commit fbc1cb5

Browse files
committed
Make is_prepared more fine-grained
1 parent 71fc72d commit fbc1cb5

File tree

6 files changed

+236
-50
lines changed

6 files changed

+236
-50
lines changed

include/mesh/mesh_base.h

Lines changed: 156 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ class MeshBase : public ParallelObject
145145
virtual ~MeshBase ();
146146

147147
/**
148-
* A partitioner to use at each prepare_for_use()
148+
* A partitioner to use at each partitioning
149149
*/
150150
virtual std::unique_ptr<Partitioner> & partitioner() { return _partitioner; }
151151

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

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

191191
/**
192-
* Tells this we have done some operation where we should no longer consider ourself prepared
192+
* Tells this we have done some operation where we should no longer
193+
* consider ourself prepared. This is a very coarse setting; it may
194+
* be preferable to mark finer-grained settings instead.
193195
*/
194196
void set_isnt_prepared()
195-
{ _is_prepared = false; }
197+
{ _preparation = false; }
198+
199+
/**
200+
* Tells this we have done some operation creating unpartitioned
201+
* elements.
202+
*/
203+
void set_isnt_partitioned()
204+
{ _preparation.is_partitioned = false; }
205+
206+
/**
207+
* Tells this we have done some operation (e.g. adding elements to a
208+
* distributed mesh on one processor only) which can lose
209+
* synchronization of id counts.
210+
*/
211+
void set_hasnt_synched_id_counts()
212+
{ _preparation.has_synched_id_counts = false; }
213+
214+
/**
215+
* Tells this we have done some operation (e.g. adding elements
216+
* without setting their neighbor pointers) which requires neighbor
217+
* pointers to be found later
218+
*/
219+
void set_hasnt_neighbor_ptrs()
220+
{ _preparation.has_neighbor_ptrs = false; }
221+
222+
/**
223+
* Tells this we have done some operation (e.g. adding elements with
224+
* a new dimension or subdomain value) which may invalidate cached
225+
* summaries of element data
226+
*/
227+
void set_hasnt_cached_elem_data()
228+
{ _preparation.has_cached_elem_data = false; }
229+
230+
/**
231+
* Tells this we have done some operation (e.g. refining elements
232+
* with interior parents) which requires interior parent pointers to
233+
* be found later
234+
*/
235+
void set_hasnt_interior_parent_ptrs()
236+
{ _preparation.has_interior_parent_ptrs = false; }
237+
238+
/**
239+
* Tells this we have done some operation (e.g. repartitioning)
240+
* which may have left elements as ghosted which on a distributed
241+
* mesh should be remote.
242+
*
243+
* User code should probably never need to use this; we can set it
244+
* in Partitioner.
245+
*/
246+
void set_hasnt_removed_remote_elements()
247+
{ _preparation.has_removed_remote_elements = false; }
248+
249+
/**
250+
* Tells this we have done some operation (e.g. coarsening)
251+
* which may have left orphaned nodes in need of removal.
252+
*
253+
* Most user code should probably never need to use this; we can set
254+
* it in MeshRefinement.
255+
*/
256+
void set_hasnt_removed_orphaned_nodes()
257+
{ _preparation.has_removed_orphaned_nodes = false; }
258+
259+
/**
260+
* Tells this we have done some operation (e.g. adding or removing
261+
* elements) which may require a reinit() of custom ghosting
262+
* functors.
263+
*/
264+
void hasnt_reinit_ghosting_functors()
265+
{ _preparation.has_reinit_ghosting_functors = false; }
266+
267+
/**
268+
* Tells this we have done some operation (e.g. removing elements or
269+
* adding new boundary entries) which may have invalidated our
270+
* cached boundary id sets.
271+
*/
272+
void set_hasnt_boundary_id_sets()
273+
{ _preparation.has_boundary_id_sets = false; }
196274

197275
/**
198276
* \returns \p true if all elements and nodes of the mesh
@@ -240,7 +318,9 @@ class MeshBase : public ParallelObject
240318
* except for "ghosts" which touch a local element, and deletes
241319
* all nodes which are not part of a local or ghost element
242320
*/
243-
virtual void delete_remote_elements () {}
321+
virtual void delete_remote_elements () {
322+
_preparation.has_removed_remote_elements = true;
323+
}
244324

245325
/**
246326
* Loops over ghosting functors and calls mesh_reinit()
@@ -727,7 +807,7 @@ class MeshBase : public ParallelObject
727807
* To ensure a specific element id, call e->set_id() before adding it;
728808
* only do this in parallel if you are manually keeping ids consistent.
729809
*
730-
* Users should call MeshBase::prepare_for_use() after elements are
810+
* Users should call MeshBase::complete_preparation() after elements are
731811
* added to and/or deleted from the mesh.
732812
*/
733813
virtual Elem * add_elem (Elem * e) = 0;
@@ -746,7 +826,7 @@ class MeshBase : public ParallelObject
746826
* Insert elem \p e to the element array, preserving its id
747827
* and replacing/deleting any existing element with the same id.
748828
*
749-
* Users should call MeshBase::prepare_for_use() after elements are
829+
* Users should call MeshBase::complete_preparation() after elements are
750830
* added to and/or deleted from the mesh.
751831
*/
752832
virtual Elem * insert_elem (Elem * e) = 0;
@@ -765,8 +845,8 @@ class MeshBase : public ParallelObject
765845
* Removes element \p e from the mesh. This method must be
766846
* implemented in derived classes in such a way that it does not
767847
* invalidate element iterators. Users should call
768-
* MeshBase::prepare_for_use() after elements are added to and/or
769-
* deleted from the mesh.
848+
* MeshBase::complete_preparation() after elements are added to
849+
* and/or deleted from the mesh.
770850
*
771851
* \note Calling this method may produce isolated nodes, i.e. nodes
772852
* not connected to any element.
@@ -833,7 +913,7 @@ class MeshBase : public ParallelObject
833913

834914
/**
835915
* Removes any orphaned nodes, nodes not connected to any elements.
836-
* Typically done automatically in prepare_for_use
916+
* Typically done automatically in a preparation step
837917
*/
838918
void remove_orphaned_nodes ();
839919

@@ -1107,12 +1187,19 @@ class MeshBase : public ParallelObject
11071187
const std::vector<T> * default_values = nullptr);
11081188

11091189
/**
1110-
* Prepare a newly ecreated (or read) mesh for use.
1111-
* This involves 4 steps:
1112-
* 1.) call \p find_neighbors()
1113-
* 2.) call \p partition()
1114-
* 3.) call \p renumber_nodes_and_elements()
1115-
* 4.) call \p cache_elem_data()
1190+
* Prepare a newly created (or read) mesh for use.
1191+
* This involves several steps:
1192+
* 1.) renumbering (if enabled)
1193+
* 2.) removing any orphaned nodes
1194+
* 3.) updating parallel id counts
1195+
* 4.) finding neighbor links
1196+
* 5.) caching summarized element data
1197+
* 6.) finding interior parent links
1198+
* 7.) clearing any old point locator
1199+
* 8.) calling reinit() on ghosting functors
1200+
* 9.) repartitioning (if enabled)
1201+
* 10.) removing any remote elements (if enabled)
1202+
* 11.) regenerating summarized boundary id sets
11161203
*
11171204
* The argument to skip renumbering is now deprecated - to prevent a
11181205
* mesh from being renumbered, set allow_renumbering(false). The argument to skip
@@ -1127,6 +1214,15 @@ class MeshBase : public ParallelObject
11271214
void prepare_for_use (const bool skip_renumber_nodes_and_elements);
11281215
void prepare_for_use ();
11291216

1217+
/*
1218+
* Prepare a newly created or modified mesh for use.
1219+
*
1220+
* Unlike \p prepare_for_use(), \p complete_preparation() performs
1221+
* *only* those preparatory steps that have been marked as
1222+
* necessary in the MeshBase::Preparation state.
1223+
*/
1224+
void complete_preparation();
1225+
11301226
/**
11311227
* Call the default partitioner (currently \p metis_partition()).
11321228
*/
@@ -1786,9 +1882,47 @@ class MeshBase : public ParallelObject
17861882
unsigned char _default_mapping_data;
17871883

17881884
/**
1789-
* Flag indicating if the mesh has been prepared for use.
1790-
*/
1791-
bool _is_prepared;
1885+
* Flags indicating in what ways the mesh has been prepared for use.
1886+
*/
1887+
struct Preparation {
1888+
bool is_partitioned = false,
1889+
has_synched_id_counts = false,
1890+
has_neighbor_ptrs = false,
1891+
has_cached_elem_data = false,
1892+
has_interior_parent_ptrs = false,
1893+
has_removed_remote_elements = false,
1894+
has_removed_orphaned_nodes = false,
1895+
has_boundary_id_sets = false,
1896+
has_reinit_ghosting_functors = false;
1897+
1898+
operator bool() const {
1899+
return is_partitioned &&
1900+
has_synched_id_counts &&
1901+
has_neighbor_ptrs &&
1902+
has_cached_elem_data &&
1903+
has_interior_parent_ptrs &&
1904+
has_removed_remote_elements &&
1905+
has_removed_orphaned_nodes &&
1906+
has_reinit_ghosting_functors &&
1907+
has_boundary_id_sets;
1908+
}
1909+
1910+
Preparation & operator= (bool set_all) {
1911+
is_partitioned = set_all;
1912+
has_synched_id_counts = set_all;
1913+
has_neighbor_ptrs = set_all;
1914+
has_cached_elem_data = set_all;
1915+
has_interior_parent_ptrs = set_all;
1916+
has_removed_remote_elements = set_all;
1917+
has_removed_orphaned_nodes = set_all;
1918+
has_reinit_ghosting_functors = set_all;
1919+
has_boundary_id_sets = set_all;
1920+
1921+
return *this;
1922+
}
1923+
};
1924+
1925+
Preparation _preparation;
17921926

17931927
/**
17941928
* A \p PointLocator class for this mesh.

src/mesh/boundary_info.C

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,8 @@ void BoundaryInfo::regenerate_id_sets()
421421
_communicator.set_union(_es_id_to_name);
422422
_communicator.set_union(_global_boundary_ids);
423423
}
424+
425+
_mesh->_preparation.has_boundary_id_sets = true;
424426
}
425427

426428

src/mesh/distributed_mesh.C

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,8 @@ void DistributedMesh::update_parallel_id_counts()
289289
((_next_unique_id + this->n_processors() - 1) / (this->n_processors() + 1) + 1) *
290290
(this->n_processors() + 1) + this->processor_id();
291291
#endif
292+
293+
this->_preparation.has_synched_id_counts = true;
292294
}
293295

294296

@@ -1620,6 +1622,8 @@ void DistributedMesh::renumber_nodes_and_elements ()
16201622
}
16211623
}
16221624

1625+
this->_preparation.has_removed_orphaned_nodes = true;
1626+
16231627
if (_skip_renumber_nodes_and_elements)
16241628
{
16251629
this->update_parallel_id_counts();
@@ -1780,6 +1784,8 @@ void DistributedMesh::delete_remote_elements()
17801784
this->libmesh_assert_valid_parallel_ids();
17811785
this->libmesh_assert_valid_parallel_flags();
17821786
#endif
1787+
1788+
this->_preparation.has_removed_remote_elements = true;
17831789
}
17841790

17851791

0 commit comments

Comments
 (0)