OOFEM 3.0
Loading...
Searching...
No Matches
isointerfacedamage02.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 <algorithm>
36
38#include "gausspoint.h"
39#include "floatmatrix.h"
40#include "floatarray.h"
41#include "mathfem.h"
42#include "datastream.h"
43#include "contextioerr.h"
44#include "classfactory.h"
45#include "dynamicinputrecord.h"
46
47namespace oofem {
49
50IsoInterfaceDamageMaterial_2 :: IsoInterfaceDamageMaterial_2(int n, Domain *d) : StructuralInterfaceMaterial(n, d)
51{}
52
53
55IsoInterfaceDamageMaterial_2 :: giveEngTraction_3d(const FloatArrayF<3> &jump, GaussPoint *gp, TimeStep *tStep) const
56{
58
59 // compute equivalent strain
60 double equivStrain = macbra( jump.at(1) );
61
62 // compute value of loading function if strainLevel crit apply
63 double f = equivStrain - status->giveKappa();
64
65 double tempKappa = 0.0, omega = 0.0;
66 if ( f <= 0.0 ) {
67 // damage do not grow
68 tempKappa = status->giveKappa();
69 omega = status->giveDamage();
70 } else {
71 // damage grows
72 tempKappa = equivStrain;
73 // evaluate damage parameter
74 omega = this->computeDamageParam(tempKappa, jump, gp);
75 }
76
77 auto de = this->give3dStiffnessMatrix_Eng(ElasticStiffness, gp, tStep);
78 auto answer = dot(de, jump);
79 // damage in tension only
80 if ( equivStrain >= 0.0 ) {
81 answer *= 1.0 - omega;
82 }
83
84 // update gp
85 status->letTempJumpBe(jump);
86 status->letTempTractionBe(answer);
87 status->setTempKappa(tempKappa);
88 status->setTempDamage(omega);
89
90 return answer;
91}
92
93
95IsoInterfaceDamageMaterial_2 :: give3dStiffnessMatrix_Eng(MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) const
96{
98
99 // assemble eleastic stiffness
100 auto answer = diag<3>({kn, ks, ks});
101
102 if ( rMode == ElasticStiffness ) {
103 return answer;
104 }
105
106 double om = min(status->giveTempDamage(), maxOmega);
107 double un = status->giveTempJump().at(1);
108 if ( rMode == SecantStiffness ) {
109 // damage in tension only
110 if ( un >= 0 ) {
111 answer *= 1.0 - om;
112 }
113
114 return answer;
115 } else { // Tangent Stiffness
116 // damage in tension only
117 if ( un >= 0 ) {
118 answer *= 1.0 - om;
119#if 0
120 // Unreachable code - commented out to supress compiler warnings
121 double dom = -( -e0 / un / un * exp( -( ft / gf ) * ( un - e0 ) ) + e0 / un * exp( -( ft / gf ) * ( un - e0 ) ) * ( -( ft / gf ) ) );
122 if ( ( om > 0. ) && ( status->giveTempKappa() > status->giveKappa() ) ) {
123 const auto &e = status->giveTempJump();
124 auto se = dot(answer, e);
125 answer.at(1, 1) -= se.at(1) * dom;
126 answer.at(2, 1) -= se.at(2) * dom;
127 }
128#endif
129 }
130 return answer;
131 }
132}
133
134
135int
136IsoInterfaceDamageMaterial_2 :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
137{
139 if ( type == IST_DamageTensor ) {
140 answer.resize(6);
141 answer.zero();
142 answer.at(1) = answer.at(2) = answer.at(3) = status->giveDamage();
143 return 1;
144 } else if ( type == IST_DamageTensorTemp ) {
145 answer.resize(6);
146 answer.zero();
147 answer.at(1) = answer.at(2) = answer.at(3) = status->giveTempDamage();
148 return 1;
149 } else if ( type == IST_PrincipalDamageTensor ) {
150 answer.resize(3);
151 answer.at(1) = answer.at(2) = answer.at(3) = status->giveDamage();
152 return 1;
153 } else if ( type == IST_PrincipalDamageTempTensor ) {
154 answer.resize(3);
155 answer.at(1) = answer.at(2) = answer.at(3) = status->giveTempDamage();
156 return 1;
157 } else if ( type == IST_MaxEquivalentStrainLevel ) {
158 answer.resize(1);
159 answer.at(1) = status->giveKappa();
160 return 1;
161 } else {
162 return StructuralInterfaceMaterial :: giveIPValue(answer, gp, type, tStep);
163 }
164}
165
166
167void
168IsoInterfaceDamageMaterial_2 :: initializeFrom(InputRecord &ir)
169{
170 StructuralInterfaceMaterial :: initializeFrom(ir);
171
172 std :: ifstream is;
173 int nbrOfLinesToRead;
174
178
179 this->e0 = ft / kn;
180
181 //Set limit on the maximum isotropic damage parameter if needed
183 maxOmega = min(maxOmega, 0.999999);
184 maxOmega = max(maxOmega, 0.0);
185
186 // Parse the table file
188
189 is.open(tablename.c_str(), std :: ifstream :: in);
190 if ( !is.is_open() ) {
191 OOFEM_ERROR("Can't open table file %s.", tablename.c_str() );
192 }
193
194 // Read first line
195 if ( is >> nbrOfLinesToRead ) {
196 printf("NumberofLinestoRead: %d\n", nbrOfLinesToRead);
197 } else {
198 OOFEM_ERROR("Error reading table file, first line should be "
199 "an integer stating how many strain damage pairs that exist in the file.");
200 }
201
202 damages.resize(nbrOfLinesToRead + 1);
203 strains.resize(nbrOfLinesToRead + 1);
204
205 // Insert a (0,0) pair
206 strains(0) = damages(0) = 0.0;
207
208 for ( int i = 0; i < nbrOfLinesToRead; i++ ) {
209 if ( !( is >> strains(i + 1) >> damages(i + 1) ) ) {
210 OOFEM_ERROR("Error reading table file at line %d, expected a "
211 "strain damage pair.", i + 2);
212 }
213
214 if ( ( damages(i + 1) < damages(i) ) || ( strains(i + 1) < strains(i) ) ) {
215 OOFEM_ERROR("Error reading table file at line %d, strain "
216 "and damage must be given in an increasing order and be positive.", i + 2);
217 }
218 }
219
220 // We add e0 to the strains since strains should be given as the increase in
221 // strain relative to e0.
222 strains.add(e0);
223}
224
225
226void
227IsoInterfaceDamageMaterial_2 :: giveInputRecord(DynamicInputRecord &input)
228{
229 StructuralInterfaceMaterial :: giveInputRecord(input);
230
236}
237
238
239double
240IsoInterfaceDamageMaterial_2 :: computeEquivalentStrain(const FloatArrayF<3> &strain, GaussPoint *gp, TimeStep *tStep) const
241{
242 return macbra( strain.at(1) );
243}
244
245double
246IsoInterfaceDamageMaterial_2 :: computeDamageParam(double kappa, const FloatArrayF<3> &strain, GaussPoint *gp) const
247{
248 if ( kappa > this->e0 ) {
249 // Linear interpolation between table values.
250
251 // If out of bounds damage is set to the last given damage value in the table
252 if ( kappa >= strains.at( strains.giveSize() ) ) {
253 return damages.at( damages.giveSize() );
254 } else {
255 // std::lower_bound uses binary search to find index with value bounding kappa from above
256 int index = (int)(std :: lower_bound(strains.givePointer(), strains.givePointer() + strains.giveSize(), kappa) - strains.givePointer());
257
258#if 0
259 printf("e0 %lf\n", e0);
260 printf( "sizeof %d\n", sizeof( strains.givePointer() ) );
261 printf("pointer: %d\n", index);
262 printf("value: %lf\n", * index);
263 printf( "Index found: %d\n", index - strains.givePointer() );
264 printf( "First index: %d\n", strains.givePointer() );
265 printf( "Last index: %d\n", strains.givePointer() + strains.giveSize() );
266#endif
267
268 // Pointer arithmetic to find the values used in interpolation
269 double x0 = strains(index - 1);
270 double x1 = strains(index );
271 double y0 = damages(index - 1);
272 double y1 = damages(index );
273
274 // Interpolation formula
275 return y0 + ( y1 - y0 ) * ( kappa - x0 ) / ( x1 - x0 );
276 }
277 } else {
278 return 0.0;
279 }
280}
281
282
283IsoInterfaceDamageMaterialStatus_2 :: IsoInterfaceDamageMaterialStatus_2(GaussPoint *g) :
285{
286 kappa = tempKappa = 0.0;
287 damage = tempDamage = 0.0;
288}
289
290
291void
292IsoInterfaceDamageMaterialStatus_2 :: printOutputAt(FILE *file, TimeStep *tStep) const
293{
294 StructuralInterfaceMaterialStatus :: printOutputAt(file, tStep);
295 fprintf(file, "status { ");
296 if ( this->damage > 0.0 ) {
297 fprintf(file, "kappa %f, damage %f ", this->kappa, this->damage);
298 }
299
300 fprintf(file, "}\n");
301}
302
303
304void
305IsoInterfaceDamageMaterialStatus_2 :: initTempStatus()
306{
307 StructuralInterfaceMaterialStatus :: initTempStatus();
308 this->tempKappa = this->kappa;
309 this->tempDamage = this->damage;
310}
311
312void
313IsoInterfaceDamageMaterialStatus_2 :: updateYourself(TimeStep *tStep)
314{
315 StructuralInterfaceMaterialStatus :: updateYourself(tStep);
316 this->kappa = this->tempKappa;
317 this->damage = this->tempDamage;
318}
319
320
321void
322IsoInterfaceDamageMaterialStatus_2 :: saveContext(DataStream &stream, ContextMode mode)
323{
324 StructuralInterfaceMaterialStatus :: saveContext(stream, mode);
325
326 if ( !stream.write(kappa) ) {
328 }
329
330 if ( !stream.write(damage) ) {
332 }
333}
334
335void
336IsoInterfaceDamageMaterialStatus_2 :: restoreContext(DataStream &stream, ContextMode mode)
337{
338 StructuralInterfaceMaterialStatus :: restoreContext(stream, mode);
339
340 if ( !stream.read(kappa) ) {
342 }
343
344 if ( !stream.read(damage) ) {
346 }
347}
348} // end namespace oofem
#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.
void setField(int item, InputFieldType id)
double & at(std::size_t i)
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
double kappa
Scalar measure of the largest equivalent displacement ever reached in material.
double giveTempKappa() const
Returns the temp. scalar measure of the largest strain level.
double tempDamage
Non-equilibrated damage level of material.
double tempKappa
Non-equilibrated scalar measure of the largest equivalent displacement.
void setTempKappa(double newKappa)
Sets the temp scalar measure of the largest strain level to given value.
double giveTempDamage() const override
Returns the temp. damage level.
double giveKappa() const
Returns the last equilibrated scalar measure of the largest strain level.
double giveDamage() const override
Returns the last equilibrated damage level.
void setTempDamage(double newDamage)
Sets the temp damage level to given value.
FloatArray damages
Damages read from the second column in the table file.
double e0
Limit elastic deformation.
double maxOmega
Maximum limit on omega. The purpose is elimination of a too compliant material which may cause conver...
virtual double computeDamageParam(double kappa, const FloatArrayF< 3 > &strain, GaussPoint *gp) const
FloatArray strains
Strains read from the first column in the table file.
FloatMatrixF< 3, 3 > give3dStiffnessMatrix_Eng(MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) const override
std::string tablename
Name of table file.
double kn
Elastic properties (normal moduli).
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Definition material.C:206
StructuralInterfaceMaterialStatus(GaussPoint *g)
Constructor. Creates new StructuralInterfaceMaterialStatus with number n, belonging to domain d and I...
const FloatArrayF< 3 > & giveTempJump() const
Returns the const pointer to receiver's temporary jump.
void letTempTractionBe(const FloatArrayF< 3 > v)
Assigns tempTraction to given vector v.
void letTempJumpBe(const FloatArrayF< 3 > v)
Assigns tempJump to given vector v.
#define THROW_CIOERR(e)
#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_IsoInterfaceDamageMaterial_2_ft
#define _IFT_IsoInterfaceDamageMaterial_2_maxOmega
#define _IFT_IsoInterfaceDamageMaterial_2_ks
#define _IFT_IsoInterfaceDamageMaterial_2_kn
#define _IFT_IsoInterfaceDamageMaterial_2_tablename
long ContextMode
Definition contextmode.h:43
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
double macbra(double x)
Returns the positive part of given float.
Definition mathfem.h:128
FloatArrayF< N > max(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
FloatMatrixF< N, N > diag(const FloatArrayF< N > &v)
double dot(const FloatArray &x, const FloatArray &y)
@ 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