OOFEM 3.0
Loading...
Searching...
No Matches
j2mplasticmaterial.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 "j2mplasticmaterial.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
44namespace oofem {
46
47J2MPlasticMaterial :: J2MPlasticMaterial(int n, Domain *d) : MPlasticMaterial(n, d)
48{
50 this->nsurf = 1;
51}
52
53
54void
55J2MPlasticMaterial :: initializeFrom(InputRecord &ir)
56{
57 double value;
58
59 MPlasticMaterial :: initializeFrom(ir);
60 linearElasticMaterial->initializeFrom(ir);
61
63 k = value / sqrt(3.0);
64
65 kinematicModuli = 0.0;
67
68 isotropicModuli = 0.0;
70
71 if ( fabs(kinematicModuli) > 1.e-12 ) {
73 }
74
75 if ( fabs(isotropicModuli) > 1.e-12 ) {
77 }
78
79 int rma = 0;
81 if ( rma == 0 ) {
83 } else {
85 }
86}
87
88
89std::unique_ptr<MaterialStatus>
90J2MPlasticMaterial :: CreateStatus(GaussPoint *gp) const
91{
92 return std::make_unique<MPlasticMaterialStatus>(gp, this->giveSizeOfReducedHardeningVarsVector(gp));
93}
94
95void
96J2MPlasticMaterial :: computeStressSpaceHardeningVars(FloatArray &answer, GaussPoint *gp,
97 const FloatArray &strainSpaceHardeningVariables) const
98{
99 // in full stress strain space
100 int count = 0, size = this->giveSizeOfFullHardeningVarsVector(), isize, rSize;
101 IntArray mask;
102
103 if ( !hasHardening() ) {
104 answer.clear();
105 return;
106 }
107
108 answer.resize(size);
109 StructuralMaterial :: giveVoigtSymVectorMask( mask, gp->giveMaterialMode() );
110 isize = mask.giveSize();
111 rSize = this->giveSizeOfReducedHardeningVarsVector(gp);
112
113 /* kinematic hardening variables are first */
114 if ( this->kinematicHardeningFlag ) {
115 for ( int i = 1; i <= isize; i++ ) {
116 // to be consistent with equivalent plastic strain formulation
117 // we multiply by (sqrt(2.)*2./3.)
118 answer.at( mask.at(i) ) = ( sqrt(2.) * 2. / 3. ) * this->kinematicModuli * strainSpaceHardeningVariables.at(i);
119 }
120
121 count = 6;
122 }
123
124 if ( this->isotropicHardeningFlag ) {
125 answer.at(count + 1) = this->isotropicModuli *
126 strainSpaceHardeningVariables.at(rSize);
127 }
128
129 answer.negated();
130}
131
132
133
134double
135J2MPlasticMaterial :: computeYieldValueAt(GaussPoint *gp, int isurf, const FloatArray &stressVector,
136 const FloatArray &stressSpaceHardeningVars) const
137{
138 double f;
139 FloatArray helpVector, backStress;
140
141 if ( this->kinematicHardeningFlag ) {
142 if ( stressVector.isNotEmpty() ) {
143 this->giveStressBackVector(backStress, stressSpaceHardeningVars);
144 helpVector = stressVector;
145 helpVector.add(backStress);
146 } else {
147 return -k;
148 }
149 } else {
150 helpVector = stressVector;
151 }
152
153 f = sqrt( this->computeJ2InvariantAt(helpVector) );
154
155 //if (this->kinematicHardeningFlag) delete helpVector;
156
157 return f + sqrt(1. / 3.) * this->giveIsotropicHardeningVar(stressSpaceHardeningVars) - this->k;
158}
159
160
161void
162J2MPlasticMaterial :: computeHardeningReducedModuli(FloatMatrix &answer, GaussPoint *gp,
163 const FloatArray &strainSpaceHardeningVariables,
164 TimeStep *tStep) const
165{
166 /* computes hardening moduli in reduced stress strain space (for kinematic back-stress)*/
167
168 int size = this->giveSizeOfReducedHardeningVarsVector(gp);
169
170 if ( !hasHardening() ) {
171 answer.clear();
172 return;
173 }
174
175 answer.resize(size, size);
176 answer.zero();
177
178 /* kinematic hardening variables are first */
179 if ( this->kinematicHardeningFlag ) {
180 int ksize = StructuralMaterial :: giveSizeOfVoigtSymVector( gp->giveMaterialMode() );
181 for ( int i = 1; i <= ksize; i++ ) {
182 answer.at(i, i) = this->kinematicModuli;
183 }
184 }
185
186 if ( this->isotropicHardeningFlag ) {
187 answer.at(size, size) = this->isotropicModuli;
188 }
189}
190
191
192void
193J2MPlasticMaterial :: computeStressGradientVector(FloatArray &answer, functType ftype, int isurf, GaussPoint *gp, const FloatArray &stressVector,
194 const FloatArray &stressSpaceHardeningVars) const
195{
196 /* stress gradient of yield function in full stress - strain space */
197
198 double f, ax, ay, az, sx, sy, sz;
199 FloatArray helpVector, backStress;
200
201 answer.resize(6);
202 answer.zero();
203 if ( this->kinematicHardeningFlag ) {
204 if ( stressVector.isNotEmpty() ) {
205 this->giveStressBackVector(backStress, stressSpaceHardeningVars);
206 helpVector = stressVector;
207 helpVector.add(backStress);
208 } else {
209 return;
210 }
211 } else {
212 helpVector = stressVector;
213 }
214
215 f = sqrt( this->computeJ2InvariantAt(helpVector) );
216 // check for yield value zero value
217 if ( fabs(f) < 1.e-6 ) {
218 return;
219 }
220
221 ax = helpVector.at(1);
222 ay = helpVector.at(2);
223 az = helpVector.at(3);
224
225 sx = ( 2. / 3. ) * ax - ( 1. / 3. ) * ay - ( 1. / 3. ) * az;
226 sy = ( 2. / 3. ) * ay - ( 1. / 3. ) * ax - ( 1. / 3. ) * az;
227 sz = ( 2. / 3. ) * az - ( 1. / 3. ) * ay - ( 1. / 3. ) * ax;
228
229 answer.at(1) = 0.5 * sx / f;
230 answer.at(2) = 0.5 * sy / f;
231 answer.at(3) = 0.5 * sz / f;
232 answer.at(4) = helpVector.at(4) / f;
233 answer.at(5) = helpVector.at(5) / f;
234 answer.at(6) = helpVector.at(6) / f;
235}
236
237void
238J2MPlasticMaterial :: computeStressSpaceHardeningVarsReducedGradient(FloatArray &answer, functType ftype, int isurf, GaussPoint *gp,
239 const FloatArray &stressVector,
240 const FloatArray &stressSpaceHardeningVars) const
241{
242 /* computes stress space hardening gradient in reduced stress-strain space */
243
244 int kcount = 0, size = this->giveSizeOfReducedHardeningVarsVector(gp);
245 //double f,ax,ay,az,sx,sy,sz;
246 FloatArray fullKinematicGradient, reducedKinematicGrad;
247
248 if ( !hasHardening() ) {
249 answer.clear();
250 return;
251 }
252
253 answer.resize(size);
254
255 /* kinematic hardening variables first */
256 if ( this->kinematicHardeningFlag ) {
257 this->computeStressGradientVector(fullKinematicGradient, ftype, isurf, gp, stressVector, stressSpaceHardeningVars);
258 StructuralMaterial :: giveReducedSymVectorForm( reducedKinematicGrad, fullKinematicGradient, gp->giveMaterialMode() );
259
260 kcount = reducedKinematicGrad.giveSize();
261 }
262
263 if ( this->kinematicHardeningFlag ) {
264 for ( int i = 1; i <= kcount; i++ ) {
265 answer.at(i) = reducedKinematicGrad.at(i);
266 }
267 }
268
269 if ( this->isotropicHardeningFlag ) {
270 answer.at(size) = sqrt(1. / 3.);
271 }
272}
273
274
275int
276J2MPlasticMaterial :: hasHardening() const
277{
278 return ( this->kinematicHardeningFlag || this->isotropicHardeningFlag );
279}
280
281
282void
283J2MPlasticMaterial :: computeReducedGradientMatrix(FloatMatrix &answer, int isurf,
284 GaussPoint *gp,
285 const FloatArray &stressVector,
286 const FloatArray &stressSpaceHardeningVars) const
287{
288 int size;
289 int imask, jmask;
290 FloatArray helpVector, backStress, df(6);
291 IntArray mask;
292 double f, f32, f12, ax, ay, az;
293
294 StructuralMaterial :: giveInvertedVoigtVectorMask( mask, gp->giveMaterialMode() );
295 size = StructuralMaterial :: giveSizeOfVoigtSymVector( gp->giveMaterialMode() ) +
297
298 answer.resize(size, size);
299 answer.zero();
300
301
302 if ( stressVector.giveSize() != 0 ) {
303 /* kinematic hardening variables first */
304 if ( this->kinematicHardeningFlag ) {
305 this->giveStressBackVector(backStress, stressSpaceHardeningVars);
306 helpVector = stressVector;
307 helpVector.add(backStress);
308 } else {
309 helpVector = stressVector;
310 }
311
312 f = this->computeJ2InvariantAt(helpVector);
313 f12 = sqrt(f);
314 f32 = pow(f, 3. / 2.);
315
316 ax = helpVector.at(1);
317 ay = helpVector.at(2);
318 az = helpVector.at(3);
319
320 df.at(1) = ( 2. / 3. ) * ax - ( 1. / 3. ) * ay - ( 1. / 3. ) * az;
321 df.at(2) = ( 2. / 3. ) * ay - ( 1. / 3. ) * ax - ( 1. / 3. ) * az;
322 df.at(3) = ( 2. / 3. ) * az - ( 1. / 3. ) * ay - ( 1. / 3. ) * ax;
323 df.at(4) = 2. * helpVector.at(4);
324 df.at(5) = 2. * helpVector.at(5);
325 df.at(6) = 2. * helpVector.at(6);
326
327 for ( int i = 1; i <= 3; i++ ) {
328 if ( ( imask = mask.at(i) ) == 0 ) {
329 continue;
330 }
331
332 for ( int j = i; j <= 3; j++ ) {
333 if ( ( jmask = mask.at(j) ) == 0 ) {
334 continue;
335 }
336
337 if ( i == j ) {
338 answer.at(imask, jmask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j) + 0.5 * ( 1. / f12 ) * ( 4. / 6 );
339 } else {
340 answer.at(imask, jmask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j) + 0.5 * ( 1. / f12 ) * ( -2. / 6 );
341 answer.at(jmask, imask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j) + 0.5 * ( 1. / f12 ) * ( -2. / 6 );
342 }
343 }
344 }
345
346 for ( int i = 1; i <= 3; i++ ) {
347 if ( ( imask = mask.at(i) ) == 0 ) {
348 continue;
349 }
350
351 for ( int j = 4; j <= 6; j++ ) {
352 if ( ( jmask = mask.at(j) ) == 0 ) {
353 continue;
354 }
355
356 answer.at(imask, jmask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j);
357 answer.at(jmask, imask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j);
358 }
359 }
360
361 for ( int i = 4; i <= 6; i++ ) {
362 if ( ( imask = mask.at(i) ) == 0 ) {
363 continue;
364 }
365
366 for ( int j = i; j <= 6; j++ ) {
367 if ( ( jmask = mask.at(j) ) == 0 ) {
368 continue;
369 }
370
371 if ( i == j ) {
372 answer.at(imask, jmask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j) + 0.5 * ( 1. / f12 ) * 2.;
373 } else {
374 answer.at(imask, jmask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j);
375 answer.at(jmask, imask) = -( 1. / 4. ) * ( 1. / f32 ) * df.at(i) * df.at(j);
376 }
377 }
378 }
379 }
380
381 /* for isotropic hardening: the corresponding part of gradient matrix is zero valued */
382}
383
384
385void
386J2MPlasticMaterial :: compute3dElasticModuli(FloatMatrix &answer,
387 GaussPoint *gp,
388 TimeStep *tStep) const
389{
390 /* Returns 3d elastic moduli */
391 answer = this->linearElasticMaterial->give3dMaterialStiffnessMatrix(ElasticStiffness, gp, tStep);
392}
393
394
395double
396J2MPlasticMaterial :: computeJ2InvariantAt(const FloatArray &stressVector) const
397{
398 double answer;
399 double v1, v2, v3;
400
401 if ( stressVector.isEmpty() ) {
402 return 0.0;
403 }
404
405 v1 = ( ( stressVector.at(1) - stressVector.at(2) ) * ( stressVector.at(1) - stressVector.at(2) ) );
406 v2 = ( ( stressVector.at(2) - stressVector.at(3) ) * ( stressVector.at(2) - stressVector.at(3) ) );
407 v3 = ( ( stressVector.at(3) - stressVector.at(1) ) * ( stressVector.at(3) - stressVector.at(1) ) );
408
409 answer = ( 1. / 6. ) * ( v1 + v2 + v3 ) + stressVector.at(4) * stressVector.at(4) +
410 stressVector.at(5) * stressVector.at(5) + stressVector.at(6) * stressVector.at(6);
411
412 return answer;
413}
414
415
416int
417J2MPlasticMaterial :: giveSizeOfFullHardeningVarsVector() const
418{
419 /* Returns the size of hardening variables vector */
420 int size = 0;
421
423 size += 6; /* size of full stress vector */
424 }
425
427 size += 1; /* scalar value */
428 }
429
430 return size;
431}
432
433int
434J2MPlasticMaterial :: giveSizeOfReducedHardeningVarsVector(GaussPoint *gp) const
435{
436 /* Returns the size of hardening variables vector */
437 int size = 0;
438
440 size += StructuralMaterial :: giveSizeOfVoigtSymVector( gp->giveMaterialMode() );
441 }
442
444 size += 1; /* scalar value */
445 }
446
447 return size;
448}
449
450
451void
452J2MPlasticMaterial :: giveStressBackVector(FloatArray &answer,
453 const FloatArray &stressSpaceHardeningVars) const
454{
455 /* returns part of hardening vector corresponding to kinematic hardening */
456 if ( this->kinematicHardeningFlag ) {
457 answer.resize(6);
458 for ( int i = 1; i <= 6; i++ ) {
459 answer.at(i) = stressSpaceHardeningVars.at(i);
460 }
461
462 return;
463 }
464
465 answer.clear();
466}
467
468
469double
470J2MPlasticMaterial :: giveIsotropicHardeningVar(const FloatArray &stressSpaceHardeningVars) const
471{
472 /* returns value in hardening vector corresponding to isotropic hardening */
473 if ( !isotropicHardeningFlag ) {
474 return 0.;
475 } else if ( this->kinematicHardeningFlag ) {
476 return stressSpaceHardeningVars.at(7);
477 } else {
478 return stressSpaceHardeningVars.at(1);
479 }
480}
481} // end namespace oofem
#define REGISTER_Material(class)
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
bool isEmpty() const
Returns true if receiver is empty.
Definition floatarray.h:265
void add(const FloatArray &src)
Definition floatarray.C:218
bool isNotEmpty() const
Returns true if receiver is not empty.
Definition floatarray.h:263
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
int hasHardening() const override
int giveSizeOfFullHardeningVarsVector() const override
double giveIsotropicHardeningVar(const FloatArray &stressSpaceHardeningVars) const
void giveStressBackVector(FloatArray &answer, const FloatArray &stressSpaceHardeningVars) const
double computeJ2InvariantAt(const FloatArray &stressVector) const
int giveSizeOfReducedHardeningVarsVector(GaussPoint *gp) const override
void computeStressGradientVector(FloatArray &answer, functType ftype, int isurf, GaussPoint *gp, const FloatArray &stressVector, const FloatArray &stressSpaceHardeningVars) const override
MPlasticMaterial(int n, Domain *d)
functType
Type that allows to distinguish between yield function and loading function.
int nsurf
Number of yield surfaces.
enum oofem::MPlasticMaterial::ReturnMappingAlgoType rmType
LinearElasticMaterial * linearElasticMaterial
Reference to bulk (undamaged) material.
#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_J2MPlasticMaterial_khm
#define _IFT_J2MPlasticMaterial_ihm
#define _IFT_J2MPlasticMaterial_rma
#define _IFT_J2MPlasticMaterial_ry

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