LAMMPS Python回调与外部控制
通过嵌入式python命令和Python调用C接口,读取同一双原子模型的能量、坐标和完整原子力。
阅读本篇目录
在LAMMPS输入里调用Python函数,与从外部Python脚本控制LAMMPS,是两个方向。本篇把两条路径放在同一个小体系中,便于检查参数、返回值和实际原子力。
1 准备并运行#
下载完整输入、实算数值和运行脚本,在新目录操作:
unzip lammps-optional-interfaces-wave298-*.zip
cd lammps-optional-interfaces-wave298
bash preview.sh
sbatch run.slurm
squeue -u "$USER"
preview/先重画随包参考数据。作业会在需要时运行bash build.sh构建独立环境,再运行bash run.sh完成原生计算、提取和绘图;已有预览会保留。完成后查看native-results/、results/和plots/,不必再次运行bash run.sh。需要重做时换新解压目录。
这份模板申请P100分区中的8个CPU核心和一张显卡;独立构建使用8核,双原子接口计算使用CPU,没有GPU计算内核或GPU加速比。在自己已分配的相容资源内,也可依次运行bash build.sh和bash run.sh。
这里的可选构建位于自己的runtime/,不覆盖公共LAMMPS模块。环境为LAMMPS30Sep2026、GNU13.3、Python3.12.14、MDI1.4.26、KIM-API2.4.2和libcurl8.21.0,采用串行共享库。复用集群已有的CPU依赖库,首次构建需要访问固定版本的官方源码。普通LAMMPS模块不一定启用了PYTHON、MDI或KIM,不能仅看版本号就判断可用。
2 先看实际结构和结果#
本例是40 Å周期盒中的两个Ar原子,第一原子坐标为(20,20,18) Å,第二原子先为(20,20,22) Å,再改成(20,20,22.2) Å。相距4.0和4.2 Å,彼此之外没有截断内的周期镜像。
使用同一组Lennard-Jones参数:ε=0.0104 eV、σ=3.4 Å、截断8.15 Å,不作能量平移。它来自KIM-API2.4.2的编程示例,用于理解接口,不是对真实氩物性的精度推荐。
| 距离 / Å | 势能 / eV | 下方原子的+z方向力 / eV·Å⁻¹ |
|---|---|---|
| 4.0 | −0.00977216275313524 | +0.00578235848440572 |
| 4.2 | −0.00841273649185532 | +0.00731112332477757 |
两个原子的力大小相等、方向相反。正号表示下方原子受力朝向上方原子;这里给出的是固定构型的零步能量与力,不是MD轨迹、温度或扩散结果。

灰线是独立LJ解析公式,彩色点是四条接口实际得到的两个构型;点重合表示数值一致,不是把解析曲线当成一条MD轨迹。
3 在LAMMPS输入中注册函数#
先看完整输入和函数:
cat inputs/in.python
cat callbacks.py
cat native-results/python/python-results.dat
完整输入已经包含建盒、原子、质量、势函数和两次零步求值。核心部分如下:
variable r equal 4.0
variable pyE python energy_reference
python energy_reference input 1 v_r return v_pyE format ff file callbacks.py
variable pyF python force_reference
python force_reference input 1 v_r return v_pyF format ff exists
python energy_reference invoke logreturn
python force_reference invoke logreturn
file载入Python文件,exists使用已经载入的另一函数,invoke立即调用并输出返回值。format ff表示一个浮点输入和一个浮点返回值。改变原子坐标后,输入把r更新到4.2,再次求值。
def energy_reference(r):
x = (3.4 / r) ** 6
return 4 * 0.0104 * (x * x - x)
def force_reference(r):
x = (3.4 / r) ** 6
return 24 * 0.0104 / r * (x - 2 * x * x)
这些函数用于独立比较。LAMMPS的力仍由pair_style lj/cut原生计算;返回一个Python数值并不会自动把它施加到原子上。python source here还实际执行了一段独立Python语句,结果可在native-results/python/python-source-called.txt查看。
4 从外部Python控制同一个共享库#
cat python_ctypes_driver.py
cat native-results/ctypes/ctypes-results.json
cat results/interface-values.csv
本例使用Python标准库ctypes调用官方C接口。脚本依次创建LAMMPS实例、送入完整输入、读取势能及六个力分量,再写入新坐标并重新求值,最后关闭实例。
关键调用是lammps_open_no_mpi、lammps_commands_string、lammps_get_thermo、lammps_gather_atoms、lammps_scatter_atoms和lammps_close。指针返回值要设为c_void_p,势能返回值要设为c_double;漏设类型可能导致指针截断或错误数值。
共享库路径由运行脚本明确指定为本次runtime/build/liblammps.so。它先于其他依赖目录参与动态链接,嵌入式Python也使用与编译时相同的Python前缀。不要把其他版本的共享库、Python包装层或解释器混用。
5 换成自己的计算#
先在原生命令行中确认输入能独立运行,再把需要扫描的坐标或参数交给外部脚本。输入文件、元素、势函数、单位和并行构建要一起核对。本例只有两原子和单进程,不代表多MPI进程中的数组分布、线程并发和回调开销已经适用于大体系。