科研科学计算高性能计算【免费下载链接】lammpsPublic development project of the LAMMPS MD software package项目地址https://gitcode.com/gh_mirrors/la/lammps点击查看免费下载fix python/invoke是 LAMMPS PYTHON 包提供的一个特殊 fix它允许你在模拟运行过程中每隔 N 个时间步自动调用一个预先定义好的 Python 函数。读透本文你将掌握两种回调时机post_force与end_of_step的语义区别、回调函数的编写规范含通过指针回连 LAMMPS 的方法、该 fix 在源码层面的调用链GIL 加锁、PyCapsule 指针传递、compute 步长注册并能直接复用仓库自带的完整示例脚本完成自己的开发。命令语法与参数官方文档doc/src/fix_python_invoke.rst给出的完整语法为fix ID group-ID python/invoke N callback function_name各参数含义如下参数说明IDfix 的唯一标识符此 fix 内部并不使用它group-ID目标原子组此 fix 内部并不使用它可任意填写惯例写allpython/invoke本 fix 的样式名N执行周期每 N 个时间步调用一次回调必须为正整数callback回调时机取值为post_force或end_of_stepfunction_namePython 回调函数的函数名必须已存在于当前 Python 解释器的全局作用域中其中两种回调时机的语义为post_force 每 N 个时间步、在原子受力计算force computation完成之后回调end_of_step 每 N 个时间步、在时间步末尾回调。从源码可以确认参数校验逻辑构造函数中要求参数总数恰好为 6否则报Illegal fix python/invoke commandN解析后必须大于 0且callback只接受post_force与end_of_step两个字符串任何其它取值都会触发Unsupported callback name for fix python/invoke错误。这些检查位于 src/PYTHON/fix_python_invoke.cpp。值得注意的是ID和group-ID虽然出现在语法中但实现里完全忽略它们从 fix_python_invoke.h 的类定义看FixPythonInvoke类只保存了lmpPtr、pFunc、selected_callback、nvalid等成员没有任何与组或 fix ID 相关的状态。因此输入脚本中写fix pf all python/invoke ...里的all只是一个占位写法。官方文档示例定义回调并注册两个周期文档给出的最小完整示例如下它演示了如何在输入脚本中用python命令内联定义两个回调函数并分别以两种时机、每 50 步注册一次python post_force_callback here from lammps import lammps def post_force_callback(lammps_ptr, vflag): lmp lammps(ptrlammps_ptr) # access LAMMPS state using Python interface python end_of_step_callback here def end_of_step_callback(lammps_ptr): lmp lammps(ptrlammps_ptr) # access LAMMPS state using Python interface fix pf all python/invoke 50 post_force post_force_callback fix eos all python/invoke 50 end_of_step end_of_step_callback示例中有几个关键点回调函数的签名由回调时机决定。post_force回调接收两个参数第一个是 LAMMPS 指针对象第二个是vflag整型对应该 fix 被触发时的计算标志end_of_step回调只接收 LAMMPS 指针一个参数。指针对象用于回连 LAMMPS。回调的第一个参数是一个封装了LAMMPS *的指针对象在 Python 侧通过from lammps import lammps导入模块后以lammps(ptrlammps_ptr)构造接口实例随后可用完整的 LAMMPS 库接口查询或操作模拟状态例如extract_global、extract_compute、set_系列函数等。函数必须位于全局作用域。回调函数必须定义在嵌入式 Python 解释器的 main__main__模块全局作用域中。可以用python ... here内联定义如上也可以从其它 Python 模块导入如果 LAMMPS 本身是由 Python 通过库接口驱动的驱动端解释器中定义的函数同样可被找到。从 C 实现看这一全局作用域要求构造函数通过PyImport_AddModule(__main__)获取 main 模块再用PyObject_GetAttrString(pyMain, fname)按名字查找函数找不到即报Could not find Python function错误见 fix_python_invoke.cpp。这也意味着嵌套在其它函数内部的定义、或以import之外的方式注入的名字都不会被找到。完整实战示例examples/python/in.fix_python_invoke仓库提供了可直接运行的完整输入脚本 examples/python/in.fix_python_invoke它搭建了一个 4000 原子的 3D Lennard-Jones 熔化体系并同时启用两种回调每 50 步打印一次当前时间步# 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 1.0 velocity all create 3.0 87287 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 python end_of_step_callback here from __future__ import print_function from lammps import lammps def end_of_step_callback(lmp): L lammps(ptrlmp) t L.extract_global(ntimestep) print(### END OF STEP ###, t) def post_force_callback(lmp, v): L lammps(ptrlmp) t L.extract_global(ntimestep) print(### POST_FORCE ###, t) fix 1 all nve fix 2 all python/invoke 50 end_of_step end_of_step_callback fix 3 all python/invoke 50 post_force post_force_callback thermo 50 run 250配套的运行日志examples/python/log.27Nov18.fix_python_invoke.g.1记录了该脚本在单核下的实际输出可用于验证回调行为是否符合预期。脚本中的细节值得注意neigh_modify every 20 delay 0 check no控制邻居列表更新策略与回调本身无关但体现了典型的熔化模拟配置两个回调都通过extract_global(ntimestep)读取全局时间步并print。由于该脚本在单核下运行每个打印只出现一次多核运行时每个 MPI 进程都会执行本地副本的回调详见后文并行运行时注意事项。源码解析回调是如何被调度的理解 src/PYTHON/fix_python_invoke.cpp 的实现能澄清这个 fix 的几个关键设计1. 回调时机的注册——setmask()机制setmask()直接返回selected_callback即POST_FORCE或END_OF_STEP位掩码LAMMPS 的 modify 框架据此决定在时间步生命周期的哪个阶段调用该 fix。此外setup(int vflag)中当选择了post_force时会转调post_force(vflag)这保证初始化阶段的受力计算也会触发回调逻辑。2. 步长周期——nextvalid()与 compute 注册构造函数与init()中都会计算nvalid nextvalid()公式为(ntimestep/nevery 1)*nevery即下一个能被nevery整除的步并调用modify-addstep_compute_all(nvalid)把所有 compute 的调用步对齐到该值。源码注释解释了原因Python 回调内部可能触发 compute 求值而 LAMMPS 无法预先知道会触发哪些 compute因此统一把它们都注册进来避免步长不整除导致的错误。init()中的重新注册则针对minimize之后ntimestep被重置的场景——如果nvalid update-ntimestep说明之前发生过能量极小化需要重新对齐。3. 实际回调——GIL 与 PyObject_CallFunction两个回调入口post_force(int vflag)和end_of_step()的骨架一致见 fix_python_invoke.cppvoid FixPythonInvoke::post_force(int vflag) { if (update-ntimestep % nevery ! 0) return; // python code may invoke computes so wrap with clear/add modify-clearstep_compute(); PyUtils::GIL lock; char fmt[] Oi; PyObject * result PyObject_CallFunction((PyObject*)pFunc, fmt, (PyObject*)lmpPtr, vflag); if (!result) { PyUtils::Print_Errors(); error-all(FLERR,Fix python/invoke post_force() method failed); } ... }要点周期判断update-ntimestep % nevery ! 0时直接返回post_force每个时间步都会被 modify 框架调到但只有落在 N 的整数倍步才真正执行回调。GIL 加锁PyUtils::GIL是一个 RAII 包装类定义于 src/PYTHON/python_utils.h构造时PyGILState_Ensure()、析构时PyGILState_Release()保证每次进入 CPython API 前正确持有全局解释器锁这对嵌入式解释器在多线程/MPI 环境中的正确性至关重要。参数格式串post_force用Oi格式传指针对象 整型 vflagend_of_step用O只传指针对象。这与前面回调签名要求一一对应。指针封装构造函数中lmpPtr PyCapsule_New((void *)lmp, nullptr, nullptr)即 LAMMPS 指针是以 PyCapsule 形式传给 Python 的Python 侧lammps(ptr...)正是读取这个 Capsule 还原出 C 实例。错误处理若 Python 函数抛出异常导致result为空先打印 Python 侧异常PyUtils::Print_Errors()调用PyErr_Print()后PyErr_Clear()再以Fix python/invoke post_force() method failed或... end_of_step() method failed终止运行。重要警告回调中不要执行输入脚本命令官方文档特别警告虽然可以从回调中通过库函数访问 LAMMPS 状态但尝试在其中执行输入脚本命令即lmp.command(...)/lmp.file(...)最好情况是不生效最坏情况会导致未定义行为。源码层面的佐证是python命令文档doc/src/python.rst明确说明当 Python 函数在时间步中间例如被fix python/invoke每步调用触发时无法像在两次run之间那样安全地执行任意输入脚本命令。fix_python_invoke.cpp 中用modify-clearstep_compute()包裹回调的注释python code may invoke computes so wrap with clear/add也表明回调上下文是一个受限的、需要特殊保护的时间步中段环境。因此fix python/invoke回调的合理用途是查询状态extract_global、extract_compute、extract_atom等、写入外部文件或调用不涉及完整命令流的库接口而不是驱动run、pair_style这类命令——后者的正确用法是 python 命令的invoke模式在输入脚本流程中显式调用而不是嵌在时间步中间的回调里。重启、输出与运行控制行为官方文档明确了该 fix 的静默属性重启文件不向二进制重启文件写入任何该 fix 的信息重启后需重新创建 fix 并重新定义/加载 Python 函数fix_modify所有fix_modify选项对该 fix 均无意义输出该 fix 不存储任何全局或逐原子量无法通过thermo/compute/variable等输出机制访问run start/stop其任何参数都不能用作run命令的start/stop关键词能量极小化在minimize期间不会被调用与源码中init()对 minimize 后步长重新对齐的逻辑相呼应。构建前提PYTHON 包与 CMake 构建该 fix 属于 PYTHON 包只有编译时启用了该包的 LAMMPS 才可用。从仓库现状看构建方式需要注意一个文档与代码的差异原始文档提到启用该功能的设置位于lib/python/Makefile.lammps参见lib/python/README但当前仓库中已不存在lib/python/目录src/PYTHON/Install.sh 明确提示The PYTHON package no longer supports the legacy build system. Please build LAMMPS with CMake instead.也就是说当前版本应使用 CMake 构建。CMake 侧的实际逻辑在 cmake/Modules/Packages/PYTHON.cmakefind_package(Python COMPONENTS Interpreter) ... find_package(Python REQUIRED COMPONENTS Interpreter Development) target_link_libraries(lammps PRIVATE Python::Python) target_compile_definitions(lammps PRIVATE -DLMP_PYTHON)即启用 PYTHON 包后CMake 会查找系统中的 Python需要解释器 开发头文件/库把 LAMMPS 与Python::Python链接并定义LMP_PYTHON宏来编入src/PYTHON/下的源码。典型配置命令形如cmake -BLAMMPS_build -BLAMMPS_build/pymodules -GLammps -DCMAKE_BUILD_TYPERelease -DLAMMPS_KSPACEpack -DLAMMPS_PACKAGEpython -DLAMMPS_BUILD_OMPON以-DLAMMPS_PACKAGEpython打开该包若回调中要使用from lammps import lammps回连 LAMMPS还需按 python/lammps 模块的构建说明生成 Python 绑定模块且可执行文件与共享库需由同一份源码构建以保持一致。另一个来自 python 命令文档 的限制值得留意如果回调代码要import lammps模块那么嵌入式解释器和 LAMMPS 共享库必须链接到同一个 Python 运行时若你的 Python 解释器是静态链接的文档指出 Conda 环境有时如此加载 LAMMPS 共享库会创建第二个隐藏的__main__模块导致之前定义的全局函数和变量不可见。并行运行时注意事项与python命令的说明一致使用fix python/invoke在 MPI 并行下运行时有三点每个 MPI 进程都会执行自己的回调副本。回调里的print会输出 P 份P 为进程数且可能交错出现。示例脚本中的打印在多核下会重复这是正常现象回调内 import 的 Python 模块会由每个进程从磁盘加载。大规模并行时这可能成为瓶颈某些超算甚至禁止 Python 从磁盘加载模块需要预先构建好包含所需模块的 Python 库再链接 LAMMPS若回调调用需要全局通信的库函数例如触发涉及 MPI_Allreduce 的操作必须保证所有进程的回调都发起同样的调用否则可能出现死锁。与 python 命令的分工fix python/invoke与 python 命令 同属 PYTHON 包但职责不同可配合使用python命令fix python/invoke触发时机输入脚本处理流程中invoke、变量求值模拟运行中每 N 步典型用途复杂循环、条件逻辑、调用run等命令周期性采样状态、外部联动可否执行输入脚本命令两次run之间可以不建议最好情况不生效最坏未定义行为参数传递input/format/return关键词定义固定为指针post_force时的 vflag一个常见的组合模式是用python source/python name ... file xxx.py加载共享的回调函数文件再用一条或多条fix ... python/invoke以不同周期、不同时机注册其中多个函数从而在一个输入脚本中集中管理所有 Python 逻辑。小结fix ID group-ID python/invoke N callback function_nameID 与 group-ID 被忽略N 为回调周期callback 取post_force受力计算后回调附带 vflag 参数或end_of_step步末回调回调函数须定义在嵌入式解释器__main__全局作用域第一个参数是指向 LAMMPS 的 PyCapsule 指针通过lammps(ptr...)还原为库接口实例源码上回调在 GIL 保护下经PyObject_CallFunction触发并用clearstep_compute/addstep_compute保护可能受扰的 compute 步长该 fix 不参与重启、输出与 fix_modify不在minimize中触发当前版本请使用 CMake-DLAMMPS_PACKAGEpython构建旧版lib/python/Makefile.lammps流程已废弃。可继续深入的文件src/PYTHON/fix_python_invoke.cpp、examples/python/in.fix_python_invoke、cmake/Modules/Packages/PYTHON.cmake、doc/src/python.rst。赞分享科研科学计算高性能计算【免费下载链接】lammpsPublic development project of the LAMMPS MD software package项目地址https://gitcode.com/gh_mirrors/la/lammps点击查看免费下载相关推荐LAMMPS fix evaporate 命令详解周期性删除原子模拟溶剂蒸发与干燥过程LAMMPS fix evaporate 命令详解周期性删除原子模拟溶剂蒸发与干燥过程 fix evaporate 是 LAMMPSLarge scale科研科学计算高性能计算LAMMPS fix adapt 命令完全指南在模拟过程中动态自适应力场参数与原子属性LAMMPS fix adapt 命令完全指南在模拟过程中动态自适应力场参数与原子属性 导读 fix adapt 是 LAMMPS 中用于在分子动力学MD科研科学计算高性能计算CubeFS 部署依赖清单从 gcc-c 到 Kafka/Consul 的版本要求与底层原理解析CubeFS 部署依赖清单从 gcc c 到 Kafka/Consul 的版本要求与底层原理解析 导读 本文是 CubeFS 集群部署前的前置检查清单科研科学计算高性能计算上一篇HS2-HF_PatchHoney Select 2终极增强补丁完整安装与使用指南下一篇Visual Studio Code JavaScript 扩展入门指南ESLint、代码片段与路径/npm IntelliSense 实战创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考