OOFEM 3.0
Loading...
Searching...
No Matches
perfectlyplasticmaterial.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
37#include "gausspoint.h"
38#include "floatmatrix.h"
39#include "floatarray.h"
40#include "mathfem.h"
41#include "datastream.h"
42#include "contextioerr.h"
43
44namespace oofem {
45bool
46PerfectlyPlasticMaterial :: hasMaterialModeCapability(MaterialMode mode) const
47//
48// returns whether receiver supports given mode
49//
50{
51 return mode == _3dMat ||
52 //<RESTRICTED_SECTION>
53 mode == _PlaneStress ||
54 //</RESTRICTED_SECTION>
55 mode == _PlaneStrain ||
56 mode == _1dMat ||
57 mode == _PlateLayer ||
58 mode == _2dBeamLayer;
59}
60
61
62void
63PerfectlyPlasticMaterial :: giveRealStressVector(FloatArray &answer,
64 GaussPoint *gp,
65 const FloatArray &totalStrain,
66 TimeStep *tStep) const
67//
68// returns stress vector (in full or reduced form ) of receiver according to
69// previous level of stress and current
70// strain increment, the only way, how to correctly update gp records
71//
72//
73// may be good idea for nonlinear materials overload this function in order to
74// capture strain - stress history for proper modelling receiver behaviour
75// and in order to capture possible failure of material
76//
77// Note: formulated in full stress strain space
78{
79 FloatArray elasticStressIncrement;
80 FloatArray workStress, *yieldStressGrad, workStress2, stressVector3d;
81 FloatArray mStrainIncrement3d, mStressElasticIncrement3d, PlasticStrainVector3d;
82 FloatArray dSigmaIncrement3d, *stressCorrection, *loadingStressGrad;
83 FloatArray helpArray;
84 FloatArray plasticStrainIncrement3d, strainIncrement, reducedStrain, reducedStrainIncrement;
85 FloatArray statusFullStressVector, statusFullPlasticVector;
86 FloatArray plasticStrainVector;
87 PerfectlyPlasticMaterialStatus *status = static_cast< PerfectlyPlasticMaterialStatus * >( this->giveStatus(gp) );
88
89 FloatMatrix dp;
90 StructuralCrossSection *crossSection = static_cast< StructuralCrossSection * >
91 ( gp->giveElement()->giveCrossSection() );
92 double f0, f1, f2, help, dLambda, r, r1, m;
93
94 // init temp variables (of YC,LC,Material) at the beginning of step
95 this->initTempStatus(gp);
96 // subtract stress independent part
97 // note: eigenStrains (temperature) is not contained in mechanical strain stored in gp
98 // therefore it is necessary to subtract always the total eigen strain value
99 this->giveStressDependentPartOfStrainVector(reducedStrain, gp, totalStrain,
100 tStep, VM_Total);
101
102 reducedStrainIncrement.beDifferenceOf( reducedStrain, status->giveStrainVector() );
103
104 StructuralMaterial :: giveFullSymVectorForm( strainIncrement, reducedStrainIncrement, gp->giveMaterialMode() );
105 plasticStrainVector = status->givePlasticStrainVector();
106 StructuralMaterial :: giveFullSymVectorForm( statusFullPlasticVector, plasticStrainVector, gp->giveMaterialMode() );
107 StructuralMaterial :: giveFullSymVectorForm( statusFullStressVector, status->giveStressVector(), gp->giveMaterialMode() );
108
109 //
110 // Note : formulated in full stress strain space
111 //
112 this->computeTrialStressIncrement(elasticStressIncrement, gp, strainIncrement, tStep);
113 //
114 // calculate deltaSigmaPlastic
115 //
116 workStress = statusFullStressVector;
117 workStress.add(elasticStressIncrement);
118
119 f0 = this->computeYCValueAt(gp, & statusFullStressVector,
120 & statusFullPlasticVector);
121
122 f1 = this->computeYCValueAt(gp, & workStress,
123 & statusFullPlasticVector);
124
125 PlasticStrainVector3d = statusFullPlasticVector;
126
127
128 if ( f1 >= 0. ) { // loading surface violated by the elastic trial set
129 if ( f0 < 0. ) { // previously in elastic area
130 // element not yielding - set the print status
131 status->setTempYieldFlag(0);
132 // compute scaling factor
133 r1 = -f0 / ( f1 - f0 ); // linear interpolation in f (Zienkiewicz, 1969)
134 yieldStressGrad = this->GiveYCStressGradient(gp, & statusFullStressVector,
135 & statusFullPlasticVector);
136 crossSection->imposeStressConstrainsOnGradient(gp, yieldStressGrad);
137
138 help = 0.;
139 for ( int i = 1; i <= 6; i++ ) {
140 help += yieldStressGrad->at(i) * elasticStressIncrement.at(i);
141 }
142
143 delete yieldStressGrad;
144
145 workStress2 = elasticStressIncrement;
146 workStress2.times(r1);
147 workStress2.add(statusFullStressVector);
148
149 f2 = this->computeYCValueAt(gp, & workStress2,
150 & statusFullPlasticVector);
151
152 if ( fabs(help) > 1.e-6 ) {
153 r = r1 - f2 / help; // improved value of r (Nayak & Zienkiewicz, 1972)
154 } else {
155 r = r1;
156 }
157 } else { // f0 should be zero
158 r = 0.;
159 }
160
161 stressVector3d = elasticStressIncrement;
162 stressVector3d.times(r);
163 stressVector3d.add(statusFullStressVector);
164
165 m = STRAIN_STEPS;
166 mStrainIncrement3d = strainIncrement;
167 mStrainIncrement3d.times( ( 1.0 - r ) / m );
168 mStressElasticIncrement3d = elasticStressIncrement;
169 mStressElasticIncrement3d.times( ( 1.0 - r ) / m );
170
171 // test if fracture or failure occurs
172 this->updateIfFailure(gp, & stressVector3d, & PlasticStrainVector3d);
173 // element yielding - set the print status
174 status->setTempYieldFlag(1);
175 // loop over m-steps
176 for ( int i = 1; i <= m; i++ ) {
177 // yieldStressGrad = yieldCriteria->
178 // GiveStressGradient (gp, stressVector3d,
179 // PlasticStrainVector3d,
180 // gp-> giveHardeningParam());
181
182 // compute dLambda and dp
183 this->computePlasticStiffnessAt(dp, gp,
184 & stressVector3d,
185 & PlasticStrainVector3d,
186 & mStrainIncrement3d,
187 tStep,
188 dLambda);
189 if ( dLambda < 0. ) {
190 dLambda = 0.;
191 }
192
193 dSigmaIncrement3d.beProductOf(dp, mStrainIncrement3d);
194 dSigmaIncrement3d.negated();
195 dSigmaIncrement3d.add(mStressElasticIncrement3d);
196 // compute normal to loading surface
197 loadingStressGrad = this->GiveLCStressGradient(gp, & stressVector3d,
198 & PlasticStrainVector3d);
199
200 // update the stress state
201 stressVector3d.add(dSigmaIncrement3d);
202 // compute stress corrections
203
204 stressCorrection = this->
205 GiveStressCorrectionBackToYieldSurface(gp, & stressVector3d,
206 & PlasticStrainVector3d);
207 // apply the stress correction -> correction is in the direction of
208 // the normal to the yield surface
209 stressVector3d.add(* stressCorrection);
210 // test = yieldCriteria-> computeValueAt(stressVector3d,
211 // PlasticStrainVector3d,
212 // gp-> giveHardeningParam());
213
214 // calculate plastic strain increment
215
216 crossSection->imposeStrainConstrainsOnGradient(gp, loadingStressGrad);
217 loadingStressGrad->times(dLambda);
218 PlasticStrainVector3d.add(* loadingStressGrad);
219 // strainVector3d -> add (mStrainIncrement3d);
220
221 // update yieldCriteria and loading criteria records to newly reached state
222 // in loadingStressGrad is stored current plastic vector increment
223 this->updateTempYC(gp, & stressVector3d, & PlasticStrainVector3d);
224 this->updateTempLC(gp, & stressVector3d, & PlasticStrainVector3d);
225
226 // test if fracture or failure occurs
227 this->updateIfFailure(gp, & stressVector3d, & PlasticStrainVector3d);
228
229 delete loadingStressGrad;
230 delete stressCorrection;
231 }
232
233 // compute total stress increment during strainIncrement
234 // totalStressIncrement = statusFullStressVector;
235 // totalStressIncrement.times (-1.0);
236 // totalStressIncrement.add (stressVector3d);
237 // update gp
238 FloatArray helpArry;
239 StructuralMaterial :: giveReducedSymVectorForm( helpArry, stressVector3d, gp->giveMaterialMode() );
240
241 status->letTempStressVectorBe(helpArry);
242 status->letTempStrainVectorBe(totalStrain);
243 } else {
244 // element not yielding - set the print status
245 status->setTempYieldFlag(0);
246 stressVector3d = statusFullStressVector;
247 stressVector3d.add(elasticStressIncrement);
248 // test if fracture or failure occurs
249 this->updateIfFailure(gp, & stressVector3d, & PlasticStrainVector3d);
250 // update gp
251 status->letTempStrainVectorBe(totalStrain);
252 StructuralMaterial :: giveReducedSymVectorForm( helpArray, stressVector3d, gp->giveMaterialMode() );
253 status->letTempStressVectorBe(helpArray);
254 }
255
256 // update gp plastic strain
257 plasticStrainIncrement3d.beDifferenceOf(PlasticStrainVector3d, statusFullPlasticVector);
258 StructuralMaterial :: giveReducedSymVectorForm( helpArray, plasticStrainIncrement3d, gp->giveMaterialMode() );
259 status->letPlasticStrainIncrementVectorBe(helpArray);
260
261 StructuralMaterial :: giveReducedSymVectorForm( answer, stressVector3d, gp->giveMaterialMode() );
262}
263
264
265void
266PerfectlyPlasticMaterial :: giveEffectiveMaterialStiffnessMatrix(FloatMatrix &answer,
267 MatResponseMode mode,
268 GaussPoint *gp,
269 TimeStep *tStep) const
270//
271//
272// for case of perfectly plastic material
273// computes full elastic constitutive matrix for case of gp stress-strain state.
274// if strainIncrement == NULL a loading is assumed
275//
276// we follow terminology based on paper from R. de Borst:
277// "Smeared Cracking, plasticity, creep - Unified Aproach"
278//
279// if derived material would like to implement failure behaviour
280// it must redefine basic Give3dMaterialStiffnessMatrix function
281// in order to take possible failure (tension cracking) into account
282//
283{
284 // FloatMatrix *de; // elastic matrix respecting fracture or failure
285 StructuralMaterial *lMat = static_cast< StructuralMaterial * >( this->giveLinearElasticMaterial() );
286
287 if ( lMat->hasMaterialModeCapability( gp->giveMaterialMode() ) ) {
288 FloatMatrix stiff;
289 lMat->giveStiffnessMatrix(stiff, mode, gp, tStep);
290 this->giveFullSymMatrixForm( answer, stiff, gp->giveMaterialMode() );
291 } else {
292 OOFEM_ERROR("giveEffectiveMaterialStiffnessMatrix - unsupported material mode");
293 }
294}
295
296void
297PerfectlyPlasticMaterial :: giveMaterialStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode,
298 GaussPoint *gp,
299 TimeStep *tStep) const
300//
301//
302//
303// computes full constitutive matrix for case of gp stress-strain state.
304// it returns elasto-plastic stiffness material matrix.
305// if strainIncrement == NULL a loading is assumed
306// for detailed description see (W.F.Chen: Plasticity in Reinforced Concrete, McGraw-Hill, 1982,
307// chapter 6.)
308//
309// if derived material would like to implement failure behaviour
310// it must redefine basic Give3dMaterialStiffnessMatrix function
311// in order to take possible failure (tension cracking) into account
312//
313// in this function answer is Material stiffness matrix respecting
314// current stress-strain mode in gp. This is reached by using
315// impose constraints functions
316{
317 FloatArray statusFullStressVector, statusFullPlasticVector, plasticStrainVector;
318 double lambda;
319 PerfectlyPlasticMaterialStatus *status = static_cast< PerfectlyPlasticMaterialStatus * >( this->giveStatus(gp) );
320
321 // double f = domain->giveYieldCriteria(yieldCriteria)->
322 // computeValueAt(gp->giveStressVector(), gp->givePlasticStrainVector(),
323 // gp-> giveHardeningParam());
324
325 this->giveEffectiveMaterialStiffnessMatrix(answer, mode, gp, tStep);
326 // if (f < YIELD_BOUNDARY) // linear elastic behaviour
327 // return de;
328
329 if ( status->giveYieldFlag() == 0 ) {
330 return;
331 }
332
333 // if secant stiffness requested assume initial elastic matrix
334 if ( mode == SecantStiffness ) {
335 return;
336 }
337
338 plasticStrainVector = status->givePlasticStrainVector();
339 StructuralMaterial :: giveFullSymVectorForm( statusFullPlasticVector, plasticStrainVector, gp->giveMaterialMode() );
340 StructuralMaterial :: giveFullSymVectorForm( statusFullStressVector, status->giveStressVector(), gp->giveMaterialMode() );
341
342 // yield condition satisfied
343 FloatMatrix dp;
344 this->computePlasticStiffnessAt(dp, gp, & statusFullStressVector,
345 & statusFullPlasticVector,
346 NULL,
347 tStep,
348 lambda);
349 answer.add(dp);
350}
351
352
354PerfectlyPlasticMaterial :: give3dMaterialStiffnessMatrix(MatResponseMode mode,
355 GaussPoint *gp,
356 TimeStep *tStep) const
357//
358//
359//
360// computes full 3d constitutive matrix for case of 3d stress-strain state.
361// it returns elasto-plastic stiffness material matrix.
362// if strainIncrement == NULL a loading is assumed
363// for detailed description see (W.F.Chen: Plasticity in Reinforced Concrete, McGraw-Hill, 1982,
364// chapter 6.)
365//
366// if derived material would like to implement failure behaviour
367// it must redefine basic Give3dMaterialStiffnessMatrix function
368// in order to take possible failure (tension cracking) into account
369//
370//
371{
372 // we can force 3d response, and we obtain correct 3d tangent matrix,
373 // but in fact, stress integration algorithm will not work
374 // because in stress integration algorithm we are unable to recognize
375 // which reduction from 3d case should be performed to obtain correct result.
376 // so for new stressStrain state, instead of programming 3d reduction,
377 // you should enhance imposeConstraints functions for ne state, and
378 // then programming simple inteface function for you stressstrain state
379 // calling GiveMaterailStiffenssMatrix, which imposes constrains correctly.
380
381 if ( mode == ElasticStiffness ) {
382 return this->linearElasticMaterial->give3dMaterialStiffnessMatrix(mode, gp, tStep);
383 } else {
384 FloatMatrix answer;
385 const_cast<PerfectlyPlasticMaterial*>(this)->giveMaterialStiffnessMatrix(answer, mode, gp, tStep);
386 return answer;
387 }
388}
389
390
392PerfectlyPlasticMaterial :: givePlaneStressStiffMtrx(MatResponseMode mode,
393 GaussPoint *gp,
394 TimeStep *tStep) const
395//
396// returns receiver's 2dPlaneStressMtrx
397// (2dPlaneStres ==> sigma_z = tau_xz = tau_yz = 0.)
398//
399// standard method from Material Class overloaded, because no inversion is needed.
400// the reduction from 3d case will not work
401// this implementation should be faster.
402{
403 if ( mode == ElasticStiffness ) {
404 return this->linearElasticMaterial->givePlaneStressStiffMtrx(mode, gp, tStep);
405 } else {
406 FloatMatrix fullAnswer, answer;
407 const_cast<PerfectlyPlasticMaterial*>(this)->giveMaterialStiffnessMatrix(fullAnswer, mode, gp, tStep);
408 StructuralMaterial :: giveReducedSymMatrixForm( answer, fullAnswer, gp->giveMaterialMode() );
409 return answer;
410 }
411}
412
413
415PerfectlyPlasticMaterial :: givePlaneStrainStiffMtrx(MatResponseMode mode,
416 GaussPoint *gp,
417 TimeStep *tStep) const
418//
419// return receiver's 2dPlaneStrainMtrx constructed from
420// general 3dMatrialStiffnessMatrix
421// (2dPlaneStrain ==> eps_z = gamma_xz = gamma_yz = 0.)
422//
423{
424 if ( mode == ElasticStiffness ) {
425 return this->linearElasticMaterial->givePlaneStrainStiffMtrx(mode, gp, tStep);
426 } else {
427 FloatMatrix fullAnswer, answer;
428 const_cast<PerfectlyPlasticMaterial*>(this)->giveMaterialStiffnessMatrix(fullAnswer, mode, gp, tStep);
429 StructuralMaterial :: giveReducedSymMatrixForm( answer, fullAnswer, gp->giveMaterialMode() );
430 return answer;
431 }
432}
433
434
436PerfectlyPlasticMaterial :: give1dStressStiffMtrx(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const
437
438//
439// returns receiver's 1dMaterialStiffnessMAtrix
440// (1d case ==> sigma_y = sigma_z = tau_yz = tau_zx = tau_xy = 0.)
441{
442 if ( mode == ElasticStiffness ) {
443 return this->linearElasticMaterial->give1dStressStiffMtrx(mode, gp, tStep);
444 } else {
445 FloatMatrix fullAnswer, answer;
446 const_cast<PerfectlyPlasticMaterial*>(this)->giveMaterialStiffnessMatrix(fullAnswer, mode, gp, tStep);
447 StructuralMaterial :: giveReducedSymMatrixForm( answer, fullAnswer, gp->giveMaterialMode() );
448 return answer;
449 }
450}
451
452
453
455PerfectlyPlasticMaterial :: give2dBeamLayerStiffMtrx(MatResponseMode mode,
456 GaussPoint *gp,
457 TimeStep *tStep) const
458//
459// returns receiver's 2dBeamLayerStiffMtrx.
460// (2dPlaneStres ==> sigma_z = tau_xz = tau_yz = 0.)
461//
462// standard method from Material Class overloaded, because no inversion is needed.
463// the reduction from 3d case will not work
464// this implementation should be faster.
465{
466 if ( mode == ElasticStiffness ) {
467 return this->linearElasticMaterial->give2dBeamLayerStiffMtrx(mode, gp, tStep);
468 } else {
469 FloatMatrix fullAnswer, answer;
470 const_cast<PerfectlyPlasticMaterial*>(this)->giveMaterialStiffnessMatrix(fullAnswer, mode, gp, tStep);
471 StructuralMaterial :: giveReducedSymMatrixForm( answer, fullAnswer, gp->giveMaterialMode() );
472 return answer;
473 }
474}
475
476
478PerfectlyPlasticMaterial :: givePlateLayerStiffMtrx(MatResponseMode mode,
479 GaussPoint *gp,
480 TimeStep *tStep) const
481//
482// returns receiver's 2dPlateLayerMtrx
483// (2dPlaneStres ==> sigma_z = tau_xz = tau_yz = 0.)
484//
485// standard method from Material Class overloaded, because no inversion is needed.
486// the reduction from 3d case will not work
487// this implementation should be faster.
488{
489 if ( mode == ElasticStiffness ) {
490 return this->linearElasticMaterial->givePlateLayerStiffMtrx(mode, gp, tStep);
491 } else {
492 FloatMatrix fullAnswer, answer;
493 const_cast<PerfectlyPlasticMaterial*>(this)->giveMaterialStiffnessMatrix(fullAnswer, mode, gp, tStep);
494 StructuralMaterial :: giveReducedSymMatrixForm( answer, fullAnswer, gp->giveMaterialMode() );
495 return answer;
496 }
497}
498
499
500void
501PerfectlyPlasticMaterial :: computeTrialStressIncrement(FloatArray &answer, GaussPoint *gp,
502 const FloatArray &strainIncrement,
503 TimeStep *tStep) const
504//
505// computest the elastic stress increment
506// from stressIncrement in full stress strain space
507//
508{
509 FloatMatrix materialMatrix;
510
511 if ( strainIncrement.giveSize() == 0 ) {
512 answer.clear();
513 return;
514 }
515
516 this->giveEffectiveMaterialStiffnessMatrix(materialMatrix, TangentStiffness, gp, tStep);
517 answer.beProductOf(materialMatrix, strainIncrement);
518}
519
520
521void
522PerfectlyPlasticMaterial :: computePlasticStiffnessAt(FloatMatrix &answer,
523 GaussPoint *gp,
524 FloatArray *currentStressVector,
525 FloatArray *currentPlasticStrainVector,
526 FloatArray *strainIncrement3d,
527 TimeStep *tStep,
528 double &lambda) const
529//
530// Computes full form of Plastic stiffness Matrix at given state.
531// gp is used only and only for setting proper MaterialMode ()
532// returns proportionality factor lambda also if strainIncrement3d != NULL
533{
534 StructuralCrossSection *crossSection = static_cast< StructuralCrossSection * >
535 ( gp->giveElement()->giveCrossSection() );
536 FloatMatrix de, *yeldStressGradMat, *loadingStressGradMat;
537 FloatMatrix fsde, gsfsde;
538 FloatArray *yeldStressGrad, *loadingStressGrad;
539 FloatArray help;
540 double denominator, nominator;
541 //
542 // force de to be elastic even if gp in plastic state
543 // to do this, a flag in this class exist -> ForceElasticResponce
544 // if this flag is set to nonzero, function this::Give3dMaterialStiffnessMatrix
545 // will be forced to return only elasticPart of 3dMaterialStiffnessMatrix
546 // This function also set the ForceElasticFlagResponce to zero.
547 //
548 this->giveEffectiveMaterialStiffnessMatrix(de, TangentStiffness, gp, tStep);
549
550 yeldStressGrad = this->GiveYCStressGradient(gp, currentStressVector,
551 currentPlasticStrainVector);
552 crossSection->imposeStressConstrainsOnGradient(gp, yeldStressGrad);
553 yeldStressGradMat = new FloatMatrix(FloatMatrix::fromArray(*yeldStressGrad, 1)); // transpose
554
555 loadingStressGrad = this->GiveLCStressGradient(gp, currentStressVector,
556 currentPlasticStrainVector);
557
558 crossSection->imposeStrainConstrainsOnGradient(gp, loadingStressGrad);
559 loadingStressGradMat = new FloatMatrix(FloatMatrix::fromArray(*yeldStressGrad));
560
561 help.beProductOf(de, * loadingStressGrad);
562 delete loadingStressGrad;
563
564 fsde.beProductOf(* yeldStressGradMat, de);
565 delete yeldStressGradMat;
566 gsfsde.beProductOf(* loadingStressGradMat, fsde);
567 delete loadingStressGradMat;
568
569 denominator = 0.;
570 for ( int i = 1; i <= 6; i++ ) {
571 denominator += yeldStressGrad->at(i) * help.at(i);
572 }
573
574 answer.beProductOf(de, gsfsde);
575
576 answer.times( -( 1. / denominator ) );
577
578 if ( strainIncrement3d != NULL ) { // compute proportional factor lambda
579 nominator = 0.;
580 help.beProductOf(de, * strainIncrement3d);
581 for ( int i = 1; i <= 6; i++ ) {
582 nominator += yeldStressGrad->at(i) * help.at(i);
583 }
584
585 lambda = nominator / denominator;
586 }
587
588 delete yeldStressGrad;
589}
590
591
593PerfectlyPlasticMaterial :: GiveStressCorrectionBackToYieldSurface(GaussPoint *gp,
594 FloatArray *stressVector3d,
595 FloatArray *plasticVector3d) const
596//
597// returns the stress correction -> correction is in the direction of
598// the normal to the yield surface
599// in full stress strain space
600{
601 FloatArray *yeldStressGrad, *stressCorrection;
602 StructuralCrossSection *crossSection = static_cast< StructuralCrossSection * >
603 ( gp->giveElement()->giveCrossSection() );
604 double f3, help;
605
606 yeldStressGrad = this->GiveYCStressGradient(gp,
607 stressVector3d,
608 plasticVector3d);
609 crossSection->imposeStressConstrainsOnGradient(gp, yeldStressGrad);
610
611 f3 = this->computeYCValueAt(gp, stressVector3d, plasticVector3d);
612
613 help = 0.;
614 for ( int j = 1; j <= 6; j++ ) {
615 help += yeldStressGrad->at(j) * yeldStressGrad->at(j);
616 }
617
618 stressCorrection = new FloatArray(*yeldStressGrad);
619 stressCorrection->times(-f3 / help);
620
621
622 delete yeldStressGrad;
623 return stressCorrection;
624}
625
626
627void
628PerfectlyPlasticMaterial :: initializeFrom(InputRecord &ir)
629{
630 Material :: initializeFrom(ir);
631 this->giveLinearElasticMaterial()->initializeFrom(ir);
632}
633
634
635double
636PerfectlyPlasticMaterial :: give(int aProperty, GaussPoint *gp) const
637// Returns the value of the property aProperty (e.g. the Young's modulus
638// 'E') of the receiver.
639{
640 double value = 0.0;
641
642 if ( propertyDictionary.includes(aProperty) ) {
643 value = propertyDictionary.at(aProperty);
644 } else {
645 if ( linearElasticMaterial ) {
646 value = this->linearElasticMaterial->give(aProperty, gp);
647 } else {
648 OOFEM_ERROR("property not defined");
649 }
650 }
651
652 return value;
653}
654
655
656std::unique_ptr<MaterialStatus>
657PerfectlyPlasticMaterial :: CreateStatus(GaussPoint *gp) const
658/*
659 * creates new material status corresponding to this class
660 */
661{
662 return std::make_unique<PerfectlyPlasticMaterialStatus>(gp);
663}
664
665
666int
667PerfectlyPlasticMaterial :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
668{
669 PerfectlyPlasticMaterialStatus *status = static_cast< PerfectlyPlasticMaterialStatus * >( this->giveStatus(gp) );
670 if ( type == IST_PlasticStrainTensor ) {
671 const FloatArray &ep = status->givePlasticStrainVector();
673 StructuralMaterial :: giveFullSymVectorForm( answer, ep, gp->giveMaterialMode() );
674 return 1;
675 } else if ( type == IST_PrincipalPlasticStrainTensor ) {
676 FloatArray st;
677
678 const FloatArray &s = status->givePlasticStrainVector();
680 StructuralMaterial :: giveFullSymVectorForm( st, s, gp->giveMaterialMode() );
681
682 this->computePrincipalValues(answer, st, principal_strain);
683 return 1;
684 } else {
685 return StructuralMaterial :: giveIPValue(answer, gp, type, tStep);
686 }
687}
688
689
690//##################################################################################################
691
692
693PerfectlyPlasticMaterialStatus :: PerfectlyPlasticMaterialStatus(GaussPoint *g) :
695{
696 temp_yield_flag = yield_flag = 0; // elastic case at beginning
697}
698
699
700void
701PerfectlyPlasticMaterialStatus :: saveContext(DataStream &stream, ContextMode mode)
702{
703 StructuralMaterialStatus :: saveContext(stream, mode);
704
705 if ( !stream.write(yield_flag) ) {
707 }
708
710 if ( ( iores = plasticStrainVector.storeYourself(stream) ) != CIO_OK ) {
711 THROW_CIOERR(iores);
712 }
713}
714
715
716void
717PerfectlyPlasticMaterialStatus :: restoreContext(DataStream &stream, ContextMode mode)
718{
719 StructuralMaterialStatus :: restoreContext(stream, mode);
720
721 if ( !stream.read(yield_flag) ) {
723 }
724
726 if ( ( iores = plasticStrainVector.restoreYourself(stream) ) != CIO_OK ) {
727 THROW_CIOERR(iores);
728 }
729}
730
731
732void
733PerfectlyPlasticMaterialStatus :: printOutputAt(FILE *file, TimeStep *tStep) const
734{
735 StructuralMaterialStatus :: printOutputAt(file, tStep);
736 fprintf(file, "status { yield_flag %d}\n", yield_flag);
737}
738
739
740void
741PerfectlyPlasticMaterialStatus :: initTempStatus()
742//
743// initialize record at the begining of new load step
744//
745{
746 StructuralMaterialStatus :: initTempStatus();
747
748 if ( plasticStrainVector.giveSize() == 0 ) {
749 plasticStrainVector.resize( StructuralMaterial :: giveSizeOfVoigtSymVector( gp->giveMaterialMode() ) );
750 plasticStrainVector.zero();
751 }
752
753 if ( plasticStrainIncrementVector.giveSize() == 0 ) {
754 plasticStrainIncrementVector.resize( StructuralMaterial :: giveSizeOfVoigtSymVector( gp->giveMaterialMode() ) );
756 } else {
758 }
759
761}
762
763
764void
765PerfectlyPlasticMaterialStatus :: updateYourself(TimeStep *tStep)
766{
767 StructuralMaterialStatus :: updateYourself(tStep);
768
771
773}
774} // 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.
double & at(Index i)
Definition floatarray.h:202
void beDifferenceOf(const FloatArray &a, const FloatArray &b)
Definition floatarray.C:403
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:689
void add(const FloatArray &src)
Definition floatarray.C:218
void times(double s)
Definition floatarray.C:834
static FloatMatrix fromArray(const FloatArray &vector, bool transpose=false)
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
MaterialMode giveMaterialMode()
Returns corresponding material mode of receiver.
Definition gausspoint.h:190
GaussPoint * gp
Associated integration point.
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Definition material.C:206
Dictionary propertyDictionary
Definition material.h:107
virtual void initTempStatus(GaussPoint *gp) const
Definition material.C:221
const FloatArray & givePlasticStrainVector() const
virtual void updateTempYC(GaussPoint *gp, FloatArray *, FloatArray *) const
virtual void updateIfFailure(GaussPoint *gp, FloatArray *stressVector3d, FloatArray *PlasticStrainVector3d) const
FloatArray * GiveStressCorrectionBackToYieldSurface(GaussPoint *gp, FloatArray *stressVector3d, FloatArray *plasticVector3d) const
void computePlasticStiffnessAt(FloatMatrix &answer, GaussPoint *gp, FloatArray *currentStressVector, FloatArray *currentPlasticStrainVector, FloatArray *strainIncrement3d, TimeStep *tStep, double &lambda) const
LinearElasticMaterial * linearElasticMaterial
virtual void updateTempLC(GaussPoint *gp, FloatArray *, FloatArray *) const
virtual FloatArray * GiveYCStressGradient(GaussPoint *gp, FloatArray *, FloatArray *) const
virtual void giveEffectiveMaterialStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const
virtual FloatArray * GiveLCStressGradient(GaussPoint *gp, FloatArray *, FloatArray *) const
virtual double computeYCValueAt(GaussPoint *gp, FloatArray *, FloatArray *) const
virtual void giveMaterialStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const
LinearElasticMaterial * giveLinearElasticMaterial() const
void computeTrialStressIncrement(FloatArray &answer, GaussPoint *gp, const FloatArray &strainIncrement, TimeStep *tStep) const
virtual FloatArray * imposeStressConstrainsOnGradient(GaussPoint *gp, FloatArray *gradientStressVector3d)
virtual FloatArray * imposeStrainConstrainsOnGradient(GaussPoint *gp, FloatArray *gradientStressVector3d)
const FloatArray & giveStrainVector() const
Returns the const pointer to receiver's strain 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 giveFullSymMatrixForm(FloatMatrix &answer, const FloatMatrix &red, MaterialMode matMode)
Converts the full unsymmetric Voigt matrix (4th order tensor) to reduced form.
bool hasMaterialModeCapability(MaterialMode mode) const override
static void computePrincipalValues(FloatArray &answer, const FloatArray &s, stressStrainPrincMode mode)
Common functions for convenience.
StructuralMaterial(int n, Domain *d)
virtual void giveStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const
void giveStressDependentPartOfStrainVector(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedStrainVector, TimeStep *tStep, ValueModeType mode) const
#define THROW_CIOERR(e)
#define OOFEM_ERROR(...)
Definition error.h:79
#define STRAIN_STEPS
Definition material.h:58
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