Skip to content
Merged

Beta #144

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install ruff
- run: ruff check ourocode/ tests/

test:
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install dependencies
run: |
pip install --upgrade pip
pip install -e ".[test]"
- name: Run tests
run: pytest tests/ -v --tb=short
227 changes: 227 additions & 0 deletions .windsurf/agents.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
# Ourocode — Contexte agent Cascade

## Vue d'ensemble du projet

**Ourocode** est une bibliothèque Python (v1.9.0, Python ≥ 3.12) de calcul de structure selon les Eurocodes avec Annexes Nationales Françaises.
Auteur : Anthony PARISOT — [OUREA STRUCTURE](https://ourea-structure.fr)
Licence : Apache 2.0

---

## Architecture du code

```
ourocode/
├── ourocode/
│ ├── __version__.py
│ ├── data/ # Données CSV/JSON de référence normative
│ │ ├── caracteristique_meca_acier.csv
│ │ ├── caracteristique_meca_bois.csv
│ │ ├── caracteristique_meca_panel.csv
│ │ ├── caracteristique_meca_beton.csv
│ │ ├── carte_action_region.csv # Zones neige/vent/sismique par code INSEE
│ │ ├── coeff_psy.csv
│ │ ├── kmod.csv / kdef.csv / kfi.csv / gammaM.csv
│ │ ├── limite_fleche.csv
│ │ ├── exploitation.csv
│ │ ├── section_boulon.csv
│ │ ├── qualite_acier.csv
│ │ ├── sismique/ # Données sismiques (catégories, sols…)
│ │ └── vent/ # Données vent par zones
│ └── eurocode/
│ ├── objet.py # Classe de base Objet
│ ├── A0_Projet.py # Classes Projet, Batiment, Model_generator
│ ├── EC0_Combinaison.py # EN 1990 – Combinaisons d'actions
│ ├── EC1_Exploitation.py # EN 1991 – Charges d'exploitation
│ ├── EC1_Neige.py # EN 1991 – Action neige
│ ├── EC1_Vent.py # EN 1991 – Action vent
│ ├── EC3_Element_droit.py # EN 1993 – Éléments droits acier
│ ├── EC3_Assemblage.py # EN 1993 – Assemblages acier
│ ├── EC3_Feu.py # EN 1993 – Vérification feu acier
│ ├── EC5_Element_droit.py # EN 1995 – Éléments droits bois
│ ├── EC5_Assemblage.py # EN 1995 – Assemblages bois
│ ├── EC5_CVT.py # EN 1995 – Murs à ossature bois (MOB/CVT)
│ ├── EC5_Feu.py # EN 1995 – Vérification feu bois
│ └── EC8_Sismique.py # EN 1998 – Action sismique
└── tests/
├── test_A0_Projet.py
├── test_EC0_Combinaison.py
├── test_EC1_Neige.py
├── test_EC3_Assemblage.py
├── test_EC3_Element_droit.py
├── test_EC5_Assemblage.py
├── test_EC5_CVT.py
├── test_EC5_Element_droit.py
├── test_EC5_Feu.py
└── test_EC8_Sismique.py
```

---

## Hiérarchie des classes (héritage)

```
Objet (objet.py)
└── Projet (A0_Projet.py)
├── Batiment (A0_Projet.py)
│ ├── Neige (EC1_Neige.py)
│ ├── Sismique (EC8_Sismique.py)
│ └── MOB (EC5_CVT.py)
├── Combinaison (EC0_Combinaison.py)
├── Barre (EC5_Element_droit.py)
│ ├── Flexion, Traction, Compression, Cisaillement,
│ │ Compression_perpendiculaire, Compression_inclinees, Deformation…
│ └── Feu (EC5_Feu.py)
├── Plat (EC3_Element_droit.py) ← acier
└── Assemblage (EC5_Assemblage.py)
└── Pointe, Agrafe, Boulon, Tirefond, Broche…
```

---

## Classe de base : `Objet`

Toutes les classes héritent de `Objet` (`objet.py`). Points clés :

- **`PATH_CATALOG`** : résolution automatique du chemin vers `ourocode/data/`.
- **`_data_from_csv(data_file)`** : lecture des CSV de référence via pandas.
- **`_from_parent_class(objet, **kwargs)`** : instanciation d'une sous-classe à partir d'une instance parente existante (pattern central du catalogue).
- **`_from_dict(dictionary)`** : instanciation depuis un dictionnaire.
- **`_assign_handcalcs_value(handcalc_value, args)`** : assigne les résultats `handcalcs` aux attributs d'instance.
- **`_physical_to_dict` / `_dict_to_physical`** : sérialisation/désérialisation des objets `forallpeople.Physical`.
- **`save_data` / `load_data`** : persistence JSON ou CSV (ouvre un `QFileDialog` si pas de chemin fourni).
- **`save_object` / `_open_object`** : sérialisation pickle vers fichier `.oco`.
- **`synthese_taux_travail()` / `_add_synthese_taux_travail()`** : tableau pandas de synthèse des taux de travail (situation normale + incendie).
- **`JUPYTER_DISPLAY`** : booléen de classe, contrôle l'affichage LaTeX dans Jupyter.

---

## Unités : `forallpeople` (si)

Toutes les grandeurs physiques utilisent `forallpeople` avec l'environnement `"structural"`.

| Entrée utilisateur | Unité interne |
|--------------------|---------------|
| dimensions (b, h, t) | `si.mm` |
| longueurs de projet | `si.m` |
| forces | `si.kN` ou `si.N` |
| contraintes | `si.MPa` ou `si.N/si.mm**2` |

La méthode `_convert_unit_physical` gère les conversions entre unités SI.
Toujours fournir les valeurs numériques brutes au constructeur (ex : `b=100` pour 100 mm) — la conversion `* si.mm` est faite **dans** le constructeur.

---

## Génération LaTeX avec `handcalcs`

Chaque méthode de vérification retourne un tuple `(latex_str, valeur)` via le décorateur `@handcalc`.
Exemple d'usage dans Jupyter :

```python
from IPython.display import display, Latex
latex_taux, taux = panne_flexion.taux_m_d()
display(Latex(latex_taux))
```

---

## Classes et modules clés

### `A0_Projet.py` — Base projet
- **`Projet`** : définit ingénieur, numéro, adresse, code INSEE, altitude.
- **`Batiment`** : ajoute dimensions (h, d, b), angles de toiture.
- **`Model_generator`** : modèle éléments finis via `PyNiteFEA` (FEModel3D).

### `EC0_Combinaison.py` — EN 1990
- **`Combinaison`** : génère les combinaisons ELU_STR, ELU_STR_ACC, ELS_C, ELS_QP à partir d'un `Model_generator`.
- Actions : G, Q, Sn, W+, W-, Sx, Ae.

### `EC1_Neige.py` — EN 1991-1-3
- **`Neige`** → hérite de `Batiment`.
- Récupère la zone neige via code INSEE (`carte_action_region.csv`).

### `EC1_Vent.py` — EN 1991-1-4
- Classes vent héritant de `Batiment`.

### `EC3_Element_droit.py` — EN 1993-1-1
- **`Plat`** : plaque acier (t, h, b, classe_acier S235/S355…, classe transversale 1-3).
- Classe 4 non implémentée → `ValueError`.

### `EC3_Assemblage.py` — EN 1993 assemblages acier

### `EC3_Feu.py` — EN 1993 feu

### `EC5_Element_droit.py` — EN 1995-1-1
- **`Barre`** : pièce bois (b, h, section, classe C24/GL24h/OSB…, cs 1-3, humidité Hi/Hf).
- Sous-classes de vérification : `Flexion`, `Traction`, `Compression`, `Cisaillement`, `Compression_perpendiculaire`, `Compression_inclinees`, `Deformation`.

### `EC5_Assemblage.py` — EN 1995 assemblages bois
- **`Assemblage`** : bois/bois ou bois/métal, prend deux objets `Barre` ou `Plat`.
- Sous-classes : `Pointe`, `Agrafe`, `Boulon`, `Tirefond`, `Broche`.

### `EC5_CVT.py` — EN 1995 §9.2.4 Murs à ossature bois
- **`MOB`** → hérite de `Batiment`.
- Méthode A : systèmes de murs, panneaux, connecteurs, calcul efforts CVT + déformations.

### `EC5_Feu.py` — EN 1995-1-2
- **`Feu`** → hérite de `Barre`.
- Vitesse de carbonisation, section résiduelle, vérifications ELU incendie.

### `EC8_Sismique.py` — EN 1998
- **`Sismique`** → hérite de `Batiment`.
- Méthode des forces latérales, classes de ductilité (DCL/DCM/DCH), spectre de réponse.

---

## Données de référence (`ourocode/data/`)

| Fichier | Contenu |
|---------|---------|
| `caracteristique_meca_bois.csv` | fm, ft, fc, E… pour C14→GL32h, LVL, OSB |
| `caracteristique_meca_panel.csv` | Caractéristiques panneaux OSB/CP |
| `caracteristique_meca_acier.csv` | fy, fu pour S235, S275, S355, S420, S460 |
| `carte_action_region.csv` | Zone neige/vent/sismique par code INSEE (5 chiffres) |
| `kmod.csv` | Coefficients kmod par classe de service et durée de chargement |
| `kdef.csv` | Coefficients de fluage kdef |
| `gammaM.csv` | Coefficients partiels γM par type de bois |
| `limite_fleche.csv` | Limites de flèche par type d'élément |
| `sismique/` | Catégories d'importance, classes de sol |

---

## Dépendances principales

| Package | Usage |
|---------|-------|
| `forallpeople` | Calcul avec unités physiques SI |
| `handcalcs` | Génération de LaTeX depuis du Python |
| `PyNiteFEA` | Modèle éléments finis 3D |
| `pyvista` + `PySide6` | Visualisation 3D et dialogues fichiers |
| `pandas` | Lecture des CSV de référence |
| `Pillow` | Affichage des images de schémas |

---

## Tests

```bash
pytest --cov=. --cov-report html
```

Fichiers de test dans `tests/`, nommés `test_<module>.py`.
Couvrent les modules principaux. Pas de test dédié à `EC1_Vent.py` ni `EC3_Feu.py` pour l'instant.

---

## Conventions et patterns importants

1. **Pattern `_from_parent_class`** : pour enchaîner les vérifications, on passe un objet déjà instancié à une sous-classe :
```python
barre = Barre(b=100, h=200, classe="C24", cs=2, ...)
flexion = Flexion._from_parent_class(barre, lo_rel_y=5000, ...)
```
2. **`**kwargs` remontants** : tous les constructeurs acceptent `**kwargs` transmis à `super().__init__()`, ce qui permet de passer les paramètres `Projet` directement lors de la création d'une `Barre`.
3. **Arguments à choix multiples** : les paramètres dont la valeur est un tuple/liste dans la signature sont des énumérations de valeurs acceptées (ex : `section=["Rectangulaire","Circulaire"]`).
4. **Unités en entrée** : toujours des valeurs numériques brutes, la conversion est faite dans le constructeur (`self.b = b * si.mm`).
5. **Résultats des méthodes de vérification** : tuple `(latex_str, valeur_numérique)`.
6. **`QFileDialog`** est requis pour `save_data`/`load_data` sans argument `path` → nécessite un environnement Qt actif.
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Changelog

Toutes les modifications notables de ce projet seront documentées dans ce fichier.

Le format est basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/),
et ce projet adhère au [Semantic Versioning](https://semver.org/lang/fr/).

## [Unreleased]

### Changed
- PySide6, PyNiteFEA et pyvista sont désormais des dépendances optionnelles (`pip install "ourocode[full]"`).
- Les messages utilisateur (`print`) convertis en `warnings.warn` dans EC5_Element_droit, EC5_Feu, EC5_Assemblage.
- Import wildcard `from math import *` supprimé dans EC1_Vent.py.

### Fixed
- Suppression des `print` de debug dans EC5_Element_droit, EC1_Vent, EC3_Feu, EC5_Assemblage.
- Correction du shadow de la variable `si` (module forallpeople) dans `objet.py` `_add_synthese_taux_travail`.
- Remplacement du `bare except` par `except ImportError` dans `objet.py`.
- Correction des badges du README (licence, CI, release).

### Added
- CI GitHub Actions : lint (ruff) + tests (pytest) sur push/PR vers main.
- CHANGELOG.md.
- Documentation des dépendances optionnelles dans le README.

## [1.9.0] - 2025

### Added
- Module EC3_Feu : calcul température acier au feu selon EN 1993-1-2.
- Module EC8_Sismique : spectre élastique selon EN 1998-1.
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@

# 📐 Ourocode - Bibliothèque Python pour le calcul de structure selon les Eurocodes

[![License: Apache License 2.0](https://img.shields.io/badge/License-A-blue.svg)](LICENSE)
<!-- [![PyPI](https://img.shields.io/pypi/v/eurocode-calc.svg)](https://pypi.org/project/ourocode/) -->
[![Tests](https://img.shields.io/github/v/release/AnthonyPrst/ourocode)](https://github.com/AnthonyPrst/ourocode/pyptoject.toml)
[![Coverage](https://img.shields.io/codecov/c/github/ton-org/eurocode)](https://codecov.io/gh/ton-org/ourocode)
[![License: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)
[![CI](https://github.com/AnthonyPrst/ourocode/actions/workflows/ci.yml/badge.svg)](https://github.com/AnthonyPrst/ourocode/actions/workflows/ci.yml)
[![Release](https://img.shields.io/github/v/release/AnthonyPrst/ourocode)](https://github.com/AnthonyPrst/ourocode/releases)

---

Expand Down Expand Up @@ -40,6 +39,13 @@ pip install ourocode
pip install git+https://github.com/AnthonyPrst/ourocode.git
```

> Avec les dépendances optionnelles (GUI PySide6 et/ou MEF Pynite) :
```bash
pip install "ourocode[full]" # GUI + MEF
pip install "ourocode[gui]" # PySide6 uniquement
pip install "ourocode[mef]" # PyNiteFEA + pyvista uniquement
```

---

## ✨ Fonctionnalités
Expand Down
19 changes: 18 additions & 1 deletion ourocode/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1,18 @@
__version__ = "1.9.0"
from pathlib import Path

try:
import tomllib
except ImportError:
try:
import tomli as tomllib
except ImportError:
tomllib = None

if tomllib is not None:
_pyproject_path = Path(__file__).parent.parent / "pyproject.toml"
with open(_pyproject_path, "rb") as f:
_data = tomllib.load(f)
__version__ = _data["project"]["version"]
else:
# Fallback si tomllib/tomli non disponible (Python < 3.11 sans tomli)
__version__ = "1.9.0"
Loading
Loading