Smith  0.1
Smith is an implicit thermal structural mechanics simulation code.
green_saint_venant_thermoelastic.hpp
1 // Copyright (c) Lawrence Livermore National Security, LLC and
2 // other Smith Project Developers. See the top-level LICENSE file for
3 // details.
4 //
5 // SPDX-License-Identifier: (BSD-3-Clause)
6 
7 #pragma once
8 
11 
13 
17 template <typename T, int dim>
18 auto greenStrain(const tensor<T, dim, dim>& grad_u)
19 {
20  return 0.5 * (grad_u + transpose(grad_u) + dot(transpose(grad_u), grad_u));
21 }
22 
26 template <typename EType>
27 auto bulkModulus(EType E, double nu)
28 {
29  return E / (3.0 * (1.0 - 2.0 * nu));
30 }
31 
35 template <typename EType>
36 auto shearModulus(EType E, double nu)
37 {
38  return 0.5 * E / (1.0 + nu);
39 }
40 
44 template <typename EType, typename AlphaType, typename TGradU, typename TTheta, int dim>
45 auto greenSaintVenantPiola(EType E, double nu, AlphaType alpha, double theta_ref,
46  const tensor<TGradU, dim, dim>& grad_u, TTheta theta)
47 {
48  const auto K = bulkModulus(E, nu);
49  const auto G = shearModulus(E, nu);
50  static constexpr auto I = Identity<dim>();
51  auto F = grad_u + I;
52  const auto Eg = greenStrain(grad_u);
53  const auto trEg = tr(Eg);
54  const auto S = 2.0 * G * dev(Eg) + K * (trEg - static_cast<double>(dim) * alpha * (theta - theta_ref)) * I;
55  return dot(F, S);
56 }
57 
61 template <typename TGradTheta, int dim>
62 auto fourierHeatFlux(double kappa, const tensor<TGradTheta, dim>& grad_theta)
63 {
64  return -kappa * grad_theta;
65 }
66 
69  double density;
70  double E;
71  double nu;
72  double C_v;
73  double alpha;
74  double theta_ref;
75  double kappa;
76 
78  struct State {
79  double strain_trace;
80  };
81 
100  template <typename T1, typename T2, typename T3, int dim>
101  auto operator()(State& state, const tensor<T1, dim, dim>& grad_u, T2 theta, const tensor<T3, dim>& grad_theta) const
102  {
103  const auto Eg = greenStrain(grad_u);
104  const auto trEg = tr(Eg);
105  const auto Piola = greenSaintVenantPiola(E, nu, alpha, theta_ref, grad_u, theta);
106  const auto s0 = -3.0 * bulkModulus(E, nu) * alpha * theta * (trEg - state.strain_trace);
107  const auto q0 = fourierHeatFlux(kappa, grad_theta);
108 
109  state.strain_trace = get_value(trEg);
110 
111  return smith::tuple{Piola, C_v, s0, q0};
112  }
113 
119  template <typename T1, typename T2, int dim>
120  auto calculateFreeEnergy(const tensor<T1, dim, dim>& grad_u, T2 theta) const
121  {
122  const double K = E / (3.0 * (1.0 - 2.0 * nu));
123  const double G = 0.5 * E / (1.0 + nu);
124  auto strain = greenStrain(grad_u);
125  auto trE = tr(strain);
126  auto psi_1 = G * squared_norm(dev(strain)) + 0.5 * K * trE * trE;
127  using std::log;
128  auto logT = log(theta / theta_ref);
129  auto psi_2 = C_v * (theta - theta_ref - theta * logT);
130  auto psi_3 = -3.0 * K * alpha * (theta - theta_ref) * trE;
131  return psi_1 + psi_2 + psi_3;
132  }
133 };
134 
137  double density;
138  double E;
139  double nu;
140  double C_v;
141  double alpha0;
142  double theta_ref;
143  double kappa;
144 
146  struct State {
147  double strain_trace;
148  };
149 
170  template <typename T1, typename T2, typename T3, typename T4, int dim>
171  auto operator()(State& state, const tensor<T1, dim, dim>& grad_u, T2 theta, const tensor<T3, dim>& grad_theta,
172  T4 thermal_expansion_scaling) const
173  {
174  auto [scale, unused] = thermal_expansion_scaling;
175  const auto Eg = greenStrain(grad_u);
176  const auto trEg = tr(Eg);
177  auto alpha = alpha0 * scale;
178  const auto Piola = greenSaintVenantPiola(E, nu, alpha, theta_ref, grad_u, theta);
179  const auto s0 = -3.0 * bulkModulus(E, nu) * alpha * theta * (trEg - state.strain_trace);
180  const auto q0 = fourierHeatFlux(kappa, grad_theta);
181 
182  state.strain_trace = get_value(trEg);
183 
184  return smith::tuple{Piola, C_v, s0, q0};
185  }
186 
193  template <typename T1, typename T2, typename T3, int dim>
194  auto calculateFreeEnergy(const tensor<T1, dim, dim>& grad_u, T2 theta, T3 thermal_expansion_scaling) const
195  {
196  auto [scale, unused] = thermal_expansion_scaling;
197  const double K = bulkModulus(E, nu);
198  const double G = shearModulus(E, nu);
199  auto strain = greenStrain(grad_u);
200  auto trE = tr(strain);
201  const auto alpha = alpha0 * scale;
202  auto psi_1 = G * squared_norm(dev(strain)) + 0.5 * K * trE * trE;
203  using std::log;
204  auto logT = log(theta / theta_ref);
205  auto psi_2 = C_v * (theta - theta_ref - theta * logT);
206  auto psi_3 = -3.0 * K * alpha * (theta - theta_ref) * trE;
207  return psi_1 + psi_2 + psi_3;
208  }
209 };
210 
211 } // namespace smith::thermomechanics
Thermomechanics helper data types.
auto fourierHeatFlux(double kappa, const tensor< TGradTheta, dim > &grad_theta)
Compute referential Fourier heat flux.
auto greenSaintVenantPiola(EType E, double nu, AlphaType alpha, double theta_ref, const tensor< TGradU, dim, dim > &grad_u, TTheta theta)
Compute first Piola stress for Green-Saint Venant thermoelasticity.
auto greenStrain(const tensor< T, dim, dim > &grad_u)
Compute Green's strain from the displacement gradient.
auto bulkModulus(EType E, double nu)
Compute isotropic bulk modulus from Young's modulus and Poisson ratio.
auto shearModulus(EType E, double nu)
Compute isotropic shear modulus from Young's modulus and Poisson ratio.
SMITH_HOST_DEVICE auto log(dual< gradient_type > a)
implementation of the natural logarithm function for dual numbers
Definition: dual.hpp:389
mfem::future::tuple< T... > tuple
Expose MFEM tuple in the Smith namespace.
Definition: tuple.hpp:241
constexpr SMITH_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
constexpr SMITH_HOST_DEVICE auto transpose(const isotropic_tensor< T, m, m > &I)
return the transpose of an isotropic tensor
constexpr SMITH_HOST_DEVICE auto dev(const tensor< T, n, n > &A)
Calculates the deviator of a matrix (rank-2 tensor)
Definition: tensor.hpp:1200
constexpr SMITH_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:445
constexpr SMITH_HOST_DEVICE auto tr(const isotropic_tensor< T, m, m > &I)
calculate the trace of an isotropic tensor
constexpr SMITH_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
Arbitrary-rank tensor class.
Definition: tensor.hpp:28
auto calculateFreeEnergy(const tensor< T1, dim, dim > &grad_u, T2 theta) const
evaluate free energy density
auto operator()(State &state, const tensor< T1, dim, dim > &grad_u, T2 theta, const tensor< T3, dim > &grad_theta) const
Evaluate constitutive variables for thermomechanics.
auto operator()(State &state, const tensor< T1, dim, dim > &grad_u, T2 theta, const tensor< T3, dim > &grad_theta, T4 thermal_expansion_scaling) const
Evaluate constitutive variables for thermomechanics.
auto calculateFreeEnergy(const tensor< T1, dim, dim > &grad_u, T2 theta, T3 thermal_expansion_scaling) const
evaluate free energy density
Implementation of the tensor class used by Functional.
Smith tuple compatibility layer over mfem::future::tuple.