☰
LAMMPS 热力学输出机制详解:Thermo 类架构、四种输出样式与自定义扩展指南
2026/10/15 16:40:04 网站建设 项目流程
  • 科研
  • 科学计算
  • 高性能计算

【免费下载链接】lammps

Public development project of the LAMMPS MD software package

项目地址:https://gitcode.com/gh_mirrors/la/lammps
点击查看免费下载

本文以 doc/src/Modify_thermo.rst 为骨架,结合 src/thermo.cpp、src/thermo.h 源码与 doc/src/thermo_style.rst、doc/src/thermo_modify.rst、doc/src/thermo.rst 文档,系统梳理 LAMMPS 热力学输出(thermo output)的完整技术脉络。你将掌握:内置one/multi/yaml/custom四种输出样式的工作方式与默认行为、全部内置 thermo keyword 的含义与单位语义、thermo_modify全部选项的实战用法,以及如何在thermo.cpp中新增自定义 thermo style 与自定义 thermo keyword 的完整开发流程。

LAMMPS 在模拟过程中会周期性地把温度、能量、压力等热力学量打印到屏幕与 log 文件,这套输出机制由Thermo类实现。在动手修改或扩展它之前,先理解其整体设计,再深入每个环节,最后结合源码给出可落地的定制方案。

Thermo 类整体架构

热力学输出(thermodynamic output)的功能集中在 src/thermo.cpp 与 src/thermo.h 两个文件中:Thermo类负责计算并打印热力学信息。它由三个上层命令驱动,三者各司其职:

  • thermo 命令:控制输出频率——每 N 步输出一次,也支持用 equal-style 变量动态决定输出步。
  • thermo_style 命令:控制输出内容与格式——选择四种样式之一并(在custom下)列出要输出的 keyword 列表。
  • thermo_modify 命令:调整输出细节——丢失原子处理、警告策略、归一化、列名、数字格式、温度/压力 compute 的替换等。

从源码结构看,Thermo类对外暴露的公共接口(src/thermo.h 第 36–58 行)包括构造函数、init()、header()、footer()、compute()与evaluate_keyword(),另有lost_check()与modify_params();内部通过一组compute_*()成员函数逐一计算每个 keyword 的数值。整个输出管线可归纳为:

  1. 构造Thermo对象时解析thermo_style参数,确定样式与 keyword 列表;
  2. init()中补充动态字段(如vol)、装配每列的输出格式字符串、解析各 compute/fix/variable 引用;
  3. 每次输出时compute()调用各字段对应的compute_*()方法,把ivalue/dvalue/bivalue三个成员变量中的结果按格式化字符串写入一行文本,由 0 号 MPI rank 打印;
  4. header()/footer()在输出块首尾打印列头与 YAML 结束标记。

四种内置输出样式

src/thermo.cpp 中定义了ONELINE、MULTILINE、YAMLLINE三种行布局枚举,对应one、multi、yaml三种内置样式,加上最通用的custom共四种。每种样式本质上是一个 keyword 列表 + 一组整数/浮点默认格式 + 一个行布局,全部集中在 src/thermo.cpp 第 75–88 行:

enum { ONELINE, MULTILINE, YAMLLINE }; // style "one" static constexpr char ONE[] = "step temp epair emol etotal press"; #define FORMAT_FLOAT_ONE_DEFAULT "% -14.8g" #define FORMAT_INT_ONE_DEFAULT "%10d " // style "multi" static constexpr char MULTI[] = "etotal ke temp pe ebond eangle edihed eimp evdwl ecoul elong press"; #define FORMAT_FLOAT_MULTI_DEFAULT "%14.4f" #define FORMAT_INT_MULTI_DEFAULT "%14d" // style "yaml" static constexpr char YAML[] = "step temp ke pe ebond eangle edihed eimp evdwl ecoul elong press"; #define FORMAT_FLOAT_YAML_DEFAULT "%.15g" #define FORMAT_INT_YAML_DEFAULT "%d"

各样式语义如下:

样式等价 keyword 列表行布局默认整数格式默认浮点格式默认输出频率
onestep temp epair emol etotal press单行纯数值%10d%-14.8gthermo 0(仅在开始与结束时输出)
multietotal ke temp pe ebond eangle edihed eimp evdwl ecoul elong press多行、每行 3 个带字符串标识的量%14d%14.4f同上
yamlstep temp ke pe ebond eangle edihed eimp evdwl ecoul elong pressYAML 块(---/keywords:/data:/...)%d%.15g同上
custom用户显式列出默认同one,可由thermo_modify line改为multi/yaml同one同one同上

从thermo_style命令的默认值看(doc/src/thermo_style.rst 第 546–551 行),系统默认采用thermo_style one,而thermo命令默认是thermo 0(doc/src/thermo.rst 第 64–68 行),即只输出首尾两帧,实际应用中几乎总要显式给出输出频率。

one 样式

one打印单行热力学信息,等价于thermo_style custom step temp epair emol etotal press,行内只有数值。它在屏幕和 log 文件中最常见,适合人工快速查看。

multi 样式

multi以多行形式列出热力学量,等价于thermo_style custom etotal ke temp pe ebond eangle edihed eimp evdwl ecoul elong press。每行输出 3 个量,每个量带一个字符串标识(如E_bond、Temp),并在输出块首行打出一条虚线分隔的标题行,包含当前步号与累计 CPU 时间——其格式串定义在 src/thermo.cpp 第 90–91 行:

static constexpr char FORMAT_MULTI_HEADER[] = "------------ Step {:14} ----- CPU = {:12.7g} (sec) -------------";

yaml 样式

yaml(doc/src/thermo_style.rst 中标注为 2022 年 3 月 24 日版本新增)与one类似,但以 YAML 格式输出,便于被脚本语言与数据处理工具直接解析。由于 LAMMPS 在热力学输出之前、之后或中间还可能打印其他内容,YAML 块需要与其余输出隔离。文档给出了用正则提取的标准做法(doc/src/thermo_style.rst 第 140–142 行):

egrep '^(keywords:|data:$|---$|\.\.\.$| - \[)' log.lammps > log.yaml

从源码看,YAML 输出的头部由header()生成(src/thermo.cpp 第 387–410 行),形如:

--- keywords: ['Step', 'Temp', 'KinEng', 'PotEng', ...] data: - [0, 300.0, ...], - [100, 301.2, ...], ...

其中...由footer()在运行结束时补写(src/thermo.cpp 第 416–425 行),- [列表前缀与]闭合则是在init()装配格式串时插入(src/thermo.cpp 第 257、323 行)。提取出的 YAML 文件可进一步用Howto structured data output指南(doc/src/Howto_structured_data.rst)介绍的方法处理。

custom 样式与通配符

custom是最通用的样式:它允许用户显式列出 keyword,并且支持通配符*自动展开。在Thermo构造函数中(src/thermo.cpp 第 140–162 行),custom分支会调用utils::expand_args()对参数做通配符展开。通配符形式有四种:*(全部)、*n(1..n)、n*(n..N)、m*n(m..n),其中 N 为向量长度。例如(doc/src/thermo_style.rst 第 438–444 行):

compute myTemp all temp thermo_style custom step temp etotal c_myTemp[*] # 等价于: thermo_style custom step temp etotal & c_myTemp[1] c_myTemp[2] c_myTemp[3] & c_myTemp[4] c_myTemp[5] c_myTemp[6]

注意:对于 vector-style 变量,只允许*n或m*n形式——因为向量长度直到求值时才确定,必须显式给出上界;若指定的 n 大于实际向量长度,缺失位置输出 0(src/thermo.cpp 第 1778–1787 行compute_variable()的实现印证了这一点)。

另外,所有非custom样式在模拟盒体积会变化(domain->box_change为真)时,会自动在输出列表末尾追加vol字段,这一逻辑位于Thermo::init()(src/thermo.cpp 第 220–222 行)。

thermo keyword 全量清单

custom样式可选的关键词分门别类列于 doc/src/thermo_style.rst 第 22–98 行,同时 src/thermo.cpp 第 57–70 行的注释也完整列出了这些 keyword,二者一一对应。下表按语义分组归纳,单位由 units 命令 决定(如能量为能量单位、温度为温度单位、压力为压力单位):

类别keywords说明
时间/步进step、elapsed、elaplong、dt、time当前步、本次 run 已走步数、系列 run 起始步以来步数、步长、模拟时间
CPU/性能cpu、tpcpu、spcpu、cpuuse、cpuremain、part、timeremain本 run 已耗 CPU 秒、模拟时间/CPU 秒、步数/CPU 秒、CPU 利用率(多线程可 >100%)、预计剩余 CPU 时间、分区编号、超时剩余秒数
系统基础量atoms、temp、press、pe、ke、etotal原子数、温度、压力、总势能、动能、总能(pe+ke)
能量分项evdwl、ecoul、epair、ebond、eangle、edihed、eimp、emol、elong、etailvdW 对势能(含尾校正)、库仑对势能、对势能(evdwl+ecoul+elong)、键能、角能、二面角能、非正常角能、分子内能、长程 kspace 能、vdW 长程尾校正
守恒/耦合enthalpy、ecouple、econserve焓(etotal+press×vol)、恒温/恒压 fix 引起的累计能量变化、pe+ke+ecouple
几何/盒vol、density、lx、ly、lz、xlo、xhi、ylo、yhi、zlo、zhi、xy、xz、yz体积、质量密度、盒长、盒边界、受限三斜盒的倾斜因子
一般三斜盒avecx...cvecz(9 个)、cella、cellb、cellc、cellalpha、cellbeta、cellgamma盒三条边向量分量、晶胞常数与角度
压力张量pxx、pyy、pzz、pxy、pxz、pyz对称压力张量的 6 个分量
结构计数bonds、angles、dihedrals、impropers已定义的各类键合相互作用数
力/邻居fmax、fnorm、nbuild、ndanger力最大值(∞-范数)、力向量长度(2-范数)、邻居表重建次数、危险重建次数
外部引用c_ID、c_ID[I]、c_ID[I][J]、f_ID、f_ID[I]、f_ID[I][J]、v_name、v_name[I]compute/fix 的全局标量、向量、数组元素;equal/vector 型变量的值

几个易误解 keyword 的精确含义

  • elapsedvselaplong:elapsed是本次 run 开始以来的步数;elaplong是一系列 run(配合 run 命令 的start/stop关键字)中首个 run 以来的步数;两者都不使用时数值相同。源码中分别取ntimestep - update->firststep与ntimestep - update->beginstep(src/thermo.cpp 第 1805–1815 行)。
  • time:当前累计模拟时间。若步长恒定且未重置步号,它就是step*dt;若步长被fix dt/reset改变或步号被reset_timestep重置,则为累计值。实现见compute_time()(src/thermo.cpp 第 1826–1829 行)。
  • tpcpu/spcpu:均为“即时”性能指标,以上次输出到本次输出之间为窗口。spcpu是窗口内步数差 / CPU 秒差;tpcpu是窗口内模拟时间差 / CPU 秒差,不追踪步长变化。源码compute_tpcpu()/compute_spcpu()(src/thermo.cpp 第 1843–1897 行)用缓存的上次时刻与 CPU 值求差,正是“最近 100 步速率”语义的实现。
  • cpuuse:MPI rank 0 的 CPU 利用率百分比。单线程运行通常接近 100%;偏低说明 LAMMPS 可能阻塞在文件 I/O 或与其他进程争抢 CPU;使用 KOKKOS、INTEL、OPENMP 包多线程时可能超过 100%,理想值接近 nthreads×100%。
  • cpuremain:基于已耗时间的线性外推估计剩余 CPU 时间,仅当后续单步耗时有代表性才准确;首步输出为 0。对minimize则基于maxiter假设跑满最大迭代数。
  • timeremain:配合 timer timeout 命令 使用;计时器未启用时为 0.0,已超时为负值。文档给出了配合循环优雅退出的惯用法(doc/src/thermo_style.rst 第 328–330 行):
if "$(timeremain) < 0.0" then "quit 0"
  • ecouple与econserve:ecouple是恒温/恒压 fix 累积转移到耦合库的能量,正值表示能量被从系统取走;econserve = pe + ke + ecouple = etotal + ecouple。在 NVT、NPH、NPT 系综下econserve理想上应保持恒定。源码compute_ecouple()调用modify->energy_couple(),compute_econserve()为二者之和(src/thermo.cpp 第 2131–2145 行)。
  • fmax/fnorm:适合监控能量最小化进度。fmax是力向量的无穷范数(任一分量最大值),fnorm是全体原子力向量长度的 2-范数。
  • nbuild/ndanger:监控邻居表重建。ndanger非零时建议减小neigh_modify delay因子,避免原子在重建前移出邻居表皮距离导致漏算力。
  • cella系关键字:cella/cellb/cellc/cellalpha/cellbeta/cellgamma对应晶体的晶胞常数与角度,由受限三斜盒表示(lx,ly,lz,yz,xz,xy)推导而来。

温度/压力/势能三个隐式 compute

多个 keyword(temp、press、ke、etotal、enthalpy、pxx等)需要温度、压力或势能作为中间量。LAMMPS 启动时会自动创建三个默认 compute,等价于执行了以下命令(doc/src/thermo_style.rst 第 187–229 行):

compute thermo_temp all temp compute thermo_press all pressure thermo_temp compute thermo_pe all pe

源码中这三个 ID 以常量形式定义(src/thermo.cpp 第 95–97 行),并在parse_fields()中通过add_compute(id_temp, SCALAR)等方式登记(src/thermo.cpp 第 926–941 行)。要点:

  • ke由温度按每自由度½ kBT推算(compute_ke()中0.5 * temperature->dof * force->boltz,见 src/thermo.cpp 第 1965–1970 行)。因此更换温度 compute(thermo_modify temp)会改变动能结果——不同温度 compute 可能扣除不同的非热速度成分、计入不同的自由度(平动/转动等)。
  • pe会把设置了fix_modify energy yes的 fix 能量贡献计入(如 fix wall/lj93)。
  • etail(vdW 长程尾校正)仅在pair_modify tail开启时非零,且已包含在evdwl、epair、pe、etotal中;对应的压力尾校正也计入press与pxx等(实现见compute_evdwl()的etail/volume累加,src/thermo.cpp 第 1990–1993 行)。
  • 这些默认 compute 同样可用compute_modify调整属性,或用thermo_modify temp/press直接替换。

thermo_modify 全部选项实战解析

thermo_modify 命令 用于控制热力学信息的计算与打印细节。语法为thermo_modify keyword value ...,可用选项为lost、lost/bond、warn、norm、flush、line、colname、format、temp、press、triclinic/general。

重要注意事项:thermo_modify的选项只作用于当前已定义的thermo style;一旦后续再执行thermo_style命令,所有热力学设置(包括此前thermo_modify的修改)都会恢复默认值。因此输入脚本中若出现thermo_style命令,thermo_modify必须放在它之后。

lost / lost/bond:丢失原子的处理

lost决定每次计算热力学量时是否检查“丢失原子”及其后果。原子在非周期性边界上移出盒子、或在重排邻居前移出超过一个盒长(或子域长度)即视为丢失,后者通常源于过大步长或过大的力/速度。三个取值:

  • ignore:不检查;
  • error:检查并在首次发现时直接报错退出;
  • warn:检查并打印一次警告(仅第一次丢失时),然后继续运行。

源码中lost_check()(src/thermo.cpp 第 519–564 行)通过MPI_Allreduce统计全局原子数与警告数,lostflag决定报错(ERROR)还是警告(WARN),并同步维护atom->natoms。

lost/bond则针对成键相互作用(键、角等)中找不到成键原子时抛错的问题。默认是致命错误;但在某些场景(如气体分子从固定边界漂出盒子、一个原子先被删除)下可能希望仅警告或跳过缺失键合。三个取值同为error/warn/ignore。

warn:警告消息控制

warn控制警告消息的打印与数量。默认上限为 100,计数对整个输入文件生效,除非用thermo_modify warn reset重置。取值:

  • ignore:抑制所有警告;
  • always:不设上限,总是打印;
  • reset:将内部警告计数清零;
  • default:清零计数并把上限恢复为 100;
  • 一个数字:把上限改为该数。

典型用法(doc/src/thermo_modify.rst 第 118–123 行):平衡阶段放宽警告(可接受),到生产阶段再收紧。源码中ignore调用error->set_maxwarn(-1)、always调用set_maxwarn(0)、reset清零计数、default调用error->reset_warn()(src/thermo.cpp 第 675–690 行)。需要注意:上限同时按每进程计数与全局总计数执行,但为效率起见总计数只在有热力学输出的步更新,因此大量 MPI 进程并行时实际打印的警告数可能明显超过上限。

norm:是否按原子数归一化

norm决定各热力学量是否除以原子数:

  • yes:对广延量(随原子数缩放)归一化,如pe、ebond、enthalpy等所有能量类 keyword;
  • no:不归一化。

强度量(如temp、press)从不会被归一化。对于thermo_style custom中来自 compute/fix 的输出值,各 fix/compute 文档页会标注其是广延还是强度;来自变量公式的值一律视为强度量,若确实需要归一化可在公式中显式除以原子数(源码compute_pe()中if (normflag) dvalue /= natoms;即典型实现,src/thermo.cpp 第 1957–1961 行)。

默认值随单位制不同:lj单位为yes,real与metal为no(doc/src/thermo_modify.rst 第 300–303 行)。源码中Thermo::init()在用户未指定时按unit_style设置normvalue(src/thermo.cpp 第 209–214 行)。

flush:输出立即落盘

flush yes在每次热力学输出写到屏幕与 log 文件后立即执行 flush,确保即使 LAMMPS 中途终止,输出也已写入(默认no)。注意这不影响 OS 或设备层的缓冲,硬件故障时仍可能丢失数据。

line:输出行布局

line one|multi|yaml覆盖当前 thermo style 的行布局设置。custom样式默认按one布局输出,可用它改为multi或yaml。源码modify_params()中对line的处理直接改写lineflag(src/thermo.cpp 第 703–713 行)。

colname:自定义列头

colname更改输出列的表头文本,可多次使用:

  • colname ID string:ID为正整数表示从左数第 N 列;为负整数表示从右数(-1 即最后一列);也可以是 thermo keyword 或 compute/fix/property/variable 引用。例如:
thermo_modify colname 1 Timestep colname -2 Pressure colname f_1[1] AvgDensity
  • colname auto:让支持该特性的 fix/compute 生成更描述性的字符串——目前包括fix nvt、fix npt、fix nph、compute reduce、fix bond/react。
  • colname default:恢复默认列名(与thermo_style命令参数同约定)。default会清除此前全部设置;多个设置指向同一 keyword 时,最后一次生效;auto只覆盖用户未显式指定的列。

源码中colname分支支持整数列号(负号先换算nfield_initial + icol + 1)与 keyword 查表key2col(src/thermo.cpp 第 715–741 行),colname_auto()负责自动列名。

format:数字输出格式

format使用 C 风格 printf 格式串,有以下形式:

  • format line string:整行格式串,含 N 个字段,多字段时须用引号包裹;
  • format int string/format float string:应用到所有整数/浮点输出值;
  • format ID string:作用于指定列,ID 规则同colname(正整数、负整数、keyword 或 c/f/v 引用);
  • format ID-range string:支持范围如3*6、*、2*、*3(含负数的范围不支持),范围中所有列应用同一格式;
  • format none:清除所有自定义格式,恢复默认。

格式串优先级:单列 ID 格式 >int/float全局设置 >line设置 > 默认格式。示例(doc/src/thermo_modify.rst 第 41–48 行):

thermo_modify temp myTemp format 3 %15.8g thermo_modify temp myTemp format line "%ld %g %g %15.8g" thermo_modify line multi format float %g thermo_modify line yaml format none

源码实现值得注意:format int设置会同时派生大整数格式(utils::adjust_format(format_int_user, utils::FmtArg::BIGINT),src/thermo.cpp 第 759–765 行),并在init()中逐列校验格式串与值类型是否匹配、不匹配即报错(src/thermo.cpp 第 291–303 行)——这是较新版本的行为(文档标注 2026 年 9 月 2 日变更),此前类型不匹配会被静默接受并产生错误输出。另外,step与atoms内部以 8 字节有符号整数存储,用户可用%d风格格式,LAMMPS 会自动转换成对应的 8 字节形式。

各样式默认格式(doc/src/thermo_modify.rst 第 305–309 行):

样式line 默认int 默认float 默认
one/customone%10d%14.8g
multimulti%14d%14.4f
yamlyaml%d%.15g

temp / press:替换温度、压力 compute

  • thermo_modify temp compute-ID:指定一个先前由 compute 命令 定义的、能计算温度的计算,替代默认的thermo_temp,用于所有需要温度的 keyword。
  • thermo_modify press compute-ID:同理替代默认的thermo_press,用于press、enthalpy、pxx等。

源码中temp分支会校验 compute 的tempflag并警告其组若非all;关键副作用是它会调用pcompute->reset_extra_compute_fix()把当前使用的压力 compute 的温度来源一并替换(src/thermo.cpp 第 578–617 行)。因此存在顺序敏感性:pressure compute 在定义时以某个温度 compute 为参数,temp关键字只有在press之后出现才会覆盖它;若temp在press之前,新压力 compute 不受temp设置影响(doc/src/thermo_modify.rst 第 262–273 行)。

triclinic/general:一般三斜盒输出

triclinic/general yes仅当模拟盒以一般三斜盒(general triclinic)方式创建时可用。置yes后,盒边向量(avec/bvec/cvec系 keyword)与压力张量分量(pxx,pyy,pzz,pxy,pxz,pyz)将按一般三斜盒相对标准 xyz 坐标轴的方向输出;否则按内部旋转后的受限三斜盒方向输出。由于力与坐标在两种表示下都被旋转,两组数值通常不同。正交盒与受限三斜盒的边向量关系、一般三斜盒与晶胞常数的换算详见 Howto_triclinic。源码中该选项在非一般三斜盒上启用会直接报错(src/thermo.cpp 第 642–649 行)。

在源码中新增自定义 thermo style

扩展内置样式(如新增myStyle)的工作集中在 src/thermo.cpp,流程如下。先在文件中搜索CUSTOMIZATION并注意带 "thermo style" 的标注——共有三处:

  1. 加入枚举常量:在第 75 行enum { ONELINE, MULTILINE, YAMLLINE };中加入新值(如MYSTYLE)。
  2. 定义 keyword 串与默认格式:在第 77–88 行区域定义新样式关键字列表字符串(如static constexpr char MYSTYLE[] = "step temp pe press";),并定义整数与浮点默认格式宏。
  3. 在构造函数中登记:第 127–165 行的 if-else 链中加入else if (strcmp(arg[0], "myStyle") == 0) { line = MYSTYLE; lineflag = MYSTYLE; },同时把lineflag的取值分支补充到init()中格式装配处(第 267–287 行的默认格式选择,以及第 305–324 行的行尾处理逻辑)。

新样式本质上就是“一组 keyword + 一组格式 + 一个布局枚举”,其余字段解析、compute 登记、打印装配均复用现有机制,无需改动其他文件。

在源码中新增自定义 thermo keyword

向thermo.cpp添加新的 keyword(如myEnergy)需要完成四个步骤,同样以文件中标注CUSTOMIZATION且提及 "keyword" 的位置为线索(共五处:第 57 行列表注释、第 893 行parse_fields()、第 1370 行evaluate_keyword()、第 149 行附近头文件方法原型、第 1795 行计算函数区)。

第一步:声明成员函数

在 src/thermo.h 第 149 行 "customize a new keyword by adding a method prototype" 注释处,按既有模式声明计算函数,如void compute_myenergy();。该函数由Thermo::compute()通过函数指针vfunc[ifield]间接调用。

第二步:在 parse_fields() 中登记

parse_fields()(src/thermo.cpp 第 889 行起)把 keyword 字符串映射为表头文本、计算函数与值类型。以现有条目为模板(第 943–951 行):

} else if (word == "evdwl") { addfield("E_vdwl", &Thermo::compute_evdwl, FLOAT); index_pe = add_compute(id_pe, SCALAR); } else if (word == "ecoul") { addfield("E_coul", &Thermo::compute_ecoul, FLOAT); index_pe = add_compute(id_pe, SCALAR); }

即仿写:

} else if (word == "myenergy") { addfield("MyEnergy", &Thermo::compute_myenergy, FLOAT); }

Thermo::addfield()(src/thermo.cpp 第 1243–1249 行)把表头写入keyword[nfield]、函数指针写入vfunc[nfield]、类型写入vtype[nfield]。

第三步:注意 addfield() 第三个参数的语义

addfield()的第三个参数是类型标志,决定该 keyword 输出值的种类与格式化方式(文档中的关键提示,见 doc/src/Modify_thermo.rst 第 41–48 行):

  • FLOAT:浮点值,函数内把结果存入成员变量dvalue;
  • INT:普通整数,结果存入ivalue;
  • BIGINT:大整数(8 字节),结果存入bivalue。

类型信息同时决定了init()中选择何种默认格式串(FLOAT 对应%14.8g一类、INT/BIGINT 对应%10d一类)。

第四步:实现计算函数

在compute_myenergy()实现中完成计算并把结果放入对应成员变量。参考能量类 keyword 的既有实现(如compute_evdwl()使用MPI_Allreduce跨进程求和,src/thermo.cpp 第 1984–1996 行):

void Thermo::compute_myenergy() { double tmp = 0.0; // ... 计算逻辑 ... MPI_Allreduce(&tmp, &dvalue, 1, MPI_DOUBLE, MPI_SUM, world); if (normflag) dvalue /= natoms; }

第五步:在 evaluate_keyword() 中注册(供变量引用)

evaluate_keyword()(src/thermo.cpp 第 1373 行起)由Variable类在 equal-style 变量公式遇到 thermo keyword 时调用,把 keyword 求值结果以 double 返回。若希望v_myvar这样的变量也能直接引用myenergy,需在第 1479 行附近仿照既有条目加 if 分支,例如:

} else if (word == "myenergy") { check_pe(word); compute_myenergy(); }

check_pe()(src/thermo.cpp 第 1314–1329 行)等check_*函数用于确保依赖的温度/压力/势能 compute 已初始化并已在本步被调用——能量类 keyword 依赖pe必须先被触发,这些检查正是为evaluate_keyword()路径准备的。若变量引用了不在 thermo style 中的 keyword,会因pe/temperature等指针为空而报错。

头文件与实现的一致性

最后在 src/thermo.h 中补充void compute_myenergy();原型(文件第 149 行注释区)。之后重新编译 LAMMPS 即可在输入脚本中使用thermo_style custom ... myenergy与变量公式v_myvar。

更轻量的替代方案:优先使用 compute / fix / variable

在动手改 C++ 源码之前,请先评估更简单的路线——文档明确指出(doc/src/Modify_thermo.rst 第 50–54 行):由于thermo_style custom已支持引用 fix、compute 和 variable 的输出,很多“自定义量”不必新增 keyword 即可实现:

  • 标量/向量/数组:c_ID、c_ID[I]、c_ID[I][J]输出 compute 的全局值;f_ID系列同理对应 fix。
  • 任意公式:equal-style 变量公式可引用 thermo keyword、per-atom 属性、其他 compute/fix/变量,因此在变量里写表达式往往是实现自定义输出的最灵活途径。
  • 单原子属性:equal-style 变量可以按原子 ID 索引 atom-style 变量,从而把某个特定原子的坐标或属性直接放进 thermo 输出。
  • 时间平均量:keyword 输出的是当前步瞬时值;要得到含历史的时间平均量,可用f_ID引用做时间平均的 fix,如 fix ave/time。

自定义输出值的归一化行为也要留意:compute/fix 的广延值可能按全系统原子数(而非 compute 组内原子数)归一化,取决于thermo_modify norm;变量公式值则一律视为强度量原样输出。

从 log 文件读取热力学输出的实践

配套 log 文件 与 dump 输出的读取与解析也是实际工作中绕不开的环节。YAML 样式产出可直接用正则提取(见上文egrep示例);结构化数据处理方法见 Howto structured data output;Python 用户还可通过 lammps Python 模块 的lammps.get_thermo()系列接口在脚本中直接读取热力学量,无需解析文本。此外,thermo 命令 支持用 equal-style 变量(如logfreq(10,3,10))实现 0、10、20、30、100、200、300、1000… 这样的对数间隔输出,适合长时间模拟兼顾早期密集与后期稀疏的采样需求:

variable s equal logfreq(10,3,10) thermo v_s

关键源码位置速查

用途文件与位置
Thermo 类声明、compute 方法原型src/thermo.h
样式定义与默认格式(ONE/MULTI/YAML)src/thermo.cpp
构造函数解析样式、custom 通配符展开src/thermo.cpp
init()动态 vol 字段与格式装配src/thermo.cpp
header()/footer()块首尾输出src/thermo.cpp
compute()主打印管线与 lost 检查src/thermo.cpp
modify_params()(thermo_modify 全部分支)src/thermo.cpp
parse_fields()keyword→函数/格式映射src/thermo.cpp
addfield()/add_compute()/add_fix()/add_variable()src/thermo.cpp
evaluate_keyword()变量路径求值src/thermo.cpp
各compute_*()数值计算实现src/thermo.cpp
thermo / thermo_style / thermo_modify 命令文档doc/src/thermo.rst、doc/src/thermo_style.rst、doc/src/thermo_modify.rst

掌握以上内容后,无论是日常调参(频率、内容、格式、归一化)、并行/多分区下的性能监控(spcpu、cpuuse、part、timeremain),还是为特定力场或自定义能量项扩展 LAMMPS 的热力学输出,都已有清晰的路线图可循。

  • 科研
  • 科学计算
  • 高性能计算

【免费下载链接】lammps

Public development project of the LAMMPS MD software package

项目地址:https://gitcode.com/gh_mirrors/la/lammps
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询