void PLC_LSH::computeLSH( const SymmTensor & strain_increment, SymmTensor & plastic_strain_increment, SymmTensor & stress_new ) { // compute deviatoric trial stress SymmTensor dev_trial_stress(stress_new); dev_trial_stress.addDiag( -stress_new.trace()/3 ); // effective trial stress Real dts_squared = dev_trial_stress.doubleContraction(dev_trial_stress); Real effective_trial_stress = std::sqrt(1.5 * dts_squared); // determine if yield condition is satisfied Real yield_condition = effective_trial_stress - _hardening_variable_old[_qp] - _yield_stress; _hardening_variable[_qp] = _hardening_variable_old[_qp]; _plastic_strain[_qp] = _plastic_strain_old[_qp]; if (yield_condition > 0) // then use newton iteration to determine effective plastic strain increment { unsigned int it = 0; Real plastic_residual = 0; Real norm_plas_residual = 10; Real first_norm_plas_residual = 10; Real scalar_plastic_strain_increment = 0; while (it < _max_its && norm_plas_residual > _absolute_tolerance && (norm_plas_residual/first_norm_plas_residual) > _relative_tolerance) { plastic_residual = effective_trial_stress - (3. * _shear_modulus * scalar_plastic_strain_increment) - _hardening_variable[_qp] - _yield_stress; norm_plas_residual = std::abs(plastic_residual); if (it == 0) { first_norm_plas_residual = norm_plas_residual; } scalar_plastic_strain_increment += plastic_residual / (3. * _shear_modulus + _hardening_constant); _hardening_variable[_qp] = _hardening_variable_old[_qp] + (_hardening_constant * scalar_plastic_strain_increment); if (_output_iteration_info == true) { _console << "pls_it=" << it << " trl_strs=" << effective_trial_stress << " del_p=" << scalar_plastic_strain_increment << " harden=" << _hardening_variable[_qp] << " rel_res=" << norm_plas_residual/first_norm_plas_residual << " rel_tol=" << _relative_tolerance << " abs_res=" << norm_plas_residual << " abs_tol=" << _absolute_tolerance << std::endl; } ++it; } if (it == _max_its && norm_plas_residual > _absolute_tolerance && (norm_plas_residual/first_norm_plas_residual) > _relative_tolerance) { mooseError("Max sub-newton iteration hit during plasticity increment solve!"); } if (effective_trial_stress < 0.01) { effective_trial_stress = 0.01; } plastic_strain_increment = dev_trial_stress; plastic_strain_increment *= (1.5*scalar_plastic_strain_increment/effective_trial_stress); SymmTensor elastic_strain_increment(strain_increment); elastic_strain_increment -= plastic_strain_increment; // compute stress increment stress_new = *elasticityTensor() * elastic_strain_increment; // update stress and plastic strain stress_new += _stress_old; _plastic_strain[_qp] += plastic_strain_increment; } // end of if statement }
void PLC_LSH::computeCreep( const SymmTensor & strain_increment, SymmTensor & creep_strain_increment, SymmTensor & stress_new ) { // compute deviatoric trial stress SymmTensor dev_trial_stress(stress_new); dev_trial_stress.addDiag( -dev_trial_stress.trace()/3.0 ); // compute effective trial stress Real dts_squared = dev_trial_stress.doubleContraction(dev_trial_stress); Real effective_trial_stress = std::sqrt(1.5 * dts_squared); // Use Newton sub-iteration to determine effective creep strain increment Real exponential(1); if (_has_temp) { exponential = std::exp(-_activation_energy/(_gas_constant *_temperature[_qp])); } Real expTime = std::pow(_t, _m_exponent); Real del_p = 0; unsigned int it = 0; Real creep_residual = 10; Real norm_creep_residual = 10; Real first_norm_creep_residual = 10; while (it < _max_its && norm_creep_residual > _absolute_tolerance && (norm_creep_residual/first_norm_creep_residual) > _relative_tolerance) { Real phi = _coefficient*std::pow(effective_trial_stress - 3*_shear_modulus*del_p, _n_exponent)* exponential*expTime; Real dphi_ddelp = -3*_coefficient*_shear_modulus*_n_exponent* std::pow(effective_trial_stress-3*_shear_modulus*del_p, _n_exponent-1)*exponential*expTime; creep_residual = phi - del_p/_dt; norm_creep_residual = std::abs(creep_residual); if (it == 0) { first_norm_creep_residual = norm_creep_residual; } del_p += creep_residual / (1/_dt - dphi_ddelp); if (_output_iteration_info == true) { _console << "crp_it=" << it << " trl_strs=" << effective_trial_stress << " phi=" << phi << " dphi=" << dphi_ddelp << " del_p=" << del_p << " rel_res=" << norm_creep_residual/first_norm_creep_residual << " rel_tol=" << _relative_tolerance << " abs_res=" << norm_creep_residual << " abs_tol=" << _absolute_tolerance << std::endl; } ++it; } if (it == _max_its && norm_creep_residual > _absolute_tolerance && (norm_creep_residual/first_norm_creep_residual) > _relative_tolerance) { mooseError("Max sub-newton iteration hit during creep solve!"); } // compute creep and elastic strain increments (avoid potential divide by zero - how should this be done)? if (effective_trial_stress < 0.01) { effective_trial_stress = 0.01; } creep_strain_increment = dev_trial_stress; creep_strain_increment *= (1.5*del_p/effective_trial_stress); SymmTensor elastic_strain_increment(strain_increment); elastic_strain_increment -= creep_strain_increment; // compute stress increment stress_new = *elasticityTensor() * elastic_strain_increment; // update stress and creep strain stress_new += _stress_old; _creep_strain[_qp] = creep_strain_increment; _creep_strain[_qp] += _creep_strain_old[_qp]; }
void ReturnMappingModel::computeStress(const Elem & /*current_elem*/, unsigned qp, const SymmElasticityTensor & elasticityTensor, const SymmTensor & stress_old, SymmTensor & strain_increment, SymmTensor & stress_new, SymmTensor & inelastic_strain_increment) { // compute deviatoric trial stress SymmTensor dev_trial_stress(stress_new); dev_trial_stress.addDiag(-dev_trial_stress.trace()/3.0); // compute effective trial stress Real dts_squared = dev_trial_stress.doubleContraction(dev_trial_stress); Real effective_trial_stress = std::sqrt(1.5 * dts_squared); // compute effective strain increment SymmTensor dev_strain_increment(strain_increment); dev_strain_increment.addDiag(-strain_increment.trace()/3.0); _effective_strain_increment = dev_strain_increment.doubleContraction(dev_strain_increment); _effective_strain_increment = std::sqrt(2.0/3.0 * _effective_strain_increment); computeStressInitialize(qp, effective_trial_stress, elasticityTensor); // Use Newton sub-iteration to determine inelastic strain increment Real scalar = 0; unsigned int it = 0; Real residual = 10; Real norm_residual = 10; Real first_norm_residual = 10; std::string iter_output; while (it < _max_its && norm_residual > _absolute_tolerance && (norm_residual/first_norm_residual) > _relative_tolerance) { iterationInitialize(qp, scalar); residual = computeResidual(qp, effective_trial_stress, scalar); norm_residual = std::abs(residual); if (it == 0) { first_norm_residual = norm_residual; if (first_norm_residual == 0) { first_norm_residual = 1; } } scalar -= residual / computeDerivative(qp, effective_trial_stress, scalar); if (_output_iteration_info == true || _output_iteration_info_on_error == true) { iter_output = "In the element " + Moose::stringify(_current_elem->id()) + + " and the qp point " + Moose::stringify(qp) + ": \n" + + " iteration = " + Moose::stringify(it ) + "\n" + + " effective trial stress = " + Moose::stringify(effective_trial_stress) + "\n" + + " scalar effective inelastic strain = " + Moose::stringify(scalar) +"\n" + + " relative residual = " + Moose::stringify(norm_residual/first_norm_residual) + "\n" + + " relative tolerance = " + Moose::stringify(_relative_tolerance) + "\n" + + " absolute residual = " + Moose::stringify(norm_residual) + "\n" + + " absolute tolerance = " + Moose::stringify(_absolute_tolerance) + "\n"; } iterationFinalize(qp, scalar); ++it; } if (_output_iteration_info) _console << iter_output; if (it == _max_its && norm_residual > _absolute_tolerance && (norm_residual/first_norm_residual) > _relative_tolerance) { if (_output_iteration_info_on_error) { Moose::err << iter_output; } mooseError("Exceeded maximum iterations in ReturnMappingModel solve for material: " << _name << ". Rerun with 'output_iteration_info_on_error = true' for more information."); } // compute inelastic and elastic strain increments (avoid potential divide by zero - how should this be done)? if (effective_trial_stress < 0.01) { effective_trial_stress = 0.01; } inelastic_strain_increment = dev_trial_stress; inelastic_strain_increment *= (1.5*scalar/effective_trial_stress); strain_increment -= inelastic_strain_increment; // compute stress increment stress_new = elasticityTensor * strain_increment; // update stress stress_new += stress_old; computeStressFinalize(qp, inelastic_strain_increment); }
void ReturnMappingModel::computeStress(const Elem & /*current_elem*/, const SymmElasticityTensor & elasticityTensor, const SymmTensor & stress_old, SymmTensor & strain_increment, SymmTensor & stress_new, SymmTensor & inelastic_strain_increment) { // compute deviatoric trial stress SymmTensor dev_trial_stress(stress_new); dev_trial_stress.addDiag(-dev_trial_stress.trace() / 3.0); // compute effective trial stress Real dts_squared = dev_trial_stress.doubleContraction(dev_trial_stress); Real effective_trial_stress = std::sqrt(1.5 * dts_squared); // compute effective strain increment SymmTensor dev_strain_increment(strain_increment); dev_strain_increment.addDiag(-strain_increment.trace() / 3.0); _effective_strain_increment = dev_strain_increment.doubleContraction(dev_strain_increment); _effective_strain_increment = std::sqrt(2.0 / 3.0 * _effective_strain_increment); const SymmIsotropicElasticityTensor * iso_e_t = dynamic_cast<const SymmIsotropicElasticityTensor *>(&elasticityTensor); if (!iso_e_t) mooseError("Models derived from ReturnMappingModel require a SymmIsotropicElasticityTensor"); _three_shear_modulus = 3.0 * iso_e_t->shearModulus(); computeStressInitialize(effective_trial_stress, elasticityTensor); Real scalar; returnMappingSolve(effective_trial_stress, scalar, _console); // compute inelastic and elastic strain increments if (_legacy_return_mapping) { if (effective_trial_stress < 0.01) effective_trial_stress = 0.01; inelastic_strain_increment = dev_trial_stress; inelastic_strain_increment *= (1.5 * scalar / effective_trial_stress); } else { if (scalar != 0.0) inelastic_strain_increment = dev_trial_stress * (1.5 * scalar / effective_trial_stress); else inelastic_strain_increment = 0.0; } strain_increment -= inelastic_strain_increment; _effective_inelastic_strain[_qp] = _effective_inelastic_strain_old[_qp] + scalar; // compute stress increment stress_new = elasticityTensor * strain_increment; // update stress stress_new += stress_old; computeStressFinalize(inelastic_strain_increment); }
void ReturnMappingModel::computeStress( const Elem & /*current_elem*/, unsigned qp, const SymmElasticityTensor & elasticityTensor, const SymmTensor & stress_old, SymmTensor & strain_increment, SymmTensor & stress_new, SymmTensor & inelastic_strain_increment ) { // compute deviatoric trial stress SymmTensor dev_trial_stress(stress_new); dev_trial_stress.addDiag( -dev_trial_stress.trace()/3.0 ); // compute effective trial stress Real dts_squared = dev_trial_stress.doubleContraction(dev_trial_stress); Real effective_trial_stress = std::sqrt(1.5 * dts_squared); // compute effective strain increment SymmTensor dev_strain_increment(strain_increment); dev_strain_increment.addDiag( -strain_increment.trace()/3.0); _effective_strain_increment = dev_strain_increment.doubleContraction(dev_strain_increment); _effective_strain_increment = std::sqrt(2.0/3.0 * _effective_strain_increment); computeStressInitialize(qp, effective_trial_stress, elasticityTensor); // Use Newton sub-iteration to determine inelastic strain increment Real scalar = 0; unsigned int it = 0; Real residual = 10; Real norm_residual = 10; Real first_norm_residual = 10; std::stringstream iter_output; while (it < _max_its && norm_residual > _absolute_tolerance && (norm_residual/first_norm_residual) > _relative_tolerance) { iterationInitialize( qp, scalar ); residual = computeResidual(qp, effective_trial_stress, scalar); norm_residual = std::abs(residual); if (it == 0) { first_norm_residual = norm_residual; if (first_norm_residual == 0) { first_norm_residual = 1; } } scalar -= residual / computeDerivative(qp, effective_trial_stress, scalar); if (_output_iteration_info == true || _output_iteration_info_on_error == true) { iter_output << " it=" << it << " trl_strs=" << effective_trial_stress << " scalar=" << scalar << " rel_res=" << norm_residual/first_norm_residual << " rel_tol=" << _relative_tolerance << " abs_res=" << norm_residual << " abs_tol=" << _absolute_tolerance << std::endl; } iterationFinalize( qp, scalar ); ++it; } if (_output_iteration_info) _console << iter_output.str(); if (it == _max_its && norm_residual > _absolute_tolerance && (norm_residual/first_norm_residual) > _relative_tolerance) { if (_output_iteration_info_on_error) { Moose::err << iter_output.str(); } mooseError("Max sub-newton iteration hit during nonlinear constitutive model solve! (" << _name << ")"); } // compute inelastic and elastic strain increments (avoid potential divide by zero - how should this be done)? if (effective_trial_stress < 0.01) { effective_trial_stress = 0.01; } inelastic_strain_increment = dev_trial_stress; inelastic_strain_increment *= (1.5*scalar/effective_trial_stress); strain_increment -= inelastic_strain_increment; // compute stress increment stress_new = elasticityTensor * strain_increment; // update stress stress_new += stress_old; computeStressFinalize(qp, inelastic_strain_increment); }