LCOV - code coverage report
Current view: top level - src/materials - PlasticTruss.C (source / functions) Hit Total Coverage
Test: idaholab/moose solid_mechanics: f45d79 Lines: 75 77 97.4 %
Date: 2025-07-25 05:00:39 Functions: 7 7 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 "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             : }

Generated by: LCOV version 1.14