LCOV - code coverage report
Current view: top level - src/materials - CombinedNonlinearHardeningPlasticity.C (source / functions) Hit Total Coverage
Test: idaholab/moose solid_mechanics: f45d79 Lines: 101 125 80.8 %
Date: 2025-07-25 05:00:39 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         192 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::validParams()
      13             : {
      14             :   InputParameters params = RadialReturnBackstressStressUpdateBaseTempl<is_ad>::validParams();
      15         192 :   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         384 :   params.addParam<Real>("q", 0.0, "Saturation value for isotropic hardening (Q in Voce model)");
      19         384 :   params.addParam<Real>("b", 0.0, "Rate constant for isotropic hardening (b in Voce model)");
      20         384 :   params.addParam<FunctionName>("yield_stress_function",
      21             :                                 "Yield stress as a function of temperature");
      22         384 :   params.addParam<Real>("yield_stress", "The point at which plastic strain begins accumulating");
      23         384 :   params.addParam<FunctionName>("isotropic_hardening_function",
      24             :                                 "True stress as a function of plastic strain");
      25         384 :   params.addParam<Real>("isotropic_hardening_constant", "Isotropic hardening slope");
      26         384 :   params.addCoupledVar("temperature", 0.0, "Coupled Temperature");
      27         192 :   params.set<std::string>("effective_inelastic_strain_name") = "effective_plastic_strain";
      28         384 :   params.addParam<Real>("kinematic_hardening_modulus", 0.0, "Kinematic hardening modulus");
      29         384 :   params.addParam<Real>(
      30         384 :       "gamma", 0.0, "The nonlinear hardening parameter (gamma) for back stress evolution");
      31             : 
      32         192 :   return params;
      33           0 : }
      34             : 
      35             : template <bool is_ad>
      36         144 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::CombinedNonlinearHardeningPlasticityTempl(
      37             :     const InputParameters & parameters)
      38             :   : RadialReturnBackstressStressUpdateBaseTempl<is_ad>(parameters),
      39         432 :     _yield_stress_function(this->isParamValid("yield_stress_function")
      40         144 :                                ? &this->getFunction("yield_stress_function")
      41             :                                : nullptr),
      42         576 :     _yield_stress(this->isParamValid("yield_stress") ? this->template getParam<Real>("yield_stress")
      43             :                                                      : 0),
      44         144 :     _isotropic_hardening_constant(
      45         144 :         this->isParamValid("isotropic_hardening_constant")
      46         432 :             ? this->template getParam<Real>("isotropic_hardening_constant")
      47             :             : 0),
      48         144 :     _isotropic_hardening_function(this->isParamValid("isotropic_hardening_function")
      49         144 :                                       ? &this->getFunction("isotropic_hardening_function")
      50             :                                       : nullptr),
      51         144 :     _yield_condition(-1.0), // set to a non-physical value to catch uninitalized yield condition
      52         144 :     _isotropic_hardening_slope(0.0),
      53         144 :     _plastic_strain(
      54         144 :         this->template declareGenericProperty<RankTwoTensor, is_ad>(_base_name + "plastic_strain")),
      55         144 :     _plastic_strain_old(
      56         144 :         this->template getMaterialPropertyOld<RankTwoTensor>(_base_name + "plastic_strain")),
      57         288 :     _kinematic_hardening_modulus(this->template getParam<Real>("kinematic_hardening_modulus")),
      58         288 :     _gamma(this->template getParam<Real>("gamma")),
      59         288 :     _q(this->template getParam<Real>("q")),
      60         288 :     _b(this->template getParam<Real>("b")),
      61         288 :     _isotropic_hardening_variable(this->template declareGenericProperty<Real, is_ad>(
      62             :         _base_name + "isotropic_hardening_variable")),
      63         144 :     _isotropic_hardening_variable_old(
      64         144 :         this->template getMaterialPropertyOld<Real>(_base_name + "isotropic_hardening_variable")),
      65         144 :     _kinematic_hardening_variable(
      66         144 :         this->template declareGenericProperty<Real, is_ad>("kinematic_hardening_variable")),
      67         144 :     _kinematic_hardening_variable_old(
      68         144 :         this->template getMaterialPropertyOld<Real>("kinematic_hardening_variable")),
      69         432 :     _temperature(this->template coupledGenericValue<is_ad>("temperature"))
      70             : {
      71         288 :   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         576 :   if (_yield_stress_function == nullptr && !this->isParamValid("yield_stress"))
      75           0 :     mooseError("Either yield_stress or yield_stress_function must be given");
      76         288 :   if (!parameters.isParamValid("isotropic_hardening_constant") &&
      77         144 :       !this->isParamValid("isotropic_hardening_function"))
      78           0 :     mooseError(
      79             :         "Either isotropic_hardening_constant or isotropic_hardening_function must be defined");
      80         288 :   if (parameters.isParamSetByUser("isotropic_hardening_constant") &&
      81         432 :       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         144 : }
      86             : 
      87             : template <bool is_ad>
      88             : void
      89         576 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::initQpStatefulProperties()
      90             : {
      91         576 :   _isotropic_hardening_variable[_qp] = 0.0;
      92         576 :   _kinematic_hardening_variable[_qp] = 0.0;
      93         576 :   _plastic_strain[_qp].zero();
      94         576 :   RadialReturnBackstressStressUpdateBaseTempl<is_ad>::initQpStatefulProperties();
      95         576 : }
      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     1323840 : 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     1323840 :   computeYieldStress(elasticity_tensor);
     118     1323840 :   _yield_condition =
     119     1323840 :       effective_trial_stress - _isotropic_hardening_variable_old[_qp] - _yield_stress;
     120     1323840 :   _plastic_strain[_qp] = _plastic_strain_old[_qp];
     121     1323840 : }
     122             : 
     123             : template <bool is_ad>
     124             : GenericReal<is_ad>
     125     3712528 : 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     3712528 :   if (_yield_condition > 0.0)
     131             :   {
     132     3587824 :     _isotropic_hardening_slope = computeIsotropicHardeningDerivative(scalar);
     133     3587824 :     _isotropic_hardening_variable[_qp] = computeIsotropicHardeningValue(scalar);
     134     3587824 :     _kinematic_hardening_variable[_qp] = computeKinematicHardeningValue(scalar);
     135     3587824 :     GenericReal<is_ad> residual = (effective_trial_stress - _kinematic_hardening_variable[_qp] -
     136     3587824 :                                    _isotropic_hardening_variable[_qp] - _yield_stress) /
     137     3587824 :                                       _three_shear_modulus -
     138             :                                   scalar;
     139     3587824 :     return residual;
     140             :   }
     141           0 :   return 0.0;
     142             : }
     143             : 
     144             : template <bool is_ad>
     145             : GenericReal<is_ad>
     146     3712528 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeDerivative(
     147             :     const GenericReal<is_ad> & /*effective_trial_stress*/, const GenericReal<is_ad> & /*scalar*/)
     148             : {
     149     3712528 :   if (_yield_condition > 0.0)
     150     3587824 :     return -1.0 - _isotropic_hardening_slope / _three_shear_modulus;
     151           0 :   return 1.0;
     152             : }
     153             : 
     154             : template <bool is_ad>
     155             : void
     156     2517896 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::iterationFinalize(
     157             :     const GenericReal<is_ad> & scalar)
     158             : {
     159     2517896 :   if (_yield_condition > 0.0)
     160             :   {
     161     2393192 :     _isotropic_hardening_variable[_qp] = computeIsotropicHardeningValue(scalar);
     162     2393192 :     _kinematic_hardening_variable[_qp] = computeKinematicHardeningValue(scalar);
     163             :   }
     164     2517896 : }
     165             : 
     166             : template <bool is_ad>
     167             : void
     168     1323840 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeStressFinalize(
     169             :     const GenericRankTwoTensor<is_ad> & plastic_strain_increment)
     170             : {
     171     1323840 :   _plastic_strain[_qp] += plastic_strain_increment;
     172     1323840 :   this->_backstress[_qp] =
     173     1323840 :       this->_backstress_old[_qp] +
     174     1323840 :       (2.0 / 3.0) * _kinematic_hardening_modulus * plastic_strain_increment -
     175     1323840 :       _gamma * this->_backstress[_qp] * this->_effective_inelastic_strain_increment;
     176     1323840 : }
     177             : 
     178             : template <bool is_ad>
     179             : GenericReal<is_ad>
     180     5981016 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeIsotropicHardeningValue(
     181             :     const GenericReal<is_ad> & scalar)
     182             : {
     183    11962032 :   const Real _q = this->template getParam<Real>("q");
     184    11962032 :   const Real _b = this->template getParam<Real>("b");
     185     5981016 :   if (_isotropic_hardening_function)
     186             :   {
     187           0 :     const Real strain_old = this->_effective_inelastic_strain_old[_qp];
     188           0 :     return _isotropic_hardening_function->value(strain_old + scalar) - _yield_stress;
     189             :   }
     190             : 
     191     5981016 :   _isotropic_hardening_variable[_qp] = _q * (1.0 - std::exp(-_b * scalar));
     192             : 
     193     5981016 :   return (_isotropic_hardening_variable_old[_qp] + _isotropic_hardening_slope * scalar +
     194     5981016 :           _b * (_q - _isotropic_hardening_variable_old[_qp]) *
     195     5981016 :               this->_effective_inelastic_strain_increment);
     196             : }
     197             : 
     198             : template <bool is_ad>
     199             : GenericReal<is_ad>
     200     3587824 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeIsotropicHardeningDerivative(
     201             :     const GenericReal<is_ad> & /*scalar*/)
     202             : {
     203     3587824 :   if (_isotropic_hardening_function)
     204             :   {
     205           0 :     const Real strain_old = this->_effective_inelastic_strain_old[_qp];
     206           0 :     return _isotropic_hardening_function->timeDerivative(strain_old);
     207             :   }
     208     3587824 :   return _isotropic_hardening_constant;
     209             : }
     210             : 
     211             : template <bool is_ad>
     212             : GenericReal<is_ad>
     213     5981016 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeKinematicHardeningValue(
     214             :     const GenericReal<is_ad> & scalar)
     215             : {
     216     5981016 :   _kinematic_hardening_variable[_qp] = _kinematic_hardening_modulus * scalar;
     217     5981016 :   return _kinematic_hardening_variable[_qp];
     218             : }
     219             : 
     220             : template <bool is_ad>
     221             : void
     222     1323840 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeYieldStress(
     223             :     const GenericRankFourTensor<is_ad> & /*elasticity_tensor*/)
     224             : {
     225     1323840 :   if (_yield_stress_function)
     226             :   {
     227           0 :     static const Moose::GenericType<Point, is_ad> p;
     228           0 :     _yield_stress = _yield_stress_function->value(_temperature[_qp], p);
     229           0 :     if (_yield_stress <= 0.0)
     230           0 :       mooseError("In ",
     231           0 :                  this->_name,
     232             :                  ": The calculated yield stress (",
     233           0 :                  _yield_stress,
     234             :                  ") is less than zero");
     235             :   }
     236     1323840 : }
     237             : 
     238             : template class CombinedNonlinearHardeningPlasticityTempl<false>;
     239             : template class CombinedNonlinearHardeningPlasticityTempl<true>;

Generated by: LCOV version 1.14