Line data Source code
1 : //* This file is part of the MOOSE framework
2 : //* https://mooseframework.inl.gov
3 : //*
4 : //* All rights reserved, see COPYRIGHT for full restrictions
5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 : //*
7 : //* Licensed under LGPL 2.1, please see LICENSE for details
8 : //* https://www.gnu.org/licenses/lgpl-2.1.html
9 :
10 : #pragma once
11 :
12 : #include "libmesh/replicated_mesh.h"
13 : #include "libmesh/boundary_info.h"
14 :
15 : #include "MooseUtils.h"
16 : #include "MooseTypes.h"
17 : #include "FaceInfo.h"
18 : #include "MeshGenerator.h"
19 :
20 : // Utilities for MeshBase
21 : // Many of these utilities could live in libMesh, and in fact, before adding a new one here
22 : // you should also check mesh_tools.h in libMesh to see if it does not exist there already.
23 :
24 : namespace MooseMeshUtils
25 : {
26 :
27 : // Used to temporarily store information about which lower-dimensional
28 : // sides to add and what subdomain id to use for the added sides.
29 : struct ElemSidePair
30 : {
31 26600 : ElemSidePair(Elem * elem_in, unsigned short int side_in) : elem(elem_in), side(side_in) {}
32 :
33 : Elem * elem;
34 : unsigned short int side;
35 : };
36 :
37 : /**
38 : * Merges the boundary IDs of boundaries that have the same names
39 : * but different IDs.
40 : * @param mesh The input mesh whose boundaries we will modify
41 : */
42 : void mergeBoundaryIDsWithSameName(MeshBase & mesh);
43 :
44 : /**
45 : * Changes the old boundary ID to a new ID in the mesh
46 : *
47 : * @param mesh the mesh
48 : * @param old_id the old boundary id
49 : * @param new_id the new boundary id
50 : * @param delete_prev whether to delete the previous boundary id from the mesh
51 : */
52 : void changeBoundaryId(MeshBase & mesh,
53 : const libMesh::boundary_id_type old_id,
54 : const libMesh::boundary_id_type new_id,
55 : bool delete_prev);
56 :
57 : /**
58 : * Changes the old subdomain ID to a new ID in the mesh
59 : *
60 : * @param mesh the mesh
61 : * @param old_id the old subdomain id
62 : * @param new_id the new subdomain id
63 : */
64 : void
65 : changeSubdomainId(MeshBase & mesh, const subdomain_id_type old_id, const subdomain_id_type new_id);
66 :
67 : /**
68 : * Gets the boundary IDs with their names.
69 : *
70 : * The ordering of the returned boundary ID vector matches the vector of the boundary
71 : * names in \p boundary_name.
72 : * When a boundary name is not available in the mesh, if \p generate_unknown is true
73 : * a non-existant boundary ID will be returned, otherwise a BoundaryInfo::invalid_id
74 : * will be returned.
75 : */
76 : std::vector<BoundaryID> getBoundaryIDs(const libMesh::MeshBase & mesh,
77 : const std::vector<BoundaryName> & boundary_name,
78 : bool generate_unknown,
79 : const std::set<BoundaryID> & mesh_boundary_ids);
80 :
81 : /**
82 : * Gets the boundary IDs with their names.
83 : *
84 : * The ordering of the returned boundary ID vector matches the vector of the boundary
85 : * names in \p boundary_name.
86 : * When a boundary name is not available in the mesh, if \p generate_unknown is true
87 : * a non-existant boundary ID will be returned, otherwise a BoundaryInfo::invalid_id
88 : * will be returned.
89 : */
90 : std::vector<BoundaryID> getBoundaryIDs(const libMesh::MeshBase & mesh,
91 : const std::vector<BoundaryName> & boundary_name,
92 : bool generate_unknown);
93 :
94 : /**
95 : * Gets the boundary IDs into a set with their names.
96 : *
97 : * Because libMesh allows the same boundary to have multiple different boundary names,
98 : * the size of the returned boundary ID set may be smaller than the size of the boundary
99 : * name vector.
100 : * When a boundary name is not available in the mesh, if \p generate_unknown is true
101 : * a non-existant boundary ID will be returned, otherwise a BoundaryInfo::invalid_id
102 : * will be returned.
103 : */
104 : std::set<BoundaryID> getBoundaryIDSet(const libMesh::MeshBase & mesh,
105 : const std::vector<BoundaryName> & boundary_name,
106 : bool generate_unknown);
107 :
108 : /**
109 : * Gets the boundary ID associated with the given BoundaryName.
110 : *
111 : * This is needed because the BoundaryName can be either an ID or a name.
112 : * If it is a name, the mesh is queried for the ID associated with said name.
113 : */
114 : BoundaryID getBoundaryID(const BoundaryName & boundary_name, const MeshBase & mesh);
115 :
116 : /**
117 : * Gets the subdomain ID associated with the given SubdomainName.
118 : *
119 : * This is needed because the SubdomainName can be either an ID or a name.
120 : * If it is a name, the mesh is queried for the ID associated with said name.
121 : */
122 : SubdomainID getSubdomainID(const SubdomainName & subdomain_name, const MeshBase & mesh);
123 :
124 : /**
125 : * Get the associated subdomainIDs for the subdomain names that are passed in.
126 : *
127 : * @param mesh The mesh
128 : * @param subdomain_name The names of the subdomains
129 : * @return The subdomain ids from the passed subdomain names.
130 : */
131 : std::vector<subdomain_id_type> getSubdomainIDs(const libMesh::MeshBase & mesh,
132 : const std::vector<SubdomainName> & subdomain_name);
133 : std::set<subdomain_id_type> getSubdomainIDs(const libMesh::MeshBase & mesh,
134 : const std::set<SubdomainName> & subdomain_name);
135 :
136 : /**
137 : * Calculates the centroid of a MeshBase.
138 : * @param mesh input mesh whose centroid needs to be calculated
139 : * @return a Point corresponding to the mesh centroid
140 : */
141 : Point meshCentroidCalculator(const MeshBase & mesh);
142 :
143 : /**
144 : * Calculates the centroid of a boundary on a mesh
145 : * @param boundary boundary to compute the centroid of
146 : * @param mesh input mesh holding the boundary whose centroid needs to be calculated
147 : * @return a Point corresponding to the boundary centroid
148 : */
149 : Point boundaryCentroidCalculator(const BoundaryName & boundary, MeshBase & mesh);
150 :
151 : /**
152 : * Calculates the side-volume weighted (side-vertex) average normal of a boundary on a mesh
153 : * @param boundary boundary to compute the weighted normal of
154 : * @param mesh input mesh holding the boundary whose averaged normal needs to be calculated
155 : * @return a Point corresponding to the boundary weighted normal
156 : */
157 : RealVectorValue boundaryWeightedNormal(const BoundaryName & boundary, MeshBase & mesh);
158 :
159 : /**
160 : * Compute a coordinate transformation volume integration factor
161 : * @param point The libMesh \p Point in space where we are evaluating the factor
162 : * @param factor The output of this function. Would be 1 for cartesian coordinate systems, 2*pi*r
163 : * for cylindrical coordinate systems, and 4*pi*r^2 for spherical coordinate systems
164 : * @param coord_type The coordinate system type, e.g. cartesian (COORD_XYZ), cylindrical (COORD_RZ),
165 : * or spherical (COORD_RSPHERICAL)
166 : * @param rz_radial_coord The index at which to index \p point for the radial coordinate when in a
167 : * cylindrical coordinate system
168 : */
169 : template <typename P, typename C>
170 : void
171 1886887158 : coordTransformFactor(const P & point,
172 : C & factor,
173 : const Moose::CoordinateSystemType coord_type,
174 : const unsigned int rz_radial_coord = libMesh::invalid_uint)
175 : {
176 1886887158 : switch (coord_type)
177 : {
178 1884270561 : case Moose::COORD_XYZ:
179 1884270561 : factor = 1.0;
180 1884270561 : break;
181 2583805 : case Moose::COORD_RZ:
182 : {
183 : mooseAssert(rz_radial_coord != libMesh::invalid_uint,
184 : "Must pass in a valid rz radial coordinate");
185 2583805 : factor = 2 * M_PI * point(rz_radial_coord);
186 2583805 : break;
187 : }
188 32792 : case Moose::COORD_RSPHERICAL:
189 32792 : factor = 4 * M_PI * point(0) * point(0);
190 32792 : break;
191 0 : default:
192 0 : mooseError("Unknown coordinate system");
193 : }
194 1886887158 : }
195 :
196 : /**
197 : * Computes the distance to a general axis
198 : *
199 : * @param[in] point Point for which to compute distance from axis
200 : * @param[in] origin Axis starting point
201 : * @param[in] direction Axis direction
202 : */
203 : template <typename P, typename C>
204 : C
205 1063075 : computeDistanceToAxis(const P & point, const Point & origin, const RealVectorValue & direction)
206 : {
207 1063075 : return (point - origin).cross(direction).norm();
208 : }
209 :
210 : /**
211 : * Computes the maximum distance from all nodes of a mesh to a general axis
212 : *
213 : * @param[in] mesh mesh to get the distance from
214 : * @param[in] origin Axis starting point
215 : * @param[in] direction Axis direction
216 : */
217 : Real computeMaxDistanceToAxis(const MeshBase & mesh,
218 : const Point & origin,
219 : const RealVectorValue & direction);
220 :
221 : /**
222 : * Computes a coordinate transformation factor for a general axisymmetric axis
223 : *
224 : * @param[in] point The libMesh \p Point in space where we are evaluating the factor
225 : * @param[in] axis The pair of values defining the general axisymmetric axis.
226 : * Respectively, the values are the axis starting point and direction.
227 : * @param[out] factor The coordinate transformation factor
228 : */
229 : template <typename P, typename C>
230 : void
231 1063075 : coordTransformFactorRZGeneral(const P & point,
232 : const std::pair<Point, RealVectorValue> & axis,
233 : C & factor)
234 : {
235 1063075 : factor = 2 * M_PI * computeDistanceToAxis<P, C>(point, axis.first, axis.second);
236 1063075 : }
237 :
238 : inline void
239 : computeFiniteVolumeCoords(FaceInfo & fi,
240 : const Moose::CoordinateSystemType coord_type,
241 : const unsigned int rz_radial_coord = libMesh::invalid_uint)
242 : {
243 : coordTransformFactor(fi.faceCentroid(), fi.faceCoord(), coord_type, rz_radial_coord);
244 : }
245 :
246 : /**
247 : * Create a new set of element-wise IDs by finding unique combinations of existing extra ID values
248 : *
249 : * This function finds the unique combinations by recursively calling itself for extra ID inputs. In
250 : * the recursive calling, the new unique combinations is determined by combining the extra ID value
251 : * of current level and the unique combination determined in the previous level in recursion. In the
252 : * lowest level of recursion, the base combination is set by the unique ID values of the
253 : * corresponding extra ID.
254 : *
255 : * @param mesh input mesh
256 : * @param block_ids block ids
257 : * @param extra_ids extra ids
258 : * @return map of element id to new extra id
259 : **/
260 : std::unordered_map<dof_id_type, dof_id_type>
261 : getExtraIDUniqueCombinationMap(const MeshBase & mesh,
262 : const std::set<SubdomainID> & block_ids,
263 : std::vector<ExtraElementIDName> extra_ids);
264 :
265 : /**
266 : * Decides whether all the Points of a vector of Points are in a plane that is defined by a normal
267 : * vector and an inplane Point
268 : * @param vec_pts vector of points to be examined
269 : * @param plane_nvec normal vector of the plane
270 : * @param fixed_pt a Point in the plane
271 : * @return whether all the Points are in the given plane
272 : */
273 : bool isCoPlanar(const std::vector<Point> & vec_pts, const Point plane_nvec, const Point fixed_pt);
274 :
275 : /**
276 : * Decides whether all the Points of a vector of Points are in a plane with a given normal vector
277 : * @param vec_pts vector of points to be examined
278 : * @param plane_nvec normal vector of the plane
279 : * @return whether all the Points are in the same plane with the given normal vector
280 : */
281 : bool isCoPlanar(const std::vector<Point> & vec_pts, const Point plane_nvec);
282 :
283 : /**
284 : * Decides whether all the Points of a vector of Points are coplanar
285 : * @param vec_pts vector of points to be examined
286 : * @return whether all the Points are in a same plane
287 : */
288 : bool isCoPlanar(const std::vector<Point> & vec_pts);
289 :
290 : /**
291 : * Checks input mesh and returns max(block ID) + 1, which represents
292 : * a block ID that is not currently in use in the mesh
293 : * @param input mesh over which to compute the next free block id
294 : */
295 : SubdomainID getNextFreeSubdomainID(MeshBase & input_mesh);
296 :
297 : /**
298 : * Checks input mesh and returns the largest boundary ID in the mesh plus one, which is
299 : * a boundary ID in the mesh that is not currently in use
300 : * @param input mesh over which to compute the next free boundary ID
301 : */
302 : BoundaryID getNextFreeBoundaryID(MeshBase & input_mesh);
303 :
304 : /**
305 : * Whether a particular subdomain ID exists in the mesh
306 : * @param input mesh over which to determine subdomain IDs
307 : * @param subdomain ID
308 : */
309 : bool hasSubdomainID(const MeshBase & input_mesh, const SubdomainID & id);
310 :
311 : /**
312 : * Whether a particular subdomain name exists in the mesh
313 : * @param input mesh over which to determine subdomain names
314 : * @param subdomain name
315 : */
316 : bool hasSubdomainName(const MeshBase & input_mesh, const SubdomainName & name);
317 :
318 : /**
319 : * Whether a particular boundary ID exists in the mesh
320 : * @param input mesh over which to determine boundary IDs
321 : * @param boundary ID
322 : */
323 : bool hasBoundaryID(const MeshBase & input_mesh, const BoundaryID id);
324 :
325 : /**
326 : * Whether a particular boundary name exists in the mesh
327 : * @param input mesh over which to determine boundary names
328 : * @param boundary name
329 : */
330 : bool hasBoundaryName(const MeshBase & input_mesh, const BoundaryName & name);
331 :
332 : /**
333 : * Convert a list of sides in the form of a vector of pairs of node ids into a list of ordered nodes
334 : * based on connectivity
335 : * @param node_assm vector of pairs of node ids that represent the sides
336 : * @param elem_id_list vector of element ids that represent the elements that contain the sides
337 : * @param midpoint_node_list vector of node ids that represent the midpoints of the sides for
338 : * quadratic sides
339 : * @param ordered_node_list vector of node ids that represent the ordered nodes
340 : * @param ordered_elem_id_list vector of element corresponding to the ordered nodes
341 : * */
342 : void makeOrderedNodeList(std::vector<std::pair<dof_id_type, dof_id_type>> & node_assm,
343 : std::vector<dof_id_type> & elem_id_list,
344 : std::vector<dof_id_type> & midpoint_node_list,
345 : std::vector<dof_id_type> & ordered_node_list,
346 : std::vector<dof_id_type> & ordered_elem_id_list);
347 :
348 : /**
349 : * Convert a list of sides in the form of a vector of pairs of node ids into a list of ordered nodes
350 : * based on connectivity
351 : * @param node_assm vector of pairs of node ids that represent the sides
352 : * @param elem_id_list vector of element ids that represent the elements that contain the sides
353 : * @param ordered_node_list vector of node ids that represent the ordered nodes
354 : * @param ordered_elem_id_list vector of element corresponding to the ordered nodes
355 : * */
356 : void makeOrderedNodeList(std::vector<std::pair<dof_id_type, dof_id_type>> & node_assm,
357 : std::vector<dof_id_type> & elem_id_list,
358 : std::vector<dof_id_type> & ordered_node_list,
359 : std::vector<dof_id_type> & ordered_elem_id_list);
360 :
361 : /**
362 : * Converts a given name (BoundaryName or SubdomainName) that is known to only contain digits into a
363 : * corresponding ID (BoundaryID or SubdomainID) and performs bounds checking to ensure that overflow
364 : * doesn't happen.
365 : * @param name Name that is to be converted into an ID.
366 : * @return ID type corresponding to the type of name.
367 : */
368 : template <typename T, typename Q>
369 : Q
370 504055 : getIDFromName(const T & name)
371 : {
372 504055 : if (!MooseUtils::isDigits(name))
373 0 : mooseError(
374 : "'name' ", name, " should only contain digits that can be converted to a numerical type.");
375 504055 : long long id = std::stoll(name);
376 504055 : Q id_Q = Q(id);
377 504055 : if (id < std::numeric_limits<Q>::min() || id > std::numeric_limits<Q>::max())
378 3 : mooseError(MooseUtils::prettyCppType<T>(&name),
379 : " ",
380 : name,
381 : " is not within the numeric limits of the expected ID type ",
382 : MooseUtils::prettyCppType<Q>(&id_Q),
383 : ".");
384 :
385 504052 : return id_Q;
386 : }
387 :
388 : /**
389 : * Swap two nodes within an element
390 : * @param elem element whose nodes need to be swapped
391 : * @param nd1 index of the first node to be swapped
392 : * @param nd2 index of the second node to be swapped
393 : */
394 : void swapNodesInElem(Elem & elem, const unsigned int nd1, const unsigned int nd2);
395 :
396 : /**
397 : * Reprocess the swap related input parameters to make pairs out of them to ease further processing
398 : * @param class_name name of the mesh generator class used for exception messages
399 : * @param id_name name of the parameter to be swapped used for exception messages
400 : * @param id_swaps vector of vectors of the ids to be swapped
401 : * @param id_swap_pairs vector of maps of the swapped pairs
402 : * @param row_index_shift shift to be applied to the row index in the exception messages (useful
403 : * when this method is utilized to process a fraction of a long vector)
404 : */
405 : template <typename T>
406 : void
407 812 : idSwapParametersProcessor(const std::string & class_name,
408 : const std::string & id_name,
409 : const std::vector<std::vector<T>> & id_swaps,
410 : std::vector<std::unordered_map<T, T>> & id_swap_pairs,
411 : const unsigned int row_index_shift = 0)
412 : {
413 812 : id_swap_pairs.resize(id_swaps.size());
414 1241 : for (const auto i : index_range(id_swaps))
415 : {
416 429 : const auto & swaps = id_swaps[i];
417 429 : auto & swap_pairs = id_swap_pairs[i];
418 :
419 429 : if (swaps.size() % 2)
420 0 : throw MooseException("Row ",
421 0 : row_index_shift + i + 1,
422 : " of ",
423 : id_name,
424 : " in ",
425 : class_name,
426 : " does not contain an even number of entries! Num entries: ",
427 0 : swaps.size());
428 :
429 429 : swap_pairs.reserve(swaps.size() / 2);
430 1134 : for (unsigned int j = 0; j < swaps.size(); j += 2)
431 705 : swap_pairs[swaps[j]] = swaps[j + 1];
432 : }
433 812 : }
434 :
435 : /**
436 : * Reprocess the elem_integers_swaps into maps so they are easier to use
437 : * @param class_name name of the mesh generator class used for exception messages
438 : * @param num_sections number of sections in the mesh
439 : * @param num_integers number of extra element integers in the mesh
440 : * @param elem_integers_swaps vector of vectors of vectors of extra element ids to be swapped
441 : * @param elem_integers_swap_pairs vector of maps of the swapped pairs
442 : */
443 : void extraElemIntegerSwapParametersProcessor(
444 : const std::string & class_name,
445 : const unsigned int num_sections,
446 : const unsigned int num_integers,
447 : const std::vector<std::vector<std::vector<dof_id_type>>> & elem_integers_swaps,
448 : std::vector<std::unordered_map<dof_id_type, dof_id_type>> & elem_integers_swap_pairs);
449 :
450 : /**
451 : * Build a lower-dimensional mesh from a boundary of an input mesh
452 : * Note: The lower-dimensional mesh will only have one subdomain and one boundary.
453 : * Error will be thrown if the mesh does not have the boundary.
454 : * This function works only with replicated mesh, for similar functionality with
455 : * distributed meshes, please refer to LowerDBlockFromSidesetGenerator generator.
456 : * @param input_mesh The input mesh
457 : * @param boundary_id The boundary id
458 : */
459 : std::unique_ptr<ReplicatedMesh> buildBoundaryMesh(const MeshBase & input_mesh,
460 : const boundary_id_type boundary_id);
461 :
462 : /**
463 : * Build a loop mesh of edges from the contiguous 2D boundary of 2D input mesh
464 : * Note: The lower-dimensional mesh will only have one subdomain.
465 : * An error will be thrown if the mesh does not have the boundary.
466 : * Note: currently, the boundary_id must be a nodeset!
467 : * @param input_mesh The input mesh
468 : * @param boundary_id The boundary id
469 : */
470 : std::unique_ptr<ReplicatedMesh> buildLoopBoundaryOf2DMesh(const MeshBase & input_mesh,
471 : const boundary_id_type boundary_id);
472 :
473 : /**
474 : * Build a map from the node ids to all element ids they are part of for the nodes on a particular
475 : * nodeset
476 : * @param input_mesh The input mesh to get the map for
477 : * @param boundary_id The boundary id of interest
478 : */
479 : std::unordered_map<dof_id_type, std::unordered_set<dof_id_type>>
480 : buildBoundaryNodeToElemMap(const MeshBase & input_mesh, const boundary_id_type boundary_id);
481 :
482 : /**
483 : * Get all the nodes on that particular boundary, whether a nodeset or a sideset.
484 : * Note: if the mesh has both a nodeset and a sideset with the same ID, they will both be considered
485 : * If this is undesirable, renumber one of them prior to calling this routine
486 : * @param input_mesh The input mesh to get the map for
487 : * @param boundary_id The boundary id of interest
488 : */
489 : std::set<dof_id_type> getBoundaryNodes(const MeshBase & mesh, const BoundaryID boundary_id);
490 :
491 : /**
492 : * Create a new subdomain by generating new side elements from a list of sidesets in a given mesh.
493 : * @param mesh The mesh to work on
494 : * @param boundary_names The names of the sidesets to be used to create the new subdomain
495 : * @param new_subdomain_id The ID of the new subdomain to be created based on the sidesets
496 : * @param new_subdomain_name The name of the new subdomain to be created based on the sidesets
497 : * @param type_name The type of the mesh generator that is calling this method, used for error
498 : * messages and debugging purposes.
499 : */
500 : void createSubdomainFromSidesets(MeshBase & mesh,
501 : std::vector<BoundaryName> boundary_names,
502 : const SubdomainID new_subdomain_id,
503 : const SubdomainName new_subdomain_name,
504 : const std::string type_name);
505 :
506 : /**
507 : * Convert a list of blocks in a given mesh to a standalone new mesh.
508 : * @param source_mesh The source mesh from which the blocks will be converted
509 : * @param target_mesh The target mesh to which the blocks will be converted
510 : * @param target_blocks The names of the blocks to be converted to the target mesh
511 : */
512 : void convertBlockToMesh(MeshBase & source_mesh,
513 : MeshBase & target_mesh,
514 : const std::vector<SubdomainName> & target_blocks);
515 :
516 : /**
517 : * Helper function for copying one mesh into another
518 : * @param mg The mesh generator calling this function
519 : * @param destination The mesh to copy into
520 : * @param source The mesh to copy from
521 : * @param avoid_merging_subdomains If true, subdomain IDs in the source mesh will
522 : * be offset to avoid merging with subdomain IDs in the destination mesh
523 : * @param avoid_merging_boundaries If true, boundary IDs in the source mesh will
524 : * be offset to avoid merging with boundary IDs in the destination mesh
525 : * @param communicator The communicator for parallel operations
526 : */
527 : void copyIntoMesh(MeshGenerator & mg,
528 : UnstructuredMesh & destination,
529 : const UnstructuredMesh & source,
530 : const bool avoid_merging_subdomains,
531 : const bool avoid_merging_boundaries,
532 : const Parallel::Communicator & communicator);
533 :
534 : /**
535 : * Generates meshes from edges connecting a list of points.
536 : * @param mesh The mesh to be built
537 : * @param points The list of points defining the polyline
538 : * @param loop Whether the polyline is a closed loop
539 : * @param start_boundary The boundary name to assign to the start of the polyline (if
540 : * not a loop)
541 : * @param end_boundary The boundary name to assign to the end of the polyline (if
542 : * not a loop)
543 : * @param nums_edges_between_points The numbers of edges to create between each pair of points
544 : * (if only one number is given, it is used for all point pairs)
545 : */
546 : void buildPolyLineMesh(MeshBase & mesh,
547 : const std::vector<Point> & points,
548 : const bool loop,
549 : const BoundaryName & start_boundary,
550 : const BoundaryName & end_boundary,
551 : const std::vector<unsigned int> & nums_edges_between_points);
552 :
553 : /**
554 : * Generates meshes from edges connecting a list of points.
555 : * @param mesh The mesh to be built
556 : * @param points The list of points defining the polyline
557 : * @param loop Whether the polyline is a closed loop
558 : * @param start_boundary The boundary name to assign to the start of the polyline (if
559 : * not a loop)
560 : * @param end_boundary The boundary name to assign to the end of the polyline (if
561 : * not a loop)
562 : * @param max_elem_size The maximum element size for the mesh
563 : */
564 : void buildPolyLineMesh(MeshBase & mesh,
565 : const std::vector<Point> & points,
566 : const bool loop,
567 : const BoundaryName & start_boundary,
568 : const BoundaryName & end_boundary,
569 : const Real max_elem_size);
570 :
571 : /**
572 : * Adds a sideset for the external boundary of the mesh (e.g. all element sides with no neighbors)
573 : * @param mesh the mesh to modify
574 : * @param extern_bid the ID to assign to the external boundary
575 : * @param has_external_bid false if all elements of the mesh are internal (for example a sphere
576 : * shell)
577 : */
578 : void addExternalBoundary(MeshBase & mesh, const BoundaryID extern_bid, bool & has_external_bid);
579 : }
|