LCOV - code coverage report
Current view: top level - src/materials - ADMultiplePowerLawCreepStressUpdate.C (source / functions) Hit Total Coverage
Test: idaholab/moose solid_mechanics: #32971 (54bef8) with base c6cf66 Lines: 59 64 92.2 %
Date: 2026-05-29 20:40:07 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : 
      10             : #include "ADMultiplePowerLawCreepStressUpdate.h"
      11             : #include <algorithm>
      12             : 
      13             : registerMooseObject("SolidMechanicsApp", ADMultiplePowerLawCreepStressUpdate);
      14             : 
      15             : InputParameters
      16          98 : ADMultiplePowerLawCreepStressUpdate::validParams()
      17             : {
      18          98 :   InputParameters params = ADRadialReturnCreepStressUpdateBase::validParams();
      19          98 :   params.addClassDescription(
      20             :       "This class uses the stress update material in a radial return isotropic power law creep "
      21             :       "model. This class can be used in conjunction with other creep and plasticity materials "
      22             :       "for more complex simulations.");
      23             : 
      24             :   // Linear strain hardening parameters
      25         196 :   params.addCoupledVar("temperature", "Coupled temperature");
      26         196 :   params.addRequiredParam<std::vector<Real>>("coefficient",
      27             :                                              "Leading coefficient in power-law equation");
      28         196 :   params.addRequiredParam<std::vector<Real>>("n_exponent",
      29             :                                              "Exponent on effective stress in power-law equation");
      30         196 :   params.addRequiredParam<std::vector<Real>>("m_exponent",
      31             :                                              "Exponent on time in power-law equation");
      32         196 :   params.addRequiredParam<std::vector<Real>>("stress_thresholds",
      33             :                                              "Stress intervals to switch creep behavior");
      34         196 :   params.addRequiredParam<std::vector<Real>>("activation_energy", "Activation energy");
      35         196 :   params.addParam<Real>("gas_constant", 8.3143, "Universal gas constant");
      36         196 :   params.addParam<Real>("start_time", 0.0, "Start time (if not zero)");
      37          98 :   return params;
      38           0 : }
      39             : 
      40          73 : ADMultiplePowerLawCreepStressUpdate::ADMultiplePowerLawCreepStressUpdate(
      41          73 :     const InputParameters & parameters)
      42             :   : ADRadialReturnCreepStressUpdateBase(parameters),
      43          73 :     _temperature(isParamValid("temperature") ? &adCoupledValue("temperature") : nullptr),
      44         146 :     _coefficient(getParam<std::vector<Real>>("coefficient")),
      45         146 :     _n_exponent(getParam<std::vector<Real>>("n_exponent")),
      46         146 :     _m_exponent(getParam<std::vector<Real>>("m_exponent")),
      47         146 :     _stress_thresholds(getParam<std::vector<Real>>("stress_thresholds")),
      48         146 :     _activation_energy(getParam<std::vector<Real>>("activation_energy")),
      49         146 :     _gas_constant(getParam<Real>("gas_constant")),
      50         146 :     _start_time(getParam<Real>("start_time")),
      51          73 :     _exponential(1),
      52          73 :     _exp_time(0),
      53          73 :     _stress_index(0),
      54         146 :     _number_of_models(_m_exponent.size())
      55             : {
      56             : 
      57          73 :   if (!std::is_sorted(_stress_thresholds.begin(), _stress_thresholds.end()))
      58           1 :     paramError("stress_thresholds",
      59             :                "Stress thresholds input must be provided in increasing ordered");
      60             : 
      61          72 :   if (_coefficient.size() != _n_exponent.size() || _coefficient.size() != _m_exponent.size() ||
      62             :       _coefficient.size() != _activation_energy.size())
      63           0 :     paramError(
      64             :         "n_exponent",
      65             :         "Inputs to ADMultiplePowerLawCreepStressUpdate creep models must have the same size");
      66             : 
      67          72 :   if (_number_of_models != _stress_thresholds.size() - 1)
      68           0 :     paramError("stress_thresholds",
      69             :                "The number of creep models must be the number of stress thresholds minute. That "
      70             :                "is, one creep model will be valid between two stress thresholds");
      71             : 
      72         192 :   for (unsigned int i = 0; i < _number_of_models; i++)
      73         120 :     if (_start_time < this->_app.getStartTime() && (std::trunc(_m_exponent[i]) != _m_exponent[i]))
      74           0 :       paramError("start_time",
      75             :                  "Start time must be equal to or greater than the Executioner start_time if a "
      76             :                  "non-integer m_exponent is used");
      77          72 : }
      78             : 
      79             : void
      80     3461712 : ADMultiplePowerLawCreepStressUpdate::computeStressInitialize(
      81             :     const ADReal & effective_trial_stress, const ADRankFourTensor & elasticity_tensor)
      82             : {
      83             :   using std::exp;
      84             : 
      85     3461712 :   ADRadialReturnStressUpdate::computeStressInitialize(effective_trial_stress, elasticity_tensor);
      86             : 
      87     3461712 :   _stress_index = stressIndex(effective_trial_stress);
      88             : 
      89     3461712 :   if (_temperature)
      90           0 :     _exponential = exp(-_activation_energy[_stress_index] / (_gas_constant * (*_temperature)[_qp]));
      91             : 
      92     3461712 :   _exp_time = pow(_t - _start_time, _m_exponent[_stress_index]);
      93     3461712 : }
      94             : 
      95             : ADReal
      96    21295546 : ADMultiplePowerLawCreepStressUpdate::computeResidual(const ADReal & effective_trial_stress,
      97             :                                                      const ADReal & scalar)
      98             : {
      99             :   using std::pow;
     100             : 
     101    21295546 :   const ADReal stress_delta = effective_trial_stress - _three_shear_modulus * scalar;
     102    21295546 :   const ADReal creep_rate = _coefficient[_stress_index] *
     103    42591092 :                             pow(stress_delta, _n_exponent[_stress_index]) * _exponential *
     104    21295546 :                             _exp_time;
     105    21295546 :   return creep_rate * _dt - scalar;
     106             : }
     107             : 
     108             : ADReal
     109    21295546 : ADMultiplePowerLawCreepStressUpdate::computeDerivative(const ADReal & effective_trial_stress,
     110             :                                                        const ADReal & scalar)
     111             : {
     112             :   using std::pow;
     113             : 
     114    21295546 :   const ADReal stress_delta = effective_trial_stress - _three_shear_modulus * scalar;
     115             :   const ADReal creep_rate_derivative =
     116    21295546 :       -_coefficient[_stress_index] * _three_shear_modulus * _n_exponent[_stress_index] *
     117    21295546 :       pow(stress_delta, _n_exponent[_stress_index] - 1.0) * _exponential * _exp_time;
     118    42591092 :   return creep_rate_derivative * _dt - 1.0;
     119             : }
     120             : 
     121             : Real
     122      172692 : ADMultiplePowerLawCreepStressUpdate::computeStrainEnergyRateDensity(
     123             :     const ADMaterialProperty<RankTwoTensor> & stress,
     124             :     const ADMaterialProperty<RankTwoTensor> & strain_rate)
     125             : {
     126      172692 :   if (_n_exponent[_stress_index] <= 1)
     127             :     return 0.0;
     128             : 
     129      172692 :   Real creep_factor = _n_exponent[_stress_index] / (_n_exponent[_stress_index] + 1);
     130             : 
     131      345384 :   return MetaPhysicL::raw_value(creep_factor * stress[_qp].doubleContraction((strain_rate)[_qp]));
     132             : }
     133             : 
     134             : bool
     135     3461712 : ADMultiplePowerLawCreepStressUpdate::substeppingCapabilityEnabled()
     136             : {
     137     3461712 :   return this->_use_substepping != ADRadialReturnStressUpdate::SubsteppingType::NONE;
     138             : }
     139             : 
     140             : std::size_t
     141     3461712 : ADMultiplePowerLawCreepStressUpdate::stressIndex(const ADReal & effective_trial_stress)
     142             : {
     143             :   // Check the correct model for *this* radial return
     144             :   std::size_t i = 0;
     145     5105930 :   while (i < _number_of_models - 1 && effective_trial_stress > _stress_thresholds[i + 1])
     146             :     ++i;
     147             : 
     148     3461712 :   return i;
     149             : }

Generated by: LCOV version 1.14