16 #include "libmesh/boundary_info.h" 17 #include "libmesh/function_base.h" 18 #include "libmesh/cell_prism6.h" 19 #include "libmesh/cell_prism18.h" 20 #include "libmesh/cell_prism21.h" 21 #include "libmesh/cell_hex8.h" 22 #include "libmesh/cell_hex20.h" 23 #include "libmesh/cell_hex27.h" 24 #include "libmesh/cell_c0polyhedron.h" 25 #include "libmesh/edge_edge2.h" 26 #include "libmesh/edge_edge3.h" 27 #include "libmesh/edge_edge4.h" 28 #include "libmesh/face_quad4.h" 29 #include "libmesh/face_quad8.h" 30 #include "libmesh/face_quad9.h" 31 #include "libmesh/face_tri3.h" 32 #include "libmesh/face_tri6.h" 33 #include "libmesh/face_tri7.h" 34 #include "libmesh/face_c0polygon.h" 35 #include "libmesh/libmesh_logging.h" 36 #include "libmesh/mesh_communication.h" 37 #include "libmesh/mesh_modification.h" 38 #include "libmesh/mesh_serializer.h" 39 #include "libmesh/mesh_tools.h" 40 #include "libmesh/parallel.h" 41 #include "libmesh/remote_elem.h" 42 #include "libmesh/string_to_enum.h" 43 #include "libmesh/unstructured_mesh.h" 44 #include "libmesh/point.h" 51 FancyExtruderGenerator,
61 "Extrudes a 1D mesh into 2D, or a 2D mesh into 3D, and supports a variable height for each " 62 "elevation, variable number of layers within each elevation, variable growth factors of " 63 "axial element sizes within each elevation and remap subdomain_ids, boundary_ids and element " 64 "extra integers within each elevation as well as interface boundaries between neighboring " 65 "elevation layers, as well as following a 1D curve and modifying the radial (normal to " 66 "the extrusion axis) extent of the geometry.");
71 params.
addParam<std::vector<Real>>(
"heights", {},
"The height of each elevation");
73 "biases",
"biases>0.0",
"The axial growth factor used for mesh biasing for each elevation.");
74 params.
addParam<std::vector<unsigned int>>(
77 "The number of layers for each elevation - must be num_elevations in length!");
80 params.
addParam<std::vector<std::vector<subdomain_id_type>>>(
83 "For each row, every two entries are interpreted as a pair of " 84 "'from' and 'to' to remap the subdomains for that elevation");
85 params.
addParam<std::vector<std::vector<boundary_id_type>>>(
88 "For each row, every two entries are interpreted as a pair of " 89 "'from' and 'to' to remap the boundaries for that elevation");
90 params.
addParam<std::vector<std::string>>(
91 "elem_integer_names_to_swap",
93 "Array of element extra integer names that need to be swapped during extrusion.");
94 params.
addParam<std::vector<std::vector<std::vector<dof_id_type>>>>(
95 "elem_integers_swaps",
97 "For each row, every two entries are interpreted as a pair of 'from' and 'to' to remap the " 98 "element extra integer for that elevation. If multiple element extra integers need to be " 99 "swapped, the enties are stacked based on the order provided in " 100 "'elem_integer_names_to_swap' to form the third dimension.");
104 "A vector that points in the direction to extrude (note, this will be " 105 "normalized internally - so don't worry about it here)");
108 "Name of the mesh generator providing the line mesh curve to be extruded along. The " 109 "extrusion path follows the node order in the line mesh");
111 "start_extrusion_direction",
112 "A vector that points in the starting direction for extruding along a curve. This vector " 113 "should be the tangent vector at the FIRST node of the extrusion curve. Vector will be " 114 "normalized in code, so don't worry about it here.");
116 "end_extrusion_direction",
117 "A vector that points in the ending direction for extruding along a curve. This vector " 118 "should be the tangent vector at the LAST node of the extrusion curve. Vector will be " 119 "normalized in code, so don't worry about it here.");
124 "The boundary name to set on the top boundary. If omitted an ID will be generated.");
127 "The boundary name to set on the bottom boundary. If omitted an ID will be generated.");
128 params.
addParam<std::vector<std::vector<subdomain_id_type>>>(
129 "upward_boundary_source_blocks",
"Block ids used to generate upward interface boundaries.");
130 params.
addParam<std::vector<std::vector<boundary_id_type>>>(
"upward_boundary_ids",
131 "Upward interface boundary ids.");
132 params.
addParam<std::vector<std::vector<subdomain_id_type>>>(
133 "downward_boundary_source_blocks",
134 "Block ids used to generate downward interface boundaries.");
135 params.
addParam<std::vector<std::vector<boundary_id_type>>>(
"downward_boundary_ids",
136 "Downward interface boundary ids.");
141 "Pitch for helicoidal extrusion around an axis going through the origin " 142 "following the direction vector");
145 "If modifying the radial extent of the extruded geometry, final radial " 146 "extent to reach at the end of the extrusion process");
147 MooseEnum radial_growth_methods(
"linear cubic",
"linear");
149 radial_growth_methods,
150 "Functional form to change radius while extruding along curve.");
151 params.
addParam<
Real>(
"start_radial_growth_rate", 1.,
"Starting rate of radial expansion.");
152 params.
addParam<
Real>(
"end_radial_growth_rate", 1.,
"Ending rate of radial expansion.");
155 "top_boundary bottom_boundary upward_boundary_source_blocks upward_boundary_ids " 156 "downward_boundary_source_blocks downward_boundary_ids",
157 "Boundary Assignment");
159 "subdomain_swaps boundary_swaps elem_integer_names_to_swap elem_integers_swaps",
"ID Swap");
160 params.
addParamNamesToGroup(
"extrusion_curve start_extrusion_direction end_extrusion_direction",
161 "Extrusion along curve");
163 "start_radial_growth_rate end_radial_growth_rate",
164 "Radial transformation");
171 _input(getMesh(
"input")),
172 _heights(getParam<
std::vector<
Real>>(
"heights")),
173 _biases(isParamValid(
"biases") ? getParam<
std::vector<
Real>>(
"biases")
174 :
std::vector<
Real>(_heights.size(), 1.0)),
175 _num_layers(getParam<
std::vector<unsigned
int>>(
"num_layers")),
178 _elem_integer_names_to_swap(getParam<
std::vector<
std::string>>(
"elem_integer_names_to_swap")),
179 _elem_integers_swaps(
181 _direction(isParamValid(
"direction") ? getParam<Point>(
"direction") : Point(0, 0, 0)),
182 _extrusion_curve(getMesh(
"extrusion_curve", true)),
183 _start_extrusion_direction(isParamValid(
"start_extrusion_direction")
186 _end_extrusion_direction(isParamValid(
"end_extrusion_direction")
189 _extrude_along_curve(isParamValid(
"extrusion_curve")),
190 _has_top_boundary(isParamValid(
"top_boundary")),
191 _top_boundary(isParamValid(
"top_boundary") ? getParam<BoundaryName>(
"top_boundary") :
"0"),
192 _has_bottom_boundary(isParamValid(
"bottom_boundary")),
193 _bottom_boundary(isParamValid(
"bottom_boundary") ? getParam<BoundaryName>(
"bottom_boundary")
195 _upward_boundary_source_blocks(
196 isParamValid(
"upward_boundary_source_blocks")
200 _upward_boundary_ids(
201 isParamValid(
"upward_boundary_ids")
205 _downward_boundary_source_blocks(isParamValid(
"downward_boundary_source_blocks")
207 "downward_boundary_source_blocks")
210 _downward_boundary_ids(
211 isParamValid(
"downward_boundary_ids")
215 _twist_pitch(getParam<
Real>(
"twist_pitch")),
216 _end_radial_extent(getParam<
Real>(
"end_radial_extent")),
217 _radial_expansion_method(getParam<
MooseEnum>(
"radial_growth_method")),
218 _start_radial_growth_rate(getParam<
Real>(
"start_radial_growth_rate")),
219 _end_radial_growth_rate(getParam<
Real>(
"end_radial_growth_rate"))
224 paramError(
"heights",
"heights cannot be set if extruding along curve!");
226 paramError(
"biases",
"biases cannot be set if extruding along curve!");
228 paramError(
"num_layers",
"num_layers cannot be set if extruding along curve!");
230 paramError(
"direction",
"direction cannot be set if extruding along curve!");
235 paramError(
"direction",
"Must have some length!");
239 unsigned int num_elevations;
247 "heights",
"The length of 'heights' and 'num_layers' must be the same in ",
name());
254 "If specified, 'subdomain_swaps' (" + std::to_string(
_subdomain_swaps.size()) +
255 ") must be equal to 1 when extruding along a curve.");
259 "If specified, 'subdomain_swaps' (" + std::to_string(
_subdomain_swaps.size()) +
260 ") must be the same length as 'heights' (" + std::to_string(num_elevations) +
281 "If specified, 'boundary_swaps' (" + std::to_string(
_boundary_swaps.size()) +
282 ") must be the same length as 'heights' (" + std::to_string(num_elevations) +
289 "If specified, 'boundary_swaps' (" + std::to_string(
_boundary_swaps.size()) +
290 ") must be equal to 1 when extruding along a curve.");
307 "If specified, 'elem_integers_swaps' must have the same length as the length of " 308 "'elem_integer_names_to_swap'.");
311 if (unit_elem_integers_swaps.size() != num_elevations)
313 "If specified, each element of 'elem_integers_swaps' must have the same length as " 314 "the length of 'heights'.");
331 bool has_negative_entry =
false;
332 bool has_positive_entry =
false;
336 has_positive_entry =
true;
338 has_negative_entry =
true;
341 if (has_negative_entry && has_positive_entry)
342 paramError(
"heights",
"Cannot have both positive and negative heights!");
344 paramError(
"biases",
"Size of this parameter, if provided, must be the same as heights.");
353 "upward_boundary_ids",
354 "This parameter must have the same length (" +
357 std::to_string(num_elevations) +
358 "). Note that the number of heights is set to 1 when extruding along a curve.");
362 "This parameter must have the same length (" +
364 ") as upward_boundary_source_blocks (" +
366 std::to_string(num_elevations) +
")");
373 "Every element of this parameter must have the same length as the corresponding " 374 "element of upward_boundary_source_blocks.");
382 "downward_boundary_ids",
383 "This parameter must have the same length (" +
385 ") as downward_boundary_source_blocks (" +
387 std::to_string(num_elevations) +
388 "). Note that the number of heights is set to 1 when extruding along a curve.");
392 "This parameter must have the same length (" +
394 ") as downward_boundary_source_blocks (" +
396 std::to_string(num_elevations) +
")");
402 "Every element of this parameter must have the same length as the corresponding " 403 "element of downward_boundary_source_blocks.");
406 std::unique_ptr<MeshBase>
414 mesh->set_mesh_dimension(
_input->mesh_dimension() + 1);
425 " of 'elem_integer_names_to_swap' in is not a valid extra element integer of the " 429 const unsigned int num_extra_elem_integers =
_input->n_elem_integers();
430 std::vector<std::string> id_names;
432 for (
unsigned int i = 0; i < num_extra_elem_integers; i++)
434 id_names.push_back(
_input->get_elem_integer_name(i));
435 if (!
mesh->has_elem_integer(id_names[i]))
436 mesh->add_elem_integer(id_names[i]);
440 if (!
_input->preparation().has_cached_elem_data)
441 _input->cache_elem_data();
442 const auto & input_subdomain_map =
_input->get_subdomain_name_map();
443 const auto & input_sideset_map =
_input->get_boundary_info().get_sideset_name_map();
444 const auto & input_nodeset_map =
_input->get_boundary_info().get_nodeset_name_map();
450 paramError(
"subdomain_swaps",
"The block '",
swap[i],
"' was not found within the mesh");
456 paramError(
"boundary_swaps",
"The boundary '",
swap[i],
"' was not found within the mesh");
460 for (
const auto bid : layer_vec)
463 "upward_boundary_source_blocks",
"The block '", bid,
"' was not found within the mesh");
465 for (
const auto bid : layer_vec)
470 "' was not found within the mesh");
473 std::unique_ptr<MeshBase> input = std::move(
_input);
474 std::unique_ptr<MeshBase> extrusion_curve;
479 std::unique_ptr<libMesh::MeshSerializer> serializer;
481 serializer = std::make_unique<libMesh::MeshSerializer>(*extrusion_curve);
485 if (!input->is_serial())
487 input->delete_remote_elements();
489 mesh->delete_remote_elements();
492 if (input->n_nodes() != input->max_node_id())
493 input->renumber_nodes_and_elements();
495 if (input->n_nodes() != input->max_node_id())
497 "You must allow renumbering, because the extruded mesh should be contiguously numbered. " 498 "Alternatively, you can use a separate mesh generator (MeshRepairGenerator with the " 499 "renumber_contiguously parameter for example) to renumber the nodes contiguously.");
501 unsigned int total_num_layers;
502 unsigned int total_num_elevations;
506 total_num_elevations =
_heights.size();
510 total_num_layers = extrusion_curve->n_elem();
511 total_num_elevations = 1;
517 #ifdef LIBMESH_ENABLE_UNIQUE_ID 519 bool has_poly_midnodes =
false;
522 bool has_polygons =
false;
523 unsigned int order = 1;
525 BoundaryInfo & boundary_info =
mesh->get_boundary_info();
526 const BoundaryInfo & input_boundary_info = input->get_boundary_info();
529 std::vector<BoundaryName> new_boundary_names;
534 std::vector<boundary_id_type> new_boundary_ids =
536 const auto user_bottom_boundary_id =
538 const auto user_top_boundary_id =
542 mesh->reserve_elem(total_num_layers * orig_elem);
546 bool extruding_quad_eights =
false;
547 std::vector<ElemType> types;
548 MeshTools::elem_types(*input, types);
549 for (
const auto elem_type : types)
551 if (higher_orders.count(elem_type))
553 if (elem_type ==
QUAD8)
554 extruding_quad_eights =
true;
556 mesh->comm().max(order);
557 mesh->comm().max(extruding_quad_eights);
560 mesh->reserve_nodes((order * total_num_layers + 1) * orig_nodes);
563 std::vector<boundary_id_type> ids_to_copy;
566 Real start_radial_extent = 0;
567 Point reference_point;
569 reference_point = *(extrusion_curve->node_ptr(0));
570 else if (!MooseUtils::absoluteFuzzyEqual(
_twist_pitch, 0.))
572 reference_point = Point(0, 0, 0);
582 reference_direction =
586 (*(extrusion_curve->node_ptr(1)) - *(extrusion_curve->node_ptr(0))).unit());
591 start_radial_extent =
596 Real total_extrusion_distance_at_axis;
599 if (!extrusion_curve->is_prepared())
600 extrusion_curve->prepare_for_use();
601 total_extrusion_distance_at_axis = MeshTools::volume(*extrusion_curve);
604 total_extrusion_distance_at_axis = std::accumulate(
_heights.begin(),
_heights.end(), 0);
607 for (
const auto & node : input->node_ptr_range())
609 unsigned int current_node_layer = 0;
610 Point orig_node_to_previous;
611 Point orig_node_to_current;
612 Real sum_step_sizes = 0.;
613 Real sum_step_sizes_at_axis = 0.;
615 Real start_node_radius = (*node - reference_point).
norm();
618 for (
const auto e :
make_range(total_num_elevations))
624 num_layers = extrusion_curve->n_elem();
634 unsigned int num_heights_at_elevation = order * num_layers + (e == 0 ? 1 : 0);
639 for (
const auto k :
make_range(num_heights_at_elevation))
643 if (e == 0 && k == 0)
644 orig_node_to_current.
zero();
652 Real step_size_at_axis = 0;
656 const Node * P_current = extrusion_curve->node_ptr(k);
658 const Node * P_prev = extrusion_curve->node_ptr(k - 1);
661 const auto old_node = orig_node_to_previous + *node;
663 Real node_distance_to_curve = b_vec.
norm();
674 const auto P_next = extrusion_curve->node_ptr(k + 1);
675 intersecting_plane_normal_vec =
678 else if (k < order * num_layers - 1)
680 const auto P_next = extrusion_curve->node_ptr(k + 1);
682 intersecting_plane_normal_vec = *P_next - *P_prev;
690 intersecting_plane_normal_vec /= intersecting_plane_normal_vec.
norm();
692 Point new_node_point;
695 if (MooseUtils::absoluteFuzzyEqual(
696 prev_intersecting_plane_normal_vec.cross(intersecting_plane_normal_vec)
699 new_node_point = old_node + *P_current - *P_prev;
707 auto axis = prev_intersecting_plane_normal_vec.cross(intersecting_plane_normal_vec);
708 const auto sin_th = axis.norm();
710 Real cos_th = prev_intersecting_plane_normal_vec * intersecting_plane_normal_vec;
712 const auto new_v = cos_th * b_vec + axis.
cross(b_vec) * sin_th +
713 axis * (axis * b_vec) * (1. - cos_th);
715 mooseAssert(MooseUtils::absoluteFuzzyEqual(new_v.norm(), b_vec.
norm()),
716 "Radial extent be conserved");
717 new_node_point = *P_current + new_v;
720 orig_node_to_current = new_node_point - *node;
722 step_size = (orig_node_to_current - orig_node_to_previous).
norm();
723 step_size_at_axis = (*P_current - *P_prev).
norm();
724 prev_intersecting_plane_normal_vec = intersecting_plane_normal_vec;
732 "Norm of direction vector is not 1!");
737 step_size = ((*P_current - (orig_node_to_previous + *node)) *
_direction);
738 step_size_at_axis = step_size;
739 orig_node_to_current = orig_node_to_previous +
_direction * step_size;
747 auto layer_index = (k - (e == 0 ? 1 : 0)) / order + 1;
748 step_size = MooseUtils::absoluteFuzzyEqual(bias, 1.0)
749 ? height / (
Real)num_layers / (
Real)order
750 : height *
std::pow(bias, (
Real)(layer_index - 1)) * (1.0 - bias) /
752 step_size_at_axis = step_size;
753 orig_node_to_current =
754 orig_node_to_previous +
759 sum_step_sizes += step_size;
760 sum_step_sizes_at_axis += step_size_at_axis;
768 (sum_step_sizes_at_axis - step_size_at_axis) / total_extrusion_distance_at_axis;
769 Real t = sum_step_sizes_at_axis / total_extrusion_distance_at_axis;
774 node_to_extrusion_axis =
775 *node + orig_node_to_current - *(extrusion_curve->node_ptr(k));
777 else if (!MooseUtils::absoluteFuzzyEqual(
_twist_pitch, 0.))
778 node_to_extrusion_axis =
779 *node + orig_node_to_current - (reference_point +
_direction * sum_step_sizes);
783 node_to_extrusion_axis = *node - reference_point;
786 const auto radius_scaling = start_node_radius / start_radial_extent;
792 orig_node_to_current += (start_radial_extent * (radial_ratio_m1 - radial_ratio) +
794 radius_scaling * node_to_extrusion_axis.
unit();
803 if (!MooseUtils::absoluteFuzzyEqual(twist1.
norm(), .0))
804 twist1 /= twist1.
norm();
821 Point extrusion_axis_at_elevation;
822 Point prev_extrusion_axis_at_elevation;
825 extrusion_axis_at_elevation = *extrusion_curve->node_ptr(k);
826 prev_extrusion_axis_at_elevation = *extrusion_curve->node_ptr(k - 1);
831 extrusion_axis_at_elevation = reference_point +
_direction * sum_step_sizes;
832 prev_extrusion_axis_at_elevation =
833 reference_point +
_direction * (sum_step_sizes - step_size);
837 twist *= (*node + orig_node_to_current - extrusion_axis_at_elevation).
norm();
840 if (!MooseUtils::absoluteFuzzyEqual(twist1.
norm(), .0))
841 orig_node_to_current += twist;
846 Node * new_node =
mesh->add_point(*node + orig_node_to_current,
847 node->id() + (current_node_layer * orig_nodes),
848 node->processor_id());
850 #ifdef LIBMESH_ENABLE_UNIQUE_ID 857 (current_node_layer - 1) * (orig_elem + orig_nodes) +
859 new_node->set_unique_id(uid);
863 input_boundary_info.boundary_ids(node, ids_to_copy);
865 boundary_info.add_node(new_node, ids_to_copy);
867 for (
const auto & id_to_copy : ids_to_copy)
869 boundary_info.add_node(new_node,
875 orig_node_to_previous = orig_node_to_current;
876 current_node_layer++;
881 const auto & side_ids = input_boundary_info.get_side_boundary_ids();
884 side_ids.empty() ? 0 : cast_int<boundary_id_type>(*side_ids.rbegin() + 1);
889 input->comm().max(next_side_id);
892 std::map<std::array<unsigned int, 3>, std::shared_ptr<libMesh::Polygon>> poly_extruded_sides;
895 for (
const auto & elem : input->element_ptr_range())
897 const ElemType etype = elem->type();
902 unsigned int current_layer = 0;
904 for (
unsigned int e = 0; e != total_num_elevations; e++)
908 for (
unsigned int k = 0; k != num_layers; ++k)
910 std::unique_ptr<Elem> new_elem;
911 bool is_flipped(
false);
916 new_elem = std::make_unique<Quad4>();
918 0,
mesh->node_ptr(elem->node_ptr(0)->id() + (current_layer * orig_nodes)));
920 1,
mesh->node_ptr(elem->node_ptr(1)->id() + (current_layer * orig_nodes)));
922 2,
mesh->node_ptr(elem->node_ptr(1)->id() + ((current_layer + 1) * orig_nodes)));
924 3,
mesh->node_ptr(elem->node_ptr(0)->id() + ((current_layer + 1) * orig_nodes)));
927 new_elem->set_neighbor(3, const_cast<RemoteElem *>(
remote_elem));
929 new_elem->set_neighbor(1, const_cast<RemoteElem *>(
remote_elem));
935 new_elem = std::make_unique<Quad9>();
937 0,
mesh->node_ptr(elem->node_ptr(0)->id() + (2 * current_layer * orig_nodes)));
939 1,
mesh->node_ptr(elem->node_ptr(1)->id() + (2 * current_layer * orig_nodes)));
942 mesh->node_ptr(elem->node_ptr(1)->id() + ((2 * current_layer + 2) * orig_nodes)));
945 mesh->node_ptr(elem->node_ptr(0)->id() + ((2 * current_layer + 2) * orig_nodes)));
947 4,
mesh->node_ptr(elem->node_ptr(2)->id() + (2 * current_layer * orig_nodes)));
950 mesh->node_ptr(elem->node_ptr(1)->id() + ((2 * current_layer + 1) * orig_nodes)));
953 mesh->node_ptr(elem->node_ptr(2)->id() + ((2 * current_layer + 2) * orig_nodes)));
956 mesh->node_ptr(elem->node_ptr(0)->id() + ((2 * current_layer + 1) * orig_nodes)));
959 mesh->node_ptr(elem->node_ptr(2)->id() + ((2 * current_layer + 1) * orig_nodes)));
962 new_elem->set_neighbor(3, const_cast<RemoteElem *>(
remote_elem));
964 new_elem->set_neighbor(1, const_cast<RemoteElem *>(
remote_elem));
970 new_elem = std::make_unique<Prism6>();
972 0,
mesh->node_ptr(elem->node_ptr(0)->id() + (current_layer * orig_nodes)));
974 1,
mesh->node_ptr(elem->node_ptr(1)->id() + (current_layer * orig_nodes)));
976 2,
mesh->node_ptr(elem->node_ptr(2)->id() + (current_layer * orig_nodes)));
978 3,
mesh->node_ptr(elem->node_ptr(0)->id() + ((current_layer + 1) * orig_nodes)));
980 4,
mesh->node_ptr(elem->node_ptr(1)->id() + ((current_layer + 1) * orig_nodes)));
982 5,
mesh->node_ptr(elem->node_ptr(2)->id() + ((current_layer + 1) * orig_nodes)));
985 new_elem->set_neighbor(1, const_cast<RemoteElem *>(
remote_elem));
987 new_elem->set_neighbor(2, const_cast<RemoteElem *>(
remote_elem));
989 new_elem->set_neighbor(3, const_cast<RemoteElem *>(
remote_elem));
991 if (new_elem->volume() < 0.0)
1003 new_elem = std::make_unique<Prism18>();
1005 0,
mesh->node_ptr(elem->node_ptr(0)->id() + (2 * current_layer * orig_nodes)));
1007 1,
mesh->node_ptr(elem->node_ptr(1)->id() + (2 * current_layer * orig_nodes)));
1009 2,
mesh->node_ptr(elem->node_ptr(2)->id() + (2 * current_layer * orig_nodes)));
1012 mesh->node_ptr(elem->node_ptr(0)->id() + ((2 * current_layer + 2) * orig_nodes)));
1015 mesh->node_ptr(elem->node_ptr(1)->id() + ((2 * current_layer + 2) * orig_nodes)));
1018 mesh->node_ptr(elem->node_ptr(2)->id() + ((2 * current_layer + 2) * orig_nodes)));
1020 6,
mesh->node_ptr(elem->node_ptr(3)->id() + (2 * current_layer * orig_nodes)));
1022 7,
mesh->node_ptr(elem->node_ptr(4)->id() + (2 * current_layer * orig_nodes)));
1024 8,
mesh->node_ptr(elem->node_ptr(5)->id() + (2 * current_layer * orig_nodes)));
1027 mesh->node_ptr(elem->node_ptr(0)->id() + ((2 * current_layer + 1) * orig_nodes)));
1030 mesh->node_ptr(elem->node_ptr(1)->id() + ((2 * current_layer + 1) * orig_nodes)));
1033 mesh->node_ptr(elem->node_ptr(2)->id() + ((2 * current_layer + 1) * orig_nodes)));
1036 mesh->node_ptr(elem->node_ptr(3)->id() + ((2 * current_layer + 2) * orig_nodes)));
1039 mesh->node_ptr(elem->node_ptr(4)->id() + ((2 * current_layer + 2) * orig_nodes)));
1042 mesh->node_ptr(elem->node_ptr(5)->id() + ((2 * current_layer + 2) * orig_nodes)));
1045 mesh->node_ptr(elem->node_ptr(3)->id() + ((2 * current_layer + 1) * orig_nodes)));
1048 mesh->node_ptr(elem->node_ptr(4)->id() + ((2 * current_layer + 1) * orig_nodes)));
1051 mesh->node_ptr(elem->node_ptr(5)->id() + ((2 * current_layer + 1) * orig_nodes)));
1054 new_elem->set_neighbor(1, const_cast<RemoteElem *>(
remote_elem));
1056 new_elem->set_neighbor(2, const_cast<RemoteElem *>(
remote_elem));
1058 new_elem->set_neighbor(3, const_cast<RemoteElem *>(
remote_elem));
1060 if (new_elem->volume() < 0.0)
1075 new_elem = std::make_unique<Prism21>();
1077 0,
mesh->node_ptr(elem->node_ptr(0)->id() + (2 * current_layer * orig_nodes)));
1079 1,
mesh->node_ptr(elem->node_ptr(1)->id() + (2 * current_layer * orig_nodes)));
1081 2,
mesh->node_ptr(elem->node_ptr(2)->id() + (2 * current_layer * orig_nodes)));
1084 mesh->node_ptr(elem->node_ptr(0)->id() + ((2 * current_layer + 2) * orig_nodes)));
1087 mesh->node_ptr(elem->node_ptr(1)->id() + ((2 * current_layer + 2) * orig_nodes)));
1090 mesh->node_ptr(elem->node_ptr(2)->id() + ((2 * current_layer + 2) * orig_nodes)));
1092 6,
mesh->node_ptr(elem->node_ptr(3)->id() + (2 * current_layer * orig_nodes)));
1094 7,
mesh->node_ptr(elem->node_ptr(4)->id() + (2 * current_layer * orig_nodes)));
1096 8,
mesh->node_ptr(elem->node_ptr(5)->id() + (2 * current_layer * orig_nodes)));
1099 mesh->node_ptr(elem->node_ptr(0)->id() + ((2 * current_layer + 1) * orig_nodes)));
1102 mesh->node_ptr(elem->node_ptr(1)->id() + ((2 * current_layer + 1) * orig_nodes)));
1105 mesh->node_ptr(elem->node_ptr(2)->id() + ((2 * current_layer + 1) * orig_nodes)));
1108 mesh->node_ptr(elem->node_ptr(3)->id() + ((2 * current_layer + 2) * orig_nodes)));
1111 mesh->node_ptr(elem->node_ptr(4)->id() + ((2 * current_layer + 2) * orig_nodes)));
1114 mesh->node_ptr(elem->node_ptr(5)->id() + ((2 * current_layer + 2) * orig_nodes)));
1117 mesh->node_ptr(elem->node_ptr(3)->id() + ((2 * current_layer + 1) * orig_nodes)));
1120 mesh->node_ptr(elem->node_ptr(4)->id() + ((2 * current_layer + 1) * orig_nodes)));
1123 mesh->node_ptr(elem->node_ptr(5)->id() + ((2 * current_layer + 1) * orig_nodes)));
1125 18,
mesh->node_ptr(elem->node_ptr(6)->id() + (2 * current_layer * orig_nodes)));
1128 mesh->node_ptr(elem->node_ptr(6)->id() + ((2 * current_layer + 2) * orig_nodes)));
1131 mesh->node_ptr(elem->node_ptr(6)->id() + ((2 * current_layer + 1) * orig_nodes)));
1134 new_elem->set_neighbor(1, const_cast<RemoteElem *>(
remote_elem));
1136 new_elem->set_neighbor(2, const_cast<RemoteElem *>(
remote_elem));
1138 new_elem->set_neighbor(3, const_cast<RemoteElem *>(
remote_elem));
1140 if (new_elem->volume() < 0.0)
1156 new_elem = std::make_unique<Hex8>();
1158 0,
mesh->node_ptr(elem->node_ptr(0)->id() + (current_layer * orig_nodes)));
1160 1,
mesh->node_ptr(elem->node_ptr(1)->id() + (current_layer * orig_nodes)));
1162 2,
mesh->node_ptr(elem->node_ptr(2)->id() + (current_layer * orig_nodes)));
1164 3,
mesh->node_ptr(elem->node_ptr(3)->id() + (current_layer * orig_nodes)));
1166 4,
mesh->node_ptr(elem->node_ptr(0)->id() + ((current_layer + 1) * orig_nodes)));
1168 5,
mesh->node_ptr(elem->node_ptr(1)->id() + ((current_layer + 1) * orig_nodes)));
1170 6,
mesh->node_ptr(elem->node_ptr(2)->id() + ((current_layer + 1) * orig_nodes)));
1172 7,
mesh->node_ptr(elem->node_ptr(3)->id() + ((current_layer + 1) * orig_nodes)));
1175 new_elem->set_neighbor(1, const_cast<RemoteElem *>(
remote_elem));
1177 new_elem->set_neighbor(2, const_cast<RemoteElem *>(
remote_elem));
1179 new_elem->set_neighbor(3, const_cast<RemoteElem *>(
remote_elem));
1181 new_elem->set_neighbor(4, const_cast<RemoteElem *>(
remote_elem));
1183 if (new_elem->volume() < 0.0)
1196 new_elem = std::make_unique<Hex20>();
1198 0,
mesh->node_ptr(elem->node_ptr(0)->id() + (2 * current_layer * orig_nodes)));
1200 1,
mesh->node_ptr(elem->node_ptr(1)->id() + (2 * current_layer * orig_nodes)));
1202 2,
mesh->node_ptr(elem->node_ptr(2)->id() + (2 * current_layer * orig_nodes)));
1204 3,
mesh->node_ptr(elem->node_ptr(3)->id() + (2 * current_layer * orig_nodes)));
1207 mesh->node_ptr(elem->node_ptr(0)->id() + ((2 * current_layer + 2) * orig_nodes)));
1210 mesh->node_ptr(elem->node_ptr(1)->id() + ((2 * current_layer + 2) * orig_nodes)));
1213 mesh->node_ptr(elem->node_ptr(2)->id() + ((2 * current_layer + 2) * orig_nodes)));
1216 mesh->node_ptr(elem->node_ptr(3)->id() + ((2 * current_layer + 2) * orig_nodes)));
1218 8,
mesh->node_ptr(elem->node_ptr(4)->id() + (2 * current_layer * orig_nodes)));
1220 9,
mesh->node_ptr(elem->node_ptr(5)->id() + (2 * current_layer * orig_nodes)));
1222 10,
mesh->node_ptr(elem->node_ptr(6)->id() + (2 * current_layer * orig_nodes)));
1224 11,
mesh->node_ptr(elem->node_ptr(7)->id() + (2 * current_layer * orig_nodes)));
1227 mesh->node_ptr(elem->node_ptr(0)->id() + ((2 * current_layer + 1) * orig_nodes)));
1230 mesh->node_ptr(elem->node_ptr(1)->id() + ((2 * current_layer + 1) * orig_nodes)));
1233 mesh->node_ptr(elem->node_ptr(2)->id() + ((2 * current_layer + 1) * orig_nodes)));
1236 mesh->node_ptr(elem->node_ptr(3)->id() + ((2 * current_layer + 1) * orig_nodes)));
1239 mesh->node_ptr(elem->node_ptr(4)->id() + ((2 * current_layer + 2) * orig_nodes)));
1242 mesh->node_ptr(elem->node_ptr(5)->id() + ((2 * current_layer + 2) * orig_nodes)));
1245 mesh->node_ptr(elem->node_ptr(6)->id() + ((2 * current_layer + 2) * orig_nodes)));
1248 mesh->node_ptr(elem->node_ptr(7)->id() + ((2 * current_layer + 2) * orig_nodes)));
1251 new_elem->set_neighbor(1, const_cast<RemoteElem *>(
remote_elem));
1253 new_elem->set_neighbor(2, const_cast<RemoteElem *>(
remote_elem));
1255 new_elem->set_neighbor(3, const_cast<RemoteElem *>(
remote_elem));
1257 new_elem->set_neighbor(4, const_cast<RemoteElem *>(
remote_elem));
1259 if (new_elem->volume() < 0.0)
1276 new_elem = std::make_unique<Hex27>();
1278 0,
mesh->node_ptr(elem->node_ptr(0)->id() + (2 * current_layer * orig_nodes)));
1280 1,
mesh->node_ptr(elem->node_ptr(1)->id() + (2 * current_layer * orig_nodes)));
1282 2,
mesh->node_ptr(elem->node_ptr(2)->id() + (2 * current_layer * orig_nodes)));
1284 3,
mesh->node_ptr(elem->node_ptr(3)->id() + (2 * current_layer * orig_nodes)));
1287 mesh->node_ptr(elem->node_ptr(0)->id() + ((2 * current_layer + 2) * orig_nodes)));
1290 mesh->node_ptr(elem->node_ptr(1)->id() + ((2 * current_layer + 2) * orig_nodes)));
1293 mesh->node_ptr(elem->node_ptr(2)->id() + ((2 * current_layer + 2) * orig_nodes)));
1296 mesh->node_ptr(elem->node_ptr(3)->id() + ((2 * current_layer + 2) * orig_nodes)));
1298 8,
mesh->node_ptr(elem->node_ptr(4)->id() + (2 * current_layer * orig_nodes)));
1300 9,
mesh->node_ptr(elem->node_ptr(5)->id() + (2 * current_layer * orig_nodes)));
1302 10,
mesh->node_ptr(elem->node_ptr(6)->id() + (2 * current_layer * orig_nodes)));
1304 11,
mesh->node_ptr(elem->node_ptr(7)->id() + (2 * current_layer * orig_nodes)));
1307 mesh->node_ptr(elem->node_ptr(0)->id() + ((2 * current_layer + 1) * orig_nodes)));
1310 mesh->node_ptr(elem->node_ptr(1)->id() + ((2 * current_layer + 1) * orig_nodes)));
1313 mesh->node_ptr(elem->node_ptr(2)->id() + ((2 * current_layer + 1) * orig_nodes)));
1316 mesh->node_ptr(elem->node_ptr(3)->id() + ((2 * current_layer + 1) * orig_nodes)));
1319 mesh->node_ptr(elem->node_ptr(4)->id() + ((2 * current_layer + 2) * orig_nodes)));
1322 mesh->node_ptr(elem->node_ptr(5)->id() + ((2 * current_layer + 2) * orig_nodes)));
1325 mesh->node_ptr(elem->node_ptr(6)->id() + ((2 * current_layer + 2) * orig_nodes)));
1328 mesh->node_ptr(elem->node_ptr(7)->id() + ((2 * current_layer + 2) * orig_nodes)));
1330 20,
mesh->node_ptr(elem->node_ptr(8)->id() + (2 * current_layer * orig_nodes)));
1333 mesh->node_ptr(elem->node_ptr(4)->id() + ((2 * current_layer + 1) * orig_nodes)));
1336 mesh->node_ptr(elem->node_ptr(5)->id() + ((2 * current_layer + 1) * orig_nodes)));
1339 mesh->node_ptr(elem->node_ptr(6)->id() + ((2 * current_layer + 1) * orig_nodes)));
1342 mesh->node_ptr(elem->node_ptr(7)->id() + ((2 * current_layer + 1) * orig_nodes)));
1345 mesh->node_ptr(elem->node_ptr(8)->id() + ((2 * current_layer + 2) * orig_nodes)));
1348 mesh->node_ptr(elem->node_ptr(8)->id() + ((2 * current_layer + 1) * orig_nodes)));
1351 new_elem->set_neighbor(1, const_cast<RemoteElem *>(
remote_elem));
1353 new_elem->set_neighbor(2, const_cast<RemoteElem *>(
remote_elem));
1355 new_elem->set_neighbor(3, const_cast<RemoteElem *>(
remote_elem));
1357 new_elem->set_neighbor(4, const_cast<RemoteElem *>(
remote_elem));
1359 if (new_elem->volume() < 0.0)
1377 has_polygons =
true;
1378 const auto num_sides = elem->n_sides();
1379 std::vector<std::shared_ptr<libMesh::Polygon>>
sides;
1380 sides.reserve(2 + num_sides);
1382 mooseError(
"Too many nodes in polygons to extrude it. Max number of the prism " 1383 "polyhedral nodes after extrusion: " +
1386 auto new_ptr = std::make_shared<libMesh::C0Polygon>(num_sides);
1387 for (
const auto node_i :
make_range(elem->n_nodes()))
1393 mesh->node_ptr(elem->node_ptr(node_i)->id() + (current_layer * orig_nodes)));
1395 sides.push_back(new_ptr);
1397 auto translated_side = std::make_shared<libMesh::C0Polygon>(num_sides);
1398 for (
const auto node_i :
make_range(elem->n_nodes()))
1399 translated_side->set_node(node_i,
1400 mesh->node_ptr(elem->node_ptr(node_i)->id() +
1401 ((current_layer + 1) * orig_nodes)));
1402 sides.push_back(translated_side);
1405 for (
const auto side_i :
make_range(num_sides))
1408 std::array<unsigned int, 3> side_key = {
1410 static_cast<unsigned int>(
1411 std::min(elem->node_ptr(side_i)->id(),
1412 elem->node_ptr((side_i + 1) % num_sides)->id())),
1413 static_cast<unsigned int>(
1414 std::max(elem->node_ptr(side_i)->id(),
1415 elem->node_ptr((side_i + 1) % num_sides)->id()))};
1416 if (poly_extruded_sides.count(side_key))
1418 sides.push_back(poly_extruded_sides[side_key]);
1423 auto vert_side = std::make_shared<libMesh::C0Polygon>(4);
1424 vert_side->set_node(
1425 0,
mesh->node_ptr(elem->node_ptr(side_i)->id() + (current_layer * orig_nodes)));
1426 vert_side->set_node(1,
1427 mesh->node_ptr(elem->node_ptr((side_i + 1) % num_sides)->id() +
1428 (current_layer * orig_nodes)));
1429 vert_side->set_node(2,
1430 mesh->node_ptr(elem->node_ptr((side_i + 1) % num_sides)->id() +
1431 ((current_layer + 1) * orig_nodes)));
1432 vert_side->set_node(3,
1433 mesh->node_ptr(elem->node_ptr(side_i)->id() +
1434 ((current_layer + 1) * orig_nodes)));
1435 sides.push_back(vert_side);
1437 poly_extruded_sides.insert(std::make_pair(side_key, vert_side));
1439 mooseAssert(
sides.size() == 2 + num_sides,
"Unexpected size of side vector");
1442 std::unique_ptr<libMesh::Node> mid_elem_node;
1443 new_elem = std::make_unique<libMesh::C0Polyhedron>(
sides, mid_elem_node);
1446 #ifdef LIBMESH_ENABLE_UNIQUE_ID 1449 unsigned int total_new_node_layers = total_num_layers * order;
1450 unsigned int last_uid = orig_unique_ids + (total_new_node_layers - 1) * orig_elem +
1451 total_new_node_layers * orig_nodes + elem->unique_id();
1452 mid_elem_node->set_unique_id(last_uid);
1453 has_poly_midnodes =
true;
1455 mesh->add_node(std::move(mid_elem_node));
1464 new_elem->set_id(elem->id() + (current_layer * orig_elem));
1465 new_elem->processor_id() = elem->processor_id();
1467 #ifdef LIBMESH_ENABLE_UNIQUE_ID 1474 (current_layer - 1) * (orig_elem + orig_nodes) +
1475 orig_nodes + elem->id();
1477 new_elem->set_unique_id(uid);
1481 new_elem->subdomain_id() = elem->subdomain_id();
1484 if (k == num_layers - 1)
1487 const unsigned short top_id =
1488 new_elem->dim() == 3 ? cast_int<unsigned short>(elem->n_sides() + 1) : 2;
1494 boundary_info.add_side(
1500 const unsigned short top_id =
1501 new_elem->dim() == 3 ? cast_int<unsigned short>(elem->n_sides() + 1) : 2;
1505 boundary_info.add_side(
1514 auto new_id_it = elevation_swap_pairs.find(elem->subdomain_id());
1516 if (new_id_it != elevation_swap_pairs.end())
1517 new_elem->subdomain_id() = new_id_it->second;
1520 Elem * added_elem =
mesh->add_elem(std::move(new_elem));
1523 for (
unsigned int i = 0; i < num_extra_elem_integers; i++)
1524 added_elem->set_extra_integer(i, elem->get_extra_integer(i));
1532 auto new_extra_id_it = elevation_extra_swap_pairs.find(
1535 if (new_extra_id_it != elevation_extra_swap_pairs.end())
1537 new_extra_id_it->second);
1542 for (
auto s : elem->side_index_range())
1544 input_boundary_info.boundary_ids(elem, s, ids_to_copy);
1546 if (added_elem->dim() == 3)
1553 boundary_info.add_side(added_elem, cast_int<unsigned short>(s + 1), ids_to_copy);
1555 for (
const auto & id_to_copy : ids_to_copy)
1556 boundary_info.add_side(added_elem,
1557 cast_int<unsigned short>(s + 1),
1568 libmesh_assert_less(s, 2);
1569 const unsigned short sidemap[2] = {3, 1};
1571 boundary_info.add_side(added_elem, sidemap[s], ids_to_copy);
1573 for (
const auto & id_to_copy : ids_to_copy)
1574 boundary_info.add_side(added_elem,
1583 if (current_layer == 0)
1585 const unsigned short top_id =
1586 added_elem->dim() == 3 ? cast_int<unsigned short>(elem->n_sides() + 1) : 2;
1590 "We should have retrieved a proper boundary ID");
1591 boundary_info.add_side(added_elem, is_flipped ?
top_id : 0, user_bottom_boundary_id);
1594 boundary_info.add_side(added_elem, is_flipped ?
top_id : 0, next_side_id);
1597 if (current_layer == total_num_layers - 1)
1602 const unsigned short top_id =
1603 added_elem->dim() == 3 ? cast_int<unsigned short>(elem->n_sides() + 1) : 2;
1608 "We should have retrieved a proper boundary ID");
1609 boundary_info.add_side(added_elem, is_flipped ? 0 :
top_id, user_top_boundary_id);
1612 boundary_info.add_side(
1613 added_elem, is_flipped ? 0 :
top_id, cast_int<boundary_id_type>(next_side_id + 1));
1621 if (has_polygons && !input->is_serial())
1622 mooseError(
"Distributed meshes are not supported when extruding polygons at this time.");
1624 #ifdef LIBMESH_ENABLE_UNIQUE_ID 1627 unsigned int total_new_node_layers = total_num_layers * order;
1628 unsigned int new_unique_ids = orig_unique_ids + (total_new_node_layers - 1) * orig_elem +
1629 total_new_node_layers * orig_nodes;
1631 if (has_poly_midnodes)
1632 new_unique_ids += orig_elem;
1633 mesh->set_next_unique_id(new_unique_ids);
1637 if (!input_subdomain_map.empty())
1638 mesh->set_subdomain_name_map().insert(input_subdomain_map.begin(), input_subdomain_map.end());
1639 if (!input_sideset_map.empty())
1640 mesh->get_boundary_info().set_sideset_name_map().insert(input_sideset_map.begin(),
1641 input_sideset_map.end());
1642 if (!input_nodeset_map.empty())
1643 mesh->get_boundary_info().set_nodeset_name_map().insert(input_nodeset_map.begin(),
1644 input_nodeset_map.end());
1647 boundary_info.sideset_name(new_boundary_ids.front()) = new_boundary_names.front();
1649 boundary_info.sideset_name(new_boundary_ids.back()) = new_boundary_names.back();
1651 mesh->unset_is_prepared();
1654 if (extruding_quad_eights)
1655 mesh->prepare_for_use();
void swapNodesInElem(Elem &elem, const unsigned int nd1, const unsigned int nd2)
Swap two nodes within an element.
std::vector< std::unordered_map< boundary_id_type, boundary_id_type > > _boundary_swap_pairs
Easier to work with version of _boundary_swaps.
MetaPhysicL::DualNumber< V, D, asd > abs(const MetaPhysicL::DualNumber< V, D, asd > &a)
std::unique_ptr< MeshBase > & _input
Mesh that comes from another generator.
const RealVectorValue _end_extrusion_direction
Extrusion direction for the final layer of the extrusion.
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sin(_arg) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tan
virtual const char * what() const
Get out the error message.
const unsigned int invalid_uint
const Real _end_radial_extent
Radial extent of the extruded geometry at the end of the extrusion.
std::unique_ptr< MeshBase > & _extrusion_curve
Curve mesh to extrude along.
void paramError(const std::string ¶m, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
static constexpr Real TOLERANCE
void swap(std::vector< T > &data, const std::size_t idx0, const std::size_t idx1, const libMesh::Parallel::Communicator &comm)
Swap function for serial or distributed vector of data.
std::vector< unsigned int > _elem_integer_indices_to_swap
Point _direction
The direction of the extrusion.
const std::vector< Real > & _heights
Height of each elevation.
AdvancedExtruderGenerator(const InputParameters ¶meters)
bool hasBoundaryID(const MeshBase &input_mesh, const BoundaryID id)
Whether a particular boundary ID exists in the mesh.
const Real _twist_pitch
Axial pitch for a full rotation.
const BoundaryName _bottom_boundary
const std::vector< std::vector< subdomain_id_type > > _downward_boundary_source_blocks
The list of input mesh's blocks that need to be assigned downward boundary interfaces for each layer ...
const BoundaryName _top_boundary
auto max(const L &left, const R &right)
const std::vector< std::vector< boundary_id_type > > _upward_boundary_ids
Upward boundary interfaces for each layer of elevation.
bool hasSubdomainID(const MeshBase &input_mesh, const SubdomainID &id)
Whether a particular subdomain ID exists in the mesh.
TypeVector< Real > unit() const
const Real _start_radial_growth_rate
Derivative of the radial expansion function at the beginning of the extrusion.
const std::string & name() const
Get the name of the class.
Extrudes a mesh to another dimension.
static const boundary_id_type invalid_id
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template cos(_arg) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(cos
const std::vector< std::vector< boundary_id_type > > _downward_boundary_ids
Downward boundary interfaces for each layer of elevation.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
void idSwapParametersProcessor(const std::string &class_name, const std::string &id_name, const std::vector< std::vector< T >> &id_swaps, std::vector< std::unordered_map< T, T >> &id_swap_pairs, const unsigned int row_index_shift=0)
Reprocess the swap related input parameters to make pairs out of them to ease further processing...
std::vector< BoundaryID > getBoundaryIDs(const libMesh::MeshBase &mesh, const std::vector< BoundaryName > &boundary_name, bool generate_unknown, const std::set< BoundaryID > &mesh_boundary_ids)
Gets the boundary IDs with their names.
std::vector< std::unordered_map< subdomain_id_type, subdomain_id_type > > _subdomain_swap_pairs
Easier to work with version of _sudomain_swaps.
TypeVector< typename CompareTypes< Real, T2 >::supertype > cross(const TypeVector< T2 > &v) const
static InputParameters validParams()
const Real _end_radial_growth_rate
Derivative of the radial expansion function at the end of the extrusion.
std::string stringify(const T &t)
conversion to string
const std::vector< std::vector< subdomain_id_type > > & _subdomain_swaps
Subdomains to swap out for each elevation.
registerMooseObjectRenamed("MooseApp", FancyExtruderGenerator, "02/18/2023 24:00", AdvancedExtruderGenerator)
const std::vector< std::vector< boundary_id_type > > & _boundary_swaps
Boundaries to swap out for each elevation.
const boundary_id_type top_id
bool _extrude_along_curve
Whether we are extruding along a curve.
Provides a way for users to bail out of the current solve.
Real radialExpansionRatio(const Real t) const
Calculate the share of the radial expansion to apply at the local node This share goes from 0 at the ...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const std::vector< std::vector< std::vector< dof_id_type > > > & _elem_integers_swaps
Extra element integers to swap out for each elevation and each element interger name.
const bool _has_bottom_boundary
const std::vector< Real > _biases
Bias growth factor of each elevation.
IntRange< T > make_range(T beg, T end)
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
registerMooseObject("MooseApp", AdvancedExtruderGenerator)
const std::vector< std::vector< subdomain_id_type > > _upward_boundary_source_blocks
The list of input mesh's blocks that need to be assigned upward boundary interfaces for each layer of...
const std::vector< unsigned int > & _num_layers
Number of layers in each elevation.
void extraElemIntegerSwapParametersProcessor(const std::string &class_name, const unsigned int num_sections, const unsigned int num_integers, const std::vector< std::vector< std::vector< dof_id_type >>> &elem_integers_swaps, std::vector< std::unordered_map< dof_id_type, dof_id_type >> &elem_integers_swap_pairs)
Reprocess the elem_integers_swaps into maps so they are easier to use.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Point meshCentroidCalculator(const MeshBase &mesh)
Calculates the centroid of a MeshBase.
std::unique_ptr< MeshBase > buildMeshBaseObject(unsigned int dim=libMesh::invalid_uint)
Build a MeshBase object whose underlying type will be determined by the Mesh input file block...
Real computeMaxDistanceToAxis(const MeshBase &mesh, const Point &origin, const RealVectorValue &direction)
Computes the maximum distance from all nodes of a mesh to a general axis.
const MooseEnum _radial_expansion_method
Function type for modifying the radial extent of the extruded shape.
static InputParameters validParams()
const bool _has_top_boundary
auto min(const L &left, const R &right)
const std::vector< std::string > & _elem_integer_names_to_swap
Names and indices of extra element integers to swap.
bool isParamSetByUser(const std::string &name) const
Test if the supplied parameter is set by a user, as opposed to not set or set to default.
MooseUnits pow(const MooseUnits &, int)
MeshGenerators are objects that can modify or add to an existing mesh.
void ErrorVector unsigned int
auto index_range(const T &sizable)
std::vector< std::unordered_map< dof_id_type, dof_id_type > > _elem_integers_swap_pairs
Easier to work with version of _elem_integers_swaps.
static const unsigned int max_n_nodes
const RealVectorValue _start_extrusion_direction
Extrusion direction to follow at the start (first layer) of the extrusion.
const RemoteElem * remote_elem