diff --git a/modules/reactor/doc/content/source/meshgenerators/FlexiblePatternGenerator.md b/modules/reactor/doc/content/source/meshgenerators/FlexiblePatternGenerator.md index 1bec42b7bada..f0870839d439 100644 --- a/modules/reactor/doc/content/source/meshgenerators/FlexiblePatternGenerator.md +++ b/modules/reactor/doc/content/source/meshgenerators/FlexiblePatternGenerator.md @@ -91,6 +91,12 @@ In both [!param](/Mesh/FlexiblePatternGenerator/hex_patterns) and [!param](/Mesh id=mixed_pattern_m caption=Output example of mixed patterning with dummy unit meshes. +## Extra Element ID Assignment for Unit Meshes + +For each unit mesh involved in the patterning, two types of extra element IDs can be automatically assigned to facilitate subsequent data analysis, using different assignment modes. + +The `cell` style extra element ID can be specified using the [!param](/Mesh/FlexiblePatternGenerator/cell_id_name) parameter. It is similar to the `cell` option in [`PatternedHexMeshGenerator`](/PatternedHexMeshGenerator.md)'s [!param](/Mesh/PatternedHexMeshGenerator/assign_type) parameter, which assigns a unique extra element ID for each component unit mesh in sequential order. On the other hand, the `pattern` style extra element ID can be specified using the [!param](/Mesh/FlexiblePatternGenerator/pattern_id_name) parameter. It is similar to the `pattern` option in [`PatternedHexMeshGenerator`](/PatternedHexMeshGenerator.md)'s [!param](/Mesh/PatternedHexMeshGenerator/assign_type) parameter, which assigns the extra element ID based on the IDs (i.e., sequential order) of the input meshes defined in [!param](/Mesh/FlexiblePatternGenerator/inputs). By default, both assigned extra element IDs begin with 0 and increment by 1. Alternatively, these generated extra element IDs can be shifted using the [!param](/Mesh/FlexiblePatternGenerator/cell_id_shift) and [!param](/Mesh/FlexiblePatternGenerator/pattern_id_shift), respectively. + !syntax parameters /Mesh/FlexiblePatternGenerator !syntax inputs /Mesh/FlexiblePatternGenerator diff --git a/modules/reactor/include/meshgenerators/FlexiblePatternGenerator.h b/modules/reactor/include/meshgenerators/FlexiblePatternGenerator.h index c6250331ab10..f58b0266a440 100644 --- a/modules/reactor/include/meshgenerators/FlexiblePatternGenerator.h +++ b/modules/reactor/include/meshgenerators/FlexiblePatternGenerator.h @@ -74,6 +74,15 @@ class FlexiblePatternGenerator : public PolygonMeshGeneratorBase // PolygonMeshGeneratorBase::INTRINSIC_SIDESET_ID::OUTER_SIDESET_ID) from the inputs const bool _delete_default_external_boundary_from_inputs; + /// Name of the extra element id to be assigned to distinguish component unit cell meshes + const ExtraElementIDName _cell_id_name; + /// Shift value to be added to the extra element id to distinguish component unit cell meshes + const dof_id_type _cell_id_shift; + /// Name of the extra element id to be assigned to distinguish input unit meshes + const ExtraElementIDName _pattern_id_name; + /// Shift value to be added to the extra element id to distinguish input unit meshes + const dof_id_type _pattern_id_shift; + /// Boundary ID of the external boundary const boundary_id_type _external_boundary_id; /// Boundary Name of the external boundary diff --git a/modules/reactor/src/meshgenerators/FlexiblePatternGenerator.C b/modules/reactor/src/meshgenerators/FlexiblePatternGenerator.C index 41849fed526b..c8f8bdbbf206 100644 --- a/modules/reactor/src/meshgenerators/FlexiblePatternGenerator.C +++ b/modules/reactor/src/meshgenerators/FlexiblePatternGenerator.C @@ -129,6 +129,26 @@ FlexiblePatternGenerator::validParams() true, "Whether to delete the default external boundary from the input meshes."); + params.addParam( + "cell_id_name", + "The name of the extra element id to be assigned for each component " + "unit mesh in sequential order."); + + params.addParam( + "cell_id_shift", + 0, + "The shift value to be added to the cell id to avoid conflicts with ids in other meshes."); + + params.addParam( + "pattern_id_name", + "The name of the extra element id to be assigned based on the ID of " + "the input meshes in sequential order."); + + params.addParam( + "pattern_id_shift", + 0, + "The shift value to be added to the pattern id to avoid conflicts with ids in other meshes."); + params.addClassDescription("This FlexiblePatternGenerator object is designed to generate a " "mesh with a background region with dispersed unit meshes in " "it and distributed based on a series of flexible patterns."); @@ -151,6 +171,8 @@ FlexiblePatternGenerator::validParams() "boundary_type boundary_mesh boundary_sectors boundary_size " "delete_default_external_boundary_from_inputs external_boundary_id external_boundary_name", "Boundary"); + params.addParamNamesToGroup("cell_id_name cell_id_shift pattern_id_name pattern_id_shift", + "Reporting Id"); return params; } @@ -207,6 +229,13 @@ FlexiblePatternGenerator::FlexiblePatternGenerator(const InputParameters & param : SubdomainName()), _delete_default_external_boundary_from_inputs( getParam("delete_default_external_boundary_from_inputs")), + _cell_id_name(isParamValid("cell_id_name") ? getParam("cell_id_name") + : ExtraElementIDName()), + _cell_id_shift(getParam("cell_id_shift")), + _pattern_id_name(isParamValid("pattern_id_name") + ? getParam("pattern_id_name") + : ExtraElementIDName()), + _pattern_id_shift(getParam("pattern_id_shift")), _external_boundary_id(isParamValid("external_boundary_id") ? getParam("external_boundary_id") : (boundary_id_type)OUTER_SIDESET_ID), @@ -217,6 +246,15 @@ FlexiblePatternGenerator::FlexiblePatternGenerator(const InputParameters & param { declareMeshesForSub("inputs"); + if (_cell_id_name.empty() && isParamSetByUser("cell_id_name")) + paramError("cell_id_name", "This parameter must be non empty if provided."); + if (_cell_id_name.empty() && isParamSetByUser("cell_id_shift")) + paramError("cell_id_name", "This parameter must be provided if cell_id_shift is set."); + if (_pattern_id_name.empty() && isParamSetByUser("pattern_id_name")) + paramError("pattern_id_name", "This parameter must be non empty if provided."); + if (_pattern_id_name.empty() && isParamSetByUser("pattern_id_shift")) + paramError("pattern_id_name", "This parameter must be provided if pattern_id_shift is set."); + const std::vector extra_positions(getParam>("extra_positions")); const std::vector extra_positions_mg_indices( getParam>("extra_positions_mg_indices")); @@ -509,6 +547,28 @@ FlexiblePatternGenerator::FlexiblePatternGenerator(const InputParameters & param patterned_pin_mg_series.push_back(name() + "_pos_" + std::to_string(i)); addMeshSubgenerator("TransformGenerator", patterned_pin_mg_series.back(), params); + + if (_cell_id_name.size()) + { + auto params = _app.getFactory().getValidParams("ParsedExtraElementIDGenerator"); + params.set("input") = patterned_pin_mg_series.back(); + params.set("expression") = std::to_string(i + _cell_id_shift); + params.set("extra_elem_integer_name") = _cell_id_name; + + patterned_pin_mg_series.back() = name() + "_ceeid_" + std::to_string(i); + addMeshSubgenerator("ParsedExtraElementIDGenerator", patterned_pin_mg_series.back(), params); + } + if (_pattern_id_name.size()) + { + auto params = _app.getFactory().getValidParams("ParsedExtraElementIDGenerator"); + params.set("input") = patterned_pin_mg_series.back(); + params.set("expression") = + std::to_string(_positions[i].second + _pattern_id_shift); + params.set("extra_elem_integer_name") = _pattern_id_name; + + patterned_pin_mg_series.back() = name() + "_peeid_" + std::to_string(i); + addMeshSubgenerator("ParsedExtraElementIDGenerator", patterned_pin_mg_series.back(), params); + } } auto params = _app.getFactory().getValidParams("XYDelaunayGenerator"); diff --git a/modules/reactor/test/tests/meshgenerators/flexible_pattern_generator/fp_eeid.i b/modules/reactor/test/tests/meshgenerators/flexible_pattern_generator/fp_eeid.i new file mode 100644 index 000000000000..8934985feb80 --- /dev/null +++ b/modules/reactor/test/tests/meshgenerators/flexible_pattern_generator/fp_eeid.i @@ -0,0 +1,125 @@ +[Mesh] + [accg_1] + type = AdvancedConcentricCircleGenerator + num_sectors = 9 + ring_radii = '2' + ring_intervals = '1' + ring_block_ids = '10' + ring_block_names = 'accg_1' + create_outward_interface_boundaries = false + [] + [accg_2] + type = AdvancedConcentricCircleGenerator + num_sectors = 9 + ring_radii = '2' + ring_intervals = '1' + ring_block_ids = '20' + ring_block_names = 'accg_2' + create_outward_interface_boundaries = false + [] + [accg_3] + type = AdvancedConcentricCircleGenerator + num_sectors = 9 + ring_radii = '2' + ring_intervals = '1' + ring_block_ids = '30' + ring_block_names = 'accg_3' + create_outward_interface_boundaries = false + [] + [fpg] + type = FlexiblePatternGenerator + inputs = 'accg_1 accg_2 accg_3' + boundary_type = HEXAGON + boundary_size = ${fparse 12.0*sqrt(3.0)} + boundary_sectors = 10 + + extra_positions = '0.0 6.0 0.0 + 0.0 -6.0 0.0 + 0.0 0.0 0.0' + extra_positions_mg_indices = '0 1 2' + + desired_area = 1.0 + [] +[] + +[Problem] + solve = false +[] + +[AuxVariables] + [pin_id] + order = CONSTANT + family = MONOMIAL + [] +[] + +[AuxKernels] + [pin_id] + type = ExtraElementIDAux + extra_id_name = pin_id + variable = pin_id + [] +[] + +[Postprocessors] + [accg_1_pin_id_avg] + type = ElementAverageValue + variable = pin_id + block = 10 + [] + [accg_2_pin_id_avg] + type = ElementAverageValue + variable = pin_id + block = 20 + [] + [accg_3_pin_id_avg] + type = ElementAverageValue + variable = pin_id + block = 30 + [] + [accg_1_pin_id_max] + type = ElementExtremeValue + variable = pin_id + block = 10 + [] + [accg_2_pin_id_max] + type = ElementExtremeValue + variable = pin_id + block = 20 + [] + [accg_3_pin_id_max] + type = ElementExtremeValue + variable = pin_id + block = 30 + [] + [accg_1_pin_id_min] + type = ElementExtremeValue + variable = pin_id + block = 10 + value_type = min + [] + [accg_2_pin_id_min] + type = ElementExtremeValue + variable = pin_id + block = 20 + value_type = min + [] + [accg_3_pin_id_min] + type = ElementExtremeValue + variable = pin_id + block = 30 + value_type = min + [] +[] + +[Executioner] + type = Transient + num_steps = 1 +[] + +[Outputs] + [csv] + type = CSV + execute_on = FINAL + [] +[] diff --git a/modules/reactor/test/tests/meshgenerators/flexible_pattern_generator/fp_eeid_pattern.i b/modules/reactor/test/tests/meshgenerators/flexible_pattern_generator/fp_eeid_pattern.i new file mode 100644 index 000000000000..be21e0a2a7b6 --- /dev/null +++ b/modules/reactor/test/tests/meshgenerators/flexible_pattern_generator/fp_eeid_pattern.i @@ -0,0 +1,104 @@ +[Mesh] + [accg_1] + type = AdvancedConcentricCircleGenerator + num_sectors = 9 + ring_radii = '2' + ring_intervals = '1' + ring_block_ids = '10' + ring_block_names = 'accg_1' + create_outward_interface_boundaries = false + [] + [accg_2] + type = AdvancedConcentricCircleGenerator + num_sectors = 9 + ring_radii = '2' + ring_intervals = '1' + ring_block_ids = '20' + ring_block_names = 'accg_2' + create_outward_interface_boundaries = false + [] + [fpg] + type = FlexiblePatternGenerator + inputs = 'accg_1 accg_2' + boundary_type = HEXAGON + boundary_size = ${fparse 12.0*sqrt(3.0)} + boundary_sectors = 10 + + extra_positions = '0.0 6.0 0.0 + 0.0 -6.0 0.0 + 0.0 0.0 0.0' + extra_positions_mg_indices = '0 1 0' + + pattern_id_name = pattern_id + pattern_id_shift = 20 + + desired_area = 1.0 + [] +[] + +[Problem] + solve = false +[] + +[AuxVariables] + [pattern_id] + order = CONSTANT + family = MONOMIAL + [] +[] + +[AuxKernels] + [pin_id] + type = ExtraElementIDAux + extra_id_name = pattern_id + variable = pattern_id + [] +[] + +[Postprocessors] + [accg_1_pin_id_avg] + type = ElementAverageValue + variable = pattern_id + block = 10 + [] + [accg_1_pin_id_max] + type = ElementExtremeValue + variable = pattern_id + block = 10 + [] + [accg_1_pin_id_min] + type = ElementExtremeValue + variable = pattern_id + block = 10 + value_type = min + [] + [accg_2_pin_id_avg] + type = ElementAverageValue + variable = pattern_id + block = 20 + [] + [accg_2_pin_id_max] + type = ElementExtremeValue + variable = pattern_id + block = 20 + [] + [accg_2_pin_id_min] + type = ElementExtremeValue + variable = pattern_id + block = 20 + value_type = min + [] +[] + +[Executioner] + type = Transient + num_steps = 1 +[] + +[Outputs] + [csv] + type = CSV + execute_on = FINAL + file_base = 'fp_eeid_pattern' + [] +[] diff --git a/modules/reactor/test/tests/meshgenerators/flexible_pattern_generator/gold/fp_eeid_cell.csv b/modules/reactor/test/tests/meshgenerators/flexible_pattern_generator/gold/fp_eeid_cell.csv new file mode 100644 index 000000000000..206dde01e3f1 --- /dev/null +++ b/modules/reactor/test/tests/meshgenerators/flexible_pattern_generator/gold/fp_eeid_cell.csv @@ -0,0 +1,2 @@ +time,accg_1_pin_id_avg,accg_1_pin_id_max,accg_1_pin_id_min,accg_2_pin_id_avg,accg_2_pin_id_max,accg_2_pin_id_min,accg_3_pin_id_avg,accg_3_pin_id_max,accg_3_pin_id_min +1,1,1,1,2,2,2,3,3,3 diff --git a/modules/reactor/test/tests/meshgenerators/flexible_pattern_generator/gold/fp_eeid_pattern.csv b/modules/reactor/test/tests/meshgenerators/flexible_pattern_generator/gold/fp_eeid_pattern.csv new file mode 100644 index 000000000000..472df3a2218d --- /dev/null +++ b/modules/reactor/test/tests/meshgenerators/flexible_pattern_generator/gold/fp_eeid_pattern.csv @@ -0,0 +1,2 @@ +time,accg_1_pin_id_avg,accg_1_pin_id_max,accg_1_pin_id_min,accg_2_pin_id_avg,accg_2_pin_id_max,accg_2_pin_id_min +1,20,20,20,21,21,21 diff --git a/modules/reactor/test/tests/meshgenerators/flexible_pattern_generator/tests b/modules/reactor/test/tests/meshgenerators/flexible_pattern_generator/tests index 574f7aa771c6..baa3e6e65086 100644 --- a/modules/reactor/test/tests/meshgenerators/flexible_pattern_generator/tests +++ b/modules/reactor/test/tests/meshgenerators/flexible_pattern_generator/tests @@ -1,6 +1,6 @@ [Tests] design = 'meshgenerators/FlexiblePatternGenerator.md' - issues = '#24938 #26776 #27471' + issues = '#24938 #26776 #27471 #29529' [test] requirement = "The system shall generate " [single_hex_pattern_hex] @@ -89,6 +89,23 @@ recover = false detail = "a mixed patterned mesh with hexagonal background." [] + [eeid_cell] + type = CSVDiff + input = fp_eeid.i + csvdiff = fp_eeid_cell.csv + cli_args = "Mesh/fpg/cell_id_name='pin_id' + Mesh/fpg/cell_id_shift=1 + Outputs/csv/file_base=fp_eeid_cell" + recover = false + detail = "a patterned mesh with an extra element id assigned to each component mesh (cell mode)." + [] + [eeid_pattern] + type = CSVDiff + input = fp_eeid_pattern.i + csvdiff = fp_eeid_pattern.csv + recover = false + detail = "a patterned mesh with an extra element id assigned to each input mesh (pattern mode)." + [] [patterned_assm] type = CSVDiff input = patterned_assm.i @@ -333,5 +350,33 @@ expect_err = "this parameter must be provided for non-CUSTOM" detail = "if the boundary pitch value is not provided when the boundary type is not custom." [] + [error_empty_cell_eeid_name] + type = RunException + input = fp_eeid.i + cli_args = "Mesh/fpg/cell_id_name=''" + expect_err = "This parameter must be non empty if provided." + detail = "if an empty cell type id name is provided." + [] + [error_standalone_cell_eeid_shift] + type = RunException + input = fp_eeid.i + cli_args = "Mesh/fpg/cell_id_shift=1" + expect_err = "This parameter must be provided if cell_id_shift is set." + detail = "if a cell type id shift is set without specifying the unit mesh id name." + [] + [error_empty_pattern_eeid_name] + type = RunException + input = fp_eeid.i + cli_args = "Mesh/fpg/pattern_id_name=''" + expect_err = "This parameter must be non empty if provided." + detail = "if an empty pattern id name is provided." + [] + [error_standalone_pattern_eeid_shift] + type = RunException + input = fp_eeid.i + cli_args = "Mesh/fpg/pattern_id_shift=1" + expect_err = "This parameter must be provided if pattern_id_shift is set." + detail = "if a pattern id shift is set without specifying the unit mesh id name." + [] [] []