Example #1
0
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);
    }
}
Example #2
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);
}
Example #3
0
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

}
Example #4
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");
}