使用pymatgen进行有序无序转变(上)

pymatgen的transformations模块提供了许多用于结构转换的方法(类),使用这些类可以轻易的实现掺杂、建超胞、添加氧化态等功能,这里介绍一下用于有序无序转换的两个类:EnumerateStructureTransformationOrderDisorderedStructureTransformation。这两个类可以实现类似supercell软件的功能,将无序结构转变为有序结构。

下面我们以立方体结构钙钛矿(CaTiO_3)为例,学习一下如何使用该模块建模。(CaTiO_3)的结构文件可以去 materials project 网站下载(mp-5827)。

关于有序无序转变

首先来了解一下什么是有序(order)与无序(disorder)结构,打开我们在mp上下载的cif文件:

# generated using pymatgen
data_CaTiO3
_symmetry_space_group_name_H-M   Pm-3m
_cell_length_a   3.88947141
_cell_length_b   3.88947141
_cell_length_c   3.88947141
_cell_angle_alpha   90.00000000
_cell_angle_beta   90.00000000
_cell_angle_gamma   90.00000000
_symmetry_Int_Tables_number   221
_chemical_formula_structural   CaTiO3
_chemical_formula_sum   'Ca1 Ti1 O3'
_cell_volume   58.83987623
_cell_formula_units_Z   1
loop_
 _symmetry_equiv_pos_site_id
 _symmetry_equiv_pos_as_xyz
  1  'x, y, z'
  2  '-x, -y, -z'
  3  '-y, x, z'
  4  'y, -x, -z'
  5  '-x, -y, z'
  6  'x, y, -z'
  7  'y, -x, z'
  8  '-y, x, -z'
  9  'x, -y, -z'
  10  '-x, y, z'
  11  '-y, -x, -z'
  12  'y, x, z'
  13  '-x, y, -z'
  14  'x, -y, z'
  15  'y, x, -z'
  16  '-y, -x, z'
  17  'z, x, y'
  18  '-z, -x, -y'
  19  'z, -y, x'
  20  '-z, y, -x'
  21  'z, -x, -y'
  22  '-z, x, y'
  23  'z, y, -x'
  24  '-z, -y, x'
  25  '-z, x, -y'
  26  'z, -x, y'
  27  '-z, -y, -x'
  28  'z, y, x'
  29  '-z, -x, y'
  30  'z, x, -y'
  31  '-z, y, x'
  32  'z, -y, -x'
  33  'y, z, x'
  34  '-y, -z, -x'
  35  'x, z, -y'
  36  '-x, -z, y'
  37  '-y, z, -x'
  38  'y, -z, x'
  39  '-x, z, y'
  40  'x, -z, -y'
  41  '-y, -z, x'
  42  'y, z, -x'
  43  '-x, -z, -y'
  44  'x, z, y'
  45  'y, -z, -x'
  46  '-y, z, x'
  47  'x, -z, y'
  48  '-x, z, -y'
loop_
 _atom_site_type_symbol
 _atom_site_label
 _atom_site_symmetry_multiplicity
 _atom_site_fract_x
 _atom_site_fract_y
 _atom_site_fract_z
 _atom_site_occupancy
  Ca  Ca0  1  0.500000  0.500000  0.500000  1
  Ti  Ti1  1  0.000000  0.000000  0.000000  1
  O  O2  3  0.000000  0.000000  0.500000  1

内容很多,前面的内容我们只需要关注这么几个内容:

  • 空间群 Pm-3m
  • 化学式 CaTiO3
  • 各原子数目 Ca1 Ti1 O3

下面我们来看一下最后几行

 _atom_site_type_symbol
 _atom_site_label
 _atom_site_symmetry_multiplicity
 _atom_site_fract_x
 _atom_site_fract_y
 _atom_site_fract_z
 _atom_site_occupancy
  Ca  Ca0  1  0.500000  0.500000  0.500000  1
  Ti  Ti1  1  0.000000  0.000000  0.000000  1
  O  O2  3  0.000000  0.000000  0.500000  1

上面七行对应的是下面七列的信息,分别是:

元素符号 原子序号 原子数 x轴坐标 y轴坐标 z轴坐标 占据比
Ca Ca0 1 0.5 0.5 0.5 1
Ti Ti1 1 0 0 0 1
O O2 3 0 0 0.5 1

可以看到CaTiO3中每个原子的占据比都是1,且其结构符合 Pm\overline3m 空间群的对称性,因此它是一个有序结构,也可以说是一个完美晶体。而无序结构顾名思义就是不是完美晶体的结构,在这里一般指的是占据比 occupancy != 1的结构。

在研究掺杂的过程中,我们会经常遇到这种情况,某个位置发生取代掺杂,部分原子被取代后占据比就会小于1。还有一种情况就是某种材料具有钙钛矿、尖晶石等结构,但是没有这种材料的结构文件,比如Li_{3x}La_{2/3-x}TiO_3(LLTO),锂镧钛氧是一种离子电导率很高的固态电解质材料,通过解析XRD数据发现它具有钙钛矿结构,其中Li和La占据A site,也就是Ca的位置,那么我们就可以以CaTiO3的结构为基础,通过取代Ca来得到 LLTO 的结构文件。

但是问题就来了,我们取代后的文件元素占据比小于1,变成了无序结构(disordered structure),而我们使用VASP的软件进行计算的时候,原子的占据比必须是1,那我们怎么办呢?

一种通用的做法是建一个超胞(supercell),也就是把现有的晶胞在三个方向上扩展若干倍,将分数占据比的元素按比例分配到每个位置上,得到一系列的结构后计算它们的能量,取能量最低者即为我们需要的结构。
比如我们在三个方向上都扩展三倍,得到一个 3x3x3 的超胞,此时结构化学式就变成了 Ca_{27}Ti_{27}O_{81},对于电导率最高的 Li_{0.33}La_{0.56}TiO_3

  • Li : 0.33 x 27 = 8.91 \approx 9
  • La : 0.56 x 27 = 15.12 \approx 15
  • Ti : 1 x 27 = 27
  • O : 3x27 = 81

此时LLTO的化学式可以写作 Li_9La_{15}Ti_{27}O_{81},也就是说,我们用9个Li、15个La和3个空位取代了A site上的27个Ca,此时我们得到了一个有132个原子的超胞,我们可以把它作为 LLTO 的晶胞,这个过程称之为 ordering,通过这个过程我们把一个分数占据的disordered的结构变成了一个ordered的结构。

但是问题就来了,我们取代后可以得到多少种结构呢?做个排列组合:C_{27}^{15}C_{12}^9 = 17383860 x 220 = 3824449200,对于简单地取代,我们可以通过枚举将所有结构列出来,但对这种有天文数字的组合,显然我们不可能全部列出来。

对这种情况,一种可行的方法是随机取代得到若干种结构,然后通过静电能(electrostatic energy) 排序取能量最低的几个结构,再对这几个结构进行DFT计算以得到能量最低者。

两种方法

下面我们分别来介绍一下两种方法,我们以LSTF为例,即 Li_{0.38}Sr_{0.44}Ta_{0.7}Hf_{0.3}O_{2.95}F_{0.05},这是一种固态电解质,具有立方体型钙钛矿结构。为了方便,我们忽略F,只考虑Li、Sr、Ta、Hf、O五种元素,化合价分别为+1、+2、+5、+4、-2。细心的同学可能会发现电荷不平衡,不过没有关系。

首先我们要设计一下结构,为了对称这里我选择建一个 3x3x3 的超胞,则该结构化学式为:Li_{10}Sr_{12}Ta_{19}Hf_8O_{81}

pymatgen提供了多种建超胞的方法,可以通过structure的make_supercell()方法直接建,也可以通过SupercellTransformation类返回新的结构而不改变原结构。

OrderDisorderedStructureTransformation类

我们首先来看一下如何使用OrderDisorderedStructureTransformation类进行ordering,该类位于pymatgen.transformations.standard_transformations模块中:

class OrderDisorderedStructureTransformation(algo=0, symmetrized_structures=False, no_oxi_states=False)

可以看到,该类有三个可选参数:

  • algo,即algorithm,排序所用算法,默认为0,可以不用管
    • 0:ALGO_FAST
    • 1:ALGO_COMPLETE
    • 2:ALGO_BEST_FIRST
  • symmetrized_structures:是否为对称性结构,默认False
  • no_oxi_states:是否在ordering前去除氧化态,默认False,即不去除

氧化态即是否带电荷,我们的结构文件中是原子,因此不带电荷,而计算静电能需要知道每种元素的电荷,因为静电能是整体的电荷相互作用,没有电荷也就无法计算静电能了。我们可以通过Structure类的add_oxidation_state_by_element方法给元素添加氧化态,也可以通过该模块下的OxidationStateDecorationTransformation类进行添加。

属性与方法
属性:

  • lowest_energy_structure:具有最低能量的结构
  • _all_structures:存有ordering后结构的列表,结构以字典的形式储存。
  • inverse: 没什么意义,不用管
  • is_one_to_many: 是否返回多个结果,不用管

方法:apply_transformation(structure, return_ranked_list=False)
ordering的方法,structure为我们要排序的结构,return_ranked_list控制返回值:

  • False:默认值,返回Ewald能最低的结构
  • 整数:返回该数量的结构,以字典列表的形式,每个结构储存在一个字典中,字典还包括其他信息,可以通过structure 键来访问。

代码:

import os
from pymatgen.io.cif import CifParser, CifWriter
from pymatgen.transformations.standard_transformations import SubstitutionTransformation, OrderDisorderedStructureTransformation, SupercellTransformation

# read in the CaTiO3 structure from cif file 
filename = 'CaTiO3_mp-5827_symmetrized.cif'
parser = CifParser(filename)
init_structure = parser.get_structures()[0]

# add oxidation states to the structure
data = {"Ca":2, "Ti":4, "O":-2}
init_structure.add_oxidation_state_by_element(data)

# substitute to get the partial occupancied structure
species_map = {"Ca2+":{"Li1+":0.38, "Sr2+":0.44},"Ti4+":{"Ta5+":0.7,"Hf4+":0.3}}
substitutuin = SubstitutionTransformation(species_map)
structure = substitutuin.apply_transformation(init_structure)
``
# make a 3x3x3 supercell
structure.make_supercell(3)
'''
# you can also use the SupercellTransformation class to achieve it
sc = SupercellTransformation().from_scaling_factors(3,3,3)
supercell = sc.apply_transformation(structure)
'''

# ordering,here we set return_ranked_list as 100 to get 100 structures
order = OrderDisorderedStructureTransformation()
standard_structures = order.apply_transformation(structure,return_ranked_list=100)

# save ordered structures to files
if !os.path.exists('ordering'):
    os.mkdir('ordering')
i = 1
for s in ordered_structures:
    cif = CifWriter(s['structure'])
    cif.write_file('ordering/structure_{:0>3d}.cif'.format(i))
    i+=1

当你运行这段代码的时候,你会发现程序会报错:

ValueError: Occupancy fractions not consistent with size of unit cell

这是为什么呢?我们查看一下该类的源码,找到出错的位置:

for k, v in total_occupancy.items():
    if abs(v - round(v)) > 0.25:
        raise ValueError("Occupancy fractions not consistent "
                         "with size of unit cell")

再来看看文档中对该类的说明:

simple rounding of the occupancies are performed, with no attempt made to achieve a target composition. This is usually not a problem for most ordering problems, but there can be times where rounding errors may result in structures that do not have the desired composition.

龟龟,文档中说会简单地取整,应该可以理解为四舍五入,然鹅,代码中设置了限制,超过0.25就不给算了,而对Li:0.38 x 27 = 10.26 比我们取的10大了0.26,已经超过了0.25,我们对代码做一下修改,把0.38改为0.37,此时:0.37 x 27 = 9.99 就没得问题了:

# substitute to get the partial occupancied structure
species_map = {"Ca2+":{"Li1+":0.37, "Sr2+":0.44},"Ti4+":{"Ta5+":0.7,"Hf4+":0.3}}
substitutuin = SubstitutionTransformation(species_map)
structure = substitutuin.apply_transformation(init_structure)

再次运行程序,我的电脑陷入了沉思...
看一下说明:

The algorithm can currently compute approximately 5,000,000 permutations per minute.

这个算法每分钟能处理大约5百万个结果,但是我们有上亿种结构,因此需要程序跑几分钟。当然如果你用超算或者服务器的话应该会快一点。

程序运行完后,你会发现脚本目录下多了一个 ordering 文件夹,里面有我们order后的结构,文件名形如 structure_***.cif 的形式,结构是根据ewald energy / atom由低到高排列的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 226,333评论 6 524
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 97,345评论 3 411
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 173,869评论 0 370
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 61,897评论 1 305
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 70,790评论 6 404
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 54,288评论 1 318
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 42,449评论 3 433
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 41,579评论 0 282
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 48,092评论 1 329
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 40,080评论 3 352
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 42,192评论 1 362
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,767评论 5 354
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 43,491评论 3 342
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,860评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 35,070评论 1 278
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,793评论 3 385
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 47,218评论 2 369

推荐阅读更多精彩内容

  • ROS学习笔记1(基础知识和ROS架构) 文章目录 ROS学习笔记1(基础知识和ROS架构) 1. 什...
    A_MARK阅读 349评论 0 0
  • 为何而生 为何而逝 为何而喜 为何而悲 只为了 伸手就可以碰触到的 那一抹阳光 温暖 宁静
    静凤竹阅读 287评论 1 3
  • 对年轻人来说,谈论爱情不仅成了一种需求,更是一种时尚。我们渴望爱,追索爱,在得到时喜悦癫狂,在失去时堕落绝望。可事...
    Jellyyyy阅读 1,088评论 1 0
  • 一、当前读和快照读: 1.、快照读(snapshot read): 简单的select操作(不包括 select ...
    墨殇染泪阅读 476评论 0 1
  • 一个宿舍六个人 一个和热恋的男友打电话玩游戏写作业,样样东西有条不紊 一个天天背着书包出宿舍,一副努力认真写作业,...
    榆林境阅读 244评论 0 0