LAMMPS fix python/move:用 Python 脚本实现自定义原子运动与时间积分
科研科学计算高性能计算【免费下载链接】lammpsPublic development project of the LAMMPS MD software package项目地址https://gitcode.com/gh_mirrors/la/lammps点击查看免费下载本文围绕 LAMMPS 的fix python/move命令展开说明如何在分子动力学运行中从 Python 脚本动态定义原子的运动/位置更新方式。读完后你将掌握该 fix 的完整命令语法、Python 模块文件的类接口模板、三个官方示例含 NVE 重实现与 NumPy 性能优化的完整用法以及该 fix 在 C 侧的模块加载、GIL 管理与积分回调机制从而能够把自定义积分器、特殊位置更新逻辑以脚本形式接入 LAMMPS 运行流程。定位与适用场景fix python/move提供了一种方式在 MD 运行过程中原子如何被移动由从文件加载进 LAMMPS 并执行的 Python 脚本代码定义且执行时机与其他可在积分步骤中触发的 fix 相同。官方文档原文见 doc/src/fix_python_move.rst。它典型用于两类场景复杂的位置更新实现内置 fix 无法表达的、依赖每步状态的位置/速度修改逻辑修改后的时间积分方法重写积分方案例如自定义 Verlet 变体、混合步长策略而不必修改 C 源码。需要明确其性能预期由于 Python 是解释型语言该 fix 的执行速度通常明显慢于对应的 C 实现在特定情形下通过有效使用 NumPy对 LAMMPS 内存零拷贝的向量化操作可以将性能损失控制在可接受范围内。官方示例 examples/python/README.fix_python_move 即以此为主题演示。命令语法与示例语法形式继承自原文档fix python/move pymodule.CLASS其中pymodule.CLASS的含义是使用模块/文件pymodule中的类CLASS来计算原子如何移动。原文档给出的两个示例fix 1 all python/move py_nve.NVE fix 1 all python/move py_nve.NVE_OPT即加载py_nve.py模块并分别实例化其中的NVE或NVE_OPT类作为积分器。Python 模块文件的接口要求Python 模块文件必须以下列代码开头原文档模板与 examples/python/py_nve.py 的实际结构一致from __future__ import print_function import lammps import ctypes import traceback import numpy as np # class LAMMPSFix(object): def __init__(self, ptr, group_nameall): self.lmp lammps.lammps(ptrptr) self.group_name group_name # class LAMMPSFixMove(LAMMPSFix): def __init__(self, ptr, group_nameall): super(LAMMPSFixMove, self).__init__(ptr, group_name) # def init(self): pass # def initial_integrate(self, vflag): pass # def final_integrate(self): pass # def initial_integrate_respa(self, vflag, ilevel, iloop): pass # def final_integrate_respa(self, ilevel, iloop): pass # def reset_dt(self): pass任何实现新原子运动功能的类都必须继承LAMMPSFixMove类并按需覆写上述方法。各回调的语义与 C 侧 src/PYTHON/fix_python_move.h 中的虚函数声明一一对应方法触发时机init()fix 初始化阶段run/minimize开始前的设置阶段initial_integrate(vflag)每个 timestep 积分的前半段力已计算后vflag指示是否需要更新速度final_integrate()每个 timestep 积分的后半段initial_integrate_respa(vflag, ilevel, iloop)使用fix respa多级时间步时各 level/loop 的初始积分final_integrate_respa(ilevel, iloop)fix respa各 level/loop 的收尾积分reset_dt()步长改变如reset命令或 RESPA 层间切换时需要重置步长相关缓存C 侧对回调掩码的声明印证了这套触发点见 src/PYTHON/fix_python_move.cppint FixPythonMove::setmask() { int mask 0; mask | INITIAL_INTEGRATE; mask | FINAL_INTEGRATE; mask | INITIAL_INTEGRATE_RESPA; mask | FINAL_INTEGRATE_RESPA; return mask; }官方示例用 Python 重实现 NVEexamples/python目录提供了完整的 melt熔化示例用python/move替换默认 NVE 积分器。三个输入脚本共享同一套 LJ 熔化体系units lj、atom_style atomic、lattice fcc 0.8442、10×10×10 的 box、pair_style lj/cut 2.5区别仅在于 fix 一行。基线版examples/python/in.fix_python_move_nve_melt# 3d Lennard-Jones melt units lj atom_style atomic lattice fcc 0.8442 region box block 0 10 0 10 0 10 create_box 1 box create_atoms 1 box mass * 1.0 velocity all create 3.0 87287 loop geom pair_style lj/cut 2.5 pair_coeff 1 1 1.0 1.0 2.5 neighbor 0.3 bin neigh_modify every 20 delay 0 check no fix 1 all python/move py_nve.NVE thermo 50 run 250关键数据访问方式示例通过self.lmp.numpy.extract_atom(...)获取mass、type、x、v、f等数据得到的是直接指向 C 端内存的 numpy 视图——无需拷贝即可用 numpy 操作原地修改 LAMMPS 的原子数组这是 Python 集成中避免性能陷阱的核心手段见 examples/python/README.fix_python_move。examples/python/py_nve.py 中实现了三个类分别演示不同层次的用法NVE逐原子 Python 循环的标准 NVE 实现。init()中缓存dt与dtf 0.5 * dt * ftm2v其中ftm2v是把力换算成速度增量的单位因子通过self.lmp.extract_global(ftm2v)获取随units不同而不同initial_integrate执行半步力更新加整步位移final_integrate执行另一半步力更新for i in range(nlocal): dtfm self.dtf / mass[int(atype[i])] v[i,:] dtfm * f[i,:] x[i,:] self.dtv * v[i,:]注意通过self.lmp.extract_setting(nlocal)获取本 rank 拥有的原子数只对[:nlocal]范围做本地积分——这是多进程并行时的正确性要点。NVE_Opt对应 in.fix_python_move_nve_melt_opt同样的算法但改为 NumPy 向量化——用np.take(mass, atype[:nlocal])一次算出所有原子的dtfm数组按坐标分量整体更新。README 指出尽管仍比原生fix nve慢得多但简单代码转换即可带来显著提速。NVE_Group对应 in.fix_python_move_nve_melt_group只在 grouphalfregion half block 0 5 0 10 0 10定义的半块区域内做 NVE 积分。实现方式是取mask self.lmp.numpy.extract_atom(mask)用位与运算mask[i] self.group_mask过滤原子group 的 bit 位下标通过self.lmp.available_ids(group).index(self.group_name)查得再1 group_index构造掩码。C 侧工作原理模块加载与类实例化fix python/move在构造时完成 Python 侧的全部准备工作src/PYTHON/fix_python_move.cpp设置dynamic_group_allow 1允许该 fix 的动态 group与time_integrate 1声明这是一个时间积分器调用python-init()初始化内嵌 Python 解释器随后通过PyUtils::GIL lock;获取 GILGIL 的 RAII 封装见 src/PYTHON/python_utils.h把当前工作目录.追加进PYTHONPATH因此脚本中的import py_nve可以找到位于输入脚本同目录下的py_nve.py按最后一个.拆分arg[3]得到模块名与类名PyImport_ImportModule加载模块PyObject_GetAttrString取出类对象。加载失败时报错Loading python integrator module failure类不存在时报Could not find integrator class ... in module ...通过PyCapsule_New((void *)lmp, nullptr, nullptr)把 LAMMPS 主对象指针打包成 Python 可见的胶囊对象再PyObject_CallFunction(py_move_type, (char *)O, ptr)调用类构造函数完成实例化。这里有一个值得注意的实现细节C 侧只传入 LAMMPS 指针这一个参数group_name依赖 Python 类构造函数签名中的默认值。这就是 py_nve.py 中NVE_Group把默认值写成group_namehalf的原因——类自身声明默认值与输入脚本中 fix 所在的 group 约定一致。Python 端拿到的ptr正是python/lammps包的入口lammps.lammps(ptrptr)用它构造出完整的lammps对象从而可以使用extract_global见 python/lammps/core.py、extract_setting、available_ids以及numpy子模块的extract_atom见 python/lammps/numpy_wrapper.py等 API。积分回调的转发此后每个积分阶段的 C 虚函数都只是一层薄转发加 GIL 锁、PyObject_CallMethod调用同名 Python 方法、失败时PyUtils::Print_Errors()打印 Python 异常并抛出对应错误如Fix python/move initial_integrate() method failed。以initial_integrate为例fix_python_move.cppvoid FixPythonMove::initial_integrate(int vflag) { PyUtils::GIL lock; PyObject * result PyObject_CallMethod((PyObject*)py_move, (char *)initial_integrate, (char *)i, vflag); if (!result) { PyUtils::Print_Errors(); error-all(FLERR,Fix python/move initial_integrate() method failed); } Py_CLEAR(result); }RESHA相关回调则以iii/ii格式字符串传入vflag, ilevel, iloop等整型参数。析构函数中Py_CLEAR(py_move)释放 Python 对象引用。与 fix python/invoke 的区别同目录还有 src/PYTHON/fix_python_invoke.cpp它面向的是按每N步在post_force或end_of_step时机调用__main__模块里的某个 Python 函数而python/move是专职的、与积分器生命周期绑定的类接口。两者可互为补充文档的 Related commands 部分也把fix python/invoke列为相关命令。状态保存与输出行为以下行为直接继承自官方文档说明使用时需知晓restart不向 binary restart 文件 写入任何关于该 fix 的信息fix_modifyfix_modify 的选项对该 fix 均无意义输出该 fix 不存储任何全局或每原子量因此 output commands 无法访问其内部状态若需观测 Python 积分器内部变量需自行在 Python 侧写文件或使用其他机制run start/stop该 fix 的参数不能用于 run 命令的start/stop关键词minimize在 能量最小化 期间不会调用该 fix默认该 fix 无额外默认参数。性能表现参考仓库中保留的示例运行日志4 MPI 进程、4000 原子、250 步直观体现了 Python 积分器的开销分布。基线NVE版examples/python/log.7Aug25.fix_python_move_nve_melt.g.4中 Modify 阶段占去 90.13% 的总时间整机性能约 257 timesteps/s而 NumPy 优化版NVE_Optexamples/python/log.7Aug25.fix_python_move_nve_melt_opt.g.4中 Modify 阶段占比降至约 20%Pair/Neigh/Comm 的固定开销重新成为主要成分。这组数据印证了文档中通过有效使用 NumPy 可以限制性能惩罚的说法同时也说明 Python 版与原生 C 积分器之间仍存在数量级的差距该 fix 更适合算法开发、调试与小规模体系。单元测试 unittest/force-styles/tests/fix-timestep-python_move_nve.yaml 则以fix test all python/move py_nve.NVE作为 post_command对 fourmol 体系的原子位置/速度做逐值回归验证保证了 Python NVE 与参考数据的一致性。构建前提与相关命令该 fix 属于PYTHON package只有在 LAMMPS 构建时启用了该 package 才可用详见 Build package 页面package 源码位于 src/PYTHON/含fix_python_move.cpp、python_impl.cpp等Python 侧依赖lammps包位于 python/lammps/与numpy脚本通过self.lmp lammps.lammps(ptrptr)与内嵌解释器对接相关命令fix nve本 fix 通常用于替代或对照的对象、fix python/invoke周期性回调式 Python 接口。进一步阅读路径内容路径命令文档原文doc/src/fix_python_move.rstPython 模块示例NVE / NVE_Opt / NVE_Groupexamples/python/py_nve.py三个输入脚本in.fix_python_move_nve_melt、in.fix_python_move_nve_melt_opt、in.fix_python_move_nve_melt_group示例说明examples/python/README.fix_python_moveC 实现src/PYTHON/fix_python_move.cpp、src/PYTHON/fix_python_move.h、src/PYTHON/python_utils.h回归测试unittest/force-styles/tests/fix-timestep-python_move_nve.yaml赞分享科研科学计算高性能计算【免费下载链接】lammpsPublic development project of the LAMMPS MD software package项目地址https://gitcode.com/gh_mirrors/la/lammps点击查看免费下载相关推荐LAMMPS fix planeforce 详解强制原子约束在指定平面内运动的实现原理与用法LAMMPS fix planeforce 详解强制原子约束在指定平面内运动的实现原理与用法 fix planeforce 是 LAMMPS 中用于运动学约束科研科学计算高性能计算LAMMPS fix nve 命令详解NVE 微正则系综时间积分的实现原理与实战指南LAMMPS fix nve 命令详解NVE 微正则系综时间积分的实现原理与实战指南 本文基于 LAMMPS 官方文档 fix nve 命令页 doc/sr科研科学计算高性能计算LAMMPS Python 示例脚本全解析用 Python 驱动、操控与可视化分子动力学模拟LAMMPS Python 示例脚本全解析用 Python 驱动、操控与可视化分子动力学模拟 LAMMPS 官方在 python/examples 目录中提供科研科学计算高性能计算上一篇三步快速解锁网盘高速下载终极直链解析工具完整指南下一篇LinkSwift九大网盘直链下载助手的终极技术指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考