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