近鄰列表(neighbor list,也叫做Verlet list)是分子動力學模擬中為了加速體系粒子間相互作用的力的計算而設置的一種數據結構或採取的技術。
首先我們講解下為啥用近鄰列表:在分子動力學模擬中,粒子間相互作用力的計算最耗時間,而其中非鍵合作用力的計算又佔主要部分。因此,如何有效地提高計算非鍵合作用力的效率成為提高分子動力學計算效率的關鍵因素。前面關於截斷半徑的介紹就是一種方法。雖然截斷半徑的設置可以大大減少需要計算相互作用力的原子對數目,但是在模擬中的每次迭代都要對全部粒子進行搜索,以判斷每個粒子截斷半徑範圍內的其它粒子,當體系中粒子數比較大的時候,這個是很耗時間的。
近鄰列表的根本思想是在限定的局部空間而非整個模擬盒子範圍內搜索可能產生相互作用的粒子對。在近鄰列表法中,將與粒子i距離在Rm內的粒子都存儲在該列表中,在模擬中作用力的計算仍考慮截斷半徑Rcut的範圍。在一段模擬時間內,如果Rm範圍外的粒子都不會進去Rcut的範圍,則不需要更新近鄰列表。Rm-Rcut的範圍即是一個緩衝區域,即下圖的skin region。在計算與粒子i之間的作用力時,該區域內的粒子實際上並不被考慮。簡單說,這是一種用計算機內存空間換取CPU計算時間的方法。
通過上述介紹,大家可以猜想,如果頻繁的更新 list也是一個耗時的問題。如果不想頻繁的更新list,那skin region可以設置大些,這樣外面的粒子就不會進入cut區域。但是這又增加了每個粒子的list內的原子數目,增加了計算量。所以一般軟體會設置一些參數來人為調試什麼情況下比較佳。
除了近鄰列表法,還有cell list的方法,這個對於非常大的box,能起到更好的加速作用。 Celllist方法是把盒子分成很多小份(如下圖),但是每份的尺寸要大於rcut,這也計算的時候,只需要考慮近鄰的小box內的粒子就行了。
很多程序,是上述兩個方法combine在一起使用的,先畫cell,然後近鄰Cell 處理用 verlet list.
對於 LAMMPS,我們一般用neighbor 和 neighbor_modify來設置 verlet list。大家現在應該知道其參數 bin的意義了吧。但LAMMPS neighbor_modify裡的check delay 等參數之間的關係,確實讓人難理解。為給大家說明清楚,我們看看如下簡單的代碼:
ago++;
if(ago >= delay && ago % every == 0) {
if (build_once) return 0;
if (dist_check == 0) return 1;
return check_distance();
}else return 0;
上面的意思是說:如果這次更新list滿足你設置的delay, 且是every的整數倍,會查看是否設置了once,如果設置了,就一直不更新,如何沒有,就會檢查你有沒有把check設置為 no,如果是,就更新,不做check。如果check設置為 yes,那就進行check處理,返回 check的結果。看著那麼麻煩的設置,還是推薦大家用默認吧。
gromacs也有list更新的參數設置,只不過沒有lammps那麼煩,它只有過多少步更新一次,默認是10,一般模擬就用默認吧