void KelvinChainSolidMaterial :: giveEigenStrainVector(FloatArray &answer, GaussPoint *gp, TimeStep *tStep, ValueModeType mode) // // computes the strain due to creep at constant stress during the increment // (in fact, the INCREMENT of creep strain is computed for mode == VM_Incremental) // { int mu; double betaMu; double v; FloatArray *sigmaVMu = NULL, reducedAnswer, help; FloatMatrix C; KelvinChainSolidMaterialStatus *status = static_cast< KelvinChainSolidMaterialStatus * >( this->giveStatus(gp) ); if ( (tStep->giveIntrinsicTime() < this->castingTime) ) { OOFEM_ERROR("Attempted to evaluate creep strain for time lower than casting time"); } if ( this->EparVal.isEmpty() ) { this->updateEparModuli(0., gp, tStep); // stiffnesses are time independent (evaluated at time t = 0.) } if ( mode == VM_Incremental ) { for ( mu = 1; mu <= nUnits; mu++ ) { betaMu = this->computeBetaMu(gp, tStep, mu); sigmaVMu = & status->giveHiddenVarsVector(mu); // JB if ( sigmaVMu->isNotEmpty() ) { help.zero(); help.add(* sigmaVMu); help.times( ( 1.0 - betaMu ) / this->giveEparModulus(mu) ); reducedAnswer.add(help); } } if ( sigmaVMu->isNotEmpty() ) { help = reducedAnswer; this->giveUnitComplianceMatrix(C, gp, tStep); reducedAnswer.beProductOf(C, help); v = this->computeSolidifiedVolume(gp, tStep); reducedAnswer.times(1. / v); } answer = reducedAnswer; } else { /* error - total mode not implemented yet */ OOFEM_ERROR("mode is not supported"); } }
void KelvinChainSolidMaterial :: giveEigenStrainVector(FloatArray &answer, MatResponseForm form, GaussPoint *gp, TimeStep *atTime, ValueModeType mode) // // computes the strain due to creep at constant stress during the increment // (in fact, the INCREMENT of creep strain is computed for mode == VM_Incremental) // { int mu; double betaMu; double v; FloatArray *sigmaVMu, reducedAnswer, help; FloatMatrix C; KelvinChainSolidMaterialStatus *status = ( KelvinChainSolidMaterialStatus * ) this->giveStatus(gp); if ( mode == VM_Incremental ) { for ( mu = 1; mu <= nUnits; mu++ ) { betaMu = this->computeBetaMu(gp, atTime, mu); sigmaVMu = status->giveHiddenVarsVector(mu); if ( sigmaVMu ) { help.zero(); help.add(* sigmaVMu); help.times( ( 1.0 - betaMu ) / this->giveEparModulus(mu) ); reducedAnswer.add(help); } } if ( sigmaVMu ) { help = reducedAnswer; this->giveUnitComplianceMatrix(C, ReducedForm, gp, atTime); reducedAnswer.beProductOf(C, help); v = this->computeSolidifiedVolume(gp, atTime); reducedAnswer.times(1. / v); } if ( form == ReducedForm ) { answer = reducedAnswer; return; } // expand the strain to full form if requested ( ( StructuralCrossSection * ) gp->giveCrossSection() )-> giveFullCharacteristicVector(answer, gp, reducedAnswer); } else { /* error - total mode not implemented yet */ _error("giveEigenStrainVector - mode is not supported"); } }
void KelvinChainSolidMaterial :: computeHiddenVars(GaussPoint *gp, TimeStep *tStep) { /* * Updates hidden variables used to effectively trace the load history */ double betaMu; double lambdaMu; FloatArray help, SigmaVMu, deltaEps0, deltaSigma; FloatMatrix D; KelvinChainSolidMaterialStatus *status = static_cast< KelvinChainSolidMaterialStatus * >( this->giveStatus(gp) ); if ( !this->isActivated(tStep) ) { help.resize(StructuralMaterial :: giveSizeOfVoigtSymVector( gp->giveMaterialMode() ) ); help.zero(); for ( int mu = 1; mu <= nUnits; mu++ ) { status->letTempHiddenVarsVectorBe(mu, help); } return; } help = status->giveTempStrainVector(); // gives updated strain vector (at the end of time-step) help.subtract( status->giveStrainVector() ); // strain increment in current time-step // Subtract the stress-independent part of strain this->computeStressIndependentStrainVector(deltaEps0, gp, tStep, VM_Incremental); if ( deltaEps0.giveSize() ) { help.subtract(deltaEps0); // should be equal to zero if there is no stress change during the time-step } this->giveUnitStiffnessMatrix(D, gp, tStep); help.times( this->giveEModulus(gp, tStep) ); deltaSigma.beProductOf(D, help); for ( int mu = 1; mu <= nUnits; mu++ ) { betaMu = this->computeBetaMu(gp, tStep, mu); lambdaMu = this->computeLambdaMu(gp, tStep, mu); help = deltaSigma; help.times(lambdaMu); SigmaVMu = status->giveHiddenVarsVector(mu); if ( SigmaVMu.giveSize() ) { SigmaVMu.times(betaMu); SigmaVMu.add(help); status->letTempHiddenVarsVectorBe(mu, SigmaVMu); } else { status->letTempHiddenVarsVectorBe(mu, help); } } }
void KelvinChainSolidMaterial :: updateYourself(GaussPoint *gp, TimeStep *tNow) { /* * Updates hidden variables used to effectively trace the load history */ double betaMu; double lambdaMu; FloatArray help, *SigmaVMu, deltaEps0, deltaSigma; FloatMatrix D; KelvinChainSolidMaterialStatus *status = ( KelvinChainSolidMaterialStatus * ) this->giveStatus(gp); help = status->giveTempStrainVector(); // gives updated strain vector (at the end of time-step) help.subtract( status->giveStrainVector() ); // strain increment in current time-step // Subtract the stress-independent part of strain this->computeStressIndependentStrainVector(deltaEps0, gp, tNow, VM_Incremental); if ( deltaEps0.giveSize() ) { help.subtract(deltaEps0); // should be equal to zero if there is no stress change during the time-step } this->giveUnitStiffnessMatrix(D, ReducedForm, gp, tNow); help.times( this->giveEModulus(gp, tNow) ); deltaSigma.beProductOf(D, help); for ( int mu = 1; mu <= nUnits; mu++ ) { betaMu = this->computeBetaMu(gp, tNow, mu); lambdaMu = this->computeLambdaMu(gp, tNow, mu); help = deltaSigma; help.times(lambdaMu); SigmaVMu = status->giveHiddenVarsVector(mu); if ( SigmaVMu ) { SigmaVMu->times(betaMu); SigmaVMu->add(help); } else { status->letHiddenVarsVectorBe( mu, ( new FloatArray(help) ) ); } } status->updateYourself(tNow); }