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
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.
const std::string & name() const
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)