我正在做一个模拟气体硬球模型的项目。(类似于理想气体模型)
我写了我的整个项目,而且它正在起作用。为了让您了解我所做的事情,有一个循环执行以下操作:(伪代码)
Get_Next_Collision(); // Figure out when the next collision will occur
Step_Time_Forwards(); // Step to time of collision
Process_Collision(); // Process collision between 2 particles
(Repeat)对于大量粒子(例如N粒子),必须进行O(N*N)检查,以确定下一次碰撞何时发生。遵循上述程序显然效率低下,因为在绝大多数情况下,粒子对之间的碰撞不受其他地方碰撞处理的影响。因此,希望有某种形式的优先级队列来存储每个粒子的下一个事件。(实际上,由于一次碰撞涉及两个粒子,所以只有一半的事件会被储存起来,因为如果A和B碰撞,那么B也会与A同时碰撞。)
我发现很难编写这样的事件/冲突优先级队列。
我想知道是否有任何分子动力学模拟器已经编写,我可以去看看源代码,以了解我如何实现这样一个优先级队列。
做了谷歌搜索后,我很清楚有很多MD程序已经被编写出来了,但是它们中的许多要么过于复杂,要么不合适。
这可能是因为它们具有巨大的功能,包括产生可视化的能力,或者计算具有相互作用力的粒子的模拟的能力等等。
有些模拟器是不适合的,因为它们为不同的模型做了计算,例如,除了能量守恒的东西,硬球模型和弹性碰撞。例如,粒子与势或非球形粒子相互作用。
我试过查看LAMMPS的源代码,但是它很大,我很难理解它。
我希望这是关于我想做的事情的足够的信息。如果没有,我可能会添加一些更多的信息。
发布于 2015-02-28 16:18:46
我不明白“优先级队列”方法是如何工作的,但我有一种可能会帮助您的替代方法。这就是我认为博伊科·佩尔法诺夫()的意思是“利用地方”。
您可以将粒子排序为“桶”,这样您就不需要检查每个粒子之间的相互关系(O(n平方) )。这利用了这样一个事实,即粒子只有在它们已经非常接近的情况下才能碰撞。创建表示小区域/体积的桶,并填充当前在桶的区域/卷中的所有粒子( O(n)最坏的情况)。然后检查桶内的所有粒子与桶中的其他粒子(O(m*(n/m )平方)平均值,m=桶数)。桶必须是重叠的,这样才能工作,否则你也可以检查来自相邻桶的粒子。
更新:如果粒子可以比桶长的距离移动,一个明显的“解决方案”是减少时间步幅。但是,这将再次增加算法的运行时间,并且只有在有最大速度的情况下才能工作。
另一个适用的解决方案,即使没有最大的速度,将是创建一个额外的‘高速’桶。由于速度分布通常是高斯曲线,因此不需要将许多粒子放入桶中,因此“桶法”仍将比O(n平方)更有效。
发布于 2015-02-28 16:50:43
本地感知系统的基本版本如下所示:
timestep=(griddim/2) / max_speed。这个假设认为,最多有四个相邻网格立方体的粒子在理论上可以在这段时间内相互作用。mini_timestep < timestep,其中每个粒子被检查是否可能与其可观测宇宙中的其他粒子发生碰撞)。将冲突存储到按时间排序的任何结构中,甚至只是按冲突时间排序的数组。timestep通过为止。按每个网格正方形更新粒子的所有权。该系统的优点是,对于每个时间窗口,我们都有(假设粒子的均匀分布) O(universe_particles * grid_size)而不是O(universe_particles * universe_size)的碰撞检查。在良好的条件下(取决于宇宙大小、速度和粒子密度),你可以将计算效率提高数量级。
https://stackoverflow.com/questions/28783601
复制相似问题