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)
118 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
666 auto trim_vec = [](
auto & dof_vec) {
667 auto last_non_null = std::find_if(dof_vec.rbegin(), dof_vec.rend(), [](
DofObject * d) { return (d != nullptr); });
668 dof_vec.resize(last_non_null.base()-dof_vec.begin());
671 trim_vec(this->_nodes);
679#ifdef LIBMESH_ENABLE_UNIQUE_ID
683 parallel_object_only();
702 LOG_SCOPE(
"renumber_nodes_and_elem()",
"Mesh");
709 std::unordered_set<Node *> connected_nodes;
716 std::vector<Elem *>::iterator in =
_elements.begin();
717 std::vector<Elem *>::iterator out_iter =
_elements.begin();
718 const std::vector<Elem *>::iterator end =
_elements.end();
720 for (; in != end; ++in)
729 el->
set_id (next_free_elem++);
735 connected_nodes.insert(&n);
744 if (n.id() == next_free_node)
747 else if (n.id() > next_free_node)
758 std::swap(_nodes[src_idx],
762 if (_nodes[src_idx] !=
nullptr)
763 _nodes[src_idx]->set_id (src_idx);
764 _nodes[dst_idx]->set_id (dst_idx);
783 std::vector<Node *>::iterator in = _nodes.begin();
784 std::vector<Node *>::iterator out_iter = _nodes.begin();
785 const std::vector<Node *>::iterator end = _nodes.end();
787 for (; in != end; ++in)
794 if (connected_nodes.count(nd))
800 nd->
set_id (next_free_node++);
815 _nodes.erase (out_iter, end);
825 std::vector<Node *>::iterator nd = _nodes.begin();
826 const std::vector<Node *>::iterator end = _nodes.end();
828 std::advance (nd, next_free_node);
830 for (
auto & node :
as_range(nd, end))
848 _nodes.erase (nd, end);
854 libmesh_assert_equal_to (next_free_elem,
_elements.size());
855 libmesh_assert_equal_to (next_free_node, _nodes.size());
866 if (this->_nodes[n] !=
nullptr)
867 this->_nodes[n]->set_id() = cast_int<dof_id_type>(n);
872 this->
_elements[e]->set_id() = cast_int<dof_id_type>(e);
878 return static_cast<dof_id_type>(std::distance (this->active_elements_begin(),
879 this->active_elements_end()));
882std::vector<dof_id_type>
886 std::vector<dof_id_type> representative_elem_ids;
891 std::vector<subdomain_id_type> subdomains;
902 std::vector<const Elem *> list;
910 for (
const auto & elem : active_element_ptr_range())
913 list.push_back(elem);
914 (*subdomain_ids)[elem->id()] = subdomain_counter;
920 dof_id_type min_id = std::numeric_limits<dof_id_type>::max();
921 while (list.size() > 0)
924 const Elem * elem = list.back(); list.pop_back(); ++visited;
926 min_id = std::min(elem->
id(), min_id);
935 list.push_back(neighbor);
936 (*subdomain_ids)[neighbor->
id()] = subdomain_counter;
941 representative_elem_ids.push_back(min_id);
944 while (visited != n_active);
946 return representative_elem_ids;
949std::unordered_map<dof_id_type, std::vector<std::vector<Point>>>
953 "Error: get_boundary_points only works for 2D now");
957 std::vector<subdomain_id_type> subdomains;
960 std::unordered_map<dof_id_type, std::vector<std::vector<Point>>> boundary_points;
964 struct boundary_side_compare
966 bool operator()(
const std::pair<const Elem *, unsigned int> & lhs,
967 const std::pair<const Elem *, unsigned int> & rhs)
const
969 if (lhs.first->id() < rhs.first->id())
971 else if (lhs.first->id() == rhs.first->id())
973 if (lhs.second < rhs.second)
979 std::set<std::pair<const Elem *, unsigned int>, boundary_side_compare> boundary_elements;
980 for (
const auto & elem : active_element_ptr_range())
981 for (
auto s : elem->side_index_range())
982 if (elem->neighbor_ptr(s) ==
nullptr)
983 boundary_elements.insert(std::pair<const Elem *, unsigned int>(elem, s));
985 while (!boundary_elements.empty())
988 const Elem * eseed = boundary_elements.begin()->first;
989 unsigned int sseed = boundary_elements.begin()->second;
995 std::vector<Point> bpoints;
996 const Elem * elem = eseed;
997 unsigned int s = sseed;
998 std::vector<unsigned int> local_side_nodes = elem->
nodes_on_side(s);
1001 std::pair<const Elem *, unsigned int> side(elem, s);
1003 boundary_elements.erase(side);
1008 bpoints.push_back(*
static_cast<const Point *
>(elem->
node_ptr(local_side_nodes[i])));
1011 const Node * node = elem->
node_ptr(local_side_nodes[1]);
1012 std::set<const Elem *> neighbors;
1016 if (neighbors.size() != 1)
1017 neighbors.erase(elem);
1021 for (
const auto & neighbor : neighbors)
1023 for (
auto ss : neighbor->side_index_range())
1024 if (neighbor->neighbor_ptr(
ss) ==
nullptr && !(elem == neighbor && s ==
ss))
1026 local_side_nodes = neighbor->nodes_on_side(
ss);
1028 if (neighbor->node_ptr(local_side_nodes[0]) == node)
1035 else if (neighbor->node_ptr(local_side_nodes[1]) == node)
1041 auto temp(local_side_nodes);
1042 local_side_nodes[0] = temp[1];
1043 local_side_nodes[1] = temp[0];
1044 for (
unsigned int i = 2; i < temp.size(); ++i)
1045 local_side_nodes[temp.size() + 1 - i] = temp[i];
1053 libmesh_error_msg_if(!found,
"ERROR: mesh topology error on visiting boundary sides");
1056 if (elem == eseed && s == sseed)
1059 boundary_points[elem_ids[subdomain_id]].push_back(bpoints);
1062 return boundary_points;
void max(const T &r, T &o, Request &req) const
void remove(const Node *node)
Removes the boundary conditions associated with node node, if any exist.
virtual void clear() override
Free all new memory associated with the object, but restore its original state, with the mesh pointer...
The DofObject defines an abstract base class for objects that have degrees of freedom associated with...
processor_id_type processor_id() const
void add_extra_integers(const unsigned int n_integers)
Assigns a set of extra integers to this DofObject.
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
unique_id_type unique_id() const
bool valid_unique_id() const
void set_unique_id(unique_id_type new_id)
Sets the unique_id for this DofObject.
This is the base class from which all geometric element types are derived.
SimpleRange< NodeRefIter > node_ref_range()
Returns a range with all nodes of an element, usable in range-based for loops.
virtual std::vector< unsigned int > nodes_on_side(const unsigned int) const =0
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...
static constexpr subdomain_id_type invalid_subdomain_id
A static integral constant representing an invalid subdomain id.
const Node * node_ptr(const unsigned int i) const
void set_mapping_type(const ElemMappingType type)
Sets the value of the mapping type for the element.
void set_mapping_data(const unsigned char data)
Sets the value of the mapping data for the element.
const Elem * neighbor_ptr(unsigned int i) const
IntRange< unsigned short > side_index_range() const
This is the MeshBase class.
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 const Node & node_ref(const dof_id_type i) const
virtual bool is_serial() const
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Preparation preparation() const
bool allow_renumbering() const
unsigned int mesh_dimension() const
bool skip_partitioning() const
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,...
bool allow_detect_interior_parents() 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...
void allow_renumbering(bool allow)
If false is passed in then this mesh will no longer be renumbered when being prepared for use.
const std::map< subdomain_id_type, std::string > & get_subdomain_name_map() const
ElemMappingType default_mapping_type() const
Returns the default master space to physical space mapping basis functions to be used on newly added ...
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.
unique_id_type _next_unique_id
The next available unique id for assigning ids to DOF objects.
bool _skip_renumber_nodes_and_elements
If this is true then renumbering will be kept to a minimum.
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.
virtual void clear()
Deletes all the element and node data that is currently stored.
constraint_rows_type _constraint_rows
std::unique_ptr< Partitioner > _partitioner
A partitioner to use at each prepare_for_use().
bool allow_remote_element_removal() const
bool allow_find_neighbors() const
unsigned char default_mapping_data() const
Returns any default data value used by the master space to physical space mapping.
void clear_point_locator()
Releases the current PointLocator object.
void copy_constraint_rows(const MeshBase &other_mesh)
Copy the constraints from the other mesh to this mesh.
std::vector< std::string > _node_integer_names
The array of names for integer data associated with each node in the mesh.
std::map< subdomain_id_type, std::string > & set_subdomain_name_map()
Preparation _preparation
Flags indicating in what ways this mesh has been prepared.
void skip_partitioning(bool skip)
If true is passed in then nothing on this mesh will be (re)partitioned.
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 ...
void post_dofobject_moves(MeshBase &&other_mesh)
Moves any superclass data (e.g.
void clear_stored_ranges()
Clears stored ranges, to indicate that the mesh has changed and they should be regenerated when next ...
This is the MeshCommunication class.
void allgather(MeshBase &mesh) const
This method takes an input DistributedMesh which may be distributed among all the processors.
A Node is like a Point, but with more information.
static std::unique_ptr< Node > build(const Node &n)
const Parallel::Communicator & comm() const
static std::unique_ptr< Partitioner > build(const PartitionerType solver_package)
Builds a Partitioner of the type specified by partitioner_type.
A Point defines a location in LIBMESH_DIM dimensional Real space.
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
virtual void clear() override
Clear all internal data.
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.
std::vector< Elem * > _elements
The elements in the mesh.
virtual Node * add_node(Node *n) override final
Add Node n to the end of the vertex array.
virtual void update_parallel_id_counts() override
Updates parallel caches so that methods like n_elem() accurately reflect changes on other processors.
virtual void move_nodes_and_elements(MeshBase &&other_mesh) override
Move node and elements from a ReplicatedMesh.
virtual void delete_node(Node *n) override final
Removes the Node n from the mesh.
ReplicatedMesh(const Parallel::Communicator &comm_in, unsigned char dim=1)
Constructor.
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 ...
virtual dof_id_type max_node_id() const override final
virtual dof_id_type max_elem_id() const override final
virtual const Node * node_ptr(const dof_id_type i) 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.
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...
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 dof_id_type n_active_elem() const override final
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...
virtual dof_id_type n_elem() const override final
virtual void delete_elem(Elem *e) override final
Removes element e from the mesh.
virtual const Elem * query_elem_ptr(const dof_id_type i) const override final
std::unordered_map< dof_id_type, std::vector< std::vector< Point > > > get_boundary_points() const
Return all points on boundary.
virtual const Elem * elem_ptr(const dof_id_type i) const override final
virtual Elem * add_elem(Elem *e) override final
Add elem e to the end of the element array.
ReplicatedMesh & operator=(const ReplicatedMesh &)=delete
Copy assignment is not allowed.
virtual dof_id_type n_nodes() const override final
unsigned int level ElemType type std::set< subdomain_id_type > ss
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 MeshBase & assign(MeshBase &&other_mesh) override
Shim to call the move assignment operator for this class.
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.
virtual const Point & point(const dof_id_type i) const override final
virtual void set_next_unique_id(unique_id_type id) override final
Sets the next available unique id to be used.
virtual unique_id_type parallel_max_unique_id() const override final
virtual const Node * query_node_ptr(const dof_id_type i) const override final
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...
virtual ~ReplicatedMesh()
Destructor.
The UnstructuredMesh class is derived from the MeshBase class.
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...
UnstructuredMesh & operator=(const UnstructuredMesh &)=delete
Copy assignment is not allowed.
The libMesh namespace provides an interface to certain functionality in the library.
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
T command_line_value(const std::string &, T)
uint8_t processor_id_type
bool has_removed_orphaned_nodes
bool has_synched_id_counts