ourocode 1.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 ourocode might be problematic. Click here for more details.
- ourocode/__init__.py +0 -0
- ourocode/__version__.py +1 -0
- ourocode/data/caracteristique_meca_acier.csv +33 -0
- ourocode/data/caracteristique_meca_bois.csv +59 -0
- ourocode/data/carte_action_region.csv +36722 -0
- ourocode/data/coeff_psy.csv +13 -0
- ourocode/data/exploitation.csv +17 -0
- ourocode/data/gammaM.csv +14 -0
- ourocode/data/kdef.csv +11 -0
- ourocode/data/kfi.csv +10 -0
- ourocode/data/kmod.csv +16 -0
- ourocode/data/limite_fleche.csv +9 -0
- ourocode/data/qualite_acier.csv +18 -0
- ourocode/data/screenshot/C90_def.png +0 -0
- ourocode/data/screenshot/Kv_def.png +0 -0
- ourocode/data/screenshot/fleche.png +0 -0
- ourocode/data/screenshot/sign_convention.png +0 -0
- ourocode/data/section_boulon.csv +12 -0
- ourocode/data/vent/vent_Cp_toiture_isolee_1_versant.csv +22 -0
- ourocode/data/vent/vent_Cp_toiture_isolee_1_versant.png +0 -0
- ourocode/data/vent/vent_Cp_toiture_isolee_2_versants.csv +31 -0
- ourocode/data/vent/vent_Cp_toiture_isolee_2_versants.png +0 -0
- ourocode/data/vent/vent_Cpe_mur_verticaux.csv +11 -0
- ourocode/data/vent/vent_Cpe_mur_verticaux.png +0 -0
- ourocode/data/vent/vent_Cpe_toiture_1_versant.png +0 -0
- ourocode/data/vent/vent_Cpe_toiture_1_versant_0_degres.csv +13 -0
- ourocode/data/vent/vent_Cpe_toiture_1_versant_180_degres.csv +13 -0
- ourocode/data/vent/vent_Cpe_toiture_1_versant_90_degres.csv +13 -0
- ourocode/data/vent/vent_Cpe_toiture_2_versants.png +0 -0
- ourocode/data/vent/vent_Cpe_toiture_2_versants_0_degres.csv +21 -0
- ourocode/data/vent/vent_Cpe_toiture_2_versants_90_degres.csv +21 -0
- ourocode/data/vent/vent_Cpe_toiture_terrasse.csv +21 -0
- ourocode/data/vent/vent_Cpe_toiture_terrasse.png +0 -0
- ourocode/data/vent/vent_Ffr.png +0 -0
- ourocode/eurocode/A0_Projet.py +1408 -0
- ourocode/eurocode/EC0_Combinaison.py +1763 -0
- ourocode/eurocode/EC1_Exploitation.py +103 -0
- ourocode/eurocode/EC1_Neige.py +385 -0
- ourocode/eurocode/EC1_Vent.py +1388 -0
- ourocode/eurocode/EC3_Assemblage.py +466 -0
- ourocode/eurocode/EC3_Element_droit.py +302 -0
- ourocode/eurocode/EC5_Assemblage.py +1760 -0
- ourocode/eurocode/EC5_Element_droit.py +1740 -0
- ourocode/eurocode/EC5_Feu.py +922 -0
- ourocode/eurocode/EC8_Sismique.py +2 -0
- ourocode/eurocode/__init__.py +0 -0
- ourocode/eurocode/logical.py +83 -0
- ourocode/eurocode/objet.py +263 -0
- ourocode-1.6.0.dist-info/METADATA +331 -0
- ourocode-1.6.0.dist-info/RECORD +53 -0
- ourocode-1.6.0.dist-info/WHEEL +5 -0
- ourocode-1.6.0.dist-info/licenses/LICENSE +201 -0
- ourocode-1.6.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1760 @@
|
|
|
1
|
+
# coding in UTF-8
|
|
2
|
+
# by Anthony PARISOT
|
|
3
|
+
# under Python 3.9.4
|
|
4
|
+
|
|
5
|
+
############# Le but de ce fichier est de regrouper toute les fonctions d'assemblage par organe métalique dans l'EN-1995 #############
|
|
6
|
+
from copy import deepcopy
|
|
7
|
+
import math as mt
|
|
8
|
+
from math import sin, cos, radians, sqrt, pi
|
|
9
|
+
|
|
10
|
+
import forallpeople as si
|
|
11
|
+
si.environment("structural")
|
|
12
|
+
from handcalcs.decorator import handcalc
|
|
13
|
+
|
|
14
|
+
from ourocode.eurocode.A0_Projet import Projet
|
|
15
|
+
from ourocode.eurocode.EC5_Element_droit import Barre, Cisaillement
|
|
16
|
+
|
|
17
|
+
def interpolationLineaire(x, xa, xb, ya, yb):
|
|
18
|
+
"""Fait une interpolation linéaire pour trouver un résultat y entre deux valeur xa et xb """
|
|
19
|
+
y = ya + (x - xa) * ((yb - ya)/(xb - xa))
|
|
20
|
+
return y
|
|
21
|
+
|
|
22
|
+
# ====================================================== GENERAL =========================================================
|
|
23
|
+
# 8.1 Généralité
|
|
24
|
+
class Assemblage(Projet):
|
|
25
|
+
GAMMA_M_ASS = 1.3
|
|
26
|
+
DICO_COEF_LIMITE = {"Pointe circulaire": 0.15, "Pointe carrée": 0.25,
|
|
27
|
+
"Boulon": 0.25, "Autres pointes": 0.5, "Tirefond": 1}
|
|
28
|
+
TYPE_BOIS_ASSEMBLAGE = ("Bois","PP/OSB", "CP", "Panneau dur")
|
|
29
|
+
TYPE_ASSEMBLAGE = ("Bois/Bois", "Bois/Métal")
|
|
30
|
+
|
|
31
|
+
def __init__(self,beam_1:object, beam_2:object, nfile: int=1, nCis: int=("1","2"), **kwargs):
|
|
32
|
+
"""Créer un objet Assemblage qui permet de calculer un assemblage bois/bois ou bois/métal à l'EN 1995.
|
|
33
|
+
Cette classe est dérivé de la classe Projet du module A0_Project.py
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
beam_1 (object): objet correspondant à i=1, Beam ou dérivé de cet objet provenant du module EC5_Element_droit.py
|
|
37
|
+
ou bien objet Element ou dérivé de cet objet provenant du module EC3_Element_droit.py
|
|
38
|
+
|
|
39
|
+
beam_2 (object): objet correspondant à i=2, Beam ou dérivé de cet objet provenant du module EC5_Element_droit.py
|
|
40
|
+
ou bien objet Element ou dérivé de cet objet provenant du module EC3_Element_droit.py
|
|
41
|
+
|
|
42
|
+
nfile (int, optional): le nombre de file dans l'assemblage. Defaults to 1.
|
|
43
|
+
nCis (int, optional): Nombre de plan cisaillé entre 1 et 2. Defaults to ["1","2"].
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
super().__init__(**kwargs)
|
|
47
|
+
#type_organe : le type d'organe de l'assemblage "Pointe circulaire", "Pointe carrée", "Autres pointes", "Agrafe", "Tirefond", "Boulon"ou"Broche", "plaque", "Anneau", "Crampon C1/C9","Crampon C10/C11".
|
|
48
|
+
self.beam_1 = beam_1
|
|
49
|
+
self.beam_2 = beam_2
|
|
50
|
+
self.nfile = nfile
|
|
51
|
+
self.nCis = nCis
|
|
52
|
+
self.__type_assemblage()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def __type_assemblage(self):
|
|
56
|
+
self._type_beam = []
|
|
57
|
+
for i, beam in enumerate([self.beam_1, self.beam_2]):
|
|
58
|
+
try:
|
|
59
|
+
if beam.type_bois:
|
|
60
|
+
if beam.type_bois in ["Massif","BLC", "LVL"]:
|
|
61
|
+
self._type_beam.append(self.TYPE_BOIS_ASSEMBLAGE[0])
|
|
62
|
+
elif beam.type_bois in ["OSB 2", "OSB 3/4"]:
|
|
63
|
+
self._type_beam.append(self.TYPE_BOIS_ASSEMBLAGE[1])
|
|
64
|
+
elif beam.type_bois == "CP":
|
|
65
|
+
self._type_beam.append(self.TYPE_BOIS_ASSEMBLAGE[2])
|
|
66
|
+
elif beam.type_bois == "Panneau dur":
|
|
67
|
+
self._type_beam.append(self.TYPE_BOIS_ASSEMBLAGE[3])
|
|
68
|
+
|
|
69
|
+
beam.rho_k = int(beam.caract_meca.loc["rhok"])
|
|
70
|
+
except AttributeError:
|
|
71
|
+
self._type_beam.append("Métal")
|
|
72
|
+
|
|
73
|
+
# Détermine le type d'assemblage Bois/Bois ou Bois/métal
|
|
74
|
+
if self._type_beam[0] in self.TYPE_BOIS_ASSEMBLAGE:
|
|
75
|
+
if self._type_beam[1] in self.TYPE_BOIS_ASSEMBLAGE:
|
|
76
|
+
self.type_assemblage = self.TYPE_ASSEMBLAGE[0]
|
|
77
|
+
else:
|
|
78
|
+
self.type_assemblage = self.TYPE_ASSEMBLAGE[1]
|
|
79
|
+
|
|
80
|
+
else:
|
|
81
|
+
self.type_assemblage = self.TYPE_ASSEMBLAGE[1]
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def rho_mean_ass(self):
|
|
86
|
+
if self.type_assemblage == __class__.TYPE_ASSEMBLAGE[0]:
|
|
87
|
+
rho_m1 = int(self.beam_1.caract_meca.loc["rhomean"])
|
|
88
|
+
rho_m2 = int(self.beam_2.caract_meca.loc["rhomean"])
|
|
89
|
+
return mt.sqrt(rho_m1 * rho_m2)
|
|
90
|
+
else:
|
|
91
|
+
if self._type_beam[0] in self.TYPE_BOIS_ASSEMBLAGE:
|
|
92
|
+
return int(self.beam_1.caract_meca.loc["rhomean"])
|
|
93
|
+
else:
|
|
94
|
+
return int(self.beam_2.caract_meca.loc["rhomean"])
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _min_nef(self, list_nef: list):
|
|
98
|
+
"""Retourne le nef minimum entre les 2
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
list_nef (list): list des nef en format handcalcs
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
_type_: _description_
|
|
105
|
+
"""
|
|
106
|
+
nef_1 = list_nef[0]
|
|
107
|
+
nef_2 = list_nef[1]
|
|
108
|
+
|
|
109
|
+
min_nef = min(self.nfile * nef_1[1], self.n * nef_2[1])
|
|
110
|
+
if min_nef == (self.nfile * nef_1[1]):
|
|
111
|
+
return list_nef[0]
|
|
112
|
+
else:
|
|
113
|
+
n_file = deepcopy(self.nfile)
|
|
114
|
+
self.nfile = self.n
|
|
115
|
+
self.n = n_file
|
|
116
|
+
return list_nef[1]
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
# 7.1 Glissement des assemblages
|
|
120
|
+
def Kser(self):
|
|
121
|
+
"""Calcul le kser du type d'un organe et de l'asssemblage en N/mm
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
list: retourne une liste du kser d'un organe par plan de cisaillement et celui de l'assemblage
|
|
126
|
+
"""
|
|
127
|
+
rho_mean = self.rho_mean_ass
|
|
128
|
+
if self.type_organe == "Anneau" or self.type_organe == "Crampon C10/C11":
|
|
129
|
+
dc = self.dc.value*10**3
|
|
130
|
+
else:
|
|
131
|
+
d = self.d.value*10**3
|
|
132
|
+
|
|
133
|
+
if self.type_organe == "Boulon" or self.type_organe == "Broche" or self.type_organe == "Tirefond":
|
|
134
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
135
|
+
def val():
|
|
136
|
+
K_ser = rho_mean**1.5 * d / 23 # N/mm
|
|
137
|
+
return K_ser * si.N / si.mm
|
|
138
|
+
elif self.type_organe == "Pointe circulaire" or self.type_organe == "Pointe carrée" or self.type_organe == "Autres pointes":
|
|
139
|
+
if self.percage:
|
|
140
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
141
|
+
def val():
|
|
142
|
+
K_ser = rho_mean**1.5 * d / 23 # N/mm
|
|
143
|
+
return K_ser * si.N / si.mm
|
|
144
|
+
else:
|
|
145
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
146
|
+
def val():
|
|
147
|
+
K_ser = rho_mean**1.5 * d**0.8 / 30 # N/mm
|
|
148
|
+
return K_ser * si.N / si.mm
|
|
149
|
+
elif self.type_organe == "Agrafe":
|
|
150
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
151
|
+
def val():
|
|
152
|
+
K_ser = rho_mean**1.5 * self.d**0.8 / 80 # N/mm
|
|
153
|
+
return K_ser * si.N / si.mm
|
|
154
|
+
elif self.type_organe == "Anneau" or self.type_organe == "Crampon C10/C11":
|
|
155
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
156
|
+
def val():
|
|
157
|
+
K_ser = rho_mean * dc / 2 # N/mm
|
|
158
|
+
return K_ser * si.N / si.mm
|
|
159
|
+
elif self.type_organe == "Crampon C1/C9":
|
|
160
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
161
|
+
def val():
|
|
162
|
+
K_ser = 1.5 * rho_mean * d / 4 # N/mm
|
|
163
|
+
return K_ser * si.N / si.mm
|
|
164
|
+
return val()
|
|
165
|
+
|
|
166
|
+
def Kser_ass(self):
|
|
167
|
+
n_file = self.nfile
|
|
168
|
+
K_ser = self.Kser()[1]
|
|
169
|
+
n = self.n
|
|
170
|
+
n_Cis = self.nCis
|
|
171
|
+
k_type = 1
|
|
172
|
+
if self.type_assemblage == __class__.TYPE_ASSEMBLAGE[1]:
|
|
173
|
+
k_type = 2
|
|
174
|
+
@handcalc(override="short", precision=3, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
175
|
+
def val():
|
|
176
|
+
K_ser_ass = K_ser * n_file * n * n_Cis * k_type
|
|
177
|
+
return K_ser_ass
|
|
178
|
+
return val()
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
# 8.1.4 Effort d'assemblage inclinés par rapport au fil
|
|
182
|
+
|
|
183
|
+
def _w(self, wpl: int=0):
|
|
184
|
+
"""Calcul le facteur de modification pour le calcul de la valeur caractéristique au fendage F90,Rk avec:
|
|
185
|
+
wpl : largeur de la plaque métallique emboutie parallèlement au fil en mm
|
|
186
|
+
type_organe : type d'organe utilisé, pour les plaques métalliques embouties : "plaque", pour les autres : "autres" """
|
|
187
|
+
if self.type_organe == "plaques métaliques embouties":
|
|
188
|
+
w = max((wpl / 100) ** 0.35, 1)
|
|
189
|
+
else:
|
|
190
|
+
w = 1
|
|
191
|
+
return w
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def F90Rk(self, b:int, h:int, he:int, w: int=1):
|
|
195
|
+
"""Calcul la valeur caractérisque de la capacité au fendage en N avec :
|
|
196
|
+
b : l'épaisseur de l'élément en mm
|
|
197
|
+
h : la hauteur de l'élément en mm
|
|
198
|
+
he : la distance de rive chargée vis à vis du centre de l'organe le plus plus éloigné ou du bord de la plaque
|
|
199
|
+
w : facteur de modification """
|
|
200
|
+
h_e = he
|
|
201
|
+
@handcalc(override="short", precision=0, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
202
|
+
def val():
|
|
203
|
+
F_90_Rk = 14 * b * w * sqrt(h_e / (1 - (h_e / h))) # N
|
|
204
|
+
return F_90_Rk * si.N
|
|
205
|
+
return val()
|
|
206
|
+
|
|
207
|
+
# 8.2 Capacité résistante latérale pour les organes métaliques de type tige
|
|
208
|
+
# 8.2.2 Assemblage bois/bois bois/panneau
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def _FvRk_BoisBois(self, effet_corde: bool):
|
|
212
|
+
"""Calcul la capacité résistante en cisaillement de la tige en N par plan de cisaillement avec
|
|
213
|
+
t1 : valeur minimale entre epaisseur de l'élément bois latéral et la profondeur de pénétration en mm
|
|
214
|
+
t2 : epaisseur de l'élément bois central en mm """
|
|
215
|
+
|
|
216
|
+
f_h1k = self.fh1k[1].value * 10**-6
|
|
217
|
+
f_h2k = self.fh2k[1].value * 10**-6
|
|
218
|
+
t_1 = self.t1.value * 10**3
|
|
219
|
+
t_2 = self.t2.value * 10**3
|
|
220
|
+
diam = self.d.value * 10**3
|
|
221
|
+
M_y_Rk = self.MyRk[1].value * 10**3
|
|
222
|
+
|
|
223
|
+
coef_limit_Johansen = self.DICO_COEF_LIMITE.get(self.type_organe, 0)
|
|
224
|
+
if effet_corde:
|
|
225
|
+
F_ax_Rk = self.FaxRk.value
|
|
226
|
+
else:
|
|
227
|
+
F_ax_Rk = 0
|
|
228
|
+
|
|
229
|
+
if self.nCis == 1:
|
|
230
|
+
|
|
231
|
+
@handcalc(override="long", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
232
|
+
def val():
|
|
233
|
+
effet_corde = F_ax_Rk/4 # N
|
|
234
|
+
beta = f_h2k / f_h1k
|
|
235
|
+
a = f_h1k * t_1 * diam # N
|
|
236
|
+
b = f_h2k * t_2 * diam # N
|
|
237
|
+
c = a/(1 + beta) * (sqrt(beta + 2 * beta**2 * (1 + t_2 / t_1 + (t_2 / t_1)**2) + beta**3 * (t_2 / t_1)**2) - beta * (1 + t_2 / t_1)) # N
|
|
238
|
+
c = c + min(effet_corde, c*coef_limit_Johansen) # N
|
|
239
|
+
d = 1.05 * a / (2 + beta) * (sqrt(2 * beta * (1 + beta) + (4 * beta * (2 + beta) * M_y_Rk)/(f_h1k * t_1**2 * diam)) - beta) # N
|
|
240
|
+
d = d + min(effet_corde, d*coef_limit_Johansen) # N
|
|
241
|
+
e = 1.05 * (f_h1k * t_2 * diam) / (1 + 2 * beta) * (sqrt(2 * beta**2 * (1 + beta) + (4 * beta * (1 + 2 * beta) * M_y_Rk)/(f_h1k * t_2**2 * diam)) - beta) # N
|
|
242
|
+
e = e + min(effet_corde, e*coef_limit_Johansen) # N
|
|
243
|
+
f = 1.15 * sqrt((2 * beta)/(1 + beta)) * sqrt(2 * M_y_Rk * f_h1k * diam) # N
|
|
244
|
+
f = f + min(effet_corde, f*coef_limit_Johansen) # N
|
|
245
|
+
return a, b, c, d, e, f
|
|
246
|
+
|
|
247
|
+
calcul = val()
|
|
248
|
+
a = calcul[1][0] * si.N
|
|
249
|
+
b = calcul[1][1] * si.N
|
|
250
|
+
c = calcul[1][2] * si.N
|
|
251
|
+
d = calcul[1][3] * si.N
|
|
252
|
+
e = calcul[1][4] * si.N
|
|
253
|
+
f = calcul[1][5] * si.N
|
|
254
|
+
dicoRupture = {a: "A", b: "B", c: "C", d: "D", e: "E", f: "F"}
|
|
255
|
+
FvRk = min(a, b, c, d, e, f)
|
|
256
|
+
mode_rupture = dicoRupture[FvRk]
|
|
257
|
+
|
|
258
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
259
|
+
def val2():
|
|
260
|
+
F_v_Rk = min(a, b, c, d, e, f)
|
|
261
|
+
mode_rupture
|
|
262
|
+
return F_v_Rk, mode_rupture
|
|
263
|
+
calcul2 = val2()
|
|
264
|
+
|
|
265
|
+
else:
|
|
266
|
+
@handcalc(override="long", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
267
|
+
def val():
|
|
268
|
+
effet_corde = F_ax_Rk/4 # N
|
|
269
|
+
beta = f_h2k / f_h1k
|
|
270
|
+
g = f_h1k * t_1 * diam # N
|
|
271
|
+
h = 0.5 * f_h2k * t_2 * diam # N
|
|
272
|
+
j = 1.05 * g / (2 + beta) * (sqrt(2 * beta * (1 + beta) + (4 * beta * (2 + beta) * M_y_Rk)/ (f_h1k * t_1**2 * diam)) - beta) # N
|
|
273
|
+
j = j + min(effet_corde, j*coef_limit_Johansen) # N
|
|
274
|
+
k = 1.15 * sqrt((2 * beta)/(1 + beta)) * sqrt(2 * M_y_Rk * f_h1k * diam) # N
|
|
275
|
+
k = k + min(effet_corde, k*coef_limit_Johansen) # N
|
|
276
|
+
return g, h, j, k
|
|
277
|
+
|
|
278
|
+
calcul = val()
|
|
279
|
+
g = calcul[1][0] * si.N
|
|
280
|
+
h = calcul[1][1] * si.N
|
|
281
|
+
j = calcul[1][2] * si.N
|
|
282
|
+
k = calcul[1][3] * si.N
|
|
283
|
+
FvRk = min(g, h, j, k)
|
|
284
|
+
dicoRupture = {g: "G", h: "H", j: "J", k: "K"}
|
|
285
|
+
mode_rupture = dicoRupture[FvRk]
|
|
286
|
+
|
|
287
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
288
|
+
def val2():
|
|
289
|
+
F_v_Rk = min(g, h, j, k)
|
|
290
|
+
mode_rupture
|
|
291
|
+
return F_v_Rk, mode_rupture
|
|
292
|
+
calcul2 = val2()
|
|
293
|
+
|
|
294
|
+
return (calcul[0] + calcul2[0], calcul2[1])
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
# 8.2.3 Assemblage bois métal
|
|
298
|
+
def _FvRk_BoisMetal(self, effet_corde: bool):
|
|
299
|
+
"""Calcul la capacité résistante en cisaillement de la tige en N par plan de cisaillement avec
|
|
300
|
+
t1 : valeur minimale entre epaisseur de l'élément bois latéral et la profondeur de pénétration en mm
|
|
301
|
+
t2 : epaisseur de l'élément bois central en mm
|
|
302
|
+
"""
|
|
303
|
+
diam = self.d.value * 10**3
|
|
304
|
+
M_y_Rk = self.MyRk[1].value * 10**3
|
|
305
|
+
coef_limit_Johansen = self.DICO_COEF_LIMITE.get(self.type_organe, 0)
|
|
306
|
+
if effet_corde:
|
|
307
|
+
F_ax_Rk = self.FaxRk.value
|
|
308
|
+
else:
|
|
309
|
+
F_ax_Rk = 0
|
|
310
|
+
|
|
311
|
+
if self._type_beam[0] == "Métal":
|
|
312
|
+
f_h2k = self.fh2k[1].value * 10**-6
|
|
313
|
+
t_2 = self.t2.value * 10**3
|
|
314
|
+
self.t = self.beam_1.t
|
|
315
|
+
if self.nCis == 2:
|
|
316
|
+
self.pos_plaq = "externe"
|
|
317
|
+
else:
|
|
318
|
+
f_h1k = self.fh1k[1].value * 10**-6
|
|
319
|
+
t_1 = self.t1.value * 10**3
|
|
320
|
+
self.t = self.beam_2.t
|
|
321
|
+
if self.nCis == 2:
|
|
322
|
+
self.pos_plaq = "centrale"
|
|
323
|
+
|
|
324
|
+
if self.t <= 0.5 * self.d:
|
|
325
|
+
self.type_plaque = "mince"
|
|
326
|
+
|
|
327
|
+
elif self.d <= self.t:
|
|
328
|
+
self.type_plaque = "epaisse"
|
|
329
|
+
|
|
330
|
+
else:
|
|
331
|
+
self.type_plaque = "intermédiaire"
|
|
332
|
+
print("ATTENTION interpolation linéaire à faire ! EC5-8.2.3.1")
|
|
333
|
+
|
|
334
|
+
if self.type_plaque == "mince" and self.nCis == 1:
|
|
335
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
336
|
+
def val():
|
|
337
|
+
effet_corde = F_ax_Rk/4 # N
|
|
338
|
+
a = 0.4 * f_h1k * t_1 * diam # N
|
|
339
|
+
b = 1.15 * sqrt(2 * M_y_Rk * f_h1k * diam) # N
|
|
340
|
+
b = b + min(effet_corde, b*coef_limit_Johansen) # N
|
|
341
|
+
return a, b
|
|
342
|
+
|
|
343
|
+
calcul = val()
|
|
344
|
+
a = calcul[1][0] * si.N
|
|
345
|
+
b = calcul[1][1] * si.N
|
|
346
|
+
dicoRupture = {a: "A", b: "B"}
|
|
347
|
+
FvRk = min(a, b)
|
|
348
|
+
mode_rupture = dicoRupture[FvRk]
|
|
349
|
+
|
|
350
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
351
|
+
def val2():
|
|
352
|
+
F_v_Rk = min(a, b)
|
|
353
|
+
mode_rupture
|
|
354
|
+
return F_v_Rk, mode_rupture
|
|
355
|
+
calcul2 = val2()
|
|
356
|
+
|
|
357
|
+
elif self.type_plaque == "epaisse" and self.nCis == 1:
|
|
358
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
359
|
+
def val():
|
|
360
|
+
effet_corde = F_ax_Rk/4 # N
|
|
361
|
+
c = f_h1k * t_1 * diam # N
|
|
362
|
+
d = c * (sqrt(2 + (4 * M_y_Rk) / (f_h1k * diam * t_1 ** 2)) - 1) # N
|
|
363
|
+
d = d + min(effet_corde, d*coef_limit_Johansen) # N
|
|
364
|
+
e = 2.3 * sqrt(M_y_Rk * f_h1k * diam) # N
|
|
365
|
+
e = e + min(effet_corde, e*coef_limit_Johansen) # N
|
|
366
|
+
return c, d, e
|
|
367
|
+
|
|
368
|
+
calcul = val()
|
|
369
|
+
c = calcul[1][0] * si.N
|
|
370
|
+
d = calcul[1][1] * si.N
|
|
371
|
+
e = calcul[1][2] * si.N
|
|
372
|
+
dicoRupture = {c: "C", d: "D", e: "E"}
|
|
373
|
+
FvRk = min(c, d, e)
|
|
374
|
+
mode_rupture = dicoRupture[FvRk]
|
|
375
|
+
|
|
376
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
377
|
+
def val2():
|
|
378
|
+
F_v_Rk = min(c, d, e)
|
|
379
|
+
mode_rupture
|
|
380
|
+
return F_v_Rk, mode_rupture
|
|
381
|
+
calcul2 = val2()
|
|
382
|
+
|
|
383
|
+
elif self.nCis == 2 and self.pos_plaq == "centrale":
|
|
384
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
385
|
+
def val():
|
|
386
|
+
effet_corde = F_ax_Rk/4 # N
|
|
387
|
+
f = f_h1k * t_1 * diam # N
|
|
388
|
+
g = f * (sqrt(2 + (4 * M_y_Rk) / (f_h1k * diam * t_1 ** 2)) - 1) # N
|
|
389
|
+
g = g + min(effet_corde, g*coef_limit_Johansen) # N
|
|
390
|
+
h = 2.3 * sqrt(M_y_Rk * f_h1k * diam) # N
|
|
391
|
+
h = h + min(effet_corde, h*coef_limit_Johansen) # N
|
|
392
|
+
return f, g, h
|
|
393
|
+
|
|
394
|
+
calcul = val()
|
|
395
|
+
f = calcul[1][0] * si.N
|
|
396
|
+
g = calcul[1][1] * si.N
|
|
397
|
+
h = calcul[1][2] * si.N
|
|
398
|
+
dicoRupture = {f: "F", g: "G", h: "H"}
|
|
399
|
+
FvRk = min(f, g, h)
|
|
400
|
+
mode_rupture = dicoRupture[FvRk]
|
|
401
|
+
|
|
402
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
403
|
+
def val2():
|
|
404
|
+
F_v_Rk = min(f, g, h)
|
|
405
|
+
mode_rupture
|
|
406
|
+
return F_v_Rk, mode_rupture
|
|
407
|
+
calcul2 = val2()
|
|
408
|
+
|
|
409
|
+
elif self.type_plaque == "mince" and self.nCis == 2 and self.pos_plaq != "centrale":
|
|
410
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
411
|
+
def val():
|
|
412
|
+
effet_corde = F_ax_Rk/4 # N
|
|
413
|
+
j = 0.5 * f_h2k * t_2 * diam # N
|
|
414
|
+
k = 1.15 * sqrt(2 * M_y_Rk * f_h2k * diam) # N
|
|
415
|
+
k = k + min(effet_corde, k*coef_limit_Johansen) # N
|
|
416
|
+
return j, k
|
|
417
|
+
|
|
418
|
+
calcul = val()
|
|
419
|
+
j = calcul[1][0] * si.N
|
|
420
|
+
k = calcul[1][1] * si.N
|
|
421
|
+
dicoRupture = {j: "J", k: "K"}
|
|
422
|
+
FvRk = min(j, k)
|
|
423
|
+
mode_rupture = dicoRupture[FvRk]
|
|
424
|
+
|
|
425
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
426
|
+
def val2():
|
|
427
|
+
F_v_Rk = min(j, k)
|
|
428
|
+
mode_rupture
|
|
429
|
+
return F_v_Rk, mode_rupture
|
|
430
|
+
calcul2 = val2()
|
|
431
|
+
|
|
432
|
+
else:
|
|
433
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
434
|
+
def val():
|
|
435
|
+
effet_corde = F_ax_Rk/4 # N
|
|
436
|
+
l = 0.5 * f_h2k * t_2 * diam # N
|
|
437
|
+
m = 2.3 * sqrt(M_y_Rk * f_h2k * diam) # N
|
|
438
|
+
m = m + min(effet_corde, m*coef_limit_Johansen) # N
|
|
439
|
+
return l, m
|
|
440
|
+
|
|
441
|
+
calcul = val()
|
|
442
|
+
l = calcul[1][0] * si.N
|
|
443
|
+
m = calcul[1][1] * si.N
|
|
444
|
+
dicoRupture = {l: "L", m: "M"}
|
|
445
|
+
FvRk = min(l, m)
|
|
446
|
+
mode_rupture = dicoRupture[FvRk]
|
|
447
|
+
|
|
448
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
449
|
+
def val2():
|
|
450
|
+
F_v_Rk = min(l, m)
|
|
451
|
+
mode_rupture
|
|
452
|
+
return F_v_Rk, mode_rupture
|
|
453
|
+
calcul2 = val2()
|
|
454
|
+
|
|
455
|
+
return (calcul[0] + calcul2[0], calcul2[1])
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
# 8.1.2 Assemblage par organe multiple
|
|
459
|
+
|
|
460
|
+
def FvRk(self, effet_corde: bool=("True", "False")):
|
|
461
|
+
"""Calcul la valeur de calcul caractéristique de résistance au cisaillement de l'assemblage en N
|
|
462
|
+
|
|
463
|
+
Args:
|
|
464
|
+
effet_corde (bool): prise en compte de l'effet de corde, si oui alors True.
|
|
465
|
+
Attention: pour que l'effet de corde soit prit en compte, il faut que le FaxRk du type de tige est été calculé préalablement.
|
|
466
|
+
|
|
467
|
+
Returns:
|
|
468
|
+
float: effort de reprise caractéristique de l'assemblage en N
|
|
469
|
+
"""
|
|
470
|
+
# Fvrktot : capacité résistante en cisaillement caractéristique avec la partie de Johansen + l'effet de corde en N
|
|
471
|
+
if self.type_assemblage == __class__.TYPE_ASSEMBLAGE[0]:
|
|
472
|
+
latex, self.Fv_Rk = self._FvRk_BoisBois(effet_corde)
|
|
473
|
+
else:
|
|
474
|
+
latex, self.Fv_Rk = self._FvRk_BoisMetal(effet_corde)
|
|
475
|
+
|
|
476
|
+
F_v_Rk = self.Fv_Rk[0]
|
|
477
|
+
n_file = self.nfile
|
|
478
|
+
n_ef = self._nef
|
|
479
|
+
n_cisaillement = self.nCis
|
|
480
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
481
|
+
def val():
|
|
482
|
+
F_v_Rk_ass = F_v_Rk * n_file * n_ef * n_cisaillement
|
|
483
|
+
return F_v_Rk_ass
|
|
484
|
+
FvRkass_latex, self.Fv_Rk_ass = val()
|
|
485
|
+
latex = latex + FvRkass_latex
|
|
486
|
+
return (latex, self.Fv_Rk_ass)
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
def F_Rd(self, F_Rk: si.kN, loadtype=Barre.LOAD_TIME):
|
|
490
|
+
"""Calcul la valeur de calcul (design) de résistance de l'assemblage en N avec :
|
|
491
|
+
|
|
492
|
+
Args:
|
|
493
|
+
F_rk (float): capacité résistante caractéristique de l'organe en kN
|
|
494
|
+
loadtype (str, optional): Durée de chargement (Permanente, Court terme etc.). Defaults to "Permanente"."""
|
|
495
|
+
F_Rk = F_Rk * si.kN
|
|
496
|
+
gamma_M = self.GAMMA_M_ASS
|
|
497
|
+
if "Métal" in self._type_beam:
|
|
498
|
+
if self._type_beam[0] == "Métal":
|
|
499
|
+
k_mod = self.beam_2._get_k_mod(loadtype)
|
|
500
|
+
else:
|
|
501
|
+
k_mod = self.beam_1._get_k_mod(loadtype)
|
|
502
|
+
else:
|
|
503
|
+
k_mod = sqrt(self.beam_1._get_k_mod(loadtype) * self.beam_2._get_k_mod(loadtype))
|
|
504
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
505
|
+
def val():
|
|
506
|
+
F_Rd = (F_Rk * k_mod) /gamma_M # Valeur de calcul (design)
|
|
507
|
+
return F_Rd
|
|
508
|
+
return val()
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
# Annexe A : Cisaillement de bloc
|
|
512
|
+
def FbsRk(self, dp:si.mm, a1:si.mm, a2:si.mm, a3t:si.mm, Kcr: float=0.67, num_beam: int=("1", "2")):
|
|
513
|
+
"""Calcul la valeur caractéristique en cisaillement de bloc en N pour l'élément 1 ou 2 de l'assemblage.
|
|
514
|
+
Attention pour que cette fonction puisse s'éxecuter il faut avoir préalablement éxécuté la fontion FvRk.
|
|
515
|
+
|
|
516
|
+
Args:
|
|
517
|
+
dp (float): diamètre de perçage en mm
|
|
518
|
+
a1 (float): pince longitudinale en mm
|
|
519
|
+
a2 (float): pince perpendiculaire en mm
|
|
520
|
+
a3t (float): pince en bord chargée suivant le file en mm
|
|
521
|
+
kcr (float, optional): coeff de réduction largeur en cisaillement.
|
|
522
|
+
Si aucune valeur n'est rentrée alors il sera automatiquement calculé. Defaults to 0.67.
|
|
523
|
+
num_beam (int, optional): numéro de l'élément à vérifier. Defaults to 1.
|
|
524
|
+
"""
|
|
525
|
+
diam = self.d
|
|
526
|
+
diam_percage = dp * si.mm
|
|
527
|
+
|
|
528
|
+
a_1 = a1 * si.mm
|
|
529
|
+
a_2 = a2 * si.mm
|
|
530
|
+
a_3_t = a3t * si.mm
|
|
531
|
+
M_y_Rk = self.MyRk[1]
|
|
532
|
+
n = self.n
|
|
533
|
+
n_file = self.nfile
|
|
534
|
+
|
|
535
|
+
mode_rupture = self.Fv_Rk[1]
|
|
536
|
+
|
|
537
|
+
# on calcul les valeur caractéristique de base de notre éléméent
|
|
538
|
+
if num_beam == 1:
|
|
539
|
+
parent_beam = self.beam_1
|
|
540
|
+
f_hk = self.fh1k[1]
|
|
541
|
+
t_1 = self.t1
|
|
542
|
+
else:
|
|
543
|
+
parent_beam = self.beam_2
|
|
544
|
+
f_hk = self.fh2k[1]
|
|
545
|
+
t_1 = self.t2
|
|
546
|
+
f_t0_k = float(parent_beam.caract_meca.loc["ft0k"]) * si.MPa
|
|
547
|
+
f_v_k = float(parent_beam.caract_meca.loc["fvk"]) * si.MPa
|
|
548
|
+
|
|
549
|
+
# On calcul le kcr si aucune valeur n'est donnée en argument
|
|
550
|
+
if not Kcr:
|
|
551
|
+
cis_beam = Cisaillement._from_parent_class(parent_beam)
|
|
552
|
+
K_cr = cis_beam.K_cr
|
|
553
|
+
else:
|
|
554
|
+
K_cr = Kcr
|
|
555
|
+
|
|
556
|
+
@handcalc(override="long", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
557
|
+
def l_net():
|
|
558
|
+
l_v_i = a_1 - diam_percage # Distance entre perçage dans le sens fil
|
|
559
|
+
L_net_v = 2 * (l_v_i * (n - 1) + a_3_t - (diam_percage / 2)) # Longueur résiduelle de la surface de rupture en cisaillement
|
|
560
|
+
|
|
561
|
+
l_t_i = a_2 - diam_percage # Distance entre perçage dans le sens perpendiculaire au fil
|
|
562
|
+
L_net_t = l_t_i * (n_file - 1) # Largeur résiduelle de la section perpendiculaire au fil
|
|
563
|
+
|
|
564
|
+
mode_rupture
|
|
565
|
+
return L_net_v, L_net_t
|
|
566
|
+
|
|
567
|
+
L_net_value = l_net()
|
|
568
|
+
latex = L_net_value[0]
|
|
569
|
+
L_net_v, L_net_t = L_net_value[1]
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
if mode_rupture in ("C", "F", "J", "L", "K", "M"):
|
|
573
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
574
|
+
def a_net_v():
|
|
575
|
+
A_net_v = L_net_v * (t_1 * K_cr)
|
|
576
|
+
return A_net_v
|
|
577
|
+
a_net_v_result = a_net_v()
|
|
578
|
+
latex = latex + a_net_v_result[0]
|
|
579
|
+
A_net_v = a_net_v_result[1]
|
|
580
|
+
else:
|
|
581
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
582
|
+
def a_net_v(t_ef):
|
|
583
|
+
A_net_v = L_net_v / 2 * (L_net_t + 2 * (t_ef * K_cr))
|
|
584
|
+
return A_net_v
|
|
585
|
+
|
|
586
|
+
match mode_rupture:
|
|
587
|
+
case "A":
|
|
588
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
589
|
+
def tef():
|
|
590
|
+
t_ef = 0.4*t_1 # Épaisseur efficace
|
|
591
|
+
return t_ef
|
|
592
|
+
case "B":
|
|
593
|
+
@handcalc(override="long", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
594
|
+
def tef():
|
|
595
|
+
t_ef = 1.4 * sqrt(M_y_Rk / (f_hk * diam)) # Épaisseur efficace
|
|
596
|
+
return t_ef
|
|
597
|
+
case "D"|"G":
|
|
598
|
+
@handcalc(override="long", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
599
|
+
def tef():
|
|
600
|
+
t_ef = t_1 * (sqrt(2 + (4 * M_y_Rk ) / (f_hk * diam * t_1**2)-1)) # Épaisseur efficace
|
|
601
|
+
return t_ef
|
|
602
|
+
case "E"|"H":
|
|
603
|
+
@handcalc(override="long", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
604
|
+
def tef():
|
|
605
|
+
t_ef = 2 * sqrt(M_y_Rk / (f_hk * diam)) # Épaisseur efficace
|
|
606
|
+
return t_ef
|
|
607
|
+
tef_result = tef()
|
|
608
|
+
a_net_v_result = a_net_v(tef_result[1])
|
|
609
|
+
latex = latex + tef_result[0] + a_net_v_result[0]
|
|
610
|
+
A_net_v = a_net_v_result[1]
|
|
611
|
+
|
|
612
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
613
|
+
def f_bs_Rk():
|
|
614
|
+
A_net_t = L_net_t * t_1
|
|
615
|
+
F_bs_Rk = max(0.7 * A_net_v * f_v_k, 1.5 * A_net_t * f_t0_k)
|
|
616
|
+
return F_bs_Rk
|
|
617
|
+
|
|
618
|
+
result = f_bs_Rk()
|
|
619
|
+
self.F_bs_Rk = result[1]
|
|
620
|
+
return (latex + result[0], self.F_bs_Rk)
|
|
621
|
+
|
|
622
|
+
def taux_cisaillement(self, Fv_Ed: si.kN, loadtype=Barre.LOAD_TIME):
|
|
623
|
+
"""Détermine le taux de cisaillement de l'assemblage
|
|
624
|
+
|
|
625
|
+
Args:
|
|
626
|
+
Fv_Ed (float): effort de cisaillement à reprendre en kN
|
|
627
|
+
"""
|
|
628
|
+
Fv_Rd_ass = self.F_Rd(self.Fv_Rk_ass.value*10**-3, loadtype)[1]
|
|
629
|
+
Fv_Ed = abs(Fv_Ed) * si.kN
|
|
630
|
+
@handcalc(override="long", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
631
|
+
def val():
|
|
632
|
+
taux_cisaillement = Fv_Ed / Fv_Rd_ass * 100
|
|
633
|
+
return taux_cisaillement
|
|
634
|
+
return val()
|
|
635
|
+
|
|
636
|
+
|
|
637
|
+
# ======================================================= POINTE =========================================================
|
|
638
|
+
# 8.3 Assemblage par pointes
|
|
639
|
+
|
|
640
|
+
class Pointe(Assemblage):
|
|
641
|
+
""" Défini un objet pointe avec :
|
|
642
|
+
d : diamètre de la pointe en mm (pour les pointe carrée = coté de la pointe)
|
|
643
|
+
d_tete : diamètre de la tête en mm
|
|
644
|
+
l : longueur sous la tête en mm
|
|
645
|
+
qualite = qualité de l'acier
|
|
646
|
+
n : nombre d'organe dans une file
|
|
647
|
+
alpha1 : angle entre l'effort de l'organe et le fil du bois 1 en °
|
|
648
|
+
alpha2 : angle entre l'effort de l'organe et le fil du bois 2 en °
|
|
649
|
+
type_organe : "Carrée" = False "Circulaire" = True
|
|
650
|
+
percage : "False", "True"
|
|
651
|
+
"""
|
|
652
|
+
|
|
653
|
+
TYPE_ASSEMBLAGE = ("Bois/Bois", ("CP", "Panneau dur", "PP/OSB"), "Bois/Métal")
|
|
654
|
+
QUALITE_ACIER = ('6.8', '8.8', '9.8', '10.9', '12.9')
|
|
655
|
+
TYPE_ORGANE = ("Pointe circulaire", "Pointe carrée", "Autres pointes")
|
|
656
|
+
|
|
657
|
+
def __init__(self, d:si.mm, d_tete:si.mm, l:si.mm, qualite: str=QUALITE_ACIER, n: int=1, alpha1: float=0, alpha2: float=0, type_organe: str=TYPE_ORGANE, percage: bool=("False", "True"), *args, **kwargs):
|
|
658
|
+
super().__init__(*args, **kwargs)
|
|
659
|
+
self.d = d * si.mm
|
|
660
|
+
self.d_tete = d_tete * si.mm
|
|
661
|
+
self.l = l * si.mm #longueur sous tête
|
|
662
|
+
self.qualite = qualite
|
|
663
|
+
self.n = n
|
|
664
|
+
self.fu = self.__qualite_acier.loc["fub"] *si.MPa
|
|
665
|
+
self.alpha = [alpha1, alpha2]
|
|
666
|
+
self.percage = percage
|
|
667
|
+
self.type_organe = type_organe
|
|
668
|
+
|
|
669
|
+
self.__t1_t2()
|
|
670
|
+
self._fhik()
|
|
671
|
+
|
|
672
|
+
|
|
673
|
+
@property
|
|
674
|
+
def __qualite_acier(self):
|
|
675
|
+
df = self._data_from_csv("qualite_acier.csv")
|
|
676
|
+
df = df.loc[self.qualite]
|
|
677
|
+
return df
|
|
678
|
+
|
|
679
|
+
@property
|
|
680
|
+
def _type_circulaire(self):
|
|
681
|
+
if self.type_organe == "Pointe carrée":
|
|
682
|
+
return False
|
|
683
|
+
else:
|
|
684
|
+
return True
|
|
685
|
+
|
|
686
|
+
|
|
687
|
+
def __t1_t2(self):
|
|
688
|
+
"""Retourne t1 et t2 en mm suivant l'EN 1995 §8.3.1.1
|
|
689
|
+
"""
|
|
690
|
+
l_pointe = self.d #Longueur de la pointe à déduire
|
|
691
|
+
if self.type_organe == "Tirefond":
|
|
692
|
+
l_pointe = self.d_vis
|
|
693
|
+
|
|
694
|
+
if self.nCis == 1:
|
|
695
|
+
if self._type_beam[0] in self.TYPE_BOIS_ASSEMBLAGE:
|
|
696
|
+
self.t1 = self.beam_1.b_calcul
|
|
697
|
+
else:
|
|
698
|
+
self.t1 = self.beam_1.t
|
|
699
|
+
|
|
700
|
+
if self._type_beam[1] in self.TYPE_BOIS_ASSEMBLAGE:
|
|
701
|
+
self.t2 = self.l - self.t1 - l_pointe
|
|
702
|
+
|
|
703
|
+
else:
|
|
704
|
+
if self._type_beam[0] in self.TYPE_BOIS_ASSEMBLAGE:
|
|
705
|
+
if "Bois/Métal" in self.type_assemblage:
|
|
706
|
+
b_beam_2 = self.beam_2.t + 2
|
|
707
|
+
else:
|
|
708
|
+
b_beam_2 = self.beam_2.b_calcul
|
|
709
|
+
self.t1 = min(self.beam_1.b_calcul, self.l - self.beam_1.b_calcul - b_beam_2 - l_pointe)
|
|
710
|
+
else:
|
|
711
|
+
print("Il n'est pas possible sauf erreur d'avoir un assemblage double cisaillement avec une pointe !")
|
|
712
|
+
if self._type_beam[1] in self.TYPE_BOIS_ASSEMBLAGE:
|
|
713
|
+
self.t2 = self.beam_2.b_calcul
|
|
714
|
+
else:
|
|
715
|
+
self.t2 = self.beam_2.t
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
@property
|
|
719
|
+
def MyRk(self):
|
|
720
|
+
""" Défini le moment d'écoulement plastique d'une pointe en N.mm avec:
|
|
721
|
+
d : diamètre de la pointe en mm (pour les pointe carrée = coté de la pointe)
|
|
722
|
+
fu : la résistance caractéristique en traction du fil d'acier en N/mm2 """
|
|
723
|
+
f_u = self.fu.value * 10**-6
|
|
724
|
+
d = self.d.value * 10**3
|
|
725
|
+
if self.fu >= 600:
|
|
726
|
+
if self._type_circulaire == True:
|
|
727
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
728
|
+
def val():
|
|
729
|
+
M_y_Rk = 0.3 * f_u* d**2.6 # N.mm
|
|
730
|
+
return M_y_Rk * si.N*si.mm
|
|
731
|
+
else:
|
|
732
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
733
|
+
def val():
|
|
734
|
+
M_y_Rk = 0.45 * f_u* d**2.6 # N.mm
|
|
735
|
+
return M_y_Rk * si.N*si.mm
|
|
736
|
+
return val()
|
|
737
|
+
else:
|
|
738
|
+
print("La résistance du fil en traction est inférieur à 600 MPa, vérifier vos données !")
|
|
739
|
+
|
|
740
|
+
|
|
741
|
+
def _fhk_bois(self, beam:object):
|
|
742
|
+
""" Calcul la portance locale des pointes inférieur à 8mm dans le bois et le LVL en MPa
|
|
743
|
+
"""
|
|
744
|
+
d = self.d.value * 10**3
|
|
745
|
+
rho_k = beam.rho_k
|
|
746
|
+
if self.percage:
|
|
747
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
748
|
+
def val():
|
|
749
|
+
fhk = 0.082 * (1 - 0.01 * d) * rho_k # MPa
|
|
750
|
+
return fhk * si.MPa
|
|
751
|
+
else:
|
|
752
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
753
|
+
def val():
|
|
754
|
+
fhk = 0.082 * rho_k * d**(-0.3) # MPa
|
|
755
|
+
return fhk * si.MPa
|
|
756
|
+
return val()
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
def _fhk_panneau(self, beam:object):
|
|
760
|
+
"""Calcul la portance locale des pointes dans les panneaux en MPa
|
|
761
|
+
|
|
762
|
+
Args:
|
|
763
|
+
t (int): épaisseur du panneau en mm
|
|
764
|
+
self.d_tete (int): diamètre de la tête de la pointe
|
|
765
|
+
|
|
766
|
+
Returns:
|
|
767
|
+
float: portance locale en MPa
|
|
768
|
+
"""
|
|
769
|
+
d = self.d.value * 10**3
|
|
770
|
+
b_calcul = beam.b_calcul
|
|
771
|
+
rho_k = beam.rho_k
|
|
772
|
+
if self.d_tete >= 2*d:
|
|
773
|
+
if beam.type_bois == "CP":
|
|
774
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
775
|
+
def val():
|
|
776
|
+
fhk = 0.11 * rho_k * d**-0.3 # MPa
|
|
777
|
+
return fhk * si.MPa
|
|
778
|
+
elif beam.type_bois == "Panneau dur":
|
|
779
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
780
|
+
def val():
|
|
781
|
+
fhk = 30 * d**-0.3 * b_calcul**0.6 # MPa
|
|
782
|
+
return fhk * si.MPa
|
|
783
|
+
else:
|
|
784
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
785
|
+
def val():
|
|
786
|
+
fhk = 65 * d**-0.7 * b_calcul**0.1 # MPa
|
|
787
|
+
return fhk * si.MPa
|
|
788
|
+
return val()
|
|
789
|
+
else:
|
|
790
|
+
print(f"La tête de la pointe doit être au moins égale à {2*d} mm")
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
def _fhik(self) -> tuple:
|
|
794
|
+
"""Calcul la portance locale d'une pointe en MPa dans les deux éléments de l'assemblage
|
|
795
|
+
|
|
796
|
+
ATTENTION: Pas de prise en compte des panneaux durs au sens de la norme EN 622-2
|
|
797
|
+
|
|
798
|
+
Returns:
|
|
799
|
+
tuple: (fh1k, fh2k) en MPa
|
|
800
|
+
"""
|
|
801
|
+
dict_beam = {"1": {}, "2": {}}
|
|
802
|
+
for i, beam in enumerate([self.beam_1, self.beam_2]):
|
|
803
|
+
if self._type_beam[i] == "Bois":
|
|
804
|
+
dict_beam[str(i+1)]["fhk"] = self._fhk_bois(beam)
|
|
805
|
+
|
|
806
|
+
elif self._type_beam[i] == "CP" or self._type_beam[i] == "PP/OSB":
|
|
807
|
+
dict_beam[str(i+1)]["fhk"] = self._fhk_panneau(beam)
|
|
808
|
+
|
|
809
|
+
else:
|
|
810
|
+
dict_beam[str(i+1)]["fhk"] = 0
|
|
811
|
+
|
|
812
|
+
# if self._type_beam[i] != "Métal":
|
|
813
|
+
# if i:
|
|
814
|
+
# self.t2 = self.beam_2.b_calcul
|
|
815
|
+
# else:
|
|
816
|
+
# self.t1 = self.beam_1.b_calcul
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
self.fh1k = dict_beam["1"]["fhk"]
|
|
820
|
+
self.fh2k = dict_beam["2"]["fhk"]
|
|
821
|
+
return self.fh1k, self.fh2k
|
|
822
|
+
|
|
823
|
+
|
|
824
|
+
def _kef(self, a1:int):
|
|
825
|
+
""" coefficient donnée dans le tableau 8.1 fonction de a1 et du percage qui réduit le nombre efficace de pointe dans le sens
|
|
826
|
+
du fil avec :
|
|
827
|
+
a1 : l'espacement entre tige dans le sens du fil du bois """
|
|
828
|
+
if self.type_organe == "Tirefond":
|
|
829
|
+
d = self.d_vis
|
|
830
|
+
else:
|
|
831
|
+
d = self.d
|
|
832
|
+
listeTab = (d * 4, d * 7, d *
|
|
833
|
+
10, d * 14, ("x", 0.7, 0.85, 1))
|
|
834
|
+
|
|
835
|
+
if a1 >= listeTab[3]:
|
|
836
|
+
kef = 1
|
|
837
|
+
j = 0
|
|
838
|
+
for i in range(4):
|
|
839
|
+
|
|
840
|
+
if listeTab[i] <= a1:
|
|
841
|
+
|
|
842
|
+
if a1 == listeTab[i]:
|
|
843
|
+
kef = listeTab[4][i]
|
|
844
|
+
|
|
845
|
+
if kef == "x" and self.percage == False:
|
|
846
|
+
kef = 0
|
|
847
|
+
|
|
848
|
+
elif kef == "x" and self.percage == True:
|
|
849
|
+
kef = 0.5
|
|
850
|
+
j += 1
|
|
851
|
+
|
|
852
|
+
else:
|
|
853
|
+
if listeTab[4][j-1] == "x" and self.percage == False:
|
|
854
|
+
kef = interpolationLineaire(
|
|
855
|
+
a1, listeTab[j-1], listeTab[j], 0, listeTab[4][j])
|
|
856
|
+
|
|
857
|
+
elif listeTab[4][j-1] == "x" and self.percage == True:
|
|
858
|
+
kef = interpolationLineaire(
|
|
859
|
+
a1, listeTab[j-1], listeTab[j], 0.5, listeTab[4][j])
|
|
860
|
+
|
|
861
|
+
else:
|
|
862
|
+
kef = interpolationLineaire(
|
|
863
|
+
a1, listeTab[j-1], listeTab[j], listeTab[4][j-1], listeTab[4][j])
|
|
864
|
+
self.kef = kef
|
|
865
|
+
return self.kef
|
|
866
|
+
|
|
867
|
+
|
|
868
|
+
def nef(self, a1_beam1:int, a1_beam2:int):
|
|
869
|
+
"""Défini le nombre efficace d'organe dans une file avec :
|
|
870
|
+
a1_beam1 : espacement entre les organes dans la barre 1 en mm
|
|
871
|
+
a1_beam2 : espacement entre les organes dans la barre 2 en mm"""
|
|
872
|
+
nef_list = []
|
|
873
|
+
for i, _ in enumerate([self.beam_1, self.beam_2]):
|
|
874
|
+
if i:
|
|
875
|
+
a_1 = a1_beam2 * si.mm
|
|
876
|
+
n = self.nfile
|
|
877
|
+
else:
|
|
878
|
+
a_1 = a1_beam1 * si.mm
|
|
879
|
+
n = self.n
|
|
880
|
+
|
|
881
|
+
k_ef = self._kef(a_1)
|
|
882
|
+
|
|
883
|
+
if n == 1:
|
|
884
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
885
|
+
def val():
|
|
886
|
+
n_ef =1
|
|
887
|
+
return n_ef
|
|
888
|
+
nef_list.append(val())
|
|
889
|
+
else :
|
|
890
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
891
|
+
def val():
|
|
892
|
+
n_ef = n**k_ef
|
|
893
|
+
return n_ef
|
|
894
|
+
nef_list.append(val())
|
|
895
|
+
result = self._min_nef(nef_list)
|
|
896
|
+
self._nef = result[1]
|
|
897
|
+
return result
|
|
898
|
+
|
|
899
|
+
# def FvRk(self, effet_corde: bool=("True", "False")):
|
|
900
|
+
# """Calcul la valeur de calcul caractéristique de résistance au cisaillement de l'assemblage en N
|
|
901
|
+
|
|
902
|
+
# Args:
|
|
903
|
+
# effet_corde (bool): prise en compte de l'effet de corde, si oui alors True.
|
|
904
|
+
|
|
905
|
+
# Returns:
|
|
906
|
+
# float: effort de reprise caractéristique de l'assemblage en N
|
|
907
|
+
# """
|
|
908
|
+
# super()._FvRk(effet_corde)
|
|
909
|
+
|
|
910
|
+
# def FbsRk(self, dp:float, a1:float, a2:float, a3t:float, Kcr: float=0.67, num_beam: int=("1", "2")):
|
|
911
|
+
# """Calcul la valeur caractéristique en cisaillement de bloc en N pour l'élément 1 ou 2 de l'assemblage.
|
|
912
|
+
# Attention pour que cette fonction puisse s'éxecuter il faut avoir préalablement éxécuté la fontion FvRk.
|
|
913
|
+
|
|
914
|
+
# Args:
|
|
915
|
+
# dp (float): diamètre de perçage en mm
|
|
916
|
+
# a1 (float): pince longitudinale en mm
|
|
917
|
+
# a2 (float): pince perpendiculaire en mm
|
|
918
|
+
# a3t (float): pince en bord chargée suivant le file en mm
|
|
919
|
+
# kcr (float, optional): coeff de réduction largeur en cisaillement.
|
|
920
|
+
# Si aucune valeur n'est rentrée alors il sera automatiquement calculé. Defaults to 0.67.
|
|
921
|
+
# num_beam (int, optional): numéro de l'élément à vérifier. Defaults to 1.
|
|
922
|
+
# """
|
|
923
|
+
# super()._FbsRk(dp, a1, a2, a3t, Kcr, num_beam)
|
|
924
|
+
|
|
925
|
+
@property
|
|
926
|
+
def pince(self):
|
|
927
|
+
"""Défini les différentes pinces minimales pour une pointe en mm avec :
|
|
928
|
+
alpha : angle entre l'effort de l'organe et le fil du bois en °
|
|
929
|
+
d : diamètre efficace de la pointe ou du tire fond si d<=6mm en mm """
|
|
930
|
+
|
|
931
|
+
dict_pince = {}
|
|
932
|
+
if self.type_organe == "Tirefond":
|
|
933
|
+
self.d = self.d_vis
|
|
934
|
+
for i, beam in enumerate([self.beam_1, self.beam_2]):
|
|
935
|
+
if not self._type_beam[i] in self.TYPE_BOIS_ASSEMBLAGE:
|
|
936
|
+
continue
|
|
937
|
+
|
|
938
|
+
alpha = self.alpha[i]
|
|
939
|
+
rho_k = beam.rho_k
|
|
940
|
+
if self.percage == True:
|
|
941
|
+
a1 = round((4 + mt.cos(mt.radians(alpha))) * self.d, 1)
|
|
942
|
+
a2 = round((3 + mt.sin(mt.radians(alpha))) * self.d, 1)
|
|
943
|
+
a3t = round((7 + 5 * mt.cos(mt.radians(alpha))) * self.d, 1)
|
|
944
|
+
a3c = round(7 * self.d, 1)
|
|
945
|
+
a4c = round(3 * self.d, 1)
|
|
946
|
+
|
|
947
|
+
if self.d < 5:
|
|
948
|
+
a4t = round((3 + 2 * mt.sin(mt.radians(alpha))) * self.d, 1)
|
|
949
|
+
else:
|
|
950
|
+
a4t = round((3 + 4 * mt.sin(mt.radians(alpha))) * self.d, 1)
|
|
951
|
+
else:
|
|
952
|
+
if rho_k <= 420:
|
|
953
|
+
if self.d < 5:
|
|
954
|
+
print (mt.cos(mt.radians(alpha)))
|
|
955
|
+
a1 = round((5 + 5 * mt.cos(mt.radians(alpha))) * self.d, 1)
|
|
956
|
+
a4t = round((5 + 2 * mt.sin(mt.radians(alpha))) * self.d, 1)
|
|
957
|
+
else:
|
|
958
|
+
a1 = round((5 + 7 * mt.cos(mt.radians(alpha))) * self.d, 1)
|
|
959
|
+
a4t = round((5 + 5 * mt.sin(mt.radians(alpha))) * self.d, 1)
|
|
960
|
+
|
|
961
|
+
a2 = round(5 * self.d, 1)
|
|
962
|
+
a3t = round((10 + 5 * mt.cos(mt.radians(alpha))) * self.d, 1)
|
|
963
|
+
a3c = round(10 * self.d, 1)
|
|
964
|
+
a4c = a2
|
|
965
|
+
|
|
966
|
+
elif rho_k > 420 and rho_k <= 500:
|
|
967
|
+
a1 = round((7 + 8 * mt.cos(mt.radians(alpha))) * self.d, 1)
|
|
968
|
+
a2 = round(7 * self.d, 1)
|
|
969
|
+
a3t = round((15 + 5 * mt.cos(mt.radians(alpha))) * self.d, 1)
|
|
970
|
+
a3c = round(15 * self.d, 1)
|
|
971
|
+
a4c = a2
|
|
972
|
+
|
|
973
|
+
if self.d < 5:
|
|
974
|
+
a4t = round((7 + 2 * mt.sin(mt.radians(alpha))) * self.d, 1)
|
|
975
|
+
else:
|
|
976
|
+
a4t = round((7 + 5 * mt.sin(mt.radians(alpha))) * self.d, 1)
|
|
977
|
+
else:
|
|
978
|
+
print("Il faut absolument prépercer au dessus de rho,k: 500 kg/m3")
|
|
979
|
+
|
|
980
|
+
if self.type_assemblage == __class__.TYPE_ASSEMBLAGE[0]: #Si assemblage bois bois
|
|
981
|
+
pass
|
|
982
|
+
|
|
983
|
+
elif self.type_assemblage == __class__.TYPE_ASSEMBLAGE[1]: #Si assemblage bois métal
|
|
984
|
+
a1 = round(a1 * 0.7, 1)
|
|
985
|
+
a2 = round(a2 * 0.7, 1)
|
|
986
|
+
|
|
987
|
+
else: #Si assemblage bois panneau
|
|
988
|
+
a1 = round(a1 * 0.85, 1)
|
|
989
|
+
a2 = round(a2 * 0.85, 1)
|
|
990
|
+
if beam.type_bois == "CP":
|
|
991
|
+
a3t = round((3 + 4 * mt.sin(mt.radians(alpha))) * self.d, 1)
|
|
992
|
+
a3c = round(3 * self.d, 1)
|
|
993
|
+
a4t = a3t
|
|
994
|
+
a4c = a3c
|
|
995
|
+
|
|
996
|
+
dict_pince["barre "+str(i+1)] = {"a1": a1, "a2":a2, "a3t": a3t, "a3c": a3c, "a4t": a4t, "a4c": a4c}
|
|
997
|
+
return dict_pince
|
|
998
|
+
|
|
999
|
+
|
|
1000
|
+
def prepercage(self, sensible: bool=("False", "True")):
|
|
1001
|
+
"""Défini l'épaisseur en mm minimale pour éviter le pré-perçage des pointes
|
|
1002
|
+
|
|
1003
|
+
Args:
|
|
1004
|
+
sensible (bool, optional): Défini si le bois utilisé est sensible à la fissuration (selon AN §8.3.1.2(7) douglas et pin maritime). Defaults to False.
|
|
1005
|
+
|
|
1006
|
+
Returns:
|
|
1007
|
+
int: l'épaisseur du bois en mm
|
|
1008
|
+
"""
|
|
1009
|
+
if sensible:
|
|
1010
|
+
t = max(14 * self.d,
|
|
1011
|
+
(13 * self.d - 30) * (self.pk / 200))
|
|
1012
|
+
else:
|
|
1013
|
+
t = max(7 * self.d,
|
|
1014
|
+
(13 * self.d - 30) * (self.pk / 400))
|
|
1015
|
+
print(f"l'épaisseur minimale pour éviter le pré-perçage est de {t} mm")
|
|
1016
|
+
return int(t)
|
|
1017
|
+
|
|
1018
|
+
|
|
1019
|
+
|
|
1020
|
+
|
|
1021
|
+
|
|
1022
|
+
|
|
1023
|
+
# ======================================================= BOULON =========================================================
|
|
1024
|
+
# 8.5 Assemblage par boulon
|
|
1025
|
+
|
|
1026
|
+
class Boulon(Assemblage):
|
|
1027
|
+
""" Défini un objet boulon avec :
|
|
1028
|
+
d : diamètre efficace du boulon (ou du tire fond si >6mm) en mm
|
|
1029
|
+
fuk : la valeur caractéristique de résistance à la traction du boulon en N/mm2
|
|
1030
|
+
n : nombre de boulons dans une file
|
|
1031
|
+
alpha 1 : angle entre l'effort de l'organe et le fil du bois en ° pour la barre 1
|
|
1032
|
+
alpha 2 : angle entre l'effort de l'organe et le fil du bois en ° pour la barre 2
|
|
1033
|
+
|
|
1034
|
+
t1 (int, optional): longueur de contact avec la tige pour la pièce 1 en mm.
|
|
1035
|
+
ATTENTION : Cet argument n'est pas obligatoire par défaut, il est calculé par le type de tige utilisée.
|
|
1036
|
+
Il n'est nécessaire de le remplir uniquement si vous avez un t1 spécifique, par exemple avec une chapelle réduisant ainsi la portance local à une longueur inférieur à celle de l'épaisseur de la pièce 1.
|
|
1037
|
+
|
|
1038
|
+
t2 (int, optional): longueur de contact avec la tige pour la pièce 2 en mm.
|
|
1039
|
+
ENTION : Même chose que pour t1 mais pour la pièce 2.
|
|
1040
|
+
"""
|
|
1041
|
+
|
|
1042
|
+
QUALITE_ACIER = tuple(Assemblage._data_from_csv(Assemblage, "qualite_acier.csv").index)
|
|
1043
|
+
|
|
1044
|
+
def __init__(self, d:si.mm, qualite: str=QUALITE_ACIER, n: int=1, alpha1: float=0, alpha2: float=0, t1: int=0, t2: int=0, **kwargs):
|
|
1045
|
+
super().__init__(**kwargs)
|
|
1046
|
+
self.type_organe = "Boulon"
|
|
1047
|
+
if "type_organe" in kwargs.keys():
|
|
1048
|
+
self.type_organe = kwargs.pop("type_organe")
|
|
1049
|
+
self.d = d * si.mm
|
|
1050
|
+
self.qualite = qualite
|
|
1051
|
+
self.fuk = self.__qualite_acier.loc["fub"] *si.MPa
|
|
1052
|
+
self.n = n
|
|
1053
|
+
self._nef = n
|
|
1054
|
+
self.alpha = [alpha1, alpha2]
|
|
1055
|
+
self.t1 = t1
|
|
1056
|
+
self.t2 = t2
|
|
1057
|
+
|
|
1058
|
+
self.__t1_t2()
|
|
1059
|
+
self._fhik()
|
|
1060
|
+
|
|
1061
|
+
@property
|
|
1062
|
+
def __qualite_acier(self):
|
|
1063
|
+
df = self._data_from_csv("qualite_acier.csv")
|
|
1064
|
+
df = df.loc[self.qualite]
|
|
1065
|
+
return df
|
|
1066
|
+
|
|
1067
|
+
|
|
1068
|
+
# 8.5.1 Boulons chargés latéralement
|
|
1069
|
+
# 8.5.1.1 Généralité et assemblage bois/bois
|
|
1070
|
+
|
|
1071
|
+
def __t1_t2(self):
|
|
1072
|
+
"""Retourne t1 et t2 en mm suivant l'EN 1995 §8.3.1.1
|
|
1073
|
+
"""
|
|
1074
|
+
for i, _ in enumerate([self.beam_1, self.beam_2]):
|
|
1075
|
+
if self._type_beam[i] != "Métal":
|
|
1076
|
+
if not i:
|
|
1077
|
+
if not self.t1:
|
|
1078
|
+
if self.type_organe == "Tirefond" and self.nCis == 2:
|
|
1079
|
+
if "Bois/Métal" in self.type_assemblage:
|
|
1080
|
+
b_beam_2 = self.beam_2.t + 2
|
|
1081
|
+
else:
|
|
1082
|
+
b_beam_2 = self.beam_2.b_calcul
|
|
1083
|
+
l_pointe = self.d_vis
|
|
1084
|
+
print(self.l , self.beam_1.b_calcul , b_beam_2 , l_pointe)
|
|
1085
|
+
self.t1 = min(self.beam_1.b_calcul, self.l - self.beam_1.b_calcul - b_beam_2 - l_pointe)
|
|
1086
|
+
continue
|
|
1087
|
+
self.t1 = self.beam_1.b_calcul
|
|
1088
|
+
else:
|
|
1089
|
+
self.t1 = self.t1 * si.mm
|
|
1090
|
+
else:
|
|
1091
|
+
l_pointe = 0
|
|
1092
|
+
if self.type_organe == "Tirefond":
|
|
1093
|
+
l_pointe = self.d_vis
|
|
1094
|
+
l_vis = self.l
|
|
1095
|
+
if i:
|
|
1096
|
+
if not self.t2:
|
|
1097
|
+
self.t2 = min(self.beam_2.b_calcul,l_vis-l_pointe-self.t1)
|
|
1098
|
+
else:
|
|
1099
|
+
self.t2 = self.t2 * si.mm
|
|
1100
|
+
else:
|
|
1101
|
+
if i:
|
|
1102
|
+
if not self.t2:
|
|
1103
|
+
self.t2 = self.beam_2.b_calcul
|
|
1104
|
+
else:
|
|
1105
|
+
self.t2 = self.t2 * si.mm
|
|
1106
|
+
|
|
1107
|
+
|
|
1108
|
+
def _fh0k(self, beam: object):
|
|
1109
|
+
"""Calcul la portance locale d'un boulon bois/bois ou d'un tire fond si d>6mm avec :
|
|
1110
|
+
beam: poutre à calculer
|
|
1111
|
+
"""
|
|
1112
|
+
rho_k = beam.rho_k
|
|
1113
|
+
d = self.d.value *10**3
|
|
1114
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
1115
|
+
def val():
|
|
1116
|
+
f_h0k = 0.082 * (1 - 0.01 * d) * rho_k # MPa
|
|
1117
|
+
return f_h0k * si.MPa
|
|
1118
|
+
return val()
|
|
1119
|
+
|
|
1120
|
+
|
|
1121
|
+
def _K_90(self, beam: object):
|
|
1122
|
+
"""Coef. modélisant la diminution de portance local quand un angle est donnée entre l'effort et le fil avec
|
|
1123
|
+
beam: poutre à calculer"""
|
|
1124
|
+
|
|
1125
|
+
if beam.classe[0:1] == "C" or beam.classe[0:2] == "GL":
|
|
1126
|
+
type_b = "C"
|
|
1127
|
+
elif beam.classe[0:3] == "LVL":
|
|
1128
|
+
type_b = "LVL"
|
|
1129
|
+
else:
|
|
1130
|
+
type_b = "D"
|
|
1131
|
+
|
|
1132
|
+
if type_b == "C":
|
|
1133
|
+
ck90 = 1.35 + 0.015 * self.d.value *10**3
|
|
1134
|
+
elif type_b == "LVL":
|
|
1135
|
+
ck90 = 1.30 + 0.015 * self.d.value *10**3
|
|
1136
|
+
else:
|
|
1137
|
+
ck90 = 0.9 + 0.015 * self.d.value *10**3
|
|
1138
|
+
return ck90
|
|
1139
|
+
|
|
1140
|
+
|
|
1141
|
+
def _fhak(self, fh0k:float, k_90:float, alpha):
|
|
1142
|
+
"""Calcul la portance locale d'un boulon bois/bois ou d'un tire fond si d>6mm par rapport à un effort donné à un angle
|
|
1143
|
+
du fil en MPa avec :
|
|
1144
|
+
fh0k : portance locale dans le sens du fil d'un boulon
|
|
1145
|
+
alpha : angle entre l'effort de l'organe et le fil du bois en °
|
|
1146
|
+
k90 : coef. de réduction de la portance locale quand un effort à un angle par rapport au fil du bois"""
|
|
1147
|
+
f_h0k = fh0k[1]
|
|
1148
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
1149
|
+
def val():
|
|
1150
|
+
f_h_alpha_k = f_h0k / (k_90 * sin(radians(alpha)) ** 2 + cos(radians(alpha)) ** 2)
|
|
1151
|
+
return f_h_alpha_k
|
|
1152
|
+
return val()
|
|
1153
|
+
|
|
1154
|
+
|
|
1155
|
+
# 8.5.1.1 Généralité et assemblage bois/panneaux
|
|
1156
|
+
def _fhk(self, beam:object):
|
|
1157
|
+
""" Calcul la portance locale d'un boulon dans un assemblage bois/panneaux en MPa avec :
|
|
1158
|
+
d : diamètre efficace du boulon (ou du tire fond si >6mm) en mm
|
|
1159
|
+
rho_k : masse volumique caractéristique du contreplaqué en kg/m3
|
|
1160
|
+
ep : epaisseur du panneau en mm """
|
|
1161
|
+
rho_k = beam.rho_k
|
|
1162
|
+
d = self.d.value *10**3
|
|
1163
|
+
ep = beam.b_calcul.value *10**3
|
|
1164
|
+
|
|
1165
|
+
if beam.type_bois == "CP":
|
|
1166
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
1167
|
+
def val():
|
|
1168
|
+
f_hk = 0.11 * (1 - 0.01 * d) * rho_k # MPa
|
|
1169
|
+
return f_hk
|
|
1170
|
+
else:
|
|
1171
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
1172
|
+
def val():
|
|
1173
|
+
f_hk = 50 * (d**(-0.6)) * (ep**0.2) # MPa
|
|
1174
|
+
return f_hk
|
|
1175
|
+
return val()
|
|
1176
|
+
|
|
1177
|
+
|
|
1178
|
+
|
|
1179
|
+
def _fhik(self):
|
|
1180
|
+
"""Calcul la portance locale d'un boulon bois/bois ou d'un tire fond si d>6mm
|
|
1181
|
+
"""
|
|
1182
|
+
|
|
1183
|
+
dict_beam = {"1": {}, "2": {}}
|
|
1184
|
+
|
|
1185
|
+
for i, beam in enumerate([self.beam_1, self.beam_2]):
|
|
1186
|
+
if self._type_beam[i] == "Bois":
|
|
1187
|
+
dict_beam[str(i+1)]["fh0k"] = self._fh0k(beam)
|
|
1188
|
+
dict_beam[str(i+1)]["K90"] = self._K_90(beam)
|
|
1189
|
+
dict_beam[str(i+1)]["fhik"] = self._fhak(dict_beam[str(i+1)]["fh0k"], dict_beam[str(i+1)]["K90"], self.alpha[i])
|
|
1190
|
+
dict_beam[str(i+1)]["fhik"] = (dict_beam[str(i+1)]["fh0k"][0] + dict_beam[str(i+1)]["fhik"][0], dict_beam[str(i+1)]["fhik"][1])
|
|
1191
|
+
|
|
1192
|
+
elif self._type_beam[i] == "CP" or self._type_beam[i] == "PP/OSB":
|
|
1193
|
+
dict_beam[str(i+1)]["fhik"] = self._fhk(beam)
|
|
1194
|
+
|
|
1195
|
+
else:
|
|
1196
|
+
dict_beam[str(i+1)]["fhik"] = 0
|
|
1197
|
+
|
|
1198
|
+
self.fh1k = dict_beam["1"]["fhik"]
|
|
1199
|
+
self.fh2k = dict_beam["2"]["fhik"]
|
|
1200
|
+
return self.fh1k, self.fh2k
|
|
1201
|
+
|
|
1202
|
+
|
|
1203
|
+
@property
|
|
1204
|
+
def MyRk(self):
|
|
1205
|
+
"""Défini le moment d'écoulement plastique d'un boulon en N.mm avec:
|
|
1206
|
+
fuk : la valeur caractéristique de résistance à la traction du boulon en N/mm2
|
|
1207
|
+
d : diamètre efficace du boulon (ou du tire fond si >6mm) en mm"""
|
|
1208
|
+
f_uk = self.fuk.value * 10**-6
|
|
1209
|
+
d = self.d.value * 10**3
|
|
1210
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
1211
|
+
def val():
|
|
1212
|
+
M_y_Rk = 0.3 * f_uk * d ** 2.6 # N.mm
|
|
1213
|
+
return M_y_Rk * si.N*si.mm
|
|
1214
|
+
return val()
|
|
1215
|
+
|
|
1216
|
+
|
|
1217
|
+
@property
|
|
1218
|
+
def pince(self):
|
|
1219
|
+
"""Défini les différentes pinces minimales pour un boulon en mm avec :
|
|
1220
|
+
alpha : angle entre l'effort de l'organe et le fil du bois en °
|
|
1221
|
+
d : diamètre efficace du boulon (ou du tire fond si >6mm) en mm """
|
|
1222
|
+
dict_pince = {}
|
|
1223
|
+
if self.type_organe == "Tirefond":
|
|
1224
|
+
self.d = self.d_vis
|
|
1225
|
+
for i, alpha in enumerate(self.alpha):
|
|
1226
|
+
if not self._type_beam[i] in self.TYPE_BOIS_ASSEMBLAGE:
|
|
1227
|
+
continue
|
|
1228
|
+
a1 = round((4 + mt.cos(mt.radians(alpha))) * self.d, 1)
|
|
1229
|
+
a2 = round(4 * self.d, 1)
|
|
1230
|
+
a3t = round(max(7 * self.d, 80*si.mm),1)
|
|
1231
|
+
|
|
1232
|
+
if alpha <= 30:
|
|
1233
|
+
a3c = round(4 * self.d, 1)
|
|
1234
|
+
else:
|
|
1235
|
+
a3c = round((1 + 6 * mt.sin(mt.radians(alpha))) * self.d, 1)
|
|
1236
|
+
|
|
1237
|
+
a4t = round(max((2 + 2 * mt.sin(mt.radians(alpha))) * self.d, 3 * self.d), 1)
|
|
1238
|
+
a4c = round(3 * self.d, 1)
|
|
1239
|
+
dict_pince["barre "+str(i+1)] = {"a1": a1, "a2":a2, "a3t": a3t, "a3c": a3c, "a4t": a4t, "a4c": a4c}
|
|
1240
|
+
return dict_pince
|
|
1241
|
+
|
|
1242
|
+
|
|
1243
|
+
def nef(self, a1_beam1:int, a1_beam2:int):
|
|
1244
|
+
"""Défini le nombre efficace d'organe (boulon) dans une file avec :
|
|
1245
|
+
a1 : l'espacement entre boulon dans le sens du fil du bois
|
|
1246
|
+
n : nombre de boulons dans une file
|
|
1247
|
+
d : diamètre efficace du boulon (ou du tire fond si >6mm) en mm"""
|
|
1248
|
+
d = self.d
|
|
1249
|
+
if self.type_organe == "Tirefond":
|
|
1250
|
+
d = self.d_vis
|
|
1251
|
+
|
|
1252
|
+
nef_list = []
|
|
1253
|
+
for i, alpha in enumerate(self.alpha):
|
|
1254
|
+
if i:
|
|
1255
|
+
a_1 = a1_beam2 * si.mm
|
|
1256
|
+
n = self.nfile
|
|
1257
|
+
else:
|
|
1258
|
+
a_1 = a1_beam1 * si.mm
|
|
1259
|
+
n = self.n
|
|
1260
|
+
|
|
1261
|
+
if n == 1 or alpha == 90:
|
|
1262
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
1263
|
+
def val():
|
|
1264
|
+
n_ef = n
|
|
1265
|
+
return n_ef
|
|
1266
|
+
nef_list.append(val())
|
|
1267
|
+
else:
|
|
1268
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
1269
|
+
def val():
|
|
1270
|
+
n_ef = min(n**0.9 * (a_1/(13 * d))**(1/4), n)
|
|
1271
|
+
return n_ef
|
|
1272
|
+
nef_list.append(val())
|
|
1273
|
+
|
|
1274
|
+
if alpha > 0 and alpha < 90:
|
|
1275
|
+
n_ef = nef_list[i][1]
|
|
1276
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
1277
|
+
def nef_a():
|
|
1278
|
+
n_ef_a = n_ef + alpha * (n - n_ef)/90
|
|
1279
|
+
return n_ef_a
|
|
1280
|
+
value2 = nef_a()
|
|
1281
|
+
nef_list[i] = (nef_list[i][0] + value2[0] , value2[1])
|
|
1282
|
+
result = self._min_nef(nef_list)
|
|
1283
|
+
self._nef = result[1]
|
|
1284
|
+
return result
|
|
1285
|
+
|
|
1286
|
+
|
|
1287
|
+
# 8.5.2 Boulons chargés axialement
|
|
1288
|
+
def Fax_Rk(self, d_int: float=0, d_ext: float=0, filetage_EN1090: bool=("True", "False")):
|
|
1289
|
+
"""Calcul la résistance axial caractéristique d'un boulon chargé axialement à partir soit de la rondelle soit de la plaque métalique.
|
|
1290
|
+
|
|
1291
|
+
Args:
|
|
1292
|
+
d_int (float, optional): diamètre intérieur de la rondelle en mm ou du trou de perçage dans la plaque métallique. Defaults to 0.
|
|
1293
|
+
d_ext (float, optional): diamètre extérieur de la rondelle en mm. Defaults to 0.
|
|
1294
|
+
filetage_EN1090 (bool, optional): définit si le filetage est conforme à l'EN 1090, soit matricé. Si filetage usiné alors False. Defaults to True.
|
|
1295
|
+
|
|
1296
|
+
Returns:
|
|
1297
|
+
FaxRk: la résistance axial d'un boulon en N
|
|
1298
|
+
"""
|
|
1299
|
+
from ourocode.eurocode.EC3_Assemblage import Tige
|
|
1300
|
+
d_int = d_int * si.mm
|
|
1301
|
+
d_ext = d_ext * si.mm
|
|
1302
|
+
|
|
1303
|
+
if self._type_beam[0] == "Métal":
|
|
1304
|
+
FtRd = Tige(self.d.value*10**3, d_int, self.qualite, True, filetage_EN1090, t=self.beam_1.t.value*10**3, h=self.beam_1.h.value*10**3, classe_acier=self.beam_1.classe_acier, classe_transv=self.beam_1.classe_transv).FtRd
|
|
1305
|
+
d_ext = min(self.beam_1.t*12, 4*self.d)
|
|
1306
|
+
fc_90_k = float(self.beam_2.caract_meca.loc["fc90k"]) * si.MPa
|
|
1307
|
+
else:
|
|
1308
|
+
FtRd = Tige(self.d.value*10**3, d_int, self.qualite, True, filetage_EN1090, t=0, h=0, classe_acier="S235", classe_transv=3).FtRd
|
|
1309
|
+
fc_90_k = float(self.beam_1.caract_meca.loc["fc90k"]) * si.MPa
|
|
1310
|
+
|
|
1311
|
+
Ft_Rd = FtRd[1]
|
|
1312
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
1313
|
+
def val():
|
|
1314
|
+
A_int = pi * (d_int / 2)**2
|
|
1315
|
+
A_rondelle = pi * (d_ext / 2)**2 - A_int
|
|
1316
|
+
|
|
1317
|
+
f_c90_k_rond = fc_90_k * 3
|
|
1318
|
+
F_c90_d = f_c90_k_rond * A_rondelle
|
|
1319
|
+
F_ax_Rk = min(F_c90_d, Ft_Rd)
|
|
1320
|
+
return F_ax_Rk
|
|
1321
|
+
FaxRk = val()
|
|
1322
|
+
self.FaxRk = FaxRk[1]
|
|
1323
|
+
return (FtRd[0] + FaxRk[0], FaxRk[1])
|
|
1324
|
+
|
|
1325
|
+
|
|
1326
|
+
# ======================================================= BROCHE =========================================================
|
|
1327
|
+
# 8.6 Assemblage par broche
|
|
1328
|
+
|
|
1329
|
+
class Broche(Boulon):
|
|
1330
|
+
""" Créer une classe Broche.
|
|
1331
|
+
d : diamètre efficace de la broche ( entre 6 et 30 mm) en mm
|
|
1332
|
+
qualite : qualite de la broche
|
|
1333
|
+
n : nombre de broche dans une file
|
|
1334
|
+
alpha : angle entre l'effort de l'organe et le fil du bois en °
|
|
1335
|
+
|
|
1336
|
+
t1 (int, optional): longueur de contacte avec la tige pour la pièce 1 en mm.
|
|
1337
|
+
ATTENTION : Cet argument n'est pas obligatoire par défaut, il est calculer par le type de tige utilisée.
|
|
1338
|
+
Il n'est nécessaire de le remplir que si vous avez un t1 spécifique, par exemple avec une chapelle réduisant ainsi la portance local à une longueur inférieur à celle de l'épaisseur de la pièce 1.
|
|
1339
|
+
|
|
1340
|
+
t2 (int, optional): longueur de contacte avec la tige pour la pièce 2 en mm.
|
|
1341
|
+
ATTENTION : Même chose que pour t1 mais pour la pièce 2.
|
|
1342
|
+
"""
|
|
1343
|
+
|
|
1344
|
+
def __init__(self, d:float, qualite: str=Boulon.QUALITE_ACIER, n: int=1, alpha1: float=0, alpha2: float=0, t1: int=0, t2: int=0, **kwargs):
|
|
1345
|
+
super().__init__(d, qualite, n, alpha1, alpha2, **kwargs)
|
|
1346
|
+
self.type_organe = "Broche"
|
|
1347
|
+
|
|
1348
|
+
@property
|
|
1349
|
+
def Fax_Rk(self):
|
|
1350
|
+
self.FaxRk = 0
|
|
1351
|
+
return 0
|
|
1352
|
+
|
|
1353
|
+
@property
|
|
1354
|
+
def pince(self):
|
|
1355
|
+
"""Défini les différentes pinces minimales pour une broche en mm avec :
|
|
1356
|
+
alpha : angle entre l'effort de l'organe et le fil du bois en °
|
|
1357
|
+
d : diamètre efficace du boulon (ou du tire fond si >6mm) en mm """
|
|
1358
|
+
dict_pince = {}
|
|
1359
|
+
for i, alpha in enumerate(self.alpha):
|
|
1360
|
+
a1 = round((3 + 2 * (mt.cos(mt.radians(alpha)))) * self.d, 1)
|
|
1361
|
+
a2 = round(3 * self.d, 1)
|
|
1362
|
+
a3t = round(max(7 * self.d, 80*si.mm), 1)
|
|
1363
|
+
|
|
1364
|
+
if alpha <= 150 and alpha < 210:
|
|
1365
|
+
|
|
1366
|
+
a3c = round(max(3.5 * self.d, 40*si.mm), 1)
|
|
1367
|
+
|
|
1368
|
+
else:
|
|
1369
|
+
|
|
1370
|
+
a3c = round((a3t * mt.sin(mt.radians(alpha))), 1)
|
|
1371
|
+
|
|
1372
|
+
a4t = round(max((2 + 2 * mt.sin(mt.radians(alpha))) * self.d, 3 * self.d), 1)
|
|
1373
|
+
a4c = round(3 * self.d, 1)
|
|
1374
|
+
dict_pince["barre "+str(i+1)] = {"a1": a1, "a2":a2, "a3t": a3t, "a3c": a3c, "a4t": a4t, "a4c": a4c}
|
|
1375
|
+
return dict_pince
|
|
1376
|
+
|
|
1377
|
+
|
|
1378
|
+
# ======================================================= TIREFOND =========================================================
|
|
1379
|
+
|
|
1380
|
+
|
|
1381
|
+
class _Tirefond(object):
|
|
1382
|
+
def __init__(self, d:si.mm, d1:si.mm, ds:si.mm, dh:si.mm, l:si.mm, n, rho_a:float, fhead:float, ftensk:float, MyRk:float=0, alpha1: float=0, alpha2: float=0, percage: bool=("False", "True"), **kwargs):
|
|
1383
|
+
"""Défini un object tirefond
|
|
1384
|
+
|
|
1385
|
+
Args:
|
|
1386
|
+
d (si.mm): diamètre extérieur du filet en mm
|
|
1387
|
+
d1 (float): diamètre du noyaux en mm
|
|
1388
|
+
ds (float): diamètre de la tête en mm
|
|
1389
|
+
dh (float): diamètre de la tête en mm
|
|
1390
|
+
l (float): longueur total de la vis en mm
|
|
1391
|
+
n (int): le nombre de vis dans une file
|
|
1392
|
+
rho_a (float): masse volumique associée au tirefond en fax,k en kg/m3
|
|
1393
|
+
fhead (float): valeur caractéristique de traversée de la tête du tirefond à l'EN 14592 en Mpa
|
|
1394
|
+
ftensk (float): valeur caractéristique en traction du tirefond en N
|
|
1395
|
+
|
|
1396
|
+
MyRk (float, optional): le moment d'écoulement plastique de la vis en N.mm.
|
|
1397
|
+
Si cette attribut est remplie, alors on récupère la valeur founis sinon on le calcul à l'EC5.
|
|
1398
|
+
Defaults to 0.
|
|
1399
|
+
|
|
1400
|
+
alpha1 (float, optional): angle entre l'effort de l'organe et le fil du bois 1 en °. Defaults to 0.
|
|
1401
|
+
alpha2 (float, optional): angle entre l'effort de l'organe et le fil du bois 2 en °. Defaults to 0.
|
|
1402
|
+
percage (bool, optional): l'élément est-il préperçé ? Si oui alors True. Defaults to ("False", "True").
|
|
1403
|
+
"""
|
|
1404
|
+
self.d_vis = d * si.mm
|
|
1405
|
+
self.d1 = d1 * si.mm
|
|
1406
|
+
self.ds = ds * si.mm
|
|
1407
|
+
self.dh = dh * si.mm
|
|
1408
|
+
# self.d_ef = min(d1*1.1, ds) A valider !!!!!
|
|
1409
|
+
self.d_ef = d1*1.1
|
|
1410
|
+
self.l = l * si.mm #longueur sous tête
|
|
1411
|
+
self.n = n
|
|
1412
|
+
self.percage = percage
|
|
1413
|
+
self.alpha = [alpha1, alpha2]
|
|
1414
|
+
self.type_organe = "Tirefond"
|
|
1415
|
+
self.rho_a = rho_a * si.kg/si.m**3
|
|
1416
|
+
self.fhead = fhead * si.MPa
|
|
1417
|
+
self.ftensk = ftensk * si.N
|
|
1418
|
+
|
|
1419
|
+
|
|
1420
|
+
# 8.7.2 Tirefond chargés axialement
|
|
1421
|
+
def pince_tirefond_axial(self, t: int):
|
|
1422
|
+
"""
|
|
1423
|
+
Défini les pinces d'un tirefond en mm lorsqu'il est chargée axialement et l'epaisseur de bois supérieur à 12*d.
|
|
1424
|
+
Args:
|
|
1425
|
+
t(int) : epaisseur de bois en mm
|
|
1426
|
+
"""
|
|
1427
|
+
if t >= 12 * self.d_vis:
|
|
1428
|
+
|
|
1429
|
+
a1 = 7 * self.d_vis
|
|
1430
|
+
a2 = 5 * self.d_vis
|
|
1431
|
+
a1CG = 10 * self.d_vis
|
|
1432
|
+
a2CG = 4 * self.d_vis
|
|
1433
|
+
else:
|
|
1434
|
+
print("L'épaisseur de bois n'est pas suffisante, il faut un bois de {0} mm minimum !".format(
|
|
1435
|
+
12*self.d_vis))
|
|
1436
|
+
return {"a1": a1, "a2": a2, "a1CG": a1CG, "a2CG": a2CG}
|
|
1437
|
+
|
|
1438
|
+
|
|
1439
|
+
@property
|
|
1440
|
+
def nefTraction(self):
|
|
1441
|
+
"""Renvoie le nombre efficace de tirefond quand ils sont solicités par une composante parallèle à la partie lisse."""
|
|
1442
|
+
n = self.n * self.nfile
|
|
1443
|
+
if n > 1:
|
|
1444
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
1445
|
+
def val():
|
|
1446
|
+
n_ef_traction = n**0.9
|
|
1447
|
+
return n_ef_traction
|
|
1448
|
+
else:
|
|
1449
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
1450
|
+
def val():
|
|
1451
|
+
n_ef_traction = 1
|
|
1452
|
+
return n_ef_traction
|
|
1453
|
+
return val()
|
|
1454
|
+
|
|
1455
|
+
|
|
1456
|
+
def faxk(self, l_ef:int, beam:str=["1", "2"]):
|
|
1457
|
+
"""
|
|
1458
|
+
Calcul la valeur caractéristique de la résistance à l'arrachement perpendiculaire au fil en N/mm2 si 6mm<=d<=12mm
|
|
1459
|
+
et 0.6<=d1/d<=0.75.
|
|
1460
|
+
|
|
1461
|
+
Args:
|
|
1462
|
+
l_ef (int): longueur de pénétration de la partie filetée en mm
|
|
1463
|
+
beam (str): élément à calculer 1 ou 2
|
|
1464
|
+
"""
|
|
1465
|
+
d = self.d_vis.value*10**3
|
|
1466
|
+
d1 = self.d1.value*10**3
|
|
1467
|
+
if beam == "1":
|
|
1468
|
+
rho_k = self.beam_1.rho_k
|
|
1469
|
+
else:
|
|
1470
|
+
rho_k = self.beam_2.rho_k
|
|
1471
|
+
|
|
1472
|
+
if 6 <= d <= 12 and 0.6 <= d1 / d <= 0.75:
|
|
1473
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
1474
|
+
def val():
|
|
1475
|
+
f_axk = 0.52 * (d ** -0.5) * (l_ef ** -0.1) * (rho_k ** 0.8)
|
|
1476
|
+
return f_axk
|
|
1477
|
+
return val()
|
|
1478
|
+
|
|
1479
|
+
else:
|
|
1480
|
+
print(
|
|
1481
|
+
"le diamètre ne répond pas aux spécifications demandées en 8.7.2(4) de l'EN 1995 partie assemblage")
|
|
1482
|
+
|
|
1483
|
+
|
|
1484
|
+
def _FaxaRk(self, faxk:float, l_ef:int, alpha:int, beam:str=["1", "2"]):
|
|
1485
|
+
"""
|
|
1486
|
+
Calcul la valeur caractéristique de la résistance à l'arrachement du tirefond à un angle alpha par rapport au fil en N.
|
|
1487
|
+
|
|
1488
|
+
Args:
|
|
1489
|
+
faxk (float): Valeur caractéristique de résistance à l'arrachement perpendiculaire au fil en N/mm2
|
|
1490
|
+
l_ef (int): longueur de pénétration de la partie filetée en mm
|
|
1491
|
+
alpha (int): angle formé entre l'axe du tirefond et le fil du bois, doit être supérieur à 30°
|
|
1492
|
+
beam (str): élement à calculer 1 ou 2
|
|
1493
|
+
"""
|
|
1494
|
+
d = self.d_vis.value*10**3
|
|
1495
|
+
d_1 = self.d1
|
|
1496
|
+
rho_a = self.rho_a.value
|
|
1497
|
+
if beam == "1":
|
|
1498
|
+
rho_k = self.beam_1.rho_k
|
|
1499
|
+
else:
|
|
1500
|
+
rho_k = self.beam_2.rho_k
|
|
1501
|
+
|
|
1502
|
+
if 6 <= d <= 12 and 0.6 <= (d_1 / d) <= 0.75:
|
|
1503
|
+
@handcalc(override="long", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
1504
|
+
def val():
|
|
1505
|
+
kd = min((d / 8), 1)
|
|
1506
|
+
F_ax_a_Rk = (faxk * d * l_ef * kd) / (1.2 * cos(radians(alpha)) ** 2 + sin(radians(alpha)) ** 2)
|
|
1507
|
+
return F_ax_a_Rk
|
|
1508
|
+
else:
|
|
1509
|
+
@handcalc(override="long", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
1510
|
+
def val():
|
|
1511
|
+
F_ax_a_Rk = ((faxk * d * l_ef) / (1.2 * (cos(radians(alpha))) ** 2 + (sin(radians(alpha))) ** 2)) * ((rho_k / rho_a) ** 0.8) #N
|
|
1512
|
+
return F_ax_a_Rk
|
|
1513
|
+
return val()
|
|
1514
|
+
|
|
1515
|
+
def _FaxaRkHead(self):
|
|
1516
|
+
"""
|
|
1517
|
+
Calcul la valeur caractéristique de résistance à la traversée de la tête du tirefond dans l'assemblage en N.
|
|
1518
|
+
"""
|
|
1519
|
+
f_head = self.fhead.value*10**-6
|
|
1520
|
+
d_h = self.dh.value*10**3
|
|
1521
|
+
rho_a = self.rho_a.value
|
|
1522
|
+
rho_k = self.beam_1.rho_k
|
|
1523
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
1524
|
+
def val():
|
|
1525
|
+
F_axRkhead = f_head * d_h**2 * ((rho_k/rho_a)**0.8) #N
|
|
1526
|
+
return F_axRkhead
|
|
1527
|
+
return val()
|
|
1528
|
+
|
|
1529
|
+
|
|
1530
|
+
def Fax_Rk(self, faxk:float, l_ef:int, alpha:int, beam:str=["1", "2"]):
|
|
1531
|
+
"""Calcul la valeur caractéristique de résistance du tirefond axialement entre la résistance caractéristique de la tête et du pas de vis dans le bois en N.
|
|
1532
|
+
Cette fonction détermine ensuite la valeur de résistance caractéristique de l'assemblage en prenant compte du nombre efficace de tirefond en traction.
|
|
1533
|
+
|
|
1534
|
+
Args:
|
|
1535
|
+
faxk (float): Valeur caractéristique de résistance à l'arrachement perpendiculaire au fil en N/mm2
|
|
1536
|
+
l_ef (int): longueur de pénétration de la partie filetée en mm
|
|
1537
|
+
alpha (int): angle formé entre l'axe du tirefond et le fil du bois, doit être supérieur à 30°
|
|
1538
|
+
beam (str, optional): élément à calculer 1 ou 2
|
|
1539
|
+
"""
|
|
1540
|
+
F_ax_a_Rk_value = self._FaxaRk(faxk, l_ef, alpha, beam)
|
|
1541
|
+
F_ax_a_Rk = F_ax_a_Rk_value[1]
|
|
1542
|
+
F_ax_a_Rk_head_value = self._FaxaRkHead()
|
|
1543
|
+
F_ax_a_Rk_head = F_ax_a_Rk_head_value[1]
|
|
1544
|
+
|
|
1545
|
+
@handcalc(override="long", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
1546
|
+
def val():
|
|
1547
|
+
F_ax_Rk = min(F_ax_a_Rk, F_ax_a_Rk_head) #N
|
|
1548
|
+
return F_ax_Rk
|
|
1549
|
+
FaxRk = val()
|
|
1550
|
+
self.FaxRk = FaxRk[1]
|
|
1551
|
+
|
|
1552
|
+
f_ax_Rk = FaxRk[1]
|
|
1553
|
+
n_ef_traction = self.nefTraction[1]
|
|
1554
|
+
|
|
1555
|
+
@handcalc(override="long", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
1556
|
+
def val_ass():
|
|
1557
|
+
F_ax_Rk_ass = f_ax_Rk * n_ef_traction # N
|
|
1558
|
+
return F_ax_Rk_ass
|
|
1559
|
+
F_ax_Rk_ass = val_ass()
|
|
1560
|
+
|
|
1561
|
+
return (F_ax_a_Rk_value[0] + F_ax_a_Rk_head_value[0] + FaxRk[0] + F_ax_Rk_ass[0], F_ax_Rk_ass[1])
|
|
1562
|
+
|
|
1563
|
+
|
|
1564
|
+
def FtRk(self):
|
|
1565
|
+
""" Calcul la résistance caractéristique en traction pur du fil des tirefonds dans l'assemblage en N."""
|
|
1566
|
+
n_ef_traction = self.nefTraction[1]
|
|
1567
|
+
f_tens_k = self.ftensk
|
|
1568
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
1569
|
+
def val():
|
|
1570
|
+
f_tRk = n_ef_traction * f_tens_k
|
|
1571
|
+
return f_tRk
|
|
1572
|
+
return val()
|
|
1573
|
+
|
|
1574
|
+
|
|
1575
|
+
class Tirefond_inf_7(_Tirefond, Pointe):
|
|
1576
|
+
def __init__(self, d:si.mm, d1:float, ds:float, dh:float, l:float, n:int, rho_a:float, fhead:float, ftensk:float, MyRk:float=0, alpha1: float=0, alpha2: float=0, percage: bool=("False", "True"), **kwargs):
|
|
1577
|
+
"""Défini un object tirefond qui a un diamètre efficace inférieur à 6mm
|
|
1578
|
+
|
|
1579
|
+
Args:
|
|
1580
|
+
d (si.mm): diamètre extérieur du filet en mm
|
|
1581
|
+
d1 (float): diamètre du noyaux en mm
|
|
1582
|
+
ds (float): diamètre de la tête en mm
|
|
1583
|
+
dh (float): diamètre de la tête en mm
|
|
1584
|
+
l (float): longueur total de la vis en mm
|
|
1585
|
+
n (int): le nombre de vis dans une file
|
|
1586
|
+
rho_a (float): masse volumique associée au tirefond en fax,k en kg/m3
|
|
1587
|
+
fhead (float): valeur caractéristique de traversée de la tête du tirefond à l'EN 14592 en Mpa
|
|
1588
|
+
ftensk (float): valeur caractéristique en traction du tirefond en N
|
|
1589
|
+
|
|
1590
|
+
MyRk (float, optional): le moment d'écoulement plastique de la vis en N.mm.
|
|
1591
|
+
Si cette attribut est remplie, alors on récupère la valeur founis sinon on le calcul à l'EC5.
|
|
1592
|
+
Defaults to 0.
|
|
1593
|
+
|
|
1594
|
+
alpha1 (float, optional): angle entre l'effort de l'organe et le fil du bois 1 en °. Defaults to 0.
|
|
1595
|
+
alpha2 (float, optional): angle entre l'effort de l'organe et le fil du bois 2 en °. Defaults to 0.
|
|
1596
|
+
percage (bool, optional): l'élément est-il préperçé ? Si oui alors True. Defaults to ("False", "True").
|
|
1597
|
+
"""
|
|
1598
|
+
qualite = "6.8"
|
|
1599
|
+
self.d_vis = d * si.mm
|
|
1600
|
+
if "qualite" in kwargs.keys():
|
|
1601
|
+
qualite = kwargs.pop("qualite")
|
|
1602
|
+
|
|
1603
|
+
if d1*1.1 <= 6:
|
|
1604
|
+
Pointe.__init__(self, d=d1*1.1, d_tete=dh, l=l, qualite=qualite, n=n, alpha1=alpha1, alpha2=alpha2, type_organe="Tirefond", percage=percage, **kwargs)
|
|
1605
|
+
_Tirefond.__init__(self, d, d1, ds, dh, l, n, rho_a, fhead, ftensk, MyRk, alpha1, alpha2, percage)
|
|
1606
|
+
else:
|
|
1607
|
+
raise "Erreur, le tirefond est considéré comme un boulon et non une pointe"
|
|
1608
|
+
|
|
1609
|
+
if MyRk:
|
|
1610
|
+
self._MyRk_fourni = MyRk * si.N*si.mm
|
|
1611
|
+
|
|
1612
|
+
@property
|
|
1613
|
+
def MyRk(self):
|
|
1614
|
+
if hasattr(self, "_MyRk_fourni"):
|
|
1615
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
1616
|
+
def val():
|
|
1617
|
+
MyRk = self._MyRk_fourni
|
|
1618
|
+
return MyRk
|
|
1619
|
+
return val()
|
|
1620
|
+
else:
|
|
1621
|
+
return super().MyRk
|
|
1622
|
+
|
|
1623
|
+
|
|
1624
|
+
class Tirefond_sup_6(_Tirefond, Boulon):
|
|
1625
|
+
""" Défini un object tirefond avec :
|
|
1626
|
+
d : diamètre extérieur du filet en mm
|
|
1627
|
+
d1 : diamètre du noyaux en mm
|
|
1628
|
+
dh : diamètre de la tête en mm
|
|
1629
|
+
rho_a : masse volumique associée au tirefond en fax,k en kg/m3
|
|
1630
|
+
fhead : valeur caractéristique de traversée de la tête du tirefond à l'EN14592 en Mpa
|
|
1631
|
+
ftensk : valeur caractéristique en traction du tirefond en N
|
|
1632
|
+
n : nombre de boulons dans une file
|
|
1633
|
+
alpha1 : angle entre l'effort de l'organe et le fil du bois 1 en °
|
|
1634
|
+
alpha2 : angle entre l'effort de l'organe et le fil du bois 2 en °"""
|
|
1635
|
+
|
|
1636
|
+
def __init__(self, d:si.mm, d1:float, ds:float, dh:float, l:si.mm, n, rho_a:float, fhead:float, ftensk:float, MyRk:float=0, alpha1: float=0, alpha2: float=0, **kwargs):
|
|
1637
|
+
"""Défini un object tirefond qui a un diamètre efficace supérieur à 6mm
|
|
1638
|
+
|
|
1639
|
+
Args:
|
|
1640
|
+
d (si.mm): diamètre extérieur du filet en mm
|
|
1641
|
+
d1 (float): diamètre du noyaux en mm
|
|
1642
|
+
ds (float): diamètre de la tête en mm
|
|
1643
|
+
dh (float): diamètre de la tête en mm
|
|
1644
|
+
l (float): longueur total de la vis en mm
|
|
1645
|
+
n (int): le nombre de vis dans une file
|
|
1646
|
+
rho_a (float): masse volumique associée au tirefond en fax,k en kg/m3
|
|
1647
|
+
fhead (float): valeur caractéristique de traversée de la tête du tirefond à l'EN 14592 en Mpa
|
|
1648
|
+
ftensk (float): valeur caractéristique en traction du tirefond en N
|
|
1649
|
+
|
|
1650
|
+
MyRk (float, optional): le moment d'écoulement plastique de la vis en N.mm.
|
|
1651
|
+
Si cette attribut est remplie, alors on récupère la valeur founis sinon on le calcul à l'EC5.
|
|
1652
|
+
Defaults to 0.
|
|
1653
|
+
|
|
1654
|
+
alpha1 (float, optional): angle entre l'effort de l'organe et le fil du bois 1 en °. Defaults to 0.
|
|
1655
|
+
alpha2 (float, optional): angle entre l'effort de l'organe et le fil du bois 2 en °. Defaults to 0.
|
|
1656
|
+
"""
|
|
1657
|
+
qualite = "6.8"
|
|
1658
|
+
self.d_vis = d * si.mm
|
|
1659
|
+
self.l = l * si.mm
|
|
1660
|
+
if "qualite" in kwargs.keys():
|
|
1661
|
+
qualite = kwargs.pop("qualite")
|
|
1662
|
+
|
|
1663
|
+
if d1*1.1 > 6:
|
|
1664
|
+
Boulon.__init__(self, d=d1*1.1, qualite=qualite, n=n, alpha1=alpha1, alpha2=alpha2, type_organe="Tirefond", **kwargs)
|
|
1665
|
+
_Tirefond.__init__(self, d, d1, ds, dh, l, n, rho_a, fhead, ftensk, MyRk, alpha1, alpha2)
|
|
1666
|
+
|
|
1667
|
+
else:
|
|
1668
|
+
print("Erreur, le tirefond est considéré comme une pointe et non un boulon")
|
|
1669
|
+
|
|
1670
|
+
if MyRk:
|
|
1671
|
+
self._MyRk_fourni = MyRk * si.N*si.mm
|
|
1672
|
+
|
|
1673
|
+
@property
|
|
1674
|
+
def MyRk(self):
|
|
1675
|
+
if hasattr(self, "_MyRk_fourni"):
|
|
1676
|
+
@handcalc(override="short", precision=2, jupyter_display=self.JUPYTER_DISPLAY, left="\\[", right="\\]")
|
|
1677
|
+
def val():
|
|
1678
|
+
MyRk = self._MyRk_fourni
|
|
1679
|
+
return MyRk
|
|
1680
|
+
return val()
|
|
1681
|
+
else:
|
|
1682
|
+
return super().MyRk
|
|
1683
|
+
# ======================================================= ANNEAU =========================================================
|
|
1684
|
+
# 8.9 Assemblage par anneaux
|
|
1685
|
+
|
|
1686
|
+
|
|
1687
|
+
# class Annneau(object):
|
|
1688
|
+
# """Défini un objet anneau avec :"""
|
|
1689
|
+
|
|
1690
|
+
# def __init__(self, dc: float, t1:float, t2:float, hc:float, typeA="bois"):
|
|
1691
|
+
# self.type_organe = "Anneau"
|
|
1692
|
+
# self.dc = dc
|
|
1693
|
+
# self.t1 = t1
|
|
1694
|
+
# self.t2 = t2
|
|
1695
|
+
# self.he = hc/2
|
|
1696
|
+
# self.typeA = typeA
|
|
1697
|
+
|
|
1698
|
+
# def ki(self, nAss:int, a3t:float, rhok:int):
|
|
1699
|
+
# """ Donne les facteur ki (de 1 à 4) dans un dico avec:
|
|
1700
|
+
# nAss : nombre d'assemblage par plan de cisaillement
|
|
1701
|
+
# a3t = distance d'extrémité chargé (en traction) """
|
|
1702
|
+
# listk = [0.0]*4
|
|
1703
|
+
|
|
1704
|
+
# if nAss > 1:
|
|
1705
|
+
# ka = 1
|
|
1706
|
+
# else:
|
|
1707
|
+
# ka = 1.25
|
|
1708
|
+
|
|
1709
|
+
# listk[0] = min(1,
|
|
1710
|
+
# self.t1 / (3 * self.he),
|
|
1711
|
+
# self.t2 / (5 * self.he))
|
|
1712
|
+
|
|
1713
|
+
# listk[1] = min(ka,
|
|
1714
|
+
# a3t / (2 * self.dc))
|
|
1715
|
+
|
|
1716
|
+
# listk[2] = min(1.75,
|
|
1717
|
+
# rhok / 350)
|
|
1718
|
+
|
|
1719
|
+
# if self.typeA == "bois":
|
|
1720
|
+
# k4 = 1
|
|
1721
|
+
# else:
|
|
1722
|
+
# k4 = 1.25
|
|
1723
|
+
# listk[3] = k4
|
|
1724
|
+
# dico = {}
|
|
1725
|
+
# for i in range(1, 5):
|
|
1726
|
+
# cle = "k" + str(i)
|
|
1727
|
+
# dico[cle] = listk[i-1]
|
|
1728
|
+
|
|
1729
|
+
# return dico
|
|
1730
|
+
|
|
1731
|
+
# def Fv0Rk(self, dicoKi:dict):
|
|
1732
|
+
# """ Retourne la résistance en cidaillement de l'anneau en N avec:
|
|
1733
|
+
# dicoKi = dictionnaire des facteurs ki (def ki)"""
|
|
1734
|
+
# fv0rk = min(dicoKi["k1"] * dicoKi["k2"] * dicoKi["k3"] * dicoKi["k4"] * (35 * self.dc**1.5),
|
|
1735
|
+
# dicoKi["k1"] * dicoKi["k3"] * self.he * (31.5 * self.dc))
|
|
1736
|
+
# return fv0rk
|
|
1737
|
+
|
|
1738
|
+
|
|
1739
|
+
# def FvaRk(self):
|
|
1740
|
+
# pass
|
|
1741
|
+
|
|
1742
|
+
|
|
1743
|
+
if __name__ == "__main__":
|
|
1744
|
+
from EC5_Element_droit import Barre
|
|
1745
|
+
from EC3_Element_droit import Element
|
|
1746
|
+
|
|
1747
|
+
beam1 = Barre(60, 140, "Rectangulaire", classe="C24", cs=2)
|
|
1748
|
+
beam1._f_type_d("fm0k", "Instantanee", "Fondamentales")
|
|
1749
|
+
|
|
1750
|
+
beam2 = Barre(160, 160, "Rectangulaire", classe="GL24h", cs=2)
|
|
1751
|
+
beam1._f_type_d("fm0k", "Instantanee", "Fondamentales")
|
|
1752
|
+
|
|
1753
|
+
ass = Assemblage(beam1, beam2, nfile=1, nCis=2)
|
|
1754
|
+
bl = Boulon._from_parent_class(ass, d=12, qualite="4.6", n=2, alpha=0)
|
|
1755
|
+
bl.FaxRk(14,30,True,"Court terme", "Fondamentales")
|
|
1756
|
+
print(bl.FvRk(True))
|
|
1757
|
+
|
|
1758
|
+
# pointe = Pointe._from_parent_class(ass, d=6, d_tete=12, l=120, qualite="10.9", n=1, alpha=0, type_organe="Autres pointes", percage="False")
|
|
1759
|
+
# print(pointe.pince_ass)
|
|
1760
|
+
|