61 return mode == _3dLattice;
85 OOFEM_WARNING(
"Friction angle angle1 very large. Really intended? Default value is 0.23");
94 OOFEM_WARNING(
"Flow angle flow exceeds friction angle angle1. Set flow equal to angle1.\n");
111 ftOne = 0.15 * this->
ft;
133 if ( ftLocal == 0 ) {
146 double help = le * ( kappaDOne + omega * kappaDTwo ) / this->
wf;
147 double Lhs = le * kappaDTwo / this->
wf * strength * exp(-help) - kappaDTwo * this->
eNormalMean;
148 R = ( 1 - omega ) * kappaDTwo * this->eNormalMean - strength * exp(-help);
151 OOFEM_ERROR(
"computeDamageParam: algorithm not converging");
153 }
while ( fabs(R) >= 1.e-6 || omega < 0.0 );
155 double omegaOne = ( this->
eNormalMean * kappaDTwo * this->
wfOne - ftLocal * this->
wfOne - ( this->
ftOneRatio * ftLocal - ftLocal ) * kappaDOne * le ) /
157 double helpOne = le * kappaDOne + le * omegaOne * kappaDTwo;
163 double helpTwo = le * kappaDOne + le * omegaTwo * kappaDTwo;
166 if ( helpOne >= 0. && helpOne <
wfOne ) {
168 }
else if ( helpTwo >
wfOne && helpTwo <
wf ) {
170 }
else if ( helpTwo >
wf ) {
179 }
else if ( omega < 0.0 ) {
187std::unique_ptr<MaterialStatus>
203 double yieldValue = 0;
205 double shearNorm =
norm(stress [ { 1, 2 } ]);
208 if ( stress.
at(1) >= transition ) {
209 yieldValue = pow(shearNorm, 2.) + pow(this->
frictionAngleOne, 2.) * pow(stress.
at(1), 2.) +
213 yieldValue = pow(shearNorm, 2.) + pow(stress.
at(1) / this->frictionAngleTwo, 2.) +
214 2. * ( fcLocal - this->
frictionAngleOne * this->frictionAngleTwo * ftLocal ) / ( pow(this->frictionAngleTwo, 2.) * ( 1. + this->
frictionAngleOne * this->frictionAngleTwo ) ) * hardening * stress.
at(1) +
215 ( pow(fcLocal, 2.) * ( 1. - pow(this->
frictionAngleOne * this->frictionAngleTwo, 2.) ) -
216 2. * fcLocal * ftLocal * this->
frictionAngleOne * this->frictionAngleTwo * ( 1. + this->
frictionAngleOne * this->frictionAngleTwo ) ) / ( pow(this->frictionAngleTwo, 2.) * pow(1. + this->
frictionAngleOne * this->frictionAngleTwo, 2.) ) * pow(hardening, 2.);
225 return exp(kappa / this->
aHard);
231 return 1. / this->
aHard * exp(kappa / this->
aHard);
237 return 1. / pow(this->
aHard, 2.) * exp(kappa / this->
aHard);
251 double shearNorm =
norm(stress [ { 1, 2 } ]);
255 if ( stress.
at(1) >= transition ) {
257 f.
at(2) = 2. * shearNorm;
261 f.
at(1) = 2. * stress.
at(1) / pow(this->frictionAngleTwo, 2.) + 2. * ( fcLocal - this->
frictionAngleOne * this->frictionAngleTwo * ftLocal ) / ( pow(this->frictionAngleTwo, 2.) * ( 1. + this->
frictionAngleOne * this->frictionAngleTwo ) ) * hardening;
262 f.
at(2) = 2. * shearNorm;
263 f.
at(3) = 2. * ( fcLocal - this->
frictionAngleOne * this->frictionAngleTwo * ftLocal ) / ( pow(this->frictionAngleTwo, 2.) * ( 1. + this->
frictionAngleOne * this->frictionAngleTwo ) ) * stress.
at(1) * dHardeningDKappa +
264 2. * ( pow(fcLocal, 2.) * ( 1. - pow(this->
frictionAngleOne * this->frictionAngleTwo, 2.) ) -
282 double shearNorm =
norm(stress [ { 1, 2 } ]);
286 if ( stress.
at(1) >= transition ) {
288 m.
at(2) = 2. * shearNorm;
289 m.
at(3) = fabs( m.
at(1) );
292 m.
at(2) = 2. * shearNorm;
293 m.
at(3) = fabs( m.
at(1) );
311 if ( stress.
at(1) >= transition ) {
323 dm.
at(3, 1) = dm.
at(1, 1);
324 dm.
at(3, 2) = dm.
at(1, 2);
325 dm.
at(3, 3) = dm.
at(1, 3);
328 dm.
at(1, 1) = 2. / pow(this->flowAngleTwo, 2.);
330 dm.
at(1, 3) = 2. * ( fcLocal - this->
flowAngleOne * this->flowAngleTwo * ftLocal ) / ( pow(this->flowAngleTwo, 2.) * ( 1. + this->
flowAngleOne * this->flowAngleTwo ) ) * dHardeningDKappa;
338 dm.
at(3, 1) = -dm.
at(1, 1);
339 dm.
at(3, 2) = -dm.
at(1, 2);
340 dm.
at(3, 3) = -dm.
at(1, 3);
369 auto strain = reducedStrain [ { 0, 1, 2 } ];
373 auto tempPlasticStrain = status->givePlasticLatticeStrain() [ { 0, 1, 2 } ];
377 auto stress =
mult(tangent, strain - tempPlasticStrain);
386 int subIncrementCounter = 0;
391 if ( yieldValue / pow(fcLocal, 2.) >
yieldTol ) {
393 int subIncrementFlag = 0;
394 auto convergedStrain = oldStrain;
395 auto tempStrain = strain;
396 auto deltaStrain = strain - oldStrain;
400 stress =
mult(tangent, tempStrain - tempPlasticStrain);
405 subIncrementCounter++;
409 OOFEM_LOG_INFO(
"ConvergedStrain value %e %e %e\n", convergedStrain.at(1), convergedStrain.at(2), convergedStrain.at(3) );
410 OOFEM_LOG_INFO(
"tempStrain value %e %e %e\n", tempStrain.at(1), tempStrain.at(2), tempStrain.at(3) );
411 OOFEM_LOG_INFO(
"deltaStrain value %e %e %e\n", deltaStrain.at(1), deltaStrain.at(2), deltaStrain.at(3) );
412 OOFEM_LOG_INFO(
"targetstrain value %e %e %e\n", strain.at(1), strain.at(2), strain.at(3) );
414 OOFEM_ERROR(
"LatticePlasticityDamage :: performPlasticityReturn - Could not reach convergence with small deltaStrain, giving up.");
417 subIncrementFlag = 1;
419 tempStrain = convergedStrain + deltaStrain;
420 }
else if ( returnResult ==
RR_Converged && subIncrementFlag == 1 ) {
421 tempPlasticStrain.at(1) = tempStrain.at(1) - stress.at(1) /
eNormalMean;
422 tempPlasticStrain.at(2) = tempStrain.at(2) - stress.at(2) / ( this->
alphaOne *
eNormalMean );
423 tempPlasticStrain.at(3) = tempStrain.at(3) - stress.at(3) / ( this->
alphaOne *
eNormalMean );
425 status->letTempPlasticLatticeStrainBe(
assemble< 6 >(tempPlasticStrain, { 0, 1, 2 }) );
426 status->setTempKappaP(tempKappa);
428 subIncrementFlag = 0;
430 convergedStrain = tempStrain;
431 deltaStrain = strain - convergedStrain;
433 subIncrementCounter = 0;
435 status->setTempKappaP(tempKappa);
441 tempPlasticStrain.at(1) = strain.at(1) - stress.at(1) /
eNormalMean;
445 status->letTempPlasticLatticeStrainBe(
assemble< 6 >(tempPlasticStrain, { 0, 1, 2 }) );
470 double deltaLambda = 0.;
472 auto trialStress = stress;
473 auto tempStress = trialStress;
475 double trialShearStressNorm =
norm(trialStress [ { 1, 2 } ]);
477 double tempShearStressNorm = trialShearStressNorm;
479 double thetaTrial = atan2( stress.
at(3), stress.
at(2) );
482 double kappa = status->giveKappaP();
483 double tempKappa = kappa;
487 unknowns.
at(1) = trialStress.at(1);
488 unknowns.
at(2) = trialShearStressNorm;
489 unknowns.
at(3) = tempKappa;
497 residuals.
at(4) = yieldValue;
499 double normOfResiduals = 1.;
501 int iterationCount = 0;
502 while ( normOfResiduals >
yieldTol ) {
511 residualsNorm.
at(1) = residuals.
at(1) / fcLocal;
512 residualsNorm.
at(2) = residuals.
at(2) / fcLocal;
513 residualsNorm.
at(3) = residuals.
at(3);
514 residualsNorm.
at(4) = residuals.
at(4) / pow(fcLocal, 2.);
516 normOfResiduals =
norm(residualsNorm);
519 if ( std::isnan(normOfResiduals) ) {
526 auto jacobian =
computeJacobian(tempStress, tempKappa, deltaLambda, gp, tStep);
529 if ( solution.first ) {
530 unknowns -= solution.second;
536 unknowns.
at(2) =
max(unknowns.
at(2), 0.);
537 unknowns.
at(3) =
max(unknowns.
at(3), kappa);
538 unknowns.
at(4) =
max(unknowns.
at(4), 0.);
541 tempStress.at(1) = unknowns.
at(1);
542 tempShearStressNorm = unknowns.
at(2);
544 tempStress.at(2) = tempShearStressNorm * cos(thetaTrial);
545 tempStress.at(3) = tempShearStressNorm * sin(thetaTrial);
547 tempKappa = unknowns.
at(3);
548 deltaLambda = unknowns.
at(4);
553 residuals.
at(1) = tempStress.at(1) - trialStress.at(1) + this->
eNormalMean * deltaLambda * mVector.at(1);
554 residuals.
at(2) = tempShearStressNorm - trialShearStressNorm + this->
alphaOne * this->
eNormalMean * deltaLambda * mVector.at(2);
555 residuals.
at(3) = -tempKappa + kappa + deltaLambda * mVector.at(3);
572 const double deltaLambda,
582 jacobian.
at(1, 1) = 1. + this->
eNormalMean * deltaLambda * dMMatrix.at(1, 1);
583 jacobian.
at(1, 2) = this->
eNormalMean * deltaLambda * dMMatrix.at(1, 2);
584 jacobian.
at(1, 3) = this->
eNormalMean * deltaLambda * dMMatrix.at(1, 3);
592 jacobian.
at(3, 1) = deltaLambda * dMMatrix.at(3, 1);
593 jacobian.
at(3, 2) = deltaLambda * dMMatrix.at(3, 2);
594 jacobian.
at(3, 3) = deltaLambda * dMMatrix.at(3, 3) - 1.;
595 jacobian.
at(3, 4) = mVector.at(3);
597 jacobian.
at(4, 1) = fVector.at(1);
598 jacobian.
at(4, 2) = fVector.at(2);
599 jacobian.
at(4, 3) = fVector.at(3);
600 jacobian.
at(4, 4) = 0.;
629 auto reducedStrain = originalStrain;
631 if ( thermalStrain.giveSize() ) {
640 omega = status->giveTempDamage();
643 stress *= ( 1. - omega );
645 status->letTempLatticeStrainBe(originalStrain);
646 status->letTempReducedLatticeStrainBe(reducedStrain);
647 status->letTempLatticeStressBe(stress);
663 auto tempPlasticStrain = status->giveTempPlasticLatticeStrain();
664 auto plasticStrain = status->givePlasticLatticeStrain();
665 auto deltaPlasticStrain = tempPlasticStrain - plasticStrain;
668 double omega = status->giveDamage();
669 double tempKappaDOne = status->giveKappaDOne();
670 double tempKappaDTwo = status->giveKappaDTwo();
673 double tempKappaP = status->giveTempKappaP();
674 double kappaP = status->giveKappaP();
675 double deltaKappaP = tempKappaP - kappaP;
680 if ( deltaKappaP <= 0. ) {
681 tempKappaDOne = status->giveKappaDOne();
682 tempKappaDTwo = status->giveKappaDTwo();
683 omega = status->giveDamage();
684 if ( status->giveCrackFlag() != 0 ) {
685 status->setTempCrackFlag(2);
687 status->setTempCrackFlag(0);
690 if ( deltaPlasticStrain.at(1) <= 0. ) {
691 tempKappaDOne = status->giveKappaDOne();
692 tempKappaDTwo = status->giveKappaDTwo();
693 omega = status->giveDamage();
694 status->setTempCrackFlag(3);
696 tempKappaDOne += deltaPlasticStrain.at(1);
698 if ( ftLocal == 0 ) {
699 tempKappaDTwo = hardening * strength / this->
eNormalMean;
701 tempKappaDTwo = hardening * ftLocal / this->
eNormalMean;
708 if ( ( tempKappaDOne + omega * tempKappaDTwo ) * le > 0. ) {
709 status->setTempCrackFlag(1);
711 status->setTempCrackFlag(0);
719 status->letTempDamageLatticeStrainBe(tempDamageLatticeStrain);
721 double crackWidth =
norm( tempPlasticStrain + omega * ( reducedStrain - tempPlasticStrain ) ) * le;
729 status->setTempKappaDOne(tempKappaDOne);
730 status->setTempKappaDTwo(tempKappaDTwo);
731 status->setTempDamage(omega);
732 status->setTempCrackWidth(crackWidth);
851 if ( mode == ElasticStiffness ) {
853 }
else if ( ( mode == SecantStiffness ) || ( mode == TangentStiffness ) ) {
855 double omega =
min(status->giveTempDamage(), 0.99999);
856 return elastic * ( 1. - omega );
870 if ( type == IST_DamageTensor ) {
873 answer.
at(1) = answer.
at(2) = answer.
at(3) = status->giveDamage();
875 }
else if ( type == IST_DamageScalar ) {
878 answer.
at(1) = status->giveDamage();
880 }
else if ( type == IST_CrackedFlag ) {
883 answer.
at(1) = status->giveCrackFlag();
885 }
else if ( type == IST_DissWork ) {
888 answer.
at(1) = status->giveDissipation();
890 }
else if ( type == IST_DeltaDissWork ) {
893 answer.
at(1) = status->giveDeltaDissipation();
895 }
else if ( type == IST_CrackWidth ) {
898 answer.
at(1) = status->giveCrackWidth();
900 }
else if ( type == IST_CharacteristicLength ) {
905 }
else if ( type == IST_PlasticLatticeStrain ) {
906 answer = status->givePlasticLatticeStrain();
908 }
else if ( type == IST_TensileStrength ) {
937 fprintf(file,
"plasticStrains ");
939 fprintf(file,
"% .8e ", s);
942 fprintf(file,
", kappaP %.8e, kappaDOne %.8e, kappaDTwo %.8e, damage %.8e, deltaDissipation %.8e, dissipation %.8e, crackFlag %d, crackWidth %.8e \n", this->
kappaP, this->
kappaDOne, this->
kappaDTwo, this->
damage, this->
deltaDissipation, this->
dissipation, this->
crackFlag, this->
crackWidth);
#define REGISTER_Material(class)
virtual int read(int *data, std::size_t count)=0
Reads count integer values into array pointed by data.
virtual int write(const int *data, std::size_t count)=0
Writes count integer values from array pointed by data.
int giveGlobalNumber() const
Domain * domain
Link to domain object, useful for communicating with other FEM components.
double & at(std::size_t i)
void zero()
Zeroes all coefficients of receiver.
double at(std::size_t i, std::size_t j) const
Element * giveElement()
Returns corresponding element to receiver.
LatticeLinearElastic(int n, Domain *d)
double alphaOne
Ratio of shear and normal modulus.
double alphaTwo
Ratio of torsion and normal modulus.
void initializeFrom(InputRecord &ir) override
double eNormalMean
Normal modulus.
double give(int aProperty, GaussPoint *gp) const override
MaterialStatus * giveStatus(GaussPoint *gp) const override
FloatMatrixF< 6, 6 > give3dLatticeStiffnessMatrix(MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) const override
void saveContext(DataStream &stream, ContextMode mode) override
FloatArrayF< 6 > plasticLatticeStrain
Equilibriated plastic lattice strain.
const FloatArrayF< 6 > & giveReducedLatticeStrain() const
Returns reduced lattice strain.
LatticeMaterialStatus(GaussPoint *g)
double crackWidth
Crack width.
void initTempStatus() override
double deltaDissipation
Increment of dissipation.
void updateYourself(TimeStep *) override
double dissipation
dissipation
void restoreContext(DataStream &stream, ContextMode mode) override
void printOutputAt(FILE *file, TimeStep *tStep) const override
Print receiver's output to given stream.
void updateYourself(TimeStep *) override
LatticePlasticityDamageStatus(int n, Domain *d, GaussPoint *g)
Constructor.
void initTempStatus() override
void printOutputAt(FILE *file, TimeStep *tStep) const override
Print receiver's output to given stream.
double giveKappaP() const
void restoreContext(DataStream &stream, ContextMode mode) override
void saveContext(DataStream &stream, ContextMode mode) override
double fc
compressive strength
FloatArrayF< 6 > giveLatticeStress3d(const FloatArrayF< 6 > &jump, GaussPoint *gp, TimeStep *tStep) override
double performRegularReturn(FloatArrayF< 3 > &stress, LatticePlasticityDamage_ReturnResult &returnResult, double yieldValue, GaussPoint *gp, TimeStep *tStep) const
double flowAngleTwo
frictional angle of the plastic potential
double computeDDHardeningDDKappa(const double kappa, GaussPoint *gp) const
double computeDHardeningDKappa(const double kappa, GaussPoint *gp) const
int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *atTime) override
LatticePlasticityDamage_ReturnResult
double ftOneRatio
ratio of tensile stress value for bilinear stress-crack opening curve
std::unique_ptr< MaterialStatus > CreateStatus(GaussPoint *gp) const override
bool hasMaterialModeCapability(MaterialMode mode) const override
double flowAngleOne
frictional angle of the plastic potential
double yieldTol
yield tolerance
virtual double giveTensileStrength(GaussPoint *gp, TimeStep *tStep) const
double computeHardening(const double kappa, GaussPoint *gp) const
FloatMatrixF< 4, 4 > computeJacobian(const FloatArrayF< 3 > &sigma, const double tempKappa, const double deltaLambda, GaussPoint *gp, TimeStep *tStep) const
double ft
tensile strength
virtual double giveCompressiveStrength(GaussPoint *gp, TimeStep *tStep) const
virtual double computeDamageParam(double kappaOne, double kappaTwo, GaussPoint *gp, TimeStep *tStep) const
int softeningType
softening type determines the type of softening. 0 is exponential and 1 is bilinear.
double give(int aProperty, GaussPoint *gp) const override
FloatMatrixF< 3, 3 > computeDMMatrix(const FloatArrayF< 3 > &sigma, const double deltaLambda, GaussPoint *gp, TimeStep *tStep) const
virtual FloatArrayF< 6 > giveReducedStrain(GaussPoint *gp, TimeStep *tStep) const
double frictionAngleTwo
frictional angle of the yield surface
FloatArrayF< 3 > computeMVector(const FloatArrayF< 3 > &sigma, const double deltaLambda, GaussPoint *gp, TimeStep *tStep) const
double aHard
hardening parameter
int numberOfSubIncrements
double frictionAngleOne
frictional angle of the yield surface
FloatMatrixF< 6, 6 > give3dLatticeStiffnessMatrix(MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) const override
double computeYieldValue(const FloatArrayF< 3 > &sigma, const double tempKappa, GaussPoint *gp, TimeStep *tStep) const
FloatArrayF< 6 > performPlasticityReturn(GaussPoint *gp, const FloatArrayF< 6 > &reducedStrain, TimeStep *tStep) const
double wf
determines the softening -> corresponds to crack opening (not strain) when tension stress vanishes
FloatArrayF< 3 > computeFVector(const FloatArrayF< 3 > &sigma, const double deltaLambda, GaussPoint *gp, TimeStep *tStep) const
double wfOne
crack opening value for bilinear stress-crack opening curve
int newtonIter
maximum number of iterations for stress return
LatticePlasticityDamage(int n, Domain *d)
Constructor.
void initializeFrom(InputRecord &ir) override
void performDamageEvaluation(GaussPoint *gp, FloatArrayF< 6 > &reducedStrain, TimeStep *tStep) const
virtual double giveLength()
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
bool give(int key, GaussPoint *gp, double &value) const
virtual FloatArray computeStressIndependentStrainVector(GaussPoint *gp, TimeStep *tStep, ValueModeType mode) const
#define OOFEM_WARNING(...)
#define _IFT_LatticePlasticityDamage_angle2
#define _IFT_LatticePlasticityDamage_sub
#define _IFT_LatticePlasticityDamage_tol
#define _IFT_LatticePlasticityDamage_ahard
#define _IFT_LatticePlasticityDamage_wf1
#define _IFT_LatticePlasticityDamage_iter
#define _IFT_LatticePlasticityDamage_ft1
#define _IFT_LatticePlasticityDamage_stype
#define _IFT_LatticePlasticityDamage_damage
#define _IFT_LatticePlasticityDamage_flow
#define _IFT_LatticePlasticityDamage_fc
#define _IFT_LatticePlasticityDamage_angle1
#define _IFT_LatticePlasticityDamage_wf
#define _IFT_LatticePlasticityDamage_ft
#define OOFEM_LOG_INFO(...)
double norm(const FloatArray &x)
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
std::pair< bool, FloatArrayF< N > > solve_check(FloatMatrixF< N, N > mtrx, const FloatArrayF< N > &b, double zeropiv=1e-20)
FloatArrayF< N > assemble(const FloatArrayF< M > &x, int const (&c)[M])
Assemble components into zero matrix.
FloatArrayF< N > max(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
FloatArrayF< N > mult(const FloatArrayF< N > &x, const FloatArrayF< N > &y)
Element-wise multiplication.
@ CIO_IOERR
General IO error.