void RCM2Material :: giveRealStressVector(FloatArray &answer, MatResponseForm form, GaussPoint *gp, const FloatArray &totalStrain, TimeStep *atTime) // // returns real stress vector in 3d stress space of receiver according to // previous level of stress and current // strain increment, the only way, how to correctly update gp records // { FloatArray princStress, reducedStressVector, crackStrain, reducedAnswer; FloatArray reducedTotalStrainVector, principalStrain, strainVector; FloatMatrix tempCrackDirs; RCM2MaterialStatus *status = ( RCM2MaterialStatus * ) this->giveStatus(gp); StructuralCrossSection *crossSection = ( StructuralCrossSection * ) gp->giveElement()->giveCrossSection(); this->initTempStatus(gp); this->initGpForNewStep(gp); // subtract stress independent part // note: eigenStrains (temperature) is not contained in mechanical strain stored in gp // therefore it is necessary to subtract always the total eigen strain value this->giveStressDependentPartOfStrainVector(reducedTotalStrainVector, gp, totalStrain, atTime, VM_Total); // crossSection->giveFullCharacteristicVector(strainVector, gp, reducedTotalStrainVector); status->giveTempCrackDirs(tempCrackDirs); this->computePrincipalValDir(principalStrain, tempCrackDirs, strainVector, principal_strain); this->giveRealPrincipalStressVector3d(princStress, gp, principalStrain, tempCrackDirs, atTime); princStress.resize(6); status->giveTempCrackDirs(tempCrackDirs); this->transformStressVectorTo(answer, tempCrackDirs, princStress, 1); status->letTempStrainVectorBe(totalStrain); crossSection->giveReducedCharacteristicVector(reducedStressVector, gp, answer); status->letTempStressVectorBe(reducedStressVector); status->giveCrackStrainVector(crackStrain); this->updateCrackStatus(gp, crackStrain); if ( form == FullForm ) { return; } crossSection->giveReducedCharacteristicVector(reducedAnswer, gp, answer); answer = reducedAnswer; }
void RCM2Material :: giveEffectiveMaterialStiffnessMatrix(FloatMatrix &answer, MatResponseForm form, MatResponseMode rMode, GaussPoint *gp, TimeStep *atTime) // // returns effective material stiffness matrix in full form // for gp stress strain mode // { RCM2MaterialStatus *status = ( RCM2MaterialStatus * ) this->giveStatus(gp); StructuralMaterial *lMat = static_cast< StructuralMaterial * >( this->giveLinearElasticMaterial() ); int numberOfActiveCracks = status->giveNumberOfTempActiveCracks(); int i, j, indi, indj, ii, jj; double G, princStressDis, princStrainDis; FloatMatrix de, invDe, compliance, dcr, d, df, t, tt, tempCrackDirs; FloatArray principalStressVector, principalStrainVector; IntArray mask; if ( ( rMode == ElasticStiffness ) || ( numberOfActiveCracks == 0 ) ) { lMat->giveCharacteristicMatrix(answer, form, rMode, gp, atTime); return; } // this->updateActiveCrackMap(gp) must be done after restart. this->updateActiveCrackMap(gp); status->giveTempCrackDirs(tempCrackDirs); this->giveNormalElasticStiffnessMatrix(de, ReducedForm, rMode, gp, atTime, tempCrackDirs); invDe.beInverseOf(de); this->giveCrackedStiffnessMatrix(dcr, rMode, gp, atTime); this->giveStressStrainMask( mask, ReducedForm, gp->giveMaterialMode() ); compliance.resize( mask.giveSize(), mask.giveSize() ); // we will set // first we set compliances for normal streses in // local coordinate system defined by crackplane for ( i = 1; i <= 3; i++ ) { if ( ( indi = this->giveStressStrainComponentIndOf(FullForm, gp->giveMaterialMode(), i) ) ) { for ( j = 1; j <= 3; j++ ) { if ( ( indj = this->giveStressStrainComponentIndOf(FullForm, gp->giveMaterialMode(), j) ) ) { compliance.at(indi, indj) += invDe.at(i, j); } } if ( status->isCrackActive(i) ) { if ( dcr.at(i, i) <= 1.e-8 ) { compliance.at(indi, indi) *= rcm2_BIGNUMBER; } else { compliance.at(indi, indi) += 1. / dcr.at(i, i); } } } } status->getPrincipalStressVector(principalStressVector); status->getPrincipalStrainVector(principalStrainVector); // now remain to set shears G = this->give(pscm_G, gp); for ( i = 4; i <= 6; i++ ) { if ( ( indi = this->giveStressStrainComponentIndOf(FullForm, gp->giveMaterialMode(), i) ) ) { if ( i == 4 ) { ii = 2; jj = 3; } else if ( i == 5 ) { ii = 1; jj = 3; } else { ii = 1; jj = 2; } princStressDis = principalStressVector.at(ii) - principalStressVector.at(jj); princStrainDis = principalStrainVector.at(ii) - principalStrainVector.at(jj); if ( fabs(princStrainDis) < rcm_SMALL_STRAIN ) { compliance.at(indi, indi) = 1. / G; } else if ( fabs(princStressDis) < 1.e-8 ) { compliance.at(indi, indi) = rcm2_BIGNUMBER; } else { compliance.at(indi, indi) = 2 * princStrainDis / princStressDis; } } } // now we invert compliance to get stiffness in reduced space d.beInverseOf(compliance); // delete compliance; // // now let d to grow to Full Format // this->giveStressStrainMask( mask, ReducedForm, gp->giveMaterialMode() ); df.beSubMatrixOfSizeOf(d, mask, 6); // // final step - transform stiffnes to global c.s // this->giveStressVectorTranformationMtrx(t, tempCrackDirs, 1); tt.beTranspositionOf(t); df.rotatedWith(tt); if ( form == FullForm ) { answer = df; } else { // reduced form asked this->giveStressStrainMask( mask, FullForm, gp->giveMaterialMode() ); answer.beSubMatrixOf(df, mask); } }
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); }