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 "CrystalPlasticityHCPDislocationSlipBeyerleinUpdate.h"
11 : #include "libmesh/int_range.h"
12 :
13 : registerMooseObject("TensorMechanicsApp", CrystalPlasticityHCPDislocationSlipBeyerleinUpdate);
14 :
15 : InputParameters
16 142 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate::validParams()
17 : {
18 142 : InputParameters params = CrystalPlasticityStressUpdateBase::validParams();
19 142 : params.addClassDescription("Two-term dislocation slip model for hexagonal close packed crystals "
20 : "from Beyerline and Tome");
21 :
22 284 : params.set<MooseEnum>("crystal_lattice_type") = "HCP";
23 142 : params.suppressParameter<MooseEnum>("crystal_lattice_type");
24 :
25 284 : params.addCoupledVar("temperature", "The name of the temperature variable");
26 284 : params.addRequiredRangeCheckedParam<Real>(
27 : "initial_forest_dislocation_density",
28 : "initial_forest_dislocation_density>0",
29 : "The initial density of the forest dislocations, in 1/mm^2, assumed "
30 : "to be split evenly among all slip systems");
31 284 : params.addRequiredRangeCheckedParam<Real>(
32 : "initial_substructure_density",
33 : "initial_substructure_density>0",
34 : "The initial total density of the sessile dislocations, in 1/mm^2");
35 :
36 284 : params.addParam<unsigned int>(
37 : "slip_system_modes",
38 284 : 1,
39 : "Number of different types of slip systems in this HCP crystal, e.g. for a material with "
40 : "basal<a>, prismatic<a>, and pyramidal<a> active slip systems, this number would be 3");
41 284 : params.addParam<std::vector<unsigned int>>(
42 : "number_slip_systems_per_mode",
43 142 : std::vector<unsigned int>(),
44 : "The number of slip systems per each slip system type. The sum of the entries of the vector "
45 : "given here must equal the value given for the total number of slip systems.");
46 284 : params.addParam<std::vector<Real>>(
47 : "lattice_friction_per_mode",
48 142 : std::vector<Real>(),
49 : "Value of the lattice friction for each type of the slip system, units of MPa. The order "
50 : "must be consistent with the number of slip systems per type vector.");
51 :
52 284 : params.addParam<std::vector<Real>>(
53 : "effective_shear_modulus_per_mode",
54 142 : std::vector<Real>(),
55 : "Effective isotropic shear modulus value, mu, in MPa. The order "
56 : "must be consistent with the number of slip systems per type vector.");
57 :
58 284 : params.addParam<std::vector<Real>>(
59 : "burgers_vector_per_mode",
60 142 : std::vector<Real>(),
61 : "Value of the Burgers vector, b, for each type of the slip system, units of mm. The order "
62 : "must "
63 : "be consistent with the number of slip systems per type vector.");
64 284 : params.addParam<std::vector<Real>>(
65 : "slip_generation_coefficient_per_mode",
66 142 : std::vector<Real>(),
67 : "Slip dislocation generation coefficient value for each type of the slip system, k_1, units "
68 : "of 1/mm. The order "
69 : "must be consistent with the number of slip systems per type vector.");
70 284 : params.addParam<std::vector<Real>>(
71 : "normalized_slip_activiation_energy_per_mode",
72 142 : std::vector<Real>(),
73 : "Value of the slip dislocation attraction activation energy for each type of the slip "
74 : "system, g, dimensionless. The order must be consistent with the number of slip systems per "
75 : "type vector.");
76 284 : params.addParam<std::vector<Real>>(
77 : "slip_energy_proportionality_factor_per_mode",
78 142 : std::vector<Real>(),
79 : "Value of the the dislocation slip attraction energy proportionality factor for each type of "
80 : "the slip system, D, units of MPa. The order must be consistent with the number of slip "
81 : "systems "
82 : "per type vector.");
83 284 : params.addParam<std::vector<Real>>(
84 : "substructure_rate_coefficient_per_mode",
85 142 : std::vector<Real>(),
86 : "Material-independent rate constant that accounts for locking of slip dislocations in "
87 : "sessile substructure dislocation segments, q, dimensionless. This value is often determined "
88 : "through dislocation dynamics calculations. The order must be consistent with the number of "
89 : "slip systems per type vector.");
90 :
91 284 : params.addParam<Real>("gamma_o", 1.0e-3, "Reference strain rate on each slip system, in 1/s");
92 284 : params.addParam<Real>("strain_rate_sensitivity_exponent",
93 284 : 0.05,
94 : "The strain rate sensitivity exponent for the power law relationship of "
95 : "resolved shear stress");
96 284 : params.addParam<Real>("forest_interaction_parameter",
97 284 : 0.9,
98 : "Forest dislocation interaction parameter, Chi, dimensionless.");
99 284 : params.addParam<Real>("Boltzman_constant", 1.38065e-20, "Boltzman constant, in MPa-mm^3/K");
100 426 : params.addRangeCheckedParam<Real>("applied_strain_rate",
101 284 : 1.0e-4,
102 : "applied_strain_rate<=1.0e-3 & applied_strain_rate>=1.0e-5",
103 : "Value of the applied macroscopic strain rate and should "
104 : "correspond to the simulation loading conditions, in 1/s.");
105 284 : params.addParam<Real>("reference_macroscopic_strain_rate",
106 284 : 1.0e7,
107 : "Value of the reference macroscopic strain rate for the thermal "
108 : "dislocation attraction, in 1/s.");
109 284 : params.addParam<Real>("substructure_hardening_coefficient",
110 284 : 0.086,
111 : "Value of the coefficient for the expanded Taylor hardening substructure "
112 : "hardening relation, set to recover the Taylor hardening law for low "
113 : "substructure densities, k_{sub}, dimensionless.");
114 284 : params.addParam<std::vector<Real>>(
115 : "Hall_Petch_like_constant_per_mode",
116 142 : std::vector<Real>(),
117 : "The microstructure Hall-Petch like coefficient value used to capture the influence of grain "
118 : "size on slip system resistance in the absence of twin dislocations, dimensionless");
119 284 : params.addRequiredRangeCheckedParam<Real>(
120 : "grain_size", "grain_size>0", "Value of the crystal grain size, in mm");
121 :
122 284 : params.addParam<MaterialPropertyName>(
123 : "total_twin_volume_fraction",
124 : "Total twin volume fraction, if twinning is considered in the simulation");
125 :
126 142 : return params;
127 0 : }
128 :
129 110 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate::
130 110 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate(const InputParameters & parameters)
131 : : CrystalPlasticityStressUpdateBase(parameters),
132 :
133 106 : _temperature(coupledValue("temperature")),
134 106 : _forest_dislocation_density(
135 106 : declareProperty<std::vector<Real>>(_base_name + "forest_dislocation_density")),
136 106 : _forest_dislocation_density_old(
137 106 : getMaterialPropertyOld<std::vector<Real>>(_base_name + "forest_dislocation_density")),
138 106 : _forest_dislocation_increment(
139 106 : declareProperty<std::vector<Real>>(_base_name + "forest_dislocation_increment")),
140 106 : _forest_dislocations_removed_increment(
141 106 : declareProperty<std::vector<Real>>(_base_name + "_forest_dislocations_removed_increment")),
142 212 : _initial_forest_dislocation_density(getParam<Real>("initial_forest_dislocation_density")),
143 106 : _total_substructure_density(declareProperty<Real>(_base_name + "total_substructure_density")),
144 106 : _total_substructure_density_old(
145 106 : getMaterialPropertyOld<Real>(_base_name + "total_substructure_density")),
146 106 : _total_substructure_density_increment(
147 106 : declareProperty<Real>(_base_name + "total_substructure_increment")),
148 212 : _initial_substructure_density(getParam<Real>("initial_substructure_density")),
149 :
150 212 : _slip_system_modes(getParam<unsigned int>("slip_system_modes")),
151 212 : _number_slip_systems_per_mode(
152 : getParam<std::vector<unsigned int>>("number_slip_systems_per_mode")),
153 212 : _lattice_friction(getParam<std::vector<Real>>("lattice_friction_per_mode")),
154 :
155 212 : _reference_strain_rate(getParam<Real>("gamma_o")),
156 212 : _rate_sensitivity_exponent(getParam<Real>("strain_rate_sensitivity_exponent")),
157 :
158 212 : _burgers_vector(getParam<std::vector<Real>>("burgers_vector_per_mode")),
159 212 : _slip_generation_coefficient(
160 : getParam<std::vector<Real>>("slip_generation_coefficient_per_mode")),
161 212 : _slip_activation_energy(
162 : getParam<std::vector<Real>>("normalized_slip_activiation_energy_per_mode")),
163 212 : _proportionality_factor(
164 : getParam<std::vector<Real>>("slip_energy_proportionality_factor_per_mode")),
165 212 : _forest_interaction_coefficient(getParam<Real>("forest_interaction_parameter")),
166 212 : _boltzman_constant(getParam<Real>("Boltzman_constant")),
167 212 : _macro_applied_strain_rate(getParam<Real>("applied_strain_rate")),
168 212 : _macro_reference_strain_rate(getParam<Real>("reference_macroscopic_strain_rate")),
169 :
170 212 : _shear_modulus(getParam<std::vector<Real>>("effective_shear_modulus_per_mode")),
171 212 : _substructure_rate_coefficient(
172 : getParam<std::vector<Real>>("substructure_rate_coefficient_per_mode")),
173 212 : _substructure_hardening_coefficient(getParam<Real>("substructure_hardening_coefficient")),
174 212 : _hallpetch_like_coefficient(getParam<std::vector<Real>>("Hall_Petch_like_constant_per_mode")),
175 212 : _grain_size(getParam<Real>("grain_size")),
176 :
177 : // Twinning contributions, if used
178 106 : _include_twinning_in_Lp(parameters.isParamValid("total_twin_volume_fraction")),
179 212 : _twin_volume_fraction_total(_include_twinning_in_Lp
180 115 : ? &getMaterialPropertyOld<Real>("total_twin_volume_fraction")
181 322 : : nullptr)
182 : {
183 : // resize local caching vectors used for substepping
184 106 : _previous_substep_slip_resistance.resize(_number_slip_systems);
185 106 : _previous_substep_forest_dislocations.resize(_number_slip_systems);
186 106 : _slip_resistance_before_update.resize(_number_slip_systems);
187 106 : _forest_dislocations_before_update.resize(_number_slip_systems);
188 :
189 : // check that the number of slip systems is equal to the sum of the types of slip system
190 106 : if (_number_slip_systems_per_mode.size() != _slip_system_modes)
191 1 : paramError("number_slip_systems_per_mode",
192 : "The size the number of slip systems per mode is not equal to the number of slip "
193 : "system types.");
194 :
195 : // Check that the number of slip mode dependent parameters is given matches the number of slip
196 : // modes
197 105 : if (_burgers_vector.size() != _slip_system_modes)
198 1 : paramError("burgers_vector_per_mode",
199 : "Please ensure that the size of burgers_vector_per_mode equals the value supplied "
200 : "for slip_system_modes");
201 :
202 104 : if (_slip_generation_coefficient.size() != _slip_system_modes)
203 1 : paramError("slip_generation_coefficient_per_mode",
204 : "Please ensure that the size of slip_generation_coefficient_per_mode equals the "
205 : "value supplied for slip_system_modes");
206 :
207 103 : if (_slip_activation_energy.size() != _slip_system_modes)
208 1 : paramError("normalized_slip_activiation_energy_per_mode",
209 : "Please ensure that the size of normalized_slip_activiation_energy_per_mode equals "
210 : "the value supplied for slip_system_modes");
211 :
212 102 : if (_proportionality_factor.size() != _slip_system_modes)
213 1 : paramError("slip_energy_proportionality_factor_per_mode",
214 : "Please ensure that the size of slip_energy_proportionality_factor_per_mode equals "
215 : "the value supplied for slip_system_modes");
216 :
217 101 : if (_shear_modulus.size() != _slip_system_modes)
218 1 : paramError("effective_shear_modulus_per_mode",
219 : "Please ensure that the size of effective_shear_modulus_per_mode equals the "
220 : "value supplied for slip_system_modes");
221 :
222 100 : if (_substructure_rate_coefficient.size() != _slip_system_modes)
223 1 : paramError("substructure_rate_coefficient_per_mode",
224 : "Please ensure that the size of substructure_rate_coefficient_per_mode equals the "
225 : "value supplied for slip_system_modes");
226 :
227 99 : if (_hallpetch_like_coefficient.size() != _slip_system_modes)
228 1 : paramError("Hall_Petch_like_constant_per_mode",
229 : "Please ensure that the size of Hall_Petch_like_constant_per_mode equals the value "
230 : "supplied for slip_system_modes");
231 :
232 98 : if (_lattice_friction.size() != _slip_system_modes)
233 1 : paramError("lattice_friction_per_mode",
234 : "Please ensure that the size of lattice_friction_per_mode equals the value supplied "
235 : "for slip_system_modes");
236 :
237 : unsigned int sum = 0;
238 300 : for (const auto i : make_range(_slip_system_modes))
239 203 : sum += _number_slip_systems_per_mode[i];
240 97 : if (sum != _number_slip_systems)
241 1 : paramError("slip_system_modes",
242 : "The number of slip systems and the sum of the slip systems in each of the slip "
243 : "system modes are not equal");
244 96 : }
245 :
246 : void
247 5184 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate::initQpStatefulProperties()
248 : {
249 5184 : CrystalPlasticityStressUpdateBase::initQpStatefulProperties();
250 :
251 : // Resize constitutive-model specific material properties
252 5184 : _forest_dislocation_density[_qp].resize(_number_slip_systems);
253 5184 : _forest_dislocation_increment[_qp].resize(_number_slip_systems);
254 5184 : _forest_dislocations_removed_increment[_qp].resize(_number_slip_systems);
255 5184 : _initial_lattice_friction.resize(_number_slip_systems);
256 :
257 : // Set constitutive-model specific initial values from parameters
258 5184 : const Real forest_density_per_system = _initial_forest_dislocation_density / _number_slip_systems;
259 76160 : for (const auto i : make_range(_number_slip_systems))
260 : {
261 70976 : _forest_dislocation_density[_qp][i] = forest_density_per_system;
262 70976 : _forest_dislocation_increment[_qp][i] = 0.0;
263 70976 : _slip_increment[_qp][i] = 0.0;
264 : }
265 :
266 : // Set initial resistance from lattice friction, which is type dependent
267 : unsigned int slip_mode = 0;
268 : unsigned int counter_adjustment = 0;
269 76160 : for (const auto i : make_range(_number_slip_systems))
270 : {
271 70976 : if ((i - counter_adjustment) < _number_slip_systems_per_mode[slip_mode])
272 66176 : _initial_lattice_friction(i) = _lattice_friction[slip_mode];
273 : else
274 : {
275 4800 : counter_adjustment += _number_slip_systems_per_mode[slip_mode];
276 4800 : ++slip_mode;
277 4800 : _initial_lattice_friction(i) = _lattice_friction[slip_mode];
278 : }
279 : }
280 :
281 5184 : calculateGrainSizeResistance();
282 :
283 76160 : for (const auto i : make_range(_number_slip_systems))
284 70976 : _slip_resistance[_qp][i] = _initial_lattice_friction(i);
285 :
286 5184 : _total_substructure_density[_qp] = _initial_substructure_density;
287 5184 : _total_substructure_density_increment[_qp] = 0.0;
288 5184 : }
289 :
290 : void
291 5184 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate::calculateGrainSizeResistance()
292 : {
293 : unsigned int slip_mode = 0;
294 : unsigned int counter_adjustment = 0;
295 76160 : for (const auto i : make_range(_number_slip_systems))
296 : {
297 : Real hallpetch_burgers_term = 0.0;
298 70976 : if ((i - counter_adjustment) < _number_slip_systems_per_mode[slip_mode])
299 66176 : hallpetch_burgers_term = _hallpetch_like_coefficient[slip_mode] * _shear_modulus[slip_mode] *
300 66176 : std::sqrt(_burgers_vector[slip_mode]);
301 : else
302 : {
303 4800 : counter_adjustment += _number_slip_systems_per_mode[slip_mode];
304 4800 : ++slip_mode;
305 4800 : hallpetch_burgers_term = _hallpetch_like_coefficient[slip_mode] * _shear_modulus[slip_mode] *
306 4800 : std::sqrt(_burgers_vector[slip_mode]);
307 : }
308 70976 : _initial_lattice_friction(i) += hallpetch_burgers_term / std::sqrt(_grain_size);
309 : }
310 5184 : }
311 :
312 : void
313 239010 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate::setInitialConstitutiveVariableValues()
314 : {
315 239010 : _slip_resistance[_qp] = _slip_resistance_old[_qp];
316 239010 : _previous_substep_slip_resistance = _slip_resistance_old[_qp];
317 :
318 239010 : _forest_dislocation_density[_qp] = _forest_dislocation_density_old[_qp];
319 239010 : _previous_substep_forest_dislocations = _forest_dislocation_density_old[_qp];
320 :
321 239010 : _total_substructure_density[_qp] = _total_substructure_density_old[_qp];
322 239010 : _previous_substep_total_substructure_density = _total_substructure_density_old[_qp];
323 239010 : }
324 :
325 : void
326 447138 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate::setSubstepConstitutiveVariableValues()
327 : {
328 447138 : _slip_resistance[_qp] = _previous_substep_slip_resistance;
329 447138 : _forest_dislocation_density[_qp] = _previous_substep_forest_dislocations;
330 447138 : _total_substructure_density[_qp] = _previous_substep_total_substructure_density;
331 447138 : }
332 :
333 : bool
334 2383110 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate::calculateSlipRate()
335 : {
336 32185481 : for (const auto i : make_range(_number_slip_systems))
337 : {
338 29874058 : Real driving_force = std::abs(_tau[_qp][i] / _slip_resistance[_qp][i]);
339 29874058 : if (driving_force < _zero_tol)
340 5385786 : _slip_increment[_qp][i] = 0.0;
341 : else
342 : {
343 24488272 : _slip_increment[_qp][i] =
344 24488272 : _reference_strain_rate * std::pow(driving_force, (1.0 / _rate_sensitivity_exponent));
345 24488272 : if (_tau[_qp][i] < 0.0)
346 12318739 : _slip_increment[_qp][i] *= -1.0;
347 : }
348 29874058 : if (std::abs(_slip_increment[_qp][i]) * _substep_dt > _slip_incr_tol)
349 : {
350 71687 : if (_print_convergence_message)
351 1 : mooseWarning("Maximum allowable slip increment exceeded ",
352 1 : std::abs(_slip_increment[_qp][i]) * _substep_dt);
353 : return false;
354 : }
355 : }
356 : return true;
357 : }
358 :
359 : void
360 2311423 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate::calculateEquivalentSlipIncrement(
361 : RankTwoTensor & equivalent_slip_increment)
362 : {
363 2311423 : if (_include_twinning_in_Lp)
364 : {
365 2025040 : for (const auto i : make_range(_number_slip_systems))
366 1898475 : equivalent_slip_increment += (1.0 - (*_twin_volume_fraction_total)[_qp]) *
367 1898475 : _flow_direction[_qp][i] * _slip_increment[_qp][i] * _substep_dt;
368 : }
369 : else // if no twinning volume fraction material property supplied, use base class
370 2184858 : CrystalPlasticityStressUpdateBase::calculateEquivalentSlipIncrement(equivalent_slip_increment);
371 2311423 : }
372 :
373 : void
374 2311423 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate::calculateConstitutiveSlipDerivative(
375 : std::vector<Real> & dslip_dtau)
376 : {
377 31898752 : for (const auto i : make_range(_number_slip_systems))
378 : {
379 29587329 : if (MooseUtils::absoluteFuzzyEqual(_tau[_qp][i], 0.0))
380 4493569 : dslip_dtau[i] = 0.0;
381 : else
382 25093760 : dslip_dtau[i] = _slip_increment[_qp][i] /
383 25093760 : (_rate_sensitivity_exponent * std::abs(_tau[_qp][i])) * _substep_dt;
384 : }
385 2311423 : }
386 :
387 : bool
388 461034 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate::areConstitutiveStateVariablesConverged()
389 : {
390 461034 : if (isConstitutiveStateVariableConverged(_forest_dislocation_density[_qp],
391 461034 : _forest_dislocations_before_update,
392 461034 : _previous_substep_forest_dislocations,
393 844546 : _rel_state_var_tol) &&
394 834292 : isSubstructureDislocationDensityConverged() &&
395 373258 : isConstitutiveStateVariableConverged(_slip_resistance[_qp],
396 373258 : _slip_resistance_before_update,
397 373258 : _previous_substep_slip_resistance,
398 373258 : _resistance_tol))
399 : return true;
400 : return false;
401 : }
402 :
403 : bool
404 383512 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate::isSubstructureDislocationDensityConverged()
405 : {
406 : bool converged_flag = true;
407 :
408 : Real substructure_diff =
409 383512 : std::abs(_total_substructure_density_before_update - _total_substructure_density[_qp]);
410 :
411 383512 : if (_previous_substep_total_substructure_density < _zero_tol && substructure_diff > _zero_tol)
412 : converged_flag = false;
413 383512 : else if (_previous_substep_total_substructure_density > _zero_tol &&
414 383512 : substructure_diff > _rel_state_var_tol * _previous_substep_total_substructure_density)
415 : converged_flag = false;
416 :
417 383512 : return converged_flag;
418 : }
419 :
420 : void
421 372490 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate::updateSubstepConstitutiveVariableValues()
422 : {
423 372490 : _previous_substep_slip_resistance = _slip_resistance[_qp];
424 372490 : _previous_substep_forest_dislocations = _forest_dislocation_density[_qp];
425 372490 : _previous_substep_total_substructure_density = _total_substructure_density[_qp];
426 372490 : }
427 :
428 : void
429 461034 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate::cacheStateVariablesBeforeUpdate()
430 : {
431 461034 : _slip_resistance_before_update = _slip_resistance[_qp];
432 461034 : _forest_dislocations_before_update = _forest_dislocation_density[_qp];
433 461034 : _total_substructure_density_before_update = _total_substructure_density[_qp];
434 461034 : }
435 :
436 : void
437 461034 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate::calculateStateVariableEvolutionRateComponent()
438 : {
439 461034 : calculateForestDislocationEvolutionIncrement();
440 461034 : calculateSubstructureDensityEvolutionIncrement();
441 461034 : }
442 :
443 : void
444 461034 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate::calculateForestDislocationEvolutionIncrement()
445 : {
446 461034 : DenseVector<Real> k1_term(_number_slip_systems);
447 461034 : DenseVector<Real> k2_term(_number_slip_systems);
448 :
449 : const Real temperature_strain_term =
450 461034 : _boltzman_constant * _temperature[_qp] *
451 461034 : std::log(_macro_applied_strain_rate / _macro_reference_strain_rate);
452 :
453 : // solve first for the coefficients, which depend on the given slip mode
454 : unsigned int slip_mode = 0;
455 : unsigned int counter_adjustment = 0;
456 6844228 : for (const auto i : make_range(_number_slip_systems))
457 : {
458 : Real interaction_term = 0.0;
459 : Real volume_term = 0.0;
460 6383194 : if ((i - counter_adjustment) < _number_slip_systems_per_mode[slip_mode])
461 : {
462 5959272 : k1_term(i) = _slip_generation_coefficient[slip_mode];
463 5959272 : interaction_term = _forest_interaction_coefficient * _burgers_vector[slip_mode] /
464 : _slip_activation_energy[slip_mode];
465 5959272 : volume_term =
466 5959272 : _proportionality_factor[slip_mode] * Utility::pow<3>(_burgers_vector[slip_mode]);
467 : }
468 : else
469 : {
470 423922 : counter_adjustment += _number_slip_systems_per_mode[slip_mode];
471 423922 : ++slip_mode;
472 :
473 423922 : k1_term(i) = _slip_generation_coefficient[slip_mode];
474 423922 : interaction_term = _forest_interaction_coefficient * _burgers_vector[slip_mode] /
475 : _slip_activation_energy[slip_mode];
476 423922 : volume_term =
477 423922 : _proportionality_factor[slip_mode] * Utility::pow<3>(_burgers_vector[slip_mode]);
478 : }
479 6383194 : k2_term(i) = interaction_term * k1_term(i) * (1.0 - temperature_strain_term / volume_term);
480 : }
481 :
482 6844228 : for (const auto i : make_range(_number_slip_systems))
483 : {
484 6383194 : const Real abs_slip_increment = std::abs(_slip_increment[_qp][i]);
485 : Real generated_dislocations = 0.0;
486 :
487 6383194 : if (_forest_dislocation_density[_qp][i] > 0.0)
488 6383194 : generated_dislocations = k1_term(i) * std::sqrt(_forest_dislocation_density[_qp][i]) *
489 6383194 : abs_slip_increment * _substep_dt;
490 :
491 6383194 : _forest_dislocations_removed_increment[_qp][i] =
492 6383194 : k2_term(i) * _forest_dislocation_density[_qp][i] * abs_slip_increment * _substep_dt;
493 :
494 6383194 : _forest_dislocation_increment[_qp][i] =
495 6383194 : generated_dislocations - _forest_dislocations_removed_increment[_qp][i];
496 : }
497 461034 : }
498 :
499 : void
500 461034 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate::calculateSubstructureDensityEvolutionIncrement()
501 : {
502 : // calculate the generation coefficient, which depends on the slip mode
503 461034 : DenseVector<Real> generation_term(_number_slip_systems);
504 :
505 : unsigned int slip_mode = 0;
506 : unsigned int counter_adjustment = 0;
507 6844228 : for (const auto i : make_range(_number_slip_systems))
508 : {
509 6383194 : if ((i - counter_adjustment) < _number_slip_systems_per_mode[slip_mode])
510 5959272 : generation_term(i) = _substructure_rate_coefficient[slip_mode] * _burgers_vector[slip_mode];
511 : else
512 : {
513 423922 : counter_adjustment += _number_slip_systems_per_mode[slip_mode];
514 423922 : ++slip_mode;
515 423922 : generation_term(i) = _substructure_rate_coefficient[slip_mode] * _burgers_vector[slip_mode];
516 : }
517 : }
518 :
519 : // perform the summing calculation over all slip systems
520 461034 : _total_substructure_density_increment[_qp] = 0.0;
521 461034 : const Real sqrt_substructures = std::sqrt(_total_substructure_density[_qp]);
522 :
523 6844228 : for (const auto i : make_range(_number_slip_systems))
524 6383194 : _total_substructure_density_increment[_qp] +=
525 6383194 : generation_term(i) * sqrt_substructures * _forest_dislocations_removed_increment[_qp][i];
526 461034 : }
527 :
528 : void
529 908172 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate::calculateSlipResistance()
530 : {
531 908172 : DenseVector<Real> forest_hardening(_number_slip_systems);
532 908172 : DenseVector<Real> substructure_hardening(_number_slip_systems);
533 :
534 : unsigned int slip_mode = 0;
535 : unsigned int counter_adjustment = 0;
536 13813412 : for (const auto i : make_range(_number_slip_systems))
537 : {
538 : Real burgers = 0.0;
539 : Real shear_modulus = 0.0;
540 12905240 : if ((i - counter_adjustment) < _number_slip_systems_per_mode[slip_mode])
541 : {
542 12042436 : burgers = _burgers_vector[slip_mode];
543 12042436 : shear_modulus = _shear_modulus[slip_mode];
544 : }
545 : else
546 : {
547 862804 : counter_adjustment += _number_slip_systems_per_mode[slip_mode];
548 862804 : ++slip_mode;
549 862804 : burgers = _burgers_vector[slip_mode];
550 862804 : shear_modulus = _shear_modulus[slip_mode];
551 : }
552 :
553 : // forest dislocation hardening
554 12905240 : if (_forest_dislocation_density[_qp][i] > 0.0)
555 12905240 : forest_hardening(i) = _forest_interaction_coefficient * burgers * shear_modulus *
556 12905240 : std::sqrt(_forest_dislocation_density[_qp][i]);
557 : else
558 0 : forest_hardening(i) = 0.0;
559 :
560 : // substructure dislocation hardening
561 12905240 : if (_total_substructure_density[_qp] > 0.0)
562 : {
563 12905240 : const Real spacing_term = burgers * std::sqrt(_total_substructure_density[_qp]);
564 12905240 : substructure_hardening(i) = _substructure_hardening_coefficient * shear_modulus *
565 12905240 : spacing_term * std::log10(1.0 / spacing_term);
566 : }
567 : else
568 0 : substructure_hardening(i) = 0.0;
569 : }
570 :
571 : // have the constant initial value, while it's not a function of temperature, sum
572 13813412 : for (const auto i : make_range(_number_slip_systems))
573 12905240 : _slip_resistance[_qp][i] =
574 12905240 : _initial_lattice_friction(i) + forest_hardening(i) + substructure_hardening(i);
575 908172 : }
576 :
577 : bool
578 461034 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate::updateStateVariables()
579 : {
580 461034 : if (calculateForestDislocationDensity() && calculateSubstructureDislocationDensity())
581 : return true;
582 : else
583 0 : return false;
584 : }
585 :
586 : bool
587 461034 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate::calculateForestDislocationDensity()
588 : {
589 6844228 : for (const auto i : make_range(_number_slip_systems))
590 : {
591 6383194 : if (_previous_substep_forest_dislocations[i] < _zero_tol &&
592 241590 : _forest_dislocation_increment[_qp][i] < 0.0)
593 0 : _forest_dislocation_density[_qp][i] = _previous_substep_forest_dislocations[i];
594 : else
595 6383194 : _forest_dislocation_density[_qp][i] =
596 6383194 : _previous_substep_forest_dislocations[i] + _forest_dislocation_increment[_qp][i];
597 :
598 6383194 : if (_forest_dislocation_density[_qp][i] < 0.0)
599 : return false;
600 : }
601 : return true;
602 : }
603 :
604 : bool
605 461034 : CrystalPlasticityHCPDislocationSlipBeyerleinUpdate::calculateSubstructureDislocationDensity()
606 : {
607 461034 : if (_previous_substep_total_substructure_density < _zero_tol &&
608 0 : _total_substructure_density_increment[_qp] < 0.0)
609 0 : _total_substructure_density[_qp] = _previous_substep_total_substructure_density;
610 : else
611 461034 : _total_substructure_density[_qp] =
612 461034 : _previous_substep_total_substructure_density + _total_substructure_density_increment[_qp];
613 :
614 461034 : if (_total_substructure_density[_qp] < 0.0)
615 0 : return false;
616 :
617 : return true;
618 : }
|