OOFEM 3.0
Loading...
Searching...
No Matches
concretedpm2.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 "concretedpm2.h"
36#include "floatarray.h"
37#include "floatmatrix.h"
39#include "gausspoint.h"
40#include "intarray.h"
41#include "datastream.h"
42#include "contextioerr.h"
43#include "timestep.h"
47#include "mathfem.h"
48#include "classfactory.h"
49#include <limits>
50
51namespace oofem {
53
62
63void
101
102void
104{
105 // Call corresponding function of the parent class to update
106 // variables defined there.
108
109 // update variables defined in ConcreteDPM2Status
110
112
114
115 //Plasticity part
118
119
120 //Damage part
124
127
130
133
136
138
140
142
143#ifdef keep_track_of_dissipated_energy
146#endif
147}
148
149void
151{
152 // Call corresponding function of the parent class to print
154
155 fprintf(file, "\tstatus { ");
156
157 // print status flag
158 switch ( state_flag ) {
160 fprintf(file, "Elastic, ");
161 break;
163 fprintf(file, "Unloading, ");
164 break;
166 fprintf(file, "Plastic, ");
167 break;
169 fprintf(file, "Damage, ");
170 break;
172 fprintf(file, "PlasticDamage, ");
173 break;
174 }
175
176 // print plastic strain vector and inelastic strain vector
177 auto inelasticStrainVector = ( ( FloatArrayF< 6 >(strainVector) - plasticStrain ) * damageTension + plasticStrain ) * le;
178
179 fprintf(file, " reduced ");
180 for ( auto &val : reducedStrain ) {
181 fprintf(file, " %.10e", val);
182 }
183
184 fprintf(file, " plastic ");
185 for ( auto &val : plasticStrain ) {
186 fprintf(file, " %.10e", val);
187 }
188
189 fprintf(file, " inelastic ");
190 for ( auto &val : inelasticStrainVector ) {
191 fprintf(file, " %.10e", val);
192 }
193
194 fprintf(file, " equivStrain %.10e,", equivStrain);
195
196 fprintf(file, " kappaDTension %.10e,", kappaDTension);
197
198 fprintf(file, " kappaDCompression %.10e,", kappaDCompression);
199
200 fprintf(file, " kappaP %.10e,", kappaP);
201
202 fprintf(file, " kappaDTensionOne %.10e,", kappaDTensionOne);
203
204 fprintf(file, " kappaDCompressionOne %.10e,", kappaDCompressionOne);
205
206 fprintf(file, " kappaDTensionTwo %.10e,", kappaDTensionTwo);
207
208 fprintf(file, " kappaDCompressionTwo %.10e,", kappaDCompressionTwo);
209
210 fprintf(file, " damageTension %.10e,", damageTension);
211
212 fprintf(file, " damageCompression %.10e,", damageCompression);
213
214 fprintf(file, " alpha %.10e,", this->alpha);
215
216#ifdef keep_track_of_dissipated_energy
217 fprintf(file, " dissW %g, freeE %g, stressW %g ", this->dissWork, ( this->stressWork ) - ( this->dissWork ), this->stressWork);
218#endif
219 fprintf(file, "}\n");
220}
221
222void
224{
226
228
229
230 if ( ( iores = plasticStrain.storeYourself(stream) ) != CIO_OK ) {
231 THROW_CIOERR(iores);
232 }
233 if ( ( iores = reducedStrain.storeYourself(stream) ) != CIO_OK ) {
234 THROW_CIOERR(iores);
235 }
236
237
238 if ( !stream.write(kappaP) ) {
240 }
241
242
243 if ( !stream.write(le) ) {
245 }
246
247 if ( !stream.write(alpha) ) {
249 }
250
251 if ( !stream.write(equivStrain) ) {
253 }
254
255 if ( !stream.write(equivStrainTension) ) {
257 }
258
259 if ( !stream.write(equivStrainCompression) ) {
261 }
262
263 if ( !stream.write(kappaDTension) ) {
265 }
266
267 if ( !stream.write(kappaDCompression) ) {
269 }
270
271 if ( !stream.write(kappaDTensionOne) ) {
273 }
274
275 if ( !stream.write(kappaDCompressionOne) ) {
277 }
278
279 if ( !stream.write(kappaDTensionTwo) ) {
281 }
282
283 if ( !stream.write(kappaDCompressionTwo) ) {
285 }
286
287
288 if ( !stream.write(damageTension) ) {
290 }
291
292 if ( !stream.write(damageCompression) ) {
294 }
295
296 if ( !stream.write(deltaEquivStrain) ) {
298 }
299
300 if ( !stream.write(rateFactor) ) {
302 }
303
304 if ( !stream.write(rateStrain) ) {
306 }
307
308 if ( !stream.write(state_flag) ) {
310 }
311
312
313#ifdef keep_track_of_dissipated_energy
314 if ( !stream.write(stressWork) ) {
316 }
317
318 if ( !stream.write(dissWork) ) {
320 }
321
322#endif
323}
324
325
326void
328{
330
332
333 if ( ( iores = plasticStrain.restoreYourself(stream) ) != CIO_OK ) {
334 THROW_CIOERR(iores);
335 }
336 if ( ( iores = reducedStrain.restoreYourself(stream) ) != CIO_OK ) {
337 THROW_CIOERR(iores);
338 }
339
340 if ( !stream.read(kappaP) ) {
342 }
343
344 if ( !stream.read(le) ) {
346 }
347
348 if ( !stream.read(alpha) ) {
350 }
351
352 if ( !stream.read(equivStrain) ) {
354 }
355
356 if ( !stream.read(equivStrainTension) ) {
358 }
359
360 if ( !stream.read(equivStrainCompression) ) {
362 }
363
364 if ( !stream.read(kappaDTension) ) {
366 }
367
368 if ( !stream.read(kappaDCompression) ) {
370 }
371
372 if ( !stream.read(kappaDTensionOne) ) {
374 }
375
376 if ( !stream.read(kappaDCompressionOne) ) {
378 }
379
380 if ( !stream.read(kappaDTensionTwo) ) {
382 }
383
384 if ( !stream.read(kappaDCompressionTwo) ) {
386 }
387
388
389 if ( !stream.read(damageTension) ) {
391 }
392
393 if ( !stream.read(damageCompression) ) {
395 }
396
397 if ( !stream.read(deltaEquivStrain) ) {
399 }
400
401 if ( !stream.read(rateFactor) ) {
403 }
404
405 if ( !stream.read(rateStrain) ) {
407 }
408
409 if ( !stream.read(state_flag) ) {
411 }
412
413
414#ifdef keep_track_of_dissipated_energy
415 if ( !stream.read(stressWork) ) {
417 }
418
419 if ( !stream.read(dissWork) ) {
421 }
422
423#endif
424}
425
426#ifdef keep_track_of_dissipated_energy
427void
429{
430 auto tempTotalstrain = tempReducedStrain;
431 auto totalstrain = reducedStrain;
432
433 //Calculate increase or decrease of total strain tensor during iteration/step
434 auto deltaTotalStrain = tempTotalstrain - totalstrain;
435
436 //Ask for stress tensor at step
437 auto stress = tempStressVector;
438
439 //Calculate increase/decrease in total work
440 double dSW = ( dot(tempStressVector, deltaTotalStrain) + dot(stressVector, deltaTotalStrain) ) / 2.;
441
442 double tempStressWork = this->giveTempStressWork() + dSW;
443
444 //Calculate temporary elastic strain
445 auto tempElasticStrain = tempTotalstrain - tempPlasticStrain;
446
447 //Calculate elastically stored energy density
448 double We = dot(tempStressVector, tempElasticStrain) / 2.;
449
450 // dissipative work density
452
453 // to avoid extremely small negative dissipation due to round-off error
454 // (note: gf is the dissipation density at complete failure, per unit volume)
455 //Rough estimation of gf which is ok for this purpose
456
457 if ( fabs(tempDissWork) < 1.e-12 * gf ) {
458 tempDissWork = 0.;
459 }
460
461 this->setTempStressWork(tempStressWork);
463}
464#endif
465
466// ********************************
467// *** CLASS CONCRETE DAMAGE PLASTICITY MODEL 2 ***
468// ********************************
469
470#define IDM_ITERATION_LIMIT 1.e-8
471
476
477
478bool
480//
481// returns whether receiver supports given mode
482//
483{
484 return mode == _3dMat;
485}
486
487
488void
490{
491 // call the corresponding service for the linear elastic material
493 linearElasticMaterial.initializeFrom(ir);
494
495 //damage flag
496 this->damageFlag = 1; //Default value using damage in tension and compression according to IJSS CDPM2 paper.
498
499 // elastic parameters
502 propertyDictionary.add('E', this->eM);
503 propertyDictionary.add('n', this->nu);
504
505 this->gM = this->eM / ( 2. * ( 1. + this->nu ) );
506 this->kM = this->eM / ( 3. * ( 1. - 2. * this->nu ) );
507
510
511 this->e0 = this->ft / this->eM;
512
513 // default parameters
514 this->ecc = 0.525;
516 this->yieldHardInitial = 0.3;
518
519 //Inclination at transition point
520 this->yieldHardPrimePeak = 0.5;
522
523 if ( this->yieldHardPrimePeak < 0 ) {
524 this->yieldHardPrimePeak = 0.;
525 OOFEM_WARNING("kPrimePeak cannot be less than zero");
526 } else if ( this->yieldHardPrimePeak > ( 1. - this->yieldHardInitial ) ) {
527 this->yieldHardPrimePeak = 1. - this->yieldHardInitial;
528 OOFEM_WARNING("kPrimePeak cannot be greater than 1.-kinit");
529 }
530
531 this->AHard = 8.e-2;
533 this->BHard = 3.e-3;
535 this->CHard = 2.;
537 this->DHard = 1.e-6;
539 this->dilationConst = 0.85;
541
542 this->softeningType = 1; //0-Linear softening; 1-Bilinear softening; 2-Exponential
544
545 if ( softeningType > 2 ) {
546 throw ValueInputException(ir, _IFT_ConcreteDPM2_softeningType, "softening type not implemented");
547 }
548
550
551 if ( this->softeningType == 1 ) {
552 this->ftOne = 0.3 * this->ft;
554 this->wfOne = 0.15 * this->wf;
556 }
557
558 this->efCompression = 100.e-6;
560
561 this->ASoft = 15;
563
564 this->helem = 0.;
566
567
568 //Compute m
569 m = 3. * ( pow(this->fc, 2.) - pow(this->ft, 2.) ) / ( this->fc * this->ft ) * this->ecc / ( this->ecc + 1. );
570
571 //Compute default value of dilationConst
572 this->yieldTol = 1.e-6;
574
575 this->yieldTolDamage = this->yieldTol * 10.;
576
577 this->newtonIter = 100;
579
580 this->strengthRateType = 0;
583 OOFEM_ERROR("strength rate type not implemented. Must be 0, 1 or 2\n");
584 }
585
586 this->deltaTime = -1.;
587 this->energyRateType = 0;
588 if ( this->strengthRateType > 0 ) {
591 }
592}
593
594
595void
597{
599 if ( ( mode & CM_Definition ) ) {
600 if ( !stream.write(fc) ) {
602 }
603 if ( !stream.write(ft) ) {
605 }
606 if ( !stream.write(ecc) ) {
608 }
609 if ( !stream.write(damageFlag) ) {
611 }
612 if ( !stream.write(e0) ) {
614 }
615 if ( !stream.write(AHard) ) {
617 }
618 if ( !stream.write(BHard) ) {
620 }
621 if ( !stream.write(CHard) ) {
623 }
624 if ( !stream.write(DHard) ) {
626 }
627 if ( !stream.write(hardeningModulus) ) {
629 }
630 if ( !stream.write(ASoft) ) {
632 }
633 if ( !stream.write(yieldHardPrimePeak) ) {
635 }
636 if ( !stream.write(yieldHardInitial) ) {
638 }
639 if ( !stream.write(dilationConst) ) {
641 }
642 if ( !stream.write(m) ) {
644 }
645 if ( !stream.write(mQ) ) {
647 }
648 if ( !stream.write(helem) ) {
650 }
651 if ( !stream.write(eM) ) {
653 }
654 if ( !stream.write(gM) ) {
656 }
657 if ( !stream.write(kM) ) {
659 }
660 if ( !stream.write(nu) ) {
662 }
663 if ( !stream.write(efCompression) ) {
665 }
666 if ( !stream.write(wf) ) {
668 }
669 if ( !stream.write(wfOne) ) {
671 }
672 if ( !stream.write(ftOne) ) {
674 }
675 if ( !stream.write(yieldTol) ) {
677 }
678 if ( !stream.write(yieldTolDamage) ) {
680 }
681 if ( !stream.write(newtonIter) ) {
683 }
684 if ( !stream.write(softeningType) ) {
686 }
687 if ( !stream.write(deltaTime) ) {
689 }
690 if ( !stream.write(strengthRateType) ) {
692 }
693 if ( !stream.write(energyRateType) ) {
695 }
696 }
697
698
699 linearElasticMaterial.saveContext(stream, mode);
700}
701
702void
704{
706 if ( ( mode & CM_Definition ) ) {
707 if ( !stream.read(fc) ) {
709 }
710 if ( !stream.read(ft) ) {
712 }
713 if ( !stream.read(ecc) ) {
715 }
716 if ( !stream.read(damageFlag) ) {
718 }
719 if ( !stream.read(e0) ) {
721 }
722 if ( !stream.read(AHard) ) {
724 }
725 if ( !stream.read(BHard) ) {
727 }
728 if ( !stream.read(CHard) ) {
730 }
731 if ( !stream.read(DHard) ) {
733 }
734 if ( !stream.read(hardeningModulus) ) {
736 }
737 if ( !stream.read(ASoft) ) {
739 }
740 if ( !stream.read(yieldHardPrimePeak) ) {
742 }
743 if ( !stream.read(yieldHardInitial) ) {
745 }
746 if ( !stream.read(dilationConst) ) {
748 }
749 if ( !stream.read(m) ) {
751 }
752 if ( !stream.read(mQ) ) {
754 }
755 if ( !stream.read(helem) ) {
757 }
758 if ( !stream.read(eM) ) {
760 }
761 if ( !stream.read(gM) ) {
763 }
764 if ( !stream.read(kM) ) {
766 }
767 if ( !stream.read(nu) ) {
769 }
770 if ( !stream.read(efCompression) ) {
772 }
773 if ( !stream.read(wf) ) {
775 }
776 if ( !stream.read(wfOne) ) {
778 }
779 if ( !stream.read(ftOne) ) {
781 }
782 if ( !stream.read(yieldTol) ) {
784 }
785 if ( !stream.read(yieldTolDamage) ) {
787 }
788 if ( !stream.read(newtonIter) ) {
790 }
791 if ( !stream.read(softeningType) ) {
793 }
794 if ( !stream.read(deltaTime) ) {
796 }
797 if ( !stream.read(strengthRateType) ) {
799 }
800 if ( !stream.read(energyRateType) ) {
802 }
803 }
804 linearElasticMaterial.restoreContext(stream, mode);
805}
806
807
808
809
812{
813 auto status = static_cast< ConcreteDPM2Status * >( this->giveStatus(gp) );
814
815 // Initialize temp variables for this gauss point
816 status->initTempStatus();
817
818 // Remove thermal/shrinkage strains
819 auto thermalStrain = this->computeStressIndependentStrainVector_3d(gp, tStep, VM_Total);
820
821 auto strainVector = fullStrainVector - thermalStrain;
822
823 status->letTempReducedStrainBe(strainVector);
824
825 //Calculate time increment
826 double dt = deltaTime;
827 if ( dt == -1 ) {
828 if ( tStep->giveTimeIncrement() == 0 ) { //Problem with the first step. For some reason the time increment is zero
829 dt = 1.;
830 } else {
831 dt = tStep->giveTimeIncrement();
832 }
833 }
834
835 auto D = this->linearElasticMaterial.give3dMaterialStiffnessMatrix(ElasticStiffness, gp, tStep);
836 // perform plasticity return
837 auto effectiveStress = performPlasticityReturn(gp, D, strainVector);
838
839 FloatArrayF< 6 >effectiveStressTension;
840 FloatArrayF< 6 >effectiveStressCompression;
841 FloatArrayF< 6 >stress;
842
843 double alpha = 0.;
844
845 if ( this->damageFlag != 0 ) {//Apply damage
846 alpha = computeAlpha(effectiveStressTension, effectiveStressCompression, effectiveStress);
847 auto damages = computeDamage(strainVector, D, dt, gp, tStep, alpha, effectiveStress);
848
849 if ( this->damageFlag == 1 ) { //Default as described in IJSS CDPM2 article
850 stress = effectiveStressTension * ( 1. - damages.at(1) ) + effectiveStressCompression * ( 1. - damages.at(2) );
851 } else if ( this->damageFlag == 2 ) { //Simplified version without split of stress but two damage variables
852 stress = effectiveStress * ( 1. - ( 1. - alpha ) * damages.at(1) ) * ( 1. - alpha * damages.at(2) );
853 } else if ( this->damageFlag == 3 ) { //Consider only tensile damage. Reduction to a fully isotropic model. Similar to CDPM article.
854 stress = effectiveStress * ( 1. - damages.at(1) );
855 } else {
856 OOFEM_ERROR("Unknown value of damage flag. Must be 0, 1, 2 or 3");
857 }
858 } else {
859 stress = effectiveStress;
860 }
861
862 status->letTempStrainVectorBe(fullStrainVector);
863 status->letTempAlphaBe(alpha);
864 status->letTempStressVectorBe(stress);
865 status->letTempEffectiveStressBe(effectiveStress);
866#ifdef keep_track_of_dissipated_energy
867 double gf = pow(ft, 2) / this->eM; //rough estimation only for this purpose
868 status->computeWork(gp, gf);
869#endif
870 assignStateFlag(gp);
871 return stress;
872}
873
874
877 const FloatMatrixF< 6, 6 > &D,
878 double deltaTime,
879 GaussPoint *gp,
880 TimeStep *tStep,
881 double tempAlpha,
882 const FloatArrayF< 6 > &effectiveStress) const
883{
884 auto status = static_cast< ConcreteDPM2Status * >( this->giveStatus(gp) );
885
886 double tempEquivStrain;
887 double deltaPlasticStrainNorm;
888 double tempDamageTension = 0.0;
889 double tempDamageCompression = 0.0;
890
891 double tempKappaDTension = 0.0, tempKappaDCompression = 0.0;
892 double tempKappaDTensionOne = 0.0, tempKappaDTensionTwo = 0.0;
893 double tempKappaDCompressionOne = 0.0, tempKappaDCompressionTwo = 0.0;
894
895 double minEquivStrain = 0.;
896
897 double sig, rho, theta;
898 //Calculate coordinates
899 computeCoordinates(effectiveStress, sig, rho, theta);
900
901 int unAndReloadingFlag = checkForUnAndReloading(tempEquivStrain, minEquivStrain, D, gp);
902
903 double rateFactor;
904 if ( ( status->giveDamageTension() == 0. ) && ( status->giveDamageCompression() == 0. ) ) {
905 rateFactor = computeRateFactor(tempAlpha, deltaTime, gp, tStep);
906 } else {
907 rateFactor = status->giveRateFactor();
908 }
909
910
911 //Compute equivalent strains for tension and compression
912 double tempEquivStrainTension = 0.;
913 double tempEquivStrainCompression = 0.;
914
915 tempEquivStrainTension = status->giveEquivStrainTension() + ( tempEquivStrain - status->giveEquivStrain() ) / rateFactor;
916
917 if ( unAndReloadingFlag == 0 ) { //Standard way
918 tempEquivStrainCompression = status->giveEquivStrainCompression() + ( tempAlpha * ( tempEquivStrain - status->giveEquivStrain() ) ) / rateFactor;
919 } else {
920 tempEquivStrainCompression = status->giveEquivStrainCompression() + status->giveAlpha() * ( minEquivStrain - status->giveEquivStrain() ) / rateFactor + ( tempAlpha * ( tempEquivStrain - minEquivStrain ) ) / rateFactor;
921 }
922
923
924 //If damage threshold is exceeded determine the rate factor from the previous step
925 if ( ( tempEquivStrainTension > e0 || tempEquivStrainCompression > e0 ) &&
926 ( ( status->giveDamageTension() == 0. ) && ( status->giveDamageCompression() == 0. ) ) && !tStep->isTheFirstStep() ) {
927 //Rate factor from last step
928 rateFactor = status->giveRateFactor();
929
930 tempEquivStrainTension = status->giveEquivStrainTension() + ( tempEquivStrain - status->giveEquivStrain() ) / rateFactor;
931 if ( unAndReloadingFlag == 0 ) { //Standard way
932 tempEquivStrainCompression = status->giveEquivStrainCompression() + ( tempAlpha * ( tempEquivStrain - status->giveEquivStrain() ) ) / rateFactor;
933 } else {
934 tempEquivStrainCompression = status->giveEquivStrainCompression() + status->giveAlpha() * ( minEquivStrain - status->giveEquivStrain() ) / rateFactor + ( tempAlpha * ( tempEquivStrain - minEquivStrain ) ) / rateFactor;
935 }
936 }
937
938 status->letTempRateFactorBe(rateFactor);
939
940 double fTension = tempEquivStrainTension - status->giveKappaDTension();
941 double fCompression = tempEquivStrainCompression - status->giveKappaDCompression();
942
943 //Normalize the fs
944 fTension = fTension / e0;
945 fCompression = fCompression / e0;
946
947 double ductilityMeasure = computeDuctilityMeasureDamage(gp, sig, rho);
948 double deltaPlasticStrainNormTension, deltaPlasticStrainNormCompression;
949
950 if ( fTension < -yieldTolDamage && fCompression < -yieldTolDamage ) {
951 //Neither tension nor compression is active
952
953 tempKappaDTension = status->giveKappaDTension();
954 tempKappaDTensionOne = status->giveKappaDTensionOne();
955 tempKappaDTensionTwo = status->giveKappaDTensionTwo();
956
957 tempKappaDCompression = status->giveKappaDCompression();
958 tempKappaDCompressionOne = status->giveKappaDCompressionOne();
959 tempKappaDCompressionTwo = status->giveKappaDCompressionTwo();
960
961 tempDamageTension = status->giveDamageTension();
962 tempDamageCompression = status->giveDamageCompression();
963 } else if ( fTension >= -yieldTolDamage && fCompression < -yieldTolDamage ) { //Only tension is active
964 //Update tension history variables
965 tempKappaDTension = tempEquivStrainTension;
966 deltaPlasticStrainNorm = computeDeltaPlasticStrainNormTension(tempKappaDTension, status->giveKappaDTension(), gp);
967 tempKappaDTensionOne = status->giveKappaDTensionOne() + deltaPlasticStrainNorm / ductilityMeasure / rateFactor;
968 tempKappaDTensionTwo = status->giveKappaDTensionTwo() + ( tempKappaDTension - status->giveKappaDTension() ) / ductilityMeasure;
969
970 //Nothing changes for compression history variables
971 tempKappaDCompression = status->giveKappaDCompression();
972 tempKappaDCompressionOne = status->giveKappaDCompressionOne();
973 tempKappaDCompressionTwo = status->giveKappaDCompressionTwo();
974
975 //Initialise damage with tensile history variable
976 this->initDamaged(tempKappaDTension, strain, gp);
977
978 tempDamageTension = computeDamageParamTension(tempKappaDTension, tempKappaDTensionOne, tempKappaDTensionTwo, status->giveLe(), status->giveDamageTension(), rateFactor);
979
980 tempDamageCompression = status->giveDamageCompression();
981 } else if ( fTension < -yieldTolDamage && fCompression >= -yieldTolDamage ) {
982 //Only compression is active
983
984 //Nothing changes for the history variables in tension
985 tempKappaDTension = status->giveKappaDTension();
986 tempKappaDTensionOne = status->giveKappaDTensionOne();
987 tempKappaDTensionTwo = status->giveKappaDTensionTwo();
988
989 //Update compression history variables
990 tempKappaDCompression = tempEquivStrainCompression;
991 deltaPlasticStrainNormCompression = computeDeltaPlasticStrainNormCompression(tempAlpha, tempKappaDCompression, status->giveKappaDCompression(), gp, rho);
992 tempKappaDCompressionOne = status->giveKappaDCompressionOne() + deltaPlasticStrainNormCompression / ( ductilityMeasure * rateFactor );
993 tempKappaDCompressionTwo = status->giveKappaDCompressionTwo() + ( tempKappaDCompression - status->giveKappaDCompression() ) / ductilityMeasure;
994
995 //Determine damage parameters
996 tempDamageTension = status->giveDamageTension();
997 tempDamageCompression = computeDamageParamCompression(tempKappaDCompression, tempKappaDCompressionOne, tempKappaDCompressionTwo, status->giveDamageCompression(), rateFactor);
998 } else if ( fTension >= -yieldTolDamage && fCompression >= -yieldTolDamage ) {
999 //Both tension and compression is active
1000
1001 //Update tension history variables
1002 tempKappaDTension = tempEquivStrainTension;
1003 deltaPlasticStrainNormTension = computeDeltaPlasticStrainNormTension(tempKappaDTension, status->giveKappaDTension(), gp);
1004 tempKappaDTensionOne = status->giveKappaDTensionOne() + deltaPlasticStrainNormTension / ( ductilityMeasure * rateFactor );
1005 tempKappaDTensionTwo = status->giveKappaDTensionTwo() + ( tempKappaDTension - status->giveKappaDTension() ) / ductilityMeasure;
1006
1007 //Update the compression history variables
1008 tempKappaDCompression = tempEquivStrainCompression;
1009 deltaPlasticStrainNormCompression =
1010 computeDeltaPlasticStrainNormCompression(tempAlpha, tempKappaDCompression, status->giveKappaDCompression(), gp, rho);
1011 tempKappaDCompressionOne = status->giveKappaDCompressionOne() + deltaPlasticStrainNormCompression / ( ductilityMeasure * rateFactor );
1012 tempKappaDCompressionTwo = status->giveKappaDCompressionTwo() +
1013 ( tempKappaDCompression - status->giveKappaDCompression() ) / ductilityMeasure;
1014
1015 //Determine the damage parameters
1016 this->initDamaged(tempKappaDTension, strain, gp);
1017
1018 tempDamageTension = computeDamageParamTension(tempKappaDTension, tempKappaDTensionOne, tempKappaDTensionTwo, status->giveLe(), status->giveDamageTension(), rateFactor);
1019
1020 tempDamageCompression = computeDamageParamCompression(tempKappaDCompression, tempKappaDCompressionOne, tempKappaDCompressionTwo, status->giveDamageCompression(), rateFactor);
1021 }
1022
1023 //Write all temp history variables to the status
1024 status->letTempEquivStrainBe(tempEquivStrain);
1025
1026 //Tension
1027 status->letTempEquivStrainTensionBe(tempEquivStrainTension);
1028 status->letTempKappaDTensionBe(tempKappaDTension);
1029 status->letTempKappaDTensionOneBe(tempKappaDTensionOne);
1030 status->letTempKappaDTensionTwoBe(tempKappaDTensionTwo);
1031 status->letTempDamageTensionBe(tempDamageTension);
1032
1033 //Compression
1034 status->letTempEquivStrainCompressionBe(tempEquivStrainCompression);
1035 status->letTempKappaDCompressionBe(tempKappaDCompression);
1036 status->letTempKappaDCompressionOneBe(tempKappaDCompressionOne);
1037 status->letTempKappaDCompressionTwoBe(tempKappaDCompressionTwo);
1038 status->letTempDamageCompressionBe(tempDamageCompression);
1039
1040 return {
1041 tempDamageTension, tempDamageCompression
1042 };
1043}
1044
1045int
1047 double &minEquivStrain,
1048 const FloatMatrixF< 6, 6 > &D,
1049 GaussPoint *gp) const
1050{
1051 auto status = static_cast< ConcreteDPM2Status * >( this->giveStatus(gp) );
1052
1053 //Access old and new strains
1054 const auto &oldStrain = status->giveReducedStrain();
1055 const auto &strain = status->giveTempReducedStrain();
1056
1057 //Compute the temp equivalent strain
1058 auto tempElasticStrain = strain - status->giveTempPlasticStrain();
1059 auto tempEffectiveStress = dot(D, tempElasticStrain);
1060
1061 double sigEffective, rhoEffective, thetaEffective;
1062 computeCoordinates(tempEffectiveStress, sigEffective, rhoEffective, thetaEffective);
1063 tempEquivStrain = computeEquivalentStrain(sigEffective, rhoEffective, thetaEffective);
1064 //Get the equivalent strain from the status
1065 double equivStrain = status->giveEquivStrain();
1066
1067 //Compute the increment of effective stress
1068 auto elasticStrain = oldStrain - status->givePlasticStrain();
1069 auto effectiveStress = dot(D, elasticStrain);
1070
1071 auto deltaEffectiveStress = tempEffectiveStress - effectiveStress;
1072
1073 //Compute equivalent strains for stress state slightly greater than the effective stress and smaller than the temp effective stress
1074 //For slightly more than effective stress
1075 auto intermediateEffectiveStressPlus = effectiveStress + 0.01 * deltaEffectiveStress;
1076 computeCoordinates(intermediateEffectiveStressPlus, sigEffective, rhoEffective, thetaEffective);
1077 double equivStrainPlus = computeEquivalentStrain(sigEffective, rhoEffective, thetaEffective);
1078
1079 //For slightly less than temp effective stress
1080 auto intermediateEffectiveStressMinus = effectiveStress + 0.99 * deltaEffectiveStress;
1081 computeCoordinates(intermediateEffectiveStressMinus, sigEffective, rhoEffective, thetaEffective);
1082 double tempEquivStrainMinus = computeEquivalentStrain(sigEffective, rhoEffective, thetaEffective);
1083
1084 //Check for unloading and reloading in the same step
1085 int unloadingFlag = 0;
1086 minEquivStrain = equivStrain;
1087
1088 if ( ( equivStrain > equivStrainPlus && tempEquivStrain > tempEquivStrainMinus ) &&
1089 ( fabs(equivStrainPlus - equivStrain) > yieldTolDamage / 100. && fabs(tempEquivStrainMinus - tempEquivStrain) > yieldTolDamage / 100. ) ) {
1090 unloadingFlag = 1;
1091 //Unloading and reloading takes place. Find the minimum equivalent strain by subincrementing the effective stress increment
1092 for ( double k = 1.0; k <= 100.0; k = k + 1.0 ) {
1093 auto intermediateEffectiveStress = effectiveStress + k / 100. * deltaEffectiveStress;
1094 computeCoordinates(intermediateEffectiveStress, sigEffective, rhoEffective, thetaEffective);
1095 double midEquivStrain = computeEquivalentStrain(sigEffective, rhoEffective, thetaEffective);
1096
1097 if ( midEquivStrain <= minEquivStrain ) {
1098 minEquivStrain = midEquivStrain;
1099 } else {
1100 return unloadingFlag;
1101 }
1102 }
1103 }
1104 return unloadingFlag;
1105}
1106
1107
1108double
1110 double deltaTime,
1111 GaussPoint *gp,
1112 TimeStep *tStep) const
1113{
1114 if ( this->strengthRateType == 0 ) {
1115 return 1;
1116 }
1117
1118 auto status = static_cast< ConcreteDPM2Status * >( this->giveStatus(gp) );
1119
1120 const auto &strain = status->giveTempReducedStrain();
1121
1122 //Determine the principal values of the strain
1123 auto principalStrain = StructuralMaterial::computePrincipalValues(from_voigt_strain_6(strain) );
1124
1125 //Determine max and min value;
1126 double maxStrain = -1.e20, minStrain = 1.e20;
1127 for ( int k = 1; k <= principalStrain.giveSize(); k++ ) {
1128 //maximum
1129 if ( principalStrain.at(k) > maxStrain ) {
1130 maxStrain = principalStrain.at(k);
1131 }
1132
1133 //minimum
1134 if ( principalStrain.at(k) < minStrain ) {
1135 minStrain = principalStrain.at(k);
1136 }
1137 }
1138
1139 //Evaluate the equivalent strains
1140 double strainRate;
1141 double oldRateStrain = status->giveRateStrain();
1142 if ( 1. - alpha > CDPM2_TOL ) { //Tension
1143 strainRate = ( maxStrain - oldRateStrain ) / deltaTime;
1144 status->letTempRateStrainBe(maxStrain);
1145 } else { //Compression
1146 strainRate = ( minStrain - oldRateStrain ) / deltaTime;
1147 status->letTempRateStrainBe(minStrain);
1148 }
1149
1150 //Tension
1151 //For tension according to Model Code 2010
1152 double rateFactorTension = 1.;
1153 double strainRateRatioTension = strainRate / 1.e-6;
1154
1155 if ( this->strengthRateType == 1 ) {
1156 if ( strainRate < 1.e-6 ) {
1157 rateFactorTension = 1.;
1158 } else if ( 1.e-6 < strainRate ) {
1159 rateFactorTension = pow(strainRateRatioTension, 0.018);
1160 }
1161 } else if ( this->strengthRateType == 2 ) {
1162 if ( strainRate < 1.e-6 ) {
1163 rateFactorTension = 1.;
1164 } else if ( 1.e-6 < strainRate && strainRate < 10 ) {
1165 rateFactorTension = pow(strainRateRatioTension, 0.018);
1166 } else {
1167 rateFactorTension = 0.0062 * pow(strainRateRatioTension, 1. / 3.);
1168 }
1169 }
1170
1171 //For compression according to Model Code 2010
1172 double rateFactorCompression = 1.;
1173 double strainRateRatioCompression = strainRate / ( -30.e-6 );
1174 if ( this->strengthRateType == 1 ) {
1175 if ( strainRate > -30.e-6 ) {
1176 rateFactorCompression = 1.;
1177 } else if ( -30.e-6 > strainRate ) {
1178 rateFactorCompression = pow(strainRateRatioCompression, 0.014);
1179 }
1180 } else if ( this->strengthRateType == 2 ) {
1181 if ( strainRate > -30.e-6 ) {
1182 rateFactorCompression = 1.;
1183 } else if ( -30.e-6 > strainRate && strainRate > -30 ) {
1184 rateFactorCompression = pow(strainRateRatioCompression, 0.014);
1185 } else if ( -30 > strainRate && strengthRateType == 2 ) {
1186 rateFactorCompression = 0.012 * pow(strainRateRatioCompression, 0.333);
1187 }
1188 }
1189
1190 double rateFactor = ( 1. - alpha ) * rateFactorTension + alpha * rateFactorCompression;
1191
1192 return rateFactor;
1193}
1194
1195
1196double
1197ConcreteDPM2::computeDeltaPlasticStrainNormTension(double tempKappaD, double kappaD, GaussPoint *gp) const
1198{
1199 auto status = static_cast< ConcreteDPM2Status * >( this->giveStatus(gp) );
1200
1201 const auto &tempPlasticStrain = status->giveTempPlasticStrain();
1202 const auto &plasticStrain = status->givePlasticStrain();
1203
1204 auto deltaPlasticStrain = tempPlasticStrain - plasticStrain;
1205
1206 double deltaPlasticStrainNorm = 0;
1207
1208 //Distinguish pre-peak, peak and post-peak
1209
1210 double factor = 0.;
1211 if ( tempKappaD < e0 * ( 1. - yieldTolDamage ) ) {
1212 deltaPlasticStrainNorm = 0.;
1213 } else if ( tempKappaD > e0 * ( 1. - yieldTolDamage ) && kappaD < e0 * ( 1. - yieldTolDamage ) ) {
1214 factor = ( 1. - ( e0 - kappaD ) / ( tempKappaD - kappaD ) );
1215 deltaPlasticStrain *= factor;
1216 deltaPlasticStrainNorm = norm(deltaPlasticStrain);
1217 } else {
1218 deltaPlasticStrainNorm = norm(deltaPlasticStrain);
1219 }
1220
1221 return deltaPlasticStrainNorm;
1222}
1223
1224
1225double
1226ConcreteDPM2::computeDeltaPlasticStrainNormCompression(double tempAlpha, double tempKappaD, double kappaD, GaussPoint *gp, const double rho) const
1227{
1228 auto status = static_cast< ConcreteDPM2Status * >( this->giveStatus(gp) );
1229
1230 const auto &tempPlasticStrain = status->giveTempPlasticStrain();
1231 const auto &plasticStrain = status->givePlasticStrain();
1232
1233 auto deltaPlasticStrain = tempAlpha * ( tempPlasticStrain - plasticStrain );
1234
1235 double deltaPlasticStrainNorm = 0;
1236
1237 //Distinguish pre-peak, peak and post-peak
1238 if ( tempKappaD < e0 * ( 1. - yieldTolDamage ) ) {
1239 deltaPlasticStrainNorm = 0.;
1240 } else if ( tempKappaD > e0 * ( 1. - yieldTolDamage ) && kappaD < e0 * ( 1. - yieldTolDamage ) ) {
1241 double factor = ( 1. - ( e0 - kappaD ) / ( tempKappaD - kappaD ) );
1242 deltaPlasticStrain *= factor;
1243 deltaPlasticStrainNorm = norm(deltaPlasticStrain);
1244 } else {
1245 deltaPlasticStrainNorm = norm(deltaPlasticStrain);
1246 }
1247
1248 double tempKappaP = status->giveTempKappaP();
1249 double yieldHardTwo = computeHardeningTwo(tempKappaP);
1250 double extraFactor;
1251 if ( rho < 1.e-16 ) {
1252 extraFactor = this->ft * yieldHardTwo * sqrt(2. / 3.) / 1.e-16 / sqrt(1. + 2. * pow(this->dilationConst, 2.) );
1253 } else {
1254 extraFactor = this->ft * yieldHardTwo * sqrt(2. / 3.) / rho / sqrt(1. + 2. * pow(this->dilationConst, 2.) );
1255 }
1256
1257 return deltaPlasticStrainNorm * extraFactor;
1258}
1259
1260
1261double
1263 double rho,
1264 double theta) const
1265{
1266 double rFunction = ( 4. * ( 1. - pow(this->ecc, 2.) ) * pow(cos(theta), 2.) + pow(2. * this->ecc - 1., 2.) ) / ( 2. * ( 1. - pow(this->ecc, 2.) ) * cos(theta) + ( 2. * this->ecc - 1. ) * sqrt(4. * ( 1. - pow(this->ecc, 2.) ) * pow(cos(theta), 2.) + 5. * pow(this->ecc, 2.) - 4. * this->ecc) );
1267
1268 double pHelp = -this->m * ( rho * rFunction / ( sqrt(6.) * fc ) + sig / fc );
1269
1270 double qHelp = -3. / 2. * pow(rho, 2.) / pow(this->fc, 2.);
1271
1272 double help = -0.5 * pHelp + sqrt(pow(pHelp, 2.) / 4. - qHelp);
1273
1274 double tempEquivStrain = 0.;
1275 if ( help > 0 ) {
1276 tempEquivStrain = help * e0;
1277 }
1278 return tempEquivStrain;
1279}
1280
1281
1282double
1283ConcreteDPM2::computeDamageParamTension(double equivStrain, double kappaOne, double kappaTwo, double le, double omegaOld, double rateFactor) const
1284{
1285 double omega = 0.;
1286
1287 //So that damage does not turn out to be negative if function is entered for equivstrains smaller thatn e0.
1288 double ftTemp = this->ft * ( 1. - yieldTolDamage );
1289
1290 double wfMod = this->wf;
1291 double wfOneMod = this->wfOne;
1292
1293 if ( this->strengthRateType > 0 ) {
1294 if ( this->energyRateType == 0 ) {
1295 wfMod /= pow(rateFactor, 2.);
1296 wfOneMod /= pow(rateFactor, 2.);
1297 } else if ( this->energyRateType == 1 ) {
1298 wfMod /= rateFactor;
1299 wfOneMod /= rateFactor;
1300 }
1301 }
1302
1303 double help;
1304 if ( equivStrain > e0 * ( 1. - yieldTolDamage ) ) {
1305 if ( softeningType == 0 ) { //linear
1306 omega = ( this->eM * equivStrain * wfMod - ftTemp * wfMod + ftTemp * kappaOne * le ) /
1307 ( this->eM * equivStrain * wfMod - ftTemp * le * kappaTwo );
1308 } else if ( softeningType == 1 ) { //bilinear: Calculate damage parameter for both parts of bilinear curve and check which fulfils limits.
1309 omega = ( this->eM * equivStrain * wfOneMod - ftTemp * wfOneMod - ( this->ftOne - ftTemp ) * kappaOne * le ) /
1310 ( this->eM * equivStrain * wfOneMod + ( this->ftOne - ftTemp ) * le * kappaTwo );
1311 help = le * kappaOne + le * omega * kappaTwo;
1312
1313 if ( help >= 0. && help < wfOneMod ) {
1314 return omega;
1315 }
1316
1317 omega = ( this->eM * equivStrain * ( wfMod - wfOneMod ) - this->ftOne * ( wfMod - wfOneMod ) +
1318 this->ftOne * kappaOne * le - this->ftOne * wfOneMod ) /
1319 ( this->eM * equivStrain * ( wfMod - wfOneMod ) - this->ftOne * le * kappaTwo );
1320 help = le * kappaOne + le * omega * kappaTwo;
1321
1322 if ( help > wfOneMod && help < wfMod ) {
1323 return omega;
1324 }
1325 } else if ( softeningType == 2 ) { //exponential: Iterative solution
1326 omega = 1.; //Initial guess
1327 double residual = 0.;
1328 double dResidualDOmega = 0.;
1329 int nite = 0;
1330
1331 do {
1332 nite++;
1333
1334 residual = ( 1 - omega ) * this->eM * equivStrain - ftTemp * exp(-le * ( omega * kappaTwo + kappaOne ) / wfMod);
1335 dResidualDOmega = -this->eM * equivStrain + ftTemp * le * kappaTwo / wfMod * exp(-le * ( omega * kappaTwo + kappaOne ) / wfMod);
1336
1337 omega -= residual / dResidualDOmega;
1338 if ( nite > newtonIter ) {
1339 OOFEM_ERROR("algorithm not converging");
1340 }
1341 } while ( fabs(residual / ftTemp) >= 1.e-8 );
1342 }
1343 } else {
1344 omega = 0.;
1345 }
1346
1347
1348 if ( omega > 1. ) {
1349 omega = 1.;
1350 }
1351
1352 if ( omega < 0. || omega < omegaOld ) {
1353 omega = omegaOld;
1354 }
1355
1356
1357 return omega;
1358}
1359
1360double
1361ConcreteDPM2::computeDamageParamCompression(double equivStrain, double kappaOne, double kappaTwo, double omegaOld, double rateFactor) const
1362{
1363 if ( this->damageFlag == 3 ) {
1364 return 0.;
1365 }
1366
1367 double ftTemp = this->ft * ( 1. - yieldTolDamage );
1368 double efCompressionMod = this->efCompression;
1369
1370 if ( this->strengthRateType > 0 ) {
1371 if ( this->energyRateType == 0 ) {
1372 efCompressionMod /= pow(rateFactor, 2.);
1373 } else if ( this->energyRateType == 1 ) {
1374 efCompressionMod /= rateFactor;
1375 }
1376 }
1377
1378 double omega = 1.;
1379 int nite = 0;
1380 double residual = 0.;
1381 double dResidualDOmega = 0.;
1382
1383 if ( equivStrain > e0 * ( 1. - yieldTolDamage ) ) {
1384 do {
1385 nite++;
1386
1387 residual = ( 1. - omega ) * this->eM * equivStrain - ftTemp * exp(-( kappaOne + omega * kappaTwo ) / efCompressionMod);
1388 dResidualDOmega = -this->eM * equivStrain + ftTemp * kappaTwo / efCompressionMod * exp(-( kappaOne + omega * kappaTwo ) / efCompressionMod);
1389
1390 omega -= residual / dResidualDOmega;
1391 if ( nite > newtonIter ) {
1392 OOFEM_ERROR("algorithm not converging");
1393 }
1394 } while ( fabs(residual / ft) >= 1.e-8 );
1395 } else {
1396 omega = 0.;
1397 }
1398
1399 if ( omega > 1. ) {
1400 omega = 1.;
1401 }
1402 if ( omega < omegaOld || omega < 0. ) {
1403 omega = omegaOld;
1404 }
1405
1406 return omega;
1407}
1408
1409
1410
1411void
1413 const FloatArrayF< 6 > &strain,
1414 GaussPoint *gp) const
1415{
1416 if ( kappaD <= e0 * ( 1. - yieldTolDamage ) ) {
1417 return;
1418 }
1419
1420 auto status = static_cast< ConcreteDPM2Status * >( this->giveStatus(gp) );
1421
1422 if ( helem > 0. ) {
1423 status->setLe(helem);
1424 } else if ( status->giveDamageTension() == 0. && status->giveDamageCompression() == 0. ) {
1425 //auto [principalStrains, principalDir] = computePrincipalValDir(from_voigt_strain(strain)); // c++17
1426 auto tmp = computePrincipalValDir(from_voigt_strain_6(strain) );
1427 auto principalStrains = tmp.first;
1428 auto principalDir = tmp.second;
1429
1430 // find index of max positive principal strain
1431 int indx = 1;
1432 for ( int i = 2; i <= 3; i++ ) {
1433 if ( principalStrains.at(i) > principalStrains.at(indx) ) {
1434 indx = i;
1435 }
1436 }
1437
1438 FloatArray crackPlaneNormal(3);
1439 for ( int i = 1; i <= 3; i++ ) {
1440 crackPlaneNormal.at(i) = principalDir.at(i, indx);
1441 }
1442
1443 // evaluate the projected element size
1444 double le = gp->giveElement()->giveCharacteristicLength(crackPlaneNormal);
1445 if ( le == 0. ) {
1446 le = gp->giveElement()->computeMeanSize();
1447 }
1448
1449 // store le in the corresponding status
1450 status->setLe(le);
1451 } else if ( status->giveLe() == 0. ) {
1452 // this happens if the status is initialized from a file
1453 // with nonzero damage
1454 // le determined as square root of element area or cube root of el. volume
1455 double le = gp->giveElement()->computeMeanSize();
1456 status->setLe(le);
1457 }
1458}
1459
1460
1461double
1462ConcreteDPM2::computeDuctilityMeasureDamage(GaussPoint *gp, const double sig, const double rho) const
1463{
1464 //1./sqrt(6.)=0.40824829
1465 double alphaZero = 0.40824829;
1466
1467 double Rs = 0;
1468 if ( sig < 0. ) {
1469 if ( rho > 1.e-16 ) {
1470 Rs = -sig / ( alphaZero * rho );
1471 } else { //Need to set a dummy valye
1472 Rs = -sig * 1.e16 / alphaZero;
1473 }
1474 } else {
1475 Rs = 0;
1476 }
1477
1478 return 1. + ( ASoft - 1. ) * Rs; // ductilityMeasure
1479}
1480
1481
1484{
1485 auto status = static_cast< ConcreteDPM2Status * >( this->giveStatus(gp) );
1486
1489
1490 //get plastic strain and kappa
1491 auto tempPlasticStrain = status->givePlasticStrain();
1492 double tempKappaP = status->giveKappaP();
1493
1494 //this theta computed here should stay constant for the rest of procedure.
1495
1496 const auto &oldStrain = status->giveReducedStrain();
1497
1498 // introduce a strange subincrementation flag
1499 int subIncrementFlag = 0;
1500
1501 double apexStress = 0.;
1502 int subincrementcounter = 0;
1503 //Attempt to implement subincrementation
1504 // initialize variables
1505 subIncrementFlag = 0;
1506 auto convergedStrain = oldStrain;
1507 auto tempStrain = strain;
1508 auto deltaStrain = strain - oldStrain;
1509
1510 FloatArrayF< 6 >effectiveStress;
1511
1512 //To get into the loop
1513 returnResult = RR_NotConverged;
1514 while ( returnResult == RR_NotConverged || subIncrementFlag == 1 ) {
1515 auto elasticStrain = tempStrain - tempPlasticStrain;
1516
1517 effectiveStress = dot(D, elasticStrain);
1518
1519 double sig, rho, theta;
1520 computeCoordinates(effectiveStress, sig, rho, theta);
1521 double yieldValue = computeYieldValue(sig, rho, theta, tempKappaP);
1522
1523 apexStress = 0.;
1524
1525 if ( yieldValue > 0. ) {
1526 checkForVertexCase(apexStress, returnType, sig, tempKappaP, gp);
1527 if ( returnType == RT_Tension || returnType == RT_Compression ) {
1528 tempKappaP = performVertexReturn(effectiveStress, returnResult, returnType, apexStress, tempKappaP, gp);
1529 status->letTempKappaPBe(tempKappaP);
1530 if ( returnType == RT_Tension ) {
1531 status->letTempStateFlagBe(ConcreteDPM2Status::ConcreteDPM2_VertexTension);
1532 } else if ( returnType == RT_Compression ) {
1533 status->letTempStateFlagBe(ConcreteDPM2Status::ConcreteDPM2_VertexCompression);
1534 }
1535 }
1536 if ( returnType == RT_Regular ) {
1537 tempKappaP = performRegularReturn(effectiveStress, returnResult, returnType, tempKappaP, gp, theta);
1538 status->letTempKappaPBe(tempKappaP);
1539 }
1540 } else {
1541 returnResult = RR_Converged;
1542 tempPlasticStrain = status->givePlasticStrain();
1543 status->letTempPlasticStrainBe(tempPlasticStrain);
1544 status->letTempKappaPBe(tempKappaP);
1545 break;
1546 }
1547
1548 if ( returnResult == RR_NotConverged ) {
1549 subincrementcounter++;
1550 if ( subincrementcounter > 10 ) {
1551 OOFEM_LOG_INFO("Unstable element %d \n", gp->giveElement()->giveGlobalNumber() );
1552 OOFEM_LOG_INFO("Old strain vector %g %g %g %g %g %g \n", oldStrain.at(1), oldStrain.at(2), oldStrain.at(3), oldStrain.at(4), oldStrain.at(5), oldStrain.at(6) );
1553
1554 const auto &help = status->giveTempPlasticStrain();
1555 OOFEM_LOG_INFO("Old plastic strain vector %g %g %g %g %g %g \n", help.at(1), help.at(2), help.at(3), help.at(4), help.at(5), help.at(6) );
1556 OOFEM_LOG_INFO("New strain vector %g %g %g %g %g %g \n", strain.at(1), strain.at(2), strain.at(3), strain.at(4), strain.at(5), strain.at(6) );
1557
1558 computeCoordinates(effectiveStress, sig, rho, theta);
1559 double sig1, rho1, theta1;
1560 auto help1 = dot(D, oldStrain - help);
1561 computeCoordinates(help1, sig1, rho1, theta1);
1562 yieldValue = computeYieldValue(sig, rho, theta, tempKappaP);
1563 OOFEM_LOG_INFO("OLD Sig %g rho %g theta %g \n", sig1, rho1, theta1);
1564 OOFEM_LOG_INFO("NEW Sig %g rho %g theta %g \n", sig, rho, theta);
1565 if ( returnType == RT_Tension || returnType == RT_Compression ) {
1566 OOFEM_LOG_INFO("Vertex case apexstress %g\n", apexStress);
1567 } else {
1568 OOFEM_LOG_INFO("Regular case %g \n", 15.18);
1569 }
1570 OOFEM_LOG_INFO("KappaP old %g new %g yieldfun %g\n", status->giveTempKappaP(), tempKappaP, yieldValue);
1571 OOFEM_ERROR("Could not reach convergence with small deltaStrain, giving up.");
1572 } else if ( subincrementcounter > 9 && tempKappaP < 1. ) {
1573 tempKappaP = 1.;
1574 status->letTempKappaPBe(tempKappaP);
1575 }
1576
1577 subIncrementFlag = 1;
1578 deltaStrain *= 0.5;
1579 tempStrain = convergedStrain + deltaStrain;
1580 } else if ( returnResult == RR_Converged && subIncrementFlag == 0 ) {
1581 auto C = inv(D); // compliance
1582 elasticStrain = dot(C, effectiveStress);
1583 tempPlasticStrain = strain - elasticStrain;
1584 status->letTempPlasticStrainBe(tempPlasticStrain);
1585 } else if ( returnResult == RR_Converged && subIncrementFlag == 1 ) {
1586 subincrementcounter = 0;
1587 auto C = inv(D); // compliance
1588 elasticStrain = dot(C, effectiveStress);
1589 tempPlasticStrain = tempStrain - elasticStrain;
1590 status->letTempPlasticStrainBe(tempPlasticStrain);
1591
1592 subIncrementFlag = 0;
1593 returnResult = RR_NotConverged;
1594 convergedStrain = tempStrain;
1595 deltaStrain = strain - convergedStrain;
1596 tempStrain = strain;
1597 }
1598 }
1599
1600 return effectiveStress;
1601}
1602
1603void
1605 ConcreteDPM2_ReturnType &returnType,
1606 double sig,
1607 double tempKappa,
1608 GaussPoint *gp) const
1609{
1610 //auto status = static_cast< ConcreteDPM2Status * >( this->giveStatus(gp) );
1611
1612 answer = 0.;
1613 if ( sig > 0. ) {
1614 returnType = RT_Tension;
1615 } else if ( sig < 0. && tempKappa < 1. ) {
1616 returnType = RT_Compression;
1617 } else {
1618 returnType = RT_Regular;
1619 }
1620}
1621
1622
1623double
1625 ConcreteDPM2_ReturnResult &returnResult,
1626 ConcreteDPM2_ReturnType &returnType,
1627 double apexStress, double tempKappaP,
1628 GaussPoint *gp) const
1629{
1630 //auto [deviatoricStressTrial, sigTrial] = computeDeviatoricVolumetricSplit(effectiveStress); // c++17
1631 auto tmp = computeDeviatoricVolumetricSplit(effectiveStress);
1632 auto deviatoricStressTrial = tmp.first;
1633 auto sigTrial = tmp.second;
1634
1635 //auto status = static_cast< ConcreteDPM2Status * >( this->giveStatus(gp) );
1636
1637 double rhoTrial = computeSecondCoordinate(deviatoricStressTrial);
1638
1639 double kappaInitial = tempKappaP;
1640
1641 double sig2 = apexStress;
1642
1643 tempKappaP = computeTempKappa(kappaInitial, sigTrial, rhoTrial, sigTrial);
1644
1645 double yieldValue = computeYieldValue(sigTrial, 0., 0., tempKappaP);
1646
1647 tempKappaP = computeTempKappa(kappaInitial, sigTrial, rhoTrial, sig2);
1648
1649 double yieldValueMid = computeYieldValue(sig2, 0., 0., tempKappaP);
1650
1651 if ( yieldValue * yieldValueMid >= 0. ) {
1652 returnType = RT_Regular;
1653 returnResult = RR_NotConverged;
1654 return kappaInitial;
1655 }
1656
1657 double dSig, sigAnswer;
1658 if ( yieldValue < 0.0 ) {
1659 dSig = sig2 - sigTrial;
1660 sigAnswer = sig2;
1661 } else {
1662 dSig = sigTrial - sig2;
1663 sigAnswer = sig2;
1664 }
1665
1666 for ( int j = 0; j < 250; j++ ) {
1667 dSig = 0.5 * dSig;
1668
1669 double sigMid = sigAnswer + dSig;
1670
1671
1672 tempKappaP = computeTempKappa(kappaInitial, sigTrial, rhoTrial, sigMid);
1673
1674 yieldValueMid = computeYieldValue(sigMid, 0., 0., tempKappaP);
1675
1676 if ( yieldValueMid <= 0. ) {
1677 sigAnswer = sigMid;
1678 }
1679
1680 if ( fabs(yieldValueMid) < yieldTol && yieldValueMid <= 0. ) {
1681 double ratioPotential =
1682 computeRatioPotential(sigAnswer, 0, tempKappaP);
1683
1684
1685 double ratioTrial = rhoTrial / ( sigTrial - sigAnswer );
1686
1687 if ( ( ( ( ratioPotential >= ratioTrial ) && returnType == RT_Tension ) ) ||
1688 ( ( ratioPotential <= ratioTrial ) && returnType == RT_Compression ) ) {
1689 for ( int i = 0; i < 3; i++ ) {
1690 effectiveStress.at(i + 1) = sigAnswer;
1691 }
1692
1693 for ( int i = 3; i < 6; i++ ) {
1694 effectiveStress.at(i + 1) = 0.;
1695 }
1696 returnResult = RR_Converged;
1697 return tempKappaP;
1698 } else {
1699 returnType = RT_Regular;
1700 returnResult = RR_NotConverged;
1701 return kappaInitial;
1702 }
1703 }
1704 }
1705
1706 for ( int i = 0; i < 3; i++ ) {
1707 effectiveStress.at(i + 1) = sigAnswer;
1708 }
1709
1710 for ( int i = 3; i < 6; i++ ) {
1711 effectiveStress.at(i + 1) = 0.;
1712 }
1713 returnResult = RR_Converged;
1714
1715 OOFEM_WARNING("Perform vertex return not converged!\n");
1716
1717 return tempKappaP;
1718}
1719
1720
1721double
1723 double sigTrial,
1724 double rhoTrial,
1725 double sig) const
1726{
1727 //This function is called, if stress state is in vertex case
1728 double equivalentDeltaPlasticStrain = sqrt(1. / 9. * pow( ( sigTrial - sig ) / ( kM ), 2. ) +
1729 pow(rhoTrial / ( 2. * gM ), 2.) );
1730
1731 double thetaVertex = M_PI / 3.;
1732 double ductilityMeasure = computeDuctilityMeasure(sig, 0., thetaVertex);
1733
1734 return kappaInitial + equivalentDeltaPlasticStrain / ductilityMeasure;
1735}
1736
1737
1738double
1740 double rho,
1741 double theta) const
1742{
1743 double thetaConst = pow(2. * cos(theta), 2.);
1744 double ductilityMeasure;
1745 double x = -( sig + fc / 3 ) / fc;
1746 if ( x < 0. ) {
1747 /*Introduce exponential help function which results in a smooth
1748 * transition. */
1749 double EHard = BHard - DHard;
1750 double FHard = ( BHard - DHard ) * CHard / ( AHard - BHard );
1751 ductilityMeasure = ( EHard * exp(x / FHard) + DHard ) / thetaConst;
1752 } else {
1753 ductilityMeasure = ( AHard + ( BHard - AHard ) * exp(-x / ( CHard ) ) ) / thetaConst;
1754 }
1755
1756 return ductilityMeasure;
1757}
1758
1759
1760double
1762 double rho,
1763 double tempKappa) const
1764{
1765 //compute yieldHard and yieldSoft
1766 double yieldHardOne = computeHardeningOne(tempKappa);
1767 double yieldHardTwo = computeHardeningTwo(tempKappa);
1768
1769 //Compute dilation parameter
1770 double AGParam = this->ft * yieldHardTwo * 3 / this->fc + m / 2;
1771 double BGParam =
1772 yieldHardTwo / 3. * ( 1. + this->ft / this->fc ) /
1773 ( log(AGParam) + log(this->dilationConst + 1.) - log(2 * this->dilationConst - 1.) - log(3. * yieldHardTwo + this->m / 2) );
1774
1775 double R = ( sig - ft / 3. * yieldHardTwo ) / fc / BGParam;
1776 double mQ = AGParam * exp(R);
1777
1778 double Bl = sig / fc + rho / ( fc * sqrt(6.) );
1779
1780 double Al = ( 1. - yieldHardOne ) * pow(Bl, 2.) + sqrt(3. / 2.) * rho / fc;
1781
1782 double dgdsig = 4. * ( 1. - yieldHardOne ) / fc * Al * Bl + pow(yieldHardOne, 2.) * mQ / fc;
1783
1784 double dgdrho = Al / ( sqrt(6.) * fc ) * ( 4. * ( 1. - yieldHardOne ) * Bl + 6. ) +
1785
1786 m * pow(yieldHardOne, 2.) / ( sqrt(6.) * fc );
1787
1788 return dgdrho / dgdsig * 3. * ( 1. - 2. * nu ) / ( 1. + nu );
1789}
1790
1791
1792double
1794 ConcreteDPM2_ReturnResult &returnResult,
1795 ConcreteDPM2_ReturnType &returnType,
1796 double kappaP,
1797 GaussPoint *gp,
1798 double theta) const
1799{
1800 auto status = static_cast< ConcreteDPM2Status * >( this->giveStatus(gp) );
1801
1802 //Define stressVariables
1803 double trialSig, trialRho;
1804
1805 auto trialStress = effectiveStress;
1806
1807 //compute invariants from stress state
1808 //auto [deviatoricTrialStress, trialSig] = computeDeviatoricVolumetricSplit(trialStress); // c++17
1809 auto tmp = computeDeviatoricVolumetricSplit(trialStress);
1810 auto deviatoricTrialStress = tmp.first;
1811 trialSig = tmp.second;
1812 trialRho = computeSecondCoordinate(deviatoricTrialStress);
1813
1814 double sig = trialSig;
1815 double rho = trialRho;
1816
1817 // Starting guess:
1818 double tempKappaP = kappaP;
1819
1820 // Look at the magnitudes of the residuals. You have to scale the yieldValue down.
1821 double yieldValue = computeYieldValue(sig, rho, theta, tempKappaP);
1822
1823 //initialise unknowns
1824 FloatArray unknowns;
1825 FloatArray residuals;
1826 residuals.resize(4);
1827 residuals.at(4) = yieldValue; //store in the last element of the array
1828 unknowns.resize(4);
1829 unknowns.at(1) = trialSig;
1830 unknowns.at(2) = trialRho;
1831 unknowns.at(3) = tempKappaP;
1832 unknowns.at(4) = 0.;
1833
1834 double deltaLambda = 0.;
1835 double normOfResiduals = 1.; //just to get into the loop
1836
1837 // N.R. iteration for finding the correct plastic return which is found when the norm of the residuals are equal to zero
1838
1839 int iterationCount = 0;
1840 while ( normOfResiduals > yieldTol ) {
1841 iterationCount++;
1842 if ( iterationCount == newtonIter ) {
1843 returnResult = RR_NotConverged;
1844
1845 return kappaP;
1846 }
1847
1848 auto residualsNorm = residuals;
1849 //Normalize residuals. Think about it more.
1850 residualsNorm.at(1) /= this->kM;
1851 residualsNorm.at(2) /= 2. * this->gM;
1852
1853 normOfResiduals = norm(residualsNorm);
1854
1855 if ( std::isnan(normOfResiduals) ) {
1856 returnResult = RR_NotConverged;
1857 return kappaP;
1858 }
1859
1860 if ( normOfResiduals > yieldTol ) {
1861 // Test to run newton iteration using inverse of Jacobian
1862 auto jacobian = computeJacobian(sig, rho, theta, tempKappaP, deltaLambda, gp);
1863
1864 try {
1865 auto deltaIncrement = solve( jacobian, FloatArrayF< 4 >(residuals) );
1866 unknowns -= deltaIncrement;
1867 } catch ( ... ) {
1868 returnResult = RR_NotConverged;
1869 return kappaP;
1870 }
1871
1872 unknowns.at(2) = max(unknowns.at(2), 0.); //Keep rho greater than zero!
1873 unknowns.at(3) = max(unknowns.at(3), kappaP); //Keep deltaKappa greater than zero!
1874 unknowns.at(4) = max(unknowns.at(4), 0.); //Keep deltaLambda greater than zero!
1875
1876 //compute residuals
1877 sig = unknowns.at(1);
1878 rho = unknowns.at(2);
1879 tempKappaP = unknowns.at(3);
1880 deltaLambda = unknowns.at(4);
1881
1882 /* Compute the mVector holding the derivatives of the g function and the hardening function*/
1883 auto dGDInv = computeDGDInv(sig, rho, tempKappaP);
1884 double dKappaDDeltaLambda = computeDKappaDDeltaLambda(sig, rho, theta, tempKappaP);
1885
1886 residuals.at(1) = sig - trialSig + this->kM * deltaLambda * dGDInv.at(1);
1887 residuals.at(2) = rho - trialRho + ( 2. * this->gM ) * deltaLambda * dGDInv.at(2);
1888 residuals.at(3) = -tempKappaP + kappaP + deltaLambda * dKappaDDeltaLambda;
1889 residuals.at(4) = computeYieldValue(sig, rho, theta, tempKappaP);
1890 }
1891 }
1892
1893
1894 //compute the principal directions of the stress
1895 //auto [helpStress, stressPrincipalDir] = StructuralMaterial :: computePrincipalValDir(from_voigt_stress(trialStress)); // c++17
1897 auto stressPrincipalDir = tmpEig.second;
1898
1899 FloatArrayF< 6 >stressPrincipal;
1900 stressPrincipal [ 0 ] = sig + sqrt(2. / 3.) * rho * cos(theta);
1901 stressPrincipal [ 1 ] = sig + sqrt(2. / 3.) * rho * cos(theta - 2. * M_PI / 3.);
1902 stressPrincipal [ 2 ] = sig + sqrt(2. / 3.) * rho * cos(theta + 2. * M_PI / 3.);
1903 effectiveStress = transformStressVectorTo(stressPrincipalDir, stressPrincipal, 1);
1904 returnResult = RR_Converged;
1905
1906 //Store deltaLambda in status
1907 status->letDeltaLambdaBe(deltaLambda);
1908
1909 return tempKappaP;
1910}
1911
1912
1915 double rho,
1916 double theta,
1917 double kappa,
1918 double deltaLambda,
1919 GaussPoint *gp) const
1920{
1921 auto dFDInv = computeDFDInv(sig, rho, theta, kappa);
1922 auto dGDInv = computeDGDInv(sig, rho, kappa);
1923 auto dDGDDInv = computeDDGDDInv(sig, rho, kappa);
1924
1925 double dKappaDDeltaLambda = computeDKappaDDeltaLambda(sig, rho, theta, kappa);
1926 double dFDKappa = computeDFDKappa(sig, rho, theta, kappa);
1927
1928 auto dDGDInvDKappa = computeDDGDInvDKappa(sig, rho, kappa);
1929
1930 double dDKappaDDeltaLambdaDKappa = computeDDKappaDDeltaLambdaDKappa(sig, rho, theta, kappa);
1931 auto dDKappaDDeltaLambdaDInv = computeDDKappaDDeltaLambdaDInv(sig, rho, theta, kappa);
1932
1934 /* Compute matrix*/
1935 answer.at(1, 1) = 1. + this->kM * deltaLambda * dDGDDInv.at(1, 1);
1936 answer.at(1, 2) = this->kM * deltaLambda * dDGDDInv.at(1, 2);
1937 answer.at(1, 3) = this->kM * deltaLambda * dDGDInvDKappa.at(1);
1938 answer.at(1, 4) = this->kM * dGDInv.at(1);
1939 /**/
1940 answer.at(2, 1) = 2. * this->gM * deltaLambda * dDGDDInv.at(2, 1);
1941 answer.at(2, 2) = 1. + 2. * this->gM * deltaLambda * dDGDDInv.at(2, 2);
1942 answer.at(2, 3) = 2. * this->gM * deltaLambda * dDGDInvDKappa.at(2);
1943 answer.at(2, 4) = 2. * this->gM * dGDInv.at(2);
1944 /**/
1945 answer.at(3, 1) = deltaLambda * dDKappaDDeltaLambdaDInv.at(1);
1946 answer.at(3, 2) = deltaLambda * dDKappaDDeltaLambdaDInv.at(2);
1947 answer.at(3, 3) = deltaLambda * dDKappaDDeltaLambdaDKappa - 1.;
1948 answer.at(3, 4) = dKappaDDeltaLambda;
1949 /**/
1950 answer.at(4, 1) = dFDInv.at(1);
1951 answer.at(4, 2) = dFDInv.at(2);
1952 answer.at(4, 3) = dFDKappa;
1953 answer.at(4, 4) = 0.;
1954 return answer;
1955}
1956
1957
1958
1959
1960double
1962 double rho,
1963 double theta,
1964 double tempKappa) const
1965{
1966 //compute yieldHard
1967 double yieldHardOne = computeHardeningOne(tempKappa);
1968 double yieldHardTwo = computeHardeningTwo(tempKappa);
1969
1970
1971 // compute elliptic function r
1972 double rFunction = ( 4. * ( 1. - pow(ecc, 2.) ) * pow(cos(theta), 2.) +
1973 pow( ( 2. * ecc - 1. ), 2. ) ) /
1974 ( 2. * ( 1. - pow(ecc, 2.) ) * cos(theta) +
1975 ( 2. * ecc - 1. ) * sqrt(4. * ( 1. - pow(ecc, 2.) ) * pow(cos(theta), 2.)
1976 + 5. * pow(ecc, 2.) - 4. * ecc) );
1977
1978 //compute help function Al
1979 double Al = ( 1. - yieldHardOne ) * pow( ( sig / fc + rho / ( sqrt(6.) * fc ) ), 2. ) +
1980 sqrt(3. / 2.) * rho / fc;
1981
1982 //Compute yield equation
1983 return pow(Al, 2.) +
1984 pow(yieldHardOne, 2.) * yieldHardTwo * m * ( sig / fc + rho * rFunction / ( sqrt(6.) * fc ) ) -
1985 pow(yieldHardOne, 2.) * pow(yieldHardTwo, 2.);
1986}
1987
1988
1989double
1991 double rho,
1992 double theta,
1993 double tempKappa) const
1994{
1995 double dFDKappa;
1996 //compute yieldHard and yieldSoft
1997 double yieldHardOne = computeHardeningOne(tempKappa);
1998 double yieldHardTwo = computeHardeningTwo(tempKappa);
1999 // compute the derivative of the hardening and softening laws
2000 double dYieldHardOneDKappa = computeHardeningOnePrime(tempKappa);
2001 double dYieldHardTwoDKappa = computeHardeningTwoPrime(tempKappa);
2002 //compute elliptic function r
2003 double rFunction =
2004 ( 4. * ( 1. - pow(ecc, 2) ) * pow(cos(theta), 2) + pow( ( 2. * ecc - 1. ), 2 ) ) /
2005 ( 2 * ( 1. - pow(ecc, 2) ) * cos(theta) + ( 2. * ecc - 1. ) * sqrt(4. * ( 1. - pow(ecc, 2) ) * pow(cos(theta), 2) + 5. * pow(ecc, 2) - 4. * ecc) );
2006
2007 //compute help functions Al, Bl
2008 double Al = ( 1. - yieldHardOne ) * pow( ( sig / fc + rho / ( sqrt(6.) * fc ) ), 2.) + sqrt(3. / 2.) * rho / fc;
2009
2010
2011 double Bl = sig / fc + rho / ( fc * sqrt(6.) );
2012 double dFDYieldHardOne = -2. * Al * pow(Bl, 2.)
2013 + 2. * yieldHardOne * yieldHardTwo * m * ( sig / fc + rho * rFunction / ( sqrt(6.) * fc ) ) - 2. * yieldHardOne * pow(yieldHardTwo, 2.);
2014
2015 double dFDYieldHardTwo = pow(yieldHardOne, 2.) * m * ( sig / fc + rho * rFunction / ( sqrt(6.) * fc ) ) - 2. * yieldHardTwo * pow(yieldHardOne, 2.);
2016
2017 // compute dFDKappa
2018 dFDKappa = dFDYieldHardOne * dYieldHardOneDKappa +
2019 dFDYieldHardTwo * dYieldHardTwoDKappa;
2020 /*
2021 * set dFDKappa to zero, if it becomes greater than zero.
2022 * dFDKappa can only be negative or zero in the converged state for
2023 * the case of hardenig and perfect plasticity. For trial stresses, however,
2024 * it might be psoitive, which may lead to convergency problems. Therefore,
2025 * it is set to zero in this cases.
2026 */
2027 if ( dFDKappa > 0. ) {
2028 dFDKappa = 0.;
2029 }
2030
2031 return dFDKappa;
2032}
2033
2036 double rho,
2037 double theta,
2038 double tempKappa) const
2039{
2040 //compute yieldHard
2041 double yieldHardOne = computeHardeningOne(tempKappa);
2042 double yieldHardTwo = computeHardeningTwo(tempKappa);
2043
2044 //compute elliptic function r
2045 double rFunction = ( 4. * ( 1. - ecc * ecc ) * cos(theta) * cos(theta) + ( 2. * ecc - 1. ) * ( 2. * ecc - 1. ) ) /
2046 ( 2. * ( 1. - ecc * ecc ) * cos(theta) + ( 2. * ecc - 1. ) * sqrt(4. * ( 1. - ecc * ecc ) * cos(theta) * cos(theta)
2047 + 5. * ecc * ecc - 4. * ecc) );
2048
2049 //compute help functions AL, BL
2050 double AL = ( 1. - yieldHardOne ) * pow( ( sig / fc + rho / ( sqrt(6.) * fc ) ), 2. ) + sqrt(3. / 2.) * rho / fc;
2051 double BL = sig / fc + rho / ( fc * sqrt(6.) );
2052
2053 //compute dfdsig
2054 double dfdsig = 4. * ( 1. - yieldHardOne ) / fc * AL * BL + yieldHardTwo * pow(yieldHardOne, 2.) * m / fc;
2055
2056 //compute dfdrho
2057 double dfdrho = AL / ( sqrt(6.) * fc ) * ( 4. * ( 1. - yieldHardOne ) * BL + 6. ) + rFunction * m * yieldHardTwo * pow(yieldHardOne, 2.) / ( sqrt(6.) * fc );
2058
2059 return {
2060 dfdsig, dfdrho
2061 };
2062}
2063
2064
2065double
2067 double rho,
2068 double theta,
2069 double tempKappa) const
2070{
2071 auto dGDInv = computeDGDInv(sig, rho, tempKappa);
2072 double equivalentDGDStress = sqrt(1. / 3. * pow(dGDInv [ 0 ], 2.) + pow(dGDInv [ 1 ], 2.) );
2073 double ductilityMeasure = computeDuctilityMeasure(sig, rho, theta);
2074 return equivalentDGDStress / ductilityMeasure; // dKappaDDeltaLambda
2075}
2076
2079 double rho,
2080 double theta,
2081 double tempKappa) const
2082{
2083 //Compute first and second derivative of plastic potential
2084 auto dGDInv = computeDGDInv(sig, rho, tempKappa);
2085 auto dDGDDInv = computeDDGDDInv(sig, rho, tempKappa);
2086
2087 //Compute equivalentDGDStress
2088 double equivalentDGDStress = sqrt(1. / 3. * pow(dGDInv [ 0 ], 2.) + pow(dGDInv [ 1 ], 2.) );
2089
2090 //computeDuctilityMeasure
2091 double ductilityMeasure = computeDuctilityMeasure(sig, rho, theta);
2092
2093 //Compute dEquivalentDGDStressDInv
2094 FloatArrayF< 2 >dEquivalentDGDStressDInv;
2095 dEquivalentDGDStressDInv [ 0 ] =
2096 ( 2. / 3. * dGDInv [ 0 ] * dDGDDInv(0, 0) + 2. * dGDInv [ 1 ] * dDGDDInv(1, 0) ) / ( 2. * equivalentDGDStress );
2097 dEquivalentDGDStressDInv [ 1 ] =
2098 ( 2. / 3. * dGDInv [ 0 ] * dDGDDInv(0, 1) + 2. * dGDInv [ 1 ] * dDGDDInv(1, 1) ) / ( 2. * equivalentDGDStress );
2099
2100
2101 // compute the derivative of
2102 auto dDuctilityMeasureDInv = computeDDuctilityMeasureDInv(sig, rho, theta, tempKappa);
2103
2104 FloatArrayF< 2 >answer;
2105 answer [ 0 ] = ( dEquivalentDGDStressDInv [ 0 ] * ductilityMeasure - equivalentDGDStress * dDuctilityMeasureDInv [ 0 ] ) / pow(ductilityMeasure, 2.);
2106 answer [ 1 ] = ( dEquivalentDGDStressDInv [ 1 ] * ductilityMeasure - equivalentDGDStress * dDuctilityMeasureDInv [ 1 ] ) / pow(ductilityMeasure, 2.);
2107 return answer;
2108}
2109
2112{
2113 auto tmp = computeDeviatoricVolumetricSplit(stress);
2114 auto deviatoricStress = tmp.first;
2115 double sig = tmp.second;
2116
2117 double rho = computeSecondCoordinate(deviatoricStress);
2118 double theta = computeThirdCoordinate(deviatoricStress);
2119
2120 auto dDKappaDDeltaLambdaDInv = computeDDKappaDDeltaLambdaDInv(sig, rho, theta, tempKappa);
2121
2122 // compute dDKappaDDeltaLambdaDCosTheta
2123 auto dGDInv = computeDGDInv(sig, rho, tempKappa);
2124
2125 double equivalentDGDStress = sqrt(1. / 3. * pow(dGDInv [ 0 ], 2.) + pow(dGDInv [ 1 ], 2.) );
2126
2127 double ductilityMeasure = computeDuctilityMeasure(sig, rho, theta);
2128
2129 //Reuse implementation to compute dKappaDDeltaLambdaDCosTheta
2130 //Ductility measure has in denominator (2*cos(theta))^2
2131 double dDKappaDDeltaLambdaDCosTheta = equivalentDGDStress / ductilityMeasure / cos(theta);
2132 // dDKappaDDeltaLambdaDCosTheta = 0.;
2133
2134 auto dSigDStress = computeDSigDStress();
2135 auto dRhoDStress = computeDRhoDStress(stress);
2136 auto dCosThetaDStress = computeDCosThetaDStress(stress);
2137
2138 dSigDStress *= dDKappaDDeltaLambdaDInv.at(1);
2139
2140 dRhoDStress *= dDKappaDDeltaLambdaDInv.at(2);
2141
2142 dCosThetaDStress *= dDKappaDDeltaLambdaDCosTheta;
2143
2144 auto dDKappaDDeltaLambdaDStress = dSigDStress + dRhoDStress + dCosThetaDStress;
2145
2146 return dDKappaDDeltaLambdaDStress;
2147}
2148
2150ConcreteDPM2::computeDDGDStressDKappa(const FloatArrayF< 6 > &stress, double tempKappa) const
2151{
2152 FloatArrayF< 6 >answer;
2153
2154 auto tmp = computeDeviatoricVolumetricSplit(stress);
2155 auto deviatoricStress = tmp.first;
2156 double sig = tmp.second;
2157
2158 double rho = computeSecondCoordinate(deviatoricStress);
2159 // double theta = computeThirdCoordinate(deviatoricStress);
2160
2161 auto dDGDInvDKappa = computeDDGDInvDKappa(sig, rho, tempKappa);
2162 auto dSigDStress = computeDSigDStress();
2163 auto dRhoDStress = computeDRhoDStress(stress);
2164
2165 answer = dSigDStress;
2166 answer *= dDGDInvDKappa.at(1);
2167
2168 FloatArrayF< 6 >temp1;
2169 temp1 = dRhoDStress;
2170 temp1 *= dDGDInvDKappa.at(2);
2171
2172 answer += temp1;
2173
2174 return answer;
2175}
2176
2177
2178
2179double
2180ConcreteDPM2::computeDDKappaDDeltaLambdaDKappa(double sig, double rho, double theta, double tempKappa) const
2181{
2182 //Compute first and second derivative of plastic potential
2183 auto dGDInv = computeDGDInv(sig, rho, tempKappa);
2184 auto dDGDInvDKappa = computeDDGDInvDKappa(sig, rho, tempKappa);
2185
2186 double equivalentDGDStress = sqrt( 1. / 3. * pow(dGDInv [ 0 ], 2.) + pow(dGDInv [ 1 ], 2.) );
2187
2188 double ductilityMeasure = computeDuctilityMeasure(sig, rho, theta);
2189 //Compute dEquivalentDGDStressDKappa
2190 double dEquivalentDGDStressDKappa =
2191 ( 2. / 3. * dGDInv [ 0 ] * dDGDInvDKappa [ 0 ] + 2. * dGDInv [ 1 ] * dDGDInvDKappa [ 1 ] ) / ( 2. * equivalentDGDStress );
2192
2193 return dEquivalentDGDStressDKappa / ductilityMeasure;
2194}
2195
2198 double rho,
2199 double theta,
2200 double tempKappa) const
2201{
2202 double thetaConst = pow(2. * cos(theta), 2.);
2203 double x = ( -( sig + fc / 3. ) ) / fc;
2204
2205 if ( x < 0. ) {
2206 double dXDSig = -1. / fc;
2207 /* Introduce exponential help function which results in a
2208 * smooth transition. */
2209 double EHard = BHard - DHard;
2210 double FHard = ( BHard - DHard ) * CHard / ( AHard - BHard );
2211
2212 double dDuctilityMeasureDX = EHard / FHard * exp(x / FHard) / thetaConst;
2213 return {
2214 dDuctilityMeasureDX *dXDSig, 0.
2215 };
2216 } else {
2217 double dXDSig = -1. / fc;
2218 double dDuctilityMeasureDX = -( BHard - AHard ) / ( CHard ) / thetaConst * exp(-x / ( CHard ) );
2219 return {
2220 dDuctilityMeasureDX *dXDSig, 0.
2221 };
2222 }
2223}
2224
2227 double rho,
2228 double tempKappa) const
2229{
2230 //compute yieldHard and yieldSoft
2231 double yieldHardOne = computeHardeningOne(tempKappa);
2232 double yieldHardTwo = computeHardeningTwo(tempKappa);
2233
2234 //Compute dilation parameter
2235 double AGParam = this->ft * yieldHardTwo * 3 / this->fc + m / 2;
2236 double BGParam =
2237 yieldHardTwo / 3. * ( 1. + this->ft / this->fc ) /
2238 ( log(AGParam) + log(this->dilationConst + 1.) - log(2 * this->dilationConst - 1.) - log(3. * yieldHardTwo + this->m / 2) );
2239
2240 double R = ( sig - ft / 3. * yieldHardTwo ) / fc / BGParam;
2241 double mQ = AGParam * exp(R);
2242
2243 double Bl = sig / fc + rho / ( fc * sqrt(6.) );
2244
2245 double Al = ( 1. - yieldHardOne ) * pow(Bl, 2.) + sqrt(3. / 2.) * rho / fc;
2246
2247 double dgdsig = 4. * ( 1. - yieldHardOne ) / fc * Al * Bl + pow(yieldHardOne, 2.) * mQ / fc;
2248
2249 double dgdrho = Al / ( sqrt(6.) * fc ) * ( 4. * ( 1. - yieldHardOne ) * Bl + 6. ) +
2250 m * pow(yieldHardOne, 2.) / ( sqrt(6.) * fc );
2251
2252 return {
2253 dgdsig, dgdrho
2254 };
2255}
2256
2259 double tempKappa) const
2260{
2261 double sig, rho, theta;
2262 computeCoordinates(stress, sig, rho, theta);
2263 auto dFDInv = computeDFDInv(sig, rho, theta, tempKappa);
2264
2265 double dRDCosTheta = computeDRDCosTheta(theta, this->ecc);
2266
2267 double yieldHardOne = computeHardeningOne(tempKappa);
2268 double yieldHardTwo = computeHardeningTwo(tempKappa);
2269
2270 //Compute dFDCosTheta. This was not needed for the stress return, but now for the tangent stiffness
2271 auto dFDCosTheta = dRDCosTheta * pow(yieldHardOne, 2.) * yieldHardTwo * m * rho / ( sqrt(6.) * fc );
2272
2273 auto dSigDStress = computeDSigDStress();
2274 auto dRhoDStress = computeDRhoDStress(stress);
2275 auto dCosThetaDStress = computeDCosThetaDStress(stress);
2276
2277 dSigDStress *= dFDInv.at(1);
2278 dRhoDStress *= dFDInv.at(2);
2279 dCosThetaDStress *= dFDCosTheta;
2280
2281 auto dFDStress = dSigDStress + dRhoDStress + dCosThetaDStress;
2282
2283 return dFDStress;
2284}
2285
2287ConcreteDPM2::computeDGDStress(const FloatArrayF< 6 > &stress, const double tempKappa) const
2288{
2289 auto tmp = computeDeviatoricVolumetricSplit(stress);
2290 auto deviatoricStress = tmp.first;
2291 double sig = tmp.second;
2292 double rho = computeSecondCoordinate(deviatoricStress);
2293
2294 //compute dGDSig*dSigDStress + dGDRho*dRhoDStress
2295 auto dGDInv = computeDGDInv(sig, rho, tempKappa);
2296 auto dSigDStress = computeDSigDStress();
2297 auto dRhoDStress = computeDRhoDStress(stress);
2298
2299 dSigDStress *= dGDInv.at(1);
2300 dRhoDStress *= dGDInv.at(2);
2301 dSigDStress += dRhoDStress;
2302
2303 return dSigDStress;
2304}
2305
2306
2307
2308//Debug
2311 const double deltaLambda,
2312 GaussPoint *gp,
2313 TimeStep *atTime,
2314 const double tempKappa) const
2315{
2316 FloatMatrixF< 8, 8 >jacobian;
2317 auto dFDStress = computeDFDStress(stress, tempKappa);
2318 auto dGDStress = computeDGDStress(stress, tempKappa);
2319 auto dDGDDStress = computeDDGDDStress(stress, tempKappa);
2320 auto dDGDStressDKappa = computeDDGDStressDKappa(stress, tempKappa);
2321 auto dDKappaDDeltaLambdaDStress = computeDDKappaDDeltaLambdaDStress(stress, tempKappa);
2322
2323 double sig, rho, theta;
2324 computeCoordinates(stress, sig, rho, theta);
2325
2326 double dFDKappa = computeDFDKappa(sig, rho, theta, tempKappa);
2327 double dKappaDDeltaLambda = computeDKappaDDeltaLambda(sig, rho, theta, tempKappa);
2328
2329 double dDKappaDDeltaLambdaDKappa = computeDDKappaDDeltaLambdaDKappa(sig, rho, theta, tempKappa);
2330
2331 auto d = this->linearElasticMaterial.give3dMaterialStiffnessMatrix(ElasticStiffness, gp, atTime);
2332
2333 auto helpA = dot(d, dDGDDStress);
2334
2335 //Assign jacobian
2336 for ( int i = 0; i < 6; i++ ) {
2337 for ( int j = 0; j < 6; j++ ) {
2338 if ( i == j ) {
2339 jacobian.at(i + 1, j + 1) = 1. + deltaLambda * helpA.at(i + 1, j + 1);
2340 } else {
2341 jacobian.at(i + 1, j + 1) = deltaLambda * helpA.at(i + 1, j + 1);
2342 }
2343 }
2344 }
2345
2346 FloatArrayF< 6 >helpB;
2347 helpB = dot(d, dDGDStressDKappa);
2348
2349 for ( int i = 0; i < 6; i++ ) {
2350 jacobian.at(i + 1, 7) = deltaLambda * helpB.at(i + 1);
2351 }
2352
2353 helpB = dot(d, dGDStress);
2354
2355 for ( int i = 0; i < 6; i++ ) {
2356 jacobian.at(i + 1, 8) = helpB.at(i + 1);
2357 }
2358
2359 for ( int i = 0; i < 6; i++ ) {
2360 jacobian.at(7, i + 1) = deltaLambda * dDKappaDDeltaLambdaDStress.at(i + 1);
2361 }
2362
2363
2364 jacobian.at(7, 7) = deltaLambda * dDKappaDDeltaLambdaDKappa - 1.;
2365 jacobian.at(7, 8) = dKappaDDeltaLambda;
2366
2367 for ( int i = 0; i < 6; i++ ) {
2368 jacobian.at(8, i + 1) = dFDStress.at(i + 1);
2369 }
2370
2371 jacobian.at(8, 7) = dFDKappa;
2372 jacobian.at(8, 8) = 0.;
2373
2374 return jacobian;
2375}
2376
2377
2380 const double tempKappa) const
2381{
2383
2384 auto tmp = computeDeviatoricVolumetricSplit(stress);
2385 auto deviatoricStress = tmp.first;
2386 double sig = tmp.second;
2387 double rho = computeSecondCoordinate(deviatoricStress);
2388
2389 //compute deriviates with respect to invariants
2390 auto dDGDDInv = computeDDGDDInv(sig, rho, tempKappa);
2391 auto dGDInv = computeDGDInv(sig, rho, tempKappa);
2392
2393 //Compute derivatives of invariants with respect to stress
2394 auto dRhoDStress = computeDRhoDStress(stress);
2395
2396 auto dDRhoDDStress = computeDDRhoDDStress(stress);
2397
2398 auto dSigDStress = computeDSigDStress();
2399
2400 //Assemble terms
2401
2402 //Compute (dDGDDSig*dSigDStress + dDGDSigDRho*dRhoDStress)*dSigDStress
2403 FloatArrayF< 6 >temp1;
2404 temp1 = dSigDStress;
2405 temp1 *= dDGDDInv.at(1, 1);
2406
2407 FloatArrayF< 6 >temp2;
2408 temp2 = dRhoDStress;
2409 temp2 *= dDGDDInv.at(1, 2);
2410
2411 temp1 += temp2;
2412
2414 helpA = dyad(temp1, dSigDStress);
2415
2416 //Compute (dDGDDRho*dRhoDStress + dDGDRhoDSig*dSigDStress)*dRhoDstress
2417 temp1 = dRhoDStress;
2418 temp1 *= dDGDDInv.at(2, 2);
2419
2420 temp2 = dSigDStress;
2421 temp2 *= dDGDDInv.at(2, 1);
2422
2423 temp1 += temp2;
2424
2426 helpB = dyad(temp1, dRhoDStress);
2427
2428 //compute dGDRho * dDRhoDDStress
2429 FloatMatrixF< 6, 6 >helpC = dDRhoDDStress;
2430 helpC *= dGDInv.at(2);
2431
2432 //The term dGDSig*dDSigDDStress is zero
2433
2434 //sum up all parts
2435 answer = helpA;
2436 answer += helpB;
2437 answer += helpC;
2438
2439 return answer;
2440}
2441
2444 double rho,
2445 double tempKappa) const
2446{
2447 //Compute dilation parameter
2448
2449 //compute yieldHard and yieldSoft
2450 double yieldHardOne = computeHardeningOne(tempKappa);
2451 double yieldHardTwo = computeHardeningTwo(tempKappa);
2452
2453 double dYieldHardOneDKappa = computeHardeningOnePrime(tempKappa);
2454 double dYieldHardTwoDKappa = computeHardeningTwoPrime(tempKappa);
2455
2456 //Compute dilation parameter
2457 double AGParam = this->ft * yieldHardTwo * 3 / this->fc + m / 2;
2458 double BGParam =
2459 yieldHardTwo / 3. * ( 1. + this->ft / this->fc ) /
2460 ( log(AGParam) + log(this->dilationConst + 1.) - log(2 * this->dilationConst - 1.) - log(3. * yieldHardTwo + this->m / 2) );
2461
2462 double R = ( sig - ft / 3. * yieldHardTwo ) / ( fc * BGParam );
2463 double mQ = AGParam * exp(R);
2464
2465 //Compute the derivative of mQ with respect to kappa
2466
2467 //Derivative of AGParam
2468 double dAGParamDKappa = dYieldHardTwoDKappa * 3. * this->ft / this->fc;
2469
2470 //Derivative of BGParam
2471 double BGParamTop = yieldHardTwo / 3. * ( 1. + this->ft / this->fc );
2472 double BGParamBottom = ( log(AGParam) + log(this->dilationConst + 1.) - log(2 * this->dilationConst - 1.) - log(3. * yieldHardTwo + this->m / 2) );
2473
2474 double dBGParamTopDKappa = dYieldHardTwoDKappa / 3. * ( 1. + this->ft / this->fc );
2475 double dBGParamBottomDKappa = 1. / AGParam * dAGParamDKappa - 3. * dYieldHardTwoDKappa / ( 3 * yieldHardTwo + m / 2. );
2476 double dBGParamDKappa = ( dBGParamTopDKappa * BGParamBottom - BGParamTop * dBGParamBottomDKappa ) / pow(BGParamBottom, 2.);
2477
2478 //Derivative of R
2479 double RTop = ( sig - ft / 3. * yieldHardTwo );
2480 double RBottom = fc * BGParam;
2481 double dRTopDKappa = -this->ft / 3. * dYieldHardTwoDKappa;
2482 double dRBottomDKappa = this->fc * dBGParamDKappa;
2483 double dRDKappa = ( dRTopDKappa * RBottom - RTop * dRBottomDKappa ) / pow(RBottom, 2.);
2484
2485 double dMQDKappa = dAGParamDKappa * exp(R) + AGParam * dRDKappa * exp(R);
2486
2487 double Bl = sig / fc + rho / ( fc * sqrt(6.) );
2488
2489 double Al = ( 1. - yieldHardOne ) * pow(Bl, 2.) + sqrt(3. / 2.) * rho / fc;
2490
2491 double dAlDYieldHard = -pow(Bl, 2.);
2492
2493 const double dDGDSigDKappa =
2494 ( -4. * Al * Bl / fc + 4. * ( 1 - yieldHardOne ) / fc * dAlDYieldHard * Bl ) * dYieldHardOneDKappa +
2495 dYieldHardOneDKappa * 2 * yieldHardOne * mQ / fc + pow(yieldHardOne, 2.) * dMQDKappa / fc;
2496
2497 //dDGDSigDKappa = 0.;
2498
2499 const double dDGDRhoDKappa =
2500 ( dAlDYieldHard / ( sqrt(6.) * fc ) * ( 4. * ( 1. - yieldHardOne ) * Bl + 6. ) -
2501 4. * Al / ( sqrt(6.) * fc ) * Bl + m / ( sqrt(6.) * fc ) * 2 * yieldHardOne ) * dYieldHardOneDKappa;
2502
2503 return {
2504 dDGDSigDKappa, dDGDRhoDKappa
2505 };
2506}
2507
2510 double rho,
2511 double tempKappa) const
2512{
2513 //compute yieldHardOne and yieldSoft
2514 double yieldHardOne = computeHardeningOne(tempKappa);
2515 double yieldHardTwo = computeHardeningTwo(tempKappa);
2516
2517 //CoQpute dilation parameter
2518 double AGParam = this->ft * yieldHardTwo * 3 / this->fc + m / 2;
2519 double BGParam =
2520 yieldHardTwo / 3. * ( 1. + this->ft / this->fc ) /
2521 ( log(AGParam) + log(this->dilationConst + 1.) - log(2 * this->dilationConst - 1.) - log(3. * yieldHardTwo + this->m / 2) );
2522
2523 double R = ( sig - ft / 3. * yieldHardTwo ) / fc / BGParam;
2524
2525 double dMQDSig = AGParam / ( BGParam * fc ) * exp(R);
2526
2527 //compute help parameter Al and Bl and the corresponding derivatives
2528 double Bl = sig / fc + rho / ( fc * sqrt(6.) );
2529
2530 double Al = ( 1. - yieldHardOne ) * pow(Bl, 2.) +
2531 sqrt(3. / 2.) * rho / fc;
2532
2533 double dAlDSig = 2. * ( 1. - yieldHardOne ) * Bl / fc;
2534 double dBlDSig = 1. / fc;
2535
2536 double dAlDRho = 2. * ( 1. - yieldHardOne ) * Bl / ( fc * sqrt(6.) ) + sqrt(3. / 2.) / fc;
2537 double dBlDRho = 1. / ( fc * sqrt(6.) );
2538
2539 //compute second derivatives of g
2540 double ddgddSig = 4. * ( 1. - yieldHardOne ) / fc * ( dAlDSig * Bl + Al * dBlDSig ) +
2541 pow(yieldHardOne, 2.) * dMQDSig / fc;
2542 // ddgddSig = 0.;
2543
2544 double ddgddRho = dAlDRho / ( sqrt(6.) * fc ) * ( 4. * ( 1. - yieldHardOne ) * Bl + 6. ) +
2545 Al * dBlDRho * 4. * ( 1. - yieldHardOne ) / ( sqrt(6.) * fc );
2546
2547 double ddgdSigdRho = 4. * ( 1. - yieldHardOne ) / fc * ( dAlDRho * Bl + Al * dBlDRho );
2548 // ddgdSigdRho = 0.;
2549
2550 double ddgdRhodSig = dAlDSig / ( sqrt(6.) * fc ) * ( 4. * ( 1. - yieldHardOne ) * Bl + 6. )
2551 + Al / ( sqrt(6.) * fc ) * ( 4. * ( 1. - yieldHardOne ) * dBlDSig );
2552 // ddgdRhodSig = 0.;
2553
2555 answer.at(1, 1) = ddgddSig;
2556 answer.at(1, 2) = ddgdSigdRho;
2557 answer.at(2, 1) = ddgdRhodSig;
2558 answer.at(2, 2) = ddgddRho;
2559 return answer;
2560}
2561
2562
2563
2564double
2566 FloatArrayF< 6 > &effectiveStressCompression,
2567 const FloatArrayF< 6 > &effectiveStress) const
2568{
2570 auto principalStress = tmp.first;
2571 auto stressPrincipalDir = tmp.second;
2572
2573 //Split the principal values in a tension and a compression part
2574 FloatArrayF< 6 >principalStressTension;
2575 FloatArrayF< 6 >principalStressCompression;
2576
2577 for ( int i = 1; i <= principalStress.giveSize(); i++ ) {
2578 if ( principalStress.at(i) >= 0 ) {
2579 principalStressTension.at(i) = principalStress.at(i);
2580 principalStressCompression.at(i) = 0.;
2581 } else {
2582 principalStressTension.at(i) = 0.;
2583 principalStressCompression.at(i) = principalStress.at(i);
2584 }
2585 }
2586
2587 //Transform the tension and compression principal stresses back to the original coordinate system
2588
2589 //Take care of type of stress state for tension
2590 effectiveStressTension = transformStressVectorTo(stressPrincipalDir, principalStressTension, 1);
2591
2592 //Take care of type of stress state for compression
2593 effectiveStressCompression = transformStressVectorTo(stressPrincipalDir, principalStressCompression, 1);
2594
2595 //Determine the two factors from the stress
2596
2597 double squareNormOfPrincipalStress = norm_squared(principalStress);
2598
2599 double alphaTension = 0.;
2600
2601 if ( squareNormOfPrincipalStress > 0 ) {
2602 for ( int i = 1; i <= principalStress.giveSize(); i++ ) {
2603 alphaTension += principalStressTension.at(i) *
2604 ( principalStressTension.at(i) + principalStressCompression.at(i) ) / squareNormOfPrincipalStress;
2605 }
2606 }
2607
2608 return 1. - alphaTension;
2609}
2610
2611
2612double
2614{
2615 if ( kappa <= 0. ) {
2616 return yieldHardInitial;
2617 } else if ( kappa > 0. && kappa < 1. ) {
2618 return
2619 ( 1. - yieldHardInitial - yieldHardPrimePeak ) * pow(kappa, 3.)
2620 - ( 3. * ( 1. - yieldHardInitial ) - 3. * yieldHardPrimePeak ) * pow(kappa, 2.)
2621 + ( 3. * ( 1. - yieldHardInitial ) - 2. * yieldHardPrimePeak ) * kappa
2623 } else {
2624 return 1.;
2625 }
2626}
2627
2628
2629double
2631{
2632 if ( kappa <= 0. ) {
2633 return 3. * ( 1 - yieldHardInitial ) - 2. * yieldHardPrimePeak;
2634 } else if ( kappa >= 0. && kappa < 1. ) {
2635 return
2636 3. * ( 1. - yieldHardInitial - yieldHardPrimePeak ) * pow(kappa, 2.)
2637 - 2. * ( 3. * ( 1. - yieldHardInitial ) - 3. * yieldHardPrimePeak ) * kappa
2638 + ( 3. * ( 1. - yieldHardInitial ) - 2. * yieldHardPrimePeak );
2639 } else {
2640 return 0.;
2641 }
2642}
2643
2644
2645double
2647{
2648 if ( kappa <= 0. ) {
2649 return 1.;
2650 } else if ( kappa > 0. && kappa < 1. ) {
2651 return 1.;
2652 } else {
2653 return 1. + ( kappa - 1. ) * yieldHardPrimePeak;
2654 }
2655}
2656
2657
2658double
2660{
2661 if ( kappa <= 0. ) {
2662 return 0.;
2663 } else if ( kappa >= 0. && kappa < 1. ) {
2664 return 0.;
2665 } else {
2666 return yieldHardPrimePeak;
2667 }
2668}
2669
2672 GaussPoint *gp,
2673 TimeStep *tStep) const
2674{
2675 auto status = static_cast< ConcreteDPM2Status * >( giveStatus(gp) );
2676 if ( mode == SecantStiffness ) {
2677 return this->compute3dSecantStiffness(gp, tStep);
2678 } else if ( mode == TangentStiffness ) {
2679 const int stateFlag = status->giveTempStateFlag();
2681 return this->compute3dTangentStiffness(gp, tStep);
2682 } else {
2683 return this->compute3dSecantStiffness(gp, tStep);
2684 }
2685 }
2686 //Elastic case
2687 return this->linearElasticMaterial.give3dMaterialStiffnessMatrix(mode, gp, tStep);
2688}
2689
2690
2693{
2694 auto status = static_cast< ConcreteDPM2Status * >( giveStatus(gp) );
2695
2696 // Damage parameters
2697 double omegaTension = min(status->giveTempDamageTension(), 0.999999);
2698 double omegaCompression = min(status->giveTempDamageCompression(), 0.999999);
2699
2700 double alpha = status->giveTempAlpha();
2701
2702 auto d = this->linearElasticMaterial.give3dMaterialStiffnessMatrix(ElasticStiffness, gp, tStep);
2703
2704 if ( damageFlag == 2 ) {
2705 d *= ( 1. - omegaTension );
2706 } else if ( damageFlag == 3 ) {
2707 d *= ( 1. - ( 1. - alpha ) * omegaTension ) * ( 1. - alpha * omegaCompression );
2708 }
2709
2710 return d;
2711}
2712
2715{
2717
2718 FloatArrayF< 6 >effectiveStress;
2719 auto status = static_cast< ConcreteDPM2Status * >( giveStatus(gp) );
2720 effectiveStress = status->giveTempEffectiveStress();
2721
2722 double tempKappa = status->giveTempKappaP();
2723 double deltaLambda = status->giveDeltaLambda();
2724
2725 //Computes only the plastic part of the tangent stiffness
2726 auto d = this->linearElasticMaterial.give3dMaterialStiffnessMatrix(ElasticStiffness, gp, tStep);
2727
2728 // Debug
2729 FloatMatrixF< 8, 8 >fullJacobian = computeFullJacobian(effectiveStress, deltaLambda, gp, tStep, tempKappa);
2730
2731 FloatMatrixF< 8, 8 >invFullJacobian = inv(fullJacobian);
2732
2734 for ( int i = 1; i <= 6; i++ ) {
2735 for ( int j = 1; j <= 6; j++ ) {
2736 help.at(i, j) = invFullJacobian.at(i, j);
2737 }
2738 }
2739
2740 answer = dot(help, d);
2741
2742 // Damage parameters
2743 double omegaTension = min(status->giveTempDamageTension(), 0.999999);
2744 double omegaCompression = min(status->giveTempDamageCompression(), 0.999999);
2745 double alpha = status->giveTempAlpha();
2746
2747 if ( damageFlag == 2 ) {
2748 answer *= ( 1. - ( 1. - alpha ) * omegaTension ) * ( 1. - alpha * omegaCompression );
2749 } else if ( damageFlag == 3 ) {
2750 answer *= ( 1. - omegaTension );
2751 }
2752
2753 return answer;
2754}
2755
2756void
2757ConcreteDPM2::computeCoordinates(const FloatArrayF< 6 > &stress, double &sigNew, double &rhoNew, double &thetaNew) const
2758{
2759 auto tmp = computeDeviatoricVolumetricSplit(stress);
2760 auto deviatoricStress = tmp.first;
2761 sigNew = tmp.second;
2762 rhoNew = computeSecondCoordinate(deviatoricStress);
2763 thetaNew = computeThirdCoordinate(deviatoricStress);
2764}
2765
2766void
2768{
2769 auto status = static_cast< ConcreteDPM2Status * >( this->giveStatus(gp) );
2770
2771 //Get kappaD from status to define state later on
2772 double damageTension = status->giveDamageTension();
2773 double damageCompression = status->giveDamageCompression();
2774 double tempDamageTension = status->giveTempDamageTension();
2775 double tempDamageCompression = status->giveTempDamageCompression();
2776 double kappaP = status->giveKappaP();
2777 double tempKappaP = status->giveTempKappaP();
2778
2779 if ( tempKappaP > kappaP ) {
2780 if ( tempDamageTension > damageTension || tempDamageTension == 1. ||
2781 tempDamageCompression > damageCompression || tempDamageCompression == 1. ) {
2782 if ( status->giveTempStateFlag() == ConcreteDPM2Status::ConcreteDPM2_VertexTension ) {
2783 status->letTempStateFlagBe(ConcreteDPM2Status::ConcreteDPM2_VertexTensionDamage);
2784 } else if ( status->giveTempStateFlag() == ConcreteDPM2Status::ConcreteDPM2_VertexTension ) {
2786 } else {
2787 status->letTempStateFlagBe(ConcreteDPM2Status::ConcreteDPM2_PlasticDamage);
2788 }
2789 } else {
2790 status->letTempStateFlagBe(ConcreteDPM2Status::ConcreteDPM2_Plastic);
2791 }
2792 } else {
2793 const int state_flag = status->giveStateFlag();
2794 if ( tempDamageTension > damageTension || tempDamageTension == 1. ||
2795 tempDamageCompression > damageCompression || tempDamageCompression == 1. ) {
2796 status->letTempStateFlagBe(ConcreteDPM2Status::ConcreteDPM2_Damage);
2797 } else {
2798 if ( state_flag == ConcreteDPM2Status::ConcreteDPM2_Elastic ) {
2799 status->letTempStateFlagBe(ConcreteDPM2Status::ConcreteDPM2_Elastic);
2800 } else {
2801 status->letTempStateFlagBe(ConcreteDPM2Status::ConcreteDPM2_Unloading);
2802 }
2803 }
2804 }
2805}
2806
2807
2808double
2809ConcreteDPM2::computeDRDCosTheta(const double theta, const double ecc) const
2810{
2811 // double thetaCrit = M_PI/3.*0.999;
2812 double ACostheta = 4. * ( 1. - ecc * ecc ) * cos(theta) * cos(theta) +
2813 ( 2. * ecc - 1. ) * ( 2. * ecc - 1. );
2814 double BCostheta = 2. * ( 1. - ecc * ecc ) * cos(theta) +
2815 ( 2. * ecc - 1. ) * sqrt(4. * ( 1. - ecc * ecc ) * cos(theta) * cos(theta)
2816 + 5. * ecc * ecc - 4. * ecc);
2817 double A1Costheta = 8. * ( 1. - pow(ecc, 2.) ) * cos(theta);
2818 double B1Costheta = 2. * ( 1. - pow(ecc, 2.) ) +
2819 4. * ( 2. * ecc - 1. ) * ( 1. - pow(ecc, 2.) ) * cos(theta) /
2820 sqrt(4. * ( 1. - pow(ecc, 2.) ) * pow(cos(theta), 2.) +
2821 5. * pow(ecc, 2.) - 4. * ecc);
2822 double dRDCostheta = A1Costheta / BCostheta - ACostheta / pow(BCostheta, 2.) * B1Costheta;
2823 return dRDCostheta;
2824}
2825
2826double
2827ConcreteDPM2::computeDDRDDCosTheta(const double theta, const double ecc) const
2828{
2829 // double thetaCrit = M_PI/3.*0.999;
2830 // if (thetaCrit<theta){
2831 // printf("theta = %e\n", theta);
2832 // return 0;
2833 // }
2834
2835 //compute the derivative of the rFunction with respect to costheta
2836 double atheta = 4. * ( 1. - ecc * ecc ) * cos(theta) * cos(theta) +
2837 ( 2. * ecc - 1. ) * ( 2. * ecc - 1. );
2838 double btheta = 2. * ( 1. - ecc * ecc ) * cos(theta) +
2839 ( 2. * ecc - 1. ) * sqrt(4. * ( 1. - ecc * ecc ) * cos(theta) * cos(theta)
2840 + 5. * ecc * ecc - 4. * ecc);
2841 double a1theta = 8. * ( 1. - ecc * ecc ) * cos(theta);
2842 double b1theta = 2. * ( 1. - ecc * ecc ) +
2843 4. * ( 2. * ecc - 1. ) * ( 1. - ecc * ecc ) * cos(theta) /
2844 sqrt(4. * ( 1. - ecc * ecc ) * cos(theta) * cos(theta) +
2845 5. * ecc * ecc - 4. * ecc);
2846
2847 //compute the second derivative of rFunction with respect to theta
2848 double a2theta = 8. * ( 1. - pow(ecc, 2.) );
2849 double Ntheta = 4. * ( 1. - ecc * ecc ) * cos(theta) * cos(theta) +
2850 5. * ecc * ecc - 4. * ecc;
2851 printf( "cos(theta) = %e\n", cos(theta) );
2852 double b2theta = 4. * ( 2. * ecc - 1. ) * ( 1. - ecc * ecc ) / sqrt(Ntheta) *
2853 ( 1. - 4. * ( 1. - ecc * ecc ) * cos(theta) * cos(theta) / Ntheta );
2854 double ddrddcostheta = a2theta / btheta - 2. * a1theta * b1theta / ( btheta * btheta ) -
2855 atheta * b2theta / ( btheta * btheta ) +
2856 2. * atheta * b1theta * b1theta / ( btheta * btheta * btheta );
2857
2858 return ddrddcostheta;
2859}
2860
2861
2864{
2865 //compute volumetric deviatoric split
2866 auto deviatoricStress = computeDeviator(stress);
2867
2868 //compute the coordinates
2869 double rho = computeSecondCoordinate(deviatoricStress);
2870
2871 //compute principal stresses and directions
2872 //auto [principalDeviatoricStress, principalDir] = computePrincipalValDir(from_voigt_stress(deviatoricStress)); // c++17
2873 auto tmp = computePrincipalValDir(from_voigt_stress_6(deviatoricStress) );
2874 auto principalDeviatoricStress = tmp.first;
2875 auto principalDir = tmp.second;
2876
2877 //compute the derivative of s1 with respect to the cartesian stress
2878 FloatArrayF< 6 >ds1DStress;
2879 ds1DStress.at(1) = principalDir.at(1, 1) * principalDir.at(1, 1) - 1. / 3.;
2880 ds1DStress.at(2) = principalDir.at(2, 1) * principalDir.at(2, 1) - 1. / 3.;
2881 ds1DStress.at(3) = principalDir.at(3, 1) * principalDir.at(3, 1) - 1. / 3.;
2882 ds1DStress.at(4) = 2. * principalDir.at(2, 1) * principalDir.at(3, 1);
2883 ds1DStress.at(5) = 2. * principalDir.at(3, 1) * principalDir(1, 1);
2884 ds1DStress.at(6) = 2. * principalDir.at(1, 1) * principalDir.at(2, 1);
2885
2886 //compute dCosThetaDStress
2887 auto dCosThetaDStress = ds1DStress * ( sqrt(3. / 2.) * rho / pow(rho, 2.) ) +
2888 computeDRhoDStress(stress) * ( -sqrt(3. / 2.) * principalDeviatoricStress [ 0 ] / pow(rho, 2.) );
2889 return dCosThetaDStress;
2890}
2891
2892
2895{
2896 //compute volumetric deviatoric split
2897 auto deviatoricStress = computeDeviator(stress);
2898
2899 //compute the coordinate
2900 double rho = computeSecondCoordinate(deviatoricStress);
2901
2902 //compute principal stresses and directions
2903 //auto [principalDeviatoricStress, principalDir] = computePrincipalValDir(from_voigt_stress(deviatoricStress)); // c++17
2904 auto tmp = computePrincipalValDir(from_voigt_stress_6(deviatoricStress) );
2905 auto principalDeviatoricStress = tmp.first;
2906 auto principalDir = tmp.second;
2907
2908
2909 //compute the derivative of s1 with respect to the cartesian stress
2910 FloatArrayF< 6 >dS1DStress;
2911 dS1DStress.at(1) = principalDir.at(1, 1) * principalDir.at(1, 1) - 1. / 3.;
2912 dS1DStress.at(2) = principalDir.at(2, 1) * principalDir.at(2, 1) - 1. / 3.;
2913 dS1DStress.at(3) = principalDir.at(3, 1) * principalDir.at(3, 1) - 1. / 3.;
2914 dS1DStress.at(4) = 2. * principalDir.at(2, 1) * principalDir.at(3, 1);
2915 dS1DStress.at(5) = 2. * principalDir.at(3, 1) * principalDir.at(1, 1);
2916 dS1DStress.at(6) = 2. * principalDir.at(1, 1) * principalDir.at(2, 1);
2917
2918 //compute the second derivative of costheta
2919 FloatMatrixF< 6, 6 >dDCosThetaDDStress;
2920 //compute the product of dS1DStress and DRhoDStress
2921 auto dRhoDStress = computeDRhoDStress(stress);
2922 FloatMatrixF< 6, 6 >dS1DRho;
2923 for ( int v = 0; v < 6; v++ ) {
2924 for ( int w = 0; w < 6; w++ ) {
2925 dS1DRho.at(v + 1, w + 1) = dS1DStress.at(v + 1) * dRhoDStress.at(w + 1);
2926 }
2927 }
2928
2929 //compute the square of dRhoDStress and DRhoDStress
2930 FloatMatrixF< 6, 6 >dRhoDRho;
2931 for ( int v = 0; v < 6; v++ ) {
2932 for ( int w = 0; w < 6; w++ ) {
2933 dRhoDRho.at(v + 1, w + 1) = dRhoDStress.at(v + 1) * dRhoDStress.at(w + 1);
2934 }
2935 }
2936
2937 //compute the product of dRhoDStress and DS1DStress
2938 FloatMatrixF< 6, 6 >dRhoDS1;
2939 for ( int v = 0; v < 6; v++ ) {
2940 for ( int w = 0; w < 6; w++ ) {
2941 dRhoDS1.at(v + 1, w + 1) = dRhoDStress.at(v + 1) * dS1DStress.at(w + 1);
2942 }
2943 }
2944
2945 auto dDRhoDDStress = computeDDRhoDDStress(stress);
2946 dDCosThetaDDStress = dDRhoDDStress;
2947 dDCosThetaDDStress *= ( -sqrt(3. / 2.) * principalDeviatoricStress.at(1) / pow(rho, 2.) );
2948
2949 auto helpB1 = dS1DRho;
2950 helpB1 *= ( -sqrt(3. / 2.) / pow(rho, 2.) );
2951
2952 auto helpC1 = dRhoDRho;
2953 helpC1 *= ( sqrt(6.) * principalDeviatoricStress.at(1) / pow(rho, 3.) );
2954
2955 auto helpD1 = dRhoDS1;
2956 helpD1 *= ( -sqrt(3. / 2.) / pow(rho, 2.) );
2957 dDCosThetaDDStress += helpB1;
2958 dDCosThetaDDStress += helpC1;
2959 dDCosThetaDDStress += helpD1;
2960
2961 return dDCosThetaDDStress;
2962}
2963
2964
2967{
2968 //compute volumetric deviatoric split
2969 auto deviatoricStress = computeDeviator(stress);
2970 double rho = computeSecondCoordinate(deviatoricStress);
2971
2972 //compute the derivative of J2 with respect to the stress
2973 auto dJ2DStress = deviatoricStress;
2974 for ( int i = 3; i < 6; i++ ) {
2975 dJ2DStress.at(i + 1) = deviatoricStress.at(i + 1) * 2.0;
2976 }
2977
2978 //compute the derivative of rho with respect to stress
2979 return dJ2DStress * ( 1. / rho );
2980}
2981
2984{
2985 return {
2986 1. / 3., 1. / 3., 1. / 3., 0., 0., 0.
2987 };
2988}
2989
2990
2993{
2994 //compute volumetric deviatoric split
2995 auto deviatoricStress = computeDeviator(stress);
2996 double rho = computeSecondCoordinate(deviatoricStress);
2997
2998 //compute first dericative of J2
2999 auto dJ2dstress = deviatoricStress;
3000 for ( int i = 3; i < 6; i++ ) {
3001 dJ2dstress.at(i + 1) = deviatoricStress.at(i + 1) * 2.;
3002 }
3003
3004 //compute second derivative of J2
3005 FloatMatrixF< 6, 6 >ddJ2ddstress;
3006 for ( int i = 0; i < 6; i++ ) {
3007 if ( i < 3 ) {
3008 ddJ2ddstress.at(i + 1, i + 1) = 2. / 3.;
3009 }
3010
3011 if ( i > 2 ) {
3012 ddJ2ddstress.at(i + 1, i + 1) = 2.;
3013 }
3014 }
3015
3016 ddJ2ddstress.at(1, 2) = -1. / 3.;
3017 ddJ2ddstress.at(1, 3) = -1. / 3.;
3018 ddJ2ddstress.at(2, 1) = -1. / 3.;
3019 ddJ2ddstress.at(2, 3) = -1. / 3.;
3020 ddJ2ddstress.at(3, 1) = -1. / 3.;
3021 ddJ2ddstress.at(3, 2) = -1. / 3.;
3022
3023 return ddJ2ddstress * ( 1. / rho ) + dyad(dJ2dstress, dJ2dstress) * ( -1. / ( rho * rho * rho ) );
3024}
3025
3026int
3028 GaussPoint *gp,
3029 InternalStateType type,
3030 TimeStep *tStep)
3031{
3032 auto status = static_cast< ConcreteDPM2Status * >( this->giveStatus(gp) );
3033
3034 switch ( type ) {
3035 case IST_PlasticStrainTensor:
3036 answer = status->givePlasticStrain();
3037 return 1;
3038
3039 case IST_DamageTensor:
3040 answer.resize(6);
3041 answer.zero();
3042 answer.at(1) = status->giveDamageTension();
3043 answer.at(2) = status->giveDamageCompression();
3044 answer.at(3) = status->giveDissWork();
3045 return 1;
3046
3047#ifdef keep_track_of_dissipated_energy
3048 case IST_StressWorkDensity:
3049 answer.resize(1);
3050 answer.at(1) = status->giveStressWork();
3051 return 1;
3052
3053 case IST_DissWorkDensity:
3054 answer.resize(1);
3055 answer.at(1) = status->giveDissWork();
3056 return 1;
3057
3058 case IST_FreeEnergyDensity:
3059 answer.resize(1);
3060 answer.at(1) = status->giveStressWork() - status->giveDissWork();
3061 return 1;
3062
3063#endif
3064 default:
3065 return StructuralMaterial::giveIPValue(answer, gp, type, tStep);
3066 }
3067}
3068
3069std::unique_ptr<MaterialStatus>
3071{
3072 return std::make_unique<ConcreteDPM2Status>(gp);
3073}
3074} //end of namespace
#define REGISTER_Material(class)
int state_flag
Indicates the state (i.e. elastic, unloading, plastic, damage, vertex) of the Gauss point.
double rateStrain
Strains that are used for calculation of strain rates.
void initTempStatus() override
void computeWork(GaussPoint *gp, double ft)
FloatArrayF< 6 > reducedStrain
const FloatArrayF< 6 > & giveTempPlasticStrain() const
double tempStressWork
Non-equilibrated density of total work done by stresses on strain increments.
double giveTempStressWork()
Returns the temp density of total work of stress on strain increments.
void updateYourself(TimeStep *tStep) override
void setTempDissWork(double w)
Sets the density of dissipated work to given value.
double dissWork
Density of dissipated work.
FloatArrayF< 6 > plasticStrain
void saveContext(DataStream &stream, ContextMode mode) override
double stressWork
Density of total work done by stresses on strain increments.
const FloatArrayF< 6 > & giveTempReducedStrain() const
void setTempStressWork(double w)
Sets the density of total work of stress on strain increments to given value.
void printOutputAt(FILE *file, TimeStep *tStep) const override
Print receiver's output to given stream.
void restoreContext(DataStream &stream, ContextMode mode) override
ConcreteDPM2Status(GaussPoint *gp)
Constructor.
FloatArrayF< 6 > tempPlasticStrain
double giveDamageTension() const
double tempDissWork
Non-equilibrated density of dissipated work.
FloatArrayF< 6 > tempReducedStrain
const FloatArrayF< 6 > & giveReducedStrain() const
FloatArrayF< 2 > computeDFDInv(double sig, double rho, double theta, double tempKappa) const
double yieldHardInitial
Parameter of the hardening law of the plasticity model.
FloatArrayF< 6 > computeDGDStress(const FloatArrayF< 6 > &stress, const double tempKappa) const
double deltaTime
Input parameter which simulates a loading rate. Only for debugging purposes.
double AHard
Parameter of the ductilityMeasure of the plasticity model.
FloatArrayF< 2 > computeDDGDInvDKappa(double sig, double rho, double tempKappa) const
void assignStateFlag(GaussPoint *gp) const
Assign state flag.
double computeDFDKappa(double sig, double rho, double theta, double tempKappa) const
FloatArrayF< 6 > performPlasticityReturn(GaussPoint *gp, const FloatMatrixF< 6, 6 > &D, const FloatArrayF< 6 > &strain) const
double yieldTolDamage
yield tolerance for the damage model.
double hardeningModulus
Hardening modulus.
FloatMatrixF< 8, 8 > computeFullJacobian(const FloatArrayF< 6 > &stress, const double deltaLambda, GaussPoint *gp, TimeStep *atTime, const double tempKappa) const
FloatMatrixF< 2, 2 > computeDDGDDInv(double sig, double rho, double tempKappa) const
FloatArrayF< 2 > computeDGDInv(double sig, double rho, double tempKappa) const
ConcreteDPM2(int n, Domain *d)
Constructor.
double ftOne
Control parameter for the bilinear softening law.
FloatArrayF< 6 > computeDRhoDStress(const FloatArrayF< 6 > &stress) const
Computes the derivative of rho with respect to the stress.
void saveContext(DataStream &stream, ContextMode mode) override
double computeHardeningTwo(double tempKappa) const
double mQ
Dilation parameter of the plastic potential.
double computeDKappaDDeltaLambda(double sig, double rho, double theta, double tempKappa) const
double DHard
Parameter of the ductilityMeasure of the plasticity model.
double computeAlpha(FloatArrayF< 6 > &effectiveStressTension, FloatArrayF< 6 > &effectiveStressCompression, const FloatArrayF< 6 > &effectiveStress) const
Compute alpha for rate effect.
FloatMatrixF< 6, 6 > computeDDCosThetaDDStress(const FloatArrayF< 6 > &stress) const
double computeDDKappaDDeltaLambdaDKappa(double sig, double rho, double theta, double tempKappa) const
std::unique_ptr< MaterialStatus > CreateStatus(GaussPoint *gp) const override
double computeDRDCosTheta(const double theta, const double ecc) const
Computes the derivative of function r with respect to cos theta.
double computeDuctilityMeasureDamage(GaussPoint *gp, const double sig, const double rho) const
Compute the ductility measure for the damage model.
FloatArrayF< 2 > computeDamage(const FloatArrayF< 6 > &strain, const FloatMatrixF< 6, 6 > &D, double timeFactor, GaussPoint *gp, TimeStep *tStep, double alpha, const FloatArrayF< 6 > &effectiveStress) const
Compute damage parameters.
int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep) override
bool hasMaterialModeCapability(MaterialMode mode) const override
int softeningType
Type of softening function used.
double gM
Elastic shear modulus.
virtual double computeDuctilityMeasure(double sig, double rho, double theta) const
double computeYieldValue(double sig, double rho, double theta, double tempKappa) const
FloatArrayF< 2 > computeDDuctilityMeasureDInv(double sig, double rho, double theta, double tempKappa) const
double performRegularReturn(FloatArrayF< 6 > &stress, ConcreteDPM2_ReturnResult &returnResult, ConcreteDPM2_ReturnType &returnType, double kappaP, GaussPoint *gp, double theta) const
double nu
Elastic poisson's ration.
double kM
Elastic bulk modulus.
virtual double computeDamageParamTension(double equivStrain, double kappaOne, double kappaTwo, double le, double omegaOld, double rateFactor) const
Compute damage parameter in tension.
double CHard
Parameter of the ductilityMeasure of the plasticity model.
void initDamaged(double kappa, const FloatArrayF< 6 > &strain, GaussPoint *gp) const
FloatArrayF< 6 > computeDSigDStress() const
Computes the derivative of sig with respect to the stress.
FloatMatrixF< 6, 6 > compute3dTangentStiffness(GaussPoint *gp, TimeStep *tStep) const
Compute the 3d tangent stiffness matrix.
double computeTempKappa(double kappaInitial, double sigTrial, double rhoTrial, double sig) const
Compute tempKappa.
double fc
Parameters of the yield surface of the plasticity model. fc is the uniaxial compressive strength,...
double helem
Element size (to be used in fracture energy approach (crack band).
FloatArrayF< 6 > computeDCosThetaDStress(const FloatArrayF< 6 > &stress) const
double computeRatioPotential(double sig, double rho, double tempKappa) const
FloatArrayF< 6 > computeDFDStress(const FloatArrayF< 6 > &stress, const double tempKappa) const
double BHard
Parameter of the ductilityMeasure of the plasticity model.
FloatArrayF< 6 > computeDDGDStressDKappa(const FloatArrayF< 6 > &stress, double tempKappa) const
double dilationConst
Control parameter for te volumetric plastic flow of the plastic potential.
double performVertexReturn(FloatArrayF< 6 > &stress, ConcreteDPM2_ReturnResult &returnResult, ConcreteDPM2_ReturnType &returnType, double apexStress, double tempKappaP, GaussPoint *gp) const
void initializeFrom(InputRecord &ir) override
FloatMatrixF< 6, 6 > computeDDRhoDDStress(const FloatArrayF< 6 > &stress) const
Computes the second derivative of rho with the respect to the stress.
IsotropicLinearElasticMaterial linearElasticMaterial
Pointer for linear elastic material.
double computeDeltaPlasticStrainNormTension(double tempKappaD, double kappaD, GaussPoint *gp) const
Compute equivalent strain value for tension.
double yieldHardPrimePeak
Parameter of the hardening law of the plasticity model.
double computeRateFactor(double alpha, double timeFactor, GaussPoint *gp, TimeStep *deltaTime) const
int newtonIter
Maximum number of iterations for stress return.
FloatMatrixF< 6, 6 > compute3dSecantStiffness(GaussPoint *gp, TimeStep *tStep) const
Compute the 3d secant stiffness matrix.
double ASoft
Parameter of the ductilityMeasure of the damage model.
FloatArrayF< 2 > computeDDKappaDDeltaLambdaDInv(double sig, double rho, double theta, double tempKappa) const
FloatMatrixF< 6, 6 > computeDDGDDStress(const FloatArrayF< 6 > &stress, const double tempKappa) const
double efCompression
Control parameter for the exponential softening law.
double computeHardeningTwoPrime(double tempKappa) const
double wfOne
Control parameter for the bilinear softening law in tension.
int checkForUnAndReloading(double &tempEquivStrain, double &minEquivStrain, const FloatMatrixF< 6, 6 > &D, GaussPoint *gp) const
Check for un- and reloading in the damage part.
void computeCoordinates(const FloatArrayF< 6 > &stress, double &sig, double &rho, double &theta) const
Compute the Haigh-Westergaard coordinates.
void checkForVertexCase(double &answer, ConcreteDPM2_ReturnType &returnType, double sig, double tempKappa, GaussPoint *gp) const
void restoreContext(DataStream &stream, ContextMode mode) override
double yieldTol
yield tolerance for the plasticity model.
double m
Friction parameter of the yield surface.
virtual double computeEquivalentStrain(double sig, double rho, double theta) const
Compute the base equivalent strain value.
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.
FloatArrayF< 6 > computeDDKappaDDeltaLambdaDStress(const FloatArrayF< 6 > &stress, double tempKappa) const
double computeDDRDDCosTheta(const double theta, const double ecc) const
Computes the second derivative of function r with respect to cos theta.
double eM
Elastic Young's modulus.
double computeDeltaPlasticStrainNormCompression(double tempAlpha, double tempKappaD, double kappaD, GaussPoint *gp, const double rho) const
Compute equivalent strain value for compression.
virtual double computeDamageParamCompression(double equivStrain, double kappaOne, double kappaTwo, double omegaOld, double rateFactor) const
Compute damage parameter in compression.
double wf
Control parameter for the linear/bilinear softening law in tension.
FloatMatrixF< 6, 6 > give3dMaterialStiffnessMatrix(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const override
FloatMatrixF< 4, 4 > computeJacobian(double sig, double rho, double theta, double tempKappa, double deltaLambda, GaussPoint *gp) const
double computeHardeningOnePrime(double tempKappa) 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
int giveGlobalNumber() const
Definition element.h:1129
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)
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
double at(std::size_t i, std::size_t j) const
Element * giveElement()
Returns corresponding element to receiver.
Definition gausspoint.h:187
GaussPoint * gp
Associated integration point.
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Definition material.C:206
Dictionary propertyDictionary
Definition material.h:107
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 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 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
double giveTimeIncrement()
Returns solution step associated time increment.
Definition timestep.h:168
bool isTheFirstStep()
Definition timestep.C:148
#define _IFT_ConcreteDPM2_dilation
#define _IFT_ConcreteDPM2_energyratetype
#define _IFT_ConcreteDPM2_damflag
#define _IFT_ConcreteDPM2_hp
#define _IFT_ConcreteDPM2_newtoniter
#define _IFT_ConcreteDPM2_softeningType
#define _IFT_ConcreteDPM2_wf
#define _IFT_ConcreteDPM2_chard
#define _IFT_ConcreteDPM2_yieldtol
#define _IFT_ConcreteDPM2_asoft
#define CDPM2_TOL
#define _IFT_ConcreteDPM2_ahard
#define _IFT_ConcreteDPM2_dhard
#define _IFT_ConcreteDPM2_helem
#define _IFT_ConcreteDPM2_wfOne
#define _IFT_ConcreteDPM2_ftOne
#define _IFT_ConcreteDPM2_ecc
#define _IFT_ConcreteDPM2_efc
#define _IFT_ConcreteDPM2_fc
#define _IFT_ConcreteDPM2_ft
#define _IFT_ConcreteDPM2_bhard
#define _IFT_ConcreteDPM2_kinit
#define _IFT_ConcreteDPM2_deltatime
#define _IFT_ConcreteDPM2_strengthratetype
#define THROW_CIOERR(e)
#define CM_Definition
Definition contextmode.h:47
#define OOFEM_WARNING(...)
Definition error.h:80
#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 OOFEM_LOG_INFO(...)
Definition logger.h:143
#define M_PI
Definition mathfem.h:52
long ContextMode
Definition contextmode.h:43
double norm(const FloatArray &x)
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
@ 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)
FloatArrayF< N > max(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
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.
double norm_squared(const FloatArrayF< N > &x)
Computes the L2 norm of x.

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