- 科研
- 科学计算
- 高性能计算
【免费下载链接】lammps
Public development project of the LAMMPS MD software package
lattice是 LAMMPS 中用于定义晶格(lattice)的核心命令:它描述一组由单胞(unit cell)和基原子(basis atoms)构成、在空间中无限复制的点阵,并决定这些点在模拟盒子(simulation box)中的位置。本指南以 doc/src/lattice.rst 为骨架,结合 src/lattice.cpp 源码与仓库中的真实示例,系统讲解内置晶格样式、scale/origin/orient/spacing/a1/a2/a3/basis 全部参数、LJ 归约密度换算、一般三斜晶格(triclinic/general)以及"单位晶格间距"(units lattice)的底层机制。读完本文,你将能自如地构造 fcc/bcc/hcp/diamond 等标准晶格,用 custom 样式还原任意晶体结构(如 Wurtzite CdSe),并正确地把晶格原子填充进模拟盒子。
命令语法与参数总览
lattice命令的完整语法为:
lattice style scale keyword values ...- style:
none、sc、bcc、fcc、hcp、diamond、sq、sq2、hex、custom之一; - scale:晶格与模拟盒子之间的缩放因子;
- 其后可追加零个或多个 keyword/value 对,支持的 keyword 包括:
| keyword | 取值 | 含义 |
|---|---|---|
origin | x y z | 晶格在盒子内的平移量,为单胞边长的小数(0 <= x,y,z < 1) |
orient | dim i j k | 将晶格某个晶向对齐到盒子坐标轴(dim = x/y/z,i,j,k 为整数晶向) |
spacing | dx dy dz | 直接指定盒子 x,y,z 方向上的晶格间距 |
a1、a2、a3 | x y z | 定义单胞的三个边矢量(仅custom样式可用) |
basis | x y z | 添加一个基原子,坐标为分数坐标(0 <= x,y,z < 1,仅custom样式可用) |
triclinic/general | 无取值 | 声明该晶格用于一般三斜模拟盒子 |
典型示例:
lattice fcc 3.52 lattice hex 0.85 lattice sq 0.8 origin 0.0 0.5 0.0 orient x 1 1 0 orient y -1 1 0 lattice custom 3.52 a1 1.0 0.0 0.0 a2 0.5 1.0 0.0 a3 0.0 0.0 0.5 & basis 0.0 0.0 0.0 basis 0.5 0.5 0.5 triclinic/general lattice none 2.0LAMMPS 中"晶格"的定义非常朴素:它就是一个点集,由带基原子的单胞沿各方向无限复制而成。晶格在两条路径上发挥作用:
- create_atoms 命令把原子放到模拟盒子内部的晶格点上,且允许把不同的原子类型分配给不同的基原子(通过
basis子选项); - 由晶格隐含的 x,y,z 方向晶格间距,可以被其他命令当作"距离单位"使用,例如 create_box、region、velocity,当问题几何本质上是"原子坐落在晶格上"时非常方便。
晶格样式必须与模拟维度一致(见 dimension 命令):sc、bcc、fcc、hcp、diamond用于三维问题;sq、sq2、hex用于二维问题;custom二维、三维均可。
lattice命令可以在输入脚本中多次使用,每次调用都会重新定义晶格属性,并影响之后所有使用晶格属性的命令。典型应用是重复执行lattice→region→create_atoms序列,在不同几何区域内用不同晶格取向填充原子,从而构建多晶(poly-crystalline)模型。
内置晶格样式:单胞结构与基原子摆放
除none和custom外,其余样式在 src/lattice.cpp 中通过add_basis()直接写入预定义的基原子分数坐标:
| 样式 | 维度 | 单胞边矢量 | 基原子数 | 基原子位置(分数坐标) |
|---|---|---|---|---|
sc | 3d | 立方体,边长 1.0 | 1 | (0,0,0) |
bcc | 3d | 立方体,边长 1.0 | 2 | (0,0,0)、(0.5,0.5,0.5) |
fcc | 3d | 立方体,边长 1.0 | 4 | (0,0,0)、(0.5,0.5,0)、(0.5,0,0.5)、(0,0.5,0.5) |
hcp | 3d | a1=(1,0,0)、a2=(0,√3,0)、a3=(0,0,√(8/3)) | 4 | z=0 平面两个、z=0.5 平面两个 |
diamond | 3d | 立方体,边长 1.0 | 8 | 角点 + 三个面心 + 四个 (0.25,0.25,0.25) 类偏移位 |
sq | 2d | 正方形,边长 1.0 | 1 | (0,0) |
sq2 | 2d | 正方形,边长 1.0 | 2 | (0,0)、(0.5,0.5) |
hex | 2d | 矩形:a1=(1,0,0)、a2=(0,√3,0) | 2 | (0,0)、(0.5,0.5) |
其中sc、bcc、fcc、diamond使用单位立方单胞(a1 = 1 0 0、a2 = 0 1 0、a3 = 0 0 1);hcp的 a2、a3 分量在 src/lattice.cpp 中由sqrt(3.0)与sqrt(8.0/3.0)直接设置。注意 LAMMPS 里"单胞"(unit cell)沿用了固态物理中"primitive vectors"的命名,但并不要求它是体积最小的"primitive cell"。
维度不匹配会被直接拒绝:在二维模拟中使用sc/bcc/fcc/hcp/diamond,或三维模拟中使用sq/sq2/hex,都会触发Lattice style incompatible with simulation dimension错误(src/lattice.cpp)。
none样式:只定义间距,不定义原子
none样式不定义单胞和基原子集合,因此不能与 create_atoms 一起使用;但它通过 scale 参数定义晶格间距,可供其他命令作为距离单位。none样式不能附带任何其他 keyword/value。系统默认即lattice none 1.0,表示晶格间距等于 1 个距离单位(由 units 命令定义)。源码中none样式强制要求恰好两个参数,并把xlattice = ylattice = zlattice = scale(src/lattice.cpp)。
scale 参数:绝对距离与 LJ 归约密度
scale决定单胞映射进模拟盒子时的放大倍数,即施加到单胞上的乘法因子。其含义取决于当前 units:
- 除
lj外的所有单位制:scale直接以该单位制的距离单位给出。例如real或metal单位下,单位立方单胞配scale = 3.52,得到间距为 3.52 Å 的立方晶格;cgs单位下则为 3.52 cm。 lj单位制:scale是 Lennard-Jones 归约密度 ρ*。LAMMPS 通过公式factor^dim = ρ/ρ*反推出乘法因子,其中 ρ = N/V,V 是晶格单胞体积,N 是单胞内基原子数,dim 是模拟维度(2 或 3)。效果上,若模拟中 LJ 粒子的尺寸 σ = 1.0,那么该晶格下的粒子就落在目标归约密度上。
源码中 LJ 单位下的换算发生在 src/lattice.cpp:
if (strcmp(update->unit_style,"lj") == 0) { double vec[3]; MathExtra::cross3(a2,a3,vec); double volume = fabs(MathExtra::dot3(a1,vec)); scale = pow(nbasis/volume/scale,1.0/dimension); }即先由 a1、a2、a3 叉乘点积算出单胞体积,再按(N/(V·ρ*))^(1/dim)计算真正的缩放因子——这正是examples/melt/in.melt中lattice fcc 0.8442的来由(对应 ρ* ≈ 0.8442 的 fcc 熔体)。
origin / orient / spacing:把理想单胞搬进模拟盒子
origin:平移
origin x y z指定单胞映射进盒子时的平移量,取值为各方向晶格间距的小数(0 <= x,y,z < 1)。二维模拟中origin的 z 值必须为 0.0(源码在 src/lattice.cpp 校验)。例如examples/PACKAGES/cnp/in.cnp中origin 0.01 0.01 0.01把 fcc 晶格整体微移,以消除位错计算中的对称性。
orient:旋转
orient dim i j k把晶格的某个晶向(crystallographic direction,整数三元组)对齐到模拟盒子的某个坐标轴。例如orient x 2 1 0表示盒子 x 轴沿晶格 [210] 方向,y、z 依此类推。三个晶向不必是单位矢量,但必须相互正交且满足右手定则(X×Y 指向 Z)。二维模拟要求orientx、y 的第三分量为 0,orientz 的第一、第二分量为 0(src/lattice.cpp)。
需要特别留意:上述"晶向对齐"的描述只对正交立方单胞(二维即正方形)严格成立。对于hcp、hex或 a1/a2/a3 非正交的custom晶格,更正确的理解是把三个 orient 矢量当作一个 3×3 旋转矩阵,作用在 a1、a2、a3 上,将原单胞旋转到盒子中的新朝向。
spacing:直接设定晶格间距
spacing dx dy dz直接设定三个方向的晶格间距,三个值都必须非零(二维模拟中 dz 用 1.0)。这些值会被 scale 因子再乘一次,因此spacing 1.0表示"一个单胞边长",与 scale 无关。当 LAMMPS 自动计算的间距在后续命令中不好用时(典型如非正交或旋转晶格),可以用它手工覆盖。
custom 样式:用 a1/a2/a3/basis 构造任意晶体
custom是功能最强大的样式,允许通过a1、a2、a3指定任意长度、可非正交(倾斜平行六面体)的单胞边矢量,并用basis逐次向单胞添加基原子。basis的参数是分数坐标(0.0 <= x,y,z < 1.0);二维模拟中任何基原子的 z 分数坐标必须为 0.0。
基原子的位置矢量 x 是三个边矢量的线性组合:
x = bx·a1 + by·a2 + bz·a3
其中 bx、by、bz 就是basis关键字给出的三个值。默认情况下 a1、a2、a3 是三个正交单位矢量(单位立方体的边)。
a1/a2/a3/basis关键字只能用于custom样式,对其他样式使用会在 src/lattice.cpp 中被拒绝(Invalid a1/a2/a3/basis option in lattice command for non-custom style)。此外,基原子坐标越界(< 0 或 >= 1)也会被逐项校验并报错。
实战:构造 Wurtzite(纤锌矿)CdSe 晶体
文档给出了一个完整的 Wurtzite 晶体构造示例,晶格常数近似 CdSe,采用 √3×1 正交超胞,x、y、z 方向分别沿 [1̄2̄30]、[10̄10]、[0001]:
variable a equal 4.34 variable b equal $a*sqrt(3.0) variable c equal $a*sqrt(8.0/3.0) variable third equal 1.0/3.0 variable five6 equal 5.0/6.0 lattice custom 1.0 & a1 $b 0.0 0.0 & a2 0.0 $a 0.0 & a3 0.0 0.0 $c & basis 0.0 0.0 0.0 & basis 0.5 0.5 0.0 & basis ${third} 0.0 0.5 & basis ${five6} 0.5 0.5 & basis 0.0 0.0 0.625 & basis 0.5 0.5 0.625 & basis ${third} 0.0 0.125 & basis ${five6} 0.5 0.125 region myreg block 0 1 0 1 0 1 create_box 2 myreg create_atoms 1 box & basis 5 2 & basis 6 2 & basis 7 2 & basis 8 2注意这里用了 8 个基原子(4 个阳离子位 + 4 个阴离子位),并在create_atoms中用basis 5 2等子选项把第 5~8 号基原子指定为类型 2,从而在一个晶格上生成两种原子——这正是 create_atoms 支持"不同基原子配不同原子类型"能力的体现,对应 src/create_atoms.cpp 中basistype[]数组的按基原子类型映射逻辑。
类似的custom用法还可见于 examples/ASPHERE/flat_membrane/in.flat_membrane:它用custom加两个基原子构造椭圆体薄膜的斜方单胞;以及 examples/ELASTIC_T/BORN_MATRIX/Silicon/init.in,用custom加 8 个基原子构造金刚石硅。
triclinic/general:一般三斜晶格支持
triclinic/general选项声明晶格用于一般三斜(general triclinic)模拟盒子,区别于正交盒或受限三斜盒(restricted triclinic,三类盒子的完整说明见 Howto_triclinic)。使用约束如下(src/lattice.cpp):
- 必须配合
custom样式使用; - a1、a2、a3 必须是某个单胞的边矢量,可任意,但须非零、互不平行、不共面,且构成右手系(a1×a2 指向 a3 方向)。左手系可以通过交换任意一对 a 矢量的顺序转为右手系;
- 二维模拟中 a3 必须为 (0.0, 0.0, 1.0)(即默认值);
origin与orient必须保持默认值:origin = (0,0,0),orient 分别为 (100)、(010)、(001)。
该选项的用途:用户可能从固态晶体学表示或 DFT 代码导入数据,LAMMPS 为此提供了直接按 a1/a2/a3 定义一般三斜晶格的便利。但正如 Howto_triclinic 所说明的,LAMMPS 内部只使用受限三斜模拟盒子:当create_box与create_atoms被调用时,盒子和逐原子信息(坐标、速度等)都会从一般三斜形式转换到受限三斜形式(源码中通过domain->general_to_restricted_rotation()完成,见 src/lattice.cpp);其他任何使用本命令晶格间距的命令(如region)也都作用于受限三斜盒子。
create_box可用带triclinic/general的晶格生成各方向按 a1/a2/a3 单胞复制、三个盒子边矢量任意的一般三斜盒;create_atoms同样要求带该选项的晶格,才能把原子(或分子)放到 a1/a2/a3 与基原子定义的格点上。
晶格间距的自动计算与 units lattice
多个 LAMMPS 命令支持"units lattice"选项,即把 x,y,z 方向的晶格间距当作距离单位。例如region命令可以创建 10x20x20 的块,其中 10 表示 x 方向的 10 个晶格间距。值得注意的是,尽管名叫"晶格间距",所有带units lattice选项的命令其实只是把这三个值当作 units 定义的距离单位的缩放因子——因此如果你不喜欢 LAMMPS 算出的间距(例如非正交或旋转单胞),完全可以用spacing选项改成你想要的值。
不指定spacing时,间距的自动计算流程(对应 src/lattice.cpp 的bbox()遍历):
- 把单胞映射进模拟盒子(缩放 + 旋转),得到(可能改变大小与朝向的)单胞;
- 取变换后单胞 8 个角点(二维为 4 个)x 坐标的 min/max 之差作为 X 方向晶格间距,Y、Z 同理。
如果指定了triclinic/general,单胞先被转换到受限三斜朝向(一次旋转操作),再按上述流程求 8 角点的 min/max 范围确定间距——因为其他命令使用的间距总是针对受限三斜盒。
若单胞正交且边与坐标轴对齐(未通过orient旋转),各方向间距就是 scale 乘以对应 a1/a2/a3 的长度。例如 scale = 3.0 Å 的hex晶格,x 方向间距为 3.0,y 方向为 3·√3。
需要警惕的坑:对非正交单胞或施加了orient旋转的情况,LAMMPS 算出的间距通常不那么直观,且不保证某个方向的间距是该方向晶格周期的整数倍。因此,如果你在某个维度上创建一个边长是"晶格间距"整数倍的正交周期盒,再用create_atoms填满原子,得到的不一定是周期系统——盒子面处的原子可能错误重叠。
每次使用lattice命令,LAMMPS 都会把计算出的间距打印到日志中(Lattice spacing in x,y,z = ...,见 src/lattice.cpp),便于你在后续命令中核对间距的实际数值。
坐标系变换的底层原理
lattice命令内部维护了晶格坐标与盒子坐标之间的双向变换矩阵,全部由 src/lattice.cpp 实现:
setup_transform()构造 3×3 的primitive矩阵(a1/a2/a3 按列排布)及其逆矩阵priminv,再把归一化的 orient 矢量分别按行(rotaterow)和按列(rotatecol)排成旋转矩阵;lattice2box()完成晶格坐标 → 盒子坐标:
xyz_box = Rotate_row · scale · P · xyz_lattice + offset
其中 offset = (xlattice·origin[0], ylattice·origin[1], zlattice·origin[2]);
box2lattice()完成逆向变换(P_inv · 1/scale · Rotate_col · (xyz_box − offset))。
create_atoms在把原子放到格点上时正是调用这套变换(src/create_atoms.cpp 用xlattice/ylattice/zlattice缩放units lattice尺寸)。此外,构造阶段还有一系列几何合法性校验(src/lattice.cpp):无基原子(No basis atoms in lattice)、orient 矢量不正交、不满足右手定则、primitive 矢量共线(Lattice primitive vectors are collinear)都会直接报错终止。
多晶与旋转晶格实战:部分位错 Cu 晶体的构造
examples/PACKAGES/cnp/in.cnp 是 fcc 铜中部分位错(partial dislocation)生成的经典示例,展示了lattice三个变换参数的联合使用:
units metal boundary p p p atom_style atomic lattice fcc 3.615 origin 0.01 0.01 0.01 orient x -1 -1 2 orient y 1 1 1 orient z -1 1 0 region mdbox block 0 3 0.0 14.0 0 84 units lattice region system block 0 3 1.1 13.1 0 84 units lattice create_box 2 mdbox create_atoms 1 region system mass * 63.54 pair_style eam/alloy pair_coeff * * Cu_mishin1.eam.alloy Cu Cu这里的orient把晶格 [2̄11]、[111]、[1̄10] 方向分别旋转到盒子 x、y、z 轴(三者满足右手定则),region使用units lattice让盒子尺寸直接以晶格间距为单位表达,最终在一个倾斜取向的 fcc 铜单胞中造出含位错的模拟体系。与之形成对照的是 examples/PACKAGES/basal/in.basal:它用custom样式加 4 个基原子、再配三组orient,构造了六方密排基面取向的晶体。
限制、相关命令与默认值
限制:a1/a2/a3/basis关键字只能用于custom样式;triclinic/general也必须配custom使用。
相关命令:dimension、create_atoms、region,以及配套的 create_box、units、velocity 与 Howto_triclinic。
默认值:系统默认lattice none 1.0。其他样式的选项默认值为:origin = 0.0 0.0 0.0;orient = x 1 0 0、y 0 1 0、z 0 0 1;a1 = 1 0 0、a2 = 0 1 0、a3 = 0 0 1(对应 src/lattice.cpp 中的初始化代码)。
小结
lattice命令是 LAMMPS 一切"按晶格造原子"工作流的起点:内置样式覆盖了常见晶体结构,custom加a1/a2/a3/basis覆盖了任意晶体学单胞,scale/origin/orient/spacing控制单胞到盒子的缩放、平移、旋转与间距覆盖,triclinic/general打通了与 DFT/晶体学数据的一般三斜对接。理解其单胞-盒子坐标变换(src/lattice.cpp)与"units lattice"间距语义,能让你在构建多晶、位错、薄膜、超胞等体系时少走弯路,并规避非正交/旋转晶格下非周期填充的隐患。
- 科研
- 科学计算
- 高性能计算
【免费下载链接】lammps
Public development project of the LAMMPS MD software package
相关推荐
MKS Monster8 8轴主板完整配置实战:30分钟搞定接线、固件刷写与调优
MKS Monster8 8轴主板完整配置实战:30分钟搞定接线、固件刷写与调优 "主板明明通了电,电机却像没睡醒一样狂抖;驱动也装好了,屏幕上却永远显示高温警
科研科学计算高性能计算LAMMPS 多副本模拟(Multi-Replica)完全指南:原理、命令与实战
LAMMPS 多副本模拟(Multi Replica)完全指南:原理、命令与实战 多副本模拟(Multi replica simulation)是 LAMMPS
科研科学计算高性能计算LAMMPS compute property/grid 命令完全指南:分布式网格的 ID、索引与坐标输出
LAMMPS compute property/grid 命令完全指南:分布式网格的 ID、索引与坐标输出 导读 : compute property/grid
科研科学计算高性能计算
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考