52DruckerPragerPlasticitySMStatus :: DruckerPragerPlasticitySMStatus(
GaussPoint *
gp) :
62DruckerPragerPlasticitySMStatus :: initTempStatus()
65 StructuralMaterialStatus :: initTempStatus();
74DruckerPragerPlasticitySMStatus :: updateYourself(
TimeStep *tStep)
77 StructuralMaterialStatus :: updateYourself(tStep);
87DruckerPragerPlasticitySMStatus :: printOutputAt(FILE *file,
TimeStep *tStep)
const
90 StructuralMaterialStatus :: printOutputAt(file, tStep);
92 fprintf(file,
"\tstatus { ");
96 case DruckerPragerPlasticitySMStatus :: DP_Elastic:
97 fprintf(file,
" Elastic, ");
99 case DruckerPragerPlasticitySMStatus :: DP_Yielding:
100 fprintf(file,
" Yielding, ");
102 case DruckerPragerPlasticitySMStatus :: DP_Vertex:
103 fprintf(file,
" Vertex_return, ");
105 case DruckerPragerPlasticitySMStatus :: DP_Unloading:
106 fprintf(file,
" Unloading, ");
113 fprintf(file,
"plasticStrains ");
114 for (
auto &val : plasticStrainVector ) {
115 fprintf( file,
" %.4e", val );
118 fprintf(file,
"}\n");
120 fprintf(file,
"\t\thardening_parameter ");
122 fprintf(file,
" %.4e\n",
kappa);
128 StructuralMaterialStatus :: saveContext(stream, mode);
152 StructuralMaterialStatus :: restoreContext(stream, mode);
177DruckerPragerPlasticitySM :: DruckerPragerPlasticitySM(
int n,
Domain *d) :
187 StructuralMaterial :: initializeFrom(ir);
216 "must be 1 (linear hardening/softening) or 2 (exponential hardening/softening)");
238 auto strainVectorR = strain - thermalStrain;
244 status->letTempStrainVectorBe(strain);
247 return status->giveTempStressVector();
259 double gM = eM / ( 2. * ( 1. + nu ) );
260 double kM = eM / ( 3. * ( 1. - 2. * nu ) );
264 auto strainDeviator = tmp.first;
265 auto volumetricStrain = tmp.second;
268 double volumetricElasticTrialStrain = volumetricStrain - status->giveVolumetricPlasticStrain();
269 auto plasticStrainDeviator = status->givePlasticStrainDeviator();
270 auto elasticStrainDeviator = strainDeviator - plasticStrainDeviator;
273 double volumetricStress = 3. * kM * volumetricElasticTrialStrain;
279 double kappa = status->giveKappa();
280 double tempKappa = kappa;
288 tempKappa, volumetricElasticTrialStrain, kappa);
289 status->letTempStateFlagBe(DruckerPragerPlasticitySMStatus :: DP_Vertex);
292 status->letTempStateFlagBe(DruckerPragerPlasticitySMStatus :: DP_Yielding);
295 const int state_flag = status->giveStateFlag();
296 if ( state_flag == DruckerPragerPlasticitySMStatus :: DP_Elastic ) {
297 status->letTempStateFlagBe(DruckerPragerPlasticitySMStatus :: DP_Elastic);
299 status->letTempStateFlagBe(DruckerPragerPlasticitySMStatus :: DP_Unloading);
304 status->letTempKappaBe(tempKappa);
308 status->letTempStressVectorBe(stress);
312 plasticStrainDeviator = strainDeviator - elasticStrainDeviator;
313 status->letTempPlasticStrainDeviatorBe(plasticStrainDeviator);
314 status->letTempVolumetricPlasticStrainBe(volumetricStrain - volumetricStress / 3. / kM);
318DruckerPragerPlasticitySM :: checkForVertexCase(
double eM,
double gM,
double kM,
double trialStressJTwo,
double volumetricStress,
double tempKappa)
const
323 double deltaLambdaMax = sqrt(trialStressJTwo) / gM;
327 double volConstant = 3. * kM *
alphaPsi;
330 0., tempKappa +
kFactor * deltaLambdaMax, eM);
331 if ( yieldValue / eM > -
yieldTol ) {
340DruckerPragerPlasticitySM :: performRegularReturn(
double eM,
double gM,
double kM,
double trialStressJTwo,
FloatArrayF<6> &stressDeviator,
double &volumetricStress,
double &tempKappa)
const
343 double deltaLambdaMax = sqrt(trialStressJTwo) / gM;
346 double volConstant = 3. * kM *
alphaPsi;
347 double devConstant = sqrt(2.) * gM;
349 double yieldValuePrimeZero = -9. *
alpha *
alphaPsi * kM - gM;
351 auto flowDir = stressDeviator * ( 1. / sqrt(2. * trialStressJTwo) );
354 int iterationCount = 0;
355 double deltaLambda = 0.;
356 double deltaLambdaIncrement = 0.;
357 double yieldValue =
computeYieldValue(volumetricStress, trialStressJTwo, tempKappa, eM);
358 double newtonError = fabs(yieldValue / eM);
363 OOFEM_ERROR(
"Newton iteration for deltaLambda (regular stress return) did not converge after newtonIter iterations. You might want to try increasing the optional parameter newtoniter or yieldtol in the material record of your input file.");
367 deltaLambdaIncrement = -yieldValue / yieldValuePrime;
373 if ( deltaLambda + deltaLambdaIncrement > deltaLambdaMax ) {
374 OOFEM_LOG_DEBUG(
"Special case in Newton-iteration for regular return. This may cause loss of quadratic convergence.\n");
375 deltaLambdaIncrement = deltaLambdaMax - deltaLambda;
378 deltaLambda += deltaLambdaIncrement;
379 tempKappa +=
kFactor * deltaLambdaIncrement;
380 volumetricStress -= volConstant * deltaLambdaIncrement;
385 stressDeviator += (-devConstant * deltaLambdaIncrement) * flowDir;
388 newtonError = fabs(yieldValue / eM);
392 OOFEM_LOG_DEBUG(
"IterationCount in regular return = %d\n", iterationCount);
394 if ( deltaLambda < 0. ) {
395 OOFEM_ERROR(
"Fatal error in the Newton iteration for regular stress return. deltaLambda is evaluated as negative, but should always be positive. This is most likely due to a softening law with local snapback, which is physically inadmissible.n");
400DruckerPragerPlasticitySM :: performVertexReturn(
double eM,
double gM,
double kM,
double trialStressJTwo,
FloatArrayF<6> &stressDeviator,
double &volumetricStress,
double &tempKappa,
double volumetricElasticTrialStrain,
double kappa)
const
404 double yieldValuePrimeZero = 3. *
alpha;
406 double deviatorContribution = trialStressJTwo / 3. / gM / gM;
409 volumetricStress = 3. * kM * volumetricElasticTrialStrain;
412 int iterationCount = 0;
413 double deltaVolumetricStress = 0.;
414 double deltaVolumetricStressIncrement = 0.;
415 double deltaKappa = sqrt(deviatorContribution);
416 tempKappa = kappa + deltaKappa;
418 double newtonError = fabs(yieldValue / eM);
423 OOFEM_ERROR(
"Newton iteration for deltaLambda (vertex stress return) did not converge after newtonIter iterations. You might want to try increasing the optional parameter newtoniter or yieldtol in the material record of your input file.");
427 double yieldValuePrime;
428 if ( deltaKappa == 0. ) {
429 yieldValuePrime = yieldValuePrimeZero
432 yieldValuePrime = yieldValuePrimeZero
434 * deltaVolumetricStress / deltaKappa;
437 deltaVolumetricStressIncrement = -yieldValue / yieldValuePrime;
438 deltaVolumetricStress += deltaVolumetricStressIncrement;
439 volumetricStress += deltaVolumetricStressIncrement;
440 deltaKappa = sqrt(2. / 9. / kM / kM * deltaVolumetricStress * deltaVolumetricStress
441 + deviatorContribution);
442 tempKappa = kappa + deltaKappa;
444 newtonError = fabs(yieldValue / eM);
445 OOFEM_LOG_DEBUG(
"NewtonError in iteration %d in vertex return = %e\n", iterationCount, newtonError);
448 OOFEM_LOG_DEBUG(
"Done iteration in vertex return, after %d\n", iterationCount);
450 if ( deltaKappa < 0. ) {
451 OOFEM_ERROR(
"Fatal error in the Newton iteration for vertex stress return. deltaKappa is evaluated as negative, but should always be positive. This is most likely due to a softening law with a local snapback, which is physically inadmissible.");
456DruckerPragerPlasticitySM :: computeYieldValue(
double volumetricStress,
465DruckerPragerPlasticitySM :: computeYieldStressInShear(
double kappa,
double eM)
const
471 if ( yieldStress < 0. ) {
480 OOFEM_ERROR(
"Case failed: choose linear hardening/softening (1), exponential hardening/softening (2) in input file.");
485DruckerPragerPlasticitySM :: computeYieldStressPrime(
double kappa,
double eM)
const
499 OOFEM_ERROR(
"Case failed: choose linear hardening/softening (1), exponential hardening/softening (2) in input file.");
505DruckerPragerPlasticitySM :: give3dMaterialStiffnessMatrix(MatResponseMode mode,
510 case ElasticStiffness:
511 return LEMaterial.give3dMaterialStiffnessMatrix(mode, gp, tStep);
513 case SecantStiffness:
514 return LEMaterial.give3dMaterialStiffnessMatrix(mode, gp, tStep);
516 case TangentStiffness:
518 ->giveTempStateFlag() ) {
519 case DruckerPragerPlasticitySMStatus :: DP_Elastic:
520 case DruckerPragerPlasticitySMStatus :: DP_Unloading:
521 return LEMaterial.give3dMaterialStiffnessMatrix(mode, gp, tStep);
522 case DruckerPragerPlasticitySMStatus :: DP_Yielding:
526 case DruckerPragerPlasticitySMStatus :: DP_Vertex:
537 OOFEM_ERROR(
"Switch failed: Only elastic and tangent stiffness are supported.");
543DruckerPragerPlasticitySM :: giveRegAlgorithmicStiffMatrix(MatResponseMode mode,
557 double gM = eM / ( 2. * ( 1. + nu ) );
558 double kM = eM / ( 3. * ( 1. - 2. * nu ) );
560 auto flowDir = deviatoricStress / normOfStress;
562 double kappa = status->giveKappa();
563 double tempKappa = status->giveTempKappa();
564 double deltaKappa = tempKappa - kappa;
565 double deltaLambdaStar = sqrt(2.) * gM * deltaKappa /
kFactor / normOfStress;
570 OOFEM_ERROR(
"computeYieldStressPrime is zero. This happens mainly due to excessive softening.");
573 double a_const = 1. + deltaLambdaStar;
574 double b_const = 3. *
alpha *
alphaPsi * kM / hStar - deltaLambdaStar / 3.;
575 double c_const = 3. * sqrt(2.) *
alphaPsi * kM / 2. / hStar;
576 double d_const = sqrt(2.) *
alpha * gM / hStar;
577 double e_const = gM / hStar - deltaLambdaStar;
581 for (
int i = 1; i < 7; i++ ) {
582 A_Matrix.
at(i, i) = a_const;
585 for (
int i = 1; i < 4; i++ ) {
586 for (
int j = 1; j < 4; j++ ) {
587 A_Matrix.
at(i, j) += b_const;
591 for (
int i = 1; i < 4; i++ ) {
592 for (
int j = 1; j < 4; j++ ) {
593 A_Matrix.
at(i, j) += c_const * flowDir.at(j);
596 for (
int j = 4; j < 7; j++ ) {
597 A_Matrix.
at(i, j) += 2. *c_const *flowDir.at(j);
601 for (
int i = 1; i < 7; i++ ) {
602 for (
int j = 1; j < 4; j++ ) {
603 A_Matrix.
at(i, j) += d_const * flowDir.at(i);
607 for (
int i = 1; i < 7; i++ ) {
608 for (
int j = 1; j < 4; j++ ) {
609 A_Matrix.
at(i, j) += e_const * flowDir.at(i) * flowDir.at(j);
613 for (
int j = 4; j < 7; j++ ) {
614 A_Matrix.
at(i, j) += 2. *e_const *flowDir.at(i) * flowDir.at(j);
618 auto De =
LEMaterial.give3dMaterialStiffnessMatrix(mode, gp, tStep);
621 return dot(
inv(A_Matrix), De);
625DruckerPragerPlasticitySM :: giveVertexAlgorithmicStiffMatrix(MatResponseMode mode,
632 double deltaKappa = tempKappa - status->giveKappa();
637 double kM = eM / ( 3. * ( 1. - 2. * nu ) );
639 if ( deltaKappa <= 0. ) {
642 return LEMaterial.give3dMaterialStiffnessMatrix( mode, gp, tStep);
646 double deltaVolumetricPlasticStrain =
647 status->giveTempVolumetricPlasticStrain() - status->giveVolumetricPlasticStrain();
653 auto elasticStrainDeviator = strainDeviator -
FloatArrayF<6>(status->givePlasticStrainDeviator());
656 kM * HBar / ( HBar * deltaVolumetricPlasticStrain + 9. / 2. *
alpha * kM * deltaKappa );
658 if ( ( HBar * deltaVolumetricPlasticStrain + 9. / 2. *
alpha * kM * deltaKappa ) == 0. ) {
665 for (
int i = 1; i < 4; i++ ) {
666 for (
int j = 1; j < 4; j++ ) {
667 answer.
at(i, j) = deltaVolumetricPlasticStrain;
671 for (
int i = 1; i < 4; i++ ) {
672 for (
int j = 1; j < 4; j++ ) {
673 answer.
at(i, j) += elasticStrainDeviator.at(j);
676 for (
int j = 4; j < 7; j++ ) {
677 answer.
at(i, j) += .5 * elasticStrainDeviator.at(j);
681 return a_const * answer;
693 case IST_PlasticStrainTensor:
694 answer = status->givePlasticStrainVector();
697 case IST_DamageTensor:
700 answer.
at(1) = answer.
at(2) = answer.
at(3) = status->giveKappa();
704 return StructuralMaterial :: giveIPValue(answer, gp, type, tStep);
708std::unique_ptr<MaterialStatus>
709DruckerPragerPlasticitySM :: CreateStatus(
GaussPoint *gp)
const
711 return std::make_unique<DruckerPragerPlasticitySMStatus>(gp);
716DruckerPragerPlasticitySM :: predictRelativeComputationalCost(
GaussPoint *gp)
721 if ( ( state_flag == DruckerPragerPlasticitySMStatus :: DP_Vertex ) ||
722 ( state_flag == DruckerPragerPlasticitySMStatus :: DP_Yielding ) ) {
#define REGISTER_Material(class)
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 tempVolumetricPlasticStrain
int giveStateFlag() const
double kappa
Hardening variable.
double volumetricPlasticStrain
Volumetric plastic strain.
FloatArrayF< 6 > givePlasticStrainVector() const
double giveTempKappa() const
int state_flag
Indicates the state (i.e. elastic, yielding, vertex, unloading) of the Gauss point.
FloatArrayF< 6 > plasticStrainDeviator
Deviatoric of plastic strain.
FloatArrayF< 6 > tempPlasticStrainDeviator
DruckerPragerPlasticitySM(int n, Domain *d)
Constructor.
double initialYieldStress
Parameter of all three laws, this is the initial value of the yield stress in pure shear.
double computeYieldValue(double meanStress, double JTwo, double kappa, double eM) const
int newtonIter
Maximum number of iterations for stress return.
void performVertexReturn(double eM, double gM, double kM, double trialStressJTwo, FloatArrayF< 6 > &stressDeviator, double &volumetricStress, double &tempKappa, double volumetricElasticTrialStrain, double kappa) const
double kFactor
Scalar factor between rate of plastic multiplier and rate of hardening variable.
double yieldTol
Yield tolerance.
virtual double computeYieldStressPrime(double kappa, double eM) const
FloatMatrixF< 6, 6 > giveVertexAlgorithmicStiffMatrix(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const
double limitYieldStress
Parameter of the exponential hardening law.
double hardeningModulus
Hardening modulus normalized with the elastic modulus, parameter of the linear hardening/softening la...
bool checkForVertexCase(double eM, double gM, double kM, double trialStressJTwo, double volumetricStress, double tempKappa) const
FloatMatrixF< 6, 6 > giveRegAlgorithmicStiffMatrix(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const
double alpha
Friction coefficient, parameter of the yield criterion.
double alphaPsi
Dilatancy coefficient, parameter of the flow rule.
void performLocalStressReturn(GaussPoint *gp, const FloatArrayF< 6 > &strain) const
double kappaC
Parameter of the exponential laws.
void performRegularReturn(double eM, double gM, double kM, double trialStressJTwo, FloatArrayF< 6 > &stressDeviator, double &volumetricStress, double &tempKappa) const
IsotropicLinearElasticMaterial LEMaterial
Associated linear elastic material.
virtual double computeYieldStressInShear(double kappa, double eM) const
void zero()
Zeroes all coefficients of receiver.
double at(std::size_t i, std::size_t j) const
GaussPoint * gp
Associated integration point.
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
virtual void initTempStatus(GaussPoint *gp) const
const FloatArray & giveTempStressVector() const
Returns the const pointer to receiver's temporary stress vector.
StructuralMaterialStatus(GaussPoint *g)
Constructor. Creates new StructuralMaterialStatus with IntegrationPoint g.
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.
static FloatArrayF< 6 > computeDeviatoricVolumetricSum(const FloatArrayF< 6 > &dev, double mean)
static FloatArrayF< 6 > applyDeviatoricElasticCompliance(const FloatArrayF< 6 > &stress, double EModulus, double nu)
StructuralMaterial(int n, Domain *d)
static FloatArrayF< 6 > applyDeviatoricElasticStiffness(const FloatArrayF< 6 > &strain, double EModulus, double nu)
static double computeSecondStressInvariant(const FloatArrayF< 6 > &s)
static FloatArrayF< 6 > computeDeviator(const FloatArrayF< 6 > &s)
static std::pair< FloatArrayF< 6 >, double > computeDeviatoricVolumetricSplit(const FloatArrayF< 6 > &s)
FloatArrayF< 6 > computeStressIndependentStrainVector_3d(GaussPoint *gp, TimeStep *tStep, ValueModeType mode) const
#define _IFT_DruckerPragerPlasticitySM_ht
#define _IFT_DruckerPragerPlasticitySM_iys
Initial yield stress under pure shear.
#define _IFT_DruckerPragerPlasticitySM_lys
#define _IFT_DruckerPragerPlasticitySM_newtoniter
#define _IFT_DruckerPragerPlasticitySM_kc
#define _IFT_DruckerPragerPlasticitySM_yieldtol
#define _IFT_DruckerPragerPlasticitySM_alpha
Friction coefficient.
#define _IFT_DruckerPragerPlasticitySM_hm
#define _IFT_DruckerPragerPlasticitySM_alphapsi
Dilatancy coefficient.
#define OOFEM_LOG_DEBUG(...)
double dot(const FloatArray &x, const FloatArray &y)
FloatMatrixF< N, N > inv(const FloatMatrixF< N, N > &mat, double zeropiv=1e-24)
Computes the inverse.
FloatArrayF< N > zeros()
For more readable code.
@ CIO_IOERR
General IO error.