libMesh
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Public Attributes | Protected Types | Protected Member Functions | Protected Attributes | Private Types | Private Member Functions | List of all members
libMesh::ParallelMesh Class Referenceabstract

#include <parallel_mesh.h>

Inheritance diagram for libMesh::ParallelMesh:
[legend]

Public Types

template<typename Obj >
using dofobject_container = mapvector< Obj *, dof_id_type >
 
using dofobject_container = chunked_mapvector< Obj *, dof_id_type, LIBMESH_MAPVECTOR_CHUNK_SIZE >
 
typedef std::set< elemset_id_type > elemset_type
 Typedef for the "set" container used to store elemset ids.
 
typedef std::vector< GhostingFunctor * >::const_iterator GhostingFunctorIterator
 Iterator type for ghosting functor ranges.
 
typedef Predicates::multi_predicate Predicate
 We need an empty, generic class to act as a predicate for this and derived mesh classes.
 
typedef StoredRange< MeshBase::const_element_iterator, const Elem * > ConstElemRange
 
typedef std::vector< std::pair< std::pair< const Elem *, unsigned int >, Real > > constraint_rows_mapped_type
 
typedef std::map< const Node *, constraint_rows_mapped_type > constraint_rows_type
 

Public Member Functions

 ParallelMesh (const Parallel::Communicator &comm_in, unsigned char dim=1)
 
 ParallelMesh (const UnstructuredMesh &other_mesh)
 
virtual std::unique_ptr< MeshBase > clone () const override
 Virtual copy-constructor, creates a copy of this mesh.
 
 ~ParallelMesh ()=default
 
virtual MeshBase & assign (MeshBase &&other_mesh) override
 Shim to call the move assignment operator for this class.
 
virtual bool subclass_locally_equals (const MeshBase &other_mesh) const override
 Shim to allow operator == (&) to behave like a virtual function without having to be one.
 
virtual void clear () override
 Clear all internal data.
 
virtual void clear_elems () override
 Clear internal Elem data.
 
virtual void redistribute () override
 Redistribute elements between processors.
 
virtual void update_post_partitioning () override
 Recalculate cached data after elements and nodes have been repartitioned.
 
virtual bool is_serial () const override final
 
virtual bool is_serial_on_zero () const override final
 
virtual void set_distributed () override final
 Asserts that not all elements and nodes of the mesh necessarily exist on the current processor.
 
virtual bool is_replicated () const override final
 
template<typename T >
void libmesh_assert_valid_parallel_object_ids (const dofobject_container< T > &) const
 Verify id, processor_id, and if applicable unique_id consistency of a parallel objects container.
 
virtual void libmesh_assert_valid_parallel_ids () const override
 Verify id and processor_id consistency of our elements and nodes containers.
 
void libmesh_assert_valid_parallel_p_levels () const
 Verify p_level consistency of our elements containers.
 
void libmesh_assert_valid_parallel_flags () const
 Verify refinement_flag and p_refinement_flag consistency of our elements containers.
 
template<typename T >
dof_id_type renumber_dof_objects (dofobject_container< T > &)
 Renumber a parallel objects container.
 
virtual void renumber_nodes_and_elements () override
 Remove nullptr elements from arrays.
 
virtual void allgather () override
 Gathers all elements and nodes of the mesh onto every processor.
 
virtual void gather_to_zero () override
 Gathers all elements and nodes of the mesh onto processor zero.
 
virtual void delete_remote_elements () override
 Deletes all nonlocal elements of the mesh except for "ghosts" which touch a local element, and deletes all nodes which are not part of a local or ghost element.
 
virtual void add_extra_ghost_elem (Elem *e)
 Inserts the element and adds it to a list of elements that should not get deleted or have their descendants deleted by delete_remote_elements.
 
virtual void clear_extra_ghost_elems ()
 Clears extra ghost elements.
 
virtual void clear_extra_ghost_elems (const std::set< Elem * > &extra_ghost_elems)
 Clears specified extra ghost elements.
 
const std::set< Elem * > & extra_ghost_elems () const
 Const accessor to the ghosted elements.
 
virtual dof_id_type n_nodes () const override final
 
virtual dof_id_type max_node_id () const override final
 
virtual void reserve_nodes (const dof_id_type) override final
 Reserves space for a known number of nodes.
 
virtual dof_id_type n_elem () const override final
 
virtual dof_id_type n_active_elem () const override final
 
virtual dof_id_type max_elem_id () const override final
 
virtual void reserve_elem (const dof_id_type) override final
 Reserves space for a known number of elements.
 
virtual void update_parallel_id_counts () override
 Updates parallel caches so that methods like n_elem() accurately reflect changes on other processors.
 
virtual dof_id_type parallel_n_nodes () const override
 
dof_id_type parallel_max_node_id () const
 
virtual dof_id_type parallel_n_elem () const override
 
dof_id_type parallel_max_elem_id () const
 
virtual unique_id_type parallel_max_unique_id () const override
 
virtual void set_next_unique_id (unique_id_type id) override
 Sets the next available unique id to be used.
 
virtual const Point & point (const dof_id_type i) const override final
 
virtual const Node * node_ptr (const dof_id_type i) const override final
 
virtual Node * node_ptr (const dof_id_type i) override final
 
virtual const Node * query_node_ptr (const dof_id_type i) const override final
 
virtual Node * query_node_ptr (const dof_id_type i) override final
 
virtual const Elem * elem_ptr (const dof_id_type i) const override final
 
virtual Elem * elem_ptr (const dof_id_type i) override final
 
virtual const Elem * query_elem_ptr (const dof_id_type i) const override final
 
virtual Elem * query_elem_ptr (const dof_id_type i) override final
 
virtual Node * add_point (const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id) override final
 functions for adding /deleting nodes elements.
 
virtual Node * add_node (Node *n) override final
 Add Node n to the end of the vertex array.
 
virtual Node * add_node (std::unique_ptr< Node > n) override final
 Version of add_node() taking a std::unique_ptr by value.
 
virtual void own_node (Node &n) override final
 Takes ownership of node n on this partition of a distributed mesh, by setting n.processor_id() to this->processor_id(), as well as changing n.id() and moving it in the mesh's internal container to give it a new authoritative id.
 
virtual void delete_node (Node *n) override final
 Removes the Node n from the mesh.
 
virtual void renumber_node (dof_id_type old_id, dof_id_type new_id) override final
 Changes the id of node old_id, both by changing node(old_id)->id() and by moving node(old_id) in the mesh's internal container.
 
virtual Elem * add_elem (Elem *e) override final
 Add elem e to the end of the element array.
 
virtual Elem * add_elem (std::unique_ptr< Elem > e) override final
 Version of add_elem() taking a std::unique_ptr by value.
 
virtual Elem * insert_elem (Elem *e) override final
 Insert elem e to the element array, preserving its id and replacing/deleting any existing element with the same id.
 
virtual Elem * insert_elem (std::unique_ptr< Elem > e) override final
 Version of insert_elem() taking a std::unique_ptr by value.
 
virtual void delete_elem (Elem *e) override final
 Removes element e from the mesh.
 
virtual void renumber_elem (dof_id_type old_id, dof_id_type new_id) override final
 Changes the id of element old_id, both by changing elem(old_id)->id() and by moving elem(old_id) in the mesh's internal container.
 
virtual void fix_broken_node_and_element_numbering () override
 There is no reason for a user to ever call this function.
 
 DECLARE_ELEM_ITERATORS (,,)
 Elem and Node iterator accessor functions.
 
 DECLARE_ELEM_ITERATORS (active_,,)
 
 DECLARE_ELEM_ITERATORS (ancestor_,,) DECLARE_ELEM_ITERATORS(subactive_
 
 DECLARE_ELEM_ITERATORS (local_,,) DECLARE_ELEM_ITERATORS(unpartitioned_
 
 DECLARE_ELEM_ITERATORS (facelocal_,,) DECLARE_ELEM_ITERATORS(level_
 
unsigned int level DECLARE_ELEM_ITERATORS (pid_, processor_id_type pid, pid) DECLARE_ELEM_ITERATORS(type_
 
unsigned int level ElemType type DECLARE_ELEM_ITERATORS (active_subdomain_, subdomain_id_type sid, sid) DECLARE_ELEM_ITERATORS(active_subdomain_set_
 
 DECLARE_ELEM_ITERATORS (not_active_,,)
 
 DECLARE_ELEM_ITERATORS (not_ancestor_,,)
 
 DECLARE_ELEM_ITERATORS (not_subactive_,,)
 
 DECLARE_ELEM_ITERATORS (not_local_,,)
 
 DECLARE_ELEM_ITERATORS (not_level_, unsigned int level, level) DECLARE_ELEM_ITERATORS(active_local_
 
 DECLARE_ELEM_ITERATORS (active_not_local_,,) DECLARE_ELEM_ITERATORS(active_unpartitioned_
 
 DECLARE_ELEM_ITERATORS (active_type_, ElemType type, type) DECLARE_ELEM_ITERATORS(active_pid_
 
processor_id_type pid DECLARE_ELEM_ITERATORS (local_level_, unsigned int level, level) DECLARE_ELEM_ITERATORS(local_not_level_
 
processor_id_type pid unsigned int level DECLARE_ELEM_ITERATORS (active_local_subdomain_, subdomain_id_type sid, sid) DECLARE_ELEM_ITERATORS(active_local_subdomain_set_
 
processor_id_type pid unsigned int level std::set< subdomain_id_type > ss DECLARE_ELEM_ITERATORS (semilocal_,,) DECLARE_ELEM_ITERATORS(ghost_
 
processor_id_type pid unsigned int level std::set< subdomain_id_type > ss DECLARE_ELEM_ITERATORS (active_semilocal_,,) DECLARE_ELEM_ITERATORS(evaluable_
 
processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num DECLARE_ELEM_ITERATORS (multi_evaluable_, std::vector< const DofMap * > dof_maps, dof_maps) DECLARE_ELEM_ITERATORS(flagged_
 
processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num unsigned char rflag DECLARE_ELEM_ITERATORS (flagged_pid_, unsigned char rflag LIBMESH_COMMA processor_id_type pid, rflag LIBMESH_COMMA pid) DECLARE_NODE_ITERATORS(
 
unsigned int level ElemType type std::set< subdomain_id_type > virtual ss SimpleRange< element_iterator > active_subdomain_elements_ptr_range (subdomain_id_type sid) override final
 
virtual SimpleRange< const_element_iterator > active_subdomain_elements_ptr_range (subdomain_id_type sid) const override final
 
virtual SimpleRange< element_iterator > active_local_subdomain_elements_ptr_range (subdomain_id_type sid) override final
 
virtual SimpleRange< const_element_iterator > active_local_subdomain_elements_ptr_range (subdomain_id_type sid) const override final
 
virtual SimpleRange< element_iterator > active_subdomain_set_elements_ptr_range (std::set< subdomain_id_type > ss) override final
 
virtual SimpleRange< const_element_iterator > active_subdomain_set_elements_ptr_range (std::set< subdomain_id_type > ss) const override final
 
processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num unsigned char rflag DECLARE_NODE_ITERATORS (active_,,) DECLARE_NODE_ITERATORS(local_
 
processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num unsigned char rflag DECLARE_NODE_ITERATORS (bnd_,,) DECLARE_NODE_ITERATORS(pid_
 
processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num unsigned char rflag processor_id_type pid DECLARE_NODE_ITERATORS (bid_, boundary_id_type bid, bid) DECLARE_NODE_ITERATORS(evaluable_
 
virtual void read (const std::string &name, void *mesh_data=nullptr, bool skip_renumber_nodes_and_elements=false, bool skip_find_neighbors=false, bool skip_detect_interior_parents=false) override
 Reads the file specified by name.
 
virtual void write (const std::string &name) const override
 Write the file specified by name.
 
void write (const std::string &name, const std::vector< Number > &values, const std::vector< std::string > &variable_names) const
 Write to the file specified by name.
 
virtual void all_first_order () override
 Converts a mesh with higher-order elements into a mesh with linear elements.
 
virtual void all_second_order_range (const SimpleRange< element_iterator > &range, const bool full_ordered=true) override
 Converts a (conforming, non-refined) mesh with linear elements into a mesh with second-order elements.
 
virtual void all_complete_order_range (const SimpleRange< element_iterator > &range) override
 Converts a (conforming, non-refined) mesh with linear elements into a mesh with "complete" order elements, i.e.
 
void create_pid_mesh (UnstructuredMesh &pid_mesh, const processor_id_type pid) const
 Generates a new mesh containing all the elements which are assigned to processor pid.
 
void create_submesh (UnstructuredMesh &new_mesh, const const_element_iterator &it, const const_element_iterator &it_end) const
 Constructs a mesh called "new_mesh" from the current mesh by iterating over the elements between it and it_end and adding them to the new mesh.
 
std::size_t stitch_meshes (const MeshBase &other_mesh, boundary_id_type this_mesh_boundary, boundary_id_type other_mesh_boundary, Real tol=TOLERANCE, bool clear_stitched_boundary_ids=false, bool verbose=true, bool use_binary_search=true, bool enforce_all_nodes_match_on_boundaries=false, bool merge_boundary_nodes_all_or_nothing=false, bool remap_subdomain_ids=false, bool prepare_after_stitching=true)
 Stitch other_mesh to this mesh so that this mesh is the union of the two meshes.
 
std::size_t stitch_surfaces (boundary_id_type boundary_id_1, boundary_id_type boundary_id_2, Real tol=TOLERANCE, bool clear_stitched_boundary_ids=false, bool verbose=true, bool use_binary_search=true, bool enforce_all_nodes_match_on_boundaries=false, bool merge_boundary_nodes_all_or_nothing=false, bool prepare_after_stitching=true)
 Similar to stitch_meshes, except that we stitch two adjacent surfaces within this mesh.
 
virtual void copy_nodes_and_elements (const MeshBase &other_mesh, const bool skip_find_neighbors=false, dof_id_type element_id_offset=0, dof_id_type node_id_offset=0, unique_id_type unique_id_offset=0, std::unordered_map< subdomain_id_type, subdomain_id_type > *id_remapping=nullptr, const bool skip_preparation=false)
 Deep copy of nodes and elements from another mesh object (used by subclass copy constructors and by mesh merging operations)
 
virtual void move_nodes_and_elements (MeshBase &&other_mesh)=0
 Move node and elements from other_mesh to this mesh.
 
virtual void find_neighbors (const bool reset_remote_elements=false, const bool reset_current_list=true, const bool assert_valid=true, const bool check_non_remote=true) override
 Other functions from MeshBase requiring re-definition.
 
virtual bool contract () override
 Delete subactive (i.e.
 
bool operator== (const MeshBase &other_mesh) const
 This tests for exactly-equal data in all the senses that a mathematician would care about (element connectivity, nodal coordinates), but in the senses a programmer would care about it allows for non-equal equivalence in some ways (we accept different Elem/Node addresses in memory) but not others (we do not accept different subclass types, nor even different Elem/Node ids).
 
bool operator!= (const MeshBase &other_mesh) const
 
bool locally_equals (const MeshBase &other_mesh) const
 This behaves the same as operator==, but only for the local and ghosted aspects of the mesh; i.e.
 
virtual std::unique_ptr< Partitioner > & partitioner ()
 A partitioner to use at each partitioning.
 
const BoundaryInfo & get_boundary_info () const
 The information about boundary ids on the mesh.
 
BoundaryInfo & get_boundary_info ()
 Writable information about boundary ids on the mesh.
 
bool is_prepared () const
 
Preparation preparation () const
 
void set_isnt_prepared ()
 Tells this we have done some operation where we should no longer consider ourself prepared.
 
void unset_is_prepared ()
 Tells this we have done some operation where we should no longer consider ourself prepared.
 
void unset_is_partitioned ()
 Tells this we have done some operation creating unpartitioned elements.
 
void unset_has_synched_id_counts ()
 Tells this we have done some operation (e.g.
 
void unset_has_neighbor_ptrs ()
 Tells this we have done some operation (e.g.
 
void unset_has_cached_elem_data ()
 Tells this we have done some operation (e.g.
 
void unset_has_interior_parent_ptrs ()
 Tells this we have done some operation (e.g.
 
void unset_has_removed_remote_elements ()
 Tells this we have done some operation (e.g.
 
void unset_has_removed_orphaned_nodes ()
 Tells this we have done some operation (e.g.
 
void unset_has_reinit_ghosting_functors ()
 Tells this we have done some operation (e.g.
 
void unset_has_boundary_id_sets ()
 Tells this we have done some operation which may have invalidated our cached boundary id sets.
 
void unset_has_synched_subdomain_name_map ()
 Tells this we have done some operation which may have left the subdomain id to name map inconsistent across processors.
 
void reinit_ghosting_functors ()
 Loops over ghosting functors and calls mesh_reinit()
 
unsigned int mesh_dimension () const
 
void set_mesh_dimension (unsigned char d)
 Resets the logical dimension of the mesh.
 
const std::set< unsigned char > & elem_dimensions () const
 
const std::set< Order > & elem_default_orders () const
 
Order supported_nodal_order () const
 
void set_elem_dimensions (std::set< unsigned char > elem_dims)
 Most of the time you should not need to call this, as the element dimensions will be set automatically by a call to cache_elem_data(), therefore only call this if you know what you're doing.
 
void add_elemset_code (dof_id_type code, MeshBase::elemset_type id_set)
 Tabulate a user-defined "code" for elements which belong to the element sets specified in id_set.
 
unsigned int n_elemsets () const
 Returns the number of unique elemset ids which have been added via add_elemset_code(), which is the size of the _all_elemset_ids set.
 
void get_elemsets (dof_id_type elemset_code, MeshBase::elemset_type &id_set_to_fill) const
 Look up the element sets for a given elemset code and vice-versa.
 
dof_id_type get_elemset_code (const MeshBase::elemset_type &id_set) const
 
std::vector< dof_id_type > get_elemset_codes () const
 Return a vector of all elemset codes defined on the mesh.
 
void change_elemset_code (dof_id_type old_code, dof_id_type new_code)
 Replace elemset code "old_code" with "new_code".
 
void change_elemset_id (elemset_id_type old_id, elemset_id_type new_id)
 Replace elemset id "old_id" with "new_id".
 
unsigned int spatial_dimension () const
 
void set_spatial_dimension (unsigned char d)
 Sets the "spatial dimension" of the Mesh.
 
dof_id_type n_nodes_on_proc (const processor_id_type proc) const
 
dof_id_type n_local_nodes () const
 
dof_id_type n_unpartitioned_nodes () const
 
unique_id_type next_unique_id () const
 
dof_id_type n_elem_on_proc (const processor_id_type proc) const
 
dof_id_type n_local_elem () const
 
dof_id_type n_unpartitioned_elem () const
 
dof_id_type n_active_elem_on_proc (const processor_id_type proc) const
 
dof_id_type n_active_local_elem () const
 
dof_id_type n_sub_elem () const
 
dof_id_type n_active_sub_elem () const
 Same as n_sub_elem(), but only counts active elements.
 
virtual const Node & node_ref (const dof_id_type i) const
 
virtual Node & node_ref (const dof_id_type i)
 
virtual const Elem & elem_ref (const dof_id_type i) const
 
virtual Elem & elem_ref (const dof_id_type i)
 
ElemMappingType default_mapping_type () const
 Returns the default master space to physical space mapping basis functions to be used on newly added elements.
 
void set_default_mapping_type (const ElemMappingType type)
 Set the default master space to physical space mapping basis functions to be used on newly added elements.
 
unsigned char default_mapping_data () const
 Returns any default data value used by the master space to physical space mapping.
 
void set_default_mapping_data (const unsigned char data)
 Set the default master space to physical space mapping basis functions to be used on newly added elements.
 
void remove_orphaned_nodes ()
 Removes any orphaned nodes, nodes not connected to any elements.
 
unsigned int add_elem_integer (std::string name, bool allocate_data=true, dof_id_type default_value=DofObject::invalid_id)
 Register an integer datum (of type dof_id_type) to be added to each element in the mesh.
 
std::vector< unsigned int > add_elem_integers (const std::vector< std::string > &names, bool allocate_data=true, const std::vector< dof_id_type > *default_values=nullptr)
 Register integer data (of type dof_id_type) to be added to each element in the mesh, one string name for each new integer.
 
unsigned int get_elem_integer_index (std::string_view name) const
 
bool has_elem_integer (std::string_view name) const
 
const std::string & get_elem_integer_name (unsigned int i) const
 
unsigned int n_elem_integers () const
 
template<typename T >
unsigned int add_elem_datum (const std::string &name, bool allocate_data=true, const T *default_value=nullptr)
 Register a datum (of type T) to be added to each element in the mesh.
 
template<typename T >
std::vector< unsigned int > add_elem_data (const std::vector< std::string > &names, bool allocate_data=true, const std::vector< T > *default_values=nullptr)
 Register data (of type T) to be added to each element in the mesh.
 
unsigned int add_node_integer (std::string name, bool allocate_data=true, dof_id_type default_value=DofObject::invalid_id)
 Register an integer datum (of type dof_id_type) to be added to each node in the mesh.
 
std::vector< unsigned int > add_node_integers (const std::vector< std::string > &names, bool allocate_data=true, const std::vector< dof_id_type > *default_values=nullptr)
 Register integer data (of type dof_id_type) to be added to each node in the mesh.
 
unsigned int get_node_integer_index (std::string_view name) const
 
bool has_node_integer (std::string_view name) const
 
const std::string & get_node_integer_name (unsigned int i) const
 
unsigned int n_node_integers () const
 
template<typename T >
unsigned int add_node_datum (const std::string &name, bool allocate_data=true, const T *default_value=nullptr)
 Register a datum (of type T) to be added to each node in the mesh.
 
template<typename T >
std::vector< unsigned int > add_node_data (const std::vector< std::string > &name, bool allocate_data=true, const std::vector< T > *default_values=nullptr)
 Register data (of type T) to be added to each node in the mesh.
 
void prepare_for_use (const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
 Prepare a newly created (or read) mesh for use.
 
void prepare_for_use (const bool skip_renumber_nodes_and_elements)
 
void prepare_for_use ()
 
void complete_preparation ()
 
virtual void partition (const unsigned int n_parts)
 Call the default partitioner (currently metis_partition()).
 
void partition ()
 
void allow_renumbering (bool allow)
 If false is passed in then this mesh will no longer be renumbered when being prepared for use.
 
bool allow_renumbering () const
 
void allow_find_neighbors (bool allow)
 If false is passed then this mesh will no longer work to find element neighbors when being prepared for use.
 
bool allow_find_neighbors () const
 
void allow_detect_interior_parents (bool allow)
 If false is passed then this mesh will no longer work to detect interior parents when being prepared for use.
 
bool allow_detect_interior_parents () const
 
void allow_remote_element_removal (bool allow)
 If false is passed in then this mesh will no longer have remote elements deleted when being prepared for use; i.e.
 
bool allow_remote_element_removal () const
 
void allow_node_and_elem_unique_id_overlap (bool allow)
 If true is passed, then this mesh will no longer require unique_ids to be unique across the set of all DofObjects.
 
bool allow_node_and_elem_unique_id_overlap () const
 
void skip_noncritical_partitioning (bool skip)
 If true is passed in then the elements on this mesh will no longer be (re)partitioned, and the nodes on this mesh will only be repartitioned if they are found "orphaned" via coarsening or other removal of the last element responsible for their node/element processor id consistency.
 
bool skip_noncritical_partitioning () const
 
void skip_partitioning (bool skip)
 If true is passed in then nothing on this mesh will be (re)partitioned.
 
bool skip_partitioning () const
 
void add_ghosting_functor (GhostingFunctor &ghosting_functor)
 Adds a functor which can specify ghosting requirements for use on distributed meshes.
 
void add_ghosting_functor (std::shared_ptr< GhostingFunctor > ghosting_functor)
 Adds a functor which can specify ghosting requirements for use on distributed meshes.
 
void remove_ghosting_functor (GhostingFunctor &ghosting_functor)
 Removes a functor which was previously added to the set of ghosting functors.
 
GhostingFunctorIterator ghosting_functors_begin () const
 Beginning of range of ghosting functors.
 
GhostingFunctorIterator ghosting_functors_end () const
 End of range of ghosting functors.
 
GhostingFunctor & default_ghosting ()
 Default ghosting functor.
 
void subdomain_ids (std::set< subdomain_id_type > &ids, const bool global=true) const
 Constructs a list of all subdomain identifiers in the local mesh if global == false, and in the global mesh if global == true (default).
 
subdomain_id_type n_subdomains () const
 
subdomain_id_type n_local_subdomains () const
 
unsigned int n_partitions () const
 
std::string get_info (const unsigned int verbosity=0, const bool global=true) const
 
void print_info (std::ostream &os=libMesh::out, const unsigned int verbosity=0, const bool global=true) const
 Prints relevant information about the mesh.
 
void all_second_order (const bool full_ordered=true)
 Calls the range-based version of this function with a range consisting of all elements in the mesh.
 
virtual void all_complete_order ()
 Calls the range-based version of this function with a range consisting of all elements in the mesh.
 
unsigned int recalculate_n_partitions ()
 In a few (very rare) cases, the user may have manually tagged the elements with specific processor IDs by hand, without using a partitioner.
 
std::unique_ptr< PointLocatorBase > sub_point_locator () const
 
void set_point_locator_close_to_point_tol (Real val)
 Set value used by PointLocatorBase::close_to_point_tol().
 
Real get_point_locator_close_to_point_tol () const
 
void clear_point_locator ()
 Releases the current PointLocator object.
 
void set_count_lower_dim_elems_in_point_locator (bool count_lower_dim_elems)
 In the point locator, do we count lower dimensional elements when we refine point locator regions? This is relevant in tree-based point locators, for example.
 
bool get_count_lower_dim_elems_in_point_locator () const
 Get the current value of _count_lower_dim_elems_in_point_locator.
 
std::string & subdomain_name (subdomain_id_type id)
 
const std::string & subdomain_name (subdomain_id_type id) const
 
void set_subdomain_name (subdomain_id_type id, const std::string &name, bool synchronous=false)
 Sets the name for the provided id.
 
subdomain_id_type get_id_by_name (std::string_view name) const
 
 ABSTRACT_ELEM_ITERATORS (,) ABSTRACT_ELEM_ITERATORS(active_
 
 ABSTRACT_ELEM_ITERATORS (ancestor_,) ABSTRACT_ELEM_ITERATORS(subactive_
 
 ABSTRACT_ELEM_ITERATORS (local_,) ABSTRACT_ELEM_ITERATORS(unpartitioned_
 
 ABSTRACT_ELEM_ITERATORS (facelocal_,) ABSTRACT_ELEM_ITERATORS(level_
 
unsigned int level ABSTRACT_ELEM_ITERATORS (pid_, processor_id_type pid) ABSTRACT_ELEM_ITERATORS(type_
 
unsigned int level ElemType type ABSTRACT_ELEM_ITERATORS (active_subdomain_, subdomain_id_type sid) ABSTRACT_ELEM_ITERATORS(active_subdomain_set_
 
unsigned int level ElemType type std::set< subdomain_id_type > ss ABSTRACT_ELEM_ITERATORS (not_active_,) ABSTRACT_ELEM_ITERATORS(not_ancestor_
 
unsigned int level ElemType type std::set< subdomain_id_type > ss ABSTRACT_ELEM_ITERATORS (not_subactive_,) ABSTRACT_ELEM_ITERATORS(not_local_
 
unsigned int level ElemType type std::set< subdomain_id_type > ss ABSTRACT_ELEM_ITERATORS (not_level_, unsigned int level) ABSTRACT_ELEM_ITERATORS(active_local_
 
unsigned int level ElemType type std::set< subdomain_id_type > ss ABSTRACT_ELEM_ITERATORS (active_not_local_,) ABSTRACT_ELEM_ITERATORS(active_unpartitioned_
 
unsigned int level ElemType type std::set< subdomain_id_type > ss ABSTRACT_ELEM_ITERATORS (active_type_, ElemType type) ABSTRACT_ELEM_ITERATORS(active_pid_
 
unsigned int level ElemType type std::set< subdomain_id_type > ss processor_id_type pid ABSTRACT_ELEM_ITERATORS (local_level_, unsigned int level) ABSTRACT_ELEM_ITERATORS(local_not_level_
 
unsigned int level ElemType type std::set< subdomain_id_type > ss processor_id_type pid unsigned int level ABSTRACT_ELEM_ITERATORS (active_local_subdomain_, subdomain_id_type sid) ABSTRACT_ELEM_ITERATORS(active_local_subdomain_set_
 
 ABSTRACT_ELEM_ITERATORS (semilocal_,) ABSTRACT_ELEM_ITERATORS(ghost_
 
 ABSTRACT_ELEM_ITERATORS (active_semilocal_,) ABSTRACT_ELEM_ITERATORS(evaluable_
 
const ElemRange & element_stored_range ()
 
const ConstElemRange & active_local_element_stored_range () const
 
void clear_stored_ranges ()
 Clears stored ranges, to indicate that the mesh has changed and they should be regenerated when next needed.
 
std::map< subdomain_id_type, std::string > & set_subdomain_name_map ()
 
const std::map< subdomain_id_type, std::string > & get_subdomain_name_map () const
 
constraint_rows_type & get_constraint_rows ()
 Constraint rows accessors.
 
const constraint_rows_type & get_constraint_rows () const
 
constraint_rows_type & set_constraint_rows ()
 
dof_id_type n_constraint_rows () const
 Returns how many total constraint rows we have.
 
void copy_constraint_rows (const MeshBase &other_mesh)
 Copy the constraints from the other mesh to this mesh.
 
template<typename T >
void copy_constraint_rows (const SparseMatrix< T > &constraint_operator, bool precondition_constraint_operator=false)
 Copy the constraints from the given matrix to this mesh.
 
void print_constraint_rows (std::ostream &os=libMesh::out, bool print_nonlocal=false) const
 Prints (from processor 0) all mesh constraint rows.
 
std::string get_local_constraints (bool print_nonlocal=false) const
 Gets a string reporting all mesh constraint rows local to this processor.
 
void cache_elem_dims ()
 
void cache_elem_data ()
 
void sync_subdomain_name_map ()
 libMesh often expects all processors to know about names of all subdomain ids, but distributed mesh generators may only know about part of a mesh when creating names.
 
void detect_interior_parents ()
 Search the mesh for elements that have a neighboring element of dim+1 and set that element as the interior parent.
 
const MeshBase & interior_mesh () const
 
MeshBase & interior_mesh ()
 
void set_interior_mesh (MeshBase &int_mesh)
 Sets the interior mesh.
 
const std::set< subdomain_id_type > & get_mesh_subdomains () const
 
void add_disjoint_neighbor_boundary_pairs (const boundary_id_type b1, const boundary_id_type b2, const RealVectorValue &translation)
 Register a pair of boundaries as disjoint neighbor boundary pairs.
 
PeriodicBoundaries * get_disjoint_neighbor_boundary_pairs ()
 
const PeriodicBoundaries * get_disjoint_neighbor_boundary_pairs () const
 
void remove_disjoint_boundary_pair (const boundary_id_type b1, const boundary_id_type b2)
 
const Parallel::Communicator & comm () const
 
processor_id_type n_processors () const
 
processor_id_type processor_id () const
 

Public Attributes

unsigned int level
 
processor_id_type pid unsigned int level
 
unsigned int level ElemType type
 
unsigned int level ElemType type std::set< subdomain_id_type > ss
 
processor_id_type pid unsigned int level std::set< subdomain_id_type > ss
 
processor_id_type pid
 
processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num unsigned char rflag processor_id_type pid
 
processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap &dof_map LIBMESH_COMMA unsigned int var_num = libMesh::invalid_uint
 
processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num unsigned char rflag processor_id_type pid const DofMap &dof_map LIBMESH_COMMA unsigned int var_num = libMesh::invalid_uint
 
processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num unsigned char rflag
 
processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num unsigned char rflag processor_id_type pid const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num DECLARE_NODE_ITERATORS(multi_evaluable_, std::vector< const DofMap * > dof_maps, dof_maps) protected dofobject_container< Node > _nodes
 Move node and elements from a DistributedMesh.
 
dofobject_container< Elem > _elements
 The elements in the mesh.
 
bool _is_serial
 A boolean remembering whether we're serialized or not.
 
bool _is_serial_on_proc_0
 A boolean remembering whether we're serialized to proc 0 or not.
 
bool _deleted_coarse_elements
 A boolean remembering whether we've recently deleted top-level elements or not.
 
dof_id_type _n_nodes
 Cached data from the last renumber_nodes_and_elements call.
 
dof_id_type _n_elem
 
dof_id_type _max_node_id
 
dof_id_type _max_elem_id
 
dof_id_type _next_free_local_node_id
 Guaranteed globally unused IDs for use when adding new nodes or elements.
 
dof_id_type _next_free_local_elem_id
 
dof_id_type _next_free_unpartitioned_node_id
 
dof_id_type _next_free_unpartitioned_elem_id
 
unique_id_type _next_unpartitioned_unique_id
 The next available unique id for assigning ids to unpartitioned DOF objects.
 
std::set< Elem * > _extra_ghost_elems
 These are extra ghost elements that we want to make sure not to delete when we call delete_remote_elements()
 
const DofMap &dof_map LIBMESH_COMMA unsigned int Elem * ElemRange
 

Protected Types

typedef variant_filter_iterator< MeshBase::Predicate, Elem * > elem_filter_iter
 The original iterator classes weren't properly const-safe; relying on their const-incorrectness is now deprecated.
 
typedef variant_filter_iterator< MeshBase::Predicate, Elem *const, Elem *const &, Elem *const *, const Elem *const, const Elem *const &, const Elem *const * > elem_filter_iter
 
typedef variant_filter_iterator< MeshBase::Predicate, Elem *const, Elem *const &, Elem *const * > const_elem_filter_iter
 
typedef variant_filter_iterator< MeshBase::Predicate, const Elem *const, const Elem *const &, const Elem *const * > const_elem_filter_iter
 
typedef variant_filter_iterator< MeshBase::Predicate, Node * > node_filter_iter
 
typedef variant_filter_iterator< MeshBase::Predicate, Node *const, Node *const &, Node *const *, const Node *const, const Node *const &, const Node *const * > node_filter_iter
 
typedef variant_filter_iterator< MeshBase::Predicate, Node *const, Node *const &, Node *const * > const_node_filter_iter
 
typedef variant_filter_iterator< MeshBase::Predicate, const Node *const, const Node *const &, const Node *const * > const_node_filter_iter
 

Protected Member Functions

void post_dofobject_moves (MeshBase &&other_mesh)
 Moves any superclass data (e.g.
 
void copy_cached_data (const MeshBase &other_mesh)
 Helper class to copy cached data, to synchronize with a possibly unprepared other_mesh.
 
bool nodes_and_elements_equal (const MeshBase &other_mesh) const
 Tests for equality of all elements and nodes in the mesh.
 
unsigned int & set_n_partitions ()
 
void size_elem_extra_integers ()
 Size extra-integer arrays of all elements in the mesh.
 
void size_node_extra_integers ()
 Size extra-integer arrays of all nodes in the mesh.
 
std::pair< std::vector< unsigned int >, std::vector< unsigned int > > merge_extra_integer_names (const MeshBase &other)
 Merge extra-integer arrays from an other mesh.
 
dof_id_type count_constraint_rows ()
 Helper function for subclasses to use to set _n_constraint_rows.
 

Protected Attributes

std::unique_ptr< PeriodicBoundaries > _disjoint_neighbor_boundary_pairs
 The disjoint neighbor boundary id pairs.
 
std::unique_ptr< BoundaryInfo > boundary_info
 This class holds the boundary information.
 
unsigned int _n_parts
 The number of partitions the mesh has.
 
ElemMappingType _default_mapping_type
 The default mapping type (typically Lagrange) between master and physical space to assign to newly added elements.
 
unsigned char _default_mapping_data
 The default mapping data (unused with Lagrange, used for nodal weight lookup index with rational bases) to assign to newly added elements.
 
Preparation _preparation
 Flags indicating in what ways this mesh has been prepared.
 
std::unique_ptr< ElemRange > _element_stored_range
 A cached ElemRange for threaded mutation of all semilocal elements of this mesh.
 
std::unique_ptr< ConstElemRange > _const_active_local_element_stored_range
 A cached ConstElemRange for threaded calculation on all local elements of this mesh.
 
std::unique_ptr< PointLocatorBase > _point_locator
 A PointLocator class for this mesh.
 
bool _count_lower_dim_elems_in_point_locator
 Do we count lower dimensional elements in point locator refinement? This is relevant in tree-based point locators, for example.
 
std::unique_ptr< Partitioner > _partitioner
 A partitioner to use at each prepare_for_use().
 
unique_id_type _next_unique_id
 The next available unique id for assigning ids to DOF objects.
 
MeshBase * _interior_mesh
 Defaulting to this, a pointer to the mesh used to generate boundary elements on this.
 
bool _skip_noncritical_partitioning
 If this is true then no partitioning should be done with the possible exception of orphaned nodes.
 
bool _skip_all_partitioning
 If this is true then no partitioning should be done.
 
bool _skip_renumber_nodes_and_elements
 If this is true then renumbering will be kept to a minimum.
 
bool _skip_find_neighbors
 If this is true then we will skip find_neighbors in prepare_for_use.
 
bool _skip_detect_interior_parents
 If this is true then we will skip detect_interior_parents in prepare_for_use.
 
bool _allow_remote_element_removal
 If this is false then even on DistributedMesh remote elements will not be deleted during mesh preparation.
 
bool _allow_node_and_elem_unique_id_overlap
 The Exodus reader (and potentially other readers in the future?) now supports setting Node and Elem unique_ids based on values from within the Exodus file itself, rather than generating them automatically in LibMesh.
 
std::map< subdomain_id_type, std::string > _block_id_to_name
 This structure maintains the mapping of named blocks for file formats that support named blocks.
 
std::set< unsigned char > _elem_dims
 We cache the dimension of the elements present in the mesh.
 
std::set< Order > _elem_default_orders
 We cache the (default) order of the geometric elements present in the mesh.
 
Order _supported_nodal_order
 We cache the maximum nodal order supported by all the mesh's elements (the minimum supported_nodal_order() of any element)
 
std::set< subdomain_id_type > _mesh_subdomains
 We cache the subdomain ids of the elements present in the mesh.
 
std::map< dof_id_type, const MeshBase::elemset_type * > _elemset_codes
 Map from "element set code" to list of set ids to which that element belongs (and vice-versa).
 
std::map< MeshBase::elemset_type, dof_id_type > _elemset_codes_inverse_map
 
MeshBase::elemset_type _all_elemset_ids
 
unsigned char _spatial_dimension
 The "spatial dimension" of the Mesh.
 
std::vector< std::string > _elem_integer_names
 The array of names for integer data associated with each element in the mesh.
 
std::vector< dof_id_type > _elem_integer_default_values
 The array of default initialization values for integer data associated with each element in the mesh.
 
std::vector< std::string > _node_integer_names
 The array of names for integer data associated with each node in the mesh.
 
std::vector< dof_id_type > _node_integer_default_values
 The array of default initialization values for integer data associated with each node in the mesh.
 
std::unique_ptr< GhostingFunctor > _default_ghosting
 The default geometric GhostingFunctor, used to implement standard libMesh element ghosting behavior.
 
std::vector< GhostingFunctor * > _ghosting_functors
 The list of all GhostingFunctor objects to be used when distributing a DistributedMesh.
 
std::map< GhostingFunctor *, std::shared_ptr< GhostingFunctor > > _shared_functors
 Hang on to references to any GhostingFunctor objects we were passed in shared_ptr form.
 
constraint_rows_type _constraint_rows
 
dof_id_type _n_constraint_rows
 
Real _point_locator_close_to_point_tol
 If nonzero, we will call PointLocatorBase::set_close_to_point_tol() on any PointLocators that we create.
 
const Parallel::Communicator & _communicator
 

Private Types

typedef dofobject_container< Elem >::veclike_iterator elem_iterator_imp
 Typedefs for the container implementation.
 
typedef dofobject_container< Elem >::const_veclike_iterator const_elem_iterator_imp
 
typedef dofobject_container< Node >::veclike_iterator node_iterator_imp
 Typedefs for the container implementation.
 
typedef dofobject_container< Node >::const_veclike_iterator const_node_iterator_imp
 

Private Member Functions

void set_next_ids ()
 Derives _next_free_local_node_id, _next_free_local_elem_id, _next_free_unpartitioned_node_id, and _next_free_unpartitioned_elem_id from the current _max_node_id and _max_elem_id, interleaving ids among processors so that each processor (and the unpartitioned pool) has its own reserved slot in every repeating group of n_processors()+1 ids.
 
void set_next_unique_ids (unique_id_type parallel_max_unique_id)
 Derives _next_unique_id and _next_unpartitioned_unique_id from parallel_max_unique_id, the largest unique id currently in use (or any other value guaranteed to be at least that large, such as a trusted next_unique_id()), using the same processor-interleaved id ranges as set_next_ids().
 
std::size_t stitching_helper (const MeshBase *other_mesh, boundary_id_type boundary_id_1, boundary_id_type boundary_id_2, Real tol, bool clear_stitched_boundary_ids, bool verbose, bool use_binary_search, bool enforce_all_nodes_match_on_boundaries, bool skip_find_neighbors, bool merge_boundary_nodes_all_or_nothing, bool remap_subdomain_ids, bool prepare_after_stitching)
 Helper function for stitch_meshes and stitch_surfaces that does the mesh stitching.
 

Detailed Description

Definition at line 34 of file parallel_mesh.h.

Member Typedef Documentation

◆ const_elem_filter_iter [1/2]

typedef variant_filter_iterator<MeshBase::Predicate, Elem * const, Elem * const &, Elem * const *> libMesh::MeshBase::const_elem_filter_iter
protectedinherited

Definition at line 2504 of file mesh_base.h.

◆ const_elem_filter_iter [2/2]

typedef variant_filter_iterator<MeshBase::Predicate, const Elem * const, const Elem * const &, const Elem * const *> libMesh::MeshBase::const_elem_filter_iter
protectedinherited

Definition at line 2524 of file mesh_base.h.

◆ const_elem_iterator_imp

typedef dofobject_container<Elem>::const_veclike_iterator libMesh::DistributedMesh::const_elem_iterator_imp
privateinherited

Definition at line 496 of file distributed_mesh.h.

◆ const_node_filter_iter [1/2]

typedef variant_filter_iterator<MeshBase::Predicate, Node * const, Node * const &, Node * const *> libMesh::MeshBase::const_node_filter_iter
protectedinherited

Definition at line 2511 of file mesh_base.h.

◆ const_node_filter_iter [2/2]

typedef variant_filter_iterator<MeshBase::Predicate, const Node * const, const Node * const &, const Node * const *> libMesh::MeshBase::const_node_filter_iter
protectedinherited

Definition at line 2537 of file mesh_base.h.

◆ const_node_iterator_imp

typedef dofobject_container<Node>::const_veclike_iterator libMesh::DistributedMesh::const_node_iterator_imp
privateinherited

Definition at line 502 of file distributed_mesh.h.

◆ ConstElemRange

Definition at line 1899 of file mesh_base.h.

◆ constraint_rows_mapped_type

typedef std::vector<std::pair<std::pair<const Elem *, unsigned int>, Real> > libMesh::MeshBase::constraint_rows_mapped_type
inherited

Definition at line 1933 of file mesh_base.h.

◆ constraint_rows_type

Definition at line 1934 of file mesh_base.h.

◆ dofobject_container [1/2]

template<typename Obj >
using libMesh::DistributedMesh::dofobject_container = mapvector<Obj *, dof_id_type>
inherited

Definition at line 63 of file distributed_mesh.h.

◆ dofobject_container [2/2]

using libMesh::DistributedMesh::dofobject_container = chunked_mapvector<Obj *, dof_id_type, LIBMESH_MAPVECTOR_CHUNK_SIZE>
inherited

Definition at line 65 of file distributed_mesh.h.

◆ elem_filter_iter [1/2]

The original iterator classes weren't properly const-safe; relying on their const-incorrectness is now deprecated.

Definition at line 2499 of file mesh_base.h.

◆ elem_filter_iter [2/2]

typedef variant_filter_iterator<MeshBase::Predicate, Elem * const, Elem * const &, Elem * const *, const Elem * const, const Elem * const &, const Elem * const *> libMesh::MeshBase::elem_filter_iter
protectedinherited

Definition at line 2519 of file mesh_base.h.

◆ elem_iterator_imp

typedef dofobject_container<Elem>::veclike_iterator libMesh::DistributedMesh::elem_iterator_imp
privateinherited

Typedefs for the container implementation.

Definition at line 495 of file distributed_mesh.h.

◆ elemset_type

typedef std::set<elemset_id_type> libMesh::MeshBase::elemset_type
inherited

Typedef for the "set" container used to store elemset ids.

The main requirements are that the entries be sorted and unique, so std::set works for this, but there may be more efficient alternatives.

Definition at line 463 of file mesh_base.h.

◆ GhostingFunctorIterator

typedef std::vector<GhostingFunctor*>::const_iterator libMesh::MeshBase::GhostingFunctorIterator
inherited

Iterator type for ghosting functor ranges.

This has changed in the past and may change again; code should use auto or the type here.

Definition at line 1471 of file mesh_base.h.

◆ node_filter_iter [1/2]

Definition at line 2506 of file mesh_base.h.

◆ node_filter_iter [2/2]

typedef variant_filter_iterator<MeshBase::Predicate, Node * const, Node * const &, Node * const *, const Node * const, const Node * const &, const Node * const *> libMesh::MeshBase::node_filter_iter
protectedinherited

Definition at line 2532 of file mesh_base.h.

◆ node_iterator_imp

typedef dofobject_container<Node>::veclike_iterator libMesh::DistributedMesh::node_iterator_imp
privateinherited

Typedefs for the container implementation.

Definition at line 501 of file distributed_mesh.h.

◆ Predicate

We need an empty, generic class to act as a predicate for this and derived mesh classes.

Definition at line 1589 of file mesh_base.h.

Constructor & Destructor Documentation

◆ ParallelMesh() [1/2]

libMesh::ParallelMesh::ParallelMesh ( const Parallel::Communicator &  comm_in,
unsigned char  dim = 1 
)
inlineexplicit

Definition at line 38 of file parallel_mesh.h.

40 : DistributedMesh(comm_in,dim) {}
unsigned int dim
DistributedMesh(const Parallel::Communicator &comm_in, unsigned char dim=1)
Constructor.

◆ ParallelMesh() [2/2]

libMesh::ParallelMesh::ParallelMesh ( const UnstructuredMesh &  other_mesh)
inline

Definition at line 42 of file parallel_mesh.h.

42: DistributedMesh(other_mesh) {}

◆ ~ParallelMesh()

libMesh::ParallelMesh::~ParallelMesh ( )
default

Member Function Documentation

◆ ABSTRACT_ELEM_ITERATORS() [1/15]

libMesh::MeshBase::ABSTRACT_ELEM_ITERATORS ( )
inherited

◆ ABSTRACT_ELEM_ITERATORS() [2/15]

unsigned int level ElemType type std::set< subdomain_id_type > ss processor_id_type pid unsigned int level libMesh::MeshBase::ABSTRACT_ELEM_ITERATORS ( active_local_subdomain_  ,
subdomain_id_type  sid 
)
inherited

◆ ABSTRACT_ELEM_ITERATORS() [3/15]

unsigned int level ElemType type std::set< subdomain_id_type > ss libMesh::MeshBase::ABSTRACT_ELEM_ITERATORS ( active_not_local_  )
inherited

◆ ABSTRACT_ELEM_ITERATORS() [4/15]

libMesh::MeshBase::ABSTRACT_ELEM_ITERATORS ( active_semilocal_  )
inherited

◆ ABSTRACT_ELEM_ITERATORS() [5/15]

unsigned int level ElemType type libMesh::MeshBase::ABSTRACT_ELEM_ITERATORS ( active_subdomain_  ,
subdomain_id_type  sid 
)
inherited

◆ ABSTRACT_ELEM_ITERATORS() [6/15]

unsigned int level ElemType type std::set< subdomain_id_type > ss libMesh::MeshBase::ABSTRACT_ELEM_ITERATORS ( active_type_  ,
ElemType  type 
)
inherited

◆ ABSTRACT_ELEM_ITERATORS() [7/15]

libMesh::MeshBase::ABSTRACT_ELEM_ITERATORS ( ancestor_  )
inherited

◆ ABSTRACT_ELEM_ITERATORS() [8/15]

libMesh::MeshBase::ABSTRACT_ELEM_ITERATORS ( facelocal_  )
inherited

◆ ABSTRACT_ELEM_ITERATORS() [9/15]

libMesh::MeshBase::ABSTRACT_ELEM_ITERATORS ( local_  )
inherited

◆ ABSTRACT_ELEM_ITERATORS() [10/15]

unsigned int level ElemType type std::set< subdomain_id_type > ss processor_id_type pid libMesh::MeshBase::ABSTRACT_ELEM_ITERATORS ( local_level_  ,
unsigned int  level 
)
inherited

◆ ABSTRACT_ELEM_ITERATORS() [11/15]

unsigned int level ElemType type std::set< subdomain_id_type > ss libMesh::MeshBase::ABSTRACT_ELEM_ITERATORS ( not_active_  )
inherited

◆ ABSTRACT_ELEM_ITERATORS() [12/15]

unsigned int level ElemType type std::set< subdomain_id_type > ss libMesh::MeshBase::ABSTRACT_ELEM_ITERATORS ( not_level_  ,
unsigned int  level 
)
inherited

◆ ABSTRACT_ELEM_ITERATORS() [13/15]

unsigned int level ElemType type std::set< subdomain_id_type > ss libMesh::MeshBase::ABSTRACT_ELEM_ITERATORS ( not_subactive_  )
inherited

◆ ABSTRACT_ELEM_ITERATORS() [14/15]

unsigned int level libMesh::MeshBase::ABSTRACT_ELEM_ITERATORS ( pid_  ,
processor_id_type  pid 
)
inherited

◆ ABSTRACT_ELEM_ITERATORS() [15/15]

libMesh::MeshBase::ABSTRACT_ELEM_ITERATORS ( semilocal_  )
inherited

◆ active_local_element_stored_range()

const ConstElemRange & libMesh::MeshBase::active_local_element_stored_range ( ) const
inherited
Returns
A reference to a cached vector copy of a range of pointers to all active local elements, suitable for threading.

Iterating over only local elements is most useful for computing on the mesh, so we only have a non-const version for now.

Definition at line 1969 of file mesh_base.C.

1970{
1972 {
1973 // Range construction may not be safe within threads
1975
1977 std::make_unique<ConstElemRange>(this->active_local_elements_begin(),
1978 this->active_local_elements_end());
1979 }
1980
1982}
std::unique_ptr< ConstElemRange > _const_active_local_element_stored_range
A cached ConstElemRange for threaded calculation on all local elements of this mesh.
Definition mesh_base.h:2228
bool in_threads
A boolean which is true iff we are in a Threads:: function It may be useful to assert(!...
Definition threads.C:33
libmesh_assert(ctx)

References libMesh::MeshBase::_const_active_local_element_stored_range, libMesh::Threads::in_threads, and libMesh::libmesh_assert().

Referenced by libMesh::FEMSystem::assemble_qoi(), libMesh::FEMSystem::assemble_qoi_derivative(), libMesh::FEMSystem::assembly(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::MeshTetInterface::check_hull_integrity(), libMesh::MeshRefinement::create_parent_error_vector(), libMesh::MeshTools::n_active_local_levels(), libMesh::FEMSystem::postprocess(), and libMesh::MeshBase::subdomain_ids().

◆ active_local_subdomain_elements_ptr_range() [1/2]

virtual SimpleRange< const_element_iterator > libMesh::DistributedMesh::active_local_subdomain_elements_ptr_range ( subdomain_id_type  sid) const
inlinefinaloverridevirtualinherited

Implements libMesh::MeshBase.

Definition at line 363 of file distributed_mesh.h.

363{ return active_local_subdomain_element_ptr_range(sid); }

◆ active_local_subdomain_elements_ptr_range() [2/2]

virtual SimpleRange< element_iterator > libMesh::DistributedMesh::active_local_subdomain_elements_ptr_range ( subdomain_id_type  sid)
inlinefinaloverridevirtualinherited

Implements libMesh::MeshBase.

Definition at line 362 of file distributed_mesh.h.

362{ return active_local_subdomain_element_ptr_range(sid); }

◆ active_subdomain_elements_ptr_range() [1/2]

virtual SimpleRange< const_element_iterator > libMesh::DistributedMesh::active_subdomain_elements_ptr_range ( subdomain_id_type  sid) const
inlinefinaloverridevirtualinherited

Implements libMesh::MeshBase.

Definition at line 361 of file distributed_mesh.h.

361{ return active_subdomain_element_ptr_range(sid); }

◆ active_subdomain_elements_ptr_range() [2/2]

unsigned int level ElemType type std::set< subdomain_id_type > virtual ss SimpleRange< element_iterator > libMesh::DistributedMesh::active_subdomain_elements_ptr_range ( subdomain_id_type  sid)
inlinefinaloverridevirtualinherited

Implements libMesh::MeshBase.

Definition at line 360 of file distributed_mesh.h.

360{ return active_subdomain_element_ptr_range(sid); }

◆ active_subdomain_set_elements_ptr_range() [1/2]

virtual SimpleRange< const_element_iterator > libMesh::DistributedMesh::active_subdomain_set_elements_ptr_range ( std::set< subdomain_id_type >  ss) const
inlinefinaloverridevirtualinherited

Implements libMesh::MeshBase.

Definition at line 365 of file distributed_mesh.h.

365{ return active_subdomain_set_element_ptr_range(ss); }
unsigned int level ElemType type std::set< subdomain_id_type > ss

References libMesh::DistributedMesh::ss.

◆ active_subdomain_set_elements_ptr_range() [2/2]

virtual SimpleRange< element_iterator > libMesh::DistributedMesh::active_subdomain_set_elements_ptr_range ( std::set< subdomain_id_type >  ss)
inlinefinaloverridevirtualinherited

Implements libMesh::MeshBase.

Definition at line 364 of file distributed_mesh.h.

364{ return active_subdomain_set_element_ptr_range(ss); }

References libMesh::DistributedMesh::ss.

◆ add_disjoint_neighbor_boundary_pairs()

void libMesh::MeshBase::add_disjoint_neighbor_boundary_pairs ( const boundary_id_type  b1,
const boundary_id_type  b2,
const RealVectorValue &  translation 
)
inherited

Register a pair of boundaries as disjoint neighbor boundary pairs.

Definition at line 2287 of file mesh_base.C.

2290 {
2291 // Lazily allocate the container the first time it’s needed
2293 _disjoint_neighbor_boundary_pairs = std::make_unique<PeriodicBoundaries>();
2294
2295 PeriodicBoundaries & db = *_disjoint_neighbor_boundary_pairs;
2296
2297 // Create forward and inverse boundary mappings
2298 PeriodicBoundary forward(translation);
2299 PeriodicBoundary inverse(translation * -1.0);
2300
2301 forward.myboundary = b1;
2302 forward.pairedboundary = b2;
2303 inverse.myboundary = b2;
2304 inverse.pairedboundary = b1;
2305
2306 // Add both directions into the container
2307 db.emplace(b1, forward.clone());
2308 db.emplace(b2, inverse.clone());
2309 }
std::unique_ptr< PeriodicBoundaries > _disjoint_neighbor_boundary_pairs
The disjoint neighbor boundary id pairs.
Definition mesh_base.h:2131
LIBMESH_DEVICE_INLINE ResultTensor inverse(const TensorLike &T_in, const unsigned int dim=LIBMESH_DIM)

References libMesh::MeshBase::_disjoint_neighbor_boundary_pairs, libMesh::PeriodicBoundary::clone(), libMesh::PeriodicBoundaryBase::myboundary, and libMesh::PeriodicBoundaryBase::pairedboundary.

Referenced by DisjointNeighborTest::build_four_disjoint_elems(), DisjointNeighborTest::build_split_mesh_with_interface(), DisjointNeighborTest::build_two_disjoint_elems(), libMesh::CheckpointIO::read_header(), libMesh::UnstructuredMesh::stitching_helper(), DisjointNeighborTest::testDisjointNeighborConflictError(), CheckpointIOTest::testDisjointNeighborPairsCheckpoint(), and DisjointNeighborTest::testStitchCrossMesh().

◆ add_elem() [1/2]

Elem * libMesh::DistributedMesh::add_elem ( Elem *  e)
finaloverridevirtualinherited

Add elem e to the end of the element array.

To add an element locally, set e->processor_id() before adding it. 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::complete_preparation() after elements are added to and/or deleted from the mesh.

Implements libMesh::MeshBase.

Definition at line 594 of file distributed_mesh.C.

595{
596 // Don't try to add nullptrs!
598
599 // Trying to add an existing element is a no-op
600 if (e->valid_id() && _elements[e->id()] == e)
601 return e;
602
603 const processor_id_type elem_procid = e->processor_id();
604
605 if (!e->valid_id())
606 {
607 // We should only be creating new ids past the end of the range
608 // of existing ids
609 libmesh_assert_greater_equal(_next_free_unpartitioned_elem_id,
611 libmesh_assert_greater_equal(_next_free_local_elem_id, _max_elem_id);
612
613 // Use the unpartitioned ids for unpartitioned elems, and
614 // temporarily for ghost elems
616 if (elem_procid == this->processor_id())
617 next_id = &_next_free_local_elem_id;
618 e->set_id (*next_id);
619 }
620
621 {
622 // Advance next_ids up high enough that each is pointing to an
623 // unused id and any subsequent increments will still point us
624 // to unused ids
625 _max_elem_id = std::max(_max_elem_id,
626 static_cast<dof_id_type>(e->id()+1));
627
630 ((_max_elem_id-1) / (this->n_processors() + 1) + 1) *
631 (this->n_processors() + 1) + this->n_processors();
634 ((_max_elem_id + this->n_processors() - 1) / (this->n_processors() + 1) + 1) *
635 (this->n_processors() + 1) + this->processor_id();
636
637#ifndef NDEBUG
638 // We need a const dofobject_container so we don't inadvertently create
639 // nullptr entries when testing for non-nullptr ones
640 const dofobject_container<Elem> & const_elements = _elements;
641#endif
644 }
645
646 // Don't try to overwrite existing elems
647 libmesh_assert (!_elements[e->id()]);
648
649 _elements[e->id()] = e;
650
651 // We actually added a new element. Some of our caches might still
652 // be valid, but we should clear the ones which definitely are not.
653 this->clear_point_locator();
654 this->clear_stored_ranges();
655
656 // Try to make the cached elem data more accurate
657 if (elem_procid == this->processor_id() ||
658 elem_procid == DofObject::invalid_processor_id)
659 _n_elem++;
660
661#ifdef LIBMESH_ENABLE_UNIQUE_ID
662 if (!e->valid_unique_id())
663 {
664 if (processor_id() == e->processor_id())
665 {
666 e->set_unique_id(_next_unique_id);
667 _next_unique_id += this->n_processors() + 1;
668 }
669 else
670 {
671 e->set_unique_id(_next_unpartitioned_unique_id);
673 }
674 }
675 else
676 {
677 _next_unique_id = std::max(_next_unique_id, e->unique_id()+1);
679 ((_next_unique_id + this->n_processors() - 1) / (this->n_processors() + 1) + 1) *
680 (this->n_processors() + 1) + this->processor_id();
681 }
682#endif
683
684 // Unpartitioned elems should be added on every processor
685 // And shouldn't be added in the same batch as ghost elems
686 // But we might be just adding on processor 0 to
687 // broadcast later
688 // #ifdef DEBUG
689 // if (elem_procid == DofObject::invalid_processor_id)
690 // {
691 // dof_id_type elem_id = e->id();
692 // this->comm().max(elem_id);
693 // libmesh_assert_equal_to (elem_id, e->id());
694 // }
695 // #endif
696
697 // Make sure any new element is given space for any extra integers
698 // we've requested
699 e->add_extra_integers(_elem_integer_names.size(),
701
702 // And set mapping type and data on any new element
703 e->set_mapping_type(this->default_mapping_type());
704 e->set_mapping_data(this->default_mapping_data());
705
706 return e;
707}
dof_id_type _next_free_unpartitioned_elem_id
dofobject_container< Elem > _elements
The elements in the mesh.
unique_id_type _next_unpartitioned_unique_id
The next available unique id for assigning ids to unpartitioned DOF objects.
static constexpr processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
Definition dof_object.h:484
ElemMappingType default_mapping_type() const
Returns the default master space to physical space mapping basis functions to be used on newly added ...
Definition mesh_base.h:938
unique_id_type _next_unique_id
The next available unique id for assigning ids to DOF objects.
Definition mesh_base.h:2257
std::vector< std::string > _elem_integer_names
The array of names for integer data associated with each element in the mesh.
Definition mesh_base.h:2383
std::vector< dof_id_type > _elem_integer_default_values
The array of default initialization values for integer data associated with each element in the mesh.
Definition mesh_base.h:2389
unsigned char default_mapping_data() const
Returns any default data value used by the master space to physical space mapping.
Definition mesh_base.h:956
void clear_point_locator()
Releases the current PointLocator object.
Definition mesh_base.C:1881
void clear_stored_ranges()
Clears stored ranges, to indicate that the mesh has changed and they should be regenerated when next ...
Definition mesh_base.C:1984
processor_id_type processor_id() const
processor_id_type n_processors() const
uint8_t dof_id_type
Definition id_types.h:67
uint8_t processor_id_type
Definition id_types.h:104

References libMesh::MeshBase::_elem_integer_default_values, libMesh::MeshBase::_elem_integer_names, libMesh::DistributedMesh::_elements, libMesh::DistributedMesh::_max_elem_id, libMesh::DistributedMesh::_n_elem, libMesh::DistributedMesh::_next_free_local_elem_id, libMesh::DistributedMesh::_next_free_unpartitioned_elem_id, libMesh::MeshBase::_next_unique_id, libMesh::DistributedMesh::_next_unpartitioned_unique_id, libMesh::DofObject::add_extra_integers(), libMesh::MeshBase::clear_point_locator(), libMesh::MeshBase::clear_stored_ranges(), libMesh::MeshBase::default_mapping_data(), libMesh::MeshBase::default_mapping_type(), libMesh::DofObject::id(), libMesh::DofObject::invalid_processor_id, libMesh::libmesh_assert(), libMesh::ParallelObject::n_processors(), libMesh::DofObject::processor_id(), libMesh::ParallelObject::processor_id(), libMesh::DofObject::set_id(), libMesh::Elem::set_mapping_data(), libMesh::Elem::set_mapping_type(), libMesh::DofObject::set_unique_id(), libMesh::DofObject::unique_id(), libMesh::DofObject::valid_id(), and libMesh::DofObject::valid_unique_id().

Referenced by libMesh::DistributedMesh::add_elem(), libMesh::DistributedMesh::add_extra_ghost_elem(), DisjointNeighborTest::testDisjointNeighborConflictError(), and DisjointNeighborTest::testStitchCrossMesh().

◆ add_elem() [2/2]

Elem * libMesh::DistributedMesh::add_elem ( std::unique_ptr< Elem >  e)
finaloverridevirtualinherited

Version of add_elem() taking a std::unique_ptr by value.

The version taking a dumb pointer will eventually be deprecated in favor of this version. This API is intended to indicate that ownership of the Elem is transferred to the Mesh when this function is called, and it should play more nicely with the Elem::build() API which has always returned a std::unique_ptr.

Implements libMesh::MeshBase.

Definition at line 711 of file distributed_mesh.C.

712{
713 // The mesh now takes ownership of the Elem. Eventually the guts of
714 // add_elem() will get moved to a private helper function, and
715 // calling add_elem() directly will be deprecated.
716 return add_elem(e.release());
717}
virtual Elem * add_elem(Elem *e) override final
Add elem e to the end of the element array.

References libMesh::DistributedMesh::add_elem().

◆ add_elem_data()

template<typename T >
std::vector< unsigned int > libMesh::MeshBase::add_elem_data ( const std::vector< std::string > &  names,
bool  allocate_data = true,
const std::vector< T > *  default_values = nullptr 
)
inlineinherited

Register data (of type T) to be added to each element in the mesh.

If the mesh already has elements, data is allocated in each.

Newly allocated values for the new datum with name names[i] will be initialized to default_values[i], or to meaningless memcpy output if default_values is null.

Returns
The starting index number for the new data, or for the existing data if one by the same name has already been added.

If type T is larger than dof_id_type, each datum will end up spanning multiple index values, but will be queried with the starting index number.

No type checking is done with this function! If you add data of type T, don't try to access it with a call specifying type U.

Definition at line 2725 of file mesh_base.h.

2728{
2729 libmesh_assert(!default_values || default_values->size() == names.size());
2730
2731 std::vector<unsigned int> returnval(names.size());
2732
2733 const std::size_t old_size = _elem_integer_names.size();
2734
2735 for (auto i : index_range(names))
2736 returnval[i] =
2737 this->add_elem_datum<T>(names[i], false,
2738 default_values ?
2739 (*default_values)[i] : nullptr);
2740
2741 if (allocate_data && old_size != _elem_integer_names.size())
2743
2744 return returnval;
2745}
void size_elem_extra_integers()
Size extra-integer arrays of all elements in the mesh.
Definition mesh_base.C:2376
unsigned int add_elem_datum(const std::string &name, bool allocate_data=true, const T *default_value=nullptr)
Register a datum (of type T) to be added to each element in the mesh.
Definition mesh_base.h:2701
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition int_range.h:153

References libMesh::MeshBase::_elem_integer_names, libMesh::index_range(), libMesh::libmesh_assert(), and libMesh::MeshBase::size_elem_extra_integers().

◆ add_elem_datum()

template<typename T >
unsigned int libMesh::MeshBase::add_elem_datum ( const std::string &  name,
bool  allocate_data = true,
const T *  default_value = nullptr 
)
inlineinherited

Register a datum (of type T) to be added to each element in the mesh.

If the mesh already has elements, data by default is allocated in each of them. This may be expensive to do repeatedly; use add_elem_data instead. Alternatively, the allocate_data option can be manually set to false, but if this is done then a manual call to size_elem_extra_integers() will need to be done before the new space is usable.

Newly allocated values for the new datum will be initialized to *default_value if default_value is not null, or to meaningless memcpy output otherwise.

Returns
The index numbers for the new data, and/or for existing data if data by some of the same names has already been added.

If type T is larger than dof_id_type, its data will end up spanning multiple index values, but will be queried with the starting index number.

No type checking is done with this function! If you add data of type T, don't try to access it with a call specifying type U.

Definition at line 2701 of file mesh_base.h.

2704{
2705 const std::size_t old_size = _elem_integer_names.size();
2706
2707 unsigned int n_more_integers = (sizeof(T)-1)/sizeof(dof_id_type);
2708 std::vector<dof_id_type> int_data(n_more_integers+1, DofObject::invalid_id);
2709 if (default_value)
2710 std::memcpy(int_data.data(), default_value, sizeof(T));
2711
2712 unsigned int start_idx = this->add_elem_integer(name, false, int_data[0]);
2713 for (unsigned int i=0; i != n_more_integers; ++i)
2714 this->add_elem_integer(name+"__"+std::to_string(i), false, int_data[i+1]);
2715
2716 if (allocate_data && old_size != _elem_integer_names.size())
2718
2719 return start_idx;
2720}
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition dof_object.h:473
unsigned int add_elem_integer(std::string name, bool allocate_data=true, dof_id_type default_value=DofObject::invalid_id)
Register an integer datum (of type dof_id_type) to be added to each element in the mesh.
Definition mesh_base.C:623

References libMesh::MeshBase::_elem_integer_names, libMesh::MeshBase::add_elem_integer(), libMesh::DofObject::invalid_id, and libMesh::MeshBase::size_elem_extra_integers().

Referenced by ExtraIntegersTest::build_mesh().

◆ add_elem_integer()

unsigned int libMesh::MeshBase::add_elem_integer ( std::string  name,
bool  allocate_data = true,
dof_id_type  default_value = DofObject::invalid_id 
)
inherited

Register an integer datum (of type dof_id_type) to be added to each element in the mesh.

If the mesh already has elements, data by default is allocated in each of them. This may be expensive to do repeatedly; use add_elem_integers instead. Alternatively, the allocate_data option can be manually set to false, but if this is done then a manual call to size_elem_extra_integers() will need to be done before the new space is usable.

Newly allocated values for the new datum will be initialized to default_value

Returns
The index number for the new datum, or for the existing datum if one by the same name has already been added.

Definition at line 623 of file mesh_base.C.

626{
627 for (auto i : index_range(_elem_integer_names))
629 {
630 libmesh_assert_less(i, _elem_integer_default_values.size());
631 _elem_integer_default_values[i] = default_value;
632 return i;
633 }
634
635 libmesh_assert_equal_to(_elem_integer_names.size(),
637 _elem_integer_names.push_back(std::move(name));
638 _elem_integer_default_values.push_back(default_value);
639 if (allocate_data)
641 return _elem_integer_names.size()-1;
642}
std::string name(const ElemQuality q)
This function returns a string containing some name for q.

References libMesh::MeshBase::_elem_integer_default_values, libMesh::MeshBase::_elem_integer_names, libMesh::index_range(), and libMesh::MeshBase::size_elem_extra_integers().

Referenced by libMesh::MeshBase::add_elem_datum(), libMesh::BoundaryInfo::add_elements(), ExtraIntegersTest::build_mesh(), ExtraIntegersTest::checkpoint_helper(), libMesh::ExodusII_IO::read(), libMesh::CheckpointIO::read_header(), ExtraIntegersTest::test_helper(), MeshStitchTest::testMeshStitchElemsets(), and WriteElemsetData::testWriteImpl().

◆ add_elem_integers()

std::vector< unsigned int > libMesh::MeshBase::add_elem_integers ( const std::vector< std::string > &  names,
bool  allocate_data = true,
const std::vector< dof_id_type > *  default_values = nullptr 
)
inherited

Register integer data (of type dof_id_type) to be added to each element in the mesh, one string name for each new integer.

If the mesh already has elements, data by default is allocated in each of them.

Newly allocated values for the new datum with name names[i] will be initialized to default_values[i], or to DofObject::invalid_id if default_values is null.

Returns
The index numbers for the new data, and/or for existing data if data by some of the same names has already been added.

Definition at line 646 of file mesh_base.C.

649{
650 libmesh_assert(!default_values || default_values->size() == names.size());
651 libmesh_assert_equal_to(_elem_integer_names.size(), _elem_integer_default_values.size());
652
653 std::unordered_map<std::string, std::size_t> name_indices;
654 for (auto i : index_range(_elem_integer_names))
655 name_indices[_elem_integer_names[i]] = i;
656
657 std::vector<unsigned int> returnval(names.size());
658
659 bool added_an_integer = false;
660 for (auto i : index_range(names))
661 {
662 const std::string & name = names[i];
663 if (const auto it = name_indices.find(name);
664 it != name_indices.end())
665 {
666 returnval[i] = it->second;
667 _elem_integer_default_values[it->second] =
668 default_values ? (*default_values)[i] : DofObject::invalid_id;
669 }
670 else
671 {
672 returnval[i] = _elem_integer_names.size();
673 name_indices[name] = returnval[i];
674 _elem_integer_names.push_back(name);
676 (default_values ? (*default_values)[i] : DofObject::invalid_id);
677 added_an_integer = true;
678 }
679 }
680
681 if (allocate_data && added_an_integer)
683
684 return returnval;
685}

References libMesh::MeshBase::_elem_integer_default_values, libMesh::MeshBase::_elem_integer_names, libMesh::index_range(), libMesh::DofObject::invalid_id, libMesh::libmesh_assert(), and libMesh::MeshBase::size_elem_extra_integers().

Referenced by libMesh::MeshBase::merge_extra_integer_names(), and libMesh::XdrIO::read_header().

◆ add_elemset_code()

void libMesh::MeshBase::add_elemset_code ( dof_id_type  code,
MeshBase::elemset_type  id_set 
)
inherited

Tabulate a user-defined "code" for elements which belong to the element sets specified in id_set.

For example, suppose that we have two elemsets A and B with the following Elem ids: Elemset A = {1, 3} Elemset B = {2, 3}

This implies the following mapping from elem id to elemset id: Elem 1 -> {A} Elem 2 -> {B} Elem 3 -> {A,B}

In this case, we would need to tabulate three different elemset codes, e.g.: 0 -> {A} 1 -> {B} 2 -> {A,B}

Also sets up the inverse mapping, so that if one knows all the element sets an Elem belongs to, one can look up the corresponding elemset code.

Definition at line 461 of file mesh_base.C.

462{
463 // Populate inverse map, stealing id_set's resources
464 auto [it1, inserted1] = _elemset_codes_inverse_map.emplace(std::move(id_set), code);
465
466 // Reference to the newly inserted (or previously existing) id_set
467 const auto & inserted_id_set = it1->first;
468
469 // Keep track of all elemset ids ever added for O(1) n_elemsets()
470 // performance. Only need to do this if we didn't know about this
471 // id_set before...
472 if (inserted1)
473 _all_elemset_ids.insert(inserted_id_set.begin(), inserted_id_set.end());
474
475 // Take the address of the newly emplaced set to use in
476 // _elemset_codes, avoid duplicating std::set storage
477 auto [it2, inserted2] = _elemset_codes.emplace(code, &inserted_id_set);
478
479 // Throw an error if this code already exists with a pointer to a
480 // different set of ids.
481 libmesh_error_msg_if(!inserted2 && it2->second != &inserted_id_set,
482 "The elemset code " << code << " already exists with a different id_set.");
483}
MeshBase::elemset_type _all_elemset_ids
Definition mesh_base.h:2371
std::map< dof_id_type, const MeshBase::elemset_type * > _elemset_codes
Map from "element set code" to list of set ids to which that element belongs (and vice-versa).
Definition mesh_base.h:2369
std::map< MeshBase::elemset_type, dof_id_type > _elemset_codes_inverse_map
Definition mesh_base.h:2370

References libMesh::MeshBase::_all_elemset_ids, libMesh::MeshBase::_elemset_codes, and libMesh::MeshBase::_elemset_codes_inverse_map.

Referenced by libMesh::MeshBase::change_elemset_code(), libMesh::ExodusII_IO::read(), libMesh::XdrIO::read_header(), libMesh::UnstructuredMesh::stitching_helper(), MeshStitchTest::testMeshStitchElemsets(), and WriteElemsetData::testWriteImpl().

◆ add_extra_ghost_elem()

void libMesh::DistributedMesh::add_extra_ghost_elem ( Elem *  e)
virtualinherited

Inserts the element and adds it to a list of elements that should not get deleted or have their descendants deleted by delete_remote_elements.

This is handy for inserting otherwise off-processor elements that you want to keep track of on this processor.

Definition at line 1876 of file distributed_mesh.C.

1877{
1878 // First add the elem like normal
1879 add_elem(e);
1880
1881 // Now add it to the set that won't be deleted when we call
1882 // delete_remote_elements()
1883 _extra_ghost_elems.insert(e);
1884}
std::set< Elem * > _extra_ghost_elems
These are extra ghost elements that we want to make sure not to delete when we call delete_remote_ele...

References libMesh::DistributedMesh::_extra_ghost_elems, and libMesh::DistributedMesh::add_elem().

◆ add_ghosting_functor() [1/2]

void libMesh::MeshBase::add_ghosting_functor ( GhostingFunctor &  ghosting_functor)
inherited

Adds a functor which can specify ghosting requirements for use on distributed meshes.

Multiple ghosting functors can be added; any element which is required by any functor will be ghosted.

GhostingFunctor memory must be managed by the code which calls this function; the GhostingFunctor lifetime is expected to extend until either the functor is removed or the Mesh is destructed.

Definition at line 1079 of file mesh_base.C.

1080{
1081 // We used to implicitly support duplicate inserts to std::set
1082#ifdef LIBMESH_ENABLE_DEPRECATED
1083 _ghosting_functors.erase
1084 (std::remove(_ghosting_functors.begin(),
1085 _ghosting_functors.end(),
1086 &ghosting_functor),
1087 _ghosting_functors.end());
1088#endif
1089
1090 // We shouldn't have two copies of the same functor
1091 libmesh_assert(std::find(_ghosting_functors.begin(),
1092 _ghosting_functors.end(),
1093 &ghosting_functor) ==
1094 _ghosting_functors.end());
1095
1096 _ghosting_functors.push_back(&ghosting_functor);
1097}
std::vector< GhostingFunctor * > _ghosting_functors
The list of all GhostingFunctor objects to be used when distributing a DistributedMesh.
Definition mesh_base.h:2436

References libMesh::MeshBase::_ghosting_functors, and libMesh::libmesh_assert().

Referenced by libMesh::MeshBase::add_ghosting_functor(), main(), libMesh::MeshBase::MeshBase(), and EquationSystemsTest::testDisableDefaultGhosting().

◆ add_ghosting_functor() [2/2]

void libMesh::MeshBase::add_ghosting_functor ( std::shared_ptr< GhostingFunctor >  ghosting_functor)
inlineinherited

Adds a functor which can specify ghosting requirements for use on distributed meshes.

Multiple ghosting functors can be added; any element which is required by any functor will be ghosted.

GhostingFunctor memory when using this method is managed by the shared_ptr mechanism.

Definition at line 1456 of file mesh_base.h.

1457 { _shared_functors[ghosting_functor.get()] = ghosting_functor;
1458 this->add_ghosting_functor(*ghosting_functor); }
std::map< GhostingFunctor *, std::shared_ptr< GhostingFunctor > > _shared_functors
Hang on to references to any GhostingFunctor objects we were passed in shared_ptr form.
Definition mesh_base.h:2442
void add_ghosting_functor(GhostingFunctor &ghosting_functor)
Adds a functor which can specify ghosting requirements for use on distributed meshes.
Definition mesh_base.C:1079

References libMesh::MeshBase::_shared_functors, and libMesh::MeshBase::add_ghosting_functor().

◆ add_node() [1/2]

Node * libMesh::DistributedMesh::add_node ( Node *  n)
finaloverridevirtualinherited

Add Node n to the end of the vertex array.

Implements libMesh::MeshBase.

Definition at line 884 of file distributed_mesh.C.

885{
886 // Don't try to add nullptrs!
888
889 // Trying to add an existing node is a no-op
890 if (n->valid_id() && _nodes[n->id()] == n)
891 return n;
892
893 const processor_id_type node_procid = n->processor_id();
894
895 if (!n->valid_id())
896 {
897 // We should only be creating new ids past the end of the range
898 // of existing ids
899 libmesh_assert_greater_equal(_next_free_unpartitioned_node_id,
901 libmesh_assert_greater_equal(_next_free_local_node_id, _max_node_id);
902
903 // Use the unpartitioned ids for unpartitioned nodes,
904 // and temporarily for ghost nodes
906 if (node_procid == this->processor_id())
907 next_id = &_next_free_local_node_id;
908 n->set_id (*next_id);
909 }
910
911 {
912 // Advance next_ids up high enough that each is pointing to an
913 // unused id and any subsequent increments will still point us
914 // to unused ids
915 _max_node_id = std::max(_max_node_id,
916 static_cast<dof_id_type>(n->id()+1));
917
920 ((_max_node_id-1) / (this->n_processors() + 1) + 1) *
921 (this->n_processors() + 1) + this->n_processors();
924 ((_max_node_id + this->n_processors() - 1) / (this->n_processors() + 1) + 1) *
925 (this->n_processors() + 1) + this->processor_id();
926
927#ifndef NDEBUG
928 // We need a const dofobject_container so we don't inadvertently create
929 // nullptr entries when testing for non-nullptr ones
930 const dofobject_container<Node> & const_nodes = _nodes;
931#endif
934 }
935
936 // Don't try to overwrite existing nodes
937 libmesh_assert (!_nodes[n->id()]);
938
939 _nodes[n->id()] = n;
940
941 // Try to make the cached node data more accurate
942 if (node_procid == this->processor_id() ||
943 node_procid == DofObject::invalid_processor_id)
944 _n_nodes++;
945
946#ifdef LIBMESH_ENABLE_UNIQUE_ID
947 if (!n->valid_unique_id())
948 {
949 if (processor_id() == n->processor_id())
950 {
951 n->set_unique_id(_next_unique_id);
952 _next_unique_id += this->n_processors() + 1;
953 }
954 else
955 {
956 n->set_unique_id(_next_unpartitioned_unique_id);
958 }
959 }
960 else
961 {
962 _next_unique_id = std::max(_next_unique_id, n->unique_id()+1);
964 ((_next_unique_id + this->n_processors() - 1) / (this->n_processors() + 1) + 1) *
965 (this->n_processors() + 1) + this->processor_id();
966 }
967#endif
968
969 n->add_extra_integers(_node_integer_names.size(),
971
972 // Unpartitioned nodes should be added on every processor
973 // And shouldn't be added in the same batch as ghost nodes
974 // But we might be just adding on processor 0 to
975 // broadcast later
976 // #ifdef DEBUG
977 // if (node_procid == DofObject::invalid_processor_id)
978 // {
979 // dof_id_type node_id = n->id();
980 // this->comm().max(node_id);
981 // libmesh_assert_equal_to (node_id, n->id());
982 // }
983 // #endif
984
985 return n;
986}
dof_id_type _n_nodes
Cached data from the last renumber_nodes_and_elements call.
dof_id_type _next_free_unpartitioned_node_id
processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num unsigned char rflag processor_id_type pid const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num DECLARE_NODE_ITERATORS(multi_evaluable_, std::vector< const DofMap * > dof_maps, dof_maps) protected dofobject_container< Node > _nodes
Move node and elements from a DistributedMesh.
dof_id_type _next_free_local_node_id
Guaranteed globally unused IDs for use when adding new nodes or elements.
std::vector< dof_id_type > _node_integer_default_values
The array of default initialization values for integer data associated with each node in the mesh.
Definition mesh_base.h:2401
std::vector< std::string > _node_integer_names
The array of names for integer data associated with each node in the mesh.
Definition mesh_base.h:2395

References libMesh::DistributedMesh::_max_node_id, libMesh::DistributedMesh::_n_nodes, libMesh::DistributedMesh::_next_free_local_node_id, libMesh::DistributedMesh::_next_free_unpartitioned_node_id, libMesh::MeshBase::_next_unique_id, libMesh::DistributedMesh::_next_unpartitioned_unique_id, libMesh::MeshBase::_node_integer_default_values, libMesh::MeshBase::_node_integer_names, libMesh::DistributedMesh::_nodes, libMesh::DofObject::add_extra_integers(), libMesh::DofObject::id(), libMesh::DofObject::invalid_processor_id, libMesh::libmesh_assert(), libMesh::ParallelObject::n_processors(), libMesh::DofObject::processor_id(), libMesh::ParallelObject::processor_id(), libMesh::DofObject::set_id(), libMesh::DofObject::set_unique_id(), libMesh::DofObject::unique_id(), libMesh::DofObject::valid_id(), and libMesh::DofObject::valid_unique_id().

Referenced by libMesh::DistributedMesh::add_node(), libMesh::DistributedMesh::add_point(), and libMesh::DistributedMesh::own_node().

◆ add_node() [2/2]

Node * libMesh::DistributedMesh::add_node ( std::unique_ptr< Node >  n)
finaloverridevirtualinherited

Version of add_node() taking a std::unique_ptr by value.

The version taking a dumb pointer will eventually be deprecated in favor of this version. This API is intended to indicate that ownership of the Node is transferred to the Mesh when this function is called, and it should play more nicely with the Node::build() API which has always returned a std::unique_ptr.

Implements libMesh::MeshBase.

Definition at line 988 of file distributed_mesh.C.

989{
990 // The mesh now takes ownership of the Node. Eventually the guts of
991 // add_node() will get moved to a private helper function, and
992 // calling add_node() directly will be deprecated.
993 return add_node(n.release());
994}
virtual Node * add_node(Node *n) override final
Add Node n to the end of the vertex array.

References libMesh::DistributedMesh::add_node().

◆ add_node_data()

template<typename T >
std::vector< unsigned int > libMesh::MeshBase::add_node_data ( const std::vector< std::string > &  name,
bool  allocate_data = true,
const std::vector< T > *  default_values = nullptr 
)
inlineinherited

Register data (of type T) to be added to each node in the mesh.

If the mesh already has nodes, data by default is allocated in each.

Newly allocated values for the new datum with name names[i] will be initialized to default_values[i], or to meaningless memcpy output if default_values is null.

Returns
The starting index number for the new data, or for the existing data if one by the same name has already been added.

If type T is larger than dof_id_type, its data will end up spanning multiple index values, but will be queried with the starting index number.

No type checking is done with this function! If you add data of type T, don't try to access it with a call specifying type U.

Definition at line 2774 of file mesh_base.h.

2777{
2778 libmesh_assert(!default_values || default_values->size() == names.size());
2779
2780 std::vector<unsigned int> returnval(names.size());
2781
2782 const std::size_t old_size = _node_integer_names.size();
2783
2784 for (auto i : index_range(names))
2785 returnval[i] =
2786 this->add_node_datum<T>(names[i], false,
2787 default_values ?
2788 (*default_values)[i] : nullptr);
2789
2790 if (allocate_data && old_size != _node_integer_names.size())
2792
2793 return returnval;
2794}
unsigned int add_node_datum(const std::string &name, bool allocate_data=true, const T *default_value=nullptr)
Register a datum (of type T) to be added to each node in the mesh.
Definition mesh_base.h:2750
void size_node_extra_integers()
Size extra-integer arrays of all nodes in the mesh.
Definition mesh_base.C:2391

References libMesh::MeshBase::_node_integer_names, libMesh::index_range(), libMesh::libmesh_assert(), and libMesh::MeshBase::size_node_extra_integers().

◆ add_node_datum()

template<typename T >
unsigned int libMesh::MeshBase::add_node_datum ( const std::string &  name,
bool  allocate_data = true,
const T *  default_value = nullptr 
)
inlineinherited

Register a datum (of type T) to be added to each node in the mesh.

If the mesh already has nodes, data by default is allocated in each of them. This may be expensive to do repeatedly; use add_node_data instead. Alternatively, the allocate_data option can be manually set to false, but if this is done then a manual call to size_node_extra_integers() will need to be done before the new space is usable.

Newly allocated values for the new datum will be initialized to *default_value if default_value is not null, or to meaningless memcpy output otherwise.

Returns
The starting index number for the new datum, or for the existing datum if one by the same name has already been added.

If type T is larger than dof_id_type, its data will end up spanning multiple index values, but will be queried with the starting index number.

No type checking is done with this function! If you add data of type T, don't try to access it with a call specifying type U.

Definition at line 2750 of file mesh_base.h.

2753{
2754 const std::size_t old_size = _node_integer_names.size();
2755
2756 unsigned int n_more_integers = (sizeof(T)-1)/sizeof(dof_id_type);
2757 std::vector<dof_id_type> int_data(n_more_integers+1, DofObject::invalid_id);
2758 if (default_value)
2759 std::memcpy(int_data.data(), default_value, sizeof(T));
2760
2761 unsigned int start_idx = this->add_node_integer(name, false, int_data[0]);
2762 for (unsigned int i=0; i != n_more_integers; ++i)
2763 this->add_node_integer(name+"__"+std::to_string(i), false, int_data[i+1]);
2764
2765 if (allocate_data && old_size != _node_integer_names.size())
2767
2768 return start_idx;
2769}
unsigned int add_node_integer(std::string name, bool allocate_data=true, dof_id_type default_value=DofObject::invalid_id)
Register an integer datum (of type dof_id_type) to be added to each node in the mesh.
Definition mesh_base.C:712

References libMesh::MeshBase::_node_integer_names, libMesh::MeshBase::add_node_integer(), libMesh::DofObject::invalid_id, and libMesh::MeshBase::size_node_extra_integers().

Referenced by libMesh::MeshTools::Modification::all_rbb(), ExtraIntegersTest::build_mesh(), libMesh::ExodusII_IO::read(), and libMesh::DynaIO::read_mesh().

◆ add_node_integer()

unsigned int libMesh::MeshBase::add_node_integer ( std::string  name,
bool  allocate_data = true,
dof_id_type  default_value = DofObject::invalid_id 
)
inherited

Register an integer datum (of type dof_id_type) to be added to each node in the mesh.

If the mesh already has nodes, data by default is allocated in each of them. This may be expensive to do repeatedly; use add_node_integers instead. Alternatively, the allocate_data option can be manually set to false, but if this is done then a manual call to size_node_extra_integers() will need to be done before the new space is usable.

Newly allocated values for the new datum will be initialized to default_value

Returns
The index number for the new datum, or for the existing datum if one by the same name has already been added.

Definition at line 712 of file mesh_base.C.

715{
716 for (auto i : index_range(_node_integer_names))
718 {
719 libmesh_assert_less(i, _node_integer_default_values.size());
720 _node_integer_default_values[i] = default_value;
721 return i;
722 }
723
724 libmesh_assert_equal_to(_node_integer_names.size(),
726 _node_integer_names.push_back(std::move(name));
727 _node_integer_default_values.push_back(default_value);
728 if (allocate_data)
730 return _node_integer_names.size()-1;
731}

References libMesh::MeshBase::_node_integer_default_values, libMesh::MeshBase::_node_integer_names, libMesh::index_range(), and libMesh::MeshBase::size_node_extra_integers().

Referenced by libMesh::MeshBase::add_node_datum(), ExtraIntegersTest::build_mesh(), ExtraIntegersTest::checkpoint_helper(), libMesh::CheckpointIO::read_header(), and ExtraIntegersTest::test_helper().

◆ add_node_integers()

std::vector< unsigned int > libMesh::MeshBase::add_node_integers ( const std::vector< std::string > &  names,
bool  allocate_data = true,
const std::vector< dof_id_type > *  default_values = nullptr 
)
inherited

Register integer data (of type dof_id_type) to be added to each node in the mesh.

If the mesh already has nodes, data by default is allocated in each.

Newly allocated values for the new datum with name names[i] will be initialized to default_values[i], or to DofObject::invalid_id if default_values is null.

Returns
The index numbers for the new data, and/or for existing data if data by some of the same names has already been added.

Definition at line 735 of file mesh_base.C.

738{
739 libmesh_assert(!default_values || default_values->size() == names.size());
740 libmesh_assert_equal_to(_node_integer_names.size(), _node_integer_default_values.size());
741
742 std::unordered_map<std::string, std::size_t> name_indices;
743 for (auto i : index_range(_node_integer_names))
744 name_indices[_node_integer_names[i]] = i;
745
746 std::vector<unsigned int> returnval(names.size());
747
748 bool added_an_integer = false;
749 for (auto i : index_range(names))
750 {
751 const std::string & name = names[i];
752 if (const auto it = name_indices.find(name);
753 it != name_indices.end())
754 {
755 returnval[i] = it->second;
756 _node_integer_default_values[it->second] =
757 default_values ? (*default_values)[i] : DofObject::invalid_id;
758 }
759 else
760 {
761 returnval[i] = _node_integer_names.size();
762 name_indices[name] = returnval[i];
763 _node_integer_names.push_back(name);
765 (default_values ? (*default_values)[i] : DofObject::invalid_id);
766 added_an_integer = true;
767 }
768 }
769
770 if (allocate_data && added_an_integer)
772
773 return returnval;
774}

References libMesh::MeshBase::_node_integer_default_values, libMesh::MeshBase::_node_integer_names, libMesh::index_range(), libMesh::DofObject::invalid_id, libMesh::libmesh_assert(), and libMesh::MeshBase::size_node_extra_integers().

Referenced by libMesh::MeshBase::merge_extra_integer_names(), and libMesh::XdrIO::read_header().

◆ add_point()

Node * libMesh::DistributedMesh::add_point ( const Point &  p,
const dof_id_type  id = DofObject::invalid_id,
const processor_id_type  proc_id = DofObject::invalid_processor_id 
)
finaloverridevirtualinherited

functions for adding /deleting nodes elements.

Implements libMesh::MeshBase.

Definition at line 848 of file distributed_mesh.C.

851{
852 Node * old_n = this->query_node_ptr(id);
853
854 if (old_n)
855 {
856 *old_n = p;
857 old_n->processor_id() = proc_id;
858
859 return old_n;
860 }
861
862 Node * n = Node::build(p, id).release();
863 n->processor_id() = proc_id;
864
866}
virtual const Node * query_node_ptr(const dof_id_type i) const override final
static std::unique_ptr< Node > build(const Node &n)
Definition node.h:315

References libMesh::DistributedMesh::add_node(), libMesh::Node::build(), libMesh::DofObject::processor_id(), and libMesh::DistributedMesh::query_node_ptr().

Referenced by DisjointNeighborTest::testDisjointNeighborConflictError(), and DisjointNeighborTest::testStitchCrossMesh().

◆ all_complete_order()

void libMesh::MeshBase::all_complete_order ( )
virtualinherited

Calls the range-based version of this function with a range consisting of all elements in the mesh.

Definition at line 1823 of file mesh_base.C.

1824{
1825 this->all_complete_order_range(this->element_ptr_range());
1826}
virtual void all_complete_order_range(const SimpleRange< element_iterator > &range)=0
Converts a set of elements in this (conforming, non-refined) mesh into "complete" order elements,...

References libMesh::MeshBase::all_complete_order_range().

Referenced by AllSecondOrderTest::allCompleteOrder(), libMesh::MeshTools::Generation::build_cube(), FEHybridOrientationTest< order, family >::build_mesh(), libMesh::MeshTetInterface::increase_tet_order(), libMesh::TriangulatorInterface::increase_triangle_order(), main(), and MeshTetTest::testNetGenTet14Curved().

◆ all_complete_order_range()

void libMesh::UnstructuredMesh::all_complete_order_range ( const SimpleRange< element_iterator > &  range)
overridevirtualinherited

Converts a (conforming, non-refined) mesh with linear elements into a mesh with "complete" order elements, i.e.

elements which can store degrees of freedom on any vertex, edge, or face. For example, a mesh consisting of Tet4 or Tet10 will be converted to a mesh with Tet14 etc.

Implements libMesh::MeshBase.

Definition at line 1848 of file unstructured_mesh.C.

1849{
1850 LOG_SCOPE("all_complete_order()", "Mesh");
1851
1852 /*
1853 * The maximum number of new higher-order nodes we might be adding,
1854 * for use when picking unique unique_id values later. This variable
1855 * is not used unless unique ids are enabled.
1856 */
1857 unsigned int max_new_nodes_per_elem;
1858
1859 /*
1860 * for speed-up of the \p add_point() method, we
1861 * can reserve memory. Guess the number of additional
1862 * nodes based on the element spatial dimensions and the
1863 * total number of nodes in the mesh as an upper bound.
1864 */
1865 switch (this->mesh_dimension())
1866 {
1867 case 1:
1868 /*
1869 * in 1D, there can only be order-increase from Edge2
1870 * to Edge3. Something like 1/2 of n_nodes() have
1871 * to be added
1872 */
1873 max_new_nodes_per_elem = 3 - 2;
1874 this->reserve_nodes(static_cast<unsigned int>
1875 (1.5*static_cast<double>(this->n_nodes())));
1876 break;
1877
1878 case 2:
1879 /*
1880 * in 2D, we typically refine from Tri3 or Tri6 to Tri7 (2.3333
1881 * or 1.1667 times the nodes) but might refine from Quad4 to
1882 * Quad9 (2.25 times the nodes)
1883 */
1884 max_new_nodes_per_elem = 9 - 4;
1885 this->reserve_nodes(static_cast<unsigned int>
1886 (2*static_cast<double>(this->n_nodes())));
1887 break;
1888
1889
1890 case 3:
1891 /*
1892 * in 3D, we typically refine from Tet10 to Tet14 (factor = 1.4)
1893 * but may go Hex8 to Hex27 or Tet4 to Tet14 (something > 3).
1894 * Since in 3D there _are_ already quite some nodes, and since
1895 * we do not want to overburden the memory by a too-conservative
1896 * guess, use a moderate bound
1897 */
1898 max_new_nodes_per_elem = 27 - 8;
1899 this->reserve_nodes(static_cast<unsigned int>
1900 (2.5*static_cast<double>(this->n_nodes())));
1901 break;
1902
1903 default:
1904 // Hm?
1905 libmesh_error_msg("Unknown mesh dimension " << this->mesh_dimension());
1906 }
1907
1908 // All the real work is done in the helper function
1909 all_increased_order_range(*this, range, max_new_nodes_per_elem,
1910 [](ElemType t) {
1912 });
1913}
static ElemType complete_order_equivalent_type(const ElemType et)
Definition elem.C:3755
unsigned int mesh_dimension() const
Definition mesh_base.C:435
virtual dof_id_type n_nodes() const =0
virtual void reserve_nodes(const dof_id_type nn)=0
Reserves space for a known number of nodes.
ElemType
Defines an enum for geometric element types.

References libMesh::Elem::complete_order_equivalent_type(), libMesh::MeshBase::mesh_dimension(), libMesh::MeshBase::n_nodes(), and libMesh::MeshBase::reserve_nodes().

◆ all_first_order()

void libMesh::UnstructuredMesh::all_first_order ( )
overridevirtualinherited

Converts a mesh with higher-order elements into a mesh with linear elements.

For example, a mesh consisting of Tet10 will be converted to a mesh with Tet4 etc.

Prepare to identify (and then delete) a bunch of no-longer-used nodes.

If the second order element had any boundary conditions they should be transferred to the first-order element. The old boundary conditions will be removed from the BoundaryInfo data structure by insert_elem.

Implements libMesh::MeshBase.

Definition at line 1646 of file unstructured_mesh.C.

1647{
1648 LOG_SCOPE("all_first_order()", "Mesh");
1649
1653 std::vector<bool> node_touched_by_me(this->max_node_id(), false);
1654
1655 // Loop over the high-ordered elements.
1656 // First make sure they _are_ indeed high-order, and then replace
1657 // them with an equivalent first-order element.
1658 for (auto & so_elem : element_ptr_range())
1659 {
1660 libmesh_assert(so_elem);
1661
1662 /*
1663 * build the first-order equivalent, add to
1664 * the new_elements list.
1665 */
1666 auto lo_elem = Elem::build
1668 (so_elem->type()), so_elem->parent());
1669
1670 const unsigned short n_sides = so_elem->n_sides();
1671
1672 for (unsigned short s=0; s != n_sides; ++s)
1673 if (so_elem->neighbor_ptr(s) == remote_elem)
1674 lo_elem->set_neighbor(s, const_cast<RemoteElem *>(remote_elem));
1675
1676#ifdef LIBMESH_ENABLE_AMR
1677 /*
1678 * Reset the parent links of any child elements
1679 */
1680 if (so_elem->has_children())
1681 for (unsigned int c = 0, nc = so_elem->n_children(); c != nc; ++c)
1682 {
1683 Elem * child = so_elem->child_ptr(c);
1684 if (child != remote_elem)
1685 child->set_parent(lo_elem.get());
1686 lo_elem->add_child(child, c);
1687 }
1688
1689 /*
1690 * Reset the child link of any parent element
1691 */
1692 if (so_elem->parent())
1693 {
1694 unsigned int c =
1695 so_elem->parent()->which_child_am_i(so_elem);
1696 lo_elem->parent()->replace_child(lo_elem.get(), c);
1697 }
1698
1699 /*
1700 * Copy as much data to the new element as makes sense
1701 */
1702 lo_elem->set_p_level(so_elem->p_level());
1703 lo_elem->set_refinement_flag(so_elem->refinement_flag());
1704 lo_elem->set_p_refinement_flag(so_elem->p_refinement_flag());
1705#endif
1706
1707 libmesh_assert_equal_to (lo_elem->n_vertices(), so_elem->n_vertices());
1708
1709 /*
1710 * By definition the vertices of the linear and
1711 * second order element are identically numbered.
1712 * transfer these.
1713 */
1714 for (unsigned int v=0, snv=so_elem->n_vertices(); v < snv; v++)
1715 {
1716 lo_elem->set_node(v, so_elem->node_ptr(v));
1717 node_touched_by_me[lo_elem->node_id(v)] = true;
1718 }
1719
1720 /*
1721 * find_neighbors relies on remote_elem neighbor links being
1722 * properly maintained.
1723 */
1724 for (unsigned short s=0; s != n_sides; s++)
1725 {
1726 if (so_elem->neighbor_ptr(s) == remote_elem)
1727 lo_elem->set_neighbor(s, const_cast<RemoteElem*>(remote_elem));
1728 }
1729
1737 (this->get_boundary_info(), so_elem, lo_elem.get());
1738
1739 /*
1740 * The new first-order element is ready.
1741 * Inserting it into the mesh will replace and delete
1742 * the second-order element.
1743 */
1744 lo_elem->set_id(so_elem->id());
1745#ifdef LIBMESH_ENABLE_UNIQUE_ID
1746 lo_elem->set_unique_id(so_elem->unique_id());
1747#endif
1748
1749 const unsigned int nei = so_elem->n_extra_integers();
1750 lo_elem->add_extra_integers(nei);
1751 for (unsigned int i=0; i != nei; ++i)
1752 lo_elem->set_extra_integer(i, so_elem->get_extra_integer(i));
1753
1754 lo_elem->inherit_data_from(*so_elem);
1755
1756 this->insert_elem(std::move(lo_elem));
1757 }
1758
1759 // Deleting nodes does not invalidate iterators, so this is safe.
1760 for (const auto & node : this->node_ptr_range())
1761 if (!node_touched_by_me[node->id()])
1762 this->delete_node(node);
1763
1764 // If crazy people applied boundary info to non-vertices and then
1765 // deleted those non-vertices, we should make sure their boundary id
1766 // caches are correct.
1768
1769 // On hanging nodes that used to also be second order nodes, we
1770 // might now have an invalid nodal processor_id()
1772
1773 // delete or renumber nodes if desired
1774 this->prepare_for_use();
1775}
void copy_boundary_ids(const BoundaryInfo &old_boundary_info, const Elem *const old_elem, const Elem *const new_elem)
void regenerate_id_sets()
Clears and regenerates the cached sets of ids.
This is the base class from which all geometric element types are derived.
Definition elem.h:96
const Elem * child_ptr(unsigned int i) const
Definition elem.h:3301
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition elem.C:382
static ElemType first_order_equivalent_type(const ElemType et)
Definition elem.C:3201
void set_parent(Elem *p)
Sets the pointer to the element's parent.
Definition elem.h:3184
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition mesh_base.h:170
virtual Elem * insert_elem(Elem *e)=0
Insert elem e to the element array, preserving its id and replacing/deleting any existing element wit...
virtual void delete_node(Node *n)=0
Removes the Node n from the mesh.
virtual dof_id_type max_node_id() const =0
void prepare_for_use()
Definition mesh_base.C:860
static void set_node_processor_ids(MeshBase &mesh)
This function is called after partitioning to set the processor IDs for the nodes.
In parallel meshes where a ghost element has neighbors which do not exist on the local processor,...
Definition remote_elem.h:61
const RemoteElem * remote_elem
Definition remote_elem.C:57

References libMesh::Elem::add_child(), libMesh::DofObject::add_extra_integers(), libMesh::Elem::build(), libMesh::Elem::child_ptr(), libMesh::BoundaryInfo::copy_boundary_ids(), libMesh::MeshBase::delete_node(), libMesh::Elem::first_order_equivalent_type(), libMesh::MeshBase::get_boundary_info(), libMesh::Elem::inherit_data_from(), libMesh::MeshBase::insert_elem(), libMesh::libmesh_assert(), libMesh::MeshBase::max_node_id(), libMesh::Elem::n_vertices(), libMesh::Elem::node_id(), libMesh::Elem::parent(), libMesh::MeshBase::prepare_for_use(), libMesh::BoundaryInfo::regenerate_id_sets(), libMesh::remote_elem, libMesh::Elem::replace_child(), libMesh::DofObject::set_extra_integer(), libMesh::DofObject::set_id(), libMesh::Elem::set_neighbor(), libMesh::Elem::set_node(), libMesh::Partitioner::set_node_processor_ids(), libMesh::Elem::set_p_level(), libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_parent(), libMesh::Elem::set_refinement_flag(), and libMesh::DofObject::set_unique_id().

◆ all_second_order()

void libMesh::MeshBase::all_second_order ( const bool  full_ordered = true)
inherited

Calls the range-based version of this function with a range consisting of all elements in the mesh.

Definition at line 1818 of file mesh_base.C.

1819{
1820 this->all_second_order_range(this->element_ptr_range(), full_ordered);
1821}
virtual void all_second_order_range(const SimpleRange< element_iterator > &range, const bool full_ordered=true)=0
Converts a set of this Mesh's elements defined by range from FIRST order to SECOND order.

References libMesh::MeshBase::all_second_order_range().

Referenced by AllSecondOrderTest::allSecondOrder(), libMesh::MeshTools::Generation::build_cube(), build_domain(), libMesh::MeshTetInterface::increase_tet_order(), libMesh::TriangulatorInterface::increase_triangle_order(), main(), ExtraIntegersTest::test_helper(), MeshTetTest::testNetGenQuadraticCurved(), and InfFERadialTest::testRefinement().

◆ all_second_order_range()

void libMesh::UnstructuredMesh::all_second_order_range ( const SimpleRange< element_iterator > &  range,
const bool  full_ordered = true 
)
overridevirtualinherited

Converts a (conforming, non-refined) mesh with linear elements into a mesh with second-order elements.

For example, a mesh consisting of Tet4 will be converted to a mesh with Tet10 etc.

Note
For some elements like Hex8 there exist two higher order equivalents, Hex20 and Hex27. When full_ordered is true (default), then Hex27 is built. Otherwise, Hex20 is built. The same holds obviously for Quad4, Prism6, etc.

Implements libMesh::MeshBase.

Definition at line 1780 of file unstructured_mesh.C.

1782{
1783 LOG_SCOPE("all_second_order_range()", "Mesh");
1784
1785 /*
1786 * The maximum number of new second order nodes we might be adding,
1787 * for use when picking unique unique_id values later. This variable
1788 * is not used unless unique ids are enabled.
1789 */
1790 unsigned int max_new_nodes_per_elem;
1791
1792 /*
1793 * For speed-up of the \p add_point() method, we
1794 * can reserve memory. Guess the number of additional
1795 * nodes based on the element spatial dimensions and the
1796 * total number of nodes in the mesh as an upper bound.
1797 */
1798 switch (this->mesh_dimension())
1799 {
1800 case 1:
1801 /*
1802 * in 1D, there can only be order-increase from Edge2
1803 * to Edge3. Something like 1/2 of n_nodes() have
1804 * to be added
1805 */
1806 max_new_nodes_per_elem = 3 - 2;
1807 this->reserve_nodes(static_cast<unsigned int>
1808 (1.5*static_cast<double>(this->n_nodes())));
1809 break;
1810
1811 case 2:
1812 /*
1813 * in 2D, either refine from Tri3 to Tri6 (double the nodes)
1814 * or from Quad4 to Quad8 (again, double) or Quad9 (2.25 that much)
1815 */
1816 max_new_nodes_per_elem = 9 - 4;
1817 this->reserve_nodes(static_cast<unsigned int>
1818 (2*static_cast<double>(this->n_nodes())));
1819 break;
1820
1821
1822 case 3:
1823 /*
1824 * in 3D, either refine from Tet4 to Tet10 (factor = 2.5) up to
1825 * Hex8 to Hex27 (something > 3). Since in 3D there _are_ already
1826 * quite some nodes, and since we do not want to overburden the memory by
1827 * a too conservative guess, use the lower bound
1828 */
1829 max_new_nodes_per_elem = 27 - 8;
1830 this->reserve_nodes(static_cast<unsigned int>
1831 (2.5*static_cast<double>(this->n_nodes())));
1832 break;
1833
1834 default:
1835 // Hm?
1836 libmesh_error_msg("Unknown mesh dimension " << this->mesh_dimension());
1837 }
1838
1839 // All the real work is done in the helper function
1840 all_increased_order_range(*this, range, max_new_nodes_per_elem,
1841 [full_ordered](ElemType t) {
1842 return Elem::second_order_equivalent_type(t, full_ordered);
1843 });
1844}
static ElemType second_order_equivalent_type(const ElemType et, const bool full_ordered=true)
Definition elem.C:3571

References libMesh::MeshBase::mesh_dimension(), libMesh::MeshBase::n_nodes(), libMesh::MeshBase::reserve_nodes(), and libMesh::Elem::second_order_equivalent_type().

◆ allgather()

void libMesh::DistributedMesh::allgather ( )
overridevirtualinherited

Gathers all elements and nodes of the mesh onto every processor.

Reimplemented from libMesh::MeshBase.

Definition at line 1896 of file distributed_mesh.C.

1897{
1898 if (_is_serial)
1899 return;
1900 MeshCommunication().allgather(*this);
1901 _is_serial = true;
1902 _is_serial_on_proc_0 = true;
1903
1904 // Make sure our caches are up to date and our
1905 // DofObjects are well packed
1906#ifdef DEBUG
1907 libmesh_assert_equal_to (this->n_nodes(), this->parallel_n_nodes());
1908 libmesh_assert_equal_to (this->n_elem(), this->parallel_n_elem());
1909 const dof_id_type pmax_node_id = this->parallel_max_node_id();
1910 const dof_id_type pmax_elem_id = this->parallel_max_elem_id();
1911 libmesh_assert_equal_to (this->max_node_id(), pmax_node_id);
1912 libmesh_assert_equal_to (this->max_elem_id(), pmax_elem_id);
1913
1914 // If we've disabled renumbering we can't be sure we're contiguous
1915 // libmesh_assert_equal_to (this->n_nodes(), this->max_node_id());
1916 // libmesh_assert_equal_to (this->n_elem(), this->max_elem_id());
1917
1918 // Make sure our neighbor links are all fine
1920
1921 // Make sure our ids and flags are consistent
1924#endif
1925}
dof_id_type parallel_max_node_id() const
virtual dof_id_type n_nodes() const override final
void libmesh_assert_valid_parallel_flags() const
Verify refinement_flag and p_refinement_flag consistency of our elements containers.
virtual dof_id_type parallel_n_elem() const override
virtual dof_id_type max_node_id() const override final
virtual dof_id_type parallel_n_nodes() const override
virtual dof_id_type max_elem_id() const override final
dof_id_type parallel_max_elem_id() const
bool _is_serial
A boolean remembering whether we're serialized or not.
virtual dof_id_type n_elem() const override final
virtual void libmesh_assert_valid_parallel_ids() const override
Verify id and processor_id consistency of our elements and nodes containers.
bool _is_serial_on_proc_0
A boolean remembering whether we're serialized to proc 0 or not.
void libmesh_assert_valid_neighbors(const MeshBase &mesh, bool assert_valid_remote_elems=true)
A function for verifying that neighbor connectivity is correct (each element is a neighbor of or desc...

References libMesh::DistributedMesh::_is_serial, libMesh::DistributedMesh::_is_serial_on_proc_0, libMesh::MeshCommunication::allgather(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_flags(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_ids(), libMesh::DistributedMesh::max_elem_id(), libMesh::DistributedMesh::max_node_id(), libMesh::DistributedMesh::n_elem(), libMesh::DistributedMesh::n_nodes(), libMesh::DistributedMesh::parallel_max_elem_id(), libMesh::DistributedMesh::parallel_max_node_id(), libMesh::DistributedMesh::parallel_n_elem(), and libMesh::DistributedMesh::parallel_n_nodes().

◆ allow_detect_interior_parents() [1/2]

bool libMesh::MeshBase::allow_detect_interior_parents ( ) const
inlineinherited

◆ allow_detect_interior_parents() [2/2]

void libMesh::MeshBase::allow_detect_interior_parents ( bool  allow)
inlineinherited

If false is passed then this mesh will no longer work to detect interior parents when being prepared for use.

Definition at line 1373 of file mesh_base.h.

References libMesh::MeshBase::_skip_detect_interior_parents.

Referenced by libMesh::UnstructuredMesh::copy_nodes_and_elements(), libMesh::DistributedMesh::DistributedMesh(), and libMesh::ReplicatedMesh::ReplicatedMesh().

◆ allow_find_neighbors() [1/2]

bool libMesh::MeshBase::allow_find_neighbors ( ) const
inlineinherited

◆ allow_find_neighbors() [2/2]

void libMesh::MeshBase::allow_find_neighbors ( bool  allow)
inlineinherited

If false is passed then this mesh will no longer work to find element neighbors when being prepared for use.

Definition at line 1366 of file mesh_base.h.

1366{ _skip_find_neighbors = !allow; }

References libMesh::MeshBase::_skip_find_neighbors.

Referenced by libMesh::DistributedMesh::DistributedMesh(), and libMesh::ReplicatedMesh::ReplicatedMesh().

◆ allow_node_and_elem_unique_id_overlap() [1/2]

bool libMesh::MeshBase::allow_node_and_elem_unique_id_overlap ( ) const
inlineinherited

Definition at line 1392 of file mesh_base.h.

bool _allow_node_and_elem_unique_id_overlap
The Exodus reader (and potentially other readers in the future?) now supports setting Node and Elem u...
Definition mesh_base.h:2313

References libMesh::MeshBase::_allow_node_and_elem_unique_id_overlap.

◆ allow_node_and_elem_unique_id_overlap() [2/2]

void libMesh::MeshBase::allow_node_and_elem_unique_id_overlap ( bool  allow)
inlineinherited

If true is passed, then this mesh will no longer require unique_ids to be unique across the set of all DofObjects.

That is, although no two Elems (resp. Nodes) will share the same unique_id, a given Elem and Node might share the same unique_id.

Definition at line 1391 of file mesh_base.h.

References libMesh::MeshBase::_allow_node_and_elem_unique_id_overlap.

Referenced by libMesh::MeshTools::libmesh_assert_valid_unique_ids(), and libMesh::ExodusII_IO::read().

◆ allow_remote_element_removal() [1/2]

bool libMesh::MeshBase::allow_remote_element_removal ( ) const
inlineinherited

Definition at line 1383 of file mesh_base.h.

bool _allow_remote_element_removal
If this is false then even on DistributedMesh remote elements will not be deleted during mesh prepara...
Definition mesh_base.h:2300

References libMesh::MeshBase::_allow_remote_element_removal.

Referenced by libMesh::UnstructuredMesh::copy_nodes_and_elements(), libMesh::DistributedMesh::DistributedMesh(), libMesh::ReplicatedMesh::ReplicatedMesh(), and libMesh::UnstructuredMesh::stitching_helper().

◆ allow_remote_element_removal() [2/2]

void libMesh::MeshBase::allow_remote_element_removal ( bool  allow)
inlineinherited

◆ allow_renumbering() [1/2]

bool libMesh::MeshBase::allow_renumbering ( ) const
inlineinherited

◆ allow_renumbering() [2/2]

void libMesh::MeshBase::allow_renumbering ( bool  allow)
inlineinherited

If false is passed in then this mesh will no longer be renumbered when being prepared for use.

This may slightly adversely affect performance during subsequent element access, particularly when using a distributed mesh.

Important! When allow_renumbering(false) is set, ReplicatedMesh::n_elem() and ReplicatedMesh::n_nodes() will return wrong values whenever adaptive refinement is followed by adaptive coarsening. (Uniform refinement followed by uniform coarsening is OK.) This is due to the fact that n_elem() and n_nodes() are currently O(1) functions that just return the size of the respective underlying vectors, and this size is wrong when the numbering includes "gaps" from nodes and elements that have been deleted. We plan to implement a caching mechanism in the near future that will fix this incorrect behavior.

Definition at line 1359 of file mesh_base.h.

References libMesh::MeshBase::_skip_renumber_nodes_and_elements.

Referenced by AllSecondOrderTest::allSecondOrderMixedFixing(), DisjointNeighborTest::build_four_disjoint_elems(), DisjointNeighborTest::build_two_disjoint_elems(), libMesh::ExodusII_IO::copy_elemental_solution(), libMesh::ExodusII_IO::copy_nodal_solution(), libMesh::DistributedMesh::DistributedMesh(), main(), AllSecondOrderTest::MixedFixingImpl(), libMesh::ErrorVector::plot_error(), libMesh::GMVIO::read(), libMesh::NameBasedIO::read(), libMesh::ReplicatedMesh::ReplicatedMesh(), libMesh::C0Polyhedron::retriangulate(), WriteVecAndScalar::setupTests(), ConstraintOperatorTest::test1DCoarseningNewNodes(), ConstraintOperatorTest::test1DCoarseningOperator(), MeshGenerationTest::testBuildSphere(), CheckpointIOTest::testC0PolygonCheckpoint(), CheckpointIOTest::testC0PolyhedronCheckpoint(), MeshInputTest::testCopyElementSolutionImpl(), MeshInputTest::testCopyElementVectorImpl(), MeshInputTest::testCopyNodalSolutionImpl(), ConstraintOperatorTest::testCoreform(), DisjointNeighborTest::testDisjointNeighborConflictError(), CheckpointIOTest::testDisjointNeighborPairsCheckpoint(), MeshGenerationTest::tester(), MeshInputTest::testExodusCopyHighOrderElementSolution(), MeshInputTest::testExodusWriteElementDataFromDiscontinuousNodalData(), ExtraIntegersTest::testExtraIntegersExodusReading(), SystemsTest::testProjectMatrix1D(), SystemsTest::testProjectMatrix2D(), SystemsTest::testProjectMatrix3D(), EquationSystemsTest::testRefineThenReinitPreserveFlags(), EquationSystemsTest::testRepartitionThenReinit(), BoundaryInfoTest::testShellFaceConstraints(), MeshInputTest::testSingleElementImpl(), DisjointNeighborTest::testStitchCrossMesh(), MeshSmootherTest::testVariationalPrism21MultipleSubdomains(), MeshInputTest::testVTKPreserveElemIds(), MeshInputTest::testVTKPreserveSubdomainIds(), MeshInputTest::testVTKReadPolyhedra(), MeshInputTest::testVTKReadPolyhedraSerial(), WriteElemsetData::testWriteImpl(), WriteNodesetData::testWriteImpl(), and WriteSidesetData::testWriteImpl().

◆ assign()

MeshBase & libMesh::DistributedMesh::assign ( MeshBase &&  other_mesh)
overridevirtualinherited

Shim to call the move assignment operator for this class.

Implements libMesh::UnstructuredMesh.

Definition at line 91 of file distributed_mesh.C.

92{
93 *this = std::move(cast_ref<DistributedMesh&>(other_mesh));
94
95 return *this;
96}

Referenced by libMesh::DistributedMesh::renumber_nodes_and_elements().

◆ cache_elem_data()

void libMesh::MeshBase::cache_elem_data ( )
inherited

Definition at line 2000 of file mesh_base.C.

2001{
2002 // This requires an inspection on every processor
2003 parallel_object_only();
2004
2005 // Need to clear containers first in case all elements of a
2006 // particular dimension/order/subdomain have been deleted.
2007 _elem_dims.clear();
2008 _elem_default_orders.clear();
2009 _mesh_subdomains.clear();
2011
2012 for (const auto & elem : this->active_element_ptr_range())
2013 {
2014 _elem_dims.insert(cast_int<unsigned char>(elem->dim()));
2015 _elem_default_orders.insert(elem->default_order());
2016 _mesh_subdomains.insert(elem->subdomain_id());
2018 static_cast<Order>
2019 (std::min(static_cast<int>(_supported_nodal_order),
2020 static_cast<int>(elem->supported_nodal_order())));
2021 }
2022
2023 if (!this->is_serial())
2024 {
2025 // Some different dimension/order/subdomain elements may only live
2026 // on other processors
2027 this->comm().set_union(_elem_dims);
2031 }
2032
2033 // If the largest element dimension found is larger than the current
2034 // _spatial_dimension, increase _spatial_dimension.
2035 unsigned int max_dim = this->mesh_dimension();
2036 if (max_dim > _spatial_dimension)
2037 _spatial_dimension = cast_int<unsigned char>(max_dim);
2038
2039 // _spatial_dimension may need to increase from 1->2 or 2->3 if the
2040 // mesh is full of 1D elements but they are not x-aligned, or the
2041 // mesh is full of 2D elements but they are not in the x-y plane.
2042 // If the mesh is x-aligned or x-y planar, we will end up checking
2043 // every node's coordinates and not breaking out of the loop
2044 // early...
2045 if (_spatial_dimension < LIBMESH_DIM)
2046 {
2047 for (const auto & node : this->node_ptr_range())
2048 {
2049 // Note: the exact floating point comparison is intentional,
2050 // we don't want to get tripped up by tolerances.
2051 if ((*node)(0) != 0. && _spatial_dimension < 1)
2053
2054 if ((*node)(1) != 0. && _spatial_dimension < 2)
2055 {
2057#if LIBMESH_DIM == 2
2058 // If libmesh is compiled in 2D mode, this is the
2059 // largest spatial dimension possible so we can break
2060 // out.
2061 break;
2062#endif
2063 }
2064
2065#if LIBMESH_DIM > 2
2066 if ((*node)(2) != 0.)
2067 {
2068 // Spatial dimension can't get any higher than this, so
2069 // we can break out.
2071 break;
2072 }
2073#endif
2074 }
2075 }
2076
2078}
void min(const T &r, T &o, Request &req) const
void set_union(T &data, const unsigned int root_id) const
virtual bool is_serial() const
Definition mesh_base.h:357
Order _supported_nodal_order
We cache the maximum nodal order supported by all the mesh's elements (the minimum supported_nodal_or...
Definition mesh_base.h:2340
unsigned char _spatial_dimension
The "spatial dimension" of the Mesh.
Definition mesh_base.h:2377
std::set< subdomain_id_type > _mesh_subdomains
We cache the subdomain ids of the elements present in the mesh.
Definition mesh_base.h:2345
std::set< Order > _elem_default_orders
We cache the (default) order of the geometric elements present in the mesh.
Definition mesh_base.h:2334
std::set< unsigned char > _elem_dims
We cache the dimension of the elements present in the mesh.
Definition mesh_base.h:2327
Preparation _preparation
Flags indicating in what ways this mesh has been prepared.
Definition mesh_base.h:2207
const Parallel::Communicator & comm() const

References libMesh::MeshBase::_elem_default_orders, libMesh::MeshBase::_elem_dims, libMesh::MeshBase::_mesh_subdomains, libMesh::MeshBase::_preparation, libMesh::MeshBase::_spatial_dimension, libMesh::MeshBase::_supported_nodal_order, libMesh::ParallelObject::comm(), libMesh::MeshBase::Preparation::has_cached_elem_data, libMesh::MeshBase::is_serial(), libMesh::MAXIMUM, libMesh::MeshBase::mesh_dimension(), libMesh::Parallel::Communicator::min(), and libMesh::Parallel::Communicator::set_union().

Referenced by ExodusC0PolyhedronTest::build_c0polyhedron(), libMesh::MeshBase::cache_elem_dims(), libMesh::MeshBase::complete_preparation(), main(), libMesh::MeshBase::set_elem_dimensions(), libMesh::VariationalMeshSmoother::setup(), ExodusC0PolyhedronTest::test_write_and_read_mixed_poly_hex_impl(), ExodusC0PolyhedronTest::test_write_cube_header(), MeshSmootherTest::testVariationalSmoother(), and libMesh::NetGenMeshInterface::triangulate().

◆ cache_elem_dims()

void libMesh::MeshBase::cache_elem_dims ( )
inherited
Deprecated:
This method has ben replaced by cache_elem_data which caches data in addition to elem dimensions (e.g. elem subdomain ids) Search the mesh and cache the different dimensions of the elements present in the mesh. This is done in prepare_for_use(), but can be done manually by other classes after major mesh modifications.

Definition at line 1992 of file mesh_base.C.

1993{
1994 libmesh_deprecated();
1995
1996 this->cache_elem_data();
1997}

References libMesh::MeshBase::cache_elem_data().

◆ change_elemset_code()

void libMesh::MeshBase::change_elemset_code ( dof_id_type  old_code,
dof_id_type  new_code 
)
inherited

Replace elemset code "old_code" with "new_code".

This function loops over all elements and changes the extra integer corresponding to the "elemset_code" label, and updates the _elemset_codes and _elemset_codes_inverse_map members. Does not change the elemset ids of any of the sets.

Definition at line 517 of file mesh_base.C.

518{
519 // Look up elemset ids for old_code
520 auto it = _elemset_codes.find(old_code);
521
522 // If we don't have the old_code, then do nothing. Alternatively, we
523 // could throw an error since trying to change an elemset code you
524 // don't have could indicate there's a problem...
525 if (it == _elemset_codes.end())
526 return;
527
528 // Make copy of the set of elemset ids. We are not changing these,
529 // only updating the elemset code it corresponds to.
530 elemset_type id_set_copy = *(it->second);
531
532 // Look up the corresponding entry in the inverse map. Note: we want
533 // the iterator because we are going to remove it.
534 auto inverse_it = _elemset_codes_inverse_map.find(id_set_copy);
535 libmesh_error_msg_if(inverse_it == _elemset_codes_inverse_map.end(),
536 "Expected _elemset_codes_inverse_map entry for elemset code " << old_code);
537
538 // Erase entry from inverse map
539 _elemset_codes_inverse_map.erase(inverse_it);
540
541 // Erase entry from forward map
542 _elemset_codes.erase(it);
543
544 // Add new code with original set of ids.
545 this->add_elemset_code(new_code, id_set_copy);
546
547 // We can't update any actual elemset codes if there is no extra integer defined for it.
548 if (!this->has_elem_integer("elemset_code"))
549 return;
550
551 // Get index of elemset_code extra integer
552 unsigned int elemset_index = this->get_elem_integer_index("elemset_code");
553
554 // Loop over all elems and update code
556 (this->element_stored_range(),
557 [elemset_index, old_code, new_code](const ElemRange & range)
558 {
559 for (Elem * elem : range)
560 {
561 dof_id_type elemset_code =
562 elem->get_extra_integer(elemset_index);
563
564 if (elemset_code == old_code)
565 elem->set_extra_integer(elemset_index, new_code);
566 }
567 });
568}
unsigned int get_elem_integer_index(std::string_view name) const
Definition mesh_base.C:689
const ElemRange & element_stored_range()
Definition mesh_base.C:1954
bool has_elem_integer(std::string_view name) const
Definition mesh_base.C:701
const DofMap &dof_map LIBMESH_COMMA unsigned int Elem * ElemRange
Definition mesh_base.h:1898
void add_elemset_code(dof_id_type code, MeshBase::elemset_type id_set)
Tabulate a user-defined "code" for elements which belong to the element sets specified in id_set.
Definition mesh_base.C:461
std::set< elemset_id_type > elemset_type
Typedef for the "set" container used to store elemset ids.
Definition mesh_base.h:463
void parallel_for(const Range &range, const Body &body, unsigned int n_threads=libMesh::n_threads())
Execute the provided function object in parallel on the specified range.

References libMesh::MeshBase::_elemset_codes, libMesh::MeshBase::_elemset_codes_inverse_map, libMesh::MeshBase::add_elemset_code(), libMesh::MeshBase::element_stored_range(), libMesh::MeshBase::get_elem_integer_index(), libMesh::MeshBase::has_elem_integer(), and libMesh::Threads::parallel_for().

◆ change_elemset_id()

void libMesh::MeshBase::change_elemset_id ( elemset_id_type  old_id,
elemset_id_type  new_id 
)
inherited

Replace elemset id "old_id" with "new_id".

Does not change any of the elemset codes, so does not need to loop over the elements themselves.

Definition at line 570 of file mesh_base.C.

571{
572 // Early return if we don't have old_id
573 if (!_all_elemset_ids.count(old_id))
574 return;
575
576 // Throw an error if the new_id is already used
577 libmesh_error_msg_if(_all_elemset_ids.count(new_id),
578 "Cannot change elemset id " << old_id <<
579 " to " << new_id << ", " << new_id << " already exists.");
580
581 // We will build up a new version of the inverse map so we can iterate over
582 // the current one without invalidating anything.
583 std::map<MeshBase::elemset_type, dof_id_type> new_elemset_codes_inverse_map;
584 for (const auto & [id_set, elemset_code] : _elemset_codes_inverse_map)
585 {
586 auto id_set_copy = id_set;
587 if (id_set_copy.count(old_id))
588 {
589 // Remove old_id, insert new_id
590 id_set_copy.erase(old_id);
591 id_set_copy.insert(new_id);
592 }
593
594 // Store in new version of map
595 new_elemset_codes_inverse_map.emplace(id_set_copy, elemset_code);
596 }
597
598 // Swap existing map with newly-built one
599 _elemset_codes_inverse_map.swap(new_elemset_codes_inverse_map);
600
601 // Reconstruct _elemset_codes map
602 _elemset_codes.clear();
603 for (const auto & [id_set, elemset_code] : _elemset_codes_inverse_map)
604 _elemset_codes.emplace(elemset_code, &id_set);
605
606 // Update _all_elemset_ids
607 _all_elemset_ids.erase(old_id);
608 _all_elemset_ids.insert(new_id);
609}

References libMesh::MeshBase::_all_elemset_ids, libMesh::MeshBase::_elemset_codes, and libMesh::MeshBase::_elemset_codes_inverse_map.

◆ clear()

void libMesh::DistributedMesh::clear ( )
overridevirtualinherited

Clear all internal data.

Reimplemented from libMesh::MeshBase.

Definition at line 1062 of file distributed_mesh.C.

1063{
1064 // Call parent clear function
1066
1067 // Clear our elements and nodes
1068 // There is no need to remove them from
1069 // the BoundaryInfo data structure since we
1070 // already cleared it.
1072
1073 for (auto & node : _nodes)
1074 delete node;
1075
1076 _nodes.clear();
1077
1078 // We're no longer distributed if we were before
1079 _is_serial = true;
1080 _is_serial_on_proc_0 = true;
1081
1082 // We deleted a ton of coarse elements, but their nodes got deleted too so
1083 // all is copacetic.
1085
1086 // Correct our caches
1087 _n_nodes = 0;
1088 _max_node_id = 0;
1091}
virtual void clear_elems() override
Clear internal Elem data.
bool _deleted_coarse_elements
A boolean remembering whether we've recently deleted top-level elements or not.
virtual void clear() override
Free all new memory associated with the object, but restore its original state, with the mesh pointer...
Definition dof_map.C:872
virtual void clear()
Deletes all the element and node data that is currently stored.
Definition mesh_base.C:1036

References libMesh::DistributedMesh::_deleted_coarse_elements, libMesh::DistributedMesh::_is_serial, libMesh::DistributedMesh::_is_serial_on_proc_0, libMesh::DistributedMesh::_max_node_id, libMesh::DistributedMesh::_n_nodes, libMesh::DistributedMesh::_next_free_local_node_id, libMesh::DistributedMesh::_next_free_unpartitioned_node_id, libMesh::DistributedMesh::_nodes, libMesh::MeshBase::clear(), libMesh::DofMap::clear(), libMesh::DistributedMesh::clear_elems(), libMesh::ParallelObject::n_processors(), and libMesh::ParallelObject::processor_id().

Referenced by libMesh::DistributedMesh::~DistributedMesh().

◆ clear_elems()

void libMesh::DistributedMesh::clear_elems ( )
overridevirtualinherited

◆ clear_extra_ghost_elems() [1/2]

virtual void libMesh::DistributedMesh::clear_extra_ghost_elems ( )
inlinevirtualinherited

Clears extra ghost elements.

Definition at line 257 of file distributed_mesh.h.

257{ _extra_ghost_elems.clear(); }

References libMesh::DistributedMesh::_extra_ghost_elems.

◆ clear_extra_ghost_elems() [2/2]

void libMesh::DistributedMesh::clear_extra_ghost_elems ( const std::set< Elem * > &  extra_ghost_elems)
virtualinherited

Clears specified extra ghost elements.

Definition at line 1887 of file distributed_mesh.C.

1888{
1889 std::set<Elem *> tmp;
1890 std::set_difference(_extra_ghost_elems.begin(), _extra_ghost_elems.end(),
1891 extra_ghost_elems.begin(), extra_ghost_elems.end(),
1892 std::inserter(tmp, tmp.begin()));
1893 _extra_ghost_elems = tmp;
1894}
const std::set< Elem * > & extra_ghost_elems() const
Const accessor to the ghosted elements.

References libMesh::DistributedMesh::_extra_ghost_elems, and libMesh::DistributedMesh::extra_ghost_elems().

◆ clear_point_locator()

void libMesh::MeshBase::clear_point_locator ( )
inherited

◆ clear_stored_ranges()

void libMesh::MeshBase::clear_stored_ranges ( )
inherited

◆ clone()

virtual std::unique_ptr< MeshBase > libMesh::ParallelMesh::clone ( ) const
inlineoverridevirtual

Virtual copy-constructor, creates a copy of this mesh.

Reimplemented from libMesh::DistributedMesh.

Definition at line 44 of file parallel_mesh.h.

45 { return std::make_unique<ParallelMesh>(*this); }

◆ comm()

const Parallel::Communicator & libMesh::ParallelObject::comm ( ) const
inlineinherited
Returns
A reference to the Parallel::Communicator object used by this mesh.

Definition at line 97 of file parallel_object.h.

98 { return _communicator; }
const Parallel::Communicator & _communicator

References libMesh::ParallelObject::_communicator.

Referenced by libMesh::__libmesh_petsc_diff_solver_jacobian(), libMesh::__libmesh_petsc_diff_solver_monitor(), libMesh::__libmesh_petsc_diff_solver_residual(), libMesh::ExactSolution::_compute_error(), libMesh::UniformRefinementEstimator::_estimate_error(), libMesh::Partitioner::_find_global_index_by_pid_map(), libMesh::BoundaryInfo::_find_id_maps(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_get_diagonal(), libMesh::SlepcEigenSolver< T >::_petsc_shell_matrix_get_diagonal(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_mult(), libMesh::SlepcEigenSolver< T >::_petsc_shell_matrix_mult(), libMesh::PetscLinearSolver< T >::_petsc_shell_matrix_mult_add(), libMesh::DofMap::add_constraints_to_send_list(), add_cube_convex_hull_to_mesh(), libMesh::PetscDMWrapper::add_dofs_helper(), libMesh::PetscDMWrapper::add_dofs_to_section(), libMesh::TransientRBConstruction::add_IC_to_RB_space(), libMesh::RBEIMEvaluation::add_interpolation_data(), libMesh::CondensedEigenSystem::add_matrices(), libMesh::EigenSystem::add_matrices(), libMesh::System::add_matrix(), libMesh::System::add_matrix(), libMesh::System::add_matrix(), libMesh::RBConstruction::add_scaled_matrix_and_vector(), libMesh::System::add_vector(), libMesh::MeshTools::Modification::all_tri(), libMesh::LaplaceMeshSmoother::allgather_graph(), libMesh::DofMap::allgather_recursive_constraints(), libMesh::RBConstruction::allocate_data_structures(), libMesh::TransientRBConstruction::allocate_data_structures(), libMesh::TransientRBConstruction::assemble_affine_expansion(), libMesh::AdvectionSystem::assemble_claw_rhs(), libMesh::FEMSystem::assemble_qoi(), libMesh::Nemesis_IO::assert_symmetric_cmaps(), libMesh::MeshCommunication::assign_global_indices(), libMesh::Partitioner::assign_partitioning(), libMesh::MeshTools::Generation::build_extrusion(), libMesh::Partitioner::build_graph(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::BoundaryInfo::build_node_list_from_side_list(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::EquationSystems::build_parallel_solution_vector(), libMesh::PetscDMWrapper::build_section(), libMesh::PetscDMWrapper::build_sf(), libMesh::BoundaryInfo::build_side_list_from_node_list(), libMesh::MeshBase::cache_elem_data(), centroid_l2_error(), libMesh::DofMap::check_dirichlet_bcid_consistency(), libMesh::MeshTetInterface::check_hull_integrity(), MeshInputTest::checkHexPrismPolyhedron(), libMesh::MeshBase::complete_preparation(), libMesh::RBConstruction::compute_Fq_representor_innerprods(), libMesh::RBConstruction::compute_max_error_bound(), libMesh::Nemesis_IO_Helper::compute_num_global_elem_blocks(), libMesh::Nemesis_IO_Helper::compute_num_global_nodesets(), libMesh::Nemesis_IO_Helper::compute_num_global_sidesets(), libMesh::RBConstruction::compute_output_dual_innerprods(), libMesh::RBConstruction::compute_residual_dual_norm_slow(), libMesh::RBSCMConstruction::compute_SCM_bounds_on_training_set(), libMesh::DofMap::computed_sparsity_already(), libMesh::Problem_Interface::computeJacobian(), libMesh::Problem_Interface::computePreconditioner(), PetscSolverConfiguration::configure_solver(), libMesh::ContinuationSystem::ContinuationSystem(), libMesh::MeshBase::copy_constraint_rows(), libMesh::ExodusII_IO::copy_elemental_solution(), libMesh::ExodusII_IO::copy_nodal_solution(), libMesh::ExodusII_IO::copy_scalar_solution(), libMesh::CondensedEigenSystem::copy_super_to_sub(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::MeshBase::count_constraint_rows(), libMesh::MeshTools::create_bounding_box(), libMesh::DofMap::create_dof_constraints(), libMesh::MeshTools::create_nodal_bounding_box(), libMesh::MeshRefinement::create_parent_error_vector(), libMesh::MeshTools::create_processor_bounding_box(), libMesh::MeshTools::create_subdomain_bounding_box(), libMesh::PetscMatrix< T >::create_submatrix_nosort(), create_wrapped_function(), libMesh::MeshCommunication::delete_remote_elements(), libMesh::MeshBase::detect_interior_parents(), libMesh::RBEIMEvaluation::distribute_bfs(), DMlibMeshFunction(), DMlibMeshJacobian(), DMlibMeshSetSystem_libMesh(), DMVariableBounds_libMesh(), libMesh::DTKSolutionTransfer::DTKSolutionTransfer(), libMesh::MeshRefinement::eliminate_unrefined_patches(), libMesh::RBEIMConstruction::enrich_eim_approximation_on_interiors(), libMesh::RBEIMConstruction::enrich_eim_approximation_on_nodes(), libMesh::RBEIMConstruction::enrich_eim_approximation_on_sides(), libMesh::TransientRBConstruction::enrich_RB_space(), libMesh::EpetraVector< T >::EpetraVector(), AssembleOptimization::equality_constraints(), libMesh::AdjointRefinementEstimator::estimate_error(), libMesh::ExactErrorEstimator::estimate_error(), libMesh::JumpErrorEstimator::estimate_error(), libMesh::PatchRecoveryErrorEstimator::estimate_error(), libMesh::WeightedPatchRecoveryErrorEstimator::estimate_error(), libMesh::SmoothnessEstimator::estimate_smoothness(), libMesh::MeshRefinement::flag_elements_by_elem_fraction(), libMesh::MeshRefinement::flag_elements_by_error_fraction(), libMesh::MeshRefinement::flag_elements_by_error_tolerance(), libMesh::MeshRefinement::flag_elements_by_mean_stddev(), libMesh::MeshRefinement::flag_elements_by_nelem_target(), libMesh::RBEIMEvaluation::gather_bfs(), libMesh::DofMap::gather_constraints(), libMesh::MeshfreeInterpolation::gather_remote_data(), libMesh::CondensedEigenSystem::get_eigenpair(), libMesh::RBEIMEvaluation::get_eim_basis_function_node_value(), libMesh::RBEIMEvaluation::get_eim_basis_function_side_value(), libMesh::RBEIMEvaluation::get_eim_basis_function_value(), libMesh::MeshBase::get_info(), libMesh::RBEIMEvaluation::get_interior_basis_functions_as_vecs(), libMesh::ImplicitSystem::get_linear_solver(), libMesh::RBEIMConstruction::get_max_abs_value(), libMesh::RBEIMConstruction::get_node_max_abs_value(), libMesh::RBEIMEvaluation::get_parametrized_function_node_value(), libMesh::RBEIMEvaluation::get_parametrized_function_side_value(), libMesh::RBEIMEvaluation::get_parametrized_function_value(), libMesh::RBEIMConstruction::get_random_point(), libMesh::RBEIMConstruction::get_random_point(), libMesh::RBEIMConstruction::get_random_point(), libMesh::MeshTetInterface::improve_hull_integrity(), AssembleOptimization::inequality_constraints(), AssembleOptimization::inequality_constraints_jacobian(), libMesh::StaticCondensation::init(), libMesh::TimeSolver::init(), libMesh::SystemSubsetBySubdomain::init(), libMesh::LocationMap< T >::init(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), ElasticitySystem::init_data(), libMesh::AdvectionSystem::init_data(), libMesh::ClawSystem::init_data(), libMesh::PetscDMWrapper::init_petscdm(), libMesh::ExodusII_IO_Helper::initialize(), libMesh::OptimizationSystem::initialize_equality_constraints_storage(), libMesh::OptimizationSystem::initialize_inequality_constraints_storage(), libMesh::RBEIMConstruction::initialize_parametrized_functions_in_training_set(), libMesh::RBEIMConstruction::inner_product(), integrate_function(), libMesh::MeshTools::Modification::interpolate_surface(), libMesh::MeshTools::libmesh_assert_consistent_distributed(), libMesh::MeshTools::libmesh_assert_consistent_distributed_nodes(), libMesh::MeshTools::libmesh_assert_contiguous_dof_ids(), libMesh::MeshTools::libmesh_assert_equal_connectivity(), libMesh::MeshTools::libmesh_assert_equal_points(), libMesh::MeshTools::libmesh_assert_parallel_consistent_new_node_procids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Elem >(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_topology_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_valid_boundary_ids(), libMesh::MeshTools::libmesh_assert_valid_constraint_rows(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_flags(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_object_ids(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_p_levels(), libMesh::MeshTools::libmesh_assert_valid_refinement_flags(), libMesh::MeshTools::libmesh_assert_valid_unique_ids(), libMesh::libmesh_petsc_linesearch_shellfunc(), libMesh::libmesh_petsc_preconditioner_apply(), libMesh::libmesh_petsc_snes_postcheck(), libMesh::MeshRefinement::limit_level_mismatch_at_edge(), libMesh::MeshRefinement::limit_level_mismatch_at_node(), libMesh::MeshRefinement::limit_overrefined_boundary(), libMesh::MeshRefinement::limit_underrefined_boundary(), libMesh::LinearImplicitSystem::LinearImplicitSystem(), main(), libMesh::MeshCommunication::make_elems_parallel_consistent(), libMesh::MeshCommunication::make_new_node_proc_ids_parallel_consistent(), libMesh::MeshCommunication::make_new_nodes_parallel_consistent(), libMesh::MeshCommunication::make_node_bcids_parallel_consistent(), libMesh::MeshCommunication::make_node_ids_parallel_consistent(), libMesh::MeshCommunication::make_node_proc_ids_parallel_consistent(), libMesh::MeshCommunication::make_node_unique_ids_parallel_consistent(), libMesh::MeshCommunication::make_nodes_parallel_consistent(), libMesh::MeshCommunication::make_p_levels_parallel_consistent(), libMesh::TransientRBConstruction::mass_matrix_scaled_matvec(), libMesh::FEMSystem::mesh_position_set(), libMesh::TriangulatorInterface::MeshedHole::MeshedHole(), LinearElasticityWithContact::move_mesh(), libMesh::DistributedMesh::n_active_elem(), libMesh::MeshTools::n_active_levels(), libMesh::BoundaryInfo::n_boundary_conds(), libMesh::MeshTools::n_connected_components(), libMesh::DofMap::n_constrained_dofs(), libMesh::DofMap::n_dofs(), libMesh::DofMap::n_dofs_per_processor(), libMesh::BoundaryInfo::n_edge_conds(), libMesh::CondensedEigenSystem::n_global_non_condensed_dofs(), libMesh::MeshTools::n_levels(), MixedOrderTest::n_neighbor_links(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::SparsityPattern::Build::n_nonzeros(), libMesh::MeshTools::n_p_levels(), libMesh::BoundaryInfo::n_shellface_conds(), libMesh::RBEIMEvaluation::node_distribute_bfs(), libMesh::RBEIMEvaluation::node_gather_bfs(), libMesh::RBEIMConstruction::node_inner_product(), libMesh::PetscVector< T >::operator=(), libMesh::MeshBase::operator==(), libMesh::DistributedMesh::parallel_max_elem_id(), libMesh::DistributedMesh::parallel_max_node_id(), libMesh::DistributedMesh::parallel_max_unique_id(), libMesh::ReplicatedMesh::parallel_max_unique_id(), libMesh::DistributedMesh::parallel_n_elem(), libMesh::DistributedMesh::parallel_n_nodes(), libMesh::SparsityPattern::Build::parallel_sync(), libMesh::BoundaryInfo::parallel_sync_node_ids(), libMesh::BoundaryInfo::parallel_sync_side_ids(), libMesh::MeshTools::paranoid_n_levels(), libMesh::Partitioner::partition(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::petsc_auto_fieldsplit(), MeshGenerationTest::polyhedronTetNeighbor(), LaplaceSystem::postprocess(), PoissonSystem::postprocess(), libMesh::MeshBase::print_constraint_rows(), libMesh::DofMap::print_dof_constraints(), libMesh::DofMap::process_mesh_constraint_rows(), libMesh::Partitioner::processor_pairs_to_interface_nodes(), libMesh::InterMeshProjection::project_system_vectors(), libMesh::XdrIO::read(), libMesh::Nemesis_IO::read(), FEMParameters::read(), libMesh::EquationSystems::read(), libMesh::CheckpointIO::read_header(), libMesh::ExodusII_IO::read_header(), libMesh::System::read_header(), libMesh::XdrIO::read_header(), libMesh::RBEIMEvaluation::read_in_interior_basis_functions(), libMesh::RBEIMEvaluation::read_in_node_basis_functions(), libMesh::RBEIMEvaluation::read_in_side_basis_functions(), libMesh::RBEvaluation::read_in_vectors_from_multiple_files(), libMesh::RBConstruction::read_riesz_representors_from_files(), libMesh::TransientRBConstruction::read_riesz_representors_from_files(), libMesh::System::read_SCALAR_dofs(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs_helper(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::XdrIO::read_serialized_nodes(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::XdrIO::read_serialized_subdomain_names(), libMesh::System::read_serialized_vector(), libMesh::Nemesis_IO_Helper::read_var_names_impl(), MeshFunctionTest::read_variable_info_from_output_data(), libMesh::MeshBase::recalculate_n_partitions(), libMesh::SimplexRefiner::refine_via_edges(), libMesh::StaticCondensationDofMap::reinit(), libMesh::BoundaryInfo::remove_edge_id(), libMesh::BoundaryInfo::remove_node_id(), libMesh::BoundaryInfo::remove_shellface_id(), libMesh::BoundaryInfo::remove_side_id(), libMesh::DistributedMesh::renumber_dof_objects(), libMesh::DistributedMesh::renumber_nodes_and_elements(), LinearElasticityWithContact::residual_and_jacobian(), OverlappingAlgebraicGhostingTest::run_ghosting_test(), OverlappingCouplingGhostingTest::run_sparsity_pattern_test(), scale_mesh_and_plot(), libMesh::DofMap::scatter_constraints(), libMesh::CheckpointIO::select_split_config(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::send_and_insert_dof_values(), libMesh::TransientRBConstruction::set_error_temporal_data(), libMesh::Partitioner::set_interface_node_processor_ids_BFS(), libMesh::Partitioner::set_interface_node_processor_ids_linear(), libMesh::Partitioner::set_interface_node_processor_ids_petscpartitioner(), libMesh::Partitioner::set_node_processor_ids(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::Partitioner::set_parent_processor_ids(), libMesh::PetscDMWrapper::set_point_range_in_section(), libMesh::PetscDiffSolver::setup_petsc_data(), libMesh::RBEIMEvaluation::side_distribute_bfs(), libMesh::RBEIMEvaluation::side_gather_bfs(), libMesh::RBEIMConstruction::side_inner_product(), libMesh::Partitioner::single_partition(), libMesh::LaplaceMeshSmoother::smooth(), libMesh::VariationalMeshSmoother::smooth(), libMesh::NoxNonlinearSolver< Number >::solve(), libMesh::ClawSystem::solve_conservation_law(), libMesh::split_mesh(), libMesh::RBEIMConstruction::store_eim_solutions_for_training_set(), libMesh::MeshBase::subdomain_ids(), libMesh::BoundaryInfo::sync(), libMesh::MeshBase::sync_subdomain_name_map(), ConstraintOperatorTest::test1DCoarseningNewNodes(), ConstraintOperatorTest::test1DCoarseningOperator(), MeshFunctionTest::test_bad_gradient_var_with_out_of_mesh_value(), MeshFunctionTest::test_bad_hessian_var_with_out_of_mesh_value(), MeshfunctionDFEM::test_mesh_function_dfem(), MeshfunctionDFEM::test_mesh_function_dfem_grad(), MeshFunctionTest::test_p_level(), ExodusC0PolyhedronTest::test_write_and_read_hexagonal_prism(), ExodusC0PolygonTest::test_write_and_read_pentagon(), DofMapTest::testBadElemFECombo(), SystemsTest::testBlockRestrictedVarNDofs(), BoundaryInfoTest::testBoundaryOnChildrenErrors(), MeshGenerationTest::testBuildCube(), BoundaryInfoTest::testBuildSideListFromNodeListThinMesh(), CheckpointIOTest::testC0PolygonCheckpoint(), VolumeTest::testC0PolygonMethods(), CheckpointIOTest::testC0PolyhedronCheckpoint(), VolumeTest::testC0PolyhedronMethods(), ConstraintOperatorTest::testCoreform(), ConnectedComponentsTest::testEdge(), MeshInputTest::testExodusIGASidesets(), MeshTriangulationTest::testFoundCenters(), PointLocatorTest::testLocator(), BoundaryInfoTest::testMesh(), BoundaryMeshSubdomainTest::testPerBoundarySubdomain(), PointLocatorTest::testPlanar(), MeshTriangulationTest::testPoly2TriEdge3ToTri7CenterFixup(), MeshTriangulationTest::testPoly2TriRefinementBase(), SystemsTest::testProjectCubeWithMeshFunction(), SystemsTest::testProjectScalarCoarsening(), BoundaryInfoTest::testRenumber(), BoundaryInfoTest::testSelectiveRenumber(), BoundaryMeshSubdomainTest::testSingleSubdomain(), CheckpointIOTest::testSplitter(), MeshInputTest::testTetgenIO(), MeshTriangulationTest::testTriangulatorInterp(), MeshTriangulationTest::testTriangulatorMeshedHoles(), MeshTriangulationTest::testTriangulatorRoundHole(), MeshSmootherTest::testVariationalSmoother(), libMesh::MeshTools::total_weight(), libMesh::RBConstruction::train_reduced_basis_with_POD(), libMesh::MeshfreeSolutionTransfer::transfer(), libMesh::MeshFunctionSolutionTransfer::transfer(), libMesh::Poly2TriTriangulator::triangulate(), libMesh::RBConstruction::truth_assembly(), libMesh::TransientRBConstruction::truth_assembly(), update_current_local_solution(), libMesh::TransientRBConstruction::update_RB_initial_condition_all_N(), libMesh::RBConstruction::update_RB_system_matrices(), libMesh::TransientRBConstruction::update_RB_system_matrices(), libMesh::TransientRBConstruction::update_residual_terms(), libMesh::RBConstruction::update_residual_terms(), libMesh::MeshTools::volume(), libMesh::STLIO::write(), libMesh::XdrIO::write(), libMesh::NameBasedIO::write(), libMesh::VTKIO::write_nodal_data(), libMesh::RBEIMEvaluation::write_out_interior_basis_functions(), libMesh::RBEIMEvaluation::write_out_node_basis_functions(), libMesh::RBEIMEvaluation::write_out_side_basis_functions(), libMesh::RBEvaluation::write_out_vectors(), libMesh::RBConstruction::write_riesz_representors_to_files(), libMesh::TransientRBConstruction::write_riesz_representors_to_files(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), libMesh::XdrIO::write_serialized_nodesets(), libMesh::RBDataSerialization::RBEvaluationSerialization::write_to_file(), libMesh::RBDataSerialization::TransientRBEvaluationSerialization::write_to_file(), libMesh::RBDataSerialization::RBEIMEvaluationSerialization::write_to_file(), and libMesh::RBDataSerialization::RBSCMEvaluationSerialization::write_to_file().

◆ complete_preparation()

void libMesh::MeshBase::complete_preparation ( )
inherited

Definition at line 874 of file mesh_base.C.

875{
876 LOG_SCOPE("complete_preparation()", "MeshBase");
877
878 parallel_object_only();
879
880 libmesh_assert(this->comm().verify(this->is_serial()));
881
882 // If we don't go into this method with valid constraint rows, we're
883 // only going to be able to make that worse.
884#ifdef DEBUG
886#endif
887
888 // A distributed mesh may have processors with no elements (or
889 // processors with no elements of higher dimension, if we ever
890 // support mixed-dimension meshes), but we want consistent
891 // mesh_dimension anyways.
892 //
893 // cache_elem_data() should get the elem_dimensions() and
894 // mesh_dimension() correct later, and we don't need it earlier.
895
896
897 // Renumber the nodes and elements so that they in contiguous
898 // blocks. By default, _skip_renumber_nodes_and_elements is false.
899 //
900 // Instances where you if prepare_for_use() should not renumber the nodes
901 // and elements include reading in e.g. an xda/r or gmv file. In
902 // this case, the ordering of the nodes may depend on an accompanying
903 // solution, and the node ordering cannot be changed.
904
905
906 // Mesh modification operations might not leave us with consistent
907 // id counts, or might leave us with orphaned nodes we're no longer
908 // using, but our partitioner might need that consistency and/or
909 // might be confused by orphaned nodes.
911 {
915 }
916 else
917 {
919 this->remove_orphaned_nodes();
922 }
923
924 // Let all the elements find their neighbors
926 this->find_neighbors();
927
928 // The user may have set boundary conditions. We require that the
929 // boundary conditions were set consistently. Because we examine
930 // neighbors when evaluating non-raw boundary condition IDs, this
931 // assert is only valid when our neighbor links are in place.
932#ifdef DEBUG
934#endif
935
936 // Search the mesh for all the dimensions of the elements
937 // and cache them.
939 this->cache_elem_data();
940
941 // libMesh expects every processor to know about every subdomain
942 // name, but distributed mesh generators may only have set names for
943 // the part of the mesh they know about, so make sure the map is
944 // consistent everywhere.
947
948 // Search the mesh for elements that have a neighboring element
949 // of dim+1 and set that element as the interior parent
951 {
954 else
955 {
956 // We must set the flag that says "interior parent pointers have been set up"
957 // even though we skip detect_interior_parents().
959 }
960 }
961
962 // Fix up node unique ids in case mesh generation code didn't take
963 // exceptional care to do so.
964 // MeshCommunication().make_node_unique_ids_parallel_consistent(*this);
965
966 // We're going to still require that mesh generation code gets
967 // element unique ids consistent.
968#if defined(DEBUG) && defined(LIBMESH_ENABLE_UNIQUE_ID)
970#endif
971
972 // Allow our GhostingFunctor objects to reinit if necessary.
973 // Do this before partitioning and redistributing, and before
974 // deleting remote elements.
977
978 // Partition the mesh unless *all* partitioning is to be skipped.
979 // If only noncritical partitioning is to be skipped, the
980 // partition() call will still check for orphaned nodes.
982 this->partition();
983 else if (!this->n_unpartitioned_elem() &&
984 !this->n_unpartitioned_nodes())
986
987 // If we're using DistributedMesh, we'll probably want it
988 // parallelized.
992 else
994
995 // Much of our boundary info may have been for now-remote parts of the mesh,
996 // in which case we don't want to keep local copies of data meant to be
997 // local. On the other hand we may have deleted, or the user may have added in
998 // a distributed fashion, boundary data that is meant to be global. So we
999 // handle both of those scenarios here
1002
1005
1006 // The mesh is now prepared for use, with the possible exception of
1007 // partitioning that was supposed to be skipped, and it should know
1008 // it.
1009#ifndef NDEBUG
1010 Preparation completed_preparation = _preparation;
1011 if (skip_partitioning())
1012 completed_preparation.is_partitioned = true;
1013 libmesh_assert(completed_preparation);
1014#endif
1015
1016#ifdef DEBUG
1018#ifdef LIBMESH_ENABLE_UNIQUE_ID
1020#endif
1021#endif
1022}
bool skip_partitioning() const
Definition mesh_base.h:1435
virtual void renumber_nodes_and_elements()=0
After partitioning a mesh it is useful to renumber the nodes and elements so that they lie in contigu...
dof_id_type n_unpartitioned_elem() const
Definition mesh_base.h:700
void remove_orphaned_nodes()
Removes any orphaned nodes, nodes not connected to any elements.
Definition mesh_base.C:801
dof_id_type n_unpartitioned_nodes() const
Definition mesh_base.h:594
virtual void delete_remote_elements()
When supported, deletes all nonlocal elements of the mesh except for "ghosts" which touch a local ele...
Definition mesh_base.h:399
virtual void find_neighbors(const bool reset_remote_elements=false, const bool reset_current_list=true, const bool assert_valid=true, const bool check_non_remote=true)=0
Locate element face (edge in 2D) neighbors.
void sync_subdomain_name_map()
libMesh often expects all processors to know about names of all subdomain ids, but distributed mesh g...
Definition mesh_base.C:2081
virtual void update_parallel_id_counts()=0
Updates parallel caches so that methods like n_elem() accurately reflect changes on other processors.
void reinit_ghosting_functors()
Loops over ghosting functors and calls mesh_reinit()
Definition mesh_base.C:1025
void detect_interior_parents()
Search the mesh for elements that have a neighboring element of dim+1 and set that element as the int...
Definition mesh_base.C:2092
void libmesh_assert_valid_unique_ids(const MeshBase &mesh)
A function for verifying that unique ids match across processors.
void libmesh_assert_valid_boundary_ids(const MeshBase &mesh)
A function for verifying that boundary condition ids match across processors.
void libmesh_assert_valid_constraint_rows(const MeshBase &mesh)
A function for verifying that all mesh constraint rows express relations between nodes and elements t...

References libMesh::MeshBase::_allow_remote_element_removal, libMesh::MeshBase::_preparation, libMesh::MeshBase::_skip_detect_interior_parents, libMesh::MeshBase::_skip_find_neighbors, libMesh::MeshBase::_skip_renumber_nodes_and_elements, libMesh::MeshBase::cache_elem_data(), libMesh::ParallelObject::comm(), libMesh::MeshBase::delete_remote_elements(), libMesh::MeshBase::detect_interior_parents(), libMesh::MeshBase::find_neighbors(), libMesh::MeshBase::get_boundary_info(), libMesh::MeshBase::Preparation::has_boundary_id_sets, libMesh::MeshBase::Preparation::has_cached_elem_data, libMesh::MeshBase::Preparation::has_interior_parent_ptrs, libMesh::MeshBase::Preparation::has_neighbor_ptrs, libMesh::MeshBase::Preparation::has_reinit_ghosting_functors, libMesh::MeshBase::Preparation::has_removed_orphaned_nodes, libMesh::MeshBase::Preparation::has_removed_remote_elements, libMesh::MeshBase::Preparation::has_synched_id_counts, libMesh::MeshBase::Preparation::has_synched_subdomain_name_map, libMesh::MeshBase::Preparation::is_partitioned, libMesh::MeshBase::is_serial(), libMesh::libmesh_assert(), libMesh::MeshTools::libmesh_assert_valid_boundary_ids(), libMesh::MeshTools::libmesh_assert_valid_constraint_rows(), libMesh::MeshTools::libmesh_assert_valid_unique_ids(), libMesh::MeshBase::n_unpartitioned_elem(), libMesh::MeshBase::n_unpartitioned_nodes(), libMesh::MeshBase::partition(), libMesh::BoundaryInfo::regenerate_id_sets(), libMesh::MeshBase::reinit_ghosting_functors(), libMesh::MeshBase::remove_orphaned_nodes(), libMesh::MeshBase::renumber_nodes_and_elements(), libMesh::MeshBase::skip_partitioning(), libMesh::MeshBase::sync_subdomain_name_map(), and libMesh::MeshBase::update_parallel_id_counts().

Referenced by main(), libMesh::MeshBase::prepare_for_use(), BoundaryMeshSubdomainTest::testDefaultSubdomain(), MeshBaseTest::testMeshBaseVerifyHasCachedElemData(), MeshBaseTest::testMeshBaseVerifyHasNeighborPtrs(), MeshBaseTest::testMeshBaseVerifyRemovalPreparation(), BoundaryMeshSubdomainTest::testPerBoundarySubdomain(), and BoundaryMeshSubdomainTest::testSingleSubdomain().

◆ contract()

bool libMesh::UnstructuredMesh::contract ( )
overridevirtualinherited

Delete subactive (i.e.

children of coarsened) elements. This removes all elements descended from currently active elements in the mesh.

Implements libMesh::MeshBase.

Definition at line 1583 of file unstructured_mesh.C.

1584{
1585 LOG_SCOPE ("contract()", "Mesh");
1586
1587 // Flag indicating if this call actually changes the mesh
1588 bool mesh_changed = false;
1589
1590#ifdef DEBUG
1591 for (const auto & elem : this->element_ptr_range())
1592 libmesh_assert(elem->active() || elem->subactive() || elem->ancestor());
1593#endif
1594
1595 // Loop over the elements.
1596 for (auto & elem : this->element_ptr_range())
1597 {
1598 // Delete all the subactive ones
1599 if (elem->subactive())
1600 {
1601 // No level-0 element should be subactive.
1602 // Note that we CAN'T test elem->level(), as that
1603 // touches elem->parent()->dim(), and elem->parent()
1604 // might have already been deleted!
1605 libmesh_assert(elem->parent());
1606
1607 // Delete the element
1608 // This just sets a pointer to nullptr, and doesn't
1609 // invalidate any iterators
1610 this->delete_elem(elem);
1611
1612 // the mesh has certainly changed
1613 mesh_changed = true;
1614 }
1615 else
1616 {
1617 // Compress all the active ones
1618 if (elem->active())
1619 elem->contract();
1620 else
1621 libmesh_assert (elem->ancestor());
1622 }
1623 }
1624
1625 // Strip any newly-created nullptr voids out of the element array
1627
1628 // FIXME: Need to understand why deleting subactive children
1629 // invalidates the point locator. For now we will clear it explicitly
1630 this->clear_point_locator();
1631
1632 // Allow our GhostingFunctor objects to reinit if necessary.
1633 for (auto & gf : as_range(this->ghosting_functors_begin(),
1634 this->ghosting_functors_end()))
1635 {
1636 libmesh_assert(gf);
1637 gf->mesh_reinit();
1638 }
1639
1640 return mesh_changed;
1641}
virtual void delete_elem(Elem *e)=0
Removes element e from the mesh.
GhostingFunctorIterator ghosting_functors_begin() const
Beginning of range of ghosting functors.
Definition mesh_base.h:1476
GhostingFunctorIterator ghosting_functors_end() const
End of range of ghosting functors.
Definition mesh_base.h:1482
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.

References libMesh::as_range(), libMesh::MeshBase::clear_point_locator(), libMesh::MeshBase::delete_elem(), libMesh::MeshBase::ghosting_functors_begin(), libMesh::MeshBase::ghosting_functors_end(), libMesh::libmesh_assert(), and libMesh::MeshBase::renumber_nodes_and_elements().

◆ copy_cached_data()

void libMesh::MeshBase::copy_cached_data ( const MeshBase &  other_mesh)
protectedinherited

Helper class to copy cached data, to synchronize with a possibly unprepared other_mesh.

Definition at line 2447 of file mesh_base.C.

2448{
2449 this->_spatial_dimension = other_mesh._spatial_dimension;
2450 this->_elem_dims = other_mesh._elem_dims;
2451 this->_elem_default_orders = other_mesh._elem_default_orders;
2452 this->_supported_nodal_order = other_mesh._supported_nodal_order;
2453 this->_mesh_subdomains = other_mesh._mesh_subdomains;
2454}

References libMesh::MeshBase::_elem_default_orders, libMesh::MeshBase::_elem_dims, libMesh::MeshBase::_mesh_subdomains, libMesh::MeshBase::_spatial_dimension, and libMesh::MeshBase::_supported_nodal_order.

◆ copy_constraint_rows() [1/2]

void libMesh::MeshBase::copy_constraint_rows ( const MeshBase &  other_mesh)
inherited

Copy the constraints from the other mesh to this mesh.

Definition at line 2506 of file mesh_base.C.

2507{
2508 LOG_SCOPE("copy_constraint_rows(mesh)", "MeshBase");
2509
2510 _n_constraint_rows = other_mesh._n_constraint_rows;
2511
2512 _constraint_rows.clear();
2513
2514 const auto & other_constraint_rows = other_mesh.get_constraint_rows();
2515 for (const auto & [other_node, other_node_constraints] : other_constraint_rows)
2516 {
2517 const Node * const our_node = this->node_ptr(other_node->id());
2518 constraint_rows_mapped_type our_node_constraints;
2519 for (const auto & [other_inner_key_pair, constraint_value] : other_node_constraints)
2520 {
2521 const auto & [other_elem, local_node_id] = other_inner_key_pair;
2522 const Elem * const our_elem = this->elem_ptr(other_elem->id());
2523 our_node_constraints.emplace_back(std::make_pair(our_elem, local_node_id), constraint_value);
2524 }
2525 _constraint_rows[our_node] = std::move(our_node_constraints);
2526 }
2527}
virtual const Node * node_ptr(const dof_id_type i) const =0
std::vector< std::pair< std::pair< const Elem *, unsigned int >, Real > > constraint_rows_mapped_type
Definition mesh_base.h:1933
virtual const Elem * elem_ptr(const dof_id_type i) const =0
constraint_rows_type _constraint_rows
Definition mesh_base.h:2454
dof_id_type _n_constraint_rows
Definition mesh_base.h:2456

References libMesh::MeshBase::_constraint_rows, libMesh::MeshBase::_n_constraint_rows, libMesh::MeshBase::elem_ptr(), libMesh::MeshBase::get_constraint_rows(), and libMesh::MeshBase::node_ptr().

Referenced by libMesh::DistributedMesh::DistributedMesh(), main(), libMesh::ReplicatedMesh::ReplicatedMesh(), ConstraintOperatorTest::test1DCoarseningNewNodes(), ConstraintOperatorTest::test1DCoarseningOperator(), ConstraintOperatorTest::testCoreform(), and ConnectedComponentsTest::testEdge().

◆ copy_constraint_rows() [2/2]

template<typename T >
void libMesh::MeshBase::copy_constraint_rows ( const SparseMatrix< T > &  constraint_operator,
bool  precondition_constraint_operator = false 
)
inherited

Copy the constraints from the given matrix to this mesh.

The constraint_operator should be an mxn matrix, where m == this->n_nodes() and the operator indexing matches the current node indexing. This may require users to disable mesh renumbering in between loading a mesh file and loading a constraint matrix which matches it.

If any "constraint" rows in the matrix are unit vectors, the node corresponding to that row index will be left unconstrained, and will be used to constrain any other nodes which have a non-zero in the column index of that unit vector.

For each matrix column index which does not correspond to an existing node, a new NodeElem will be added to the mesh on which to store the new unconstrained degree(s) of freedom.

If precondition_constraint_operator is true, then the values of those new unconstrained degrees of freedom may be scaled to improve the conditioning of typical PDE matrices integrated on constrained mesh elements.

T for the constraint_operator in this function should be Real or Number ... and the data should be Real - we just allow complex T for the sake of subclasses which have to be configured and compiled with only one runtime option.

Definition at line 2532 of file mesh_base.C.

2534{
2535 LOG_SCOPE("copy_constraint_rows(mat)", "MeshBase");
2536
2537 this->_constraint_rows.clear();
2538
2539 // We're not going to support doing this distributed yet; it'd be
2540 // pointless unless we temporarily had a linear partitioning to
2541 // better match the constraint operator.
2542 MeshSerializer serialize(*this);
2543
2544 // Our current mesh should already reflect the desired assembly space
2545 libmesh_error_msg_if(this->n_nodes() != constraint_operator.m(),
2546 "Constraint operator matrix with " <<
2547 constraint_operator.m() <<
2548 "rows does not match this mesh with " <<
2549 this->n_nodes() << " nodes");
2550
2551 // First, find what new unconstrained DoFs we need to add. We can't
2552 // iterate over columns in a SparseMatrix, so we'll iterate over
2553 // rows and keep track of columns.
2554
2555 // If we have nodes that will work unconstrained, keep track of
2556 // their node ids and corresponding column indices.
2557 // existing_unconstrained_nodes[column_id] = node_id
2558 std::map<dof_id_type, dof_id_type> existing_unconstrained_columns;
2559 std::set<dof_id_type> existing_unconstrained_nodes;
2560
2561 // In case we need new nodes, keep track of their columns.
2562 // columns[j][k] will be the kth row index and value of column j
2563 typedef
2564 std::unordered_map<dof_id_type,
2565 std::vector<std::pair<dof_id_type, Real>>>
2566 columns_type;
2567 columns_type columns(constraint_operator.n());
2568
2569 // If we need to precondition the constraint operator (e.g. it's an
2570 // unpreconditioned extraction operator for a Flex IGA matrix),
2571 // we'll want to keep track of the sum of each column, because we'll
2572 // be dividing each column by that sum (Jacobi preconditioning on
2573 // the right, which then leads to symmetric preconditioning on a
2574 // physics Jacobian).
2575 std::unordered_map<dof_id_type, Real> column_sums;
2576
2577 // Work in parallel, though we'll have to sync shortly
2578 for (auto i : make_range(constraint_operator.row_start(),
2579 constraint_operator.row_stop()))
2580 {
2581 std::vector<numeric_index_type> indices;
2582 std::vector<T> values;
2583
2584 constraint_operator.get_row(i, indices, values);
2585 libmesh_assert_equal_to(indices.size(), values.size());
2586
2587 if (indices.size() == 1 &&
2588 values[0] == T(1))
2589 {
2590 // If we have multiple simple Ui=Uj constraints, let the
2591 // first one be our "unconstrained" node and let the others
2592 // be constrained to it.
2593 if (existing_unconstrained_columns.find(indices[0]) !=
2594 existing_unconstrained_columns.end())
2595 {
2596 const auto j = indices[0];
2597 columns[j].emplace_back(i, 1);
2598 }
2599 else
2600 {
2601 existing_unconstrained_nodes.insert(i);
2602 existing_unconstrained_columns.emplace(indices[0],i);
2603 }
2604 }
2605 else
2606 for (auto jj : index_range(indices))
2607 {
2608 const auto j = indices[jj];
2609 const Real coef = libmesh_real(values[jj]);
2610 libmesh_assert_equal_to(coef, values[jj]);
2611 columns[j].emplace_back(i, coef);
2612 }
2613 }
2614
2615 // Merge data from different processors' slabs of the matrix
2616 this->comm().set_union(existing_unconstrained_nodes);
2617 this->comm().set_union(existing_unconstrained_columns);
2618
2619 std::vector<columns_type> all_columns;
2620 this->comm().allgather(columns, all_columns);
2621
2622 columns.clear();
2623 for (auto p : index_range(all_columns))
2624 for (auto & [j, subcol] : all_columns[p])
2625 for (auto [i, v] : subcol)
2626 columns[j].emplace_back(i,v);
2627
2628 // Keep track of elements on which unconstrained nodes exist, and
2629 // their local node indices.
2630 // node_to_elem_ptrs[node] = [elem_id, local_node_num]
2631 std::unordered_map<const Node *, std::pair<dof_id_type, unsigned int>> node_to_elem_ptrs;
2632
2633 // Find elements attached to any existing nodes that will stay
2634 // unconstrained. We'll also build a subdomain set here so we don't
2635 // have to assert that the mesh is already prepared before we pick a
2636 // new subdomain for any NodeElems we need to add.
2637 std::set<subdomain_id_type> subdomain_ids;
2638 for (const Elem * elem : this->element_ptr_range())
2639 {
2640 subdomain_ids.insert(elem->subdomain_id());
2641 for (auto n : make_range(elem->n_nodes()))
2642 {
2643 const Node * node = elem->node_ptr(n);
2644 if (existing_unconstrained_nodes.count(node->id()))
2645 node_to_elem_ptrs.emplace(node, std::make_pair(elem->id(), n));
2646 }
2647 }
2648
2649 const subdomain_id_type new_sbd_id = *subdomain_ids.rbegin() + 1;
2650
2651 for (auto j : make_range(constraint_operator.n()))
2652 {
2653 // If we already have a good node for this then we're done
2654 if (existing_unconstrained_columns.count(j))
2655 continue;
2656
2657 // Get a half-decent spot to place a new NodeElem for
2658 // unconstrained DoF(s) here. Getting a *fully*-decent spot
2659 // would require finding a Moore-Penrose pseudoinverse, and I'm
2660 // not going to do that, but scaling a transpose will at least
2661 // get us a little uniqueness to make visualization reasonable.
2662 Point newpt;
2663 Real total_scaling = 0;
2664 unsigned int total_entries = 0;
2665
2666 // We'll get a decent initial pid choice here too, if only to
2667 // aid in later repartitioning.
2668 std::map<processor_id_type, int> pids;
2669
2670 auto & column = columns[j];
2671 for (auto [i, r] : column)
2672 {
2673 Node & constrained_node = this->node_ref(i);
2674 const Point constrained_pt = constrained_node;
2675 newpt += r*constrained_pt;
2676 total_scaling += r;
2677 ++total_entries;
2678 ++pids[constrained_node.processor_id()];
2679 }
2680
2681 if (precondition_constraint_operator)
2682 column_sums[j] = total_scaling;
2683
2684 libmesh_error_msg_if
2685 (!total_entries,
2686 "Empty column " << j <<
2687 " found in constraint operator matrix");
2688
2689 // If we have *cancellation* here then we can end up dividing by
2690 // zero; try just evenly scaling across all constrained node
2691 // points instead.
2692 if (total_scaling > TOLERANCE)
2693 newpt /= total_scaling;
2694 else
2695 newpt /= total_entries;
2696
2697 Node *n = this->add_point(newpt);
2698 std::unique_ptr<Elem> elem = Elem::build(NODEELEM);
2699 elem->set_node(0, n);
2700 elem->subdomain_id() = new_sbd_id;
2701
2702 Elem * added_elem = this->add_elem(std::move(elem));
2703 this->_elem_dims.insert(0);
2704 this->_elem_default_orders.insert(added_elem->default_order());
2706 static_cast<Order>
2707 (std::min(static_cast<int>(this->_supported_nodal_order),
2708 static_cast<int>(added_elem->supported_nodal_order())));
2709 this->_mesh_subdomains.insert(new_sbd_id);
2710 node_to_elem_ptrs.emplace(n, std::make_pair(added_elem->id(), 0));
2711 existing_unconstrained_columns.emplace(j,n->id());
2712
2713 // Repartition the new objects *after* adding them, so a
2714 // DistributedMesh doesn't get confused and think you're not
2715 // adding them on all processors at once.
2716 int n_pids = 0;
2717 for (auto [pid, count] : pids)
2718 if (count >= n_pids)
2719 {
2720 n_pids = count;
2721 added_elem->processor_id() = pid;
2722 n->processor_id() = pid;
2723 }
2724 }
2725
2726 // Calculate constraint rows in an indexed form that's easy for us
2727 // to allgather
2728 std::unordered_map<dof_id_type,
2729 std::vector<std::pair<std::pair<dof_id_type, unsigned int>,Real>>>
2730 indexed_constraint_rows;
2731
2732 for (auto i : make_range(constraint_operator.row_start(),
2733 constraint_operator.row_stop()))
2734 {
2735 if (existing_unconstrained_nodes.count(i))
2736 continue;
2737
2738 std::vector<numeric_index_type> indices;
2739 std::vector<T> values;
2740
2741 constraint_operator.get_row(i, indices, values);
2742
2743 std::vector<std::pair<std::pair<dof_id_type, unsigned int>, Real>> constraint_row;
2744
2745 for (auto jj : index_range(indices))
2746 {
2747 const dof_id_type node_id =
2748 existing_unconstrained_columns[indices[jj]];
2749
2750 Node & constraining_node = this->node_ref(node_id);
2751
2752 libmesh_assert(node_to_elem_ptrs.count(&constraining_node));
2753
2754 auto p = node_to_elem_ptrs[&constraining_node];
2755
2756 Real coef = libmesh_real(values[jj]);
2757 libmesh_assert_equal_to(coef, values[jj]);
2758
2759 // If we're preconditioning and we created a nodeelem then
2760 // we can scale the meaning of that nodeelem's value to give
2761 // us a better-conditioned matrix after the constraints are
2762 // applied.
2763 if (precondition_constraint_operator)
2764 if (auto sum_it = column_sums.find(indices[jj]);
2765 sum_it != column_sums.end())
2766 {
2767 const Real scaling = sum_it->second;
2768
2769 if (scaling > TOLERANCE)
2770 coef /= scaling;
2771 }
2772
2773 constraint_row.emplace_back(std::make_pair(p, coef));
2774 }
2775
2776 indexed_constraint_rows.emplace(i, std::move(constraint_row));
2777 }
2778
2779 this->comm().set_union(indexed_constraint_rows);
2780
2781 // Add constraint rows as mesh constraint rows
2782 for (auto & [node_id, indexed_row] : indexed_constraint_rows)
2783 {
2784 Node * constrained_node = this->node_ptr(node_id);
2785
2786 constraint_rows_mapped_type constraint_row;
2787
2788 for (auto [p, coef] : indexed_row)
2789 {
2790 const Elem * elem = this->elem_ptr(p.first);
2791 constraint_row.emplace_back
2792 (std::make_pair(std::make_pair(elem, p.second), coef));
2793 }
2794
2795 this->_constraint_rows.emplace(constrained_node,
2796 std::move(constraint_row));
2797 }
2798
2800}
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
virtual const Node & node_ref(const dof_id_type i) const
Definition mesh_base.h:742
void subdomain_ids(std::set< subdomain_id_type > &ids, const bool global=true) const
Constructs a list of all subdomain identifiers in the local mesh if global == false,...
Definition mesh_base.C:1127
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
Add a new Node at Point p to the end of the vertex array, with processor_id procid.
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
dof_id_type count_constraint_rows()
Helper function for subclasses to use to set _n_constraint_rows.
Definition mesh_base.C:2487
LIBMESH_DEVICE_INLINE ResultVector column(const TensorLike &T_in, const unsigned int col_index)
TestClass subdomain_id_type
Based on the 4-byte comment warning above, this probably doesn't work with exodusII at all....
Definition id_types.h:43
LIBMESH_DEVICE_INLINE T libmesh_real(T a)
static constexpr Real TOLERANCE
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition int_range.h:176

References libMesh::MeshBase::_constraint_rows, libMesh::MeshBase::_elem_default_orders, libMesh::MeshBase::_elem_dims, libMesh::MeshBase::_mesh_subdomains, libMesh::MeshBase::_n_constraint_rows, libMesh::MeshBase::_supported_nodal_order, libMesh::MeshBase::add_elem(), libMesh::MeshBase::add_point(), libMesh::Parallel::Communicator::allgather(), libMesh::Elem::build(), libMesh::ParallelObject::comm(), libMesh::MeshBase::count_constraint_rows(), libMesh::Elem::default_order(), libMesh::MeshBase::elem_ptr(), libMesh::SparseMatrix< T >::get_row(), libMesh::DofObject::id(), libMesh::index_range(), libMesh::libmesh_assert(), libMesh::libmesh_real(), libMesh::SparseMatrix< T >::m(), libMesh::make_range(), libMesh::SparseMatrix< T >::n(), libMesh::MeshBase::n_nodes(), libMesh::MeshBase::node_ptr(), libMesh::MeshBase::node_ref(), libMesh::NODEELEM, libMesh::DofObject::processor_id(), libMesh::Real, libMesh::SparseMatrix< T >::row_start(), libMesh::SparseMatrix< T >::row_stop(), libMesh::Parallel::Communicator::set_union(), libMesh::MeshBase::subdomain_ids(), libMesh::Elem::supported_nodal_order(), and libMesh::TOLERANCE.

◆ copy_nodes_and_elements()

void libMesh::UnstructuredMesh::copy_nodes_and_elements ( const MeshBase &  other_mesh,
const bool  skip_find_neighbors = false,
dof_id_type  element_id_offset = 0,
dof_id_type  node_id_offset = 0,
unique_id_type  unique_id_offset = 0,
std::unordered_map< subdomain_id_type, subdomain_id_type > *  id_remapping = nullptr,
const bool  skip_preparation = false 
)
virtualinherited

Deep copy of nodes and elements from another mesh object (used by subclass copy constructors and by mesh merging operations)

This will not copy most "high level" data in the mesh; that is done separately by constructors. An exception is that, if the other_mesh has element or node extra_integer data, any names for that data which do not already exist on this mesh are added so that all such data can be copied.

If an id_remapping map is provided, then element subdomain ids in other_mesh will be converted using it before adding them to this mesh.

For backwards compatibility, this does some limited mesh preparation after the copy: everything except for renumbering, remote element removal, and partitioning. To skip just the step of that preparation which finds new neighbor_ptr links between elements, set skip_find_neighbors. To skip all of that preparation, set skip_preparation. If preparation is skipped, it is the users responsibility to set the flags indicating what preparation may still be necessary before using the mesh later.

Definition at line 648 of file unstructured_mesh.C.

660{
661 LOG_SCOPE("copy_nodes_and_elements()", "UnstructuredMesh");
662
663 // If we're asked to skip all preparation, we should be skipping
664 // find_neighbors specifically.
665 libmesh_assert(!skip_preparation || skip_find_neighbors);
666
667 std::pair<std::vector<unsigned int>, std::vector<unsigned int>>
668 extra_int_maps = this->merge_extra_integer_names(other_mesh);
669
670 const unsigned int n_old_node_ints = extra_int_maps.second.size(),
671 n_new_node_ints = _node_integer_names.size(),
672 n_old_elem_ints = extra_int_maps.first.size(),
673 n_new_elem_ints = _elem_integer_names.size();
674
675 // If we are partitioned into fewer parts than the incoming mesh has
676 // processors to handle, then we need to "wrap" the other Mesh's
677 // processor ids to fit within our range. This can happen, for
678 // example, while stitching meshes with small numbers of elements in
679 // parallel...
680 bool wrap_proc_ids = (this->n_processors() <
681 other_mesh.n_partitions());
682
683 // We're assuming the other mesh has proper element number ordering,
684 // so that we add parents before their children, and that the other
685 // mesh is consistently partitioned. We're not assuming that node
686 // proc ids are topologically consistent, so we don't just
687 // libmesh_assert_valid_procids.
688#ifdef DEBUG
691#endif
692
693 //Copy in Nodes
694 {
695 //Preallocate Memory if necessary
696 this->reserve_nodes(other_mesh.n_nodes());
697
698 for (const auto & oldn : other_mesh.node_ptr_range())
699 {
700 processor_id_type added_pid = cast_int<processor_id_type>
701 (wrap_proc_ids ? oldn->processor_id() % this->n_processors() : oldn->processor_id());
702
703 // Add new nodes in old node Point locations
704 Node * newn =
705 this->add_point(*oldn,
706 oldn->id() + node_id_offset,
707 added_pid);
708
709 newn->add_extra_integers(n_new_node_ints);
710 for (unsigned int i = 0; i != n_old_node_ints; ++i)
711 newn->set_extra_integer(extra_int_maps.second[i],
712 oldn->get_extra_integer(i));
713
714#ifdef LIBMESH_ENABLE_UNIQUE_ID
715 newn->set_unique_id(oldn->unique_id() + unique_id_offset);
716#endif
717 }
718 }
719
720 //Copy in Elements
721 {
722 //Preallocate Memory if necessary
723 this->reserve_elem(other_mesh.n_elem());
724
725 // Declare a map linking old and new elements, needed to copy the neighbor lists
726 typedef std::unordered_map<const Elem *, Elem *> map_type;
727 map_type old_elems_to_new_elems, ip_map;
728
729 // Loop over the elements
730 for (const auto & old : other_mesh.element_ptr_range())
731 {
732 // Build a new element
733 Elem * newparent = old->parent() ?
734 this->elem_ptr(old->parent()->id() + element_id_offset) :
735 nullptr;
736 auto el = old->disconnected_clone();
737 el->set_parent(newparent);
738
739 subdomain_id_type sbd_id = old->subdomain_id();
740 if (id_remapping)
741 {
742 auto remapping_it = id_remapping->find(sbd_id);
743 if (remapping_it != id_remapping->end())
744 sbd_id = remapping_it->second;
745 }
746 el->subdomain_id() = sbd_id;
747
748 // Hold off on trying to set the interior parent because we may actually
749 // add lower dimensional elements before their interior parents
750 if (old->interior_parent())
751 ip_map[old] = el.get();
752
753#ifdef LIBMESH_ENABLE_AMR
754 if (old->has_children())
755 for (unsigned int c = 0, nc = old->n_children(); c != nc; ++c)
756 if (old->child_ptr(c) == remote_elem)
757 el->add_child(const_cast<RemoteElem *>(remote_elem), c);
758
759 //Create the parent's child pointers if necessary
760 if (newparent)
761 {
762 unsigned int oldc = old->parent()->which_child_am_i(old);
763 newparent->add_child(el.get(), oldc);
764 }
765
766 // Copy the refinement flags
767 el->set_refinement_flag(old->refinement_flag());
768
769 // Use hack_p_level since we may not have sibling elements
770 // added yet
771 el->hack_p_level(old->p_level());
772
773 el->set_p_refinement_flag(old->p_refinement_flag());
774#endif // #ifdef LIBMESH_ENABLE_AMR
775
776 //Assign all the nodes
777 for (auto i : el->node_index_range())
778 el->set_node(i,
779 this->node_ptr(old->node_id(i) + node_id_offset));
780
781 // And start it off with the same processor id (mod _n_parts).
782 el->processor_id() = cast_int<processor_id_type>
783 (wrap_proc_ids ? old->processor_id() % this->n_processors() : old->processor_id());
784
785 // Give it the same element and unique ids
786 el->set_id(old->id() + element_id_offset);
787
788 el->add_extra_integers(n_new_elem_ints);
789 for (unsigned int i = 0; i != n_old_elem_ints; ++i)
790 el->set_extra_integer(extra_int_maps.first[i],
791 old->get_extra_integer(i));
792
793#ifdef LIBMESH_ENABLE_UNIQUE_ID
794 el->set_unique_id(old->unique_id() + unique_id_offset);
795#endif
796
797 //Hold onto it
798 if (!skip_find_neighbors)
799 {
800 for (auto s : old->side_index_range())
801 if (old->neighbor_ptr(s) == remote_elem)
802 el->set_neighbor(s, const_cast<RemoteElem *>(remote_elem));
803 this->add_elem(std::move(el));
804 }
805 else
806 {
807 Elem * new_el = this->add_elem(std::move(el));
808 old_elems_to_new_elems[old] = new_el;
809 }
810 }
811
812 // If the other_mesh had some interior parents, we may need to
813 // copy those pointers (if they're to elements in a third mesh),
814 // or create new equivalent pointers (if they're to elements we
815 // just copied), or scream and die (if the other mesh had interior
816 // parents from a third mesh but we already have interior parents
817 // that aren't to that same third mesh.
818 if (!ip_map.empty())
819 {
820 std::atomic<bool> existing_interior_parents{false};
821
823 (this->element_stored_range(),
824 [&existing_interior_parents](const ElemRange & range)
825 {
826 for (Elem * elem : range)
827 if (elem->interior_parent())
828 {
829 existing_interior_parents = true;
830 break;
831 }
832 });
833
834 MeshBase * other_interior_mesh =
835 const_cast<MeshBase *>(&other_mesh.interior_mesh());
836
837 // If we don't already have interior parents, then we can just
838 // use whatever interior_mesh we need for the incoming
839 // elements.
840 if (!existing_interior_parents)
841 {
842 if (other_interior_mesh == &other_mesh)
843 this->set_interior_mesh(*this);
844 else
845 this->set_interior_mesh(*other_interior_mesh);
846 }
847
848 if (other_interior_mesh == &other_mesh &&
849 _interior_mesh == this)
850 for (auto & elem_pair : ip_map)
851 elem_pair.second->set_interior_parent(
852 this->elem_ptr(elem_pair.first->interior_parent()->id() + element_id_offset));
853 else if (other_interior_mesh == _interior_mesh)
854 for (auto & elem_pair : ip_map)
855 {
856 Elem * ip = const_cast<Elem *>(elem_pair.first->interior_parent());
858 ip == other_interior_mesh->elem_ptr(ip->id()));
859 elem_pair.second->set_interior_parent(ip);
860 }
861 else
862 libmesh_error_msg("Cannot copy boundary elements between meshes with different interior meshes");
863 }
864
865 // Loop (again) over the elements to fill in the neighbors
866 if (skip_find_neighbors)
867 {
868 old_elems_to_new_elems[remote_elem] = const_cast<RemoteElem*>(remote_elem);
869
870 for (const auto & old_elem : other_mesh.element_ptr_range())
871 {
872 Elem * new_elem = old_elems_to_new_elems[old_elem];
873 for (auto s : old_elem->side_index_range())
874 {
875 const Elem * old_neighbor = old_elem->neighbor_ptr(s);
876 Elem * new_neighbor = old_elems_to_new_elems[old_neighbor];
877 new_elem->set_neighbor(s, new_neighbor);
878 }
879 }
880 }
881 }
882
883#ifdef LIBMESH_ENABLE_UNIQUE_ID
884 // We set the unique ids of nodes after adding them to the mesh such that our value of
885 // _next_unique_id may be wrong. So we amend that here
886 this->set_next_unique_id(other_mesh.parallel_max_unique_id() + unique_id_offset + 1);
887#endif
888
889 // Finally, partially prepare the new Mesh for use, if that isn't
890 // being skipped.
891 // Even the default behavior here is for backwards compatibility,
892 // and we don't want to prepare everything.
893
894 if (!skip_preparation)
895 {
896 // Keep the same numbering and partitioning and distribution
897 // status for now, but save our original policies to restore
898 // later.
899 const bool allowed_renumbering = this->allow_renumbering();
900 const bool allowed_find_neighbors = this->allow_find_neighbors();
901 const bool allowed_elem_removal = this->allow_remote_element_removal();
902 const bool allowed_detect_detect_interior_parents = this->allow_detect_interior_parents();
903 this->allow_renumbering(false);
904 this->allow_remote_element_removal(false);
905 this->allow_find_neighbors(!skip_find_neighbors);
907
908 // We should generally be able to skip *all* partitioning here
909 // because we're only adding one already-consistent mesh to
910 // another.
911 const bool skipped_partitioning = this->skip_partitioning();
912 this->skip_partitioning(true);
913
914 const bool was_prepared = this->is_prepared();
915 this->prepare_for_use();
916
917 //But in the long term, don't change our policies.
918 this->allow_find_neighbors(allowed_find_neighbors);
919 this->allow_renumbering(allowed_renumbering);
920 this->allow_remote_element_removal(allowed_elem_removal);
921 this->skip_partitioning(skipped_partitioning);
922 this->allow_detect_interior_parents(allowed_detect_detect_interior_parents);
923
924 // That prepare_for_use() call marked us as prepared, but we
925 // specifically avoided some important preparation, so we might not
926 // actually be prepared now.
927 if (skip_find_neighbors ||
928 !was_prepared || !other_mesh.is_prepared())
929 this->unset_is_prepared();
930 }
931
932 // In general we've just invalidated just about everything, and we'd
933 // like to unset_is_prepared(), but specific use cases might know a
934 // priori that they're still partitioned well, or that they've
935 // copied in a disjoint mesh component and don't need new neighbor
936 // pointers, or that they're not adding anything that would change
937 // cached subdomain/element/boundary sets, etc., so we'll rely on
938 // users of the "advanced" skip_preparation option to also set what
939 // preparation they still need.
940
941 // else
942 // this->unset_is_prepared();
943}
void add_extra_integers(const unsigned int n_integers)
Assigns a set of extra integers to this DofObject.
Definition dof_object.C:482
dof_id_type id() const
Definition dof_object.h:833
void set_unique_id(unique_id_type new_id)
Sets the unique_id for this DofObject.
Definition dof_object.h:862
void set_extra_integer(const unsigned int index, const dof_id_type value)
Sets the value on this object of the extra integer associated with index, which should have been obta...
const Elem * parent() const
Definition elem.h:3168
void set_neighbor(const unsigned int i, Elem *n)
Assigns n as the neighbor.
Definition elem.h:2756
void add_child(Elem *elem)
Adds a child pointer to the array of children of this element.
Definition elem.C:2155
const Elem * neighbor_ptr(unsigned int i) const
Definition elem.h:2736
This is the MeshBase class.
Definition mesh_base.h:81
bool is_prepared() const
Definition mesh_base.C:1065
bool allow_renumbering() const
Definition mesh_base.h:1360
virtual dof_id_type n_elem() const =0
bool allow_detect_interior_parents() const
Definition mesh_base.h:1374
unsigned int n_partitions() const
Definition mesh_base.h:1530
virtual void set_next_unique_id(unique_id_type id)=0
Sets the next available unique id to be used.
MeshBase * _interior_mesh
Defaulting to this, a pointer to the mesh used to generate boundary elements on this.
Definition mesh_base.h:2264
std::pair< std::vector< unsigned int >, std::vector< unsigned int > > merge_extra_integer_names(const MeshBase &other)
Merge extra-integer arrays from an other mesh.
Definition mesh_base.C:2400
const MeshBase & interior_mesh() const
Definition mesh_base.h:2053
bool allow_remote_element_removal() const
Definition mesh_base.h:1383
bool allow_find_neighbors() const
Definition mesh_base.h:1367
virtual void reserve_elem(const dof_id_type ne)=0
Reserves space for a known number of elements.
void set_interior_mesh(MeshBase &int_mesh)
Sets the interior mesh.
Definition mesh_base.h:2063
void allow_detect_interior_parents(bool allow)
If false is passed then this mesh will no longer work to detect interior parents when being prepared ...
Definition mesh_base.h:1373
void unset_is_prepared()
Tells this we have done some operation where we should no longer consider ourself prepared.
Definition mesh_base.C:1071
virtual unique_id_type parallel_max_unique_id() const =0
A Node is like a Point, but with more information.
Definition node.h:55
The StoredRange class defines a contiguous, divisible set of objects.
void libmesh_assert_valid_amr_elem_ids(const MeshBase &mesh)
A function for verifying that ids of elements are correctly sorted for AMR (parents have lower ids th...
void libmesh_assert_parallel_consistent_procids< Node >(const MeshBase &mesh)

References libMesh::MeshBase::_elem_integer_names, libMesh::MeshBase::_interior_mesh, libMesh::MeshBase::_node_integer_names, libMesh::Elem::add_child(), libMesh::MeshBase::add_elem(), libMesh::MeshBase::add_point(), libMesh::MeshBase::allow_detect_interior_parents(), libMesh::MeshBase::allow_detect_interior_parents(), libMesh::MeshBase::allow_find_neighbors(), libMesh::MeshBase::allow_remote_element_removal(), libMesh::MeshBase::allow_renumbering(), libMesh::MeshBase::elem_ptr(), libMesh::MeshBase::element_stored_range(), libMesh::DofObject::id(), libMesh::MeshBase::interior_mesh(), libMesh::MeshBase::is_prepared(), libMesh::libmesh_assert(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_valid_amr_elem_ids(), libMesh::MeshBase::merge_extra_integer_names(), libMesh::MeshBase::n_elem(), libMesh::MeshBase::n_nodes(), libMesh::MeshBase::n_partitions(), libMesh::ParallelObject::n_processors(), libMesh::Elem::neighbor_ptr(), libMesh::Threads::parallel_for(), libMesh::MeshBase::parallel_max_unique_id(), libMesh::Elem::parent(), libMesh::MeshBase::prepare_for_use(), libMesh::remote_elem, libMesh::MeshBase::reserve_elem(), libMesh::MeshBase::reserve_nodes(), libMesh::MeshBase::set_interior_mesh(), libMesh::Elem::set_neighbor(), libMesh::MeshBase::set_next_unique_id(), libMesh::MeshBase::skip_partitioning(), and libMesh::MeshBase::unset_is_prepared().

Referenced by libMesh::DistributedMesh::DistributedMesh(), libMesh::ReplicatedMesh::ReplicatedMesh(), and libMesh::UnstructuredMesh::stitching_helper().

◆ count_constraint_rows()

dof_id_type libMesh::MeshBase::count_constraint_rows ( )
protectedinherited

Helper function for subclasses to use to set _n_constraint_rows.

Definition at line 2487 of file mesh_base.C.

2488{
2489 dof_id_type n_local_rows=0, n_unpartitioned_rows=0;
2490 for (const auto & [node, node_constraints] : _constraint_rows)
2491 {
2492 // Unpartitioned nodes
2493 if (node->processor_id() == DofObject::invalid_processor_id)
2494 n_unpartitioned_rows++;
2495 else if (node->processor_id() == this->processor_id())
2496 n_local_rows++;
2497 }
2498
2499 this->comm().sum(n_local_rows);
2500
2501 return n_unpartitioned_rows + n_local_rows;
2502}

References libMesh::MeshBase::_constraint_rows, libMesh::ParallelObject::comm(), libMesh::DofObject::invalid_processor_id, libMesh::ParallelObject::processor_id(), and libMesh::Parallel::Communicator::sum().

Referenced by libMesh::MeshBase::copy_constraint_rows(), libMesh::MeshCommunication::delete_remote_elements(), libMesh::DistributedMesh::update_parallel_id_counts(), and libMesh::ReplicatedMesh::update_parallel_id_counts().

◆ create_pid_mesh()

void libMesh::UnstructuredMesh::create_pid_mesh ( UnstructuredMesh &  pid_mesh,
const processor_id_type  pid 
) const
inherited

Generates a new mesh containing all the elements which are assigned to processor pid.

This mesh is written to the pid_mesh reference which you must create and pass to the function.

Definition at line 1471 of file unstructured_mesh.C.

1473{
1474
1475 // Issue a warning if the number the number of processors
1476 // currently available is less that that requested for
1477 // partitioning. This is not necessarily an error since
1478 // you may run on one processor and still partition the
1479 // mesh into several partitions.
1480#ifdef DEBUG
1481 if (this->n_processors() < pid)
1482 {
1483 libMesh::out << "WARNING: You are creating a "
1484 << "mesh for a processor id (="
1485 << pid
1486 << ") greater than "
1487 << "the number of processors available for "
1488 << "the calculation. (="
1489 << this->n_processors()
1490 << ")."
1491 << std::endl;
1492 }
1493#endif
1494
1495 this->create_submesh (pid_mesh,
1496 this->active_pid_elements_begin(pid),
1497 this->active_pid_elements_end(pid));
1498}
void create_submesh(UnstructuredMesh &new_mesh, const const_element_iterator &it, const const_element_iterator &it_end) const
Constructs a mesh called "new_mesh" from the current mesh by iterating over the elements between it a...
OStreamProxy out

References libMesh::UnstructuredMesh::create_submesh(), libMesh::ParallelObject::n_processors(), and libMesh::out.

◆ create_submesh()

void libMesh::UnstructuredMesh::create_submesh ( UnstructuredMesh &  new_mesh,
const const_element_iterator &  it,
const const_element_iterator &  it_end 
) const
inherited

Constructs a mesh called "new_mesh" from the current mesh by iterating over the elements between it and it_end and adding them to the new mesh.

Definition at line 1506 of file unstructured_mesh.C.

1509{
1510 // Just in case the subdomain_mesh already has some information
1511 // in it, get rid of it.
1512 new_mesh.clear();
1513
1514 // If we're not serial, our submesh isn't either.
1515 // There are no remote elements to delete on an empty mesh, but
1516 // calling the method to do so marks the mesh as parallel.
1517 if (!this->is_serial())
1518 new_mesh.delete_remote_elements();
1519
1520 // Fail if (*this == new_mesh), we cannot create a submesh inside ourself!
1521 // This may happen if the user accidentally passes the original mesh into
1522 // this function! We will check this by making sure we did not just
1523 // clear ourself.
1524 libmesh_assert_not_equal_to (this->n_nodes(), 0);
1525 libmesh_assert_not_equal_to (this->n_elem(), 0);
1526
1527 // Container to catch boundary IDs handed back by BoundaryInfo
1528 std::vector<boundary_id_type> bc_ids;
1529
1530 // Put any extra integers on the new mesh too
1531 new_mesh.merge_extra_integer_names(*this);
1532 const unsigned int n_node_ints = _node_integer_names.size();
1533
1534 for (const auto & old_elem : as_range(it, it_end))
1535 {
1536 // Add an equivalent element type to the new_mesh.
1537 // disconnected_clone() copies ids, extra element integers, etc.
1538 auto uelem = old_elem->disconnected_clone();
1539 Elem * new_elem = new_mesh.add_elem(std::move(uelem));
1540 libmesh_assert(new_elem);
1541
1542 // Loop over the nodes on this element.
1543 for (auto n : old_elem->node_index_range())
1544 {
1545 const dof_id_type this_node_id = old_elem->node_id(n);
1546
1547 // Add this node to the new mesh if it's not there already
1548 if (!new_mesh.query_node_ptr(this_node_id))
1549 {
1550 Node * newn =
1551 new_mesh.add_point (old_elem->point(n),
1552 this_node_id,
1553 old_elem->node_ptr(n)->processor_id());
1554
1555 newn->add_extra_integers(n_node_ints);
1556 for (unsigned int i = 0; i != n_node_ints; ++i)
1557 newn->set_extra_integer(i, old_elem->node_ptr(n)->get_extra_integer(i));
1558
1559#ifdef LIBMESH_ENABLE_UNIQUE_ID
1560 newn->set_unique_id(old_elem->node_ptr(n)->unique_id());
1561#endif
1562 }
1563
1564 // Define this element's connectivity on the new mesh
1565 new_elem->set_node(n, new_mesh.node_ptr(this_node_id));
1566 }
1567
1568 // Maybe add boundary conditions for this element
1569 for (auto s : old_elem->side_index_range())
1570 {
1571 this->get_boundary_info().boundary_ids(old_elem, s, bc_ids);
1572 new_mesh.get_boundary_info().add_side (new_elem, s, bc_ids);
1573 }
1574 } // end loop over elements
1575
1576 // Prepare the new_mesh for use
1577 new_mesh.prepare_for_use();
1578}
void boundary_ids(const Node *node, std::vector< boundary_id_type > &vec_to_fill) const
Fills a user-provided std::vector with the boundary ids associated with Node node.
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
Add side side of element number elem with boundary id id to the boundary information data structure.
virtual Node *& set_node(const unsigned int i)
Definition elem.h:2688
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
Prepare a newly created (or read) mesh for use.
Definition mesh_base.C:824
virtual const Node * query_node_ptr(const dof_id_type i) const =0

References libMesh::MeshBase::_node_integer_names, libMesh::MeshBase::add_elem(), libMesh::DofObject::add_extra_integers(), libMesh::MeshBase::add_point(), libMesh::BoundaryInfo::add_side(), libMesh::as_range(), libMesh::BoundaryInfo::boundary_ids(), libMesh::MeshBase::clear(), libMesh::MeshBase::delete_remote_elements(), libMesh::MeshBase::get_boundary_info(), libMesh::MeshBase::is_serial(), libMesh::libmesh_assert(), libMesh::MeshBase::merge_extra_integer_names(), libMesh::MeshBase::n_elem(), libMesh::MeshBase::n_nodes(), libMesh::MeshBase::node_ptr(), libMesh::MeshBase::prepare_for_use(), libMesh::MeshBase::query_node_ptr(), libMesh::DofObject::set_extra_integer(), libMesh::Elem::set_node(), and libMesh::DofObject::set_unique_id().

Referenced by libMesh::UnstructuredMesh::create_pid_mesh().

◆ DECLARE_ELEM_ITERATORS() [1/20]

libMesh::DistributedMesh::DECLARE_ELEM_ITERATORS ( )
inherited

Elem and Node iterator accessor functions.

See MeshBase for documentation.

◆ DECLARE_ELEM_ITERATORS() [2/20]

libMesh::DistributedMesh::DECLARE_ELEM_ITERATORS ( active_  )
inherited

◆ DECLARE_ELEM_ITERATORS() [3/20]

processor_id_type pid unsigned int level libMesh::DistributedMesh::DECLARE_ELEM_ITERATORS ( active_local_subdomain_  ,
subdomain_id_type  sid,
sid   
)
inherited

◆ DECLARE_ELEM_ITERATORS() [4/20]

libMesh::DistributedMesh::DECLARE_ELEM_ITERATORS ( active_not_local_  )
inherited

◆ DECLARE_ELEM_ITERATORS() [5/20]

processor_id_type pid unsigned int level std::set< subdomain_id_type > ss libMesh::DistributedMesh::DECLARE_ELEM_ITERATORS ( active_semilocal_  )
inherited

◆ DECLARE_ELEM_ITERATORS() [6/20]

unsigned int level ElemType type libMesh::DistributedMesh::DECLARE_ELEM_ITERATORS ( active_subdomain_  ,
subdomain_id_type  sid,
sid   
)
inherited

◆ DECLARE_ELEM_ITERATORS() [7/20]

libMesh::DistributedMesh::DECLARE_ELEM_ITERATORS ( active_type_  ,
ElemType  type,
type   
)
inherited

◆ DECLARE_ELEM_ITERATORS() [8/20]

libMesh::DistributedMesh::DECLARE_ELEM_ITERATORS ( ancestor_  )
inherited

◆ DECLARE_ELEM_ITERATORS() [9/20]

libMesh::DistributedMesh::DECLARE_ELEM_ITERATORS ( facelocal_  )
inherited

◆ DECLARE_ELEM_ITERATORS() [10/20]

processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num unsigned char rflag libMesh::DistributedMesh::DECLARE_ELEM_ITERATORS ( flagged_pid_  ,
unsigned char rflag LIBMESH_COMMA processor_id_type  pid,
rflag LIBMESH_COMMA  pid 
)
inherited

◆ DECLARE_ELEM_ITERATORS() [11/20]

libMesh::DistributedMesh::DECLARE_ELEM_ITERATORS ( local_  )
inherited

◆ DECLARE_ELEM_ITERATORS() [12/20]

processor_id_type pid libMesh::DistributedMesh::DECLARE_ELEM_ITERATORS ( local_level_  ,
unsigned int  level,
level   
)
inherited

◆ DECLARE_ELEM_ITERATORS() [13/20]

processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num libMesh::DistributedMesh::DECLARE_ELEM_ITERATORS ( multi_evaluable_  ,
std::vector< const DofMap * >  dof_maps,
dof_maps   
)
inherited

◆ DECLARE_ELEM_ITERATORS() [14/20]

libMesh::DistributedMesh::DECLARE_ELEM_ITERATORS ( not_active_  )
inherited

◆ DECLARE_ELEM_ITERATORS() [15/20]

libMesh::DistributedMesh::DECLARE_ELEM_ITERATORS ( not_ancestor_  )
inherited

◆ DECLARE_ELEM_ITERATORS() [16/20]

libMesh::DistributedMesh::DECLARE_ELEM_ITERATORS ( not_level_  ,
unsigned int  level,
level   
)
inherited

◆ DECLARE_ELEM_ITERATORS() [17/20]

libMesh::DistributedMesh::DECLARE_ELEM_ITERATORS ( not_local_  )
inherited

◆ DECLARE_ELEM_ITERATORS() [18/20]

libMesh::DistributedMesh::DECLARE_ELEM_ITERATORS ( not_subactive_  )
inherited

◆ DECLARE_ELEM_ITERATORS() [19/20]

unsigned int level libMesh::DistributedMesh::DECLARE_ELEM_ITERATORS ( pid_  ,
processor_id_type  pid,
pid   
)
inherited

◆ DECLARE_ELEM_ITERATORS() [20/20]

processor_id_type pid unsigned int level std::set< subdomain_id_type > ss libMesh::DistributedMesh::DECLARE_ELEM_ITERATORS ( semilocal_  )
inherited

◆ DECLARE_NODE_ITERATORS() [1/3]

processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num unsigned char rflag libMesh::DistributedMesh::DECLARE_NODE_ITERATORS ( active_  )
inherited

◆ DECLARE_NODE_ITERATORS() [2/3]

processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num unsigned char rflag processor_id_type pid libMesh::DistributedMesh::DECLARE_NODE_ITERATORS ( bid_  ,
boundary_id_type  bid,
bid   
)
inherited

◆ DECLARE_NODE_ITERATORS() [3/3]

processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num unsigned char rflag libMesh::DistributedMesh::DECLARE_NODE_ITERATORS ( bnd_  )
inherited

◆ default_ghosting()

GhostingFunctor & libMesh::MeshBase::default_ghosting ( )
inlineinherited

Default ghosting functor.

Definition at line 1488 of file mesh_base.h.

1488{ return *_default_ghosting; }
std::unique_ptr< GhostingFunctor > _default_ghosting
The default geometric GhostingFunctor, used to implement standard libMesh element ghosting behavior.
Definition mesh_base.h:2427

References libMesh::MeshBase::_default_ghosting.

◆ default_mapping_data()

unsigned char libMesh::MeshBase::default_mapping_data ( ) const
inlineinherited

Returns any default data value used by the master space to physical space mapping.

Definition at line 956 of file mesh_base.h.

957 {
959 }
unsigned char _default_mapping_data
The default mapping data (unused with Lagrange, used for nodal weight lookup index with rational base...
Definition mesh_base.h:2202

References libMesh::MeshBase::_default_mapping_data.

Referenced by libMesh::DistributedMesh::add_elem(), libMesh::ReplicatedMesh::add_elem(), MeshInputTest::helperTestingDynaQuad(), libMesh::DistributedMesh::insert_elem(), libMesh::ReplicatedMesh::insert_elem(), libMesh::VTKIO::nodes_to_vtk(), AllRBBTest::test_box(), and MeshInputTest::testDynaReadPatch().

◆ default_mapping_type()

ElemMappingType libMesh::MeshBase::default_mapping_type ( ) const
inlineinherited

Returns the default master space to physical space mapping basis functions to be used on newly added elements.

Definition at line 938 of file mesh_base.h.

939 {
941 }
ElemMappingType _default_mapping_type
The default mapping type (typically Lagrange) between master and physical space to assign to newly ad...
Definition mesh_base.h:2195

References libMesh::MeshBase::_default_mapping_type.

Referenced by libMesh::DistributedMesh::add_elem(), libMesh::ReplicatedMesh::add_elem(), libMesh::VTKIO::cells_to_vtk(), MeshInputTest::helperTestingDynaQuad(), libMesh::DistributedMesh::insert_elem(), libMesh::ReplicatedMesh::insert_elem(), libMesh::VTKIO::nodes_to_vtk(), libMesh::VTKIO::read(), MeshInputTest::testDynaFileMappings(), MeshInputTest::testDynaReadPatch(), and MeshInputTest::testExodusFileMappings().

◆ delete_elem()

void libMesh::DistributedMesh::delete_elem ( Elem *  e)
finaloverridevirtualinherited

Removes element 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::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.

Implements libMesh::MeshBase.

Definition at line 783 of file distributed_mesh.C.

784{
785 libmesh_assert (e);
786
787 // Try to make the cached elem data more accurate
788 _n_elem--;
789
790 // Was this a coarse element, not just a coarsening where we still
791 // have some ancestor structure? Was it a *local* element, that we
792 // might have been depending on as an owner of local nodes? We'll
793 // have to be more careful with our nodes in contract() later; no
794 // telling if we just locally orphaned a node that should be
795 // globally retained.
796 if (e->processor_id() == this->processor_id() &&
797 !e->parent())
799
800 // Delete the element from the BoundaryInfo object
801 this->get_boundary_info().remove(e);
802
803 // But not yet from the container; we might invalidate
804 // an iterator that way!
805
806 //_elements.erase(e->id());
807
808 // Instead, we set it to nullptr for now
809
810 _elements[e->id()] = nullptr;
811
812 // delete the element
813 delete e;
814
815 // Some of our caches might still be valid, but we should clear the
816 // ones which definitely are not.
817 this->clear_point_locator();
818 this->clear_stored_ranges();
819}
void remove(const Node *node)
Removes the boundary conditions associated with node node, if any exist.

References libMesh::DistributedMesh::_deleted_coarse_elements, libMesh::DistributedMesh::_elements, libMesh::DistributedMesh::_n_elem, libMesh::MeshBase::clear_point_locator(), libMesh::MeshBase::clear_stored_ranges(), libMesh::MeshBase::get_boundary_info(), libMesh::DofObject::id(), libMesh::libmesh_assert(), libMesh::Elem::parent(), libMesh::DofObject::processor_id(), and libMesh::BoundaryInfo::remove().

Referenced by libMesh::DistributedMesh::insert_elem().

◆ delete_node()

void libMesh::DistributedMesh::delete_node ( Node *  n)
finaloverridevirtualinherited

Removes the Node n from the mesh.

Implements libMesh::MeshBase.

Definition at line 996 of file distributed_mesh.C.

997{
999 libmesh_assert(_nodes[n->id()]);
1000
1001 // Try to make the cached elem data more accurate
1002 _n_nodes--;
1003
1004 // Delete the node from the BoundaryInfo object
1005 this->get_boundary_info().remove(n);
1006 _constraint_rows.erase(n);
1007
1008 // But not yet from the container; we might invalidate
1009 // an iterator that way!
1010
1011 //_nodes.erase(n->id());
1012
1013 // Instead, we set it to nullptr for now
1014
1015 _nodes[n->id()] = nullptr;
1016
1017 // delete the node
1018 delete n;
1019}

References libMesh::MeshBase::_constraint_rows, libMesh::DistributedMesh::_n_nodes, libMesh::DistributedMesh::_nodes, libMesh::MeshBase::get_boundary_info(), libMesh::DofObject::id(), libMesh::libmesh_assert(), and libMesh::BoundaryInfo::remove().

◆ delete_remote_elements()

void libMesh::DistributedMesh::delete_remote_elements ( )
overridevirtualinherited

Deletes all nonlocal elements of the mesh except for "ghosts" which touch a local element, and deletes all nodes which are not part of a local or ghost element.

Reimplemented from libMesh::MeshBase.

Definition at line 1800 of file distributed_mesh.C.

1801{
1802#ifdef DEBUG
1803 // Make sure our neighbor links are all fine
1805
1806 // And our child/parent links, and our flags
1808
1809 // Make sure our ids and flags are consistent
1812
1813 libmesh_assert_equal_to (this->n_nodes(), this->parallel_n_nodes());
1814 libmesh_assert_equal_to (this->n_elem(), this->parallel_n_elem());
1815 const dof_id_type pmax_node_id = this->parallel_max_node_id();
1816 const dof_id_type pmax_elem_id = this->parallel_max_elem_id();
1817 libmesh_assert_equal_to (this->max_node_id(), pmax_node_id);
1818 libmesh_assert_equal_to (this->max_elem_id(), pmax_elem_id);
1819#endif
1820
1821 _is_serial = false;
1822 _is_serial_on_proc_0 = false;
1823
1824 MeshCommunication().delete_remote_elements(*this, _extra_ghost_elems);
1825
1826 libmesh_assert_equal_to (this->max_elem_id(), this->parallel_max_elem_id());
1827
1828 // Now make sure the containers actually shrink - strip
1829 // any newly-created nullptr voids out of the element array
1830 dofobject_container<Elem>::veclike_iterator e_it = _elements.begin();
1831 const dofobject_container<Elem>::veclike_iterator e_end = _elements.end();
1832 while (e_it != e_end)
1833 if (!*e_it)
1834 e_it = _elements.erase(e_it);
1835 else
1836 ++e_it;
1837
1838 dofobject_container<Node>::veclike_iterator n_it = _nodes.begin();
1839 const dofobject_container<Node>::veclike_iterator n_end = _nodes.end();
1840 while (n_it != n_end)
1841 if (!*n_it)
1842 n_it = _nodes.erase(n_it);
1843 else
1844 ++n_it;
1845
1846 // We may have deleted no-longer-connected nodes or coarsened-away
1847 // elements; let's update our caches.
1849
1850 // We may have deleted nodes or elements that were the only local
1851 // representatives of some particular boundary id(s); let's update
1852 // those caches.
1854
1855#ifdef DEBUG
1856 // We might not have well-packed objects if the user didn't allow us
1857 // to renumber
1858 // libmesh_assert_equal_to (this->n_nodes(), this->max_node_id());
1859 // libmesh_assert_equal_to (this->n_elem(), this->max_elem_id());
1860
1861 // Make sure our neighbor links are all fine
1863
1864 // And our child/parent links, and our flags
1866
1867 // Make sure our ids and flags are consistent
1870#endif
1871
1873}
virtual void update_parallel_id_counts() override
Updates parallel caches so that methods like n_elem() accurately reflect changes on other processors.
void libmesh_assert_valid_refinement_tree(const MeshBase &mesh)
A function for verifying that elements on this processor have valid descendants and consistent active...

References libMesh::DistributedMesh::_elements, libMesh::DistributedMesh::_extra_ghost_elems, libMesh::DistributedMesh::_is_serial, libMesh::DistributedMesh::_is_serial_on_proc_0, libMesh::DistributedMesh::_nodes, libMesh::MeshBase::_preparation, libMesh::MeshCommunication::delete_remote_elements(), libMesh::MeshBase::get_boundary_info(), libMesh::MeshBase::Preparation::has_removed_remote_elements, libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_flags(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_ids(), libMesh::MeshTools::libmesh_assert_valid_refinement_tree(), libMesh::DistributedMesh::max_elem_id(), libMesh::DistributedMesh::max_node_id(), libMesh::DistributedMesh::n_elem(), libMesh::DistributedMesh::n_nodes(), libMesh::DistributedMesh::parallel_max_elem_id(), libMesh::DistributedMesh::parallel_max_node_id(), libMesh::DistributedMesh::parallel_n_elem(), libMesh::DistributedMesh::parallel_n_nodes(), libMesh::BoundaryInfo::regenerate_id_sets(), and libMesh::DistributedMesh::update_parallel_id_counts().

◆ detect_interior_parents()

void libMesh::MeshBase::detect_interior_parents ( )
inherited

Search the mesh for elements that have a neighboring element of dim+1 and set that element as the interior parent.

Definition at line 2092 of file mesh_base.C.

2093{
2094 LOG_SCOPE("detect_interior_parents()", "MeshBase");
2095
2096 // This requires an inspection on every processor
2097 parallel_object_only();
2098
2099 // This requires up-to-date mesh dimensions, but if we don't have
2100 // them cached then we can't update them without changing the mesh
2101 // in unexpected ways that interfere with our tests of
2102 // partially-prepared meshes in MeshTools::*valid_is_prepared
2103 std::set<unsigned char> elem_dims_copy;
2105 elem_dims_copy = this->elem_dimensions();
2106 else
2107 {
2108 for (const auto & elem : this->active_element_ptr_range())
2109 elem_dims_copy.insert(cast_int<unsigned char>(elem->dim()));
2110 if (!this->is_serial())
2111 this->comm().set_union(elem_dims_copy);
2112 }
2113
2114 // Early return if the mesh is empty or has elements of a single spatial dimension.
2115 if (elem_dims_copy.size() <= 1)
2116 {
2118 return;
2119 }
2120
2121 // Convenient elem_dimensions iterators
2122 const auto dim_start = elem_dims_copy.begin();
2123 const auto dim_end = elem_dims_copy.end();
2124
2125 // In this function we find only +1 dimensional interior parents,
2126 // (so, for a given element el, the interior parent p must satisfy p.dim() == el.dim() + 1).
2127 // Therefore, we can avoid checking the existence of interior parents
2128 // for all those elements el such there there is no p with p.dim() == el.dim() + 1.
2129 // We store whether to skip any given dimension in the construction of interior parents
2130 // inside the vector in dimensions_to_skip_for_interior_parents.
2131 std::vector<bool> skip_dimension_for_interior_parents(/*count=*/LIBMESH_DIM+1, /*value=*/false);
2132 skip_dimension_for_interior_parents.back() = true;
2133
2134 // Moreover, in the following, we will build a node-to-elem map.
2135 // It is among the elems of this map that we will look for interior parents.
2136 // Therefore, we can skip all elems p such that there is no el with el.dim() == p.dim() - 1.
2137 // We store whether to skip any given dimension in the construction of the node-to-elem map
2138 // in the vector skip_dimensions_for_node_to_el_map.
2139 std::vector<bool> skip_dimensions_for_node_to_el_map(/*count=*/LIBMESH_DIM+1, /*value=*/false);
2140 skip_dimensions_for_node_to_el_map[*dim_start] = true;
2141
2142 // We also create a flag to know if all dimensions should be skipped,
2143 // and if we should therefore return early.
2144 bool skip_all_dimensions = true;
2145
2146 // Fill dimensions_to_skip_for_interior_parents and dimensions_to_skip_for_node_to_el_map.
2147 for (auto [it, next] = std::make_tuple(dim_start, std::next(dim_start));
2148 next != dim_end; ++it, ++next)
2149 {
2150 if (*it + 1 != *next) // if sequential dimensions differ by exactly 1
2151 {
2152 skip_dimension_for_interior_parents[*it] = true;
2153 skip_dimensions_for_node_to_el_map[*next] = true;
2154 }
2155 else if (!skip_dimension_for_interior_parents[*it])
2156 skip_all_dimensions = false;
2157 }
2158
2159 // There is nothing to do if all dimensions should be
2160 // skipped. Before returning, we must also set the flag that says
2161 // "interior parent pointers have been set up" even though we
2162 // determined there was no work to be done.
2163 if (skip_all_dimensions)
2164 {
2166 return;
2167 }
2168
2169 // Do we have interior parent pointers going to a different mesh?
2170 // If so then we'll still check to make sure that's the only place
2171 // they go, so we can libmesh_not_implemented() if not.
2172 const bool separate_interior_mesh = (&(this->interior_mesh()) != this);
2173
2174 // This map will be used to set interior parents
2175 std::unordered_map<dof_id_type, std::vector<dof_id_type>> node_to_elem;
2176
2177 for (const auto & elem : this->element_ptr_range())
2178 {
2179 // Ignore element if it cannot be interior parent of any other elem.
2180 if (skip_dimensions_for_node_to_el_map[elem->dim()])
2181 continue;
2182
2183 // Populating the node_to_elem map, same as MeshTools::build_nodes_to_elem_map
2184 for (auto n : make_range(elem->n_vertices()))
2185 {
2186 libmesh_assert_less (elem->id(), this->max_elem_id());
2187
2188 node_to_elem[elem->node_id(n)].push_back(elem->id());
2189 }
2190 }
2191
2192 // Automatically set interior parents
2193 for (const auto & element : this->element_ptr_range())
2194 {
2195 // Ignore elements with dimensions to skip
2196 // or elements that already have an interior parent.
2197 if (skip_dimension_for_interior_parents[element->dim()] || element->interior_parent())
2198 continue;
2199
2200 // Start by generating sets of dim+1 dimensional elements that
2201 // touch each vertex of the current element. If we encounter a
2202 // vertex not connected to _any_ dim+1 dimensional elements,
2203 // then we can exit the loop without checking the remaining
2204 // vertices since an interior parent (if it exists) will be
2205 // connected to all vertices of the current element.
2206 std::vector<std::set<dof_id_type>> neighbors( element->n_vertices() );
2207
2208 bool found_interior_parents = true;
2209
2210 for (auto n : make_range(element->n_vertices()))
2211 {
2212 auto it = node_to_elem.find(element->node_id(n));
2213
2214 // Check at first that this node is not isolated.
2215 if (it == node_to_elem.end())
2216 {
2217 found_interior_parents = false;
2218 break; // out of n-loop
2219 }
2220
2221 for (const auto & vertex_neighbor_id : it->second)
2222 if (this->elem_ref(vertex_neighbor_id).dim() == element->dim()+1)
2223 neighbors[n].insert(vertex_neighbor_id);
2224
2225 if (neighbors[n].empty())
2226 {
2227 // We have found an empty set for one vertex, no reason
2228 // to continue.
2229 found_interior_parents = false;
2230 break; // out of n-loop
2231 }
2232 }
2233
2234 // If we have generated a non-empty set of elements for each
2235 // vertex, we will now look for a vertex_neighbor_id that
2236 // appears in _all_ of those sets. If found, this is our interior
2237 // parent id. If multiple such common ids are found, we will
2238 // take the lowest such id to be the interior parent id.
2239 if (found_interior_parents)
2240 {
2241 std::set<dof_id_type> & neighbors_0 = neighbors[0];
2242 for (const auto & interior_parent_id : neighbors_0)
2243 {
2244 found_interior_parents = false;
2245 for (auto n : make_range(1u, element->n_vertices()))
2246 {
2247 if (neighbors[n].count(interior_parent_id))
2248 {
2249 found_interior_parents = true;
2250 }
2251 else
2252 {
2253 found_interior_parents = false;
2254 break;
2255 }
2256 }
2257
2258 if (found_interior_parents)
2259 {
2260 element->set_interior_parent(this->elem_ptr(interior_parent_id));
2261 break;
2262 }
2263 }
2264
2265 // Do we have a mixed dimensional mesh that contains some of
2266 // its own interior parents, but we already expect to have
2267 // interior parents on a different mesh? That's going to
2268 // take some work to support if anyone needs it.
2269 if (separate_interior_mesh)
2270 libmesh_not_implemented_msg
2271 ("interior_parent() values in multiple meshes are unsupported.");
2272 }
2273 }
2274
2275 // This flag doesn't necessarily mean any Elems actually have
2276 // interior parent pointers, just that we did all the work to
2277 // determine whether or not they do.
2279}
const std::set< unsigned char > & elem_dimensions() const
Definition mesh_base.h:2650
virtual const Elem & elem_ref(const dof_id_type i) const
Definition mesh_base.h:785
Tnew cast_int(Told oldvar)

References libMesh::MeshBase::_preparation, libMesh::ParallelObject::comm(), libMesh::Elem::dim(), libMesh::MeshBase::elem_dimensions(), libMesh::MeshBase::elem_ptr(), libMesh::MeshBase::elem_ref(), libMesh::MeshBase::Preparation::has_cached_elem_data, libMesh::MeshBase::Preparation::has_interior_parent_ptrs, libMesh::MeshBase::interior_mesh(), libMesh::MeshBase::is_serial(), libMesh::make_range(), and libMesh::Parallel::Communicator::set_union().

Referenced by libMesh::MeshBase::complete_preparation().

◆ elem_default_orders()

const std::set< Order > & libMesh::MeshBase::elem_default_orders ( ) const
inlineinherited
Returns
A const reference to a std::set of element default orders present in the mesh.

Definition at line 2658 of file mesh_base.h.

References libMesh::MeshBase::_elem_default_orders, libMesh::MeshBase::_preparation, libMesh::MeshBase::Preparation::has_cached_elem_data, and libMesh::libmesh_assert().

Referenced by MeshSmootherTest::testVariationalSmoother().

◆ elem_dimensions()

const std::set< unsigned char > & libMesh::MeshBase::elem_dimensions ( ) const
inlineinherited

◆ elem_ptr() [1/2]

const Elem * libMesh::DistributedMesh::elem_ptr ( const dof_id_type  i) const
finaloverridevirtualinherited
Returns
A pointer to the \( i^{th} \) element, which should be present in this processor's subset of the mesh data structure.

Implements libMesh::MeshBase.

Definition at line 540 of file distributed_mesh.C.

541{
543 libmesh_assert_equal_to (_elements[i]->id(), i);
544
545 return _elements[i];
546}

References libMesh::DistributedMesh::_elements, and libMesh::libmesh_assert().

Referenced by libMesh::DistributedMesh::fix_broken_node_and_element_numbering().

◆ elem_ptr() [2/2]

Elem * libMesh::DistributedMesh::elem_ptr ( const dof_id_type  i)
finaloverridevirtualinherited
Returns
A writable pointer to the \( i^{th} \) element, which should be present in this processor's subset of the mesh data structure.

Implements libMesh::MeshBase.

Definition at line 551 of file distributed_mesh.C.

552{
554 libmesh_assert_equal_to (_elements[i]->id(), i);
555
556 return _elements[i];
557}

References libMesh::DistributedMesh::_elements, and libMesh::libmesh_assert().

◆ elem_ref() [1/2]

virtual Elem & libMesh::MeshBase::elem_ref ( const dof_id_type  i)
inlinevirtualinherited
Returns
A writable reference to the \( i^{th} \) element, which should be present in this processor's subset of the mesh data structure.

Definition at line 795 of file mesh_base.h.

796 {
797 return *this->elem_ptr(i);
798 }

References libMesh::MeshBase::elem_ptr().

◆ elem_ref() [2/2]

virtual const Elem & libMesh::MeshBase::elem_ref ( const dof_id_type  i) const
inlinevirtualinherited
Returns
A reference to the \( i^{th} \) element, which should be present in this processor's subset of the mesh data structure.

Definition at line 785 of file mesh_base.h.

786 {
787 return *this->elem_ptr(i);
788 }

References libMesh::MeshBase::elem_ptr().

Referenced by GhostDofConstraintPartitioner::_do_partition(), libMesh::SyncSubdomainIds::act_on_data(), libMesh::SyncElementIntegers::act_on_data(), libMesh::SyncRefinementFlags::act_on_data(), libMesh::AbaqusIO::assign_sideset_ids(), libMesh::AbaqusIO::assign_subdomain_ids(), libMesh::Nemesis_IO_Helper::build_element_and_node_maps(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::BoundaryInfo::build_side_list_from_node_list(), libMesh::Nemesis_IO_Helper::compute_num_global_sidesets(), libMesh::MeshBase::detect_interior_parents(), libMesh::RBEIMConstruction::enrich_eim_approximation_on_interiors(), libMesh::RBEIMConstruction::enrich_eim_approximation_on_sides(), libMesh::SyncSubdomainIds::gather_data(), libMesh::SyncElementIntegers::gather_data(), libMesh::SyncRefinementFlags::gather_data(), libMesh::MeshTetInterface::improve_hull_integrity(), main(), MeshPerElemTest< elem_type >::meshes_equal_enough(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::ProjectVertices::operator()(), libMesh::RBParametrizedFunction::preevaluate_parametrized_function_on_mesh(), libMesh::RBParametrizedFunction::preevaluate_parametrized_function_on_mesh_sides(), libMesh::ExodusII_IO::read(), libMesh::CheckpointIO::read_remote_elem(), SystemsTest::testDofCouplingWithVarGroups(), MeshExtruderTest::testExtruder(), DofMapTest::testGhostConstraintSendList(), SystemsTest::testSetSystemParameterOverEquationSystem(), libMesh::FroIO::write(), libMesh::ExodusII_IO_Helper::write_elements(), libMesh::Nemesis_IO_Helper::write_elements(), libMesh::GmshIO::write_mesh(), and libMesh::ExodusII_IO_Helper::write_sidesets().

◆ element_stored_range()

const ElemRange & libMesh::MeshBase::element_stored_range ( )
inherited
Returns
A reference to a cached vector copy of a range of pointers to all semilocal elements, suitable for threading.

Iterating over all semilocal elements is most useful for modifying the mesh, so we only have a non-const version for now.

Definition at line 1954 of file mesh_base.C.

1955{
1957 {
1958 // Range construction may not be safe within threads
1960
1962 std::make_unique<ElemRange>(this->elements_begin(),
1963 this->elements_end());
1964 }
1965
1966 return *_element_stored_range;
1967}

References libMesh::MeshBase::_element_stored_range, libMesh::Threads::in_threads, and libMesh::libmesh_assert().

Referenced by libMesh::EquationSystems::allgather(), libMesh::MeshBase::change_elemset_code(), libMesh::MeshTools::Modification::change_subdomain_id(), libMesh::UnstructuredMesh::copy_nodes_and_elements(), libMesh::UnstructuredMesh::find_neighbors(), libMesh::EquationSystems::reinit_mesh(), libMesh::EquationSystems::reinit_solutions(), and libMesh::MeshBase::size_elem_extra_integers().

◆ extra_ghost_elems()

const std::set< Elem * > & libMesh::DistributedMesh::extra_ghost_elems ( ) const
inlineinherited

Const accessor to the ghosted elements.

Definition at line 267 of file distributed_mesh.h.

267{ return _extra_ghost_elems; }

References libMesh::DistributedMesh::_extra_ghost_elems.

Referenced by libMesh::DistributedMesh::clear_extra_ghost_elems().

◆ find_neighbors()

void libMesh::UnstructuredMesh::find_neighbors ( const bool  reset_remote_elements = false,
const bool  reset_current_list = true,
const bool  assert_valid = true,
const bool  check_non_remote = true 
)
overridevirtualinherited

Other functions from MeshBase requiring re-definition.

Here we look at all of the child elements which don't already have valid neighbors.

If a child element has a nullptr neighbor it is either because it is on the boundary or because its neighbor is at a different level. In the latter case we must get the neighbor from the parent.

If a child element has a remote_elem neighbor on a boundary it shares with its parent, that info may have become out-dated through coarsening of the neighbor's parent. In this case, if the parent's neighbor is active then the child should share it.

Furthermore, that neighbor better be active, otherwise we missed a child somewhere.

We also need to look through children ordered by increasing refinement level in order to add new interior_parent() links in boundary elements which have just been generated by refinement, and fix links in boundary elements whose previous interior_parent() has just been coarsened away.

Implements libMesh::MeshBase.

Definition at line 999 of file unstructured_mesh.C.

1003{
1004 // We might actually want to run this on an empty mesh
1005 // (e.g. the boundary mesh for a nonexistent bcid!)
1006 // libmesh_assert_not_equal_to (this->n_nodes(), 0);
1007 // libmesh_assert_not_equal_to (this->n_elem(), 0);
1008
1009 // This function must be run on all processors at once
1010 parallel_object_only();
1011
1012 LOG_SCOPE("find_neighbors()", "Mesh");
1013
1014 //TODO:[BSK] This should be removed later?!
1015 if (reset_current_list)
1017 (this->element_stored_range(),
1018 [reset_remote_elements](const ElemRange & range)
1019 {
1020 for (Elem * e : range)
1021 for (auto s : e->side_index_range())
1022 if (e->neighbor_ptr(s) != remote_elem || reset_remote_elements)
1023 e->set_neighbor(s, nullptr);
1024 });
1025
1026 // Find neighboring elements by first finding elements
1027 // with identical side keys and then check to see if they
1028 // are neighbors
1029 {
1030 // data structures -- Use the hash_multimap if available
1031 typedef dof_id_type key_type;
1032 typedef std::pair<Elem *, unsigned char> val_type;
1033 typedef std::unordered_multimap<key_type, val_type> map_type;
1034
1035 // A map from side keys to corresponding elements & side numbers
1036 map_type side_to_elem_map;
1037
1038 // Pull objects out of the loop to reduce heap operations
1039 std::unique_ptr<Elem> my_side, their_side;
1040
1041 for (const auto & element : this->element_ptr_range())
1042 {
1043 for (auto ms : element->side_index_range())
1044 {
1045 next_side:
1046 // If we haven't yet found a neighbor on this side, try.
1047 // Even if we think our neighbor is remote, that
1048 // information may be out of date.
1049 //
1050 // If we're only checking remote neighbors, after a
1051 // redistribution, then we'll skip the non-remote ones
1052 if ((element->neighbor_ptr(ms) == nullptr && check_non_remote) ||
1053 element->neighbor_ptr(ms) == remote_elem)
1054 {
1055 // Get the key for the side of this element. Use the
1056 // low_order_key so we can find neighbors in
1057 // mixed-order meshes if necessary.
1058 const dof_id_type key = element->low_order_key(ms);
1059
1060 // Look for elements that have an identical side key
1061 auto bounds = side_to_elem_map.equal_range(key);
1062
1063 // May be multiple keys, check all the possible
1064 // elements which _might_ be neighbors.
1065 if (bounds.first != bounds.second)
1066 {
1067 // Get the side for this element
1068 element->side_ptr(my_side, ms);
1069
1070 // Look at all the entries with an equivalent key
1071 while (bounds.first != bounds.second)
1072 {
1073 // Get the potential element
1074 Elem * neighbor = bounds.first->second.first;
1075
1076 // Get the side for the neighboring element
1077 const unsigned int ns = bounds.first->second.second;
1078 neighbor->side_ptr(their_side, ns);
1079 //libmesh_assert(my_side.get());
1080 //libmesh_assert(their_side.get());
1081
1082 // If found a match with my side
1083 //
1084 // In 1D, since parents and children have an
1085 // equal side (i.e. a node) we need to check
1086 // for matching level() to avoid setting our
1087 // neighbor pointer to any of our neighbor's
1088 // descendants.
1089 if (sides_are_the_same_elem(*my_side, *their_side) &&
1090 (element->level() == neighbor->level()))
1091 {
1092 // So share a side. Is this a mixed pair
1093 // of subactive and active/ancestor
1094 // elements?
1095 // If not, then we're neighbors.
1096 // If so, then the subactive's neighbor is
1097
1098 if (element->subactive() ==
1099 neighbor->subactive())
1100 {
1101 // an element is only subactive if it has
1102 // been coarsened but not deleted
1103 element->set_neighbor (ms,neighbor);
1104 neighbor->set_neighbor(ns,element);
1105 }
1106 else if (element->subactive())
1107 {
1108 element->set_neighbor(ms,neighbor);
1109 }
1110 else if (neighbor->subactive())
1111 {
1112 neighbor->set_neighbor(ns,element);
1113 }
1114 side_to_elem_map.erase (bounds.first);
1115
1116 // get out of this nested crap
1117 goto next_side;
1118 }
1119
1120 ++bounds.first;
1121 }
1122 }
1123
1124 // didn't find a match...
1125 // Build the map entry for this element
1126 side_to_elem_map.emplace
1127 (key, std::make_pair(element, cast_int<unsigned char>(ms)));
1128 }
1129 }
1130 }
1131 }
1132
1133#ifdef LIBMESH_ENABLE_PERIODIC
1134 // Get the disjoint neighbor boundary pairs object (from periodic BCs)
1135 auto * db = this->get_disjoint_neighbor_boundary_pairs();
1136
1137 if (db)
1138 {
1139 // Obtain a point locator
1140 std::unique_ptr<PointLocatorBase> point_locator = this->sub_point_locator();
1141
1142 for (const auto & element : this->element_ptr_range())
1143 {
1144 for (auto ms : element->side_index_range())
1145 {
1146 // Skip if this side already has a valid neighbor (including remote neighbors)
1147 if (element->neighbor_ptr(ms) != nullptr &&
1148 element->neighbor_ptr(ms) != remote_elem)
1149 continue;
1150
1151 for (const auto & [id, boundary_ptr] : *db)
1152 {
1153 if (!this->get_boundary_info().has_boundary_id(element, ms, id))
1154 continue;
1155
1156 unsigned int neigh_side;
1157 const Elem * neigh =
1158 db->neighbor(id, *point_locator, element, ms, &neigh_side);
1159
1160 if (neigh && neigh != remote_elem && neigh != element)
1161 {
1162 auto neigh_changeable = this->elem_ptr(neigh->id());
1163 element->set_neighbor(ms, neigh_changeable);
1164 neigh_changeable->set_neighbor(neigh_side, element);
1165 }
1166 }
1167 }
1168 }
1169 }
1170#endif // LIBMESH_ENABLE_PERIODIC
1171
1172#ifdef LIBMESH_ENABLE_AMR
1173
1201 const unsigned int n_levels = MeshTools::n_levels(*this);
1202 for (unsigned int level = 1; level < n_levels; ++level)
1203 {
1204 for (auto & current_elem : as_range(level_elements_begin(level),
1205 level_elements_end(level)))
1206 {
1207 libmesh_assert(current_elem);
1208 Elem * parent = current_elem->parent();
1209 libmesh_assert(parent);
1210 const unsigned int my_child_num = parent->which_child_am_i(current_elem);
1211
1212 for (auto s : current_elem->side_index_range())
1213 {
1214 if (current_elem->neighbor_ptr(s) == nullptr ||
1215 (current_elem->neighbor_ptr(s) == remote_elem &&
1216 parent->is_child_on_side(my_child_num, s)))
1217 {
1218 Elem * neigh = parent->neighbor_ptr(s);
1219
1220 // If neigh was refined and had non-subactive children
1221 // made remote earlier, then our current elem should
1222 // actually have one of those remote children as a
1223 // neighbor
1224 if (neigh &&
1225 (neigh->ancestor() ||
1226 // If neigh has subactive children which should have
1227 // matched as neighbors of the current element but
1228 // did not, then those likewise must be remote
1229 // children.
1230 (current_elem->subactive() && neigh->has_children() &&
1231 (neigh->level()+1) == current_elem->level())))
1232 {
1233#ifdef DEBUG
1234 // Let's make sure that "had children made remote"
1235 // situation is actually the case
1236 libmesh_assert(neigh->has_children());
1237 bool neigh_has_remote_children = false;
1238 for (auto & child : neigh->child_ref_range())
1239 if (&child == remote_elem)
1240 neigh_has_remote_children = true;
1241 libmesh_assert(neigh_has_remote_children);
1242
1243 // And let's double-check that we don't have
1244 // a remote_elem neighboring an active local element
1245 if (current_elem->active())
1246 libmesh_assert_not_equal_to (current_elem->processor_id(),
1247 this->processor_id());
1248#endif // DEBUG
1249 neigh = const_cast<RemoteElem *>(remote_elem);
1250 }
1251 // If neigh and current_elem are more than one level
1252 // apart, figuring out whether we have a remote
1253 // neighbor here becomes much harder.
1254 else if (neigh && (current_elem->subactive() &&
1255 neigh->has_children()))
1256 {
1257 // Find the deepest descendant of neigh which
1258 // we could consider for a neighbor. If we run
1259 // out of neigh children, then that's our
1260 // neighbor. If we find a potential neighbor
1261 // with remote_children and we don't find any
1262 // potential neighbors among its non-remote
1263 // children, then our neighbor must be remote.
1264 while (neigh != remote_elem &&
1265 neigh->has_children())
1266 {
1267 bool found_neigh = false;
1268 for (unsigned int c = 0, nc = neigh->n_children();
1269 !found_neigh && c != nc; ++c)
1270 {
1271 Elem * child = neigh->child_ptr(c);
1272 if (child == remote_elem)
1273 continue;
1274 for (auto ncn : child->neighbor_ptr_range())
1275 {
1276 if (ncn != remote_elem &&
1277 ncn->is_ancestor_of(current_elem))
1278 {
1279 neigh = ncn;
1280 found_neigh = true;
1281 break;
1282 }
1283 }
1284 }
1285 if (!found_neigh)
1286 neigh = const_cast<RemoteElem *>(remote_elem);
1287 }
1288 }
1289 current_elem->set_neighbor(s, neigh);
1290#ifdef DEBUG
1291 if (neigh != nullptr && neigh != remote_elem)
1292 // We ignore subactive elements here because
1293 // we don't care about neighbors of subactive element.
1294 if ((!neigh->active()) && (!current_elem->subactive()))
1295 {
1296 libMesh::err << "On processor " << this->processor_id()
1297 << std::endl;
1298 libMesh::err << "Bad element ID = " << current_elem->id()
1299 << ", Side " << s << ", Bad neighbor ID = " << neigh->id() << std::endl;
1300 libMesh::err << "Bad element proc_ID = " << current_elem->processor_id()
1301 << ", Bad neighbor proc_ID = " << neigh->processor_id() << std::endl;
1302 libMesh::err << "Bad element size = " << current_elem->hmin()
1303 << ", Bad neighbor size = " << neigh->hmin() << std::endl;
1304 libMesh::err << "Bad element center = " << current_elem->vertex_average()
1305 << ", Bad neighbor center = " << neigh->vertex_average() << std::endl;
1306 libMesh::err << "ERROR: "
1307 << (current_elem->active()?"Active":"Ancestor")
1308 << " Element at level "
1309 << current_elem->level() << std::endl;
1310 libMesh::err << "with "
1311 << (parent->active()?"active":
1312 (parent->subactive()?"subactive":"ancestor"))
1313 << " parent share "
1314 << (neigh->subactive()?"subactive":"ancestor")
1315 << " neighbor at level " << neigh->level()
1316 << std::endl;
1317 NameBasedIO(*this).write ("bad_mesh.gmv");
1318 libmesh_error_msg("Problematic mesh written to bad_mesh.gmv.");
1319 }
1320#endif // DEBUG
1321 }
1322 }
1323
1324 // We can skip to the next element if we're full-dimension
1325 // and therefore don't have any interior parents
1326 if (current_elem->dim() >= LIBMESH_DIM)
1327 continue;
1328
1329 // We have no interior parents unless we can find one later
1330 current_elem->set_interior_parent(nullptr);
1331
1332 Elem * pip = parent->interior_parent();
1333
1334 if (!pip)
1335 continue;
1336
1337 // If there's no interior_parent children, whether due to a
1338 // remote element or a non-conformity, then there's no
1339 // children to search.
1340 if (pip == remote_elem || pip->active())
1341 {
1342 current_elem->set_interior_parent(pip);
1343 continue;
1344 }
1345
1346 // For node comparisons we'll need a sensible tolerance
1347 Real node_tolerance = current_elem->hmin() * TOLERANCE;
1348
1349 // Otherwise our interior_parent should be a child of our
1350 // parent's interior_parent.
1351 for (auto & child : pip->child_ref_range())
1352 {
1353 // If we have a remote_elem, that might be our
1354 // interior_parent. We'll set it provisionally now and
1355 // keep trying to find something better.
1356 if (&child == remote_elem)
1357 {
1358 current_elem->set_interior_parent
1359 (const_cast<RemoteElem *>(remote_elem));
1360 continue;
1361 }
1362
1363 bool child_contains_our_nodes = true;
1364 for (auto & n : current_elem->node_ref_range())
1365 {
1366 bool child_contains_this_node = false;
1367 for (auto & cn : child.node_ref_range())
1369 (n, node_tolerance))
1370 {
1371 child_contains_this_node = true;
1372 break;
1373 }
1374 if (!child_contains_this_node)
1375 {
1376 child_contains_our_nodes = false;
1377 break;
1378 }
1379 }
1380 if (child_contains_our_nodes)
1381 {
1382 current_elem->set_interior_parent(&child);
1383 break;
1384 }
1385 }
1386
1387 // We should have found *some* interior_parent at this
1388 // point, whether semilocal or remote.
1389 libmesh_assert(current_elem->interior_parent());
1390 }
1391 }
1392#endif // AMR
1393
1394#ifdef DEBUG
1395 if (assert_valid)
1396 {
1398 !reset_remote_elements);
1400 }
1401#else
1402 libmesh_ignore(assert_valid);
1403#endif
1404
1405 this->_preparation.has_neighbor_ptrs = true;
1406}
processor_id_type processor_id() const
Definition dof_object.h:895
virtual bool is_child_on_side(const unsigned int c, const unsigned int s) const =0
bool active() const
Definition elem.h:3079
bool is_ancestor_of(const Elem *descendant) const
Definition elem.h:3147
bool has_children() const
Definition elem.h:3117
virtual std::unique_ptr< Elem > side_ptr(unsigned int i)=0
bool ancestor() const
Definition elem.C:2121
void set_interior_parent(Elem *p)
Sets the pointer to the element's interior_parent.
Definition elem.C:1162
unsigned int which_child_am_i(const Elem *e) const
Definition elem.h:3330
virtual Real hmin() const
Definition elem.C:623
unsigned int level() const
Definition elem.h:3212
virtual unsigned int n_children() const =0
const Elem * interior_parent() const
Definition elem.C:1100
bool subactive() const
Definition elem.h:3097
Point vertex_average() const
Definition elem.C:609
PeriodicBoundaries * get_disjoint_neighbor_boundary_pairs()
Definition mesh_base.C:2311
std::unique_ptr< PointLocatorBase > sub_point_locator() const
Definition mesh_base.C:1848
This class supports simple reads and writes in any libMesh-supported format, by dispatching to one of...
virtual void write(const std::string &mesh_file) override
This method implements writing a mesh to a specified file.
void libmesh_assert_valid_amr_interior_parents(const MeshBase &mesh)
A function for verifying that any interior_parent pointers on elements are consistent with AMR (paren...
unsigned int n_levels(const MeshBase &mesh)
Definition mesh_tools.C:826
OStreamProxy err
bool absolute_fuzzy_equals(const T &var1, const T2 &var2, const Real tol=TOLERANCE *TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
void libmesh_ignore(const Args &...)

References libMesh::MeshBase::_preparation, libMesh::Elem::active(), libMesh::Elem::ancestor(), libMesh::as_range(), libMesh::Elem::child_ptr(), libMesh::Elem::child_ref_range(), libMesh::MeshBase::elem_ptr(), libMesh::MeshBase::element_stored_range(), libMesh::err, libMesh::MeshBase::get_boundary_info(), libMesh::MeshBase::get_disjoint_neighbor_boundary_pairs(), libMesh::BoundaryInfo::has_boundary_id(), libMesh::Elem::has_children(), libMesh::MeshBase::Preparation::has_neighbor_ptrs, libMesh::Elem::hmin(), libMesh::DofObject::id(), libMesh::Elem::interior_parent(), libMesh::Elem::is_ancestor_of(), libMesh::Elem::is_child_on_side(), libMesh::Elem::level(), libMesh::libmesh_assert(), libMesh::MeshTools::libmesh_assert_valid_amr_interior_parents(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::libmesh_ignore(), libMesh::Elem::n_children(), libMesh::MeshTools::n_levels(), libMesh::Elem::neighbor_ptr(), libMesh::Elem::neighbor_ptr_range(), libMesh::Threads::parallel_for(), libMesh::Elem::parent(), libMesh::DofObject::processor_id(), libMesh::ParallelObject::processor_id(), libMesh::Real, libMesh::remote_elem, libMesh::Elem::set_interior_parent(), libMesh::Elem::set_neighbor(), libMesh::Elem::side_ptr(), libMesh::MeshBase::sub_point_locator(), libMesh::Elem::subactive(), libMesh::TOLERANCE, libMesh::Elem::vertex_average(), libMesh::Elem::which_child_am_i(), and libMesh::NameBasedIO::write().

Referenced by libMesh::TriangleWrapper::copy_tri_to_mesh(), libMesh::MeshTetInterface::improve_hull_integrity(), libMesh::Poly2TriTriangulator::insert_refinement_points(), libMesh::DistributedMesh::redistribute(), libMesh::UnstructuredMesh::stitching_helper(), libMesh::NetGenMeshInterface::triangulate(), and libMesh::TriangleInterface::triangulate().

◆ fix_broken_node_and_element_numbering()

void libMesh::DistributedMesh::fix_broken_node_and_element_numbering ( )
overridevirtualinherited

There is no reason for a user to ever call this function.

This function restores a previously broken element/node numbering such that mesh.node_ref(n).id() == n.

Implements libMesh::MeshBase.

Definition at line 1745 of file distributed_mesh.C.

1746{
1747 // We can't use range-for here because we need access to the special
1748 // iterators' methods, not just to their dereferenced values.
1749
1750 // Nodes first
1751 for (auto pr = this->_nodes.begin(),
1752 end = this->_nodes.end(); pr != end; ++pr)
1753 {
1754 Node * n = *pr;
1755 if (n != nullptr)
1756 {
1757 const dof_id_type id = pr.index();
1758 n->set_id() = id;
1759 libmesh_assert_equal_to(this->node_ptr(id), n);
1760 }
1761 }
1762
1763 // Elements next
1764 for (auto pr = this->_elements.begin(),
1765 end = this->_elements.end(); pr != end; ++pr)
1766 {
1767 Elem * e = *pr;
1768 if (e != nullptr)
1769 {
1770 const dof_id_type id = pr.index();
1771 e->set_id() = id;
1772 libmesh_assert_equal_to(this->elem_ptr(id), e);
1773 }
1774 }
1775}
virtual const Elem * elem_ptr(const dof_id_type i) const override final
virtual const Node * node_ptr(const dof_id_type i) const override final

References libMesh::DistributedMesh::_elements, libMesh::DistributedMesh::_nodes, libMesh::DistributedMesh::elem_ptr(), libMesh::DistributedMesh::node_ptr(), and libMesh::DofObject::set_id().

◆ gather_to_zero()

void libMesh::DistributedMesh::gather_to_zero ( )
overridevirtualinherited

Gathers all elements and nodes of the mesh onto processor zero.

Reimplemented from libMesh::MeshBase.

Definition at line 1927 of file distributed_mesh.C.

1928{
1930 return;
1931
1932 _is_serial_on_proc_0 = true;
1933 MeshCommunication().gather(0, *this);
1934}

References libMesh::DistributedMesh::_is_serial_on_proc_0, and libMesh::MeshCommunication::gather().

◆ get_boundary_info() [1/2]

BoundaryInfo & libMesh::MeshBase::get_boundary_info ( )
inlineinherited

Writable information about boundary ids on the mesh.

Definition at line 175 of file mesh_base.h.

175{ return *boundary_info; }
std::unique_ptr< BoundaryInfo > boundary_info
This class holds the boundary information.
Definition mesh_base.h:2143

References libMesh::MeshBase::boundary_info.

◆ get_boundary_info() [2/2]

const BoundaryInfo & libMesh::MeshBase::get_boundary_info ( ) const
inlineinherited

The information about boundary ids on the mesh.

Definition at line 170 of file mesh_base.h.

170{ return *boundary_info; }

References libMesh::MeshBase::boundary_info.

Referenced by libMesh::MeshTools::Subdivision::add_boundary_ghosts(), libMesh::UnstructuredMesh::all_first_order(), libMesh::MeshTools::Subdivision::all_subdivision(), libMesh::MeshTools::Modification::all_tri(), LinearElasticity::assemble(), assemble_elasticity(), assemble_poisson(), assemble_shell(), assemble_temperature_jump(), libMesh::AbaqusIO::assign_boundary_node_ids(), libMesh::AbaqusIO::assign_sideset_ids(), AssemblyF0::boundary_assembly(), AssemblyF1::boundary_assembly(), AssemblyF2::boundary_assembly(), AssemblyA0::boundary_assembly(), AssemblyA1::boundary_assembly(), AssemblyA2::boundary_assembly(), libMesh::MeshTools::Generation::build_cube(), libMesh::MeshTools::Generation::build_delaunay_square(), libMesh::MeshTools::Generation::build_extrusion(), DisjointNeighborTest::build_four_disjoint_elems(), DisjointNeighborTest::build_split_mesh_with_interface(), DisjointNeighborTest::build_two_disjoint_elems(), libMesh::MeshTools::Modification::change_boundary_id(), libMesh::DofMap::check_dirichlet_bcid_consistency(), libMesh::MeshBase::complete_preparation(), libMesh::Nemesis_IO_Helper::compute_num_global_nodesets(), libMesh::Nemesis_IO_Helper::compute_num_global_sidesets(), libMesh::FEGenericBase< OutputType >::compute_periodic_constraints(), libMesh::TriangleWrapper::copy_tri_to_mesh(), libMesh::UnstructuredMesh::create_submesh(), libMesh::MeshTetInterface::delete_2D_hull_elements(), libMesh::DistributedMesh::delete_elem(), libMesh::ReplicatedMesh::delete_elem(), libMesh::DistributedMesh::delete_node(), libMesh::ReplicatedMesh::delete_node(), libMesh::DistributedMesh::delete_remote_elements(), libMesh::DistributedMesh::DistributedMesh(), libMesh::UnstructuredMesh::find_neighbors(), libMesh::MeshTools::Modification::flatten(), libMesh::MeshBase::get_info(), AssemblyPointLoadX::get_nodal_rhs_values(), AssemblyPointLoadY::get_nodal_rhs_values(), AssemblyPointLoadZ::get_nodal_rhs_values(), libMesh::UNVIO::groups_in(), libMesh::MeshTetInterface::improve_hull_integrity(), libMesh::HDGProblem::init(), ElasticitySystem::init_data(), libMesh::ExodusII_IO_Helper::initialize(), LinearElasticityWithContact::initialize_contact_load_paths(), libMesh::Poly2TriTriangulator::insert_refinement_points(), libMesh::MeshTools::Modification::interpolate_surface(), libMesh::HDGProblem::jacobian(), libMesh::MeshTools::libmesh_assert_valid_boundary_ids(), main(), AugmentSparsityOnInterface::mesh_reinit(), libMesh::TriangulatorInterface::MeshedHole::MeshedHole(), libMesh::PeriodicBoundaries::neighbor(), libMesh::MeshTools::Modification::orient_elements(), libMesh::TetGenMeshInterface::pointset_convexhull(), libMesh::Nemesis_IO::prepare_to_write_nodal_data(), libMesh::Nemesis_IO::read(), libMesh::AbaqusIO::read(), libMesh::ExodusII_IO::read(), libMesh::CheckpointIO::read_bcs(), libMesh::ExodusII_IO_Helper::read_edge_blocks(), libMesh::CheckpointIO::read_header(), libMesh::GmshIO::read_mesh(), libMesh::CheckpointIO::read_nodesets(), libMesh::XdrIO::read_serialized_bcs_helper(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::SimplexRefiner::refine_via_edges(), MeshStitchTest::renameAndShift(), libMesh::DistributedMesh::renumber_nodes_and_elements(), libMesh::ReplicatedMesh::renumber_nodes_and_elements(), libMesh::ReplicatedMesh::ReplicatedMesh(), libMesh::HDGProblem::residual(), libMesh::RBEIMEvaluation::side_distribute_bfs(), libMesh::PetscDiffSolver::solve(), libMesh::UnstructuredMesh::stitching_helper(), libMesh::MeshTools::Generation::surface_octahedron(), libMesh::BoundaryInfo::sync(), AllTriTest::test_helper(), AllTriTest::test_helper_c0polyhedron(), ExodusC0PolyhedronTest::test_write_cube_header(), AllTriTest::testAllTriC0Polygon(), AllTriTest::testAllTriC0PolygonOctagon(), MeshTetTest::testBcids(), BoundaryInfoTest::testBoundaryIDs(), BoundaryInfoTest::testBoundaryOnChildrenBoundaryIDs(), BoundaryInfoTest::testBoundaryOnChildrenBoundarySides(), BoundaryInfoTest::testBoundaryOnChildrenElementsRefineCoarsen(), BoundaryInfoTest::testBoundaryOnChildrenErrors(), SystemsTest::testBoundaryProjectCube(), BoundaryInfoTest::testBuildNodeListFromSideList(), BoundaryInfoTest::testBuildSideListFromNodeList(), BoundaryInfoTest::testBuildSideListFromNodeListDistributedMesh(), BoundaryInfoTest::testBuildSideListFromNodeListThinMesh(), VolumeTest::testC0PolygonMethods(), BoundaryMeshSubdomainTest::testDefaultSubdomain(), DisjointNeighborTest::testDisjointNeighborConflictError(), CheckpointIOTest::testDisjointNeighborPairsCheckpoint(), BoundaryInfoTest::testEdgeBoundaryConditions(), MeshInputTest::testExodusIGASidesets(), MeshInputTest::testGmshBCIDOverlap(), BoundaryInfoTest::testInternalBoundary(), MeshInputTest::testLowOrderEdgeBlocks(), BoundaryInfoTest::testMesh(), BoundaryInfoTest::testNameCopying(), BoundaryMeshSubdomainTest::testPerBoundarySubdomain(), PeriodicBCTest::testPeriodicBC(), MeshTriangulationTest::testPoly2TriHolesInteriorRefinedBase(), BoundaryInfoTest::testRenumber(), BoundaryInfoTest::testSelectiveRenumber(), BoundaryInfoTest::testShellFaceConstraints(), BoundaryMeshSubdomainTest::testSingleSubdomain(), DisjointNeighborTest::testStitchCrossMesh(), MeshTetTest::testTrisToTets(), MeshSmootherTest::testVariationalSmoother(), WriteEdgesetData::testWriteImpl(), WriteNodesetData::testWriteImpl(), WriteSidesetData::testWriteImpl(), libMesh::NetGenMeshInterface::triangulate(), libMesh::Poly2TriTriangulator::triangulate_current_points(), libMesh::Parallel::Packing< Elem * >::unpack(), libMesh::Parallel::Packing< Node * >::unpack(), libMesh::MeshTetInterface::volume_to_surface_mesh(), libMesh::FroIO::write(), libMesh::XdrIO::write(), libMesh::Nemesis_IO::write(), libMesh::ExodusII_IO::write(), libMesh::CheckpointIO::write(), libMesh::ExodusII_IO_Helper::write_elements(), libMesh::GmshIO::write_mesh(), libMesh::ExodusII_IO_Helper::write_nodesets(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::XdrIO::write_serialized_nodesets(), and libMesh::ExodusII_IO_Helper::write_sidesets().

◆ get_constraint_rows() [1/2]

constraint_rows_type & libMesh::MeshBase::get_constraint_rows ( )
inlineinherited

◆ get_constraint_rows() [2/2]

const constraint_rows_type & libMesh::MeshBase::get_constraint_rows ( ) const
inlineinherited

Definition at line 1944 of file mesh_base.h.

1945 { return _constraint_rows; }

References libMesh::MeshBase::_constraint_rows.

◆ get_count_lower_dim_elems_in_point_locator()

bool libMesh::MeshBase::get_count_lower_dim_elems_in_point_locator ( ) const
inherited

Get the current value of _count_lower_dim_elems_in_point_locator.

Definition at line 1895 of file mesh_base.C.

1896{
1898}
bool _count_lower_dim_elems_in_point_locator
Do we count lower dimensional elements in point locator refinement? This is relevant in tree-based po...
Definition mesh_base.h:2243

References libMesh::MeshBase::_count_lower_dim_elems_in_point_locator.

Referenced by libMesh::TreeNode< N >::insert().

◆ get_disjoint_neighbor_boundary_pairs() [1/2]

PeriodicBoundaries * libMesh::MeshBase::get_disjoint_neighbor_boundary_pairs ( )
inherited

◆ get_disjoint_neighbor_boundary_pairs() [2/2]

const PeriodicBoundaries * libMesh::MeshBase::get_disjoint_neighbor_boundary_pairs ( ) const
inherited

Definition at line 2316 of file mesh_base.C.

2317 {
2319 }

References libMesh::MeshBase::_disjoint_neighbor_boundary_pairs.

◆ get_elem_integer_index()

unsigned int libMesh::MeshBase::get_elem_integer_index ( std::string_view  name) const
inherited

Definition at line 689 of file mesh_base.C.

690{
691 for (auto i : index_range(_elem_integer_names))
693 return i;
694
695 libmesh_error_msg("Unknown elem integer " << name);
697}
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition libmesh.h:303

References libMesh::MeshBase::_elem_integer_names, libMesh::index_range(), and libMesh::invalid_uint.

Referenced by libMesh::MeshBase::change_elemset_code(), WriteElemsetData::checkElemsetCodes(), ExtraIntegersTest::testExtraIntegersExodusReading(), and libMesh::ExodusII_IO_Helper::write_elemsets().

◆ get_elem_integer_name()

const std::string & libMesh::MeshBase::get_elem_integer_name ( unsigned int  i) const
inlineinherited

Definition at line 1083 of file mesh_base.h.

1084 { return _elem_integer_names[i]; }

References libMesh::MeshBase::_elem_integer_names.

Referenced by libMesh::XdrIO::write(), and libMesh::CheckpointIO::write().

◆ get_elemset_code()

dof_id_type libMesh::MeshBase::get_elemset_code ( const MeshBase::elemset_type &  id_set) const
inherited

Definition at line 502 of file mesh_base.C.

503{
504 auto it = _elemset_codes_inverse_map.find(id_set);
505 return (it == _elemset_codes_inverse_map.end()) ? DofObject::invalid_id : it->second;
506}

References libMesh::MeshBase::_elemset_codes_inverse_map, and libMesh::DofObject::invalid_id.

Referenced by WriteElemsetData::checkElemsetCodes(), and libMesh::ExodusII_IO::read().

◆ get_elemset_codes()

std::vector< dof_id_type > libMesh::MeshBase::get_elemset_codes ( ) const
inherited

Return a vector of all elemset codes defined on the mesh.

We get this by looping over the _elemset_codes map.

Definition at line 508 of file mesh_base.C.

509{
510 std::vector<dof_id_type> ret;
511 ret.reserve(_elemset_codes.size());
512 for (const auto & pr : _elemset_codes)
513 ret.push_back(pr.first);
514 return ret;
515}

References libMesh::MeshBase::_elemset_codes.

Referenced by libMesh::UnstructuredMesh::stitching_helper(), and libMesh::XdrIO::write().

◆ get_elemsets()

void libMesh::MeshBase::get_elemsets ( dof_id_type  elemset_code,
MeshBase::elemset_type &  id_set_to_fill 
) const
inherited

Look up the element sets for a given elemset code and vice-versa.

The elemset must have been previously stored by calling add_elemset_code(). If no such code/set is found, returns the empty set or DofObject::invalid_id, respectively.

Definition at line 492 of file mesh_base.C.

493{
494 // If we don't recognize this elemset_code, hand back an empty set
495 id_set_to_fill.clear();
496
497 if (const auto it = _elemset_codes.find(elemset_code);
498 it != _elemset_codes.end())
499 id_set_to_fill.insert(it->second->begin(), it->second->end());
500}

References libMesh::MeshBase::_elemset_codes.

Referenced by libMesh::UnstructuredMesh::stitching_helper(), WriteElemsetData::testWriteImpl(), libMesh::XdrIO::write(), and libMesh::ExodusII_IO_Helper::write_elemsets().

◆ get_id_by_name()

subdomain_id_type libMesh::MeshBase::get_id_by_name ( std::string_view  name) const
inherited
Returns
The id of the named subdomain if it exists, Elem::invalid_subdomain_id otherwise.

Definition at line 1941 of file mesh_base.C.

1942{
1943 // Linear search over the map values.
1944 for (const auto & [sbd_id, sbd_name] : _block_id_to_name)
1945 if (sbd_name == name)
1946 return sbd_id;
1947
1948 // If we made it here without returning, we don't have a subdomain
1949 // with the requested name, so return Elem::invalid_subdomain_id.
1951}
static constexpr subdomain_id_type invalid_subdomain_id
A static integral constant representing an invalid subdomain id.
Definition elem.h:246
std::map< subdomain_id_type, std::string > _block_id_to_name
This structure maintains the mapping of named blocks for file formats that support named blocks.
Definition mesh_base.h:2320

References libMesh::MeshBase::_block_id_to_name, and libMesh::Elem::invalid_subdomain_id.

◆ get_info()

std::string libMesh::MeshBase::get_info ( const unsigned int  verbosity = 0,
const bool  global = true 
) const
inherited
Returns
A string containing relevant information about the mesh.

verbosity sets the verbosity, with 0 being the least and 2 being the greatest. 0 - Dimensions, number of nodes, number of elems, number of subdomains, number of partitions, prepared status. 1 - Adds the mesh bounding box, mesh element types, specific nodesets/edgesets/sidesets with element types, number of nodes/edges/sides. 2 - Adds volume information and bounding boxes to boundary information.

The global parameter pertains primarily to verbosity levels 1 and above. When global == true, information is only output on rank 0 and the information is reduced. When global == false, information is output on all ranks that pertains only to that local partition.

Definition at line 1276 of file mesh_base.C.

1277{
1278 std::ostringstream oss;
1279
1280 oss << " Mesh Information:" << '\n';
1281
1282 if (!_elem_dims.empty())
1283 {
1284 oss << " elem_dimensions()={";
1285 std::copy(_elem_dims.begin(),
1286 --_elem_dims.end(), // --end() is valid if the set is non-empty
1287 std::ostream_iterator<unsigned int>(oss, ", "));
1288 oss << cast_int<unsigned int>(*_elem_dims.rbegin());
1289 oss << "}";
1290 if (!this->preparation().has_cached_elem_data)
1291 oss << " (may be out of date)";
1292 oss << '\n';
1293 }
1294
1295 if (!_elem_default_orders.empty())
1296 {
1297 oss << " elem_default_orders()={";
1298 std::transform(_elem_default_orders.begin(),
1299 --_elem_default_orders.end(),
1300 std::ostream_iterator<std::string>(oss, ", "),
1301 [](Order o)
1302 { return Utility::enum_to_string<Order>(o); });
1303 oss << Utility::enum_to_string<Order>(*_elem_default_orders.rbegin());
1304 oss << "}";
1305 if (!this->preparation().has_cached_elem_data)
1306 oss << " (may be out of date)";
1307 oss << '\n';
1308 }
1309
1310 oss << " supported_nodal_order()=" << this->_supported_nodal_order;
1311 if (!this->preparation().has_cached_elem_data)
1312 oss << " (may be out of date)";
1313 oss << '\n';
1314
1315 oss << " spatial_dimension()=" << int(this->_spatial_dimension);
1316 if (!this->preparation().has_cached_elem_data)
1317 oss << " (may be out of date)";
1318 oss << '\n';
1319
1320 oss << " n_nodes()=" << this->n_nodes() << '\n'
1321 << " n_local_nodes()=" << this->n_local_nodes() << '\n'
1322 << " n_elem()=" << this->n_elem() << '\n'
1323 << " n_local_elem()=" << this->n_local_elem() << '\n';
1324#ifdef LIBMESH_ENABLE_AMR
1325 oss << " n_active_elem()=" << this->n_active_elem() << '\n';
1326#endif
1327 if (global)
1328 oss << " n_subdomains()=" << static_cast<std::size_t>(this->n_subdomains()) << '\n';
1329 else
1330 oss << " n_local_subdomains()= " << static_cast<std::size_t>(this->n_local_subdomains()) << '\n';
1331 oss << " n_elemsets()=" << static_cast<std::size_t>(this->n_elemsets()) << '\n';
1332 if (!_elemset_codes.empty())
1333 oss << " n_elemset_codes=" << _elemset_codes.size() << '\n';
1334 oss << " n_partitions()=" << static_cast<std::size_t>(this->n_partitions()) << '\n'
1335 << " n_processors()=" << static_cast<std::size_t>(this->n_processors()) << '\n'
1336 << " n_threads()=" << static_cast<std::size_t>(libMesh::n_threads()) << '\n'
1337 << " processor_id()=" << static_cast<std::size_t>(this->processor_id()) << '\n'
1338 << " is_prepared()=" << (this->is_prepared() ? "true" : "false") << '\n'
1339 << " is_replicated()=" << (this->is_replicated() ? "true" : "false") << '\n';
1340
1341 if (verbosity > 0)
1342 {
1343 if (global)
1344 {
1345 libmesh_parallel_only(this->comm());
1346 if (this->processor_id() != 0)
1347 oss << "\n Detailed global get_info() (verbosity > 0) is reduced and output to only rank 0.";
1348 }
1349
1350 // Helper for printing element types
1351 const auto elem_type_helper = [](const std::set<int> & elem_types) {
1352 std::stringstream ss;
1353 for (auto it = elem_types.begin(); it != elem_types.end();)
1354 {
1356 if (++it != elem_types.end())
1357 ss << ", ";
1358 }
1359 return ss.str();
1360 };
1361
1362 // Helper for whether or not the given DofObject is to be included. If we're doing
1363 // a global reduction, we also count unpartitioned objects on rank 0.
1364 const auto include_object = [this, &global](const DofObject & dof_object) {
1365 return this->processor_id() == dof_object.processor_id() ||
1366 (global &&
1367 this->processor_id() == 0 &&
1368 dof_object.processor_id() == DofObject::invalid_processor_id);
1369 };
1370
1371 Real volume = 0;
1372
1373 // Add bounding box information
1374 const auto bbox = global ? MeshTools::create_bounding_box(*this) : MeshTools::create_local_bounding_box(*this);
1375 if (!global || this->processor_id() == 0)
1376 oss << "\n " << (global ? "" : "Local ") << "Mesh Bounding Box:\n"
1377 << " Minimum: " << bbox.min() << "\n"
1378 << " Maximum: " << bbox.max() << "\n"
1379 << " Delta: " << (bbox.max() - bbox.min()) << "\n";
1380
1381 // Obtain the global or local element types
1382 std::set<int> elem_types;
1383 for (const Elem * elem : this->active_local_element_ptr_range())
1384 elem_types.insert(elem->type());
1385 if (global)
1386 {
1387 // Pick up unpartitioned elems on rank 0
1388 if (this->processor_id() == 0)
1389 for (const Elem * elem : this->active_unpartitioned_element_ptr_range())
1390 elem_types.insert(elem->type());
1391
1392 this->comm().set_union(elem_types);
1393 }
1394
1395 // Add element types
1396 if (!global || this->processor_id() == 0)
1397 oss << "\n " << (global ? "" : "Local ") << "Mesh Element Type(s):\n "
1398 << elem_type_helper(elem_types) << "\n";
1399
1400 // Reduce the nodeset ids
1401 auto nodeset_ids = this->get_boundary_info().get_node_boundary_ids();
1402 if (global)
1403 this->comm().set_union(nodeset_ids);
1404
1405 // Accumulate local information for each nodeset
1406 struct NodesetInfo
1407 {
1408 std::size_t num_nodes = 0;
1409 BoundingBox bbox;
1410 };
1411 std::map<boundary_id_type, NodesetInfo> nodeset_info_map;
1412 for (const auto & [node, id] : this->get_boundary_info().get_nodeset_map())
1413 {
1414 if (!include_object(*node))
1415 continue;
1416
1417 NodesetInfo & info = nodeset_info_map[id];
1418
1419 ++info.num_nodes;
1420
1421 if (verbosity > 1)
1422 info.bbox.union_with(*node);
1423 }
1424
1425 // Add nodeset info
1426 if (!global || this->processor_id() == 0)
1427 {
1428 oss << "\n " << (global ? "" : "Local ") << "Mesh Nodesets:\n";
1429 if (nodeset_ids.empty())
1430 oss << " None\n";
1431 }
1432
1433 const auto & nodeset_name_map = this->get_boundary_info().get_nodeset_name_map();
1434 for (const auto id : nodeset_ids)
1435 {
1436 NodesetInfo & info = nodeset_info_map[id];
1437
1438 // Reduce the local information for this nodeset if required
1439 if (global)
1440 {
1441 this->comm().sum(info.num_nodes);
1442 if (verbosity > 1)
1443 {
1444 this->comm().min(info.bbox.min());
1445 this->comm().max(info.bbox.max());
1446 }
1447 }
1448
1449 const bool has_name = nodeset_name_map.count(id) && nodeset_name_map.at(id).size();
1450 const std::string name = has_name ? nodeset_name_map.at(id) : "";
1451 if (global)
1452 libmesh_assert(this->comm().verify(name));
1453
1454 if (global ? this->processor_id() == 0 : info.num_nodes > 0)
1455 {
1456 oss << " Nodeset " << id;
1457 if (has_name)
1458 oss << " (" << name << ")";
1459 oss << ", " << info.num_nodes << " " << (global ? "" : "local ") << "nodes\n";
1460
1461 if (verbosity > 1)
1462 {
1463 oss << " " << (global ? "Bounding" : "Local bounding") << " box minimum: "
1464 << info.bbox.min() << "\n"
1465 << " " << (global ? "Bounding" : "Local bounding") << " box maximum: "
1466 << info.bbox.max() << "\n"
1467 << " " << (global ? "Bounding" : "Local bounding") << " box delta: "
1468 << (info.bbox.max() - info.bbox.min()) << "\n";
1469 }
1470 }
1471 }
1472
1473 // Reduce the sideset ids
1474 auto sideset_ids = this->get_boundary_info().get_side_boundary_ids();
1475 if (global)
1476 this->comm().set_union(sideset_ids);
1477
1478 // Accumulate local information for each sideset
1479 struct SidesetInfo
1480 {
1481 std::size_t num_sides = 0;
1482 Real volume = 0;
1483 std::set<int> side_elem_types;
1484 std::set<int> elem_types;
1485 std::set<dof_id_type> elem_ids;
1486 std::set<dof_id_type> node_ids;
1487 BoundingBox bbox;
1488 };
1489 ElemSideBuilder side_builder;
1490 std::map<boundary_id_type, SidesetInfo> sideset_info_map;
1491 for (const auto & pair : this->get_boundary_info().get_sideset_map())
1492 {
1493 const Elem * elem = pair.first;
1494 if (!include_object(*elem))
1495 continue;
1496
1497 const auto id = pair.second.second;
1498 SidesetInfo & info = sideset_info_map[id];
1499
1500 const auto s = pair.second.first;
1501 const Elem & side = side_builder(*elem, s);
1502
1503 ++info.num_sides;
1504 info.side_elem_types.insert(side.type());
1505 info.elem_types.insert(elem->type());
1506 info.elem_ids.insert(elem->id());
1507
1508 for (const Node & node : side.node_ref_range())
1509 if (include_object(node))
1510 info.node_ids.insert(node.id());
1511
1512 if (verbosity > 1)
1513 {
1514 info.volume += side.volume();
1515 info.bbox.union_with(side.loose_bounding_box());
1516 }
1517 }
1518
1519 // Add sideset info
1520 if (!global || this->processor_id() == 0)
1521 {
1522 oss << "\n " << (global ? "" : "Local ") << "Mesh Sidesets:\n";
1523 if (sideset_ids.empty())
1524 oss << " None\n";
1525 }
1526 const auto & sideset_name_map = this->get_boundary_info().get_sideset_name_map();
1527 for (const auto id : sideset_ids)
1528 {
1529 SidesetInfo & info = sideset_info_map[id];
1530
1531 auto num_elems = info.elem_ids.size();
1532 auto num_nodes = info.node_ids.size();
1533
1534 // Reduce the local information for this sideset if required
1535 if (global)
1536 {
1537 this->comm().sum(info.num_sides);
1538 this->comm().set_union(info.side_elem_types, 0);
1539 this->comm().sum(num_elems);
1540 this->comm().set_union(info.elem_types, 0);
1541 this->comm().sum(num_nodes);
1542 if (verbosity > 1)
1543 {
1544 this->comm().sum(info.volume);
1545 this->comm().min(info.bbox.min());
1546 this->comm().max(info.bbox.max());
1547 }
1548 }
1549
1550 const bool has_name = sideset_name_map.count(id) && sideset_name_map.at(id).size();
1551 const std::string name = has_name ? sideset_name_map.at(id) : "";
1552 if (global)
1553 libmesh_assert(this->comm().verify(name));
1554
1555 if (global ? this->processor_id() == 0 : info.num_sides > 0)
1556 {
1557 oss << " Sideset " << id;
1558 if (has_name)
1559 oss << " (" << name << ")";
1560 oss << ", " << info.num_sides << " sides (" << elem_type_helper(info.side_elem_types) << ")"
1561 << ", " << num_elems << " " << (global ? "" : "local ") << "elems (" << elem_type_helper(info.elem_types) << ")"
1562 << ", " << num_nodes << " " << (global ? "" : "local ") << "nodes\n";
1563
1564 if (verbosity > 1)
1565 {
1566 oss << " " << (global ? "Side" : "Local side") << " volume: " << info.volume << "\n"
1567 << " " << (global ? "Bounding" : "Local bounding") << " box minimum: "
1568 << info.bbox.min() << "\n"
1569 << " " << (global ? "Bounding" : "Local bounding") << " box maximum: "
1570 << info.bbox.max() << "\n"
1571 << " " << (global ? "Bounding" : "Local bounding") << " box delta: "
1572 << (info.bbox.max() - info.bbox.min()) << "\n";
1573 }
1574 }
1575 }
1576
1577 // Reduce the edgeset ids
1578 auto edgeset_ids = this->get_boundary_info().get_edge_boundary_ids();
1579 if (global)
1580 this->comm().set_union(edgeset_ids);
1581
1582 // Accumulate local information for each edgeset
1583 struct EdgesetInfo
1584 {
1585 std::size_t num_edges = 0;
1586 std::set<int> edge_elem_types;
1587 BoundingBox bbox;
1588 };
1589 std::map<boundary_id_type, EdgesetInfo> edgeset_info_map;
1590 std::unique_ptr<const Elem> edge;
1591
1592 for (const auto & pair : this->get_boundary_info().get_edgeset_map())
1593 {
1594 const Elem * elem = pair.first;
1595 if (!include_object(*elem))
1596 continue;
1597
1598 const auto id = pair.second.second;
1599 EdgesetInfo & info = edgeset_info_map[id];
1600
1601 elem->build_edge_ptr(edge, pair.second.first);
1602
1603 ++info.num_edges;
1604 info.edge_elem_types.insert(edge->type());
1605
1606 if (verbosity > 1)
1607 info.bbox.union_with(edge->loose_bounding_box());
1608 }
1609
1610 // Add edgeset info
1611 if (!global || this->processor_id() == 0)
1612 {
1613 oss << "\n " << (global ? "" : "Local ") << "Mesh Edgesets:\n";
1614 if (edgeset_ids.empty())
1615 oss << " None\n";
1616 }
1617
1618 const auto & edgeset_name_map = this->get_boundary_info().get_edgeset_name_map();
1619 for (const auto id : edgeset_ids)
1620 {
1621 EdgesetInfo & info = edgeset_info_map[id];
1622
1623 // Reduce the local information for this edgeset if required
1624 if (global)
1625 {
1626 this->comm().sum(info.num_edges);
1627 this->comm().set_union(info.edge_elem_types, 0);
1628 if (verbosity > 1)
1629 {
1630 this->comm().min(info.bbox.min());
1631 this->comm().min(info.bbox.max());
1632 }
1633 }
1634
1635 const bool has_name = edgeset_name_map.count(id) && edgeset_name_map.at(id).size();
1636 const std::string name = has_name ? edgeset_name_map.at(id) : "";
1637 if (global)
1638 libmesh_assert(this->comm().verify(name));
1639
1640 if (global ? this->processor_id() == 0 : info.num_edges > 0)
1641 {
1642 oss << " Edgeset " << id;
1643 if (has_name)
1644 oss << " (" << name << ")";
1645 oss << ", " << info.num_edges << " " << (global ? "" : "local ") << "edges ("
1646 << elem_type_helper(info.edge_elem_types) << ")\n";
1647
1648 if (verbosity > 1)
1649 {
1650 oss << " " << (global ? "Bounding" : "Local bounding") << " box minimum: "
1651 << info.bbox.min() << "\n"
1652 << " " << (global ? "Bounding" : "Local bounding") << " box maximum: "
1653 << info.bbox.max() << "\n"
1654 << " " << (global ? "Bounding" : "Local bounding") << " box delta: "
1655 << (info.bbox.max() - info.bbox.min()) << "\n";
1656 }
1657 }
1658 }
1659
1660 // Reduce the block IDs and block names
1661 std::set<subdomain_id_type> subdomains;
1662 for (const Elem * elem : this->active_element_ptr_range())
1663 if (include_object(*elem))
1664 subdomains.insert(elem->subdomain_id());
1665 if (global)
1666 this->comm().set_union(subdomains);
1667
1668 // Accumulate local information for each subdomain
1669 struct SubdomainInfo
1670 {
1671 std::size_t num_elems = 0;
1672 Real volume = 0;
1673 std::set<int> elem_types;
1674 std::set<dof_id_type> active_node_ids;
1675#ifdef LIBMESH_ENABLE_AMR
1676 std::size_t num_active_elems = 0;
1677#endif
1678 BoundingBox bbox;
1679 };
1680 std::map<subdomain_id_type, SubdomainInfo> subdomain_info_map;
1681 for (const Elem * elem : this->element_ptr_range())
1682 if (include_object(*elem))
1683 {
1684 SubdomainInfo & info = subdomain_info_map[elem->subdomain_id()];
1685
1686 ++info.num_elems;
1687 info.elem_types.insert(elem->type());
1688
1689#ifdef LIBMESH_ENABLE_AMR
1690 if (elem->active())
1691 ++info.num_active_elems;
1692#endif
1693
1694 for (const Node & node : elem->node_ref_range())
1695 if (include_object(node) && node.active())
1696 info.active_node_ids.insert(node.id());
1697
1698 if (verbosity > 1 && elem->active())
1699 {
1700 info.volume += elem->volume();
1701 info.bbox.union_with(elem->loose_bounding_box());
1702 }
1703 }
1704
1705 // Add subdomain info
1706 oss << "\n " << (global ? "" : "Local ") << "Mesh Subdomains:\n";
1707 const auto & subdomain_name_map = this->get_subdomain_name_map();
1708 for (const auto id : subdomains)
1709 {
1710 SubdomainInfo & info = subdomain_info_map[id];
1711
1712 auto num_active_nodes = info.active_node_ids.size();
1713
1714 // Reduce the information for this subdomain if needed
1715 if (global)
1716 {
1717 this->comm().sum(info.num_elems);
1718#ifdef LIBMESH_ENABLE_AMR
1719 this->comm().sum(info.num_active_elems);
1720#endif
1721 this->comm().sum(num_active_nodes);
1722 this->comm().set_union(info.elem_types, 0);
1723 if (verbosity > 1)
1724 {
1725 this->comm().min(info.bbox.min());
1726 this->comm().max(info.bbox.max());
1727 this->comm().sum(info.volume);
1728 }
1729 }
1730 if (verbosity > 1)
1731 volume += info.volume;
1732
1733 const bool has_name = subdomain_name_map.count(id);
1734 const std::string name = has_name ? subdomain_name_map.at(id) : "";
1735 if (global)
1736 libmesh_assert(this->comm().verify(name));
1737
1738 if (!global || this->processor_id() == 0)
1739 {
1740 oss << " Subdomain " << id;
1741 if (has_name)
1742 oss << " (" << name << ")";
1743 oss << ": " << info.num_elems << " " << (global ? "" : "local ") << "elems "
1744 << "(" << elem_type_helper(info.elem_types);
1745#ifdef LIBMESH_ENABLE_AMR
1746 oss << ", " << info.num_active_elems << " active";
1747#endif
1748 oss << "), " << num_active_nodes << " " << (global ? "" : "local ") << "active nodes\n";
1749 if (verbosity > 1)
1750 {
1751 oss << " " << (global ? "Volume" : "Local volume") << ": " << info.volume << "\n";
1752 oss << " " << (global ? "Bounding" : "Local bounding") << " box minimum: "
1753 << info.bbox.min() << "\n"
1754 << " " << (global ? "Bounding" : "Local bounding") << " box maximum: "
1755 << info.bbox.max() << "\n"
1756 << " " << (global ? "Bounding" : "Local bounding") << " box delta: "
1757 << (info.bbox.max() - info.bbox.min()) << "\n";
1758 }
1759 }
1760 }
1761
1762 oss << " " << (global ? "Global" : "Local") << " mesh volume = " << volume << "\n";
1763
1764 }
1765
1766 return oss.str();
1767}
void ErrorVector unsigned int
void max(const T &r, T &o, Request &req) const
const std::set< boundary_id_type > & get_edge_boundary_ids() const
const std::set< boundary_id_type > & get_node_boundary_ids() const
const std::set< boundary_id_type > & get_side_boundary_ids() const
const std::map< boundary_id_type, std::string > & get_edgeset_name_map() const
const std::map< boundary_id_type, std::string > & get_nodeset_name_map() const
const std::map< boundary_id_type, std::string > & get_sideset_name_map() const
const Point & min() const
Preparation preparation() const
Definition mesh_base.h:213
virtual bool is_replicated() const
Definition mesh_base.h:379
const std::map< subdomain_id_type, std::string > & get_subdomain_name_map() const
Definition mesh_base.h:1930
subdomain_id_type n_local_subdomains() const
Definition mesh_base.C:1205
dof_id_type n_local_elem() const
Definition mesh_base.h:694
dof_id_type n_local_nodes() const
Definition mesh_base.h:588
unsigned int n_elemsets() const
Returns the number of unique elemset ids which have been added via add_elemset_code(),...
Definition mesh_base.C:487
virtual dof_id_type n_active_elem() const =0
subdomain_id_type n_subdomains() const
Definition mesh_base.C:1191
MPI_Info info
void elem_types(const MeshBase &mesh, std::vector< ElemType > &et)
Fills in a vector of all element types in the mesh.
Definition mesh_tools.C:723
Real volume(const MeshBase &mesh, unsigned int dim=libMesh::invalid_uint)
Find the total volume of a mesh (interpreting that as area for dim = 2, or total arc length for dim =...
libMesh::BoundingBox create_bounding_box(const MeshBase &mesh)
Definition mesh_tools.C:566
libMesh::BoundingBox create_local_bounding_box(const MeshBase &mesh)
Definition mesh_tools.C:631
std::string enum_to_string(const T e)
unsigned int n_threads()

References libMesh::MeshBase::_elem_default_orders, libMesh::MeshBase::_elem_dims, libMesh::MeshBase::_elemset_codes, libMesh::MeshBase::_spatial_dimension, libMesh::MeshBase::_supported_nodal_order, libMesh::Elem::build_edge_ptr(), libMesh::ParallelObject::comm(), libMesh::MeshTools::create_bounding_box(), libMesh::MeshTools::create_local_bounding_box(), libMesh::Utility::enum_to_string(), libMesh::MeshBase::get_boundary_info(), libMesh::BoundaryInfo::get_edge_boundary_ids(), libMesh::BoundaryInfo::get_edgeset_map(), libMesh::BoundaryInfo::get_edgeset_name_map(), libMesh::BoundaryInfo::get_node_boundary_ids(), libMesh::BoundaryInfo::get_nodeset_map(), libMesh::BoundaryInfo::get_nodeset_name_map(), libMesh::BoundaryInfo::get_side_boundary_ids(), libMesh::BoundaryInfo::get_sideset_map(), libMesh::BoundaryInfo::get_sideset_name_map(), libMesh::MeshBase::get_subdomain_name_map(), libMesh::DofObject::id(), int, libMesh::DofObject::invalid_processor_id, libMesh::MeshBase::is_prepared(), libMesh::MeshBase::is_replicated(), libMesh::libmesh_assert(), libMesh::Elem::loose_bounding_box(), libMesh::Parallel::Communicator::max(), libMesh::Parallel::Communicator::min(), libMesh::MeshBase::n_active_elem(), libMesh::MeshBase::n_elem(), libMesh::MeshBase::n_elemsets(), libMesh::MeshBase::n_local_elem(), libMesh::MeshBase::n_local_nodes(), libMesh::MeshBase::n_local_subdomains(), libMesh::MeshBase::n_nodes(), libMesh::MeshBase::n_partitions(), libMesh::ParallelObject::n_processors(), libMesh::MeshBase::n_subdomains(), libMesh::n_threads(), libMesh::Elem::node_ref_range(), libMesh::MeshBase::preparation(), libMesh::ParallelObject::processor_id(), libMesh::Real, libMesh::Parallel::Communicator::set_union(), libMesh::Parallel::Communicator::sum(), libMesh::Elem::type(), and libMesh::Elem::volume().

Referenced by libMesh::MeshBase::print_info().

◆ get_local_constraints()

std::string libMesh::MeshBase::get_local_constraints ( bool  print_nonlocal = false) const
inherited

Gets a string reporting all mesh constraint rows local to this processor.

If print_nonlocal is true, then nonlocal constraints which are locally known are included.

Definition at line 2831 of file mesh_base.C.

2832{
2833 std::ostringstream os;
2834
2835 if (print_nonlocal)
2836 os << "All ";
2837 else
2838 os << "Local ";
2839
2840 os << "Mesh Constraint Rows:"
2841 << std::endl;
2842
2843 for (const auto & [node, row] : _constraint_rows)
2844 {
2845 const bool local = (node->processor_id() == this->processor_id());
2846
2847 // Skip non-local dofs if requested
2848 if (!print_nonlocal && !local)
2849 continue;
2850
2851 os << "Constraints for " << (local ? "Local" : "Ghost") << " Node " << node->id()
2852 << ": \t";
2853
2854 for (const auto & [elem_and_node, coef] : row)
2855 os << " ((" << elem_and_node.first->id() << ',' << elem_and_node.second << "), " << coef << ")\t";
2856
2857 os << std::endl;
2858 }
2859
2860 return os.str();
2861}
LIBMESH_DEVICE_INLINE ResultVector row(const TensorLike &T_in, const unsigned int row_index)

References libMesh::MeshBase::_constraint_rows, and libMesh::ParallelObject::processor_id().

Referenced by libMesh::MeshBase::print_constraint_rows().

◆ get_mesh_subdomains()

const std::set< subdomain_id_type > & libMesh::MeshBase::get_mesh_subdomains ( ) const
inlineinherited
Returns
The cached mesh subdomains. As long as the mesh is prepared, this should contain all the subdomain ids across processors. Relies on the mesh being prepared

Definition at line 2674 of file mesh_base.h.

References libMesh::MeshBase::_mesh_subdomains, libMesh::MeshBase::_preparation, libMesh::MeshBase::Preparation::has_cached_elem_data, and libMesh::libmesh_assert().

◆ get_node_integer_index()

unsigned int libMesh::MeshBase::get_node_integer_index ( std::string_view  name) const
inherited

Definition at line 778 of file mesh_base.C.

779{
780 for (auto i : index_range(_node_integer_names))
782 return i;
783
784 libmesh_error_msg("Unknown node integer " << name);
786}

References libMesh::MeshBase::_node_integer_names, libMesh::index_range(), and libMesh::invalid_uint.

◆ get_node_integer_name()

const std::string & libMesh::MeshBase::get_node_integer_name ( unsigned int  i) const
inlineinherited

Definition at line 1205 of file mesh_base.h.

1206 { return _node_integer_names[i]; }

References libMesh::MeshBase::_node_integer_names.

Referenced by libMesh::XdrIO::write(), and libMesh::CheckpointIO::write().

◆ get_point_locator_close_to_point_tol()

Real libMesh::MeshBase::get_point_locator_close_to_point_tol ( ) const
inherited

Definition at line 2369 of file mesh_base.C.

2370{
2372}
Real _point_locator_close_to_point_tol
If nonzero, we will call PointLocatorBase::set_close_to_point_tol() on any PointLocators that we crea...
Definition mesh_base.h:2467

References libMesh::MeshBase::_point_locator_close_to_point_tol.

◆ get_subdomain_name_map()

const std::map< subdomain_id_type, std::string > & libMesh::MeshBase::get_subdomain_name_map ( ) const
inlineinherited

◆ ghosting_functors_begin()

GhostingFunctorIterator libMesh::MeshBase::ghosting_functors_begin ( ) const
inlineinherited

◆ ghosting_functors_end()

GhostingFunctorIterator libMesh::MeshBase::ghosting_functors_end ( ) const
inlineinherited

◆ has_elem_integer()

bool libMesh::MeshBase::has_elem_integer ( std::string_view  name) const
inherited

◆ has_node_integer()

bool libMesh::MeshBase::has_node_integer ( std::string_view  name) const
inherited

Definition at line 790 of file mesh_base.C.

791{
792 for (auto & entry : _node_integer_names)
793 if (entry == name)
794 return true;
795
796 return false;
797}

References libMesh::MeshBase::_node_integer_names.

Referenced by ExtraIntegersTest::checkpoint_helper().

◆ insert_elem() [1/2]

Elem * libMesh::DistributedMesh::insert_elem ( Elem *  e)
finaloverridevirtualinherited

Insert elem e to the element array, preserving its id and replacing/deleting any existing element with the same id.

Users should call MeshBase::complete_preparation() after elements are added to and/or deleted from the mesh.

Implements libMesh::MeshBase.

Definition at line 721 of file distributed_mesh.C.

722{
723 if (_elements[e->id()])
724 this->delete_elem(_elements[e->id()]);
725
726#ifdef LIBMESH_ENABLE_UNIQUE_ID
727 if (!e->valid_unique_id())
728 {
729 if (processor_id() == e->processor_id())
730 {
731 e->set_unique_id(_next_unique_id);
732 _next_unique_id += this->n_processors() + 1;
733 }
734 else
735 {
736 e->set_unique_id(_next_unpartitioned_unique_id);
738 }
739 }
740 else
741 {
742 _next_unique_id = std::max(_next_unique_id, e->unique_id()+1);
744 ((_next_unique_id + this->n_processors() - 1) / (this->n_processors() + 1) + 1) *
745 (this->n_processors() + 1) + this->processor_id();
746 }
747#endif
748
749 // Try to make the cached elem data more accurate
750 processor_id_type elem_procid = e->processor_id();
751 if (elem_procid == this->processor_id() ||
752 elem_procid == DofObject::invalid_processor_id)
753 _n_elem++;
754
755 _elements[e->id()] = e;
756
757 // We actually added a new element. Some of our caches might still
758 // be valid, but we should clear the ones which definitely are not.
759 this->clear_point_locator();
760 this->clear_stored_ranges();
761
762 // Make sure any new element is given space for any extra integers
763 // we've requested
764 e->add_extra_integers(_elem_integer_names.size(),
766
767 // And set mapping type and data on any new element
768 e->set_mapping_type(this->default_mapping_type());
769 e->set_mapping_data(this->default_mapping_data());
770
771 return e;
772}
virtual void delete_elem(Elem *e) override final
Removes element e from the mesh.

References libMesh::MeshBase::_elem_integer_default_values, libMesh::MeshBase::_elem_integer_names, libMesh::DistributedMesh::_elements, libMesh::DistributedMesh::_n_elem, libMesh::MeshBase::_next_unique_id, libMesh::DistributedMesh::_next_unpartitioned_unique_id, libMesh::DofObject::add_extra_integers(), libMesh::MeshBase::clear_point_locator(), libMesh::MeshBase::clear_stored_ranges(), libMesh::MeshBase::default_mapping_data(), libMesh::MeshBase::default_mapping_type(), libMesh::DistributedMesh::delete_elem(), libMesh::DofObject::id(), libMesh::DofObject::invalid_processor_id, libMesh::ParallelObject::n_processors(), libMesh::DofObject::processor_id(), libMesh::ParallelObject::processor_id(), libMesh::Elem::set_mapping_data(), libMesh::Elem::set_mapping_type(), libMesh::DofObject::set_unique_id(), libMesh::DofObject::unique_id(), and libMesh::DofObject::valid_unique_id().

Referenced by libMesh::DistributedMesh::insert_elem().

◆ insert_elem() [2/2]

Elem * libMesh::DistributedMesh::insert_elem ( std::unique_ptr< Elem >  e)
finaloverridevirtualinherited

Version of insert_elem() taking a std::unique_ptr by value.

The version taking a dumb pointer will eventually be deprecated in favor of this version. This API is intended to indicate that ownership of the Elem is transferred to the Mesh when this function is called, and it should play more nicely with the Elem::build() API which has always returned a std::unique_ptr.

Implements libMesh::MeshBase.

Definition at line 774 of file distributed_mesh.C.

775{
776 // The mesh now takes ownership of the Elem. Eventually the guts of
777 // insert_elem(Elem*) will get moved to a private helper function, and
778 // calling insert_elem(Elem*) directly will be deprecated.
779 return insert_elem(e.release());
780}
virtual Elem * insert_elem(Elem *e) override final
Insert elem e to the element array, preserving its id and replacing/deleting any existing element wit...

References libMesh::DistributedMesh::insert_elem().

◆ interior_mesh() [1/2]

MeshBase & libMesh::MeshBase::interior_mesh ( )
inlineinherited
Returns
A writeable reference to the interior mesh.

Definition at line 2058 of file mesh_base.h.

2058{ return *_interior_mesh; }

References libMesh::MeshBase::_interior_mesh.

◆ interior_mesh() [2/2]

const MeshBase & libMesh::MeshBase::interior_mesh ( ) const
inlineinherited
Returns
A mesh that may own interior parents of elements in this mesh. In most cases this mesh includes its own interior parents, but in cases where a separate "interior" mesh was used to create this mesh as a distinct lower-dimensional boundary (or boundary subset) mesh, the original mesh will be returned here.

Definition at line 2053 of file mesh_base.h.

2053{ return *_interior_mesh; }

References libMesh::MeshBase::_interior_mesh.

Referenced by libMesh::BoundaryInfo::add_elements(), libMesh::UnstructuredMesh::copy_nodes_and_elements(), libMesh::MeshBase::detect_interior_parents(), and libMesh::Parallel::Packing< Elem * >::unpack().

◆ is_prepared()

bool libMesh::MeshBase::is_prepared ( ) const
inherited

◆ is_replicated()

virtual bool libMesh::DistributedMesh::is_replicated ( ) const
inlinefinaloverridevirtualinherited
Returns
true if new elements and nodes can and should be created in synchronization on all processors, false otherwise

Reimplemented from libMesh::MeshBase.

Definition at line 182 of file distributed_mesh.h.

183 { return false; }

◆ is_serial()

virtual bool libMesh::DistributedMesh::is_serial ( ) const
inlinefinaloverridevirtualinherited
Returns
true if all elements and nodes of the mesh exist on the current processor, false otherwise

Reimplemented from libMesh::MeshBase.

Definition at line 160 of file distributed_mesh.h.

161 { return _is_serial; }

References libMesh::DistributedMesh::_is_serial.

Referenced by libMesh::DistributedMesh::redistribute().

◆ is_serial_on_zero()

virtual bool libMesh::DistributedMesh::is_serial_on_zero ( ) const
inlinefinaloverridevirtualinherited
Returns
true if all elements and nodes of the mesh exist on the processor 0, false otherwise

Reimplemented from libMesh::MeshBase.

Definition at line 167 of file distributed_mesh.h.

168 { return _is_serial || _is_serial_on_proc_0; }

References libMesh::DistributedMesh::_is_serial, and libMesh::DistributedMesh::_is_serial_on_proc_0.

Referenced by main().

◆ libmesh_assert_valid_parallel_flags()

void libMesh::DistributedMesh::libmesh_assert_valid_parallel_flags ( ) const
inherited

Verify refinement_flag and p_refinement_flag consistency of our elements containers.

Calls libmesh_assert() on each possible failure.

Definition at line 1251 of file distributed_mesh.C.

1252{
1253#if defined(LIBMESH_ENABLE_AMR) && !defined(NDEBUG)
1254 // This function must be run on all processors at once
1255 parallel_object_only();
1256
1257 dof_id_type pmax_elem_id = this->parallel_max_elem_id();
1258
1259 for (dof_id_type i=0; i != pmax_elem_id; ++i)
1260 {
1261 Elem * el = _elements[i]; // Returns nullptr if there's no map entry
1262
1263 unsigned int refinement_flag = el ?
1264 static_cast<unsigned int> (el->refinement_flag()) : libMesh::invalid_uint;
1265 unsigned int p_refinement_flag = el ?
1266 static_cast<unsigned int> (el->p_refinement_flag()) : libMesh::invalid_uint;
1267
1268 libmesh_assert(this->comm().semiverify(el ? &refinement_flag : nullptr));
1269
1270 // p refinement flags aren't always kept correct on inactive
1271 // ghost elements
1272 libmesh_assert(this->comm().semiverify((el && el->active()) ? &p_refinement_flag : nullptr));
1273 }
1274#endif // LIBMESH_ENABLE_AMR
1275}
The libMesh namespace provides an interface to certain functionality in the library.

References libMesh::DistributedMesh::_elements, libMesh::Elem::active(), libMesh::ParallelObject::comm(), libMesh::invalid_uint, libMesh::libmesh_assert(), libMesh::Elem::p_refinement_flag(), libMesh::DistributedMesh::parallel_max_elem_id(), and libMesh::Elem::refinement_flag().

Referenced by libMesh::DistributedMesh::allgather(), libMesh::DistributedMesh::delete_remote_elements(), and libMesh::DistributedMesh::renumber_nodes_and_elements().

◆ libmesh_assert_valid_parallel_ids()

void libMesh::DistributedMesh::libmesh_assert_valid_parallel_ids ( ) const
overridevirtualinherited

Verify id and processor_id consistency of our elements and nodes containers.

Calls libmesh_assert() on each possible failure.

Reimplemented from libMesh::MeshBase.

Definition at line 1220 of file distributed_mesh.C.

1221{
1224}
void libmesh_assert_valid_parallel_object_ids(const dofobject_container< T > &) const
Verify id, processor_id, and if applicable unique_id consistency of a parallel objects container.

References libMesh::DistributedMesh::_elements, libMesh::DistributedMesh::_nodes, and libMesh::DistributedMesh::libmesh_assert_valid_parallel_object_ids().

Referenced by libMesh::BoundaryInfo::add_elements(), libMesh::DistributedMesh::allgather(), libMesh::DistributedMesh::delete_remote_elements(), and libMesh::DistributedMesh::renumber_nodes_and_elements().

◆ libmesh_assert_valid_parallel_object_ids()

template<typename T >
void libMesh::DistributedMesh::libmesh_assert_valid_parallel_object_ids ( const dofobject_container< T > &  objects) const
inherited

Verify id, processor_id, and if applicable unique_id consistency of a parallel objects container.

Calls libmesh_assert() on each possible failure in that container.

Definition at line 1164 of file distributed_mesh.C.

1165{
1166 // This function must be run on all processors at once
1167 parallel_object_only();
1168
1169 const dof_id_type pmax_node_id = this->parallel_max_node_id();
1170 const dof_id_type pmax_elem_id = this->parallel_max_elem_id();
1171 const dof_id_type pmax_id = std::max(pmax_node_id, pmax_elem_id);
1172
1173 for (dof_id_type i=0; i != pmax_id; ++i)
1174 {
1175 T * obj = objects[i]; // Returns nullptr if there's no map entry
1176
1177 // Local lookups by id should return the requested object
1178 libmesh_assert(!obj || obj->id() == i);
1179
1180 // All processors with an object should agree on id
1181#ifndef NDEBUG
1182 const dof_id_type dofid = obj && obj->valid_id() ?
1183 obj->id() : DofObject::invalid_id;
1184 libmesh_assert(this->comm().semiverify(obj ? &dofid : nullptr));
1185#endif
1186
1187 // All processors with an object should agree on processor id
1188 const dof_id_type procid = obj && obj->valid_processor_id() ?
1189 obj->processor_id() : DofObject::invalid_processor_id;
1190 libmesh_assert(this->comm().semiverify(obj ? &procid : nullptr));
1191
1192 dof_id_type min_procid = procid;
1193 this->comm().min(min_procid);
1194
1195 // Either:
1196 // 1.) I own this elem (min_procid == this->processor_id()) *and* I have a valid pointer to it (obj != nullptr)
1197 // or
1198 // 2.) I don't own this elem (min_procid != this->processor_id()). (In this case I may or may not have a valid pointer to it.)
1199
1200 // Original assert logic
1201 // libmesh_assert (min_procid != this->processor_id() || obj);
1202
1203 // More human-understandable logic...
1205 ((min_procid == this->processor_id()) && obj)
1206 ||
1207 (min_procid != this->processor_id())
1208 );
1209
1210#if defined(LIBMESH_ENABLE_UNIQUE_ID) && !defined(NDEBUG)
1211 // All processors with an object should agree on unique id
1212 const unique_id_type uniqueid = obj ? obj->unique_id() : 0;
1213 libmesh_assert(this->comm().semiverify(obj ? &uniqueid : nullptr));
1214#endif
1215 }
1216}
uint8_t unique_id_type
Definition id_types.h:86

References libMesh::ParallelObject::comm(), libMesh::DofObject::invalid_id, libMesh::DofObject::invalid_processor_id, libMesh::libmesh_assert(), libMesh::Parallel::Communicator::min(), libMesh::DistributedMesh::parallel_max_elem_id(), libMesh::DistributedMesh::parallel_max_node_id(), and libMesh::ParallelObject::processor_id().

Referenced by libMesh::DistributedMesh::libmesh_assert_valid_parallel_ids().

◆ libmesh_assert_valid_parallel_p_levels()

void libMesh::DistributedMesh::libmesh_assert_valid_parallel_p_levels ( ) const
inherited

Verify p_level consistency of our elements containers.

Calls libmesh_assert() on each possible failure.

Definition at line 1228 of file distributed_mesh.C.

1229{
1230#ifndef NDEBUG
1231 // This function must be run on all processors at once
1232 parallel_object_only();
1233
1234 dof_id_type pmax_elem_id = this->parallel_max_elem_id();
1235
1236 for (dof_id_type i=0; i != pmax_elem_id; ++i)
1237 {
1238 Elem * el = _elements[i]; // Returns nullptr if there's no map entry
1239
1240 unsigned int p_level = el ? (el->p_level()) : libMesh::invalid_uint;
1241
1242 // All processors with an active element should agree on p level
1243 libmesh_assert(this->comm().semiverify((el && el->active()) ? &p_level : nullptr));
1244 }
1245#endif
1246}

References libMesh::DistributedMesh::_elements, libMesh::Elem::active(), libMesh::ParallelObject::comm(), libMesh::invalid_uint, libMesh::libmesh_assert(), libMesh::Elem::p_level(), and libMesh::DistributedMesh::parallel_max_elem_id().

Referenced by libMesh::DistributedMesh::renumber_nodes_and_elements().

◆ locally_equals()

bool libMesh::MeshBase::locally_equals ( const MeshBase &  other_mesh) const
inherited

This behaves the same as operator==, but only for the local and ghosted aspects of the mesh; i.e.

operator== is true iff local equality is true on every rank.

Definition at line 284 of file mesh_base.C.

285{
286 // Check whether (almost) everything in the base is equal
287 //
288 // We don't check _next_unique_id here, because it's expected to
289 // change in a DistributedMesh prepare_for_use(); it's conceptually
290 // "mutable".
291 //
292 // We use separate if statements instead of logical operators here,
293 // to make it easy to see the failing condition when using a
294 // debugger to figure out why a MeshTools::valid_is_prepared(mesh)
295 // is failing.
296 if (_n_parts != other_mesh._n_parts)
297 return false;
298 if (_default_mapping_type != other_mesh._default_mapping_type)
299 return false;
300 if (_default_mapping_data != other_mesh._default_mapping_data)
301 return false;
302 if (_preparation != other_mesh._preparation)
303 return false;
305 other_mesh._count_lower_dim_elems_in_point_locator)
306 return false;
307
308 // We should either both have our own interior parents or both not;
309 // but if we both don't then we can't really assert anything else
310 // because pointing at the same interior mesh is fair but so is
311 // pointing at two different copies of "the same" interior mesh.
312 if ((_interior_mesh == this) !=
313 (other_mesh._interior_mesh == &other_mesh))
314 return false;
315
316 if (_skip_noncritical_partitioning != other_mesh._skip_noncritical_partitioning)
317 return false;
318 if (_skip_all_partitioning != other_mesh._skip_all_partitioning)
319 return false;
320 if (_skip_renumber_nodes_and_elements != other_mesh._skip_renumber_nodes_and_elements)
321 return false;
322 if (_skip_find_neighbors != other_mesh._skip_find_neighbors)
323 return false;
324 if (_skip_detect_interior_parents != other_mesh._skip_detect_interior_parents)
325 return false;
326 if (_allow_remote_element_removal != other_mesh._allow_remote_element_removal)
327 return false;
328 if (_allow_node_and_elem_unique_id_overlap != other_mesh._allow_node_and_elem_unique_id_overlap)
329 return false;
330 if (_spatial_dimension != other_mesh._spatial_dimension)
331 return false;
332 if (_n_constraint_rows != other_mesh._n_constraint_rows)
333 return false;
334 if (_point_locator_close_to_point_tol != other_mesh._point_locator_close_to_point_tol)
335 return false;
336 if (_block_id_to_name != other_mesh._block_id_to_name)
337 return false;
338 if (_elem_dims != other_mesh._elem_dims)
339 return false;
340 if (_elem_default_orders != other_mesh._elem_default_orders)
341 return false;
342 if (_supported_nodal_order != other_mesh._supported_nodal_order)
343 return false;
344 if (_mesh_subdomains != other_mesh._mesh_subdomains)
345 return false;
346 if (_all_elemset_ids != other_mesh._all_elemset_ids)
347 return false;
348 if (_elem_integer_names != other_mesh._elem_integer_names)
349 return false;
350 if (_elem_integer_default_values != other_mesh._elem_integer_default_values)
351 return false;
352 if (_node_integer_names != other_mesh._node_integer_names)
353 return false;
354 if (_node_integer_default_values != other_mesh._node_integer_default_values)
355 return false;
356 if (static_cast<bool>(_default_ghosting) != static_cast<bool>(other_mesh._default_ghosting))
357 return false;
358 if (static_cast<bool>(_partitioner) != static_cast<bool>(other_mesh._partitioner))
359 return false;
360 if (*boundary_info != *other_mesh.boundary_info)
361 return false;
362
363 // First check whether the "existence" of the two pointers differs (one present, one absent)
364 if (static_cast<bool>(_disjoint_neighbor_boundary_pairs) !=
365 static_cast<bool>(other_mesh._disjoint_neighbor_boundary_pairs))
366 return false;
367 // If both exist, compare the contents (Weak Test: just compare sizes like `_ghosting_functors`)
369 (_disjoint_neighbor_boundary_pairs->size() != other_mesh._disjoint_neighbor_boundary_pairs->size()))
370 return false;
371
372 const constraint_rows_type & other_rows =
373 other_mesh.get_constraint_rows();
374 for (const auto & [node, row] : this->_constraint_rows)
375 {
376 const dof_id_type node_id = node->id();
377 const Node * other_node = other_mesh.query_node_ptr(node_id);
378 if (!other_node)
379 return false;
380
381 auto it = other_rows.find(other_node);
382 if (it == other_rows.end())
383 return false;
384
385 const auto & other_row = it->second;
386 if (row.size() != other_row.size())
387 return false;
388
389 for (auto i : index_range(row))
390 {
391 const auto & [elem_pair, coef] = row[i];
392 const auto & [other_elem_pair, other_coef] = other_row[i];
393 libmesh_assert(elem_pair.first);
394 libmesh_assert(other_elem_pair.first);
395 if (elem_pair.first->id() !=
396 other_elem_pair.first->id() ||
397 elem_pair.second !=
398 other_elem_pair.second ||
399 coef != other_coef)
400 return false;
401 }
402 }
403
404 for (const auto & [elemset_code, elemset_ptr] : this->_elemset_codes)
405 if (const auto it = other_mesh._elemset_codes.find(elemset_code);
406 it == other_mesh._elemset_codes.end() || *elemset_ptr != *it->second)
407 return false;
408
409 // FIXME: we have no good way to compare ghosting functors, since
410 // they're in a vector of pointers, and we have no way *at all*
411 // to compare ghosting functors, since they don't have operator==
412 // defined and we encourage users to subclass them. We can check if
413 // we have the same number, is all.
414 if (_ghosting_functors.size() !=
415 other_mesh._ghosting_functors.size())
416 return false;
417
418 // Same deal for partitioners. We tested that we both have one or
419 // both don't, but are they equivalent? Let's guess "yes".
420
421 // Now let the subclasses decide whether everything else is equal
422 return this->subclass_locally_equals(other_mesh);
423}
bool _skip_all_partitioning
If this is true then no partitioning should be done.
Definition mesh_base.h:2275
bool _skip_noncritical_partitioning
If this is true then no partitioning should be done with the possible exception of orphaned nodes.
Definition mesh_base.h:2270
virtual bool subclass_locally_equals(const MeshBase &other_mesh) const =0
Shim to allow operator == (&) to behave like a virtual function without having to be one.
std::unique_ptr< Partitioner > _partitioner
A partitioner to use at each prepare_for_use().
Definition mesh_base.h:2251
unsigned int _n_parts
The number of partitions the mesh has.
Definition mesh_base.h:2189
std::map< const Node *, constraint_rows_mapped_type > constraint_rows_type
Definition mesh_base.h:1934

References libMesh::MeshBase::_all_elemset_ids, libMesh::MeshBase::_allow_node_and_elem_unique_id_overlap, libMesh::MeshBase::_allow_remote_element_removal, libMesh::MeshBase::_block_id_to_name, libMesh::MeshBase::_constraint_rows, libMesh::MeshBase::_count_lower_dim_elems_in_point_locator, libMesh::MeshBase::_default_ghosting, libMesh::MeshBase::_default_mapping_data, libMesh::MeshBase::_default_mapping_type, libMesh::MeshBase::_disjoint_neighbor_boundary_pairs, libMesh::MeshBase::_elem_default_orders, libMesh::MeshBase::_elem_dims, libMesh::MeshBase::_elem_integer_default_values, libMesh::MeshBase::_elem_integer_names, libMesh::MeshBase::_elemset_codes, libMesh::MeshBase::_ghosting_functors, libMesh::MeshBase::_interior_mesh, libMesh::MeshBase::_mesh_subdomains, libMesh::MeshBase::_n_constraint_rows, libMesh::MeshBase::_n_parts, libMesh::MeshBase::_node_integer_default_values, libMesh::MeshBase::_node_integer_names, libMesh::MeshBase::_partitioner, libMesh::MeshBase::_point_locator_close_to_point_tol, libMesh::MeshBase::_preparation, libMesh::MeshBase::_skip_all_partitioning, libMesh::MeshBase::_skip_detect_interior_parents, libMesh::MeshBase::_skip_find_neighbors, libMesh::MeshBase::_skip_noncritical_partitioning, libMesh::MeshBase::_skip_renumber_nodes_and_elements, libMesh::MeshBase::_spatial_dimension, libMesh::MeshBase::_supported_nodal_order, libMesh::MeshBase::boundary_info, libMesh::MeshBase::get_constraint_rows(), libMesh::index_range(), libMesh::libmesh_assert(), libMesh::MeshBase::query_node_ptr(), and libMesh::MeshBase::subclass_locally_equals().

Referenced by libMesh::MeshBase::operator==().

◆ max_elem_id()

virtual dof_id_type libMesh::DistributedMesh::max_elem_id ( ) const
inlinefinaloverridevirtualinherited
Returns
A number one greater than the maximum element id in the mesh. A more apt name for this method would be end_elem_id

Implements libMesh::MeshBase.

Definition at line 275 of file distributed_mesh.h.

275{ return _max_elem_id; }

References libMesh::DistributedMesh::_max_elem_id.

Referenced by libMesh::DistributedMesh::allgather(), libMesh::DistributedMesh::delete_remote_elements(), MeshPerElemTest< elem_type >::meshes_equal_enough(), and libMesh::DistributedMesh::renumber_nodes_and_elements().

◆ max_node_id()

virtual dof_id_type libMesh::DistributedMesh::max_node_id ( ) const
inlinefinaloverridevirtualinherited
Returns
A number one greater than the maximum node id in the mesh. A more apt name for this method would be end_node_id

Implements libMesh::MeshBase.

Definition at line 271 of file distributed_mesh.h.

271{ return _max_node_id; }

References libMesh::DistributedMesh::_max_node_id.

Referenced by libMesh::DistributedMesh::allgather(), libMesh::DistributedMesh::delete_remote_elements(), MeshPerElemTest< elem_type >::meshes_equal_enough(), and libMesh::DistributedMesh::renumber_nodes_and_elements().

◆ merge_extra_integer_names()

std::pair< std::vector< unsigned int >, std::vector< unsigned int > > libMesh::MeshBase::merge_extra_integer_names ( const MeshBase &  other)
protectedinherited

Merge extra-integer arrays from an other mesh.

Returns two mappings from index values in other to (possibly newly created) index values with the same string name in this mesh, the first for element integers and the second for node integers.

Definition at line 2400 of file mesh_base.C.

2401{
2402 std::pair<std::vector<unsigned int>, std::vector<unsigned int>> returnval;
2403 returnval.first = this->add_elem_integers(other._elem_integer_names, true, &other._elem_integer_default_values);
2404 returnval.second = this->add_node_integers(other._node_integer_names, true, &other._node_integer_default_values);
2405 return returnval;
2406}
std::vector< unsigned int > add_node_integers(const std::vector< std::string > &names, bool allocate_data=true, const std::vector< dof_id_type > *default_values=nullptr)
Register integer data (of type dof_id_type) to be added to each node in the mesh.
Definition mesh_base.C:735
std::vector< unsigned int > add_elem_integers(const std::vector< std::string > &names, bool allocate_data=true, const std::vector< dof_id_type > *default_values=nullptr)
Register integer data (of type dof_id_type) to be added to each element in the mesh,...
Definition mesh_base.C:646

References libMesh::MeshBase::_elem_integer_default_values, libMesh::MeshBase::_elem_integer_names, libMesh::MeshBase::_node_integer_default_values, libMesh::MeshBase::_node_integer_names, libMesh::MeshBase::add_elem_integers(), and libMesh::MeshBase::add_node_integers().

Referenced by libMesh::UnstructuredMesh::copy_nodes_and_elements(), and libMesh::UnstructuredMesh::create_submesh().

◆ mesh_dimension()

unsigned int libMesh::MeshBase::mesh_dimension ( ) const
inherited
Returns
The logical dimension of the mesh; i.e. the manifold dimension of the elements in the mesh. When we have multi-dimensional meshes (e.g. hexes and quads in the same mesh) then this will return the largest such dimension.

Definition at line 435 of file mesh_base.C.

436{
437 if (!_elem_dims.empty())
438 return cast_int<unsigned int>(*_elem_dims.rbegin());
439 return 0;
440}

References libMesh::MeshBase::_elem_dims.

Referenced by libMesh::UniformRefinementEstimator::_estimate_error(), libMesh::HPCoarsenTest::add_projection(), libMesh::UnstructuredMesh::all_complete_order_range(), libMesh::UnstructuredMesh::all_second_order_range(), libMesh::MeshTools::Modification::all_tri(), alternative_fe_assembly(), LinearElasticity::assemble(), assemble(), assemble(), assemble_1D(), AssembleOptimization::assemble_A_and_F(), assemble_biharmonic(), assemble_cd(), assemble_cd(), assemble_divgrad(), assemble_elasticity(), assemble_ellipticdg(), assemble_func(), assemble_graddiv(), assemble_helmholtz(), assemble_laplace(), assemble_mass(), assemble_matrices(), assemble_poisson(), assemble_poisson(), assemble_poisson(), assemble_SchroedingerEquation(), assemble_shell(), assemble_stokes(), assemble_temperature_jump(), assemble_wave(), assemble_wave(), libMesh::MeshTools::Generation::build_cube(), libMesh::MeshBase::cache_elem_data(), compute_enriched_soln(), compute_jacobian(), compute_residual(), LinearElasticity::compute_stresses(), LargeDeformationElasticity::compute_stresses(), LinearElasticityWithContact::compute_stresses(), compute_stresses(), libMesh::VariationalSmootherConstraint::constrain(), libMesh::VariationalSmootherConstraint::constrain_node_to_line(), libMesh::VariationalSmootherConstraint::constrain_node_to_plane(), libMesh::DofMap::create_dof_constraints(), libMesh::MeshTools::Modification::distort(), NavierSystem::element_constraint(), HeatSystem::element_time_derivative(), NavierSystem::element_time_derivative(), SolidSystem::element_time_derivative(), libMesh::ExactErrorEstimator::estimate_error(), fe_assembly(), libMesh::VariationalSmootherConstraint::fix_node(), libMesh::MeshRefinement::flag_elements_by_elem_fraction(), libMesh::MeshRefinement::flag_elements_by_nelem_target(), NavierSystem::forcing(), form_functionA(), form_functionB(), form_matrixA(), libMesh::ReplicatedMesh::get_boundary_points(), libMesh::LaplaceMeshSmoother::init(), libMesh::PointLocatorTree::init(), NavierSystem::init_data(), SolidSystem::init_data(), ElasticityRBConstruction::init_data(), libMesh::ExodusII_IO_Helper::initialize(), libMesh::Nemesis_IO_Helper::initialize(), integrate_function(), LargeDeformationElasticity::jacobian(), LaplaceYoung::jacobian(), main(), NavierSystem::mass_residual(), Integrate::operator()(), libMesh::PatchRecoveryErrorEstimator::EstimateError::operator()(), libMesh::SmoothnessEstimator::EstimateSmoothness::operator()(), libMesh::WeightedPatchRecoveryErrorEstimator::EstimateError::operator()(), NavierSystem::postprocess(), libMesh::VTKIO::read(), libMesh::Nemesis_IO::read(), libMesh::GMVIO::read(), libMesh::ExodusII_IO::read(), libMesh::CheckpointIO::read_connectivity(), libMesh::System::read_header(), libMesh::UCDIO::read_implementation(), libMesh::XdrIO::read_serialized_connectivity(), LargeDeformationElasticity::residual(), LaplaceYoung::residual(), LinearElasticityWithContact::residual_and_jacobian(), SolidSystem::save_initial_mesh(), libMesh::HPCoarsenTest::select_refinement(), libMesh::PetscPreconditioner< T >::set_hypre_ads_data(), libMesh::PetscPreconditioner< T >::set_hypre_ams_data(), libMesh::PetscPreconditioner< T >::set_petsc_aux_data(), setup(), NavierSystem::side_constraint(), libMesh::MeshTools::Modification::smooth(), MeshSpatialDimensionTest::test1D(), MeshSpatialDimensionTest::test2D(), CheckpointIOTest::testC0PolygonCheckpoint(), CheckpointIOTest::testC0PolyhedronCheckpoint(), BoundaryMeshSubdomainTest::testDefaultSubdomain(), InfFERadialTest::testInfQuants(), InfFERadialTest::testInfQuants_numericDeriv(), BoundaryMeshSubdomainTest::testPerBoundarySubdomain(), InfFERadialTest::testSides(), InfFERadialTest::testSingleOrder(), BoundaryMeshSubdomainTest::testSingleSubdomain(), MeshSmootherTest::testVariationalSmootherRegression(), libMesh::BoundaryVolumeSolutionTransfer::transfer(), libMesh::DTKSolutionTransfer::transfer(), libMesh::MeshTools::volume(), libMesh::PostscriptIO::write(), libMesh::CheckpointIO::write(), libMesh::GMVIO::write_binary(), libMesh::TecplotIO::write_binary(), libMesh::GMVIO::write_discontinuous_gmv(), libMesh::UCDIO::write_implementation(), libMesh::UCDIO::write_nodal_data(), libMesh::EnsightIO::write_scalar_ascii(), libMesh::GnuPlotIO::write_solution(), and libMesh::EnsightIO::write_vector_ascii().

◆ move_nodes_and_elements()

virtual void libMesh::UnstructuredMesh::move_nodes_and_elements ( MeshBase &&  other_mesh)
pure virtualinherited

Move node and elements from other_mesh to this mesh.

Implemented in libMesh::ReplicatedMesh.

◆ n_active_elem()

dof_id_type libMesh::DistributedMesh::n_active_elem ( ) const
finaloverridevirtualinherited
Returns
The number of active elements in the mesh.

Implemented in terms of active_element_iterators.

Implements libMesh::MeshBase.

Definition at line 1779 of file distributed_mesh.C.

1780{
1781 parallel_object_only();
1782
1783 // Get local active elements first
1784 dof_id_type active_elements =
1785 static_cast<dof_id_type>(std::distance (this->active_local_elements_begin(),
1786 this->active_local_elements_end()));
1787 this->comm().sum(active_elements);
1788
1789 // Then add unpartitioned active elements, which should exist on
1790 // every processor
1791 active_elements +=
1792 static_cast<dof_id_type>(std::distance
1793 (this->active_pid_elements_begin(DofObject::invalid_processor_id),
1794 this->active_pid_elements_end(DofObject::invalid_processor_id)));
1795 return active_elements;
1796}

References libMesh::ParallelObject::comm(), libMesh::DofObject::invalid_processor_id, and libMesh::Parallel::Communicator::sum().

◆ n_active_elem_on_proc()

dof_id_type libMesh::MeshBase::n_active_elem_on_proc ( const processor_id_type  proc) const
inherited
Returns
The number of active elements on processor proc.

Definition at line 1243 of file mesh_base.C.

1244{
1245 libmesh_assert_less (proc_id, this->n_processors());
1246 return static_cast<dof_id_type>(std::distance (this->active_pid_elements_begin(proc_id),
1247 this->active_pid_elements_end (proc_id)));
1248}

References libMesh::ParallelObject::n_processors().

Referenced by libMesh::MeshBase::n_active_local_elem().

◆ n_active_local_elem()

dof_id_type libMesh::MeshBase::n_active_local_elem ( ) const
inlineinherited

◆ n_active_sub_elem()

dof_id_type libMesh::MeshBase::n_active_sub_elem ( ) const
inherited

Same as n_sub_elem(), but only counts active elements.

Definition at line 1264 of file mesh_base.C.

1265{
1266 dof_id_type ne=0;
1267
1268 for (const auto & elem : this->active_element_ptr_range())
1269 ne += elem->n_sub_elem();
1270
1271 return ne;
1272}
dof_id_type n_sub_elem() const
Definition mesh_base.C:1252

Referenced by libMesh::TecplotIO::write_ascii(), libMesh::GMVIO::write_ascii_old_impl(), and libMesh::TecplotIO::write_binary().

◆ n_constraint_rows()

dof_id_type libMesh::MeshBase::n_constraint_rows ( ) const
inlineinherited

Returns how many total constraint rows we have.

This is cached data, so it can be called from individual ranks.

Definition at line 2691 of file mesh_base.h.

References libMesh::MeshBase::_n_constraint_rows, libMesh::MeshBase::_preparation, libMesh::MeshBase::Preparation::has_synched_id_counts, and libMesh::libmesh_assert().

Referenced by libMesh::DofMap::create_dof_constraints(), and libMesh::DofMap::process_mesh_constraint_rows().

◆ n_elem()

virtual dof_id_type libMesh::DistributedMesh::n_elem ( ) const
inlinefinaloverridevirtualinherited
Returns
The number of elements in the mesh.

The standard n_elem() function may return a cached value on distributed meshes, and so can be called by any processor at any time.

Implements libMesh::MeshBase.

Definition at line 273 of file distributed_mesh.h.

273{ return _n_elem; }

References libMesh::DistributedMesh::_n_elem.

Referenced by libMesh::DistributedMesh::allgather(), libMesh::DistributedMesh::delete_remote_elements(), libMesh::DistributedMesh::renumber_nodes_and_elements(), AllRBBTest::test_circle(), AllRBBTest::test_sphere(), ExodusC0PolyhedronTest::test_write_and_read_hexagonal_prism(), and ExodusC0PolygonTest::test_write_and_read_pentagon().

◆ n_elem_integers()

unsigned int libMesh::MeshBase::n_elem_integers ( ) const
inlineinherited

◆ n_elem_on_proc()

dof_id_type libMesh::MeshBase::n_elem_on_proc ( const processor_id_type  proc) const
inherited
Returns
The number of elements on processor proc.

Definition at line 1230 of file mesh_base.C.

1231{
1232 // We're either counting a processor's elements or unpartitioned
1233 // elements
1234 libmesh_assert (proc_id < this->n_processors() ||
1236
1237 return static_cast<dof_id_type>(std::distance (this->pid_elements_begin(proc_id),
1238 this->pid_elements_end (proc_id)));
1239}

References libMesh::DofObject::invalid_processor_id, libMesh::libmesh_assert(), and libMesh::ParallelObject::n_processors().

Referenced by libMesh::MeshBase::n_local_elem(), and libMesh::MeshBase::n_unpartitioned_elem().

◆ n_elemsets()

unsigned int libMesh::MeshBase::n_elemsets ( ) const
inherited

Returns the number of unique elemset ids which have been added via add_elemset_code(), which is the size of the _all_elemset_ids set.

Definition at line 487 of file mesh_base.C.

488{
489 return _all_elemset_ids.size();
490}

References libMesh::MeshBase::_all_elemset_ids.

Referenced by libMesh::MeshBase::get_info(), libMesh::ExodusII_IO_Helper::initialize(), libMesh::ExodusII_IO::read(), and libMesh::ExodusII_IO_Helper::write_elemsets().

◆ n_local_elem()

dof_id_type libMesh::MeshBase::n_local_elem ( ) const
inlineinherited
Returns
The number of elements on the local processor.

Definition at line 694 of file mesh_base.h.

695 { return this->n_elem_on_proc (this->processor_id()); }
dof_id_type n_elem_on_proc(const processor_id_type proc) const
Definition mesh_base.C:1230

References libMesh::MeshBase::n_elem_on_proc(), and libMesh::ParallelObject::processor_id().

Referenced by libMesh::DTKAdapter::DTKAdapter(), libMesh::MeshBase::get_info(), libMesh::DistributedMesh::parallel_n_elem(), and DofMapTest::testBadElemFECombo().

◆ n_local_nodes()

dof_id_type libMesh::MeshBase::n_local_nodes ( ) const
inlineinherited
Returns
The number of nodes on the local processor.

Definition at line 588 of file mesh_base.h.

589 { return this->n_nodes_on_proc (this->processor_id()); }
dof_id_type n_nodes_on_proc(const processor_id_type proc) const
Definition mesh_base.C:1217

References libMesh::MeshBase::n_nodes_on_proc(), and libMesh::ParallelObject::processor_id().

Referenced by libMesh::MeshBase::get_info(), libMesh::VTKIO::nodes_to_vtk(), and libMesh::DistributedMesh::parallel_n_nodes().

◆ n_local_subdomains()

subdomain_id_type libMesh::MeshBase::n_local_subdomains ( ) const
inherited
Returns
The number of subdomains in the local mesh. Subdomains correspond to separate subsets of the mesh which could correspond e.g. to different materials in a solid mechanics application, or regions where different physical processes are important. The subdomain mapping is independent from the parallel decomposition.

Definition at line 1205 of file mesh_base.C.

1206{
1207 std::set<subdomain_id_type> ids;
1208
1209 this->subdomain_ids (ids, /* global = */ false);
1210
1211 return cast_int<subdomain_id_type>(ids.size());
1212}

References libMesh::MeshBase::subdomain_ids().

Referenced by libMesh::MeshBase::get_info().

◆ n_node_integers()

unsigned int libMesh::MeshBase::n_node_integers ( ) const
inlineinherited

◆ n_nodes()

virtual dof_id_type libMesh::DistributedMesh::n_nodes ( ) const
inlinefinaloverridevirtualinherited
Returns
The number of nodes in the mesh.

This function and others must be defined in derived classes since the MeshBase class has no specific storage for nodes or elements. The standard n_nodes() function may return a cached value on distributed meshes, and so can be called by any processor at any time.

Implements libMesh::MeshBase.

Definition at line 270 of file distributed_mesh.h.

270{ return _n_nodes; }

References libMesh::DistributedMesh::_n_nodes.

Referenced by libMesh::DistributedMesh::allgather(), libMesh::DistributedMesh::delete_remote_elements(), libMesh::DistributedMesh::renumber_nodes_and_elements(), AllRBBTest::test_circle(), and MixedOrderTest::testStitch().

◆ n_nodes_on_proc()

dof_id_type libMesh::MeshBase::n_nodes_on_proc ( const processor_id_type  proc) const
inherited
Returns
The number of nodes on processor proc.

Definition at line 1217 of file mesh_base.C.

1218{
1219 // We're either counting a processor's nodes or unpartitioned
1220 // nodes
1221 libmesh_assert (proc_id < this->n_processors() ||
1223
1224 return static_cast<dof_id_type>(std::distance (this->pid_nodes_begin(proc_id),
1225 this->pid_nodes_end (proc_id)));
1226}

References libMesh::DofObject::invalid_processor_id, libMesh::libmesh_assert(), and libMesh::ParallelObject::n_processors().

Referenced by libMesh::MeshBase::n_local_nodes(), and libMesh::MeshBase::n_unpartitioned_nodes().

◆ n_partitions()

unsigned int libMesh::MeshBase::n_partitions ( ) const
inlineinherited
Returns
The number of partitions which have been defined via a call to either mesh.partition() or by building a Partitioner object and calling partition.
Note
The partitioner object is responsible for setting this value.

Definition at line 1530 of file mesh_base.h.

1531 { return _n_parts; }

References libMesh::MeshBase::_n_parts.

Referenced by libMesh::Partitioner::assign_partitioning(), libMesh::UnstructuredMesh::copy_nodes_and_elements(), libMesh::MeshBase::get_info(), libMesh::BoundaryInfo::sync(), CheckpointIOTest::testSplitter(), libMesh::NameBasedIO::write(), libMesh::GMVIO::write_ascii_new_impl(), and libMesh::GMVIO::write_ascii_old_impl().

◆ n_processors()

processor_id_type libMesh::ParallelObject::n_processors ( ) const
inlineinherited
Returns
The number of processors in the group.

Definition at line 103 of file parallel_object.h.

104 {
105 processor_id_type returnval =
106 cast_int<processor_id_type>(_communicator.size());
107 libmesh_assert(returnval); // We never have an empty comm
108 return returnval;
109 }
processor_id_type size() const

References libMesh::ParallelObject::_communicator, libMesh::libmesh_assert(), and libMesh::Parallel::Communicator::size().

Referenced by libMesh::Partitioner::_find_global_index_by_pid_map(), libMesh::BoundaryInfo::_find_id_maps(), libMesh::DofMap::add_constraints_to_send_list(), libMesh::PetscDMWrapper::add_dofs_to_section(), libMesh::DistributedMesh::add_elem(), libMesh::DistributedMesh::add_node(), libMesh::System::add_vector(), libMesh::LaplaceMeshSmoother::allgather_graph(), libMesh::DofMap::allgather_recursive_constraints(), libMesh::FEMSystem::assembly(), ExodusC0PolyhedronTest::assert_distributed_if_parallel(), libMesh::Nemesis_IO::assert_symmetric_cmaps(), libMesh::Partitioner::assign_partitioning(), libMesh::AztecLinearSolver< T >::AztecLinearSolver(), libMesh::Partitioner::build_graph(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::DistributedMesh::clear(), libMesh::DistributedMesh::clear_elems(), libMesh::Nemesis_IO_Helper::compute_border_node_ids(), libMesh::Nemesis_IO_Helper::construct_nemesis_filename(), libMesh::UnstructuredMesh::copy_nodes_and_elements(), libMesh::ExodusII_IO::copy_scalar_solution(), libMesh::Nemesis_IO::copy_scalar_solution(), libMesh::UnstructuredMesh::create_pid_mesh(), libMesh::MeshTools::create_processor_bounding_box(), libMesh::EnsightIO::EnsightIO(), libMesh::RBEIMEvaluation::gather_bfs(), libMesh::MeshBase::get_info(), libMesh::StaticCondensation::init(), libMesh::SystemSubsetBySubdomain::init(), libMesh::PetscDMWrapper::init_petscdm(), libMesh::ExodusII_IO_Helper::initialize(), libMesh::Nemesis_IO_Helper::initialize(), libMesh::DistributedMesh::insert_elem(), libMesh::NumericVector< T >::is_effectively_ghosted(), libMesh::NumericVector< T >::is_effectively_serial(), libMesh::MeshTools::libmesh_assert_contiguous_dof_ids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_new_node_procids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Elem >(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_topology_consistent_procids< Node >(), libMesh::MeshTools::libmesh_assert_valid_boundary_ids(), libMesh::MeshTools::libmesh_assert_valid_dof_ids(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::MeshTools::libmesh_assert_valid_refinement_flags(), libMesh::MeshBase::n_active_elem_on_proc(), libMesh::DofMap::n_dofs_per_processor(), libMesh::MeshBase::n_elem_on_proc(), libMesh::MeshBase::n_nodes_on_proc(), libMesh::RBEIMEvaluation::node_gather_bfs(), libMesh::MeshBase::partition(), libMesh::Partitioner::partition(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::MeshBase::print_constraint_rows(), libMesh::DofMap::print_dof_constraints(), libMesh::Nemesis_IO::read(), libMesh::CheckpointIO::read(), libMesh::NameBasedIO::read(), libMesh::CheckpointIO::read_connectivity(), libMesh::XdrIO::read_header(), libMesh::CheckpointIO::read_nodes(), libMesh::System::read_parallel_data(), libMesh::System::read_SCALAR_dofs(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::System::read_serialized_vector(), libMesh::DistributedMesh::renumber_dof_objects(), libMesh::Partitioner::repartition(), OverlappingFunctorTest::run_partitioner_test(), libMesh::DofMap::scatter_constraints(), libMesh::DistributedMesh::set_next_ids(), libMesh::DistributedMesh::set_next_unique_id(), libMesh::DistributedMesh::set_next_unique_ids(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::PetscDMWrapper::set_point_range_in_section(), WriteVecAndScalar::setupTests(), libMesh::RBEIMEvaluation::side_gather_bfs(), ExodusC0PolyhedronTest::test_write_and_read_mixed_hex_tet_block_names_impl(), CheckpointIOTest::testDisjointNeighborPairsCheckpoint(), DistributedMeshTest::testRemoteElemError(), CheckpointIOTest::testSplitter(), libMesh::GMVIO::write_binary(), libMesh::GMVIO::write_discontinuous_gmv(), libMesh::ExodusII_IO_Helper::write_nodal_coordinates(), libMesh::ExodusII_IO::write_nodal_data(), libMesh::VTKIO::write_nodal_data(), libMesh::System::write_parallel_data(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::XdrIO::write_serialized_nodes(), and libMesh::XdrIO::write_serialized_nodesets().

◆ n_sub_elem()

dof_id_type libMesh::MeshBase::n_sub_elem ( ) const
inherited
Returns
The number of elements that will be written out in certain I/O formats.

For example, a 9-noded quadrilateral will be broken into 4 linear sub-elements for plotting purposes. Thus, for a mesh of 2 QUAD9 elements n_tecplot_elem() will return 8. Implemented in terms of element_iterators.

Definition at line 1252 of file mesh_base.C.

1253{
1254 dof_id_type ne=0;
1255
1256 for (const auto & elem : this->element_ptr_range())
1257 ne += elem->n_sub_elem();
1258
1259 return ne;
1260}

◆ n_subdomains()

subdomain_id_type libMesh::MeshBase::n_subdomains ( ) const
inherited
Returns
The number of subdomains in the global mesh. Subdomains correspond to separate subsets of the mesh which could correspond e.g. to different materials in a solid mechanics application, or regions where different physical processes are important. The subdomain mapping is independent from the parallel decomposition.

Definition at line 1191 of file mesh_base.C.

1192{
1193 // This requires an inspection on every processor
1194 parallel_object_only();
1195
1196 std::set<subdomain_id_type> ids;
1197
1198 this->subdomain_ids (ids);
1199
1200 return cast_int<subdomain_id_type>(ids.size());
1201}

References libMesh::MeshBase::subdomain_ids().

Referenced by libMesh::MeshBase::get_info(), OverlappingCouplingFunctor::OverlappingCouplingFunctor(), MeshSubdomainIDTest::testUnpartitioned(), libMesh::XdrIO::write(), and libMesh::NameBasedIO::write_nodal_data().

◆ n_unpartitioned_elem()

dof_id_type libMesh::MeshBase::n_unpartitioned_elem ( ) const
inlineinherited

◆ n_unpartitioned_nodes()

dof_id_type libMesh::MeshBase::n_unpartitioned_nodes ( ) const
inlineinherited
Returns
The number of nodes owned by no processor.

Definition at line 594 of file mesh_base.h.

References libMesh::DofObject::invalid_processor_id, and libMesh::MeshBase::n_nodes_on_proc().

Referenced by libMesh::MeshBase::complete_preparation(), and libMesh::DistributedMesh::parallel_n_nodes().

◆ next_unique_id()

unique_id_type libMesh::MeshBase::next_unique_id ( ) const
inlineinherited

◆ node_ptr() [1/2]

const Node * libMesh::DistributedMesh::node_ptr ( const dof_id_type  i) const
finaloverridevirtualinherited
Returns
A pointer to the \( i^{th} \) node, which should be present in this processor's subset of the mesh data structure.

Implements libMesh::MeshBase.

Definition at line 486 of file distributed_mesh.C.

487{
489 libmesh_assert_equal_to (_nodes[i]->id(), i);
490
491 return _nodes[i];
492}

References libMesh::DistributedMesh::_nodes, and libMesh::libmesh_assert().

Referenced by libMesh::DistributedMesh::fix_broken_node_and_element_numbering(), MeshPerElemTest< elem_type >::meshes_equal_enough(), DisjointNeighborTest::testDisjointNeighborConflictError(), and DisjointNeighborTest::testStitchCrossMesh().

◆ node_ptr() [2/2]

Node * libMesh::DistributedMesh::node_ptr ( const dof_id_type  i)
finaloverridevirtualinherited
Returns
A writable pointer to the \( i^{th} \) node, which should be present in this processor's subset of the mesh data structure.

Implements libMesh::MeshBase.

Definition at line 497 of file distributed_mesh.C.

498{
500 libmesh_assert_equal_to (_nodes[i]->id(), i);
501
502 return _nodes[i];
503}

References libMesh::DistributedMesh::_nodes, and libMesh::libmesh_assert().

◆ node_ref() [1/2]

virtual Node & libMesh::MeshBase::node_ref ( const dof_id_type  i)
inlinevirtualinherited
Returns
A reference to the \( i^{th} \) node, which should be present in this processor's subset of the mesh data structure.

Definition at line 751 of file mesh_base.h.

752 {
753 return *this->node_ptr(i);
754 }

References libMesh::MeshBase::node_ptr().

◆ node_ref() [2/2]

virtual const Node & libMesh::MeshBase::node_ref ( const dof_id_type  i) const
inlinevirtualinherited
Returns
A constant reference (for reading only) to the \( i^{th} \) node, which should be present in this processor's subset of the mesh data structure.

Definition at line 742 of file mesh_base.h.

743 {
744 return *this->node_ptr(i);
745 }

References libMesh::MeshBase::node_ptr().

Referenced by libMesh::SyncNodalPositions::act_on_data(), LinearElasticityWithContact::add_contact_edge_elements(), add_cube_convex_hull_to_mesh(), assemble_matrix_and_rhs(), libMesh::InfElemBuilder::build_inf_elem(), GhostDofConstraint::constrain(), libMesh::MeshBase::copy_constraint_rows(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::DTKAdapter::DTKAdapter(), fill_dirichlet_bc(), libMesh::MeshTools::Modification::interpolate_surface(), main(), libMesh::DistributedMesh::point(), libMesh::ReplicatedMesh::point(), libMesh::ExodusII_IO::read(), libMesh::XdrIO::read_serialized_nodes(), libMesh::DistributedMesh::renumber_nodes_and_elements(), LinearElasticityWithContact::residual_and_jacobian(), libMesh::Partitioner::set_interface_node_processor_ids_BFS(), libMesh::Partitioner::set_interface_node_processor_ids_linear(), libMesh::Partitioner::set_interface_node_processor_ids_petscpartitioner(), libMesh::Partitioner::set_node_processor_ids(), libMesh::LaplaceMeshSmoother::smooth(), libMesh::VariationalMeshSmoother::smooth(), libMesh::MeshTools::Modification::smooth(), libMesh::UnstructuredMesh::stitching_helper(), DofMapTest::testGhostConstraintSendList(), HDivGradTest::testGradByFiniteDifference(), MeshTriangulationTest::testPoly2TriHolesInterpRefined(), MeshSmootherTest::testVariationalSmoother(), MeshSmootherTest::testVariationalSmootherRegression(), libMesh::DTKAdapter::update_variable_values(), and libMesh::GmshIO::write_mesh().

◆ nodes_and_elements_equal()

bool libMesh::MeshBase::nodes_and_elements_equal ( const MeshBase &  other_mesh) const
protectedinherited

Tests for equality of all elements and nodes in the mesh.

Helper function for subclass_equals() in unstructured mesh subclasses.

Definition at line 2457 of file mesh_base.C.

2458{
2459 for (const auto & other_node : other_mesh.node_ptr_range())
2460 {
2461 const Node * node = this->query_node_ptr(other_node->id());
2462 if (!node)
2463 return false;
2464 if (*other_node != *node)
2465 return false;
2466 }
2467 for (const auto & node : this->node_ptr_range())
2468 if (!other_mesh.query_node_ptr(node->id()))
2469 return false;
2470
2471 for (const auto & other_elem : other_mesh.element_ptr_range())
2472 {
2473 const Elem * elem = this->query_elem_ptr(other_elem->id());
2474 if (!elem)
2475 return false;
2476 if (!other_elem->topologically_equal(*elem))
2477 return false;
2478 }
2479 for (const auto & elem : this->element_ptr_range())
2480 if (!other_mesh.query_elem_ptr(elem->id()))
2481 return false;
2482
2483 return true;
2484}
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0

References libMesh::MeshBase::query_elem_ptr(), and libMesh::MeshBase::query_node_ptr().

◆ operator!=()

bool libMesh::MeshBase::operator!= ( const MeshBase &  other_mesh) const
inlineinherited

Definition at line 138 of file mesh_base.h.

139 {
140 return !(*this == other_mesh);
141 }

◆ operator==()

bool libMesh::MeshBase::operator== ( const MeshBase &  other_mesh) const
inherited

This tests for exactly-equal data in all the senses that a mathematician would care about (element connectivity, nodal coordinates), but in the senses a programmer would care about it allows for non-equal equivalence in some ways (we accept different Elem/Node addresses in memory) but not others (we do not accept different subclass types, nor even different Elem/Node ids).

Though this method is non-virtual, its implementation calls the virtual function subclass_locally_equals() to test for equality of subclass-specific data as well.

Definition at line 274 of file mesh_base.C.

275{
276 LOG_SCOPE("operator==()", "MeshBase");
277
278 bool is_equal = this->locally_equals(other_mesh);
279 this->comm().min(is_equal);
280 return is_equal;
281}
bool locally_equals(const MeshBase &other_mesh) const
This behaves the same as operator==, but only for the local and ghosted aspects of the mesh; i....
Definition mesh_base.C:284

References libMesh::ParallelObject::comm(), libMesh::MeshBase::locally_equals(), and libMesh::Parallel::Communicator::min().

◆ own_node()

void libMesh::DistributedMesh::own_node ( Node &  n)
finaloverridevirtualinherited

Takes ownership of node n on this partition of a distributed mesh, by setting n.processor_id() to this->processor_id(), as well as changing n.id() and moving it in the mesh's internal container to give it a new authoritative id.

Reimplemented from libMesh::MeshBase.

Definition at line 869 of file distributed_mesh.C.

870{
871 // This had better be a node in our mesh
872 libmesh_assert(_nodes[n.id()] == &n);
873
874 _nodes[n.id()] = nullptr;
875 _n_nodes--;
876
877 n.set_id(DofObject::invalid_id);
878 n.processor_id() = this->processor_id();
879
880 this->add_node(&n);
881}

References libMesh::DistributedMesh::_n_nodes, libMesh::DistributedMesh::_nodes, libMesh::DistributedMesh::add_node(), libMesh::DofObject::id(), libMesh::DofObject::invalid_id, libMesh::libmesh_assert(), libMesh::DofObject::processor_id(), libMesh::ParallelObject::processor_id(), and libMesh::DofObject::set_id().

◆ parallel_max_elem_id()

dof_id_type libMesh::DistributedMesh::parallel_max_elem_id ( ) const
inherited

Definition at line 372 of file distributed_mesh.C.

373{
374 // This function must be run on all processors at once
375 parallel_object_only();
376
377 dof_id_type max_local = 0;
378
379 dofobject_container<Elem>::const_reverse_veclike_iterator
380 rit = _elements.rbegin();
381
382 const dofobject_container<Elem>::const_reverse_veclike_iterator
383 rend = _elements.rend();
384
385 // Look for the maximum element id. Search backwards through
386 // elements so we can break out early. Beware of nullptr entries that
387 // haven't yet been cleared from _elements.
388 for (; rit != rend; ++rit)
389 {
390 const DofObject *d = *rit;
391 if (d)
392 {
393 libmesh_assert(_elements[d->id()] == d);
394 max_local = d->id() + 1;
395 break;
396 }
397 }
398
399 this->comm().max(max_local);
400 return max_local;
401}

References libMesh::DistributedMesh::_elements, libMesh::ParallelObject::comm(), libMesh::DofObject::id(), libMesh::libmesh_assert(), and libMesh::Parallel::Communicator::max().

Referenced by libMesh::DistributedMesh::allgather(), libMesh::DistributedMesh::delete_remote_elements(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_flags(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_object_ids(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_p_levels(), libMesh::DistributedMesh::renumber_nodes_and_elements(), and libMesh::DistributedMesh::update_parallel_id_counts().

◆ parallel_max_node_id()

dof_id_type libMesh::DistributedMesh::parallel_max_node_id ( ) const
inherited

Definition at line 446 of file distributed_mesh.C.

447{
448 // This function must be run on all processors at once
449 parallel_object_only();
450
451 dof_id_type max_local = 0;
452
453 dofobject_container<Node>::const_reverse_veclike_iterator
454 rit = _nodes.rbegin();
455
456 const dofobject_container<Node>::const_reverse_veclike_iterator
457 rend = _nodes.rend();
458
459 // Look for the maximum node id. Search backwards through
460 // nodes so we can break out early. Beware of nullptr entries that
461 // haven't yet been cleared from _nodes
462 for (; rit != rend; ++rit)
463 {
464 const DofObject *d = *rit;
465 if (d)
466 {
467 libmesh_assert(_nodes[d->id()] == d);
468 max_local = d->id() + 1;
469 break;
470 }
471 }
472
473 this->comm().max(max_local);
474 return max_local;
475}

References libMesh::DistributedMesh::_nodes, libMesh::ParallelObject::comm(), libMesh::DofObject::id(), libMesh::libmesh_assert(), and libMesh::Parallel::Communicator::max().

Referenced by libMesh::DistributedMesh::allgather(), libMesh::DistributedMesh::delete_remote_elements(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_object_ids(), libMesh::DistributedMesh::renumber_nodes_and_elements(), and libMesh::DistributedMesh::update_parallel_id_counts().

◆ parallel_max_unique_id()

unique_id_type libMesh::DistributedMesh::parallel_max_unique_id ( ) const
overridevirtualinherited
Returns
A number greater than or equal to the maximum unique_id in the mesh.

Implements libMesh::MeshBase.

Definition at line 406 of file distributed_mesh.C.

407{
408 // This function must be run on all processors at once
409 parallel_object_only();
410
411 unique_id_type max_local = std::max(_next_unique_id,
413 this->comm().max(max_local);
414 return max_local;
415}

References libMesh::MeshBase::_next_unique_id, libMesh::DistributedMesh::_next_unpartitioned_unique_id, libMesh::ParallelObject::comm(), and libMesh::Parallel::Communicator::max().

Referenced by libMesh::DistributedMesh::set_next_unique_ids(), and libMesh::DistributedMesh::update_parallel_id_counts().

◆ parallel_n_elem()

dof_id_type libMesh::DistributedMesh::parallel_n_elem ( ) const
overridevirtualinherited
Returns
The number of elements in the mesh.

The parallel_n_elem() function computes a parallel-synchronized value on distributed meshes, and so must be called in parallel only.

Implements libMesh::MeshBase.

Definition at line 359 of file distributed_mesh.C.

360{
361 // This function must be run on all processors at once
362 parallel_object_only();
363
364 dof_id_type n_local = this->n_local_elem();
365 this->comm().sum(n_local);
366 n_local += this->n_unpartitioned_elem();
367 return n_local;
368}

References libMesh::ParallelObject::comm(), libMesh::MeshBase::n_local_elem(), libMesh::MeshBase::n_unpartitioned_elem(), and libMesh::Parallel::Communicator::sum().

Referenced by libMesh::DistributedMesh::allgather(), libMesh::DistributedMesh::delete_remote_elements(), libMesh::DistributedMesh::renumber_nodes_and_elements(), and libMesh::DistributedMesh::update_parallel_id_counts().

◆ parallel_n_nodes()

dof_id_type libMesh::DistributedMesh::parallel_n_nodes ( ) const
overridevirtualinherited
Returns
The number of nodes in the mesh.

This function and others must be overridden in derived classes since the MeshBase class has no specific storage for nodes or elements. The parallel_n_nodes() function computes a parallel-synchronized value on distributed meshes, and so must be called in parallel only.

Implements libMesh::MeshBase.

Definition at line 433 of file distributed_mesh.C.

434{
435 // This function must be run on all processors at once
436 parallel_object_only();
437
438 dof_id_type n_local = this->n_local_nodes();
439 this->comm().sum(n_local);
440 n_local += this->n_unpartitioned_nodes();
441 return n_local;
442}

References libMesh::ParallelObject::comm(), libMesh::MeshBase::n_local_nodes(), libMesh::MeshBase::n_unpartitioned_nodes(), and libMesh::Parallel::Communicator::sum().

Referenced by libMesh::DistributedMesh::allgather(), libMesh::DistributedMesh::delete_remote_elements(), libMesh::DistributedMesh::renumber_nodes_and_elements(), DisjointNeighborTest::testStitchCrossMesh(), DisjointNeighborTest::testStitchingDiscontinuousBoundaries(), and libMesh::DistributedMesh::update_parallel_id_counts().

◆ partition() [1/2]

void libMesh::MeshBase::partition ( )
inlineinherited

◆ partition() [2/2]

void libMesh::MeshBase::partition ( const unsigned int  n_parts)
virtualinherited

Call the default partitioner (currently metis_partition()).

Definition at line 1784 of file mesh_base.C.

1785{
1786 // If we get here and we have unpartitioned elements, we need that
1787 // fixed.
1788 if (this->n_unpartitioned_elem() > 0)
1789 {
1791 libmesh_assert (this->is_serial());
1792 partitioner()->partition (*this, n_parts);
1793 }
1794 // A nullptr partitioner or a skip_partitioning(true) call or a
1795 // skip_noncritical_partitioning(true) call means don't repartition;
1796 // skip_noncritical_partitioning() checks all these.
1798 {
1799 partitioner()->partition (*this, n_parts);
1800 }
1801 else
1802 {
1803 // Adaptive coarsening may have "orphaned" nodes on processors
1804 // whose elements no longer share them. We need to check for
1805 // and possibly fix that.
1807
1808 // Make sure locally cached partition count is correct
1810
1811 // Make sure any other locally cached data is correct
1813 }
1814
1816}
virtual std::unique_ptr< Partitioner > & partitioner()
A partitioner to use at each partitioning.
Definition mesh_base.h:165
unsigned int recalculate_n_partitions()
In a few (very rare) cases, the user may have manually tagged the elements with specific processor ID...
Definition mesh_base.C:1828
virtual void update_post_partitioning()
Recalculate any cached data (or invalidate any caches that are computed on the fly) after elements an...
Definition mesh_base.C:1181
bool skip_noncritical_partitioning() const
Definition mesh_base.h:1418
void correct_node_proc_ids(MeshBase &)
Changes the processor ids on each node so be the same as the id of the lowest element touching that n...
const Elem & get(const ElemType type_in)

References libMesh::MeshBase::_preparation, libMesh::MeshTools::correct_node_proc_ids(), libMesh::MeshBase::Preparation::is_partitioned, libMesh::MeshBase::is_serial(), libMesh::libmesh_assert(), libMesh::MeshBase::n_unpartitioned_elem(), libMesh::MeshBase::partitioner(), libMesh::MeshBase::recalculate_n_partitions(), libMesh::MeshBase::skip_noncritical_partitioning(), and libMesh::MeshBase::update_post_partitioning().

Referenced by main(), libMesh::split_mesh(), ExtraIntegersTest::test_helper(), MappedSubdomainPartitionerTest::testMappedSubdomainPartitioner(), CheckpointIOTest::testMissingSplitError(), EquationSystemsTest::testRepartitionThenReinit(), and CheckpointIOTest::testSplitter().

◆ partitioner()

virtual std::unique_ptr< Partitioner > & libMesh::MeshBase::partitioner ( )
inlinevirtualinherited

◆ point()

const Point & libMesh::DistributedMesh::point ( const dof_id_type  i) const
finaloverridevirtualinherited
Returns
A constant reference (for reading only) to the \( i^{th} \) point, which should be present in this processor's subset of the mesh data structure.

Implements libMesh::MeshBase.

Definition at line 479 of file distributed_mesh.C.

480{
481 return this->node_ref(i);
482}

References libMesh::MeshBase::node_ref().

◆ post_dofobject_moves()

void libMesh::MeshBase::post_dofobject_moves ( MeshBase &&  other_mesh)
protectedinherited

Moves any superclass data (e.g.

GhostingFunctors that might rely on element and nodal data (which is managed by subclasses!) being already moved first.

Must be manually called in dofobject-managing subclass move operators.

Definition at line 2411 of file mesh_base.C.

2412{
2413 // Now that all the DofObject moving is done, we can move the GhostingFunctor objects
2414 // which include the _default_ghosting,_ghosting_functors and _shared_functors. We also need
2415 // to set the mesh object associated with these functors to the assignee mesh.
2416
2417 // _default_ghosting
2418 _default_ghosting = std::move(other_mesh._default_ghosting);
2419 _default_ghosting->set_mesh(this);
2420
2421 // _ghosting_functors
2422 _ghosting_functors = std::move(other_mesh._ghosting_functors);
2423
2424 for (const auto gf : _ghosting_functors )
2425 {
2426 gf->set_mesh(this);
2427 }
2428
2429 // _shared_functors
2430 _shared_functors = std::move(other_mesh._shared_functors);
2431
2432 for (const auto & sf : _shared_functors )
2433 {
2434 (sf.second)->set_mesh(this);
2435 }
2436
2437 // _constraint_rows
2438 _constraint_rows = std::move(other_mesh._constraint_rows);
2439 _n_constraint_rows = other_mesh._n_constraint_rows;
2440
2441 if (other_mesh.partitioner())
2442 _partitioner = std::move(other_mesh.partitioner());
2443}

References libMesh::MeshBase::_constraint_rows, libMesh::MeshBase::_default_ghosting, libMesh::MeshBase::_ghosting_functors, libMesh::MeshBase::_n_constraint_rows, libMesh::MeshBase::_partitioner, and libMesh::MeshBase::_shared_functors.

Referenced by libMesh::ReplicatedMesh::operator=().

◆ preparation()

Preparation libMesh::MeshBase::preparation ( ) const
inlineinherited

◆ prepare_for_use() [1/3]

void libMesh::MeshBase::prepare_for_use ( )
inherited

◆ prepare_for_use() [2/3]

void libMesh::MeshBase::prepare_for_use ( const bool  skip_renumber_nodes_and_elements)
inherited

Definition at line 843 of file mesh_base.C.

844{
845 libmesh_deprecated();
846
847 // We only respect the users wish if they tell us to skip renumbering. If they tell us not to
848 // skip renumbering but someone previously called allow_renumbering(false), then the latter takes
849 // precedence
850 if (skip_renumber_nodes_and_elements)
851 this->allow_renumbering(false);
852
853 this->prepare_for_use();
854}

References libMesh::MeshBase::allow_renumbering(), and libMesh::MeshBase::prepare_for_use().

◆ prepare_for_use() [3/3]

void libMesh::MeshBase::prepare_for_use ( const bool  skip_renumber_nodes_and_elements,
const bool  skip_find_neighbors 
)
inherited

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

For backwards compatibility, prepare_for_use() performs all those steps, regardless of the official preparation() state of the mesh. In codes which have maintained a valid preparation() state via methods such as unset_has_synched_id_counts(), calling complete_preparation() will result in a fully-prepared mesh at less cost.

The argument to skip renumbering is now deprecated - to prevent a mesh from being renumbered, set allow_renumbering(false). The argument to skip finding neighbors is also deprecated. To prevent find_neighbors, set allow_find_neighbors(false)

If this is a distributed mesh, local copies of remote elements will be deleted here - to keep those elements replicated during preparation, set allow_remote_element_removal(false).

Definition at line 824 of file mesh_base.C.

825{
826 libmesh_deprecated();
827
828 // We only respect the users wish if they tell us to skip renumbering. If they tell us not to
829 // skip renumbering but someone previously called allow_renumbering(false), then the latter takes
830 // precedence
831 if (skip_renumber_nodes_and_elements)
832 this->allow_renumbering(false);
833
834 // We always accept the user's value for skip_find_neighbors, in contrast to skip_renumber
835 const bool old_allow_find_neighbors = this->allow_find_neighbors();
836 this->allow_find_neighbors(!skip_find_neighbors);
837
838 this->prepare_for_use();
839
840 this->allow_find_neighbors(old_allow_find_neighbors);
841}

References libMesh::MeshBase::allow_find_neighbors(), libMesh::MeshBase::allow_renumbering(), and libMesh::MeshBase::prepare_for_use().

Referenced by LinearElasticityWithContact::add_contact_edge_elements(), libMesh::MeshTools::Subdivision::all_subdivision(), libMesh::MeshTools::Modification::all_tri(), ExodusC0PolyhedronTest::build_c0polyhedron(), libMesh::MeshTools::Generation::build_cube(), libMesh::MeshTools::Generation::build_extrusion(), DisjointNeighborTest::build_four_disjoint_elems(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::InfElemBuilder::build_inf_elem(), FEHybridOrientationTest< order, family >::build_mesh(), ExodusC0PolygonTest::build_pentagon(), DisjointNeighborTest::build_split_mesh_with_interface(), DisjointNeighborTest::build_two_disjoint_elems(), VolumeTest::buildC0Polyhedron(), libMesh::UnstructuredMesh::create_submesh(), libMesh::MeshTools::Modification::flatten(), main(), MeshGenerationTest::polyhedronTetNeighbor(), libMesh::MeshTools::Subdivision::prepare_subdivision_mesh(), libMesh::GMVIO::read(), libMesh::SimplexRefiner::refine_elements(), libMesh::C0Polyhedron::retriangulate(), libMesh::MeshTools::Generation::surface_octahedron(), libMesh::BoundaryInfo::sync(), MeshSpatialDimensionTest::test1D(), ConstraintOperatorTest::test1DCoarseningNewNodes(), ConstraintOperatorTest::test1DCoarseningOperator(), MeshSpatialDimensionTest::test2D(), AllTriTest::test_helper_c0polyhedron(), ExodusTest< elem_type >::test_read_gold(), XdrIOTest< elem_type >::test_read_gold(), ExodusTest< elem_type >::test_write(), XdrIOTest< elem_type >::test_write(), ExodusC0PolyhedronTest::test_write_and_read_hexagonal_prism(), ExodusC0PolyhedronTest::test_write_and_read_mixed_hex_tet_block_names_impl(), ExodusC0PolyhedronTest::test_write_and_read_mixed_poly_hex_impl(), ExodusC0PolygonTest::test_write_and_read_pentagon(), MeshInputTest::testAbaqusRead(), AllTriTest::testAllTriC0PolygonOctagon(), SystemsTest::testBlockRestrictedVarNDofs(), BoundaryInfoTest::testBoundaryIDs(), BoundaryInfoTest::testBoundaryOnChildrenBoundaryIDs(), BoundaryInfoTest::testBoundaryOnChildrenBoundarySides(), BoundaryInfoTest::testBoundaryOnChildrenElementsRefineCoarsen(), BoundaryInfoTest::testBoundaryOnChildrenErrors(), CheckpointIOTest::testC0PolygonCheckpoint(), CheckpointIOTest::testC0PolyhedronCheckpoint(), MeshInputTest::testCopyElementSolutionImpl(), MeshInputTest::testCopyElementVectorImpl(), MeshInputTest::testCopyNodalSolutionImpl(), ConstraintOperatorTest::testCoreform(), MeshDeletionsTest::testDeleteElem(), DisjointNeighborTest::testDisjointNeighborConflictError(), CheckpointIOTest::testDisjointNeighborPairsCheckpoint(), SystemsTest::testDofCouplingWithVarGroups(), MeshInputTest::testDynaFileMappings(), MeshInputTest::testDynaNoSplines(), MeshInputTest::testDynaReadElem(), MeshInputTest::testDynaReadPatch(), ConnectedComponentsTest::testEdge(), MeshTriangulationTest::testEdge3Mesh(), MeshTriangulationTest::testEdgesMesh(), MeshInputTest::testExodusCopyHighOrderElementSolution(), MeshInputTest::testExodusFileMappings(), MeshInputTest::testExodusIGASidesets(), MeshInputTest::testExodusWriteElementDataFromDiscontinuousNodalData(), BoundaryInfoTest::testInternalBoundary(), MeshInputTest::testLowOrderEdgeBlocks(), MeshInputTest::testNemesisReadImpl(), MeshTetTest::testNetGenQuadraticCurved(), MeshTetTest::testNetGenTet14Curved(), NodalNeighborsTest::testOrientation(), PeriodicBCTest::testPeriodicBC(), MeshTriangulationTest::testPoly2TriBad1DMultiBoundary(), MeshTriangulationTest::testPoly2TriBad2DMultiBoundary(), MeshTriangulationTest::testPoly2TriBadEdges(), MeshTriangulationTest::testPoly2TriEdge3ToTri6FlipThrows(), EquationSystemsTest::testPostInitAddElem(), SystemsTest::testProjectMatrix3D(), SystemsTest::testProjectScalarCoarsening(), InfFERadialTest::testRefinement(), EquationSystemsTest::testReinitWithNodeElem(), SystemsTest::testSetSystemParameterOverEquationSystem(), BoundaryInfoTest::testShellFaceConstraints(), MeshInputTest::testSingleElementImpl(), DisjointNeighborTest::testStitchCrossMesh(), MeshInputTest::testTetgenIO(), MeshTetTest::testTetsToTets(), MeshTetTest::testTrisToTetsError(), MeshInputTest::testVTKPreserveElemIds(), MeshInputTest::testVTKPreserveSubdomainIds(), MeshInputTest::testVTKReadPolyhedra(), MeshInputTest::testVTKReadPolyhedraSerial(), tetrahedralize_domain(), libMesh::NetGenMeshInterface::triangulate(), libMesh::TriangleInterface::triangulate(), libMesh::Poly2TriTriangulator::triangulate(), and libMesh::MeshTetInterface::volume_to_surface_mesh().

◆ print_constraint_rows()

void libMesh::MeshBase::print_constraint_rows ( std::ostream &  os = libMesh::out,
bool  print_nonlocal = false 
) const
inherited

Prints (from processor 0) all mesh constraint rows.

If print_nonlocal is true, then each constraint is printed once for each processor that knows about it, which may be useful for DistributedMesh debugging.

Definition at line 2803 of file mesh_base.C.

2805{
2806 parallel_object_only();
2807
2808 std::string local_constraints =
2809 this->get_local_constraints(print_nonlocal);
2810
2811 if (this->processor_id())
2812 {
2813 this->comm().send(0, local_constraints);
2814 }
2815 else
2816 {
2817 os << "Processor 0:\n";
2818 os << local_constraints;
2819
2820 for (auto p : IntRange<processor_id_type>(1, this->n_processors()))
2821 {
2822 this->comm().receive(p, local_constraints);
2823 os << "Processor " << p << ":\n";
2824 os << local_constraints;
2825 }
2826 }
2827}
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
void send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
std::string get_local_constraints(bool print_nonlocal=false) const
Gets a string reporting all mesh constraint rows local to this processor.
Definition mesh_base.C:2831

References libMesh::ParallelObject::comm(), libMesh::MeshBase::get_local_constraints(), libMesh::ParallelObject::n_processors(), libMesh::ParallelObject::processor_id(), libMesh::Parallel::Communicator::receive(), and libMesh::Parallel::Communicator::send().

◆ print_info()

void libMesh::MeshBase::print_info ( std::ostream &  os = libMesh::out,
const unsigned int  verbosity = 0,
const bool  global = true 
) const
inherited

Prints relevant information about the mesh.

Take note of the docstring for get_info() for more information pretaining to the verbosity and global parameters.

Definition at line 1770 of file mesh_base.C.

1771{
1772 os << this->get_info(verbosity, global)
1773 << std::endl;
1774}
std::string get_info(const unsigned int verbosity=0, const bool global=true) const
Definition mesh_base.C:1276

References libMesh::MeshBase::get_info().

Referenced by assemble_and_solve(), libMesh::InfElemBuilder::build_inf_elem(), main(), main(), and setup().

◆ processor_id()

processor_id_type libMesh::ParallelObject::processor_id ( ) const
inlineinherited
Returns
The rank of this processor in the group.

Definition at line 114 of file parallel_object.h.

115 { return cast_int<processor_id_type>(_communicator.rank()); }
processor_id_type rank() const

References libMesh::ParallelObject::_communicator, and libMesh::Parallel::Communicator::rank().

Referenced by libMesh::BoundaryInfo::_find_id_maps(), libMesh::PetscDMWrapper::add_dofs_to_section(), libMesh::DistributedMesh::add_elem(), libMesh::BoundaryInfo::add_elements(), libMesh::DistributedMesh::add_node(), libMesh::MeshTools::Modification::all_tri(), libMesh::FEMSystem::assembly(), libMesh::Nemesis_IO::assert_symmetric_cmaps(), libMesh::Partitioner::assign_partitioning(), libMesh::Nemesis_IO_Helper::build_element_and_node_maps(), libMesh::Partitioner::build_graph(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::BoundaryInfo::build_node_list_from_side_list(), libMesh::EquationSystems::build_parallel_elemental_solution_vector(), libMesh::EquationSystems::build_parallel_solution_vector(), libMesh::MeshFunction::check_found_elem(), libMesh::DistributedMesh::clear(), libMesh::DistributedMesh::clear_elems(), libMesh::ExodusII_IO_Helper::close(), libMesh::Nemesis_IO_Helper::compute_border_node_ids(), libMesh::Nemesis_IO_Helper::compute_communication_map_parameters(), libMesh::Nemesis_IO_Helper::compute_internal_and_border_elems_and_internal_nodes(), libMesh::RBConstruction::compute_max_error_bound(), libMesh::Nemesis_IO_Helper::compute_node_communication_maps(), libMesh::Nemesis_IO_Helper::compute_num_global_elem_blocks(), libMesh::Nemesis_IO_Helper::compute_num_global_nodesets(), libMesh::Nemesis_IO_Helper::compute_num_global_sidesets(), libMesh::Nemesis_IO_Helper::construct_nemesis_filename(), libMesh::ExodusII_IO::copy_elemental_solution(), libMesh::ExodusII_IO::copy_nodal_solution(), libMesh::ExodusII_IO::copy_scalar_solution(), libMesh::Nemesis_IO::copy_scalar_solution(), libMesh::MeshTools::correct_node_proc_ids(), libMesh::MeshBase::count_constraint_rows(), libMesh::ExodusII_IO_Helper::create(), libMesh::MeshCommunication::delete_remote_elements(), libMesh::DistributedMesh::DistributedMesh(), libMesh::DofMapBase::end_dof(), libMesh::DofMapBase::end_old_dof(), libMesh::EnsightIO::EnsightIO(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::find_dofs_to_send(), libMesh::UnstructuredMesh::find_neighbors(), libMesh::DofMapBase::first_dof(), libMesh::DofMapBase::first_old_dof(), libMesh::RBEIMEvaluation::gather_bfs(), libMesh::Nemesis_IO_Helper::get_cmap_params(), libMesh::Nemesis_IO_Helper::get_eb_info_global(), libMesh::Nemesis_IO_Helper::get_elem_cmap(), libMesh::Nemesis_IO_Helper::get_elem_map(), libMesh::MeshBase::get_info(), libMesh::Nemesis_IO_Helper::get_init_global(), libMesh::Nemesis_IO_Helper::get_init_info(), libMesh::RBEIMEvaluation::get_interior_basis_functions_as_vecs(), libMesh::Nemesis_IO_Helper::get_loadbal_param(), libMesh::DofMap::get_local_constraints(), libMesh::MeshBase::get_local_constraints(), libMesh::Nemesis_IO_Helper::get_node_cmap(), libMesh::Nemesis_IO_Helper::get_node_map(), libMesh::Nemesis_IO_Helper::get_ns_param_global(), libMesh::Nemesis_IO_Helper::get_ss_param_global(), libMesh::SparsityPattern::Build::handle_vi_vj(), libMesh::LaplaceMeshSmoother::init(), libMesh::SystemSubsetBySubdomain::init(), HeatSystem::init_data(), libMesh::ExodusII_IO_Helper::initialize(), libMesh::ExodusII_IO_Helper::initialize_element_variables(), libMesh::ExodusII_IO_Helper::initialize_global_variables(), libMesh::ExodusII_IO_Helper::initialize_nodal_variables(), libMesh::DistributedMesh::insert_elem(), libMesh::MeshTools::Modification::interpolate_surface(), libMesh::SparsityPattern::Build::join(), libMesh::RBEvaluation::legacy_write_offline_data_to_files(), libMesh::RBSCMEvaluation::legacy_write_offline_data_to_files(), libMesh::TransientRBEvaluation::legacy_write_offline_data_to_files(), libMesh::MeshTools::libmesh_assert_consistent_distributed(), libMesh::MeshTools::libmesh_assert_consistent_distributed_nodes(), libMesh::MeshTools::libmesh_assert_contiguous_dof_ids(), libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Elem >(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_object_ids(), main(), AugmentSparsityOnInterface::mesh_reinit(), libMesh::TriangulatorInterface::MeshedHole::MeshedHole(), libMesh::MeshBase::n_active_local_elem(), libMesh::BoundaryInfo::n_boundary_conds(), libMesh::MeshTools::n_connected_components(), libMesh::BoundaryInfo::n_edge_conds(), libMesh::DofMapBase::n_local_dofs(), libMesh::MeshBase::n_local_elem(), libMesh::MeshBase::n_local_nodes(), libMesh::BoundaryInfo::n_nodeset_conds(), libMesh::BoundaryInfo::n_shellface_conds(), libMesh::RBEIMEvaluation::node_gather_bfs(), libMesh::DistributedMesh::own_node(), libMesh::BoundaryInfo::parallel_sync_node_ids(), libMesh::BoundaryInfo::parallel_sync_side_ids(), libMesh::MeshBase::print_constraint_rows(), libMesh::DofMap::print_dof_constraints(), libMesh::DofMap::process_mesh_constraint_rows(), libMesh::Nemesis_IO_Helper::put_cmap_params(), libMesh::Nemesis_IO_Helper::put_elem_cmap(), libMesh::Nemesis_IO_Helper::put_elem_map(), libMesh::Nemesis_IO_Helper::put_loadbal_param(), libMesh::Nemesis_IO_Helper::put_node_cmap(), libMesh::Nemesis_IO_Helper::put_node_map(), libMesh::XdrIO::read(), libMesh::Nemesis_IO::read(), libMesh::CheckpointIO::read(), libMesh::NameBasedIO::read(), libMesh::EquationSystems::read(), libMesh::EquationSystems::read(), libMesh::ExodusII_IO_Helper::read_elem_num_map(), libMesh::ExodusII_IO_Helper::read_global_values(), libMesh::CheckpointIO::read_header(), libMesh::ExodusII_IO::read_header(), libMesh::System::read_header(), libMesh::XdrIO::read_header(), libMesh::DynaIO::read_mesh(), libMesh::ExodusII_IO_Helper::read_node_num_map(), libMesh::System::read_parallel_data(), libMesh::RBConstruction::read_riesz_representors_from_files(), libMesh::TransientRBConstruction::read_riesz_representors_from_files(), libMesh::System::read_SCALAR_dofs(), libMesh::XdrIO::read_serialized_bc_names(), libMesh::XdrIO::read_serialized_bcs_helper(), libMesh::System::read_serialized_blocked_dof_objects(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::System::read_serialized_data(), libMesh::XdrIO::read_serialized_nodes(), libMesh::XdrIO::read_serialized_nodesets(), libMesh::XdrIO::read_serialized_subdomain_names(), libMesh::System::read_serialized_vector(), libMesh::System::read_serialized_vectors(), libMesh::Nemesis_IO_Helper::read_var_names_impl(), libMesh::SimplexRefiner::refine_via_edges(), libMesh::SimplexRefiner::refine_via_edges(), libMesh::StaticCondensationDofMap::reinit(), libMesh::DistributedMesh::renumber_dof_objects(), libMesh::DistributedMesh::renumber_nodes_and_elements(), libMesh::DofMap::scatter_constraints(), libMesh::CheckpointIO::select_split_config(), libMesh::DistributedMesh::set_next_ids(), libMesh::DistributedMesh::set_next_unique_id(), libMesh::DistributedMesh::set_next_unique_ids(), libMesh::DofMap::set_nonlocal_dof_objects(), libMesh::PetscDMWrapper::set_point_range_in_section(), libMesh::RBEIMEvaluation::side_gather_bfs(), MeshFunctionTest::test_bad_gradient_var_with_out_of_mesh_value(), MeshFunctionTest::test_bad_hessian_var_with_out_of_mesh_value(), ExodusTest< elem_type >::test_read_gold(), ExodusTest< elem_type >::test_write(), ExodusC0PolyhedronTest::test_write_and_read_hexagonal_prism(), ExodusC0PolyhedronTest::test_write_and_read_mixed_hex_tet_block_names_impl(), ExodusC0PolygonTest::test_write_and_read_pentagon(), MeshInputTest::testAbaqusRead(), MeshInputTest::testBadGmsh(), BoundaryInfoTest::testBoundaryIDs(), MeshInputTest::testCopyElementSolutionImpl(), MeshInputTest::testCopyElementVectorImpl(), MeshInputTest::testCopyNodalSolutionImpl(), DefaultCouplingTest::testCoupling(), PointNeighborCouplingTest::testCoupling(), MeshInputTest::testDynaFileMappings(), MeshInputTest::testDynaNoSplines(), MeshInputTest::testDynaReadElem(), MeshInputTest::testDynaReadPatch(), MeshInputTest::testExodusCopyHighOrderElementSolution(), MeshInputTest::testExodusFileMappings(), MeshInputTest::testExodusIGASidesets(), MeshInputTest::testExodusWriteElementDataFromDiscontinuousNodalData(), DofMapTest::testGhostConstraintSendList(), MeshInputTest::testGmshBCIDOverlap(), MeshInputTest::testGoodGmsh(), MeshInputTest::testGoodSTL(), MeshInputTest::testGoodSTLBinary(), BoundaryInfoTest::testInternalBoundary(), MeshInputTest::testLowOrderEdgeBlocks(), BoundaryMeshSubdomainTest::testPerBoundarySubdomain(), SystemsTest::testProjectMatrix3D(), BoundaryInfoTest::testShellFaceConstraints(), MeshInputTest::testSingleElementImpl(), BoundaryMeshSubdomainTest::testSingleSubdomain(), WriteVecAndScalar::testSolution(), CheckpointIOTest::testSplitter(), MeshInputTest::testTetgenIO(), MeshSmootherTest::testVariationalSmoother(), libMesh::MeshTools::total_weight(), libMesh::NetGenMeshInterface::triangulate(), libMesh::Parallel::Packing< Elem * >::unpack(), libMesh::Parallel::Packing< Node * >::unpack(), libMesh::DTKAdapter::update_variable_values(), libMesh::MeshTools::volume(), libMesh::STLIO::write(), libMesh::XdrIO::write(), libMesh::NameBasedIO::write(), libMesh::CheckpointIO::write(), libMesh::EquationSystems::write(), libMesh::EquationSystems::write(), libMesh::GMVIO::write_discontinuous_gmv(), libMesh::ExodusII_IO::write_element_data(), libMesh::ExodusII_IO::write_element_data_from_discontinuous_nodal_data(), libMesh::ExodusII_IO_Helper::write_element_values(), libMesh::ExodusII_IO_Helper::write_element_values_element_major(), libMesh::ExodusII_IO_Helper::write_elements(), libMesh::ExodusII_IO_Helper::write_elemset_data(), libMesh::ExodusII_IO_Helper::write_elemsets(), libMesh::ExodusII_IO::write_global_data(), libMesh::ExodusII_IO_Helper::write_global_values(), libMesh::System::write_header(), libMesh::ExodusII_IO::write_information_records(), libMesh::ExodusII_IO_Helper::write_information_records(), libMesh::ExodusII_IO_Helper::write_nodal_coordinates(), libMesh::ExodusII_IO::write_nodal_data(), libMesh::VTKIO::write_nodal_data(), libMesh::UCDIO::write_nodal_data(), libMesh::ExodusII_IO::write_nodal_data_common(), libMesh::ExodusII_IO::write_nodal_data_discontinuous(), libMesh::ExodusII_IO_Helper::write_nodal_values(), libMesh::ExodusII_IO_Helper::write_nodeset_data(), libMesh::ExodusII_IO_Helper::write_nodesets(), libMesh::Nemesis_IO_Helper::write_nodesets(), libMesh::RBEIMEvaluation::write_out_interior_basis_functions(), libMesh::RBEIMEvaluation::write_out_node_basis_functions(), libMesh::RBEIMEvaluation::write_out_side_basis_functions(), write_output_solvedata(), libMesh::System::write_parallel_data(), libMesh::RBConstruction::write_riesz_representors_to_files(), libMesh::System::write_SCALAR_dofs(), libMesh::XdrIO::write_serialized_bc_names(), libMesh::XdrIO::write_serialized_bcs_helper(), libMesh::System::write_serialized_blocked_dof_objects(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::System::write_serialized_data(), libMesh::XdrIO::write_serialized_nodes(), libMesh::XdrIO::write_serialized_nodesets(), libMesh::XdrIO::write_serialized_subdomain_names(), libMesh::System::write_serialized_vector(), libMesh::System::write_serialized_vectors(), libMesh::ExodusII_IO_Helper::write_sideset_data(), libMesh::ExodusII_IO_Helper::write_sidesets(), libMesh::Nemesis_IO_Helper::write_sidesets(), libMesh::ExodusII_IO::write_timestep(), libMesh::ExodusII_IO_Helper::write_timestep(), and libMesh::ExodusII_IO::write_timestep_discontinuous().

◆ query_elem_ptr() [1/2]

const Elem * libMesh::DistributedMesh::query_elem_ptr ( const dof_id_type  i) const
finaloverridevirtualinherited
Returns
A pointer to the \( i^{th} \) element, or nullptr if no such element exists in this processor's mesh data structure.

Implements libMesh::MeshBase.

Definition at line 562 of file distributed_mesh.C.

563{
564 if (const auto it = _elements.find(i);
565 it != _elements.end())
566 {
567 const Elem * e = *it;
568 libmesh_assert (!e || e->id() == i);
569 return e;
570 }
571
572 return nullptr;
573}

References libMesh::DistributedMesh::_elements, libMesh::DofObject::id(), and libMesh::libmesh_assert().

Referenced by libMesh::DistributedMesh::subclass_locally_equals(), ExodusC0PolyhedronTest::test_write_and_read_hexagonal_prism(), and ExodusC0PolygonTest::test_write_and_read_pentagon().

◆ query_elem_ptr() [2/2]

Elem * libMesh::DistributedMesh::query_elem_ptr ( const dof_id_type  i)
finaloverridevirtualinherited
Returns
A writable pointer to the \( i^{th} \) element, or nullptr if no such element exists in this processor's mesh data structure.

Implements libMesh::MeshBase.

Definition at line 578 of file distributed_mesh.C.

579{
580 if (auto it = _elements.find(i);
581 it != _elements.end())
582 {
583 Elem * e = *it;
584 libmesh_assert (!e || e->id() == i);
585 return e;
586 }
587
588 return nullptr;
589}

References libMesh::DistributedMesh::_elements, libMesh::DofObject::id(), and libMesh::libmesh_assert().

◆ query_node_ptr() [1/2]

const Node * libMesh::DistributedMesh::query_node_ptr ( const dof_id_type  i) const
finaloverridevirtualinherited
Returns
A pointer to the \( i^{th} \) node, or nullptr if no such node exists in this processor's mesh data structure.

Implements libMesh::MeshBase.

Definition at line 508 of file distributed_mesh.C.

509{
510 if (const auto it = _nodes.find(i);
511 it != _nodes.end())
512 {
513 const Node * n = *it;
514 libmesh_assert (!n || n->id() == i);
515 return n;
516 }
517
518 return nullptr;
519}

References libMesh::DistributedMesh::_nodes, libMesh::DofObject::id(), and libMesh::libmesh_assert().

Referenced by libMesh::DistributedMesh::add_point().

◆ query_node_ptr() [2/2]

Node * libMesh::DistributedMesh::query_node_ptr ( const dof_id_type  i)
finaloverridevirtualinherited
Returns
A writable pointer to the \( i^{th} \) node, or nullptr if no such node exists in this processor's mesh data structure.

Implements libMesh::MeshBase.

Definition at line 524 of file distributed_mesh.C.

525{
526 if (auto it = _nodes.find(i);
527 it != _nodes.end())
528 {
529 Node * n = *it;
530 libmesh_assert (!n || n->id() == i);
531 return n;
532 }
533
534 return nullptr;
535}

References libMesh::DistributedMesh::_nodes, libMesh::DofObject::id(), and libMesh::libmesh_assert().

◆ read()

void libMesh::UnstructuredMesh::read ( const std::string &  name,
void *  mesh_data = nullptr,
bool  skip_renumber_nodes_and_elements = false,
bool  skip_find_neighbors = false,
bool  skip_detect_interior_parents = false 
)
overridevirtualinherited

Reads the file specified by name.

Attempts to figure out the proper method by the file extension. This is now the only way to read a mesh. The UnstructuredMesh then initializes its data structures and is ready for use.

The skip_renumber_nodes_and_elements argument is now deprecated - to disallow renumbering, set MeshBase::allow_renumbering(false).

Set skip_find_neighbors=true to skip the find-neighbors operation during prepare_for_use. This operation isn't always necessary and it can be time-consuming, which is why we provide an option to skip it.

Implements libMesh::MeshBase.

Definition at line 1410 of file unstructured_mesh.C.

1415{
1416 // Set the skip_renumber_nodes_and_elements flag on all processors
1417 // if necessary.
1418 // This ensures that renumber_nodes_and_elements is *not* called
1419 // during prepare_for_use() for certain types of mesh files.
1420 // This is required in cases where there is an associated solution
1421 // file which expects a certain ordering of the nodes.
1422 if (Utility::ends_with(name, ".gmv"))
1423 this->allow_renumbering(false);
1424
1425 NameBasedIO(*this).read(name);
1426
1427 if (skip_renumber_nodes_and_elements)
1428 {
1429 // Use MeshBase::allow_renumbering() yourself instead.
1430 libmesh_deprecated();
1431 this->allow_renumbering(false);
1432 }
1433
1434 // Done reading the mesh. Now prepare it for use.
1435 const bool old_allow_find_neighbors = this->allow_find_neighbors();
1436 const bool old_allow_detect_interior_parents = this->allow_detect_interior_parents();
1437
1438 this->allow_find_neighbors(!skip_find_neighbors);
1439 this->allow_detect_interior_parents(!skip_detect_interior_parents);
1440
1441 this->prepare_for_use();
1442
1443 this->allow_find_neighbors(old_allow_find_neighbors);
1444 this->allow_detect_interior_parents(old_allow_detect_interior_parents);
1445}
virtual void read(const std::string &mesh_file) override
This method implements reading a mesh from a specified file.
bool ends_with(std::string_view superstring, std::string_view suffix)
Look for a substring at the very end of a string.
Definition utility.C:213

References libMesh::MeshBase::allow_detect_interior_parents(), libMesh::MeshBase::allow_find_neighbors(), libMesh::MeshBase::allow_renumbering(), libMesh::Utility::ends_with(), libMesh::MeshBase::prepare_for_use(), and libMesh::NameBasedIO::read().

Referenced by ExtraIntegersTest::checkpoint_helper(), main(), ExtraIntegersTest::test_helper(), MeshStitchTest::testNodeElemStitch(), SlitMeshRefinedSystemTest::testRestart(), and WriteElemsetData::testWriteImpl().

◆ recalculate_n_partitions()

unsigned int libMesh::MeshBase::recalculate_n_partitions ( )
inherited

In a few (very rare) cases, the user may have manually tagged the elements with specific processor IDs by hand, without using a partitioner.

In this case, the Mesh will not know that the total number of partitions, _n_parts, has changed, unless you call this function. This is an O(N active elements) calculation. The return value is the number of partitions, and _n_parts is also set by this function.

Definition at line 1828 of file mesh_base.C.

1829{
1830 // This requires an inspection on every processor
1831 parallel_object_only();
1832
1833 unsigned int max_proc_id=0;
1834
1835 for (const auto & elem : this->active_local_element_ptr_range())
1836 max_proc_id = std::max(max_proc_id, static_cast<unsigned int>(elem->processor_id()));
1837
1838 // The number of partitions is one more than the max processor ID.
1839 _n_parts = max_proc_id+1;
1840
1841 this->comm().max(_n_parts);
1842
1843 return _n_parts;
1844}

References libMesh::MeshBase::_n_parts, libMesh::ParallelObject::comm(), and libMesh::Parallel::Communicator::max().

Referenced by libMesh::MeshBase::partition(), and libMesh::CheckpointIO::read().

◆ redistribute()

void libMesh::DistributedMesh::redistribute ( )
overridevirtualinherited

Redistribute elements between processors.

This gets called automatically by the Partitioner, and is a no-op in the case of a serialized mesh.

Reimplemented from libMesh::MeshBase.

Definition at line 1111 of file distributed_mesh.C.

1112{
1113 // If this is a truly parallel mesh, go through the redistribution/gather/delete remote steps
1114 if (!this->is_serial())
1115 {
1116 // Construct a MeshCommunication object to actually redistribute the nodes
1117 // and elements according to the partitioner, and then to re-gather the neighbors.
1118 MeshCommunication mc;
1119 mc.redistribute(*this);
1120
1122
1123 // We communicate valid neighbor links for newly-redistributed
1124 // elements, but we may still have remote_elem links that should
1125 // be corrected but whose correction wasn't communicated.
1126 this->find_neighbors(/*reset_remote_elements*/ false,
1127 /*reset_current_list*/ false /*non-default*/,
1128 /*assert_valid*/ false,
1129 /*check_non_remote*/ false /*non-default!*/);
1130
1131 // Is this necessary? If we are called from prepare_for_use(), this will be called
1132 // anyway... but users can always call partition directly, in which case we do need
1133 // to call delete_remote_elements()...
1134 //
1135 // Regardless of whether it's necessary, it isn't safe. We
1136 // haven't communicated new node processor_ids yet, and we can't
1137 // delete nodes until we do.
1138 // this->delete_remote_elements();
1139 }
1140 else
1141 // The base class can handle non-distributed things, like
1142 // notifying any GhostingFunctors of changes
1144}
virtual bool is_serial() const override final
virtual void redistribute()
Redistribute elements between processors.
Definition mesh_base.C:1169
virtual void find_neighbors(const bool reset_remote_elements=false, const bool reset_current_list=true, const bool assert_valid=true, const bool check_non_remote=true) override
Other functions from MeshBase requiring re-definition.

References libMesh::UnstructuredMesh::find_neighbors(), libMesh::DistributedMesh::is_serial(), libMesh::MeshBase::redistribute(), libMesh::MeshCommunication::redistribute(), and libMesh::DistributedMesh::update_parallel_id_counts().

◆ reinit_ghosting_functors()

void libMesh::MeshBase::reinit_ghosting_functors ( )
inherited

Loops over ghosting functors and calls mesh_reinit()

Definition at line 1025 of file mesh_base.C.

1026{
1027 for (auto & gf : _ghosting_functors)
1028 {
1029 libmesh_assert(gf);
1030 gf->mesh_reinit();
1031 }
1032
1034}

References libMesh::MeshBase::_ghosting_functors, libMesh::MeshBase::_preparation, libMesh::MeshBase::Preparation::has_reinit_ghosting_functors, and libMesh::libmesh_assert().

Referenced by libMesh::MeshBase::complete_preparation().

◆ remove_disjoint_boundary_pair()

void libMesh::MeshBase::remove_disjoint_boundary_pair ( const boundary_id_type  b1,
const boundary_id_type  b2 
)
inherited

Definition at line 2321 of file mesh_base.C.

2323 {
2324 // Nothing to remove if not allocated or empty
2326 return;
2327
2328 auto & pairs = *_disjoint_neighbor_boundary_pairs;
2329
2330 // Helper to check and erase both directions
2331 auto erase_if_match = [](boundary_id_type key,
2332 boundary_id_type pair,
2333 PeriodicBoundaries & pb_map)
2334 {
2335 auto it = pb_map.find(key);
2336 if (it != pb_map.end())
2337 {
2338 const auto & pb = *(it->second);
2339 // Check both directions
2340 if ((pb.myboundary == key && pb.pairedboundary == pair) ||
2341 (pb.pairedboundary == key && pb.myboundary == pair))
2342 pb_map.erase(it);
2343 }
2344 };
2345
2346 erase_if_match(b1, b2, pairs);
2347 erase_if_match(b2, b1, pairs);
2348 }
int8_t boundary_id_type
Definition id_types.h:51

References libMesh::MeshBase::_disjoint_neighbor_boundary_pairs.

Referenced by libMesh::UnstructuredMesh::stitching_helper().

◆ remove_ghosting_functor()

void libMesh::MeshBase::remove_ghosting_functor ( GhostingFunctor &  ghosting_functor)
inherited

Removes a functor which was previously added to the set of ghosting functors.

Definition at line 1101 of file mesh_base.C.

1102{
1103 auto raw_it = std::find(_ghosting_functors.begin(),
1104 _ghosting_functors.end(), &ghosting_functor);
1105
1106 // The DofMap has a "to_mesh" parameter that tells it to avoid
1107 // registering a new functor with the mesh, but it doesn't keep
1108 // track of which functors weren't added, so we'll support "remove a
1109 // functor that isn't there" just like we did with set::erase
1110 // before.
1111 if (raw_it != _ghosting_functors.end())
1112 _ghosting_functors.erase(raw_it);
1113
1114 // We shouldn't have had two copies of the same functor
1115 libmesh_assert(std::find(_ghosting_functors.begin(),
1116 _ghosting_functors.end(),
1117 &ghosting_functor) ==
1118 _ghosting_functors.end());
1119
1120 if (const auto it = _shared_functors.find(&ghosting_functor);
1121 it != _shared_functors.end())
1122 _shared_functors.erase(it);
1123}

References libMesh::MeshBase::_ghosting_functors, libMesh::MeshBase::_shared_functors, and libMesh::libmesh_assert().

Referenced by EquationSystemsTest::testDisableDefaultGhosting(), and libMesh::DofMap::~DofMap().

◆ remove_orphaned_nodes()

void libMesh::MeshBase::remove_orphaned_nodes ( )
inherited

Removes any orphaned nodes, nodes not connected to any elements.

Typically done automatically in a preparation step

Definition at line 801 of file mesh_base.C.

802{
803 LOG_SCOPE("remove_orphaned_nodes()", "MeshBase");
804
805 // Will hold the set of nodes that are currently connected to elements
806 std::unordered_set<Node *> connected_nodes;
807
808 // Loop over the elements. Find which nodes are connected to at
809 // least one of them.
810 for (const auto & element : this->element_ptr_range())
811 for (auto & n : element->node_ref_range())
812 connected_nodes.insert(&n);
813
814 for (const auto & node : this->node_ptr_range())
815 if (!connected_nodes.count(node))
816 this->delete_node(node);
817
819}

References libMesh::MeshBase::_preparation, libMesh::MeshBase::delete_node(), and libMesh::MeshBase::Preparation::has_removed_orphaned_nodes.

Referenced by libMesh::MeshBase::complete_preparation().

◆ renumber_dof_objects()

template<typename T >
dof_id_type libMesh::DistributedMesh::renumber_dof_objects ( dofobject_container< T > &  objects)
inherited

Renumber a parallel objects container.

Returns
The smallest globally unused id for that container.

Definition at line 1281 of file distributed_mesh.C.

1282{
1283 // This function must be run on all processors at once
1284 parallel_object_only();
1285
1286 typedef typename dofobject_container<T>::veclike_iterator object_iterator;
1287
1288 // In parallel we may not know what objects other processors have.
1289 // Start by figuring out how many
1290 dof_id_type unpartitioned_objects = 0;
1291
1292 std::unordered_map<processor_id_type, dof_id_type>
1293 ghost_objects_from_proc;
1294
1295 object_iterator it = objects.begin();
1296 object_iterator end = objects.end();
1297
1298 while (it != end)
1299 {
1300 T * obj = *it;
1301
1302 // Remove any nullptr container entries while we're here.
1303 if (!obj)
1304 it = objects.erase(it);
1305 else
1306 {
1307 processor_id_type obj_procid = obj->processor_id();
1308 if (obj_procid == DofObject::invalid_processor_id)
1309 unpartitioned_objects++;
1310 else
1311 ghost_objects_from_proc[obj_procid]++;
1312
1313 // Finally, increment the iterator
1314 ++it;
1315 }
1316 }
1317
1318 std::vector<dof_id_type> objects_on_proc(this->n_processors(), 0);
1319 auto this_it = ghost_objects_from_proc.find(this->processor_id());
1320 this->comm().allgather
1321 ((this_it == ghost_objects_from_proc.end()) ?
1322 dof_id_type(0) : this_it->second, objects_on_proc);
1323
1324#ifndef NDEBUG
1325 libmesh_assert(this->comm().verify(unpartitioned_objects));
1326 for (processor_id_type p=0, np=this->n_processors(); p != np; ++p)
1327 if (ghost_objects_from_proc.count(p))
1328 libmesh_assert_less_equal (ghost_objects_from_proc[p], objects_on_proc[p]);
1329 else
1330 libmesh_assert_less_equal (0, objects_on_proc[p]);
1331#endif
1332
1333 // We'll renumber objects in blocks by processor id
1334 std::vector<dof_id_type> first_object_on_proc(this->n_processors());
1335 for (processor_id_type i=1, np=this->n_processors(); i != np; ++i)
1336 first_object_on_proc[i] = first_object_on_proc[i-1] +
1337 objects_on_proc[i-1];
1338 dof_id_type next_id = first_object_on_proc[this->processor_id()];
1339 dof_id_type first_free_id =
1340 first_object_on_proc[this->n_processors()-1] +
1341 objects_on_proc[this->n_processors()-1] +
1342 unpartitioned_objects;
1343
1344 // First set new local object ids and build request sets
1345 // for non-local object ids
1346
1347 // Request sets to send to each processor
1348 std::map<processor_id_type, std::vector<dof_id_type>>
1349 requested_ids;
1350
1351 // We know how many objects live on each processor, so reserve() space for
1352 // each.
1353 auto ghost_end = ghost_objects_from_proc.end();
1354 for (auto p : make_range(this->n_processors()))
1355 if (p != this->processor_id())
1356 {
1357 if (const auto p_it = ghost_objects_from_proc.find(p);
1358 p_it != ghost_end)
1359 requested_ids[p].reserve(p_it->second);
1360 }
1361
1362 end = objects.end();
1363 for (it = objects.begin(); it != end; ++it)
1364 {
1365 T * obj = *it;
1366 if (!obj)
1367 continue;
1368 if (obj->processor_id() == this->processor_id())
1369 obj->set_id(next_id++);
1370 else if (obj->processor_id() != DofObject::invalid_processor_id)
1371 requested_ids[obj->processor_id()].push_back(obj->id());
1372 }
1373
1374 // Next set ghost object ids from other processors
1375
1376 auto gather_functor =
1377 [
1378#ifndef NDEBUG
1379 this,
1380 &first_object_on_proc,
1381 &objects_on_proc,
1382#endif
1383 &objects]
1384 (processor_id_type, const std::vector<dof_id_type> & ids,
1385 std::vector<dof_id_type> & new_ids)
1386 {
1387 std::size_t ids_size = ids.size();
1388 new_ids.resize(ids_size);
1389
1390 for (std::size_t i=0; i != ids_size; ++i)
1391 {
1392 T * obj = objects[ids[i]];
1393 libmesh_assert(obj);
1394 libmesh_assert_equal_to (obj->processor_id(), this->processor_id());
1395 new_ids[i] = obj->id();
1396
1397 libmesh_assert_greater_equal (new_ids[i],
1398 first_object_on_proc[this->processor_id()]);
1399 libmesh_assert_less (new_ids[i],
1400 first_object_on_proc[this->processor_id()] +
1401 objects_on_proc[this->processor_id()]);
1402 }
1403 };
1404
1405 auto action_functor =
1406 [
1407#ifndef NDEBUG
1408 &first_object_on_proc,
1409 &objects_on_proc,
1410#endif
1411 &objects]
1412 (processor_id_type libmesh_dbg_var(pid),
1413 const std::vector<dof_id_type> & ids,
1414 const std::vector<dof_id_type> & data)
1415 {
1416 // Copy the id changes we've now been informed of
1417 for (auto i : index_range(ids))
1418 {
1419 T * obj = objects[ids[i]];
1420 libmesh_assert (obj);
1421 libmesh_assert_equal_to (obj->processor_id(), pid);
1422 libmesh_assert_greater_equal (data[i],
1423 first_object_on_proc[pid]);
1424 libmesh_assert_less (data[i],
1425 first_object_on_proc[pid] +
1426 objects_on_proc[pid]);
1427 obj->set_id(data[i]);
1428 }
1429 };
1430
1431 const dof_id_type * ex = nullptr;
1433 (this->comm(), requested_ids, gather_functor, action_functor, ex);
1434
1435#ifdef LIBMESH_ENABLE_UNIQUE_ID
1436 auto unique_gather_functor =
1437 [
1438#ifndef NDEBUG
1439 this,
1440#endif
1441 &objects]
1442 (processor_id_type, const std::vector<dof_id_type> & ids,
1443 std::vector<unique_id_type> & data)
1444 {
1445 std::size_t ids_size = ids.size();
1446 data.resize(ids_size);
1447
1448 for (std::size_t i=0; i != ids_size; ++i)
1449 {
1450 T * obj = objects[ids[i]];
1451 libmesh_assert(obj);
1452 libmesh_assert_equal_to (obj->processor_id(), this->processor_id());
1453 data[i] = obj->valid_unique_id() ? obj->unique_id() : DofObject::invalid_unique_id;
1454 }
1455 };
1456
1457 auto unique_action_functor =
1458 [&objects]
1459 (processor_id_type libmesh_dbg_var(pid),
1460 const std::vector<dof_id_type> & ids,
1461 const std::vector<unique_id_type> & data)
1462 {
1463 for (auto i : index_range(ids))
1464 {
1465 T * obj = objects[ids[i]];
1466 libmesh_assert (obj);
1467 libmesh_assert_equal_to (obj->processor_id(), pid);
1468 if (!obj->valid_unique_id() && data[i] != DofObject::invalid_unique_id)
1469 obj->set_unique_id(data[i]);
1470 }
1471 };
1472
1473 const unique_id_type * unique_ex = nullptr;
1475 (this->comm(), requested_ids, unique_gather_functor,
1476 unique_action_functor, unique_ex);
1477#endif
1478
1479 // Next set unpartitioned object ids
1480 next_id = 0;
1481 for (auto i : make_range(this->n_processors()))
1482 next_id += objects_on_proc[i];
1483 for (it = objects.begin(); it != end; ++it)
1484 {
1485 T * obj = *it;
1486 if (!obj)
1487 continue;
1488 if (obj->processor_id() == DofObject::invalid_processor_id)
1489 obj->set_id(next_id++);
1490 }
1491
1492 // Finally shuffle around objects so that container indices
1493 // match ids
1494 it = objects.begin();
1495 end = objects.end();
1496 while (it != end)
1497 {
1498 T * obj = *it;
1499 if (obj) // don't try shuffling already-nullptr entries
1500 {
1501 T * next = objects[obj->id()];
1502 // If we have to move this object
1503 if (next != obj)
1504 {
1505 // nullptr out its original position for now
1506 // (our shuffling may put another object there shortly)
1507 *it = nullptr;
1508
1509 // There may already be another object with this id that
1510 // needs to be moved itself
1511 while (next)
1512 {
1513 // We shouldn't be trying to give two objects the
1514 // same id
1515 libmesh_assert_not_equal_to (next->id(), obj->id());
1516 objects[obj->id()] = obj;
1517 obj = next;
1518 next = objects[obj->id()];
1519 }
1520 objects[obj->id()] = obj;
1521 }
1522 }
1523
1524 // Remove any container entries that were left as nullptr.
1525 if (!obj)
1526 it = objects.erase(it);
1527 else
1528 ++it;
1529 }
1530
1531 return first_free_id;
1532}
static constexpr unique_id_type invalid_unique_id
An invalid unique_id to distinguish an uninitialized DofObject.
Definition dof_object.h:478
void pull_parallel_vector_data(const Communicator &comm, const MapToVectors &queries, GatherFunctor &gather_data, const ActionFunctor &act_on_data, const datum *example)

References libMesh::Parallel::Communicator::allgather(), libMesh::mapvector< Val, index_t >::begin(), libMesh::ParallelObject::comm(), libMesh::mapvector< Val, index_t >::end(), libMesh::mapvector< Val, index_t >::erase(), libMesh::index_range(), libMesh::DofObject::invalid_processor_id, libMesh::DofObject::invalid_unique_id, libMesh::libmesh_assert(), libMesh::make_range(), libMesh::ParallelObject::n_processors(), libMesh::DistributedMesh::pid, libMesh::ParallelObject::processor_id(), and TIMPI::pull_parallel_vector_data().

Referenced by libMesh::DistributedMesh::renumber_nodes_and_elements().

◆ renumber_elem()

void libMesh::DistributedMesh::renumber_elem ( dof_id_type  old_id,
dof_id_type  new_id 
)
finaloverridevirtualinherited

Changes the id of element old_id, both by changing elem(old_id)->id() and by moving elem(old_id) in the mesh's internal container.

No element with the id new_id should already exist.

Implements libMesh::MeshBase.

Definition at line 823 of file distributed_mesh.C.

825{
826 // This could be a no-op
827 if (old_id == new_id)
828 return;
829
830 Elem * el = _elements[old_id];
831 libmesh_assert (el);
832 libmesh_assert_equal_to (el->id(), old_id);
833
834 el->set_id(new_id);
835 libmesh_assert (!_elements[new_id]);
836 _elements[new_id] = el;
837 _elements.erase(old_id);
838
839 // Should we delete any caches here? Our point locator indexes by
840 // element pointer and should be fine with an id change. Our stored
841 // ranges are no longer sorted, which is *probably* fine, but let's
842 // just be safe.
843 this->clear_stored_ranges();
844}

References libMesh::DistributedMesh::_elements, libMesh::MeshBase::clear_stored_ranges(), libMesh::DofObject::id(), libMesh::libmesh_assert(), and libMesh::DofObject::set_id().

Referenced by MeshPerElemTest< elem_type >::meshes_equal_enough().

◆ renumber_node()

void libMesh::DistributedMesh::renumber_node ( dof_id_type  old_id,
dof_id_type  new_id 
)
finaloverridevirtualinherited

Changes the id of node old_id, both by changing node(old_id)->id() and by moving node(old_id) in the mesh's internal container.

No element with the id new_id should already exist.

Implements libMesh::MeshBase.

Definition at line 1023 of file distributed_mesh.C.

1025{
1026 // This could be a no-op
1027 if (old_id == new_id)
1028 return;
1029
1030 Node * nd = _nodes[old_id];
1031 libmesh_assert (nd);
1032 libmesh_assert_equal_to (nd->id(), old_id);
1033
1034 // If we have nodes shipped to this processor for NodeConstraints
1035 // use, then those nodes will exist in _nodes, but may not be
1036 // locatable via a TopologyMap due to the insufficiency of elements
1037 // connecting to them. If local refinement then wants to create a
1038 // *new* node in the same location, it will initially get a temporary
1039 // id, and then make_node_ids_parallel_consistent() will try to move
1040 // it to the canonical id. We need to account for this case to
1041 // avoid false positives and memory leaks.
1042#ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
1043 if (_nodes[new_id])
1044 {
1045 libmesh_assert_equal_to (*(Point *)_nodes[new_id],
1046 *(Point *)_nodes[old_id]);
1047 _nodes.erase(new_id);
1048 }
1049#else
1050 // If we aren't shipping nodes for NodeConstraints, there should be
1051 // no reason for renumbering one node onto another.
1052 libmesh_assert (!_nodes[new_id]);
1053#endif
1054 _nodes[new_id] = nd;
1055 nd->set_id(new_id);
1056
1057 _nodes.erase(old_id);
1058}

References libMesh::DistributedMesh::_nodes, libMesh::DofObject::id(), libMesh::libmesh_assert(), and libMesh::DofObject::set_id().

Referenced by MeshPerElemTest< elem_type >::meshes_equal_enough().

◆ renumber_nodes_and_elements()

void libMesh::DistributedMesh::renumber_nodes_and_elements ( )
overridevirtualinherited

Remove nullptr elements from arrays.

Implements libMesh::MeshBase.

Definition at line 1535 of file distributed_mesh.C.

1536{
1537 parallel_object_only();
1538
1539#ifdef DEBUG
1540 // Make sure our ids and flags are consistent
1544#endif
1545
1546 LOG_SCOPE("renumber_nodes_and_elements()", "DistributedMesh");
1547
1548 // Nodes not connected to any elements, and nullptr node entries
1549 // in our container, should be deleted. But wait! If we've deleted coarse
1550 // local elements on some processor, other processors might have ghosted
1551 // nodes from it that are now no longer connected to any elements on it, but
1552 // that are connected to their own semilocal elements. We'll have to
1553 // communicate to ascertain if that's the case.
1555
1556 // What used nodes do we see on our proc?
1557 std::set<dof_id_type> used_nodes;
1558
1559 // What used node info should we send from our proc? Could we take ownership
1560 // of each node if we needed to?
1561 std::map<processor_id_type, std::map<dof_id_type, bool>>
1562 used_nodes_on_proc;
1563
1564 // flag the nodes we need
1565 for (auto & elem : this->element_ptr_range())
1566 for (const Node & node : elem->node_ref_range())
1567 {
1568 const dof_id_type n = node.id();
1569 used_nodes.insert(n);
1571 {
1572 const processor_id_type p = node.processor_id();
1573 if (p != this->processor_id())
1574 {
1575 auto & used_nodes_on_p = used_nodes_on_proc[p];
1576 if (elem->processor_id() == this->processor_id())
1577 used_nodes_on_p[n] = true;
1578 else
1579 if (!used_nodes_on_p.count(n))
1580 used_nodes_on_p[n] = false;
1581 }
1582 }
1583 }
1584
1586 {
1587 // "unsigned char" == "bool, but MPI::BOOL is iffy to use"
1588 typedef unsigned char boolish;
1589 std::map<processor_id_type, std::vector<std::pair<dof_id_type, boolish>>>
1590 used_nodes_on_proc_vecs;
1591 for (auto & [pid, nodemap] : used_nodes_on_proc)
1592 used_nodes_on_proc_vecs[pid].assign(nodemap.begin(), nodemap.end());
1593
1594 std::map<dof_id_type,processor_id_type> repartitioned_node_pids;
1595 std::map<processor_id_type, std::set<dof_id_type>>
1596 repartitioned_node_sets_to_push;
1597
1598 auto ids_action_functor =
1599 [&used_nodes, &repartitioned_node_pids,
1600 &repartitioned_node_sets_to_push]
1602 const std::vector<std::pair<dof_id_type, boolish>> & ids_and_bools)
1603 {
1604 for (auto [n, sender_could_become_owner] : ids_and_bools)
1605 {
1606 // If we don't see a use for our own node, but someone
1607 // else does, better figure out who should own it next.
1608 if (!used_nodes.count(n))
1609 {
1610 if (auto it = repartitioned_node_pids.find(n);
1611 sender_could_become_owner)
1612 {
1613 if (it != repartitioned_node_pids.end() &&
1614 pid < it->second)
1615 it->second = pid;
1616 else
1617 repartitioned_node_pids[n] = pid;
1618 }
1619 else
1620 if (it == repartitioned_node_pids.end())
1621 repartitioned_node_pids[n] =
1623
1624 repartitioned_node_sets_to_push[pid].insert(n);
1625 }
1626 }
1627 };
1628
1629 // We need two pushes instead of a pull here because we need to
1630 // know *all* the queries for a particular node before we can
1631 // respond to *any* of them.
1633 (this->comm(), used_nodes_on_proc_vecs, ids_action_functor);
1634
1635 // Repartition (what used to be) our own nodes first
1636 for (auto & [n, p] : repartitioned_node_pids)
1637 {
1638 Node & node = this->node_ref(n);
1639 libmesh_assert_equal_to(node.processor_id(), this->processor_id());
1640 libmesh_assert_not_equal_to_msg(p, DofObject::invalid_processor_id, "Node " << n << " is lost?");
1641 node.processor_id() = p;
1642 }
1643
1644 // Then push to repartition others' ghosted copies.
1645
1646 std::map<processor_id_type, std::vector<std::pair<dof_id_type,processor_id_type>>>
1647 repartitioned_node_vecs;
1648
1649 for (auto & [p, nodeset] : repartitioned_node_sets_to_push)
1650 {
1651 auto & rn_vec = repartitioned_node_vecs[p];
1652 for (auto n : nodeset)
1653 rn_vec.emplace_back(n, repartitioned_node_pids[n]);
1654 }
1655
1656 auto repartition_node_functor =
1657 [this]
1658 (processor_id_type libmesh_dbg_var(pid),
1659 const std::vector<std::pair<dof_id_type, processor_id_type>> & ids_and_pids)
1660 {
1661 for (auto [n, p] : ids_and_pids)
1662 {
1663 libmesh_assert_not_equal_to(p, DofObject::invalid_processor_id);
1664 Node & node = this->node_ref(n);
1665 libmesh_assert_equal_to(node.processor_id(), pid);
1666 node.processor_id() = p;
1667 }
1668 };
1669
1671 (this->comm(), repartitioned_node_vecs, repartition_node_functor);
1672 }
1673
1675
1676 // Nodes not connected to any local elements, and nullptr node entries
1677 // in our container, are deleted
1678 {
1679 node_iterator_imp it = _nodes.begin();
1680 node_iterator_imp end = _nodes.end();
1681
1682 while (it != end)
1683 {
1684 Node * nd = *it;
1685 if (!nd)
1686 it = _nodes.erase(it);
1687 else if (!used_nodes.count(nd->id()))
1688 {
1689 // remove any boundary information associated with
1690 // this node
1691 this->get_boundary_info().remove (nd);
1692 _constraint_rows.erase(nd);
1693
1694 // delete the node
1695 delete nd;
1696
1697 it = _nodes.erase(it);
1698 }
1699 else
1700 ++it;
1701 }
1702 }
1703
1705
1707 {
1709 return;
1710 }
1711
1712 // Finally renumber all the elements
1713 _n_elem = this->renumber_dof_objects (this->_elements);
1714
1715 // and all the remaining nodes
1716 _n_nodes = this->renumber_dof_objects (this->_nodes);
1717
1718 // And figure out what IDs we should use when adding new nodes and
1719 // new elements
1721
1722 // Make sure our caches are up to date and our
1723 // DofObjects are well packed
1724#ifdef DEBUG
1725 libmesh_assert_equal_to (this->n_nodes(), this->parallel_n_nodes());
1726 libmesh_assert_equal_to (this->n_elem(), this->parallel_n_elem());
1727 const dof_id_type pmax_node_id = this->parallel_max_node_id();
1728 const dof_id_type pmax_elem_id = this->parallel_max_elem_id();
1729 libmesh_assert_equal_to (this->max_node_id(), pmax_node_id);
1730 libmesh_assert_equal_to (this->max_elem_id(), pmax_elem_id);
1731 libmesh_assert_equal_to (this->n_nodes(), this->max_node_id());
1732 libmesh_assert_equal_to (this->n_elem(), this->max_elem_id());
1733
1734 // Make sure our ids and flags are consistent
1737
1738 // And make sure we've made our numbering monotonic
1740#endif
1741}
dof_id_type renumber_dof_objects(dofobject_container< T > &)
Renumber a parallel objects container.
void libmesh_assert_valid_parallel_p_levels() const
Verify p_level consistency of our elements containers.
dofobject_container< Node >::veclike_iterator node_iterator_imp
Typedefs for the container implementation.
virtual MeshBase & assign(MeshBase &&other_mesh) override
Shim to call the move assignment operator for this class.
void push_parallel_vector_data(const Communicator &comm, MapToVectors &&data, const ActionFunctor &act_on_data)
void libmesh_assert_valid_elem_ids(const MeshBase &mesh)
A function for verifying that ids and processor assignment of elements are correctly sorted (monotone...

References libMesh::MeshBase::_constraint_rows, libMesh::DistributedMesh::_deleted_coarse_elements, libMesh::DistributedMesh::_elements, libMesh::DistributedMesh::_n_elem, libMesh::DistributedMesh::_n_nodes, libMesh::DistributedMesh::_nodes, libMesh::MeshBase::_preparation, libMesh::MeshBase::_skip_renumber_nodes_and_elements, libMesh::DistributedMesh::assign(), libMesh::ParallelObject::comm(), libMesh::MeshBase::get_boundary_info(), libMesh::MeshBase::Preparation::has_removed_orphaned_nodes, libMesh::DofObject::id(), libMesh::DofObject::invalid_processor_id, libMesh::MeshTools::libmesh_assert_valid_elem_ids(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_flags(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_ids(), libMesh::DistributedMesh::libmesh_assert_valid_parallel_p_levels(), libMesh::Parallel::Communicator::max(), libMesh::DistributedMesh::max_elem_id(), libMesh::DistributedMesh::max_node_id(), libMesh::DistributedMesh::n_elem(), libMesh::DistributedMesh::n_nodes(), libMesh::MeshBase::node_ref(), libMesh::DistributedMesh::parallel_max_elem_id(), libMesh::DistributedMesh::parallel_max_node_id(), libMesh::DistributedMesh::parallel_n_elem(), libMesh::DistributedMesh::parallel_n_nodes(), libMesh::DistributedMesh::pid, libMesh::DofObject::processor_id(), libMesh::ParallelObject::processor_id(), TIMPI::push_parallel_vector_data(), libMesh::BoundaryInfo::remove(), libMesh::DistributedMesh::renumber_dof_objects(), and libMesh::DistributedMesh::update_parallel_id_counts().

◆ reserve_elem()

virtual void libMesh::DistributedMesh::reserve_elem ( const dof_id_type  ne)
inlinefinaloverridevirtualinherited

Reserves space for a known number of elements.

Note
This method may or may not do anything, depending on the actual Mesh implementation. If you know the number of elements you will add and call this method before repeatedly calling add_point() the implementation will be more efficient.

Implements libMesh::MeshBase.

Definition at line 276 of file distributed_mesh.h.

276{}

◆ reserve_nodes()

virtual void libMesh::DistributedMesh::reserve_nodes ( const dof_id_type  nn)
inlinefinaloverridevirtualinherited

Reserves space for a known number of nodes.

Note
This method may or may not do anything, depending on the actual Mesh implementation. If you know the number of nodes you will add and call this method before repeatedly calling add_point() the implementation will be more efficient.

Implements libMesh::MeshBase.

Definition at line 272 of file distributed_mesh.h.

272{}

◆ set_constraint_rows()

constraint_rows_type & libMesh::MeshBase::set_constraint_rows ( )
inlineinherited

◆ set_count_lower_dim_elems_in_point_locator()

void libMesh::MeshBase::set_count_lower_dim_elems_in_point_locator ( bool  count_lower_dim_elems)
inherited

In the point locator, do we count lower dimensional elements when we refine point locator regions? This is relevant in tree-based point locators, for example.

Definition at line 1888 of file mesh_base.C.

1889{
1890 _count_lower_dim_elems_in_point_locator = count_lower_dim_elems;
1891}

References libMesh::MeshBase::_count_lower_dim_elems_in_point_locator.

◆ set_default_mapping_data()

void libMesh::MeshBase::set_default_mapping_data ( const unsigned char  data)
inlineinherited

Set the default master space to physical space mapping basis functions to be used on newly added elements.

Definition at line 965 of file mesh_base.h.

966 {
968 }

References libMesh::MeshBase::_default_mapping_data.

Referenced by libMesh::MeshTools::Modification::all_rbb(), libMesh::ExodusII_IO::read(), and libMesh::DynaIO::read_mesh().

◆ set_default_mapping_type()

void libMesh::MeshBase::set_default_mapping_type ( const ElemMappingType  type)
inlineinherited

Set the default master space to physical space mapping basis functions to be used on newly added elements.

Definition at line 947 of file mesh_base.h.

948 {
950 }

References libMesh::MeshBase::_default_mapping_type.

Referenced by libMesh::MeshTools::Modification::all_rbb(), libMesh::ExodusII_IO::read(), and libMesh::DynaIO::read_mesh().

◆ set_distributed()

virtual void libMesh::DistributedMesh::set_distributed ( )
inlinefinaloverridevirtualinherited

Asserts that not all elements and nodes of the mesh necessarily exist on the current processor.

Reimplemented from libMesh::MeshBase.

Definition at line 174 of file distributed_mesh.h.

175 { _is_serial = false;
176 _is_serial_on_proc_0 = false; }

References libMesh::DistributedMesh::_is_serial, and libMesh::DistributedMesh::_is_serial_on_proc_0.

◆ set_elem_dimensions()

void libMesh::MeshBase::set_elem_dimensions ( std::set< unsigned char >  elem_dims)
inherited

Most of the time you should not need to call this, as the element dimensions will be set automatically by a call to cache_elem_data(), therefore only call this if you know what you're doing.

In some specialized situations, for example when adding a single Elem on all procs, it can be faster to skip calling cache_elem_data() and simply specify the element dimensions manually, which is why this setter exists.

Definition at line 444 of file mesh_base.C.

445{
446#ifdef DEBUG
447 // In debug mode, we call cache_elem_data() and then make sure
448 // the result actually agrees with what the user specified.
449 parallel_object_only();
450
451 this->cache_elem_data();
452 libmesh_assert_msg(_elem_dims == elem_dims, \
453 "Specified element dimensions does not match true element dimensions!");
454#endif
455
456 _elem_dims = std::move(elem_dims);
457}

References libMesh::MeshBase::_elem_dims, and libMesh::MeshBase::cache_elem_data().

◆ set_interior_mesh()

void libMesh::MeshBase::set_interior_mesh ( MeshBase &  int_mesh)
inlineinherited

Sets the interior mesh.

For advanced use only.

Definition at line 2063 of file mesh_base.h.

2063{ _interior_mesh = &int_mesh; }

References libMesh::MeshBase::_interior_mesh.

Referenced by libMesh::BoundaryInfo::add_elements(), and libMesh::UnstructuredMesh::copy_nodes_and_elements().

◆ set_isnt_prepared()

void libMesh::MeshBase::set_isnt_prepared ( )
inlineinherited

Tells this we have done some operation where we should no longer consider ourself prepared.

This is a very coarse setting; it is generally more efficient to mark finer-grained settings instead.

This method name is now deprecated, in part to match the less awkward unset_has_ names of the more fine-grained methods, in part as a way to prompt older user codes to use the more fine-grained methods where they can, to speed up the complete_preparation() calls afterward.

Definition at line 228 of file mesh_base.h.

229 { libmesh_deprecated(); _preparation = false; }

References libMesh::MeshBase::_preparation.

◆ set_mesh_dimension()

void libMesh::MeshBase::set_mesh_dimension ( unsigned char  d)
inlineinherited

◆ set_n_partitions()

unsigned int & libMesh::MeshBase::set_n_partitions ( )
inlineprotectedinherited
Returns
A writable reference to the number of partitions.

Definition at line 2176 of file mesh_base.h.

2177 { return _n_parts; }

References libMesh::MeshBase::_n_parts.

Referenced by libMesh::Partitioner::partition(), libMesh::Partitioner::repartition(), and libMesh::BoundaryInfo::sync().

◆ set_next_ids()

void libMesh::DistributedMesh::set_next_ids ( )
privateinherited

Derives _next_free_local_node_id, _next_free_local_elem_id, _next_free_unpartitioned_node_id, and _next_free_unpartitioned_elem_id from the current _max_node_id and _max_elem_id, interleaving ids among processors so that each processor (and the unpartitioned pool) has its own reserved slot in every repeating group of n_processors()+1 ids.

Definition at line 268 of file distributed_mesh.C.

269{
271 ((_max_elem_id-1) / (this->n_processors() + 1) + 1) *
272 (this->n_processors() + 1) + this->n_processors();
274 ((_max_elem_id + this->n_processors() - 1) / (this->n_processors() + 1) + 1) *
275 (this->n_processors() + 1) + this->processor_id();
276
278 ((_max_node_id-1) / (this->n_processors() + 1) + 1) *
279 (this->n_processors() + 1) + this->n_processors();
281 ((_max_node_id + this->n_processors() - 1) / (this->n_processors() + 1) + 1) *
282 (this->n_processors() + 1) + this->processor_id();
283}

References libMesh::DistributedMesh::_max_elem_id, libMesh::DistributedMesh::_max_node_id, libMesh::DistributedMesh::_next_free_local_elem_id, libMesh::DistributedMesh::_next_free_local_node_id, libMesh::DistributedMesh::_next_free_unpartitioned_elem_id, libMesh::DistributedMesh::_next_free_unpartitioned_node_id, libMesh::ParallelObject::n_processors(), and libMesh::ParallelObject::processor_id().

Referenced by libMesh::DistributedMesh::DistributedMesh(), and libMesh::DistributedMesh::update_parallel_id_counts().

◆ set_next_unique_id()

void libMesh::DistributedMesh::set_next_unique_id ( unique_id_type  id)
overridevirtualinherited

Sets the next available unique id to be used.

On a ReplicatedMesh, or when adding unpartitioned objects to a DistributedMesh, this must be kept in sync on all processors.

On a DistributedMesh, other unique_id values (larger than this one) may be chosen next, to allow unique_id assignment without communication.

Implements libMesh::MeshBase.

Definition at line 419 of file distributed_mesh.C.

420{
421 _next_unique_id = id;
423 ((_next_unique_id-1) / (this->n_processors() + 1) + 1) *
424 (this->n_processors() + 1) + this->n_processors();
426 ((_next_unique_id + this->n_processors() - 1) / (this->n_processors() + 1) + 1) *
427 (this->n_processors() + 1) + this->processor_id();
428}

References libMesh::MeshBase::_next_unique_id, libMesh::DistributedMesh::_next_unpartitioned_unique_id, libMesh::ParallelObject::n_processors(), and libMesh::ParallelObject::processor_id().

Referenced by MeshPerElemTest< elem_type >::meshes_equal_enough().

◆ set_next_unique_ids()

void libMesh::DistributedMesh::set_next_unique_ids ( unique_id_type  parallel_max_unique_id)
privateinherited

Derives _next_unique_id and _next_unpartitioned_unique_id from parallel_max_unique_id, the largest unique id currently in use (or any other value guaranteed to be at least that large, such as a trusted next_unique_id()), using the same processor-interleaved id ranges as set_next_ids().

Definition at line 286 of file distributed_mesh.C.

287{
288 // Unique ids are laid out in repeating groups of (n_processors()+1)
289 // consecutive integers ("alignment" here means a value's position, i.e.
290 // its residue mod (n_processors()+1), within one of these groups). In
291 // every group, the first n_processors() slots (residues 0..n_processors()-1)
292 // are each permanently earmarked for one processor's locally-owned
293 // objects, and the last slot (residue n_processors()) is permanently
294 // earmarked for unpartitioned objects.
295 //
296 // parallel_max_unique_id carries no guarantee of landing on any
297 // particular residue, so rather than simply offsetting it by
298 // processor_id()/n_processors(), we have to explicitly round up to the
299 // start of the next full, entirely-unused group before adding this
300 // processor's (or the unpartitioned pool's) fixed offset into that group.
301 //
302 // (parallel_max_unique_id - 1) / (n_processors()+1) + 1 is the standard
303 // integer idiom for ceil(parallel_max_unique_id / (n_processors()+1)):
304 // the number of complete groups needed to reach at least past the
305 // current max id. Multiplying back by (n_processors()+1) gives the first
306 // id of the next group that is guaranteed to be entirely unused; adding
307 // n_processors(), the unpartitioned pool's fixed offset within a group,
308 // lands on that pool's reserved slot in that group.
310 ((parallel_max_unique_id - 1) / (this->n_processors() + 1) + 1) *
311 (this->n_processors() + 1) +
312 this->n_processors();
313
314 // Same idiom, but shifted by (n_processors()-1) before dividing so that
315 // the rounding accounts for processor_id() possibly being less than the
316 // residue the raw max id already occupies within its group; this can
317 // land this processor's slot in the same group as the unpartitioned
318 // pool's above, or push it into the following group, depending on where
319 // the max id and this processor's offset happen to fall.
321 ((parallel_max_unique_id + this->n_processors() - 1) / (this->n_processors() + 1) + 1) *
322 (this->n_processors() + 1) +
323 this->processor_id();
324}
virtual unique_id_type parallel_max_unique_id() const override

References libMesh::MeshBase::_next_unique_id, libMesh::DistributedMesh::_next_unpartitioned_unique_id, libMesh::ParallelObject::n_processors(), libMesh::DistributedMesh::parallel_max_unique_id(), and libMesh::ParallelObject::processor_id().

Referenced by libMesh::DistributedMesh::DistributedMesh(), and libMesh::DistributedMesh::update_parallel_id_counts().

◆ set_point_locator_close_to_point_tol()

void libMesh::MeshBase::set_point_locator_close_to_point_tol ( Real  val)
inherited

Set value used by PointLocatorBase::close_to_point_tol().

Defaults to 0.0. If nonzero, calls close_to_point_tol() whenever a new PointLocator is built for use by this Mesh. Since the Mesh controls the creation and destruction of the PointLocator, if there are any parameters we need to customize on it, the Mesh will need to know about them.

Definition at line 2355 of file mesh_base.C.

2356{
2358 if (_point_locator)
2359 {
2360 if (val > 0.)
2361 _point_locator->set_close_to_point_tol(val);
2362 else
2363 _point_locator->unset_close_to_point_tol();
2364 }
2365}

References libMesh::MeshBase::_point_locator, and libMesh::MeshBase::_point_locator_close_to_point_tol.

◆ set_spatial_dimension()

void libMesh::MeshBase::set_spatial_dimension ( unsigned char  d)
inherited

Sets the "spatial dimension" of the Mesh.

See the documentation for Mesh::spatial_dimension() for more information.

Definition at line 613 of file mesh_base.C.

614{
615 // The user can set the _spatial_dimension however they wish,
616 // libMesh will only *increase* the spatial dimension, however,
617 // never decrease it.
619}

References libMesh::MeshBase::_spatial_dimension.

Referenced by libMesh::MeshTools::Generation::build_cube(), MeshSpatialDimensionTest::test2D(), and InfFERadialTest::testRefinement().

◆ set_subdomain_name()

void libMesh::MeshBase::set_subdomain_name ( subdomain_id_type  id,
const std::string &  name,
bool  synchronous = false 
)
inherited

Sets the name for the provided id.

Parameters
idThe subdomain id to set the name for
nameThe subdomain name
synchronousWhether this method is being called across all mesh ranks. If this is true, then we don't have to register this collective container as being out of sync

Definition at line 1929 of file mesh_base.C.

1932{
1933 if (synchronous)
1934 parallel_object_only();
1935 else
1937 _block_id_to_name[id] = name;
1938}
void unset_has_synched_subdomain_name_map()
Tells this we have done some operation which may have left the subdomain id to name map inconsistent ...
Definition mesh_base.h:350

References libMesh::MeshBase::_block_id_to_name, and libMesh::MeshBase::unset_has_synched_subdomain_name_map().

Referenced by libMesh::AbaqusIO::assign_subdomain_ids(), libMesh::UNVIO::groups_in(), libMesh::Nemesis_IO::read(), libMesh::ExodusII_IO::read(), libMesh::GmshIO::read_mesh(), libMesh::UnstructuredMesh::stitching_helper(), ExodusC0PolyhedronTest::test_write_and_read_mixed_hex_tet_block_names_impl(), MeshStitchTest::testAmbiguousRemappingStitch(), and MeshStitchTest::testRemappingStitch().

◆ set_subdomain_name_map()

std::map< subdomain_id_type, std::string > & libMesh::MeshBase::set_subdomain_name_map ( )
inlineinherited

◆ size_elem_extra_integers()

void libMesh::MeshBase::size_elem_extra_integers ( )
protectedinherited

Size extra-integer arrays of all elements in the mesh.

Definition at line 2376 of file mesh_base.C.

2377{
2378 const std::size_t new_size = _elem_integer_names.size();
2379
2381 (this->element_stored_range(),
2382 [new_size, this](const ElemRange & range)
2383 {
2384 for (Elem * elem : range)
2385 elem->add_extra_integers(new_size, this->_elem_integer_default_values);
2386 });
2387}

References libMesh::MeshBase::_elem_integer_names, libMesh::MeshBase::element_stored_range(), and libMesh::Threads::parallel_for().

Referenced by libMesh::MeshBase::add_elem_data(), libMesh::MeshBase::add_elem_datum(), libMesh::MeshBase::add_elem_integer(), and libMesh::MeshBase::add_elem_integers().

◆ size_node_extra_integers()

void libMesh::MeshBase::size_node_extra_integers ( )
protectedinherited

Size extra-integer arrays of all nodes in the mesh.

Definition at line 2391 of file mesh_base.C.

2392{
2393 const std::size_t new_size = _node_integer_names.size();
2394 for (auto node : this->node_ptr_range())
2395 node->add_extra_integers(new_size, _node_integer_default_values);
2396}

References libMesh::MeshBase::_node_integer_default_values, and libMesh::MeshBase::_node_integer_names.

Referenced by libMesh::MeshBase::add_node_data(), libMesh::MeshBase::add_node_datum(), libMesh::MeshBase::add_node_integer(), and libMesh::MeshBase::add_node_integers().

◆ skip_noncritical_partitioning() [1/2]

bool libMesh::MeshBase::skip_noncritical_partitioning ( ) const
inlineinherited

◆ skip_noncritical_partitioning() [2/2]

void libMesh::MeshBase::skip_noncritical_partitioning ( bool  skip)
inlineinherited

If true is passed in then the elements on this mesh will no longer be (re)partitioned, and the nodes on this mesh will only be repartitioned if they are found "orphaned" via coarsening or other removal of the last element responsible for their node/element processor id consistency.

Note
It would probably be a bad idea to call this on a DistributedMesh before the first partitioning has happened... because no elements would get assigned to your processor pool.
Skipping partitioning can have adverse effects on your performance when using AMR... i.e. you could get large load imbalances. However you might still want to use this if the communication and computation of the rebalance and repartition is too high for your application.

It is also possible, for backwards-compatibility purposes, to skip noncritical partitioning by resetting the partitioner() pointer for this mesh.

Definition at line 1415 of file mesh_base.h.

References libMesh::MeshBase::_skip_noncritical_partitioning.

Referenced by libMesh::MeshTools::correct_node_proc_ids(), MeshInputTest::testCopyElementSolutionImpl(), MeshInputTest::testCopyElementVectorImpl(), and MeshInputTest::testCopyNodalSolutionImpl().

◆ skip_partitioning() [1/2]

bool libMesh::MeshBase::skip_partitioning ( ) const
inlineinherited

◆ skip_partitioning() [2/2]

void libMesh::MeshBase::skip_partitioning ( bool  skip)
inlineinherited

If true is passed in then nothing on this mesh will be (re)partitioned.

Note
The caveats for skip_noncritical_partitioning() still apply, and removing elements from a mesh with this setting enabled can leave node processor ids in an inconsistent state (not matching any attached element), causing failures in other library code. Do not use this setting along with element deletion or coarsening.

Definition at line 1433 of file mesh_base.h.

1433{ _skip_all_partitioning = skip; }

References libMesh::MeshBase::_skip_all_partitioning.

Referenced by libMesh::DistributedMesh::DistributedMesh(), libMesh::CheckpointIO::read(), libMesh::ReplicatedMesh::ReplicatedMesh(), and CheckpointIOTest::testSplitter().

◆ spatial_dimension()

unsigned int libMesh::MeshBase::spatial_dimension ( ) const
inlineinherited
Returns
The "spatial dimension" of the mesh.

The spatial dimension is defined as:

1 - for an exactly x-aligned mesh of 1D elements 2 - for an exactly x-y planar mesh of 2D elements 3 - otherwise

No tolerance checks are performed to determine whether the Mesh is x-aligned or x-y planar, only strict equality with zero in the higher dimensions is checked. Also, x-z and y-z planar meshes are considered to have spatial dimension == 3.

The spatial dimension is updated during mesh preparation based on the dimensions of the various elements present in the Mesh, but is never automatically decreased.

For example, if the user calls set_spatial_dimension(2) and then later inserts 3D elements into the mesh, Mesh::spatial_dimension() will return 3 after the next call to prepare_for_use() or complete_preparation(). On the other hand, if the user calls set_spatial_dimension(3) and then inserts only x-aligned 1D elements into the Mesh, mesh.spatial_dimension() will remain 3.

Definition at line 2682 of file mesh_base.h.

2683{
2685
2686 return cast_int<unsigned int>(_spatial_dimension);
2687}

References libMesh::MeshBase::_preparation, libMesh::MeshBase::_spatial_dimension, libMesh::MeshBase::Preparation::has_cached_elem_data, and libMesh::libmesh_assert().

Referenced by libMesh::EquationSystems::build_elemental_data_variable_names(), libMesh::EquationSystems::build_parallel_solution_vector(), libMesh::EquationSystems::build_variable_names(), libMesh::EquationSystems::find_variable_numbers_by_predicate(), libMesh::ExodusII_IO_Helper::initialize(), MeshSpatialDimensionTest::test1D(), and MeshSpatialDimensionTest::test2D().

◆ stitch_meshes()

std::size_t libMesh::UnstructuredMesh::stitch_meshes ( const MeshBase &  other_mesh,
boundary_id_type  this_mesh_boundary,
boundary_id_type  other_mesh_boundary,
Real  tol = TOLERANCE,
bool  clear_stitched_boundary_ids = false,
bool  verbose = true,
bool  use_binary_search = true,
bool  enforce_all_nodes_match_on_boundaries = false,
bool  merge_boundary_nodes_all_or_nothing = false,
bool  remap_subdomain_ids = false,
bool  prepare_after_stitching = true 
)
inherited

Stitch other_mesh to this mesh so that this mesh is the union of the two meshes.

this_mesh_boundary and other_mesh_boundary are used to specify a dim-1 dimensional surface on which we seek to merge any "overlapping" nodes, where we use the parameter tol as a relative tolerance (relative to the smallest edge length on the surfaces being stitched) to determine whether or not nodes are overlapping. If clear_stitched_boundary_ids==true, this function clears boundary_info IDs in this mesh associated this_mesh_boundary and other_mesh_boundary. If use_binary_search is true, we use an optimized "sort then binary search" algorithm for finding matching nodes. Otherwise we use a N^2 algorithm (which can be more reliable at dealing with slightly misaligned meshes). If enforce_all_nodes_match_on_boundaries is true, we throw an error if the number of nodes on the specified boundaries don't match the number of nodes that were merged. This is a helpful error check in some cases. If this is true, it overrides the value of merge_boundary_nodes_all_or_nothing. If skip_find_neighbors is true, a faster stitching method is used, where the lists of neighbors for each elements are copied as well and patched, without calling the time-consuming find_neighbors() function. This option is now hard-coded to true. If merge_boundary_nodes_all_or_nothing is true, instead of throwing an error like enforce_all_nodes_match_on_boundaries, the meshes are combined anyway but coincident nodes are not merged into single nodes. This is useful in cases where you are not sure if the boundaries are fully conforming beforehand and you want to handle the non-conforming cases differently.

Note that the element IDs for elements in the stitched mesh corresponding to "this" mesh will be unchanged. The IDs for elements corresponding to other_mesh will be incremented by this->max_elem_id().

There is no simple a priori relationship between node IDs in "this" mesh and other_mesh and node IDs in the stitched mesh because the number of nodes (and hence the node IDs) in the stitched mesh depend on how many nodes are stitched.

If remap_subdomain_ids is true then we assume that some subdomain ids might have been autogenerated, so we remap them as necessary, treating subdomain names as the important thing for consistency; if we have missing names and cannot infer a consistent resolution to an id conflict then we exit with an error. If remap_subdomain_ids is false then we revert to the older libMesh behavior: leave all subdomain ids alone and woe unto you if you weren't keeping track of them.

If prepare_after_stitching is true then we prepare the newly stitched mesh for use immediately after stitching. If the mesh does not need to be completely prepared for use yet (e.g. because it will undergo further stitching etc. before repartitioning for load balancing is desired), this can be set to false to potentially improve performance.

Returns
the count of how many nodes were merged between the two meshes. This can be zero in the case of no matching nodes or if merge_boundary_nodes_all_or_nothing was active and relevant.

Definition at line 1917 of file unstructured_mesh.C.

1928{
1929 LOG_SCOPE("stitch_meshes()", "UnstructuredMesh");
1930 return stitching_helper(&other_mesh,
1931 this_mesh_boundary_id,
1932 other_mesh_boundary_id,
1933 tol,
1934 clear_stitched_boundary_ids,
1935 verbose,
1936 use_binary_search,
1937 enforce_all_nodes_match_on_boundaries,
1938 true,
1939 merge_boundary_nodes_all_or_nothing,
1940 remap_subdomain_ids,
1941 prepare_after_stitching);
1942}
std::size_t stitching_helper(const MeshBase *other_mesh, boundary_id_type boundary_id_1, boundary_id_type boundary_id_2, Real tol, bool clear_stitched_boundary_ids, bool verbose, bool use_binary_search, bool enforce_all_nodes_match_on_boundaries, bool skip_find_neighbors, bool merge_boundary_nodes_all_or_nothing, bool remap_subdomain_ids, bool prepare_after_stitching)
Helper function for stitch_meshes and stitch_surfaces that does the mesh stitching.

References libMesh::UnstructuredMesh::stitching_helper().

Referenced by main(), DisjointNeighborTest::testDisjointNeighborConflictError(), MeshStitchTest::testNodeElemStitch(), and DisjointNeighborTest::testStitchCrossMesh().

◆ stitch_surfaces()

std::size_t libMesh::UnstructuredMesh::stitch_surfaces ( boundary_id_type  boundary_id_1,
boundary_id_type  boundary_id_2,
Real  tol = TOLERANCE,
bool  clear_stitched_boundary_ids = false,
bool  verbose = true,
bool  use_binary_search = true,
bool  enforce_all_nodes_match_on_boundaries = false,
bool  merge_boundary_nodes_all_or_nothing = false,
bool  prepare_after_stitching = true 
)
inherited

Similar to stitch_meshes, except that we stitch two adjacent surfaces within this mesh.

Definition at line 1946 of file unstructured_mesh.C.

1956{
1957 return stitching_helper(nullptr,
1958 boundary_id_1,
1959 boundary_id_2,
1960 tol,
1961 clear_stitched_boundary_ids,
1962 verbose,
1963 use_binary_search,
1964 enforce_all_nodes_match_on_boundaries,
1965 /* skip_find_neighbors = */ true,
1966 merge_boundary_nodes_all_or_nothing,
1967 /* remap_subdomain_ids = */ false,
1968 prepare_after_stitching);
1969}

References libMesh::UnstructuredMesh::stitching_helper().

Referenced by DisjointNeighborTest::testStitchingDiscontinuousBoundaries().

◆ stitching_helper()

std::size_t libMesh::UnstructuredMesh::stitching_helper ( const MeshBase *  other_mesh,
boundary_id_type  boundary_id_1,
boundary_id_type  boundary_id_2,
Real  tol,
bool  clear_stitched_boundary_ids,
bool  verbose,
bool  use_binary_search,
bool  enforce_all_nodes_match_on_boundaries,
bool  skip_find_neighbors,
bool  merge_boundary_nodes_all_or_nothing,
bool  remap_subdomain_ids,
bool  prepare_after_stitching 
)
privateinherited

Helper function for stitch_meshes and stitch_surfaces that does the mesh stitching.

Definition at line 1973 of file unstructured_mesh.C.

1985{
1986#ifdef DEBUG
1987 // We rely on neighbor links here
1989#endif
1990
1991 bool is_valid_disjoint_pair_to_stitch = false;
1992
1993#ifdef LIBMESH_ENABLE_PERIODIC
1994 auto * this_db = this->get_disjoint_neighbor_boundary_pairs();
1995 auto * other_db = (other_mesh ? other_mesh->get_disjoint_neighbor_boundary_pairs() : nullptr);
1996 const bool have_disc_bdys =
1997 (this_db && !this_db->empty()) || (other_db && !other_db->empty());
1998
1999 if (have_disc_bdys)
2000 {
2001 const boundary_id_type a = this_mesh_boundary_id;
2002 const boundary_id_type b = other_mesh_boundary_id;
2003
2004 auto get_pb = [](const PeriodicBoundaries * db, boundary_id_type id)
2005 {
2006 return db ? db->boundary(id) : nullptr;
2007 };
2008
2009 // this mesh
2010 const auto * pb_this_a = get_pb(this_db, a);
2011 const auto * pb_this_b = get_pb(this_db, b);
2012 const bool in_this =
2013 (pb_this_a && pb_this_a->pairedboundary == b) ||
2014 (pb_this_b && pb_this_b->pairedboundary == a);
2015
2016 // other mesh
2017 const auto * pb_other_b = get_pb(other_db, b);
2018 const auto * pb_other_a = get_pb(other_db, a);
2019 const bool in_other =
2020 (pb_other_b && pb_other_b->pairedboundary == a) ||
2021 (pb_other_a && pb_other_a->pairedboundary == b);
2022
2023 // Conflict conditions:
2024 // Case 1: On "this" mesh, a or b exist but are not paired,
2025 // while the other mesh pairs them.
2026 if (!in_this && (pb_this_a || pb_this_b) && in_other)
2027 libmesh_error_msg("Disjoint neighbor boundary pairing mismatch: on 'this' mesh, "
2028 "boundary (" << a << " or " << b
2029 << ") exists but is not paired; on 'other' mesh the pair is present.");
2030
2031 // Case 2: On "other" mesh, a or b exist but are not paired,
2032 // while this mesh pairs them.
2033 if (!in_other && (pb_other_a || pb_other_b) && in_this)
2034 libmesh_error_msg("Disjoint neighbor boundary pairing mismatch: on 'other' mesh, "
2035 "boundary (" << a << " or " << b
2036 << ") exists but is not paired; on 'this' mesh the pair is present.");
2037
2038 // Legal conditions: either side has a correct pairing
2039 if (in_this || in_other)
2040 is_valid_disjoint_pair_to_stitch = true;
2041 }
2042#endif // LIBMESH_ENABLE_PERIODIC
2043
2044 // We can't even afford any unset neighbor links here.
2045 if (!this->is_prepared())
2046 this->find_neighbors();
2047
2048 // FIXME: make distributed mesh support efficient.
2049 // Yes, we currently suck.
2050 MeshSerializer serialize(*this);
2051
2052 // *Badly*.
2053 std::unique_ptr<MeshSerializer> serialize_other;
2054 if (other_mesh)
2055 serialize_other = std::make_unique<MeshSerializer>
2056 (*const_cast<MeshBase *>(other_mesh));
2057
2058 std::map<dof_id_type, dof_id_type> node_to_node_map, other_to_this_node_map; // The second is the inverse map of the first
2059 std::map<dof_id_type, std::vector<dof_id_type>> node_to_elems_map;
2060
2061 typedef dof_id_type key_type;
2062 typedef std::pair<const Elem *, unsigned char> val_type;
2063 typedef std::pair<key_type, val_type> key_val_pair;
2064 typedef std::unordered_multimap<key_type, val_type> map_type;
2065 // Mapping between all side keys in this mesh and elements+side numbers relevant to the boundary in this mesh as well.
2066 map_type side_to_elem_map;
2067
2068 // If there is only one mesh (i.e. other_mesh == nullptr), then loop over this mesh twice
2069 if (!other_mesh)
2070 {
2071 other_mesh = this;
2072 }
2073
2074 if ((this_mesh_boundary_id != BoundaryInfo::invalid_id) &&
2075 (other_mesh_boundary_id != BoundaryInfo::invalid_id))
2076 {
2077 LOG_SCOPE("stitch_meshes node merging", "UnstructuredMesh");
2078
2079 // While finding nodes on the boundary, also find the minimum edge length
2080 // of all faces on both boundaries. This will later be used in relative
2081 // distance checks when stitching nodes.
2082 Real h_min = std::numeric_limits<Real>::max();
2083 bool h_min_updated = false;
2084
2085 // Loop below fills in these sets for the two meshes.
2086 std::set<dof_id_type> this_boundary_node_ids, other_boundary_node_ids;
2087
2088 // Pull objects out of the loop to reduce heap operations
2089 std::unique_ptr<const Elem> side;
2090
2091 {
2092 // Make temporary fixed-size arrays for loop
2093 boundary_id_type id_array[2] = {this_mesh_boundary_id, other_mesh_boundary_id};
2094 std::set<dof_id_type> * set_array[2] = {&this_boundary_node_ids, &other_boundary_node_ids};
2095 const MeshBase * mesh_array[2] = {this, other_mesh};
2096
2097 for (unsigned i=0; i<2; ++i)
2098 {
2099 // First we deal with node boundary IDs. We only enter
2100 // this loop if we have at least one nodeset. Note that we
2101 // do not attempt to make an h_min determination here.
2102 // The h_min determination is done while looping over the
2103 // Elems and checking their sides and edges for boundary
2104 // information, below.
2105 if (mesh_array[i]->get_boundary_info().n_nodeset_conds() > 0)
2106 {
2107 // build_node_list() returns a vector of (node-id, bc-id) tuples
2108 for (const auto & t : mesh_array[i]->get_boundary_info().build_node_list())
2109 {
2110 boundary_id_type node_bc_id = std::get<1>(t);
2111 if (node_bc_id == id_array[i])
2112 {
2113 dof_id_type this_node_id = std::get<0>(t);
2114 set_array[i]->insert( this_node_id );
2115 }
2116 }
2117 }
2118
2119 // Container to catch boundary IDs passed back from BoundaryInfo.
2120 std::vector<boundary_id_type> bc_ids;
2121
2122 // Pointers to boundary NodeElems encountered while looping over the entire Mesh
2123 // and checking side and edge boundary ids. The Nodes associated with NodeElems
2124 // may be in a boundary nodeset, but not connected to any other Elems. In this
2125 // case, we also consider the "minimum node separation distance" amongst all
2126 // NodeElems when determining the relevant h_min value for this mesh.
2127 std::vector<const Elem *> boundary_node_elems;
2128
2129 for (auto & el : mesh_array[i]->element_ptr_range())
2130 {
2131 // Now check whether elem has a face on the specified boundary
2132 for (auto side_id : el->side_index_range())
2133 {
2134 bool should_stitch_this_side =
2135 (el->neighbor_ptr(side_id) == nullptr) ||
2136 (is_valid_disjoint_pair_to_stitch &&
2137 mesh_array[i]->get_boundary_info().has_boundary_id(el, side_id, id_array[i]));
2138
2139 if (should_stitch_this_side)
2140 {
2141 // Get *all* boundary IDs on this side, not just the first one!
2142 mesh_array[i]->get_boundary_info().boundary_ids (el, side_id, bc_ids);
2143
2144 if (std::find(bc_ids.begin(), bc_ids.end(), id_array[i]) != bc_ids.end())
2145 {
2146 el->build_side_ptr(side, side_id);
2147 for (auto & n : side->node_ref_range())
2148 set_array[i]->insert(n.id());
2149
2150 h_min = std::min(h_min, side->hmin());
2151 h_min_updated = true;
2152
2153 // This side is on the boundary, add its information to side_to_elem
2154 if (skip_find_neighbors && (i==0))
2155 {
2156 key_type key = el->low_order_key(side_id);
2157 val_type val;
2158 val.first = el;
2159 val.second = cast_int<unsigned char>(side_id);
2160
2161 key_val_pair kvp;
2162 kvp.first = key;
2163 kvp.second = val;
2164 side_to_elem_map.insert (kvp);
2165 }
2166 }
2167
2168 // Also, check the edges on this side. We don't have to worry about
2169 // updating neighbor info in this case since elements don't store
2170 // neighbor info on edges.
2171 for (auto edge_id : el->edge_index_range())
2172 {
2173 if (el->is_edge_on_side(edge_id, side_id))
2174 {
2175 // Get *all* boundary IDs on this edge, not just the first one!
2176 mesh_array[i]->get_boundary_info().edge_boundary_ids (el, edge_id, bc_ids);
2177
2178 if (std::find(bc_ids.begin(), bc_ids.end(), id_array[i]) != bc_ids.end())
2179 {
2180 std::unique_ptr<const Elem> edge (el->build_edge_ptr(edge_id));
2181 for (auto & n : edge->node_ref_range())
2182 set_array[i]->insert( n.id() );
2183
2184 h_min = std::min(h_min, edge->hmin());
2185 h_min_updated = true;
2186 }
2187 }
2188 } // end for (edge_id)
2189 } // end if (should_stitch_this_side)
2190 } // end for (side_id)
2191
2192 // Alternatively, is this a boundary NodeElem? If so,
2193 // add it to a list of NodeElems that will later be
2194 // used to set h_min based on the minimum node
2195 // separation distance between all pairs of boundary
2196 // NodeElems.
2197 if (el->type() == NODEELEM)
2198 {
2199 mesh_array[i]->get_boundary_info().boundary_ids(el->node_ptr(0), bc_ids);
2200 if (std::find(bc_ids.begin(), bc_ids.end(), id_array[i]) != bc_ids.end())
2201 {
2202 boundary_node_elems.push_back(el);
2203
2204 // Debugging:
2205 // libMesh::out << "Elem " << el->id() << " is a NodeElem on boundary " << id_array[i] << std::endl;
2206 }
2207 } // end if (el->type() == NODEELEM)
2208 } // end for (el)
2209
2210 // Compute the minimum node separation distance amongst
2211 // all boundary NodeElem pairs.
2212 {
2213 const auto N = boundary_node_elems.size();
2214 for (auto node_elem_i : make_range(N))
2215 for (auto node_elem_j : make_range(node_elem_i+1, N))
2216 {
2217 Real node_sep =
2218 (boundary_node_elems[node_elem_i]->point(0) - boundary_node_elems[node_elem_j]->point(0)).norm();
2219
2220 // We only want to consider non-coincident
2221 // boundary NodeElem pairs when determining the
2222 // minimum node separation distance.
2223 if (node_sep > 0.)
2224 {
2225 h_min = std::min(h_min, node_sep);
2226 h_min_updated = true;
2227 }
2228 } // end for (node_elem_j)
2229 } // end minimum NodeElem separation scope
2230 } // end for (i)
2231 } // end scope
2232
2233 if (verbose)
2234 {
2235 libMesh::out << "In UnstructuredMesh::stitch_meshes:\n"
2236 << "This mesh has " << this_boundary_node_ids.size()
2237 << " nodes on boundary `"
2238 << this->get_boundary_info().get_sideset_name(this_mesh_boundary_id)
2239 << "' (" << this_mesh_boundary_id << ").\n"
2240 << "Other mesh has " << other_boundary_node_ids.size()
2241 << " nodes on boundary `"
2242 << other_mesh->get_boundary_info().get_sideset_name(other_mesh_boundary_id)
2243 << "' (" << other_mesh_boundary_id << ").\n";
2244
2245 if (h_min_updated)
2246 {
2247 libMesh::out << "Minimum edge length on both surfaces is " << h_min << ".\n";
2248 }
2249 else
2250 {
2251 libMesh::out << "No minimum edge length determined on specified surfaces." << std::endl;
2252 }
2253 }
2254
2255 // At this point, if h_min==0 it means that there were at least two coincident
2256 // nodes on the surfaces being stitched, and we don't currently support that case.
2257 // (It might be possible to support, but getting it exactly right would be tricky
2258 // and probably not worth the extra complications to the "normal" case.)
2259 libmesh_error_msg_if(h_min < std::numeric_limits<Real>::epsilon(),
2260 "Coincident nodes detected on source and/or target "
2261 "surface, stitching meshes is not possible.");
2262
2263 // We require nanoflann for the "binary search" (really kd-tree)
2264 // option to work. If it's not available, turn that option off,
2265 // warn the user, and fall back on the N^2 search algorithm.
2266 if (use_binary_search)
2267 {
2268#ifndef LIBMESH_HAVE_NANOFLANN
2269 use_binary_search = false;
2270 libmesh_warning("The use_binary_search option in the "
2271 "UnstructuredMesh stitching algorithms requires nanoflann "
2272 "support. Falling back on N^2 search algorithm.");
2273#endif
2274 }
2275
2276 if (!this_boundary_node_ids.empty())
2277 {
2278 if (use_binary_search)
2279 {
2280#ifdef LIBMESH_HAVE_NANOFLANN
2281 typedef nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<Real, VectorOfNodesAdaptor>,
2282 VectorOfNodesAdaptor, 3, std::size_t> kd_tree_t;
2283
2284 // Create the dataset needed to build the kd tree with nanoflann
2285 std::vector<std::pair<Point, dof_id_type>> this_mesh_nodes(this_boundary_node_ids.size());
2286
2287 for (auto [it, ctr] = std::make_tuple(this_boundary_node_ids.begin(), 0u);
2288 it != this_boundary_node_ids.end(); ++it, ++ctr)
2289 {
2290 this_mesh_nodes[ctr].first = this->point(*it);
2291 this_mesh_nodes[ctr].second = *it;
2292 }
2293
2294 VectorOfNodesAdaptor vec_nodes_adaptor(this_mesh_nodes);
2295
2296 kd_tree_t this_kd_tree(3, vec_nodes_adaptor, 10);
2297 this_kd_tree.buildIndex();
2298
2299 // Storage for nearest neighbor in the loop below
2300 std::size_t ret_index;
2301 Real ret_dist_sqr;
2302
2303 // Loop over other mesh. For each node, find its nearest neighbor in this mesh, and fill in the maps.
2304 for (const auto & node_id : other_boundary_node_ids)
2305 {
2306 const auto & p = other_mesh->point(node_id);
2307 const Real query_pt[] = {p(0), p(1), p(2)};
2308 this_kd_tree.knnSearch(&query_pt[0], 1, &ret_index, &ret_dist_sqr);
2309
2310 // TODO: here we should use the user's specified tolerance
2311 // and the previously determined value of h_min in the
2312 // distance comparison, not just TOLERANCE^2.
2313 if (ret_dist_sqr < TOLERANCE*TOLERANCE)
2314 {
2315 node_to_node_map[this_mesh_nodes[ret_index].second] = node_id;
2316 other_to_this_node_map[node_id] = this_mesh_nodes[ret_index].second;
2317 }
2318 }
2319
2320 // If the two maps don't have the same size, it means one
2321 // node in this mesh is the nearest neighbor of several
2322 // nodes in other mesh. Since the stitching is ambiguous in
2323 // this case, we throw an error.
2324 libmesh_error_msg_if(node_to_node_map.size() != other_to_this_node_map.size(),
2325 "Error: Found multiple matching nodes in stitch_meshes");
2326#endif
2327 }
2328 else // !use_binary_search
2329 {
2330 // In the unlikely event that two meshes composed entirely of
2331 // NodeElems are being stitched together, we will not have
2332 // selected a valid h_min value yet, and the distance
2333 // comparison below will be true for essentially any two
2334 // nodes. In this case we simply fall back on an absolute
2335 // distance check.
2336 if (!h_min_updated)
2337 {
2338 libmesh_warning("No valid h_min value was found, falling back on "
2339 "absolute distance check in the N^2 search algorithm.");
2340 h_min = 1.;
2341 }
2342
2343 // Otherwise, use a simple N^2 search to find the closest matching points. This can be helpful
2344 // in the case that we have tolerance issues which cause mismatch between the two surfaces
2345 // that are being stitched.
2346 for (const auto & this_node_id : this_boundary_node_ids)
2347 {
2348 Node & this_node = this->node_ref(this_node_id);
2349
2350 bool found_matching_nodes = false;
2351
2352 for (const auto & other_node_id : other_boundary_node_ids)
2353 {
2354 const Node & other_node = other_mesh->node_ref(other_node_id);
2355
2356 Real node_distance = (this_node - other_node).norm();
2357
2358 if (node_distance < tol*h_min)
2359 {
2360 // Make sure we didn't already find a matching node!
2361 libmesh_error_msg_if(found_matching_nodes,
2362 "Error: Found multiple matching nodes in stitch_meshes");
2363
2364 node_to_node_map[this_node_id] = other_node_id;
2365 other_to_this_node_map[other_node_id] = this_node_id;
2366
2367 found_matching_nodes = true;
2368 }
2369 }
2370 }
2371 }
2372 }
2373
2374 // Build up the node_to_elems_map, using only one loop over other_mesh
2375 for (auto & el : other_mesh->element_ptr_range())
2376 {
2377 // For each node on the element, find the corresponding node
2378 // on "this" Mesh, 'this_node_id', if it exists, and push
2379 // the current element ID back onto node_to_elems_map[this_node_id].
2380 // For that we will use the reverse mapping we created at
2381 // the same time as the forward mapping.
2382 for (auto & n : el->node_ref_range())
2383 if (const auto it = other_to_this_node_map.find(/*other_node_id=*/n.id());
2384 it != other_to_this_node_map.end())
2385 node_to_elems_map[/*this_node_id=*/it->second].push_back( el->id() );
2386 }
2387
2388 if (verbose)
2389 {
2390 libMesh::out << "In UnstructuredMesh::stitch_meshes:\n"
2391 << "Found " << node_to_node_map.size()
2392 << " matching nodes.\n"
2393 << std::endl;
2394 }
2395
2396 if (enforce_all_nodes_match_on_boundaries)
2397 {
2398 std::size_t n_matching_nodes = node_to_node_map.size();
2399 std::size_t this_mesh_n_nodes = this_boundary_node_ids.size();
2400 std::size_t other_mesh_n_nodes = other_boundary_node_ids.size();
2401 libmesh_error_msg_if((n_matching_nodes != this_mesh_n_nodes) || (n_matching_nodes != other_mesh_n_nodes),
2402 "Error: We expected the number of nodes to match.");
2403 }
2404
2405 if (merge_boundary_nodes_all_or_nothing)
2406 {
2407 std::size_t n_matching_nodes = node_to_node_map.size();
2408 std::size_t this_mesh_n_nodes = this_boundary_node_ids.size();
2409 std::size_t other_mesh_n_nodes = other_boundary_node_ids.size();
2410 if ((n_matching_nodes != this_mesh_n_nodes) || (n_matching_nodes != other_mesh_n_nodes))
2411 {
2412 if (verbose)
2413 {
2414 libMesh::out << "Skipping node merging in "
2415 "UnstructuredMesh::stitch_meshes because not "
2416 "all boundary nodes were matched."
2417 << std::endl;
2418 }
2419 node_to_node_map.clear();
2420 other_to_this_node_map.clear();
2421 node_to_elems_map.clear();
2422 }
2423 }
2424 }
2425 else
2426 {
2427 if (verbose)
2428 {
2429 libMesh::out << "Skip node merging in UnstructuredMesh::stitch_meshes:" << std::endl;
2430 }
2431 }
2432
2433 dof_id_type node_delta = this->max_node_id();
2434 dof_id_type elem_delta = this->max_elem_id();
2435
2436 unique_id_type unique_delta =
2437#ifdef LIBMESH_ENABLE_UNIQUE_ID
2438 this->parallel_max_unique_id();
2439#else
2440 0;
2441#endif
2442
2443 // If other_mesh != nullptr, then we have to do a bunch of work
2444 // in order to copy it to this mesh
2445 if (this!=other_mesh)
2446 {
2447 LOG_SCOPE("stitch_meshes copying", "UnstructuredMesh");
2448
2449#ifdef LIBMESH_ENABLE_PERIODIC
2450 // Copy disjoint neighbor boundary pairs (PeriodicBoundary objects)
2451 // from `other_mesh` to `this` mesh
2452 if (other_db && !other_db->empty())
2453 {
2454 for (const auto & [bdy_id, pb_ptr] : *other_db)
2455 {
2456 const auto & pb = *pb_ptr;
2457 const boundary_id_type a = pb.myboundary;
2458 const boundary_id_type b = pb.pairedboundary;
2459
2460 if (this_db)
2461 {
2462 // Skip if identical pair already exists
2463 if (const auto * existing_pb = this_db->boundary(a))
2464 if ((existing_pb->myboundary == a && existing_pb->pairedboundary == b) ||
2465 (existing_pb->myboundary == b && existing_pb->pairedboundary == a))
2466 continue;
2467
2468 // If both boundary ids exist on this mesh but aren't paired here, refuse to create a new pair
2469 const auto & bdy_ids = this->get_boundary_info().get_boundary_ids();
2470 const bool a_exists = bdy_ids.count(a);
2471 const bool b_exists = bdy_ids.count(b);
2472 // If a and b already exist on `this`, we should be screaming and dying
2473 // unless they already have PeriodicBoundary objects connecting them too
2474 if (a_exists && b_exists && !this_db->boundary(a))
2475 libmesh_error_msg("Conflict: boundaries " << a << " and " << b
2476 << " already exist on this mesh but are not paired.");
2477 }
2478
2479 this->add_disjoint_neighbor_boundary_pairs(a, b, pb.get_corresponding_pos(Point(0.0,0.0,0.0)));
2480 }
2481 }
2482#endif // LIBMESH_ENABLE_PERIODIC
2483
2484
2485 // Increment the node_to_node_map and node_to_elems_map
2486 // to account for id offsets
2487 for (auto & pr : node_to_node_map)
2488 pr.second += node_delta;
2489
2490 for (auto & pr : node_to_elems_map)
2491 for (auto & entry : pr.second)
2492 entry += elem_delta;
2493
2494 // We run into problems when the libMesh subdomain standard (the
2495 // id defines the subdomain; the name was an afterthought) and
2496 // the MOOSE standard (the name defines the subdomain; the id
2497 // might be autogenerated) clash.
2498 //
2499 // Subdomain ids with the same name in both meshes are surely
2500 // meant to represent the same subdomain. We can just merge
2501 // them.
2502 //
2503 // Subdomain ids which don't have a name in either mesh are
2504 // almost surely meant to represent the same subdomain. We'll
2505 // just merge them.
2506 //
2507 // Subdomain ids with different names in different meshes, or
2508 // names with different ids in different meshes, are trickier.
2509 // For backwards compatibility we default to the old "just copy
2510 // all the subdomain ids over" behavior, but if requested we'll
2511 // remap any ids that appear to be clear conflicts, and we'll
2512 // scream and die if we see any ids that are ambiguous due to
2513 // being named in one mesh but not the other.
2514 std::unordered_map<subdomain_id_type, subdomain_id_type> id_remapping;
2515 if (remap_subdomain_ids)
2516 {
2517 const auto & this_map = this->get_subdomain_name_map();
2518 const auto & other_map = other_mesh->get_subdomain_name_map();
2519 std::unordered_map<std::string, subdomain_id_type> other_map_reversed;
2520 for (auto & [sid, sname] : other_map)
2521 other_map_reversed.emplace(sname, sid);
2522
2523 std::unordered_map<std::string, subdomain_id_type> this_map_reversed;
2524 for (auto & [sid, sname] : this_map)
2525 this_map_reversed.emplace(sname, sid);
2526
2527 // We don't require either mesh to be prepared, but that
2528 // means we need to check for subdomains manually.
2529 auto get_subdomains = [](const MeshBase & mesh) {
2530 std::set<subdomain_id_type> all_subdomains;
2531 for (auto & el : mesh.element_ptr_range())
2532 all_subdomains.insert(el->subdomain_id());
2533 return all_subdomains;
2534 };
2535
2536 const auto this_subdomains = get_subdomains(*this);
2537 const auto other_subdomains = get_subdomains(*other_mesh);
2538
2539 for (auto & [sid, sname] : this_map)
2540 {
2541 // The same name with the same id means we're fine. The
2542 // same name with another id means we remap their id to
2543 // ours
2544 if (const auto other_reverse_it = other_map_reversed.find(sname);
2545 other_reverse_it != other_map_reversed.end() && other_reverse_it->second != sid)
2546 id_remapping[other_reverse_it->second] = sid;
2547
2548 // The same id with a different name, we'll get to
2549 // later. The same id without any name means we don't
2550 // know what the user wants.
2551 if (other_subdomains.count(sid) && !other_map.count(sid))
2552 libmesh_error_msg("Can't safely stitch with a mesh sharing subdomain id "
2553 << sid << " but not subdomain name " << sname);
2554 }
2555
2556 subdomain_id_type next_free_id = 0;
2557 // We might try to stitch empty meshes ...
2558 if (!this_subdomains.empty())
2559 next_free_id = *this_subdomains.rbegin() + 1;
2560 if (!other_subdomains.empty())
2561 next_free_id =
2562 std::max(next_free_id,
2563 cast_int<subdomain_id_type>
2564 (*other_subdomains.rbegin() + 1));
2565
2566 for (auto & [sid, sname] : other_map)
2567 {
2568 // At this point we've figured out any remapping
2569 // necessary for an sname that we share. And we don't
2570 // need to remap any sid we don't share.
2571 if (!this_map_reversed.count(sname))
2572 {
2573 // But if we don't have this sname and we do have this
2574 // sid then we can't just merge into that.
2575 if (this_subdomains.count(sid))
2576 {
2577 // If we have this sid with no name, we don't
2578 // know what the user wants.
2579 if (!this_map.count(sid))
2580 libmesh_error_msg("Can't safely stitch with a mesh sharing subdomain id "
2581 << sid << " but under subdomain name " << sname);
2582
2583 // We have this sid under a different name, so
2584 // we just need to give the other elements a new
2585 // id.
2586
2587 // Users might have done crazy things with id
2588 // choice so let's make sure they didn't get too
2589 // crazy.
2590 libmesh_error_msg_if ((!this_subdomains.empty() &&
2591 next_free_id < *this_subdomains.rbegin()) ||
2592 (!other_subdomains.empty() &&
2593 next_free_id < *other_subdomains.rbegin()),
2594 "Subdomain id overflow");
2595
2596 id_remapping[sid] = next_free_id++;
2597 this->set_subdomain_name(next_free_id, sname);
2598 }
2599 // If we don't have this subdomain id, well, we're
2600 // about to, so we should have its name too.
2601 else
2602 this->set_subdomain_name(sid, sname);
2603 }
2604 }
2605 }
2606
2607 // Copy mesh data. If we skip the call to find_neighbors(), the lists
2608 // of neighbors will be copied verbatim from the other mesh
2609 this->copy_nodes_and_elements(*other_mesh, skip_find_neighbors,
2610 elem_delta, node_delta,
2611 unique_delta, &id_remapping);
2612
2613 // Copy BoundaryInfo from other_mesh too. We do this via the
2614 // list APIs rather than element-by-element for speed.
2615 BoundaryInfo & boundary = this->get_boundary_info();
2616 const BoundaryInfo & other_boundary = other_mesh->get_boundary_info();
2617
2618 for (const auto & t : other_boundary.build_node_list())
2619 boundary.add_node(std::get<0>(t) + node_delta,
2620 std::get<1>(t));
2621
2622 for (const auto & t : other_boundary.build_side_list())
2623 boundary.add_side(std::get<0>(t) + elem_delta,
2624 std::get<1>(t),
2625 std::get<2>(t));
2626
2627 for (const auto & t : other_boundary.build_edge_list())
2628 boundary.add_edge(std::get<0>(t) + elem_delta,
2629 std::get<1>(t),
2630 std::get<2>(t));
2631
2632 for (const auto & t : other_boundary.build_shellface_list())
2633 boundary.add_shellface(std::get<0>(t) + elem_delta,
2634 std::get<1>(t),
2635 std::get<2>(t));
2636
2637 const auto & other_ns_id_to_name = other_boundary.get_nodeset_name_map();
2638 auto & ns_id_to_name = boundary.set_nodeset_name_map();
2639 ns_id_to_name.insert(other_ns_id_to_name.begin(), other_ns_id_to_name.end());
2640
2641 const auto & other_ss_id_to_name = other_boundary.get_sideset_name_map();
2642 auto & ss_id_to_name = boundary.set_sideset_name_map();
2643 ss_id_to_name.insert(other_ss_id_to_name.begin(), other_ss_id_to_name.end());
2644
2645 const auto & other_es_id_to_name = other_boundary.get_edgeset_name_map();
2646 auto & es_id_to_name = boundary.set_edgeset_name_map();
2647 es_id_to_name.insert(other_es_id_to_name.begin(), other_es_id_to_name.end());
2648
2649 // Merge other_mesh's elemset information with ours. Throw an
2650 // error if this and other_mesh have overlapping elemset codes
2651 // that refer to different elemset ids.
2652 std::vector<dof_id_type> this_elemset_codes = this->get_elemset_codes();
2653 MeshBase::elemset_type this_id_set_to_fill, other_id_set_to_fill;
2654 for (const auto & elemset_code : other_mesh->get_elemset_codes())
2655 {
2656 // Get the elemset ids for this elemset_code on other_mesh
2657 other_mesh->get_elemsets(elemset_code, other_id_set_to_fill);
2658
2659 // Check that this elemset code does not already exist
2660 // in this mesh, or if it does, that it has the same elemset
2661 // ids associated with it.
2662 //
2663 // Note: get_elemset_codes() is guaranteed to return a
2664 // sorted vector, so we can binary search in it.
2665 auto it = Utility::binary_find(this_elemset_codes.begin(),
2666 this_elemset_codes.end(),
2667 elemset_code);
2668
2669 if (it != this_elemset_codes.end())
2670 {
2671 // This mesh has the same elemset code. Does it refer to
2672 // the same elemset ids?
2673 this->get_elemsets(elemset_code, this_id_set_to_fill);
2674
2675 // Throw an error if they don't match, otherwise we
2676 // don't need to do anything
2677 libmesh_error_msg_if(other_id_set_to_fill != this_id_set_to_fill,
2678 "Attempted to stitch together meshes with conflicting elemset codes.");
2679 }
2680 else
2681 {
2682 // Add other_mesh's elemset code to this mesh
2683 this->add_elemset_code(elemset_code, other_id_set_to_fill);
2684 }
2685 }
2686
2687 } // end if (other_mesh)
2688
2689 // Finally, we need to "merge" the overlapping nodes
2690 // We do this by iterating over node_to_elems_map and updating
2691 // the elements so that they "point" to the nodes that came
2692 // from this mesh, rather than from other_mesh.
2693 // Then we iterate over node_to_node_map and delete the
2694 // duplicate nodes that came from other_mesh.
2695
2696 {
2697 LOG_SCOPE("stitch_meshes node updates", "UnstructuredMesh");
2698
2699 // Container to catch boundary IDs passed back from BoundaryInfo.
2700 std::vector<boundary_id_type> bc_ids;
2701
2702 for (const auto & [target_node_id, elem_vec] : node_to_elems_map)
2703 {
2704 dof_id_type other_node_id = node_to_node_map[target_node_id];
2705 Node & target_node = this->node_ref(target_node_id);
2706
2707 std::size_t n_elems = elem_vec.size();
2708 for (std::size_t i=0; i<n_elems; i++)
2709 {
2710 dof_id_type elem_id = elem_vec[i];
2711 Elem * el = this->elem_ptr(elem_id);
2712
2713 // find the local node index that we want to update
2714 unsigned int local_node_index = el->local_node(other_node_id);
2715 libmesh_assert_not_equal_to(local_node_index, libMesh::invalid_uint);
2716
2717 // We also need to copy over the nodeset info here,
2718 // because the node will get deleted below
2719 this->get_boundary_info().boundary_ids(el->node_ptr(local_node_index), bc_ids);
2720 el->set_node(local_node_index, &target_node);
2721 this->get_boundary_info().add_node(&target_node, bc_ids);
2722 }
2723 }
2724 }
2725
2726 {
2727 LOG_SCOPE("stitch_meshes node deletion", "UnstructuredMesh");
2728 for (const auto & [other_node_id, this_node_id] : node_to_node_map)
2729 {
2730 // In the case that this==other_mesh, the two nodes might be the same (e.g. if
2731 // we're stitching a "sliver"), hence we need to skip node deletion in that case.
2732 if ((this == other_mesh) && (this_node_id == other_node_id))
2733 continue;
2734
2735 this->delete_node( this->node_ptr(this_node_id) );
2736 }
2737 }
2738
2739 // If find_neighbors() wasn't called in prepare_for_use(), we need to
2740 // manually loop once more over all elements adjacent to the stitched boundary
2741 // and fix their lists of neighbors.
2742 // This is done according to the following steps:
2743 // 1. Loop over all copied elements adjacent to the boundary using node_to_elems_map (trying to avoid duplicates)
2744 // 2. Look at all their sides with a nullptr neighbor and update them using side_to_elem_map if necessary
2745 // 3. Update the corresponding side in side_to_elem_map as well
2746 if (skip_find_neighbors)
2747 {
2748 LOG_SCOPE("stitch_meshes neighbor fixes", "UnstructuredMesh");
2749
2750 // Pull objects out of the loop to reduce heap operations
2751 std::unique_ptr<const Elem> my_side, their_side;
2752
2753 std::set<dof_id_type> fixed_elems;
2754 for (const auto & pr : node_to_elems_map)
2755 {
2756 std::size_t n_elems = pr.second.size();
2757 for (std::size_t i=0; i<n_elems; i++)
2758 {
2759 dof_id_type elem_id = pr.second[i];
2760 if (!fixed_elems.count(elem_id))
2761 {
2762 Elem * el = this->elem_ptr(elem_id);
2763 fixed_elems.insert(elem_id);
2764 for (auto s : el->side_index_range())
2765 {
2766 bool has_real_neighbor = (el->neighbor_ptr(s) != nullptr);
2767 bool has_disdjoint_neighbor = is_valid_disjoint_pair_to_stitch &&
2768 (this->get_boundary_info().has_boundary_id(el, s, this_mesh_boundary_id)
2769 || this->get_boundary_info().has_boundary_id(el, s, other_mesh_boundary_id));
2770
2771 if (!has_real_neighbor || has_disdjoint_neighbor)
2772 {
2773 key_type key = el->low_order_key(s);
2774 auto bounds = side_to_elem_map.equal_range(key);
2775
2776 if (bounds.first != bounds.second)
2777 {
2778 // Get the side for this element
2779 el->side_ptr(my_side, s);
2780
2781 // Look at all the entries with an equivalent key
2782 while (bounds.first != bounds.second)
2783 {
2784 // Get the potential element
2785 Elem * neighbor = const_cast<Elem *>(bounds.first->second.first);
2786
2787 // Get the side for the neighboring element
2788 const unsigned int ns = bounds.first->second.second;
2789 neighbor->side_ptr(their_side, ns);
2790 //libmesh_assert(my_side.get());
2791 //libmesh_assert(their_side.get());
2792
2793 // If found a match with my side
2794 //
2795 // We need special tests here for 1D:
2796 // since parents and children have an equal
2797 // side (i.e. a node), we need to check
2798 // ns != ms, and we also check level() to
2799 // avoid setting our neighbor pointer to
2800 // any of our neighbor's descendants
2801 if ((*my_side == *their_side) &&
2802 (el->level() == neighbor->level()) &&
2803 ((el->dim() != 1) || (ns != s)))
2804 {
2805 // So share a side. Is this a mixed pair
2806 // of subactive and active/ancestor
2807 // elements?
2808 // If not, then we're neighbors.
2809 // If so, then the subactive's neighbor is
2810
2811 if (el->subactive() ==
2812 neighbor->subactive())
2813 {
2814 // an element is only subactive if it has
2815 // been coarsened but not deleted
2816 el->set_neighbor (s,neighbor);
2817 neighbor->set_neighbor(ns,el);
2818 }
2819 else if (el->subactive())
2820 {
2821 el->set_neighbor(s,neighbor);
2822 }
2823 else if (neighbor->subactive())
2824 {
2825 neighbor->set_neighbor(ns,el);
2826 }
2827 // It's OK to invalidate the
2828 // bounds.first iterator here,
2829 // as we are immediately going
2830 // to break out of this while
2831 // loop. bounds.first will
2832 // therefore not be used for
2833 // anything else.
2834 side_to_elem_map.erase (bounds.first);
2835 break;
2836 }
2837
2838 ++bounds.first;
2839 }
2840 }
2841 }
2842 }
2843 }
2844 }
2845 }
2846 }
2847
2848#ifdef LIBMESH_ENABLE_PERIODIC
2849 // Remove only the disjoint pair that was actually stitched.
2850 // Safe because `is_valid_disjoint_pair_to_stitch` is true
2851 // only if this exact (a,b) pair exists in the registry.
2852 // Other disjoint pairs remain untouched.
2853 if (is_valid_disjoint_pair_to_stitch)
2854 this->remove_disjoint_boundary_pair(this_mesh_boundary_id, other_mesh_boundary_id);
2855#endif
2856
2857 if (prepare_after_stitching)
2858 {
2859 // We set our new neighbor pointers already
2860 const bool old_allow_find_neighbors = this->allow_find_neighbors();
2861 this->allow_find_neighbors(!skip_find_neighbors);
2862
2863 // We haven't newly remoted any elements
2864 const bool old_allow_remote_element_removal = this->allow_remote_element_removal();
2865 this->allow_remote_element_removal(false);
2866
2867 this->prepare_for_use();
2868
2869 this->allow_find_neighbors(old_allow_find_neighbors);
2870 this->allow_remote_element_removal(old_allow_remote_element_removal);
2871 }
2872
2873 // After the stitching, we may want to clear boundary IDs from element
2874 // faces that are now internal to the mesh
2875 if (clear_stitched_boundary_ids)
2876 {
2877 LOG_SCOPE("stitch_meshes clear bcids", "UnstructuredMesh");
2878
2880 this_mesh_boundary_id, other_mesh_boundary_id, /*clear_nodeset_data=*/true);
2881 }
2882
2883 // Return the number of nodes which were merged.
2884 return node_to_node_map.size();
2885}
The BoundaryInfo class contains information relevant to boundary conditions including storing faces,...
bool has_boundary_id(const Node *const node, const boundary_id_type id) const
void edge_boundary_ids(const Elem *const elem, const unsigned short int edge, std::vector< boundary_id_type > &vec_to_fill) const
void clear_stitched_boundary_side_ids(boundary_id_type sideset_id, boundary_id_type other_sideset_id, bool clear_nodeset_data=false)
Clear sideset information along a stitched mesh interface.
std::map< boundary_id_type, std::string > & set_sideset_name_map()
const std::set< boundary_id_type > & get_boundary_ids() const
const std::string & get_sideset_name(boundary_id_type id) const
void add_node(const Node *node, const boundary_id_type id)
Add Node node with boundary id id to the boundary information data structures.
static const boundary_id_type invalid_id
Number used for internal use.
std::map< boundary_id_type, std::string > & set_edgeset_name_map()
std::map< boundary_id_type, std::string > & set_nodeset_name_map()
virtual dof_id_type low_order_key(const unsigned int s) const =0
unsigned int local_node(const dof_id_type i) const
Definition elem.h:2617
virtual unsigned short dim() const =0
const Node * node_ptr(const unsigned int i) const
Definition elem.h:2637
void set_subdomain_name(subdomain_id_type id, const std::string &name, bool synchronous=false)
Sets the name for the provided id.
Definition mesh_base.C:1929
virtual const Point & point(const dof_id_type i) const =0
std::vector< dof_id_type > get_elemset_codes() const
Return a vector of all elemset codes defined on the mesh.
Definition mesh_base.C:508
virtual Node * add_node(Node *n)=0
Add Node n to the end of the vertex array.
virtual dof_id_type max_elem_id() const =0
void get_elemsets(dof_id_type elemset_code, MeshBase::elemset_type &id_set_to_fill) const
Look up the element sets for a given elemset code and vice-versa.
Definition mesh_base.C:492
void remove_disjoint_boundary_pair(const boundary_id_type b1, const boundary_id_type b2)
Definition mesh_base.C:2321
void add_disjoint_neighbor_boundary_pairs(const boundary_id_type b1, const boundary_id_type b2, const RealVectorValue &translation)
Register a pair of boundaries as disjoint neighbor boundary pairs.
Definition mesh_base.C:2287
Temporarily serialize a DistributedMesh for non-distributed-mesh capable code paths.
We're using a class instead of a typedef to allow forward declarations and future flexibility.
PeriodicBoundaryBase * boundary(boundary_id_type id)
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:41
virtual void copy_nodes_and_elements(const MeshBase &other_mesh, const bool skip_find_neighbors=false, dof_id_type element_id_offset=0, dof_id_type node_id_offset=0, unique_id_type unique_id_offset=0, std::unordered_map< subdomain_id_type, subdomain_id_type > *id_remapping=nullptr, const bool skip_preparation=false)
Deep copy of nodes and elements from another mesh object (used by subclass copy constructors and by m...
static const Real b
MeshBase & mesh
LIBMESH_DEVICE_INLINE auto norm(const T &a)
ForwardIterator binary_find(ForwardIterator first, ForwardIterator last, const T &value)
The STL provides std::binary_search() which returns true or false depending on whether the searched-f...
Definition utility.h:233
const boundary_id_type side_id

References libMesh::MeshBase::add_disjoint_neighbor_boundary_pairs(), libMesh::BoundaryInfo::add_edge(), libMesh::MeshBase::add_elemset_code(), libMesh::BoundaryInfo::add_node(), libMesh::BoundaryInfo::add_shellface(), libMesh::BoundaryInfo::add_side(), libMesh::MeshBase::allow_find_neighbors(), libMesh::MeshBase::allow_remote_element_removal(), b, libMesh::Utility::binary_find(), libMesh::PeriodicBoundaries::boundary(), libMesh::BoundaryInfo::boundary_ids(), libMesh::BoundaryInfo::build_edge_list(), libMesh::BoundaryInfo::build_node_list(), libMesh::BoundaryInfo::build_shellface_list(), libMesh::BoundaryInfo::build_side_list(), libMesh::BoundaryInfo::clear_stitched_boundary_side_ids(), libMesh::UnstructuredMesh::copy_nodes_and_elements(), libMesh::MeshBase::delete_node(), libMesh::Elem::dim(), libMesh::BoundaryInfo::edge_boundary_ids(), libMesh::MeshBase::elem_ptr(), libMesh::UnstructuredMesh::find_neighbors(), libMesh::BoundaryInfo::get_boundary_ids(), libMesh::MeshBase::get_boundary_info(), libMesh::MeshBase::get_disjoint_neighbor_boundary_pairs(), libMesh::BoundaryInfo::get_edgeset_name_map(), libMesh::MeshBase::get_elemset_codes(), libMesh::MeshBase::get_elemsets(), libMesh::BoundaryInfo::get_nodeset_name_map(), libMesh::BoundaryInfo::get_sideset_name(), libMesh::BoundaryInfo::get_sideset_name_map(), libMesh::MeshBase::get_subdomain_name_map(), libMesh::BoundaryInfo::has_boundary_id(), libMesh::BoundaryInfo::invalid_id, libMesh::invalid_uint, libMesh::MeshBase::is_prepared(), libMesh::Elem::level(), libMesh::MeshTools::libmesh_assert_valid_neighbors(), libMesh::Elem::local_node(), libMesh::Elem::low_order_key(), libMesh::make_range(), libMesh::MeshBase::max_elem_id(), libMesh::MeshBase::max_node_id(), mesh, libMesh::Elem::neighbor_ptr(), libMesh::MeshBase::node_ptr(), libMesh::Elem::node_ptr(), libMesh::MeshBase::node_ref(), libMesh::NODEELEM, libMesh::out, libMesh::MeshBase::parallel_max_unique_id(), libMesh::MeshBase::point(), libMesh::MeshBase::prepare_for_use(), libMesh::Real, libMesh::MeshBase::remove_disjoint_boundary_pair(), libMesh::BoundaryInfo::set_edgeset_name_map(), libMesh::Elem::set_neighbor(), libMesh::Elem::set_node(), libMesh::BoundaryInfo::set_nodeset_name_map(), libMesh::BoundaryInfo::set_sideset_name_map(), libMesh::MeshBase::set_subdomain_name(), side_id, libMesh::Elem::side_index_range(), libMesh::Elem::side_ptr(), libMesh::Elem::subactive(), and libMesh::TOLERANCE.

Referenced by libMesh::UnstructuredMesh::stitch_meshes(), and libMesh::UnstructuredMesh::stitch_surfaces().

◆ sub_point_locator()

std::unique_ptr< PointLocatorBase > libMesh::MeshBase::sub_point_locator ( ) const
inherited
Returns
A pointer to a subordinate PointLocatorBase object for this mesh, constructing a master PointLocator first if necessary. This should not be used in threaded or non-parallel_only code unless the master has already been constructed.

Definition at line 1848 of file mesh_base.C.

1849{
1850 // If there's no master point locator, then we need one.
1851 if (_point_locator.get() == nullptr)
1852 {
1853 // PointLocator construction may not be safe within threads
1855
1856 // And it may require parallel communication
1857 parallel_object_only();
1858
1859#ifdef LIBMESH_ENABLE_NANOFLANN_POINTLOCATOR
1861#else
1863#endif
1864
1866 _point_locator->set_close_to_point_tol(_point_locator_close_to_point_tol);
1867 }
1868
1869 // Otherwise there was a master point locator, and we can grab a
1870 // sub-locator easily.
1871 return
1872#ifdef LIBMESH_ENABLE_NANOFLANN_POINTLOCATOR
1874#else
1876#endif
1877}
static std::unique_ptr< PointLocatorBase > build(PointLocatorType t, const MeshBase &mesh, const PointLocatorBase *master=nullptr)
Builds an PointLocator for the mesh mesh.

References libMesh::MeshBase::_point_locator, libMesh::MeshBase::_point_locator_close_to_point_tol, libMesh::PointLocatorBase::build(), libMesh::Threads::in_threads, libMesh::libmesh_assert(), libMesh::NANOFLANN, and libMesh::TREE_ELEMENTS.

Referenced by WriteElemsetData::checkElemsetCodes(), libMesh::DofMap::create_dof_constraints(), libMesh::UnstructuredMesh::find_neighbors(), libMesh::MeshFunction::init(), libMesh::MeshTools::libmesh_assert_consistent_distributed_nodes(), main(), libMesh::DefaultCoupling::mesh_reinit(), libMesh::OverlapCoupling::mesh_reinit(), libMesh::PointNeighborCoupling::mesh_reinit(), MeshPerElemTest< elem_type >::meshes_equal_enough(), OverlappingCouplingFunctor::operator()(), MeshFunctionTest::test_bad_gradient_var_with_out_of_mesh_value(), MeshFunctionTest::test_bad_hessian_var_with_out_of_mesh_value(), PointLocatorTest::testLocator(), MeshInputTest::testMasterCenters(), PointLocatorTest::testPlanar(), SystemsTest::testProjectCube(), SystemsTest::testProjectLine(), and SystemsTest::testProjectSquare().

◆ subclass_locally_equals()

bool libMesh::DistributedMesh::subclass_locally_equals ( const MeshBase &  other_mesh) const
overridevirtualinherited

Shim to allow operator == (&) to behave like a virtual function without having to be one.

Implements libMesh::MeshBase.

Definition at line 98 of file distributed_mesh.C.

99{
100 const DistributedMesh * dist_mesh_ptr =
101 dynamic_cast<const DistributedMesh *>(&other_mesh_base);
102 if (!dist_mesh_ptr)
103 return false;
104 const DistributedMesh & other_mesh = *dist_mesh_ptr;
105
106 if (_is_serial != other_mesh._is_serial ||
107 _is_serial_on_proc_0 != other_mesh._is_serial_on_proc_0 ||
108 _deleted_coarse_elements != other_mesh._deleted_coarse_elements ||
109 _n_nodes != other_mesh._n_nodes ||
110 _n_elem != other_mesh._n_elem ||
111 _max_node_id != other_mesh._max_node_id ||
112 _max_elem_id != other_mesh._max_elem_id ||
113 // We expect these things to change in a prepare_for_use();
114 // they're conceptually "mutable"...
115/*
116 _next_free_local_node_id != other_mesh._next_free_local_node_id ||
117 _next_free_local_elem_id != other_mesh._next_free_local_elem_id ||
118 _next_free_unpartitioned_node_id != other_mesh._next_free_unpartitioned_node_id ||
119 _next_free_unpartitioned_elem_id != other_mesh._next_free_unpartitioned_elem_id ||
120#ifdef LIBMESH_ENABLE_UNIQUE_ID
121 _next_unpartitioned_unique_id != other_mesh._next_unpartitioned_unique_id ||
122#endif
123*/
124 !this->nodes_and_elements_equal(other_mesh))
125 return false;
126
127 if (_extra_ghost_elems.size() !=
128 other_mesh._extra_ghost_elems.size())
129 return false;
130 for (auto & elem : _extra_ghost_elems)
131 {
132 libmesh_assert(this->query_elem_ptr(elem->id()) == elem);
133 const Elem * other_elem = other_mesh.query_elem_ptr(elem->id());
134 if (!other_elem ||
135 !other_mesh._extra_ghost_elems.count(const_cast<Elem *>(other_elem)))
136 return false;
137 }
138
139 return true;
140}
virtual const Elem * query_elem_ptr(const dof_id_type i) const override final

References libMesh::DistributedMesh::_deleted_coarse_elements, libMesh::DistributedMesh::_extra_ghost_elems, libMesh::DistributedMesh::_is_serial, libMesh::DistributedMesh::_is_serial_on_proc_0, libMesh::DistributedMesh::_max_elem_id, libMesh::DistributedMesh::_max_node_id, libMesh::DistributedMesh::_n_elem, libMesh::DistributedMesh::_n_nodes, libMesh::libmesh_assert(), and libMesh::DistributedMesh::query_elem_ptr().

◆ subdomain_ids()

void libMesh::MeshBase::subdomain_ids ( std::set< subdomain_id_type > &  ids,
const bool  global = true 
) const
inherited

Constructs a list of all subdomain identifiers in the local mesh if global == false, and in the global mesh if global == true (default).

Subdomains correspond to separate subsets of the mesh which could correspond e.g. to different materials in a solid mechanics application, or regions where different physical processes are important. The subdomain mapping is independent from the parallel decomposition.

Unpartitioned elements are included in the set in the case that global == true. If global == false, the unpartitioned elements are not included because unpartitioned elements do not have a sense of locality.

Definition at line 1127 of file mesh_base.C.

1128{
1129 // This requires an inspection on every processor
1130 if (global)
1131 parallel_object_only();
1132
1133 struct SBDInserter {
1134 std::set<subdomain_id_type> my_ids;
1135
1136 SBDInserter () {}
1137 SBDInserter (SBDInserter &, Threads::split) {}
1138
1139 void operator()(const ConstElemRange & range) {
1140 for (const Elem * elem : range)
1141 my_ids.insert(elem->subdomain_id());
1142 }
1143
1144 void join(SBDInserter & other) {
1145 my_ids.merge(other.my_ids);
1146 }
1147 };
1148
1149 SBDInserter inserter;
1151
1152 ids.swap(inserter.my_ids);
1153
1154 if (global)
1155 {
1156 // Only include the unpartitioned elements if the user requests the global IDs.
1157 // In the case of the local subdomain IDs, it doesn't make sense to include the
1158 // unpartitioned elements because said elements do not have a sense of locality.
1159 for (const auto & elem : this->active_unpartitioned_element_ptr_range())
1160 ids.insert(elem->subdomain_id());
1161
1162 // Some subdomains may only live on other processors
1163 this->comm().set_union(ids);
1164 }
1165}
const ConstElemRange & active_local_element_stored_range() const
Definition mesh_base.C:1969
void parallel_reduce(const Range &range, Body &body, unsigned int n_threads=libMesh::n_threads())
Execute the provided reduction operation in parallel on the specified range.

References libMesh::MeshBase::active_local_element_stored_range(), libMesh::ParallelObject::comm(), libMesh::Threads::parallel_reduce(), and libMesh::Parallel::Communicator::set_union().

Referenced by libMesh::MeshBase::copy_constraint_rows(), libMesh::ReplicatedMesh::get_disconnected_subdomains(), libMesh::MeshBase::n_local_subdomains(), libMesh::MeshBase::n_subdomains(), OverlappingCouplingFunctor::OverlappingCouplingFunctor(), libMesh::TecplotIO::TecplotIO(), MeshSubdomainIDTest::testMultiple(), and MeshSubdomainIDTest::testUnpartitioned().

◆ subdomain_name() [1/2]

std::string & libMesh::MeshBase::subdomain_name ( subdomain_id_type  id)
inherited
Deprecated:
Returns
A writable reference for setting an optional name for a subdomain. This method is deprecated; use set_subdomain_name() instead.

Definition at line 1902 of file mesh_base.C.

1903{
1904 // Use set_subdomain_name() instead
1905 libmesh_deprecated();
1906
1907 // We'd like to do this so our preparation isn't invalidated by a
1908 // write, but for all we know the user is just reading from a
1909 // non-const mesh!
1910 // this->unset_has_synched_subdomain_name_map();
1911
1912 return _block_id_to_name[id];
1913}

References libMesh::MeshBase::_block_id_to_name.

Referenced by DMlibMeshSetSystem_libMesh(), MeshInputTest::testGmshBCIDOverlap(), libMesh::TecplotIO::write_binary(), and libMesh::ExodusII_IO_Helper::write_elements().

◆ subdomain_name() [2/2]

const std::string & libMesh::MeshBase::subdomain_name ( subdomain_id_type  id) const
inherited
Returns
A reference for getting an optional name for a subdomain.

Definition at line 1917 of file mesh_base.C.

1918{
1919 // An empty string to return when no matching subdomain name is found
1920 static const std::string empty;
1921
1922 if (const auto iter = _block_id_to_name.find(id);
1923 iter == _block_id_to_name.end())
1924 return empty;
1925 else
1926 return iter->second;
1927}

References libMesh::MeshBase::_block_id_to_name.

◆ supported_nodal_order()

Order libMesh::MeshBase::supported_nodal_order ( ) const
inlineinherited
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.

Definition at line 2666 of file mesh_base.h.

References libMesh::MeshBase::_preparation, libMesh::MeshBase::_supported_nodal_order, libMesh::MeshBase::Preparation::has_cached_elem_data, and libMesh::libmesh_assert().

◆ sync_subdomain_name_map()

void libMesh::MeshBase::sync_subdomain_name_map ( )
inherited

libMesh often expects all processors to know about names of all subdomain ids, but distributed mesh generators may only know about part of a mesh when creating names.

This method can synchronize the subdomain id to name map across processors, assuming no conflicts exist. It is called automatically during complete_preparation() unless the map is already known to be synchronized.

Definition at line 2081 of file mesh_base.C.

2082{
2083 // This requires every processor
2084 parallel_object_only();
2085
2087
2089}

References libMesh::MeshBase::_block_id_to_name, libMesh::MeshBase::_preparation, libMesh::ParallelObject::comm(), libMesh::MeshBase::Preparation::has_synched_subdomain_name_map, and libMesh::Parallel::Communicator::set_union().

Referenced by libMesh::MeshBase::complete_preparation().

◆ unset_has_boundary_id_sets()

void libMesh::MeshBase::unset_has_boundary_id_sets ( )
inlineinherited

Tells this we have done some operation which may have invalidated our cached boundary id sets.

User code which removes elements, or which adds or removes boundary entries, should call this method.

Definition at line 340 of file mesh_base.h.

References libMesh::MeshBase::_preparation, and libMesh::MeshBase::Preparation::has_boundary_id_sets.

Referenced by libMesh::BoundaryInfo::add_elements(), and MeshBaseTest::testMeshBaseVerifyRemovalPreparation().

◆ unset_has_cached_elem_data()

void libMesh::MeshBase::unset_has_cached_elem_data ( )
inlineinherited

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.

User code which adds new elements to this mesh must call this function.

Definition at line 281 of file mesh_base.h.

References libMesh::MeshBase::_preparation, and libMesh::MeshBase::Preparation::has_cached_elem_data.

Referenced by libMesh::BoundaryInfo::add_elements(), libMesh::MeshTools::Modification::change_subdomain_id(), libMesh::MeshTools::Modification::redistribute(), libMesh::MeshTools::Modification::rotate(), libMesh::MeshTools::Modification::scale(), MeshBaseTest::testMeshBaseVerifyHasCachedElemData(), and libMesh::MeshTools::Modification::translate().

◆ unset_has_interior_parent_ptrs()

void libMesh::MeshBase::unset_has_interior_parent_ptrs ( )
inlineinherited

Tells this we have done some operation (e.g.

refining elements with interior parents) which requires interior parent pointers to be found later.

Most user code will not need to call this method; any user code that manipulates interior parents or their boundary elements may be an exception.

Definition at line 293 of file mesh_base.h.

References libMesh::MeshBase::_preparation, and libMesh::MeshBase::Preparation::has_interior_parent_ptrs.

◆ unset_has_neighbor_ptrs()

void libMesh::MeshBase::unset_has_neighbor_ptrs ( )
inlineinherited

Tells this we have done some operation (e.g.

adding elements without setting their neighbor pointers, or adding disjoint neighbor boundary pairs) which requires neighbor pointers to be determined later.

User code which adds new elements to this mesh must call this function or manually set neighbor pointer from and to those elements.

Definition at line 270 of file mesh_base.h.

References libMesh::MeshBase::_preparation, and libMesh::MeshBase::Preparation::has_neighbor_ptrs.

Referenced by libMesh::BoundaryInfo::add_elements(), and MeshBaseTest::testMeshBaseVerifyHasNeighborPtrs().

◆ unset_has_reinit_ghosting_functors()

void libMesh::MeshBase::unset_has_reinit_ghosting_functors ( )
inlineinherited

Tells this we have done some operation (e.g.

adding or removing elements) which may require a reinit() of custom ghosting functors.

User code which adds or removes elements should call this method. User code which moves nodes ... should probably call this method, in case ghosting functors depending on position exist?

Definition at line 330 of file mesh_base.h.

References libMesh::MeshBase::_preparation, and libMesh::MeshBase::Preparation::has_reinit_ghosting_functors.

Referenced by libMesh::BoundaryInfo::add_elements().

◆ unset_has_removed_orphaned_nodes()

void libMesh::MeshBase::unset_has_removed_orphaned_nodes ( )
inlineinherited

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. User code which deletes elements without carefully deleting orphaned nodes should call this manually.

Definition at line 318 of file mesh_base.h.

References libMesh::MeshBase::_preparation, and libMesh::MeshBase::Preparation::has_removed_orphaned_nodes.

Referenced by MeshBaseTest::testMeshBaseVerifyRemovalPreparation().

◆ unset_has_removed_remote_elements()

void libMesh::MeshBase::unset_has_removed_remote_elements ( )
inlineinherited

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. Any user code which manually repartitions elements on distributed meshes may need to call this manually, in addition to manually communicating elements with newly-created ghosting requirements.

Definition at line 307 of file mesh_base.h.

References libMesh::MeshBase::_preparation, and libMesh::MeshBase::Preparation::has_removed_remote_elements.

◆ unset_has_synched_id_counts()

void libMesh::MeshBase::unset_has_synched_id_counts ( )
inlineinherited

Tells this we have done some operation (e.g.

adding objects to a distributed mesh on one processor only) which can lose synchronization of id counts.

User code which does distributed additions of nodes or elements must call either this method or update_parallel_id_counts().

Definition at line 257 of file mesh_base.h.

References libMesh::MeshBase::_preparation, and libMesh::MeshBase::Preparation::has_synched_id_counts.

Referenced by DistributedMeshTest::testCopyConstructorUnsynchedIdCounts().

◆ unset_has_synched_subdomain_name_map()

void libMesh::MeshBase::unset_has_synched_subdomain_name_map ( )
inlineinherited

Tells this we have done some operation which may have left the subdomain id to name map inconsistent across processors.

User code which adds or changes subdomain names should call this method.

Definition at line 350 of file mesh_base.h.

References libMesh::MeshBase::_preparation, and libMesh::MeshBase::Preparation::has_synched_subdomain_name_map.

Referenced by libMesh::MeshBase::set_subdomain_name(), and libMesh::MeshBase::set_subdomain_name_map().

◆ unset_is_partitioned()

void libMesh::MeshBase::unset_is_partitioned ( )
inlineinherited

Tells this we have done some operation creating unpartitioned elements.

User code which adds elements to this mesh must either partition them too or call this method.

Definition at line 246 of file mesh_base.h.

247 { _preparation.is_partitioned = false; }

References libMesh::MeshBase::_preparation, and libMesh::MeshBase::Preparation::is_partitioned.

Referenced by MeshBaseTest::testMeshBaseVerifyRemovalPreparation().

◆ unset_is_prepared()

void libMesh::MeshBase::unset_is_prepared ( )
inherited

Tells this we have done some operation where we should no longer consider ourself prepared.

This is a very coarse setting; it is generally more efficient to mark finer-grained settings instead.

Definition at line 1071 of file mesh_base.C.

1072{
1073 _preparation = false;
1074 this->clear_point_locator();
1075 this->clear_stored_ranges();
1076}

References libMesh::MeshBase::_preparation, libMesh::MeshBase::clear_point_locator(), and libMesh::MeshBase::clear_stored_ranges().

Referenced by libMesh::UnstructuredMesh::copy_nodes_and_elements(), and MeshTetTest::testTrisToTets().

◆ update_parallel_id_counts()

void libMesh::DistributedMesh::update_parallel_id_counts ( )
overridevirtualinherited

Updates parallel caches so that methods like n_elem() accurately reflect changes on other processors.

Implements libMesh::MeshBase.

Definition at line 331 of file distributed_mesh.C.

332{
333 // This function must be run on all processors at once
334 parallel_object_only();
335
336 _n_elem = this->parallel_n_elem();
337 _n_nodes = this->parallel_n_nodes();
340
341 this->set_next_ids();
342
343 // set_next_unique_ids() needs the true parallel max unique id (not just
344 // this processor's possibly-stale cached _next_unique_id) since the whole
345 // point of this function is to recompute counters that may have drifted
346 // out of sync.
347#ifdef LIBMESH_ENABLE_UNIQUE_ID
349#endif
350
352
354}
void set_next_ids()
Derives _next_free_local_node_id, _next_free_local_elem_id, _next_free_unpartitioned_node_id,...
void set_next_unique_ids(unique_id_type parallel_max_unique_id)
Derives _next_unique_id and _next_unpartitioned_unique_id from parallel_max_unique_id,...

References libMesh::DistributedMesh::_max_elem_id, libMesh::DistributedMesh::_max_node_id, libMesh::MeshBase::_n_constraint_rows, libMesh::DistributedMesh::_n_elem, libMesh::DistributedMesh::_n_nodes, libMesh::MeshBase::_preparation, libMesh::MeshBase::count_constraint_rows(), libMesh::MeshBase::Preparation::has_synched_id_counts, libMesh::DistributedMesh::parallel_max_elem_id(), libMesh::DistributedMesh::parallel_max_node_id(), libMesh::DistributedMesh::parallel_max_unique_id(), libMesh::DistributedMesh::parallel_n_elem(), libMesh::DistributedMesh::parallel_n_nodes(), libMesh::DistributedMesh::set_next_ids(), and libMesh::DistributedMesh::set_next_unique_ids().

Referenced by libMesh::DistributedMesh::delete_remote_elements(), libMesh::DistributedMesh::redistribute(), libMesh::DistributedMesh::renumber_nodes_and_elements(), and libMesh::DistributedMesh::update_post_partitioning().

◆ update_post_partitioning()

void libMesh::DistributedMesh::update_post_partitioning ( )
overridevirtualinherited

Recalculate cached data after elements and nodes have been repartitioned.

Reimplemented from libMesh::MeshBase.

Definition at line 1148 of file distributed_mesh.C.

1149{
1150 // this->recalculate_n_partitions();
1151
1152 // Let's do the base class cache clearing first, just in case our
1153 // later computations are ever changed to make use of a local
1154 // elements range cache
1156
1157 // Partitioning changes our numbers of unpartitioned objects
1159}

References libMesh::DistributedMesh::update_parallel_id_counts(), and libMesh::MeshBase::update_post_partitioning().

◆ write() [1/2]

void libMesh::UnstructuredMesh::write ( const std::string &  name) const
overridevirtualinherited

Write the file specified by name.

Attempts to figure out the proper method by the file extension.

Implements libMesh::MeshBase.

Definition at line 1449 of file unstructured_mesh.C.

1450{
1451 LOG_SCOPE("write()", "Mesh");
1452
1453 NameBasedIO(*this).write(name);
1454}

References libMesh::NameBasedIO::write().

Referenced by main().

◆ write() [2/2]

void libMesh::UnstructuredMesh::write ( const std::string &  name,
const std::vector< Number > &  values,
const std::vector< std::string > &  variable_names 
) const
inherited

Write to the file specified by name.

Attempts to figure out the proper method by the file extension. Also writes data.

Definition at line 1458 of file unstructured_mesh.C.

1461{
1462 LOG_SCOPE("write()", "Mesh");
1463
1464 NameBasedIO(*this).write_nodal_data(name, v, vn);
1465}
virtual void write_nodal_data(const std::string &, const std::vector< Number > &, const std::vector< std::string > &) override
This method implements writing a mesh with nodal data to a specified file where the nodal data and va...

References libMesh::NameBasedIO::write_nodal_data().

Member Data Documentation

◆ _all_elemset_ids

MeshBase::elemset_type libMesh::MeshBase::_all_elemset_ids
protectedinherited

◆ _allow_node_and_elem_unique_id_overlap

bool libMesh::MeshBase::_allow_node_and_elem_unique_id_overlap
protectedinherited

The Exodus reader (and potentially other readers in the future?) now supports setting Node and Elem unique_ids based on values from within the Exodus file itself, rather than generating them automatically in LibMesh.

In this case, the unique_ids will not necessarily be unique across the set of all DofObjects, although they should still be unique within the individual sets of Elems and Nodes. The reader can therefore set this Mesh flag (which defaults to false) to indicate we should be less strict when checking the "uniqueness" of unique_ids.

Definition at line 2313 of file mesh_base.h.

Referenced by libMesh::MeshBase::allow_node_and_elem_unique_id_overlap(), libMesh::MeshBase::allow_node_and_elem_unique_id_overlap(), libMesh::MeshBase::locally_equals(), and libMesh::MeshBase::operator=().

◆ _allow_remote_element_removal

bool libMesh::MeshBase::_allow_remote_element_removal
protectedinherited

◆ _block_id_to_name

std::map<subdomain_id_type, std::string> libMesh::MeshBase::_block_id_to_name
protectedinherited

◆ _communicator

const Parallel::Communicator& libMesh::ParallelObject::_communicator
protectedinherited

◆ _const_active_local_element_stored_range

std::unique_ptr<ConstElemRange> libMesh::MeshBase::_const_active_local_element_stored_range
mutableprotectedinherited

A cached ConstElemRange for threaded calculation on all local elements of this mesh.

This will not actually be built unless needed. Further, since we want our elem_stored_range() method to be const (yet do the dynamic allocating) this needs to be mutable.

Definition at line 2228 of file mesh_base.h.

Referenced by libMesh::MeshBase::active_local_element_stored_range(), libMesh::MeshBase::clear_stored_ranges(), libMesh::MeshBase::operator=(), and libMesh::MeshBase::update_post_partitioning().

◆ _constraint_rows

constraint_rows_type libMesh::MeshBase::_constraint_rows
protectedinherited

◆ _count_lower_dim_elems_in_point_locator

bool libMesh::MeshBase::_count_lower_dim_elems_in_point_locator
protectedinherited

Do we count lower dimensional elements in point locator refinement? This is relevant in tree-based point locators, for example.

Definition at line 2243 of file mesh_base.h.

Referenced by libMesh::MeshBase::get_count_lower_dim_elems_in_point_locator(), libMesh::MeshBase::locally_equals(), libMesh::MeshBase::operator=(), and libMesh::MeshBase::set_count_lower_dim_elems_in_point_locator().

◆ _default_ghosting

std::unique_ptr<GhostingFunctor> libMesh::MeshBase::_default_ghosting
protectedinherited

The default geometric GhostingFunctor, used to implement standard libMesh element ghosting behavior.

We use a base class pointer here to avoid dragging in more header dependencies.

Definition at line 2427 of file mesh_base.h.

Referenced by libMesh::MeshBase::default_ghosting(), libMesh::MeshBase::locally_equals(), libMesh::MeshBase::MeshBase(), libMesh::MeshBase::MeshBase(), and libMesh::MeshBase::post_dofobject_moves().

◆ _default_mapping_data

unsigned char libMesh::MeshBase::_default_mapping_data
protectedinherited

The default mapping data (unused with Lagrange, used for nodal weight lookup index with rational bases) to assign to newly added elements.

Definition at line 2202 of file mesh_base.h.

Referenced by libMesh::MeshBase::default_mapping_data(), libMesh::MeshBase::locally_equals(), libMesh::MeshBase::operator=(), and libMesh::MeshBase::set_default_mapping_data().

◆ _default_mapping_type

ElemMappingType libMesh::MeshBase::_default_mapping_type
protectedinherited

The default mapping type (typically Lagrange) between master and physical space to assign to newly added elements.

Definition at line 2195 of file mesh_base.h.

Referenced by libMesh::MeshBase::default_mapping_type(), libMesh::MeshBase::locally_equals(), libMesh::MeshBase::operator=(), and libMesh::MeshBase::set_default_mapping_type().

◆ _deleted_coarse_elements

bool libMesh::DistributedMesh::_deleted_coarse_elements
inherited

A boolean remembering whether we've recently deleted top-level elements or not.

If so, we'll need to be extra careful when deleting "unused" nodes they used to have, because those nodes might still be used by ghost elements.

Definition at line 441 of file distributed_mesh.h.

Referenced by libMesh::DistributedMesh::clear(), libMesh::DistributedMesh::delete_elem(), libMesh::DistributedMesh::DistributedMesh(), libMesh::DistributedMesh::renumber_nodes_and_elements(), and libMesh::DistributedMesh::subclass_locally_equals().

◆ _disjoint_neighbor_boundary_pairs

std::unique_ptr<PeriodicBoundaries> libMesh::MeshBase::_disjoint_neighbor_boundary_pairs
protectedinherited

◆ _elem_default_orders

std::set<Order> libMesh::MeshBase::_elem_default_orders
protectedinherited

We cache the (default) order of the geometric elements present in the mesh.

E.g. if we have a mesh with TRI3 and TRI6 elements, this structure will contain FIRST and SECOND.

Definition at line 2334 of file mesh_base.h.

Referenced by libMesh::MeshBase::cache_elem_data(), libMesh::MeshBase::clear(), libMesh::MeshBase::copy_cached_data(), libMesh::MeshBase::copy_constraint_rows(), libMesh::MeshBase::elem_default_orders(), libMesh::MeshBase::get_info(), libMesh::MeshBase::locally_equals(), and libMesh::MeshBase::operator=().

◆ _elem_dims

std::set<unsigned char> libMesh::MeshBase::_elem_dims
protectedinherited

◆ _elem_integer_default_values

std::vector<dof_id_type> libMesh::MeshBase::_elem_integer_default_values
protectedinherited

◆ _elem_integer_names

std::vector<std::string> libMesh::MeshBase::_elem_integer_names
protectedinherited

◆ _element_stored_range

std::unique_ptr<ElemRange> libMesh::MeshBase::_element_stored_range
mutableprotectedinherited

A cached ElemRange for threaded mutation of all semilocal elements of this mesh.

This will not actually be built unless needed. Further, since we want our elem_stored_range() method to be const (yet do the dynamic allocating) this needs to be mutable.

Definition at line 2217 of file mesh_base.h.

Referenced by libMesh::MeshBase::clear_stored_ranges(), libMesh::MeshBase::element_stored_range(), and libMesh::MeshBase::operator=().

◆ _elements

dofobject_container<Elem> libMesh::DistributedMesh::_elements
inherited

◆ _elemset_codes

std::map<dof_id_type, const MeshBase::elemset_type *> libMesh::MeshBase::_elemset_codes
protectedinherited

Map from "element set code" to list of set ids to which that element belongs (and vice-versa).

Remarks: 1.) The elemset code is a dof_id_type because (if used) it is stored as an extra_integer (named "elemset_code") on all elements, and extra_integers are of type dof_id_type. Elements which do not belong to any set should be assigned an elemset code of DofObject::invalid_id. 2.) Element sets can be thought of as a generalization of the concept of a subdomain. Subdomains have the following restrictions: a.) A given element can only belong to a single subdomain b.) When using Exodus file input/output, subdomains are (unfortunately) tied to the concept of exodus element blocks, which consist of a single geometric element type, somewhat limiting their generality. 3.) The user is responsible for filling in the values of this map in a consistent manner, unless the elemsets are read in from an Exodus file, in which case the elemset codes will be set up automatically. The codes can basically be chosen arbitrarily, with the one requirement that elements which belong to no sets should have a set code of DofObject::invalid_id. 4.) We also keep a list of all the elemset ids which have been added in order to support O(1) performance behavior in n_elemsets() calls.

Definition at line 2369 of file mesh_base.h.

Referenced by libMesh::MeshBase::add_elemset_code(), libMesh::MeshBase::change_elemset_code(), libMesh::MeshBase::change_elemset_id(), libMesh::MeshBase::clear(), libMesh::MeshBase::get_elemset_codes(), libMesh::MeshBase::get_elemsets(), libMesh::MeshBase::get_info(), libMesh::MeshBase::locally_equals(), libMesh::MeshBase::MeshBase(), and libMesh::MeshBase::operator=().

◆ _elemset_codes_inverse_map

std::map<MeshBase::elemset_type, dof_id_type> libMesh::MeshBase::_elemset_codes_inverse_map
protectedinherited

◆ _extra_ghost_elems

std::set<Elem *> libMesh::DistributedMesh::_extra_ghost_elems
inherited

◆ _ghosting_functors

std::vector<GhostingFunctor *> libMesh::MeshBase::_ghosting_functors
protectedinherited

◆ _interior_mesh

MeshBase* libMesh::MeshBase::_interior_mesh
protectedinherited

◆ _is_serial

bool libMesh::DistributedMesh::_is_serial
inherited

◆ _is_serial_on_proc_0

bool libMesh::DistributedMesh::_is_serial_on_proc_0
inherited

◆ _max_elem_id

dof_id_type libMesh::DistributedMesh::_max_elem_id
inherited

◆ _max_node_id

dof_id_type libMesh::DistributedMesh::_max_node_id
inherited

◆ _mesh_subdomains

std::set<subdomain_id_type> libMesh::MeshBase::_mesh_subdomains
protectedinherited

◆ _n_constraint_rows

dof_id_type libMesh::MeshBase::_n_constraint_rows
protectedinherited

◆ _n_elem

dof_id_type libMesh::DistributedMesh::_n_elem
inherited

◆ _n_nodes

dof_id_type libMesh::DistributedMesh::_n_nodes
inherited

◆ _n_parts

unsigned int libMesh::MeshBase::_n_parts
protectedinherited

The number of partitions the mesh has.

This is set by the partitioners, and may not be changed directly by the user.

Note
The number of partitions need not equal this->n_processors(), consider for example the case where you simply want to partition a mesh on one processor and view the result in GMV.

Definition at line 2189 of file mesh_base.h.

Referenced by libMesh::MeshBase::clear(), libMesh::MeshBase::locally_equals(), libMesh::MeshBase::n_partitions(), libMesh::MeshBase::operator=(), libMesh::MeshBase::recalculate_n_partitions(), and libMesh::MeshBase::set_n_partitions().

◆ _next_free_local_elem_id

dof_id_type libMesh::DistributedMesh::_next_free_local_elem_id
inherited

◆ _next_free_local_node_id

dof_id_type libMesh::DistributedMesh::_next_free_local_node_id
inherited

Guaranteed globally unused IDs for use when adding new nodes or elements.

Definition at line 452 of file distributed_mesh.h.

Referenced by libMesh::DistributedMesh::add_node(), libMesh::DistributedMesh::clear(), libMesh::DistributedMesh::DistributedMesh(), and libMesh::DistributedMesh::set_next_ids().

◆ _next_free_unpartitioned_elem_id

dof_id_type libMesh::DistributedMesh::_next_free_unpartitioned_elem_id
inherited

◆ _next_free_unpartitioned_node_id

dof_id_type libMesh::DistributedMesh::_next_free_unpartitioned_node_id
inherited

◆ _next_unique_id

unique_id_type libMesh::MeshBase::_next_unique_id
protectedinherited

◆ _next_unpartitioned_unique_id

unique_id_type libMesh::DistributedMesh::_next_unpartitioned_unique_id
inherited

◆ _node_integer_default_values

std::vector<dof_id_type> libMesh::MeshBase::_node_integer_default_values
protectedinherited

◆ _node_integer_names

std::vector<std::string> libMesh::MeshBase::_node_integer_names
protectedinherited

◆ _nodes

processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num unsigned char rflag processor_id_type pid const DofMap& dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num DECLARE_NODE_ITERATORS (multi_evaluable_, std::vector<const DofMap *> dof_maps, dof_maps) protected dofobject_container<Node> libMesh::DistributedMesh::_nodes
inherited

◆ _partitioner

std::unique_ptr<Partitioner> libMesh::MeshBase::_partitioner
protectedinherited

◆ _point_locator

std::unique_ptr<PointLocatorBase> libMesh::MeshBase::_point_locator
mutableprotectedinherited

A PointLocator class for this mesh.

This will not actually be built unless needed. Further, since we want our point_locator() method to be const (yet do the dynamic allocating) this needs to be mutable. Since the PointLocatorBase::build() member is used, and it operates on a constant reference to the mesh, this is OK.

Definition at line 2237 of file mesh_base.h.

Referenced by libMesh::MeshBase::clear_point_locator(), libMesh::MeshBase::operator=(), libMesh::MeshBase::set_point_locator_close_to_point_tol(), and libMesh::MeshBase::sub_point_locator().

◆ _point_locator_close_to_point_tol

Real libMesh::MeshBase::_point_locator_close_to_point_tol
protectedinherited

◆ _preparation

Preparation libMesh::MeshBase::_preparation
protectedinherited

Flags indicating in what ways this mesh has been prepared.

Definition at line 2207 of file mesh_base.h.

Referenced by libMesh::MeshBase::cache_elem_data(), libMesh::MeshBase::clear(), libMesh::MeshBase::complete_preparation(), libMesh::MeshBase::delete_remote_elements(), libMesh::DistributedMesh::delete_remote_elements(), libMesh::MeshBase::detect_interior_parents(), libMesh::DistributedMesh::DistributedMesh(), libMesh::MeshBase::elem_default_orders(), libMesh::MeshBase::elem_dimensions(), libMesh::UnstructuredMesh::find_neighbors(), libMesh::BoundaryInfo::get_global_boundary_ids(), libMesh::MeshBase::get_mesh_subdomains(), libMesh::MeshBase::is_prepared(), libMesh::MeshBase::locally_equals(), libMesh::MeshBase::n_constraint_rows(), libMesh::MeshBase::operator=(), libMesh::MeshBase::partition(), libMesh::MeshBase::preparation(), libMesh::MeshBase::prepare_for_use(), libMesh::MeshBase::reinit_ghosting_functors(), libMesh::MeshBase::remove_orphaned_nodes(), libMesh::DistributedMesh::renumber_nodes_and_elements(), libMesh::ReplicatedMesh::renumber_nodes_and_elements(), libMesh::ReplicatedMesh::ReplicatedMesh(), libMesh::MeshBase::set_constraint_rows(), libMesh::MeshBase::set_isnt_prepared(), libMesh::MeshBase::spatial_dimension(), libMesh::MeshBase::supported_nodal_order(), libMesh::MeshBase::sync_subdomain_name_map(), libMesh::BoundaryInfo::synchronize_global_id_set(), libMesh::MeshBase::unset_has_boundary_id_sets(), libMesh::MeshBase::unset_has_cached_elem_data(), libMesh::MeshBase::unset_has_interior_parent_ptrs(), libMesh::MeshBase::unset_has_neighbor_ptrs(), libMesh::MeshBase::unset_has_reinit_ghosting_functors(), libMesh::MeshBase::unset_has_removed_orphaned_nodes(), libMesh::MeshBase::unset_has_removed_remote_elements(), libMesh::MeshBase::unset_has_synched_id_counts(), libMesh::MeshBase::unset_has_synched_subdomain_name_map(), libMesh::MeshBase::unset_is_partitioned(), libMesh::MeshBase::unset_is_prepared(), libMesh::DistributedMesh::update_parallel_id_counts(), and libMesh::ReplicatedMesh::update_parallel_id_counts().

◆ _shared_functors

std::map<GhostingFunctor *, std::shared_ptr<GhostingFunctor> > libMesh::MeshBase::_shared_functors
protectedinherited

Hang on to references to any GhostingFunctor objects we were passed in shared_ptr form.

Definition at line 2442 of file mesh_base.h.

Referenced by libMesh::MeshBase::add_ghosting_functor(), libMesh::MeshBase::post_dofobject_moves(), and libMesh::MeshBase::remove_ghosting_functor().

◆ _skip_all_partitioning

bool libMesh::MeshBase::_skip_all_partitioning
protectedinherited

◆ _skip_detect_interior_parents

bool libMesh::MeshBase::_skip_detect_interior_parents
protectedinherited

◆ _skip_find_neighbors

bool libMesh::MeshBase::_skip_find_neighbors
protectedinherited

◆ _skip_noncritical_partitioning

bool libMesh::MeshBase::_skip_noncritical_partitioning
protectedinherited

If this is true then no partitioning should be done with the possible exception of orphaned nodes.

Definition at line 2270 of file mesh_base.h.

Referenced by libMesh::MeshBase::locally_equals(), libMesh::MeshBase::operator=(), libMesh::MeshBase::skip_noncritical_partitioning(), and libMesh::MeshBase::skip_noncritical_partitioning().

◆ _skip_renumber_nodes_and_elements

bool libMesh::MeshBase::_skip_renumber_nodes_and_elements
protectedinherited

◆ _spatial_dimension

unsigned char libMesh::MeshBase::_spatial_dimension
protectedinherited

◆ _supported_nodal_order

Order libMesh::MeshBase::_supported_nodal_order
protectedinherited

◆ boundary_info

std::unique_ptr<BoundaryInfo> libMesh::MeshBase::boundary_info
protectedinherited

This class holds the boundary information.

It can store nodes, edges, and faces with a corresponding id that facilitates setting boundary conditions.

Direct access to this class is now officially deprecated and will be removed in future libMesh versions. Use the get_boundary_info() accessor instead.

Definition at line 2143 of file mesh_base.h.

Referenced by libMesh::MeshBase::clear(), libMesh::MeshBase::get_boundary_info(), libMesh::MeshBase::get_boundary_info(), libMesh::MeshBase::locally_equals(), and libMesh::MeshBase::operator=().

◆ ElemRange

const DofMap& dof_map LIBMESH_COMMA unsigned int Elem* libMesh::MeshBase::ElemRange
inherited

Definition at line 1898 of file mesh_base.h.

◆ level [1/2]

unsigned int libMesh::DistributedMesh::level
inherited

Definition at line 352 of file distributed_mesh.h.

◆ level [2/2]

processor_id_type pid unsigned int libMesh::DistributedMesh::level
inherited

Definition at line 379 of file distributed_mesh.h.

◆ pid [1/2]

processor_id_type libMesh::DistributedMesh::pid
inherited

◆ pid [2/2]

processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num unsigned char rflag processor_id_type libMesh::DistributedMesh::pid
inherited

Definition at line 401 of file distributed_mesh.h.

◆ rflag

processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num unsigned char libMesh::DistributedMesh::rflag
inherited

Definition at line 391 of file distributed_mesh.h.

◆ ss [1/2]

unsigned int level ElemType type std::set<subdomain_id_type> libMesh::DistributedMesh::ss
inherited

◆ ss [2/2]

processor_id_type pid unsigned int level std::set<subdomain_id_type> libMesh::DistributedMesh::ss
inherited

Definition at line 381 of file distributed_mesh.h.

◆ type

unsigned int level ElemType libMesh::DistributedMesh::type
inherited

Definition at line 354 of file distributed_mesh.h.

◆ var_num [1/2]

processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap& dof_map LIBMESH_COMMA unsigned int libMesh::DistributedMesh::var_num = libMesh::invalid_uint
inherited

Definition at line 387 of file distributed_mesh.h.

◆ var_num [2/2]

processor_id_type pid unsigned int level std::set< subdomain_id_type > ss const DofMap &dof_map LIBMESH_COMMA unsigned int dof_map LIBMESH_COMMA var_num unsigned char rflag processor_id_type pid const DofMap& dof_map LIBMESH_COMMA unsigned int libMesh::DistributedMesh::var_num = libMesh::invalid_uint
inherited

Definition at line 404 of file distributed_mesh.h.


The documentation for this class was generated from the following file: