高性能计算服务
>
软件专区
>
最佳实践
>
以 LiCoO2 正极材料为例:快速分析脱锂结构凸包图并绘制理论电压曲线
随着锂离子电池在新能源汽车、消费电子和储能中的广泛应用,对其正极材料的微观结构与电化学性能的研究日益深入。LiCoO₂(钴酸锂)作为最早商业化的层状正极材料之一,其脱锂过程中的结构稳定性和电压行为一直是研究的重点。
为了深入理解LiCoO₂在充放电过程中Li含量变化所引发的结构和热力学稳定性变化,研究者借助第一性原理计算构建其脱锂过程中的吉布斯自由能凸包图(Convex Hull),并基于此进一步绘制理论电压曲线,从而预测其电压平台、相变路径及多相共存区间。
本次实操,我们以LiCoO2正极材料为例,基于超算互联网使用VASP与Pymatgen、Disorder 快速分析脱锂结构凸包图并绘制理论电压曲线,展示了从材料计算到电化学性能预测的完整流程,并提供详尽的Python脚本,为进一步研究锂离子电池正极材料的脱嵌锂机制及其结构-性能关系提供了全面可复现的工作流框架。
首先,在超算互联网使用pip一键安装:pip install pymatgen
官网:https://pymatgen.org/installation.html
disorder 是一种开源软件,用于生成不可约的位点占有配置(即对称不等价的无序结构),它可以极其有效地建模多组分合金或晶格缺陷(例如取代和空位)。在本案例中,将使用disorder来生成LiCoO2不同脱锂态的结构。
Github地址:https://github.com/jichunlian/disorder/tree/main
依次在命令行运行:
# 解压
unzip disorder-main.zip
# 进入文件夹
cd disorder-main
# 安装
make
make clean
# 添加到环境
export PATH=$PATH:disorder_installation_path/disorder-main/bin
为什么要使用disorder?
总所周知,脱锂态的结构实际上是删掉结构中的Li原子,引入空位来生成对应脱锂态化学式的结构。
例如本案例采用2x2x1超胞的LiCoO2结构,包含12个Li原子,12个Co原子,24个O原子。如果我们要得到Li11Co12O24的脱锂态结构,我们只需要删掉一个Li原子即可,而考虑到对称性的话,结构满锂态下所有的Li原子都是等价的,所以此时我们随意删掉一个Li原子即可。
如果继续生成Li10Co12O24的脱锂态结构,此时由于空位有两个,所有的可能结构数量为$C^2_{12} = 66$。当然里面包含了很多对称性重复的结构,而此时disorder的作用便是在此基础上进行对称性去重,来极大的缩减我们的实际计算量。
disorder的使用需要准备两个文件,以生成Li0.5CoO2脱锂态结构为例:
初始的结构文件需要是满锂态晶体结构文件,格式与vasp的POSCAR一致,只是重命名为SPOSCAR
Li12 Co12 O24
1.0
5.6225137710000004 0.0000000000000000 0.0000000000000000
-2.8112568856000002 4.8692397588000000 0.0000000000000000
0.0000000000000000 0.0000000000000000 13.9094562531000001
Li Co O
12 12 24
direct
0.0000000000000000 0.0000000000000000 0.0000000000000000 Li
0.0000000000000000 0.5000000000000000 0.0000000000000000 Li
0.5000000000000000 0.0000000000000000 0.0000000000000000 Li
0.5000000000000000 0.5000000000000000 0.0000000000000000 Li
0.3333333434999999 0.1666666715000000 0.3333333430000000 Li
0.3333333435000000 0.6666666715000000 0.3333333430000000 Li
0.8333333435000000 0.1666666715000000 0.3333333430000000 Li
......
......
&input
nsub = 2
subs = 6,6
symb = 'Li','Kw' ! The quotes is unnecessary for the ifort compiler
site = 1
prec = 1D-5
lpro = .true.
lpos = .true.
! leqa = .true.
! lspg = .true.
lcfg = .false.
/
关键参数说明:
nsub
:表示掺杂的元数,这里脱锂的结构可以理解为Li原子和空位在Li位点进行掺杂,所以设置2即可;
subs
:位点的数量分配,与symb
一一对应,这里分别分配6个Li和6个空位,即此时生成的是Li0.5CoO2脱离态结构;
symb
:对应的元素符号,与subs
一一对应,空位 "Kw" 的表示为拼音“kongwei"缩写,K大写;
site
:掺杂位点在SPOSCAR中的顺序,根据上面的SPOSCAR可知,Li位点为第一个,因此设置为1。
lpos
:true—生成POSCAR文件;false—只输出生成结构数量信息,不会生成POSCAR文件
以生成$Li_{0.5}CoO_2$脱锂态结构为例。$2\times2\times1$满锂结构的原子为$Li_{12}Co_{12}O_{24}$,包含12个Li。
&input
nsub = 2
subs = 6,6
symb = 'Li','Kw' ! The quotes is unnecessary for the ifort compiler
site = 1
prec = 1D-5
lpro = .true.
lpos = .true.
! leqa = .true.
! lspg = .true.
lcfg = .false.
/
disorder
,会在当前路径下生成poscar
文件夹,里面包含了所有的不重复计量比为$Li_{0.5}CoO_2$的脱锂态结构:输出结果:
poscar
文件夹中生成17个不重复的结构:同理,我们可以把从Li1~Li11所有脱锂态的结构批量生成。Li0结构唯一,即把满锂结构中所有Li原子删掉即可。
NOTE:INDSOD文件中subs
和symb
推进按照原子数量从小到大进行排列。
此时当前路径下应该包含所有Li1~Li11的脱锂态结构:
.
├── Li1
│ ├── INDSOD
│ ├── poscar
│ │ └── POSCAR-1
│ └── SPOSCAR
├── Li10
│ ├── INDSOD
│ ├── poscar
│ │ ├── POSCAR-1
│ │ ├── POSCAR-2
│ │ └── POSCAR-3
│ └── SPOSCAR
├── Li11
│ ├── INDSOD
│ ├── poscar
│ │ └── POSCAR-1
│ └── SPOSCAR
├── Li2
│ ├── INDSOD
│ ├── poscar
│ │ ├── POSCAR-1
│ │ ├── POSCAR-2
│ │ └── POSCAR-3
│ └── SPOSCAR
├── Li3
│ ├── INDSOD
│ ├── poscar
│ │ ├── POSCAR-1
│ │ ├── POSCAR-2
│ │ ├── POSCAR-3
│ │ ├── POSCAR-4
│ │ ├── POSCAR-5
│ │ └── POSCAR-6
│ └── SPOSCAR
├── Li4
│ ├── INDSOD
│ ├── poscar
│ │ ├── POSCAR-01
│ │ ├── POSCAR-02
│ │ ├── POSCAR-03
│ │ ├── POSCAR-04
│ │ ├── POSCAR-05
│ │ ├── POSCAR-06
│ │ ├── POSCAR-07
│ │ ├── POSCAR-08
│ │ ├── POSCAR-09
│ │ ├── POSCAR-10
│ │ └── POSCAR-11
│ └── SPOSCAR
├── Li5
│ ├── INDSOD
│ ├── poscar
│ │ ├── POSCAR-01
│ │ ├── POSCAR-02
│ │ ├── POSCAR-03
│ │ ├── POSCAR-04
│ │ ├── POSCAR-05
│ │ ├── POSCAR-06
│ │ ├── POSCAR-07
│ │ ├── POSCAR-08
│ │ ├── POSCAR-09
│ │ ├── POSCAR-10
│ │ ├── POSCAR-11
│ │ ├── POSCAR-12
│ │ └── POSCAR-13
│ └── SPOSCAR
├── Li6
│ ├── INDSOD
│ ├── poscar
│ │ ├── POSCAR-01
│ │ ├── POSCAR-02
│ │ ├── POSCAR-03
│ │ ├── POSCAR-04
│ │ ├── POSCAR-05
│ │ ├── POSCAR-06
│ │ ├── POSCAR-07
│ │ ├── POSCAR-08
│ │ ├── POSCAR-09
│ │ ├── POSCAR-10
│ │ ├── POSCAR-11
│ │ ├── POSCAR-12
│ │ ├── POSCAR-13
│ │ ├── POSCAR-14
│ │ ├── POSCAR-15
│ │ ├── POSCAR-16
│ │ └── POSCAR-17
│ └── SPOSCAR
├── Li7
│ ├── INDSOD
│ ├── poscar
│ │ ├── POSCAR-01
│ │ ├── POSCAR-02
│ │ ├── POSCAR-03
│ │ ├── POSCAR-04
│ │ ├── POSCAR-05
│ │ ├── POSCAR-06
│ │ ├── POSCAR-07
│ │ ├── POSCAR-08
│ │ ├── POSCAR-09
│ │ ├── POSCAR-10
│ │ ├── POSCAR-11
│ │ ├── POSCAR-12
│ │ └── POSCAR-13
│ └── SPOSCAR
├── Li8
│ ├── INDSOD
│ ├── poscar
│ │ ├── POSCAR-01
│ │ ├── POSCAR-02
│ │ ├── POSCAR-03
│ │ ├── POSCAR-04
│ │ ├── POSCAR-05
│ │ ├── POSCAR-06
│ │ ├── POSCAR-07
│ │ ├── POSCAR-08
│ │ ├── POSCAR-09
│ │ ├── POSCAR-10
│ │ └── POSCAR-11
│ └── SPOSCAR
├── Li9
│ ├── INDSOD
│ ├── poscar
│ │ ├── POSCAR-1
│ │ ├── POSCAR-2
│ │ ├── POSCAR-3
│ │ ├── POSCAR-4
│ │ ├── POSCAR-5
│ │ └── POSCAR-6
│ └── SPOSCAR
将上面得到的所有脱锂态(包括Li0和Li12)用vasp进行优化计算,用pymatgen读取vasprun.xml文件可获取所有结构的computed_entry
用于自动生成脱锂凸包图,代码示例如下:
from pymatgen.entries.computed_entries import ComputedEntry
from pymatgen.io.vasp.outputs import Vasprun
vasprun = Vasprun('/path/vasprun.xml')
entry = vasprun.get_computed_entry()
为了获得一个包含所有结构的entries
,只需要循环处理所有vasprun.xml文件并append,即可生成一个包含所有结构entry的entries
列表:
from pymatgen.entries.computed_entries import ComputedEntry
from pymatgen.io.vasp.outputs import Vasprun
import os
work_dir = os.getcwd()
# 遍历Li0~Li12文件夹及子文件夹获取所有vasprun.xml文件
states = [state for state in os.listdir(work_dir) if os.path.isdir(os.path.join(work_dir,state))]
entries = []
for state in states:
try:
# 遍历poscar文件夹中所有结构的计算文件夹
folds = [fold for fold in os.listdir(poscar_dir) if os.path.isdir(os.path.join(poscar_dir, fold))]
for fold in folds:
vasprun = Vasprun(os.path.join(poscar_dir, fold, 'vasprun.xml'))
con_entry = vasprun.get_computed_entry()
entries.append(con_entry)
except Exception as e:
print(f"error in {state}-{fold}: {e}")
继续调用CompoundPhaseDiagram
和PDPlotter
方法来分析并绘制凸包图:
from pymatgen.analysis.phase_diagram import CompoundPhaseDiagram, PDPlotter
PD = CompoundPhaseDiagram(entries, terminal_compositions=[Composition('Co12O24'),Composition('Li12Co12O24')], normalize_terminal_compositions=False)
plotter = PDPlotter(PD, show_unstable=True)
fig = plotter.get_plot()
fig.update_layout(dict(paper_bgcolor='white',
xaxis_title="Lithiation"))
fig.write_html('/path/phase_diagram.html')
打开html可以在外部浏览器阅览plotly
图片,plotly
是一个可以交互的对象,当把鼠标移到数据点上时会显示能量等信息:
如果需要保存为png
格式图片,可直接点击plotly
图片最上面保存图片按钮进行保存:
理论电压平台的计算公式为:
$$ \bar{V}(x_1,x_2) = -\frac{E(\text{Li}_{x_1}\text{MO}2) - E(\text{Li}\text{MO}_2) - (x_1 - x_2)E(\text{Li})}{zF} $$
其中$x_1,x_2$为凸包图中位于凸包线上的点。
使用pymatgen可以直接根据凸包线上稳定结构的entry自动分析出理论电压平台,通过下面的代码我们可以自动找出位于凸包线上的稳定结构:
from pymatgen.analysis.phase_diagram import *
PD = CompoundPhaseDiagram(entries, terminal_compositions=[Composition('Co12O24'),Composition('Li12Co12O24')], normalize_terminal_compositions=False)
stable_entries = PD.stable_entries
stable_list = []
for s_entry in stable_entries:
for entry in entries:
if entry.formula == s_entry.formula and entry.energy == s_entry.energy:
stable_list.append(entry)
print(f"稳定结构有:{len(stable_list)} 个")
for i in stable_list:
print(i.formula)
输出:
稳定结构有:4 个
Li6 Co12 O24
Co12 O24
Li12 Co12 O24
Li3 Co12 O24
然后调用VoltageProfilePlotter
和InsertionElectrode
可以直接生成理论电压平台结果,在此之前我们还计算一个bulk-Li来得到对应的工作电极的entry
,完整代码如下:
from pymatgen.apps.battery.insertion_battery import InsertionElectrode
from pymatgen.apps.battery.plotter import VoltageProfilePlotter
from pymatgen.io.vasp.outputs import Vasprun
# Li entry
Li_vasprun = Vasprun('/Li/vasprun.xml')
Li_entry = Li_vasprun.get_computed_entry()
ie = InsertionElectrode.from_entries(stable_list, Li_entry)
vpp = VoltageProfilePlotter()
vpp.add_electrode(electrode=ie)
vpp.get_plotly_figure()
运行代码后可直接得到理论电压平台的plotly
格式图片:
以上,我们就完成了以经典层状正极材料 LiCoO₂为例,使用VASP进行第一性原理能量计算,并结合pymatgen、disorder对脱锂结构进行自动处理与分析,快速构建凸包图并绘制理论电压曲线的全流程,为研究人员提供了全面且易于操作的计算范式。
参考资料: