Нестационарное уравнение диффузии-адвекции с зависящим от времени граничным условием Дирихле - PullRequest
1 голос
/ 21 мая 2019

Я хотел бы настроить fipy для решения одномерного уравнения диффузии-адвекции с синусоидальной границей.

Я получил следующий код:

from fipy import *
import numpy as np 
import matplotlib.pylab as plt

def boundary(t):
    return 1 + 0.1 * np.sin(6*np.pi*t)

nx = 50
dx = 1./nx
mesh = Grid1D(nx=nx, dx=dx)
n_model = CellVariable(name="density",mesh=mesh,value=1., hasOld=True)
D_model = CellVariable(name="D",mesh=mesh,value=mesh.x[::-1]*5.+3)
v_model = FaceVariable(name="v",mesh=mesh,value=1. )
v_model = (-1*mesh.x) * [[1.]]
n_model.constrain(boundary(0.), mesh.facesRight)
equation = (TransientTerm(var=n_model) == DiffusionTerm(coeff=D_model,var=n_model) \
                + ExponentialConvectionTerm(coeff=v_model,var=n_model))
timeStepDuration = 0.9 * dx**2 / (2 * 1)  * 1e2
time_length = 2
steps = np.int(time_length/timeStepDuration)
t = 0
n_out = np.zeros((steps,nx))
import time
t1 = time.time()
for step in xrange(steps):
    t += timeStepDuration
    n_model.updateOld()
    n_out[step] = n_model.globalValue
    n_model.constrain(boundary(t), mesh.facesRight)
    equation.solve(dt=timeStepDuration)
print "Execution time: %.3f"%(time.time()-t1)

plt.figure()
plt.imshow(n_out.T)
plt.colorbar()
plt.show()

Код работает нормально иЯ получаю разумные результаты.Однако это также довольно медленно, примерно 3,5 с для цикла.Есть ли лучший способ реализовать это?Или как я могу ускорить систему?

1 Ответ

2 голосов
/ 21 мая 2019

Вы не хотите продолжать ограничивать n_model.Ограничения не заменяются;все они применяются последовательно.Вместо этого делайте то, что мы демонстрируем в examples.diffusion.mesh1D.Объявите t как Variable, ограничьте n_model в терминах этого Variable и обновите значение t на каждом временном шаге.Для меня это примерно в 4 раза быстрее.

from fipy import *
import numpy as np 
import matplotlib.pylab as plt

def boundary(t):
    return 1 + 0.1 * np.sin(6*np.pi*t)

nx = 50
dx = 1./nx
mesh = Grid1D(nx=nx, dx=dx)
n_model = CellVariable(name="density",mesh=mesh,value=1., hasOld=True)
D_model = CellVariable(name="D",mesh=mesh,value=mesh.x[::-1]*5.+3)
v_model = FaceVariable(name="v",mesh=mesh,value=1. )
v_model = (-1*mesh.x) * [[1.]]
t = Variable(value=0.)
n_model.constrain(boundary(t), mesh.facesRight)
equation = (TransientTerm(var=n_model) == DiffusionTerm(coeff=D_model,var=n_model) \
                + ExponentialConvectionTerm(coeff=v_model,var=n_model))
timeStepDuration = 0.9 * dx**2 / (2 * 1)  * 1e2
time_length = 2
steps = np.int(time_length/timeStepDuration)
n_out = np.zeros((steps,nx))
import time
t1 = time.time()
for step in xrange(steps):
    t.setValue(t() + timeStepDuration)
    n_model.updateOld()
    n_out[step] = n_model.globalValue
    equation.solve(dt=timeStepDuration)
print "Execution time: %.3f"%(time.time()-t1)

plt.figure()
plt.imshow(n_out.T)
plt.colorbar()
plt.show()
...