structuralcodes 0.5.0__py3-none-any.whl → 0.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of structuralcodes might be problematic. Click here for more details.
- structuralcodes/__init__.py +1 -1
- structuralcodes/codes/mc2010/_concrete_creep_and_shrinkage.py +2 -2
- structuralcodes/core/base.py +115 -4
- structuralcodes/geometry/__init__.py +2 -8
- structuralcodes/geometry/_geometry.py +11 -22
- structuralcodes/geometry/_reinforcement.py +1 -3
- structuralcodes/geometry/profiles/__init__.py +19 -0
- structuralcodes/geometry/profiles/_base_profile.py +305 -0
- structuralcodes/geometry/profiles/_common_functions.py +194 -0
- structuralcodes/geometry/profiles/_he.py +192 -0
- structuralcodes/geometry/profiles/_ipe.py +130 -0
- structuralcodes/geometry/profiles/_ipn.py +329 -0
- structuralcodes/geometry/profiles/_ub.py +264 -0
- structuralcodes/geometry/profiles/_ubp.py +227 -0
- structuralcodes/geometry/profiles/_uc.py +276 -0
- structuralcodes/geometry/profiles/_upn.py +315 -0
- structuralcodes/materials/basic/_elastic.py +18 -1
- structuralcodes/materials/basic/_elasticplastic.py +18 -1
- structuralcodes/materials/basic/_generic.py +18 -1
- structuralcodes/materials/concrete/__init__.py +3 -0
- structuralcodes/materials/concrete/_concrete.py +10 -1
- structuralcodes/materials/concrete/_concreteEC2_2004.py +14 -0
- structuralcodes/materials/concrete/_concreteEC2_2023.py +14 -0
- structuralcodes/materials/concrete/_concreteMC2010.py +19 -0
- structuralcodes/materials/constitutive_laws/__init__.py +3 -0
- structuralcodes/materials/constitutive_laws/_elasticplastic.py +2 -2
- structuralcodes/materials/constitutive_laws/_initial_strain.py +130 -0
- structuralcodes/materials/reinforcement/__init__.py +6 -0
- structuralcodes/materials/reinforcement/_reinforcement.py +10 -1
- structuralcodes/materials/reinforcement/_reinforcementEC2_2004.py +14 -0
- structuralcodes/materials/reinforcement/_reinforcementEC2_2023.py +14 -0
- structuralcodes/materials/reinforcement/_reinforcementMC2010.py +14 -0
- structuralcodes/sections/section_integrators/__init__.py +3 -1
- structuralcodes/sections/section_integrators/_marin_integrator.py +1 -1
- {structuralcodes-0.5.0.dist-info → structuralcodes-0.6.0.dist-info}/METADATA +2 -2
- {structuralcodes-0.5.0.dist-info → structuralcodes-0.6.0.dist-info}/RECORD +39 -29
- structuralcodes/geometry/_steel_sections.py +0 -2155
- /structuralcodes/{sections/section_integrators → core}/_marin_integration.py +0 -0
- {structuralcodes-0.5.0.dist-info → structuralcodes-0.6.0.dist-info}/WHEEL +0 -0
- {structuralcodes-0.5.0.dist-info → structuralcodes-0.6.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
"""UPN profiles."""
|
|
2
|
+
|
|
3
|
+
from shapely import (
|
|
4
|
+
Polygon,
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
from ._base_profile import BaseProfile
|
|
8
|
+
from ._common_functions import (
|
|
9
|
+
_create_taper_U_section,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class UPN(BaseProfile):
|
|
14
|
+
"""Simple class for representing an UPN profile.
|
|
15
|
+
|
|
16
|
+
European standard channels UPN 50 - 400.
|
|
17
|
+
|
|
18
|
+
Taper flange Channels.
|
|
19
|
+
|
|
20
|
+
14% slope in flange.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
parameters = {
|
|
24
|
+
'UPN50': {
|
|
25
|
+
'h': 50.0,
|
|
26
|
+
'b': 38.0,
|
|
27
|
+
'tw': 5.0,
|
|
28
|
+
'tf': 7.0,
|
|
29
|
+
'r1': 7.0,
|
|
30
|
+
'r2': 4.0,
|
|
31
|
+
'd': 21.0,
|
|
32
|
+
},
|
|
33
|
+
'UPN65': {
|
|
34
|
+
'h': 65.0,
|
|
35
|
+
'b': 42.0,
|
|
36
|
+
'tw': 5.5,
|
|
37
|
+
'tf': 7.5,
|
|
38
|
+
'r1': 8.0,
|
|
39
|
+
'r2': 4.0,
|
|
40
|
+
'd': 34.0,
|
|
41
|
+
},
|
|
42
|
+
'UPN80': {
|
|
43
|
+
'h': 80.0,
|
|
44
|
+
'b': 45.0,
|
|
45
|
+
'tw': 6.0,
|
|
46
|
+
'tf': 8.0,
|
|
47
|
+
'r1': 8.0,
|
|
48
|
+
'r2': 4.0,
|
|
49
|
+
'd': 47.0,
|
|
50
|
+
},
|
|
51
|
+
'UPN100': {
|
|
52
|
+
'h': 100.0,
|
|
53
|
+
'b': 50.0,
|
|
54
|
+
'tw': 6.0,
|
|
55
|
+
'tf': 8.5,
|
|
56
|
+
'r1': 9.0,
|
|
57
|
+
'r2': 5.0,
|
|
58
|
+
'd': 64.0,
|
|
59
|
+
},
|
|
60
|
+
'UPN120': {
|
|
61
|
+
'h': 120.0,
|
|
62
|
+
'b': 55.0,
|
|
63
|
+
'tw': 7.0,
|
|
64
|
+
'tf': 9.0,
|
|
65
|
+
'r1': 9.0,
|
|
66
|
+
'r2': 5.0,
|
|
67
|
+
'd': 82.0,
|
|
68
|
+
},
|
|
69
|
+
'UPN140': {
|
|
70
|
+
'h': 140.0,
|
|
71
|
+
'b': 60.0,
|
|
72
|
+
'tw': 7.0,
|
|
73
|
+
'tf': 10.0,
|
|
74
|
+
'r1': 10.0,
|
|
75
|
+
'r2': 5.0,
|
|
76
|
+
'd': 98.0,
|
|
77
|
+
},
|
|
78
|
+
'UPN160': {
|
|
79
|
+
'h': 160.0,
|
|
80
|
+
'b': 65.0,
|
|
81
|
+
'tw': 7.5,
|
|
82
|
+
'tf': 10.5,
|
|
83
|
+
'r1': 11.0,
|
|
84
|
+
'r2': 6.0,
|
|
85
|
+
'd': 115.0,
|
|
86
|
+
},
|
|
87
|
+
'UPN180': {
|
|
88
|
+
'h': 180.0,
|
|
89
|
+
'b': 70.0,
|
|
90
|
+
'tw': 8.0,
|
|
91
|
+
'tf': 11.0,
|
|
92
|
+
'r1': 11.0,
|
|
93
|
+
'r2': 6.0,
|
|
94
|
+
'd': 133.0,
|
|
95
|
+
},
|
|
96
|
+
'UPN200': {
|
|
97
|
+
'h': 200.0,
|
|
98
|
+
'b': 75.0,
|
|
99
|
+
'tw': 8.5,
|
|
100
|
+
'tf': 11.5,
|
|
101
|
+
'r1': 12.0,
|
|
102
|
+
'r2': 6.0,
|
|
103
|
+
'd': 151.0,
|
|
104
|
+
},
|
|
105
|
+
'UPN220': {
|
|
106
|
+
'h': 220.0,
|
|
107
|
+
'b': 80.0,
|
|
108
|
+
'tw': 9.0,
|
|
109
|
+
'tf': 12.5,
|
|
110
|
+
'r1': 13.0,
|
|
111
|
+
'r2': 7.0,
|
|
112
|
+
'd': 167.0,
|
|
113
|
+
},
|
|
114
|
+
'UPN240': {
|
|
115
|
+
'h': 240.0,
|
|
116
|
+
'b': 85.0,
|
|
117
|
+
'tw': 9.5,
|
|
118
|
+
'tf': 13.0,
|
|
119
|
+
'r1': 13.0,
|
|
120
|
+
'r2': 7.0,
|
|
121
|
+
'd': 184.0,
|
|
122
|
+
},
|
|
123
|
+
'UPN260': {
|
|
124
|
+
'h': 260.0,
|
|
125
|
+
'b': 90.0,
|
|
126
|
+
'tw': 10.0,
|
|
127
|
+
'tf': 14.0,
|
|
128
|
+
'r1': 14.0,
|
|
129
|
+
'r2': 7.0,
|
|
130
|
+
'd': 200.0,
|
|
131
|
+
},
|
|
132
|
+
'UPN280': {
|
|
133
|
+
'h': 280.0,
|
|
134
|
+
'b': 95.0,
|
|
135
|
+
'tw': 10.0,
|
|
136
|
+
'tf': 15.0,
|
|
137
|
+
'r1': 15.0,
|
|
138
|
+
'r2': 8.0,
|
|
139
|
+
'd': 216.0,
|
|
140
|
+
},
|
|
141
|
+
'UPN300': {
|
|
142
|
+
'h': 300.0,
|
|
143
|
+
'b': 100.0,
|
|
144
|
+
'tw': 10.0,
|
|
145
|
+
'tf': 16.0,
|
|
146
|
+
'r1': 16.0,
|
|
147
|
+
'r2': 8.0,
|
|
148
|
+
'd': 232.0,
|
|
149
|
+
},
|
|
150
|
+
'UPN320': {
|
|
151
|
+
'h': 320.0,
|
|
152
|
+
'b': 100.0,
|
|
153
|
+
'tw': 14.0,
|
|
154
|
+
'tf': 17.5,
|
|
155
|
+
'r1': 18.0,
|
|
156
|
+
'r2': 9.0,
|
|
157
|
+
'd': 246.0,
|
|
158
|
+
},
|
|
159
|
+
'UPN350': {
|
|
160
|
+
'h': 350.0,
|
|
161
|
+
'b': 100.0,
|
|
162
|
+
'tw': 14.0,
|
|
163
|
+
'tf': 16.0,
|
|
164
|
+
'r1': 16.0,
|
|
165
|
+
'r2': 8.0,
|
|
166
|
+
'd': 282.0,
|
|
167
|
+
},
|
|
168
|
+
'UPN380': {
|
|
169
|
+
'h': 380.0,
|
|
170
|
+
'b': 102.0,
|
|
171
|
+
'tw': 13.5,
|
|
172
|
+
'tf': 16.0,
|
|
173
|
+
'r1': 16.0,
|
|
174
|
+
'r2': 8.0,
|
|
175
|
+
'd': 313.0,
|
|
176
|
+
},
|
|
177
|
+
'UPN400': {
|
|
178
|
+
'h': 400.0,
|
|
179
|
+
'b': 110.0,
|
|
180
|
+
'tw': 14.0,
|
|
181
|
+
'tf': 18.0,
|
|
182
|
+
'r1': 18.0,
|
|
183
|
+
'r2': 9.0,
|
|
184
|
+
'd': 324.0,
|
|
185
|
+
},
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
@classmethod
|
|
189
|
+
def get_polygon(cls, name: str) -> Polygon:
|
|
190
|
+
"""Returns a shapely polygon representing an UPN section."""
|
|
191
|
+
if isinstance(name, (float, int)):
|
|
192
|
+
name = f'UPN{int(name):0d}'
|
|
193
|
+
parameters = cls.parameters.get(name)
|
|
194
|
+
if parameters is None:
|
|
195
|
+
raise ValueError(
|
|
196
|
+
f"Profile '{name}' not found in UPN sections. "
|
|
197
|
+
"Select a valid profile (available ones: "
|
|
198
|
+
f"{cls.profiles()})"
|
|
199
|
+
)
|
|
200
|
+
if parameters['h'] <= 300:
|
|
201
|
+
parameters['slope'] = 0.08
|
|
202
|
+
parameters['u'] = parameters['b'] / 2.0
|
|
203
|
+
else:
|
|
204
|
+
parameters['slope'] = 0.05
|
|
205
|
+
parameters['u'] = (parameters['b'] - parameters['tw']) / 2.0
|
|
206
|
+
return _create_taper_U_section(
|
|
207
|
+
**{
|
|
208
|
+
key: parameters[key]
|
|
209
|
+
for key in parameters
|
|
210
|
+
if key in ['h', 'b', 'tw', 'tf', 'r1', 'r2', 'slope', 'u']
|
|
211
|
+
}
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
@classmethod
|
|
215
|
+
def profiles(cls) -> list:
|
|
216
|
+
"""Returns a list containing all available profiles."""
|
|
217
|
+
return list(cls.parameters.keys())
|
|
218
|
+
|
|
219
|
+
def __init__(self, name: str) -> None:
|
|
220
|
+
"""Creates a new UPN object."""
|
|
221
|
+
if isinstance(name, (float, int)):
|
|
222
|
+
name = f'UPN{int(name):0d}'
|
|
223
|
+
parameters = self.parameters.get(name)
|
|
224
|
+
if parameters is None:
|
|
225
|
+
raise ValueError(
|
|
226
|
+
f"Profile '{name}' not found in UPN sections. "
|
|
227
|
+
"Select a valid profile (available ones: "
|
|
228
|
+
f"{self.profiles()})"
|
|
229
|
+
)
|
|
230
|
+
super().__init__()
|
|
231
|
+
self._h = parameters.get('h')
|
|
232
|
+
self._b = parameters.get('b')
|
|
233
|
+
self._tw = parameters.get('tw')
|
|
234
|
+
self._tf = parameters.get('tf')
|
|
235
|
+
self._r1 = parameters.get('r1')
|
|
236
|
+
self._r2 = parameters.get('r2')
|
|
237
|
+
if self._h <= 300:
|
|
238
|
+
self._flange_slope = 0.08
|
|
239
|
+
self._u = self._b / 2.0
|
|
240
|
+
else:
|
|
241
|
+
self._flange_slope = 0.05
|
|
242
|
+
self._u = (self._b - self._tw) / 2.0
|
|
243
|
+
self._polygon = _create_taper_U_section(
|
|
244
|
+
h=self._h,
|
|
245
|
+
b=self._b,
|
|
246
|
+
tw=self._tw,
|
|
247
|
+
tf=self._tf,
|
|
248
|
+
r1=self._r1,
|
|
249
|
+
r2=self._r2,
|
|
250
|
+
slope=self._flange_slope,
|
|
251
|
+
u=self._u,
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
@property
|
|
255
|
+
def polygon(self) -> Polygon:
|
|
256
|
+
"""Returns shapely Polygon of section.
|
|
257
|
+
|
|
258
|
+
Returns:
|
|
259
|
+
Polygon: The represention of the UPN section.
|
|
260
|
+
"""
|
|
261
|
+
return self._polygon
|
|
262
|
+
|
|
263
|
+
@property
|
|
264
|
+
def h(self) -> float:
|
|
265
|
+
"""Returns height of UPN section.
|
|
266
|
+
|
|
267
|
+
Returns:
|
|
268
|
+
float: Height h of UPN section.
|
|
269
|
+
"""
|
|
270
|
+
return self._h
|
|
271
|
+
|
|
272
|
+
@property
|
|
273
|
+
def b(self) -> float:
|
|
274
|
+
"""Returns width of UPN section.
|
|
275
|
+
|
|
276
|
+
Returns:
|
|
277
|
+
float: Width b of UPN section.
|
|
278
|
+
"""
|
|
279
|
+
return self._b
|
|
280
|
+
|
|
281
|
+
@property
|
|
282
|
+
def tw(self) -> float:
|
|
283
|
+
"""Returns thickness of web of UPN section.
|
|
284
|
+
|
|
285
|
+
Returns:
|
|
286
|
+
float: Web thickness tw of UPN section.
|
|
287
|
+
"""
|
|
288
|
+
return self._tw
|
|
289
|
+
|
|
290
|
+
@property
|
|
291
|
+
def tf(self) -> float:
|
|
292
|
+
"""Returns thickness of flange of UPN section.
|
|
293
|
+
|
|
294
|
+
Returns:
|
|
295
|
+
float: Flange thickness tw of UPN section.
|
|
296
|
+
"""
|
|
297
|
+
return self._tf
|
|
298
|
+
|
|
299
|
+
@property
|
|
300
|
+
def r1(self) -> float:
|
|
301
|
+
"""Returns fillet radius of UPN section.
|
|
302
|
+
|
|
303
|
+
Returns:
|
|
304
|
+
float: Fillet radius r1 of UPN section.
|
|
305
|
+
"""
|
|
306
|
+
return self._r1
|
|
307
|
+
|
|
308
|
+
@property
|
|
309
|
+
def r2(self) -> float:
|
|
310
|
+
"""Returns fillet radius of UPN section.
|
|
311
|
+
|
|
312
|
+
Returns:
|
|
313
|
+
float: Fillet radius r2 of UPN section.
|
|
314
|
+
"""
|
|
315
|
+
return self._r2
|
|
@@ -15,6 +15,9 @@ class ElasticMaterial(Material):
|
|
|
15
15
|
self,
|
|
16
16
|
E: float,
|
|
17
17
|
density: float,
|
|
18
|
+
initial_strain: t.Optional[float] = None,
|
|
19
|
+
initial_stress: t.Optional[float] = None,
|
|
20
|
+
strain_compatibility: t.Optional[float] = None,
|
|
18
21
|
name: t.Optional[str] = None,
|
|
19
22
|
):
|
|
20
23
|
"""Initialize a material with an elastic plastic constitutive law.
|
|
@@ -22,11 +25,25 @@ class ElasticMaterial(Material):
|
|
|
22
25
|
Arguments:
|
|
23
26
|
E (float): The Young's modulus.
|
|
24
27
|
density (float): The density.
|
|
28
|
+
initial_strain (Optional[float]): Initial strain of the material.
|
|
29
|
+
initial_stress (Optional[float]): Initial stress of the material.
|
|
30
|
+
strain_compatibility (Optional[bool]): Only relevant if
|
|
31
|
+
initial_strain or initial_stress are different from zero. If
|
|
32
|
+
True, the material deforms with the geometry. If False, the
|
|
33
|
+
stress in the material upon loading is kept constant
|
|
34
|
+
corresponding to the initial strain.
|
|
25
35
|
name (str, optional): The name of the material, default value None.
|
|
26
36
|
"""
|
|
27
|
-
super().__init__(
|
|
37
|
+
super().__init__(
|
|
38
|
+
density=density,
|
|
39
|
+
initial_strain=initial_strain,
|
|
40
|
+
initial_stress=initial_stress,
|
|
41
|
+
strain_compatibility=strain_compatibility,
|
|
42
|
+
name=name if name else 'ElasticMaterial',
|
|
43
|
+
)
|
|
28
44
|
self._E = E
|
|
29
45
|
self._constitutive_law = create_constitutive_law('elastic', self)
|
|
46
|
+
self._apply_initial_strain()
|
|
30
47
|
|
|
31
48
|
@property
|
|
32
49
|
def E(self) -> float:
|
|
@@ -21,6 +21,9 @@ class ElasticPlasticMaterial(Material):
|
|
|
21
21
|
density: float,
|
|
22
22
|
Eh: float = 0,
|
|
23
23
|
eps_su: t.Optional[float] = None,
|
|
24
|
+
initial_strain: t.Optional[float] = None,
|
|
25
|
+
initial_stress: t.Optional[float] = None,
|
|
26
|
+
strain_compatibility: t.Optional[float] = None,
|
|
24
27
|
name: t.Optional[str] = None,
|
|
25
28
|
):
|
|
26
29
|
"""Initialize a material with an elastic plastic constitutive law.
|
|
@@ -31,9 +34,22 @@ class ElasticPlasticMaterial(Material):
|
|
|
31
34
|
density (float): The density.
|
|
32
35
|
Eh (float, optional): The hardening modulus, default value 0.
|
|
33
36
|
eps_su (float, optional): The ultimate strain, default value None.
|
|
37
|
+
initial_strain (Optional[float]): Initial strain of the material.
|
|
38
|
+
initial_stress (Optional[float]): Initial stress of the material.
|
|
39
|
+
strain_compatibility (Optional[bool]): Only relevant if
|
|
40
|
+
initial_strain or initial_stress are different from zero. If
|
|
41
|
+
True, the material deforms with the geometry. If False, the
|
|
42
|
+
stress in the material upon loading is kept constant
|
|
43
|
+
corresponding to the initial strain.
|
|
34
44
|
name (str, optional): The name of the material, default value None.
|
|
35
45
|
"""
|
|
36
|
-
super().__init__(
|
|
46
|
+
super().__init__(
|
|
47
|
+
density=density,
|
|
48
|
+
initial_strain=initial_strain,
|
|
49
|
+
initial_stress=initial_stress,
|
|
50
|
+
strain_compatibility=strain_compatibility,
|
|
51
|
+
name=name if name else 'ElasticPlasticMaterial',
|
|
52
|
+
)
|
|
37
53
|
self._E = E
|
|
38
54
|
self._fy = fy
|
|
39
55
|
self._Eh = Eh
|
|
@@ -42,6 +58,7 @@ class ElasticPlasticMaterial(Material):
|
|
|
42
58
|
self._constitutive_law = create_constitutive_law(
|
|
43
59
|
'elasticplastic', self
|
|
44
60
|
)
|
|
61
|
+
self._apply_initial_strain()
|
|
45
62
|
|
|
46
63
|
@property
|
|
47
64
|
def E(self) -> float:
|
|
@@ -12,6 +12,9 @@ class GenericMaterial(Material):
|
|
|
12
12
|
self,
|
|
13
13
|
density: float,
|
|
14
14
|
constitutive_law: ConstitutiveLaw,
|
|
15
|
+
initial_strain: t.Optional[float] = None,
|
|
16
|
+
initial_stress: t.Optional[float] = None,
|
|
17
|
+
strain_compatibility: t.Optional[bool] = None,
|
|
15
18
|
name: t.Optional[str] = None,
|
|
16
19
|
):
|
|
17
20
|
"""Initialize a material with a constitutive law.
|
|
@@ -20,7 +23,21 @@ class GenericMaterial(Material):
|
|
|
20
23
|
density (float): The density.
|
|
21
24
|
constitutive_law (ConstitutiveLaw): The constitutive law of the
|
|
22
25
|
material.
|
|
26
|
+
initial_strain (Optional[float]): Initial strain of the material.
|
|
27
|
+
initial_stress (Optional[float]): Initial stress of the material.
|
|
28
|
+
strain_compatibility (Optional[bool]): Only relevant if
|
|
29
|
+
initial_strain or initial_stress are different from zero. If
|
|
30
|
+
True, the material deforms with the geometry. If False, the
|
|
31
|
+
stress in the material upon loading is kept constant
|
|
32
|
+
corresponding to the initial strain.
|
|
23
33
|
name (str, optional): The name of the material, default value None.
|
|
24
34
|
"""
|
|
25
|
-
super().__init__(
|
|
35
|
+
super().__init__(
|
|
36
|
+
density=density,
|
|
37
|
+
initial_strain=initial_strain,
|
|
38
|
+
initial_stress=initial_stress,
|
|
39
|
+
strain_compatibility=strain_compatibility,
|
|
40
|
+
name=name if name else 'GenericMaterial',
|
|
41
|
+
)
|
|
26
42
|
self._constitutive_law = constitutive_law
|
|
43
|
+
self._apply_initial_strain()
|
|
@@ -49,6 +49,9 @@ def create_concrete(
|
|
|
49
49
|
desired standard. If None (default) the globally used design
|
|
50
50
|
standard will be adopted. Otherwise the design standard specified
|
|
51
51
|
will be used for the instance of the material.
|
|
52
|
+
**kwargs: Other valid keyword arguments that are collected and passed
|
|
53
|
+
to the specific concrete material. Please inspect the documentation
|
|
54
|
+
of the other concrete materials to see valid arguments.
|
|
52
55
|
|
|
53
56
|
Raises:
|
|
54
57
|
ValueError: if the design code is not valid or does not cover concrete
|
|
@@ -21,10 +21,19 @@ class Concrete(Material):
|
|
|
21
21
|
density: float = 2400,
|
|
22
22
|
gamma_c: t.Optional[float] = None,
|
|
23
23
|
existing: t.Optional[bool] = False,
|
|
24
|
+
initial_strain: t.Optional[float] = None,
|
|
25
|
+
initial_stress: t.Optional[float] = None,
|
|
26
|
+
strain_compatibility: t.Optional[bool] = None,
|
|
24
27
|
) -> None:
|
|
25
28
|
"""Initializes an abstract concrete material."""
|
|
26
29
|
name = name if name is not None else 'Concrete'
|
|
27
|
-
super().__init__(
|
|
30
|
+
super().__init__(
|
|
31
|
+
density=density,
|
|
32
|
+
initial_strain=initial_strain,
|
|
33
|
+
initial_stress=initial_stress,
|
|
34
|
+
strain_compatibility=strain_compatibility,
|
|
35
|
+
name=name,
|
|
36
|
+
)
|
|
28
37
|
|
|
29
38
|
self._fck = abs(fck)
|
|
30
39
|
if existing:
|
|
@@ -46,6 +46,9 @@ class ConcreteEC2_2004(Concrete): # noqa: N801
|
|
|
46
46
|
ConstitutiveLaw,
|
|
47
47
|
]
|
|
48
48
|
] = 'parabolarectangle',
|
|
49
|
+
initial_strain: t.Optional[float] = None,
|
|
50
|
+
initial_stress: t.Optional[float] = None,
|
|
51
|
+
strain_compatibility: t.Optional[bool] = None,
|
|
49
52
|
fcm: t.Optional[float] = None,
|
|
50
53
|
fctm: t.Optional[float] = None,
|
|
51
54
|
fctk_5: t.Optional[float] = None,
|
|
@@ -80,6 +83,13 @@ class ConcreteEC2_2004(Concrete): # noqa: N801
|
|
|
80
83
|
law type for concrete. (valid options for string: 'elastic',
|
|
81
84
|
'parabolarectangle', 'bilinearcompression', 'sargin',
|
|
82
85
|
'popovics').
|
|
86
|
+
initial_strain (Optional[float]): Initial strain of the material.
|
|
87
|
+
initial_stress (Optional[float]): Initial stress of the material.
|
|
88
|
+
strain_compatibility (Optional[bool]): Only relevant if
|
|
89
|
+
initial_strain or initial_stress are different from zero. If
|
|
90
|
+
True, the material deforms with the geometry. If False, the
|
|
91
|
+
stress in the material upon loading is kept constant
|
|
92
|
+
corresponding to the initial strain.
|
|
83
93
|
fcm (float, optional): The mean compressive strength.
|
|
84
94
|
fctm (float, optional): The mean tensile strength.
|
|
85
95
|
fctk_5 (float, optional): The 5% fractile for the tensile strength.
|
|
@@ -130,6 +140,9 @@ class ConcreteEC2_2004(Concrete): # noqa: N801
|
|
|
130
140
|
density=density,
|
|
131
141
|
existing=False,
|
|
132
142
|
gamma_c=gamma_c,
|
|
143
|
+
initial_strain=initial_strain,
|
|
144
|
+
initial_stress=initial_stress,
|
|
145
|
+
strain_compatibility=strain_compatibility,
|
|
133
146
|
)
|
|
134
147
|
self._alpha_cc = alpha_cc
|
|
135
148
|
self._fcm = abs(fcm) if fcm is not None else None
|
|
@@ -165,6 +178,7 @@ class ConcreteEC2_2004(Concrete): # noqa: N801
|
|
|
165
178
|
raise ValueError(
|
|
166
179
|
'The provided constitutive law is not valid for concrete.'
|
|
167
180
|
)
|
|
181
|
+
self._apply_initial_strain()
|
|
168
182
|
|
|
169
183
|
def __post_init__(self):
|
|
170
184
|
"""Validator for the attributes that are set in the constructor."""
|
|
@@ -48,6 +48,9 @@ class ConcreteEC2_2023(Concrete): # noqa: N801
|
|
|
48
48
|
ConstitutiveLaw,
|
|
49
49
|
]
|
|
50
50
|
] = 'parabolarectangle',
|
|
51
|
+
initial_strain: t.Optional[float] = None,
|
|
52
|
+
initial_stress: t.Optional[float] = None,
|
|
53
|
+
strain_compatibility: t.Optional[bool] = None,
|
|
51
54
|
fcm: t.Optional[float] = None,
|
|
52
55
|
fctm: t.Optional[float] = None,
|
|
53
56
|
fctk_5: t.Optional[float] = None,
|
|
@@ -80,6 +83,13 @@ class ConcreteEC2_2023(Concrete): # noqa: N801
|
|
|
80
83
|
law type for concrete. (valid options for string: 'elastic',
|
|
81
84
|
'parabolarectangle', 'bilinearcompression', 'sargin',
|
|
82
85
|
'popovics').
|
|
86
|
+
initial_strain (Optional[float]): Initial strain of the material.
|
|
87
|
+
initial_stress (Optional[float]): Initial stress of the material.
|
|
88
|
+
strain_compatibility (Optional[bool]): Only relevant if
|
|
89
|
+
initial_strain or initial_stress are different from zero. If
|
|
90
|
+
True, the material deforms with the geometry. If False, the
|
|
91
|
+
stress in the material upon loading is kept constant
|
|
92
|
+
corresponding to the initial strain.
|
|
83
93
|
fcm (float, optional): The mean compressive strength.
|
|
84
94
|
fctm (float, optional): The mean tensile strength.
|
|
85
95
|
fctk_5 (float, optional): The 5% fractile for the tensile strength.
|
|
@@ -124,6 +134,9 @@ class ConcreteEC2_2023(Concrete): # noqa: N801
|
|
|
124
134
|
density=density,
|
|
125
135
|
existing=False,
|
|
126
136
|
gamma_c=gamma_c,
|
|
137
|
+
initial_strain=initial_strain,
|
|
138
|
+
initial_stress=initial_stress,
|
|
139
|
+
strain_compatibility=strain_compatibility,
|
|
127
140
|
)
|
|
128
141
|
self._kE = kE
|
|
129
142
|
self._strength_dev_class = strength_dev_class.strip().lower()
|
|
@@ -158,6 +171,7 @@ class ConcreteEC2_2023(Concrete): # noqa: N801
|
|
|
158
171
|
raise ValueError(
|
|
159
172
|
'The provided constitutive law is not valid for concrete.'
|
|
160
173
|
)
|
|
174
|
+
self._apply_initial_strain()
|
|
161
175
|
|
|
162
176
|
def __post_init__(self):
|
|
163
177
|
"""Validator for the attributes that are set in the constructor."""
|
|
@@ -48,6 +48,9 @@ class ConcreteMC2010(Concrete):
|
|
|
48
48
|
ConstitutiveLaw,
|
|
49
49
|
]
|
|
50
50
|
] = 'parabolarectangle',
|
|
51
|
+
initial_strain: t.Optional[float] = None,
|
|
52
|
+
initial_stress: t.Optional[float] = None,
|
|
53
|
+
strain_compatibility: t.Optional[bool] = None,
|
|
51
54
|
fcm: t.Optional[float] = None,
|
|
52
55
|
fctm: t.Optional[float] = None,
|
|
53
56
|
fctkmin: t.Optional[float] = None,
|
|
@@ -77,6 +80,18 @@ class ConcreteMC2010(Concrete):
|
|
|
77
80
|
alpha_cc (float, optional): A factor for considering long-term
|
|
78
81
|
effects on the strength, and effects that arise from the way
|
|
79
82
|
the load is applied.
|
|
83
|
+
consitutive_law (ConstitutiveLaw | str): A valid ConstitutiveLaw
|
|
84
|
+
object for concrete or a string defining a valid constitutive
|
|
85
|
+
law type for concrete. (valid options for string: 'elastic',
|
|
86
|
+
'parabolarectangle', 'bilinearcompression', 'sargin',
|
|
87
|
+
'popovics').
|
|
88
|
+
initial_strain (Optional[float]): Initial strain of the material.
|
|
89
|
+
initial_stress (Optional[float]): Initial stress of the material.
|
|
90
|
+
strain_compatibility (Optional[bool]): Only relevant if
|
|
91
|
+
initial_strain or initial_stress are different from zero. If
|
|
92
|
+
True, the material deforms with the geometry. If False, the
|
|
93
|
+
stress in the material upon loading is kept constant
|
|
94
|
+
corresponding to the initial strain.
|
|
80
95
|
fcm (float, optional): The mean compressive strength.
|
|
81
96
|
fctm (float, optional): The mean tensile strength.
|
|
82
97
|
fctkmin (float, optional): The minimum tensile strength.
|
|
@@ -126,6 +141,9 @@ class ConcreteMC2010(Concrete):
|
|
|
126
141
|
name=name,
|
|
127
142
|
density=density,
|
|
128
143
|
gamma_c=gamma_c,
|
|
144
|
+
initial_strain=initial_strain,
|
|
145
|
+
initial_stress=initial_stress,
|
|
146
|
+
strain_compatibility=strain_compatibility,
|
|
129
147
|
)
|
|
130
148
|
self._alpha_cc = alpha_cc
|
|
131
149
|
self._fcm = abs(fcm) if fcm is not None else None
|
|
@@ -162,6 +180,7 @@ class ConcreteMC2010(Concrete):
|
|
|
162
180
|
raise ValueError(
|
|
163
181
|
'The provided constitutive law is not valid for concrete.'
|
|
164
182
|
)
|
|
183
|
+
self._apply_initial_strain()
|
|
165
184
|
|
|
166
185
|
def __post_init__(self):
|
|
167
186
|
"""Validator for the attributes that are set in the constructor."""
|
|
@@ -6,6 +6,7 @@ from ...core.base import ConstitutiveLaw, Material
|
|
|
6
6
|
from ._bilinearcompression import BilinearCompression
|
|
7
7
|
from ._elastic import Elastic
|
|
8
8
|
from ._elasticplastic import ElasticPlastic
|
|
9
|
+
from ._initial_strain import InitialStrain
|
|
9
10
|
from ._parabolarectangle import ParabolaRectangle
|
|
10
11
|
from ._popovics import Popovics
|
|
11
12
|
from ._sargin import Sargin
|
|
@@ -19,6 +20,7 @@ __all__ = [
|
|
|
19
20
|
'Popovics',
|
|
20
21
|
'Sargin',
|
|
21
22
|
'UserDefined',
|
|
23
|
+
'InitialStrain',
|
|
22
24
|
'get_constitutive_laws_list',
|
|
23
25
|
'create_constitutive_law',
|
|
24
26
|
]
|
|
@@ -31,6 +33,7 @@ CONSTITUTIVE_LAWS: t.Dict[str, ConstitutiveLaw] = {
|
|
|
31
33
|
'parabolarectangle': ParabolaRectangle,
|
|
32
34
|
'popovics': Popovics,
|
|
33
35
|
'sargin': Sargin,
|
|
36
|
+
'initialstrain': InitialStrain,
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
|
|
@@ -34,8 +34,8 @@ class ElasticPlastic(ConstitutiveLaw):
|
|
|
34
34
|
|
|
35
35
|
Keyword Arguments:
|
|
36
36
|
Eh (float): The hardening modulus.
|
|
37
|
-
eps_su (float): The ultimate strain.
|
|
38
|
-
name (str): A descriptive name for the constitutive law.
|
|
37
|
+
eps_su (float, optional): The ultimate strain.
|
|
38
|
+
name (str, optional): A descriptive name for the constitutive law.
|
|
39
39
|
"""
|
|
40
40
|
name = name if name is not None else 'ElasticPlasticLaw'
|
|
41
41
|
super().__init__(name=name)
|