21 #include "libmesh/replicated_mesh.h" 23 #include "libmesh/boundary_info.h" 24 #include "libmesh/elem.h" 25 #include "libmesh/libmesh_logging.h" 26 #include "libmesh/mesh_communication.h" 27 #include "libmesh/parallel_implementation.h" 28 #include "libmesh/partitioner.h" 29 #include "libmesh/point.h" 30 #include "libmesh/string_to_enum.h" 31 #include "libmesh/utility.h" 34 #include <unordered_map> 35 #include <unordered_set> 45 _n_nodes(0), _n_elem(0)
47 #ifdef LIBMESH_ENABLE_UNIQUE_ID 53 const std::string default_partitioner =
"metis";
54 const std::string my_partitioner =
58 (Utility::string_to_enum<PartitionerType>(my_partitioner));
72 #ifdef LIBMESH_ENABLE_UNIQUE_ID
75 !this->nodes_and_elements_equal(other_mesh))
94 #ifdef LIBMESH_ENABLE_UNIQUE_ID 102 _n_nodes(0), _n_elem(0)
123 this_boundary_info = other_boundary_info;
135 LOG_SCOPE(
"operator=(&&)",
"ReplicatedMesh");
153 *
this = std::move(cast_ref<ReplicatedMesh&>(other_mesh));
160 ReplicatedMesh & other_mesh = cast_ref<ReplicatedMesh&>(other_meshbase);
162 this->_nodes = std::move(other_mesh._nodes);
182 libmesh_assert_equal_to (_nodes[i]->
id(), i);
194 libmesh_assert_equal_to (_nodes[i]->
id(), i);
207 _nodes[i]->
id() == i);
220 _nodes[i]->
id() == i);
232 libmesh_assert_equal_to (
_elements[i]->
id(), i);
244 libmesh_assert_equal_to (
_elements[i]->
id(), i);
290 #ifdef LIBMESH_ENABLE_UNIQUE_ID 342 #ifdef LIBMESH_ENABLE_UNIQUE_ID 350 libmesh_assert_less (eid,
_elements.size());
355 libmesh_assert_equal_to (oldelem->id(), eid);
389 std::vector<Elem *>::iterator pos =
_elements.end();
400 std::advance(pos, e->
id());
431 if (old_id == new_id)
459 if (
id < _nodes.size())
464 _nodes.push_back (static_cast<Node *>(
nullptr));
474 cast_int<dof_id_type>(_nodes.size()-1) :
id).release();
480 #ifdef LIBMESH_ENABLE_UNIQUE_ID 511 if (
id < _nodes.size())
520 n->
set_id (cast_int<dof_id_type>(_nodes.size()));
526 #ifdef LIBMESH_ENABLE_UNIQUE_ID 547 #ifdef LIBMESH_ENABLE_DEPRECATED 551 libmesh_deprecated();
552 libmesh_error_msg_if(!n,
"Error, attempting to insert nullptr node.");
555 if (n->
id() < _nodes.size())
565 libmesh_error_msg_if(_nodes[ n->
id() ] !=
nullptr,
566 "Error, cannot insert new node on top of existing node.");
573 _nodes.resize(n->
id() + 1);
576 #ifdef LIBMESH_ENABLE_UNIQUE_ID 589 _nodes[ n->
id() ] = n;
598 libmesh_deprecated();
610 libmesh_assert_less (n->
id(), _nodes.size());
614 std::vector<Node *>::iterator pos;
619 if (_nodes[n->
id()] == n)
621 pos = _nodes.begin();
622 std::advance(pos, n->
id());
626 pos = std::find (_nodes.begin(),
652 if (old_id == new_id)
656 Node * nd = _nodes[old_id];
659 if (new_id >= _nodes.size())
660 _nodes.resize(new_id+1,
nullptr);
665 _nodes[old_id] =
nullptr;
681 for (
auto & node : _nodes)
703 #ifdef LIBMESH_ENABLE_UNIQUE_ID 710 #ifdef LIBMESH_ENABLE_UNIQUE_ID 714 parallel_object_only();
733 LOG_SCOPE(
"renumber_nodes_and_elem()",
"Mesh");
740 std::unordered_set<Node *> connected_nodes;
747 std::vector<Elem *>::iterator in =
_elements.begin();
748 std::vector<Elem *>::iterator out_iter =
_elements.begin();
749 const std::vector<Elem *>::iterator end =
_elements.end();
751 for (; in != end; ++in)
760 el->
set_id (next_free_elem++);
766 connected_nodes.insert(&n);
775 if (n.id() == next_free_node)
778 else if (n.id() > next_free_node)
789 std::swap(_nodes[src_idx],
793 if (_nodes[src_idx] !=
nullptr)
794 _nodes[src_idx]->set_id (src_idx);
795 _nodes[dst_idx]->set_id (dst_idx);
814 std::vector<Node *>::iterator in = _nodes.begin();
815 std::vector<Node *>::iterator out_iter = _nodes.begin();
816 const std::vector<Node *>::iterator end = _nodes.end();
818 for (; in != end; ++in)
825 if (connected_nodes.count(nd))
831 nd->
set_id (next_free_node++);
846 _nodes.erase (out_iter, end);
856 std::vector<Node *>::iterator nd = _nodes.begin();
857 const std::vector<Node *>::iterator end = _nodes.end();
859 std::advance (nd, next_free_node);
861 for (
auto & node :
as_range(nd, end))
879 _nodes.erase (nd, end);
883 libmesh_assert_equal_to (next_free_elem,
_elements.size());
884 libmesh_assert_equal_to (next_free_node, _nodes.size());
895 if (this->_nodes[n] !=
nullptr)
896 this->_nodes[n]->set_id() = cast_int<dof_id_type>(n);
901 this->
_elements[e]->set_id() = cast_int<dof_id_type>(e);
908 this->active_elements_end()));
911 std::vector<dof_id_type>
915 std::vector<dof_id_type> representative_elem_ids;
920 std::vector<subdomain_id_type> subdomains;
931 std::vector<const Elem *> list;
939 for (
const auto & elem : active_element_ptr_range())
942 list.push_back(elem);
943 (*subdomain_ids)[elem->id()] = subdomain_counter;
949 dof_id_type min_id = std::numeric_limits<dof_id_type>::max();
950 while (list.size() > 0)
953 const Elem * elem = list.back(); list.pop_back(); ++visited;
955 min_id = std::min(elem->
id(), min_id);
964 list.push_back(neighbor);
965 (*subdomain_ids)[neighbor->
id()] = subdomain_counter;
970 representative_elem_ids.push_back(min_id);
973 while (visited != n_active);
975 return representative_elem_ids;
978 std::unordered_map<dof_id_type, std::vector<std::vector<Point>>>
982 "Error: get_boundary_points only works for 2D now");
986 std::vector<subdomain_id_type> subdomains;
989 std::unordered_map<dof_id_type, std::vector<std::vector<Point>>> boundary_points;
993 struct boundary_side_compare
995 bool operator()(
const std::pair<const Elem *, unsigned int> & lhs,
996 const std::pair<const Elem *, unsigned int> & rhs)
const 998 if (lhs.first->id() < rhs.first->id())
1000 else if (lhs.first->id() == rhs.first->id())
1002 if (lhs.second < rhs.second)
1008 std::set<std::pair<const Elem *, unsigned int>, boundary_side_compare> boundary_elements;
1009 for (
const auto & elem : active_element_ptr_range())
1010 for (
auto s : elem->side_index_range())
1011 if (elem->neighbor_ptr(s) ==
nullptr)
1012 boundary_elements.insert(std::pair<const Elem *, unsigned int>(elem, s));
1014 while (!boundary_elements.empty())
1017 const Elem * eseed = boundary_elements.begin()->first;
1018 unsigned int sseed = boundary_elements.begin()->second;
1024 std::vector<Point> bpoints;
1025 const Elem * elem = eseed;
1026 unsigned int s = sseed;
1027 std::vector<unsigned int> local_side_nodes = elem->
nodes_on_side(s);
1030 std::pair<const Elem *, unsigned int> side(elem, s);
1032 boundary_elements.erase(side);
1037 bpoints.push_back(*static_cast<const Point *>(elem->
node_ptr(local_side_nodes[i])));
1040 const Node * node = elem->
node_ptr(local_side_nodes[1]);
1041 std::set<const Elem *> neighbors;
1045 if (neighbors.size() != 1)
1046 neighbors.erase(elem);
1050 for (
const auto & neighbor : neighbors)
1052 for (
auto ss : neighbor->side_index_range())
1053 if (neighbor->neighbor_ptr(
ss) ==
nullptr && !(elem == neighbor && s ==
ss))
1055 local_side_nodes = neighbor->nodes_on_side(
ss);
1057 if (neighbor->node_ptr(local_side_nodes[0]) == node)
1064 else if (neighbor->node_ptr(local_side_nodes[1]) == node)
1070 auto temp(local_side_nodes);
1071 local_side_nodes[0] = temp[1];
1072 local_side_nodes[1] = temp[0];
1073 for (
unsigned int i = 2; i < temp.size(); ++i)
1074 local_side_nodes[temp.size() + 1 - i] = temp[i];
1082 libmesh_error_msg_if(!found,
"ERROR: mesh topology error on visiting boundary sides");
1085 if (elem == eseed && s == sseed)
1088 boundary_points[elem_ids[subdomain_id]].push_back(bpoints);
1091 return boundary_points;
virtual dof_id_type n_nodes() const override final
UnstructuredMesh & operator=(const UnstructuredMesh &)=delete
Copy assignment is not allowed.
virtual dof_id_type max_node_id() const override final
unique_id_type & set_unique_id()
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...
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
bool _skip_renumber_nodes_and_elements
If this is true then renumbering will be kept to a minimum.
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)
Deep copy of nodes and elements from another mesh object (used by subclass copy constructors and by m...
A Node is like a Point, but with more information.
virtual dof_id_type n_elem() const override final
std::vector< std::string > _elem_integer_names
The array of names for integer data associated with each element in the mesh.
virtual const Node * query_node_ptr(const dof_id_type i) const override final
void set_mapping_type(const ElemMappingType type)
Sets the value of the mapping type for the element.
std::vector< Elem * > _elements
The elements in the mesh.
void allow_renumbering(bool allow)
If false is passed in then this mesh will no longer be renumbered when being prepared for use...
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 ...
IntRange< unsigned short > side_index_range() const
void skip_partitioning(bool skip)
If true is passed in then nothing on this mesh will be (re)partitioned.
virtual ~ReplicatedMesh()
Destructor.
virtual void set_next_unique_id(unique_id_type id) override final
Sets the next available unique id to be used.
void copy_cached_data(const MeshBase &other_mesh)
Helper class to copy cached data, to synchronize with a possibly unprepared other_mesh.
virtual Node * insert_node(Node *n) override final
These methods are deprecated.
void remove(const Node *node)
Removes the boundary conditions associated with node node, if any exist.
std::vector< dof_id_type > get_disconnected_subdomains(std::vector< subdomain_id_type > *subdomain_ids=nullptr) const
Return IDs of representative elements of all disconnected subdomains.
virtual dof_id_type max_elem_id() const override final
This is the base class from which all geometric element types are derived.
constraint_rows_type _constraint_rows
unique_id_type unique_id() const
void copy_constraint_rows(const MeshBase &other_mesh)
Copy the constraints from the other mesh to this mesh.
const Parallel::Communicator & comm() const
The libMesh namespace provides an interface to certain functionality in the library.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
std::unordered_map< dof_id_type, std::vector< std::vector< Point > > > get_boundary_points() const
Return all points on boundary.
std::vector< std::string > _node_integer_names
The array of names for integer data associated with each node in the mesh.
virtual void delete_elem(Elem *e) override final
Removes element e from the mesh.
virtual Node * add_node(Node *n) override final
Add Node n to the end of the vertex array.
virtual MeshBase & assign(MeshBase &&other_mesh) override
Shim to call the move assignment operator for this class.
Real distance(const Point &p)
uint8_t processor_id_type
This is the MeshBase class.
ElemMappingType default_mapping_type() const
Returns the default master space to physical space mapping basis functions to be used on newly added ...
virtual const Elem * query_elem_ptr(const dof_id_type i) const override final
virtual unique_id_type parallel_max_unique_id() const override final
virtual void delete_node(Node *n) override final
Removes the Node n from the mesh.
unique_id_type _next_unique_id
The next available unique id for assigning ids to DOF objects.
virtual void clear() override
Free all new memory associated with the object, but restore its original state, with the mesh pointer...
virtual const Elem * elem_ptr(const dof_id_type i) const override final
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 ...
virtual bool is_serial() const
static const subdomain_id_type invalid_subdomain_id
A static integral constant representing an invalid subdomain id.
friend class MeshCommunication
Make the MeshCommunication class a friend so that it can directly broadcast *_integer_names.
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 t...
T command_line_value(const std::string &, T)
static std::unique_ptr< Partitioner > build(const PartitionerType solver_package)
Builds a Partitioner of the type specified by partitioner_type.
const std::map< subdomain_id_type, std::string > & get_subdomain_name_map() const
virtual void clear() override
Clear all internal data.
The UnstructuredMesh class is derived from the MeshBase class.
unsigned char default_mapping_data() const
Returns any default data value used by the master space to physical space mapping.
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
void find_point_neighbors(const Point &p, std::set< const Elem *> &neighbor_set) const
This function finds all active elements (including this one) which are in the same manifold as this e...
std::unique_ptr< Partitioner > _partitioner
A partitioner to use at each prepare_for_use().
virtual void move_nodes_and_elements(MeshBase &&other_mesh) override
Move node and elements from a ReplicatedMesh.
void set_mapping_data(const unsigned char data)
Sets the value of the mapping data for the element.
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).
bool allow_find_neighbors() const
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
bool valid_unique_id() 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 f...
bool allow_remote_element_removal() const
virtual void clear()
Deletes all the element and node data that is currently stored.
virtual Elem * add_elem(Elem *e) override final
Add elem e to the end of the element array.
virtual void renumber_nodes_and_elements() override
After partitioning a mesh it is useful to renumber the nodes and elements so that they lie in contigu...
unsigned int level ElemType type std::set< subdomain_id_type > ss
virtual const Point & point(const dof_id_type i) const override final
bool skip_partitioning() const
SimpleRange< NodeRefIter > node_ref_range()
Returns a range with all nodes of an element, usable in range-based for loops.
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...
static std::unique_ptr< Node > build(const Node &n)
const Elem * neighbor_ptr(unsigned int i) const
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...
virtual dof_id_type n_active_elem() const override final
ReplicatedMesh & operator=(const ReplicatedMesh &)=delete
Copy assignment is not allowed.
virtual void update_parallel_id_counts() override
Updates parallel caches so that methods like n_elem() accurately reflect changes on other processors...
virtual void clear_elems() override
Clear internal Elem data.
virtual void fix_broken_node_and_element_numbering() override
There is no reason for a user to ever call this function.
void max(const T &r, T &o, Request &req) const
void post_dofobject_moves(MeshBase &&other_mesh)
Moves any superclass data (e.g.
const Node * node_ptr(const unsigned int i) const
virtual const Node * node_ptr(const dof_id_type i) const override final
bool _is_prepared
Flag indicating if the mesh has been prepared for use.
void add_extra_integers(const unsigned int n_integers)
Assigns a set of extra integers to this DofObject.
unsigned int mesh_dimension() const
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.
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 dof_id_typ _n_nodes)
The vertices (spatial coordinates) of the mesh.
virtual const Node & node_ref(const dof_id_type i) const
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...
bool allow_renumbering() const
ReplicatedMesh(const Parallel::Communicator &comm_in, unsigned char dim=1)
Constructor.
const DofMap &dof_map LIBMESH_COMMA unsigned int std::string & set_subdomain_name_map()
processor_id_type processor_id() const
A Point defines a location in LIBMESH_DIM dimensional Real space.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
virtual std::vector< unsigned int > nodes_on_side(const unsigned int) const =0