https://mooseframework.inl.gov
HomogenizedTotalLagrangianStressDivergenceS.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 
11 
12 // MOOSE includes
13 #include "Function.h"
14 #include "MooseVariableScalar.h"
15 
17 
20 {
22  params.addClassDescription("Total Lagrangian stress equilibrium kernel with "
23  "homogenization constraint Jacobian terms");
24  params.renameCoupledVar(
25  "scalar_variable", "macro_var", "Optional scalar field with the macro gradient");
27  "constraint_types",
29  "Type of each constraint: strain, stress, or none. The types are specified in the "
30  "column-major order, and there must be 9 entries in total.");
31  params.addRequiredParam<std::vector<FunctionName>>(
32  "targets", "Functions giving the targets to hit for constraint types that are not none.");
33 
34  return params;
35 }
36 
38  const InputParameters & parameters)
40 {
41  // Constraint types
42  auto types = getParam<MultiMooseEnum>("constraint_types");
43  if (types.size() != Moose::dim * Moose::dim)
44  mooseError("Number of constraint types must equal dim * dim. ", types.size(), " are provided.");
45 
46  // Targets to hit
47  const std::vector<FunctionName> & fnames = getParam<std::vector<FunctionName>>("targets");
48 
49  // Prepare the constraint map
50  unsigned int fcount = 0;
51  for (const auto j : make_range(Moose::dim))
52  for (const auto i : make_range(Moose::dim))
53  {
54  const auto idx = i + Moose::dim * j;
55  const auto ctype = static_cast<HomogenizationS::ConstraintType>(types.get(idx));
57  {
58  const Function * const f = &getFunctionByName(fnames[fcount++]);
59  _cmap[{i, j}] = {ctype, f};
60  }
61  }
62 }
63 
64 void
66 {
67  std::vector<Real> scalar_residuals(_k_order);
68 
69  // only assemble scalar residual once; i.e. when handling the first displacement component
70  if (_alpha == 0)
71  {
72  for (_qp = 0; _qp < _qrule->n_points(); _qp++)
73  {
74  initScalarQpResidual();
75  Real dV = _JxW[_qp] * _coord[_qp];
76  _h = 0; // single index for residual vector; double indices for constraint tensor component
77  for (auto && [indices, constraint] : _cmap)
78  {
79  auto && [i, j] = indices;
80  auto && [ctype, ctarget] = constraint;
81 
83  {
85  scalar_residuals[_h++] += dV * (_pk1[_qp](i, j) - ctarget->value(_t, _q_point[_qp]));
87  scalar_residuals[_h++] +=
88  dV * (_F[_qp](i, j) - (Real(i == j) + ctarget->value(_t, _q_point[_qp])));
89  else
90  mooseError("Unknown constraint type in the integral!");
91  }
92  else
93  {
95  scalar_residuals[_h++] += dV * (_pk1[_qp](i, j) - ctarget->value(_t, _q_point[_qp]));
97  scalar_residuals[_h++] += dV * (0.5 * (_F[_qp](i, j) + _F[_qp](j, i)) -
98  (Real(i == j) + ctarget->value(_t, _q_point[_qp])));
99  else
100  mooseError("Unknown constraint type in the integral!");
101  }
102  }
103  }
104  }
105 
106  addResiduals(
107  _assembly, scalar_residuals, _kappa_var_ptr->dofIndices(), _kappa_var_ptr->scalingFactor());
108 }
109 
110 void
112 {
113  _local_ke.resize(_k_order, _k_order);
114 
115  // only assemble scalar residual once; i.e. when handling the first displacement component
116  if (_alpha == 0)
117  {
118  for (_qp = 0; _qp < _qrule->n_points(); _qp++)
119  {
120  initScalarQpJacobian(_kappa_var);
121  Real dV = _JxW[_qp] * _coord[_qp];
122 
123  _h = 0;
124  for (auto && [indices1, constraint1] : _cmap)
125  {
126  auto && [i, j] = indices1;
127  auto && ctype = constraint1.first;
128  _l = 0;
129  for (auto && indices2 : _cmap)
130  {
131  auto && [a, b] = indices2.first;
133  _local_ke(_h, _l++) += dV * (_dpk1[_qp](i, j, a, b));
134  else if (ctype == HomogenizationS::ConstraintType::Strain)
135  {
136  if (_large_kinematics)
137  _local_ke(_h, _l++) += dV * (Real(i == a && j == b));
138  else
139  _local_ke(_h, _l++) +=
140  dV * (0.5 * Real(i == a && j == b) + 0.5 * Real(i == b && j == a));
141  }
142  else
143  mooseError("Unknown constraint type in Jacobian calculator!");
144  }
145  _h++;
146  }
147  }
148  }
149 
150  addJacobian(_assembly,
151  _local_ke,
152  _kappa_var_ptr->dofIndices(),
153  _kappa_var_ptr->dofIndices(),
154  _kappa_var_ptr->scalingFactor());
155 }
156 
157 void
159  const unsigned int jvar_num)
160 {
161  const auto & jvar = getVariable(jvar_num);
162  // Get dofs and order of this variable; at least one will be _var
163  const auto jvar_size = jvar.phiSize();
164  _local_ke.resize(_k_order, jvar_size);
165 
166  for (_qp = 0; _qp < _qrule->n_points(); _qp++)
167  {
168  // single index for Jacobian column; double indices for constraint tensor component
169  unsigned int h = 0;
170  Real dV = _JxW[_qp] * _coord[_qp];
171  for (auto && [indices, constraint] : _cmap)
172  {
173  // copy constraint indices to protected variables to pass to Qp routine
174  _m = indices.first;
175  _n = indices.second;
176  _ctype = constraint.first;
177  initScalarQpOffDiagJacobian(jvar);
178  for (_j = 0; _j < jvar_size; _j++)
179  _local_ke(h, _j) += dV * computeScalarQpOffDiagJacobian(jvar_num);
180  h++;
181  }
182  }
183 
184  addJacobian(_assembly,
185  _local_ke,
186  _kappa_var_ptr->dofIndices(),
187  jvar.dofIndices(),
188  _kappa_var_ptr->scalingFactor());
189 }
190 
191 void
193  const unsigned int svar_num)
194 {
195 
196  // Get dofs and order of this scalar; at least one will be _kappa_var
197  const auto & svar = _sys.getScalarVariable(_tid, svar_num);
198  const unsigned int s_order = svar.order();
199  _local_ke.resize(_test.size(), s_order);
200 
201  for (_qp = 0; _qp < _qrule->n_points(); _qp++)
202  {
203  unsigned int l = 0;
204  Real dV = _JxW[_qp] * _coord[_qp];
205  for (auto && [indices, constraint] : _cmap)
206  {
207  // copy constraint indices to protected variables to pass to Qp routine
208  _m = indices.first;
209  _n = indices.second;
210  _ctype = constraint.first;
211  initScalarQpJacobian(svar_num);
212  for (_i = 0; _i < _test.size(); _i++)
213  {
214  _local_ke(_i, l) += dV * computeQpOffDiagJacobianScalar(svar_num);
215  }
216  l++;
217  }
218  }
219 
220  addJacobian(_assembly, _local_ke, _var.dofIndices(), svar.dofIndices(), _var.scalingFactor());
221 }
222 
223 Real
225 {
226  // Just in case, skip any other scalar variables
227  if (svar_num == _kappa_var)
228  return _dpk1[_qp].contractionKl(_m, _n, gradTest(_alpha));
229  else
230  return 0.;
231 }
232 
233 Real
235 {
236  // ONLY assemble the contribution from _alpha component, which is connected with _var
237  // The other components are handled by other kernel instances with other _alpha
238  if (jvar_num == _var.number())
239  {
241  return _dpk1[_qp].contractionIj(_m, _n, gradTrial(_alpha));
243  if (_large_kinematics)
244  return Real(_m == _alpha) * gradTrial(_alpha)(_m, _n);
245  else
246  return 0.5 * (Real(_m == _alpha) * gradTrial(_alpha)(_m, _n) +
247  Real(_n == _alpha) * gradTrial(_alpha)(_n, _m));
248  else
249  mooseError("Unknown constraint type in kernel calculation!");
250  }
251  else
252  return 0.;
253 }
static InputParameters validParams()
const unsigned int _alpha
Which component of the vector residual this kernel is responsible for.
const bool _large_kinematics
If true use large deformation kinematics.
void mooseError(Args &&... args)
static constexpr std::size_t dim
void renameCoupledVar(const std::string &old_name, const std::string &new_name, const std::string &new_docstring)
const MultiMooseEnum constraintType("strain stress none")
Moose constraint type, for input.
Enforce equilibrium with a total Lagrangian formulation.
void addRequiredParam(const std::string &name, const std::string &doc_string)
unsigned int _m
Used internally to iterate over each scalar component.
registerMooseObject("SolidMechanicsTestApp", HomogenizedTotalLagrangianStressDivergenceS)
HomogenizationS::ConstraintType _ctype
The constraint type; initialize with &#39;none&#39;.
virtual void computeScalarResidual() override
Method for computing the scalar part of residual for _kappa.
Real f(Real x)
Test function for Brents method.
HomogenizationS::ConstraintMap _cmap
Type of each constraint (stress or strain) for each component.
virtual void computeScalarOffDiagJacobian(const unsigned int jvar_num) override
Method for computing an off-diagonal jacobian component d-_kappa-residual / d-jvar.
virtual RankTwoTensor gradTest(unsigned int component) override
virtual Real computeQpOffDiagJacobianScalar(const unsigned int svar_num) override
Method for computing d-_var-residual / d-svar at quadrature points.
const MaterialProperty< RankTwoTensor > & _F
The actual (stabilized) deformation gradient.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
ConstraintType
Constraint type: stress/PK stress or strain/deformation gradient.
virtual void computeOffDiagJacobianScalarLocal(const unsigned int svar_num) override
Method for computing an off-diagonal jacobian component d-_var-residual / d-svar. ...
virtual void computeScalarJacobian() override
Method for computing the scalar variable part of Jacobian for d-_kappa-residual / d-_kappa...
IntRange< T > make_range(T beg, T end)
Total Lagrangian formulation with all homogenization terms (one disp_xyz field and macro_gradient sca...
void addClassDescription(const std::string &doc_string)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
virtual Real computeScalarQpOffDiagJacobian(const unsigned int jvar_num) override
Method for computing an off-diagonal jacobian component at quadrature points.
const MaterialProperty< RankFourTensor > & _dpk1
The derivative of the PK1 stress with respect to the deformation gradient.
const MaterialProperty< RankTwoTensor > & _pk1
The 1st Piola-Kirchhoff stress.
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)
virtual RankTwoTensor gradTrial(unsigned int component) override