void FiniteStrainRatePlasticMaterial::computeQpStress() { RankTwoTensor dp,sig; //Obtain previous plastic rate of deformation tensor dp=_plastic_strain_old[_qp]; //Solve J2 plastic constitutive equations based on current strain increment //Returns current stress and plastic rate of deformation tensor returnMap(_stress_old[_qp], _strain_increment[_qp], _elasticity_tensor[_qp], dp, sig); _stress[_qp] = sig; //Rotate the stress to the current configuration _stress[_qp] = _rotation_increment[_qp] * _stress[_qp] * _rotation_increment[_qp].transpose(); //Updates current plastic rate of deformation tensor _plastic_strain[_qp] = dp; //Evaluate and update current equivalent plastic strain _eqv_plastic_strain[_qp] = std::pow(2.0/3.0,0.5) * dp.L2norm(); //Calculate elastic strain increment RankTwoTensor delta_ee = _strain_increment[_qp]-(_plastic_strain[_qp]-_plastic_strain_old[_qp]); //Update elastic strain tensor in intermediate configuration _elastic_strain[_qp] = _elastic_strain_old[_qp] + delta_ee; //Rotate elastic strain tensor to the current configuration _elastic_strain[_qp] = _rotation_increment[_qp] * _elastic_strain[_qp] * _rotation_increment[_qp].transpose(); //Rotate to plastic rate of deformation tensor the current configuration _plastic_strain[_qp] = _rotation_increment[_qp] * _plastic_strain[_qp] * _rotation_increment[_qp].transpose(); //Update strain in intermediate configuration _total_strain[_qp] = _total_strain_old[_qp] + _strain_increment[_qp]; //Rotate strain to current configuration _total_strain[_qp] = _rotation_increment[_qp] * _total_strain[_qp] * _rotation_increment[_qp].transpose(); }
void FiniteStrainPlasticMaterial::computeQpStress() { // perform the return-mapping algorithm returnMap(_stress_old[_qp], _eqv_plastic_strain_old[_qp], _plastic_strain_old[_qp], _strain_increment[_qp], _elasticity_tensor[_qp], _stress[_qp], _eqv_plastic_strain[_qp], _plastic_strain[_qp]); // Rotate the stress tensor to the current configuration _stress[_qp] = _rotation_increment[_qp] * _stress[_qp] * _rotation_increment[_qp].transpose(); // Rotate plastic strain tensor to the current configuration _plastic_strain[_qp] = _rotation_increment[_qp] * _plastic_strain[_qp] * _rotation_increment[_qp].transpose(); _Jacobian_mult[_qp] = _elasticity_tensor[_qp]; }
void FiniteStrainPlasticBase::computeQpStress() { if (_fspb_debug == 3) { checkJacobian(); mooseError("Jacobian has been checked. Exiting with no error"); } preReturnMap(); /** * the idea in the following is to potentially subdivide the * strain increment into smaller portions * First one subdivision is tried, and if that fails then * 2 are tried, then 4, etc. This is in the hope that the * time-step for the entire mesh need not be cut if there * are only a few "bad" quadpoints where the return-map * is difficult */ bool return_successful = false; // number of subdivisions of the strain increment currently being tried unsigned int num_subdivisions = 1; while (num_subdivisions <= _max_subdivisions && !return_successful) { // prepare the variables for this set of strain increments RankTwoTensor dep = _strain_increment[_qp]/num_subdivisions; RankTwoTensor stress_previous = _stress_old[_qp]; RankTwoTensor plastic_strain_previous = _plastic_strain_old[_qp]; std::vector<Real> intnl_previous; intnl_previous.resize(_intnl_old[_qp].size()); for (unsigned int a = 0; a < _intnl_old[_qp].size(); ++a) intnl_previous[a] = _intnl_old[_qp][a]; // now do the work: apply the "dep" over num_subdivisions "substeps" for (unsigned substep = 0 ; substep < num_subdivisions ; ++substep) { return_successful = returnMap(stress_previous, plastic_strain_previous, _intnl_old[_qp], dep, _elasticity_tensor[_qp], _stress[_qp], _plastic_strain[_qp], _intnl[_qp], _f[_qp], _iter[_qp]); if (return_successful) { // record the updated variables in readiness for the next substep stress_previous = _stress[_qp]; plastic_strain_previous = _plastic_strain[_qp]; for (unsigned int a = 0; a < _intnl_old[_qp].size(); ++a) intnl_previous[a] = _intnl[_qp][a]; } else break; // oh dear, we need to increase the number of subdivisions } if (!return_successful) num_subdivisions *= 2; } if (!return_successful) { _console << "After making " << num_subdivisions << " subdivisions of the strain increment with L2norm " << _strain_increment[_qp].L2norm() << " the returnMap algorithm failed\n"; _fspb_debug_stress = _stress_old[_qp]; _fspb_debug_pm.assign(numberOfYieldFunctions(), 1); // this is chosen arbitrarily - please change if a more suitable value occurs to you! _fspb_debug_intnl.resize(numberOfInternalParameters()); for (unsigned a = 0 ; a < numberOfInternalParameters() ; ++a) _fspb_debug_intnl[a] = _intnl_old[_qp][a]; checkDerivatives(); checkJacobian(); mooseError("Exiting\n"); } postReturnMap(); //Update measures of strain _elastic_strain[_qp] = _elastic_strain_old[_qp] + _strain_increment[_qp] - (_plastic_strain[_qp] - _plastic_strain_old[_qp]); _total_strain[_qp] = _total_strain_old[_qp] + _strain_increment[_qp]; //Rotate the tensors to the current configuration _stress[_qp] = _rotation_increment[_qp]*_stress[_qp]*_rotation_increment[_qp].transpose(); _elastic_strain[_qp] = _rotation_increment[_qp] * _elastic_strain[_qp] * _rotation_increment[_qp].transpose(); _total_strain[_qp] = _rotation_increment[_qp] * _total_strain[_qp] * _rotation_increment[_qp].transpose(); _plastic_strain[_qp] = _rotation_increment[_qp] * _plastic_strain[_qp] * _rotation_increment[_qp].transpose(); }