OOFEM 3.0
Loading...
Searching...
No Matches
compodamagemat.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 "compodamagemat.h"
37#include "gausspoint.h"
40#include "mathfem.h"
41#include "classfactory.h"
42#include "contextioerr.h"
43#include "crosssection.h"
44
45namespace oofem {
47
48CompoDamageMat :: CompoDamageMat(int n, Domain *d) : StructuralMaterial(n, d)
49{
50}
51
52
53void CompoDamageMat :: initializeFrom(InputRecord &ir)
54{
55 Material :: initializeFrom(ir);
56
57 double value;
58
59 //define transversely othotropic material stiffness parameters
61 propertyDictionary.add(Ex, value);
63 propertyDictionary.add(Ey, value);
64 propertyDictionary.add(Ez, value);
66 propertyDictionary.add(NYxy, value);
67 propertyDictionary.add(NYxz, value);
69 propertyDictionary.add(NYyz, value);
70 propertyDictionary.add(NYzy, value);
72 propertyDictionary.add(Gxy, value);
73 propertyDictionary.add(Gxz, value);
74
75 //calulate remaining components
76 propertyDictionary.add( Gyz, this->give(Ey, NULL) / ( 1. + this->give(NYxy, NULL) ) );
77 propertyDictionary.add( NYyx, this->give(Ey, NULL) * this->give(NYxy, NULL) / this->give(Ex, NULL) );
78 //propertyDictionary -> add(Gzy,this->give(Gyz,NULL));
79 propertyDictionary.add( NYzx, this->give(NYyx, NULL) );
80
82
83 //this->inputTension.printYourself();
85
86 if ( this->inputTension.giveSize() != 12 ) {
87 OOFEM_ERROR("need 12 components for tension in pairs f0 Gf for all 6 directions");
88 }
89
90 if ( this->inputCompression.giveSize() != 12 ) {
91 OOFEM_ERROR("need 12 components for compression in pairs f0 Gf for all 6 directions");
92 }
93
94 for ( int i = 1; i <= 12; i += 2 ) {
95 if ( this->inputTension.at(i) < 0.0 ) {
96 OOFEM_ERROR("negative f0 detected for tension");
97 }
98
99 if ( this->inputCompression.at(i) > 0.0 ) {
100 OOFEM_ERROR("positive f0 detected for compression");
101 }
102 }
103
104 this->afterIter = 0;
106
107 this->afterIter = 0;
109}
110
111void CompoDamageMat :: giveInputRecord(DynamicInputRecord &input)
112{
113 StructuralMaterial :: giveInputRecord(input);
114 OOFEM_ERROR("Not implemented yet");
115}
116
117
118//called at the beginning of each time increment (not iteration), no influence of parameter
120CompoDamageMat :: give3dMaterialStiffnessMatrix(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const
121{
122
123 //already with reduced components
124 auto d = this->giveUnrotated3dMaterialStiffnessMatrix(mode, gp);
125 FloatMatrixF<6,6> rotationMatrix;
126 if ( this->giveMatStiffRotationMatrix(rotationMatrix, gp) ) { //material rotation due to lcs
127 d = rotate(d, rotationMatrix);
128 }
129 return d;
130}
131
132//called in each iteration, support for 3D and 1D material mode
133void CompoDamageMat :: giveRealStressVector(FloatArray &answer, GaussPoint *gp, const FloatArray &totalStrain, TimeStep *tStep) const
134{
135 int i_max, s;
136 double delta, sigma, charLen, tmp = 0., Gf_tmp;
137 CompoDamageMatStatus *st = static_cast< CompoDamageMatStatus * >( this->giveStatus(gp) );
138 Element *element = gp->giveElement();
139 FloatArray strainVectorL(6), stressVectorL(6), tempStressVectorL(6), reducedTotalStrainVector(6), ans, equilStressVectorL(6), equilStrainVectorL(6), charLenModes(6);
140 FloatArray *inputFGf;
141 FloatMatrix de, elementCs(3, 3);
142 MaterialMode mMode = gp->giveMaterialMode();
143
144 st->Iteration++; //increase the call number at IP
145
146 //subtract strain independent part - temperature, creep ..., in global c.s.
147 this->giveStressDependentPartOfStrainVector(reducedTotalStrainVector, gp, totalStrain, tStep, VM_Total);
148 //reducedTotalStrainVector.printYourself();
149
150 switch ( mMode ) {
151 case _3dMat: //applies only for 3D
152 {
153 if ( !element->giveLocalCoordinateSystem(elementCs) ) { //lcs undefined
154 elementCs.resize(3, 3);
155 elementCs.beUnitMatrix();
156 }
157
158 //first run
159 if ( st->elemCharLength.at(1) == 0. ) {
160 this->giveCharLength(st, gp, elementCs);
161 //check that no snap-back occurs due to large element characteristic length (fixed-crack orientation)
162 //see Bazant, Planas: Fracture and Size Effect, pp. 251
163 this->checkSnapBack(gp, mMode);
164 }
165
166 //transform strain to local c.s.
167 strainVectorL = this->transformStrainVectorTo(elementCs, reducedTotalStrainVector, 0);
168 //strainVectorL.printYourself();
169
170 //damage criteria based on stress, assuming same damage parameter for tension/compression
171 //determine unequilibrated stress vector
172 de = this->giveUnrotated3dMaterialStiffnessMatrix(SecantStiffness, gp);
173 tempStressVectorL.beProductOf(de, strainVectorL);
174 i_max = 6;
175 break;
176 }
177
178 case _1dMat:
179 { //applies only for 1D, strain vectors are already in local c.s.
180 if ( st->elemCharLength.at(1) == 0. ) {
181 FloatArray normal(0);
182 st->elemCharLength.at(1) = gp->giveElement()->giveCharacteristicLength(normal); //truss length
183 this->checkSnapBack(gp, mMode);
184 }
185
186 strainVectorL.at(1) = reducedTotalStrainVector.at(1);
187 tempStressVectorL.zero();
188 tempStressVectorL.at(1) = this->give(Ex, NULL) * strainVectorL.at(1);
189 i_max = 1;
190 break;
191 }
192 default:
193 {
194 OOFEM_ERROR("Material mode %s not supported", __MaterialModeToString(mMode) );
195 }
196 }
197
198 //proceed 6 components for 3D or 1 component for 1D, damage evolution is based on the evolution of strains
199 //xx, yy, zz, yz, zx, xy
200 for ( int i = 1; i <= i_max; i++ ) {
201 if ( tempStressVectorL.at(i) >= 0. ) { //unequilibrated stress, tension
202 inputFGf = & inputTension; //contains pairs (stress - fracture energy)
203 s = 0;
204 } else { //unequilibrated stress, compression
205 inputFGf = & inputCompression;
206 s = 6;
207 }
208
209 if ( ( fabs( tempStressVectorL.at(i) ) > fabs( ( * inputFGf ).at(2 * i - 1) ) ) && ( st->strainAtMaxStress.at(i + s) == 0. ) && ( st->Iteration > this->afterIter ) ) { //damage initiated now, can be replaced for more advanced initiation criteria, e.g. Hill's maximum combination of stresses
210 //equilibrated strain and stress from the last time step, transform to local c.s.
211 switch ( mMode ) {
212 case _3dMat:
213 ans = st->giveStrainVector();
214 equilStrainVectorL = this->transformStrainVectorTo(elementCs, ans, 0);
215 ans = st->giveStressVector();
216 equilStressVectorL = this->transformStressVectorTo(elementCs, ans, 0);
217 break;
218
219 case _1dMat:
220 equilStrainVectorL = st->giveStrainVector();
221 equilStressVectorL = st->giveStressVector();
222 break;
223
224 default:
225 OOFEM_ERROR("Material mode %s not supported", __MaterialModeToString(mMode) );
226 }
227
228 //subdivide last increment, interpolate, delta in range <0;1>
229 delta = ( ( * inputFGf ).at(2 * i - 1) - equilStressVectorL.at(i) ) / ( tempStressVectorL.at(i) - equilStressVectorL.at(i) );
230 delta = min(delta, 1.);
231 delta = max(delta, 0.); //stabilize transition from tensile to compression (denom -> 0)
232
233 st->strainAtMaxStress.at(i + s) = equilStrainVectorL.at(i) + delta * ( strainVectorL.at(i) - equilStrainVectorL.at(i) );
234
235 st->initDamageStress.at(i + s) = equilStressVectorL.at(i) + delta * ( tempStressVectorL.at(i) - equilStressVectorL.at(i) );
236
237 //determine characteristic length for six stresses/strains
238 this->giveCharLengthForModes(charLenModes, gp);
239 charLen = charLenModes.at(i);
240
241 //determine maximum strain at zero stress based on fracture energy - mode I, linear softening
242 //st->maxStrainAtZeroStress.at(i + s) = st->strainAtMaxStress.at(i + s) + 2 * fabs( ( * inputFGf ).at(2 * i) ) / charLen / st->initDamageStress.at(i + s); //Gf scaled for characteristic size
243 //st->maxStrainAtZeroStress.at(i + s) = 2 * fabs( ( * inputFGf ).at(2 * i) ) / charLen / st->initDamageStress.at(i + s); //Gf scaled for characteristic size
244 //st->maxStrainAtZeroStress.at(i + s) = 2 * fabs( ( * inputFGf ).at(2 * i) ) / charLen / st->initDamageStress.at(i + s);
245
246 switch ( i ) {
247 case 1: tmp = this->give(Ex, NULL);
248 break;
249 case 2: tmp = this->give(Ey, NULL);
250 break;
251 case 3: tmp = this->give(Ez, NULL);
252 break;
253 case 4: tmp = this->give(Gyz, NULL);
254 break;
255 case 5: tmp = this->give(Gxz, NULL);
256 break;
257 case 6: tmp = this->give(Gxy, NULL);
258 break;
259 }
260
261 //remaining fracture energy for the softening part in [N/m], calculated as a 1D case
262 Gf_tmp = ( * inputFGf ).at(2 * i) - st->initDamageStress.at(i + s) * st->initDamageStress.at(i + s) * charLen / 2. / tmp;
263
264 if ( Gf_tmp < 0. ) {
265 OOFEM_WARNING("Too large initiation trial stress in element %d, component %d, |%f| < |%f|=f_t, negative remaining Gf=%f, treated as a snap-back", gp->giveElement()->giveNumber(), s == 0 ? i : -i, st->initDamageStress.at(i + s), tempStressVectorL.at(i), Gf_tmp);
266 st->hasSnapBack.at(i) = 1;
267 }
268
269 st->maxStrainAtZeroStress.at(i + s) = st->strainAtMaxStress.at(i + s) + 2 * Gf_tmp / charLen / st->initDamageStress.at(i + s); //scaled for element's characteristic size
270
271 //check the snap-back
272 if ( fabs( st->maxStrainAtZeroStress.at(i + s) ) < fabs( st->strainAtMaxStress.at(i + s) ) && st->hasSnapBack.at(i) == 0 ) {
273 OOFEM_WARNING( "Snap-back occured in element %d, component %d, |elastic strain=%f| > |fracturing strain %f|", gp->giveElement()->giveNumber(), s == 0 ? i : -i, st->strainAtMaxStress.at(i + s), st->maxStrainAtZeroStress.at(i + s) );
274 st->hasSnapBack.at(i) = 1;
275 }
276 }
277
278 if ( st->strainAtMaxStress.at(i + s) != 0. && fabs( strainVectorL.at(i) ) > fabs( st->kappa.at(i + s) ) ) { //damage started and grows
279 //OOFEM_LOG_INFO("Damage at strain %f and stress %f (i=%d, s=%d) in GP %d element %d\n", st->strainAtMaxStress.at(i + s), tempStressVectorL.at(i), i, s,gp->giveNumber(), gp->giveElement()->giveNumber() );
280 //desired stress
281 sigma = st->initDamageStress.at(i + s) * ( st->maxStrainAtZeroStress.at(i + s) - strainVectorL.at(i) ) / ( st->maxStrainAtZeroStress.at(i + s) - st->strainAtMaxStress.at(i + s) );
282
283 //check that sigma remains in tension/compression area
284 if ( s == 0 ) { //tension
285 sigma = max(sigma, 0.000001);
286 } else {
287 sigma = min(sigma, -0.000001);
288 }
289
290 switch ( i ) { //need to subtract contributions from strains
291 //in equations we use nu12 = E11/E22*nu21, nu13 = E11/E33*nu31, nu23 = E22/E33*nu32
292 case 1: tmp = 1. - sigma / ( this->give(Ex, NULL) * strainVectorL.at(i) + this->give(NYxy, NULL) * tempStressVectorL.at(2) + this->give(NYxz, NULL) * tempStressVectorL.at(3) );
293 break;
294 case 2: tmp = 1. - sigma / ( this->give(Ey, NULL) * strainVectorL.at(i) + this->give(NYyx, NULL) * tempStressVectorL.at(1) + this->give(NYyz, NULL) * tempStressVectorL.at(3) );
295 break;
296 case 3: tmp = 1. - sigma / ( this->give(Ez, NULL) * strainVectorL.at(i) + this->give(NYzx, NULL) * tempStressVectorL.at(1) + this->give(NYzy, NULL) * tempStressVectorL.at(2) );
297 break;
298 case 4: tmp = 1. - sigma / this->give(Gyz, NULL) / strainVectorL.at(i);
299 break;
300 case 5: tmp = 1. - sigma / this->give(Gxz, NULL) / strainVectorL.at(i);
301 break;
302 case 6: tmp = 1. - sigma / this->give(Gxy, NULL) / strainVectorL.at(i);
303 break;
304 }
305
306 st->tempOmega.at(i) = max( tmp, st->omega.at(i) ); //damage can only grow, interval <0;1>
307 st->tempOmega.at(i) = min(st->tempOmega.at(i), 0.9999);
308 st->tempOmega.at(i) = max(st->tempOmega.at(i), 0.0000);
309 st->tempKappa.at(i + s) = strainVectorL.at(i);
310
311 if ( st->hasSnapBack.at(i) == 1 ) {
312 st->tempOmega.at(i) = 0.9999;
313 }
314 }
315 }
316
317 switch ( mMode ) {
318 case _3dMat: {
319 //already with reduced stiffness components in local c.s.
320 de = this->giveUnrotated3dMaterialStiffnessMatrix(SecantStiffness, gp);
321 //de.printYourself();
322 //in local c.s.
323 stressVectorL.beProductOf(de, strainVectorL);
324 //stressVectorL.printYourself();
325 //transform local c.s to global c.s.
326 st->tempStressMLCS = stressVectorL;
327 answer = this->transformStressVectorTo(elementCs, stressVectorL, 1);
328 break;
329 }
330 case _1dMat: {
331 answer.resize(1);
332 answer.at(1) = ( 1 - st->tempOmega.at(1) ) * this->give(Ex, NULL) * strainVectorL.at(1); //tempStress
333 st->tempStressMLCS.at(1) = answer.at(1);
334 break;
335 }
336 default:
337 OOFEM_ERROR("Material mode not supported");
338 }
339
340 st->letTempStressVectorBe(answer); //needed in global c.s for 3D
341
342 //not changed inside this function body
343 st->letTempStrainVectorBe(totalStrain); //needed in global c.s for 3D
344}
345
346//used for output in *.hom a *.out
347int CompoDamageMat :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
348{
349 CompoDamageMatStatus *status = static_cast< CompoDamageMatStatus * >( this->giveStatus(gp) );
350 if ( type == IST_DamageTensor ) {
351 answer = status->omega;
352 } else {
353 StructuralMaterial :: giveIPValue(answer, gp, type, tStep);
354 }
355
356 return 1;
357}
358
359FloatMatrixF<6,6> CompoDamageMat :: giveUnrotated3dMaterialStiffnessMatrix(MatResponseMode mode, GaussPoint *gp) const
360{
361 double denom;
362 double ex, ey, ez, nxy, nxz, nyz, gyz, gzx, gxy;
363 double a, b, c, d, e, f;
364 FloatArray tempOmega;
365
366 FloatMatrixF<6,6> answer;
367
368 CompoDamageMatStatus *st = static_cast< CompoDamageMatStatus * >( this->giveStatus(gp) );
369
370 ex = this->give(Ex, NULL);
371 ey = this->give(Ey, NULL);
372 ez = this->give(Ez, NULL);
373 nxy = this->give(NYxy, NULL);
374 nxz = nxy;
375 nyz = this->give(NYyz, NULL);
376 gyz = this->give(Gyz, NULL);
377 gzx = this->give(Gxz, NULL);
378 gxy = this->give(Gxy, NULL);
379
380 //xx, yy, zz, yz, zx, xy
381 //assemble stiffness matrix for transversely orthotropic material with reduced moduli, derived from compliance matrix with only reduced diagonal terms. Procedure can be used for fully orthotropic stiffness matrix as well
382 a = 1. - st->tempOmega.at(1);
383 b = 1. - st->tempOmega.at(2);
384 c = 1. - st->tempOmega.at(3);
385 d = 1. - st->tempOmega.at(4);
386 e = 1. - st->tempOmega.at(5);
387 f = 1. - st->tempOmega.at(6);
388
389 if ( mode == ElasticStiffness ) {
390 a = b = c = d = e = f = 0.;
391 }
392
393 denom = -ey * ex + ex * nyz * nyz * b * c * ez + nxy * nxy * a * b * ey * ey + 2 * nxy * a * b * ey * nxz * nyz * c * ez + nxz * nxz * a * ey * c * ez;
394
395 answer.at(1, 1) = ( -ey + nyz * nyz * b * c * ez ) * a * ex * ex / denom;
396 answer.at(1, 2) = -( nxy * ey + nxz * nyz * c * ez ) * ex * ey * a * b / denom;
397 answer.at(1, 3) = -( nxy * nyz * b + nxz ) * ey * ex * a * c * ez / denom;
398 answer.at(2, 2) = ( -ex + nxz * nxz * a * c * ez ) * b * ey * ey / denom;
399 answer.at(2, 3) = -( nyz * ex + nxz * nxy * a * ey ) * ey * b * c * ez / denom;
400 answer.at(3, 3) = ( -ex + nxy * nxy * a * b * ey ) * ey * c * ez / denom;
401 answer.at(4, 4) = gyz;
402 answer.at(5, 5) = gzx;
403 answer.at(6, 6) = gxy;
404 answer.symmetrized();
405 //answer.printYourself();
406 return answer;
407}
408
409//returns material rotation stiffness matrix [6x6]
410int CompoDamageMat :: giveMatStiffRotationMatrix(FloatMatrixF<6,6> &answer, GaussPoint *gp) const
411{
412 FloatMatrix Lt(3, 3);
413 StructuralElement *element = static_cast< StructuralElement * >( gp->giveElement() );
414 MaterialMode mMode = gp->giveMaterialMode();
415
416 switch ( mMode ) {
417 case _1dMat: //do not rotate 1D materials on trusses and beams
418 break;
419 case _3dMat:
420 if ( !element->giveLocalCoordinateSystem(Lt) ) { //lcs not defined on element
421 return 0;
422 }
423
424 //rotate from unrotated (base) c.s. to local material c.s.
425 answer = this->giveStrainVectorTranformationMtrx(Lt);
426 return 1;
427
428 break;
429 default:
430 OOFEM_ERROR("Material mode %s not supported", __MaterialModeToString(mMode) );
431 }
432
433 return 0;
434}
435
436// determine characteristic fracture area for three orthogonal cracks, based on the size of element (crack band model).
437// Since the orientation of cracks is aligned with the orientation of material, determination is based only on the geometry (not on the direction of principal stress etc.).
438// Assumption that fracture localizes into all integration points on element.
439// Material orientation in global c.s. is passed. Called in the first run
440void CompoDamageMat :: giveCharLength(CompoDamageMatStatus *status, GaussPoint *gp, FloatMatrix &elementCs) const
441{
442 FloatArray crackPlaneNormal(3);
443
444 //elementCs.printYourself();
445
446 //normal to x,y,z is the same as in elementCs
447
448 for ( int i = 1; i <= 3; i++ ) {
449 for ( int j = 1; j <= 3; j++ ) {
450 crackPlaneNormal.at(j) = elementCs.at(j, i);
451 }
452
453 status->elemCharLength.at(i) = gp->giveElement()->giveCharacteristicLength(crackPlaneNormal);
454 }
455}
456
457//determine characteristic length for six stresses/strains in their modes
458void
459CompoDamageMat :: giveCharLengthForModes(FloatArray &charLenModes, GaussPoint *gp) const
460{
461 CompoDamageMatStatus *st = static_cast< CompoDamageMatStatus * >( this->giveStatus(gp) );
462
463 charLenModes.resize(6);
464 charLenModes.at(1) = st->elemCharLength.at(1);
465 charLenModes.at(2) = st->elemCharLength.at(2);
466 charLenModes.at(3) = st->elemCharLength.at(3);
467 charLenModes.at(4) = ( st->elemCharLength.at(2) + st->elemCharLength.at(3) ) / 2.; //average two directions
468 charLenModes.at(5) = ( st->elemCharLength.at(3) + st->elemCharLength.at(1) ) / 2.; //average two directions
469 charLenModes.at(6) = ( st->elemCharLength.at(1) + st->elemCharLength.at(2) ) / 2.; //average two directions
470}
471
472//check that elemnt is small enough to prevent snap-back
473void CompoDamageMat :: checkSnapBack(GaussPoint *gp, MaterialMode mMode) const
474{
475 CompoDamageMatStatus *st = static_cast< CompoDamageMatStatus * >( this->giveStatus(gp) );
476 FloatArray charLenModes(6);
477 FloatArray *inputFGf;
478 double l_ch, ft, Gf, elem_h, modulus = -1.0;
479
480 for ( int j = 0; j <= 1; j++ ) {
481 if ( j == 0 ) {
482 inputFGf = & inputTension;
483 } else {
484 inputFGf = & inputCompression;
485 }
486
487 switch ( mMode ) {
488 case _3dMat:
489 this->giveCharLengthForModes(charLenModes, gp);
490 for ( int i = 1; i <= 6; i++ ) {
491 ft = fabs( ( * inputFGf ).at(2 * i - 1) );
492 Gf = ( * inputFGf ).at(2 * i);
493 switch ( i ) {
494 case 1:
495 modulus = this->give(Ex, NULL);
496 break;
497 case 2:
498 modulus = this->give(Ey, NULL);
499 break;
500 case 3:
501 modulus = this->give(Ez, NULL);
502 break;
503 case 4:
504 modulus = this->give(Gyz, NULL);
505 break;
506 case 5:
507 modulus = this->give(Gxz, NULL);
508 break;
509 case 6:
510 modulus = this->give(Gxy, NULL);
511 break;
512 }
513
514 l_ch = modulus * Gf / ft / ft;
515 elem_h = charLenModes.at(i);
516 if ( elem_h > 2 * l_ch ) {
517 if ( this->allowSnapBack.contains(i + 6 * j) ) {
518 OOFEM_LOG_INFO("Allowed snapback of 3D element %d GP %d Gf(%d)=%f, would need Gf>%f\n", gp->giveElement()->giveGlobalNumber(), gp->giveNumber(), j == 0 ? i : -i, Gf, ft * ft * elem_h / 2 / modulus);
519 } else {
520 OOFEM_ERROR("Decrease size of 3D element %d or increase Gf(%d)=%f to Gf>%f, possible snap-back problems", gp->giveElement()->giveNumber(), j == 0 ? i : -i, Gf, ft * ft * elem_h / 2 / modulus);
521 }
522 }
523 }
524
525 break;
526 case _1dMat:
527 ft = fabs( ( * inputFGf ).at(1) );
528 Gf = ( * inputFGf ).at(2);
529 modulus = this->give(Ex, NULL);
530 l_ch = modulus * Gf / ft / ft;
531 elem_h = st->elemCharLength.at(1);
532 if ( elem_h > 2 * l_ch ) {
534 if ( this->allowSnapBack.contains(1 + 6 * j) ) {
535 OOFEM_LOG_INFO("Allowed snapback of 1D element %d GP %d Gf(%d)=%f, would need Gf>%f\n", gp->giveElement()->giveGlobalNumber(), gp->giveNumber(), j == 0 ? 1 : -1, Gf, ft * ft * elem_h / 2 / modulus);
536 } else {
537 OOFEM_ERROR("Decrease size of 1D element %d or increase Gf(%d)=%f to Gf>%f, possible snap-back problems", gp->giveElement()->giveNumber(), j == 0 ? 1 : -1, Gf, ft * ft * elem_h / 2 / modulus);
538 }
539 }
540
541 break;
542 default:
543 OOFEM_ERROR("Material mode %s not supported", __MaterialModeToString(mMode) );
544 }
545 }
546}
547
548// constructor
549CompoDamageMatStatus :: CompoDamageMatStatus(GaussPoint *g) : StructuralMaterialStatus(g)
550{
551 //largest strain ever reached [6 tension, 6 compression]
552 this->kappa.resize(12);
553 this->kappa.zero();
554 this->tempKappa.resize(12);
555 this->tempKappa.zero();
556
557 //array of damage parameters [6] for both tension and compression
558 this->omega.resize(6);
559 this->omega.zero();
560 this->tempOmega.resize(6);
561 this->tempOmega.zero();
562 this->hasSnapBack.resize(6);
563 this->hasSnapBack.zero();
564
565 this->initDamageStress.resize(12);
566 this->initDamageStress.zero();
567 this->maxStrainAtZeroStress.resize(12);
568 this->maxStrainAtZeroStress.zero();
569 this->strainAtMaxStress.resize(12);
570 this->strainAtMaxStress.zero();
571
572 this->tempStressMLCS.resize(6);
573 this->tempStressMLCS.zero();
574
575 this->elemCharLength.resize(3);
576 this->elemCharLength.zero();
577}
578
579
580void CompoDamageMatStatus :: printOutputAt(FILE *file, TimeStep *tStep) const
581{
582 int maxComponents = 0;
583 StructuralMaterialStatus :: printOutputAt(file, tStep);
584 fprintf(file, "status {");
585 switch ( gp->giveMaterialMode() ) {
586 case _3dMat: {
587 maxComponents = 6;
588 break;
589 }
590 case _1dMat: {
591 maxComponents = 1;
592 break;
593 }
594 default:
595 OOFEM_ERROR("Material mode not supported");
596 }
597
598 if ( !this->omega.containsOnlyZeroes() ) {
599 fprintf(file, " omega ");
600 for ( int i = 1; i <= maxComponents; i++ ) {
601 fprintf( file, "%.4f ", this->omega.at(i) );
602 }
603 }
604
605 fprintf(file, " Local_stress ");
606 for ( int i = 1; i <= maxComponents; i++ ) {
607 fprintf( file, "%.2e ", this->tempStressMLCS.at(i) );
608 }
609
610 fprintf(file, " kappa "); //print pairs tension-compression
611 for ( int i = 1; i <= maxComponents; i++ ) {
612 for ( int j = 0; j < 2; j++ ) {
613 fprintf( file, "%.2e ", this->kappa.at(6 * j + i) );
614 }
615 }
616
617 fprintf(file, "}\n");
618}
619
620
621//initializes temp variables according to variables form previous equilibrium state, resets tempStressVector, tempStrainVector
622//function called at the beginning of each time increment (not iteration)
623void CompoDamageMatStatus :: initTempStatus()
624{ }
625
626// updates variables (nonTemp variables describing situation at previous equilibrium state)
627// after a new equilibrium state has been reached
628// temporary variables are having values corresponding to newly reached equilibrium
629void CompoDamageMatStatus :: updateYourself(TimeStep *tStep)
630{
631 //here stressVector = tempStressVector; strainVector = tempStrainVector;
632 StructuralMaterialStatus :: updateYourself(tStep); //MaterialStatus::updateYourself, i.e. stressVector = tempStressVector; strainVector = tempStrainVector;
633 this->kappa = this->tempKappa;
634 this->omega = this->tempOmega;
635 this->Iteration = 0;
636}
637
638
639void CompoDamageMatStatus :: saveContext(DataStream &stream, ContextMode mode)
640{
641 StructuralMaterialStatus :: saveContext(stream, mode);
642}
643
644void CompoDamageMatStatus :: restoreContext(DataStream &stream, ContextMode mode)
645{
646 StructuralMaterialStatus :: restoreContext(stream, mode);
647}
648} // end namespace oofem
#define REGISTER_Material(class)
FloatArray initDamageStress
Stress at which damage starts. For uniaxial loading is equal to given maximum stress in the input....
FloatArray tempKappa
Highest strain ever reached at IP. Can be unequilibrated from last iterations [6 tension,...
FloatArray elemCharLength
Characteristic element length at IP in three perpendicular planes aligned with material orientation.
FloatArray kappa
Highest strain ever reached in all previous equilibrated steps [6 tension, 6 compression].
FloatArray tempStressMLCS
Only for printing purposes in CompoDamageMatStatus.
FloatArray strainAtMaxStress
Strain when damage is initiated at IP. In literature denoted eps_0 [6 tension, 6 compression].
IntArray hasSnapBack
Checks whether snapback occurred at IP.
int Iteration
Iteration in the time step.
FloatArray omega
Highest damage ever reached in all previous equilibrated steps at IP [6 for tension and compression].
FloatArray maxStrainAtZeroStress
Maximum strain when stress becomes zero due to complete damage (omega = 1) at IP. Determined from fra...
FloatArray tempOmega
Highest damage ever reached at IP. Can be unequilibrated from last iterations [6 for tension and comp...
void giveCharLengthForModes(FloatArray &charLenModes, GaussPoint *gp) const
IntArray allowSnapBack
Stress components which are allowed for snap back [6 tension, 6 compression].
FloatArray inputTension
Six stress components of tension components read from the input file.
int giveMatStiffRotationMatrix(FloatMatrixF< 6, 6 > &answer, GaussPoint *gp) const
void checkSnapBack(GaussPoint *gp, MaterialMode mMode) const
void giveCharLength(CompoDamageMatStatus *status, GaussPoint *gp, FloatMatrix &elementCs) const
FloatMatrixF< 6, 6 > giveUnrotated3dMaterialStiffnessMatrix(MatResponseMode mode, GaussPoint *gp) const
FloatArray inputCompression
Six stress components of compression components read from the input file.
int giveGlobalNumber() const
Definition element.h:1129
virtual double giveCharacteristicLength(const FloatArray &normalToCrackPlane)
Definition element.h:938
virtual int giveLocalCoordinateSystem(FloatMatrix &answer)
Definition element.C:1252
int giveNumber() const
Definition femcmpnn.h:104
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
double at(std::size_t i, std::size_t j) const
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
double at(std::size_t i, std::size_t j) const
void beUnitMatrix()
Sets receiver to unity matrix.
int giveNumber()
Returns number of receiver.
Definition gausspoint.h:183
MaterialMode giveMaterialMode()
Returns corresponding material mode of receiver.
Definition gausspoint.h:190
Element * giveElement()
Returns corresponding element to receiver.
Definition gausspoint.h:187
int & at(std::size_t i)
Definition intarray.h:104
GaussPoint * gp
Associated integration point.
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Definition material.C:206
Dictionary propertyDictionary
Definition material.h:107
virtual double give(int aProperty, GaussPoint *gp) const
Definition material.C:51
const FloatArray & giveStrainVector() const
Returns the const pointer to receiver's strain vector.
StructuralMaterialStatus(GaussPoint *g)
Constructor. Creates new StructuralMaterialStatus with IntegrationPoint g.
const FloatArray & giveStressVector() const
Returns the const pointer to receiver's stress vector.
void letTempStressVectorBe(const FloatArray &v)
Assigns tempStressVector to given vector v.
void letTempStrainVectorBe(const FloatArray &v)
Assigns tempStrainVector to given vector v.
StructuralMaterial(int n, Domain *d)
static FloatMatrixF< 6, 6 > giveStrainVectorTranformationMtrx(const FloatMatrixF< 3, 3 > &base, bool transpose=false)
static FloatArrayF< 6 > transformStrainVectorTo(const FloatMatrixF< 3, 3 > &base, const FloatArrayF< 6 > &strain, bool transpose=false)
void giveStressDependentPartOfStrainVector(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedStrainVector, TimeStep *tStep, ValueModeType mode) const
static FloatArrayF< 6 > transformStressVectorTo(const FloatMatrixF< 3, 3 > &base, const FloatArrayF< 6 > &stress, bool transpose=false)
#define _IFT_CompoDamageMat_afteriter
#define _IFT_CompoDamageMat_nuyz
#define _IFT_CompoDamageMat_Gxy
#define _IFT_CompoDamageMat_nuxynuxz
#define _IFT_CompoDamageMat_exx
#define _IFT_CompoDamageMat_allowSnapBack
#define _IFT_CompoDamageMat_compres_f0_gf
#define _IFT_CompoDamageMat_eyyezz
#define _IFT_CompoDamageMat_tension_f0_gf
#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 OOFEM_LOG_INFO(...)
Definition logger.h:143
#define Ey
Definition matconst.h:60
#define NYyz
Definition matconst.h:52
#define Ez
Definition matconst.h:61
#define Gxz
Definition matconst.h:71
#define NYxy
Definition matconst.h:53
#define NYxz
Definition matconst.h:51
#define NYyx
Definition matconst.h:56
#define NYzy
Definition matconst.h:55
#define Gyz
Definition matconst.h:70
#define Ex
Definition matconst.h:59
#define NYzx
Definition matconst.h:54
#define Gxy
Definition matconst.h:72
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)
FloatMatrixF< M, M > rotate(FloatMatrixF< N, N > &a, const FloatMatrixF< N, M > &r)
Computes .

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