Line data Source code
1 : // The libMesh Finite Element Library.
2 : // Copyright (C) 2002-2026 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 801984 : virtual dof_id_type n_nodes () const override final
140 19148 : { return _n_nodes; }
141 :
142 384 : virtual dof_id_type parallel_n_nodes () const override final
143 384 : { return _n_nodes; }
144 :
145 8394116 : virtual dof_id_type max_node_id () const override final
146 8767793 : { return cast_int<dof_id_type>(_nodes.size()); }
147 :
148 17350 : virtual void reserve_nodes (const dof_id_type nn) override final
149 17350 : { _nodes.reserve (nn); }
150 :
151 75898 : virtual dof_id_type n_elem () const override final
152 14453 : { 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 8831116 : virtual dof_id_type max_elem_id () const override final
160 9056637 : { 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 15808 : virtual void reserve_elem (const dof_id_type ne) override final
168 15808 : { _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 : virtual void delete_node (Node * n) override final;
195 : virtual void renumber_node (dof_id_type old_id, dof_id_type new_id) override final;
196 : virtual Elem * add_elem (Elem * e) override final;
197 : virtual Elem * add_elem (std::unique_ptr<Elem> e) override final;
198 : virtual Elem * insert_elem (Elem * e) override final;
199 : virtual Elem * insert_elem (std::unique_ptr<Elem> e) override final;
200 : virtual void delete_elem (Elem * e) override final;
201 : virtual void renumber_elem (dof_id_type old_id, dof_id_type new_id) override final;
202 :
203 : /**
204 : * There is no reason for a user to ever call this function.
205 : *
206 : * This function restores a previously broken element/node numbering such that
207 : * \p mesh.node_ref(n).id() == n.
208 : */
209 : virtual void fix_broken_node_and_element_numbering () override;
210 :
211 : /**
212 : * Return IDs of representative elements of all disconnected subdomains.
213 : * Subdomains are considered connected only when they are sharing at least
214 : * one d-1 dimensional object (side in 2D, face in 3D), where d is
215 : * the mesh dimension.
216 : * The optional argument can be used for getting the subdomain IDs of all
217 : * elements with element IDs as the index.
218 : * This function cannot be called for a mesh with hanging nodes from
219 : * adaptive mesh refinement.
220 : */
221 : std::vector<dof_id_type> get_disconnected_subdomains(std::vector<subdomain_id_type> * subdomain_ids = nullptr) const;
222 :
223 : /**
224 : * Return all points on boundary.
225 : * The key of the returned unordered map is the ID of a representative
226 : * element of all disconnected subdomains. Subdomains are considered
227 : * connected only when they are sharing at least one d-1 dimensional object
228 : * (side in 2D), where d is the mesh dimension.
229 : * The size of the unordered map value is the number of disconnected
230 : * boundaries for a subdomain. Boundaries are considered
231 : * connected only when they are sharing a d-2 dimensional object.
232 : * This function currently only works for 2D meshes.
233 : * The points of each boundary are ordered to form an enclosure.
234 : */
235 : std::unordered_map<dof_id_type, std::vector<std::vector<Point>>> get_boundary_points() const;
236 :
237 : public:
238 : /**
239 : * Elem and Node iterator accessor functions. See MeshBase for
240 : * documentation.
241 : */
242 289659 : DECLARE_ELEM_ITERATORS(,,);
243 497276 : DECLARE_ELEM_ITERATORS(active_,,);
244 0 : DECLARE_ELEM_ITERATORS(ancestor_,,)
245 0 : DECLARE_ELEM_ITERATORS(subactive_,,)
246 0 : DECLARE_ELEM_ITERATORS(local_,,)
247 0 : DECLARE_ELEM_ITERATORS(unpartitioned_,,)
248 0 : DECLARE_ELEM_ITERATORS(facelocal_,,)
249 0 : DECLARE_ELEM_ITERATORS(level_, unsigned int level, level)
250 0 : DECLARE_ELEM_ITERATORS(pid_, processor_id_type pid, pid)
251 0 : DECLARE_ELEM_ITERATORS(type_, ElemType type, type)
252 :
253 1500 : DECLARE_ELEM_ITERATORS(active_subdomain_, subdomain_id_type sid, sid)
254 0 : DECLARE_ELEM_ITERATORS(active_subdomain_set_, std::set<subdomain_id_type> ss, ss)
255 :
256 0 : DECLARE_ELEM_ITERATORS(not_active_,,);
257 0 : DECLARE_ELEM_ITERATORS(not_ancestor_,,);
258 0 : DECLARE_ELEM_ITERATORS(not_subactive_,,);
259 0 : DECLARE_ELEM_ITERATORS(not_local_,,);
260 0 : DECLARE_ELEM_ITERATORS(not_level_, unsigned int level, level)
261 :
262 183322 : DECLARE_ELEM_ITERATORS(active_local_,,)
263 0 : DECLARE_ELEM_ITERATORS(active_not_local_,,)
264 5286 : DECLARE_ELEM_ITERATORS(active_unpartitioned_,,)
265 0 : DECLARE_ELEM_ITERATORS(active_type_, ElemType type, type)
266 0 : DECLARE_ELEM_ITERATORS(active_pid_, processor_id_type pid, pid)
267 0 : DECLARE_ELEM_ITERATORS(local_level_, unsigned int level, level)
268 0 : DECLARE_ELEM_ITERATORS(local_not_level_, unsigned int level, level)
269 1152 : DECLARE_ELEM_ITERATORS(active_local_subdomain_, subdomain_id_type sid, sid)
270 0 : DECLARE_ELEM_ITERATORS(active_local_subdomain_set_, std::set<subdomain_id_type> ss, ss)
271 :
272 : // Backwards compatibility
273 750 : virtual SimpleRange<element_iterator> active_subdomain_elements_ptr_range(subdomain_id_type sid) override final { return active_subdomain_element_ptr_range(sid); }
274 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); }
275 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); }
276 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); }
277 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); }
278 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); }
279 :
280 0 : DECLARE_ELEM_ITERATORS(semilocal_,,)
281 0 : DECLARE_ELEM_ITERATORS(ghost_,,)
282 0 : DECLARE_ELEM_ITERATORS(active_semilocal_,,)
283 :
284 0 : DECLARE_ELEM_ITERATORS(evaluable_, const DofMap & dof_map LIBMESH_COMMA unsigned int var_num = libMesh::invalid_uint, dof_map LIBMESH_COMMA var_num)
285 0 : DECLARE_ELEM_ITERATORS(multi_evaluable_, std::vector<const DofMap *> dof_maps, dof_maps)
286 :
287 : #ifdef LIBMESH_ENABLE_AMR
288 0 : DECLARE_ELEM_ITERATORS(flagged_, unsigned char rflag, rflag)
289 :
290 : // Elem::refinement_flag() == rflag && Elem::processor_id() == pid
291 0 : DECLARE_ELEM_ITERATORS(flagged_pid_, unsigned char rflag LIBMESH_COMMA processor_id_type pid, rflag LIBMESH_COMMA pid)
292 : #endif
293 :
294 228993 : DECLARE_NODE_ITERATORS(,,)
295 276 : DECLARE_NODE_ITERATORS(active_,,)
296 39672 : DECLARE_NODE_ITERATORS(local_,,)
297 0 : DECLARE_NODE_ITERATORS(bnd_,,)
298 0 : DECLARE_NODE_ITERATORS(pid_, processor_id_type pid, pid)
299 0 : DECLARE_NODE_ITERATORS(bid_, boundary_id_type bid, bid)
300 :
301 0 : DECLARE_NODE_ITERATORS(evaluable_, const DofMap & dof_map LIBMESH_COMMA unsigned int var_num = libMesh::invalid_uint, dof_map LIBMESH_COMMA var_num)
302 :
303 0 : DECLARE_NODE_ITERATORS(multi_evaluable_, std::vector<const DofMap *> dof_maps, dof_maps)
304 :
305 :
306 : protected:
307 :
308 : /**
309 : * The vertices (spatial coordinates) of the mesh.
310 : */
311 : std::vector<Node *> _nodes;
312 :
313 : dof_id_type _n_nodes;
314 :
315 : /**
316 : * The elements in the mesh.
317 : */
318 : std::vector<Elem *> _elements;
319 :
320 : dof_id_type _n_elem;
321 :
322 : private:
323 :
324 : /**
325 : * Typedefs for the container implementation. In this case,
326 : * it's just a std::vector<Elem *>.
327 : */
328 : typedef std::vector<Elem *>::iterator elem_iterator_imp;
329 : typedef std::vector<Elem *>::const_iterator const_elem_iterator_imp;
330 :
331 : /**
332 : * Typedefs for the container implementation. In this case,
333 : * it's just a std::vector<Node *>.
334 : */
335 : typedef std::vector<Node *>::iterator node_iterator_imp;
336 : typedef std::vector<Node *>::const_iterator const_node_iterator_imp;
337 : };
338 :
339 : } // namespace libMesh
340 :
341 :
342 :
343 : #endif // LIBMESH_REPLICATED_MESH_H
|