8 辅助工具使用教程

备注

用DSPAW完成DFT计算后,想快速分析结果、画图,或者完成一些常见的数据处理任务?

dspawpyPython ≥ 3.8 )就是这样一款辅助工具,它可以编程调用(参考下文示例脚本),也提供了一个命令行交互程序

参考下方教程 安装 后,命令行输入 dspawpy 后回车即可使用交互程序:

 ... loading dspawpy cli ...

 ********这是dspawpy命令行交互小工具,预祝您使用愉快********
    ( )
   _| |  ___  _ _      _ _  _   _   _  _ _    _   _
 /'_` |/',__)( '_`\  /'_` )( ) ( ) ( )( '_`\ ( ) ( )
( (_| |\__, \| (_) )( (_| || \_/ \_/ || (_) )| (_) |
 \__,_)(____/| ,__/'`\__,_) \___x___/ | ,__/  \__, |
             | |                      | |    ( )_| |
             (_)                      (_)     \___/

 [版本号]: [安装路径]

 ======================================
 |  1: update更新
 |  2: structure结构转化
 |  3: volumetricData数据处理
 |  4: band能带数据处理
 |  5: dos态密度数据处理
 |  6: bandDos能带和态密度共同显示
 |  7: optical光学性质数据处理
 |  8: neb过渡态计算数据处理
 |  9: phonon声子计算数据处理
 |  10: aimd分子动力学模拟数据处理
 |  11: Polarization铁电极化数据处理
 |  12: ZPE零点振动能数据处理
 |  13: TS的热校正能
 |
 |  q: 退出
 ======================================
 --> 输入数字后回车选择功能:

亮点:

  • 自动补全: 按Tab键即可生效,有助于快速且正确地输入程序所需要的参数

  • 多线程懒加载:在等待用户输入时后台加载模块,大幅缩短等待时间;仅加载必要模块,减少内存占用

注意:

  • 在远程服务器上使用时,由于机器的磁盘读写性能不佳,可能需要较长的启动时间,极端情况下可能长达半分钟(与服务器当时的磁盘读写性能直接相关)。如果无法忍受,请在自己的电脑上安装dspawpy使用

  • 输入 cli 回车后,python会先加载内建模块,完成后显示 … loading dspawpy cli … 提示语句,表明进入第二阶段(开始加载第三方依赖库)

  • 等待第二阶段完成后,会显示欢迎界面,此时dspwapy已完成前期加载,进入第三阶段。后续将动态根据选择的功能模块加载相应的依赖库,从而最大限度减少等待时间

8.1 安装与更新

  1. 在HZW机器上,已提前安装 dspawpy,使用以下命令激活虚拟环境即可使用:

source /data/hzwtech/profile/dspawpy.env
  1. 在其他机器上,请自行安装 dspawpy(下列两种方式二选一):

mamba install dspawpy -c conda-forge
#conda install dspawpy -c conda-forge
  • 或使用 pip3 (部分操作系统中没有pip3可执行程序,此时请尝试pip)

pip
  • pip3 是 python3 自带的包管理器

  • Linux和Mac一般自带python3和pip3。

  • Windows平台打开 microsoft store 搜索 python 安装即可

_images/python_ms_store.png

然后打开 cmd 或者 powershell 即可使用 pip。

pip3 install dspawpy

关于如何设置pip和conda镜像地址以加速安装过程,可参考 https://mirrors.tuna.tsinghua.edu.cn/help/pypi/https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/

如果安装依然失败,请尝试上面的 mamba/conda 安装法。

警告

在集群上,由于权限问题,公共路径中的pip很可能不支持全局安装python库,必须在 pip install 后面追加 --user 选项安装到家目录 ~/.local/lib/python3.x/site-packages/ 下,其中3.x表示python解释器版本,x可能是8-12之间的任意整数

python将优先读取家目录下的dspawpy,即使公共环境中的dspawpy的版本比家目录中的dspawpy的版本新! 因此,如果以前用 --user 安装过dspawpy,又忘记手动更新家目录下的老版本dspawpy,即使source了公共环境,也无法调用公共环境中的dspawpy,依旧会使用老版本dspawpy,导致一些BUG。

因此,鉴于HZW集群每周自动更新dspawpy,建议不要在家目录下重复安装,已安装的建议删除 。如果在其他集群上,请确保及时手动更新家目录下的 dspawpy

如果不想删除家目录中的dspawpy,又不想更新它,可以在运行python脚本时,尝试 -s 选项避免导入家目录中的 dspawpy: python -s your-script.py。cli 不支持这个命令行选项

更新 dspawpy

如果 dspawpy 是通过 mamba/conda 安装的,使用以下命令更新:

mamba update dspawpy
#conda update dspawpy

如果 dspawpy 是通过 pip 安装的,那么:

pip install dspawpy -U # -U 表示安装最新版

备注

如果 pip 使用了国内的镜像网站,可能由于镜像网站尚未同步最新版 dspawpy dspawpy_version 而导致无法顺利升级,请使用如下命令告诉 pip 从pypi官网下载安装:

pip install dspawpy -i https://pypi.org/simple --user -U # -i 指定下载地址,--user 表示仅为当前用户安装,-U 表示安装最新版

如果运行时出现 dspawpy 相关 错误信息,请先检查是否已正确导入最新版本的 dspawpy 并检查安装路径:

$ python3 # 或 python
>>> import dspawpy
>>> dspawpy.__version__ # 将输出版本号
>>> dspawpy.__file__ # 将输出安装路径

8.2 structure结构转化

读取结构信息使用 read 函数;将结构信息写入文件,使用 write 函数;快速结构转化,使用 convert 函数:

API: read(), write(), convert()
dspawpy.io.structure.convert(infile, si=None, ele=None, ai=None, infmt: Optional[str] = None, task: str = 'scf', outfile: str = 'temp.xyz', outfmt: Optional[str] = None, coords_are_cartesian: bool = True)

从infile中读取结构信息,完成格式转化后写入outfile

  • 多构型 -> 单构型,仅写入最后一个离子步信息

  • 晶体结构 -> 分子结构,将丢失晶胞信息

  • 分子结构 -> 晶体结构,将添加一个2倍最大原子xyz坐标的晶胞

  • pdb 和 dump 格式可能存在浮点数精度损失

参数
  • infile (str or list) –

    • h5/json/as/hzw/cif/poscar/cssr/xsf/mcsqs/prismatic/yaml/fleur-inpgen文件路径;

    • 若给定文件夹路径,可配合task参数读取内部的 {task}.h5/json 文件

    • 若给定字符串列表,将依次读取数据并合并成一个Structures列表

  • si (int, list or str) –

    • 构型编号,从 1 开始

      • si=1, 读取第一个构型

      • si=[1,2], 读取第一个和第二个构型

      • si=’:’, 读取所有构型

      • si=’-3:’, 读取最后三个构型

    • 若为空,多构型文件将读取所有构型,单构型文件将读取最新构型

    • 此参数仅对 h5/json 文件有效

  • ele (str or list) –

    • 元素符号,写法参考:’H’ 或 [‘H’,’O’]

    • 若为空,将读取所有元素的原子信息

    • 此参数仅对 h5/json 文件有效

  • ai (int or list or str) –

    • 原子编号,从 1 开始

    • 用法同si

    • 若为空,将读取所有原子信息

    • 此参数仅对 h5/json 文件有效

  • infmt (str) –

    • 输入结构文件类型,例如 ‘h5’,如果为None,则根据文件后规则判断

  • task (str) –

    • 用于当 datafile 为文件夹路径时,寻找内部的 {task}.h5/json 文件。

    • 计算任务类型,包括 ‘scf’, ‘relax’, ‘neb’, ‘aimd’ 四种,其他值将被忽略。

  • outfile (str) –

    • 输出文件名

  • outfmt (str) –

    • 输出结构文件类型,例如 ‘xyz’,如果为None,则根据文件后规则判断

  • coords_are_cartesian (bool) –

    • 是否写作笛卡尔坐标,默认为True;否则写成分数坐标形式

    • 此选项暂时仅对 as 和 json 格式有效

实际案例

>>> from dspawpy.io.structure import convert
>>> convert('dspawpy_proj/dspawpy_tests/inputs/supplement/PtH.as', outfile='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.hzw') 
==> ...PtH.hzw

格式转换批量测试

>>> for readable in ['relax.h5', 'system.json', 'aimd.pdb', 'latestStructure.as', 'CuO.hzw', 'POSCAR']:
...     for writable in ['pdb', 'xyz', 'dump', 'as', 'hzw', 'POSCAR']:
...         convert('dspawpy_proj/dspawpy_tests/inputs/supplement/stru/'+readable, outfile=f"dspawpy_proj/dspawpy_tests/outputs/doctest/{readable.split('.')[0]}.{writable}") 
==> ...relax.pdb
==> ...relax.xyz
==> ...relax.dump
==> ...relax.as
==> ...relax.hzw
==> ...system.pdb
==> ...system.xyz
==> ...system.dump
==> ...system.as
==> ...system.hzw
==> ...aimd.pdb
==> ...aimd.xyz
==> ...aimd.dump
==> ...aimd.as
==> ...aimd.hzw
==> ...latestStructure.pdb
==> ...latestStructure.xyz
==> ...latestStructure.dump
==> ...latestStructure.as
==> ...latestStructure.hzw
==> ...CuO.pdb
==> ...CuO.xyz
==> ...CuO.dump
==> ...CuO.as
==> ...CuO.hzw
==> ...POSCAR.pdb
==> ...POSCAR.xyz
==> ...POSCAR.dump
==> ...POSCAR.as
==> ...POSCAR.hzw
dspawpy.io.structure.read(datafile: Union[str, list], si=None, ele=None, ai=None, fmt: Optional[str] = None, task: Optional[str] = 'scf')

读取一/多个h5/json文件,返回pymatgen的Structures列表

参数
  • datafile (str or list) –

    • h5/json/as/hzw/cif/poscar/cssr/xsf/mcsqs/prismatic/yaml/fleur-inpgen文件路径;

    • 若给定文件夹路径,可配合task参数读取内部的 {task}.h5/json 文件

    • 若给定字符串列表,将依次读取数据并合并成一个Structures列表

  • si (int, list or str) –

    • 构型编号,从 1 开始

      • si=1, 读取第一个构型

      • si=[1,2], 读取第一个和第二个构型

      • si=’:’, 读取所有构型

      • si=’-3:’, 读取最后三个构型

    • 若为空,多构型文件将读取所有构型,单构型文件将读取最新构型

    • 此参数仅对 h5/json 文件有效

  • ele (str or list) –

    • 元素符号,写法参考:’H’ 或 [‘H’,’O’]

    • 若为空,将读取所有元素的原子信息

    • 此参数仅对 h5/json 文件有效

  • ai (int or list or str) –

    • 原子编号,从 1 开始

    • 用法同si

    • 若为空,将读取所有原子信息

    • 此参数仅对 h5/json 文件有效

  • fmt (str) –

    • 文件格式,包括 ‘as’, ‘hzw’, ‘xyz’, ‘pdb’, ‘h5’, ‘json’ 6种,其他值将被忽略。

    • 若为空,文件类型将依据文件名称惯例判断。

  • task (str) –

    • 用于当 datafile 为文件夹路径时,寻找内部的 {task}.h5/json 文件。

    • 计算任务类型,包括 ‘scf’, ‘relax’, ‘neb’, ‘aimd’ 四种,其他值将被忽略。

返回

pymatgen_Structures – 结构列表

返回类型

List[Structure]

实际案例

>>> from dspawpy.io.structure import read

读取单个文件生成 Structures 列表

>>> pymatgen_Structures = read(datafile='dspawpy_proj/dspawpy_tests/inputs/supplement/PtH.as')
>>> len(pymatgen_Structures)
1
>>> pymatgen_Structures = read(datafile='dspawpy_proj/dspawpy_tests/inputs/supplement/PtH.hzw')
>>> len(pymatgen_Structures)
1
>>> pymatgen_Structures = read(datafile='dspawpy_proj/dspawpy_tests/inputs/supplement/Si2.xyz')
>>> len(pymatgen_Structures)
1
>>> pymatgen_Structures = read(datafile='dspawpy_proj/dspawpy_tests/inputs/supplement/aimd.pdb')
>>> len(pymatgen_Structures)
1000
>>> pymatgen_Structures = read(datafile='dspawpy_proj/dspawpy_tests/inputs/2.1/relax.h5') 
>>> len(pymatgen_Structures)
3
>>> pymatgen_Structures = read(datafile='dspawpy_proj/dspawpy_tests/inputs/2.1/relax.json') 
>>> len(pymatgen_Structures)
3

注意pymatgen_Structures是由多个 Structure 对象组成的列表,每个 Structure 对象分别对应一个构型。如果只有一个构型,也会返回列表,请使用 pymatgen_Structures[0] 获取 Structure 对象

当datafile为列表时,将依次读取多个文件,合并成一个Structures列表

>>> pymatgen_Structures = read(datafile=['dspawpy_proj/dspawpy_tests/inputs/supplement/aimd1.h5','dspawpy_proj/dspawpy_tests/inputs/supplement/aimd2.h5']) 
dspawpy.io.structure.write(structure, filename: str, fmt: Optional[str] = None, coords_are_cartesian: bool = True)

往结构文件中写入信息

参数
  • structure (Structure) – pymatgen的Structure对象

  • filename (str) – 结构文件名

  • fmt (str) –

    • 结构文件类型,原生支持 ‘json’, ‘as’, ‘hzw’, ‘pdb’, ‘xyz’, ‘dump’ 六种

  • coords_are_cartesian (bool) –

    • 是否写作笛卡尔坐标,默认为True;否则写成分数坐标形式

    • 此选项暂时仅对 as 和 json 格式有效

实际案例

先读取结构信息:

>>> from dspawpy.io.structure import read
>>> s = read('dspawpy_proj/dspawpy_tests/inputs/2.15/01/neb01.h5') 
>>> len(s)
17

将结构信息写入文件:

>>> from dspawpy.io.structure import write
>>> write(s, filename='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.json', coords_are_cartesian=True) 
==> ...PtH.json
>>> write(s, filename='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.as', coords_are_cartesian=True) 
==> ...PtH.as
>>> write(s, filename='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.hzw', coords_are_cartesian=True) 
==> ...PtH.hzw

pdb, xyz, dump 三种类型的文件,可以写入多个构型,形成“轨迹”。生成的 xyz 等轨迹文件可使用 OVITO 等可视化软件打开观察。

>>> write(s, filename='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.pdb', coords_are_cartesian=True) 
==> ...PtH.pdb
>>> write(s, filename='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.xyz', coords_are_cartesian=True) 
==> ...PtH.xyz
>>> write(s, filename='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.dump', coords_are_cartesian=True) 
==> ...PtH.dump

单结构信息推荐使用 as 格式存储,如果 Structure 中有磁矩或自由度信息,将会按最完整的格式统一写入,形如 Fix_x, Fix_y, Fix_z, Mag_x, Mag_y, Mag_z,自由度信息默认为 F,磁矩默认为 0.0。可视情况自行手动删除生成的 as 文件中的这些默认信息。写成其他类型的结构文件,将忽略磁矩和自由度信息

可参考 2conversion.py 脚本完成转化:

 1from dspawpy.io.structure import convert
 2
 3convert(
 4    infile="dspawpy_proj/dspawpy_tests/inputs/2.1/relax.h5",  # 待转化结构,如果在当前路径,可以只写文件名
 5    si=None,  # 筛选构型编号,如果不指定,默认读取全部
 6    ele=None,  # 筛选元素符号,默认读取所有元素的原子信息
 7    ai=None,  # 筛选原子编号,从 1 开始,默认读取所有原子信息
 8    infmt=None,  # 输入结构文件类型,例如 'h5',如果为None,将根据文件名规则模糊匹配
 9    task="relax",  # 任务类型,此参数仅当 infile 为文件夹而非文件名时有效
10    outfile="dspawpy_proj/dspawpy_tests/outputs/us/relaxed.xyz",  # 结构文件名
11    outfmt=None,  # 输出结构文件类型,例如 'xyz',如果为None,将根据文件名规则模糊匹配
12    coords_are_cartesian=True,  # 默认以笛卡尔坐标写入
13)

convert 函数的几个关键参数设置规则见下表:

dspawpy 支持读写的结构文件列表

infmt(输入文件格式)

infile(输入文件名模糊匹配)

outfmt(输出文件格式)

outfile(输出文件名模糊匹配)

说明

h5

*.h5

X

X

DS-PAW计算完成后保存的hdf5类型文件

json

*.json

json

*.json

DS-PAW计算完成后保存的json类型文件

pdb

*.pdb

pdb

*.pdb

Protein Data Bank

as

*.as

as

*.as

DS-PAW记载原子坐标等信息的结构文件

hzw

*.hzw

hzw

*.hzw

DeviceStudio默认的结构文件

xyz

*.xyz

xyz

*.xyz

读取时仅支持分子结构的单构型,写入时则是包含晶胞的extended-xyz类型轨迹文件

X

X

dump

*.dump

lammps-dump类型轨迹文件

X

*.cif*/*.mcif*

cif/mcif

*.cif*/*.mcif*

Crystallographic Information File

X

*POSCAR*/*CONTCAR*/*.vasp/CHGCAR*/LOCPOT*/vasprun*.xml*

poscar

*POSCAR*

VASP文件

X

*.cssr*

cssr

*.cssr*

Crystal Structure Standard Representation

X

*.yaml/*.yml

yaml/yml

*.yaml/*.yml

YAML Ain’t Markup Language

X

*.xsf*

xsf

*.xsf*

eXtended Structural Format

X

*rndstr.in*/*lat.in*/*bestsqs*

mcsqs

*rndstr.in*/*lat.in*/*bestsqs*

Monte Carlo Special Quasirandom Structure

X

inp*.xml/*.in*/inp_*

fleur-inpgen

*.in*

FLEUR 结构文件,须额外安装 pymatgen-io-fleur 库

X

*.res

res

*.res

ShelX res 结构文件

X

*.config*/*.pwmat*

pwmat

*.config/*.pwmat

PWmat 文件

X

X

prismatic

*prismatic*

用于STEM模拟的一种文件格式

X

CTRL*

X

X

Stuttgart LMTO-ASA 文件

备注

  • 上述表格中 * 号表示任意字符,X 表示不支持

  • h5, json, pdb, xyz, dump, CONTCAR等格式支持多个结构组成的轨迹信息(常见于结构优化或者NEB或者AIMD任务)

  • in(out)fmt 参数优先级高于文件名模糊匹配规则;例如,指定 in(out)fmt=’h5’ 后,文件名可以是任意值,甚至可以是 a.json

  • 将结构信息写为 json 格式时,仅支持可视化 NEB 链任务,详见 观察NEB链 节相关说明

  • DS-PAW 输出的 neb.h5、phonon.h5、phonon.json、neb.json以及wannier.json 暂时无法读取结构信息

8.3 volumetricData数据处理

volumetricData可视化

  • 参考 3vis_vol.py

     1from dspawpy.io.write import write_VESTA
     2
     3# 读取数据文件(h5或json格式),处理后输出到cube文件
     4write_VESTA(
     5    in_filename="dspawpy_proj/dspawpy_tests/inputs/2.2/rho.h5",  # 包含电子体系信息的json或h5文件路径
     6    data_type="rho",  # 数据类型,支持 "rho", "potential", "elf", "pcharge", "rhoBound"
     7    out_filename="dspawpy_proj/dspawpy_tests/outputs/us/DS-PAW_rho.cube",  # 输出文件路径
     8    gridsize=(10, 10, 10),  # 指定插值网格大小
     9    format="cube",  # 支持cube, vesta和txt格式(xyz格点坐标+数值)
    10)
    

    将转换后的文件 DS-PAW_rho.cube 拖入 VESTA 软件中显示:

    _images/1-3.png

    晶体硅单胞的电荷密度分布示意图

差分volumetricData可视化

  • 参考 3dvol.py

     1from dspawpy.io.write import write_delta_rho_vesta
     2
     3# 读取数据文件(h5或json格式),处理后输出到cube文件,可直接使用vesta打开且体积小
     4write_delta_rho_vesta(
     5    total="dspawpy_proj/dspawpy_tests/inputs/supplement/AB.h5",  # 包含所有组元的体系的数据文件
     6    individuals=[
     7        "dspawpy_proj/dspawpy_tests/inputs/supplement/A.h5",
     8        "dspawpy_proj/dspawpy_tests/inputs/supplement/B.h5",
     9    ],  # 包含各组元的体系的数据文件
    10    output="dspawpy_proj/dspawpy_tests/outputs/us/3delta_rho.cube",  # 输出文件路径
    11)
    

    上述脚本支持处理多元体系的电荷密度差,示例以二元体系为例,得到了 AB.h5 与 A.h5 和 B.h5 之间的电荷密度差文件 delta_rho.cube ,该文件可直接使用 VESTA 打开。

volumetricData面平均

 1from dspawpy.plot import average_along_axis
 2
 3axes = ["2"]  # “0”, "1", "2" 分别对应xyz轴向,选择要沿着哪些轴平均
 4axes_indices = [int(i) for i in axes]
 5for ai in axes_indices:
 6    plt = average_along_axis(
 7        datafile="dspawpy_proj/dspawpy_tests/inputs/3.3/scf.h5",  # 数据文件路径
 8        task="potential",  # 任务名称,可以是 'rho', 'potential', 'elf', 'pcharge', 'rhoBound'
 9        axis=ai,  # 沿着哪个轴向绘制势能曲线
10        smooth=False,  # 是否平滑
11        smooth_frac=0.8,  # 平滑系数
12        subtype=None,  # 用于指定task数据子类,目前仅用于 Potential
13        label=f"axis{ai}",  # 图例标签
14    )
15if len(axes_indices) > 1:
16    plt.legend()
17
18plt.xlabel("Grid Index")
19plt.ylabel("TotalElectrostaticPotential (eV)")
20plt.savefig("dspawpy_proj/dspawpy_tests/outputs/us/3pot_ave.png", dpi=300)  # 图片名称

处理 应用案例 3.3 小节所得静电势文件,可得真空方向势函数曲线如下所示:

_images/3pot_ave.png

AuAl势函数示意图

API: write_VESTA(), write_delta_rho_vesta(), average_along_axis()
  • write_VESTA 函数负责处理volumetricData可视化:

    dspawpy.io.write.write_VESTA(in_filename: str, data_type: str, out_filename: str = 'DS-PAW.cube', subtype: Optional[str] = None, format: str = 'cube', compact: bool = False, inorm: bool = False, gridsize: Optional[Sequence[int]] = None)

    从包含电子体系信息的json或h5文件中读取数据并写入VESTA格式的文件中

    参数
    • in_filename (str) – 包含电子体系信息的json或h5文件路径

    • data_type (str) – 数据类型,支持 “rho”, “potential”, “elf”, “pcharge”, “rhoBound”

    • out_filename (str) – 输出文件路径, 默认 “DS-PAW.cube”

    • subtype (Optional[str]) – 用于指定data_type的数据子类型,默认为None,将读取 potential 的 TotalElectrostaticPotential 数据

    • format (str) – 输出的数据格式,支持 “cube” 和 “vesta” (”vasp”),默认为 “cube”,大小写不敏感

    • compact (bool) – 每个格点的数据都换行,通过减少空格数量减小文件体积(不会影响VESTA软件的解析),默认为False

    • inorm (bool) – 是否归一化体积数据,使其总和为1,默认为False

    • gridsize (Optional[Sequence[int]]) – 重新定义的格点数,格式为 (ngx, ngy, ngz),默认为None,即使用原始格点数

    返回

    out_filename – VESTA格式的文件

    返回类型

    file

    实际案例

    >>> from dspawpy.io.write import write_VESTA
    >>> write_VESTA("dspawpy_proj/dspawpy_tests/inputs/2.2/rho.json", "rho", out_filename='dspawpy_proj/dspawpy_tests/outputs/doctest/rho.cube') 
    ==> ...rho.cube
    
    >>> from dspawpy.io.write import write_VESTA
    >>> write_VESTA(
    ...     in_filename="dspawpy_proj/dspawpy_tests/inputs/2.7/potential.h5",
    ...     data_type="potential",
    ...     out_filename="dspawpy_proj/dspawpy_tests/outputs/doctest/my_potential.txt",
    ...     subtype='TotalElectrostaticPotential', # or 'TotalLocalPotential'
    ...     format='txt',
    ...     gridsize=(50,50,50), # all integer, can be larger or less than the original gridsize
    ... ) 
    Interpolating volumetric data...
    volumetric data interpolated
    ==> ...my_potential.txt
    >>> write_VESTA(
    ...     in_filename="dspawpy_proj/dspawpy_tests/inputs/2.8/elf.h5",
    ...     data_type="elf",
    ...     out_filename="dspawpy_proj/dspawpy_tests/outputs/doctest/elf.txt",
    ...     format='txt',
    ... ) 
    ==> ...elf.txt
    >>> write_VESTA(
    ...     in_filename="dspawpy_proj/dspawpy_tests/inputs/2.9/pcharge.h5",
    ...     data_type="pcharge",
    ...     out_filename="dspawpy_proj/dspawpy_tests/outputs/doctest/pcharge.txt",
    ...     format='txt',
    ... ) 
    ==> ...pcharge.txt
    
    >>> with open("dspawpy_proj/dspawpy_tests/outputs/doctest/my_potential.txt") as t:
    ...     contents = t.readlines()
    ...     for line in contents[:10]:
    ...         print(line.strip())
    # 2 atoms
    # 50 50 50 grid size
    # x y z value
    0.000 0.000 0.000      0.3279418
    0.055 0.055 0.000     -0.0740864
    0.110 0.110 0.000     -0.8811762
    0.165 0.165 0.000     -2.1283864
    0.220 0.220 0.000     -4.0559144
    0.275 0.275 0.000     -6.8291031
    0.330 0.330 0.000    -10.1550910
    

volumetricData 指的是随空间位置变化的物理量,如电荷密度 rho,势能函数 potential,局域电荷密度 elf,部分电荷密度 pcharge,溶剂束缚电荷密度 rhoBound 等。这些数据在 DS-PAW 中以 volumetricData 类型保存。

  • write_delta_rho_vesta 函数负责处理差分volumetricData可视化:

    dspawpy.io.write.write_delta_rho_vesta(total: str, individuals: Sequence[str], output: str = 'delta_rho.cube', format: str = 'cube', compact: bool = False, inorm: bool = False, gridsize: Optional[Sequence] = None)

    电荷密度差分可视化

    DeviceStudio暂不支持大文件,临时写成可以用VESTA打开的格式

    参数
    • total (str) – 体系总电荷密度文件路径,可以是h5或json格式

    • individuals (Sequence of str) – 体系各组分电荷密度文件路径,可以是h5或json格式

    • output (str) – 输出文件路径,默认 “delta_rho.cube”

    • format (str) – 输出的数据格式,支持 “cube” 和 “vasp”,默认为 “cube”

    • compact (bool) – 每个格点的数据都换行,通过减少空格数量减小文件体积(不会影响VESTA软件的解析),默认为False

    • inorm (bool) – 是否归一化体积数据,使其总和为1,默认为False

    • gridsize (tuple) – 重新定义的格点数,格式为 (ngx, ngy, ngz),默认为None,即使用原始格点数

    返回

    output – 电荷差分(total-individual1-individual2-…)后的电荷密度文件,

    返回类型

    file

    实际案例

    >>> from dspawpy.io.write import write_delta_rho_vesta
    >>> write_delta_rho_vesta(total='dspawpy_proj/dspawpy_tests/inputs/supplement/AB.h5',
    ...     individuals=['dspawpy_proj/dspawpy_tests/inputs/supplement/A.h5', 'dspawpy_proj/dspawpy_tests/inputs/supplement/B.h5'],
    ...     output='dspawpy_proj/dspawpy_tests/outputs/doctest/delta_rho.cube') 
    ==> ...delta_rho.cube
    
  • average_along_axis 函数负责处理volumetricData面平均数据:

    dspawpy.plot.average_along_axis(datafile: str = 'potential.h5', task: str = 'potential', axis: int = 2, smooth: bool = False, smooth_frac: float = 0.8, raw: bool = False, subtype: Optional[str] = None, verbose: bool = False, **kwargs)

    绘制沿着某个轴向的物理量平均值曲线

    参数
    • datafile (str or list or np.ndarray) – h5或json文件路径或包含任意这些文件的文件夹,默认 ‘potential.h5’

    • task (str) – 任务类型,可以是 ‘rho’, ‘potential’, ‘elf’, ‘pcharge’, ‘rhoBound’

    • axis (int) – 沿着哪个轴向绘制势能曲线, 默认2

    • smooth (bool) – 是否平滑, 默认False

    • smooth_frac (float) – 平滑系数, 默认0.8

    • raw (bool) – 是否返回绘图数据到csv文件

    • subtype (str) – 用于指定task数据子类,默认None,代表绘制 Potential/TotalElectrostaticPotential

    • **kwargs (dict) – 其他参数, 传递给 matplotlib.pyplot.plot

    返回

    axes – 可传递给其他函数进行进一步处理

    返回类型

    matplotlib.axes._subplots.AxesSubplot

    实际案例

    >>> from dspawpy.plot import average_along_axis
    

    读取 potential.h5 文件中的数据,绘图并保存原始绘图数据到csv文件

    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/3.3/rho.h5', task='rho', axis=2, smooth=True, smooth_frac=0.8) 
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/rho_h5.png')
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/3.3/rho.json', task='rho', axis=2, smooth=True, smooth_frac=0.8) 
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/rho_json.png')
    
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.7/potential.h5', task='potential', axis=2, smooth=True, smooth_frac=0.8, raw=True) 
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/potential_h5.png')
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.7/potential.json', task='potential', axis=2, smooth=True, smooth_frac=0.8) 
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/potential_json.png')
    
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.8/elf.h5', task='elf', axis=2, smooth=True, smooth_frac=0.8) 
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/elf_h5.png')
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.8/elf.json', task='elf', axis=2, smooth=True, smooth_frac=0.8) 
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/elf_json.png')
    
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.9/pcharge.h5', task='pcharge', axis=2, smooth=True, smooth_frac=0.8) 
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/pcharge_h5.png')
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.9/pcharge.json', task='pcharge', axis=2, smooth=True, smooth_frac=0.8) 
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/pcharge_json.png')
    
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.28/rhoBound.h5', task='rhoBound', axis=2, smooth=True, smooth_frac=0.8) 
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/rhoBound_h5.png')
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.28/rhoBound.json', task='rhoBound', axis=2, smooth=True, smooth_frac=0.8) 
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/rhoBound_json.png')
    

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

8.4 band能带数据处理

知识点:

  1. 脚本中调用get_band_data()读取数据,在读取数据时设置efermi=XX可将能量零点修改为指定值;设置zero_to_efermi=True, 可将能量零点修改问所读取的文件中的费米能级处

  2. 脚本调用pymatgen的BSPlotter.get_plot()画图,在画图时可设置zero_to_efermi=True,将坐标轴能量零点修改到费米能级处。由于pymatgen在2023.8.17的一处关键更新将绘图函数返回对象从plt改成了axes,导致后续脚本可能出现不兼容。因此用户脚本相关部分已添加一个判断语句加以处理。

  3. 能带两步算需从第一步自洽计算获取准确费米能级(从自洽获得的system.json),若获取失败,用户可在调用get_band_data读取数据时,利用参数efermi修改能量零点。例如:band_data=get_band_data(‘band.h5’,efermi=-1.5)

  4. 脚本中画图调用pymatgen中的BSPlotter.get_plot, 当判断体系为非金属时,设置zero_to_efermi会认为VBM为费米能级能量而非文件读取时的费米能级。故当体系为非金属时,在数据读取时设置zero_to_efermi=True和在画图时设置zero_to_efermi=True得到的图会有区别

执行本节所列的python脚本,程序会判断是否为金属体系。若为非金属体系,将要求选择是否平移费米能级到能量零点,请按提示操作。

普通能带处理

参考 4bandplot.py

 1import os
 2
 3import matplotlib.pyplot as plt
 4from dspawpy.io.read import get_band_data
 5from pymatgen.electronic_structure.plotter import BSPlotter
 6
 7datafile = "dspawpy_proj/dspawpy_tests/inputs/supplement/pband.h5"  # 指定数据文件路径
 8band_data = get_band_data(
 9    band_dir=datafile,
10    syst_dir=None,  # system.json文件路径,仅当band_dir为json文件时需要
11    efermi=None,  # 用于手动修正费米能级
12    zero_to_efermi=True,  # 非金属体系应将零点能移动到费米能级
13)
14
15bsp = BSPlotter(band_data)
16axes_or_plt = bsp.get_plot(
17    zero_to_efermi=False,  # 上面读取数据时已经平移,此处应关闭
18    ylim=[-10, 10],  # 能带图的纵坐标范围
19    smooth=False,  # 是否对能带图进行平滑处理
20    vbm_cbm_marker=False,  # 是否在能带图中标记导带和价带
21    smooth_tol=0,  # 平滑处理的阈值
22    smooth_k=3,  # 平滑处理的阶数
23    smooth_np=100,  # 平滑处理的点数
24)
25
26if isinstance(axes_or_plt, plt.Axes):
27    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
28else:
29    fig = axes_or_plt.gcf()  # older version pymatgen
30
31# 添加能量零点参考线
32for ax in fig.axes:
33    ax.axhline(0, lw=2, ls="-.", color="gray")
34
35figname = "dspawpy_proj/dspawpy_tests/outputs/us/4bandplot.png"  # 输出的能带图文件名
36os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
37fig.savefig(figname, dpi=300)

知识点:

能带两步算需从自洽计算获取准确的费米能级(从system.json获取),若获取失败,用户可在 get_band_data 函数中指定 efermi 参数修改

执行代码可以得到类似以下能带图:

_images/4bandplot.png

二硫化钼能带示意图

将能带投影到每一种元素分别作图,数据点大小表示该元素对该轨道的贡献

参考 4bandplot_elt.py

 1import os
 2
 3import matplotlib.pyplot as plt
 4import numpy as np
 5from dspawpy.io.read import get_band_data
 6from pymatgen.electronic_structure.plotter import BSPlotterProjected
 7
 8datafile = "dspawpy_proj/dspawpy_tests/inputs/supplement/pband.h5"  # 指定数据文件路径
 9band_data = get_band_data(
10    band_dir=datafile,
11    syst_dir=None,  # system.json文件路径,仅当band_dir为json文件时需要
12    efermi=None,  # 用于手动修正费米能级
13    zero_to_efermi=True,  # 非金属体系应将零点能移动到费米能级
14)
15
16bsp = BSPlotterProjected(bs=band_data)  # 初始化BSPlotterProjected类
17axes_or_plt = bsp.get_elt_projected_plots(
18    zero_to_efermi=False,  # 上面读取数据时已经平移,此处应关闭
19    ylim=[-8, 5],  # 设置能量范围
20    vbm_cbm_marker=False,  # 是否标记导带底和价带顶
21)
22
23if isinstance(axes_or_plt, plt.Axes):
24    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
25elif np.iterable(axes_or_plt):
26    fig = np.asarray(axes_or_plt).flatten()[0].get_figure()
27else:
28    fig = axes_or_plt.gcf()  # older version pymatgen
29
30# 添加能量零点参考线
31for ax in fig.axes:
32    ax.axhline(0, lw=2, ls="-.", color="gray")
33
34figname = (
35    "dspawpy_proj/dspawpy_tests/outputs/us/4bandplot_elt.png"  # 输出的能带图文件名
36)
37os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
38fig.savefig(figname, dpi=300)

知识点:

  1. 用户如果需要绘制能带投影的数据,此时需要使用 BSPlotterProjected模块

  2. 使用 BSPlotterProjected模块中 get_elt_projected_plots 函数能够绘制每种元素对轨道贡献的能带图

执行代码可以得到类似以下能带图:

_images/4bandplot_elt.png

二硫化钼元素投影能带示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

能带投影到不同元素的不同轨道

参考 4bandplot_elt_orbit.py

 1import os
 2
 3import matplotlib.pyplot as plt
 4import numpy as np
 5from dspawpy.io.read import get_band_data
 6from pymatgen.electronic_structure.plotter import BSPlotterProjected
 7
 8datafile = "dspawpy_proj/dspawpy_tests/inputs/supplement/pband.h5"  # 指定数据文件路径
 9band_data = get_band_data(
10    band_dir=datafile,
11    syst_dir=None,  # system.json文件路径,仅当band_dir为json文件时需要
12    efermi=None,  # 用于手动修正费米能级
13    zero_to_efermi=True,  # 非金属体系应将零点能移动到费米能级
14)
15
16bsp = BSPlotterProjected(bs=band_data)  # 初始化BSPlotterProjected类
17# ! 选定元素与轨道,创建字典
18dict_elem_orbit = {"Mo": ["d"], "S": ["s"]}
19
20axes_or_plt = bsp.get_projected_plots_dots(
21    dictio=dict_elem_orbit,
22    zero_to_efermi=False,  # 上面读取数据时已经平移,此处应关闭
23    ylim=[-8, 5],  # 设置能量范围
24    vbm_cbm_marker=False,  # 是否标记导带底和价带顶
25)
26
27if isinstance(axes_or_plt, plt.Axes):
28    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
29elif np.iterable(axes_or_plt):
30    fig = np.asarray(axes_or_plt).flatten()[0].get_figure()
31else:
32    fig = axes_or_plt.gcf()  # older version pymatgen
33
34# 添加能量零点参考线
35for ax in fig.axes:
36    ax.axhline(0, lw=2, ls="-.", color="gray")
37
38figname = "dspawpy_proj/dspawpy_tests/outputs/us/4bandplot_elt_orbit.png"  # 输出的能带图文件名
39os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
40fig.savefig(figname, dpi=300)

知识点:

  1. 使用 BSPlotterProjected模块中 get_projected_plots_dots可以让用户来自定义需要绘制的某种元素某种轨道(L)的能带图

  2. 例如 get_projected_plots_dots ({‘Mo’:[‘d’],’S’:[‘s’]})就是绘制Mo的d轨道和S的s轨道

执行代码可以得到类似以下能带图:

_images/4bandplot_elt_orbit.png

二硫化钼元素轨道投影能带示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

将能带投影到不同原子的不同轨道

参考 4bandplot_patom_porbit.py

 1import os
 2
 3import matplotlib.pyplot as plt
 4import numpy as np
 5from dspawpy.io.read import get_band_data
 6from pymatgen.electronic_structure.plotter import BSPlotterProjected
 7
 8datafile = "dspawpy_proj/dspawpy_tests/inputs/supplement/pband.h5"  # 指定数据文件路径
 9band_data = get_band_data(
10    band_dir=datafile,
11    syst_dir=None,  # system.json文件路径,仅当band_dir为json文件时需要
12    efermi=None,  # 用于手动修正费米能级
13    zero_to_efermi=True,  # 非金属体系应将零点能移动到费米能级
14)
15
16bsp = BSPlotterProjected(bs=band_data)
17# ! 指定元素和轨道和原子序号
18dict_elem_orbit = {"Mo": ["px", "py", "pz"]}
19dict_elem_index = {"Mo": [1]}
20
21axes_or_plt = bsp.get_projected_plots_dots_patom_pmorb(
22    dictio=dict_elem_orbit,  # 指定元素-轨道字典
23    dictpa=dict_elem_index,  # 指定元素-原子序号字典
24    sum_atoms=None,  # 是否对原子求和
25    sum_morbs=None,  # 是否对轨道求和
26    zero_to_efermi=False,  # 上面读取数据时已经平移,此处应关闭
27    ylim=None,  # 设置能量范围
28    vbm_cbm_marker=False,  # 是否标记导带底和价带顶
29    selected_branches=None,  # 指定绘制的能带分支
30    w_h_size=(12, 8),  # 设置图片宽高
31    num_column=None,  # 设置每行显示的图片数量
32)
33
34if isinstance(axes_or_plt, plt.Axes):
35    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
36elif np.iterable(axes_or_plt):
37    fig = np.asarray(axes_or_plt).flatten()[0].get_figure()
38else:
39    fig = axes_or_plt.gcf()  # older version pymatgen
40
41# 添加能量零点参考线
42for ax in fig.axes:
43    ax.axhline(0, lw=2, ls="-.", color="gray")
44
45figname = (
46    "dspawpy_proj/dspawpy_tests/outputs/us/4band_patom_porbit.png"  # 输出的能带图文件名
47)
48os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
49fig.savefig(figname, dpi=300)

知识点:

  1. 使用 BSPlotterProjected模块中 get_projected_plots_dots_patom_pmorb 的自由度更高,可以让用户来自定义需要绘制的某些原子某些轨道的能带图

  2. dictpa指定原子,dictio 指定该原子的轨道

  3. 如果要将一些原子或一些轨道的投影分量叠加起来,请根据 get_projected_plots_dots_patom_pmorb 函数文档指定 sum_atoms 或 sum_morbs 参数

警告

  1. 如果只选择单个轨道,且轨道名称不止一个字母(例如px、dxy、dxz),get_projected_plots_dots_patom_pmorb 函数将报错,详情见 此处

执行代码可以得到类似以下能带图:

_images/4band_patom_porbit.png

二硫化钼原子投影能带示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

能带反折叠处理

参考 4bandunfolding.py

 1import os
 2
 3from dspawpy.plot import plot_bandunfolding
 4
 5plt = plot_bandunfolding(
 6    datafile="dspawpy_proj/dspawpy_tests/inputs/2.22.1/band.h5",  # 读取数据
 7    ef=None,  # 费米能级,从文件中读取
 8    de=0.05,  # 能带宽度,默认0.05
 9    dele=0.06,  # 能带间隔,默认0.06
10)
11
12plt.ylim(-15, 10)
13figname = (
14    "dspawpy_proj/dspawpy_tests/outputs/us/4bandunfolding.png"  # 输出的能带图文件名
15)
16os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
17plt.savefig(figname, dpi=300)
18# plt.show()

执行代码可以得到类似以下能带图:

_images/4bandunfolding.png

Cu3Au能带反折叠示意图

警告

此功能暂不支持将非金属材料的费米能级设为能量零点(默认价带顶为能量零点)。

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

band-compare能带对比图处理

将普通能带和wannier能带绘制在同一张图上

参考 4bandcompare.py

 1import os
 2
 3from dspawpy.io.read import get_band_data
 4from pymatgen.electronic_structure.plotter import BSPlotter
 5
 6band_data = get_band_data(
 7    band_dir="dspawpy_proj/dspawpy_tests/inputs/2.30/wannier.h5",  # 瓦尼尔能带文件路径
 8    syst_dir=None,  # system.json文件路径,仅当band_dir为json文件时需要
 9    efermi=None,  # 用于手动修正费米能级
10    zero_to_efermi=False,  # 是否将零点能移动到费米能级
11)
12bsp = BSPlotter(bs=band_data)
13band_data = get_band_data(
14    band_dir="dspawpy_proj/dspawpy_tests/inputs/2.3/band.h5",  # 读取DFT能带
15    syst_dir=None,  # system.json文件路径,仅当band_dir为json文件时需要
16    efermi=None,  # 用于手动修正费米能级
17    zero_to_efermi=False,  # 是否将零点能移动到费米能级
18)
19
20bsp2 = BSPlotter(bs=band_data)
21bsp.add_bs(bsp2._bs)
22axes_or_plt = bsp.get_plot(
23    zero_to_efermi=True,  # 将零点能移动到费米能级
24    ylim=[-10, 10],  # 能带图的纵坐标范围
25    smooth=False,  # 是否对能带图进行平滑处理
26    vbm_cbm_marker=False,  # 是否在能带图中标记导带和价带
27    smooth_tol=0,  # 平滑处理的阈值
28    smooth_k=3,  # 平滑处理的阶数
29    smooth_np=100,  # 平滑处理的点数
30    bs_labels=["wannier interpolated", "DFT"],  # 能带图中的标签
31)
32
33import matplotlib.pyplot as plt  # noqa: E402
34
35if isinstance(axes_or_plt, plt.Axes):
36    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
37else:
38    fig = axes_or_plt.gcf()  # older version pymatgen
39
40# 添加能量零点参考线
41for ax in fig.axes:
42    ax.axhline(0, lw=2, ls="-.", color="gray")
43
44figname = "dspawpy_proj/dspawpy_tests/outputs/us/4wanierBand.png"  # 输出的能带图文件名
45os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
46fig.savefig(figname, dpi=300)

执行代码可得到类似如下能带对比曲线:

_images/wannier_band.png

晶体硅瓦尼尔能带与DFT能带示意图

API: get_band_data()
  • get_band_data 函数负责读取能带数据如下:

    dspawpy.io.read.get_band_data(band_dir: str, syst_dir: Optional[str] = None, efermi: Optional[float] = None, zero_to_efermi: bool = False, verbose: bool = False) BandStructureSymmLine

    读取h5或json文件中的能带数据,构建BandStructureSymmLine对象

    参数
    • band_dir (str) –

      • 能带文件路径,band.h5 / band.json 或包含band.h5 / band.json的文件夹

      • 注意,wannier.h5 也可以使用此函数读取,但band_dir不支持文件夹类型

    • syst_dir (str) – system.json 路径,仅为辅助处理 Wannier 数据而准备(从中读取结构和费米能级)

    • efermi (float, optional) – 费米能级,如果h5文件中的费米能级不正确,可以通过此参数指定费米能级

    • zero_to_efermi (bool, optional) – 是否将费米能级移动到0

    返回类型

    BandStructureSymmLine

    实际案例

    >>> from dspawpy.io.read import get_band_data
    >>> band = get_band_data(band_dir='dspawpy_proj/dspawpy_tests/inputs/2.3/band.h5')
    >>> band = get_band_data(band_dir='dspawpy_proj/dspawpy_tests/inputs/2.4/band.h5')
    >>> band = get_band_data(band_dir='dspawpy_proj/dspawpy_tests/inputs/2.4/band.json')
    

    如果希望通过指定wannier.json来处理瓦尼尔能带,需要额外指定syst_dir参数

    >>> band = get_band_data(band_dir='dspawpy_proj/dspawpy_tests/inputs/2.30/wannier.h5')
    >>> band = get_band_data(band_dir='dspawpy_proj/dspawpy_tests/inputs/2.30/wannier.json', syst_dir='dspawpy_proj/dspawpy_tests/inputs/2.30/system.json')
    

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

8.5 dos态密度数据处理

总的态密度

参考 5dosplot_total.py

 1import os
 2
 3from dspawpy.io.read import get_dos_data
 4from dspawpy.plot import plot_dos
 5from pymatgen.electronic_structure.plotter import DosPlotter
 6
 7dos_data = get_dos_data(
 8    dos_dir="dspawpy_proj/dspawpy_tests/inputs/3.2.4/dos.h5",  # 读取投影态密度数据
 9    return_dos=False,  # 如果为False,则统一返回CompleteDos对象(无论计算时是否开了投影)
10)
11dos_plotter = DosPlotter(
12    zero_at_efermi=True,  # 是否将费米能级作为零点
13    stack=False,  # True表示绘制面积图
14    sigma=None,  # 高斯展宽,None表示不进行平滑处理
15)
16dos_plotter.add_dos(label="total dos", dos=dos_data)  # 设置态密度图例  # 传入态密度数据
17
18ax = plot_dos(
19    dosplotter=dos_plotter,
20    xlim=[-10, 5],  # 设置能量范围
21    ylim=[-15, 15],  # 设置态密度范围
22)
23ax.axhline(0, lw=2, ls="-.", color="gray")
24
25filename = (
26    "dspawpy_proj/dspawpy_tests/outputs/us/5dos_total.png"  # 输出的态密度图文件名
27)
28os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
29
30fig = ax.get_figure()
31fig.savefig(filename, dpi=300)

知识点:

  1. 使用 get_dos_data 函数可以将DS-PAW计算得到的 dos.h5 文件转化为 pymatgen 支持的格式

  2. 使用 DosPlotter模块获取到DS-PAW计算的 dos.h5 的数据

  3. DosPlotter函数可以传递参数:stack参数表示画态密度是否加阴影, zero_at_efermi 表示是否在态密度图中进行将费米能量置零,这里设置 stack=False , zero_at_efermi=False

  4. 使用 DosPlotter 模块中 add_dos 获取态密度的数据

  5. DosPlotter模块中 get_plot函数 绘制态密度图

执行代码可以得到类似以下态密度图:

_images/5dos_total.png

NiO态密度示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

将态密度投影到不同的轨道上

参考 5dosplot_spd.py

 1import os
 2
 3from dspawpy.io.read import get_dos_data
 4from dspawpy.plot import plot_dos
 5from pymatgen.electronic_structure.plotter import DosPlotter
 6
 7dos_data = get_dos_data(
 8    dos_dir="dspawpy_proj/dspawpy_tests/inputs/3.2.4/dos.h5",  # 读取投影态密度数据
 9    return_dos=False,  # 如果为False,则统一返回CompleteDos对象(无论计算时是否开了投影)
10)
11dos_plotter = DosPlotter(
12    zero_at_efermi=True,  # 是否将费米能级作为零点
13    stack=False,  # True表示绘制面积图
14    sigma=None,  # 高斯展宽,None表示不进行平滑处理
15)
16dos_plotter.add_dos_dict(
17    dos_dict=dos_data.get_spd_dos(),
18    key_sort_func=None,  # 轨道投影  # 指定排序函数
19)
20ax = plot_dos(
21    dosplotter=dos_plotter,
22    xlim=[-10, 5],  # 设置能量范围
23    ylim=None,  # 设置态密度范围
24)
25
26ax.axhline(0, lw=2, ls="-.", color="gray")
27
28filename = "dspawpy_proj/dspawpy_tests/outputs/us/5dos_spd.png"  # 输出的态密度图文件名
29os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
30
31fig = ax.get_figure()
32fig.savefig(filename, dpi=300)

知识点:

使用 DosPlotter模块中 add_dos_dict 函数 获取投影态密度的数据,之后使用 get_spd_dos 将投影信息按照 spd 轨道投影输出

执行代码可以得到类似以下态密度图:

_images/5dos_spd.png

NiO轨道投影态密度示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

将态密度投影到不同的元素上

参考 5dosplot_elt.py

 1import os
 2
 3from dspawpy.io.read import get_dos_data
 4from dspawpy.plot import plot_dos
 5from pymatgen.electronic_structure.plotter import DosPlotter
 6
 7dos_data = get_dos_data(
 8    dos_dir="dspawpy_proj/dspawpy_tests/inputs/3.2.4/dos.h5",  # 读取投影态密度数据
 9    return_dos=False,  # 如果为False,则统一返回CompleteDos对象(无论计算时是否开了投影)
10)
11dos_plotter = DosPlotter(
12    zero_at_efermi=True,  # 是否将费米能级作为零点
13    stack=False,  # True表示绘制面积图
14    sigma=None,  # 高斯展宽,None表示不进行平滑处理
15)
16dos_plotter.add_dos_dict(
17    dos_dict=dos_data.get_element_dos(),
18    key_sort_func=None,  # 元素投影态密度  # 指定排序函数
19)
20
21ax = plot_dos(
22    dosplotter=dos_plotter,
23    xlim=[-10, 5],  # 设置能量范围
24    ylim=None,  # 设置态密度范围
25)
26ax.axhline(0, lw=2, ls="-.", color="gray")
27
28filename = "dspawpy_proj/dspawpy_tests/outputs/us/5dos_elt.png"  # 输出的态密度图文件名
29os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
30
31fig = ax.get_figure()
32fig.savefig(filename, dpi=300)

知识点:

使用 DosPlotter模块中 add_dos_dict 函数 获取投影态密度的数据,之后使用 get_element_dos 将投影信息按照不同元素投影输出

执行代码可以得到类似以下态密度图:

_images/5dos_elt.png

NiO元素投影态密度示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

将态密度投影到不同原子的不同轨道上

参考 5dosplot_atom_orbit.py

 1import os
 2
 3from dspawpy.io.read import get_dos_data
 4from dspawpy.plot import plot_dos
 5from pymatgen.electronic_structure.core import Orbital
 6from pymatgen.electronic_structure.plotter import DosPlotter
 7
 8dos_data = get_dos_data(
 9    dos_dir="dspawpy_proj/dspawpy_tests/inputs/3.2.4/dos.h5",  # 读取投影态密度数据
10    return_dos=False,  # 如果为False,则统一返回CompleteDos对象(无论计算时是否开了投影)
11)
12dos_plotter = DosPlotter(
13    zero_at_efermi=True,  # 是否将费米能级作为零点
14    stack=False,  # True表示绘制面积图
15    sigma=None,  # 高斯展宽,None表示不进行平滑处理
16)
17
18# ! 指定原子序号和轨道
19dict_index_orbit = {0: ["dxy"], 2: ["s"]}
20
21print("正在绘图...")
22for index in dict_index_orbit:
23    _os = dict_index_orbit[index]
24    _e = str(dos_data.structure.sites[index].species)
25    for _orb in _os:
26        dos_plotter.add_dos(
27            f"{_e}(atom-{index}) {_orb}",  # label
28            dos_data.get_site_orbital_dos(
29                dos_data.structure[index], getattr(Orbital, _orb),
30            ),
31        )
32
33ax = plot_dos(
34    dosplotter=dos_plotter,
35    xlim=[-10, 5],  # 设置能量范围
36    ylim=None,  # 设置态密度范围
37)
38ax.axhline(0, lw=2, ls="-.", color="gray")
39
40figname = (
41    "dspawpy_proj/dspawpy_tests/outputs/us/5dos_atom_orbit.png"  # 输出的态密度图文件名
42)
43os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
44
45fig = ax.get_figure()
46fig.savefig(figname, dpi=300)

知识点:

  1. 使用 get_site_orbital_dos函数提取dos数据中特定原子特定轨道的贡献,dos_data.structure[0],Orbital(4) 表示获取第1个原子的dxy轨道的态密度,get_site_orbital_dos函数中序号从0开始

  2. 运行此脚本,根据提示选择元素和轨道,可以得到相应的态密度图

执行代码可以得到类似以下态密度图:

_images/5dos_atom_orbit.png

NiO原子轨道态密度示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

将态密度投影到不同原子的分裂d轨道(t2g, eg)上

参考 5dosplot_t2g_eg.py

 1import os
 2
 3from dspawpy.io.read import get_dos_data
 4from dspawpy.plot import plot_dos
 5from pymatgen.electronic_structure.plotter import DosPlotter
 6
 7dos_data = get_dos_data(
 8    dos_dir="dspawpy_proj/dspawpy_tests/inputs/3.2.4/dos.h5",  # 读取投影态密度数据
 9    return_dos=False,  # 如果为False,则统一返回CompleteDos对象(无论计算时是否开了投影)
10)
11dos_plotter = DosPlotter(
12    zero_at_efermi=True,  # 是否将费米能级作为零点
13    stack=False,  # True表示绘制面积图
14    sigma=None,  # 高斯展宽,None表示不进行平滑处理
15)
16# print(dos_data.structure)
17
18# ! 指定原子序号,从0开始
19ais = [1]
20
21print("正在绘图...")
22atom_indices = [int(ai) for ai in ais]
23for atom_index in atom_indices:
24    dos_plotter.add_dos_dict(
25        dos_data.get_site_t2g_eg_resolved_dos(dos_data.structure[atom_index]),
26    )
27
28ax = plot_dos(
29    dosplotter=dos_plotter,
30    xlim=[-10, 5],  # 设置能量范围
31    ylim=None,  # 设置态密度范围
32)
33ax.axhline(0, lw=2, ls="-.", color="gray")
34
35filename = (
36    "dspawpy_proj/dspawpy_tests/outputs/us/5dos_t2g_eg.png"  # 输出的态密度图文件名
37)
38os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
39
40fig = ax.get_figure()
41fig.savefig(filename, dpi=300)

知识点:

  1. 使用 get_site_t2g_eg_resolved_dos函数 提取dos数据中特定原子的 t2g和 eg轨道的贡献,这是获取第2个原子的t2g和eg轨道的贡献

  2. 运行此脚本,根据提示选择原子序号,可以得到相应的态密度图

执行代码可以得到类似以下态密度图:

_images/5dos_t2g_eg.png

NiO分裂d轨道原子投影态密度示意图

知识点:

如果元素不含d轨道,会画成空白图片

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

d-带中心分析

以 Pb-slab 体系为例,对 Pt 原子进行 d-band 中心分析:

参考 5center_dband.py

 1from dspawpy.io.read import get_dos_data
 2from dspawpy.io.utils import d_band
 3
 4dos_data = get_dos_data(
 5    dos_dir="dspawpy_proj/dspawpy_tests/inputs/supplement/dos.h5",  # 读取投影态密度数据
 6    return_dos=False,  # 如果为False,则统一返回CompleteDos对象(无论计算时是否开了投影)
 7)
 8for spin in dos_data.densities:
 9    print("spin=", spin)
10    c = d_band(spin, dos_data)
11    print(c)

执行代码可以得到类似以下结果:

spin=1
-1.785319344084034

备注

目前仅支持全部原子平均的 d 轨道中心,不支持元素、原子投影或其他轨道,也不支持选择自旋方向或能量范围。

get_dos_data 函数负责处理态密度数据:

API: get_dos_data()
dspawpy.io.read.get_dos_data(dos_dir: str, return_dos: bool = False, verbose: bool = False)

读取h5或json文件中的态密度数据,构建CompleteDos或DOS对象

参数
  • dos_dir (str) – 态密度文件路径,dos.h5 / dos.json 或包含dos.h5 / dos.json的文件夹

  • return_dos (bool, optional) – 是否返回DOS对象,如果为False,则统一返回CompleteDos对象(无论计算时是否开了投影)

返回类型

CompleteDos or Dos

实际案例

>>> from dspawpy.io.read import get_dos_data
>>> dos = get_dos_data(dos_dir='dspawpy_proj/dspawpy_tests/inputs/2.5/dos.h5')
>>> dos = get_dos_data(dos_dir='dspawpy_proj/dspawpy_tests/inputs/2.5/dos.h5', return_dos=True)

8.6 bandDos能带和态密度共同显示

以应用教程中Si体系为例:

将能带和态密度显示在一张图上

参考 6bandDosplot.py

 1import os
 2
 3import numpy as np
 4from dspawpy.io.read import get_band_data, get_dos_data
 5from matplotlib.axes import Axes
 6from pymatgen.electronic_structure.plotter import BSDOSPlotter
 7
 8bandfile = "dspawpy_proj/dspawpy_tests/inputs/2.3/band.h5"  # 普通能带数据
 9band_data = get_band_data(
10    band_dir=bandfile,
11    syst_dir=None,  # system.json文件路径,仅当band_dir为json文件时需要
12    efermi=None,  # 用于手动修正费米能级
13    zero_to_efermi=True,  # 非金属体系应将零点能移动到费米能级
14)
15dosfile = "dspawpy_proj/dspawpy_tests/inputs/2.5/dos.h5"  # 态密度数据
16dos_data = get_dos_data(
17    dos_dir=dosfile,
18    return_dos=False,  # 如果为False,则统一返回CompleteDos对象(无论计算时是否开了投影)
19)
20bdp = BSDOSPlotter(
21    bs_projection=None,  # 能带的投影方式,None表示不投影
22    dos_projection=None,  # 态密度的投影方式,None表示不投影
23    vb_energy_range=4,  # 价带能量范围
24    cb_energy_range=4,  # 导带能量范围
25    fixed_cb_energy=False,  # 是否固定导带能量范围
26    egrid_interval=1,  # 能量格点间隔
27    font="DejaVu Sans",  # 默认Times New Roman,修改成 DejaVu Sans,可避免在linux上因字体未安装而出现的警告
28    axis_fontsize=20,  # 坐标轴字体大小
29    tick_fontsize=15,  # 刻度字体大小
30    legend_fontsize=14,  # 图例字体大小
31    bs_legend="best",  # 能带图图例位置
32    dos_legend="best",  # 态密度图图例位置
33    rgb_legend=True,  # 是否使用彩色图例
34    fig_size=(11, 8.5),  # 图片大小
35)
36axes_or_plt = bdp.get_plot(bs=band_data, dos=dos_data)  # 传入能带数据  # 传入态密度数据
37
38if isinstance(axes_or_plt, Axes):
39    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
40elif np.iterable(axes_or_plt):
41    fig = np.asarray(axes_or_plt).flatten()[0].get_figure()
42else:
43    fig = axes_or_plt.gcf()  # older version pymatgen
44
45filename = (
46    "dspawpy_proj/dspawpy_tests/outputs/us/6bandDos.png"  # 输出的能带-态密度图文件名
47)
48os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
49fig.savefig(filename, dpi=300)

执行代码可以得到类似以下能带态密度图:

_images/6bandDos.png

单晶硅能带-态密度示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

将能带和投影态密度显示在一张图上

参考 6bandPdosplot.py

 1import os
 2
 3import numpy as np
 4from dspawpy.io.read import get_band_data, get_dos_data
 5from matplotlib.axes import Axes
 6from pymatgen.electronic_structure.plotter import BSDOSPlotter
 7
 8bandfile = "dspawpy_proj/dspawpy_tests/inputs/2.4/band.h5"  # 普通能带数据
 9band_data = get_band_data(
10    band_dir=bandfile,
11    syst_dir=None,  # system.json文件路径,仅当band_dir为json文件时需要
12    efermi=None,  # 用于手动修正费米能级
13    zero_to_efermi=True,  # 非金属体系应将零点能移动到费米能级
14)
15dosfile = "dspawpy_proj/dspawpy_tests/inputs/2.6/dos.h5"  # 投影态密度数据
16dos_data = get_dos_data(
17    dos_dir=dosfile,
18    return_dos=False,  # 如果为False,则统一返回CompleteDos对象(无论计算时是否开了投影)
19)
20bdp = BSDOSPlotter(
21    bs_projection="elements",  # 能带的投影方式,None表示不投影
22    dos_projection="elements",  # 投影态密度到元素上
23    vb_energy_range=4,  # 价带能量范围
24    cb_energy_range=4,  # 导带能量范围
25    fixed_cb_energy=False,  # 是否固定导带能量范围
26    egrid_interval=1,  # 能量格点间隔
27    font="DejaVu Sans",  # 默认Times New Roman,修改成 DejaVu Sans,可避免在linux上因字体未安装而出现的警告
28    axis_fontsize=20,  # 坐标轴字体大小
29    tick_fontsize=15,  # 刻度字体大小
30    legend_fontsize=14,  # 图例字体大小
31    bs_legend="best",  # 能带图图例位置
32    dos_legend="best",  # 投影态密度图图例位置
33    rgb_legend=True,  # 是否使用彩色图例
34    fig_size=(11, 8.5),  # 图片大小
35)
36axes_or_plt = bdp.get_plot(
37    bs=band_data, dos=dos_data,
38)  # 传入能带数据  # 传入投影态密度数据
39
40if isinstance(axes_or_plt, Axes):
41    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
42elif np.iterable(axes_or_plt):
43    fig = np.asarray(axes_or_plt).flatten()[0].get_figure()
44else:
45    fig = axes_or_plt.gcf()  # older version pymatgen
46
47filename = "dspawpy_proj/dspawpy_tests/outputs/us/6bandPdos.png"  # 输出的能带-投影态密度图文件名
48os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
49fig.savefig(filename, dpi=300)

执行代码可以得到类似以下能带态密度图:

_images/6bandPdos.png

单晶硅能带-投影态密度示意图

警告

  1. 给定投影能带数据,默认将沿着元素投影;给定普通能带数据(或体系所含元素种类超过4种),则不投影,并输出警告

  2. 给定投影态密度数据,默认也将沿着元素投影,可以换成沿着轨道投影,或者不投影;给定普通态密度数据且未关闭态密度投影选项 BSDOSPlotter(dos_projection=None),pymatgen绘图程序将报错,这就是上面特意准备了一个 6bandDosplot.py 文件的原因。

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

8.7 optical光学性质数据处理

以快速入门Si体系光学性质计算得到的 scf.h5 为例(注:输出文件名与task一致,task = scf,io.optical = true可计算光学性质):

反射率数据处理,参考 7optical.py

 1from dspawpy.plot import plot_optical
 2
 3plot_optical(
 4    datafile="dspawpy_proj/dspawpy_tests/inputs/2.12/scf.h5",
 5    keys=["ExtinctionCoefficient", "Reflectance"],
 6    axes=["X"],  # ["X", "Y", "Z", "XY", "YZ", "ZX"]
 7    prefix="",  # 保存到哪个文件夹中,若为空,表示当前文件夹
 8    save=True,  # 是否工具性质名称保存图片,若为 False,请参考下方脚本自行保存
 9)
10# 以上函数将绘制并分别保存 ExtinctionCoefficient 和 Reflectance 的图像
11# 要将多个性质绘制在同一张图中,请取消注释以下代码,并将上方 save 参数设置为 False
12# import os
13# import matplotlib.pyplot as plt
14#
15# plt.tick_params(labelsize=16)
16# plt.tight_layout()
17# filename = (
18#     "dspawpy_proj/dspawpy_tests/outputs/us/7optical.png"  # 输出的光学性质图文件名
19# )
20# os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
21# plt.savefig(filename, dpi=300)

知识点:

Reflectance为光学性质中的一种,用户可以根据自己的需求将该关键词修改为“AbsorptionCoefficient”或”ExtinctionCoefficient”或”RefractiveIndex”,分别对应吸收系数、消光系数和折射率

执行代码可以得到类似以下反射率随能量变化的曲线:

_images/7optical.png

单晶硅Reflectance随光子能量变化趋势示意图

API: plot_optical()
dspawpy.plot.plot_optical(datafile: str = 'optical.h5', keys: List[str] = ['AbsorptionCoefficient', 'ExtinctionCoefficient', 'RefractiveIndex', 'Reflectance'], axes: List[str] = ['X', 'Y', 'Z', 'XY', 'YZ', 'ZX'], raw: bool = False, prefix: str = '', save: bool = True, verbose: bool = False)

光学性质计算任务完成后,读取数据并绘制预览图

optical.h5/optical.json -> optical.png

参数
  • datafile (str) – h5或json文件路径或包含任意这些文件的文件夹,默认 ‘optical.h5’

  • keys (List[str]) – 可选 “AbsorptionCoefficient”, “ExtinctionCoefficient”, “RefractiveIndex”, “Reflectance” 中的任意一个,默认 “AbsorptionCoefficient”

  • axes (List[str]) – 序号,默认”X”, “Y”, “Z”, “XY”, “YZ”, “ZX”

  • raw (bool) – 是否保存绘图数据到csv

  • prefix (str) – 保存图片的文件夹路径,若留空则保存在当前目录

  • save (bool) – 是否保存图片,默认True

实际案例

绘图并保存绘图数据到rawoptical.csv

>>> from dspawpy.plot import plot_optical
>>> plot_optical("dspawpy_proj/dspawpy_tests/inputs/2.12/scf.h5", "AbsorptionCoefficient", ['X', 'Y'], prefix='dspawpy_proj/dspawpy_tests/outputs/doctest')
>>> plot_optical("dspawpy_proj/dspawpy_tests/inputs/2.12/optical.json", ["AbsorptionCoefficient"], ['X', 'Y'], prefix='dspawpy_proj/dspawpy_tests/outputs/doctest', raw=True)

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

8.8 neb过渡态计算数据处理

以快速入门 H 在 Pt(100) 表面扩散为例进行介绍:

输入文件之生成中间构型

  • 参考 8neb_interpolate_structures.py

     1from dspawpy.diffusion.neb import NEB, write_neb_structures
     2from dspawpy.diffusion.nebtools import write_json_chain
     3from dspawpy.io.structure import read
     4
     5# 读取初态构型
     6init_struct = read("dspawpy_proj/dspawpy_tests/inputs/2.15/00/structure00.as")[0]
     7# 读取末态构型
     8final_struct = read("dspawpy_proj/dspawpy_tests/inputs/2.15/04/structure04.as")[0]
     9
    10neb = NEB(
    11    initial_structure=init_struct,  # 初态构型
    12    final_structure=final_struct,  # 末态构型
    13    nimages=8,  # 共8个构型,包括初末态
    14)
    15structures = neb.linear_interpolate()  # 线性插值
    16# structures = neb.idpp_interpolate()   #idpp插值
    17
    18# 保存 as 结构文件到 dest 路径下
    19write_neb_structures(
    20    structures=structures,  # 插入插值后的构型链
    21    coords_are_cartesian=True,  # 是否以笛卡尔坐标保存
    22    fmt="as",  # 保存格式,支持'json', 'as', 'hzw', 'pdb', 'xyz', 'dump' 六种
    23    path="dspawpy_proj/dspawpy_tests/outputs/us/8neb_interpolate_structures",  # 保存路径
    24    prefix="structure",  # 文件名前缀
    25)
    26
    27# 预览初插构型链
    28write_json_chain(
    29    preview=True,  # 是否为预览模式
    30    directory="dspawpy_proj/dspawpy_tests/outputs/us/8neb_interpolate_structures",  # NEB计算目录
    31    step=-1,  # 默认保存最后一个离子步(最新)的构型链
    32    dst="dspawpy_proj/dspawpy_tests/outputs/us/8neb",  # 保存路径
    33)
    34# write_xyz_chain(preview=True, # 是否为预览模式
    35#                  directory="dspawpy_proj/dspawpy_tests/outputs/us/8neb_interpolate_structures", # NEB计算目录
    36#                  step=-1, # 默认保存最后一个离子步(最新)的构型链
    37#                  dst='dspawpy_proj/dspawpy_tests/outputs/us/8neb' # 保存路径
    38# )
    

知识点:

  1. 用户可以根据需要自行修改插点个数,设置为8得到包含8个结构文件的文件夹,其中中间构型为6个

  2. neb.linear_interpolate为线性插值方法,pbc参数为 True 时将锁定寻找最短扩散路径,默认为 False 以增加用户控制的灵活性,这是因为

  3. 举个例子,初态某原子的分数坐标是 0.2,终态变成 0.8。pbc = True 将强制设置扩散路径为 0.2 -> -0.2。pbc = False 则用户可以令程序按照 0.2 -> 0.8 的扩散路径进行插值;如果要用最短路径,手动将 0.8 改为 -0.2 即可,从而确保程序按照使用者的意图完成插值初猜。

绘制能垒图

neb.iniFin = true/false

当设置 neb.iniFin = true/false 时,都可使用读取neb计算的路径进行势垒分析(确保初末态计算文件在neb计算路径下):

  • 参考 8neb_barrier_CubicSpline.py

     1from dspawpy.diffusion.nebtools import plot_barrier
     2
     3directory_of_neb_task = (
     4    "dspawpy_proj/dspawpy_tests/inputs/2.15"  # <-- 请修改成实际NEB路径
     5)
     6
     7# 三次样条插值 (CubicSpline) 绘制能垒图
     8plot_barrier(
     9    directory=directory_of_neb_task,  # neb任务的路径
    10    method="CubicSpline",  # 三次样条插值
    11    figname="dspawpy_proj/dspawpy_tests/outputs/us/8neb_barrier_CubicSpline.png",  # 输出的能垒图文件名
    12    show=False,  # 是否显示能垒图
    13)
    

备注

运行上述脚本后,可得到类似以下三次样条插值的势垒曲线:

_images/neb-barrier_cs.png

对于这个算例,三次样条插值后,曲线会出现不合理的“下坠”区域,这是三次样条插值算法的特性所决定的。

dspawpy 内部调用 scipy 的插值算法 ,上面这个脚本我们以三次样条插值算法为例,它在 scipy 文档中的定义为:

class scipy.interpolate.CubicSpline(x, y, axis=0, bc_type='not-a-knot', extrapolate=None)

关键词参数包括 axis, bc_type, extrapolate,具体含义见 scipy.interpolate.CubicSpline 。我们可以往 plot_barrier 函数中指定相应的关键词参数(axis, bc_type, extrapolate),将其传递给 scipy.interpolate.CubicSpline 这个类处理。

下面我们采用 8neb_barrier.py 脚本,对比三种算法插值绘制出的曲线:

 1import os
 2
 3import matplotlib.pyplot as plt
 4from dspawpy.diffusion.nebtools import plot_barrier
 5
 6# 对比不同插值方法绘制出的能垒曲线的区别,此时show应当设置为False
 7# 1. interp1d
 8plot_barrier(
 9    directory="dspawpy_proj/dspawpy_tests/inputs/2.15",  # neb计算的路径
10    ri=None,  # 初始构型与第二个构型之间的反应坐标,当NEB任务只计算了中间构型时需要
11    rf=None,  # 最后一个构型与倒数第二个构型之间的反应坐标,当NEB任务只计算了中间构型时需要
12    ei=None,  # 初始构型的能量,当NEB任务只计算了中间构型时需要
13    ef=None,  # 最后一个构型的能量,当NEB任务只计算了中间构型时需要
14    method="interp1d",  # 插值方法
15    figname=None,  # 输出的能垒图文件名
16    show=False,  # 是否显示能垒图
17    kind="quadratic",  # 插值方法的参数
18)
19# 2. CubicSpline
20plot_barrier(
21    directory="dspawpy_proj/dspawpy_tests/inputs/2.15",
22    method="CubicSpline",
23    figname=None,
24    show=False,
25)
26# 3. pchip
27plot_barrier(
28    directory="dspawpy_proj/dspawpy_tests/inputs/2.15",
29    method="pchip",
30    figname=None,
31    show=False,
32)
33
34filename = "dspawpy_proj/dspawpy_tests/outputs/us/8neb_barrier_comparison.png"  # 输出的能垒图文件名
35os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
36plt.savefig(filename, dpi=300)
37# plt.show()
_images/neb-barrier.png

知识点:

  1. 选择合适的插值算法对于优化最终曲线的呈现效果至关重要

  2. 多数情况下,选择 pchip 这种单调三次样条插值算法即可达到较好效果,这也是默认调用的插值算法

neb.iniFin = true

当设置 neb.iniFin = true 时,读取neb计算所得的 neb.h5/neb.json 文件可快速进行势垒分析:

  • 参考 8neb_barrier_CubicSpline.py

    1from dspawpy.diffusion.nebtools import plot_barrier
    2
    3# 三次样条插值 (CubicSpline) 绘制能垒图
    4plot_barrier(
    5    datafile="dspawpy_proj/dspawpy_tests/inputs/2.15/neb.h5",  # neb.h5的路径
    6    method="CubicSpline",  # 三次样条插值
    7    figname="dspawpy_proj/dspawpy_tests/outputs/us/8neb_barrier_.png",  # 输出的能垒图文件名
    8    show=False,  # 是否显示能垒图
    9)
    

处理得到的势垒图与之前读取路径效果一致。

备注

  1. neb.h5 和 neb.json文件所存能量为TotalEnergy,如需得精确的势垒值,建议采用读取neb计算路径的方法进行处理(取TotalEnergy0)

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

过渡态计算数据处理

NEB计算完成后,一般要画出能垒图观察,并检查各插值构型最终的受力大小,从而确保受力小于指定的阈值。如果结果异常,还需要检查各插值构型在结构优化过程中的受力与能量变化趋势,判断是否真正“收敛”。上述这些操作至少需要三次循环,为简化操作,我们提供了一个一步到位的总结函数 summary

  • 参考 8neb_check_results.py

     1from dspawpy.diffusion.nebtools import summary
     2
     3# 导入neb计算目录,需提供neb计算完成后的完整文件夹
     4summary(
     5    directory="dspawpy_proj/dspawpy_tests/inputs/2.15",
     6    show_converge=False,  # 是否显示能量和受力收敛过程图
     7    outdir="dspawpy_proj/dspawpy_tests/outputs/us/8neb",  # 能量和受力收敛过程图保存路径
     8    figname="dspawpy_proj/dspawpy_tests/outputs/us/8neb/neb_barrier_summary.png",  # 能垒图保存路径
     9)
    10# 可以进一步设置其他关键字参数,用于绘制能垒图,例如:
    11# summary(directory = 'dspawpy_proj/dspawpy_tests/inputs/2.15', method='CubicSpline') # 改为三次样条插值CubicSpline
    

    知识点:

    1. 此脚本将以表格形式打印各构型的能量和受力、绘制能垒图,并绘制中间构型的能量与受力收敛过程图

    2. neb.iniFin = false ,用户必须将自洽计算的结果文件 scf.h5system.json 文件复制到对应的初末态子文件夹中,否则程序无法读取初末态能量和受力信息,将报错退出

    3. 默认情况下,能垒图存储在neb计算目录外层,各中间构型的能量与受力收敛图存储在各子文件夹

    执行代码可以得到类似如下NEB计算各构型的能量和受力表格:

    Image

    Force (eV/Å)

    Reaction coordinate (Å)

    Energy (eV)

    Delta energy (eV)

    00

    0.1803

    0.0000

    -39637.0984

    0.0000

    01

    0.0263

    0.5428

    -39637.0186

    0.0798

    02

    0.0248

    1.0868

    -39636.8801

    0.2183

    03

    0.2344

    1.5884

    -39636.9984

    0.1000

    04

    0.0141

    2.0892

    -39637.0900

    0.0084

    除了可以获得能垒图外,还可以得到各中间构型的能量和受力收敛曲线(以02构型为例)

    _images/neb-energy.png

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

观察NEB链

此处所说NEB链指的是各插值构型(structure00.as, structure01.as, …)之间的几何关系,而不是单个构型在优化过程中的变化。

  • NEB任务计算量较大,观察NEB链有助于判断NEB计算的收敛速度。另外,通过插值算法生成中间结构后,经常需要预览NEB链。这些需求可以通过 8neb_visualize.py 脚本实现:

 1from dspawpy.diffusion.nebtools import write_json_chain, write_xyz_chain
 2
 3# 将NEB计算路径下的构型链转成json格式文件
 4write_json_chain(
 5    preview=False,  # NEB计算如果已经完成,则可以不是预览模式
 6    directory="dspawpy_proj/dspawpy_tests/inputs/2.15",  # NEB计算目录
 7    step=-1,  # 默认保存最后一个离子步(最新)的构型链
 8    dst="dspawpy_proj/dspawpy_tests/outputs/us/8neb",  # 保存路径
 9    ignorels=False,  # 设为True则忽略 latestStructureXX.as 文件
10)
11
12# 将NEB计算路径下的构型链转成xyz格式文件
13write_xyz_chain(
14    preview=False,  # NEB计算如果已经完成,则可以不是预览模式
15    directory="dspawpy_proj/dspawpy_tests/inputs/2.15",  # NEB计算目录
16    step=-1,  # 默认保存最后一个离子步(最新)的构型链
17    dst="dspawpy_proj/dspawpy_tests/outputs/us/8neb",  # 保存路径
18    ignorels=False,  # 设为True则忽略 latestStructureXX.as 文件
19)

知识点:

  1. 此脚本生成neb_movie*.json文件后,通过 Device Studio –> Simulator –> DS-PAW –> Analysis Plot 打开 json 文件即可观察

  2. directory指定为NEB计算主路径,需提供neb计算完成后的完整文件夹

  3. 该脚本支持处理正在进行中的(即未完成的)neb计算文件,方便用户监测实时轨迹

  4. xyz文件可通过 OVITO 软件打开查看:通过 Device Studio –> Simulator –> OVITO 打开可视化界面,将xyz文件拖入即可

  5. 结构信息读取优先级:latestStructureXX.as > h5 > json;设置ignorels为True后,先尝试读取 h5 中的数据,失败则读取 json 中的数据

计算构型间距

  • 参考这个脚本 8calc_dist.py

     1from dspawpy.diffusion.nebtools import get_distance
     2from dspawpy.io.structure import read
     3
     4# 请根据实际情况修改 structure01.as 和 structure02.as 结构文件的路径
     5# 先读取两个构型的分数坐标、元素列表和晶胞信息
     6s1 = read("dspawpy_proj/dspawpy_tests/inputs/2.15/01/structure01.as")[0]
     7s2 = read("dspawpy_proj/dspawpy_tests/inputs/2.15/02/structure02.as")[0]
     8# 计算两个构型的距离,注意这个函数只接受分数坐标
     9dist = get_distance(
    10    spo1=s1.frac_coords,
    11    spo2=s2.frac_coords,
    12    lat1=s1.lattice.matrix,
    13    lat2=s2.lattice.matrix,
    14)
    15print("两个构型的距离为:", dist, "Angstrom")
    

neb续算

  • 如果需对neb进行续算,可参考 8neb_restart.py

     1import os
     2from shutil import copytree, rmtree
     3
     4from dspawpy.diffusion.nebtools import restart
     5
     6if os.path.isdir("dspawpy_proj/dspawpy_tests/outputs/us/neb4bk"):
     7    rmtree("dspawpy_proj/dspawpy_tests/outputs/us/neb4bk")
     8
     9copytree(
    10    "dspawpy_proj/dspawpy_tests/inputs/2.15",
    11    "dspawpy_proj/dspawpy_tests/outputs/us/neb4bk",
    12)
    13restart(
    14    directory="dspawpy_proj/dspawpy_tests/outputs/us/neb4bk",  # NEB任务路径
    15    output="dspawpy_proj/dspawpy_tests/outputs/us/8neb_restart",  # 备份到哪
    16)
    

    具体效果见 neb过渡态计算续算说明

neb计算过程中能量和最大原子受力的变化趋势图

  • 要查看neb计算过程中能量和最大原子受力的变化趋势图,可参考 8neb_energy_force_curves.py

    1from dspawpy.diffusion.nebtools import monitor_force_energy
    2
    3# 指定NEB计算文件夹路径,运行后会在指定目录生成 Energies.png 和 MaxForce.png 图片
    4unfinished_neb_folder = "dspawpy_proj/dspawpy_tests/inputs/supplement/neb_unfinished"
    5monitor_force_energy(
    6    directory=unfinished_neb_folder,
    7    outdir="imgs",  # 输出图片路径
    8)
    

    将生成能量和受力变化趋势图:

    _images/Energies.png
    _images/MaxForce.png
API: write_neb_structures(), plot_barrier(), summary(), get_distance(), write_movie_json(), write_xyz(), restart()
  • write_neb_structures 函数负责生成中间构型:

    dspawpy.diffusion.neb.write_neb_structures(structures: list, coords_are_cartesian: bool = True, fmt: str = 'as', path: str = '.', prefix='structure')

    插值并生成中间构型文件

    参数
    • structures (list) – 构型列表

    • coords_are_cartesian (bool) – 坐标是否为笛卡尔坐标

    • fmt (str) – 结构文件类型,默认为 “as”

    • path (str) – 保存路径

    • prefix (str) – 文件名前缀,默认为 “structure”,这样的话生成的就是 structure00.as, structure01.as, …

    返回

    保存构型文件

    返回类型

    file

    实际案例

    先读取as文件创建structure对象

    >>> from dspawpy.io.structure import read
    >>> init_struct = read("dspawpy_proj/dspawpy_tests/inputs/2.15/00/structure00.as")[0]
    >>> final_struct = read("dspawpy_proj/dspawpy_tests/inputs/2.15/04/structure04.as")[0]
    

    然后,插值并生成中间构型文件

    >>> from dspawpy.diffusion.neb import NEB,write_neb_structures
    >>> neb = NEB(init_struct,final_struct,8)
    >>> structures = neb.linear_interpolate()   #线性插值
    

    插值完成的构型可指定保存到neb文件夹下

    >>> write_neb_structures(structures, path="dspawpy_proj/dspawpy_tests/outputs/doctest/11neb_interpolate_structures") 
    ==> ...structure00.as
    ==> ...structure01.as
    ==> ...structure02.as
    ==> ...structure03.as
    ==> ...structure04.as
    ==> ...structure05.as
    ==> ...structure06.as
    ==> ...structure07.as
    
  • plot_barrier 函数负责绘制能垒图:

    dspawpy.diffusion.nebtools.plot_barrier(datafile: str = 'neb.h5', directory: Optional[str] = None, ri: Optional[float] = None, rf: Optional[float] = None, ei: Optional[float] = None, ef: Optional[float] = None, method: str = 'PchipInterpolator', figname: Optional[str] = 'neb_barrier.png', show: bool = True, raw: bool = False, verbose: bool = False, **kwargs)

    调用 scipy.interpolate 插值算法,拟合NEB能垒并绘图

    参数
    • datafile (str) – neb.h5或neb.json文件路径

    • directory (str) – NEB计算路径

    • ri (float) – 初态反应坐标

    • rf (float) – 末态反应坐标

    • ei (float) – 初态自洽能量

    • ef (float) – 末态自洽能量

    • method (str, optional) – 插值算法, 默认’PchipInterpolator’

    • figname (str, optional) – 能垒图名称, 默认’neb_barrier.png’

    • show (bool, optional) – 是否展示交互界面, 默认True

    • raw (bool, optional) – 是否返回绘图数据到csv

    引发
    • ImportError – 指定了scipy.interpolate中不存在的插值算法

    • ValueError – 传递给插值算法的参数不符合该算法要求

    实际案例

    >>> from dspawpy.diffusion.nebtools import plot_barrier
    >>> import matplotlib.pyplot as plt
    

    对比不同插值算法

    >>> plot_barrier(directory='dspawpy_proj/dspawpy_tests/inputs/2.15', method='interp1d', kind=2, figname=None, show=False)
    >>> plot_barrier(directory='dspawpy_proj/dspawpy_tests/inputs/2.15', method='interp1d', kind=3, figname=None, show=False)
    >>> plot_barrier(directory='dspawpy_proj/dspawpy_tests/inputs/2.15', method='CubicSpline', figname=None, show=False)
    >>> plot_barrier(directory='dspawpy_proj/dspawpy_tests/inputs/2.15', method='pchip', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/barrier_comparison.png', show=False) 
    ==> ...barrier_comparison.png
    

    尝试读取neb.h5文件或neb.json文件

    >>> plot_barrier(datafile='dspawpy_proj/dspawpy_tests/inputs/2.15/neb.h5', method='pchip', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/barrier_h5.png', show=False) 
    ==> ...barrier_h5.png
    >>> plot_barrier(datafile='dspawpy_proj/dspawpy_tests/inputs/2.15/neb.json', method='pchip', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/barrier_json.png', show=False) 
    ==> ...barrier_json.png
    
  • summary 函数负责总结NEB计算任务的说明文档:

    dspawpy.diffusion.nebtools.summary(directory: str = '.', raw=False, show_converge=False, outdir: Optional[str] = None, **kwargs)

    NEB任务完成总结,依次执行以下步骤:

      1. 打印各构型受力、反应坐标、能量、与初始构型的能量差

      1. 绘制能垒图

      1. 绘制并保存结构优化过程的能量和受力收敛过程图

    参数
    • directory (str) – NEB路径, 默认当前路径

    • raw (bool) – 是否保存绘图数据到csv文件

    • show_converge (bool) – 是否展示结构优化过程的能量和受力收敛过程图,默认不展示

    • outdir (str) – 收敛过程图保存路径,默认为directory

    • **kwargs (dict) – 传递给plot_barrier的参数

    实际案例

    >>> from dspawpy.diffusion.nebtools import summary
    >>> directory = 'dspawpy_proj/dspawpy_tests/inputs/2.15' # NEB计算路径,默认当前路径
    >>> summary(directory, show=False, figname='dspawpy_proj/dspawpy_tests/outputs/doctest/neb_barrier.png') 
    shape: (5, 5)
    ┌────────────┬─────────────┬──────────┬───────────────┬──────────┐
    │ FolderName ┆ Force(eV/Å) ┆ RC(Å)    ┆ Energy(eV)    ┆ E-E0(eV) │
    ╞════════════╪═════════════╪══════════╪═══════════════╪══════════╡
    │ 00         ┆ 0.180272    ┆ 0.0      ┆ -39637.097656 ┆ 0.0      │
    │ 01         ┆ 0.014094    ┆ 0.542789 ┆ -39637.019531 ┆ 0.079814 │
    │ 02         ┆ 0.026337    ┆ 1.0868   ┆ -39636.878906 ┆ 0.218265 │
    │ 03         ┆ 0.024798    ┆ 1.588367 ┆ -39637.0      ┆ 0.100043 │
    │ 04         ┆ 0.234429    ┆ 2.089212 ┆ -39637.089844 ┆ 0.008414 │
    └────────────┴─────────────┴──────────┴───────────────┴──────────┘
    ==> ...neb_barrier.png
    ==> ...converge.png
    ==> ...converge.png
    ==> ...converge.png
    
    >>> summary(directory, show=False, figname='dspawpy_proj/dspawpy_tests/outputs/doctest/neb_barrier.png', outdir="dspawpy_proj/dspawpy_tests/outputs/doctest/neb_summary") 
    shape: (5, 5)
    ┌────────────┬─────────────┬──────────┬───────────────┬──────────┐
    │ FolderName ┆ Force(eV/Å) ┆ RC(Å)    ┆ Energy(eV)    ┆ E-E0(eV) │
    ╞════════════╪═════════════╪══════════╪═══════════════╪══════════╡
    │ 00         ┆ 0.180272    ┆ 0.0      ┆ -39637.097656 ┆ 0.0      │
    │ 01         ┆ 0.014094    ┆ 0.542789 ┆ -39637.019531 ┆ 0.079814 │
    │ 02         ┆ 0.026337    ┆ 1.0868   ┆ -39636.878906 ┆ 0.218265 │
    │ 03         ┆ 0.024798    ┆ 1.588367 ┆ -39637.0      ┆ 0.100043 │
    │ 04         ┆ 0.234429    ┆ 2.089212 ┆ -39637.089844 ┆ 0.008414 │
    └────────────┴─────────────┴──────────┴───────────────┴──────────┘
    ==> ...neb_barrier.png
    ==> ...converge.png
    ==> ...converge.png
    ==> ...converge.png
    

    若inifin=false,用户必须将自洽的scf.h5或system.json放到初末态子文件夹中

  • get_distance 函数可以计算两个构型间的距离:

    dspawpy.diffusion.nebtools.get_distance(spo1, spo2, lat1, lat2)

    根据两个结构的分数坐标和晶胞计算距离

    参数
    • spo1 (np.ndarray) – 分数坐标列表1

    • spo2 (np.ndarray) – 分数坐标列表2

    • lat1 (np.ndarray) – 晶胞1

    • lat2 (np.ndarray) – 晶胞2

    返回

    距离

    返回类型

    float

    实际案例

    先读取结构信息

    >>> from dspawpy.io.structure import read
    >>> s1 = read('dspawpy_proj/dspawpy_tests/inputs/2.15/01/structure01.as')[0]
    >>> s2 = read('dspawpy_proj/dspawpy_tests/inputs/2.15/02/structure02.as')[0]
    

    计算两个构型的距离

    >>> from dspawpy.diffusion.nebtools import get_distance
    >>> dist = get_distance(s1.frac_coords, s2.frac_coords, s1.lattice.matrix, s2.lattice.matrix)
    >>> print('两个构型的距离为:', dist, 'Angstrom')
    两个构型的距离为: 0.476972808803491 Angstrom
    
  • write_movie_jsonwrite_xyz 函数可以将中间构型写入json或者xyz文件:

  • restart 函数负责重启NEB计算:

    dspawpy.diffusion.nebtools.restart(directory: str = '.', output: str = 'bakfile')

    将旧NEB任务归档压缩,并在原路径下准备续算

    参数
    • directory (str) – 旧NEB任务所在路径,默认当前路径

    • output (str) – 备份文件夹路径,默认将在当前路径新建一个bakfile文件夹用于备份; 也可以任意指定一个路径,但不能与当前路径相同

    实际案例

    >>> from dspawpy.diffusion.nebtools import restart
    >>> from shutil import copytree
    >>> copytree('dspawpy_proj/dspawpy_tests/inputs/2.15', 'dspawpy_proj/dspawpy_tests/outputs/doctest/neb4bk2', dirs_exist_ok=True)
    'dspawpy_proj/dspawpy_tests/outputs/doctest/neb4bk2'
    >>> restart(directory='dspawpy_proj/dspawpy_tests/outputs/doctest/neb4bk2', output='dspawpy_proj/dspawpy_tests/outputs/doctest/neb_backup') 
    ==> ...neb_backup
    

    续算准备工作可能需要较长时间才能完成,请耐心等待

  • monitor_force_energy 函数负责绘制NEB计算过程的能量和受力变化趋势图:

    dspawpy.diffusion.nebtools.monitor_force_energy(directory: str, outdir: str = '.')

    从xx/DS-PAW.log中读取NEB计算过程中的受力和能量,绘制曲线

    计算过程中无json文件输出,nebXX.h5文件中只有受力信息,因此只能读取 DS-PAW.log

    每一步的能量行匹配规则比较复杂

    … # nstep-1 | energy | dE | time # nstep | energy | dE | time

    Distance(Angstrom) to previous and next images:

    实际案例

    >>> from dspawpy.diffusion.nebtools import monitor_force_energy
    >>> monitor_force_energy(
    ...     directory="dspawpy_proj/dspawpy_tests/inputs/supplement/neb_unfinished",
    ...     outdir="imgs"
    ... ) 
    Max Force shape: (57, 4)
    ┌───────────┬───────────┬───────────┬───────────┐
    │ Folder 01 ┆ Folder 02 ┆ Folder 03 ┆ Folder 04 │
    ╞═══════════╪═══════════╪═══════════╪═══════════╡
    │ 23.775228 ┆ 71.547767 ┆ 72.641234 ┆ 24.147289 │
    │ 22.683711 ┆ 68.595607 ┆ 69.704747 ┆ 23.0549   │
    │ 5.624252  ┆ 20.071221 ┆ 20.049429 ┆ 5.567894  │
    │ 5.354774  ┆ 19.631643 ┆ 19.599093 ┆ 5.425462  │
    │ 3.188546  ┆ 9.840143  ┆ 9.748006  ┆ 2.943709  │
    │ …         ┆ …         ┆ …         ┆ …         │
    │ 0.293867  ┆ 0.812679  ┆ 0.920251  ┆ 0.573649  │
    │ 0.27249   ┆ 0.7475    ┆ 0.921836  ┆ 0.540239  │
    │ 0.299767  ┆ 0.360673  ┆ 1.174016  ┆ 0.416171  │
    │ 0.249903  ┆ 0.288985  ┆ 1.169237  ┆ 0.366117  │
    │ 0.204396  ┆ 0.518356  ┆ 0.913792  ┆ 0.300884  │
    └───────────┴───────────┴───────────┴───────────┘
    Energies shape: (57, 4)
    ┌───────────────┬───────────────┬───────────────┬───────────────┐
    │ Folder 01     ┆ Folder 02     ┆ Folder 03     ┆ Folder 04     │
    ╞═══════════════╪═══════════════╪═══════════════╪═══════════════╡
    │ -40448.281556 ┆ -40436.419243 ┆ -40436.084611 ┆ -40447.527434 │
    │ -40448.491374 ┆ -40437.026948 ┆ -40436.685178 ┆ -40447.73947  │
    │ -40451.391617 ┆ -40446.884408 ┆ -40446.613158 ┆ -40450.686918 │
    │ -40451.448662 ┆ -40447.079933 ┆ -40446.803281 ┆ -40450.743777 │
    │ -40452.126865 ┆ -40450.274376 ┆ -40449.978142 ┆ -40451.405157 │
    │ …             ┆ …             ┆ …             ┆ …             │
    │ -40452.620987 ┆ -40452.538682 ┆ -40452.230568 ┆ -40452.056262 │
    │ -40452.621777 ┆ -40452.544298 ┆ -40452.231776 ┆ -40452.055815 │
    │ -40452.620701 ┆ -40452.565649 ┆ -40452.164604 ┆ -40452.035357 │
    │ -40452.621371 ┆ -40452.569113 ┆ -40452.164784 ┆ -40452.037426 │
    │ -40452.622418 ┆ -40452.577864 ┆ -40452.141919 ┆ -40452.037885 │
    └───────────────┴───────────────┴───────────────┴───────────────┘
    ==> ...MaxForce.png
    ==> ...Energies.png
    

8.9 phonon声子计算数据处理

以MgO体系的声子能带态密度计算得到的 phonon.h5 为例:

如果未安装 phonopy,运行下列脚本时会弹出 no module named 'phonopy' 信息,不影响程序正常运行

声子能带数据处理

 1import os
 2
 3from dspawpy.io.read import get_phonon_band_data
 4from pymatgen.phonon.plotter import PhononBSPlotter
 5
 6band_data = get_phonon_band_data(
 7    "dspawpy_proj/dspawpy_tests/inputs/2.16.1/phonon.h5",
 8)  # 读取声子能带
 9bsp = PhononBSPlotter(band_data)
10axes_or_plt = bsp.get_plot(ylim=None, units="thz")  # y轴范围  # 单位
11import matplotlib.pyplot as plt  # noqa: E402
12
13if isinstance(axes_or_plt, plt.Axes):
14    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
15elif isinstance(axes_or_plt, tuple):
16    fig = axes_or_plt[0].get_figure()
17else:
18    fig = axes_or_plt.gcf()  # older version pymatgen
19
20filename = "dspawpy_proj/dspawpy_tests/outputs/us/9phonon_bandplot.png"  # 输出的声子能带图文件名
21os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
22fig.savefig(filename, dpi=300)

执行代码可以得到类似以下声子能带曲线:

_images/phonon-nonac.png

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

声子态密度数据处理

  • 参考 9phonon_dosplot.py

     1import os
     2
     3from dspawpy.io.read import get_phonon_dos_data
     4from pymatgen.phonon.plotter import PhononDosPlotter
     5
     6dos = get_phonon_dos_data("dspawpy_proj/dspawpy_tests/inputs/2.16.1/phonon.h5")
     7dp = PhononDosPlotter(
     8    stack=False,  # True表示绘制面积图
     9    sigma=None,  # 高斯模糊参数
    10)
    11dp.add_dos(label="Phonon", dos=dos)  # 图例  # 要绘制的声子态密度
    12axes_or_plt = dp.get_plot(
    13    xlim=[0, 20],  # x轴范围
    14    ylim=None,  # y轴范围
    15    units="thz",  # 单位
    16)
    17import matplotlib.pyplot as plt  # noqa: E402
    18
    19if isinstance(axes_or_plt, plt.Axes):
    20    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
    21elif isinstance(axes_or_plt, tuple):
    22    fig = axes_or_plt[0].get_figure()
    23else:
    24    fig = axes_or_plt.gcf()  # older version pymatgen
    25
    26filename = (
    27    "dspawpy_proj/dspawpy_tests/outputs/us/9phonon_dosplot.png"  # 输出的能垒图文件名
    28)
    29os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
    30fig.savefig(filename, dpi=300)
    

    执行代码可以得到类似以下声子态密度曲线:

_images/9phonon_dosplot.png

单晶硅声子态密度示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

声子热力学数据处理

可以参考 9phonon_thermal.py

1from dspawpy.plot import plot_phonon_thermal
2
3plot_phonon_thermal(
4    datafile="dspawpy_proj/dspawpy_tests/inputs/2.26/phonon.h5",  # phonon.h5数据文件路径
5    figname="dspawpy_proj/dspawpy_tests/outputs/us/9phonon.png",  # 输出的声子热力学图文件名
6    show=False,  # 是否显示图片
7)

执行代码可以得到类似以下声子热力学曲线:

_images/9phonon.png

单晶硅声子热力学性质示意图

API: get_phonon_band_data(), get_phonon_dos_data(), plot_phonon_thermal()
  • get_phonon_band_data 函数负责读取声子能带:

    dspawpy.io.read.get_phonon_band_data(phonon_band_dir: str, verbose: bool = False)

    读取h5或json文件中的声子能带数据,构建PhononBandStructureSymmLine对象

    参数

    phonon_band_dir (str) – 能带文件路径,phonon.h5 / phonon.json 或包含这两个文件的文件夹

    返回类型

    PhononBandStructureSymmLine

    实际案例

    >>> from dspawpy.io.read import get_phonon_band_data
    >>> band_data = get_phonon_band_data("dspawpy_proj/dspawpy_tests/inputs/2.16/phonon.h5") # 读取声子能带
    >>> band_data = get_phonon_band_data("dspawpy_proj/dspawpy_tests/inputs/2.16/phonon.json") # 读取声子能带
    
  • get_phonon_dos_data 函数负责读取声子态密度:

    dspawpy.io.read.get_phonon_dos_data(phonon_dos_dir: str, verbose: bool = False)

    读取h5或json文件中的声子态密度数据,构建PhononDos对象

    参数

    phonon_dos_dir (str) – 声子态密度文件路径,phonon_dos.h5 / phonon_dos.json 或包含这两个文件的文件夹

    返回类型

    PhononDos

    实际案例

    >>> from dspawpy.io.read import get_phonon_dos_data
    >>> phdos = get_phonon_dos_data(phonon_dos_dir='dspawpy_proj/dspawpy_tests/inputs/2.16.1/phonon.json')
    >>> phdos = get_phonon_dos_data(phonon_dos_dir='dspawpy_proj/dspawpy_tests/inputs/2.16.1/phonon.h5')
    >>> phdos.frequencies
    array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9,  1. ,
            1.1,  1.2,  1.3,  1.4,  1.5,  1.6,  1.7,  1.8,  1.9,  2. ,  2.1,
            2.2,  2.3,  2.4,  2.5,  2.6,  2.7,  2.8,  2.9,  3. ,  3.1,  3.2,
            3.3,  3.4,  3.5,  3.6,  3.7,  3.8,  3.9,  4. ,  4.1,  4.2,  4.3,
            4.4,  4.5,  4.6,  4.7,  4.8,  4.9,  5. ,  5.1,  5.2,  5.3,  5.4,
            5.5,  5.6,  5.7,  5.8,  5.9,  6. ,  6.1,  6.2,  6.3,  6.4,  6.5,
            6.6,  6.7,  6.8,  6.9,  7. ,  7.1,  7.2,  7.3,  7.4,  7.5,  7.6,
            7.7,  7.8,  7.9,  8. ,  8.1,  8.2,  8.3,  8.4,  8.5,  8.6,  8.7,
            8.8,  8.9,  9. ,  9.1,  9.2,  9.3,  9.4,  9.5,  9.6,  9.7,  9.8,
            9.9, 10. , 10.1, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9,
           11. , 11.1, 11.2, 11.3, 11.4, 11.5, 11.6, 11.7, 11.8, 11.9, 12. ,
           12.1, 12.2, 12.3, 12.4, 12.5, 12.6, 12.7, 12.8, 12.9, 13. , 13.1,
           13.2, 13.3, 13.4, 13.5, 13.6, 13.7, 13.8, 13.9, 14. , 14.1, 14.2,
           14.3, 14.4, 14.5, 14.6, 14.7, 14.8, 14.9, 15. , 15.1, 15.2, 15.3,
           15.4, 15.5, 15.6, 15.7, 15.8, 15.9, 16. , 16.1, 16.2, 16.3, 16.4,
           16.5, 16.6, 16.7, 16.8, 16.9, 17. , 17.1, 17.2, 17.3, 17.4, 17.5,
           17.6, 17.7, 17.8, 17.9, 18. , 18.1, 18.2, 18.3, 18.4, 18.5, 18.6,
           18.7, 18.8, 18.9, 19. , 19.1, 19.2, 19.3, 19.4, 19.5, 19.6, 19.7,
           19.8, 19.9, 20. ])
    
  • plot_phonon_thermal 函数负责绘制声子热力学性质图:

    dspawpy.plot.plot_phonon_thermal(datafile: str = 'phonon.h5', figname: str = 'phonon.png', show: bool = True, raw: bool = False, verbose: bool = False)

    声子热力学计算任务完成后,绘制相关物理量随温度变化曲线

    phonon.h5/phonon.json -> phonon.png

    参数
    • datafile (str) – h5或json文件路径或包含任意这些文件的文件夹,默认 ‘phonon.h5’

    • figname (str) – 保存图片的文件名

    • show (bool) – 是否弹出交互界面

    • raw (bool) – 是否保存绘图数据到rawphonon.csv文件

    返回

    figname – 图片路径,默认 ‘phonon.png’

    返回类型

    str

    实际案例

    >>> from dspawpy.plot import plot_phonon_thermal
    >>> plot_phonon_thermal('dspawpy_proj/dspawpy_tests/inputs/2.26/phonon.h5', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/phonon_thermal_h5.png', show=False)
    >>> plot_phonon_thermal('dspawpy_proj/dspawpy_tests/inputs/2.26/phonon.json', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/phonon_thermal_json.png', show=False, raw=True)
    

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

8.10 aimd分子动力学模拟数据处理

以快速入门 \(H_{2}O\) 分子体系分子动力学模拟得到的 aimd.h5 为例:

轨迹文件转换格式为.xyz或.dump

从aimd输出的hdf5文件中读取数据,并生成轨迹文件

生成的.xyz或.dump格式文件,可拖入OVITO观察,通过 Device Studio –> Simulator –> OVITO 打开 OVITO 可视化界面,将xyz文件或dump文件拖入OVITO即可。

参考 10write_aimd_traj.py

1from dspawpy.io.structure import convert
2
3convert(
4    infile="dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5",  # 待转化结构,如果在当前路径,可以只写文件名
5    si=None,  # 筛选构型编号,如果不指定,默认读取全部
6    ele=None,  # 筛选元素符号,默认读取所有元素的原子信息
7    ai=None,  # 筛选原子编号,从 1 开始,默认读取所有原子信息
8    outfile="dspawpy_proj/dspawpy_tests/outputs/us/10aimdTraj.xyz",  # 也可以生成 .dump 文件(精度较低),暂时只支持正交晶胞
9)

执行代码将生成.xyz和.dump格式的轨迹文件,该文件可通过OVITO打开。关于结构文件转化的更多细节,请参考 structure结构转化

知识点:

OVITO 与 dspawpy 都不支持将非正交晶胞的体系保存为dump文件

动力学过程中能量、温度等变化曲线

  • 参考 10check_aimd_conv.py

     1from dspawpy.plot import plot_aimd
     2
     3plot_aimd(
     4    datafile="dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5",  # 数据文件路径
     5    show=False,  # 是否弹出图像窗口
     6    figname="dspawpy_proj/dspawpy_tests/outputs/us/10aimd.png",  # 输出的图像文件名
     7    flags_str="1 2 3 4 5",  # 选择数据类型
     8)
     9# 其中flags_str的含义如下
    10# 1. 动能
    11# 2. 总能
    12# 3. 压力
    13# 4. 温度
    14# 5. 体积
    

    执行代码将生成如下组合图:

    _images/aimd-joined.png

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

均方位移(MSD) 分析

  • 参考 10aimd_msd.py

     1from dspawpy.analysis.aimdtools import get_lagtime_msd, plot_msd
     2
     3# 如果AIMD非一次性完成,可以将多个h5文件路径以列表形式赋值给datafile参数
     4lagtime, msd = get_lagtime_msd(
     5    datafile="dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5",  # 数据文件路径
     6    select="all",  # 默认选择所有原子
     7    msd_type="xyz",  # 默认计算xyz方向的msd
     8    timestep=None,  # 默认从datafile文件中读取时间步长
     9)
    10# 用获取的数据画图并保存
    11plot_msd(
    12    lagtime,  # 横坐标
    13    msd,  # 纵坐标
    14    xlim=None,  # 设置x轴的显示范围
    15    ylim=None,  # 设置y轴的显示范围
    16    figname="dspawpy_proj/dspawpy_tests/outputs/us/10MSD.png",  # 输出的图像文件名
    17    show=False,  # 是否弹出图像窗口
    18    #   ax = None, # 可指定子图
    19)
    

    执行代码将生成类似如下图片:

    _images/10MSD.png

    均方位移(MSD)示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

均方根偏差(RMSD) 分析

  • 参考 10aimd_rmsd.py

     1from dspawpy.analysis.aimdtools import get_lagtime_rmsd, plot_rmsd
     2
     3# 如果AIMD非一次性完成,可以将多个h5文件路径以列表形式赋值给datafile参数
     4lagtime, rmsd = get_lagtime_rmsd(
     5    datafile="dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5",
     6    timestep=None,  # 数据文件路径  # 默认从datafile文件中读取时间步长
     7)
     8plot_rmsd(
     9    lagtime,  # 横坐标
    10    rmsd,  # 纵坐标
    11    xlim=None,  # 设置x轴的显示范围
    12    ylim=None,  # 设置y轴的显示范围
    13    figname="dspawpy_proj/dspawpy_tests/outputs/us/10RMSD.png",  # 输出的图像文件名
    14    show=False,  # 是否弹出图像窗口
    15    ax=None,  # 可指定子图
    16)
    

    执行代码将生成类似如下图片:

    _images/10RMSD.png

    均方根偏差(RMSD)示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

原子对分布函数或径向分布函数(RDFs) 分析

  • 参考 10aimd_rdf.py

     1from dspawpy.analysis.aimdtools import get_rs_rdfs, plot_rdf
     2
     3# 如果AIMD非一次性完成,可以将多个h5文件路径以列表形式赋值给datafile参数
     4rs, rdfs = get_rs_rdfs(
     5    datafile="dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5",  # 数据文件路径
     6    ele1="H",  # 中心元素
     7    ele2="O",  # 对象元素
     8    rmin=0.0,  # 最小半径
     9    rmax=10.0,  # 最大半径
    10    ngrid=1000,  # 网格数
    11    sigma=0.1,  # sigma值
    12)
    13plot_rdf(
    14    rs,  # 横坐标
    15    rdfs,  # 纵坐标
    16    "H",  # 中心元素
    17    "O",  # 对象元素
    18    figname="dspawpy_proj/dspawpy_tests/outputs/us/10RDF.png",  # 图像保存路径
    19    show=False,  # 是否弹出图像窗口
    20    ax=None,  # 可指定子图
    21)
    

    执行代码将生成类似如下图片:

    _images/10RDF.png

    径向分布函数(RDFs)示意图

  • 这部分涉及的统计学计算较复杂,更多细节请参考函数API

API: plot_aimd(), get_lagtime_msd(), plot_msd(), get_rs_rdfs(), plot_rdf(), get_lagtime_rmsd(), plot_rmsd()
  • plot_aimd 函数可用于协助检查AIMD计算过程中关键物理量的收敛过程:

    dspawpy.plot.plot_aimd(datafile: str = 'aimd.h5', show: bool = True, figname: str = 'aimd.png', flags_str: str = '12345', raw: bool = False)

    AIMD任务完成后,绘制关键物理量的收敛过程图

    aimd.h5 -> aimd.png

    参数
    • datafile (str or list) – h5文件位置. 例如 ‘aimd.h5’ 或 [‘aimd.h5’, ‘aimd2.h5’]

    • show (bool) – 是否展示交互界面. 默认 False

    • figname (str) – 保存的图片路径. 默认 ‘aimd.h5’

    • flags_str (str) – 子图编号. 1. 动能 2. 总能 3. 压力 4. 温度 5. 体积

    • raw (bool) – 是否输出绘图数据到csv文件

    返回

    figname – 图片路径,默认 ‘aimd.png’

    返回类型

    str

    实际案例

    >>> from dspawpy.plot import plot_aimd
    

    读取 aimd.h5 文件内容,画出动能、总能、温度、体积的收敛过程图,并保存相应数据到 rawaimd_*.csv 中

    >>> plot_aimd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', flags_str='1 2 3 4 5', raw=True, show=False, figname="dspawpy_proj/dspawpy_tests/outputs/doctest/aimdconv.png")
    >>> plot_aimd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.json', flags_str='1 2 3 4 5', show=False, figname="dspawpy_proj/dspawpy_tests/outputs/doctest/aimdconv_json.png")
    
  • get_*plot_* 函数负责读取AIMD计算过程中的关键物理量:

    dspawpy.analysis.aimdtools.get_lagtime_msd(datafile: Union[str, List[str]], select: Union[str, List[int]] = 'all', msd_type: str = 'xyz', timestep: Optional[float] = None)

    计算不同时间步长下的均方位移

    参数
    • datafile (str or list of str) –

      • aimd.h5/aimd.json文件路径或包含这些文件的文件夹路径(优先寻找aimd.h5)

      • 写成列表将依次读取数据并合并到一起

      • 例如[‘aimd1.h5’, ‘aimd2.h5’, ‘/data/home/my_aimd_task’]

    • select (str or list of int) – 选择原子序号或元素,原子序号从0开始;默认为’all’,计算所有原子

    • msd_type (str) – 计算MSD的类型,可选xyz,xy,xz,yz,x,y,z,默认为’xyz’,即计算所有分量

    • timestep (float) – 相邻结构的时间间隔,单位为fs,默认None,将从datafile中读取,失败则设为1.0fs; 若不为None,则将使用该值计算时间序列

    返回

    • lagtime (np.ndarray) – 时间序列

    • result (np.ndarray) – 均方位移序列

    实际案例

    >>> from dspawpy.analysis.aimdtools import get_lagtime_msd
    >>> lagtime, msd = get_lagtime_msd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.json', timestep=0.1)
    Calculating MSD...
    >>> lagtime, msd = get_lagtime_msd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5')
    Calculating MSD...
    >>> lagtime
    array([0.000e+00, 1.000e+00, 2.000e+00, ..., 1.997e+03, 1.998e+03,
           1.999e+03])
    >>> msd
    array([0.00000000e+00, 3.75844096e-03, 1.45298732e-02, ...,
           7.98518472e+02, 7.99267490e+02, 7.99992702e+02])
    >>> lagtime, msd = get_lagtime_msd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', select='H')
    Calculating MSD...
    >>> lagtime, msd = get_lagtime_msd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.json', select=[0,1])
    Calculating MSD...
    >>> lagtime, msd = get_lagtime_msd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', select=['H','O'])
    Calculating MSD...
    >>> lagtime, msd = get_lagtime_msd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.json', select=0)
    Calculating MSD...
    
    dspawpy.analysis.aimdtools.get_lagtime_rmsd(datafile: Union[str, List[str]], timestep: Optional[float] = None)
    参数
    • datafile (str or list of str) –

      • aimd.h5/aimd.json文件路径或包含这些文件的文件夹路径(优先寻找aimd.h5)

      • 写成列表将依次读取数据并合并到一起

      • 例如[‘aimd1.h5’, ‘aimd2.h5’, ‘/data/home/my_aimd_task’]

    • timestep (float) – 相邻结构的时间间隔,单位为fs,默认None,将从datafile中读取,失败则设为1.0fs; 若不为None,则将使用该值计算时间序列

    返回

    • lagtime (numpy.ndarray) – 时间序列

    • rmsd (numpy.ndarray) – 均方根偏差序列

    实际案例

    >>> from dspawpy.analysis.aimdtools import get_lagtime_rmsd
    >>> lagtime, rmsd = get_lagtime_rmsd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.json')
    Calculating RMSD...
    >>> lagtime, rmsd = get_lagtime_rmsd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', timestep=0.1)
    Calculating RMSD...
    >>> lagtime
    array([0.000e+00, 1.000e-01, 2.000e-01, ..., 1.997e+02, 1.998e+02,
           1.999e+02])
    >>> rmsd
    array([ 0.        ,  0.05321816,  0.09771622, ..., 28.27847679,
           28.28130893, 28.28414224])
    
    dspawpy.analysis.aimdtools.get_rs_rdfs(datafile: Union[str, List[str]], ele1: str, ele2: str, rmin: float = 0, rmax: float = 10, ngrid: int = 101, sigma: float = 0)

    计算rdf分布函数

    参数
    • datafile (str or list of str) –

      • aimd.h5/aimd.json文件路径或包含这些文件的文件夹路径(优先寻找aimd.h5)

      • 写成列表将依次读取数据并合并到一起

      • 例如[‘aimd1.h5’, ‘aimd2.h5’, ‘/data/home/my_aimd_task’]

    • ele1 (list) – 中心元素

    • ele2 (list) – 相邻元素

    • rmin (float) – 径向分布最小值,默认为0

    • rmax (float) – 径向分布最大值,默认为10

    • ngrid (int) – 径向分布网格数,默认为101

    • sigma (float) – 平滑参数

    返回

    • r (numpy.ndarray) – 径向分布网格点

    • rdf (numpy.ndarray) – 径向分布函数

    实际案例

    >>> from dspawpy.analysis.aimdtools import get_rs_rdfs
    >>> rs, rdfs = get_rs_rdfs(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5',ele1='H',ele2='O', sigma=1e-6)
    Calculating RDF...
    >>> rs, rdfs = get_rs_rdfs(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5',ele1='H',ele2='O')
    Calculating RDF...
    >>> rdfs
    array([0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.00646866,
           0.01098199, 0.0004777 , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        ])
    
    dspawpy.analysis.aimdtools.plot_msd(lagtime, result, xlim: Optional[Sequence] = None, ylim: Optional[Sequence] = None, figname: Optional[str] = None, show: bool = True, ax=None, **kwargs)

    AIMD任务完成后,计算均方位移(MSD)

    参数
    • lagtime (np.ndarray) – 时间序列

    • result (np.ndarray) – 均方位移序列

    • xlim (list of float) – x轴的范围,默认为None,自动设置

    • ylim (list of float) – y轴的范围,默认为None,自动设置

    • figname (str) – 图片名称,默认为None,不保存图片

    • show (bool) – 是否显示图片,默认为True

    • ax (matplotlib axes object) – 用于将图片绘制到matplotlib的子图上

    • **kwargs (dict) – 其他参数,如线条宽度、颜色等,传递给plt.plot函数

    返回类型

    MSD分析后的图片

    实际案例

    >>> from dspawpy.analysis.aimdtools import get_lagtime_msd, plot_msd
    

    指定h5文件位置,用 get_lagtime_msd 函数获取数据,select 参数选择第n个原子(不是元素)

    >>> lagtime, msd = get_lagtime_msd('dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', select=[0]) 
    Calculating MSD...
    

    用获取的数据画图并保存

    >>> plot_msd(lagtime, msd, xlim=[0,800], ylim=[0,1000], figname='dspawpy_proj/dspawpy_tests/outputs/doctest/MSD.png', show=False) 
    ==> ...MSD.png
    ...
    
    dspawpy.analysis.aimdtools.plot_rdf(rs, rdfs, ele1: str, ele2: str, xlim: Optional[Sequence] = None, ylim: Optional[Sequence] = None, figname: Optional[str] = None, show: bool = True, ax=None, **kwargs)

    AIMD计算后分析rdf并画图

    参数
    • rs (numpy.ndarray) – 径向分布网格点

    • rdfs (numpy.ndarray) – 径向分布函数

    • ele1 (list) – 中心元素

    • ele2 (list) – 相邻元素

    • xlim (list) – x轴范围,默认为None,即自动设置

    • ylim (list) – y轴范围,默认为None,即自动设置

    • figname (str) – 图片名称,默认为None,即不保存图片

    • show (bool) – 是否显示图片,默认为True

    • ax (matplotlib.axes.Axes) – 画图的坐标轴,默认为None,即新建坐标轴

    • **kwargs (dict) – 其他参数,如线条宽度、颜色等,传递给plt.plot函数

    返回类型

    rdf分析后的图片

    实际案例

    >>> from dspawpy.analysis.aimdtools import get_rs_rdfs, plot_rdf
    

    先获取rs和rdfs数据作为xy轴数据

    >>> rs, rdfs = get_rs_rdfs('dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', 'H', 'O', rmax=6)
    Calculating RDF...
    

    将xy轴数据传入plot_rdf函数绘图

    >>> plot_rdf(rs, rdfs, 'H','O', xlim=[0, 6], ylim=[0, 0.015],figname='dspawpy_proj/dspawpy_tests/outputs/doctest/RDF.png', show=False) 
    ==> ...RDF.png
    
    dspawpy.analysis.aimdtools.plot_rmsd(lagtime, result, xlim: Optional[Sequence] = None, ylim: Optional[Sequence] = None, figname: Optional[str] = None, show: bool = True, ax=None, **kwargs)

    AIMD计算后分析rmsd并画图

    参数
    • lagtime – 时间序列

    • result – 均方根偏差序列

    • xlim (list) – x轴范围

    • ylim (list) – y轴范围

    • figname (str) – 图片保存路径

    • show (bool) – 是否显示图片

    • ax (matplotlib.axes._subplots.AxesSubplot) – 画子图的话,传入子图对象

    • **kwargs (dict) – 传入plt.plot的参数

    返回类型

    rmsd分析结构的图片

    实际案例

    >>> from dspawpy.analysis.aimdtools import get_lagtime_rmsd, plot_rmsd
    

    timestep 表示时间步长

    >>> lagtime, rmsd = get_lagtime_rmsd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', timestep=0.1)
    Calculating RMSD...
    >>> lagtime, rmsd = get_lagtime_rmsd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.json', timestep=0.1)
    Calculating RMSD...
    

    直接保存为RMSD.png图片

    >>> plot_rmsd(lagtime, rmsd, xlim=[0,200], ylim=[0, 30],figname='dspawpy_proj/dspawpy_tests/outputs/doctest/RMSD.png', show=False) 
    ==> ...RMSD.png
    ...
    
  • 提取数据自行处理请参考:

     1from dspawpy.io.read import get_sinfo
     2from dspawpy.io.structure import read
     3
     4aimd_h5_files = ['aimd1.h5','aimd2.h5','aimd3.h5'] # 可以从计算完成的多个 aimd.h5 中依次抽取数据并合并
     5
     6# 一次性读取多个aimd.h5文件中的数据并创建pymatgen的Structures列表
     7pymatgen_structures = read(datafile=aimd_h5_files)
     8
     9# 或者将数组提取出来
    10for i, df in enumerate(aimd_h5_files): # 依次获取每个aimd.h5文件的数据
    11    Nstep, elements, positions, lattices, D_mag_fix = get_sinfo(df)
    12    # Nstep 表示总离子步数 (int)
    13    # elements 表示元素列表,(Natom x 1)
    14    # positions 表示离子坐标,(Nstep x Natom x 3)
    15    # lattices 表示晶胞矩阵,(Nstep x 3 x 3
    16    # D_mag_fix 磁矩、自由度相关信息字典
    

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

8.11 Polarization铁电极化数据处理

以快速入门 \(HfO_{2}\) 体系铁电计算得到的系列 scf.h5 为例:

  • 参考 11Ferri.py

    1from dspawpy.plot import plot_polarization_figure
    2
    3plot_polarization_figure(
    4    directory="dspawpy_proj/dspawpy_tests/inputs/2.20",  # 铁电极化计算路径
    5    repetition=2,  # 数据点绘图时重复次数
    6    figname="dspawpy_proj/dspawpy_tests/outputs/us/11pol.png",  # 输出的极化图文件名
    7    show=False,  # 是否显示极化图
    8)  # --> pol.png
    

    执行代码将生成如下组合图:

    _images/11pol.png

    12组结构对应极化数值

    查看首尾构型的铁电极化数值,可以参考如下:

    1from dspawpy.plot import plot_polarization_figure
    2
    3plot_polarization_figure(directory='.', annotation=True, annotation_style=1) # 显示首尾构型的铁电极化数值
    

    执行代码将生成如下组合图:

    _images/Ferri-Pola-anno1.png

    12组结构对应极化数值(带首尾构型数值)

    也可以使用第二种批注样式:

    1from dspawpy.plot import plot_polarization_figure
    2
    3plot_polarization_figure(directory='.', annotation=True, annotation_style=2) # 显示首尾构型的铁电极化数值
    

    执行代码将生成如下组合图:

    _images/Ferri-Pola-anno2.png

    12组结构对应极化数值(带首尾构型数值)

API: plot_polarization_figure()
  • plot_polarization_figure 函数负责绘制铁电极化图:

    dspawpy.plot.plot_polarization_figure(directory: str, repetition: int = 2, annotation: bool = False, annotation_style: int = 1, show: bool = True, figname: str = 'pol.png', raw: bool = False)

    绘制铁电极化结果图

    参数
    • directory (str) – 铁电极化计算任务主目录

    • repetition (int) – 沿上(或下)方向重复绘制的次数, 默认 2

    • annotation (bool) – 是否显示首尾构型的铁电极化数值, 默认显示

    • show (bool) – 是否交互显示图片, 默认 True

    • figname (str) – 图片保存路径, 默认 ‘pol.png’

    • raw (bool) – 是否将原始数据保存到csv文件

    返回

    axes – 可传递给其他函数进行进一步处理

    返回类型

    matplotlib.axes._subplots.AxesSubplot

    实际案例

    >>> from dspawpy.plot import plot_polarization_figure
    >>> result = plot_polarization_figure(directory='dspawpy_proj/dspawpy_tests/inputs/2.20', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/pol1.png', show=False, annotation=True, annotation_style=1)
    >>> result = plot_polarization_figure(directory='dspawpy_proj/dspawpy_tests/inputs/2.20', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/pol2.png', show=False, annotation=True, annotation_style=2)
    

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

8.12 ZPE零点振动能数据处理

以快速入门 \(CO\) 体系频率计算得到的 frequency.txt 文件为例,计算零点振动能,基于以下公式:

\[ZPE=\sum_{i=1}^{3 N} \frac{h \nu_i}{2}\]

其中, \(\nu_i\) 是简正频率, \(h\) 是普朗克常数( \(6.626\times10^{-34} J\cdot s\)), \(N\) 是原子数。

  • 参考 12getZPE.py

    1from dspawpy.io.utils import getZPE
    2
    3# 导入频率计算得到的frequency.txt文件
    4getZPE(
    5    fretxt="dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt",
    6)
    

    执行代码结果文件将保存到 ZPE.dat 文件中,文件内容如下:

    Data read from D:\quickstart\2.13\frequency.txt
    Frequency (meV)
    284.840038
    
    --> Zero-point energy,  ZPE (eV): 0.142420019
    
API: getZPE()
  • getZPE 函数负责计算零点振动能:

    dspawpy.io.utils.getZPE(fretxt: str = 'frequency.txt')

    从fretext中读取数据,计算ZPE

    将另外保存结果到 ZPE_TS.dat 中

    参数

    fretxt (str) – 记录频率信息的文件所在路径, 默认当前路径下的’frequency.txt’

    返回

    ZPE – 零点能

    返回类型

    float

    实际案例

    >>> from dspawpy.io.utils import getZPE
    >>> ZPE=getZPE(fretxt='dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt')
    --> Zero-point energy,  ZPE (eV): 0.1424200165
    

8.13 TS的热校正能

吸附质的熵变对能量的贡献

计算基于以下公式:

\[\Delta S_{a d s}\left(0 \rightarrow T, P^0\right)=S_{v i b}=\sum_{i=1}^{3 N}\left[\frac{N_{\mathrm{A}} h \nu_i}{T\left(e^{h \nu_i / k_{\mathrm{B}} T}-1\right)}-R \ln \left(1-e^{-h \nu_i / k_{\mathrm{B}} T}\right)\right]\]

其中, \(\Delta S_{a d s}\) 表示吸附质的熵变,根据简谐近似计算。\(S_{v i b}\) 表示振动熵。 \(\nu_i\) 是简正频率,\(N_A\) 是阿伏伽德罗常数( \(6.022\times10^{23} mol^{-1}\) ), \(h\) 是普朗克常数( \(6.626\times10^{-34} J\cdot s\)), \(k_B\) 是玻尔兹曼常数( \(1.38\times10^{-23} J\cdot K^{-1}\)), \(R\) 是理想气体常数( \(8.314 J\cdot mol^{-1}\cdot K^{-1}\)), \(T\) 是体系温度,单位 \(K\)

  • 参考 13getTSads.py

    1from dspawpy.io.utils import getTSads
    2
    3# 导入频率计算得到的frequency.txt文件,温度可自行修改
    4getTSads(
    5    fretxt="dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt",
    6    T=298.15,
    7)
    

    执行代码结果文件将保存到 TS.dat 文件中,文件内容如下:

    Data read from D:\quickstart\2.13\frequency.txt
    Frequency (THz)
    68.873994
    
    --> Entropy contribution,  T*S (eV): 4.7566990201851275e-06
    

理想气体的熵变对能量的贡献

计算基于如下公式:

\[\begin{split}\begin{aligned} S(T, P) & =S\left(T, P^{\circ}\right)-k_{\mathrm{B}} \ln \frac{P}{P^{\circ}} \\ & =S_{\text {trans }}+S_{\text {rot }}+S_{\text {elec }}+S_{\text {vib }}-k_{\mathrm{B}} \ln \frac{P}{P^{\circ}} \end{aligned}\end{split}\]

其中:

\[S_{\text {trans }}=k_{\mathrm{B}}\left\{\ln \left[\left(\frac{2 \pi M k_{\mathrm{B}} T}{h^2}\right)^{3 / 2} \frac{k_{\mathrm{B}} T}{P^{\circ}}\right]+\frac{5}{2}\right\}\]
\[\begin{split}S_{\mathrm{rot}}= \begin{cases}0 & \text {, monatomic } \\ k_{\mathrm{B}}\left[\ln \left(\frac{8 \pi^2 I k_{\mathrm{B}} T}{\sigma h^2}\right)+1\right] & \text {, linear } \\ k_{\mathrm{B}}\left\{\ln \left[\frac{\sqrt{\pi I_A I_{\mathrm{B}} I_{\mathrm{C}}}}{\sigma}\left(\frac{8 \pi^2 k_B T}{h^2}\right)^{3 / 2}\right]+\frac{3}{2}\right\} & \text {, nonlinear }\end{cases}\end{split}\]
\[S_{\text {elec }}=k_{\mathrm{B}} \ln [2 \times(\text { total spin })+1]\]
\[S_{\text {vib }}=k_{\mathrm{B}} \sum_i^{\text {vib DOF }}\left[\frac{\epsilon_i}{k_{\mathrm{B}} T\left(e^{\epsilon_i / k_{\mathrm{B}} T}-1\right)}-\ln \left(1-e^{-\epsilon_i / k_{\mathrm{B}} T}\right)\right]\]

其中:\(I_A\)\(I_C\) 是非线性分子的三个主惯性矩, \(I\) 是线性分子的简并惯性矩, \(\sigma\) 是分子的对称数。另外,monatomic 表示单原子分子,linear 表示线性分子,nonlinear 表示非线性分子。total spin 是总自旋数。 vib DOF 表示振动自由度。

  • 参考 13getTSgas.py 脚本处理:

     1from dspawpy.io.utils import getTSgas
     2
     3# 从计算结果文件json或h5中读取元素和坐标
     4TSgas = getTSgas(
     5    fretxt="dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt",
     6    datafile="dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.h5",
     7    potentialenergy=-0.0,
     8    geometry="linear",
     9    symmetrynumber=1,
    10    spin=1,
    11    temperature=298.15,
    12    pressure=101325.0,
    13)
    14print("Entropy contribution, T*S (eV):", TSgas)
    15
    16# 如果只有频率txt文件,可通过手动指定元素和坐标完成计算
    17# TSgas = getTSgas(fretxt='dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt', datafile=None, potentialenergy=-0.0, elements=['H', 'H'], geometry='linear', positions=[[0.0, 0.0, 0.0], [0.0, 0.0, 1.0]], symmetrynumber=1, spin=1, temperature=298.15, pressure=101325.0)
    
API: getTSads(), getTSgas()
  • getTSads 函数负责计算吸附质熵变对能量的贡献:

    dspawpy.io.utils.getTSads(fretxt: str = 'frequency.txt', T: float = 298.15)

    从fretext中读取数据,计算ZPE和TS

    将另外保存结果到 TSads.dat 中

    参数
    • fretxt (str) – 记录频率信息的文件所在路径, 默认当前路径下的’frequency.txt’

    • T (float) – 温度,单位K, 默认298.15

    返回

    TS – 熵校正

    返回类型

    float

    实际案例

    >>> from dspawpy.io.utils import getTSads
    >>> TSads=getTSads(fretxt='dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt', T=298.15)
    --> T*S (eV): 4.7566997225177686e-06
    
  • getTSgas 函数负责计算理想气体熵变对能量的贡献:

    dspawpy.io.utils.getTSgas(fretxt='frequency.txt', datafile='.', potentialenergy: float = 0.0, elements=None, geometry='linear', positions=None, symmetrynumber=1, spin=1, temperature=298.15, pressure: float = 101325, verbose: bool = False)

    理想气体近似下,计算熵的能量贡献

    参数
    • fretxt (str) – 记录频率信息的文件所在路径, 默认当前路径下的’frequency.txt’

    • datafile (str) – 计算结果json或h5文件或包含它们的文件夹路径, 默认当前路径; 如果设置为None,则需要传入elements和positions参数

    • potentialenergy (float) – 势能,单位eV

    • elements (list) – 元素列表,如果

    • geometry (str) – 分子几何,monatomic, linear, nonlinear

    • positions (list) – 原子坐标,单位Angstrom

    • symmetrynumber (int) – 对称数

    • spin (int) – 自旋数

    • temperature (float) – 温度,单位K

    • pressure (float) – 压强,单位Pa

    返回

    TSgas – 理想气体近似下,计算熵的能量贡献,单位eV

    返回类型

    float

    实际案例

    >>> from dspawpy.io.utils import getTSgas
    >>> TSgas=getTSgas(fretxt='dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt', datafile='dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.h5', potentialenergy=-0.0,  geometry='linear', symmetrynumber=1, spin=1, temperature=298.15, pressure=101325.0)
    --> T*S (eV): 0.8515317035550232
    

8.14 附录