예제 #1
0
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);
}
예제 #2
0
파일: misesmat.C 프로젝트: rainbowlqs/oofem
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);
}