https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ComputeExternalGrainForceAndTorque.C
Go to the documentation of this file.
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
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
30 const InputParameters & parameters)
33 _c_name(coupledName("c", 0)),
34 _c_var(coupled("c")),
35 _dF_name(getParam<MaterialPropertyName>("force_density")),
36 _dF(getMaterialPropertyByName<std::vector<RealGradient>>(_dF_name)),
37 _dFdc(getMaterialPropertyByName<std::vector<RealGradient>>(
38 derivativePropertyNameFirst(_dF_name, _c_name))),
39 _op_num(coupledComponents("etas")),
40 _grain_tracker(getUserObject<GrainTrackerInterface>("grain_data")),
41 _vals_var(_op_num),
42 _vals_name(_op_num),
43 _dFdeta(_op_num)
44{
45 for (unsigned int i = 0; i < _op_num; ++i)
46 {
47 _vals_var[i] = coupled("etas", i);
48 _vals_name[i] = coupledName("etas", i);
49 _dFdeta[i] = &getMaterialPropertyByName<std::vector<RealGradient>>(
51 }
52}
53
54void
56{
58 _ncomp = 6 * _grain_num;
59
62 _force_torque_store.assign(_ncomp, 0.0);
63
64 if (_fe_problem.currentlyComputingJacobian())
65 {
66 _total_dofs = _subproblem.es().n_dofs();
69
70 for (unsigned int i = 0; i < _op_num; ++i)
72 }
73}
74
75void
77{
78 const auto & op_to_grains = _grain_tracker.getVarToFeatureVector(_current_elem->id());
79
80 for (unsigned int i = 0; i < _grain_num; ++i)
81 for (unsigned int j = 0; j < _op_num; ++j)
82 if (i == op_to_grains[j])
83 {
84 const auto centroid = _grain_tracker.getGrainCentroid(i);
85 for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
86 if (_dF[_qp][j](0) != 0.0 || _dF[_qp][j](1) != 0.0 || _dF[_qp][j](2) != 0.0)
87 {
88 const RealGradient compute_torque =
89 _JxW[_qp] * _coord[_qp] *
90 (_current_elem->vertex_average() - centroid).cross(_dF[_qp][j]);
91 _force_torque_store[6 * i + 0] += _JxW[_qp] * _coord[_qp] * _dF[_qp][j](0);
92 _force_torque_store[6 * i + 1] += _JxW[_qp] * _coord[_qp] * _dF[_qp][j](1);
93 _force_torque_store[6 * i + 2] += _JxW[_qp] * _coord[_qp] * _dF[_qp][j](2);
94 _force_torque_store[6 * i + 3] += compute_torque(0);
95 _force_torque_store[6 * i + 4] += compute_torque(1);
96 _force_torque_store[6 * i + 5] += compute_torque(2);
97 }
98 }
99}
100
101void
103{
104 const auto & op_to_grains = _grain_tracker.getVarToFeatureVector(_current_elem->id());
105
106 if (jvar == _c_var)
107 for (unsigned int i = 0; i < _grain_num; ++i)
108 for (unsigned int j = 0; j < _op_num; ++j)
109 if (i == op_to_grains[j])
110 {
111 const auto centroid = _grain_tracker.getGrainCentroid(i);
112 for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
113 if (_dFdc[_qp][j](0) != 0.0 || _dFdc[_qp][j](1) != 0.0 || _dFdc[_qp][j](2) != 0.0)
114 {
115 const Real factor = _JxW[_qp] * _coord[_qp] * _phi[_j][_qp];
116 const RealGradient compute_torque_jacobian_c =
117 factor * (_current_elem->vertex_average() - centroid).cross(_dFdc[_qp][j]);
118 _force_torque_c_jacobian_store[(6 * i + 0) * _total_dofs + _j_global] +=
119 factor * _dFdc[_qp][j](0);
120 _force_torque_c_jacobian_store[(6 * i + 1) * _total_dofs + _j_global] +=
121 factor * _dFdc[_qp][j](1);
122 _force_torque_c_jacobian_store[(6 * i + 2) * _total_dofs + _j_global] +=
123 factor * _dFdc[_qp][j](2);
124 _force_torque_c_jacobian_store[(6 * i + 3) * _total_dofs + _j_global] +=
125 compute_torque_jacobian_c(0);
126 _force_torque_c_jacobian_store[(6 * i + 4) * _total_dofs + _j_global] +=
127 compute_torque_jacobian_c(1);
128 _force_torque_c_jacobian_store[(6 * i + 5) * _total_dofs + _j_global] +=
129 compute_torque_jacobian_c(2);
130 }
131 }
132
133 for (unsigned int i = 0; i < _op_num; ++i)
134 if (jvar == _vals_var[i])
135 for (unsigned int j = 0; j < _grain_num; ++j)
136 for (unsigned int k = 0; k < _op_num; ++k)
137 if (j == op_to_grains[k])
138 {
139 const auto centroid = _grain_tracker.getGrainCentroid(j);
140 for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
141 if ((*_dFdeta[i])[_qp][j](0) != 0.0 || (*_dFdeta[i])[_qp][j](1) != 0.0 ||
142 (*_dFdeta[i])[_qp][j](2) != 0.0)
143 {
144 const Real factor = _JxW[_qp] * _coord[_qp] * _phi[_j][_qp];
145 const RealGradient compute_torque_jacobian_eta =
146 factor *
147 (_current_elem->vertex_average() - centroid).cross((*_dFdeta[i])[_qp][k]);
148 _force_torque_eta_jacobian_store[i][(6 * j + 0) * _total_dofs + _j_global] +=
149 factor * (*_dFdeta[i])[_qp][k](0);
150 _force_torque_eta_jacobian_store[i][(6 * j + 1) * _total_dofs + _j_global] +=
151 factor * (*_dFdeta[i])[_qp][k](1);
152 _force_torque_eta_jacobian_store[i][(6 * j + 2) * _total_dofs + _j_global] +=
153 factor * (*_dFdeta[i])[_qp][k](2);
154 _force_torque_eta_jacobian_store[i][(6 * j + 3) * _total_dofs + _j_global] +=
155 compute_torque_jacobian_eta(0);
156 _force_torque_eta_jacobian_store[i][(6 * j + 4) * _total_dofs + _j_global] +=
157 compute_torque_jacobian_eta(1);
158 _force_torque_eta_jacobian_store[i][(6 * j + 5) * _total_dofs + _j_global] +=
159 compute_torque_jacobian_eta(2);
160 }
161 }
162}
163
164void
166{
167 gatherSum(_force_torque_store);
168 for (unsigned int i = 0; i < _grain_num; ++i)
169 {
170 _force_values[i](0) = _force_torque_store[6 * i + 0];
171 _force_values[i](1) = _force_torque_store[6 * i + 1];
172 _force_values[i](2) = _force_torque_store[6 * i + 2];
173 _torque_values[i](0) = _force_torque_store[6 * i + 3];
174 _torque_values[i](1) = _force_torque_store[6 * i + 4];
175 _torque_values[i](2) = _force_torque_store[6 * i + 5];
176 }
177
178 if (_fe_problem.currentlyComputingJacobian())
179 {
181 for (unsigned int i = 0; i < _op_num; ++i)
183 }
184}
185
186void
188{
189 const auto & pps = static_cast<const ComputeExternalGrainForceAndTorque &>(y);
190 for (unsigned int i = 0; i < _ncomp; ++i)
192 if (_fe_problem.currentlyComputingJacobian())
193 {
194 for (unsigned int i = 0; i < _ncomp * _total_dofs; ++i)
195 _force_torque_c_jacobian_store[i] += pps._force_torque_c_jacobian_store[i];
196 for (unsigned int i = 0; i < _op_num; ++i)
197 for (unsigned int j = 0; j < _ncomp * _total_dofs; ++j)
198 _force_torque_eta_jacobian_store[i][j] += pps._force_torque_eta_jacobian_store[i][j];
199 }
200}
201
202const std::vector<RealGradient> &
207
208const std::vector<RealGradient> &
213
214const std::vector<Real> &
219const std::vector<std::vector<Real>> &
registerMooseObject("PhaseFieldApp", ComputeExternalGrainForceAndTorque)
const std::vector< double > y
This class is here to get the force and torque acting on a grain.
ComputeExternalGrainForceAndTorque(const InputParameters &parameters)
std::vector< const MaterialProperty< std::vector< RealGradient > > * > _dFdeta
const unsigned int _op_num
no. of order parameters
std::vector< std::vector< Real > > _force_torque_eta_jacobian_store
virtual const std::vector< RealGradient > & getForceValues() const
virtual const std::vector< RealGradient > & getTorqueValues() const
const MaterialProperty< std::vector< RealGradient > > & _dF
MaterialPropertyName _dF_name
material property that provides force density
virtual const std::vector< std::vector< Real > > & getForceEtaJacobians() const
const MaterialProperty< std::vector< RealGradient > > & _dFdc
material property that provides jacobian of force density with respect to c
std::vector< Real > _force_torque_c_jacobian_store
vector storing jacobian of grain force and torque values
std::vector< RealGradient > _force_values
providing grain forces, torques and their jacobians w. r. t c
std::vector< Real > _force_torque_store
vector storing grain force and torque values
const GrainTrackerInterface & _grain_tracker
provide UserObject for calculating grain volumes and centers
virtual const std::vector< Real > & getForceCJacobians() const
const MaterialPropertyName derivativePropertyNameFirst(const MaterialPropertyName &base, const SymbolName &c1) const
This class provides interface for extracting the forces and torques computed in other UserObjects.
This class defines the interface for the GrainTracking objects.
virtual std::size_t getTotalFeatureCount() const =0
Returns a number large enough to contain the largest ID for all grains in use.
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 Point getGrainCentroid(unsigned int grain_id) const =0
Returns the centroid for the given grain number.
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
void addCoupledVar(const std::string &name, const std::string &doc_string)
static InputParameters validParams()