OOFEM 3.0
Loading...
Searching...
No Matches
concretedpm.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 "concretedpm.h"
36#include "floatarray.h"
37#include "floatmatrix.h"
39#include "gausspoint.h"
40#include "intarray.h"
41#include "mathfem.h"
42#include "datastream.h"
43#include "contextioerr.h"
46#include "classfactory.h"
47
48namespace oofem {
51//static bool __dummy_ConcreteDPM_alt __attribute__((unused)) = GiveClassFactory().registerMaterial("concreteidp", matCreator< ConcreteDPM > );
53
62
63
64void
66{
67 // Call the function of the parent class to initialize the variables defined there.
77}
78
79void
81{
82#ifdef SOPHISTICATED_SIZEDEPENDENT_ADJUSTMENT
84#endif
85 // Call corresponding function of the parent class to update
86 // variables defined there.
88
89 // update variables defined in ConcreteDPMStatus
98}
99
100void
102{
103 // Call corresponding function of the parent class to print
104 // variables defined there.
106
107 fprintf(file, "\tstatus { ");
108
109 // print status flag
110 switch ( state_flag ) {
112 fprintf(file, "statusflag 0 (Elastic),");
113 break;
115 fprintf(file, "statusflag 1 (Unloading),");
116 break;
118 fprintf(file, "statusflag 2 (Plastic),");
119 break;
121 fprintf(file, "statusflag 3 (Damage),");
122 break;
124 fprintf(file, "statusflag 4 (PlasticDamage),");
125 break;
127 fprintf(file, "statusflag 5 (VertexCompression),");
128 break;
130 fprintf(file, "statusflag 6 (VertexTension),");
131 break;
133 fprintf(file, "statusflag 7 (VertexCompressionDamage),");
134 break;
136 fprintf(file, "statusflag 8 (VertexTensionDamage),");
137 break;
138 }
139
140#if 0
141 // print plastic strain vector
142 FloatArray plasticStrainVector();
143 giveFullPlasticStrainVector(plasticStrainVector);
144 fprintf(file, "plastic strains ");
145 for ( auto &val : plasticStrainVector ) {
146 fprintf(file, " %.4e", val);
147 }
148#endif
149
150 // print hardening/softening parameters and damage
151
152 //fprintf (file," kappaP %.4e", kappaP ) ;
153 //fprintf (file,", kappaD %.4e", kappaD ) ;
154 fprintf(file, ", kappa %.4e %.4e", kappaP, kappaD);
155 fprintf(file, ", damage %.4e", damage);
156
157 // end of record
158 fprintf(file, "}\n");
159}
160
161void
163{
165
167
168 if ( ( iores = plasticStrain.storeYourself(stream) ) != CIO_OK ) {
169 THROW_CIOERR(iores);
170 }
171
172 if ( !stream.write(tempVolumetricPlasticStrain) ) {
174 }
175 if ( !stream.write(dFDKappa) ) {
177 }
178
179
180 if ( !stream.write(kappaP) ) {
182 }
183 if ( !stream.write(le) ) {
185 }
186
187 if ( !stream.write(kappaD) ) {
189 }
190
191 if ( !stream.write(equivStrain) ) {
193 }
194
195 if ( !stream.write(damage) ) {
197 }
198 if ( !stream.write(deltaEquivStrain) ) {
200 }
201
202 if ( !stream.write(state_flag) ) {
204 }
205
206 if ( !stream.write(vertexType) ) {
208 }
209
210 #ifdef SOPHISTICATED_SIZEDEPENDENT_ADJUSTMENT
211 if ( !stream.write(epsloc) ) {
213 }
214 #endif
215
216
217}
218
219
220void
222{
224
226 if ( ( iores = plasticStrain.restoreYourself(stream) ) != CIO_OK ) {
227 THROW_CIOERR(iores);
228 }
229
230 if ( !stream.read(tempVolumetricPlasticStrain) ) {
232 }
233 if ( !stream.read(dFDKappa) ) {
235 }
236
237
238 if ( !stream.read(kappaP) ) {
240 }
241 if ( !stream.read(le) ) {
243 }
244
245 if ( !stream.read(kappaD) ) {
247 }
248
249 if ( !stream.read(equivStrain) ) {
251 }
252
253 if ( !stream.read(damage) ) {
255 }
256 if ( !stream.read(deltaEquivStrain) ) {
258 }
259
260 if ( !stream.read(state_flag) ) {
262 }
263
264 if ( !stream.read(vertexType) ) {
266 }
267
268 #ifdef SOPHISTICATED_SIZEDEPENDENT_ADJUSTMENT
269 if ( !stream.read(epsloc) ) {
271 }
272 #endif
273
274}
275
276int
278{
279 if ( type == IST_DamageScalar ) {
280 damage = value.at(1);
281 return 1;
282 }
283
284 if ( type == IST_CumPlasticStrain ) {
285 kappaP = value.at(1);
286 return 1;
287 }
288
289 if ( type == IST_CumPlasticStrain_2 ) {
290 kappaD = value.at(1);
291 return 1;
292 }
293
294 return 0;
295}
296
297
298// ******************************************************
299// *** CLASS CONCRETE DAMAGE-PLASTIC MATERIAL MODEL ***
300// ******************************************************
301
302//#define DPM_ITERATION_LIMIT 1.e-8
303
308
309
310void
312{
313 // call the corresponding service for the linear elastic material
315 linearElasticMaterial.initializeFrom(ir);
316
317 // double value;
318 // elastic parameters
321 propertyDictionary.add('E', eM);
322 propertyDictionary.add('n', nu);
323
324 // IR_GIVE_FIELD(ir, value, _IFT_IsotropicLinearElasticMaterial_talpha);
325 // propertyDictionary.add(tAlpha, value);
326
327 gM = eM / ( 2. * ( 1. + nu ) );
328 kM = eM / ( 3. * ( 1. - 2. * nu ) );
329
330 // instanciate the variables of the plasticity model
335
336 // damage parameters - only exponential softening
337 // [in ef variable the wf (crack opening) is stored]
338 if ( ir.hasField(_IFT_ConcreteDPM_wf) ) {
340 // fracture energy
341 } else {
342 double Gf;
344 ef = Gf / ft; // convert fracture energy to crack opening
345 }
346
347 // default parameters
348 ecc = 0.525;
350 yieldHardInitial = 0.1;
352 AHard = 8.e-2;
354 BHard = 3.e-3;
356 CHard = 2.;
358 DHard = 1.e-6;
360 ASoft = 15.;
362 helem = 0.;
364#ifdef SOPHISTICATED_SIZEDEPENDENT_ADJUSTMENT
365 href = 0.;
367#endif
368
369 //Compute m
370 m = 3. * ( pow(fc, 2.) - pow(ft, 2.) ) / ( fc * ft ) * ecc / ( ecc + 1. );
371 //Compute default value of dilationConst
372 dilationConst = -0.85;
374
375 yieldTol = 1.e-10;
377 newtonIter = 100;
379}
380
383 TimeStep *tStep) const
384{
385 auto status = giveConcreteDPMStatus(gp);
386
387 // Initialize temp variables for this gauss point
388 status->initTempStatus();
389
390
391 // subtract stress-independent part of strain
392 // (due to temperature changes, shrinkage, etc.)
393 auto thermalStrain = this->computeStressIndependentStrainVector_3d(gp, tStep, VM_Total);
394 auto strain = totalStrain - thermalStrain;
395
396 // perform plasticity return
397 performPlasticityReturn(gp, strain);
398
399 // compute damage
400 //auto [tempDamage, tempKappaD] = computeDamage(strain, gp, tStep); // c++17
401 auto tempDamKapD = computeDamage(strain, gp, tStep); // c++17
402 auto tempDamage = tempDamKapD.first;
403 auto tempKappaD = tempDamKapD.second;
404
405 // compute elastic strains and effective stress
406 const auto &tempPlasticStrain = status->giveTempPlasticStrain();
407 auto elasticStrain = strain - tempPlasticStrain;
408 auto effectiveStress = applyElasticStiffness(elasticStrain, eM, nu);
409
410 // compute the nominal stress
411 auto stress = effectiveStress * ( 1. - tempDamage );
412
413 status->letTempKappaDBe(tempKappaD);
414 status->letTempDamageBe(tempDamage);
415
416 status->letTempStrainVectorBe(totalStrain);
417 status->letTempStressVectorBe(stress);
418
419 assignStateFlag(gp);
420
421
422
423#ifdef SOPHISTICATED_SIZEDEPENDENT_ADJUSTMENT
424 // check whether the second-order work is negative
425 // (must be done !!!before!!! the update of strain and stress)
426 if ( status->giveEpsLoc() < 0. ) {
427 FloatArray strainIncrement = totalStrain - status->giveStrainVector();
428 auto stressIncrement = stress - FloatArrayF< 6 >(status->giveStressVector() );
429 int n = strainIncrement.giveSize();
430 double work = strainIncrement.dotProduct(stressIncrement, n);
431 //printf(" work : %g\n", work);
432 if ( work < 0. ) {
433 double E = this->give('E', gp);
434 double ft = this->give(ft_strength, gp);
435 double tmpEpsloc = tempKappaD + tempDamage * ft / E;
436 status->letTempEpslocBe(tmpEpsloc);
437 }
438 }
439
440#endif
441 return stress;
442}
443
444
445std::pair< double, double >
447{
448 auto status = giveConcreteDPMStatus(gp);
449 double equivStrain = computeEquivalentStrain(strain, gp, tStep);
450 double f = equivStrain - status->giveKappaD();
451 if ( f <= 0.0 ) {
452 // damage does not grow
453 double tempKappaD = status->giveKappaD();
454 double tempDamage = status->giveDamage();
455 return {
456 tempDamage, tempKappaD
457 };
458 } else {
459 // damage grows
460 double tempKappaD = equivStrain;
461#ifdef SOPHISTICATED_SIZEDEPENDENT_ADJUSTMENT
462 if ( ( href <= 0. ) || ( status->giveEpsLoc() >= 0. ) ) {
463 // evaluate and store the effective element size (if not known yet)
464 this->initDamaged(tempKappaD, strain, gp);
465 }
466
467#else
468 this->initDamaged(tempKappaD, strain, gp);
469#endif
470 double tempDamage = computeDamageParam(tempKappaD, gp);
471 return {
472 tempDamage, tempKappaD
473 };
474 }
475}
476
477double
479{
480 //The equivalent strain is based on the volumetric plastic strain
481 auto status = giveConcreteDPMStatus(gp);
482 auto tempKappaP = status->giveTempKappaP();
483 auto kappaP = status->giveKappaP();
484 double equivStrain = status->giveEquivStrain();
485 double deltaEquivStrain = 0.;
486 double tempEquivStrain = 0.;
487 if ( tempKappaP <= 1.0 || tempKappaP == kappaP ) {
488 return equivStrain;
489 } else if ( tempKappaP > 1.0 && tempKappaP != kappaP ) {
490 const auto &plasticStrain = status->givePlasticStrain();
491 const auto &tempPlasticStrain = status->giveTempPlasticStrain();
492
493 double volumetricPlasticStrain = plasticStrain [ 0 ] + plasticStrain [ 1 ] + plasticStrain [ 2 ];
494 double tempVolumetricPlasticStrain = tempPlasticStrain [ 0 ] + tempPlasticStrain [ 1 ] + tempPlasticStrain [ 2 ];
495 if ( kappaP < 1.0 ) {
496 //compute volumetric plastic strain at peak
497 double peakVolumetricPlasticStrain = ( 1. - kappaP ) / ( tempKappaP - kappaP ) *
498 ( tempVolumetricPlasticStrain - volumetricPlasticStrain ) +
499 volumetricPlasticStrain;
500 if ( peakVolumetricPlasticStrain < 0. ) {
501 peakVolumetricPlasticStrain = 0.;
502 }
503
504 deltaEquivStrain = tempVolumetricPlasticStrain - peakVolumetricPlasticStrain;
505 tempEquivStrain = deltaEquivStrain / computeDuctilityMeasureDamage(strain, gp);
506 if ( tempEquivStrain < 0. ) {
507 tempEquivStrain = 0.;
508 }
509 } else {
510 deltaEquivStrain = ( tempVolumetricPlasticStrain - volumetricPlasticStrain );
511 if ( deltaEquivStrain < 0. ) {
512 deltaEquivStrain = 0.;
513 }
514
515 tempEquivStrain = equivStrain +
516 deltaEquivStrain / computeDuctilityMeasureDamage(strain, gp);
517 }
518 }
519
520 status->letTempEquivStrainBe(tempEquivStrain);
521 status->letDeltaEquivStrainBe(deltaEquivStrain);
522 return tempEquivStrain;
523}
524
525double
527{
528 auto status = giveConcreteDPMStatus(gp);
529 double le = status->giveLe();
530 if ( le == 0. ) {
531 if ( helem > 0. ) {
532 le = helem;
533 } else {
534 le = gp->giveElement()->computeMeanSize();
535 }
536
537 status->setLe(le);
538 }
539
540 double answer = -( this->ef / le ) * log(1. - dam) - dam * ft / eM;
541 return answer;
542}
543
544#define DPM_DAMAGE_TOLERANCE 1.e-8
545
546double
548{
549 double omega = 0.;
550 if ( kappa > 0. ) {
551 // iteration to achieve mesh objectivity
552 // this is only valid for tension
554 int nite = 0;
555 double R, Lhs, aux, aux1;
556
557 double h = status->giveLe(); // effective element size
558
559#ifdef SOPHISTICATED_SIZEDEPENDENT_ADJUSTMENT
560 // the procedure is different before and after localization
561 double epsloc = status->giveEpsLoc();
562 if ( ( href <= 0. ) || ( epsloc < 0. ) ) { // before localization, the reference element size href is used (but only if it is really specified by the user)
563 if ( href > 0. ) {
564 h = href; // reference element size
565 }
566
567#endif
568 // standard damage evaluation procedure
569 aux1 = ( ft / eM ) * h / ef;
570 if ( aux1 > 1 ) {
571 printf("computeDamageParam: ft=%g, E=%g, wf=%g, hmax=E*wf/ft=%g, h=%g\n", ft, eM, ef, eM * ef / ft, h);
572 OOFEM_ERROR("element too large");
573 }
574
575 do {
576 nite++;
577 aux = exp(-h * ( omega * ft / eM + kappa ) / ef);
578 R = 1. - omega - aux;
579 Lhs = -1. + aux1 * aux;
580 omega -= R / Lhs;
581 if ( nite > 40 ) {
582 OOFEM_ERROR("algorithm not converging");
583 }
584 } while ( fabs(R) >= DPM_DAMAGE_TOLERANCE );
585
586#ifdef SOPHISTICATED_SIZEDEPENDENT_ADJUSTMENT
587 } else { // after localization, more complicated formula
588 if ( helem > 0. ) {
589 h = helem; // predefined element size
590 } else {
591 h = status->giveLe(); // effective element size
592 }
593
594 aux1 = ( ft / eM ) * h / ef;
595 do {
596 nite++;
597 aux = exp(-( ( href - h ) * epsloc + h * ( omega * ft / eM + kappa ) ) / ef);
598 R = 1. - omega - aux;
599 Lhs = -1. + aux1 * aux;
600 omega -= R / Lhs;
601 if ( nite > 40 ) {
602 printf("computeDamageParam: algorithm not converging (part 2)");
603 }
604 } while ( fabs(R) >= DPM_DAMAGE_TOLERANCE );
605 }
606
607#endif
608 if ( ( omega > 1.0 ) || ( omega < 0.0 ) ) {
609 OOFEM_ERROR("internal error, omega = %g", omega);
610 }
611 }
612
613 return omega;
614}
615
616
617void
619 const FloatArrayF< 6 > &strain,
620 GaussPoint *gp) const
621{
622 auto status = giveConcreteDPMStatus(gp);
623
624 if ( kappaD <= 0. ) {
625 return;
626 }
627
628 if ( helem > 0. ) {
629 status->setLe(helem);
630 } else if ( status->giveDamage() == 0. ) {
631 //auto [principalStrains, principalDir] = computePrincipalValDir(from_voigt_strain(strain)); // c++17
632 auto tmp = computePrincipalValDir(from_voigt_strain_6(strain) );
633 auto principalStrains = tmp.first;
634 auto principalDir = tmp.second;
635 // find index of max positive principal strain
636 int indx = 1;
637 for ( int i = 2; i <= 3; i++ ) {
638 if ( principalStrains.at(i) > principalStrains.at(indx) ) {
639 indx = i;
640 }
641 }
642
643 FloatArrayF< 3 >crackPlaneNormal;
644 for ( int i = 1; i <= 3; i++ ) {
645 crackPlaneNormal.at(i) = principalDir.at(i, indx);
646 }
647
648 // evaluate the projected element size
649 double le = gp->giveElement()->giveCharacteristicLength(crackPlaneNormal);
650 if ( le == 0. ) {
651 le = gp->giveElement()->computeMeanSize();
652 }
653
654 // store le in the corresponding status
655 status->setLe(le);
656 } else if ( status->giveLe() == 0. ) {
657 // this happens if the status is initialized from a file
658 // with nonzero damage
659 // le determined as square root of element area or cube root of el. volume
660 status->setLe(gp->giveElement()->computeMeanSize() );
661 }
662}
663
664double
666{
667 auto status = giveConcreteDPMStatus(gp);
668 const auto &plasticStrain = status->givePlasticStrain();
669 auto tempPlasticStrain = status->giveTempPlasticStrain() - plasticStrain;
670
671 double volStrain = tempPlasticStrain [ 0 ] + tempPlasticStrain [ 1 ] + tempPlasticStrain [ 2 ];
672 // auto principalStrain = computePrincipalValues(from_voigt_strain(strain));
673 auto principalStrain = computePrincipalValues(from_voigt_strain_6(tempPlasticStrain) );
674
675 double negativeVolStrain = 0.;
676 for ( int i = 0; i < 3; i++ ) {
677 if ( principalStrain [ i ] < 0. ) {
678 negativeVolStrain += principalStrain [ i ];
679 }
680 }
681
682 //compute ductility measure
683 double Rs = -negativeVolStrain / volStrain;
684 if ( Rs < 1.0 ) {
685 return 1. + ASoft * pow(Rs, 2.);
686 } else {
687 return 1. - 3. * ASoft + 4. * ASoft * sqrt(Rs);
688 }
689}
690
691void
693 FloatArrayF< 6 > &strain) const
694{
695 auto status = static_cast< ConcreteDPMStatus * >( this->giveStatus(gp) );
696
697 status->initTempStatus();
698
699 //get temp plastic strain and tempKappa
700 auto tempPlasticStrain = status->giveTempPlasticStrain();
701 auto tempKappaP = status->giveTempKappaP();
702
703 // compute elastic strains and trial stress
704 auto elasticStrain = strain - tempPlasticStrain;
705 auto effectiveStress = applyElasticStiffness(elasticStrain, eM, nu);
706
707 //Compute trial coordinates
708 //auto [sig, rho, thetaTrial] = computeTrialCoordinates(effectiveStress, gp); // c++17
709 auto tmp = computeTrialCoordinates(effectiveStress, gp); // c++17
710 double sig = std::get< 0 >(tmp);
711 double rho = std::get< 1 >(tmp);
712 double thetaTrial = std::get< 2 >(tmp);
713
714 double yieldValue = computeYieldValue(sig, rho, thetaTrial, tempKappaP);
715 // choose correct stress return and update state flag
716 if ( yieldValue > yieldTol ) {
717 double apexStress = 0.;
718 this->checkForVertexCase(apexStress, sig, tempKappaP, gp);
719
720 //Make the appropriate return
721 if ( status->giveTempVertexType() == ConcreteDPMStatus::VT_Tension || status->giveTempVertexType() == ConcreteDPMStatus::VT_Compression ) {
722 performVertexReturn(effectiveStress, apexStress, gp);
723 if ( status->giveTempVertexType() == ConcreteDPMStatus::VT_Regular ) {
724 //This was no real vertex case
725 //get the original tempKappaP and stress
726 tempKappaP = status->giveTempKappaP();
727 effectiveStress = applyElasticStiffness(elasticStrain, eM, nu);
728 }
729 }
730
731 if ( status->giveTempVertexType() == ConcreteDPMStatus::VT_Regular ) {
732 performRegularReturn(effectiveStress, gp, thetaTrial);
733 }
734 }
735
736 // update temp kappaP
737 // status->letTempKappaPBe(tempKappaP);
738 // compute the plastic strains
739 elasticStrain = applyElasticCompliance(effectiveStress, eM, nu);
740 tempPlasticStrain = strain - elasticStrain;
741 status->letTempPlasticStrainBe(tempPlasticStrain);
742}
743
744
745void
747 const double sig,
748 const double tempKappa,
749 GaussPoint *gp) const
750{
751 auto status = static_cast< ConcreteDPMStatus * >( this->giveStatus(gp) );
752
753 //Compute sigZero and compare with actual sig
754 double apexCompression = 0.;
755
756 //compressive apex
757 if ( ( tempKappa < 1. ) && ( sig < 0. ) ) {
758 const double yieldHardOne = computeHardeningOne(tempKappa);
759 double sigZero = -15. * fc;
760 double FZero = 1.;
761 int l = 0;
762 while ( fabs(FZero) > yieldTol && l <= newtonIter ) {
763 l++;
764 FZero = pow( ( 1. - yieldHardOne ), 2. ) * pow( ( sigZero / fc ), 4. ) +
765 pow(yieldHardOne, 2.) * m * ( sigZero / fc ) - pow(yieldHardOne, 2.);
766
767 double dFZeroDSigZero = pow( ( 1. - yieldHardOne ), 2. ) * 4. * pow( ( sigZero / fc ), 3. ) / fc +
768 pow(yieldHardOne, 2.) * m / fc;
769
770 sigZero = sigZero - FZero / dFZeroDSigZero;
771 }
772
773 if ( l < 15 && sigZero < 0. ) {
774 apexCompression = sigZero;
775 } else {
776 apexCompression = -15. * fc;
777 }
778 }
779
780 if ( ( sig > 0. && tempKappa < 1. ) || ( sig > fc / m && tempKappa >= 1. ) ) {
781 answer = 0.;
782 status->letTempVertexTypeBe(ConcreteDPMStatus::VT_Tension);
783 } else if ( sig < apexCompression ) {
784 answer = apexCompression;
785 status->letTempVertexTypeBe(ConcreteDPMStatus::VT_Compression);
786 } else {
787 status->letTempVertexTypeBe(ConcreteDPMStatus::VT_Regular);
788 }
789}
790
791void
792ConcreteDPM::performRegularReturn(FloatArrayF< 6 > &effectiveStress, GaussPoint *gp, const double theta) const
793{
794 auto status = static_cast< ConcreteDPMStatus * >( this->giveStatus(gp) );
795
796 //compute the principal directions of the stress
797 //auto [help, stressPrincipalDir] = computePrincipalValDir(from_voigt_stress(effectiveStress)); // c++17
798 auto tmp = computePrincipalValDir(from_voigt_stress_6(effectiveStress) );
799 auto stressPrincipalDir = tmp.second;
800
801 //compute invariants from stress state
802 //auto [deviatoricStress, sig] = this->computeDeviatoricVolumetricSplit(effectiveStress); // c++17
803 auto tmp2 = this->computeDeviatoricVolumetricSplit(effectiveStress);
804 auto deviatoricStress = tmp2.first;
805 double sig = tmp2.second;
806 double rho = computeSecondCoordinate(deviatoricStress);
807 double deltaLambda = 0.;
808
809 const double volumetricPlasticStrain = 3. * status->giveVolumetricPlasticStrain();
810
811 const double deviatoricPlasticStrainNorm = status->giveDeviatoricPlasticStrainNorm();
812
813 double tempVolumetricPlasticStrain = volumetricPlasticStrain;
814 double tempDeviatoricPlasticStrainNorm = deviatoricPlasticStrainNorm;
815
816 const double kappaP = status->giveKappaP();
817 auto tempKappaP = kappaP;
818
819 auto yieldValue = computeYieldValue(sig, rho, theta, tempKappaP);
820 double residualNorm = fabs(yieldValue);
821
822 int negativeRhoFlag = 0;
823
824 int iterationCount = 0;
825 while ( residualNorm > yieldTol ) {
826 if ( ++iterationCount == newtonIter ) {
827 OOFEM_ERROR("Closest point projection did not converge.");
828 }
829
830 //compute the stress, yield value and resdiuals
831 auto dGDInv = computeDGDInv(sig, rho, tempKappaP);
832 auto dFDInv = computeDFDInv(sig, rho, theta, tempKappaP);
833 auto dFDKappa = computeDFDKappa(sig, rho, theta, tempKappaP);
834 auto dKappaDDeltaLambda = computeDKappaDDeltaLambda(sig, rho, theta, tempKappaP);
835 yieldValue = computeYieldValue(sig, rho, theta, tempKappaP);
836 //The residual volumetric plastic strain is defined as eps1+eps2+eps3
837 FloatArrayF< 3 >residual;
838 residual [ 0 ] = volumetricPlasticStrain - tempVolumetricPlasticStrain +
839 deltaLambda * dGDInv [ 0 ];
840 residual [ 1 ] = deviatoricPlasticStrainNorm -
841 tempDeviatoricPlasticStrainNorm + deltaLambda * dGDInv [ 1 ];
842 residual [ 2 ] = kappaP - tempKappaP + deltaLambda * dKappaDDeltaLambda;
843
844 // weighted norm
845 //residualNorm = norm(residual); - yieldValue forgotten!
846
847 residualNorm = pow(residual [ 0 ], 2.) + pow(residual [ 1 ], 2.) +
848 pow(residual [ 2 ], 2.) + pow(yieldValue, 2.);
849 residualNorm = sqrt(residualNorm);
850
851 // printf("\n residualNorm= %e\n", residualNorm);
852 if ( residualNorm > yieldTol ) {
853 auto aMatrix = computeAMatrix(sig, rho, theta, tempKappaP, deltaLambda);
854
855 // assemble the derivatives of the yield surface
856 FloatArrayF< 3 >derivativesOfYieldSurface;
857 for ( int i = 0; i < 2; i++ ) {
858 derivativesOfYieldSurface [ i ] = dFDInv [ i ];
859 }
860
861 derivativesOfYieldSurface [ 2 ] = dFDKappa;
862 //assemble flow rules
863 FloatArrayF< 3 >flowRules;
864 for ( int i = 0; i < 2; i++ ) {
865 flowRules [ i ] = dGDInv [ i ];
866 }
867
868 flowRules [ 2 ] = dKappaDDeltaLambda;
869
870 //compute the deltaLambdaIncrement
871 double deltaLambdaIncrement = yieldValue;
872 auto helpVectorA = dot(aMatrix, residual);
873 for ( int i = 0; i < 3; i++ ) {
874 deltaLambdaIncrement -= derivativesOfYieldSurface [ i ] * helpVectorA [ i ];
875 }
876
877 auto helpVectorB = dot(aMatrix, flowRules);
878 double denominator = 0.;
879 for ( int i = 0; i < 3; i++ ) {
880 denominator += derivativesOfYieldSurface [ i ] * helpVectorB [ i ];
881 }
882
883 deltaLambdaIncrement /= denominator;
884
885 //compute increment of answer
886 auto answerIncrement = -dot(aMatrix, ( residual + deltaLambdaIncrement * flowRules ) );
887 auto rhoTest = rho + answerIncrement [ 1 ];
888
889 //Special case, if rho changes sign
890 double tempKappaPTest = 0.;
891 if ( rhoTest < 0. && negativeRhoFlag == 0 ) {
892 //Determine deltaLambdaIncrement, so that rho is equal to zero
893 answerIncrement [ 1 ] = -rho;
894
895 double deltaLambdaIncrementNew =
896 ( -aMatrix(1, 0) * residual [ 0 ] - aMatrix(1, 1) * residual [ 1 ] -
897 aMatrix(1, 2) * residual [ 2 ] - answerIncrement [ 1 ] ) /
898 ( flowRules [ 0 ] * aMatrix(1, 0) + flowRules [ 1 ] * aMatrix(1, 1) +
899 flowRules [ 2 ] * aMatrix(1, 2) );
900
901 // Special case, if deltaLambdaIncrement is equal to zero.
902 if ( fabs(deltaLambdaIncrementNew) < yieldTol * 1.e3 ) {
903 negativeRhoFlag = 1;
904 deltaLambdaIncrementNew = deltaLambdaIncrement;
905 }
906
907 answerIncrement = -dot(aMatrix, ( residual + deltaLambdaIncrementNew * flowRules ) );
908
909 sig += answerIncrement [ 0 ];
910 rho += answerIncrement [ 1 ];
911
912 tempKappaPTest = tempKappaP;
913 tempKappaP += answerIncrement [ 2 ];
914 deltaLambda += deltaLambdaIncrementNew;
915 } else {
916 tempKappaPTest = tempKappaP;
917 tempKappaP += answerIncrement [ 2 ];
918 sig += answerIncrement [ 0 ];
919 rho += answerIncrement [ 1 ];
920
921 deltaLambda += deltaLambdaIncrement;
922 }
923
924 //Special case, if deltaKappaP is negative
925 if ( ( tempKappaP - status->giveKappaP() ) < 0. ) {
926 tempKappaP = tempKappaPTest;
927 }
928
929 tempVolumetricPlasticStrain -= answerIncrement [ 0 ] / ( kM );
930 tempDeviatoricPlasticStrainNorm -= answerIncrement [ 1 ] / ( 2. * gM );
931 }
932
933 //if (gp->giveElement()->giveNumber() == 1301){
934 // printf("%g %g %g\n",sig,rho,tempKappaP);
935 //}
936 }
937
938 status->letTempVolumetricPlasticStrainBe(tempVolumetricPlasticStrain / 3.);
939 if ( deltaLambda < 0 ) {
940 printf("deltaLambda = %e\n", deltaLambda);
941 printf("plastic multiplier less than zero");
942 }
943
944 // printf("\nnumber of iterations = %i\n", iterationCount);
945 status->letDeltaLambdaBe(deltaLambda);
946 FloatArrayF< 6 >stressPrincipal;
947 stressPrincipal [ 0 ] = sig + sqrt(2. / 3.) * rho * cos(theta);
948 stressPrincipal [ 1 ] = sig + sqrt(2. / 3.) * rho * cos(theta - 2. * M_PI / 3.);
949 stressPrincipal [ 2 ] = sig + sqrt(2. / 3.) * rho * cos(theta + 2. * M_PI / 3.);
950
951 effectiveStress = transformStressVectorTo(stressPrincipalDir, stressPrincipal, 1);
952
953 // PH
954 status->letTempKappaPBe(tempKappaP);
955}
956
957void
959 double apexStress,
960 GaussPoint *gp) const
961{
962 auto status = static_cast< ConcreteDPMStatus * >( this->giveStatus(gp) );
963 double sig2 = 0.;
964
965 //auto [deviatoricStressTrial, sigTrial] = this->computeDeviatoricVolumetricSplit(effectiveStress); // c++17
966 auto tmp = this->computeDeviatoricVolumetricSplit(effectiveStress);
967 auto deviatoricStressTrial = tmp.first;
968 auto sigTrial = tmp.second;
969
970 const double rhoTrial = computeSecondCoordinate(deviatoricStressTrial);
971
972 double tempKappaP = status->giveTempKappaP();
973 const double kappaInitial = tempKappaP;
974
975 if ( status->giveTempVertexType() == ConcreteDPMStatus::VT_Tension ) {
976 sig2 = -0.1 * ft;
977 } else if ( status->giveTempVertexType() == ConcreteDPMStatus::VT_Compression ) {
978 sig2 = apexStress;
979 }
980
981 tempKappaP = computeTempKappa(kappaInitial, sigTrial, rhoTrial, sigTrial);
982
983 double yieldValue = computeYieldValue(sigTrial, 0., 0., tempKappaP);
984
985 tempKappaP = computeTempKappa(kappaInitial, sigTrial, rhoTrial, sig2);
986
987 double yieldValueMid = computeYieldValue(sig2, 0., 0., tempKappaP);
988
989 if ( yieldValue * yieldValueMid >= 0. ) {
990 status->letTempVertexTypeBe(ConcreteDPMStatus::VT_Regular);
991 return;
992 }
993
994 double sigAnswer;
995 double ratioPotential;
996
997 double dSig;
998 if ( yieldValue < 0.0 ) {
999 dSig = sig2 - sigTrial;
1000 sigAnswer = sig2;
1001 } else {
1002 dSig = sigTrial - sig2;
1003 sigAnswer = sig2;
1004 }
1005
1006 for ( int j = 0; j < 250; j++ ) {
1007 dSig = 0.5 * dSig;
1008
1009 double sigMid = sigAnswer + dSig;
1010
1011
1012 tempKappaP = computeTempKappa(kappaInitial, sigTrial, rhoTrial, sigMid);
1013
1014 yieldValueMid = computeYieldValue(sigMid, 0., 0., tempKappaP);
1015
1016 if ( yieldValueMid <= 0. ) {
1017 sigAnswer = sigMid;
1018 }
1019
1020 if ( fabs(yieldValueMid) < yieldTol && yieldValueMid <= 0. ) {
1021 for ( int i = 0; i < 3; i++ ) {
1022 effectiveStress [ i ] = sigAnswer;
1023 }
1024
1025 for ( int i = 3; i < effectiveStress.giveSize(); i++ ) {
1026 effectiveStress [ i ] = 0.;
1027 }
1028
1029 ratioPotential = computeRatioPotential(sigAnswer, tempKappaP);
1030
1031 double ratioTrial = rhoTrial / ( sigTrial - sigAnswer );
1032
1033
1034 if ( ( ( ( ratioPotential >= ratioTrial ) && status->giveTempVertexType() == ConcreteDPMStatus::VT_Tension ) ) ||
1035 ( ( ratioPotential <= ratioTrial ) && status->giveTempVertexType() == ConcreteDPMStatus::VT_Compression ) ) {
1036 return;
1037 } else {
1038 status->letTempVertexTypeBe(ConcreteDPMStatus::VT_Regular);
1039 return;
1040 }
1041 }
1042 }
1043
1044 status->letTempVertexTypeBe(ConcreteDPMStatus::VT_Regular);
1045 // PH
1046 status->letTempKappaPBe(tempKappaP);
1047}
1048
1049
1050double
1051ConcreteDPM::computeTempKappa(const double kappaInitial,
1052 const double sigTrial,
1053 const double rhoTrial,
1054 const double sig) const
1055{
1056 //This function is called, if stress state is in vertex case
1057 double equivalentDeltaPlasticStrain = sqrt(1. / 9. * pow( ( sigTrial - sig ) / ( kM ), 2. ) + pow(rhoTrial / ( 2. * gM ), 2.) );
1058
1059 double rho = 0.;
1060 double thetaVertex = 0.;
1061 double ductilityMeasure = computeDuctilityMeasure(sig, rho, thetaVertex);
1062
1063 return kappaInitial + equivalentDeltaPlasticStrain / ductilityMeasure;
1064}
1065
1066
1067double
1069 const double rho,
1070 const double theta,
1071 const double tempKappa) const
1072{
1073 //compute yieldHard
1074 const double yieldHardOne = computeHardeningOne(tempKappa);
1075 const double yieldHardTwo = computeHardeningOne(tempKappa);
1076
1077 // compute elliptic function r
1078 const double rFunction = ( 4. * ( 1. - pow(ecc, 2.) ) * pow(cos(theta), 2.) +
1079 pow( ( 2. * ecc - 1. ), 2. ) ) /
1080 ( 2. * ( 1. - pow(ecc, 2.) ) * cos(theta) +
1081 ( 2. * ecc - 1. ) * sqrt(4. * ( 1. - pow(ecc, 2.) ) * pow(cos(theta), 2.)
1082 + 5. * pow(ecc, 2.) - 4. * ecc) );
1083
1084 //compute help function Al
1085 const double Al = ( 1. - yieldHardOne ) * pow( ( sig / fc + rho / ( sqrt(6.) * fc ) ), 2. ) +
1086 sqrt(3. / 2.) * rho / fc;
1087
1088 //Compute yield equation
1089 return pow(Al, 2.) +
1090 pow(yieldHardOne, 2.) * m * ( sig / fc + rho * rFunction / ( sqrt(6.) * fc ) ) -
1091 pow(yieldHardTwo, 2.);
1092}
1093
1094
1095double
1097 const double rho,
1098 const double theta,
1099 const double tempKappa) const
1100{
1101 // const double theta = thetaTrial;
1102 //compute yieldHard and yieldSoft
1103 const double yieldHardOne = computeHardeningOne(tempKappa);
1104 const double yieldHardTwo = computeHardeningOne(tempKappa);
1105 // compute the derivative of the hardening and softening laws
1106 const double dYieldHardOneDKappa = computeHardeningOnePrime(tempKappa);
1107 const double dYieldHardTwoDKappa = computeHardeningOnePrime(tempKappa);
1108
1109 //compute elliptic function r
1110 const double rFunction =
1111 ( 4. * ( 1. - ecc * ecc ) * cos(theta) * cos(theta) + ( 2. * ecc - 1. ) * ( 2. * ecc - 1. ) ) /
1112 ( 2 * ( 1. - ecc * ecc ) * cos(theta) + ( 2. * ecc - 1. ) *
1113 sqrt(4. * ( 1. - ecc * ecc ) * cos(theta) * cos(theta) + 5. * ecc * ecc - 4. * ecc) );
1114
1115 //compute help functions Al, Bl
1116 const double Al = ( 1. - yieldHardOne ) * pow( ( sig / fc + rho / ( sqrt(6.) * fc ) ), 2. ) + sqrt(3. / 2.) * rho / fc;
1117
1118 const double Bl = sig / fc + rho / ( fc * sqrt(6.) );
1119
1120 const double dFDYieldHardOne = -2. * Al * pow(Bl, 2.)
1121 + 2. * yieldHardOne * m * ( sig / fc + rho * rFunction / ( sqrt(6.) * fc ) );
1122
1123 const double dFDYieldHardTwo = -2. * yieldHardTwo;
1124
1125 // compute dFDKappa
1126 double dFDKappa = dFDYieldHardOne * dYieldHardOneDKappa +
1127 dFDYieldHardTwo * dYieldHardTwoDKappa;
1128 /*
1129 * set dFDKappa to zero, if it becomes greater than zero.
1130 * dFDKappa can only be negative or zero in the converged state for
1131 * the case of hardenig and perfect plasticity. For trial stresses, however,
1132 * it might be negative, which may lead to convergency problems. Therefore,
1133 * it is set to zero in this cases.
1134 */
1135 if ( dFDKappa > 0. ) {
1136 dFDKappa = 0.;
1137 }
1138
1139 return dFDKappa;
1140}
1141
1144 const double rho,
1145 const double theta,
1146 const double tempKappa) const
1147{
1148 // const double theta = thetaTrial;
1149
1150 //compute yieldHard
1151 const double yieldHardOne = computeHardeningOne(tempKappa);
1152
1153 //compute elliptic function r
1154 const double rFunction = ( 4. * ( 1. - ecc * ecc ) * cos(theta) * cos(theta) + ( 2. * ecc - 1. ) * ( 2. * ecc - 1. ) ) /
1155 ( 2. * ( 1. - ecc * ecc ) * cos(theta) + ( 2. * ecc - 1. ) * sqrt(4. * ( 1. - ecc * ecc ) * cos(theta) * cos(theta)
1156 + 5. * ecc * ecc - 4. * ecc) );
1157
1158 //compute help functions AL, BL
1159 const double AL = ( 1. - yieldHardOne ) * pow( ( sig / fc + rho / ( sqrt(6.) * fc ) ), 2. ) + sqrt(3. / 2.) * rho / fc;
1160 const double BL = sig / fc + rho / ( fc * sqrt(6.) );
1161
1162 //compute dfdsig
1163 const double dfdsig = 4. * ( 1. - yieldHardOne ) / fc * AL * BL + yieldHardOne * yieldHardOne * m / fc;
1164 //compute dfdrho
1165 const double dfdrho = AL / ( sqrt(6.) * fc ) * ( 4. * ( 1. - yieldHardOne ) * BL + 6. ) + rFunction * m * yieldHardOne * yieldHardOne / ( sqrt(6.) * fc );
1166
1167 return {
1168 dfdsig, dfdrho
1169 };
1170}
1171
1172double
1174 const double rho,
1175 const double theta,
1176 const double tempKappa) const
1177{
1178 //Variables
1179 auto dGDInv = computeDGDInv(sig, rho, tempKappa);
1180
1181 double equivalentDGDStress = sqrt(1. / 3. * pow(dGDInv [ 0 ], 2.) +
1182 pow(dGDInv [ 1 ], 2.) );
1183
1184 double ductilityMeasure = computeDuctilityMeasure(sig, rho, theta);
1185 double dKappaDDeltaLambda = equivalentDGDStress / ductilityMeasure;
1186 return dKappaDDeltaLambda;
1187}
1188
1189
1192 const double rho,
1193 const double theta,
1194 const double tempKappa) const
1195{
1196 //Compute first and second derivative of plastic potential
1197 auto dGDInv = computeDGDInv(sig, rho, tempKappa);
1198 auto dDGDDInv = computeDDGDDInv(sig, rho, tempKappa);
1199
1200 //Compute equivalentDGDStress
1201 double equivalentDGDStress = sqrt(1. / 3. * pow(dGDInv [ 0 ], 2.) +
1202 pow(dGDInv [ 1 ], 2.) );
1203
1204 //computeDuctilityMeasure
1205 double ductilityMeasure = computeDuctilityMeasure(sig, rho, theta);
1206
1207 //Compute dEquivalentDGDStressDInv
1208 FloatArrayF< 2 >dEquivalentDGDStressDInv;
1209 dEquivalentDGDStressDInv [ 0 ] =
1210 ( 2. / 3. * dGDInv [ 0 ] * dDGDDInv(0, 0) + 2. * dGDInv [ 1 ] * dDGDDInv(1, 0) ) / ( 2. * equivalentDGDStress );
1211 dEquivalentDGDStressDInv [ 1 ] =
1212 ( 2. / 3. * dGDInv [ 0 ] * dDGDDInv(0, 1) + 2. * dGDInv [ 1 ] * dDGDDInv(1, 1) ) / ( 2. * equivalentDGDStress );
1213
1214 // compute the derivative of
1215 auto dDuctilityMeasureDInv = computeDDuctilityMeasureDInv(sig, rho, theta, tempKappa);
1216
1217 FloatArrayF< 2 >answer;
1218 answer [ 0 ] = ( dEquivalentDGDStressDInv [ 0 ] * ductilityMeasure - equivalentDGDStress * dDuctilityMeasureDInv [ 0 ] ) / pow(ductilityMeasure, 2.);
1219 answer [ 1 ] = ( dEquivalentDGDStressDInv [ 1 ] * ductilityMeasure - equivalentDGDStress * dDuctilityMeasureDInv [ 1 ] ) / pow(ductilityMeasure, 2.);
1220 return answer;
1221}
1222
1223double
1225 const double rho,
1226 const double theta,
1227 const double tempKappa) const
1228{
1229 //Compute first and second derivative of plastic potential
1230 auto dGDInv = computeDGDInv(sig, rho, tempKappa);
1231 auto dDGDInvDKappa = computeDDGDInvDKappa(sig, rho, tempKappa);
1232
1233 double equivalentDGDStress = sqrt(1. / 3. * pow(dGDInv [ 0 ], 2.) + pow(dGDInv [ 1 ], 2.) );
1234
1235 //computeDuctilityMeasure
1236 double ductilityMeasure = computeDuctilityMeasure(sig, rho, theta);
1237
1238 //Compute dEquivalentDGDStressDKappa
1239 double dEquivalentDGDStressDKappa =
1240 ( 2. / 3. * dGDInv [ 0 ] * dDGDInvDKappa [ 0 ] + 2. * dGDInv [ 1 ] * dDGDInvDKappa [ 1 ] ) / ( 2. * equivalentDGDStress );
1241
1242 // compute the derivative of
1243 double dDuctilityMeasureDKappa = 0.;
1244
1245 double dDKappaDDeltaLambdaDKappa =
1246 ( dEquivalentDGDStressDKappa * ductilityMeasure -
1247 equivalentDGDStress * dDuctilityMeasureDKappa ) / pow(ductilityMeasure, 2.);
1248
1249 return dDKappaDDeltaLambdaDKappa;
1250}
1251
1252double
1254 const double rho,
1255 const double theta) const
1256{
1257 double thetaConst = pow(2. * cos(theta), 2.);
1258 double ductilityMeasure;
1259 double x = -( sig + fc / 3 ) / fc;
1260 if ( x < 0. ) {
1261 /*Introduce exponential help function which results in a smooth
1262 * transition. */
1263 double fZero = BHard;
1264 double fPrimeZero = -( BHard - AHard ) / ( CHard );
1265 double CHelp = DHard;
1266 double AHelp = fZero - CHelp;
1267 double BHelp = ( fZero - CHelp ) / fPrimeZero;
1268 ductilityMeasure = ( AHelp * exp(x / BHelp) + CHelp ) / thetaConst;
1269 } else {
1270 ductilityMeasure = ( AHard + ( BHard - AHard ) * exp(-x / ( CHard ) ) ) / thetaConst;
1271 }
1272
1273 if ( ductilityMeasure <= 0. ) {
1274 printf("ductilityMeasure is zero or negative");
1275 }
1276
1277 return ductilityMeasure;
1278}
1279
1282 const double rho,
1283 const double theta,
1284 const double tempKappa) const
1285{
1286 double thetaConst = pow(2. * cos(theta), 2.);
1287 double x = ( -( sig + fc / 3 ) ) / fc;
1288 if ( x < 0. ) {
1289 double dXDSig = -1. / fc;
1290 /* Introduce exponential help function which results in a
1291 * smooth transition. */
1292 double fZero = BHard;
1293 double fPrimeZero = -( BHard - AHard ) / ( CHard );
1294 double CHelp = DHard;
1295 double AHelp = fZero - CHelp;
1296 double BHelp = ( fZero - CHelp ) / fPrimeZero;
1297 double dDuctilityMeasureDX = AHelp / BHelp * exp(x / BHelp) / thetaConst;
1298 return {
1299 dDuctilityMeasureDX *dXDSig, 0.
1300 };
1301 } else {
1302 double dXDSig = -1. / fc;
1303 double dDuctilityMeasureDX = -( BHard - AHard ) / ( CHard ) / thetaConst * exp(-x / ( CHard ) );
1304 return {
1305 dDuctilityMeasureDX *dXDSig, 0.
1306 };
1307 }
1308}
1309
1310
1313 const double rho,
1314 const double tempKappa) const
1315{
1316 //Compute dilation parameter
1317 const double R = ( sig - ft / 3. ) / fc;
1318 const double mQTension = ( 3. * ft / fc + m / 2. );
1319 const double mQCompression =
1320 ( 1. + 2. * dilationConst ) / ( dilationConst - 1. ) * ( 3. + m / 2. );
1321 const double AConst = -( ft + fc ) / ( 3. * fc ) / log(mQCompression / mQTension);
1322 const double mQ = mQTension * exp(R / AConst);
1323
1324 //compute yieldHard and yieldSoft
1325 const double yieldHardOne = computeHardeningOne(tempKappa);
1326
1327 const double Bl = sig / fc + rho / ( fc * sqrt(6.) );
1328
1329 const double Al = ( 1. - yieldHardOne ) * pow(Bl, 2.) + sqrt(3. / 2.) * rho / fc;
1330
1331 const double dgdsig = 4. * ( 1. - yieldHardOne ) / fc * Al * Bl + yieldHardOne * yieldHardOne * mQ / fc;
1332
1333 const double dgdrho = Al / ( sqrt(6.) * fc ) * ( 4. * ( 1. - yieldHardOne ) * Bl + 6. ) +
1334 m * pow(yieldHardOne, 2.) / ( sqrt(6.) * fc );
1335
1336 return {
1337 dgdsig, dgdrho
1338 };
1339}
1340
1341
1342double
1344 const double tempKappa) const
1345{
1346 //Compute dilation parameter
1347 const double R = ( sig - ft / 3. ) / fc;
1348 const double mQTension = ( 3. * ft / fc + m / 2. );
1349 const double mQCompression =
1350 ( 1. + 2. * dilationConst ) / ( dilationConst - 1. ) * ( 3. + m / 2. );
1351 const double AConst = -( ft + fc ) / ( 3. * fc ) / log(mQCompression / mQTension);
1352 const double mQ = mQTension * exp(R / AConst);
1353
1354 //compute yieldHard and yieldSoft
1355 const double yieldHardOne = computeHardeningOne(tempKappa);
1356
1357 const double Bl = sig / fc;
1358
1359 const double Al = ( 1. - yieldHardOne ) * pow(Bl, 2.);
1360
1361 const double dgdsig = 4. * ( 1. - yieldHardOne ) / fc * Al * Bl + yieldHardOne * yieldHardOne * mQ / fc;
1362
1363 const double dgdrho = Al / ( sqrt(6.) * fc ) * ( 4. * ( 1. - yieldHardOne ) * Bl + 6. ) +
1364 m * pow(yieldHardOne, 2.) / ( sqrt(6.) * fc );
1365
1366 /* Debug: Introduce the factor 2G/K. I am not sure if this is correct.
1367 * There might be too many stress states in the vertex case. */
1368 return dgdrho / dgdsig * 3. * ( 1. - 2. * nu ) / ( 1. + nu );
1369}
1370
1371
1374 const double rho,
1375 const double tempKappa) const
1376{
1377 //Compute dilation parameter
1378 const double R = ( sig - ft / 3. ) / fc;
1379 const double mQTension = ( 3. * ft / fc + m / 2. );
1380 const double mQCompression =
1381 ( 1. + 2. * dilationConst ) / ( dilationConst - 1. ) * ( 3. + m / 2. );
1382 const double AConst = -( ft + fc ) / ( 3. * fc ) / log(mQCompression / mQTension);
1383 const double mQ = mQTension * exp(R / AConst);
1384
1385 //compute yieldHard and yieldSoft
1386 const double yieldHardOne = computeHardeningOne(tempKappa);
1387 const double dYieldHardOneDKappa = computeHardeningOnePrime(tempKappa);
1388
1389 const double Bl = sig / fc + rho / ( fc * sqrt(6.) );
1390
1391 const double Al = ( 1. - yieldHardOne ) * pow(Bl, 2.) + sqrt(3. / 2.) * rho / fc;
1392
1393 const double dAlDYieldHard = -pow(Bl, 2.);
1394
1395 const double dDGDSigDKappa =
1396 ( -4. * Al * Bl / fc + 4. * ( 1 - yieldHardOne ) / fc * dAlDYieldHard * Bl +
1397 2. * yieldHardOne * mQ / fc ) * dYieldHardOneDKappa;
1398
1399 const double dDGDRhoDKappa =
1400 ( dAlDYieldHard / ( sqrt(6.) * fc ) * ( 4. * ( 1. - yieldHardOne ) * Bl + 6. ) -
1401 4. * Al / ( sqrt(6.) * fc ) * Bl + 2. * m * yieldHardOne / ( sqrt(6.) * fc ) ) * dYieldHardOneDKappa;
1402
1403 return {
1404 dDGDSigDKappa, dDGDRhoDKappa
1405 };
1406}
1407
1410 const double rho,
1411 const double tempKappa) const
1412{
1413 //Compute dilation parameter
1414 const double R = ( sig - ft / 3. ) / fc;
1415 const double mQTension = ( 3. * ft / fc + m / 2. );
1416 const double mQCompression =
1417 ( 1. + 2. * dilationConst ) / ( dilationConst - 1. ) * ( 3. + m / 2. );
1418 const double AConst = -( ft + fc ) / ( 3. * fc ) / log(mQCompression / mQTension);
1419 // const double mQ = mQTension*exp(R/AConst);
1420 const double dMQDSig = mQTension / ( AConst * fc ) * exp(R / AConst);
1421
1422 //compute yieldHardOne and yieldSoft
1423 const double yieldHardOne = computeHardeningOne(tempKappa);
1424
1425 //compute help parameter Al and Bl and the corresponding derivatives
1426 const double Bl = sig / fc + rho / ( fc * sqrt(6.) );
1427
1428 const double Al = ( 1. - yieldHardOne ) * pow(Bl, 2.) +
1429 sqrt(3. / 2.) * rho / fc;
1430
1431 const double dAlDSig = 2. * ( 1. - yieldHardOne ) * Bl / fc;
1432 const double dBlDSig = 1. / fc;
1433
1434 const double dAlDRho = 2. * ( 1. - yieldHardOne ) * Bl / ( fc * sqrt(6.) ) + sqrt(3. / 2.) / fc;
1435 const double dBlDRho = 1. / ( fc * sqrt(6.) );
1436
1437 //compute second derivatives of g
1438 const double ddgddSig = 4. * ( 1. - yieldHardOne ) / fc * ( dAlDSig * Bl + Al * dBlDSig ) +
1439 yieldHardOne * yieldHardOne * dMQDSig / fc;
1440
1441 const double ddgddRho = dAlDRho / ( sqrt(6.) * fc ) * ( 4. * ( 1. - yieldHardOne ) * Bl + 6. ) +
1442 Al * dBlDRho * 4. * ( 1. - yieldHardOne ) / ( sqrt(6.) * fc );
1443
1444 const double ddgdSigdRho = 4. * ( 1. - yieldHardOne ) / fc * ( dAlDRho * Bl + Al * dBlDRho );
1445
1446 const double ddgdRhodSig = dAlDSig / ( sqrt(6.) * fc ) * ( 4. * ( 1. - yieldHardOne ) * Bl + 6. )
1447 + Al / ( sqrt(6.) * fc ) * ( 4. * ( 1. - yieldHardOne ) * dBlDSig );
1448
1450 answer(0, 0) = ddgddSig;
1451 answer(0, 1) = ddgdSigdRho;
1452 answer(1, 0) = ddgdRhodSig;
1453 answer(1, 1) = ddgddRho;
1454 return answer;
1455}
1456
1459 const double rho,
1460 const double theta,
1461 const double tempKappa,
1462 const double deltaLambda) const
1463{
1464 auto dDGDDInv = computeDDGDDInv(sig, rho, tempKappa);
1465 auto dDKappaDDeltaLambdaDInv = computeDDKappaDDeltaLambdaDInv(sig, rho, theta, tempKappa);
1466 auto dDKappaDDeltaLambdaDKappa = computeDDKappaDDeltaLambdaDKappa(sig, rho, theta, tempKappa);
1467 auto dDGDInvDKappa = computeDDGDInvDKappa(sig, rho, tempKappa);
1468
1469 FloatMatrixF< 3, 3 >aMatrixInverse;
1470 aMatrixInverse(0, 0) = 1. / ( kM ) + deltaLambda * dDGDDInv(0, 0);
1471 aMatrixInverse(0, 1) = deltaLambda * dDGDDInv(0, 1);
1472 aMatrixInverse(0, 2) = deltaLambda * dDGDInvDKappa [ 0 ];
1473
1474 aMatrixInverse(1, 0) = deltaLambda * dDGDDInv(1, 0);
1475 aMatrixInverse(1, 1) = 1. / ( 2. * gM ) + deltaLambda * dDGDDInv(1, 1);
1476 aMatrixInverse(1, 2) = deltaLambda * dDGDInvDKappa [ 1 ];
1477
1478 aMatrixInverse(2, 0) = deltaLambda * dDKappaDDeltaLambdaDInv [ 0 ];
1479 aMatrixInverse(2, 1) = deltaLambda * dDKappaDDeltaLambdaDInv [ 1 ];
1480 aMatrixInverse(2, 2) = -1. + deltaLambda * dDKappaDDeltaLambdaDKappa;
1481
1482 return inv(aMatrixInverse);
1483}
1484
1485
1486
1487double
1488ConcreteDPM::computeHardeningOne(const double kappa) const
1489{
1490 if ( kappa <= 0. ) {
1491 return yieldHardInitial;
1492 } else if ( kappa > 0. && kappa < 1. ) {
1493 return yieldHardInitial + ( 1. - yieldHardInitial ) *
1494 kappa * ( pow(kappa, 2.) - 3. * kappa + 3. );
1495 } else {
1496 return 1.;
1497 }
1498}
1499
1500
1501double
1503{
1504 if ( kappa < 0. ) {
1505 return 3. * ( 1. - yieldHardInitial );
1506 } else if ( kappa >= 0. && kappa < 1. ) {
1507 return ( 1. - yieldHardInitial ) * ( 3. * pow(kappa, 2.) - 6. * kappa + 3. );
1508 } else {
1509 return 0.;
1510 }
1511}
1512
1515 GaussPoint *gp,
1516 TimeStep *tStep) const
1517{
1518 auto status = giveConcreteDPMStatus(gp);
1519 auto d = this->linearElasticMaterial.give3dMaterialStiffnessMatrix(mode, gp, tStep);
1520 if ( mode == SecantStiffness || mode == TangentStiffness ) {
1521 double omega = status->giveTempDamage();
1522 if ( omega > 0.9999 ) {
1523 omega = 0.9999;
1524 }
1525
1526 return d * ( 1. - omega );
1527 } else {
1528 return d;
1529 }
1530}
1531
1532
1533std::tuple< double, double, double >
1535{
1536 //auto [deviatoricStress, sig] = this->computeDeviatoricVolumetricSplit(stress); // c++17
1537 auto tmp = this->computeDeviatoricVolumetricSplit(stress);
1538 auto deviatoricStress = tmp.first;
1539 double sig = tmp.second;
1540 double rho = computeSecondCoordinate(deviatoricStress);
1541 double thetaTrial = computeThirdCoordinate(deviatoricStress);
1542 return std::tuple< double, double, double > {
1543 sig, rho, thetaTrial
1544 };
1545}
1546
1547
1548void
1550{
1551 auto status = giveConcreteDPMStatus(gp);
1552 //Get kappaD from status to define state later on
1553 const auto &damage = status->giveDamage();
1554 const auto &tempDamage = status->giveTempDamage();
1555 const auto &kappaP = status->giveKappaP();
1556 const auto &tempKappaP = status->giveTempKappaP();
1557
1558 if ( tempKappaP > kappaP ) {
1559 if ( tempDamage > damage ) {
1560 status->
1562 } else {
1563 status->letTempStateFlagBe(ConcreteDPMStatus::ConcreteDPM_Plastic);
1564 }
1565 } else {
1566 const int state_flag = status->giveStateFlag();
1567 if ( state_flag == ConcreteDPMStatus::ConcreteDPM_Elastic ) {
1568 if ( tempDamage > damage ) {
1569 status->
1570 letTempStateFlagBe(ConcreteDPMStatus::ConcreteDPM_Damage);
1571 } else {
1572 status->
1573 letTempStateFlagBe(ConcreteDPMStatus::ConcreteDPM_Elastic);
1574 }
1575 } else {
1576 if ( tempDamage > damage ) {
1577 status->
1578 letTempStateFlagBe(ConcreteDPMStatus::ConcreteDPM_Damage);
1579 } else {
1580 status->
1581 letTempStateFlagBe(ConcreteDPMStatus::ConcreteDPM_Unloading);
1582 }
1583 }
1584 }
1585}
1586
1589{
1590 //compute volumetric deviatoric split
1591 auto deviatoricStress = this->computeDeviator(stress);
1592 double rho = computeSecondCoordinate(deviatoricStress);
1593
1594 //compute the derivative of J2 with respect to the stress
1595 auto dJ2DStress = deviatoricStress;
1596 for ( int i = 3; i < 6; i++ ) {
1597 dJ2DStress [ i ] = deviatoricStress [ i ] * 2.0;
1598 }
1599
1600 //compute the derivative of rho with respect to stress
1601 auto dRhoDStress = dJ2DStress * ( 1. / rho );
1602 return dRhoDStress;
1603}
1604
1605void
1607{
1608 int size = 6;
1609 for ( int i = 0; i < 3; i++ ) {
1610 answer [ i ] = 1. / 3.;
1611 }
1612
1613 for ( int i = 3; i < size; i++ ) {
1614 answer [ i ] = 0.;
1615 }
1616}
1617
1618
1621{
1622 //compute volumetric deviatoric split
1623 auto deviatoricStress = this->computeDeviator(stress);
1624 double rho = computeSecondCoordinate(deviatoricStress);
1625
1626 //compute first derivative of J2
1627 auto dJ2dstress = deviatoricStress;
1628 for ( int i = 3; i < 6; i++ ) {
1629 dJ2dstress [ i ] = deviatoricStress [ i ] * 2.;
1630 }
1631
1632 //compute second derivative of J2
1633 FloatMatrixF< 6, 6 >ddJ2ddstress;
1634 for ( int i = 0; i < 6; i++ ) {
1635 if ( i < 3 ) {
1636 ddJ2ddstress(i, i) = 2. / 3.;
1637 }
1638
1639 if ( i > 2 ) {
1640 ddJ2ddstress(i, i) = 2.;
1641 }
1642 }
1643
1644 ddJ2ddstress(0, 1) = -1. / 3.;
1645 ddJ2ddstress(0, 2) = -1. / 3.;
1646 ddJ2ddstress(1, 0) = -1. / 3.;
1647 ddJ2ddstress(1, 2) = -1. / 3.;
1648 ddJ2ddstress(2, 0) = -1. / 3.;
1649 ddJ2ddstress(2, 1) = -1. / 3.;
1650
1651 //compute square of the first derivative of J2
1652 auto dJ2DJ2 = dyad(dJ2dstress, dJ2dstress);
1653
1654 //compute the second derivative of rho
1655 auto ddRhoddStress = ddJ2ddstress * ( 1. / rho ) + dJ2DJ2 * ( -1. / ( rho * rho * rho ) );
1656 return ddRhoddStress;
1657}
1658
1661{
1662 //compute volumetric deviatoric split
1663 auto deviatoricStress = computeDeviator(stress);
1664
1665 //compute the coordinates
1666 double rho = computeSecondCoordinate(deviatoricStress);
1667
1668 //compute principal stresses and directions
1669 //auto [principalDeviatoricStress, principalDir] = computePrincipalValDir(from_voigt_stress(deviatoricStress)); // c++17
1670 auto tmp = computePrincipalValDir(from_voigt_stress_6(deviatoricStress) );
1671 auto principalDeviatoricStress = tmp.first;
1672 auto principalDir = tmp.second;
1673
1674 //compute the derivative of s1 with respect to the cartesian stress
1675 FloatArrayF< 6 >ds1DStress;
1676 ds1DStress [ 0 ] = principalDir(0, 0) * principalDir(0, 0) - 1. / 3.;
1677 ds1DStress [ 1 ] = principalDir(1, 0) * principalDir(1, 0) - 1. / 3.;
1678 ds1DStress [ 2 ] = principalDir(2, 0) * principalDir(2, 0) - 1. / 3.;
1679 ds1DStress [ 3 ] = 2. * principalDir(1, 0) * principalDir(2, 0);
1680 ds1DStress [ 4 ] = 2. * principalDir(2, 0) * principalDir(0, 0);
1681 ds1DStress [ 5 ] = 2. * principalDir(0, 0) * principalDir(1, 0);
1682
1683 //compute dCosThetaDStress
1684 auto dCosThetaDStress = ds1DStress * ( sqrt(3. / 2.) * rho / pow(rho, 2.) ) +
1685 computeDRhoDStress(stress) * ( -sqrt(3. / 2.) * principalDeviatoricStress [ 0 ] / pow(rho, 2.) );
1686 return dCosThetaDStress;
1687}
1688
1689double
1690ConcreteDPM::computeDRDCosTheta(const double theta, const double ecc) const
1691{
1692 double ACostheta = 4. * ( 1. - ecc * ecc ) * cos(theta) * cos(theta) +
1693 ( 2. * ecc - 1. ) * ( 2. * ecc - 1. );
1694 double BCostheta = 2. * ( 1. - ecc * ecc ) * cos(theta) +
1695 ( 2. * ecc - 1. ) * sqrt(4. * ( 1. - ecc * ecc ) * cos(theta) * cos(theta)
1696 + 5. * ecc * ecc - 4. * ecc);
1697 double A1Costheta = 8. * ( 1. - pow(ecc, 2.) ) * cos(theta);
1698 double B1Costheta = 2. * ( 1. - pow(ecc, 2.) ) +
1699 4. * ( 2. * ecc - 1. ) * ( 1. - pow(ecc, 2.) ) * cos(theta) /
1700 sqrt(4. * ( 1. - pow(ecc, 2.) ) * pow(cos(theta), 2.) +
1701 5. * pow(ecc, 2.) - 4. * ecc);
1702 double dRDCostheta = A1Costheta / BCostheta - ACostheta / pow(BCostheta, 2.) * B1Costheta;
1703 return dRDCostheta;
1704}
1705
1706
1707void
1709{
1710 auto status = giveConcreteDPMStatus(gp);
1711
1712 // compute kappaD from damage
1713 double kappaD = this->computeInverseDamage(status->giveDamage(), gp);
1714 status->letKappaDBe(kappaD);
1715 status->letEquivStrainBe(kappaD);
1716
1717 const auto &damage = status->giveDamage();
1718
1719 // compute plastic strain
1720 // such that the given stress is obtained at zero total strain and given damage
1721 if ( damage < 1. ) {
1722 FloatArrayF< 6 >effectiveStress = status->giveStressVector();
1723 effectiveStress *= -1. / ( 1. - damage );
1724 auto D = this->give3dMaterialStiffnessMatrix(ElasticStiffness, gp, nullptr);
1725 auto plasticStrain = solve(D, effectiveStress);
1726 status->letPlasticStrainBe(plasticStrain);
1727 }
1728}
1729
1730
1731int
1733{
1734 auto status = giveConcreteDPMStatus(gp);
1735 if ( status->setIPValue(value, type) ) {
1736 return 1;
1737 } else {
1738 return StructuralMaterial::setIPValue(value, gp, type);
1739 }
1740}
1741
1742int
1744{
1745 const auto status = giveConcreteDPMStatus(gp);
1746 //int state_flag = status->giveStateFlag();
1747 //double stateFlagValue = 0.;
1748
1749 if ( type == IST_PlasticStrainTensor ) {
1750 answer = status->givePlasticStrain();
1751 return 1;
1752 } else if ( type == IST_DamageScalar ) {
1753 answer.resize(1);
1754 answer.at(1) = status->giveDamage();
1755 return 1;
1756 } else if ( type == IST_DamageTensor ) {
1757 answer.resize(6);
1758 answer.zero();
1759 answer.at(1) = answer.at(2) = answer.at(3) = status->giveDamage();
1760 return 1;
1761 } else if ( type == IST_PrincipalDamageTensor ) {
1762 answer.resize(3);
1763 answer.zero();
1764 answer.at(1) = answer.at(2) = answer.at(3) = status->giveDamage();
1765 return 1;
1766 } else if ( type == IST_DamageTensorTemp ) {
1767 answer.resize(1);
1768 answer.at(1) = status->giveTempDamage();
1769 return 1;
1770 } else if ( type == IST_CumPlasticStrain ) {
1771 answer.resize(1);
1772 answer.at(1) = status->giveKappaP();
1773 return 1;
1774 } else if ( type == IST_CumPlasticStrain_2 ) {
1775 answer.resize(1);
1776 answer.at(1) = status->giveKappaD();
1777 return 1;
1778 } else if ( type == IST_VolumetricPlasticStrain ) {
1779 answer.resize(1);
1780 answer.at(1) = status->giveVolumetricPlasticStrain();
1781 return 1;
1782 }
1783
1784 return StructuralMaterial::giveIPValue(answer, gp, type, tStep);
1785}
1786
1787std::unique_ptr<MaterialStatus>
1789{
1790 return std::make_unique<ConcreteDPMStatus>(gp);
1791}
1792
1793void
1795{
1796 StructuralMaterial::saveContext(stream, mode);
1797 if ( ( mode & CM_Definition ) ) {
1798 if ( !stream.write(fc) ) {
1800 }
1801 if ( !stream.write(ft) ) {
1803 }
1804 if ( !stream.write(ecc) ) {
1806 }
1807 if ( !stream.write(AHard) ) {
1809 }
1810 if ( !stream.write(BHard) ) {
1812 }
1813 if ( !stream.write(CHard) ) {
1815 }
1816 if ( !stream.write(DHard) ) {
1818 }
1819 if ( !stream.write(ASoft) ) {
1821 }
1822 if ( !stream.write(yieldHardInitial) ) {
1824 }
1825 if ( !stream.write(dilationConst) ) {
1827 }
1828 if ( !stream.write(m) ) {
1830 }
1831 if ( !stream.write(mQ) ) {
1833 }
1834 if ( !stream.write(helem) ) {
1836 }
1837 if ( !stream.write(eM) ) {
1839 }
1840 if ( !stream.write(gM) ) {
1842 }
1843 if ( !stream.write(kM) ) {
1845 }
1846 if ( !stream.write(nu) ) {
1848 }
1849 if ( !stream.write(ef) ) {
1851 }
1852 if ( !stream.write(yieldTol) ) {
1854 }
1855 if ( !stream.write(newtonIter) ) {
1857 }
1858 #ifdef SOPHISTICATED_SIZEDEPENDENT_ADJUSTMENT
1859 if ( !stream.write(href) ) {
1861 }
1862 #endif
1863 }
1864 linearElasticMaterial.saveContext(stream, mode);
1865}
1866
1867void
1869{
1871 if ( ( mode & CM_Definition ) ) {
1872 if ( !stream.read(fc) ) {
1874 }
1875 if ( !stream.read(ft) ) {
1877 }
1878 if ( !stream.read(ecc) ) {
1880 }
1881 if ( !stream.read(AHard) ) {
1883 }
1884 if ( !stream.read(BHard) ) {
1886 }
1887 if ( !stream.read(CHard) ) {
1889 }
1890 if ( !stream.read(DHard) ) {
1892 }
1893 if ( !stream.read(ASoft) ) {
1895 }
1896 if ( !stream.read(yieldHardInitial) ) {
1898 }
1899 if ( !stream.read(dilationConst) ) {
1901 }
1902 if ( !stream.read(m) ) {
1904 }
1905 if ( !stream.read(mQ) ) {
1907 }
1908 if ( !stream.read(helem) ) {
1910 }
1911 if ( !stream.read(eM) ) {
1913 }
1914 if ( !stream.read(gM) ) {
1916 }
1917 if ( !stream.read(kM) ) {
1919 }
1920 if ( !stream.read(nu) ) {
1922 }
1923 if ( !stream.read(ef) ) {
1925 }
1926 if ( !stream.read(yieldTol) ) {
1928 }
1929 if ( !stream.read(newtonIter) ) {
1931 }
1932 #ifdef SOPHISTICATED_SIZEDEPENDENT_ADJUSTMENT
1933 if ( !stream.read(href) ) {
1935 }
1936 #endif
1937 }
1938
1939 linearElasticMaterial.restoreContext(stream, mode);
1940}
1941
1942
1943
1944
1945} // end namespace oofem
#define E(a, b)
#define REGISTER_Material_Alt(class, altname)
#define REGISTER_Material(class)
void saveContext(DataStream &stream, ContextMode mode) override
ConcreteDPMStatus(GaussPoint *gp)
Constructor.
Definition concretedpm.C:54
FloatArrayF< 6 > tempPlasticStrain
void printOutputAt(FILE *file, TimeStep *tStep) const override
Print receiver's output to given stream.
int setIPValue(const FloatArray &value, InternalStateType type)
void initTempStatus() override
Definition concretedpm.C:65
void restoreContext(DataStream &stream, ContextMode mode) override
double giveEpsLoc() const
void updateYourself(TimeStep *tStep) override
Definition concretedpm.C:80
FloatArrayF< 6 > plasticStrain
double kM
Elastic bulk modulus.
void initDamaged(double kappa, const FloatArrayF< 6 > &elasticStrain, GaussPoint *gp) const
ConcreteDPMStatus * giveConcreteDPMStatus(GaussPoint *gp) const
IsotropicLinearElasticMaterial linearElasticMaterial
Linear elastic material.
double mQ
The dilation parameter of the plastic potential.
double ASoft
Parameter of the ductilityMeasure of the damage model.
double computeDDKappaDDeltaLambdaDKappa(double sig, double rho, double theta, double tempKappa) const
std::tuple< double, double, double > computeTrialCoordinates(const FloatArrayF< 6 > &stress, GaussPoint *gp) const
Compute the trial coordinates.
void restoreConsistency(GaussPoint *gp) override
double computeDFDKappa(double sig, double rho, double theta, double tempKappa) const
double yieldTol
Yield tolerance for the plasticity model.
FloatArrayF< 6 > computeDCosThetaDStress(const FloatArrayF< 6 > &stress) const
Computes the derivative of costheta with respect to the stress.
double helem
Element size (to be used in fracture energy approach (crack band).
double computeHardeningOne(double tempKappa) const
FloatArrayF< 6 > giveRealStressVector_3d(const FloatArrayF< 6 > &strain, GaussPoint *gp, TimeStep *tStep) const override
Default implementation relies on giveRealStressVector for second Piola-Kirchoff stress.
void checkForVertexCase(double &answer, double sig, double tempKappa, GaussPoint *gp) const
FloatMatrixF< 6, 6 > computeDDRhoDDStress(const FloatArrayF< 6 > &stress) const
Computes the second derivative of rho with the respect to the stress.
std::unique_ptr< MaterialStatus > CreateStatus(GaussPoint *gp) const override
FloatMatrixF< 3, 3 > computeAMatrix(double sig, double rho, double theta, double tempKappa, double deltaLambda) const
double dilationConst
Control parameter for te volumetric plastic flow of the plastic potential.
FloatArrayF< 6 > computeDRhoDStress(const FloatArrayF< 6 > &stress) const
Computes the derivative of rho with respect to the stress.
void performVertexReturn(FloatArrayF< 6 > &stress, double apexStress, GaussPoint *gp) const
double gM
Elastic shear modulus.
double computeTempKappa(double kappaInitial, double sigTrial, double rhoTrial, double sig) const
FloatArrayF< 2 > computeDDKappaDDeltaLambdaDInv(double sig, double rho, double theta, double tempKappa) const
virtual double computeDuctilityMeasure(double sig, double rho, double theta) const
double computeYieldValue(double sig, double rho, double theta, double tempKappa) const
FloatMatrixF< 6, 6 > give3dMaterialStiffnessMatrix(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const override
double computeDKappaDDeltaLambda(double sig, double rho, double theta, double tempKappa) const
double computeInverseDamage(double dam, GaussPoint *gp) const
Compute the damage-driving variable from given damage.
void restoreContext(DataStream &stream, ContextMode mode) override
void computeDSigDStress(FloatArrayF< 6 > &answer) const
Computes the derivative of sig with respect to the stress.
ConcreteDPM(int n, Domain *d)
Constructor.
void initializeFrom(InputRecord &ir) override
double AHard
Parameter of the ductilityMeasure of the plasticity model.
double computeRatioPotential(double sig, double tempKappa) const
int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep) override
double nu
Elastic Poisson's ration.
double m
Plastic multiplier of the plasticity model.
double computeDuctilityMeasureDamage(const FloatArrayF< 6 > &strain, GaussPoint *gp) const
Compute the ductility measure for the damage model.
double ef
Hardening variable of plasticity model.
FloatArrayF< 2 > computeDDGDInvDKappa(double sig, double rho, double tempKappa) const
std::pair< double, double > computeDamage(const FloatArrayF< 6 > &strain, GaussPoint *gp, TimeStep *tStep) const
double CHard
Parameter of the ductilityMeasure of the plasticity model.
int newtonIter
Maximum number of iterations for stress return.
double computeDRDCosTheta(double theta, double ecc) const
Compute the derivative of R with respect to costheta.
FloatArrayF< 2 > computeDGDInv(double sig, double rho, double tempKappa) const
FloatArrayF< 2 > computeDDuctilityMeasureDInv(double sig, double rho, double theta, double tempKappa) const
FloatArrayF< 2 > computeDFDInv(double sig, double rho, double theta, double tempKappa) const
int setIPValue(const FloatArray &value, GaussPoint *gp, InternalStateType type) override
double href
Stress and its deviatoric part.
virtual double computeDamageParam(double kappa, GaussPoint *gp) const
Compute damage parameter.
void assignStateFlag(GaussPoint *gp) const
Assign state flag.
double computeHardeningOnePrime(double tempKappa) const
double DHard
Parameter of the ductilityMeasure of the plasticity model.
void performPlasticityReturn(GaussPoint *gp, FloatArrayF< 6 > &strain) const
virtual double computeEquivalentStrain(const FloatArrayF< 6 > &elasticStrain, GaussPoint *gp, TimeStep *tStep) const
Compute equivalent strain value.
double eM
Elastic Young's modulus.
double BHard
Parameter of the ductilityMeasure of the plasticity model.
double yieldHardInitial
Parameter of the hardening law of the plasticity model.
void saveContext(DataStream &stream, ContextMode mode) override
FloatMatrixF< 2, 2 > computeDDGDDInv(double sig, double rho, double tempKappa) const
void performRegularReturn(FloatArrayF< 6 > &stress, GaussPoint *gp, double theta) const
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 computeMeanSize()
Definition element.C:1100
virtual double giveCharacteristicLength(const FloatArray &normalToCrackPlane)
Definition element.h:938
virtual void restoreContext(DataStream &stream, ContextMode mode)
Definition femcmpnn.C:62
virtual void saveContext(DataStream &stream, ContextMode mode)
Definition femcmpnn.C:51
double & at(std::size_t i)
int giveSize() const
Returns the size of receiver.
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
double dotProduct(const FloatArray &x) const
Definition floatarray.C:524
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
Element * giveElement()
Returns corresponding element to receiver.
Definition gausspoint.h:187
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
GaussPoint * gp
Associated integration point.
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Definition material.C:206
Dictionary propertyDictionary
Definition material.h:107
virtual double give(int aProperty, GaussPoint *gp) const
Definition material.C:51
void printOutputAt(FILE *file, TimeStep *tStep) const override
Print receiver's output to given stream.
void saveContext(DataStream &stream, ContextMode mode) override
StructuralMaterialStatus(GaussPoint *g)
Constructor. Creates new StructuralMaterialStatus with IntegrationPoint g.
void updateYourself(TimeStep *tStep) override
FloatArray tempStrainVector
Temporary strain vector in reduced form (to find balanced state).
FloatArray tempStressVector
Temporary stress vector in reduced form (increments are used mainly in nonlinear analysis).
FloatArray stressVector
Equilibrated stress vector in reduced form.
FloatArray strainVector
Equilibrated strain vector in reduced form.
void restoreContext(DataStream &stream, ContextMode mode) override
static double computeThirdCoordinate(const FloatArrayF< 6 > &s)
static FloatArrayF< 6 > applyElasticStiffness(const FloatArrayF< 6 > &strain, double EModulus, double nu)
static FloatArrayF< 6 > applyElasticCompliance(const FloatArrayF< 6 > &stress, double EModulus, double nu)
static void computePrincipalValues(FloatArray &answer, const FloatArray &s, stressStrainPrincMode mode)
Common functions for convenience.
void initializeFrom(InputRecord &ir) override
StructuralMaterial(int n, Domain *d)
static FloatArrayF< 6 > computeDeviator(const FloatArrayF< 6 > &s)
static void computePrincipalValDir(FloatArray &answer, FloatMatrix &dir, const FloatArray &s, stressStrainPrincMode mode)
int setIPValue(const FloatArray &value, GaussPoint *gp, InternalStateType type) override
int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep) override
static double computeSecondCoordinate(const FloatArrayF< 6 > &s)
static FloatArrayF< 6 > transformStressVectorTo(const FloatMatrixF< 3, 3 > &base, const FloatArrayF< 6 > &stress, bool transpose=false)
static std::pair< FloatArrayF< 6 >, double > computeDeviatoricVolumetricSplit(const FloatArrayF< 6 > &s)
FloatArrayF< 6 > computeStressIndependentStrainVector_3d(GaussPoint *gp, TimeStep *tStep, ValueModeType mode) const
#define DPM_DAMAGE_TOLERANCE
#define _IFT_ConcreteDPM_href
Definition concretedpm.h:64
#define _IFT_ConcreteDPM_dhard
Definition concretedpm.h:57
#define _IFT_ConcreteDPM_gf
Definition concretedpm.h:63
#define _IFT_ConcreteDPM_fc
Definition concretedpm.h:50
#define _IFT_ConcreteDPM_ft
Definition concretedpm.h:51
#define _IFT_ConcreteDPM_ahard
Definition concretedpm.h:54
#define _IFT_ConcreteDPM_yieldtol
Definition concretedpm.h:60
#define _IFT_ConcreteDPM_bhard
Definition concretedpm.h:55
#define _IFT_ConcreteDPM_dilation
Definition concretedpm.h:59
#define _IFT_ConcreteDPM_ecc
Definition concretedpm.h:52
#define _IFT_ConcreteDPM_asoft
Definition concretedpm.h:58
#define _IFT_ConcreteDPM_chard
Definition concretedpm.h:56
#define _IFT_ConcreteDPM_wf
Definition concretedpm.h:62
#define _IFT_ConcreteDPM_newtoniter
Definition concretedpm.h:61
#define _IFT_ConcreteDPM_helem
Definition concretedpm.h:65
#define _IFT_ConcreteDPM_kinit
Definition concretedpm.h:53
#define THROW_CIOERR(e)
#define CM_Definition
Definition contextmode.h:47
#define OOFEM_ERROR(...)
Definition error.h:79
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Definition inputrecord.h:75
#define IR_GIVE_FIELD(__ir, __value, __id)
Definition inputrecord.h:67
#define _IFT_IsotropicLinearElasticMaterial_n
#define _IFT_IsotropicLinearElasticMaterial_e
#define fc_strength
Definition matconst.h:92
#define ft_strength
Definition matconst.h:91
#define M_PI
Definition mathfem.h:52
long ContextMode
Definition contextmode.h:43
@ AL
Updated Lagrange.
Definition fmode.h:45
FloatMatrixF< N, M > dyad(const FloatArrayF< N > &a, const FloatArrayF< M > &b)
Computes the dyadic product .
FloatMatrixF< 3, 3 > from_voigt_strain_6(const FloatArrayF< 6 > &v)
FloatMatrixF< 3, 3 > from_voigt_stress_6(const FloatArrayF< 6 > &v)
FloatArrayF< N > solve(FloatMatrixF< N, N > mtrx, const FloatArrayF< N > &b, double zeropiv=1e-20)
double dot(const FloatArray &x, const FloatArray &y)
FloatMatrixF< N, N > inv(const FloatMatrixF< N, N > &mat, double zeropiv=1e-24)
Computes the inverse.
@ 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