OOFEM 3.0
Loading...
Searching...
No Matches
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 - 2025 Borek Patzak
14 *
15 *
16 *
17 * Czech Technical University, Faculty of Civil Engineering,
18 * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19 *
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 */
34
35#include "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
45namespace oofem {
47
48J2plasticMaterial :: J2plasticMaterial(int n, Domain *d) : PlasticMaterial(n, d)
49{
51}
52
53void
54J2plasticMaterial :: initializeFrom(InputRecord &ir)
55{
56 double value;
57
58 PlasticMaterial :: initializeFrom(ir);
59 linearElasticMaterial->initializeFrom(ir);
60
62 k = value / sqrt(3.0);
63
64 kinematicModuli = 0.0;
66
67 isotropicModuli = 0.0;
69
70 if ( fabs(kinematicModuli) > 1.e-12 ) {
72 }
73
74 if ( fabs(isotropicModuli) > 1.e-12 ) {
76 }
77}
78
79void J2plasticMaterial :: giveInputRecord(DynamicInputRecord &input)
80{
81 PlasticMaterial :: giveInputRecord(input);
82
86 input.setField(0.0, _IFT_IsotropicLinearElasticMaterial_talpha); // TODO: dirty fix
87
88
89 input.setField(k * sqrt(3.0), _IFT_J2plasticMaterial_ry);
92}
93
94
95std::unique_ptr<MaterialStatus>
96J2plasticMaterial :: CreateStatus(GaussPoint *gp) const
97{
98 return std::make_unique<PlasticMaterialStatus>(gp, this->giveSizeOfReducedHardeningVarsVector(gp));
99}
100
101
103J2plasticMaterial :: ComputeStressSpaceHardeningVars(GaussPoint *gp,
104 FloatArray *strainSpaceHardeningVariables) const
105{
106 // in full stress strain space
107
108 int count = 0, size = this->giveSizeOfFullHardeningVarsVector(), isize, rSize;
109 IntArray mask;
110
111 if ( !hasHardening() ) {
112 return NULL;
113 }
114
115 FloatArray *answer = new FloatArray(size);
116 StructuralMaterial :: giveVoigtSymVectorMask( mask, gp->giveMaterialMode() );
117 isize = mask.giveSize();
118 rSize = this->giveSizeOfReducedHardeningVarsVector(gp);
119
120 /* kinematic hardening variables are first */
121 if ( this->kinematicHardeningFlag ) {
122 for ( int i = 1; i <= isize; i++ ) {
123 // to be consistent with equivalent plastic strain formulation
124 // we multiply by (sqrt(2.)*2./3.)
125 answer->at( mask.at(i) ) = ( sqrt(2.) * 2. / 3. ) * this->kinematicModuli * strainSpaceHardeningVariables->at(i);
126 }
127
128 count = 6;
129 }
130
131 if ( this->isotropicHardeningFlag ) {
132 answer->at(count + 1) = this->isotropicModuli *
133 strainSpaceHardeningVariables->at(rSize);
134 }
135
136 answer->negated();
137 return answer;
138}
139
140double
141J2plasticMaterial :: computeYieldValueAt(GaussPoint *gp, FloatArray *stressVector,
142 FloatArray *stressSpaceHardeningVars) const
143{
144 double f;
145 FloatArray helpVector, backStress;
146
147 if ( this->kinematicHardeningFlag ) {
148 if ( stressVector != NULL ) {
149 this->giveStressBackVector(backStress, * stressSpaceHardeningVars);
150 helpVector = * stressVector;
151 helpVector.add(backStress);
152 } else {
153 return -k;
154 }
155 } else {
156 helpVector = * stressVector;
157 }
158
159 f = sqrt( this->computeJ2InvariantAt(& helpVector) );
160
161 //if (this->kinematicHardeningFlag) delete helpVector;
162
163 return f + sqrt(1. / 3.) * this->giveIsotropicHardeningVar(stressSpaceHardeningVars) - this->k;
164}
165
166
167void
168J2plasticMaterial :: computeHardeningReducedModuli(FloatMatrix &answer,
169 GaussPoint *gp,
170 FloatArray *strainSpaceHardeningVariables,
171 TimeStep *tStep) const
172{
173 /* computes hardening moduli in reduced stress strain space (for kinematic back-stress)*/
174 int size = this->giveSizeOfReducedHardeningVarsVector(gp);
175
176 if ( !hasHardening() ) {
177 answer.clear();
178 return;
179 }
180
181 answer.resize(size, size);
182 answer.zero();
183
184 /* kinematic hardening variables are first */
185 if ( this->kinematicHardeningFlag ) {
186 int ksize = StructuralMaterial :: giveSizeOfVoigtSymVector( gp->giveMaterialMode() );
187 for ( int i = 1; i <= ksize; i++ ) {
188 answer.at(i, i) = this->kinematicModuli;
189 }
190 }
191
192 if ( this->isotropicHardeningFlag ) {
193 answer.at(size, size) = this->isotropicModuli;
194 }
195}
196
197
198
200J2plasticMaterial :: ComputeStressGradient(GaussPoint *gp, FloatArray *stressVector,
201 FloatArray *stressSpaceHardeningVars) const
202{
203 /* stress gradient of yield function in full stress - strain space */
204
205 double f, ax, ay, az, sx, sy, sz;
206 FloatArray *answer = new FloatArray(6);
207 FloatArray helpVector, backStress;
208
209 if ( this->kinematicHardeningFlag ) {
210 if ( stressVector != NULL ) {
211 this->giveStressBackVector(backStress, * stressSpaceHardeningVars);
212 helpVector = * stressVector;
213 helpVector.add(backStress);
214 } else {
215 return answer;
216 }
217 } else {
218 helpVector = * stressVector;
219 }
220
221 f = sqrt( this->computeJ2InvariantAt(& helpVector) );
222 // check for yield value zero value
223 if ( fabs(f) < 1.e-6 ) {
224 return answer;
225 }
226
227 ax = helpVector.at(1);
228 ay = helpVector.at(2);
229 az = helpVector.at(3);
230
231 sx = ( 2. / 3. ) * ax - ( 1. / 3. ) * ay - ( 1. / 3. ) * az;
232 sy = ( 2. / 3. ) * ay - ( 1. / 3. ) * ax - ( 1. / 3. ) * az;
233 sz = ( 2. / 3. ) * az - ( 1. / 3. ) * ay - ( 1. / 3. ) * ax;
234
235 answer->at(1) = 0.5 * sx / f;
236 answer->at(2) = 0.5 * sy / f;
237 answer->at(3) = 0.5 * sz / f;
238 answer->at(4) = helpVector.at(4) / f;
239 answer->at(5) = helpVector.at(5) / f;
240 answer->at(6) = helpVector.at(6) / f;
241
242 //if (this->kinematicHardeningFlag) delete helpVector;
243
244 return answer;
245}
246
248J2plasticMaterial :: ComputeStressSpaceHardeningVarsReducedGradient(GaussPoint *gp, FloatArray *stressVector,
249 FloatArray *stressSpaceHardeningVars) const
250{
251 /* computes stress space hardening gradient in reduced stress-strain space */
252
253 int kcount = 0, size = this->giveSizeOfReducedHardeningVarsVector(gp);
254 //double f,ax,ay,az,sx,sy,sz;
255 FloatArray *answer;
256 FloatArray *fullKinematicGradient, reducedKinematicGrad;
257
258 if ( !hasHardening() ) {
259 return NULL;
260 }
261
262 answer = new FloatArray(size);
263
264 /* kinematic hardening variables first */
265 if ( this->kinematicHardeningFlag ) {
266 fullKinematicGradient = this->ComputeStressGradient(gp, stressVector, stressSpaceHardeningVars);
267 StructuralMaterial :: giveReducedSymVectorForm( reducedKinematicGrad, * fullKinematicGradient, gp->giveMaterialMode() );
268 delete fullKinematicGradient;
269
270 kcount = reducedKinematicGrad.giveSize();
271 }
272
273 if ( this->kinematicHardeningFlag ) {
274 for ( int i = 1; i <= kcount; i++ ) {
275 answer->at(i) = reducedKinematicGrad.at(i);
276 }
277 }
278
279 if ( this->isotropicHardeningFlag ) {
280 answer->at(size) = sqrt(1. / 3.);
281 }
282
283 return answer;
284}
285
286
287
288
289int
290J2plasticMaterial :: hasHardening() const
291{
292 return ( this->kinematicHardeningFlag || this->isotropicHardeningFlag );
293}
294
295
296void
297J2plasticMaterial :: computeReducedGradientMatrix(FloatMatrix &answer,
298 GaussPoint *gp,
299 const FloatArray &stressVector,
300 const FloatArray &stressSpaceHardeningVars) const
301{
302 int size;
303 int imask, jmask;
304 FloatArray helpVector, backStress, df(6);
305 IntArray mask;
306 double f, f32, f12, ax, ay, az;
307
308 StructuralMaterial :: giveInvertedVoigtVectorMask( mask, gp->giveMaterialMode() );
309 size = StructuralMaterial :: giveSizeOfVoigtSymVector( gp->giveMaterialMode() ) +
311
312 answer.resize(size, size);
313 answer.zero();
314
315
316 if ( stressVector.giveSize() != 0 ) {
317 /* kinematic hardening variables first */
318 if ( this->kinematicHardeningFlag ) {
319 this->giveStressBackVector(backStress, stressSpaceHardeningVars);
320 helpVector = stressVector;
321 helpVector.add(backStress);
322 } else {
323 helpVector = stressVector;
324 }
325
326 f = this->computeJ2InvariantAt(& helpVector);
327 f12 = sqrt(f);
328 f32 = pow(f, 3. / 2.);
329
330 ax = helpVector.at(1);
331 ay = helpVector.at(2);
332 az = helpVector.at(3);
333
334 df.at(1) = ( 2. / 3. ) * ax - ( 1. / 3. ) * ay - ( 1. / 3. ) * az;
335 df.at(2) = ( 2. / 3. ) * ay - ( 1. / 3. ) * ax - ( 1. / 3. ) * az;
336 df.at(3) = ( 2. / 3. ) * az - ( 1. / 3. ) * ay - ( 1. / 3. ) * ax;
337 df.at(4) = 2. * helpVector.at(4);
338 df.at(5) = 2. * helpVector.at(5);
339 df.at(6) = 2. * helpVector.at(6);
340
341 for ( int i = 1; i <= 3; i++ ) {
342 if ( ( imask = mask.at(i) ) == 0 ) {
343 continue;
344 }
345
346 for ( int j = i; j <= 3; j++ ) {
347 if ( ( jmask = mask.at(j) ) == 0 ) {
348 continue;
349 }
350
351 if ( i == j ) {
352 answer.at(imask, jmask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j) + 0.5 * ( 1. / f12 ) * ( 4. / 6 );
353 } else {
354 answer.at(imask, jmask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j) + 0.5 * ( 1. / f12 ) * ( -2. / 6 );
355 answer.at(jmask, imask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j) + 0.5 * ( 1. / f12 ) * ( -2. / 6 );
356 }
357 }
358 }
359
360 for ( int i = 1; i <= 3; i++ ) {
361 if ( ( imask = mask.at(i) ) == 0 ) {
362 continue;
363 }
364
365 for ( int j = 4; j <= 6; j++ ) {
366 if ( ( jmask = mask.at(j) ) == 0 ) {
367 continue;
368 }
369
370 answer.at(imask, jmask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j);
371 answer.at(jmask, imask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j);
372 }
373 }
374
375 for ( int i = 4; i <= 6; i++ ) {
376 if ( ( imask = mask.at(i) ) == 0 ) {
377 continue;
378 }
379
380 for ( int j = i; j <= 6; j++ ) {
381 if ( ( jmask = mask.at(j) ) == 0 ) {
382 continue;
383 }
384
385 if ( i == j ) {
386 answer.at(imask, jmask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j) + 0.5 * ( 1. / f12 ) * 2.;
387 } else {
388 answer.at(imask, jmask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j);
389 answer.at(jmask, imask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j);
390 }
391 }
392 }
393 }
394 /* for isotropic hardening: the corresponding part of gradient matrix is zero valued */
395}
396
397
398void
399J2plasticMaterial :: computeTrialStressIncrement(FloatArray &answer, GaussPoint *gp,
400 const FloatArray &strainIncrement,
401 TimeStep *tStep) const
402{
403 /* Computes the full trial elastic stress vector */
404 FloatArray reducedAnswer;
405 FloatMatrix reducedModuli;
406
407 this->linearElasticMaterial->giveStiffnessMatrix(reducedModuli, ElasticStiffness,
408 gp, tStep);
409
410 reducedAnswer.beProductOf(reducedModuli, strainIncrement);
411 StructuralMaterial :: giveFullSymVectorForm( answer, reducedAnswer, gp->giveMaterialMode() );
412}
413
414
415void
416J2plasticMaterial :: compute3dElasticModuli(FloatMatrix &answer,
417 GaussPoint *gp,
418 TimeStep *tStep) const
419{
420 /* Returns 3d elastic moduli */
421 answer = this->linearElasticMaterial->give3dMaterialStiffnessMatrix(ElasticStiffness, gp, tStep);
422}
423
424
425double
426J2plasticMaterial :: computeJ2InvariantAt(FloatArray *stressVector) const
427{
428 double answer;
429 double v1, v2, v3;
430
431 if ( stressVector == NULL ) {
432 return 0.0;
433 }
434
435 v1 = ( ( stressVector->at(1) - stressVector->at(2) ) * ( stressVector->at(1) - stressVector->at(2) ) );
436 v2 = ( ( stressVector->at(2) - stressVector->at(3) ) * ( stressVector->at(2) - stressVector->at(3) ) );
437 v3 = ( ( stressVector->at(3) - stressVector->at(1) ) * ( stressVector->at(3) - stressVector->at(1) ) );
438
439 answer = ( 1. / 6. ) * ( v1 + v2 + v3 ) + stressVector->at(4) * stressVector->at(4) +
440 stressVector->at(5) * stressVector->at(5) + stressVector->at(6) * stressVector->at(6);
441
442 return answer;
443}
444
445
446int
447J2plasticMaterial :: giveSizeOfFullHardeningVarsVector() const
448{
449 /* Returns the size of hardening variables vector */
450 int size = 0;
451
453 size += 6; /* size of full stress vector */
454 }
455
457 size += 1; /* scalar value */
458 }
459
460 return size;
461}
462
463int
464J2plasticMaterial :: giveSizeOfReducedHardeningVarsVector(GaussPoint *gp) const
465{
466 /* Returns the size of hardening variables vector */
467 int size = 0;
468
470 size += StructuralMaterial :: giveSizeOfVoigtSymVector( gp->giveMaterialMode() );
471 }
472
474 size += 1; /* scalar value */
475 }
476
477 return size;
478}
479
480
481void
482J2plasticMaterial :: giveStressBackVector(FloatArray &answer,
483 const FloatArray &stressSpaceHardeningVars) const
484{
485 /* returns part of hardening vector corresponding to kinematic hardening */
486 if ( this->kinematicHardeningFlag ) {
487 answer.resize(6);
488 for ( int i = 1; i <= 6; i++ ) {
489 answer.at(i) = stressSpaceHardeningVars.at(i);
490 }
491
492 return;
493 }
494
495 answer.clear();
496}
497
498
499double
500J2plasticMaterial :: giveIsotropicHardeningVar(FloatArray *stressSpaceHardeningVars) const
501{
502 /* returns value in hardening vector corresponding to isotropic hardening */
503 if ( !isotropicHardeningFlag ) {
504 return 0.;
505 } else if ( this->kinematicHardeningFlag ) {
506 return stressSpaceHardeningVars->at(7);
507 } else {
508 return stressSpaceHardeningVars->at(1);
509 }
510}
511} // end namespace oofem
#define REGISTER_Material(class)
void setField(int item, InputFieldType id)
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:689
void add(const FloatArray &src)
Definition floatarray.C:218
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
*Sets size of receiver to be an empty matrix It will have zero rows and zero columns size void clear()
void zero()
Zeroes all coefficient of receiver.
double at(std::size_t i, std::size_t j) const
MaterialMode giveMaterialMode()
Returns corresponding material mode of receiver.
Definition gausspoint.h:190
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
double giveYoungsModulus() const
Returns Young's modulus.
double givePoissonsRatio() const
Returns Poisson's ratio.
int hasHardening() const override
int giveSizeOfReducedHardeningVarsVector(GaussPoint *gp) const override
double computeJ2InvariantAt(FloatArray *answer) const
void giveStressBackVector(FloatArray &answer, const FloatArray &stressSpaceHardeningVars) const
int giveSizeOfFullHardeningVarsVector() const override
FloatArray * ComputeStressGradient(GaussPoint *gp, FloatArray *stressVector, FloatArray *stressSpaceHardeningVars) const override
double giveIsotropicHardeningVar(FloatArray *stressSpaceHardeningVars) const
LinearElasticMaterial * linearElasticMaterial
Reference to bulk (undamaged) material.
PlasticMaterial(int n, Domain *d)
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Definition inputrecord.h:75
#define IR_GIVE_FIELD(__ir, __value, __id)
Definition inputrecord.h:67
#define _IFT_IsotropicLinearElasticMaterial_talpha
#define _IFT_IsotropicLinearElasticMaterial_n
#define _IFT_IsotropicLinearElasticMaterial_e
#define _IFT_J2plasticMaterial_ry
#define _IFT_J2plasticMaterial_khm
#define _IFT_J2plasticMaterial_ihm

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011