我正在研究一个模拟气体硬球模型的项目。 (与理想气体模型类似。)
我已经编写了我的整个项目,并且它正在运行。为了让您了解我所做的事情,有一个循环可以执行以下操作:(伪代码)
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)检查以确定何时发生下一次碰撞。遵循上述过程显然是低效的,因为在绝大多数情况下,粒子对之间的碰撞不受其他地方碰撞处理的影响。因此,希望具有某种形式的优先级队列,其存储每个粒子的下一个事件。 (实际上,由于碰撞涉及2个粒子,因此只会存储一半数量的事件,因为如果A与B发生碰撞,那么B也会与A碰撞,并且在同一时间碰撞。)
我发现很难编写这样的事件/冲突优先级队列。
我想知道是否有任何已编写的分子动力学模拟器,我可以查看源代码,以了解如何实现这样的优先级队列。
完成谷歌搜索之后,我很清楚已经编写了许多MD程序,但其中许多程序要么太复杂要么不合适。
这可能是因为它们具有巨大的功能,包括产生可视化的能力或计算粒子的模拟能力,这些粒子在它们之间具有相互作用力等等。
某些模拟器不适用,因为它们针对不同的模型进行计算,即:除了能量守恒之外的其他模型,具有弹性碰撞的硬球模型。例如,粒子与电位或非球形粒子相互作用。
我曾尝试查看LAMMPS的源代码,但它很庞大,我很难理解它。
我希望这是关于我想要做的事情的足够信息。如果没有,我可以添加更多信息。
答案 0 :(得分:0)
我不明白'优先级队列'方法是如何工作的,但我有另一种方法可以帮助你。我认为@Boyko Perfanov的意思是“利用地方性”。
您可以将粒子分类为“桶”,这样您就不必相互检查每个粒子(O(n²))。这使用了粒子只有在彼此非常接近时才会发生碰撞的事实。创建表示小面积/体积的桶,并填充当前在桶的区域/体积中的所有粒子(O(n)最坏情况)。然后检查铲斗内的所有颗粒与铲斗中的其他颗粒(O(m *(n / m)²)平均情况,m =铲斗数量)。存储桶需要重叠才能正常工作,否则您也可以检查相邻存储桶中的粒子。
更新:如果粒子可以行进的距离比铲斗大小更长,那么明显的“解决方案”就是减少时间步长。但是,这会再次增加算法的运行时间,并且仅在存在最大速度时才有效。
即使没有最高速度,另一种解决方案是创建一个额外的“高速”铲斗。由于速度分布通常是高斯曲线,因此不必将很多粒子放入该桶中,因此“桶法”仍然比O(n²)更有效。
答案 1 :(得分:0)
地点感知系统的基本版本可能如下所示:
timestep=(griddim/2) / max_speed
。这假设最多四个相邻的网格立方体中的粒子理论上可以在该时间段内相互作用。mini_timestep < timestep
,其中检查每个粒子是否与其可观察宇宙中的其他粒子发生碰撞。碰撞到按时间排序的任何结构,甚至只是一个数组,按碰撞时间排序。timestep
。按每个网格方块更新粒子的所有权。这个系统的优点是,对于每个时间窗口,我们(假设粒子的均匀分布)O(universe_particles * grid_size)而不是O(universe_particles * universe_size)检查碰撞。在良好的条件下(取决于宇宙大小,粒子的速度和密度),您可以将计算效率提高几个数量级。