Source code for elli.dispersions.tanguy

# Encoding: utf-8
"""Fractional dimensional Tanguy model."""

import numpy as np
import numpy.typing as npt
from numpy.lib.scimath import sqrt

# pylint: disable=no-name-in-module
from scipy.special import digamma, gamma

from ..utils import conversion_wavelength_energy
from .base_dispersion import Dispersion


[docs] class Tanguy(Dispersion): r"""Fractional dimensional Tanguy model. This model is an analytical expression of Wannier excitons, including bound and unbound states. Single parameters: :A: Amplitude (eV). Defaults to 1. :d: Dimensionality 1 < d <= 3. Defaults to 3. :gamma: Excitonic broadening (eV). Defaults to 0.1. :R: Excitonic binding energy (eV). Defaults to 0.1. :Eg: Optical band gap energy (eV). Defaults to 1. :a: Sellmeier coefficient for background dielectric constant (eV²). Defaults to 0. :b: Sellmeier coefficient for background dielectric constant (eV²). Defaults to 0. Repeated parameters. -- Output: The Tanguy dispersion. Since the formula is rather long it is not written here. Please refer to the references for a full formula. References: * C. Tanguy, Phys. Rev. Lett. 75, 4090 (1995). Errata, Phys. Rev. Lett. 76, 716 (1996). * C. Tanguy, Phys. Rev. B. 60. 10660 (1990). """ single_params_template = { "A": 1, "d": 3, "gamma": 0.1, "R": 0.1, "Eg": 1, "a": 0, "b": 0, } rep_params_template = {} def dielectric_function(self, lbda: npt.ArrayLike) -> npt.NDArray: E = conversion_wavelength_energy(lbda) A = self.single_params.get("A") d = self.single_params.get("d") gam = self.single_params.get("gamma") R = self.single_params.get("R") Eg = self.single_params.get("Eg") a = self.single_params.get("a") b = self.single_params.get("b") return ( 1 + a / (b - E**2) + A * R ** (d / 2 - 1) / (E + 1j * gam) ** 2 * ( Tanguy.g(Tanguy.xsi(E + 1j * gam, R, Eg), d) + Tanguy.g(Tanguy.xsi(-E - 1j * gam, R, Eg), d) - 2 * Tanguy.g(Tanguy.xsi(E * 0, R, Eg), d) ) ) @staticmethod def xsi(z, R, Eg): return sqrt(R / (Eg - z)) @staticmethod def g(xsi, d): if d == 2: return 2 * np.log(xsi) - 2 * digamma(0.5 - xsi) if d == 3: return 2 * np.log(xsi) - 2 * digamma(1 - xsi) - 1 / xsi D = d - 1 return ( 2 * np.pi * gamma(D / 2 + xsi) / gamma(D / 2) ** 2 / gamma(1 - D / 2 + xsi) / xsi ** (d - 2) * (1 / np.tan(np.pi * (D / 2 - xsi)) - 1 / np.tan(np.pi * D)) )