1a_calc_vel_ops.py — Compute Velocity Operators

Computes the velocity-operator matrix elements at each irreducible q-point using phono3py/WTE and saves them to velocity_operators/save_{iq}.hdf5. These files are required by all subsequent steps.

The velocity operator is built from the dynamical matrix and its momentum-space derivatives evaluated on a Γ-centred BZ mesh. One HDF5 file is written per irreducible q-point.

Prerequisites: phono3py environment (source activate_phono3py.sh).

cd tutorials/diffusivity
python 1a_calc_vel_ops.py
  1#!/usr/bin/env python
  2
  3import sys, os
  4import time
  5import numpy as np
  6import h5py
  7from tqdm import tqdm
  8
  9import phonopy
 10from phonopy import Phonopy
 11from phonopy import file_IO
 12from phonopy.interface.calculator import read_crystal_structure
 13VaspToTHz = phonopy.physical_units.get_physical_units().DefaultToTHz
 14
 15from wte.velocity_operator import VelocityOperator
 16
 17from ase.io import read
 18from ase.units import J, _hplanck  # conversion factors
 19from ase.dft.kpoints import bandpath
 20
 21
 22global start_time
 23
 24# if len(sys.argv) > 1:
 25#     iq = int(sys.argv[1])
 26# else:
 27#     print('error: iq not given')
 28#     exit()
 29
 30withBORN = False
 31
 32
 33def write__to_hdf5(filename, frequencies, qpoints, weights, velocity_operators):
 34    compression = "gzip"
 35    with h5py.File(filename, "w") as w:
 36        w.create_dataset("frequency", data=frequencies, compression=compression)
 37        w.create_dataset("qpoint", data=qpoints)
 38        w.create_dataset("weight", data=weights)
 39        w.create_dataset("velocity_operator", data=velocity_operators, compression=compression)
 40
 41
 42
 43start_time = time.time()
 44eV2Hz = 1 / (J * _hplanck)
 45
 46# input
 47primitive_filename = "POSCAR"
 48supercell = np.diag((2, 2, 2))
 49mesh = [5, 5, 5]
 50interpolation_mesh_size = mesh[0]
 51
 52atoms, string = read_crystal_structure(filename=primitive_filename)
 53at_positions = atoms.scaled_positions
 54nat = len(at_positions)
 55nat3 = 3 * nat
 56
 57print(nat3)
 58
 59
 60# setup FC2
 61phonons = Phonopy(atoms, supercell)
 62
 63force_constants = file_IO.read_force_constants_hdf5(filename="fc2.hdf5")
 64primitive = phonons.primitive
 65
 66if withBORN:
 67    nac_params = file_IO.parse_BORN(primitive, filename="BORN")
 68    phonons.nac_params = nac_params
 69
 70phonons.force_constants = force_constants
 71phonons.symmetrize_force_constants()
 72
 73
 74
 75# diagonalize the dynamical matrix
 76phonons.run_mesh(mesh, is_gamma_center=True, with_group_velocities=False)
 77mesh_dict = phonons.get_mesh_dict()
 78qpoints = mesh_dict['qpoints']
 79weights = mesh_dict['weights']
 80frequencies = np.asarray(mesh_dict['frequencies'])
 81n_q_pt = len(qpoints)
 82time_absolute_1 = time.time()
 83partial_time = time.time() - start_time
 84
 85print('time 1=', partial_time)
 86
 87
 88
 89# calculation of vel op elements
 90os.makedirs('velocity_operators', exist_ok=True)
 91for iq in tqdm(range(n_q_pt), desc='q-points'):
 92    q_pt = qpoints[iq, :]
 93    vel_op = VelocityOperator(
 94        dynamical_matrix=phonons.dynamical_matrix,
 95        q_length=5e-6,
 96        symmetry=phonons.primitive_symmetry,
 97        frequency_factor_to_THz=VaspToTHz,
 98    )
 99    vel_op.run([q_pt])
100    write__to_hdf5('velocity_operators/save_%d.hdf5' % (iq), frequencies[iq, :], qpoints[iq, :], weights[iq], vel_op.velocity_operators[0, :, :, :])
101
102
103print('max_f [cm^-1]=', np.amax(frequencies) * 33.356)
104print('min_f [cm^-1]=', np.amin(frequencies) * 33.356)
105
106time_absolute_2 = time.time()
107total_time = time_absolute_2 - start_time
108
109print('diagonalization time=', time_absolute_2 - time_absolute_1)
110print('total time=', total_time)