https://mooseframework.inl.gov
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"
13 #include "ElasticityTensorTools.h"
14 
15 #include "libmesh/vector_value.h"
16 
17 namespace ElasticityTensorTools
18 {
19 
20 Real
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 
67 Real
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 
84 Real
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 
101 Real
102 momentJacobianWC(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 
117 void
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 
149 void
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 }
int eps(unsigned int i, unsigned int j)
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 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 mooseError(Args &&... args)
static constexpr std::size_t dim
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...
void toMooseVoigtNotationIndexConversion(int, int &, int &)
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...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
static const std::string k
Definition: NS.h:130