https://mooseframework.inl.gov
Loading...
Searching...
No Matches
SmoothCircleBaseIC.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
10#include "SmoothCircleBaseIC.h"
11#include "MooseMesh.h"
12#include "MooseVariable.h"
13#include "FEProblemBase.h"
14
15#include "libmesh/utility.h"
16
19{
21 params.addRequiredParam<Real>("invalue", "The variable value inside the circle");
22 params.addRequiredParam<Real>("outvalue", "The variable value outside the circle");
23 params.addParam<Real>(
24 "int_width", 0.0, "The interfacial width of the void surface. Defaults to sharp interface");
25 params.addParam<bool>("3D_spheres", true, "in 3D, whether the objects are spheres or columns");
26 params.addParam<bool>("zero_gradient",
27 false,
28 "Set the gradient DOFs to zero. This can avoid "
29 "numerical problems with higher order shape "
30 "functions and overlapping circles.");
31 params.addParam<unsigned int>("rand_seed", 12345, "Seed value for the random number generator");
32 MooseEnum profileType("COS TANH", "COS");
33 params.addParam<MooseEnum>(
34 "profile", profileType, "Functional dependence for the interface profile");
35 return params;
36}
37
39 : InitialCondition(parameters),
40 _mesh(_fe_problem.mesh()),
41 _invalue(parameters.get<Real>("invalue")),
42 _outvalue(parameters.get<Real>("outvalue")),
43 _int_width(parameters.get<Real>("int_width")),
44 _3D_spheres(parameters.get<bool>("3D_spheres")),
45 _zero_gradient(parameters.get<bool>("zero_gradient")),
46 _num_dim(_3D_spheres ? 3 : 2),
47 _profile(getParam<MooseEnum>("profile").getEnum<ProfileType>())
48{
49 _random.seed(_tid, getParam<unsigned int>("rand_seed"));
50
51 if (_int_width <= 0.0 && _profile == ProfileType::TANH)
52 paramError("int_width",
53 "Interface width has to be strictly positive for the hyperbolic tangent profile");
54}
55
56void
58{
59 // Compute radii and centers and initialize vector sizes
62
63 if (_centers.size() != _radii.size())
64 mooseError("_center and _radii vectors are not the same size in the Circle IC");
65
66 if (_centers.size() < 1)
67 mooseError("_center and _radii were not initialized in the Circle IC");
68}
69
70Real
72{
73 Real value = _outvalue;
74 Real val2 = 0.0;
75
76 for (unsigned int circ = 0; circ < _centers.size() && value != _invalue; ++circ)
77 {
78 val2 = computeCircleValue(p, _centers[circ], _radii[circ]);
79 if ((val2 > value && _invalue > _outvalue) || (val2 < value && _outvalue > _invalue))
80 value = val2;
81 }
82
83 return value;
84}
85
86RealGradient
88{
90 return 0.0;
91
92 RealGradient gradient = 0.0;
93 Real value = _outvalue;
94 Real val2 = 0.0;
95
96 for (unsigned int circ = 0; circ < _centers.size(); ++circ)
97 {
98 val2 = computeCircleValue(p, _centers[circ], _radii[circ]);
99 if ((val2 > value && _invalue > _outvalue) || (val2 < value && _outvalue > _invalue))
100 {
101 value = val2;
103 }
104 }
105
106 return gradient;
107}
108
109Real
110SmoothCircleBaseIC::computeCircleValue(const Point & p, const Point & center, const Real & radius)
111{
112 Point l_center = center;
113 Point l_p = p;
114 if (!_3D_spheres) // Create 3D cylinders instead of spheres
115 {
116 l_p(2) = 0.0;
117 l_center(2) = 0.0;
118 }
119 // Compute the distance between the current point and the center
120 Real dist = _mesh.minPeriodicDistance(_var, l_p, l_center);
121
122 switch (_profile)
123 {
124 case ProfileType::COS:
125 {
126 // Return value
127 Real value = _outvalue; // Outside circle
128
129 if (dist <= radius - _int_width / 2.0) // Inside circle
130 value = _invalue;
131 else if (dist < radius + _int_width / 2.0) // Smooth interface
132 {
133 Real int_pos = (dist - radius + _int_width / 2.0) / _int_width;
134 value = _outvalue + (_invalue - _outvalue) * (1.0 + std::cos(int_pos * libMesh::pi)) / 2.0;
135 }
136 return value;
137 }
138
140 return (_invalue - _outvalue) * 0.5 * (std::tanh(2.0 * (radius - dist) / _int_width) + 1.0) +
141 _outvalue;
142
143 default:
144 mooseError("Internal error.");
145 }
146}
147
148RealGradient
150 const Point & center,
151 const Real & radius)
152{
153 Point l_center = center;
154 Point l_p = p;
155 if (!_3D_spheres) // Create 3D cylinders instead of spheres
156 {
157 l_p(2) = 0.0;
158 l_center(2) = 0.0;
159 }
160 // Compute the distance between the current point and the center
161 Real dist = _mesh.minPeriodicDistance(_var, l_p, l_center);
162
163 // early return if we are probing the center of the circle
164 if (dist == 0.0)
165 return 0.0;
166
167 Real DvalueDr = 0.0;
168 switch (_profile)
169 {
170 case ProfileType::COS:
171 if (dist < radius + _int_width / 2.0 && dist > radius - _int_width / 2.0)
172 {
173 const Real int_pos = (dist - radius + _int_width / 2.0) / _int_width;
174 const Real Dint_posDr = 1.0 / _int_width;
175 DvalueDr = Dint_posDr * (_invalue - _outvalue) *
176 (-std::sin(int_pos * libMesh::pi) * libMesh::pi) / 2.0;
177 }
178 break;
179
181 DvalueDr = -(_invalue - _outvalue) * 0.5 / _int_width * libMesh::pi *
182 (1.0 - Utility::pow<2>(std::tanh(4.0 * (radius - dist) / _int_width)));
183 break;
184
185 default:
186 mooseError("Internal error.");
187 }
188
189 return _mesh.minPeriodicVector(_var, center, p) * (DvalueDr / dist);
190}
const Real p
Point center
MooseVariableField< T > & _var
static InputParameters validParams()
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 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 minPeriodicDistance(const unsigned int sys_num, const unsigned int var_num, const Point &p, const Point &q) const
void seed(std::size_t i, unsigned int seed)
virtual Real computeCircleValue(const Point &p, const Point &center, const Real &radius)
SmoothCircleBaseIC(const InputParameters &parameters)
virtual void computeCircleCenters()=0
virtual RealGradient computeCircleGradient(const Point &p, const Point &center, const Real &radius)
virtual Real value(const Point &p)
static InputParameters validParams()
virtual RealGradient gradient(const Point &p)
std::vector< Real > _radii
std::vector< Point > _centers
enum SmoothCircleBaseIC::ProfileType _profile
virtual void computeCircleRadii()=0
virtual void initialSetup()
MeshBase & mesh
const Real pi
const Real radius