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 38180 : 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 the \p side side of
504 : * element \p elem.
505 : */
506 : void boundary_ids (const Elem * const elem,
507 : const unsigned short int side,
508 : std::vector<boundary_id_type> & vec_to_fill) const;
509 :
510 : /**
511 : * \returns The list of raw boundary ids associated with the \p side
512 : * side of element \p elem.
513 : *
514 : * These ids are "raw" because they exclude ids which are implicit,
515 : * such as a child's inheritance of its ancestors' boundary id.
516 : */
517 : void raw_boundary_ids (const Elem * const elem,
518 : const unsigned short int side,
519 : std::vector<boundary_id_type> & vec_to_fill) const;
520 :
521 : /*
522 : * Copy boundary ids associated with old_elem (but not its nodes)
523 : * from old_boundary_info (which may be this) into this boundary
524 : * info, associating them with new_elem.
525 : */
526 : void copy_boundary_ids (const BoundaryInfo & old_boundary_info,
527 : const Elem * const old_elem,
528 : const Elem * const new_elem);
529 :
530 : /**
531 : * \returns A side of element \p elem whose associated boundary id is
532 : * \p boundary_id if such a side exists, and \p invalid_uint otherwise.
533 : *
534 : * \note If multiple sides of \p elem have the same id, only the lowest numbered
535 : * such side is returned.
536 : */
537 : unsigned int side_with_boundary_id(const Elem * const elem,
538 : const boundary_id_type boundary_id) const;
539 :
540 : /**
541 : * \returns All sides of element \p elem whose associated boundary id is
542 : * \p boundary_id
543 : */
544 : std::vector<unsigned int>
545 : sides_with_boundary_id(const Elem * const elem,
546 : const boundary_id_type boundary_id) const;
547 :
548 : /**
549 : * Builds the list of unique node boundary ids.
550 : *
551 : * On a ReplicatedMesh this will be all ids; on a DistributedMesh
552 : * only ids on semilocal nodes will be included.
553 : */
554 : void build_node_boundary_ids(std::vector<boundary_id_type> & b_ids) const;
555 :
556 : /**
557 : * Builds the list of unique side boundary ids.
558 : *
559 : * On a ReplicatedMesh this will be all ids; on a DistributedMesh
560 : * only ids on sides of semilocal elements will be included.
561 : */
562 : void build_side_boundary_ids(std::vector<boundary_id_type> & b_ids) const;
563 :
564 : /**
565 : * Builds the list of unique shellface boundary ids.
566 : *
567 : * On a ReplicatedMesh this will be all ids; on a DistributedMesh
568 : * only ids on shellfaces of semilocal elements will be included.
569 : */
570 : void build_shellface_boundary_ids(std::vector<boundary_id_type> & b_ids) const;
571 :
572 : #ifdef LIBMESH_ENABLE_AMR
573 : /**
574 : * Update parent's boundary id list so that this information is consistent with
575 : * its children
576 : *
577 : * This is useful when `_children_on_boundary = true`, and is used when the
578 : * element is about to get coarsened i.e., in MeshRefinement::_coarsen_elements()
579 : *
580 : * Specifically, when we coarsen an element whose children have different boundary ids.
581 : * In such scenarios, the parent will inherit the children's boundaries if at
582 : * least 50% them own a boundary while sharing the side of the parent.
583 : */
584 : void transfer_boundary_ids_from_children(const Elem * const parent);
585 : #endif
586 :
587 : /**
588 : * \returns The number of element-side-based boundary conditions.
589 : *
590 : * This will be the correct global count even on a distributed mesh.
591 : */
592 : std::size_t n_boundary_conds () const;
593 :
594 : /**
595 : * \returns The number of edge-based boundary conditions.
596 : * Edge-based boundary IDs should only be used in 3D.
597 : *
598 : * This will be the correct global count even on a distributed mesh.
599 : */
600 : std::size_t n_edge_conds () const;
601 :
602 : /**
603 : * \returns The number of shellface-based boundary conditions.
604 : * This is only relevant on shell elements.
605 : *
606 : * This will be the correct global count even on a distributed mesh.
607 : */
608 : std::size_t n_shellface_conds () const;
609 :
610 : /**
611 : * \returns The number of node-based boundary conditions.
612 : *
613 : * This will be the correct global count even on a distributed mesh.
614 : */
615 : std::size_t n_nodeset_conds () const;
616 :
617 : /**
618 : * Creates a list of nodes and ids for those nodes.
619 : *
620 : * On a ReplicatedMesh this will include all nodes; on a
621 : * DistributedMesh only semilocal nodes will be included.
622 : *
623 : * \deprecated Use the version of build_node_list() below that
624 : * returns a std::vector of tuples instead.
625 : */
626 : #ifdef LIBMESH_ENABLE_DEPRECATED
627 : void build_node_list (std::vector<dof_id_type> & node_id_list,
628 : std::vector<boundary_id_type> & bc_id_list) const;
629 : #endif
630 :
631 : /**
632 : * As above, but the library creates and fills in a vector of
633 : * (node-id, bc-id) pairs and returns it to the user, taking
634 : * advantage of guaranteed RVO. Note: we could use std::pairs for
635 : * this, but for consistency with the other build_XYZ_list
636 : * functions, we're using tuples.
637 : *
638 : * The "sort_by" parameter controls how the resulting list of tuples
639 : * is sorted. It is possible (but not recommended) to choose
640 : * UNSORTED, since in that case the resulting vectors will
641 : * potentially be in different orders on different procs.
642 : */
643 : typedef std::tuple<dof_id_type, boundary_id_type> NodeBCTuple;
644 : enum class NodeBCTupleSortBy {NODE_ID, BOUNDARY_ID, UNSORTED};
645 : std::vector<NodeBCTuple> build_node_list(NodeBCTupleSortBy sort_by = NodeBCTupleSortBy::NODE_ID) const;
646 :
647 : /**
648 : * Adds nodes with boundary ids based on the side's boundary
649 : * ids they are connected to.
650 : */
651 : void build_node_list_from_side_list();
652 :
653 : /**
654 : * Adds sides to a sideset if every node on that side are in the same
655 : * sideset
656 : */
657 : void build_side_list_from_node_list();
658 :
659 : /**
660 : * Creates a list of element numbers, sides, and ids for those sides.
661 : *
662 : * On a ReplicatedMesh this will include all sides; on a
663 : * DistributedMesh only sides of semilocal elements will be
664 : * included.
665 : *
666 : * \deprecated Use the version of build_side_list() below that
667 : * returns a std::vector of tuples instead.
668 : */
669 : #ifdef LIBMESH_ENABLE_DEPRECATED
670 : void build_side_list (std::vector<dof_id_type> & element_id_list,
671 : std::vector<unsigned short int> & side_list,
672 : std::vector<boundary_id_type> & bc_id_list) const;
673 : #endif
674 :
675 : /**
676 : * As above, but the library creates and fills in a vector of
677 : * (elem-id, side-id, bc-id) triplets and returns it to the user,
678 : * taking advantage of guaranteed RVO.
679 : *
680 : * The returned vector is sorted by element id by default, but this
681 : * can be changed by passing SIDE_ID, BOUNDARY_ID, or UNSORTED to
682 : * this function. Note: choosing UNSORTED is not recommended since
683 : * the resulting list will potentially be in different orders on
684 : * different processors when running in parallel.
685 : */
686 : typedef std::tuple<dof_id_type, unsigned short int, boundary_id_type> BCTuple;
687 : enum class BCTupleSortBy {ELEM_ID, SIDE_ID, BOUNDARY_ID, UNSORTED};
688 : std::vector<BCTuple> build_side_list(BCTupleSortBy sort_by = BCTupleSortBy::ELEM_ID) const;
689 :
690 : /**
691 : * Creates a list of active element numbers, sides, and ids for those sides.
692 : *
693 : * On a ReplicatedMesh this will include all sides; on a
694 : * DistributedMesh only sides of semilocal elements will be
695 : * included.
696 : *
697 : * \deprecated Use the version of build_active_side_list() below
698 : * that returns a std::vector of tuples instead.
699 : */
700 : #ifdef LIBMESH_ENABLE_DEPRECATED
701 : void build_active_side_list (std::vector<dof_id_type> & element_id_list,
702 : std::vector<unsigned short int> & side_list,
703 : std::vector<boundary_id_type> & bc_id_list) const;
704 : #endif
705 :
706 : /**
707 : * As above, but the library creates and fills in a vector of
708 : * (elem-id, side-id, bc-id) triplets and returns it to the user,
709 : * taking advantage of guaranteed RVO.
710 : */
711 : std::vector<BCTuple> build_active_side_list () const;
712 :
713 : /**
714 : * Creates a list of element numbers, edges, and boundary ids for those edges.
715 : *
716 : * On a ReplicatedMesh this will include all edges; on a
717 : * DistributedMesh only edges of semilocal elements will be
718 : * included.
719 : *
720 : * \deprecated Use the version of build_edge_list() below
721 : * that returns a std::vector of tuples instead.
722 : */
723 : #ifdef LIBMESH_ENABLE_DEPRECATED
724 : void build_edge_list (std::vector<dof_id_type> & element_id_list,
725 : std::vector<unsigned short int> & edge_list,
726 : std::vector<boundary_id_type> & bc_id_list) const;
727 : #endif
728 :
729 : /**
730 : * As above, but the library creates and fills in a vector of
731 : * (elem-id, side-id, bc-id) triplets and returns it to the user,
732 : * taking advantage of guaranteed RVO.
733 : */
734 : std::vector<BCTuple> build_edge_list() const;
735 :
736 : /**
737 : * Creates a list of element numbers, shellfaces, and boundary ids for those shellfaces.
738 : *
739 : * On a ReplicatedMesh this will include all shellfaces; on a
740 : * DistributedMesh only shellfaces of semilocal elements will be
741 : * included.
742 : *
743 : * \deprecated Use the version of build_shellface_list() below
744 : * that returns a std::vector of tuples instead.
745 : */
746 : #ifdef LIBMESH_ENABLE_DEPRECATED
747 : void build_shellface_list (std::vector<dof_id_type> & element_id_list,
748 : std::vector<unsigned short int> & shellface_list,
749 : std::vector<boundary_id_type> & bc_id_list) const;
750 : #endif
751 :
752 : /**
753 : * As above, but the library creates and fills in a vector of
754 : * (elem-id, side-id, bc-id) triplets and returns it to the user,
755 : * taking advantage of guaranteed RVO.
756 : */
757 : std::vector<BCTuple> build_shellface_list() const;
758 :
759 : /**
760 : * Synchronize the boundary element side and node across processors.
761 : * This function is needed when boundary info is changed by adding or removing
762 : * sides on the fly.
763 : * Note: if the side of a ghost element is changed, then you would need to do
764 : * do parallel push (see e.g., timpi/parallel_sync.h) and then sync.
765 : */
766 : void parallel_sync_side_ids();
767 : void parallel_sync_node_ids();
768 :
769 : /**
770 : * \returns A set of the boundary ids which exist on semilocal parts
771 : * of the mesh.
772 : *
773 : * Code that wishes to access boundary ids on all parts of the mesh, including
774 : * non-local parts, should call \p get_global_boundary_ids
775 : */
776 584 : const std::set<boundary_id_type> & get_boundary_ids () const
777 584 : { return _boundary_ids; }
778 :
779 : /**
780 : * \returns A set of the boundary ids which exist globally
781 : * on the mesh. Relies on the mesh being prepared
782 : */
783 : const std::set<boundary_id_type> & get_global_boundary_ids () const;
784 :
785 : /**
786 : * \returns A reference to the set of the boundary IDs specified on
787 : * sides of semilocal mesh elements.
788 : */
789 420 : const std::set<boundary_id_type> & get_side_boundary_ids () const
790 420 : { return _side_boundary_ids; }
791 :
792 : /**
793 : * \returns A reference to the set of all boundary IDs specified on
794 : * edges of semilocal mesh elements.
795 : *
796 : * \note Edge-based boundary IDs should only be used in 3D.
797 : */
798 887 : const std::set<boundary_id_type> & get_edge_boundary_ids () const
799 887 : { return _edge_boundary_ids; }
800 :
801 : /**
802 : * \returns A reference to the set of all boundary IDs specified on
803 : * shell faces.
804 : *
805 : * \note This is only relevant on shell elements.
806 : */
807 : const std::set<boundary_id_type> & get_shellface_boundary_ids () const
808 : { return _shellface_boundary_ids; }
809 :
810 : /**
811 : * \returns A reference to the set of all boundary IDs specified on
812 : * semilocal mesh nodes.
813 : */
814 1056 : const std::set<boundary_id_type> & get_node_boundary_ids () const
815 1056 : { return _node_boundary_ids; }
816 :
817 :
818 : /**
819 : * Prints the boundary information data structure.
820 : */
821 : void print_info (std::ostream & out_stream=libMesh::out) const;
822 :
823 : /**
824 : * Prints a summary of the boundary information.
825 : */
826 : void print_summary (std::ostream & out_stream=libMesh::out) const;
827 :
828 : /**
829 : * \returns A reference for getting an optional name for a sideset.
830 : */
831 : const std::string & get_sideset_name(boundary_id_type id) const;
832 :
833 : /**
834 : * \returns A writable reference for setting an optional
835 : * name for a sideset.
836 : */
837 : std::string & sideset_name(boundary_id_type id);
838 :
839 : /**
840 : * \returns A reference for getting an optional name for a nodeset.
841 : */
842 : const std::string & get_nodeset_name(boundary_id_type id) const;
843 :
844 : /**
845 : * \returns A writable reference for setting an optional
846 : * name for a nodeset.
847 : */
848 : std::string & nodeset_name(boundary_id_type id);
849 :
850 : /**
851 : * \returns A const reference to an optional edgeset name.
852 : */
853 : const std::string & get_edgeset_name(boundary_id_type id) const;
854 :
855 : /**
856 : * \returns A writable reference to an optional edgeset name.
857 : */
858 : std::string & edgeset_name(boundary_id_type id);
859 :
860 : /**
861 : * \returns The id of the named boundary if it exists, \p invalid_id
862 : * otherwise.
863 : */
864 : boundary_id_type get_id_by_name(std::string_view name) const;
865 :
866 : /**
867 : * \returns A writable reference to the sideset name map.
868 : */
869 460 : std::map<boundary_id_type, std::string> & set_sideset_name_map ()
870 13758 : { return _ss_id_to_name; }
871 524 : const std::map<boundary_id_type, std::string> & get_sideset_name_map () const
872 1576 : { return _ss_id_to_name; }
873 :
874 : /**
875 : * \returns A writable reference to the nodeset name map.
876 : */
877 404 : std::map<boundary_id_type, std::string> & set_nodeset_name_map ()
878 11910 : { return _ns_id_to_name; }
879 508 : const std::map<boundary_id_type, std::string> & get_nodeset_name_map () const
880 1116 : { return _ns_id_to_name; }
881 :
882 : /**
883 : * \returns Writable/const reference to the edgeset name map.
884 : */
885 48 : std::map<boundary_id_type, std::string> & set_edgeset_name_map ()
886 48 : { return _es_id_to_name; }
887 56 : const std::map<boundary_id_type, std::string> & get_edgeset_name_map () const
888 332 : { return _es_id_to_name; }
889 :
890 : /**
891 : * Number used for internal use. This is the return value
892 : * if a boundary condition is not specified.
893 : */
894 : static const boundary_id_type invalid_id;
895 :
896 : /**
897 : * \returns A const reference to the nodeset map.
898 : */
899 8 : const std::multimap<const Node *, boundary_id_type> & get_nodeset_map () const
900 8 : { return _boundary_node_id; }
901 :
902 : /**
903 : * \returns A const reference to the edgeset map.
904 : */
905 8 : const std::multimap<const Elem *, std::pair<unsigned short int, boundary_id_type>> & get_edgeset_map () const
906 8 : { return _boundary_edge_id; }
907 :
908 : /**
909 : * \returns A const reference to the sideset map.
910 : */
911 8 : const std::multimap<const Elem *, std::pair<unsigned short int, boundary_id_type>> & get_sideset_map() const
912 8 : { return _boundary_side_id; }
913 :
914 : /**
915 : * \returns Whether or not there may be child elements directly assigned boundary sides
916 : */
917 1296 : bool is_children_on_boundary_side() const
918 4932053 : { return _children_on_boundary; }
919 :
920 : /**
921 : * Whether or not to allow directly setting boundary sides on child elements
922 : */
923 : void allow_children_on_boundary_side(const bool children_on_boundary)
924 : { _children_on_boundary = children_on_boundary; }
925 :
926 : private:
927 :
928 : /**
929 : * Helper method for ensuring that our multimaps don't contain
930 : * entries with duplicate keys *and* values. Probably should have
931 : * picked a different data structure there, and also not given users
932 : * an accessor with raw access to it...
933 : */
934 : void libmesh_assert_valid_multimaps() const;
935 :
936 : /**
937 : * Helper method for finding consistent maps of interior to boundary
938 : * dof_object ids. Either node_id_map or side_id_map can be nullptr,
939 : * in which case it will not be filled.
940 : */
941 : void _find_id_maps (const std::set<boundary_id_type> & requested_boundary_ids,
942 : dof_id_type first_free_node_id,
943 : std::map<dof_id_type, dof_id_type> * node_id_map,
944 : dof_id_type first_free_elem_id,
945 : std::map<std::pair<dof_id_type, unsigned char>, dof_id_type> * side_id_map,
946 : const std::set<subdomain_id_type> & subdomains_relative_to);
947 :
948 : /**
949 : * A pointer to the Mesh this boundary info pertains to.
950 : */
951 : MeshBase * _mesh;
952 :
953 : /**
954 : * Data structure that maps nodes in the mesh
955 : * to boundary ids.
956 : */
957 : std::multimap<const Node *,
958 : boundary_id_type> _boundary_node_id;
959 :
960 : /**
961 : * Data structure that maps edges of elements
962 : * to boundary ids. This is only relevant in 3D.
963 : */
964 : std::multimap<const Elem *,
965 : std::pair<unsigned short int, boundary_id_type>>
966 : _boundary_edge_id;
967 :
968 : /**
969 : * Data structure that maps faces of shell elements
970 : * to boundary ids. This is only relevant for shell elements.
971 : */
972 : std::multimap<const Elem *,
973 : std::pair<unsigned short int, boundary_id_type>>
974 : _boundary_shellface_id;
975 :
976 : /**
977 : * Data structure that maps sides of elements
978 : * to boundary ids.
979 : */
980 : std::multimap<const Elem *,
981 : std::pair<unsigned short int, boundary_id_type>>
982 : _boundary_side_id;
983 :
984 : /*
985 : * Whether or not children elements are associated with any boundary
986 : * It is false by default. The flag will be turned on if `add_side`
987 : * function is called with a child element
988 : */
989 : bool _children_on_boundary;
990 :
991 : /**
992 : * A collection of user-specified boundary ids for sides, edges, nodes,
993 : * and shell faces.
994 : * See _side_boundary_ids, _edge_boundary_ids, _node_boundary_ids, and
995 : * _shellface_boundary_ids for sets containing IDs for only sides, edges,
996 : * nodes, and shell faces, respectively.
997 : *
998 : * This only contains information related to this process's local and ghosted elements
999 : */
1000 : std::set<boundary_id_type> _boundary_ids;
1001 :
1002 : /**
1003 : * A collection of user-specified boundary ids for sides, edges, nodes,
1004 : * and shell faces.
1005 : * See _side_boundary_ids, _edge_boundary_ids, _node_boundary_ids, and
1006 : * _shellface_boundary_ids for sets containing IDs for only sides, edges,
1007 : * nodes, and shell faces, respectively.
1008 : *
1009 : * Unlike \p _boundary_ids, this member should contain boundary ids from across
1010 : * all processors after the mesh is prepared
1011 : */
1012 : std::set<boundary_id_type> _global_boundary_ids;
1013 :
1014 : /**
1015 : * Set of user-specified boundary IDs for sides *only*.
1016 : *
1017 : * \note \p _boundary_ids is the union of this set, \p
1018 : * _edge_boundary_ids, \p _node_boundary_ids, and \p
1019 : * _shellface_boundary_ids.
1020 : *
1021 : * This only contains information related to this process's local and ghosted elements
1022 : */
1023 : std::set<boundary_id_type> _side_boundary_ids;
1024 :
1025 : /**
1026 : * Set of user-specified boundary IDs for edges *only*.
1027 : * This is only relevant in 3D.
1028 : *
1029 : * \note \p _boundary_ids is the union of this set, \p _side_boundary_ids,
1030 : * \p _node_boundary_ids, and \p _shellface_boundary_ids.
1031 : *
1032 : * This only contains information related to this process's local and ghosted elements
1033 : */
1034 : std::set<boundary_id_type> _edge_boundary_ids;
1035 :
1036 : /**
1037 : * Set of user-specified boundary IDs for nodes *only*.
1038 : *
1039 : * \note \p _boundary_ids is the union of this set, \p
1040 : * _edge_boundary_ids, \p _side_boundary_ids, and \p
1041 : * _shellface_boundary_ids.
1042 : *
1043 : * This only contains information related to this process's local and ghosted elements
1044 : */
1045 : std::set<boundary_id_type> _node_boundary_ids;
1046 :
1047 : /**
1048 : * Set of user-specified boundary IDs for shellfaces *only*.
1049 : * This is only relevant for shell elements.
1050 : *
1051 : * \note \p _boundary_ids is the union of this set, \p
1052 : * _side_boundary_ids, \p _edge_boundary_ids, and \p
1053 : * _node_boundary_ids.
1054 : *
1055 : * This only contains information related to this process's local and ghosted elements
1056 : */
1057 : std::set<boundary_id_type> _shellface_boundary_ids;
1058 :
1059 : /**
1060 : * This structure maintains the mapping of named side sets
1061 : * for file formats (Exodus, Gmsh) that support this.
1062 : *
1063 : * This data is global in nature, meaning it should be an aggregate of information across
1064 : * processors
1065 : */
1066 : std::map<boundary_id_type, std::string> _ss_id_to_name;
1067 :
1068 : /**
1069 : * This structure maintains the mapping of named node 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> _ns_id_to_name;
1076 :
1077 : /**
1078 : * This structure maintains the mapping of named edge 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> _es_id_to_name;
1085 : };
1086 :
1087 : } // namespace libMesh
1088 :
1089 : #endif // LIBMESH_BOUNDARY_INFO_H
|