OOFEM 3.0
Loading...
Searching...
No Matches
frcfcmnl.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 "frcfcmnl.h"
36#include "gausspoint.h"
37#include "mathfem.h"
38#include "classfactory.h"
39#include "contextioerr.h"
40#include "datastream.h"
41#include "node.h"
42
43#include "nonlocalmaterialext.h"
44
46
47#include "floatmatrix.h"
48#include "floatarray.h"
49
50#include "dynamicinputrecord.h"
52#include "stressvector.h"
53#include "strainvector.h"
54
55
56namespace oofem {
58
59FRCFCMNL :: FRCFCMNL(int n, Domain *d) : FRCFCM(n, d), StructuralNonlocalMaterialExtensionInterface(d)
60{}
61
62
63void
64FRCFCMNL :: initializeFrom(InputRecord &ir)
65{
66 FRCFCM :: initializeFrom(ir);
67 StructuralNonlocalMaterialExtensionInterface :: initializeFrom(ir);
68 // IR_GIVE_FIELD(ir, participAngle, _IFT_FRCFCMNL_participAngle);
69 participAngle = 90.;
70}
71
72
73void
74FRCFCMNL :: giveRealStressVector(FloatArray &answer, GaussPoint *gp,
75 const FloatArray &totalStrain,
76 TimeStep *tStep) const
77{
78 // first try conventional way as if no sourrounding cracks existed
79 FCMMaterial :: giveRealStressVector(answer, gp, totalStrain, tStep);
80
81 FRCFCMNLStatus *status = static_cast< FRCFCMNLStatus * >( this->giveStatus(gp) );
82 int numberOfActiveCracks = status->giveNumberOfTempCracks();
83
84 double sigma_f_nonlocal = 0.;
85
86 FloatArray sigma, crackVec;
87 FloatMatrix sigmaL2G, sigmaG2L, crackDirs;
88 double sigma_f_local = 0.;
89 double crackStrain;
90
91 if ( numberOfActiveCracks == 0 ) {
92 sigma_f_nonlocal = this->computeNonlocalStressInFibersInUncracked(gp, tStep);
93 sigma_f_nonlocal = max( sigma_f_nonlocal, status->giveFiberStressNL(1) );
94 status->setTempFiberStressNL(1, sigma_f_nonlocal);
95
96 return;
97 } else {
98 sigma = answer; // global stress
99
100
101 sigmaL2G = status->giveL2GStressVectorTransformationMtrx();
102
103
104 sigmaG2L = status->giveG2LStressVectorTransformationMtrx();
105
106 sigma.rotatedWith(sigmaG2L, 'n'); // global stress transformed to local stress
107
108 sigma_f_local = 0.;
109
110 for ( int iCrack = 1; iCrack <= ( status->giveNumberOfTempCracks() ); iCrack++ ) {
111 // get cracking strain for i-th crack
112 crackStrain = status->giveTempCrackStrain(iCrack);
113
114 if ( crackStrain > 0. ) {
115 // get local fiber stress
116 sigma_f_local = this->computeStressInFibersInCracked(gp, tStep, crackStrain, iCrack);
117 // set local fiber stress to status
118 status->setTempFiberStressLoc(iCrack, sigma_f_local);
119 } else {
120 // set zero fiber stress
121 status->setTempFiberStressLoc(iCrack, 0.);
122 }
123
124 // and compare it to stress from surroundings sigma_f_nonlocal
125
126 crackDirs = status->giveCrackDirs();
127
128 crackVec.resize( status->giveMaxNumberOfCracks(gp) );
129 crackVec.zero();
130
131 for ( int i = 1; i <= status->giveMaxNumberOfCracks(gp); i++ ) {
132 crackVec.at(i) = crackDirs.at(i, iCrack);
133 }
134
135 // compute nonlocal stress
136 sigma_f_nonlocal = this->computeNonlocalStressInFibers(crackVec, gp, tStep);
137
138 //test !!!!
139 sigma_f_nonlocal = max( sigma_f_nonlocal, status->giveFiberStressNL(iCrack) );
140
141
142 // set nonlocal fiber stress to status
143 status->setTempFiberStressNL(iCrack, sigma_f_nonlocal);
144
145 sigma.at(iCrack) += sigma_f_nonlocal;
146 } // loop over crack directions
147
148 sigma.rotatedWith(sigmaL2G, 'n'); // modified local stress transformed to global stress
149
150 answer = sigma;
151 status->letTempStressVectorBe(sigma);
152 }
153
154 return;
155}
156
157
158
159
161double
162FRCFCMNL :: computeDebondedLength(double delta) const {
163 double a = 0.;
164
165 if ( this->fiberType == FT_CAF ) { // continuous aligned fibers
166 a = sqrt( ( this->Ef * this->Df * delta ) / ( 2. * this->tau_0 * ( 1. + this->eta ) ) );
167 } else if ( this->fiberType == FT_SAF ) { // short aligned fibers
168 // no snubbing here - debonding length is simply related to pull-out displacement and not to force...
169
170 a = sqrt( ( this->Ef * this->Df * delta ) / ( 2. * this->tau_0 * ( 1. + this->eta ) ) );
171 // threshold is related to the fibre length
172 a = min( a, this->Lf / ( 2. * ( 1. + this->eta ) ) );
173 } else if ( this->fiberType == FT_SRF ) { // short random fibers
174 a = sqrt( ( this->Ef * this->Df * delta ) / ( 2. * this->tau_0 * ( 1. + this->eta ) ) );
175 // threshold is related to the fibre length
176 a = min( a, this->Lf / ( 2. * ( 1. + this->eta ) ) );
177 } else {
178 OOFEM_ERROR("Unknown fiber type");
179 }
180
181 return a;
182}
183
184
185double
186FRCFCMNL :: computeDecreaseInFibreStress(double distance, double delta, double targetDebondedLength) const {
187 // compute decrease in fiber stress due to stress transfer to matrix
188 // delta_sigma_f = 4 * tau_eff * Vf * Xca'/ ( Df * ( 1 - Vf))
189 // Xca' = ( 4 * x^2 - 4 * x * Lf ) / ( -2 * pi * Lf * lambda )
190 // lambda = 4 / ( pi * g )
191 // where x is the distance from the crack, in this case the distance between the gauss-points
192
193
194 double delta_sigma_f = 0.;
195 double tau, x;
196
197 if ( this->fiberType == FT_CAF ) { // continuous aligned fibers
198 delta_sigma_f = this->Vf * 4. * this->tau_0 * distance / this->Df;
199 } else {
200 if ( delta < this->w_star / 2. ) {
201 tau = this->tau_0;
202 } else {
203 // maybe delta should be changed to delta_max?!?
204 tau = this->computeFiberBond(2. * delta);
205 }
206
207 x = min(distance, targetDebondedLength);
208
209 if ( this->fiberType == FT_SAF ) { // short aligned fibers
210 // delta_sigma_f is computed here in direction of the fibers, therefore no snubbing and no reduction in fibre volume
211 // this expression is derived for x < a (we are in the debonding zone) and for fibers perpendicular to the crack
212 delta_sigma_f = this->Vf * 4. * tau * ( this->Lf * x - x * x ) / ( this->Df * this->Lf );
213 } else {
214 // this expression uses the same hypothesis as in Lu & Leung 2016 (taken from Aveston 1974) that the stress transfer by friction
215 // does not continue after x (section where we want to now the stress) = xd (length of the debonded zone)
216 delta_sigma_f = this->Vf * 4. * tau * ( this->Lf * x - x * x ) / ( 3 * this->Df * this->Lf );
217 }
218 }
219
220 return delta_sigma_f;
221}
222
223
224void
225FRCFCMNL :: computeElementCentroid(FloatArray &answer, GaussPoint *gp) const {
226 double A, cx, cy, x_i, x_ii, y_i, y_ii;
227 Element *elem;
228 elem = gp->giveElement();
229 int nnode = elem->giveNumberOfNodes();
230
231 answer.resize(2);
232 answer.zero();
233
234 A = 0.;
235 cx = cy = 0.;
236
237 if ( ( nnode == 3 ) || ( nnode == 4 ) ) {
238 for ( int inod = 1; inod < nnode; inod++ ) {
239 x_i = elem->giveNode(inod)->giveCoordinate(1);
240 x_ii = elem->giveNode(inod + 1)->giveCoordinate(1);
241
242 y_i = elem->giveNode(inod)->giveCoordinate(2);
243 y_ii = elem->giveNode(inod + 1)->giveCoordinate(2);
244
245 A += 0.5 * ( x_i * y_ii - x_ii * y_i );
246
247 cx += ( x_i + x_ii ) * ( x_i * y_ii - x_ii * y_i );
248 cy += ( y_i + y_ii ) * ( x_i * y_ii - x_ii * y_i );
249 }
250
251 x_i = elem->giveNode(nnode)->giveCoordinate(1);
252 x_ii = elem->giveNode(1)->giveCoordinate(1);
253
254 y_i = elem->giveNode(nnode)->giveCoordinate(2);
255 y_ii = elem->giveNode(1)->giveCoordinate(2);
256
257 A += 0.5 * ( x_i * y_ii - x_ii * y_i );
258
259 cx += ( x_i + x_ii ) * ( x_i * y_ii - x_ii * y_i );
260 cy += ( y_i + y_ii ) * ( x_i * y_ii - x_ii * y_i );
261 }
262
263 cx /= ( 6. * A );
264 cy /= ( 6. * A );
265
266 answer.at(1) = cx;
267 answer.at(2) = cy;
268}
269
270
271bool
272FRCFCMNL :: isInElementProjection(GaussPoint *homeGp, GaussPoint *nearGp, int iNlCrack) const
273{
274 FRCFCMNLStatus *nonlocStatus;
275 nonlocStatus = static_cast< FRCFCMNLStatus * >( nearGp->giveMaterialStatus() );
276
277 Element *nearElem;
278 FloatArray examinedCoords;
279 int nnode;
280 double x, y, b_min, b_max, b_home, slope, x_min, x_max;
281
282 nearElem = nearGp->giveElement();
283
284 if ( ( fiberType == FT_CAF ) || ( fiberType == FT_SAF ) ) {
285 slope = this->orientationVector.at(2) / this->orientationVector.at(1);
286 } else {
287 slope = nonlocStatus->giveCrackDirs().at(2, iNlCrack) / nonlocStatus->giveCrackDirs().at(1, iNlCrack);
288 }
289
290 this->computeElementCentroid(examinedCoords, homeGp);
291
292 nnode = nearElem->giveNumberOfNodes();
293
294 if ( fabs(slope) < 1.e6 ) {
295 b_min = b_max = b_home = 0.;
296
297 for ( int inod = 1; inod <= nnode; inod++ ) {
298 x = nearElem->giveNode(inod)->giveCoordinate(1);
299 y = nearElem->giveNode(inod)->giveCoordinate(2);
300
301 // y = slope * x + b
302
303 if ( inod == 1 ) {
304 b_min = y - slope * x;
305 b_max = y - slope * x;
306 } else {
307 b_min = min(b_min, y - slope * x);
308 b_max = max(b_max, y - slope * x);
309 }
310 }
311
312 b_home = examinedCoords.at(2) - slope *examinedCoords.at(1);
313
314 if ( ( b_min < b_home ) && ( b_home < b_max ) ) {
315 return true;
316 } else {
317 return false;
318 }
319 } else {
320 x_min = x_max = 0.;
321
322 for ( int inod = 1; inod < nnode; inod++ ) {
323 x = nearElem->giveNode(inod)->giveCoordinate(1);
324
325 if ( inod == 1 ) {
326 x_min = x;
327 x_max = x;
328 } else {
329 x_min = min(x_min, x);
330 x_max = max(x_max, x);
331 }
332 }
333
334 if ( ( x_min < examinedCoords.at(1) ) && ( examinedCoords.at(1) < x_max ) ) {
335 return true;
336 } else {
337 return false;
338 }
339 }
340
341 // happy compiler
342 return true;
343}
344
345
346
347double
348FRCFCMNL :: computeNonlocalStressInFibers(const FloatArray &crackVectorHome, GaussPoint *gp, TimeStep *tStep) const {
349 // using "non-local" approach
350
351 // computes stress in fibers in the direction of "crackVectorHome"
352 // this can be used either to check the stress-strength criterion or when computing the stress from strain
353
354 // they key is to find the maximum stress in fibers which
355 // - diminishes with the distance from crack
356 // - diminishes with increasing angle wrt to its normal
357
358
359 FRCFCMNLStatus *nonlocStatus;
360
361 this->buildNonlocalPointTable(gp);
362
363 auto *list = this->giveIPIntegrationList(gp); // !
364
365 // two fiber stresses - from left and right part of the crack - rewrite if it turns out that one stress is fully sufficientaveraged
366 double sigma_f_left = 0.;
367 double sigma_f_right = 0.;
368
369 FloatArray coordsHome, coordsTarget;
370
371 double alpha, k_alpha_Home;
372
373 FloatArray crackVectorTarget;
374 FloatArray pointVector;
375
376 bool side;
377
378 double distance, targetCrackOpening, delta, a, targetDebondedLength, theta;
379 double sigma_f_iCr, delta_sigma_f;
380
381
382 this->computeElementCentroid(coordsHome, gp);
383
384 crackVectorTarget.resize( gp->giveMaterial()->giveDomain()->giveNumberOfSpatialDimensions() );
385 pointVector = crackVectorTarget;
386
387 for ( auto &lir : *list ) {
388 GaussPoint *neargp = lir.nearGp;
389
390 if ( neargp->giveElement()->giveNumber() != gp->giveElement()->giveNumber() ) { // it must not be the same element
391 if ( neargp->giveMaterial()->giveNumber() == gp->giveMaterial()->giveNumber() ) { // it must be the same material
392 nonlocStatus = static_cast< FRCFCMNLStatus * >( neargp->giveMaterialStatus() );
393
394 // crack(s) exist in the near gp
395 if ( nonlocStatus->giveNumberOfTempCracks() > 0 ) {
396 // do just once for all cracks
397 // get coordinates
398
399 this->computeElementCentroid(coordsTarget, neargp);
400
401 // compute the distance between evaluated element centers
402 distance = 0.;
403 for ( int i = 1; i <= coordsHome.giveSize(); i++ ) {
404 distance += ( coordsHome.at(i) - coordsTarget.at(i) ) * ( coordsHome.at(i) - coordsTarget.at(i) );
405 }
406
407 distance = sqrt(distance);
408
409 // zero the orientation vector between two points
410 pointVector.zero();
411
412
413 for ( int iNlCrack = 1; iNlCrack <= nonlocStatus->giveNumberOfTempCracks(); iNlCrack++ ) {
414 // length of the tunnel (zone where the fibers are debonded from the matrix and where friction acts) at the target gauss-point
415 targetCrackOpening = this->computeNormalCrackOpening(neargp, iNlCrack);
416
417
418 // pull-out displacement
419 delta = ( targetCrackOpening - fibreActivationOpening ) / 2.;
420
421 if ( delta > 0. ) {
422 a = this->computeDebondedLength(delta);
423
424 targetDebondedLength = a;
425
426 if ( distance < targetDebondedLength ) {
427 if ( this->isInElementProjection(gp, neargp, iNlCrack) ) {
428 // get stress in fibers bridging iNlCrack - local stress
429 sigma_f_iCr = nonlocStatus->giveTempFiberStressLoc(iNlCrack);
430
431
432 // get vector from points' coordinates - if has not been done before for the previous crack
433 if ( pointVector.containsOnlyZeroes() ) {
434 for ( int i = 1; i <= coordsHome.giveSize(); i++ ) {
435 pointVector.at(i) = ( coordsHome.at(i) - coordsTarget.at(i) ) / distance;
436 }
437 }
438
439 // the change in the bridging stress due to pulley and snubbing effects
440 if ( ( this->fiberType == FT_CAF ) || ( this->fiberType == FT_SAF ) ) {
441 theta = this->computeCrackFibreAngle(neargp, iNlCrack);
442 sigma_f_iCr /= ( fabs( cos(theta) ) * exp(fabs(theta) * this->f) );
443 } else if ( this->fiberType == FT_SRF ) {
444 sigma_f_iCr *= 2. / ( 3. * this->g );
445 } else {
446 OOFEM_ERROR("Unknown fiber type");
447 }
448
449 // change in fiber stress due to bond friction
450 delta_sigma_f = this->computeDecreaseInFibreStress(distance, delta, targetDebondedLength);
451
452 sigma_f_iCr -= delta_sigma_f;
453
454 // only positive values - can even happen to be negative?
455 sigma_f_iCr = max(sigma_f_iCr, 0.);
456
457 // decide the side
458 alpha = this->computeAngleBetweenVectors(pointVector, crackVectorHome);
459
460 if ( alpha < M_PI / 2. ) {
461 side = true;
462 } else {
463 side = false;
464 }
465
466 if ( this->fiberType == FT_CAF ) {
467 alpha = this->computeAngleBetweenVectors(crackVectorHome, this->orientationVector);
468 } else if ( this->fiberType == FT_SAF ) {
469 alpha = this->computeAngleBetweenVectors(crackVectorHome, this->orientationVector);
470 } else if ( this->fiberType == FT_SRF ) {
471 // angle factor - point vector vs. target crack
472 crackVectorTarget.zero();
473 for ( int i = 1; i <= coordsHome.giveSize(); i++ ) {
474 crackVectorTarget.at(i) = nonlocStatus->giveCrackDirs().at(i, iNlCrack);
475 }
476
477 alpha = this->computeAngleBetweenVectors(crackVectorHome, crackVectorTarget);
478 } else {
479 OOFEM_ERROR("Unknown fiber type");
480 }
481
482 // necessary correction
483 if ( alpha > M_PI / 2. ) {
484 alpha = M_PI - alpha;
485 }
486
487 // add some snubbing effect?
488 if ( alpha > participAngle * M_PI / 180. ) {
489 k_alpha_Home = 0.;
490 } else {
491 k_alpha_Home = cos( alpha * ( 90. / participAngle ) );
492 }
493
494
495 // get fiber stress
496 if ( side ) {
497 sigma_f_left = max(k_alpha_Home * sigma_f_iCr, sigma_f_left);
498 } else {
499 sigma_f_right = max(k_alpha_Home * sigma_f_iCr, sigma_f_right);
500 }
501 } // is in element projection
502 } // is in the debonded zone
503 } // positive delta
504 } // loop over target crack directions
505 } // condition for at least crack
506 } // the same material material
507 } // not the same element
508 } // loop over all gauss-points
509
510
511 return ( max(sigma_f_left, sigma_f_right) );
512 // return ( sigma_f_left + sigma_f_right );
513}
514
515
516double
517FRCFCMNL :: computeNonlocalStressInFibersInUncracked(GaussPoint *gp, TimeStep *tStep) const
518{
519 // using "non-local" approach
520
521 FRCFCMNLStatus *nonlocStatus;
522
523 this->buildNonlocalPointTable(gp);
524
525 auto *list = this->giveIPIntegrationList(gp); // !
526
527 FloatArray coordsHome, coordsTarget;
528
529 double distance, targetCrackOpening, delta, a, targetDebondedLength, theta, sigma_f_iCr, delta_sigma_f;
530 double sigma_f = 0.;
531
532 this->computeElementCentroid(coordsHome, gp);
533
534
535 for ( auto &lir : *list ) {
536 GaussPoint *neargp = lir.nearGp;
537
538 if ( neargp->giveElement()->giveNumber() != gp->giveElement()->giveNumber() ) { // it must not be the same element
539 if ( neargp->giveMaterial()->giveNumber() == gp->giveMaterial()->giveNumber() ) { // it must be the same material
540 nonlocStatus = static_cast< FRCFCMNLStatus * >( neargp->giveMaterialStatus() );
541
542 // crack(s) exist in the near gp
543 if ( nonlocStatus->giveNumberOfTempCracks() > 0 ) {
544 // do just once for all cracks
545 // get coordinates
546
547 this->computeElementCentroid(coordsTarget, neargp);
548
549 // compute the distance between evaluated element centers
550 distance = 0.;
551 for ( int i = 1; i <= coordsHome.giveSize(); i++ ) {
552 distance += ( coordsHome.at(i) - coordsTarget.at(i) ) * ( coordsHome.at(i) - coordsTarget.at(i) );
553 }
554
555 distance = sqrt(distance);
556
557
558 for ( int iNlCrack = 1; iNlCrack <= nonlocStatus->giveNumberOfTempCracks(); iNlCrack++ ) {
559 // length of the tunnel (zone where the fibers are debonded from the matrix and where friction acts) at the target gauss-point
560 targetCrackOpening = this->computeNormalCrackOpening(neargp, iNlCrack);
561
562
563 // pull-out displacement
564 delta = ( targetCrackOpening - fibreActivationOpening ) / 2.;
565
566 if ( delta > 0. ) {
567 a = this->computeDebondedLength(delta);
568
569 targetDebondedLength = a;
570
571 if ( distance < targetDebondedLength ) {
572 if ( this->isInElementProjection(gp, neargp, iNlCrack) ) {
573 // get stress in fibers bridging iNlCrack - local stress
574 sigma_f_iCr = nonlocStatus->giveTempFiberStressLoc(iNlCrack);
575
576 // the change in the bridging stress due to pulley and snubbing effects
577 if ( ( this->fiberType == FT_CAF ) || ( this->fiberType == FT_SAF ) ) {
578 theta = this->computeCrackFibreAngle(neargp, iNlCrack);
579 sigma_f_iCr /= ( fabs( cos(theta) ) * exp(fabs(theta) * this->f) );
580 } else if ( this->fiberType == FT_SRF ) {
581 sigma_f_iCr /= this->g;
582 } else {
583 OOFEM_ERROR("Unknown fiber type");
584 }
585
586 // change in fiber stress due to bond friction
587 delta_sigma_f = this->computeDecreaseInFibreStress(distance, delta, targetDebondedLength);
588
589 sigma_f_iCr -= delta_sigma_f;
590
591 // only positive values - can even happen to be negative?
592 sigma_f_iCr = max(sigma_f_iCr, 0.);
593
594 // get fiber stress
595 sigma_f = max(sigma_f_iCr, sigma_f);
596 } // is in element projection
597 } // is in the debonded zone
598 } // positive delta
599 } // loop over target crack directions
600 } // condition for at least crack
601 } // the same material material
602 } // not the same element
603 } // loop over all gauss-points
604
605
606 return sigma_f;
607}
608
609
610
611
612
613bool
614FRCFCMNL :: isStrengthExceeded(const FloatMatrix &base, GaussPoint *gp, TimeStep *tStep, int iCrack, double trialStress) const {
615 // evaluates cheaper function than is the nonlocal approach
616 if ( !FRCFCM :: isStrengthExceeded(base, gp, tStep, iCrack, trialStress) ) {
617 return false;
618 }
619
620 FRCFCMNLStatus *status = static_cast< FRCFCMNLStatus * >( this->giveStatus(gp) );
621
622 double sigma_f, sigma_m;
623
624 FloatArray crackVec;
625
626 crackVec.resize( status->giveMaxNumberOfCracks(gp) );
627 crackVec.zero();
628
629 for ( int i = 1; i <= status->giveMaxNumberOfCracks(gp); i++ ) {
630 crackVec.at(i) = base.at(i, iCrack);
631 }
632
633 sigma_f = this->computeNonlocalStressInFibers(crackVec, gp, tStep);
634
635 //test !!!!
636 sigma_f = max( sigma_f, status->giveFiberStressNL(iCrack) );
637
638 status->setTempFiberStressNL(iCrack, sigma_f);
639
640 // get neat stress in matrix
641 sigma_m = ( trialStress - sigma_f ) / ( 1. - this->Vf );
642
643 // compare matrix strength with computed stress in the matrix
644
645 if ( FCMMaterial :: isStrengthExceeded(base, gp, tStep, iCrack, sigma_m) ) {
646 return true;
647 } else {
648 return false;
649 }
650}
651
652
653
654void
655FRCFCMNL :: giveMaterialStiffnessMatrix(FloatMatrix &answer,
656 MatResponseMode rMode,
657 GaussPoint *gp,
658 TimeStep *tStep) const
659//
660// returns effective material stiffness matrix in full form
661// for gp stress strain mode
662//
663{
664 if ( rMode == ElasticStiffness ) {
665 FCMMaterial :: giveMaterialStiffnessMatrix(answer, rMode, gp, tStep);
666 } else if ( rMode == SecantStiffness ) {
667 /*FRCFCMNLStatus *status = static_cast< FRCFCMNLStatus * >( this->giveStatus(gp) );
668 * int numberOfActiveCracks = status->giveNumberOfTempCracks();
669 * double localSigmaF;
670 * double NLsigmaF;
671 *
672 * for (int iCrack = 1; iCrack <= numberOfActiveCracks; iCrack++) {
673 *
674 * localSigmaF = status->giveTempFiberStressLoc(iCrack);
675 * NLsigmaF = status->giveTempFiberStressNL(iCrack);
676 *
677 * // if ( NLsigmaF > localSigmaF ) {
678 * if ( NLsigmaF > 0. ) {
679 * FCMMaterial :: giveMaterialStiffnessMatrix(answer, ElasticStiffness, gp, tStep);
680 * return;
681 * }
682 * }*/
683
684 FCMMaterial :: giveMaterialStiffnessMatrix(answer, rMode, gp, tStep);
685 } else { // tangent stiffness
686 FCMMaterial :: giveMaterialStiffnessMatrix(answer, rMode, gp, tStep);
687 }
688
689 return;
690}
691
692
693double
694FRCFCMNL :: computeAngleBetweenVectors(const FloatArray &vec1, const FloatArray &vec2) const
695{
696 // compute angle between two vectors
697
698 if ( vec1.giveSize() != vec2.giveSize() ) {
699 OOFEM_ERROR("the length of vec1 and vec2 is not of the same");
700 }
701
702
703 //return 0.;
704
705
706 double length1 = 0., length2 = 0.;
707 double theta = 0.;
708
709 for ( int i = 1; i <= min( vec1.giveSize(), vec2.giveSize() ); i++ ) {
710 length1 += pow(vec1.at(i), 2);
711 length2 += pow(vec2.at(i), 2);
712 theta += vec1.at(i) * vec2.at(i);
713 }
714 length1 = sqrt(length1);
715 length2 = sqrt(length2);
716
717 // normalize
718 theta /= ( length1 * length2 );
719
720
721 // can be exceeded due to truncation error
722 if ( theta > 1 ) {
723 return 0.;
724 } else if ( theta < -1. ) {
725 return M_PI;
726 }
727
728
729 return acos(theta);
730}
731
732
733Interface *
734FRCFCMNL :: giveInterface(InterfaceType type)
735{
737 return static_cast< StructuralNonlocalMaterialExtensionInterface * >(this);
738 } else {
739 return NULL;
740 }
741}
742
743
744
745int
746FRCFCMNL :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
747{
748 FRCFCMNLStatus *status = static_cast< FRCFCMNLStatus * >( this->giveStatus(gp) );
749
750 double local = 0.;
751 double nl = 0.;
752
753 for ( int i = 1; i <= status->giveMaxNumberOfCracks(gp); i++ ) {
754 local = max(status->giveFiberStressLoc(i), local);
755 nl = max(status->giveFiberStressNL(i), nl);
756 }
757
758
759 // stress in fibers (per continuum)
760 if ( type == IST_FiberStressLocal ) {
761 answer.resize(1);
762 answer.at(1) = local;
763 return 1;
764
765 // stress in fibers (per continuum)
766 } else if ( type == IST_FiberStressNL ) {
767 answer.resize(1);
768 answer.at(1) = nl;
769 return 1;
770 } else {
771 return FRCFCM :: giveIPValue(answer, gp, type, tStep);
772 }
773}
774
775
776
778// FRC FCM NL STATUS ///
780
781
790
791
792void
793FRCFCMNLStatus :: printOutputAt(FILE *file, TimeStep *tStep) const
794{
795 FRCFCMStatus :: printOutputAt(file, tStep);
796
797 fprintf(file, "maxFiberStressLocal: {");
798 for ( double s: fiberStressLoc ) {
799 fprintf( file, " %f", s );
800 }
801 fprintf(file, "}\n");
802
803 fprintf(file, "maxFiberStressNL: {");
804 for ( double s: fiberStressLoc ) {
805 fprintf( file, " %f", s );
806 }
807 fprintf(file, "}\n");
808}
809
810
811void
812FRCFCMNLStatus :: initTempStatus()
813//
814// initializes temp variables according to variables form previous equlibrium state.
815// builds new crackMap
816//
817{
818 FRCFCMStatus :: initTempStatus();
819
821 this->tempFiberStressNL = this->fiberStressNL;
822}
823
824
825
826void
827FRCFCMNLStatus :: updateYourself(TimeStep *tStep)
828//
829// updates variables (nonTemp variables describing situation at previous equilibrium state)
830// after a new equilibrium state has been reached
831// temporary variables correspond to newly reched equilibrium.
832//
833{
834 FRCFCMStatus :: updateYourself(tStep);
835
837 this->fiberStressNL = this->tempFiberStressNL;
838}
839
840
841
842void
843FRCFCMNLStatus :: saveContext(DataStream &stream, ContextMode mode)
844{
845 FRCFCMStatus :: saveContext(stream, mode);
846
848 if ( ( iores = fiberStressLoc.storeYourself(stream) ) != CIO_OK ) {
849 THROW_CIOERR(iores);
850 }
851
852 if ( ( iores = fiberStressNL.storeYourself(stream) ) != CIO_OK ) {
853 THROW_CIOERR(iores);
854 }
855}
856
857void
858FRCFCMNLStatus :: restoreContext(DataStream &stream, ContextMode mode)
859{
860 FRCFCMStatus :: restoreContext(stream, mode);
861
863 if ( ( iores = fiberStressLoc.restoreYourself(stream) ) != CIO_OK ) {
864 THROW_CIOERR(iores);
865 }
866
867 if ( ( iores = fiberStressNL.restoreYourself(stream) ) != CIO_OK ) {
868 THROW_CIOERR(iores);
869 }
870}
871
872
873Interface *
874FRCFCMNLStatus :: giveInterface(InterfaceType type)
875{
877 return static_cast< StructuralNonlocalMaterialStatusExtensionInterface * >(this);
878 } else {
879 return ConcreteFCMStatus :: giveInterface(type);
880 }
881}
882} // end namespace oofem
#define REGISTER_Material(class)
MaterialStatus * giveStatus(GaussPoint *gp) const override
double giveCoordinate(int i) const
Definition dofmanager.h:383
int giveNumberOfSpatialDimensions()
Returns number of spatial dimensions.
Definition domain.C:1137
Node * giveNode(int i) const
Definition element.h:629
virtual int giveNumberOfNodes() const
Definition element.h:703
const FloatMatrix & giveG2LStressVectorTransformationMtrx()
returns transformation matrix for stress transformation from global to local coordinate system
Definition fcm.h:153
const FloatMatrix & giveL2GStressVectorTransformationMtrx()
sets transformation matrix for stress transformation from local to global coordinate system
Definition fcm.h:157
virtual int giveNumberOfTempCracks() const
returns temporary number of cracks
Definition fcm.C:2421
double giveTempCrackStrain(int icrack) const
returns i-th component of the crack strain vector (temporary)
Definition fcm.h:134
const FloatMatrix & giveCrackDirs()
returns crack directions
Definition fcm.h:172
int nMaxCracks
number of maximum possible cracks (optional parameter)
Definition fcm.h:95
virtual int giveMaxNumberOfCracks(GaussPoint *gp)
returns maximum number of cracks associated with current mode
Definition fcm.C:2438
virtual double computeNormalCrackOpening(GaussPoint *gp, int i) const
uses temporary cracking strain and characteristic length to obtain the crack opening
Definition fcm.C:1130
Domain * giveDomain() const
Definition femcmpnn.h:97
int giveNumber() const
Definition femcmpnn.h:104
double giveFiberStressLoc(int icrack) const
LOCAL FIBER STRESSES (from crack opening).
Definition frcfcmnl.h:75
FloatArray fiberStressLoc
bulk stress in fibers - evaluated from crack opening
Definition frcfcmnl.h:61
double giveTempFiberStressLoc(int icrack) const
Definition frcfcmnl.h:76
void setTempFiberStressLoc(int icrack, double newFiberStressLoc)
Definition frcfcmnl.h:77
FloatArray tempFiberStressNL
Non-equilibrated stress (bulk) in fibers.
Definition frcfcmnl.h:68
FloatArray fiberStressNL
bulk stress in fibers - evaluated from crack opening
Definition frcfcmnl.h:66
void setTempFiberStressNL(int icrack, double newFiberStressNL)
Definition frcfcmnl.h:82
double giveFiberStressNL(int icrack) const
NON-LOCAL FIBER STRESSES (from surrounding cracks).
Definition frcfcmnl.h:80
FloatArray tempFiberStressLoc
Non-equilibrated stress (bulk) in fibers.
Definition frcfcmnl.h:63
virtual double computeNonlocalStressInFibers(const FloatArray &crackVector, GaussPoint *gp, TimeStep *tStep) const
computes nonlocal stress in fibers in cracked GP
Definition frcfcmnl.C:348
bool isInElementProjection(GaussPoint *homeGp, GaussPoint *nearGp, int iNlCrack) const
checks if a element center of homeGP is in projection of element containing nearGP
Definition frcfcmnl.C:272
double computeDecreaseInFibreStress(double distance, double delta, double debondedLength) const
compute the the difference in fiber stress in the target (local stress) and receiver (nonlocal stress...
Definition frcfcmnl.C:186
double computeDebondedLength(double delta) const
computes debonded length of the fibers from the crack opening. Delta is here one half of the crack op...
Definition frcfcmnl.C:162
double participAngle
participation angle. The target gauss point must fall into this angle to contribute to the nonlocal s...
Definition frcfcmnl.h:149
double computeAngleBetweenVectors(const FloatArray &vec1, const FloatArray &vec2) const
computes an angle between two vectors
Definition frcfcmnl.C:694
void computeElementCentroid(FloatArray &answer, GaussPoint *gp) const
computes cetroid of a finite element - works only for linear 3 and 4-node elements
Definition frcfcmnl.C:225
virtual double computeNonlocalStressInFibersInUncracked(GaussPoint *gp, TimeStep *tStep) const
computes nonlocal stress in fibers in uncracked GP
Definition frcfcmnl.C:517
FRCFCMStatus(GaussPoint *g)
Definition frcfcm.C:1209
virtual double computeFiberBond(double w) const
evaluates the fiber bond if w > w*
Definition frcfcm.C:563
double f
snubbing factor "f"
Definition frcfcm.h:131
FRCFCM(int n, Domain *d)
Definition frcfcm.C:45
virtual double computeStressInFibersInCracked(GaussPoint *gp, TimeStep *tStep, double eps_cr, int i) const
compute the nominal stress in fibers in the i-th crack
Definition frcfcm.C:620
double tau_0
fiber shear strength at zero slip
Definition frcfcm.h:123
double g
auxiliary parameter computed from snubbing factor "f"
Definition frcfcm.h:134
double Ef
fiber Young's modulus
Definition frcfcm.h:146
double Df
fiber diameter
Definition frcfcm.h:143
double Lf
fiber length
Definition frcfcm.h:140
double w_star
transitional opening
Definition frcfcm.h:155
virtual double computeCrackFibreAngle(GaussPoint *gp, int i) const
compute the angle between the fibre and i-th crack normal
Definition frcfcm.C:258
double fibreActivationOpening
crack opening at which the crossing fibers begin to be activated
Definition frcfcm.h:178
double eta
aux. factor
Definition frcfcm.h:158
FiberType fiberType
Definition frcfcm.h:208
FloatArray orientationVector
orientation of fibres
Definition frcfcm.h:175
double Vf
volume fraction of fibers
Definition frcfcm.h:137
bool containsOnlyZeroes() const
Definition floatarray.C:671
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 zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void rotatedWith(FloatMatrix &r, char mode)
Definition floatarray.C:814
double at(std::size_t i, std::size_t j) const
Material * giveMaterial()
Returns reference to material associated to related element of receiver.
Definition gausspoint.h:196
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 buildNonlocalPointTable(GaussPoint *gp) const
std ::vector< localIntegrationRecord > * giveIPIntegrationList(GaussPoint *gp) const
void letTempStressVectorBe(const FloatArray &v)
Assigns tempStressVector to given vector v.
#define THROW_CIOERR(e)
#define OOFEM_ERROR(...)
Definition error.h:79
#define M_PI
Definition mathfem.h:52
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)
@ NonlocalMaterialStatusExtensionInterfaceType
@ NonlocalMaterialExtensionInterfaceType
double distance(const FloatArray &x, const FloatArray &y)

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