Source code for wannierberri.calculators.static

#######################################
#                                     #
#         integration (Efermi-only)   #
#                                     #
#######################################


import numpy as np
from collections import defaultdict
from math import ceil
from copy import copy
from ..formula import covariant as frml
from ..formula import covariant_basic as frml_basic
from .. import __factors as factors
from ..result import EnergyResult, K__Result
from .calculator import Calculator
from ..__utility import alpha_A, beta_A


# The base class for Static Calculators
# particular calculators are below


[docs] class StaticCalculator(Calculator):
[docs] def __init__(self, Efermi, tetra=False, smoother=None, constant_factor=1., use_factor=True, kwargs_formula=None, Emin=-np.Inf, Emax=np.Inf, hole_like=False, k_resolved=False, Formula=None, fder=None, **kwargs): super().__init__(**kwargs) if kwargs_formula is None: kwargs_formula = {} self.Efermi = Efermi self.Emin = Emin self.Emax = Emax self.tetra = tetra self.kwargs_formula = copy(kwargs_formula) self.k_resolved = k_resolved self.smoother = smoother self.use_factor = use_factor self.hole_like = hole_like if Formula is not None: self.Formula = Formula if fder is not None: self.fder = fder assert hasattr( self, 'fder'), "fder not set - derivative of fermi distribution . 0: fermi-sea, 1: fermi-surface 2: f'' " assert hasattr(self, 'Formula'), "Formula not set - it should be class with a trace(ik,inn,out) method " self.constant_factor = constant_factor if self.hole_like and self.fder == 0: self.constant_factor *= -1 if not self.tetra: self.extraEf = 0 if self.fder == 0 else 1 if self.fder in (1, 2) else 2 if self.fder == 3 else None self.dEF = Efermi[1] - Efermi[0] if len(Efermi) > 1 else 0.001 self.EFmin = Efermi[0] - self.extraEf * self.dEF self.EFmax = Efermi[-1] + self.extraEf * self.dEF self.nEF_extra = Efermi.shape[0] + 2 * self.extraEf
[docs] def __call__(self, data_K): nk = data_K.nk NB = data_K.num_wann formula = self.Formula(data_K, **self.kwargs_formula) ndim = formula.ndim # when we do not need k-resolved, we assume as it is only one k-point,m and dump everything there if self.k_resolved: nk_result = nk def ik_to_result(_ik): return _ik else: nk_result = 1 def ik_to_result(_): return 0 # get a list [{(ib1,ib2):W} for ik in op:ed] if self.tetra: weights = data_K.tetraWeights.weights_all_band_groups( self.Efermi, der=-1 if self.hole_like else self.fder, degen_thresh=self.degen_thresh, degen_Kramers=self.degen_Kramers, Emin=self.Emin, Emax=self.Emax) # here W is array of shape Efermi else: weights = data_K.get_bands_in_range_groups( self.EFmin, self.EFmax, degen_thresh=self.degen_thresh, degen_Kramers=self.degen_Kramers, sea=(self.fder == 0), Emin=self.Emin, Emax=self.Emax ) # here W is energy # """formula - TraceFormula to evaluate # bands = a list of lists of k-points for every shape = (3,) * ndim values = [defaultdict(lambda: np.zeros(((3,) * ndim), dtype=float)) for _ in range(nk)] for ik, bnd in enumerate(weights): if formula.additive: for n in bnd: inn = np.arange(n[0], n[1]) out = np.concatenate((np.arange(0, n[0]), np.arange(n[1], NB))) values[ik][n] = formula.trace(ik, inn, out) else: nnall = set([_ for n in bnd for _ in n]) _values = {} for n in nnall: inn = np.arange(0, n) out = np.arange(n, NB) _values[n] = formula.trace(ik, inn, out) for n in bnd: values[ik][n] = _values[n[1]] - _values[n[0]] if self.tetra: # tetrahedron method restot = np.zeros((nk_result,) + self.Efermi.shape + shape) for ik, weights in enumerate(weights): valuesik = values[ik] for n, w in weights.items(): restot[ik_to_result(ik)] += np.einsum("e,...->e...", w, valuesik[n]) else: # no tetrahedron restot = np.zeros((nk_result, self.nEF_extra,) + shape) for ik, weights in enumerate(weights): valuesik = values[ik] for n, E in sorted(weights.items()): if E < self.EFmin: restot[ik_to_result(ik)] += valuesik[n][None] elif E <= self.EFmax: iEf = ceil((E - self.EFmin) / self.dEF) restot[ik_to_result(ik), iEf:] += valuesik[n] if self.fder == 0: pass elif self.fder == 1: restot = (restot[:, 2:] - restot[:, :-2]) / (2 * self.dEF) elif self.fder == 2: restot = (restot[:, 2:] + restot[:, :-2] - 2 * restot[:, 1:-1]) / (self.dEF ** 2) elif self.fder == 3: restot = (restot[:, 4:] - restot[:, :-4] - 2 * (restot[:, 3:-1] - restot[:, 1:-3])) / ( 2 * self.dEF ** 3) else: raise NotImplementedError(f"Derivatives d^{self.fder}f/dE^{self.fder} is not implemented") restot /= data_K.cell_volume if not self.k_resolved: restot /= data_K.nk if self.use_factor: restot *= self.constant_factor else: restot *= np.sign(self.constant_factor) if self.k_resolved: return K__Result([restot], transformTR=formula.transformTR, transformInv=formula.transformInv, rank=restot.ndim - 2, other_properties=dict( comment=self.comment, efermi=self.Efermi ) ) else: res = EnergyResult(self.Efermi, restot[0], transformTR=formula.transformTR, transformInv=formula.transformInv, smoothers=[self.smoother], comment=self.comment, save_mode=self.save_mode) return res
############################################### ############################################### ############################################### ############################################### #### ###### #### Implemented calculators ###### #### ###### ############################################### ############################################### ############################################### ############################################### # TODO: Ideally, a docstring of every calculator should contain the equation that it implements # and references (with urls) to the relevant papers #################### # basic quantities # #################### class _DOS(StaticCalculator): def __init__(self, fder, **kwargs): self.Formula = frml.Identity self.fder = fder super().__init__(**kwargs) def __call__(self, data_K): return super().__call__(data_K) * data_K.cell_volume
[docs] class DOS(_DOS): r"""Density of states""" def __init__(self, **kwargs): super().__init__(fder=1, **kwargs)
[docs] class CumDOS(_DOS): r"""Cumulative density of states""" def __init__(self, **kwargs): super().__init__(fder=0, **kwargs)
[docs] class Spin(StaticCalculator): r"""Spin per unit cell (dimensionless) | Output: :math:`\int [dk] s f`""" def __init__(self, **kwargs): self.Formula = frml.Spin self.fder = 0 super().__init__(**kwargs) def __call__(self, data_K): return super().__call__(data_K) * data_K.cell_volume
[docs] class Morb(StaticCalculator): r"""Orbital magnetic moment per unit cell (:math:`\mu_B`) | Eq(1) in `Ref <https://journals.aps.org/prb/abstract/10.1103/PhysRevB.85.014435>`__ | Output: :math:`M = -\int [dk] (H + G - 2E_f \cdot \Omega) f`""" def __init__(self, constant_factor=-factors.eV_au / factors.bohr ** 2, **kwargs): self.Formula = frml.Morb_Hpm self.fder = 0 super().__init__(constant_factor=constant_factor, **kwargs) self.AHC = AHC(constant_factor=constant_factor, print_comment=False, **kwargs) def __call__(self, data_K): Hplus_res = super().__call__(data_K) Omega_res = self.AHC(data_K).mul_array(self.Efermi, axes=0) Hplus_res.add(- 2 * Omega_res) return Hplus_res * data_K.cell_volume
[docs] class Morb_test(Morb): def __init__(self, constant_factor=-factors.eV_au / factors.bohr ** 2, **kwargs): self.Formula = frml_basic.tildeHGc self.fder = 0 self.comment = r"""Orbital magnetic moment per unit cell for testing (\mu_B) Output: :math: `M = -\int [dk] (H + G - 2E_f \cdot \Omega) f`""" StaticCalculator.__init__(self, constant_factor=constant_factor, **kwargs) self.AHC = AHC_test(constant_factor=constant_factor, print_comment=False, **kwargs)
#################### # conductivities # ####################
[docs] class GME_orb_FermiSurf(StaticCalculator): r"""Gyrotropic tensor orbital part (:math:`A`) | With Fermi surface integral. Eq(9) `Ref <https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.116.077201>`__ | Output: :math:`K^{orb}_{\alpha :\mu} = \int [dk] v_\alpha m^{orb}_\mu f'` | Where :math:`m^{orb} = H + G - 2E_f \cdot \Omega`""" def __init__(self, constant_factor=factors.factor_gme * factors.fac_orb_Z, **kwargs): self.Formula = frml.VelHplus self.fder = 1 super().__init__(constant_factor=constant_factor, **kwargs) self.BerryDipole = BerryDipole_FermiSurf(constant_factor=constant_factor, print_comment=False, **kwargs) def __call__(self, data_K): Hplus_res = super().__call__(data_K) Omega_res = self.BerryDipole(data_K).mul_array(self.Efermi) return Hplus_res - 2 * Omega_res
[docs] class GME_orb_FermiSea(StaticCalculator): r"""Gyrotropic tensor orbital part (:math:`A`) | With Fermi sea integral. Eq(30) in `Ref <https://www.nature.com/articles/s41524-021-00498-5>`__ | Output: :math:`K^{orb}_{\alpha :\mu} = -\int [dk] \partial_\alpha m_\mu f` | Where :math:`m = H + G - 2E_f \cdot \Omega`""" def __init__(self, constant_factor=factors.factor_gme * factors.fac_orb_Z, **kwargs): self.Formula = frml.DerMorb self.fder = 0 super().__init__(constant_factor=constant_factor, **kwargs) self.BerryDipole = BerryDipole_FermiSea(constant_factor=constant_factor, print_comment=False, **kwargs) def __call__(self, data_K): Hplus_res = super().__call__(data_K) Hplus_res.data = Hplus_res.data.swapaxes(1, 2) Omega_res = self.BerryDipole(data_K).mul_array(self.Efermi) return Hplus_res - 2 * Omega_res
[docs] class GME_orb_FermiSea_test(StaticCalculator): r"""Gyrotropic tensor orbital part for testing (:math:`A`) | With Fermi sea integral. | Output: :math:`K^{orb}_{\alpha :\mu} = -\int [dk] \partial_\alpha m_\mu f` | Where :math: `m = H + G - 2E_f \cdot \Omega` """ def __init__(self, constant_factor=factors.factor_gme * factors.fac_orb_Z, **kwargs): self.Formula = frml_basic.tildeHGc_d self.fder = 0 super().__init__(constant_factor=constant_factor, **kwargs) self.BerryDipole = BerryDipole_FermiSea_test(constant_factor=constant_factor, print_comment=False, **kwargs) def __call__(self, data_K): Hplus_res = super().__call__(data_K) Hplus_res.data = Hplus_res.data.swapaxes(1, 2) Omega_res = self.BerryDipole(data_K).mul_array(self.Efermi) return Hplus_res - 2 * Omega_res
[docs] class GME_spin_FermiSea(StaticCalculator): r"""Gyrotropic tensor spin part (:math:`A`) | With Fermi sea integral. Eq(30) in `Ref <https://www.nature.com/articles/s41524-021-00498-5>`__ | Output: :math:`K^{spin}_{\alpha :\mu} = -\int [dk] \partial_\alpha s_\mu f`""" def __init__(self, constant_factor=factors.factor_gme * factors.fac_spin_Z, **kwargs): self.Formula = frml.DerSpin self.fder = 0 super().__init__(constant_factor=constant_factor, **kwargs) def __call__(self, data_K): res = super().__call__(data_K) # swap axes to be consistent with the eq. (29) of DOI:10.1038/s41524-021-00498-5 res.data = res.data.swapaxes(1, 2) return res
[docs] class GME_spin_FermiSurf(StaticCalculator): r"""Gyrotropic tensor spin part (:math:`A`) | With Fermi surface integral. Eq(9) `Ref <https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.116.077201>`__ | Output: :math:`K^{spin}_{\alpha :\mu} = \tau \int [dk] v_\alpha s_\mu f'`""" def __init__(self, constant_factor=factors.factor_gme * factors.fac_spin_Z, **kwargs): self.Formula = frml.VelSpin self.fder = 1 super().__init__(constant_factor=constant_factor, **kwargs)
# E^1 B^0
[docs] class AHC(StaticCalculator): r"""Anomalous Hall conductivity (:math:`s^3 \cdot A^2 / (kg \cdot m^3) = S/m`) | With Fermi sea integral Eq(11) in `Ref <https://www.nature.com/articles/s41524-021-00498-5>`__ | Output: :math:`O = -e^2/\hbar \int [dk] \Omega f` | Instruction: :math:`j_\alpha = \sigma_{\alpha\beta} E_\beta = \epsilon_{\alpha\beta\delta} O_\delta E_\beta`""" def __init__(self, constant_factor=factors.factor_ahc, **kwargs): """describe input parameters here""" self.Formula = frml.Omega self.fder = 0 super().__init__(constant_factor=constant_factor, **kwargs)
[docs] class AHC_test(StaticCalculator): r"""Anomalous Hall conductivity for testing (:math:`s^3 \cdot A^2 / (kg \cdot m^3) = S/m`) | Output: :math:`O = - e^2/\hbar \int [dk] \Omega f` | Instruction: :math:`j_\alpha = \sigma_{\alpha\beta} E_\beta = \epsilon_{\alpha\beta\delta} O_\delta E_\beta`""" def __init__(self, constant_factor=factors.factor_ahc, **kwargs): self.Formula = frml_basic.tildeFc self.fder = 0 super().__init__(constant_factor=constant_factor, **kwargs)
[docs] class Ohmic_FermiSea(StaticCalculator): __doc__ = (r"""Ohmic conductivity (:math:`S/m`) | With Fermi sea integral. Eq(31) in `Ref <https://www.nature.com/articles/s41524-021-00498-5>`__ | Output: :math:`\sigma_{\alpha\beta} = e^2/\hbar \tau \int [dk] \partial_\beta v_\alpha f`""" fr"for \tau=1{factors.TAU_UNIT_TXT}" r"| Instruction: :math:`j_\alpha = \sigma_{\alpha\beta} E_\beta`") def __init__(self, constant_factor=factors.factor_ohmic, **kwargs): self.Formula = frml.InvMass self.fder = 0 super().__init__(constant_factor=constant_factor, **kwargs)
[docs] class Ohmic_FermiSurf(StaticCalculator): r"""Ohmic conductivity (:math:`S/m`) | With Fermi surface integral. | Output: :math:`\sigma_{\alpha\beta} = -e^2/\hbar \tau \int [dk] v_\alpha v_\beta f'` | Instruction: :math:`j_\alpha = \sigma_{\alpha\beta} E_\beta`""" def __init__(self, constant_factor=factors.factor_ohmic, **kwargs): self.Formula = frml.VelVel self.fder = 1 super().__init__(constant_factor=constant_factor, **kwargs)
# E^1 B^1
[docs] class Hall_classic_FermiSurf(StaticCalculator): r"""Classic Hall conductivity (:math:`S/m/T`) | With Fermi surface integral. | Output: :math:`\sigma_{\alpha\beta :\mu} = e^3/\hbar^2 \tau^2 \epsilon_{\gamma\mu\rho} \int [dk] v_\alpha \partial_\rho v_\beta v_\gamma f'` | Instruction: :math:`j_\alpha = \sigma_{\alpha\beta :\mu} E_\beta B_\mu`""" def __init__(self, constant_factor=factors.factor_hall_classic, **kwargs): self.Formula = frml.VelMassVel self.fder = 1 super().__init__(constant_factor=constant_factor, **kwargs) def __call__(self, data_K): res = super().__call__(data_K) res.data = res.data[:, :, :, beta_A, alpha_A] - res.data[:, :, :, alpha_A, beta_A] res.data = 0.5 * (res.data[:, alpha_A, beta_A, :] - res.data[:, beta_A, alpha_A, :]) res.rank -= 2 return res
[docs] class Hall_classic_FermiSea(StaticCalculator): r"""Classic Hall conductivity (:math:`S/m/T`) | With Fermi sea integral. | Output: :math:`\sigma_{\alpha\beta :\mu} = -e^3/\hbar^2 \tau^2 \epsilon_{\gamma\mu\rho} \int [dk] \partial_\gamma v_\alpha \partial_\rho v_\beta f` | Instruction: :math:`j_\alpha = \sigma_{\alpha\beta :\mu} E_\beta B_\mu`""" def __init__(self, constant_factor=factors.factor_hall_classic, **kwargs): self.Formula = frml.MassMass self.fder = 0 super().__init__(constant_factor=constant_factor, **kwargs) def __call__(self, data_K): res = super().__call__(data_K) res.data = res.data.transpose(0, 4, 1, 2, 3) res.data = res.data[:, :, :, beta_A, alpha_A] - res.data[:, :, :, alpha_A, beta_A] res.data = 0.5 * (res.data[:, alpha_A, beta_A, :] - res.data[:, beta_A, alpha_A, :]) res.rank -= 2 return res
# E^2 B^0
[docs] class BerryDipole_FermiSurf(StaticCalculator): r"""Berry curvature dipole (dimensionless) | With Fermi surface integral. Eq(8) in `Ref <https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.115.216806>`__ | Output: :math:`D_{\beta\delta} = -\int [dk] v_\beta \Omega_\delta f'`""" def __init__(self, **kwargs): self.Formula = frml.VelOmega self.fder = 1 super().__init__(**kwargs)
[docs] class NLAHC_FermiSurf(BerryDipole_FermiSurf): r"""Nonlinear anomalous Hall conductivity (:math:`S^2/A`) | With Fermi surface integral. Eq(8) in `Ref <https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.115.216806>`__ | Output: :math:`D_{\beta\delta} = -e^3/\hbar^2 \tau \int [dk] v_\beta \Omega_\delta f'` | Instruction: :math:`j_\alpha = \epsilon_{\alpha\delta\gamma} D_{\beta\delta} E_\beta E\gamma`""" def __init__(self, constant_factor=factors.factor_nlahc, **kwargs): super().__init__(constant_factor=constant_factor, **kwargs)
[docs] class BerryDipole_FermiSea(StaticCalculator): r"""Berry curvature dipole (dimensionless) | With Fermi sea integral. Eq(29) in `Ref <https://www.nature.com/articles/s41524-021-00498-5>`__ | Output: :math:`D_{\beta\delta} = \int [dk] \partial_\beta \Omega_\delta f`""" def __init__(self, **kwargs): self.Formula = frml.DerOmega self.fder = 0 super().__init__(**kwargs) def __call__(self, data_K): res = super().__call__(data_K) # swap axes to be consistent with the eq. (29) of DOI:10.1038/s41524-021-00498-5 res.data = res.data.swapaxes(1, 2) return res
[docs] class NLAHC_FermiSea(BerryDipole_FermiSea): r"""Nonlinear anomalous Hall conductivity (:math:`S^2/A`) | With Fermi sea integral. Eq(29) in `Ref <https://www.nature.com/articles/s41524-021-00498-5>`__ | Output: :math:`D_{\beta\delta} = e^3/\hbar^2 \tau \int [dk] \partial_\beta \Omega_\delta f` | Instruction: :math:`j_\alpha = \epsilon_{\alpha\delta\gamma} D_{\beta\delta} E_\beta E\gamma`""" def __init__(self, constant_factor=factors.factor_nlahc, **kwargs): super().__init__(constant_factor=constant_factor, **kwargs)
[docs] class BerryDipole_FermiSea_test(StaticCalculator): r"""Berry curvature dipole for testing (dimensionless) | With Fermi sea integral. | Output: :math:`D_{\beta\delta} = \tau \int [dk] \partial_beta \Omega_\delta f`""" def __init__(self, **kwargs): self.Formula = frml_basic.tildeFc_d self.fder = 0 super().__init__(**kwargs) def __call__(self, data_K): res = super().__call__(data_K) # swap axes to be consistent with the eq. (29) of DOI:10.1038/s41524-021-00498-5 res.data = res.data.swapaxes(1, 2) return res
[docs] class NLDrude_FermiSea(StaticCalculator): r"""Drude conductivity (:math:`S^2/A`) | With Fermi sea integral. Eq(3) in `Ref <https://journals.aps.org/prresearch/abstract/10.1103/PhysRevResearch.2.043081>`__ | Output: :math:`\sigma_{\alpha\beta\gamma} = -e^3/\hbar^2 \tau^2 \int [dk] \partial_{\beta\gamma} v_\alpha f` | Instruction: :math:`j_\alpha = \sigma_{\alpha\beta\gamma} E_\beta E\gamma`""" def __init__(self, constant_factor=factors.factor_nldrude, **kwargs): self.Formula = frml.Der3E self.fder = 0 super().__init__(constant_factor=constant_factor, **kwargs)
[docs] class NLDrude_FermiSurf(StaticCalculator): r"""Drude conductivity (:math:`S^2/A`) | With Fermi surface integral. | Output: :math:`\sigma_{\alpha\beta\gamma} = e^3/\hbar^2 \tau^2 \int [dk] \partial_\beta v_\alpha v_\gamma f'` | Instruction: :math:`j_\alpha = \sigma_{\alpha\beta\gamma} E_\beta E\gamma`""" def __init__(self, constant_factor=factors.factor_nldrude, **kwargs): self.Formula = frml.MassVel self.fder = 1 super().__init__(constant_factor=constant_factor, **kwargs)
[docs] class NLDrude_Fermider2(StaticCalculator): r"""Drude conductivity (:math:`S^2/A`) | With second derivative of distribution function. Eq(A28) in `Ref <https://journals.aps.org/prresearch/abstract/10.1103/PhysRevResearch.2.043081>`__ | Output: :math:`\sigma_{\alpha\beta\gamma} = -e^3/\hbar^2 \tau^2 \int [dk] v_\beta v_\alpha v_\gamma f'` | Instruction: :math:`j_\alpha = \sigma_{\alpha\beta\gamma} E_\beta E\gamma`""" def __init__(self, constant_factor=factors.factor_nldrude / 2, **kwargs): self.Formula = frml.VelVelVel self.fder = 2 super().__init__(constant_factor=constant_factor, **kwargs)
# E^2 B^1
[docs] class eMChA_FermiSurf(StaticCalculator): def __init__(self, constant_factor=factors.factor_emcha, **kwargs): self.Formula = frml.emcha_surf self.fder = 1 super().__init__(constant_factor=constant_factor, **kwargs)
[docs] class NLDrude_Zeeman_spin(StaticCalculator): def __init__(self, constant_factor=factors.fac_spin_Z * factors.factor_nldrude, **kwargs): self.Formula = frml.NLDrude_Z_spin self.fder = 1 super().__init__(constant_factor=constant_factor, **kwargs)
[docs] class NLDrude_Zeeman_orb_Omega(StaticCalculator): def __init__(self, **kwargs): self.Formula = frml.NLDrude_Z_orb_Omega self.fder = 1 super().__init__(**kwargs)
[docs] class NLDrude_Zeeman_orb(StaticCalculator): def __init__(self, **kwargs): self.Formula = frml.NLDrude_Z_orb_Hplus self.fder = 1 super().__init__(**kwargs) def __call__(self, data_K): Hplus = super().__call__(data_K) Omega = NLDrude_Zeeman_orb_Omega(Efermi=self.Efermi, tetra=self.tetra, smoother=self.smoother, use_factor=False, print_comment=False, kwargs_formula=self.kwargs_formula)(data_K).mul_array(self.Efermi) final_factor = factors.fac_orb_Z * factors.factor_nldrude if not self.use_factor: final_factor = np.sign(final_factor) return final_factor * (Hplus - 2 * Omega)
# E^1 B^1
[docs] class AHC_Zeeman_spin(StaticCalculator): r"""AHC conductivity Zeeman correction term spin part (:math:`S/m/T`) | With Fermi surface integral. | Output: :math:`ZAHC^{spin}_{\alpha\beta :\mu} = e^2/\hbar \int [dk] \Omega_\delta * s_\mu f'` | Instruction: :math:`j_\alpha = \sigma_{\alpha\beta :\mu} E_\beta B_\mu = \epsilon_{\alpha\beta\delta} ZAHC^{spin}_{\alpha\beta:\mu} E_\beta B_\mu` """ def __init__(self, constant_factor=factors.fac_spin_Z * factors.factor_ahc, **kwargs): self.Formula = frml.OmegaS self.fder = 1 super().__init__(constant_factor=constant_factor, **kwargs)
[docs] class OmegaOmega(StaticCalculator): def __init__(self, **kwargs): self.Formula = frml.OmegaOmega self.fder = 1 super().__init__(**kwargs)
[docs] class AHC_Zeeman_orb(StaticCalculator): r"""AHC conductivity Zeeman correction term orbital part (:math:`S/m/T`) | With Fermi surface integral. | Output: :math:`ZAHC^{orb}_{\alpha\beta :\mu} = e^2/\hbar \int [dk] \Omega_\delta * m_\mu f'` | Where :math:`m = H + G - 2Ef*\Omega` | Instruction: :math:`j_\alpha = \sigma_{\alpha\beta :\mu} E_\beta B_\mu = e \epsilon_{\alpha\beta\delta} ZAHC^{orb}_{\alpha\beta:\mu} E_\beta B_\mu`""" def __init__(self, constant_factor=factors.fac_orb_Z * factors.factor_ahc, **kwargs): self.Formula = frml.OmegaHplus self.fder = 1 super().__init__(constant_factor=constant_factor, **kwargs) self.OmegaOmega = OmegaOmega(constant_factor=constant_factor, print_comment=False, **kwargs) def __call__(self, data_K): Hplus_res = super().__call__(data_K) Omega_res = self.OmegaOmega(data_K).mul_array(self.Efermi) return Hplus_res - 2 * Omega_res
# others
[docs] class SHC(StaticCalculator): r"""Spin Hall conductivity with dc (:math:`S/m`) | With Fermi sea integral. Eq(1) in `Ref <https://journals.aps.org/prb/abstract/10.1103/PhysRevB.99.235113>`_ | Qiao type : with kwargs_formula={'spin_current_type':'qiao'}. Eq(49,50) in `Ref <https://journals.aps.org/prb/abstract/10.1103/PhysRevB.98.214402>`__ | Ryoo type : with kwargs_formula={'spin_current_type':'ryoo'}. Eq(17,26-29) in `Ref <https://journals.aps.org/prb/abstract/10.1103/PhysRevB.99.235113>`__ | Output: :math:`\sigma_{\alpha\beta} = -e^2/\hbar \int [dk] Im(j_{nm,\alpha} v_{mn,\beta})/(\epsilon_n - \epsilon_m)^2 f` | Instruction: :math:`j_\alpha = \sigma_{\alpha\beta} E_\beta`""" def __init__(self, constant_factor=-factors.factor_ahc / 2, **kwargs): self.Formula = frml.SpinOmega self.fder = 0 super().__init__(constant_factor=constant_factor, **kwargs)