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 26606 : 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 1888988865 : 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 1888988865 : switch (coord_type)
177 : {
178 1886372918 : case Moose::COORD_XYZ:
179 1886372918 : factor = 1.0;
180 1886372918 : break;
181 2583135 : case Moose::COORD_RZ:
182 : {
183 : mooseAssert(rz_radial_coord != libMesh::invalid_uint,
184 : "Must pass in a valid rz radial coordinate");
185 2583135 : factor = 2 * M_PI * point(rz_radial_coord);
186 2583135 : break;
187 : }
188 32812 : case Moose::COORD_RSPHERICAL:
189 32812 : factor = 4 * M_PI * point(0) * point(0);
190 32812 : break;
191 0 : default:
192 0 : mooseError("Unknown coordinate system");
193 : }
194 1888988865 : }
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 1041955 : computeDistanceToAxis(const P & point, const Point & origin, const RealVectorValue & direction)
206 : {
207 1041955 : 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 1041955 : coordTransformFactorRZGeneral(const P & point,
232 : const std::pair<Point, RealVectorValue> & axis,
233 : C & factor)
234 : {
235 1041955 : factor = 2 * M_PI * computeDistanceToAxis<P, C>(point, axis.first, axis.second);
236 1041955 : }
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 : *
328 : * This returns true if \c name is non-empty and is a name (not ID) that exists.
329 : *
330 : * @param mesh mesh over which to determine boundary names
331 : * @param name boundary name
332 : */
333 : bool hasBoundaryName(const MeshBase & mesh, const BoundaryName & name);
334 :
335 : /**
336 : * Whether a particular boundary name or ID exists in the mesh.
337 : *
338 : * This returns true if \c name_or_id is non-empty and either a name or ID that exists.
339 : *
340 : * @param mesh mesh over which to determine boundary names
341 : * @param name_or_id boundary name or ID
342 : */
343 : bool hasBoundaryNameOrID(const MeshBase & mesh, const BoundaryName & name_or_id);
344 :
345 : /**
346 : * Convert a list of sides in the form of a vector of pairs of node ids into a list of ordered nodes
347 : * based on connectivity
348 : * @param node_assm vector of pairs of node ids that represent the sides
349 : * @param elem_id_list vector of element ids that represent the elements that contain the sides
350 : * @param midpoint_node_list vector of node ids that represent the midpoints of the sides for
351 : * quadratic sides
352 : * @param ordered_node_list vector of node ids that represent the ordered nodes
353 : * @param ordered_elem_id_list vector of element corresponding to the ordered nodes
354 : * */
355 : void makeOrderedNodeList(std::vector<std::pair<dof_id_type, dof_id_type>> & node_assm,
356 : std::vector<dof_id_type> & elem_id_list,
357 : std::vector<dof_id_type> & midpoint_node_list,
358 : std::vector<dof_id_type> & ordered_node_list,
359 : std::vector<dof_id_type> & ordered_elem_id_list);
360 :
361 : /**
362 : * Convert a list of sides in the form of a vector of pairs of node ids into a list of ordered nodes
363 : * based on connectivity
364 : * @param node_assm vector of pairs of node ids that represent the sides
365 : * @param elem_id_list vector of element ids that represent the elements that contain the sides
366 : * @param ordered_node_list vector of node ids that represent the ordered nodes
367 : * @param ordered_elem_id_list vector of element corresponding to the ordered nodes
368 : * */
369 : void makeOrderedNodeList(std::vector<std::pair<dof_id_type, dof_id_type>> & node_assm,
370 : std::vector<dof_id_type> & elem_id_list,
371 : std::vector<dof_id_type> & ordered_node_list,
372 : std::vector<dof_id_type> & ordered_elem_id_list);
373 :
374 : /**
375 : * Converts a given name (BoundaryName or SubdomainName) that is known to only contain digits into a
376 : * corresponding ID (BoundaryID or SubdomainID) and performs bounds checking to ensure that overflow
377 : * doesn't happen.
378 : * @param name Name that is to be converted into an ID.
379 : * @return ID type corresponding to the type of name.
380 : */
381 : template <typename T, typename Q>
382 : Q
383 504123 : getIDFromName(const T & name)
384 : {
385 504123 : if (!MooseUtils::isDigits(name))
386 0 : mooseError(
387 : "'name' ", name, " should only contain digits that can be converted to a numerical type.");
388 504123 : long long id = std::stoll(name);
389 504123 : Q id_Q = Q(id);
390 504123 : if (id < std::numeric_limits<Q>::min() || id > std::numeric_limits<Q>::max())
391 3 : mooseError(MooseUtils::prettyCppType<T>(&name),
392 : " ",
393 : name,
394 : " is not within the numeric limits of the expected ID type ",
395 : MooseUtils::prettyCppType<Q>(&id_Q),
396 : ".");
397 :
398 504120 : return id_Q;
399 : }
400 :
401 : /**
402 : * Swap two nodes within an element
403 : * @param elem element whose nodes need to be swapped
404 : * @param nd1 index of the first node to be swapped
405 : * @param nd2 index of the second node to be swapped
406 : */
407 : void swapNodesInElem(Elem & elem, const unsigned int nd1, const unsigned int nd2);
408 :
409 : /**
410 : * Reprocess the swap related input parameters to make pairs out of them to ease further processing
411 : * @param class_name name of the mesh generator class used for exception messages
412 : * @param id_name name of the parameter to be swapped used for exception messages
413 : * @param id_swaps vector of vectors of the ids to be swapped
414 : * @param id_swap_pairs vector of maps of the swapped pairs
415 : * @param row_index_shift shift to be applied to the row index in the exception messages (useful
416 : * when this method is utilized to process a fraction of a long vector)
417 : */
418 : template <typename T>
419 : void
420 812 : idSwapParametersProcessor(const std::string & class_name,
421 : const std::string & id_name,
422 : const std::vector<std::vector<T>> & id_swaps,
423 : std::vector<std::unordered_map<T, T>> & id_swap_pairs,
424 : const unsigned int row_index_shift = 0)
425 : {
426 812 : id_swap_pairs.resize(id_swaps.size());
427 1241 : for (const auto i : index_range(id_swaps))
428 : {
429 429 : const auto & swaps = id_swaps[i];
430 429 : auto & swap_pairs = id_swap_pairs[i];
431 :
432 429 : if (swaps.size() % 2)
433 0 : throw MooseException("Row ",
434 0 : row_index_shift + i + 1,
435 : " of ",
436 : id_name,
437 : " in ",
438 : class_name,
439 : " does not contain an even number of entries! Num entries: ",
440 0 : swaps.size());
441 :
442 429 : swap_pairs.reserve(swaps.size() / 2);
443 1134 : for (unsigned int j = 0; j < swaps.size(); j += 2)
444 705 : swap_pairs[swaps[j]] = swaps[j + 1];
445 : }
446 812 : }
447 :
448 : /**
449 : * Reprocess the elem_integers_swaps into maps so they are easier to use
450 : * @param class_name name of the mesh generator class used for exception messages
451 : * @param num_sections number of sections in the mesh
452 : * @param num_integers number of extra element integers in the mesh
453 : * @param elem_integers_swaps vector of vectors of vectors of extra element ids to be swapped
454 : * @param elem_integers_swap_pairs vector of maps of the swapped pairs
455 : */
456 : void extraElemIntegerSwapParametersProcessor(
457 : const std::string & class_name,
458 : const unsigned int num_sections,
459 : const unsigned int num_integers,
460 : const std::vector<std::vector<std::vector<dof_id_type>>> & elem_integers_swaps,
461 : std::vector<std::unordered_map<dof_id_type, dof_id_type>> & elem_integers_swap_pairs);
462 :
463 : /**
464 : * Build a lower-dimensional mesh from a boundary of an input mesh
465 : * Note: The lower-dimensional mesh will only have one subdomain and one boundary.
466 : * Error will be thrown if the mesh does not have the boundary.
467 : * This function works only with replicated mesh, for similar functionality with
468 : * distributed meshes, please refer to LowerDBlockFromSidesetGenerator generator.
469 : * @param input_mesh The input mesh
470 : * @param boundary_id The boundary id
471 : */
472 : std::unique_ptr<ReplicatedMesh> buildBoundaryMesh(const MeshBase & input_mesh,
473 : const boundary_id_type boundary_id);
474 :
475 : /**
476 : * Build a loop mesh of edges from the contiguous 2D boundary of 2D input mesh
477 : * Note: The lower-dimensional mesh will only have one subdomain.
478 : * An error will be thrown if the mesh does not have the boundary.
479 : * Note: currently, the boundary_id must be a nodeset!
480 : * @param input_mesh The input mesh
481 : * @param boundary_id The boundary id
482 : */
483 : std::unique_ptr<ReplicatedMesh> buildLoopBoundaryOf2DMesh(const MeshBase & input_mesh,
484 : const boundary_id_type boundary_id);
485 :
486 : /**
487 : * Build a map from the node ids to all element ids they are part of for the nodes on a particular
488 : * nodeset
489 : * @param input_mesh The input mesh to get the map for
490 : * @param boundary_id The boundary id of interest
491 : */
492 : std::unordered_map<dof_id_type, std::unordered_set<dof_id_type>>
493 : buildBoundaryNodeToElemMap(const MeshBase & input_mesh, const boundary_id_type boundary_id);
494 :
495 : /**
496 : * Get all the nodes on that particular boundary, whether a nodeset or a sideset.
497 : * Note: if the mesh has both a nodeset and a sideset with the same ID, they will both be considered
498 : * If this is undesirable, renumber one of them prior to calling this routine
499 : * @param input_mesh The input mesh to get the map for
500 : * @param boundary_id The boundary id of interest
501 : */
502 : std::set<dof_id_type> getBoundaryNodes(const MeshBase & mesh, const BoundaryID boundary_id);
503 :
504 : /**
505 : * Create a new subdomain by generating new side elements from a list of sidesets in a given mesh.
506 : * @param mesh The mesh to work on
507 : * @param boundary_names The names of the sidesets to be used to create the new subdomain
508 : * @param new_subdomain_id The ID of the new subdomain to be created based on the sidesets
509 : * @param new_subdomain_name The name of the new subdomain to be created based on the sidesets
510 : * @param type_name The type of the mesh generator that is calling this method, used for error
511 : * messages and debugging purposes.
512 : */
513 : void createSubdomainFromSidesets(MeshBase & mesh,
514 : std::vector<BoundaryName> boundary_names,
515 : const SubdomainID new_subdomain_id,
516 : const SubdomainName new_subdomain_name,
517 : const std::string type_name);
518 :
519 : /**
520 : * Convert a list of blocks in a given mesh to a standalone new mesh.
521 : * @param source_mesh The source mesh from which the blocks will be converted
522 : * @param target_mesh The target mesh to which the blocks will be converted
523 : * @param target_blocks The names of the blocks to be converted to the target mesh
524 : */
525 : void convertBlockToMesh(MeshBase & source_mesh,
526 : MeshBase & target_mesh,
527 : const std::vector<SubdomainName> & target_blocks);
528 :
529 : /**
530 : * Helper function for copying one mesh into another
531 : * @param mg The mesh generator calling this function
532 : * @param destination The mesh to copy into
533 : * @param source The mesh to copy from
534 : * @param avoid_merging_subdomains If true, subdomain IDs in the source mesh will
535 : * be offset to avoid merging with subdomain IDs in the destination mesh
536 : * @param avoid_merging_boundaries If true, boundary IDs in the source mesh will
537 : * be offset to avoid merging with boundary IDs in the destination mesh
538 : * @param communicator The communicator for parallel operations
539 : */
540 : void copyIntoMesh(MeshGenerator & mg,
541 : UnstructuredMesh & destination,
542 : const UnstructuredMesh & source,
543 : const bool avoid_merging_subdomains,
544 : const bool avoid_merging_boundaries,
545 : const Parallel::Communicator & communicator);
546 :
547 : /**
548 : * Generates meshes from edges connecting a list of points.
549 : * @param mesh The mesh to be built
550 : * @param points The list of points defining the polyline
551 : * @param loop Whether the polyline is a closed loop
552 : * @param start_boundary The boundary name to assign to the start of the polyline (if
553 : * not a loop)
554 : * @param end_boundary The boundary name to assign to the end of the polyline (if
555 : * not a loop)
556 : * @param nums_edges_between_points The numbers of edges to create between each pair of points
557 : * (if only one number is given, it is used for all point pairs)
558 : */
559 : void buildPolyLineMesh(MeshBase & mesh,
560 : const std::vector<Point> & points,
561 : const bool loop,
562 : const BoundaryName & start_boundary,
563 : const BoundaryName & end_boundary,
564 : const std::vector<unsigned int> & nums_edges_between_points);
565 :
566 : /**
567 : * Generates meshes from edges connecting a list of points, with optional midpoints to produce
568 : * Edge3 elements so as to enable quadratic meshing. If mid_points is empty, Edge2 elements are
569 : * produced.
570 : * @param mesh The mesh to be built
571 : * @param points The list of points defining the polyline
572 : * @param mid_points The optional list of midpoints corresponding to the segments for quadratic
573 : * elements. if provided, it must contains exactly one midpoint per segment and
574 : * nums_edges_between_points must be unity for every segment.
575 : * @param loop Whether the polyline is a closed loop
576 : * @param start_boundary The boundary name to assign to the start of the polyline (if
577 : * not a loop)
578 : * @param end_boundary The boundary name to assign to the end of the polyline (if
579 : * not a loop)
580 : * @param nums_edges_between_points The numbers of edges to create between each pair of points
581 : * (if only one number is given, it is used for all point pairs)
582 : */
583 : void buildPolyLineMesh(MeshBase & mesh,
584 : const std::vector<Point> & points,
585 : const std::vector<Point> & mid_points,
586 : const bool loop,
587 : const BoundaryName & start_boundary,
588 : const BoundaryName & end_boundary,
589 : const std::vector<unsigned int> & nums_edges_between_points);
590 :
591 : /**
592 : * Generates meshes from edges connecting a list of points. Note that we do not support
593 : * max_elem_size and quadratic mid points at the same time as we cannot pre-determine the number of
594 : * mid points needed for quadratic elements when max_elem_size is specified.
595 : * @param mesh The mesh to be built
596 : * @param points The list of points defining the polyline
597 : * @param loop Whether the polyline is a closed loop
598 : * @param start_boundary The boundary name to assign to the start of the polyline (if
599 : * not a loop)
600 : * @param end_boundary The boundary name to assign to the end of the polyline (if
601 : * not a loop)
602 : * @param max_elem_size The maximum element size for the mesh
603 : */
604 : void buildPolyLineMesh(MeshBase & mesh,
605 : const std::vector<Point> & points,
606 : const bool loop,
607 : const BoundaryName & start_boundary,
608 : const BoundaryName & end_boundary,
609 : const Real max_elem_size);
610 :
611 : /**
612 : * Adds a sideset for the external boundary of the mesh (e.g. all element sides with no neighbors)
613 : * @param mesh the mesh to modify
614 : * @param extern_bid the ID to assign to the external boundary
615 : * @param has_external_bid false if all elements of the mesh are internal (for example a sphere
616 : * shell)
617 : */
618 : void addExternalBoundary(MeshBase & mesh, const BoundaryID extern_bid, bool & has_external_bid);
619 : }
|