https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ElasticityTensorTools.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
10#include "MooseTypes.h"
11#include "PermutationTensor.h"
12#include "RankFourTensor.h"
14
15#include "libmesh/vector_value.h"
16
18{
19
20Real
22 unsigned int i,
23 unsigned int k,
24 const RealGradient & grad_test,
25 const RealGradient & grad_phi)
26{
27 // d(stress_ij*d(test)/dx_j)/du_k = d(C_ijmn*du_m/dx_n dtest/dx_j)/du_k (which is nonzero for m ==
28 // k)
29
30 const Real gt0 = grad_test(0);
31 const Real gt1 = grad_test(1);
32 const Real gt2 = grad_test(2);
33 const Real gp0 = grad_phi(0);
34 const Real gp1 = grad_phi(1);
35 const Real gp2 = grad_phi(2);
36
37 // clang-format off
38 // This is the algorithm that is unrolled below:
39 //
40 // Real sum = 0.0;
41 // for (const auto j: make_range(Moose::dim))
42 // for (const auto l: make_range(Moose::dim))
43 // sum += r4t(i, j, k, l) * grad_phi(l) * grad_test(j);
44 // return sum;
45
46 return
47 (
48 r4t(i,0,k,0) * gp0
49 + r4t(i,0,k,1) * gp1
50 + r4t(i,0,k,2) * gp2
51 ) * gt0
52 +
53 (
54 r4t(i,1,k,0) * gp0
55 + r4t(i,1,k,1) * gp1
56 + r4t(i,1,k,2) * gp2
57 ) * gt1
58 +
59 (
60 r4t(i,2,k,0) * gp0
61 + r4t(i,2,k,1) * gp1
62 + r4t(i,2,k,2) * gp2
63 ) * gt2;
64 // clang-format on
65}
66
67Real
69 unsigned int i,
70 unsigned int k,
71 const RealGradient & grad_test,
72 Real phi)
73{
74 // d(stress_ij*d(test)/dx_j)/dw_k = d(C_ijmn*eps_mnp*w_p*dtest/dx_j)/dw_k (only nonzero for p ==
75 // k)
76 Real sum = 0.0;
77 for (const auto j : make_range(Moose::dim))
78 for (const auto m : make_range(Moose::dim))
79 for (const auto n : make_range(Moose::dim))
80 sum += r4t(i, j, m, n) * PermutationTensor::eps(m, n, k) * grad_test(j);
81 return sum * phi;
82}
83
84Real
86 unsigned int i,
87 unsigned int k,
88 Real test,
89 const RealGradient & grad_phi)
90{
91 // Jacobian entry: d(eps_ijm*stress_jm*test)/du_k = d(eps_ijm*C_jmln*du_l/dx_n*test)/du_k (only
92 // nonzero for l == k)
93 Real sum = 0.0;
94 for (const auto j : make_range(Moose::dim))
95 for (const auto m : make_range(Moose::dim))
96 for (const auto n : make_range(Moose::dim))
97 sum += PermutationTensor::eps(i, j, m) * r4t(j, m, k, n) * grad_phi(n);
98 return test * sum;
99}
100
101Real
102momentJacobianWC(const RankFourTensor & r4t, unsigned int i, unsigned int k, Real test, Real phi)
103{
104 // Jacobian entry: d(eps_ijm*stress_jm*test)/dw_k = d(eps_ijm*C_jmln*eps_lnp*w_p*test)/dw_k (only
105 // nonzero for p ==k)
106 Real sum = 0.0;
107 for (const auto j : make_range(Moose::dim))
108 for (const auto l : make_range(Moose::dim))
109 for (const auto m : make_range(Moose::dim))
110 for (const auto n : make_range(Moose::dim))
111 sum +=
112 PermutationTensor::eps(i, j, m) * r4t(j, m, l, n) * PermutationTensor::eps(l, n, k);
113
114 return test * phi * sum;
115}
116
117void
118toVoigtNotationIndexConversion(int k, int & a, int & b)
119{
120 if (k < 3 && k >= 0)
121 a = b = k;
122 else if (k == 3)
123 {
124 a = 1;
125 b = 2;
126 }
127 else if (k == 4)
128 {
129 a = 0;
130 b = 2;
131 }
132 else if (k == 5)
133 {
134 a = 0;
135 b = 1;
136 }
137 else
138 mooseError("\nIndex out of bound while converting from tensor to voigt notation in "
139 "toVoigtNotationIndexConversion");
140}
141
142// MOOSE uses the stress tensor with components ordered as (11, 22, 33, 12, 23, 13) in voigt form.
143// This is in conflict with the voigt notation used in literature which has components ordered as
144// (11, 22, 33, 23, 13, 12). Whenever an operation involving the voigt forms of stress and
145// elasticity tensor has to be performed the voigt form of the elasticity tensor should be built
146// taking into account this difference in component-ordering for stress. The
147// toMooseVoigtNotationIndexConversion function facilitates that.
148
149void
151{
152 if (k < 3 && k >= 0)
153 a = b = k;
154 else if (k == 3)
155 {
156 a = 0;
157 b = 1;
158 }
159 else if (k == 4)
160 {
161 a = 1;
162 b = 2;
163 }
164 else if (k == 5)
165 {
166 a = 0;
167 b = 2;
168 }
169 else
170 mooseError("\nIndex out of bound while converting from tensor to MOOSE voigt notation in "
171 "toMooseVoigtNotationIndexConversion");
172}
173}
void mooseError(Args &&... args)
void toVoigtNotationIndexConversion(int, int &, int &)
Real momentJacobian(const RankFourTensor &r4t, unsigned int i, unsigned int k, Real test, const RealGradient &grad_phi)
This is used for the moment-balancing kernel eps_ijk*stress_jk*test, when varied wrt u_k Jacobian ent...
Real elasticJacobianWC(const RankFourTensor &r4t, unsigned int i, unsigned int k, const RealGradient &grad_test, Real phi)
This is used for the standard kernel stress_ij*d(test)/dx_j, when varied wrt w_k (the cosserat rotati...
Real elasticJacobian(const RankFourTensor &r4t, unsigned int i, unsigned int k, const RealGradient &grad_test, const RealGradient &grad_phi)
This is used for the standard kernel stress_ij*d(test)/dx_j, when varied wrt u_k Jacobian entry: d(st...
Real momentJacobianWC(const RankFourTensor &r4t, unsigned int i, unsigned int k, Real test, Real phi)
This is used for the moment-balancing kernel eps_ijk*stress_jk*test, when varied wrt w_k (the cossera...
void toMooseVoigtNotationIndexConversion(int, int &, int &)
static constexpr std::size_t dim
int eps(unsigned int i, unsigned int j)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real