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)
120 this_boundary_info = other_boundary_info;
132 LOG_SCOPE(
"operator=(&&)",
"ReplicatedMesh");
150 *
this = std::move(cast_ref<ReplicatedMesh&>(other_mesh));
157 ReplicatedMesh & other_mesh = cast_ref<ReplicatedMesh&>(other_meshbase);
159 this->_nodes = std::move(other_mesh._nodes);
179 libmesh_assert_equal_to (_nodes[i]->
id(), i);
191 libmesh_assert_equal_to (_nodes[i]->
id(), i);
204 _nodes[i]->
id() == i);
217 _nodes[i]->
id() == i);
229 libmesh_assert_equal_to (
_elements[i]->
id(), i);
241 libmesh_assert_equal_to (
_elements[i]->
id(), i);
287 #ifdef LIBMESH_ENABLE_UNIQUE_ID 344 #ifdef LIBMESH_ENABLE_UNIQUE_ID 352 libmesh_assert_less (eid,
_elements.size());
357 libmesh_assert_equal_to (oldelem->id(), eid);
396 std::vector<Elem *>::iterator pos =
_elements.end();
407 std::advance(pos, e->
id());
443 if (old_id == new_id)
477 if (
id < _nodes.size())
482 _nodes.push_back (static_cast<Node *>(
nullptr));
492 cast_int<dof_id_type>(_nodes.size()-1) :
id).release();
498 #ifdef LIBMESH_ENABLE_UNIQUE_ID 529 if (
id < _nodes.size())
538 n->
set_id (cast_int<dof_id_type>(_nodes.size()));
544 #ifdef LIBMESH_ENABLE_UNIQUE_ID 568 libmesh_assert_less (n->
id(), _nodes.size());
572 std::vector<Node *>::iterator pos;
577 if (_nodes[n->
id()] == n)
579 pos = _nodes.begin();
580 std::advance(pos, n->
id());
584 pos = std::find (_nodes.begin(),
610 if (old_id == new_id)
614 Node * nd = _nodes[old_id];
617 if (new_id >= _nodes.size())
618 _nodes.resize(new_id+1,
nullptr);
623 _nodes[old_id] =
nullptr;
639 for (
auto & node : _nodes)
661 #ifdef LIBMESH_ENABLE_UNIQUE_ID 670 #ifdef LIBMESH_ENABLE_UNIQUE_ID 674 parallel_object_only();
693 LOG_SCOPE(
"renumber_nodes_and_elem()",
"Mesh");
700 std::unordered_set<Node *> connected_nodes;
707 std::vector<Elem *>::iterator in =
_elements.begin();
708 std::vector<Elem *>::iterator out_iter =
_elements.begin();
709 const std::vector<Elem *>::iterator end =
_elements.end();
711 for (; in != end; ++in)
720 el->
set_id (next_free_elem++);
726 connected_nodes.insert(&n);
735 if (n.id() == next_free_node)
738 else if (n.id() > next_free_node)
749 std::swap(_nodes[src_idx],
753 if (_nodes[src_idx] !=
nullptr)
754 _nodes[src_idx]->set_id (src_idx);
755 _nodes[dst_idx]->set_id (dst_idx);
774 std::vector<Node *>::iterator in = _nodes.begin();
775 std::vector<Node *>::iterator out_iter = _nodes.begin();
776 const std::vector<Node *>::iterator end = _nodes.end();
778 for (; in != end; ++in)
785 if (connected_nodes.count(nd))
791 nd->
set_id (next_free_node++);
806 _nodes.erase (out_iter, end);
816 std::vector<Node *>::iterator nd = _nodes.begin();
817 const std::vector<Node *>::iterator end = _nodes.end();
819 std::advance (nd, next_free_node);
821 for (
auto & node :
as_range(nd, end))
839 _nodes.erase (nd, end);
845 libmesh_assert_equal_to (next_free_elem,
_elements.size());
846 libmesh_assert_equal_to (next_free_node, _nodes.size());
857 if (this->_nodes[n] !=
nullptr)
858 this->_nodes[n]->set_id() = cast_int<dof_id_type>(n);
863 this->
_elements[e]->set_id() = cast_int<dof_id_type>(e);
870 this->active_elements_end()));
873 std::vector<dof_id_type>
877 std::vector<dof_id_type> representative_elem_ids;
882 std::vector<subdomain_id_type> subdomains;
893 std::vector<const Elem *> list;
901 for (
const auto & elem : active_element_ptr_range())
904 list.push_back(elem);
905 (*subdomain_ids)[elem->id()] = subdomain_counter;
911 dof_id_type min_id = std::numeric_limits<dof_id_type>::max();
912 while (list.size() > 0)
915 const Elem * elem = list.back(); list.pop_back(); ++visited;
917 min_id = std::min(elem->
id(), min_id);
926 list.push_back(neighbor);
927 (*subdomain_ids)[neighbor->
id()] = subdomain_counter;
932 representative_elem_ids.push_back(min_id);
935 while (visited != n_active);
937 return representative_elem_ids;
940 std::unordered_map<dof_id_type, std::vector<std::vector<Point>>>
944 "Error: get_boundary_points only works for 2D now");
948 std::vector<subdomain_id_type> subdomains;
951 std::unordered_map<dof_id_type, std::vector<std::vector<Point>>> boundary_points;
955 struct boundary_side_compare
957 bool operator()(
const std::pair<const Elem *, unsigned int> & lhs,
958 const std::pair<const Elem *, unsigned int> & rhs)
const 960 if (lhs.first->id() < rhs.first->id())
962 else if (lhs.first->id() == rhs.first->id())
964 if (lhs.second < rhs.second)
970 std::set<std::pair<const Elem *, unsigned int>, boundary_side_compare> boundary_elements;
971 for (
const auto & elem : active_element_ptr_range())
972 for (
auto s : elem->side_index_range())
973 if (elem->neighbor_ptr(s) ==
nullptr)
974 boundary_elements.insert(std::pair<const Elem *, unsigned int>(elem, s));
976 while (!boundary_elements.empty())
979 const Elem * eseed = boundary_elements.begin()->first;
980 unsigned int sseed = boundary_elements.begin()->second;
986 std::vector<Point> bpoints;
987 const Elem * elem = eseed;
988 unsigned int s = sseed;
989 std::vector<unsigned int> local_side_nodes = elem->
nodes_on_side(s);
992 std::pair<const Elem *, unsigned int> side(elem, s);
994 boundary_elements.erase(side);
999 bpoints.push_back(*static_cast<const Point *>(elem->
node_ptr(local_side_nodes[i])));
1002 const Node * node = elem->
node_ptr(local_side_nodes[1]);
1003 std::set<const Elem *> neighbors;
1007 if (neighbors.size() != 1)
1008 neighbors.erase(elem);
1012 for (
const auto & neighbor : neighbors)
1014 for (
auto ss : neighbor->side_index_range())
1015 if (neighbor->neighbor_ptr(
ss) ==
nullptr && !(elem == neighbor && s ==
ss))
1017 local_side_nodes = neighbor->nodes_on_side(
ss);
1019 if (neighbor->node_ptr(local_side_nodes[0]) == node)
1026 else if (neighbor->node_ptr(local_side_nodes[1]) == node)
1032 auto temp(local_side_nodes);
1033 local_side_nodes[0] = temp[1];
1034 local_side_nodes[1] = temp[0];
1035 for (
unsigned int i = 2; i < temp.size(); ++i)
1036 local_side_nodes[temp.size() + 1 - i] = temp[i];
1044 libmesh_error_msg_if(!found,
"ERROR: mesh topology error on visiting boundary sides");
1047 if (elem == eseed && s == sseed)
1050 boundary_points[elem_ids[subdomain_id]].push_back(bpoints);
1053 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
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.
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.
bool allow_detect_interior_parents() const
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.
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 ...
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)
Preparation preparation() const
void clear_stored_ranges()
Clears stored ranges, to indicate that the mesh has changed and they should be regenerated when next ...
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
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
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
bool has_removed_orphaned_nodes
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 clear_point_locator()
Releases the current PointLocator object.
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
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...
std::map< subdomain_id_type, std::string > & set_subdomain_name_map()
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
Preparation _preparation
Flags indicating in what ways this mesh has been prepared.
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
void set_unique_id(unique_id_type new_id)
Sets the unique_id for this DofObject.
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
void add_extra_integers(const unsigned int n_integers)
Assigns a set of extra integers to this DofObject.
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...
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
bool has_synched_id_counts
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.
static constexpr subdomain_id_type invalid_subdomain_id
A static integral constant representing an invalid subdomain id.
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