Это можно решить как полностью неявную систему. Приведенный ниже код упрощает задачу, чтобы получить единый размер домена и коэффициент диффузии. k
установлено на 0,2. Он довольно хорошо передает аналитическое решение с некоторыми оговорками (см. Ниже).
from fipy import (
CellVariable,
TransientTerm,
DiffusionTerm,
ImplicitSourceTerm,
Grid1D,
Viewer,
)
L = 1.0
nx = 1000
dx = L / nx
konstant = 0.2
coeff = 1.0
mesh = Grid1D(nx=nx, dx=dx)
var_a = CellVariable(mesh=mesh, value=1.0, hasOld=True)
var_b = CellVariable(mesh=mesh, value=0.0, hasOld=True)
var_a.constrain(1.0, mesh.facesRight)
var_b.constrain(0.0, mesh.facesRight)
coeff_mask = ~mesh.facesLeft * coeff
boundary_coeff = konstant * (mesh.facesLeft * mesh.faceNormals).divergence
eqn_a = TransientTerm(var=var_a) == DiffusionTerm(
coeff_mask, var=var_a
) - ImplicitSourceTerm(boundary_coeff, var=var_a) + ImplicitSourceTerm(
boundary_coeff, var=var_b
)
eqn_b = TransientTerm(var=var_b) == DiffusionTerm(
coeff_mask, var=var_b
) - ImplicitSourceTerm(boundary_coeff, var=var_b) + ImplicitSourceTerm(
boundary_coeff, var=var_a
)
eqn = eqn_a & eqn_b
for _ in range(5):
var_a.updateOld()
var_b.updateOld()
eqn.sweep(dt=1e10)
Viewer((var_a, var_b)).plot()
print("var_a[0] (expected):", (1 + konstant) / (1 + 2 * konstant))
print("var_b[0] (expected):", konstant / (1 + 2 * konstant))
print("var_a[0] (actual):", var_a[0])
print("var_b[0] (actual):", var_b[0])
input("wait")
Обратите внимание на следующее:
Как написано, граничное условие имеет точность только первого порядка , что на самом деле не имеет значения для этой проблемы, но может повредить вам в более высоких измерениях. Могут быть способы исправить это, например, наличие небольшой ячейки рядом с границей или добавление явной поправки второго порядка для граничного условия.
Здесь объединены уравнения. В случае разъединения для достижения равновесия, вероятно, потребуется множество итераций.
Для достижения равновесия потребовалось несколько итераций, но этого не должно быть. Вероятно, это связано с тем, что решатель не сходится должным образом без нескольких попыток. Возможно, у связанных уравнений плохая обусловленность.