根据Erwin Schrodinger(在生命中是什么?),扩散可以完全由粒子的随机运动来解释。我想通过创建一个程序来自己测试,创建一个时间步骤可视化“气体分子”在密闭容器中的扩散。初始条件将有两个分区,一个低,一个高浓度。在t0之后,移除分区并允许气体扩散。我想要使用的唯一机制是向每个分子添加置换随机载体。初始条件看起来像这样。
我不知道的问题的一部分是当分子撞击边界表面时如何创建简单的台球类型反射。我假设简单的对称反射(角度=边界处的角度)。我根本没有启动代码,因为我不知道如何处理这部分,而我知道如何处理剩下的部分。我知道这更像是一个数学问题,但我如何在python中创建这些边界条件?理想情况下,我希望自己编写此功能以便我能够理解它,而不是使用可以执行此操作的预构建包。这是我正在寻找的任何给定分子。
最终,我真正需要的是:给定初始位置(x1,y2),矢量幅度v,角度θ,以及盒子大小和位置,分子的最终静止位置是什么(x2,y2)。
您不需要计算反射角度,只需将问题分解为两个:一个用于x
,另一个用于y
。在这两种情况下,当粒子超出边界时,你需要粒子“返回”。
我这次做了一个关于研究流体中颗粒密度的练习。最简单的方法是在两个方向上考虑(0,1)边界。下面的代码应该这样做(提示:正确使用abs
将创建相当于反射):
x0 = [.1, .9]
delta = [-0.2, 0.3]
x1 = [(1-abs(abs(xi + di)-1)) for xi, di in zip(x0, delta)]
print(x1)
# 0.1, 0.8
#or using numpy:
x1 = 1-np.abs(np.abs(np.asarray(x0) + np.asarray(delta))-1)
print(x1)
>> [0.09999999999999998, 0.8]
array([0.1, 0.8])
我从你的问题中假设你忽略了粒子 - 粒子碰撞和粒子 - 粒子“非叠加”
这是一个简单的实现。我每隔十步就改变一次运动矢量,这样就可以直观地检查边界反射。更新运动矢量时,粒子会闪烁红色。
ħere描述的技巧是“展开”边界框。相反,我们让粒子不受约束地移动,然后将空间折叠到边界框中。
import numpy as np
import pylab
from matplotlib.animation import FuncAnimation
xy = np.random.uniform(-1, 1, (2, 200))
xy[0, :160] = np.abs(xy[0, :160])
xy[0, 160:] = -np.abs(xy[0, 160:])
xy += 1
f, a = pylab.subplots()
pxy, = pylab.plot(*xy, 'o')
def init():
a.set_xlim(0, 2)
a.set_ylim(0, 2)
return pxy,
def update(frame):
global inc, xy
if frame % 1 < 0.01:
inc = np.random.normal(0, 0.01, xy.shape)
pxy.set_markerfacecolor('red')
elif frame % 1 < 0.11:
pxy.set_markerfacecolor('blue')
xy += inc
fxy = np.abs((xy+2)%4-2)
pxy.set_data(*fxy)
return pxy,
anim = FuncAnimation(f, update, frames=np.arange(1200) / 10,
init_func=init, blit=True)
pylab.show()
所以要记住几件事:
对于一个粒子,您不必以t_0的增量进行参数化,您可以计算截距并基本上将其放大。对于多个,您将不得不计算分子间扩散和碰撞力...这是一个更难以参数化完成的问题。
你必须计算碰撞,即当两个分子的中心彼此相距2 *半时,然后进行conserves momentum的碰撞。