【问题标题】:Non-Steady Diffusion-Advection equation with time dependent Dirichlet boundary condition具有时间相关 Dirichlet 边界条件的非稳态扩散-平流方程
【发布时间】:2019-10-07 19:12:15
【问题描述】:

我想设置 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 秒的周期。有没有更好的方法来实现这一点?或者我怎样才能加快系统速度?

【问题讨论】:

  • 3.5s 不算多。您的实际问题是想要更精细的网格、2D/3D 模拟还是需要优化的其他东西?
  • 好吧,我需要在优化例程中运行这段代码,这需要很长时间
  • 那是XY problem 的味道。请给我们完整的问题(“在脚本 Y 中运行子例程 X 需要永远”-> 也提供 Y)而不是您认为合适的解决方案(“子例程 X 太慢”)。
  • 不幸的是它不是。您知道是否有更好的方法以更依赖时间的方式使用 fipy?

标签: python fipy


【解决方案1】:

您不想继续重新限制n_model。约束不会被替换;他们都被相继申请。相反,做我们在examples.diffusion.mesh1D 中演示的事情。将t 声明为Variable,根据Variable 约束n_model,并在每个时间步更新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()

【讨论】:

  • 如果用户想在某些时间步将边界的类型更改为通量,例如当 t>1?
  • @IgorMarkelov:您可以release 初始约束并应用新约束
猜你喜欢
  • 1970-01-01
  • 2019-02-12
  • 2020-08-21
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
  • 2022-11-14
  • 1970-01-01
  • 2019-03-11
相关资源
最近更新 更多