Serac  0.1
Serac is an implicit thermal strucural mechanics simulation code.
parameterized_solid_material.hpp
Go to the documentation of this file.
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 
13 #pragma once
14 
17 
20 
26 template <int dim>
28  using State = Empty;
29 
41  template <typename DispGradType, typename BulkType, typename ShearType>
42  SERAC_HOST_DEVICE auto operator()(State& /*state*/, const DispGradType& du_dX, const BulkType& DeltaK,
43  const ShearType& DeltaG) const
44  {
45  constexpr auto I = Identity<dim>();
46  auto K = K0 + get<0>(DeltaK);
47  auto G = G0 + get<0>(DeltaG);
48  auto lambda = K - (2.0 / dim) * G;
49  auto epsilon = 0.5 * (transpose(du_dX) + du_dX);
50  return lambda * tr(epsilon) * I + 2.0 * G * epsilon;
51  }
52 
58  static constexpr int numParameters() { return 2; }
59 
60  double density;
61  double K0;
62  double G0;
63 };
64 
70 template <int dim>
72  using State = Empty;
73 
85  template <typename DispGradType, typename BulkType, typename ShearType>
86  SERAC_HOST_DEVICE auto operator()(State& /*state*/, const DispGradType& du_dX, const BulkType& DeltaK,
87  const ShearType& DeltaG) const
88  {
89  using std::log1p;
90  constexpr auto I = Identity<dim>();
91  auto K = K0 + get<0>(DeltaK);
92  auto G = G0 + get<0>(DeltaG);
93  auto lambda = K - (2.0 / dim) * G;
94  auto B_minus_I = du_dX * transpose(du_dX) + transpose(du_dX) + du_dX;
95  auto J_minus_1 = detApIm1(du_dX);
96  auto J = J_minus_1 + 1;
97  return (lambda * log1p(J_minus_1) * I + G * B_minus_I) / J;
98  }
99 
105  static constexpr int numParameters() { return 2; }
106 
107  double density;
108  double K0;
109  double G0;
110 };
111 
117 template <typename... T>
119  using type = decltype((T{} + ...));
120 };
121 
124  static constexpr int dim = 3;
125  static constexpr double tol = 1e-10;
126 
127  double E;
128  double nu;
129  double density;
130 
132  struct State {
135  };
136 
138  template <typename DisplacementGradient, typename YieldStrength, typename SaturationStrength, typename StrainConstant>
139  auto operator()(State& state, const DisplacementGradient du_dX, const YieldStrength sigma_y,
140  const SaturationStrength sigma_sat, const StrainConstant strain_constant) const
141  {
142  // The output stress tensor should use dual numbers if any of the parameters are dual.
143  // This slightly ugly trick to accomplishes that by picking up any dual number types
144  // from the parameters into the dummy variable "one".
145  // Another possiblity would be to cast the results to the correct type at the end, which
146  // would avoid doing any unneccessary arithmetic with dual numbers.
148  T one;
149  one = 1.0;
150 
151  using std::sqrt;
152  constexpr auto I = Identity<dim>();
153  const double K = E / (3.0 * (1.0 - 2.0 * nu));
154  const double G = 0.5 * E / (1.0 + nu);
155  const double rel_tol = tol * get_value(sigma_y);
156 
157  // (i) elastic predictor
158  auto el_strain = sym(du_dX) - state.plastic_strain;
159  auto p = K * tr(el_strain);
160  auto s = 2.0 * G * dev(el_strain) * one; // multiply by "one" to get type correct for parameter derivatives
161  auto q = sqrt(1.5) * norm(s);
162 
163  // (ii) admissibility
164  const double eqps_old = state.accumulated_plastic_strain;
165  auto residual = [eqps_old, G, *this](auto delta_eqps, auto trial_mises, auto y0, auto ysat, auto e0) {
166  auto Y = this->flow_strength(eqps_old + delta_eqps, y0, ysat, e0);
167  return trial_mises - 3.0 * G * delta_eqps - Y;
168  };
169  if (residual(0.0, get_value(q), get_value(sigma_y), get_value(sigma_sat), get_value(strain_constant)) > rel_tol) {
170  // (iii) return mapping
171 
172  // Note the tolerance for convergence is the same as the tolerance for entering the return map.
173  // This ensures that if the constitutive update is called again with the updated internal
174  // variables, the return map won't be repeated.
175  ScalarSolverOptions opts{.xtol = 0, .rtol = rel_tol, .max_iter = 25};
176  double lower_bound = 0.0;
177  double upper_bound = (get_value(q) - flow_strength(eqps_old, get_value(sigma_y), get_value(sigma_sat),
178  get_value(strain_constant))) /
179  (3.0 * G);
180  auto [delta_eqps, status] =
181  solve_scalar_equation(residual, 0.0, lower_bound, upper_bound, opts, q, sigma_y, sigma_sat, strain_constant);
182 
183  auto Np = 1.5 * s / q;
184 
185  s = s - 2.0 * G * delta_eqps * Np;
186  state.accumulated_plastic_strain += get_value(delta_eqps);
187  state.plastic_strain += get_value(delta_eqps) * get_value(Np);
188  }
189 
190  return s + p * I;
191  }
192 
194  template <typename PlasticStrain, typename YieldStrength, typename SaturationStrength, typename StrainConstant>
195  auto flow_strength(const PlasticStrain accumulated_plastic_strain, const YieldStrength sigma_y,
196  const SaturationStrength sigma_sat, const StrainConstant strain_constant) const
197  {
198  using std::exp;
199  return sigma_sat - (sigma_sat - sigma_y) * exp(-accumulated_plastic_strain / strain_constant);
200  };
201 };
202 
203 } // namespace serac::solid_mechanics
#define SERAC_HOST_DEVICE
Macro that evaluates to __host__ __device__ when compiling with nvcc and does nothing on a host compi...
Definition: accelerator.hpp:38
Implementation of the quadrature-function-based functional enabling rapid development of FEM formulat...
SolidMechanics helper data types.
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 detApIm1(const tensor< T, 2, 2 > &A)
computes det(A + I) - 1, where precision is not lost when the entries A_{ij} << 1
Definition: tensor.hpp:1238
constexpr SERAC_HOST_DEVICE auto sym(const isotropic_tensor< T, m, m > &I)
return the symmetric part of an isotropic tensor
SERAC_HOST_DEVICE auto sqrt(dual< gradient_type > x)
implementation of square root for dual numbers
Definition: dual.hpp:279
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 solve_scalar_equation(function &&f, double x0, double lower_bound, double upper_bound, ScalarSolverOptions options, ParamTypes... params)
Solves a nonlinear scalar-valued equation and gives derivatives of solution to parameters.
constexpr SERAC_HOST_DEVICE auto norm(const isotropic_tensor< T, m, m > &I)
compute the Frobenius norm (sqrt(tr(dot(transpose(I), I)))) of an isotropic tensor
constexpr SERAC_HOST_DEVICE auto transpose(const isotropic_tensor< T, m, m > &I)
return the transpose of an isotropic tensor
SERAC_HOST_DEVICE auto log1p(dual< gradient_type > a)
implementation of the natural logarithm of one plus the argument function for dual numbers
Definition: dual.hpp:368
SERAC_HOST_DEVICE auto exp(dual< gradient_type > a)
implementation of exponential function for dual numbers
Definition: dual.hpp:352
The material and load types for the solid functional physics module.
see Nothing for a complete description of this class and when to use it
Settings for solve_scalar_equation.
double xtol
absolute tolerance on Newton correction
variables required to characterize the hysteresis response
J2 material with Voce hardening, with hardening parameters exposed as differentiable parameters.
auto flow_strength(const PlasticStrain accumulated_plastic_strain, const YieldStrength sigma_y, const SaturationStrength sigma_sat, const StrainConstant strain_constant) const
Computes flow strength from Voce's hardening law.
static constexpr double tol
relative tolerance on residual for accepting return map solution
auto operator()(State &state, const DisplacementGradient du_dX, const YieldStrength sigma_y, const SaturationStrength sigma_sat, const StrainConstant strain_constant) const
calculate the Cauchy stress, given the displacement gradient and previous material state
SERAC_HOST_DEVICE auto operator()(State &, const DispGradType &du_dX, const BulkType &DeltaK, const ShearType &DeltaG) const
stress calculation for a linear isotropic material model
static constexpr int numParameters()
The number of parameters in the model.
SERAC_HOST_DEVICE auto operator()(State &, const DispGradType &du_dX, const BulkType &DeltaK, const ShearType &DeltaG) const
stress calculation for a NeoHookean material model
static constexpr int numParameters()
The number of parameters in the model.
Infers type resulting from algebraic expressions of a group of variables.
decltype((T{}+...)) type
type of the sum of the parameters