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