void RCM2Material :: giveCrackedStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *atTime) // // // Returns material incremental stiffness matrix for cracked concrete. // This matrix is composed from submatrix, each of them corresponds to // one active crack in material point. // when constructing submatrix, following assumptions are made: // // A salient characteriastic of crack formation concerns the fact that in most general case // of tree-dimensional solid only 3 out of 6 components of the crack strain rate vector // are possibly non-zero.(the normal and two shear strain rates). // We therefore assume that the stress-strain law for the crack has a structure // such that the other strains rate components vanish. Moreover we assume that // the novanishing strain rate components are only related to corresponding // stress rate components (submatrix has dimensions 3x3). // // if strainIncrement is defined (not null) then we take care about possible unlo&reloading // we don't teke care about possible cracking (or non-linear softening) during strain increment // this correction is made in this -> updateCrackStatus (gp); { RCM2MaterialStatus *status = ( RCM2MaterialStatus * ) this->giveStatus(gp); int i; int numberOfActiveCracks = status->giveNumberOfTempActiveCracks(); IntArray crackMap; status->giveCrackMap(crackMap); if ( numberOfActiveCracks == 0 ) { answer.resize(0, 0); return; } answer.resize(3, 3); answer.zero(); // loop over each active crack plane for ( i = 1; i <= 3; i++ ) { if ( crackMap.at(i) ) { // obtain incremental law for one crack answer.at(i, i) = this->giveCrackingModulus(rMode, gp, status->giveCrackStrain(i), i); } } }
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 :: giveRealPrincipalStressVector3d(FloatArray &answer, GaussPoint *gp, FloatArray &principalStrain, FloatMatrix &tempCrackDirs, TimeStep *atTime) // // returns real principal 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 // updates principal strain and stress of the receiver's status. // { int i, iter, ind; double maxErr; FloatArray crackStrainVector, reducedTotalStrainVector; FloatArray strainIncrement, crackStrainIterativeIncrement; FloatArray prevPrincipalStrain; FloatArray dSigma; FloatArray elastStrain, sigmaEl, sigmaCr(3); FloatArray fullDSigma; IntArray activatedCracks, crackMapping; FloatMatrix dcr, de, decr, fullDecr, crackDirs; RCM2MaterialStatus *status = ( RCM2MaterialStatus * ) this->giveStatus(gp); /* * if (status -> giveStressVector() == NULL) status->letStressVectorBe(new FloatArray(this->giveSizeOfReducedStressStrainVector(gp->giveMaterialMode()))); * if (status -> giveStrainVector() == NULL) status->letStrainVectorBe(new FloatArray(this->giveSizeOfReducedStressStrainVector(gp->giveMaterialMode()))); * // if (status -> givePlasticStrainVector() == NULL) status->letPlasticStrainVectorBe(new FloatArray(6)); * if (status -> giveStressIncrementVector() == NULL) status->letStressIncrementVectorBe(new FloatArray(this->giveSizeOfReducedStressStrainVector(gp->giveMaterialMode()))); * if (status -> giveStrainIncrementVector() == NULL) status->letStrainIncrementVectorBe(new FloatArray(this->giveSizeOfReducedStressStrainVector(gp->giveMaterialMode()))); * // if (status -> givePlasticStrainIncrementVector() == NULL) status->letPlasticStrainIncrementVectorBe(new FloatArray(6)); */ /* * // totalStressVector = gp -> giveStressVector()->GiveCopy(); * reducedTotalStrainVector = status -> giveStrainVector(); * reducedTotalStrainVector.add(fullStrainIncrement); * crossSection->giveFullCharacteristicVector(totalStrainVector, gp, reducedTotalStrainVector); * //delete reducedTotalStrainVector; * // plasticStrainVector = status -> givePlasticStrainVector()->GiveCopy(); * * * // already cracked - next directions are determined * // according to principal strain directions * status->giveTempCrackDirs(tempCrackDirs); * this->computePrincipalValDir (principalStrain, tempCrackDirs, * totalStrainVector, * principal_strain); * status->letTempCrackDirsBe (tempCrackDirs); */ status->giveCrackStrainVector(crackStrainVector); // local one status->giveCrackDirs(crackDirs); if ( principalStrain.containsOnlyZeroes() ) { // keep old principal values status->letTempCrackDirsBe(crackDirs); } else { this->sortPrincDirAndValCloseTo(& principalStrain, & tempCrackDirs, & crackDirs); status->letTempCrackDirsBe(tempCrackDirs); } // compute de in local system // for iso materials no transformation if stiffness required // // local strain increment status->givePrevPrincStrainVector(prevPrincipalStrain); strainIncrement.beDifferenceOf(principalStrain, prevPrincipalStrain); status->letPrincipalStrainVectorBe(principalStrain); this->giveNormalElasticStiffnessMatrix(de, FullForm, TangentStiffness, gp, atTime, tempCrackDirs); // // construct mapping matrix of active cracks // this mapping will dynamically change as // some crack can unlo or reload // this->updateActiveCrackMap(gp); status->giveCrackMap(crackMapping); // start iteration until stress computed from elastic increment // is equal to stress computed from cracking strain increment // we do this computation in reduced stress strain space dSigma.resize(0); for ( iter = 1; iter <= 20; iter++ ) { // // first check if already cracked // if ( status->giveNumberOfTempActiveCracks() ) { // active crack exist this->giveCrackedStiffnessMatrix(dcr, TangentStiffness, gp, atTime); fullDecr = de; fullDecr.add(dcr); decr.beSubMatrixOf(fullDecr, crackMapping); if ( dSigma.giveSize() == 0 ) { fullDSigma.beProductOf(de, strainIncrement); dSigma.beSubArrayOf(fullDSigma, crackMapping); } decr.solveForRhs(dSigma, crackStrainIterativeIncrement); for ( i = 1; i <= 3; i++ ) { if ( ( ind = crackMapping.at(i) ) ) { crackStrainVector.at(i) += crackStrainIterativeIncrement.at(ind); } } // check for crack closing, updates also cracking map this->checkIfClosedCracks(gp, crackStrainVector, crackMapping); // elastic strain component elastStrain.beDifferenceOf(principalStrain, crackStrainVector); sigmaEl.beProductOf(de, elastStrain); // Stress in cracks for ( i = 1; i <= 3; i++ ) { if ( crackMapping.at(i) ) { sigmaCr.at(i) = giveNormalCrackingStress(gp, crackStrainVector.at(i), i); } } // update status status->letCrackStrainVectorBe(crackStrainVector); } else { // // no active crack exist - elastic behaviour // elastStrain.beDifferenceOf(principalStrain, crackStrainVector); sigmaEl.beProductOf(de, elastStrain); sigmaCr.zero(); } // check for new cracks // and update crack map if necessary // when we update map, we need to add new crack at end // because sigmaCr is build this->checkForNewActiveCracks(activatedCracks, gp, crackStrainVector, sigmaEl, sigmaCr, principalStrain); if ( activatedCracks.giveSize() ) { // update crack map also this->updateActiveCrackMap(gp, & activatedCracks); status->giveCrackMap(crackMapping); // update crackMap } // // compute unbalanced stress // dSigma = sigmaEl - sigmaCr for active cracks fullDSigma = sigmaEl; fullDSigma.subtract(sigmaCr); dSigma.beSubArrayOf(fullDSigma, crackMapping); // find max error in dSigma // if max err < allovedErr -> stop iteration // allowed Err is computed relative to Ft; // check only for active cracks maxErr = 0.; for ( i = 1; i <= dSigma.giveSize(); i++ ) { if ( fabs( dSigma.at(i) ) > maxErr ) { maxErr = fabs( dSigma.at(i) ); } } if ( maxErr < rcm_STRESSRELERROR * this->give(pscm_Ft, gp) ) { status->letPrincipalStressVectorBe(sigmaEl); answer = sigmaEl; return; } } // loop // convergence not reached _error("GiveRealStressVector3d - convergence not reached"); }