LAMMPS中的变量在编写in文件时,用于循环程序条件执行控制体系运动变化模拟参数,以及分布计算核心,提高计算效率方面非常有用。因此,本文仅介绍LAMMPS的一个主要命令variable及相关命令。

lammps fix species 命令 lammps variable命令_字符串

variable 命

  • 语法

variable name style args

其中name为变量名,只能为字母,数字,下划线的组合。

style可以为:delete, index, loop, world, universe, uloop, string, format, getenv, file, atomfile, python, internal, equal, vector, atom
• 举例
variable x index run1 run2 run3 run4 run5 run6 run7 run8
variable LoopVar loop $n
variable beta equal temp/3.0
variable b1 equal x[234]+0.5*vol
variable b1 equal "x[234] + 0.5*vol"
variable b equal xcm(mol1,x)/2.0
variable b equal c_myTemp
variable b atom x*y/vol
variable foo string myfile
variable foo internal 3.5
variable myPy python increase
variable f file values.txt
variable temp world 300.0 310.0 320.0 ${Tfinal}
variable x universe 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
variable x uloop 15 pad
variable str format x %.6g
variable x delete
  • 说明

1. equal是使用最多的变量类型,equal类型的变量存储了一个可以得到具体数值的表达式,这类变量可以由其他变量调用和输出,例如,print, fix print, run every, thermo_style等。

2. vector类型的变量保存了一个可以得到向量的表达式,可以作为平均操作的输入量,或者向量中的元素也可以作为热力学量输出。

3. atom类型的变量保存了每个原子的相关数值信息,可以有dump custom命令输出。

4.  atomfile类型的变量与atom类型基本相同,不同的是这类变量是从一个文件获得每个原子的值,而不是通过表达式。atomfile中的文件类型有特殊的要求:

LAMMPS将读取atomfile文件中第一个非空白行,非注释行,该行应该为一个整数N,N可以是所有原子的个数或者其子集。然后按照下面的格式依次赋予原子一定的值,没有出现的原子ID将会被赋予值0。

ID value

5. python类型的变量可以关联到Python的函数或表达式的值,这类变量可以从Python代码中获得值。

6. index类型的变量保存了一个或多个字符串,每使用一次next命令,下一个字符串就被赋给该类变量。注意一个字符串如果在引号中,一个字符串是可以包括多个单词,也就是可以有空格。该类型的变量也可以在命令行中声明,与在in文件中声明是完全相同的,例如, -var 变量名 值1 值2...。

 7. loop类型的变量与index基本相同,只是变量的值是整数而不是字符串。loop类型的变量可以有一个或两个参数,若只有一个参数N,那么变量为1~N;若参数为N1 N2,那么变量的值为N1~N2。同样的,每一次next命令被使用,loop类型的变量就被指定为下一个值。

lammps fix species 命令 lammps variable命令_字符串_02

LAMMPS循环结构的实现

使用目前的命令可以在in文件中实现循环,例程如下:

label loop
variable a loop 5
print "A = $a"
if "$a > 2" then "jump in.script break"
next a
jump in.script loop
label break
variable a delete

注意:在in文件中如果相同的变量名被variable命令重复使用,只有第一个命令是有效的,后续的命令会被自动忽略,例如上例中循环结构中的variable a loop。但当变量的值不是表达式字符串,而是一个具体的值时,变量是可以被重新定义的。

8. world类型的变量用于将处理器分为若干部分,每个部分运行相同的程序,除了其中某个控制参数不同。需要结合命令行中的-partition命令使用。例如in文件如下:

variable a world run1 run2 run3

print test=$a

按照如下命令运行该in文件:

mpiexec -n 3 ./lmp_mpi -p 3x1 -in in.XXX

最终可以得到三个log文件,变量a的值在三个并行程序中分别被赋予run1,run2,和run3。

9. universe类型的变量的基本用法与world类似,不同的是该变量可用,例如,在8个处理器上模拟50个类似的模拟。也就是universe类型的变量的值可以超过处理器的划分总数。实现该功能需要使用next命令和循环结构,最先到达next命令的处理器组会得到一个新的变量值,这个新的变量值是与其他处理器组已有的变量值不同的值,直至universe变量的所有值被用完。

10. uloop类型的变量与universe基本相同,只是该类型变量的值是整数,可以不用分别指定一个很长的序列,而是直接给出最大的整数值即可生成序列。

11. string类型的变量代表一个字符串,与变量类型index不同的是,string类型的变量可以被另外一个variable命令重定义,此外即使string类型变量的参数出现在引号内也会进行变量替换。

12. format类型的变量相当于equal类型的变量在附加一个C语言类型的格式设置,例如,"%f"或者"%.10g",默认的格式是"%.15g".

13. file类型的变量需要从一个包含一系列字符串的文件中读取值,该文件的每一行是一个字符串,使用next命令可以依次改变file类型变量的值。

14. internal类型的变量定义时由用户指定一个初值,后续LAMMPS中的某些命令会自动的给该类型的变量赋值。目前LAMMPS中能给internal类型变量赋值的命令只有两个,create_atoms和fix_controller。例如下面的程序即可在复杂区域内完成原子的创建:

dimension 2
variable x equal 100
variable y equal 25
lattice hex 0.8442
region box block 0 $x 0 $y -0.5 0.5
create_box 1 box
variable xx internal 0.0
variable yy internal 0.0
variable v equal "(0.2*v_y*ylat * cos(v_xx/xlat * 2.0*PI*4.0/v_x) + 0.5*v_y*ylat - v_yy)>0"
create_atoms 1 box var v set x xx set y yy
write_dump all atom sinusoid.lammpstrj

其中xx, yy作为内部变量生成判断条件,并将判断结果赋予变量v,创建原子时,根据v的值是否为0判断是否创建原子。结果如下图:

lammps fix species 命令 lammps variable命令_字符串_03

  •   注意

1. 对于equal,vector,和atom类型,变量可以定义的表达式非常灵活,也是最常使用的三种变量类型,其后可以设定的表达式总结如下:

lammps fix species 命令 lammps variable命令_变量名_04

在实际应用中,理解并灵活运用以上表达式,可以得到模拟过程中的大量信息并输出。

2. 使用equal类型定义变量时,equal后面如果以表达式的形式出现则不会马上被计算,直到该变量被使用时才会被计算,如果希望变量的值立即被计算有以下两种方式

(1). 采用$()的形式,例如:

variable X equal (xlo+xhi)/2+sqrt(v_area)
region 1 block $X 2 INF INF EDGE EDGE
variable X delete
与以下语句等效:
region 1 block $((xlo+xhi)/2+sqrt(v_area)) 2 INF INF EDGE EDGE

(2).定义之后立刻引用,如果equal后面是表达式,equal只是定义了一个等式,而不计算这个等式的值。

variable v equal vol
variable v0 equal $v

假设以上两个命令之后,体系的体积又被改变:

thermo_style custom step v_v v_v0

会分别输出体系改变前后的体积。

3. 变量的引用有两种形式${}和v_, 两种形式稍有不同。v_代表一个表达式,而${}是一个值,例如下面两个例子:

variable a loop 2
region box block 0 1 0 1 0 1
create_box 1 box
label loop
variable x equal vol
variable y equal $x
next a
change_box all z final 0.0 2 boundary p p f units box
print "$x $y"
jump in.vtest loop

运行结果输出:

2 1

2 2

而下例:

variable a loop 2
region box block 0 1 0 1 0 1
create_box 1 box
label loop
variable x equal vol
variable y equal v_x
next a
change_box all z final 0.0 2 boundary p p f units box
print "$x $y"
jump in.vtest loop

输出结果为:

2 2

2 2

可见,变量equal一个表达式的时候,每次引用都会更新为当前值,而变量equal一个值的时候,只有在每一步run的时候或者再次循环到variable命令的时候才会更新。请认真体会以上两例。