https://mooseframework.inl.gov
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 
34 void
36 {
38 
39  _block_ea_values.clear();
40  _grain_misorientation.clear();
41 }
42 
43 void
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  }
54  rot /= _current_elem_volume;
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
84  EulerAngles ea = EulerAngles(q);
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 
92 void
94 {
95  for (const auto & block : _fe_problem.mesh().meshSubdomains())
96  {
99  }
100 }
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 }
std::map< SubdomainID, EulerAngles > _block_ea_values
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
static InputParameters validParams()
const MooseArray< Real > & _coord
ComputeBlockOrientationByMisorientation(const InputParameters &parameters)
const Parallel::Communicator & _communicator
const double R
const Real & _current_elem_volume
FEProblemBase & _fe_problem
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::unordered_map< SubdomainID, std::vector< std::tuple< Real, Real, Real, Real > > > _grain_misorientation
Computes the average value of a variable on each block.
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 void initialize() override
Clear internal Euler angle and misorientationdata.
Euler angle triplet.
Definition: EulerAngles.h:24
virtual MooseMesh & mesh() override
void addClassDescription(const std::string &doc_string)
const MaterialProperty< RankTwoTensor > & _updated_rotation
registerMooseObject("SolidMechanicsApp", ComputeBlockOrientationByMisorientation)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
virtual void execute() override
Compute the average of the rotation matrix, Euler angles, and misorientation in each element...
virtual void finalize() override
Sync data from all processors (gather the maximum misorientation and the corresponding EulerAngle fro...
const std::set< SubdomainID > & meshSubdomains() const