如何偏移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
相关产品推荐
相关产品推荐

