@@ -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.
0 commit comments