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 "PlasticTruss.h" 11 : #include "Function.h" 12 : #include "MooseException.h" 13 : #include "MathUtils.h" 14 : 15 : registerMooseObject("SolidMechanicsApp", PlasticTruss); 16 : 17 : InputParameters 18 148 : PlasticTruss::validParams() 19 : { 20 148 : InputParameters params = LinearElasticTruss::validParams(); 21 148 : params.addClassDescription( 22 : "Computes the stress and strain for a truss element with plastic behavior defined by either " 23 : "linear hardening or a user-defined hardening function."); 24 296 : params.addRequiredParam<Real>("yield_stress", 25 : "Yield stress after which plastic strain starts accumulating"); 26 296 : params.addParam<Real>("hardening_constant", 0.0, "Hardening slope"); 27 296 : params.addParam<FunctionName>("hardening_function", 28 : "Engineering stress as a function of plastic strain"); 29 296 : params.addParam<Real>( 30 296 : "absolute_tolerance", 1e-10, "Absolute convergence tolerance for Newton iteration"); 31 296 : params.addParam<Real>( 32 296 : "relative_tolerance", 1e-8, "Relative convergence tolerance for Newton iteration"); 33 148 : return params; 34 0 : } 35 : 36 112 : PlasticTruss::PlasticTruss(const InputParameters & parameters) 37 : : LinearElasticTruss(parameters), 38 112 : _yield_stress(getParam<Real>("yield_stress")), // Read from input file 39 224 : _hardening_constant(getParam<Real>("hardening_constant")), 40 262 : _hardening_function(isParamValid("hardening_function") ? &getFunction("hardening_function") 41 : : NULL), 42 112 : _absolute_tolerance(parameters.get<Real>("absolute_tolerance")), 43 112 : _relative_tolerance(parameters.get<Real>("relative_tolerance")), 44 224 : _total_stretch_old(getMaterialPropertyOld<Real>(_base_name + "total_stretch")), 45 112 : _plastic_strain(declareProperty<Real>(_base_name + "plastic_stretch")), 46 224 : _plastic_strain_old(getMaterialPropertyOld<Real>(_base_name + "plastic_stretch")), 47 224 : _stress_old(getMaterialPropertyOld<Real>(_base_name + "axial_stress")), 48 112 : _hardening_variable(declareProperty<Real>(_base_name + "hardening_variable")), 49 224 : _hardening_variable_old(getMaterialPropertyOld<Real>(_base_name + "hardening_variable")), 50 112 : _max_its(1000) 51 : { 52 224 : if (!parameters.isParamSetByUser("hardening_constant") && !isParamValid("hardening_function")) 53 2 : mooseError("PlasticTruss: Either hardening_constant or hardening_function must be defined"); 54 : 55 258 : if (parameters.isParamSetByUser("hardening_constant") && isParamValid("hardening_function")) 56 2 : mooseError("PlasticTruss: Only the hardening_constant or only the hardening_function can be " 57 : "defined but not both"); 58 108 : } 59 : 60 : void 61 96 : PlasticTruss::initQpStatefulProperties() 62 : { 63 96 : TrussMaterial::initQpStatefulProperties(); 64 96 : _plastic_strain[_qp] = 0.0; 65 96 : _hardening_variable[_qp] = 0.0; 66 96 : } 67 : 68 : void 69 1968 : PlasticTruss::computeQpStrain() 70 : { 71 1968 : _total_stretch[_qp] = _current_length / _origin_length - 1.0; 72 1968 : } 73 : 74 : void 75 1968 : PlasticTruss::computeQpStress() 76 : { 77 1968 : Real strain_increment = _total_stretch[_qp] - _total_stretch_old[_qp]; 78 1968 : Real trial_stress = _stress_old[_qp] + _youngs_modulus[_qp] * strain_increment; 79 : 80 1968 : _hardening_variable[_qp] = _hardening_variable_old[_qp]; 81 1968 : _plastic_strain[_qp] = _plastic_strain_old[_qp]; 82 : 83 1968 : Real yield_condition = std::abs(trial_stress) - _hardening_variable[_qp] - _yield_stress; 84 : Real iteration = 0; 85 : Real plastic_strain_increment = 0.0; 86 : Real elastic_strain_increment = strain_increment; 87 : 88 1968 : if (yield_condition > 0.0) 89 : { 90 : Real residual = std::abs(trial_stress) - _hardening_variable[_qp] - _yield_stress - 91 792 : _youngs_modulus[_qp] * plastic_strain_increment; 92 : 93 : Real reference_residual = 94 792 : std::abs(trial_stress) - _youngs_modulus[_qp] * plastic_strain_increment; 95 : 96 2640 : while (std::abs(residual) > _absolute_tolerance || 97 792 : std::abs(residual / reference_residual) > _relative_tolerance) 98 : { 99 1848 : _hardening_variable[_qp] = computeHardeningValue(plastic_strain_increment); 100 1848 : Real hardening_slope = computeHardeningDerivative(plastic_strain_increment); 101 : 102 1848 : Real scalar = (std::abs(trial_stress) - _hardening_variable[_qp] - _yield_stress - 103 1848 : _youngs_modulus[_qp] * plastic_strain_increment) / 104 1848 : (_youngs_modulus[_qp] + hardening_slope); 105 1848 : plastic_strain_increment += scalar; 106 : 107 1848 : residual = std::abs(trial_stress) - _hardening_variable[_qp] - _yield_stress - 108 1848 : _youngs_modulus[_qp] * plastic_strain_increment; 109 : 110 1848 : reference_residual = std::abs(trial_stress) - _youngs_modulus[_qp] * plastic_strain_increment; 111 : 112 1848 : ++iteration; 113 1848 : if (iteration > _max_its) // not converging 114 0 : throw MooseException("PlasticTruss: Plasticity model did not converge"); 115 : } 116 792 : plastic_strain_increment *= MathUtils::sign(trial_stress); 117 792 : _plastic_strain[_qp] += plastic_strain_increment; 118 792 : elastic_strain_increment = strain_increment - plastic_strain_increment; 119 : } 120 1968 : _elastic_stretch[_qp] = _total_stretch[_qp] - _plastic_strain[_qp]; 121 1968 : _axial_stress[_qp] = _stress_old[_qp] + _youngs_modulus[_qp] * elastic_strain_increment; 122 1968 : } 123 : 124 : Real 125 1848 : PlasticTruss::computeHardeningValue(Real scalar) 126 : { 127 1848 : if (_hardening_function) 128 : { 129 1056 : const Real strain_old = _plastic_strain_old[_qp]; 130 1056 : return _hardening_function->value(std::abs(strain_old) + scalar) - _yield_stress; 131 : } 132 : 133 792 : return _hardening_variable_old[_qp] + _hardening_constant * scalar; 134 : } 135 : 136 : Real 137 1848 : PlasticTruss::computeHardeningDerivative(Real /*scalar*/) 138 : { 139 1848 : if (_hardening_function) 140 : { 141 1056 : const Real strain_old = _plastic_strain_old[_qp]; 142 1056 : return _hardening_function->timeDerivative(std::abs(strain_old)); 143 : } 144 : 145 792 : return _hardening_constant; 146 : }