14#include "libmesh/face_quad4.h"
15#include "libmesh/face_tri3.h"
24 "nr", 1,
"nr>0",
"Number of elements in the radial direction");
26 "nt",
"nt>0",
"Number of elements in the angular direction");
30 "Inner radius. If rmin=0 then a disc mesh (with no central hole) will be created.");
34 "Minimum angle, measured in radians anticlockwise from x axis",
39 "Maximum angle, measured in radians anticlockwise from x axis. If "
40 "tmin=0 and tmax=2Pi an annular mesh is created. "
41 "Otherwise, only a sector of an annulus is created",
44 "dmin", 0.0,
"Minimum degree, measured in degrees anticlockwise from x axis");
47 "Maximum angle, measured in degrees anticlockwise from x axis. If "
48 "dmin=0 and dmax=360 an annular mesh is created. "
49 "Otherwise, only a sector of an annulus is created");
51 "growth_r", 1.0,
"growth_r>0.0",
"The ratio of radial sizes of successive rings of elements");
53 "quad_subdomain_id", 0,
"The subdomain ID given to the QUAD4 elements");
56 "The subdomain ID given to the TRI3 elements "
57 "(these exist only if rmin=0, and they exist "
58 "at the center of the disc");
59 params.
addClassDescription(
"For rmin>0: creates an annular mesh of QUAD4 elements. For rmin=0: "
60 "creates a disc mesh of QUAD4 and TRI3 elements. Boundary sidesets "
61 "are created at rmax and rmin, and given these names. If dmin!=0 and "
62 "dmax!=360, a sector of an annulus or disc is created. In this case "
63 "boundary sidesets are also created a dmin and dmax, and "
70 _nr(getParam<unsigned
int>(
"nr")),
71 _nt(getParam<unsigned
int>(
"nt")),
72 _rmin(getParam<Real>(
"rmin")),
73 _rmax(getParam<Real>(
"rmax")),
74 _dmin(parameters.isParamSetByUser(
"tmin") ? getParam<Real>(
"tmin") / M_PI * 180.0
75 : getParam<Real>(
"dmin")),
76 _dmax(parameters.isParamSetByUser(
"tmax") ? getParam<Real>(
"tmax") / M_PI * 180.0
77 : getParam<Real>(
"dmax")),
78 _radians((parameters.isParamSetByUser(
"tmin") || parameters.isParamSetByUser(
"tmax")) ? true
80 _growth_r(getParam<Real>(
"growth_r")),
81 _len(_growth_r == 1.0 ? (_rmax - _rmin) / _nr
82 : (_rmax - _rmin) * (1.0 - _growth_r) / (1.0 -
std::pow(_growth_r, _nr))),
83 _full_annulus(_dmin == 0.0 && _dmax == 360),
84 _quad_subdomain_id(getParam<
SubdomainID>(
"quad_subdomain_id")),
85 _tri_subdomain_id(getParam<
SubdomainID>(
"tri_subdomain_id")),
86 _dims_may_have_changed(false)
91 "You specified the angles using both degrees and radians. Please use degrees.");
94 paramError(
"rmax",
"rmax must be greater than rmin");
96 paramError(
"dmax",
"dmax must be greater than dmin");
98 paramError(
"dmax",
"dmax - dmin must be <= 360");
101 "nt must be greater than (dmax - dmin) / 180 in order to avoid inverted "
104 paramError(
"quad_subdomain_id",
"quad_subdomain_id must not equal tri_subdomain_id");
155std::unique_ptr<MooseMesh>
168 mesh.set_mesh_dimension(2);
169 mesh.set_spatial_dimension(2);
173 const unsigned num_nodes =
174 (
_rmin > 0.0 ? (
_nr + 1) * num_angular_nodes :
_nr * num_angular_nodes + 1);
175 const unsigned min_nonzero_layer_num = (
_rmin > 0.0 ? 0 : 1);
176 std::vector<Node *> nodes(num_nodes);
177 unsigned node_id = 0;
180 Real current_r =
_rmax;
181 for (
unsigned angle_num = 0; angle_num < num_angular_nodes; ++angle_num)
183 const Real angle =
_dmin + angle_num * dt;
184 const Real x = current_r * std::cos(angle * M_PI / 180.0);
185 const Real y = current_r * std::sin(angle * M_PI / 180.0);
186 nodes[node_id] =
mesh.add_point(Point(x, y, 0.0), node_id);
191 for (
unsigned layer_num =
_nr; layer_num > min_nonzero_layer_num; --layer_num)
199 nodes[node_id] =
mesh.add_point(Point(current_r * std::cos(
_dmin * M_PI / 180.0),
200 current_r * std::sin(
_dmin * M_PI / 180.0),
204 for (
unsigned angle_num = 1; angle_num < num_angular_nodes; ++angle_num)
206 const Real angle =
_dmin + angle_num * dt;
207 const Real x = current_r * std::cos(angle * M_PI / 180.0);
208 const Real y = current_r * std::sin(angle * M_PI / 180.0);
209 nodes[node_id] =
mesh.add_point(Point(x, y, 0.0), node_id);
211 elem->set_node(0, nodes[node_id]);
212 elem->set_node(1, nodes[node_id - 1]);
213 elem->set_node(2, nodes[node_id - num_angular_nodes - 1]);
214 elem->set_node(3, nodes[node_id - num_angular_nodes]);
218 if (layer_num ==
_nr)
235 elem->set_node(0, nodes[node_id - num_angular_nodes]);
236 elem->set_node(1, nodes[node_id - 1]);
237 elem->set_node(2, nodes[node_id - num_angular_nodes - 1]);
238 elem->set_node(3, nodes[node_id - 2 * num_angular_nodes]);
241 if (layer_num ==
_nr)
253 nodes[node_id] =
mesh.add_point(Point(0.0, 0.0, 0.0), node_id);
255 for (
unsigned angle_num = 0; angle_num < num_angular_nodes - 1; ++angle_num)
258 elem->set_node(0, nodes[node_id]);
259 elem->set_node(1, nodes[node_id - num_angular_nodes + angle_num]);
260 elem->set_node(2, nodes[node_id - num_angular_nodes + angle_num + 1]);
266 elem->set_node(0, nodes[node_id]);
267 elem->set_node(1, nodes[node_id - 1]);
268 elem->set_node(2, nodes[node_id - num_angular_nodes]);
298 mesh.prepare_for_use();
registerMooseObject("MooseApp", AnnularMesh)
void ErrorVector unsigned int
Mesh generated from parameters.
const bool _full_annulus
Whether a full annulus (as opposed to a sector) will needs to generate.
AnnularMesh(const InputParameters ¶meters)
const unsigned _nr
Number of elements in radial direction.
const Real _growth_r
Bias on radial meshing.
const SubdomainID _quad_subdomain_id
Subdomain ID of created quad elements.
virtual void buildMesh() override
Must be overridden by child classes.
const Real _len
rmax = rmin + len + len*g + len*g^2 + len*g^3 + ... + len*g^(nr-1) = rmin + len*(1 - g^nr)/(1 - g)
const Real _rmax
Maximum radius.
static InputParameters validParams()
const unsigned _nt
Number of elements in angular direction.
bool _dims_may_have_changed
Boolean to indicate that dimensions may have changed.
virtual std::unique_ptr< MooseMesh > safeClone() const override
A safer version of the clone() method that hands back an allocated object wrapped in a smart pointer.
const Real _dmin
Minimum angle in degrees.
const Real _rmin
Minimum radius.
virtual Real getMinInDimension(unsigned int component) const override
Returns the min or max of the requested dimension respectively.
const Real _dmax
Maximum angle in degrees.
const bool _radians
Bool to check if radians are given in the input file.
virtual Real getMaxInDimension(unsigned int component) const override
const SubdomainID _tri_subdomain_id
Subdomain ID of created tri elements (that only exist if rmin=0)
std::unique_ptr< T > copyConstruct(const T &object)
Copy constructs the object object.
Factory & getFactory()
Retrieve a writable reference to the Factory associated with this App.
const InputParameters & parameters() const
Get the parameters of the object.
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 ...
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...
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
virtual Elem * elem(const dof_id_type i)
Various accessors (pointers/references) for Elem "i".
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
bool prepared() const
Setter/getter for whether the mesh is prepared.
virtual Real getMaxInDimension(unsigned int component) const
static InputParameters validParams()
Typical "Moose-style" constructor and copy constructor.
virtual Real getMinInDimension(unsigned int component) const
Returns the min or max of the requested dimension respectively.
MooseApp & _app
The MOOSE application this is associated with.
std::string & sideset_name(boundary_id_type id)
std::string & nodeset_name(boundary_id_type id)
void add_node(const Node *node, const boundary_id_type id)
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
MooseUnits pow(const MooseUnits &, int)