www.mooseframework.org
SmoothCircleBaseIC.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 
10 #include "SmoothCircleBaseIC.h"
11 #include "MooseMesh.h"
12 #include "MooseVariable.h"
13 
14 #include "libmesh/utility.h"
15 
16 template <>
17 InputParameters
19 {
20  InputParameters params = validParams<InitialCondition>();
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 
38 SmoothCircleBaseIC::SmoothCircleBaseIC(const InputParameters & parameters)
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 
56 void
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 
70 Real
71 SmoothCircleBaseIC::value(const Point & p)
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 
88 {
89  if (_zero_gradient)
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;
102  gradient = computeCircleGradient(p, _centers[circ], _radii[circ]);
103  }
104  }
105 
106  return gradient;
107 }
108 
109 Real
110 SmoothCircleBaseIC::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.number(), 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 
139  case ProfileType::TANH:
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 
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.number(), 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 
180  case ProfileType::TANH:
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.number(), center, p) * (DvalueDr / dist);
190 }
SmoothCircleBaseIC::computeCircleCenters
virtual void computeCircleCenters()=0
SmoothCircleBaseIC::_random
MooseRandom _random
Definition: SmoothCircleBaseIC.h:63
SmoothCircleBaseIC::_centers
std::vector< Point > _centers
Definition: SmoothCircleBaseIC.h:54
SmoothCircleBaseIC::ProfileType::COS
SmoothCircleBaseIC::value
virtual Real value(const Point &p)
Definition: SmoothCircleBaseIC.C:71
SmoothCircleBaseIC::computeCircleValue
virtual Real computeCircleValue(const Point &p, const Point &center, const Real &radius)
Definition: SmoothCircleBaseIC.C:110
libMesh::RealGradient
VectorValue< Real > RealGradient
Definition: GrainForceAndTorqueInterface.h:17
SmoothCircleBaseIC::computeCircleRadii
virtual void computeCircleRadii()=0
SmoothCircleBaseIC.h
SmoothCircleBaseIC::_profile
enum SmoothCircleBaseIC::ProfileType _profile
SmoothCircleBaseIC::_radii
std::vector< Real > _radii
Definition: SmoothCircleBaseIC.h:55
SmoothCircleBaseIC::ProfileType::TANH
SmoothCircleBaseIC::_invalue
Real _invalue
Definition: SmoothCircleBaseIC.h:46
SmoothCircleBaseIC::computeCircleGradient
virtual RealGradient computeCircleGradient(const Point &p, const Point &center, const Real &radius)
Definition: SmoothCircleBaseIC.C:149
SmoothCircleBaseIC::_mesh
MooseMesh & _mesh
Definition: SmoothCircleBaseIC.h:44
SmoothCircleBaseIC::_outvalue
Real _outvalue
Definition: SmoothCircleBaseIC.h:47
SmoothCircleBaseIC::_zero_gradient
bool _zero_gradient
Definition: SmoothCircleBaseIC.h:50
SmoothCircleBaseIC::_int_width
Real _int_width
Definition: SmoothCircleBaseIC.h:48
SmoothCircleBaseIC::gradient
virtual RealGradient gradient(const Point &p)
Definition: SmoothCircleBaseIC.C:87
SmoothCircleBaseIC::_3D_spheres
bool _3D_spheres
Definition: SmoothCircleBaseIC.h:49
SmoothCircleBaseIC::initialSetup
virtual void initialSetup()
Definition: SmoothCircleBaseIC.C:57
validParams< SmoothCircleBaseIC >
InputParameters validParams< SmoothCircleBaseIC >()
Definition: SmoothCircleBaseIC.C:18
SmoothCircleBaseIC::SmoothCircleBaseIC
SmoothCircleBaseIC(const InputParameters &parameters)
Definition: SmoothCircleBaseIC.C:38
SmoothCircleBaseIC::ProfileType
ProfileType
Definition: SmoothCircleBaseIC.h:57