https://mooseframework.inl.gov
BimodalInverseSuperellipsoidsIC.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 
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, value invalue) and small particles (placed randomly inside the "
24  "larger particles, value outvalue)");
25  return params;
26 }
27 
29  : BimodalSuperellipsoidsIC(parameters)
30 {
31 }
32 
33 void
35 {
36  if (_size_variation_type == 2 && _size_variation > 0.0)
37  paramError("size_variation",
38  "If size_variation > 0.0, you must pass in a size_variation_type in "
39  "BimodalInverseSuperellipsoidsIC");
40 
42 }
43 
44 Real
46 {
48  Real val2 = 0.0;
49 
50  // First loop over the specified superellipsoids
51  for (unsigned int ellip = 0; ellip < _x_positions.size() && value != _invalue; ++ellip)
52  {
54  p, _centers[ellip], _as[ellip], _bs[ellip], _cs[ellip], _ns[ellip]);
55  if ((val2 > value && _invalue > _outvalue) || (val2 < value && _outvalue > _invalue))
56  value = val2;
57  }
58 
59  // Then loop over the randomly positioned particles and set value inside them back to outvalue
60  for (unsigned int ellip = _x_positions.size(); ellip < _x_positions.size() + _npart; ++ellip)
61  {
63  p, _centers[ellip], _as[ellip], _bs[ellip], _cs[ellip], _ns[ellip]);
64  if ((val2 < value && _invalue > _outvalue) || (val2 > value && _outvalue > _invalue))
65  value = val2;
66  }
67 
68  return value;
69 }
70 
71 void
73 {
74  _centers.resize(_x_positions.size() + _npart);
75 
76  // First place the specified (large) particles from the input file
77  for (unsigned int i = 0; i < _x_positions.size(); ++i)
78  {
79  _centers[i](0) = _x_positions[i];
80  _centers[i](1) = _y_positions[i];
81  _centers[i](2) = _z_positions[i];
82  }
83 
84  // Next place the randomly positioned (small) particles
85  for (unsigned int i = _x_positions.size(); i < _x_positions.size() + _npart; ++i)
86  {
87  unsigned int num_tries = 0;
88 
89  while (num_tries < _max_num_tries)
90  {
91  num_tries++;
92 
93  RealTensorValue ran;
94  ran(0, 0) = _random.rand(_tid);
95  ran(1, 1) = _random.rand(_tid);
96  ran(2, 2) = _random.rand(_tid);
97 
98  _centers[i] = _bottom_left + ran * _range;
99 
100  // check for collisions with the specified (large) and randomly placed small particles
101  for (unsigned int j = 0; j < i; ++j)
102  {
103  // Compute the distance r1 from the center of each specified superellipsoid to its
104  // outside edge along the vector between the specified superellipsoid and the current
105  // randomly positioned one.
106  // This uses the equation for a superellipse in polar coordinates and substitutes
107  // distances for sin, cos functions.
108  Point dist_vec = _mesh.minPeriodicVector(_var.number(), _centers[i], _centers[j]);
109  const Real dist = dist_vec.norm();
110 
111  // First calculate rmn1 = r1^(-n), replacing sin, cos functions with distances
112  Real rmn1 = (std::pow(std::abs(dist_vec(0) / dist / _as[j]), _ns[j]) +
113  std::pow(std::abs(dist_vec(1) / dist / _bs[j]), _ns[j]) +
114  std::pow(std::abs(dist_vec(2) / dist / _cs[j]), _ns[j]));
115  // Then calculate r1 from rmn1
116  const Real r1 = std::pow(rmn1, (-1.0 / _ns[j]));
117 
118  // Now calculate the distance r2 from the center of the randomly placed
119  // superellipsoid to its outside edge in the same manner
120  Real rmn2 = (std::pow(std::abs(dist_vec(0) / dist / _as[i]), _ns[i]) +
121  std::pow(std::abs(dist_vec(1) / dist / _bs[i]), _ns[i]) +
122  std::pow(std::abs(dist_vec(2) / dist / _cs[i]), _ns[i]));
123  const Real r2 = std::pow(rmn2, (-1.0 / _ns[i]));
124 
125  if (j < _x_positions.size())
126  {
127  if (r1 - dist - r2 < _large_spac)
128  goto fail;
129  }
130  else
131  {
132  if (dist - r1 - r2 < _small_spac)
133  goto fail;
134  }
135  }
136 
137  // accept the position of the new center
138  goto accept;
139 
140  // retry a new position until tries are exhausted
141  fail:
142  continue;
143  }
144 
145  if (num_tries == _max_num_tries)
146  mooseError("Too many tries in MultiSmoothCircleIC");
147 
148  accept:
149  continue;
150  }
151 }
registerMooseObject("PhaseFieldApp", BimodalInverseSuperellipsoidsIC)
unsigned int number() const
RealVectorValue minPeriodicVector(unsigned int nonlinear_var_num, Point p, Point q) const
virtual Real value(const Point &p)
Have to do things slightly different from SmoothSuperellipsoidBaseIC because of the inverse structure...
MooseVariableField< T > & _var
static InputParameters validParams()
BimodalSuperellipsoidsIC takes a specified number of superellipsoids, each with given parameters Thes...
TensorValue< Real > RealTensorValue
unsigned int _npart
Variables to describe the randomly placed (smaller) superellipsoids.
BimodalInverseSuperellipsoidsIC(const InputParameters &parameters)
void paramError(const std::string &param, Args... args) const
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)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
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")
BimodalInverseSuperellipsoidsIC takes a specified number of superellipsoids, each with given paramete...
Real rand(std::size_t i)
MooseUnits pow(const MooseUnits &, int)