LCOV - code coverage report
Current view: top level - src/materials - CombinedNonlinearHardeningPlasticity.C (source / functions) Hit Total Coverage
Test: idaholab/moose solid_mechanics: #32971 (54bef8) with base c6cf66 Lines: 101 125 80.8 %
Date: 2026-05-29 20:40:07 Functions: 12 26 46.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #include "CombinedNonlinearHardeningPlasticity.h"
       2             : #include "Function.h"
       3             : #include "ElasticityTensorTools.h"
       4             : #include "RadialReturnBackstressStressUpdateBase.h"
       5             : #include "ElasticityTensorTools.h"
       6             : 
       7             : registerMooseObject("SolidMechanicsApp", ADCombinedNonlinearHardeningPlasticity);
       8             : registerMooseObject("SolidMechanicsApp", CombinedNonlinearHardeningPlasticity);
       9             : 
      10             : template <bool is_ad>
      11             : InputParameters
      12         128 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::validParams()
      13             : {
      14             :   InputParameters params = RadialReturnBackstressStressUpdateBaseTempl<is_ad>::validParams();
      15         128 :   params.addClassDescription("Combined isotropic and kinematic plasticity model with nonlinear "
      16             :                              "hardening rules, including a Voce model for isotropic hardening and "
      17             :                              "an Armstrong-Fredrick model for kinematic hardening.");
      18         256 :   params.addParam<Real>("q", 0.0, "Saturation value for isotropic hardening (Q in Voce model)");
      19         256 :   params.addParam<Real>("b", 0.0, "Rate constant for isotropic hardening (b in Voce model)");
      20         256 :   params.addParam<FunctionName>("yield_stress_function",
      21             :                                 "Yield stress as a function of temperature");
      22         256 :   params.addParam<Real>("yield_stress", "The point at which plastic strain begins accumulating");
      23         256 :   params.addParam<FunctionName>("isotropic_hardening_function",
      24             :                                 "True stress as a function of plastic strain");
      25         256 :   params.addParam<Real>("isotropic_hardening_constant", "Isotropic hardening slope");
      26         256 :   params.addCoupledVar("temperature", 0.0, "Coupled Temperature");
      27         128 :   params.set<std::string>("effective_inelastic_strain_name") = "effective_plastic_strain";
      28         256 :   params.addParam<Real>("kinematic_hardening_modulus", 0.0, "Kinematic hardening modulus");
      29         256 :   params.addParam<Real>(
      30         256 :       "gamma", 0.0, "The nonlinear hardening parameter (gamma) for back stress evolution");
      31             : 
      32         128 :   return params;
      33           0 : }
      34             : 
      35             : template <bool is_ad>
      36          96 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::CombinedNonlinearHardeningPlasticityTempl(
      37             :     const InputParameters & parameters)
      38             :   : RadialReturnBackstressStressUpdateBaseTempl<is_ad>(parameters),
      39         288 :     _yield_stress_function(this->isParamValid("yield_stress_function")
      40          96 :                                ? &this->getFunction("yield_stress_function")
      41             :                                : nullptr),
      42         384 :     _yield_stress(this->isParamValid("yield_stress") ? this->template getParam<Real>("yield_stress")
      43             :                                                      : 0),
      44          96 :     _isotropic_hardening_constant(
      45          96 :         this->isParamValid("isotropic_hardening_constant")
      46         288 :             ? this->template getParam<Real>("isotropic_hardening_constant")
      47             :             : 0),
      48          96 :     _isotropic_hardening_function(this->isParamValid("isotropic_hardening_function")
      49          96 :                                       ? &this->getFunction("isotropic_hardening_function")
      50             :                                       : nullptr),
      51          96 :     _yield_condition(-1.0), // set to a non-physical value to catch uninitalized yield condition
      52          96 :     _isotropic_hardening_slope(0.0),
      53          96 :     _plastic_strain(
      54          96 :         this->template declareGenericProperty<RankTwoTensor, is_ad>(_base_name + "plastic_strain")),
      55          96 :     _plastic_strain_old(
      56          96 :         this->template getMaterialPropertyOld<RankTwoTensor>(_base_name + "plastic_strain")),
      57         192 :     _kinematic_hardening_modulus(this->template getParam<Real>("kinematic_hardening_modulus")),
      58         192 :     _gamma(this->template getParam<Real>("gamma")),
      59         192 :     _q(this->template getParam<Real>("q")),
      60         192 :     _b(this->template getParam<Real>("b")),
      61         192 :     _isotropic_hardening_variable(this->template declareGenericProperty<Real, is_ad>(
      62             :         _base_name + "isotropic_hardening_variable")),
      63          96 :     _isotropic_hardening_variable_old(
      64          96 :         this->template getMaterialPropertyOld<Real>(_base_name + "isotropic_hardening_variable")),
      65          96 :     _kinematic_hardening_variable(
      66          96 :         this->template declareGenericProperty<Real, is_ad>("kinematic_hardening_variable")),
      67          96 :     _kinematic_hardening_variable_old(
      68          96 :         this->template getMaterialPropertyOld<Real>("kinematic_hardening_variable")),
      69         288 :     _temperature(this->template coupledGenericValue<is_ad>("temperature"))
      70             : {
      71         192 :   if (parameters.isParamSetByUser("yield_stress") && _yield_stress <= 0.0)
      72           0 :     mooseError("Yield stress must be greater than zero");
      73             :   // Both of these parameters are given default values by derived classes, which makes them valid
      74         384 :   if (_yield_stress_function == nullptr && !this->isParamValid("yield_stress"))
      75           0 :     mooseError("Either yield_stress or yield_stress_function must be given");
      76         192 :   if (!parameters.isParamValid("isotropic_hardening_constant") &&
      77          96 :       !this->isParamValid("isotropic_hardening_function"))
      78           0 :     mooseError(
      79             :         "Either isotropic_hardening_constant or isotropic_hardening_function must be defined");
      80         192 :   if (parameters.isParamSetByUser("isotropic_hardening_constant") &&
      81         288 :       this->isParamValid("isotropic_hardening_function"))
      82           0 :     mooseError(
      83             :         "Only the isotropic_hardening_constant or only the isotropic_hardening_function can be "
      84             :         "defined but not both");
      85          96 : }
      86             : 
      87             : template <bool is_ad>
      88             : void
      89         384 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::initQpStatefulProperties()
      90             : {
      91         384 :   _isotropic_hardening_variable[_qp] = 0.0;
      92         384 :   _kinematic_hardening_variable[_qp] = 0.0;
      93         384 :   _plastic_strain[_qp].zero();
      94         384 :   RadialReturnBackstressStressUpdateBaseTempl<is_ad>::initQpStatefulProperties();
      95         384 : }
      96             : 
      97             : template <bool is_ad>
      98             : void
      99           0 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::propagateQpStatefulProperties()
     100             : {
     101           0 :   _isotropic_hardening_variable[_qp] = _isotropic_hardening_variable_old[_qp];
     102           0 :   _kinematic_hardening_variable[_qp] = _kinematic_hardening_variable_old[_qp];
     103           0 :   _plastic_strain[_qp] = _plastic_strain_old[_qp];
     104             : 
     105           0 :   RadialReturnBackstressStressUpdateBaseTempl<is_ad>::propagateQpStatefulPropertiesRadialReturn();
     106           0 : }
     107             : 
     108             : template <bool is_ad>
     109             : void
     110      919624 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeStressInitialize(
     111             :     const GenericReal<is_ad> & effective_trial_stress,
     112             :     const GenericRankFourTensor<is_ad> & elasticity_tensor)
     113             : {
     114           0 :   RadialReturnBackstressStressUpdateBaseTempl<is_ad>::computeStressInitialize(
     115             :       effective_trial_stress, elasticity_tensor);
     116             : 
     117      919624 :   computeYieldStress(elasticity_tensor);
     118      919624 :   _yield_condition =
     119      919624 :       effective_trial_stress - _isotropic_hardening_variable_old[_qp] - _yield_stress;
     120      919624 :   _plastic_strain[_qp] = _plastic_strain_old[_qp];
     121      919624 : }
     122             : 
     123             : template <bool is_ad>
     124             : GenericReal<is_ad>
     125     2612936 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeResidual(
     126             :     const GenericReal<is_ad> & effective_trial_stress, const GenericReal<is_ad> & scalar)
     127             : {
     128             :   mooseAssert(_yield_condition != -1.0,
     129             :               "the yield stress was not updated by computeStressInitialize");
     130     2612936 :   if (_yield_condition > 0.0)
     131             :   {
     132     2542869 :     _isotropic_hardening_slope = computeIsotropicHardeningDerivative(scalar);
     133     2542869 :     _isotropic_hardening_variable[_qp] = computeIsotropicHardeningValue(scalar);
     134     2542869 :     _kinematic_hardening_variable[_qp] = computeKinematicHardeningValue(scalar);
     135     2542869 :     GenericReal<is_ad> residual = (effective_trial_stress - _kinematic_hardening_variable[_qp] -
     136     2542869 :                                    _isotropic_hardening_variable[_qp] - _yield_stress) /
     137     2542869 :                                       _three_shear_modulus -
     138             :                                   scalar;
     139     2542869 :     return residual;
     140             :   }
     141           0 :   return 0.0;
     142             : }
     143             : 
     144             : template <bool is_ad>
     145             : GenericReal<is_ad>
     146     2612936 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeDerivative(
     147             :     const GenericReal<is_ad> & /*effective_trial_stress*/, const GenericReal<is_ad> & /*scalar*/)
     148             : {
     149     2612936 :   if (_yield_condition > 0.0)
     150     2542869 :     return -1.0 - _isotropic_hardening_slope / _three_shear_modulus;
     151           0 :   return 1.0;
     152             : }
     153             : 
     154             : template <bool is_ad>
     155             : void
     156     1766088 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::iterationFinalize(
     157             :     const GenericReal<is_ad> & scalar)
     158             : {
     159     1766088 :   if (_yield_condition > 0.0)
     160             :   {
     161     1696021 :     _isotropic_hardening_variable[_qp] = computeIsotropicHardeningValue(scalar);
     162     1696021 :     _kinematic_hardening_variable[_qp] = computeKinematicHardeningValue(scalar);
     163             :   }
     164     1766088 : }
     165             : 
     166             : template <bool is_ad>
     167             : void
     168      919624 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeStressFinalize(
     169             :     const GenericRankTwoTensor<is_ad> & plastic_strain_increment)
     170             : {
     171      919624 :   _plastic_strain[_qp] += plastic_strain_increment;
     172      919624 :   this->_backstress[_qp] =
     173      919624 :       this->_backstress_old[_qp] +
     174      919624 :       (2.0 / 3.0) * _kinematic_hardening_modulus * plastic_strain_increment -
     175      919624 :       _gamma * this->_backstress[_qp] * this->_effective_inelastic_strain_increment;
     176      919624 : }
     177             : 
     178             : template <bool is_ad>
     179             : GenericReal<is_ad>
     180     4238890 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeIsotropicHardeningValue(
     181             :     const GenericReal<is_ad> & scalar)
     182             : {
     183             :   using std::exp;
     184             : 
     185     8477780 :   const Real _q = this->template getParam<Real>("q");
     186     8477780 :   const Real _b = this->template getParam<Real>("b");
     187     4238890 :   if (_isotropic_hardening_function)
     188             :   {
     189           0 :     const Real strain_old = this->_effective_inelastic_strain_old[_qp];
     190           0 :     return _isotropic_hardening_function->value(strain_old + scalar) - _yield_stress;
     191             :   }
     192             : 
     193     4238890 :   _isotropic_hardening_variable[_qp] = _q * (1.0 - exp(-_b * scalar));
     194             : 
     195     4238890 :   return (_isotropic_hardening_variable_old[_qp] + _isotropic_hardening_slope * scalar +
     196     4238890 :           _b * (_q - _isotropic_hardening_variable_old[_qp]) *
     197     4238890 :               this->_effective_inelastic_strain_increment);
     198             : }
     199             : 
     200             : template <bool is_ad>
     201             : GenericReal<is_ad>
     202     2542869 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeIsotropicHardeningDerivative(
     203             :     const GenericReal<is_ad> & /*scalar*/)
     204             : {
     205     2542869 :   if (_isotropic_hardening_function)
     206             :   {
     207           0 :     const Real strain_old = this->_effective_inelastic_strain_old[_qp];
     208           0 :     return _isotropic_hardening_function->timeDerivative(strain_old);
     209             :   }
     210     2542869 :   return _isotropic_hardening_constant;
     211             : }
     212             : 
     213             : template <bool is_ad>
     214             : GenericReal<is_ad>
     215     4238890 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeKinematicHardeningValue(
     216             :     const GenericReal<is_ad> & scalar)
     217             : {
     218     4238890 :   _kinematic_hardening_variable[_qp] = _kinematic_hardening_modulus * scalar;
     219     4238890 :   return _kinematic_hardening_variable[_qp];
     220             : }
     221             : 
     222             : template <bool is_ad>
     223             : void
     224      919624 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeYieldStress(
     225             :     const GenericRankFourTensor<is_ad> & /*elasticity_tensor*/)
     226             : {
     227      919624 :   if (_yield_stress_function)
     228             :   {
     229           0 :     static const Moose::GenericType<Point, is_ad> p;
     230           0 :     _yield_stress = _yield_stress_function->value(_temperature[_qp], p);
     231           0 :     if (_yield_stress <= 0.0)
     232           0 :       mooseError("In ",
     233           0 :                  this->_name,
     234             :                  ": The calculated yield stress (",
     235           0 :                  _yield_stress,
     236             :                  ") is less than zero");
     237             :   }
     238      919624 : }
     239             : 
     240             : template class CombinedNonlinearHardeningPlasticityTempl<false>;
     241             : template class CombinedNonlinearHardeningPlasticityTempl<true>;

Generated by: LCOV version 1.14