OOFEM 3.0
Loading...
Searching...
No Matches
microplane_m1.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 "microplane_m1.h"
36#include "floatarray.h"
37#include "floatmatrix.h"
38#include "mathfem.h"
39#include "classfactory.h"
40
41namespace oofem {
43
44#ifdef microplane_m1_new_implementation
45// ========================= new implementation =========================
46M1Material :: M1Material(int n, Domain *d) : MicroplaneMaterial(n, d)
47{ }
48
49void
50M1Material :: initializeFrom(InputRecord &ir)
51{
52 MicroplaneMaterial :: initializeFrom(ir);
53
54 if ( nu != 0.25 ) {
55 OOFEM_WARNING("Poisson ratio of microplane model M1 must be set to 0.25");
56 }
57 nu = 0.25; // read by MicroplaneMaterial, but overwritten here
58 EN = E / ( 1. - 2. * nu );
60 HN = 0.;
62 ENtan = EN * HN / ( EN + HN );
63}
64
66M1Material :: giveRealStressVector_3d(const FloatArrayF<6> &strain, GaussPoint *gp,
67 TimeStep *tStep) const
68{
69 auto status = static_cast< M1MaterialStatus * >( this->giveStatus(gp) );
70
71 // get the status at the beginning
72 // prepare status at the end
73 this->initTempStatus(gp);
74 // get the initial values of plastic strains on microplanes (set to zero in the first step)
75 FloatArray epspN = status->giveNormalMplanePlasticStrains();
76 if ( epspN.giveSize() < numberOfMicroplanes ) {
78 epspN.zero();
79 }
80
81 FloatArrayF<6> stress;
82
83 // loop over microplanes
86 for ( int imp = 1; imp <= numberOfMicroplanes; imp++ ) {
87 double epsN = computeNormalStrainComponent(imp, strain);
88 // evaluate trial stress on the microplane
89 double sigTrial = EN * ( epsN - epspN.at(imp) );
90 // evaluate the yield stress (from total microplane strain, not from its plastic part)
91 double sigYield = EN * ( s0 + HN * epsN ) / ( EN + HN );
92 if ( sigYield < 0. ) {
93 sigYield = 0.;
94 }
95 // check whether the yield stress is exceeded and set the microplane stress
96 if ( sigTrial > sigYield ) { //plastic yielding
97 sigN.at(imp) = sigYield;
98 epspN.at(imp) = epsN - sigYield / EN;
99 plState.at(imp) = 1;
100 } else {
101 sigN.at(imp) = sigTrial;
102 plState.at(imp) = 0;
103 }
104 // add the contribution of the microplane to macroscopic stresses
105 for ( int i = 1; i <= 6; i++ ) {
106 stress.at(i) += N [ imp - 1 ] [ i - 1 ] * sigN.at(imp) * microplaneWeights [ imp - 1 ];
107 }
108 }
109 // multiply the integral over unit hemisphere by 6
110 stress *= 6;
111
112 // update status
113 status->letTempStrainVectorBe(strain);
114 status->letTempStressVectorBe(stress);
115 status->letTempNormalMplaneStressesBe(sigN);
116 status->letTempNormalMplanePlasticStrainsBe(epspN);
117 status->letPlasticStateIndicatorsBe(plState);
118 return stress;
119}
120
122M1Material :: give3dMaterialStiffnessMatrix(MatResponseMode mode,
123 GaussPoint *gp,
124 TimeStep *tStep) const
125{
126 // elastic stiffness matrix
127 if ( mode == ElasticStiffness ) {
128 return MicroplaneMaterial :: give3dMaterialStiffnessMatrix(mode, gp, tStep);
129 }
130
131 M1MaterialStatus *status = static_cast< M1MaterialStatus * >( this->giveStatus(gp) );
132 IntArray plasticState = status->givePlasticStateIndicators();
133 if ( plasticState.giveSize() != numberOfMicroplanes ) {
134 return MicroplaneMaterial :: give3dMaterialStiffnessMatrix(mode, gp, tStep);
135 }
136 // tangent stiffness matrix
137 double aux, D11 = 0., D12 = 0., D13 = 0., D14 = 0., D15 = 0., D16 = 0., D22 = 0., D23 = 0., D24 = 0., D25 = 0., D26 = 0., D33 = 0., D34 = 0., D35 = 0., D36 = 0.;
138 // loop over microplanes
139 for ( int im = 0; im < numberOfMicroplanes; im++ ) {
140 if ( plasticState.at(im + 1) ) {
141 aux = ENtan * microplaneWeights [ im ];
142 } else {
143 aux = EN * microplaneWeights [ im ];
144 }
145 D11 += aux * N [ im ] [ 0 ] * N [ im ] [ 0 ];
146 D12 += aux * N [ im ] [ 0 ] * N [ im ] [ 1 ];
147 D13 += aux * N [ im ] [ 0 ] * N [ im ] [ 2 ];
148 D14 += aux * N [ im ] [ 0 ] * N [ im ] [ 3 ];
149 D15 += aux * N [ im ] [ 0 ] * N [ im ] [ 4 ];
150 D16 += aux * N [ im ] [ 0 ] * N [ im ] [ 5 ];
151
152 D22 += aux * N [ im ] [ 1 ] * N [ im ] [ 1 ];
153 D23 += aux * N [ im ] [ 1 ] * N [ im ] [ 2 ];
154 D24 += aux * N [ im ] [ 1 ] * N [ im ] [ 3 ];
155 D25 += aux * N [ im ] [ 1 ] * N [ im ] [ 4 ];
156 D26 += aux * N [ im ] [ 1 ] * N [ im ] [ 5 ];
157
158 D33 += aux * N [ im ] [ 2 ] * N [ im ] [ 2 ];
159 D34 += aux * N [ im ] [ 2 ] * N [ im ] [ 3 ];
160 D35 += aux * N [ im ] [ 2 ] * N [ im ] [ 4 ];
161 D36 += aux * N [ im ] [ 2 ] * N [ im ] [ 5 ];
162 }
163 FloatMatrixF<6,6> answer;
164 answer.at(1, 1) = D11;
165 answer.at(1, 2) = answer.at(2, 1) = answer.at(6, 6) = D12;
166 answer.at(1, 3) = answer.at(3, 1) = answer.at(5, 5) = D13;
167 answer.at(1, 4) = answer.at(4, 1) = answer.at(5, 6) = answer.at(6, 5) = D14;
168 answer.at(1, 5) = answer.at(5, 1) = D15;
169 answer.at(1, 6) = answer.at(6, 1) = D16;
170
171 answer.at(2, 2) = D22;
172 answer.at(2, 3) = answer.at(3, 2) = answer.at(4, 4) = D23;
173 answer.at(2, 4) = answer.at(4, 2) = D24;
174 answer.at(2, 5) = answer.at(5, 2) = answer.at(4, 6) = answer.at(6, 4) = D25;
175 answer.at(2, 6) = answer.at(6, 2) = D26;
176
177 answer.at(3, 3) = answer.at(3, 3) = D33;
178 answer.at(3, 4) = answer.at(4, 3) = D34;
179 answer.at(3, 5) = answer.at(5, 3) = D35;
180 answer.at(3, 6) = answer.at(6, 3) = answer.at(4, 5) = answer.at(5, 4) = D36;
181 answer *= 6.;
182
183 return answer;
184}
185
186int
187M1Material :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
188{
189 M1MaterialStatus *status = static_cast< M1MaterialStatus * >( this->giveStatus(gp) );
190 if ( type == IST_PlasticStrainTensor ) {
191 // plastic strain is computed as total strain minus elastic strain
192 // (note that integration of microplane plastic strains would give a different result)
193 answer = status->giveStrainVector();
194 FloatArray sig = status->giveStressVector();
195 double aux = nu * ( sig.at(1) + sig.at(2) + sig.at(3) );
196 double G = E / ( 2. * ( 1. + nu ) );
197 answer.at(1) -= ( ( 1. + nu ) * sig.at(1) - aux ) / E;
198 answer.at(2) -= ( ( 1. + nu ) * sig.at(2) - aux ) / E;
199 answer.at(3) -= ( ( 1. + nu ) * sig.at(3) - aux ) / E;
200 answer.at(4) -= sig.at(4) / G;
201 answer.at(5) -= sig.at(5) / G;
202 answer.at(6) -= sig.at(6) / G;
203 return 1;
204 } else {
205 return StructuralMaterial :: giveIPValue(answer, gp, type, tStep);
206 }
207}
208
209
210M1MaterialStatus :: M1MaterialStatus(GaussPoint *g) :
212{}
213
214
215void
216M1MaterialStatus :: initTempStatus()
217{
218 StructuralMaterialStatus :: initTempStatus();
219}
220
221void
222M1MaterialStatus :: printOutputAt(FILE *file, TimeStep *tStep) const
223{
224 StructuralMaterialStatus :: printOutputAt(file, tStep);
225 fprintf(file, "status { sigN ");
226 for ( auto v : sigN ) {
227 fprintf( file, " %g ", v );
228 }
229 fprintf(file, " epspN ");
230 for ( auto v : epspN ) {
231 fprintf( file, " %g ", v );
232 }
233 fprintf(file, " plast ");
234 for ( auto v : plasticState ) {
235 fprintf( file, " %d ", v );
236 }
237 fprintf(file, "}\n");
238}
239
240void
241M1MaterialStatus :: updateYourself(TimeStep *tStep)
242{
243 sigN = tempSigN;
245 StructuralMaterialStatus :: updateYourself(tStep);
246}
247
248void
249M1MaterialStatus :: saveContext(DataStream &stream, ContextMode mode)
250{
251 StructuralMaterialStatus :: saveContext(stream, mode);
253}
254
255void
256M1MaterialStatus :: restoreContext(DataStream &stream, ContextMode mode)
257{
258 StructuralMaterialStatus :: restoreContext(stream, mode);
260}
261
262#else
263// ========================= old implementation =========================
264M1Material :: M1Material(int n, Domain *d) : StructuralMaterial(n, d)
265{ E = 0.; nu = 0.; EN = 0.; s0 = 0.; HN = 0.; }
266
267void
268M1Material :: giveRealStressVector_PlaneStress(FloatArray &answer,
269 GaussPoint *gp,
270 const FloatArray &totalStrain,
271 TimeStep *tStep)
272{
273 FloatArray sigmaN, deps, sigmaNyield;
274 double depsN, epsN;
275
276 answer.resize(3);
277 answer.zero();
278 sigmaNyield.resize(nmp);
279 sigmaNyield.zero();
280
281 M1MaterialStatus *status = static_cast< M1MaterialStatus * >( this->giveStatus(gp) );
282 this->initTempStatus(gp);
283 sigmaN = status->giveNormalMplaneStresses();
284 if ( sigmaN.giveSize() < nmp ) {
285 sigmaN.resize(nmp);
286 sigmaN.zero();
287 }
288 deps.beDifferenceOf( totalStrain, status->giveStrainVector() );
289
290 for ( int imp = 1; imp <= nmp; imp++ ) {
291 depsN = N.at(imp, 1) * deps.at(1) + N.at(imp, 2) * deps.at(2) + N.at(imp, 3) * deps.at(3);
292 epsN = N.at(imp, 1) * totalStrain.at(1) + N.at(imp, 2) * totalStrain.at(2) + N.at(imp, 3) * totalStrain.at(3);
293 sigmaN.at(imp) += EN * depsN;
294 double sy = EN * ( s0 + HN * epsN ) / ( EN + HN ); // current microplane yield stress
295 if ( sy < 0. ) {
296 sy = 0.;
297 }
298 if ( sigmaN.at(imp) > sy ) {
299 sigmaN.at(imp) = sy;
300 }
301 sigmaNyield.at(imp) = sy;
302 for ( int i = 1; i <= 3; i++ ) {
303 answer.at(i) += N.at(imp, i) * sigmaN.at(imp) * mw.at(imp);
304 }
305 }
306
307 // update status
308 status->letTempStrainVectorBe(totalStrain);
309 status->letTempNormalMplaneStressesBe(sigmaN);
310 status->letNormalMplaneYieldStressesBe(sigmaNyield);
311 status->letTempStressVectorBe(answer);
312}
313
314void
315M1Material :: giveElasticPlaneStressStiffMtrx(FloatMatrix &answer)
316{
317 answer.resize(3, 3);
318 answer.at(1, 1) = answer.at(2, 2) = E / ( 1. - nu * nu );
319 answer.at(1, 2) = answer.at(2, 1) = E * nu / ( 1. - nu * nu );
320 answer.at(1, 3) = answer.at(2, 3) = answer.at(3, 1) = answer.at(3, 2) = 0.;
321 answer.at(3, 3) = E / ( 2. * ( 1. + nu ) );
322}
323
324void
325M1Material :: givePlaneStressStiffMtrx(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep)
326{
327 answer.resize(3, 3);
328 if ( rMode == ElasticStiffness ) {
329 giveElasticPlaneStressStiffMtrx(answer);
330 return;
331 }
332
333 M1MaterialStatus *status = static_cast< M1MaterialStatus * >( this->giveStatus(gp) );
334 FloatArray sigmaN = status->giveTempNormalMplaneStresses();
335 if ( sigmaN.giveSize() != nmp ) {
336 sigmaN = status->giveNormalMplaneStresses();
337 if ( sigmaN.giveSize() != nmp ) {
338 giveElasticPlaneStressStiffMtrx(answer);
339 return;
340 }
341 }
342 FloatArray sigmaNyield = status->giveNormalMplaneYieldStresses();
343
344 double D11, D12, D13, D22, D23, aux;
345 D11 = D12 = D13 = D22 = D23 = 0.;
346 for ( int imp = 1; imp <= nmp; imp++ ) {
347 if ( sigmaN.at(imp) < sigmaNyield.at(imp) ) { // otherwise the plane is yielding
348 aux = mw.at(imp) * EN;
349 } else if ( sigmaNyield.at(imp) > 0. ) {
350 aux = mw.at(imp) * EN * HN / ( EN + HN );
351 } else {
352 aux = 0.;
353 }
354 D11 += aux * NN.at(imp, 1);
355 D12 += aux * NN.at(imp, 3);
356 D13 += aux * NN.at(imp, 2);
357 D22 += aux * NN.at(imp, 5);
358 D23 += aux * NN.at(imp, 4);
359 }
360 answer.at(1, 1) = D11;
361 answer.at(1, 2) = answer.at(2, 1) = answer.at(3, 3) = D12;
362 answer.at(1, 3) = answer.at(3, 1) = D13;
363 answer.at(2, 2) = D22;
364 answer.at(2, 3) = answer.at(3, 2) = D23;
365}
366
367
368void
369M1Material :: initializeFrom(InputRecord &ir)
370{
371 StructuralMaterial :: initializeFrom(ir);
372
373 IR_GIVE_FIELD(ir, E, _IFT_M1Material_e);
374 EN = 1.5 * E;
375 nu = 1. / 3.;
377 HN = 0.;
379
380 // specify microplanes
381 IR_GIVE_FIELD(ir, nmp, _IFT_M1Material_nmp);
382 n.resize(nmp, 2);
383 N.resize(nmp, 3);
384 NN.resize(nmp, 5);
385 mw.resize(nmp);
386 for ( int imp = 1; imp <= nmp; imp++ ) {
387 double alpha = ( imp - 1 ) * ( M_PI / nmp );
388 double c = cos(alpha);
389 double s = sin(alpha);
390 n.at(imp, 1) = c;
391 n.at(imp, 2) = s;
392 N.at(imp, 1) = c * c;
393 N.at(imp, 2) = s * s;
394 N.at(imp, 3) = c * s;
395 NN.at(imp, 1) = c * c * c * c;
396 NN.at(imp, 2) = c * c * c * s;
397 NN.at(imp, 3) = c * c * s * s;
398 NN.at(imp, 4) = c * s * s * s;
399 NN.at(imp, 5) = s * s * s * s;
400 mw.at(imp) = 2. / nmp;
401 }
402}
403
404bool
405M1Material :: hasMaterialModeCapability(MaterialMode mode) const
406{
407 return mode == _PlaneStress;
408}
409
410int
411M1Material :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
412{
413 M1MaterialStatus *status = static_cast< M1MaterialStatus * >( this->giveStatus(gp) );
414 if ( type == IST_PlasticStrainTensor ) {
415 FloatArray plasticStrain(3);
416 plasticStrain.zero();
417 FloatArray sigmaN = status->giveTempNormalMplaneStresses();
418 FloatArray strain = status->giveTempStrainVector();
419 double Exx, Eyy, Gamma;
420 Exx = Eyy = Gamma = 0.;
421 if ( sigmaN.giveSize() == nmp ) {
422 for ( int imp = 1; imp <= nmp; imp++ ) {
423 double epsN = 0.;
424 for ( int i = 1; i <= 3; i++ ) {
425 epsN += strain.at(i) * N.at(imp, i);
426 }
427 double epsNpl = epsN - sigmaN.at(imp) / EN;
428 double aux = epsNpl * mw.at(imp);
429 Exx += aux * N.at(imp, 1);
430 Eyy += aux * N.at(imp, 2);
431 Gamma += aux * N.at(imp, 3);
432 }
433 }
434 plasticStrain.at(1) = 1.5 * Exx - 0.5 * Eyy;
435 plasticStrain.at(2) = -0.5 * Exx + 1.5 * Eyy;
436 plasticStrain.at(3) = 4. * Gamma;
437 StructuralMaterial :: giveFullSymVectorForm( answer, plasticStrain, gp->giveMaterialMode() );
438 return 1;
439 } else {
440 return StructuralMaterial :: giveIPValue(answer, gp, type, tStep);
441 }
442}
443
445
446M1MaterialStatus :: M1MaterialStatus(GaussPoint *g) :
447 StructuralMaterialStatus(g), sigN(0)
448{}
449
450
451M1MaterialStatus :: ~M1MaterialStatus()
452{ }
453
454void
455M1MaterialStatus :: initTempStatus()
456{
457 StructuralMaterialStatus :: initTempStatus();
458}
459
460void
461M1MaterialStatus :: printOutputAt(FILE *file, TimeStep *tStep)
462{
463 StructuralMaterialStatus :: printOutputAt(file, tStep);
464 fprintf(file, "status { sigN ");
465 int nm = sigN.giveSize();
466 for ( int imp = 1; imp <= nm; imp++ ) {
467 fprintf( file, " %f ", sigN.at(imp) );
468 }
469 fprintf(file, "}\n");
470}
471
472void
473M1MaterialStatus :: updateYourself(TimeStep *tStep)
474{
475 sigN = tempSigN;
476 StructuralMaterialStatus :: updateYourself(tStep);
477}
478
479void
480M1MaterialStatus :: saveContext(DataStream &stream, ContextMode mode)
481{
482 StructuralMaterialStatus :: saveContext(stream, mode);
483}
484
485void
486M1MaterialStatus :: restoreContext(DataStream &stream, ContextMode mode)
487{
488 StructuralMaterialStatus :: restoreContext(stream, mode);
489}
490
491#endif // end of old implementation
492} // end namespace oofem
#define N(a, b)
#define E(a, b)
#define REGISTER_Material(class)
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 zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
double at(std::size_t i, std::size_t j) const
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
const IntArray & givePlasticStateIndicators()
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Definition material.C:206
virtual void initTempStatus(GaussPoint *gp) const
Definition material.C:221
std::vector< FloatArrayF< 6 > > N
FloatArray microplaneWeights
Integration weights of microplanes.
double E
Young's modulus.
int numberOfMicroplanes
Number of microplanes.
double nu
Poisson's ratio.
double computeNormalStrainComponent(int mnumber, const FloatArray &macroStrain) const
MicroplaneMaterial(int n, Domain *d)
const FloatArray & giveStrainVector() const
Returns the const pointer to receiver's strain vector.
StructuralMaterialStatus(GaussPoint *g)
Constructor. Creates new StructuralMaterialStatus with IntegrationPoint g.
const FloatArray & giveStressVector() const
Returns the const pointer to receiver's stress vector.
#define OOFEM_WARNING(...)
Definition error.h:80
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Definition inputrecord.h:75
#define IR_GIVE_FIELD(__ir, __value, __id)
Definition inputrecord.h:67
#define M_PI
Definition mathfem.h:52
#define _IFT_M1Material_s0
#define _IFT_M1Material_hn
long ContextMode
Definition contextmode.h:43

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