OOFEM 3.0
Loading...
Searching...
No Matches
latticeplasticitydamageviscoelastic.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 program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (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
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 */
34
36#include "gausspoint.h"
37#include "floatmatrix.h"
38#include "floatarray.h"
40#include "datastream.h"
41#include "contextioerr.h"
42#include "classfactory.h"
43
44
45namespace oofem {
47
50
51void
53{
55
57
58 RheoChainMaterial *rheoMat = static_cast< RheoChainMaterial * >( domain->giveMaterial(this->viscoMat) );
59
60 // override elastic modulus by the one given by the compliance function
61 timeFactor = 0.;
62 IR_GIVE_FIELD(ir, timeFactor, _IFT_LatticePlasticityDamageViscoelastic_timeFactor); // timeConversion equal to 1 day in current time units of the analysis
63
64 double E28 = 1. / rheoMat->computeCreepFunction(timeFactor * 28.01, timeFactor * 28., NULL, NULL); // modulus of elasticity evaluated at 28 days, duration of loading 15 min
65
66 this->eNormalMean = E28; // swap elastic modulus/stiffness
67
69 this->fib = true;
73 }
74}
75
76
77std::unique_ptr<MaterialStatus>
79{
80 return std::make_unique<LatticePlasticityDamageViscoelasticStatus>(1, LatticePlasticityDamageViscoelastic::domain, gp);
81}
82
83
86 GaussPoint *gp,
87 TimeStep *tStep)
88{
89 double tol = 1.e-12; // error in order of approx. Pascals
90
91 auto status = static_cast< LatticePlasticityDamageViscoelasticStatus * >( this->giveStatus(gp) );
92
93 RheoChainMaterial *rheoMat = static_cast< RheoChainMaterial * >( domain->giveMaterial(this->viscoMat) );
94
95 GaussPoint *rChGP = status->giveSlaveGaussPointVisco();
96 // just a dummy yet essential call to create a status of viscomaterial. Otherwise initTempStatus() would fail.
97 rheoMat->giveStatus(rChGP);
98
99 status->initTempStatus();
100
101 FloatArrayF< 6 >reducedStrainForViscoMat;
102 FloatArrayF< 6 >reducedStrain;
103 FloatArrayF< 6 >quasiReducedStrain;
104
105 FloatArray tempStressVE;
106 FloatArrayF< 6 >viscoStress;
107 FloatArrayF< 6 >plastDamStress;
108
109 int itercount = 1;
110
111 FloatArray indepStrain;
112 indepStrain = this->computeStressIndependentStrainVector(gp, tStep, VM_Total);
113
114 auto elasticStiffnessMatrix = LatticeLinearElastic::give3dLatticeStiffnessMatrix(ElasticStiffness, gp, tStep);
115
116 double tolerance = 1.;
117
118 FloatArrayF< 6 >inelasticTrialStrain;
119
120 double sigmaResid;
121 double sigmaResidPlus = this->eNormalMean;
122 double sigmaResidMinus = -sigmaResidPlus;
123
124
125 FloatArrayF< 6 >inelastPlus;
126 FloatArrayF< 6 >inelastMinus;
127
128 bool plusFlag = false;
129 bool minusFlag = false;
130
131 int iterBisection = 10;
132
133 do {
134 if ( itercount > 100 ) {
135 OOFEM_WARNING("Algorithm not converging");
136
137 printf("Algorithm not converging, giving up\n");
138 printf("Unable to reach equilibrium between viscoelastic and CDPM materials, Element %d\n", gp->giveElement()->giveNumber() );
139 printf("tolerance = %e > %e!, stress error = %e, itercount = %d\n", tolerance, tol, sigmaResid, itercount);
140
141 if ( plusFlag ) {
142 printf("inelastPlus = ");
143 for ( auto &val : inelastPlus ) {
144 printf(" %.10e", val);
145 }
146 printf(" sigmaResidPlus = %e \n", sigmaResidPlus);
147 }
148
149 if ( minusFlag ) {
150 printf("inelastMinus = ");
151 for ( auto &val : inelastMinus ) {
152 printf(" %.10e", val);
153 }
154 printf(" sigmaResidMinus = %e \n", sigmaResidMinus);
155 }
156
157 break;
158 }
159
160 reducedStrainForViscoMat = totalStrain;
161
162 if ( indepStrain.giveSize() > 0 ) {
163 reducedStrainForViscoMat -= FloatArrayF< 6 >(indepStrain);
164 }
165
166 if ( itercount < iterBisection || ( !plusFlag || !minusFlag ) ) {
167 inelasticTrialStrain = status->giveTempPlasticLatticeStrain() + FloatArrayF< 6 >( status->giveTempDamageLatticeStrain() );
168 }
169
170 reducedStrainForViscoMat -= inelasticTrialStrain;
171
172 rheoMat->giveRealStressVector(tempStressVE, rChGP, reducedStrainForViscoMat, tStep);
173 viscoStress = FloatArrayF< 6 >(tempStressVE);
174
175 for ( int i = 1; i <= 6; i++ ) {
176 quasiReducedStrain.at(i) = viscoStress.at(i) / elasticStiffnessMatrix.at(i, i) + inelasticTrialStrain.at(i);
177 }
178
179 plastDamStress = this->performPlasticityReturn(gp, quasiReducedStrain, tStep);
180 this->performDamageEvaluation(gp, quasiReducedStrain, tStep);
181 double tempDamage = status->giveTempDamage();
182 plastDamStress *= ( 1. - tempDamage );
183
184 inelasticTrialStrain = status->giveTempPlasticLatticeStrain();
185 inelasticTrialStrain += FloatArrayF< 6 >(status->giveTempDamageLatticeStrain() );
186
187 tolerance = norm(plastDamStress - viscoStress) / this->eNormalMean;
188
189 // try bisection method - prepare bounds, might be needed
190 sigmaResid = viscoStress [ 0 ] - plastDamStress [ 0 ];
191
192 if ( sigmaResid > 0. ) {
193 if ( sigmaResid < sigmaResidPlus ) {
194 plusFlag = true;
195 sigmaResidPlus = sigmaResid;
196 inelastPlus = inelasticTrialStrain;
197 }
198 } else {
199 if ( sigmaResid > sigmaResidMinus ) {
200 minusFlag = true;
201 sigmaResidMinus = sigmaResid;
202 inelastMinus = inelasticTrialStrain;
203 }
204 }
205
206 if ( itercount >= iterBisection && plusFlag && minusFlag ) {
207 inelasticTrialStrain = ( sigmaResidPlus * inelastMinus - sigmaResidMinus * inelastPlus ) / ( sigmaResidPlus - sigmaResidMinus );
208 }
209
210 itercount++;
211 } while ( tolerance >= tol );
212
213 status->letTempLatticeStrainBe(totalStrain);
214 status->letTempLatticeStressBe(viscoStress);
215 status->letTempReducedLatticeStrainBe(quasiReducedStrain);
216
217 return viscoStress;
218}
219
220double
222{
223 if ( fib ) {
224 double equivalentTime = this->giveEquivalentTime(gp, tStep);
225 double fcm = exp(this->fib_s * ( 1. - sqrt(28. * this->timeFactor / equivalentTime) ) ) * this->fib_fcm28;
226 return fcm / this->fib_fcm28 * LatticePlasticityDamage::giveCompressiveStrength(gp, tStep);
227 } else {
229 }
230}
231
232
233double
235{
236 // check if the fracture properties are constant or time-dependent
237 double ftm = 1.;
238 double ftm28 = 1.;
239
240 if ( fib ) {
241 double equivalentTime = this->giveEquivalentTime(gp, tStep);
242 double fcm = exp(this->fib_s * ( 1. - sqrt(28. * this->timeFactor / equivalentTime) ) ) * this->fib_fcm28;
243
244 //Calculate the aged tensile strength
245 if ( fcm >= 58. ) {
246 ftm = 2.12 * log(1. + 0.1 * fcm) * 1.e6 / this->stiffnessFactor;
247 } else if ( fcm <= 20. ) {
248 ftm = 0.07862 * fcm * 1.e6 / this->stiffnessFactor; // 12^(2/3) * 0.3 / 20 = 0.07862
249 } else {
250 ftm = 0.3 * pow(fcm - 8., 2. / 3.) * 1.e6 / this->stiffnessFactor; //5.1-3a
251 }
252
253 //Do the same for the 28 day compressive strength
254 if ( this->fib_fcm28 >= 58. ) {
255 ftm28 = 2.12 * log(1. + 0.1 * this->fib_fcm28) * 1.e6 / this->stiffnessFactor;
256 } else if ( this->fib_fcm28 <= 20. ) {
257 ftm28 = 0.07862 * this->fib_fcm28 * 1.e6 / this->stiffnessFactor; // 12^(2/3) * 0.3 / 20 = 0.07862
258 } else {
259 ftm28 = 0.3 * pow(this->fib_fcm28 - 8., 2. / 3.) * 1.e6 / this->stiffnessFactor; //5.1-3a
260 }
261 return ftm / ftm28 * LatticePlasticityDamage::giveTensileStrength(gp, tStep);
262 } else {
264 }
265}
266
267
270{
272 GaussPoint *slaveGp;
273
274 // get status of the slave viscoelastic material
275 slaveGp = status->giveSlaveGaussPointVisco();
276
277 // get viscoelastic material
278 RheoChainMaterial *rheoMat = static_cast< RheoChainMaterial * >( domain->giveMaterial(this->viscoMat) );
279
280 double Eincr = rheoMat->giveEModulus(slaveGp, tStep);
281
282 auto answer = LatticeLinearElastic::give3dLatticeStiffnessMatrix(ElasticStiffness, gp, tStep);
283
284 answer *= ( Eincr / this->eNormalMean );
285
286 if ( rmode == ElasticStiffness ) {
287 return answer;
288 } else if ( ( rmode == SecantStiffness ) || ( rmode == TangentStiffness ) ) {
289 double omega = min(status->giveTempDamage(), 0.99999);
290 return answer * ( 1. - omega );
291 } else {
292 OOFEM_ERROR("Unsupported stiffness mode\n");
293 }
294}
295
296int
298 GaussPoint *gp,
300 TimeStep *tStep)
301{
302 if ( ( type == IST_DryingShrinkageTensor ) ||
303 ( type == IST_AutogenousShrinkageTensor ) ||
304 ( type == IST_TotalShrinkageTensor ) ||
305 ( type == IST_CreepStrainTensor ) ||
306 ( type == IST_DryingShrinkageTensor ) ||
307 ( type == IST_ThermalStrainTensor ) ) {
309
310 RheoChainMaterial *rheoMat = static_cast< RheoChainMaterial * >( domain->giveMaterial(this->viscoMat) );
311 return rheoMat->giveIPValue(answer, status->giveSlaveGaussPointVisco(), type, tStep);
312 }
313
314 return LatticePlasticityDamage::giveIPValue(answer, gp, type, tStep);
315}
316
317
319{
320 RheoChainMaterial *rheoMat = static_cast< RheoChainMaterial * >( domain->giveMaterial(this->viscoMat) );
321
322 if ( rheoMat->giveAlphaOne() != this->alphaOne ) {
323 OOFEM_ERROR("a1 must be set to the same value in both master and viscoelastic slave materials");
324 }
325
326 if ( rheoMat->giveAlphaTwo() != this->alphaTwo ) {
327 OOFEM_ERROR("a2 must be set to the same value in both master and viscoelastic slave materials");
328 }
329
330 GaussPoint *noGP = NULL;
331 if ( rheoMat->give(tAlpha, noGP) != 0. ) {
332 OOFEM_ERROR("tAlpha must be set to 0. in slave viscoelastic material");
333 }
334
335
337}
338
339double
341{
342 RheoChainMaterial *rheoMat = static_cast< RheoChainMaterial * >( domain->giveMaterial(this->viscoMat) );
343
345
346 return rheoMat->giveEquivalentTime(status->giveSlaveGaussPointVisco(), tStep);
347}
348
349
351 LatticePlasticityDamageStatus(n, d, gp), slaveGpVisco(std::make_unique< GaussPoint >(gp->giveIntegrationRule(), 0, gp->giveNaturalCoordinates(), 0., gp->giveMaterialMode() ) )
352{}
353
354void
356//
357// initializes temp variables according to variables form previous equlibrium state.
358{
360
361 // at this point rheomat :: giveStatus (viscoGP) has to be called first
363
364 rheoStatus->initTempStatus();
365}
366
367void
369{
371 fprintf(file, "\nViscoelastic material:");
372
374
375 fprintf(file, "\n");
376}
377
378
379void
381//
382// updates variables (nonTemp variables describing situation at previous equilibrium state)
383// after a new equilibrium state has been reached
384// temporary variables are having values corresponding to newly reached equilibrium.
385//
386{
388
390}
391
392void
394//
395// saves full information stored in this Status
396// no temp variables stored
397//
398{
400
402}
403
404void
406//
407// restores full information stored in stream to this Status
408//
409{
411
413}
414} // end namespace oofem
#define REGISTER_Material(class)
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition femcmpnn.h:79
int giveNumber() const
Definition femcmpnn.h:104
virtual int checkConsistency()
Definition femcmpnn.C:89
double & at(std::size_t i)
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
IntegrationPointStatus * giveMaterialStatus(IntegrationPointStatusIDType key=IPSID_Default)
Definition gausspoint.h:204
Element * giveElement()
Returns corresponding element to receiver.
Definition gausspoint.h:187
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
virtual void printOutputAt(FILE *file, TimeStep *tStep) const
Print receiver's output to given stream.
virtual void restoreContext(DataStream &stream, ContextMode mode)
GaussPoint * gp
Associated integration point.
virtual void saveContext(DataStream &stream, ContextMode mode)
virtual void updateYourself(TimeStep *)
double eNormalMean
Normal modulus.
MaterialStatus * giveStatus(GaussPoint *gp) const override
FloatMatrixF< 6, 6 > give3dLatticeStiffnessMatrix(MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) const override
LatticePlasticityDamageStatus(int n, Domain *d, GaussPoint *g)
Constructor.
void printOutputAt(FILE *file, TimeStep *tStep) const override
Print receiver's output to given stream.
void restoreContext(DataStream &stream, ContextMode mode) override
void saveContext(DataStream &stream, ContextMode mode) override
void restoreContext(DataStream &stream, ContextMode mode) override
LatticePlasticityDamageViscoelasticStatus(int n, Domain *d, GaussPoint *g)
Constructor.
void printOutputAt(FILE *file, TimeStep *tStep) const override
Prints the receiver state to given stream.
void saveContext(DataStream &stream, ContextMode mode) override
FloatMatrixF< 6, 6 > give3dLatticeStiffnessMatrix(MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) const override
FloatArrayF< 6 > giveLatticeStress3d(const FloatArrayF< 6 > &totalStrain, GaussPoint *gp, TimeStep *tStep) override
std::unique_ptr< MaterialStatus > CreateStatus(GaussPoint *gp) const override
int viscoMat
'slave' (= viscoelastic) material model number.
int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *atTime) override
virtual double giveEquivalentTime(GaussPoint *gp, TimeStep *tStep) const
returns equivalent time (used to compute time-dependent ft and gf)
double giveCompressiveStrength(GaussPoint *gp, TimeStep *tStep) const override
double giveTensileStrength(GaussPoint *gp, TimeStep *tStep) const override
int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *atTime) override
virtual double giveTensileStrength(GaussPoint *gp, TimeStep *tStep) const
virtual double giveCompressiveStrength(GaussPoint *gp, TimeStep *tStep) const
FloatArrayF< 6 > performPlasticityReturn(GaussPoint *gp, const FloatArrayF< 6 > &reducedStrain, TimeStep *tStep) const
LatticePlasticityDamage(int n, Domain *d)
Constructor.
void initializeFrom(InputRecord &ir) override
void performDamageEvaluation(GaussPoint *gp, FloatArrayF< 6 > &reducedStrain, TimeStep *tStep) const
virtual void initTempStatus()
Definition matstatus.h:99
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Definition material.C:206
virtual double give(int aProperty, GaussPoint *gp) const
Definition material.C:51
void initTempStatus() override
Definition rheoChM.C:742
virtual double giveEModulus(GaussPoint *gp, TimeStep *tStep) const =0
Evaluation of the incremental modulus.
virtual double giveEquivalentTime(GaussPoint *gp, TimeStep *tStep) const
By default returns equivalent time in the middle of the time step.
Definition rheoChM.h:330
double giveAlphaTwo() const
Definition rheoChM.h:312
void giveRealStressVector(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedStrain, TimeStep *tStep) const override
Definition rheoChM.C:72
virtual double computeCreepFunction(double t, double t_prime, GaussPoint *gp, TimeStep *tStep) const =0
Evaluation of the creep compliance function at time t when loading is acting from time t_prime.
double giveAlphaOne() const
Definition rheoChM.h:311
int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep) override
Definition rheoChM.C:657
virtual FloatArray computeStressIndependentStrainVector(GaussPoint *gp, TimeStep *tStep, ValueModeType mode) const
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_ERROR(...)
Definition error.h:79
#define IR_GIVE_FIELD(__ir, __value, __id)
Definition inputrecord.h:67
#define _IFT_LatticePlasticityDamageViscoelastic_stiffnessFactor
#define _IFT_LatticePlasticityDamageViscoelastic_fib_s
#define _IFT_LatticePlasticityDamageViscoelastic_timedepfracturing
#define _IFT_LatticePlasticityDamageViscoelastic_fcm28
#define _IFT_LatticePlasticityDamageViscoelastic_timeFactor
#define _IFT_LatticePlasticityDamageViscoelastic_viscoMat
#define tAlpha
Definition matconst.h:67
long ContextMode
Definition contextmode.h:43
double norm(const FloatArray &x)
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
const double tolerance

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