跳转到主要内容

一个工具箱,使处理周期性边界条件下的材料更加容易。

项目描述

PyPI version PyPI status pipeline status coverage report License: MIT

pbcpy 是一个Python3包,提供了一些处理周期性边界条件(PBC)下分子和材料的有用抽象。

此外,pbcpy公开了一个完全周期的N秩数组,即pbcarray,它是由numpy.ndarray派生而来的。

最后,pbcpy提供对一些常见文件格式的IO支持

  • Quantum Espresso .pp格式(只读)

  • XCrySDen .xsf格式(只写)

索引

作者

pbcpy 是由 Pavanello Research Group 开发的

  • Alessandro Genova

由以下人员贡献:

  • Tommaso Pavanello

  • Michele Pavanello

基础

  • DirectCellCoord 类,它们分别在实空间中定义了PBC下的晶胞和笛卡尔/晶体坐标;

  • ReciprocalCell 类,它定义了倒空间中的晶胞;

  • DirectGridReciprocalGrid 类,它们是从 DirectCellReciprocalCell 派生出来的,并提供空间离散化。

  • DirectFieldReciprocalField 类,用于表示与 DirectGridReciprocalGrid 关联的标量(如电子密度或势)和/或矢量场;

安装

通过 PyPI 安装 pbcpy

pip install pbcpy

gitlab 安装开发版本;

git clone git@gitlab.com:ales.genova/pbcpy.git

注意:pbcpy 处于早期开发阶段,类和 API 可能会不事先通知而更改;

DirectCellReciprocalCell 类;

晶胞由其晶格矢量定义。为了创建一个 DirectCell 对象,我们需要提供包含晶格矢量(作为列)的 3x3 矩阵。pbcpy 预期原子单位,未来可能会添加一个灵活的单位系统;

>>> from pbcpy.base import DirectCell, ReciprocalCell
>>> import numpy as np
>>> lattice = np.identity(3)*10 # Make sure that at1 is of type numpy array.
>>> cell1 = DirectCell(lattice=lattice, origin=[0,0,0]) # 10 Bohr cubic cell

DirectCellReciprocalCell 属性;

  • lattice:晶格矢量(作为列);

  • volume:晶胞的体积;

  • origin:笛卡尔参考系的起点;

# the lattice
>>> cell1.lattice
array([[ 10.,   0.,   0.],
       [  0.,  10.,   0.],
       [  0.,   0.,  10.]])

# the volume
>>> cell1.volume
1000.0

DirectCellReciprocalCell 方法;

  • == 操作符:比较两个 Cell 对象;

  • get_reciprocal:返回一个新的 ReciprocalCell 对象,它是 self 的“倒数”晶胞(如果 self 是 DirectCell);

  • get_direct:返回一个新的 DirectCell 对象,它是 self 的“直接”晶胞(如果 self 是 ReciprocalCell);

注意,在将直接晶格和倒易晶格之间转换时,默认使用物理约定;

\big[\text{reciprocal.lattice}\big]^T = 2\pi \cdot \big[\text{direct.lattice}\big]^{-1}
>>> reciprocal_cell1 = cell1.get_reciprocal()
>>> print(reciprocal_cell1.lattice)
array([[ 0.62831853,  0. ,  0. ],
       [ 0. ,  0.62831853,  0. ],
       [ 0. ,  0. ,  0.62831853]])

>>> cell2 = reciprocal_cell1.get_direct()
>>> print(cell2.lattice)
array([[ 10.,  0.,  0.],
       [ 0.,  10.,  0.],
       [ 0.,  0.,  10.]])

>>> cell1 == cell2
True

Coord 类;

Coord 是一个基于 numpy.array 的派生类,具有一些额外的属性和方法。在周期性系统中,没有参考晶胞,坐标是没有意义的,这就是为什么 Coord 对象也包含一个内嵌的 DirectCell 属性。此外,坐标可以以 "Cartesian""Crystal" 基础表达。

>>> from pbcpy.base import Coord
>>> pos1 = Coord(pos=[0.5,0.6,0.3], cell=cell1, ctype="Cartesian")

Coord 属性;

  • basis:坐标类型:'Cartesian''Crystal'

  • cell:与坐标相关联的 DirectCell 对象。

# the coordinate type (Cartesian or Crystal)
>>> pos1.basis
'Cartesian'

# the cell attribute is a Cell object
>>> type(pos1.cell)
pbcpy.base.DirectCell

Coord 方法;

  • to_crys()to_cart():将 self 转换为晶体或笛卡尔基础(返回一个新的 Coord 对象)。

  • d_mic(other):计算连接两个坐标的矢量(从 self 到 other),使用最小图像公约(MIC)。结果是本身也是一个 Coord 对象。

  • dd_mic(other):使用 MIC 计算两个坐标之间的距离。

  • +/- 操作符:在不使用 MIC 的情况下计算两个坐标之间的差/和。当需要时自动执行基础转换。结果是本身也是一个 Coord 对象。

>>> pos1 = Coord(pos=[0.5,0.0,1.0], cell=cell1, ctype="Crystal")
>>> pos2 = Coord(pos=[0.6,-1.0,3.0], cell=cell1, ctype="Crystal")

# convert to Crystal or Cartesian (returns new object)
>>> pos1.to_cart()
Coord([  5.,   0.,  10.]) # the coordinate was already Cartesian, the result is still correct.
>>> pos1.to_crys()
Coord([ 0.5,  0. ,  1. ]) # the coordinate was already Crystal, the result is still correct.

## vector connecting two coordinates (using the minimum image convention), and distance
>>> pos1.d_mic(pos2)
Coord([ 0.1,  0. ,  0. ])
>>> pos1.dd_mic(pos2)
0.99999999999999978

## vector connecting two coordinates (without using the minimum image convention) and distance
>>> pos2 - pos1
Coord([ 0.1, -1. ,  2. ])
>>> (pos2 - pos1).length()
22.383029285599392

DirectGridReciprocalGrid 类;

DirectGridReciprocalGrid 分别是 DirectGridReciprocalGrid 的子类。网格继承了它们各自单元格的所有属性和方法,并有一些自己特有的属性来处理等间距网格上的量。

>>> from pbcpy.grid import DirectGrid
# A 10x10x10 Bohr Grid, with 100x100x100 gridpoints
>>> lattice = np.identity(3)*10
>>> grid1 = DirectGrid(lattice=lattice, nr=[100,100,100], origin=[0,0,0])

Grid 属性

  • Cell 继承的所有属性

  • dV:单一点的体积,当计算积分量时很有用

  • nr:数组,每个方向的网格点数

  • nnr:网格中的总点数

  • r:每个网格点的笛卡尔坐标。一个类型为 Coord 的 3 级数组(仅限 DirectGrid

  • s:每个网格点的晶体坐标。一个类型为 Coord 的 3 级数组(仅限 DirectGrid

  • g:每个网格点的 G 矢量(仅限 ReciprocalGrid

  • gg:每个网格点的 G 矢量的平方(仅限 ReciprocalGrid

# The volume of each point
>>> grid1.dV
0.001

# Grid points for each direction
>>> grid1.nr
array([100, 100, 100])

# Total number of grid points
>>> grid1.nnr
1000000

# Cartesian coordinates at each grid point
>>> grid1.r
Coord([[[[ 0. ,  0. ,  0. ],
         [ 0. ,  0. ,  0.1],
         [ 0. ,  0. ,  0.2],
         [ 0. ,  0. ,  0.3],
                        ...]]])

>>> grid1.r.shape
(100, 100, 100, 3)

>>> grid1.r[0,49,99]
Coord([ 0. ,  4.9,  9.9])

# Crystal coordinates at each grid point
>>> grid1.s
Coord([[[[ 0.  ,  0.  ,  0.  ],
     [ 0.  ,  0.  ,  0.01],
         [ 0.  ,  0.  ,  0.02],
         [ 0.  ,  0.  ,  0.03],
              ...]]]])

# Since DirectGrid inherits from DirectCell, we can still use the get_reciprocal methos
reciprocal_grid1 = grid1.get_reciprocal()

# reciprocal_grid1 is an instance of ReciprocalGrid
>>> reciprocal_grid1.g
array([[[[ 0.  ,  0.  ,  0.  ],
         [ 0.  ,  0.  ,  0.01],
         [ 0.  ,  0.  ,  0.02],
         ...,
         [ 0.  ,  0.  , -0.03],
         [ 0.  ,  0.  , -0.02],
         [ 0.  ,  0.  , -0.01]],
                   ...]]])

>>> reciprocal_grid1.g.shape
(100, 100, 100, 3)

>>> reciprocal_grid1.gg
array([[[ 0.    ,  0.0001,  0.0004, ...,  0.0009,  0.0004,  0.0001],
        [ 0.0001,  0.0002,  0.0005, ...,  0.001 ,  0.0005,  0.0002],
        [ 0.0004,  0.0005,  0.0008, ...,  0.0013,  0.0008,  0.0005],
        ...,
        [ 0.0009,  0.001 ,  0.0013, ...,  0.0018,  0.0013,  0.001 ],
        [ 0.0004,  0.0005,  0.0008, ...,  0.0013,  0.0008,  0.0005],
        [ 0.0001,  0.0002,  0.0005, ...,  0.001 ,  0.0005,  0.0002]],
        ...,
                                                                  ]])

>>> reciprocal_grid1.gg.shape
(100, 100, 100)

DirectFieldReciprocalField

DirectFieldReciprocalField 类分别代表直接网格和倒数网格上的标量场。这些类是 numpy.ndarray 的扩展。

操作,如插值、快速傅里叶变换和逆变换,以及任意 1D/2D/3D 切片变得非常简单。

DirectField 可以直接从 Quantum Espresso 后处理 .pp 文件生成(见下文)。

# A DirectField example
>>> from pbcpy.field import DirectField
>>> griddata = np.random.random(size=grid1.nr)
>>> field1 = DirectField(grid=grid1, griddata_3d=griddata)

# When importing a Quantum Espresso .pp files a DirectField object is created
>>> from pbcpy.formats.qepp import PP
>>> water_dimer = PP(filepp="/path/to/density.pp").read()
>>> rho = water_dimer.field
>>> type(rho)
pbcpy.field.DirectField

DirectField 属性

  • grid:表示与场相关的网格(它是一个 DirectGridReciprocalGrid 对象)

  • span:具有大于 1 的点数的网格的维度数

  • rank:每个网格点上量的维度数

    • 1:标量场(例如,rho 的秩为 1

    • >1:矢量场(例如,rho 的梯度的秩为 3

>>> type(rho.grid)
pbcpy.grid.DirectGrid

>>> rho.span
3

>>> rho.rank
1
# the density is a scalar field

DirectField 方法

  • numpy.array 继承的任何方法。

  • integral:返回场的积分。

  • get_3dinterpolation:将数据插值到不同的网格(返回一个新的 DirectField 对象)。3 阶样条插值。

  • get_cut(r0, [r1], [r2], [origin], [center], [nr]):通过提供任意向量和原点/中心来获取标量场的 1D/2D/3D 切片。

  • fft:计算自变量的傅里叶变换,并返回一个 ReciprocalField 实例,其中包含适当的 ReciprocalGrid

# Integrate the field over the whole grid
>>> rho.integral()
16.000000002898673 # the electron density of a water dimer has 16 valence electrons as expected

# Interpolate the scalar field from one grid to another
>>> rho.shape
(125, 125, 125)

>>> rho_interp = rho.get_3dinterpolation([90,90,90])
>>> rho_interp.shape
(90, 90, 90)

>> rho_interp.integral()
15.999915251442873


# Get arbitrary cuts of the scalar field.
# In this example get the cut of the electron density in the plane of the water molecule
>>> ppfile = "/path/to/density.pp"
>>> water_dimer = PP(ppfile).read()

>>> o_pos = water_dimer.ions[0].pos
>>> h1_pos = water_dimer.ions[1].pos
>>> h2_pos = water_dimer.ions[2].pos

>>> rho_cut = rho.get_cut(r0=o_h1_vec*4, r1=o_h2_vec*4, center=o_pos, nr=[100,100])

# plot_cut is itself a DirectField instance, and it can be either exported to an xsf file (see next session)
# or its values can be analized/manipulated in place.
>>> rho_cut.shape
(100,100)
>>> rho_cut.span
2
>>> rho_cut.grid.lattice
array([[ 1.57225214, -6.68207161, -0.43149218],
       [-1.75366585, -3.04623853,  0.8479004 ],
       [-7.02978121,  0.97509868, -0.30802502]])

# plot_cut is itself a Grid_Function_Base instance, and it can be either exported to an xsf file (see next session)
# or its values can be analized/manipulated in place.
>>> plot_cut.values.shape
(200, 200)

# Fourier transform of the DirectField
>>> rho_g = rho.fft()
>>> type(rho_g)
pbcpy.field.ReciprocalField

ReciprocalField 方法

  • ifft:计算自变量的逆傅里叶变换,并返回一个 DirectField 实例,其中包含适当的 DirectGrid

# inv fft:
# recall that rho_g = fft(rho)
>>> rho1 = rho_g.ifft()
>>> type(rho1)
pbcpy.field.DirectField

>>> rho1.grid == rho.grid
True

>>> np.isclose(rho1, rho).all()
True
# as expected ifft(fft(rho)) = rho

System

System 类仅包含一个 DirectCell(或 DirectGrid),一组原子 ions 和一个 DirectField

System 属性

  • 名称 : 任意名称

  • 离子 : 原子集合及其坐标

  • 晶胞 : 系统的单位晶胞(DirectCellDirectGrid

  • : 可选的 DirectField 对象。

pbcarray

pbcarraynumpy.ndarray 的子类,适合表示周期性量,通过包含强大的封装功能。 pbcarray 可以为任何秩,并且可以进行自由切片。

# 1D example, but it is valid for any rank.
>>> from pbcpy.base import pbcarray
>>> import  matplotlib.pyplot as plt
>>> x = np.linspace(0,2*np.pi, endpoint=False, num=100)
>>> y = np.sin(x)
>>> y_pbc = pbcarray(y)
>>> y_pbc.shape
(100,)                          # y_pbc only has 100 elements, but we can freely do operations such as:
>>> plt.plot(y_pbc[-100:200])   # and get the expected result

文件格式

PP

pbcpy 可以将 Quantum Espresso 后处理 .pp 文件读取到 System 对象中。

>>> water_dimer = PP(filepp='/path/to/density.pp').read()
# the output of PP.read() is a System object.

XSF

pbcpy 可以将 System 对象写入 XCrySDen 的 .xsf 文件。

>>> XSF(filexsf='/path/to/output.xsf').write(system=water_dimer)

# an optional field parameter can be passed to XSF.write() in order to override the DirectField in system.
# This is especially useful if one wants to output one system and an arbitrary cut of the grid,
# such as the one we generated earlier
>>> XSF(filexsf='/path/to/output.xsf').write(system=water_dimer, field=rho_cut)

项目详情


下载文件

下载适合您平台的文件。如果您不确定该选择哪个,请了解更多关于 安装包 的信息。

源代码分发

pbcpy-0.2.7.tar.gz (26.6 kB 查看哈希值)

上传时间 源代码

支持者