La diffusion est l’une des équations différentielles partielles les plus intuitives que vous pouvez simuler : un pic net se répand, un pas raide se lisse dans une transition douce et les gradients disparaissent progressivement. Si vous apprenez FIPY, Diffusion est également l’un des meilleurs points de départ car il s’intègre parfaitement au flux de travail de Fipy : Mesh → Variable → Équation → Boucle temporelle → Visualisation.
Dans ce guide, vous allez résoudre l’équation de diffusion dans Fipy à partir de zéro, exécuter une simulation 1D complète que vous pouvez modifier en toute sécurité, apprendre à interpréter la sortie, puis voir comment la même configuration s’étend à la 2D. L’objectif est la confiance pratique : vous devriez être en mesure de modifier la résolution, le pas de temps, la vitesse de diffusion et les conditions aux limites sans casser le modèle.
Ce que signifie la diffusion (sans les calculs lourds)
La diffusion décrit comment quelque chose se propage en raison des différences de concentration (ou de température). La chaleur se répand à travers une tige. Une goutte de colorant se répand dans l’eau. Mathématiquement, nous écrivons souvent la diffusion sous cette forme :
∂φ/∂t = ∇·(D ∇φ)
Ici φ est le champ qui vous intéresse (température, concentration, etc.). Le coefficient D contrôle la rapidité avec laquelle la diffusion se produit. Plus grand D signifie que le profil se lisse plus rapidement.
Les conditions aux limites sont importantes car les PDE ont besoin de règles sur les bords du domaine. Pour un premier cycle de diffusion, les frontières « sans flux » sont courantes : rien ne sort du domaine. Cela rend l’évolution facile à interpréter car le système n’est pas forcé par les frontières.
Comment Fipy représente la diffusion
FIPY résout les PDE à l’aide de la méthode du volume fini (FVM). Vous pouvez considérer votre domaine comme étant divisé en petites cellules. Le champ inconnu vit sur ces cellules (généralement aux centres cellulaires). La diffusion est mise en œuvre sous forme de flux entre les cellules voisines : les valeurs élevées poussent le flux vers de faibles valeurs jusqu’à ce que le profil se lisse.
Les blocs de construction FIPY pratiques sont :
Mesh— La géométrie et la résolution (grille 1D ou 2D)CellVariable— Le champφque vous résolvez pourTransientTerm()— La dérivée temporelle ∂φ/∂tDiffusionTerm(coeff=D)— L’opérateur de diffusion- Une boucle temporelle — Résolvez à plusieurs reprises avec
dtet visualisez les instantanés
Avant de commencer : liste de contrôle minimale de l’environnement
Vous avez besoin de Python Plus Fipy et d’une bibliothèque de traçage. Si vous utilisez des ordinateurs portables, le même code fonctionne ; Exécutez simplement les cellules dans l’ordre.
- Python installé (une version moderne est recommandée)
- Un environnement virtuel (recommandé)
- Fipy installé (et ses dépendances numériques)
- matplotlib installé pour le traçage
Premier exemple de travail : diffusion 1D
Nous modéliserons la diffusion sur un domaine 1D de 0 à 1 à l’aide d’une grille uniforme. La condition initiale sera une étape :
φ = 1 sur la moitié gauche et φ = 0 sur la moitié droite. La diffusion apaisera cette discontinuité dans le temps.
Le code ci-dessous est un script complet que vous pouvez exécuter tel quel.
# 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()
Ce que fait chaque bloc (afin que vous puissiez le modifier en toute sécurité)
Mesh : votre domaine et votre résolution
Grid1D(nx=nx, dx=dx) Crée une ligne divisée en nx cellules. Plus petit dx (plus grand nx) donne plus de détails mais coûte plus cher. La longueur de votre domaine est à peu près nx * dx.
CellVariable : le champ pour lequel vous résolvez
phi est stocké dans les centres de cellules. Vous commencez avec une condition initiale en utilisant setValue(). Avec Diffusion, cette forme initiale est ce que vous regardez se détendre au fil du temps.
L’équation : le changement de temps est égal à la diffusion
Cette ligne définit la PDE de diffusion dans la syntaxe de terme de FIPY :
TransientTerm() == DiffusionTerm(coeff=D)
D contrôle la rapidité avec laquelle l’étape se lisse. Si vous augmentez D, vous devriez voir la zone de transition s’élargir plus rapidement.
La boucle temporelle : avancer
Chaque appel à eq.solve(var=phi, dt=dt) fait avancer la solution d’un pas de temps. Nous capturons quelques instantanés afin que vous puissiez voir l’évolution sans tracer chaque étape.
Comment savoir si votre diffusion est correcte
Avec une condition initiale d’étape, la diffusion devrait créer une région de transition douce qui s’élargit progressivement. Le saut aigu doit s’adoucir et la courbe devrait devenir moins raide au fil du temps.
- Si le profil ne change pas : votre boucle peut ne pas fonctionner comme prévu, ou
dtetstepsproduisent trop peu de temps total. - Si le profil devient bruyant ou « explose » : réduisez
dt, augmentez la résolution ou simplifiez les limites. - Si tout semble décalé ou coupé : vérifiez votre condition initiale et confirmez que l’axe des x correspond à votre domaine.
Choisir DT et DX : Conseils pratiques sur la stabilité et la précision
Même si le code s’exécute, les choix de paramètres affectent la qualité et l’exécution. Trois ajustements couvrent la plupart des problèmes de « premier modèle » :
- Réduisez
dtsi l’évolution semble trop nerveuse, bruyante ou incohérente entre les courses. Un test rapide consiste à réduire de moitiédtet à doublerstepsafin que le temps simulé total reste similaire. - Augmenter
nxsi la courbe semble irrégulière ou si la zone de transition est mal résolue. Plus de cellules signifie généralement des profils plus lisses et de meilleurs gradients, à un coût de calcul plus élevé. - Traitez plus grand
Dcomme un « système plus rapide ». Si la diffusion est forte, vous avez généralement besoin d’undt(ou du moins pour vérifier que les résultats ne changent pas lorsque vous affinez le temps).
Une habitude simple qui empêche la confusion : chaque fois que vous modifiez dt ou nx, réexécutez et comparez deux exécutions (grossière ou raffinée). Si les courbes sont fondamentalement les mêmes, vous êtes dans un bon régime d’apprentissage et d’itération.
Six expériences rapides qui vous enseignent la diffusion rapidement
- Modifier la vitesse de diffusion : essayez
D = 0.1etD = 5.0et comparez la rapidité avec laquelle l’étape se détend. - Augmenter la résolution : modifiez
nxde 200 à 400 et voir à quoi ressemble la région de transition. - Essayez une bosse au lieu d’une étape : définissez
phi = 1uniquement dans une région étroite et regardez-la se propager de manière symétrique. - Capturez plus d’instantanés : ajoutez plus d’indices à
capture_atpour voir l’évolution de manière plus détaillée. - Exécutez plus longtemps : augmentez
stepset confirmez que le profil devient plus uniforme au fil du temps. - Enregistrer la sortie : ajouter
plt.savefig("diffusion_1d.png", dpi=200)avantplt.show().
Mise à niveau vers la diffusion 2D (changement minimal, gros gain)
Une fois que 1D se sent à l’aise, le passage à la 2D consiste principalement à modifier le maillage et la visualisation. La structure de l’équation reste la même. En 2D, vous commencerez généralement par un « spot » (valeur élevée dans une petite région) et vous le regarderez s’étaler dans une goutte lisse.
# 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()
Deux notes pratiques pour la 2D : premièrement, il peut être nettement plus lent que 1D car le nombre de cellules augmente comme nx * ny. Deuxièmement, les tracés d’images dépendent du remodelage ; Gardez votre (ny, nx) cohérent.
Dépannage : problèmes courants pour la première fois
Importer des erreurs ou des packages manquants
- Confirmez que FIPY est installé dans le même environnement où vous exécutez le script.
- Dans les ordinateurs portables, vérifiez que le noyau pointe vers le bon interpréteur.
- Vérifiez que MATPlotlib importe proprement.
La courbe ne change pas
- Augmenter le temps total simulé : augmenter
stepsoudtlégèrement (attentivement). - Assurez-vous que les instantanés incluent des étapes ultérieures, pas seulement le début.
- Confirmez que vous appelez réellement
eq.solve()dans la boucle.
La solution semble instable ou bruyante
- Réduire
dt(par exemple, de1e-4à5e-5). - Augmentez la résolution (
nx) pour mieux résoudre les gradients. - Testez un
Dplus petit pour réduire la vitesse d’évolution lors de l’apprentissage.
C’est trop lent
- Commencez avec moins de cellules, puis augmentez progressivement une fois que le flux de travail est clair.
- Capturez moins d’instantanés et tracez moins fréquemment.
- En 2D, réduisez
nxetnytout en expérimentant la configuration.
Conclusion : le modèle de diffusion que vous réutiliserez partout
La résolution de la diffusion dans Fipy enseigne une structure répétable que vous utiliserez pour de nombreux modèles PDE. Une fois que vous êtes à l’aise avec la façon dont Grid1D/Grid2D, CellVariable, TransientTerm et DiffusionTerm se connectent, vous pouvez étendre le même flux de travail à Convection – Diffusion, réaction-diffusion, sources et puits, paramètre balayages et vérifications de validation.
Si vous voulez la boucle d’apprentissage la plus rapide, effectuez une modification à la fois—D, nx, dt, ou la condition initiale — réexécute, et explique ce qui a changé et pourquoi. Cette habitude est ce qui transforme la diffusion d’une démo en un outil auquel vous pouvez avoir confiance.