第4章 原子类型与初始构型

做分子动力学模拟,第一步就是搭模型。说白了,你得告诉LAMMPS:我的体系里有哪些原子?它们长什么样?怎么排列的?

这一章,我就带你把这些基础问题彻底搞清楚。我个人习惯把初始构型比作「盖房子的地基」——地基没打好,后面算得再花哨也是白搭。

4.1 原子类型定义:给原子「上户口」

在LAMMPS里,每种原子都有一个编号,叫原子类型。比如水分子模拟,氧原子是类型1,氢原子是类型2。这个编号从1开始,不能跳号。

定义原子类型,用pair_coeff或者mass命令。举个例子:

# 定义原子质量
mass 1 16.0   # 氧原子
mass 2 1.008  # 氢原子

# 定义相互作用参数(以LJ势为例)
pair_coeff 1 1 0.1553 3.166   # O-O
pair_coeff 2 2 0.0 0.0        # H-H(无LJ作用)
pair_coeff 1 2 0.0 0.0        # O-H交叉项
我的小习惯:原子类型编号尽量跟元素周期表对应。比如C是6,O是8,这样看in文件时一眼就能认出来。当然,这只是个人偏好,不强求。

你可能会问:原子类型能有多少种?LAMMPS默认支持最大原子类型数atom_modify命令控制,默认是5492种。嗯,绝大多数情况够用了。

4.2 lattice命令:搭建晶格的「脚手架」

lattice命令是LAMMPS里最常用的建晶格工具。它定义了原子在空间中的重复排列方式。

基本语法:

lattice style scale keyword values ...

其中style可以是:

  • sc:简单立方
  • bcc:体心立方
  • fcc:面心立方
  • hcp:六方密堆积
  • diamond:金刚石结构
  • sq / sq2:二维正方形
  • hex:二维六角形

举个例子,创建一个晶格常数为3.52 Å的铜(fcc结构):

lattice fcc 3.52

这里3.52就是scale参数,代表晶格常数。LAMMPS会自动计算出基矢和原子位置。

关键点:lattice命令只定义了「晶格模板」,并没有真正创建原子。它需要配合regioncreate_atoms才能生成实际原子。

我在项目中遇到过一个问题:有人把lattice fcc 3.52写成了lattice fcc 3.52 0.0 0.0 0.0,结果原子位置全乱了。其实lattice命令的origin参数默认就是(0,0,0),不用画蛇添足。

4.3 region与create_atoms:构建复杂几何

光有晶格模板还不够,你得告诉LAMMPS:原子要放在哪个区域里。这就是region命令的活。

region可以定义各种形状:

  • block:长方体
  • sphere:球体
  • cylinder:圆柱体
  • cone:圆锥体
  • prism:斜六面体
  • union / intersect:布尔运算组合

来看一个实际例子:创建一个10×10×10 ų的铜块。

# 定义晶格
lattice fcc 3.52

# 定义区域
region mybox block 0 10 0 10 0 10

# 在区域内填充原子
create_atoms 1 region mybox

就这么简单?嗯,差不多。但要注意:create_atoms会按照当前lattice定义的晶格点,在region内生成原子。如果region边界不是晶格周期的整数倍,边缘会有些原子「悬空」。

避坑指南:我曾经在创建纳米线时,用了region cylinder配合create_atoms,结果发现圆柱体边缘的原子密度不均匀。后来我改用lattice custom配合create_atoms random才解决。所以,复杂几何体建议用random方式填充。

布尔运算组合区域,这个功能很强大。比如创建一个「球壳」:

region inner sphere 5 5 5 3
region outer sphere 5 5 5 5
region shell intersect 2 outer inner side out
create_atoms 1 region shell

这里intersect取外球减去内球,就得到了一个球壳区域。我在做纳米颗粒模拟时经常用这招。

4.4 read_data:导入外部构型文件

有时候,你的体系太复杂了——比如蛋白质、聚合物、或者从其他软件导出的结构。这时候用lattice一条条命令去建,不现实。

那就用read_data命令,直接读入外部文件。

read_data my_system.data

data文件的格式有严格规定。我总结了一个标准模板:

LAMMPS data file via write_data

8 atoms
2 atom types

0.0 50.0 xlo xhi
0.0 50.0 ylo yhi
0.0 50.0 zlo zhi

Masses

1 16.0
2 1.008

Atoms

1 1 1 0.0 10.0 10.0 10.0
2 2 1 0.0 10.5 10.0 10.0
3 2 2 0.0 9.5 10.0 10.0
...

注意几个关键点:

  • 第一行必须是LAMMPS data file开头
  • atom types必须跟实际类型数一致
  • 边界xlo xhi等必须正确
  • Atoms部分:原子ID、分子ID、原子类型、电荷(如果有)、x y z坐标
我的经验:从VMD、Material Studio等软件导出data文件时,经常会出现格式问题。我习惯用Python写个小脚本,把坐标重新整理成LAMMPS标准格式。推荐用numpypandas处理,效率很高。

还有一个常见问题:read_data读入后,原子类型编号必须跟pair_coeff等命令中的编号一致。我曾经犯过这个错——data文件里原子类型是1、2、3,但pair_coeff里写成了2、3、4,结果算出来的能量全是错的。

知识体系总览

这一章的内容,我用一张图帮你理清逻辑:

原子类型与初始构型知识体系 原子类型定义 mass / pair_coeff lattice命令 sc/bcc/fcc/hcp... region+create_atoms 几何构建与填充 read_data 外部构型导入 编号从1开始,不跳号 质量+相互作用参数 晶格常数+结构类型 仅定义模板,不生成原子 block/sphere/cylinder... 布尔运算组合区域 标准data文件格式 注意原子类型编号一致 核心原则:先定义类型 → 再定义晶格 → 然后区域填充 → 最后检查一致性 常见应用场景 晶体/金属模拟 纳米颗粒/线/管 生物分子/聚合物

这张图把四个核心模块串起来了。你想想看,从原子类型定义开始,到lattice搭建晶格模板,再到region划定区域并填充原子,最后用read_data处理复杂构型——这就是初始构型搭建的完整流程。

嗯,这一章的内容就到这里。记住:初始构型是模拟的起点,花时间把这一步做扎实,后面会省很多麻烦。


专注资料整理