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