You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何偏移Fipy网格?无需修改方程实现网格平移

平移FiPy网格起始点(无需修改PDE方程)

要让FiPy的1D网格起始点不为0,无需修改PDE方程中的x变量引用,直接在创建Grid1D时指定origin参数即可,网格的单元中心、面位置会自动使用偏移后的坐标,完全适配你依赖x变量的对流项需求。

修改后的完整代码

from fipy import Viewer, PowerLawConvectionTerm, ConvectionTerm, Variable, FaceVariable, CellVariable, Grid1D, ExplicitDiffusionTerm, TransientTerm, DiffusionTerm
from fipy.tools import numerix
import numpy as np

nx = 150
Lx = 15
dx = Lx / nx

# 关键修改:设置网格起始原点(示例设为5,网格范围5~20)
mesh = Grid1D(nx=nx, dx=dx, origin=5.0)

phi = CellVariable(name="solution variable",
                   mesh=mesh,
                   value=0.)

s = 0.5
D = s**2 / 2

timeStepDuration = 0.9 * dx**2 / (2 * D)
steps = 300
x = mesh.cellCenters[0]
t = timeStepDuration * steps

xc = mesh.cellCenters
s0 = s / 3

# 原代码中la未定义,此处假设为初始中心5,可按需调整
la = 5.0
cl = 0.2
tv = Variable(value=0)

# 初始高斯分布
def Radb(x, t, a=1, l=0, s=0.1):
    std = np.sqrt(s**2 / (2 * np.abs(a + l * t)))
    r1 = (x - 8)**2
    r2 = 2 * std**2
    return np.exp(-r1 / r2) / np.sqrt(std**2 * 2 * np.pi)  

phi.setValue(Radb(x.value, 0, a=1, l=0, s=s0))
print('check initial integral:', np.trapz(phi.value, x.value))

Pt = np.zeros((nx, steps))

for step in range(steps - 1):
    tv.setValue(step * timeStepDuration)
    # 对流项直接使用偏移后的cell中心坐标,无需手动调整
    Fc = -1 * (xc - (la + cl * tv))

    eqX = TransientTerm() == ExplicitDiffusionTerm(coeff=D) - ConvectionTerm(CellVariable(mesh=mesh, value=[Fc]))
    eqI = TransientTerm() == DiffusionTerm(coeff=D) - ConvectionTerm(CellVariable(mesh=mesh, value=[Fc]))
    eqCN = eqX + eqI

    eqCN.solve(var=phi, dt=timeStepDuration)
    Pt[:, step] = phi.value 
eqI.solve(var=phi, dt=timeStepDuration)
Pt[:, -1] = phi.value 

if __name__ == '__main__':
     viewer = Viewer(vars=(phi),
                     datamin=0., datamax=1.)
     viewer.plot()

# 验证守恒性
import matplotlib.pyplot as plt
tp = np.linspace(0, t, steps)
mass = [np.trapz(Pt[:, i], x.value) for i in range(steps)]
fig, ax = plt.subplots()
ax.plot(tp, mass, label='Total probability')
ax.axhline(y=1, ls='dashed', color='grey', label='1')
ax.axhline(y=0.9999999, ls='dotted', color='red', label='0.9999999')
plt.legend()

# 演化动画
from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots()
line, = ax.plot(x, Pt[:, 0], color='C0')
def update(i):
    line.set_ydata(Pt[:, i])
    return (line,)
anim = FuncAnimation(fig, update, frames=range(steps-1), interval=40)

关键说明

  • 网格偏移实现:Grid1D的origin参数直接定义网格的起始坐标,示例中设为5.0,网格覆盖范围为[5, 5+Lx]即[5,20],所有网格相关的坐标(cellCenters、faceCenters等)都会自动使用这个偏移后的数值。
  • 无需修改PDE:方程中的对流项直接使用xc = mesh.cellCenters即可,因为xc已经是偏移后的实际x坐标,完全适配后续非线性对流项需求。
  • 初始条件适配:初始高斯分布中的x-8无需调整,因为x现在是偏移后的真实坐标,直接对应物理空间中的位置。

内容的提问来源于stack exchange,提问作者alxg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 01:15:25