详细内容

LAMMPS讲解51-润湿moltemplate建模

工业和生活生产中很多情况都涉及到液滴在固体表面上润湿和铺展。在润湿基础理论方面,分子动力学特别适合用来研究液滴在光滑固体表面上的润湿。从基本的铺展规律到原子尺度机理都可以得到可靠的结果。大量论文已经采用分子动力学方法研究润湿过程,其中不乏顶刊论文。实践表明纳米尺度的研究对理想情况下的润湿已经足够了。本文开始介绍润湿的模拟。使用的工具就是LAMMPS。首先是如何建立润湿模型。本例讲解如何建立如下图所示的润湿模型。该模型研究圆柱形水滴在光滑固体表面的润湿。为什么是水滴,因为水最常见。为什么是圆柱形。因为圆柱形水滴可以捕捉到润滑的关键过程,同时在相同直径下用到的原子数更少。在理论上,圆柱形水滴也更容易处理。液滴尺寸的选择一般会设置初始直径大于10nm就可以了。固体表面需要保证液滴在铺展时可以充分铺展而不会受到周期性边界的影响。下面介绍如何使用moltemplate建立上图的模型。模型采用TIP4P/2005水分子力场,壁面为刚性。z方向为非周期性边界条件。xy方向为周期性边界条件。更复杂的模型也可以建立。

image.png 

LAMMPS的使用重点前处理任务之一就是建立模型。实现LAMMPS的通用建模方法是很困难的。往往需要组合几个工具才能实现建模目的。LAMMPS官网给出了多个前后处理的工具(https://lammps.sandia.gov/prepost.html),阅读工具介绍找到自己需要的工具。在这些工具中moltemplate是一款专门为LAMMPS建模开发的软件,与LAMMPS是无缝衔接的。使用moltemplate建模首先查看安装包中的例子,如果能找到相似的例子,恭喜你你的任务moltemplate可以实现,如果找不到相似的,那么就用moltemplate就很难了。目前网上的教程不能令人满意。

image.png

 

首先是moltemplate安装。这个软件安装很简单,但是需要有Linux环境。如果是Windows 10系统,可以安装ubuntu子系统获得Linux环境。首先确保你的系统中有python2.73.0版本或更新的版本。执行

which python which python3

如果输出路径则python存在,如果不存在就安装一个python。然后官网下载moltemplatehttp://www.moltemplate.org/download.html)使用git命令或下载源代码压缩包都行。如果是下载的压缩包,就解压缩到合适位置。假设moltemplate在路径/home/user下。那么就把以下两个路径加入到.bashrc文件末尾

export PATH=/home/user/moltemplate/moltemplate:$PATH

export PATH=/home/user/moltemplate/moltemplate/scripts:$PATH

然后执行

source ~/.bashrc

which moltemplate.sh

若输出路径则安装完成。上述安装假设你的shellbash

分子动力学的模型往往是由大量重复组分构成,如水体系就有大量水分子构成,金属块有大量晶胞构成等等。moltemplate建模的基本原理就是先手动设定一个重复单元的信息,然后通过在xyz三个方向上阵列复制重复单元得到想要的模型。通过阵列复制moltemplate内部自动处理atom idtype以及坐标这些信息。moltemplate没有GUI界面和LAMMPS一样通过编写文本文件然后读入文件内容执行。这些文件被称为lt文件。一般你的模型有几部分组成就会写几个lt文件加一个最终控制执行的文件。比如本文即将用到的例子就由上壁面,水和下壁面构成,因此会写4lt文件:upwall.ltdownwall.ltwater.ltsystem.lt。前三个分别设定上壁面,下壁面和水的重复单元信息,system.lt控制阵列重复的设置。

我们先来看看water.lt学习lt文件的基本内容。

wat {

 

  write("Data Atoms") {

    $atom:O  $mol:. @atom:O -1.1128  0.0000000  0.00000  0.000000

    $atom:H1 $mol:. @atom:H  0.5564  0.7569503  0.00000  0.5858823

    $atom:H2 $mol:. @atom:H  0.5564  -0.7569503 0.00000  0.5858823

  }

 

  write_once("Data Masses") {

    @atom:O 15.9994

    @atom:H 1.008

  }

 

  write("Data Bonds") {

    $bond:OH1 @bond:OH $atom:O $atom:H1

    $bond:OH2 @bond:OH $atom:O $atom:H2

  }

 

  write("Data Angles") {

    $angle:HOH @angle:HOH $atom:H1 $atom:O $atom:H2

  }

 

  write_once("In Settings") {

    bond_coeff   @bond:OH 600.0   1.0

    angle_coeff  @angle:HOH 75.0    109.47

    pair_coeff   @atom:O @atom:O lj/cut/tip4p/long 0.1553  3.166

    pair_coeff   @atom:H @atom:H lj/cut/tip4p/long 0.0     0.0

  }

 

  write_once("In Init") {

   dimension    3

   units metal

   boundary p p f

   neighbor 2.0 bin

   neigh_modify every 1 delay 0 check yes

   atom_style   full

   pair_style   hybrid lj/cut/tip4p/long 3 4 1 1 0.1546 8.5 8.5 eam

   bond_style   harmonic

   angle_style  harmonic

   kspace_style pppm/tip4p 0.0001

   kspace_modify slab 3.0

  }

}

首先在water.lt中给重复单元定义一个名称(这个名称是自定义的就像任何编程语言中的变量定义一个道理)。比如上面wat然后写一对花括号构成如下结构。花括号中的内容就是wat这个重复单位的设定,wat名称会在system.lt中调用。

wat {

   ......

}

花括号中有多个write(){}命令和write_once(){}命令组成,这两个命令实现向输出文件中写相应的内容。moltemplate每次执行会生成三个目标文本文件:system.in.initsystem.in.settingssystem.datawrite(){}命令和write_once(){}命令圆括号中的内容指出花括号中的内容向哪个文件进行写入。write(){}命令表示内容对多次写入,write_once(){}命令表示内容只写一次。write("Data Atoms") {}data文件中Atoms部分写内容,write_once("Data Masses") {}data文件中Masses部分写内容,write("Data Bonds") {}data文件中Bonds部分写内容,write("Data Angles") {}data文件中Angles部分写内容。本例中的体系是水加上金属壁面因此可以知道data文件的主体内容就包括这三个部分。write_once("In Settings") {}Settings文件写内容,write_once("In Init") {}Init文件写内容。

来看write("Data Atoms"){}中的内容。这里面每行的内容与你设定的atom_style对应,比如本例中设定的atom_stylefull,那么这里面的内容以及data文件Atoms部分每一行就包括

atom-ID mol-ID atom-type charge x y z

这些内容在moltemplate中对应为

$atom:O  $mol:. @atom:O -1.1128  0.0000000  0.00000 0.000000

我们看到这里有两个特殊字符$@$表示id@表示type,如$atom:$mol:$bond:$angle:分别表示atom-IDmol-IDbond-IDangle-ID@atom:@bond:@angle:分别表示atom typebond typeangle type。这些都是moltemplate内部的关键词(包括冒号),冒号后面是自定义的原子,键和键角的名称,或原子,键和键角类型的名称。这些名称在定义和引用时要一致。在一个重复单元中每个原子都有自己的名称,但是可能会共用atom_type,以及共用一个mol-ID。键和键角也类似。

在一个水分子中有三个原子,两个键,一个键角所以write("Data Atoms") {}中有三行内容代表三个原子的信息,分别表示一个氧原子和两个氢原子。三个原子分别表示为$atom:O$atom:H1$atom:H2,这三个原子属于分子$mol:. ,其atom_style分别为@atom:O@atom:H

$atom:O  $mol:. @atom:O -1.1128  0.0000000  0.00000  0.000000

$atom:H1 $mol:. @atom:H  0.5564  0.7569503  0.00000  0.5858823

$atom:H2 $mol:. @atom:H  0.5564  -0.7569503 0.00000  0.5858823

write("Data Bonds") {}有两行信息

 $bond:OH1 @bond:OH $atom:O $atom:H1

 $bond:OH2 @bond:OH $atom:O $atom:H2

$bond:OH1键的类型是@bond:OH,由$atom:O$atom:H1构成,$bond:OH2键的类型是@bond:OH,由$atom:O$atom:H2构成。

write("Data Angles") {}有一行信息

$angle:HOH @angle:HOH $atom:H1 $atom:O $atom:H2

$angle:HOH键角的类型是@angle:HOH,由$atom:H1$atom:O$atom:H2构成。write_once("Data Masses") {}有两行内容因为有两个type的原子。这样就把一个水分子定义完成了。

write_once("In Settings") {}write_once("In Init") {}你写什么内容后面文件中就出现什么内容。通常这部分我们会在自己的in文件中修改,这里写什么不是很关键,我们要的是data文件的内容。

类似的upwall.ltdownwall.lt中的内容也类似

upwall {

 

  #AtomID MolID AtomType Charge X Y Z

  

  write("Data Atoms") {

    $atom:UC  $mol:.  @atom:U    0.0         0.000  0.000   0.000

    $atom:UX  $mol:.  @atom:U    0.0         0.000  2.040   2.040

    $atom:UY  $mol:.  @atom:U    0.0         2.040  0.000   2.040

    $atom:UZ  $mol:.  @atom:U    0.0         2.040  2.040   0.000

  }

  

  write_once("In Settings") {

    pair_coeff @atom:U @atom:U 1.0 1.0

  }

  

  write_once("Data Masses") {

    @atom:U 1.0

  }

}

downwall {

 

  #AtomID MolID AtomType Charge X Y Z

  

  write("Data Atoms") {

    $atom:DC  $mol:.  @atom:D    0.0              0.000  0.000  0.000

    $atom:DX  $mol:.  @atom:D    0.0              0.000  2.040  -2.040

    $atom:DY  $mol:.  @atom:D    0.0              2.040  0.000  -2.040

    $atom:DZ  $mol:.  @atom:D    0.0              2.040  2.040  -0.000

  }

  

  write_once("In Settings") {

    pair_coeff @atom:D @atom:D 1.0 1.0

  }

  

  write_once("Data Masses") {

    @atom:D 1.0

  }

  

}

    定义好个重复单元的内容后剩下的就交给moltemplate了。system.lt中的内容如下

import "upwall.lt"

import "downwall.lt"

import "water.lt"  

 

write_once("Data Boundary") {

   0      408      xlo xhi

   0      32.64    ylo yhi

   -15    245      zlo zhi

}

 

UPWALL  = new upwall  [1].move(0.00, 0.00, 4.08)

                      [8].move(0.00, 4.08, 0.0)

                      [100].move(4.08, 0.0, 0.0)

UPWALL[*][*][*].move(0.0,0.0,240.0)

             

DOWNWALL  = new downwall [3].move(0.00, 0.00, -4.08)

                         [7].move(0.00, 4.08, 0.0)

                         [100].move(4.08, 0.0, 0.0)

 

wats  = new  wat[50].move(0.00, 0.00, 3.0)

                [10].move(0.00, 3.0, 0.0)

                [50].move(3.0, 0.0, 0.0)

        

wats[*][*][*].move(129,0.0,45)

 

首先把建立好的water.ltupwall.ltdownwall.lt使用import命令导入。然后用write_once命令写出盒子边界。然后使用new关键词和.move命令阵列复制重复单元得到我们需要的模型。比如

WAT = new wat  [30].move(0, 0, -3.0)

               [19].move(0, 3.0, 0)

               [19].move(3.0, 0, 0)

这块的效果就是生成一个水块名字叫WAT使用的是wat重复单元,分别以3.0为间隔在z负方向(-3.0)阵列复制30次,xy正方向阵列复制19次,这样就生成了一个长方体形状的水块。UPWALLDOWNWALL也类似。需要指出的是.move命令当加了new关键词就会新生成分子,不加就会单纯的移动已经生成的部分。

在写好所有文件后执行下面命令生成data文件

moltemplate.sh -atomstyle full system.lt

然后在ovito中观察模型是否合理,不合理再进行修改。

上面教程只是moltemplate的最基本使用,更复杂的功能可参考moltemplate的例子。但是已经够成生成大部分模型了。

 

 

感谢鲍路瑶老师的分享,内容来自于鲍老师分享出来的资料

如有需要添加微信:lmp_zhushou  进入微信群,帮助他人,共建社区

获取完整版lammps讲义可以加微信lmp_zhushou或加入QQ994359511

该部分由武汉大学阿湖宝博士编写

 


最新评论
请先登录才能进行回复登录
技术支持: CLOUD | 管理登录
seo seo