https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ComputeIncrementalBeamStrain.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#include "MooseMesh.h"
12#include "Assembly.h"
13#include "NonlinearSystem.h"
14#include "MooseVariable.h"
15#include "Function.h"
16
17#include "libmesh/quadrature.h"
18#include "libmesh/utility.h"
19
21
24{
26 params.addClassDescription("Compute a infinitesimal/large strain increment for the beam.");
28 "rotations", "The rotations appropriate for the simulation geometry and coordinate system");
30 "displacements",
31 "The displacements appropriate for the simulation geometry and coordinate system");
32 params.addRequiredParam<RealGradient>("y_orientation",
33 "Orientation of the y direction along "
34 "with Iyy is provided. This should be "
35 "perpendicular to the axis of the beam.");
37 "area",
38 "Cross-section area of the beam. Can be supplied as either a number or a variable name.");
39 params.addCoupledVar("Ay",
40 0.0,
41 "First moment of area of the beam about y axis. Can be supplied "
42 "as either a number or a variable name.");
43 params.addCoupledVar("Az",
44 0.0,
45 "First moment of area of the beam about z axis. Can be supplied "
46 "as either a number or a variable name.");
47 params.addCoupledVar("Ix",
48 "Second moment of area of the beam about x axis. Can be "
49 "supplied as either a number or a variable name. Defaults to Iy+Iz.");
50 params.addRequiredCoupledVar("Iy",
51 "Second moment of area of the beam about y axis. Can be "
52 "supplied as either a number or a variable name.");
53 params.addRequiredCoupledVar("Iz",
54 "Second moment of area of the beam about z axis. Can be "
55 "supplied as either a number or a variable name.");
56 params.addParam<bool>("large_strain", false, "Set to true if large strain are to be calculated.");
57 params.addParam<std::vector<MaterialPropertyName>>(
58 "eigenstrain_names",
59 {},
60 "List of beam eigenstrains to be applied in this strain calculation.");
61 params.addParam<FunctionName>(
62 "elasticity_prefactor",
63 "Optional function to use as a scalar prefactor on the elasticity vector for the beam.");
64 return params;
65}
66
68 : Material(parameters),
69 _has_Ix(isParamValid("Ix")),
70 _nrot(coupledComponents("rotations")),
71 _ndisp(coupledComponents("displacements")),
72 _rot_num(_nrot),
73 _disp_num(_ndisp),
74 _area(coupledValue("area")),
75 _Ay(coupledValue("Ay")),
76 _Az(coupledValue("Az")),
77 _Iy(coupledValue("Iy")),
78 _Iz(coupledValue("Iz")),
79 _Ix(_has_Ix ? coupledValue("Ix") : _zero),
80 _original_local_config(declareRestartableData<RankTwoTensor>("original_local_config")),
81 _original_length(declareProperty<Real>("original_length")),
82 _total_rotation(declareProperty<RankTwoTensor>("total_rotation")),
83 _total_disp_strain(declareProperty<RealVectorValue>("total_disp_strain")),
84 _total_rot_strain(declareProperty<RealVectorValue>("total_rot_strain")),
85 _total_disp_strain_old(getMaterialPropertyOld<RealVectorValue>("total_disp_strain")),
86 _total_rot_strain_old(getMaterialPropertyOld<RealVectorValue>("total_rot_strain")),
87 _mech_disp_strain_increment(declareProperty<RealVectorValue>("mech_disp_strain_increment")),
88 _mech_rot_strain_increment(declareProperty<RealVectorValue>("mech_rot_strain_increment")),
89 _material_stiffness(getMaterialPropertyByName<RealVectorValue>("material_stiffness")),
90 _K11(declareProperty<RankTwoTensor>("Jacobian_11")),
91 _K21_cross(declareProperty<RankTwoTensor>("Jacobian_12")),
92 _K21(declareProperty<RankTwoTensor>("Jacobian_21")),
93 _K22(declareProperty<RankTwoTensor>("Jacobian_22")),
94 _K22_cross(declareProperty<RankTwoTensor>("Jacobian_22_cross")),
95 _large_strain(getParam<bool>("large_strain")),
96 _eigenstrain_names(getParam<std::vector<MaterialPropertyName>>("eigenstrain_names")),
97 _disp_eigenstrain(_eigenstrain_names.size()),
98 _rot_eigenstrain(_eigenstrain_names.size()),
99 _disp_eigenstrain_old(_eigenstrain_names.size()),
100 _rot_eigenstrain_old(_eigenstrain_names.size()),
101 _nonlinear_sys(_fe_problem.getNonlinearSystemBase(/*nl_sys_num=*/0)),
102 _soln_disp_index_0(_ndisp),
103 _soln_disp_index_1(_ndisp),
104 _soln_rot_index_0(_ndisp),
105 _soln_rot_index_1(_ndisp),
106 _initial_rotation(declareProperty<RankTwoTensor>("initial_rotation")),
107 _effective_stiffness(declareProperty<Real>("effective_stiffness")),
108 _prefactor_function(isParamValid("elasticity_prefactor") ? &getFunction("elasticity_prefactor")
109 : nullptr)
110{
111 // Checking for consistency between length of the provided displacements and rotations vector
112 if (_ndisp != _nrot)
113 mooseError("ComputeIncrementalBeamStrain: The number of variables supplied in 'displacements' "
114 "and 'rotations' must match.");
115
116 // fetch coupled variables and gradients (as stateful properties if necessary)
117 for (unsigned int i = 0; i < _ndisp; ++i)
118 {
119 MooseVariable * disp_variable = getVar("displacements", i);
120 _disp_num[i] = disp_variable->number();
121
122 MooseVariable * rot_variable = getVar("rotations", i);
123 _rot_num[i] = rot_variable->number();
124 }
125
126 if (_large_strain && (_Ay[0] > 0.0 || _Ay[1] > 0.0 || _Az[0] > 0.0 || _Az[1] > 0.0))
127 mooseError("ComputeIncrementalBeamStrain: Large strain calculation does not currently "
128 "support asymmetric beam configurations with non-zero first or third moments of "
129 "area.");
130
131 for (unsigned int i = 0; i < _eigenstrain_names.size(); ++i)
132 {
133 _disp_eigenstrain[i] = &getMaterialProperty<RealVectorValue>("disp_" + _eigenstrain_names[i]);
134 _rot_eigenstrain[i] = &getMaterialProperty<RealVectorValue>("rot_" + _eigenstrain_names[i]);
136 &getMaterialPropertyOld<RealVectorValue>("disp_" + _eigenstrain_names[i]);
138 &getMaterialPropertyOld<RealVectorValue>("rot_" + _eigenstrain_names[i]);
139 }
140}
141
142void
144{
145 // compute initial orientation of the beam for calculating initial rotation matrix
146 const std::vector<RealGradient> * orientation =
148 .getFE(FEType().set_p_refinement(false), 1)
149 ->get_dxyzdxi();
150 RealGradient x_orientation = (*orientation)[0];
151 x_orientation /= x_orientation.norm();
152
153 RealGradient y_orientation = getParam<RealGradient>("y_orientation");
154 y_orientation /= y_orientation.norm();
155 Real sum = x_orientation(0) * y_orientation(0) + x_orientation(1) * y_orientation(1) +
156 x_orientation(2) * y_orientation(2);
157
158 if (std::abs(sum) > 1e-4)
159 mooseError("ComputeIncrementalBeamStrain: y_orientation should be perpendicular to "
160 "the axis of the beam.");
161
162 // Calculate z orientation as a cross product of the x and y orientations
163 RealGradient z_orientation;
164 z_orientation(0) = (x_orientation(1) * y_orientation(2) - x_orientation(2) * y_orientation(1));
165 z_orientation(1) = (x_orientation(2) * y_orientation(0) - x_orientation(0) * y_orientation(2));
166 z_orientation(2) = (x_orientation(0) * y_orientation(1) - x_orientation(1) * y_orientation(0));
167
168 // Rotation matrix from global to original beam local configuration
169 _original_local_config(0, 0) = x_orientation(0);
170 _original_local_config(0, 1) = x_orientation(1);
171 _original_local_config(0, 2) = x_orientation(2);
172 _original_local_config(1, 0) = y_orientation(0);
173 _original_local_config(1, 1) = y_orientation(1);
174 _original_local_config(1, 2) = y_orientation(2);
175 _original_local_config(2, 0) = z_orientation(0);
176 _original_local_config(2, 1) = z_orientation(1);
177 _original_local_config(2, 2) = z_orientation(2);
178
180
181 RealVectorValue temp;
182 _total_disp_strain[_qp] = temp;
183 _total_rot_strain[_qp] = temp;
184}
185
186void
188{
189 // fetch the two end nodes for current element
190 std::vector<const Node *> node;
191 for (unsigned int i = 0; i < 2; ++i)
192 node.push_back(_current_elem->node_ptr(i));
193
194 // calculate original length of a beam element
195 // Nodal positions do not change with time as undisplaced mesh is used by material classes by
196 // default
197 RealGradient dxyz;
198 for (unsigned int i = 0; i < _ndisp; ++i)
199 dxyz(i) = (*node[1])(i) - (*node[0])(i);
200
201 _original_length[0] = dxyz.norm();
202
203 // Fetch the solution for the two end nodes at time t
204 const NumericVector<Number> & sol = *_nonlinear_sys.currentSolution();
205 const NumericVector<Number> & sol_old = _nonlinear_sys.solutionOld();
206
207 for (unsigned int i = 0; i < _ndisp; ++i)
208 {
209 _soln_disp_index_0[i] = node[0]->dof_number(_nonlinear_sys.number(), _disp_num[i], 0);
210 _soln_disp_index_1[i] = node[1]->dof_number(_nonlinear_sys.number(), _disp_num[i], 0);
211 _soln_rot_index_0[i] = node[0]->dof_number(_nonlinear_sys.number(), _rot_num[i], 0);
212 _soln_rot_index_1[i] = node[1]->dof_number(_nonlinear_sys.number(), _rot_num[i], 0);
213
214 _disp0(i) = sol(_soln_disp_index_0[i]) - sol_old(_soln_disp_index_0[i]);
215 _disp1(i) = sol(_soln_disp_index_1[i]) - sol_old(_soln_disp_index_1[i]);
216 _rot0(i) = sol(_soln_rot_index_0[i]) - sol_old(_soln_rot_index_0[i]);
217 _rot1(i) = sol(_soln_rot_index_1[i]) - sol_old(_soln_rot_index_1[i]);
218 }
219
220 // For small rotation problems, the rotation matrix is essentially the transformation from the
221 // global to original beam local configuration and is never updated. This method has to be
222 // overriden for scenarios with finite rotation
225
226 for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
228
231}
232
233void
235{
236 const Real A_avg = (_area[0] + _area[1]) / 2.0;
237 const Real Iz_avg = (_Iz[0] + _Iz[1]) / 2.0;
238 Real Ix = _Ix[_qp];
239 if (!_has_Ix)
240 Ix = _Iy[_qp] + _Iz[_qp];
241
242 // Rotate the gradient of displacements and rotations at t+delta t from global coordinate
243 // frame to beam local coordinate frame
244 const RealVectorValue grad_disp_0(1.0 / _original_length[0] * (_disp1 - _disp0));
245 const RealVectorValue grad_rot_0(1.0 / _original_length[0] * (_rot1 - _rot0));
246 const RealVectorValue avg_rot(
247 0.5 * (_rot0(0) + _rot1(0)), 0.5 * (_rot0(1) + _rot1(1)), 0.5 * (_rot0(2) + _rot1(2)));
248
249 _grad_disp_0_local_t = _total_rotation[0] * grad_disp_0;
250 _grad_rot_0_local_t = _total_rotation[0] * grad_rot_0;
251 _avg_rot_local_t = _total_rotation[0] * avg_rot;
252
253 // displacement at any location on beam in local coordinate system at t
254 // u_1 = u_n1 - rot_3 * y + rot_2 * z
255 // u_2 = u_n2 - rot_1 * z
256 // u_3 = u_n3 + rot_1 * y
257 // where u_n1, u_n2, u_n3 are displacements at neutral axis
258
259 // small strain
260 // e_11 = u_1,1 = u_n1, 1 - rot_3, 1 * y + rot_2, 1 * z
261 // e_12 = 2 * 0.5 * (u_1,2 + u_2,1) = (- rot_3 + u_n2,1 - rot_1,1 * z)
262 // e_13 = 2 * 0.5 * (u_1,3 + u_3,1) = (rot_2 + u_n3,1 + rot_1,1 * y)
263
264 // axial and shearing strains at each qp along the length of the beam
274
275 // rotational strains at each qp along the length of the beam
276 // rot_strain_1 = integral(e_13 * y - e_12 * z) dA
277 // rot_strain_2 = integral(e_11 * z) dA
278 // rot_strain_3 = integral(e_11 * -y) dA
279 // Iyz is the product moment of inertia which is zero for most cross-sections so it is assumed to
280 // be zero for this analysis
281 const Real Iyz = 0;
287 _grad_rot_0_local_t(2) * Iyz +
291 _grad_rot_0_local_t(1) * Iyz;
292
293 if (_large_strain)
294 {
296 0.5 *
297 ((Utility::pow<2>(_grad_disp_0_local_t(0)) + Utility::pow<2>(_grad_disp_0_local_t(1)) +
298 Utility::pow<2>(_grad_disp_0_local_t(2))) *
299 _area[_qp] +
300 Utility::pow<2>(_grad_rot_0_local_t(2)) * _Iy[_qp] +
301 Utility::pow<2>(_grad_rot_0_local_t(1)) * _Iz[_qp] +
302 Utility::pow<2>(_grad_rot_0_local_t(0)) * Ix);
305 _area[_qp];
308 _area[_qp];
309
314 _Iz[_qp];
317 _Iy[_qp];
318 }
319
324
325 // Convert eigenstrain increment from global to beam local coordinate system and remove eigen
326 // strain increment
327 for (unsigned int i = 0; i < _eigenstrain_names.size(); ++i)
328 {
331 _area[_qp];
334 }
335
336 Real c1_paper = std::sqrt(_material_stiffness[0](0));
337 Real c2_paper = std::sqrt(_material_stiffness[0](1));
338
339 Real effec_stiff_1 = std::max(c1_paper, c2_paper);
340
341 Real effec_stiff_2 = 2 / (c2_paper * std::sqrt(A_avg / Iz_avg));
342
343 _effective_stiffness[_qp] = std::max(effec_stiff_1, _original_length[0] / effec_stiff_2);
344
347}
348
349void
351{
352 const Real youngs_modulus = _material_stiffness[0](0);
353 const Real shear_modulus = _material_stiffness[0](1);
354
355 const Real A_avg = (_area[0] + _area[1]) / 2.0;
356 const Real Iy_avg = (_Iy[0] + _Iy[1]) / 2.0;
357 const Real Iz_avg = (_Iz[0] + _Iz[1]) / 2.0;
358 Real Ix_avg = (_Ix[0] + _Ix[1]) / 2.0;
359 if (!_has_Ix)
360 Ix_avg = Iy_avg + Iz_avg;
361
362 // K = |K11 K12|
363 // |K21 K22|
364
365 // relation between translational displacements at node 0 and translational forces at node 0
366 RankTwoTensor K11_local;
367 K11_local.zero();
368 K11_local(0, 0) = youngs_modulus * A_avg / _original_length[0];
369 K11_local(1, 1) = shear_modulus * A_avg / _original_length[0];
370 K11_local(2, 2) = shear_modulus * A_avg / _original_length[0];
371 _K11[0] = _total_rotation[0].transpose() * K11_local * _total_rotation[0];
372
373 // relation between displacements at node 0 and rotational moments at node 0
374 RankTwoTensor K21_local;
375 K21_local.zero();
376 K21_local(2, 1) = shear_modulus * A_avg * 0.5;
377 K21_local(1, 2) = -shear_modulus * A_avg * 0.5;
378 _K21[0] = _total_rotation[0].transpose() * K21_local * _total_rotation[0];
379
380 // relation between rotations at node 0 and rotational moments at node 0
381 RankTwoTensor K22_local;
382 K22_local.zero();
383 K22_local(0, 0) = shear_modulus * Ix_avg / _original_length[0];
384 K22_local(1, 1) = youngs_modulus * Iz_avg / _original_length[0] +
385 shear_modulus * A_avg * _original_length[0] / 4.0;
386 K22_local(2, 2) = youngs_modulus * Iy_avg / _original_length[0] +
387 shear_modulus * A_avg * _original_length[0] / 4.0;
388 _K22[0] = _total_rotation[0].transpose() * K22_local * _total_rotation[0];
389
390 // relation between rotations at node 0 and rotational moments at node 1
391 RankTwoTensor K22_local_cross = -K22_local;
392 K22_local_cross(1, 1) += 2.0 * shear_modulus * A_avg * _original_length[0] / 4.0;
393 K22_local_cross(2, 2) += 2.0 * shear_modulus * A_avg * _original_length[0] / 4.0;
394 _K22_cross[0] = _total_rotation[0].transpose() * K22_local_cross * _total_rotation[0];
395
396 // relation between displacements at node 0 and rotational moments at node 1
397 _K21_cross[0] = -_K21[0];
398
399 // stiffness matrix for large strain
400 if (_large_strain)
401 {
402 // k1_large is the stiffness matrix obtained from sigma_xx * d(epsilon_xx)
403 RankTwoTensor k1_large_11;
404 // row 1
405 k1_large_11(0, 0) = Utility::pow<2>(_grad_disp_0_local_t(0)) +
406 1.5 * Utility::pow<2>(_grad_rot_0_local_t(2)) * Iy_avg +
407 1.5 * Utility::pow<2>(_grad_rot_0_local_t(1)) * Iz_avg +
408 0.5 * Utility::pow<2>(_grad_disp_0_local_t(1)) +
409 0.5 * Utility::pow<2>(_grad_disp_0_local_t(2)) +
410 0.5 * Utility::pow<2>(_grad_rot_0_local_t(0)) * Ix_avg;
411 k1_large_11(1, 0) = 0.5 * _grad_disp_0_local_t(0) * _grad_disp_0_local_t(1) -
412 1.0 / 3.0 * _grad_rot_0_local_t(0) * _grad_rot_0_local_t(1) * Iz_avg;
413 k1_large_11(2, 0) = 0.5 * _grad_disp_0_local_t(0) * _grad_disp_0_local_t(2) -
414 1.0 / 3.0 * _grad_rot_0_local_t(0) * _grad_rot_0_local_t(2) * Iy_avg;
415
416 // row 2
417 k1_large_11(0, 1) = k1_large_11(1, 0);
418 k1_large_11(1, 1) = Utility::pow<2>(_grad_disp_0_local_t(1)) +
419 1.5 * Utility::pow<2>(_grad_rot_0_local_t(0)) * Iz_avg +
420 0.5 * Utility::pow<2>(_grad_disp_0_local_t(0)) +
421 0.5 * Utility::pow<2>(_grad_disp_0_local_t(2)) +
422 0.5 * Utility::pow<2>(_grad_rot_0_local_t(2)) * Iy_avg +
423 0.5 * Utility::pow<2>(_grad_rot_0_local_t(1)) * Iz_avg +
424 0.5 * Utility::pow<2>(_grad_rot_0_local_t(0)) * Iy_avg;
425 k1_large_11(2, 1) = 0.5 * _grad_disp_0_local_t(1) * _grad_disp_0_local_t(2);
426
427 // row 3
428 k1_large_11(0, 2) = k1_large_11(2, 0);
429 k1_large_11(1, 2) = k1_large_11(2, 1);
430 k1_large_11(2, 2) = Utility::pow<2>(_grad_disp_0_local_t(2)) +
431 1.5 * Utility::pow<2>(_grad_rot_0_local_t(0)) * Iy_avg +
432 0.5 * Utility::pow<2>(_grad_disp_0_local_t(0)) +
433 0.5 * Utility::pow<2>(_grad_disp_0_local_t(1)) +
434 0.5 * Utility::pow<2>(_grad_rot_0_local_t(0)) * Iz_avg +
435 0.5 * Utility::pow<2>(_grad_rot_0_local_t(2)) * Iy_avg +
436 0.5 * Utility::pow<2>(_grad_rot_0_local_t(2)) * Iz_avg;
437
438 k1_large_11 *= 1.0 / 4.0 / Utility::pow<2>(_original_length[0]);
439
440 RankTwoTensor k1_large_21;
441 // row 1
442 k1_large_21(0, 0) = 0.5 * _grad_disp_0_local_t(0) * _grad_rot_0_local_t(0) * (Ix_avg)-1.0 /
443 3.0 * _grad_disp_0_local_t(1) * _grad_rot_0_local_t(1) * Iz_avg -
444 1.0 / 3.0 * _grad_disp_0_local_t(2) * _grad_rot_0_local_t(2);
445 k1_large_21(1, 0) = 1.5 * _grad_disp_0_local_t(0) * _grad_rot_0_local_t(1) * Iz_avg -
446 1.0 / 3.0 * _grad_disp_0_local_t(1) * _grad_rot_0_local_t(0) * Iz_avg;
447 k1_large_21(2, 0) = 1.5 * _grad_disp_0_local_t(0) * _grad_rot_0_local_t(2) * Iy_avg -
448 1.0 / 3.0 * _grad_disp_0_local_t(2) * _grad_rot_0_local_t(0) * Iy_avg;
449
450 // row 2
451 k1_large_21(0, 1) = k1_large_21(1, 0);
452 k1_large_21(1, 1) = 0.5 * _grad_disp_0_local_t(1) * _grad_rot_0_local_t(1) * Iz_avg -
453 1.0 / 3.0 * _grad_disp_0_local_t(0) * _grad_rot_0_local_t(0) * Iz_avg;
454 k1_large_21(2, 1) = 0.5 * _grad_disp_0_local_t(1) * _grad_rot_0_local_t(2) * Iy_avg;
455
456 // row 3
457 k1_large_21(0, 2) = k1_large_21(2, 0);
458 k1_large_21(1, 2) = k1_large_21(2, 1);
459 k1_large_21(2, 2) = 0.5 * _grad_disp_0_local_t(2) * _grad_rot_0_local_t(2) * Iy_avg -
460 1.0 / 3.0 * _grad_disp_0_local_t(0) * _grad_rot_0_local_t(0) * Iy_avg;
461 k1_large_21 *= 1.0 / 4.0 / Utility::pow<2>(_original_length[0]);
462
463 RankTwoTensor k1_large_22;
464 // row 1
465 k1_large_22(0, 0) = Utility::pow<2>(_grad_rot_0_local_t(0)) * Utility::pow<2>(Ix_avg) +
466 1.5 * Utility::pow<2>(_grad_disp_0_local_t(1)) * Iz_avg +
467 1.5 * Utility::pow<2>(_grad_disp_0_local_t(2)) * Iy_avg +
468 0.5 * Utility::pow<2>(_grad_disp_0_local_t(0)) * Ix_avg +
469 0.5 * Utility::pow<2>(_grad_disp_0_local_t(2)) * Iz_avg +
470 0.5 * Utility::pow<2>(_grad_disp_0_local_t(1)) * Iy_avg +
471 0.5 * Utility::pow<2>(_grad_rot_0_local_t(2)) * Iy_avg * Ix_avg +
472 0.5 * Utility::pow<2>(_grad_rot_0_local_t(1)) * Iz_avg * Ix_avg;
473 k1_large_22(1, 0) = 0.5 * _grad_rot_0_local_t(0) * _grad_rot_0_local_t(1) * Iz_avg * Ix_avg -
474 1.0 / 3.0 * _grad_disp_0_local_t(0) * _grad_disp_0_local_t(1) * Iz_avg;
475 k1_large_22(2, 0) = 0.5 * _grad_rot_0_local_t(0) * _grad_rot_0_local_t(2) * Iy_avg * Ix_avg -
476 1.0 / 3.0 * _grad_disp_0_local_t(0) * _grad_disp_0_local_t(2) * Iy_avg;
477
478 // row 2
479 k1_large_22(0, 1) = k1_large_22(1, 0);
480 k1_large_22(1, 1) = Utility::pow<2>(_grad_rot_0_local_t(1)) * Iz_avg * Iz_avg +
481 1.5 * Utility::pow<2>(_grad_disp_0_local_t(0)) * Iz_avg +
482 1.5 * Utility::pow<2>(_grad_rot_0_local_t(2)) * Iy_avg * Iz_avg +
483 0.5 * Utility::pow<2>(_grad_disp_0_local_t(1)) * Iz_avg +
484 0.5 * Utility::pow<2>(_grad_disp_0_local_t(2)) * Iz_avg +
485 0.5 * Utility::pow<2>(_grad_rot_0_local_t(0)) * Iz_avg * Ix_avg;
486 k1_large_22(2, 1) = 1.5 * _grad_rot_0_local_t(1) * _grad_rot_0_local_t(2) * Iy_avg * Iz_avg;
487
488 // row 3
489 k1_large_22(0, 2) = k1_large_22(2, 0);
490 k1_large_22(1, 2) = k1_large_22(2, 1);
491 k1_large_22(2, 2) = Utility::pow<2>(_grad_rot_0_local_t(2)) * Iy_avg * Iy_avg +
492 1.5 * Utility::pow<2>(_grad_disp_0_local_t(0)) * Iy_avg +
493 1.5 * Utility::pow<2>(_grad_rot_0_local_t(1)) * Iy_avg * Iz_avg +
494 0.5 * Utility::pow<2>(_grad_disp_0_local_t(1)) * Iy_avg +
495 0.5 * Utility::pow<2>(_grad_disp_0_local_t(2)) * Iy_avg +
496 0.5 * Utility::pow<2>(_grad_rot_0_local_t(0)) * Iz_avg * Ix_avg;
497
498 k1_large_22 *= 1.0 / 4.0 / Utility::pow<2>(_original_length[0]);
499
500 // k2_large and k3_large are contributions from tau_xy * d(gamma_xy) and tau_xz * d(gamma_xz)
501 // k2_large for node 1 is negative of that for node 0
502 RankTwoTensor k2_large_11;
503 // col 1
504 k2_large_11(0, 0) =
505 0.25 * Utility::pow<2>(_avg_rot_local_t(2)) + 0.25 * Utility::pow<2>(_avg_rot_local_t(1));
506 k2_large_11(1, 0) = -1.0 / 6.0 * _avg_rot_local_t(0) * _avg_rot_local_t(1);
507 k2_large_11(2, 0) = -1.0 / 6.0 * _avg_rot_local_t(0) * _avg_rot_local_t(2);
508
509 // col 2
510 k2_large_11(0, 1) = k2_large_11(1, 0);
511 k2_large_11(1, 1) = 0.25 * _avg_rot_local_t(0);
512
513 // col 3
514 k2_large_11(0, 2) = k2_large_11(2, 0);
515 k2_large_11(2, 2) = 0.25 * Utility::pow<2>(_avg_rot_local_t(0));
516
517 k2_large_11 *= 1.0 / 4.0 / Utility::pow<2>(_original_length[0]);
518
519 RankTwoTensor k2_large_22;
520 // col1
521 k2_large_22(0, 0) = 0.25 * Utility::pow<2>(_avg_rot_local_t(0)) * Ix_avg;
522 k2_large_22(1, 0) = 1.0 / 6.0 * _avg_rot_local_t(0) * _avg_rot_local_t(1) * Iz_avg;
523 k2_large_22(2, 0) = 1.0 / 6.0 * _avg_rot_local_t(0) * _avg_rot_local_t(2) * Iy_avg;
524
525 // col2
526 k2_large_22(0, 1) = k2_large_22(1, 0);
527 k2_large_22(1, 1) = 0.25 * Utility::pow<2>(_avg_rot_local_t(2)) * Iz_avg +
528 0.25 * Utility::pow<2>(_avg_rot_local_t(1)) * Iz_avg;
529
530 // col3
531 k2_large_22(0, 2) = k2_large_22(2, 0);
532 k2_large_22(2, 2) = 0.25 * Utility::pow<2>(_avg_rot_local_t(2)) * Iy_avg +
533 0.25 * Utility::pow<2>(_avg_rot_local_t(1)) * Iy_avg;
534
535 k2_large_22 *= 1.0 / 4.0 / Utility::pow<2>(_original_length[0]);
536
537 // k3_large for node 1 is same as that for node 0
538 RankTwoTensor k3_large_22;
539 // col1
540 k3_large_22(0, 0) = 0.25 * Utility::pow<2>(_grad_disp_0_local_t(2)) +
541 0.25 * _grad_rot_0_local_t(0) * Ix_avg +
542 0.25 * Utility::pow<2>(_grad_disp_0_local_t(1));
543 k3_large_22(1, 0) = -1.0 / 6.0 * _grad_disp_0_local_t(0) * _grad_disp_0_local_t(1) +
544 1.0 / 6.0 * _grad_rot_0_local_t(0) * _grad_rot_0_local_t(1) * Iz_avg;
545 k3_large_22(2, 0) = -1.0 / 6.0 * _grad_disp_0_local_t(0) * _grad_disp_0_local_t(2) +
546 1.0 / 6.0 * _grad_rot_0_local_t(0) * _grad_rot_0_local_t(2) * Iy_avg;
547
548 // col2
549 k3_large_22(0, 1) = k3_large_22(1, 0);
550 k3_large_22(2, 2) = 0.25 * Utility::pow<2>(_grad_disp_0_local_t(0)) +
551 0.25 * _grad_rot_0_local_t(2) * Iy_avg +
552 0.25 * _grad_rot_0_local_t(1) * Iz_avg;
553
554 // col3
555 k3_large_22(0, 2) = k3_large_22(2, 0);
556 k3_large_22(2, 2) = 0.25 * Utility::pow<2>(_grad_disp_0_local_t(0)) +
557 0.25 * _grad_rot_0_local_t(2) * Iy_avg +
558 0.25 * _grad_rot_0_local_t(1) * Iz_avg;
559
560 k3_large_22 *= 1.0 / 16.0;
561
562 RankTwoTensor k3_large_21;
563 // col1
564 k3_large_21(0, 0) = -1.0 / 6.0 *
567 k3_large_21(1, 0) = 0.25 * _grad_disp_0_local_t(0) * _avg_rot_local_t(1) -
568 1.0 / 6.0 * _grad_disp_0_local_t(1) * _avg_rot_local_t(0);
569 k3_large_21(2, 0) = 0.25 * _grad_disp_0_local_t(0) * _avg_rot_local_t(2) -
570 1.0 / 6.0 * _grad_disp_0_local_t(2) * _avg_rot_local_t(0);
571
572 // col2
573 k3_large_21(0, 1) = 0.25 * _grad_disp_0_local_t(1) * _avg_rot_local_t(0) -
574 1.0 / 6.0 * _grad_disp_0_local_t(0) * _avg_rot_local_t(1);
575 k3_large_21(1, 1) = -1.0 / 6.0 * _grad_disp_0_local_t(0) * _avg_rot_local_t(0);
576
577 // col3
578 k3_large_21(0, 2) = 0.25 * _grad_disp_0_local_t(2) * _avg_rot_local_t(0) -
579 1.0 / 6.0 * _grad_disp_0_local_t(0) * _avg_rot_local_t(2);
580 k3_large_21(2, 2) = -1.0 / 6.0 * _grad_disp_0_local_t(0) * _avg_rot_local_t(0);
581
582 k3_large_21 *= 1.0 / 8.0 / _original_length[0];
583
584 RankTwoTensor k4_large_22;
585 // col 1
586 k4_large_22(0, 0) = 0.25 * _grad_rot_0_local_t(0) * _avg_rot_local_t(0) * Ix_avg +
587 1.0 / 6.0 * _grad_rot_0_local_t(2) * _avg_rot_local_t(2) * Iy_avg +
588 1.0 / 6.0 * _grad_rot_0_local_t(1) * _avg_rot_local_t(1) * Iz_avg;
589 k4_large_22(1, 0) = 1.0 / 6.0 * _grad_rot_0_local_t(1) * _avg_rot_local_t(0) * Iz_avg;
590 k4_large_22(2, 0) = 1.0 / 6.0 * _grad_rot_0_local_t(2) * _avg_rot_local_t(0) * Iy_avg;
591
592 // col2
593 k4_large_22(0, 1) = 1.0 / 6.0 * _grad_rot_0_local_t(0) * _avg_rot_local_t(1) * Iz_avg;
594 k4_large_22(1, 1) = 0.25 * _grad_rot_0_local_t(1) * _avg_rot_local_t(1) * Iz_avg +
595 1.0 / 6.0 * _grad_rot_0_local_t(0) * _avg_rot_local_t(0) * Iz_avg;
596 k4_large_22(2, 1) = 0.25 * _grad_rot_0_local_t(1) * _avg_rot_local_t(2) * Iz_avg;
597
598 // col 3
599 k4_large_22(0, 2) = 1.0 / 6.0 * _grad_rot_0_local_t(0) * _avg_rot_local_t(2) * Iy_avg;
600 k4_large_22(1, 2) = 0.25 * _grad_rot_0_local_t(2) * _avg_rot_local_t(1) * Iy_avg;
601 k4_large_22(2, 2) = 0.25 * _grad_rot_0_local_t(2) * _avg_rot_local_t(2) * Iy_avg +
602 1.0 / 6.0 * _grad_rot_0_local_t(0) * _avg_rot_local_t(0) * Iy_avg;
603
604 k3_large_22 += 1.0 / 8.0 / _original_length[0] * (k4_large_22 + k4_large_22.transpose());
605
606 // Assembling final matrix
607 _K11[0] += _total_rotation[0].transpose() * (k1_large_11 + k2_large_11) * _total_rotation[0];
608 _K22[0] += _total_rotation[0].transpose() * (k1_large_22 + k2_large_22 + k3_large_22) *
610 _K21[0] += _total_rotation[0].transpose() * (k1_large_21 + k3_large_21) * _total_rotation[0];
611 _K21_cross[0] +=
612 _total_rotation[0].transpose() * (-k1_large_21 + k3_large_21) * _total_rotation[0];
613 _K22_cross[0] += _total_rotation[0].transpose() * (-k1_large_22 - k2_large_22 + k3_large_22) *
615 }
616}
617
618void
registerMooseObject("SolidMechanicsApp", ComputeIncrementalBeamStrain)
const FEBase *const & getFE(FEType type, unsigned int dim) const
ComputeIncrementalBeamStrain defines a displacement and rotation strain increment and rotation increm...
MaterialProperty< RealVectorValue > & _mech_disp_strain_increment
Mechanical displacement strain increment (after removal of eigenstrains) integrated over the cross-se...
std::vector< const MaterialProperty< RealVectorValue > * > _rot_eigenstrain_old
Vector of old rotational eigenstrains.
MaterialProperty< RankTwoTensor > & _K11
Stiffness matrix between displacement DOFs of same node or across nodes.
const VariableValue & _Ix
Coupled variable for the second moment of area in x direction, i.e., integral of (y^2 + z^2)*dA over ...
MaterialProperty< RankTwoTensor > & _initial_rotation
Rotational transformation from global coordinate system to initial beam local configuration.
const VariableValue & _Az
Coupled variable for the first moment of area in z direction, i.e., integral of z*dA over the cross-s...
MaterialProperty< RealVectorValue > & _total_rot_strain
Current total rotational strain integrated over the cross-section in global coordinate system.
unsigned int _nrot
Number of coupled rotational variables.
virtual void initQpStatefulProperties() override
std::vector< unsigned int > _disp_num
Variable numbers corresponding to the displacement variables.
MaterialProperty< RealVectorValue > & _mech_rot_strain_increment
Mechanical rotation strain increment (after removal of eigenstrains) integrated over the cross-sectio...
std::vector< unsigned int > _soln_rot_index_0
Indices of solution vector corresponding to rotation DOFs at the node 0.
unsigned int _ndisp
Number of coupled displacement variables.
const VariableValue & _area
Coupled variable for the beam cross-sectional area.
MaterialProperty< RankTwoTensor > & _K22
Stiffness matrix between rotation DOFs of the same node.
RealVectorValue _disp0
Displacement and rotations at the two nodes of the beam in the global coordinate system.
std::vector< const MaterialProperty< RealVectorValue > * > _disp_eigenstrain_old
Vector of old displacement eigenstrains.
MaterialProperty< RankTwoTensor > & _K21
Stiffness matrix between displacement DOFs and rotation DOFs of the same node.
const Function *const _prefactor_function
Prefactor function to multiply the elasticity tensor with.
void computeStiffnessMatrix()
Computes the stiffness matrices.
std::vector< unsigned int > _soln_rot_index_1
Indices of solution vector corresponding to rotation DOFs at the node 1.
std::vector< MaterialPropertyName > _eigenstrain_names
Vector of beam eigenstrain names.
virtual void computeRotation()
Computes the rotation matrix at time t. For small rotation scenarios, the rotation matrix at time t i...
NonlinearSystemBase & _nonlinear_sys
Reference to the nonlinear system object.
RealVectorValue _avg_rot_local_t
Average rotation calculated in the beam local configuration at time t.
RankTwoTensor & _original_local_config
Rotational transformation from global coordinate system to initial beam local configuration.
std::vector< unsigned int > _soln_disp_index_1
Indices of solution vector corresponding to displacement DOFs at the node 1.
MaterialProperty< Real > & _effective_stiffness
Psuedo stiffness for critical time step computation.
const VariableValue & _Iz
Coupled variable for the second moment of area in z direction, i.e., integral of z^2*dA over the cros...
MaterialProperty< RankTwoTensor > & _K22_cross
Stiffness matrix between rotation DOFs of different nodes.
std::vector< const MaterialProperty< RealVectorValue > * > _rot_eigenstrain
Vector of current rotational eigenstrains.
const MaterialProperty< RealVectorValue > & _total_disp_strain_old
Old total displacement strain integrated over the cross-section in global coordinate system.
void computeQpStrain()
Computes the displacement and rotation strain increments.
const VariableValue & _Iy
Coupled variable for the second moment of area in y direction, i.e., integral of y^2*dA over the cros...
const bool _large_strain
Boolean flag to turn on large strain calculation.
const bool _has_Ix
Booleans for validity of params.
MaterialProperty< RealVectorValue > & _total_disp_strain
Current total displacement strain integrated over the cross-section in global coordinate system.
RealVectorValue _grad_rot_0_local_t
Gradient of rotation calculated in the beam local configuration at time t.
const MaterialProperty< RealVectorValue > & _material_stiffness
Material stiffness vector that relates displacement strain increments to force increments.
std::vector< const MaterialProperty< RealVectorValue > * > _disp_eigenstrain
Vector of current displacement eigenstrains.
MaterialProperty< Real > & _original_length
Initial length of the beam.
MaterialProperty< RankTwoTensor > & _K21_cross
Stiffness matrix between displacement DOFs of one node to rotational DOFs of another node.
const VariableValue & _Ay
Coupled variable for the first moment of area in y direction, i.e., integral of y*dA over the cross-s...
RealVectorValue _grad_disp_0_local_t
Gradient of displacement calculated in the beam local configuration at time t.
MaterialProperty< RankTwoTensor > & _total_rotation
Rotational transformation from global coordinate system to beam local configuration at time t.
std::vector< unsigned int > _soln_disp_index_0
Indices of solution vector corresponding to displacement DOFs at the node 0.
std::vector< unsigned int > _rot_num
Variable numbers corresponding to the rotational variables.
ComputeIncrementalBeamStrain(const InputParameters &parameters)
MooseVariable * getVar(const std::string &var_name, unsigned int comp)
virtual Real value(Real t, const Point &p) const
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
void addRequiredParam(const std::string &name, const std::string &doc_string)
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)
THREAD_ID _tid
unsigned int _qp
SubProblem & _subproblem
FEProblemBase & _fe_problem
static InputParameters validParams()
const Elem *const & _current_elem
const QBase *const & _qrule
const MooseArray< Point > & _q_point
void mooseError(Args &&... args) const
unsigned int number() const
RankTwoTensorTempl< T > transpose() const
virtual const NumericVector< Number > *const & currentSolution() const override final
const bool & currentlyComputingJacobian() const
virtual Assembly & assembly(const THREAD_ID tid, const unsigned int sys_num)=0
unsigned int number() const
NumericVector< Number > & solutionOld()
Real & _t