Source code for abipy.eph.common

# coding: utf-8
"""
Objects common to the other eph modules.
"""
from __future__ import annotations

import numpy as np
import abipy.core.abinit_units as abu

from collections import OrderedDict
from monty.functools import lazy_property
from abipy.electrons.ebands import ElectronsReader

# Phonon frequency in Ha below which e-ph matrix elements are set to zero.
EPH_WTOL = 1e-6


[docs] class BaseEphReader(ElectronsReader): """ Provides methods common to the netcdf files produced by the EPH code. See Abinit docs for the meaning of the variables. """
[docs] @lazy_property def ddb_ngqpt(self) -> np.ndarray: """Q-Mesh for DDB file.""" return self.read_value("ddb_ngqpt")
[docs] @lazy_property def ngqpt(self) -> np.ndarray: """Effective Q-mesh used in to compute integrals (ph_linewidts, e-ph self-energy).""" return self.read_value("ngqpt")
[docs] @lazy_property def ph_ngqpt(self) -> np.ndarray: """Q-mesh for Phonon DOS, interpolated A2F ...""" return self.read_value("ph_ngqpt")
[docs] @lazy_property def eph_ngqpt_fine(self) -> np.ndarray: """Q-mesh for interpolated DFPT potentials""" return self.read_value("eph_ngqpt_fine")
[docs] @lazy_property def common_eph_params(self) -> dict: """ Read basic parameters (scalars) from the netcdf files produced by the EPH code and cache them """ od = OrderedDict([ ("ddb_nqbz", np.prod(self.ddb_ngqpt)), ("eph_nqbz_fine", np.prod(self.eph_ngqpt_fine)), ("ph_nqbz", np.prod(self.ph_ngqpt)), ]) for vname in ["eph_intmeth", "eph_fsewin", "eph_fsmear", "eph_extrael", "eph_fermie"]: value = self.read_value(vname) if vname in ("eph_intmeth",): value = int(value) else: value = float(value) od[vname] = value return od
[docs] def glr_frohlich(qpoint, becs_cart, epsinf_cart, phdispl_cart_bohr, phfreqs_ha, structure, qdamp=None, eph_wtol=EPH_WTOL, tol_qnorm=1e-6): """ Compute the long-range part of the e-ph matrix element with the simplified Frohlich model i.e. we include only G = 0 and the <k+q,b1|e^{i(q+G).r}|b2,k> coefficient is replaced by delta_{b1, b2} Args: qpoint: |Kpoint| object. becs_cart: (natom, 3, 3) arrays with Born effective charges in Cartesian coordinates. epsinf_cart: (3, 3) array with macroscopic dielectric tensor in Cartesian coordinates. phdispl_cart_bohr: (natom3_nu, natom3) complex array with phonon displacement in Cartesian coordinates (Bohr) phfreqs_ha: (3 * natom) array with phonon frequencies in Ha. structure: |Structure| object. qdamp: Exponential damping. eph_wtol: Set g to zero below this phonon frequency. tol_qnorm: Tolerance of the norm of the q-point. Return: (natom3) complex array with glr_nu. """ natom = len(structure) natom3 = natom * 3 # 2pi factor already included in frac_coords qcs = qpoint.cart_coords q_eps_q = np.dot(qcs, np.matmul(epsinf_cart, qcs)) phdispl_cart_bohr = np.reshape(phdispl_cart_bohr, (natom3, natom, 3)) xred = structure.frac_coords # Acoustic modes are included --> assume BECS fullfill charge neutrality glr_nu = np.empty(natom3, dtype=complex) for nu in range(natom3): if phfreqs_ha[nu] < EPH_WTOL or q_eps_q < tol_qnorm: continue num = 0.0j for iat in range(natom): cdd = phdispl_cart_bohr[nu, iat] * np.exp(-2.0j * np.pi * np.dot(qpoint.frac_coords, xred[iat])) num += np.dot(qcs, np.matmul(becs_cart[iat], cdd)) glr_nu[nu] = num / (q_eps_q * np.sqrt(2.0 * phfreqs_ha[nu])) fact = 1 if qdamp is not None: fact = np.exp(-qpoint.norm**2/(4*qdamp)) return fact * glr_nu * 4j * np.pi / (structure.volume*abu.Ang_Bohr**3)