Line data Source code
1 : // The libMesh Finite Element Library.
2 : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 :
4 : // This library is free software; you can redistribute it and/or
5 : // modify it under the terms of the GNU Lesser General Public
6 : // License as published by the Free Software Foundation; either
7 : // version 2.1 of the License, or (at your option) any later version.
8 :
9 : // This library is distributed in the hope that it will be useful,
10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 : // Lesser General Public License for more details.
13 :
14 : // You should have received a copy of the GNU Lesser General Public
15 : // License along with this library; if not, write to the Free Software
16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 :
18 :
19 :
20 : #ifndef LIBMESH_REPLICATED_MESH_H
21 : #define LIBMESH_REPLICATED_MESH_H
22 :
23 : // Local Includes
24 : #include "libmesh/unstructured_mesh.h"
25 :
26 : // C++ Includes
27 : #include <cstddef>
28 : #include <memory>
29 : #include <unordered_map>
30 :
31 : namespace libMesh
32 : {
33 :
34 : /**
35 : * The \p ReplicatedMesh class is derived from the \p MeshBase class,
36 : * and is used to store identical copies of a full mesh data
37 : * structure on each processor.
38 : *
39 : * Most methods for this class are found in MeshBase, and most
40 : * implementation details are found in UnstructuredMesh.
41 : *
42 : * \author Roy Stogner
43 : * \date 2007
44 : * \brief Mesh data structure replicated on all processors.
45 : */
46 : class ReplicatedMesh : public UnstructuredMesh
47 : {
48 : public:
49 :
50 : /**
51 : * Constructor. Takes \p dim, the dimension of the mesh.
52 : * The mesh dimension can be changed (and may automatically be
53 : * changed by mesh generation/loading) later.
54 : */
55 : explicit
56 : ReplicatedMesh (const Parallel::Communicator & comm_in,
57 : unsigned char dim=1);
58 :
59 : /**
60 : * Copy-constructor. This should be able to take a
61 : * serial or parallel mesh.
62 : */
63 : ReplicatedMesh (const MeshBase & other_mesh);
64 :
65 : /**
66 : * Copy-constructor, possibly specialized for a
67 : * serial mesh.
68 : */
69 : ReplicatedMesh (const ReplicatedMesh & other_mesh);
70 :
71 : /**
72 : * Move-constructor deleted in MeshBase.
73 : */
74 : ReplicatedMesh(ReplicatedMesh &&) = delete;
75 :
76 : /**
77 : * Copy assignment is not allowed.
78 : */
79 : ReplicatedMesh & operator= (const ReplicatedMesh &) = delete;
80 :
81 : /**
82 : * Move assignment operator.
83 : */
84 : ReplicatedMesh & operator= (ReplicatedMesh && other_mesh);
85 :
86 : /**
87 : * Shim to call the move assignment operator for this class
88 : */
89 : virtual MeshBase & assign(MeshBase && other_mesh) override;
90 :
91 : /**
92 : * Move node and elements from a ReplicatedMesh.
93 : */
94 : virtual void move_nodes_and_elements(MeshBase && other_mesh) override;
95 :
96 : /**
97 : * Shim to allow operator == (&) to behave like a virtual function
98 : * without having to be one.
99 : */
100 : virtual bool subclass_locally_equals (const MeshBase & other_mesh) const override;
101 :
102 : /**
103 : * Virtual copy-constructor, creates a copy of this mesh
104 : */
105 1056 : virtual std::unique_ptr<MeshBase> clone () const override
106 : {
107 1088 : auto returnval = std::make_unique<ReplicatedMesh>(*this);
108 : #ifdef DEBUG
109 32 : libmesh_assert(*returnval == *this);
110 : #endif
111 1088 : return returnval;
112 1024 : }
113 :
114 : /**
115 : * Destructor.
116 : */
117 : virtual ~ReplicatedMesh();
118 :
119 : /**
120 : * Clear all internal data.
121 : */
122 : virtual void clear() override;
123 :
124 : /**
125 : * Clear internal Elem data.
126 : */
127 : virtual void clear_elems() override;
128 :
129 : /**
130 : * @copydoc MeshBase::renumber_nodes_and_elements()
131 : *
132 : * Note that regardless of whether \p _skip_renumber_nodes_and_elements is true, this method will
133 : * always remove nullptr nodes and elements from arrays and consequently will always renumber. So in
134 : * practice \p _skip_renumber_nodes_and_elements means skip reordering of non-null nodes and
135 : * elements while allowing renumbering
136 : */
137 : virtual void renumber_nodes_and_elements () override;
138 :
139 896600 : virtual dof_id_type n_nodes () const override final
140 12516 : { return _n_nodes; }
141 :
142 384 : virtual dof_id_type parallel_n_nodes () const override final
143 384 : { return _n_nodes; }
144 :
145 6763546 : virtual dof_id_type max_node_id () const override final
146 6945847 : { return cast_int<dof_id_type>(_nodes.size()); }
147 :
148 14836 : virtual void reserve_nodes (const dof_id_type nn) override final
149 14836 : { _nodes.reserve (nn); }
150 :
151 63694 : virtual dof_id_type n_elem () const override final
152 11465 : { return _n_elem; }
153 :
154 384 : virtual dof_id_type parallel_n_elem () const override final
155 384 : { return _n_elem; }
156 :
157 : virtual dof_id_type n_active_elem () const override final;
158 :
159 9975997 : virtual dof_id_type max_elem_id () const override final
160 10191559 : { return cast_int<dof_id_type>(_elements.size()); }
161 :
162 : #ifdef LIBMESH_ENABLE_UNIQUE_ID
163 : virtual unique_id_type parallel_max_unique_id () const override final;
164 : virtual void set_next_unique_id(unique_id_type id) override final;
165 : #endif
166 :
167 13684 : virtual void reserve_elem (const dof_id_type ne) override final
168 13684 : { _elements.reserve (ne); }
169 :
170 : virtual void update_parallel_id_counts () override;
171 :
172 : virtual const Point & point (const dof_id_type i) const override final;
173 :
174 : virtual const Node * node_ptr (const dof_id_type i) const override final;
175 : virtual Node * node_ptr (const dof_id_type i) override final;
176 :
177 : virtual const Node * query_node_ptr (const dof_id_type i) const override final;
178 : virtual Node * query_node_ptr (const dof_id_type i) override final;
179 :
180 : virtual const Elem * elem_ptr (const dof_id_type i) const override final;
181 : virtual Elem * elem_ptr (const dof_id_type i) override final;
182 :
183 : virtual const Elem * query_elem_ptr (const dof_id_type i) const override final;
184 : virtual Elem * query_elem_ptr (const dof_id_type i) override final;
185 :
186 : /**
187 : * functions for adding /deleting nodes elements.
188 : */
189 : virtual Node * add_point (const Point & p,
190 : const dof_id_type id = DofObject::invalid_id,
191 : const processor_id_type proc_id = DofObject::invalid_processor_id) override final;
192 : virtual Node * add_node (Node * n) override final;
193 : virtual Node * add_node (std::unique_ptr<Node> n) override final;
194 :
195 : #ifdef LIBMESH_ENABLE_DEPRECATED
196 : /**
197 : * These methods are deprecated. Please use \p add_node instead
198 : * Insert \p Node \p n into the Mesh at a location consistent with
199 : * n->id(), allocating extra storage if necessary. Throws an error if:
200 : * .) n==nullptr
201 : * .) n->id() == DofObject::invalid_id
202 : * .) A node already exists in position n->id().
203 : *
204 : * This function differs from the ReplicatedMesh::add_node() function,
205 : * which is only capable of appending nodes at the end of the nodes
206 : * storage.
207 : */
208 : virtual Node * insert_node(Node * n) override final;
209 : virtual Node * insert_node(std::unique_ptr<Node> n) override final;
210 : #endif
211 :
212 : virtual void delete_node (Node * n) override final;
213 : virtual void renumber_node (dof_id_type old_id, dof_id_type new_id) override final;
214 : virtual Elem * add_elem (Elem * e) override final;
215 : virtual Elem * add_elem (std::unique_ptr<Elem> e) override final;
216 : virtual Elem * insert_elem (Elem * e) override final;
217 : virtual Elem * insert_elem (std::unique_ptr<Elem> e) override final;
218 : virtual void delete_elem (Elem * e) override final;
219 : virtual void renumber_elem (dof_id_type old_id, dof_id_type new_id) override final;
220 :
221 : /**
222 : * There is no reason for a user to ever call this function.
223 : *
224 : * This function restores a previously broken element/node numbering such that
225 : * \p mesh.node_ref(n).id() == n.
226 : */
227 : virtual void fix_broken_node_and_element_numbering () override;
228 :
229 : /**
230 : * Return IDs of representative elements of all disconnected subdomains.
231 : * Subdomains are considered connected only when they are sharing at least
232 : * one d-1 dimensional object (side in 2D, face in 3D), where d is
233 : * the mesh dimension.
234 : * The optional argument can be used for getting the subdomain IDs of all
235 : * elements with element IDs as the index.
236 : * This function cannot be called for a mesh with hanging nodes from
237 : * adaptive mesh refinement.
238 : */
239 : std::vector<dof_id_type> get_disconnected_subdomains(std::vector<subdomain_id_type> * subdomain_ids = nullptr) const;
240 :
241 : /**
242 : * Return all points on boundary.
243 : * The key of the returned unordered map is the ID of a representative
244 : * element of all disconnected subdomains. Subdomains are considered
245 : * connected only when they are sharing at least one d-1 dimensional object
246 : * (side in 2D), where d is the mesh dimension.
247 : * The size of the unordered map value is the number of disconnected
248 : * boundaries for a subdomain. Boundaries are considered
249 : * connected only when they are sharing a d-2 dimensional object.
250 : * This function currently only works for 2D meshes.
251 : * The points of each boundary are ordered to form an enclosure.
252 : */
253 : std::unordered_map<dof_id_type, std::vector<std::vector<Point>>> get_boundary_points() const;
254 :
255 : public:
256 : /**
257 : * Elem and Node iterator accessor functions. See MeshBase for
258 : * documentation.
259 : */
260 239237 : DECLARE_ELEM_ITERATORS(,,);
261 312314 : DECLARE_ELEM_ITERATORS(active_,,);
262 0 : DECLARE_ELEM_ITERATORS(ancestor_,,)
263 0 : DECLARE_ELEM_ITERATORS(subactive_,,)
264 0 : DECLARE_ELEM_ITERATORS(local_,,)
265 0 : DECLARE_ELEM_ITERATORS(unpartitioned_,,)
266 0 : DECLARE_ELEM_ITERATORS(facelocal_,,)
267 0 : DECLARE_ELEM_ITERATORS(level_, unsigned int level, level)
268 0 : DECLARE_ELEM_ITERATORS(pid_, processor_id_type pid, pid)
269 0 : DECLARE_ELEM_ITERATORS(type_, ElemType type, type)
270 :
271 1500 : DECLARE_ELEM_ITERATORS(active_subdomain_, subdomain_id_type sid, sid)
272 0 : DECLARE_ELEM_ITERATORS(active_subdomain_set_, std::set<subdomain_id_type> ss, ss)
273 :
274 0 : DECLARE_ELEM_ITERATORS(not_active_,,);
275 0 : DECLARE_ELEM_ITERATORS(not_ancestor_,,);
276 0 : DECLARE_ELEM_ITERATORS(not_subactive_,,);
277 0 : DECLARE_ELEM_ITERATORS(not_local_,,);
278 0 : DECLARE_ELEM_ITERATORS(not_level_, unsigned int level, level)
279 :
280 89738 : DECLARE_ELEM_ITERATORS(active_local_,,)
281 0 : DECLARE_ELEM_ITERATORS(active_not_local_,,)
282 4872 : DECLARE_ELEM_ITERATORS(active_unpartitioned_,,)
283 0 : DECLARE_ELEM_ITERATORS(active_type_, ElemType type, type)
284 0 : DECLARE_ELEM_ITERATORS(active_pid_, processor_id_type pid, pid)
285 0 : DECLARE_ELEM_ITERATORS(local_level_, unsigned int level, level)
286 0 : DECLARE_ELEM_ITERATORS(local_not_level_, unsigned int level, level)
287 1152 : DECLARE_ELEM_ITERATORS(active_local_subdomain_, subdomain_id_type sid, sid)
288 0 : DECLARE_ELEM_ITERATORS(active_local_subdomain_set_, std::set<subdomain_id_type> ss, ss)
289 :
290 : // Backwards compatibility
291 750 : virtual SimpleRange<element_iterator> active_subdomain_elements_ptr_range(subdomain_id_type sid) override final { return active_subdomain_element_ptr_range(sid); }
292 0 : virtual SimpleRange<const_element_iterator> active_subdomain_elements_ptr_range(subdomain_id_type sid) const override final { return active_subdomain_element_ptr_range(sid); }
293 576 : virtual SimpleRange<element_iterator> active_local_subdomain_elements_ptr_range(subdomain_id_type sid) override final { return active_local_subdomain_element_ptr_range(sid); }
294 0 : virtual SimpleRange<const_element_iterator> active_local_subdomain_elements_ptr_range(subdomain_id_type sid) const override final { return active_local_subdomain_element_ptr_range(sid); }
295 0 : virtual SimpleRange<element_iterator> active_subdomain_set_elements_ptr_range(std::set<subdomain_id_type> ss) override final { return active_subdomain_set_element_ptr_range(ss); }
296 0 : virtual SimpleRange<const_element_iterator> active_subdomain_set_elements_ptr_range(std::set<subdomain_id_type> ss) const override final { return active_subdomain_set_element_ptr_range(ss); }
297 :
298 0 : DECLARE_ELEM_ITERATORS(semilocal_,,)
299 0 : DECLARE_ELEM_ITERATORS(ghost_,,)
300 0 : DECLARE_ELEM_ITERATORS(active_semilocal_,,)
301 :
302 0 : DECLARE_ELEM_ITERATORS(evaluable_, const DofMap & dof_map LIBMESH_COMMA unsigned int var_num = libMesh::invalid_uint, dof_map LIBMESH_COMMA var_num)
303 0 : DECLARE_ELEM_ITERATORS(multi_evaluable_, std::vector<const DofMap *> dof_maps, dof_maps)
304 :
305 : #ifdef LIBMESH_ENABLE_AMR
306 0 : DECLARE_ELEM_ITERATORS(flagged_, unsigned char rflag, rflag)
307 :
308 : // Elem::refinement_flag() == rflag && Elem::processor_id() == pid
309 0 : DECLARE_ELEM_ITERATORS(flagged_pid_, unsigned char rflag LIBMESH_COMMA processor_id_type pid, rflag LIBMESH_COMMA pid)
310 : #endif
311 :
312 128281 : DECLARE_NODE_ITERATORS(,,)
313 0 : DECLARE_NODE_ITERATORS(active_,,)
314 24318 : DECLARE_NODE_ITERATORS(local_,,)
315 0 : DECLARE_NODE_ITERATORS(bnd_,,)
316 0 : DECLARE_NODE_ITERATORS(pid_, processor_id_type pid, pid)
317 0 : DECLARE_NODE_ITERATORS(bid_, boundary_id_type bid, bid)
318 :
319 0 : DECLARE_NODE_ITERATORS(evaluable_, const DofMap & dof_map LIBMESH_COMMA unsigned int var_num = libMesh::invalid_uint, dof_map LIBMESH_COMMA var_num)
320 :
321 0 : DECLARE_NODE_ITERATORS(multi_evaluable_, std::vector<const DofMap *> dof_maps, dof_maps)
322 :
323 :
324 : protected:
325 :
326 : /**
327 : * The vertices (spatial coordinates) of the mesh.
328 : */
329 : std::vector<Node *> _nodes;
330 :
331 : dof_id_type _n_nodes;
332 :
333 : /**
334 : * The elements in the mesh.
335 : */
336 : std::vector<Elem *> _elements;
337 :
338 : dof_id_type _n_elem;
339 :
340 : private:
341 :
342 : /**
343 : * Typedefs for the container implementation. In this case,
344 : * it's just a std::vector<Elem *>.
345 : */
346 : typedef std::vector<Elem *>::iterator elem_iterator_imp;
347 : typedef std::vector<Elem *>::const_iterator const_elem_iterator_imp;
348 :
349 : /**
350 : * Typedefs for the container implementation. In this case,
351 : * it's just a std::vector<Node *>.
352 : */
353 : typedef std::vector<Node *>::iterator node_iterator_imp;
354 : typedef std::vector<Node *>::const_iterator const_node_iterator_imp;
355 : };
356 :
357 : } // namespace libMesh
358 :
359 :
360 :
361 : #endif // LIBMESH_REPLICATED_MESH_H
|