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