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_BOUNDARY_INFO_H
21 : #define LIBMESH_BOUNDARY_INFO_H
22 :
23 : // Local includes
24 : #include "libmesh/libmesh_common.h"
25 : #include "libmesh/id_types.h"
26 : #include "libmesh/parallel_object.h"
27 :
28 : // C++ includes
29 : #include <cstddef>
30 : #include <map>
31 : #include <set>
32 : #include <vector>
33 : #include <tuple>
34 :
35 : namespace libMesh
36 : {
37 :
38 :
39 : // Forward declarations
40 : class Elem;
41 : class Node;
42 : class MeshBase;
43 : class UnstructuredMesh;
44 :
45 :
46 : /**
47 : * The \p BoundaryInfo class contains information relevant to boundary
48 : * conditions including storing faces, edges, and nodes on the
49 : * boundary, along with ids that can be used to identify the type of
50 : * boundary each entity is part of. It can also build a mesh that just
51 : * includes boundary elements/faces.
52 : *
53 : * \author Benjamin S. Kirk
54 : * \date 2002
55 : * \brief Used by the Mesh to keep track of boundary nodes and elements.
56 : */
57 38612 : class BoundaryInfo : public ParallelObject
58 : {
59 : protected:
60 : friend class MeshBase;
61 :
62 : /**
63 : * Constructor. Takes a reference to the mesh.
64 : * The BoundaryInfo class is only used internally
65 : * by the Mesh class. A user should never instantiate
66 : * this class. Therefore the constructor is protected.
67 : */
68 : BoundaryInfo (MeshBase & m);
69 :
70 426 : void set_mesh (MeshBase & m) { _mesh = &m; }
71 :
72 : public:
73 : /**
74 : * Copy assignment operator
75 : *
76 : * \note \p this will still reference the same MeshBase it was
77 : * constructed with. Boundary data copied from other_boundary_info
78 : * will refer to objects in this mesh which have the same
79 : * DofObject::id() as the corresponding objects in the other mesh.
80 : */
81 : BoundaryInfo & operator=(const BoundaryInfo & other_boundary_info);
82 :
83 : /**
84 : * This tests for data equality via element ids
85 : */
86 : bool operator== (const BoundaryInfo & other_boundary_info) const;
87 :
88 420 : bool operator!= (const BoundaryInfo & other_boundary_info) const
89 : {
90 5884 : return !(*this == other_boundary_info);
91 : }
92 :
93 : /**
94 : * Destructor. Not much to do.
95 : */
96 : ~BoundaryInfo ();
97 :
98 : /**
99 : * Clears the underlying data structures and restores the object to
100 : * a pristine state with no data stored.
101 : */
102 : void clear ();
103 :
104 : /**
105 : * Clears and regenerates the cached sets of ids.
106 : * This is in general necessary after use of remove_*() functions,
107 : * which remove individual id associations (an O(1) process) without
108 : * checking to see whether that is the last association with the id
109 : * (an O(N) process).
110 : */
111 : void regenerate_id_sets ();
112 :
113 : /**
114 : * Synchronizes the boundary_ids set on each processor to determine
115 : * global_boundary_ids.
116 : *
117 : * This may be necessary after use of renumber_*() functions, which
118 : * perform only local operations, if \p get_global_boundary_ids() is
119 : * to be used without a full regenerate_id_sets() call first.
120 : */
121 : void synchronize_global_id_set ();
122 :
123 : /**
124 : * Generates \p boundary_mesh data structures corresponding to the
125 : * \p mesh data structures. Allows the \p boundary_mesh to be used
126 : * like any other mesh, except with interior_parent() values defined
127 : * for algorithms which couple boundary and interior mesh
128 : * information. Any pre-existing \p boundary_mesh data is cleared.
129 : */
130 : void sync (UnstructuredMesh & boundary_mesh);
131 :
132 : /**
133 : * Generates \p boundary_mesh data structures corresponding to the
134 : * \p mesh data structures. Allows the \p boundary_mesh to be used
135 : * like any other mesh, except with interior_parent() values defined
136 : * for algorithms which couple boundary and interior mesh
137 : * information. Any pre-existing \p boundary_mesh data is cleared.
138 : * Only boundary elements with the specified ids are extracted.
139 : * Boundary IDs for the nodes on \p requested_boundary_ids
140 : * will also be copied over to \p boundary_mesh. We do not
141 : * currently copy edge boundary IDs over to \p boundary_mesh.
142 : */
143 : void sync (const std::set<boundary_id_type> & requested_boundary_ids,
144 : UnstructuredMesh & boundary_mesh);
145 :
146 : /**
147 : * Like the other sync() implementations, but specifically intended
148 : * for building "boundary" meshes from internal sidesets. In the
149 : * case of an internal sideset, each side may belong to 2
150 : * higher-dimensional parent elements, and typically we do not want
151 : * to add the same side to the boundary mesh twice. The
152 : * std::set<subdomain_id_type> passed into this function specifies
153 : * which subdomain the sides in question should relative to, so that
154 : * they are only added once.
155 : */
156 : void sync (const std::set<boundary_id_type> & requested_boundary_ids,
157 : UnstructuredMesh & boundary_mesh,
158 : const std::set<subdomain_id_type> & subdomains_relative_to);
159 :
160 : /**
161 : * Suppose we have used sync to create \p boundary_mesh. Then each
162 : * element in \p boundary_mesh will have interior_parent defined.
163 : * This method gets extra data for us:
164 : * - \p node_id_map stores a map from the node ids on the interior mesh
165 : * to the corresponding node ids of \p boundary_mesh.
166 : * - \p side_id_map stores a map from the element ids of the boundary mesh
167 : * to the side index of the interior_parent that the boundary element
168 : * corresponds to.
169 : * \p tolerance is used to identify when we have matching elements.
170 : */
171 : void get_side_and_node_maps (UnstructuredMesh & boundary_mesh,
172 : std::map<dof_id_type, dof_id_type> & node_id_map,
173 : std::map<dof_id_type, unsigned char> & side_id_map,
174 : Real tolerance=1.e-6);
175 :
176 : /**
177 : * Generates \p elements along the boundary of our _mesh, which
178 : * use pre-existing nodes on the boundary_mesh, and which have
179 : * interior_parent values properly defined.
180 : *
181 : * The \p boundary_mesh may be the *same* as the interior mesh; this
182 : * generates a mesh with elements of mixed dimension.
183 : *
184 : * Only boundary elements with the specified ids are created.
185 : */
186 : void add_elements (const std::set<boundary_id_type> & requested_boundary_ids,
187 : UnstructuredMesh & boundary_mesh,
188 : bool store_parent_side_ids = false);
189 :
190 : /**
191 : * Same as the add_elements() function above, but takes a set of
192 : * subdomains for which the sides must be relative to. This is
193 : * necessary to avoid double-adding sides of internal sidesets to
194 : * the BoundaryMesh.
195 : */
196 : void add_elements(const std::set<boundary_id_type> & requested_boundary_ids,
197 : UnstructuredMesh & boundary_mesh,
198 : const std::set<subdomain_id_type> & subdomains_relative_to,
199 : bool store_parent_side_ids = false);
200 :
201 : /**
202 : * Add \p Node \p node with boundary id \p id to the boundary
203 : * information data structures.
204 : */
205 : void add_node (const Node * node,
206 : const boundary_id_type id);
207 :
208 : /**
209 : * Add node number \p node with boundary id \p id to the boundary
210 : * information data structures.
211 : */
212 : void add_node (const dof_id_type node,
213 : const boundary_id_type id);
214 :
215 : /**
216 : * Add \p Node \p node with boundary ids \p ids to the boundary
217 : * information data structure.
218 : */
219 : void add_node (const Node * node,
220 : const std::vector<boundary_id_type> & ids);
221 :
222 : /**
223 : * Clears all the boundary information from all of the nodes in the mesh
224 : */
225 : void clear_boundary_node_ids();
226 :
227 : /**
228 : * Add edge \p edge of element number \p elem with boundary id \p id
229 : * to the boundary information data structure.
230 : * Edge-based boundary IDs should only be used in 3D.
231 : */
232 : void add_edge (const dof_id_type elem,
233 : const unsigned short int edge,
234 : const boundary_id_type id);
235 :
236 : /**
237 : * Add edge \p edge of element \p elem with boundary id \p id
238 : * to the boundary information data structure.
239 : * Edge-based boundary IDs should only be used in 3D.
240 : */
241 : void add_edge (const Elem * elem,
242 : const unsigned short int edge,
243 : const boundary_id_type id);
244 :
245 : /**
246 : * Add edge \p edge of element \p elem with boundary ids \p ids
247 : * to the boundary information data structure.
248 : * Edge-based boundary IDs should only be used in 3D.
249 : */
250 : void add_edge (const Elem * elem,
251 : const unsigned short int edge,
252 : const std::vector<boundary_id_type> & ids);
253 :
254 : /**
255 : * Add shell face \p shellface of element number \p elem with boundary id \p id
256 : * to the boundary information data structure. This is only relevant for shell
257 : * elements.
258 : */
259 : void add_shellface (const dof_id_type elem,
260 : const unsigned short int shellface,
261 : const boundary_id_type id);
262 :
263 : /**
264 : * Add shell face \p shellface of element \p elem with boundary id \p id
265 : * to the boundary information data structure. This is only relevant for shell
266 : * elements.
267 : */
268 : void add_shellface (const Elem * elem,
269 : const unsigned short int shellface,
270 : const boundary_id_type id);
271 :
272 : /**
273 : * Add shell face \p shellface of element \p elem with boundary ids \p ids
274 : * to the boundary information data structure. This is only relevant for shell
275 : * elements.
276 : */
277 : void add_shellface (const Elem * elem,
278 : const unsigned short int shellface,
279 : const std::vector<boundary_id_type> & ids);
280 :
281 : /**
282 : * Add side \p side of element number \p elem with boundary id \p id
283 : * to the boundary information data structure.
284 : */
285 : void add_side (const dof_id_type elem,
286 : const unsigned short int side,
287 : const boundary_id_type id);
288 :
289 : /**
290 : * Add side \p side of element \p elem with boundary id \p id
291 : * to the boundary information data structure.
292 : */
293 : void add_side (const Elem * elem,
294 : const unsigned short int side,
295 : const boundary_id_type id);
296 :
297 : /**
298 : * Add side \p side of element \p elem with boundary ids \p ids
299 : * to the boundary information data structure.
300 : */
301 : void add_side (const Elem * elem,
302 : const unsigned short int side,
303 : const std::vector<boundary_id_type> & ids);
304 :
305 : /**
306 : * Removes the boundary conditions associated with node \p node,
307 : * if any exist.
308 : */
309 : void remove (const Node * node);
310 :
311 : /**
312 : * Removes the boundary conditions associated with element \p elem,
313 : * if any exist.
314 : */
315 : void remove (const Elem * elem);
316 :
317 : /**
318 : * Removes boundary id \p id from node \p node, if it exists.
319 : */
320 : void remove_node (const Node * node,
321 : const boundary_id_type id);
322 :
323 : /**
324 : * Removes all boundary conditions associated with edge \p edge of
325 : * element \p elem, if any exist.
326 : */
327 : void remove_edge (const Elem * elem,
328 : const unsigned short int edge);
329 :
330 : /**
331 : * Removes the boundary id \p id from edge \p edge of element \p
332 : * elem, if it exists.
333 : */
334 : void remove_edge (const Elem * elem,
335 : const unsigned short int edge,
336 : const boundary_id_type id);
337 :
338 : /**
339 : * Removes all boundary conditions associated with shell face
340 : * \p shellface of element \p elem, if any exist.
341 : */
342 : void remove_shellface (const Elem * elem,
343 : const unsigned short int shellface);
344 :
345 : /**
346 : * Removes all boundary conditions associated with shell face
347 : * \p shellface of element \p elem, if any exist.
348 : */
349 : void remove_shellface (const Elem * elem,
350 : const unsigned short int shellface,
351 : const boundary_id_type id);
352 :
353 : /**
354 : * Removes all boundary conditions associated with side \p side of
355 : * element \p elem, if any exist.
356 : */
357 : void remove_side (const Elem * elem,
358 : const unsigned short int side);
359 :
360 : /**
361 : * Removes the boundary id \p id from side \p side of element \p
362 : * elem, if it exists.
363 : */
364 : void remove_side (const Elem * elem,
365 : const unsigned short int side,
366 : const boundary_id_type id);
367 :
368 : /**
369 : * Clear sideset information along a stitched mesh interface
370 : * @param sideset_id A sideset on one side of the stitched mesh interface
371 : * @param other_sideset_id The sideset on the other side of the stitched mesh interface
372 : * @param clear_nodeset_data Whether to clear boundary information for the nodes along
373 : * the stitched mesh interface
374 : */
375 : void clear_stitched_boundary_side_ids (boundary_id_type sideset_id,
376 : boundary_id_type other_sideset_id,
377 : bool clear_nodeset_data = false);
378 :
379 : /**
380 : * Removes all entities (nodes, sides, edges, shellfaces) with boundary
381 : * id \p id from their respective containers and erases any record of
382 : * \p id's existence from the BoundaryInfo object. That is, after
383 : * calling remove_id(), \p id will no longer be in the sets returned by
384 : * get_boundary_ids(), get_side_boundary_ids(), etc., and will not
385 : * be in the bc_id_list vector returned by build_side_list(), etc.
386 : *
387 : * Set the \p global parameter to true if this is being called for
388 : * all processes in the object's communicator, in which case we will
389 : * remove the id from the global boundary ID container
390 : */
391 : void remove_id (boundary_id_type id, bool global = false);
392 :
393 : /**
394 : * Removes all sides with boundary id \p id from the BoundaryInfo
395 : * object, removes it from the set of side boundary ids, and removes
396 : * it from the set of boundary ids if no other boundary type uses it.
397 : *
398 : * Set the \p global parameter to true if this is being called for
399 : * all processes in the object's communicator, in which case we will
400 : * remove the id from the global boundary ID container
401 : */
402 : void remove_side_id (boundary_id_type id, bool global = false);
403 :
404 : /**
405 : * Removes all edges with boundary id \p id from the BoundaryInfo
406 : * object, removes it from the set of edge boundary ids, and removes
407 : * it from the set of boundary ids if no other boundary type uses it.
408 : *
409 : * Set the \p global parameter to true if this is being called for
410 : * all processes in the object's communicator, in which case we will
411 : * remove the id from the global boundary ID container
412 : */
413 : void remove_edge_id (boundary_id_type id, bool global = false);
414 :
415 : /**
416 : * Removes all shellfaces with boundary id \p id from the
417 : * BoundaryInfo object, removes it from the set of shellface
418 : * boundary ids, and removes it from the set of boundary ids if no
419 : * other boundary type uses it.
420 : *
421 : * Set the \p global parameter to true if this is being called for
422 : * all processes in the object's communicator, in which case we will
423 : * remove the id from the global boundary ID container
424 : */
425 : void remove_shellface_id (boundary_id_type id, bool global = false);
426 :
427 : /**
428 : * Removes all nodes with boundary id \p id from the BoundaryInfo
429 : * object, removes it from the set of node boundary ids, and removes
430 : * it from the set of boundary ids if no other boundary type uses it.
431 : *
432 : * Set the \p global parameter to true if this is being called for
433 : * all processes in the object's communicator, in which case we will
434 : * remove the id from the global boundary ID container
435 : */
436 : void remove_node_id (boundary_id_type id, bool global = false);
437 :
438 : /**
439 : * Changes all entities (nodes, sides, edges, shellfaces) with boundary
440 : * id \p old_id to instead be labeled by boundary id \p new_id.
441 : */
442 : void renumber_id (boundary_id_type old_id, boundary_id_type new_id);
443 :
444 : /**
445 : * Changes all sides with boundary id \p old_id to instead be
446 : * labeled by boundary id \p new_id.
447 : */
448 : void renumber_side_id (boundary_id_type old_id, boundary_id_type new_id);
449 :
450 : /**
451 : * Changes all edges with boundary id \p old_id to instead be
452 : * labeled by boundary id \p new_id.
453 : */
454 : void renumber_edge_id (boundary_id_type old_id, boundary_id_type new_id);
455 :
456 : /**
457 : * Changes all shellfaces with boundary id \p old_id to instead be
458 : * labeled by boundary id \p new_id.
459 : */
460 : void renumber_shellface_id (boundary_id_type old_id, boundary_id_type new_id);
461 :
462 : /**
463 : * Changes all nodes with boundary id \p old_id to instead be
464 : * labeled by boundary id \p new_id.
465 : */
466 : void renumber_node_id (boundary_id_type old_id, boundary_id_type new_id);
467 :
468 : /**
469 : * \returns The number of user-specified boundary ids on the
470 : * semilocal part of the mesh.
471 : *
472 : * \note DistributedMesh users may need to compare boundary_ids sets
473 : * via inter-processor communication.
474 : */
475 2 : std::size_t n_boundary_ids () const { return _boundary_ids.size(); }
476 :
477 : /**
478 : * \returns \p true if \p node is associated with boundary \p id.
479 : */
480 : bool has_boundary_id (const Node * const node,
481 : const boundary_id_type id) const;
482 :
483 : /**
484 : * Fills a user-provided std::vector with the boundary ids associated
485 : * with \p Node \p node.
486 : */
487 : void boundary_ids (const Node * node,
488 : std::vector<boundary_id_type> & vec_to_fill) const;
489 :
490 : /**
491 : * \returns The number of boundary ids associated with \p Node \p node.
492 : */
493 : unsigned int n_boundary_ids (const Node * node) const;
494 :
495 : /**
496 : * \returns The number of boundary ids associated with the \p edge
497 : * edge of element \p elem.
498 : *
499 : * \note Edge-based boundary IDs should only be used in 3D.
500 : */
501 : unsigned int n_edge_boundary_ids (const Elem * const elem,
502 : const unsigned short int edge) const;
503 :
504 : /**
505 : * \returns The list of boundary ids associated with the \p edge edge of
506 : * element \p elem.
507 : *
508 : * \note Edge-based boundary IDs should only be used in 3D.
509 : */
510 : void edge_boundary_ids (const Elem * const elem,
511 : const unsigned short int edge,
512 : std::vector<boundary_id_type> & vec_to_fill) const;
513 :
514 : /**
515 : * \returns The list of raw boundary ids associated with the \p edge
516 : * edge of element \p elem.
517 : *
518 : * These ids are "raw" because they exclude ids which are implicit,
519 : * such as a child's inheritance of its ancestors' boundary id.
520 : *
521 : * \note Edge-based boundary IDs should only be used in 3D.
522 : */
523 : void raw_edge_boundary_ids (const Elem * const elem,
524 : const unsigned short int edge,
525 : std::vector<boundary_id_type> & vec_to_fill) const;
526 :
527 : /**
528 : * \returns The number of boundary ids associated with the specified
529 : * shell face of element \p elem.
530 : *
531 : * \note This is only relevant for shell elements.
532 : */
533 : unsigned int n_shellface_boundary_ids (const Elem * const elem,
534 : const unsigned short int shellface) const;
535 :
536 : /**
537 : * \returns The list of boundary ids associated with the specified shell face
538 : * of element \p elem.
539 : *
540 : * \note This is only relevant for shell elements.
541 : */
542 : void shellface_boundary_ids (const Elem * const elem,
543 : const unsigned short int shellface,
544 : std::vector<boundary_id_type> & vec_to_fill) const;
545 :
546 : /**
547 : * \returns The list of raw boundary ids associated with the
548 : * specified shell face of element \p elem.
549 : *
550 : * These ids are "raw" because they exclude ids which are implicit,
551 : * such as a child's inheritance of its ancestors' boundary id.
552 : *
553 : * \note This is only relevant for shell elements.
554 : */
555 : void raw_shellface_boundary_ids (const Elem * const elem,
556 : const unsigned short int shellface,
557 : std::vector<boundary_id_type> & vec_to_fill) const;
558 :
559 : /**
560 : * \returns \p true if side \p side of Elem \p elem is associated
561 : * with \p id.
562 : */
563 : bool has_boundary_id (const Elem * const elem,
564 : const unsigned short int side,
565 : const boundary_id_type id) const;
566 :
567 : /**
568 : * \returns The number of boundary ids associated with the \p side
569 : * side of element \p elem.
570 : */
571 : unsigned int n_boundary_ids (const Elem * const elem,
572 : const unsigned short int side) const;
573 :
574 : /**
575 : * \returns The number of raw (excludes ancestors) boundary ids associated with the \p side
576 : * side of element \p elem.
577 : */
578 : unsigned int n_raw_boundary_ids (const Elem * const elem,
579 : const unsigned short int side) const;
580 :
581 : /**
582 : * \returns The list of boundary ids associated with any of the sides of
583 : * element \p elem. Indexed by sides.
584 : */
585 : void side_boundary_ids (const Elem * const elem,
586 : std::vector<std::vector<boundary_id_type>> & vec_to_fill) const;
587 :
588 : /**
589 : * \returns The list of boundary ids associated with the \p side side of
590 : * element \p elem.
591 : */
592 : void boundary_ids (const Elem * const elem,
593 : const unsigned short int side,
594 : std::vector<boundary_id_type> & vec_to_fill) const;
595 :
596 : /**
597 : * \returns The list of raw boundary ids associated with the \p side
598 : * side of element \p elem.
599 : *
600 : * These ids are "raw" because they exclude ids which are implicit,
601 : * such as a child's inheritance of its ancestors' boundary id.
602 : */
603 : void raw_boundary_ids (const Elem * const elem,
604 : const unsigned short int side,
605 : std::vector<boundary_id_type> & vec_to_fill) const;
606 :
607 : /*
608 : * Copy boundary ids associated with old_elem (but not its nodes)
609 : * from old_boundary_info (which may be this) into this boundary
610 : * info, associating them with new_elem.
611 : */
612 : void copy_boundary_ids (const BoundaryInfo & old_boundary_info,
613 : const Elem * const old_elem,
614 : const Elem * const new_elem);
615 :
616 : /**
617 : * \returns A side of element \p elem whose associated boundary id is
618 : * \p boundary_id if such a side exists, and \p invalid_uint otherwise.
619 : *
620 : * \note If multiple sides of \p elem have the same id, only the lowest numbered
621 : * such side is returned.
622 : */
623 : unsigned int side_with_boundary_id(const Elem * const elem,
624 : const boundary_id_type boundary_id) const;
625 :
626 : /**
627 : * \returns All sides of element \p elem whose associated boundary id is
628 : * \p boundary_id
629 : */
630 : std::vector<unsigned int>
631 : sides_with_boundary_id(const Elem * const elem,
632 : const boundary_id_type boundary_id) const;
633 :
634 : /**
635 : * Builds the list of unique node boundary ids.
636 : *
637 : * On a ReplicatedMesh this will be all ids; on a DistributedMesh
638 : * only ids on semilocal nodes will be included.
639 : */
640 : void build_node_boundary_ids(std::vector<boundary_id_type> & b_ids) const;
641 :
642 : /**
643 : * Builds the list of unique side boundary ids.
644 : *
645 : * On a ReplicatedMesh this will be all ids; on a DistributedMesh
646 : * only ids on sides of semilocal elements will be included.
647 : */
648 : void build_side_boundary_ids(std::vector<boundary_id_type> & b_ids) const;
649 :
650 : /**
651 : * Builds the list of unique shellface boundary ids.
652 : *
653 : * On a ReplicatedMesh this will be all ids; on a DistributedMesh
654 : * only ids on shellfaces of semilocal elements will be included.
655 : */
656 : void build_shellface_boundary_ids(std::vector<boundary_id_type> & b_ids) const;
657 :
658 : #ifdef LIBMESH_ENABLE_AMR
659 : /**
660 : * Update parent's boundary id list so that this information is consistent with
661 : * its children
662 : *
663 : * This is useful when `_children_on_boundary = true`, and is used when the
664 : * element is about to get coarsened i.e., in MeshRefinement::_coarsen_elements()
665 : *
666 : * Specifically, when we coarsen an element whose children have different boundary ids.
667 : * In such scenarios, the parent will inherit the children's boundaries if at
668 : * least 50% them own a boundary while sharing the side of the parent.
669 : */
670 : void transfer_boundary_ids_from_children(const Elem * const parent);
671 : #endif
672 :
673 : /**
674 : * \returns The number of element-side-based boundary conditions.
675 : *
676 : * This will be the correct global count even on a distributed mesh.
677 : */
678 : std::size_t n_boundary_conds () const;
679 :
680 : /**
681 : * \returns The number of edge-based boundary conditions.
682 : * Edge-based boundary IDs should only be used in 3D.
683 : *
684 : * This will be the correct global count even on a distributed mesh.
685 : */
686 : std::size_t n_edge_conds () const;
687 :
688 : /**
689 : * \returns The number of shellface-based boundary conditions.
690 : * This is only relevant on shell elements.
691 : *
692 : * This will be the correct global count even on a distributed mesh.
693 : */
694 : std::size_t n_shellface_conds () const;
695 :
696 : /**
697 : * \returns The number of node-based boundary conditions.
698 : *
699 : * This will be the correct global count even on a distributed mesh.
700 : */
701 : std::size_t n_nodeset_conds () const;
702 :
703 : /**
704 : * Creates a list of nodes and ids for those nodes.
705 : *
706 : * On a ReplicatedMesh this will include all nodes; on a
707 : * DistributedMesh only semilocal nodes will be included.
708 : *
709 : * \deprecated Use the version of build_node_list() below that
710 : * returns a std::vector of tuples instead.
711 : */
712 : #ifdef LIBMESH_ENABLE_DEPRECATED
713 : void build_node_list (std::vector<dof_id_type> & node_id_list,
714 : std::vector<boundary_id_type> & bc_id_list) const;
715 : #endif
716 :
717 : /**
718 : * As above, but the library creates and fills in a vector of
719 : * (node-id, bc-id) pairs and returns it to the user, taking
720 : * advantage of guaranteed RVO. Note: we could use std::pairs for
721 : * this, but for consistency with the other build_XYZ_list
722 : * functions, we're using tuples.
723 : *
724 : * The "sort_by" parameter controls how the resulting list of tuples
725 : * is sorted. It is possible (but not recommended) to choose
726 : * UNSORTED, since in that case the resulting vectors will
727 : * potentially be in different orders on different procs.
728 : */
729 : typedef std::tuple<dof_id_type, boundary_id_type> NodeBCTuple;
730 : enum class NodeBCTupleSortBy {NODE_ID, BOUNDARY_ID, UNSORTED};
731 : std::vector<NodeBCTuple> build_node_list(NodeBCTupleSortBy sort_by = NodeBCTupleSortBy::NODE_ID) const;
732 :
733 : /**
734 : * Adds nodes with boundary ids based on the side's boundary
735 : * ids they are connected to.
736 : *
737 : * @param sideset_list sidesets to build nodesets from.
738 : * If empty (default), builds from all existing
739 : * sidesets
740 : */
741 : void build_node_list_from_side_list(const std::set<boundary_id_type> & sideset_list = {});
742 :
743 : /**
744 : * Adds sides to a sideset if every node on that side are in the same
745 : * sideset
746 : * @param nodeset_list nodesets to build sidesets from.
747 : * If empty (default), builds from all existing sidesets
748 : */
749 : void build_side_list_from_node_list(const std::set<boundary_id_type> & nodeset_list = {});
750 :
751 : /**
752 : * Creates a list of element numbers, sides, and ids for those sides.
753 : *
754 : * On a ReplicatedMesh this will include all sides; on a
755 : * DistributedMesh only sides of semilocal elements will be
756 : * included.
757 : *
758 : * \deprecated Use the version of build_side_list() below that
759 : * returns a std::vector of tuples instead.
760 : */
761 : #ifdef LIBMESH_ENABLE_DEPRECATED
762 : void build_side_list (std::vector<dof_id_type> & element_id_list,
763 : std::vector<unsigned short int> & side_list,
764 : std::vector<boundary_id_type> & bc_id_list) const;
765 : #endif
766 :
767 : /**
768 : * As above, but the library creates and fills in a vector of
769 : * (elem-id, side-id, bc-id) triplets and returns it to the user,
770 : * taking advantage of guaranteed RVO.
771 : *
772 : * The returned vector is sorted by element id by default, but this
773 : * can be changed by passing SIDE_ID, BOUNDARY_ID, or UNSORTED to
774 : * this function. Note: choosing UNSORTED is not recommended since
775 : * the resulting list will potentially be in different orders on
776 : * different processors when running in parallel.
777 : */
778 : typedef std::tuple<dof_id_type, unsigned short int, boundary_id_type> BCTuple;
779 : enum class BCTupleSortBy {ELEM_ID, SIDE_ID, BOUNDARY_ID, UNSORTED};
780 : std::vector<BCTuple> build_side_list(BCTupleSortBy sort_by = BCTupleSortBy::ELEM_ID) const;
781 :
782 : /**
783 : * Creates a list of active element numbers, sides, and ids for those sides.
784 : *
785 : * On a ReplicatedMesh this will include all sides; on a
786 : * DistributedMesh only sides of semilocal elements will be
787 : * included.
788 : *
789 : * \deprecated Use the version of build_active_side_list() below
790 : * that returns a std::vector of tuples instead.
791 : */
792 : #ifdef LIBMESH_ENABLE_DEPRECATED
793 : void build_active_side_list (std::vector<dof_id_type> & element_id_list,
794 : std::vector<unsigned short int> & side_list,
795 : std::vector<boundary_id_type> & bc_id_list) const;
796 : #endif
797 :
798 : /**
799 : * As above, but the library creates and fills in a vector of
800 : * (elem-id, side-id, bc-id) triplets and returns it to the user,
801 : * taking advantage of guaranteed RVO.
802 : */
803 : std::vector<BCTuple> build_active_side_list () const;
804 :
805 : /**
806 : * Creates a list of element numbers, edges, and boundary ids for those edges.
807 : *
808 : * On a ReplicatedMesh this will include all edges; on a
809 : * DistributedMesh only edges of semilocal elements will be
810 : * included.
811 : *
812 : * \deprecated Use the version of build_edge_list() below
813 : * that returns a std::vector of tuples instead.
814 : */
815 : #ifdef LIBMESH_ENABLE_DEPRECATED
816 : void build_edge_list (std::vector<dof_id_type> & element_id_list,
817 : std::vector<unsigned short int> & edge_list,
818 : std::vector<boundary_id_type> & bc_id_list) const;
819 : #endif
820 :
821 : /**
822 : * As above, but the library creates and fills in a vector of
823 : * (elem-id, side-id, bc-id) triplets and returns it to the user,
824 : * taking advantage of guaranteed RVO.
825 : */
826 : std::vector<BCTuple> build_edge_list() const;
827 :
828 : /**
829 : * Creates a list of element numbers, shellfaces, and boundary ids for those shellfaces.
830 : *
831 : * On a ReplicatedMesh this will include all shellfaces; on a
832 : * DistributedMesh only shellfaces of semilocal elements will be
833 : * included.
834 : *
835 : * \deprecated Use the version of build_shellface_list() below
836 : * that returns a std::vector of tuples instead.
837 : */
838 : #ifdef LIBMESH_ENABLE_DEPRECATED
839 : void build_shellface_list (std::vector<dof_id_type> & element_id_list,
840 : std::vector<unsigned short int> & shellface_list,
841 : std::vector<boundary_id_type> & bc_id_list) const;
842 : #endif
843 :
844 : /**
845 : * As above, but the library creates and fills in a vector of
846 : * (elem-id, side-id, bc-id) triplets and returns it to the user,
847 : * taking advantage of guaranteed RVO.
848 : */
849 : std::vector<BCTuple> build_shellface_list() const;
850 :
851 : /**
852 : * Synchronize the boundary element side and node across processors.
853 : * This function is needed when boundary info is changed by adding or removing
854 : * sides on the fly.
855 : * Note: if the side of a ghost element is changed, then you would need to do
856 : * do parallel push (see e.g., timpi/parallel_sync.h) and then sync.
857 : */
858 : void parallel_sync_side_ids();
859 : void parallel_sync_node_ids();
860 :
861 : /**
862 : * \returns A set of the boundary ids which exist on semilocal parts
863 : * of the mesh.
864 : *
865 : * Code that wishes to access boundary ids on all parts of the mesh, including
866 : * non-local parts, should call \p get_global_boundary_ids
867 : */
868 584 : const std::set<boundary_id_type> & get_boundary_ids () const
869 584 : { return _boundary_ids; }
870 :
871 : /**
872 : * \returns A set of the boundary ids which exist globally
873 : * on the mesh. Relies on the mesh being prepared
874 : */
875 : const std::set<boundary_id_type> & get_global_boundary_ids () const;
876 :
877 : /**
878 : * \returns A reference to the set of the boundary IDs specified on
879 : * sides of semilocal mesh elements.
880 : */
881 420 : const std::set<boundary_id_type> & get_side_boundary_ids () const
882 420 : { return _side_boundary_ids; }
883 :
884 : /**
885 : * \returns A reference to the set of all boundary IDs specified on
886 : * edges of semilocal mesh elements.
887 : *
888 : * \note Edge-based boundary IDs should only be used in 3D.
889 : */
890 887 : const std::set<boundary_id_type> & get_edge_boundary_ids () const
891 887 : { return _edge_boundary_ids; }
892 :
893 : /**
894 : * \returns A reference to the set of all boundary IDs specified on
895 : * shell faces.
896 : *
897 : * \note This is only relevant on shell elements.
898 : */
899 : const std::set<boundary_id_type> & get_shellface_boundary_ids () const
900 : { return _shellface_boundary_ids; }
901 :
902 : /**
903 : * \returns A reference to the set of all boundary IDs specified on
904 : * semilocal mesh nodes.
905 : */
906 1056 : const std::set<boundary_id_type> & get_node_boundary_ids () const
907 1056 : { return _node_boundary_ids; }
908 :
909 :
910 : /**
911 : * Prints the boundary information data structure.
912 : */
913 : void print_info (std::ostream & out_stream=libMesh::out) const;
914 :
915 : /**
916 : * Prints a summary of the boundary information.
917 : */
918 : void print_summary (std::ostream & out_stream=libMesh::out) const;
919 :
920 : /**
921 : * \returns A reference for getting an optional name for a sideset.
922 : */
923 : const std::string & get_sideset_name(boundary_id_type id) const;
924 :
925 : /**
926 : * \returns A writable reference for setting an optional
927 : * name for a sideset.
928 : */
929 : std::string & sideset_name(boundary_id_type id);
930 :
931 : /**
932 : * \returns A reference for getting an optional name for a nodeset.
933 : */
934 : const std::string & get_nodeset_name(boundary_id_type id) const;
935 :
936 : /**
937 : * \returns A writable reference for setting an optional
938 : * name for a nodeset.
939 : */
940 : std::string & nodeset_name(boundary_id_type id);
941 :
942 : /**
943 : * \returns A const reference to an optional edgeset name.
944 : */
945 : const std::string & get_edgeset_name(boundary_id_type id) const;
946 :
947 : /**
948 : * \returns A writable reference to an optional edgeset name.
949 : */
950 : std::string & edgeset_name(boundary_id_type id);
951 :
952 : /**
953 : * \returns The id of the named boundary if it exists, \p invalid_id
954 : * otherwise.
955 : */
956 : boundary_id_type get_id_by_name(std::string_view name) const;
957 :
958 : /**
959 : * \returns A writable reference to the sideset name map.
960 : */
961 472 : std::map<boundary_id_type, std::string> & set_sideset_name_map ()
962 14184 : { return _ss_id_to_name; }
963 524 : const std::map<boundary_id_type, std::string> & get_sideset_name_map () const
964 1576 : { return _ss_id_to_name; }
965 :
966 : /**
967 : * \returns A writable reference to the nodeset name map.
968 : */
969 408 : std::map<boundary_id_type, std::string> & set_nodeset_name_map ()
970 12052 : { return _ns_id_to_name; }
971 508 : const std::map<boundary_id_type, std::string> & get_nodeset_name_map () const
972 1116 : { return _ns_id_to_name; }
973 :
974 : /**
975 : * \returns Writable/const reference to the edgeset name map.
976 : */
977 48 : std::map<boundary_id_type, std::string> & set_edgeset_name_map ()
978 48 : { return _es_id_to_name; }
979 56 : const std::map<boundary_id_type, std::string> & get_edgeset_name_map () const
980 332 : { return _es_id_to_name; }
981 :
982 : /**
983 : * Number used for internal use. This is the return value
984 : * if a boundary condition is not specified.
985 : */
986 : static const boundary_id_type invalid_id;
987 :
988 : /**
989 : * \returns A const reference to the nodeset map.
990 : */
991 8 : const std::multimap<const Node *, boundary_id_type> & get_nodeset_map () const
992 8 : { return _boundary_node_id; }
993 :
994 : /**
995 : * \returns A const reference to the edgeset map.
996 : */
997 8 : const std::multimap<const Elem *, std::pair<unsigned short int, boundary_id_type>> & get_edgeset_map () const
998 8 : { return _boundary_edge_id; }
999 :
1000 : /**
1001 : * \returns A const reference to the sideset map.
1002 : */
1003 8 : const std::multimap<const Elem *, std::pair<unsigned short int, boundary_id_type>> & get_sideset_map() const
1004 8 : { return _boundary_side_id; }
1005 :
1006 : /**
1007 : * \returns Whether or not there may be child elements directly assigned boundary sides
1008 : */
1009 1296 : bool is_children_on_boundary_side() const
1010 4932084 : { return _children_on_boundary; }
1011 :
1012 : /**
1013 : * Whether or not to allow directly setting boundary sides on child elements
1014 : */
1015 : void allow_children_on_boundary_side(const bool children_on_boundary)
1016 : { _children_on_boundary = children_on_boundary; }
1017 :
1018 : private:
1019 :
1020 : /**
1021 : * Helper method for ensuring that our multimaps don't contain
1022 : * entries with duplicate keys *and* values. Probably should have
1023 : * picked a different data structure there, and also not given users
1024 : * an accessor with raw access to it...
1025 : */
1026 : void libmesh_assert_valid_multimaps() const;
1027 :
1028 : /**
1029 : * Helper method for finding consistent maps of interior to boundary
1030 : * dof_object ids. Either node_id_map or side_id_map can be nullptr,
1031 : * in which case it will not be filled.
1032 : */
1033 : void _find_id_maps (const std::set<boundary_id_type> & requested_boundary_ids,
1034 : dof_id_type first_free_node_id,
1035 : std::map<dof_id_type, dof_id_type> * node_id_map,
1036 : dof_id_type first_free_elem_id,
1037 : std::map<std::pair<dof_id_type, unsigned char>, dof_id_type> * side_id_map,
1038 : const std::set<subdomain_id_type> & subdomains_relative_to);
1039 :
1040 : /**
1041 : * A pointer to the Mesh this boundary info pertains to.
1042 : */
1043 : MeshBase * _mesh;
1044 :
1045 : /**
1046 : * Data structure that maps nodes in the mesh
1047 : * to boundary ids.
1048 : */
1049 : std::multimap<const Node *,
1050 : boundary_id_type> _boundary_node_id;
1051 :
1052 : /**
1053 : * Data structure that maps edges of elements
1054 : * to boundary ids. This is only relevant in 3D.
1055 : */
1056 : std::multimap<const Elem *,
1057 : std::pair<unsigned short int, boundary_id_type>>
1058 : _boundary_edge_id;
1059 :
1060 : /**
1061 : * Data structure that maps faces of shell elements
1062 : * to boundary ids. This is only relevant for shell elements.
1063 : */
1064 : std::multimap<const Elem *,
1065 : std::pair<unsigned short int, boundary_id_type>>
1066 : _boundary_shellface_id;
1067 :
1068 : /**
1069 : * Data structure that maps sides of elements
1070 : * to boundary ids.
1071 : */
1072 : std::multimap<const Elem *,
1073 : std::pair<unsigned short int, boundary_id_type>>
1074 : _boundary_side_id;
1075 :
1076 : /*
1077 : * Whether or not children elements are associated with any boundary
1078 : * It is false by default. The flag will be turned on if `add_side`
1079 : * function is called with a child element
1080 : */
1081 : bool _children_on_boundary;
1082 :
1083 : /**
1084 : * A collection of user-specified boundary ids for sides, edges, nodes,
1085 : * and shell faces.
1086 : * See _side_boundary_ids, _edge_boundary_ids, _node_boundary_ids, and
1087 : * _shellface_boundary_ids for sets containing IDs for only sides, edges,
1088 : * nodes, and shell faces, respectively.
1089 : *
1090 : * This only contains information related to this process's local and ghosted elements
1091 : */
1092 : std::set<boundary_id_type> _boundary_ids;
1093 :
1094 : /**
1095 : * A collection of user-specified boundary ids for sides, edges, nodes,
1096 : * and shell faces.
1097 : * See _side_boundary_ids, _edge_boundary_ids, _node_boundary_ids, and
1098 : * _shellface_boundary_ids for sets containing IDs for only sides, edges,
1099 : * nodes, and shell faces, respectively.
1100 : *
1101 : * Unlike \p _boundary_ids, this member should contain boundary ids from across
1102 : * all processors after the mesh is prepared
1103 : */
1104 : std::set<boundary_id_type> _global_boundary_ids;
1105 :
1106 : /**
1107 : * Set of user-specified boundary IDs for sides *only*.
1108 : *
1109 : * \note \p _boundary_ids is the union of this set, \p
1110 : * _edge_boundary_ids, \p _node_boundary_ids, and \p
1111 : * _shellface_boundary_ids.
1112 : *
1113 : * This only contains information related to this process's local and ghosted elements
1114 : */
1115 : std::set<boundary_id_type> _side_boundary_ids;
1116 :
1117 : /**
1118 : * Set of user-specified boundary IDs for edges *only*.
1119 : * This is only relevant in 3D.
1120 : *
1121 : * \note \p _boundary_ids is the union of this set, \p _side_boundary_ids,
1122 : * \p _node_boundary_ids, and \p _shellface_boundary_ids.
1123 : *
1124 : * This only contains information related to this process's local and ghosted elements
1125 : */
1126 : std::set<boundary_id_type> _edge_boundary_ids;
1127 :
1128 : /**
1129 : * Set of user-specified boundary IDs for nodes *only*.
1130 : *
1131 : * \note \p _boundary_ids is the union of this set, \p
1132 : * _edge_boundary_ids, \p _side_boundary_ids, and \p
1133 : * _shellface_boundary_ids.
1134 : *
1135 : * This only contains information related to this process's local and ghosted elements
1136 : */
1137 : std::set<boundary_id_type> _node_boundary_ids;
1138 :
1139 : /**
1140 : * Set of user-specified boundary IDs for shellfaces *only*.
1141 : * This is only relevant for shell elements.
1142 : *
1143 : * \note \p _boundary_ids is the union of this set, \p
1144 : * _side_boundary_ids, \p _edge_boundary_ids, and \p
1145 : * _node_boundary_ids.
1146 : *
1147 : * This only contains information related to this process's local and ghosted elements
1148 : */
1149 : std::set<boundary_id_type> _shellface_boundary_ids;
1150 :
1151 : /**
1152 : * This structure maintains the mapping of named side sets
1153 : * for file formats (Exodus, Gmsh) that support this.
1154 : *
1155 : * This data is global in nature, meaning it should be an aggregate of information across
1156 : * processors
1157 : */
1158 : std::map<boundary_id_type, std::string> _ss_id_to_name;
1159 :
1160 : /**
1161 : * This structure maintains the mapping of named node sets
1162 : * for file formats (Exodus, Gmsh) that support this.
1163 : *
1164 : * This data is global in nature, meaning it should be an aggregate of information across
1165 : * processors
1166 : */
1167 : std::map<boundary_id_type, std::string> _ns_id_to_name;
1168 :
1169 : /**
1170 : * This structure maintains the mapping of named edge sets
1171 : * for file formats (Exodus, Gmsh) that support this.
1172 : *
1173 : * This data is global in nature, meaning it should be an aggregate of information across
1174 : * processors
1175 : */
1176 : std::map<boundary_id_type, std::string> _es_id_to_name;
1177 : };
1178 :
1179 : } // namespace libMesh
1180 :
1181 : #endif // LIBMESH_BOUNDARY_INFO_H
|