OOFEM 3.0
Loading...
Searching...
No Matches
concretefcm.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 "concretefcm.h"
36#include "gausspoint.h"
37#include "mathfem.h"
38#include "classfactory.h"
39#include "contextioerr.h"
40
41namespace oofem {
43
44ConcreteFCM :: ConcreteFCM(int n, Domain *d) : FCMMaterial(n, d), RandomMaterialExtensionInterface()
45{}
46
47void
48ConcreteFCM :: initializeFrom(InputRecord &ir)
49{
50 FCMMaterial :: initializeFrom(ir);
51 RandomMaterialExtensionInterface :: initializeFrom(ir);
52
53 // type of TENSION SOFTENING
54 int softening = 0;
56 switch ( softening ) {
57 case 0:
59 Ft = 1.e50;
60 Gf = 1.e50;
61 break;
62
63 case 1:
67 break;
68
69 case 2:
73 break;
74
75 case 3:
79 break;
80
81 case 4:
86
87 if ( soft_w.at(1) > 0. ) {
88 throw ValueInputException(ir, _IFT_ConcreteFCM_soft_w, "The first entry in soft_w must be 0.");
89 }
90
91 if ( soft_w.giveSize() != soft_function_w.giveSize() ) {
92 throw ValueInputException(ir, _IFT_ConcreteFCM_soft_function_w, "the size of 'soft_w' and 'soft(w)' must be the same");
93 }
94 break;
95
96 case 5:
99 this->eps_f = 1.;
102
103 if ( this->giveCrackSpacing() > 0. ) {
104 throw ValueInputException(ir, _IFT_FCM_crackSpacing, "crack spacing must not be defined in strain-defined materials (does not make sense)");
105 }
106
107 break;
108
109 case 6:
114
115 if ( soft_eps.at(1) > 0. ) {
116 throw ValueInputException(ir, _IFT_ConcreteFCM_soft_eps, "The first entry in soft_eps must be 0.");
117 }
118
119 if ( soft_eps.giveSize() != soft_function_eps.giveSize() ) {
120 throw ValueInputException(ir, _IFT_ConcreteFCM_soft_function_eps, "the size of 'soft_eps' and 'soft(eps)' must be the same");
121 }
122
123 if ( this->giveCrackSpacing() > 0. ) {
124 throw ValueInputException(ir, "foo", "crack spacing must not be defined in strain-defined materials (does not make sense)");
125 }
126
127 break;
128
129 default:
130 throw ValueInputException(ir, _IFT_ConcreteFCM_softType, "Unknown softening type");
131 }
132
133
134 // type of SHEAR STIFFNESS REDUCTION
135 int shear = 0;
137 switch ( shear ) {
138 case 0:
140
141 break;
142
143 case 1:
145 beta = 0.01;
147
148 if ( beta >= 1. ) {
149 throw ValueInputException(ir, _IFT_ConcreteFCM_beta, "Parameter beta must be <= 1");
150 }
151
152 break;
153
154 case 2:
155 // todo: resolve problems with convergence when crack is wide open
156 // this does not happen when beta is used instead sf
158 sf = 20.;
160
161 sf_numer = sf;
163 break;
164
165 case 3: // w is the maximum reached crack opening, not the current value!
169
170 if ( beta_w.giveSize() != beta_function.giveSize() ) {
171 throw ValueInputException(ir, _IFT_ConcreteFCM_beta_function, "the size of 'beta_w' and 'beta(w)' must be the same");
172 }
173 break;
174
175
176 default:
177 throw ValueInputException(ir, _IFT_ConcreteFCM_shearType, "Shear stiffness reduction typ is unknown");
178 }
179
180
181 // type of SHEAR STRENGTH CUTOFF
182 shear = 0;
183
185 switch ( shear ) {
186 case 0:
188 break;
189
190 case 1:
192 break;
193
194 case 2:
196
200
201 break;
202
203 case 3:
205 break;
206
207 default:
208 throw ValueInputException(ir, _IFT_ConcreteFCM_shearStrengthType, "Shear stiffness reduction type is unknown");
209 }
210}
211
212
213double
214ConcreteFCM :: giveCrackingModulus(MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep, int i) const
215//
216// returns current cracking modulus according to crackStrain for i-th
217// crackplane
218//
219{
220 ConcreteFCMStatus *status = static_cast< ConcreteFCMStatus * >( this->giveStatus(gp) );
221 double E = this->computeOverallElasticStiffness(gp, tStep);
222
223 if ( status->giveTempCrackStatus(i) == pscm_NONE ) {
224 return E * fcm_BIGNUMBER;
225 }
226
227 // very high stiffness also for compression
228 if ( status->giveTempCrackStatus(i) == pscm_CLOSED ) {
229 return E * fcm_BIGNUMBER;
230 }
231
232 return giveCrackingModulusInTension(rMode, gp, tStep, i);
233
234}
235
236
237double
238ConcreteFCM :: giveCrackingModulusInTension(MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep, int i) const
239{
240
241 ConcreteFCMStatus *status = static_cast< ConcreteFCMStatus * >( this->giveStatus(gp) );
242
243 double Cf = 0.;
244 double ef, emax, c1, c2, Le, Ncr, w;
245
246 double ft = this->giveTensileStrength(gp, tStep);
247 double Gf = this->giveFractureEnergy(gp, tStep);
248 double ec = status->giveTempCrackStrain(i);
249 double E = this->computeOverallElasticStiffness(gp, tStep);
250
251
252
253 emax = max(status->giveMaxCrackStrain(i), ec);
254
255 Le = status->giveCharLength(i);
256
257 // modification to take into account crack spacing - makes sense only in crack-opening-based materials
258 Ncr = this->giveNumberOfCracksInDirection(gp, i);
259
260 ec /= Ncr;
261 emax /= Ncr;
262
263
264 if ( ( rMode == TangentStiffness ) && ( ec >= emax ) ) { // tangent and NOT unloading
265 if ( softType == ST_NONE ) {
266 OOFEM_ERROR("For unknown reason the tensile strength has been exceeded and cracking has been initiated!");
267 } else if ( softType == ST_Exponential ) {
268 ef = Gf / ( ft * Le );
269
270 if ( emax == 0. ) { // just initiated and closing crack
271 Cf = -ft / ef;
272 } else { // further softening - negative stiffness
273 Cf = -ft / ef *exp(-ec / ef);
274 }
275 } else if ( softType == ST_Linear ) {
276 // fracturing strain at zero traction
277 ef = 2. * Gf / ( ft * Le );
278
279 if ( ( ec >= ef ) || ( emax >= ef ) ) {
280 // fully open crack - no stiffness
281 Cf = 0.;
282 } else { // further softening - negative stiffness
283 Cf = -ft / ef;
284 }
285 } else if ( softType == ST_Hordijk ) {
286 c1 = 3.;
287 c2 = 6.93;
288
289 ef = 5.14 * Gf / ft / Le;
290
291 if ( ( ec >= ef ) || ( emax >= ef ) ) {
292 Cf = 0.;
293 } else if ( emax == 0. ) { // just initiated and closing crack
294 Cf = ft * ( -c2 / ef - ( exp(-c2) * ( c1 * c1 * c1 + 1. ) ) / ef );
295 } else { // further softening - negative stiffness
296 Cf = ft * ( ( 3. * c1 * c1 * c1 * ec * ec * exp(-( c2 * ec ) / ef) ) / ( ef * ef * ef ) - ( c2 * exp(-( c2 * ec ) / ef) * ( c1 * c1 * c1 * ec * ec * ec + ef * ef * ef ) ) / ( ef * ef * ef * ef ) - ( exp(-c2) * ( c1 * c1 * c1 + 1. ) ) / ef );
297 }
298 } else if ( softType == ST_UserDefinedCrack ) {
299 w = ec * Le;
300
301 if ( w > soft_w.at(soft_w.giveSize() ) ) {
302 Cf = 0.;
303#ifdef DEBUG
304 OOFEM_WARNING("Crack width is larger than the last user-defined value in the traction-opening law.");
305#endif
306 } else if ( emax == 0. ) {
307 Cf = ft * ( soft_function_w.at(2) - soft_function_w.at(1) ) / ( ( soft_w.at(2) - soft_w.at(1) ) / Le );
308 } else { // softening
309 for ( int i = 1; i <= soft_w.giveSize(); i++ ) {
310 if ( ( w - soft_w.at(i) ) < fcm_SMALL_STRAIN ) {
311 if ( i == 1 ) {
312 Cf = ft * ( soft_function_w.at(2) - soft_function_w.at(1) ) / ( ( soft_w.at(2) - soft_w.at(1) ) / Le );
313 break;
314 } else {
315 Cf = ft * ( soft_function_w.at(i) - soft_function_w.at(i - 1) ) / ( ( soft_w.at(i) - soft_w.at(i - 1) ) / Le );
316 break;
317 }
318 }
319 }
320 }
321 } else if ( softType == ST_LinearHardeningStrain ) {
322 if ( ( ec >= this->eps_f ) || ( emax >= this->eps_f ) ) {
323 Cf = 0.;
324 } else {
325 // hardening
326 Cf = this->H;
327 }
328 } else if ( softType == ST_UserDefinedStrain ) {
329
330 if ( ec > soft_eps.at(soft_eps.giveSize() ) ) {
331 Cf = 0.;
332#ifdef DEBUG
333 OOFEM_WARNING("Crack strain is larger than the last user-defined value in the stress-crack-strain law.");
334#endif
335 } else if ( emax == 0. ) {
336 Cf = ft * ( soft_function_eps.at(2) - soft_function_eps.at(1) ) / ( soft_eps.at(2) - soft_eps.at(1) );
337 } else { // softening
338 for ( int i = 1; i <= soft_eps.giveSize(); i++ ) {
339 if ( ( ec - soft_eps.at(i) ) < fcm_SMALL_STRAIN ) {
340 if ( i == 1 ) {
341 Cf = ft * ( soft_function_eps.at(2) - soft_function_eps.at(1) ) / ( soft_eps.at(2) - soft_eps.at(1) );
342 break;
343 } else {
344 Cf = ft * ( soft_function_eps.at(i) - soft_function_eps.at(i - 1) ) / ( soft_eps.at(i) - soft_eps.at(i - 1) );
345 break;
346 }
347 }
348 }
349 }
350 } else {
351 OOFEM_ERROR("Unknown Softening Mode");
352 }
353 } else { // secant stiffness OR tangent stiffness and unloading
354 if ( emax <= 0. ) { // just initiated crack that wants to close
355 return E * fcm_BIGNUMBER;
356 }
357
358 Cf = ConcreteFCM :: giveNormalCrackingStress(gp, tStep, emax * Ncr, i); // gets stress
359 Cf /= ( emax ); // converted into stiffness
360 }
361
362 // to take into account crack-spacing
363 return Cf / Ncr;
364}
365
366
367double
368ConcreteFCM :: giveNormalCrackingStress(GaussPoint *gp, TimeStep *tStep, double ec, int i) const
369//
370// returns receivers Normal Stress in crack i for given cracking strain
371//
372{
373 ConcreteFCMStatus *status = static_cast< ConcreteFCMStatus * >( this->giveStatus(gp) );
374
375 double traction;
376 double Le, ef, emax, w, E, c1, c2;
377 double Gf = this->giveFractureEnergy(gp, tStep);
378 double ft = this->giveTensileStrength(gp, tStep);
379
380 if ( status->giveTempCrackStatus(i) == pscm_CLOSED ) {
381 E = this->computeOverallElasticStiffness(gp, tStep);
382 return E * ec;
383 }
384
385 Le = status->giveCharLength(i);
386 emax = max(status->giveMaxCrackStrain(i), ec);
387
388 // to take into account crack spacing
389 ec /= this->giveNumberOfCracksInDirection(gp, i);
390 emax /= this->giveNumberOfCracksInDirection(gp, i);
391
392
393 if ( softType == ST_NONE ) {
394 OOFEM_ERROR("For unknown reason the tensile strength has been exceeded and cracking has been initiated!");
395 } else if ( softType == ST_Exponential ) {
396 ef = Gf / ( ft * Le );
397 if ( ec >= emax ) {
398 // further softening
399 traction = ft * exp(-ec / ef);
400 } else {
401 // crack closing
402 // or unloading or reloading regime
403 traction = ft * ec / emax *exp(-emax / ef);
404 }
405 } else if ( softType == ST_Linear ) {
406 // fracturing strain at zero traction
407 ef = 2. * Gf / ( ft * Le );
408
409 if ( ( ec >= ef ) || ( emax >= ef ) ) {
410 // fully open crack - no stiffness
411 traction = 0.;
412 } else if ( ec >= emax ) {
413 // further softening
414 traction = ft - ft * ec / ef;
415 } else if ( ec <= 0. ) {
416 traction = 0.;
417 } else {
418 traction = ft * ec * ( ef - emax ) / ( emax * ef );
419 }
420 } else if ( softType == ST_Hordijk ) {
421 c1 = 3.;
422 c2 = 6.93;
423
424 ef = 5.14 * Gf / ft / Le;
425
426 if ( ( ec >= ef ) || ( emax >= ef ) ) {
427 // fully open crack - no stiffness
428 traction = 0.;
429 } else if ( ec >= emax ) {
430 // further softening
431 traction = ft * ( ( 1. + pow( ( c1 * ec / ef ), 3. ) ) * exp(-c2 * ec / ef) - ec / ef * ( 1. + c1 * c1 * c1 ) * exp(-c2) );
432 } else if ( ec <= 0. ) {
433 traction = 0.;
434 } else {
435 traction = ft * ec / emax * ( ( 1. + pow( ( c1 * emax / ef ), 3. ) ) * exp(-c2 * emax / ef) - emax / ef * ( 1. + c1 * c1 * c1 ) * exp(-c2) );
436 }
437 } else if ( softType == ST_UserDefinedCrack ) {
438 w = ec * Le;
439
440 traction = 0.;
441
442 if ( w > soft_w.at(soft_w.giveSize() ) ) {
443 traction = 0.;
444#ifdef DEBUG
445 OOFEM_WARNING("Crack width is larger than the last user-defined value in the traction-opening law.");
446#endif
447 } else if ( ec >= emax ) { // softening
448 for ( int i = 1; i <= soft_w.giveSize(); i++ ) {
449 if ( ( w - soft_w.at(i) ) < fcm_SMALL_STRAIN ) {
450 if ( i == 1 ) { // eps \approx 0 bound
451 traction = soft_function_w.at(i) * ft;
452 break;
453 } else {
454 traction = soft_function_w.at(i - 1) + ( soft_function_w.at(i) - soft_function_w.at(i - 1) ) / ( soft_w.at(i) - soft_w.at(i - 1) ) * ( w - soft_w.at(i - 1) );
455 traction *= ft;
456 break;
457 }
458 }
459 }
460 } else if ( ec <= 0. ) { // closing
461 traction = 0.;
462 } else { //unlo-relo
463 w = emax * Le; // lower stiffness
464
465 for ( int i = 1; i <= soft_w.giveSize(); i++ ) {
466 if ( ( w - soft_w.at(i) ) < fcm_SMALL_STRAIN ) {
467 if ( i == 1 ) { // eps \approx 0
468 traction = soft_function_w.at(i) * ft * ec / emax;
469 break;
470 } else {
471 traction = soft_function_w.at(i - 1) + ( soft_function_w.at(i) - soft_function_w.at(i - 1) ) / ( soft_w.at(i) - soft_w.at(i - 1) ) * ( w - soft_w.at(i - 1) );
472 traction *= ft * ec / emax;
473 break;
474 }
475 }
476 }
477 }
478 } else if ( softType == ST_LinearHardeningStrain ) {
479 if ( ( ec >= this->eps_f ) || ( emax >= this->eps_f ) ) {
480 traction = 0.;
481 } else if ( emax == 0. ) {
482 traction = ft;
483 } else {
484 // unloading or reloading regime
485 // emax * Le = crack width
486 // traction = ( this->Ft + emax * Le * this->H ) * ec / emax;
487 // written in terms of strain and not crack width
488 traction = ( ft + emax * this->H ) * ec / emax;
489 }
490 } else if ( softType == ST_UserDefinedStrain ) {
491
492 traction = 0.;
493
494 if ( emax > soft_eps.at(soft_eps.giveSize() ) ) {
495 traction = 0.;
496#ifdef DEBUG
497 OOFEM_WARNING("Cracking strain is larger than the last user-defined value in the traction-cracking-strain law.");
498#endif
499 } else if ( ec >= emax ) { // softening
500 for ( int i = 1; i <= soft_eps.giveSize(); i++ ) {
501 if ( ( ec - soft_eps.at(i) ) < fcm_SMALL_STRAIN ) {
502 if ( i == 1 ) { // eps \approx 0 bound
503 traction = soft_function_eps.at(i) * ft;
504 break;
505 } else {
506 traction = soft_function_eps.at(i - 1) + ( soft_function_eps.at(i) - soft_function_eps.at(i - 1) ) / ( soft_eps.at(i) - soft_eps.at(i - 1) ) * ( ec - soft_eps.at(i - 1) );
507 traction *= ft;
508 break;
509 }
510 }
511 }
512 } else if ( ec <= 0. ) { // closing
513 traction = 0.;
514 } else { //unlo-relo
515 for ( int i = 1; i <= soft_eps.giveSize(); i++ ) {
516 if ( ( emax - soft_eps.at(i) ) < fcm_SMALL_STRAIN ) {
517 if ( i == 1 ) { // eps \approx 0
518 traction = soft_function_eps.at(i) * ft * ec / emax;
519 break;
520 } else {
521 traction = soft_function_eps.at(i - 1) + ( soft_function_eps.at(i) - soft_function_eps.at(i - 1) ) / ( soft_eps.at(i) - soft_eps.at(i - 1) ) * ( emax - soft_eps.at(i - 1) );
522 traction *= ft * ec / emax;
523 break;
524 }
525 }
526 }
527 }
528 } else {
529 OOFEM_ERROR("Unknown Softening Mode");
530 }
531
532 return traction;
533}
534
535double
536ConcreteFCM :: computeEffectiveShearModulus(GaussPoint *gp, TimeStep *tStep, int shearDirection) const
537
538{
539 double G, Geff, D2tot, N;
540 int crackA, crackB;
541
542 G = this->computeOverallElasticShearModulus(gp, tStep);
543
544 if ( this->isIntactForShear(gp, shearDirection) ) {
545 Geff = G;
546 } else {
547 if ( this->shearType == SHR_NONE ) {
548 Geff = G;
549 } else if ( this->shearType == SHR_Const_ShearRetFactor ) {
550 if ( multipleCrackShear ) {
551 if ( shearDirection == 4 ) {
552 crackA = 2;
553 crackB = 3;
554 } else if ( shearDirection == 5 ) {
555 crackA = 1;
556 crackB = 3;
557 } else if ( shearDirection == 6 ) {
558 crackA = 1;
559 crackB = 2;
560 } else {
561 OOFEM_ERROR("Unexpected value of index i (4, 5, 6 permitted only)");
562 }
563
564 // total number of parallel cracks in both directions
565 N = this->giveNumberOfCracksInDirection(gp, crackA) + this->giveNumberOfCracksInDirection(gp, crackB);
566 } else {
567 N = this->giveNumberOfCracksForShearDirection(gp, shearDirection);
568 }
569
570 Geff = G * this->beta / ( N - this->beta * ( N - 1 ) ); // for N = 1... Geff = G * beta
571 } else if ( this->shearType == SHR_Const_ShearFactorCoeff ) {
572 // contributions from shear terms in: De - De (De + Dcr)^-1 De
573 D2tot = this->computeNumerD2Modulus(gp, tStep, shearDirection);
574 // number of parallel cracks already taken into account
575 Geff = G * D2tot / ( G + D2tot );
576 } else if ( this->shearType == SHR_UserDefined_ShearRetFactor ) {
577 // contributions from shear terms in: De - De (De + Dcr)^-1 De
578 D2tot = this->computeNumerD2Modulus(gp, tStep, shearDirection);
579 // number of parallel cracks already taken into account
580 Geff = G * D2tot / ( G + D2tot );
581 } else {
582 OOFEM_ERROR("Unknown Shear Mode");
583 }
584 }
585
586 return Geff;
587}
588
589
590double
591ConcreteFCM :: computeD2ModulusForCrack(GaussPoint *gp, TimeStep *tStep, int icrack) const
592{
593 double D2, N, G, E, w, beta_m;
594
595 if ( icrack >= 4 ) {
596 OOFEM_ERROR("Unexpected crack number");
597 }
598
599 N = this->giveNumberOfCracksInDirection(gp, icrack);
600
601 if ( this->isIntact(gp, icrack) || ( this->shearType == SHR_NONE ) ) {
602 E = this->computeOverallElasticStiffness(gp, tStep);
603 D2 = E * fcm_BIGNUMBER;
604 } else {
606 G = this->computeOverallElasticShearModulus(gp, tStep);
607 D2 = G * this->beta / ( 1. - this->beta );
608 D2 /= N;
609 } else if ( shearType == SHR_Const_ShearFactorCoeff ) {
610 // for the number of parallel cracks is taken care of in "giveCrackingModulus"
611 // however, it is essential to reduce the final modulus due to the presence of multiple cracks
612 D2 = this->sf * ConcreteFCM::giveCrackingModulusInTension(SecantStiffness, gp, tStep, icrack);
613 D2 /= N;
614 } else if ( this->shearType == SHR_UserDefined_ShearRetFactor ) {
615 // for the number of parallel cracks is taken care of in the evaluation of normalcrackopening
616 // however, it is essential to reduce the final modulus due to the presence of multiple cracks
617
618 G = this->computeOverallElasticShearModulus(gp, tStep);
619 w = max( this->computeNormalCrackOpening(gp, icrack), this->computeMaxNormalCrackOpening(gp, tStep, icrack) );
620
622
623 beta_m = 0.;
624 for ( int i = 1; i <= this->beta_w.giveSize(); i++ ) {
625 if ( ( w - this->beta_w.at(i) ) < fcm_SMALL_STRAIN ) {
626 if ( i == 1 ) {
627 beta_m = this->beta_function.at(i);
628 } else {
629 beta_m = this->beta_function.at(i - 1) + ( this->beta_function.at(i) - this->beta_function.at(i - 1) ) / ( this->beta_w.at(i) - this->beta_w.at(i - 1) ) * ( w - this->beta_w.at(i - 1) );
630 }
631
632 beta_m = min(1., beta_m);
633 break;
634 }
635 }
636
637 if ( beta_m >= 1. ) {
638 D2 = G * fcm_BIGNUMBER;
639 } else {
640 D2 = G * beta_m / ( 1. - beta_m );
641 D2 /= N;
642 }
643 } else {
644 D2 = 0;
645 OOFEM_ERROR("Unknown Softening Mode");
646 }
647 }
648
649
650
651 return D2;
652}
653
654
655
656double
657ConcreteFCM :: computeNumerD2ModulusForCrack(GaussPoint *gp, TimeStep *tStep, int icrack) const
658{
659 double D2, N, E;
660
661 if ( icrack >= 4 ) {
662 OOFEM_ERROR("Unexpected crack number");
663 }
664
665 N = this->giveNumberOfCracksInDirection(gp, icrack);
666
667 if ( this->isIntact(gp, icrack) || ( this->shearType == SHR_NONE ) ) {
668 E = this->computeOverallElasticStiffness(gp, tStep);
669 D2 = E * fcm_BIGNUMBER;
670 } else {
672 D2 = ConcreteFCM :: computeD2ModulusForCrack(gp, tStep, icrack);
673 } else if ( shearType == SHR_Const_ShearFactorCoeff ) {
674 // for the number of parallel cracks is taken care of in "giveCrackingModulus"
675 // however, it is essential to reduce the final modulus due to the presence of multiple cracks
676 D2 = this->sf_numer * ConcreteFCM::giveCrackingModulusInTension(SecantStiffness, gp, tStep, icrack);
677 D2 /= N;
678 } else if ( this->shearType == SHR_UserDefined_ShearRetFactor ) {
679 D2 = ConcreteFCM :: computeD2ModulusForCrack(gp, tStep, icrack);
680 } else {
681 D2 = 0;
682 OOFEM_ERROR("Unknown Softening Mode");
683 }
684 }
685
686 return D2;
687}
688
689
690
691void
692ConcreteFCM :: checkSnapBack(GaussPoint *gp, TimeStep *tStep, int i) const
693{
694 ConcreteFCMStatus *status = static_cast< ConcreteFCMStatus * >( this->giveStatus(gp) );
695
696 double E, Gf, ft, Le;
697 double ef = 0.;
698 double slope;
699 double efail, c1, c2;
700
701 Le = status->giveCharLength(i);
702
703 Gf = this->giveFractureEnergy(gp, tStep);
704 ft = this->giveTensileStrength(gp, tStep);
705
706 E = this->computeOverallElasticStiffness(gp, tStep);
707
708 if ( softType == ST_NONE ) {
709 OOFEM_ERROR("For unknown reason the tensile strength has been exceeded and cracking has been initiated!");
710 } else if ( softType == ST_Exponential ) {
711 ef = Gf / ( ft * Le );
712 } else if ( softType == ST_Linear ) {
713 ef = 2. * Gf / ( ft * Le );
714 } else if ( softType == ST_Hordijk ) {
715 efail = 5.14 * Gf / ft / Le;
716 c1 = 3.;
717 c2 = 6.93;
718 // ef = ft / slope of the softening branch at the peak stress
719 ef = 1. / ( c2 / efail + ( exp(-c2) * ( c1 * c1 * c1 + 1. ) ) / efail );
720 } else if ( softType == ST_UserDefinedCrack ) {
721 ef = 1.e20;
722
723 for ( int i = 1; i < soft_w.giveSize(); i++ ) {
724 slope = ( soft_function_w.at(i + 1) - soft_function_w.at(i) ) / ( ( soft_w.at(i + 1) - soft_w.at(i) ) / Le );
725 if ( slope < 0. ) {
726 ef = min(fabs(1. / slope), ef);
727 }
728 }
729 } else if ( softType == ST_LinearHardeningStrain ) {
730 return;
731 } else if ( softType == ST_UserDefinedStrain ) {
732 ef = 1.e20;
733
734 for ( int i = 1; i < soft_eps.giveSize(); i++ ) {
735 slope = ( soft_function_eps.at(i + 1) - soft_function_eps.at(i) ) / ( soft_eps.at(i + 1) - soft_eps.at(i) );
736 if ( slope < 0. ) {
737 ef = min(fabs(1. / slope), ef);
738 }
739 }
740 } else {
741 OOFEM_ERROR("Unknown Softening Mode");
742 }
743
744 if ( ef <= ft / E ) {
745 OOFEM_WARNING("ef %e < e0 %e, this leads to material snapback in element %d, characteristic length %f (E=%e, ft=%e)", ef, ft / E, gp->giveElement()->giveGlobalNumber(), Le, E, ft);
746 }
747}
748
749
750double
751ConcreteFCM :: maxShearStress(GaussPoint *gp, TimeStep *tStep, int i) const {
752 int dir_1, dir_2;
753 double maxTau, crackOpening, wmax, scale;
754
755 if ( this->isIntactForShear(gp, i) ) {
756 return this->giveTensileStrength(gp, tStep) * fcm_BIGNUMBER;
757 }
758
759 if ( this->shearStrengthType == SHS_NONE ) {
760 maxTau = this->giveTensileStrength(gp, tStep) * fcm_BIGNUMBER;
761 } else if ( this->shearStrengthType == SHS_Const_Ft ) {
762 maxTau = this->giveTensileStrength(gp, tStep);
763 } else if ( this->shearStrengthType == SHS_Collins_Interlock ) {
764 if ( i == 4 ) { // y-z
765 dir_1 = 2;
766 dir_2 = 3;
767 } else if ( i == 5 ) { // x-z
768 dir_1 = 1;
769 dir_2 = 3;
770 } else if ( i == 6 ) { // x-y
771 dir_1 = 1;
772 dir_2 = 2;
773 } else {
774 OOFEM_ERROR("Unexpected number for shear stress (must be either 4, 5 or 6).");
775 }
776
777 // from temporary strain
778 crackOpening = max( this->computeNormalCrackOpening(gp, dir_1), this->computeNormalCrackOpening(gp, dir_2) );
779
780 // from the entire history
781 wmax = max( this->computeMaxNormalCrackOpening(gp, tStep, dir_1), this->computeMaxNormalCrackOpening(gp, tStep, dir_2) );
782
783 crackOpening = max(wmax, crackOpening);
784
785 scale = 1000. / lengthScale;
786 maxTau = 0.18 * sqrt(this->fc) / ( 0.31 + 24. * crackOpening * scale / ( this->ag * scale + 16. ) );
787
788 } else if ( this->shearStrengthType == SHS_Residual_Ft ) {
789 maxTau = this->computeResidualTensileStrength(gp, tStep);
790
791 } else {
792 OOFEM_ERROR("Unexpected shearStrengthType");
793 }
794
795 return maxTau;
796}
797
798double
799ConcreteFCM :: computeResidualTensileStrength(GaussPoint *gp, TimeStep *tStep) const {
800
801 ConcreteFCMStatus *status = static_cast< ConcreteFCMStatus * >( this->giveStatus(gp) );
802
803 double sigma;
804 int nCracks;
805 double emax;
806
807 nCracks = status->giveNumberOfTempCracks();
808
809 sigma = this->giveTensileStrength(gp, tStep);
810
811 for ( int i = 1; i <= nCracks; i++ ) {
812
813 emax = status->giveMaxCrackStrain(i);
814
815 if (emax > 0.) {
816 emax /= this->giveNumberOfCracksInDirection(gp, i);
817
818 sigma = ConcreteFCM :: giveNormalCrackingStress(gp, tStep, emax, i);
819 sigma = min( sigma, this->giveTensileStrength(gp, tStep) );
820 }
821 }
822
823 return sigma;
824}
825
826
827double
828ConcreteFCM :: give(int aProperty, GaussPoint *gp) const
829{
830 this->giveStatus(gp);
831
832 double answer;
833 if ( RandomMaterialExtensionInterface :: give(aProperty, gp, answer) ) {
834 return answer;
835 } else if ( aProperty == gf_ID ) {
836 return this->Gf;
837 } else if ( aProperty == ft_strength ) {
838 return this->Ft;
839 } else {
840 return FCMMaterial :: give(aProperty, gp);
841 }
842}
843
844
845int
846ConcreteFCM :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
847{
848
849 if ( type == IST_TensileStrength ) {
850 answer.resize(1);
851 answer.at(1) = this->giveTensileStrength(gp, tStep);
852 return 1;
853
854 } else if ( type == IST_ResidualTensileStrength ) {
855
856 answer.resize(1);
857 answer.zero();
858 answer.at(1) = this->computeResidualTensileStrength(gp, tStep);
859
860 return 1;
861 }
862
863 return FCMMaterial :: giveIPValue(answer, gp, type, tStep);
864}
865
866
868ConcreteFCM :: giveStatus(GaussPoint *gp) const
869{
870 if (gp->hasMaterialStatus()) {
871 return static_cast< MaterialStatus * >( gp->giveMaterialStatus() );
872 } else {
873 MaterialStatus *status = static_cast<MaterialStatus*> (gp->setMaterialStatus (this->CreateStatus(gp)));
874 this->_generateStatusVariables(gp);
875 return status;
876 }
877}
878
879
880
881
883// CONCRETE FCM STATUS ///
885
886ConcreteFCMStatus :: ConcreteFCMStatus(GaussPoint *gp) :
888{}
889
890
891
892void
893ConcreteFCMStatus :: printOutputAt(FILE *file, TimeStep *tStep) const
894{
895 FCMMaterialStatus :: printOutputAt(file, tStep);
896}
897
898
899
900
901
902void
903ConcreteFCMStatus :: initTempStatus()
904//
905// initializes temp variables according to variables form previous equlibrium state.
906//
907{
908 FCMMaterialStatus :: initTempStatus();
909}
910
911
912void
913ConcreteFCMStatus :: updateYourself(TimeStep *tStep)
914//
915// updates variables (nonTemp variables describing situation at previous equilibrium state)
916// after a new equilibrium state has been reached
917// temporary variables correspond to newly reched equilibrium.
918//
919{
920 FCMMaterialStatus :: updateYourself(tStep);
921}
922
923Interface *
924ConcreteFCMStatus :: giveInterface(InterfaceType type)
925{
927 return static_cast< RandomMaterialStatusExtensionInterface * >(this);
928 } else {
929 return nullptr;
930 }
931}
932
933
934void
935ConcreteFCMStatus :: saveContext(DataStream &stream, ContextMode mode)
936{
937 FCMMaterialStatus :: saveContext(stream, mode);
938}
939
940
941void
942ConcreteFCMStatus :: restoreContext(DataStream &stream, ContextMode mode)
943{
944 FCMMaterialStatus :: restoreContext(stream, mode);
945}
946
947} // end namespace oofem
#define N(a, b)
#define E(a, b)
#define REGISTER_Material(class)
double lengthScale
Collins' aggregate interlock: 1 for meter, 1000 for analysis in mm.
virtual double computeResidualTensileStrength(GaussPoint *gp, TimeStep *tStep) const
based on the maximum crack opening evaluates the residual strength
double giveTensileStrength(GaussPoint *gp, TimeStep *tStep) const override
comutes tensile strength
FloatArray beta_w
user-defined shear retention factor (with respect to crack opening)
virtual double giveFractureEnergy(GaussPoint *gp, TimeStep *tStep) const
FloatArray soft_function_eps
std::unique_ptr< MaterialStatus > CreateStatus(GaussPoint *gp) const override
double fc
Collins' aggregate interlock: compressive strength in MPa.
FloatArray soft_w
user-defined softening (traction-COD)
double ag
Collins' aggregate interlock: aggregate diameter in appropriate units (same as FE mesh).
double beta
shear retention factor
double sf
shear factor
FloatArray soft_function_w
FloatArray soft_eps
user-defined softening (traction-strain)
double sf_numer
shear factor for numerical purpose
double eps_f
strain at failure
FloatArray beta_function
double Ft
Tensile strength.
double Gf
Fracture energy.
ShearStrengthType shearStrengthType
double giveCrackingModulusInTension(MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep, int i) const override
returns stiffness in the normal direction of the i-th crack
MaterialStatus * giveStatus(GaussPoint *gp) const override
SofteningType softType
ShearRetentionType shearType
double H
hardening modulus
int giveGlobalNumber() const
Definition element.h:1129
double giveCharLength(int icrack) const
returns characteristic length associated with i-th crack direction
Definition fcm.h:162
const IntArray & giveTempCrackStatus()
returns vector of temporary crack statuses
Definition fcm.h:119
virtual int giveNumberOfTempCracks() const
returns temporary number of cracks
Definition fcm.C:2421
FCMMaterialStatus(GaussPoint *g)
Definition fcm.C:2300
double giveMaxCrackStrain(int icrack)
returns maximum crack strain for the i-th crack (equilibrated value)
Definition fcm.h:109
double giveTempCrackStrain(int icrack) const
returns i-th component of the crack strain vector (temporary)
Definition fcm.h:134
virtual double computeNormalCrackOpening(GaussPoint *gp, int i) const
uses temporary cracking strain and characteristic length to obtain the crack opening
Definition fcm.C:1130
bool multipleCrackShear
if true = takes shear compliance of all cracks, false = only dominant crack contribution,...
Definition fcm.h:281
virtual bool isIntactForShear(GaussPoint *gp, int i) const
returns true for closed or no cracks associated to given shear direction (i = 4, 5,...
Definition fcm.C:1060
virtual double giveNumberOfCracksForShearDirection(GaussPoint *gp, int i) const
returns number of cracks for given shear direction (i = 4, 5, 6) which is treated as the maximum of t...
Definition fcm.C:2051
virtual bool isIntact(GaussPoint *gp, int icrack) const
returns true for closed or no crack (i = 1, 2, 3)
Definition fcm.C:1042
virtual double giveCrackSpacing(void) const
returns either user-provided value of crack spacing or a value computed from composition
Definition fcm.C:2025
virtual double giveNumberOfCracksInDirection(GaussPoint *gp, int iCrack) const
returns number of fictiotious parallel cracks in the direction of i-th crack
Definition fcm.C:2032
virtual double computeOverallElasticShearModulus(GaussPoint *gp, TimeStep *tStep) const
returns overall shear modulus
Definition fcm.h:380
virtual double computeOverallElasticStiffness(GaussPoint *gp, TimeStep *tStep) const
returns overall Young's modulus
Definition fcm.h:377
virtual double computeMaxNormalCrackOpening(GaussPoint *gp, TimeStep *tStep, int i) const
uses maximum equilibrated cracking strain and characteristic length to obtain the maximum reached cra...
Definition fcm.C:1149
virtual double computeNumerD2Modulus(GaussPoint *gp, TimeStep *tStep, int i) const
shear modulus in a STIFFNESS MATRIX for a given shear direction (4, 5, 6)
Definition fcm.C:1927
FCMMaterial(int n, Domain *d)
Definition fcm.C:46
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
bool hasMaterialStatus(IntegrationPointStatusIDType key=IPSID_Default) const
Definition gausspoint.h:206
IntegrationPointStatus * setMaterialStatus(std::unique_ptr< IntegrationPointStatus > ptr, IntegrationPointStatusIDType key=IPSID_Default)
Definition gausspoint.h:213
IntegrationPointStatus * giveMaterialStatus(IntegrationPointStatusIDType key=IPSID_Default)
Definition gausspoint.h:204
Element * giveElement()
Returns corresponding element to receiver.
Definition gausspoint.h:187
GaussPoint * gp
Associated integration point.
void _generateStatusVariables(GaussPoint *) const
#define _IFT_ConcreteFCM_soft_function_eps
Definition concretefcm.h:58
#define _IFT_ConcreteFCM_ag
Definition concretefcm.h:53
#define _IFT_ConcreteFCM_gf
Definition concretefcm.h:47
#define _IFT_ConcreteFCM_fc
Definition concretefcm.h:52
#define _IFT_ConcreteFCM_beta_w
Definition concretefcm.h:59
#define _IFT_ConcreteFCM_sf_numer
Definition concretefcm.h:51
#define _IFT_ConcreteFCM_beta
Definition concretefcm.h:49
#define _IFT_ConcreteFCM_eps_f
Definition concretefcm.h:62
#define _IFT_ConcreteFCM_shearType
Definition concretefcm.h:45
#define _IFT_ConcreteFCM_soft_function_w
Definition concretefcm.h:56
#define _IFT_ConcreteFCM_ft
Definition concretefcm.h:48
#define _IFT_ConcreteFCM_beta_function
Definition concretefcm.h:60
#define _IFT_ConcreteFCM_soft_eps
Definition concretefcm.h:57
#define _IFT_ConcreteFCM_lengthScale
Definition concretefcm.h:54
#define _IFT_ConcreteFCM_shearStrengthType
Definition concretefcm.h:46
#define _IFT_ConcreteFCM_soft_w
Definition concretefcm.h:55
#define _IFT_ConcreteFCM_softType
Definition concretefcm.h:44
#define _IFT_ConcreteFCM_sf
Definition concretefcm.h:50
#define _IFT_ConcreteFCM_H
Definition concretefcm.h:61
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_ERROR(...)
Definition error.h:79
#define pscm_NONE
Definition fcm.h:56
#define fcm_BIGNUMBER
Definition fcm.h:63
#define _IFT_FCM_crackSpacing
Definition fcm.h:47
#define pscm_CLOSED
Definition fcm.h:60
#define fcm_SMALL_STRAIN
Definition fcm.h:62
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Definition inputrecord.h:75
#define IR_GIVE_FIELD(__ir, __value, __id)
Definition inputrecord.h:67
#define gf_ID
Definition matconst.h:85
#define ft_strength
Definition matconst.h:91
long ContextMode
Definition contextmode.h:43
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
FloatArrayF< N > max(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
@ RandomMaterialStatusExtensionInterfaceType

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