简体   繁体   English

使用scipy.integrate将布朗运动纳入粒子轨迹积分

[英]Including Brownian Motion into Particle Trajectory Integration using scipy.integrate

I want to add thermal fluctuations on top of a simple linear particle interaction model. 我想在简单的线性粒子交互模型之上添加热波动。 So far (without Brownian motion) everything was done using scipy.integrate.odeint and worked perfectly. 到目前为止(没有布朗运动)一切都是使用scipy.integrate.odeint完成并且工作得很好。 Therefore it would be nice to find a way to include random motion by using one of the scipy.integrate metods. 因此,通过使用scipy.integrate metods之一找到一种包含随机运动的方法会很好。 The problem is the following: Using a Langevin heat bath i would have to update the particle positions(x) and velocities(v) as follows: 问题如下:使用Langevin热浴我必须更新粒子位置(x)和速度(v),如下所示:

x = x + v * dt x = x + v * dt

v = v + (interaction_force * dt + random_force * dt) /mass v = v +(interaction_force * dt + random_force * dt)/ mass

where: random_force = sqrt(constant/ dt )*random_number 其中:random_force = sqrt(constant / dt )* random_number

I think there are two problems: 我认为有两个问题:

  1. The steps size dt comes up inside the random_force. 步骤大小dt出现在random_force中。 But i don't know the current step size which changes during the run by adaptive step size control. 但我不知道在运行期间通过自适应步长控制改变的当前步长。

  2. The step size control will get into trouble since as long as two different random_numbers are used for the comparison of the different step sizes there will be relative big difference. 步长控制将遇到麻烦,因为只要使用两个不同的random_number来比较不同的步长,就会有相对大的差异。 (I'm not sure if there are two different random_numbers used) (我不确定是否使用了两个不同的random_numbers)

The only idea i have is to use a method with fixed step size. 我唯一的想法是使用固定步长的方法。 But i haven't found any jet. 但我没有发现任何喷气式飞机。 Any better ides how to solve this problem? 任何更好的想法如何解决这个问题?

If you have access to the absolute time inside the model, you can use a pseudo-random number generator that generates a unique random number for a given time. 如果您可以访问模型内​​的绝对时间,则可以使用伪随机数生成器,该生成器在给定时间内生成唯一的随机数。

Such a time-dependent pseudo-random number generator can operate independent of the step size and generates the same value whenever a time-point is visited repeatedly. 这种与时间相关的伪随机数发生器可以独立于步长操作,并且每当重复访问时间点时产生相同的值。

If you do not have access to the absolute time, you may be able to simply integrate 1*dt to get the time. 如果您无法访问绝对时间,您可以简单地集成1 * dt来获取时间。

Here is a very crude implementation of such a time-dependent random number generator: 这是一个非常粗略的实现这种时间相关的随机数发生器:

import numpy as np
import matplotlib.pyplot as plt    
import struct

# create a gaussian "random number" that is deterministic in the time parameter
def t_rand(time):
    tmp = struct.pack('f', time)
    int_time = struct.unpack('i', tmp)
    np.random.seed(int_time)
    return np.random.randn()

# demonstrate the behavior of t_rand

t1 = np.linspace(0, 1, 21)
t2 = np.linspace(0, 1, 41)

plt.subplot(2, 1, 1)
plt.plot(t1, [t_rand(t) for t in t1])
plt.plot(t2, [t_rand(t) for t in t2])

plt.subplot(2, 1, 2)
plt.hist([t_rand(t) for t in np.linspace(0, 10, 10000)], 30)

It may not be wise to manipulate the global random seed for this purpose, but if the problem is isolated enough it will work. 为此目的操纵全局随机种子可能并不明智,但如果问题足够孤立,它将起作用。

在此输入图像描述

The image above shows that for two sequences with different time steps the same value is generated for the same time point. 上图显示对于具有不同时间步长的两个序列,对于相同的时间点生成相同的值。 The figure below shows the histogram of the random values, which indicates that at least the shape of the distribution seems untouched by this crude manipulation of the random seed. 下图显示了随机值的直方图,表明至少分布的形状似乎未被随机种子的粗略操作所触及。

I don't know if my approach actually works inside an integrator. 我不知道我的方法是否真的适用于集成商。 Problem 2 may still be an issue, but I think problem 1 is adequately addressed. 问题2可能仍然是一个问题,但我认为问题1得到了充分解决。 This may not solve the problem entirely, but it may get you started. 这可能无法完全解决问题,但它可能会让你开始。 A more professional solution could be to use a stochastich differential equation solver, such as PyS³DE . 更专业的解决方案可以是使用随机差分方程求解器,例如PyS³DE

The kind of methods used in something like odeint are not appropriate for SDEs. odeint这样的方法不适合odeint Resizable timestep methods don't really work with Brownian motion because the solution doesn't converge to something smooth as the timestep gets smaller. 可调整大小的时间步长方法实际上不适用于布朗运动,因为随着时间步长变小,解决方案不会收敛到平滑的东西。

You're better off just using the Euler Maruyama method . 你最好只使用Euler Maruyama方法 This method is sufficiently simple that you can write the integration routine yourself. 此方法非常简单,您可以自己编写集成例程。

There are more advanced methods: the next most well-known is the Milstein method which can be more accurate for multiplicative SDEs but is equivalent for additive SDEs (such as yours). 还有更先进的方法:下一个最着名的方法是Milstein方法,它对于乘法SDE可以更准确,但对于加性SDE(例如你的)是等效的。 In general the gain from using more complex methods is not as big for SDEs as for ODEs so I would say just use EM. 一般来说,使用更复杂方法的收益对于SDE而言并不像对于ODE那么大,所以我会说只使用EM。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM