Source code for sisl.physics.distribution

"""Distribution functions
=========================

.. module:: sisl.physics.distribution
   :noindex:

Various distributions using different smearing techniques.

.. autosummary::
   :toctree:

   get_distribution
   gaussian
   lorentzian
   fermi_dirac
   bose_einstein
   cold


.. autofunction:: gaussian
   :noindex:
.. autofunction:: lorentzian
   :noindex:
.. autofunction:: fermi_dirac
   :noindex:
.. autofunction:: bose_einstein
   :noindex:
.. autofunction:: cold
   :noindex:

"""
from __future__ import print_function, division

from functools import partial

import numpy as np
from scipy.special import erf
_pi = np.pi
_sqrt_2pi = (2 * _pi) ** 0.5

__all__ = ['get_distribution', 'gaussian', 'lorentzian']
__all__ += ['fermi_dirac', 'bose_einstein', 'cold']


[docs]def get_distribution(method, smearing=0.1, x0=0.): r""" Create a distribution function, Gaussian, Lorentzian etc. See the details regarding the distributions in their respective documentation. Parameters ---------- method: {'gaussian', 'lorentzian'} distribution function smearing: float, optional smearing parameter for the method (:math:`\sigma` for Gaussian, :math:`\gamma` for Lorenztian etc.) x0: float, optional maximum of the distribution function Returns ------- callable a function which accepts one argument """ m = method.lower() if m in ['gauss', 'gaussian']: return partial(gaussian, sigma=smearing, x0=x0) elif m in ['lorentz', 'lorentzian']: return partial(lorentzian, gamma=smearing, x0=x0) elif m in ['fd', 'fermi_dirac']: return partial(fermi_dirac, kT=smearing, mu=x0) elif m in ['bose_einstein']: return partial(bose_einstein, kT=smearing, mu=x0) elif m in ['cold']: return partial(cold, kT=smearing, mu=x0) raise ValueError("get_distribution does not implement the {} distribution function, have you mispelled?".format(method))
[docs]def gaussian(x, sigma=0.1, x0=0.): r""" Gaussian distribution function .. math:: G(x,\sigma,x_0) = \frac{1}{\sqrt{2\pi\sigma^2}}\exp\Big[\frac{- (x - x_0)^2}{2\sigma^2}\Big] Parameters ---------- x: array_like points at which the Gaussian distribution is calculated sigma: float, optional spread of the Gaussian x0: float, optional maximum position of the Gaussian Returns ------- numpy.ndarray the Gaussian distribution, same length as `x` """ return np.exp(-(x - x0) ** 2 / (2 * sigma ** 2)) / (_sqrt_2pi * sigma)
[docs]def lorentzian(x, gamma=0.1, x0=0.): r""" Lorentzian distribution function .. math:: L(x,\gamma,x_0) = \frac{1}{\pi}\frac{\gamma}{(x-x_0)^2 + \gamma^2} Parameters ---------- x: array_like points at which the Lorentzian distribution is calculated gamma: float, optional spread of the Lorentzian x0: float, optional maximum position of the Lorentzian Returns ------- numpy.ndarray the Lorentzian distribution, same length as `x` """ return (gamma / _pi) / ((x - x0) ** 2 + gamma ** 2)
[docs]def fermi_dirac(E, kT=0.1, mu=0.): r""" Fermi-Dirac distribution function .. math:: n_F(E,k_BT,\mu) = \frac{1}{\exp\Big[\frac{E - \mu}{k_BT}\Big] + 1} Parameters ---------- E: array_like energy evaluation points kT: float, optional temperature broadening mu: float, optional chemical potential Returns ------- numpy.ndarray the Fermi-Dirac distribution, same length as `E` """ return 1. / (np.exp((E - mu) / kT) + 1.)
[docs]def bose_einstein(E, kT=0.1, mu=0.): r""" Bose-Einstein distribution function .. math:: n_B(E,k_BT,\mu) = \frac{1}{\exp\Big[\frac{E - \mu}{k_BT}\Big] - 1} Parameters ---------- E: array_like energy evaluation points kT: float, optional temperature broadening mu: float, optional chemical potential Returns ------- numpy.ndarray the Bose-Einstein distribution, same length as `E` """ return 1. / (np.exp((E - mu) / kT) - 1.)
[docs]def cold(E, kT=0.1, mu=0.): r""" Cold smearing function, Marzari-Vanderbilt, PRL 82, 16, 1999 .. math:: C(E,k_BT,\mu) = \frac12 + \mathrm{erf}\Big(-\frac{E-\mu}{k_BT}-\frac1{\sqrt2}\Big) + \frac1{\sqrt{2\pi}} \exp\Bigg\{-\Big[\frac{E-\mu}{k_BT}+\frac1{\sqrt2}\Big]^2\Bigg\} Parameters ---------- E: array_like energy evaluation points kT: float, optional temperature broadening mu: float, optional chemical potential Returns ------- numpy.ndarray the Cold smearing distribution function, same length as `E` """ x = - (E - mu) / kT - 1 / 2 ** 0.5 return 0.5 + 0.5 * erf(x) + 1 / _sqrt_2pi * np.exp(-x**2)