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_UNSTRUCTURED_MESH_H
21 : #define LIBMESH_UNSTRUCTURED_MESH_H
22 :
23 : // Local Includes
24 : #include "libmesh/mesh_base.h"
25 :
26 : // C++ Includes
27 : #include <cstddef>
28 :
29 : namespace libMesh
30 : {
31 :
32 : /**
33 : * The \p UnstructuredMesh class is derived from the \p MeshBase class. The
34 : * user will typically want to instantiate and use the
35 : * Mesh class in her applications, which is currently a simple
36 : * derived class of UnstructuredMesh.
37 : * In order to use the adaptive mesh refinement capabilities
38 : * of the library, first instantiate a MeshRefinement object
39 : * with a reference to this class. Then call the appropriate
40 : * refinement functions from that object. To interact with the
41 : * boundary, instantiate a BoundaryMesh with a reference to
42 : * this class, and then use that object's functionality.
43 : *
44 : * \author Roy Stogner
45 : * \date 2007
46 : * \brief Base class for Replicated and Distributed meshes.
47 : */
48 24 : class UnstructuredMesh : public MeshBase
49 : {
50 : public:
51 :
52 : /**
53 : * Constructor. Takes \p dim, the dimension of the mesh.
54 : * The mesh dimension can be changed (and may automatically be
55 : * changed by mesh generation/loading) later.
56 : */
57 : explicit
58 : UnstructuredMesh (const Parallel::Communicator & comm_in,
59 : unsigned char dim=1);
60 :
61 : /**
62 : * UnstructuredMesh uses a defaulted copy constructor.
63 : */
64 : UnstructuredMesh(const UnstructuredMesh &) = default;
65 :
66 : /**
67 : * UnstructuredMesh constructor from arbitrary (e.g. Cartesian
68 : * someday?) meshes
69 : */
70 : UnstructuredMesh(const MeshBase &);
71 :
72 : /**
73 : * Move-constructor deleted in MeshBase.
74 : */
75 : UnstructuredMesh(UnstructuredMesh &&) = delete;
76 :
77 : /**
78 : * Copy assignment is not allowed.
79 : */
80 : UnstructuredMesh & operator= (const UnstructuredMesh &) = delete;
81 :
82 : /**
83 : * Move assignment is allowed, by subclasses who handle
84 : * post_dofobject_moves()
85 : */
86 402 : UnstructuredMesh & operator= (UnstructuredMesh && other_mesh) = default;
87 :
88 : virtual MeshBase & assign(MeshBase && other_mesh) override = 0;
89 :
90 : /**
91 : * Destructor.
92 : */
93 : virtual ~UnstructuredMesh();
94 :
95 : /**
96 : * Reads the file specified by \p name. Attempts to figure out the
97 : * proper method by the file extension. This is now the only
98 : * way to read a mesh. The \p UnstructuredMesh then initializes its data
99 : * structures and is ready for use.
100 : *
101 : * The skip_renumber_nodes_and_elements argument is now deprecated -
102 : * to disallow renumbering, set \p MeshBase::allow_renumbering(false).
103 : *
104 : * Set skip_find_neighbors=true to skip the find-neighbors operation
105 : * during prepare_for_use. This operation isn't always necessary
106 : * and it can be time-consuming, which is why we provide an option to
107 : * skip it.
108 : */
109 : virtual void read (const std::string & name,
110 : void * mesh_data=nullptr,
111 : bool skip_renumber_nodes_and_elements=false,
112 : bool skip_find_neighbors=false,
113 : bool skip_detect_interior_parents=false) override;
114 : /**
115 : * Write the file specified by \p name. Attempts to figure out the
116 : * proper method by the file extension.
117 : */
118 : virtual void write (const std::string & name) const override;
119 :
120 : /**
121 : * Write to the file specified by \p name. Attempts to figure out the
122 : * proper method by the file extension. Also writes data.
123 : */
124 : void write (const std::string & name,
125 : const std::vector<Number> & values,
126 : const std::vector<std::string> & variable_names) const;
127 :
128 : /**
129 : * Converts a mesh with higher-order
130 : * elements into a mesh with linear elements. For
131 : * example, a mesh consisting of \p Tet10 will be converted
132 : * to a mesh with \p Tet4 etc.
133 : */
134 : virtual void all_first_order () override;
135 :
136 : /**
137 : * Converts a (conforming, non-refined) mesh with linear elements
138 : * into a mesh with second-order elements. For example, a mesh
139 : * consisting of \p Tet4 will be converted to a mesh with \p Tet10
140 : * etc.
141 : *
142 : * \note For some elements like \p Hex8 there exist two higher order
143 : * equivalents, \p Hex20 and \p Hex27. When \p full_ordered is \p
144 : * true (default), then \p Hex27 is built. Otherwise, \p Hex20 is
145 : * built. The same holds obviously for \p Quad4, \p Prism6, etc.
146 : */
147 : virtual void all_second_order_range (const SimpleRange<element_iterator> & range,
148 : const bool full_ordered=true) override;
149 :
150 : /**
151 : * Converts a (conforming, non-refined) mesh with linear elements
152 : * into a mesh with "complete" order elements, i.e. elements which
153 : * can store degrees of freedom on any vertex, edge, or face. For
154 : * example, a mesh consisting of \p Tet4 or \p Tet10 will be
155 : * converted to a mesh with \p Tet14 etc.
156 : */
157 : virtual void all_complete_order_range (const SimpleRange<element_iterator> & range) override;
158 :
159 : /**
160 : * Generates a new mesh containing all the elements which
161 : * are assigned to processor \p pid. This mesh is written
162 : * to the pid_mesh reference which you must create and pass
163 : * to the function.
164 : */
165 : void create_pid_mesh (UnstructuredMesh & pid_mesh,
166 : const processor_id_type pid) const;
167 :
168 : /**
169 : * Constructs a mesh called "new_mesh" from the current mesh by
170 : * iterating over the elements between it and it_end and adding
171 : * them to the new mesh.
172 : */
173 : void create_submesh (UnstructuredMesh & new_mesh,
174 : const const_element_iterator & it,
175 : const const_element_iterator & it_end) const;
176 :
177 : /**
178 : * Stitch \p other_mesh to this mesh so that this mesh is the union of the two meshes.
179 : * \p this_mesh_boundary and \p other_mesh_boundary are used to specify a dim-1 dimensional
180 : * surface on which we seek to merge any "overlapping" nodes, where we use the parameter
181 : * \p tol as a relative tolerance (relative to the smallest edge length on the surfaces
182 : * being stitched) to determine whether or not nodes are overlapping.
183 : * If \p clear_stitched_boundary_ids==true, this function clears boundary_info IDs in this
184 : * mesh associated \p this_mesh_boundary and \p other_mesh_boundary.
185 : * If \p use_binary_search is true, we use an optimized "sort then binary search" algorithm
186 : * for finding matching nodes. Otherwise we use a N^2 algorithm (which can be more reliable
187 : * at dealing with slightly misaligned meshes).
188 : * If \p enforce_all_nodes_match_on_boundaries is true, we throw an error if the number of
189 : * nodes on the specified boundaries don't match the number of nodes that were merged.
190 : * This is a helpful error check in some cases. If this is true, it overrides the value of
191 : * \p merge_boundary_nodes_all_or_nothing.
192 : * If \p skip_find_neighbors is true, a faster stitching method is used, where the lists of
193 : * neighbors for each elements are copied as well and patched, without calling the time-consuming
194 : * find_neighbors() function. This option is now hard-coded to true.
195 : * If \p merge_boundary_nodes_all_or_nothing is true, instead of throwing an error
196 : * like \p enforce_all_nodes_match_on_boundaries, the meshes are combined anyway but coincident
197 : * nodes are not merged into single nodes. This is useful in cases where you are not sure if the
198 : * boundaries are fully conforming beforehand and you want to handle the non-conforming cases
199 : * differently.
200 : *
201 : * Note that the element IDs for elements in the stitched mesh corresponding to "this" mesh
202 : * will be unchanged. The IDs for elements corresponding to \p other_mesh will be incremented
203 : * by this->max_elem_id().
204 : *
205 : * There is no simple a priori relationship between node IDs in "this" mesh
206 : * and other_mesh and node IDs in the stitched mesh because the number of nodes (and hence
207 : * the node IDs) in the stitched mesh depend on how many nodes are stitched.
208 : *
209 : * If \p remap_subdomain_ids is true then we assume that some
210 : * subdomain ids might have been autogenerated, so we remap them as
211 : * necessary, treating subdomain names as the important thing for
212 : * consistency; if we have missing names and cannot infer a
213 : * consistent resolution to an id conflict then we exit with an
214 : * error. If \p remap_subdomain_ids is false then we revert to the
215 : * older libMesh behavior: leave all subdomain ids alone and woe
216 : * unto you if you weren't keeping track of them.
217 : *
218 : * If \p prepare_after_stitching is true then we prepare the newly
219 : * stitched mesh for use immediately after stitching. If the mesh
220 : * does not need to be completely prepared for use yet (e.g. because
221 : * it will undergo further stitching etc. before repartitioning for
222 : * load balancing is desired), this can be set to false to
223 : * potentially improve performance.
224 : *
225 : * \returns the count of how many nodes were merged between the two meshes.
226 : * This can be zero in the case of no matching nodes or if
227 : * \p merge_boundary_nodes_all_or_nothing was active and relevant.
228 : */
229 : std::size_t stitch_meshes (const MeshBase & other_mesh,
230 : boundary_id_type this_mesh_boundary,
231 : boundary_id_type other_mesh_boundary,
232 : Real tol=TOLERANCE,
233 : bool clear_stitched_boundary_ids=false,
234 : bool verbose=true,
235 : bool use_binary_search=true,
236 : bool enforce_all_nodes_match_on_boundaries=false,
237 : bool merge_boundary_nodes_all_or_nothing=false,
238 : bool remap_subdomain_ids=false,
239 : bool prepare_after_stitching=true);
240 :
241 : /**
242 : * Similar to stitch_meshes, except that we stitch two adjacent surfaces within this mesh.
243 : */
244 : std::size_t stitch_surfaces (boundary_id_type boundary_id_1,
245 : boundary_id_type boundary_id_2,
246 : Real tol=TOLERANCE,
247 : bool clear_stitched_boundary_ids=false,
248 : bool verbose=true,
249 : bool use_binary_search=true,
250 : bool enforce_all_nodes_match_on_boundaries=false,
251 : bool merge_boundary_nodes_all_or_nothing=false,
252 : bool prepare_after_stitching=true);
253 :
254 : /**
255 : * Deep copy of nodes and elements from another mesh object (used by
256 : * subclass copy constructors and by mesh merging operations)
257 : *
258 : * This will not copy most "high level" data in the mesh; that is
259 : * done separately by constructors. An exception is that, if the
260 : * \p other_mesh has element or node extra_integer data, any names
261 : * for that data which do not already exist on \p this mesh are
262 : * added so that all such data can be copied.
263 : *
264 : * If an \p id_remapping map is provided, then element subdomain ids
265 : * in \p other_mesh will be converted using it before adding them to
266 : * \p this mesh.
267 : *
268 : * For backwards compatibility, this does some limited mesh
269 : * preparation after the copy: everything except for renumbering,
270 : * remote element removal, and partitioning. To skip just the
271 : * step of that preparation which finds new neighbor_ptr links
272 : * between elements, set \p skip_find_neighbors. To skip all of
273 : * that preparation, set \p skip_preparation. If preparation is
274 : * skipped, it is the users responsibility to set the flags
275 : * indicating what preparation may still be necessary before using
276 : * the mesh later.
277 : */
278 : virtual void copy_nodes_and_elements (const MeshBase & other_mesh,
279 : const bool skip_find_neighbors = false,
280 : dof_id_type element_id_offset = 0,
281 : dof_id_type node_id_offset = 0,
282 : unique_id_type unique_id_offset = 0,
283 : std::unordered_map<subdomain_id_type, subdomain_id_type> *
284 : id_remapping = nullptr,
285 : const bool skip_preparation = false);
286 :
287 : /**
288 : * Move node and elements from other_mesh to this mesh.
289 : */
290 : virtual void move_nodes_and_elements(MeshBase && other_mesh) = 0;
291 :
292 :
293 : /**
294 : * Other functions from MeshBase requiring re-definition.
295 : */
296 : virtual void find_neighbors (const bool reset_remote_elements = false,
297 : const bool reset_current_list = true,
298 : const bool assert_valid = true) override;
299 :
300 : #ifdef LIBMESH_ENABLE_AMR
301 : /**
302 : * Delete subactive (i.e. children of coarsened) elements.
303 : * This removes all elements descended from currently active
304 : * elements in the mesh.
305 : */
306 : virtual bool contract () override;
307 : #endif // #ifdef LIBMESH_ENABLE_AMR
308 :
309 : private:
310 :
311 : /**
312 : * Helper function for stitch_meshes and stitch_surfaces
313 : * that does the mesh stitching.
314 : */
315 : std::size_t stitching_helper (const MeshBase * other_mesh,
316 : boundary_id_type boundary_id_1,
317 : boundary_id_type boundary_id_2,
318 : Real tol,
319 : bool clear_stitched_boundary_ids,
320 : bool verbose,
321 : bool use_binary_search,
322 : bool enforce_all_nodes_match_on_boundaries,
323 : bool skip_find_neighbors,
324 : bool merge_boundary_nodes_all_or_nothing,
325 : bool remap_subdomain_ids,
326 : bool prepare_after_stitching);
327 : };
328 :
329 :
330 : } // namespace libMesh
331 :
332 : #endif // LIBMESH_UNSTRUCTURED_MESH_H
|