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