www.mooseframework.org
EulerAngleUpdater.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 "EulerAngleUpdater.h"
11 #include "GrainTrackerInterface.h"
13 #include "RotationTensor.h"
14 
15 registerMooseObject("PhaseFieldApp", EulerAngleUpdater);
16 
17 template <>
18 InputParameters
20 {
21  InputParameters params = validParams<EulerAngleProvider>();
22  params.addClassDescription(
23  "Provide updated euler angles after rigid body rotation of the grains.");
24  params.addRequiredParam<UserObjectName>("grain_tracker_object",
25  "The FeatureFloodCount UserObject to get values from.");
26  params.addRequiredParam<UserObjectName>("euler_angle_provider",
27  "Name of Euler angle provider user object");
28  params.addRequiredParam<UserObjectName>("grain_torques_object",
29  "Name of Euler angle provider user object");
30  params.addRequiredParam<VectorPostprocessorName>("grain_volumes",
31  "The feature volume VectorPostprocessorValue.");
32  params.addParam<Real>("rotation_constant", 1.0, "Constant value characterizing grain rotation");
33  return params;
34 }
35 
36 EulerAngleUpdater::EulerAngleUpdater(const InputParameters & params)
37  : EulerAngleProvider(params),
38  _grain_tracker(getUserObject<GrainTrackerInterface>("grain_tracker_object")),
39  _euler(getUserObject<EulerAngleProvider>("euler_angle_provider")),
40  _grain_torque(getUserObject<GrainForceAndTorqueInterface>("grain_torques_object")),
41  _grain_volumes(getVectorPostprocessorValue("grain_volumes", "feature_volumes")),
42  _mr(getParam<Real>("rotation_constant")),
43  _first_time(true)
44 {
45 }
46 
47 void
49 {
50  const auto grain_num = _grain_tracker.getTotalFeatureCount();
51 
52  if (_first_time)
53  {
54  _angles.resize(grain_num);
55  _angles_old.resize(grain_num);
56  for (unsigned int i = 0; i < grain_num; ++i)
57  _angles[i] = _euler.getEulerAngles(i); // Read initial euler angles
58  }
59 
60  unsigned int angle_size = _angles.size();
61  for (unsigned int i = angle_size; i < grain_num; ++i) // if new grains are created
62  _angles.push_back(_euler.getEulerAngles(i)); // Assign initial euler angles
63 
64  for (unsigned int i = 0; i < grain_num; ++i)
65  {
66  if (!_first_time && !_fe_problem.converged())
67  _angles[i] = _angles_old[i];
68 
70 
71  if (i <= angle_size) // if new grains are created
72  _angles_old[i] = _angles[i];
73  else
74  _angles_old.push_back(_angles[i]);
75 
76  RotationTensor R0(_angles_old[i]); // RotationTensor as per old euler angles
77  RealVectorValue torque_rotated =
78  R0 * torque; // Applied torque is rotated to allign with old grain axes
79  RealVectorValue omega =
80  _mr / _grain_volumes[i] * torque_rotated; // Angular velocity as per old grain axes
90  RealVectorValue angle_change;
91  angle_change(0) = omega(2) * _dt;
92  angle_change(1) =
93  (omega(0) * std::cos(angle_change(0)) + omega(1) * std::sin(angle_change(0))) * _dt;
94  angle_change(2) = (omega(0) * std::sin(angle_change(0)) * std::sin(angle_change(1)) -
95  omega(1) * std::cos(angle_change(0)) * std::sin(angle_change(1)) +
96  omega(2) * std::cos(angle_change(1))) *
97  _dt;
98  angle_change *= (180.0 / libMesh::pi);
99 
100  RotationTensor R1(angle_change); // Rotation matrix due to torque
107  RealTensorValue R = R1 * R0;
108 
109  if (R(2, 2) != 1.0 && R(2, 2) != -1.0) // checks if cos(Phi) = 1 or -1
110  {
111  _angles[i].phi1 = std::atan2(R(2, 0), -R(2, 1)) * (180.0 / libMesh::pi);
112  _angles[i].Phi = std::acos(R(2, 2)) * (180.0 / libMesh::pi);
113  _angles[i].phi2 = std::atan2(R(0, 2), R(1, 2)) * (180.0 / libMesh::pi);
114  }
115  else if (R(2, 2) == 1.0) // special case for Phi = 0.0
116  {
117  if (R0(2, 2) == 1.0)
118  // when Phi_old = 0.0; all the rotations are about z axis and angles accumulates after each
119  // rotation
120  _angles[i].phi1 = _angles_old[i].phi1 + _angles_old[i].phi2 + angle_change(0);
121  else
122  _angles[i].phi1 = angle_change(0);
123  // Comply with bunge euler angle definitions, 0.0 <= phi1 <= 360.0
124  if (std::abs(_angles[i].phi1) > 360.0)
125  {
126  int laps = _angles[i].phi1 / 360.0;
127  _angles[i].phi1 -= laps * 360.0;
128  }
129  _angles[i].Phi = 0.0;
130  _angles[i].phi2 = -_angles[i].phi1 + std::atan2(R(0, 1), R(1, 1)) * (180.0 / libMesh::pi);
131  }
132  else
133  {
134  if (R0(2, 2) == 1.0)
135  _angles[i].phi1 = _angles_old[i].phi1 + _angles_old[i].phi2 + angle_change(0);
136  else
137  _angles[i].phi1 = angle_change(0);
138  // Comply with bunge euler angle definitions, 0.0 <= phi1 <= 360.0
139  if (std::abs(_angles[i].phi1) > 360.0)
140  {
141  int laps = _angles[i].phi1 / 360.0;
142  _angles[i].phi1 -= laps * 360.0;
143  }
144  _angles[i].Phi = 180.0;
145  _angles[i].phi2 = _angles[i].phi1 - std::atan2(-R(0, 1), -R(1, 1)) * (180.0 / libMesh::pi);
146  }
147 
148  // Following checks and updates are done only to comply with bunge euler angle definitions, 0.0
149  // <= phi1/phi2 <= 360.0
150  if (_angles[i].phi1 < 0.0)
151  _angles[i].phi1 += 360.0;
152  if (_angles[i].phi2 < 0.0)
153  _angles[i].phi2 += 360.0;
154  if (_angles[i].Phi < 0.0)
155  mooseError("Euler angle out of range.");
156  }
157 
158  _first_time = false;
159 }
160 
161 unsigned int
163 {
164  return _angles.size();
165 }
166 
167 const EulerAngles &
169 {
170  mooseAssert(i < getGrainNum(), "Requesting Euler angles for an invalid grain id");
171  return _angles[i];
172 }
173 
174 const EulerAngles &
176 {
177  mooseAssert(i < getGrainNum(), "Requesting Euler angles for an invalid grain id");
178  return _angles_old[i];
179 }
EulerAngleUpdater::getGrainNum
virtual unsigned int getGrainNum() const override
Definition: EulerAngleUpdater.C:162
GrainTrackerInterface
This class defines the interface for the GrainTracking objects.
Definition: GrainTrackerInterface.h:24
libMesh::RealGradient
VectorValue< Real > RealGradient
Definition: GrainForceAndTorqueInterface.h:17
GrainForceAndTorqueInterface.h
EulerAngleUpdater::_grain_tracker
const GrainTrackerInterface & _grain_tracker
Definition: EulerAngleUpdater.h:50
EulerAngleUpdater::_euler
const EulerAngleProvider & _euler
Definition: EulerAngleUpdater.h:51
EulerAngleUpdater.h
EulerAngleUpdater::getEulerAnglesOld
virtual const EulerAngles & getEulerAnglesOld(unsigned int) const
Definition: EulerAngleUpdater.C:175
EulerAngleUpdater::_grain_volumes
const VectorPostprocessorValue & _grain_volumes
Definition: EulerAngleUpdater.h:53
EulerAngleProvider
Abstract base class for user objects that implement the Euler Angle provider interface.
Definition: EulerAngleProvider.h:24
validParams< EulerAngleProvider >
InputParameters validParams< EulerAngleProvider >()
EulerAngleUpdater::EulerAngleUpdater
EulerAngleUpdater(const InputParameters &parameters)
Definition: EulerAngleUpdater.C:36
GrainTrackerInterface::getTotalFeatureCount
virtual std::size_t getTotalFeatureCount() const =0
Returns a number large enough to contain the largest ID for all grains in use.
EulerAngleUpdater
Update Euler angles of each grains after rigid body rotation This class estimates the rotation of pri...
Definition: EulerAngleUpdater.h:36
RotationTensor
This is a RealTensor version of a rotation matrix It is instantiated with the Euler angles,...
Definition: RotationTensor.h:29
validParams< EulerAngleUpdater >
InputParameters validParams< EulerAngleUpdater >()
Definition: EulerAngleUpdater.C:19
GrainTrackerInterface.h
EulerAngleUpdater::_angles
std::vector< EulerAngles > _angles
Definition: EulerAngleUpdater.h:58
EulerAngleUpdater::_mr
const Real _mr
Definition: EulerAngleUpdater.h:55
EulerAngleUpdater::_first_time
bool _first_time
Definition: EulerAngleUpdater.h:56
registerMooseObject
registerMooseObject("PhaseFieldApp", EulerAngleUpdater)
EulerAngleUpdater::_grain_torque
const GrainForceAndTorqueInterface & _grain_torque
Definition: EulerAngleUpdater.h:52
RotationTensor.h
EulerAngles
Euler angle triplet.
Definition: EulerAngles.h:22
EulerAngleUpdater::initialize
virtual void initialize() override
Definition: EulerAngleUpdater.C:48
EulerAngleUpdater::getEulerAngles
virtual const EulerAngles & getEulerAngles(unsigned int) const override
Definition: EulerAngleUpdater.C:168
GrainForceAndTorqueInterface::getTorqueValues
virtual const std::vector< RealGradient > & getTorqueValues() const =0
EulerAngleProvider::getEulerAngles
virtual const EulerAngles & getEulerAngles(unsigned int) const =0
EulerAngleUpdater::_angles_old
std::vector< EulerAngles > _angles_old
Definition: EulerAngleUpdater.h:59
GrainForceAndTorqueInterface
This class provides interface for extracting the forces and torques computed in other UserObjects.
Definition: GrainForceAndTorqueInterface.h:24