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); }
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); }
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); }