Bonjour à tous,
Je suis étudiant en construction bois (charpentes, ossature bois, lamellé-collé ...).
Je me suis mis à la programmation (très) amateur pour vérifier et dimensionner aux Eurocodes les éléments d'une structure en bois au début avec les tableur puis avec Python.
Bref explications des Eurocodes :
Les Eurocodes (EC) sont les normes européennes de calculs dans le domaine du Génie Civil.
Il y a 10 familles ; EC0 et EC1 traitent de la base (charges de neiges, de vent...), EC2 à 7 et 9 traitent des différents matériaux utilisés, EC8 traitent des séismes.
Elles vont devenir obligatoires dans tout les pays Européens d'ici quelques années.
Pour le bois on travaille avec les EC5.
Logiciels existants propriétaires :
Il existes pour l'instant 3 logiciels propriétaire et pro-MS Windows qui permettent de calculer une structure.
MD-BAT de la société MD-BAT. Simple et plus ou moins efficaces.
Autodesk Robot Structural Analysis Professional de la société Autodesk. Une véritable usine à gaz !
ACORD de la société itech-soft. Pas encore testé.
Bien sur les licences coutent très cher.
Logiciels existants libre :
pyBar un logiciel libre de rdm pour le calcul de structures planes de type poutres, basé sur la méthode des déplacements.
structurix est un programme gratuit de calcul basé sur le principe des éléments finis.
Code_Aster
SALOME MECA
CAELinux est une distribution basée sur Ubuntu 8.04 intégrant toute sorte de logiciel de calcul.
Idée initiale :
Après discussion avec les personnes intéressées on pourrait s'orienter vers un logiciel de RDM Multi Matériaux.
C'est pourquoi, j'aimerais créer un logiciel libre et gratuit pour vérifier une structure en bois.
Bien sur je ne pourrais pas faire quelque chose d'aussi poussé que ce qu'y existent déjà.
Mais je vise les petits artisans et les PME principalement afin de promouvoir les maisons à ossature bois car ce domaine souffre de l'incompétence de certains ce qui donne une mauvaise image de la filière.
En effet comme on présente ça comme quelque chose de facile il y a des opportunistes qui font n'importe quoi.
Le but :
Mon but final serait des coupler tout ça avec le logiciel
pyBar.
Il y aurait une première partie pour définir les charges, une deuxième partie pour modéliser la structure avec pyBar en reprenant les charges de la première partie, et enfin une troisième partie pour vérifier et éditer une note de calcul.
Voilà où j'en suis :
Autant dire tout de suite...pas loin !
Le premier programme que j'ai créé est une petite interface en Python et tkinter pour vérifier dans un premier temps une barre en traction. Il se base sur une "base de données" en xml.
materiau.xml
<?xml version="1.0" ?>
<element_racine>
<profil id="C14" mat="BM" essence="resineux" fmk="14" ftok="8" ft90k="0.4" fc0k="16" fc90k="2" fvk="1.7" E0m="7" E0k="4.7" E90m="0.23" Gm="0.44" Gk="0.29" pk="290" pm="350" gM="1.3"/>
<profil id="C16" mat="BM" essence="resineux" fmk="16" ftok="10" ft90k="0.5" fc0k="17" fc90k="2.2" fvk="1.8" E0m="8" E0k="5.4" E90m="0.27" Gm="0.5" Gk="0.34" pk="310" pm="370" gM="1.3"/>
<profil id="C18" mat="BM" essence="resineux" fmk="18" ftok="11" ft90k="0.5" fc0k="18" fc90k="2.2" fvk="2" E0m="9" E0k="6" E90m="0.3" Gm="0.56" Gk="0.38" pk="320" pm="380" gM="1.3"/>
<profil id="C20" mat="BM" essence="resineux" fmk="20" ftok="12" ft90k="0.5" fc0k="19" fc90k="2.3" fvk="2.2" E0m="9.5" E0k="6.4" E90m="0.32" Gm="0.59" Gk="0.4" pk="330" pm="390" gM="1.3"/>
<profil id="C22" mat="BM" essence="resineux" fmk="22" ftok="13" ft90k="0.5" fc0k="20" fc90k="2.4" fvk="2.4" E0m="10" E0k="6.7" E90m="0.33" Gm="0.63" Gk="0.42" pk="340" pm="410" gM="1.3"/>
<profil id="C24" mat="BM" essence="resineux" fmk="24" ftok="14" ft90k="0.5" fc0k="21" fc90k="2.5" fvk="2.5" E0m="11" E0k="7.4" E90m="0.37" Gm="0.69" Gk="0.46" pk="350" pm="420" gM="1.3"/>
<profil id="C27" mat="BM" essence="resineux" fmk="27" ftok="16" ft90k="0.6" fc0k="22" fc90k="2.6" fvk="2.8" E0m="11.5" E0k="7.7" E90m="0.38" Gm="0.72" Gk="0.48" pk="370" pm="450" gM="1.3"/>
<profil id="C30" mat="BM" essence="resineux" fmk="30" ftok="18" ft90k="0.6" fc0k="23" fc90k="2.7" fvk="3" E0m="12" E0k="8" E90m="0.4" Gm="0.75" Gk="0.5" pk="380" pm="460" gM="1.3"/>
<profil id="C35" mat="BM" essence="resineux" fmk="35" ftok="21" ft90k="0.6" fc0k="25" fc90k="2.8" fvk="3.4" E0m="13" E0k="8.7" E90m="0.43" Gm="0.81" Gk="0.54" pk="400" pm="480" gM="1.3"/>
<profil id="C40" mat="BM" essence="resineux" fmk="40" ftok="24" ft90k="0.6" fc0k="26" fc90k="2.9" fvk="3.8" E0m="14" E0k="9.4" E90m="0.47" Gm="0.88" Gk="0.59" pk="420" pm="500" gM="1.3"/>
<profil id="C45" mat="BM" essence="resineux" fmk="45" ftok="27" ft90k="0.6" fc0k="27" fc90k="3.1" fvk="3.8" E0m="15" E0k="10" E90m="0.5" Gm="0.94" Gk="0.63" pk="440" pm="520" gM="1.3"/>
<profil id="C50" mat="BM" essence="resineux" fmk="50" ftok="30" ft90k="0.6" fc0k="29" fc90k="3.2" fvk="3.8" E0m="16" E0k="10.7" E90m="0.53" Gm="1" Gk="0.67" pk="460" pm="550" gM="1.3"/>
<profil id="D30" mat="BM" essence="feuillu" fmk="30" ftok="18" ft90k="0.6" fc0k="23" fc90k="8" fvk="3" E0m="10" E0k="8" E90m="0.64" Gm="0.6" Gk="0.5" pk="530" pm="640" gM="1.3"/>
<profil id="D35" mat="BM" essence="feuillu" fmk="35" ftok="21" ft90k="0.6" fc0k="25" fc90k="8.4" fvk="3.4" E0m="10" E0k="8.7" E90m="0.69" Gm="0.65" Gk="0.54" pk="560" pm="670" gM="1.3"/>
<profil id="D40" mat="BM" essence="feuillu" fmk="40" ftok="24" ft90k="0.6" fc0k="26" fc90k="8.8" fvk="3.8" E0m="11" E0k="9.4" E90m="0.75" Gm="0.7" Gk="0.59" pk="590" pm="700" gM="1.3"/>
<profil id="D50" mat="BM" essence="feuillu" fmk="50" ftok="30" ft90k="0.6" fc0k="29" fc90k="9.7" fvk="4.6" E0m="14" E0k="11.8" E90m="0.93" Gm="0.88" Gk="0.74" pk="650" pm="780" gM="1.3"/>
<profil id="D60" mat="BM" essence="feuillu" fmk="60" ftok="36" ft90k="0.6" fc0k="32" fc90k="10.5" fvk="5.3" E0m="17" E0k="14.3" E90m="1.13" Gm="1.06" Gk="0.89" pk="700" pm="840" gM="1.3"/>
<profil id="D70" mat="BM" essence="feuillu" fmk="70" ftok="42" ft90k="0.6" fc0k="34" fc90k="13.5" fvk="6" E0m="20" E0k="16.8" E90m="1.33" Gm="1.25" Gk="1.05" pk="900" pm="1080" gM="1.3"/>
<profil id="GL24h" mat="BLC" essence="resineux" fmk="24" ftok="16.5" ft90k="0.4" fc0k="24" fc90k="2.7" fvk="2.7" E0m="11.6" E0k="9.4" E90m="0.39" Gm="0.72" Gk="0.59" pk="380" pm="440" gM="1.25"/>
<profil id="GL28h" mat="BLC" essence="resineux" fmk="28" ftok="19.5" ft90k="0.45" fc0k="26.5" fc90k="3" fvk="3.2" E0m="12.6" E0k="10.2" E90m="0.42" Gm="0.78" Gk="0.64" pk="410" pm="480" gM="1.25"/>
<profil id="GL32h" mat="BLC" essence="resineux" fmk="32" ftok="22.5" ft90k="0.5" fc0k="29" fc90k="3.3" fvk="3.8" E0m="13.7" E0k="11.1" E90m="0.46" Gm="0.85" Gk="0.69" pk="430" pm="520" gM="1.25"/>
<profil id="GL36h" mat="BLC" essence="resineux" fmk="36" ftok="26" ft90k="0.6" fc0k="31" fc90k="3.6" fvk="4.3" E0m="14.7" E0k="11.9" E90m="0.49" Gm="0.91" Gk="0.74" pk="450" pm="560" gM="1.25"/>
<profil id="GL24c" mat="BLC" essence="resineux" fmk="24" ftok="14" ft90k="0.35" fc0k="21" fc90k="2.4" fvk="2.2" E0m="11.6" E0k="9.4" E90m="0.32" Gm="0.59" Gk="0.59" pk="350" pm="420" gM="1.25"/>
<profil id="GL28c" mat="BLC" essence="resineux" fmk="28" ftok="16.5" ft90k="0.4" fc0k="24" fc90k="2.7" fvk="2.7" E0m="12.6" E0k="10.2" E90m="0.39" Gm="0.72" Gk="0.64" pk="380" pm="460" gM="1.25"/>
<profil id="GL32c" mat="BLC" essence="resineux" fmk="32" ftok="19.5" ft90k="0.45" fc0k="26.5" fc90k="3" fvk="3.2" E0m="13.7" E0k="11.1" E90m="0.42" Gm="0.78" Gk="0.69" pk="410" pm="500" gM="1.25"/>
<profil id="GL36c" mat="BLC" essence="resineux" fmk="36" ftok="22.5" ft90k="0.5" fc0k="29" fc90k="3.3" fvk="3.8" E0m="14.7" E0k="11.9" E90m="0.46" Gm="0.85" Gk="0.74" pk="450" pm="540" gM="1.25"/>
</element_racine>
Le programme :
tractionEC5.py
Je n'ai aucune responsabilité quant à une éventuelle crise cardiaque ou perte de cheveux si un programmeur voit ça 😛
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Calcul du taux de travail en traction
import os
import os.path
import sys
import Pmw
from Tkinter import *
import tkMessageBox
from math import *
from xml.dom import minidom
HERE = os.path.dirname(sys.argv[0])
APPDIR = os.path.abspath(HERE)
sys.path.insert(0, APPDIR)
os.chdir(APPDIR)
#################################
#----------FONCTIONS------------#
# #
#################################
# fonction de récupération de la valeur en fonction du "symbole" dans la liste de 25 "ligne"
# du fichier materiau.xml. 25 lignes pour les 25 classes mécaniques de bois.
# RAPPEL : 0<=ligne<=25 ; m = "id" mat essence fmk ftok ft90k fc0k fc90k
#fvk E0m E0k E90m Gm Gk pk pm gM
def valeur_du_symbole(ligne,symbole) :
xmldoc = minidom.parse('materiau.xml')
reflist = xmldoc.getElementsByTagName('profil')
ligneX = reflist[ligne]
ligneX.attributes[symbole]
valeur_symbole = ligneX.attributes[symbole]
valeur_symbole = valeur_symbole.value
valeur_symbole = valeur_symbole.encode('utf-8')
return valeur_symbole
# création list classe mécanique bois
def list_classmeca():
xmldoc = minidom.parse('materiau.xml')
reflist = xmldoc.getElementsByTagName('profil')
listmeca = [ligneX.attributes["id"].value for ligneX in reflist]
return listmeca
#trouve le numéro de ligne de l'entrée de la combobox dans mecalist
def trouve():
classmeca = combo.get()
i=0
while i< len(mecalist):
if mecalist[i]==classmeca:
return i
i=i+1
return -1
#affiche valeur ft0k dans entr3
def affiche_ft0k():
entr3.delete(0,20)
ft0k=valeur_du_symbole(trouve(),"ftok")
entr3.insert(0, ft0k)
#affiche valeur de gM dans entr4
def affiche_gM():
entr4.delete(0,20)
gM=valeur_du_symbole(trouve(),"gM")
entr4.insert(0, gM)
#affiche valeurs k ft0k et gM dans entr3 et entr4
def affiche_valeursk():
affiche_ft0k()
affiche_gM()
#calcul de kh
def calcul_kh():
entr5.delete(0,20)
gM=float(entr4.get())
hauteur=float(entr2.get())
if gM==1.3:
if hauteur>=150:
kh=1.0
entr5.insert(0,kh)
else :
if hauteur<150 :
kh=(150/hauteur)
kh =pow(kh,0.2)
kh=min(1.3,kh)
kh=float(int(kh*100))/100
entr5.insert(0,kh)
elif gM==1.25:
if hauteur>=600:
kh=1.0
entr5.insert(0,kh)
else :
if hauteur<600 :
kh=pow(600/hauteur,0.1)
kh=min(1.1,kh)
kh=float(int(kh*100))/100
entr5.insert(0,kh)
#calcul du taux de travail
def calculfinal():
base = eval(entr1.get())
hauteur = eval(entr2.get())
Aire = base * hauteur
Effort = eval(entr6.get())
st0d = Effort / Aire
Ft0k = eval(entr3.get())
Kh = eval(entr5.get())
Kmod = eval(entr7.get())
gM = float(eval(entr4.get()))
Ft0d = Ft0k * Kh * Kmod / gM
travail = (st0d / Ft0d)
return travail
# Affich messagBox du taux de travail et inscrit le résultat en bas
def affiche_travail():
Titel = "Traction"
Message = float(int(calculfinal()*10000))/100
Message = "Taux de travail = " + str(Message) + "%"
messbox = tkMessageBox.showinfo(Titel, Message)
txt10.configure(text=Message)
#################################
#----------WIDGETS--------------#
#fentre,bouton,entry,combo #
#################################
#récupe des listes
mecalist = list_classmeca()
# création de la fenetre
fen1=Pmw.initialise()
fen1.title("Vérification du taux de travail en traction")
# création de widgets 'Label' et 'Entry' :
tex01 = Label(fen1, text='Vérification du taux de travail en traction.')
tex02 = Label(fen1, text='Définition de l\'élément étudié')
b1 =Button(fen1,text = 'Appliquer les valeurs k',command = affiche_valeursk)
txt1 = Label(fen1, text ='Base, b en mm :')
txt2 = Label(fen1, text ='Hauteur, h en mm :')
txt3 = Label(fen1, text ='ft,0,k en MPa :')
txt4 = Label(fen1, text ='γM :')
txt5 = Label(fen1, text ='kh :')
b2 = Button(fen1,text ='Calcul de kh?',command = calcul_kh)
tex03 = Label(fen1, text='Définition de l\'effort')
txt6 = Label(fen1, text ='N en N :')
txt7 = Label(fen1, text ='kmod :')
entr1 = Entry(fen1)
entr2 = Entry(fen1)
entr3 = Entry(fen1)
entr4 = Entry(fen1)
entr5 = Entry(fen1)
entr6 = Entry(fen1)
entr7 = Entry(fen1)
b3 = Button(fen1, text ='Calcul taux de travail',command=affiche_travail)
txt10 = Label(fen1, text ='néant')
b4 = Button(fen1,text='Fermer',command=sys.exit)
# Mise en place de combobox :
combo = Pmw.ComboBox(fen1, labelpos = NW,
label_text = 'Choisissez la classe mécanique :',
scrolledlist_items = mecalist,
listheight = 150,)
# Mise en page à l'aide de la méthode 'grid'
tex01.grid(row=1, column=1)
tex02.grid(row =2, column =1)
b1.grid(row=2, column =3)
txt1.grid(row =4, column =1)
txt2.grid(row =5, column =1)
txt3.grid(row =6, column =1)
txt4.grid(row =7, column =1)
txt5.grid(row =8, column =1)
tex03.grid(row =9, column =1)
txt6.grid(row =10, column =1)
txt7.grid(row =11, column =1)
entr1.grid(row =4, column =2)
entr2.grid(row =5, column =2)
entr3.grid(row =6, column =2)
entr4.grid(row =7, column =2)
entr5.grid(row =8, column =2)
b2.grid(row=8, column =3)
entr6.grid(row =10, column =2)
entr7.grid(row =11, column =2)
b3.grid(row=16,column= 2)
txt10.grid(row=17, column= 2)
combo.grid(row = 2,column=2)
b4.grid(row=17, column= 3)
# démarrage :
fen1.mainloop()
Amis étudiants en Construction Bois ou en Génie Civil, Charpentiers, Programmeurs, si ce projet vous intéresses faites moi signe.
En ce qui me concerne je suis doué pour les calculs, et les GUI même si j'aime la programmation il faut avoué que je suis très limité de ce coté là.
De plus j'ai toute la vie devant moi.
Je suis ouvert à toutes critiques et propositions.
A suivre...