pyflange 0.1.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.
pyflange/__init__.py ADDED
File without changes
pyflange/bolts.py ADDED
@@ -0,0 +1,447 @@
1
+ # pyFlange - python library for large flanges design
2
+ # Copyright (C) 2024 KCI The Engineers B.V.,
3
+ # Siemens Gamesa Renewable Energy B.V.,
4
+ # Nederlandse Organisatie voor toegepast-natuurwetenschappelijk onderzoek TNO.
5
+ #
6
+ # This program is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License, as published by
8
+ # the Free Software Foundation, either version 3 of the License, or any
9
+ # later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License version 3 for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # version 3 along with this program. If not, see <https://www.gnu.org/licenses/>.
18
+
19
+ '''
20
+ The ``bolts`` module contains a ``MetricBolt`` class that generates generic
21
+ bolts with metric screw thread and a ``StandardMetricBolt`` function that
22
+ generates MetricBolt objects with standard properties.
23
+ '''
24
+
25
+ from dataclasses import dataclass
26
+ from functools import cached_property
27
+
28
+ import logging
29
+ logging.basicConfig()
30
+ logger = logging.getLogger(__name__)
31
+ logger.setLevel(logging.DEBUG)
32
+
33
+ # UNITS OF MEASUREMENT
34
+ # Distance
35
+ m = 1
36
+ mm = 0.001*m
37
+ # Pressure
38
+ Pa = 1
39
+ MPa = 1e6*Pa
40
+ GPa = 1e9*Pa
41
+
42
+
43
+
44
+ class Bolt:
45
+ pass
46
+
47
+
48
+
49
+ @dataclass
50
+ class MetricBolt (Bolt):
51
+ ''' Generates a generic bolt with metric screw thread accoridng ISO 68-1, defined
52
+ by the following parameters:
53
+
54
+ - ``nominal_diameter`` : ``float``
55
+ The outermost diameter of the screw thread.
56
+
57
+ - ``thread_pitch`` : ``float``
58
+ The pitch of the metric thread.
59
+
60
+ - ``yield_stress`` : ``float``
61
+ Nominal yield stress (0.2% strain limit) of the bolt material.
62
+
63
+ - ``ultimate_tensile_stress`` : ``float``
64
+ Nominal ultimate tensile stress of the bolt material.
65
+
66
+ - ``elastic_modulus`` : ``float`` [optional]
67
+ The Young's modulus of the bolt material.
68
+ If omitted, it defaults to 210e9 N/m². Notice that the default value assumes
69
+ that the chosen unit for distance is m and the chosen unit for forces is N. If
70
+ that's not the case, you should enter the proper value of this parameter.
71
+
72
+ - ``poissons_ratio`` : ``float`` [optional]
73
+ The Poisson's ratio of the bolt material.
74
+ If omitted, it defaults to 0.30.
75
+
76
+ - ``shank_length`` : ``float`` [optional]
77
+ The length of the shank. If omitted, it defaults to 0.
78
+
79
+ - ``shank_diameter_ratio`` : ``float`` [optional]
80
+ The ratio between the shank diameter and the bolt nominal diameter.
81
+ If omitted, it defaults to 1, which means that the shank hs the
82
+ nominal diameter.
83
+
84
+ - ``stud`` : ``bool`` [optional]
85
+ True if this is a stud bolt, False if it is not.
86
+ If omitted, it defaults to False.
87
+
88
+ The parameters must be expressed in a consistent system of units. For example,
89
+ if you chose to input distances in mm and forces in N, then stresses must be
90
+ expressed in N/mm². All the bolt attributes and methods will return values
91
+ consistently with the input units of measurement.
92
+
93
+ All the input parameters are also available as attributes of the generated
94
+ object (e.g. ``bolt.shank_length``, ``bolt.yield_stress``, etc.).
95
+
96
+ This instances of this calss are designed to be immutable, which means than
97
+ changing an attribute after creating an object is not a good idea. If you
98
+ need a different bolt with different attributes, create a new one.
99
+ '''
100
+
101
+ nominal_diameter: float
102
+ thread_pitch: float
103
+
104
+ yield_stress: float
105
+ ultimate_tensile_stress: float
106
+ elastic_modulus: float = 210*GPa
107
+ poissons_ratio: float = 0.3
108
+
109
+ shank_length: float = 0
110
+ shank_diameter_ratio: float = 1
111
+ stud: bool = False
112
+
113
+
114
+ # -------------------------------------------------------------
115
+ # GEOMETRY
116
+ # -------------------------------------------------------------
117
+
118
+ @cached_property
119
+ def designation (self):
120
+ ''' Bolt designation string, which is, for example, ``"M16"``
121
+ for a bolt with nominal diameter 16 mm.
122
+ '''
123
+ return f"M{int(self.nominal_diameter*1000)}"
124
+
125
+
126
+ @cached_property
127
+ def shank_diameter (self):
128
+ ''' Diameter of the shank. '''
129
+ return self.nominal_diameter * self.shank_diameter_ratio
130
+
131
+
132
+ @cached_property
133
+ def thread_height (self):
134
+ ''' Height of the metric thread fundamental triangle (H),
135
+ as defined in ISO 68-1:1998.
136
+ '''
137
+ return 0.5 * 3**0.5 * self.thread_pitch
138
+
139
+
140
+ @cached_property
141
+ def thread_basic_minor_diameter (self):
142
+ ''' Basic minor diameter (d1) as defined in ISO 68-1:1998.'''
143
+ return self.nominal_diameter - 2 * 5/8 * self.thread_height
144
+
145
+
146
+ @cached_property
147
+ def thread_basic_pitch_diameter (self):
148
+ ''' Basic minor diameter (d2) as defined in ISO 68-1:1998.'''
149
+ return self.nominal_diameter - 2 * 3/8 * self.thread_height
150
+
151
+
152
+ @cached_property
153
+ def thread_minor_diameter (self):
154
+ ''' Minor diameter (d3) as defined in ISO 898-1:2013.'''
155
+ return self.thread_basic_minor_diameter - self.thread_height/6
156
+
157
+
158
+ @cached_property
159
+ def shank_cross_section_area (self):
160
+ ''' Area of the shank transversal cross-section.'''
161
+ from math import pi
162
+ return pi * self.shank_diameter**2 / 4
163
+
164
+
165
+ @cached_property
166
+ def nominal_cross_section_area (self):
167
+ ''' Area of a circle with nominal diameter.'''
168
+ from math import pi
169
+ return pi * self.nominal_diameter**2 / 4
170
+
171
+
172
+ @cached_property
173
+ def tensile_cross_section_area (self):
174
+ ''' Tensile stress area.'''
175
+ from math import pi
176
+ return pi * (self.nominal_diameter - 1.081*self.thread_height)**2 / 4
177
+
178
+
179
+
180
+ # -------------------------------------------------------------
181
+ # MATERIAL PROPERTIES
182
+ # -------------------------------------------------------------
183
+
184
+ @cached_property
185
+ def shear_modulus (self):
186
+ ''' Shear modulus G, calculated from the Young's modulus and
187
+ Poisson's ratio, under the assumption of isotropic and elastic
188
+ bolt material.'''
189
+ return 0.5 * self.elastic_modulus / (1 + self.poissons_ratio)
190
+
191
+
192
+
193
+ # -------------------------------------------------------------
194
+ # MECHANICAL PROPERTIES
195
+ # -------------------------------------------------------------
196
+
197
+ def ultimate_tensile_capacity (self, standard="Eurocode"):
198
+ ''' Returns the design ultimate tensile force that the bolt can take,
199
+ according to a given standard.
200
+
201
+ Currently the only standard available is "Eurocode", which is also the
202
+ default value of the ``standard`` parameter.
203
+ '''
204
+ if standard == "Eurocode":
205
+ return 0.9 * self.ultimate_tensile_stress * self.tensile_cross_section_area / 1.25
206
+ else:
207
+ raise ValueError(f"Unsupported standard: '{standard}'")
208
+
209
+
210
+ def axial_stiffness (self, length):
211
+ ''' Given a clamped ``length``, returns the axial stiffness of the bolt,
212
+ according to VDI 2230, Part 1, Section 5.1.1.1.
213
+ '''
214
+
215
+ # Verify input validity
216
+ assert length >= self.shank_length, "The lolt can't be shorter than its shank."
217
+
218
+ # Common variables
219
+ from math import pi
220
+ E = self.elastic_modulus
221
+ An = self.nominal_cross_section_area
222
+ As = self.shank_cross_section_area
223
+ At = pi * self.thread_minor_diameter**2 / 4
224
+
225
+ # Resilience of unthreaded part
226
+ L1 = self.shank_length
227
+ d1 = L1 / (E * As)
228
+
229
+ # Resilience at the minor diameter of the engaged bolt thread
230
+ LG = 0.5 * self.nominal_diameter
231
+ dG = LG / (E * At)
232
+
233
+ # Resilience of the nut
234
+ LM = 0.4 * self.nominal_diameter
235
+ dM = LM / (E * An)
236
+
237
+ # Resilience of threaded part
238
+ LGew = length - self.shank_length
239
+ dGew = LGew / (E * At)
240
+
241
+ # Resilience of hex head
242
+ LSK = 0.5 * self.nominal_diameter
243
+ dSK = LSK / (E * An)
244
+
245
+ # Total stiffness
246
+ if self.stud:
247
+ return 1 / (d1 + 2*dG + 2*dM + dGew)
248
+ else:
249
+ return 1 / (d1 + dG + dM + dGew + dSK)
250
+
251
+
252
+ def bending_stiffness (self, length):
253
+ ''' Given a clamped ``length``, returns the bending stiffness of the bolt,
254
+ according to VDI 2230, Part 1, Section 5.1.1.2.
255
+ '''
256
+
257
+ logger.debug(f"{self.designation} BENDING STIFFNESS FOR BOLT LENGTH L = {length*1000:.1f} mm")
258
+
259
+ # Verify input validity
260
+ assert length >= self.shank_length, "The lolt can't be shorter than its shank."
261
+
262
+ # Common variables
263
+ from math import pi
264
+ E = self.elastic_modulus
265
+ In = pi * self.nominal_diameter**4 / 64
266
+ Is = pi * self.shank_diameter**4 / 64
267
+ It = pi * self.thread_minor_diameter**4 / 64
268
+
269
+ # Bending resilience of unthreaded part
270
+ L1 = self.shank_length
271
+ b1 = L1 / (E * Is)
272
+
273
+ # Bending resilience at the minor diameter of the engaged bolt thread
274
+ LG = 0.5 * self.nominal_diameter
275
+ bG = LG / (E * It)
276
+
277
+ # Bending resilience of the nut
278
+ LM = 0.4 * self.nominal_diameter
279
+ bM = LM / (E * In)
280
+
281
+ # Bending resilience of threaded part
282
+ LGew = length - self.shank_length
283
+ bGew = LGew / (E * It)
284
+
285
+ # Bending resilience of hex head
286
+ LSK = 0.5 * self.nominal_diameter
287
+ bSK = LSK / (E * In)
288
+
289
+ logger.debug(f"Bending resilience of hex head: beta_Sk = {bSK*1e9} rad/(GN.m)")
290
+ logger.debug(f"Bending resilience of unthreaded part beta_1 = {b1*1e9} rad/(GN.m)")
291
+ logger.debug(f"Bending resilience of threaded part: beta_Gew = {bGew*1e9} rad/(GN.m)")
292
+ logger.debug(f"Bending resilience of minor diameter of engaged bolt thread: beta_G = {bG*1e9} rad/(GN.m)")
293
+ logger.debug(f"Bending resilience of nut: beta_M = {bM*1e9} rad/(GN.m)")
294
+
295
+ # Total bending stiffness
296
+ if self.stud:
297
+ return 1 / (b1 + 2*bG + 2*bM + bGew)
298
+ else:
299
+ return 1 / (b1 + bG + bM + bGew + bSK)
300
+
301
+
302
+
303
+
304
+ def StandardMetricBolt (designation, material_grade, shank_length=0.0, shank_diameter_ratio=1.0, stud=False):
305
+ ''' This function provides a convenient way for creating ``MetricBolt``
306
+ object, given the standard geometry designation (e.g. "M20") and the
307
+ standard material grade designation (e.g. "8.8").
308
+
309
+ The required parameters are:
310
+
311
+ - ``designation`` : ``str``
312
+ The metric screw thread designation. The allowed values are: 'M4', 'M5',
313
+ 'M6', 'M8', 'M10', 'M12', 'M14', 'M16', 'M18', 'M20', 'M22', 'M24',
314
+ 'M27', 'M30', 'M33', 'M36', 'M39', 'M42', 'M45', 'M48', 'M52', 'M56',
315
+ 'M60', 'M64', 'M72', 'M80', 'M90', 'M100'.
316
+
317
+ This parameter corresponds to a standard nominal diameter and a relevant
318
+ thread pitch value (i.e. the standard coarse pitch value).
319
+
320
+ - ``material_grade`` : ``str``
321
+ The material grade designation. The allowed values are: '4.6', '4.8',
322
+ '5.6', '5.8', '6.8', '8.8', '9.8', '10.9' and '12.9' for carbon-steel
323
+ bolts; 'A50', 'A70', 'A80' and 'A100' for austenitic bolts; 'D70', 'D80'
324
+ and 'D100' for duplex bolts; 'C50', 'C70', 'C80' and 'C110' for
325
+ martensitic bolts; 'F45' and 'F60' for ferritic bolts.
326
+
327
+ This parameter corresponds to a standard set of the paraters ``yield_stress``,
328
+ ``ultimate_tensile_stress``, ``elastic_modulus`` and ``poissons_ratio``.
329
+
330
+ - ``shank_length`` : ``float`` [optional]
331
+ The length of the shank. If omitted, it defaults to 0.
332
+
333
+ - ``shank_diameter_ratio`` : ``float`` [optional]
334
+ The ratio between the shank diameter and the bolt nominal diameter.
335
+ If omitted, it defaults to 1, which means that the shank hs the
336
+ nominal diameter.
337
+
338
+ - ``stud`` : ``bool`` [optional]
339
+ True if this is a stud bolt, False if it is not.
340
+ If omitted, it defaults to False.
341
+
342
+ '''
343
+
344
+ geometry = _standard['geometry'][designation]
345
+ meterial = _standard['materials'][material_grade]
346
+
347
+ return MetricBolt(
348
+ nominal_diameter = geometry['D'],
349
+ thread_pitch = geometry['Pc'],
350
+ yield_stress = material['fy'],
351
+ ultimate_tensile_stress = material['fu'],
352
+ elastic_modulus = material['E'],
353
+ poissons_ratio = material['nu'],
354
+ shank_length = shank_length,
355
+ shank_diameter_ratio = shank_diameter_ratio,
356
+ stud = stud)
357
+
358
+ _standard = {
359
+
360
+ "geometry": {
361
+
362
+ "M4" : {"D" : 4.00*mm, # nominal diameter
363
+ "Pc" : 0.70*mm, # coarse screw thead pitch
364
+ "Pf" : None, # fine screaw thead pitch
365
+ "t_nut": 3.20*mm, # nut thickness
366
+ "t_hex": 2.80*mm, # hex head thickness
367
+ "D_hex": 7.66*mm, # hex head/nut circumscribed circle diameter
368
+ "d_hex": 7.00*mm, # hex head/nut inscribed circle diameter
369
+ "d_was": 4.30*mm, # washer hole diameter ISO 7089
370
+ "D_was": 9.00*mm, # washer outer diameter ISO 7089
371
+ "t_was": 0.80*mm}, # washer thickness ISO 7089
372
+
373
+ "M5" : {"D": 5*mm, "Pc":0.80*mm, "Pf":None, "t_nut": 4.7*mm, "t_hex": 3.5*mm, "D_hex": 8.79*mm, "d_hex": 8*mm, "d_was": 5.3*mm, "D_was": 10*mm, "t_was": 1.0*mm},
374
+ "M6" : {"D": 6*mm, "Pc":1.00*mm, "Pf":None, "t_nut": 5.2*mm, "t_hex": 4.0*mm, "D_hex": 11.05*mm, "d_hex": 10*mm, "d_was": 6.4*mm, "D_was": 12*mm, "t_was": 1.6*mm},
375
+ "M8" : {"D": 8*mm, "Pc":1.25*mm, "Pf":1.00, "t_nut": 6.8*mm, "t_hex": 5.3*mm, "D_hex": 14.38*mm, "d_hex": 13*mm, "d_was": 8.4*mm, "D_was": 16*mm, "t_was": 1.6*mm},
376
+ "M10" : {"D":10*mm, "Pc":1.50*mm, "Pf":1.25, "t_nut": 8.4*mm, "t_hex": 6.4*mm, "D_hex": 18.90*mm, "d_hex": 17*mm, "d_was": 10.5*mm, "D_was": 20*mm, "t_was": 2.0*mm},
377
+ "M12" : {"D":12*mm, "Pc":1.75*mm, "Pf":1.50, "t_nut":10.8*mm, "t_hex": 7.5*mm, "D_hex": 21.10*mm, "d_hex": 19*mm, "d_was": 13.0*mm, "D_was": 24*mm, "t_was": 2.5*mm},
378
+ "M14" : {"D":14*mm, "Pc":2.00*mm, "Pf":1.50, "t_nut":12.8*mm, "t_hex": 8.8*mm, "D_hex": 24.49*mm, "d_hex": 22*mm, "d_was": 15.0*mm, "D_was": 28*mm, "t_was": 2.5*mm}, # 2nd choice
379
+ "M16" : {"D":16*mm, "Pc":2.00*mm, "Pf":1.50, "t_nut":14.8*mm, "t_hex":10.0*mm, "D_hex": 26.75*mm, "d_hex": 24*mm, "d_was": 17.0*mm, "D_was": 30*mm, "t_was": 3.0*mm},
380
+ "M18" : {"D":18*mm, "Pc":2.50*mm, "Pf":2.00, "t_nut":15.8*mm, "t_hex":11.5*mm, "D_hex": 30.14*mm, "d_hex": 27*mm, "d_was": 19.0*mm, "D_was": 34*mm, "t_was": 3.0*mm}, # 2nd choice
381
+ "M20" : {"D":20*mm, "Pc":2.50*mm, "Pf":2.00, "t_nut":18.0*mm, "t_hex":12.5*mm, "D_hex": 33.53*mm, "d_hex": 30*mm, "d_was": 21.0*mm, "D_was": 37*mm, "t_was": 3.0*mm},
382
+ "M22" : {"D":22*mm, "Pc":2.50*mm, "Pf":2.00, "t_nut":19.4*mm, "t_hex":14.0*mm, "D_hex": 35.72*mm, "d_hex": 32*mm, "d_was": 23.0*mm, "D_was": 39*mm, "t_was": 3.0*mm}, # 2nd choice
383
+ "M24" : {"D":24*mm, "Pc":3.00*mm, "Pf":2.00, "t_nut":21.5*mm, "t_hex":15.0*mm, "D_hex": 39.98*mm, "d_hex": 36*mm, "d_was": 25.0*mm, "D_was": 44*mm, "t_was": 4.0*mm},
384
+ "M27" : {"D":27*mm, "Pc":3.00*mm, "Pf":2.00, "t_nut":23.8*mm, "t_hex":17.0*mm, "D_hex": 45.20*mm, "d_hex": 41*mm, "d_was": 28.0*mm, "D_was": 50*mm, "t_was": 4.0*mm}, # 2nd choice
385
+ "M30" : {"D":30*mm, "Pc":3.50*mm, "Pf":2.00, "t_nut":25.6*mm, "t_hex":18.7*mm, "D_hex": 50.85*mm, "d_hex": 46*mm, "d_was": 31.0*mm, "D_was": 56*mm, "t_was": 4.0*mm},
386
+ "M33" : {"D":33*mm, "Pc":3.50*mm, "Pf":2.00, "t_nut":28.7*mm, "t_hex":21.0*mm, "D_hex": 55.37*mm, "d_hex": 50*mm, "d_was": 34.0*mm, "D_was": 60*mm, "t_was": 5.0*mm}, # 2nd choice
387
+ "M36" : {"D":36*mm, "Pc":4.00*mm, "Pf":3.00, "t_nut":31.0*mm, "t_hex":22.5*mm, "D_hex": 60.79*mm, "d_hex": 55*mm, "d_was": 37.0*mm, "D_was": 66*mm, "t_was": 5.0*mm},
388
+ "M39" : {"D":39*mm, "Pc":4.00*mm, "Pf":3.00, "t_nut":33.4*mm, "t_hex":25.0*mm, "D_hex": 66.44*mm, "d_hex": 60*mm, "d_was": 40.0*mm, "D_was": 72*mm, "t_was": 6.0*mm}, # 2nd choice
389
+ "M42" : {"D":42*mm, "Pc":4.50*mm, "Pf":3.00, "t_nut":34.0*mm, "t_hex":26.0*mm, "D_hex": 71.30*mm, "d_hex": 65*mm, "d_was": 43.0*mm, "D_was": 78*mm, "t_was": 7.0*mm},
390
+ "M45" : {"D":45*mm, "Pc":4.50*mm, "Pf":3.00, "t_nut":36.0*mm, "t_hex":28.0*mm, "D_hex": 76.95*mm, "d_hex": 70*mm, "d_was": 46.0*mm, "D_was": 85*mm, "t_was": 7.0*mm}, # 2nd choice
391
+ "M48" : {"D":48*mm, "Pc":5.00*mm, "Pf":3.00, "t_nut":38.0*mm, "t_hex":30.0*mm, "D_hex": 82.60*mm, "d_hex": 75*mm, "d_was": 50.0*mm, "D_was": 92*mm, "t_was": 8.0*mm},
392
+ "M52" : {"D":52*mm, "Pc":5.00*mm, "Pf":4.00, "t_nut":42.0*mm, "t_hex":33.0*mm, "D_hex": 88.25*mm, "d_hex": 80*mm, "d_was": 54.0*mm, "D_was": 98*mm, "t_was": 8.0*mm}, # 2nd choice
393
+ "M56" : {"D":56*mm, "Pc":5.50*mm, "Pf":4.00, "t_nut":45.0*mm, "t_hex":35.0*mm, "D_hex": 93.56*mm, "d_hex": 85*mm, "d_was": 58.0*mm, "D_was":105*mm, "t_was": 9.0*mm},
394
+ "M60" : {"D":60*mm, "Pc":5.50*mm, "Pf":4.00, "t_nut":48.0*mm, "t_hex":38.0*mm, "D_hex": 99.21*mm, "d_hex": 90*mm, "d_was": 62.0*mm, "D_was":110*mm, "t_was": 9.0*mm}, # 2nd choice
395
+ "M64" : {"D":64*mm, "Pc":6.00*mm, "Pf":4.00, "t_nut":51.0*mm, "t_hex":40.0*mm, "D_hex":104.86*mm, "d_hex": 95*mm, "d_was": 66.0*mm, "D_was":115*mm, "t_was": 9.0*mm},
396
+ "M72" : {"D":72*mm, "Pc":6.00*mm, "Pf":4.00, "t_nut":58.0*mm, "t_hex":46.5*mm, "D_hex":116.20*mm, "d_hex":105*mm, "d_was": 74.0*mm, "D_was":125*mm, "t_was":10.0*mm},
397
+ "M80" : {"D":80*mm, "Pc":6.00*mm, "Pf":4.00, "t_nut":64.0*mm, "t_hex":51.6*mm, "D_hex":127.50*mm, "d_hex":115*mm, "d_was": 82.0*mm, "D_was":140*mm, "t_was":12.0*mm},
398
+ "M90" : {"D":90*mm, "Pc":6.00*mm, "Pf":4.00, "t_nut":72.0*mm, "t_hex":57.7*mm, "D_hex":144.10*mm, "d_hex":130*mm, "d_was": 93.0*mm, "D_was":160*mm, "t_was":12.0*mm},
399
+ "M100": {"D":100*mm,"Pc":6.00*mm, "Pf":4.00, "t_nut":80.0*mm, "t_hex":63.9*mm, "D_hex":161.02*mm, "d_hex":145*mm, "d_was":104.0*mm, "D_was":175*mm, "t_was":14.0*mm}
400
+ },
401
+
402
+ "materials": {
403
+
404
+ # Carbon-steel and alloy steel bolts,
405
+ # according to ISO 898-1
406
+
407
+ "4.6": {
408
+ "fy": 240*MPa, # yield stress (stress at 0.2% non-proportional elongation)
409
+ "fu": 400*MPa, # ultimate tensile stress
410
+ "E" : 210*GPa, # elastic modulus
411
+ "nu": 0.3 # poissons ratio
412
+ },
413
+
414
+ "4.8" : {"fy": 320*MPa, "fu": 400*MPa, "E":210*GPa, "nu":0.3},
415
+ "5.6" : {"fy": 300*MPa, "fu": 500*MPa, "E":210*GPa, "nu":0.3},
416
+ "5.8" : {"fy": 400*MPa, "fu": 500*MPa, "E":210*GPa, "nu":0.3},
417
+ "6.8" : {"fy": 480*MPa, "fu": 600*MPa, "E":210*GPa, "nu":0.3},
418
+ "8.8" : {"fy": 640*MPa, "fu": 800*MPa, "E":210*GPa, "nu":0.3},
419
+ "9.8" : {"fy": 720*MPa, "fu": 900*MPa, "E":210*GPa, "nu":0.3},
420
+ "10.9" : {"fy": 900*MPa, "fu":1000*MPa, "E":210*GPa, "nu":0.3},
421
+ "12.9" : {"fy":1080*MPa, "fu":1200*MPa, "E":210*GPa, "nu":0.3},
422
+
423
+ # Stainless-steel bolts,
424
+ # according to ISO 3506-1
425
+
426
+ # ISO 3506-1 Austenitic
427
+ "A50" : {"fy": 210*MPa, "fu": 500*MPa, "E":210*GPa, "nu":0.3},
428
+ "A70" : {"fy": 450*MPa, "fu": 700*MPa, "E":210*GPa, "nu":0.3},
429
+ "A80" : {"fy": 600*MPa, "fu": 800*MPa, "E":210*GPa, "nu":0.3},
430
+ "A100": {"fy": 800*MPa, "fu":1000*MPa, "E":210*GPa, "nu":0.3},
431
+
432
+ # ISO 3506-1 Duplex
433
+ "D70" : {"fy": 450*MPa, "fu": 700*MPa, "E":210*GPa, "nu":0.3},
434
+ "D80" : {"fy": 600*MPa, "fu": 800*MPa, "E":210*GPa, "nu":0.3},
435
+ "D100": {"fy": 800*MPa, "fu":1000*MPa, "E":210*GPa, "nu":0.3},
436
+
437
+ # ISO 3506-1 Martensitic
438
+ "C50" : {"fy": 250*MPa, "fu": 500*MPa, "E":210*GPa, "nu":0.3},
439
+ "C70" : {"fy": 410*MPa, "fu": 700*MPa, "E":210*GPa, "nu":0.3},
440
+ "C80" : {"fy": 640*MPa, "fu": 800*MPa, "E":210*GPa, "nu":0.3},
441
+ "C110": {"fy": 820*MPa, "fu":1100*MPa, "E":210*GPa, "nu":0.3},
442
+
443
+ # ISO 3506-1 Ferritic
444
+ "F45" : {"fy": 250*MPa, "fu": 450*MPa, "E":210*GPa, "nu":0.3},
445
+ "F60" : {"fy": 410*MPa, "fu": 600*MPa, "E":210*GPa, "nu":0.3}
446
+ }
447
+ }