https://mooseframework.inl.gov
TemperatureDependentHardeningStressUpdate.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 
11 
12 #include "PiecewiseLinear.h"
13 #include "ElasticityTensorTools.h"
14 
17 
18 template <bool is_ad>
21 {
23  params.addClassDescription("Computes the stress as a function of temperature "
24  "and plastic strain from user-supplied hardening "
25  "functions. This class can be used in conjunction "
26  "with other creep and plasticity materials for "
27  "more complex simulations");
28  params.set<Real>("yield_stress") = 1.0;
29  params.set<Real>("hardening_constant") = 1.0;
30 
31  params.suppressParameter<Real>("yield_stress");
32  params.suppressParameter<FunctionName>("yield_stress_function");
33  params.suppressParameter<Real>("hardening_constant");
34  params.suppressParameter<FunctionName>("hardening_function");
35 
36  params.addRequiredParam<std::vector<FunctionName>>(
37  "hardening_functions",
38  "List of functions of true stress as function of plastic strain at different temperatures");
39  params.addRequiredParam<std::vector<Real>>(
40  "temperatures",
41  "List of temperatures corresponding to the functions listed in 'hardening_functions'");
42 
43  return params;
44 }
45 
46 template <bool is_ad>
49  : IsotropicPlasticityStressUpdateTempl<is_ad>(parameters),
50  _hardening_functions_names(
51  this->template getParam<std::vector<FunctionName>>("hardening_functions")),
52  _hf_temperatures(this->template getParam<std::vector<Real>>("temperatures"))
53 {
54  const unsigned int len = _hardening_functions_names.size();
55  if (len < 2)
56  mooseError("At least two stress-strain curves must be provided in hardening_functions");
57  _hardening_functions.resize(len);
58 
59  const unsigned int len_temps = _hf_temperatures.size();
60  if (len != len_temps)
61  mooseError("The vector of hardening function temperatures must have the same length as the "
62  "vector of temperature dependent hardening functions.");
63 
64  // Check that the temperatures are strictly increasing
65  for (unsigned int i = 1; i < len_temps; ++i)
66  if (_hf_temperatures[i] <= _hf_temperatures[i - 1])
67  mooseError("The temperature dependent hardening functions and corresponding temperatures "
68  "should be listed in order of increasing temperature.");
69 
70  std::vector<Real> yield_stress_vec;
71  for (unsigned int i = 0; i < len; ++i)
72  {
73  const PiecewiseLinear * const f = dynamic_cast<const PiecewiseLinear *>(
75  if (!f)
76  mooseError("Function ", _hardening_functions_names[i], " not found in ", this->name());
77 
79 
80  yield_stress_vec.push_back(f->value(0.0, Point()));
81  }
82 
83  _interp_yield_stress = std::make_unique<LinearInterpolation>(_hf_temperatures, yield_stress_vec);
84 }
85 
86 template <bool is_ad>
87 void
89  const GenericReal<is_ad> & effectiveTrialStress,
90  const GenericRankFourTensor<is_ad> & elasticity_tensor)
91 {
94  initializeHardeningFunctions();
95  computeYieldStress(elasticity_tensor);
96 
97  this->_yield_condition =
98  effectiveTrialStress - this->_hardening_variable_old[_qp] - this->_yield_stress;
99  this->_hardening_variable[_qp] = this->_hardening_variable_old[_qp];
100  this->_plastic_strain[_qp] = this->_plastic_strain_old[_qp];
101 }
102 
103 template <bool is_ad>
104 void
106 {
107  const Real temp = MetaPhysicL::raw_value(this->_temperature[_qp]);
108  if (temp > _hf_temperatures[0] && temp < _hf_temperatures.back())
109  {
110  for (unsigned int i = 0; i < _hf_temperatures.size() - 1; ++i)
111  {
112  if (temp >= _hf_temperatures[i] && temp < _hf_temperatures[i + 1])
113  {
114  _hf_index_lo = i;
115  _hf_index_hi = i + 1;
116  _hf_fraction =
117  (temp - _hf_temperatures[i]) / (_hf_temperatures[i + 1] - _hf_temperatures[i]);
118  }
119  }
120  }
121  else if (temp <= _hf_temperatures[0])
122  {
123  _hf_index_lo = 0;
124  _hf_index_hi = _hf_index_lo;
125  _hf_fraction = 0.0;
126  }
127  else if (temp >= _hf_temperatures.back())
128  {
129  _hf_index_lo = _hf_temperatures.size() - 1;
130  _hf_index_hi = _hf_index_lo;
131  _hf_fraction = 1.0;
132  }
133 
134  if (_hf_fraction < 0.0)
135  mooseError("The hardening function fraction cannot be less than zero.");
136 }
137 
138 template <bool is_ad>
141  const GenericReal<is_ad> & scalar)
142 {
143  const Real strain = this->_effective_inelastic_strain_old[_qp] + MetaPhysicL::raw_value(scalar);
144  const GenericReal<is_ad> stress =
145  (1.0 - _hf_fraction) * _hardening_functions[_hf_index_lo]->value(strain, Point()) +
146  _hf_fraction * _hardening_functions[_hf_index_hi]->value(strain, Point());
147 
148  return stress - this->_yield_stress;
149 }
150 
151 template <bool is_ad>
154  const GenericReal<is_ad> & /*scalar*/)
155 {
156  const Real strain_old = this->_effective_inelastic_strain_old[_qp];
157 
158  return (1.0 - _hf_fraction) *
159  _hardening_functions[_hf_index_lo]->timeDerivative(strain_old, Point()) +
160  _hf_fraction * _hardening_functions[_hf_index_hi]->timeDerivative(strain_old, Point());
161 }
162 
163 template <bool is_ad>
164 void
166  const GenericRankFourTensor<is_ad> & /*elasticity_tensor*/)
167 {
168  this->_yield_stress =
169  _interp_yield_stress->sample(MetaPhysicL::raw_value(this->_temperature[_qp]));
170  if (this->_yield_stress <= 0.0)
171  mooseError("The yield stress must be greater than zero, but during the simulation your yield "
172  "stress became less than zero.");
173 }
174 
virtual GenericReal< is_ad > computeHardeningValue(const GenericReal< is_ad > &scalar) override
Moose::GenericType< Real, is_ad > GenericReal
This class uses the Discrete material in a radial return isotropic plasticity model.
void mooseError(Args &&... args)
std::vector< Real > _hf_temperatures
The temperatures at which each of the hardening functions are defined.
virtual void computeStressInitialize(const GenericReal< is_ad > &effective_trial_stress, const GenericRankFourTensor< is_ad > &elasticity_tensor)
Perform any necessary initialization before return mapping iterations.
T & set(const std::string &name, bool quiet_mode=false)
virtual void computeStressInitialize(const GenericReal< is_ad > &effectiveTrialStress, const GenericRankFourTensor< is_ad > &elasticity_tensor) override
Perform any necessary initialization before return mapping iterations.
auto raw_value(const Eigen::Map< T > &in)
Moose::GenericType< RankFourTensor, is_ad > GenericRankFourTensor
virtual const std::string & name() const
void addRequiredParam(const std::string &name, const std::string &doc_string)
virtual void computeYieldStress(const GenericRankFourTensor< is_ad > &elasticity_tensor) override
void suppressParameter(const std::string &name)
Real elasticity_tensor(unsigned int i, unsigned int j, unsigned int k, unsigned int l)
This class inherits from IsotropicPlasticityStressUpdate.
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
Real f(Real x)
Test function for Brents method.
const std::vector< FunctionName > _hardening_functions_names
The function names and expressions for hardening as a function of temperature.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const Function & getFunctionByName(const FunctionName &name) const
virtual GenericReal< is_ad > computeHardeningDerivative(const GenericReal< is_ad > &scalar) override
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
void initializeHardeningFunctions()
Determines the section of the piecewise temperature dependent hardening function for the current temp...
registerMooseObject("SolidMechanicsApp", TemperatureDependentHardeningStressUpdate)