https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
32
33void
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
44Real
46{
47 Real value = _outvalue;
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
71void
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, _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)
const Real p
BimodalInverseSuperellipsoidsIC takes a specified number of superellipsoids, each with given paramete...
BimodalInverseSuperellipsoidsIC(const InputParameters &parameters)
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.
static InputParameters validParams()
MooseVariableField< T > & _var
void addClassDescription(const std::string &doc_string)
void paramError(const std::string &param, Args... args) const
void mooseError(Args &&... args) const
RealVectorValue minPeriodicVector(const unsigned int sys_num, const unsigned int var_num, Point p, Point q) const
Real rand(std::size_t i)
virtual Real computeSuperellipsoidInverseValue(const Point &p, const Point &center, Real a, Real b, Real c, Real n)
virtual Real computeSuperellipsoidValue(const Point &p, const Point &center, Real a, Real b, Real c, Real n)