OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
j2plasticmaterial.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 
35 #include "j2plasticmaterial.h"
37 #include "gausspoint.h"
38 #include "floatmatrix.h"
39 #include "floatarray.h"
40 #include "intarray.h"
41 #include "mathfem.h"
42 #include "classfactory.h"
43 #include "dynamicinputrecord.h"
44 
45 namespace oofem {
46 REGISTER_Material(J2plasticMaterial);
47 
49 {
52 }
53 
55 {
56 }
57 
60 {
61  IRResultType result; // Required by IR_GIVE_FIELD macro
62  double value;
63 
65  if ( result != IRRT_OK ) return result;
67  if ( result != IRRT_OK ) return result;
68 
70  k = value / sqrt(3.0);
71 
72  kinematicModuli = 0.0;
74 
75  isotropicModuli = 0.0;
77 
78  if ( fabs(kinematicModuli) > 1.e-12 ) {
80  }
81 
82  if ( fabs(isotropicModuli) > 1.e-12 ) {
84  }
85 
86  return IRRT_OK;
87 }
88 
90 {
92 
96  input.setField(0.0, _IFT_IsotropicLinearElasticMaterial_talpha); // TODO: dirty fix
97 
98 
99  input.setField(k * sqrt(3.0), _IFT_J2plasticMaterial_ry);
102 }
103 
104 
107 {
108  return new PlasticMaterialStatus(1, this->giveDomain(), gp, this->giveSizeOfReducedHardeningVarsVector(gp));
109 }
110 
111 
112 FloatArray *
114  FloatArray *strainSpaceHardeningVariables)
115 {
116  // in full stress strain space
117 
118  int count = 0, size = this->giveSizeOfFullHardeningVarsVector(), isize, rSize;
119  IntArray mask;
120 
121  if ( !hasHardening() ) {
122  return NULL;
123  }
124 
125  FloatArray *answer = new FloatArray(size);
127  isize = mask.giveSize();
128  rSize = this->giveSizeOfReducedHardeningVarsVector(gp);
129 
130  /* kinematic hardening variables are first */
131  if ( this->kinematicHardeningFlag ) {
132  for ( int i = 1; i <= isize; i++ ) {
133  // to be consistent with equivalent plastic strain formulation
134  // we multiply by (sqrt(2.)*2./3.)
135  answer->at( mask.at(i) ) = ( sqrt(2.) * 2. / 3. ) * this->kinematicModuli * strainSpaceHardeningVariables->at(i);
136  }
137 
138  count = 6;
139  }
140 
141  if ( this->isotropicHardeningFlag ) {
142  answer->at(count + 1) = this->isotropicModuli *
143  strainSpaceHardeningVariables->at(rSize);
144  }
145 
146  answer->negated();
147  return answer;
148 }
149 
150 double
152  FloatArray *stressSpaceHardeningVars)
153 {
154  double f;
155  FloatArray helpVector, backStress;
156 
157  if ( this->kinematicHardeningFlag ) {
158  if ( stressVector != NULL ) {
159  this->giveStressBackVector(backStress, * stressSpaceHardeningVars);
160  helpVector = * stressVector;
161  helpVector.add(backStress);
162  } else {
163  return -k;
164  }
165  } else {
166  helpVector = * stressVector;
167  }
168 
169  f = sqrt( this->computeJ2InvariantAt(& helpVector) );
170 
171  //if (this->kinematicHardeningFlag) delete helpVector;
172 
173  return f + sqrt(1. / 3.) * this->giveIsotropicHardeningVar(stressSpaceHardeningVars) - this->k;
174 }
175 
176 
177 void
179  GaussPoint *gp,
180  FloatArray *strainSpaceHardeningVariables,
181  TimeStep *tStep)
182 {
183  /* computes hardening moduli in reduced stress strain space (for kinematic back-stress)*/
184  int size = this->giveSizeOfReducedHardeningVarsVector(gp);
185 
186  if ( !hasHardening() ) {
187  answer.clear();
188  return;
189  }
190 
191  answer.resize(size, size);
192  answer.zero();
193 
194  /* kinematic hardening variables are first */
195  if ( this->kinematicHardeningFlag ) {
197  for ( int i = 1; i <= ksize; i++ ) {
198  answer.at(i, i) = this->kinematicModuli;
199  }
200  }
201 
202  if ( this->isotropicHardeningFlag ) {
203  answer.at(size, size) = this->isotropicModuli;
204  }
205 }
206 
207 
208 
209 FloatArray *
211  FloatArray *stressSpaceHardeningVars)
212 {
213  /* stress gradient of yield function in full stress - strain space */
214 
215  double f, ax, ay, az, sx, sy, sz;
216  FloatArray *answer = new FloatArray(6);
217  FloatArray helpVector, backStress;
218 
219  if ( this->kinematicHardeningFlag ) {
220  if ( stressVector != NULL ) {
221  this->giveStressBackVector(backStress, * stressSpaceHardeningVars);
222  helpVector = * stressVector;
223  helpVector.add(backStress);
224  } else {
225  return answer;
226  }
227  } else {
228  helpVector = * stressVector;
229  }
230 
231  f = sqrt( this->computeJ2InvariantAt(& helpVector) );
232  // check for yield value zero value
233  if ( fabs(f) < 1.e-6 ) {
234  return answer;
235  }
236 
237  ax = helpVector.at(1);
238  ay = helpVector.at(2);
239  az = helpVector.at(3);
240 
241  sx = ( 2. / 3. ) * ax - ( 1. / 3. ) * ay - ( 1. / 3. ) * az;
242  sy = ( 2. / 3. ) * ay - ( 1. / 3. ) * ax - ( 1. / 3. ) * az;
243  sz = ( 2. / 3. ) * az - ( 1. / 3. ) * ay - ( 1. / 3. ) * ax;
244 
245  answer->at(1) = 0.5 * sx / f;
246  answer->at(2) = 0.5 * sy / f;
247  answer->at(3) = 0.5 * sz / f;
248  answer->at(4) = helpVector.at(4) / f;
249  answer->at(5) = helpVector.at(5) / f;
250  answer->at(6) = helpVector.at(6) / f;
251 
252  //if (this->kinematicHardeningFlag) delete helpVector;
253 
254  return answer;
255 }
256 
257 FloatArray *
259  FloatArray *stressSpaceHardeningVars)
260 {
261  /* computes stress space hardening gradient in reduced stress-strain space */
262 
263  int kcount = 0, size = this->giveSizeOfReducedHardeningVarsVector(gp);
264  //double f,ax,ay,az,sx,sy,sz;
265  FloatArray *answer;
266  FloatArray *fullKinematicGradient, reducedKinematicGrad;
267 
268  if ( !hasHardening() ) {
269  return NULL;
270  }
271 
272  answer = new FloatArray(size);
273 
274  /* kinematic hardening variables first */
275  if ( this->kinematicHardeningFlag ) {
276  fullKinematicGradient = this->ComputeStressGradient(gp, stressVector, stressSpaceHardeningVars);
277  StructuralMaterial :: giveReducedSymVectorForm( reducedKinematicGrad, * fullKinematicGradient, gp->giveMaterialMode() );
278  delete fullKinematicGradient;
279 
280  kcount = reducedKinematicGrad.giveSize();
281  }
282 
283  if ( this->kinematicHardeningFlag ) {
284  for ( int i = 1; i <= kcount; i++ ) {
285  answer->at(i) = reducedKinematicGrad.at(i);
286  }
287  }
288 
289  if ( this->isotropicHardeningFlag ) {
290  answer->at(size) = sqrt(1. / 3.);
291  }
292 
293  return answer;
294 }
295 
296 
297 
298 
299 int
301 {
302  return ( this->kinematicHardeningFlag || this->isotropicHardeningFlag );
303 }
304 
305 
306 void
308  GaussPoint *gp,
309  const FloatArray &stressVector,
310  const FloatArray &stressSpaceHardeningVars)
311 {
312  int size;
313  int imask, jmask;
314  FloatArray helpVector, backStress, df(6);
315  IntArray mask;
316  double f, f32, f12, ax, ay, az;
317 
321 
322  answer.resize(size, size);
323  answer.zero();
324 
325 
326  if ( stressVector.giveSize() != 0 ) {
327  /* kinematic hardening variables first */
328  if ( this->kinematicHardeningFlag ) {
329  this->giveStressBackVector(backStress, stressSpaceHardeningVars);
330  helpVector = stressVector;
331  helpVector.add(backStress);
332  } else {
333  helpVector = stressVector;
334  }
335 
336  f = this->computeJ2InvariantAt(& helpVector);
337  f12 = sqrt(f);
338  f32 = pow(f, 3. / 2.);
339 
340  ax = helpVector.at(1);
341  ay = helpVector.at(2);
342  az = helpVector.at(3);
343 
344  df.at(1) = ( 2. / 3. ) * ax - ( 1. / 3. ) * ay - ( 1. / 3. ) * az;
345  df.at(2) = ( 2. / 3. ) * ay - ( 1. / 3. ) * ax - ( 1. / 3. ) * az;
346  df.at(3) = ( 2. / 3. ) * az - ( 1. / 3. ) * ay - ( 1. / 3. ) * ax;
347  df.at(4) = 2. * helpVector.at(4);
348  df.at(5) = 2. * helpVector.at(5);
349  df.at(6) = 2. * helpVector.at(6);
350 
351  for ( int i = 1; i <= 3; i++ ) {
352  if ( ( imask = mask.at(i) ) == 0 ) {
353  continue;
354  }
355 
356  for ( int j = i; j <= 3; j++ ) {
357  if ( ( jmask = mask.at(j) ) == 0 ) {
358  continue;
359  }
360 
361  if ( i == j ) {
362  answer.at(imask, jmask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j) + 0.5 * ( 1. / f12 ) * ( 4. / 6 );
363  } else {
364  answer.at(imask, jmask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j) + 0.5 * ( 1. / f12 ) * ( -2. / 6 );
365  answer.at(jmask, imask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j) + 0.5 * ( 1. / f12 ) * ( -2. / 6 );
366  }
367  }
368  }
369 
370  for ( int i = 1; i <= 3; i++ ) {
371  if ( ( imask = mask.at(i) ) == 0 ) {
372  continue;
373  }
374 
375  for ( int j = 4; j <= 6; j++ ) {
376  if ( ( jmask = mask.at(j) ) == 0 ) {
377  continue;
378  }
379 
380  answer.at(imask, jmask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j);
381  answer.at(jmask, imask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j);
382  }
383  }
384 
385  for ( int i = 4; i <= 6; i++ ) {
386  if ( ( imask = mask.at(i) ) == 0 ) {
387  continue;
388  }
389 
390  for ( int j = i; j <= 6; j++ ) {
391  if ( ( jmask = mask.at(j) ) == 0 ) {
392  continue;
393  }
394 
395  if ( i == j ) {
396  answer.at(imask, jmask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j) + 0.5 * ( 1. / f12 ) * 2.;
397  } else {
398  answer.at(imask, jmask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j);
399  answer.at(jmask, imask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j);
400  }
401  }
402  }
403  }
404  /* for isotropic hardening: the corresponding part of gradient matrix is zero valued */
405 }
406 
407 
408 void
410  const FloatArray &strainIncrement,
411  TimeStep *tStep)
412 {
413  /* Computes the full trial elastic stress vector */
414  FloatArray reducedAnswer;
415  FloatMatrix reducedModuli;
416 
417  this->giveLinearElasticMaterial()->giveStiffnessMatrix(reducedModuli, ElasticStiffness,
418  gp, tStep);
419 
420  reducedAnswer.beProductOf(reducedModuli, strainIncrement);
421  StructuralMaterial :: giveFullSymVectorForm( answer, reducedAnswer, gp->giveMaterialMode() );
422 }
423 
424 
425 void
427  GaussPoint *gp,
428  TimeStep *tStep)
429 {
430  /* Returns 3d elastic moduli */
431  this->giveLinearElasticMaterial()->give3dMaterialStiffnessMatrix(answer, ElasticStiffness, gp, tStep);
432 }
433 
434 
435 double
437 {
438  double answer;
439  double v1, v2, v3;
440 
441  if ( stressVector == NULL ) {
442  return 0.0;
443  }
444 
445  v1 = ( ( stressVector->at(1) - stressVector->at(2) ) * ( stressVector->at(1) - stressVector->at(2) ) );
446  v2 = ( ( stressVector->at(2) - stressVector->at(3) ) * ( stressVector->at(2) - stressVector->at(3) ) );
447  v3 = ( ( stressVector->at(3) - stressVector->at(1) ) * ( stressVector->at(3) - stressVector->at(1) ) );
448 
449  answer = ( 1. / 6. ) * ( v1 + v2 + v3 ) + stressVector->at(4) * stressVector->at(4) +
450  stressVector->at(5) * stressVector->at(5) + stressVector->at(6) * stressVector->at(6);
451 
452  return answer;
453 }
454 
455 
456 int
458 {
459  /* Returns the size of hardening variables vector */
460  int size = 0;
461 
462  if ( kinematicHardeningFlag ) {
463  size += 6; /* size of full stress vector */
464  }
465 
466  if ( isotropicHardeningFlag ) {
467  size += 1; /* scalar value */
468  }
469 
470  return size;
471 }
472 
473 int
475 {
476  /* Returns the size of hardening variables vector */
477  int size = 0;
478 
479  if ( kinematicHardeningFlag ) {
481  }
482 
483  if ( isotropicHardeningFlag ) {
484  size += 1; /* scalar value */
485  }
486 
487  return size;
488 }
489 
490 
491 void
493  const FloatArray &stressSpaceHardeningVars)
494 {
495  /* returns part of hardening vector corresponding to kinematic hardening */
496  if ( this->kinematicHardeningFlag ) {
497  answer.resize(6);
498  for ( int i = 1; i <= 6; i++ ) {
499  answer.at(i) = stressSpaceHardeningVars.at(i);
500  }
501 
502  return;
503  }
504 
505  answer.clear();
506 }
507 
508 
509 double
511 {
512  /* returns value in hardening vector corresponding to isotropic hardening */
513  if ( !isotropicHardeningFlag ) {
514  return 0.;
515  } else if ( this->kinematicHardeningFlag ) {
516  return stressSpaceHardeningVars->at(7);
517  } else {
518  return stressSpaceHardeningVars->at(1);
519  }
520 }
521 } // end namespace oofem
static int giveSizeOfVoigtSymVector(MaterialMode mmode)
Returns the size of symmetric part of a reduced stress/strain vector according to given mode...
void setField(int item, InputFieldType id)
MaterialMode giveMaterialMode()
Returns corresponding material mode of receiver.
Definition: gausspoint.h:191
static int giveVoigtSymVectorMask(IntArray &answer, MaterialMode mmode)
The same as giveVoigtVectorMask but returns a mask corresponding to a symmetric second order tensor...
virtual void computeTrialStressIncrement(FloatArray &answer, GaussPoint *gp, const FloatArray &strainIncrement, TimeStep *tStep)
Class and object Domain.
Definition: domain.h:115
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
void clear()
Clears receiver (zero size).
Definition: floatarray.h:206
virtual void computeHardeningReducedModuli(FloatMatrix &answer, GaussPoint *gp, FloatArray *strainSpaceHardeningVariables, TimeStep *tStep)
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
static void giveFullSymVectorForm(FloatArray &answer, const FloatArray &vec, MaterialMode matMode)
Converts the reduced unsymmetric Voigt vector (2nd order tensor) to full form.
#define _IFT_J2plasticMaterial_ihm
virtual FloatArray * ComputeStressGradient(GaussPoint *gp, FloatArray *stressVector, FloatArray *stressSpaceHardeningVars)
double givePoissonsRatio()
Returns Poisson&#39;s ratio.
int giveSizeOfReducedHardeningVarsVector(GaussPoint *gp) const
double giveIsotropicHardeningVar(FloatArray *stressSpaceHardeningVars)
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
virtual void giveStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)
Computes the stiffness matrix for giveRealStressVector of receiver in given integration point...
#define _IFT_IsotropicLinearElasticMaterial_talpha
#define _IFT_IsotropicLinearElasticMaterial_n
virtual FloatArray * ComputeStressSpaceHardeningVars(GaussPoint *gp, FloatArray *strainSpaceHardeningVariables)
static void giveReducedSymVectorForm(FloatArray &answer, const FloatArray &vec, MaterialMode matMode)
Converts the full unsymmetric Voigt vector (2nd order tensor) to reduced form.
This class implements an isotropic linear elastic material in a finite element problem.
LinearElasticMaterial * linearElasticMaterial
Reference to bulk (undamaged) material.
virtual void give3dMaterialStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)
Computes full 3d material stiffness matrix at given integration point, time, respecting load history ...
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Receiver becomes the result of the product of aMatrix and anArray.
Definition: floatarray.C:676
#define _IFT_IsotropicLinearElasticMaterial_e
double at(int i, int j) const
Coefficient access function.
Definition: floatmatrix.h:176
LinearElasticMaterial * giveLinearElasticMaterial()
Returns reference to undamaged (bulk) material.
virtual FloatArray * ComputeStressSpaceHardeningVarsReducedGradient(GaussPoint *gp, FloatArray *stressVector, FloatArray *stressSpaceHardeningVars)
Abstract base class representing a material status information.
Definition: matstatus.h:84
virtual void compute3dElasticModuli(FloatMatrix &answer, GaussPoint *gp, TimeStep *tStep)
Class representing vector of real numbers.
Definition: floatarray.h:82
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
friend class PlasticMaterialStatus
void resize(int rows, int cols)
Checks size of receiver towards requested bounds.
Definition: floatmatrix.C:1358
Class representing the general Input Record.
Definition: inputrecord.h:101
#define _IFT_J2plasticMaterial_khm
Class representing the a dynamic Input Record.
virtual void computeReducedGradientMatrix(FloatMatrix &answer, GaussPoint *gp, const FloatArray &stressVector, const FloatArray &stressSpaceHardeningVars)
static void giveInvertedVoigtVectorMask(IntArray &answer, MaterialMode mmode)
Gives the inverted version of giveVoigtVectorMask.
void zero()
Zeroes all coefficient of receiver.
Definition: floatmatrix.C:1326
Domain * giveDomain() const
Definition: femcmpnn.h:100
virtual MaterialStatus * CreateStatus(GaussPoint *gp) const
Creates new copy of associated status and inserts it into given integration point.
virtual double computeYieldValueAt(GaussPoint *gp, FloatArray *stressVector, FloatArray *stressSpaceHardeningVars)
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
REGISTER_Material(DummyMaterial)
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:78
int giveSize() const
Definition: intarray.h:203
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
the oofem namespace is to define a context or scope in which all oofem names are defined.
void clear()
Sets size of receiver to be an empty matrix. It will have zero rows and zero columns size...
Definition: floatmatrix.h:516
#define IR_GIVE_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:69
void negated()
Switches the sign of every coefficient of receiver.
Definition: floatarray.C:739
double giveYoungsModulus()
Returns Young&#39;s modulus.
J2plasticMaterial(int n, Domain *d)
#define _IFT_J2plasticMaterial_ry
Class representing integration point in finite element program.
Definition: gausspoint.h:93
This class implements a general plastic material.
Class representing solution step.
Definition: timestep.h:80
double computeJ2InvariantAt(FloatArray *answer)
void add(const FloatArray &src)
Adds array src to receiver.
Definition: floatarray.C:156
void giveStressBackVector(FloatArray &answer, const FloatArray &stressSpaceHardeningVars)
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:29 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011