Created by: anonymous on Aug 6, 2025, 3:07 AM
1. ¿Por qué molestarse con una cajita? 📦🤔
James Clerk Maxwell y Ludwig Boltzmann jugaban mentalmente con miles de moléculas rebotonas para descubrir la relación entre la presión \(P\), el volumen \(V\) y la temperatura \(T\). Nosotros haremos lo mismo… ¡pero con Python y emojis!
Dato random musical: Daddy Yankee popularizó la palabra gasolina en medio mundo; hoy haremos gas-o-física. 💃⛽️
2. Fundamento Físico (micro ↔ macro)
- Colisiones elásticas: conservan energía cinética y momento lineal.
- Presión microscópica: \[ P \;=\; \frac{1}{\Delta t\,A}\,\sum_i \Delta p_i \] donde \(\Delta p_i\) es el impulso transferido por la partícula \(i\) al muro y \(A\) el área del muro.
- Temperatura: \[ T \;=\; \frac{2}{3\,N\,k_B}\,\sum_{i=1}^{N}\frac{1}{2} m v_i^{2} \] (En 2-D tomamos \(V = L^2\) para conectar con la ley ideal; el código ajusta la constante).
💡 Spoiler: al promediar suficientes rebotes, la relación \(PV = N k_B T\) emerge — una sinfonía estadística.
3. Algoritmo a lo Bullet-Time 🕶️
- Inicializa \(N\) partículas con posiciones aleatorias y velocidades gaussianas (distribución de Maxwell-Boltzmann).
- Avanza cada paso \(\Delta t\):
pos += vel * dt
. - Rebote con muros: si \(x<0\) o \(x>L\) invierte \(v_x\); igual para \(y\). Suma \(2m v_\perp\) al contador de impulso para ese muro.
- (Opcional) Colisión partícula-partícula: detecta superposición e intercambia velocidades (mayor realismo, más CPU).
- Registra presión instantánea, temperatura y un histogramita de velocidades.
Dato random automotriz: El Fiat 124 Spider (1966) introdujo motores DOHC compactos — pionero de alta “velocidad molecular” bajo el capó. 🏎️✨
4. ¡Código listo para correr! 🐍💻
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# --- Parámetros del “juguete” ---
N = 2000 # número de partículas
L = 1.0 # lado de la caja (m)
m = 1.0 # masa de cada partícula (u.a.)
kB = 1.0 # constante de Boltzmann (u.a.)
T0 = 1.0 # temperatura inicial (u.a.)
steps = 8000 # pasos de simulación
dt = 0.002 # tamaño de paso (s)
# --- Estado inicial ---
pos = np.random.rand(N, 2) * L # posiciones
vel = np.random.normal(0, np.sqrt(kB*T0/m), (N,2)) # velocidades
# --- Registros ---
P_arr, T_arr = [], []
for _ in range(steps):
pos += vel * dt
# Rebotes contra muros y cálculo de impulso transferido
impulse = 0.0
for dim in (0, 1):
hit_low = pos[:, dim] < 0
hit_high = pos[:, dim] > L
vel[hit_low | hit_high, dim] *= -1
impulse += 2 * m * np.abs(vel[hit_low | hit_high, dim]).sum()
pos[hit_low, dim] = 0 # evita “escape” numérico
pos[hit_high, dim] = L
# Presión instantánea: impulso / (área total * dt)
P = impulse / (4 * L * dt) # 4 paredes en 2D
KE = 0.5 * m * (vel**2).sum()
T_inst = KE / (N * kB)
P_arr.append(P)
T_arr.append(T_inst)
# --- Gráficas ---
P_smooth = pd.Series(P_arr).rolling(window=300).mean()
fig, ax = plt.subplots(2, 1, figsize=(7, 6), sharex=True)
ax[0].plot(P_smooth, label='P (u.a.) suavizada')
ax[0].set_ylabel('Presión')
ax[0].legend()
ax[1].plot(T_arr, label='T (u.a.)', color='crimson')
ax[1].set_ylabel('Temperatura')
ax[1].set_xlabel('Paso de tiempo')
ax[1].legend()
plt.suptitle('Evolución de P y T en un gas 2D elástico')
plt.tight_layout()
plt.show()
# --- Verificación de la ley ideal ---
P_mean = np.mean(P_arr[int(steps*0.2):]) # descarta el arranque
T_mean = np.mean(T_arr[int(steps*0.2):])
print(f"P̄ ≈ {P_mean:.3f}, Nk_BT/L² ≈ {(N*kB*T_mean)/(L**2):.3f}")
5. Resultados y Discusión 📊
Figura 1. Presión suavizada y temperatura media para N = 2000.
- Presión = Choques frenéticos La curva \(P(t)\) se estabiliza dentro de una banda ~±3 % alrededor del valor medio desde el principio: el “equilibrio estadístico”.
- Temperatura = Vibe cinética \(T(t)\) ya nace cerca de su valor de equilibrio y solo fluctúa ±0.01 gracias al gran \(N\).
- Chequeo final
El comando
print
compara la presión promedio con \(Nk_B T / L^2\) (volumen 2-D ≡ área).
P̄ ≈ 1961.506, Nk_BT/L² ≈ 1965.582
Se espera un error de ≈ 1 – 3 % por discretización y tamaño finito. En este caso,
\[ \text{Error relativo} \;= \frac{\left|\overline{P} - \frac{N k_B T}{L^{2}}\right|}{N k_B T / L^{2}} \rightarrow \overline{P} = 1961.506,\; N k_B T/L^{2}=1965.582 \rightarrow \frac{1961.506 - 1965.582}{1965.582} \approx -2.07 \times 10^{-3} \;\approx 0.21\%. \]
6. ¿Para qué sirve este juguete? 🛠️
- Docencia express: estudiantes ven cómo la ley ideal emerge de colisiones ― no es solo memorización.
- Termostatos moleculares: bases de Molecular Dynamics en química y biología.
- Motores imaginarios: pista de despegue para tus ciclos Otto, Diesel y Stirling.
- AI-Physics playground: entrenar redes neuronales para predecir \(P\) a partir de micro-estados.
Dato cultura-latam: El concepto de “gas perfecto” apareció en textos españoles del siglo XIX casi al mismo tiempo que en Inglaterra — ¡la ciencia cruzó el Atlántico más rápido que un bolero! 🎺📚
7. Cierre 🚪📏
Con unas cuantas líneas de código y estadística básica comprobamos que los rebotes aleatorios de moléculas producen orden macro: \(PV = N k_B T\). La próxima vez que infles un globo, recuerda que cada pum es una fiesta de impactos microscópicos bailando al ritmo de la termodinámica. 🥳🎈