第 1 步
配体和蛋白必须属于同一个力场家族。三条常用路线如下,GROMACS 2026 自带 amber14sb.ff 和 amber19sb.ff,CHARMM36m 需要从 MacKerell 实验室下载 GROMACS 端口。
混用力场时 grompp 不会报错
CHARMM 端口的 [ defaults ] 是 fudgeLJ 1.0、fudgeQQ 1.0;AMBER 和 GAFF 是 0.5、0.8333。把 GAFF 配体放进 CHARMM 体系,grompp 照常生成 tpr,但配体的 1-4 相互作用按 CHARMM 规则缩放,内部能量是错的。本页实测(GROMACS 2026.3):把 ACPYPE 生成的 GAFF2 配体放进 charmm36-feb2026 体系,grompp 没有任何 WARNING,日志只显示 Generating 1-4 interactions: fudge = 1。
CGenFF 版本要和端口版本一致
feb2026 端口分为 CGenFF 4.6 和 5.0 两套包,5.0 是默认。服务器用哪个版本的 CGenFF 程序生成配体,就下载对应的端口;用 5.0 生成的配体配 jul2022 端口(只含 4.6),会出现 Atomtype not found 或参数缺失。
ACPYPE 一定要写 -n
不给 -n 时,ACPYPE 用 antechamber 的 Gasteiger 电荷求和来猜净电荷。羧酸根、季铵等带电配体容易猜错,而 AM1-BCC 计算本身不会提示。
AM1-BCC 还是 ABCG2
ABCG2 把 GAFF2 在 FreeSolv(642 个分子)上的水合自由能 RMSE 降到 0.99 kcal/mol;但在 12 个靶点、507 个微扰的相对结合自由能测试中,ABCG2 的 ΔΔG RMSE 为 1.38 kcal/mol,AM1-BCC 为 1.31 kcal/mol,差异不显著。做结合模拟时 AM1-BCC 仍是稳妥的默认值。
| 路线 | 蛋白力场 | 配体工具与电荷 | 质量指标 | 水模型 | 适合场景 |
|---|---|---|---|---|---|
| CHARMM | CHARMM36m(charmm36-feb2026_cgenff-5.0.ff) | CGenFF 服务器(cgenff.com)直接导出 GROMACS 格式;电荷由 CGenFF 按类比给出 | penalty:<10 可直接用,10–50 需基本验证,>50 需重新优化 | CHARMM 修改版 TIP3P(端口中的 tip3p) | 跟随 Lemkul 官方教程;膜蛋白或已有 CHARMM 体系 |
| AMBER + GAFF2 | AMBER14SB 或 AMBER19SB(GROMACS 2026 自带) | ACPYPE 调用 antechamber;默认 AM1-BCC(-c bcc),也可用 ABCG2(-c abcg2) | parmchk2 补出的参数(frcmod 中标注 ATTN 的项);无统一数值阈值 | AMBER14SB 用 TIP3P;AMBER19SB 用 OPC 或 OPC3 | 对接后快速建体系;后续做 gmx_MMPBSA |
| AMBER + OpenFF | AMBER14SB | OpenFF Toolkit + Interchange;Sage 2.3.0 用 NAGL 图神经网络电荷(offxml 中的模型文件为 openff-gnn-am1bcc-1.0.0.pt),Sage 2.2 及以前用 AM1-BCC | 无 penalty;以 Sage 覆盖的元素和化学类型为准 | TIP3P(Sage 与 TIP3P 共同优化) | 含 Sage 训练集覆盖较好的类药分子;需要和 OpenMM 流程共用参数 |
第 2 步
Vina 输出的 PDBQT 没有键级,也没有连在碳上的氢。直接用 OpenBabel 把 PDBQT 转成 mol2,会按几何推断键级,Meeko 文档中的示例就给一个环加出了错误的双键。
配体如果在对接前用 Meeko 准备,PDBQT 的 REMARK 中保存了 SMILES 和原子映射,mk_export.py 可以据此恢复键级和全部氢。连在碳上的氢由 RDKit 按简单几何规则补回,后面的能量最小化会修正它们。
配体的质子化状态在对接前就已确定,Meeko 和 Vina 都不会修改它。MD 中使用的质子化状态应与对接时一致;如果需要改(例如按 pH 7.4 让羧基去质子化),应改 SMILES 后重新对接,或者至少用新的 SMILES 模板重建氢。
拼接复合物时,配体坐标要用参数化工具输出的文件(ACPYPE 的 LIG_GMX.gro、CGenFF 服务器返回的 pdb)。这些文件的原子顺序和原子名与拓扑一一对应,坐标来自你输入的对接构象。直接粘贴对接结果中的坐标,原子顺序几乎一定对不上。
# Ligand prepared with Meeko before docking: restore bond orders and all H from the PDBQT REMARKs
mk_export.py vina_out.pdbqt -s lig_docked.sdf # older releases use -o; check mk_export.py --help
# Keep only the pose you want (first record = top-ranked pose), then write mol2 for CGenFF / ACPYPE
obabel lig_docked.sdf -O lig.mol2 -l 1
# obabel names the residue UNL1; rename it so ACPYPE writes residue LIG (make_ndx, gmx_MMPBSA and the analysis commands select "LIG")
sed -i.bak 's/UNL1/LIG1/' lig.mol2
# Check the net charge before parameterization
python3 -c "from rdkit import Chem; m=Chem.MolFromMolFile('lig_docked.sdf',removeHs=False); print(Chem.GetFormalCharge(m), m.GetNumAtoms())"# Ligand NOT prepared with Meeko: rebuild bond orders from a SMILES template, keep the docked coordinates
from rdkit import Chem
from rdkit.Chem import AllChem
pose = Chem.MolFromPDBFile("lig_pose.pdb", removeHs=True) # heavy atoms of the docked pose
template = Chem.MolFromSmiles("CCCc1ccccc1O") # same protonation state you want in MD
pose = AllChem.AssignBondOrdersFromTemplate(template, pose)
pose_h = Chem.AddHs(pose, addCoords=True) # H placed on the docked heavy atoms
Chem.MolToMolFile(pose_h, "lig_docked.sdf")
print("formal charge:", Chem.GetFormalCharge(pose_h))
# Then, as above: obabel lig_docked.sdf -O lig.mol2 && sed -i.bak 's/UNL1/LIG1/' lig.mol2# Protein only: remove ligand, crystal waters and additives first
grep -v -e HETATM -e CONECT complex_docked.pdb > protein.pdb
# CHARMM36m route (force field directory unpacked in the working directory)
# -ter: choose NH3+ and COO-. Without it an N-terminal MET gets MET1 from ethers.n.tdb and pdb2gmx stops
gmx pdb2gmx -f protein.pdb -o protein.gro -p topol.top -ff charmm36-feb2026_cgenff-5.0 -water tip3p -ignh -his -ter
# AMBER route (amber14sb.ff ships with GROMACS 2026)
gmx pdb2gmx -f protein.pdb -o protein.gro -p topol.top -ff amber14sb -water tip3p -ignh -his- pdb2gmx 默认按氢键几何判断组氨酸质子化;活性位点附近的 His、Asp、Glu 建议用 PROPKA 等工具算 pKa 后,通过 -his 等交互选项手动指定。
- -ignh 让 pdb2gmx 忽略输入中的氢并按力场重新加氢,可以避免对接软件加的氢名与 rtp 不匹配。
- GROMACS 2026 中 pdb2gmx -rtpres 默认为 auto,会在需要时改写残基名,使 grompp 能正确分配 CMAP。
- 蛋白有缺失残基或缺失侧链原子时,pdb2gmx 会报 Long bonds and/or missing atoms,需要先补全结构。
第 3 步
合并拓扑只有三条规则:[ defaults ] 全体系只能有一个;配体 [ atomtypes ] 放在 forcefield.itp 之后、任何 [ moleculetype ] 之前;位置限制文件紧跟在它所属的 moleculetype 之后。
CGenFF 服务器导出的 lig_gmx.top 是独立体系拓扑。按 Lemkul 当前教程的做法改成 itp:删除 forcefield.itp 的 include,把 lig_ffbonded.itp 的内容贴进来,删掉水和离子部分,把 moleculetype 名从 Other 改为 LIG。配体的新二面角参数在 [ dihedraltypes ] 中,所以这个 itp 也要放在 forcefield.itp 之后、蛋白 moleculetype 之前。
genrestr 写出的原子编号相对于 moleculetype。在完整复合物的 gro 上运行,编号会是全体系编号,grompp 报 Atom index (n) in position_restraints out of bounds。ACPYPE 已经生成 posre_LIG.itp,可以直接用。
pdb2gmx 处理多条链时,蛋白 moleculetype 写在 topol_Protein_chain_A.itp 等文件里,topol.top 中只有它们的 include。配体的 include 放在这些 include 之后、水模型 include 之前。
ACPYPE 写出的 [ atomtypes ] 没有原子序数列,grompp 会把配体原子的 atomnumber 记为 -1。力场计算不受影响,但 GROMACS 2024 起的 gmx hbond 按元素识别供体和受体,对配体会报 Selection 'resname LIG' has no donors AND has no acceptors! Nothing to be done.(本页在 GROMACS 2026.3 上实测)。AMBER 路线代码中的第二个 awk 按质量补上原子序数,补后同一条命令正常输出配体与 Gln102 之间的氢键。CGenFF 端口和 OpenFF Interchange 的 atomtypes 自带原子序数,不需要这一步。
# GAFF2 + AM1-BCC; always pass the net charge with -n
acpype -i lig.mol2 -b LIG -c bcc -a gaff2 -n 0
cd LIG.acpype
# LIG_GMX.itp starts with [ atomtypes ]; split it so atomtypes can go before every [ moleculetype ]
# ACPYPE atomtypes carry no atomic number; the second awk adds it (from the mass) so that
# gmx hbond (2024+) can find the ligand's N/O donors and acceptors
awk '/^\[ *atomtypes *\]/{f=1} /^\[ *moleculetype *\]/{f=0} f' LIG_GMX.itp | \
awk '!/^ *[;[]/ && NF>=7 {m=$3; z=(m<1.5)?1:(m<13)?6:(m<15)?7:(m<17)?8:(m<20)?9:(m<31.5)?15:(m<33)?16:(m<36)?17:(m<80)?35:53; $2=$2" "z} 1' \
> ../LIG_atomtypes.itp
awk '/^\[ *moleculetype *\]/{f=1} f' LIG_GMX.itp > ../LIG.itp
cp LIG_GMX.gro ../LIG.gro
cp posre_LIG.itp ../posre_LIG.itp # heavy-atom restraints, 1000 kJ/mol/nm^2
cd ..# OpenFF Sage ligand -> GROMACS files (Interchange)
from openff.toolkit import ForceField, Molecule
from openff.interchange import Interchange
lig = Molecule.from_file("lig_docked.sdf") # coordinates = docked pose, H included
lig.name = "LIG"
sage = ForceField("openff-2.3.0.offxml")
inter = Interchange.from_smirnoff(force_field=sage, topology=[lig], box=[5, 5, 5])
inter.to_top("LIG_openff.top")
inter.to_gro("LIG_openff.gro")
# Then split it in bash; [ defaults ] is dropped, and the moleculetype part stops at [ system ]:
# awk '/^\[ *atomtypes *\]/{f=1} /^\[ *moleculetype *\]/{f=0} f' LIG_openff.top > LIG_atomtypes.itp
# awk '/^\[ *moleculetype *\]/{f=1} /^\[ *system *\]/{f=0} f' LIG_openff.top > LIG.itp
# cp LIG_openff.gro LIG.gro # atom order = lig_docked.sdf; make posre_LIG.itp with genrestr as in the CGenFF route# CGenFF route: generate ligand heavy-atom restraints on the ligand-only coordinates
gmx editconf -f lig_gmx.pdb -o LIG.gro
printf '0 & ! a H*\nq\n' | gmx make_ndx -f LIG.gro -o index_LIG.ndx
echo 3 | gmx genrestr -f LIG.gro -n index_LIG.ndx -o posre_LIG.itp -fc 1000 1000 1000# Append ligand atoms to the protein coordinates (same frame, nm)
python3 - <<'EOF'
p = open("protein.gro").read().splitlines()
l = open("LIG.gro").read().splitlines()
atoms = p[2:-1] + l[2:-1]
open("complex.gro", "w").write("\n".join([p[0], f"{len(atoms):5d}", *atoms, p[-1]]) + "\n")
EOF; topol.top (AMBER + GAFF2 example; CHARMM route is identical in layout)
#include "amber14sb.ff/forcefield.itp"
#include "LIG_atomtypes.itp" ; ligand atomtypes: after forcefield.itp, before any [ moleculetype ]
[ moleculetype ]
; Name nrexcl
Protein_chain_A 3
... ; written by pdb2gmx
; Include Position restraint file
#ifdef POSRES
#include "posre.itp"
#endif
; Ligand topology and its restraints (must follow the ligand [ moleculetype ])
#include "LIG.itp"
#ifdef POSRES_LIG
#include "posre_LIG.itp"
#endif
; Include water topology
#include "amber14sb.ff/tip3p.itp"
...
[ molecules ]
; Compound #mols (same order as complex.gro)
Protein_chain_A 1
LIG 1第 4 步
gmx editconf -f complex.gro -o box.gro -bt dodecahedron -d 1.0 -c
gmx solvate -cp box.gro -cs spc216.gro -p topol.top -o solv.gro # OPC/TIP4P-type water: -cs tip4p.gro
gmx grompp -f ions.mdp -c solv.gro -p topol.top -o ions.tpr
echo SOL | gmx genion -s ions.tpr -o solv_ions.gro -p topol.top -pname NA -nname CL -neutral -conc 0.15; ions.mdp (only used to build ions.tpr for genion)
integrator = steep
emtol = 1000.0
emstep = 0.01
nsteps = 50000
nstlist = 1
cutoff-scheme = Verlet
coulombtype = cutoff ; plain cutoff: no "Ewald with net charge" warning before neutralization
rcoulomb = 1.0
rvdw = 1.0
pbc = xyz盒子大小
-d 1.0 使复合物与其周期镜像至少相距 2.0 nm,大于 1.2 nm 的截断,复合物不会直接与自身镜像作用。GROMACS 手册的严格条件是盒长不小于分子尺寸加两倍截断(CHARMM 设置下相当于 -d 1.2),常见做法是放宽到 -d 1.0 以减少水分子。菱形十二面体的体积是同等镜像距离立方盒的 71%。
水盒子文件
TIP3P、SPC 等三位点水用 spc216.gro;AMBER19SB 配 OPC 时用四位点水盒子 tip4p.gro。
离子名
GROMACS 自带的 AMBER 端口和 CHARMM 端口都定义了 NA 和 CL;CHARMM 端口中的 NA/SOD、CL/CLA 是同一原子类型。-conc 0.15 在中和之外再加到 0.15 mol/L。
genion 选错组
提示选择要被替换的组时选 SOL。选 Water 或 System 时,如果组内原子不连续,会报 The solvent group ... is not continuous。
第 5 步
以下参数按 CHARMM36m 写,与 GROMACS 手册给出的 CHARMM36 设置和 Lemkul 当前教程一致。用 AMBER 路线时只替换非键截断部分。
; em.mdp (CHARMM36m settings; see the AMBER note below)
integrator = steep
emtol = 1000.0 ; kJ/mol/nm
emstep = 0.01
nsteps = 50000
nstlist = 1
cutoff-scheme = Verlet
coulombtype = PME
rcoulomb = 1.2
vdwtype = Cut-off
vdw-modifier = Force-switch
rvdw-switch = 1.0
rvdw = 1.2
DispCorr = no
pbc = xyz; nvt.mdp 100 ps, protein and ligand heavy atoms restrained
define = -DPOSRES -DPOSRES_LIG
integrator = md
nsteps = 50000 ; 50000 * 2 fs = 100 ps
dt = 0.002
nstxout-compressed = 5000
nstenergy = 500
nstlog = 500
continuation = no
constraint-algorithm = lincs
constraints = h-bonds
lincs-iter = 1
lincs-order = 4
cutoff-scheme = Verlet
nstlist = 20
coulombtype = PME
rcoulomb = 1.2
fourierspacing = 0.16
pme-order = 4
vdwtype = Cut-off
vdw-modifier = Force-switch
rvdw-switch = 1.0
rvdw = 1.2
DispCorr = no
tcoupl = V-rescale
tc-grps = System
tau-t = 1.0
ref-t = 300
pcoupl = no
pbc = xyz
gen-vel = yes
gen-temp = 300
gen-seed = -1 ; new seed per replica; npt.mdp 100 ps, restraints kept, C-rescale barostat
define = -DPOSRES -DPOSRES_LIG
integrator = md
nsteps = 50000
dt = 0.002
nstxout-compressed = 5000
nstenergy = 500
nstlog = 500
continuation = yes
constraint-algorithm = lincs
constraints = h-bonds
lincs-iter = 1
lincs-order = 4
cutoff-scheme = Verlet
nstlist = 20
coulombtype = PME
rcoulomb = 1.2
fourierspacing = 0.16
pme-order = 4
vdwtype = Cut-off
vdw-modifier = Force-switch
rvdw-switch = 1.0
rvdw = 1.2
DispCorr = no
tcoupl = V-rescale
tc-grps = System
tau-t = 1.0
ref-t = 300
pcoupl = C-rescale
pcoupltype = isotropic
tau-p = 5.0
ref-p = 1.0
compressibility = 4.5e-5
refcoord-scaling = com ; required with position restraints + pressure coupling
pbc = xyz
gen-vel = no; md.mdp 100 ns production, no restraints
integrator = md
nsteps = 50000000 ; 50,000,000 * 2 fs = 100 ns
dt = 0.002
nstxout = 0
nstvout = 0
nstfout = 0
nstxout-compressed = 5000 ; one frame every 10 ps
compressed-x-grps = System
nstenergy = 5000
nstlog = 5000
continuation = yes
constraint-algorithm = lincs
constraints = h-bonds
lincs-iter = 1
lincs-order = 4
cutoff-scheme = Verlet
nstlist = 20
coulombtype = PME
rcoulomb = 1.2
fourierspacing = 0.16
pme-order = 4
vdwtype = Cut-off
vdw-modifier = Force-switch
rvdw-switch = 1.0
rvdw = 1.2
DispCorr = no
tcoupl = V-rescale
tc-grps = System
tau-t = 1.0
ref-t = 300
pcoupl = C-rescale
pcoupltype = isotropic
tau-p = 5.0
ref-p = 1.0
compressibility = 4.5e-5
pbc = xyz
gen-vel = no; AMBER14SB / AMBER19SB + GAFF2 or Sage: replace the nonbonded block with
rcoulomb = 1.0
vdwtype = Cut-off
vdw-modifier = Potential-shift
rvdw = 1.0
DispCorr = EnerPres
; and delete rvdw-switch- AMBER 路线的截断设置没有官方推荐值。rvdw = rcoulomb = 1.0 nm、Potential-shift、DispCorr = EnerPres 是 GROMACS 论坛上的社区常用写法,用于 AMBER14SB 和 AMBER19SB。
- constraints = h-bonds 配合 dt = 2 fs。GPU 驻留更新(-update gpu)要求约束只包含 h-bonds。
- C-rescale 的 tau-p 默认 5 ps,平衡和生产都可以用;旧教程中生产阶段改用 Parrinello-Rahman 的做法不再必要。
- refcoord-scaling = com 必须写在带位置限制的 NPT 中,否则 grompp 给出 You are using pressure coupling with absolute position restraints 的警告。
- NVT 和 NPT 各 100 ps 是 Lemkul 教程的长度。判断标准是温度、压力和密度在后半段平稳;gmx energy 选 Temperature、Pressure、Density 查看。
- 100 ns、每 10 ps 一帧的 xtc 约有 10000 帧。只关心复合物时,可以把 compressed-x-grps 改为 Protein_LIG(需要 -n index.ndx),轨迹体积会小很多。
版本差异
多数中文教程复述的是 Lemkul 2018 版教程。以下是它与 GROMACS 2026 及 Lemkul 当前版教程不一致的地方。
2018 版教程把配体与蛋白放在同一温控组,是因为配体和离子这类原子很少的组动能涨落大,单独耦合时恒温器不稳定。V-rescale 下用 System 一个组就能避免这个问题。
# Optional: two coupling groups (the 2018 tutorial layout)
printf '"Protein" | "LIG"\nq\n' | gmx make_ndx -f em.gro -o index.ndx
# in nvt/npt/md.mdp: tc-grps = Protein_LIG Water_and_ions tau-t = 1.0 1.0 ref-t = 300 300
gmx grompp -f nvt.mdp -c em.gro -r em.gro -p topol.top -n index.ndx -o nvt.tpr| 旧写法 | 在 GROMACS 2026 中的结果 | 现在的写法 |
|---|---|---|
| pcoupl = Berendsen(NPT 平衡) | grompp 给出 WARNING,必须加 -maxwarn 才能继续 | pcoupl = C-rescale,tau-p = 5.0 |
| tcoupl = Berendsen | 同样给出 WARNING | tcoupl = V-rescale |
| tc-grps = Protein_JZ4 Water_and_ions | 可以运行,但需要 make_ndx 建组并在 grompp 加 -n | tc-grps = System(Lemkul 当前版);分两组也正确,但不要把配体或离子单独成组 |
| charmm36-jul2022.ff + cgenff_charmm2gmx.py | 只含 CGenFF 4.6 参数;与 5.0 生成的配体不匹配 | charmm36-feb2026_cgenff-5.0.ff,服务器直接导出 GROMACS 格式 |
| ns_type = grid | 被忽略,打印 Ignoring obsolete mdp entry | 删除这一行 |
| mdp 中拼错或已删除的参数 | Unknown left-hand ... in parameter file,计为一条 WARNING | 对照当前 mdp 文档改名 |
| gmx mdrun -nsteps 改步数 | 仍可用,但自 2019 起不推荐 | gmx convert-tpr -extend / -until / -nsteps |
| mdrun -deffnm | 2026 中仍可用,自 2021 起标记为将移除 | 可继续用;续跑时必须与首次运行一致 |
第 6 步
gmx grompp -f em.mdp -c solv_ions.gro -p topol.top -o em.tpr
gmx mdrun -v -deffnm em
gmx grompp -f nvt.mdp -c em.gro -r em.gro -p topol.top -o nvt.tpr
gmx mdrun -deffnm nvt -nb gpu -pme gpu
gmx grompp -f npt.mdp -c nvt.gro -r nvt.gro -t nvt.cpt -p topol.top -o npt.tpr
gmx mdrun -deffnm npt -nb gpu -pme gpu
gmx grompp -f md.mdp -c npt.gro -t npt.cpt -p topol.top -o md.tpr
gmx mdrun -deffnm md -ntmpi 1 -ntomp 8 -nb gpu -pme gpu -bonded gpu -update gpu -pin on# Three independent replicas: same minimized structure, new velocities in NVT
for r in 1 2 3; do
mkdir -p rep$r && cd rep$r
gmx grompp -f ../nvt.mdp -c ../em.gro -r ../em.gro -p ../topol.top -o nvt.tpr
gmx mdrun -deffnm nvt -nb gpu -pme gpu
gmx grompp -f ../npt.mdp -c nvt.gro -r nvt.gro -t nvt.cpt -p ../topol.top -o npt.tpr
gmx mdrun -deffnm npt -nb gpu -pme gpu
gmx grompp -f ../md.mdp -c npt.gro -t npt.cpt -p ../topol.top -o md.tpr
gmx mdrun -deffnm md -ntmpi 1 -nb gpu -pme gpu -bonded gpu -update gpu
cd ..
done- 能量最小化的合格标准是日志中出现 converged to Fmax < 1000,并且势能为负;Lemkul 教程中普通蛋白水体系的势能量级为 10^5–10^6 kJ/mol,具体取决于体系大小和水分子数。
- -r em.gro 是位置限制的参考坐标,GROMACS 2018 起必须显式给出。
- -update gpu 在 NVT 和 NPT 中不显式指定,mdrun 默认 -update auto,遇到不支持的功能会回退到 CPU;显式写 -update gpu 而不支持时会直接报错。
- 单 GPU 时 -ntmpi 1,-ntomp 设为分配给该任务的物理核数。PME 放在 GPU 上时 -npme 只能为 1。
- GPU 驻留运行中,频繁计算能量和频繁耦合会拖慢速度;nstcalcenergy 保持默认 100 或更大。
- 经验数据:一个约 6 万原子的蛋白水体系,全部任务放 GPU(-nb -pme -bonded -update gpu)时,作者在 T4、V100、A100 上分别测得约 80、150、250 ns/day,24 核 CPU 约 20 ns/day(腾讯云经验帖,作者自述为粗略测试)。
- 本页实测(CPU,仅作对照,GPU 会快得多):T4 溶菌酶 L99A/M102Q 与 2-丙基苯酚(PDB 3HTB),AMBER14SB + GAFF2(AM1-BCC),菱形十二面体 -d 1.0,0.15 M NaCl,共 33379 原子;conda-forge GROMACS 2026.3 CPU 版,Apple M2 8 核,1 个 thread-MPI rank × 8 个 OpenMP 线程,测试时机器上同时运行其他任务。ACPYPE 计算 AM1-BCC 电荷用时 31 s;能量最小化 955 步达到 Fmax < 1000(势能 −5.34×10^5 kJ/mol),用时约 8 min;50 ps 生产段在机器负载高时为 4.8 ns/day;负载较低时(1 分钟平均负载约 13)用 mdrun -nsteps 5000 -resethway 测得 10.3 ns/day,按此速度 100 ns 约需 10 天。
-maxwarn
-maxwarn N 让 grompp 在不超过 N 条 WARNING 时继续生成 tpr。NOTE 不计数。grompp 的帮助写明它不用于常规使用,可能生成不稳定的体系。判断方法是逐条读警告原文。
| 警告原文(节选) | 含义 | 处理 |
|---|---|---|
| You are using Ewald electrostatics in a system with net charge | 体系未中和时用了 PME | 只在生成 ions.tpr 时出现可以用 -maxwarn 1,genion 随后会中和;用 coulombtype = cutoff 的 ions.mdp 则不会出现。EM 及之后仍出现,说明没中和或配体电荷之和偏离整数,要修拓扑 |
| N non-matching atom names ... atom names from topol.top will be used | 坐标文件和拓扑的原子顺序或名字对不上 | 不能跳过。跳过后坐标会套上错误原子的参数。用参数化工具输出的配体坐标重新拼接 |
| Atomtype X was defined previously ... and has now been defined again | 配体 itp 重复定义了力场里已有的原子类型 | 不能跳过。后一次定义会覆盖前一次,可能改掉蛋白力场的参数。删除重复项,或给配体原子类型改名 |
| You are using pressure coupling with absolute position restraints | 带位置限制的 NPT 没设 refcoord-scaling | 不跳过,加 refcoord-scaling = com |
| The Berendsen thermostat does not generate the correct kinetic energy distribution;The Berendsen barostat does not generate any strictly correct ensemble | 用了 Berendsen(本页实测,各计一条 WARNING) | 改为 V-rescale / C-rescale |
| Unknown left-hand '...' in parameter file | mdp 参数名拼错或已被删除 | 改正参数名;跳过意味着该参数没有生效 |
| System has non-zero total charge: 0.000999 | 这是 NOTE,不需要 -maxwarn | 检查配体电荷之和;偏离整数超过 0.01 时回到参数化步骤 |
续跑
# 1) Interrupted run: continue from the last checkpoint (written every 15 min by default)
gmx mdrun -deffnm md -cpi md.cpt -nb gpu -pme gpu -bonded gpu -update gpu
# 2) Finished 100 ns, extend by another 100 ns (-extend is in ps)
gmx convert-tpr -s md.tpr -extend 100000 -o md_200ns.tpr
gmx mdrun -deffnm md -s md_200ns.tpr -cpi md.cpt -nb gpu -pme gpu -bonded gpu -update gpu
# Or set the end time directly: run until 200 ns
gmx convert-tpr -s md.tpr -until 200000 -o md_200ns.tpr
# 3) Queue system with a wall-time limit: stop cleanly before 23.5 h and write a checkpoint
gmx mdrun -deffnm md -cpi md.cpt -maxh 23.5
# 4) Changing mdp options while continuing (e.g. output frequency)
gmx grompp -f md_new.mdp -c npt.gro -t md.cpt -p topol.top -o md_new.tpr
gmx mdrun -s md_new.tpr -cpi md.cpt -noappend| 报错原文(节选) | 原因 | 处理 |
|---|---|---|
| The input requested N steps, however the checkpoint file has already reached step M | tpr 的总步数少于 checkpoint 已到达的步数,常见于延长过一次后又用了原来的 md.tpr。本页实测:模拟正好跑完时直接 -cpi 续跑不会报错,日志显示 continuing from step N 后立即结束,一步也不多跑 | 用 convert-tpr -extend 或 -until 生成新 tpr,并在 -s 中指定它 |
| Checksum wrong for 'md.log'. The file has been replaced or its contents have been modified | 输出文件在两次运行之间被改动或替换 | 恢复原文件,或加 -noappend 写成 .part0002 新文件 |
| Some output files listed in the checkpoint file md.cpt are not present or not named as the output files by the current program | 续跑时的文件名与首次运行不同,常见于首次用 -deffnm、续跑没用 | 使用与首次运行相同的 -deffnm 或文件名 |
| Checkpoint file is for a system of X atoms, while the current system consists of Y atoms | cpt 与 tpr 不属于同一体系 | 找到对应的 tpr 和 cpt |
| Cannot restart with appending because the previous simulation part used ... precision | 前后两次用了单精度和双精度不同的 GROMACS | 使用同一构建,或加 -noappend |
- -extend 和 -until 的单位是 ps。想多跑 100 ns 写 -extend 100000;GROMACS 论坛上有用户按步数写成 -extend 5000000,结果设成了 5 μs。
- checkpoint 默认每 15 分钟写一次(-cpt 15),意外中断最多损失约 15 分钟。
- 改 mdp 参数续跑时用 grompp -t md.cpt 读入完整精度的坐标和速度,保持 continuation = yes、gen-vel = no。
- 不要用最后一帧 gro 代替 cpt 续跑。gro 只有三位小数的坐标,没有恒温器、恒压器状态。
- 用 -noappend 续跑时,新文件名中的编号是模拟段号:第一次续跑为 md.part0002.*,之后递增。本页实测:同一体系第 4 段用 -noappend 得到 md.part0004.xtc,gmx trjcat -f md.xtc md.part0004.xtc 可直接拼接。
报错
| 报错原文(节选) | 真实原因 | 处理 |
|---|---|---|
| Residue 'LIG' not found in residue topology database | 把含配体的 pdb 交给了 pdb2gmx | pdb2gmx 只处理蛋白,配体单独参数化 |
| Atom HB3 in residue XXX not found in rtp entry | 输入中的氢名与力场 rtp 不一致 | 加 -ignh 让 pdb2gmx 重新加氢 |
| Invalid order for directive atomtypes | 配体 [ atomtypes ] 出现在蛋白 moleculetype 之后 | 把 atomtypes 拆成单独文件,紧跟 forcefield.itp include |
| Found a second defaults directive | 配体 top/itp 中带有 [ defaults ] | 删除配体文件中的 [ defaults ] |
| Atomtype XXX not found | 配体 atomtypes 没被 include,或 CGenFF 版本与端口版本不一致 | 检查 include 顺序;换用匹配版本的 CHARMM 端口 |
| No such moleculetype LIG | [ molecules ] 中的名字与配体 moleculetype 名不同 | 两处改成同一个名字 |
| number of coordinates in coordinate file (solv.gro, N) does not match topology (topol.top, M) | [ molecules ] 漏了配体,或数量、顺序与 gro 不一致 | 按 gro 中的顺序核对每个分子的数量 |
| Atom index (n) in position_restraints out of bounds (1-m) | 配体位置限制放错了 moleculetype,或 genrestr 在复合物上运行 | include 紧跟配体 itp;在只含配体的 gro 上重跑 genrestr |
| Steepest Descents converged to machine precision ... but did not reach the requested Fmax < 1000 | 原子重叠或配体几何异常 | 看日志中 Maximum force = ... on atom N,定位该原子;对接构象与蛋白冲突或氢位置异常时,先单独在真空中最小化配体再检查 |
| LINCS WARNING ... relative constraint deviation | 体系在 NVT 初期爆掉,多数源于配体拓扑或最小化不充分 | 按 GROMACS 文档的诊断步骤:看哪个原子最先失稳;分别最小化纯蛋白水体系、真空中的配体、水中的配体;用 gmx energy 看哪个成键能量项异常 |
| atom C1 not found in buiding block 1MET while combining tdb and rtp | CHARMM36 端口中 ethers.n.tdb 定义了名为 MET1 的末端,N 端为 Met 的蛋白默认选中它(本页在 GROMACS 2026.3 上用 jul2022 与 feb2026 两个端口实测均如此) | pdb2gmx 加 -ter,N 端选 NH3+,C 端选 COO- |
| step N: One or more water molecules can not be settled(能量最小化初期,同时写出 stepNb.pdb、stepNc.pdb) | 最速下降法某一步步长过大,刚性水无法约束;该步被拒绝,算法自动缩小步长 | 最小化最终出现 converged to Fmax < 1000 即可忽略,删除 step*.pdb;在 NVT 或生产阶段出现则按 LINCS 报错处理 |
时长与副本
副本数
Communications Biology 2023 发布的 MD 可靠性检查表要求每个条件至少 3 条独立模拟并做统计分析。Knapp 等(JCTC 2018)用 100 条副本做测试,建议 5–10 条作为经验下限,并发现多条较短副本比一条长轨迹的结论更可靠。
副本怎么产生
从同一个最小化结构出发,在 NVT 中用 gen-seed = -1 重新生成速度,三条副本各自经过 NVT、NPT 和生产模拟。只改最后的生产段不算独立副本。
时长怎么判断
以你要报告的观测量是否收敛为准:配体相对蛋白的 RMSD、关键氢键距离在后半段是否平稳,以及三条副本的平均值是否接近。Lemkul 教程中 10 ns 只用于演示。
构象漂走的处理
配体 RMSD 在某条副本中持续上升并离开口袋,这是结果的一部分,应和其他副本一起报告,并统计配体留在口袋中的副本比例。
分析
RMSD、RMSF、回转半径、氢键和 SASA 的命令与判读见《分子动力学模拟结果怎么分析》。这里只讲做 MM/GBSA 前必须完成的预处理和 gmx_MMPBSA 1.7 的变化。
# Make molecules whole and keep the complex centered
printf '"Protein" | "LIG"\nq\n' | gmx make_ndx -f em.gro -o index.ndx
printf 'Protein_LIG\nSystem\n' | gmx trjconv -s md.tpr -f md.xtc -n index.ndx \
-o md_center.xtc -center -pbc mol -ur compact
# gmx_MMPBSA 1.7.x, GB with the 1.7 defaults written out explicitly
cat > mmpbsa.in <<'EOF'
&general
sys_name="complex", startframe=5001, endframe=10000, interval=10,
PBRadii=4,
/
&gb
igb=8, saltcon=0.150,
/
EOF
gmx_MMPBSA -O -i mmpbsa.in -cs md.tpr -ct md_center.xtc -ci index.ndx \
-cg Protein LIG -cp topol.top -o FINAL_RESULTS_MMPBSA.dat -eo FINAL_RESULTS_MMPBSA.csv- gmx_MMPBSA 1.7.0 于 2026-09-12 发布。GROMACS 计算必须提供 -cp topol.top,配体拓扑必须已经在 topol.top 中。
- 1.7.0 改了默认值:不写时 igb 由 5 变为 8,PBRadii 由 3 变为 4(mbondi3),exdi 由 80 变为 78.5。和旧结果比较前,把这些值显式写进输入文件。
- qh_entropy = 1 在 1.7.0 中被拒绝。需要熵校正时使用 interaction entropy 或 C2 entropy。
- 测试范围:GROMACS 2022–2026,AmberTools ≥24.8 且 <27,Python 3.11–3.12。
- MM/GBSA 的绝对数值通常明显偏离实验结合自由能。它适合比较同一靶点上结构相近的配体,比较时各配体要用相同的协议和帧数。
- 相邻帧高度相关,帧数加倍不会让误差减半。示例中每 10 帧取 1 帧(100 ps),误差用三条副本之间的差异来估计。
- 本页实测:gmx_MMPBSA 1.7.0(pip 安装,AmberTools 26,GROMACS 2026.3)在上述 3HTB 体系上用 -cg Protein LIG(-cg 接受组名或从 0 开始的组号)跑通,6 帧 GB 计算约 70 s,FINAL_RESULTS_MMPBSA.dat 末尾给出 ΔTOTAL。这只是 50 ps 轨迹上的连通性测试,数值不具有参考意义。
国内做法
计算化学公社和 Sobereva 博客中最常见的 AMBER 路线是:用 Multiwfn 自带脚本算 RESP 或 RESP2 电荷,再用 Sobtop 按 GAFF 生成拓扑。力场与上文 ACPYPE 路线相同,区别在电荷方法和工具。以下内容来自 Sobtop 主页、Sobereva 博文和公社答疑帖,命令按 Sobtop 2026.1.16 和 Multiwfn 自带脚本核对。
# 1) 电荷:Multiwfn 自带的脚本(Multiwfn 目录下 examples/RESP/),在 Linux 下运行
# 运行前在脚本中改好 ORCA= 与 orca_2mkl= 的路径、nprocs 和 maxcore
# 参数:结构文件 净电荷 自旋多重度;输入对接得到的带氢配体,脚本先做 B97-3c 优化再算电荷
./RESP2_ORCA.sh lig.mol2 0 1
# 结构已经优化过时,用不做优化的版本
./RESP2_ORCA_noopt.sh lig.mol2 0 1
# 有 Gaussian 时用 RESP2.sh 或 RESP.sh,用法相同
# 输出 lig.chg:前四列是元素和坐标,最后一列是电荷,原子顺序与输入文件一致
# 2) 拓扑:启动 ./sobtop 后依次输入(Sobtop 主页例 2 的 GAFF 路线)
# lig.mol2 对接构象、带氢、键级正确的 mol2
# lig.chg 在主菜单直接输入 chg 文件路径,载入 RESP2 电荷
# 2, [回车] 写出 gro,坐标取自 mol2
# 1, 2, 4 写 GROMACS 拓扑;指认 GAFF 原子类型;从参数库取参数,缺失项由程序猜
# [回车], [回车] 使用默认的 top 和 itp 路径Sobtop 的输出怎样并入 topol.top
Sobtop 写出 lig.itp 和 lig.top。lig.top 只有 [ defaults ](fudgeLJ 0.5、fudgeQQ 0.8333,与 AMBER 相同)和 include,合并时不用。lig.itp 开头是 [ atomtypes ],按第 3 步的规则拆出,放在 forcefield.itp 之后。Sobtop 的 atomtypes 带原子序数列(at.num),不需要 ACPYPE 路线中补原子序数的步骤。残基名默认是 MOL,分子名取文件名;本页命令按 LIG 选组,要么把 itp 和 gro 中的名字改成 LIG,要么在命令中改用 MOL。以上按 Sobtop 2026.1.16 包中的 Methyl_benzoate 示例文件核对。
mol2 不带电荷时,拓扑中电荷全为 0
Sobtop 把 mol2 中记录的原子电荷写进 itp;mol2 不含电荷时全部写 0,程序不报错。对接软件导出的 mol2 可能带 Gasteiger 电荷,也会被直接采用。生成拓扑后检查 [ atoms ] 中 charge 列的数值确实来自 chg 文件,且总和等于净电荷。
选项 4 的缺失参数是猜出来的
选 4 时,参数库中缺少的键和角以当前结构为平衡值、力常数取近似值,缺少的二面角旋转势垒设为 0。普通有机配体一般不缺参数;屏幕列出缺失项时要逐条看,缺的是可旋转二面角时需要另行处理。想让键和角参数更准,可以选 7:由 Gaussian 的 fchk 或 ORCA 的 hess 文件中的 Hessian 计算键和角参数,二面角仍取 GAFF(Sobtop 主页例 3)。
RESP 的计算级别
RESP.sh 默认在 B3LYP-D3(BJ)/def2-SVP 下优化,在 B3LYP-D3(BJ)/def2-TZVP 下算单点,溶剂默认用 IEFPCM 水;ORCA 版脚本用 B97-3c 优化,两者结果相差零点零几属于正常。Sobereva 在公社答疑中指出:6-311G** 适合做优化和频率,给 Multiwfn 算 RESP 偏低;给氢加弥散函数没有必要。含 18 号及以后元素(如 Br、I)时 Gaussian 没有内置的拟合半径,脚本不能自动完成,需要按 sobereva.com/441 手动计算。溶液中的模拟,Sobereva 推荐用 RESP2(0.5)。
用哪个构象算配体电荷
Sobereva 的建议(sobereva.com/441 附 2):对接得到的配体构象可能不合理,不宜直接用来算 RESP;先以对接构象为初猜做常规几何优化,再算 RESP,然后跑复合物 MD。如果 MD 中配体的主要构象与优化构象差别显著,对轨迹做簇分析取代表构象,在力场下能量极小化后抠出配体,直接算单点 RESP(不再做量子化学优化),用新电荷做正式模拟。配体来自高分辨率晶体结构时,只优化氢的位置后算 RESP。
AM1-BCC、ABCG2 和 RESP:公社里的两种意见
Sobereva 的观点是:ABCG2 只是取代 AM1-BCC,不能取代 RESP 或 RESP2。ABCG2 开发组的成员在同一帖中回复:ABCG2 专为 GAFF2 调参,在溶剂化自由能上优于 RESP,GAFF2-ABCG2 与 GAFF2-RESP(2) 都应视为正确的搭配。另一帖指出,含 P=O 的分子(磷酸酯、FAD 等)由 antechamber 调用 sqm 算 AM1-BCC 时,优化中可能有氢移到 P=O 上,电荷随之出错,此类分子改用 Multiwfn 算 RESP。
gmx_MMPBSA、gmx_mmpbsa、g_mmpbsa 是三个工具
中文资料中三者经常混用。本页分析一节用的 gmx_MMPBSA 是 Valdés-Tresanco 等开发的 Python 程序,基于 AmberTools 的 MMPBSA.py。gmx_mmpbsa 是 Jerkwin(李继存)写的 bash 脚本,用 gmx dump 从 tpr 读取参数、调用 APBS 计算 PB 项,2019 年的版本只有 PB、没有 GB 和熵项,2021 年的更新加入了屏蔽效应和熵贡献。g_mmpbsa 只支持特定版本的 GROMACS 和 APBS,Jerkwin 中文教程第 9 节介绍的是它和 GMXPBSAtool。照抄命令前先确认教程用的是哪一个,三者的输入和输出互不通用。
交给 Agent
指令示例:"用 docking/vina_out.pdbqt 中排名第一的构象和 receptor.pdb,按 AMBER14SB + GAFF2(AM1-BCC,配体净电荷 0)建体系,0.15 M NaCl,跑 3 条 100 ns 副本,最后 50 ns 做 gmx_MMPBSA,并检查配体是否留在口袋中。"
智能体会依次导出带氢配体、运行 ACPYPE 和 pdb2gmx、合并拓扑、溶剂化加离子、最小化和平衡,按需要租用 GPU 跑生产模拟,中断后从 checkpoint 续跑,再做 PBC 处理、RMSD 与氢键分析和 gmx_MMPBSA。产出包括 topol.top 和全部 itp、四个 mdp、每条副本的 tpr/xtc/edr/log、分析曲线和 FINAL_RESULTS_MMPBSA.dat。Scientify 的案例"溶菌酶分子动力学模拟"和"计算小分子水合自由能"使用的是同一套环境。
你仍需要自己判断:配体的质子化状态和净电荷是否正确,His 等关键残基的质子化是否合理,对接构象本身是否可信,以及 MM/GBSA 数值在论文中应如何解释。
参考资料
- GROMACS 2026 mdp 选项文档 — Berendsen、C-rescale、约束、refcoord-scaling 的官方说明
- GROMACS 2026 新功能:AMBER14SB/AMBER19SB 与 pdb2gmx -rtpres — 自带 AMBER 力场与 validation pending 状态
- GROMACS 力场说明 — CHARMM36 推荐设置;AMBER19SB 搭配 OPC/OPC3
- GROMACS 源码 readir.cpp、grompp.cpp、toppush.cpp、topio.cpp(release-2026) — 各条 grompp 警告的原文及其属于 WARNING 还是 NOTE
- GROMACS:Managing long simulations — -cpi、追加与校验、convert-tpr 延长
- gmx convert-tpr 帮助 — -extend/-until 的单位为 ps
- GROMACS mdrun 性能指南 — GPU 驻留运行、-npme 限制
- GROMACS 参考手册:周期性边界条件 — 菱形十二面体体积与盒子尺寸条件
- Lemkul:Lysozyme in Water 能量最小化 — EM 势能量级与 Fmax 判断
- Genheden & Ryde:MM/PBSA 与 MM/GBSA 综述 — MM/GBSA 的适用范围与局限
- GROMACS 常见错误 — 拓扑类报错的官方解释
- GROMACS 术语:Blowing up 与不稳定体系诊断 — LINCS 警告的排查步骤
- Lemkul:Protein-Ligand Complex 教程(2025.x 版) — 当前版流程、mdp 与 penalty 阈值
- Lemkul:Protein-Ligand Complex 教程(2018 版) — 旧版写法对照
- MacKerell 实验室:CHARMM36 GROMACS 端口 — feb2026 端口与 CGenFF 版本匹配要求
- ACPYPE(GitHub) — 命令参数、ABCG2 选项、净电荷猜测逻辑
- He et al. ABCG2, JCTC 2025 — ABCG2 水合自由能数据
- Behera, Gapsys, de Groot, JCIM 2025 — ABCG2 与 AM1-BCC 的结合自由能对比
- OpenFF force fields 发布记录 — Sage 2.3.0 使用 AshGC 电荷,与 TIP3P 共同优化
- OpenFF Interchange 构建与导出文档 — from_smirnoff 与 GROMACS 导出
- Meeko:导出对接结果 — PDBQT 键级问题与 mk_export.py
- gmx_MMPBSA 1.7.0 发布说明 — 默认值变化与 -cp 要求
- gmx_MMPBSA 兼容性与迁移说明 — 支持的 GROMACS、AmberTools、Python 版本
- Reliability and reproducibility checklist for MD simulations, Commun. Biol. 2023 — 每个条件至少 3 条独立模拟
- Knapp, Ospina-Forero, Deane, JCTC 2018 — 副本数量的经验下限
- GROMACS 论坛:AMBER 力场的非键 mdp 参数 — 经验帖:AMBER 截断设置的社区常用写法
- GROMACS 论坛:Extend option in gmx convert-tpr — 经验帖:-extend 按步数填写导致延长过多
- gmx-users:v-rescale fatal error(离子单独耦合) — 经验帖:Lemkul 说明离子不能单独作为温控组
- gmx-users:CGenFF validation / optimization — 经验帖:CGenFF penalty 的解读与验证讨论
- 腾讯云开发者社区:GROMACS GPU 版安装与速度测试 — 经验帖:6 万原子体系在 T4/V100/A100 上的粗略速度
- Sobtop 主页(2026.1.16,例 2 与例 3) — Sobtop 的菜单流程、mol2 电荷读取、缺失参数处理与 Hessian 参数
- Sobereva:计算 RESP 原子电荷的超级懒人脚本 — RESP.sh 的默认级别、参数、noopt 版本与 18 号以后元素的限制
- Sobereva:ORCA 结合 Multiwfn 计算 RESP、RESP2 和 1.2*CM5 原子电荷的懒人脚本 — RESP2_ORCA.sh 的设置项(ORCA 路径、nprocs、maxcore)与 B97-3c 优化
- Sobereva:RESP 拟合静电势电荷的原理以及在 Multiwfn 中的计算(附 2) — 蛋白-配体体系中配体 RESP 电荷用哪个构象计算
- 计算化学公社:小分子拓扑 RESP 电荷和力场参数的 Gaussian 关键词 — 经验帖:Sobereva 关于 RESP 单点基组和弥散函数的答复
- 计算化学公社:GAFF2 搭配的 ABCG2 电荷是否比 RESP/RESP2 更好 — 经验帖:Sobereva 与 ABCG2 开发组成员的两种意见
- 计算化学公社:关于计算配体 RESP 电荷的一点小问题 — 经验帖:含 P=O 分子用 sqm 算 AM1-BCC 出错
- Jerkwin:gmx_mmpbsa 使用说明 — 基于 APBS 的 gmx_mmpbsa 脚本,与 gmx_MMPBSA 名称相近、功能不同