LCOV - code coverage report
Current view: top level - src/materials - RadialReturnStressUpdate.C (source / functions) Hit Total Coverage
Test: idaholab/moose solid_mechanics: #31613 (c7d555) with base 7323e9 Lines: 173 181 95.6 %
Date: 2025-11-06 14:18:25 Functions: 25 28 89.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : 
       2             : //* This file is part of the MOOSE framework
       3             : //* https://mooseframework.inl.gov
       4             : //*
       5             : //* All rights reserved, see COPYRIGHT for full restrictions
       6             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       7             : //*
       8             : //* Licensed under LGPL 2.1, please see LICENSE for details
       9             : //* https://www.gnu.org/licenses/lgpl-2.1.html
      10             : 
      11             : #include "RadialReturnStressUpdate.h"
      12             : 
      13             : #include "MooseMesh.h"
      14             : #include "ElasticityTensorTools.h"
      15             : 
      16             : template <bool is_ad>
      17             : InputParameters
      18        5390 : RadialReturnStressUpdateTempl<is_ad>::validParams()
      19             : {
      20        5390 :   InputParameters params = StressUpdateBaseTempl<is_ad>::validParams();
      21        5390 :   params.addClassDescription("Calculates the effective inelastic strain increment required to "
      22             :                              "return the isotropic stress state to a J2 yield surface.  This class "
      23             :                              "is intended to be a parent class for classes with specific "
      24             :                              "constitutive models.");
      25        5390 :   params += SingleVariableReturnMappingSolutionTempl<is_ad>::validParams();
      26       10780 :   params.addParam<Real>("max_inelastic_increment",
      27       10780 :                         1e-4,
      28             :                         "The maximum inelastic strain increment allowed in a time step");
      29       10780 :   params.addRequiredParam<std::string>(
      30             :       "effective_inelastic_strain_name",
      31             :       "Name of the material property that stores the effective inelastic strain");
      32       10780 :   params.addParam<bool>("use_substep", false, "Whether to use substepping");
      33             : 
      34       10780 :   MooseEnum substeppingType("NONE ERROR_BASED INCREMENT_BASED", "NONE");
      35       10780 :   substeppingType.addDocumentation("NONE", "Do not use substepping");
      36       10780 :   substeppingType.addDocumentation(
      37             :       "ERROR_BASED",
      38             :       "Use substepping with a substep size that will yield, at most, the creep numerical "
      39             :       "integration error given by substep_strain_tolerance.");
      40       10780 :   substeppingType.addDocumentation(
      41             :       "INCREMENT_BASED",
      42             :       "Use substepping with a substep size that will keep each inelastic strain increment below "
      43             :       "the maximum inelastic strain increment allowed in a time step.");
      44       10780 :   params.addParam<MooseEnum>(
      45             :       "use_substepping", substeppingType, "Whether and how to use substepping");
      46       10780 :   params.addParam<bool>(
      47             :       "adaptive_substepping",
      48       10780 :       false,
      49             :       "Use adaptive substepping, where the number of substeps is successively doubled until the "
      50             :       "return mapping model successfully converges or the maximum number of substeps is reached. ");
      51             : 
      52       16170 :   params.addDeprecatedParam<bool>(
      53       10780 :       "use_substep", false, "Whether to use substepping", "Use `use_substepping` instead");
      54       10780 :   params.addParam<Real>("substep_strain_tolerance",
      55       10780 :                         0.1,
      56             :                         "Maximum ratio of the initial elastic strain increment at start of the "
      57             :                         "return mapping solve to the maximum inelastic strain allowable in a "
      58             :                         "single substep. Reduce this value to increase the number of substeps");
      59       10780 :   params.addParam<bool>("apply_strain", true, "Flag to apply strain. Used for testing.");
      60       10780 :   params.addParamNamesToGroup(
      61             :       "effective_inelastic_strain_name substep_strain_tolerance apply_strain", "Advanced");
      62       10780 :   params.addParam<bool>("use_substep_integration_error",
      63       10780 :                         false,
      64             :                         "If true, it establishes a substep size that will yield, at most,"
      65             :                         "the creep numerical integration error given by substep_strain_tolerance.");
      66       10780 :   params.addParam<unsigned>("maximum_number_substeps",
      67       10780 :                             25,
      68             :                             "The maximum number of substeps allowed before cutting the time step.");
      69        5390 :   return params;
      70        5390 : }
      71             : 
      72             : template <bool is_ad>
      73        4045 : RadialReturnStressUpdateTempl<is_ad>::RadialReturnStressUpdateTempl(
      74             :     const InputParameters & parameters)
      75             :   : StressUpdateBaseTempl<is_ad>(parameters),
      76             :     SingleVariableReturnMappingSolutionTempl<is_ad>(parameters),
      77        5538 :     _effective_inelastic_strain(this->template declareGenericProperty<Real, is_ad>(
      78        4045 :         this->_base_name +
      79             :         this->template getParam<std::string>("effective_inelastic_strain_name"))),
      80       13628 :     _effective_inelastic_strain_old(this->template getMaterialPropertyOld<Real>(
      81             :         this->_base_name +
      82             :         this->template getParam<std::string>("effective_inelastic_strain_name"))),
      83        8090 :     _max_inelastic_increment(this->template getParam<Real>("max_inelastic_increment")),
      84        8090 :     _substep_tolerance(this->template getParam<Real>("substep_strain_tolerance")),
      85        4045 :     _identity_two(RankTwoTensor::initIdentity),
      86        4045 :     _identity_symmetric_four(RankFourTensor::initIdentitySymmetricFour),
      87        4045 :     _deviatoric_projection_four(_identity_symmetric_four -
      88        4045 :                                 _identity_two.outerProduct(_identity_two) / 3.0),
      89        8090 :     _apply_strain(this->template getParam<bool>("apply_strain")),
      90        4045 :     _use_substepping(
      91        4045 :         this->template getParam<MooseEnum>("use_substepping").template getEnum<SubsteppingType>()),
      92        8090 :     _adaptive_substepping(this->template getParam<bool>("adaptive_substepping")),
      93       12135 :     _maximum_number_substeps(this->template getParam<unsigned>("maximum_number_substeps"))
      94             : {
      95        8090 :   if (this->_pars.isParamSetByUser("use_substep"))
      96             :   {
      97          12 :     if (this->_pars.isParamSetByUser("use_substepping"))
      98           0 :       this->paramError("use_substep",
      99             :                        "Remove this parameter and just keep `use_substepping` in the input");
     100             : 
     101           6 :     if (parameters.get<bool>("use_substep"))
     102             :     {
     103           6 :       if (parameters.get<bool>("use_substep_integration_error"))
     104           0 :         _use_substepping = SubsteppingType::ERROR_BASED;
     105             :       else
     106           6 :         _use_substepping = SubsteppingType::INCREMENT_BASED;
     107             :     }
     108             :   }
     109             : 
     110        8090 :   if (this->_pars.isParamSetByUser("maximum_number_substeps") &&
     111          66 :       _use_substepping == SubsteppingType::NONE)
     112           0 :     this->paramError(
     113             :         "maximum_number_substeps",
     114             :         "The parameter maximum_number_substeps can only be used when the substepping option "
     115             :         "(use_substepping) is not set to NONE");
     116             : 
     117        4045 :   if (_adaptive_substepping && _use_substepping == SubsteppingType::NONE)
     118           0 :     this->paramError(
     119             :         "adaptive_substepping",
     120             :         "The parameter adaptive_substepping can only be used when the substepping option "
     121             :         "(use_substepping) is not set to NONE");
     122        4045 : }
     123             : 
     124             : template <bool is_ad>
     125             : void
     126       26376 : RadialReturnStressUpdateTempl<is_ad>::initQpStatefulProperties()
     127             : {
     128       75232 :   _effective_inelastic_strain[_qp] = 0.0;
     129       26376 : }
     130             : 
     131             : template <bool is_ad>
     132             : void
     133    29766204 : RadialReturnStressUpdateTempl<is_ad>::computeStressInitialize(
     134             :     const GenericReal<is_ad> & /*effective_trial_stress*/,
     135             :     const GenericRankFourTensor<is_ad> & elasticity_tensor)
     136             : {
     137             :   // Set the value of 3 * shear modulus for use as a reference residual value
     138    86597218 :   _three_shear_modulus = 3.0 * ElasticityTensorTools::getIsotropicShearModulus(elasticity_tensor);
     139    29766204 : }
     140             : 
     141             : template <bool is_ad>
     142             : void
     143      549504 : RadialReturnStressUpdateTempl<is_ad>::propagateQpStatefulPropertiesRadialReturn()
     144             : {
     145      549504 :   _effective_inelastic_strain[_qp] = _effective_inelastic_strain_old[_qp];
     146      549504 : }
     147             : 
     148             : template <bool is_ad>
     149             : int
     150       26238 : RadialReturnStressUpdateTempl<is_ad>::calculateNumberSubsteps(
     151             :     const GenericRankTwoTensor<is_ad> & strain_increment)
     152             : {
     153             :   // compute an effective elastic strain measure
     154        4740 :   const GenericReal<is_ad> contracted_elastic_strain =
     155       21498 :       strain_increment.doubleContraction(strain_increment);
     156             :   const Real effective_elastic_strain =
     157       26238 :       std::sqrt(3.0 / 2.0 * MetaPhysicL::raw_value(contracted_elastic_strain));
     158             : 
     159       26238 :   if (MooseUtils::absoluteFuzzyEqual(effective_elastic_strain, 0.0))
     160             :     return 1;
     161             : 
     162       18166 :   if (_use_substepping == SubsteppingType::INCREMENT_BASED)
     163             :   {
     164       10008 :     const Real ratio = effective_elastic_strain / _max_inelastic_increment;
     165             : 
     166       10008 :     if (ratio > _substep_tolerance)
     167       10002 :       return std::ceil(ratio / _substep_tolerance);
     168             :     return 1;
     169             :   }
     170             : 
     171        8158 :   if (_use_substepping == SubsteppingType::ERROR_BASED)
     172             :   {
     173        8158 :     const Real accurate_time_step_ratio = _substep_tolerance / effective_elastic_strain;
     174             : 
     175        8158 :     if (accurate_time_step_ratio < 1.0)
     176        2764 :       return std::ceil(1.0 / accurate_time_step_ratio);
     177             :     return 1;
     178             :   }
     179             : 
     180           0 :   mooseError("calculateNumberSubsteps should not have been called. Notify a developer.");
     181             : }
     182             : 
     183             : template <bool is_ad>
     184             : void
     185           0 : RadialReturnStressUpdateTempl<is_ad>::computeTangentOperator(Real /*effective_trial_stress*/,
     186             :                                                              const RankTwoTensor & /*stress_new*/,
     187             :                                                              RankFourTensor & /*tangent_operator*/)
     188             : {
     189           0 :   mooseError("computeTangentOperator called: no tangent computation is needed for AD");
     190             : }
     191             : 
     192             : template <>
     193             : void
     194      678956 : RadialReturnStressUpdateTempl<false>::computeTangentOperator(Real effective_trial_stress,
     195             :                                                              const RankTwoTensor & stress_new,
     196             :                                                              RankFourTensor & tangent_operator)
     197             : {
     198      678956 :   if (getTangentCalculationMethod() == TangentCalculationMethod::PARTIAL)
     199             :   {
     200      603284 :     if (MooseUtils::absoluteFuzzyEqual(_effective_inelastic_strain_increment, 0.0))
     201       75614 :       tangent_operator.zero();
     202             :     else
     203             :     {
     204             :       // mu = _three_shear_modulus / 3.0;
     205             :       // norm_dev_stress = ||s_n+1||
     206             :       // effective_trial_stress = von mises trial stress = std::sqrt(3.0 / 2.0) * ||s_n+1^trial||
     207             :       // scalar_effective_inelastic_strain = Delta epsilon^cr_n+1
     208             :       // deriv = derivative of scalar_effective_inelastic_strain w.r.t. von mises stress
     209             :       // deriv = std::sqrt(3.0 / 2.0) partial Delta epsilon^cr_n+1n over partial ||s_n+1^trial||
     210             : 
     211             :       mooseAssert(_three_shear_modulus != 0.0, "Shear modulus is zero");
     212             : 
     213      527670 :       const RankTwoTensor deviatoric_stress = stress_new.deviatoric();
     214      527670 :       const Real norm_dev_stress_squared = deviatoric_stress.doubleContraction(deviatoric_stress);
     215      527670 :       if (MooseUtils::absoluteFuzzyEqual(norm_dev_stress_squared, 0.0))
     216             :       {
     217           0 :         tangent_operator.zero();
     218             :         return;
     219             :       }
     220      527670 :       const Real norm_dev_stress = std::sqrt(norm_dev_stress_squared);
     221             : 
     222      527670 :       const RankTwoTensor flow_direction = deviatoric_stress / norm_dev_stress;
     223             :       const RankFourTensor flow_direction_dyad = flow_direction.outerProduct(flow_direction);
     224             :       const Real deriv =
     225      527670 :           computeStressDerivative(effective_trial_stress, _effective_inelastic_strain_increment);
     226      527670 :       const Real scalar_one = _three_shear_modulus * _effective_inelastic_strain_increment /
     227      527670 :                               std::sqrt(1.5) / norm_dev_stress;
     228             : 
     229      527670 :       tangent_operator = scalar_one * _deviatoric_projection_four +
     230     1055340 :                          (_three_shear_modulus * deriv - scalar_one) * flow_direction_dyad;
     231             :     }
     232             :   }
     233             : }
     234             : 
     235             : template <bool is_ad>
     236             : void
     237    58555054 : RadialReturnStressUpdateTempl<is_ad>::updateState(
     238             :     GenericRankTwoTensor<is_ad> & strain_increment,
     239             :     GenericRankTwoTensor<is_ad> & inelastic_strain_increment,
     240             :     const GenericRankTwoTensor<is_ad> & /*rotation_increment*/,
     241             :     GenericRankTwoTensor<is_ad> & stress_new,
     242             :     const RankTwoTensor & /*stress_old*/,
     243             :     const GenericRankFourTensor<is_ad> & elasticity_tensor,
     244             :     const RankTwoTensor & elastic_strain_old,
     245             :     bool compute_full_tangent_operator,
     246             :     RankFourTensor & tangent_operator)
     247             : {
     248             :   using std::sqrt;
     249             : 
     250             :   // compute the deviatoric trial stress and trial strain from the current intermediate
     251             :   // configuration
     252    58555054 :   GenericRankTwoTensor<is_ad> deviatoric_trial_stress = stress_new.deviatoric();
     253             : 
     254             :   // compute the effective trial stress
     255    29766204 :   GenericReal<is_ad> dev_trial_stress_squared =
     256    28788850 :       deviatoric_trial_stress.doubleContraction(deviatoric_trial_stress);
     257    57781970 :   GenericReal<is_ad> effective_trial_stress = MetaPhysicL::raw_value(dev_trial_stress_squared)
     258    58555054 :                                                   ? sqrt(3.0 / 2.0 * dev_trial_stress_squared)
     259    29766204 :                                                   : 0.0;
     260             : 
     261    58555054 :   computeStressInitialize(effective_trial_stress, elasticity_tensor);
     262             : 
     263             :   mooseAssert(
     264             :       _three_shear_modulus != 0.0,
     265             :       "Shear modulus is zero. Ensure that the base class computeStressInitialize() is called.");
     266             : 
     267             :   // Use Newton iteration to determine the scalar effective inelastic strain increment
     268    58555050 :   _effective_inelastic_strain_increment = 0.0;
     269    58555050 :   if (!MooseUtils::absoluteFuzzyEqual(effective_trial_stress, 0.0))
     270             :   {
     271    56889686 :     this->returnMappingSolve(
     272    56889686 :         effective_trial_stress, _effective_inelastic_strain_increment, this->_console);
     273    56889658 :     if (_effective_inelastic_strain_increment != 0.0)
     274    54197785 :       inelastic_strain_increment =
     275             :           deviatoric_trial_stress *
     276    82442780 :           (1.5 * _effective_inelastic_strain_increment / effective_trial_stress);
     277             :     else
     278      748107 :       inelastic_strain_increment.zero();
     279             :   }
     280             :   else
     281      773084 :     inelastic_strain_increment.zero();
     282             : 
     283    58555022 :   if (_apply_strain)
     284             :   {
     285    58540702 :     strain_increment -= inelastic_strain_increment;
     286    58540702 :     updateEffectiveInelasticStrain(_effective_inelastic_strain_increment);
     287             : 
     288             :     // Use the old elastic strain here because we require tensors used by this class
     289             :     // to be isotropic and this method natively allows for changing in time
     290             :     // elasticity tensors
     291    88304736 :     stress_new = elasticity_tensor * (strain_increment + elastic_strain_old);
     292             :   }
     293             : 
     294    58555022 :   computeStressFinalize(inelastic_strain_increment);
     295             : 
     296             :   if constexpr (!is_ad)
     297             :   {
     298    28788836 :     if (compute_full_tangent_operator)
     299      203888 :       computeTangentOperator(effective_trial_stress, stress_new, tangent_operator);
     300             :   }
     301             :   else
     302             :   {
     303             :     libmesh_ignore(compute_full_tangent_operator);
     304             :     libmesh_ignore(tangent_operator);
     305             :   }
     306    58555022 : }
     307             : 
     308             : template <bool is_ad>
     309             : void
     310       26246 : RadialReturnStressUpdateTempl<is_ad>::updateStateSubstepInternal(
     311             :     GenericRankTwoTensor<is_ad> & strain_increment,
     312             :     GenericRankTwoTensor<is_ad> & inelastic_strain_increment,
     313             :     const GenericRankTwoTensor<is_ad> & rotation_increment,
     314             :     GenericRankTwoTensor<is_ad> & stress_new,
     315             :     const RankTwoTensor & stress_old,
     316             :     const GenericRankFourTensor<is_ad> & elasticity_tensor,
     317             :     const RankTwoTensor & elastic_strain_old,
     318             :     unsigned int total_number_substeps,
     319             :     bool compute_full_tangent_operator,
     320             :     RankFourTensor & tangent_operator)
     321             : {
     322             :   using std::sqrt;
     323             : 
     324             :   // if only one substep is needed, then call the original update state method
     325       26246 :   if (total_number_substeps == 1)
     326             :   {
     327       13472 :     updateState(strain_increment,
     328             :                 inelastic_strain_increment,
     329             :                 rotation_increment,
     330             :                 stress_new,
     331             :                 stress_old,
     332             :                 elasticity_tensor,
     333             :                 elastic_strain_old,
     334             :                 compute_full_tangent_operator,
     335             :                 tangent_operator);
     336             : 
     337       13464 :     this->storeIncrementalMaterialProperties(total_number_substeps);
     338       13464 :     return;
     339             :   }
     340             : 
     341       12774 :   if (total_number_substeps > _maximum_number_substeps)
     342          22 :     mooseException("The number of substeps computed exceeds 'maximum_number_substeps'.");
     343             : 
     344             :   // cut the original timestep
     345       12752 :   _dt = _dt_original / total_number_substeps;
     346             : 
     347             :   // initialize the inputs
     348       12752 :   const GenericRankTwoTensor<is_ad> strain_increment_per_step =
     349             :       strain_increment / total_number_substeps;
     350       12752 :   GenericRankTwoTensor<is_ad> sub_stress_new = elasticity_tensor * elastic_strain_old;
     351        8524 :   GenericRankTwoTensor<is_ad> sub_elastic_strain_old = elastic_strain_old;
     352             : 
     353             :   // clear the original inputs
     354       12752 :   MathUtils::mooseSetToZero(strain_increment);
     355       12752 :   MathUtils::mooseSetToZero(inelastic_strain_increment);
     356       12752 :   MathUtils::mooseSetToZero(stress_new);
     357             : 
     358       12752 :   GenericReal<is_ad> sub_effective_inelastic_strain_increment = 0.0;
     359        8524 :   GenericRankTwoTensor<is_ad> sub_inelastic_strain_increment = inelastic_strain_increment;
     360             : 
     361      666236 :   for (unsigned int step = 0; step < total_number_substeps; ++step)
     362             :   {
     363             :     // set up input for this substep
     364      323728 :     GenericRankTwoTensor<is_ad> sub_strain_increment = strain_increment_per_step;
     365      653492 :     sub_stress_new += elasticity_tensor * sub_strain_increment;
     366             : 
     367             :     Real effective_sub_stress_new;
     368             :     if constexpr (!is_ad)
     369             :     {
     370             :       // compute effective_sub_stress_new
     371      323728 :       const RankTwoTensor deviatoric_sub_stress_new = sub_stress_new.deviatoric();
     372             :       const Real dev_sub_stress_new_squared =
     373      323728 :           deviatoric_sub_stress_new.doubleContraction(deviatoric_sub_stress_new);
     374      323728 :       effective_sub_stress_new = sqrt(3.0 / 2.0 * dev_sub_stress_new_squared);
     375             :     }
     376             :     else
     377             :       libmesh_ignore(effective_sub_stress_new);
     378             : 
     379             :     // update stress and strain based on the strain increment
     380      653492 :     updateState(sub_strain_increment,
     381             :                 sub_inelastic_strain_increment,
     382             :                 rotation_increment, // not used in updateState
     383             :                 sub_stress_new,
     384             :                 stress_old, // not used in updateState
     385             :                 elasticity_tensor,
     386             :                 elastic_strain_old,
     387             :                 false);
     388             :     // do not compute tangent until the end of this substep (or not at all for is_ad == true)
     389             : 
     390             :     // update strain and stress
     391      653484 :     strain_increment += sub_strain_increment;
     392      653484 :     inelastic_strain_increment += sub_inelastic_strain_increment;
     393      653484 :     sub_elastic_strain_old += sub_strain_increment;
     394      653488 :     sub_stress_new = elasticity_tensor * sub_elastic_strain_old;
     395             : 
     396             :     // accumulate scalar_effective_inelastic_strain
     397      653484 :     sub_effective_inelastic_strain_increment += _effective_inelastic_strain_increment;
     398             : 
     399             :     if constexpr (!is_ad)
     400      323724 :       computeTangentOperator(effective_sub_stress_new, sub_stress_new, tangent_operator);
     401             : 
     402             :     // store incremental material properties for this step
     403      653484 :     this->storeIncrementalMaterialProperties(total_number_substeps);
     404             :   }
     405             : 
     406             :   // update stress
     407        8520 :   stress_new = sub_stress_new;
     408             : 
     409             :   // update effective inelastic strain
     410       12744 :   updateEffectiveInelasticStrain(sub_effective_inelastic_strain_increment);
     411             : }
     412             : 
     413             : template <bool is_ad>
     414             : void
     415       26238 : RadialReturnStressUpdateTempl<is_ad>::updateStateSubstep(
     416             :     GenericRankTwoTensor<is_ad> & strain_increment,
     417             :     GenericRankTwoTensor<is_ad> & inelastic_strain_increment,
     418             :     const GenericRankTwoTensor<is_ad> & rotation_increment,
     419             :     GenericRankTwoTensor<is_ad> & stress_new,
     420             :     const RankTwoTensor & stress_old,
     421             :     const GenericRankFourTensor<is_ad> & elasticity_tensor,
     422             :     const RankTwoTensor & elastic_strain_old,
     423             :     bool compute_full_tangent_operator,
     424             :     RankFourTensor & tangent_operator)
     425             : {
     426       26238 :   unsigned int num_substeps = calculateNumberSubsteps(strain_increment);
     427       26238 :   _dt_original = _dt;
     428             :   while (true)
     429             :   {
     430             :     try
     431             :     {
     432       26246 :       updateStateSubstepInternal(strain_increment,
     433             :                                  inelastic_strain_increment,
     434             :                                  rotation_increment,
     435             :                                  stress_new,
     436             :                                  stress_old,
     437             :                                  elasticity_tensor,
     438             :                                  elastic_strain_old,
     439             :                                  num_substeps,
     440             :                                  compute_full_tangent_operator,
     441             :                                  tangent_operator);
     442             :     }
     443          68 :     catch (MooseException & e)
     444             :     {
     445             :       // if we are not using adaptive substepping we just rethrow the exception
     446          38 :       if (!_adaptive_substepping)
     447          22 :         throw e;
     448             : 
     449             :       // otherwise we double the number of substeps and try again
     450          16 :       num_substeps *= 2;
     451          16 :       if (num_substeps <= _maximum_number_substeps)
     452             :         continue;
     453             : 
     454             :       // too meany substeps, break out of the loop
     455             :       break;
     456             :     }
     457             : 
     458             :     // updateStateSubstepInternal was successful (didn't throw)
     459       26208 :     _dt = _dt_original;
     460       26208 :     return;
     461             :   }
     462             : 
     463             :   // recover the original timestep
     464           8 :   _dt = _dt_original;
     465             : 
     466           8 :   mooseException("Adaptive substepping failed. Maximum number of substeps exceeded.");
     467             : }
     468             : 
     469             : template <bool is_ad>
     470             : Real
     471   297632479 : RadialReturnStressUpdateTempl<is_ad>::computeReferenceResidual(
     472             :     const GenericReal<is_ad> & effective_trial_stress,
     473             :     const GenericReal<is_ad> & scalar_effective_inelastic_strain)
     474             : {
     475   297632479 :   return MetaPhysicL::raw_value(effective_trial_stress / _three_shear_modulus) -
     476   297632479 :          MetaPhysicL::raw_value(scalar_effective_inelastic_strain);
     477             : }
     478             : 
     479             : template <bool is_ad>
     480             : GenericReal<is_ad>
     481    56697310 : RadialReturnStressUpdateTempl<is_ad>::maximumPermissibleValue(
     482             :     const GenericReal<is_ad> & effective_trial_stress) const
     483             : {
     484    56697310 :   return effective_trial_stress / _three_shear_modulus;
     485             : }
     486             : 
     487             : template <bool is_ad>
     488             : Real
     489    29247740 : RadialReturnStressUpdateTempl<is_ad>::computeTimeStepLimit()
     490             : {
     491             :   const Real scalar_inelastic_strain_incr =
     492    29247740 :       std::abs(MetaPhysicL::raw_value(_effective_inelastic_strain[_qp]) -
     493    29247740 :                _effective_inelastic_strain_old[_qp]);
     494    29247740 :   if (!scalar_inelastic_strain_incr)
     495             :     return std::numeric_limits<Real>::max();
     496             : 
     497    24680287 :   return _dt * _max_inelastic_increment / scalar_inelastic_strain_incr;
     498             : }
     499             : 
     500             : template <bool is_ad>
     501             : void
     502       25364 : RadialReturnStressUpdateTempl<is_ad>::outputIterationSummary(std::stringstream * iter_output,
     503             :                                                              const unsigned int total_it)
     504             : {
     505       25364 :   if (iter_output)
     506             :   {
     507       25364 :     *iter_output << "At element " << _current_elem->id() << " _qp=" << _qp << " Coordinates "
     508       25364 :                  << _q_point[_qp] << " block=" << _current_elem->subdomain_id() << '\n';
     509             :   }
     510       25364 :   SingleVariableReturnMappingSolutionTempl<is_ad>::outputIterationSummary(iter_output, total_it);
     511       25364 : }
     512             : 
     513             : template class RadialReturnStressUpdateTempl<false>;
     514             : template class RadialReturnStressUpdateTempl<true>;

Generated by: LCOV version 1.14