Line data Source code
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 "EulerAngleUpdaterCheck.h" 11 : #include "EulerAngleUpdater.h" 12 : #include "EulerAngleProvider.h" 13 : #include "GrainTrackerInterface.h" 14 : #include "GrainForceAndTorqueInterface.h" 15 : #include "RotationTensor.h" 16 : 17 : registerMooseObject("PhaseFieldApp", EulerAngleUpdaterCheck); 18 : 19 : InputParameters 20 22 : EulerAngleUpdaterCheck::validParams() 21 : { 22 22 : InputParameters params = GeneralVectorPostprocessor::validParams(); 23 22 : params.addClassDescription( 24 : "Provide updated Euler angles after rigid body rotation of the grains."); 25 44 : params.addRequiredParam<UserObjectName>("grain_tracker_object", 26 : "The FeatureFloodCount UserObject to get values from."); 27 44 : params.addParam<UserObjectName>("euler_angle_updater", 28 : "Name of Euler angle provider user object"); 29 44 : params.addRequiredParam<UserObjectName>("grain_torques_object", 30 : "Name of Euler angle provider user object"); 31 44 : params.addRequiredParam<VectorPostprocessorName>("grain_volumes", 32 : "The feature volume VectorPostprocessorValue."); 33 44 : params.addParam<Real>("rotation_constant", 1.0, "constant value characterizing grain rotation"); 34 22 : return params; 35 0 : } 36 : 37 11 : EulerAngleUpdaterCheck::EulerAngleUpdaterCheck(const InputParameters & params) 38 : : GeneralVectorPostprocessor(params), 39 11 : _diff(declareVector("vec_diff")), 40 11 : _grain_tracker(getUserObject<GrainTrackerInterface>("grain_tracker_object")), 41 11 : _euler(getUserObject<EulerAngleUpdater>("euler_angle_updater")), 42 11 : _grain_torque(getUserObject<GrainForceAndTorqueInterface>("grain_torques_object")), 43 11 : _grain_volumes(getVectorPostprocessorValue("grain_volumes", "feature_volumes")), 44 33 : _mr(getParam<Real>("rotation_constant")) 45 : { 46 11 : } 47 : 48 : void 49 17 : EulerAngleUpdaterCheck::initialize() 50 : { 51 17 : const auto grain_num = _grain_tracker.getTotalFeatureCount(); 52 17 : _angles.resize(grain_num); 53 17 : _angles_old.resize(grain_num); 54 17 : _diff.assign(3 * grain_num, 0.0); 55 : 56 34 : for (unsigned int i = 0; i < grain_num; ++i) 57 : { 58 17 : _angles[i] = _euler.getEulerAngles(i); 59 17 : _angles_old[i] = _euler.getEulerAnglesOld(i); 60 17 : RealGradient torque = _grain_torque.getTorqueValues()[i]; 61 : 62 : RealVectorValue a(1, 1, 1); 63 17 : RotationTensor R(_angles[i]); // Final rotation tensor 64 17 : RealVectorValue a_rot = R * a; // final rotated vector 65 : 66 17 : RotationTensor R0(_angles_old[i]); // RotationTensor as per old euler angles 67 17 : RealVectorValue torque_rot = R0 * torque; // Rotated torque 68 17 : RealVectorValue a_rot0 = R0 * a; // Rotated unit vector as per old euler angles 69 : 70 : /** 71 : * Change in euler angles are obtained from the torque & angular velocities about the material 72 : * axes. 73 : * Change in phi1, Phi and phi2 are caused by rotation about z axis, x' axis & z'' axis, 74 : * respectively. 75 : * Components of the angular velocities across z, x' and z'' axes are obtained from the torque 76 : * values. 77 : * This yields change in euler angles due to grain rotation. 78 : */ 79 : RealVectorValue torque_rot1; 80 : RealVectorValue angle_rot; 81 : torque_rot1(0) = 82 : torque_rot(2); // Tourque about z changed to torque responsible for chaneg in angle phi1 83 17 : angle_rot(0) = _mr / _grain_volumes[i] * torque_rot1(0) * _dt; // change in phi1 84 : // Tourque about x' changed to torque responsible for chaneg in angle Phi 85 : torque_rot1(1) = 86 17 : (torque_rot(0) * std::cos(angle_rot(0)) + torque_rot(1) * std::sin(angle_rot(0))); 87 17 : angle_rot(1) = _mr / _grain_volumes[i] * torque_rot1(1) * _dt; // change in Phi 88 : // Tourque about z'' changed to torque responsible for chaneg in angle phi2 89 17 : torque_rot1(2) = (torque_rot(0) * std::sin(angle_rot(0)) * std::sin(angle_rot(1)) - 90 17 : torque_rot(1) * std::cos(angle_rot(0)) * std::sin(angle_rot(1)) + 91 17 : torque_rot(2) * std::cos(angle_rot(1))); 92 17 : angle_rot(2) = _mr / _grain_volumes[i] * torque_rot1(2) * _dt; // change in phi2 93 : angle_rot *= (180.0 / libMesh::pi); 94 : 95 17 : RotationTensor R4(angle_rot); // RotationTensor due to grain rotation 96 17 : RealVectorValue a_rot1 = R4 * a_rot0; // Final rotated vector obtained in two step rotation 97 : 98 : // Difference between the final positions of the rotated vector obtained in two different ways, 99 : // should be 0.0 100 17 : _diff[3 * i + 0] = a_rot(0) - a_rot1(0); 101 17 : _diff[3 * i + 1] = a_rot(1) - a_rot1(1); 102 17 : _diff[3 * i + 2] = a_rot(2) - a_rot1(2); 103 : } 104 17 : }