85 _nt(getParam<unsigned
int>(
"nt")),
86 _rmin(getParam<Real>(
"rmin")),
87 _rmax(getParam<Real>(
"rmax")),
88 _radial_positions(getParam<
std::vector<Real>>(
"radial_positions")),
89 _nr(parameters.isParamSetByUser(
"radial_positions") ? _radial_positions.size() + 1
90 : getParam<unsigned
int>(
"nr")),
91 _dmin(parameters.isParamSetByUser(
"tmin") ? getParam<Real>(
"tmin") / M_PI * 180.0
92 : getParam<Real>(
"dmin")),
93 _dmax(parameters.isParamSetByUser(
"tmax") ? getParam<Real>(
"tmax") / M_PI * 180.0
94 : getParam<Real>(
"dmax")),
95 _radians((parameters.isParamSetByUser(
"tmin") || parameters.isParamSetByUser(
"tmax")) ? true
97 _growth_r(getParam<Real>(
"growth_r")),
98 _len(_growth_r == 1.0 ? (_rmax - _rmin) / _nr
99 : (_rmax - _rmin) * (1.0 -
std::abs(_growth_r)) /
100 (1.0 -
std::pow(
std::abs(_growth_r), _nr))),
101 _full_annulus(_dmin == 0.0 && _dmax == 360),
102 _quad_subdomain_id(getParam<
SubdomainID>(
"quad_subdomain_id")),
103 _tri_subdomain_id(getParam<
SubdomainID>(
"tri_subdomain_id")),
104 _equal_area(getParam<bool>(
"equal_area")),
105 _boundary_name_prefix(isParamValid(
"boundary_name_prefix")
106 ? getParam<BoundaryName>(
"boundary_name_prefix") +
"_"
108 _boundary_id_offset(getParam<boundary_id_type>(
"boundary_id_offset"))
113 "You specified the angles using both degrees and radians. Please use degrees.");
118 paramError(
"nr",
"The 'nr' parameter cannot be specified together with 'radial_positions'");
121 "The 'equal_area' parameter cannot be specified together with 'radial_positions'");
124 "The 'growth_r' parameter cannot be specified together with 'radial_positions'");
126 if (rpos <= _rmin || rpos >=
_rmax)
129 "The following provided value is not within the bounds between 'rmin' and 'rmax': ",
134 paramError(
"growth_r",
"The 'growth_r' parameter cannot be combined with 'equal_area'");
137 paramError(
"rmax",
"rmax must be greater than rmin");
139 paramError(
"dmax",
"dmax must be greater than dmin");
141 paramError(
"dmax",
"dmax - dmin must be <= 360");
144 "nt must be greater than (dmax - dmin) / 180 in order to avoid inverted "
147 paramError(
"quad_subdomain_id",
"quad_subdomain_id must not equal tri_subdomain_id");
158 mesh->set_mesh_dimension(2);
159 mesh->set_spatial_dimension(2);
160 BoundaryInfo & boundary_info =
mesh->get_boundary_info();
163 const unsigned num_nodes =
164 (
_rmin > 0.0 ? (
_nr + 1) * num_angular_nodes :
_nr * num_angular_nodes + 1);
165 const unsigned min_nonzero_layer_num = (
_rmin > 0.0 ? 0 : 1);
166 std::vector<Node *> nodes(num_nodes);
167 unsigned node_id = 0;
170 Real current_r =
_rmax;
171 for (
unsigned angle_num = 0; angle_num < num_angular_nodes; ++angle_num)
173 const Real angle =
_dmin + angle_num * dt;
174 const Real x = current_r * std::cos(angle * M_PI / 180.0);
175 const Real y = current_r * std::sin(angle * M_PI / 180.0);
176 nodes[node_id] =
mesh->add_point(Point(x, y, 0.0), node_id);
181 Real outer_r =
_rmax;
184 for (
unsigned layer_num =
_nr; layer_num > min_nonzero_layer_num; --layer_num)
195 current_r = std::sqrt(outer_r * outer_r - ring_area);
208 nodes[node_id] =
mesh->add_point(Point(current_r * std::cos(
_dmin * M_PI / 180.0),
209 current_r * std::sin(
_dmin * M_PI / 180.0),
213 for (
unsigned angle_num = 1; angle_num < num_angular_nodes; ++angle_num)
215 const Real angle =
_dmin + angle_num * dt;
216 const Real x = current_r * std::cos(angle * M_PI / 180.0);
217 const Real y = current_r * std::sin(angle * M_PI / 180.0);
218 nodes[node_id] =
mesh->add_point(Point(x, y, 0.0), node_id);
219 Elem * elem =
mesh->add_elem(
new Quad4);
220 elem->set_node(0, nodes[node_id]);
221 elem->set_node(1, nodes[node_id - 1]);
222 elem->set_node(2, nodes[node_id - num_angular_nodes - 1]);
223 elem->set_node(3, nodes[node_id - num_angular_nodes]);
227 if (layer_num ==
_nr)
229 boundary_info.add_side(elem, 2, 1);
232 boundary_info.add_side(elem, 0, 0);
235 boundary_info.add_side(elem, 1, 2);
238 boundary_info.add_side(elem, 3, 3);
243 Elem * elem =
mesh->add_elem(
new Quad4);
244 elem->set_node(0, nodes[node_id - num_angular_nodes]);
245 elem->set_node(1, nodes[node_id - 1]);
246 elem->set_node(2, nodes[node_id - num_angular_nodes - 1]);
247 elem->set_node(3, nodes[node_id - 2 * num_angular_nodes]);
250 if (layer_num ==
_nr)
252 boundary_info.add_side(elem, 2, 1);
255 boundary_info.add_side(elem, 0, 0);
262 nodes[node_id] =
mesh->add_point(Point(0.0, 0.0, 0.0), node_id);
263 boundary_info.add_node(node_id, 0);
264 for (
unsigned angle_num = 0; angle_num < num_angular_nodes - 1; ++angle_num)
266 Elem * elem =
mesh->add_elem(
new Tri3);
267 elem->set_node(0, nodes[node_id]);
268 elem->set_node(1, nodes[node_id - num_angular_nodes + angle_num]);
269 elem->set_node(2, nodes[node_id - num_angular_nodes + angle_num + 1]);
274 Elem * elem =
mesh->add_elem(
new Tri3);
275 elem->set_node(0, nodes[node_id]);
276 elem->set_node(1, nodes[node_id - 1]);
277 elem->set_node(2, nodes[node_id - num_angular_nodes]);
282 boundary_info.sideset_name(0) =
"rmin";
283 boundary_info.sideset_name(1) =
"rmax";
284 boundary_info.nodeset_name(0) =
"rmin";
285 boundary_info.nodeset_name(1) =
"rmax";
290 boundary_info.sideset_name(2) =
"tmin";
291 boundary_info.sideset_name(3) =
"tmax";
292 boundary_info.nodeset_name(2) =
"tmin";
293 boundary_info.nodeset_name(3) =
"tmax";
297 boundary_info.sideset_name(2) =
"dmin";
298 boundary_info.sideset_name(3) =
"dmax";
299 boundary_info.nodeset_name(2) =
"dmin";
300 boundary_info.nodeset_name(3) =
"dmax";
306 const auto mesh_boundary_ids = boundary_info.get_boundary_ids();
307 for (
auto rit = mesh_boundary_ids.rbegin(); rit != mesh_boundary_ids.rend(); ++rit)
310 const std::string old_sideset_name = boundary_info.sideset_name(*rit);
311 const std::string old_nodeset_name = boundary_info.nodeset_name(*rit);
326 mesh->prepare_for_use();
327 return dynamic_pointer_cast<MeshBase>(
mesh);