13 #include "MooseException.h"
24 params.addClassDescription(
"Compute state (stress and internal parameters such as plastic "
25 "strains and internal parameters) using an iterative process. "
26 "Combinations of creep models and plastic models may be used.");
27 params.addParam<
unsigned int>(
"max_iterations",
29 "Maximum number of the stress update "
30 "iterations over the stress change after all "
31 "update materials are called");
32 params.addParam<Real>(
"relative_tolerance",
34 "Relative convergence tolerance for the stress "
35 "update iterations over the stress change "
36 "after all update materials are called");
37 params.addParam<Real>(
"absolute_tolerance",
39 "Absolute convergence tolerance for the stress "
40 "update iterations over the stress change "
41 "after all update materials are called");
42 params.addParam<
bool>(
43 "internal_solve_full_iteration_history",
45 "Set to true to output stress update iteration information over the stress change");
46 params.addParam<
bool>(
"perform_finite_strain_rotations",
48 "Tensors are correctly rotated in "
49 "finite-strain simulations. For "
50 "optimal performance you can set "
51 "this to 'false' if you are only "
52 "ever using small strains");
53 MooseEnum tangent_operator(
"elastic nonlinear",
"nonlinear");
54 params.addParam<MooseEnum>(
57 "Type of tangent operator to return. 'elastic': return the "
58 "elasticity tensor. 'nonlinear': return the full, general consistent tangent "
60 params.addRequiredParam<std::vector<MaterialName>>(
62 "The material objects to use to calculate stress and inelastic strains. "
63 "Note: specify creep models first and plasticity models second.");
64 params.addParam<std::vector<Real>>(
"combined_inelastic_strain_weights",
65 "The combined_inelastic_strain Material Property is a "
66 "weighted sum of the model inelastic strains. This parameter "
67 "is a vector of weights, of the same length as "
68 "inelastic_models. Default = '1 1 ... 1'. This "
69 "parameter is set to 1 if the number of models = 1");
70 params.addParam<
bool>(
71 "cycle_models",
false,
"At timestep N use only inelastic model N % num_models.");
72 params.addParam<MaterialName>(
"damage_model",
"Name of the damage model");
79 _max_iterations(parameters.get<unsigned int>(
"max_iterations")),
80 _relative_tolerance(parameters.get<Real>(
"relative_tolerance")),
81 _absolute_tolerance(parameters.get<Real>(
"absolute_tolerance")),
82 _internal_solve_full_iteration_history(getParam<bool>(
"internal_solve_full_iteration_history")),
83 _perform_finite_strain_rotations(getParam<bool>(
"perform_finite_strain_rotations")),
84 _elastic_strain_old(getMaterialPropertyOld<
RankTwoTensor>(_base_name +
"elastic_strain")),
85 _strain_increment(getMaterialProperty<
RankTwoTensor>(_base_name +
"strain_increment")),
86 _inelastic_strain(declareProperty<
RankTwoTensor>(_base_name +
"combined_inelastic_strain")),
87 _inelastic_strain_old(
88 getMaterialPropertyOld<
RankTwoTensor>(_base_name +
"combined_inelastic_strain")),
89 _tangent_operator_type(getParam<MooseEnum>(
"tangent_operator").getEnum<
TangentOperatorEnum>()),
90 _num_models(getParam<std::vector<MaterialName>>(
"inelastic_models").size()),
91 _tangent_computation_flag(_num_models, false),
93 _inelastic_weights(isParamValid(
"combined_inelastic_strain_weights")
94 ? getParam<std::vector<Real>>(
"combined_inelastic_strain_weights")
95 : std::vector<Real>(_num_models, true)),
96 _consistent_tangent_operator(_num_models),
97 _cycle_models(getParam<bool>(
"cycle_models")),
98 _matl_timestep_limit(declareProperty<Real>(
"matl_timestep_limit")),
99 _identity_symmetric_four(
RankFourTensor::initIdentitySymmetricFour),
100 _all_models_isotropic(true),
101 _damage_model(isParamValid(
"damage_model")
102 ? dynamic_cast<
DamageBase *>(&getMaterial(
"damage_model"))
107 "ComputeMultipleInelasticStress: combined_inelastic_strain_weights must contain the same "
108 "number of entries as inelastic_models ",
127 std::vector<MaterialName> models = getParam<std::vector<MaterialName>>(
"inelastic_models");
131 StressUpdateBase * rrr = dynamic_cast<StressUpdateBase *>(&getMaterialByName(models[i]));
138 mooseError(
"Model " + models[i] +
139 " requires an isotropic elasticity tensor, but the one supplied is not "
140 "guaranteed isotropic");
143 mooseError(
"Model " + models[i] +
" is not compatible with ComputeMultipleInelasticStress");
155 bool full_present =
false;
156 bool partial_present =
false;
167 partial_present =
true;
172 if (full_present && partial_present)
175 ": Models that calculate the full tangent operator and the partial tangent "
176 "operator are being combined. Either set tangent_operator to elastic, implement "
177 "the corrent tangent formulations, or use different models.");
181 paramError(
"damage_model",
183 " is not compatible with ComputeMultipleInelasticStress");
235 if (_fe_problem.currentlyComputingJacobian())
244 elastic_strain_increment,
245 combined_inelastic_strain_increment);
247 updateQpState(elastic_strain_increment, combined_inelastic_strain_increment);
263 if (force_elasticity_rotation ||
276 _console << std::endl
277 <<
"iteration output for ComputeMultipleInelasticStress solve:"
278 <<
" time=" << _t <<
" int_pt=" << _qp << std::endl;
280 Real l2norm_delta_stress;
281 Real first_l2norm_delta_stress = 1.0;
284 std::vector<RankTwoTensor> inelastic_strain_increment;
287 for (
unsigned i_rmm = 0; i_rmm <
_models.size(); ++i_rmm)
288 inelastic_strain_increment[i_rmm].zero();
294 for (
unsigned i_rmm = 0; i_rmm <
_num_models; ++i_rmm)
302 for (
unsigned j_rmm = 0; j_rmm <
_num_models; ++j_rmm)
304 elastic_strain_increment -= inelastic_strain_increment[j_rmm];
323 elastic_strain_increment,
324 inelastic_strain_increment[i_rmm],
334 for (
unsigned int i = 0; i < LIBMESH_DIM; ++i)
336 for (
unsigned int j = 0; j < LIBMESH_DIM; ++j)
338 if (
_stress[_qp](i, j) > stress_max(i, j))
339 stress_max(i, j) =
_stress[_qp](i, j);
340 else if (stress_min(i, j) >
_stress[_qp](i, j))
341 stress_min(i, j) =
_stress[_qp](i, j);
350 l2norm_delta_stress = (stress_max - stress_min).
L2norm();
351 if (
counter == 0 && l2norm_delta_stress > 0.0)
352 first_l2norm_delta_stress = l2norm_delta_stress;
356 _console <<
"stress iteration number = " <<
counter <<
"\n"
357 <<
" relative l2 norm delta stress = "
358 << (0 == first_l2norm_delta_stress ? 0
359 : l2norm_delta_stress / first_l2norm_delta_stress)
362 <<
" absolute l2 norm delta stress = " << l2norm_delta_stress <<
"\n"
372 throw MooseException(
"Max stress iteration hit during ComputeMultipleInelasticStress solve!");
374 combined_inelastic_strain_increment.zero();
375 for (
unsigned i_rmm = 0; i_rmm <
_num_models; ++i_rmm)
376 combined_inelastic_strain_increment +=
379 if (_fe_problem.currentlyComputingJacobian())
383 for (
unsigned i_rmm = 0; i_rmm <
_num_models; ++i_rmm)
400 for (
unsigned i_rmm = 0; i_rmm <
_num_models; ++i_rmm)
402 mooseAssert(A.isSymmetric(),
"Tangent operator isn't symmetric");
409 for (
unsigned i_rmm = 1; i_rmm <
_num_models; ++i_rmm)
416 unsigned model_number,
438 elastic_strain_increment,
439 combined_inelastic_strain_increment,
442 if (_fe_problem.currentlyComputingJacobian())
449 mooseAssert(A.isSymmetric(),
"Tangent operator isn't symmetric");
460 for (
unsigned i_rmm = 0; i_rmm <
_num_models; ++i_rmm)
461 if (i_rmm != model_number)
462 _models[i_rmm]->propagateQpStatefulProperties();
471 const bool jac = _fe_problem.currentlyComputingJacobian();
473 _models[model_number]->updateState(elastic_strain_increment,
474 inelastic_strain_increment,
481 consistent_tangent_operator);
483 _models[model_number]->updateState(elastic_strain_increment,
484 inelastic_strain_increment,
491 consistent_tangent_operator);
496 consistent_tangent_operator.zero();