LCOV - code coverage report
Current view: top level - src/materials - ComputeMultipleInelasticStress.C (source / functions) Hit Total Coverage
Test: idaholab/moose solid_mechanics: f45d79 Lines: 55 70 78.6 %
Date: 2025-07-25 05:00:39 Functions: 4 4 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 "ComputeMultipleInelasticStress.h"
      11             : 
      12             : #include "StressUpdateBase.h"
      13             : #include "MooseException.h"
      14             : #include "DamageBase.h"
      15             : #include "libmesh/int_range.h"
      16             : 
      17             : registerMooseObject("SolidMechanicsApp", ComputeMultipleInelasticStress);
      18             : 
      19             : InputParameters
      20        5858 : ComputeMultipleInelasticStress::validParams()
      21             : {
      22        5858 :   InputParameters params = ComputeMultipleInelasticStressBase::validParams();
      23       11716 :   params.addRequiredParam<std::vector<MaterialName>>(
      24             :       "inelastic_models",
      25             :       "The material objects to use to calculate stress and inelastic strains. "
      26             :       "Note: specify creep models first and plasticity models second.");
      27        5858 :   return params;
      28           0 : }
      29             : 
      30        4388 : ComputeMultipleInelasticStress::ComputeMultipleInelasticStress(const InputParameters & parameters)
      31        4388 :   : ComputeMultipleInelasticStressBase(parameters)
      32             : {
      33        4388 : }
      34             : 
      35             : std::vector<MaterialName>
      36        4194 : ComputeMultipleInelasticStress::getInelasticModelNames()
      37             : {
      38       12582 :   return getParam<std::vector<MaterialName>>("inelastic_models");
      39             : }
      40             : 
      41             : void
      42     1526416 : ComputeMultipleInelasticStress::updateQpState(RankTwoTensor & elastic_strain_increment,
      43             :                                               RankTwoTensor & combined_inelastic_strain_increment)
      44             : {
      45     1526416 :   if (_internal_solve_full_iteration_history == true)
      46             :   {
      47           0 :     _console << std::endl
      48           0 :              << "iteration output for ComputeMultipleInelasticStress solve:"
      49           0 :              << " time=" << _t << " int_pt=" << _qp << std::endl;
      50             :   }
      51             :   Real l2norm_delta_stress;
      52             :   Real first_l2norm_delta_stress = 1.0;
      53     1526416 :   unsigned int counter = 0;
      54             : 
      55             :   std::vector<RankTwoTensor> inelastic_strain_increment;
      56     1526416 :   inelastic_strain_increment.resize(_num_models);
      57             : 
      58     4579248 :   for (const auto i_rmm : index_range(_models))
      59             :     inelastic_strain_increment[i_rmm].zero();
      60             : 
      61     1526416 :   RankTwoTensor stress_max, stress_min;
      62             : 
      63             :   do
      64             :   {
      65    18584148 :     for (const auto i_rmm : index_range(_models))
      66             :     {
      67    12389432 :       _models[i_rmm]->setQp(_qp);
      68             : 
      69             :       // initially assume the strain is completely elastic
      70    12389432 :       elastic_strain_increment = _strain_increment[_qp];
      71             :       // and subtract off all inelastic strain increments calculated so far
      72             :       // except the one that we're about to calculate
      73    37168296 :       for (const auto j_rmm : make_range(_num_models))
      74    24778864 :         if (i_rmm != j_rmm)
      75    12389432 :           elastic_strain_increment -= inelastic_strain_increment[j_rmm];
      76             : 
      77             :       // form the trial stress, with the check for changed elasticity constants
      78    12389432 :       if (_is_elasticity_tensor_guaranteed_isotropic || !_perform_finite_strain_rotations)
      79    12383672 :         _stress[_qp] =
      80    12383672 :             _elasticity_tensor[_qp] * (_elastic_strain_old[_qp] + elastic_strain_increment);
      81             :       else
      82             :       {
      83        5760 :         if (_damage_model)
      84           0 :           _stress[_qp] = _undamaged_stress_old + _elasticity_tensor[_qp] * elastic_strain_increment;
      85             :         else
      86        5760 :           _stress[_qp] = _stress_old[_qp] + _elasticity_tensor[_qp] * elastic_strain_increment;
      87             :       }
      88             : 
      89             :       // given a trial stress (_stress[_qp]) and a strain increment (elastic_strain_increment)
      90             :       // let the i^th model produce an admissible stress (as _stress[_qp]), and decompose
      91             :       // the strain increment into an elastic part (elastic_strain_increment) and an
      92             :       // inelastic part (inelastic_strain_increment[i_rmm])
      93    12389432 :       computeAdmissibleState(i_rmm,
      94             :                              elastic_strain_increment,
      95             :                              inelastic_strain_increment[i_rmm],
      96             :                              _consistent_tangent_operator[i_rmm]);
      97             : 
      98    12389432 :       if (i_rmm == 0)
      99             :       {
     100     6194716 :         stress_max = _stress[_qp];
     101     6194716 :         stress_min = _stress[_qp];
     102             :       }
     103             :       else
     104             :       {
     105    24778864 :         for (const auto i : make_range(Moose::dim))
     106    74336592 :           for (const auto j : make_range(Moose::dim))
     107    55752444 :             if (_stress[_qp](i, j) > stress_max(i, j))
     108    23755300 :               stress_max(i, j) = _stress[_qp](i, j);
     109    31997144 :             else if (stress_min(i, j) > _stress[_qp](i, j))
     110    18819504 :               stress_min(i, j) = _stress[_qp](i, j);
     111             :       }
     112             :     }
     113             : 
     114             :     // now check convergence in the stress:
     115             :     // once the change in stress is within tolerance after each recompute material
     116             :     // consider the stress to be converged
     117     6194716 :     l2norm_delta_stress = (stress_max - stress_min).L2norm();
     118     6194716 :     if (counter == 0 && l2norm_delta_stress > 0.0)
     119             :       first_l2norm_delta_stress = l2norm_delta_stress;
     120             : 
     121     6194716 :     if (_internal_solve_full_iteration_history == true)
     122             :     {
     123           0 :       _console << "stress iteration number = " << counter << "\n"
     124           0 :                << " relative l2 norm delta stress = "
     125           0 :                << (0 == first_l2norm_delta_stress ? 0
     126           0 :                                                   : l2norm_delta_stress / first_l2norm_delta_stress)
     127           0 :                << "\n"
     128           0 :                << " stress convergence relative tolerance = " << _relative_tolerance << "\n"
     129           0 :                << " absolute l2 norm delta stress = " << l2norm_delta_stress << "\n"
     130           0 :                << " stress convergence absolute tolerance = " << _absolute_tolerance << std::endl;
     131             :     }
     132     6194716 :     ++counter;
     133     6191836 :   } while (counter < _max_iterations && l2norm_delta_stress > _absolute_tolerance &&
     134    10877400 :            (l2norm_delta_stress / first_l2norm_delta_stress) > _relative_tolerance &&
     135     4668300 :            _num_models != 1);
     136             : 
     137     1526416 :   if (counter == _max_iterations && l2norm_delta_stress > _absolute_tolerance &&
     138           0 :       (l2norm_delta_stress / first_l2norm_delta_stress) > _relative_tolerance)
     139           0 :     throw MooseException("Max stress iteration hit during ComputeMultipleInelasticStress solve!");
     140             : 
     141             :   combined_inelastic_strain_increment.zero();
     142     4579248 :   for (const auto i_rmm : make_range(_num_models))
     143             :     combined_inelastic_strain_increment +=
     144     3052832 :         _inelastic_weights[i_rmm] * inelastic_strain_increment[i_rmm];
     145             : 
     146     1526416 :   if (_fe_problem.currentlyComputingJacobian())
     147      139104 :     computeQpJacobianMult();
     148             : 
     149     1526416 :   _material_timestep_limit[_qp] = 0.0;
     150     4579248 :   for (const auto i_rmm : make_range(_num_models))
     151     3052832 :     _material_timestep_limit[_qp] += 1.0 / _models[i_rmm]->computeTimeStepLimit();
     152             : 
     153     1526416 :   if (MooseUtils::absoluteFuzzyEqual(_material_timestep_limit[_qp], 0.0))
     154      116594 :     _material_timestep_limit[_qp] = std::numeric_limits<Real>::max();
     155             :   else
     156     1409822 :     _material_timestep_limit[_qp] = 1.0 / _material_timestep_limit[_qp];
     157     1526416 : }

Generated by: LCOV version 1.14