Reading Time: 10 minutes

Points à retenir clés

  • Les limites périodiques de FIPY sont mises en œuvre de manière plus propre avec les objets PeriodicGrid ou les commandes de maillage périodique GMSH plutôt qu’un couplage manuel.
  • Les limites symétriques sont des conditions de Neumann à flux zéro appliquée aux plans de symétrie. Ce n’est pas une catégorie FIPY distincte, mais une utilisation physique des modèles de conditions aux limites standard.
  • Les frontières de Robin combinent des contraintes de valeur et de flux. Ils peuvent être implémentés avec ImplicitRobinSource, ImplicitSourceTerm ou une approche de divergence FaceVariable.
  • Les écueils des limites de Robin les plus courants sont les erreurs de signe des conventions de direction de flux incorrectes et l’alias de variable lorsque plusieurs noms de Python font référence au même objet FaceVariable.
  • Pour les limites périodiques dépendant du temps, utilisez des expressions conditionnelles telles que t % 10 plutôt que les fonctions Python. Les fonctions Python ne sont pas réévaluées automatiquement à mesure que la variable de temps de simulation change.

Si vous avez travaillé sur des didacticiels Fipy de base, vous savez déjà que les conditions aux limites sont celles où la théorie rencontre les bords du maillage. Dirichlet, Neumann, Robin et les frontières périodiques peuvent sembler simples en théorie, mais les détails de la mise en œuvre sont importants dans les simulations réelles.

Cet article couvre les modèles FIPY avancés pour les domaines périodiques, les plans de symétrie et les limites de Robin. Celles-ci sont courantes dans les modèles de cellules unitaires, les problèmes axisymétriques, les transferts de chaleur par convection et les simulations d’échange de masse.

Les exemples ci-dessous montrent comment implémenter chaque type de limite correctement, comment choisir entre les approches et comment éviter les défaillances silencieuses qui peuvent perdre des heures de débogage.

Conditions aux limites périodiques : couplage des arêtes

Les limites périodiques collent les côtés opposés du domaine. Une solution laissant un côté réapparaît sur le côté opposé. Ce modèle est courant dans les simulations de cellules unitaires, les éléments de volume représentatifs, la science des matériaux et les modèles de transport simplifiés où le domaine réel se répète.

L’approche simple : Objets PériodiqueGrid

Fipy fournit des objets de grille périodiques intégrés qui gèrent automatiquement le couplage du visage. Pour les domaines 1D, la configuration est simple :

from fipy import PeriodicGrid1D, CellVariable, DiffusionTerm, TransientTerm

nx = 50
dx = 1.0
mesh = PeriodicGrid1D(nx=nx, dx=dx)

C = CellVariable(name="concentration", mesh=mesh, value=0.0)

# No explicit boundary condition needed.
# FiPy handles periodic coupling through the mesh.
eq = TransientTerm() == DiffusionTerm(coeff=1.0)

# Initialize with a non-uniform perturbation.
x = mesh.cellCenters[0]
C.setValue(1.0, where=(x > 0.7) & (x < 0.8))

eq.sweep(var=C)

Pour les domaines 2D, FIPY fournit PeriodicGrid2D et des variantes orientées :

from fipy import PeriodicGrid2D, CellVariable, DiffusionTerm

nx, ny = 50, 50
dx = dy = 1.0

# Periodic on all sides
mesh = PeriodicGrid2D(nx=nx, ny=ny, dx=dx, dy=dy)

# Oriented variants can be used when needed:
# PeriodicGrid2DLeftRight: periodic only in x
# PeriodicGrid2DTopBottom: periodic only in y

Les variantes orientées sont utiles lorsque vous avez besoin de périodicité dans une direction mais dans des conditions aux limites différentes dans l’autre. Par exemple, un problème de transport peut nécessiter des entrées et des sorties périodiques dans une direction et des parois sans flux dans l’autre.

Géométries complexes : maillages périodiques GMSH

Lorsque le domaine n’est pas une simple ligne ou un rectangle, utilisez GMSH pour définir des relations périodiques au niveau du maillage. Les commandes importantes sont Periodic Line et Periodic Surface.

// In a Gmsh .geo file
Periodic Line {1} = {2} + 10;
Periodic Surface {3} = {4};

Importez ensuite le maillage en Python :

from fipy import GmshImporter2D

mesh = GmshImporter2D("mesh.geo")

L’avantage est que le couplage périodique est défini dans le maillage, et non manuellement dans le solveur. Ceci est plus robuste pour les géométries arbitraires car le solveur fonctionne avec un maillage qui contient déjà les relations périodiques.

Couplage facial manuel : lorsque vous avez besoin de contrôle

Pour les cas personnalisés, vous souhaiterez peut-être mapper manuellement des faces et appliquer des contraintes. Cela donne un contrôle total mais nécessite une indexation minutieuse des visages.

from fipy import CellVariable, Grid1D

nx = 50
dx = 1.0
mesh = Grid1D(nx=nx, dx=dx)

C = CellVariable(mesh=mesh, value=0.0)

left_faces = mesh.facesLeft
right_faces = mesh.facesRight

# Manual periodic-style coupling
C.constrain(C.faceValue[mesh.facesLeft.value], where=mesh.facesRight)

Le couplage manuel est plus fragile que l’utilisation de PeriodicGrid. Préférez les maillages périodiques intégrés à moins que vous n’ayez besoin d’un comportement qu’ils ne peuvent pas fournir.

Limites périodiques dépendant du temps

Les limites périodiques dépendant du temps peuvent être délicates. Une erreur courante consiste à définir une fonction Python et à s’attendre à ce que Fipy la réévalue automatiquement :

# Wrong: this evaluates once and then stays fixed
def sw_func(t):
    if t < 5:
        return 0.0
    elif t < 10:
        return 1.0
    else:
        return sw_func(t - 10)

valueRight = sw_func(t)

Le résultat de la fonction est évalué une fois. Lorsque t change, la valeur limite ne se met pas à jour automatiquement.

Utilisez à la place des expressions conditionnelles et des variables compatibles FIPY :

# Correct pattern: expression can re-evaluate as t changes
t_mod = t % 10
valueRight = ((t_mod >= 5) & (t_mod < 10)) * 1.0

C.constrain(valueRight, where=mesh.facesRight)

Le point clé est que les variables FIPY se comportent comme des expressions symboliques. Créez des conditions dépendant du temps avec des expressions compatibles avec FIPY, des masques logiques et des opérations de style tableau plutôt que des instructions Python if.

Lorsque les limites périodiques échouent silencieusement

Une panne silencieuse courante consiste à utiliser une condition initiale uniforme sur un domaine périodique :

C = CellVariable(mesh=mesh, value=1.0)

eq = TransientTerm() == DiffusionTerm(coeff=1.0)
eq.solve(var=C, dt=0.1)

Le résultat ne change jamais car le champ n’a pas de dégradé. Les limites périodiques ne créent pas de gradients par elles-mêmes.

Initialisez toujours des domaines périodiques avec une condition non uniforme, telle qu’une perturbation, une fonction de pas ou une blob gaussienne.

Conditions aux limites symétriques : flux nuls sur les plans de symétrie

Les frontières symétriques exploitent la symétrie afin que vous ne puissiez simuler qu’une partie du domaine. Ceci est courant dans le transfert de chaleur axisymétrique, les modèles cristallographiques et les flux avec des plans de symétrie.

Dans FIPY, les limites symétriques sont implémentées comme des conditions de Neumann à flux nul sur le plan de symétrie.

from fipy import Grid2D, CellVariable, DiffusionTerm, TransientTerm

nx, ny = 50, 25
dx = dy = 0.1

mesh = Grid2D(nx=nx, ny=ny, dx=dx, dy=dy)

T = CellVariable(name="temperature", mesh=mesh, value=100.0)

# Symmetry plane at the top: zero flux
T.faceGrad.constrain(0.0, where=mesh.facesTop)

# Bottom boundary: fixed temperature
T.constrain(100.0, where=mesh.facesBottom)

# Left and right: insulated
T.faceGrad.constrain(0.0, where=mesh.facesLeft)
T.faceGrad.constrain(0.0, where=mesh.facesRight)

eq = TransientTerm() == DiffusionTerm(coeff=1.0)

La signification physique est que la chaleur ou la masse ne traverse pas le plan de symétrie car la moitié omise du domaine reflète la moitié simulée.

Coordonnées cylindriques axisymétriques

Les problèmes axisymétriques nécessitent des soins supplémentaires car la coordonnée radiale change l’opérateur de diffusion. En coordonnées cylindriques, le terme de diffusion radiale comprend un facteur géométrique :

(1/R) ∂(R ∂C/∂R) / ∂R

FIPY peut représenter ce type de comportement, mais la configuration nécessite une construction soignée et une conception de maillage.

from fipy import CellVariable, FaceVariable, DiffusionTerm, TransientTerm

r = mesh.cellCenters[0]

# Example structure for a radial coefficient
axisymmetric_coeff = FaceVariable(mesh=mesh, value=1.0)

eq = TransientTerm() == DiffusionTerm(coeff=axisymmetric_coeff)

L’axe à r = 0 est singulier en raison du facteur 1/r. Évitez de placer les centres de cellules exactement à r = 0. Démarrez le maillage à un petit rayon positif, utilisez soigneusement les coordonnées radiales centrées sur les cellules ou utilisez une conception de maillage qui évite la singularité.

Conditions aux limites de Robin : contraintes de valeur-flux mixtes

Les conditions aux limites de Robin spécifient une combinaison linéaire de la variable et de sa dérivée normale. Ils combinent une contrainte de valeur avec une contrainte de flux.

Un exemple courant est la loi de refroidissement de Newton :

k ∂t/∂n + h(t – t∞) = 0

Ici, le flux de chaleur à la limite est proportionnel à la différence entre la température de surface et la température ambiante.

L’approche implicitrobinsource

ImplicitRobinSource est souvent l’approche la plus propre pour le transfert de chaleur par convection et l’échange de masse.

import fipy as fp

nx = 50
dx = 1.0
mesh = fp.Grid1D(nx=nx, dx=dx)

T = fp.CellVariable(name="temperature", mesh=mesh, value=20.0)

# Physical parameters
k = 1.0
h = 0.5
T_inf = 10.0
T_left = 100.0

# Equation setup
eq = fp.TransientTerm() == fp.DiffusionTerm(coeff=k)

# Left boundary: fixed temperature
bc_left = fp.FixedValue(mesh.facesLeft, T_left)

# Right boundary: convective heat transfer
bc_right = fp.ImplicitRobinSource(
    mesh.facesRight,
    coeff=h,
    value=h * T_inf
)

dt = 0.1
for step in range(100):
    eq.solve(var=T, boundaryConditions=[bc_left, bc_right], dt=dt)

L’approche ImplicitRobinSource ajoute une source implicite ou une contribution de puits à la matrice du solveur. Cela peut être plus stable que la manipulation explicite des limites, en particulier pour les problèmes d’échange de chaleur ou de transfert de masse.

L’approche de divergence de faces variables

Pour des coefficients variant dans l’espace ou des limites multi-physiques couplées, une approche de divergence FaceVariable donne plus de contrôle.

from fipy import CellVariable, FaceVariable, Grid1D
from fipy import DiffusionTerm, ImplicitSourceTerm, TransientTerm

nx = 100
dx = 1.0
mesh = Grid1D(nx=nx, dx=dx)

C = CellVariable(mesh=mesh, value=0.0)

D_coeff = 2.0
h_coeff = 1.0
C_ambient = 0.5

# Step 1: define face coefficient
D_face = FaceVariable(mesh=mesh, value=D_coeff)

# Step 2: zero out coefficient at the boundary as a precaution
D_face[..., mesh.facesLeft.value] = 0.0

# Step 3: formulate Robin-like boundary contribution
robin_flux = (h_coeff * (C_ambient - C)).divergence

eq = (
    TransientTerm()
    == DiffusionTerm(coeff=D_face)
    + robin_flux
    - ImplicitSourceTerm(coeff=0.0)
)

Cette approche nécessite une attention à trois détails :

  1. Mettez à zéro le coefficient de diffusion à la face limite cible.
  2. Formulez le flux de Robin comme source de divergence.
  3. Ajoutez la contribution à l’équation de manière cohérente.

La mise à zéro du coefficient de limite est souvent traitée comme une précaution sûre car elle empêche le comportement par défaut de non-flux d’entrer en conflit avec la contribution personnalisée de Robin.

Pièges de la limite commune de Robin

Signez les erreurs dans le sens du flux

La convention de signe peut basculer selon que le flux est traité comme une source vers l’intérieur ou vers l’extérieur.

# Wrong sign
RobinCoeff = maskSurfaces * D * n / (-dPf.dot(a) + b)

# Corrected sign pattern
RobinCoeff = maskSurfaces * D * n / (dPf.dot(a) + b)

Vérifier les cas limitants :

  • Si h → 0, la limite doit se comporter comme un flux zéro neumann.
  • Si h → ∞, la limite doit se comporter comme un dirichlet à valeur fixe.

alias variable

L’alias des variables se produit lorsque plusieurs noms Python pointent vers le même objet FaceVariable.

# Wrong: all names reference the same object
D = FaceVariable(mesh=mesh, value=0.9)
Gamma = D
b = D

Gamma.setValue(0.0, where=maskSurfaces)

Changer Gamma change également D et b. Cela peut briser silencieusement la condition aux limites.

Utilisez plutôt une expression non mutante :

# Better: create a new masked expression
Gamma = D * ~maskSurfaces

Cela crée une nouvelle expression qui est D éloignée de la limite et zéro sur la limite, sans muter l’objet d’origine.

Problèmes de convergence

Les frontières de Robin peuvent rendre les résolutions instables ou difficiles à converger. Une solution de contournement pratique consiste à introduire la dépendance au temps, même pour un problème qui devrait atteindre un état stable. L’évolution transitoire peut aider le solveur à aborder la solution correcte plus progressivement.

Limites spatialement variables et basées sur les patchs

Les conditions aux limites ne peuvent être appliquées qu’aux régions sélectionnées en utilisant des masques spatiaux. Ceci est utile lorsque différentes parties d’une même limite ont un comportement physique différent.

from fipy import Grid2D, CellVariable, DiffusionTerm

nx, ny = 80, 80
dx = dy = 0.1
mesh = Grid2D(nx=nx, ny=ny, dx=dx, dy=dy)

T = CellVariable(mesh=mesh, value=0.0)

X, Y = mesh.faceCenters

# Left half of the boundary
mask_left = X < 0.5 * nx * dx

# Fixed value on one patch
T.constrain(1.0, where=mesh.facesLeft & mask_left)

# Zero flux on the other patch
T.faceGrad.constrain(0.0, where=mesh.facesLeft & ~mask_left)

Cette approche de limite de patch est importante pour les problèmes de conditions physiques mixtes, telles qu’un mur qui est partiellement chauffé et partiellement isolé.

Ce que nous recommandons : Choisir la bonne approche

Limites périodiques

  1. Utilisez PeriodicGrid pour des domaines 1D, 2D ou 3D structurés simples.
  2. Utilisez des maillages périodiques GMSH pour les géométries complexes, car le couplage au niveau du maillage est plus robuste que les contraintes de face manuelle.
  3. Initialiser avec des conditions non uniformes car les valeurs uniformes ne produisent aucune évolution dans les problèmes de diffusion pure.
  4. Utilisez des expressions conditionnelles telles que t % N pour des limites périodiques dépendant du temps, et non des fonctions Python.

Limites symétriques

  1. Appliquer des conditions Neumann à flux zéro avec faceGrad.constrain(0.0) sur le plan de symétrie.
  2. Pour les problèmes axisymétriques, traitez soigneusement la singularité r = 0 grâce à la conception de maillage.
  3. Vérifiez la symétrie en vérifiant que le gradient de solution est nul au niveau du plan de symétrie.

frontières de robin

  1. Utilisez ImplicitRobinSource pour le transfert de chaleur par convection et l’échange de masse.
  2. Utilisez l’approche de divergence FaceVariable pour des coefficients variant dans l’espace ou des limites multi-physiques couplées.
  3. Les coefficients de zéro sur la face limite par précaution lors de l’utilisation de formulations de flux personnalisés.
  4. Surveillez les erreurs de signe et vérifiez les cas limitants.
  5. Surveillez l’alias variable. Préférez les expressions masquées telles que D * ~mask plutôt que de muter les variables partagées avec setValue().

Comparaison : quand utiliser chaque approche

Type de limite cas d’utilisation Approche FIPY recommandée écueil commun
Périodique, structuré Cellules unitaires, RVE, domaines répétitifs PeriodicGrid1D, PeriodicGrid2D ou PeriodicGrid3D État initial uniforme
Périodique, complexe Géométries arbitraires Commandes GMS Periodic Erreurs d’importation ou de couplage de maillage
Périodique, variable dans le temps Débits pulsés ou conditions cycliques Expression conditionnelle telle que t % N Les fonctions Python ne réévaluent pas
Symétrique Problèmes axisymétriques ou symétrie cristalline faceGrad.constrain(0.0) r = 0 Singularité en coordonnées cylindriques
Robin, convection Transfert de chaleur ou échange de masse ImplicitRobinSource Signez les erreurs dans le sens du flux
Robin, complexe Coefficients variant spatialement ou couplage multi-physique FaceVariable Plus divergence Problèmes d’alias et de convergence variables

Dépannage : défaillances courantes des conditions aux limites

La solution ne change pas

Si un domaine périodique produit la même valeur partout, vérifiez la condition initiale. Une condition initiale uniforme n’a pas de gradient, donc la diffusion pure n’a rien à évoluer.

la valeur limite est erronée

Pour les limites de Robin, vérifiez :

  • Le signe de la direction du flux.
  • Que vous contraigniez les visages plutôt que les cellules.
  • si le coefficient de diffusion a été mis à zéro à la limite dans les formulations personnalisées.

Le solveur diverge

Pour les limites de Robin, essayez :

  • Réduire dt et augmenter la résolution.
  • Ajout d’une évolution transitoire même pour les problèmes destinés à atteindre un état stable.
  • Utiliser les solveurs PETSC au lieu de simples balayages pour les configurations de limites complexes.

La limite ne se met pas à jour

Pour les limites périodiques dépendant du temps, la cause probable est une fonction python utilisée à la place d’une expression FIPY. Utilisez les objets Variable et les masques logiques au lieu des instructions if et elif.

Conclusion

Les conditions aux limites périodiques, symétriques et de Robin sont celles où la théorie de Fipy rencontre les bords du maillage. Les grilles périodiques gèrent automatiquement le couplage du visage. Les plans de symétrie sont des conditions de Neumann à flux zéro. Les frontières de Robin combinent les contraintes de valeur et de flux via ImplicitRobinSource ou une approche de divergence FaceVariable.

L’habitude la plus importante est de vérifier les cas limitants. Pour les limites de Robin, vérifiez que h → 0 donne un comportement sans flux et que h → ∞ donne un comportement à valeur fixe. Pour les domaines périodiques, vérifiez que la condition initiale n’est pas uniforme. Pour les limites symétriques, confirmez que le gradient au niveau du plan de symétrie est nul.

Ces vérifications récupèrent la plupart des erreurs de condition aux limites avant qu’elles ne deviennent de longues sessions de débogage.

Guides connexes

Prochaines étapes

  1. Commencez par PeriodicGrid1D pour un simple domaine périodique 1D.
  2. Ajoutez une dépendance temporelle avec des expressions conditionnelles telles que t % N.
  3. Pour les limites de Robin, commencez par ImplicitRobinSource et vérifiez les cas limitants.
  4. Déplacez-vous vers les maillages GMSH pour des géométries complexes une fois les cas structurés.

Pour obtenir de l’aide sur la mise en œuvre des conditions aux limites dans des modèles de recherche spécifiques, visitez notre page d’accueil pour consulter des ressources et un soutien au développement de Fipy.