Вероятно, неплохо сгладить дельта-функцию Дирака, как это делается с помощью методов диффузионного интерфейса (см. Уравнения 11, 12 и 13 здесь ).Таким образом, это один из вариантов
def delta_func(x, epsilon):
return ((x < epsilon) & (x > -epsilon)) * \
(1 + numerix.cos(numerix.pi * x / epsilon)) / 2 / epsilon
2 * epsilon
- это ширина дельта-функции Дирака, и он выбирается равным нескольким интервалам сетки.Вы также можете просто использовать 1 / dx
и выбрать ближайшую точку сетки к местоположению дельта-функции Дирака.Тем не менее, я думаю, что это становится более зависимым от сетки.Вот рабочий код в 1D.
from fipy import *
nx = 50
dx = dy = 0.025 # grid spacing
L = dx * nx
mesh = Grid1D(dx=dx, nx=nx)
phi = CellVariable(name="solution variable", mesh=mesh, value=0.)
Gamma=1
def delta_func(x, epsilon):
return ((x < epsilon) & (x > -epsilon)) * \
(1 + numerix.cos(numerix.pi * x / epsilon)) / 2 / epsilon
x0 = L / 2.
eqG = TransientTerm() == DiffusionTerm(coeff=Gamma)+ delta_func(mesh.x - x0, 2 * dx)
valueTopLeft = 0
valueBottomRight = 1
timeStepDuration = 10 * 0.9 * dx ** 2 / (2 * 0.8)
steps = 100
viewer = Viewer(phi)
for step in range(steps):
res = eqG.solve(var=phi, dt=timeStepDuration)
print(step)
viewer.plot()
input('stopped')
Здесь epsilon = 2 * dx
, произвольный выбор, а дельта-функция сосредоточена вокруг L / 2
.2D просто нужно умножить функции.