www.mooseframework.org
BimodalInverseSuperellipsoidsIC.C
Go to the documentation of this file.
1 /****************************************************************/
2 /* MOOSE - Multiphysics Object Oriented Simulation Environment */
3 /* */
4 /* All contents are licensed under LGPL V2.1 */
5 /* See LICENSE for full restrictions */
6 /****************************************************************/
7 
9 
10 // MOOSE includes
11 #include "MooseMesh.h"
12 #include "MooseVariable.h"
13 
14 template <>
15 InputParameters
17 {
18  InputParameters params = validParams<BimodalSuperellipsoidsIC>();
19  params.addClassDescription("Bimodal size distribution of large particles (specified in input "
20  "file, value invalue) and small particles (placed randomly inside the "
21  "larger particles, value outvalue)");
22  return params;
23 }
24 
26  : BimodalSuperellipsoidsIC(parameters)
27 {
28 }
29 
30 void
32 {
33  if (_size_variation_type == 2 && _size_variation > 0.0)
34  mooseError("If size_variation > 0.0, you must pass in a size_variation_type in "
35  "BimodalInverseSuperellipsoidsIC");
36 
38 }
39 
40 Real
42 {
43  Real value = _outvalue;
44  Real val2 = 0.0;
45 
46  // First loop over the specified superellipsoids
47  for (unsigned int ellip = 0; ellip < _x_positions.size() && value != _invalue; ++ellip)
48  {
50  p, _centers[ellip], _as[ellip], _bs[ellip], _cs[ellip], _ns[ellip]);
51  if ((val2 > value && _invalue > _outvalue) || (val2 < value && _outvalue > _invalue))
52  value = val2;
53  }
54 
55  // Then loop over the randomly positioned particles and set value inside them back to outvalue
56  for (unsigned int ellip = _x_positions.size(); ellip < _x_positions.size() + _npart; ++ellip)
57  {
59  p, _centers[ellip], _as[ellip], _bs[ellip], _cs[ellip], _ns[ellip]);
60  if ((val2 < value && _invalue > _outvalue) || (val2 > value && _outvalue > _invalue))
61  value = val2;
62  }
63 
64  return value;
65 }
66 
67 void
69 {
70  _centers.resize(_x_positions.size() + _npart);
71 
72  // First place the specified (large) particles from the input file
73  for (unsigned int i = 0; i < _x_positions.size(); ++i)
74  {
75  _centers[i](0) = _x_positions[i];
76  _centers[i](1) = _y_positions[i];
77  _centers[i](2) = _z_positions[i];
78  }
79 
80  // Next place the randomly positioned (small) particles
81  for (unsigned int i = _x_positions.size(); i < _x_positions.size() + _npart; ++i)
82  {
83  unsigned int num_tries = 0;
84 
85  while (num_tries < _max_num_tries)
86  {
87  num_tries++;
88 
89  RealTensorValue ran;
90  ran(0, 0) = _random.rand(_tid);
91  ran(1, 1) = _random.rand(_tid);
92  ran(2, 2) = _random.rand(_tid);
93 
94  _centers[i] = _bottom_left + ran * _range;
95 
96  // check for collisions with the specified (large) and randomly placed small particles
97  for (unsigned int j = 0; j < i; ++j)
98  {
99  // Compute the distance r1 from the center of each specified superellipsoid to its
100  // outside edge along the vector between the specified superellipsoid and the current
101  // randomly positioned one.
102  // This uses the equation for a superellipse in polar coordinates and substitutes
103  // distances for sin, cos functions.
104  Point dist_vec = _mesh.minPeriodicVector(_var.number(), _centers[i], _centers[j]);
105  const Real dist = dist_vec.norm();
106 
107  // First calculate rmn1 = r1^(-n), replacing sin, cos functions with distances
108  Real rmn1 = (std::pow(std::abs(dist_vec(0) / dist / _as[j]), _ns[j]) +
109  std::pow(std::abs(dist_vec(1) / dist / _bs[j]), _ns[j]) +
110  std::pow(std::abs(dist_vec(2) / dist / _cs[j]), _ns[j]));
111  // Then calculate r1 from rmn1
112  const Real r1 = std::pow(rmn1, (-1.0 / _ns[j]));
113 
114  // Now calculate the distance r2 from the center of the randomly placed
115  // superellipsoid to its outside edge in the same manner
116  Real rmn2 = (std::pow(std::abs(dist_vec(0) / dist / _as[i]), _ns[i]) +
117  std::pow(std::abs(dist_vec(1) / dist / _bs[i]), _ns[i]) +
118  std::pow(std::abs(dist_vec(2) / dist / _cs[i]), _ns[i]));
119  const Real r2 = std::pow(rmn2, (-1.0 / _ns[i]));
120 
121  if (j < _x_positions.size())
122  {
123  if (r1 - dist - r2 < _large_spac)
124  goto fail;
125  }
126  else
127  {
128  if (dist - r1 - r2 < _small_spac)
129  goto fail;
130  }
131  }
132 
133  // accept the position of the new center
134  goto accept;
135 
136  // retry a new position until tries are exhausted
137  fail:
138  continue;
139  }
140 
141  if (num_tries == _max_num_tries)
142  mooseError("Too many tries in MultiSmoothCircleIC");
143 
144  accept:
145  continue;
146  }
147 }
InputParameters validParams< BimodalSuperellipsoidsIC >()
virtual Real value(const Point &p)
Have to do things slightly different from SmoothSuperellipsoidBaseIC because of the inverse structure...
BimodalSuperellipsoidsIC takes a specified number of superellipsoids, each with given parameters Thes...
unsigned int _npart
Variables to describe the randomly placed (smaller) superellipsoids.
BimodalInverseSuperellipsoidsIC(const InputParameters &parameters)
virtual Real computeSuperellipsoidValue(const Point &p, const Point &center, Real a, Real b, Real c, Real n)
virtual Real computeSuperellipsoidInverseValue(const Point &p, const Point &center, Real a, Real b, Real c, Real n)
ExpressionBuilder::EBTerm pow(const ExpressionBuilder::EBTerm &left, T exponent)
InputParameters validParams< BimodalInverseSuperellipsoidsIC >()