15 #include "libmesh/elem.h" 25 "Divide the mesh along a cylindrical grid. The innermost numbering of divisions is the " 26 "radial bins, then comes the azimuthal bins, then the axial bins");
29 params.
addRequiredParam<Point>(
"axis_direction",
"Direction of the cylinder's axis");
32 "Direction of the 0-azimuthal-angle vector, normal to the cylinder's axis");
34 "Point on the cylinder's axis, acting as the center of this local " 35 "R-theta-Z coordinate based division");
36 params.
addParam<PositionsName>(
"center_positions",
37 "Positions of the points on the cylinders' respective axis, " 38 "acting as the center of the local " 39 "R-theta-Z coordinate based divisions");
43 "r_min", 0,
"r_min>=0",
"Minimum radial coordinate (for a hollow cylinder)");
46 "cylinder_axial_min", std::numeric_limits<Real>::lowest(),
"Minimum axial coordinate");
52 "n_radial",
"n_radial>0",
"Number of divisions in the cylinder radial direction");
54 "n_azimuthal", 1,
"n_azimuthal>0",
"Number of divisions in the azimuthal direction");
56 "n_axial", 1,
"n_axial>0",
"Number of divisions in the cylinder axial direction");
58 params.
addParam<
bool>(
"assign_domain_outside_grid_to_border",
60 "Whether to map the domain outside the grid back to the border of the grid " 61 "(radially or axially)");
68 _direction(getParam<Point>(
"axis_direction")),
69 _center(isParamValid(
"center") ? &getParam<Point>(
"center") : nullptr),
71 isParamValid(
"center_positions")
72 ? &_fe_problem->getPositionsObject(getParam<PositionsName>(
"center_positions"))
74 _azim_dir(getParam<Point>(
"azimuthal_start")),
75 _min_r(getParam<
Real>(
"r_min")),
76 _max_r(getParam<
Real>(
"r_max")),
77 _min_z(getParam<
Real>(
"cylinder_axial_min")),
78 _max_z(getParam<
Real>(
"cylinder_axial_max")),
79 _n_radial(getParam<unsigned
int>(
"n_radial")),
80 _n_azim(getParam<unsigned
int>(
"n_azimuthal")),
81 _n_axial(getParam<unsigned
int>(
"n_axial")),
82 _outside_grid_counts_as_border(getParam<bool>(
"assign_domain_outside_grid_to_border"))
88 paramError(
"center",
"You must pass a parameter for the center of the cylindrical frame");
91 if (!MooseUtils::absoluteFuzzyEqual(
_direction.norm_sq(), 1))
92 paramError(
"axis_direction",
"Axis must have a norm of 1");
93 if (!MooseUtils::absoluteFuzzyEqual(
_azim_dir.norm_sq(), 1))
94 paramError(
"azimuthal_start",
"Azimuthal axis must have a norm of 1");
98 paramError(
"r_min",
"Maximum radius must be larger than minimum radius");
100 paramError(
"cylinder_axial_min",
"Maximum axial extent must be larger than minimum");
104 paramError(
"n_radial",
"Zero-thickness cylinder cannot be subdivided radially");
106 paramError(
"n_axial",
"Zero-height cylinder cannot be subdivided axially");
109 if ((
_min_z == std::numeric_limits<Real>::lowest() ||
113 "Infinite-height cylinder cannot be subdivided axially. Please specify both a " 114 "cylinder axial minimum and maximum extent");
132 if (MooseUtils::absoluteFuzzyGreaterThan(min_dist, min_center_dist))
134 "Cylindrical grids centered on the positions are too close to each other (min distance: ",
136 "), closer than the radial extent of each grid. Mesh division is ill-defined");
159 unsigned int offset = 0;
173 in_plane = (pt - new_center) - pc(2) *
_direction;
176 pc(0) = in_plane.norm();
182 if (MooseUtils::absoluteFuzzyLessThan(pc(0),
_min_r) ||
183 MooseUtils::absoluteFuzzyGreaterThan(pc(0),
_max_r))
185 if (MooseUtils::absoluteFuzzyLessThan(pc(2),
_min_z) ||
186 MooseUtils::absoluteFuzzyGreaterThan(pc(2),
_max_z))
191 auto ir = not_found, ia = not_found, iz = not_found;
198 if (jr > 0 && jr <
_n_radial && MooseUtils::absoluteFuzzyEqual(border_r, pc(0)))
200 "Querying the division index for a point of a boundary between two regions radially: " +
202 if (border_r >= pc(0))
204 ir = jr > 0 ? jr - 1 : 0;
210 const auto border_a = widths(1) * ja /
_n_azim;
211 if (ja > 0 && ja <
_n_azim && MooseUtils::absoluteFuzzyEqual(border_a, pc(1)))
212 mooseWarning(
"Querying the division index for a point of a boundary between two regions " 215 if (border_a >= pc(1))
217 ia = ja > 0 ? ja - 1 : 0;
224 if (jz > 0 && jz <
_n_axial && MooseUtils::absoluteFuzzyEqual(border_z, pc(2)))
225 mooseWarning(
"Querying the division index for a point of a boundary between two axial " 226 "regions along the cylinder axis: " +
228 if (border_z >= pc(2))
230 iz = jz > 0 ? jz - 1 : 0;
236 if (MooseUtils::absoluteFuzzyGreaterEqual(pc(0),
_max_r))
238 if (MooseUtils::absoluteFuzzyGreaterEqual(pc(2),
_max_z))
242 if (ir == not_found && MooseUtils::absoluteFuzzyEqual(widths(0), 0))
244 if (iz == not_found && MooseUtils::absoluteFuzzyEqual(widths(2), 0))
246 mooseAssert(ir != not_found,
"We should have found a mesh division bin radially");
247 mooseAssert(ia != not_found,
"We should have found a mesh division bin azimuthally");
248 mooseAssert(iz != not_found,
"We should have found a mesh division bin axially");
static InputParameters validParams()
const unsigned int _n_radial
Number of divisions in the radial direction.
CylindricalGridDivision(const InputParameters ¶meters)
Divides the mesh based on a cylindrical grid.
const Point *const _center
Point at the center of the cylinder, serving as the coordinate frame center.
const Real _min_r
Minimal radial extent of the cylinder.
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 ...
const ExecFlagType & getCurrentExecuteOnFlag() const
Return/set the current execution flag.
registerMooseObject("MooseApp", CylindricalGridDivision)
const Positions *const _center_positions
Positions giving all the centers of the cylinders, serving as the coordinate frame center...
const Point & getPosition(unsigned int index, bool initial) const
Getter for a single position at a known index.
const bool _outside_grid_counts_as_border
Whether to map outside the grid onto the inner/outer crowns (radially) or top/bottom bins (axially) ...
virtual void initialize() override
Set up any data members that would be necessary to obtain the division indices.
Base class for MeshDivision objects.
auto max(const L &left, const R &right)
void mooseWarning(Args &&... args) const
unsigned int getNearestPositionIndex(const Point &target, bool initial) const
Find the nearest Position index for a given point.
const Point _azim_dir
Azimuthal axis direction (angle = 0)
const unsigned int _n_axial
Number of divisions in the cylinder axial direction.
unsigned int getNumPositions(bool initial=false) const
}
const Real _max_z
Maximal axial extent of the cylinder.
std::string stringify(const T &t)
conversion to string
unsigned int INVALID_DIVISION_INDEX
Invalid subdomain id to return when outside the mesh division.
bool _mesh_fully_indexed
Whether the mesh is fully covered / indexed, all elements and points have a valid index...
const unsigned int _n_azim
Number of divisions in the azimuthal direction.
const Point _direction
Axis direction of the cylinder.
void setNumDivisions(const unsigned int ndivs)
Set the number of divisions.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const FEProblemBase *const _fe_problem
Pointer to the problem, needed to retrieve pointers to various objects.
const Real _max_r
Maximal radial extent of the cylinder.
IntRange< T > make_range(T beg, T end)
Real getMinDistanceBetweenPositions() const
Find the minimum distance between positions.
static InputParameters validParams()
Class constructor.
void ErrorVector unsigned int
virtual unsigned int divisionIndex(const Point &pt) const override
Return the index of the division to which the point belongs.
const Real _min_z
Minimal axial extent of the cylinder.
const ExecFlagType EXEC_INITIAL