Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions tutorial/exciton-phonon/ip_raman.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
"""
IP one-phonon Stokes Raman with yambopy.

The driver does all the band-window bookkeeping:
- loads lattice, electrons, dipoles, ndb.elph
- BZ-expands the dipoles via YamboDipolesDB(expand=True) and reorders
them into the LetzElPhC k-grid
- slices electron energies, dipoles and gkkp to the user-chosen
`raman_bands` window (Fortran 1-indexed, inclusive)
- passes ready-to-use arrays to ip_resonant_raman_tensor_oneph

The Raman function itself takes only the energies, dipoles, gkkp,
cell volume and broadening and evaluates the formula.

Assumes yambo wrote velocity-gauge dipoles (DIP_v in ndb.dipoles).
"""

import numpy as np

from yambopy import (YamboLatticeDB, YamboElectronsDB,
YamboDipolesDB, LetzElphElectronPhononDB)
from yambopy.exciton_phonon.excph_resonant_raman import ip_resonant_raman_tensor_oneph


# ---- User inputs ----------------------------------------------------------
folder = '.'
SAVE_dir = folder + '/SAVE'
elph_path = folder + '/ndb.elph'
dipole_path = folder + '/dipoles/ndb.dipoles'

omega_range = (1.0, 6.0, 501) # laser energies (eV): min, max, npts
broading = 0.10 # Lorentzian broadening (eV)
ph_fre_th = 5.0 # acoustic-mode cutoff (cm^-1)
raman_bands = (44, 56) # 1-indexed Fortran inclusive


# ---- Databases ------------------------------------------------------------
lattice = YamboLatticeDB.from_db_file(filename='%s/ns.db1' % SAVE_dir)
electrons = YamboElectronsDB.from_db_file(folder=SAVE_dir,
filename='ns.db1', Expand=True)
dipdb = YamboDipolesDB.from_db_file(lattice,
filename=dipole_path,
dip_type='v',
project=False,
expand=True)
elph = LetzElphElectronPhononDB(elph_path, read_all=True)


# ---- Yambo BZ -> elph BZ permutation --------------------------------------
diff = elph.kpoints[:, None, :] - lattice.red_kpoints[None, :, :]
diff = diff - np.round(diff)
perm = np.argmin(np.linalg.norm(diff, axis=-1), axis=1)


Comment on lines +50 to +54
# ---- Resolve band range (1-indexed inclusive, Fortran) -------------------
b_in_F, b_out_F = raman_bands
nb = b_out_F - b_in_F + 1
n_val = int(electrons.nbandsv) - (b_in_F - 1)
nc = nb - n_val
cell_vol = float(lattice.lat_vol)


# ---- eph_g(q=0) sliced to the raman window --------------------------------
elph_b_in_F = int(min(elph.bands))
off = b_in_F - elph_b_in_F

iq0 = 0
g_q0 = elph.gkkp[iq0, :, :, 0, :, :] # (nk, nmodes, nb_i, nb_f)
g_q0 = np.swapaxes(g_q0, -1, -2)
eph_g = np.transpose(g_q0, (1, 0, 2, 3)) / 2.0 # (nmodes, nk, nb_eph, nb_eph), Ha
eph_g = eph_g[:, :, off : off + nb, off : off + nb] # (nmodes, nk, nb, nb)

ph_eV = elph.ph_energies[iq0] # (nmodes,), eV
Comment on lines +58 to +73


# ---- KS energies in elph k-order, sliced to the raman window --------------
el_eV = electrons.eigenvalues[0][perm, b_in_F - 1 : b_out_F] # (nk, nb)


# ---- Velocity dipoles: cv block, reorder, slice to raman cv block --------
nv_dip = int(dipdb.nbandsv)
nc_dip = int(dipdb.nbandsc)
elec_dipoles = dipdb.dipoles[:, :, nv_dip : nv_dip + nc_dip, :nv_dip] # (nk_y, 3, nc_dip, nv_dip)
elec_dipoles = elec_dipoles[perm] # -> elph k-order
elec_dipoles = elec_dipoles[:, :, :nc, -n_val:] # raman cv block
elec_dipoles = np.transpose(elec_dipoles, (1, 0, 2, 3)) # (3, nk, nc, n_val)


# ---- Raman calculation ----------------------------------------------------
laser_eV = np.linspace(omega_range[0], omega_range[1], int(omega_range[2]))

R = ip_resonant_raman_tensor_oneph(
laser_energies = laser_eV,
ph_energies = ph_eV,
el_energies = el_eV,
elec_dipoles = elec_dipoles,
eph_g = eph_g,
cell_vol = cell_vol,
broad = broading,
ph_freq_threshold = ph_fre_th,
)


# ---- Save -----------------------------------------------------------------
raman_inte = np.sum(np.abs(R)**2, axis=(1, 2, 3))

np.savetxt('raman_intensity.dat',
np.column_stack([laser_eV, raman_inte]),
header='laser_energy(eV) raman_intensity(arb.u.)')

np.savez('Raman_tensors.npz',
laser_energies_eV = laser_eV,
ph_freq_cm = ph_eV * 8065.54,
raman_tensor = R)

print('Wrote raman_intensity.dat and Raman_tensors.npz')
Loading