https://mooseframework.inl.gov
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 
10 #include "SphericalGridDivision.h"
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
62  if (!_center && !_center_positions)
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
71  paramError("n_radial", "Zero-thickness sphere cannot be subdivided radially");
72 }
73 
74 void
76 {
77  if (!_center_positions)
79  else
81 
82  // Check that the grid is well-defined
84  {
85  Real min_dist = 2 * _max_r;
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
99  _mesh_fully_indexed = true;
101  _mesh_fully_indexed = false;
102 }
103 
104 unsigned int
105 SphericalGridDivision::divisionIndex(const Elem & elem) const
106 {
107  return divisionIndex(elem.vertex_average());
108 }
109 
110 unsigned 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  {
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)))
143  mooseWarning(
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
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 }
void addRequiredRangeCheckedParam(const std::string &name, const std::string &parsed_function, const std::string &doc_string)
These methods add an range checked parameters.
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
Definition: MooseUtils.h:380
const Real _min_r
Minimal radial extent of the sphere.
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:435
const Real _max_r
Maximal radial extent of the sphere.
const ExecFlagType & getCurrentExecuteOnFlag() const
Return/set the current execution flag.
const bool _outside_grid_counts_as_border
Whether to map outside the grid onto the inner/outer shells (radially)
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const Point *const _center
Point at the center of the sphere, serving as the coordinate frame center.
virtual unsigned int divisionIndex(const Point &pt) const override
Return the index of the division to which the point belongs.
SphericalGridDivision(const InputParameters &parameters)
const Point & getPosition(unsigned int index, bool initial) const
Getter for a single position at a known index.
Definition: Positions.C:59
const unsigned int _n_radial
Number of divisions in the radial direction.
Base class for MeshDivision objects.
Definition: MeshDivision.h:35
virtual void initialize() override
Set up any data members that would be necessary to obtain the division indices.
unsigned int getNearestPositionIndex(const Point &target, bool initial) const
Find the nearest Position index for a given point.
Definition: Positions.C:96
bool absoluteFuzzyLessThan(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether a variable is less than another variable within an absolute tolerance...
Definition: MooseUtils.h:475
unsigned int getNumPositions(bool initial=false) const
}
Definition: Positions.h:37
auto norm(const T &a) -> decltype(std::abs(a))
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:64
unsigned int INVALID_DIVISION_INDEX
Invalid subdomain id to return when outside the mesh division.
Definition: MeshDivision.h:28
Divides the mesh based on a spherical grid.
const Positions *const _center_positions
Positions giving all the centers of the spheres, serving as the coordinate frame center.
bool _mesh_fully_indexed
Whether the mesh is fully covered / indexed, all elements and points have a valid index...
Definition: MeshDivision.h:77
void setNumDivisions(const unsigned int ndivs)
Set the number of divisions.
Definition: MeshDivision.h:65
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.
Definition: MeshDivision.h:71
void mooseWarning(Args &&... args) const
Emits a warning prefixed with object name and type.
Definition: MooseBase.h:295
IntRange< T > make_range(T beg, T end)
bool absoluteFuzzyGreaterEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether a variable is greater than or equal to another variable within an absolute ...
Definition: MooseUtils.h:404
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 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 addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
Real getMinDistanceBetweenPositions() const
Find the minimum distance between positions.
Definition: Positions.C:242
static InputParameters validParams()
Class constructor.
Definition: MeshDivision.C:14
void ErrorVector unsigned int
bool absoluteFuzzyGreaterThan(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether a variable is greater than another variable within an absolute tolerance...
Definition: MooseUtils.h:428
registerMooseObject("MooseApp", SphericalGridDivision)
static InputParameters validParams()
const ExecFlagType EXEC_INITIAL
Definition: Moose.C:30