void RCM2Material :: updateActiveCrackMap(GaussPoint *gp, const IntArray *activatedCracks) // // // updates mapping matrix of active cracks // { int i, indx = 1; RCM2MaterialStatus *status = ( RCM2MaterialStatus * ) this->giveStatus(gp); IntArray crackMap; status->giveCrackMap(crackMap); //if (crackMap == NULL) _error ("updateActiveCrackMap: NULL pointer encountered"); for ( i = 1; i <= 3; i++ ) { if ( status->isCrackActive(i) ) { crackMap.at(i) = indx++; } else if ( activatedCracks ) { if ( ( activatedCracks->at(i) != 0 ) ) { crackMap.at(i) = indx++; } } else { crackMap.at(i) = 0; } } // store modified map into status status->letCrackMapBe(crackMap); }
void RCM2Material :: checkIfClosedCracks(GaussPoint *gp, FloatArray &crackStrainVector, IntArray &crackMap) // // Check if crack closing occurs // if yes updates crackStrainVector and gp-status accordingly // { RCM2MaterialStatus *status = ( RCM2MaterialStatus * ) this->giveStatus(gp); int i, isClosing = 0; for ( i = 1; i <= 3; i++ ) { if ( crackMap.at(i) ) { if ( crackStrainVector.at(i) < 0. ) { // crack closing occur crackStrainVector.at(i) = 0.; crackMap.at(i) = 0; // status->giveTempCrackStatus()->at(i) = pscm_CLOSED; isClosing = 1; } } } status->letCrackMapBe(crackMap); if ( isClosing ) { this->updateActiveCrackMap(gp); } status->giveCrackMap(crackMap); // update crack Map }
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 :: updateCrackStatus(GaussPoint *gp, const FloatArray &crackStrain) // // updates gp records and MatStatus due to cracking. // // Updates MatStatus (respective it's temporary variables) to current // reached status during integrating incremental constitutive relations // Temporary variables are used, because we may integrate constitutive // realtions many times for different strainIncrement in order to // reach equilibrium state, so we don't want to change other variables // which describing previously reached equlibrium. After a new equilibrium // is reached, this->updateYourself is called which invokes matStatus-> // updateYourself(), which copies temporary variables to variables // describing equilibrium. // // { int i; double minCrackStrainsForFullyOpenCrack; RCM2MaterialStatus *status = ( RCM2MaterialStatus * ) this->giveStatus(gp); IntArray crackMap; status->giveCrackMap(crackMap); // check if material previously cracked // and compute possible crack planes // or if newer cracked, so we compute principal stresses // (for iso mat. coincide with princ strains) // and compare them with reduced tension strength // as a criterion for crack initiation // principalStrain = status->givePrincipalStrainVector(); // transform stresses to principal directions of strains // // local stress is updated according to reached local crack strain // for ( i = 1; i <= 3; i++ ) { // loop over each possible crack plane if ( ( crackMap.at(i) != 0 ) && ( this->giveStressStrainComponentIndOf(FullForm, gp->giveMaterialMode(), i) ) ) { if ( status->giveTempMaxCrackStrain(i) < crackStrain.at(i) ) { status->setTempMaxCrackStrain( i, crackStrain.at(i) ); } minCrackStrainsForFullyOpenCrack = this->giveMinCrackStrainsForFullyOpenCrack(gp, i); //if ((crackStrain.at(i) >= status->giveMinCrackStrainsForFullyOpenCrack(i)) && if ( ( crackStrain.at(i) >= minCrackStrainsForFullyOpenCrack ) && ( crackStrain.at(i) >= status->giveTempMaxCrackStrain(i) ) ) { // // fully open crack // status->setTempCrackStatus(i, pscm_OPEN); } else if ( crackStrain.at(i) >= status->giveTempMaxCrackStrain(i) ) { // // further softening of crack // status->setTempCrackStatus(i, pscm_SOFTENING); // status->giveTempReachedSofteningStress()->at(i) = localStress->at(i); } else if ( crackStrain.at(i) <= 0. ) { if ( status->giveTempCrackStatus(i) != pscm_NONE ) { // previously active crack becomes closed status->setTempCrackStatus(i, pscm_CLOSED); } } else { // // crack unloading or reloading // status->setTempCrackStatus(i, pscm_UNLOADING); } } // end for possible direction } // end loop over prin directions }
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 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"); }