Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
524704c
check_non_remote optional in find_neighbors
roystgnr Jan 28, 2026
64a176a
Check for non-remoted neighbors postredistribution
roystgnr Jan 28, 2026
3e24d00
Assert our cache is still good
roystgnr Jan 22, 2024
dec9659
Test partially-prepared status validity too
roystgnr Dec 3, 2025
221f145
More testing of preparation() validity in dbg mode
roystgnr Dec 5, 2025
387d1de
Added MeshBase::assert_equal_to
roystgnr Dec 10, 2025
a4d16a7
Add MeshTools::libmesh_assert_valid_is_prepared()
roystgnr Dec 10, 2025
29da19f
Enable !NDEBUG libmesh_assert_X as libmesh_assert
roystgnr Dec 10, 2025
23d528b
Assert that we only assemble on prepared meshes
roystgnr Dec 3, 2025
d53226e
Use libmesh_assert_valid_is_prepared()
roystgnr Dec 10, 2025
94d0314
Only enforce preparation with --disable-deprecated
roystgnr Dec 11, 2025
62a4b04
Preparation::libmesh_assert_consistent()
roystgnr Dec 18, 2025
5dc74b7
Test for parallel-consistent preparation
roystgnr Dec 18, 2025
eb170a8
Fix mesh preparation in misc ex15
roystgnr Feb 25, 2026
d18f11b
More fine-grained copy_nodes_and_elements flagging
roystgnr Feb 27, 2026
bfd0088
Assert caches are prepared before allowing queries
roystgnr Feb 27, 2026
5b2dad9
Fix PerfLog name
roystgnr Feb 27, 2026
5963d5c
Fix detect_interior_parents w/o cached elem dims
roystgnr Apr 14, 2026
a9bbd34
Update _global_boundary_ids when renumbering
roystgnr Apr 14, 2026
8ec38a1
Fix mesh flagging in MeshModification functions
roystgnr Apr 14, 2026
ba677d5
System/ES init can prepare unprepared meshes
roystgnr Apr 14, 2026
2281f8e
Handle unprepared meshes in VariationalSmoother
roystgnr Apr 14, 2026
33df539
Make test work w/redistribute() cache invalidation
roystgnr Apr 14, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,10 @@ int main (int argc, char** argv)
sync_obj);
}

// We'll need to update caches of subdomain ids too, to keep the
// mesh prepared.
mesh.cache_elem_data();

// Now we set the sources of the field: prism-shaped objects that are
// determined here by containing certain points:
auto p_pt_lctr = mesh.sub_point_locator();
Expand Down
2 changes: 1 addition & 1 deletion include/mesh/distributed_mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class DistributedMesh : public UnstructuredMesh
* Shim to allow operator == (&) to behave like a virtual function
* without having to be one.
*/
virtual bool subclass_locally_equals (const MeshBase & other_mesh) const override;
virtual std::string_view subclass_first_difference_from (const MeshBase & other_mesh_base) const override;

/**
* Virtual copy-constructor, creates a copy of this mesh
Expand Down
87 changes: 74 additions & 13 deletions include/mesh/mesh_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ class MeshBase : public ParallelObject
* ids).
*
* Though this method is non-virtual, its implementation calls the
* virtual function \p subclass_locally_equals() to test for
* virtual function \p subclass_first_difference_from() to test for
* equality of subclass-specific data as well.
*/
bool operator== (const MeshBase & other_mesh) const;
Expand All @@ -145,6 +145,14 @@ class MeshBase : public ParallelObject
return !(*this == other_mesh);
}

/**
* This behaves like libmesh_assert(*this == other_mesh), but gives
* a more useful accounting of the first difference found, if the
* assertion fails.
*/
void assert_equal_to (const MeshBase & other_mesh,
std::string_view failure_context) const;

/**
* This behaves the same as operator==, but only for the local and
* ghosted aspects of the mesh; i.e. operator== is true iff local
Expand Down Expand Up @@ -239,8 +247,7 @@ class MeshBase : public ParallelObject
* consider ourself prepared. This is a very coarse setting; it is
* generally more efficient to mark finer-grained settings instead.
*/
void unset_is_prepared()
{ _preparation = false; }
void unset_is_prepared();

/**
* Tells this we have done some operation creating unpartitioned
Expand Down Expand Up @@ -423,23 +430,20 @@ class MeshBase : public ParallelObject
* \returns A const reference to a std::set of element dimensions
* present in the mesh.
*/
const std::set<unsigned char> & elem_dimensions() const
{ return _elem_dims; }
const std::set<unsigned char> & elem_dimensions() const;

/**
* \returns A const reference to a std::set of element default
* orders present in the mesh.
*/
const std::set<Order> & elem_default_orders() const
{ return _elem_default_orders; }
const std::set<Order> & elem_default_orders() const;

/**
* \returns The smallest supported_nodal_order() of any element
* present in the mesh, which is thus the maximum supported nodal
* order on the mesh as a whole.
*/
Order supported_nodal_order() const
{ return _supported_nodal_order; }
Order supported_nodal_order() const;

/**
* Most of the time you should not need to call this, as the element
Expand Down Expand Up @@ -982,10 +986,17 @@ class MeshBase : public ParallelObject
*
* If \p assert_valid is left as true, then in dbg mode extensive
* consistency checking is performed before returning.
*
* If \p check_non_remote is set to false, then only sides which
* currently have remote neighbors are checked for possible local
* neighbors. This is intended to handle a corner case where
* ancestor neighbors are redistributed to a processor only by other
* processors who do not see that neighbor link.
*/
virtual void find_neighbors (const bool reset_remote_elements = false,
const bool reset_current_list = true,
const bool assert_valid = true) = 0;
const bool assert_valid = true,
const bool check_non_remote = true) = 0;

/**
* Removes any orphaned nodes, nodes not connected to any elements.
Expand Down Expand Up @@ -1997,8 +2008,7 @@ class MeshBase : public ParallelObject
* should contain all the subdomain ids across processors. Relies on the mesh
* being prepared
*/
const std::set<subdomain_id_type> & get_mesh_subdomains() const
{ libmesh_assert(this->is_prepared()); return _mesh_subdomains; }
const std::set<subdomain_id_type> & get_mesh_subdomains() const;

#ifdef LIBMESH_ENABLE_PERIODIC
/**
Expand Down Expand Up @@ -2043,6 +2053,9 @@ class MeshBase : public ParallelObject
bool operator== (const Preparation & other) const;
bool operator!= (const Preparation & other) const;

// Assert that a Preparation object is identical across processors
void libmesh_assert_consistent (const Parallel::Communicator & libmesh_dbg_var(comm));

bool is_partitioned;
bool has_synched_id_counts;
bool has_neighbor_ptrs;
Expand Down Expand Up @@ -2092,14 +2105,20 @@ class MeshBase : public ParallelObject
* Shim to allow operator == (&) to behave like a virtual function
* without having to be one.
*/
virtual bool subclass_locally_equals (const MeshBase & other_mesh) const = 0;
virtual std::string_view subclass_first_difference_from (const MeshBase & other_mesh) const = 0;

/**
* Tests for equality of all elements and nodes in the mesh. Helper
* function for subclass_equals() in unstructured mesh subclasses.
*/
bool nodes_and_elements_equal(const MeshBase & other_mesh) const;

/**
*
*/
std::string_view first_difference_from(const MeshBase & other_mesh) const;


/**
* \returns A writable reference to the number of partitions.
*/
Expand Down Expand Up @@ -2546,6 +2565,48 @@ MeshBase::const_node_iterator : MeshBase::const_node_filter_iter
};


// ------------------------------------------------------------
// Elem class member functions
inline
const std::set<unsigned char> & MeshBase::elem_dimensions() const
{
libmesh_assert(_preparation.has_cached_elem_data);
return _elem_dims;
}


inline
const std::set<Order> & MeshBase::elem_default_orders() const
{
libmesh_assert(_preparation.has_cached_elem_data);
return _elem_default_orders;
}


inline
Order MeshBase::supported_nodal_order() const
{
libmesh_assert(_preparation.has_cached_elem_data);
return _supported_nodal_order;
}


inline
const std::set<subdomain_id_type> & MeshBase::get_mesh_subdomains() const
{
libmesh_assert(_preparation.has_cached_elem_data);
return _mesh_subdomains;
}


inline
unsigned int MeshBase::spatial_dimension () const
{
libmesh_assert(_preparation.has_cached_elem_data);

return cast_int<unsigned int>(_spatial_dimension);
}

template <typename T>
inline
unsigned int MeshBase::add_elem_datum(const std::string & name,
Expand Down
56 changes: 50 additions & 6 deletions include/mesh/mesh_tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -394,24 +394,35 @@ void clear_spline_nodes(MeshBase &);

/**
* A function for testing whether a mesh's cached is_prepared() setting
* is not a false positive. If the mesh is marked as not prepared, or
* if preparing the already-partitioned mesh (without any
* repartitioning or renumbering) does not change it, then we return
* true. If the mesh believes it is prepared but prepare_for_use()
* would change it, we return false.
* is not a false positive, and that its preparation() values are not
* false positives. If the mesh is marked as completely not prepared, or
* if preparing a already-prepared mesh (without any repartitioning or
* renumbering) or preparing after a complete_preparation() (likewise)
* does not change the mesh, then we return true. If the mesh believes it
* is prepared but prepare_for_use() would change it, or if the mesh
* believes it is partially prepared in a certain way but
* complete_preparation() does not completely prepare it, we return
* false.
*/
bool valid_is_prepared (const MeshBase & mesh);

///@{

/**
* The following functions, only available in builds with NDEBUG
* The following functions, no-ops except in builds with NDEBUG
* undefined, are for asserting internal consistency that we hope
* should never be broken in opt
*/

#ifndef NDEBUG

/**
* Like libmesh_assert(MeshTools::valid_is_prepared(mesh)), but
* provides more information on preparation incompleteness in case of
* an error.
*/
void libmesh_assert_valid_is_prepared (const MeshBase & mesh);

/**
* A function for testing that all DofObjects within a mesh
* have the same n_systems count
Expand Down Expand Up @@ -644,6 +655,39 @@ namespace Private {
void globally_renumber_nodes_and_elements (MeshBase &);
} // end namespace Private


// Declare inline no-ops for assertions with NDEBUG defined
#ifdef NDEBUG

inline void libmesh_assert_valid_is_prepared (const MeshBase &) {}

inline void libmesh_assert_equal_n_systems (const MeshBase &) {}

inline void libmesh_assert_old_dof_objects (const MeshBase &) {}

inline void libmesh_assert_valid_node_pointers (const MeshBase &) {}

inline void libmesh_assert_valid_remote_elems (const MeshBase &) {}

inline void libmesh_assert_valid_elem_ids (const MeshBase &) {}

inline void libmesh_assert_valid_amr_elem_ids (const MeshBase &) {}

inline void libmesh_assert_valid_amr_interior_parents (const MeshBase &) {}

inline void libmesh_assert_contiguous_dof_ids (const MeshBase &, unsigned int) {}

template <typename DofObjectSubclass>
inline void libmesh_assert_topology_consistent_procids (const MeshBase &) {}

inline void libmesh_assert_canonical_node_procids (const MeshBase &) {}

inline void libmesh_assert_valid_refinement_tree (const MeshBase &) {}

#endif // NDEBUG



} // end namespace MeshTools

} // namespace libMesh
Expand Down
2 changes: 1 addition & 1 deletion include/mesh/replicated_mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class ReplicatedMesh : public UnstructuredMesh
* Shim to allow operator == (&) to behave like a virtual function
* without having to be one.
*/
virtual bool subclass_locally_equals (const MeshBase & other_mesh) const override;
virtual std::string_view subclass_first_difference_from (const MeshBase & other_mesh_base) const override;

/**
* Virtual copy-constructor, creates a copy of this mesh
Expand Down
3 changes: 2 additions & 1 deletion include/mesh/unstructured_mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,8 @@ class UnstructuredMesh : public MeshBase
*/
virtual void find_neighbors (const bool reset_remote_elements = false,
const bool reset_current_list = true,
const bool assert_valid = true) override;
const bool assert_valid = true,
const bool check_non_remote = true) override;

#ifdef LIBMESH_ENABLE_AMR
/**
Expand Down
10 changes: 10 additions & 0 deletions src/mesh/boundary_info.C
Original file line number Diff line number Diff line change
Expand Up @@ -2144,6 +2144,8 @@ void BoundaryInfo::renumber_id (boundary_id_type old_id,
{
_boundary_ids.erase(old_id);
_boundary_ids.insert(new_id);
_global_boundary_ids.erase(old_id);
_global_boundary_ids.insert(new_id);
}

renumber_name(_ss_id_to_name, old_id, new_id);
Expand Down Expand Up @@ -2183,8 +2185,10 @@ void BoundaryInfo::renumber_side_id (boundary_id_type old_id,
!_node_boundary_ids.count(old_id))
{
_boundary_ids.erase(old_id);
_global_boundary_ids.erase(old_id);
}
_boundary_ids.insert(new_id);
_global_boundary_ids.insert(new_id);
}

renumber_name(_ss_id_to_name, old_id, new_id);
Expand Down Expand Up @@ -2222,8 +2226,10 @@ void BoundaryInfo::renumber_edge_id (boundary_id_type old_id,
!_node_boundary_ids.count(old_id))
{
_boundary_ids.erase(old_id);
_global_boundary_ids.erase(old_id);
}
_boundary_ids.insert(new_id);
_global_boundary_ids.insert(new_id);
}

renumber_name(_es_id_to_name, old_id, new_id);
Expand Down Expand Up @@ -2261,8 +2267,10 @@ void BoundaryInfo::renumber_shellface_id (boundary_id_type old_id,
!_node_boundary_ids.count(old_id))
{
_boundary_ids.erase(old_id);
_global_boundary_ids.erase(old_id);
}
_boundary_ids.insert(new_id);
_global_boundary_ids.insert(new_id);
}

this->libmesh_assert_valid_multimaps();
Expand Down Expand Up @@ -2298,8 +2306,10 @@ void BoundaryInfo::renumber_node_id (boundary_id_type old_id,
!_edge_boundary_ids.count(old_id))
{
_boundary_ids.erase(old_id);
_global_boundary_ids.erase(old_id);
}
_boundary_ids.insert(new_id);
_global_boundary_ids.insert(new_id);
}

renumber_name(_ns_id_to_name, old_id, new_id);
Expand Down
Loading