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_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 41828 : 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 14302 : 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 element sides with boundary ids in the
185 : * \p requested_boundary_ids set are considered for addition.
186 : *
187 : * If \p new_subdomain_ids is empty, newly created elements retain the
188 : * default subdomain id. If it contains a single entry, all new elements
189 : * are assigned that subdomain id. If its size equals
190 : * \p requested_boundary_ids.size(), new elements are assigned subdomain
191 : * ids in one-to-one correspondence with the boundary ids (iterated in
192 : * sorted order).
193 : */
194 : void add_elements (const std::set<boundary_id_type> & requested_boundary_ids,
195 : UnstructuredMesh & boundary_mesh,
196 : bool store_parent_side_ids = false,
197 : const std::vector<subdomain_id_type> & new_subdomain_ids = {});
198 :
199 : /**
200 : * Same as the add_elements() function above, but takes a set of
201 : * subdomains for which the sides must be relative to. This is
202 : * necessary to avoid double-adding sides of internal sidesets to
203 : * the BoundaryMesh.
204 : */
205 : void add_elements(const std::set<boundary_id_type> & requested_boundary_ids,
206 : UnstructuredMesh & boundary_mesh,
207 : const std::set<subdomain_id_type> & subdomains_relative_to,
208 : bool store_parent_side_ids = false,
209 : const std::vector<subdomain_id_type> & new_subdomain_ids = {});
210 :
211 : /**
212 : * Add \p Node \p node with boundary id \p id to the boundary
213 : * information data structures.
214 : */
215 : void add_node (const Node * node,
216 : const boundary_id_type id);
217 :
218 : /**
219 : * Add node number \p node with boundary id \p id to the boundary
220 : * information data structures.
221 : */
222 : void add_node (const dof_id_type node,
223 : const boundary_id_type id);
224 :
225 : /**
226 : * Add \p Node \p node with boundary ids \p ids to the boundary
227 : * information data structure.
228 : */
229 : void add_node (const Node * node,
230 : const std::vector<boundary_id_type> & ids);
231 :
232 : /**
233 : * Clears all the boundary information from all of the nodes in the mesh
234 : */
235 : void clear_boundary_node_ids();
236 :
237 : /**
238 : * Add edge \p edge of element number \p elem with boundary id \p id
239 : * to the boundary information data structure.
240 : * Edge-based boundary IDs should only be used in 3D.
241 : */
242 : void add_edge (const dof_id_type elem,
243 : const unsigned short int edge,
244 : const boundary_id_type id);
245 :
246 : /**
247 : * Add edge \p edge of element \p elem with boundary id \p id
248 : * to the boundary information data structure.
249 : * Edge-based boundary IDs should only be used in 3D.
250 : */
251 : void add_edge (const Elem * elem,
252 : const unsigned short int edge,
253 : const boundary_id_type id);
254 :
255 : /**
256 : * Add edge \p edge of element \p elem with boundary ids \p ids
257 : * to the boundary information data structure.
258 : * Edge-based boundary IDs should only be used in 3D.
259 : */
260 : void add_edge (const Elem * elem,
261 : const unsigned short int edge,
262 : const std::vector<boundary_id_type> & ids);
263 :
264 : /**
265 : * Add shell face \p shellface of element number \p elem with boundary id \p id
266 : * to the boundary information data structure. This is only relevant for shell
267 : * elements.
268 : */
269 : void add_shellface (const dof_id_type elem,
270 : const unsigned short int shellface,
271 : const boundary_id_type id);
272 :
273 : /**
274 : * Add shell face \p shellface of element \p elem with boundary id \p id
275 : * to the boundary information data structure. This is only relevant for shell
276 : * elements.
277 : */
278 : void add_shellface (const Elem * elem,
279 : const unsigned short int shellface,
280 : const boundary_id_type id);
281 :
282 : /**
283 : * Add shell face \p shellface of element \p elem with boundary ids \p ids
284 : * to the boundary information data structure. This is only relevant for shell
285 : * elements.
286 : */
287 : void add_shellface (const Elem * elem,
288 : const unsigned short int shellface,
289 : const std::vector<boundary_id_type> & ids);
290 :
291 : /**
292 : * Add side \p side of element number \p elem with boundary id \p id
293 : * to the boundary information data structure.
294 : */
295 : void add_side (const dof_id_type elem,
296 : const unsigned short int side,
297 : const boundary_id_type id);
298 :
299 : /**
300 : * Add side \p side of element \p elem with boundary id \p id
301 : * to the boundary information data structure.
302 : */
303 : void add_side (const Elem * elem,
304 : const unsigned short int side,
305 : const boundary_id_type id);
306 :
307 : /**
308 : * Add side \p side of element \p elem with boundary ids \p ids
309 : * to the boundary information data structure.
310 : */
311 : void add_side (const Elem * elem,
312 : const unsigned short int side,
313 : const std::vector<boundary_id_type> & ids);
314 :
315 : /**
316 : * Removes the boundary conditions associated with node \p node,
317 : * if any exist.
318 : */
319 : void remove (const Node * node);
320 :
321 : /**
322 : * Removes the boundary conditions associated with element \p elem,
323 : * if any exist.
324 : */
325 : void remove (const Elem * elem);
326 :
327 : /**
328 : * Removes boundary id \p id from node \p node, if it exists.
329 : */
330 : void remove_node (const Node * node,
331 : const boundary_id_type id);
332 :
333 : /**
334 : * Removes all boundary conditions associated with edge \p edge of
335 : * element \p elem, if any exist.
336 : */
337 : void remove_edge (const Elem * elem,
338 : const unsigned short int edge);
339 :
340 : /**
341 : * Removes the boundary id \p id from edge \p edge of element \p
342 : * elem, if it exists.
343 : */
344 : void remove_edge (const Elem * elem,
345 : const unsigned short int edge,
346 : const boundary_id_type id);
347 :
348 : /**
349 : * Removes all boundary conditions associated with shell face
350 : * \p shellface of element \p elem, if any exist.
351 : */
352 : void remove_shellface (const Elem * elem,
353 : const unsigned short int shellface);
354 :
355 : /**
356 : * Removes all boundary conditions associated with shell face
357 : * \p shellface of element \p elem, if any exist.
358 : */
359 : void remove_shellface (const Elem * elem,
360 : const unsigned short int shellface,
361 : const boundary_id_type id);
362 :
363 : /**
364 : * Removes all boundary conditions associated with side \p side of
365 : * element \p elem, if any exist.
366 : */
367 : void remove_side (const Elem * elem,
368 : const unsigned short int side);
369 :
370 : /**
371 : * Removes the boundary id \p id from side \p side of element \p
372 : * elem, if it exists.
373 : */
374 : void remove_side (const Elem * elem,
375 : const unsigned short int side,
376 : const boundary_id_type id);
377 :
378 : /**
379 : * Clear sideset information along a stitched mesh interface
380 : * @param sideset_id A sideset on one side of the stitched mesh interface
381 : * @param other_sideset_id The sideset on the other side of the stitched mesh interface
382 : * @param clear_nodeset_data Whether to clear boundary information for the nodes along
383 : * the stitched mesh interface
384 : */
385 : void clear_stitched_boundary_side_ids (boundary_id_type sideset_id,
386 : boundary_id_type other_sideset_id,
387 : bool clear_nodeset_data = false);
388 :
389 : /**
390 : * Removes all entities (nodes, sides, edges, shellfaces) with boundary
391 : * id \p id from their respective containers and erases any record of
392 : * \p id's existence from the BoundaryInfo object. That is, after
393 : * calling remove_id(), \p id will no longer be in the sets returned by
394 : * get_boundary_ids(), get_side_boundary_ids(), etc., and will not
395 : * be in the bc_id_list vector returned by build_side_list(), etc.
396 : *
397 : * Set the \p global parameter to true if this is being called for
398 : * all processes in the object's communicator, in which case we will
399 : * remove the id from the global boundary ID container
400 : */
401 : void remove_id (boundary_id_type id, bool global = false);
402 :
403 : /**
404 : * Removes all sides with boundary id \p id from the BoundaryInfo
405 : * object, removes it from the set of side boundary ids, and removes
406 : * it from the set of boundary ids if no other boundary type uses it.
407 : *
408 : * Set the \p global parameter to true if this is being called for
409 : * all processes in the object's communicator, in which case we will
410 : * remove the id from the global boundary ID container
411 : */
412 : void remove_side_id (boundary_id_type id, bool global = false);
413 :
414 : /**
415 : * Removes all edges with boundary id \p id from the BoundaryInfo
416 : * object, removes it from the set of edge boundary ids, and removes
417 : * it from the set of boundary ids if no other boundary type uses it.
418 : *
419 : * Set the \p global parameter to true if this is being called for
420 : * all processes in the object's communicator, in which case we will
421 : * remove the id from the global boundary ID container
422 : */
423 : void remove_edge_id (boundary_id_type id, bool global = false);
424 :
425 : /**
426 : * Removes all shellfaces with boundary id \p id from the
427 : * BoundaryInfo object, removes it from the set of shellface
428 : * boundary ids, and removes it from the set of boundary ids if no
429 : * other boundary type uses it.
430 : *
431 : * Set the \p global parameter to true if this is being called for
432 : * all processes in the object's communicator, in which case we will
433 : * remove the id from the global boundary ID container
434 : */
435 : void remove_shellface_id (boundary_id_type id, bool global = false);
436 :
437 : /**
438 : * Removes all nodes with boundary id \p id from the BoundaryInfo
439 : * object, removes it from the set of node boundary ids, and removes
440 : * it from the set of boundary ids if no other boundary type uses it.
441 : *
442 : * Set the \p global parameter to true if this is being called for
443 : * all processes in the object's communicator, in which case we will
444 : * remove the id from the global boundary ID container
445 : */
446 : void remove_node_id (boundary_id_type id, bool global = false);
447 :
448 : /**
449 : * Changes all entities (nodes, sides, edges, shellfaces) with boundary
450 : * id \p old_id to instead be labeled by boundary id \p new_id.
451 : */
452 : void renumber_id (boundary_id_type old_id, boundary_id_type new_id);
453 :
454 : /**
455 : * Changes all sides with boundary id \p old_id to instead be
456 : * labeled by boundary id \p new_id.
457 : */
458 : void renumber_side_id (boundary_id_type old_id, boundary_id_type new_id);
459 :
460 : /**
461 : * Changes all edges with boundary id \p old_id to instead be
462 : * labeled by boundary id \p new_id.
463 : */
464 : void renumber_edge_id (boundary_id_type old_id, boundary_id_type new_id);
465 :
466 : /**
467 : * Changes all shellfaces with boundary id \p old_id to instead be
468 : * labeled by boundary id \p new_id.
469 : */
470 : void renumber_shellface_id (boundary_id_type old_id, boundary_id_type new_id);
471 :
472 : /**
473 : * Changes all nodes with boundary id \p old_id to instead be
474 : * labeled by boundary id \p new_id.
475 : */
476 : void renumber_node_id (boundary_id_type old_id, boundary_id_type new_id);
477 :
478 : /**
479 : * \returns The number of user-specified boundary ids on the
480 : * semilocal part of the mesh.
481 : *
482 : * \note DistributedMesh users may need to compare boundary_ids sets
483 : * via inter-processor communication.
484 : */
485 2 : std::size_t n_boundary_ids () const { return _boundary_ids.size(); }
486 :
487 : /**
488 : * \returns \p true if \p node is associated with boundary \p id.
489 : */
490 : bool has_boundary_id (const Node * const node,
491 : const boundary_id_type id) const;
492 :
493 : /**
494 : * Fills a user-provided std::vector with the boundary ids associated
495 : * with \p Node \p node.
496 : */
497 : void boundary_ids (const Node * node,
498 : std::vector<boundary_id_type> & vec_to_fill) const;
499 :
500 : /**
501 : * \returns The number of boundary ids associated with \p Node \p node.
502 : */
503 : unsigned int n_boundary_ids (const Node * node) const;
504 :
505 : /**
506 : * \returns The number of boundary ids associated with the \p edge
507 : * edge of element \p elem.
508 : *
509 : * \note Edge-based boundary IDs should only be used in 3D.
510 : */
511 : unsigned int n_edge_boundary_ids (const Elem * const elem,
512 : const unsigned short int edge) const;
513 :
514 : /**
515 : * \returns The list of boundary ids associated with the \p edge edge of
516 : * element \p elem.
517 : *
518 : * \note Edge-based boundary IDs should only be used in 3D.
519 : */
520 : void edge_boundary_ids (const Elem * const elem,
521 : const unsigned short int edge,
522 : std::vector<boundary_id_type> & vec_to_fill) const;
523 :
524 : /**
525 : * \returns The list of raw boundary ids associated with the \p edge
526 : * edge of element \p elem.
527 : *
528 : * These ids are "raw" because they exclude ids which are implicit,
529 : * such as a child's inheritance of its ancestors' boundary id.
530 : *
531 : * \note Edge-based boundary IDs should only be used in 3D.
532 : */
533 : void raw_edge_boundary_ids (const Elem * const elem,
534 : const unsigned short int edge,
535 : std::vector<boundary_id_type> & vec_to_fill) const;
536 :
537 : /**
538 : * \returns The number of boundary ids associated with the specified
539 : * shell face of element \p elem.
540 : *
541 : * \note This is only relevant for shell elements.
542 : */
543 : unsigned int n_shellface_boundary_ids (const Elem * const elem,
544 : const unsigned short int shellface) const;
545 :
546 : /**
547 : * \returns The list of boundary ids associated with the specified shell face
548 : * of element \p elem.
549 : *
550 : * \note This is only relevant for shell elements.
551 : */
552 : void shellface_boundary_ids (const Elem * const elem,
553 : const unsigned short int shellface,
554 : std::vector<boundary_id_type> & vec_to_fill) const;
555 :
556 : /**
557 : * \returns The list of raw boundary ids associated with the
558 : * specified shell face of element \p elem.
559 : *
560 : * These ids are "raw" because they exclude ids which are implicit,
561 : * such as a child's inheritance of its ancestors' boundary id.
562 : *
563 : * \note This is only relevant for shell elements.
564 : */
565 : void raw_shellface_boundary_ids (const Elem * const elem,
566 : const unsigned short int shellface,
567 : std::vector<boundary_id_type> & vec_to_fill) const;
568 :
569 : /**
570 : * \returns \p true if side \p side of Elem \p elem is associated
571 : * with \p id.
572 : */
573 : bool has_boundary_id (const Elem * const elem,
574 : const unsigned short int side,
575 : const boundary_id_type id) const;
576 :
577 : /**
578 : * \returns The number of boundary ids associated with the \p side
579 : * side of element \p elem.
580 : */
581 : unsigned int n_boundary_ids (const Elem * const elem,
582 : const unsigned short int side) const;
583 :
584 : /**
585 : * \returns The number of raw (excludes ancestors) boundary ids associated with the \p side
586 : * side of element \p elem.
587 : */
588 : unsigned int n_raw_boundary_ids (const Elem * const elem,
589 : const unsigned short int side) const;
590 :
591 : /**
592 : * \returns The list of boundary ids associated with any of the sides of
593 : * element \p elem. Indexed by sides.
594 : */
595 : void side_boundary_ids (const Elem * const elem,
596 : std::vector<std::vector<boundary_id_type>> & vec_to_fill) const;
597 :
598 : /**
599 : * \returns The list of boundary ids associated with the \p side side of
600 : * element \p elem.
601 : */
602 : void boundary_ids (const Elem * const elem,
603 : const unsigned short int side,
604 : std::vector<boundary_id_type> & vec_to_fill) const;
605 :
606 : /**
607 : * \returns The list of raw boundary ids associated with the \p side
608 : * side of element \p elem.
609 : *
610 : * These ids are "raw" because they exclude ids which are implicit,
611 : * such as a child's inheritance of its ancestors' boundary id.
612 : */
613 : void raw_boundary_ids (const Elem * const elem,
614 : const unsigned short int side,
615 : std::vector<boundary_id_type> & vec_to_fill) const;
616 :
617 : /*
618 : * Copy boundary ids associated with old_elem (but not its nodes)
619 : * from old_boundary_info (which may be this) into this boundary
620 : * info, associating them with new_elem.
621 : */
622 : void copy_boundary_ids (const BoundaryInfo & old_boundary_info,
623 : const Elem * const old_elem,
624 : const Elem * const new_elem);
625 :
626 : /**
627 : * \returns A side of element \p elem whose associated boundary id is
628 : * \p boundary_id if such a side exists, and \p invalid_uint otherwise.
629 : *
630 : * \note If multiple sides of \p elem have the same id, only the lowest numbered
631 : * such side is returned.
632 : */
633 : unsigned int side_with_boundary_id(const Elem * const elem,
634 : const boundary_id_type boundary_id) const;
635 :
636 : /**
637 : * \returns All sides of element \p elem whose associated boundary id is
638 : * \p boundary_id
639 : */
640 : std::vector<unsigned int>
641 : sides_with_boundary_id(const Elem * const elem,
642 : const boundary_id_type boundary_id) const;
643 :
644 : /**
645 : * Builds the list of unique node boundary ids.
646 : *
647 : * On a ReplicatedMesh this will be all ids; on a DistributedMesh
648 : * only ids on semilocal nodes will be included.
649 : */
650 : void build_node_boundary_ids(std::vector<boundary_id_type> & b_ids) const;
651 :
652 : /**
653 : * Builds the list of unique side boundary ids.
654 : *
655 : * On a ReplicatedMesh this will be all ids; on a DistributedMesh
656 : * only ids on sides of semilocal elements will be included.
657 : */
658 : void build_side_boundary_ids(std::vector<boundary_id_type> & b_ids) const;
659 :
660 : /**
661 : * Builds the list of unique shellface boundary ids.
662 : *
663 : * On a ReplicatedMesh this will be all ids; on a DistributedMesh
664 : * only ids on shellfaces of semilocal elements will be included.
665 : */
666 : void build_shellface_boundary_ids(std::vector<boundary_id_type> & b_ids) const;
667 :
668 : #ifdef LIBMESH_ENABLE_AMR
669 : /**
670 : * Update parent's boundary id list so that this information is consistent with
671 : * its children
672 : *
673 : * This is useful when `_children_on_boundary = true`, and is used when the
674 : * element is about to get coarsened i.e., in MeshRefinement::_coarsen_elements()
675 : *
676 : * Specifically, when we coarsen an element whose children have different boundary ids.
677 : * In such scenarios, the parent will inherit the children's boundaries if at
678 : * least 50% them own a boundary while sharing the side of the parent.
679 : */
680 : void transfer_boundary_ids_from_children(const Elem * const parent);
681 : #endif
682 :
683 : /**
684 : * \returns The number of element-side-based boundary conditions.
685 : *
686 : * This will be the correct global count even on a distributed mesh.
687 : */
688 : std::size_t n_boundary_conds () const;
689 :
690 : /**
691 : * \returns The number of edge-based boundary conditions.
692 : * Edge-based boundary IDs should only be used in 3D.
693 : *
694 : * This will be the correct global count even on a distributed mesh.
695 : */
696 : std::size_t n_edge_conds () const;
697 :
698 : /**
699 : * \returns The number of shellface-based boundary conditions.
700 : * This is only relevant on shell elements.
701 : *
702 : * This will be the correct global count even on a distributed mesh.
703 : */
704 : std::size_t n_shellface_conds () const;
705 :
706 : /**
707 : * \returns The number of node-based boundary conditions.
708 : *
709 : * This will be the correct global count even on a distributed mesh.
710 : */
711 : std::size_t n_nodeset_conds () const;
712 :
713 : /**
714 : * Create a list of (node_id, boundary_id) tuples for all relevant
715 : * nodes. On a ReplicatedMesh this will include all nodes; on a
716 : * DistributedMesh only semilocal nodes will be included. Note: we
717 : * could use std::pairs for this, but for consistency with the other
718 : * build_XYZ_list functions, we're using tuples.
719 : *
720 : * The "sort_by" parameter controls how the resulting list of tuples
721 : * is sorted. It is possible (but not recommended) to choose
722 : * UNSORTED, since in that case the resulting vectors will
723 : * potentially be in different orders on different procs.
724 : */
725 : typedef std::tuple<dof_id_type, boundary_id_type> NodeBCTuple;
726 : enum class NodeBCTupleSortBy {NODE_ID, BOUNDARY_ID, UNSORTED};
727 : std::vector<NodeBCTuple> build_node_list(NodeBCTupleSortBy sort_by = NodeBCTupleSortBy::NODE_ID) const;
728 :
729 : /**
730 : * Adds nodes with boundary ids based on the side's boundary
731 : * ids they are connected to.
732 : *
733 : * @param sideset_list sidesets to build nodesets from.
734 : * If empty (default), builds from all existing
735 : * sidesets
736 : */
737 : void build_node_list_from_side_list(const std::set<boundary_id_type> & sideset_list = {});
738 :
739 : /**
740 : * Adds sides to a sideset if every node on that side are in the same
741 : * sideset
742 : * @param nodeset_list nodesets to build sidesets from.
743 : * If empty (default), builds from all existing sidesets
744 : */
745 : void build_side_list_from_node_list(const std::set<boundary_id_type> & nodeset_list = {});
746 :
747 : /**
748 : * Create a list of (element_id, side_id, boundary_id) tuples for
749 : * relevant sides. On a ReplicatedMesh this will include all sides;
750 : * on a DistributedMesh only sides of semilocal elements will be
751 : * included.
752 : *
753 : * The returned vector is sorted by element id by default, but this
754 : * can be changed by passing SIDE_ID, BOUNDARY_ID, or UNSORTED to
755 : * this function. Note: choosing UNSORTED is not recommended since
756 : * the resulting list will potentially be in different orders on
757 : * different processors when running in parallel.
758 : */
759 : typedef std::tuple<dof_id_type, unsigned short int, boundary_id_type> BCTuple;
760 : enum class BCTupleSortBy {ELEM_ID, SIDE_ID, BOUNDARY_ID, UNSORTED};
761 : std::vector<BCTuple> build_side_list(BCTupleSortBy sort_by = BCTupleSortBy::ELEM_ID) const;
762 :
763 : /**
764 : * Create a list of (element_id, side_id, boundary_id) tuples for
765 : * all relevant active sides. On a ReplicatedMesh this will include
766 : * all sides; on a DistributedMesh only sides of semilocal elements
767 : * will be included.
768 : */
769 : std::vector<BCTuple> build_active_side_list () const;
770 :
771 : /**
772 : * Create a list of (element_id, edge_id, boundary_id) tuples for
773 : * all relevant edges. On a ReplicatedMesh this will include all
774 : * edges; on a DistributedMesh only edges of semilocal elements will
775 : * be included.
776 : */
777 : std::vector<BCTuple> build_edge_list() const;
778 :
779 : /**
780 : * Create a list of (element_id, shellface_id, boundary_id) tuples
781 : * for all relevant shellfaces. On a ReplicatedMesh this will
782 : * include all shellfaces; on a DistributedMesh only shellfaces of
783 : * semilocal elements will be included.
784 : */
785 : std::vector<BCTuple> build_shellface_list() const;
786 :
787 : /**
788 : * Synchronize the boundary element side and node across processors.
789 : * This function is needed when boundary info is changed by adding or removing
790 : * sides on the fly.
791 : * Note: if the side of a ghost element is changed, then you would need to do
792 : * do parallel push (see e.g., timpi/parallel_sync.h) and then sync.
793 : */
794 : void parallel_sync_side_ids();
795 : void parallel_sync_node_ids();
796 :
797 : /**
798 : * \returns A set of the boundary ids which exist on semilocal parts
799 : * of the mesh.
800 : *
801 : * Code that wishes to access boundary ids on all parts of the mesh, including
802 : * non-local parts, should call \p get_global_boundary_ids
803 : */
804 584 : const std::set<boundary_id_type> & get_boundary_ids () const
805 584 : { return _boundary_ids; }
806 :
807 : /**
808 : * \returns A set of the boundary ids which exist globally
809 : * on the mesh. Relies on the mesh being prepared
810 : */
811 : const std::set<boundary_id_type> & get_global_boundary_ids () const;
812 :
813 : /**
814 : * \returns A reference to the set of the boundary IDs specified on
815 : * sides of semilocal mesh elements.
816 : */
817 420 : const std::set<boundary_id_type> & get_side_boundary_ids () const
818 420 : { return _side_boundary_ids; }
819 :
820 : /**
821 : * \returns A reference to the set of all boundary IDs specified on
822 : * edges of semilocal mesh elements.
823 : *
824 : * \note Edge-based boundary IDs should only be used in 3D.
825 : */
826 892 : const std::set<boundary_id_type> & get_edge_boundary_ids () const
827 892 : { return _edge_boundary_ids; }
828 :
829 : /**
830 : * \returns A reference to the set of all boundary IDs specified on
831 : * shell faces.
832 : *
833 : * \note This is only relevant on shell elements.
834 : */
835 : const std::set<boundary_id_type> & get_shellface_boundary_ids () const
836 : { return _shellface_boundary_ids; }
837 :
838 : /**
839 : * \returns A reference to the set of all boundary IDs specified on
840 : * semilocal mesh nodes.
841 : */
842 1056 : const std::set<boundary_id_type> & get_node_boundary_ids () const
843 1056 : { return _node_boundary_ids; }
844 :
845 :
846 : /**
847 : * Prints the boundary information data structure.
848 : */
849 : void print_info (std::ostream & out_stream=libMesh::out) const;
850 :
851 : /**
852 : * Prints a summary of the boundary information.
853 : */
854 : void print_summary (std::ostream & out_stream=libMesh::out) const;
855 :
856 : /**
857 : * \returns A reference for getting an optional name for a sideset.
858 : */
859 : const std::string & get_sideset_name(boundary_id_type id) const;
860 :
861 : /**
862 : * \returns A writable reference for setting an optional
863 : * name for a sideset.
864 : */
865 : std::string & sideset_name(boundary_id_type id);
866 :
867 : /**
868 : * \returns A reference for getting an optional name for a nodeset.
869 : */
870 : const std::string & get_nodeset_name(boundary_id_type id) const;
871 :
872 : /**
873 : * \returns A writable reference for setting an optional
874 : * name for a nodeset.
875 : */
876 : std::string & nodeset_name(boundary_id_type id);
877 :
878 : /**
879 : * \returns A const reference to an optional edgeset name.
880 : */
881 : const std::string & get_edgeset_name(boundary_id_type id) const;
882 :
883 : /**
884 : * \returns A writable reference to an optional edgeset name.
885 : */
886 : std::string & edgeset_name(boundary_id_type id);
887 :
888 : /**
889 : * \returns The id of the named boundary if it exists, \p invalid_id
890 : * otherwise.
891 : */
892 : boundary_id_type get_id_by_name(std::string_view name) const;
893 :
894 : /**
895 : * \returns A writable reference to the sideset name map.
896 : */
897 1270 : std::map<boundary_id_type, std::string> & set_sideset_name_map ()
898 42119 : { return _ss_id_to_name; }
899 537 : const std::map<boundary_id_type, std::string> & get_sideset_name_map () const
900 3467 : { return _ss_id_to_name; }
901 :
902 : /**
903 : * \returns A writable reference to the nodeset name map.
904 : */
905 758 : std::map<boundary_id_type, std::string> & set_nodeset_name_map ()
906 24083 : { return _ns_id_to_name; }
907 519 : const std::map<boundary_id_type, std::string> & get_nodeset_name_map () const
908 1753 : { return _ns_id_to_name; }
909 :
910 : /**
911 : * \returns Writable/const reference to the edgeset name map.
912 : */
913 56 : std::map<boundary_id_type, std::string> & set_edgeset_name_map ()
914 56 : { return _es_id_to_name; }
915 64 : const std::map<boundary_id_type, std::string> & get_edgeset_name_map () const
916 340 : { return _es_id_to_name; }
917 :
918 : /**
919 : * Number used for internal use. This is the return value
920 : * if a boundary condition is not specified.
921 : */
922 : static const boundary_id_type invalid_id;
923 :
924 : /**
925 : * \returns A const reference to the nodeset map.
926 : */
927 8 : const std::multimap<const Node *, boundary_id_type> & get_nodeset_map () const
928 8 : { return _boundary_node_id; }
929 :
930 : /**
931 : * \returns A const reference to the edgeset map.
932 : */
933 8 : const std::multimap<const Elem *, std::pair<unsigned short int, boundary_id_type>> & get_edgeset_map () const
934 8 : { return _boundary_edge_id; }
935 :
936 : /**
937 : * \returns A const reference to the sideset map.
938 : */
939 8 : const std::multimap<const Elem *, std::pair<unsigned short int, boundary_id_type>> & get_sideset_map() const
940 8 : { return _boundary_side_id; }
941 :
942 : /**
943 : * \returns Whether or not there may be child elements directly assigned boundary sides
944 : */
945 1296 : bool is_children_on_boundary_side() const
946 5319284 : { return _children_on_boundary; }
947 :
948 : /**
949 : * Whether or not to allow directly setting boundary sides on child elements
950 : */
951 : void allow_children_on_boundary_side(const bool children_on_boundary)
952 : { _children_on_boundary = children_on_boundary; }
953 :
954 : private:
955 :
956 : /**
957 : * Helper method for ensuring that our multimaps don't contain
958 : * entries with duplicate keys *and* values. Probably should have
959 : * picked a different data structure there, and also not given users
960 : * an accessor with raw access to it...
961 : */
962 : void libmesh_assert_valid_multimaps() const;
963 :
964 : /**
965 : * Helper method for finding consistent maps of interior to boundary
966 : * dof_object ids. Either node_id_map or side_id_map can be nullptr,
967 : * in which case it will not be filled.
968 : */
969 : void _find_id_maps (const std::set<boundary_id_type> & requested_boundary_ids,
970 : dof_id_type first_free_node_id,
971 : std::map<dof_id_type, dof_id_type> * node_id_map,
972 : dof_id_type first_free_elem_id,
973 : std::map<std::pair<dof_id_type, unsigned char>, dof_id_type> * side_id_map,
974 : const std::set<subdomain_id_type> & subdomains_relative_to);
975 :
976 : /**
977 : * A pointer to the Mesh this boundary info pertains to.
978 : */
979 : MeshBase * _mesh;
980 :
981 : /**
982 : * Data structure that maps nodes in the mesh
983 : * to boundary ids.
984 : */
985 : std::multimap<const Node *,
986 : boundary_id_type> _boundary_node_id;
987 :
988 : /**
989 : * Data structure that maps edges of elements
990 : * to boundary ids. This is only relevant in 3D.
991 : */
992 : std::multimap<const Elem *,
993 : std::pair<unsigned short int, boundary_id_type>>
994 : _boundary_edge_id;
995 :
996 : /**
997 : * Data structure that maps faces of shell elements
998 : * to boundary ids. This is only relevant for shell elements.
999 : */
1000 : std::multimap<const Elem *,
1001 : std::pair<unsigned short int, boundary_id_type>>
1002 : _boundary_shellface_id;
1003 :
1004 : /**
1005 : * Data structure that maps sides of elements
1006 : * to boundary ids.
1007 : */
1008 : std::multimap<const Elem *,
1009 : std::pair<unsigned short int, boundary_id_type>>
1010 : _boundary_side_id;
1011 :
1012 : /*
1013 : * Whether or not children elements are associated with any boundary
1014 : * It is false by default. The flag will be turned on if `add_side`
1015 : * function is called with a child element
1016 : */
1017 : bool _children_on_boundary;
1018 :
1019 : /**
1020 : * A collection of user-specified boundary ids for sides, edges, nodes,
1021 : * and shell faces.
1022 : * See _side_boundary_ids, _edge_boundary_ids, _node_boundary_ids, and
1023 : * _shellface_boundary_ids for sets containing IDs for only sides, edges,
1024 : * nodes, and shell faces, respectively.
1025 : *
1026 : * This only contains information related to this process's local and ghosted elements
1027 : */
1028 : std::set<boundary_id_type> _boundary_ids;
1029 :
1030 : /**
1031 : * A collection of user-specified boundary ids for sides, edges, nodes,
1032 : * and shell faces.
1033 : * See _side_boundary_ids, _edge_boundary_ids, _node_boundary_ids, and
1034 : * _shellface_boundary_ids for sets containing IDs for only sides, edges,
1035 : * nodes, and shell faces, respectively.
1036 : *
1037 : * Unlike \p _boundary_ids, this member should contain boundary ids from across
1038 : * all processors after the mesh is prepared
1039 : */
1040 : std::set<boundary_id_type> _global_boundary_ids;
1041 :
1042 : /**
1043 : * Set of user-specified boundary IDs for sides *only*.
1044 : *
1045 : * \note \p _boundary_ids is the union of this set, \p
1046 : * _edge_boundary_ids, \p _node_boundary_ids, and \p
1047 : * _shellface_boundary_ids.
1048 : *
1049 : * This only contains information related to this process's local and ghosted elements
1050 : */
1051 : std::set<boundary_id_type> _side_boundary_ids;
1052 :
1053 : /**
1054 : * Set of user-specified boundary IDs for edges *only*.
1055 : * This is only relevant in 3D.
1056 : *
1057 : * \note \p _boundary_ids is the union of this set, \p _side_boundary_ids,
1058 : * \p _node_boundary_ids, and \p _shellface_boundary_ids.
1059 : *
1060 : * This only contains information related to this process's local and ghosted elements
1061 : */
1062 : std::set<boundary_id_type> _edge_boundary_ids;
1063 :
1064 : /**
1065 : * Set of user-specified boundary IDs for nodes *only*.
1066 : *
1067 : * \note \p _boundary_ids is the union of this set, \p
1068 : * _edge_boundary_ids, \p _side_boundary_ids, and \p
1069 : * _shellface_boundary_ids.
1070 : *
1071 : * This only contains information related to this process's local and ghosted elements
1072 : */
1073 : std::set<boundary_id_type> _node_boundary_ids;
1074 :
1075 : /**
1076 : * Set of user-specified boundary IDs for shellfaces *only*.
1077 : * This is only relevant for shell elements.
1078 : *
1079 : * \note \p _boundary_ids is the union of this set, \p
1080 : * _side_boundary_ids, \p _edge_boundary_ids, and \p
1081 : * _node_boundary_ids.
1082 : *
1083 : * This only contains information related to this process's local and ghosted elements
1084 : */
1085 : std::set<boundary_id_type> _shellface_boundary_ids;
1086 :
1087 : /**
1088 : * This structure maintains the mapping of named side sets
1089 : * for file formats (Exodus, Gmsh) that support this.
1090 : *
1091 : * This data is global in nature, meaning it should be an aggregate of information across
1092 : * processors
1093 : */
1094 : std::map<boundary_id_type, std::string> _ss_id_to_name;
1095 :
1096 : /**
1097 : * This structure maintains the mapping of named node sets
1098 : * for file formats (Exodus, Gmsh) that support this.
1099 : *
1100 : * This data is global in nature, meaning it should be an aggregate of information across
1101 : * processors
1102 : */
1103 : std::map<boundary_id_type, std::string> _ns_id_to_name;
1104 :
1105 : /**
1106 : * This structure maintains the mapping of named edge sets
1107 : * for file formats (Exodus, Gmsh) that support this.
1108 : *
1109 : * This data is global in nature, meaning it should be an aggregate of information across
1110 : * processors
1111 : */
1112 : std::map<boundary_id_type, std::string> _es_id_to_name;
1113 : };
1114 :
1115 : } // namespace libMesh
1116 :
1117 : #endif // LIBMESH_BOUNDARY_INFO_H
|