void TutorialMaterial :: giveRealStressVector_3d(FloatArray &answer, GaussPoint *gp, const FloatArray &totalStrain, TimeStep *tStep) { FloatArray strain; TutorialMaterialStatus *status = static_cast< TutorialMaterialStatus * >( this->giveStatus(gp) ); // subtract stress thermal expansion this->giveStressDependentPartOfStrainVector_3d(strain, gp, totalStrain, tStep, VM_Total); FloatArray trialElastStrain; trialElastStrain.beDifferenceOf(strain, status->givePlasticStrain()); // Compute trial stress = sig_tr = sig_old + E*delta_eps FloatMatrix elasticStiffness; D.give3dMaterialStiffnessMatrix(elasticStiffness, TangentStiffness, gp, tStep); FloatArray trialStress; trialStress.beProductOf(elasticStiffness, trialElastStrain); FloatArray sphTrialStress, devTrialStress; computeSphDevPartOf(trialStress, sphTrialStress, devTrialStress); double J2 = this->computeSecondStressInvariant(devTrialStress); double effectiveTrialStress = sqrt(3 * J2); #if 1 double temperatureScaling = 1.0; #else double temperature; FloatArray et; static_cast< StructuralElement *>(gp->giveIntegrationRule()->giveElement())->computeResultingIPTemperatureAt(et, tStep, gp, VM_Total); temperature = et.at(1) + 800; double temperatureScaling = temperature <= 400 ? 1.0 : 1.0 - (temperature - 400) * 0.5 / 400; #endif // evaluate the yield surface double k = status->giveK(); double phiTrial = effectiveTrialStress - ( temperatureScaling * this->sig0 + temperatureScaling * H * k ); if ( phiTrial < 0.0 ) { // elastic answer = trialStress; status->letTempPlasticStrainBe(status->givePlasticStrain()); } else { // plastic loading double G = D.giveShearModulus(); double mu = phiTrial / ( 3.0 * G + temperatureScaling * H ); // plastic multiplier answer = devTrialStress * ( 1.0 - 3.0*G*mu/effectiveTrialStress); // radial return answer.add(sphTrialStress); k += mu; FloatArray plasticStrain = status->givePlasticStrain(); FloatArray dPlStrain; applyDeviatoricElasticCompliance(dPlStrain, devTrialStress, 0.5); plasticStrain.add(mu * 3. / (2. * effectiveTrialStress), dPlStrain); status->letTempPlasticStrainBe(plasticStrain); } // Store the temporary values for the given iteration status->letTempStrainVectorBe(totalStrain); status->letTempStressVectorBe(answer); status->letTempKBe(k); status->letTempDevTrialStressBe(devTrialStress); }
void MisesMat :: performPlasticityReturn(GaussPoint *gp, const FloatArray &totalStrain) { MisesMatStatus *status = static_cast< MisesMatStatus * >( this->giveStatus(gp) ); double kappa; FloatArray plStrain; FloatArray fullStress; // get the initial plastic strain and initial kappa from the status plStrain = status->givePlasticStrain(); kappa = status->giveCumulativePlasticStrain(); // === radial return algorithm === if ( totalStrain.giveSize() == 1 ) { LinearElasticMaterial *lmat = this->giveLinearElasticMaterial(); double E = lmat->give('E', gp); /*trial stress*/ fullStress.resize(6); fullStress.at(1) = E * ( totalStrain.at(1) - plStrain.at(1) ); double trialS = fabs(fullStress.at(1)); /*yield function*/ double yieldValue = trialS - (sig0 + H * kappa); // === radial return algorithm === if ( yieldValue > 0 ) { double dKappa = yieldValue / ( H + E ); kappa += dKappa; plStrain.at(1) += dKappa * signum( fullStress.at(1) ); plStrain.at(2) -= 0.5 * dKappa * signum( fullStress.at(1) ); plStrain.at(3) -= 0.5 * dKappa * signum( fullStress.at(1) ); fullStress.at(1) -= dKappa * E * signum( fullStress.at(1) ); } } else { // elastic predictor FloatArray elStrain = totalStrain; elStrain.subtract(plStrain); FloatArray elStrainDev; double elStrainVol; elStrainVol = computeDeviatoricVolumetricSplit(elStrainDev, elStrain); FloatArray trialStressDev; applyDeviatoricElasticStiffness(trialStressDev, elStrainDev, G); /**************************************************************/ double trialStressVol = 3 * K * elStrainVol; /**************************************************************/ // store the deviatoric and trial stress (reused by algorithmic stiffness) status->letTrialStressDevBe(trialStressDev); status->setTrialStressVol(trialStressVol); // check the yield condition at the trial state double trialS = computeStressNorm(trialStressDev); double yieldValue = sqrt(3./2.) * trialS - (sig0 + H * kappa); if ( yieldValue > 0. ) { // increment of cumulative plastic strain double dKappa = yieldValue / ( H + 3. * G ); kappa += dKappa; FloatArray dPlStrain; // the following line is equivalent to multiplication by scaling matrix P applyDeviatoricElasticCompliance(dPlStrain, trialStressDev, 0.5); // increment of plastic strain plStrain.add(sqrt(3. / 2.) * dKappa / trialS, dPlStrain); // scaling of deviatoric trial stress trialStressDev.times(1. - sqrt(6.) * G * dKappa / trialS); } // assemble the stress from the elastically computed volumetric part // and scaled deviatoric part computeDeviatoricVolumetricSum(fullStress, trialStressDev, trialStressVol); } // store the effective stress in status status->letTempEffectiveStressBe(fullStress); // store the plastic strain and cumulative plastic strain status->letTempPlasticStrainBe(plStrain); status->setTempCumulativePlasticStrain(kappa); }