FiPy 中随时间演化的平流系数,平流-扩散方程(2D)
Evolutive advection coefficient with time in FiPy, advection - diffusion equation (2D)
我正在尝试开发一个代表从法国到中非的鹳迁徙的模型。我选择了 FiPy。
我想把时间设置成一个完整的迁徙时间:首先,鹳在法国随机扩散,但当时间到达一个极限值时,迁徙开始,出现一个平流系数。
我先尝试了扩散系数,它起作用了:
# Model parameters
D = Variable(value=(0))
ux = 100
uy = -150
q = 0
Lx, Ly = 2500, 2500
Nx, Ny = 100, 100
dx, dy = Lx/Nx, Ly/Ny
Cx, Cy = Lx/4, 3*Ly/4
sigma = Lx/10
T = 10
dt = T/1000
Np = 10 # Number of snapshots of the solution (one every Nt/Np time steps)
Nt = Np*np.ceil(T/(Np*dt)).astype('int') # Nt must be an integer divisible by Np
# Define the grid/mesh
mesh = Grid2D(nx=Nx, ny=Ny, dx=dx, dy=dy)
x, y = mesh.cellCenters[0], mesh.cellCenters[1]
# Define the model variable and set the boundary conditions
phi = CellVariable(name="numerical solution", mesh=mesh, value=numerix.exp(-((x-Cx)**2 + (y-Cy)**2)/(2*sigma**2)))
meshBnd = mesh.facesLeft | mesh.facesRight | mesh.facesBottom | mesh.facesTop
# impose zero flux on all 4 boundaries
phi.faceGrad.constrain(0., where=meshBnd)
# Define and then solve the equation
eq = TransientTerm() == DiffusionTerm(coeff=D) \
- ExponentialConvectionTerm(coeff=(ux,uy)) \
+ ImplicitSourceTerm(coeff=q)
my_sol = np.zeros((Np,Nx*Ny)) # Matrix with Np solution snapshots
my_sol[0,:] = phi
k = 1
for step in np.arange(1,Nt):
if step < Nt/2:
print(step)
D.setValue(0)
else:
D.setValue(5000) # setting D=5000
eq.solve(var=phi, dt=dt)
if np.mod(step,Nt/Np)==0:
print(step,k)
my_sol[k,:] = phi
k += 1
结果如下:
前五张快照:
然后扩散系数变化:
但当我尝试相同的操作时,没有变化,ux uy
系数保持不变。
# In model parameters :
D = Variable(value=(0))
ux = Variable(value=0)
uy = Variable(value=0)
q = 0
# In equation resolution loop :
for step in np.arange(1,Nt):
if step < Nt/2:
print(step)
D.setValue(0)
else:
D.setValue(5000)
ux.setValue(100)
uy.setValue(-150)
eq.solve(var=phi, dt=dt)
if np.mod(step,Nt/Np)==0:
print(step,k)
my_sol[k,:] = phi
k += 1
但是平流没有变化...
感谢您的帮助
这些:
ux = Variable(value=0)
uy = Variable(value=0)
是 FiPy Variable
对象,但是这个
(ux,uy)
不是。 FiPy 无法识别元组并将其转换为 NumPy 数组,因此它会失去与 ux
或 uy
.
的任何更改的连接
这应该有效:
coeff=(ux * FaceVariable(mesh=mesh, value=[1,0])
+ uy * FaceVariable(mesh=mesh, value=[0,1]))
解释:
- 一个
Variable
表示一个任意形状的值,但没有空间关系。
- A
FaceVariable
表示在 Mesh
. 的面上定义的任何级别的字段
- 乘以
FaceVariable(mesh=mesh, value=[1,0])
和 FaceVariable(mesh=mesh, value=[0,1])
将标量值 ux
和 uy
转换为等级 1 字段的 x 和 y 分量。
- 原则上应该可以写成
ux * [1,0] + uy * [0,1]
或者ux * [[1],[0]] + uy * [[0],[1]]
来创建一个vectorVariable
不是字段,但是ExponentialConvectionTerm
不识别该数量的变化;我不确定为什么。
我正在尝试开发一个代表从法国到中非的鹳迁徙的模型。我选择了 FiPy。
我想把时间设置成一个完整的迁徙时间:首先,鹳在法国随机扩散,但当时间到达一个极限值时,迁徙开始,出现一个平流系数。
我先尝试了扩散系数,它起作用了:
# Model parameters
D = Variable(value=(0))
ux = 100
uy = -150
q = 0
Lx, Ly = 2500, 2500
Nx, Ny = 100, 100
dx, dy = Lx/Nx, Ly/Ny
Cx, Cy = Lx/4, 3*Ly/4
sigma = Lx/10
T = 10
dt = T/1000
Np = 10 # Number of snapshots of the solution (one every Nt/Np time steps)
Nt = Np*np.ceil(T/(Np*dt)).astype('int') # Nt must be an integer divisible by Np
# Define the grid/mesh
mesh = Grid2D(nx=Nx, ny=Ny, dx=dx, dy=dy)
x, y = mesh.cellCenters[0], mesh.cellCenters[1]
# Define the model variable and set the boundary conditions
phi = CellVariable(name="numerical solution", mesh=mesh, value=numerix.exp(-((x-Cx)**2 + (y-Cy)**2)/(2*sigma**2)))
meshBnd = mesh.facesLeft | mesh.facesRight | mesh.facesBottom | mesh.facesTop
# impose zero flux on all 4 boundaries
phi.faceGrad.constrain(0., where=meshBnd)
# Define and then solve the equation
eq = TransientTerm() == DiffusionTerm(coeff=D) \
- ExponentialConvectionTerm(coeff=(ux,uy)) \
+ ImplicitSourceTerm(coeff=q)
my_sol = np.zeros((Np,Nx*Ny)) # Matrix with Np solution snapshots
my_sol[0,:] = phi
k = 1
for step in np.arange(1,Nt):
if step < Nt/2:
print(step)
D.setValue(0)
else:
D.setValue(5000) # setting D=5000
eq.solve(var=phi, dt=dt)
if np.mod(step,Nt/Np)==0:
print(step,k)
my_sol[k,:] = phi
k += 1
结果如下:
前五张快照:
然后扩散系数变化:
但当我尝试相同的操作时,没有变化,ux uy
系数保持不变。
# In model parameters :
D = Variable(value=(0))
ux = Variable(value=0)
uy = Variable(value=0)
q = 0
# In equation resolution loop :
for step in np.arange(1,Nt):
if step < Nt/2:
print(step)
D.setValue(0)
else:
D.setValue(5000)
ux.setValue(100)
uy.setValue(-150)
eq.solve(var=phi, dt=dt)
if np.mod(step,Nt/Np)==0:
print(step,k)
my_sol[k,:] = phi
k += 1
但是平流没有变化...
感谢您的帮助
这些:
ux = Variable(value=0)
uy = Variable(value=0)
是 FiPy Variable
对象,但是这个
(ux,uy)
不是。 FiPy 无法识别元组并将其转换为 NumPy 数组,因此它会失去与 ux
或 uy
.
这应该有效:
coeff=(ux * FaceVariable(mesh=mesh, value=[1,0])
+ uy * FaceVariable(mesh=mesh, value=[0,1]))
解释:
- 一个
Variable
表示一个任意形状的值,但没有空间关系。 - A
FaceVariable
表示在Mesh
. 的面上定义的任何级别的字段
- 乘以
FaceVariable(mesh=mesh, value=[1,0])
和FaceVariable(mesh=mesh, value=[0,1])
将标量值ux
和uy
转换为等级 1 字段的 x 和 y 分量。 - 原则上应该可以写成
ux * [1,0] + uy * [0,1]
或者ux * [[1],[0]] + uy * [[0],[1]]
来创建一个vectorVariable
不是字段,但是ExponentialConvectionTerm
不识别该数量的变化;我不确定为什么。