OOFEM 3.0
Loading...
Searching...
No Matches
misesmat.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 "misesmat.h"
37#include "gausspoint.h"
38#include "floatmatrix.h"
39#include "floatarray.h"
40#include "function.h"
41#include "intarray.h"
42#include "mathfem.h"
43#include "contextioerr.h"
44#include "datastream.h"
45#include "classfactory.h"
46#include "fieldmanager.h"
48#include "engngm.h"
49
50namespace oofem {
52
53
57
58
59void
61{
63 linearElasticMaterial.initializeFrom(ir); // takes care of elastic constants
64
65 G = linearElasticMaterial.giveShearModulus();
66 K = linearElasticMaterial.giveBulkModulus();
67
68
69 hType = 0;
71
72 if ( hType == 0 ) {
73 IR_GIVE_FIELD(ir, sig0, _IFT_MisesMat_sig0); // uniaxial yield stress
74 H = 0.;
75 IR_GIVE_OPTIONAL_FIELD(ir, H, _IFT_MisesMat_h); // hardening modulus
76 } else if ( hType == 1 ) { //user defined hardening function
79
80 if ( h_eps.at(1) != 0. ) {
81 throw ValueInputException(ir, _IFT_MisesMat_h_eps, "The first entry in h_eps must be 0.");
82 }
83
84 if ( h_eps.giveSize() != h_function_eps.giveSize() ) {
85 throw ValueInputException(ir, _IFT_MisesMat_h_function_eps, "the size of 'h_eps' and 'h(eps)' must be the same");
86 }
87 } else {
88 throw ValueInputException(ir, _IFT_MisesMat_htype, "Unknown htype. Should be either 0 or 1.\n");
89 }
90
91 omega_crit = 0;
93
94 a = 0;
95 IR_GIVE_OPTIONAL_FIELD(ir, a, _IFT_MisesMat_a); // exponent in damage law
96
97 yieldTol = 1.e-6;
98 IR_GIVE_OPTIONAL_FIELD(ir, yieldTol, _IFT_MisesMat_yieldTol); // tolerance in the yield condition
99}
100
101// creates a new material status corresponding to this class
102std::unique_ptr<MaterialStatus>
104{
105 return std::make_unique<MisesMatStatus>(gp);
106}
107
110 GaussPoint *gp,
111 TimeStep *tStep) const
112{
114#if 1
115 auto status = static_cast< MisesMatStatus * >( this->giveStatus(gp) );
116
117 // subtract stress independent part
118 FloatArray strainR;
119 this->giveStressDependentPartOfStrainVector(strainR, gp, totalStrain, tStep, VM_Total);
120 this->performPlasticityReturn(strainR, gp, tStep);
121 double omega = computeDamage(gp, tStep);
122 FloatArrayF< 6 >stress = status->giveTempEffectiveStress() * ( 1 - omega );
123
124 // Compute the other components of the strain:
125 double E = linearElasticMaterial.give('E', gp), nu = linearElasticMaterial.give('n', gp);
126
127 auto strain = status->getTempPlasticStrain();
128 strain [ 0 ] = totalStrain [ 0 ];
129 strain [ 1 ] -= nu / E * status->giveTempEffectiveStress() [ 0 ];
130 strain [ 2 ] -= nu / E * status->giveTempEffectiveStress() [ 0 ];
131
132 status->letTempStrainVectorBe(strain);
133 status->setTempDamage(omega);
134 status->letTempStressVectorBe(stress);
135 return stress [ 0 ];
136
137#else
138 return StructuralMaterial::giveRealStressVector_1d(totalStrain, gp, tStep);
139
140#endif
141}
142
143
146 GaussPoint *gp, TimeStep *tStep) const
147{
148 auto status = static_cast< MisesMatStatus * >( this->giveStatus(gp) );
149 // initialization
150 const_cast< MisesMat * >( this )->initTempStatus(gp);
151 this->performPlasticityReturn_PlaneStress(totalStrain, gp, tStep);
152 double omega = computeDamage(gp, tStep);
153 FloatArrayF< 3 >stress = status->giveTempEffectiveStress() * ( 1 - omega );
154 status->setTempDamage(omega);
155 status->letTempStrainVectorBe(totalStrain);
156 status->letTempStressVectorBe(stress);
157 return stress;
158}
159
160
163 TimeStep *tStep) const
164{
165 auto status = static_cast< MisesMatStatus * >( this->giveStatus(gp) );
166 // subtract stress independent part
167 FloatArray strainR(6);
168 this->giveStressDependentPartOfStrainVector(strainR, gp, strain, tStep, VM_Total);
169
170 this->performPlasticityReturn(strainR, gp, tStep);
171 double omega = computeDamage(gp, tStep);
172 auto stress = status->giveTempEffectiveStress() * ( 1 - omega );
173 status->setTempDamage(omega);
174 status->letTempStrainVectorBe(strain);
175 status->letTempStressVectorBe(stress);
176 return stress;
177}
178
179
180void
182{
183 auto status = static_cast< MisesMatStatus * >( this->giveStatus(gp) );
184 double kappa;
185 FloatArray plStrain;
186 FloatArray fullStress;
187 // get the initial plastic strain and initial kappa from the status
188 plStrain = status->givePlasticStrain();
189 kappa = status->giveCumulativePlasticStrain();
190
191 double dKappa = 0.;
192 // === radial return algorithm ===
193 if ( totalStrain.giveSize() == 1 ) {
194 double E = linearElasticMaterial.give('E', gp);
195 /*trial stress*/
196 fullStress.resize(6);
197 fullStress.at(1) = E * ( totalStrain.at(1) - plStrain.at(1) );
198 double trialS = fabs(fullStress.at(1) );
199 /*yield function*/
200 double yieldValue = trialS - computeYieldStress(kappa, gp, tStep);
201 // === radial return algorithm ===
202 if ( yieldValue > 0 ) {
203 if ( hType == 0 ) {
204 dKappa = yieldValue / ( computeYieldStressPrime(kappa) + E );
205 }
206 if ( hType == 1 ) {
207 dKappa += yieldValue / ( computeYieldStressPrime(kappa) + E );
208 yieldValue = trialS - checkYieldStress(dKappa, kappa, gp, tStep);
209 yieldValue -= E * dKappa;
210 if ( yieldValue > 1.e-10 ) {
211 dKappa += yieldValue / ( computeYieldStressPrime(kappa + dKappa) + E );
212 }
213 }
214
215 kappa += dKappa;
216 plStrain.at(1) += dKappa * signum(fullStress.at(1) );
217 plStrain.at(2) -= 0.5 * dKappa * signum(fullStress.at(1) );
218 plStrain.at(3) -= 0.5 * dKappa * signum(fullStress.at(1) );
219 fullStress.at(1) -= dKappa * E * signum(fullStress.at(1) );
220 }
221 } else {
222 // elastic predictor
223 FloatArray elStrain = totalStrain;
224 elStrain.subtract(plStrain);
225 //auto [elStrainDev, elStrainVol] = computeDeviatoricVolumetricSplit(elStrain); // c++17
226 auto tmp = computeDeviatoricVolumetricSplit(elStrain);
227 auto elStrainDev = tmp.first;
228 auto elStrainVol = tmp.second;
229 FloatArray trialStressDev = applyDeviatoricElasticStiffness(elStrainDev, G);
230 /**************************************************************/
231 double trialStressVol = 3 * K * elStrainVol;
232 /**************************************************************/
233
234 // store the deviatoric and trial stress (reused by algorithmic stiffness)
235 status->letTrialStressDevBe(trialStressDev);
236 status->setTrialStressVol(trialStressVol);
237 // check the yield condition at the trial state
238 double trialS = computeStressNorm(trialStressDev);
239 double yieldValue = sqrt(3. / 2.) * trialS - ( computeYieldStress(kappa, gp, tStep) );
240 if ( yieldValue > 0. ) {
241 // increment of cumulative plastic strain
242 double dKappa = yieldValue / ( computeYieldStressPrime(kappa) + 3. * G );
243 kappa += dKappa;
244 // the following line is equivalent to multiplication by scaling matrix P
245 FloatArray dPlStrain = applyDeviatoricElasticCompliance(trialStressDev, 0.5);
246 // increment of plastic strain
247 plStrain.add(sqrt(3. / 2.) * dKappa / trialS, dPlStrain);
248 // scaling of deviatoric trial stress
249 trialStressDev.times(1. - sqrt(6.) * G * dKappa / trialS);
250 }
251
252 // assemble the stress from the elastically computed volumetric part
253 // and scaled deviatoric part
254
255 fullStress = computeDeviatoricVolumetricSum(trialStressDev, trialStressVol);
256 }
257
258 // store the effective stress in status
259 status->letTempEffectiveStressBe(fullStress);
260 // store the plastic strain and cumulative plastic strain
261 status->letTempPlasticStrainBe(plStrain);
262 status->setTempCumulativePlasticStrain(kappa);
263}
264
265void
267{
268 double E = linearElasticMaterial.give('E', gp);
269 double nu = linearElasticMaterial.give('n', gp);
270 MisesMatStatus *status = static_cast< MisesMatStatus * >( this->giveStatus(gp) );
271 double kappa;
272 FloatArray plStrain, redPlStrain;
273 FloatArray fullStress;
274 // get the initial plastic strain and initial kappa from the status
275 plStrain = status->givePlasticStrain();
276 StructuralMaterial::giveReducedSymVectorForm(redPlStrain, plStrain, _PlaneStress);
277 kappa = status->giveCumulativePlasticStrain();
278 FloatMatrix Ps, Pe;
279
280 FloatArray elStrain = totalStrain;
281 elStrain.subtract(redPlStrain);
282 FloatArray elStrainDev;
283 double elStrainVol;
284 // Elastic predictor: Compute elastic trial state
285 // Volumetric strain
286 double factor = 2. * G / ( K + 4. / 3. * G );
287 elStrainVol = ( elStrain.at(1) + elStrain.at(2) ) * factor;
288 //Elastic trial deviatoric strain
289 elStrainDev = elStrain;
290 elStrainDev.at(1) -= elStrainVol / 3.;
291 elStrainDev.at(2) -= elStrainVol / 3.;
292 // Elastic trial stress components
293 FloatArray trialStressDev;
294 trialStressDev = elStrainDev;
295 trialStressDev.times(2. * G);
296 trialStressDev.at(3) /= 2.;
297 //applyDeviatoricElasticStiffness(trialStressDev, elStrainDev, G);
298 double trialStressVol = 3 * K * elStrainVol;
299 FloatArray trialStress(trialStressDev);
300 trialStress.at(1) += trialStressVol / 3.;
301 trialStress.at(2) += trialStressVol / 3.;
302 // Compute yield function value at trial state
303 double a1 = ( trialStress.at(1) + trialStress.at(2) ) * ( trialStress.at(1) + trialStress.at(2) );
304 double a2 = ( trialStress.at(2) - trialStress.at(1) ) * ( trialStress.at(2) - trialStress.at(1) );
305 double a3 = trialStress.at(3) * trialStress.at(3);
306 double sigmaY = this->computeYieldStress(kappa, gp, tStep);
307 double xi = 1. / 6. * a1 + 0.5 * a2 + 2. * a3;
308 //Yield function
309 double yieldValue = 0.5 * xi - 1. / 3. * sigmaY * sigmaY;
310 // double dGamma ; // not used
311 // Check for plastic admissibility
312 if ( yieldValue / sigmaY > yieldTol ) {
313 // Plastic step: Apply return mapping - use Newton-Raphson algorithm
314 // to solve the plane stress-projected return mapping
315 // equation for the plastic multiplier (Box 9.5)
316 double dKappa = 0;
317 int iter = 0;
318 double f = yieldValue;
319 double denom1 = 1.;
320 double denom2 = 1.;
321 while ( true ) {
322 double HiP = this->computeYieldStressPrime(kappa + dKappa * sqrt(2. * xi / 3.) );
323 double dXi = -a1 * E / ( 1. - nu ) / 9. / denom1 / denom1 / denom1 - 2. * G * ( a2 + 4. * a3 ) / denom2 / denom2 / denom2;
324 double Hbar = 2. * sigmaY * HiP * sqrt(2. / 3.) * ( sqrt(xi) + dKappa * dXi / ( 2. * sqrt(xi) ) );
325 double df = 0.5 * dXi - 1. / 3. * Hbar;
326 dKappa -= f / df;
327 // Compute new residual (yield function value)
328 denom1 = ( 1. + E * dKappa / 3. / ( 1. - nu ) );
329 denom2 = ( 1 + 2. * G * dKappa );
330 xi = a1 / 6. / denom1 / denom1 + ( 0.5 * a2 + 2. * a3 ) / denom2 / denom2;
331 sigmaY = this->computeYieldStress(kappa + sqrt(2. * xi / 3.) * dKappa, gp, tStep);
332
333 f = 1. / 2. * xi - 1. / 3. * sigmaY * sigmaY;
334
335 if ( fabs(f / sigmaY) < yieldTol ) {
336 break;
337 }
338 iter++;
339 if ( iter > 400 ) {
340 OOFEM_WARNING("No convergence of the stress return algorithm in MisesMat :: performPlasticityReturn_PlaneStress\n");
341 break;
342 }
343 }
344 // update accumulated plastic strain
345 // dGamma = dKappa;
346 kappa += sqrt(2. * xi / 3.) * dKappa;
347 // update stress components: sigma := A sigma^trial
348 double As1 = 3. * ( 1. - nu ) / ( 3 * ( 1 - nu ) + E * dKappa );
349 double As2 = 1. / ( 1. + 2. * G * dKappa );
350 FloatMatrix A(3, 3);
351 A.at(1, 1) = 0.5 * ( As1 + As2 );
352 A.at(2, 2) = A.at(1, 1);
353 A.at(1, 2) = 0.5 * ( As1 - As2 );
354 A.at(2, 1) = A.at(1, 2);
355 A.at(3, 3) = As2;
356 fullStress.beProductOf(A, trialStress);
357 elStrainVol = ( fullStress.at(1) + fullStress.at(2) ) / 3. / K;
358 // compute corresponding elastic (engineering) strain components
359 redPlStrain.at(1) = totalStrain.at(1) - ( 2. / 3. * fullStress.at(1) - 1. / 3. * fullStress.at(2) ) / 2. / G - elStrainVol / 3;
360 redPlStrain.at(2) = totalStrain.at(2) - ( 2. / 3. * fullStress.at(2) - 1. / 3. * fullStress.at(1) ) / 2. / G - elStrainVol / 3;
361 redPlStrain.at(3) = totalStrain.at(3) - fullStress.at(3) / G;
362 StructuralMaterial::giveFullSymVectorForm(plStrain, redPlStrain, _PlaneStress);
363 // incompresibility condition
364 plStrain.at(3) = -( plStrain.at(1) + plStrain.at(2) );
365 // store the plastic strain and cumulative plastic strain
366 } else {
367 fullStress = trialStress;
368 }
369
370
371 // storing into the status
372 status->letTempPlasticStrainBe(plStrain);
373 status->setTempCumulativePlasticStrain(kappa);
374 status->letTempEffectiveStressBe(fullStress);
375}
376
377
378double
379MisesMat::checkYieldStress(double &dKappa, double kappa, GaussPoint *gp, TimeStep *tStep) const
380{
381 double yieldStress = 0.;
382 if ( hType == 1 ) {
383 if ( kappa + dKappa > h_eps.at(h_eps.giveSize() ) ) {
384 OOFEM_ERROR("kappa outside range of specified hardening law/n");
385 }
386
387 for ( int i = 1; i < h_eps.giveSize(); i++ ) {
388 if ( kappa + dKappa >= h_eps.at(i) && kappa + dKappa < h_eps.at(i + 1) && kappa < h_eps.at(i) ) {
389 yieldStress = h_function_eps.at(i);
390 dKappa = h_eps.at(i) - kappa;
391 return yieldStress;
392 } else if ( kappa >= h_eps.at(i) && kappa < h_eps.at(i + 1) && kappa + dKappa >= h_eps.at(i) && kappa + dKappa < h_eps.at(i + 1) ) {
393 yieldStress = h_function_eps.at(i) + ( kappa + dKappa - h_eps.at(i) ) / ( h_eps.at(i + 1) - h_eps.at(i) ) * ( h_function_eps.at(i + 1) - h_function_eps.at(i) );
394 return yieldStress;
395 }
396 }
397 } else {
398 OOFEM_ERROR("MisesMat: Should not check yield stress for htype = 0\n");
399 }
400 return yieldStress;
401}
402
403double
404MisesMat::computeYieldStress(double kappa, GaussPoint *gp, TimeStep *tStep) const
405{
406 double yieldStress = 0.;
407 if ( hType == 0 ) {
408 return this->giveS(gp, tStep) + this->H * kappa; // + ( this->sigInf - this->sig0 ) * (1. - exp(-expD*kappa));
409 } else {
410 if ( kappa > h_eps.at(h_eps.giveSize() ) ) {
411 OOFEM_ERROR("kappa outside range of specified hardening law/n");
412 }
413
414 for ( int i = 1; i < h_eps.giveSize(); i++ ) {
415 if ( kappa >= h_eps.at(i) && kappa < h_eps.at(i + 1) ) {
416 yieldStress = h_function_eps.at(i) + ( kappa - h_eps.at(i) ) / ( h_eps.at(i + 1) - h_eps.at(i) ) * ( h_function_eps.at(i + 1) - h_function_eps.at(i) );
417 return yieldStress;
418 }
419 }
420 }
421 return yieldStress;
422}
423
424
425double
427{
428 double yieldStressPrime;
429 if ( hType == 0 ) {
430 yieldStressPrime = this->H;
431 return yieldStressPrime;
432 } else {
433 if ( kappa > h_eps.at(h_eps.giveSize() ) ) {
434 OOFEM_ERROR("kappa outside range of specified hardening law/n");
435 }
436
437
438 for ( int i = 1; i < h_eps.giveSize(); i++ ) {
439 if ( kappa >= h_eps.at(i) && kappa < h_eps.at(i + 1) ) {
440 yieldStressPrime = ( h_function_eps.at(i + 1) - h_function_eps.at(i) ) / ( h_eps.at(i + 1) - h_eps.at(i) );
441 return yieldStressPrime;
442 }
443 }
444 }
445 return 0.;
446}
447
448
449
450double
451MisesMat::computeDamageParam(double tempKappa) const
452{
453 if ( tempKappa > 0. ) {
454 return omega_crit * ( 1.0 - exp(-a * tempKappa) );
455 } else {
456 return 0.;
457 }
458}
459
460double
462{
463 if ( tempKappa >= 0. ) {
464 return omega_crit * a * exp(-a * tempKappa);
465 } else {
466 return 0.;
467 }
468}
469
470
471double
473{
474 auto status = static_cast< MisesMatStatus * >( this->giveStatus(gp) );
475 double dam = status->giveDamage();
476 double tempKappa = computeCumPlastStrain(gp, tStep);
477 double tempDam = computeDamageParam(tempKappa);
478 if ( dam > tempDam ) {
479 tempDam = dam;
480 }
481
482 return tempDam;
483}
484
485
487{
488 auto status = static_cast< MisesMatStatus * >( this->giveStatus(gp) );
489 return status->giveTempCumulativePlasticStrain();
490}
491
492
493
494// returns the consistent (algorithmic) tangent stiffness matrix
497 GaussPoint *gp,
498 TimeStep *tStep) const
499{
500 // start from the elastic stiffness
501 auto d = this->linearElasticMaterial.give3dMaterialStiffnessMatrix(mode, gp, tStep);
502 if ( mode != TangentStiffness ) {
503 return d;
504 }
505
506 auto status = static_cast< MisesMatStatus * >( this->giveStatus(gp) );
507 double kappa = status->giveCumulativePlasticStrain();
508 double tempKappa = status->giveTempCumulativePlasticStrain();
509 // increment of cumulative plastic strain as an indicator of plastic loading
510 double dKappa = tempKappa - kappa;
511
512 if ( dKappa <= 0.0 ) { // elastic loading - elastic stiffness plays the role of tangent stiffness
513 return d;
514 }
515
516 // === plastic loading ===
517
518 // yield stress at the beginning of the step
519 double sigmaY = computeYieldStress(kappa, gp, tStep);
520
521 // trial deviatoric stress and its norm
522 const FloatArrayF< 6 >trialStressDev = status->giveTrialStressDev();
523 //double trialStressVol = status->giveTrialStressVol();
524 double trialS = computeStressNorm(trialStressDev);
525
526 // one correction term
527 double factor = -2. * sqrt(6.) * G * G / trialS;
528 double factor1 = factor * sigmaY / ( ( computeYieldStressPrime(kappa) + 3. * G ) * trialS * trialS );
529 d += factor1 * dyad(trialStressDev, trialStressDev);
530
531 // another correction term
532 double factor2 = factor * dKappa;
533 d += factor2 * I_dev6;
534
535 //influence of damage
536 // double omega = computeDamageParam(tempKappa);
537 double omega = status->giveTempDamage();
538 d *= 1. - omega;
539 const FloatArrayF< 6 >effStress = status->giveTempEffectiveStress();
540 double omegaPrime = computeDamageParamPrime(tempKappa);
541 double scalar = -omegaPrime *sqrt(6.) * G / ( 3. * G + computeYieldStressPrime(kappa) ) / trialS;
542 d += scalar * dyad(effStress, trialStressDev);
543 return d;
544}
545
546
548MisesMat::givePlaneStressStiffMtrx(MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep) const
549{
550 auto status = static_cast< MisesMatStatus * >( this->giveStatus(gp) );
551 // start from the elastic stiffness
552 auto d = linearElasticMaterial.givePlaneStressStiffMtrx(mmode, gp, tStep);
553 if ( mmode != TangentStiffness ) {
554 double omega = status->giveTempDamage();
555 return d * ( 1. - omega );
556 }
557
558 double kappa = status->giveCumulativePlasticStrain();
559 double tempKappa = status->giveTempCumulativePlasticStrain();
560 // increment of cumulative plastic strain as an indicator of plastic loading
561 double dKappa = tempKappa - kappa;
562 if ( dKappa <= 0.0 ) { // elastic loading - elastic stiffness plays the role of tangent stiffness
563 return d;
564 }
565 // Compute elastoplastic consistent tangent (Box 9.6)
566 FloatArray stress, fullStress;
567 fullStress = status->giveTempStressVector();
568 StructuralMaterial::giveReducedSymVectorForm(stress, fullStress, _PlaneStress);
569 // Compute xi
570 double xi = 2. / 3. * ( stress.at(1) * stress.at(1) + stress.at(2) * stress.at(2) - stress.at(1) * stress.at(2) ) + 2. * stress.at(3) * stress.at(3);
571 // compute dGamma
572 double dGamma = dKappa * sqrt(3. / 2. / xi);
573 // Hardening slope
574 double HiP = this->computeYieldStressPrime(tempKappa);
575 // Matrix E components
576
577 double E = linearElasticMaterial.give('E', gp);
578 double nu = linearElasticMaterial.give('n', gp);
579 double Es1 = 3. * E / ( 3. * ( 1. - nu ) + E * dGamma );
580 double Es2 = 2. * G / ( 1. + 2. * G * dGamma );
581 double Es3 = Es2 / 2.;
582 // Components of the matrix product EP
583 double EPs1 = 1. / 3. * Es1;
584 double EPs2 = Es2;
585 double EPs3 = EPs2;
586 FloatMatrix EP(3, 3);
587 EP.at(1, 1) = 0.5 * ( EPs1 + EPs2 );
588 EP.at(2, 2) = EP.at(1, 1);
589 EP.at(1, 2) = 0.5 * ( EPs1 - EPs2 );
590 EP.at(2, 1) = EP.at(1, 2);
591 EP.at(3, 3) = EPs3;
592 // Vector n
593 FloatArray n(3);
594 n.beProductOf(EP, stress);
595 // Scalar alpha
596 double denom1 = stress.at(1) * ( 2. / 3. * n.at(1) - 1. / 3. * n.at(2) ) + stress.at(2) * ( 2. / 3. * n.at(2) - 1. / 3. * n.at(1) ) + 2. * stress.at(3) * n.at(3);
597 double denom2 = 2. * xi * HiP / ( 3. - 2. * HiP * dGamma );
598 double alpha = 1. / ( denom1 + denom2 );
599 FloatMatrix correction;
600 correction.beDyadicProductOf(n, n);
601 correction.times(alpha);
602
604 answer.at(1, 1) = 0.5 * ( Es1 + Es2 );
605 answer.at(2, 2) = answer.at(1, 1);
606 answer.at(1, 2) = 0.5 * ( Es1 - Es2 );
607 answer.at(2, 1) = answer.at(1, 2);
608 answer.at(3, 3) = Es3;
609 answer -= FloatMatrixF< 3, 3 >(correction);
610 //@todo: add damage part of the stiffness
611 return answer;
612}
613
614
617 GaussPoint *gp,
618 TimeStep *tStep) const
619{
620 MisesMatStatus *status = static_cast< MisesMatStatus * >( this->giveStatus(gp) );
621 double kappa = status->giveCumulativePlasticStrain();
622 // increment of cumulative plastic strain as an indicator of plastic loading
623 double tempKappa = status->giveTempCumulativePlasticStrain();
624 double omega = status->giveTempDamage();
625 auto elastic = this->linearElasticMaterial.give1dStressStiffMtrx(mode, gp, tStep);
626 double E = elastic.at(1, 1);
627 if ( mode != TangentStiffness ) {
628 return elastic;
629 }
630
631 if ( tempKappa <= kappa ) { // elastic loading - elastic stiffness plays the role of tangent stiffness
632 return elastic * ( 1 - omega );
633 }
634
635 // === plastic loading ===
636 const FloatArray &stressVector = status->giveTempEffectiveStress();
637 double stress = stressVector.at(1);
638 return {
639 ( 1 - omega ) * E * computeYieldStressPrime(kappa) / ( E + computeYieldStressPrime(kappa) ) - computeDamageParamPrime(tempKappa) * E / ( E + computeYieldStressPrime(kappa) ) * stress * signum(stress)
640 };
641}
642
643#ifdef __OOFEG
644#endif
645
646int
648{
649 MisesMatStatus *status = static_cast< MisesMatStatus * >( this->giveStatus(gp) );
650 if ( type == IST_PlasticStrainTensor ) {
651 answer = status->givePlasDef();
652 return 1;
653 } else if ( type == IST_MaxEquivalentStrainLevel ) {
654 answer.resize(1);
655 answer.at(1) = status->giveCumulativePlasticStrain();
656 return 1;
657 } else if ( ( type == IST_DamageScalar ) || ( type == IST_DamageTensor ) ) {
658 answer.resize(1);
659 answer.at(1) = status->giveDamage();
660 return 1;
661 } else if ( type == IST_YieldStrength ) {
662 answer.resize(1);
663 answer.at(1) = this->giveS(gp, tStep);
664 return 1;
665 } else {
666 return StructuralMaterial::giveIPValue(answer, gp, type, tStep);
667 }
668}
669
670//=============================================================================
671
680
681
682void
684{
686
687 fprintf(file, " plastic ");
688 for ( auto &val : this->plasticStrain ) {
689 fprintf(file, "%.4e ", val);
690 }
691 fprintf(file, "\n");
692
693 fprintf(file, "status { ");
694 // print damage
695 fprintf(file, "damage %.4e", tempDamage);
696 // print the cumulative plastic strain
697 fprintf(file, ", kappa ");
698 fprintf(file, " %.4e", kappa);
699
700 fprintf(file, "}\n");
701
702 fprintf(file, "}\n");
703}
704
705
706// initializes temporary variables based on their values at the previous equlibrium state
708{
710
714 trialStressD.clear(); // to indicate that it is not defined yet
715}
716
717
718// updates internal variables when equilibrium is reached
719void
721{
723
727 trialStressD.clear(); // to indicate that it is not defined any more
728}
729
730
731double
733{
734
735 return sig0.eval({ { "te", giveTemperature(gp, tStep) }, { "t", tStep->giveIntrinsicTime() } }, this->giveDomain(), gp, giveTemperature(gp, tStep) );
736
737}
738
740{
741 FieldManager *fm = this->domain->giveEngngModel()->giveContext()->giveFieldManager();
742 FieldPtr tf;
743 int err;
744 if ( ( tf = fm->giveField(FT_Temperature) ) ) {
745 // temperature field registered
746 FloatArray gcoords, answer;
747 static_cast< StructuralElement * >( gp->giveElement() )->computeGlobalCoordinates(gcoords, gp->giveNaturalCoordinates() );
748 if ( ( err = tf->evaluateAt(answer, gcoords, VM_Total, tStep) ) ) {
749 OOFEM_ERROR("tf->evaluateAt failed, element %d, error code %d", gp->giveElement()->giveNumber(), err);
750 }
751 return answer.at(1);
752 }
753 return 0.;
754}
755
756
757void
759{
761
763 if ( ( iores = plasticStrain.storeYourself(stream) ) != CIO_OK ) {
764 THROW_CIOERR(iores);
765 }
766
767 if ( !stream.write(kappa) ) {
769 }
770
771 if ( !stream.write(damage) ) {
773 }
774}
775
776
777void
779{
781
783 if ( ( iores = plasticStrain.restoreYourself(stream) ) != CIO_OK ) {
784 THROW_CIOERR(iores);
785 }
786
787 if ( !stream.read(kappa) ) {
789 }
790
791 if ( !stream.read(damage) ) {
793 }
794}
795} // end namespace oofem
#define E(a, b)
#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.
virtual int computeGlobalCoordinates(FloatArray &answer, const FloatArray &lcoords)
Definition element.C:1225
Domain * giveDomain() const
Definition femcmpnn.h:97
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition femcmpnn.h:79
int giveNumber() const
Definition femcmpnn.h:104
FieldPtr giveField(FieldType key)
double & at(std::size_t i)
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:689
void add(const FloatArray &src)
Definition floatarray.C:218
void subtract(const FloatArray &src)
Definition floatarray.C:320
void times(double s)
Definition floatarray.C:834
double at(std::size_t i, std::size_t j) const
void times(double f)
void beDyadicProductOf(const FloatArray &vec1, const FloatArray &vec2)
double at(std::size_t i, std::size_t j) const
const FloatArray & giveNaturalCoordinates() const
Returns coordinate array of receiver.
Definition gausspoint.h:138
Element * giveElement()
Returns corresponding element to receiver.
Definition gausspoint.h:187
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Definition material.C:206
virtual void initTempStatus(GaussPoint *gp) const
Definition material.C:221
void restoreContext(DataStream &stream, ContextMode mode) override
Definition misesmat.C:778
double giveDamage() const
Definition misesmat.h:197
double damage
damage variable (initial).
Definition misesmat.h:182
void letTempEffectiveStressBe(const FloatArray &values)
Definition misesmat.h:213
double giveTempCumulativePlasticStrain() const
Definition misesmat.h:201
void printOutputAt(FILE *file, TimeStep *tStep) const override
Print receiver's output to given stream.
Definition misesmat.C:683
const FloatArray & givePlasDef()
Definition misesmat.h:225
void saveContext(DataStream &stream, ContextMode mode) override
Definition misesmat.C:758
double giveTempDamage() const
Definition misesmat.h:198
double giveCumulativePlasticStrain() const
Definition misesmat.h:200
const FloatArray & giveTempEffectiveStress() const
Definition misesmat.h:203
FloatArray trialStressD
Deviatoric trial stress - needed for tangent stiffness.
Definition misesmat.h:167
FloatArray effStress
Definition misesmat.h:172
void letTempPlasticStrainBe(const FloatArray &values)
Definition misesmat.h:206
void initTempStatus() override
Definition misesmat.C:707
void setTempCumulativePlasticStrain(double value)
Definition misesmat.h:221
FloatArray tempPlasticStrain
Plastic strain (final).
Definition misesmat.h:164
double kappa
Cumulative plastic strain (initial).
Definition misesmat.h:176
double tempDamage
damage variable (final).
Definition misesmat.h:185
void updateYourself(TimeStep *tStep) override
Definition misesmat.C:720
const FloatArray & givePlasticStrain() const
Definition misesmat.h:191
FloatArray tempEffStress
Definition misesmat.h:173
MisesMatStatus(GaussPoint *g)
Definition misesmat.C:672
double tempKappa
Cumulative plastic strain (final).
Definition misesmat.h:179
FloatArray plasticStrain
Plastic strain (initial).
Definition misesmat.h:161
FloatArrayF< 1 > giveRealStressVector_1d(const FloatArrayF< 1 > &reducedE, GaussPoint *gp, TimeStep *tStep) const override
Default implementation relies on giveRealStressVector_StressControl.
Definition misesmat.C:109
ScalarFunction sig0
Initial (uniaxial) yield stress.
Definition misesmat.h:92
IsotropicLinearElasticMaterial linearElasticMaterial
Reference to the basic elastic material.
Definition misesmat.h:80
double giveS(GaussPoint *gp, TimeStep *tStep) const
Definition misesmat.C:732
virtual double computeCumPlastStrain(GaussPoint *gp, TimeStep *tStep) const
Definition misesmat.C:486
void initializeFrom(InputRecord &ir) override
Definition misesmat.C:60
double computeDamageParam(double tempKappa) const
Definition misesmat.C:451
double computeYieldStress(double kappa, GaussPoint *gp, TimeStep *tStep) const
Definition misesmat.C:404
double G
Elastic shear modulus.
Definition misesmat.h:83
FloatMatrixF< 6, 6 > give3dMaterialStiffnessMatrix(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const override
Definition misesmat.C:496
double a
exponent in damage function.
Definition misesmat.h:103
double giveTemperature(GaussPoint *gp, TimeStep *tStep) const
Definition misesmat.C:739
FloatMatrixF< 1, 1 > give1dStressStiffMtrx(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const override
Definition misesmat.C:616
double checkYieldStress(double &dKappa, double kappa, GaussPoint *gp, TimeStep *tStep) const
Definition misesmat.C:379
int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep) override
Definition misesmat.C:647
std::unique_ptr< MaterialStatus > CreateStatus(GaussPoint *gp) const override
Definition misesmat.C:103
double computeDamage(GaussPoint *gp, TimeStep *tStep) const
Definition misesmat.C:472
double yieldTol
tolerance for the yield function in RRM algorithm.
Definition misesmat.h:106
void performPlasticityReturn(const FloatArray &totalStrain, GaussPoint *gp, TimeStep *tStep) const
Definition misesmat.C:181
FloatArray h_eps
user-defined hardening (yield stress - kappa)
Definition misesmat.h:98
FloatMatrixF< 3, 3 > givePlaneStressStiffMtrx(MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep) const override
Definition misesmat.C:548
double computeYieldStressPrime(double kappa) const
Definition misesmat.C:426
int hType
type of hardening function
Definition misesmat.h:95
double H
Hardening modulus.
Definition misesmat.h:89
FloatArrayF< 3 > giveRealStressVector_PlaneStress(const FloatArrayF< 3 > &totalStrain, GaussPoint *gp, TimeStep *tStep) const override
Default implementation relies on giveRealStressVector_StressControl.
Definition misesmat.C:145
void performPlasticityReturn_PlaneStress(const FloatArrayF< 3 > &totalStrain, GaussPoint *gp, TimeStep *tStep) const
Definition misesmat.C:266
double omega_crit
critical(maximal) damage.
Definition misesmat.h:101
double K
Elastic bulk modulus.
Definition misesmat.h:86
FloatArray h_function_eps
Definition misesmat.h:98
double computeDamageParamPrime(double tempKappa) const
Definition misesmat.C:461
MisesMat(int n, Domain *d)
Definition misesmat.C:54
FloatArrayF< 6 > giveRealStressVector_3d(const FloatArrayF< 6 > &strain, GaussPoint *gp, TimeStep *tStep) const override
Default implementation relies on giveRealStressVector for second Piola-Kirchoff stress.
Definition misesmat.C:162
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 stressVector
Equilibrated stress vector in reduced form.
FloatArray strainVector
Equilibrated strain vector in reduced form.
void restoreContext(DataStream &stream, ContextMode mode) override
virtual FloatArrayF< 1 > giveRealStressVector_1d(const FloatArrayF< 1 > &reducedE, GaussPoint *gp, TimeStep *tStep) const
Default implementation relies on giveRealStressVector_StressControl.
static FloatArrayF< 6 > computeDeviatoricVolumetricSum(const FloatArrayF< 6 > &dev, double mean)
static void giveReducedSymVectorForm(FloatArray &answer, const FloatArray &vec, MaterialMode matMode)
Converts the full unsymmetric Voigt vector (2nd order tensor) to reduced form.
static FloatArrayF< 6 > applyDeviatoricElasticCompliance(const FloatArrayF< 6 > &stress, double EModulus, double nu)
void initializeFrom(InputRecord &ir) override
StructuralMaterial(int n, Domain *d)
static FloatArrayF< 6 > applyDeviatoricElasticStiffness(const FloatArrayF< 6 > &strain, double EModulus, double nu)
static double computeStressNorm(const FloatArrayF< 6 > &stress)
void giveStressDependentPartOfStrainVector(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedStrainVector, TimeStep *tStep, ValueModeType mode) const
int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep) override
static std::pair< FloatArrayF< 6 >, double > computeDeviatoricVolumetricSplit(const FloatArrayF< 6 > &s)
static void giveFullSymVectorForm(FloatArray &answer, const FloatArray &vec, MaterialMode matMode)
Converts the reduced unsymmetric Voigt vector (2nd order tensor) to full form.
double giveIntrinsicTime()
Returns intrinsic time, e.g. time in which constitutive model is evaluated.
Definition timestep.h:166
#define THROW_CIOERR(e)
#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_MisesMat_a
Definition misesmat.h:55
#define _IFT_MisesMat_sig0
Definition misesmat.h:49
#define _IFT_MisesMat_h_function_eps
Definition misesmat.h:53
#define _IFT_MisesMat_h_eps
Definition misesmat.h:52
#define _IFT_MisesMat_omega_crit
Definition misesmat.h:54
#define _IFT_MisesMat_h
Definition misesmat.h:50
#define _IFT_MisesMat_yieldTol
Definition misesmat.h:56
#define _IFT_MisesMat_htype
Definition misesmat.h:51
long ContextMode
Definition contextmode.h:43
FloatMatrixF< N, M > dyad(const FloatArrayF< N > &a, const FloatArrayF< M > &b)
Computes the dyadic product .
double signum(double i)
Returns the signum of given value (i = 0 returns 0, i < 0 returns -1, i > 0 returns 1).
Definition mathfem.C:327
const FloatMatrixF< 6, 6 > I_dev6
I_dev matrix in Voigt (stress) form.
std::shared_ptr< Field > FieldPtr
Definition field.h:78
@ CIO_IOERR
General IO error.

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011