Reading Time: 10 minutes

Comida clave

  • Los límites periódicos en FIPY se implementan de manera más limpia con objetos PeriodicGrid o comandos de malla periódica GMSH en lugar de acoplamiento facial manual.
  • Los límites simétricos son las condiciones de Neumann de flujo cero aplicadas a los planos de simetría. No son una categoría FIPY separada, sino un uso físico de patrones de condiciones de contorno estándar.
  • Los límites de Robin combinan las restricciones de valor y flujo. Se pueden implementar con ImplicitRobinSource, ImplicitSourceTerm o un enfoque de divergencia FaceVariable.
  • Las trampas más comunes de los límites de Robin son errores de signo de convenciones de dirección de flujo incorrectas y alias de variables cuando varios nombres de Python hacen referencia al mismo objeto FaceVariable.
  • Para los límites periódicos dependientes del tiempo, use expresiones condicionales como t % 10 en lugar de funciones de Python. Las funciones de Python no se vuelven a evaluar automáticamente a medida que cambia la variable de tiempo de simulación.

Si ha trabajado en tutoriales básicos de Fipy, ya sabe que las condiciones de los límites son donde la teoría cumple con los bordes de la malla. Dirichlet, Neumann, Robin y los límites periódicos pueden parecer simples en teoría, pero los detalles de implementación son importantes en simulaciones reales.

Este artículo cubre patrones avanzados de FIPY para dominios periódicos, planos de simetría y límites de Robin. Estos son comunes en modelos de celdas unitarias, problemas axisimétricos, transferencia de calor convectiva y simulaciones de intercambio de masas.

Los siguientes ejemplos muestran cómo implementar cada tipo de límite correctamente, cómo elegir entre enfoques y cómo evitar fallas silenciosas que pueden desperdiciar horas de depuración.

Condiciones de contorno periódicas: Acoplamiento de los bordes

Límites periódicos Pegue lados opuestos del dominio. Una solución que deja un lado reaparece en el lado opuesto. Este patrón es común en simulaciones de celdas unitarias, elementos de volumen representativos, ciencia de materiales y modelos de transporte simplificado donde se repite el dominio real.

El enfoque simple: objetos PeriodicGrid

Fipy proporciona objetos de cuadrícula periódicas incorporados que manejan automáticamente el acoplamiento de cara. Para los dominios 1D, la configuración es 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)

Para los dominios 2D, Fipy proporciona PeriodicGrid2D y variantes orientadas:

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

Las variantes orientadas son útiles cuando se necesita periodicidad en una dirección pero en diferentes condiciones de contorno en la otra. Por ejemplo, un problema de transporte puede necesitar flujo de entrada y salida periódica en una dirección y paredes de no flujo en la otra.

Geometrías complejas: mallas periódicas GMSH

Cuando el dominio no sea una línea o un rectángulo simple, use GMSH para definir relaciones periódicas en el nivel de malla. Los comandos importantes son Periodic Line y Periodic Surface.

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

Luego importa la malla en Python:

from fipy import GmshImporter2D

mesh = GmshImporter2D("mesh.geo")

La ventaja es que el acoplamiento periódico se define en la malla, no manualmente en el solucionador. Esto es más robusto para las geometrías arbitrarias porque el solucionador funciona con una malla que ya contiene las relaciones periódicas.

Acoplamiento facial manual: cuando necesitas control

Para casos personalizados, es posible que desee asignar caras manualmente y aplicar restricciones. Esto da un control total, pero requiere una cuidadosa indexación facial.

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)

El acoplamiento manual es más frágil que usar PeriodicGrid. Prefiere mallas periódicas integradas a menos que necesite un comportamiento que no puedan proporcionar.

Límites periódicos dependientes del tiempo

Los límites periódicos dependientes del tiempo pueden ser complicados. Un error común es definir una función de Python y esperar que Fipy vuelva a evaluarlo automáticamente:

# 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)

El resultado de la función se evalúa una vez. A medida que cambia t, el valor de límite no se actualiza automáticamente.

Use expresiones condicionales y variables compatibles con FIPY en su lugar:

# 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)

El punto clave es que las variables fipy se comportan como expresiones simbólicas. Cree condiciones dependientes del tiempo con expresiones compatibles con FIPY, máscaras lógicas y operaciones de estilo de arreglo en lugar de sentencias de Python if.

Cuando los límites periódicos fallan en silencio

Una falla silenciosa común es usar una condición inicial uniforme en un dominio periódico:

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

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

El resultado nunca cambia porque el campo no tiene gradiente. Los límites periódicos no crean gradientes por sí mismos.

Siempre inicialice los dominios periódicos con una condición no uniforme, como una perturbación, una función de paso o un blob gaussiano.

Condiciones de contorno simétricas: flujo cero en los planos de simetría

Los límites simétricos explotan la simetría para que pueda simular solo una parte del dominio. Esto es común en la transferencia de calor axisimétrica, modelos cristalográficos y flujos con planos de simetría.

En FIPY, los límites simétricos se implementan como condiciones de Neumann de flujo cero en el plano de simetría.

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)

El significado físico es que el calor o la masa no cruzan el plano de simetría porque la mitad omitida del dominio refleja la mitad simulada.

Coordenadas cilíndricas axisimétricas

Los problemas axisimétricos requieren un cuidado adicional porque la coordenada radial cambia el operador de difusión. En coordenadas cilíndricas, el término de difusión radial incluye un factor geométrico:

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

Fipy puede representar este tipo de comportamiento, pero la configuración requiere una construcción de coeficiente y un diseño de malla cuidadosos.

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)

El eje en r = 0 es singular debido al factor 1/r. Evite colocar los centros de las celdas exactamente en r = 0. Comience la malla en un pequeño radio positivo, use las coordenadas radiales centradas en la celda con cuidado o use un diseño de malla que evite la singularidad.

Condiciones de contorno de Robin: restricciones de flujo de valor mixto

Las condiciones de contorno de Robin especifican una combinación lineal de la variable y su derivada normal. Combinan una restricción de valor con una restricción de flujo.

Un ejemplo común es la ley de enfriamiento de Newton:

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

Aquí, el flujo de calor en el límite es proporcional a la diferencia entre la temperatura de la superficie y la temperatura ambiente.

El enfoque implicitrobinsource

ImplicitRobinSource es a menudo el enfoque más limpio para la transferencia de calor por convección y el intercambio de masas.

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)

El enfoque ImplicitRobinSource agrega una fuente implícita o una contribución de sumidero a la matriz del solucionador. Esto puede ser más estable que el manejo explícito de límites, especialmente para problemas de intercambio de calor o transferencia de masa.

El enfoque de divergencia facevariable

Para coeficientes espacialmente variables o límites multifísicos acoplados, un enfoque de divergencia FaceVariable da más control.

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)
)

Este enfoque requiere atención a tres detalles:

  1. Cero a cero el coeficiente de difusión en la cara del límite objetivo.
  2. Formule el Robin Flux como fuente de divergencia.
  3. Añade la contribución a la ecuación de manera consistente.

La puesta a cero del coeficiente de límite a menudo se trata como una precaución segura porque evita que el comportamiento predeterminado de NO-flux entre en conflicto con la contribución de Robin personalizada.

Trampas comunes de los límites de Robin

Errores de señalización en la dirección de flujo

La convención de signos puede cambiar dependiendo de si el flujo se trata como una fuente interna o un fregadero exterior.

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

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

Verificar casos limitantes:

  • Si h → 0, el límite debe comportarse como Neumann de flujo cero.
  • Si h → ∞, el límite debe comportarse como Dirichlet de valor fijo.

Alisado variable

El alias de variable ocurre cuando varios nombres de Python apuntan al mismo objeto 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)

Cambiando Gamma también cambia D y b. Esto puede romper silenciosamente la condición de contorno.

Use una expresión no mutadora en su lugar:

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

Esto crea una nueva expresión que está D lejos del límite y cero en el límite, sin mutar el objeto original.

Problemas de convergencia

Los límites de Robin pueden hacer que las soluciones de estado estacionario sean inestables o difíciles de converger. Una solución práctica es introducir la dependencia del tiempo incluso para un problema que debería alcanzar el estado estable. La evolución transitoria puede ayudar al solucionador a acercarse a la solución correcta de forma más gradual.

Límites espacialmente variados y basados en parches

Las condiciones de contorno se pueden aplicar solo a regiones seleccionadas mediante máscaras espaciales. Esto es útil cuando diferentes partes del mismo límite tienen un comportamiento físico diferente.

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)

Este enfoque de límites de parche es importante para problemas con condiciones físicas mixtas, como una pared que está parcialmente calentada y parcialmente aislada.

Lo que recomendamos: Elegir el enfoque correcto

Límites periódicos

  1. Use PeriodicGrid para dominios 1D, 2D o 3D estructurados simples.
  2. Utilice mallas periódicas de GMSH para geometrías complejas porque el acoplamiento a nivel de malla es más robusto que las restricciones de cara manuales.
  3. Inicializar con condiciones no uniformes porque los valores uniformes no producen evolución en problemas de difusión pura.
  4. Use expresiones condicionales como t % N para los límites periódicos dependientes del tiempo, no para las funciones de Python.

Límites simétricos

  1. Aplique las condiciones de Neumann de flujo cero con faceGrad.constrain(0.0) en el plano de simetría.
  2. Para problemas axisimétricos, maneje con cuidado la singularidad r = 0 a través del diseño de malla.
  3. Verifique la simetría comprobando que el gradiente de solución es cero en el plano de simetría.

Límites de Robin

  1. Use ImplicitRobinSource para la transferencia de calor por convección y el intercambio de masa.
  2. Utilice el enfoque de divergencia FaceVariable para coeficientes que varían espacialmente o límites multifísicos acoplados.
  3. Coeficientes de cero en la cara del límite como precaución al utilizar formulaciones de flujo personalizados.
  4. Esté atento a los errores de señalización y verifique los casos limitantes.
  5. Esté atento al aliasing variable. Prefiera expresiones enmascaradas como D * ~mask en lugar de mutar variables compartidas con setValue().

Comparación: Cuándo utilizar cada enfoque

Tipo de límite Caso de uso Enfoque fibroso recomendado Trampa común
periódico, estructurado Células unitarias, RVE, dominios repetidos PeriodicGrid1D, PeriodicGrid2D o PeriodicGrid3D Condición inicial uniforme
periódico, complejo Geometrías arbitrarias GMSH Periodic Comandos Errores de importación o emparejamiento de malla
Periódico, variable en el tiempo Flujos pulsantes o condiciones cíclicas Expresión condicional como t % N Las funciones de Python no vuelven a evaluar
Simétrico Problemas axisimétricos o simetría cristalina faceGrad.constrain(0.0) r = 0 Singularidad en coordenadas cilíndricas
Robin, convectivo Transferencia de calor o intercambio de masa ImplicitRobinSource Errores de señalización en dirección de flujo
Robin, complejo Coeficientes espacialmente variables o acoplamiento multifísico FaceVariable más divergencia Problemas variables de aliasing y convergencia

Solución de problemas: fallas comunes en las condiciones de contorno

La solución no cambia

Si un dominio periódico produce el mismo valor en todas partes, verifique la condición inicial. Una condición inicial uniforme no tiene gradiente, por lo que la difusión pura no tiene nada que evolucionar.

El valor de límite es incorrecto

Para los límites de Robin, verifique:

  • El signo de la dirección del flujo.
  • si está restringiendo caras en lugar de células.
  • si el coeficiente de difusión se puso a cero en el límite en las formulaciones personalizadas.

El solucionador diverge

Para los límites de Robin, intente:

  • reduciendo dt y aumentando la resolución.
  • Agregando una evolución transitoria incluso para los problemas destinados a alcanzar el estado estacionario.
  • Usando solucionadores de PETSC en lugar de barridos simples para configuraciones de límites complejas.

El límite no se actualiza

Para los límites periódicos dependientes del tiempo, la causa probable es una función de Python que se usa en lugar de una expresión de Fipy. Utilice las sentencias Variable objetos y máscaras lógicas en lugar de las sentencias if y elif.

Conclusión

Las condiciones de contorno periódicas, simétricas y de Robin son donde la teoría de Fipy se encuentra con los bordes de la malla. Las rejillas periódicas manejan el acoplamiento facial automáticamente. Los planos de simetría son condiciones de flujo cero. Los límites de Robin combinan las restricciones de valor y flujo a través de ImplicitRobinSource o un enfoque de divergencia FaceVariable.

El hábito más importante es verificar los casos limitantes. Para los límites de Robin, verifique que h → 0 proporcione un comportamiento sin flujo y h → ∞ proporcione un comportamiento de valor fijo. Para dominios periódicos, verifique que la condición inicial no sea uniforme. Para los límites simétricos, confirme que el gradiente en el plano de simetría sea cero.

Estas comprobaciones detectan la mayoría de los errores de las condiciones de los límites antes de que se conviertan en largas sesiones de depuración.

Guías relacionadas

Próximos pasos

  1. Comience con PeriodicGrid1D para un dominio periódico 1D simple.
  2. Agregue dependencia del tiempo con expresiones condicionales como t % N.
  3. Para los límites de Robin, comience con ImplicitRobinSource y verifique los casos limitantes.
  4. Mover a las mallas GMSH para geometrías complejas una vez que funcionan los casos estructurados.

Para obtener ayuda para implementar las condiciones de los límites en modelos de investigación específicos, visite nuestra página de inicio para obtener recursos de consultoría y apoyo al desarrollo de FIPY.