LAMMPS fix graphics/periodic 命令详解:在 dump image 中叠加周期性镜像的可视化实现
LAMMPS fix graphics/periodic 命令详解:在 dump image 中叠加周期性镜像的可视化实现
本文围绕 LAMMPS 的 fix graphics/periodic 命令展开:它通过 dump image 的 fix 关键字将模拟盒边界外的周期性镜像原子与键叠加到渲染图像中,用于直观展示周期性体系的连续性。读完后你可以掌握该命令的完整语法、各关键字(xlo/xhi 等、radius、atoms、bonds)的语义与默认值、与 dump image 及 dump_modify fcolor/ftrans 的配合方式,并能从源码层面理解镜像对象的生成与渲染流程。
命令语法与关键字
fix graphics/periodic 的完整语法如下(源自 fix_graphics_periodic.rst):
fix ID group-ID graphics/periodic Nevery keyword args ...
- ID、group-ID:含义同 fix 通用命令;group-ID 决定哪些原子会被复制为周期性镜像。若要显示键的镜像,键的两端原子都必须在该 group 内。
- Nevery:每隔多少个时间步更新一次图形信息,应与配套
dump image命令的 N 参数一致,否则 LAMMPS 会报错停止。 - 其后可以追加零个或多个关键字或关键字/值对,共四类:
| 关键字 | 取值 | 作用 |
|---|---|---|
xlo, xhi, ylo, yhi, zlo, zhi |
无值 | 在主模拟盒对应方向、对应边界一侧生成整套周期性镜像 |
radius |
auto 或正数(距离单位) |
设置镜像原子的半径;auto 表示从原子类型继承 |
atoms |
yes/no |
是否显示周期性镜像原子 |
bonds |
yes/no |
是否显示周期性镜像键 |
文档给出的两条示例命令是:
fix vec all graphics/periodic 10 ylo zhi zlo yhi xlo
fix vec all graphics/periodic 1000 ylo zhi zlo yhi bonds no radius 0.5
默认值:radius = auto,atoms = yes,bonds = yes(仅当原子风格为分子体系时,否则为 no),且不启用任何方向的周期性镜像。
从源码 fix_graphics_periodic.cpp 的构造函数可以核对这些默认值与解析逻辑:atomflag 初始化为 true,bondflag 取 atom->molecular == Atom::MOLECULAR 的值,radius 初始为 -1.0(内部用负值表示 auto);Nevery <= 0 会报 "Illegal fix graphics/periodic nevery value" 错误,radius <= 0 会报 "radius must be > 0",未知关键字会直接报 "Unknown fix graphics/periodic keyword"。此外还有一个构造函数末尾的强校验:若 atom_style 不是分子体系却请求显示键镜像,会直接报 "Cannot display periodic images of bonds with non-molecular system" 错误,这正是文档中 "bonds 默认随原子风格而定" 这一行为背后的实现依据。
与 dump image 的配合:fix 关键字、fflag1/fflag2 与颜色/透明度
fix graphics/periodic 是为 dump image 的 fix 关键字设计的:它把 group 内原子和键的周期性镜像作为图形对象加入渲染内容。在 dump image 中对应的写法为(参见 dump_image.rst 语法段):
fix = fixID color fflag1 fflag2
其中 color 取 type、element 或 const 三种着色方式之一。行为要点:
- 使用
type或element着色时,镜像原子/键的颜色与主模拟盒中的对应对象一致; - 使用
const着色时,默认颜色为white,可用dump_modify viz fcolor fixID 颜色修改; - 镜像对象默认完全不透明,可用
dump_modify viz ftrans fixID 透明度调整——对镜像而言,调低透明度通常能增强"主体盒内原子 + 边界外镜像"的层次感。
两个数字标志的含义专门针对本 fix:
- fflag1:键端球帽。
0表示键两端不加球帽;1只在下端加帽;2只在上端加帽;3两端都加。文档建议:如果同时还绘制了镜像原子(atoms yes),非 0 取值是冗余的;如果只画镜像键(atoms no),取3通常是期望的效果。 - fflag2:键直径相对系数。用于相对自动选择的键直径做缩放,文档建议大多数场景取
0.0。
在渲染侧,dump_image.cpp 在每帧绘制完主体原子后遍历 dump image 登记的 compute/fix 对象,调用 iobj.fptr->image(objvec, objarray) 取出对象数组再逐个绘制;fflag1/fflag2 正是通过 dump image fix 命令存入该对象记录并在绘制键帽/直径时读取的。基类 fix.h 中 image() 的默认实现返回 0,也就是说只有实现了该虚函数的 fix 才能向 dump image 供图——fix graphics/periodic 即属于这一类。
源码剖析:镜像对象如何生成
理解这条命令最快的方式是看 FixGraphicsPeriodic::end_of_step():
- 复制份数:按六个方向标志计算
nx = 1 + pxlo + pxhi(y、z 方向同理),总网格为nx*ny*nz,其中主盒之外的份数nrep = nx*ny*nz - 1。六个关键字全部启用时即为 3×3×3 网格,主盒周围共渲染 26 份系统副本——与文档 "If all keywords are used, there will be 26 additional copies of the system rendered" 完全对应。 - 对象计数与分配:先遍历
groupbit内的局部原子统计所需对象数(每份镜像各占一份,并考虑该原子在 group 内关联的键),再memory->create出imgobjs(对象类型数组)与imgparms(每对象 8 个 double 的参数数组)。 - 坐标偏移:对每个 group 内原子,在
(ix, iy, iz)三个方向的副本上生成Graphics::SPHERE对象,坐标写作x[i][k] + i*domain->prd[k]——直接以晶格向量prd做平移。键镜像生成Graphics::BOND对象,两端原子都通过domain->closest_image()取最近镜像位置并同样加上i*prd平移;若最近镜像不在主盒内(m < 0)或另一端原子不在 group 中,则该键镜像被跳过。 - 半径:
imgparms[n][4] = 2.0 * radius,即以直径形式存储;radius为auto时由dump image侧按原子类型的adial参数继承。
另外两个值得注意的实现细节:
setmask()注册了POST_FORCE、POST_FORCE_RESPA和END_OF_STEP三类更新位(见 fix_graphics_periodic.cpp#L111-L118),并在setup()中主动触发一次end_of_step(),因此run 0之类的零步运行(如单元测试)也能立刻产出镜像数据;- 构造函数设置了
dynamic_group_allow = 1,表示该 fix 可以挂在动态 group(group ... dynamic)上,镜像集合会随 group 按频率刷新。这一能力是官方示例中"只把部分水分子画进镜像"的关键。
image() 虚函数(fix_graphics_periodic.cpp#L214-L219)只做三件事:把内部 imgobjs/imgparms 指针交给调用方并返回 numobjs,与 dump image 的取数接口一一对应。
可运行的实战脚本
仓库单元测试 fix-graphics-periodic-faces.yaml 给出了一份最小可运行组合(截取其中命令部分,用 run 0 立即渲染):
units real
atom_style full
region box block -5 5 -5 5 -5 5
create_box 2 box bond/types 1 angle/types 1 extra/bond/per/atom 2 extra/angle/per/atom 1 extra/special/per/atom 2
mass 1 15.9994
mass 2 1.008
pair_style lj/cut/coul/cut 8.0
pair_coeff 1 1 0.1553 3.166
pair_coeff 2 2 0.0 1.0
bond_style zero
bond_coeff 1 1.0
angle_style zero
angle_coeff 1 109.47
molecule water h2o.mol
create_atoms 0 random 12 34564 NULL mol water 25367 overlap 2.5
fix per all graphics/periodic 1 xlo yhi zlo
dump viz all image 1 image.png type type size 200 200 zoom 0.6 view 70 20 shiny 0.1 bond atom 0.3 box yes 0.025 fix per type 0 0
dump_modify viz backcolor gray adiam 1 0.5 adiam 2 0.3 acolor 1 blue acolor 2 red
run 0
要点:fix 只对 xlo、yhi、zlo 三个面开镜像("三面向外"式构图);dump ... fix per type 0 0 表示按原子类型着色、键不加球帽、键直径用自动值。
fix-graphics-periodic-radius-nobonds.yaml 则演示了只画镜像原子、且手动指定半径的用法:
fix per all graphics/periodic 1 ylo yhi zlo zhi bonds no radius 0.7
dump viz all image 1 image.png type type size 200 200 zoom 0.6 view 90 0 shiny 0.1 bond atom 0.3 box yes 0.025 fix per type 0 0
这里 bonds no radius 0.7 同时启用了四向 y/z 镜像,镜像原子半径固定为 0.7(距离单位),键完全交给 dump image 自己的 bond atom 0.3 在主盒内绘制。
更有代表性的生产级用法见官方示例 in.peptide-depth:溶溶五肽体系只想让"盒子下部的水 + 全部肽"参与镜像,做法是先把筛选条件写成原子变量,再创建两个 dynamic group 并按 dump 频率刷新,最后挂 fix:
group water subtract all peptide
# true for lower part of water and all peptide atoms
variable lower atom (z<$(zlo+0.4*(zhi-zlo))||gmask(peptide))
# for creating periodic extensions only for water
group lower dynamic water var lower every ${dumpfreq}
# selecting atoms for visualization
group viz dynamic all var lower every ${dumpfreq}
# add periodic replica to the left, right, and back
fix img lower graphics/periodic ${dumpfreq} xlo ylo yhi bonds no
dump viz viz image ${dumpfreq} peptide-depth-*.ppm element type &
size 800 800 zoom 1.6 view 78 10 box yes 0.02 &
shiny 0.8 fsaa yes ssao yes 2451512 0.8 &
depthcue yes 1.0 black 0.3 defocus yes 1.0 0.4 &
fix img element 0 0
这段脚本展示了 fix graphics/periodic 的三种典型能力组合:按 group 局部镜像(非全体系)、bonds no 只镜像原子、element 着色 + fflag1 0 fflag2 0 的默认键渲染,同时 Nevery(${dumpfreq})与 dump 的 N 参数严格一致。
限制与注意事项
文档 Restrictions 一节 列出的约束,结合源码可以逐条确认:
- 依赖 GRAPHICS package:只有编译时启用了 GRAPHICS 包才能使用该 fix 和
dump image。CMake 预设中,basic.cmake 把 GRAPHICS 列为ALL_PACKAGES之一,all_on/all_off预设也包含/排除了该包,可按 Build package 的说明自行控制。 - 仅支持原子与键的镜像:目前只能在各方向上复制原子和键,不支持角/二面体等其他分子项的镜像。
- body/椭球等粒子退化为球:body particles 或 ellipsoids 等"非球"粒子在本 fix 中显示为球体。
- restart 与 fix_modify:本 fix 不向二进制 restart 文件写任何信息,也没有任何
fix_modify选项适用。 - Nevery 必须与 dump 匹配:源码中
global_freq = nevery,dump image在建立fix对象记录时会校验该 fix 的更新频率与 dump 频率的兼容性,不匹配会报错,这是文档承诺的运行时约束在实现中的落点。 - 键镜像的可见性依赖 group 完整性:由
end_of_step()中的closest_image+ group mask 双重检查可知,跨盒边界的键只有当两端原子都在 group 内时才会被镜像绘制,构造 group 时容易踩坑。
相关命令
fix graphics/periodic 属于 Howto_viz 中 "Visualizing graphics provided by compute or fix commands" 一表所列的图形类 fix 家族,同一接口下还有:
- fix graphics/arrows:向量箭头(速度、力等)
- fix graphics/chunk:按 chunk 着色平面/多面体
- fix graphics/isosurface:等值面
- fix graphics/labels:文字标签与色标
- fix graphics/lines:任意折线
- fix graphics/objects:任意基本图形对象
- fix graphics/replica:副本(replica)体系的图形
- dump image:承载上述所有 fix 图形的渲染命令
其中 graphics/replica 与 graphics/periodic 名字相近但目的不同:前者面向多副本(如 UMBRELLA/REPLICA)体系,后者专门为主盒生成边界外的周期镜像。本命令自 LAMMPS 2026-02-11 版本引入(文档中标注 versionadded 11Feb2026),实现文件为 fix_graphics_periodic.h 与 fix_graphics_periodic.cpp,回归测试位于 unittest/graphics/tests/ 下两个 YAML 图像比对用例。