www.mooseframework.org
BimodalSuperellipsoidsIC.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 
12 // MOOSE includes
13 #include "MooseMesh.h"
14 #include "MooseVariable.h"
15 
17 
20 {
22  params.addClassDescription("Bimodal size distribution of large particles (specified in input "
23  "file) and small particles (placed randomly outside the larger "
24  "particles)");
25  params.addRequiredParam<unsigned int>("npart", "The number of random (small) particles to place");
26  params.addRequiredParam<Real>(
27  "small_spac",
28  "minimum spacing between small particles, measured from closest edge to closest edge");
29  params.addRequiredParam<Real>("large_spac",
30  "minimum spacing between large and small particles, "
31  "measured from closest edge to closest edge");
32  params.addRequiredParam<Real>(
33  "small_a", "Mean semiaxis a value for the randomly placed (small) superellipsoids");
34  params.addRequiredParam<Real>(
35  "small_b", "Mean semiaxis b value for the randomly placed (small) superellipsoids");
36  params.addRequiredParam<Real>(
37  "small_c", "Mean semiaxis c value for the randomly placed (small) superellipsoids");
38  params.addRequiredParam<Real>("small_n",
39  "Exponent n for the randomly placed (small) superellipsoids");
40  params.addParam<Real>("size_variation",
41  0.0,
42  "Plus or minus fraction of random variation in the "
43  "semiaxes for uniform, standard deviation for "
44  "normal");
45  MooseEnum rand_options("uniform normal none", "none");
46  params.addParam<MooseEnum>(
47  "size_variation_type", rand_options, "Type of distribution that random semiaxes will follow");
48  params.addParam<unsigned int>(
49  "numtries", 1000, "The number of tries to place the random particles");
50  return params;
51 }
52 
54  : SpecifiedSmoothSuperellipsoidIC(parameters),
55  _npart(getParam<unsigned int>("npart")),
56  _small_spac(getParam<Real>("small_spac")),
57  _large_spac(getParam<Real>("large_spac")),
58  _small_a(getParam<Real>("small_a")),
59  _small_b(getParam<Real>("small_b")),
60  _small_c(getParam<Real>("small_c")),
61  _small_n(getParam<Real>("small_n")),
62  _size_variation(getParam<Real>("size_variation")),
63  _size_variation_type(getParam<MooseEnum>("size_variation_type")),
64  _max_num_tries(getParam<unsigned int>("numtries"))
65 {
66 }
67 
68 void
70 {
71  // Set up domain bounds with mesh tools
72  for (const auto i : make_range(Moose::dim))
73  {
76  }
78 
79  if (_size_variation_type == 2 && _size_variation > 0.0)
80  mooseError("If size_variation > 0.0, you must pass in a size_variation_type in "
81  "BimodalSuperellipsoidsIC");
82 
84 }
85 
86 void
88 {
89  _as.resize(_input_as.size() + _npart);
90  _bs.resize(_input_bs.size() + _npart);
91  _cs.resize(_input_cs.size() + _npart);
92 
93  // First fill in the specified (large) superellipsoids from the input file
94  for (unsigned int i = 0; i < _input_as.size(); ++i)
95  {
96  _as[i] = _input_as[i];
97  _bs[i] = _input_bs[i];
98  _cs[i] = _input_cs[i];
99  }
100 
101  // Then fill in the randomly positioned (small) superellipsoids
102  for (unsigned int i = _input_as.size(); i < _input_as.size() + _npart; ++i)
103  {
104  // Vary semiaxes
105  switch (_size_variation_type)
106  {
107  case 0: // Random distrubtion, maintaining constant shape
108  {
109  Real rand_num = _random.rand(_tid);
110  _as[i] = _small_a * (1.0 + (1.0 - 2.0 * rand_num) * _size_variation);
111  _bs[i] = _small_b * (1.0 + (1.0 - 2.0 * rand_num) * _size_variation);
112  _cs[i] = _small_c * (1.0 + (1.0 - 2.0 * rand_num) * _size_variation);
113  break;
114  }
115  case 1: // Normal distribution of semiaxis size, maintaining constant shape
117  _bs[i] = _as[i] * _small_b / _small_a;
118  _cs[i] = _as[i] * _small_c / _small_a;
119  break;
120  case 2: // No variation
121  _as[i] = _small_a;
122  _bs[i] = _small_b;
123  _cs[i] = _small_c;
124  }
125 
126  if (_as[i] < 0.0)
127  _as[i] = 0.0;
128  if (_bs[i] < 0.0)
129  _bs[i] = 0.0;
130  if (_cs[i] < 0.0)
131  _cs[i] = 0.0;
132  }
133 }
134 
135 void
137 {
138  _ns.resize(_input_ns.size() + _npart);
139 
140  // First fill in the specified (large) superellipsoids from the input file
141  for (unsigned int i = 0; i < _input_ns.size(); ++i)
142  _ns[i] = _input_ns[i];
143 
144  // Then fill in the randomly positioned (small) superellipsoids
145  // The shape is assumed to stay constant so n does not vary
146  for (unsigned int i = _input_ns.size(); i < _input_ns.size() + _npart; ++i)
147  _ns[i] = _small_n;
148 }
149 
150 void
152 {
153  _centers.resize(_x_positions.size() + _npart);
154 
155  // First place the specified (large) particles from the input file
156  for (unsigned int i = 0; i < _x_positions.size(); ++i)
157  {
158  _centers[i](0) = _x_positions[i];
159  _centers[i](1) = _y_positions[i];
160  _centers[i](2) = _z_positions[i];
161  }
162 
163  // Next place the randomly positioned (small) particles
164  for (unsigned int i = _x_positions.size(); i < _x_positions.size() + _npart; ++i)
165  {
166  unsigned int num_tries = 0;
167 
168  while (num_tries < _max_num_tries)
169  {
170  num_tries++;
171 
172  RealTensorValue ran;
173  ran(0, 0) = _random.rand(_tid);
174  ran(1, 1) = _random.rand(_tid);
175  ran(2, 2) = _random.rand(_tid);
176 
177  _centers[i] = _bottom_left + ran * _range;
178 
179  // check for collisions with the specified (large) and randomly placed small particles
180  for (unsigned int j = 0; j < i; ++j)
181  {
182  // Compute the distance r1 from the center of each specified superellipsoid to its
183  // outside edge along the vector between the specified superellipsoid and the current
184  // randomly positioned one.
185  // This uses the equation for a superellipse in polar coordinates and substitutes
186  // distances for sin, cos functions.
187  Point dist_vec = _mesh.minPeriodicVector(_var.number(), _centers[i], _centers[j]);
188  const Real dist = dist_vec.norm();
189 
190  // First calculate rmn1 = r1^(-n), replacing sin, cos functions with distances
191  Real rmn1 = (std::pow(std::abs(dist_vec(0) / dist / _as[j]), _ns[j]) +
192  std::pow(std::abs(dist_vec(1) / dist / _bs[j]), _ns[j]) +
193  std::pow(std::abs(dist_vec(2) / dist / _cs[j]), _ns[j]));
194  // Then calculate r1 from rmn1
195  const Real r1 = std::pow(rmn1, (-1.0 / _ns[j]));
196 
197  // Now calculate the distance r2 from the center of the randomly placed
198  // superellipsoid to its outside edge in the same manner
199  Real rmn2 = (std::pow(std::abs(dist_vec(0) / dist / _as[i]), _ns[i]) +
200  std::pow(std::abs(dist_vec(1) / dist / _bs[i]), _ns[i]) +
201  std::pow(std::abs(dist_vec(2) / dist / _cs[i]), _ns[i]));
202  const Real r2 = std::pow(rmn2, (-1.0 / _ns[i]));
203 
204  // Calculate the distance between the edges (first in the list are the large then come the
205  // small)
206  if ((dist - r1 - r2) < (j < _x_positions.size() ? _large_spac : _small_spac))
207  goto fail;
208  }
209 
210  // accept the position of the new center
211  goto accept;
212 
213  // retry a new position until tries are exhausted
214  fail:
215  continue;
216  }
217 
218  if (num_tries == _max_num_tries)
219  mooseError("Too many tries in MultiSmoothCircleIC");
220 
221  accept:
222  continue;
223  }
224 }
registerMooseObject("PhaseFieldApp", BimodalSuperellipsoidsIC)
virtual Real getMaxInDimension(unsigned int component) const
virtual void computeSuperellipsoidSemiaxes()
virtual Real getMinInDimension(unsigned int component) const
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
unsigned int number() const
RealVectorValue minPeriodicVector(unsigned int nonlinear_var_num, Point p, Point q) const
static constexpr std::size_t dim
SpecifiedSmoothSuperellipsoidIC creates multiple SmoothSuperellipsoids (number = size of x_positions)...
MooseVariableField< T > & _var
static InputParameters validParams()
void addRequiredParam(const std::string &name, const std::string &doc_string)
Real randNormal(std::size_t i, Real mean, Real sigma)
BimodalSuperellipsoidsIC takes a specified number of superellipsoids, each with given parameters Thes...
ADRealEigenVector< T, D, asd > abs(const ADRealEigenVector< T, D, asd > &)
TensorValue< Real > RealTensorValue
unsigned int _npart
Variables to describe the randomly placed (smaller) superellipsoids.
BimodalSuperellipsoidsIC(const InputParameters &parameters)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
Real rand(std::size_t i)
MooseUnits pow(const MooseUnits &, int)
void ErrorVector unsigned int