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 : }
|