https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ComputeFiniteStrainNOSPD.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#include "libmesh/utility.h"
13
15
18{
19 return MooseEnum("TaylorExpansion EigenSolution", "TaylorExpansion");
20}
21
24{
27 "Class for computing nodal quantities for residual and jacobian calculation "
28 "for peridynamic correspondence models under finite strain assumptions");
29
30 params.addParam<MooseEnum>("decomposition_method",
32 "Methods to calculate the strain and rotation increments");
33
34 return params;
35}
36
38 : ComputeStrainBaseNOSPD(parameters),
39 _strain_rate(declareProperty<RankTwoTensor>("strain_rate")),
40 _strain_increment(declareProperty<RankTwoTensor>("strain_increment")),
41 _rotation_increment(declareProperty<RankTwoTensor>("rotation_increment")),
42 _deformation_gradient_old(getMaterialPropertyOld<RankTwoTensor>("deformation_gradient")),
43 _mechanical_strain_old(getMaterialPropertyOld<RankTwoTensor>("mechanical_strain")),
44 _total_strain_old(getMaterialPropertyOld<RankTwoTensor>("total_strain")),
45 _eigenstrains_old(_eigenstrain_names.size()),
46 _Fhat(2),
47 _decomposition_method(getParam<MooseEnum>("decomposition_method").getEnum<DecompMethod>())
48{
49 for (unsigned int i = 0; i < _eigenstrains_old.size(); ++i)
50 _eigenstrains_old[i] = &getMaterialPropertyOld<RankTwoTensor>(_eigenstrain_names[i]);
51}
52
53void
55{
57
59
60 RankTwoTensor total_strain_increment;
61
62 // Two ways to calculate these increments: TaylorExpansion(default) or EigenSolution
63 computeQpStrainRotationIncrements(total_strain_increment, _rotation_increment[_qp]);
64
65 _strain_increment[_qp] = total_strain_increment;
66
67 // Remove the eigenstrain increment
69
70 if (_dt > 0)
71 _strain_rate[_qp] = _strain_increment[_qp] / _dt;
72 else
73 _strain_rate[_qp].zero();
74
75 // Update strain in intermediate configuration
77 _total_strain[_qp] = _total_strain_old[_qp] + total_strain_increment;
78
79 // Rotate strain to current configuration
82 _total_strain[_qp] =
83 _rotation_increment[_qp] * _total_strain[_qp] * _rotation_increment[_qp].transpose();
84
85 // zero out all strain measures for broken bond
86 if (_bond_status_var->getElementalValue(_current_elem) < 0.5)
87 {
88 _strain_rate[_qp].zero();
89 _strain_increment[_qp].zero();
90 _rotation_increment[_qp].zero();
91 _mechanical_strain[_qp].zero();
92 _total_strain[_qp].zero();
93 }
94}
95
96void
98{
99 // Incremental deformation gradient of current step w.r.t previous step:
100 // _Fhat = deformation_gradient * inv(deformation_gradient_old)
101 _Fhat[_qp] = _deformation_gradient[_qp] * _deformation_gradient_old[_qp].inverse();
102}
103
104void
106 RankTwoTensor & rotation_increment)
107{
108 switch (_decomposition_method)
109 {
111 {
112 // inverse of _Fhat
113 RankTwoTensor invFhat(_Fhat[_qp].inverse());
114
115 // A = I - _Fhat^-1
117 A -= invFhat;
118
119 // Cinv - I = A A^T - A - A^T;
120 RankTwoTensor Cinv_I = A * A.transpose() - A - A.transpose();
121
122 // strain rate D from Taylor expansion, Chat = (-1/2(Chat^-1 - I) + 1/4*(Chat^-1 - I)^2 + ...
123 total_strain_increment = -Cinv_I * 0.5 + Cinv_I * Cinv_I * 0.25;
124
125 const Real a[3] = {invFhat(1, 2) - invFhat(2, 1),
126 invFhat(2, 0) - invFhat(0, 2),
127 invFhat(0, 1) - invFhat(1, 0)};
128
129 Real q = (a[0] * a[0] + a[1] * a[1] + a[2] * a[2]) / 4.0;
130 Real trFhatinv_1 = invFhat.trace() - 1.0;
131 const Real p = trFhatinv_1 * trFhatinv_1 / 4.0;
132
133 // cos theta_a
134 const Real C1_squared = p +
135 3.0 * Utility::pow<2>(p) * (1.0 - (p + q)) / Utility::pow<2>(p + q) -
136 2.0 * Utility::pow<3>(p) * (1.0 - (p + q)) / Utility::pow<3>(p + q);
137 if (C1_squared <= 0.0)
138 mooseException(
139 "Cannot take square root of a number less than or equal to zero in the calculation of "
140 "C1 for the Rashid approximation for the rotation tensor.");
141
142 const Real C1 = std::sqrt(C1_squared);
143
144 Real C2;
145 if (q > 0.01)
146 // (1-cos theta_a)/4q
147 C2 = (1.0 - C1) / (4.0 * q);
148 else
149 // alternate form for small q
150 C2 = 0.125 + q * 0.03125 * (Utility::pow<2>(p) - 12.0 * (p - 1.0)) / Utility::pow<2>(p) +
151 Utility::pow<2>(q) * (p - 2.0) * (Utility::pow<2>(p) - 10.0 * p + 32.0) /
152 Utility::pow<3>(p) +
153 Utility::pow<3>(q) *
154 (1104.0 - 992.0 * p + 376.0 * Utility::pow<2>(p) - 72.0 * Utility::pow<3>(p) +
155 5.0 * Utility::pow<4>(p)) /
156 (512.0 * Utility::pow<4>(p));
157
158 const Real C3_test =
159 (p * q * (3.0 - q) + Utility::pow<3>(p) + Utility::pow<2>(q)) / Utility::pow<3>(p + q);
160
161 if (C3_test <= 0.0)
162 mooseException(
163 "Cannot take square root of a number less than or equal to zero in the calculation of "
164 "C3_test for the Rashid approximation for the rotation tensor.");
165
166 const Real C3 = 0.5 * std::sqrt(C3_test); // sin theta_a/(2 sqrt(q))
167
168 // Calculate incremental rotation. Note that this value is the transpose of that from Rashid,
169 // 93, so we transpose it before storing
170 RankTwoTensor R_incr;
171 R_incr.addIa(C1);
172 for (unsigned int i = 0; i < 3; ++i)
173 for (unsigned int j = 0; j < 3; ++j)
174 R_incr(i, j) += C2 * a[i] * a[j];
175
176 R_incr(0, 1) += C3 * a[2];
177 R_incr(0, 2) -= C3 * a[1];
178 R_incr(1, 0) -= C3 * a[2];
179 R_incr(1, 2) += C3 * a[0];
180 R_incr(2, 0) += C3 * a[1];
181 R_incr(2, 1) -= C3 * a[0];
182
183 rotation_increment = R_incr.transpose();
184 break;
185 }
187 {
189 FactorizedRankTwoTensor Uhat = MathUtils::sqrt(Chat);
190 rotation_increment = _Fhat[_qp] * Uhat.inverse().get();
191 total_strain_increment = MathUtils::log(Uhat).get();
192 break;
193 }
194
195 default:
196 mooseError("ComputeFiniteStrainNOSPD Error: Invalid decomposition type! Please specify : "
197 "TaylorExpansion or "
198 "EigenSolution.");
199 }
200}
201
202void
204{
205 for (unsigned int i = 0; i < _eigenstrains.size(); ++i)
206 {
207 strain -= (*_eigenstrains[i])[_qp];
208 strain += (*_eigenstrains_old[i])[_qp];
209 }
210}
registerMooseObject("PeridynamicsApp", ComputeFiniteStrainNOSPD)
const Real p
void mooseError(Args &&... args)
Material class for peridynamic correspondence model for finite strain.
void subtractEigenstrainIncrementFromStrain(RankTwoTensor &strain)
Function to compute the mechanical strain tensor by subtracting thermal strain from the total strain.
MaterialProperty< RankTwoTensor > & _strain_increment
ComputeFiniteStrainNOSPD(const InputParameters &parameters)
DecompMethod
Method to decompose into rotation increment and strain increment.
void computeQpStrainRotationIncrements(RankTwoTensor &e, RankTwoTensor &r)
Function to compute strain and rotational increments.
MaterialProperty< RankTwoTensor > & _rotation_increment
const MaterialProperty< RankTwoTensor > & _total_strain_old
const MaterialProperty< RankTwoTensor > & _deformation_gradient_old
Material properties to fetch.
const DecompMethod _decomposition_method
const MaterialProperty< RankTwoTensor > & _mechanical_strain_old
std::vector< const MaterialProperty< RankTwoTensor > * > _eigenstrains_old
static InputParameters validParams()
std::vector< RankTwoTensor > _Fhat
'Incremental' deformation gradient
MaterialProperty< RankTwoTensor > & _strain_rate
Material properties to store.
virtual void computeQpStrain() override
Function to compute strain tensors.
Base material class for correspondence material model.
std::vector< const MaterialProperty< RankTwoTensor > * > _eigenstrains
MaterialProperty< RankTwoTensor > & _total_strain
static InputParameters validParams()
std::vector< MaterialPropertyName > _eigenstrain_names
virtual void computeQpDeformationGradient()
Function to compute deformation gradient for peridynamic correspondence model.
MaterialProperty< RankTwoTensor > & _mechanical_strain
MaterialProperty< RankTwoTensor > & _deformation_gradient
FactorizedRankTwoTensorTempl< T > inverse() const
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 addIa(const T &a)
RankTwoTensorTempl< T > transpose() const
static RankTwoTensorTempl< T > transposeTimes(const RankTwoTensorTempl< T > &)