OOFEM 3.0
Loading...
Searching...
No Matches
mplasticmaterial.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 "mplasticmaterial.h"
36#include "gausspoint.h"
37#include "floatmatrix.h"
38#include "floatarray.h"
39#include "intarray.h"
40#include "datastream.h"
41#include "contextioerr.h"
42
43namespace oofem {
44#define YIELD_TOL 1.e-4
45#define RES_TOL 1.e-4
46#define PLASTIC_MATERIAL_MAX_ITERATIONS 90
47
48MPlasticMaterial :: MPlasticMaterial(int n, Domain *d) : StructuralMaterial(n, d)
49{
50}
51
52
53MPlasticMaterial :: ~MPlasticMaterial()
54{
56}
57
58
59bool
60MPlasticMaterial :: hasMaterialModeCapability(MaterialMode mode) const
61//
62// returns whether receiver supports given mode
63//
64{
65 return mode == _3dMat ||
66 mode == _1dMat ||
67 //<RESTRICTED_SECTION>
68 mode == _PlaneStress ||
69 //</RESTRICTED_SECTION>
70 mode == _PlaneStrain;
71}
72
73
74std::unique_ptr<MaterialStatus>
75MPlasticMaterial :: CreateStatus(GaussPoint *gp) const
76{
77 return std::make_unique<MPlasticMaterialStatus>(gp, this->giveSizeOfReducedHardeningVarsVector(gp));
78}
79
80
81void
82MPlasticMaterial :: giveRealStressVector(FloatArray &answer,
83 GaussPoint *gp,
84 const FloatArray &totalStrain,
85 TimeStep *tStep) const
86//
87// returns real stress vector in 3d stress space of receiver according to
88// previous level of stress and current
89// strain increment, the only way, how to correctly update gp records
90//
91// completely formulated in Reduced stress-strain space
92{
93 FloatArray strainSpaceHardeningVariables;
94 FloatArray fullStressVector;
95 FloatArray strainVectorR, plasticStrainVectorR;
96 FloatArray helpVec;
97 IntArray activeConditionMap(this->nsurf);
98 FloatArray gamma;
99
100 MPlasticMaterialStatus *status = static_cast< MPlasticMaterialStatus * >( this->giveStatus(gp) );
101
102 this->initTempStatus(gp);
103
104 // subtract stress independent part
105 // note: eigenStrains (temperature) is not contained in mechanical strain stored in gp
106 // therefore it is necessary to subtract always the total eigen strain value
107 this->giveStressDependentPartOfStrainVector(strainVectorR, gp, totalStrain,
108 tStep, VM_Total);
109
110 /*
111 * stress return algorithm
112 */
113
114 //if (0) this->cuttingPlaneReturn (fullStressVector, activeConditionMap, gamma, form, gp, totalStrain, tStep);
115 //else this->closestPointReturn (fullStressVector, activeConditionMap, gamma, form, gp, totalStrain, tStep);
116 if ( rmType == mpm_ClosestPoint ) {
117 this->closestPointReturn(fullStressVector, activeConditionMap, gamma, gp, strainVectorR,
118 plasticStrainVectorR, strainSpaceHardeningVariables, tStep);
119 } else {
120 this->cuttingPlaneReturn(fullStressVector, activeConditionMap, gamma, gp, strainVectorR,
121 plasticStrainVectorR, strainSpaceHardeningVariables, tStep);
122 }
123
124
125 status->letTempStrainVectorBe(totalStrain);
126 StructuralMaterial :: giveReducedSymVectorForm( helpVec, fullStressVector, gp->giveMaterialMode() );
127 status->letTempStressVectorBe(helpVec);
128
129 status->letTempPlasticStrainVectorBe(plasticStrainVectorR);
130 status->letTempStrainSpaceHardeningVarsVectorBe(strainSpaceHardeningVariables);
131
132 status->setTempGamma(gamma);
133 status->setTempActiveConditionMap(activeConditionMap);
134
135
136 // update state flag
137 int newState, state = status->giveStateFlag();
138 bool yieldFlag = false;
139 for ( int i = 1; i <= nsurf; i++ ) {
140 if ( gamma.at(i) > 0. ) {
141 yieldFlag = true;
142 }
143 }
144
145 if ( yieldFlag ) {
146 newState = MPlasticMaterialStatus :: PM_Yielding; // test if plastic loading occur
147 }
148 // no plastic loading - check for unloading
149 else if ( ( state == MPlasticMaterialStatus :: PM_Yielding ) || ( state == MPlasticMaterialStatus :: PM_Unloading ) ) {
150 newState = MPlasticMaterialStatus :: PM_Unloading;
151 } else {
152 newState = MPlasticMaterialStatus :: PM_Elastic;
153 }
154
155 status->letTempStateFlagBe(newState);
156
157 answer = status->giveTempStressVector();
158}
159
160
161void
162MPlasticMaterial :: closestPointReturn(FloatArray &answer,
163 IntArray &activeConditionMap,
164 FloatArray &gamma,
165 GaussPoint *gp,
166 const FloatArray &totalStrain,
167 FloatArray &plasticStrainVectorR,
168 FloatArray &strainSpaceHardeningVariables,
169 TimeStep *tStep) const
170{
171 FloatArray fullStressVector;
172 FloatArray elasticStrainVectorR;
173 FloatArray fullStressSpaceHardeningVars, residualVectorR;
174
175 FloatArray helpVector, helpVector2;
176 FloatArray dgamma, tempGamma;
177 FloatMatrix elasticModuli, hardeningModuli, consistentModuli;
178 FloatMatrix elasticModuliInverse, hardeningModuliInverse;
179 FloatMatrix helpMtrx;
180 FloatMatrix gmat;
181 std :: vector< FloatArray > yieldGradVec(this->nsurf), loadGradVec(this->nsurf), * yieldGradVecPtr, * loadGradVecPtr;
182 FloatArray rhs;
183 double yieldValue;
184 int nIterations = 0;
185 int i, j, strSize, totSize;
186 int elastic, restart, actSurf, indx;
187 bool yieldConsistency;
188
189
190 if ( this->plType == associatedPT ) {
191 yieldGradVecPtr = loadGradVecPtr = & yieldGradVec;
192 } else {
193 yieldGradVecPtr = & yieldGradVec;
194 loadGradVecPtr = & loadGradVec;
195 }
196
197 MPlasticMaterialStatus *status = static_cast< MPlasticMaterialStatus * >( this->giveStatus(gp) );
198
199 plasticStrainVectorR = status->givePlasticStrainVector();
200 strainSpaceHardeningVariables = status->giveStrainSpaceHardeningVars();
201
202 dgamma.resize(nsurf);
203 dgamma.zero();
204 gamma.resize(nsurf);
205 gamma.zero();
206
207 strSize = totalStrain.giveSize(); // size of reducedStrain Vector
208 totSize = strSize + strainSpaceHardeningVariables.giveSize();
209
210 // compute elastic moduli and its inverse
211 this->computeReducedElasticModuli(elasticModuli, gp, tStep);
212 elasticModuliInverse.beInverseOf(elasticModuli);
213 // delete elasticModuli;
214
215 //
216 // Elastic Predictor
217 //
218
219 elasticStrainVectorR = totalStrain;
220 elasticStrainVectorR.subtract(plasticStrainVectorR);
221 // stress vector in full form due to computational convinience
222 //if (fullStressVector) delete fullStressVector;
223 this->computeTrialStressIncrement(fullStressVector, gp, elasticStrainVectorR, tStep);
224 this->computeStressSpaceHardeningVars(fullStressSpaceHardeningVars, gp, strainSpaceHardeningVariables);
225
226 //
227 // check for plastic process
228 //
229 elastic = 1;
230 actSurf = 0;
231 activeConditionMap.zero();
232 for ( i = 1; i <= this->nsurf; i++ ) {
233 yieldValue = this->computeYieldValueAt(gp, i, fullStressVector, fullStressSpaceHardeningVars);
234 if ( yieldValue > YIELD_TOL ) {
235 elastic = 0;
236 actSurf += 1;
237 activeConditionMap.at(i) = actSurf;
238 }
239 }
240
241 if ( !elastic ) {
242 /*
243 * plastic multisurface closest-point corrector
244 */
245
246
247 do {
248 do { // restart loop
249 elasticStrainVectorR = totalStrain;
250 elasticStrainVectorR.subtract(plasticStrainVectorR);
251 // stress vector in full form due to computational convinience
252 //if (fullStressVector) delete fullStressVector;
253 this->computeTrialStressIncrement(fullStressVector, gp, elasticStrainVectorR, tStep);
254 this->computeStressSpaceHardeningVars(fullStressSpaceHardeningVars, gp, strainSpaceHardeningVariables);
255
256 // compute gradients
257 for ( i = 1; i <= nsurf; i++ ) {
258 this->computeGradientVector(yieldGradVec [ i - 1 ], yieldFunction, i, gp, fullStressVector, fullStressSpaceHardeningVars);
259 }
260
261 if ( this->plType == nonassociatedPT ) {
262 for ( i = 1; i <= nsurf; i++ ) {
263 this->computeGradientVector(loadGradVec [ i - 1 ], loadFunction, i, gp, fullStressVector, fullStressSpaceHardeningVars);
264 }
265 }
266
267
268 //this->computeGradientVector (gradientVectorR, gp, &fullStressVector, fullStressSpaceHardeningVars);
269 this->computeResidualVector(residualVectorR, gp, gamma, activeConditionMap, plasticStrainVectorR,
270 strainSpaceHardeningVariables, * loadGradVecPtr);
271
272 // check convergence
273 yieldConsistency = true;
274 for ( i = 1; i <= nsurf; i++ ) {
275 if ( activeConditionMap.at(i) ) {
276 yieldValue = this->computeYieldValueAt(gp, i, fullStressVector, fullStressSpaceHardeningVars);
277 if ( ( yieldValue >= YIELD_TOL ) ) {
278 yieldConsistency = false;
279 }
280 }
281 }
282
283 if ( yieldConsistency && ( residualVectorR.computeNorm() < RES_TOL ) ) {
284 answer = fullStressVector;
285 printf(" (%d iterations)", nIterations);
286 return;
287 }
288
289 // compute consistent tangent moduli
290 this->computeHardeningReducedModuli(hardeningModuli, gp, strainSpaceHardeningVariables, tStep);
291 if ( hardeningModuli.giveNumberOfRows() ) {
292 hardeningModuliInverse.beInverseOf(hardeningModuli);
293 // delete hardeningModuli;
294 } else {
295 hardeningModuliInverse.clear();
296 }
297
298 this->computeAlgorithmicModuli(consistentModuli, gp, elasticModuliInverse,
299 hardeningModuliInverse, gamma, activeConditionMap,
300 fullStressVector, fullStressSpaceHardeningVars);
301
302 rhs.resize(actSurf);
303 gmat.resize(actSurf, actSurf);
304 for ( i = 1; i <= nsurf; i++ ) {
305 if ( activeConditionMap.at(i) ) {
306 yieldValue = this->computeYieldValueAt(gp, i, fullStressVector, fullStressSpaceHardeningVars);
307 helpVector.beTProductOf(consistentModuli, ( * yieldGradVecPtr ) [ i - 1 ]);
308
309 for ( j = 1; j <= this->nsurf; j++ ) {
310 if ( activeConditionMap.at(j) ) {
311 gmat.at(i, j) = ( * loadGradVecPtr ) [ j - 1 ].dotProduct(helpVector);
312 }
313 }
314
315 rhs.at(i) = yieldValue - residualVectorR.dotProduct(helpVector);
316 }
317 }
318
319 // obtain increment to consistency parameter
320 gmat.solveForRhs(rhs, helpVector);
321
322 // assign gammas
323 for ( i = 1; i <= this->nsurf; i++ ) {
324 if ( ( indx = activeConditionMap.at(i) ) ) {
325 dgamma.at(i) = helpVector.at(indx);
326 } else {
327 dgamma.at(i) = 0.0;
328 }
329 }
330
331 tempGamma = gamma;
332 tempGamma.add(dgamma);
333
334 //
335 // check active constraint
336 //
337
338 restart = 0;
339 for ( i = 1; i <= this->nsurf; i++ ) {
340 if ( tempGamma.at(i) < 0.0 ) {
341 restart = 1;
342 }
343 }
344
345 if ( restart ) {
346 // build up new activeConditionMap and restart the iterartion from begining
347 actSurf = 0;
348 activeConditionMap.zero();
349 for ( i = 1; i <= this->nsurf; i++ ) {
350 if ( tempGamma.at(i) > 0.0 ) {
351 actSurf += 1;
352 activeConditionMap.at(i) = actSurf;
353 }
354 }
355
356 continue;
357 } else {
358 break;
359 }
360 } while ( 1 ); // end restart loop
361
362 // obtain incremental plastic strains and internal variables
363 // residualVectorR vector and gradVec array are changed
364 // but they are computed once again when new iteration starts
365 for ( i = 1; i <= nsurf; i++ ) {
366 if ( activeConditionMap.at(i) ) {
367 ( * loadGradVecPtr ) [ i - 1 ].times( dgamma.at(i) );
368 residualVectorR.add( ( * loadGradVecPtr ) [ i - 1 ] );
369 }
370 }
371
372 helpVector.beProductOf(consistentModuli, residualVectorR);
373 this->computeDiagModuli(helpMtrx, gp, elasticModuliInverse, hardeningModuliInverse);
374 helpVector2.beProductOf(helpMtrx, helpVector);
375
376 // Update state variables and consistency parameter
377 for ( i = 1; i <= strSize; i++ ) {
378 plasticStrainVectorR.at(i) += helpVector2.at(i);
379 }
380
381 for ( i = strSize + 1; i <= totSize; i++ ) {
382 strainSpaceHardeningVariables.at(i - strSize) += helpVector2.at(i);
383 }
384
385 gamma.add(dgamma);
386
387 // increment iteration count
388 nIterations++;
389
390 if ( nIterations > PLASTIC_MATERIAL_MAX_ITERATIONS ) {
391 OOFEM_WARNING("local equlibrium not reached in %d iterations\nElement %d, gp %d, continuing",
393 answer = fullStressVector;
394 break;
395 }
396 } while ( 1 );
397 } else {
398 answer = fullStressVector;
399 }
400}
401
402
403void
404MPlasticMaterial :: cuttingPlaneReturn(FloatArray &answer,
405 IntArray &activeConditionMap,
406 FloatArray &gamma,
407 GaussPoint *gp,
408 const FloatArray &totalStrain,
409 FloatArray &plasticStrainVectorR,
410 FloatArray &strainSpaceHardeningVariables,
411 TimeStep *tStep) const
412{
413 FloatArray elasticStrainVectorR;
414 FloatArray fullStressVector, fullStressSpaceHardeningVars;
415 FloatArray helpVector, trialStressIncrement, rhs;
416 FloatMatrix elasticModuli, hardeningModuli, dmat, gmatInv;
417 std :: vector< FloatArray > yieldGradVec(this->nsurf), loadGradVec(this->nsurf), * yieldGradVecPtr, * loadGradVecPtr;
418 FloatArray dgamma(this->nsurf);
419 double yieldValue;
420 int nIterations = 0;
421 int size, sizeR, i, j, elastic, restart, actSurf, indx, iindx, jindx;
422
423 MPlasticMaterialStatus *status = static_cast< MPlasticMaterialStatus * >( this->giveStatus(gp) );
424
425 if ( this->plType == associatedPT ) {
426 yieldGradVecPtr = loadGradVecPtr = & yieldGradVec;
427 } else {
428 yieldGradVecPtr = & yieldGradVec;
429 loadGradVecPtr = & loadGradVec;
430 }
431
432 // huhu:
433 plasticStrainVectorR = status->givePlasticStrainVector();
434 strainSpaceHardeningVariables = status->giveStrainSpaceHardeningVars();
435
436 dgamma.resize(nsurf);
437 dgamma.zero();
438 gamma.resize(nsurf);
439 gamma.zero();
440 // compute elastic moduli
441 this->computeReducedElasticModuli(elasticModuli, gp, tStep);
442 // compute hardening moduli and its inverse
443 this->computeHardeningReducedModuli(hardeningModuli, gp, strainSpaceHardeningVariables, tStep);
444
445 // initialize activeConditionMap
446 elasticStrainVectorR = totalStrain;
447 elasticStrainVectorR.subtract(plasticStrainVectorR);
448 // stress vector in full form due to computational convinience
449 this->computeTrialStressIncrement(fullStressVector, gp, elasticStrainVectorR, tStep);
450 StructuralMaterial :: giveReducedSymVectorForm( trialStressIncrement, fullStressVector, gp->giveMaterialMode() );
451 trialStressIncrement.subtract( status->giveStressVector() );
452 this->computeStressSpaceHardeningVars(fullStressSpaceHardeningVars, gp, strainSpaceHardeningVariables);
453
454 elastic = 1;
455 actSurf = 0;
456 activeConditionMap.zero();
457 for ( i = 1; i <= this->nsurf; i++ ) {
458 yieldValue = this->computeYieldValueAt(gp, i, fullStressVector, fullStressSpaceHardeningVars);
459 if ( yieldValue > YIELD_TOL ) {
460 elastic = 0;
461 actSurf += 1;
462 activeConditionMap.at(i) = actSurf;
463 }
464 }
465
466 if ( !elastic ) {
467 //
468 // compute consistent moduli
469 //
470 sizeR = elasticModuli.giveNumberOfRows();
471 size = sizeR + hardeningModuli.giveNumberOfRows();
472
473 dmat.resize(size, size);
474 dmat.zero();
475
476 for ( i = 1; i <= sizeR; i++ ) {
477 for ( j = 1; j <= sizeR; j++ ) {
478 dmat.at(i, j) = elasticModuli.at(i, j);
479 }
480 }
481
482 for ( i = sizeR + 1; i <= size; i++ ) {
483 for ( j = sizeR + 1; j <= size; j++ ) {
484 dmat.at(i, j) = hardeningModuli.at(i - sizeR, j - sizeR);
485 }
486 }
487
488 do { // local equilibrium loop
489 // update hardening moduli and its inverse
490 this->computeHardeningReducedModuli(hardeningModuli, gp, strainSpaceHardeningVariables, tStep);
491 for ( i = sizeR + 1; i <= size; i++ ) {
492 for ( j = sizeR + 1; j <= size; j++ ) {
493 dmat.at(i, j) = hardeningModuli.at(i - sizeR, j - sizeR);
494 }
495 }
496
497 do { // loop for restart
498 gmatInv.resize(actSurf, actSurf);
499 gmatInv.zero();
500 rhs.resize(actSurf);
501 rhs.zero();
502
503 // compute gradients
504 for ( i = 1; i <= nsurf; i++ ) {
505 this->computeGradientVector(yieldGradVec [ i - 1 ], yieldFunction, i, gp, fullStressVector, fullStressSpaceHardeningVars);
506 }
507
508 if ( this->plType == nonassociatedPT ) {
509 for ( i = 1; i <= nsurf; i++ ) {
510 this->computeGradientVector(loadGradVec [ i - 1 ], loadFunction, i, gp, fullStressVector, fullStressSpaceHardeningVars);
511 }
512 }
513
514
515
516 for ( i = 1; i <= nsurf; i++ ) {
517 if ( ( iindx = activeConditionMap.at(i) ) ) {
518 rhs.at(iindx) = this->computeYieldValueAt(gp, i, fullStressVector, fullStressSpaceHardeningVars);
519 helpVector.beTProductOf(dmat, ( * yieldGradVecPtr ) [ i - 1 ]);
520
521 for ( j = 1; j <= this->nsurf; j++ ) {
522 if ( ( jindx = activeConditionMap.at(j) ) ) {
523 gmatInv.at(iindx, jindx) = ( * loadGradVecPtr ) [ j - 1 ].dotProduct(helpVector);
524 }
525 }
526 }
527 }
528
529 /*
530 * // compute plastic multipliers for active conds.
531 * //computee gmatInv
532 * gradMat.resize(actSurf, size);
533 * for (i=1; i<=nsurf; i++) {
534 * if ((iindx = activeConditionMap.at(i))) {
535 * rhs.at (iindx) = this-> computeYieldValueAt (gp, i, fullStressVector, fullStressSpaceHardeningVars);
536 * for (j=1; j<=size; j++) {
537 * gradMat.at(iindx, j) = (*yieldGradVecPtr)[i-1].at(j);
538 * }
539 * }
540 * }
541 * helpMtrx.resize(actSurf, size);
542 * helpMtrx.beProductOf (gradMat, dmat);
543 * gmatInv.beProductTOf (helpMtrx, gradMat);
544 */
545 // solve for plastic multiplier increments
546 gmatInv.solveForRhs(rhs, helpVector);
547 // assign gammas
548 for ( i = 1; i <= this->nsurf; i++ ) {
549 if ( ( indx = activeConditionMap.at(i) ) ) {
550 dgamma.at(i) = helpVector.at(indx);
551 } else {
552 dgamma.at(i) = 0.0;
553 }
554 }
555
556
557
558 restart = 0;
559 // check for active conditions
560 for ( i = 1; i <= this->nsurf; i++ ) {
561 if ( ( gamma.at(i) + dgamma.at(i) ) < 0.0 ) {
562 gamma.at(i) = 0.0;
563 restart = 1;
564 }
565 }
566
567 if ( restart ) {
568 // build up new activeConditionMap and restart the iterartion from begining
569 actSurf = 0;
570 activeConditionMap.zero();
571 for ( i = 1; i <= this->nsurf; i++ ) {
572 if ( ( gamma.at(i) + dgamma.at(i) ) > 0.0 ) {
573 actSurf += 1;
574 activeConditionMap.at(i) = actSurf;
575 }
576 }
577
578 continue;
579 } else {
580 break;
581 }
582 } while ( 1 ); // end restart loop
583
584 // compute plastic strain vector
585 helpVector.resize(sizeR);
586 helpVector.zero();
587 for ( i = 1; i <= this->nsurf; i++ ) {
588 if ( activeConditionMap.at(i) ) {
589 ( * loadGradVecPtr ) [ i - 1 ].times( dgamma.at(i) );
590 for ( j = 1; j <= sizeR; j++ ) {
591 helpVector.at(j) += ( * loadGradVecPtr ) [ i - 1 ].at(j);
592 }
593 }
594 }
595
596 plasticStrainVectorR.add(helpVector);
597 // update strain space hardening vector
598 helpVector.resize(size - sizeR);
599 helpVector.zero();
600 for ( i = 1; i <= this->nsurf; i++ ) {
601 if ( activeConditionMap.at(i) ) {
602 //gradVec[i-1].times(gamma.at(i));
603 for ( j = sizeR + 1; j <= size; j++ ) {
604 helpVector.at(j - sizeR) += ( * loadGradVecPtr ) [ i - 1 ].at(j);
605 }
606 }
607 }
608
609 strainSpaceHardeningVariables.add(helpVector);
610 // update plastic multipliers
611 gamma.add(dgamma);
612
613 elasticStrainVectorR = totalStrain;
614 elasticStrainVectorR.subtract(plasticStrainVectorR);
615 // stress vector in full form due to computational convinience
616 this->computeTrialStressIncrement(fullStressVector, gp, elasticStrainVectorR, tStep);
617 this->computeStressSpaceHardeningVars(fullStressSpaceHardeningVars, gp, strainSpaceHardeningVariables);
618
619 elastic = 1;
620 for ( i = 1; i <= this->nsurf; i++ ) {
621 yieldValue = this->computeYieldValueAt(gp, i, fullStressVector, fullStressSpaceHardeningVars);
622 // check for end of iteration
623 if ( yieldValue > YIELD_TOL ) {
624 elastic = 0;
625 }
626 }
627
628 if ( elastic ) {
629 break;
630 }
631
632 // increment iteration count
633 nIterations++;
634
635 if ( nIterations > PLASTIC_MATERIAL_MAX_ITERATIONS ) {
636 char buff [ 200 ], buff1 [ 150 ];
637 sprintf(buff, "GiveRealStressVector: local equlibrium not reached in %d iterations", PLASTIC_MATERIAL_MAX_ITERATIONS);
638 sprintf( buff1, "Element %d, gp %d, continuing", gp->giveElement()->giveNumber(), gp->giveNumber() );
639 OOFEM_WARNING(buff, buff1);
640 //nIterations = 0; goto huhu;
641 break;
642 }
643 } while ( 1 );
644 }
645
646 printf(" (%d iterations)", nIterations);
647 answer = fullStressVector;
648}
649
650
651void
652MPlasticMaterial :: computeGradientVector(FloatArray &answer, functType ftype, int isurf,
653 GaussPoint *gp,
654 const FloatArray &fullStressVector,
655 const FloatArray &fullStressSpaceHardeningVars) const
656{
657 /*
658 * Computes gradient vector R in reduced form.
659 * R = {\der{\sigma}{f_{n+1}}, \der{q}{f_{n+1}}}^T
660 * Gradient vector contains partial derivatives of yield function
661 * with respect to stresses and with respect to
662 * strain space hardening variables
663 *
664 * Note: variables with R postfix are in reduced stress-space.
665 */
666 FloatArray stressGradient, stressGradientR;
667 FloatArray stressSpaceHardVarGradient;
668 int isize, size;
669
670 this->computeStressGradientVector(stressGradient, ftype, isurf, gp, fullStressVector,
671 fullStressSpaceHardeningVars);
672
673 StructuralMaterial :: giveReducedSymVectorForm( stressGradientR, stressGradient, gp->giveMaterialMode() );
674
675 this->computeStressSpaceHardeningVarsReducedGradient(stressSpaceHardVarGradient, ftype, isurf, gp,
676 fullStressVector, fullStressSpaceHardeningVars);
677
678 isize = stressGradientR.giveSize();
679 if ( stressSpaceHardVarGradient.isNotEmpty() ) {
680 size = isize + stressSpaceHardVarGradient.giveSize();
681 } else {
682 size = isize;
683 }
684
685 answer.resize(size);
686 for ( int i = 1; i <= isize; i++ ) {
687 answer.at(i) = stressGradientR.at(i);
688 }
689
690 for ( int i = isize + 1; i <= size; i++ ) {
691 answer.at(i) = stressSpaceHardVarGradient.at(i - isize);
692 }
693}
694
695
696void
697MPlasticMaterial :: computeResidualVector(FloatArray &answer, GaussPoint *gp, const FloatArray &gamma,
698 const IntArray &activeConditionMap, const FloatArray &plasticStrainVectorR,
699 const FloatArray &strainSpaceHardeningVariables,
700 std :: vector< FloatArray > &gradientVectorR) const
701{
702 /* Computes Residual vector for closest point projection algorithm */
703
704 FloatArray oldPlasticStrainVectorR, oldStrainSpaceHardeningVariables;
705 int isize, size;
706 MPlasticMaterialStatus *status = static_cast< MPlasticMaterialStatus * >( this->giveStatus(gp) );
707
708 isize = plasticStrainVectorR.giveSize();
709 size = gradientVectorR [ 0 ].giveSize();
710
711 answer.resize(size);
712 oldPlasticStrainVectorR = status->givePlasticStrainVector();
713 oldStrainSpaceHardeningVariables = status->giveStrainSpaceHardeningVars();
714
715 for ( int i = 1; i <= isize; i++ ) {
716 answer.at(i) = oldPlasticStrainVectorR.at(i) - plasticStrainVectorR.at(i);
717 }
718
719 for ( int i = isize + 1; i <= size; i++ ) {
720 answer.at(i) = oldStrainSpaceHardeningVariables.at(i - isize) - strainSpaceHardeningVariables.at(i - isize);
721 }
722
723 for ( int i = 1; i <= this->nsurf; i++ ) {
724 if ( activeConditionMap.at(i) ) {
725 for ( int j = 1; j <= size; j++ ) {
726 answer.at(j) += gamma.at(i) * gradientVectorR [ i - 1 ].at(j);
727 }
728 }
729 }
730}
731
732
733void
734MPlasticMaterial :: computeTrialStressIncrement(FloatArray &answer, GaussPoint *gp,
735 const FloatArray &elasticStrainVectorR,
736 TimeStep *tStep) const
737{
738 /* Computes the full trial elastic stress vector */
739
740 FloatMatrix de;
741 FloatArray reducedAnswer;
742
743 this->computeReducedElasticModuli(de, gp, tStep);
744 //this->giveLinearElasticMaterial()->giveCharacteristicMatrix(de, TangentStiffness, gp, tStep);
745 reducedAnswer.beProductOf(de, elasticStrainVectorR);
746 StructuralMaterial :: giveFullSymVectorForm( answer, reducedAnswer, gp->giveMaterialMode() );
747}
748
749
750void
751MPlasticMaterial :: computeAlgorithmicModuli(FloatMatrix &answer,
752 GaussPoint *gp,
753 const FloatMatrix &elasticModuliInverse,
754 const FloatMatrix &hardeningModuliInverse,
755 const FloatArray &gamma,
756 const IntArray &activeConditionMap,
757 const FloatArray &fullStressVector,
758 const FloatArray &fullStressSpaceHardeningVars) const
759{
760 /* returns consistent moduli in reduced form.
761 * Note: elasticModuli and hardeningModuli will be inverted
762 *
763 * stressVector in full form
764 */
765 FloatMatrix gradientMatrix;
766 FloatMatrix helpInverse;
767 int i, j, isize, size;
768
769 isize = elasticModuliInverse.giveNumberOfRows();
770 if ( this->hasHardening() ) {
771 size = isize + hardeningModuliInverse.giveNumberOfRows();
772 } else {
773 size = isize;
774 }
775
776 // assemble consistent moduli
777 helpInverse.resize(size, size);
778 helpInverse.zero();
779 for ( i = 1; i <= nsurf; i++ ) {
780 if ( activeConditionMap.at(i) ) {
781 // ask gradientMatrix
782 this->computeReducedGradientMatrix(gradientMatrix, i, gp, fullStressVector,
783 fullStressSpaceHardeningVars);
784
785 gradientMatrix.times( gamma.at(i) );
786 helpInverse.add(gradientMatrix);
787 }
788 }
789
790 for ( i = 1; i <= isize; i++ ) {
791 for ( j = 1; j <= isize; j++ ) {
792 helpInverse.at(i, j) += elasticModuliInverse.at(i, j);
793 }
794 }
795
796 if ( hardeningModuliInverse.giveNumberOfRows() > 0 ) {
797 for ( i = isize + 1; i <= size; i++ ) {
798 for ( j = isize + 1; j <= size; j++ ) {
799 helpInverse.at(i, j) += hardeningModuliInverse.at(i - isize, j - isize);
800 }
801 }
802 }
803
804 if ( hasHardening() && ( hardeningModuliInverse.giveNumberOfRows() == 0 ) ) {
805 FloatMatrix help;
806 help.beInverseOf(helpInverse);
807 answer.resize( isize + fullStressSpaceHardeningVars.giveSize(), isize + fullStressSpaceHardeningVars.giveSize() );
808 answer.zero();
809 for ( i = 1; i <= size; i++ ) {
810 for ( j = 1; j <= size; j++ ) {
811 answer.at(i, j) = help.at(i, j);
812 }
813 }
814 } else {
815 answer.beInverseOf(helpInverse);
816 }
817}
818
819// ----------------------------------------------------------------------------//
820
821
823MPlasticMaterial :: giveConsistentStiffnessMatrix(MatResponseMode mode,
824 GaussPoint *gp,
825 TimeStep *tStep) const
826{
827 //
828 // returns receiver material matrix for given reached state
829 // described by temp variables.
830 //
831
832 FloatMatrix consistentModuli, elasticModuli, hardeningModuli;
833 FloatMatrix elasticModuliInverse, hardeningModuliInverse;
834 FloatMatrix gmatInv, gmat, gradMat, helpMtrx, helpMtrx2, nmat, sbm1;
835 FloatArray stressVector, fullStressVector;
836 FloatArray stressSpaceHardeningVars;
837 FloatArray strainSpaceHardeningVariables;
838 std :: vector< FloatArray > yieldGradVec(this->nsurf), loadGradVec(this->nsurf), * yieldGradVecPtr, * loadGradVecPtr;
839
840 IntArray activeConditionMap;
841 FloatArray gamma;
842 int size, sizeR, i, j, iindx, actSurf = 0;
843
844 MPlasticMaterialStatus *status = static_cast< MPlasticMaterialStatus * >( this->giveStatus(gp) );
845
846 if ( this->plType == associatedPT ) {
847 yieldGradVecPtr = loadGradVecPtr = & yieldGradVec;
848 } else {
849 yieldGradVecPtr = & yieldGradVec;
850 loadGradVecPtr = & loadGradVec;
851 }
852
853 // ask for plastic consistency parameter
854 gamma = status->giveTempGamma();
855 activeConditionMap = status->giveTempActiveConditionMap();
856 //
857 // check for elastic cases
858 //
859 if ( ( status->giveTempStateFlag() == MPlasticMaterialStatus :: PM_Elastic ) || ( status->giveTempStateFlag() == MPlasticMaterialStatus :: PM_Unloading ) ) {
860 FloatMatrix answer;
861 this->linearElasticMaterial->giveStiffnessMatrix(answer, TangentStiffness, gp, tStep);
862 return answer;
863 }
864
865 //
866 // plastic case
867 //
868 // determine number of active surfaces
869 for ( i = 1; i <= nsurf; i++ ) {
870 if ( activeConditionMap.at(i) ) {
871 actSurf++;
872 }
873 }
874
875 // compute elastic moduli and its inverse
876 this->computeReducedElasticModuli(elasticModuli, gp, tStep);
877 elasticModuliInverse.beInverseOf(elasticModuli);
878 sizeR = elasticModuliInverse.giveNumberOfRows();
879
880 // compute hardening moduli and its inverse
881 this->computeHardeningReducedModuli(hardeningModuli, gp, strainSpaceHardeningVariables, tStep);
882 if ( hardeningModuli.giveNumberOfRows() ) {
883 hardeningModuliInverse.beInverseOf(hardeningModuli);
884 } else {
885 hardeningModuliInverse.clear();
886 }
887
888 stressVector = status->giveStressVector();
889 StructuralMaterial :: giveFullSymVectorForm( fullStressVector, stressVector, gp->giveMaterialMode() );
890 strainSpaceHardeningVariables = status->giveStrainSpaceHardeningVars();
891 this->computeStressSpaceHardeningVars(stressSpaceHardeningVars, gp, strainSpaceHardeningVariables);
892
893
894 //
895 // compute consistent moduli
896 //
897 this->computeAlgorithmicModuli(consistentModuli, gp, elasticModuliInverse, hardeningModuliInverse, gamma,
898 activeConditionMap, fullStressVector, stressSpaceHardeningVars);
899
900 //computee gmatInv
901 for ( i = 1; i <= nsurf; i++ ) {
902 this->computeGradientVector(yieldGradVec [ i - 1 ], yieldFunction, i, gp, fullStressVector, stressSpaceHardeningVars);
903 }
904
905 if ( this->plType == nonassociatedPT ) {
906 for ( i = 1; i <= nsurf; i++ ) {
907 this->computeGradientVector(loadGradVec [ i - 1 ], loadFunction, i, gp, fullStressVector, stressSpaceHardeningVars);
908 }
909 }
910
911
912 size = consistentModuli.giveNumberOfColumns();
913 gradMat.resize(actSurf, size);
914 for ( i = 1; i <= nsurf; i++ ) {
915 if ( ( iindx = activeConditionMap.at(i) ) ) {
916 for ( j = 1; j <= size; j++ ) {
917 gradMat.at(iindx, j) = ( * yieldGradVecPtr ) [ i - 1 ].at(j);
918 }
919 }
920 }
921
922 if ( this->plType == associatedPT ) {
923 helpMtrx.resize(actSurf, size);
924 helpMtrx.beProductTOf(consistentModuli, gradMat);
925 gmatInv.beProductOf(gradMat, helpMtrx);
926 gmat.beInverseOf(gmatInv);
927
928 nmat.resize(sizeR, size);
929 sbm1.beSubMatrixOf(consistentModuli, 1, sizeR, 1, size);
930 nmat.beProductTOf(sbm1, gradMat);
931 helpMtrx.beProductOf(nmat, gmat);
932 sbm1.beSubMatrixOf(consistentModuli, 1, size, 1, sizeR);
933 nmat.beProductOf(gradMat, sbm1);
934
935 helpMtrx2.beProductOf(helpMtrx, nmat);
936
937 FloatMatrix answer;
938 answer.beSubMatrixOf(consistentModuli, 1, sizeR, 1, sizeR);
939 answer.subtract(helpMtrx2);
940 return answer;
941 } else {
942 FloatMatrix lgradMat(actSurf, size);
943 for ( i = 1; i <= nsurf; i++ ) {
944 if ( ( iindx = activeConditionMap.at(i) ) ) {
945 for ( j = 1; j <= size; j++ ) {
946 lgradMat.at(iindx, j) = ( * loadGradVecPtr ) [ i - 1 ].at(j);
947 }
948 }
949 }
950
951 helpMtrx.resize(actSurf, size);
952 helpMtrx.beProductTOf(consistentModuli, lgradMat);
953 gmatInv.beProductOf(gradMat, helpMtrx);
954 gmat.beInverseOf(gmatInv);
955
956 nmat.resize(sizeR, size);
957 sbm1.beSubMatrixOf(consistentModuli, 1, sizeR, 1, size);
958 nmat.beProductTOf(sbm1, lgradMat);
959 helpMtrx.beProductOf(nmat, gmat);
960 sbm1.beSubMatrixOf(consistentModuli, 1, size, 1, sizeR);
961 nmat.beProductOf(gradMat, sbm1);
962 helpMtrx2.beProductOf(helpMtrx, nmat);
963
964 FloatMatrix answer;
965 answer.beSubMatrixOf(consistentModuli, 1, sizeR, 1, sizeR);
966 answer.subtract(helpMtrx2);
967 return answer;
968 }
969}
970
971
972void
973MPlasticMaterial :: giveElastoPlasticStiffnessMatrix(FloatMatrix &answer,
974 MatResponseMode mode,
975 GaussPoint *gp,
976 TimeStep *tStep) const
977{
978 //
979 // returns receiver material matrix for given reached state
980 // described by temp variables.
981 //
982
983 FloatMatrix dmat, elasticModuli, hardeningModuli;
984 FloatMatrix gmatInv, gmat, gradMat, helpMtrx, helpMtrx2;
985 FloatArray stressVector, fullStressVector;
986 FloatArray stressSpaceHardeningVars;
987 FloatArray strainSpaceHardeningVariables;
988 std :: vector< FloatArray > yieldGradVec(this->nsurf), loadGradVec(this->nsurf);
989
990 IntArray activeConditionMap;
991 int size, sizeR, i, j, iindx, actSurf = 0;
992
993 MPlasticMaterialStatus *status = static_cast< MPlasticMaterialStatus * >( this->giveStatus(gp) );
994
995 // ask for plastic consistency parameter
996 activeConditionMap = status->giveTempActiveConditionMap();
997 //
998 // check for elastic cases
999 //
1000 if ( ( status->giveTempStateFlag() == MPlasticMaterialStatus :: PM_Elastic ) || ( status->giveTempStateFlag() == MPlasticMaterialStatus :: PM_Unloading ) ) {
1001 this->linearElasticMaterial->giveStiffnessMatrix(answer, TangentStiffness, gp, tStep);
1002 return;
1003 }
1004
1005 //
1006 // plastic case
1007 //
1008 // determine number of active surfaces
1009 for ( i = 1; i <= nsurf; i++ ) {
1010 if ( activeConditionMap.at(i) ) {
1011 actSurf++;
1012 }
1013 }
1014
1015 // compute elastic moduli and its inverse
1016 this->computeReducedElasticModuli(elasticModuli, gp, tStep);
1017 sizeR = elasticModuli.giveNumberOfRows();
1018
1019 // compute hardening moduli and its inverse
1020 this->computeHardeningReducedModuli(hardeningModuli, gp, strainSpaceHardeningVariables, tStep);
1021
1022 stressVector = status->giveStressVector();
1023 StructuralMaterial :: giveFullSymVectorForm( fullStressVector, stressVector, gp->giveMaterialMode() );
1024 strainSpaceHardeningVariables = status->giveStrainSpaceHardeningVars();
1025 this->computeStressSpaceHardeningVars(stressSpaceHardeningVars, gp, strainSpaceHardeningVariables);
1026
1027
1028 //
1029 // compute consistent moduli
1030 //
1031 size = elasticModuli.giveNumberOfRows() + hardeningModuli.giveNumberOfRows();
1032 dmat.resize(size, size);
1033 dmat.zero();
1034
1035 for ( i = 1; i <= sizeR; i++ ) {
1036 for ( j = 1; j <= sizeR; j++ ) {
1037 dmat.at(i, j) = elasticModuli.at(i, j);
1038 }
1039 }
1040
1041 for ( i = sizeR + 1; i <= size; i++ ) {
1042 for ( j = sizeR + 1; j <= size; j++ ) {
1043 dmat.at(i, j) = hardeningModuli.at(i - sizeR, j - sizeR);
1044 }
1045 }
1046
1047
1048 //computee gmatInv
1049 for ( i = 1; i <= nsurf; i++ ) {
1050 this->computeGradientVector(yieldGradVec [ i - 1 ], yieldFunction, i, gp, fullStressVector, stressSpaceHardeningVars);
1051 }
1052
1053 if ( this->plType == nonassociatedPT ) {
1054 for ( i = 1; i <= nsurf; i++ ) {
1055 this->computeGradientVector(loadGradVec [ i - 1 ], loadFunction, i, gp, fullStressVector, stressSpaceHardeningVars);
1056 }
1057 }
1058
1059 gradMat.resize(actSurf, size);
1060 for ( i = 1; i <= nsurf; i++ ) {
1061 if ( ( iindx = activeConditionMap.at(i) ) ) {
1062 for ( j = 1; j <= size; j++ ) {
1063 gradMat.at(iindx, j) = yieldGradVec [ i - 1 ].at(j);
1064 }
1065 }
1066 }
1067
1068 if ( this->plType == associatedPT ) {
1069 helpMtrx.resize(actSurf, size);
1070 helpMtrx.beProductOf(gradMat, dmat);
1071 gmatInv.beProductTOf(helpMtrx, gradMat);
1072 gmat.beInverseOf(gmatInv);
1073
1074 helpMtrx.beProductOf(gradMat, elasticModuli);
1075 helpMtrx2.beProductOf(gmat, helpMtrx);
1076 answer.beTProductOf(helpMtrx, helpMtrx2);
1077 answer.negated();
1078 answer.add(elasticModuli);
1079 } else {
1080 FloatMatrix lgradMat(actSurf, size);
1081 for ( i = 1; i <= nsurf; i++ ) {
1082 if ( ( iindx = activeConditionMap.at(i) ) ) {
1083 for ( j = 1; j <= size; j++ ) {
1084 lgradMat.at(iindx, j) = loadGradVec [ i - 1 ].at(j);
1085 }
1086 }
1087 }
1088
1089 helpMtrx.resize(actSurf, size);
1090 helpMtrx.beProductOf(gradMat, dmat);
1091 gmatInv.beProductTOf(helpMtrx, lgradMat);
1092 gmat.beInverseOf(gmatInv);
1093
1094 helpMtrx.beProductOf(gradMat, elasticModuli);
1095 helpMtrx2.beProductOf(gmat, helpMtrx);
1096 helpMtrx.beProductTOf(elasticModuli, lgradMat);
1097 answer.beTProductOf(helpMtrx, helpMtrx2);
1098 answer.negated();
1099 answer.add(elasticModuli);
1100 }
1101}
1102
1103
1104void
1105MPlasticMaterial :: computeDiagModuli(FloatMatrix &answer,
1106 GaussPoint *gp, FloatMatrix &elasticModuliInverse,
1107 FloatMatrix &hardeningModuliInverse) const
1108{
1109 //
1110 // assembles diagonal moduli from elasticModuliInverse and hardeningModuliInverse
1111 //
1112 int size1, size2;
1113
1114 size1 = elasticModuliInverse.giveNumberOfRows();
1115 if ( hardeningModuliInverse.giveNumberOfRows() ) {
1116 size2 = size1 + hardeningModuliInverse.giveNumberOfRows();
1117 } else {
1118 size2 = size1;
1119 }
1120
1121 answer.resize(size2, size2);
1122 answer.zero();
1123
1124 for ( int i = 1; i <= size1; i++ ) {
1125 for ( int j = 1; j <= size1; j++ ) {
1126 answer.at(i, j) = elasticModuliInverse.at(i, j);
1127 }
1128 }
1129
1130 for ( int i = size1 + 1; i <= size2; i++ ) {
1131 for ( int j = size1 + 1; j <= size2; j++ ) {
1132 answer.at(i, j) = hardeningModuliInverse.at(i - size1, j - size1);
1133 }
1134 }
1135}
1136
1137
1138void
1139MPlasticMaterial :: computeReducedElasticModuli(FloatMatrix &answer,
1140 GaussPoint *gp,
1141 TimeStep *tStep) const
1142{ /* Returns elastic moduli in reduced stress-strain space*/
1143 this->linearElasticMaterial->giveStiffnessMatrix(answer, ElasticStiffness, gp, tStep);
1144}
1145
1146
1147// overloaded from structural material
1148
1150MPlasticMaterial :: give3dMaterialStiffnessMatrix(MatResponseMode mode,
1151 GaussPoint *gp,
1152 TimeStep *tStep) const
1153//
1154//
1155//
1156// computes full 3d constitutive matrix for case of 3d stress-strain state.
1157// it returns elasto-plastic stiffness material matrix.
1158// if strainIncrement == NULL a loading is assumed
1159// for detailed description see (W.F.Chen: Plasticity in Reinforced Concrete, McGraw-Hill, 1982,
1160// chapter 6.)
1161//
1162// if derived material would like to implement failure behaviour
1163// it must redefine basic Give3dMaterialStiffnessMatrix function
1164// in order to take possible failure (tension cracking) into account
1165//
1166//
1167//
1168{
1169 // we can force 3d response, and we obtain correct 3d tangent matrix,
1170 // but in fact, stress integration algorithm will not work
1171 // because in stress integration algorithm we are unable to recognize
1172 // which reduction from 3d case should be performed to obtain correct result.
1173 // so for new stressStrain state, instead of programming 3d reduction,
1174 // you should enhance imposeConstraints functions for ne state, and
1175 // then programming simple inteface function for you stressstrain state
1176 // calling GiveMaterailStiffenssMatrix, which imposes constrains correctly.
1177 if ( mode == ElasticStiffness ) {
1178 return this->linearElasticMaterial->give3dMaterialStiffnessMatrix(mode, gp, tStep);
1179 } else if ( rmType == mpm_ClosestPoint ) {
1180 return this->giveConsistentStiffnessMatrix(mode, gp, tStep);
1181 } else {
1182 FloatMatrix answer;
1183 this->giveElastoPlasticStiffnessMatrix(answer, mode, gp, tStep);
1184 return answer;
1185 }
1186}
1187
1188
1190MPlasticMaterial :: givePlaneStressStiffMtrx(MatResponseMode mode,
1191 GaussPoint *gp,
1192 TimeStep *tStep) const
1193
1194//
1195// returns receiver's 2dPlaneStressMtrx
1196// (2dPlaneStres ==> sigma_z = tau_xz = tau_yz = 0.)
1197//
1198// standard method from Material Class overloaded, because no inversion is needed.
1199// the reduction from 3d case will not work
1200// this implementation should be faster.
1201{
1202 if ( mode == ElasticStiffness ) {
1203 return this->linearElasticMaterial->givePlaneStressStiffMtrx(mode, gp, tStep);
1204 } else if ( rmType == mpm_ClosestPoint ) {
1205 return this->giveConsistentStiffnessMatrix(mode, gp, tStep);
1206 } else {
1207 FloatMatrix answer;
1208 this->giveElastoPlasticStiffnessMatrix(answer, mode, gp, tStep);
1209 return answer;
1210 }
1211}
1212
1213
1215MPlasticMaterial :: givePlaneStrainStiffMtrx(MatResponseMode mode,
1216 GaussPoint *gp,
1217 TimeStep *tStep) const
1218
1219//
1220// return receiver's 2dPlaneStrainMtrx constructed from
1221// general 3dMatrialStiffnessMatrix
1222// (2dPlaneStrain ==> eps_z = gamma_xz = gamma_yz = 0.)
1223//
1224{
1225 if ( mode == ElasticStiffness ) {
1226 return this->linearElasticMaterial->givePlaneStrainStiffMtrx(mode, gp, tStep);
1227 } else if ( rmType == mpm_ClosestPoint ) {
1228 return this->giveConsistentStiffnessMatrix(mode, gp, tStep);
1229 } else {
1230 FloatMatrix answer;
1231 this->giveElastoPlasticStiffnessMatrix(answer, mode, gp, tStep);
1232 return answer;
1233 }
1234}
1235
1236
1238MPlasticMaterial :: give1dStressStiffMtrx(MatResponseMode mode,
1239 GaussPoint *gp,
1240 TimeStep *tStep) const
1241
1242//
1243// returns receiver's 1dMaterialStiffnessMAtrix
1244// (1d case ==> sigma_y = sigma_z = tau_yz = tau_zx = tau_xy = 0.)
1245{
1246 if ( mode == ElasticStiffness ) {
1247 return this->linearElasticMaterial->give1dStressStiffMtrx(mode, gp, tStep);
1248 } else if ( rmType == mpm_ClosestPoint ) {
1249 return this->giveConsistentStiffnessMatrix(mode, gp, tStep);
1250 } else {
1251 FloatMatrix answer;
1252 const_cast<MPlasticMaterial*>(this)->giveElastoPlasticStiffnessMatrix(answer, mode, gp, tStep);
1253 return answer;
1254 }
1255}
1256
1257
1259MPlasticMaterial :: give2dBeamLayerStiffMtrx(MatResponseMode mode,
1260 GaussPoint *gp,
1261 TimeStep *tStep) const
1262//
1263// returns receiver's 2dBeamLayerStiffMtrx.
1264// (2dPlaneStres ==> sigma_z = tau_xz = tau_yz = 0.)
1265//
1266// standard method from Material Class overloaded, because no inversion is needed.
1267// the reduction from 3d case will not work
1268// this implementation should be faster.
1269{
1270 if ( mode == ElasticStiffness ) {
1271 return this->linearElasticMaterial->give2dBeamLayerStiffMtrx(mode, gp, tStep);
1272 } else if ( rmType == mpm_ClosestPoint ) {
1273 return this->giveConsistentStiffnessMatrix(mode, gp, tStep);
1274 } else {
1275 FloatMatrix answer;
1276 const_cast<MPlasticMaterial*>(this)->giveElastoPlasticStiffnessMatrix(answer, mode, gp, tStep);
1277 return answer;
1278 }
1279}
1280
1281
1283MPlasticMaterial :: givePlateLayerStiffMtrx(MatResponseMode mode,
1284 GaussPoint *gp,
1285 TimeStep *tStep) const
1286//
1287// returns receiver's 2dPlateLayerMtrx
1288// (2dPlaneStres ==> sigma_z = tau_xz = tau_yz = 0.)
1289//
1290// standard method from Material Class overloaded, because no inversion is needed.
1291// the reduction from 3d case will not work
1292// this implementation should be faster.
1293{
1294 if ( mode == ElasticStiffness ) {
1295 return this->linearElasticMaterial->givePlateLayerStiffMtrx(mode, gp, tStep);
1296 } else if ( rmType == mpm_ClosestPoint ) {
1297 return this->giveConsistentStiffnessMatrix(mode, gp, tStep);
1298 } else {
1299 FloatMatrix answer;
1300 const_cast<MPlasticMaterial*>(this)->giveElastoPlasticStiffnessMatrix(answer, mode, gp, tStep);
1301 return answer;
1302 }
1303}
1304
1305
1307MPlasticMaterial :: giveFiberStiffMtrx(MatResponseMode mode,
1308 GaussPoint *gp,
1309 TimeStep *tStep) const
1310//
1311// returns receiver's Fiber
1312// (1dFiber ==> sigma_y = sigma_z = tau_yz = 0.)
1313//
1314// standard method from Material Class overloaded, because no inversion is needed.
1315// the reduction from 3d case will not work
1316// this implementation should be faster.
1317{
1318 if ( mode == ElasticStiffness ) {
1319 return this->linearElasticMaterial->giveFiberStiffMtrx(mode, gp, tStep);
1320 } else if ( rmType == mpm_ClosestPoint ) {
1321 return this->giveConsistentStiffnessMatrix(mode, gp, tStep);
1322 } else {
1323 FloatMatrix answer;
1324 const_cast<MPlasticMaterial*>(this)->giveElastoPlasticStiffnessMatrix(answer, mode, gp, tStep);
1325 return answer;
1326 }
1327}
1328
1329
1330int
1331MPlasticMaterial :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
1332{
1333 MPlasticMaterialStatus *status = static_cast< MPlasticMaterialStatus * >( this->giveStatus(gp) );
1334 if ( type == IST_PlasticStrainTensor ) {
1335 const FloatArray &ep = status->givePlasticStrainVector();
1337 StructuralMaterial :: giveFullSymVectorForm( answer, ep, gp->giveMaterialMode() );
1338 return 1;
1339 } else if ( type == IST_PrincipalPlasticStrainTensor ) {
1340 FloatArray st;
1341
1342 const FloatArray &s = status->givePlasticStrainVector();
1344 StructuralMaterial :: giveFullSymVectorForm( st, s, gp->giveMaterialMode() );
1345
1346 this->computePrincipalValues(answer, st, principal_strain);
1347 return 1;
1348 } else {
1349 return StructuralMaterial :: giveIPValue(answer, gp, type, tStep);
1350 }
1351}
1352
1353
1354MPlasticMaterialStatus :: MPlasticMaterialStatus(GaussPoint *g, int statusSize) :
1357{}
1358
1359
1360void
1361MPlasticMaterialStatus :: printOutputAt(FILE *file, TimeStep *tStep) const
1362{
1363 StructuralMaterialStatus :: printOutputAt(file, tStep);
1364 fprintf(file, "status { ");
1365 if ( ( state_flag == MPlasticMaterialStatus :: PM_Yielding ) || ( state_flag == MPlasticMaterialStatus :: PM_Unloading ) ) {
1366 if ( state_flag == MPlasticMaterialStatus :: PM_Yielding ) {
1367 fprintf(file, " Yielding, ");
1368 } else {
1369 fprintf(file, " Unloading, ");
1370 }
1371
1372 fprintf(file, " plastic strains ");
1373 for ( auto &val : plasticStrainVector ) {
1374 fprintf( file, " %.4e", val );
1375 }
1376
1377 if ( strainSpaceHardeningVarsVector.giveSize() ) {
1378 fprintf(file, ", strain space hardening vars ");
1379 for ( auto &val : strainSpaceHardeningVarsVector ) {
1380 fprintf( file, " %.4e", val );
1381 }
1382 }
1383 }
1384
1385 fprintf(file, "}\n");
1386}
1387
1388
1389void MPlasticMaterialStatus :: initTempStatus()
1390//
1391// initializes temp variables according to variables form previous equlibrium state.
1392//
1393{
1394 StructuralMaterialStatus :: initTempStatus();
1395
1396 if ( plasticStrainVector.giveSize() == 0 ) {
1397 plasticStrainVector.resize( StructuralMaterial :: giveSizeOfVoigtSymVector( gp->giveMaterialMode() ) );
1398 plasticStrainVector.zero();
1399 }
1400
1402
1404
1405
1406 tempGamma = gamma;
1408}
1409
1410
1411void
1412MPlasticMaterialStatus :: updateYourself(TimeStep *tStep)
1413//
1414// updates variables (nonTemp variables describing situation at previous equilibrium state)
1415// after a new equilibrium state has been reached
1416// temporary variables are having values corresponding to newly reched equilibrium.
1417//
1418{
1419 StructuralMaterialStatus :: updateYourself(tStep);
1420
1423
1425 gamma = tempGamma;
1427}
1428
1429
1430void
1431MPlasticMaterialStatus :: saveContext(DataStream &stream, ContextMode mode)
1432{
1433 StructuralMaterialStatus :: saveContext(stream, mode);
1434
1435 contextIOResultType iores;
1436 if ( ( iores = plasticStrainVector.storeYourself(stream) ) != CIO_OK ) {
1437 THROW_CIOERR(iores);
1438 }
1439
1440 if ( ( iores = strainSpaceHardeningVarsVector.storeYourself(stream) ) != CIO_OK ) {
1441 THROW_CIOERR(iores);
1442 }
1443
1444 if ( !stream.write(state_flag) ) {
1446 }
1447
1448 if ( ( iores = gamma.storeYourself(stream) ) != CIO_OK ) {
1449 THROW_CIOERR(iores);
1450 }
1451
1452 if ( ( iores = activeConditionMap.storeYourself(stream) ) != CIO_OK ) {
1453 THROW_CIOERR(iores);
1454 }
1455}
1456
1457
1458void
1459MPlasticMaterialStatus :: restoreContext(DataStream &stream, ContextMode mode)
1460{
1461 StructuralMaterialStatus :: restoreContext(stream, mode);
1462
1463 contextIOResultType iores;
1464 if ( ( iores = plasticStrainVector.restoreYourself(stream) ) != CIO_OK ) {
1465 THROW_CIOERR(iores);
1466 }
1467
1468 if ( ( iores = strainSpaceHardeningVarsVector.restoreYourself(stream) ) != CIO_OK ) {
1469 THROW_CIOERR(iores);
1470 }
1471
1472 if ( !stream.read(state_flag) ) {
1474 }
1475
1476 if ( ( iores = gamma.restoreYourself(stream) ) != CIO_OK ) {
1477 THROW_CIOERR(iores);
1478 }
1479
1480 if ( ( iores = activeConditionMap.restoreYourself(stream) ) != CIO_OK ) {
1481 THROW_CIOERR(iores);
1482 }
1483}
1484} // end namespace oofem
virtual int read(int *data, std::size_t count)=0
Reads count integer values into array pointed by data.
virtual int write(const int *data, std::size_t count)=0
Writes count integer values from array pointed by data.
int giveNumber() const
Definition femcmpnn.h:104
double computeNorm() const
Definition floatarray.C:861
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
double dotProduct(const FloatArray &x) const
Definition floatarray.C:524
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:689
void beTProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:721
void add(const FloatArray &src)
Definition floatarray.C:218
void subtract(const FloatArray &src)
Definition floatarray.C:320
bool isNotEmpty() const
Returns true if receiver is not empty.
Definition floatarray.h:263
void times(double f)
void add(const FloatMatrix &a)
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 beSubMatrixOf(const FloatMatrix &src, Index topRow, Index bottomRow, Index topCol, Index bottomCol)
void beProductTOf(const FloatMatrix &a, const FloatMatrix &b)
int giveNumberOfColumns() const
Returns number of columns of receiver.
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
void zero()
Zeroes all coefficient of receiver.
bool beInverseOf(const FloatMatrix &src)
int giveNumberOfRows() const
Returns number of rows of receiver.
double at(std::size_t i, std::size_t j) const
bool solveForRhs(const FloatArray &b, FloatArray &answer, bool transpose=false)
void subtract(const FloatMatrix &a)
void beTProductOf(const FloatMatrix &a, const FloatMatrix &b)
int giveNumber()
Returns number of receiver.
Definition gausspoint.h:183
MaterialMode giveMaterialMode()
Returns corresponding material mode of receiver.
Definition gausspoint.h:190
Element * giveElement()
Returns corresponding element to receiver.
Definition gausspoint.h:187
void zero()
Sets all component to zero.
Definition intarray.C:52
int & at(std::size_t i)
Definition intarray.h:104
GaussPoint * gp
Associated integration point.
const FloatArray & giveTempGamma()
FloatArray gamma
Consistency parameter values (needed for algorithmic stiffness).
void letTempStrainSpaceHardeningVarsVectorBe(FloatArray v)
void setTempActiveConditionMap(IntArray v)
const FloatArray & givePlasticStrainVector() const
Returns the equilibrated strain vector.
IntArray activeConditionMap
Active set of yield functions (needed for algorithmic stiffness).
const FloatArray & giveStrainSpaceHardeningVars() const
Returns the equilibrated hardening variable vector.
const IntArray & giveTempActiveConditionMap()
int state_flag
Yield function status indicator.
FloatArray strainSpaceHardeningVarsVector
Strain space hardening variables.
FloatArray plasticStrainVector
Plastic strain vector.
void letTempPlasticStrainVectorBe(FloatArray v)
virtual int giveSizeOfReducedHardeningVarsVector(GaussPoint *) const
void cuttingPlaneReturn(FloatArray &answer, IntArray &activeConditionMap, FloatArray &gamma, GaussPoint *gp, const FloatArray &totalStrain, FloatArray &plasticStrainR, FloatArray &strainSpaceHardeningVariables, TimeStep *tStep) const
virtual void computeTrialStressIncrement(FloatArray &answer, GaussPoint *gp, const FloatArray &strainIncrement, TimeStep *tStep) const
void computeAlgorithmicModuli(FloatMatrix &answer, GaussPoint *gp, const FloatMatrix &elasticModuliInverse, const FloatMatrix &hardeningModuliInverse, const FloatArray &gamma, const IntArray &activeConditionMap, const FloatArray &fullStressVector, const FloatArray &fullStressSpaceHardeningVars) const
void closestPointReturn(FloatArray &answer, IntArray &activeConditionMap, FloatArray &gamma, GaussPoint *gp, const FloatArray &totalStrain, FloatArray &plasticStrainR, FloatArray &strainSpaceHardeningVariables, TimeStep *tStep) const
virtual void computeReducedGradientMatrix(FloatMatrix &answer, int isurf, GaussPoint *gp, const FloatArray &stressVector, const FloatArray &stressSpaceHardeningVars) const =0
virtual void computeStressSpaceHardeningVars(FloatArray &answer, GaussPoint *gp, const FloatArray &strainSpaceHardeningVariables) const =0
virtual void computeReducedElasticModuli(FloatMatrix &answer, GaussPoint *gp, TimeStep *tStep) const
MPlasticMaterial(int n, Domain *d)
virtual void computeHardeningReducedModuli(FloatMatrix &answer, GaussPoint *gp, const FloatArray &strainSpaceHardeningVariables, TimeStep *tStep) const =0
virtual void computeStressGradientVector(FloatArray &answer, functType ftype, int isurf, GaussPoint *gp, const FloatArray &stressVector, const FloatArray &stressSpaceHardeningVars) const =0
virtual double computeYieldValueAt(GaussPoint *gp, int isurf, const FloatArray &stressVector, const FloatArray &stressSpaceHardeningVars) const =0
functType
Type that allows to distinguish between yield function and loading function.
virtual void computeStressSpaceHardeningVarsReducedGradient(FloatArray &answer, functType ftype, int isurf, GaussPoint *gp, const FloatArray &stressVector, const FloatArray &stressSpaceHardeningVars) const =0
int nsurf
Number of yield surfaces.
virtual int hasHardening() const
enum oofem::MPlasticMaterial::ReturnMappingAlgoType rmType
void computeGradientVector(FloatArray &answer, functType ftype, int isurf, GaussPoint *gp, const FloatArray &fullStressVector, const FloatArray &fullStressSpaceHardeningVars) const
void computeResidualVector(FloatArray &answer, GaussPoint *gp, const FloatArray &gamma, const IntArray &activeConditionMap, const FloatArray &plasticStrainVectorR, const FloatArray &strainSpaceHardeningVariables, std ::vector< FloatArray > &gradVec) const
virtual void giveElastoPlasticStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const
virtual FloatMatrix giveConsistentStiffnessMatrix(MatResponseMode, GaussPoint *gp, TimeStep *tStep) const
LinearElasticMaterial * linearElasticMaterial
Reference to bulk (undamaged) material.
enum oofem::MPlasticMaterial::plastType plType
void computeDiagModuli(FloatMatrix &answer, GaussPoint *gp, FloatMatrix &elasticModuliInverse, FloatMatrix &hardeningModuliInverse) const
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Definition material.C:206
virtual void initTempStatus(GaussPoint *gp) const
Definition material.C:221
const FloatArray & giveTempStressVector() const
Returns the const pointer to receiver's temporary stress vector.
StructuralMaterialStatus(GaussPoint *g)
Constructor. Creates new StructuralMaterialStatus with IntegrationPoint g.
const FloatArray & giveStressVector() const
Returns the const pointer to receiver's stress vector.
void letTempStressVectorBe(const FloatArray &v)
Assigns tempStressVector to given vector v.
void letTempStrainVectorBe(const FloatArray &v)
Assigns tempStrainVector to given vector v.
static void computePrincipalValues(FloatArray &answer, const FloatArray &s, stressStrainPrincMode mode)
Common functions for convenience.
StructuralMaterial(int n, Domain *d)
void giveStressDependentPartOfStrainVector(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedStrainVector, TimeStep *tStep, ValueModeType mode) const
#define THROW_CIOERR(e)
#define OOFEM_WARNING(...)
Definition error.h:80
#define RES_TOL
#define YIELD_TOL
#define PLASTIC_MATERIAL_MAX_ITERATIONS
long ContextMode
Definition contextmode.h:43
@ principal_strain
For computing principal strains from engineering strains.
@ CIO_IOERR
General IO error.

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