[toc]
介绍
- 用于分子系统构建、MD模拟和MD数据的后处理软件。
环境配置
Linux: Ubuntu-22.04
1 | sudo apt install git |
Clone、编译、安装
1 | git clone https://github.com/MolTwister/MolTwister.git |
安装成功输出
1 | Consolidate compiler generated dependencies of target MolTwister |
教程实操
- 终端输入
moltwister
打开MolTwister
命令行和右侧3D View
创建一个水分子PDB
在MolTwister命令行执行以下命令:
1
2
3
4add atom H1 at 0 0 0
add atom O from atom 0 dist 0.96
add atom H2 from bond 0 1 angle 104.5 0.0 dist 0.96
genbonds这将在(x, y, z)=(0,0,0)处创建一个名为H1的氢原子(其中前导H产生一个氢原子),索引为0。然后加入一个氧原子,称为O,与索引为0的原子保持0.96埃的距离。最后,在索引为0 (H1)和1 (O)的原子之间以104.5度和0.0度的二面角形成键,与O的距离为0.96埃,加入一个氢原子H2
如下图:
测量距离和角度,检查一切是否如我们所料
1
2
3measure bondlength id 0 1
measure bondlength id 1
measure angle id 0 1 2measure工具还可以测量没有相连的两个原子之间距离:
1
measure bondlength id 0 2
要创建PDB文件内容,可以这样写:
1
2print pdb
print pdb > my_water.pdb
创建liquid water
打开
MolTwister
,确保你有my_water.pdb
(在上述教程中创建的pdb
文件,或类似的pdb
文件)。执行如下命令:1
2
3
4
5load my_water.pdb
sel all
copy sel 10 10 10 3.0 3.0 3.0
autoscale
genbonds这将把PDB文件加载到MolTwister中,选择水分子的所有原子,然后在x, y和z方向上复制该选择10次,每个方向上的距离为3埃。最后,自动缩放用于放大整个系统,然后为每个水分子创建键。
创建MolTwister脚本
创建一个名为
gen_my_water_mol.script
的文件。编写脚本,编写以下内容:1
2
3
4exec("add atom H1 at 0 0 0");
exec("add atom O from atom 0 dist 0.96");
exec("add atom H2 from bond 0 1 angle 104.5 0.0 dist 0.96");
exec("genbonds");在MolTwister中运行以下命令:
1
load gen_my_water_mol.script
这将通过依次调用文件中给出的每个命令来创建一个水分子。
创建一个MolTwister Python脚本
创建一个名为
gen_cube.py
的Python
脚本,其中包含(required Python3
):1
2
3
4
5
6
7
8
9
10
11import moltwister as mt
for i in range(0, 10):
for j in range(0, 10):
for k in range (0, 10):
x = i*3.0
y = j*4.0
z = k*1.5
mt.mt_exec(f"add atom O at {x} {y} {z}")
mt.mt_exec("autoscale")然后在MolTwister中执行如下命令:
1
load gen_cube.py
Water simulation, thermalization, RDF, MSD, VACF, and VDOS
引言
在本教程中,我们将创建一个单一的水分子,然后复制它来创建一个水相。随后,我们分配了力场参数,进行了能量优化,然后进行了仿真
一旦模拟完成,我们将绘制温度作为时间的函数来确定热化点。接下来是计算
- 径向分布函数,
- 均方位移和自扩散,
- 速度自相关函数,
- 以及振动态密度。
创造一个水分子
1 | add atom Hw1 at 0 0 0 |
分配力场参数
我们现在可以为新创建的水分子分配力场参数。
我们可以直接输入命令,但我们可能需要在研究过程中多次分配力场。因此,我们创建一个名为
water_ff.script
的文件。该文件应包含:1
2
3
4
5
6
7
8
9
10
11# water_ff.script-->TIP3P water
mod mass name Hw1 to 1.00784;
mod mass name Hw2 to 1.00784;
mod mass name Ow to 15.999;
add mdbond Ow Hw1 Harm all_r_less_than 1.1 1882.8 0.9572;
add mdbond Ow Hw2 Harm all_r_less_than 1.1 1882.8 0.9572;
add mdangle Hw1 Ow Hw2 Harm all_r_less_than 1.1 230.12 104.52;
add mdnonbonded Ow Ow LJ 0.426768 3.188;
清除所有内容
很多时候,我们希望在MolTwister中执行子任务,最终得到一个脚本、pdb文件或类似的文件,可以稍后重新加载。在创建这些之后,我们通常想要从MolTwister内存中删除我们所做的一切。这分两步完成。
首先我们删除我们在3D视图中看到的:
1
2sel all
del sel随后,我们删除所有力场参数
1
del ff
在某些系统上,还可以打开几个MolTwister实例,这在某些情况下可能很有用。
调查一下力场
注意,要使下面的Python脚本工作,必须在系统上安装
MatplotLib
,这可以通过调用来完成:pip install matplotlib
要使MolTwister工作,必须安装Python,所以系统上应该已经安装了Python。
将所需的数据再次加载到系统中:
1
2load single_water.pdb
load water_ff.script我们可以输出数据来显示指定力场电位的图,但首先我们需要知道指定力场的指数,这可以通过调用:
1
2
3
4list ff
help moldyn
# 我们可以看看水氧之间的伦纳德-琼斯势,也就是指数为0的非成键势
moldyn ff nonbondforceprofile 0 2.9 10.0 100 > OwOw_LJ.dat其中结果存储在OwOw_LJ.dat文件中。这可以使用以下Python脚本绘制,名称为
plot_non_bonded.py
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21import matplotlib.pyplot as plt
listX = []
listY = []
f = open("OwOw_LJ.dat", "r")
startOfList = False
for line in f:
if startOfList:
s = line.split()
if len(s) >= 3:
listX.append(float(s[0])) # Extract r in Å
listY.append(float(s[2])) # Extract U in kJ/mol
if "Potential" in line:
startOfList = True
fig, ax = plt.subplots()
ax.plot(listX, listY)
ax.set(xlabel='r [Å]', ylabel='U [kJ/mol]', title='Ow-Ow Lennard-Jones potential')
plt.show()运行脚本画出LJ势能图:
创建liquid water
现在我们要使用
single_water.pdb
文件,创建并构建了一个包含512
个水分子的水相,随机放置,没有碰撞。假设密度为$$997 kg/m^3$$,两个氢的质量为1.0078
,一个氧的质量为15.999
,我们先计算一下盒子的大概尺寸:1
2
3
4
5
6
7
8
9
10
11calculate volumefromdensity 997 1.0078,1.0078,15.999 512
# output:
# Mass of atom 0 of single molecule = 1.0078 g/mol
# Mass of atom 1 of single molecule = 1.0078 g/mol
# Mass of atom 2 of single molecule = 15.9990 g/mol
#
# Target density = 997.0000 kg/m^3
# Number of molecules = 512
# Destination volume = 15362.3861 Angstrom^3
# Destination length for cubic system = 24.8591 Angstrom对于一个立方模拟盒,这产生的边长约为25 Å
我们现在应该确保我们从一个干净的MolTwister开始:
1
2
3sel all
del sel
del ff首先我们加载水分子:
1
load single_water.pdb
然后说del来删除之前的东西。随后,选择所有原子,将其随机放置在一个边长为25 Å,分子原子之间最小距离为1.5 Å的立方盒子中,并制作512份副本:
1
2sel all
copy sel random 25 25 25 512 1.5检查我们是否通过选择所有的水氧(Ow)并计算它们来创建512个分子:
1
2
3sel none
sel atomname Ow
measure count selMD模拟器只接受几何中心位于原点的系统。因此,我们需要通过调用将系统替换到这个位置
1
2mod atompos all geomcent 0 0 0
autoscale现在将系统保存到PDB文件中
1
print pdb > water.pdb
建立周期边界条件
现在我们要为模拟设置适当的周期边界条件(PBC)。
从上面的构造我们知道所有的原子都在25个Å的盒子里,但是我们也可以通过:
1
2
3
4
5
6
7
8measure pbc
# output:
# x = [-10.0000, 10.0000]
# y = [-10.0000, 10.0000]
# z = [-10.0000, 10.0000]
#
# User defined PBC!然后,我们在PBC的每一边添加足够的量,以确保分子不会靠近PBC另一边的分子。因此,我们调用
1
mod userdefpbc -12.5 12.5 -12.5 12.5 -12.5 12.5
设置一个25 × 25 × 25 Å边界框,我们调用
1
set userdefpbc on
为了激活它。聪明的做法是创建一个名为
pbc.script
的文件。并插入最后两个命令,这样我们就不必每次都手动调整PBC,而是只需编写load pbc.script
进行能量优化
分子被随机放置在我们创造的液相中,所以通过执行能量优化来最小化原子之间的力是一个好主意。
我们将使用默认的最大优化步数和默认的学习率来实现这一点,但我们将设置当能量变化小于10 kJ/mol时算法将停止。
要查看默认值,请调用:
1
moldyn cfg get
为了设置
10 kJ/mol
的精度,调用1
moldyn cfg set optaccuracy 10
我们现在从一个新的MolTwister开始:
1
2
3
4
5
6sel all
del sel
del ff
load water.pdb
load pbc.script
load water_ff.script然后,开始能量优化:
1
2moldyn cfg set outstride 10
moldyn optimizeenergy直到它终止。这将生成一个名为
traj.dcd
的文件 ‘和out.txt
。通过创建一个名为
plot_energy.py
的Python脚本,包含:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21import matplotlib.pyplot as plt
listX = []
listY = []
f = open("out.txt", "r")
startOfList = False
for line in f:
if startOfList and "Searching" not in line:
s = line.split()
if len(s) >= 6:
listX.append(float(s[0])) # Extract time step column
listY.append(float(s[5])) # Extract energy column
if "Step," not in line and "Step" in line:
startOfList = True
fig, ax = plt.subplots()
ax.plot(listX, listY)
ax.set(xlabel='Step', ylabel='U [kJ/mol]', title='Energy optimization')
plt.show()我们可以看到优化过程的能量图:
如果对结果感到满意,可以将优化过程的最后一帧导出到PDB文件。首先加载轨迹
1
load traj.dcd
您可以通过单击3D视图并使用左右箭头键逐步查看优化过程。您还可以启用
fog
,以更好的深度可视化1
set fog on
我们现在通过导出优化的帧(在本例中为帧499)
1
print pdb frame 499 > initial.pdb
我们将使用它作为模拟的起始框架。
如果您愿意,可以重命名该轨迹。DCD和out.txt文件从能源优化安全保管。它们将在后面的步骤中被删除。
执行分子动力学模拟
我们重新开始清除MolTwister内存:
1
2
3sel all
del sel
del ff现在删除所有剩余traj.dcd和out.txt文件
我们重新加载初始系统,PBC和力场参数
1
2
3load initial.pdb
load pbc.script
load water_ff.script我们配置为以
0.5 fs
的速度运行100000
个时间步,总共产生50 ps
,并且我们将输出步长设置为10
帧:1
2
3moldyn cfg set timestep 0.5
moldyn cfg set timesteps 100000
moldyn cfg set outstride 10现在我们可以运行模拟
1
moldyn run
在相对较新的CPU上,此模拟将花费几个小时并产生一个traj.dcd轨迹文件和一个out.txt输出文件。
如果模拟失败,例如产生NaN (Not a Number),那么可以尝试减少时间步长。例如,从0.5到0.2秒,以获得更好的平衡。
一旦模拟完成,我们可以加载轨迹文件通过
1
load traj.dcd
并利用键盘的左右箭头进行仿真分析。调用帮助查看如何调整每次按键的步数,以及如何显示/隐藏跨边界的键,以及在透视图和正射影视图之间切换。
绘制温度随模拟时间的函数
温度作为时间步长的函数可以在
out.txt
中找到,我们将使用Python绘制结果。创建文件plot_temp.py
,并输入以下脚本:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21import matplotlib.pyplot as plt
listX = []
listY = []
f = open("out.txt", "r")
startOfList = False
for line in f:
if startOfList and "Searching" not in line:
s = line.split()
if len(s) >= 3:
listX.append(float(s[0])) # Extract time step column
listY.append(float(s[2])) # Extract temperature column
if "Timestep," not in line and "Timestep" in line:
startOfList = True
fig, ax = plt.subplots()
ax.plot(listX, listY)
ax.set(xlabel='Step', ylabel='T [K]', title='Temperature')
plt.show()温度vs时间:
这应该能清楚地显示系统的热化周期。这对于确定在模拟中的哪个点找到可以执行计算的热化数据非常重要。在本教程中,我们将假设系统在8000个时间步长之后热化,这对应于DCD文件中的帧索引800,因为我们每10个时间步长输出一次。