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 : 45 1142 : params.addRequiredRangeCheckedParam<Real>( 46 : "microcracking_initiation_strain", 47 : "microcracking_initiation_strain > 0", 48 : "Linear strain at which the microcracking initiates (in [m/m])"); 49 : 50 1142 : params.addRequiredRangeCheckedParam<Real>( 51 : "microcracking_strain_branch", 52 : "microcracking_strain_branch > 0", 53 : "Parameter controlling the rate at which the microcracking increases (in [m/m])"); 54 : 55 1142 : params.addParam<Real>( 56 : "expansion_stress_limit", 57 : "Upper bound compressive stress beyond which damage is controlled by the external stress"); 58 : 59 571 : return params; 60 0 : } 61 : 62 438 : ConcreteExpansionMicrocrackingDamage::ConcreteExpansionMicrocrackingDamage( 63 438 : const InputParameters & parameters) 64 : : ScalarDamageBase(parameters), 65 : GuaranteeConsumer(this), 66 438 : _eigenstrain_name(getParam<MaterialPropertyName>("microcracking_eigenstrain_name")), 67 438 : _eigenstrain(getMaterialProperty<RankTwoTensor>(_eigenstrain_name)), 68 438 : _eigenstrain_old(getMaterialPropertyOld<RankTwoTensor>(_eigenstrain_name)), 69 876 : _assume_isotropic_expansion(getParam<bool>("assume_isotropic_expansion")), 70 876 : _eigenstrain_factor(getParam<Real>("eigenstrain_factor")), 71 876 : _epsilon_init(getParam<Real>("microcracking_initiation_strain")), 72 876 : _epsilon_branch(getParam<Real>("microcracking_strain_branch")), 73 876 : _include_confinement_effects(getParam<bool>("include_confinement_effects")), 74 1746 : _sigma_u(isParamValid("expansion_stress_limit") ? getParam<Real>("expansion_stress_limit") 75 : : 0.0), 76 876 : _stress(getMaterialPropertyOld<RankTwoTensor>("stress")), 77 438 : _elasticity_tensor_name(_base_name + "elasticity_tensor"), 78 438 : _elasticity_tensor(getMaterialPropertyByName<RankFourTensor>(_elasticity_tensor_name)), 79 876 : _eigenvalues(3, 0.0) 80 : { 81 1227 : if (_include_confinement_effects && !parameters.isParamSetByUser("expansion_stress_limit")) 82 3 : paramError("expansion_stress_limit", 83 : "is a required parameter for include_confinement_effects = true"); 84 : 85 435 : if (_include_confinement_effects && !(_sigma_u > 0)) 86 3 : paramError("expansion_stress_limit", 87 : "needs to be strictly > 0 for include_confinement_effects = true"); 88 432 : } 89 : 90 : void 91 423 : ConcreteExpansionMicrocrackingDamage::initialSetup() 92 : { 93 846 : if (!hasGuaranteedMaterialProperty(_elasticity_tensor_name, Guarantee::ISOTROPIC)) 94 3 : mooseError("ConcreteExpansionMicrocrackingDamage " 95 : "requires that the elasticity tensor be guaranteed isotropic"); 96 420 : } 97 : 98 : void 99 150080 : ConcreteExpansionMicrocrackingDamage::updateQpDamageIndex() 100 : { 101 150080 : const Real linear_expansion = computeLinearExpansion(_eigenstrain[_qp]); 102 : const Real inc_linear_expansion = 103 150080 : linear_expansion - computeLinearExpansion(_eigenstrain_old[_qp]); 104 : 105 150080 : _damage_index[_qp] = _damage_index_old[_qp]; 106 : 107 : // no additional expansion implies no additional damage 108 150080 : if (inc_linear_expansion < TOLERANCE) 109 22400 : return; 110 : 111 : // unconfined damage 112 : Real inc_damage_unconfined = 0.0; 113 142800 : if (linear_expansion > _epsilon_init) 114 : { 115 : const Real linear_expansion_eq = 116 : inc_linear_expansion + 117 201264 : std::max(0.0, 118 100632 : _epsilon_init + _epsilon_branch * (1.0 + 1.0 / (1.0 - _damage_index_old[_qp]))); 119 100632 : const Real next_damage_unconfined = 120 100632 : 1.0 - _epsilon_branch / (linear_expansion_eq - (_epsilon_branch + _epsilon_init)); 121 201264 : inc_damage_unconfined = std::max(0.0, next_damage_unconfined - _damage_index_old[_qp]); 122 : } 123 : 124 : // no stress control implies damage from unconfined expansion only 125 142800 : if (!_include_confinement_effects) 126 : { 127 15120 : _damage_index[_qp] = std::min(1.0, _damage_index_old[_qp] + inc_damage_unconfined); 128 15120 : return; 129 : } 130 : 131 : // confined damage 132 : Real inc_damage_confined = 0.0; 133 : 134 : // sum of compressive stress (positive value) 135 127680 : _stress[_qp].symmetricEigenvalues(_eigenvalues); 136 342496 : const Real sigma_compressive = -std::min(0.0, _eigenvalues[0]) - std::min(0.0, _eigenvalues[1]) - 137 127680 : std::min(0.0, _eigenvalues[2]); 138 : 139 127680 : if (sigma_compressive > 0.0) 140 : { 141 115332 : const Real E = ElasticityTensorTools::getIsotropicYoungsModulus(_elasticity_tensor[_qp]); 142 115332 : const Real confinement_factor = E / std::max(_sigma_u, sigma_compressive); 143 : const Real linear_expansion_eq = 144 : inc_linear_expansion + 145 115332 : std::max(0.0, 146 115332 : _damage_index_old[_qp] / (confinement_factor * (1.0 - _damage_index_old[_qp]))); 147 : 148 115332 : const Real next_damage_confined = 1.0 - 1.0 / (1.0 + confinement_factor * linear_expansion_eq); 149 230664 : inc_damage_confined = std::max(0.0, next_damage_confined - _damage_index_old[_qp]); 150 : } 151 : 152 : // combined damage as combination of unconfined + confined 153 195580 : const Real coef = std::max(0.0, std::min(1.0, sigma_compressive / _sigma_u)); 154 127680 : _damage_index[_qp] = std::min( 155 255360 : 1.0, 156 127680 : _damage_index_old[_qp] + 157 377804 : std::max(0.0, coef * inc_damage_confined + (1.0 - coef) * inc_damage_unconfined)); 158 : } 159 : 160 : Real 161 300160 : ConcreteExpansionMicrocrackingDamage::computeLinearExpansion(const RankTwoTensor & strain) 162 : { 163 : // the expansion is assumed isotropic 164 300160 : if (_assume_isotropic_expansion) 165 511448 : return std::max(0.0, strain(0, 0) * _eigenstrain_factor); 166 : 167 : // otherwise we use the principal expansion directions 168 : else 169 : { 170 31024 : strain.symmetricEigenvalues(_eigenvalues); 171 31024 : return std::max(std::max(0.0, _eigenvalues[0] * _eigenstrain_factor), 172 31024 : std::max(std::max(0.0, _eigenvalues[1] * _eigenstrain_factor), 173 62048 : std::max(0.0, _eigenvalues[2] * _eigenstrain_factor))); 174 : } 175 : }