www.mooseframework.org
TricrystalTripleJunctionIC.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 #include "MooseRandom.h"
12 #include "MooseMesh.h"
13 #include "MathUtils.h"
14 
16 
17 template <>
18 InputParameters
20 {
21  InputParameters params = validParams<InitialCondition>();
22  params.addClassDescription("Tricrystal with a triple junction");
23  params.addRequiredParam<unsigned int>("op_num", "Number of grain order parameters");
24  params.addRequiredParam<unsigned int>("op_index", "Index for the current grain order parameter");
25  params.addParam<Real>("theta1", 135.0, "Angle of first grain at triple junction in degrees");
26  params.addParam<Real>("theta2", 135.0, "Angle of second grain at triple junction in degrees");
27  params.addParam<Point>(
28  "junction",
29  "The point where the triple junction is located. Default is the center of the mesh");
30  return params;
31 }
32 
33 TricrystalTripleJunctionIC::TricrystalTripleJunctionIC(const InputParameters & parameters)
34  : InitialCondition(parameters),
35  _mesh(_fe_problem.mesh()),
36  _op_num(getParam<unsigned int>("op_num")),
37  _op_index(getParam<unsigned int>("op_index")),
38  _theta1(getParam<Real>("theta1")),
39  _theta2(getParam<Real>("theta2"))
40 {
41  if (_op_num != 3)
42  paramError("op_num", "Tricrystal ICs must have op_num = 3");
43 
44  if (_theta1 + _theta2 >= 360.0)
45  paramError("theta1", "Sum of the angles theta1 and theta2 must total less than 360 degrees");
46 
47  // Default junction point is the center
48  if (!parameters.isParamValid("junction"))
49  {
50  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
51  _junction(i) = (_mesh.getMaxInDimension(i) - _mesh.getMinInDimension(i)) / 2.0;
52  }
53  else
54  _junction = getParam<Point>("junction");
55 
56  // Make sure that _junction is in the domain
57  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
58  {
59  if ((_mesh.getMinInDimension(i) > _junction(i)) || (_mesh.getMaxInDimension(i) < _junction(i)))
60  paramError("junction", "Triple junction out of bounds");
61  }
62 
63  // Convert the angles to radians
64  _theta1 = _theta1 * libMesh::pi / 180.0;
65  _theta2 = _theta2 * libMesh::pi / 180.0;
66 
67  // Change the first angle to be measured from the +x axis
68  _theta1 = 3.0 * libMesh::pi / 2.0 - _theta1;
69 
70  // Change the third angle to be measured from the +x axis
71  _theta2 = _theta2 - libMesh::pi / 2.0;
72 
73  // Only compute the tangent once for computational efficiency
74  _tan_theta1 = std::tan(_theta1);
75  _tan_theta2 = std::tan(_theta2);
76 }
77 
78 Real
80 {
81  /*
82  * This does all the work to create a triple junction that looks like the letter Y
83  */
84  Real dist_left; // The distance from the point to the line specified by _theta1
85  Real dist_right; // The distance from the point to the line specified by _theta2
86 
87  // Check if the point is above or below the left-most line
88  // Function to use is y = _junction(1) + (x - _junction(0)) * std::tan(libMesh::pi/2.0 - _theta1)
89  if (_theta1 == 0) // Handle tan(0) case
90  dist_left = p(1) - _junction(1);
91  else
92  dist_left = p(1) - (_junction(1) + (p(0) - _junction(0)) * _tan_theta1);
93 
94  // Check if the point is above or below the right-most line
95  // Function to use is y = _junction(1) + (x - _junction(0))*std::tan(-(libMesh::pi/2.0 - _theta2))
96  if (_theta2 == 0) // Handle tan(0) classes
97  dist_right = p(1) - _junction(1);
98  else
99  dist_right = p(1) - (_junction(1) + (p(0) - _junction(0)) * _tan_theta2);
100 
101  // Check if the point is to the left or right of the middle line
102  Real dist_center = p(0) - _junction(0); // Negative value if the point is to the left
103 
104  if (_tan_theta1 > 0 && _theta1 <= libMesh::pi / 2.0) // Case for large left grain
105  {
106  /*
107  * There's a lot going on here. The first statement tells MOOSE to check and
108  * see if the current point is above the line defined by the first angle, only
109  * if it is past the center line. All other points to the left of the center
110  * line are going to be part of the 1st grain (_op_index == 1)
111  * The second statement defines the second grain by the line defined by _theta2
112  * and marks everything below that line, and to the right of the center line.
113  * The third statement takes care of everything in between.
114  */
115  if ((((dist_left >= 0 && dist_center >= 0) || (dist_center < 0)) && _op_index == 1) ||
116  (dist_right <= 0 && dist_center > 0 && _op_index == 2) ||
117  (dist_left < 0 && dist_center > 0 && dist_right > 0 && _op_index == 3))
118  return 1.0;
119  else
120  return 0.0;
121  }
122 
123  // This does a similar thing as the above case, but switches it for the right and left grains
124  else if (_tan_theta2 < 0 && _theta2 >= libMesh::pi / 2.0) // Case for large right grain
125  {
126  if ((dist_left <= 0 && dist_center <= 0 && _op_index == 1) ||
127  (((dist_right >= 0 && dist_center <= 0) || (dist_center > 0)) && _op_index == 2) ||
128  (dist_left > 0 && dist_right < 0 && dist_center < 0 && _op_index == 3))
129  return 1.0;
130  else
131  return 0.0;
132  }
133 
134  else // all other cases
135  {
136  if ((dist_left <= 0 && dist_center <= 0 && _op_index == 1) || // First grain
137  (dist_right <= 0 && dist_center > 0 && _op_index == 2) || // Second grain
138  (((dist_left > 0 && dist_center < 0) || (dist_right > 0 && dist_center >= 0)) &&
139  _op_index == 3)) // Third grain
140  return 1.0;
141  else
142  return 0.0;
143  }
144 }
TricrystalTripleJunctionIC::_op_index
const unsigned int _op_index
Definition: TricrystalTripleJunctionIC.h:38
TricrystalTripleJunctionIC::TricrystalTripleJunctionIC
TricrystalTripleJunctionIC(const InputParameters &parameters)
Definition: TricrystalTripleJunctionIC.C:33
TricrystalTripleJunctionIC::_op_num
const unsigned int _op_num
Number of order parameters.
Definition: TricrystalTripleJunctionIC.h:35
TricrystalTripleJunctionIC::_tan_theta1
Real _tan_theta1
tangent of the first angle after a shift of pi/2
Definition: TricrystalTripleJunctionIC.h:50
TricrystalTripleJunctionIC::value
virtual Real value(const Point &p)
Definition: TricrystalTripleJunctionIC.C:79
TricrystalTripleJunctionIC.h
TricrystalTripleJunctionIC::_tan_theta2
Real _tan_theta2
tangent of the second angle after a shift of pi/2
Definition: TricrystalTripleJunctionIC.h:53
validParams< TricrystalTripleJunctionIC >
InputParameters validParams< TricrystalTripleJunctionIC >()
Definition: TricrystalTripleJunctionIC.C:19
TricrystalTripleJunctionIC
TricrystalTripleJunctionIC creates a 3-grain structure with a triple junction centered at _junction a...
Definition: TricrystalTripleJunctionIC.h:24
TricrystalTripleJunctionIC::_junction
Point _junction
Point where the triple junction occurs.
Definition: TricrystalTripleJunctionIC.h:41
registerMooseObject
registerMooseObject("PhaseFieldApp", TricrystalTripleJunctionIC)
TricrystalTripleJunctionIC::_theta2
Real _theta2
Angle of third grain at triple junction in radians.
Definition: TricrystalTripleJunctionIC.h:47
TricrystalTripleJunctionIC::_theta1
Real _theta1
Angle of first grain at triple junction in radians.
Definition: TricrystalTripleJunctionIC.h:44
TricrystalTripleJunctionIC::_mesh
const MooseMesh & _mesh
Definition: TricrystalTripleJunctionIC.h:32