Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 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 "ComputeCreepPlasticityStress.h" 11 : 12 : #include "ElasticityTensorTools.h" 13 : 14 : #include "MooseException.h" 15 : #include "libmesh/int_range.h" 16 : 17 : registerMooseObject("SolidMechanicsApp", ComputeCreepPlasticityStress); 18 : 19 : InputParameters 20 72 : ComputeCreepPlasticityStress::validParams() 21 : { 22 72 : InputParameters params = ComputeMultipleInelasticStressBase::validParams(); 23 72 : params.addClassDescription("Compute state (stress and internal parameters such as inelastic " 24 : "strains and internal parameters) using an Newton process for one " 25 : "creep and one plasticity model"); 26 144 : params.addRequiredParam<MaterialName>("creep_model", 27 : "Creep model that derives from PowerLawCreepStressUpdate."); 28 144 : params.addRequiredParam<MaterialName>( 29 : "plasticity_model", "Plasticity model that derives from IsotropicPlasticityStressUpdate."); 30 : 31 72 : return params; 32 0 : } 33 : 34 54 : ComputeCreepPlasticityStress::ComputeCreepPlasticityStress(const InputParameters & parameters) 35 54 : : ComputeMultipleInelasticStressBase(parameters) 36 : { 37 54 : } 38 : 39 : std::vector<MaterialName> 40 54 : ComputeCreepPlasticityStress::getInelasticModelNames() 41 : { 42 : std::vector<MaterialName> names = {getParam<MaterialName>("creep_model"), 43 162 : getParam<MaterialName>("plasticity_model")}; 44 54 : return names; 45 162 : } 46 : 47 : void 48 54 : ComputeCreepPlasticityStress::initialSetup() 49 : { 50 54 : ComputeMultipleInelasticStressBase::initialSetup(); 51 : 52 54 : if (_models.size() != 2) 53 0 : mooseError("Error in ComputeCreepPlasticityStress: two models are required."); 54 : 55 54 : _creep_model = dynamic_cast<PowerLawCreepStressUpdate *>(_models[0]); 56 54 : if (!_creep_model) 57 0 : mooseError("Model " + getParam<MaterialName>("creep_model") + 58 : " is not a compatible creep model in ComputeCreepPlasticityStress."); 59 : 60 54 : _plasticity_model = dynamic_cast<IsotropicPlasticityStressUpdate *>(_models[1]); 61 54 : if (!_plasticity_model) 62 0 : mooseError("Model " + getParam<MaterialName>("plasticity_model") + 63 : " is not a compatible plasticity model in ComputeCreepPlasticityStress."); 64 54 : } 65 : 66 : void 67 238688 : ComputeCreepPlasticityStress::updateQpState(RankTwoTensor & elastic_strain_increment, 68 : RankTwoTensor & combined_inelastic_strain_increment) 69 : { 70 238688 : if (_internal_solve_full_iteration_history == true) 71 : { 72 0 : _console << std::endl 73 0 : << "iteration output for ComputeCreepPlasticityStress solve:" 74 0 : << " time=" << _t << " int_pt=" << _qp << std::endl; 75 : } 76 : 77 716064 : for (const auto i_rmm : index_range(_models)) 78 : _inelastic_strain_increment[i_rmm].zero(); 79 : 80 238688 : elastic_strain_increment = _strain_increment[_qp]; 81 238688 : computeStress(elastic_strain_increment, _stress[_qp]); 82 : 83 238688 : const RankTwoTensor trial_stress = _stress[_qp]; 84 238688 : const RankTwoTensor deviatoric_trial_stress = trial_stress.deviatoric(); 85 : const Real effective_trial_stress = 86 238688 : std::sqrt(1.5 * deviatoric_trial_stress.doubleContraction(deviatoric_trial_stress)); 87 : 88 : // 89 : // First, compute creep response assuming no plasticity 90 : // 91 238688 : _creep_model->setQp(_qp); 92 238688 : computeAdmissibleState( 93 : 0, elastic_strain_increment, _inelastic_strain_increment[0], _consistent_tangent_operator[0]); 94 238688 : _effective_creep_strain_increment = _creep_model->effectiveInelasticStrainIncrement(); 95 : 96 : // 97 : // Now check the plasticity model. 98 : // If no yielding, we are done. 99 : // 100 238688 : _plasticity_model->setQp(_qp); 101 238688 : computeAdmissibleState( 102 : 1, elastic_strain_increment, _inelastic_strain_increment[1], _consistent_tangent_operator[1]); 103 238688 : _effective_plastic_strain_increment = _plasticity_model->effectiveInelasticStrainIncrement(); 104 : const Real yield_condition = _plasticity_model->yieldCondition(); 105 : 106 238688 : if (yield_condition > 0.0) // yielding even with maximum creep strain 107 : { 108 80560 : const Real max_effective_creep_strain_increment = _effective_creep_strain_increment; 109 : 110 : // 111 : // Compute plastic response given no creep 112 : // 113 80560 : elastic_strain_increment = _strain_increment[_qp]; 114 80560 : _stress[_qp] = trial_stress; 115 80560 : computeAdmissibleState(1, 116 : elastic_strain_increment, 117 : _inelastic_strain_increment[1], 118 : _consistent_tangent_operator[1]); 119 : const Real max_effective_plastic_strain_increment = 120 80560 : _plasticity_model->effectiveInelasticStrainIncrement(); 121 : 122 : // 123 : // Reset plasticity model 124 : // 125 80560 : _plasticity_model->computeStressInitialize(effective_trial_stress, _elasticity_tensor[_qp]); 126 : 127 : // 128 : // The residual for the creep law is (creep rate)*dt - (creep strain increment) 129 : // We want the creep rate calculation to depend on both creep and plasticity. 130 : // Since we send in the total scalar inelastic strain (creep and plasticity), we need to correct 131 : // the second term by adding the plastic strain. 132 : // 133 80560 : Real creep_residual = _creep_model->computeResidual(effective_trial_stress, 134 161120 : _effective_creep_strain_increment + 135 80560 : _effective_plastic_strain_increment); 136 80560 : creep_residual += _effective_plastic_strain_increment; 137 : 138 : // 139 : // We want the plasticity resdiual to be (effective_trial_stress - r - yield_stress)/3G - (total 140 : // inelastic increment) 141 : // The standard residual for plasticity is (effective_trial_stress - r - yield_stress)/3G - 142 : // (plasticity strain increment) 143 : // Since we send in the plastic inelastic strain (for calculation of r), we must subtract the 144 : // creep strain to correct the final term in our desired residual 145 : // 146 80560 : Real plasticity_residual = _plasticity_model->computeResidual( 147 80560 : effective_trial_stress, _effective_plastic_strain_increment); 148 80560 : plasticity_residual -= _effective_creep_strain_increment; 149 : 150 80560 : unsigned int counter = 0; 151 80560 : Real residual = 0; 152 : const Real threeG = 153 80560 : 3.0 * ElasticityTensorTools::getIsotropicShearModulus(_elasticity_tensor[_qp]); 154 80560 : const Real reference_residual = effective_trial_stress / threeG; 155 : 156 : do 157 : { 158 : // 159 : // Solve Ax=b where x is the vector of creep and plastic inelastic strains 160 : // 161 : // x1 => creep 162 : // x2 => plasticity 163 : // 164 : // 165 : // A11 (creep,creep) 166 : // 167 142400 : Real A11 = _creep_model->computeDerivative(effective_trial_stress, 168 284800 : _effective_creep_strain_increment + 169 142400 : _effective_plastic_strain_increment); 170 : // 171 : // A12 (creep,plasticity) 172 : // 173 142400 : Real A12 = A11 + 1.0; 174 : // 175 : // A21 (plasticity,creep) 176 : // 177 : Real A21 = -1.0; 178 : // 179 : // A22 (plasticity,plasticity) 180 : // 181 142400 : Real A22 = _plasticity_model->computeDerivative(effective_trial_stress, 182 : _effective_plastic_strain_increment); 183 : 184 142400 : Real rhs1 = creep_residual; 185 142400 : Real rhs2 = plasticity_residual; 186 : 187 : // 188 : // Solve 189 : // 190 : // A11*a + A21 = 0 191 : // A11*a = -A21 192 : // a = -A21/A11 193 142400 : const Real a = -A21 / A11; 194 : A21 = 0; 195 142400 : A22 += a * A12; 196 142400 : rhs2 += a * rhs1; 197 : 198 142400 : Real x2 = rhs2 / A22; 199 142400 : Real x1 = (rhs1 - A12 * x2) / A11; 200 : 201 142400 : while (_effective_creep_strain_increment - x1 < 0) 202 0 : x1 *= 0.5; 203 142400 : while (_effective_plastic_strain_increment - x2 < 0) 204 0 : x2 *= 0.5; 205 : 206 142400 : while (_effective_creep_strain_increment - x1 > max_effective_creep_strain_increment) 207 0 : x1 *= 0.5; 208 142400 : while (_effective_plastic_strain_increment - x2 > max_effective_plastic_strain_increment) 209 0 : x2 *= 0.5; 210 : 211 : // This check is to avoid a fpe in the creep law. 212 : // Maybe it is better to check for this condition in the creep law 213 142400 : if (effective_trial_stress < threeG * (_effective_creep_strain_increment - x1 + 214 142400 : _effective_plastic_strain_increment - x2)) 215 : { 216 : const Real sum = 217 : _effective_creep_strain_increment - x1 + _effective_plastic_strain_increment - x2; 218 0 : const Real factor = 0.9 * effective_trial_stress / (threeG * sum); 219 0 : const Real cNew = (_effective_creep_strain_increment - x1) * factor; 220 0 : const Real pNew = (_effective_plastic_strain_increment - x2) * factor; 221 0 : x1 = _effective_creep_strain_increment - cNew; 222 0 : x2 = _effective_plastic_strain_increment - pNew; 223 : } 224 : 225 142400 : _effective_creep_strain_increment -= x1; 226 142400 : _effective_plastic_strain_increment -= x2; 227 : 228 : // 229 : // The residual for the creep law is (creep rate)*dt - (creep strain increment) 230 : // 231 142400 : creep_residual = _creep_model->computeResidual(effective_trial_stress, 232 142400 : _effective_creep_strain_increment + 233 : _effective_plastic_strain_increment); 234 142400 : creep_residual += _effective_plastic_strain_increment; 235 : // 236 : // The residual for plasticity is (effective_trial_stress - r - yield_stress)/3G - scalar 237 : // 238 142400 : plasticity_residual = _plasticity_model->computeResidual(effective_trial_stress, 239 : _effective_plastic_strain_increment); 240 142400 : plasticity_residual -= _effective_creep_strain_increment; 241 : 242 142400 : residual = 243 142400 : std::sqrt(creep_residual * creep_residual + plasticity_residual * plasticity_residual); 244 : 245 142400 : if (_internal_solve_full_iteration_history == true) 246 : { 247 0 : _console << "stress iteration number = " << counter << "\n relative residual = " 248 0 : << (0 == reference_residual ? 0 : residual / reference_residual) 249 0 : << "\n stress convergence relative tolerance = " << _relative_tolerance 250 0 : << "\n absolute residual = " << residual 251 0 : << "\n creep residual = " << creep_residual 252 0 : << "\n plasticity residual = " << plasticity_residual 253 0 : << "\n creep iteration increment = " << x1 254 0 : << "\n plasticity iteration increment = " << x2 255 0 : << "\n creep scalar strain = " << _effective_creep_strain_increment 256 0 : << "\n plasticity scalar strain = " << _effective_plastic_strain_increment 257 0 : << "\n max creep scalar strain = " << max_effective_creep_strain_increment 258 0 : << "\n max plasticity scalar strain = " << max_effective_plastic_strain_increment 259 0 : << "\n stress convergence absolute tolerance = " << _absolute_tolerance 260 0 : << std::endl; 261 : } 262 142400 : ++counter; 263 142400 : } while (counter < _max_iterations && residual > _absolute_tolerance && 264 61840 : (residual / reference_residual) > _relative_tolerance); 265 : 266 80560 : if (counter == _max_iterations && residual > _absolute_tolerance && 267 0 : (residual / reference_residual) > _relative_tolerance) 268 : { 269 0 : std::stringstream msg; 270 0 : msg << "\n relative residual = " 271 0 : << (0 == reference_residual ? 0 : residual / reference_residual) 272 0 : << "\n stress convergence relative tolerance = " << _relative_tolerance 273 0 : << "\n absolute residual = " << residual << "\n creep residual = " << creep_residual 274 0 : << "\n plasticity residual = " << plasticity_residual 275 0 : << "\n creep scalar strain = " << _effective_creep_strain_increment 276 0 : << "\n plasticity scalar strain = " << _effective_plastic_strain_increment 277 0 : << "\n max creep scalar strain = " << max_effective_creep_strain_increment 278 0 : << "\n max plasticity scalar strain = " << max_effective_plastic_strain_increment 279 0 : << "\n stress convergence absolute tolerance = " << _absolute_tolerance << std::endl; 280 : 281 0 : throw MooseException("Max stress iteration hit during ComputeCreepPlasticityStress solve! " + 282 0 : _name + msg.str()); 283 0 : } 284 : } 285 238688 : computeInelasticStrainIncrements(effective_trial_stress, deviatoric_trial_stress); 286 : 287 238688 : finalizeConstitutiveModels(); 288 : 289 : combined_inelastic_strain_increment.zero(); 290 716064 : for (const auto i_rmm : make_range(_num_models)) 291 477376 : combined_inelastic_strain_increment += _inelastic_strain_increment[i_rmm]; 292 : 293 238688 : if (yield_condition > 0.0) 294 : { 295 80560 : elastic_strain_increment = _strain_increment[_qp] - combined_inelastic_strain_increment; 296 80560 : _stress[_qp] = _elasticity_tensor[_qp] * (elastic_strain_increment + _elastic_strain_old[_qp]); 297 : 298 80560 : computeTangentOperators(); 299 : } 300 : else 301 : { 302 : // The tangent for creep was called in the initial creep solve. 303 : 304 : // Set the tangent for plasticity to zero 305 158128 : _consistent_tangent_operator[1].zero(); 306 : } 307 : 308 238688 : if (_fe_problem.currentlyComputingJacobian()) 309 37632 : computeQpJacobianMult(); 310 : 311 238688 : _material_timestep_limit[_qp] = 0.0; 312 716064 : for (const auto i_rmm : make_range(_num_models)) 313 477376 : _material_timestep_limit[_qp] += 1.0 / _models[i_rmm]->computeTimeStepLimit(); 314 : 315 238688 : if (MooseUtils::absoluteFuzzyEqual(_material_timestep_limit[_qp], 0.0)) 316 2304 : _material_timestep_limit[_qp] = std::numeric_limits<Real>::max(); 317 : else 318 236384 : _material_timestep_limit[_qp] = 1.0 / _material_timestep_limit[_qp]; 319 238688 : } 320 : 321 : void 322 399808 : ComputeCreepPlasticityStress::computeStress(const RankTwoTensor & elastic_strain_increment, 323 : RankTwoTensor & stress) 324 : { 325 : // form the stress, with the check for changed elasticity constants 326 399808 : if (_is_elasticity_tensor_guaranteed_isotropic || !_perform_finite_strain_rotations) 327 399808 : stress = _elasticity_tensor[_qp] * (_elastic_strain_old[_qp] + elastic_strain_increment); 328 : else 329 : { 330 0 : if (_damage_model) 331 0 : stress = _undamaged_stress_old + _elasticity_tensor[_qp] * elastic_strain_increment; 332 : else 333 0 : stress = _stress_old[_qp] + _elasticity_tensor[_qp] * elastic_strain_increment; 334 : } 335 399808 : } 336 : 337 : void 338 80560 : ComputeCreepPlasticityStress::computeTangentOperators() 339 : { 340 80560 : auto elastic_strain_inc = _strain_increment[_qp] - _inelastic_strain_increment[1]; 341 : 342 80560 : RankTwoTensor stress; 343 80560 : computeStress(elastic_strain_inc, stress); 344 80560 : RankTwoTensor deviatoric_stress = stress.deviatoric(); 345 80560 : Real effective_stress = std::sqrt(1.5 * deviatoric_stress.doubleContraction(deviatoric_stress)); 346 : 347 80560 : _creep_model->computeTangentOperator( 348 80560 : effective_stress, _stress[_qp], _consistent_tangent_operator[0]); 349 : 350 80560 : elastic_strain_inc = _strain_increment[_qp] - _inelastic_strain_increment[0]; 351 : 352 80560 : computeStress(elastic_strain_inc, stress); 353 80560 : deviatoric_stress = stress.deviatoric(); 354 80560 : effective_stress = std::sqrt(1.5 * deviatoric_stress.doubleContraction(deviatoric_stress)); 355 : 356 80560 : _plasticity_model->computeTangentOperator( 357 80560 : effective_stress, _stress[_qp], _consistent_tangent_operator[1]); 358 80560 : } 359 : 360 : void 361 238688 : ComputeCreepPlasticityStress::computeInelasticStrainIncrements( 362 : Real effective_trial_stress, const RankTwoTensor & deviatoric_trial_stress) 363 : { 364 238688 : if (!MooseUtils::absoluteFuzzyEqual(effective_trial_stress, 0.0)) 365 : { 366 238496 : if (_effective_creep_strain_increment != 0.0) 367 219104 : _inelastic_strain_increment[0] = 368 219104 : deviatoric_trial_stress * 369 219104 : (1.5 * _effective_creep_strain_increment / effective_trial_stress); 370 : else 371 : _inelastic_strain_increment[0].zero(); 372 : 373 238496 : if (_effective_plastic_strain_increment != 0.0) 374 80560 : _inelastic_strain_increment[1] = 375 80560 : deviatoric_trial_stress * 376 80560 : (1.5 * _effective_plastic_strain_increment / effective_trial_stress); 377 : else 378 : _inelastic_strain_increment[1].zero(); 379 : } 380 : else 381 : { 382 : _inelastic_strain_increment[0].zero(); 383 : _inelastic_strain_increment[1].zero(); 384 : } 385 238688 : } 386 : 387 : void 388 238688 : ComputeCreepPlasticityStress::finalizeConstitutiveModels() 389 : { 390 238688 : _creep_model->updateEffectiveInelasticStrainIncrement(_effective_creep_strain_increment); 391 238688 : _plasticity_model->updateEffectiveInelasticStrainIncrement(_effective_plastic_strain_increment); 392 238688 : _creep_model->updateEffectiveInelasticStrain(_effective_creep_strain_increment); 393 238688 : _plasticity_model->updateEffectiveInelasticStrain(_effective_plastic_strain_increment); 394 238688 : _creep_model->resetIncrementalMaterialProperties(); 395 238688 : _creep_model->computeStressFinalize(_inelastic_strain_increment[0]); 396 238688 : _plasticity_model->computeStressFinalize(_inelastic_strain_increment[1]); 397 238688 : }