第2章:输入文件结构解析
好,咱们直接进入正题。LAMMPS的输入文件,说白了就是一份「操作说明书」。你告诉LAMMPS:用什么单位、建多大的盒子、放多少原子、跑什么力场、怎么输出结果。我刚开始学的时候,总觉得这玩意儿像天书,后来发现——其实就那么几个核心模块。
2.1 输入文件的整体框架
一个标准的LAMMPS输入文件,我习惯把它分成四大块:
- 初始化设置:units、atom_style、boundary、dimension等
- 模型构建:region、create_box、create_atoms、lattice等
- 力场与参数:pair_style、pair_coeff、bond_style等
- 运行控制:fix、compute、dump、thermo、run等
你想想看,这就像盖房子。先打地基(初始化),再搭框架(建盒子),然后砌墙放家具(加原子和力场),最后通水电开始住人(跑模拟)。顺序错了,房子就塌了。
核心原则:LAMMPS读取输入文件是顺序执行的。前面的命令定义了后面的环境。比如你还没定义units就写pair_coeff,LAMMPS会直接报错。
2.2 units与atom_style设置
这两个命令,我建议你放在输入文件的第一行和第二行。为什么?因为它们定义了整个模拟的「语言」。
2.2.1 units命令
units决定了所有物理量的单位体系。LAMMPS提供了好几种,常用的就这几个:
| style | 质量 | 距离 | 时间 | 能量 | 典型应用 |
|---|---|---|---|---|---|
| real | g/mol | Å | fs | kcal/mol | 生物分子、聚合物 |
| metal | g/mol | Å | ps | eV | 金属、材料科学 |
| lj | 无量纲 | σ | τ | ε | 粗粒化、Lennard-Jones |
| si | kg | m | s | J | 宏观尺度 |
我的习惯:做生物分子模拟,我几乎只用real单位。做金属材料,用metal。有一次我接手别人的项目,他用了real但力场参数是metal的,结果能量算出来差了三个数量级……嗯,从那以后我第一件事就是检查units。
2.2.2 atom_style命令
atom_style定义了每个原子携带哪些信息。说白了,就是告诉LAMMPS:每个原子要记住哪些属性。
# 常用示例
units real
atom_style full # 带电荷、键、角、二面角等(生物分子常用)
atom_style atomic # 只带位置和类型(简单体系)
atom_style charge # 带位置、类型和电荷
避坑指南:我曾经犯过一个错——用atomic style去读一个带电荷的data文件。结果LAMMPS直接崩溃,查了半天才发现是atom_style没设对。记住:atom_style必须和你的力场、data文件匹配。
2.3 边界条件与模拟盒子定义
模拟盒子,就是你的「小宇宙」。边界条件决定了这个小宇宙的「墙」是什么样子的。
2.3.1 boundary命令
boundary命令设置三个方向(x、y、z)的边界类型:
- p(periodic):周期性边界。原子从一边出去,从另一边进来。最常用。
- f(fixed):固定边界。原子撞到边界就弹回来。
- s(shrink-wrapped):收缩包裹。边界会跟着原子移动。
- m(minimum):最小边界。类似s但只收缩不扩张。
# 常见设置
boundary p p p # 三个方向都是周期性(体相模拟)
boundary p p f # xy周期性,z方向固定(薄膜模拟)
boundary p p s # xy周期性,z方向收缩包裹(液滴模拟)
关键点:周期性边界不是万能的。做表面或界面模拟时,z方向用p会出问题——原子会从下面跑到上面去。我见过有人做水在石墨烯上的接触角模拟,z方向用了p,结果水分子从底部跑上来,模拟直接废了。
2.3.2 region与create_box
先定义区域,再创建盒子。这是标准流程。
# 定义一个长方体区域
region mybox block -10 10 -10 10 -10 10 units box
# 基于这个区域创建模拟盒子
create_box 2 mybox # 2表示有两种原子类型
这里有个细节:region的坐标单位由units box或units lattice决定。我个人习惯用units box,这样坐标就是绝对长度,不容易搞混。
2.4 关键命令的书写规范与执行顺序
嗯,这部分我踩过的坑最多。LAMMPS的命令顺序,说白了就是「先定义后使用」。但有些细节,新手很容易忽略。
2.4.1 命令书写规范
- 大小写不敏感:但建议全小写,看着整齐。
- 注释用#:一行中#后面的内容会被忽略。
- 续行符用&:一行写不下,用&换行。
- 变量用${}:比如${T}表示变量T的值。
# 一个完整的例子
units real
atom_style full
boundary p p p
# 定义盒子
region box block 0 50 0 50 0 50 units box
create_box 2 box
# 创建原子(这里用lattice方式)
lattice fcc 3.615
create_atoms 1 region box
# 设置力场
pair_style lj/cut 10.0
pair_coeff 1 1 0.010 3.405
# 设置输出
thermo 100
dump mydump all custom 1000 dump.lammpstrj id type x y z
# 运行
velocity all create 300.0 12345
fix 1 all nvt temp 300.0 300.0 100.0
run 10000
2.4.2 执行顺序的黄金法则
- 先全局,后局部:units、atom_style、boundary这些全局设置必须放在最前面。
- 先建盒子,后放原子:create_box必须在create_atoms之前。
- 先定义力场类型,后设置参数:pair_style必须在pair_coeff之前。
- 先设置初始条件,后运行:velocity、fix这些必须在run之前。
我曾经犯过的错:有一次我写了一个很长的输入文件,中间加了一行create_atoms,结果发现原子没加上。查了半天,原来是我在create_box之后、create_atoms之前,不小心写了个read_data命令——直接把盒子覆盖了。顺序啊顺序,血的教训。
2.5 本章知识体系
下面这张图,是我自己总结的输入文件结构。你照着这个框架写,基本不会出大问题。
我的建议:刚开始写输入文件,别急着一次写完。先搭框架,再填内容。每加一行命令,心里默念一遍「这个命令需要前面哪些定义?」。养成这个习惯,能省下大量debug的时间。
好了,这一章的内容就到这里。输入文件的结构,说白了就是「初始化→建模型→设力场→跑模拟」这四步。每一步都有它的规矩,顺序错了就报错。你先把这四层的逻辑理清楚,后面写任何输入文件都不会慌。
公众号:蓝海资料掘金营,微信deep3321