www.mooseframework.org
MultiSmoothSuperellipsoidIC.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 
10 // Creates multiple superellipsoids that are positioned randomly throughout the domain
11 // each semiaxis can be varied by a uniform or normal distribution
12 
14 
15 // MOOSE includes
16 #include "MooseMesh.h"
17 #include "MooseUtils.h"
18 #include "MooseVariable.h"
19 
21 
22 template <>
23 InputParameters
25 {
26  InputParameters params = validParams<SmoothSuperellipsoidBaseIC>();
27  params.addClassDescription("Random distribution of smooth ellipse with given minimum spacing");
28  params.addRequiredParam<std::vector<unsigned int>>("numbub",
29  "Vector of the number of bubbles to place");
30  params.addRequiredParam<std::vector<Real>>(
31  "bubspac",
32  "Vector of the minimum spacing of bubbles of one type, measured from center to center");
33  params.addParam<unsigned int>("max_num_tries", 1000, "The number of tries");
34  params.addRequiredParam<std::vector<Real>>(
35  "semiaxis_a", "Vector of mean semiaxis values in the x direction for the ellipse");
36  params.addRequiredParam<std::vector<Real>>(
37  "semiaxis_b", "Vector of mean semiaxis values in the y direction for the ellipse");
38  params.addRequiredParam<std::vector<Real>>("semiaxis_c",
39  "Vector of mean semiaxis values in the z direction "
40  "for the ellipse, must be greater than 0 even if 2D.");
41  params.addParam<std::vector<Real>>(
42  "exponent",
43  std::vector<Real>(),
44  "Vector of exponents for each superellipsoid, n=2 is a normal ellipse");
45  params.addParam<std::vector<Real>>("semiaxis_a_variation",
46  std::vector<Real>(),
47  "Vector of plus or minus fractions of random variation in the "
48  "bubble semiaxis in the x direction for uniform, standard "
49  "deviation for normal");
50  params.addParam<std::vector<Real>>("semiaxis_b_variation",
51  std::vector<Real>(),
52  "Vector of plus or minus fractions of random variation in the "
53  "bubble semiaxis in the y direction for uniform, standard "
54  "deviation for normal");
55  params.addParam<std::vector<Real>>("semiaxis_c_variation",
56  std::vector<Real>(),
57  "Vector of plus or minus fractions of random variation in the "
58  "bubble semiaxis in the z direction for uniform, standard "
59  "deviation for normal. Must be set to 0 if 2D.");
60  params.addParam<bool>("check_extremes",
61  false,
62  "Check all Superellipsoid extremes (center +- "
63  "each semiaxis) for overlap, must have "
64  "prevent_overlap set to True.");
65  params.addParam<bool>("prevent_overlap",
66  false,
67  "Check all Superellipsoid centers for overlap with other superellipsoids.");
68  params.addParam<bool>("vary_axes_independently",
69  true,
70  "If true the length of each semiaxis is randomly chosen "
71  "within the provided parameters, if false then one random "
72  "number is generated and applied to all semiaxes.");
73  MooseEnum rand_options("uniform normal none", "none");
74  params.addParam<MooseEnum>(
75  "semiaxis_variation_type",
76  rand_options,
77  "Type of distribution that random superellipsoid semiaxes will follow");
78  return params;
79 }
80 
82  : SmoothSuperellipsoidBaseIC(parameters),
83  _max_num_tries(getParam<unsigned int>("max_num_tries")),
84  _semiaxis_variation_type(getParam<MooseEnum>("semiaxis_variation_type")),
85  _prevent_overlap(getParam<bool>("prevent_overlap")),
86  _check_extremes(getParam<bool>("check_extremes")),
87  _vary_axes_independently(getParam<bool>("vary_axes_independently")),
88  _numbub(parameters.get<std::vector<unsigned int>>("numbub")),
89  _bubspac(parameters.get<std::vector<Real>>("bubspac")),
90  _exponent(parameters.get<std::vector<Real>>("exponent")),
91  _semiaxis_a(parameters.get<std::vector<Real>>("semiaxis_a")),
92  _semiaxis_b(parameters.get<std::vector<Real>>("semiaxis_b")),
93  _semiaxis_c(parameters.get<std::vector<Real>>("semiaxis_c")),
94  _semiaxis_a_variation(parameters.get<std::vector<Real>>("semiaxis_a_variation")),
95  _semiaxis_b_variation(parameters.get<std::vector<Real>>("semiaxis_b_variation")),
96  _semiaxis_c_variation(parameters.get<std::vector<Real>>("semiaxis_c_variation"))
97 {
98 }
99 
100 void
102 {
103  unsigned int nv = _numbub.size();
104 
105  if (nv != _bubspac.size() || nv != _exponent.size() || nv != _semiaxis_a.size() ||
106  nv != _semiaxis_b.size() || nv != _semiaxis_c.size())
107  mooseError("Vectors for numbub, bubspac, exponent, semiaxis_a, semiaxis_b, and semiaxis_c must "
108  "be the same size.");
109 
110  if (_semiaxis_variation_type != 2 &&
111  (nv != _semiaxis_a_variation.size() || nv != _semiaxis_b_variation.size() ||
112  nv != _semiaxis_c_variation.size()))
113  mooseError("Vectors for numbub, semiaxis_a_variation, semiaxis_b_variation, and "
114  "semiaxis_c_variation must be the same size.");
115 
116  if (_semiaxis_variation_type == 2 &&
117  (_semiaxis_a_variation.size() > 0 || _semiaxis_b_variation.size() > 0 ||
118  _semiaxis_c_variation.size() > 0))
119  mooseWarning(
120  "Values were provided for semiaxis_a/b/c_variation but semiaxis_variation_type is set "
121  "to 'none' in 'MultiSmoothSuperellipsoidIC'.");
122 
123  for (_gk = 0; _gk < nv; ++_gk)
124  {
125  // Set up domain bounds with mesh tools
126  for (unsigned int i = 0; i < LIBMESH_DIM; i++)
127  {
128  _bottom_left(i) = _mesh.getMinInDimension(i);
129  _top_right(i) = _mesh.getMaxInDimension(i);
130  }
132 
134  }
135 }
136 
137 void
139 {
140  Real randnum;
141  unsigned int start = _as.size();
142  _as.resize(start + _numbub[_gk]);
143  _bs.resize(start + _numbub[_gk]);
144  _cs.resize(start + _numbub[_gk]);
145 
146  for (unsigned int i = start; i < _as.size(); i++)
147  {
148  switch (_semiaxis_variation_type)
149  {
150  case 0: // Uniform distrubtion
151  randnum = _random.rand(_tid);
152  _as[i] = _semiaxis_a[_gk] * (1.0 + (1.0 - 2.0 * randnum) * _semiaxis_a_variation[_gk]);
153  _bs[i] = _semiaxis_b[_gk] *
154  (1.0 + (1.0 - 2.0 * (_vary_axes_independently ? _random.rand(_tid) : randnum)) *
156  _cs[i] = _semiaxis_c[_gk] *
157  (1.0 + (1.0 - 2.0 * (_vary_axes_independently ? _random.rand(_tid) : randnum)) *
159  break;
160 
161  case 1: // Normal distribution
162  randnum = _random.randNormal(_tid, 0, 1);
163  _as[i] = _semiaxis_a[_gk] + (randnum * _semiaxis_a_variation[_gk]);
164  _bs[i] = _semiaxis_b[_gk] +
165  ((_vary_axes_independently ? _random.randNormal(_tid, 0, 1) : randnum) *
167  _cs[i] = _semiaxis_c[_gk] +
168  ((_vary_axes_independently ? _random.randNormal(_tid, 0, 1) : randnum) *
170  break;
171 
172  case 2: // No variation
173  _as[i] = _semiaxis_a[_gk];
174  _bs[i] = _semiaxis_b[_gk];
175  _cs[i] = _semiaxis_c[_gk];
176  }
177 
178  _as[i] = _as[i] < 0.0 ? 0.0 : _as[i];
179  _bs[i] = _bs[i] < 0.0 ? 0.0 : _bs[i];
180  _cs[i] = _cs[i] < 0.0 ? 0.0 : _cs[i];
181  }
182 }
183 
184 void
186 {
187  unsigned int start = _centers.size();
188  _centers.resize(start + _numbub[_gk]);
189 
190  for (unsigned int i = start; i < _centers.size(); i++)
191  {
192  // Vary circle center positions
193  unsigned int num_tries = 0;
194  while (num_tries < _max_num_tries)
195  {
196  num_tries++;
197 
198  RealTensorValue ran;
199  ran(0, 0) = _random.rand(_tid);
200  ran(1, 1) = _random.rand(_tid);
201  ran(2, 2) = _random.rand(_tid);
202 
203  _centers[i] = _bottom_left + ran * _range;
204 
205  for (unsigned int j = 0; j < i; ++j)
206  if (_mesh.minPeriodicDistance(_var.number(), _centers[i], _centers[j]) < _bubspac[_gk] ||
207  ellipsoidsOverlap(i, j))
208  goto fail;
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("max_num_tries reached in 'MultiSmoothSuperellipsoidIC'.");
220 
221  accept:
222  continue;
223  }
224 }
225 
226 void
228 {
229  unsigned int start = _ns.size();
230  _ns.resize(start + _numbub[_gk]);
231 
232  for (unsigned int i = start; i < _ns.size(); ++i)
233  _ns[i] = _exponent[_gk];
234 }
235 
236 bool
237 MultiSmoothSuperellipsoidIC::ellipsoidsOverlap(unsigned int i, unsigned int j)
238 {
239  // Check for overlap between centers
240  const Point dist_vec = _mesh.minPeriodicVector(_var.number(), _centers[i], _centers[j]);
241  const Real dist = dist_vec.norm();
242 
243  // Handle this case independently because we cannot calculate polar angles at this point
244  if (MooseUtils::absoluteFuzzyEqual(dist, 0.0))
245  return true;
246 
247  // Compute the distance r from the center of the superellipsoid to its outside edge
248  // along the vector from the center to the current point
249  // This uses the equation for a superellipse in polar coordinates and substitutes
250  // distances for sin, cos functions
251  Real rmn;
252 
253  // calculate rmn = r^(-n), replacing sin, cos functions with distances
254  rmn = (std::pow(std::abs(dist_vec(0) / dist / _as[i]), _ns[i]) +
255  std::pow(std::abs(dist_vec(1) / dist / _bs[i]), _ns[i]) +
256  std::pow(std::abs(dist_vec(2) / dist / _cs[i]), _ns[i]));
257  // calculate r2 from rmn
258  const Real r1 = std::pow(rmn, (-1.0 / _ns[i]));
259 
260  // calculate rmn = r^(-n), replacing sin, cos functions with distances
261  rmn = (std::pow(std::abs(dist_vec(0) / dist / _as[j]), _ns[j]) +
262  std::pow(std::abs(dist_vec(1) / dist / _bs[j]), _ns[j]) +
263  std::pow(std::abs(dist_vec(2) / dist / _cs[j]), _ns[j]));
264  const Real r2 = std::pow(rmn, (-1.0 / _ns[j]));
265 
266  if (dist < r1 + r2)
267  return true;
268 
269  // Check for overlap between extremes of new ellipsoid candidate and the center
270  // of accepted ellisoids if _check_extremes enabled
271  if (_check_extremes)
272  return checkExtremes(i, j) || checkExtremes(j, i);
273 
274  // otherwise no overlap has been detected
275  return false;
276 }
277 
278 bool
279 MultiSmoothSuperellipsoidIC::checkExtremes(unsigned int i, unsigned int j)
280 {
281  Point tmp_p;
282  for (unsigned int pc = 0; pc < 6; pc++)
283  {
284  tmp_p = _centers[j];
285  // Find extremes along semiaxis of candidate ellipsoids
286  if (pc == 0)
287  tmp_p(0) -= _as[j];
288  else if (pc == 1)
289  tmp_p(0) += _as[j];
290  else if (pc == 2)
291  tmp_p(1) -= _bs[j];
292  else if (pc == 3)
293  tmp_p(1) += _bs[j];
294  else if (pc == 4)
295  tmp_p(2) -= _cs[j];
296  else
297  tmp_p(2) += _cs[j];
298 
299  const Point dist_vec = _mesh.minPeriodicVector(_var.number(), _centers[i], tmp_p);
300  const Real dist = dist_vec.norm();
301 
302  // Handle this case independently because we cannot calculate polar angles at this point
303  if (MooseUtils::absoluteFuzzyEqual(dist, 0.0))
304  return true;
305 
306  // calculate rmn = r^(-n), replacing sin, cos functions with distances
307  Real rmn = (std::pow(std::abs(dist_vec(0) / dist / _as[i]), _ns[i]) +
308  std::pow(std::abs(dist_vec(1) / dist / _bs[i]), _ns[i]) +
309  std::pow(std::abs(dist_vec(2) / dist / _cs[i]), _ns[i]));
310  Real r = std::pow(rmn, (-1.0 / _ns[i]));
311 
312  if (dist < r)
313  return true;
314  }
315 
316  return false;
317 }
SmoothSuperellipsoidBaseIC::_centers
std::vector< Point > _centers
Definition: SmoothSuperellipsoidBaseIC.h:60
validParams< MultiSmoothSuperellipsoidIC >
InputParameters validParams< MultiSmoothSuperellipsoidIC >()
Definition: MultiSmoothSuperellipsoidIC.C:24
MultiSmoothSuperellipsoidIC.h
MultiSmoothSuperellipsoidIC::_gk
unsigned int _gk
Definition: MultiSmoothSuperellipsoidIC.h:41
MultiSmoothSuperellipsoidIC::_exponent
std::vector< Real > _exponent
Definition: MultiSmoothSuperellipsoidIC.h:54
SmoothSuperellipsoidBaseIC::_mesh
MooseMesh & _mesh
Definition: SmoothSuperellipsoidBaseIC.h:50
MultiSmoothSuperellipsoidIC::_check_extremes
const bool _check_extremes
Definition: MultiSmoothSuperellipsoidIC.h:45
MultiSmoothSuperellipsoidIC::MultiSmoothSuperellipsoidIC
MultiSmoothSuperellipsoidIC(const InputParameters &parameters)
Definition: MultiSmoothSuperellipsoidIC.C:81
MultiSmoothSuperellipsoidIC::_vary_axes_independently
const bool _vary_axes_independently
Definition: MultiSmoothSuperellipsoidIC.h:46
pow
ExpressionBuilder::EBTerm pow(const ExpressionBuilder::EBTerm &left, T exponent)
Definition: ExpressionBuilder.h:673
MultiSmoothSuperellipsoidIC::_bubspac
std::vector< Real > _bubspac
Definition: MultiSmoothSuperellipsoidIC.h:53
MultiSmoothSuperellipsoidIC::_numbub
std::vector< unsigned int > _numbub
Definition: MultiSmoothSuperellipsoidIC.h:52
MultiSmoothSuperellipsoidIC::computeSuperellipsoidExponents
virtual void computeSuperellipsoidExponents()
Definition: MultiSmoothSuperellipsoidIC.C:227
SmoothSuperellipsoidBaseIC::initialSetup
virtual void initialSetup()
Definition: SmoothSuperellipsoidBaseIC.C:51
MultiSmoothSuperellipsoidIC::_semiaxis_b_variation
std::vector< Real > _semiaxis_b_variation
Definition: MultiSmoothSuperellipsoidIC.h:59
MultiSmoothSuperellipsoidIC::computeSuperellipsoidCenters
virtual void computeSuperellipsoidCenters()
Definition: MultiSmoothSuperellipsoidIC.C:185
MultiSmoothSuperellipsoidIC::_semiaxis_c_variation
std::vector< Real > _semiaxis_c_variation
Definition: MultiSmoothSuperellipsoidIC.h:60
SmoothSuperellipsoidBaseIC::_as
std::vector< Real > _as
Definition: SmoothSuperellipsoidBaseIC.h:61
MultiSmoothSuperellipsoidIC::_semiaxis_a_variation
std::vector< Real > _semiaxis_a_variation
Definition: MultiSmoothSuperellipsoidIC.h:58
MultiSmoothSuperellipsoidIC::_max_num_tries
const unsigned int _max_num_tries
Definition: MultiSmoothSuperellipsoidIC.h:40
MultiSmoothSuperellipsoidIC::_semiaxis_a
std::vector< Real > _semiaxis_a
Definition: MultiSmoothSuperellipsoidIC.h:55
MultiSmoothSuperellipsoidIC
MultismoothSuperellipsoidIC creates multiple SmoothSuperellipsoid (number = numbub) that are randomly...
Definition: MultiSmoothSuperellipsoidIC.h:25
MultiSmoothSuperellipsoidIC::computeSuperellipsoidSemiaxes
virtual void computeSuperellipsoidSemiaxes()
Definition: MultiSmoothSuperellipsoidIC.C:138
MultiSmoothSuperellipsoidIC::_semiaxis_b
std::vector< Real > _semiaxis_b
Definition: MultiSmoothSuperellipsoidIC.h:56
SmoothSuperellipsoidBaseIC::_random
MooseRandom _random
Definition: SmoothSuperellipsoidBaseIC.h:66
MultiSmoothSuperellipsoidIC::_semiaxis_variation_type
const MooseEnum _semiaxis_variation_type
Definition: MultiSmoothSuperellipsoidIC.h:43
MultiSmoothSuperellipsoidIC::_bottom_left
Point _bottom_left
Definition: MultiSmoothSuperellipsoidIC.h:48
SmoothSuperellipsoidBaseIC
SmoothSuperellipsoidBaseIC is the base class for all initial conditions that create superellipsoids.
Definition: SmoothSuperellipsoidBaseIC.h:28
SmoothSuperellipsoidBaseIC::_ns
std::vector< Real > _ns
Definition: SmoothSuperellipsoidBaseIC.h:64
MultiSmoothSuperellipsoidIC::_semiaxis_c
std::vector< Real > _semiaxis_c
Definition: MultiSmoothSuperellipsoidIC.h:57
MultiSmoothSuperellipsoidIC::_top_right
Point _top_right
Definition: MultiSmoothSuperellipsoidIC.h:49
SmoothSuperellipsoidBaseIC::_bs
std::vector< Real > _bs
Definition: SmoothSuperellipsoidBaseIC.h:62
validParams< SmoothSuperellipsoidBaseIC >
InputParameters validParams< SmoothSuperellipsoidBaseIC >()
Definition: SmoothSuperellipsoidBaseIC.C:18
MultiSmoothSuperellipsoidIC::ellipsoidsOverlap
virtual bool ellipsoidsOverlap(unsigned int i, unsigned int j)
Definition: MultiSmoothSuperellipsoidIC.C:237
registerMooseObject
registerMooseObject("PhaseFieldApp", MultiSmoothSuperellipsoidIC)
MultiSmoothSuperellipsoidIC::initialSetup
virtual void initialSetup()
Definition: MultiSmoothSuperellipsoidIC.C:101
SmoothSuperellipsoidBaseIC::_cs
std::vector< Real > _cs
Definition: SmoothSuperellipsoidBaseIC.h:63
MultiSmoothSuperellipsoidIC::checkExtremes
virtual bool checkExtremes(unsigned int i, unsigned int j)
Definition: MultiSmoothSuperellipsoidIC.C:279
MultiSmoothSuperellipsoidIC::_range
Point _range
Definition: MultiSmoothSuperellipsoidIC.h:50