OOFEM 3.0
Loading...
Searching...
No Matches
druckerpragercutmat.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 "druckerpragercutmat.h"
37#include "floatmatrix.h"
38#include "floatarray.h"
39#include "gausspoint.h"
40#include "mathfem.h"
41#include "contextioerr.h"
42#include "datastream.h"
43#include "classfactory.h"
44
45namespace oofem {
47
48// constructor
49DruckerPragerCutMat :: DruckerPragerCutMat(int n, Domain *d) : MPlasticMaterial2(n, d)
50{
52 this->nsurf = 4;
54 // this->rmType = mpm_ClosestPoint;
55
56 this->plType = nonassociatedPT; // Rankine associated, DP nonassociated
57}
58
59bool
60DruckerPragerCutMat :: hasMaterialModeCapability(MaterialMode mode) const
61{
62 return mode == _3dMat || mode == _PlaneStrain;
63}
64
65// reads the model parameters from the input file
66void
67DruckerPragerCutMat :: initializeFrom(InputRecord &ir)
68{
69 StructuralMaterial :: initializeFrom(ir);
70 linearElasticMaterial->initializeFrom(ir); // takes care of elastic constants
71
72 G = static_cast< IsotropicLinearElasticMaterial * >(linearElasticMaterial)->giveShearModulus();
73 K = static_cast< IsotropicLinearElasticMaterial * >(linearElasticMaterial)->giveBulkModulus();
74
75 IR_GIVE_FIELD(ir, tau0, _IFT_DruckerPragerCutMat_tau0); // initial yield stress under pure shear (DP model)
76 IR_GIVE_FIELD(ir, sigT, _IFT_DruckerPragerCutMat_sigT); // uniaxial tensile strength for cut-off, (Rankine plasticity model)
77 IR_GIVE_FIELD(ir, alpha, _IFT_DruckerPragerCutMat_alpha); // friction coefficient (DP model)
79 IR_GIVE_OPTIONAL_FIELD(ir, alphaPsi, _IFT_DruckerPragerCutMat_alphapsi); //dilatancy coefficient (DP model)
80 IR_GIVE_OPTIONAL_FIELD(ir, H, _IFT_DruckerPragerCutMat_h); // hardening modulus (DP model)
82 IR_GIVE_OPTIONAL_FIELD(ir, a, _IFT_DruckerPragerCutMat_a); // exponent in damage law
83 IR_GIVE_OPTIONAL_FIELD(ir, yieldTol, _IFT_DruckerPragerCutMat_yieldTol); //tolerance of the error in the yield criterion
84 IR_GIVE_OPTIONAL_FIELD(ir, newtonIter, _IFT_DruckerPragerCutMat_newtonIter); //Maximum number of iterations in lambda search
85}
86
87
88std::unique_ptr<MaterialStatus>
89DruckerPragerCutMat :: CreateStatus(GaussPoint *gp) const
90{
91 return std::make_unique<MPlasticMaterial2Status>(gp, this->giveSizeOfReducedHardeningVarsVector(gp));
92}
93
94double
95DruckerPragerCutMat :: computeYieldValueAt(GaussPoint *gp, int isurf, const FloatArray &stressVector, const FloatArray &strainSpaceHardeningVariables) const
96{
97 //strainSpaceHardeningVariables = kappa
98 if ( isurf <= 3 ) { //Rankine, surfaces 1,2,3
99 FloatArray princStress(3);
100 this->computePrincipalValues(princStress, stressVector, principal_stress);
101 return princStress.at(isurf) - this->sigT;
102 } else { //Drucker-Prager, surface 4
103 double DPYieldStressInShear = tau0 + H *strainSpaceHardeningVariables.at(4);
104 //auto [deviatoricStress, volumetricStress] = this->computeDeviatoricVolumetricSplit(stressVector); // c++17
105 auto tmp = this->computeDeviatoricVolumetricSplit(stressVector); // c++17
106 auto deviatoricStress = tmp.first;
107 auto volumetricStress = tmp.second;
108 auto JTwo = computeSecondStressInvariant(deviatoricStress);
109 return 3. * alpha * volumetricStress + sqrt(JTwo) - DPYieldStressInShear;
110 }
111}
112
113//associated and nonassociated flow rule
114void
115DruckerPragerCutMat :: computeStressGradientVector(FloatArray &answer, functType ftype, int isurf, GaussPoint *gp, const FloatArray &stressVector, const FloatArray &stressSpaceHardeningVars) const
116{
117 FloatArray princStress(3);
118 FloatMatrix t(3, 3);
119
120 // compute principal stresses and their directions
121 this->computePrincipalValDir(princStress, t, stressVector, principal_stress);
122
123 // derivation through stress transformation matrix. The transformation matrix is stored in t columnwise
124 answer.resize(6);
125 if ( isurf <= 3 ) { //Rankine associated
126 answer.at(1) = t.at(1, isurf) * t.at(1, isurf); //xx = 11
127 answer.at(2) = t.at(2, isurf) * t.at(2, isurf); //yy = 22
128 answer.at(3) = t.at(3, isurf) * t.at(3, isurf); //zz = 33
129 answer.at(4) = t.at(2, isurf) * t.at(3, isurf); //yz = 23
130 answer.at(5) = t.at(1, isurf) * t.at(3, isurf); //xz = 13
131 answer.at(6) = t.at(1, isurf) * t.at(2, isurf); //xy = 12
132 } else { //DP nonassociated
133
134 auto deviatoricStress = this->computeDeviator(stressVector);
135 auto sqrtJTwo = sqrt( computeSecondStressInvariant(deviatoricStress) );
136
137 answer.at(1) = alphaPsi + deviatoricStress.at(1) / 2. / sqrtJTwo;
138 answer.at(2) = alphaPsi + deviatoricStress.at(2) / 2. / sqrtJTwo;
139 answer.at(3) = alphaPsi + deviatoricStress.at(3) / 2. / sqrtJTwo;
140 answer.at(4) = stressVector.at(4) / sqrtJTwo;
141 answer.at(5) = stressVector.at(5) / sqrtJTwo;
142 answer.at(6) = stressVector.at(6) / sqrtJTwo;
143 }
144}
145
146//necesarry only for mpm_ClosestPoint, see Jirasek: Inelastic analysis of structures, pp. 411.
147//Hessian matrix
148void
149DruckerPragerCutMat :: computeReducedSSGradientMatrix(FloatMatrix &gradientMatrix, int isurf, GaussPoint *gp, const FloatArray &fullStressVector, const FloatArray &strainSpaceHardeningVariables) const
150{
151 switch ( gp->giveMaterialMode() ) {
152 case _3dMat:
153 gradientMatrix.resize(6, 6);
154 break;
155 case _PlaneStrain:
156 gradientMatrix.resize(4, 4);
157 break;
158 default:
159 OOFEM_ERROR("Unknown material mode (%s)", __MaterialModeToString( gp->giveMaterialMode() ) );
160 }
161
162 gradientMatrix.zero();
163
164 if ( isurf == 4 ) {
165 double c1 = 0.;
166 double JTwo, sqrtJTwo;
167
168 auto deviatoricStress = computeDeviator(fullStressVector);
169 JTwo = computeSecondStressInvariant(deviatoricStress);
170 sqrtJTwo = sqrt(JTwo);
171
172 if ( gp->giveMaterialMode() == _3dMat ) {
173 for ( int i = 1; i <= 6; i++ ) {
174 for ( int j = i; j <= 6; j++ ) {
175 if ( ( i == 1 && j == 1 ) || ( i == 2 && j == 2 ) || ( i == 3 && j == 3 ) ) {
176 c1 = 2 / 3.;
177 } else if ( ( i == 4 && j == 4 ) || ( i == 5 && j == 5 ) || ( i == 6 && j == 6 ) ) {
178 c1 = 1.;
179 } else if ( i <= 3 && j <= 3 ) {
180 c1 = -1 / 3.;
181 } else {
182 c1 = 0;
183 }
184 gradientMatrix.at(i, j) = 0.5 / JTwo * ( c1 * sqrtJTwo - deviatoricStress.at(i) * deviatoricStress.at(j) / 2. / sqrtJTwo );
185 }
186 }
187 gradientMatrix.symmetrized();
188 } else if ( gp->giveMaterialMode() == _PlaneStrain ) {
189 for ( int i = 1; i <= 4; i++ ) {
190 for ( int j = i; j <= 4; j++ ) {
191 if ( ( i == 1 && j == 1 ) || ( i == 2 && j == 2 ) || ( i == 3 && j == 3 ) ) {
192 c1 = 2 / 3.;
193 } else if ( ( i == 4 && j == 4 ) ) {
194 c1 = 1.;
195 } else if ( i <= 3 && j <= 3 ) {
196 c1 = -1 / 3.;
197 } else {
198 c1 = 0;
199 }
200 gradientMatrix.at(i, j) = 0.5 / JTwo * ( c1 * sqrtJTwo - deviatoricStress.at(i) * deviatoricStress.at(j) / 2. / sqrtJTwo );
201 }
202 }
203 gradientMatrix.symmetrized();
204 } else {
205 OOFEM_ERROR("Unknown material mode (%s)", __MaterialModeToString( gp->giveMaterialMode() ) );
206 }
207 }
208}
209
210
211void
212DruckerPragerCutMat :: computeReducedElasticModuli(FloatMatrix &answer,
213 GaussPoint *gp,
214 TimeStep *tStep) const
215{ /* Returns elastic moduli in reduced stress-strain space*/
216 this->linearElasticMaterial->giveStiffnessMatrix(answer, ElasticStiffness, gp, tStep);
217}
218
219//answer is dkappa (cumulative plastic strain), flow rule
220void DruckerPragerCutMat :: computeStrainHardeningVarsIncrement(FloatArray &answer, GaussPoint *gp, const FloatArray &stress, const FloatArray &dlambda, const FloatArray &dplasticStrain, const IntArray &activeConditionMap) const
221{
222 answer.resize(4);
223 answer.zero();
224
225 if ( dlambda.at(4) > 0. ) {
226 answer.at(4) = dlambda.at(4) * sqrt(1. / 3. + 2 * alphaPsi * alphaPsi);
227 }
228}
229
230// Computes the derivative of yield/loading function with respect to kappa_1, kappa_2 etc.
231void DruckerPragerCutMat :: computeKGradientVector(FloatArray &answer, functType ftype, int isurf, GaussPoint *gp, FloatArray &fullStressVector, const FloatArray &strainSpaceHardeningVariables) const
232{
233 answer.resize(1); //1 hardening variable for DP model - kappa
234 answer.zero();
235
236 if ( isurf == 4 ) {
237 answer.at(1) = this->H;
238 }
239}
240
241//necesarry only for mpm_ClosestPoint
242//Computes second mixed derivative of loading function with respect to stress and hardening vars.
243void DruckerPragerCutMat :: computeReducedSKGradientMatrix(FloatMatrix &gradientMatrix, int isurf, GaussPoint *gp, const FloatArray &fullStressVector, const FloatArray &strainSpaceHardeningVariables) const
244{
245 int size = StructuralMaterial :: giveSizeOfVoigtSymVector( gp->giveMaterialMode() );
246 gradientMatrix.resize(size, 1); //six stresses in 3D and one kappa
247 gradientMatrix.zero();
248}
249
250// computes dKappa_i/dsig_j gradient matrix
251void DruckerPragerCutMat :: computeReducedHardeningVarsSigmaGradient(FloatMatrix &answer, GaussPoint *gp, const IntArray &activeConditionMap, const FloatArray &fullStressVector, const FloatArray &strainSpaceHardeningVars, const FloatArray &dlambda) const
252{
253 int size = StructuralMaterial :: giveSizeOfVoigtSymVector( gp->giveMaterialMode() );
254 answer.resize(1, size);
255 answer.zero();
256}
257
258// computes dKappa_i/dLambda_j for one surface
259void DruckerPragerCutMat :: computeReducedHardeningVarsLamGradient(FloatMatrix &answer, GaussPoint *gp, int actSurf, const IntArray &activeConditionMap, const FloatArray &fullStressVector, const FloatArray &strainSpaceHardeningVars, const FloatArray &dlambda) const
260{
261 int indx;
262 answer.resize(1, actSurf); //actSurf = number of active surfaces
263 answer.zero();
264
265 if ( ( indx = activeConditionMap.at(4) ) ) {
266 if ( dlambda.at(4) > 0. ) {
267 answer.at(1, indx) = sqrt(1. / 3. + 2 * alphaPsi * alphaPsi);
268 }
269 }
270}
271
272
273int
274DruckerPragerCutMat :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
275{
276 //MaterialStatus *status = this->giveStatus(gp);
277 if ( type == IST_DamageScalar ) {
278 answer.resize(1);
279 answer.zero();
281 //answer.at(1) = status->giveDamage();
282 return 1;
283 } else if ( type == IST_DamageTensor ) {
284 answer.resize(6);
285 answer.zero();
286 //answer.at(1) = answer.at(2) = answer.at(3) = status->giveDamage();
287 return 1;
288 } else {
289 return MPlasticMaterial2 :: giveIPValue(answer, gp, type, tStep);
290 }
291}
292} // end namespace oofem
#define REGISTER_Material(class)
double omegaCrit
Maximum damage value.
double sigT
Uniaxial tensile strength for cut-off.
double alphaPsi
Dilatancy coefficient (allowing non-associated plasticity).
double G
Elastic shear modulus.
double yieldTol
Tolerance of the error in the yield criterion.
int giveSizeOfReducedHardeningVarsVector(GaussPoint *) const override
double K
Elastic bulk modulus.
double alpha
Friction coefficient.
double a
Parameter for damage computation from cumulative plastic strain.
double tau0
Initial yield stress under pure shear.
int newtonIter
Maximum number of iterations in lambda search.
double H
Hardening modulus.
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
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
void zero()
Zeroes all coefficient of receiver.
double at(std::size_t i, std::size_t j) const
MaterialMode giveMaterialMode()
Returns corresponding material mode of receiver.
Definition gausspoint.h:190
int & at(std::size_t i)
Definition intarray.h:104
enum oofem::MPlasticMaterial2::ReturnMappingAlgoType rmType
LinearElasticMaterial * linearElasticMaterial
Reference to bulk (undamaged) material.
functType
Type that allows to distinguish between yield function and loading function.
MPlasticMaterial2(int n, Domain *d)
enum oofem::MPlasticMaterial2::plastType plType
int nsurf
Number of yield surfaces.
static void computePrincipalValues(FloatArray &answer, const FloatArray &s, stressStrainPrincMode mode)
Common functions for convenience.
static double computeSecondStressInvariant(const FloatArrayF< 6 > &s)
static FloatArrayF< 6 > computeDeviator(const FloatArrayF< 6 > &s)
static void computePrincipalValDir(FloatArray &answer, FloatMatrix &dir, const FloatArray &s, stressStrainPrincMode mode)
static std::pair< FloatArrayF< 6 >, double > computeDeviatoricVolumetricSplit(const FloatArrayF< 6 > &s)
#define _IFT_DruckerPragerCutMat_h
Hardening modulus (DP model).
#define _IFT_DruckerPragerCutMat_omegaCrit
Critical damage.
#define _IFT_DruckerPragerCutMat_newtonIter
Maximum number of iterations in lambda search.
#define _IFT_DruckerPragerCutMat_tau0
Initial yield stress under pure shear (DP model).
#define _IFT_DruckerPragerCutMat_sigT
Uniaxial tensile strength for cut-off, (Rankine plasticity model).
#define _IFT_DruckerPragerCutMat_alphapsi
#define _IFT_DruckerPragerCutMat_yieldTol
Tolerance of the error in the yield criterion.
#define _IFT_DruckerPragerCutMat_alpha
Friction coefficient (DP model).
#define _IFT_DruckerPragerCutMat_a
Exponent in damage law.
#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
@ principal_stress
For computing principal stresses.

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