https://mooseframework.inl.gov
Loading...
Searching...
No Matches
SphericalGridDivision.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#include "MooseMesh.h"
12#include "FEProblemBase.h"
13#include "Positions.h"
14
15#include "libmesh/elem.h"
16#include <math.h>
17
19
22{
24 params.addClassDescription("Divide the mesh along a spherical grid.");
25
26 // Definition of the sphere(s)
27 params.addParam<Point>("center", "Center of the sphere");
28 params.addParam<PositionsName>("center_positions", "Positions of the centers of the spheres");
29
30 // Spatial bounds of the sphere
31 params.addRangeCheckedParam<Real>(
32 "r_min", 0, "r_min>=0", "Minimum radial coordinate (for a hollow sphere)");
33 params.addRequiredRangeCheckedParam<Real>("r_max", "r_max>0", "Maximum radial coordinate");
34
35 // Number of bins
36 params.addRequiredRangeCheckedParam<unsigned int>(
37 "n_radial", "n_radial>0", "Number of divisions in the sphere radial direction");
38
39 params.addParam<bool>("assign_domain_outside_grid_to_border",
40 false,
41 "Whether to map the domain outside the grid back to the border of the grid "
42 "(radially or axially)");
43
44 return params;
45}
46
48 : MeshDivision(parameters),
49 _center(isParamValid("center") ? &getParam<Point>("center") : nullptr),
50 _center_positions(
51 isParamValid("center_positions")
52 ? &_fe_problem->getPositionsObject(getParam<PositionsName>("center_positions"))
53 : nullptr),
54 _min_r(getParam<Real>("r_min")),
55 _max_r(getParam<Real>("r_max")),
56 _n_radial(getParam<unsigned int>("n_radial")),
57 _outside_grid_counts_as_border(getParam<bool>("assign_domain_outside_grid_to_border"))
58{
60
61 // Check that we know the centers
63 paramError("center", "You must pass a parameter for the center of the spherical frame");
64
65 // Check non-negative size
66 if (_max_r < _min_r)
67 paramError("r_min", "Maximum radius must be larger than minimum radius");
68
69 // Check non-zero size if subdivided
70 if (_n_radial > 1 && MooseUtils::absoluteFuzzyEqual(_min_r, _max_r))
71 paramError("n_radial", "Zero-thickness sphere cannot be subdivided radially");
72}
73
74void
76{
79 else
81
82 // Check that the grid is well-defined
84 {
85 Real min_dist = 2 * _max_r;
86 Real min_center_dist = _center_positions->getMinDistanceBetweenPositions();
87 // Note that if the positions are not co-planar, the distance reported would be bigger but there
88 // could still be an overlap. Looking at min_center_dist is not enough
89 if (MooseUtils::absoluteFuzzyGreaterThan(min_dist, min_center_dist))
91 "Spherical grids centered on the positions are too close to each other (min distance: ",
92 min_center_dist,
93 "), closer than the radial extent of each grid. Mesh division is ill-defined");
94 }
95
96 // We could alternatively check every point in the mesh but it seems expensive
97 // A bounding box check could also suffice but the sphere would need to be excessively large to
98 // enclose the entire mesh
101 _mesh_fully_indexed = false;
102}
103
104unsigned int
106{
107 return divisionIndex(elem.vertex_average());
108}
109
110unsigned int
112{
113 // Compute coordinates of the point in the spherical coordinates
114 Point pc;
115 unsigned int offset = 0;
116 if (_center)
117 pc(0) = (pt - *_center).norm();
118 else
119 {
120 // If distributing using positions, find the closest position
121 const bool initial = _fe_problem->getCurrentExecuteOnFlag() == EXEC_INITIAL;
122 const auto nearest_center_index = _center_positions->getNearestPositionIndex(pt, initial);
123 offset = nearest_center_index * _n_radial;
124 pc(0) = (pt - _center_positions->getPosition(nearest_center_index, initial)).norm();
125 }
126
128 {
129 if (MooseUtils::absoluteFuzzyLessThan(pc(0), _min_r) ||
130 MooseUtils::absoluteFuzzyGreaterThan(pc(0), _max_r))
132 }
133
134 const auto not_found = MooseMeshDivision::INVALID_DIVISION_INDEX;
135 auto ir = not_found;
136 const Real width = _max_r - _min_r;
137
138 // Look inside the grid and on the left / back / bottom
139 for (const auto jr : make_range(_n_radial + 1))
140 {
141 const auto border_r = _min_r + width * jr / _n_radial;
142 if (jr > 0 && jr < _n_radial && MooseUtils::absoluteFuzzyEqual(border_r, pc(0)))
144 "Querying the division index for a point of a boundary between two regions radially: " +
145 Moose::stringify(pt));
146 if (border_r >= pc(0))
147 {
148 ir = jr > 0 ? jr - 1 : 0;
149 break;
150 }
151 }
152
153 // Look beyond the extent of the radial grid
154 if (MooseUtils::absoluteFuzzyGreaterEqual(pc(0), _max_r))
155 ir = _n_radial - 1;
156
157 // Handle edge case on widths
158 if (ir == not_found && MooseUtils::absoluteFuzzyEqual(width, 0))
159 ir = 0;
160
161 mooseAssert(ir != not_found, "We should have found a mesh division bin radially");
162 return offset + ir;
163}
const ExecFlagType EXEC_INITIAL
Definition Moose.C:30
registerMooseObject("MooseApp", SphericalGridDivision)
void ErrorVector unsigned int
const ExecFlagType & getCurrentExecuteOnFlag() const
Return/set the current execution flag.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void addRequiredRangeCheckedParam(const std::string &name, const std::string &parsed_function, const std::string &doc_string)
These methods add an range checked parameters.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object.
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump.
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
Base class for MeshDivision objects.
static InputParameters validParams()
Class constructor.
const FEProblemBase *const _fe_problem
Pointer to the problem, needed to retrieve pointers to various objects.
void setNumDivisions(const unsigned int ndivs)
Set the number of divisions.
bool _mesh_fully_indexed
Whether the mesh is fully covered / indexed, all elements and points have a valid index.
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition MooseBase.h:457
const Point & getPosition(unsigned int index, bool initial) const
Getter for a single position at a known index.
Definition Positions.C:59
unsigned int getNearestPositionIndex(const Point &target, bool initial) const
Find the nearest Position index for a given point.
Definition Positions.C:96
unsigned int getNumPositions(bool initial=false) const
}
Definition Positions.h:37
Real getMinDistanceBetweenPositions() const
Find the minimum distance between positions.
Definition Positions.C:242
void mooseWarning(Args &&... args) const
Divides the mesh based on a spherical grid.
virtual unsigned int divisionIndex(const Point &pt) const override
Return the index of the division to which the point belongs.
virtual void initialize() override
Set up any data members that would be necessary to obtain the division indices.
static InputParameters validParams()
SphericalGridDivision(const InputParameters &parameters)
const Real _max_r
Maximal radial extent of the sphere.
const Positions *const _center_positions
Positions giving all the centers of the spheres, serving as the coordinate frame center.
const Point *const _center
Point at the center of the sphere, serving as the coordinate frame center.
const bool _outside_grid_counts_as_border
Whether to map outside the grid onto the inner/outer shells (radially)
const unsigned int _n_radial
Number of divisions in the radial direction.
const Real _min_r
Minimal radial extent of the sphere.
unsigned int INVALID_DIVISION_INDEX
Invalid subdomain id to return when outside the mesh division.
std::string stringify(const T &t)
conversion to string
Definition Conversion.h:64