https://mooseframework.inl.gov
Loading...
Searching...
No Matches
SimpleHexagonGenerator.C
Go to the documentation of this file.
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
11
12// C++ includes
13#include <cmath>
14
16
19{
21 MooseEnum element_type("TRI QUAD HYBRID", "TRI");
22 params.addParam<MooseEnum>("element_type",
23 element_type,
24 "Whether the simple hexagon mesh is made of TRI or QUAD elements.");
26 "hexagon_size", "hexagon_size>0.0", "Size of the hexagon to be generated.");
27 MooseEnum hexagon_size_style("apothem radius", "apothem");
28 params.addParam<MooseEnum>(
29 "hexagon_size_style",
30 hexagon_size_style,
31 "Style in which the hexagon size is given (default: apothem i.e. half-pitch). Option: " +
32 hexagon_size_style.getRawNames());
33 params.addRangeCheckedParam<unsigned int>(
34 "radial_intervals",
35 "radial_intervals>1",
36 "Number of pin radial meshing rings (only applicable when 'element_type' is 'HYBRID').");
37 params.addRangeCheckedParam<std::vector<subdomain_id_type>>(
38 "block_id",
39 "block_id>=0",
40 "Optional customized block id; two ids are needed for HYBRID 'element_type'.");
41 params.addParam<std::vector<SubdomainName>>(
42 "block_name",
43 "Optional customized block name; two names are needed for HYBRID 'element_type'.");
44 params.addRangeCheckedParam<boundary_id_type>("external_boundary_id",
45 "external_boundary_id>=0",
46 "Optional customized external boundary id.");
47 params.addParam<BoundaryName>("external_boundary_name",
48 "Optional customized external boundary name.");
49 params.addParamNamesToGroup("block_id block_name external_boundary_id external_boundary_name",
50 "Customized Subdomain/Boundary");
52 "This SimpleHexagonGenerator object is designed to generate a simple hexagonal mesh that "
53 "only contains six simple azimuthal triangular elements, two quadrilateral elements, or six "
54 "central azimuthal triangular elements plus a several layers of quadrilateral elements.");
55
56 return params;
57}
58
60 : PolygonMeshGeneratorBase(parameters),
61 _element_type(getParam<MooseEnum>("element_type").template getEnum<ElemType>()),
62 _hexagon_size(getParam<Real>("hexagon_size")),
63 _hexagon_size_style(
64 getParam<MooseEnum>("hexagon_size_style").template getEnum<PolygonSizeStyle>()),
65 _radial_intervals(isParamValid("radial_intervals")
66 ? getParam<unsigned int>("radial_intervals")
67 : (_element_type == ElemType::HYBRID ? 2 : 1)),
68 _block_id(isParamValid("block_id") ? getParam<std::vector<subdomain_id_type>>("block_id")
69 : std::vector<subdomain_id_type>()),
70 _block_name(isParamValid("block_name") ? getParam<std::vector<SubdomainName>>("block_name")
71 : std::vector<SubdomainName>()),
72 _boundary_id_valid(isParamValid("external_boundary_id")),
73 _external_boundary_id(isParamValid("external_boundary_id")
74 ? getParam<boundary_id_type>("external_boundary_id")
75 : 0),
76 _external_boundary_name(isParamValid("external_boundary_name")
77 ? getParam<BoundaryName>("external_boundary_name")
78 : BoundaryName())
79{
82 "radial_intervals",
83 "A non-unity 'radial_intervals' value is only supported when 'element_type' is 'HYBRID'.");
86 : _hexagon_size * std::cos(M_PI / (Real)HEXAGON_NUM_SIDES));
87 if ((_block_id.size() > 1) && _element_type != ElemType::HYBRID)
89 "block_id",
90 "if provided, the size of this parameter must be one if 'element_type' is TRI or QUAD.");
91 if ((_block_id.size() != 0 && _block_id.size() != 2) && _element_type == ElemType::HYBRID)
92 paramError("block_id",
93 "if provided, the size of this parameter must be two if 'element_type' is HYBRID.");
94 if (_block_name.size() != 0 && _block_name.size() != _block_id.size())
95 paramError("block_name", "if provided, this parameter must have the same size as 'block_id'.");
96 declareMeshProperty<unsigned int>("background_intervals_meta", _radial_intervals);
97 declareMeshProperty<dof_id_type>("node_id_background_meta",
99 declareMeshProperty<Real>("max_radius_meta", 0.0);
100 declareMeshProperty<std::vector<unsigned int>>("num_sectors_per_side_meta", {1, 1, 1, 1, 1, 1});
101 declareMeshProperty<Real>("pitch_meta", _pitch);
102}
103
104std::unique_ptr<MeshBase>
106{
107 const Real radius = _pitch / std::sqrt(3.0);
108 auto mesh = buildReplicatedMesh(2);
109 BoundaryInfo & boundary_info = mesh->get_boundary_info();
110 // In the ElemType::TRI mode, total nodes number is 6 * _radial_intervals + 1, while
111 // _radial_intervals must be trivial (1);
112 // In the ElemType::QUAD model, total nodes number is 6 * _radial_intervals, while
113 // _radial_intervals must be trivial (1);
114 // In the ElemType::HYBRID mode, total nodes number is 6 * _radial_intervals + 1.
115 std::vector<Node *> nodes(HEXAGON_NUM_SIDES * _radial_intervals +
118 {
119 // The trivial center node with node_id = 6 (HEXAGON_NUM_SIDES) * _radial_intervals
120 Point center_p = Point(0.0, 0.0, 0.0);
122 mesh->add_point(center_p, HEXAGON_NUM_SIDES * _radial_intervals);
123 }
124 // loop to create nodes by radial layers
125 for (unsigned int j = 0; j < _radial_intervals; j++)
126 // loop to create the six nodes in each layer
127 for (unsigned int i = 0; i < HEXAGON_NUM_SIDES; i++)
128 {
129 Point side_p = Point(radius * (Real)(_radial_intervals - j) / (Real)_radial_intervals *
130 sin(M_PI / ((Real)HEXAGON_NUM_SIDES / 2.0) * (Real)i),
131 radius * (Real)(_radial_intervals - j) / (Real)_radial_intervals *
132 cos(M_PI / ((Real)HEXAGON_NUM_SIDES / 2.0) * (Real)i),
133 0.0);
134 nodes[j * HEXAGON_NUM_SIDES + i] = mesh->add_point(side_p, j * HEXAGON_NUM_SIDES + i);
135 }
136
138 {
139 // loop to create outer layer QUAD elements
140 // Note that the direction is from outer to inner
141 for (unsigned int j = 0; j < _radial_intervals - 1; j++)
142 {
143 // loop to create the six QUAD elements for each layer
144 for (unsigned int i = 0; i < HEXAGON_NUM_SIDES; i++)
145 {
146 Elem * elem = mesh->add_elem(new Quad4);
147 elem->set_node(0, nodes[HEXAGON_NUM_SIDES * j + i]);
148 elem->set_node(1, nodes[HEXAGON_NUM_SIDES * j + (i + 1) % HEXAGON_NUM_SIDES]);
149 elem->set_node(2, nodes[HEXAGON_NUM_SIDES * (j + 1) + (i + 1) % HEXAGON_NUM_SIDES]);
150 elem->set_node(3, nodes[HEXAGON_NUM_SIDES * (j + 1) + i]);
151 // Assign the default external boundary id if applicable so that the mesh can be used as
152 // input of `PatterneHexMeshGenerator`.
153 if (j == 0)
154 boundary_info.add_side(elem, 0, OUTER_SIDESET_ID);
155 // Default subdomain id
156 elem->subdomain_id() = 2;
157 }
158 }
159 // loop to create the six TRI elements
160 for (unsigned int i = 0; i < HEXAGON_NUM_SIDES; i++)
161 {
162 Elem * elem = mesh->add_elem(new Tri3);
163 elem->set_node(0, nodes[HEXAGON_NUM_SIDES * _radial_intervals]);
164 elem->set_node(2, nodes[HEXAGON_NUM_SIDES * (_radial_intervals - 1) + i]);
165 elem->set_node(
166 1, nodes[HEXAGON_NUM_SIDES * (_radial_intervals - 1) + (i + 1) % HEXAGON_NUM_SIDES]);
167 // Assign the default external boundary id if applicable so that the mesh can be used as input
168 // of `PatterneHexMeshGenerator`.
170 boundary_info.add_side(elem, 1, OUTER_SIDESET_ID);
171 // Default subdomain id
172 elem->subdomain_id() = 1;
173 }
174 }
175 else
176 // loop to create the two elements
177 for (unsigned int i = 0; i < HEXAGON_NUM_SIDES / 3; i++)
178 {
179 Elem * elem = mesh->add_elem(new Quad4);
180 elem->set_node(0, nodes[i * 3]);
181 elem->set_node(1, nodes[(i * 3 + 3) % HEXAGON_NUM_SIDES]);
182 elem->set_node(2, nodes[i * 3 + 2]);
183 elem->set_node(3, nodes[i * 3 + 1]);
184 // Assign the default external boundary id so that the mesh can be used as input of
185 // `PatterneHexMeshGenerator`.
186 boundary_info.add_side(elem, 1, OUTER_SIDESET_ID);
187 boundary_info.add_side(elem, 2, OUTER_SIDESET_ID);
188 boundary_info.add_side(elem, 3, OUTER_SIDESET_ID);
189 // Default subdomain id
190 elem->subdomain_id() = 1;
191 }
192
193 // Assign customized (optional) subdomain id/name and external boundary id/name.
194 if (!_block_id.empty())
195 for (const auto & elem : mesh->active_element_ptr_range())
196 {
197 if (elem->subdomain_id() == 1)
198 elem->subdomain_id() = _block_id.front();
199 else
200 elem->subdomain_id() = _block_id.back();
201 }
202 if (!_block_name.empty())
203 for (unsigned int i = 0; i < _block_name.size(); i++)
204 mesh->set_subdomain_name(_block_id[i], _block_name[i], true);
205
207 MooseMesh::changeBoundaryId(*mesh, OUTER_SIDESET_ID, _external_boundary_id, false);
208 if (!_external_boundary_name.empty())
209 {
210 mesh->get_boundary_info().sideset_name(
213 mesh->get_boundary_info().nodeset_name(
216 }
217
218 mesh->prepare_for_use();
219 return dynamic_pointer_cast<MeshBase>(mesh);
220}
registerMooseObject("ReactorApp", SimpleHexagonGenerator)
void ErrorVector unsigned int
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
void addRequiredRangeCheckedParam(const std::string &name, const std::string &parsed_function, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
std::unique_ptr< ReplicatedMesh > buildReplicatedMesh(unsigned int dim=libMesh::invalid_uint)
void paramError(const std::string &param, Args... args) const
A base class that contains common members for Reactor module mesh generators.
PolygonSizeStyle
An enum class for style of input polygon size.
static InputParameters validParams()
This SimpleHexagonGenerator object is designed to generate a simple hexagonal mesh that only contains...
enum SimpleHexagonGenerator::ElemType _element_type
ElemType
Type of elements to build the mesh.
const bool _boundary_id_valid
Whether external_boundary_id is provided.
Real _pitch
Pitch size of the hexagon.
const PolygonSizeStyle _hexagon_size_style
Style of the size parameter.
const boundary_id_type _external_boundary_id
Boundary ID of the external boundary.
const Real _hexagon_size
Size parameter of the hexagon.
SimpleHexagonGenerator(const InputParameters &parameters)
static InputParameters validParams()
std::unique_ptr< MeshBase > generate() override
const unsigned int _radial_intervals
Number of radial meshing intervals.
const BoundaryName _external_boundary_name
Boundary Name of the external boundary.
const std::vector< subdomain_id_type > _block_id
Subdomain ID of the mesh.
const std::vector< SubdomainName > _block_name
Subdomain Name of the mesh.
MeshBase & mesh