LCOV - code coverage report
Current view: top level - src/materials/crystal_plasticity - CrystalPlasticityTwinningKalidindiUpdate.C (source / functions) Hit Total Coverage
Test: idaholab/moose tensor_mechanics: d6b47a Lines: 159 165 96.4 %
Date: 2024-02-27 11:53:14 Functions: 14 14 100.0 %
Legend: Lines: hit not hit

          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 "CrystalPlasticityTwinningKalidindiUpdate.h"
      11             : #include "libmesh/int_range.h"
      12             : 
      13             : registerMooseObject("TensorMechanicsApp", CrystalPlasticityTwinningKalidindiUpdate);
      14             : 
      15             : InputParameters
      16         140 : CrystalPlasticityTwinningKalidindiUpdate::validParams()
      17             : {
      18         140 :   InputParameters params = CrystalPlasticityStressUpdateBase::validParams();
      19         140 :   params.addClassDescription(
      20             :       "Twinning propagation model based on Kalidindi's treatment of twinning in a FCC material");
      21         280 :   params.addParam<Real>(
      22             :       "initial_total_twin_volume_fraction",
      23         280 :       0.0,
      24             :       "The initial sum of the twin volume fraction across all twin systems in the crystal, if "
      25             :       "any. This value is distributed evenly across all twin systems in the crystal.");
      26         420 :   params.addRangeCheckedParam<Real>(
      27             :       "twin_reference_strain_rate",
      28         280 :       1.0e-3,
      29             :       "twin_reference_strain_rate>0",
      30             :       "The reference strain rate, gamma_o, for the power law plastic slip law "
      31             :       "due to twin propagation.");
      32         420 :   params.addRangeCheckedParam<Real>(
      33             :       "twin_strain_rate_sensitivity_exponent",
      34         280 :       0.05,
      35             :       "twin_strain_rate_sensitivity_exponent>0",
      36             :       "The strain rate sensitivity exponent for twin propagation power law "
      37             :       "strain rate calculation");
      38         420 :   params.addRangeCheckedParam<Real>(
      39             :       "characteristic_twin_shear",
      40         280 :       1.0 / std::sqrt(2.0),
      41             :       "characteristic_twin_shear>0",
      42             :       "The amount of shear that is associated with a twin in this cubic structure");
      43         420 :   params.addRangeCheckedParam<Real>(
      44             :       "initial_twin_lattice_friction",
      45         280 :       0.0,
      46             :       "initial_twin_lattice_friction>=0",
      47             :       "The initial value of the lattice friction for twin propogation, often "
      48             :       "calculated as a fraction of the Peierls strength");
      49         420 :   params.addRangeCheckedParam<Real>(
      50             :       "non_coplanar_coefficient_twin_hardening",
      51         280 :       8000.0,
      52             :       "non_coplanar_coefficient_twin_hardening>=0",
      53             :       "The factor to apply to the hardening of non-coplanar twin systems "
      54             :       "strength as a function of the volume fraction of twins");
      55         420 :   params.addRangeCheckedParam<Real>(
      56             :       "coplanar_coefficient_twin_hardening",
      57         280 :       800.0,
      58             :       "coplanar_coefficient_twin_hardening>=0",
      59             :       "Hardening coefficient for coplanar twin systems strength as a function of "
      60             :       "the volume fraction of twins");
      61         420 :   params.addRangeCheckedParam<Real>(
      62             :       "non_coplanar_twin_hardening_exponent",
      63         280 :       0.05,
      64             :       "non_coplanar_twin_hardening_exponent>=0",
      65             :       "Parameter used to increase the hardening of non-coplanar twin systems such that the "
      66             :       "propagation of twins on conplanar systems is favored at early deformation stages.");
      67         420 :   params.addRangeCheckedParam<Real>(
      68             :       "upper_limit_twin_volume_fraction",
      69         280 :       0.8,
      70             :       "upper_limit_twin_volume_fraction>0&upper_limit_twin_volume_fraction<=1",
      71             :       "The maximumum amount of twinning volume fraction allowed");
      72             : 
      73         140 :   return params;
      74           0 : }
      75             : 
      76         105 : CrystalPlasticityTwinningKalidindiUpdate::CrystalPlasticityTwinningKalidindiUpdate(
      77         105 :     const InputParameters & parameters)
      78             :   : CrystalPlasticityStressUpdateBase(parameters),
      79             : 
      80         105 :     _total_twin_volume_fraction(declareProperty<Real>(_base_name + "total_volume_fraction_twins")),
      81         105 :     _total_twin_volume_fraction_old(
      82         105 :         getMaterialPropertyOld<Real>(_base_name + "total_volume_fraction_twins")),
      83         210 :     _initial_total_twin_volume_fraction(getParam<Real>("initial_total_twin_volume_fraction")),
      84         105 :     _twin_volume_fraction(
      85         105 :         declareProperty<std::vector<Real>>(_base_name + "twin_system_volume_fraction")),
      86         105 :     _twin_volume_fraction_old(
      87         105 :         getMaterialPropertyOld<std::vector<Real>>(_base_name + "twin_system_volume_fraction")),
      88         105 :     _twin_volume_fraction_increment(
      89         105 :         declareProperty<std::vector<Real>>(_base_name + "twin_system_volume_fraction_increment")),
      90         210 :     _reference_strain_rate(getParam<Real>("twin_reference_strain_rate")),
      91         210 :     _rate_sensitivity_exponent(getParam<Real>("twin_strain_rate_sensitivity_exponent")),
      92         210 :     _characteristic_twin_shear(getParam<Real>("characteristic_twin_shear")),
      93         210 :     _twin_initial_lattice_friction(getParam<Real>("initial_twin_lattice_friction")),
      94         105 :     _non_coplanar_coefficient_twin_hardening(
      95         210 :         getParam<Real>("non_coplanar_coefficient_twin_hardening")),
      96         210 :     _coplanar_coefficient_twin_hardening(getParam<Real>("coplanar_coefficient_twin_hardening")),
      97         210 :     _noncoplanar_exponent(getParam<Real>("non_coplanar_twin_hardening_exponent")),
      98         210 :     _limit_twin_volume_fraction(getParam<Real>("upper_limit_twin_volume_fraction")),
      99             : 
     100             :     // resize local caching vectors used for substepping
     101         105 :     _previous_substep_twin_resistance(_number_slip_systems, 0.0),
     102         105 :     _previous_substep_twin_volume_fraction(_number_slip_systems, 0.0),
     103         105 :     _twin_resistance_before_update(_number_slip_systems, 0.0),
     104         210 :     _twin_volume_fraction_before_update(_number_slip_systems, 0.0)
     105             : {
     106         105 : }
     107             : 
     108             : void
     109        6080 : CrystalPlasticityTwinningKalidindiUpdate::initQpStatefulProperties()
     110             : {
     111        6080 :   CrystalPlasticityStressUpdateBase::initQpStatefulProperties();
     112             : 
     113             :   // Resize constitutive-model specific material properties
     114        6080 :   _twin_volume_fraction[_qp].resize(_number_slip_systems);
     115        6080 :   _twin_volume_fraction_increment[_qp].resize(_number_slip_systems);
     116             : 
     117             :   // Set constitutive-model specific initial values from parameters
     118        6080 :   _total_twin_volume_fraction[_qp] = _initial_total_twin_volume_fraction;
     119        6080 :   const Real twin_volume_fraction_per_system =
     120        6080 :       _initial_total_twin_volume_fraction / _number_slip_systems;
     121       64704 :   for (const auto i : make_range(_number_slip_systems))
     122             :   {
     123       58624 :     _twin_volume_fraction[_qp][i] = twin_volume_fraction_per_system;
     124       58624 :     _slip_resistance[_qp][i] = _twin_initial_lattice_friction;
     125       58624 :     _slip_increment[_qp][i] = 0.0;
     126             :   }
     127        6080 : }
     128             : 
     129             : void
     130      202942 : CrystalPlasticityTwinningKalidindiUpdate::setInitialConstitutiveVariableValues()
     131             : {
     132      202942 :   _slip_resistance[_qp] = _slip_resistance_old[_qp];
     133      202942 :   _previous_substep_twin_resistance = _slip_resistance_old[_qp];
     134             : 
     135      202942 :   _twin_volume_fraction[_qp] = _twin_volume_fraction_old[_qp];
     136      202942 :   _previous_substep_twin_volume_fraction = _twin_volume_fraction_old[_qp];
     137      202942 : }
     138             : 
     139             : void
     140      203558 : CrystalPlasticityTwinningKalidindiUpdate::setSubstepConstitutiveVariableValues()
     141             : {
     142      203558 :   _slip_resistance[_qp] = _previous_substep_twin_resistance;
     143      203558 :   _twin_volume_fraction[_qp] = _previous_substep_twin_volume_fraction;
     144      203558 : }
     145             : 
     146             : bool
     147     2226207 : CrystalPlasticityTwinningKalidindiUpdate::calculateSlipRate()
     148             : {
     149             :   Real total_twin_volume_fraction = 0.0;
     150    21941681 :   for (const auto i : make_range(_number_slip_systems))
     151    19715474 :     total_twin_volume_fraction += _twin_volume_fraction[_qp][i];
     152             : 
     153     2226207 :   if (total_twin_volume_fraction < _limit_twin_volume_fraction)
     154             :   {
     155    21833565 :     for (const auto i : make_range(_number_slip_systems))
     156             :     {
     157    19615675 :       if (_tau[_qp][i] > 0.0)
     158             :       {
     159    11211183 :         const Real driving_force = (_tau[_qp][i] / _slip_resistance[_qp][i]);
     160    11211183 :         _slip_increment[_qp][i] = std::pow(driving_force, (1.0 / _rate_sensitivity_exponent)) *
     161    11211183 :                                   _reference_strain_rate * _substep_dt;
     162             :       }
     163             :       else // twin propagation is directional
     164     8404492 :         _slip_increment[_qp][i] = 0.0;
     165             : 
     166             :       // Check for allowable plastic strain due to twin propagation
     167    19615675 :       if (_slip_increment[_qp][i] > _slip_incr_tol)
     168             :       {
     169           1 :         if (_print_convergence_message)
     170           1 :           mooseWarning("Maximum allowable plastic slip increment due to twinning exceeded the "
     171             :                        "user-defined tolerance on twin system ",
     172             :                        i,
     173             :                        ", with a value of",
     174             :                        _slip_increment[_qp][i],
     175             :                        " when the increment tolerance is set at ",
     176           1 :                        _slip_incr_tol);
     177             : 
     178           0 :         return false;
     179             :       }
     180             :     }
     181             :   }
     182             :   else // Once reach the limit of volume fraction, all subsequent increments will be zero
     183        8316 :     std::fill(_slip_increment[_qp].begin(), _slip_increment[_qp].end(), 0.0);
     184             : 
     185             :   return true;
     186             : }
     187             : 
     188             : void
     189     2226206 : CrystalPlasticityTwinningKalidindiUpdate::calculateConstitutiveSlipDerivative(
     190             :     std::vector<Real> & dslip_dtau)
     191             : {
     192             :   Real total_twin_volume_fraction = 0.0;
     193    21941668 :   for (const auto i : make_range(_number_slip_systems))
     194    19715462 :     total_twin_volume_fraction += _twin_volume_fraction[_qp][i];
     195             : 
     196             :   // Once reach the limit of volume fraction, all plastic slip increments will be zero
     197     2226206 :   if (total_twin_volume_fraction >= _limit_twin_volume_fraction)
     198             :     std::fill(dslip_dtau.begin(), dslip_dtau.end(), 0.0);
     199             :   else
     200             :   {
     201    21833560 :     for (const auto i : make_range(_number_slip_systems))
     202             :     {
     203    19615670 :       if (_tau[_qp][i] <= 0.0)
     204     8404490 :         dslip_dtau[i] = 0.0;
     205             :       else
     206    11211180 :         dslip_dtau[i] =
     207    11211180 :             _slip_increment[_qp][i] / (_rate_sensitivity_exponent * _tau[_qp][i]) * _substep_dt;
     208             :     }
     209             :   }
     210     2226206 : }
     211             : 
     212             : bool
     213      449506 : CrystalPlasticityTwinningKalidindiUpdate::areConstitutiveStateVariablesConverged()
     214             : {
     215      449506 :   if (isConstitutiveStateVariableConverged(_twin_volume_fraction[_qp],
     216      449506 :                                            _twin_volume_fraction_before_update,
     217      449506 :                                            _previous_substep_twin_volume_fraction,
     218      652375 :                                            _rel_state_var_tol) &&
     219      202869 :       isConstitutiveStateVariableConverged(_slip_resistance[_qp],
     220      202869 :                                            _twin_resistance_before_update,
     221      202869 :                                            _previous_substep_twin_resistance,
     222      202869 :                                            _resistance_tol))
     223             :     return true;
     224             :   return false;
     225             : }
     226             : 
     227             : void
     228      202869 : CrystalPlasticityTwinningKalidindiUpdate::updateSubstepConstitutiveVariableValues()
     229             : {
     230      202869 :   _previous_substep_twin_resistance = _slip_resistance[_qp];
     231      202869 :   _previous_substep_twin_volume_fraction = _twin_volume_fraction[_qp];
     232      202869 : }
     233             : 
     234             : void
     235      458013 : CrystalPlasticityTwinningKalidindiUpdate::cacheStateVariablesBeforeUpdate()
     236             : {
     237      458013 :   _twin_resistance_before_update = _slip_resistance[_qp];
     238      458013 :   _twin_volume_fraction_before_update = _twin_volume_fraction[_qp];
     239      458013 : }
     240             : 
     241             : void
     242      458013 : CrystalPlasticityTwinningKalidindiUpdate::calculateStateVariableEvolutionRateComponent()
     243             : {
     244     5106445 :   for (const auto i : make_range(_number_slip_systems))
     245     4648432 :     _twin_volume_fraction_increment[_qp][i] =
     246     4648432 :         _slip_increment[_qp][i] / _characteristic_twin_shear * _substep_dt;
     247      458013 : }
     248             : 
     249             : bool
     250      458013 : CrystalPlasticityTwinningKalidindiUpdate::updateStateVariables()
     251             : {
     252      458013 :   if (calculateTwinVolumeFraction())
     253             :     return true;
     254             :   else
     255          58 :     return false;
     256             : }
     257             : 
     258             : bool
     259      458013 : CrystalPlasticityTwinningKalidindiUpdate::calculateTwinVolumeFraction()
     260             : {
     261      458013 :   _total_twin_volume_fraction[_qp] = 0.0;
     262             : 
     263     5106445 :   for (const auto i : make_range(_number_slip_systems))
     264             :   {
     265     4648432 :     if (_previous_substep_twin_volume_fraction[i] < _zero_tol &&
     266     3534082 :         _twin_volume_fraction_increment[_qp][i] < 0.0)
     267           0 :       _twin_volume_fraction_increment[_qp][i] = _previous_substep_twin_volume_fraction[i];
     268             :     else
     269     4648432 :       _twin_volume_fraction[_qp][i] =
     270     4648432 :           _previous_substep_twin_volume_fraction[i] + _twin_volume_fraction_increment[_qp][i];
     271             : 
     272     4648432 :     if (_twin_volume_fraction[_qp][i] < 0.0)
     273             :     {
     274           0 :       if (_print_convergence_message)
     275           0 :         mooseWarning("A negative twin volume fraction value was computed: ",
     276             :                      _twin_volume_fraction[_qp][i],
     277             :                      " on twin system ",
     278             :                      i);
     279           0 :       return false;
     280             :     }
     281             :     else
     282     4648432 :       _total_twin_volume_fraction[_qp] += _twin_volume_fraction[_qp][i];
     283             :   }
     284             : 
     285      458013 :   if ((_total_twin_volume_fraction[_qp] - _limit_twin_volume_fraction) >
     286      458013 :       (_rel_state_var_tol * _limit_twin_volume_fraction))
     287             :   {
     288          59 :     if (_print_convergence_message)
     289          59 :       mooseWarning("Maximum allowable twin volume fraction limit exceeded with a value of ",
     290             :                    _total_twin_volume_fraction[_qp],
     291             :                    " when the limit is set as ",
     292          59 :                    _limit_twin_volume_fraction,
     293             :                    " with a user-set tolerance value of ",
     294          59 :                    _rel_state_var_tol);
     295             : 
     296          58 :     return false;
     297             :   }
     298             :   else
     299             :   {
     300      457954 :     calculateTwinResistance();
     301      457954 :     return true;
     302             :   }
     303             : }
     304             : 
     305             : void
     306      457954 : CrystalPlasticityTwinningKalidindiUpdate::calculateTwinResistance()
     307             : {
     308      457954 :   DenseVector<Real> twin_hardening_increment(_number_slip_systems);
     309             : 
     310     5105678 :   for (const auto i : make_range(_number_slip_systems))
     311             :   {
     312     4647724 :     twin_hardening_increment(i) = 0.0;
     313    56139956 :     for (const auto j : make_range(_number_slip_systems))
     314             :     {
     315    51492232 :       if (MooseUtils::relativeFuzzyEqual(_slip_plane_normal[j](0), _slip_plane_normal[i](0)) &&
     316             :           MooseUtils::relativeFuzzyEqual(_slip_plane_normal[j](1), _slip_plane_normal[i](1)))
     317             :       // If the first two are the same, the third index will have to be as well
     318             :       {
     319    12751404 :         if (_slip_increment[_qp][j] > 0.0)
     320     6346892 :           twin_hardening_increment(i) += _coplanar_coefficient_twin_hardening *
     321     6346892 :                                          _total_twin_volume_fraction[_qp] *
     322     6346892 :                                          _twin_volume_fraction[_qp][j];
     323             :       }
     324             :       else // assume non-coplanar
     325             :       {
     326    38740828 :         if (_slip_increment[_qp][j] > 0.0)
     327    19720548 :           twin_hardening_increment(i) +=
     328    19720548 :               _non_coplanar_coefficient_twin_hardening *
     329    19720548 :               std::pow(_total_twin_volume_fraction[_qp], _noncoplanar_exponent) *
     330    19720548 :               _twin_volume_fraction[_qp][j];
     331             :       }
     332             :     }
     333             :   }
     334             : 
     335     5105678 :   for (const auto i : make_range(_number_slip_systems))
     336             :   {
     337     4647724 :     twin_hardening_increment(i) *= _characteristic_twin_shear;
     338     4647724 :     if (twin_hardening_increment(i) <= 0.0)
     339      183532 :       _slip_resistance[_qp][i] = _previous_substep_twin_resistance[i];
     340             :     else
     341     4464192 :       _slip_resistance[_qp][i] = twin_hardening_increment(i) + _previous_substep_twin_resistance[i];
     342             :   }
     343      457954 : }

Generated by: LCOV version 1.14