www.mooseframework.org
ADComputeIncrementalShellStrain.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 #include "Assembly.h"
13 #include "NonlinearSystem.h"
14 #include "MooseVariable.h"
15 #include "ArbitraryQuadrature.h"
16 #include "DenseMatrix.h"
17 
18 #include "libmesh/quadrature.h"
19 #include "libmesh/utility.h"
20 #include "libmesh/enum_quadrature_type.h"
21 #include "libmesh/fe_type.h"
22 #include "libmesh/string_to_enum.h"
23 #include "libmesh/quadrature_gauss.h"
24 
26 
29  ADMaterial,
30  params.addClassDescription("Compute a small strain increment for the shell.");
31  params.addRequiredCoupledVar(
32  "rotations", "The rotations appropriate for the simulation geometry and coordinate system");
33  params.addRequiredCoupledVar(
34  "displacements",
35  "The displacements appropriate for the simulation geometry and coordinate system");
36  params.addRequiredCoupledVar(
37  "thickness",
38  "Thickness of the shell. Can be supplied as either a number or a variable name.");
39  params.addRequiredParam<std::string>("through_thickness_order",
40  "Quadrature order in out of plane direction");
41  params.addParam<bool>("large_strain",
42  false,
43  "Set to true to turn on finite strain calculations."););
44 
45 template <ComputeStage compute_stage>
47  const InputParameters & parameters)
48  : ADMaterial<compute_stage>(parameters),
49  _nrot(coupledComponents("rotations")),
50  _ndisp(coupledComponents("displacements")),
51  _rot_num(_nrot),
52  _disp_num(_ndisp),
53  _thickness(coupledValue("thickness")),
54  _large_strain(getParam<bool>("large_strain")),
55  _strain_increment(),
56  _total_strain(),
57  _total_strain_old(),
58  _nonlinear_sys(_fe_problem.getNonlinearSystemBase()),
59  _soln_disp_index(4),
60  _soln_rot_index(4),
61  _soln_vector(20, 1),
62  _strain_vector(5, 1),
63  _nodes(4),
64  _node_normal(declareADProperty<RealVectorValue>("node_normal")),
65  _node_normal_old(getMaterialPropertyOldByName<RealVectorValue>("node_normal")),
66  _dxyz_dxi(),
67  _dxyz_deta(),
68  _dxyz_dzeta(),
69  _dxyz_dxi_old(),
70  _dxyz_deta_old(),
71  _dxyz_dzeta_old(),
72  _v1(4),
73  _v2(4),
74  _B(),
75  _B_old(),
76  _ge(),
77  _ge_old(),
78  _J_map(),
79  _J_map_old(),
80  _rotation_matrix(),
81  _total_global_strain(),
82  _sol(_nonlinear_sys.currentSolution()),
83  _sol_old(_nonlinear_sys.solutionOld())
84 {
85  // Checking for consistency between length of the provided displacements and rotations vector
86  if (_ndisp != 3 || _nrot != 2)
87  mooseError(
88  "ADComputeIncrementalShellStrain: The number of variables supplied in 'displacements' "
89  "must be 3 and that in 'rotations' must be 2.");
90 
91  if (_mesh.hasSecondOrderElements())
92  mooseError(
93  "ADComputeIncrementalShellStrain: Shell element is implemented only for linear elements.");
94 
95  // fetch coupled variables and gradients (as stateful properties if necessary)
96  for (unsigned int i = 0; i < _ndisp; ++i)
97  {
98  MooseVariable * disp_variable = getVar("displacements", i);
99  _disp_num[i] = disp_variable->number();
100 
101  if (i < _nrot)
102  {
103  MooseVariable * rot_variable = getVar("rotations", i);
104  _rot_num[i] = rot_variable->number();
105  }
106  }
107 
108  _t_qrule = libmesh_make_unique<QGauss>(
109  1, Utility::string_to_enum<Order>(getParam<std::string>("through_thickness_order")));
110  _t_points = _t_qrule->get_points();
111  _strain_increment.resize(_t_points.size());
112  _total_strain.resize(_t_points.size());
113  _total_strain_old.resize(_t_points.size());
114  _B.resize(_t_points.size());
115  _B_old.resize(_t_points.size());
116  _ge.resize(_t_points.size());
117  _ge_old.resize(_t_points.size());
118  _J_map.resize(_t_points.size());
119  _J_map_old.resize(_t_points.size());
120  _dxyz_dxi.resize(_t_points.size());
121  _dxyz_deta.resize(_t_points.size());
122  _dxyz_dzeta.resize(_t_points.size());
123  _dxyz_dxi_old.resize(_t_points.size());
124  _dxyz_deta_old.resize(_t_points.size());
125  _dxyz_dzeta_old.resize(_t_points.size());
126  _rotation_matrix.resize(_t_points.size());
127  _total_global_strain.resize(_t_points.size());
128  for (unsigned int i = 0; i < _t_points.size(); ++i)
129  {
130  _strain_increment[i] =
131  &declareADProperty<RankTwoTensor>("strain_increment_t_points_" + std::to_string(i));
132  _total_strain[i] =
133  &declareADProperty<RankTwoTensor>("total_strain_t_points_" + std::to_string(i));
134  _total_strain_old[i] =
135  &getMaterialPropertyOldByName<RankTwoTensor>("total_strain_t_points_" + std::to_string(i));
136  _B[i] = &declareADProperty<DenseMatrix<Real>>("B_t_points_" + std::to_string(i));
137  _B_old[i] = &getMaterialPropertyOldByName<DenseMatrix<Real>>("B_t_points_" + std::to_string(i));
138  _ge[i] = &declareADProperty<RankTwoTensor>("ge_t_points_" + std::to_string(i));
139  _ge_old[i] = &getMaterialPropertyOldByName<RankTwoTensor>("ge_t_points_" + std::to_string(i));
140  _J_map[i] = &declareADProperty<Real>("J_mapping_t_points_" + std::to_string(i));
141  _J_map_old[i] = &getMaterialPropertyOldByName<Real>("J_mapping_t_points_" + std::to_string(i));
142  _dxyz_dxi[i] = &declareADProperty<RealVectorValue>("dxyz_dxi_t_points_" + std::to_string(i));
143  _dxyz_dxi_old[i] =
144  &getMaterialPropertyOldByName<RealVectorValue>("dxyz_dxi_t_points_" + std::to_string(i));
145  _dxyz_deta[i] = &declareADProperty<RealVectorValue>("dxyz_deta_t_points_" + std::to_string(i));
146  _dxyz_deta_old[i] =
147  &getMaterialPropertyOldByName<RealVectorValue>("dxyz_deta_t_points_" + std::to_string(i));
148  _dxyz_dzeta[i] =
149  &declareADProperty<RealVectorValue>("dxyz_dzeta_t_points_" + std::to_string(i));
150  _dxyz_dzeta_old[i] =
151  &getMaterialPropertyOldByName<RealVectorValue>("dxyz_dzeta_t_points_" + std::to_string(i));
152  // Create rotation matrix and total strain global for output purposes only
153  _rotation_matrix[i] = &declareProperty<RankTwoTensor>("rotation_t_points_" + std::to_string(i));
155  &declareProperty<RankTwoTensor>("total_global_strain_t_points_" + std::to_string(i));
156  }
157 
158  // used later for computing local coordinate system
159  _x2(1) = 1;
160  _x3(2) = 1;
161 }
162 
163 template <ComputeStage compute_stage>
164 void
166 {
167  unsigned int dim = _current_elem->dim();
168  if ((dim != 2))
169  mooseError(
170  "ADComputeIncrementalShellStrain: Shell element is implemented only for 2D elements");
171  if (_current_elem->n_nodes() != 4)
172  mooseError("ADComputeIncrementalShellStrain: Shell element needs to have exactly four nodes.");
173  computeGMatrix();
174  computeBMatrix();
175 }
176 
177 template <ComputeStage compute_stage>
178 void
180 {
181  // quadrature points in isoparametric space
182  _2d_points = _qrule->get_points(); // would be in 2D
183 
184  // derivatives of shape functions (dphidxi, dphideta and dphidzeta) evaluated at quadrature points
185  // (in isoparametric space).
186  unsigned int dim = _current_elem->dim();
187  FEType fe_type(Utility::string_to_enum<Order>("First"),
188  Utility::string_to_enum<FEFamily>("LAGRANGE"));
189  auto & fe = _fe_problem.assembly(_tid).getFE(fe_type, dim);
190  _dphidxi_map = fe->get_fe_map().get_dphidxi_map();
191  _dphideta_map = fe->get_fe_map().get_dphideta_map();
192  _phi_map = fe->get_fe_map().get_phi_map();
193 
194  for (unsigned int i = 0; i < 4; ++i)
195  _nodes[i] = _current_elem->node_ptr(i);
196 
197  for (unsigned int i = 0; i < _2d_points.size(); ++i)
198  {
199  for (unsigned int j = 0; j < _t_points.size(); ++j)
200  {
201  (*_ge[j])[i] = (*_ge_old[j])[i];
202  (*_J_map[j])[i] = (*_J_map_old[j])[i];
203  (*_dxyz_dxi[j])[i] = (*_dxyz_dxi_old[j])[i];
204  (*_dxyz_deta[j])[i] = (*_dxyz_deta_old[j])[i];
205  (*_dxyz_dzeta[j])[i] = (*_dxyz_dzeta_old[j])[i];
206  (*_B[j])[i] = (*_B_old[j])[i];
207  }
208  }
209 
210  computeSolnVector();
211 
212  computeNodeNormal();
213 
214  for (unsigned int i = 0; i < _2d_points.size(); ++i)
215  {
216  for (unsigned int j = 0; j < _t_points.size(); ++j)
217  {
218  // compute strain increment in covariant coordinate system using B and _soln_vector
219  for (unsigned int temp1 = 0; temp1 < 5; ++temp1)
220  {
221  _strain_vector(temp1) = 0.0;
222  for (unsigned int temp2 = 0; temp2 < 20; ++temp2)
223  _strain_vector(temp1) += (*_B[j])[i](temp1, temp2) * _soln_vector(temp2);
224  }
225  (*_strain_increment[j])[i](0, 0) = _strain_vector(0);
226  (*_strain_increment[j])[i](1, 1) = _strain_vector(1);
227  (*_strain_increment[j])[i](0, 1) = _strain_vector(2);
228  (*_strain_increment[j])[i](0, 2) = _strain_vector(3);
229  (*_strain_increment[j])[i](1, 2) = _strain_vector(4);
230  (*_strain_increment[j])[i](1, 0) = (*_strain_increment[j])[i](0, 1);
231  (*_strain_increment[j])[i](2, 0) = (*_strain_increment[j])[i](0, 2);
232  (*_strain_increment[j])[i](2, 1) = (*_strain_increment[j])[i](1, 2);
233 
234  (*_total_strain[j])[i] = (*_total_strain_old[j])[i] + (*_strain_increment[j])[i];
235 
236  for (unsigned int ii = 0; ii < 3; ++ii)
237  for (unsigned int jj = 0; jj < 3; ++jj)
238  _unrotated_total_strain(ii, jj) = MetaPhysicL::raw_value((*_total_strain[j])[i](ii, jj));
239  (*_total_global_strain[j])[i] = (*_rotation_matrix[j])[i].transpose() *
240  _unrotated_total_strain * (*_rotation_matrix[j])[i];
241  }
242  }
243  copyDualNumbersToValues();
244 }
245 
246 template <ComputeStage compute_stage>
247 void
249 {
250  // quadrature points in isoparametric space
251  _2d_points = _qrule->get_points(); // would be in 2D
252 
253  unsigned int dim = _current_elem->dim();
254 
255  // derivatives of shape functions (dphidxi, dphideta and dphidzeta) evaluated at quadrature points
256  // (in isoparametric space).
257  FEType fe_type(Utility::string_to_enum<Order>("First"),
258  Utility::string_to_enum<FEFamily>("LAGRANGE"));
259  auto & fe = _fe_problem.assembly(_tid).getFE(fe_type, dim);
260  _dphidxi_map = fe->get_fe_map().get_dphidxi_map();
261  _dphideta_map = fe->get_fe_map().get_dphideta_map();
262  _phi_map = fe->get_fe_map().get_phi_map();
263 
264  for (unsigned int i = 0; i < 4; ++i)
265  _nodes[i] = _current_elem->node_ptr(i);
266 
267  ADRealVectorValue x = (*_nodes[1] - *_nodes[0]);
268  ADRealVectorValue y = (*_nodes[3] - *_nodes[0]);
269  ADRealVectorValue normal = x.cross(y);
270  normal /= normal.norm();
271 
272  for (unsigned int k = 0; k < 4; ++k)
273  _node_normal[k] = normal;
274 
275  ADRankTwoTensor a;
276  ADDenseMatrix b(5, 20);
277  ADRealVectorValue c;
278  RankTwoTensor d;
279  for (unsigned int t = 0; t < _t_points.size(); ++t)
280  {
281  (*_strain_increment[t])[_qp] = a;
282  (*_total_strain[t])[_qp] = a;
283  (*_B[t])[_qp] = b;
284  (*_ge[t])[_qp] = a;
285  (*_J_map[t])[_qp] = 0;
286  (*_dxyz_dxi[t])[_qp] = c;
287  (*_dxyz_deta[t])[_qp] = c;
288  (*_dxyz_dzeta[t])[_qp] = c;
289  (*_rotation_matrix[t])[_qp] = d;
290  }
291 
292  // calculating derivatives of shape function in physical space (dphi/dx, dphi/dy, dphi/dz) at
293  // quadrature points these are g_{i} in Dvorkin's paper
294  for (unsigned int i = 0; i < _2d_points.size(); ++i)
295  {
296  for (unsigned int j = 0; j < _t_points.size(); ++j)
297  {
298  (*_dxyz_dxi[j])[i].zero();
299  for (unsigned int component = 0; component < 3; ++component)
300  {
301  (*_dxyz_dxi[j])[i](component) = 0.0;
302  (*_dxyz_deta[j])[i](component) = 0.0;
303  (*_dxyz_dzeta[j])[i](component) = 0.0;
304 
305  for (unsigned int k = 0; k < _nodes.size(); ++k)
306  {
307  (*_dxyz_dxi[j])[i](component) += _dphidxi_map[k][i] * ((*_nodes[k])(component)) +
308  _t_points[j](0) / 2.0 * _thickness[i] *
309  _dphidxi_map[k][i] * _node_normal[k](component);
310  (*_dxyz_deta[j])[i](component) += _dphideta_map[k][i] * ((*_nodes[k])(component)) +
311  _t_points[j](0) / 2.0 * _thickness[i] *
312  _dphideta_map[k][i] * _node_normal[k](component);
313  (*_dxyz_dzeta[j])[i](component) +=
314  _thickness[i] * _phi_map[k][i] * _node_normal[k](component) / 2.0;
315  }
316  }
317  }
318  }
319 
320  for (unsigned int i = 0; i < _2d_points.size(); ++i)
321  {
322  for (unsigned int j = 0; j < _t_points.size(); ++j)
323  {
324  // calculate gij for elasticity tensor
325  ADRankTwoTensor gmn;
326  RankTwoTensor J;
327  for (unsigned int component = 0; component < 3; ++component)
328  {
329  gmn(0, 0) += (*_dxyz_dxi[j])[i](component) * (*_dxyz_dxi[j])[i](component);
330  gmn(1, 1) += (*_dxyz_deta[j])[i](component) * (*_dxyz_deta[j])[i](component);
331  gmn(2, 2) += (*_dxyz_dzeta[j])[i](component) * (*_dxyz_dzeta[j])[i](component);
332  gmn(0, 1) += (*_dxyz_dxi[j])[i](component) * (*_dxyz_deta[j])[i](component);
333  gmn(0, 2) += (*_dxyz_dxi[j])[i](component) * (*_dxyz_dzeta[j])[i](component);
334  gmn(1, 2) += (*_dxyz_deta[j])[i](component) * (*_dxyz_dzeta[j])[i](component);
335 
336  J(0, component) = MetaPhysicL::raw_value((*_dxyz_dxi[j])[i](component));
337  J(1, component) = MetaPhysicL::raw_value((*_dxyz_deta[j])[i](component));
338  J(2, component) = MetaPhysicL::raw_value((*_dxyz_dzeta[j])[i](component));
339  }
340  gmn(1, 0) = gmn(0, 1);
341  gmn(2, 0) = gmn(0, 2);
342  gmn(2, 1) = gmn(1, 2);
343 
344  ADRankTwoTensor gmninv_temp = gmn.inverse();
345  (*_J_map[j])[i] = std::sqrt(gmn.det());
346  (*_rotation_matrix[j])[i] = J;
347 
348  // calculate ge
349  ADRealVectorValue e3 = (*_dxyz_dzeta[j])[i] / (*_dxyz_dzeta[j])[i].norm();
350  ADRealVectorValue e1 = (*_dxyz_deta[j])[i].cross(e3);
351  e1 /= e1.norm();
352  ADRealVectorValue e2 = e3.cross(e1);
353  e2 /= e2.norm();
354 
355  ADRankTwoTensor local_rotation_mat;
356  local_rotation_mat(0, 0) = e1(0);
357  local_rotation_mat(0, 1) = e1(1);
358  local_rotation_mat(0, 2) = e1(2);
359  local_rotation_mat(1, 0) = e2(0);
360  local_rotation_mat(1, 1) = e2(1);
361  local_rotation_mat(1, 2) = e2(2);
362  local_rotation_mat(2, 0) = e3(0);
363  local_rotation_mat(2, 1) = e3(1);
364  local_rotation_mat(2, 2) = e3(2);
365 
366  ADRankTwoTensor gmninv = local_rotation_mat.transpose() * gmninv_temp * local_rotation_mat;
367 
368  (*_ge[j])[i](0, 0) = (gmninv * (*_dxyz_dxi[j])[i]) * e1;
369  (*_ge[j])[i](0, 1) = (gmninv * (*_dxyz_dxi[j])[i]) * e2;
370  (*_ge[j])[i](0, 2) = (gmninv * (*_dxyz_dxi[j])[i]) * e3;
371  (*_ge[j])[i](1, 0) = (gmninv * (*_dxyz_deta[j])[i]) * e1;
372  (*_ge[j])[i](1, 1) = (gmninv * (*_dxyz_deta[j])[i]) * e2;
373  (*_ge[j])[i](1, 2) = (gmninv * (*_dxyz_deta[j])[i]) * e3;
374  (*_ge[j])[i](2, 0) = (gmninv * (*_dxyz_dzeta[j])[i]) * e1;
375  (*_ge[j])[i](2, 1) = (gmninv * (*_dxyz_dzeta[j])[i]) * e2;
376  (*_ge[j])[i](2, 2) = (gmninv * (*_dxyz_dzeta[j])[i]) * e3;
377  }
378  }
379 }
380 
381 template <ComputeStage compute_stage>
382 void
384 {
385  for (unsigned int k = 0; k < _nodes.size(); ++k)
386  _node_normal[k] = _node_normal_old[k];
387 }
388 
389 template <ComputeStage compute_stage>
390 void
392 {
393  // compute nodal local axis
394  for (unsigned int k = 0; k < _nodes.size(); ++k)
395  {
396  _v1[k] = _x2.cross(_node_normal[k]);
397  _v1[k] /= _x2.norm() * _node_normal[k].norm();
398 
399  // If x2 is parallel to node normal, set V1 to x3
400  if (MooseUtils::absoluteFuzzyEqual(_v1[k].norm(), 0.0, 1e-6))
401  _v1[k] = _x3;
402 
403  _v2[k] = _node_normal[k].cross(_v1[k]);
404  }
405 
406  // compute B matrix rows correspond to [ux1, ux2, ux3, ux4, uy1, uy2, uy3, uy4, uz1, uz2, uz3,
407  // uz4, a1, a2, a3, a4, b1, b2, b3, b4]
408  for (unsigned int i = 0; i < _2d_points.size(); ++i)
409  {
410  for (unsigned int j = 0; j < _t_points.size(); ++j)
411  {
412  (*_B[j])[i].resize(5, 20);
413  (*_B[j])[i].zero();
414  for (unsigned int k = 0; k < _nodes.size(); ++k)
415  {
416  // corresponding to strain(0,0)
417  (*_B[j])[i](0, k) += _dphidxi_map[k][i] * (*_dxyz_dxi[j])[i](0);
418  (*_B[j])[i](0, 4 + k) = _dphidxi_map[k][i] * (*_dxyz_dxi[j])[i](1);
419  (*_B[j])[i](0, 8 + k) = _dphidxi_map[k][i] * (*_dxyz_dxi[j])[i](2);
420  (*_B[j])[i](0, 12 + k) = _dphidxi_map[k][i] * _t_points[j](0) / 2.0 * _thickness[i] *
421  (-_v2[k] * (*_dxyz_dxi[j])[i]);
422  (*_B[j])[i](0, 16 + k) = _dphidxi_map[k][i] * _t_points[j](0) / 2.0 * _thickness[i] *
423  (_v1[k] * (*_dxyz_dxi[j])[i]);
424 
425  // corresponding to strain(1,1)
426  (*_B[j])[i](1, k) = _dphideta_map[k][i] * (*_dxyz_deta[j])[i](0);
427  (*_B[j])[i](1, 4 + k) = _dphideta_map[k][i] * (*_dxyz_deta[j])[i](1);
428  (*_B[j])[i](1, 8 + k) = _dphideta_map[k][i] * (*_dxyz_deta[j])[i](2);
429  (*_B[j])[i](1, 12 + k) = _dphideta_map[k][i] * _t_points[j](0) / 2.0 * _thickness[i] *
430  (-_v2[k] * (*_dxyz_deta[j])[i]);
431  (*_B[j])[i](1, 16 + k) = _dphideta_map[k][i] * _t_points[j](0) / 2.0 * _thickness[i] *
432  (_v1[k] * (*_dxyz_deta[j])[i]);
433 
434  // corresponding to strain(2,2) = 0
435 
436  // corresponding to strain(0,1)
437  (*_B[j])[i](2, k) = 0.5 * (_dphideta_map[k][i] * (*_dxyz_dxi[j])[i](0) +
438  _dphidxi_map[k][i] * (*_dxyz_deta[j])[i](0));
439  (*_B[j])[i](2, 4 + k) = 0.5 * (_dphideta_map[k][i] * (*_dxyz_dxi[j])[i](1) +
440  _dphidxi_map[k][i] * (*_dxyz_deta[j])[i](1));
441  (*_B[j])[i](2, 8 + k) = 0.5 * (_dphideta_map[k][i] * (*_dxyz_dxi[j])[i](2) +
442  _dphidxi_map[k][i] * (*_dxyz_deta[j])[i](2));
443  (*_B[j])[i](2, 12 + k) =
444  0.25 * _t_points[j](0) * _thickness[i] * -_v2[k] *
445  (_dphideta_map[k][i] * (*_dxyz_dxi[j])[i] + _dphidxi_map[k][i] * (*_dxyz_deta[j])[i]);
446  (*_B[j])[i](2, 16 + k) =
447  0.25 * _t_points[j](0) * _thickness[i] * _v1[k] *
448  ((*_dxyz_deta[j])[i] * _dphidxi_map[k][i] + (*_dxyz_dxi[j])[i] * _dphideta_map[k][i]);
449  }
450 
451  _g3_a = _thickness[i] / 4.0 * (_node_normal[2] + _node_normal[3]);
452  _g3_c = _thickness[i] / 4.0 * (_node_normal[0] + _node_normal[1]);
453  _g3_b = _thickness[i] / 4.0 * (_node_normal[0] + _node_normal[3]);
454  _g3_d = _thickness[i] / 4.0 * (_node_normal[1] + _node_normal[2]);
455 
456  _g1_a = 0.5 * ((*_nodes[2]) - (*_nodes[3])) +
457  _t_points[j](0) / 4.0 * _thickness[i] * (_node_normal[2] - _node_normal[3]);
458  _g1_c = 0.5 * ((*_nodes[1]) - (*_nodes[0])) +
459  _t_points[j](0) / 4.0 * _thickness[i] * (_node_normal[1] - _node_normal[0]);
460  _g2_b = 0.5 * ((*_nodes[3]) - (*_nodes[0])) +
461  _t_points[j](0) / 4.0 * _thickness[i] * (_node_normal[3] - _node_normal[0]);
462  _g2_d = 0.5 * ((*_nodes[2]) - (*_nodes[1])) +
463  _t_points[j](0) / 4.0 * _thickness[i] * (_node_normal[2] - _node_normal[1]);
464 
465  updateGVectors(); // for large strain problems
466 
467  // corresponding to strain(0,2)
468  for (unsigned int component = 0; component < 3; component++)
469  {
470  (*_B[j])[i](3, 2 + component * 4) = 0.125 * (1.0 + _2d_points[i](1)) * _g3_a(component);
471  (*_B[j])[i](3, 3 + component * 4) = 0.125 * (1.0 + _2d_points[i](1)) * -_g3_a(component);
472  (*_B[j])[i](3, 1 + component * 4) = 0.125 * (1.0 - _2d_points[i](1)) * _g3_c(component);
473  (*_B[j])[i](3, component * 4) = 0.125 * (1.0 - _2d_points[i](1)) * -_g3_c(component);
474  }
475  (*_B[j])[i](3, 14) = 0.125 * (1.0 + _2d_points[i](1)) * 0.5 * _thickness[i] * _g1_a * -_v2[2];
476  (*_B[j])[i](3, 18) = 0.125 * (1.0 + _2d_points[i](1)) * 0.5 * _thickness[i] * _g1_a * _v1[2];
477  (*_B[j])[i](3, 15) = 0.125 * (1.0 + _2d_points[i](1)) * 0.5 * _thickness[i] * _g1_a * -_v2[3];
478  (*_B[j])[i](3, 19) = 0.125 * (1.0 + _2d_points[i](1)) * 0.5 * _thickness[i] * _g1_a * _v1[3];
479 
480  (*_B[j])[i](3, 13) = 0.125 * (1.0 - _2d_points[i](1)) * 0.5 * _thickness[i] * _g1_c * -_v2[1];
481  (*_B[j])[i](3, 17) = 0.125 * (1.0 - _2d_points[i](1)) * 0.5 * _thickness[i] * _g1_c * _v1[1];
482  (*_B[j])[i](3, 12) = 0.125 * (1.0 - _2d_points[i](1)) * 0.5 * _thickness[i] * _g1_c * -_v2[0];
483  (*_B[j])[i](3, 16) = 0.125 * (1.0 - _2d_points[i](1)) * 0.5 * _thickness[i] * _g1_c * _v1[0];
484 
485  // corresponding to strain(1,2)
486  for (unsigned int component = 0; component < 3; component++)
487  {
488  (*_B[j])[i](4, 2 + component * 4) = 0.125 * (1.0 + _2d_points[i](0)) * _g3_d(component);
489  (*_B[j])[i](4, 1 + component * 4) = 0.125 * (1.0 + _2d_points[i](0)) * -_g3_d(component);
490  (*_B[j])[i](4, 3 + component * 4) = 0.125 * (1.0 - _2d_points[i](0)) * _g3_b(component);
491  (*_B[j])[i](4, component * 4) = 0.125 * (1.0 - _2d_points[i](0)) * -_g3_b(component);
492  }
493  (*_B[j])[i](4, 14) = 0.125 * (1.0 + _2d_points[i](0)) * 0.5 * _thickness[i] * _g2_d * -_v2[2];
494  (*_B[j])[i](4, 18) = 0.125 * (1.0 + _2d_points[i](0)) * 0.5 * _thickness[i] * _g2_d * _v1[2];
495  (*_B[j])[i](4, 13) = 0.125 * (1.0 + _2d_points[i](0)) * 0.5 * _thickness[i] * _g2_d * -_v2[1];
496  (*_B[j])[i](4, 17) = 0.125 * (1.0 + _2d_points[i](0)) * 0.5 * _thickness[i] * _g2_d * _v1[1];
497 
498  (*_B[j])[i](4, 15) = 0.125 * (1.0 - _2d_points[i](0)) * 0.5 * _thickness[i] * _g2_b * -_v2[3];
499  (*_B[j])[i](4, 19) = 0.125 * (1.0 - _2d_points[i](0)) * 0.5 * _thickness[i] * _g2_b * _v1[3];
500  (*_B[j])[i](4, 12) = 0.125 * (1.0 - _2d_points[i](0)) * 0.5 * _thickness[i] * _g2_b * -_v2[0];
501  (*_B[j])[i](4, 16) = 0.125 * (1.0 - _2d_points[i](0)) * 0.5 * _thickness[i] * _g2_b * _v1[0];
502  }
503  }
504 }
505 
506 template <>
507 void
509 {
510  _soln_vector.zero();
511 
512  for (unsigned int j = 0; j < 4; ++j)
513  {
514  _soln_disp_index[j].resize(_ndisp);
515  _soln_rot_index[j].resize(_nrot);
516 
517  for (unsigned int i = 0; i < _ndisp; ++i)
518  {
519  _soln_disp_index[j][i] = _nodes[j]->dof_number(_nonlinear_sys.number(), _disp_num[i], 0);
520  _soln_vector(j + i * _nodes.size()) =
521  (*_sol)(_soln_disp_index[j][i]) - _sol_old(_soln_disp_index[j][i]);
522  }
523 
524  for (unsigned int i = 0; i < _nrot; ++i)
525  {
526  _soln_rot_index[j][i] = _nodes[j]->dof_number(_nonlinear_sys.number(), _rot_num[i], 0);
527  _soln_vector(j + 12 + i * _nodes.size()) =
528  (*_sol)(_soln_rot_index[j][i]) - _sol_old(_soln_rot_index[j][i]);
529  }
530  }
531 }
532 
533 template <>
534 void
536 {
537  _soln_vector.zero();
538 
539  for (unsigned int j = 0; j < 4; ++j)
540  {
541  _soln_disp_index[j].resize(_ndisp);
542  _soln_rot_index[j].resize(_nrot);
543 
544  for (unsigned int i = 0; i < _ndisp; ++i)
545  {
546  size_t ad_offset = _disp_num[i] * _nonlinear_sys.getMaxVarNDofsPerElem();
547  _soln_disp_index[j][i] = _nodes[j]->dof_number(_nonlinear_sys.number(), _disp_num[i], 0);
548  _soln_vector(j + i * _nodes.size()) =
549  (*_sol)(_soln_disp_index[j][i]) - _sol_old(_soln_disp_index[j][i]);
550  Moose::derivInsert(_soln_vector(j + i * _nodes.size()).derivatives(), ad_offset + j, 1.);
551  }
552 
553  for (unsigned int i = 0; i < _nrot; ++i)
554  {
555  size_t ad_offset = _rot_num[i] * _nonlinear_sys.getMaxVarNDofsPerElem();
556  _soln_rot_index[j][i] = _nodes[j]->dof_number(_nonlinear_sys.number(), _rot_num[i], 0);
557  _soln_vector(j + 12 + i * _nodes.size()) =
558  (*_sol)(_soln_rot_index[j][i]) - _sol_old(_soln_rot_index[j][i]);
559  Moose::derivInsert(_soln_vector(j + 12 + i * _nodes.size()).derivatives(), ad_offset + j, 1.);
560  }
561  }
562 }
ADComputeIncrementalShellStrain::_t_qrule
std::unique_ptr< QGauss > _t_qrule
Quadrature rule in the out of plane direction.
Definition: ADComputeIncrementalShellStrain.h:150
ADComputeIncrementalShellStrain::initQpStatefulProperties
virtual void initQpStatefulProperties() override
Definition: ADComputeIncrementalShellStrain.C:165
ADComputeIncrementalShellStrain::_dxyz_dxi
std::vector< ADMaterialProperty(RealVectorValue) * > _dxyz_dxi
Derivative of global x, y and z w.r.t isoparametric coordinate xi.
Definition: ADComputeIncrementalShellStrain.h:168
ADComputeIncrementalShellStrain::computeSolnVector
virtual void computeSolnVector()
Computes the 20x1 soln vector and its derivatives for each shell element.
ADComputeIncrementalShellStrain::_disp_num
std::vector< unsigned int > _disp_num
Variable numbers corresponding to the displacement variables.
Definition: ADComputeIncrementalShellStrain.h:108
ADComputeIncrementalShellStrain::_total_strain
std::vector< ADMaterialProperty(RankTwoTensor) * > _total_strain
Total strain increment in the covariant coordinate system.
Definition: ADComputeIncrementalShellStrain.h:120
ADComputeIncrementalShellStrain::_ge_old
std::vector< const MaterialProperty< RankTwoTensor > * > _ge_old
Old ge matrix for elasticity tensor conversion.
Definition: ADComputeIncrementalShellStrain.h:201
ADComputeIncrementalShellStrain::_x3
ADRealVectorValue _x3
Definition: ADComputeIncrementalShellStrain.h:217
ADComputeIncrementalShellStrain::_dxyz_dxi_old
std::vector< const MaterialProperty< RealVectorValue > * > _dxyz_dxi_old
Old derivative of global x, y and z w.r.t isoparametric coordinate xi.
Definition: ADComputeIncrementalShellStrain.h:177
ADComputeIncrementalShellStrain::_dxyz_deta
std::vector< ADMaterialProperty(RealVectorValue) * > _dxyz_deta
Derivative of global x, y and z w.r.t isoparametric coordinate eta.
Definition: ADComputeIncrementalShellStrain.h:171
ADComputeIncrementalShellStrain::_J_map
std::vector< ADMaterialProperty(Real) * > _J_map
Material property containing jacobian of transformation.
Definition: ADComputeIncrementalShellStrain.h:204
registerADMooseObject
registerADMooseObject("TensorMechanicsApp", ADComputeIncrementalShellStrain)
defineADValidParams
defineADValidParams(ADComputeIncrementalShellStrain, ADMaterial, params.addClassDescription("Compute a small strain increment for the shell.");params.addRequiredCoupledVar("rotations", "The rotations appropriate for the simulation geometry and coordinate system");params.addRequiredCoupledVar("displacements", "The displacements appropriate for the simulation geometry and coordinate system");params.addRequiredCoupledVar("thickness", "Thickness of the shell. Can be supplied as either a number or a variable name.");params.addRequiredParam< std::string >("through_thickness_order", "Quadrature order in out of plane direction");params.addParam< bool >("large_strain", false, "Set to true to turn on finite strain calculations.");)
ADComputeIncrementalShellStrain::computeBMatrix
virtual void computeBMatrix()
Computes the B matrix that connects strains to nodal displacements and rotations.
Definition: ADComputeIncrementalShellStrain.C:391
ADComputeIncrementalShellStrain::_B
std::vector< ADMaterialProperty(DenseMatrix< Real >) * > _B
B_matrix for small strain.
Definition: ADComputeIncrementalShellStrain.h:192
ADComputeIncrementalShellStrain::_ndisp
unsigned int _ndisp
Number of coupled displacement variables.
Definition: ADComputeIncrementalShellStrain.h:102
ADComputeIncrementalShellStrain::computeGMatrix
virtual void computeGMatrix()
Computes the transformation matrix from natural coordinates to local cartesian coordinates for elasti...
Definition: ADComputeIncrementalShellStrain.C:248
MaterialTensorCalculatorTools::component
Real component(const SymmTensor &symm_tensor, unsigned int index)
Definition: MaterialTensorCalculatorTools.C:16
ADComputeIncrementalShellStrain::_ge
std::vector< ADMaterialProperty(RankTwoTensor) * > _ge
ge matrix for elasticity tensor conversion
Definition: ADComputeIncrementalShellStrain.h:198
ADComputeIncrementalShellStrain::_nrot
unsigned int _nrot
Number of coupled rotational variables.
Definition: ADComputeIncrementalShellStrain.h:99
ADComputeIncrementalShellStrain::_strain_increment
std::vector< ADMaterialProperty(RankTwoTensor) * > _strain_increment
Strain increment in the covariant coordinate system.
Definition: ADComputeIncrementalShellStrain.h:117
ADComputeIncrementalShellStrain::ADComputeIncrementalShellStrain
ADComputeIncrementalShellStrain(const InputParameters &parameters)
Definition: ADComputeIncrementalShellStrain.C:46
ADComputeIncrementalShellStrain::_dxyz_deta_old
std::vector< const MaterialProperty< RealVectorValue > * > _dxyz_deta_old
Old derivative of global x, y and z w.r.t isoparametric coordinate eta.
Definition: ADComputeIncrementalShellStrain.h:180
ADComputeIncrementalShellStrain::_rotation_matrix
std::vector< MaterialProperty< RankTwoTensor > * > _rotation_matrix
Rotation matrix material property.
Definition: ADComputeIncrementalShellStrain.h:210
ADComputeIncrementalShellStrain::_J_map_old
std::vector< const MaterialProperty< Real > * > _J_map_old
Old material property containing jacobian of transformation.
Definition: ADComputeIncrementalShellStrain.h:207
ADComputeIncrementalShellStrain::_x2
ADRealVectorValue _x2
simulation variables
Definition: ADComputeIncrementalShellStrain.h:216
ADComputeIncrementalShellStrain::_t_points
std::vector< Point > _t_points
Quadrature points in the out of plane direction in isoparametric coordinate system.
Definition: ADComputeIncrementalShellStrain.h:153
ADComputeIncrementalShellStrain::_dxyz_dzeta
std::vector< ADMaterialProperty(RealVectorValue) * > _dxyz_dzeta
Derivative of global x, y and z w.r.t isoparametric coordinate zeta.
Definition: ADComputeIncrementalShellStrain.h:174
ADComputeIncrementalShellStrain::_B_old
std::vector< const MaterialProperty< DenseMatrix< Real > > * > _B_old
Old B_matrix for small strain.
Definition: ADComputeIncrementalShellStrain.h:195
ADComputeIncrementalShellStrain::_dxyz_dzeta_old
std::vector< const MaterialProperty< RealVectorValue > * > _dxyz_dzeta_old
Old derivative of global x, y and z w.r.t isoparametric coordinate zeta.
Definition: ADComputeIncrementalShellStrain.h:183
ADComputeIncrementalShellStrain.h
ADComputeIncrementalShellStrain::_total_global_strain
std::vector< MaterialProperty< RankTwoTensor > * > _total_global_strain
Total strain in global coordinate system.
Definition: ADComputeIncrementalShellStrain.h:213
ADComputeIncrementalShellStrain::_rot_num
std::vector< unsigned int > _rot_num
Variable numbers corresponding to the rotational variables.
Definition: ADComputeIncrementalShellStrain.h:105
RankTwoTensorTempl< Real >
ADComputeIncrementalShellStrain::_total_strain_old
std::vector< const MaterialProperty< RankTwoTensor > * > _total_strain_old
Old total strain increment in the covariant coordinate system.
Definition: ADComputeIncrementalShellStrain.h:123
ADComputeIncrementalShellStrain::computeProperties
virtual void computeProperties() override
Definition: ADComputeIncrementalShellStrain.C:179
ADComputeIncrementalShellStrain::computeNodeNormal
virtual void computeNodeNormal()
Computes the node normal at each node.
Definition: ADComputeIncrementalShellStrain.C:383
ADComputeIncrementalShellStrain
Definition: ADComputeIncrementalShellStrain.h:56