www.mooseframework.org
ComputeGrainForceAndTorque.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 "GrainTrackerInterface.h"
12 
13 #include "libmesh/quadrature.h"
14 
16 
19 {
21  params.addClassDescription("Userobject for calculating force and torque acting on a grain");
22  params.addParam<MaterialPropertyName>("force_density", "force_density", "Force density material");
23  params.addParam<UserObjectName>("grain_data", "center of mass of grains");
24  params.addCoupledVar("c", "Concentration field");
25  params.addCoupledVar("etas", "Array of coupled order parameters");
26  return params;
27 }
28 
32  _c_name(coupledName("c", 0)),
33  _c_var(coupled("c")),
34  _dF_name(getParam<MaterialPropertyName>("force_density")),
35  _dF(getMaterialPropertyByName<std::vector<RealGradient>>(_dF_name)),
36  _dFdc(getMaterialPropertyByName<std::vector<RealGradient>>(
37  derivativePropertyNameFirst(_dF_name, _c_name))),
38  _op_num(coupledComponents("etas")),
39  _grain_tracker(getUserObject<GrainTrackerInterface>("grain_data")),
40  _vals_var(_op_num),
41  _vals_name(_op_num),
42  _dFdgradeta(_op_num)
43 {
44  for (unsigned int i = 0; i < _op_num; ++i)
45  {
46  _vals_var[i] = coupled("etas", i);
47  _vals_name[i] = coupledName("etas", i);
48  _dFdgradeta[i] = &getMaterialPropertyByName<std::vector<Real>>(
50  }
51 }
52 
53 void
55 {
57  _ncomp = 6 * _grain_num;
58 
59  _force_values.resize(_grain_num);
60  _torque_values.resize(_grain_num);
61  _force_torque_store.assign(_ncomp, 0.0);
62 
63  if (_fe_problem.currentlyComputingJacobian())
64  {
65  _total_dofs = _subproblem.es().n_dofs();
68 
69  for (unsigned int i = 0; i < _op_num; ++i)
71  }
72 }
73 
74 void
76 {
77  const auto & op_to_grains = _grain_tracker.getVarToFeatureVector(_current_elem->id());
78 
79  for (unsigned int i = 0; i < _grain_num; ++i)
80  for (unsigned int j = 0; j < _op_num; ++j)
81  if (i == op_to_grains[j])
82  {
83  const auto centroid = _grain_tracker.getGrainCentroid(i);
84  for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
85  if (_dF[_qp][j](0) != 0.0 || _dF[_qp][j](1) != 0.0 || _dF[_qp][j](2) != 0.0)
86  {
87  const RealGradient compute_torque =
88  _JxW[_qp] * _coord[_qp] *
89  (_current_elem->vertex_average() - centroid).cross(_dF[_qp][j]);
90  _force_torque_store[6 * i + 0] += _JxW[_qp] * _coord[_qp] * _dF[_qp][j](0);
91  _force_torque_store[6 * i + 1] += _JxW[_qp] * _coord[_qp] * _dF[_qp][j](1);
92  _force_torque_store[6 * i + 2] += _JxW[_qp] * _coord[_qp] * _dF[_qp][j](2);
93  _force_torque_store[6 * i + 3] += compute_torque(0);
94  _force_torque_store[6 * i + 4] += compute_torque(1);
95  _force_torque_store[6 * i + 5] += compute_torque(2);
96  }
97  }
98 }
99 
100 void
102 {
103  const auto & op_to_grains = _grain_tracker.getVarToFeatureVector(_current_elem->id());
104 
105  if (jvar == _c_var)
106  for (unsigned int i = 0; i < _grain_num; ++i)
107  for (unsigned int j = 0; j < _op_num; ++j)
108  if (i == op_to_grains[j])
109  {
110  const auto centroid = _grain_tracker.getGrainCentroid(i);
111  for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
112  if (_dFdc[_qp][j](0) != 0.0 || _dFdc[_qp][j](1) != 0.0 || _dFdc[_qp][j](2) != 0.0)
113  {
114  const Real factor = _JxW[_qp] * _coord[_qp] * _phi[_j][_qp];
115  const RealGradient compute_torque_jacobian_c =
116  factor * (_current_elem->vertex_average() - centroid).cross(_dFdc[_qp][j]);
117  _force_torque_c_jacobian_store[(6 * i + 0) * _total_dofs + _j_global] +=
118  factor * _dFdc[_qp][j](0);
119  _force_torque_c_jacobian_store[(6 * i + 1) * _total_dofs + _j_global] +=
120  factor * _dFdc[_qp][j](1);
121  _force_torque_c_jacobian_store[(6 * i + 2) * _total_dofs + _j_global] +=
122  factor * _dFdc[_qp][j](2);
123  _force_torque_c_jacobian_store[(6 * i + 3) * _total_dofs + _j_global] +=
124  compute_torque_jacobian_c(0);
125  _force_torque_c_jacobian_store[(6 * i + 4) * _total_dofs + _j_global] +=
126  compute_torque_jacobian_c(1);
127  _force_torque_c_jacobian_store[(6 * i + 5) * _total_dofs + _j_global] +=
128  compute_torque_jacobian_c(2);
129  }
130  }
131 
132  for (unsigned int i = 0; i < _op_num; ++i)
133  if (jvar == _vals_var[i])
134  for (unsigned int j = 0; j < _grain_num; ++j)
135  for (unsigned int k = 0; k < _op_num; ++k)
136  if (j == op_to_grains[k])
137  {
138  const auto centroid = _grain_tracker.getGrainCentroid(j);
139  for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
140  if ((*_dFdgradeta[i])[_qp][j] != 0.0)
141  {
142  const Real factor = _JxW[_qp] * _coord[_qp] * (*_dFdgradeta[i])[_qp][k];
143  const RealGradient compute_torque_jacobian_eta =
144  factor * (_current_elem->vertex_average() - centroid).cross(_grad_phi[_j][_qp]);
145  _force_torque_eta_jacobian_store[i][(6 * j + 0) * _total_dofs + _j_global] +=
146  factor * _grad_phi[_j][_qp](0);
147  _force_torque_eta_jacobian_store[i][(6 * j + 1) * _total_dofs + _j_global] +=
148  factor * _grad_phi[_j][_qp](1);
149  _force_torque_eta_jacobian_store[i][(6 * j + 2) * _total_dofs + _j_global] +=
150  factor * _grad_phi[_j][_qp](2);
151  _force_torque_eta_jacobian_store[i][(6 * j + 3) * _total_dofs + _j_global] +=
152  compute_torque_jacobian_eta(0);
153  _force_torque_eta_jacobian_store[i][(6 * j + 4) * _total_dofs + _j_global] +=
154  compute_torque_jacobian_eta(1);
155  _force_torque_eta_jacobian_store[i][(6 * j + 5) * _total_dofs + _j_global] +=
156  compute_torque_jacobian_eta(2);
157  }
158  }
159 }
160 
161 void
163 {
164  gatherSum(_force_torque_store);
165  for (unsigned int i = 0; i < _grain_num; ++i)
166  {
167  _force_values[i](0) = _force_torque_store[6 * i + 0];
168  _force_values[i](1) = _force_torque_store[6 * i + 1];
169  _force_values[i](2) = _force_torque_store[6 * i + 2];
170  _torque_values[i](0) = _force_torque_store[6 * i + 3];
171  _torque_values[i](1) = _force_torque_store[6 * i + 4];
172  _torque_values[i](2) = _force_torque_store[6 * i + 5];
173  }
174 
175  if (_fe_problem.currentlyComputingJacobian())
176  {
178  for (unsigned int i = 0; i < _op_num; ++i)
179  gatherSum(_force_torque_eta_jacobian_store[i]);
180  }
181 }
182 
183 void
185 {
186  const auto & pps = static_cast<const ComputeGrainForceAndTorque &>(y);
187  for (unsigned int i = 0; i < _ncomp; ++i)
188  _force_torque_store[i] += pps._force_torque_store[i];
189  if (_fe_problem.currentlyComputingJacobian())
190  {
191  for (unsigned int i = 0; i < _ncomp * _total_dofs; ++i)
192  _force_torque_c_jacobian_store[i] += pps._force_torque_c_jacobian_store[i];
193  for (unsigned int i = 0; i < _op_num; ++i)
194  for (unsigned int j = 0; j < _ncomp * _total_dofs; ++j)
195  _force_torque_eta_jacobian_store[i][j] += pps._force_torque_eta_jacobian_store[i][j];
196  }
197 }
198 
199 const std::vector<RealGradient> &
201 {
202  return _force_values;
203 }
204 
205 const std::vector<RealGradient> &
207 {
208  return _torque_values;
209 }
210 
211 const std::vector<Real> &
213 {
215 }
216 const std::vector<std::vector<Real>> &
218 {
220 }
const GrainTrackerInterface & _grain_tracker
provide UserObject for calculating grain volumes and centers
ComputeGrainForceAndTorque(const InputParameters &parameters)
std::vector< Real > _force_torque_c_jacobian_store
vector storing jacobian of grain force and torque values
This class defines the interface for the GrainTracking objects.
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
This class provides interface for extracting the forces and torques computed in other UserObjects...
std::vector< RealGradient > _force_values
providing grain forces, torques and their jacobians w. r. t c
virtual const std::vector< std::vector< Real > > & getForceEtaJacobians() const
static InputParameters validParams()
if(subdm)
virtual void executeJacobian(unsigned int jvar)
virtual const std::vector< RealGradient > & getForceValues() const
const MaterialPropertyName derivativePropertyNameFirst(const MaterialPropertyName &base, const SymbolName &c1) const
const std::vector< double > y
std::vector< std::vector< Real > > _force_torque_eta_jacobian_store
virtual std::size_t getTotalFeatureCount() const =0
Returns a number large enough to contain the largest ID for all grains in use.
const MaterialProperty< std::vector< RealGradient > > & _dF
virtual const std::vector< unsigned int > & getVarToFeatureVector(dof_id_type elem_id) const =0
Returns a list of active unique feature ids for a particular element.
virtual void threadJoin(const UserObject &y)
std::vector< RealGradient > _torque_values
std::vector< const MaterialProperty< std::vector< Real > > * > _dFdgradeta
virtual Point getGrainCentroid(unsigned int grain_id) const =0
Returns the centroid for the given grain number.
This class is here to get the force and torque acting on a grain.
virtual const std::vector< RealGradient > & getTorqueValues() const
void addCoupledVar(const std::string &name, const std::string &doc_string)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
registerMooseObject("PhaseFieldApp", ComputeGrainForceAndTorque)
static InputParameters validParams()
void addClassDescription(const std::string &doc_string)
std::vector< unsigned int > _vals_var
MaterialPropertyName _dF_name
material property that provides force density
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
unsigned int _op_num
no. of order parameters
const MaterialProperty< std::vector< RealGradient > > & _dFdc
material property that provides jacobian of force density with respect to c
std::vector< VariableName > _vals_name
virtual const std::vector< Real > & getForceCJacobians() const
static const std::string k
Definition: NS.h:124
std::vector< Real > _force_torque_store
vector storing grain force and torque values