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");
41 _grain_volumes(getVectorPostprocessorValue(
"grain_volumes",
"feature_volumes")),
42 _mr(getParam<Real>(
"rotation_constant")),
56 for (
unsigned int i = 0; i < grain_num; ++i)
60 unsigned int angle_size =
_angles.size();
61 for (
unsigned int i = angle_size; i < grain_num; ++i)
64 for (
unsigned int i = 0; i < grain_num; ++i)
77 RealVectorValue torque_rotated =
79 RealVectorValue omega =
90 RealVectorValue angle_change;
91 angle_change(0) = omega(2) * _dt;
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))) *
98 angle_change *= (180.0 / libMesh::pi);
107 RealTensorValue R = R1 * R0;
109 if (R(2, 2) != 1.0 && R(2, 2) != -1.0)
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);
115 else if (R(2, 2) == 1.0)
122 _angles[i].phi1 = angle_change(0);
124 if (std::abs(
_angles[i].phi1) > 360.0)
126 int laps =
_angles[i].phi1 / 360.0;
127 _angles[i].phi1 -= laps * 360.0;
130 _angles[i].phi2 = -
_angles[i].phi1 + std::atan2(R(0, 1), R(1, 1)) * (180.0 / libMesh::pi);
137 _angles[i].phi1 = angle_change(0);
139 if (std::abs(
_angles[i].phi1) > 360.0)
141 int laps =
_angles[i].phi1 / 360.0;
142 _angles[i].phi1 -= laps * 360.0;
145 _angles[i].phi2 =
_angles[i].phi1 - std::atan2(-R(0, 1), -R(1, 1)) * (180.0 / libMesh::pi);
155 mooseError(
"Euler angle out of range.");
170 mooseAssert(i <
getGrainNum(),
"Requesting Euler angles for an invalid grain id");
177 mooseAssert(i <
getGrainNum(),
"Requesting Euler angles for an invalid grain id");