Skip to content

Commit dd2ba0e

Browse files
committed
Add eigenstrain (#70)
1 parent 23f6fec commit dd2ba0e

File tree

4 files changed

+41
-7
lines changed

4 files changed

+41
-7
lines changed

include/tensor_computes/FFTMechanics.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class FFTMechanics : public TensorOperator<>
6565
const torch::Tensor * const _applied_macroscopic_strain;
6666

6767
const bool _verbose;
68+
const bool _accept_nonconverged;
6869

6970
using TensorOperatorBase::_dim;
7071
using TensorOperatorBase::_domain;

include/tensor_computes/HyperElasticIsotropic.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ class HyperElasticIsotropic : public TensorOperator<>
3131
const torch::Tensor _tI4s;
3232
const torch::Tensor _tII;
3333

34+
/// deformation gradient tensor
3435
const torch::Tensor & _tF;
36+
/// optional eigenstrain tensor
37+
const torch::Tensor * _pFstar;
38+
3539
const torch::Tensor & _tmu;
3640
const torch::Tensor & _tK;
3741
torch::Tensor & _tK4;

src/tensor_computes/FFTMechanics.C

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ FFTMechanics::validParams()
4242
"Applied macroscopic strain");
4343
params.addParam<TensorInputBufferName>("F", "F", "Deformation gradient tensor.");
4444
params.addParam<bool>("verbose", false, "Print non-linear residuals.");
45+
params.addParam<bool>("accept_nonconverged", false, "Accept a non-converged solution");
4546
return params;
4647
}
4748

@@ -69,7 +70,8 @@ FFTMechanics::FFTMechanics(const InputParameters & parameters)
6970
_applied_macroscopic_strain(isParamValid("applied_macroscopic_strain")
7071
? &getInputBuffer("applied_macroscopic_strain")
7172
: nullptr),
72-
_verbose(getParam<bool>("verbose"))
73+
_verbose(getParam<bool>("verbose")),
74+
_accept_nonconverged(getParam<bool>("accept_nonconverged"))
7375
{
7476
// Build projection tensor once
7577
const auto & q = _domain.getKGrid();
@@ -148,7 +150,7 @@ FFTMechanics::computeBuffer()
148150

149151
// print nonlinear residual to the screen
150152
if (_verbose)
151-
_console << "|R|=" << anorm << "\t|R/R0|=" << rnorm << '\n';
153+
_console << "|R|=" << anorm << "\t|R/R0|=" << rnorm << std::endl;
152154

153155
// check convergence
154156
if ((rnorm < _nl_rel_tol || anorm < _nl_abs_tol) && iiter > 0)
@@ -157,7 +159,17 @@ FFTMechanics::computeBuffer()
157159
iiter++;
158160

159161
if (iiter > _nl_max_its)
160-
paramError("nl_max_its",
161-
"Exceeded the maximum number of nonlinear iterations without converging.");
162+
{
163+
if (_accept_nonconverged)
164+
paramWarning(
165+
"nl_max_its", "Accepting non-converged solution |R|=", anorm, "\t|R/R0|=", rnorm);
166+
else
167+
paramError(
168+
"nl_max_its",
169+
"Exceeded the maximum number of nonlinear iterations without converging with |R|=",
170+
anorm,
171+
"\t|R/R0|=",
172+
rnorm);
173+
}
162174
}
163175
}

src/tensor_computes/HyperElasticIsotropic.C

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ HyperElasticIsotropic::validParams()
1717
InputParameters params = TensorOperator<>::validParams();
1818
params.addClassDescription("Hyperelastic isotropic constitutive model.");
1919
params.addRequiredParam<TensorInputBufferName>("F", "Deformation gradient tensor");
20+
params.addParam<TensorInputBufferName>("Fstar", "Optional eigenstrain tensor");
2021
params.addRequiredParam<TensorInputBufferName>("mu", "Deformation gradient tensor");
2122
params.addRequiredParam<TensorInputBufferName>("K", "Deformation gradient tensor");
2223
params.addParam<TensorOutputBufferName>("tangent_operator", "dstressdstrain", "Stiffness tensor");
@@ -32,6 +33,7 @@ HyperElasticIsotropic::HyperElasticIsotropic(const InputParameters & parameters)
3233
_tI4s((_tI4 + _tI4rt) / 2.0),
3334
_tII(MooseTensor::dyad22(_tI, _tI)),
3435
_tF(getInputBuffer("F")),
36+
_pFstar(isParamValid("Fstar") ? &getInputBuffer("Fstar") : nullptr),
3537
_tmu(getInputBuffer("mu")),
3638
_tK(getInputBuffer("K")),
3739
_tK4(getOutputBuffer("tangent_operator"))
@@ -43,10 +45,25 @@ HyperElasticIsotropic::computeBuffer()
4345
{
4446
using namespace MooseTensor;
4547

48+
const auto F_e = _pFstar ? dot22(_tF, torch::inverse(*_pFstar)) : _tF;
49+
50+
// Compute Green–Lagrange strain E = 0.5 (F_e^T * F_e - I)
51+
const auto E = 0.5 * (dot22(trans2(F_e), F_e) - _tI);
52+
53+
// Build material stiffness tensor
4654
const auto C4 = _tK.reshape(_domain.getValueShape({1, 1, 1, 1})) * _tII +
4755
2. * _tmu.reshape(_domain.getValueShape({1, 1, 1, 1})) * (_tI4s - 1. / 3. * _tII);
48-
const auto S = ddot42(C4, .5 * (dot22(trans2(_tF), _tF) - _tI));
4956

50-
_u = dot22(_tF, S);
51-
_tK4 = dot24(S, _tI4) + ddot44(ddot44(_tI4rt, dot42(dot24(_tF, C4), trans2(_tF))), _tI4rt);
57+
// Second Piola-Kirchhoff stress: S = C : E
58+
const auto S = ddot42(C4, E);
59+
60+
// First Piola-Kirchhoff stress: P = F_e * S
61+
_u = dot22(F_e, S);
62+
63+
_tK4 = dot24(S, _tI4) + ddot44(ddot44(_tI4rt, dot42(dot24(F_e, C4), trans2(F_e))), _tI4rt);
64+
65+
// Consistent tangent: K_ijkl = F^e_{im} C_{jlmn} F^e_{kn} + delta_{ik} S_{jl}
66+
// const auto K_geo = torch::einsum("...im,...jlmn,...kn->...ijkl", {F_e, C4, F_e});
67+
// const auto K_stress = torch::einsum("ik,jl,...jl->...ijkl", {_ti, _ti, S});
68+
// _tK4 = K_geo + K_stress;
5269
}

0 commit comments

Comments
 (0)