LCOV - code coverage report
Current view: top level - src/materials - ConcreteExpansionMicrocrackingDamage.C (source / functions) Hit Total Coverage
Test: idaholab/blackbear: 276f95 Lines: 79 80 98.8 %
Date: 2025-10-28 03:10:25 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /****************************************************************/
       2             : /*               DO NOT MODIFY THIS HEADER                      */
       3             : /*                       BlackBear                              */
       4             : /*                                                              */
       5             : /*           (c) 2017 Battelle Energy Alliance, LLC             */
       6             : /*                   ALL RIGHTS RESERVED                        */
       7             : /*                                                              */
       8             : /*          Prepared by Battelle Energy Alliance, LLC           */
       9             : /*            Under Contract No. DE-AC07-05ID14517              */
      10             : /*            With the U. S. Department of Energy               */
      11             : /*                                                              */
      12             : /*            See COPYRIGHT for full restrictions               */
      13             : /****************************************************************/
      14             : 
      15             : #include "ConcreteExpansionMicrocrackingDamage.h"
      16             : #include "ElasticityTensorTools.h"
      17             : 
      18             : registerMooseObject("BlackBearApp", ConcreteExpansionMicrocrackingDamage);
      19             : 
      20             : InputParameters
      21         571 : ConcreteExpansionMicrocrackingDamage::validParams()
      22             : {
      23         571 :   InputParameters params = ScalarDamageBase::validParams();
      24         571 :   params.addClassDescription("Scalar damage model based on extent of internal expansion");
      25             : 
      26        1142 :   params.addRequiredParam<MaterialPropertyName>(
      27             :       "microcracking_eigenstrain_name",
      28             :       "Name of the eigenstrain driving the microcracking damage process");
      29             : 
      30        1142 :   params.addParam<bool>("assume_isotropic_expansion",
      31        1142 :                         true,
      32             :                         "Indicates whether the model assumes an isotropic expansion (true) or "
      33             :                         "computes the linear expansion based on the first principal eigenstrain "
      34             :                         "(false)");
      35             : 
      36        1142 :   params.addParam<bool>("include_confinement_effects",
      37        1142 :                         true,
      38             :                         "Indicates whether the damage is affected by the current stress state");
      39             : 
      40        1142 :   params.addParam<Real>("eigenstrain_factor",
      41        1142 :                         1.0,
      42             :                         "Correction factor by which the eigenstrain is multiplied before "
      43             :                         "evaluating the damage");
      44        1142 :   params.setDocUnit("eigenstrain_factor", "unitless");
      45             : 
      46        1142 :   params.addRequiredRangeCheckedParam<Real>("microcracking_initiation_strain",
      47             :                                             "microcracking_initiation_strain > 0",
      48             :                                             "Linear strain at which the microcracking initiates");
      49        1142 :   params.setDocUnit("microcracking_initiation_strain", "unitless");
      50             : 
      51        1142 :   params.addRequiredRangeCheckedParam<Real>(
      52             :       "microcracking_strain_branch",
      53             :       "microcracking_strain_branch > 0",
      54             :       "Parameter controlling the rate at which the microcracking increases");
      55        1142 :   params.setDocUnit("microcracking_strain_branch", "unitless");
      56             : 
      57        1142 :   params.addParam<Real>(
      58             :       "expansion_stress_limit",
      59             :       "Upper bound compressive stress beyond which damage is controlled by the external stress");
      60        1142 :   params.setDocUnit("expansion_stress_limit", "stress");
      61             : 
      62         571 :   return params;
      63           0 : }
      64             : 
      65         438 : ConcreteExpansionMicrocrackingDamage::ConcreteExpansionMicrocrackingDamage(
      66         438 :     const InputParameters & parameters)
      67             :   : ScalarDamageBase(parameters),
      68             :     GuaranteeConsumer(this),
      69         438 :     _eigenstrain_name(getParam<MaterialPropertyName>("microcracking_eigenstrain_name")),
      70         438 :     _eigenstrain(getMaterialProperty<RankTwoTensor>(_eigenstrain_name)),
      71         438 :     _eigenstrain_old(getMaterialPropertyOld<RankTwoTensor>(_eigenstrain_name)),
      72         876 :     _assume_isotropic_expansion(getParam<bool>("assume_isotropic_expansion")),
      73         876 :     _eigenstrain_factor(getParam<Real>("eigenstrain_factor")),
      74         876 :     _epsilon_init(getParam<Real>("microcracking_initiation_strain")),
      75         876 :     _epsilon_branch(getParam<Real>("microcracking_strain_branch")),
      76         876 :     _include_confinement_effects(getParam<bool>("include_confinement_effects")),
      77        1746 :     _sigma_u(isParamValid("expansion_stress_limit") ? getParam<Real>("expansion_stress_limit")
      78             :                                                     : 0.0),
      79         876 :     _stress(getMaterialPropertyOld<RankTwoTensor>("stress")),
      80         438 :     _elasticity_tensor_name(_base_name + "elasticity_tensor"),
      81         438 :     _elasticity_tensor(getMaterialPropertyByName<RankFourTensor>(_elasticity_tensor_name)),
      82         876 :     _eigenvalues(3, 0.0)
      83             : {
      84        1227 :   if (_include_confinement_effects && !parameters.isParamSetByUser("expansion_stress_limit"))
      85           3 :     paramError("expansion_stress_limit",
      86             :                "is a required parameter for include_confinement_effects = true");
      87             : 
      88         435 :   if (_include_confinement_effects && !(_sigma_u > 0))
      89           3 :     paramError("expansion_stress_limit",
      90             :                "needs to be strictly > 0 for include_confinement_effects = true");
      91         432 : }
      92             : 
      93             : void
      94         423 : ConcreteExpansionMicrocrackingDamage::initialSetup()
      95             : {
      96         846 :   if (!hasGuaranteedMaterialProperty(_elasticity_tensor_name, Guarantee::ISOTROPIC))
      97           3 :     mooseError("ConcreteExpansionMicrocrackingDamage "
      98             :                "requires that the elasticity tensor be guaranteed isotropic");
      99         420 : }
     100             : 
     101             : void
     102       67424 : ConcreteExpansionMicrocrackingDamage::updateQpDamageIndex()
     103             : {
     104       67424 :   const Real linear_expansion = computeLinearExpansion(_eigenstrain[_qp]);
     105             :   const Real inc_linear_expansion =
     106       67424 :       linear_expansion - computeLinearExpansion(_eigenstrain_old[_qp]);
     107             : 
     108       67424 :   _damage_index[_qp] = _damage_index_old[_qp];
     109             : 
     110             :   // no additional expansion implies no additional damage
     111       67424 :   if (inc_linear_expansion < TOLERANCE)
     112       10304 :     return;
     113             : 
     114             :   // unconfined damage
     115             :   Real inc_damage_unconfined = 0.0;
     116       63840 :   if (linear_expansion > _epsilon_init)
     117             :   {
     118             :     const Real linear_expansion_eq =
     119             :         inc_linear_expansion +
     120       90048 :         std::max(0.0,
     121       45024 :                  _epsilon_init + _epsilon_branch * (1.0 + 1.0 / (1.0 - _damage_index_old[_qp])));
     122       45024 :     const Real next_damage_unconfined =
     123       45024 :         1.0 - _epsilon_branch / (linear_expansion_eq - (_epsilon_branch + _epsilon_init));
     124       90048 :     inc_damage_unconfined = std::max(0.0, next_damage_unconfined - _damage_index_old[_qp]);
     125             :   }
     126             : 
     127             :   // no stress control implies damage from unconfined expansion only
     128       63840 :   if (!_include_confinement_effects)
     129             :   {
     130        6720 :     _damage_index[_qp] = std::min(1.0, _damage_index_old[_qp] + inc_damage_unconfined);
     131        6720 :     return;
     132             :   }
     133             : 
     134             :   // confined damage
     135             :   Real inc_damage_confined = 0.0;
     136             : 
     137             :   // sum of compressive stress (positive value)
     138       57120 :   _stress[_qp].symmetricEigenvalues(_eigenvalues);
     139      150304 :   const Real sigma_compressive = -std::min(0.0, _eigenvalues[0]) - std::min(0.0, _eigenvalues[1]) -
     140       57120 :                                  std::min(0.0, _eigenvalues[2]);
     141             : 
     142       57120 :   if (sigma_compressive > 0.0)
     143             :   {
     144       50792 :     const Real E = ElasticityTensorTools::getIsotropicYoungsModulus(_elasticity_tensor[_qp]);
     145       50792 :     const Real confinement_factor = E / std::max(_sigma_u, sigma_compressive);
     146             :     const Real linear_expansion_eq =
     147             :         inc_linear_expansion +
     148       50792 :         std::max(0.0,
     149       50792 :                  _damage_index_old[_qp] / (confinement_factor * (1.0 - _damage_index_old[_qp])));
     150             : 
     151       50792 :     const Real next_damage_confined = 1.0 - 1.0 / (1.0 + confinement_factor * linear_expansion_eq);
     152      101584 :     inc_damage_confined = std::max(0.0, next_damage_confined - _damage_index_old[_qp]);
     153             :   }
     154             : 
     155             :   // combined damage as combination of unconfined + confined
     156       87920 :   const Real coef = std::max(0.0, std::min(1.0, sigma_compressive / _sigma_u));
     157       57120 :   _damage_index[_qp] = std::min(
     158      114240 :       1.0,
     159       57120 :       _damage_index_old[_qp] +
     160      168952 :           std::max(0.0, coef * inc_damage_confined + (1.0 - coef) * inc_damage_unconfined));
     161             : }
     162             : 
     163             : Real
     164      134848 : ConcreteExpansionMicrocrackingDamage::computeLinearExpansion(const RankTwoTensor & strain)
     165             : {
     166             :   // the expansion is assumed isotropic
     167      134848 :   if (_assume_isotropic_expansion)
     168      229376 :     return std::max(0.0, strain(0, 0) * _eigenstrain_factor);
     169             : 
     170             :   // otherwise we use the principal expansion directions
     171             :   else
     172             :   {
     173       13888 :     strain.symmetricEigenvalues(_eigenvalues);
     174       13888 :     return std::max(std::max(0.0, _eigenvalues[0] * _eigenstrain_factor),
     175       13888 :                     std::max(std::max(0.0, _eigenvalues[1] * _eigenstrain_factor),
     176       27776 :                              std::max(0.0, _eigenvalues[2] * _eigenstrain_factor)));
     177             :   }
     178             : }

Generated by: LCOV version 1.14