structuralcodes 0.4.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/ec2_2004/__init__.py +2 -0
- structuralcodes/codes/ec2_2004/shear.py +44 -4
- structuralcodes/codes/mc2010/__init__.py +18 -0
- structuralcodes/codes/mc2010/_concrete_creep_and_shrinkage.py +2 -2
- structuralcodes/codes/mc2010/_concrete_punching.py +300 -388
- structuralcodes/core/base.py +116 -5
- structuralcodes/geometry/__init__.py +2 -8
- structuralcodes/geometry/_circular.py +3 -10
- structuralcodes/geometry/_geometry.py +58 -114
- structuralcodes/geometry/_rectangular.py +3 -10
- structuralcodes/geometry/_reinforcement.py +9 -14
- 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/__init__.py +2 -1
- structuralcodes/materials/basic/__init__.py +11 -0
- structuralcodes/materials/basic/_elastic.py +69 -0
- structuralcodes/materials/basic/_elasticplastic.py +92 -0
- structuralcodes/materials/basic/_generic.py +43 -0
- 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 +15 -1
- structuralcodes/materials/reinforcement/_reinforcementEC2_2023.py +15 -1
- structuralcodes/materials/reinforcement/_reinforcementMC2010.py +15 -1
- structuralcodes/sections/_generic.py +53 -14
- structuralcodes/sections/_rc_utils.py +15 -5
- structuralcodes/sections/section_integrators/__init__.py +3 -1
- structuralcodes/sections/section_integrators/_fiber_integrator.py +19 -11
- structuralcodes/sections/section_integrators/_marin_integrator.py +25 -20
- {structuralcodes-0.4.0.dist-info → structuralcodes-0.6.0.dist-info}/METADATA +2 -2
- structuralcodes-0.6.0.dist-info/RECORD +77 -0
- structuralcodes/geometry/_steel_sections.py +0 -2155
- structuralcodes-0.4.0.dist-info/RECORD +0 -63
- /structuralcodes/{sections/section_integrators → core}/_marin_integration.py +0 -0
- {structuralcodes-0.4.0.dist-info → structuralcodes-0.6.0.dist-info}/WHEEL +0 -0
- {structuralcodes-0.4.0.dist-info → structuralcodes-0.6.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
"""UC profiles."""
|
|
2
|
+
|
|
3
|
+
from shapely import (
|
|
4
|
+
Polygon,
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
from ._base_profile import BaseProfile
|
|
8
|
+
from ._common_functions import (
|
|
9
|
+
_create_I_section,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class UC(BaseProfile):
|
|
14
|
+
"""Simple class for representing a UC profile.
|
|
15
|
+
|
|
16
|
+
Universal Columns.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
parameters = {
|
|
20
|
+
'UC152x152x23': {
|
|
21
|
+
'h': 152.0,
|
|
22
|
+
'b': 152.0,
|
|
23
|
+
'tw': 5.8,
|
|
24
|
+
'tf': 6.8,
|
|
25
|
+
'r': 8.0,
|
|
26
|
+
},
|
|
27
|
+
'UC152x152x30': {
|
|
28
|
+
'h': 158.0,
|
|
29
|
+
'b': 153.0,
|
|
30
|
+
'tw': 6.5,
|
|
31
|
+
'tf': 9.4,
|
|
32
|
+
'r': 8.0,
|
|
33
|
+
},
|
|
34
|
+
'UC152x152x37': {
|
|
35
|
+
'h': 162.0,
|
|
36
|
+
'b': 154.0,
|
|
37
|
+
'tw': 8.0,
|
|
38
|
+
'tf': 11.5,
|
|
39
|
+
'r': 8.0,
|
|
40
|
+
},
|
|
41
|
+
'UC152x152x44': {
|
|
42
|
+
'h': 166.0,
|
|
43
|
+
'b': 156.0,
|
|
44
|
+
'tw': 9.5,
|
|
45
|
+
'tf': 13.6,
|
|
46
|
+
'r': 8.0,
|
|
47
|
+
},
|
|
48
|
+
'UC152x152x51': {
|
|
49
|
+
'h': 170.0,
|
|
50
|
+
'b': 157.0,
|
|
51
|
+
'tw': 11.0,
|
|
52
|
+
'tf': 15.7,
|
|
53
|
+
'r': 8.0,
|
|
54
|
+
},
|
|
55
|
+
'UC203x203x46': {
|
|
56
|
+
'h': 203.0,
|
|
57
|
+
'b': 204.0,
|
|
58
|
+
'tw': 7.2,
|
|
59
|
+
'tf': 11.0,
|
|
60
|
+
'r': 13.0,
|
|
61
|
+
},
|
|
62
|
+
'UC203x203x52': {
|
|
63
|
+
'h': 206.0,
|
|
64
|
+
'b': 204.0,
|
|
65
|
+
'tw': 7.9,
|
|
66
|
+
'tf': 12.5,
|
|
67
|
+
'r': 13.0,
|
|
68
|
+
},
|
|
69
|
+
'UC203x203x60': {
|
|
70
|
+
'h': 210.0,
|
|
71
|
+
'b': 206.0,
|
|
72
|
+
'tw': 9.4,
|
|
73
|
+
'tf': 14.2,
|
|
74
|
+
'r': 13.0,
|
|
75
|
+
},
|
|
76
|
+
'UC203x203x71': {
|
|
77
|
+
'h': 216.0,
|
|
78
|
+
'b': 206.0,
|
|
79
|
+
'tw': 10.0,
|
|
80
|
+
'tf': 17.3,
|
|
81
|
+
'r': 13.0,
|
|
82
|
+
},
|
|
83
|
+
'UC203x203x86': {
|
|
84
|
+
'h': 222.0,
|
|
85
|
+
'b': 209.0,
|
|
86
|
+
'tw': 12.7,
|
|
87
|
+
'tf': 20.5,
|
|
88
|
+
'r': 13.0,
|
|
89
|
+
},
|
|
90
|
+
'UC203x203x100': {
|
|
91
|
+
'h': 229.0,
|
|
92
|
+
'b': 210.0,
|
|
93
|
+
'tw': 14.5,
|
|
94
|
+
'tf': 23.7,
|
|
95
|
+
'r': 13.0,
|
|
96
|
+
},
|
|
97
|
+
'UC203x203x113': {
|
|
98
|
+
'h': 235.0,
|
|
99
|
+
'b': 212.0,
|
|
100
|
+
'tw': 16.3,
|
|
101
|
+
'tf': 26.9,
|
|
102
|
+
'r': 13.0,
|
|
103
|
+
},
|
|
104
|
+
'UC203x203x127': {
|
|
105
|
+
'h': 241.0,
|
|
106
|
+
'b': 214.0,
|
|
107
|
+
'tw': 18.1,
|
|
108
|
+
'tf': 30.1,
|
|
109
|
+
'r': 13.0,
|
|
110
|
+
},
|
|
111
|
+
'UC254x254x73': {
|
|
112
|
+
'h': 254.0,
|
|
113
|
+
'b': 255.0,
|
|
114
|
+
'tw': 8.6,
|
|
115
|
+
'tf': 14.2,
|
|
116
|
+
'r': 20.0,
|
|
117
|
+
},
|
|
118
|
+
'UC254x254x81': {
|
|
119
|
+
'h': 256.0,
|
|
120
|
+
'b': 255.0,
|
|
121
|
+
'tw': 9.4,
|
|
122
|
+
'tf': 15.6,
|
|
123
|
+
'r': 20.0,
|
|
124
|
+
},
|
|
125
|
+
'UC254x254x89': {
|
|
126
|
+
'h': 260.0,
|
|
127
|
+
'b': 256.0,
|
|
128
|
+
'tw': 10.3,
|
|
129
|
+
'tf': 17.3,
|
|
130
|
+
'r': 20.0,
|
|
131
|
+
},
|
|
132
|
+
'UC254x254x101': {
|
|
133
|
+
'h': 264.0,
|
|
134
|
+
'b': 257.0,
|
|
135
|
+
'tw': 11.9,
|
|
136
|
+
'tf': 19.6,
|
|
137
|
+
'r': 20.0,
|
|
138
|
+
},
|
|
139
|
+
'UC254x254x107': {
|
|
140
|
+
'h': 267.0,
|
|
141
|
+
'b': 259.0,
|
|
142
|
+
'tw': 12.8,
|
|
143
|
+
'tf': 20.5,
|
|
144
|
+
'r': 20.0,
|
|
145
|
+
},
|
|
146
|
+
'UC254x254x115': {
|
|
147
|
+
'h': 269.0,
|
|
148
|
+
'b': 259.0,
|
|
149
|
+
'tw': 13.5,
|
|
150
|
+
'tf': 22.1,
|
|
151
|
+
'r': 20.0,
|
|
152
|
+
},
|
|
153
|
+
'UC254x254x132': {
|
|
154
|
+
'h': 276.0,
|
|
155
|
+
'b': 261.0,
|
|
156
|
+
'tw': 15.3,
|
|
157
|
+
'tf': 25.3,
|
|
158
|
+
'r': 20.0,
|
|
159
|
+
},
|
|
160
|
+
'UC254x254x149': {
|
|
161
|
+
'h': 282.0,
|
|
162
|
+
'b': 263.0,
|
|
163
|
+
'tw': 17.3,
|
|
164
|
+
'tf': 28.4,
|
|
165
|
+
'r': 20.0,
|
|
166
|
+
},
|
|
167
|
+
'UC254x254x167': {
|
|
168
|
+
'h': 289.0,
|
|
169
|
+
'b': 265.0,
|
|
170
|
+
'tw': 19.2,
|
|
171
|
+
'tf': 31.7,
|
|
172
|
+
'r': 20.0,
|
|
173
|
+
},
|
|
174
|
+
'UC305x305x97': {
|
|
175
|
+
'h': 308.0,
|
|
176
|
+
'b': 305.0,
|
|
177
|
+
'tw': 9.9,
|
|
178
|
+
'tf': 15.4,
|
|
179
|
+
'r': 20.0,
|
|
180
|
+
},
|
|
181
|
+
'UC305x305x107': {
|
|
182
|
+
'h': 311.0,
|
|
183
|
+
'b': 306.0,
|
|
184
|
+
'tw': 10.9,
|
|
185
|
+
'tf': 17.0,
|
|
186
|
+
'r': 20.0,
|
|
187
|
+
},
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
@classmethod
|
|
191
|
+
def get_polygon(cls, name: str) -> Polygon:
|
|
192
|
+
"""Returns a shapely polygon representing a UC section."""
|
|
193
|
+
parameters = cls.parameters.get(name)
|
|
194
|
+
if parameters is None:
|
|
195
|
+
raise ValueError(
|
|
196
|
+
f"Profile '{name}' not found in UC sections. "
|
|
197
|
+
"Select a valid profile (available ones: "
|
|
198
|
+
f"{cls.profiles()})"
|
|
199
|
+
)
|
|
200
|
+
return _create_I_section(**parameters)
|
|
201
|
+
|
|
202
|
+
@classmethod
|
|
203
|
+
def profiles(cls) -> list:
|
|
204
|
+
"""Returns a list containing all available profiles."""
|
|
205
|
+
return list(cls.parameters.keys())
|
|
206
|
+
|
|
207
|
+
def __init__(self, name: str) -> None:
|
|
208
|
+
"""Creates a new UC object."""
|
|
209
|
+
parameters = self.parameters.get(name)
|
|
210
|
+
if parameters is None:
|
|
211
|
+
raise ValueError(
|
|
212
|
+
f"Profile '{name}' not found in UC sections. "
|
|
213
|
+
"Select a valid profile (available ones: "
|
|
214
|
+
f"{self.profiles()})"
|
|
215
|
+
)
|
|
216
|
+
super().__init__()
|
|
217
|
+
self._h = parameters.get('h')
|
|
218
|
+
self._b = parameters.get('b')
|
|
219
|
+
self._tw = parameters.get('tw')
|
|
220
|
+
self._tf = parameters.get('tf')
|
|
221
|
+
self._r = parameters.get('r')
|
|
222
|
+
self._polygon = _create_I_section(**parameters)
|
|
223
|
+
|
|
224
|
+
@property
|
|
225
|
+
def polygon(self) -> Polygon:
|
|
226
|
+
"""Returns shapely Polygon of section.
|
|
227
|
+
|
|
228
|
+
Returns:
|
|
229
|
+
Polygon: The represention of the UC section.
|
|
230
|
+
"""
|
|
231
|
+
return self._polygon
|
|
232
|
+
|
|
233
|
+
@property
|
|
234
|
+
def h(self) -> float:
|
|
235
|
+
"""Returns height of UC section.
|
|
236
|
+
|
|
237
|
+
Returns:
|
|
238
|
+
float: Height h of UC section.
|
|
239
|
+
"""
|
|
240
|
+
return self._h
|
|
241
|
+
|
|
242
|
+
@property
|
|
243
|
+
def b(self) -> float:
|
|
244
|
+
"""Returns width of UC section.
|
|
245
|
+
|
|
246
|
+
Returns:
|
|
247
|
+
float: Width b of UC section.
|
|
248
|
+
"""
|
|
249
|
+
return self._b
|
|
250
|
+
|
|
251
|
+
@property
|
|
252
|
+
def tw(self) -> float:
|
|
253
|
+
"""Returns thickness of web of UC section.
|
|
254
|
+
|
|
255
|
+
Returns:
|
|
256
|
+
float: Web thickness tw of UC section.
|
|
257
|
+
"""
|
|
258
|
+
return self._tw
|
|
259
|
+
|
|
260
|
+
@property
|
|
261
|
+
def tf(self) -> float:
|
|
262
|
+
"""Returns thickness of flange of UC section.
|
|
263
|
+
|
|
264
|
+
Returns:
|
|
265
|
+
float: Flange thickness tw of UC section.
|
|
266
|
+
"""
|
|
267
|
+
return self._tf
|
|
268
|
+
|
|
269
|
+
@property
|
|
270
|
+
def r(self) -> float:
|
|
271
|
+
"""Returns fillet radius of UC section.
|
|
272
|
+
|
|
273
|
+
Returns:
|
|
274
|
+
float: Fillet radius r of UC section.
|
|
275
|
+
"""
|
|
276
|
+
return self._r
|
|
@@ -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
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""A collection of basic material classes."""
|
|
2
|
+
|
|
3
|
+
from ._elastic import ElasticMaterial
|
|
4
|
+
from ._elasticplastic import ElasticPlasticMaterial
|
|
5
|
+
from ._generic import GenericMaterial
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
'ElasticMaterial',
|
|
9
|
+
'ElasticPlasticMaterial',
|
|
10
|
+
'GenericMaterial',
|
|
11
|
+
]
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""A material class with elastic properties."""
|
|
2
|
+
|
|
3
|
+
import typing as t
|
|
4
|
+
|
|
5
|
+
from ...core.base import Material
|
|
6
|
+
from ..constitutive_laws import create_constitutive_law
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ElasticMaterial(Material):
|
|
10
|
+
"""A material class with elastic properties."""
|
|
11
|
+
|
|
12
|
+
_E: float
|
|
13
|
+
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
E: float,
|
|
17
|
+
density: float,
|
|
18
|
+
initial_strain: t.Optional[float] = None,
|
|
19
|
+
initial_stress: t.Optional[float] = None,
|
|
20
|
+
strain_compatibility: t.Optional[float] = None,
|
|
21
|
+
name: t.Optional[str] = None,
|
|
22
|
+
):
|
|
23
|
+
"""Initialize a material with an elastic plastic constitutive law.
|
|
24
|
+
|
|
25
|
+
Arguments:
|
|
26
|
+
E (float): The Young's modulus.
|
|
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.
|
|
35
|
+
name (str, optional): The name of the material, default value None.
|
|
36
|
+
"""
|
|
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
|
+
)
|
|
44
|
+
self._E = E
|
|
45
|
+
self._constitutive_law = create_constitutive_law('elastic', self)
|
|
46
|
+
self._apply_initial_strain()
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def E(self) -> float:
|
|
50
|
+
"""Returns the Young's modulus."""
|
|
51
|
+
return self._E
|
|
52
|
+
|
|
53
|
+
def __elastic__(self) -> dict:
|
|
54
|
+
"""Returns kwargs for creating an elastic constitutive law."""
|
|
55
|
+
return {'E': self.E}
|
|
56
|
+
|
|
57
|
+
@classmethod
|
|
58
|
+
def from_material(cls, other_material: Material):
|
|
59
|
+
"""Create an elastic material based on another material."""
|
|
60
|
+
# Create name of elastic material
|
|
61
|
+
name = other_material.name
|
|
62
|
+
if name is not None:
|
|
63
|
+
name += '_elastic'
|
|
64
|
+
|
|
65
|
+
return cls(
|
|
66
|
+
E=other_material.constitutive_law.get_tangent(eps=0),
|
|
67
|
+
density=other_material.density,
|
|
68
|
+
name=name,
|
|
69
|
+
)
|