OOFEM 3.0
Loading...
Searching...
No Matches
mpsdammat.C
Go to the documentation of this file.
1/*
2 *
3 * ##### ##### ###### ###### ### ###
4 * ## ## ## ## ## ## ## ### ##
5 * ## ## ## ## #### #### ## # ##
6 * ## ## ## ## ## ## ## ##
7 * ## ## ## ## ## ## ## ##
8 * ##### ##### ## ###### ## ##
9 *
10 *
11 * OOFEM : Object Oriented Finite Element Code
12 *
13 * Copyright (C) 1993 - 2025 Borek Patzak
14 *
15 *
16 *
17 * Czech Technical University, Faculty of Civil Engineering,
18 * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19 *
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 */
34
35#include "mpsdammat.h"
36#include "mathfem.h"
37#include "gausspoint.h"
38#include "timestep.h"
39#include "stressvector.h"
40#include "engngm.h"
41#include "contextioerr.h"
42#include "datastream.h"
43#include "classfactory.h"
44
45namespace oofem {
47
48/***************************************************************/
49/************** MPSDamMaterialStatus *******************/
50/***************************************************************/
51
52
53
54MPSDamMaterialStatus :: MPSDamMaterialStatus(GaussPoint *g, int nunits) :
55 MPSMaterialStatus(g, nunits),
57{
58 int rsize = StructuralMaterial :: giveSizeOfVoigtSymVector( g->giveMaterialMode() );
59 effectiveStressVector.resize(rsize);
61}
62
63
64void
65MPSDamMaterialStatus :: initTempStatus()
66{
67 MPSMaterialStatus :: initTempStatus();
68
69 this->tempKappa = this->kappa;
70 this->tempDamage = this->damage;
71
73
74 if ( !damage ) {
75 var_e0 = var_gf = 0.;
76 }
77}
78
79
80void
81MPSDamMaterialStatus :: updateYourself(TimeStep *tStep)
82{
83 MPSMaterialStatus :: updateYourself(tStep);
84
85 this->kappa = this->tempKappa;
86 this->damage = this->tempDamage;
87
89
90 if ( !damage ) {
91 var_e0 = var_gf = 0.;
92 }
93}
94
95
96void
97MPSDamMaterialStatus :: giveCrackVector(FloatArray &answer) const
98{
100}
101
102
103void
104MPSDamMaterialStatus :: printOutputAt(FILE *file, TimeStep *tStep) const
105{
106 MPSMaterialStatus :: printOutputAt(file, tStep);
107
108 fprintf(file, "damage status { ");
109 if ( this->kappa > 0 && this->damage <= 0 ) {
110 fprintf(file, "kappa %f", this->kappa);
111 } else if ( this->damage > 0.0 ) {
112 fprintf( file, "kappa %f, damage %f crackVector %f %f %f", this->kappa, this->damage, this->crackVector.at(1), this->crackVector.at(2), this->crackVector.at(3) );
113 }
114 fprintf(file, "}\n");
115}
116
117
118void
119MPSDamMaterialStatus :: saveContext(DataStream &stream, ContextMode mode)
120{
121 MPSMaterialStatus :: saveContext(stream, mode);
122
123 if ( !stream.write(kappa) ) {
125 }
126
127 if ( !stream.write(damage) ) {
129 }
130
131 if ( !stream.write(charLength) ) {
133 }
134
136 if ( ( iores = crackVector.storeYourself(stream) ) != CIO_OK ) {
137 THROW_CIOERR(iores);
138 }
139
140 if ( !stream.write(var_e0) ) {
142 }
143
144 if ( !stream.write(var_gf) ) {
146 }
147
148 if ( ( iores = effectiveStressVector.storeYourself(stream) ) != CIO_OK ) {
149 THROW_CIOERR(iores);
150 }
151}
152
153void
154MPSDamMaterialStatus :: restoreContext(DataStream &stream, ContextMode mode)
155{
156 MPSMaterialStatus :: restoreContext(stream, mode);
157
158 if ( !stream.read(kappa) ) {
160 }
161
162 if ( !stream.read(damage) ) {
164 }
165
166 if ( !stream.read(charLength) ) {
168 }
169
171 if ( ( iores = crackVector.restoreYourself(stream) ) != CIO_OK ) {
172 THROW_CIOERR(iores);
173 }
174
175 if ( !stream.read(var_e0) ) {
177 }
178
179 if ( !stream.read(var_gf) ) {
181 }
182
183 if ( ( iores = effectiveStressVector.restoreYourself(stream) ) != CIO_OK ) {
184 THROW_CIOERR(iores);
185 }
186}
187
188// ***********************************************************************************
189// *** CLASS Damage extension of MPS model for creep and shrinakge of concrete ***
190// ***********************************************************************************
191
192
193MPSDamMaterial :: MPSDamMaterial(int n, Domain *d) : MPSMaterial(n, d)
194{}
195
196
197bool
198MPSDamMaterial :: hasMaterialModeCapability(MaterialMode mode) const
199{
200 return mode == _3dMat || mode == _PlaneStress || mode == _PlaneStrain || mode == _1dMat;
201}
202
203
204void
205MPSDamMaterial :: initializeFrom(InputRecord &ir)
206{
207 MPSMaterial :: initializeFrom(ir);
208
209 this->isotropic = false;
211 this->isotropic = true;
212 }
213
214 int damageLaw = 0;
216
217 this->timeDepFracturing = false;
218
220 this->timeDepFracturing = true;
221 //
223 // the same compressive strength as for the prediction using the B3 formulas
224
225 this->gf28 = 0.;
226 this->ft28 = 0.;
227
229
231 if (gf28 < 0.) {
232 OOFEM_ERROR("Fracture energy at 28 days must be positive");
233 }
235
236 if (ft28 < 0.) {
237 OOFEM_ERROR("Tensile strength at 28 days must be positive");
238 }
239
240 } else {
244 }
245
246 } else {
247
248 //applies only in this class
249 switch ( damageLaw ) {
250
251 case 0: // exponential softening - default
255 break;
256
257 case 1: // linear softening law
261 break;
262
263 case 6:
265 break;
266
267 default:
268 OOFEM_ERROR("Softening type number %d is unknown", damageLaw);
269 }
270 }
271
273}
274
275
276void
277MPSDamMaterial :: giveRealStressVector(FloatArray &answer, GaussPoint *gp, const FloatArray &totalStrain, TimeStep *tStep) const
278{
279 if ( this->E < 0. ) { // initialize dummy elastic modulus E
280 this->E = 1. / MPSMaterial :: computeCreepFunction(28.01*this->lambda0, 28.*this->lambda0, gp, tStep);
281 }
282
283 MPSDamMaterialStatus *status = static_cast< MPSDamMaterialStatus * >( this->giveStatus(gp) );
284
285 MaterialMode mode = gp->giveMaterialMode();
286
287 FloatArray principalStress;
288 FloatMatrix principalDir;
289
290 StressVector tempEffectiveStress(mode);
291 StressVector tempNominalStress(mode);
292
293 double f, sigma1, kappa, tempKappa = 0.0, omega = 0.0;
294
295 // effective stress computed by the viscoelastic MPS material
296 MPSMaterial :: giveRealStressVector(tempEffectiveStress, gp, totalStrain, tStep);
297
298 if ( !this->isActivated(tStep) ) {
299 FloatArray help;
300 help.resize( StructuralMaterial :: giveSizeOfVoigtSymVector( gp->giveMaterialMode() ) );
301 help.zero();
302
303 status->letTempStrainVectorBe(help);
304 status->letTempStressVectorBe(help);
306
307#ifdef supplementary_info
308 status->setResidualTensileStrength(0.);
309 status->setCrackWidth(0.);
310 status->setTempKappa(0.);
311 status->setTempDamage(0.);
312#endif
313
314 answer = tempEffectiveStress;
315 return;
316 }
317
318 tempEffectiveStress.computePrincipalValDir(principalStress, principalDir);
319
320 sigma1 = 0.;
321 if ( principalStress.at(1) > 0.0 ) {
322 sigma1 = principalStress.at(1);
323 }
324
325 kappa = sigma1 / this->E;
326
327 f = kappa - status->giveKappa();
328
329 if ( f <= 0.0 ) { // damage does not grow
330 tempKappa = status->giveKappa();
331 omega = status->giveDamage();
332
333#ifdef supplementary_info
334 double residualStrength = 0.;
335 double e0;
336
337 if ( ( this->timeDepFracturing ) && ( this->givee0(gp) == 0. ) ) {
338 this->initDamagedFib(gp, tStep);
339 }
340
341 e0 = this->givee0(gp);
342
343 if ( omega == 0. ) {
344 residualStrength = E * e0; // undamaged material
345 } else {
346 double gf, ef, wf = 0., Le;
347 gf = this->givegf(gp);
348 Le = status->giveCharLength();
349
350 if ( softType == ST_Exponential_Cohesive_Crack ) { // exponential softening
351 wf = gf / this->E / e0; // wf is the crack opening
352 } else if ( softType == ST_Linear_Cohesive_Crack ) { // linear softening law
353 wf = 2. * gf / this->E / e0; // wf is the crack opening
354 } else {
355 OOFEM_ERROR("Gf unsupported for softening type softType = %d", softType);
356 }
357
358 ef = wf / Le; //ef is the fracturing strain
359
360 if ( this->softType == ST_Linear_Cohesive_Crack ) {
361 residualStrength = E * e0 * ( ef - tempKappa ) / ( ef - e0 );
362 } else if ( this->softType == ST_Exponential_Cohesive_Crack ) {
363 residualStrength = E * e0 * exp(-1. * ( tempKappa - e0 ) / ef);
364 } else {
365 OOFEM_ERROR("Unknown softening type for cohesive crack model.");
366 }
367 }
368
369 if ( status ) {
370 status->setResidualTensileStrength(residualStrength);
371 }
372
373#endif
374 } else {
375 // damage grows
376 tempKappa = kappa;
377
378 FloatArray crackPlaneNormal(3);
379 for ( int i = 1; i <= principalStress.giveSize(); i++ ) {
380 crackPlaneNormal.at(i) = principalDir.at(i, 1);
381 }
382 this->initDamaged(tempKappa, crackPlaneNormal, gp, tStep);
383 omega = this->computeDamage(tempKappa, gp);
384 }
385
386 answer.zero();
387
388 if ( omega > 0. ) {
389 tempNominalStress = tempEffectiveStress;
390
391 if ( this->isotropic ) {
392 // convert effective stress to nominal stress
393 tempNominalStress.times(1. - omega);
394 answer.add(tempNominalStress);
395 } else {
396 // stress transformation matrix
397 FloatMatrix Tstress;
398
399 // compute principal nominal stresses by multiplying effective stresses by damage
400 for ( int i = 1; i <= principalStress.giveSize(); i++ ) {
401 if ( principalStress.at(i) > 0. ) {
402 // convert principal effective stress to nominal stress
403 principalStress.at(i) *= ( 1. - omega );
404 }
405 }
406
407 if ( mode == _PlaneStress ) {
408 principalStress.resizeWithValues(3);
409 Tstress = givePlaneStressVectorTranformationMtrx(principalDir, true);
410 } else {
411 principalStress.resizeWithValues(6);
412 Tstress = giveStressVectorTranformationMtrx(principalDir, true);
413 }
414
415 principalStress.rotatedWith(Tstress, 'n');
416
417
418 if ( mode == _PlaneStress ) { // plane stress
419 answer.add(principalStress);
420 } else if ( this->giveSizeOfVoigtSymVector(mode) != this->giveSizeOfVoigtSymVector(_3dMat) ) { // mode = _PlaneStrain or axial symmetry
421 StressVector redFormStress(mode);
422 redFormStress.convertFromFullForm(principalStress, mode);
423 answer.add(redFormStress);
424 } else { // 3D
425 answer.add(principalStress);
426 }
427 }
428 } else {
429 answer.add(tempEffectiveStress);
430 }
431
432#ifdef supplementary_info
433
434 if ( ( omega == 0. ) || ( sigma1 <= 0 ) ) {
435 status->setCrackWidth(0.);
436 } else {
437 FloatArray principalStrains;
438 this->computePrincipalValues(principalStrains, totalStrain, principal_strain);
439
440 double crackWidth;
441 //case when the strain localizes into narrow band and after a while the stresses relax
442
443 double strainWithoutTemperShrink = principalStrains.at(1);
444 strainWithoutTemperShrink -= status->giveTempThermalStrain();
445 strainWithoutTemperShrink -= status->giveTempDryingShrinkageStrain();
446 strainWithoutTemperShrink -= status->giveTempAutogenousShrinkageStrain();
447
448
449 crackWidth = status->giveCharLength() * omega * strainWithoutTemperShrink;
450
451 status->setCrackWidth(crackWidth);
452 }
453
454#endif
455
456 // update gp
457 status->letTempStrainVectorBe(totalStrain);
458 status->letTempStressVectorBe(answer);
459 status->letTempViscoelasticStressVectorBe(tempEffectiveStress);
460 status->setTempKappa(tempKappa);
461 status->setTempDamage(omega);
462}
463
464
465void
466MPSDamMaterial :: initDamagedFib(GaussPoint *gp, TimeStep *tStep) const
467{
468 auto status = static_cast< MPSDamMaterialStatus * >( this->giveStatus(gp) );
469
470 if ( status->giveDamage() == 0. ) {
471 double tequiv = this->computeEquivalentTime(gp, tStep, 0);
472 double e0 = this->computeTensileStrength(tequiv) / this->E;
473 double gf = this->computeFractureEnergy(tequiv);
474
475 status->sete0(e0);
476 status->setgf(gf);
477 }
478}
479
480double
481MPSDamMaterial :: givee0(GaussPoint *gp) const
482{
483 if ( this->timeDepFracturing ) {
484 auto status = static_cast< MPSDamMaterialStatus * >( this->giveStatus(gp) );
485 return status->givee0();
486 } else {
487 return this->ft / this->E;
488 }
489}
490
491
492double
493MPSDamMaterial :: givegf(GaussPoint *gp) const
494{
495 if ( this->timeDepFracturing ) {
496 auto status = static_cast< MPSDamMaterialStatus * >( this->giveStatus(gp) );
497 return status->givegf();
498 } else {
499 return this->const_gf;
500 }
501}
502
503
504double
505MPSDamMaterial :: computeFractureEnergy(double equivalentTime) const
506{
507 // the fracture energy has the same time evolution as the tensile strength,
508 // the direct relation to the mean value of compressive strength according to Model Code
509 // highly overestimates the initial (early age) value of the fracture energy
510 //( fractureEnergy = 73. * fcm(t)^0.18 )
511
512 // evolution of the mean compressive strength with respect to equivalent time/age/maturity
513 // returns fcm in MPa
514
515 /* if (this->gf28 > 0.) {
516 double fcm28mod;
517 fcm28mod = pow ( this->gf28 * MPSMaterial :: stiffnessFactor / 73. , 1. / 0.18 );
518 fcm = exp( fib_s * ( 1. - sqrt(28. * MPSMaterial :: lambda0 / equivalentTime) ) ) * fcm28mod;
519
520 } else {
521 fcm = exp( fib_s * ( 1. - sqrt(28. * MPSMaterial :: lambda0 / equivalentTime) ) ) * fib_fcm28;
522 }
523
524 fractureEnergy = 73. * pow(fcm, 0.18) / MPSMaterial :: stiffnessFactor;
525 */
526
527 // 1) read or estimate the 28-day value of fracture energy
528
529 double fractureEnergy28;
530 if ( this->gf28 > 0. ) {
531 fractureEnergy28 = this->gf28;
532 } else {
533 fractureEnergy28 = 73. * pow(fib_fcm28, 0.18) / MPSMaterial :: stiffnessFactor;
534 }
535
536 // 2) compute the tensile strengh according to provided equivalent time
537
538 double ftm = this->computeTensileStrength(equivalentTime);
539 double ftm28 = this->computeTensileStrength(28. * MPSMaterial :: lambda0);
540
541 // 3) calculate the resulting fracture energy as gf28 * ft/ft28
542
543 return fractureEnergy28 * ftm / ftm28;
544}
545
546double
547MPSDamMaterial :: computeTensileStrength(double equivalentTime) const
548{
549 double fcm, ftm;
550
551 if ( this->ft28 > 0. ) {
552 double fcm28mod = pow ( this->ft28 * MPSMaterial :: stiffnessFactor / 0.3e6, 3./2. ) + 8.;
553 fcm = exp( fib_s * ( 1. - sqrt(28. * MPSMaterial :: lambda0 / equivalentTime) ) ) * fcm28mod;
554
555 } else {
556 // returns fcm in MPa - formula 5.1-51, Table 5.1-9
557 fcm = exp( fib_s * ( 1. - sqrt(28. * MPSMaterial :: lambda0 / equivalentTime) ) ) * fib_fcm28;
558 }
559
560
561 // ftm adjusted according to the stiffnessFactor (MPa by default)
562 if ( fcm >= 58. ) {
563 ftm = 2.12 * log ( 1. + 0.1 * fcm ) * 1.e6 / MPSMaterial :: stiffnessFactor;
564 } else if ( fcm <= 20. ) {
565 ftm = 0.07862 * fcm * 1.e6 / MPSMaterial :: stiffnessFactor; // 12^(2/3) * 0.3 / 20 = 0.07862
566 } else {
567 ftm = 0.3 * pow(fcm - 8., 2. / 3.) * 1.e6 / MPSMaterial :: stiffnessFactor; //5.1-3a
568 }
569
570 /*
571 if ( fcm >= 20. ) {
572 ftm = 0.3 * pow(fcm - 8., 2. / 3.) * 1.e6 / MPSMaterial :: stiffnessFactor; //5.1-3a
573 } else if ( fcm < 8. ) {
574 // upper formula does not hold for concretes with fcm < 8 MPa
575 ftm = 0.3 * pow(fcm, 2. / 3.) * 1.e6 / MPSMaterial :: stiffnessFactor;
576 } else {
577 // smooth transition
578 ftm = 0.3 * pow(fcm - ( 8. * ( fcm - 8. ) / ( 20. - 8. ) ), 2. / 3.) * 1.e6 / MPSMaterial :: stiffnessFactor;
579 }*/
580
581 return ftm;
582}
583
584
585double
586MPSDamMaterial :: computeDamage(double kappa, GaussPoint *gp) const
587{
588 if ( this->softType == ST_Disable_Damage ) { //dummy material with no damage
589 return 0.;
590 } else {
591 return computeDamageForCohesiveCrack(kappa, gp);
592 }
593}
594
595double
596MPSDamMaterial :: computeDamageForCohesiveCrack(double kappa, GaussPoint *gp) const
597{
598 auto status = static_cast< MPSDamMaterialStatus * >( this->giveStatus(gp) );
599
600 double omega = 0.0;
601 double e0 = this->givee0(gp);
602 if ( kappa > e0 ) {
603 double gf = this->givegf(gp);
604
605 double wf = 0.;
606 if ( softType == ST_Exponential_Cohesive_Crack ) { // exponential softening
607 wf = gf / this->E / e0; // wf is the crack opening
608 } else if ( softType == ST_Linear_Cohesive_Crack ) { // linear softening law
609 wf = 2. * gf / this->E / e0; // wf is the crack opening
610 } else {
611 OOFEM_ERROR("Gf unsupported for softening type softType = %d", softType);
612 }
613
614 double Le = status->giveCharLength();
615 double ef = wf / Le; //ef is the fracturing strain
616 if ( ef < e0 ) { //check that no snapback occurs
617 double minGf = 0.;
618 OOFEM_WARNING("ef %e < e0 %e, this leads to material snapback in element %d, characteristic length %f", ef, e0, gp->giveElement()->giveGlobalNumber(), Le);
619
620 if ( softType == ST_Exponential_Cohesive_Crack ) { //exponential softening
621 minGf = this->E * e0 * e0 * Le;
622 } else if ( softType == ST_Linear_Cohesive_Crack ) { //linear softening law
623 minGf = this->E * e0 * e0 * Le / 2.;
624 } else {
625 OOFEM_WARNING("Gf unsupported for softening type softType = %d", softType);
626 }
627
628 OOFEM_WARNING("Material number %d, decrease e0, or increase Gf from %f to Gf=%f", this->giveNumber(), gf, minGf);
629 if ( checkSnapBack ) {
630 OOFEM_ERROR("x");
631 }
632 }
633
634 if ( this->softType == ST_Linear_Cohesive_Crack ) {
635 if ( kappa < ef ) {
636 omega = ( ef / kappa ) * ( kappa - e0 ) / ( ef - e0 );
637 } else {
638 omega = 1.0; //maximum omega (maxOmega) is adjusted just for stiffness matrix in isodamagemodel.C
639 }
640 } else if ( this->softType == ST_Exponential_Cohesive_Crack ) {
641 // exponential cohesive crack - iteration needed
642 double R = 0.;
643 int nite = 0;
644 // iteration to achieve objectivity
645 // we are looking for a state in which the elastic stress is equal to
646 // the stress from crack-opening relation
647 // ef has now the meaning of strain
648 do {
649 nite++;
650 double help = omega * kappa / ef;
651 R = ( 1. - omega ) * kappa - e0 *exp(-help); //residuum
652 double Lhs = kappa - e0 *exp(-help) * kappa / ef; //- dR / (d omega)
653 omega += R / Lhs;
654 if ( nite > 40 ) {
655 OOFEM_ERROR("algorithm not converging");
656 }
657 } while ( fabs(R) >= e0 * MPSDAMMAT_ITERATION_LIMIT );
658 } else {
659 OOFEM_ERROR("Unknown softening type for cohesive crack model.");
660 }
661
662 if ( omega > 1.0 ) {
663 OOFEM_ERROR("damage parameter is %f, which is greater than 1, snap-back problems", omega);
664 }
665
666 if ( omega < 0.0 ) {
667 OOFEM_WARNING("damage parameter is %f, which is smaller than 0, snap-back problems", omega);
668 omega = 1.;
669 if ( checkSnapBack ) {
670 OOFEM_ERROR("x");
671 }
672
673 }
674
675#ifdef supplementary_info
676 double residualStrength = 0.;
677
678 if ( omega == 0. ) {
679 residualStrength = E * e0; // undamaged material
680 } else {
681 if ( this->softType == ST_Linear_Cohesive_Crack ) {
682 residualStrength = E * e0 * ( ef - kappa ) / ( ef - e0 );
683 } else if ( this->softType == ST_Exponential_Cohesive_Crack ) {
684 residualStrength = E * e0 * exp(-1. * ( kappa - e0 ) / ef);
685 } else {
686 OOFEM_ERROR("Unknown softening type for cohesive crack model.");
687 }
688 }
689
690 status->setResidualTensileStrength(residualStrength);
691#endif
692 }
693
694 return omega;
695}
696
697void
698MPSDamMaterial :: initDamaged(double kappa, FloatArray &principalDirection, GaussPoint *gp, TimeStep *tStep) const
699{
700 auto status = static_cast< MPSDamMaterialStatus * >( this->giveStatus(gp) );
701
702 if ( this->timeDepFracturing ) {
703 this->initDamagedFib(gp, tStep);
704 }
705
706 double e0 = this->givee0(gp);
707 double gf = this->givegf(gp);
708 double wf = 0.;
709
710 if ( softType == ST_Disable_Damage ) {
711 return;
712 } else if ( softType == ST_Exponential_Cohesive_Crack ) { // exponential softening
713 wf = gf / E / e0; // wf is the crack opening
714 } else if ( softType == ST_Linear_Cohesive_Crack ) { // linear softening law
715 wf = 2. * gf / E / e0; // wf is the crack opening
716 } else {
717 OOFEM_ERROR("Gf unsupported for softening type softType = %d", softType);
718 }
719
720 if ( ( kappa > e0 ) && ( status->giveDamage() == 0. ) ) {
721 status->setCrackVector(principalDirection);
722
723 double le = gp->giveElement()->giveCharacteristicSize(gp, principalDirection, ecsMethod);
724 status->setCharLength(le);
725
726 if ( gf != 0. && e0 >= ( wf / le ) ) { // case for a given fracture energy
727 OOFEM_WARNING("Fracturing strain %e is lower than the elastic strain e0=%e, possible snap-back. Element number %d, wf %e, le %e. Increase fracturing strain or decrease element size by at least %f", wf / le, e0, gp->giveElement()->giveLabel(), wf, le, e0/(wf/le) );
728 if ( checkSnapBack ) {
729 OOFEM_ERROR("x");
730 }
731 }
732 }
733}
734
735
736
737std::unique_ptr<MaterialStatus>
738MPSDamMaterial :: CreateStatus(GaussPoint *gp) const
739/*
740 * creates a new material status corresponding to this class
741 */
742{
743 return std::make_unique<MPSDamMaterialStatus>(gp, nUnits);
744}
745
746
748MPSDamMaterial :: give3dMaterialStiffnessMatrix(MatResponseMode mode,
749 GaussPoint *gp,
750 TimeStep *tStep) const
751{
752 auto d = RheoChainMaterial :: give3dMaterialStiffnessMatrix(ElasticStiffness, gp, tStep);
753
754 if ( mode == ElasticStiffness || ( mode == SecantStiffness && !this->isotropic ) ) {
755 return d;
756 }
757
758 auto status = static_cast< MPSDamMaterialStatus * >( this->giveStatus(gp) );
759 double tempDamage = min(status->giveTempDamage(), this->maxOmega);
760 return d * (1.0 - tempDamage);
761}
762
763
765MPSDamMaterial :: givePlaneStressStiffMtrx(MatResponseMode mode,
766 GaussPoint *gp,
767 TimeStep *tStep) const
768{
769 auto d = RheoChainMaterial :: givePlaneStressStiffMtrx(ElasticStiffness, gp, tStep);
770
771 if ( mode == ElasticStiffness || ( mode == SecantStiffness && !this->isotropic ) ) {
772 return d;
773 }
774
775 auto status = static_cast< MPSDamMaterialStatus * >( this->giveStatus(gp) );
776 double tempDamage = min(status->giveTempDamage(), this->maxOmega);
777 return d * (1.0 - tempDamage);
778}
779
780
782MPSDamMaterial :: givePlaneStrainStiffMtrx(MatResponseMode mode,
783 GaussPoint *gp,
784 TimeStep *tStep) const
785{
786 auto d = RheoChainMaterial :: givePlaneStrainStiffMtrx(ElasticStiffness, gp, tStep);
787
788 if ( mode == ElasticStiffness || ( mode == SecantStiffness && !this->isotropic ) ) {
789 return d;
790 }
791
792 auto status = static_cast< MPSDamMaterialStatus * >( this->giveStatus(gp) );
793 double tempDamage = min(status->giveTempDamage(), this->maxOmega);
794 return d * (1.0 - tempDamage);
795}
796
797
799MPSDamMaterial :: give1dStressStiffMtrx(MatResponseMode mode,
800 GaussPoint *gp,
801 TimeStep *tStep) const
802{
803 auto d = RheoChainMaterial :: give1dStressStiffMtrx(ElasticStiffness, gp, tStep);
804
805 if ( mode == ElasticStiffness || ( mode == SecantStiffness && !this->isotropic ) ) {
806 return d;
807 }
808
809 auto status = static_cast< MPSDamMaterialStatus * >( this->giveStatus(gp) );
810 double tempDamage = min(status->giveTempDamage(), this->maxOmega);
811 return d * (1.0 - tempDamage);
812}
813
814
815int
816MPSDamMaterial :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
817{
818 auto status = static_cast< MPSDamMaterialStatus * >( this->giveStatus(gp) );
819 if ( type == IST_DamageScalar ) {
820 answer.resize(1);
821 answer.zero();
822 answer.at(1) = status->giveDamage();
823 return 1;
824 } else if ( type == IST_DamageTensor ) {
825 answer.resize(6);
826 answer.zero();
827 answer.at(1) = answer.at(2) = answer.at(3) = status->giveDamage();
828 return 1;
829 } else if ( type == IST_PrincipalDamageTensor ) {
830 answer.resize(3);
831 answer.zero();
832 answer.at(1) = status->giveDamage();
833 return 1;
834 } else if ( type == IST_DamageTensorTemp ) {
835 answer.resize(6);
836 answer.zero();
837 answer.at(1) = answer.at(2) = answer.at(3) = status->giveTempDamage();
838 return 1;
839 } else if ( type == IST_PrincipalDamageTempTensor ) {
840 answer.resize(3);
841 answer.zero();
842 answer.at(1) = status->giveTempDamage();
843 return 1;
844 } else if ( type == IST_CharacteristicLength ) {
845 answer.resize(1);
846 answer.zero();
847 answer.at(1) = status->giveCharLength();
848 return 1;
849 } else if ( type == IST_CrackVector ) {
850 answer.resize(3);
851 answer.zero();
852 status->giveCrackVector(answer);
853 return 1;
854 } else if ( type == IST_CrackWidth ) {
855 answer.resize(1);
856 answer.zero();
857 answer.at(1) = status->giveCrackWidth();
858 return 1;
859 } else if ( type == IST_ResidualTensileStrength ) {
860 answer.resize(1);
861 answer.zero();
862 answer.at(1) = status->giveResidualTensileStrength();
863 return 1;
864 } else if ( type == IST_TensileStrength ) {
865 double tequiv = status->giveEquivalentTime();
866 answer.resize(1);
867 answer.zero();
868 if (tequiv >= 0.) {
869 answer.at(1) = this->computeTensileStrength(tequiv);
870 }
871 return 1;
872 } else if ( type == IST_CrackIndex ) {
873 //ratio of real principal stress / strength. 1 if damage already occured.
874 answer.resize(1);
875 answer.zero();
876 if ( status->giveDamage()>0. ){
877 answer.at(1)=1.;
878 return 1;
879 }
880 //FloatArray effectiveStress = status->giveTempViscoelasticStressVector();
881 //StructuralMaterial :: computePrincipalValues(principalStress, effectiveStress, principal_stress);
882 FloatArray principalStress;
883 StructuralMaterial :: giveIPValue(principalStress, gp, IST_PrincipalStressTensor, tStep);
884 double tequiv = status->giveEquivalentTime();
885 if ( tequiv >= 0. ) {
886 double ft = this->computeTensileStrength(tequiv);
887 if ( ft > 1.e-20 && principalStress.at(1)>1.e-20 ) {
888 answer.at(1) = principalStress.at(1)/ft;
889 }
890 }
891 return 1;
892 } else {
893 return MPSMaterial :: giveIPValue(answer, gp, type, tStep);
894 }
895
896 // return 1; // to make the compiler happy
897}
898} // end namespace oofem
#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
Definition element.h:1129
virtual double giveCharacteristicSize(GaussPoint *gp, FloatArray &normalToCrackPlane, ElementCharSizeMethod method)
Definition element.h:965
int giveLabel() const
Definition element.h:1125
int giveNumber() const
Definition femcmpnn.h:104
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void resizeWithValues(Index s, std::size_t allocChunk=0)
Definition floatarray.C:103
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void rotatedWith(FloatMatrix &r, char mode)
Definition floatarray.C:814
void beScaled(double s, const FloatArray &b)
Definition floatarray.C:208
void add(const FloatArray &src)
Definition floatarray.C:218
void times(double s)
Definition floatarray.C:834
double at(std::size_t i, std::size_t j) const
MaterialMode giveMaterialMode()
Returns corresponding material mode of receiver.
Definition gausspoint.h:190
Element * giveElement()
Returns corresponding element to receiver.
Definition gausspoint.h:187
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
double var_e0
hydration-degree dependent equivalent strain at stress peak
Definition mpsdammat.h:94
double tempKappa
Non-equilibrated scalar measure of the largest strain level.
Definition mpsdammat.h:82
FloatArray tempEffectiveStressVector
Temporary stress vector in reduced form (increments are used mainly in nonlinear analysis).
Definition mpsdammat.h:78
double tempDamage
Non-equilibrated damage level of material.
Definition mpsdammat.h:86
void setTempKappa(double newKappa)
Sets the temp scalar measure of the largest strain level to given value.
Definition mpsdammat.h:116
double giveCharLength() const
Returns characteristic length stored in receiver.
Definition mpsdammat.h:125
void setResidualTensileStrength(double src)
Definition mpsdammat.h:145
double damage
Damage level of material.
Definition mpsdammat.h:84
void setCrackWidth(double src)
Definition mpsdammat.h:143
FloatArray effectiveStressVector
Equilibrated stress vector in reduced form.
Definition mpsdammat.h:76
double kappa
Scalar measure of the largest strain level ever reached in material.
Definition mpsdammat.h:80
void letTempViscoelasticStressVectorBe(FloatArray v)
Assigns tempStressVector to given vector v.
Definition mpsdammat.h:108
double giveDamage() const
Returns the last equilibrated damage level.
Definition mpsdammat.h:118
void setTempDamage(double newDamage)
Sets the temp damage level to given value.
Definition mpsdammat.h:122
FloatArray crackVector
Crack orientation normalized to damage magnitude. This is useful for plotting cracks as a vector fiel...
Definition mpsdammat.h:91
double var_gf
hydration-degree dependent fracture energy
Definition mpsdammat.h:96
double charLength
Characteristic length.
Definition mpsdammat.h:89
double giveKappa() const
Returns the last equilibrated scalar measure of the largest strain level.
Definition mpsdammat.h:112
double givee0(GaussPoint *gp) const
Definition mpsdammat.C:481
void initDamagedFib(GaussPoint *gp, TimeStep *tStep) const
Definition mpsdammat.C:466
double computeDamage(double kappa, GaussPoint *gp) const
Definition mpsdammat.C:586
void initDamaged(double kappa, FloatArray &totalStrainVector, GaussPoint *gp, TimeStep *tStep) const
Definition mpsdammat.C:698
double E
dummy Young's modulus
Definition mpsdammat.h:190
double givegf(GaussPoint *gp) const
Definition mpsdammat.C:493
int checkSnapBack
Check possible snap back flag.
Definition mpsdammat.h:210
double gf28
28-day value of fracture energy. Used only with "timedepfracturing"
Definition mpsdammat.h:225
double ft28
28-day value of tensile strength. Used only with "timedepfracturing"
Definition mpsdammat.h:223
ElementCharSizeMethod ecsMethod
Method used for evaluation of characteristic element size.
Definition mpsdammat.h:220
SofteningType softType
Parameter specifying the type of softening (damage law).
Definition mpsdammat.h:217
double computeDamageForCohesiveCrack(double kappa, GaussPoint *gp) const
Definition mpsdammat.C:596
virtual double computeTensileStrength(double equivalentTime) const
Definition mpsdammat.C:547
virtual double computeFractureEnergy(double equivalentTime) const
Definition mpsdammat.C:505
double ft
Equivalent strain at stress peak (or a similar parameter).
Definition mpsdammat.h:199
MPSMaterialStatus(GaussPoint *g, int nunits)
Definition mps.C:54
double giveTempAutogenousShrinkageStrain(void)
Definition mps.h:205
double giveTempDryingShrinkageStrain(void)
Definition mps.h:201
double computeEquivalentTime(GaussPoint *gp, TimeStep *tStep, int option) const
Definition mps.C:1705
MPSMaterial(int n, Domain *d)
Definition mps.h:308
double lambda0
constant equal to one day in time units of analysis (eg. 86400 if the analysis runs in seconds)
Definition mps.h:235
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Definition material.C:206
double giveTempThermalStrain(void)
Definition rheoChM.h:125
bool isActivated(TimeStep *tStep) const override
Extended meaning: returns true if the material is cast (target time > casting time) or the precasing ...
Definition rheoChM.h:321
int nUnits
Number of (Maxwell or Kelvin) units in the rheologic chain.
Definition rheoChM.h:145
void convertFromFullForm(const FloatArray &reducedform, MaterialMode mode)
void computePrincipalValDir(FloatArray &answer, FloatMatrix &dir) const override
void letTempStressVectorBe(const FloatArray &v)
Assigns tempStressVector to given vector v.
void letTempStrainVectorBe(const FloatArray &v)
Assigns tempStrainVector to given vector v.
static FloatMatrixF< 3, 3 > givePlaneStressVectorTranformationMtrx(const FloatMatrixF< 2, 2 > &base, bool transpose=false)
static FloatMatrixF< 6, 6 > giveStressVectorTranformationMtrx(const FloatMatrixF< 3, 3 > &base, bool transpose=false)
static void computePrincipalValues(FloatArray &answer, const FloatArray &s, stressStrainPrincMode mode)
Common functions for convenience.
static int giveSizeOfVoigtSymVector(MaterialMode mmode)
#define THROW_CIOERR(e)
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_ERROR(...)
Definition error.h:79
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Definition inputrecord.h:75
#define IR_GIVE_FIELD(__ir, __value, __id)
Definition inputrecord.h:67
#define _IFT_MPSMaterial_fc
Definition mps.h:49
#define _IFT_MPSDamMaterial_gf28
Definition mpsdammat.h:63
#define _IFT_MPSDamMaterial_damageLaw
Definition mpsdammat.h:57
#define _IFT_MPSDamMaterial_isotropic
Definition mpsdammat.h:53
#define MPSDAMMAT_ITERATION_LIMIT
Definition mpsdammat.h:68
#define _IFT_MPSDamMaterial_timedepfracturing
Definition mpsdammat.h:50
#define _IFT_MPSDamMaterial_gf
Definition mpsdammat.h:60
#define _IFT_MPSDamMaterial_ft
Definition mpsdammat.h:59
#define _IFT_MPSDamMaterial_fib_s
Definition mpsdammat.h:51
#define _IFT_MPSDamMaterial_checkSnapBack
Definition mpsdammat.h:58
#define _IFT_MPSDamMaterial_ft28
Definition mpsdammat.h:62
long ContextMode
Definition contextmode.h:43
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
@ principal_strain
For computing principal strains from engineering strains.
@ CIO_IOERR
General IO error.

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011