Serac  0.1
Serac is an implicit thermal strucural mechanics simulation code.
green_saint_venant_thermoelastic.hpp
1 // Copyright (c) 2019-2024, Lawrence Livermore National Security, LLC and
2 // other Serac Project Developers. See the top-level LICENSE file for
3 // details.
4 //
5 // SPDX-License-Identifier: (BSD-3-Clause)
6 
9 
10 namespace serac {
11 
15 template <typename T>
16 auto greenStrain(const tensor<T, 3, 3>& grad_u)
17 {
18  return 0.5 * (grad_u + transpose(grad_u) + dot(transpose(grad_u), grad_u));
19 }
20 
23  double density;
24  double E;
25  double nu;
26  double C_v;
27  double alpha;
28  double theta_ref;
29  double k;
30 
32  struct State {
33  double strain_trace;
34  };
35 
54  template <typename T1, typename T2, typename T3>
55  auto operator()(State& state, const tensor<T1, 3, 3>& grad_u, T2 theta, const tensor<T3, 3>& grad_theta) const
56  {
57  const double K = E / (3.0 * (1.0 - 2.0 * nu));
58  const double G = 0.5 * E / (1.0 + nu);
59  static constexpr auto I = Identity<3>();
60  auto F = grad_u + I;
61  const auto Eg = greenStrain(grad_u);
62  const auto trEg = tr(Eg);
63 
64  // stress
65  const auto S = 2.0 * G * dev(Eg) + K * (trEg - 3.0 * alpha * (theta - theta_ref)) * I;
66  const auto P = dot(F, S);
67  const auto sigma = dot(P, transpose(F)) / det(F);
68 
69  // internal heat source
70  const auto s0 = -3 * K * alpha * theta * (trEg - state.strain_trace);
71 
72  // heat flux
73  const auto q0 = -k * grad_theta;
74 
75  state.strain_trace = get_value(trEg);
76 
77  return serac::tuple{sigma, C_v, s0, q0};
78  }
79 
85  template <typename T1, typename T2>
86  auto calculateFreeEnergy(const tensor<T1, 3, 3>& grad_u, T2 theta) const
87  {
88  const double K = E / (3.0 * (1.0 - 2.0 * nu));
89  const double G = 0.5 * E / (1.0 + nu);
90  auto strain = greenStrain(grad_u);
91  auto trE = tr(strain);
92  auto psi_1 = G * squared_norm(dev(strain)) + 0.5 * K * trE * trE;
93  using std::log;
94  auto logT = log(theta / theta_ref);
95  auto psi_2 = C_v * (theta - theta_ref - theta * logT);
96  auto psi_3 = -3.0 * K * alpha * (theta - theta_ref) * trE;
97  return psi_1 + psi_2 + psi_3;
98  }
99 };
100 
103  double density;
104  double E;
105  double nu;
106  double C_v;
107  double alpha0;
108  double theta_ref;
109  double k;
110 
112  struct State {
113  double strain_trace;
114  };
115 
136  template <typename T1, typename T2, typename T3, typename T4>
137  auto operator()(State& state, const tensor<T1, 3, 3>& grad_u, T2 theta, const tensor<T3, 3>& grad_theta,
138  T4 thermal_expansion_scaling) const
139  {
140  auto [scale, unused] = thermal_expansion_scaling;
141  const double K = E / (3.0 * (1.0 - 2.0 * nu));
142  const double G = 0.5 * E / (1.0 + nu);
143  static constexpr auto I = Identity<3>();
144  auto F = grad_u + I;
145  const auto Eg = greenStrain(grad_u);
146  const auto trEg = tr(Eg);
147  auto alpha = alpha0 * scale;
148 
149  // stress
150  const auto S = 2.0 * G * dev(Eg) + K * (trEg - 3.0 * alpha * (theta - theta_ref)) * I;
151  const auto P = dot(F, S);
152  const auto sigma = (dot(P, transpose(F))) / det(F);
153 
154  // internal heat source
155  const auto s0 = -3 * K * alpha * theta * (trEg - state.strain_trace);
156 
157  // heat flux
158  const auto q0 = -k * grad_theta;
159 
160  state.strain_trace = get_value(trEg);
161 
162  return serac::tuple{sigma, C_v, s0, q0};
163  }
164 
171  template <typename T1, typename T2, typename T3>
172  auto calculateFreeEnergy(const tensor<T1, 3, 3>& grad_u, T2 theta, T3 thermal_expansion_scaling) const
173  {
174  auto [scale, unused] = thermal_expansion_scaling;
175  const double K = E / (3.0 * (1.0 - 2.0 * nu));
176  const double G = 0.5 * E / (1.0 + nu);
177  auto strain = greenStrain(grad_u);
178  auto trE = tr(strain);
179  const double alpha = alpha0 * scale;
180  auto psi_1 = G * squared_norm(dev(strain)) + 0.5 * K * trE * trE;
181  using std::log;
182  auto logT = log(theta / theta_ref);
183  auto psi_2 = C_v * (theta - theta_ref - theta * logT);
184  auto psi_3 = -3.0 * K * alpha * (theta - theta_ref) * trE;
185  return psi_1 + psi_2 + psi_3;
186  }
187 };
188 
189 } // namespace serac
Accelerator functionality.
Definition: serac.cpp:38
constexpr SERAC_HOST_DEVICE auto tr(const isotropic_tensor< T, m, m > &I)
calculate the trace of an isotropic tensor
constexpr SERAC_HOST_DEVICE auto dot(const isotropic_tensor< S, m, m > &I, const tensor< T, m, n... > &A)
dot product between an isotropic and (nonisotropic) tensor
constexpr SERAC_HOST_DEVICE auto dev(const tensor< T, n, n > &A)
Calculates the deviator of a matrix (rank-2 tensor)
Definition: tensor.hpp:1124
constexpr SERAC_HOST_DEVICE auto get_value(const T &arg)
return the "value" part from a given type. For non-dual types, this is just the identity function
Definition: dual.hpp:416
auto greenStrain(const tensor< T, 3, 3 > &grad_u)
Compute Green's strain from the displacement gradient.
constexpr SERAC_HOST_DEVICE auto det(const isotropic_tensor< T, m, m > &I)
compute the determinant of an isotropic tensor
constexpr SERAC_HOST_DEVICE auto transpose(const isotropic_tensor< T, m, m > &I)
return the transpose of an isotropic tensor
constexpr SERAC_HOST_DEVICE auto squared_norm(const isotropic_tensor< T, m, m > &I)
compute the squared Frobenius norm (tr(dot(transpose(I), I))) of an isotropic tensor
SERAC_HOST_DEVICE auto log(dual< gradient_type > a)
implementation of the natural logarithm function for dual numbers
Definition: dual.hpp:360
double strain_trace
trace of Green-Saint Venant strain tensor
Green-Saint Venant isotropic thermoelastic model.
auto calculateFreeEnergy(const tensor< T1, 3, 3 > &grad_u, T2 theta) const
evaluate free energy density
auto operator()(State &state, const tensor< T1, 3, 3 > &grad_u, T2 theta, const tensor< T3, 3 > &grad_theta) const
Evaluate constitutive variables for thermomechanics.
double theta_ref
datum temperature for thermal expansion
double alpha0
reference value of thermal expansion coefficient
auto calculateFreeEnergy(const tensor< T1, 3, 3 > &grad_u, T2 theta, T3 thermal_expansion_scaling) const
evaluate free energy density
auto operator()(State &state, const tensor< T1, 3, 3 > &grad_u, T2 theta, const tensor< T3, 3 > &grad_theta, T4 thermal_expansion_scaling) const
Evaluate constitutive variables for thermomechanics.
Arbitrary-rank tensor class.
Definition: tensor.hpp:29
This is a class that mimics most of std::tuple's interface, except that it is usable in CUDA kernels ...
Definition: tuple.hpp:28
Implementation of the tensor class used by Functional.
Implements a std::tuple-like object that works in CUDA kernels.