Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://www.mooseframework.org 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("TensorMechanicsApp", ADMultiplePowerLawCreepStressUpdate); 14 : 15 : InputParameters 16 74 : ADMultiplePowerLawCreepStressUpdate::validParams() 17 : { 18 74 : InputParameters params = ADRadialReturnCreepStressUpdateBase::validParams(); 19 74 : 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 148 : params.addCoupledVar("temperature", "Coupled temperature"); 26 148 : params.addRequiredParam<std::vector<Real>>("coefficient", 27 : "Leading coefficient in power-law equation"); 28 148 : params.addRequiredParam<std::vector<Real>>("n_exponent", 29 : "Exponent on effective stress in power-law equation"); 30 148 : params.addRequiredParam<std::vector<Real>>("m_exponent", 31 : "Exponent on time in power-law equation"); 32 148 : params.addRequiredParam<std::vector<Real>>("stress_thresholds", 33 : "Stress intervals to switch creep behavior"); 34 148 : params.addRequiredParam<std::vector<Real>>("activation_energy", "Activation energy"); 35 148 : params.addParam<Real>("gas_constant", 8.3143, "Universal gas constant"); 36 148 : params.addParam<Real>("start_time", 0.0, "Start time (if not zero)"); 37 74 : return params; 38 0 : } 39 : 40 55 : ADMultiplePowerLawCreepStressUpdate::ADMultiplePowerLawCreepStressUpdate( 41 55 : const InputParameters & parameters) 42 : : ADRadialReturnCreepStressUpdateBase(parameters), 43 55 : _temperature(isParamValid("temperature") ? &adCoupledValue("temperature") : nullptr), 44 110 : _coefficient(getParam<std::vector<Real>>("coefficient")), 45 110 : _n_exponent(getParam<std::vector<Real>>("n_exponent")), 46 110 : _m_exponent(getParam<std::vector<Real>>("m_exponent")), 47 110 : _stress_thresholds(getParam<std::vector<Real>>("stress_thresholds")), 48 110 : _activation_energy(getParam<std::vector<Real>>("activation_energy")), 49 110 : _gas_constant(getParam<Real>("gas_constant")), 50 110 : _start_time(getParam<Real>("start_time")), 51 55 : _exponential(1), 52 55 : _exp_time(0), 53 55 : _stress_index(0), 54 110 : _number_of_models(_m_exponent.size()) 55 : { 56 : 57 55 : 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 54 : 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 54 : 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 144 : for (unsigned int i = 0; i < _number_of_models; i++) 73 90 : 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 54 : } 78 : 79 : void 80 2256988 : ADMultiplePowerLawCreepStressUpdate::computeStressInitialize( 81 : const ADReal & effective_trial_stress, const ADRankFourTensor & elasticity_tensor) 82 : { 83 2256988 : ADRadialReturnStressUpdate::computeStressInitialize(effective_trial_stress, elasticity_tensor); 84 : 85 2256988 : _stress_index = stressIndex(effective_trial_stress); 86 : 87 2256988 : if (_temperature) 88 : _exponential = 89 0 : std::exp(-_activation_energy[_stress_index] / (_gas_constant * (*_temperature)[_qp])); 90 : 91 2256988 : _exp_time = std::pow(_t - _start_time, _m_exponent[_stress_index]); 92 2256988 : } 93 : 94 : ADReal 95 13853872 : ADMultiplePowerLawCreepStressUpdate::computeResidual(const ADReal & effective_trial_stress, 96 : const ADReal & scalar) 97 : { 98 13853872 : const ADReal stress_delta = effective_trial_stress - _three_shear_modulus * scalar; 99 13853872 : const ADReal creep_rate = _coefficient[_stress_index] * 100 27707744 : std::pow(stress_delta, _n_exponent[_stress_index]) * _exponential * 101 13853872 : _exp_time; 102 13853872 : return creep_rate * _dt - scalar; 103 : } 104 : 105 : ADReal 106 13853872 : ADMultiplePowerLawCreepStressUpdate::computeDerivative(const ADReal & effective_trial_stress, 107 : const ADReal & scalar) 108 : { 109 13853872 : const ADReal stress_delta = effective_trial_stress - _three_shear_modulus * scalar; 110 : const ADReal creep_rate_derivative = 111 13853872 : -_coefficient[_stress_index] * _three_shear_modulus * _n_exponent[_stress_index] * 112 13853872 : std::pow(stress_delta, _n_exponent[_stress_index] - 1.0) * _exponential * _exp_time; 113 27707744 : return creep_rate_derivative * _dt - 1.0; 114 : } 115 : 116 : Real 117 113688 : ADMultiplePowerLawCreepStressUpdate::computeStrainEnergyRateDensity( 118 : const ADMaterialProperty<RankTwoTensor> & stress, 119 : const ADMaterialProperty<RankTwoTensor> & strain_rate) 120 : { 121 113688 : if (_n_exponent[_stress_index] <= 1) 122 : return 0.0; 123 : 124 113688 : Real creep_factor = _n_exponent[_stress_index] / (_n_exponent[_stress_index] + 1); 125 : 126 227376 : return MetaPhysicL::raw_value(creep_factor * stress[_qp].doubleContraction((strain_rate)[_qp])); 127 : } 128 : 129 : bool 130 2256988 : ADMultiplePowerLawCreepStressUpdate::substeppingCapabilityEnabled() 131 : { 132 2256988 : return this->_use_substepping != ADRadialReturnStressUpdate::SubsteppingType::NONE; 133 : } 134 : 135 : std::size_t 136 2256988 : ADMultiplePowerLawCreepStressUpdate::stressIndex(const ADReal & effective_trial_stress) 137 : { 138 : // Check the correct model for *this* radial return 139 : std::size_t i = 0; 140 3326774 : while (i < _number_of_models - 1 && effective_trial_stress > _stress_thresholds[i + 1]) 141 : ++i; 142 : 143 2256988 : return i; 144 : }