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

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Tue Jan 2 2018 20:07:28 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011