OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
druckerPragerPlasticitySM.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 - 2013 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 
36 
37 #include "floatarray.h"
38 #include "floatmatrix.h"
39 #include "../sm/Materials/structuralms.h"
40 #include "gausspoint.h"
41 #include "intarray.h"
42 #include "../sm/Materials/structuralmaterial.h"
44 #include "datastream.h"
45 #include "contextioerr.h"
46 #include "mathfem.h"
47 #include "classfactory.h"
48 
49 namespace oofem {
50 REGISTER_Material(DruckerPragerPlasticitySM);
51 
53  StructuralMaterialStatus(n, d, gp),
54  plasticStrainDeviator( 6 ),
55  tempPlasticStrainDeviator( 6 )
56 {
61 
62  kappa = tempKappa = 0.;
65 }
66 
68 { }
69 
70 void
72 {
73  // Call the function of the parent class to initialize the variables defined there.
75 
78  tempKappa = kappa;
80 }
81 
82 void
84 {
85  // Call corresponding function of the parent class to update variables defined there.
87 
88  // update variables defined in DruckerPragerPlasticitySMStatus
91  kappa = tempKappa;
93 }
94 
95 void
97 {
98  // Call corresponding function of the parent class to print variables defined there.
100 
101  fprintf(file, "\tstatus { ");
102 
103  // print status flag
104  switch ( state_flag ) {
106  fprintf(file, " Elastic, ");
107  break;
109  fprintf(file, " Yielding, ");
110  break;
112  fprintf(file, " Vertex_return, ");
113  break;
115  fprintf(file, " Unloading, ");
116  break;
117  }
118 
119  // print plastic strain vector
120  FloatArray plasticStrainVector;
121  givePlasticStrainVector(plasticStrainVector);
122 
123  fprintf(file, "plasticStrains ");
124  for ( auto &val : plasticStrainVector ) {
125  fprintf( file, " %.4e", val );
126  }
127 
128  fprintf(file, "}\n");
129 
130  fprintf(file, "\t\thardening_parameter ");
131  // print hardening parameter
132  fprintf(file, " %.4e\n", kappa);
133 }
134 
137 {
138  contextIOResultType iores;
139 
140  // save parent class status
141  if ( ( iores = StructuralMaterialStatus :: saveContext(stream, mode, obj) ) != CIO_OK ) {
142  THROW_CIOERR(iores);
143  }
144 
145  // write raw data
146  if ( ( iores = plasticStrainDeviator.storeYourself(stream) ) != CIO_OK ) {
147  THROW_CIOERR(iores);
148  }
149 
150  if ( !stream.write(volumetricPlasticStrain) ) {
152  }
153 
154  if ( !stream.write(kappa) ) {
156  }
157 
158  if ( !stream.write(temp_state_flag) ) {
160  }
161 
162  return CIO_OK;
163 }
164 
165 
168 {
169  contextIOResultType iores;
170 
171  // read parent class status
172  if ( ( iores = StructuralMaterialStatus :: restoreContext(stream, mode, obj) ) != CIO_OK ) {
173  THROW_CIOERR(iores);
174  }
175 
176  // read raw data
177  if ( ( iores = plasticStrainDeviator.restoreYourself(stream) ) != CIO_OK ) {
178  THROW_CIOERR(iores);
179  }
180 
181  if ( !stream.read(volumetricPlasticStrain) ) {
183  }
184 
185  if ( !stream.read(kappa) ) {
187  }
188 
189  if ( !stream.read(temp_state_flag) ) {
191  }
192 
193  return CIO_OK;
194 }
195 
196 // *************************************************************
197 // *** CLASS DRUCKER-PRAGER PLASTICITY STRUCTURAL MATERIAL ***
198 // *************************************************************
199 
200 
202  StructuralMaterial(n, d)
203 {
205  kFactor = 0.;
206  yieldTol = 0.;
207  newtonIter = 0;
208 }
209 
211 {
212  delete LEMaterial;
213 }
214 
217 {
218  // Required by IR_GIVE_FIELD macro
219  IRResultType result;
220  // call the corresponding service of structural material
222  if ( result != IRRT_OK ) return result;
223 
224  // call the corresponding service for the linear elastic material
225  result = LEMaterial->initializeFrom(ir);
226  if ( result != IRRT_OK ) return result;
227 
228  // initialize elastic constants
229  //eM = LEMaterial->give(Ex,gp);
230  //nu = LEMaterial->give(NYxz,gp);
231  //gM = eM / ( 2. * ( 1. + nu ) );
232  //kM = eM / ( 3. * ( 1. - 2. * nu ) );
233 
234  // instanciate the variables defined in DruckerPragerPlasticitySM
235  IR_GIVE_FIELD(ir, initialYieldStress, _IFT_DruckerPragerPlasticitySM_iys); // initial yield stress under pure shear
236  IR_GIVE_FIELD(ir, alpha, _IFT_DruckerPragerPlasticitySM_alpha); // friction coefficient
237  IR_GIVE_FIELD(ir, alphaPsi, _IFT_DruckerPragerPlasticitySM_alphapsi); //dilatancy coefficient
238  // this is valid for strain hardening/softening only (not for work hardening/softening)
239  kFactor = sqrt(1. / 3. + 2. * alphaPsi * alphaPsi);
240 
242 
243  switch ( hardeningType ) {
244  case 1: // linear hardening/softening
246  break;
247  case 2: // exponential hardening/softening
250  break;
251  default:
252  OOFEM_WARNING("Choose hardeningType 1 (linear hardening/softening), 2 (exponential hardening/softening) in input file!");
253  return IRRT_BAD_FORMAT;
254  }
255 
256  yieldTol = 1.e-14;
258  newtonIter = 30;
260 
261  return IRRT_OK;
262 }
263 
264 void
266  GaussPoint *gp,
267  const FloatArray &totalStrain,
268  TimeStep *tStep)
269 {
270  FloatArray strainVectorR;
271 
273  static_cast< DruckerPragerPlasticitySMStatus * >( this->giveStatus(gp) );
274 
275  // Initialize temp variables for this gauss point
276  initTempStatus(gp);
277 
278  // subtract stress independent part
279  // note: eigenStrains (temperature) is not contained in mechanical strain stored in gp
280  // therefore it is necessary to subtract always the total eigen strain value
281  this->giveStressDependentPartOfStrainVector_3d(strainVectorR, gp, totalStrain,
282  tStep, VM_Total);
283 
284  // perform the local stress return and update the history variables
285  performLocalStressReturn(gp, strainVectorR);
286 
287  // copy total strain vector to the temp status
288  status->letTempStrainVectorBe(totalStrain);
289 
290  // give back correct form of stressVector to giveRealStressVector
291  answer = status->giveTempStressVector();
292 }
293 
294 void
296  const FloatArray &strain)
297 {
299  static_cast< DruckerPragerPlasticitySMStatus * >( giveStatus(gp) );
300 
301  // split total strains in volumetric and deviatoric part
302  FloatArray strainDeviator;
303  double volumetricStrain;
304  // elastic constants
305  double eM = LEMaterial->give(Ex, gp);
306  double nu = LEMaterial->give(NYxz, gp);
307  double gM = eM / ( 2. * ( 1. + nu ) );
308  double kM = eM / ( 3. * ( 1. - 2. * nu ) );
309 
310  volumetricStrain = computeDeviatoricVolumetricSplit(strainDeviator, strain);
311 
312  // compute trial elastic strains
313  double volumetricElasticTrialStrain =
314  volumetricStrain - status->giveVolumetricPlasticStrain();
315  FloatArray plasticStrainDeviator = status->givePlasticStrainDeviator();
316  FloatArray elasticStrainDeviator = strainDeviator;
317  elasticStrainDeviator.subtract(plasticStrainDeviator);
318 
319  // compute trial stresses
320  FloatArray stressDeviator;
321  double volumetricStress = 3. * kM * volumetricElasticTrialStrain;
322  applyDeviatoricElasticStiffness(stressDeviator, elasticStrainDeviator, gM);
323  // norm of trial stress deviator
324  double trialStressJTwo = computeSecondStressInvariant(stressDeviator);
325 
326  // initialize hardening parameter
327  double kappa = status->giveKappa();
328  double tempKappa = kappa;
329 
330  // choose and perform correct stress return and update state flag
331  if ( computeYieldValue(volumetricStress, trialStressJTwo, tempKappa, eM) / eM
332  > yieldTol ) {
333  //printf("*");
334  if ( checkForVertexCase(eM, gM, kM, trialStressJTwo, volumetricStress, tempKappa) ) {
335  performVertexReturn(eM, gM, kM, trialStressJTwo, stressDeviator, volumetricStress,
336  tempKappa, volumetricElasticTrialStrain, kappa);
338  } else {
339  performRegularReturn(eM, gM, kM, trialStressJTwo, stressDeviator, volumetricStress, tempKappa);
341  }
342  } else {
343  const int state_flag = status->giveStateFlag();
344  if ( state_flag == DruckerPragerPlasticitySMStatus :: DP_Elastic ) {
346  } else {
348  }
349  }
350 
351  // update kappa
352  status->letTempKappaBe(tempKappa);
353 
354  // compute full stresses from deviatoric and volumetric part and store them
355  FloatArray stress;
356  computeDeviatoricVolumetricSum(stress, stressDeviator, volumetricStress);
357  status->letTempStressVectorBe(stress);
358 
359  // compute and update plastic strains, volumetric and deviatoric part
360  applyDeviatoricElasticCompliance(elasticStrainDeviator, stressDeviator, gM);
361  plasticStrainDeviator = strainDeviator;
362  plasticStrainDeviator.subtract(elasticStrainDeviator);
363  status->letTempPlasticStrainDeviatorBe(plasticStrainDeviator);
364  status->letTempVolumetricPlasticStrainBe(volumetricStrain - volumetricStress / 3. / kM);
365 }
366 
367 bool
368 DruckerPragerPlasticitySM :: checkForVertexCase(double eM, double gM, double kM, double trialStressJTwo, double volumetricStress, double tempKappa)
369 {
370  // delta lambda max corresponds to the maximum value
371  // of the rate of the plastic multiplier for regular plastic flow
372  // and allows to distinguish between regular return and vertex case
373  double deltaLambdaMax = sqrt(trialStressJTwo) / gM;
374 
375  // vertex case:
376  // yield value positive under the assumption of maximum regular plastic flow
377  double volConstant = 3. * kM * alphaPsi;
378  double yieldValue =
379  computeYieldValue(volumetricStress - volConstant * deltaLambdaMax,
380  0., tempKappa + kFactor * deltaLambdaMax, eM);
381  if ( yieldValue / eM > -yieldTol ) {
382  return true;
383  }
384 
385  // regular case
386  return false;
387 }
388 
389 void
390 DruckerPragerPlasticitySM :: performRegularReturn(double eM, double gM, double kM, double trialStressJTwo, FloatArray &stressDeviator, double &volumetricStress, double &tempKappa)
391 {
392  // delta lambda max controls the maximum plastic flow, see below
393  double deltaLambdaMax = sqrt(trialStressJTwo) / gM;
394 
395  // declare some constants for faster use
396  double volConstant = 3. * kM * alphaPsi;
397  double devConstant = sqrt(2.) * gM;
398  // yield value prime is derivative of yield value with respect to deltaLambda
399  double yieldValuePrimeZero = -9. * alpha * alphaPsi * kM - gM;
400 
401  FloatArray flowDir = stressDeviator;
402  flowDir.times( 1. / sqrt(2. * trialStressJTwo) );
403 
404 
405  // some variables needed for iteration
406  double yieldValuePrime;
407  FloatArray plasticFlow;
408 
409  // initialize Newton iteration
410  double tempJTwo;
411  int iterationCount = 0;
412  double deltaLambda = 0.;
413  double deltaLambdaIncrement = 0.;
414  double yieldValue = computeYieldValue(volumetricStress, trialStressJTwo, tempKappa, eM);
415  double newtonError = fabs(yieldValue / eM);
416  //printf("\nnewtonError = %e\n", newtonError) ;
417  // Newton iteration to find deltaLambda
418  while ( newtonError > yieldTol ) {
419  if ( ++iterationCount > newtonIter ) {
420  OOFEM_ERROR("Newton iteration for deltaLambda (regular stress return) did not converge after newtonIter iterations. You might want to try increasing the optional parameter newtoniter or yieldtol in the material record of your input file.");
421  }
422 
423  yieldValuePrime = yieldValuePrimeZero - kFactor *computeYieldStressPrime(tempKappa, eM);
424  deltaLambdaIncrement = -yieldValue / yieldValuePrime;
425 
426  // deltaLambdaMax may be exceeded if the yield stress has almost vanished
427  // If this happens, the stress deviator will evolve too much,
428  // and will then be on the other side of the hydrostatic axis.
429  // This causes the failure of the Newton-iteration and has to be avoided.
430  if ( deltaLambda + deltaLambdaIncrement > deltaLambdaMax ) {
431  OOFEM_LOG_DEBUG("Special case in Newton-iteration for regular return. This may cause loss of quadratic convergence.\n");
432  deltaLambdaIncrement = deltaLambdaMax - deltaLambda;
433  }
434 
435  deltaLambda += deltaLambdaIncrement;
436  tempKappa += kFactor * deltaLambdaIncrement;
437  volumetricStress -= volConstant * deltaLambdaIncrement;
438 
439  // plasticFlow = flowDir ;
440  //plasticFlow.times( devConstant * deltaLambdaIncrement ) ;
441  //stressDeviator.subtract( plasticFlow ) ;
442 
443  stressDeviator.add(-devConstant * deltaLambdaIncrement, flowDir);
444  tempJTwo = computeSecondStressInvariant(stressDeviator);
445  yieldValue = computeYieldValue(volumetricStress, tempJTwo, tempKappa, eM);
446  newtonError = fabs(yieldValue / eM);
447  //printf("newtonError = %e\n", newtonError) ;
448  }
449 
450  OOFEM_LOG_DEBUG("IterationCount in regular return = %d\n", iterationCount);
451 
452  if ( deltaLambda < 0. ) {
453  OOFEM_ERROR("Fatal error in the Newton iteration for regular stress return. deltaLambda is evaluated as negative, but should always be positive. This is most likely due to a softening law with local snapback, which is physically inadmissible.n");
454  }
455 }
456 
457 void
458 DruckerPragerPlasticitySM :: performVertexReturn(double eM, double gM, double kM, double trialStressJTwo, FloatArray &stressDeviator, double &volumetricStress, double &tempKappa, double volumetricElasticTrialStrain, double kappa)
459 {
460  // declare some constants for faster use
461  // yield value prime is derivative of yield value with respect to deltaLambda
462  double yieldValuePrimeZero = 3. * alpha;
463  // contribution of deviatoric strain to hardening
464  double deviatorContribution = trialStressJTwo / 3. / gM / gM;
465  // in the vertex case, deviatoric stresses are zero
466  stressDeviator.zero();
467  volumetricStress = 3. * kM * volumetricElasticTrialStrain;
468 
469  // needed for iteration
470  double yieldValuePrime;
471 
472  // initialize Newton iteration
473  int iterationCount = 0;
474  double deltaVolumetricStress = 0.;
475  double deltaVolumetricStressIncrement = 0.;
476  double deltaKappa = sqrt(deviatorContribution);
477  tempKappa = kappa + deltaKappa;
478  double yieldValue = computeYieldValue(volumetricStress, 0., tempKappa, eM);
479  double newtonError = fabs(yieldValue / eM);
480 
481  // Newton iteration to find deltaLambda
482  while ( newtonError > yieldTol ) {
483  if ( ++iterationCount > newtonIter ) {
484  OOFEM_ERROR("Newton iteration for deltaLambda (vertex stress return) did not converge after newtonIter iterations. You might want to try increasing the optional parameter newtoniter or yieldtol in the material record of your input file.");
485  }
486 
487  // exclude division by zero
488  if ( deltaKappa == 0. ) {
489  yieldValuePrime = yieldValuePrimeZero
490  - sqrt(2.) / 3. / kM *computeYieldStressPrime(tempKappa, eM);
491  } else {
492  yieldValuePrime = yieldValuePrimeZero
493  - 2. / 9. / kM / kM *computeYieldStressPrime(tempKappa, eM)
494  * deltaVolumetricStress / deltaKappa;
495  }
496 
497  deltaVolumetricStressIncrement = -yieldValue / yieldValuePrime;
498  deltaVolumetricStress += deltaVolumetricStressIncrement;
499  volumetricStress += deltaVolumetricStressIncrement;
500  deltaKappa = sqrt(2. / 9. / kM / kM * deltaVolumetricStress * deltaVolumetricStress
501  + deviatorContribution);
502  tempKappa = kappa + deltaKappa;
503  yieldValue = computeYieldValue(volumetricStress, 0., tempKappa, eM);
504  newtonError = fabs(yieldValue / eM);
505  OOFEM_LOG_DEBUG("NewtonError in iteration %d in vertex return = %e\n", iterationCount, newtonError);
506  }
507 
508  OOFEM_LOG_DEBUG("Done iteration in vertex return, after %d\n", iterationCount);
509 
510  if ( deltaKappa < 0. ) {
511  OOFEM_ERROR("Fatal error in the Newton iteration for vertex stress return. deltaKappa is evaluated as negative, but should always be positive. This is most likely due to a softening law with a local snapback, which is physically inadmissible.");
512  }
513 }
514 
515 double
517  double JTwo,
518  double kappa,
519  double eM) const
520 {
521  return 3. * alpha * volumetricStress + sqrt(JTwo) - computeYieldStressInShear(kappa, eM);
522 }
523 
524 double
526 {
527  double yieldStress;
528  switch ( hardeningType ) {
529  case 1: // linear hardening/softening.
530  yieldStress = initialYieldStress + hardeningModulus * eM * kappa;
531  if ( yieldStress < 0. ) {
532  yieldStress = 0.;
533  //printf("Yield stress zero reached in computeYieldStressInShear.\n") ;
534  }
535 
536  break;
537  case 2: // exponential hardening
538  yieldStress =
540  break;
541  default:
542  //StructuralMaterial :: OOFEM_ERROR( "Case failed: choose linear hardening/softening (1), exponential hardening/softening (2) in input file.") ;
543  OOFEM_ERROR("Case failed: choose linear hardening/softening (1), exponential hardening/softening (2) in input file.");
544  return 0.;
545 
546  break;
547  }
548 
549  return yieldStress;
550 }
551 
552 double
554 {
555  switch ( hardeningType ) {
556  case 1: // linear hardening/softening.
557  // if the limit value for kappa is exceeded in the softening case, the derivative is zero
558  if ( ( hardeningModulus < 0. ) && ( kappa >= -initialYieldStress / hardeningModulus / eM ) ) {
559  return 0.0;
560  } else {
561  return eM * hardeningModulus;
562  }
563 
564  break;
565  case 2: // exponential hardening
566  return ( limitYieldStress - initialYieldStress ) / kappaC *exp(-kappa / kappaC);
567 
568  break;
569  default:
570  //StructuralMaterial :: OOFEM_ERROR( "Case failed: choose linear hardening/softening (1), exponential hardening/softening (2) in input file.") ;
571  OOFEM_ERROR("Case failed: choose linear hardening/softening (1), exponential hardening/softening (2) in input file.");
572  return 0.;
573 
574  break;
575  }
576 }
577 
578 void
580  MatResponseMode mode,
581  GaussPoint *gp,
582  TimeStep *tStep)
583 {
584  switch ( mode ) {
585  case ElasticStiffness:
586  LEMaterial->give3dMaterialStiffnessMatrix(answer, mode, gp, tStep);
587  break;
588 
589  case SecantStiffness:
590  LEMaterial->give3dMaterialStiffnessMatrix(answer, mode, gp, tStep);
591  break;
592 
593 
594  case TangentStiffness:
595  switch ( ( static_cast< DruckerPragerPlasticitySMStatus * >( this->giveStatus(gp) ) )
596  ->giveTempStateFlag() ) {
597  case DruckerPragerPlasticitySMStatus :: DP_Elastic: // elastic stiffness
598  case DruckerPragerPlasticitySMStatus :: DP_Unloading: // elastic stiffness
599  LEMaterial->give3dMaterialStiffnessMatrix(answer, mode, gp, tStep);
600  break;
602  // elasto-plastic stiffness for regular case
603  //printf("\nAssembling regular algorithmic stiffness matrix.") ;
604  giveRegAlgorithmicStiffMatrix(answer, mode, gp, tStep);
605  break;
607  // elasto-plastic stiffness for vertex case
608  //printf("\nAssembling vertex case algorithmic stiffness matrix.") ;
609  giveVertexAlgorithmicStiffMatrix(answer, mode, gp, tStep);
610  break;
611  default:
612  OOFEM_ERROR("Case did not match.");
613  break;
614  }
615 
616  break;
617 
618  default:
619  OOFEM_ERROR("Switch failed: Only elastic and tangent stiffness are supported.");
620  break;
621  }
622 }
623 
624 void
626  MatResponseMode mode,
627  GaussPoint *gp,
628  TimeStep *tStep)
629 {
630  int i, j;
632  static_cast< DruckerPragerPlasticitySMStatus * >( this->giveStatus(gp) );
633 
634  const FloatArray &stressVector = status->giveTempStressVector();
635  FloatArray deviatoricStress;
636  computeDeviatoricVolumetricSplit(deviatoricStress, stressVector);
637  double normOfStress = sqrt( 2. * computeSecondStressInvariant(deviatoricStress) );
638  // elastic constants
639  double eM = LEMaterial->give(Ex, gp);
640  double nu = LEMaterial->give(NYxz, gp);
641  double gM = eM / ( 2. * ( 1. + nu ) );
642  double kM = eM / ( 3. * ( 1. - 2. * nu ) );
643 
644 
645 
646  FloatArray flowDir = deviatoricStress;
647  flowDir.times(1. / normOfStress);
648 
649  double kappa = status->giveKappa();
650  double tempKappa = status->giveTempKappa();
651  double deltaKappa = tempKappa - kappa;
652  double deltaLambdaStar = sqrt(2.) * gM * deltaKappa / kFactor / normOfStress;
653  double hStar = kFactor * computeYieldStressPrime(tempKappa, eM);
654 
655  //exclude division by zero
656  if ( hStar == 0. ) {
657  OOFEM_ERROR("computeYieldStressPrime is zero. This happens mainly due to excessive softening.");
658  }
659 
660  double a_const = 1. + deltaLambdaStar;
661  double b_const = 3. * alpha * alphaPsi * kM / hStar - deltaLambdaStar / 3.;
662  double c_const = 3. * sqrt(2.) * alphaPsi * kM / 2. / hStar;
663  double d_const = sqrt(2.) * alpha * gM / hStar;
664  double e_const = gM / hStar - deltaLambdaStar;
665 
666  FloatMatrix A_Matrix(6, 6);
667  A_Matrix.zero();
668  for ( i = 1; i < 7; i++ ) {
669  A_Matrix.at(i, i) = a_const;
670  }
671 
672  for ( i = 1; i < 4; i++ ) {
673  for ( j = 1; j < 4; j++ ) {
674  A_Matrix.at(i, j) += b_const;
675  }
676  }
677 
678  for ( i = 1; i < 4; i++ ) {
679  for ( j = 1; j < 4; j++ ) {
680  A_Matrix.at(i, j) += c_const * flowDir.at(j);
681  }
682 
683  for ( j = 4; j < 7; j++ ) {
684  A_Matrix.at(i, j) += 2. *c_const *flowDir.at(j);
685  }
686  }
687 
688  for ( i = 1; i < 7; i++ ) {
689  for ( j = 1; j < 4; j++ ) {
690  A_Matrix.at(i, j) += d_const * flowDir.at(i);
691  }
692  }
693 
694  for ( i = 1; i < 7; i++ ) {
695  for ( j = 1; j < 4; j++ ) {
696  A_Matrix.at(i, j) += e_const * flowDir.at(i) * flowDir.at(j);
697  }
698 
699  // account for engineering notation
700  for ( j = 4; j < 7; j++ ) {
701  A_Matrix.at(i, j) += 2. *e_const *flowDir.at(i) * flowDir.at(j);
702  }
703  }
704 
705  FloatMatrix De;
706  LEMaterial->give3dMaterialStiffnessMatrix(De, mode, gp, tStep);
707 
708  // answer is A_Matrix^-1 * De
709  A_Matrix.solveForRhs(De, answer);
710 }
711 
712 void
714  MatResponseMode mode,
715  GaussPoint *gp,
716  TimeStep *tStep)
717 {
719  static_cast< DruckerPragerPlasticitySMStatus * >( this->giveStatus(gp) );
720 
721  double tempKappa = status->giveTempKappa();
722  double deltaKappa = tempKappa - status->giveKappa();
723  // elastic constants
724  double eM = LEMaterial->give(Ex, gp);
725  double nu = LEMaterial->give(NYxz, gp);
726  //double gM = eM / ( 2. * ( 1. + nu ) );
727  double kM = eM / ( 3. * ( 1. - 2. * nu ) );
728 
729  if ( deltaKappa <= 0. ) {
730  // This case occurs in the first iteration of a step.
731  // printf("deltaKappa<=0. for vertex case algorithmic stiffness, i.e. continuum tangent stiffness. Since the continuum tangent stiffness does not exist at the vertex, elastic stiffness is used instead. This will cause the loss of quadratic convergence.\n") ;
732  LEMaterial->give3dMaterialStiffnessMatrix(answer, mode, gp, tStep);
733  }
734 
735  double deltaVolumetricPlasticStrain =
737  double HBar = computeYieldStressPrime(tempKappa, eM);
738 
739  // compute elastic trial strain deviator of latest temp-state
740  FloatArray strainDeviator;
741  computeDeviatoricVolumetricSplit(strainDeviator, status->giveTempStrainVector());
742 
743  FloatArray elasticStrainDeviator = strainDeviator;
744  elasticStrainDeviator.subtract( status->givePlasticStrainDeviator() );
745 
746  double a_const =
747  kM * HBar / ( HBar * deltaVolumetricPlasticStrain + 9. / 2. * alpha * kM * deltaKappa );
748 
749  if ( ( HBar * deltaVolumetricPlasticStrain + 9. / 2. * alpha * kM * deltaKappa ) == 0. ) {
750  OOFEM_ERROR("Tangent type is singular, material ID %d\n", this->giveNumber() );
751  }
752  // compute the algorithmic tangent stiffness
753 
754  answer.resize(6, 6);
755  answer.zero();
756  for ( int i = 1; i < 4; i++ ) {
757  for ( int j = 1; j < 4; j++ ) {
758  answer.at(i, j) = deltaVolumetricPlasticStrain;
759  }
760  }
761 
762  for ( int i = 1; i < 4; i++ ) {
763  for ( int j = 1; j < 4; j++ ) {
764  answer.at(i, j) += elasticStrainDeviator.at(j);
765  }
766 
767  for ( int j = 4; j < 7; j++ ) {
768  answer.at(i, j) += .5 * elasticStrainDeviator.at(j);
769  }
770  }
771 
772  answer.times(a_const);
773 }
774 
775 int
777  GaussPoint *gp,
778  InternalStateType type,
779  TimeStep *tStep)
780 {
781  const DruckerPragerPlasticitySMStatus *status =
782  static_cast< DruckerPragerPlasticitySMStatus * >( giveStatus(gp) );
783 
784  switch ( type ) {
785  case IST_PlasticStrainTensor:
786  status->givePlasticStrainVector(answer);
787  return 1;
788 
789  case IST_DamageTensor:
790  answer.resize(6);
791  answer.zero();
792  answer.at(1) = answer.at(2) = answer.at(3) = status->giveKappa();
793  return 1;
794 
795  default:
796  return StructuralMaterial :: giveIPValue(answer, gp, type, tStep);
797  }
798 }
799 
802 {
804 }
805 
806 
807 double
809 {
811  static_cast< DruckerPragerPlasticitySMStatus * >( giveStatus(gp) );
812  int state_flag = status->giveStateFlag();
813 
814  if ( ( state_flag == DruckerPragerPlasticitySMStatus :: DP_Vertex ) ||
816  return 20.;
817  } else {
818  return 1.0;
819  }
820 }
821 
822 } // end namespace oofem
823 
824 #undef PRINTFDP
virtual void updateYourself(TimeStep *tStep)
Update equilibrium history variables according to temp-variables.
Definition: structuralms.C:96
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Returns the integration point corresponding value in Reduced form.
InternalStateType
Type representing the physical meaning of element or constitutive model internal variable.
void subtract(const FloatArray &src)
Subtracts array src to receiver.
Definition: floatarray.C:258
void letTempStrainVectorBe(const FloatArray &v)
Assigns tempStrainVector to given vector v.
Definition: structuralms.h:137
#define _IFT_DruckerPragerPlasticitySM_alphapsi
Dilatancy coefficient.
virtual void initTempStatus()
Initializes the temporary internal variables, describing the current state according to previously re...
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Returns material status of receiver in given integration point.
Definition: material.C:244
Class and object Domain.
Definition: domain.h:115
static void applyDeviatoricElasticCompliance(FloatArray &strain, const FloatArray &stress, double EModulus, double nu)
bool solveForRhs(const FloatArray &b, FloatArray &answer, bool transpose=false)
Solves the system of linear equations .
Definition: floatmatrix.C:1112
int newtonIter
Maximum number of iterations for stress return.
FloatArray tempStrainVector
Temporary strain vector in reduced form (to find balanced state)
Definition: structuralms.h:75
static void computeDeviatoricVolumetricSum(FloatArray &s, const FloatArray &dev, double mean)
const FloatArray & givePlasticStrainDeviator() const
Get the plastic strain deviator from the material status.
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
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Returns the integration point corresponding value in Reduced form.
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
This class implements a structural material status information.
Definition: structuralms.h:65
#define _IFT_DruckerPragerPlasticitySM_hm
FloatArray stressVector
Equilibrated stress vector in reduced form.
Definition: structuralms.h:71
#define _IFT_DruckerPragerPlasticitySM_newtoniter
#define Ex
Definition: matconst.h:59
virtual contextIOResultType restoreContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Restores the receiver state previously written in stream.
DruckerPragerPlasticitySM(int n, Domain *d)
Constructor.
void giveRegAlgorithmicStiffMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)
Compute and give back algorithmic stiffness matrix for the regular case (no vertex).
General IO error.
void performRegularReturn(double eM, double gM, double kM, double trialStressJTwo, FloatArray &stressDeviator, double &volumetricStress, double &tempKappa)
Perform stress return for regular case, i.e.
virtual double computeYieldStressPrime(double kappa, double eM) const
Compute derivative of yield stress with respect to the hardening variable kappa.
virtual void printOutputAt(FILE *file, TimeStep *tStep)
Print receiver&#39;s output to given stream.
virtual void printOutputAt(FILE *file, TimeStep *tStep)
Print receiver&#39;s output to given stream.
Definition: structuralms.C:73
#define OOFEM_LOG_DEBUG(...)
Definition: logger.h:128
double giveTempVolumetricPlasticStrain() const
Get the temp value of the volumetric strain deviator from the material status.
MatResponseMode
Describes the character of characteristic material matrix.
virtual int read(int *data, int count)=0
Reads count integer values into array pointed by data.
#define THROW_CIOERR(e)
Definition: contextioerr.h:61
double limitYieldStress
Parameter of the exponential hardening law.
double giveVolumetricPlasticStrain() const
Get the volumetric plastic strain from the material status.
virtual int write(const int *data, int count)=0
Writes count integer values from array pointed by data.
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
#define _IFT_DruckerPragerPlasticitySM_iys
Initial yield stress under pure shear.
double computeYieldValue(double meanStress, double JTwo, double kappa, double eM) const
Compute the yield value based on stress and hardening variable.
double kappaC
Parameter of the exponential laws.
#define _IFT_DruckerPragerPlasticitySM_ht
This class implements an isotropic linear elastic material in a finite element problem.
virtual contextIOResultType saveContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Stores receiver state to output stream.
FloatArray plasticStrainDeviator
Deviatoric of plastic strain.
#define OOFEM_ERROR(...)
Definition: error.h:61
void letTempPlasticStrainDeviatorBe(const FloatArray &v)
Assign the temp value of deviatoric plastic strain.
virtual void give3dMaterialStiffnessMatrix(FloatMatrix &answer, MatResponseMode, GaussPoint *gp, TimeStep *tStep)
Computes full 3d material stiffness matrix at given integration point, time, respecting load history ...
virtual double computeYieldStressInShear(double kappa, double eM) const
Compute the current yield stress in pure shear of the Drucker-Prager model according to the used hard...
void times(double f)
Multiplies receiver by factor f.
Definition: floatmatrix.C:1594
#define _IFT_DruckerPragerPlasticitySM_lys
void performLocalStressReturn(GaussPoint *gp, const FloatArray &strain)
Perform a standard local stress return using the function computeYieldValue at the specified Gauss po...
contextIOResultType restoreYourself(DataStream &stream)
Definition: floatarray.C:895
void giveStressDependentPartOfStrainVector_3d(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedStrainVector, TimeStep *tStep, ValueModeType mode)
#define _IFT_DruckerPragerPlasticitySM_alpha
Friction coefficient.
const FloatArray & giveTempStrainVector() const
Returns the const pointer to receiver&#39;s temporary strain vector.
Definition: structuralms.h:115
double giveTempKappa() const
Get the temp value of the hardening variable from the material status.
void giveVertexAlgorithmicStiffMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)
Compute consistent stiffness matrix for the vertex case.
double at(int i, int j) const
Coefficient access function.
Definition: floatmatrix.h:176
This class implements the material status associated to DruckerPragerPlasticitySM.
virtual contextIOResultType restoreContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Restores the receiver state previously written in stream.
Definition: structuralms.C:157
void givePlasticStrainVector(FloatArray &answer) const
Get the full plastic strain vector from the material status.
virtual void giveRealStressVector_3d(FloatArray &answer, GaussPoint *gp, const FloatArray &strainVector, TimeStep *tStep)
Default implementation relies on giveRealStressVector for second Piola-Kirchoff stress.
Abstract base class representing a material status information.
Definition: matstatus.h:84
Class representing vector of real numbers.
Definition: floatarray.h:82
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
IsotropicLinearElasticMaterial * LEMaterial
Associated linear elastic material.
double hardeningModulus
Hardening modulus normalized with the elastic modulus, parameter of the linear hardening/softening la...
void letTempStateFlagBe(int v)
Assign the temp value of the state flag.
FloatArray strainVector
Equilibrated strain vector in reduced form.
Definition: structuralms.h:69
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
IRResultType
Type defining the return values of InputRecord reading operations.
Definition: irresulttype.h:47
void performVertexReturn(double eM, double gM, double kM, double trialStressJTwo, FloatArray &stressDeviator, double &volumetricStress, double &tempKappa, double volumetricElasticTrialStrain, double kappa)
Perform stress return for vertex case, i.e.
void letTempStressVectorBe(const FloatArray &v)
Assigns tempStressVector to given vector v.
Definition: structuralms.h:135
int hardeningType
Controls the hardening function in the yield stress: 1: linear hardening/softening with cutoff at zer...
double alpha
Friction coefficient, parameter of the yield criterion.
double kFactor
Scalar factor between rate of plastic multiplier and rate of hardening variable.
static void applyDeviatoricElasticStiffness(FloatArray &stress, const FloatArray &strain, double EModulus, double nu)
DruckerPragerPlasticitySMStatus(int n, Domain *d, GaussPoint *gp)
Constructor.
void resize(int rows, int cols)
Checks size of receiver towards requested bounds.
Definition: floatmatrix.C:1358
static double computeSecondStressInvariant(const FloatArray &s)
int giveStateFlag() const
Get the state flag from the material status.
Class representing the general Input Record.
Definition: inputrecord.h:101
bool checkForVertexCase(double eM, double gM, double kM, double trialStressJTwo, double volumetricStress, double tempKappa)
Check if the trial stress state falls within the vertex region.
virtual double predictRelativeComputationalCost(GaussPoint *gp)
Returns the weight representing relative computational cost of receiver The reference material model ...
void letTempKappaBe(double v)
Assign the temp value of the hardening variable.
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
void times(double s)
Multiplies receiver with scalar.
Definition: floatarray.C:818
static double computeDeviatoricVolumetricSplit(FloatArray &dev, const FloatArray &s)
Computes split of receiver into deviatoric and volumetric part.
virtual void give3dMaterialStiffnessMatrix(FloatMatrix &answer, MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep)
Computes full 3d material stiffness matrix at given integration point, time, respecting load history ...
long ContextMode
Context mode (mask), defining the type of information written/read to/from context.
Definition: contextmode.h:43
Abstract base class for all "structural" constitutive models.
double volumetricPlasticStrain
Volumetric plastic strain.
void zero()
Zeroes all coefficient of receiver.
Definition: floatmatrix.C:1326
virtual void initTempStatus()
Initializes the temporary internal variables, describing the current state according to previously re...
Definition: structuralms.C:108
Domain * giveDomain() const
Definition: femcmpnn.h:100
double alphaPsi
Dilatancy coefficient, parameter of the flow rule.
virtual void updateYourself(TimeStep *tStep)
Update equilibrium history variables according to temp-variables.
#define _IFT_DruckerPragerPlasticitySM_yieldtol
virtual double give(int aProperty, GaussPoint *gp)
Returns the value of material property &#39;aProperty&#39;.
REGISTER_Material(DummyMaterial)
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:78
const FloatArray & giveTempStressVector() const
Returns the const pointer to receiver&#39;s temporary stress vector.
Definition: structuralms.h:117
virtual contextIOResultType saveContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Stores receiver state to output stream.
Definition: structuralms.C:133
the oofem namespace is to define a context or scope in which all oofem names are defined.
void letTempVolumetricPlasticStrainBe(double v)
Assign the temp value of volumetric plastic strain.
#define IR_GIVE_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:69
virtual void initTempStatus(GaussPoint *gp)
Initializes temporary variables stored in integration point status at the beginning of new time step...
Definition: material.C:267
int giveNumber() const
Definition: femcmpnn.h:107
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
FloatArray tempStressVector
Temporary stress vector in reduced form (increments are used mainly in nonlinear analysis) ...
Definition: structuralms.h:73
double initialYieldStress
Parameter of all three laws, this is the initial value of the yield stress in pure shear...
#define _IFT_DruckerPragerPlasticitySM_kc
Class representing integration point in finite element program.
Definition: gausspoint.h:93
#define OOFEM_WARNING(...)
Definition: error.h:62
Class representing solution step.
Definition: timestep.h:80
void add(const FloatArray &src)
Adds array src to receiver.
Definition: floatarray.C:156
#define NYxz
Definition: matconst.h:51
double giveKappa() const
Get the hardening variable from the material status.
int state_flag
Indicates the state (i.e. elastic, yielding, vertex, unloading) of the Gauss point.
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631
virtual MaterialStatus * CreateStatus(GaussPoint *gp) const
Creates new copy of associated status and inserts it into given integration point.

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