Skip to content
Open
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
88 changes: 87 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,100 @@ Todas las versiones publicadas de VentPy. El formato sigue
[Keep a Changelog](https://keepachangelog.com/es-ES/1.1.0/) y el versionado es
[semántico](https://semver.org/lang/es/).

## [Sin publicar]
## [0.3.0] — 2026-11-12

### El caudal de voladura cambia

Hasta la 0.2.1, declarar `gas_volume_per_kg` en `BlastingParams` desviaba el
cálculo a una fórmula que dividía el volumen total de gases entre el tiempo de
dilución. Ese cociente es el ritmo al que se generan los gases, no el caudal
que los diluye hasta un límite de exposición. Con 50 kg de explosivo,
0,04 m³/kg y 30 min daba 0,067 m³/min, que el redondeo de seguridad subía a 1.
El defecto alcanzaba a `calculate_blasting_flow` y también a
`VentilationGovernor`, y estaba presente desde la 0.1.0.

Desde la 0.3.0 hay un solo modelo: dilución de CO y de NOx según el tipo de
explosivo, recambio volumétrico y velocidad mínima de barrido.
`gas_volume_per_kg` ya no cambia el caudal; solo fija el volumen total de
gases que se reporta en `total_gas_volume_m3`.

**A quién afecta:** a quien haya calculado una demanda con voladura declarando
`gas_volume_per_kg`. Conviene recalcular: el caudal de voladura sube varios
órdenes de magnitud y puede pasar a ser el criterio gobernante.

| Caso (50 kg de ANFO, 30 min, frente de 12 m²) | 0.2.1 | 0.3.0 |
|---|---|---|
| `calculate_blasting_flow`, nivel del mar | 1 m³/min | 4.000 m³/min (dilución de NOx) |
| `VentilationGovernor`, 4.200 msnm, con un scoop de 150 HP | `Q_Exp` = 1; gobierna el diésel; total 981 | `Q_Exp` = 6.751; gobierna la voladura; total 7.764 |

Quien no declaraba `gas_volume_per_kg` ya obtenía en el Governor el modelo por
contaminante: sus resultados no cambian.

- `VentilationGovernor` exige ahora sección y longitud del frente para toda
voladura (las toma de `VentilationInput` si la voladura no las trae). Antes,
con `gas_volume_per_kg`, no las necesitaba.
- `calculate_blasting_flow` usa el mismo modelo sin corrección por altitud,
porque no recibe atmósfera, y omite los dos criterios de sección si no se
dan `face_area_m2` y `face_length_m`. Sin `gas_volume_per_kg` también
devolvía 1 m³/min.
- El ejemplo `01-demanda-peru` ya no incluye voladura, para seguir mostrando
el caso gobernado por el diésel. Su README explica el cambio.
- El modelo por contaminante es conservador: diluye todo el CO a 25 ppm y
todo el NOx a 5 ppm dentro del tiempo declarado, con 20 % de margen.

### Metadatos del paquete

- `pyproject.toml` declara los clasificadores de Python 3.9, 3.10, 3.11, 3.12 y 3.13, las
mismas versiones para las que `cibuildwheel` ya compila ruedas. Así PyPI las muestra en la
ficha del paquete. No cambia el código.

### Normas de Colombia y México

Dos preajustes nuevos, con el mismo patrón que el chileno: cada valor cita el
artículo o numeral leído en el texto vigente, y donde la norma no regula un
concepto la cita lo declara en vez de tomar prestado el artículo de otro país.

| Concepto | Colombia (Decreto 1886 de 2015) | México (NOM-023-STPS-2012) |
|---|---|---|
| Caudal por persona | 3 m³/min hasta 1.500 msnm y 6 de 1.500 en adelante (Art. 54, nums. 1 y 2) | 1,50 m³/min, sin escala por altitud (numeral 8.4.4 a) 1) |
| Caudal por HP diésel | 6 m³/min con CO en el escape ≤ 0,12 % (Art. 54, par. 2, num. 1) | 2,13 m³/min (numeral 8.4.4 a) 2) |
| Voladura | Sin tiempo de dilución; reingreso no antes de 15 min (Art. 157) | Sin tiempo de dilución; reconocimiento a los 30 min y sin humo (numeral 8.6.9 g) |
| Gases | Tabla del Art. 39; oxígeno en el Art. 38 y metano en el Art. 53 | NOM-010-STPS-2014, Tabla I.1, por remisión de la NOM-023 |
| Polvo | Remite a los VLP de la ACGIH (Art. 74) | NOM-010-STPS-2014, Tabla I.1 |
| Carga térmica | Temperatura efectiva (Arts. 217 y 218): el piso de 30 m/min queda como criterio de ingeniería | Índice TGBH de la NOM-015-STPS-2001: el piso de 30 m/min queda como criterio de ingeniería |

- `RegulatoryConfig.colombia()` y `RegulatoryConfig.mexico()`, los miembros
`RegulatoryStandard.D1886_Colombia` y `RegulatoryStandard.NOM023_Mexico`, y
`--norma colombia|mexico` en `ventpy demanda`, `ventpy lmp` y
`ventpy cobertura`.
- **Colombia, borde de 1.500 msnm.** Las dos bandas del Art. 54 incluyen el
1.500 en su texto. Rige la regla común de la librería: a 1.500 msnm exactos
aplica la banda inferior (3 m³/min).
- **Colombia, factor diésel.** El preajuste usa 6 m³/min por HP. Quien acredite
CO en el escape ≤ 0,08 % puede construir su configuración con 4 (Art. 54,
par. 2, num. 2). Con CO sobre 0,12 % el decreto no da valor.
- **México, oxígeno.** La NOM-023 no fija el mínimo de oxígeno en labores. La
tabla trae 19,5 % como criterio de ingeniería y la cita lo dice.
- **México, carbón.** La NOM-023 exceptúa las minas de carbón, que se rigen por
la NOM-032-STPS-2008. Este preajuste no las cubre.
- En las dos tablas de gases el SO2 solo tiene límite de corto tiempo: su
`twa_8h` es `None`, no cero.
- Colombia se verificó contra el texto consolidado con el Decreto 944 de 2022
y México contra el DOF del 11-oct-2012 y del 28-abr-2014.

### Correcciones

- `shock_factors()` listaba `x = 0.0` en expansión, contracción, codos y unión,
donde el factor sale por fórmula o es manual. Un cero se lee como «sin
pérdida»: ahora `x` es `None` en esas filas.

### Documentación de la API

- Los campos de `GasLimit` que la norma no fija valen `None`, y la ayuda lo
dice.
- `calculate_diesel_flow` aclara que solo aplica el factor por HP de la norma;
la dilución de CO y NOx por contaminante la calcula `VentilationGovernor`.

## [0.2.1] — 2026-08-20

### La cita normativa sigue a la norma configurada
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.20)
project(ventpy
VERSION 0.2.1
VERSION 0.3.0
DESCRIPTION "High-performance mine ventilation calculation library"
LANGUAGES CXX
)
Expand Down
13 changes: 7 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Contributing to VentPy · Cómo contribuir a VentPy

VentPy is an open-source library for **mine ventilation calculations**. It started with the
Peruvian standard (DS 024-2016-EM) and is growing toward **multi-standard support across Latin
America**: Chile, Colombia and Mexico.
Peruvian standard (DS 024-2016-EM), now also covers Chile (DS 132), Colombia (Decreto 1886)
and Mexico (NOM-023-STPS-2012), and is growing toward **multi-standard support across Latin
America**.

> 🇪🇸 **Este documento está en inglés y español.** Baja para la versión en español.
> **No necesitas ser programador experto.** Si eres ingeniero de minas y conoces la norma de tu
Expand Down Expand Up @@ -38,7 +39,7 @@ pip install -e ".[test,viz]"
pytest tests/python -q

# 4. Create a branch, make your change, run tests again
git checkout -b add-chile-standard
git checkout -b add-bolivia-standard
pytest tests/python -q

# 5. Commit and open a Pull Request
Expand All @@ -65,8 +66,8 @@ clear to you, it wasn't clear enough.

**No necesitas escribir C++.** En orden de lo que más falta:

1. **Agregar la norma de tu país.** ¿Conoces el reglamento de ventilación de Chile, Colombia o
México? Esa es la contribución que más necesitamos. Mira `ROADMAP.md`.
1. **Agregar la norma de tu país.** ¿Conoces el reglamento de ventilación de Bolivia, Ecuador,
Argentina u otro país? Esa es la contribución que más necesitamos. Mira `ROADMAP.md`.
2. **Casos resueltos.** Un caso real de ventilación (anonimizado) con sus números, como test.
3. **Documentación.** Corregir un párrafo confuso, traducir, agregar un diagrama.
4. **Reportar un número equivocado.** Si un resultado no calza con tu experiencia en campo,
Expand All @@ -87,7 +88,7 @@ pip install -e ".[test,viz]"
pytest tests/python -q

# 4. Crea una rama, haz tu cambio, corre los tests otra vez
git checkout -b agregar-norma-chile
git checkout -b agregar-norma-bolivia
pytest tests/python -q

# 5. Commitea y abre un Pull Request
Expand Down
36 changes: 24 additions & 12 deletions README.es.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

Cálculos de ventilación subterránea de alto rendimiento para Python, respaldados por un núcleo en C++20.

VentPy ayuda a ingenieros de minas a estimar la demanda de ventilación en operaciones subterráneas mediante una API auditable que cubre personal, flotas diesel, voladura, polvo, carga térmica, correcciones atmosféricas, diseño de ductos/red y selección de ventilador, actualmente bajo los marcos regulatorios peruano (`DS 024-2016-EM` / `DS 023-2017-EM`) y chileno (`DS 132` / `DS 594`). Los cálculos corren en un núcleo C++ tipado y probado en vez de una hoja de cálculo: cada resultado trae su criterio gobernante y su cita normativa, no solo un número.
VentPy ayuda a ingenieros de minas a estimar la demanda de ventilación en operaciones subterráneas mediante una API auditable que cubre personal, flotas diesel, voladura, polvo, carga térmica, correcciones atmosféricas, diseño de ductos/red y selección de ventilador, actualmente bajo los marcos regulatorios peruano (`DS 024-2016-EM` / `DS 023-2017-EM`), chileno (`DS 132` / `DS 594`), colombiano (`Decreto 1886 de 2015`) y mexicano (`NOM-023-STPS-2012` / `NOM-010-STPS-2014`). Los cálculos corren en un núcleo C++ tipado y probado en vez de una hoja de cálculo: cada resultado trae su criterio gobernante y su cita normativa, no solo un número.

## Qué hace VentPy

Expand All @@ -33,35 +33,47 @@ VentPy ayuda a ingenieros de minas a estimar la demanda de ventilación en opera

## Soporte multi-norma

VentPy trae preajustes oficiales para dos marcos regulatorios, cada constante citando su artículo:
VentPy trae preajustes oficiales para cuatro marcos regulatorios, cada constante citando su artículo:

```python
import ventpy

peru = ventpy.calculate_personnel_flow(15, 4200.0, ventpy.RegulatoryConfig.peru())
chile = ventpy.calculate_personnel_flow(15, 4200.0, ventpy.RegulatoryConfig.chile())
colombia = ventpy.calculate_personnel_flow(15, 4200.0, ventpy.RegulatoryConfig.colombia())
mexico = ventpy.calculate_personnel_flow(15, 4200.0, ventpy.RegulatoryConfig.mexico())

print(f"Peru: {peru.q_personnel} m3/min ({peru.flow_per_person_base} m3/min/person)")
print(f"Chile: {chile.q_personnel} m3/min ({chile.flow_per_person_base} m3/min/person)")
print(f"Peru: {peru.q_personnel} m3/min ({peru.flow_per_person_base} m3/min/person)")
print(f"Chile: {chile.q_personnel} m3/min ({chile.flow_per_person_base} m3/min/person)")
print(f"Colombia: {colombia.q_personnel} m3/min ({colombia.flow_per_person_base} m3/min/person)")
print(f"Mexico: {mexico.q_personnel} m3/min ({mexico.flow_per_person_base} m3/min/person)")
```

Salida:

```
Peru: 90.0 m3/min (6.0 m3/min/person)
Chile: 45.0 m3/min (3.0 m3/min/person)
Peru: 90.0 m3/min (6.0 m3/min/person)
Chile: 45.0 m3/min (3.0 m3/min/person)
Colombia: 90.0 m3/min (6.0 m3/min/person)
Mexico: 23.0 m3/min (1.5 m3/min/person)
```

- `RegulatoryConfig.peru()` — `DS 024-2016-EM` / `DS 023-2017-EM`.
- `RegulatoryConfig.chile()` — `DS 132`, Reglamento de Seguridad Minera (los límites de gases también usan el `DS 594`).
- `RegulatoryConfig.for_standard(standard)` — construye cualquiera de los dos preajustes a partir de un miembro del enum `RegulatoryStandard`; es lo que usa internamente el flag `--norma peru|chile` de la CLI.
- `RegulatoryConfig.colombia()` — `Decreto 1886 de 2015`, Reglamento de Seguridad en las Labores Mineras Subterráneas (consolidado con el `Decreto 944 de 2022`). Un solo escalón de altitud a los 1.500 msnm; 6 m³/min por HP, o 4 si el CO en el escape no pasa de 0,08 %, caso en que se construye una configuración propia.
- `RegulatoryConfig.mexico()` — `NOM-023-STPS-2012`, para minas subterráneas que no son de carbón. No escala por altitud; los límites de gases llegan por remisión a la `NOM-010-STPS-2014`. Las minas de carbón se rigen por la `NOM-032-STPS-2008`, que este preajuste no cubre.
- `RegulatoryConfig.for_standard(standard)` — construye cualquiera de los cuatro preajustes a partir de un miembro del enum `RegulatoryStandard`; es lo que usa internamente el flag `--norma` de la CLI.

Donde una norma no regula un concepto (tiempo de dilución tras la voladura, fugas en ductos, velocidad mínima fuera del carbón en Colombia, oxígeno mínimo en labores en México), la cita impresa lo declara y atribuye el valor a criterio de ingeniería.

Agregar la norma de otro país es la contribución que más necesita VentPy — ver [Contribuir](#contribuir).

## Estado del proyecto

VentPy se encuentra en **beta**. Los cálculos de personal, diesel, voladura, polvo, térmico, cobertura, red, ventilador y atmósfera están implementados, probados (219 pruebas en C++ y 176 en Python, incluidas pruebas basadas en propiedades y de escala hasta 500 ramales) y expuestos a Python para ambos preajustes.
VentPy se encuentra en **beta**. Los cálculos de personal, diesel, voladura, polvo, térmico, cobertura, red, ventilador y atmósfera están implementados, probados (245 pruebas en C++ y 199 en Python, incluidas pruebas basadas en propiedades y de escala hasta 500 ramales) y expuestos a Python para los cuatro preajustes.

> **En la 0.3.0 cambia el caudal de voladura.** Hasta la 0.2.1, declarar `gas_volume_per_kg` hacía que la voladura se calculara como volumen de gases entre tiempo de dilución, sin llevarlo a un límite de exposición: el resultado era del orden de 1 m³/min. Desde la 0.3.0 la voladura se calcula siempre por dilución de CO y NOx, y `gas_volume_per_kg` solo fija el volumen de gases que se reporta. Si calculaste una demanda con voladura y ese parámetro, recalcúlala: el caudal de voladura sube varios órdenes de magnitud y puede pasar a gobernar. Detalle en el [`CHANGELOG.md`](https://github.com/Miqueas7/VentPy/blob/master/CHANGELOG.md).
>
> **En la 0.2.1 cambian las citas, no los números.** Hasta la 0.2.0, todo resultado citaba el marco peruano aunque se construyera con `RegulatoryConfig.chile()`: el caudal era correcto, pero la referencia legal impresa junto a él no. Desde la 0.2.1 la cita sigue a la norma configurada, y donde el `DS 132` no regula un concepto, la cita lo declara explícitamente en vez de tomar prestado un artículo peruano. Si emitiste informes con el preajuste chileno, conviene reemitirlos.

> **Los resultados cambian entre 0.1.0 y 0.2.0.** La versión 0.2.0 corrige tres citas normativas del núcleo. Si calculaste algo con 0.1.0, conviene rehacerlo, especialmente por encima de 1.500 msnm.
Expand Down Expand Up @@ -118,9 +130,9 @@ Cinco ejemplos resueltos y auto-verificables (cada `run.py` afirma sus propios n

Instalar VentPy también instala el comando `ventpy`, una capa de presentación delgada sobre la misma API pública (sin lógica de cálculo propia) con 5 subcomandos:

- `ventpy demanda <archivo.json> [--norma peru|chile] [--json]` — demanda total de ventilación de una zona/frente
- `ventpy lmp [--norma peru|chile] [--gas GAS] [--json]` — límites máximos permisibles (LMP) de gases regulados
- `ventpy cobertura <archivo.json> [--norma peru|chile] [--json]` — análisis de déficit/cobertura de un levantamiento de zonas
- `ventpy demanda <archivo.json> [--norma peru|chile|colombia|mexico] [--json]` — demanda total de ventilación de una zona/frente
- `ventpy lmp [--norma peru|chile|colombia|mexico] [--gas GAS] [--json]` — límites máximos permisibles (LMP) de gases regulados
- `ventpy cobertura <archivo.json> [--norma peru|chile|colombia|mexico] [--json]` — análisis de déficit/cobertura de un levantamiento de zonas
- `ventpy red <archivo.json> [--json]` — balance de una red de ventilación (Hardy Cross)
- `ventpy ventilador <archivo.json> [--json]` — punto de operación de un ventilador (independiente o acoplado a una red)

Expand All @@ -142,7 +154,7 @@ regulation_ref: DS 024-2016-EM, Anexo 15, fila 33 (via Art. 246)

VentPy expone 87 nombres públicos (`ventpy.__all__`). Puntos de entrada principales:

- `RegulatoryConfig` (`.peru()`, `.chile()`, `.for_standard(...)`)
- `RegulatoryConfig` (`.peru()`, `.chile()`, `.colombia()`, `.mexico()`, `.for_standard(...)`)
- `VentilationGovernor`, `VentilationInput`
- `DieselFleet`, `AtmosphericParams`, `PersonnelParams`, `BlastingParams`, `DustParams`, `ThermalParams`

Expand Down
Loading
Loading