La difusión es una de las ecuaciones diferenciales parciales más intuitivas (PDES) que puede simular: un pico agudo se extiende, un paso empinado se suaviza en una transición suave y los gradientes desaparecen gradualmente. Si está aprendiendo Fipy, la difusión también es uno de los mejores puntos de partida porque se asigna limpiamente al flujo de trabajo principal de Fipy: Mesh → Variable → Ecuación → Time Loop → Visualización.
En esta guía, resolverá la ecuación de difusión en Fipy desde cero, ejecutará una simulación 1D completa que puede modificar de manera segura, aprenderá a interpretar la salida y luego verá cómo la misma configuración se extiende a 2D. El objetivo es la confianza práctica: debe poder cambiar la resolución, el paso de tiempo, la velocidad de difusión y las condiciones de los límites sin romper el modelo.
Qué significa la difusión (sin las matemáticas pesadas)
La difusión describe cómo algo se extiende debido a las diferencias de concentración (o temperatura). El calor se extiende a través de una varilla. Una gota de tinte se extiende en el agua. Matemáticamente, a menudo escribimos difusión de esta forma:
∂φ/∂t = ∇·(D ∇φ)
Aquí φ es el campo que te importa (temperatura, concentración, etc.). El coeficiente D controla la rapidez de la difusión. Más grande D significa que el perfil se suaviza más rápidamente.
Las condiciones de contorno son importantes porque las PDES necesitan reglas en los bordes del dominio. Para una primera ejecución de difusión, los límites de «sin flujo» son comunes: nada sale del dominio. Eso hace que la evolución sea fácil de interpretar porque el sistema no está siendo forzado por los límites.
Cómo Fipy representa la difusión
Fipy resuelve las PDE utilizando el método de volumen finito (FVM). Puede pensar en su dominio como dividido en celdas pequeñas. El campo desconocido vive en esas células (típicamente en los centros celulares). La difusión se implementa como flujo entre celdas vecinas: los valores altos empujan el flujo hacia valores bajos hasta que el perfil se vuelve más suave.
Los prácticos bloques de construcción Fipy son:
Mesh— La geometría y la resolución (cuadrícula 1D o 2D)CellVariable— El campoφque resuelvesTransientTerm()— La derivada de tiempo ∂φ/∂tDiffusionTerm(coeff=D)— El operador de difusión- Un bucle de tiempo: resolver repetidamente con
dty visualizar instantáneas
Antes de comenzar: Lista de verificación de entorno mínimo
Necesita Python Plus Fipy y una biblioteca de trazado. Si está utilizando cuadernos, el mismo código funciona; Simplemente ejecute celdas en orden.
- Python instalado (se recomienda una versión moderna)
- Un entorno virtual (recomendado)
- Fipy instalado (y sus dependencias numéricas)
- matplotlib instalado para trazar
Primer ejemplo de trabajo: difusión 1D
Modelaremos la difusión en un dominio 1D de 0 a 1 usando una cuadrícula uniforme. La condición inicial será un paso:
φ = 1 en la mitad izquierda y φ = 0 en la mitad derecha. La difusión suavizará esa discontinuidad con el tiempo.
El siguiente código es un script completo que puede ejecutar tal cual.
# Solving Diffusion Equations with FiPy: 1D Example
# Save as: diffusion_1d_fipy.py
from fipy import Grid1D, CellVariable, TransientTerm, DiffusionTerm
import matplotlib.pyplot as plt
# --- 1) Mesh setup ---
nx = 200
dx = 1.0 / nx
mesh = Grid1D(nx=nx, dx=dx)
# --- 2) Variable (field) ---
phi = CellVariable(name="phi", mesh=mesh, value=0.0)
# Initial condition: step (left half = 1, right half = 0)
x = mesh.cellCenters[0]
phi.setValue(1.0, where=(x < 0.5))
# --- 3) Diffusion equation ---
D = 1.0
eq = TransientTerm() == DiffusionTerm(coeff=D)
# --- 4) Time stepping ---
dt = 1e-4
steps = 2000
snapshots = []
times = []
capture_at = {0, 50, 200, 800, 2000}
for step in range(steps + 1):
if step in capture_at:
snapshots.append(phi.value.copy())
times.append(step * dt)
eq.solve(var=phi, dt=dt)
# --- 5) Plot ---
plt.figure()
for y, t in zip(snapshots, times):
plt.plot(x.value, y, label=f"t = {t:.4f}")
plt.xlabel("x")
plt.ylabel("phi")
plt.title("1D Diffusion in FiPy")
plt.legend()
plt.show()
Qué hace cada bloque (para que puedas modificarlo de forma segura)
Mesh: su dominio y resolución
Grid1D(nx=nx, dx=dx) Crea una línea dividida en celdas nx. más pequeño dx (más grande nx) da más detalles pero cuesta más cálculo. La longitud de su dominio es aproximadamente nx * dx.
CellVariable: el campo que resuelves para
phi se almacena en los centros celulares. Comienza con una condición inicial usando setValue(). Con la difusión, esa forma inicial es lo que ves relajarte con el tiempo.
La ecuación: El cambio de tiempo es igual a difusión
Esta línea define el PDE de difusión en la sintaxis de término de Fipy:
TransientTerm() == DiffusionTerm(coeff=D)
D Controla la rapidez con que se suaviza el paso. Si aumentas D, deberías ver que la zona de transición se ensancha más rápido.
El bucle de tiempo: dar un paso adelante
Cada llamada a eq.solve(var=phi, dt=dt) avanza la solución en un solo paso de tiempo. Capturamos algunas instantáneas para que puedas ver la evolución sin trazar cada paso.
Cómo saber si su carrera de difusión se ve correcta
Con una condición inicial de paso, la difusión debe crear una región de transición suave que se ensanche gradualmente. El salto agudo debería suavizarse y la curva debería volverse menos pronunciada con el tiempo.
- Si el perfil no cambia: es posible que su bucle no se esté ejecutando como se espera, o
dtystepsproducen muy poco tiempo total. - Si el perfil se vuelve ruidoso o «explota»: Reduzca
dt, aumente la resolución o simplifique los límites. - Si todo parece cambiado o recortado: verifique su condición inicial y confirme que el eje x coincide con su dominio.
Elegir DT y DX: consejos prácticos de estabilidad y precisión
Incluso si el código se ejecuta, las opciones de parámetros afectan la calidad y el tiempo de ejecución. Tres ajustes cubren la mayoría de los problemas del «primer modelo»:
- Reducir
dtSi la evolución parece demasiado nerviosa, ruidosa o inconsistente entre ejecuciones. Una prueba rápida es reducir a la mitaddty duplicarsteps, por lo que el tiempo total simulado permanece similar. - Aumentar
nxSi la curva parece irregular o la zona de transición está mal resuelta. Más celdas generalmente significa perfiles más suaves y mejores gradientes, a un mayor costo computacional. - Trate más grande
Dcomo un «sistema más rápido». Si la difusión es fuerte, por lo general necesitadt(o al menos para verificar que los resultados no cambien cuando refina el tiempo).
Un hábito simple que evita la confusión: siempre que cambie dt o nx, vuelva a ejecutar y compare dos ejecuciones (grueso vs refinado). Si las curvas son básicamente las mismas, estás en un buen régimen de aprendizaje e iteración.
Seis experimentos rápidos que te enseñan difusión rápido
- Cambie la velocidad de difusión: intente
D = 0.1yD = 5.0y compare la rapidez con la que se relaja el paso. - Aumente la resolución: cambie
nxde 200 a 400 y vea cómo se ve la región de transición. - Pruebe un golpe en lugar de un paso: establezca
phi = 1solo en una región estrecha y observe cómo se extiende simétricamente. - Capture más instantáneas: agregue más índices a
capture_atpara ver la evolución con más detalles. - Ejecutar más tiempo: Aumente
stepsy confirme que el perfil se vuelve más uniforme con el tiempo. - Guardar salida: Agregar
plt.savefig("diffusion_1d.png", dpi=200)antes deplt.show().
Actualización a difusión 2D (cambio mínimo, gran recompensa)
Una vez que 1D se siente cómodo, moverse a 2D se trata principalmente de cambiar la malla y la visualización. La estructura de la ecuación sigue siendo la misma. En 2D, normalmente comenzarás con un «punto» (valor alto en una región pequeña) y verás cómo se extiende en una mancha suave.
# 2D Diffusion sketch (core ideas)
from fipy import Grid2D, CellVariable, TransientTerm, DiffusionTerm
import matplotlib.pyplot as plt
nx = ny = 100
dx = dy = 1.0 / nx
mesh = Grid2D(nx=nx, ny=ny, dx=dx, dy=dy)
phi = CellVariable(name="phi", mesh=mesh, value=0.0)
x, y = mesh.cellCenters
phi.setValue(1.0, where=((x - 0.5)**2 + (y - 0.5)**2 < 0.05**2))
D = 1.0
eq = TransientTerm() == DiffusionTerm(coeff=D)
dt = 1e-4
for _ in range(500):
eq.solve(var=phi, dt=dt)
# Visualize as an image
plt.figure()
plt.imshow(phi.value.reshape((ny, nx)), origin="lower")
plt.colorbar(label="phi")
plt.title("2D Diffusion in FiPy")
plt.show()
Dos notas prácticas para 2D: primero, puede ser significativamente más lento que 1D porque el número de células crece como nx * ny. En segundo lugar, los gráficos de imágenes dependen de la remodelación; Mantenga su (ny, nx) consistente.
Solución de problemas: problemas comunes por primera vez
Errores de importación o paquetes faltantes
- Confirme que Fipy está instalado en el mismo entorno donde ejecuta el script.
- En cuadernos, verifique que el kernel apunte al intérprete correcto.
- Compruebe que matplotlib importa limpiamente.
La curva no cambia
- Aumente el tiempo total simulado: eleve
stepsodtligeramente (con cuidado). - Asegúrese de que las instantáneas incluyan pasos posteriores, no solo el comienzo.
- Confirme que en realidad está llamando a
eq.solve()dentro del bucle.
La solución parece inestable o ruidosa
- Reduzca
dt(por ejemplo, de1e-4a5e-5). - Aumente la resolución (
nx) para resolver mejor los gradientes. - Pruebe un
Dmás pequeño para reducir la velocidad de evolución mientras aprende.
es demasiado lento
- Comience con menos celdas, luego aumente gradualmente una vez que el flujo de trabajo esté claro.
- Capture menos instantáneas y trace con menos frecuencia.
- En 2D, reduzca
nxynymientras experimenta con la configuración.
Conclusión: el patrón de difusión que reutilizarás en todas partes
Resolver la difusión en Fipy enseña una estructura repetible que usará para muchos modelos PDE. Una vez que te sientas cómodo con cómo conectar Grid1D/Grid2D, CellVariable, TransientTerm y DiffusionTerm, puedes extender el mismo flujo de trabajo a convección-difusión, reacción-difusión, fuentes y sumideros, parámetro barridos y comprobaciones de validación.
Si desea el ciclo de aprendizaje más rápido, realice un cambio a la vez:D, nx, dt o la condición inicial: vuelva a ejecutar y explique qué cambió y por qué. Ese hábito es lo que convierte a la difusión de una demostración en una herramienta en la que puedes confiar.