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.

Files changed (40) hide show
  1. structuralcodes/__init__.py +1 -1
  2. structuralcodes/codes/mc2010/_concrete_creep_and_shrinkage.py +2 -2
  3. structuralcodes/core/base.py +115 -4
  4. structuralcodes/geometry/__init__.py +2 -8
  5. structuralcodes/geometry/_geometry.py +11 -22
  6. structuralcodes/geometry/_reinforcement.py +1 -3
  7. structuralcodes/geometry/profiles/__init__.py +19 -0
  8. structuralcodes/geometry/profiles/_base_profile.py +305 -0
  9. structuralcodes/geometry/profiles/_common_functions.py +194 -0
  10. structuralcodes/geometry/profiles/_he.py +192 -0
  11. structuralcodes/geometry/profiles/_ipe.py +130 -0
  12. structuralcodes/geometry/profiles/_ipn.py +329 -0
  13. structuralcodes/geometry/profiles/_ub.py +264 -0
  14. structuralcodes/geometry/profiles/_ubp.py +227 -0
  15. structuralcodes/geometry/profiles/_uc.py +276 -0
  16. structuralcodes/geometry/profiles/_upn.py +315 -0
  17. structuralcodes/materials/basic/_elastic.py +18 -1
  18. structuralcodes/materials/basic/_elasticplastic.py +18 -1
  19. structuralcodes/materials/basic/_generic.py +18 -1
  20. structuralcodes/materials/concrete/__init__.py +3 -0
  21. structuralcodes/materials/concrete/_concrete.py +10 -1
  22. structuralcodes/materials/concrete/_concreteEC2_2004.py +14 -0
  23. structuralcodes/materials/concrete/_concreteEC2_2023.py +14 -0
  24. structuralcodes/materials/concrete/_concreteMC2010.py +19 -0
  25. structuralcodes/materials/constitutive_laws/__init__.py +3 -0
  26. structuralcodes/materials/constitutive_laws/_elasticplastic.py +2 -2
  27. structuralcodes/materials/constitutive_laws/_initial_strain.py +130 -0
  28. structuralcodes/materials/reinforcement/__init__.py +6 -0
  29. structuralcodes/materials/reinforcement/_reinforcement.py +10 -1
  30. structuralcodes/materials/reinforcement/_reinforcementEC2_2004.py +14 -0
  31. structuralcodes/materials/reinforcement/_reinforcementEC2_2023.py +14 -0
  32. structuralcodes/materials/reinforcement/_reinforcementMC2010.py +14 -0
  33. structuralcodes/sections/section_integrators/__init__.py +3 -1
  34. structuralcodes/sections/section_integrators/_marin_integrator.py +1 -1
  35. {structuralcodes-0.5.0.dist-info → structuralcodes-0.6.0.dist-info}/METADATA +2 -2
  36. {structuralcodes-0.5.0.dist-info → structuralcodes-0.6.0.dist-info}/RECORD +39 -29
  37. structuralcodes/geometry/_steel_sections.py +0 -2155
  38. /structuralcodes/{sections/section_integrators → core}/_marin_integration.py +0 -0
  39. {structuralcodes-0.5.0.dist-info → structuralcodes-0.6.0.dist-info}/WHEEL +0 -0
  40. {structuralcodes-0.5.0.dist-info → structuralcodes-0.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,194 @@
1
+ """Common functions for creating profiles."""
2
+
3
+ import numpy as np
4
+ from shapely import (
5
+ LineString,
6
+ Point,
7
+ Polygon,
8
+ get_geometry,
9
+ polygonize,
10
+ set_precision,
11
+ )
12
+ from shapely.affinity import scale, translate
13
+ from shapely.geometry.polygon import orient
14
+ from shapely.ops import linemerge, unary_union
15
+
16
+
17
+ def _create_I_section(h: float, b: float, tw: float, tf: float, r: float):
18
+ """Returns a polygon for a I section."""
19
+ # top flange
20
+ top_flange = Polygon(
21
+ [
22
+ (-b / 2, -h / 2),
23
+ (b / 2, -h / 2),
24
+ (b / 2, -h / 2 + tf),
25
+ (-b / 2, -h / 2 + tf),
26
+ ]
27
+ )
28
+ # bottom flange
29
+ bottom_flange = translate(top_flange, xoff=0, yoff=h - tf)
30
+ web = Polygon(
31
+ [
32
+ (-tw / 2, -h / 2 + tf),
33
+ (tw / 2, -h / 2 + tf),
34
+ (tw / 2, h / 2 - tf),
35
+ (-tw / 2, h / 2 - tf),
36
+ ]
37
+ )
38
+ # fillets
39
+ p = Point([tw / 2 + r, -h / 2 + tf + r]).buffer(r)
40
+ s = Polygon(
41
+ [
42
+ (tw / 2, -h / 2 + tf),
43
+ (tw / 2 + r, -h / 2 + tf),
44
+ (tw / 2 + r, -h / 2 + tf + r),
45
+ (tw / 2, -h / 2 + tf + r),
46
+ ]
47
+ )
48
+ fillet = s.difference(p)
49
+ p = Point([-tw / 2 - r, -h / 2 + tf + r]).buffer(r)
50
+ s = Polygon(
51
+ [
52
+ (-tw / 2 - r, -h / 2 + tf),
53
+ (-tw / 2, -h / 2 + tf),
54
+ (-tw / 2, -h / 2 + tf + r),
55
+ (-tw / 2 - r, -h / 2 + tf + r),
56
+ ]
57
+ )
58
+ fillet = s.difference(p).union(fillet)
59
+ fillet = translate(
60
+ scale(fillet, 1, -1), xoff=0, yoff=h - 2 * tf - r
61
+ ).union(fillet)
62
+ # Create the geometry
63
+ geometries = [
64
+ set_precision(geometry, grid_size=1e-13)
65
+ for geometry in [fillet, top_flange, bottom_flange, web]
66
+ ]
67
+ return orient(unary_union(geometries), 1)
68
+
69
+
70
+ def _create_taper_I_section(
71
+ h: float,
72
+ b: float,
73
+ tw: float,
74
+ tf: float,
75
+ r1: float,
76
+ r2: float,
77
+ slope: float,
78
+ ) -> Polygon:
79
+ """Returns a shapely polygon representing a Taper Flange I Section."""
80
+ # Create first part of line
81
+ ls = [
82
+ set_precision(
83
+ LineString([[0, -h / 2], [b / 2, -h / 2]]), grid_size=1e-13
84
+ )
85
+ ]
86
+ # Create first fillet
87
+ xy = np.array(
88
+ [
89
+ [b / 2, -h / 2],
90
+ [b / 2, -h / 2 + tf - (b / 4 * slope)],
91
+ [b / 4, -h / 2 + tf],
92
+ ]
93
+ )
94
+ ls.append(
95
+ set_precision(
96
+ LineString(xy).offset_curve(r2).offset_curve(-r2), grid_size=1e-13
97
+ )
98
+ )
99
+ # Create second fillet
100
+ xy = np.array(
101
+ [
102
+ [b / 4, -h / 2 + tf],
103
+ [tw / 2, -h / 2 + tf + (b / 4 - tw / 2) * slope],
104
+ [tw / 2, 0],
105
+ ]
106
+ )
107
+ ls.append(
108
+ set_precision(
109
+ LineString(xy).offset_curve(-r1).offset_curve(r1), grid_size=1e-13
110
+ )
111
+ )
112
+
113
+ # Merge filleted
114
+ merged_ls = linemerge(ls)
115
+
116
+ # mirror the parts
117
+ merged_ls = linemerge(
118
+ [
119
+ merged_ls,
120
+ translate(scale(merged_ls, -1, 1), -b / 2, 0),
121
+ ]
122
+ )
123
+ merged_ls = linemerge(
124
+ [
125
+ merged_ls,
126
+ translate(scale(merged_ls, 1, -1), 0, h / 2),
127
+ ]
128
+ )
129
+
130
+ # Create a polygon
131
+ poly = polygonize([merged_ls])
132
+
133
+ # Return the first and only polygon of this collection
134
+ return orient(get_geometry(poly, 0), 1)
135
+
136
+
137
+ def _create_taper_U_section(
138
+ h: float,
139
+ b: float,
140
+ tw: float,
141
+ tf: float,
142
+ r1: float,
143
+ r2: float,
144
+ slope: float,
145
+ u: float,
146
+ ) -> Polygon:
147
+ """Returns a shapely polygon representing a Taper Flange U Section."""
148
+ # Create first part of line
149
+ ls = [
150
+ set_precision(
151
+ LineString([[0, h / 2], [0, 0], [b, 0]]), grid_size=1e-13
152
+ )
153
+ ]
154
+ # Create first fillet
155
+ xy = np.array([[b, 0], [b, tf - slope * u], [b - u, tf]])
156
+ ls.append(
157
+ set_precision(
158
+ LineString(xy).offset_curve(r2).offset_curve(-r2), grid_size=1e-13
159
+ )
160
+ )
161
+ # Create second fillet
162
+ xy = np.array(
163
+ [
164
+ [b - u, tf],
165
+ [tw, tf + slope * (b - u - tw)],
166
+ [tw, h / 2],
167
+ ]
168
+ )
169
+ ls.append(
170
+ set_precision(
171
+ LineString(xy).offset_curve(-r1).offset_curve(r1), grid_size=1e-13
172
+ )
173
+ )
174
+
175
+ # Merge filleted
176
+ merged_ls = linemerge(ls)
177
+
178
+ # mirror the parts
179
+ merged_ls = linemerge(
180
+ [
181
+ merged_ls,
182
+ translate(scale(merged_ls, 1, -1), 0, h / 2),
183
+ ]
184
+ )
185
+
186
+ # Create a polygon
187
+ poly = polygonize([merged_ls])
188
+
189
+ # Get the first and only polygon of this collection
190
+ poly = get_geometry(poly, 0)
191
+ # Translate it to the centroid when returning
192
+ return orient(
193
+ translate(poly, xoff=-poly.centroid.x, yoff=-poly.centroid.y), 1
194
+ )
@@ -0,0 +1,192 @@
1
+ """HE 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 HE(BaseProfile):
14
+ """Simple class for representing an HE profile.
15
+
16
+ HE A, HE B, HE M 100-1000 in accordance with Standard Euronorm 53-62.
17
+ """
18
+
19
+ parameters = {
20
+ 'HEA100': {'h': 96.0, 'b': 100.0, 'tw': 5.0, 'tf': 8.0, 'r': 12.0},
21
+ 'HEA120': {'h': 114.0, 'b': 120.0, 'tw': 5.0, 'tf': 8.0, 'r': 12.0},
22
+ 'HEA140': {'h': 133.0, 'b': 140.0, 'tw': 5.5, 'tf': 8.5, 'r': 12.0},
23
+ 'HEA160': {'h': 152.0, 'b': 160.0, 'tw': 6.0, 'tf': 9.0, 'r': 15.0},
24
+ 'HEA180': {'h': 171.0, 'b': 180.0, 'tw': 6.0, 'tf': 9.5, 'r': 15.0},
25
+ 'HEA200': {'h': 190.0, 'b': 200.0, 'tw': 6.5, 'tf': 10.0, 'r': 18.0},
26
+ 'HEA220': {'h': 210.0, 'b': 220.0, 'tw': 7.0, 'tf': 11.0, 'r': 18.0},
27
+ 'HEA240': {'h': 230.0, 'b': 240.0, 'tw': 7.5, 'tf': 12.0, 'r': 21.0},
28
+ 'HEA260': {'h': 250.0, 'b': 260.0, 'tw': 7.5, 'tf': 12.5, 'r': 24.0},
29
+ 'HEA280': {'h': 270.0, 'b': 280.0, 'tw': 8.0, 'tf': 13.0, 'r': 24.0},
30
+ 'HEA300': {'h': 290.0, 'b': 300.0, 'tw': 8.5, 'tf': 14.0, 'r': 27.0},
31
+ 'HEA320': {'h': 310.0, 'b': 300.0, 'tw': 9.0, 'tf': 15.5, 'r': 27.0},
32
+ 'HEA340': {'h': 330.0, 'b': 300.0, 'tw': 9.5, 'tf': 16.5, 'r': 27.0},
33
+ 'HEA360': {'h': 350.0, 'b': 300.0, 'tw': 10.0, 'tf': 17.5, 'r': 27.0},
34
+ 'HEA400': {'h': 390.0, 'b': 300.0, 'tw': 11.0, 'tf': 19.0, 'r': 27.0},
35
+ 'HEA450': {'h': 440.0, 'b': 300.0, 'tw': 11.5, 'tf': 21.0, 'r': 27.0},
36
+ 'HEA500': {'h': 490.0, 'b': 300.0, 'tw': 12.0, 'tf': 23.0, 'r': 27.0},
37
+ 'HEA550': {'h': 540.0, 'b': 300.0, 'tw': 12.5, 'tf': 24.0, 'r': 27.0},
38
+ 'HEA600': {'h': 590.0, 'b': 300.0, 'tw': 13.0, 'tf': 25.0, 'r': 27.0},
39
+ 'HEA650': {'h': 640.0, 'b': 300.0, 'tw': 13.5, 'tf': 26.0, 'r': 27.0},
40
+ 'HEA700': {'h': 690.0, 'b': 300.0, 'tw': 14.5, 'tf': 27.0, 'r': 27.0},
41
+ 'HEA800': {'h': 790.0, 'b': 300.0, 'tw': 15.0, 'tf': 28.0, 'r': 30.0},
42
+ 'HEA900': {'h': 890.0, 'b': 300.0, 'tw': 16.0, 'tf': 30.0, 'r': 30.0},
43
+ 'HEA1000': {'h': 990.0, 'b': 300.0, 'tw': 16.5, 'tf': 31.0, 'r': 30.0},
44
+ 'HEB100': {'h': 100.0, 'b': 100.0, 'tw': 6.0, 'tf': 10.0, 'r': 12.0},
45
+ 'HEB120': {'h': 120.0, 'b': 120.0, 'tw': 6.5, 'tf': 11.0, 'r': 12.0},
46
+ 'HEB140': {'h': 140.0, 'b': 140.0, 'tw': 7.0, 'tf': 12.0, 'r': 12.0},
47
+ 'HEB160': {'h': 160.0, 'b': 160.0, 'tw': 8.0, 'tf': 13.0, 'r': 15.0},
48
+ 'HEB180': {'h': 180.0, 'b': 180.0, 'tw': 8.5, 'tf': 14.0, 'r': 15.0},
49
+ 'HEB200': {'h': 200.0, 'b': 200.0, 'tw': 9.0, 'tf': 15.0, 'r': 18.0},
50
+ 'HEB220': {'h': 220.0, 'b': 220.0, 'tw': 9.5, 'tf': 16.0, 'r': 18.0},
51
+ 'HEB240': {'h': 240.0, 'b': 240.0, 'tw': 10.0, 'tf': 17.0, 'r': 21.0},
52
+ 'HEB260': {'h': 260.0, 'b': 260.0, 'tw': 10.0, 'tf': 17.5, 'r': 24.0},
53
+ 'HEB280': {'h': 280.0, 'b': 280.0, 'tw': 10.5, 'tf': 18.0, 'r': 24.0},
54
+ 'HEB300': {'h': 300.0, 'b': 300.0, 'tw': 11.0, 'tf': 19.0, 'r': 27.0},
55
+ 'HEB320': {'h': 320.0, 'b': 300.0, 'tw': 11.5, 'tf': 20.5, 'r': 27.0},
56
+ 'HEB340': {'h': 340.0, 'b': 300.0, 'tw': 12.0, 'tf': 21.5, 'r': 27.0},
57
+ 'HEB360': {'h': 360.0, 'b': 300.0, 'tw': 12.5, 'tf': 22.5, 'r': 27.0},
58
+ 'HEB400': {'h': 400.0, 'b': 300.0, 'tw': 13.5, 'tf': 24.0, 'r': 27.0},
59
+ 'HEB450': {'h': 450.0, 'b': 300.0, 'tw': 14.0, 'tf': 26.0, 'r': 27.0},
60
+ 'HEB500': {'h': 500.0, 'b': 300.0, 'tw': 14.5, 'tf': 28.0, 'r': 27.0},
61
+ 'HEB550': {'h': 550.0, 'b': 300.0, 'tw': 15.0, 'tf': 29.0, 'r': 27.0},
62
+ 'HEB600': {'h': 600.0, 'b': 300.0, 'tw': 15.5, 'tf': 30.0, 'r': 27.0},
63
+ 'HEB650': {'h': 650.0, 'b': 300.0, 'tw': 16.0, 'tf': 31.0, 'r': 27.0},
64
+ 'HEB700': {'h': 700.0, 'b': 300.0, 'tw': 17.0, 'tf': 32.0, 'r': 27.0},
65
+ 'HEB800': {'h': 800.0, 'b': 300.0, 'tw': 17.5, 'tf': 33.0, 'r': 30.0},
66
+ 'HEB900': {'h': 900.0, 'b': 300.0, 'tw': 18.5, 'tf': 35.0, 'r': 30.0},
67
+ 'HEB1000': {
68
+ 'h': 1000.0,
69
+ 'b': 300.0,
70
+ 'tw': 19.0,
71
+ 'tf': 36.0,
72
+ 'r': 30.0,
73
+ },
74
+ 'HEM100': {'h': 120.0, 'b': 106.0, 'tw': 12.0, 'tf': 20.0, 'r': 12.0},
75
+ 'HEM120': {'h': 140.0, 'b': 126.0, 'tw': 12.5, 'tf': 21.0, 'r': 12.0},
76
+ 'HEM140': {'h': 160.0, 'b': 146.0, 'tw': 13.0, 'tf': 22.0, 'r': 12.0},
77
+ 'HEM160': {'h': 180.0, 'b': 166.0, 'tw': 14.0, 'tf': 23.0, 'r': 15.0},
78
+ 'HEM180': {'h': 200.0, 'b': 186.0, 'tw': 14.5, 'tf': 24.0, 'r': 15.0},
79
+ 'HEM200': {'h': 220.0, 'b': 206.0, 'tw': 15.0, 'tf': 25.0, 'r': 18.0},
80
+ 'HEM220': {'h': 240.0, 'b': 226.0, 'tw': 15.5, 'tf': 26.0, 'r': 18.0},
81
+ 'HEM240': {'h': 270.0, 'b': 248.0, 'tw': 18.0, 'tf': 32.0, 'r': 21.0},
82
+ 'HEM260': {'h': 290.0, 'b': 268.0, 'tw': 18.0, 'tf': 32.5, 'r': 24.0},
83
+ 'HEM280': {'h': 310.0, 'b': 288.0, 'tw': 18.5, 'tf': 33.0, 'r': 24.0},
84
+ 'HEM300': {'h': 340.0, 'b': 310.0, 'tw': 21.0, 'tf': 39.0, 'r': 27.0},
85
+ 'HEM320': {'h': 359.0, 'b': 309.0, 'tw': 21.0, 'tf': 40.0, 'r': 27.0},
86
+ 'HEM340': {'h': 377.0, 'b': 309.0, 'tw': 21.0, 'tf': 40.0, 'r': 27.0},
87
+ 'HEM360': {'h': 395.0, 'b': 308.0, 'tw': 21.0, 'tf': 40.0, 'r': 27.0},
88
+ 'HEM400': {'h': 432.0, 'b': 307.0, 'tw': 21.0, 'tf': 40.0, 'r': 27.0},
89
+ 'HEM450': {'h': 478.0, 'b': 307.0, 'tw': 21.0, 'tf': 40.0, 'r': 27.0},
90
+ 'HEM500': {'h': 524.0, 'b': 306.0, 'tw': 21.0, 'tf': 40.0, 'r': 27.0},
91
+ 'HEM550': {'h': 572.0, 'b': 306.0, 'tw': 21.0, 'tf': 40.0, 'r': 27.0},
92
+ 'HEM600': {'h': 620.0, 'b': 305.0, 'tw': 21.0, 'tf': 40.0, 'r': 27.0},
93
+ 'HEM650': {'h': 668.0, 'b': 305.0, 'tw': 21.0, 'tf': 40.0, 'r': 27.0},
94
+ 'HEM700': {'h': 716.0, 'b': 304.0, 'tw': 21.0, 'tf': 40.0, 'r': 27.0},
95
+ 'HEM800': {'h': 814.0, 'b': 303.0, 'tw': 21.0, 'tf': 40.0, 'r': 30.0},
96
+ 'HEM900': {'h': 910.0, 'b': 302.0, 'tw': 21.0, 'tf': 40.0, 'r': 30.0},
97
+ 'HEM1000': {
98
+ 'h': 1008.0,
99
+ 'b': 302.0,
100
+ 'tw': 21.0,
101
+ 'tf': 40.0,
102
+ 'r': 30.0,
103
+ },
104
+ }
105
+
106
+ @classmethod
107
+ def get_polygon(cls, name: str) -> Polygon:
108
+ """Returns a shapely polygon representing an HE section."""
109
+ parameters = cls.parameters.get(name)
110
+ if parameters is None:
111
+ raise ValueError(
112
+ f"Profile '{name}' not found in HE sections. "
113
+ "Select a valid profile (available ones: "
114
+ f"{cls.profiles()})"
115
+ )
116
+ return _create_I_section(**parameters)
117
+
118
+ @classmethod
119
+ def profiles(cls) -> list:
120
+ """Returns a list containing all available profiles."""
121
+ return list(cls.parameters.keys())
122
+
123
+ def __init__(self, name: str) -> None:
124
+ """Creates a new HE object."""
125
+ parameters = self.parameters.get(name)
126
+ if parameters is None:
127
+ raise ValueError(
128
+ f"Profile '{name}' not found in HE sections. "
129
+ "Select a valid profile (available ones: "
130
+ f"{self.profiles()})"
131
+ )
132
+ super().__init__()
133
+ self._h = parameters.get('h')
134
+ self._b = parameters.get('b')
135
+ self._tw = parameters.get('tw')
136
+ self._tf = parameters.get('tf')
137
+ self._r = parameters.get('r')
138
+ self._polygon = _create_I_section(**parameters)
139
+
140
+ @property
141
+ def polygon(self) -> Polygon:
142
+ """Returns shapely Polygon of section.
143
+
144
+ Returns:
145
+ Polygon: The represention of the HE section.
146
+ """
147
+ return self._polygon
148
+
149
+ @property
150
+ def h(self) -> float:
151
+ """Returns height of HE section.
152
+
153
+ Returns:
154
+ float: Height h of HE section.
155
+ """
156
+ return self._h
157
+
158
+ @property
159
+ def b(self) -> float:
160
+ """Returns width of HE section.
161
+
162
+ Returns:
163
+ float: Width b of HE section.
164
+ """
165
+ return self._b
166
+
167
+ @property
168
+ def tw(self) -> float:
169
+ """Returns thickness of web of HE section.
170
+
171
+ Returns:
172
+ float: Web thickness tw of HE section.
173
+ """
174
+ return self._tw
175
+
176
+ @property
177
+ def tf(self) -> float:
178
+ """Returns thickness of flange of HE section.
179
+
180
+ Returns:
181
+ float: Flange thickness tw of HE section.
182
+ """
183
+ return self._tf
184
+
185
+ @property
186
+ def r(self) -> float:
187
+ """Returns fillet radius of HE section.
188
+
189
+ Returns:
190
+ float: Fillet radius r of HE section.
191
+ """
192
+ return self._r
@@ -0,0 +1,130 @@
1
+ """IPE 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 IPE(BaseProfile):
14
+ """Simple class for representing an IPE profile.
15
+
16
+ IPE 80-600 in accordance with standard Euronorm 19-57.
17
+ """
18
+
19
+ parameters = {
20
+ 'IPE80': {'h': 80.0, 'b': 46.0, 'tw': 3.8, 'tf': 5.2, 'r': 5.0},
21
+ 'IPE100': {'h': 100.0, 'b': 55.0, 'tw': 4.1, 'tf': 5.7, 'r': 7.0},
22
+ 'IPE120': {'h': 120.0, 'b': 64.0, 'tw': 4.4, 'tf': 6.3, 'r': 7.0},
23
+ 'IPE140': {'h': 140.0, 'b': 73.0, 'tw': 4.7, 'tf': 6.9, 'r': 7.0},
24
+ 'IPE160': {'h': 160.0, 'b': 82.0, 'tw': 5.0, 'tf': 7.4, 'r': 9.0},
25
+ 'IPE180': {'h': 180.0, 'b': 91.0, 'tw': 5.3, 'tf': 8.0, 'r': 9.0},
26
+ 'IPE200': {'h': 200.0, 'b': 100.0, 'tw': 5.6, 'tf': 8.5, 'r': 12.0},
27
+ 'IPE220': {'h': 220.0, 'b': 110.0, 'tw': 5.9, 'tf': 9.2, 'r': 12.0},
28
+ 'IPE240': {'h': 240.0, 'b': 120.0, 'tw': 6.2, 'tf': 9.8, 'r': 15.0},
29
+ 'IPE270': {'h': 270.0, 'b': 135.0, 'tw': 6.6, 'tf': 10.2, 'r': 15.0},
30
+ 'IPE300': {'h': 300.0, 'b': 150.0, 'tw': 7.1, 'tf': 10.7, 'r': 15.0},
31
+ 'IPE330': {'h': 330.0, 'b': 160.0, 'tw': 7.5, 'tf': 11.5, 'r': 18.0},
32
+ 'IPE360': {'h': 360.0, 'b': 170.0, 'tw': 8.0, 'tf': 12.7, 'r': 18.0},
33
+ 'IPE400': {'h': 400.0, 'b': 180.0, 'tw': 8.6, 'tf': 13.5, 'r': 21.0},
34
+ 'IPE450': {'h': 450.0, 'b': 190.0, 'tw': 9.4, 'tf': 14.6, 'r': 21.0},
35
+ 'IPE500': {'h': 500.0, 'b': 200.0, 'tw': 10.2, 'tf': 16.0, 'r': 21.0},
36
+ 'IPE550': {'h': 550.0, 'b': 210.0, 'tw': 11.1, 'tf': 17.2, 'r': 24.0},
37
+ 'IPE600': {'h': 600.0, 'b': 220.0, 'tw': 12.0, 'tf': 19.0, 'r': 24.0},
38
+ }
39
+
40
+ @classmethod
41
+ def get_polygon(cls, name: str) -> Polygon:
42
+ """Returns a shapely polygon representing an IPE section."""
43
+ if isinstance(name, (float, int)):
44
+ name = f'IPE{int(name):0d}'
45
+ parameters = cls.parameters.get(name)
46
+ if parameters is None:
47
+ raise ValueError(
48
+ f"Profile '{name}' not found in IPE sections. "
49
+ "Select a valid profile (available ones: "
50
+ f"{cls.profiles()})"
51
+ )
52
+ return _create_I_section(**parameters)
53
+
54
+ @classmethod
55
+ def profiles(cls) -> list:
56
+ """Returns a list containing all available profiles."""
57
+ return list(cls.parameters.keys())
58
+
59
+ def __init__(self, name: str) -> None:
60
+ """Creates a new IPE object."""
61
+ if isinstance(name, (float, int)):
62
+ name = f'IPE{int(name):0d}'
63
+ parameters = self.parameters.get(name)
64
+ if parameters is None:
65
+ raise ValueError(
66
+ f"Profile '{name}' not found in IPE sections. "
67
+ "Select a valid profile (available ones: "
68
+ f"{self.profiles()})"
69
+ )
70
+ super().__init__()
71
+ self._h = parameters.get('h')
72
+ self._b = parameters.get('b')
73
+ self._tw = parameters.get('tw')
74
+ self._tf = parameters.get('tf')
75
+ self._r = parameters.get('r')
76
+ self._polygon = _create_I_section(**parameters)
77
+
78
+ @property
79
+ def polygon(self) -> Polygon:
80
+ """Returns shapely Polygon of section.
81
+
82
+ Returns:
83
+ Polygon: The represention of the IPE section.
84
+ """
85
+ return self._polygon
86
+
87
+ @property
88
+ def h(self) -> float:
89
+ """Returns height of IPE section.
90
+
91
+ Returns:
92
+ float: Height h of IPE section.
93
+ """
94
+ return self._h
95
+
96
+ @property
97
+ def b(self) -> float:
98
+ """Returns width of IPE section.
99
+
100
+ Returns:
101
+ float: Width b of IPE section.
102
+ """
103
+ return self._b
104
+
105
+ @property
106
+ def tw(self) -> float:
107
+ """Returns thickness of web of IPE section.
108
+
109
+ Returns:
110
+ float: Web thickness tw of IPE section.
111
+ """
112
+ return self._tw
113
+
114
+ @property
115
+ def tf(self) -> float:
116
+ """Returns thickness of flange of IPE section.
117
+
118
+ Returns:
119
+ float: Flange thickness tw of IPE section.
120
+ """
121
+ return self._tf
122
+
123
+ @property
124
+ def r(self) -> float:
125
+ """Returns fillet radius of IPE section.
126
+
127
+ Returns:
128
+ float: Fillet radius r of IPE section.
129
+ """
130
+ return self._r