Exemplo n.º 1
0
void
RCM2Material :: checkForNewActiveCracks(IntArray &answer, GaussPoint *gp,
                                        const FloatArray &crackStrain,
                                        const FloatArray &princStressVector,
                                        FloatArray &crackStressVector,
                                        const FloatArray &princStrainVector)
//
// returns int_array flag showing if some crack
// is newly activated or
// closed crack is reopened
// return 0 if no crack is activated or reactivated.
// modifies crackStressVector for newly activated crack.
//
{
    double initStress, Le = 0.0;
    int i, j, upd, activationFlag = 0;
    RCM2MaterialStatus *status = ( RCM2MaterialStatus * ) this->giveStatus(gp);
    FloatArray localStress;
    FloatMatrix tempCrackDirs;
    IntArray crackMap;

    answer.resize(3);
    answer.zero();
    status->giveCrackMap(crackMap);
    localStress = princStressVector;
    //
    // local stress is updated according to reached local crack strain
    //
    for ( i = 1; i <= 3; i++ ) { // loop over each possible crack plane
        // test previous status of each possible crack plane
        upd = 0;
        if ( ( crackMap.at(i) == 0 ) &&
            ( this->giveStressStrainComponentIndOf(FullForm, gp->giveMaterialMode(), i) ) ) {
            if ( status->giveTempMaxCrackStrain(i) > 0. ) {
                // if (status->giveTempCrackStatus()->at(i) != pscm_NONE) {
                //
                // previously cracked direction
                //
                initStress = 0.;
            } else {
                // newer cracked, so we compute principal stresses
                // and compare them with reduced tension strength
                // as a criterion for crack initiation

                FloatArray crackPlaneNormal(3);
                status->giveTempCrackDirs(tempCrackDirs);
                for ( j = 1; j <= 3; j++ ) {
                    crackPlaneNormal.at(j) = tempCrackDirs.at(j, i);
                }

                // Le = gp->giveElement()->giveCharacteristicLenght (gp, &crackPlaneNormal);
                Le = this->giveCharacteristicElementLenght(gp, crackPlaneNormal);
                initStress = this->computeStrength(gp, Le);
                upd = 1;
            }

            if ( localStress.at(i) > initStress ) {
                crackStressVector.at(i) = initStress;
                answer.at(i) = 1;
                activationFlag = 1;
                if ( upd ) {
                    this->updateStatusForNewCrack(gp, i, Le);
                }
            }
        } // end of tested crack

    } // end of loop over are possible directions

    if ( activationFlag ) {
        return;
    }

    answer.resize(0);
}
Exemplo n.º 2
0
void
MPSDamMaterial :: giveRealStressVector(FloatArray &answer, GaussPoint *gp, const FloatArray &totalStrain, TimeStep *tStep)
{
    
  if (this->E < 0.) {   // initialize dummy elastic modulus E
    this->E = 1. / MPSMaterial :: computeCreepFunction(28.01, 28., gp, tStep);
  }

  MPSDamMaterialStatus *status = static_cast< MPSDamMaterialStatus * >( this->giveStatus(gp) );

    MaterialMode mode = gp->giveMaterialMode();

    FloatArray principalStress;
    FloatMatrix principalDir;

    StressVector tempEffectiveStress(mode);
    StressVector tempNominalStress(mode);

    double f, sigma1, kappa, tempKappa = 0.0, omega = 0.0;

    // effective stress computed by the viscoelastic MPS material
    MPSMaterial :: giveRealStressVector(tempEffectiveStress, gp, totalStrain, tStep);

    if ( !this->isActivated(tStep) ) {
        FloatArray help;
        help.resize( StructuralMaterial :: giveSizeOfVoigtSymVector( gp->giveMaterialMode() ) );
        help.zero();

        status->letTempStrainVectorBe(help);
        status->letTempStressVectorBe(help);
        status->letTempViscoelasticStressVectorBe(help);

#ifdef supplementary_info
        status->setResidualTensileStrength(0.);
        status->setCrackWidth(0.);
        status->setTempKappa(0.);
        status->setTempDamage(0.);
#endif

        return;
    }

    tempEffectiveStress.computePrincipalValDir(principalStress, principalDir);

    sigma1 = 0.;
    if ( principalStress.at(1) > 0.0 ) {
        sigma1 = principalStress.at(1);
    }

    kappa = sigma1 / this->E;

    f = kappa - status->giveKappa();

    if ( f <= 0.0 ) { // damage does not grow
        tempKappa = status->giveKappa();
        omega     = status->giveDamage();

#ifdef supplementary_info
        double residualStrength = 0.;
        double e0;

        if ( ( this->timeDepFracturing ) && ( this->givee0(gp) == 0. ) ) {
            this->initDamagedFib(gp, tStep);
        }

        e0 = this->givee0(gp);

        if ( omega == 0. ) {
            residualStrength = E * e0; // undamaged material
        } else {
            double gf, ef, wf = 0., Le;
            gf = this->givegf(gp);
            Le = status->giveCharLength();

            if ( softType == ST_Exponential_Cohesive_Crack ) { // exponential softening
                wf = gf / this->E / e0; // wf is the crack opening
            } else if ( softType == ST_Linear_Cohesive_Crack ) { // linear softening law
                wf = 2. * gf / this->E / e0; // wf is the crack opening
            } else {
                OOFEM_ERROR("Gf unsupported for softening type softType = %d", softType);
            }

            ef = wf / Le; //ef is the fracturing strain

            if ( this->softType == ST_Linear_Cohesive_Crack ) {
                residualStrength = E * e0 * ( ef - tempKappa ) / ( ef - e0 );
            } else if (  this->softType == ST_Exponential_Cohesive_Crack ) {
                residualStrength = E * e0 * exp(-1. * ( tempKappa - e0 ) / ef);
            } else {
                OOFEM_ERROR("Unknown softening type for cohesive crack model.");
            }
        }

        if ( status ) {
            status->setResidualTensileStrength(residualStrength);
        }

#endif
    } else {
        // damage grows
        tempKappa = kappa;

        FloatArray crackPlaneNormal(3);
        for ( int i = 1; i <= principalStress.giveSize(); i++ ) {
            crackPlaneNormal.at(i) = principalDir.at(i, 1);
        }
        this->initDamaged(tempKappa, crackPlaneNormal, gp, tStep);
        this->computeDamage(omega, tempKappa, gp);
    }

    answer.zero();

    if ( omega > 0. ) {
        tempNominalStress = tempEffectiveStress;

        if ( this->isotropic ) {
            // convert effective stress to nominal stress
            tempNominalStress.times(1. - omega);
            answer.add(tempNominalStress);
        } else {
            // stress transformation matrix
            FloatMatrix Tstress;

            // compute principal nominal stresses by multiplying effective stresses by damage
            for ( int i = 1; i <= principalStress.giveSize(); i++ ) {
                if ( principalStress.at(i) > 0. ) {
                    // convert principal effective stress to nominal stress
                    principalStress.at(i) *= ( 1. - omega );
                }
            }

            if ( mode == _PlaneStress ) {
                principalStress.resizeWithValues(3);
                givePlaneStressVectorTranformationMtrx(Tstress, principalDir, true);
            } else {
                principalStress.resizeWithValues(6);
                giveStressVectorTranformationMtrx(Tstress, principalDir, true);
            }

            principalStress.rotatedWith(Tstress, 'n');


            if ( mode == _PlaneStress ) { // plane stress
                answer.add(principalStress);
            } else if ( this->giveSizeOfVoigtSymVector(mode) != this->giveSizeOfVoigtSymVector(_3dMat) ) { // mode = _PlaneStrain or axial symmetry
                StressVector redFormStress(mode);
                redFormStress.convertFromFullForm(principalStress, mode);
                answer.add(redFormStress);
            } else { // 3D
                answer.add(principalStress);
            }
        }
    } else {
        answer.add(tempEffectiveStress);
    }

#ifdef supplementary_info

    if ( ( omega == 0. ) || ( sigma1 <= 0 ) ) {
        status->setCrackWidth(0.);
    } else {
        FloatArray principalStrains;
        this->computePrincipalValues(principalStrains, totalStrain, principal_strain);

        double crackWidth;
        //case when the strain localizes into narrow band and after a while the stresses relax

        double strainWithoutTemperShrink = principalStrains.at(1);
        strainWithoutTemperShrink -=  status->giveTempThermalStrain();
        strainWithoutTemperShrink -=  status->giveTempDryingShrinkageStrain();
        strainWithoutTemperShrink -=  status->giveTempAutogenousShrinkageStrain();


        crackWidth = status->giveCharLength() * omega * strainWithoutTemperShrink;

        status->setCrackWidth(crackWidth);
    }

#endif

    // update gp
    status->letTempStrainVectorBe(totalStrain);
    status->letTempStressVectorBe(answer);
    status->letTempViscoelasticStressVectorBe(tempEffectiveStress);
    status->setTempKappa(tempKappa);
    status->setTempDamage(omega);
}
Exemplo n.º 3
0
void
MazarsMaterial :: initDamaged(double kappa, FloatArray &totalStrainVector, GaussPoint *gp)
{
    int indmin = 1, indmax = 1;
    double le;
    FloatArray principalStrains, crackPlaneNormal(3), fullstrain;
    FloatMatrix principalDir(3, 3);
    MazarsMaterialStatus *status = static_cast< MazarsMaterialStatus * >( this->giveStatus(gp) );
    //StructuralCrossSection *crossSection = (StructuralCrossSection*) gp -> giveElement()->giveCrossSection();

    // crossSection->giveFullCharacteristicVector(fullstrain, gp, totalStrainVector);

    if ( ( kappa > this->e0 ) && ( status->giveDamage() == 0. ) ) {
        //printf (":");


        if ( gp->giveMaterialMode() == _1dMat ) {
            crackPlaneNormal.zero();
            crackPlaneNormal.at(1) = 1.0;
            le = gp->giveElement()->giveCharacteristicLenght(gp, crackPlaneNormal);
            status->setLe(le);
            status->setLec(le);
            return;
        }


        if ( gp->giveMaterialMode() == _PlaneStress ) {
            principalDir.resize(2, 2);
        }

        this->computePrincipalValDir(principalStrains, principalDir, totalStrainVector, principal_strain);
        if ( gp->giveMaterialMode() == _PlaneStress ) {
            if ( principalStrains.at(1) > principalStrains.at(2) ) {
                indmax = 1;
                indmin = 2;
            } else {
                indmax = 2;
                indmin = 1;
            }
        } else {
            // find index of max and min positive principal strains
            for ( int i = 2; i <= 3; i++ ) {
                if ( principalStrains.at(i) > principalStrains.at(indmax) ) {
                    indmax = i;
                }

                if ( principalStrains.at(i) < principalStrains.at(indmin) ) {
                    indmin = i;
                }
            }
        }

        for ( int i = 1; i <= principalStrains.giveSize(); i++ ) {
            crackPlaneNormal.at(i) = principalDir.at(i, indmax);
        }

        le = gp->giveElement()->giveCharacteristicLenght(gp, crackPlaneNormal);
        // remember le in cooresponding status for tension
        status->setLe(le);

        for ( int i = 1; i <= principalStrains.giveSize(); i++ ) {
            crackPlaneNormal.at(i) = principalDir.at(i, indmin);
        }

        le = gp->giveElement()->giveCharacteristicLenght(gp, crackPlaneNormal);
        // remember le in cooresponding status for compression
        status->setLec(le);

        // printf ("les: %e %e\n", status->giveLe(), status->giveLec());
    }

    //status->setLe(hReft); status->setLec(hRefc);
}