void IDGMaterial :: giveInternalLengthDerivative(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) { MaterialMode mMode = gp->giveMaterialMode(); if ( mMode == _PlaneStress ) { answer.resize(5, 5); answer.zero(); if ( mode == TangentStiffness ) { IDGMaterialStatus *status = static_cast< IDGMaterialStatus * >( this->giveStatus(gp) ); FloatArray stress = status->giveTempStressVector(); stress.resize(3); StressVector fullStress(stress, _PlaneStress); FloatArray sigPrinc; FloatMatrix nPrinc; // get principal trial stresses (ordered) and principal stress directions fullStress.computePrincipalValDir(sigPrinc, nPrinc); if ( sigPrinc.at(1) > 0 ) { if ( sigPrinc.at(2) > 0 && sigPrinc.at(1) != sigPrinc.at(2) ) { double gamma = beta + ( 1 - beta ) * sigPrinc.at(2) * sigPrinc.at(2) / ( sigPrinc.at(1) * sigPrinc.at(1) ); double dL2dS1 = 4. * gamma * cl * cl * ( beta - 1. ) * sigPrinc.at(2) * sigPrinc.at(2) / ( sigPrinc.at(1) * sigPrinc.at(1) * sigPrinc.at(1) ); double dL2dS2 = 4. * gamma * cl * cl * ( 1. - beta ) * sigPrinc.at(2) / ( sigPrinc.at(1) * sigPrinc.at(1) ); double dLdN = ( gamma * gamma - 1. ) * cl * cl / ( sigPrinc.at(2) - sigPrinc.at(1) ); answer.at(1, 1) = nPrinc.at(1, 1); answer.at(1, 2) = nPrinc.at(1, 2); answer.at(2, 1) = nPrinc.at(2, 1); answer.at(2, 2) = nPrinc.at(2, 2); answer.at(3, 3) = dL2dS1; answer.at(4, 4) = dL2dS2; answer.at(5, 5) = dLdN; } } } } else { OOFEM_ERROR("Unknown material mode."); } }
void IDGMaterial :: giveInternalLength(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) { if ( averType == 0 ) { answer.resize(1, 1); answer.at(1, 1) = cl; } else if ( averType == 1 ) { answer.resize(1, 1); FloatArray gpCoords; if ( gp->giveElement()->computeGlobalCoordinates( gpCoords, gp->giveNaturalCoordinates() ) == 0 ) { OOFEM_ERROR("computeGlobalCoordinates of GP failed"); } this->giveDistanceBasedCharacteristicLength(gpCoords); answer.at(1, 1) = cl; } else if ( averType == 2 ) { MaterialMode mMode = gp->giveMaterialMode(); if ( mMode == _PlaneStress ) { answer.resize(2, 2); answer.zero(); IDGMaterialStatus *status = static_cast< IDGMaterialStatus * >( this->giveStatus(gp) ); FloatArray stress = status->giveTempStressVector(); StressVector fullStress(stress, _PlaneStress); FloatArray sigPrinc; FloatMatrix nPrinc; // get principal stresses (ordered) and principal stress directions fullStress.computePrincipalValDir(sigPrinc, nPrinc); if ( nPrinc.giveNumberOfRows() == 0 ) { nPrinc.resize(2, 2); nPrinc.at(1, 1) = 1; nPrinc.at(2, 2) = 1; } // principal internal lengths double l1 = cl0; double l2 = cl0; double gamma; if ( sigPrinc.at(1) > 0 ) { if ( sigPrinc.at(2) > 0 ) { gamma = beta + ( 1 - beta ) * sigPrinc.at(2) * sigPrinc.at(2) / ( sigPrinc.at(1) * sigPrinc.at(1) ); } else { gamma = beta; } } else { gamma = 1; } l2 = l2 * gamma; // compose the internal Length matrix in global coordinates // the first subscript refers to coordinate // the second subscript refers to eigenvalue double n11 = nPrinc.at(1, 1); double n12 = nPrinc.at(1, 2); double n21 = nPrinc.at(2, 1); double n22 = nPrinc.at(2, 2); answer.at(1, 1) = l1 * l1 * n11 * n11 + l2 * l2 * n12 * n12; answer.at(1, 2) = l1 * l1 * n11 * n21 + l2 * l2 * n12 * n22; answer.at(2, 1) = l1 * l1 * n11 * n21 + l2 * l2 * n12 * n22; answer.at(2, 2) = l1 * l1 * n21 * n21 + l2 * l2 * n22 * n22; } else { OOFEM_ERROR("Unknown material mode."); } } }
// returns the stress vector in 3d stress space // computed from the previous plastic strain and current total strain void MisesMat :: performPlasticityReturn(GaussPoint *gp, const FloatArray &totalStrain) { double kappa, yieldValue, dKappa; FloatArray reducedStress; FloatArray strain, plStrain; MaterialMode mode = gp->giveMaterialMode(); MisesMatStatus *status = static_cast< MisesMatStatus * >( this->giveStatus(gp) ); StressVector fullStress(mode); this->initTempStatus(gp); this->initGpForNewStep(gp); // get the initial plastic strain and initial kappa from the status status->givePlasticStrain(plStrain); kappa = status->giveCumulativePlasticStrain(); // === radial return algorithm === if ( mode == _1dMat ) { LinearElasticMaterial *lmat = this->giveLinearElasticMaterial(); double E = lmat->give('E', gp); /*trial stress*/ fullStress.at(1) = E * ( totalStrain.at(1) - plStrain.at(1) ); double sigmaY = sig0 + H * kappa; double trialS = fullStress.at(1); trialS = fabs(trialS); /*yield function*/ yieldValue = trialS - sigmaY; // === radial return algorithm === if ( yieldValue > 0 ) { dKappa = yieldValue / ( H + E ); kappa += dKappa; fullStress.at(1) = fullStress.at(1) - dKappa *E *signum( fullStress.at(1) ); plStrain.at(1) = plStrain.at(1) + dKappa *signum( fullStress.at(1) ); } } else if ( ( mode == _PlaneStrain ) || ( mode == _3dMat ) ) { // elastic predictor StrainVector elStrain(totalStrain, mode); elStrain.subtract(plStrain); StrainVector elStrainDev(mode); double elStrainVol; elStrain.computeDeviatoricVolumetricSplit(elStrainDev, elStrainVol); StressVector trialStressDev(mode); elStrainDev.applyDeviatoricElasticStiffness(trialStressDev, G); /**************************************************************/ double trialStressVol; 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 = trialStressDev.computeStressNorm(); double sigmaY = sig0 + H * kappa; yieldValue = sqrt(3. / 2.) * trialS - sigmaY; if ( yieldValue > 0. ) { // increment of cumulative plastic strain dKappa = yieldValue / ( H + 3. * G ); kappa += dKappa; StrainVector dPlStrain(mode); // the following line is equivalent to multiplication by scaling matrix P trialStressDev.applyDeviatoricElasticCompliance(dPlStrain, 0.5); // increment of plastic strain dPlStrain.times(sqrt(3. / 2.) * dKappa / trialS); plStrain.add(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 double stressVol = 3. * K * elStrainVol; trialStressDev.computeDeviatoricVolumetricSum(fullStress, stressVol); } // store the effective stress in status status->letTempEffectiveStressBe(fullStress); // store the plastic strain and cumulative plastic strain status->letTempPlasticStrainBe(plStrain); status->setTempCumulativePlasticStrain(kappa); }