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);
681#ifdef LIBMESH_ENABLE_UNIQUE_ID
685 parallel_object_only();
704 LOG_SCOPE(
"renumber_nodes_and_elem()",
"Mesh");
711 std::unordered_set<Node *> connected_nodes;
718 std::vector<Elem *>::iterator in =
_elements.begin();
719 std::vector<Elem *>::iterator out_iter =
_elements.begin();
720 const std::vector<Elem *>::iterator end =
_elements.end();
722 for (; in != end; ++in)
731 el->
set_id (next_free_elem++);
737 connected_nodes.insert(&n);
746 if (n.id() == next_free_node)
749 else if (n.id() > next_free_node)
760 std::swap(_nodes[src_idx],
764 if (_nodes[src_idx] !=
nullptr)
765 _nodes[src_idx]->set_id (src_idx);
766 _nodes[dst_idx]->set_id (dst_idx);
785 std::vector<Node *>::iterator in = _nodes.begin();
786 std::vector<Node *>::iterator out_iter = _nodes.begin();
787 const std::vector<Node *>::iterator end = _nodes.end();
789 for (; in != end; ++in)
796 if (connected_nodes.count(nd))
802 nd->
set_id (next_free_node++);
817 _nodes.erase (out_iter, end);
827 std::vector<Node *>::iterator nd = _nodes.begin();
828 const std::vector<Node *>::iterator end = _nodes.end();
830 std::advance (nd, next_free_node);
832 for (
auto & node :
as_range(nd, end))
850 _nodes.erase (nd, end);
856 libmesh_assert_equal_to (next_free_elem,
_elements.size());
857 libmesh_assert_equal_to (next_free_node, _nodes.size());
868 if (this->_nodes[n] !=
nullptr)
869 this->_nodes[n]->set_id() = cast_int<dof_id_type>(n);
874 this->
_elements[e]->set_id() = cast_int<dof_id_type>(e);
880 return static_cast<dof_id_type>(std::distance (this->active_elements_begin(),
881 this->active_elements_end()));
884std::vector<dof_id_type>
888 std::vector<dof_id_type> representative_elem_ids;
893 std::vector<subdomain_id_type> subdomains;
904 std::vector<const Elem *> list;
912 for (
const auto & elem : active_element_ptr_range())
915 list.push_back(elem);
916 (*subdomain_ids)[elem->id()] = subdomain_counter;
922 dof_id_type min_id = std::numeric_limits<dof_id_type>::max();
923 while (list.size() > 0)
926 const Elem * elem = list.back(); list.pop_back(); ++visited;
928 min_id = std::min(elem->
id(), min_id);
937 list.push_back(neighbor);
938 (*subdomain_ids)[neighbor->
id()] = subdomain_counter;
943 representative_elem_ids.push_back(min_id);
946 while (visited != n_active);
948 return representative_elem_ids;
951std::unordered_map<dof_id_type, std::vector<std::vector<Point>>>
955 "Error: get_boundary_points only works for 2D now");
959 std::vector<subdomain_id_type> subdomains;
962 std::unordered_map<dof_id_type, std::vector<std::vector<Point>>> boundary_points;
966 struct boundary_side_compare
968 bool operator()(
const std::pair<const Elem *, unsigned int> & lhs,
969 const std::pair<const Elem *, unsigned int> & rhs)
const
971 if (lhs.first->id() < rhs.first->id())
973 else if (lhs.first->id() == rhs.first->id())
975 if (lhs.second < rhs.second)
981 std::set<std::pair<const Elem *, unsigned int>, boundary_side_compare> boundary_elements;
982 for (
const auto & elem : active_element_ptr_range())
983 for (
auto s : elem->side_index_range())
984 if (elem->neighbor_ptr(s) ==
nullptr)
985 boundary_elements.insert(std::pair<const Elem *, unsigned int>(elem, s));
987 while (!boundary_elements.empty())
990 const Elem * eseed = boundary_elements.begin()->first;
991 unsigned int sseed = boundary_elements.begin()->second;
997 std::vector<Point> bpoints;
998 const Elem * elem = eseed;
999 unsigned int s = sseed;
1000 std::vector<unsigned int> local_side_nodes = elem->
nodes_on_side(s);
1003 std::pair<const Elem *, unsigned int> side(elem, s);
1005 boundary_elements.erase(side);
1010 bpoints.push_back(*
static_cast<const Point *
>(elem->
node_ptr(local_side_nodes[i])));
1013 const Node * node = elem->
node_ptr(local_side_nodes[1]);
1014 std::set<const Elem *> neighbors;
1018 if (neighbors.size() != 1)
1019 neighbors.erase(elem);
1023 for (
const auto & neighbor : neighbors)
1025 for (
auto ss : neighbor->side_index_range())
1026 if (neighbor->neighbor_ptr(
ss) ==
nullptr && !(elem == neighbor && s ==
ss))
1028 local_side_nodes = neighbor->nodes_on_side(
ss);
1030 if (neighbor->node_ptr(local_side_nodes[0]) == node)
1037 else if (neighbor->node_ptr(local_side_nodes[1]) == node)
1043 auto temp(local_side_nodes);
1044 local_side_nodes[0] = temp[1];
1045 local_side_nodes[1] = temp[0];
1046 for (
unsigned int i = 2; i < temp.size(); ++i)
1047 local_side_nodes[temp.size() + 1 - i] = temp[i];
1055 libmesh_error_msg_if(!found,
"ERROR: mesh topology error on visiting boundary sides");
1058 if (elem == eseed && s == sseed)
1061 boundary_points[elem_ids[subdomain_id]].push_back(bpoints);
1064 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
dof_id_type _n_constraint_rows
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()
dof_id_type count_constraint_rows()
Helper function for subclasses to use to set _n_constraint_rows.
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