https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ComputeBlockOrientationByMisorientation.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 "MooseMesh.h"
12
13#include "libmesh/mesh_tools.h"
14
16
19{
21 params.addClassDescription("This object computes the orientation of each grain (block) by "
22 "calculating the maximum misorientation within the grain.");
23 return params;
24}
25
27 const InputParameters & parameters)
28 : ComputeBlockOrientationBase(parameters),
29 _updated_rotation(getMaterialProperty<RankTwoTensor>("updated_rotation")),
30 _misorient(getMaterialProperty<Real>("misorientation"))
31{
32}
33
34void
42
43void
45{
46 RankTwoTensor rot;
47 Real misorient = 0.0;
48
49 for (unsigned int _qp = 0; _qp < _qrule->n_points(); _qp++)
50 {
51 rot += _JxW[_qp] * _coord[_qp] * _updated_rotation[_qp];
52 misorient += _JxW[_qp] * _coord[_qp] * _misorient[_qp];
53 }
55 misorient /= _current_elem_volume;
56
57 // transform RankTwoTensor to Eigen::Matrix
58 Eigen::Matrix<Real, 3, 3> rot_mat;
59
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);
63
64 // SVD-based projection to SO(3)
65 Eigen::JacobiSVD<Eigen::Matrix<Real, 3, 3>> svd(rot_mat,
66 Eigen::ComputeFullU | Eigen::ComputeFullV);
67
68 Eigen::Matrix<Real, 3, 3> U = svd.matrixU();
69 Eigen::Matrix<Real, 3, 3> V = svd.matrixV();
70
71 // Enforce proper rotation (det = +1)
72 Eigen::Matrix<Real, 3, 3> R = U * V.transpose();
73 if (R.determinant() < 0.0)
74 {
75 Eigen::Matrix<Real, 3, 3> D = Eigen::Matrix<Real, 3, 3>::Identity();
76 D(2, 2) = -1.0;
77 R = U * D * V.transpose();
78 }
79
80 // compute Quaternion from rotation matrix
81 Eigen::Quaternion<Real> q(R);
82
83 // compute EulerAngle from Quaternion
85
86 // store value for the current misorientation in the subdomain
87 // save EulerAngle in tuple so that we can gather the data from all processors
88 _grain_misorientation[_current_elem->subdomain_id()].emplace_back(
89 misorient, ea.phi1, ea.Phi, ea.phi2);
90}
91
92void
101
104{
105 Real max_misorientation = 0.0; // misorientation values should within [0, pi]
106 EulerAngles ea;
107 bool has_update = false;
108 for (const auto & [misorientation, phi1, Phi, phi2] : _grain_misorientation[sid])
109 {
110 if (misorientation > max_misorientation)
111 {
112 max_misorientation = misorientation;
113 ea = EulerAngles(phi1, Phi, phi2);
114 has_update = true;
115 }
116 }
117
118 // check if we actually update EulerAngle based on misorientation
119 // if not, grab it from the previous step
120 if (!has_update)
121 return _block_ea_values[sid];
122
123 return ea;
124}
registerMooseObject("SolidMechanicsApp", ComputeBlockOrientationByMisorientation)
const double R
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.
std::map< SubdomainID, EulerAngles > _block_ea_values
Computes the average value of a variable on each block.
ComputeBlockOrientationByMisorientation(const InputParameters &parameters)
std::unordered_map< SubdomainID, std::vector< std::tuple< Real, Real, Real, Real > > > _grain_misorientation
const MaterialProperty< RankTwoTensor > & _updated_rotation
virtual void finalize() override
Sync data from all processors (gather the maximum misorientation and the corresponding EulerAngle fro...
virtual void initialize() override
Clear internal Euler angle and misorientationdata.
virtual void execute() override
Compute the average of the rotation matrix, Euler angles, and misorientation in each element.
const QBase *const & _qrule
const Elem *const & _current_elem
const MooseArray< Real > & _coord
const MooseArray< Real > & _JxW
const Real & _current_elem_volume
Euler angle triplet.
Definition EulerAngles.h:25
virtual MooseMesh & mesh() override
void addClassDescription(const std::string &doc_string)
const std::set< SubdomainID > & meshSubdomains() const
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
FEProblemBase & _fe_problem
const Parallel::Communicator & _communicator