58LatticeDamage :: hasMaterialModeCapability(MaterialMode mode)
const
60 return ( mode == _3dLattice );
67 LatticeLinearElastic :: initializeFrom(ir);
101 double paramA = 0.5 * ( e0 +
ec * e0 );
102 double paramB = (
coh * e0 ) / sqrt(1. - pow( (
ec * e0 - e0 ) / ( e0 +
ec * e0 ), 2. ) );
103 double paramC = 0.5 * ( this->
ec * e0 - e0 );
105 double shearNorm =
norm(strain [ { 1, 2 } ]);
106 return norm({ this->
alphaOne * shearNorm / paramB, ( strain.
at(1) + paramC ) / paramA }) * paramA - paramC;
111LatticeDamage :: computeDamageParam(
double tempKappa,
GaussPoint *gp)
const
118 if ( tempKappa >= e0 && tempKappa < this->
wf / le ) {
121 if ( this->
wf / le <= e0 ) {
122 OOFEM_ERROR(
"e0>wf/Le \n Possible solutions: Increase fracture energy or reduce element size\n");
125 return ( 1. - e0 / tempKappa ) / ( 1. - e0 / ( this->
wf / le ) );
126 }
else if ( tempKappa >= this->
wf / le ) {
133 if ( e0 >
wfOne / le ) {
135 }
else if (
wfOne / le > this->
wf / le ) {
139 if ( tempKappa > e0 ) {
140 double helpStrain = 0.3 * e0;
141 double omega = ( 1 - e0 / tempKappa ) / ( ( helpStrain - e0 ) / this->
wfOne * le + 1. );
143 if ( omega * tempKappa * le > 0 && omega * tempKappa * le < this->
wfOne ) {
146 omega = ( 1. - helpStrain / tempKappa - helpStrain * this->wfOne / ( tempKappa * ( this->
wf - this->wfOne ) ) ) / ( 1. - helpStrain * le / ( this->
wf - this->wfOne ) );
148 if ( omega * tempKappa * le >= this->wfOne && omega * tempKappa * le < this->
wf ) {
153 return clamp(omega, 0., 1.);
162 if ( tempKappa <= e0 ) {
166 double R = 0., omega = 0.;
167 double Ft = eNormal * e0;
170 double help = le * omega * tempKappa / this->
wf;
171 double Lhs = eNormal * tempKappa - Ft * exp(-help) * le * tempKappa / this->
wf;
172 R = ( 1. - omega ) * eNormal * tempKappa - Ft * exp(-help);
175 OOFEM_ERROR(
"computeDamageParam: algorithm not converging");
177 }
while ( fabs(R) >= 1.e-4 );
179 if ( ( omega > 1.0 ) || ( omega < 0.0 ) ) {
180 OOFEM_ERROR(
"computeDamageParam: internal error\n");
185 OOFEM_ERROR(
"computeDamageParam: unknown softening type");
190std::unique_ptr<MaterialStatus>
193 return std::make_unique<LatticeDamageStatus>(gp);
198LatticeDamage :: give3dLatticeStiffnessMatrix(MatResponseMode mode,
GaussPoint *gp,
TimeStep *tStep)
const
200 auto elastic = LatticeLinearElastic :: give3dLatticeStiffnessMatrix(mode, gp, tStep);
202 if ( mode == ElasticStiffness ) {
204 }
else if ( ( mode == SecantStiffness ) || ( mode == TangentStiffness ) ) {
207 double omega =
min(status->giveTempDamage(), 0.99999);
208 return elastic * ( 1. - omega );
216LatticeDamage :: give2dLatticeStiffnessMatrix(MatResponseMode mode,
GaussPoint *gp,
TimeStep *tStep)
const
219 auto elastic = LatticeLinearElastic :: give2dLatticeStiffnessMatrix(mode, gp, tStep);
221 if ( mode == ElasticStiffness ) {
223 }
else if ( ( mode == SecantStiffness ) || ( mode == TangentStiffness ) ) {
227 if ( omega > 0.99999 ) {
231 return elastic * ( 1. - omega );
249 auto reducedStrain = strain;
251 if ( thermalStrain.giveSize() ) {
257 omega = status->giveTempDamage();
259 auto stiffnessMatrix = LatticeLinearElastic :: give3dLatticeStiffnessMatrix(ElasticStiffness, gp, tStep);
262 for (
int i = 1; i <= 6; i++ ) {
263 answer.
at(i) = stiffnessMatrix.at(i, i) * reducedStrain.at(i) * ( 1. - omega );
268 if ( !
domain->giveEngngModel()->giveMasterEngngModel() ) {
272 double waterPressure = 0.;
273 for (
int i = 0; i < pressures.
giveSize(); i++ ) {
274 waterPressure += 1. / pressures.
giveSize() * pressures [ i ];
276 answer.
at(1) += waterPressure;
279 double tempDissipation = status->giveDissipation() + tempDeltaDissipation;
282 status->setTempDissipation(tempDissipation);
283 status->setTempDeltaDissipation(tempDeltaDissipation);
285 status->letTempLatticeStrainBe(strain);
286 status->letTempReducedLatticeStrainBe(reducedStrain);
287 status->letTempLatticeStressBe(answer);
288 status->setTempNormalLatticeStress(answer.
at(1) );
302 double f = equivStrain - status->giveKappa();
304 double tempKappa, omega = 0.;
307 tempKappa = status->giveKappa();
308 omega = status->giveDamage();
309 if ( status->giveCrackFlag() != 0 ) {
310 status->setTempCrackFlag(2);
312 status->setTempCrackFlag(0);
316 tempKappa = equivStrain;
322 status->setTempCrackFlag(1);
328 status->letTempDamageLatticeStrainBe(tempDamageLatticeStrain);
332 double crackWidth = omega *
norm(reducedStrain [ { 0, 1, 2 } ]) *
length;
334 status->setTempEquivalentStrain(equivStrain);
335 status->setTempKappa(tempKappa);
336 status->setTempDamage(omega);
337 status->setTempCrackWidth(crackWidth);
341LatticeDamage :: computeBiot(
double omega,
double kappa,
double le)
const
346 }
else if ( omega * kappa * le > 0 && omega * kappa * le < this->
wf ) {
352 OOFEM_ERROR(
"Wrong stype for btype=1. Only linear and exponential softening considered so far\n");
363 return e0 * eNormal * this->
wf / 2.;
365 return e0 * eNormal * this->
wf;
371LatticeDamage :: computeIntervals(
double testDissipation,
double referenceGf)
const
373 if ( testDissipation / ( referenceGf ) > 0.01 ) {
374 return 1000. *
min(testDissipation / referenceGf, 1.);
382LatticeDamage :: computeDeltaDissipation2d(
double omega,
390 const double eShear = this->
alphaOne * eNormal;
391 const double eTorsion = this->
alphaTwo * eNormal;
394 const auto reducedStrainOld = status->giveReducedLatticeStrain() [ { 0, 1, 5 } ];
395 const double omegaOld = status->giveDamage();
397 auto oldIntermediateStrain = reducedStrainOld;
398 double oldIntermediateOmega = omegaOld;
399 double deltaOmega = ( omega - omegaOld );
400 auto testStrain = ( reducedStrain + reducedStrainOld ) * 0.5;
401 auto testStress =
mult(tangent, testStrain);
402 double testDissipation = 0.5 *
length *
norm(testStress) * deltaOmega;
407 double oldKappa = status->giveKappa();
408 if ( deltaOmega > 0 ) {
409 double tempDeltaDissipation = 0.;
410 for (
int k = 0; k < intervals; k++ ) {
411 auto intermediateStrain = reducedStrainOld + ( k + 1 ) / intervals * ( reducedStrain - reducedStrainOld );
413 double f = equivStrain - oldKappa;
416 auto deltaOmega = ( intermediateOmega - oldIntermediateOmega );
417 auto midStrain = ( intermediateStrain + oldIntermediateStrain ) / 2.;
418 auto midStress =
mult(tangent, midStrain);
419 auto deltaTempDeltaDissipation = 0.5 *
length *
norm(midStress) * deltaOmega;
420 oldKappa = equivStrain;
421 oldIntermediateOmega = intermediateOmega;
422 tempDeltaDissipation += deltaTempDeltaDissipation;
425 oldIntermediateStrain = intermediateStrain;
427 return max(tempDeltaDissipation, 2. * referenceGf);
435LatticeDamage :: computeDeltaDissipation3d(
double omega,
443 const double eShear = this->
alphaOne * eNormal;
444 const double eTorsion = this->
alphaTwo * eNormal;
445 const FloatArrayF< 6 >tangent = { eNormal, eShear, eShear, eTorsion, eTorsion, eTorsion };
447 const auto &reducedStrainOld = status->giveReducedLatticeStrain();
448 const double omegaOld = status->giveDamage();
450 auto oldIntermediateStrain = reducedStrainOld;
451 double oldIntermediateOmega = omegaOld;
452 double deltaOmega = ( omega - omegaOld );
453 auto testStrain = ( reducedStrain + reducedStrainOld ) * 0.5;
454 auto testStress =
mult(tangent, testStrain);
455 double testDissipation = 0.5 *
length *
norm(testStress) * deltaOmega;
460 double oldKappa = status->giveKappa();
461 if ( deltaOmega > 0 ) {
462 double tempDeltaDissipation = 0.;
463 for (
int k = 0; k < intervals; k++ ) {
464 auto intermediateStrain = reducedStrainOld + ( k + 1 ) / intervals * ( reducedStrain - reducedStrainOld );
466 double f = equivStrain - oldKappa;
469 auto deltaOmega = ( intermediateOmega - oldIntermediateOmega );
470 auto midStrain = ( intermediateStrain + oldIntermediateStrain ) / 2.;
471 auto midStress =
mult(tangent, midStrain);
472 auto deltaTempDeltaDissipation = 0.5 *
length *
norm(midStress) * deltaOmega;
473 oldKappa = equivStrain;
474 oldIntermediateOmega = intermediateOmega;
475 tempDeltaDissipation += deltaTempDeltaDissipation;
478 oldIntermediateStrain = intermediateStrain;
480 return max(tempDeltaDissipation, 2. * referenceGf);
493 if ( RandomMaterialExtensionInterface :: give(aProperty, gp, answer) ) {
494 if ( answer < 0.1 ) {
496 }
else if ( answer > 10 ) {
500 }
else if ( aProperty ==
e0_ID ) {
502 }
else if ( aProperty ==
ef_ID ) {
505 return LatticeLinearElastic :: give(aProperty, gp);
516 if ( type == IST_CrackedFlag ) {
521 }
else if ( type == IST_DamageScalar ) {
526 }
else if ( type == IST_DamageTensor ) {
531 }
else if ( type == IST_DissWork ) {
536 }
else if ( type == IST_DeltaDissWork ) {
541 }
else if ( type == IST_CrackWidth ) {
546 }
else if ( type == IST_NormalStress ) {
551 }
else if ( type == IST_CharacteristicLength ) {
557 return LatticeLinearElastic :: giveIPValue(answer, gp, type, atTime);
566LatticeDamageStatus :: initTempStatus()
568 LatticeMaterialStatus :: initTempStatus();
576LatticeDamageStatus :: printOutputAt(FILE *file,
TimeStep *tStep)
const
578 LatticeMaterialStatus :: printOutputAt(file, tStep);
579 fprintf(file,
"kappa %f, equivStrain %f, damage %f, dissipation %f, deltaDissipation %f, e0 %f, crackFlag %d\n", this->
kappa, this->
equivStrain, this->
damage, this->
dissipation, this->
deltaDissipation, this->
e0, this->
crackFlag);
584LatticeDamageStatus :: updateYourself(
TimeStep *atTime)
591 LatticeMaterialStatus :: updateYourself(atTime);
605 LatticeMaterialStatus :: saveContext(stream, mode);
634 LatticeMaterialStatus :: restoreContext(stream, mode);
double length(const Vector &a)
#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.
Domain * domain
Link to domain object, useful for communicating with other FEM components.
double & at(std::size_t i)
Index giveSize() const
Returns the size of receiver.
void zero()
Zeroes all coefficients of receiver.
Element * giveElement()
Returns corresponding element to receiver.
double equivStrain
scalar measure of the largest strain level ever reached in material
double giveDamage() const
Returns the last equilibrated damage level.
double giveTempDamage() const
Returns the temp. damage level.
double tempDamage
non-equilibrated damage level of material
double tempEquivStrain
non-equilibrated scalar measure of the largest strain level
double kappa
scalar measure of the largest strain level ever reached in material
double tempKappa
non-equilibrated scalar measure of the largest strain level
double e0
random material parameter stored in status, since each gp has a differnet value.
double biot
computed biot coefficient
double damage
damage level of material
int biotType
Parameter specifying how the biot coefficient changes with the crack opening.
double biotCoefficient
Biot's coefficient.
double computeDeltaDissipation3d(double omega, const FloatArrayF< 6 > &reducedStrain, GaussPoint *gp, TimeStep *atTime) const
virtual double computeEquivalentStrain(const FloatArrayF< 6 > &strain, GaussPoint *gp) const
double computeIntervals(double testDissipation, double referenceGf) const
virtual double computeDamageParam(double kappa, GaussPoint *gp) const
double computeReferenceGf(GaussPoint *gp) const
double give(int aProperty, GaussPoint *gp) const override
double e0Mean
max effective strain at peak
double wf
determines the softening -> corresponds to crack opening when tension stress vanishes
void performDamageEvaluation(GaussPoint *gp, FloatArrayF< 6 > &reducedStrain) const
LatticeLinearElastic(int n, Domain *d)
double alphaOne
Ratio of shear and normal modulus.
double alphaTwo
Ratio of torsion and normal modulus.
double eNormalMean
Normal modulus.
MaterialStatus * giveStatus(GaussPoint *gp) const override
LatticeMaterialStatus(GaussPoint *g)
virtual double giveCrackWidth() const
double deltaDissipation
Increment of dissipation.
virtual int giveCrackFlag() const
virtual double giveDissipation() const
double dissipation
dissipation
virtual double giveDeltaDissipation() const
double giveNormalLatticeStress() const
Gives the last equilibrated normal stress.
virtual void givePressures(FloatArray &pressures)
virtual double giveLength()
virtual void initTempStatus(GaussPoint *gp) const
virtual FloatArray computeStressIndependentStrainVector(GaussPoint *gp, TimeStep *tStep, ValueModeType mode) const
#define _IFT_LatticeDamage_bio
#define _IFT_LatticeDamage_e0Mean
#define _IFT_LatticeDamage_softeningType
#define _IFT_LatticeDamage_e0OneMean
#define _IFT_LatticeDamage_ec
#define _IFT_LatticeDamage_wfOne
#define _IFT_LatticeDamage_coh
#define _IFT_LatticeDamage_wf
#define _IFT_LatticeDamage_btype
double norm(const FloatArray &x)
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
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.
double clamp(int a, int lower, int upper)
Returns the clamped value of a between upper and lower.