在MD中建立邻居列表的有效方法

计算科学 算法 模拟 分子动力学 最近邻
2021-12-13 08:46:22

我正在尝试在我的 MD 代码中实现以下形式的单元格/邻居列表方法。我已将我的模拟框划分为固定数量的单元格,并根据其位置,将每个原子正确分配到相应的单元格中。我为每个单独的单元格构建邻居列表i. 在进行计算时,我只考虑相邻单元格内的原子;此外,在这个子集上,我执行 Verlet 搜索,我只考虑半径内的原子rcutoff原子的k. 这个更小的原子子集将相互作用。我想实现的算法在这篇论文中找到,算法 C 1。算法 1 是它的伪代码。

我的问题是关于邻居列表的建立。上图是以 3 层表示的模拟框(将它们相互叠加以形成 3D 框)。

  1. 我知道我们不应该考虑所有相邻的单元格,因为这会导致重复计算相互作用。只考虑我绘制的 L 形单元格是否正确?在图中,我们正在考虑单元格 14 中的原子,并对它的邻居感兴趣。
  2. 目前,如果我使用 A LOTif/else语句来正确获取所有边界条件,我可以制作邻居列表。我一直在考虑通过检测模式来更有效/更简洁的算法,但我想不出任何东西。有没有比做一堆if语句更有效的算法?也许也可以自动考虑周期性边界条件?

本质上,我在问如何建立邻居列表。对于这部分,我希望有类似的东西,单元格的数量int neighbors[N_c][26]在哪里,每个单元格有多少个邻居N_c26i已。数据类型是int因为单元格由int. neighbors[1]返回单元格 1 的邻居数组。

2个回答

有开源的 MD 代码和教科书,描述了一般如何做到这一点。我不想推荐任何特定的,但你可以搜索“分子模拟”或类似的东西。它可能会为您节省一些程序设计时间。

在您的图表中,您重复计算单元格 5 和 23。规则是,您需要查看具有相对位置的相邻单元格(Δnx,Δny,Δnz)其中相对单元格索引采用值的所有可能组合+1,0,1; 除了如果你看(Δnx,Δny,Δnz),你不需要看(Δnx,Δny,Δnz),以免重复计算。这给出了需要考虑的 13 个相邻单元,并且您可以在计算机代码中绘制一个永久表,其中包含必要的相对索引三元组。而且,正如您所意识到的,您需要查看图中的 14 个中央单元格,其中(Δnx,Δny,Δnz)=(0,0,0):当您开始查看原子对的坐标时,需要稍微不同的处理以避免重复计算。

这导致了我的主要建议:给单元格一个 3D 整数索引(nx,ny,nz),并使用这些索引将单元格内容(例如位置或指向位置列表的指针)存储在数组(或类似的)中。然后,识别相邻单元格是一个简单的添加问题(Δnx,Δny,Δnz)(nx,ny,nz)依次检查每个相邻小区;moduloormod函数将处理与周期性边界条件相关的索引的环绕换句话说,计算modulo(nx+delta_nx,nc)(或任何你喜欢的语言的语法)nx从零到每个坐标方向nc-1都有单元格;nc同样对于nynz

在将周期性边界条件应用于对之间的向量时,可以if通过使用算术语句来避免语句,例如xij = xij - rint(xij/box)*boxwhere xijis an uncorrected Difference inx- 原子之间的坐标i是盒子的长度并且是一个函数,它给出最接近的整数到它的参数(同样,这对于不同的编程语言可能不同)。jboxrint

如果这是 VMD 识别的文件,您可以使用 tcl 脚本创建单元邻居列表,该脚本仅定义您正在使用的盒子的总体积和单元边长。然后在 3 个嵌套循环中(对于 x、y、z 轴),沿着盒子的整个体积移动(分层工作)并选择循环定义的单元坐标内的所有原子并将它们写入外部列表。