13 #include "libmesh/mesh_tools.h" 21 params.
addParam<
unsigned int>(
"bins", 20,
"Number of bins to segregate quaternions");
22 params.
addParam<
Real>(
"L_norm", 1,
"Specifies the type of average the user intends to perform");
24 "This object determines the orientation of each grain (block) by identifying the most common " 25 "orientation direction among the material points within the grain.");
32 _updated_rotation(getMaterialProperty<
RankTwoTensor>(
"updated_rotation")),
33 _bins(getParam<unsigned
int>(
"bins")),
34 _L_norm(getParam<
Real>(
"L_norm"))
53 for (
unsigned int _qp = 0; _qp <
_qrule->n_points(); _qp++)
58 Eigen::Matrix<Real, 3, 3> rot_mat;
60 for (
unsigned int i = 0; i < 3; ++i)
61 for (
unsigned int j = 0;
j < 3; ++
j)
62 rot_mat(i,
j) = rot(i,
j);
65 Eigen::JacobiSVD<Eigen::Matrix<Real, 3, 3>> svd(rot_mat,
66 Eigen::ComputeFullU | Eigen::ComputeFullV);
68 Eigen::Matrix<Real, 3, 3> U = svd.matrixU();
69 Eigen::Matrix<Real, 3, 3> V = svd.matrixV();
72 Eigen::Matrix<Real, 3, 3>
R = U * V.transpose();
73 if (
R.determinant() < 0.0)
75 Eigen::Matrix<Real, 3, 3> D = Eigen::Matrix<Real, 3, 3>::Identity();
77 R = U * D * V.transpose();
81 Eigen::Quaternion<Real> q(
R);
83 _quat[
_current_elem->subdomain_id()].push_back(std::make_tuple(q.w(), q.x(), q.y(), q.z()));
101 std::map<std::tuple<int, int, int, int>,
unsigned int> feature_weights;
106 for (
const auto & [w,
x,
y, z] :
_quat[sid])
108 const auto bin = std::make_tuple<int, int, int, int>(std::floor(w * bin_scale),
109 std::floor(
x * bin_scale),
110 std::floor(
y * bin_scale),
111 std::floor(z * bin_scale));
112 feature_weights[bin]++;
116 typedef Eigen::Matrix<Real, 4, 4> Matrix4x4;
117 Matrix4x4 quat_mat = Matrix4x4::Zero();
118 typedef Eigen::Matrix<Real, 4, 1> Vector4;
122 for (
const auto & [w,
x,
y, z] :
_quat[sid])
124 Vector4
v(w,
x,
y, z);
126 const auto bin = std::make_tuple<int, int, int, int>(std::floor(w * bin_scale),
127 std::floor(
x * bin_scale),
128 std::floor(
y * bin_scale),
129 std::floor(z * bin_scale));
130 const auto bin_size = feature_weights[bin];
134 quat_mat +=
v *
weight *
v.transpose();
140 Eigen::EigenSolver<Matrix4x4> EigenSolver(quat_mat);
141 Vector4 eigen_values = EigenSolver.eigenvalues().real();
142 Matrix4x4 eigen_vectors = EigenSolver.eigenvectors().real();
145 Vector4::Index max_index = 0;
146 eigen_values.maxCoeff(&max_index);
147 const auto max_vec = eigen_vectors.col(max_index) / eigen_vectors.col(max_index).norm();
148 const Eigen::Quaternion<Real> q(max_vec(0), max_vec(1), max_vec(2), max_vec(3));
std::map< SubdomainID, EulerAngles > _block_ea_values
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
void mooseSetToZero(T &v)
const MaterialProperty< RankTwoTensor > & _updated_rotation
static InputParameters validParams()
const MooseArray< Real > & _coord
registerMooseObject("SolidMechanicsApp", ComputeBlockOrientationByRotation)
virtual void initialize() override
Clear internal Euler angle and misorientationdata.
unsigned int _bins
number of bins for each quaternion component
const std::vector< double > y
const Parallel::Communicator & _communicator
const Real & _current_elem_volume
EulerAngles computeSubdomainEulerAngles(const SubdomainID &sid)
Compute Quaternion for each subdomain (block), following Markley, F.
Real _L_norm
parameter used to compute the weighting function for the average quaternion calculation ...
FEProblemBase & _fe_problem
virtual void execute() override
Compute the average of the rotation matrix in this element.
const std::vector< double > x
Computes the average value of a variable on each block.
Computes the average value of a variable on each block.
virtual void initialize() override
This is called before execute so you can reset any internal data.
static InputParameters validParams()
ComputeBlockOrientationByRotation(const InputParameters ¶meters)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const QBase *const & _qrule
const Elem *const & _current_elem
const MooseArray< Real > & _JxW
virtual MooseMesh & mesh() override
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
std::unordered_map< SubdomainID, std::vector< std::tuple< Real, Real, Real, Real > > > _quat
virtual void finalize() override
Gather all Euler angles from this block.
MooseUnits pow(const MooseUnits &, int)
void ErrorVector unsigned int
const std::set< SubdomainID > & meshSubdomains() const