From 66d79165f3f50a6b18f8ca3a5435ea6eccc647b5 Mon Sep 17 00:00:00 2001 From: Yinbin Miao Date: Wed, 12 Jun 2024 16:11:33 -0500 Subject: [PATCH] Code improvement for RevolveGenerator based on review comments 2 --- .../AdvancedExtruderGenerator.h | 2 +- framework/include/utils/MooseMeshUtils.h | 10 +- framework/src/utils/MooseMeshUtils.C | 33 ++--- .../include/meshgenerators/RevolveGenerator.h | 4 +- .../src/meshgenerators/RevolveGenerator.C | 117 ++++++++++++------ .../meshgenerators/revolve_generator/tests | 18 ++- 6 files changed, 124 insertions(+), 60 deletions(-) diff --git a/framework/include/meshgenerators/AdvancedExtruderGenerator.h b/framework/include/meshgenerators/AdvancedExtruderGenerator.h index a3b1adda0d06..a6e85ed6a7a7 100644 --- a/framework/include/meshgenerators/AdvancedExtruderGenerator.h +++ b/framework/include/meshgenerators/AdvancedExtruderGenerator.h @@ -58,7 +58,7 @@ class AdvancedExtruderGenerator : public MeshGenerator std::vector> _boundary_swap_pairs; /// Easier to work with version of _elem_integers_swaps - std::vector> _elem_integers_swap_pairs; + std::vector> _elem_integers_swap_pairs; /// The direction of the extrusion Point _direction; diff --git a/framework/include/utils/MooseMeshUtils.h b/framework/include/utils/MooseMeshUtils.h index 8074659121f5..cf48a4ec1bd9 100644 --- a/framework/include/utils/MooseMeshUtils.h +++ b/framework/include/utils/MooseMeshUtils.h @@ -331,13 +331,16 @@ void swapNodesInElem(Elem & elem, const unsigned int nd1, const unsigned int nd2 * @param id_name name of the parameter to be swapped used for exception messages * @param id_swaps vector of vectors of the ids to be swapped * @param id_swap_pairs vector of maps of the swapped pairs + * @param row_index_shift shift to be applied to the row index in the exception messages (useful + * when this method is utilized to process a fraction of a long vector) */ template void idSwapParametersProcessor(const std::string & class_name, const std::string & id_name, const std::vector> & id_swaps, - std::vector> & id_swap_pairs) + std::vector> & id_swap_pairs, + const unsigned int row_index_shift = 0) { id_swap_pairs.resize(id_swaps.size()); for (const auto i : index_range(id_swaps)) @@ -347,7 +350,7 @@ idSwapParametersProcessor(const std::string & class_name, if (swaps.size() % 2) throw MooseException("Row ", - i + 1, + row_index_shift + i + 1, " of ", id_name, " in ", @@ -355,6 +358,7 @@ idSwapParametersProcessor(const std::string & class_name, " does not contain an even number of entries! Num entries: ", swaps.size()); + swap_pairs.reserve(swaps.size() / 2); for (unsigned int j = 0; j < swaps.size(); j += 2) swap_pairs[swaps[j]] = swaps[j + 1]; } @@ -373,5 +377,5 @@ void extraElemIntegerSwapParametersProcessor( const unsigned int num_sections, const unsigned int num_integers, const std::vector>> & elem_integers_swaps, - std::vector> & elem_integers_swap_pairs); + std::vector> & elem_integers_swap_pairs); } diff --git a/framework/src/utils/MooseMeshUtils.C b/framework/src/utils/MooseMeshUtils.C index bd9df45ad285..3de4f6ea7417 100644 --- a/framework/src/utils/MooseMeshUtils.C +++ b/framework/src/utils/MooseMeshUtils.C @@ -499,26 +499,29 @@ extraElemIntegerSwapParametersProcessor( const unsigned int num_sections, const unsigned int num_integers, const std::vector>> & elem_integers_swaps, - std::vector> & elem_integers_swap_pairs) + std::vector> & elem_integers_swap_pairs) { - elem_integers_swap_pairs.resize(num_sections * num_integers); + elem_integers_swap_pairs.reserve(num_sections * num_integers); for (const auto i : make_range(num_integers)) { - for (const auto j : make_range(num_sections)) + const auto & elem_integer_swaps = elem_integers_swaps[i]; + std::vector> elem_integer_swap_pairs; + try { - const auto & extra_swaps = elem_integers_swaps[i][j]; - auto & extra_swap_pairs = elem_integers_swap_pairs[i * num_sections + j]; - - if (extra_swaps.size() % 2) - throw MooseException("Row ", - i * num_sections + j + 1, - " of elem_integers_swaps in ", - class_name, - " does not contain an even number of entries! Num entries: ", - extra_swaps.size()); - for (unsigned int k = 0; k < extra_swaps.size(); k += 2) - extra_swap_pairs[extra_swaps[k]] = extra_swaps[k + 1]; + MooseMeshUtils::idSwapParametersProcessor(class_name, + "elem_integers_swaps", + elem_integer_swaps, + elem_integer_swap_pairs, + i * num_sections); } + catch (const MooseException & e) + { + throw MooseException(e.what()); + } + + elem_integers_swap_pairs.insert(elem_integers_swap_pairs.end(), + elem_integer_swap_pairs.begin(), + elem_integer_swap_pairs.end()); } } } diff --git a/modules/reactor/include/meshgenerators/RevolveGenerator.h b/modules/reactor/include/meshgenerators/RevolveGenerator.h index 0cf6e618e63e..77fbfbaeb853 100644 --- a/modules/reactor/include/meshgenerators/RevolveGenerator.h +++ b/modules/reactor/include/meshgenerators/RevolveGenerator.h @@ -74,7 +74,7 @@ class RevolveGenerator : public PolygonMeshGeneratorBase std::vector> _boundary_swap_pairs; /// Easier to work with version of _elem_integers_swaps - std::vector> _elem_integers_swap_pairs; + std::vector> _elem_integers_swap_pairs; /// Whether to revolve for a full circle or not bool _full_circle_revolving; @@ -116,7 +116,7 @@ class RevolveGenerator : public PolygonMeshGeneratorBase * Categorize the nodes of an element into two groups: nodes on the axis and nodes off the axis. * @param elem the element whose nodes are to be categorized * @param nodes_on_axis a list of node IDs on the axis - * @return a pair of two lists of node IDs: the first list is for nodes on the axis, and the + * @return a pair of lists of node IDs: the first list is for nodes on the axis, and the * second list is for nodes off the axis */ std::pair, std::vector> diff --git a/modules/reactor/src/meshgenerators/RevolveGenerator.C b/modules/reactor/src/meshgenerators/RevolveGenerator.C index d0bf67e0a444..66c684b42e00 100644 --- a/modules/reactor/src/meshgenerators/RevolveGenerator.C +++ b/modules/reactor/src/meshgenerators/RevolveGenerator.C @@ -28,6 +28,7 @@ #include "libmesh/face_quad4.h" #include "libmesh/face_quad9.h" #include "libmesh/point.h" +#include "libmesh/mesh_tools.h" // C++ includes #include @@ -88,13 +89,18 @@ RevolveGenerator::validParams() "clockwise", true, "Revolve clockwise around the axis or not (i.e., counterclockwise)"); params.addRequiredParam>( - "nums_azimuthal_intervals", "The numbers of azimuthal intervals to revolve around the axis"); + "nums_azimuthal_intervals", + "List of the numbers of azimuthal interval discretization for each azimuthal section"); params.addParam("preserve_volumes", false, "Whether the volume of the revolved mesh is preserving the circular area " "by modifying (expanding) the radius to account for polygonization."); + params.addParamNamesToGroup("start_boundary end_boundary", "Boundary Assignment"); + params.addParamNamesToGroup( + "subdomain_swaps boundary_swaps elem_integer_names_to_swap elem_integers_swaps", "ID Swap"); + return params; } @@ -202,10 +208,15 @@ RevolveGenerator::generate() // Note: Inspired by AdvancedExtruderGenerator::generate() auto mesh = buildMeshBaseObject(); + + // Only works for 1D and 2D input meshes + if (_input->mesh_dimension() > 2) + paramError("input", "This mesh generator only works for 1D and 2D input meshes."); + mesh->set_mesh_dimension(_input->mesh_dimension() + 1); // Check if the element integer names are existent in the input mesh. - for (unsigned int i = 0; i < _elem_integer_names_to_swap.size(); i++) + for (const auto i : index_range(_elem_integer_names_to_swap)) if (_input->has_elem_integer(_elem_integer_names_to_swap[i])) _elem_integer_indices_to_swap.push_back( _input->get_elem_integer_index(_elem_integer_names_to_swap[i])); @@ -213,14 +224,14 @@ RevolveGenerator::generate() paramError("elem_integer_names_to_swap", "Element ", i + 1, - " of 'elem_integer_names_to_swap' in is not a valid extra element integer of the " + " of 'elem_integer_names_to_swap' is not a valid extra element integer of the " "input mesh."); // prepare for transferring extra element integers from original mesh to the revolved mesh. const unsigned int num_extra_elem_integers = _input->n_elem_integers(); std::vector id_names; - for (unsigned int i = 0; i < num_extra_elem_integers; i++) + for (const auto i : make_range(num_extra_elem_integers)) { id_names.push_back(_input->get_elem_integer_name(i)); if (!mesh->has_elem_integer(id_names[i])) @@ -347,9 +358,7 @@ RevolveGenerator::generate() // Restore the subdomain ID; we do not worry about repeated subdomain IDs because those QUAD9 // will become PYRAMID and PRISM elements with new shifts for (auto elem : input->active_subdomain_set_elements_ptr_range(converted_quad8_subdomain_ids)) - { elem->subdomain_id() -= quad_to_hi_pyramid_subdomain_id_shift; - } } // We should only record this info after QUAD8->QUAD9 conversion @@ -375,10 +384,14 @@ RevolveGenerator::generate() mesh->reserve_elem(total_num_azimuthal_intervals * orig_elem * 2); const dof_id_type elem_id_shift = total_num_azimuthal_intervals * orig_elem; - if (input->elements_begin() != input->elements_end() && - ((*input->elements_begin())->default_order() == SECOND || - (*input->elements_begin())->default_order() == THIRD)) - order = 2; + // Look for higher order elements which introduce an extra layer + std::set higher_orders = {EDGE3, TRI6, TRI7, QUAD8, QUAD9}; + std::vector types; + MeshTools::elem_types(*input, types); + for (const auto elem_type : types) + if (higher_orders.count(elem_type)) + order = 2; + mesh->comm().max(order); #ifdef LIBMESH_ENABLE_UNIQUE_ID const unique_id_type elem_unique_id_shift = @@ -404,8 +417,6 @@ RevolveGenerator::generate() nodeModification(*node); } - mesh->comm().max(order); - mesh->reserve_nodes( (order * total_num_azimuthal_intervals + 1 - (unsigned int)_full_circle_revolving) * orig_nodes); @@ -530,7 +541,7 @@ RevolveGenerator::generate() const ElemType etype = elem->type(); // revolving currently only works on coarse meshes - libmesh_assert(!elem->parent()); + mooseAssert(!elem->parent(), "RevolveGenerator only works on coarse meshes."); unsigned int current_layer = 0; @@ -545,6 +556,8 @@ RevolveGenerator::generate() std::unique_ptr new_elem; std::unique_ptr new_elem_1; bool is_flipped(false); + // In some cases, two elements per layer are generated by revolving one element. So we + // reserve an additional flag for the potential second element. bool is_flipped_additional(false); dof_id_type axis_node_case(-1); std::vector> side_pairs; @@ -673,7 +686,8 @@ RevolveGenerator::generate() is_flipped); } else - mooseError("impossible situation"); + mooseError("A degenerate TRI3 elements overlapped with the rotation axis cannot be " + "revolved."); break; } @@ -729,7 +743,9 @@ RevolveGenerator::generate() is_flipped); } else - mooseError("impossible situation"); + mooseError( + "You either have a degenerate TRI6 element, or the mid-point of the " + "on-axis edge is not colinear with the two vertices, which is not supported."); break; } case TRI7: @@ -784,7 +800,9 @@ RevolveGenerator::generate() is_flipped); } else - mooseError("impossible situation"); + mooseError("You either have a degenerate TRI6 element, or the mid-point of the " + "on-axis edge of the TRI6 element is not colinear with the two vertices, " + "which is not supported."); break; } case QUAD4: @@ -842,8 +860,8 @@ RevolveGenerator::generate() } else - mooseError( - "Degenerate element with 3 or more aligned nodes cannot be azimuthally revolved"); + mooseError("Degenerate QUAD4 element with 3 or more aligned nodes cannot be " + "azimuthally revolved"); break; } @@ -886,7 +904,9 @@ RevolveGenerator::generate() is_flipped); } else - mooseError("impossible situation"); + mooseError("You either have a degenerate QUAD8 element, or the mid-point of the " + "on-axis edge of the QUAD8 element is not colinear with the two vertices, " + "which is not supported."); break; } @@ -945,10 +965,14 @@ RevolveGenerator::generate() axis_node_case, is_flipped); } + else + mooseError("You either have a degenerate QUAD9 element, or the mid-point of the " + "on-axis edge of the QUAD9 element is not colinear with the two vertices, " + "which is not supported."); break; } default: - libmesh_not_implemented(); + mooseError("The input mesh contains unsupported element type(s)."); } new_elem->set_id(elem->id() + (current_layer * orig_elem)); new_elem->processor_id() = elem->processor_id(); @@ -997,7 +1021,8 @@ RevolveGenerator::generate() new_elem->subdomain_id() = edge_to_tri_subdomain_id_shift + elem->subdomain_id(); break; default: - mooseError("impossible situation"); + mooseAssert(false, + "impossible element type generated by revolving an EDGE2 element"); } break; case EDGE3: @@ -1010,7 +1035,8 @@ RevolveGenerator::generate() new_elem->subdomain_id() = edge_to_tri_subdomain_id_shift + elem->subdomain_id(); break; default: - mooseError("impossible situation"); + mooseAssert(false, + "impossible element type generated by revolving an EDGE3 element"); } break; case TRI3: @@ -1026,7 +1052,7 @@ RevolveGenerator::generate() new_elem->subdomain_id() = tri_to_tet_subdomain_id_shift + elem->subdomain_id(); break; default: - mooseError("impossible situation"); + mooseAssert(false, "impossible element type generated by revolving a TRI3 element"); } break; case TRI6: @@ -1042,7 +1068,7 @@ RevolveGenerator::generate() new_elem->subdomain_id() = tri_to_tet_subdomain_id_shift + elem->subdomain_id(); break; default: - mooseError("impossible situation"); + mooseAssert(false, "impossible element type generated by revolving a TRI6 element"); } break; case TRI7: @@ -1058,7 +1084,7 @@ RevolveGenerator::generate() new_elem->subdomain_id() = tri_to_tet_subdomain_id_shift + elem->subdomain_id(); break; default: - mooseError("impossible situation"); + mooseAssert(false, "impossible element type generated by revolving a TRI7 element"); } break; case QUAD4: @@ -1077,7 +1103,8 @@ RevolveGenerator::generate() quad_to_prism_subdomain_id_shift + elem->subdomain_id(); break; default: - mooseError("impossible situation"); + mooseAssert(false, + "impossible element type generated by revolving a QUAD4 element"); } break; case QUAD8: @@ -1090,7 +1117,8 @@ RevolveGenerator::generate() new_elem->subdomain_id() = quad_to_prism_subdomain_id_shift + elem->subdomain_id(); break; default: - mooseError("impossible situation"); + mooseAssert(false, + "impossible element type generated by revolving a QUAD8 element"); } break; case QUAD9: @@ -1110,11 +1138,14 @@ RevolveGenerator::generate() quad_to_hi_pyramid_subdomain_id_shift + elem->subdomain_id(); break; default: - mooseError("impossible situation"); + mooseAssert(false, + "impossible element type generated by revolving a QUAD9 element"); } break; default: - mooseError("impossible situation"); + mooseAssert(false, + "The input mesh contains unsupported element type(s), which should have " + "been checked in prior steps in this code."); } if (_subdomain_swap_pairs.size()) @@ -1196,7 +1227,8 @@ RevolveGenerator::generate() added_elem, cast_int(s), ids_to_copy_swapped); break; default: - mooseError("impossible situation"); + mooseAssert(false, + "impossible element type generated by revolving an EDGE2 element"); } break; case EDGE3: @@ -1212,7 +1244,8 @@ RevolveGenerator::generate() added_elem, cast_int(s), ids_to_copy_swapped); break; default: - mooseError("impossible situation"); + mooseAssert(false, + "impossible element type generated by revolving an EDGE3 element"); } break; case TRI3: @@ -1242,7 +1275,8 @@ RevolveGenerator::generate() added_elem, cast_int(3), ids_to_copy_swapped); break; default: - mooseError("impossible situation"); + mooseAssert(false, + "impossible element type generated by revolving a TRI3 element"); } break; case TRI6: @@ -1272,7 +1306,8 @@ RevolveGenerator::generate() added_elem, cast_int(3), ids_to_copy_swapped); break; default: - mooseError("impossible situation"); + mooseAssert(false, + "impossible element type generated by revolving a TRI6 element"); } break; case TRI7: @@ -1302,7 +1337,8 @@ RevolveGenerator::generate() added_elem, cast_int(3), ids_to_copy_swapped); break; default: - mooseError("impossible situation"); + mooseAssert(false, + "impossible element type generated by revolving a TRI7 element"); } break; case QUAD4: @@ -1338,7 +1374,8 @@ RevolveGenerator::generate() added_elem_1, cast_int(2), ids_to_copy_swapped); break; default: - mooseError("impossible situation"); + mooseAssert(false, + "impossible element type generated by revolving a QUAD4 element"); } break; case QUAD8: @@ -1360,7 +1397,8 @@ RevolveGenerator::generate() added_elem, cast_int(0), ids_to_copy_swapped); break; default: - mooseError("impossible situation"); + mooseAssert(false, + "impossible element type generated by revolving a QUAD8 element"); } break; case QUAD9: @@ -1396,11 +1434,14 @@ RevolveGenerator::generate() added_elem_1, cast_int(2), ids_to_copy_swapped); break; default: - mooseError("impossible situation"); + mooseAssert(false, + "impossible element type generated by revolving a QUAD9 element"); } break; default: - mooseError("impossible situation"); + mooseAssert(false, + "The input mesh contains unsupported element type(s), which should have " + "been checked in prior steps in this code."); } } diff --git a/modules/reactor/test/tests/meshgenerators/revolve_generator/tests b/modules/reactor/test/tests/meshgenerators/revolve_generator/tests index 87b1f54f189c..315fc46a1e43 100644 --- a/modules/reactor/test/tests/meshgenerators/revolve_generator/tests +++ b/modules/reactor/test/tests/meshgenerators/revolve_generator/tests @@ -228,6 +228,14 @@ [] [error] requirement = "The system shall throw an error if " + [err_3d_input] + type = 'RunException' + input = 'revolve_2d.i' + cli_args = '--mesh-only err_revolve_2d.e + Mesh/gmg/dim=3' + expect_err = 'This mesh generator only works for 1D and 2D input meshes.' + detail = "if input mesh has an inappropriate dimension." + [] [err_1d_nonverticle] type = 'RunException' input = 'revolve_1d.i' @@ -244,7 +252,7 @@ expect_err = 'The input mesh is either across the axis or overlapped with the axis' detail = "if the input 1D mesh has its centroid overlapped with the rotation axis." [] - [err_input_across_axis] + [err_1d_input_across_axis] type = 'RunException' input = 'revolve_1d.i' cli_args = '--mesh-only err_revolve_1d.e @@ -252,6 +260,14 @@ expect_err = 'The input mesh is across the axis' detail = "if the input 1D mesh is across the rotation axis." [] + [err_2d_input_across_axis] + type = 'RunException' + input = 'revolve_2d.i' + cli_args = '--mesh-only err_revolve_2d.e + Mesh/rg/axis_point="0.3 0.0 0.0"' + expect_err = 'The input mesh is across the axis' + detail = "if the input 2D mesh is across the rotation axis." + [] [err_input_off_plane] type = 'RunException' input = 'revolve_1d.i'