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