OOFEM 3.0
Loading...
Searching...
No Matches
mplasticmaterial2.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 "mplasticmaterial2.h"
36#include "gausspoint.h"
37#include "floatmatrix.h"
38#include "floatarray.h"
39#include "intarray.h"
40#include "mathfem.h"
41#include "datastream.h"
42#include "contextioerr.h"
43
44namespace oofem {
45#define YIELD_TOL 1.e-6
46#define YIELD_TOL_SECONDARY 1.e-4
47#define RES_TOL 1.e-8
48#define PLASTIC_MATERIAL_MAX_ITERATIONS 120
49
50MPlasticMaterial2 :: MPlasticMaterial2(int n, Domain *d) : StructuralMaterial(n, d)
51 //
52 // constructor
53 //
54{
58 iterativeUpdateOfActiveConds = false; // safe
59}
60
61
62
63MPlasticMaterial2 :: ~MPlasticMaterial2()
64//
65// destructor
66//
67{
69}
70
71
72bool
73MPlasticMaterial2 :: hasMaterialModeCapability(MaterialMode mode) const
74//
75// returns whether receiver supports given mode
76//
77{
78 return mode == _3dMat ||
79 mode == _1dMat ||
80 //<RESTRICTED_SECTION>
81 mode == _PlaneStress ||
82 //</RESTRICTED_SECTION>
83 mode == _PlaneStrain;
84}
85
86
87std::unique_ptr<MaterialStatus>
88MPlasticMaterial2 :: CreateStatus(GaussPoint *gp) const
89{
90 return std::make_unique<MPlasticMaterial2Status>(gp, this->giveSizeOfReducedHardeningVarsVector(gp));
91}
92
93
94void
95MPlasticMaterial2 :: giveRealStressVector(FloatArray &answer,
96 GaussPoint *gp,
97 const FloatArray &totalStrain,
98 TimeStep *tStep) const
99//
100// returns real stress vector in 3d stress space of receiver according to
101// previous level of stress and current
102// strain increment, the only way, how to correctly update gp records
103//
104// completely formulated in Reduced stress-strain space
105{
106 FloatArray strainSpaceHardeningVariables;
107 FloatArray fullStressVector;
108 FloatArray strainVectorR, plasticStrainVectorR;
109 FloatArray helpVec;
110 IntArray activeConditionMap(this->nsurf);
111 FloatArray gamma;
112
113 MPlasticMaterial2Status *status = static_cast< MPlasticMaterial2Status * >( this->giveStatus(gp) );
114
115 this->initTempStatus(gp);
116
117 // subtract stress independent part
118 // note: eigenStrains (temperature) is not contained in mechanical strain stored in gp
119 // therefore it is necessary to subtract always the total eigen strain value
120 this->giveStressDependentPartOfStrainVector(strainVectorR, gp, totalStrain,
121 tStep, VM_Total);
122
123 /*
124 * stress return algorithm
125 */
126
127 if ( rmType == mpm_ClosestPoint ) {
128 this->closestPointReturn(fullStressVector, activeConditionMap, gamma, gp, strainVectorR,
129 plasticStrainVectorR, strainSpaceHardeningVariables, tStep);
130 } else {
131 this->cuttingPlaneReturn(fullStressVector, activeConditionMap, gamma, gp, strainVectorR,
132 plasticStrainVectorR, strainSpaceHardeningVariables, tStep);
133 }
134
135 status->letTempStrainVectorBe(totalStrain);
136 StructuralMaterial :: giveReducedSymVectorForm( helpVec, fullStressVector, gp->giveMaterialMode() );
137
138 //perform isotropic damage on effective stress
139 double omega = computeDamage(gp, strainSpaceHardeningVariables, tStep);
140 status->letTempDamageBe(omega);
141 helpVec.times(1. - omega);
142 //end of damage part
143
144 status->letTempStressVectorBe(helpVec);
145
146 status->letTempPlasticStrainVectorBe(plasticStrainVectorR);
147 status->letTempStrainSpaceHardeningVarsVectorBe(strainSpaceHardeningVariables);
148
149 status->setTempGamma(gamma);
150 status->setTempActiveConditionMap(activeConditionMap);
151
152
153 // update state flag
154 MPlasticMaterial2Status :: state_flag_values newState, state = status->giveStateFlag();
155 bool yieldFlag = false;
156 for ( int i = 1; i <= nsurf; i++ ) {
157 if ( gamma.at(i) > 0. ) {
158 yieldFlag = true;
159 }
160 }
161
162 if ( yieldFlag ) {
163 newState = MPlasticMaterial2Status :: PM_Yielding; // test if plastic loading occur
164 }
165 // no plastic loading - check for unloading
166 else if ( ( state == MPlasticMaterial2Status :: PM_Yielding ) || ( state == MPlasticMaterial2Status :: PM_Unloading ) ) {
167 newState = MPlasticMaterial2Status :: PM_Unloading;
168 } else {
169 newState = MPlasticMaterial2Status :: PM_Elastic;
170 }
171
172 status->letTempStateFlagBe(newState);
173
174 StructuralMaterial :: giveReducedSymVectorForm( answer, fullStressVector, gp->giveMaterialMode() );
175}
176
177double
178MPlasticMaterial2 :: computeDamage(GaussPoint *gp, const FloatArray &strainSpaceHardeningVariables, TimeStep *tStep) const {
179 return 0.;
180}
181
182
183void
184MPlasticMaterial2 :: closestPointReturn(FloatArray &answer,
185 IntArray &activeConditionMap,
186 FloatArray &gamma,
187 GaussPoint *gp,
188 const FloatArray &totalStrain,
189 FloatArray &plasticStrainVectorR,
190 FloatArray &strainSpaceHardeningVariables,
191 TimeStep *tStep) const
192{
193 FloatArray fullStressVector;
194 FloatArray elasticStrainVectorR;
195 FloatArray residualVectorR;
196 FloatArray helpVector, helpVector2;
197 FloatArray dgamma, dgammared, tempGamma, dkappa;
198 FloatMatrix elasticModuli, consistentModuli;
199 FloatMatrix elasticModuliInverse;
200 FloatMatrix helpMtrx, helpMtrx2;
201 FloatMatrix ks, kl, lmat, rmat, gradientMatrix;
202 FloatMatrix gmat;
203 IntArray initialConditionMap;
204 std :: vector< FloatArray > yieldGradSigVec(this->nsurf), loadGradSigVec(this->nsurf), * loadGradSigVecPtr;
205 std :: vector< FloatArray > yieldGradKVec(this->nsurf), loadGradKVec(this->nsurf);
206 FloatArray rhs;
207 double yieldValue;
208 int nIterations = 0;
209 int strSize;
210 int elastic, restart, actSurf, indx;
211 bool yieldConsistency, init = true;
212 bool hasHardening = this->hasHardening() > 0;
213#ifdef DEBUG
214 bool debug = false;
215#endif
216
217 this->clearPopulationSet();
218
219 if ( this->plType == associatedPT ) {
220 loadGradSigVecPtr = & yieldGradSigVec;
221 } else {
222 loadGradSigVecPtr = & loadGradSigVec;
223 }
224
225 MPlasticMaterial2Status *status = static_cast< MPlasticMaterial2Status * >( this->giveStatus(gp) );
226
227huhu: //label for goto
228
229 plasticStrainVectorR = status->givePlasticStrainVector();
230 strainSpaceHardeningVariables = status->giveStrainSpaceHardeningVars();
231
232 dgamma.resize(nsurf);
233 dgamma.zero();
234 gamma.resize(nsurf);
235 gamma.zero();
236
237 strSize = totalStrain.giveSize(); // size of reducedStrain Vector
238
239 // compute elastic moduli and its inverse
240 this->computeReducedElasticModuli(elasticModuli, gp, tStep);
241 elasticModuliInverse.beInverseOf(elasticModuli);
242
243 //
244 // Elastic Predictor
245 //
246
247 elasticStrainVectorR = totalStrain;
248 elasticStrainVectorR.subtract(plasticStrainVectorR);
249 // stress vector in full form due to computational convinience
250 //if (fullStressVector) delete fullStressVector;
251 this->computeTrialStressIncrement(fullStressVector, gp, elasticStrainVectorR, tStep);
252 //
253 // check for plastic process
254 //
255 elastic = 1;
256 actSurf = 0;
257 activeConditionMap.zero();
258 if ( init ) {
259 initialConditionMap.resize(nsurf);
260 initialConditionMap.zero();
261 }
262
263 for ( int i = 1; i <= this->nsurf; i++ ) {
264 yieldValue = this->computeYieldValueAt(gp, i, fullStressVector, strainSpaceHardeningVariables);
265 if ( yieldValue > YIELD_TOL ) {
266 elastic = 0;
267 if ( init ) {
268 initialConditionMap.at(i) = 1;
269 }
270
271 if ( actSurf < this->giveMaxNumberOfActiveYieldConds(gp) ) {
272 actSurf += 1;
273 activeConditionMap.at(i) = actSurf;
274 }
275 }
276 }
277
278 init = false;
279
280 if ( !elastic ) {
281 /*
282 * plastic multisurface closest-point corrector
283 */
284 this->addNewPopulation(activeConditionMap);
285
286#ifdef DEBUG
287 if ( debug ) {
288 printf("New activeConditionMap:");
289 activeConditionMap.printYourself();
290 printf("\n");
291 }
292
293#endif
294
295 do {
296 do { // restart loop
297 // compute gradients
298 for ( int i = 1; i <= nsurf; i++ ) {
299 this->computeReducedStressGradientVector(yieldGradSigVec [ i - 1 ], yieldFunction, i, gp, fullStressVector,
300 strainSpaceHardeningVariables);
301 if ( hasHardening ) {
302 this->computeKGradientVector(yieldGradKVec [ i - 1 ], yieldFunction, i, gp, fullStressVector,
303 strainSpaceHardeningVariables);
304 }
305 }
306
307 if ( this->plType == nonassociatedPT ) {
308 for ( int i = 1; i <= nsurf; i++ ) {
309 this->computeReducedStressGradientVector(loadGradSigVec [ i - 1 ], loadFunction, i, gp, fullStressVector,
310 strainSpaceHardeningVariables);
311 if ( hasHardening ) {
312 this->computeKGradientVector(loadGradKVec [ i - 1 ], loadFunction, i, gp, fullStressVector,
313 strainSpaceHardeningVariables);
314 }
315 }
316 }
317
318
319 //this->computeGradientVector (gradientVectorR, gp, &fullStressVector, fullStressSpaceHardeningVars);
320 this->computeResidualVector(residualVectorR, gp, gamma, activeConditionMap, plasticStrainVectorR,
321 strainSpaceHardeningVariables, * loadGradSigVecPtr);
322#ifdef DEBUG
323 if ( debug ) {
324 printf("Convergence[actSet: ");
325 for ( int i = 1; i <= nsurf; i++ ) {
326 printf( "%d ", activeConditionMap.at(i) );
327 }
328
329 printf("] yield_val (gamma) ");
330 }
331
332#endif
333
334 // check convergence
335 yieldConsistency = true;
336 for ( int i = 1; i <= nsurf; i++ ) {
337 if ( activeConditionMap.at(i) ) {
338 yieldValue = this->computeYieldValueAt(gp, i, fullStressVector, strainSpaceHardeningVariables);
339 if ( fabs(yieldValue) >= YIELD_TOL ) {
340 yieldConsistency = false;
341 }
342
343#ifdef DEBUG
344 if ( debug ) {
345 printf( "%e(%e) ", yieldValue, gamma.at(i) );
346 }
347
348#endif
349 }
350 }
351
352#ifdef DEBUG
353 if ( debug ) {
354 printf("\n");
355 }
356
357#endif
358
359 //if (yieldConsistency && (sqrt(dotProduct(residualVectorR, residualVectorR, residualVectorR.giveSize())) < RES_TOL)) {
360 if ( yieldConsistency ) {
361 answer = fullStressVector;
362 //printf (" (%d iterations)", nIterations);
363
364
365 restart = 0;
366 // check for active conditions
367#ifdef DEBUG
368 if ( debug ) {
369 printf("Consistency: ");
370 }
371
372#endif
373 for ( int i = 1; i <= this->nsurf; i++ ) {
374 yieldValue = this->computeYieldValueAt(gp, i, fullStressVector, strainSpaceHardeningVariables);
375
376#ifdef DEBUG
377 if ( debug ) {
378 printf("%e ", yieldValue);
379 }
380
381#endif
382
383 if ( ( gamma.at(i) < 0.0 ) || ( ( activeConditionMap.at(i) == 0 ) && ( yieldValue > YIELD_TOL_SECONDARY ) ) ) {
384 restart = 1;
385 //printf ("*");
386 }
387 }
388
389#ifdef DEBUG
390 if ( debug ) {
391 printf("\nStress: ");
392 for ( int i = 1; i <= fullStressVector.giveSize(); i++ ) {
393 printf( " %e", fullStressVector.at(i) );
394 }
395
396 printf("\nKappa : ");
397 for ( int i = 1; i <= strainSpaceHardeningVariables.giveSize(); i++ ) {
398 printf( " %e", strainSpaceHardeningVariables.at(i) );
399 }
400
401 printf("\n Restart %d\n", restart);
402 }
403
404#endif
405
406 if ( restart ) {
407 IntArray newmap(nsurf);
408 actSurf = 0;
409 newmap.zero();
410 // buid new actsurf mask
411 for ( int i = 1; i <= this->nsurf; i++ ) {
412 yieldValue = this->computeYieldValueAt(gp, i, fullStressVector, strainSpaceHardeningVariables);
413 if ( ( ( activeConditionMap.at(i) ) && ( gamma.at(i) >= 0.0 ) ) || ( yieldValue > YIELD_TOL ) ) {
414 elastic = 0;
415 actSurf += 1;
416 newmap.at(i) = actSurf;
417 // if (actSurf == this->giveMaxNumberOfActiveYieldConds(gp)) break;
418 }
419 }
420
421 if ( this->getNewPopulation(activeConditionMap, newmap, this->giveMaxNumberOfActiveYieldConds(gp), nsurf) == 0 ) {
422#ifdef DEBUG
423 if ( !debug ) {
424 this->clearPopulationSet();
425 debug = true;
426 goto huhu;
427 } else {
428 printf("ep:");
429 plasticStrainVectorR = status->givePlasticStrainVector();
430 plasticStrainVectorR.printYourself();
431 printf("kp:");
432 strainSpaceHardeningVariables = status->giveStrainSpaceHardeningVars();
433 strainSpaceHardeningVariables.printYourself();
434 elasticStrainVectorR = totalStrain;
435 elasticStrainVectorR.subtract(plasticStrainVectorR);
436 printf("sg:");
437 this->computeTrialStressIncrement(fullStressVector, gp, elasticStrainVectorR, tStep);
438 fullStressVector.printYourself();
439
440 OOFEM_ERROR("Internal Consistency error: all combinations of yield functions tried, no consistent return");
441 }
442
443#else
444 OOFEM_ERROR("Internal Consistency error: all combinations of yield functions tried, no consistent return");
445#endif
446 }
447
448 actSurf = 0;
449 for ( int i = 1; i <= nsurf; i++ ) {
450 if ( activeConditionMap.at(i) ) {
451 actSurf++;
452 }
453 }
454
455 /*
456 * if (actSurf) {
457 * activeConditionMap=newmap;
458 * } else {
459 * restart = 0;
460 * // select any possible
461 * for (i=1; i<=this->nsurf; i++) {
462 * if (initialConditionMap.at(i)) {
463 * actSurf = 1;
464 * activeConditionMap.zero();
465 * activeConditionMap.at(i) = 1;
466 * initialConditionMap.at(i) = 0;
467 * restart = 1;
468 * break;
469 * }
470 * }
471 *
472 * if (!restart) {
473 * OOFEM_ERROR("Internal Consistency error");
474 * }
475 * }
476 */
477 plasticStrainVectorR = status->givePlasticStrainVector();
478 strainSpaceHardeningVariables = status->giveStrainSpaceHardeningVars();
479 elasticStrainVectorR = totalStrain;
480 elasticStrainVectorR.subtract(plasticStrainVectorR);
481 this->computeTrialStressIncrement(fullStressVector, gp, elasticStrainVectorR, tStep);
482 gamma.zero();
483 nIterations = 0;
484 int restart = 0;
485 if ( restart ) {
486 goto huhu;
487 }
488
489 continue;
490 }
491
492 if ( yieldConsistency && ( residualVectorR.computeNorm() < RES_TOL ) ) {
493 return;
494 }
495 }
496
497 // compute consistent tangent moduli
498 this->computeAlgorithmicModuli(consistentModuli, gp, elasticModuliInverse,
499 gamma, activeConditionMap,
500 fullStressVector, strainSpaceHardeningVariables);
501
502
504
505
506 rhs.resize(actSurf);
507 rhs.zero();
508 gmat.resize(actSurf, actSurf);
509 gmat.zero();
510 lmat.resize(actSurf, strSize);
511 lmat.zero();
512 rmat.resize(strSize, actSurf);
513 rmat.zero();
514 if ( hasHardening ) {
515 this->computeReducedHardeningVarsSigmaGradient(ks, gp, activeConditionMap, fullStressVector,
516 strainSpaceHardeningVariables, gamma);
517 this->computeReducedHardeningVarsLamGradient(kl, gp, actSurf, activeConditionMap,
518 fullStressVector, strainSpaceHardeningVariables, gamma);
519 }
520
521 for ( int i = 1; i <= nsurf; i++ ) {
522 if ( ( indx = activeConditionMap.at(i) ) ) {
523 if ( hasHardening ) {
524 helpVector.beTProductOf(ks, yieldGradKVec [ i - 1 ]);
525 helpVector.add(yieldGradSigVec [ i - 1 ]);
526 for ( int j = 1; j <= strSize; j++ ) {
527 lmat.at(indx, j) = helpVector.at(j);
528 }
529 } else {
530 for ( int j = 1; j <= strSize; j++ ) {
531 lmat.at(indx, j) = yieldGradSigVec [ i - 1 ].at(j);
532 }
533 }
534
535 if ( hasHardening ) {
536 this->computeReducedSKGradientMatrix(gradientMatrix, i, gp, fullStressVector,
537 strainSpaceHardeningVariables);
538 helpMtrx.beProductOf(gradientMatrix, kl);
539 helpMtrx.times( gamma.at(i) );
540 rmat.add(helpMtrx);
541 }
542
543 for ( int j = 1; j <= strSize; j++ ) {
544 rmat.at(j, indx) += ( * loadGradSigVecPtr ) [ i - 1 ].at(j);
545 }
546
547 if ( hasHardening ) {
548 helpVector2.beTProductOf(kl, yieldGradKVec [ i - 1 ]);
549 for ( int j = 1; j <= actSurf; j++ ) {
550 gmat.at(indx, j) = ( -1.0 ) * helpVector2.at(j);
551 }
552 }
553
554 yieldValue = this->computeYieldValueAt(gp, i, fullStressVector, strainSpaceHardeningVariables);
555 rhs.at(indx) = yieldValue;
556 //helpVector2.beTProductOf (consistentModuli, helpVector);
557 //rhs.at(indx)=yieldValue-dotProduct(helpVector2, residualVectorR, residualVectorR.giveSize());
558 }
559 }
560
561 helpMtrx.beProductOf(lmat, consistentModuli);
562 helpMtrx2.beProductOf(helpMtrx, rmat);
563 gmat.add(helpMtrx2);
564 helpVector2.beProductOf(consistentModuli, residualVectorR);
565 helpVector.beProductOf(lmat, helpVector2);
566 rhs.subtract(helpVector);
567
568
569 // obtain increment to consistency parameter
570 gmat.solveForRhs(rhs, dgammared);
571
572 // assign gammas
573 for ( int i = 1; i <= this->nsurf; i++ ) {
574 if ( ( indx = activeConditionMap.at(i) ) ) {
575 dgamma.at(i) = dgammared.at(indx);
576 } else {
577 dgamma.at(i) = 0.0;
578 }
579 }
580
581 tempGamma = gamma;
582 tempGamma.add(dgamma);
583
584
586 //
587 // check active constraint
588 //
589
590 restart = 0;
591 for ( int i = 1; i <= this->nsurf; i++ ) {
592 if ( tempGamma.at(i) < 0.0 ) {
593 restart = 1;
594 }
595 }
596
597 if ( restart ) {
598 // build up new activeConditionMap and restart the iterartion from begining
599 actSurf = 0;
600 activeConditionMap.zero();
601 for ( int i = 1; i <= this->nsurf; i++ ) {
602 if ( tempGamma.at(i) > 0.0 ) {
603 actSurf += 1;
604 activeConditionMap.at(i) = actSurf;
605 }
606 }
607
608 plasticStrainVectorR = status->givePlasticStrainVector();
609 strainSpaceHardeningVariables = status->giveStrainSpaceHardeningVars();
610 elasticStrainVectorR = totalStrain;
611 elasticStrainVectorR.subtract(plasticStrainVectorR);
612 this->computeTrialStressIncrement(fullStressVector, gp, elasticStrainVectorR, tStep);
613 gamma.zero();
614 nIterations = 0;
615 continue;
616 } else {
617 break;
618 }
619 } else {
620 break;
621 }
622 } while ( 1 ); // end restart loop
623
624 // obtain incremental plastic strains and internal variables
625 // residualVectorR vector and gradVec array are changed
626 // but they are computed once again when new iteration starts
627
628 helpVector2.resize(strSize);
629 // Update state variables and consistency parameter
630 for ( int i = 1; i <= nsurf; i++ ) {
631 if ( activeConditionMap.at(i) ) {
632 ( * loadGradSigVecPtr ) [ i - 1 ].times( dgamma.at(i) );
633 residualVectorR.add( ( * loadGradSigVecPtr ) [ i - 1 ] );
634
635 if ( hasHardening ) {
636 this->computeReducedSKGradientMatrix(gradientMatrix, i, gp, fullStressVector,
637 strainSpaceHardeningVariables);
638 this->computeReducedHardeningVarsLamGradient(kl, gp, actSurf, activeConditionMap,
639 fullStressVector, strainSpaceHardeningVariables, gamma);
640 helpMtrx.beProductOf(gradientMatrix, kl);
641 helpMtrx.times( gamma.at(i) );
642 helpVector2.beProductOf(helpMtrx, dgammared);
643
644 residualVectorR.add(helpVector2);
645 }
646 }
647 }
648
649 helpVector.beProductOf(consistentModuli, residualVectorR);
650 helpVector2.beProductOf(elasticModuliInverse, helpVector);
651
652 gamma.add(dgamma);
653 for ( int i = 1; i <= strSize; i++ ) {
654 plasticStrainVectorR.at(i) += helpVector2.at(i);
655 }
656
657 elasticStrainVectorR = totalStrain;
658 elasticStrainVectorR.subtract(plasticStrainVectorR);
659 // stress vector in full form due to computational convinience
660 this->computeTrialStressIncrement(fullStressVector, gp, elasticStrainVectorR, tStep);
661
662 if ( hasHardening ) {
663 this->computeStrainHardeningVarsIncrement(dkappa, gp, fullStressVector, gamma, helpVector2, activeConditionMap);
664 strainSpaceHardeningVariables = status->giveStrainSpaceHardeningVars();
665 strainSpaceHardeningVariables.add(dkappa);
666 }
667
668 //this->computeStrainHardeningVarsIncrement(dkappa, fullStressVector, dgamma);
669 //strainSpaceHardeningVariables.add(dkappa);
670 //this-> computeTrialStressIncrement (fullStressVector, gp, elasticStrainVectorR, tStep);
671
672 // increment iteration count
673 nIterations++;
674
675 if ( nIterations > PLASTIC_MATERIAL_MAX_ITERATIONS ) {
676#ifdef DEBUG
677 // issue warning
678 fprintf( stderr, "\nclosestPointReturn (mat no. %d): reached max number of iterations\n", this->giveNumber() );
679 fprintf(stderr, "activeSet: ");
680 for ( int i = 1; i <= nsurf; i++ ) {
681 fprintf( stderr, "%d ", activeConditionMap.at(i) );
682 }
683
684 fprintf(stderr, "\n");
685 if ( !debug ) {
686 debug = true;
687 this->clearPopulationSet();
688 goto huhu;
689 }
690
691#endif
692
693
694 // try last resort select single function from initial active set
695 restart = 0;
696 bool smartCandidate = false;
697 int candidate = 0;
698 IntArray newmap(nsurf);
699 actSurf = 0;
700 newmap.zero();
701 // check for active conditions
702 for ( int i = 1; i <= this->nsurf; i++ ) {
703 if ( activeConditionMap.at(i) ) {
704 if ( gamma.at(i) < 0.0 ) {
705 smartCandidate = true;
706 } else {
707 candidate = i;
708 }
709 }
710 }
711
712 if ( smartCandidate && candidate && initialConditionMap.at(candidate) ) {
713 actSurf = 1;
714 IntArray newMap(nsurf);
715 newMap.at(candidate) = 1;
716
717 //initialConditionMap.at(candidate) = 0;
718 if ( this->getNewPopulation(activeConditionMap, newmap, this->giveMaxNumberOfActiveYieldConds(gp), nsurf) == 0 ) {
719#ifdef DEBUG
720 if ( !debug ) {
721 this->clearPopulationSet();
722 debug = true;
723 goto huhu;
724 } else {
725 printf("ep:");
726 plasticStrainVectorR = status->givePlasticStrainVector();
727 plasticStrainVectorR.printYourself();
728 printf("kp:");
729 strainSpaceHardeningVariables = status->giveStrainSpaceHardeningVars();
730 strainSpaceHardeningVariables.printYourself();
731 elasticStrainVectorR = totalStrain;
732 elasticStrainVectorR.subtract(plasticStrainVectorR);
733 printf("sg:");
734 this->computeTrialStressIncrement(fullStressVector, gp, elasticStrainVectorR, tStep);
735 fullStressVector.printYourself();
736
737 OOFEM_ERROR("Internal Consistency error: all combinations of yield functions tried, no consistent return");
738 }
739
740#else
741 OOFEM_ERROR("Internal Consistency error: all combinations of yield functions tried, no consistent return");
742#endif
743 }
744
745 actSurf = 0;
746 for ( int i = 1; i <= nsurf; i++ ) {
747 if ( activeConditionMap.at(i) ) {
748 actSurf++;
749 }
750 }
751
752 restart = 1;
753 } else {
754 IntArray newMap(nsurf);
755 // select any possible
756 for ( int i = 1; i <= this->nsurf; i++ ) {
757 if ( initialConditionMap.at(i) ) {
758 actSurf = 1;
759 newMap.at(i) = 1;
760 //initialConditionMap.at(i) = 0;
761 if ( this->getNewPopulation(activeConditionMap, newmap, this->giveMaxNumberOfActiveYieldConds(gp), nsurf) == 0 ) {
762#ifdef DEBUG
763 if ( !debug ) {
764 this->clearPopulationSet();
765 debug = true;
766 goto huhu;
767 } else {
768 printf("ep:");
769 plasticStrainVectorR = status->givePlasticStrainVector();
770 plasticStrainVectorR.printYourself();
771 printf("kp:");
772 strainSpaceHardeningVariables = status->giveStrainSpaceHardeningVars();
773 strainSpaceHardeningVariables.printYourself();
774 elasticStrainVectorR = totalStrain;
775 elasticStrainVectorR.subtract(plasticStrainVectorR);
776 printf("sg:");
777 this->computeTrialStressIncrement(fullStressVector, gp, elasticStrainVectorR, tStep);
778 fullStressVector.printYourself();
779
780 OOFEM_ERROR("Internal Consistency error: all combinations of yield functions tried, no consistent return");
781 }
782
783#else
784 OOFEM_ERROR("Internal Consistency error: all combinations of yield functions tried, no consistent return");
785#endif
786 }
787
788 for ( actSurf = 0, i = 1; i <= nsurf; i++ ) {
789 if ( activeConditionMap.at(i) ) {
790 actSurf++;
791 }
792 }
793
794 restart = 1;
795 break;
796 }
797 }
798 }
799
800 if ( restart ) {
801 //fprintf(stderr,"===>LAST RESORT<====");
802
803 plasticStrainVectorR = status->givePlasticStrainVector();
804 strainSpaceHardeningVariables = status->giveStrainSpaceHardeningVars();
805 elasticStrainVectorR = totalStrain;
806 elasticStrainVectorR.subtract(plasticStrainVectorR);
807 this->computeTrialStressIncrement(fullStressVector, gp, elasticStrainVectorR, tStep);
808 gamma.zero();
809 nIterations = 0;
810 int restart = 0;
811 if ( restart ) {
812 goto huhu;
813 }
814
815 continue;
816 } else {
817 OOFEM_WARNING("local equlibrium not reached in %d iterations\nElement %d, gp %d, continuing",
819 answer = fullStressVector;
820 // debug line
821 nIterations = 0;
822 goto huhu;
823 }
824 }
825 } while ( 1 );
826 } else {
827 answer = fullStressVector;
828 }
829}
830
831void
832MPlasticMaterial2 :: cuttingPlaneReturn(FloatArray &answer,
833 IntArray &activeConditionMap,
834 FloatArray &gamma,
835 GaussPoint *gp,
836 const FloatArray &totalStrain,
837 FloatArray &plasticStrainVectorR,
838 FloatArray &strainSpaceHardeningVariables,
839 TimeStep *tStep) const
840{
841 FloatArray elasticStrainVectorR;
842 FloatArray fullStressVector;
843 FloatArray helpVector, helpVector2, rhs, dkappa;
844 FloatMatrix elasticModuli, helpMtrx, helpMtrx2, gmat;
845 FloatMatrix kl, ks, lmat, rmat;
846 IntArray initialConditionMap;
847 std :: vector< FloatArray > yieldGradSigVec(this->nsurf), loadGradSigVec(this->nsurf), * loadGradSigVecPtr;
848 std :: vector< FloatArray > yieldGradKVec(this->nsurf), loadGradKVec(this->nsurf);
849 FloatArray dgamma(this->nsurf);
850 double yieldValue;
851 int nIterations = 0;
852 int strSize, i, j, elastic, restart, actSurf, indx;
853 bool yieldConsistency, init = true;
854 bool hasHardening = this->hasHardening() > 0;
855
856 MPlasticMaterial2Status *status = static_cast< MPlasticMaterial2Status * >( this->giveStatus(gp) );
857
858 if ( this->plType == associatedPT ) {
859 loadGradSigVecPtr = & yieldGradSigVec;
860 } else {
861 loadGradSigVecPtr = & loadGradSigVec;
862 }
863
864huhu: //label for goto
865 plasticStrainVectorR = status->givePlasticStrainVector();
866 strainSpaceHardeningVariables = status->giveStrainSpaceHardeningVars();
867
868
869 dgamma.resize(nsurf);
870 dgamma.zero();
871 gamma.resize(nsurf);
872 gamma.zero();
873 // compute elastic moduli
874 this->computeReducedElasticModuli(elasticModuli, gp, tStep);
875 strSize = elasticModuli.giveNumberOfRows();
876
877 // initialize activeConditionMap
878 elasticStrainVectorR = totalStrain;
879 elasticStrainVectorR.subtract(plasticStrainVectorR);
880 // stress vector in full form due to computational convinience
881 this->computeTrialStressIncrement(fullStressVector, gp, elasticStrainVectorR, tStep);
882
883 elastic = 1;
884 actSurf = 0;
885 activeConditionMap.zero();
886 if ( init ) {
887 initialConditionMap.resize(nsurf);
888 initialConditionMap.zero();
889 }
890
891 for ( i = 1; i <= this->nsurf; i++ ) {
892 yieldValue = this->computeYieldValueAt(gp, i, fullStressVector, strainSpaceHardeningVariables);
893 if ( yieldValue > YIELD_TOL ) {
894 elastic = 0;
895 if ( init ) {
896 initialConditionMap.at(i) = 1;
897 }
898
899 if ( actSurf < this->giveMaxNumberOfActiveYieldConds(gp) ) {
900 actSurf += 1;
901 activeConditionMap.at(i) = actSurf;
902 }
903 }
904 }
905
906 init = false;
907
908 if ( !elastic ) {
909 do { // local equilibrium loop
910 do { // loop for restart
911 // compute gradients
912 for ( i = 1; i <= nsurf; i++ ) {
913 this->computeReducedStressGradientVector(yieldGradSigVec [ i - 1 ], yieldFunction, i, gp, fullStressVector,
914 strainSpaceHardeningVariables);
915
916 if ( hasHardening ) {
917 this->computeKGradientVector(yieldGradKVec [ i - 1 ], yieldFunction, i, gp, fullStressVector,
918 strainSpaceHardeningVariables);
919 }
920 }
921
922 if ( this->plType == nonassociatedPT ) {
923 for ( i = 1; i <= nsurf; i++ ) {
924 this->computeReducedStressGradientVector(loadGradSigVec [ i - 1 ], loadFunction, i, gp, fullStressVector,
925 strainSpaceHardeningVariables);
926 if ( hasHardening ) {
927 this->computeKGradientVector(loadGradKVec [ i - 1 ], loadFunction, i, gp, fullStressVector,
928 strainSpaceHardeningVariables);
929 }
930 }
931 }
932
933 rhs.resize(actSurf);
934 rhs.zero();
935 gmat.resize(actSurf, actSurf);
936 gmat.zero();
937 lmat.resize(actSurf, strSize);
938 lmat.zero();
939 rmat.resize(strSize, actSurf);
940 rmat.zero();
941
942 if ( hasHardening ) {
943 this->computeReducedHardeningVarsSigmaGradient(ks, gp, activeConditionMap, fullStressVector,
944 strainSpaceHardeningVariables, gamma);
945 this->computeReducedHardeningVarsLamGradient(kl, gp, actSurf, activeConditionMap,
946 fullStressVector, strainSpaceHardeningVariables, gamma);
947 }
948
949 for ( i = 1; i <= nsurf; i++ ) {
950 if ( ( indx = activeConditionMap.at(i) ) ) {
951 rhs.at(indx) = this->computeYieldValueAt(gp, i, fullStressVector, strainSpaceHardeningVariables);
952
953 if ( hasHardening ) {
954 helpVector.beTProductOf(ks, yieldGradKVec [ i - 1 ]);
955 helpVector.add(yieldGradSigVec [ i - 1 ]);
956 for ( j = 1; j <= strSize; j++ ) {
957 lmat.at(indx, j) = helpVector.at(j);
958 }
959 } else {
960 for ( j = 1; j <= strSize; j++ ) {
961 lmat.at(indx, j) = yieldGradSigVec [ i - 1 ].at(j);
962 }
963 }
964
965 for ( j = 1; j <= strSize; j++ ) {
966 rmat.at(j, indx) += ( * loadGradSigVecPtr ) [ i - 1 ].at(j);
967 }
968
969 if ( hasHardening ) {
970 helpVector2.beTProductOf(kl, yieldGradKVec [ i - 1 ]);
971 for ( j = 1; j <= actSurf; j++ ) {
972 gmat.at(indx, j) = ( -1.0 ) * helpVector2.at(j);
973 }
974 }
975 }
976 }
977
978 helpMtrx.beProductOf(lmat, elasticModuli);
979 helpMtrx2.beProductOf(helpMtrx, rmat);
980 gmat.add(helpMtrx2);
981
982 // solve for plastic multiplier increments
983 gmat.solveForRhs(rhs, helpVector);
984 // assign gammas
985 for ( i = 1; i <= this->nsurf; i++ ) {
986 if ( ( indx = activeConditionMap.at(i) ) ) {
987 dgamma.at(i) = helpVector.at(indx);
988 } else {
989 dgamma.at(i) = 0.0;
990 }
991 }
992
994 restart = 0;
995 // check for active conditions
996 for ( i = 1; i <= this->nsurf; i++ ) {
997 if ( ( gamma.at(i) + dgamma.at(i) ) < 0.0 ) {
998 gamma.at(i) = 0.0;
999 restart = 1;
1000 }
1001 }
1002
1003 if ( restart ) {
1004 // build up new activeConditionMap and restart the iterartion from begining
1005 actSurf = 0;
1006 activeConditionMap.zero();
1007 for ( i = 1; i <= this->nsurf; i++ ) {
1008 if ( ( gamma.at(i) + dgamma.at(i) ) > 0.0 ) {
1009 actSurf += 1;
1010 activeConditionMap.at(i) = actSurf;
1011 }
1012 }
1013
1014 plasticStrainVectorR = status->givePlasticStrainVector();
1015 strainSpaceHardeningVariables = status->giveStrainSpaceHardeningVars();
1016 elasticStrainVectorR = totalStrain;
1017 elasticStrainVectorR.subtract(plasticStrainVectorR);
1018 this->computeTrialStressIncrement(fullStressVector, gp, elasticStrainVectorR, tStep);
1019 gamma.zero();
1020 nIterations = 0;
1021 continue;
1022 } else {
1023 break;
1024 }
1025 } else {
1026 break;
1027 }
1028 } while ( 1 ); // end restart loop
1029
1030 // compute plastic strain vector
1031 helpVector.resize(strSize);
1032 helpVector.zero();
1033 for ( i = 1; i <= this->nsurf; i++ ) {
1034 if ( activeConditionMap.at(i) ) {
1035 ( * loadGradSigVecPtr ) [ i - 1 ].times( dgamma.at(i) );
1036 for ( j = 1; j <= strSize; j++ ) {
1037 helpVector.at(j) += ( * loadGradSigVecPtr ) [ i - 1 ].at(j);
1038 }
1039 }
1040 }
1041
1042 plasticStrainVectorR.add(helpVector);
1043
1044 // update plastic multipliers
1045 gamma.add(dgamma);
1046
1047 elasticStrainVectorR = totalStrain;
1048 elasticStrainVectorR.subtract(plasticStrainVectorR);
1049 // stress vector in full form due to computational convinience
1050 this->computeTrialStressIncrement(fullStressVector, gp, elasticStrainVectorR, tStep);
1051
1052 if ( hasHardening ) {
1053 this->computeStrainHardeningVarsIncrement(dkappa, gp, fullStressVector, gamma, helpVector, activeConditionMap);
1054 strainSpaceHardeningVariables = status->giveStrainSpaceHardeningVars();
1055 strainSpaceHardeningVariables.add(dkappa);
1056 }
1057
1058 // check convergence
1059 yieldConsistency = true;
1060 for ( i = 1; i <= nsurf; i++ ) {
1061 if ( activeConditionMap.at(i) ) {
1062 yieldValue = this->computeYieldValueAt(gp, i, fullStressVector, strainSpaceHardeningVariables);
1063 if ( fabs(yieldValue) >= YIELD_TOL ) {
1064 yieldConsistency = false;
1065 }
1066 }
1067 }
1068
1069 if ( yieldConsistency ) {
1070 restart = 0;
1071 // check for active conditions
1072 for ( i = 1; i <= this->nsurf; i++ ) {
1073 yieldValue = this->computeYieldValueAt(gp, i, fullStressVector, strainSpaceHardeningVariables);
1074 if ( ( gamma.at(i) < 0.0 ) || ( ( activeConditionMap.at(i) == 0 ) && ( yieldValue > YIELD_TOL ) ) ) {
1075 restart = 1;
1076 //printf ("*");
1077 }
1078 }
1079
1080 if ( !restart ) {
1081 break;
1082 } else {
1083 IntArray newmap(nsurf);
1084 actSurf = 0;
1085 newmap.zero();
1086 // buid new actsurf mask
1087 for ( i = 1; i <= this->nsurf; i++ ) {
1088 yieldValue = this->computeYieldValueAt(gp, i, fullStressVector, strainSpaceHardeningVariables);
1089 if ( ( ( activeConditionMap.at(i) ) && ( gamma.at(i) >= 0.0 ) ) || ( yieldValue > YIELD_TOL ) ) {
1090 elastic = 0;
1091 actSurf += 1;
1092 newmap.at(i) = actSurf;
1093 if ( actSurf == this->giveMaxNumberOfActiveYieldConds(gp) ) {
1094 break;
1095 }
1096 }
1097 }
1098
1099 activeConditionMap = newmap;
1100
1101 if ( actSurf ) {
1102 activeConditionMap = newmap;
1103 } else {
1104 restart = 0;
1105 // select any possible
1106 for ( i = 1; i <= this->nsurf; i++ ) {
1107 if ( initialConditionMap.at(i) ) {
1108 actSurf = 1;
1109 activeConditionMap.zero();
1110 activeConditionMap.at(i) = 1;
1111 initialConditionMap.at(i) = 0;
1112 restart = 1;
1113 break;
1114 }
1115 }
1116 }
1117
1118
1119
1120
1121 plasticStrainVectorR = status->givePlasticStrainVector();
1122 strainSpaceHardeningVariables = status->giveStrainSpaceHardeningVars();
1123 elasticStrainVectorR = totalStrain;
1124 elasticStrainVectorR.subtract(plasticStrainVectorR);
1125 this->computeTrialStressIncrement(fullStressVector, gp, elasticStrainVectorR, tStep);
1126 gamma.zero();
1127 nIterations = 0;
1128 int restart = 0;
1129 if ( restart ) {
1130 goto huhu;
1131 }
1132
1133 continue;
1134 //int restart = 0;
1135 //if (restart) goto huhu;
1136 }
1137 }
1138
1139 // increment iteration count
1140 nIterations++;
1141
1142 if ( nIterations > PLASTIC_MATERIAL_MAX_ITERATIONS ) {
1143 // try last resort select single function from initial active set
1144 restart = 0;
1145 bool smartCandidate = false;
1146 int candidate = 0;
1147 IntArray newmap(nsurf);
1148 actSurf = 0;
1149 newmap.zero();
1150 // check for active conditions
1151 for ( i = 1; i <= this->nsurf; i++ ) {
1152 if ( activeConditionMap.at(i) ) {
1153 if ( gamma.at(i) < 0.0 ) {
1154 smartCandidate = true;
1155 } else {
1156 candidate = i;
1157 }
1158 }
1159 }
1160
1161 if ( smartCandidate && candidate && initialConditionMap.at(candidate) ) {
1162 actSurf = 1;
1163 activeConditionMap.zero();
1164 activeConditionMap.at(candidate) = 1;
1165 initialConditionMap.at(candidate) = 0;
1166 restart = 1;
1167 } else {
1168 // select any possible
1169 for ( i = 1; i <= this->nsurf; i++ ) {
1170 if ( initialConditionMap.at(i) ) {
1171 actSurf = 1;
1172 activeConditionMap.zero();
1173 activeConditionMap.at(i) = 1;
1174 initialConditionMap.at(i) = 0;
1175 restart = 1;
1176 break;
1177 }
1178 }
1179 }
1180
1181 if ( restart ) {
1182 //fprintf(stderr,"===>LAST RESORT<====");
1183
1184 plasticStrainVectorR = status->givePlasticStrainVector();
1185 strainSpaceHardeningVariables = status->giveStrainSpaceHardeningVars();
1186 elasticStrainVectorR = totalStrain;
1187 elasticStrainVectorR.subtract(plasticStrainVectorR);
1188 this->computeTrialStressIncrement(fullStressVector, gp, elasticStrainVectorR, tStep);
1189 gamma.zero();
1190 nIterations = 0;
1191 int restart = 0;
1192 if ( restart ) {
1193 goto huhu;
1194 }
1195
1196 continue;
1197 } else {
1198 OOFEM_WARNING("local equlibrium not reached in %d iterations\nElement %d, gp %d, continuing",
1200 answer = fullStressVector;
1201 // debug line
1202 nIterations = 0;
1203 goto huhu;
1204 }
1205 }
1206 } while ( 1 );
1207 }
1208
1209 //printf (" (%d iterations)", nIterations);
1210 answer = fullStressVector;
1211}
1212
1213
1214
1215void
1216MPlasticMaterial2 :: computeReducedStressGradientVector(FloatArray &answer, functType ftype, int isurf,
1217 GaussPoint *gp, const FloatArray &stressVector,
1218 const FloatArray &strainSpaceHardeningVariables) const
1219{
1220 FloatArray stressGradient;
1221
1222 this->computeStressGradientVector(stressGradient, ftype, isurf, gp, stressVector,
1223 strainSpaceHardeningVariables);
1224
1225 StructuralMaterial :: giveReducedSymVectorForm( answer, stressGradient, gp->giveMaterialMode() );
1226}
1227
1228void
1229MPlasticMaterial2 :: computeResidualVector(FloatArray &answer, GaussPoint *gp, const FloatArray &gamma,
1230 const IntArray &activeConditionMap, const FloatArray &plasticStrainVectorR,
1231 const FloatArray &strainSpaceHardeningVariables,
1232 std :: vector< FloatArray > &gradientVectorR) const
1233{
1234 /* Computes Residual vector for closes point projection algorithm */
1235
1236 FloatArray oldPlasticStrainVectorR;
1237 int size;
1238 MPlasticMaterial2Status *status = static_cast< MPlasticMaterial2Status * >( this->giveStatus(gp) );
1239
1240 size = plasticStrainVectorR.giveSize();
1241
1242 answer.resize(size);
1243 oldPlasticStrainVectorR = status->givePlasticStrainVector();
1244
1245 for ( int i = 1; i <= size; i++ ) {
1246 answer.at(i) = oldPlasticStrainVectorR.at(i) - plasticStrainVectorR.at(i);
1247 }
1248
1249 for ( int i = 1; i <= this->nsurf; i++ ) {
1250 if ( activeConditionMap.at(i) ) {
1251 for ( int j = 1; j <= size; j++ ) {
1252 answer.at(j) += gamma.at(i) * gradientVectorR [ i - 1 ].at(j);
1253 }
1254 }
1255 }
1256}
1257
1258
1259void
1260MPlasticMaterial2 :: computeTrialStressIncrement(FloatArray &answer, GaussPoint *gp,
1261 const FloatArray &elasticStrainVectorR,
1262 TimeStep *tStep) const
1263{
1264 /* Computes the full trial elastic stress vector */
1265
1266 FloatMatrix de;
1267 FloatArray reducedAnswer;
1268
1269 this->computeReducedElasticModuli(de, gp, tStep);
1270 //this->giveLinearElasticMaterial()->giveCharacteristicMatrix(de, TangentStiffness, gp, tStep);
1271 reducedAnswer.beProductOf(de, elasticStrainVectorR);
1272 StructuralMaterial :: giveFullSymVectorForm( answer, reducedAnswer, gp->giveMaterialMode() );
1273}
1274
1275
1276void
1277MPlasticMaterial2 :: computeAlgorithmicModuli(FloatMatrix &answer,
1278 GaussPoint *gp,
1279 const FloatMatrix &elasticModuliInverse,
1280 const FloatArray &gamma,
1281 const IntArray &activeConditionMap,
1282 const FloatArray &fullStressVector,
1283 const FloatArray &strainSpaceHardeningVariables) const
1284{
1285 /* returns consistent moduli in reduced form.
1286 * stressVector in full form
1287 */
1288 FloatMatrix gradientMatrix, ks;
1289 FloatMatrix help, helpInverse;
1290 int i, j, size;
1291 bool hasHardening = this->hasHardening() > 0;
1292
1293 size = elasticModuliInverse.giveNumberOfRows();
1294
1295 // assemble consistent moduli
1296 helpInverse.resize(size, size);
1297 helpInverse.zero();
1298 for ( i = 1; i <= nsurf; i++ ) {
1299 if ( activeConditionMap.at(i) ) {
1300 // ask gradientMatrix
1301 this->computeReducedSSGradientMatrix(gradientMatrix, i, gp, fullStressVector,
1302 strainSpaceHardeningVariables);
1303
1304 gradientMatrix.times( gamma.at(i) );
1305 helpInverse.add(gradientMatrix);
1306
1307 if ( hasHardening ) {
1308 this->computeReducedSKGradientMatrix(gradientMatrix, i, gp, fullStressVector,
1309 strainSpaceHardeningVariables);
1310
1311 gradientMatrix.times( gamma.at(i) );
1312 this->computeReducedHardeningVarsSigmaGradient(ks, gp, activeConditionMap, fullStressVector, strainSpaceHardeningVariables, gamma);
1313 help.beProductOf(gradientMatrix, ks);
1314 helpInverse.add(help);
1315 }
1316 }
1317 }
1318
1319 for ( i = 1; i <= size; i++ ) {
1320 for ( j = 1; j <= size; j++ ) {
1321 helpInverse.at(i, j) += elasticModuliInverse.at(i, j);
1322 }
1323 }
1324
1325 // prevent too big numbers
1326 for ( i = 1; i <= size; i++ ) {
1327 if ( fabs( helpInverse.at(i, i) ) > 1.e16 ) {
1328 helpInverse.at(i, i) = sgn( helpInverse.at(i, i) ) * 1.e16;
1329 }
1330 }
1331
1332 answer.beInverseOf(helpInverse);
1333}
1334
1335// ----------------------------------------------------------------------------//
1336
1337
1339MPlasticMaterial2 :: giveConsistentStiffnessMatrix(MatResponseMode mode,
1340 GaussPoint *gp,
1341 TimeStep *tStep) const
1342{
1343 //
1344 // returns receiver material matrix for given reached state
1345 // described by temp variables.
1346 //
1347
1348 FloatMatrix consistentModuli, elasticModuli, umat, vmat;
1349 FloatMatrix elasticModuliInverse, kl, ks;
1350 FloatMatrix gradientMatrix, gmat, gmatInv, gradMat, helpMtrx, helpMtrx2, answerR;
1351 FloatArray gradientVector, stressVector, fullStressVector;
1352 FloatArray strainSpaceHardeningVariables, helpVector;
1353 std :: vector< FloatArray > yieldGradSigVec(this->nsurf), loadGradSigVec(this->nsurf), * loadGradSigVecPtr;
1354 std :: vector< FloatArray > yieldGradKVec(this->nsurf), loadGradKVec(this->nsurf);
1355 FloatArray helpVector2;
1356
1357 IntArray activeConditionMap, mask;
1358 FloatArray gamma;
1359 int strSize, indx, actSurf = 0;
1360 bool hasHardening = this->hasHardening() > 0;
1361
1362 MPlasticMaterial2Status *status = static_cast< MPlasticMaterial2Status * >( this->giveStatus(gp) );
1363
1364 if ( this->plType == associatedPT ) {
1365 loadGradSigVecPtr = & yieldGradSigVec;
1366 } else {
1367 loadGradSigVecPtr = & loadGradSigVec;
1368 }
1369
1370 // ask for plastic consistency parameter
1371 gamma = status->giveTempGamma();
1372 activeConditionMap = status->giveTempActiveConditionMap();
1373 //
1374 // check for elastic cases
1375 //
1376 if ( ( status->giveTempStateFlag() == MPlasticMaterial2Status :: PM_Elastic ) ||
1377 ( status->giveTempStateFlag() == MPlasticMaterial2Status :: PM_Unloading ) ) {
1378 FloatMatrix answer;
1379 const_cast<MPlasticMaterial2*>(this)->giveStiffnessMatrix(answer, ElasticStiffness, gp, tStep);
1380 return answer;
1381 }
1382
1383 //
1384 // plastic case
1385 //
1386 // determine number of active surfaces
1387 for ( int i = 1; i <= nsurf; i++ ) {
1388 if ( activeConditionMap.at(i) ) {
1389 actSurf++;
1390 }
1391 }
1392
1393 // compute elastic moduli and its inverse
1394 this->computeReducedElasticModuli(elasticModuli, gp, tStep);
1395 elasticModuliInverse.beInverseOf(elasticModuli);
1396 strSize = elasticModuliInverse.giveNumberOfRows();
1397
1398 stressVector = status->giveTempStressVector();
1399 StructuralMaterial :: giveFullSymVectorForm( fullStressVector, stressVector, gp->giveMaterialMode() );
1400 strainSpaceHardeningVariables = status->giveTempStrainSpaceHardeningVarsVector();
1401
1402 //
1403 // compute consistent moduli
1404 //
1405 this->computeAlgorithmicModuli(consistentModuli, gp, elasticModuliInverse, gamma,
1406 activeConditionMap, fullStressVector, strainSpaceHardeningVariables);
1407
1408 //computee gmatInv
1409 for ( int i = 1; i <= nsurf; i++ ) {
1410 this->computeReducedStressGradientVector(yieldGradSigVec [ i - 1 ], yieldFunction, i, gp, fullStressVector,
1411 strainSpaceHardeningVariables);
1412 if ( hasHardening ) {
1413 this->computeKGradientVector(yieldGradKVec [ i - 1 ], yieldFunction, i, gp, fullStressVector,
1414 strainSpaceHardeningVariables);
1415 }
1416 }
1417
1418 if ( this->plType == nonassociatedPT ) {
1419 for ( int i = 1; i <= nsurf; i++ ) {
1420 this->computeReducedStressGradientVector(loadGradSigVec [ i - 1 ], loadFunction, i, gp, fullStressVector,
1421 strainSpaceHardeningVariables);
1422 if ( hasHardening ) {
1423 this->computeKGradientVector(loadGradKVec [ i - 1 ], loadFunction, i, gp, fullStressVector,
1424 strainSpaceHardeningVariables);
1425 }
1426 }
1427 }
1428
1429
1430 umat.resize(strSize, actSurf);
1431 umat.zero();
1432 vmat.resize(actSurf, strSize);
1433 vmat.zero();
1434 gmat.resize(actSurf, actSurf);
1435 gmat.zero();
1436
1437 if ( hasHardening ) {
1438 this->computeReducedHardeningVarsSigmaGradient(ks, gp, activeConditionMap, fullStressVector,
1439 strainSpaceHardeningVariables, gamma);
1440 this->computeReducedHardeningVarsLamGradient(kl, gp, actSurf, activeConditionMap,
1441 fullStressVector, strainSpaceHardeningVariables, gamma);
1442 }
1443
1444 for ( int i = 1; i <= nsurf; i++ ) {
1445 if ( ( indx = activeConditionMap.at(i) ) ) {
1446 if ( hasHardening ) {
1447 helpVector.beTProductOf(ks, yieldGradKVec [ i - 1 ]);
1448 helpVector.add(yieldGradSigVec [ i - 1 ]);
1449 for ( int j = 1; j <= strSize; j++ ) {
1450 vmat.at(indx, j) = helpVector.at(j);
1451 }
1452 } else {
1453 for ( int j = 1; j <= strSize; j++ ) {
1454 vmat.at(indx, j) = yieldGradSigVec [ i - 1 ].at(j);
1455 }
1456 }
1457
1458 if ( hasHardening ) {
1459 this->computeReducedSKGradientMatrix(gradientMatrix, i, gp, fullStressVector,
1460 strainSpaceHardeningVariables);
1461 helpMtrx.beProductOf(gradientMatrix, kl);
1462 helpMtrx.times( gamma.at(i) );
1463 umat.add(helpMtrx);
1464 }
1465
1466 for ( int j = 1; j <= strSize; j++ ) {
1467 umat.at(j, indx) += ( ( * loadGradSigVecPtr ) [ i - 1 ] ).at(j);
1468 }
1469
1470
1471 if ( hasHardening ) {
1472 helpVector2.beTProductOf(kl, yieldGradKVec [ i - 1 ]);
1473 for ( int j = 1; j <= actSurf; j++ ) {
1474 gmat.at(indx, j) = ( -1.0 ) * helpVector2.at(j);
1475 }
1476 }
1477 }
1478 }
1479
1480 helpMtrx.beProductOf(vmat, consistentModuli); // V S
1481 helpMtrx2.beProductOf(helpMtrx, umat);
1482 gmat.add(helpMtrx2);
1484 gmatInv.beInverseOf(gmat);
1485
1486
1487 helpMtrx2.beProductOf(gmatInv, helpMtrx);
1488 helpMtrx.beProductOf(consistentModuli, umat); // S U
1489 FloatMatrix answer;
1490 answer.beProductOf(helpMtrx, helpMtrx2); // SUGVS
1491 answer.negated();
1492 answer.add(consistentModuli);
1493 return answer;
1494}
1495
1497MPlasticMaterial2 :: giveElastoPlasticStiffnessMatrix(MatResponseMode mode,
1498 GaussPoint *gp,
1499 TimeStep *tStep) const
1500{
1501 //
1502 // returns receiver material matrix for given reached state
1503 // described by temp variables.
1504 //
1505
1506 FloatMatrix elasticModuli, umat, vmat;
1507 FloatMatrix gmat, gmatInv, helpMtrx, helpMtrx2, kl, ks;
1508 FloatArray stressVector, fullStressVector;
1509 FloatArray strainSpaceHardeningVariables, helpVector, helpVector2;
1510 std :: vector< FloatArray > yieldGradSigVec(this->nsurf), loadGradSigVec(this->nsurf), * loadGradSigVecPtr;
1511 std :: vector< FloatArray > yieldGradKVec(this->nsurf), loadGradKVec(this->nsurf);
1512 FloatArray helpVec;
1513
1514 IntArray activeConditionMap, mask;
1515 FloatArray gamma;
1516 int strSize, indx, actSurf = 0;
1517 bool hasHardening = this->hasHardening() > 0;
1518
1519 MPlasticMaterial2Status *status = static_cast< MPlasticMaterial2Status * >( this->giveStatus(gp) );
1520
1521 if ( this->plType == associatedPT ) {
1522 loadGradSigVecPtr = & yieldGradSigVec;
1523 } else {
1524 loadGradSigVecPtr = & loadGradSigVec;
1525 }
1526
1527 // ask for plastic consistency parameter
1528 gamma = status->giveTempGamma();
1529 activeConditionMap = status->giveTempActiveConditionMap();
1530 //
1531 // check for elastic cases
1532 //
1533 if ( ( status->giveTempStateFlag() == MPlasticMaterial2Status :: PM_Elastic ) ||
1534 ( status->giveTempStateFlag() == MPlasticMaterial2Status :: PM_Unloading ) ) {
1535 FloatMatrix answer;
1536 const_cast<MPlasticMaterial2*>(this)->giveStiffnessMatrix(answer, ElasticStiffness, gp, tStep);
1537 return answer;
1538 }
1539
1540 //
1541 // plastic case
1542 //
1543 // determine number of active surfaces
1544 for ( int i = 1; i <= nsurf; i++ ) {
1545 if ( activeConditionMap.at(i) ) {
1546 actSurf++;
1547 }
1548 }
1549
1550 // compute elastic moduli and its inverse
1551 this->computeReducedElasticModuli(elasticModuli, gp, tStep);
1552
1553
1554 stressVector = status->giveStressVector();
1555 StructuralMaterial :: giveFullSymVectorForm( fullStressVector, stressVector, gp->giveMaterialMode() );
1556 strainSpaceHardeningVariables = status->giveStrainSpaceHardeningVars();
1557 strSize = elasticModuli.giveNumberOfRows();
1558
1559 //compute gmatInv
1560 for ( int i = 1; i <= nsurf; i++ ) {
1561 this->computeReducedStressGradientVector(yieldGradSigVec [ i - 1 ], yieldFunction, i, gp, fullStressVector,
1562 strainSpaceHardeningVariables);
1563 if ( hasHardening ) {
1564 this->computeKGradientVector(yieldGradKVec [ i - 1 ], yieldFunction, i, gp, fullStressVector,
1565 strainSpaceHardeningVariables);
1566 }
1567 }
1568
1569 if ( this->plType == nonassociatedPT ) {
1570 for ( int i = 1; i <= nsurf; i++ ) {
1571 this->computeReducedStressGradientVector(loadGradSigVec [ i - 1 ], loadFunction, i, gp, fullStressVector,
1572 strainSpaceHardeningVariables);
1573 if ( hasHardening ) {
1574 this->computeKGradientVector(loadGradKVec [ i - 1 ], loadFunction, i, gp, fullStressVector,
1575 strainSpaceHardeningVariables);
1576 }
1577 }
1578 }
1579
1580 umat.resize(strSize, actSurf);
1581 vmat.resize(actSurf, strSize);
1582 gmat.resize(actSurf, actSurf);
1583
1584 if ( hasHardening ) {
1585 this->computeReducedHardeningVarsSigmaGradient(ks, gp, activeConditionMap, fullStressVector,
1586 strainSpaceHardeningVariables, gamma);
1587 this->computeReducedHardeningVarsLamGradient(kl, gp, actSurf, activeConditionMap,
1588 fullStressVector, strainSpaceHardeningVariables, gamma);
1589 }
1590
1591 for ( int i = 1; i <= nsurf; i++ ) {
1592 if ( ( indx = activeConditionMap.at(i) ) ) {
1593 if ( hasHardening ) {
1594 helpVector.beTProductOf(ks, yieldGradKVec [ i - 1 ]);
1595 helpVector.add(yieldGradSigVec [ i - 1 ]);
1596 for ( int j = 1; j <= strSize; j++ ) {
1597 vmat.at(indx, j) = helpVector.at(j);
1598 }
1599 } else {
1600 for ( int j = 1; j <= strSize; j++ ) {
1601 vmat.at(indx, j) = yieldGradSigVec [ i - 1 ].at(j);
1602 }
1603 }
1604
1605 for ( int j = 1; j <= strSize; j++ ) {
1606 umat.at(j, indx) += ( * loadGradSigVecPtr ) [ i - 1 ].at(j);
1607 }
1608
1609
1610 if ( hasHardening ) {
1611 helpVector2.beTProductOf(kl, yieldGradKVec [ i - 1 ]);
1612 for ( int j = 1; j <= actSurf; j++ ) {
1613 gmat.at(indx, j) = ( -1.0 ) * helpVector2.at(j);
1614 }
1615 }
1616 }
1617 }
1618
1619 helpMtrx.beProductOf(vmat, elasticModuli); // V S
1620 helpMtrx2.beProductOf(helpMtrx, umat);
1621 gmat.add(helpMtrx2);
1623 gmatInv.beInverseOf(gmat);
1624
1625 helpMtrx.beProductOf(gmatInv, vmat);
1626 helpMtrx2.beProductOf(umat, helpMtrx);
1627 FloatMatrix answer;
1628 answer.beProductOf(elasticModuli, helpMtrx2);
1629 answer.negated();
1630 answer.add(elasticModuli);
1631 return answer;
1632}
1633
1634/*
1635 * void
1636 * MPlasticMaterial2 :: computeDiagModuli(FloatMatrix& answer,
1637 * GaussPoint *gp, FloatMatrix &elasticModuliInverse,
1638 * FloatMatrix &hardeningModuliInverse)
1639 * {
1640 * //
1641 * // assembles diagonal moduli from elasticModuliInverse and hardeningModuliInverse
1642 * //
1643 * int size1, size2, i,j;
1644 *
1645 * size1 = elasticModuliInverse.giveNumberOfRows();
1646 * if (hardeningModuliInverse.giveNumberOfRows()) size2=size1+hardeningModuliInverse.giveNumberOfRows();
1647 * else size2 = size1;
1648 *
1649 * answer.resize (size2, size2);
1650 * answer.zero();
1651 *
1652 * for (i=1; i<=size1; i++)
1653 * for (j=1; j<= size1; j++) answer.at(i,j) = elasticModuliInverse.at(i,j);
1654 *
1655 * for (i=size1+1; i<= size2; i++)
1656 * for (j=size1+1; j<= size2; j++) answer.at(i,j) = hardeningModuliInverse.at(i-size1, j-size1);
1657 * }
1658 */
1659
1660void
1661MPlasticMaterial2 :: computeReducedElasticModuli(FloatMatrix &answer,
1662 GaussPoint *gp,
1663 TimeStep *tStep) const
1664{ /* Returns elastic moduli in reduced stress-strain space*/
1665 this->linearElasticMaterial->giveStiffnessMatrix(answer, ElasticStiffness, gp, tStep);
1666}
1667
1668
1669// overloaded from structural material
1670
1672MPlasticMaterial2 :: give3dMaterialStiffnessMatrix(MatResponseMode mode,
1673 GaussPoint *gp,
1674 TimeStep *tStep) const
1675//
1676//
1677//
1678// computes full 3d constitutive matrix for case of 3d stress-strain state.
1679// it returns elasto-plastic stiffness material matrix.
1680// if strainIncrement == NULL a loading is assumed
1681// for detailed description see (W.F.Chen: Plasticity in Reinforced Concrete, McGraw-Hill, 1982,
1682// chapter 6.)
1683//
1684// if derived material would like to implement failure behaviour
1685// it must redefine basic Give3dMaterialStiffnessMatrix function
1686// in order to take possible failure (tension cracking) into account
1687//
1688//
1689//
1690{
1691 // we can force 3d response, and we obtain correct 3d tangent matrix,
1692 // but in fact, stress integration algorithm will not work
1693 // because in stress integration algorithm we are unable to recognize
1694 // which reduction from 3d case should be performed to obtain correct result.
1695 // so for new stressStrain state, instead of programming 3d reduction,
1696 // you should enhance imposeConstraints functions for ne state, and
1697 // then programming simple inteface function for you stressstrain state
1698 // calling GiveMaterailStiffenssMatrix, which imposes constrains correctly.
1699 if ( mode == TangentStiffness ) {
1700 if ( rmType == mpm_ClosestPoint ) {
1701 return this->giveConsistentStiffnessMatrix(mode, gp, tStep);
1702 } else {
1703 return this->giveElastoPlasticStiffnessMatrix(mode, gp, tStep);
1704 }
1705 } else {
1706 return this->linearElasticMaterial->give3dMaterialStiffnessMatrix(mode, gp, tStep);
1707 }
1708}
1709
1710
1712MPlasticMaterial2 :: givePlaneStressStiffMtrx(MatResponseMode mode,
1713 GaussPoint *gp,
1714 TimeStep *tStep) const
1715
1716//
1717// returns receiver's 2dPlaneStressMtrx
1718// (2dPlaneStres ==> sigma_z = tau_xz = tau_yz = 0.)
1719//
1720// standard method from Material Class overloaded, because no inversion is needed.
1721// the reduction from 3d case will not work
1722// this implementation should be faster.
1723{
1724 if ( mode == TangentStiffness ) {
1725 if ( rmType == mpm_ClosestPoint ) {
1726 return this->giveConsistentStiffnessMatrix(mode, gp, tStep);
1727 } else {
1728 return this->giveElastoPlasticStiffnessMatrix(mode, gp, tStep);
1729 }
1730 } else {
1731 return this->linearElasticMaterial->givePlaneStressStiffMtrx(mode, gp, tStep);
1732 }
1733}
1734
1735
1737MPlasticMaterial2 :: givePlaneStrainStiffMtrx(MatResponseMode mode,
1738 GaussPoint *gp,
1739 TimeStep *tStep) const
1740
1741//
1742// return receiver's 2dPlaneStrainMtrx constructed from
1743// general 3dMatrialStiffnessMatrix
1744// (2dPlaneStrain ==> eps_z = gamma_xz = gamma_yz = 0.)
1745//
1746{
1747 if ( mode == TangentStiffness ) {
1748 if ( rmType == mpm_ClosestPoint ) {
1749 return this->giveConsistentStiffnessMatrix(mode, gp, tStep);
1750 } else {
1751 return this->giveElastoPlasticStiffnessMatrix(mode, gp, tStep);
1752 }
1753 } else {
1754 return this->linearElasticMaterial->givePlaneStrainStiffMtrx(mode, gp, tStep);
1755 }
1756}
1757
1758
1760MPlasticMaterial2 :: give1dStressStiffMtrx(MatResponseMode mode,
1761 GaussPoint *gp,
1762 TimeStep *tStep) const
1763
1764//
1765// returns receiver's 1dMaterialStiffnessMAtrix
1766// (1d case ==> sigma_y = sigma_z = tau_yz = tau_zx = tau_xy = 0.)
1767{
1768 if ( mode == TangentStiffness ) {
1769 if ( rmType == mpm_ClosestPoint ) {
1770 return this->giveConsistentStiffnessMatrix(mode, gp, tStep);
1771 } else {
1772 return this->giveElastoPlasticStiffnessMatrix(mode, gp, tStep);
1773 }
1774 } else {
1775 return this->linearElasticMaterial->give1dStressStiffMtrx(mode, gp, tStep);
1776 }
1777}
1778
1779
1780
1782MPlasticMaterial2 :: give2dBeamLayerStiffMtrx(MatResponseMode mode,
1783 GaussPoint *gp,
1784 TimeStep *tStep) const
1785//
1786// returns receiver's 2dBeamLayerStiffMtrx.
1787// (2dPlaneStres ==> sigma_z = tau_xz = tau_yz = 0.)
1788//
1789// standard method from Material Class overloaded, because no inversion is needed.
1790// the reduction from 3d case will not work
1791// this implementation should be faster.
1792{
1793 if ( mode == TangentStiffness ) {
1794 if ( rmType == mpm_ClosestPoint ) {
1795 return this->giveConsistentStiffnessMatrix(mode, gp, tStep);
1796 } else {
1797 return this->giveElastoPlasticStiffnessMatrix(mode, gp, tStep);
1798 }
1799 } else {
1800 return this->linearElasticMaterial->give2dBeamLayerStiffMtrx(mode, gp, tStep);
1801 }
1802}
1803
1804
1805
1807MPlasticMaterial2 :: givePlateLayerStiffMtrx(MatResponseMode mode,
1808 GaussPoint *gp,
1809 TimeStep *tStep) const
1810//
1811// returns receiver's 2dPlateLayerMtrx
1812// (2dPlaneStres ==> sigma_z = tau_xz = tau_yz = 0.)
1813//
1814// standard method from Material Class overloaded, because no inversion is needed.
1815// the reduction from 3d case will not work
1816// this implementation should be faster.
1817{
1818 if ( mode == TangentStiffness ) {
1819 if ( rmType == mpm_ClosestPoint ) {
1820 return this->giveConsistentStiffnessMatrix(mode, gp, tStep);
1821 } else {
1822 return this->giveElastoPlasticStiffnessMatrix(mode, gp, tStep);
1823 }
1824 } else {
1825 return this->linearElasticMaterial->givePlateLayerStiffMtrx(mode, gp, tStep);
1826 }
1827}
1828
1830MPlasticMaterial2 :: giveFiberStiffMtrx(MatResponseMode mode,
1831 GaussPoint *gp,
1832 TimeStep *tStep) const
1833//
1834// returns receiver's 1dFiber
1835// (1dFiber ==> sigma_y = sigma_z = tau_yz = 0.)
1836//
1837// standard method from Material Class overloaded, because no inversion is needed.
1838// the reduction from 3d case will not work
1839// this implementation should be faster.
1840{
1841 if ( mode == TangentStiffness ) {
1842 if ( rmType == mpm_ClosestPoint ) {
1843 return this->giveConsistentStiffnessMatrix(mode, gp, tStep);
1844 } else {
1845 return this->giveElastoPlasticStiffnessMatrix(mode, gp, tStep);
1846 }
1847 } else {
1848 return this->linearElasticMaterial->giveFiberStiffMtrx(mode, gp, tStep);
1849 }
1850}
1851
1852
1853int
1854MPlasticMaterial2 :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
1855{
1856 MPlasticMaterial2Status *status = static_cast< MPlasticMaterial2Status * >( this->giveStatus(gp) );
1857 if ( type == IST_PlasticStrainTensor ) {
1858 const FloatArray &ep = status->givePlasticStrainVector();
1860 StructuralMaterial :: giveFullSymVectorForm( answer, ep, gp->giveMaterialMode() );
1861 return 1;
1862 } else if ( type == IST_PrincipalPlasticStrainTensor ) {
1863 FloatArray st;
1864
1865 const FloatArray &s = status->givePlasticStrainVector();
1866
1868 StructuralMaterial :: giveFullSymVectorForm( st, s, gp->giveMaterialMode() );
1869
1870 this->computePrincipalValues(answer, st, principal_strain);
1871 return 1;
1872 } else {
1873 return StructuralMaterial :: giveIPValue(answer, gp, type, tStep);
1874 }
1875}
1876
1877long
1878MPlasticMaterial2 :: getPopulationSignature(IntArray &mask) const
1879{
1880 long val = 0;
1881 int size = mask.giveSize();
1882 if ( size > ( int ) ( sizeof( long ) * 8 ) ) {
1883 printf("MPlasticMaterial2: too many yield conditions");
1884 }
1885
1886 for ( int i = 1; i <= mask.giveSize(); i++ ) {
1887 if ( mask.at(i) ) {
1888 val |= ( 1L << ( i - 1 ) );
1889 }
1890 }
1891
1892 return val;
1893}
1894
1895int
1896MPlasticMaterial2 :: testPopulation(long pop) const
1897{
1898 if ( populationSet.find(pop) != populationSet.end() ) {
1899 return 0;
1900 } else {
1901 return 1;
1902 }
1903}
1904
1905void
1906MPlasticMaterial2 :: clearPopulationSet() const
1907{
1908 populationSet.clear();
1909}
1910
1911void
1912MPlasticMaterial2 :: addNewPopulation(IntArray &mask) const
1913{
1914 long val = getPopulationSignature(mask);
1915 populationSet.insert(val);
1916}
1917
1918
1919int
1920MPlasticMaterial2 :: getNewPopulation(IntArray &result, IntArray &candidateMask, int degree, int size) const
1921{
1922 long val = 0;
1923 int candDegree = 0, candSize = candidateMask.giveSize();
1924 for ( int i = 1; i <= candSize; i++ ) {
1925 if ( candidateMask.at(i) ) {
1926 candDegree++;
1927 }
1928 }
1929
1930 result.resize(size);
1931
1932 // first try candidate if compatible
1933 if ( candDegree <= degree ) {
1934 // generate candite popul value
1935 val = getPopulationSignature(candidateMask);
1936
1937 if ( testPopulation(val) ) {
1938 // candite is o.k.
1939 populationSet.insert(val);
1940 result = candidateMask;
1941 return 1;
1942 }
1943 } else {
1944 // try to generate suitable candidate from candidateMask if possible
1945 // first construct array of candidates
1946 IntArray candidateArray(candDegree);
1947 IntArray ind(degree);
1948 for ( int i = 1, j = 1; i <= candSize; i++ ) {
1949 if ( candidateMask.at(i) ) {
1950 candidateArray.at(j++) = i;
1951 }
1952 }
1953
1954 // first try first degree candidates
1955 int activeIndx = degree;
1956 for ( int i = 1; i <= degree; i++ ) {
1957 ind.at(i) = i;
1958 }
1959
1960
1961 do {
1962 result.zero();
1963 int ii, count = 1;
1964 for ( int i = 1; i <= degree; i++ ) {
1965 ii = candidateArray.at( ind.at(i) );
1966 if ( !result.at(ii) ) {
1967 result.at(ii) = count++;
1968 }
1969 }
1970
1971 // order result array
1972 count = 1;
1973 for ( int i = 1; i <= size; i++ ) {
1974 if ( result.at(i) ) {
1975 result.at(i) = count++;
1976 }
1977 }
1978
1979 val = getPopulationSignature(result);
1980 if ( testPopulation(val) ) {
1981 // candite is o.k.
1982 populationSet.insert(val);
1983 return 1;
1984 }
1985
1986 bool cont = false;
1987 activeIndx = degree;
1988 do {
1989 if ( ind.at(activeIndx) < candDegree ) {
1990 ind.at(activeIndx)++;
1991 cont = false;
1992 } else {
1993 ind.at(activeIndx) = 1;
1994 activeIndx--;
1995 if ( activeIndx > 0 ) {
1996 cont = true;
1997 } else {
1998 cont = false;
1999 }
2000 }
2001 } while ( cont );
2002 } while ( activeIndx >= 1 );
2003 }
2004
2005 // generate any suitable population
2006 IntArray ind(degree);
2007 // first try first degree candidates
2008 int activeIndx = degree;
2009 for ( int i = 1; i <= degree; i++ ) {
2010 ind.at(i) = 1;
2011 }
2012
2013
2014 do {
2015 result.zero();
2016 int ii, count = 1;
2017 for ( int i = 1; i <= degree; i++ ) {
2018 ii = ind.at(i);
2019 if ( !result.at(ii) ) {
2020 result.at(ii) = count++;
2021 }
2022 }
2023
2024 // order result array
2025 count = 1;
2026 for ( int i = 1; i <= size; i++ ) {
2027 if ( result.at(i) ) {
2028 result.at(i) = count++;
2029 }
2030 }
2031
2032 val = getPopulationSignature(result);
2033 if ( testPopulation(val) ) {
2034 // candite is o.k.
2035 populationSet.insert(val);
2036 return 1;
2037 }
2038
2039 bool cont = false;
2040 activeIndx = degree;
2041 do {
2042 if ( ind.at(activeIndx) < size ) {
2043 ind.at(activeIndx)++;
2044 cont = false;
2045 } else {
2046 ind.at(activeIndx) = 1;
2047 activeIndx--;
2048 if ( activeIndx > 0 ) {
2049 cont = true;
2050 } else {
2051 cont = false;
2052 }
2053 }
2054 } while ( cont );
2055 } while ( activeIndx >= 1 );
2056
2057 // there is no population left -> return 0;
2058 return 0;
2059}
2060
2061
2062//
2063// SmearedCrackingMaterialStatus Class
2064//
2065
2066MPlasticMaterial2Status :: MPlasticMaterial2Status(GaussPoint *g, int statusSize) :
2069{ }
2070
2071
2072void
2073MPlasticMaterial2Status :: printOutputAt(FILE *file, TimeStep *tStep) const
2074{
2075 StructuralMaterialStatus :: printOutputAt(file, tStep);
2076 fprintf(file, "status { ");
2077 if ( ( state_flag == MPlasticMaterial2Status :: PM_Yielding ) || ( state_flag == MPlasticMaterial2Status :: PM_Unloading ) ) {
2078 if ( state_flag == MPlasticMaterial2Status :: PM_Yielding ) {
2079 fprintf(file, " Yielding,");
2080 } else {
2081 fprintf(file, " Unloading,");
2082 }
2083
2084 fprintf(file, " Plastic strains");
2085 for ( auto &val : plasticStrainVector ) {
2086 fprintf( file, " %.4e", val );
2087 }
2088
2089 if ( strainSpaceHardeningVarsVector.giveSize() ) {
2090 fprintf(file, " Strain space hardening vars");
2091 for ( auto &val : strainSpaceHardeningVarsVector ) {
2092 fprintf( file, " %.4e", val );
2093 }
2094 }
2095
2096 fprintf(file, " ActiveConditionMap");
2097 for ( auto &val : activeConditionMap ) {
2098 fprintf( file, " %d", val );
2099 }
2100 }
2101
2102 fprintf(file, "}\n");
2103}
2104
2105
2106void MPlasticMaterial2Status :: initTempStatus()
2107//
2108// initializes temp variables according to variables form previous equlibrium state.
2109//
2110{
2111 StructuralMaterialStatus :: initTempStatus();
2112
2113 if ( plasticStrainVector.giveSize() == 0 ) {
2114 plasticStrainVector.resize( StructuralMaterial :: giveSizeOfVoigtSymVector( gp->giveMaterialMode() ) );
2115 plasticStrainVector.zero();
2116 }
2117
2119
2121
2122
2123 tempGamma = gamma;
2125}
2126
2127
2128void
2129MPlasticMaterial2Status :: updateYourself(TimeStep *tStep)
2130//
2131// updates variables (nonTemp variables describing situation at previous equilibrium state)
2132// after a new equilibrium state has been reached
2133// temporary variables are having values corresponding to newly reached equilibrium.
2134//
2135{
2136 StructuralMaterialStatus :: updateYourself(tStep);
2137
2140
2142 gamma = tempGamma;
2144}
2145
2146
2147void
2148MPlasticMaterial2Status :: saveContext(DataStream &stream, ContextMode mode)
2149{
2150 StructuralMaterialStatus :: saveContext(stream, mode);
2151
2152 contextIOResultType iores;
2153 if ( ( iores = plasticStrainVector.storeYourself(stream) ) != CIO_OK ) {
2154 THROW_CIOERR(iores);
2155 }
2156
2157 if ( ( iores = strainSpaceHardeningVarsVector.storeYourself(stream) ) != CIO_OK ) {
2158 THROW_CIOERR(iores);
2159 }
2160
2161 if ( !stream.write(state_flag) ) {
2163 }
2164
2165 if ( ( iores = gamma.storeYourself(stream) ) != CIO_OK ) {
2166 THROW_CIOERR(iores);
2167 }
2168
2169 if ( ( iores = activeConditionMap.storeYourself(stream) ) != CIO_OK ) {
2170 THROW_CIOERR(iores);
2171 }
2172}
2173
2174
2175void
2176MPlasticMaterial2Status :: restoreContext(DataStream &stream, ContextMode mode)
2177{
2178 StructuralMaterialStatus :: restoreContext(stream, mode);
2179
2180 contextIOResultType iores;
2181 if ( ( iores = plasticStrainVector.restoreYourself(stream) ) != CIO_OK ) {
2182 THROW_CIOERR(iores);
2183 }
2184
2185 if ( ( iores = strainSpaceHardeningVarsVector.restoreYourself(stream) ) != CIO_OK ) {
2186 THROW_CIOERR(iores);
2187 }
2188
2189 int val;
2190 if ( !stream.read(val) ) {
2192 }
2194
2195 if ( ( iores = gamma.restoreYourself(stream) ) != CIO_OK ) {
2196 THROW_CIOERR(iores);
2197 }
2198
2199 if ( ( iores = activeConditionMap.restoreYourself(stream) ) != CIO_OK ) {
2200 THROW_CIOERR(iores);
2201 }
2202}
2203
2204} // 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
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
virtual void printYourself() const
Definition floatarray.C:762
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
void times(double s)
Definition floatarray.C:834
void times(double f)
void add(const FloatMatrix &a)
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
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)
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 resize(int n)
Definition intarray.C:73
void printYourself() const
Prints receiver on stdout.
Definition intarray.C:174
void zero()
Sets all component to zero.
Definition intarray.C:52
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
GaussPoint * gp
Associated integration point.
void letTempPlasticStrainVectorBe(FloatArray v)
void letTempStateFlagBe(state_flag_values v)
const FloatArray & givePlasticStrainVector() const
Returns the equilibrated strain vector.
const FloatArray & giveTempStrainSpaceHardeningVarsVector() const
Returns the actual (temp) hardening variable vector.
void letTempStrainSpaceHardeningVarsVectorBe(FloatArray v)
state_flag_values giveTempStateFlag()
IntArray activeConditionMap
Active set of yield functions (needed for algorithmic stiffness).
state_flag_values state_flag
Yield function status indicator.
const FloatArray & giveStrainSpaceHardeningVars() const
Returns the equilibrated hardening variable vector.
FloatArray plasticStrainVector
Plastic strain vector.
FloatArray gamma
Consistency parameter values (needed for algorithmic stiffness).
const IntArray & giveTempActiveConditionMap()
virtual int hasHardening() const =0
virtual void computeTrialStressIncrement(FloatArray &answer, GaussPoint *gp, const FloatArray &strainIncrement, TimeStep *tStep) const
void computeReducedStressGradientVector(FloatArray &answer, functType ftype, int isurf, GaussPoint *gp, const FloatArray &stressVector, const FloatArray &strainSpaceHardeningVariables) const
enum oofem::MPlasticMaterial2::ReturnMappingAlgoType rmType
LinearElasticMaterial * linearElasticMaterial
Reference to bulk (undamaged) material.
int getNewPopulation(IntArray &result, IntArray &candidateMask, int degree, int size) const
void addNewPopulation(IntArray &mask) const
virtual double computeDamage(GaussPoint *gp, const FloatArray &strainSpaceHardeningVariables, TimeStep *tStep) const
functType
Type that allows to distinguish between yield function and loading function.
void computeResidualVector(FloatArray &answer, GaussPoint *gp, const FloatArray &gamma, const IntArray &activeConditionMap, const FloatArray &plasticStrainVectorR, const FloatArray &strainSpaceHardeningVariables, std ::vector< FloatArray > &gradVec) const
MPlasticMaterial2(int n, Domain *d)
enum oofem::MPlasticMaterial2::plastType plType
virtual void computeReducedSSGradientMatrix(FloatMatrix &gradientMatrix, int i, GaussPoint *gp, const FloatArray &fullStressVector, const FloatArray &strainSpaceHardeningVariables) const =0
Computes second derivative of loading function with respect to stress.
virtual double computeYieldValueAt(GaussPoint *gp, int isurf, const FloatArray &stressVector, const FloatArray &strainSpaceHardeningVariables) const =0
Computes the value of yield function.
virtual int giveMaxNumberOfActiveYieldConds(GaussPoint *gp) const =0
void cuttingPlaneReturn(FloatArray &answer, IntArray &activeConditionMap, FloatArray &gamma, GaussPoint *gp, const FloatArray &totalStrain, FloatArray &plasticStrainR, FloatArray &strainSpaceHardeningVariables, TimeStep *tStep) const
bool iterativeUpdateOfActiveConds
Flag indicating whether iterative update of a set of active yield conditions takes place.
int nsurf
Number of yield surfaces.
virtual void computeReducedHardeningVarsSigmaGradient(FloatMatrix &answer, GaussPoint *gp, const IntArray &activeConditionMap, const FloatArray &fullStressVector, const FloatArray &strainSpaceHardeningVars, const FloatArray &gamma) const =0
virtual void computeReducedHardeningVarsLamGradient(FloatMatrix &answer, GaussPoint *gp, int actSurf, const IntArray &activeConditionMap, const FloatArray &fullStressVector, const FloatArray &strainSpaceHardeningVars, const FloatArray &gamma) const =0
computes derivative of vector with respect to lambda vector
virtual FloatMatrix giveElastoPlasticStiffnessMatrix(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const
virtual void computeStressGradientVector(FloatArray &answer, functType ftype, int isurf, GaussPoint *gp, const FloatArray &stressVector, const FloatArray &strainSpaceHardeningVariables) const =0
Computes the stress gradient of yield/loading function (df/d_sigma).
virtual void computeReducedElasticModuli(FloatMatrix &answer, GaussPoint *gp, TimeStep *tStep) const
virtual void computeKGradientVector(FloatArray &answer, functType ftype, int isurf, GaussPoint *gp, FloatArray &fullStressVector, const FloatArray &strainSpaceHardeningVariables) const =0
long getPopulationSignature(IntArray &mask) const
virtual void computeReducedSKGradientMatrix(FloatMatrix &gradientMatrix, int i, GaussPoint *gp, const FloatArray &fullStressVector, const FloatArray &strainSpaceHardeningVariables) const =0
Computes second derivative of loading function with respect to stress and hardening vars.
void computeAlgorithmicModuli(FloatMatrix &answer, GaussPoint *gp, const FloatMatrix &elasticModuliInverse, const FloatArray &gamma, const IntArray &activeConditionMap, const FloatArray &fullStressVector, const FloatArray &strainSpaceHardeningVariables) const
virtual FloatMatrix giveConsistentStiffnessMatrix(MatResponseMode, GaussPoint *gp, TimeStep *tStep) const
int testPopulation(long pop) const
virtual int giveSizeOfReducedHardeningVarsVector(GaussPoint *) const
virtual void computeStrainHardeningVarsIncrement(FloatArray &answer, GaussPoint *gp, const FloatArray &stress, const FloatArray &dlambda, const FloatArray &dplasticStrain, const IntArray &activeConditionMap) const =0
std ::set< long > populationSet
Set for keeping record of generated populations of active yield conditions during return.
void closestPointReturn(FloatArray &answer, IntArray &activeConditionMap, FloatArray &gamma, GaussPoint *gp, const FloatArray &totalStrain, FloatArray &plasticStrainR, FloatArray &strainSpaceHardeningVariables, TimeStep *tStep) 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)
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_WARNING(...)
Definition error.h:80
#define OOFEM_ERROR(...)
Definition error.h:79
#define RES_TOL
#define YIELD_TOL_SECONDARY
#define YIELD_TOL
#define PLASTIC_MATERIAL_MAX_ITERATIONS
long ContextMode
Definition contextmode.h:43
@ principal_strain
For computing principal strains from engineering strains.
double sgn(double i)
Returns the signum of given value (if value is < 0 returns -1, otherwise returns 1).
Definition mathfem.h:104
@ 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