资讯详情

LAMMPS fix external 完全指南:通过库接口在指定时间步施加外部力、能量与应力

📅 2026/10/16 8:48:52 | 华诺云谱 👁 阅读
LAMMPS fix external 完全指南:通过库接口在指定时间步施加外部力、能量与应力
科研科学计算高性能计算【免费下载链接】lammpsPublic development project of the LAMMPS MD software package项目地址https://gitcode.com/gh_mirrors/la/lammps点击查看免费下载本文以 doc/src/fix_external.rst 为骨架结合仓库源码src/fix_external.cpp、src/library.cpp、官方示例examples/COUPLE/python/example.py与单元测试unittest/c-library/test_library_external.cpp展开。读完本文你将掌握fix external的两种工作模式pf/callback与pf/array的完整语法、回调函数签名与数据类型约定、能量/维里一致性设置方法以及如何用 C/C、Fortran、Python 三种语言接口驱动 LAMMPS 实现分子动力学与外部程序的双向耦合。一、fix external 是什么fix external是 LAMMPS 提供的“反向回调”机制正常情况下 LAMMPS 作为被驱动方由输入脚本控制整个模拟流程而fix external允许外部程序通过 LAMMPS library interface 运行 LAMMPS 的 C/C、Fortran 程序或 Python 脚本在指定的时间步修改 LAMMPS 的某些属性其方式与其他 fix 完全一致——即在力积累阶段向组内原子额外注入外力。它的典型应用场景包括多尺度/多物理耦合外部代码如量子化学程序、粗粒度模型、有限元求解器计算力交给 LAMMPS 演化外部势场外部分程序按原子位置/时间计算附加力模拟自定义势能面外部控温/控压修正配合fix box/relax、fix npt等在变胞计算中注入外部维里贡献自定义热力学输出通过 fix 的全局向量向fix ave/time、equal-style 变量、自定义 thermo 输出传递外部计算量。从 src/fix_external.h 可以看到该类的核心公开数据成员是double **fexternal本处理器拥有的每个原子的附加力以及一系列set_*公开方法供外部驱动直接调用。二、命令语法与参数fix external的完整语法为fix ID group-ID external mode args其中参数说明IDfix 的标识符规则与其他 fix 命令一致group-ID施加外力的原子组只有组内原子会被加上外力external本 fix 的 style 名modepf/callback或pf/array两种模式见下两种模式的参数pf/callback args Ncall Napply Ncall 每 Ncall 步调用一次回调callback Napply 每 Napply 步将回调力施加到原子 pf/array args Napply Napply 每 Napply 步将数组中的力施加到原子典型示例fix 1 all external pf/callback 1 1 # 每一步都调用回调并立即施力 fix 1 all external pf/callback 100 1 # 每 100 步调用一次回调但每步都施加该力 fix 1 all external pf/array 10 # 外部程序填充力数组每 10 步施加一次参数校验的源码细节在 src/fix_external.cpp 的构造函数中参数被严格校验pf/callback必须恰好 6 个参数fix ID group external pf/callback Ncall Napply且Ncall、Napply都必须为正整数否则报Illegal value for ncall/napply in fix external pf/callbackpf/array必须恰好 5 个参数Napply同样必须为正未知的 mode 会报Unknown fix external mode。同时构造函数完成三件初始化工作通过FixExternal::grow_arrays(atom-nmax)分配fexternal数组并注册到 Atom 类的GROW回调src/fix_external.cpp这样原子数增长时数组会自动随之扩容将用户能量user_energy清零、用户维里user_virial[6]置零初始化可选的全局向量caller_vector。三、两种工作模式详解3.1 pf/callback 模式LAMMPS 主动“呼叫”外部程序pf/callback模式下fix 会每 Ncall 个时间步或最小化迭代步主动调用一次外部回调函数外部程序在回调中计算力并填入 fix 持有的数组随后 fix 每 Napply 步把该数组中的力加到组内每个原子上行为与 fix addforce 类似。关键设计点是如果Ncall Napply一次回调产生的力值会持续保留并在多个施力时刻被重复使用doc/src/fix_external.rst。这适合“力变化缓慢、不需要每步重算”的耦合场景能显著降低外部程序调用开销。回调函数的 C 签名如下src/fix_external.h 中定义的类型别名FnPtr完全一致void foo(void *ptr, bigint timestep, int nlocal, tagint *ids, double **x, double **fexternal);各参数含义参数含义ptr注册回调时由外部驱动提供的指针原样传回给驱动timestep当前 LAMMPS 时间步nlocal当前 MPI 进程上拥有的本地原子数ids本地原子的 ID 列表x本地原子的坐标double x[nlocal][3]fexternal需要填入的外部力double f[nlocal][3]fix 将把它加到原子力上类型说明doc/src/fix_external.rsttimestep类型为bigint定义在 src/lmptype.h默认是 64 位整数ids指向类型为tagint的数组默认是 32 位整数只有当 LAMMPS 以-DLAMMPS_BIGBIG编译时才变为 64 位。更多细节见手册 build settings 一节fexternal是由驱动返回的力。注册回调的推荐方式是调用 C 库接口函数lammps_set_fix_external_callback()src/library.cpp。该函数会校验 LAMMPS 句柄与 fix ID确认目标 fix 是 external 风格后调用FixExternal::set_callback()把函数指针与外部指针存入 fix。3.2 pf/array 模式外部程序主动“填表”pf/array模式下fix 只负责存储力数组并不回调任何函数。外部程序通过库接口直接获取数组指针并写入数值fix 每 Napply 步将数组中的力加到组内原子。公开的力数组成员名为double **fexternal;它由FixExternal类分配为(N, 3)数组其中 N 是本处理器拥有的原子数3 对应 fx、fy、fz 三个力分量doc/src/fix_external.rst。该数组的值由外部程序自行决定何时更新、更新多少。例如驱动程序可以分段运行 MD每段 1000 步在两次 run 命令之间从 LAMMPS 取回原子坐标、计算力、写入fexternaldoc/src/fix_external.rst。通过库接口lammps_fix_external_get_force(handle, id)src/library.cpp可以获得该数组指针。文档特别提醒由于领域分解并行下原子会在 MPI 进程间迁移、排序也会随邻居表重建而变化每次准备施力前都应重新调用该函数以获取最新的指针并可用lammps_extract_setting()查询当前nlocal把返回数组当作double force[nlocal][3]使用。两种模式的本质区别从 src/library.cpp 的文档注释可以提炼出二者的适用场景pf/callback适合力无法预先计算的情形——LAMMPS 在需要力的时刻主动呼叫外部代码现场计算pf/array适合力可预先算好的情形——控制权在 LAMMPS 与外部代码之间交替外部程序在 run 间隙把力写好。四、能量最小化与变胞计算能量、维里的一致性4.1 为什么必须设置能量与维里如果要在fix external施加外力的同时进行能量最小化必须设置与外力一致的势能否则最小化无法正确收敛。同理若要配合fix box/relaxfix_box_relax或 fix npt 等可变晶胞计算使用全局维里也必须同步更新doc/src/fix_external.rst。外部驱动通过调用FixExternal类的公开方法来完成void set_energy_global(double eng); // 全局势能 void set_virial_global(double *virial); // 全局维里6 个应力张量分量eng是广延量extensive应等于所有受影响原子的逐原子能量之和且必须以与当前模拟一致的能量单位提供doc/src/fix_external.rstvirial是长度为 6 的数组顺序为xx, yy, zz, xy, xz, yz单位为pressure*volume见 src/library.cpp 的lammps_fix_external_set_virial_global文档。4.2 逐原子能量与逐原子应力此外还有两组逐原子接口void set_energy_peratom(double *eng); // 逐原子能量长度 nlocal void set_virial_peratom(double **virial); // 逐原子应力double virial[nlocal][6]源码src/fix_external.cpp指出这两组方法只适用于pf/callback模式它们直接把贡献写入 fix 的逐原子累积数组eatom/vatom在pf/array模式下调用会打印警告Can only set energy/atom for fix external in pf/callback mode。而全局能量/维里两个 setter 在 src/fix_external.cpp 中注明与两种模式均兼容。4.3 并行下的全局量约定重要set_energy_global所有 MPI 进程必须以相同值调用该值会被当作 fix 的标量属性返回src/library.cppset_virial_global传入的同样必须是全 MPI 秩贡献的总和。源码在 src/fix_external.cpp 中会将其除以comm-nprocs后再存储因为 LAMMPS 内部的维里统计期望的是每个 MPI 进程各自的贡献。4.4 minimize 期间的行为FixExternal::setmask()src/fix_external.cpp在两种模式下都注册了PRE_REVERSE、POST_FORCE、MIN_POST_FORCE三个阶段因此该 fix 的力在能量最小化过程中同样被施加min_setup()/min_post_force()委托给post_force()。这意味着不要在 minimize 时另想办法绕过外力fix 已自动纳入。五、全局向量向 LAMMPS 输出外部计算结果fix external还支持一个由外部程序自定义长度的全局向量可被 LAMMPS 的输出命令访问例如用于 fix ave/time、equal-style 变量或自定义 thermo 输出doc/src/fix_external.rst。对应公开方法void set_vector_length(int n); // 设定向量长度必须在 run/minimize 之前调用 void set_vector(int idx, double val); // 设定第 idx 个分量注意事项来自 src/library.cpp 与 src/fix_external.cppset_vector_length必须在set_vector之前、且在 run/minimize 之前调用并行下所有 MPI 进程都必须以相同长度调用set_vector的idx是1-based即 1 到 N向量默认按“广延量”处理extvector 1因此如需在 thermo 输出中正确聚合请确保数值语义符合广延量约定越界索引会触发Invalid set_vector index ... in fix external错误。六、输出能力与 fix_modify 选项6.1 计算量汇总fix external提供三类可访问的计算量doc/src/fix_external.rst类型内容全局标量外部驱动设置的势能属性为“extensive”广延量全局向量自定义长度由外部程序通过lammps_fix_external_set_vector()/lammps_fix_external_set_vector_length()或 Python/Fortran 等价调用设置逐原子数组每个原子 3 个值即被施加的外部力实现上src/fix_external.cpp 的compute_scalar()返回user_energycompute_vector(n)返回caller_vector[n]grow_arrays()中把array_atom直接指向fexternalsrc/fix_external.cpp因此extract(fexternal, ...)也能对外暴露该数组src/fix_external.cpp。6.2 fix_modify energy / virial该 fix 支持 fix_modify 的energy与virial选项且默认均为 yesfix_modify energy yes把外部驱动设置的势能同时加入系统的全局势能与逐原子势能参与热力学输出与 compute pe/atom 的结果doc/src/fix_external.rst。注意该能量可能是一个“虚构量”但 minimize 需要它来一致地包含本 fix 施加的力即原子沿力的方向移动时势能确实下降fix_modify virial yes把外部程序计算的贡献加入系统全局压力与逐原子应力可通过 compute pressure进而进入 thermo 输出与 compute stress/atom 访问doc/src/fix_external.rst。对应源码构造函数中thermo_energy thermo_virial 1src/fix_external.cpp。重要提示如果你希望与外力关联的虚构势能被计入系统总势能即最小化的目标量绝不能对该 fix 禁用fix_modify energy选项doc/src/fix_external.rst。6.3 其他属性重启文件本 fix 的信息不会写入二进制重启文件因此跨重启时需要外部程序重新设置回调/数组与能量维里run start/stop该 fix 没有任何参数可与 run 命令的start/stop关键字搭配使用最小化本 fix 的力在 minimize 期间照常施加。七、源码级实现post_force 调用链剖析把整个机制落到代码上src/fix_external.cpppost_force()在每个时间步执行如下逻辑// 1. 回调触发仅在 pf/callback 模式且步数能被 Ncall 整除时调用 if ((mode PF_CALLBACK) (ntimestep % ncall 0)) (this-callback)(ptr_caller, update-ntimestep, atom-nlocal, atom-tag, atom-x, fexternal); // 2. 施力步数能被 Napply 整除时把 fexternal 加到组内原子的力上 if (ntimestep % napply 0) { double **f atom-f; int *mask atom-mask; int nlocal atom-nlocal; for (int i 0; i nlocal; i) if (mask[i] groupbit) { f[i][0] fexternal[i][0]; f[i][1] fexternal[i][1]; f[i][2] fexternal[i][2]; } // 3. 全局维里把外部程序上一次 set_virial_global 的值加入 if (vflag_global) for (int i 0; i 6; i) virial[i] user_virial[i]; }这段代码可以确认三个事实施力只针对组内原子通过mask[i] groupbit过滤所以group-ID的选择直接决定外力作用范围回调频率与施力频率解耦Ncall只控制回调调用Napply只控制施力因此Ncall Napply时一次回调的力会被复用多次力数组在施力之间不会自动清零除非外部程序自己覆盖维里按“上一步设置值”贡献user_virial由外部程序显式设置未设置则保持 0。另外注意pre_reverse()会记录eflagsrc/fix_external.cpp保证后续post_force()中逐原子能量统计开关正确传递init()在pf/callback模式下如果回调未设置会直接报错Fix external callback function not setsrc/fix_external.cpp避免出现“注册了 fix 却没注册回调”的静默失效。八、加速器变体external/kkfix external提供 KOKKOS 加速变体external/kk由 src/KOKKOS/fix_external_kokkos.cpp 实现。该变体继承自FixExternal主要差异是把fexternal数组迁移到 Kokkos 管理的设备内存构造时memory-destroy(fexternal)后重新grow_arrays()析构时destroy_kokkos从而支持在 GPU 等加速设备上运行。使用前提是 LAMMPS 以 KOKKOS 包构建具体构建方式见 src/KOKKOS 与相应文档。其余语法、回调与施力语义与标准版一致。九、三大语言接口C/C、Python、Fortran9.1 C/C 库接口函数清单fix external相关的库接口集中在 src/library.cpp原型声明在 src/library.h// 回调函数类型注意 tagint/bigint 随编译选项变化 typedef void (*FixExternalFnPtr)(void *, int64_t, int, int64_t *, double **, double **); void lammps_set_fix_external_callback(void *handle, const char *id, FixExternalFnPtr funcptr, void *ptr); double **lammps_fix_external_get_force(void *handle, const char *id); void lammps_fix_external_set_energy_global(void *handle, const char *id, double eng); void lammps_fix_external_set_energy_peratom(void *handle, const char *id, double *eng); void lammps_fix_external_set_virial_global(void *handle, const char *id, double *virial); void lammps_fix_external_set_virial_peratom(void *handle, const char *id, double **virial); void lammps_fix_external_set_vector_length(void *handle, const char *id, int len); void lammps_fix_external_set_vector(void *handle, const char *id, int idx, double val);其中lammps_set_fix_external_callback的ptr参数通常传入 LAMMPS 实例句柄本身这样回调内部才能调用上述set_energy_global等函数src/library.cpp。注意 src/library.h 中回调类型存在两个变体int64_t*或int*的ids取决于LAMMPS_BIGBIG是否启用——写外部代码时应与编译配置保持一致。9.2 Python 接口Python 包装位于 python/lammps/core.pyset_fix_external_callback(fix_id, callback, callerNone)core.py把 Python 函数包装成 C 回调Python 回调接收的参数依次为caller、ntimestep、nlocal、tagNumPy 整型数组、xNumPy 二维数组、fNumPy 二维数组直接写入 C 内存fix_external_get_force(fix_id)core.py获取力数组fix_external_set_energy_global、fix_external_set_virial_global、fix_external_set_energy_peratom、fix_external_set_virial_peratom、fix_external_set_vector_length、fix_external_set_vector一一对应 C 接口若安装了 NumPylmp.numpy.fix_external_get_force()等python/lammps/numpy_wrapper.py可直接返回 NumPy 视图。9.3 Fortran 接口Fortran 模块 fortran/lammps.f90 提供等价的类型绑定过程set_fix_external_callback、fix_external_get_force、fix_external_set_energy_global、fix_external_set_virial_global、fix_external_set_energy_peratom、fix_external_set_virial_peratom、fix_external_set_vector_length、fix_external_set_vectorlammps.f90并定义了external_callback_smallbig/external_callback_bigbig两种回调接口模板lammps.f90同样区分tagint位宽。仓库中 unittest/fortran/test_fortran_fixexternal.f90 提供了完整的 Fortran 侧测试示例。十、完整实战示例Python 驱动 LAMMPS 施加外部力以下示例改编自仓库官方示例 examples/COUPLE/python/example.py 与 examples/COUPLE/python/in.fix_external该目录的 README 说明这类例子用于演示库耦合能力物理过于简单、不代表真实问题建模。LAMMPS 输入脚本# LAMMPS input for coupling LAMMPS with Python via fix external units metal dimension 3 atom_style atomic atom_modify sort 0 0.0 lattice diamond 5.43 region box block 0 1 0 1 0 1 create_box 1 box create_atoms 1 box mass 1 28.08 velocity all create 300.0 87293 loop geom fix 1 all nve fix 2 all external pf/callback 1 1 thermo 1Python 驱动代码import lammps def callback(caller, ntimestep, nlocal, tag, x, fext): 每次回调LAMMPS 传入当前时间步、本地原子数、原子标签/坐标 fext 是 fix external 分配好的力数组NumPy 视图 直接修改其值即可把力写入 LAMMPS 的 C 数组。 print(Timestep:, ntimestep) print(Number of Atoms:, nlocal) print(Atom Tags:, tag) print(Atom Positions:, x) print(Force Additions:, fext) fext.fill(1.0) # 给每个原子施加 (1,1,1) 的恒定外力 print(Force additions after update:, fext) L lammps.lammps() L.file(in.fix_external) # 可以传任意 Python 对象给回调便于携带状态如 LAMMPS 句柄以做更多库调用 custom_object [Some data, L] L.set_fix_external_callback(2, callback, custom_object) L.command(run 100)要点回调内可直接调用L.fix_external_set_energy_global(2, eng)、L.fix_external_set_virial_global(2, vir)等为 minimize/变胞计算提供一致性运行前需确保 LAMMPS Python 包python/lammps已安装且 LAMMPS 以共享库形式构建并位于LD_LIBRARY_PATH。十一、测试验证与预期数值仓库自带针对该 fix 的完整单元测试可作为实现正确性的权威参照C 测试unittest/c-library/test_library_external.cpp 覆盖pf/callback与pf/array两条路径回调中设置全局/逐原子能量、维里及 6 分量全局向量并断言temp、pe、press、reduce 计算值与fexternal数组的精确数值Python 测试unittest/python/python-fix-external.py 以纯 Python 列表和 NumPy 数组两种方式设置逐原子能量/维里验证fix_external_get_force、extract_fix、get_thermo等接口行为Fortran 测试unittest/fortran/test_fortran_fixexternal.f90。测试中值得注意的设定回调在每个时间步把f[i][j] timestep时间步相关外力并通过lammps_fix_external_set_vector_length(handle, ext, 6) 6 次set_vector填充全局向量再以compute sum all reduce sum c_eatm c_vatm[*]聚合验证逐原子能量/应力路径——这同时演示了“外部向量接入 thermo 输出”的标准做法。十二、使用要点与常见误区小结两种模式别选错力需要现场计算用pf/callback力可预计算、控制权交替用pf/array频率语义要分清Ncall管回调、Napply管施力Ncall Napply时一次回调的力被多次复用minimize/变胞必须配能量与维里全局能量是广延量、与模拟单位一致全局维里按xx,yy,zz,xy,xz,yz顺序、stress*volume单位且并行下所有进程传总值逐原子能量/维里仅限pf/callback模式pf/array下调用只会得到警告pf/callback必须注册回调否则init()直接报错终止勿禁用fix_modify energy yes否则最小化无法把虚构势能纳入目标向量接口时序先set_vector_length再set_vector都在 run/minimize 之前且所有 MPI 进程一致调用索引从 1 开始pf/array的指针会失效原子迁移/邻居表重建后需重新lammps_fix_external_get_force()重启不保存状态本 fix 不写入重启文件续算时需要外部程序重新注册回调与能量/维里。十三、限制与默认值Restrictions无doc/src/fix_external.rstRelated commands无Default无——两种模式都必须显式给出Ncall/Napply参数fix_modify energy、virial默认均为 yes。赞分享科研科学计算高性能计算【免费下载链接】lammpsPublic development project of the LAMMPS MD software package项目地址https://gitcode.com/gh_mirrors/la/lammps点击查看免费下载相关推荐LAMMPS 库接口 Utility Functions 完全指南从镜像标志编解码到 fix external 回调与错误处理LAMMPS 库接口 Utility Functions 完全指南从镜像标志编解码到 fix external 回调与错误处理 本文聚焦 LAMMPS 库接口科研科学计算高性能计算Row-Bot MCP 集成完全指南连接外部工具与自定义能力Row Bot MCP 集成完全指南连接外部工具与自定义能力 Row Bot 是一款本地优先local first的个人 AI 助手而 MCP 集成 正gsd-core 外部作业External Job能力将长时计算异步化到 SLURM 调度器的完整实践指南gsd core 外部作业External Job能力将长时计算异步化到 SLURM 调度器的完整实践指南 导读 本文围绕 gsd coreGit. S上一篇Sandstorm性能优化终极指南10个简单方法提升容器化应用响应速度下一篇告别重复造轮子5款顶级.NET项目模板助你7天交付企业级应用创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑