Grids in reciprocal space#

The regular grid can be a conventional regular grid or a generalized regular grid. Here the conventional regular grid means that the grids are cut parallel to the reciprocal basis vectors. In most cases, the conventional regular grid is used. In special case, e.g., for crystals with body center tetragonal symmetry, the generalized regular grid can be useful. In phono3py, the generalized regular grid is defined to be cut parallel to the reciprocal basis vectors of the conventional unit cell.

Two types of grid data structure are used in phono3py. Normal regular grid contains translationally unique grid points (regular grid). The other grid includes the points on Brillouin zone (BZ) boundary (BZ grid).

BZGrid class instance#

Grid point information in reciprocal space is stored in the BZGrid class. This class instance can be easily accessed in the following way.

In [1]: import phono3py

In [2]: ph3 = phono3py.load("phono3py.yaml", produce_fc=False)

In [3]: ph3.mesh_numbers = [11, 11, 11]

In [4]: ph3.grid
Out[4]: <phono3py.phonon.grid.BZGrid at 0x1070f3b60>

It is recommended to read docstring in BZGrid by

In [5]: help(ph3.grid)

Some attributes of this class are presented below.

In [6]: ph3.grid.addresses.shape
Out[6]: (1367, 3)

In [7]: ph3.grid.D_diag
Out[7]: array([11, 11, 11])

In [8]: ph3.grid.P
Out[8]:
array([[1, 0, 0],
       [0, 1, 0],
       [0, 0, 1]])

In [9]: ph3.grid.Q
Out[9]:
array([[1, 0, 0],
       [0, 1, 0],
       [0, 0, 1]])

In [10]: ph3.grid.QDinv
Out[10]:
array([[0.09090909, 0.        , 0.        ],
       [0.        , 0.09090909, 0.        ],
       [0.        , 0.        , 0.09090909]])

In [11]: ph3.grid.PS
Out[11]: array([0, 0, 0])

The integer array addresses contains grid point addresses. Every grid point address is represented by the unique series of three integers. These addresses are converted to the q-points in fractional coordinates as explained in the section below.

Unless generalized regular grid is employed, the other attributes are not important. D_diag is equivalent to the three integer numbers of the specified conventional regular grid. P and Q are are the left and right unimodular matrix after Smith normal form: \(\mathrm{D}=\mathrm{PAQ}\), respectively, where \(\mathrm{A}\) is the grid matrix. D_diag is the three diagonal elements of the matrix \(\mathrm{D}\). The grid matrix is usually a diagonal matrix, then \(\mathrm{P}\) and \(\mathrm{Q}\) are chosen as identity matrix. QDinv is given by \(\mathrm{Q}\mathrm{D}^{-1}\). PS represents half-grid-shifts (usually always [0, 0, 0] in phono3py).

Find grid point index corresponding to grid point address#

Grid point index corresponding to a grid point address is obtained using the instance method BZGrid.get_indices_from_addresses as follows:

In [1]: import phono3py

In [2]: ph3 = phono3py.load("phono3py_disp.yaml")

In [3]: ph3.mesh_numbers = [20, 20, 20]

In [4]: ph3.grid.get_indices_from_addresses([0, 10, 10])
Out[4]: 4448

This index number is different between phono3py version 1.x and 2.x. To get the number corresponding to the phono3py version 1.x, store_dense_gp_map=False should be specified in phono3py.load,

In [5]: ph3 = phono3py.load("phono3py_disp.yaml", store_dense_gp_map=False)

In [6]: ph3.mesh_numbers = [20, 20, 20]

In [7]: ph3.grid.get_indices_from_addresses([0, 10, 10])
Out[7]: 4200

q-points in fractional coordinates corresponding to grid addresses#

For Gamma centered regular grid, q-points in fractional coordinates are obtained by

qpoints = addresses @ QDinv.T

For shifted regular grid (usually unused in phono3py),

qpoints = (addresses * 2 + PS) @ (QDinv.T / 2.0)

The grid addresses are stored in phonon-*.hdf5. So for conventional Gamma-centered regular grid, those information can be used to recover the corresponding q-points. For example,

In [1]: import h5py

In [2]: f = h5py.File("phonon-m111111.hdf5")

In [3]: import numpy as np

In [8]: f['grid_address'][:] @ np.diag(1.0 / f['mesh'][:])
Out[8]:
array([[ 0.        ,  0.        ,  0.        ],
       [ 0.09090909,  0.        ,  0.        ],
       [ 0.18181818,  0.        ,  0.        ],
       ...,
       [-0.27272727, -0.09090909, -0.09090909],
       [-0.18181818, -0.09090909, -0.09090909],
       [-0.09090909, -0.09090909, -0.09090909]], shape=(1367, 3))

Grid point triplets#

Three grid point indices are used to represent a q-point triplet. For example the following command generates gamma_detail-m111111-g5.hdf5,

% phono3py-load phono3py.yaml --gp 5 --br --mesh 11 11 11 --write-gamma-detail

This file contains various information:

In [1]: import h5py

In [2]: f = h5py.File("gamma_detail-m111111-g5.hdf5")

In [3]: list(f)
Out[3]:
['gamma_detail',
 'grid_point',
 'mesh',
 'temperature',
 'triplet',
 'triplet_all',
 'version',
 'weight']

In [4]: f['gamma_detail'].shape
Out[4]: (101, 146, 6, 6, 6)

For the detailed analysis of contributions of triplets to imaginary part of self energy a phonon mode of the grid point, it is necessary to understand the data structure of triplet and weight.

In [5]: f['triplet'].shape
Out[5]: (146, 3)

In [6]: f['weight'].shape
Out[6]: (146,)

In [7]: f['triplet'][:10]
Out[7]:
array([[  5,   0,   6],
       [  5,   1,   5],
       [  5,   2,   4],
       [  5,   3,   3],
       [  5,   7,  10],
       [  5,   8,   9],
       [  5,  11, 118],
       [  5,  12, 117],
       [  5,  13, 116],
       [  5,  14, 115]])

The second index of gamma_detail corresponds to the first index of triplet. Three integers of each triplet are the grid point indices, which means, the grid addresses and their q-points are recovered by

In [8]: import phono3py

In [9]: ph3 = phono3py.load("phono3py.yaml", produce_fc=False)

In [10]: ph3.mesh_numbers = [11, 11, 11]

In [11]: ph3.grid.addresses[f['triplet'][:10]]
Out[11]:
array([[[ 5,  0,  0],
        [ 0,  0,  0],
        [-5,  0,  0]],

       [[ 5,  0,  0],
        [ 1,  0,  0],
        [ 5,  0,  0]],

       [[ 5,  0,  0],
        [ 2,  0,  0],
        [ 4,  0,  0]],

       [[ 5,  0,  0],
        [ 3,  0,  0],
        [ 3,  0,  0]],

       [[ 5,  0,  0],
        [-4,  0,  0],
        [-1,  0,  0]],

       [[ 5,  0,  0],
        [-3,  0,  0],
        [-2,  0,  0]],

       [[ 5,  0,  0],
        [ 0,  1,  0],
        [-5, -1,  0]],

       [[ 5,  0,  0],
        [ 1,  1,  0],
        [ 5, -1,  0]],

       [[ 5,  0,  0],
        [ 2,  1,  0],
        [ 4, -1,  0]],

       [[ 5,  0,  0],
        [ 3,  1,  0],
        [ 3, -1,  0]]])

n [14]: ph3.grid.addresses[f['triplet'][:10]] @ ph3.grid.QDinv
Out[14]:
array([[[ 0.45454545,  0.        ,  0.        ],
        [ 0.        ,  0.        ,  0.        ],
        [-0.45454545,  0.        ,  0.        ]],

       [[ 0.45454545,  0.        ,  0.        ],
        [ 0.09090909,  0.        ,  0.        ],
        [ 0.45454545,  0.        ,  0.        ]],

       [[ 0.45454545,  0.        ,  0.        ],
        [ 0.18181818,  0.        ,  0.        ],
        [ 0.36363636,  0.        ,  0.        ]],

       [[ 0.45454545,  0.        ,  0.        ],
        [ 0.27272727,  0.        ,  0.        ],
        [ 0.27272727,  0.        ,  0.        ]],

       [[ 0.45454545,  0.        ,  0.        ],
        [-0.36363636,  0.        ,  0.        ],
        [-0.09090909,  0.        ,  0.        ]],

       [[ 0.45454545,  0.        ,  0.        ],
        [-0.27272727,  0.        ,  0.        ],
        [-0.18181818,  0.        ,  0.        ]],

       [[ 0.45454545,  0.        ,  0.        ],
        [ 0.        ,  0.09090909,  0.        ],
        [-0.45454545, -0.09090909,  0.        ]],

       [[ 0.45454545,  0.        ,  0.        ],
        [ 0.09090909,  0.09090909,  0.        ],
        [ 0.45454545, -0.09090909,  0.        ]],

       [[ 0.45454545,  0.        ,  0.        ],
        [ 0.18181818,  0.09090909,  0.        ],
        [ 0.36363636, -0.09090909,  0.        ]],

       [[ 0.45454545,  0.        ,  0.        ],
        [ 0.27272727,  0.09090909,  0.        ],
        [ 0.27272727, -0.09090909,  0.        ]]])