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
|
@@ -1,2155 +0,0 @@
|
|
|
1
|
-
"""Utility functions for importing standard steel profiles."""
|
|
2
|
-
|
|
3
|
-
import numpy as np
|
|
4
|
-
from shapely import (
|
|
5
|
-
LinearRing,
|
|
6
|
-
LineString,
|
|
7
|
-
Point,
|
|
8
|
-
Polygon,
|
|
9
|
-
get_geometry,
|
|
10
|
-
polygonize,
|
|
11
|
-
set_precision,
|
|
12
|
-
)
|
|
13
|
-
from shapely.affinity import rotate, scale, translate
|
|
14
|
-
from shapely.geometry.polygon import orient
|
|
15
|
-
from shapely.ops import linemerge, split, unary_union
|
|
16
|
-
|
|
17
|
-
from structuralcodes.sections.section_integrators._marin_integration import (
|
|
18
|
-
marin_integration,
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class BaseProfile:
|
|
23
|
-
"""Base class representing a profile.
|
|
24
|
-
|
|
25
|
-
Contains the common code for all sections.
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
def __init__(self):
|
|
29
|
-
"""Creates an empty base profile."""
|
|
30
|
-
self._polygon: Polygon = None
|
|
31
|
-
self._A: float = None
|
|
32
|
-
self._Iy: float = None
|
|
33
|
-
self._Iz: float = None
|
|
34
|
-
self._Icsi: float = None
|
|
35
|
-
self._Ieta: float = None
|
|
36
|
-
self._Iyz: float = None
|
|
37
|
-
self._Wely: float = None
|
|
38
|
-
self._Welz: float = None
|
|
39
|
-
self._iy: float = None
|
|
40
|
-
self._iz: float = None
|
|
41
|
-
self._Wply: float = None
|
|
42
|
-
self._Wplz: float = None
|
|
43
|
-
|
|
44
|
-
def _check_polygon_defined(self):
|
|
45
|
-
"""Just checks if polygon attribute is defined.
|
|
46
|
-
|
|
47
|
-
If the polygon is not defined (it should never happen), an exception
|
|
48
|
-
is Raised.
|
|
49
|
-
"""
|
|
50
|
-
# The polygon attribute should be already defined
|
|
51
|
-
if self._polygon is None:
|
|
52
|
-
raise RuntimeError(
|
|
53
|
-
'The polygon for some reason was not correctly defined.'
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
def _find_plastic_neutral_axis_y(self) -> float:
|
|
57
|
-
"""Find posizion z of plastic neutral axes parallel to y.
|
|
58
|
-
|
|
59
|
-
We use bisection algorithm within the section limits.
|
|
60
|
-
"""
|
|
61
|
-
bounds = self.polygon.bounds
|
|
62
|
-
zmin, zmax = bounds[1], bounds[3]
|
|
63
|
-
|
|
64
|
-
zA = zmin
|
|
65
|
-
zB = zmax
|
|
66
|
-
|
|
67
|
-
daA = self._find_delta_area_above_minus_below(z=zA)
|
|
68
|
-
|
|
69
|
-
ITMAX = 200
|
|
70
|
-
it = 0
|
|
71
|
-
|
|
72
|
-
while (it < ITMAX) and (abs(zB - zA) > (zmax - zmin) * 1e-10):
|
|
73
|
-
zC = (zA + zB) / 2.0
|
|
74
|
-
daC = self._find_delta_area_above_minus_below(z=zC)
|
|
75
|
-
if abs(daC) < 1e-10:
|
|
76
|
-
break
|
|
77
|
-
if daA * daC < 0:
|
|
78
|
-
# The solution is between A and C
|
|
79
|
-
zB = zC
|
|
80
|
-
else:
|
|
81
|
-
# The solution is between C and B
|
|
82
|
-
zA = zC
|
|
83
|
-
daA = daC
|
|
84
|
-
it += 1
|
|
85
|
-
if it >= ITMAX:
|
|
86
|
-
s = f'Last iteration reached a unbalance of {daC}'
|
|
87
|
-
raise ValueError(f'Maximum number of iterations reached.\n{s}')
|
|
88
|
-
|
|
89
|
-
return zC
|
|
90
|
-
|
|
91
|
-
def _find_delta_area_above_minus_below(self, z: float) -> float:
|
|
92
|
-
"""Returns area difference between above and below parts.
|
|
93
|
-
|
|
94
|
-
Above and below parts are computed splitting the polygon with a line
|
|
95
|
-
parallel to Y axes at z coordinate.
|
|
96
|
-
"""
|
|
97
|
-
bounds = self._polygon.bounds
|
|
98
|
-
xmax = max(abs(bounds[0]), bounds[2])
|
|
99
|
-
line = LineString([[-xmax * 1.05, z], [xmax * 1.05, z]])
|
|
100
|
-
|
|
101
|
-
area_above = 0
|
|
102
|
-
area_below = 0
|
|
103
|
-
# divide polygons "above" and "below" line
|
|
104
|
-
if line.intersects(self._polygon):
|
|
105
|
-
result = split(self._polygon, line)
|
|
106
|
-
# divide polygons "above" and "below" line
|
|
107
|
-
for geom in result.geoms:
|
|
108
|
-
if LinearRing(
|
|
109
|
-
(line.coords[0], line.coords[1], geom.centroid.coords[0])
|
|
110
|
-
).is_ccw:
|
|
111
|
-
area_above += geom.area
|
|
112
|
-
else:
|
|
113
|
-
area_below += geom.area
|
|
114
|
-
else:
|
|
115
|
-
# not intersecting, all the polygon is above or below the line
|
|
116
|
-
geom = self.polygon
|
|
117
|
-
if LinearRing(
|
|
118
|
-
(line.coords[0], line.coords[1], geom.centroid.coords[0])
|
|
119
|
-
).is_ccw:
|
|
120
|
-
area_above += geom.area
|
|
121
|
-
else:
|
|
122
|
-
area_below += geom.area
|
|
123
|
-
return area_above - area_below
|
|
124
|
-
|
|
125
|
-
def _find_principals_direction_and_moments(self):
|
|
126
|
-
"""Computes principal direction and second area moments."""
|
|
127
|
-
eigres = np.linalg.eig(
|
|
128
|
-
np.array([[self.Iy, self.Iyz], [self.Iyz, self.Iz]])
|
|
129
|
-
)
|
|
130
|
-
max_idx = np.argmax(eigres[0])
|
|
131
|
-
min_idx = 0 if max_idx == 1 else 1
|
|
132
|
-
self._Icsi = eigres[0][max_idx]
|
|
133
|
-
self._Ieta = eigres[0][min_idx]
|
|
134
|
-
self._theta = np.arccos(
|
|
135
|
-
np.dot(np.array([1, 0]), eigres[1][:, max_idx])
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
@property
|
|
139
|
-
def A(self) -> float:
|
|
140
|
-
"""Returns area of profile."""
|
|
141
|
-
if self._A is None:
|
|
142
|
-
# Check if the polygon is defined
|
|
143
|
-
self._check_polygon_defined()
|
|
144
|
-
# Get the polygon coordinates:
|
|
145
|
-
xy = self._polygon.exterior.coords.xy
|
|
146
|
-
# Compute area
|
|
147
|
-
self._A = marin_integration(xy[0], xy[1], 0, 0)
|
|
148
|
-
return self._A
|
|
149
|
-
|
|
150
|
-
@property
|
|
151
|
-
def Iy(self) -> float:
|
|
152
|
-
"""Returns second moment of area around y axis."""
|
|
153
|
-
if self._Iy is None:
|
|
154
|
-
# Check if the polygon is defined
|
|
155
|
-
self._check_polygon_defined()
|
|
156
|
-
# Get the polygon coordinates:
|
|
157
|
-
xy = self._polygon.exterior.coords.xy
|
|
158
|
-
# Compute second moments of inertia
|
|
159
|
-
self._Iy = marin_integration(xy[0], xy[1], 0, 2)
|
|
160
|
-
return self._Iy
|
|
161
|
-
|
|
162
|
-
@property
|
|
163
|
-
def Iz(self) -> float:
|
|
164
|
-
"""Returns second moment of area around z axis."""
|
|
165
|
-
if self._Iz is None:
|
|
166
|
-
# Check if the polygon is defined
|
|
167
|
-
self._check_polygon_defined()
|
|
168
|
-
# Get the polygon coordinates:
|
|
169
|
-
xy = self._polygon.exterior.coords.xy
|
|
170
|
-
# Compute second moments of inertia
|
|
171
|
-
self._Iz = marin_integration(xy[0], xy[1], 2, 0)
|
|
172
|
-
return self._Iz
|
|
173
|
-
|
|
174
|
-
@property
|
|
175
|
-
def Iyz(self) -> float:
|
|
176
|
-
"""Returns product moment of inertia."""
|
|
177
|
-
if self._Iyz is None:
|
|
178
|
-
# Check if the polygon is defined
|
|
179
|
-
self._check_polygon_defined()
|
|
180
|
-
# Get the polygon coordinates:
|
|
181
|
-
xy = self._polygon.exterior.coords.xy
|
|
182
|
-
# Compute product moment of area
|
|
183
|
-
self._Iyz = marin_integration(xy[0], xy[1], 1, 1)
|
|
184
|
-
return self._Iyz
|
|
185
|
-
|
|
186
|
-
@property
|
|
187
|
-
def Icsi(self) -> float:
|
|
188
|
-
"""Returns second moment of area around principal csi axis.
|
|
189
|
-
|
|
190
|
-
It is assumed that Icsi is maximum second moment, while Ieta is the
|
|
191
|
-
minimum one.
|
|
192
|
-
"""
|
|
193
|
-
if self._Icsi is None:
|
|
194
|
-
self._find_principals_direction_and_moments()
|
|
195
|
-
return self._Icsi
|
|
196
|
-
|
|
197
|
-
@property
|
|
198
|
-
def Ieta(self) -> float:
|
|
199
|
-
"""Returns second moment of area around principal eta axis.
|
|
200
|
-
|
|
201
|
-
It is assumed that Icsi is maximum second moment, while Ieta is the
|
|
202
|
-
minimum one.
|
|
203
|
-
"""
|
|
204
|
-
if self._Ieta is None:
|
|
205
|
-
self._find_principals_direction_and_moments()
|
|
206
|
-
return self._Ieta
|
|
207
|
-
|
|
208
|
-
@property
|
|
209
|
-
def theta(self) -> float:
|
|
210
|
-
"""Returns angle between x and principal eta axis.
|
|
211
|
-
|
|
212
|
-
It is assumed that Icsi is maximum second moment, while Ieta is the
|
|
213
|
-
minimum one.
|
|
214
|
-
|
|
215
|
-
Returns:
|
|
216
|
-
float: The angle in radians.
|
|
217
|
-
"""
|
|
218
|
-
if self._theta is None:
|
|
219
|
-
self._find_principals_direction_and_moments()
|
|
220
|
-
return self._theta
|
|
221
|
-
|
|
222
|
-
def _compute_elastic_moduli(self):
|
|
223
|
-
"""Compute elastic moduli Wely and Welz."""
|
|
224
|
-
# Check if the polygon is defined
|
|
225
|
-
self._check_polygon_defined()
|
|
226
|
-
# For computing section modulus get bounds
|
|
227
|
-
bounds = self._polygon.bounds
|
|
228
|
-
xmax = max(abs(bounds[0]), bounds[2])
|
|
229
|
-
ymax = max(abs(bounds[1]), bounds[3])
|
|
230
|
-
# Then compute section modulus
|
|
231
|
-
self._Wely = self.Iy / ymax
|
|
232
|
-
self._Welz = self.Iz / xmax
|
|
233
|
-
|
|
234
|
-
@property
|
|
235
|
-
def Wely(self) -> float:
|
|
236
|
-
"""Returns section modulus in y direction."""
|
|
237
|
-
if self._Wely is None:
|
|
238
|
-
# Compute elastic moduli
|
|
239
|
-
self._compute_elastic_moduli()
|
|
240
|
-
return self._Wely
|
|
241
|
-
|
|
242
|
-
@property
|
|
243
|
-
def Welz(self) -> float:
|
|
244
|
-
"""Returns section modulus in z direction."""
|
|
245
|
-
if self._Welz is None:
|
|
246
|
-
# Compute elastic moduli
|
|
247
|
-
self._compute_elastic_moduli()
|
|
248
|
-
return self._Welz
|
|
249
|
-
|
|
250
|
-
@property
|
|
251
|
-
def Wply(self) -> float:
|
|
252
|
-
"""Returns plastic section modulus in y direction."""
|
|
253
|
-
if self._Wply is None:
|
|
254
|
-
# Check if the polygon is defined
|
|
255
|
-
self._check_polygon_defined()
|
|
256
|
-
# For computing section modulus get bounds
|
|
257
|
-
bounds = self._polygon.bounds
|
|
258
|
-
xmax = max(abs(bounds[0]), bounds[2])
|
|
259
|
-
# Compute plastic section modulus
|
|
260
|
-
# find plastic neutral axis parallel to y
|
|
261
|
-
self._Wply = 0
|
|
262
|
-
z_pna = self._find_plastic_neutral_axis_y()
|
|
263
|
-
poly = translate(self._polygon, xoff=0, yoff=-z_pna)
|
|
264
|
-
result = split(
|
|
265
|
-
poly,
|
|
266
|
-
LineString([[-xmax * 1.05, 0], [xmax * 1.05, 0]]),
|
|
267
|
-
)
|
|
268
|
-
for poly in result.geoms:
|
|
269
|
-
xy = poly.exterior.coords.xy
|
|
270
|
-
self._Wply += abs(marin_integration(xy[0], xy[1], 0, 1))
|
|
271
|
-
return self._Wply
|
|
272
|
-
|
|
273
|
-
@property
|
|
274
|
-
def Wplz(self) -> float:
|
|
275
|
-
"""Returns plastic section modulus in z direction."""
|
|
276
|
-
if self._Wplz is None:
|
|
277
|
-
# Check if the polygon is defined
|
|
278
|
-
self._check_polygon_defined()
|
|
279
|
-
# For computing section modulus get bounds
|
|
280
|
-
bounds = self._polygon.bounds
|
|
281
|
-
ymax = max(abs(bounds[1]), bounds[3])
|
|
282
|
-
# Compute plastic section modulus
|
|
283
|
-
# # find plastic neutral axis parallel to z
|
|
284
|
-
self._polygon = rotate(geom=self._polygon, angle=90, origin=(0, 0))
|
|
285
|
-
self._Wplz = 0
|
|
286
|
-
y_pna = self._find_plastic_neutral_axis_y()
|
|
287
|
-
poly = translate(self._polygon, xoff=0, yoff=-y_pna)
|
|
288
|
-
result = split(
|
|
289
|
-
poly,
|
|
290
|
-
LineString([[-ymax * 1.05, 0], [ymax * 1.05, 0]]),
|
|
291
|
-
)
|
|
292
|
-
for poly in result.geoms:
|
|
293
|
-
xy = poly.exterior.coords.xy
|
|
294
|
-
self._Wplz += abs(marin_integration(xy[0], xy[1], 0, 1))
|
|
295
|
-
self._polygon = rotate(
|
|
296
|
-
geom=self._polygon, angle=-90, origin=(0, 0)
|
|
297
|
-
)
|
|
298
|
-
return self._Wplz
|
|
299
|
-
|
|
300
|
-
@property
|
|
301
|
-
def iy(self) -> float:
|
|
302
|
-
"""Returns radius of inertia of profile."""
|
|
303
|
-
# Compute radius of inertia
|
|
304
|
-
self._iy = self._iy or (self.Iy / self.A) ** 0.5
|
|
305
|
-
return self._iy
|
|
306
|
-
|
|
307
|
-
@property
|
|
308
|
-
def iz(self) -> float:
|
|
309
|
-
"""Returns radius of inertia of profile."""
|
|
310
|
-
# Compute radius of inertia
|
|
311
|
-
self._iz = self._iz or (self.Iz / self.A) ** 0.5
|
|
312
|
-
return self._iz
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
class IPE(BaseProfile):
|
|
316
|
-
"""Simple class for representing an IPE profile.
|
|
317
|
-
|
|
318
|
-
IPE 80-600 in accordance with standard Euronorm 19-57.
|
|
319
|
-
"""
|
|
320
|
-
|
|
321
|
-
parameters = {
|
|
322
|
-
'IPE80': {'h': 80.0, 'b': 46.0, 'tw': 3.8, 'tf': 5.2, 'r': 5.0},
|
|
323
|
-
'IPE100': {'h': 100.0, 'b': 55.0, 'tw': 4.1, 'tf': 5.7, 'r': 7.0},
|
|
324
|
-
'IPE120': {'h': 120.0, 'b': 64.0, 'tw': 4.4, 'tf': 6.3, 'r': 7.0},
|
|
325
|
-
'IPE140': {'h': 140.0, 'b': 73.0, 'tw': 4.7, 'tf': 6.9, 'r': 7.0},
|
|
326
|
-
'IPE160': {'h': 160.0, 'b': 82.0, 'tw': 5.0, 'tf': 7.4, 'r': 9.0},
|
|
327
|
-
'IPE180': {'h': 180.0, 'b': 91.0, 'tw': 5.3, 'tf': 8.0, 'r': 9.0},
|
|
328
|
-
'IPE200': {'h': 200.0, 'b': 100.0, 'tw': 5.6, 'tf': 8.5, 'r': 12.0},
|
|
329
|
-
'IPE220': {'h': 220.0, 'b': 110.0, 'tw': 5.9, 'tf': 9.2, 'r': 12.0},
|
|
330
|
-
'IPE240': {'h': 240.0, 'b': 120.0, 'tw': 6.2, 'tf': 9.8, 'r': 15.0},
|
|
331
|
-
'IPE270': {'h': 270.0, 'b': 135.0, 'tw': 6.6, 'tf': 10.2, 'r': 15.0},
|
|
332
|
-
'IPE300': {'h': 300.0, 'b': 150.0, 'tw': 7.1, 'tf': 10.7, 'r': 15.0},
|
|
333
|
-
'IPE330': {'h': 330.0, 'b': 160.0, 'tw': 7.5, 'tf': 11.5, 'r': 18.0},
|
|
334
|
-
'IPE360': {'h': 360.0, 'b': 170.0, 'tw': 8.0, 'tf': 12.7, 'r': 18.0},
|
|
335
|
-
'IPE400': {'h': 400.0, 'b': 180.0, 'tw': 8.6, 'tf': 13.5, 'r': 21.0},
|
|
336
|
-
'IPE450': {'h': 450.0, 'b': 190.0, 'tw': 9.4, 'tf': 14.6, 'r': 21.0},
|
|
337
|
-
'IPE500': {'h': 500.0, 'b': 200.0, 'tw': 10.2, 'tf': 16.0, 'r': 21.0},
|
|
338
|
-
'IPE550': {'h': 550.0, 'b': 210.0, 'tw': 11.1, 'tf': 17.2, 'r': 24.0},
|
|
339
|
-
'IPE600': {'h': 600.0, 'b': 220.0, 'tw': 12.0, 'tf': 19.0, 'r': 24.0},
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
@classmethod
|
|
343
|
-
def get_polygon(cls, name: str) -> Polygon:
|
|
344
|
-
"""Returns a shapely polygon representing an IPE section."""
|
|
345
|
-
if isinstance(name, (float, int)):
|
|
346
|
-
name = f'IPE{int(name):0d}'
|
|
347
|
-
parameters = cls.parameters.get(name)
|
|
348
|
-
if parameters is None:
|
|
349
|
-
raise ValueError(
|
|
350
|
-
f"Profile '{name}' not found in IPE sections. "
|
|
351
|
-
"Select a valid profile (available ones: "
|
|
352
|
-
f"{cls.profiles()})"
|
|
353
|
-
)
|
|
354
|
-
return _create_I_section(**parameters)
|
|
355
|
-
|
|
356
|
-
@classmethod
|
|
357
|
-
def profiles(cls) -> list:
|
|
358
|
-
"""Returns a list containing all available profiles."""
|
|
359
|
-
return list(cls.parameters.keys())
|
|
360
|
-
|
|
361
|
-
def __init__(self, name: str) -> None:
|
|
362
|
-
"""Creates a new IPE object."""
|
|
363
|
-
if isinstance(name, (float, int)):
|
|
364
|
-
name = f'IPE{int(name):0d}'
|
|
365
|
-
parameters = self.parameters.get(name)
|
|
366
|
-
if parameters is None:
|
|
367
|
-
raise ValueError(
|
|
368
|
-
f"Profile '{name}' not found in IPE sections. "
|
|
369
|
-
"Select a valid profile (available ones: "
|
|
370
|
-
f"{self.profiles()})"
|
|
371
|
-
)
|
|
372
|
-
super().__init__()
|
|
373
|
-
self._h = parameters.get('h')
|
|
374
|
-
self._b = parameters.get('b')
|
|
375
|
-
self._tw = parameters.get('tw')
|
|
376
|
-
self._tf = parameters.get('tf')
|
|
377
|
-
self._r = parameters.get('r')
|
|
378
|
-
self._polygon = _create_I_section(**parameters)
|
|
379
|
-
|
|
380
|
-
@property
|
|
381
|
-
def polygon(self) -> Polygon:
|
|
382
|
-
"""Returns shapely Polygon of section.
|
|
383
|
-
|
|
384
|
-
Returns:
|
|
385
|
-
Polygon: The represention of the IPE section.
|
|
386
|
-
"""
|
|
387
|
-
return self._polygon
|
|
388
|
-
|
|
389
|
-
@property
|
|
390
|
-
def h(self) -> float:
|
|
391
|
-
"""Returns height of IPE section.
|
|
392
|
-
|
|
393
|
-
Returns:
|
|
394
|
-
float: Height h of IPE section.
|
|
395
|
-
"""
|
|
396
|
-
return self._h
|
|
397
|
-
|
|
398
|
-
@property
|
|
399
|
-
def b(self) -> float:
|
|
400
|
-
"""Returns width of IPE section.
|
|
401
|
-
|
|
402
|
-
Returns:
|
|
403
|
-
float: Width b of IPE section.
|
|
404
|
-
"""
|
|
405
|
-
return self._b
|
|
406
|
-
|
|
407
|
-
@property
|
|
408
|
-
def tw(self) -> float:
|
|
409
|
-
"""Returns thickness of web of IPE section.
|
|
410
|
-
|
|
411
|
-
Returns:
|
|
412
|
-
float: Web thickness tw of IPE section.
|
|
413
|
-
"""
|
|
414
|
-
return self._tw
|
|
415
|
-
|
|
416
|
-
@property
|
|
417
|
-
def tf(self) -> float:
|
|
418
|
-
"""Returns thickness of flange of IPE section.
|
|
419
|
-
|
|
420
|
-
Returns:
|
|
421
|
-
float: Flange thickness tw of IPE section.
|
|
422
|
-
"""
|
|
423
|
-
return self._tf
|
|
424
|
-
|
|
425
|
-
@property
|
|
426
|
-
def r(self) -> float:
|
|
427
|
-
"""Returns fillet radius of IPE section.
|
|
428
|
-
|
|
429
|
-
Returns:
|
|
430
|
-
float: Fillet radius r of IPE section.
|
|
431
|
-
"""
|
|
432
|
-
return self._r
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
class HE(BaseProfile):
|
|
436
|
-
"""Simple class for representing an HE profile.
|
|
437
|
-
|
|
438
|
-
HE A, HE B, HE M 100-1000 in accordance with Standard Euronorm 53-62.
|
|
439
|
-
"""
|
|
440
|
-
|
|
441
|
-
parameters = {
|
|
442
|
-
'HEA100': {'h': 96.0, 'b': 100.0, 'tw': 5.0, 'tf': 8.0, 'r': 12.0},
|
|
443
|
-
'HEA120': {'h': 114.0, 'b': 120.0, 'tw': 5.0, 'tf': 8.0, 'r': 12.0},
|
|
444
|
-
'HEA140': {'h': 133.0, 'b': 140.0, 'tw': 5.5, 'tf': 8.5, 'r': 12.0},
|
|
445
|
-
'HEA160': {'h': 152.0, 'b': 160.0, 'tw': 6.0, 'tf': 9.0, 'r': 15.0},
|
|
446
|
-
'HEA180': {'h': 171.0, 'b': 180.0, 'tw': 6.0, 'tf': 9.5, 'r': 15.0},
|
|
447
|
-
'HEA200': {'h': 190.0, 'b': 200.0, 'tw': 6.5, 'tf': 10.0, 'r': 18.0},
|
|
448
|
-
'HEA220': {'h': 210.0, 'b': 220.0, 'tw': 7.0, 'tf': 11.0, 'r': 18.0},
|
|
449
|
-
'HEA240': {'h': 230.0, 'b': 240.0, 'tw': 7.5, 'tf': 12.0, 'r': 21.0},
|
|
450
|
-
'HEA260': {'h': 250.0, 'b': 260.0, 'tw': 7.5, 'tf': 12.5, 'r': 24.0},
|
|
451
|
-
'HEA280': {'h': 270.0, 'b': 280.0, 'tw': 8.0, 'tf': 13.0, 'r': 24.0},
|
|
452
|
-
'HEA300': {'h': 290.0, 'b': 300.0, 'tw': 8.5, 'tf': 14.0, 'r': 27.0},
|
|
453
|
-
'HEA320': {'h': 310.0, 'b': 300.0, 'tw': 9.0, 'tf': 15.5, 'r': 27.0},
|
|
454
|
-
'HEA340': {'h': 330.0, 'b': 300.0, 'tw': 9.5, 'tf': 16.5, 'r': 27.0},
|
|
455
|
-
'HEA360': {'h': 350.0, 'b': 300.0, 'tw': 10.0, 'tf': 17.5, 'r': 27.0},
|
|
456
|
-
'HEA400': {'h': 390.0, 'b': 300.0, 'tw': 11.0, 'tf': 19.0, 'r': 27.0},
|
|
457
|
-
'HEA450': {'h': 440.0, 'b': 300.0, 'tw': 11.5, 'tf': 21.0, 'r': 27.0},
|
|
458
|
-
'HEA500': {'h': 490.0, 'b': 300.0, 'tw': 12.0, 'tf': 23.0, 'r': 27.0},
|
|
459
|
-
'HEA550': {'h': 540.0, 'b': 300.0, 'tw': 12.5, 'tf': 24.0, 'r': 27.0},
|
|
460
|
-
'HEA600': {'h': 590.0, 'b': 300.0, 'tw': 13.0, 'tf': 25.0, 'r': 27.0},
|
|
461
|
-
'HEA650': {'h': 640.0, 'b': 300.0, 'tw': 13.5, 'tf': 26.0, 'r': 27.0},
|
|
462
|
-
'HEA700': {'h': 690.0, 'b': 300.0, 'tw': 14.5, 'tf': 27.0, 'r': 27.0},
|
|
463
|
-
'HEA800': {'h': 790.0, 'b': 300.0, 'tw': 15.0, 'tf': 28.0, 'r': 30.0},
|
|
464
|
-
'HEA900': {'h': 890.0, 'b': 300.0, 'tw': 16.0, 'tf': 30.0, 'r': 30.0},
|
|
465
|
-
'HEA1000': {'h': 990.0, 'b': 300.0, 'tw': 16.5, 'tf': 31.0, 'r': 30.0},
|
|
466
|
-
'HEB100': {'h': 100.0, 'b': 100.0, 'tw': 6.0, 'tf': 10.0, 'r': 12.0},
|
|
467
|
-
'HEB120': {'h': 120.0, 'b': 120.0, 'tw': 6.5, 'tf': 11.0, 'r': 12.0},
|
|
468
|
-
'HEB140': {'h': 140.0, 'b': 140.0, 'tw': 7.0, 'tf': 12.0, 'r': 12.0},
|
|
469
|
-
'HEB160': {'h': 160.0, 'b': 160.0, 'tw': 8.0, 'tf': 13.0, 'r': 15.0},
|
|
470
|
-
'HEB180': {'h': 180.0, 'b': 180.0, 'tw': 8.5, 'tf': 14.0, 'r': 15.0},
|
|
471
|
-
'HEB200': {'h': 200.0, 'b': 200.0, 'tw': 9.0, 'tf': 15.0, 'r': 18.0},
|
|
472
|
-
'HEB220': {'h': 220.0, 'b': 220.0, 'tw': 9.5, 'tf': 16.0, 'r': 18.0},
|
|
473
|
-
'HEB240': {'h': 240.0, 'b': 240.0, 'tw': 10.0, 'tf': 17.0, 'r': 21.0},
|
|
474
|
-
'HEB260': {'h': 260.0, 'b': 260.0, 'tw': 10.0, 'tf': 17.5, 'r': 24.0},
|
|
475
|
-
'HEB280': {'h': 280.0, 'b': 280.0, 'tw': 10.5, 'tf': 18.0, 'r': 24.0},
|
|
476
|
-
'HEB300': {'h': 300.0, 'b': 300.0, 'tw': 11.0, 'tf': 19.0, 'r': 27.0},
|
|
477
|
-
'HEB320': {'h': 320.0, 'b': 300.0, 'tw': 11.5, 'tf': 20.5, 'r': 27.0},
|
|
478
|
-
'HEB340': {'h': 340.0, 'b': 300.0, 'tw': 12.0, 'tf': 21.5, 'r': 27.0},
|
|
479
|
-
'HEB360': {'h': 360.0, 'b': 300.0, 'tw': 12.5, 'tf': 22.5, 'r': 27.0},
|
|
480
|
-
'HEB400': {'h': 400.0, 'b': 300.0, 'tw': 13.5, 'tf': 24.0, 'r': 27.0},
|
|
481
|
-
'HEB450': {'h': 450.0, 'b': 300.0, 'tw': 14.0, 'tf': 26.0, 'r': 27.0},
|
|
482
|
-
'HEB500': {'h': 500.0, 'b': 300.0, 'tw': 14.5, 'tf': 28.0, 'r': 27.0},
|
|
483
|
-
'HEB550': {'h': 550.0, 'b': 300.0, 'tw': 15.0, 'tf': 29.0, 'r': 27.0},
|
|
484
|
-
'HEB600': {'h': 600.0, 'b': 300.0, 'tw': 15.5, 'tf': 30.0, 'r': 27.0},
|
|
485
|
-
'HEB650': {'h': 650.0, 'b': 300.0, 'tw': 16.0, 'tf': 31.0, 'r': 27.0},
|
|
486
|
-
'HEB700': {'h': 700.0, 'b': 300.0, 'tw': 17.0, 'tf': 32.0, 'r': 27.0},
|
|
487
|
-
'HEB800': {'h': 800.0, 'b': 300.0, 'tw': 17.5, 'tf': 33.0, 'r': 30.0},
|
|
488
|
-
'HEB900': {'h': 900.0, 'b': 300.0, 'tw': 18.5, 'tf': 35.0, 'r': 30.0},
|
|
489
|
-
'HEB1000': {
|
|
490
|
-
'h': 1000.0,
|
|
491
|
-
'b': 300.0,
|
|
492
|
-
'tw': 19.0,
|
|
493
|
-
'tf': 36.0,
|
|
494
|
-
'r': 30.0,
|
|
495
|
-
},
|
|
496
|
-
'HEM100': {'h': 120.0, 'b': 106.0, 'tw': 12.0, 'tf': 20.0, 'r': 12.0},
|
|
497
|
-
'HEM120': {'h': 140.0, 'b': 126.0, 'tw': 12.5, 'tf': 21.0, 'r': 12.0},
|
|
498
|
-
'HEM140': {'h': 160.0, 'b': 146.0, 'tw': 13.0, 'tf': 22.0, 'r': 12.0},
|
|
499
|
-
'HEM160': {'h': 180.0, 'b': 166.0, 'tw': 14.0, 'tf': 23.0, 'r': 15.0},
|
|
500
|
-
'HEM180': {'h': 200.0, 'b': 186.0, 'tw': 14.5, 'tf': 24.0, 'r': 15.0},
|
|
501
|
-
'HEM200': {'h': 220.0, 'b': 206.0, 'tw': 15.0, 'tf': 25.0, 'r': 18.0},
|
|
502
|
-
'HEM220': {'h': 240.0, 'b': 226.0, 'tw': 15.5, 'tf': 26.0, 'r': 18.0},
|
|
503
|
-
'HEM240': {'h': 270.0, 'b': 248.0, 'tw': 18.0, 'tf': 32.0, 'r': 21.0},
|
|
504
|
-
'HEM260': {'h': 290.0, 'b': 268.0, 'tw': 18.0, 'tf': 32.5, 'r': 24.0},
|
|
505
|
-
'HEM280': {'h': 310.0, 'b': 288.0, 'tw': 18.5, 'tf': 33.0, 'r': 24.0},
|
|
506
|
-
'HEM300': {'h': 340.0, 'b': 310.0, 'tw': 21.0, 'tf': 39.0, 'r': 27.0},
|
|
507
|
-
'HEM320': {'h': 359.0, 'b': 309.0, 'tw': 21.0, 'tf': 40.0, 'r': 27.0},
|
|
508
|
-
'HEM340': {'h': 377.0, 'b': 309.0, 'tw': 21.0, 'tf': 40.0, 'r': 27.0},
|
|
509
|
-
'HEM360': {'h': 395.0, 'b': 308.0, 'tw': 21.0, 'tf': 40.0, 'r': 27.0},
|
|
510
|
-
'HEM400': {'h': 432.0, 'b': 307.0, 'tw': 21.0, 'tf': 40.0, 'r': 27.0},
|
|
511
|
-
'HEM450': {'h': 478.0, 'b': 307.0, 'tw': 21.0, 'tf': 40.0, 'r': 27.0},
|
|
512
|
-
'HEM500': {'h': 524.0, 'b': 306.0, 'tw': 21.0, 'tf': 40.0, 'r': 27.0},
|
|
513
|
-
'HEM550': {'h': 572.0, 'b': 306.0, 'tw': 21.0, 'tf': 40.0, 'r': 27.0},
|
|
514
|
-
'HEM600': {'h': 620.0, 'b': 305.0, 'tw': 21.0, 'tf': 40.0, 'r': 27.0},
|
|
515
|
-
'HEM650': {'h': 668.0, 'b': 305.0, 'tw': 21.0, 'tf': 40.0, 'r': 27.0},
|
|
516
|
-
'HEM700': {'h': 716.0, 'b': 304.0, 'tw': 21.0, 'tf': 40.0, 'r': 27.0},
|
|
517
|
-
'HEM800': {'h': 814.0, 'b': 303.0, 'tw': 21.0, 'tf': 40.0, 'r': 30.0},
|
|
518
|
-
'HEM900': {'h': 910.0, 'b': 302.0, 'tw': 21.0, 'tf': 40.0, 'r': 30.0},
|
|
519
|
-
'HEM1000': {
|
|
520
|
-
'h': 1008.0,
|
|
521
|
-
'b': 302.0,
|
|
522
|
-
'tw': 21.0,
|
|
523
|
-
'tf': 40.0,
|
|
524
|
-
'r': 30.0,
|
|
525
|
-
},
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
@classmethod
|
|
529
|
-
def get_polygon(cls, name: str) -> Polygon:
|
|
530
|
-
"""Returns a shapely polygon representing an HE section."""
|
|
531
|
-
parameters = cls.parameters.get(name)
|
|
532
|
-
if parameters is None:
|
|
533
|
-
raise ValueError(
|
|
534
|
-
f"Profile '{name}' not found in HE sections. "
|
|
535
|
-
"Select a valid profile (available ones: "
|
|
536
|
-
f"{cls.profiles()})"
|
|
537
|
-
)
|
|
538
|
-
return _create_I_section(**parameters)
|
|
539
|
-
|
|
540
|
-
@classmethod
|
|
541
|
-
def profiles(cls) -> list:
|
|
542
|
-
"""Returns a list containing all available profiles."""
|
|
543
|
-
return list(cls.parameters.keys())
|
|
544
|
-
|
|
545
|
-
def __init__(self, name: str) -> None:
|
|
546
|
-
"""Creates a new HE object."""
|
|
547
|
-
parameters = self.parameters.get(name)
|
|
548
|
-
if parameters is None:
|
|
549
|
-
raise ValueError(
|
|
550
|
-
f"Profile '{name}' not found in HE sections. "
|
|
551
|
-
"Select a valid profile (available ones: "
|
|
552
|
-
f"{self.profiles()})"
|
|
553
|
-
)
|
|
554
|
-
super().__init__()
|
|
555
|
-
self._h = parameters.get('h')
|
|
556
|
-
self._b = parameters.get('b')
|
|
557
|
-
self._tw = parameters.get('tw')
|
|
558
|
-
self._tf = parameters.get('tf')
|
|
559
|
-
self._r = parameters.get('r')
|
|
560
|
-
self._polygon = _create_I_section(**parameters)
|
|
561
|
-
|
|
562
|
-
@property
|
|
563
|
-
def polygon(self) -> Polygon:
|
|
564
|
-
"""Returns shapely Polygon of section.
|
|
565
|
-
|
|
566
|
-
Returns:
|
|
567
|
-
Polygon: The represention of the HE section.
|
|
568
|
-
"""
|
|
569
|
-
return self._polygon
|
|
570
|
-
|
|
571
|
-
@property
|
|
572
|
-
def h(self) -> float:
|
|
573
|
-
"""Returns height of HE section.
|
|
574
|
-
|
|
575
|
-
Returns:
|
|
576
|
-
float: Height h of HE section.
|
|
577
|
-
"""
|
|
578
|
-
return self._h
|
|
579
|
-
|
|
580
|
-
@property
|
|
581
|
-
def b(self) -> float:
|
|
582
|
-
"""Returns width of HE section.
|
|
583
|
-
|
|
584
|
-
Returns:
|
|
585
|
-
float: Width b of HE section.
|
|
586
|
-
"""
|
|
587
|
-
return self._b
|
|
588
|
-
|
|
589
|
-
@property
|
|
590
|
-
def tw(self) -> float:
|
|
591
|
-
"""Returns thickness of web of HE section.
|
|
592
|
-
|
|
593
|
-
Returns:
|
|
594
|
-
float: Web thickness tw of HE section.
|
|
595
|
-
"""
|
|
596
|
-
return self._tw
|
|
597
|
-
|
|
598
|
-
@property
|
|
599
|
-
def tf(self) -> float:
|
|
600
|
-
"""Returns thickness of flange of HE section.
|
|
601
|
-
|
|
602
|
-
Returns:
|
|
603
|
-
float: Flange thickness tw of HE section.
|
|
604
|
-
"""
|
|
605
|
-
return self._tf
|
|
606
|
-
|
|
607
|
-
@property
|
|
608
|
-
def r(self) -> float:
|
|
609
|
-
"""Returns fillet radius of HE section.
|
|
610
|
-
|
|
611
|
-
Returns:
|
|
612
|
-
float: Fillet radius r of HE section.
|
|
613
|
-
"""
|
|
614
|
-
return self._r
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
class UB(BaseProfile):
|
|
618
|
-
"""Simple class for representing a UB profile.
|
|
619
|
-
|
|
620
|
-
Universal Beams.
|
|
621
|
-
"""
|
|
622
|
-
|
|
623
|
-
parameters = {
|
|
624
|
-
'UB127x76x13': {'h': 127.0, 'b': 76.0, 'tw': 4.0, 'tf': 7.6, 'r': 8.0},
|
|
625
|
-
'UB152x89x16': {'h': 152.0, 'b': 89.0, 'tw': 4.5, 'tf': 7.7, 'r': 8.0},
|
|
626
|
-
'UB178x102x19': {
|
|
627
|
-
'h': 178.0,
|
|
628
|
-
'b': 101.0,
|
|
629
|
-
'tw': 4.8,
|
|
630
|
-
'tf': 7.9,
|
|
631
|
-
'r': 8.0,
|
|
632
|
-
},
|
|
633
|
-
'UB203x102x23': {
|
|
634
|
-
'h': 203.0,
|
|
635
|
-
'b': 102.0,
|
|
636
|
-
'tw': 5.4,
|
|
637
|
-
'tf': 9.3,
|
|
638
|
-
'r': 8.0,
|
|
639
|
-
},
|
|
640
|
-
'UB203x133x25': {
|
|
641
|
-
'h': 203.0,
|
|
642
|
-
'b': 133.0,
|
|
643
|
-
'tw': 5.7,
|
|
644
|
-
'tf': 7.8,
|
|
645
|
-
'r': 8.0,
|
|
646
|
-
},
|
|
647
|
-
'UB203x133x30': {
|
|
648
|
-
'h': 207.0,
|
|
649
|
-
'b': 134.0,
|
|
650
|
-
'tw': 6.4,
|
|
651
|
-
'tf': 9.6,
|
|
652
|
-
'r': 8.0,
|
|
653
|
-
},
|
|
654
|
-
'UB254x102x22': {
|
|
655
|
-
'h': 254.0,
|
|
656
|
-
'b': 102.0,
|
|
657
|
-
'tw': 5.7,
|
|
658
|
-
'tf': 6.8,
|
|
659
|
-
'r': 8.0,
|
|
660
|
-
},
|
|
661
|
-
'UB254x102x25': {
|
|
662
|
-
'h': 257.0,
|
|
663
|
-
'b': 102.0,
|
|
664
|
-
'tw': 6.0,
|
|
665
|
-
'tf': 8.4,
|
|
666
|
-
'r': 8.0,
|
|
667
|
-
},
|
|
668
|
-
'UB254x102x28': {
|
|
669
|
-
'h': 260.0,
|
|
670
|
-
'b': 102.0,
|
|
671
|
-
'tw': 6.3,
|
|
672
|
-
'tf': 10.0,
|
|
673
|
-
'r': 8.0,
|
|
674
|
-
},
|
|
675
|
-
'UB254x146x31': {
|
|
676
|
-
'h': 251.0,
|
|
677
|
-
'b': 146.0,
|
|
678
|
-
'tw': 6.0,
|
|
679
|
-
'tf': 8.6,
|
|
680
|
-
'r': 8.0,
|
|
681
|
-
},
|
|
682
|
-
'UB254x146x37': {
|
|
683
|
-
'h': 256.0,
|
|
684
|
-
'b': 146.0,
|
|
685
|
-
'tw': 6.3,
|
|
686
|
-
'tf': 10.9,
|
|
687
|
-
'r': 8.0,
|
|
688
|
-
},
|
|
689
|
-
'UB254x146x43': {
|
|
690
|
-
'h': 260.0,
|
|
691
|
-
'b': 147.0,
|
|
692
|
-
'tw': 7.2,
|
|
693
|
-
'tf': 12.7,
|
|
694
|
-
'r': 8.0,
|
|
695
|
-
},
|
|
696
|
-
'UB305x102x25': {
|
|
697
|
-
'h': 305.0,
|
|
698
|
-
'b': 102.0,
|
|
699
|
-
'tw': 5.8,
|
|
700
|
-
'tf': 7.0,
|
|
701
|
-
'r': 8.0,
|
|
702
|
-
},
|
|
703
|
-
'UB305x102x28': {
|
|
704
|
-
'h': 309.0,
|
|
705
|
-
'b': 102.0,
|
|
706
|
-
'tw': 6.0,
|
|
707
|
-
'tf': 8.8,
|
|
708
|
-
'r': 8.0,
|
|
709
|
-
},
|
|
710
|
-
'UB305x102x33': {
|
|
711
|
-
'h': 313.0,
|
|
712
|
-
'b': 102.0,
|
|
713
|
-
'tw': 6.6,
|
|
714
|
-
'tf': 10.8,
|
|
715
|
-
'r': 8.0,
|
|
716
|
-
},
|
|
717
|
-
'UB305x127x37': {
|
|
718
|
-
'h': 304.0,
|
|
719
|
-
'b': 123.0,
|
|
720
|
-
'tw': 7.1,
|
|
721
|
-
'tf': 10.7,
|
|
722
|
-
'r': 9.0,
|
|
723
|
-
},
|
|
724
|
-
'UB305x127x42': {
|
|
725
|
-
'h': 307.0,
|
|
726
|
-
'b': 124.0,
|
|
727
|
-
'tw': 8.0,
|
|
728
|
-
'tf': 12.1,
|
|
729
|
-
'r': 9.0,
|
|
730
|
-
},
|
|
731
|
-
'UB305x127x48': {
|
|
732
|
-
'h': 311.0,
|
|
733
|
-
'b': 125.0,
|
|
734
|
-
'tw': 9.0,
|
|
735
|
-
'tf': 14.0,
|
|
736
|
-
'r': 9.0,
|
|
737
|
-
},
|
|
738
|
-
'UB305x165x40': {
|
|
739
|
-
'h': 303.0,
|
|
740
|
-
'b': 165.0,
|
|
741
|
-
'tw': 6.0,
|
|
742
|
-
'tf': 10.2,
|
|
743
|
-
'r': 9.0,
|
|
744
|
-
},
|
|
745
|
-
'UB305x165x46': {
|
|
746
|
-
'h': 307.0,
|
|
747
|
-
'b': 166.0,
|
|
748
|
-
'tw': 6.7,
|
|
749
|
-
'tf': 11.8,
|
|
750
|
-
'r': 9.0,
|
|
751
|
-
},
|
|
752
|
-
'UB305x165x54': {
|
|
753
|
-
'h': 310.0,
|
|
754
|
-
'b': 167.0,
|
|
755
|
-
'tw': 7.9,
|
|
756
|
-
'tf': 13.7,
|
|
757
|
-
'r': 9.0,
|
|
758
|
-
},
|
|
759
|
-
'UB356x171x45': {
|
|
760
|
-
'h': 351.0,
|
|
761
|
-
'b': 171.0,
|
|
762
|
-
'tw': 7.0,
|
|
763
|
-
'tf': 9.7,
|
|
764
|
-
'r': 13.0,
|
|
765
|
-
},
|
|
766
|
-
'UB356x171x51': {
|
|
767
|
-
'h': 355.0,
|
|
768
|
-
'b': 172.0,
|
|
769
|
-
'tw': 7.4,
|
|
770
|
-
'tf': 11.5,
|
|
771
|
-
'r': 13.0,
|
|
772
|
-
},
|
|
773
|
-
'UB356x171x57': {
|
|
774
|
-
'h': 358.0,
|
|
775
|
-
'b': 172.0,
|
|
776
|
-
'tw': 8.1,
|
|
777
|
-
'tf': 13.0,
|
|
778
|
-
'r': 13.0,
|
|
779
|
-
},
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
@classmethod
|
|
783
|
-
def get_polygon(cls, name: str) -> Polygon:
|
|
784
|
-
"""Returns a shapely polygon representing a UB section."""
|
|
785
|
-
parameters = cls.parameters.get(name)
|
|
786
|
-
if parameters is None:
|
|
787
|
-
raise ValueError(
|
|
788
|
-
f"Profile '{name}' not found in UB sections. "
|
|
789
|
-
"Select a valid profile (available ones: "
|
|
790
|
-
f"{cls.profiles()})"
|
|
791
|
-
)
|
|
792
|
-
return _create_I_section(**parameters)
|
|
793
|
-
|
|
794
|
-
@classmethod
|
|
795
|
-
def profiles(cls) -> list:
|
|
796
|
-
"""Returns a list containing all available profiles."""
|
|
797
|
-
return list(cls.parameters.keys())
|
|
798
|
-
|
|
799
|
-
def __init__(self, name: str) -> None:
|
|
800
|
-
"""Creates a new UB object."""
|
|
801
|
-
parameters = self.parameters.get(name)
|
|
802
|
-
if parameters is None:
|
|
803
|
-
raise ValueError(
|
|
804
|
-
f"Profile '{name}' not found in UB sections. "
|
|
805
|
-
"Select a valid profile (available ones: "
|
|
806
|
-
f"{self.profiles()})"
|
|
807
|
-
)
|
|
808
|
-
super().__init__()
|
|
809
|
-
self._h = parameters.get('h')
|
|
810
|
-
self._b = parameters.get('b')
|
|
811
|
-
self._tw = parameters.get('tw')
|
|
812
|
-
self._tf = parameters.get('tf')
|
|
813
|
-
self._r = parameters.get('r')
|
|
814
|
-
self._polygon = _create_I_section(**parameters)
|
|
815
|
-
|
|
816
|
-
@property
|
|
817
|
-
def polygon(self) -> Polygon:
|
|
818
|
-
"""Returns shapely Polygon of section.
|
|
819
|
-
|
|
820
|
-
Returns:
|
|
821
|
-
Polygon: The represention of the UB section.
|
|
822
|
-
"""
|
|
823
|
-
return self._polygon
|
|
824
|
-
|
|
825
|
-
@property
|
|
826
|
-
def h(self) -> float:
|
|
827
|
-
"""Returns height of UB section.
|
|
828
|
-
|
|
829
|
-
Returns:
|
|
830
|
-
float: Height h of UB section.
|
|
831
|
-
"""
|
|
832
|
-
return self._h
|
|
833
|
-
|
|
834
|
-
@property
|
|
835
|
-
def b(self) -> float:
|
|
836
|
-
"""Returns width of UB section.
|
|
837
|
-
|
|
838
|
-
Returns:
|
|
839
|
-
float: Width b of UB section.
|
|
840
|
-
"""
|
|
841
|
-
return self._b
|
|
842
|
-
|
|
843
|
-
@property
|
|
844
|
-
def tw(self) -> float:
|
|
845
|
-
"""Returns thickness of web of UB section.
|
|
846
|
-
|
|
847
|
-
Returns:
|
|
848
|
-
float: Web thickness tw of UB section.
|
|
849
|
-
"""
|
|
850
|
-
return self._tw
|
|
851
|
-
|
|
852
|
-
@property
|
|
853
|
-
def tf(self) -> float:
|
|
854
|
-
"""Returns thickness of flange of UB section.
|
|
855
|
-
|
|
856
|
-
Returns:
|
|
857
|
-
float: Flange thickness tw of UB section.
|
|
858
|
-
"""
|
|
859
|
-
return self._tf
|
|
860
|
-
|
|
861
|
-
@property
|
|
862
|
-
def r(self) -> float:
|
|
863
|
-
"""Returns fillet radius of UB section.
|
|
864
|
-
|
|
865
|
-
Returns:
|
|
866
|
-
float: Fillet radius r of UB section.
|
|
867
|
-
"""
|
|
868
|
-
return self._r
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
class UC(BaseProfile):
|
|
872
|
-
"""Simple class for representing a UC profile.
|
|
873
|
-
|
|
874
|
-
Universal Columns.
|
|
875
|
-
"""
|
|
876
|
-
|
|
877
|
-
parameters = {
|
|
878
|
-
'UC152x152x23': {
|
|
879
|
-
'h': 152.0,
|
|
880
|
-
'b': 152.0,
|
|
881
|
-
'tw': 5.8,
|
|
882
|
-
'tf': 6.8,
|
|
883
|
-
'r': 8.0,
|
|
884
|
-
},
|
|
885
|
-
'UC152x152x30': {
|
|
886
|
-
'h': 158.0,
|
|
887
|
-
'b': 153.0,
|
|
888
|
-
'tw': 6.5,
|
|
889
|
-
'tf': 9.4,
|
|
890
|
-
'r': 8.0,
|
|
891
|
-
},
|
|
892
|
-
'UC152x152x37': {
|
|
893
|
-
'h': 162.0,
|
|
894
|
-
'b': 154.0,
|
|
895
|
-
'tw': 8.0,
|
|
896
|
-
'tf': 11.5,
|
|
897
|
-
'r': 8.0,
|
|
898
|
-
},
|
|
899
|
-
'UC152x152x44': {
|
|
900
|
-
'h': 166.0,
|
|
901
|
-
'b': 156.0,
|
|
902
|
-
'tw': 9.5,
|
|
903
|
-
'tf': 13.6,
|
|
904
|
-
'r': 8.0,
|
|
905
|
-
},
|
|
906
|
-
'UC152x152x51': {
|
|
907
|
-
'h': 170.0,
|
|
908
|
-
'b': 157.0,
|
|
909
|
-
'tw': 11.0,
|
|
910
|
-
'tf': 15.7,
|
|
911
|
-
'r': 8.0,
|
|
912
|
-
},
|
|
913
|
-
'UC203x203x46': {
|
|
914
|
-
'h': 203.0,
|
|
915
|
-
'b': 204.0,
|
|
916
|
-
'tw': 7.2,
|
|
917
|
-
'tf': 11.0,
|
|
918
|
-
'r': 13.0,
|
|
919
|
-
},
|
|
920
|
-
'UC203x203x52': {
|
|
921
|
-
'h': 206.0,
|
|
922
|
-
'b': 204.0,
|
|
923
|
-
'tw': 7.9,
|
|
924
|
-
'tf': 12.5,
|
|
925
|
-
'r': 13.0,
|
|
926
|
-
},
|
|
927
|
-
'UC203x203x60': {
|
|
928
|
-
'h': 210.0,
|
|
929
|
-
'b': 206.0,
|
|
930
|
-
'tw': 9.4,
|
|
931
|
-
'tf': 14.2,
|
|
932
|
-
'r': 13.0,
|
|
933
|
-
},
|
|
934
|
-
'UC203x203x71': {
|
|
935
|
-
'h': 216.0,
|
|
936
|
-
'b': 206.0,
|
|
937
|
-
'tw': 10.0,
|
|
938
|
-
'tf': 17.3,
|
|
939
|
-
'r': 13.0,
|
|
940
|
-
},
|
|
941
|
-
'UC203x203x86': {
|
|
942
|
-
'h': 222.0,
|
|
943
|
-
'b': 209.0,
|
|
944
|
-
'tw': 12.7,
|
|
945
|
-
'tf': 20.5,
|
|
946
|
-
'r': 13.0,
|
|
947
|
-
},
|
|
948
|
-
'UC203x203x100': {
|
|
949
|
-
'h': 229.0,
|
|
950
|
-
'b': 210.0,
|
|
951
|
-
'tw': 14.5,
|
|
952
|
-
'tf': 23.7,
|
|
953
|
-
'r': 13.0,
|
|
954
|
-
},
|
|
955
|
-
'UC203x203x113': {
|
|
956
|
-
'h': 235.0,
|
|
957
|
-
'b': 212.0,
|
|
958
|
-
'tw': 16.3,
|
|
959
|
-
'tf': 26.9,
|
|
960
|
-
'r': 13.0,
|
|
961
|
-
},
|
|
962
|
-
'UC203x203x127': {
|
|
963
|
-
'h': 241.0,
|
|
964
|
-
'b': 214.0,
|
|
965
|
-
'tw': 18.1,
|
|
966
|
-
'tf': 30.1,
|
|
967
|
-
'r': 13.0,
|
|
968
|
-
},
|
|
969
|
-
'UC254x254x73': {
|
|
970
|
-
'h': 254.0,
|
|
971
|
-
'b': 255.0,
|
|
972
|
-
'tw': 8.6,
|
|
973
|
-
'tf': 14.2,
|
|
974
|
-
'r': 20.0,
|
|
975
|
-
},
|
|
976
|
-
'UC254x254x81': {
|
|
977
|
-
'h': 256.0,
|
|
978
|
-
'b': 255.0,
|
|
979
|
-
'tw': 9.4,
|
|
980
|
-
'tf': 15.6,
|
|
981
|
-
'r': 20.0,
|
|
982
|
-
},
|
|
983
|
-
'UC254x254x89': {
|
|
984
|
-
'h': 260.0,
|
|
985
|
-
'b': 256.0,
|
|
986
|
-
'tw': 10.3,
|
|
987
|
-
'tf': 17.3,
|
|
988
|
-
'r': 20.0,
|
|
989
|
-
},
|
|
990
|
-
'UC254x254x101': {
|
|
991
|
-
'h': 264.0,
|
|
992
|
-
'b': 257.0,
|
|
993
|
-
'tw': 11.9,
|
|
994
|
-
'tf': 19.6,
|
|
995
|
-
'r': 20.0,
|
|
996
|
-
},
|
|
997
|
-
'UC254x254x107': {
|
|
998
|
-
'h': 267.0,
|
|
999
|
-
'b': 259.0,
|
|
1000
|
-
'tw': 12.8,
|
|
1001
|
-
'tf': 20.5,
|
|
1002
|
-
'r': 20.0,
|
|
1003
|
-
},
|
|
1004
|
-
'UC254x254x115': {
|
|
1005
|
-
'h': 269.0,
|
|
1006
|
-
'b': 259.0,
|
|
1007
|
-
'tw': 13.5,
|
|
1008
|
-
'tf': 22.1,
|
|
1009
|
-
'r': 20.0,
|
|
1010
|
-
},
|
|
1011
|
-
'UC254x254x132': {
|
|
1012
|
-
'h': 276.0,
|
|
1013
|
-
'b': 261.0,
|
|
1014
|
-
'tw': 15.3,
|
|
1015
|
-
'tf': 25.3,
|
|
1016
|
-
'r': 20.0,
|
|
1017
|
-
},
|
|
1018
|
-
'UC254x254x149': {
|
|
1019
|
-
'h': 282.0,
|
|
1020
|
-
'b': 263.0,
|
|
1021
|
-
'tw': 17.3,
|
|
1022
|
-
'tf': 28.4,
|
|
1023
|
-
'r': 20.0,
|
|
1024
|
-
},
|
|
1025
|
-
'UC254x254x167': {
|
|
1026
|
-
'h': 289.0,
|
|
1027
|
-
'b': 265.0,
|
|
1028
|
-
'tw': 19.2,
|
|
1029
|
-
'tf': 31.7,
|
|
1030
|
-
'r': 20.0,
|
|
1031
|
-
},
|
|
1032
|
-
'UC305x305x97': {
|
|
1033
|
-
'h': 308.0,
|
|
1034
|
-
'b': 305.0,
|
|
1035
|
-
'tw': 9.9,
|
|
1036
|
-
'tf': 15.4,
|
|
1037
|
-
'r': 20.0,
|
|
1038
|
-
},
|
|
1039
|
-
'UC305x305x107': {
|
|
1040
|
-
'h': 311.0,
|
|
1041
|
-
'b': 306.0,
|
|
1042
|
-
'tw': 10.9,
|
|
1043
|
-
'tf': 17.0,
|
|
1044
|
-
'r': 20.0,
|
|
1045
|
-
},
|
|
1046
|
-
}
|
|
1047
|
-
|
|
1048
|
-
@classmethod
|
|
1049
|
-
def get_polygon(cls, name: str) -> Polygon:
|
|
1050
|
-
"""Returns a shapely polygon representing a UC section."""
|
|
1051
|
-
parameters = cls.parameters.get(name)
|
|
1052
|
-
if parameters is None:
|
|
1053
|
-
raise ValueError(
|
|
1054
|
-
f"Profile '{name}' not found in UC sections. "
|
|
1055
|
-
"Select a valid profile (available ones: "
|
|
1056
|
-
f"{cls.profiles()})"
|
|
1057
|
-
)
|
|
1058
|
-
return _create_I_section(**parameters)
|
|
1059
|
-
|
|
1060
|
-
@classmethod
|
|
1061
|
-
def profiles(cls) -> list:
|
|
1062
|
-
"""Returns a list containing all available profiles."""
|
|
1063
|
-
return list(cls.parameters.keys())
|
|
1064
|
-
|
|
1065
|
-
def __init__(self, name: str) -> None:
|
|
1066
|
-
"""Creates a new UC object."""
|
|
1067
|
-
parameters = self.parameters.get(name)
|
|
1068
|
-
if parameters is None:
|
|
1069
|
-
raise ValueError(
|
|
1070
|
-
f"Profile '{name}' not found in UC sections. "
|
|
1071
|
-
"Select a valid profile (available ones: "
|
|
1072
|
-
f"{self.profiles()})"
|
|
1073
|
-
)
|
|
1074
|
-
super().__init__()
|
|
1075
|
-
self._h = parameters.get('h')
|
|
1076
|
-
self._b = parameters.get('b')
|
|
1077
|
-
self._tw = parameters.get('tw')
|
|
1078
|
-
self._tf = parameters.get('tf')
|
|
1079
|
-
self._r = parameters.get('r')
|
|
1080
|
-
self._polygon = _create_I_section(**parameters)
|
|
1081
|
-
|
|
1082
|
-
@property
|
|
1083
|
-
def polygon(self) -> Polygon:
|
|
1084
|
-
"""Returns shapely Polygon of section.
|
|
1085
|
-
|
|
1086
|
-
Returns:
|
|
1087
|
-
Polygon: The represention of the UC section.
|
|
1088
|
-
"""
|
|
1089
|
-
return self._polygon
|
|
1090
|
-
|
|
1091
|
-
@property
|
|
1092
|
-
def h(self) -> float:
|
|
1093
|
-
"""Returns height of UC section.
|
|
1094
|
-
|
|
1095
|
-
Returns:
|
|
1096
|
-
float: Height h of UC section.
|
|
1097
|
-
"""
|
|
1098
|
-
return self._h
|
|
1099
|
-
|
|
1100
|
-
@property
|
|
1101
|
-
def b(self) -> float:
|
|
1102
|
-
"""Returns width of UC section.
|
|
1103
|
-
|
|
1104
|
-
Returns:
|
|
1105
|
-
float: Width b of UC section.
|
|
1106
|
-
"""
|
|
1107
|
-
return self._b
|
|
1108
|
-
|
|
1109
|
-
@property
|
|
1110
|
-
def tw(self) -> float:
|
|
1111
|
-
"""Returns thickness of web of UC section.
|
|
1112
|
-
|
|
1113
|
-
Returns:
|
|
1114
|
-
float: Web thickness tw of UC section.
|
|
1115
|
-
"""
|
|
1116
|
-
return self._tw
|
|
1117
|
-
|
|
1118
|
-
@property
|
|
1119
|
-
def tf(self) -> float:
|
|
1120
|
-
"""Returns thickness of flange of UC section.
|
|
1121
|
-
|
|
1122
|
-
Returns:
|
|
1123
|
-
float: Flange thickness tw of UC section.
|
|
1124
|
-
"""
|
|
1125
|
-
return self._tf
|
|
1126
|
-
|
|
1127
|
-
@property
|
|
1128
|
-
def r(self) -> float:
|
|
1129
|
-
"""Returns fillet radius of UC section.
|
|
1130
|
-
|
|
1131
|
-
Returns:
|
|
1132
|
-
float: Fillet radius r of UC section.
|
|
1133
|
-
"""
|
|
1134
|
-
return self._r
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
class UBP(BaseProfile):
|
|
1138
|
-
"""Simple class for representing a UBP profile.
|
|
1139
|
-
|
|
1140
|
-
Universal Bearing Pile.
|
|
1141
|
-
"""
|
|
1142
|
-
|
|
1143
|
-
parameters = {
|
|
1144
|
-
'UBP203x203x45': {
|
|
1145
|
-
'h': 200.0,
|
|
1146
|
-
'b': 206.0,
|
|
1147
|
-
'tw': 9.5,
|
|
1148
|
-
'tf': 9.5,
|
|
1149
|
-
'r': 10.0,
|
|
1150
|
-
},
|
|
1151
|
-
'UBP203x203x54': {
|
|
1152
|
-
'h': 204.0,
|
|
1153
|
-
'b': 208.0,
|
|
1154
|
-
'tw': 11.3,
|
|
1155
|
-
'tf': 11.4,
|
|
1156
|
-
'r': 10.0,
|
|
1157
|
-
},
|
|
1158
|
-
'UBP254x254x63': {
|
|
1159
|
-
'h': 247.0,
|
|
1160
|
-
'b': 257.0,
|
|
1161
|
-
'tw': 10.6,
|
|
1162
|
-
'tf': 10.7,
|
|
1163
|
-
'r': 20.0,
|
|
1164
|
-
},
|
|
1165
|
-
'UBP254x254x71': {
|
|
1166
|
-
'h': 250.0,
|
|
1167
|
-
'b': 258.0,
|
|
1168
|
-
'tw': 12.0,
|
|
1169
|
-
'tf': 12.0,
|
|
1170
|
-
'r': 20.0,
|
|
1171
|
-
},
|
|
1172
|
-
'UBP254x254x85': {
|
|
1173
|
-
'h': 254.0,
|
|
1174
|
-
'b': 260.0,
|
|
1175
|
-
'tw': 14.4,
|
|
1176
|
-
'tf': 14.3,
|
|
1177
|
-
'r': 20.0,
|
|
1178
|
-
},
|
|
1179
|
-
'UBP305x305x79': {
|
|
1180
|
-
'h': 299.0,
|
|
1181
|
-
'b': 306.0,
|
|
1182
|
-
'tw': 11.0,
|
|
1183
|
-
'tf': 11.1,
|
|
1184
|
-
'r': 20.0,
|
|
1185
|
-
},
|
|
1186
|
-
'UBP305x305x88': {
|
|
1187
|
-
'h': 302.0,
|
|
1188
|
-
'b': 308.0,
|
|
1189
|
-
'tw': 12.4,
|
|
1190
|
-
'tf': 12.3,
|
|
1191
|
-
'r': 20.0,
|
|
1192
|
-
},
|
|
1193
|
-
'UBP305x305x95': {
|
|
1194
|
-
'h': 304.0,
|
|
1195
|
-
'b': 309.0,
|
|
1196
|
-
'tw': 13.3,
|
|
1197
|
-
'tf': 13.3,
|
|
1198
|
-
'r': 20.0,
|
|
1199
|
-
},
|
|
1200
|
-
'UBP305x305x110': {
|
|
1201
|
-
'h': 308.0,
|
|
1202
|
-
'b': 311.0,
|
|
1203
|
-
'tw': 15.3,
|
|
1204
|
-
'tf': 15.4,
|
|
1205
|
-
'r': 20.0,
|
|
1206
|
-
},
|
|
1207
|
-
'UBP305x305x126': {
|
|
1208
|
-
'h': 312.0,
|
|
1209
|
-
'b': 313.0,
|
|
1210
|
-
'tw': 17.5,
|
|
1211
|
-
'tf': 17.6,
|
|
1212
|
-
'r': 20.0,
|
|
1213
|
-
},
|
|
1214
|
-
'UBP305x305x149': {
|
|
1215
|
-
'h': 318.0,
|
|
1216
|
-
'b': 316.0,
|
|
1217
|
-
'tw': 20.6,
|
|
1218
|
-
'tf': 20.7,
|
|
1219
|
-
'r': 20.0,
|
|
1220
|
-
},
|
|
1221
|
-
'UBP305x305x186': {
|
|
1222
|
-
'h': 328.0,
|
|
1223
|
-
'b': 321.0,
|
|
1224
|
-
'tw': 25.5,
|
|
1225
|
-
'tf': 25.6,
|
|
1226
|
-
'r': 2.0,
|
|
1227
|
-
},
|
|
1228
|
-
'UBP305x305x223': {
|
|
1229
|
-
'h': 338.0,
|
|
1230
|
-
'b': 326.0,
|
|
1231
|
-
'tw': 30.3,
|
|
1232
|
-
'tf': 30.4,
|
|
1233
|
-
'r': 20.0,
|
|
1234
|
-
},
|
|
1235
|
-
'UBP356x368x109': {
|
|
1236
|
-
'h': 346.0,
|
|
1237
|
-
'b': 371.0,
|
|
1238
|
-
'tw': 12.8,
|
|
1239
|
-
'tf': 12.9,
|
|
1240
|
-
'r': 20.0,
|
|
1241
|
-
},
|
|
1242
|
-
'UBP356x368x133': {
|
|
1243
|
-
'h': 352.0,
|
|
1244
|
-
'b': 374.0,
|
|
1245
|
-
'tw': 15.6,
|
|
1246
|
-
'tf': 15.7,
|
|
1247
|
-
'r': 20.0,
|
|
1248
|
-
},
|
|
1249
|
-
'UBP356x368x152': {
|
|
1250
|
-
'h': 356.0,
|
|
1251
|
-
'b': 376.0,
|
|
1252
|
-
'tw': 17.8,
|
|
1253
|
-
'tf': 17.9,
|
|
1254
|
-
'r': 20.0,
|
|
1255
|
-
},
|
|
1256
|
-
'UBP356x368x174': {
|
|
1257
|
-
'h': 361.0,
|
|
1258
|
-
'b': 378.0,
|
|
1259
|
-
'tw': 20.3,
|
|
1260
|
-
'tf': 20.4,
|
|
1261
|
-
'r': 20.0,
|
|
1262
|
-
},
|
|
1263
|
-
}
|
|
1264
|
-
|
|
1265
|
-
@classmethod
|
|
1266
|
-
def get_polygon(cls, name: str) -> Polygon:
|
|
1267
|
-
"""Returns a shapely polygon representing a UBP section."""
|
|
1268
|
-
parameters = cls.parameters.get(name)
|
|
1269
|
-
if parameters is None:
|
|
1270
|
-
raise ValueError(
|
|
1271
|
-
f"Profile '{name}' not found in UBP sections. "
|
|
1272
|
-
"Select a valid profile (available ones: "
|
|
1273
|
-
f"{cls.profiles()})"
|
|
1274
|
-
)
|
|
1275
|
-
return _create_I_section(**parameters)
|
|
1276
|
-
|
|
1277
|
-
@classmethod
|
|
1278
|
-
def profiles(cls) -> list:
|
|
1279
|
-
"""Returns a list containing all available profiles."""
|
|
1280
|
-
return list(cls.parameters.keys())
|
|
1281
|
-
|
|
1282
|
-
def __init__(self, name: str) -> None:
|
|
1283
|
-
"""Creates a new UBP object."""
|
|
1284
|
-
parameters = self.parameters.get(name)
|
|
1285
|
-
if parameters is None:
|
|
1286
|
-
raise ValueError(
|
|
1287
|
-
f"Profile '{name}' not found in UBP sections. "
|
|
1288
|
-
"Select a valid profile (available ones: "
|
|
1289
|
-
f"{self.profiles()})"
|
|
1290
|
-
)
|
|
1291
|
-
super().__init__()
|
|
1292
|
-
self._h = parameters.get('h')
|
|
1293
|
-
self._b = parameters.get('b')
|
|
1294
|
-
self._tw = parameters.get('tw')
|
|
1295
|
-
self._tf = parameters.get('tf')
|
|
1296
|
-
self._r = parameters.get('r')
|
|
1297
|
-
self._polygon = _create_I_section(**parameters)
|
|
1298
|
-
|
|
1299
|
-
@property
|
|
1300
|
-
def polygon(self) -> Polygon:
|
|
1301
|
-
"""Returns shapely Polygon of section.
|
|
1302
|
-
|
|
1303
|
-
Returns:
|
|
1304
|
-
Polygon: The represention of the UBP section.
|
|
1305
|
-
"""
|
|
1306
|
-
return self._polygon
|
|
1307
|
-
|
|
1308
|
-
@property
|
|
1309
|
-
def h(self) -> float:
|
|
1310
|
-
"""Returns height of UBP section.
|
|
1311
|
-
|
|
1312
|
-
Returns:
|
|
1313
|
-
float: Height h of UBP section.
|
|
1314
|
-
"""
|
|
1315
|
-
return self._h
|
|
1316
|
-
|
|
1317
|
-
@property
|
|
1318
|
-
def b(self) -> float:
|
|
1319
|
-
"""Returns width of UBP section.
|
|
1320
|
-
|
|
1321
|
-
Returns:
|
|
1322
|
-
float: Width b of UBP section.
|
|
1323
|
-
"""
|
|
1324
|
-
return self._b
|
|
1325
|
-
|
|
1326
|
-
@property
|
|
1327
|
-
def tw(self) -> float:
|
|
1328
|
-
"""Returns thickness of web of UBP section.
|
|
1329
|
-
|
|
1330
|
-
Returns:
|
|
1331
|
-
float: Web thickness tw of UBP section.
|
|
1332
|
-
"""
|
|
1333
|
-
return self._tw
|
|
1334
|
-
|
|
1335
|
-
@property
|
|
1336
|
-
def tf(self) -> float:
|
|
1337
|
-
"""Returns thickness of flange of UBP section.
|
|
1338
|
-
|
|
1339
|
-
Returns:
|
|
1340
|
-
float: Flange thickness tw of UBP section.
|
|
1341
|
-
"""
|
|
1342
|
-
return self._tf
|
|
1343
|
-
|
|
1344
|
-
@property
|
|
1345
|
-
def r(self) -> float:
|
|
1346
|
-
"""Returns fillet radius of UBP section.
|
|
1347
|
-
|
|
1348
|
-
Returns:
|
|
1349
|
-
float: Fillet radius r of UBP section.
|
|
1350
|
-
"""
|
|
1351
|
-
return self._r
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
class IPN(BaseProfile):
|
|
1355
|
-
"""Simple class for representing an IPN profile.
|
|
1356
|
-
|
|
1357
|
-
IPN in accordance with standard.
|
|
1358
|
-
|
|
1359
|
-
14% slope in flange.
|
|
1360
|
-
"""
|
|
1361
|
-
|
|
1362
|
-
parameters = {
|
|
1363
|
-
'IPN80': {
|
|
1364
|
-
'h': 80.0,
|
|
1365
|
-
'b': 42.0,
|
|
1366
|
-
'tw': 3.9,
|
|
1367
|
-
'tf': 5.9,
|
|
1368
|
-
'r1': 3.9,
|
|
1369
|
-
'r2': 2.3,
|
|
1370
|
-
'd': 59.0,
|
|
1371
|
-
},
|
|
1372
|
-
'IPN100': {
|
|
1373
|
-
'h': 100.0,
|
|
1374
|
-
'b': 50.0,
|
|
1375
|
-
'tw': 4.5,
|
|
1376
|
-
'tf': 6.8,
|
|
1377
|
-
'r1': 4.5,
|
|
1378
|
-
'r2': 2.7,
|
|
1379
|
-
'd': 75.7,
|
|
1380
|
-
},
|
|
1381
|
-
'IPN120': {
|
|
1382
|
-
'h': 120.0,
|
|
1383
|
-
'b': 58.0,
|
|
1384
|
-
'tw': 5.1,
|
|
1385
|
-
'tf': 7.7,
|
|
1386
|
-
'r1': 5.1,
|
|
1387
|
-
'r2': 3.1,
|
|
1388
|
-
'd': 92.4,
|
|
1389
|
-
},
|
|
1390
|
-
'IPN140': {
|
|
1391
|
-
'h': 140.0,
|
|
1392
|
-
'b': 66.0,
|
|
1393
|
-
'tw': 5.7,
|
|
1394
|
-
'tf': 8.6,
|
|
1395
|
-
'r1': 5.7,
|
|
1396
|
-
'r2': 3.4,
|
|
1397
|
-
'd': 109.1,
|
|
1398
|
-
},
|
|
1399
|
-
'IPN160': {
|
|
1400
|
-
'h': 160.0,
|
|
1401
|
-
'b': 74.0,
|
|
1402
|
-
'tw': 6.3,
|
|
1403
|
-
'tf': 9.5,
|
|
1404
|
-
'r1': 6.3,
|
|
1405
|
-
'r2': 3.8,
|
|
1406
|
-
'd': 125.8,
|
|
1407
|
-
},
|
|
1408
|
-
'IPN180': {
|
|
1409
|
-
'h': 180.0,
|
|
1410
|
-
'b': 82.0,
|
|
1411
|
-
'tw': 6.9,
|
|
1412
|
-
'tf': 10.4,
|
|
1413
|
-
'r1': 6.9,
|
|
1414
|
-
'r2': 4.1,
|
|
1415
|
-
'd': 142.4,
|
|
1416
|
-
},
|
|
1417
|
-
'IPN200': {
|
|
1418
|
-
'h': 200.0,
|
|
1419
|
-
'b': 90.0,
|
|
1420
|
-
'tw': 7.5,
|
|
1421
|
-
'tf': 11.3,
|
|
1422
|
-
'r1': 7.5,
|
|
1423
|
-
'r2': 4.5,
|
|
1424
|
-
'd': 159.1,
|
|
1425
|
-
},
|
|
1426
|
-
'IPN220': {
|
|
1427
|
-
'h': 220.0,
|
|
1428
|
-
'b': 98.0,
|
|
1429
|
-
'tw': 8.1,
|
|
1430
|
-
'tf': 12.2,
|
|
1431
|
-
'r1': 8.1,
|
|
1432
|
-
'r2': 4.9,
|
|
1433
|
-
'd': 175.8,
|
|
1434
|
-
},
|
|
1435
|
-
'IPN240': {
|
|
1436
|
-
'h': 240.0,
|
|
1437
|
-
'b': 106.0,
|
|
1438
|
-
'tw': 8.7,
|
|
1439
|
-
'tf': 13.1,
|
|
1440
|
-
'r1': 8.7,
|
|
1441
|
-
'r2': 5.2,
|
|
1442
|
-
'd': 192.5,
|
|
1443
|
-
},
|
|
1444
|
-
'IPN260': {
|
|
1445
|
-
'h': 260.0,
|
|
1446
|
-
'b': 113.0,
|
|
1447
|
-
'tw': 9.4,
|
|
1448
|
-
'tf': 14.1,
|
|
1449
|
-
'r1': 9.4,
|
|
1450
|
-
'r2': 5.6,
|
|
1451
|
-
'd': 208.9,
|
|
1452
|
-
},
|
|
1453
|
-
'IPN280': {
|
|
1454
|
-
'h': 280.0,
|
|
1455
|
-
'b': 119.0,
|
|
1456
|
-
'tw': 10.1,
|
|
1457
|
-
'tf': 15.2,
|
|
1458
|
-
'r1': 10.1,
|
|
1459
|
-
'r2': 6.1,
|
|
1460
|
-
'd': 225.1,
|
|
1461
|
-
},
|
|
1462
|
-
'IPN300': {
|
|
1463
|
-
'h': 300.0,
|
|
1464
|
-
'b': 125.0,
|
|
1465
|
-
'tw': 10.8,
|
|
1466
|
-
'tf': 16.2,
|
|
1467
|
-
'r1': 10.8,
|
|
1468
|
-
'r2': 6.5,
|
|
1469
|
-
'd': 241.6,
|
|
1470
|
-
},
|
|
1471
|
-
'IPN320': {
|
|
1472
|
-
'h': 320.0,
|
|
1473
|
-
'b': 131.0,
|
|
1474
|
-
'tw': 11.5,
|
|
1475
|
-
'tf': 17.3,
|
|
1476
|
-
'r1': 11.5,
|
|
1477
|
-
'r2': 6.9,
|
|
1478
|
-
'd': 257.9,
|
|
1479
|
-
},
|
|
1480
|
-
'IPN340': {
|
|
1481
|
-
'h': 340.0,
|
|
1482
|
-
'b': 137.0,
|
|
1483
|
-
'tw': 12.2,
|
|
1484
|
-
'tf': 18.3,
|
|
1485
|
-
'r1': 12.2,
|
|
1486
|
-
'r2': 7.3,
|
|
1487
|
-
'd': 274.3,
|
|
1488
|
-
},
|
|
1489
|
-
'IPN360': {
|
|
1490
|
-
'h': 360.0,
|
|
1491
|
-
'b': 143.0,
|
|
1492
|
-
'tw': 13.0,
|
|
1493
|
-
'tf': 19.5,
|
|
1494
|
-
'r1': 13.0,
|
|
1495
|
-
'r2': 7.8,
|
|
1496
|
-
'd': 290.2,
|
|
1497
|
-
},
|
|
1498
|
-
'IPN380': {
|
|
1499
|
-
'h': 380.0,
|
|
1500
|
-
'b': 149.0,
|
|
1501
|
-
'tw': 13.7,
|
|
1502
|
-
'tf': 20.5,
|
|
1503
|
-
'r1': 13.7,
|
|
1504
|
-
'r2': 8.2,
|
|
1505
|
-
'd': 306.7,
|
|
1506
|
-
},
|
|
1507
|
-
'IPN400': {
|
|
1508
|
-
'h': 400.0,
|
|
1509
|
-
'b': 155.0,
|
|
1510
|
-
'tw': 14.4,
|
|
1511
|
-
'tf': 21.6,
|
|
1512
|
-
'r1': 14.4,
|
|
1513
|
-
'r2': 8.6,
|
|
1514
|
-
'd': 322.9,
|
|
1515
|
-
},
|
|
1516
|
-
'IPN450': {
|
|
1517
|
-
'h': 450.0,
|
|
1518
|
-
'b': 170.0,
|
|
1519
|
-
'tw': 16.2,
|
|
1520
|
-
'tf': 24.3,
|
|
1521
|
-
'r1': 16.2,
|
|
1522
|
-
'r2': 9.7,
|
|
1523
|
-
'd': 363.6,
|
|
1524
|
-
},
|
|
1525
|
-
'IPN500': {
|
|
1526
|
-
'h': 500.0,
|
|
1527
|
-
'b': 185.0,
|
|
1528
|
-
'tw': 18.0,
|
|
1529
|
-
'tf': 27.0,
|
|
1530
|
-
'r1': 18.0,
|
|
1531
|
-
'r2': 10.8,
|
|
1532
|
-
'd': 404.3,
|
|
1533
|
-
},
|
|
1534
|
-
'IPN550': {
|
|
1535
|
-
'h': 550.0,
|
|
1536
|
-
'b': 200.0,
|
|
1537
|
-
'tw': 19.0,
|
|
1538
|
-
'tf': 30.0,
|
|
1539
|
-
'r1': 19.0,
|
|
1540
|
-
'r2': 11.9,
|
|
1541
|
-
'd': 445.6,
|
|
1542
|
-
},
|
|
1543
|
-
'IPN600': {
|
|
1544
|
-
'h': 600.0,
|
|
1545
|
-
'b': 215.0,
|
|
1546
|
-
'tw': 21.6,
|
|
1547
|
-
'tf': 32.4,
|
|
1548
|
-
'r1': 21.6,
|
|
1549
|
-
'r2': 13.0,
|
|
1550
|
-
'd': 485.8,
|
|
1551
|
-
},
|
|
1552
|
-
}
|
|
1553
|
-
|
|
1554
|
-
@classmethod
|
|
1555
|
-
def get_polygon(cls, name: str) -> Polygon:
|
|
1556
|
-
"""Returns a shapely polygon representing an IPN section."""
|
|
1557
|
-
if isinstance(name, (float, int)):
|
|
1558
|
-
name = f'IPN{int(name):0d}'
|
|
1559
|
-
parameters = cls.parameters.get(name)
|
|
1560
|
-
if parameters is None:
|
|
1561
|
-
raise ValueError(
|
|
1562
|
-
f"Profile '{name}' not found in IPN sections. "
|
|
1563
|
-
"Select a valid profile (available ones: "
|
|
1564
|
-
f"{cls.profiles()})"
|
|
1565
|
-
)
|
|
1566
|
-
parameters['slope'] = 0.14
|
|
1567
|
-
return _create_taper_I_section(
|
|
1568
|
-
**{
|
|
1569
|
-
key: parameters[key]
|
|
1570
|
-
for key in parameters
|
|
1571
|
-
if key in ['h', 'b', 'tw', 'tf', 'r1', 'r2', 'slope']
|
|
1572
|
-
}
|
|
1573
|
-
)
|
|
1574
|
-
|
|
1575
|
-
@classmethod
|
|
1576
|
-
def profiles(cls) -> list:
|
|
1577
|
-
"""Returns a list containing all available profiles."""
|
|
1578
|
-
return list(cls.parameters.keys())
|
|
1579
|
-
|
|
1580
|
-
def __init__(self, name: str) -> None:
|
|
1581
|
-
"""Creates a new IPN object."""
|
|
1582
|
-
if isinstance(name, (float, int)):
|
|
1583
|
-
name = f'IPN{int(name):0d}'
|
|
1584
|
-
parameters = self.parameters.get(name)
|
|
1585
|
-
if parameters is None:
|
|
1586
|
-
raise ValueError(
|
|
1587
|
-
f"Profile '{name}' not found in IPN sections. "
|
|
1588
|
-
"Select a valid profile (available ones: "
|
|
1589
|
-
f"{self.profiles()})"
|
|
1590
|
-
)
|
|
1591
|
-
super().__init__()
|
|
1592
|
-
self._h = parameters.get('h')
|
|
1593
|
-
self._b = parameters.get('b')
|
|
1594
|
-
self._tw = parameters.get('tw')
|
|
1595
|
-
self._tf = parameters.get('tf')
|
|
1596
|
-
self._r1 = parameters.get('r1')
|
|
1597
|
-
self._r2 = parameters.get('r2')
|
|
1598
|
-
self._flange_slope = 0.14
|
|
1599
|
-
self._polygon = _create_taper_I_section(
|
|
1600
|
-
h=self._h,
|
|
1601
|
-
b=self._b,
|
|
1602
|
-
tw=self._tw,
|
|
1603
|
-
tf=self._tf,
|
|
1604
|
-
r1=self._r1,
|
|
1605
|
-
r2=self._r2,
|
|
1606
|
-
slope=self._flange_slope,
|
|
1607
|
-
)
|
|
1608
|
-
|
|
1609
|
-
@property
|
|
1610
|
-
def polygon(self) -> Polygon:
|
|
1611
|
-
"""Returns shapely Polygon of section.
|
|
1612
|
-
|
|
1613
|
-
Returns:
|
|
1614
|
-
Polygon: The represention of the IPN section.
|
|
1615
|
-
"""
|
|
1616
|
-
return self._polygon
|
|
1617
|
-
|
|
1618
|
-
@property
|
|
1619
|
-
def h(self) -> float:
|
|
1620
|
-
"""Returns height of IPN section.
|
|
1621
|
-
|
|
1622
|
-
Returns:
|
|
1623
|
-
float: Height h of IPN section.
|
|
1624
|
-
"""
|
|
1625
|
-
return self._h
|
|
1626
|
-
|
|
1627
|
-
@property
|
|
1628
|
-
def b(self) -> float:
|
|
1629
|
-
"""Returns width of IPN section.
|
|
1630
|
-
|
|
1631
|
-
Returns:
|
|
1632
|
-
float: Width b of IPN section.
|
|
1633
|
-
"""
|
|
1634
|
-
return self._b
|
|
1635
|
-
|
|
1636
|
-
@property
|
|
1637
|
-
def tw(self) -> float:
|
|
1638
|
-
"""Returns thickness of web of IPN section.
|
|
1639
|
-
|
|
1640
|
-
Returns:
|
|
1641
|
-
float: Web thickness tw of IPN section.
|
|
1642
|
-
"""
|
|
1643
|
-
return self._tw
|
|
1644
|
-
|
|
1645
|
-
@property
|
|
1646
|
-
def tf(self) -> float:
|
|
1647
|
-
"""Returns thickness of flange of IPN section.
|
|
1648
|
-
|
|
1649
|
-
Returns:
|
|
1650
|
-
float: Flange thickness tw of IPN section.
|
|
1651
|
-
"""
|
|
1652
|
-
return self._tf
|
|
1653
|
-
|
|
1654
|
-
@property
|
|
1655
|
-
def r1(self) -> float:
|
|
1656
|
-
"""Returns fillet radius of IPN section.
|
|
1657
|
-
|
|
1658
|
-
Returns:
|
|
1659
|
-
float: Fillet radius r1 of IPN section.
|
|
1660
|
-
"""
|
|
1661
|
-
return self._r1
|
|
1662
|
-
|
|
1663
|
-
@property
|
|
1664
|
-
def r2(self) -> float:
|
|
1665
|
-
"""Returns fillet radius of IPN section.
|
|
1666
|
-
|
|
1667
|
-
Returns:
|
|
1668
|
-
float: Fillet radius r2 of IPN section.
|
|
1669
|
-
"""
|
|
1670
|
-
return self._r2
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
class UPN(BaseProfile):
|
|
1674
|
-
"""Simple class for representing an UPN profile.
|
|
1675
|
-
|
|
1676
|
-
European standard channels UPN 50 - 400.
|
|
1677
|
-
|
|
1678
|
-
Taper flange Channels.
|
|
1679
|
-
|
|
1680
|
-
14% slope in flange.
|
|
1681
|
-
"""
|
|
1682
|
-
|
|
1683
|
-
parameters = {
|
|
1684
|
-
'UPN50': {
|
|
1685
|
-
'h': 50.0,
|
|
1686
|
-
'b': 38.0,
|
|
1687
|
-
'tw': 5.0,
|
|
1688
|
-
'tf': 7.0,
|
|
1689
|
-
'r1': 7.0,
|
|
1690
|
-
'r2': 4.0,
|
|
1691
|
-
'd': 21.0,
|
|
1692
|
-
},
|
|
1693
|
-
'UPN65': {
|
|
1694
|
-
'h': 65.0,
|
|
1695
|
-
'b': 42.0,
|
|
1696
|
-
'tw': 5.5,
|
|
1697
|
-
'tf': 7.5,
|
|
1698
|
-
'r1': 8.0,
|
|
1699
|
-
'r2': 4.0,
|
|
1700
|
-
'd': 34.0,
|
|
1701
|
-
},
|
|
1702
|
-
'UPN80': {
|
|
1703
|
-
'h': 80.0,
|
|
1704
|
-
'b': 45.0,
|
|
1705
|
-
'tw': 6.0,
|
|
1706
|
-
'tf': 8.0,
|
|
1707
|
-
'r1': 8.0,
|
|
1708
|
-
'r2': 4.0,
|
|
1709
|
-
'd': 47.0,
|
|
1710
|
-
},
|
|
1711
|
-
'UPN100': {
|
|
1712
|
-
'h': 100.0,
|
|
1713
|
-
'b': 50.0,
|
|
1714
|
-
'tw': 6.0,
|
|
1715
|
-
'tf': 8.5,
|
|
1716
|
-
'r1': 9.0,
|
|
1717
|
-
'r2': 5.0,
|
|
1718
|
-
'd': 64.0,
|
|
1719
|
-
},
|
|
1720
|
-
'UPN120': {
|
|
1721
|
-
'h': 120.0,
|
|
1722
|
-
'b': 55.0,
|
|
1723
|
-
'tw': 7.0,
|
|
1724
|
-
'tf': 9.0,
|
|
1725
|
-
'r1': 9.0,
|
|
1726
|
-
'r2': 5.0,
|
|
1727
|
-
'd': 82.0,
|
|
1728
|
-
},
|
|
1729
|
-
'UPN140': {
|
|
1730
|
-
'h': 140.0,
|
|
1731
|
-
'b': 60.0,
|
|
1732
|
-
'tw': 7.0,
|
|
1733
|
-
'tf': 10.0,
|
|
1734
|
-
'r1': 10.0,
|
|
1735
|
-
'r2': 5.0,
|
|
1736
|
-
'd': 98.0,
|
|
1737
|
-
},
|
|
1738
|
-
'UPN160': {
|
|
1739
|
-
'h': 160.0,
|
|
1740
|
-
'b': 65.0,
|
|
1741
|
-
'tw': 7.5,
|
|
1742
|
-
'tf': 10.5,
|
|
1743
|
-
'r1': 11.0,
|
|
1744
|
-
'r2': 6.0,
|
|
1745
|
-
'd': 115.0,
|
|
1746
|
-
},
|
|
1747
|
-
'UPN180': {
|
|
1748
|
-
'h': 180.0,
|
|
1749
|
-
'b': 70.0,
|
|
1750
|
-
'tw': 8.0,
|
|
1751
|
-
'tf': 11.0,
|
|
1752
|
-
'r1': 11.0,
|
|
1753
|
-
'r2': 6.0,
|
|
1754
|
-
'd': 133.0,
|
|
1755
|
-
},
|
|
1756
|
-
'UPN200': {
|
|
1757
|
-
'h': 200.0,
|
|
1758
|
-
'b': 75.0,
|
|
1759
|
-
'tw': 8.5,
|
|
1760
|
-
'tf': 11.5,
|
|
1761
|
-
'r1': 12.0,
|
|
1762
|
-
'r2': 6.0,
|
|
1763
|
-
'd': 151.0,
|
|
1764
|
-
},
|
|
1765
|
-
'UPN220': {
|
|
1766
|
-
'h': 220.0,
|
|
1767
|
-
'b': 80.0,
|
|
1768
|
-
'tw': 9.0,
|
|
1769
|
-
'tf': 12.5,
|
|
1770
|
-
'r1': 13.0,
|
|
1771
|
-
'r2': 7.0,
|
|
1772
|
-
'd': 167.0,
|
|
1773
|
-
},
|
|
1774
|
-
'UPN240': {
|
|
1775
|
-
'h': 240.0,
|
|
1776
|
-
'b': 85.0,
|
|
1777
|
-
'tw': 9.5,
|
|
1778
|
-
'tf': 13.0,
|
|
1779
|
-
'r1': 13.0,
|
|
1780
|
-
'r2': 7.0,
|
|
1781
|
-
'd': 184.0,
|
|
1782
|
-
},
|
|
1783
|
-
'UPN260': {
|
|
1784
|
-
'h': 260.0,
|
|
1785
|
-
'b': 90.0,
|
|
1786
|
-
'tw': 10.0,
|
|
1787
|
-
'tf': 14.0,
|
|
1788
|
-
'r1': 14.0,
|
|
1789
|
-
'r2': 7.0,
|
|
1790
|
-
'd': 200.0,
|
|
1791
|
-
},
|
|
1792
|
-
'UPN280': {
|
|
1793
|
-
'h': 280.0,
|
|
1794
|
-
'b': 95.0,
|
|
1795
|
-
'tw': 10.0,
|
|
1796
|
-
'tf': 15.0,
|
|
1797
|
-
'r1': 15.0,
|
|
1798
|
-
'r2': 8.0,
|
|
1799
|
-
'd': 216.0,
|
|
1800
|
-
},
|
|
1801
|
-
'UPN300': {
|
|
1802
|
-
'h': 300.0,
|
|
1803
|
-
'b': 100.0,
|
|
1804
|
-
'tw': 10.0,
|
|
1805
|
-
'tf': 16.0,
|
|
1806
|
-
'r1': 16.0,
|
|
1807
|
-
'r2': 8.0,
|
|
1808
|
-
'd': 232.0,
|
|
1809
|
-
},
|
|
1810
|
-
'UPN320': {
|
|
1811
|
-
'h': 320.0,
|
|
1812
|
-
'b': 100.0,
|
|
1813
|
-
'tw': 14.0,
|
|
1814
|
-
'tf': 17.5,
|
|
1815
|
-
'r1': 18.0,
|
|
1816
|
-
'r2': 9.0,
|
|
1817
|
-
'd': 246.0,
|
|
1818
|
-
},
|
|
1819
|
-
'UPN350': {
|
|
1820
|
-
'h': 350.0,
|
|
1821
|
-
'b': 100.0,
|
|
1822
|
-
'tw': 14.0,
|
|
1823
|
-
'tf': 16.0,
|
|
1824
|
-
'r1': 16.0,
|
|
1825
|
-
'r2': 8.0,
|
|
1826
|
-
'd': 282.0,
|
|
1827
|
-
},
|
|
1828
|
-
'UPN380': {
|
|
1829
|
-
'h': 380.0,
|
|
1830
|
-
'b': 102.0,
|
|
1831
|
-
'tw': 13.5,
|
|
1832
|
-
'tf': 16.0,
|
|
1833
|
-
'r1': 16.0,
|
|
1834
|
-
'r2': 8.0,
|
|
1835
|
-
'd': 313.0,
|
|
1836
|
-
},
|
|
1837
|
-
'UPN400': {
|
|
1838
|
-
'h': 400.0,
|
|
1839
|
-
'b': 110.0,
|
|
1840
|
-
'tw': 14.0,
|
|
1841
|
-
'tf': 18.0,
|
|
1842
|
-
'r1': 18.0,
|
|
1843
|
-
'r2': 9.0,
|
|
1844
|
-
'd': 324.0,
|
|
1845
|
-
},
|
|
1846
|
-
}
|
|
1847
|
-
|
|
1848
|
-
@classmethod
|
|
1849
|
-
def get_polygon(cls, name: str) -> Polygon:
|
|
1850
|
-
"""Returns a shapely polygon representing an UPN section."""
|
|
1851
|
-
if isinstance(name, (float, int)):
|
|
1852
|
-
name = f'UPN{int(name):0d}'
|
|
1853
|
-
parameters = cls.parameters.get(name)
|
|
1854
|
-
if parameters is None:
|
|
1855
|
-
raise ValueError(
|
|
1856
|
-
f"Profile '{name}' not found in UPN sections. "
|
|
1857
|
-
"Select a valid profile (available ones: "
|
|
1858
|
-
f"{cls.profiles()})"
|
|
1859
|
-
)
|
|
1860
|
-
if parameters['h'] <= 300:
|
|
1861
|
-
parameters['slope'] = 0.08
|
|
1862
|
-
parameters['u'] = parameters['b'] / 2.0
|
|
1863
|
-
else:
|
|
1864
|
-
parameters['slope'] = 0.05
|
|
1865
|
-
parameters['u'] = (parameters['b'] - parameters['tw']) / 2.0
|
|
1866
|
-
return _create_taper_U_section(
|
|
1867
|
-
**{
|
|
1868
|
-
key: parameters[key]
|
|
1869
|
-
for key in parameters
|
|
1870
|
-
if key in ['h', 'b', 'tw', 'tf', 'r1', 'r2', 'slope', 'u']
|
|
1871
|
-
}
|
|
1872
|
-
)
|
|
1873
|
-
|
|
1874
|
-
@classmethod
|
|
1875
|
-
def profiles(cls) -> list:
|
|
1876
|
-
"""Returns a list containing all available profiles."""
|
|
1877
|
-
return list(cls.parameters.keys())
|
|
1878
|
-
|
|
1879
|
-
def __init__(self, name: str) -> None:
|
|
1880
|
-
"""Creates a new UPN object."""
|
|
1881
|
-
if isinstance(name, (float, int)):
|
|
1882
|
-
name = f'UPN{int(name):0d}'
|
|
1883
|
-
parameters = self.parameters.get(name)
|
|
1884
|
-
if parameters is None:
|
|
1885
|
-
raise ValueError(
|
|
1886
|
-
f"Profile '{name}' not found in UPN sections. "
|
|
1887
|
-
"Select a valid profile (available ones: "
|
|
1888
|
-
f"{self.profiles()})"
|
|
1889
|
-
)
|
|
1890
|
-
super().__init__()
|
|
1891
|
-
self._h = parameters.get('h')
|
|
1892
|
-
self._b = parameters.get('b')
|
|
1893
|
-
self._tw = parameters.get('tw')
|
|
1894
|
-
self._tf = parameters.get('tf')
|
|
1895
|
-
self._r1 = parameters.get('r1')
|
|
1896
|
-
self._r2 = parameters.get('r2')
|
|
1897
|
-
if self._h <= 300:
|
|
1898
|
-
self._flange_slope = 0.08
|
|
1899
|
-
self._u = self._b / 2.0
|
|
1900
|
-
else:
|
|
1901
|
-
self._flange_slope = 0.05
|
|
1902
|
-
self._u = (self._b - self._tw) / 2.0
|
|
1903
|
-
self._polygon = _create_taper_U_section(
|
|
1904
|
-
h=self._h,
|
|
1905
|
-
b=self._b,
|
|
1906
|
-
tw=self._tw,
|
|
1907
|
-
tf=self._tf,
|
|
1908
|
-
r1=self._r1,
|
|
1909
|
-
r2=self._r2,
|
|
1910
|
-
slope=self._flange_slope,
|
|
1911
|
-
u=self._u,
|
|
1912
|
-
)
|
|
1913
|
-
|
|
1914
|
-
@property
|
|
1915
|
-
def polygon(self) -> Polygon:
|
|
1916
|
-
"""Returns shapely Polygon of section.
|
|
1917
|
-
|
|
1918
|
-
Returns:
|
|
1919
|
-
Polygon: The represention of the UPN section.
|
|
1920
|
-
"""
|
|
1921
|
-
return self._polygon
|
|
1922
|
-
|
|
1923
|
-
@property
|
|
1924
|
-
def h(self) -> float:
|
|
1925
|
-
"""Returns height of UPN section.
|
|
1926
|
-
|
|
1927
|
-
Returns:
|
|
1928
|
-
float: Height h of UPN section.
|
|
1929
|
-
"""
|
|
1930
|
-
return self._h
|
|
1931
|
-
|
|
1932
|
-
@property
|
|
1933
|
-
def b(self) -> float:
|
|
1934
|
-
"""Returns width of UPN section.
|
|
1935
|
-
|
|
1936
|
-
Returns:
|
|
1937
|
-
float: Width b of UPN section.
|
|
1938
|
-
"""
|
|
1939
|
-
return self._b
|
|
1940
|
-
|
|
1941
|
-
@property
|
|
1942
|
-
def tw(self) -> float:
|
|
1943
|
-
"""Returns thickness of web of UPN section.
|
|
1944
|
-
|
|
1945
|
-
Returns:
|
|
1946
|
-
float: Web thickness tw of UPN section.
|
|
1947
|
-
"""
|
|
1948
|
-
return self._tw
|
|
1949
|
-
|
|
1950
|
-
@property
|
|
1951
|
-
def tf(self) -> float:
|
|
1952
|
-
"""Returns thickness of flange of UPN section.
|
|
1953
|
-
|
|
1954
|
-
Returns:
|
|
1955
|
-
float: Flange thickness tw of UPN section.
|
|
1956
|
-
"""
|
|
1957
|
-
return self._tf
|
|
1958
|
-
|
|
1959
|
-
@property
|
|
1960
|
-
def r1(self) -> float:
|
|
1961
|
-
"""Returns fillet radius of UPN section.
|
|
1962
|
-
|
|
1963
|
-
Returns:
|
|
1964
|
-
float: Fillet radius r1 of UPN section.
|
|
1965
|
-
"""
|
|
1966
|
-
return self._r1
|
|
1967
|
-
|
|
1968
|
-
@property
|
|
1969
|
-
def r2(self) -> float:
|
|
1970
|
-
"""Returns fillet radius of UPN section.
|
|
1971
|
-
|
|
1972
|
-
Returns:
|
|
1973
|
-
float: Fillet radius r2 of UPN section.
|
|
1974
|
-
"""
|
|
1975
|
-
return self._r2
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
def _create_I_section(h: float, b: float, tw: float, tf: float, r: float):
|
|
1979
|
-
"""Returns a polygon for a I section."""
|
|
1980
|
-
# top flange
|
|
1981
|
-
top_flange = Polygon(
|
|
1982
|
-
[
|
|
1983
|
-
(-b / 2, -h / 2),
|
|
1984
|
-
(b / 2, -h / 2),
|
|
1985
|
-
(b / 2, -h / 2 + tf),
|
|
1986
|
-
(-b / 2, -h / 2 + tf),
|
|
1987
|
-
]
|
|
1988
|
-
)
|
|
1989
|
-
# bottom flange
|
|
1990
|
-
bottom_flange = translate(top_flange, xoff=0, yoff=h - tf)
|
|
1991
|
-
web = Polygon(
|
|
1992
|
-
[
|
|
1993
|
-
(-tw / 2, -h / 2 + tf),
|
|
1994
|
-
(tw / 2, -h / 2 + tf),
|
|
1995
|
-
(tw / 2, h / 2 - tf),
|
|
1996
|
-
(-tw / 2, h / 2 - tf),
|
|
1997
|
-
]
|
|
1998
|
-
)
|
|
1999
|
-
# fillets
|
|
2000
|
-
p = Point([tw / 2 + r, -h / 2 + tf + r]).buffer(r)
|
|
2001
|
-
s = Polygon(
|
|
2002
|
-
[
|
|
2003
|
-
(tw / 2, -h / 2 + tf),
|
|
2004
|
-
(tw / 2 + r, -h / 2 + tf),
|
|
2005
|
-
(tw / 2 + r, -h / 2 + tf + r),
|
|
2006
|
-
(tw / 2, -h / 2 + tf + r),
|
|
2007
|
-
]
|
|
2008
|
-
)
|
|
2009
|
-
fillet = s.difference(p)
|
|
2010
|
-
p = Point([-tw / 2 - r, -h / 2 + tf + r]).buffer(r)
|
|
2011
|
-
s = Polygon(
|
|
2012
|
-
[
|
|
2013
|
-
(-tw / 2 - r, -h / 2 + tf),
|
|
2014
|
-
(-tw / 2, -h / 2 + tf),
|
|
2015
|
-
(-tw / 2, -h / 2 + tf + r),
|
|
2016
|
-
(-tw / 2 - r, -h / 2 + tf + r),
|
|
2017
|
-
]
|
|
2018
|
-
)
|
|
2019
|
-
fillet = s.difference(p).union(fillet)
|
|
2020
|
-
fillet = translate(
|
|
2021
|
-
scale(fillet, 1, -1), xoff=0, yoff=h - 2 * tf - r
|
|
2022
|
-
).union(fillet)
|
|
2023
|
-
# Create the geometry
|
|
2024
|
-
geometries = [
|
|
2025
|
-
set_precision(geometry, grid_size=1e-13)
|
|
2026
|
-
for geometry in [fillet, top_flange, bottom_flange, web]
|
|
2027
|
-
]
|
|
2028
|
-
return orient(unary_union(geometries), 1)
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
def _create_taper_I_section(
|
|
2032
|
-
h: float,
|
|
2033
|
-
b: float,
|
|
2034
|
-
tw: float,
|
|
2035
|
-
tf: float,
|
|
2036
|
-
r1: float,
|
|
2037
|
-
r2: float,
|
|
2038
|
-
slope: float,
|
|
2039
|
-
) -> Polygon:
|
|
2040
|
-
"""Returns a shapely polygon representing a Taper Flange I Section."""
|
|
2041
|
-
# Create first part of line
|
|
2042
|
-
ls = [
|
|
2043
|
-
set_precision(
|
|
2044
|
-
LineString([[0, -h / 2], [b / 2, -h / 2]]), grid_size=1e-13
|
|
2045
|
-
)
|
|
2046
|
-
]
|
|
2047
|
-
# Create first fillet
|
|
2048
|
-
xy = np.array(
|
|
2049
|
-
[
|
|
2050
|
-
[b / 2, -h / 2],
|
|
2051
|
-
[b / 2, -h / 2 + tf - (b / 4 * slope)],
|
|
2052
|
-
[b / 4, -h / 2 + tf],
|
|
2053
|
-
]
|
|
2054
|
-
)
|
|
2055
|
-
ls.append(
|
|
2056
|
-
set_precision(
|
|
2057
|
-
LineString(xy).offset_curve(r2).offset_curve(-r2), grid_size=1e-13
|
|
2058
|
-
)
|
|
2059
|
-
)
|
|
2060
|
-
# Create second fillet
|
|
2061
|
-
xy = np.array(
|
|
2062
|
-
[
|
|
2063
|
-
[b / 4, -h / 2 + tf],
|
|
2064
|
-
[tw / 2, -h / 2 + tf + (b / 4 - tw / 2) * slope],
|
|
2065
|
-
[tw / 2, 0],
|
|
2066
|
-
]
|
|
2067
|
-
)
|
|
2068
|
-
ls.append(
|
|
2069
|
-
set_precision(
|
|
2070
|
-
LineString(xy).offset_curve(-r1).offset_curve(r1), grid_size=1e-13
|
|
2071
|
-
)
|
|
2072
|
-
)
|
|
2073
|
-
|
|
2074
|
-
# Merge filleted
|
|
2075
|
-
merged_ls = linemerge(ls)
|
|
2076
|
-
|
|
2077
|
-
# mirror the parts
|
|
2078
|
-
merged_ls = linemerge(
|
|
2079
|
-
[
|
|
2080
|
-
merged_ls,
|
|
2081
|
-
translate(scale(merged_ls, -1, 1), -b / 2, 0),
|
|
2082
|
-
]
|
|
2083
|
-
)
|
|
2084
|
-
merged_ls = linemerge(
|
|
2085
|
-
[
|
|
2086
|
-
merged_ls,
|
|
2087
|
-
translate(scale(merged_ls, 1, -1), 0, h / 2),
|
|
2088
|
-
]
|
|
2089
|
-
)
|
|
2090
|
-
|
|
2091
|
-
# Create a polygon
|
|
2092
|
-
poly = polygonize([merged_ls])
|
|
2093
|
-
|
|
2094
|
-
# Return the first and only polygon of this collection
|
|
2095
|
-
return orient(get_geometry(poly, 0), 1)
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
def _create_taper_U_section(
|
|
2099
|
-
h: float,
|
|
2100
|
-
b: float,
|
|
2101
|
-
tw: float,
|
|
2102
|
-
tf: float,
|
|
2103
|
-
r1: float,
|
|
2104
|
-
r2: float,
|
|
2105
|
-
slope: float,
|
|
2106
|
-
u: float,
|
|
2107
|
-
) -> Polygon:
|
|
2108
|
-
"""Returns a shapely polygon representing a Taper Flange U Section."""
|
|
2109
|
-
# Create first part of line
|
|
2110
|
-
ls = [
|
|
2111
|
-
set_precision(
|
|
2112
|
-
LineString([[0, h / 2], [0, 0], [b, 0]]), grid_size=1e-13
|
|
2113
|
-
)
|
|
2114
|
-
]
|
|
2115
|
-
# Create first fillet
|
|
2116
|
-
xy = np.array([[b, 0], [b, tf - slope * u], [b - u, tf]])
|
|
2117
|
-
ls.append(
|
|
2118
|
-
set_precision(
|
|
2119
|
-
LineString(xy).offset_curve(r2).offset_curve(-r2), grid_size=1e-13
|
|
2120
|
-
)
|
|
2121
|
-
)
|
|
2122
|
-
# Create second fillet
|
|
2123
|
-
xy = np.array(
|
|
2124
|
-
[
|
|
2125
|
-
[b - u, tf],
|
|
2126
|
-
[tw, tf + slope * (b - u - tw)],
|
|
2127
|
-
[tw, h / 2],
|
|
2128
|
-
]
|
|
2129
|
-
)
|
|
2130
|
-
ls.append(
|
|
2131
|
-
set_precision(
|
|
2132
|
-
LineString(xy).offset_curve(-r1).offset_curve(r1), grid_size=1e-13
|
|
2133
|
-
)
|
|
2134
|
-
)
|
|
2135
|
-
|
|
2136
|
-
# Merge filleted
|
|
2137
|
-
merged_ls = linemerge(ls)
|
|
2138
|
-
|
|
2139
|
-
# mirror the parts
|
|
2140
|
-
merged_ls = linemerge(
|
|
2141
|
-
[
|
|
2142
|
-
merged_ls,
|
|
2143
|
-
translate(scale(merged_ls, 1, -1), 0, h / 2),
|
|
2144
|
-
]
|
|
2145
|
-
)
|
|
2146
|
-
|
|
2147
|
-
# Create a polygon
|
|
2148
|
-
poly = polygonize([merged_ls])
|
|
2149
|
-
|
|
2150
|
-
# Get the first and only polygon of this collection
|
|
2151
|
-
poly = get_geometry(poly, 0)
|
|
2152
|
-
# Translate it to the centroid when returning
|
|
2153
|
-
return orient(
|
|
2154
|
-
translate(poly, xoff=-poly.centroid.x, yoff=-poly.centroid.y), 1
|
|
2155
|
-
)
|