OOFEM 3.0
Loading...
Searching...
No Matches
linearelasticmaterial.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
36#include "gausspoint.h"
39#include "dynamicinputrecord.h"
40#include "floatarrayf.h"
41#include "floatmatrixf.h"
42
43namespace oofem {
44void
45LinearElasticMaterial :: initializeFrom(InputRecord &ir)
46{
47 StructuralMaterial :: initializeFrom(ir);
48
49 preCastStiffnessReduction = 0.99999999;
51}
52
53
54void
55LinearElasticMaterial :: giveInputRecord(DynamicInputRecord &input)
56{
57 StructuralMaterial :: giveInputRecord(input);
59}
60
61void
62LinearElasticMaterial :: computesSubTangents()
63{
65 tangent(0, 0), tangent(1, 0), tangent(2, 0), tangent(3, 0),
66 tangent(0, 1), tangent(1, 1), tangent(2, 1), tangent(3, 1),
67 tangent(0, 2), tangent(1, 2), tangent(2, 2), tangent(3, 2),
68 tangent(0, 3), tangent(1, 3), tangent(2, 3), tangent(3, 3),
69 };
70
71 auto c = inv(tangent);
72 FloatMatrixF<3,3> reduced = {
73 c(0,0), c(0,1), c(0,5),
74 c(1,0), c(1,1), c(1,5),
75 c(5,0), c(5,1), c(5,5),
76 };
77 tangentPlaneStress = inv(reduced);
78}
79
80
82LinearElasticMaterial :: give3dMaterialStiffnessMatrix(MatResponseMode mode,
83 GaussPoint *gp,
84 TimeStep *tStep) const
85{
86 if ( tStep->giveIntrinsicTime() < this->castingTime ) {
87 return tangent * (1. - this->preCastStiffnessReduction);
88 } else {
89 return tangent;
90 }
91}
92
93
95LinearElasticMaterial :: giveThermalDilatationVector(GaussPoint *gp, TimeStep *tStep) const
96{
97 return alpha;
98}
99
100
102LinearElasticMaterial :: giveRealStressVector_3d(const FloatArrayF<6> &strain, GaussPoint *gp, TimeStep *tStep) const
103{
104 auto status = static_cast< StructuralMaterialStatus * >( this->giveStatus(gp) );
105
106 auto d = this->give3dMaterialStiffnessMatrix(TangentStiffness, gp, tStep);
107
108 FloatArrayF<6> stress;
109 if ( this->castingTime < 0. ) { // no changes in material stiffness ->> total formulation
110 auto thermalStrain = this->computeStressIndependentStrainVector_3d(gp, tStep, VM_Total);
111 auto strainVector = strain - thermalStrain;
112 stress = dot(d, strainVector);
113 } else { // changes in material stiffness ->> incremental formulation
114 auto thermalStrain = this->computeStressIndependentStrainVector_3d(gp, tStep, VM_Incremental);
115 auto strainIncrement = strain - thermalStrain - FloatArrayF<6>(status->giveStrainVector());
116
117 stress = dot(d, strainIncrement) + status->giveStressVector();
118 }
119
120 // update gp
121 status->letTempStrainVectorBe(strain);
122 status->letTempStressVectorBe(stress);
123 return stress;
124}
125
126
128LinearElasticMaterial :: giveRealStressVector_3dDegeneratedShell(const FloatArrayF<6> &strain, GaussPoint *gp, TimeStep *tStep) const
129{
130 auto status = static_cast< StructuralMaterialStatus * >( this->giveStatus(gp) );
131
132 auto d = this->give3dMaterialStiffnessMatrix(TangentStiffness, gp, tStep);
133
134 d.at(1, 1) -= d.at(1, 3) * d.at(3, 1) / d.at(3, 3);
135 d.at(2, 1) -= d.at(2, 3) * d.at(3, 1) / d.at(3, 3);
136 d.at(1, 2) -= d.at(1, 3) * d.at(3, 2) / d.at(3, 3);
137 d.at(2, 2) -= d.at(2, 3) * d.at(3, 2) / d.at(3, 3);
138
139 d.at(3, 1) = 0.0;
140 d.at(3, 2) = 0.0;
141 d.at(3, 3) = 0.0;
142 d.at(2, 3) = 0.0;
143 d.at(1, 3) = 0.0;
144
145 FloatArrayF<6> stress, strainVector;
146 if ( this->castingTime < 0. ) { // no changes in material stiffness ->> total formulation
147 auto thermalStrain = this->computeStressIndependentStrainVector_3d(gp, tStep, VM_Total);
148 strainVector = strain - thermalStrain;
149 stress = dot(d, strainVector);
150 } else { // changes in material stiffness ->> incremental formulation
151 auto thermalStrain = this->computeStressIndependentStrainVector_3d(gp, tStep, VM_Incremental);
152 auto strainIncrement = strain - thermalStrain - FloatArrayF<6>(status->giveStrainVector());
153
154 stress = dot(d, strainIncrement) + status->giveStressVector();
155 }
156
157 stress = dot(d, strainVector);
158
159 // update gp
160 status->letTempStrainVectorBe(strain);
161 status->letTempStressVectorBe(stress);
162 return stress;
163}
164
165
167LinearElasticMaterial :: giveRealStressVector_PlaneStress(const FloatArrayF<3> &reducedStrain, GaussPoint *gp, TimeStep *tStep) const
168{
169 auto status = static_cast< StructuralMaterialStatus * >( this->giveStatus(gp) );
170
171 auto d = this->givePlaneStressStiffMtrx(TangentStiffness, gp, tStep);
172
173 FloatArray answer;
174 FloatArray strainVector;
175 if ( this->castingTime < 0. ) { // no changes in material stiffness ->> total formulation
176 this->giveStressDependentPartOfStrainVector(strainVector, gp, reducedStrain, tStep, VM_Total);
177 answer.beProductOf(d, strainVector);
178 } else { // changes in material stiffness ->> incremental formulation
179 this->giveStressDependentPartOfStrainVector(strainVector, gp, reducedStrain, tStep, VM_Incremental);
180 auto strainIncrement = strainVector - status->giveStrainVector();
181
182 answer.beProductOf(d, strainIncrement);
183 answer.add( status->giveStressVector() );
184 }
185
186 // update gp
187 status->letTempStrainVectorBe(reducedStrain);
188 status->letTempStressVectorBe(answer);
189 return answer;
190}
191
192
194LinearElasticMaterial :: giveRealStressVector_1d(const FloatArrayF<1> &reducedStrain, GaussPoint *gp, TimeStep *tStep) const
195{
196 auto status = static_cast< StructuralMaterialStatus * >( this->giveStatus(gp) );
197 auto d = this->give1dStressStiffMtrx(TangentStiffness, gp, tStep);
198
199 FloatArray answer;
200 FloatArray strainVector;
201 if ( this->castingTime < 0. ) { // no changes in material stiffness ->> total formulation
202 this->giveStressDependentPartOfStrainVector(strainVector, gp, reducedStrain, tStep, VM_Total);
203 answer.beProductOf(d, strainVector);
204 } else { // changes in material stiffness ->> incremental formulation
205 this->giveStressDependentPartOfStrainVector(strainVector, gp, reducedStrain, tStep, VM_Incremental);
206 auto strainIncrement = strainVector - status->giveStrainVector();
207
208 answer.beProductOf(d, strainIncrement);
209 answer.add( status->giveStressVector() );
210 }
211
212 // update gp
213 status->letTempStrainVectorBe(reducedStrain);
214 status->letTempStressVectorBe(answer);
215 return answer;
216}
217
218
220LinearElasticMaterial :: giveRealStressVector_Warping(const FloatArrayF<2> &reducedStrain, GaussPoint *gp, TimeStep *tStep) const
221{
222 // reducedStrain contains the stress components tau_zy and tau_zx, computed as // tau_zy = G * theta * ( x + dPsi/dy )
223 // tau_zx = G * theta * (-y + dPsi/dx )
224 // where x and y are the global coordinates of the Gauss point (the origin must be at the centroid of the cross section)
225 // G is the shear modulus of elasticity and theta is the relative twist (dPhi_z/dz)
226
228
229 auto status = static_cast< StructuralMaterialStatus * >( this->giveStatus(gp) );
230 double G = this->giveShearModulus();
231 FloatArray gcoords;
232 Element *elem = gp->giveElement();
233 elem->computeGlobalCoordinates( gcoords, gp->giveNaturalCoordinates() );
234 FloatArrayF<2> answer;
235
236 if ( this->castingTime < 0. ) { // no changes in material stiffness ->> total formulation
237 answer.at(1) = reducedStrain.at(1);
238 answer.at(2) = reducedStrain.at(2);
239
240 answer *= G;
241 } else { // changes in material stiffness ->> incremental formulation
242 FloatArray strainIncrement;
243 strainIncrement.beDifferenceOf( reducedStrain, status->giveStrainVector() );
244
245 answer.at(1) = strainIncrement.at(1);
246 answer.at(2) = strainIncrement.at(2);
247 answer *= G;
248
249 if ( ( tStep->giveIntrinsicTime() < this->castingTime ) ) {
250 answer *= (1. - this->preCastStiffnessReduction);
251 }
252
253 answer += FloatArrayF<2>(status->giveStressVector());
254 }
255
256 // update gp
257
258 status->letTempStrainVectorBe(reducedStrain);
259 status->letTempStressVectorBe(answer);
260 return answer;
261}
262
263
265LinearElasticMaterial :: giveRealStressVector_2dBeamLayer(const FloatArrayF<2> &reducedStrain, GaussPoint *gp, TimeStep *tStep) const
266{
267 auto status = static_cast< StructuralMaterialStatus * >( this->giveStatus(gp) );
268
269 auto d = this->give2dBeamLayerStiffMtrx(TangentStiffness, gp, tStep);
270
271 FloatArray answer;
272 FloatArray strainVector, strainIncrement;
273 if ( this->castingTime < 0. ) { // no changes in material stiffness ->> total formulation
274 this->giveStressDependentPartOfStrainVector(strainVector, gp, reducedStrain, tStep, VM_Total);
275 answer.beProductOf(d, strainVector);
276 } else { // changes in material stiffness ->> incremental formulation
277 this->giveStressDependentPartOfStrainVector(strainVector, gp, reducedStrain, tStep, VM_Incremental);
278 strainIncrement.beDifferenceOf( strainVector, status->giveStrainVector() );
279
280 answer.beProductOf(d, strainIncrement);
281 answer.add( status->giveStressVector() );
282 }
283
284 // update gp
285 status->letTempStrainVectorBe(reducedStrain);
286 status->letTempStressVectorBe(answer);
287 return answer;
288}
289
290
292LinearElasticMaterial :: giveRealStressVector_PlateLayer(const FloatArrayF<5> &reducedStrain, GaussPoint *gp, TimeStep *tStep) const
293{
294 auto status = static_cast< StructuralMaterialStatus * >( this->giveStatus(gp) );
295
296 auto d = this->givePlateLayerStiffMtrx(TangentStiffness, gp, tStep);
297
298 FloatArray answer;
299 FloatArray strainVector, strainIncrement;
300 if ( this->castingTime < 0. ) { // no changes in material stiffness ->> total formulation
301 this->giveStressDependentPartOfStrainVector(strainVector, gp, reducedStrain, tStep, VM_Total);
302 answer.beProductOf(d, strainVector);
303 } else { // changes in material stiffness ->> incremental formulation
304 this->giveStressDependentPartOfStrainVector(strainVector, gp, reducedStrain, tStep, VM_Incremental);
305 strainIncrement.beDifferenceOf( strainVector, status->giveStrainVector() );
306
307 answer.beProductOf(d, strainIncrement);
308 answer.add( status->giveStressVector() );
309 }
310
311 // update gp
312 status->letTempStrainVectorBe(reducedStrain);
313 status->letTempStressVectorBe(answer);
314 return answer;
315}
316
317
319LinearElasticMaterial :: giveRealStressVector_Fiber(const FloatArrayF<3> &reducedStrain, GaussPoint *gp, TimeStep *tStep) const
320{
321 auto status = static_cast< StructuralMaterialStatus * >( this->giveStatus(gp) );
322
323 auto d = this->giveFiberStiffMtrx(TangentStiffness, gp, tStep);
324
325 FloatArray answer;
326 FloatArray strainVector;
327 if ( this->castingTime < 0. ) { // no changes in material stiffness ->> total formulation
328 this->giveStressDependentPartOfStrainVector(strainVector, gp, reducedStrain, tStep, VM_Total);
329 answer.beProductOf(d, strainVector);
330 } else { // changes in material stiffness ->> incremental formulation
331 this->giveStressDependentPartOfStrainVector(strainVector, gp, reducedStrain, tStep, VM_Incremental);
332 auto strainIncrement = strainVector - status->giveStrainVector();
333
334 answer.beProductOf(d, strainIncrement);
335 answer.add( status->giveStressVector() );
336 }
337
338 // update gp
339 status->letTempStrainVectorBe(reducedStrain);
340 status->letTempStressVectorBe(answer);
341 return answer;
342}
343
344void
345LinearElasticMaterial :: giveEshelbyStressVector_PlaneStrain(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedF, TimeStep *tStep)
346{
347 FloatArray fullFv;
348 StructuralMaterial :: giveFullVectorFormF(fullFv, reducedF, _PlaneStrain);
349
350 FloatMatrix H;
351 H.beMatrixForm(fullFv);
352
353 H(0, 0) -= 1.0;
354 H(1, 1) -= 1.0;
355 H(2, 2) -= 1.0;
356
357
358 StructuralMaterialStatus *status = static_cast< StructuralMaterialStatus * >( this->giveStatus(gp) );
359 const FloatArray &stressV = status->giveTempStressVector();
360
361 FloatArray fullStressV;
362 StructuralMaterial :: giveFullSymVectorForm(fullStressV, stressV, _PlaneStrain);
363
364 FloatMatrix stress;
365 stress.beMatrixFormOfStress(fullStressV);
366
367
368 double energyDens = giveEnergyDensity(gp, tStep);
369
370
371 FloatMatrix eshelbyStress(3, 3);
372 eshelbyStress.beTProductOf(H, stress);
373 eshelbyStress.negated();
374
375 eshelbyStress(0, 0) += energyDens;
376 eshelbyStress(1, 1) += energyDens;
377 eshelbyStress(2, 2) += energyDens;
378
379
380 FloatArray eshelbyStressV;
381 eshelbyStressV.beVectorForm(eshelbyStress);
382 StructuralMaterial :: giveReducedVectorForm(answer, eshelbyStressV, _PlaneStrain);
383}
384
385double
386LinearElasticMaterial :: giveEnergyDensity(GaussPoint *gp, TimeStep *tStep)
387{
388 StructuralMaterialStatus *status = static_cast< StructuralMaterialStatus * >( this->giveStatus(gp) );
389 const FloatArray &strain = status->giveTempStrainVector();
390 const FloatArray &stress = status->giveTempStressVector();
391
392 return 0.5 * stress.dotProduct(strain);
393}
394
395int
396LinearElasticMaterial :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
397{
398 StructuralMaterialStatus *status = static_cast< StructuralMaterialStatus * >( this->giveStatus(gp) );
399 if ( type == IST_ElasticStrainTensor ) {
400 this->giveStressDependentPartOfStrainVector(answer, gp, status->giveStrainVector(), tStep, VM_Total);
401 return 1;
402 } else if ( type == IST_ThermalStrainTensor ) {
403 answer = this->computeStressIndependentStrainVector_3d(gp, tStep, VM_Total);
404 return 1;
405 } else if ( type == IST_CreepStrainTensor ) {
406 answer.resize(6);
407 answer.zero();
408 return 1;
409 } else if ( type == IST_FreeEnergyDensity ) {
410 answer.resize(1);
411 answer.at(1) = this->giveEnergyDensity(gp,tStep);
412 return 1;
413 } else {
414 return StructuralMaterial :: giveIPValue(answer, gp, type, tStep);
415 }
416}
417
418
419std::unique_ptr<MaterialStatus>
420LinearElasticMaterial :: CreateStatus(GaussPoint *gp) const
421{
422 return std::make_unique<StructuralMaterialStatus>(gp);
423}
424} // end namespace oofem
void setField(int item, InputFieldType id)
virtual int computeGlobalCoordinates(FloatArray &answer, const FloatArray &lcoords)
Definition element.C:1225
double & at(std::size_t i)
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
double dotProduct(const FloatArray &x) const
Definition floatarray.C:524
void beDifferenceOf(const FloatArray &a, const FloatArray &b)
Definition floatarray.C:403
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:689
void beVectorForm(const FloatMatrix &aMatrix)
void add(const FloatArray &src)
Definition floatarray.C:218
void beMatrixFormOfStress(const FloatArray &aArray)
void beMatrixForm(const FloatArray &aArray)
void beTProductOf(const FloatMatrix &a, const FloatMatrix &b)
const FloatArray & giveNaturalCoordinates() const
Returns coordinate array of receiver.
Definition gausspoint.h:138
Element * giveElement()
Returns corresponding element to receiver.
Definition gausspoint.h:187
FloatMatrixF< 4, 4 > tangentPlaneStrain
FloatMatrixF< 3, 3 > tangentPlaneStress
double giveEnergyDensity(GaussPoint *gp, TimeStep *tStep)
virtual double giveShearModulus() const
FloatMatrixF< 6, 6 > tangent
Preconstructed 3d tangent.
FloatMatrixF< 6, 6 > give3dMaterialStiffnessMatrix(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const override
FloatArrayF< 6 > alpha
Thermal expansion.
double preCastStiffnessReduction
artificial isotropic damage to reflect reduction in stiffness for time < castingTime.
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Definition material.C:206
double castingTime
Definition material.h:115
const FloatArray & giveStrainVector() const
Returns the const pointer to receiver's strain vector.
const FloatArray & giveTempStressVector() const
Returns the const pointer to receiver's temporary stress vector.
const FloatArray & giveTempStrainVector() const
Returns the const pointer to receiver's temporary strain vector.
virtual FloatMatrixF< 3, 3 > givePlaneStressStiffMtrx(MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep) const
virtual FloatMatrixF< 5, 5 > givePlateLayerStiffMtrx(MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep) const
void giveStressDependentPartOfStrainVector(FloatArray &answer, GaussPoint *gp, const FloatArray &reducedStrainVector, TimeStep *tStep, ValueModeType mode) const
virtual FloatMatrixF< 1, 1 > give1dStressStiffMtrx(MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep) const
FloatArrayF< 6 > computeStressIndependentStrainVector_3d(GaussPoint *gp, TimeStep *tStep, ValueModeType mode) const
virtual FloatMatrixF< 2, 2 > give2dBeamLayerStiffMtrx(MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep) const
virtual FloatMatrixF< 3, 3 > giveFiberStiffMtrx(MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep) const
double giveIntrinsicTime()
Returns intrinsic time, e.g. time in which constitutive model is evaluated.
Definition timestep.h:166
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Definition inputrecord.h:75
#define _IFT_LinearElasticMaterial_preCastStiffRed
double dot(const FloatArray &x, const FloatArray &y)
FloatMatrixF< N, N > inv(const FloatMatrixF< N, N > &mat, double zeropiv=1e-24)
Computes the inverse.

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