r"""2D honeycomb lattice.
The honeycomb lattice can be decomposed into `~gftool.lattice.triangular`
sublattices.
:half_bandwidth: The half-bandwidth `D` corresponds to a nearest neighbor hopping
of `t=2D/3`.
"""
from mpmath import mp
from gftool.lattice import triangular
[docs]def gf_z(z, half_bandwidth):
r"""Local Green's function of the 2D honeycomb lattice.
The Green's function of the 2D honeycomb lattice can be expressed in terms
of the 2D triangular lattice `gftool.lattice.triangular.gf_z`,
see [horiguchi1972]_.
The Green's function has singularities at `z=±half_bandwidth/3`.
Parameters
----------
z : complex np.ndarray or complex
Green's function is evaluated at complex frequency `z`.
half_bandwidth : float
Half-bandwidth of the DOS of the honeycomb lattice.
The `half_bandwidth` corresponds to the nearest neighbor hopping
:math:`t=2D/3`.
Returns
-------
gf_z : complex np.ndarray or complex
Value of the honeycomb lattice Green's function
See Also
--------
gftool.lattice.triangular.gf_z
References
----------
.. [horiguchi1972] Horiguchi, T., 1972. Lattice Green’s Functions for the
Triangular and Honeycomb Lattices. Journal of Mathematical Physics 13,
1411–1419. https://doi.org/10.1063/1.1666155
Examples
--------
>>> ww = np.linspace(-1.5, 1.5, num=501, dtype=complex) + 1e-64j
>>> gf_ww = gt.lattice.honeycomb.gf_z(ww, half_bandwidth=1)
>>> import matplotlib.pyplot as plt
>>> _ = plt.axhline(0, color='black', linewidth=0.8)
>>> _ = plt.plot(ww.real, gf_ww.real, label=r"$\Re G$")
>>> _ = plt.plot(ww.real, gf_ww.imag, '--', label=r"$\Im G$")
>>> _ = plt.ylabel(r"$G*D$")
>>> _ = plt.xlabel(r"$\omega/D$")
>>> _ = plt.xlim(left=ww.real.min(), right=ww.real.max())
>>> _ = plt.legend()
>>> plt.show()
"""
D = half_bandwidth / 1.5
z_rel = z / D
return 2 / D * z_rel * triangular.gf_z(2*z_rel**2 - 1.5, half_bandwidth=9/4)
[docs]def dos(eps, half_bandwidth):
r"""DOS of non-interacting 2D honeycomb lattice.
The DOS diverges at `eps=±half_bandwidth/3`.
The Green's function and therefore the DOS of the 2D honeycomb lattice can
be expressed in terms of the 2D triangular lattice
`gftool.lattice.triangular.dos`, see [horiguchi1972]_.
Parameters
----------
eps : float np.ndarray or float
DOS is evaluated at points `eps`.
half_bandwidth : float
Half-bandwidth of the DOS, DOS(| `eps` | > `half_bandwidth`) = 0.
The `half_bandwidth` corresponds to the nearest neighbor hopping
:math:`t=2D/3`.
Returns
-------
dos : float np.ndarray or float
The value of the DOS.
See Also
--------
gftool.lattice.honeycomb.dos_mp : multi-precision version suitable for integration
gftool.lattice.triangular.dos
References
----------
.. [horiguchi1972] Horiguchi, T., 1972. Lattice Green’s Functions for the
Triangular and Honeycomb Lattices. Journal of Mathematical Physics 13,
1411–1419. https://doi.org/10.1063/1.1666155
Examples
--------
>>> eps = np.linspace(-1.5, 1.5, num=501)
>>> dos = gt.lattice.honeycomb.dos(eps, half_bandwidth=1)
>>> import matplotlib.pyplot as plt
>>> for pos in (-1/3, 0, +1/3):
... _ = plt.axvline(pos, color='black', linewidth=0.8)
>>> _ = plt.plot(eps, dos)
>>> _ = plt.xlabel(r"$\epsilon/D$")
>>> _ = plt.ylabel(r"DOS * $D$")
>>> _ = plt.ylim(bottom=0)
>>> _ = plt.xlim(left=eps.min(), right=eps.max())
>>> plt.show()
"""
D = half_bandwidth / 1.5
eps_rel = eps / D
return 2 / D * abs(eps_rel) * triangular.dos(2*eps_rel**2 - 1.5, half_bandwidth=9/4)
# ∫dϵ ϵ^m DOS(ϵ) for half-bandwidth D=1
# from: integral of dos_mp with mp.workdps(100)
# for m in range(0, 22, 2):
# with mp.workdps(100):
# print(mp.quad(lambda eps: 2 * eps**m * dos_mp(eps), [0, 1/3, 1])
# rational numbers obtained by mp.identify
dos_moment_coefficients = {
2: 1/3,
4: 5/27,
6: 31/243,
8: 71/729,
10: 0.0787989635726261,
12: 0.0661766781260761,
14: 0.0570430207680627,
16: 0.0501259782365305,
18: 0.0447055266609815,
20: 0.0403432070418971,
}
[docs]def dos_moment(m, half_bandwidth):
"""Calculate the `m` th moment of the honeycomb DOS.
The moments are defined as :math:`∫dϵ ϵ^m DOS(ϵ)`.
Parameters
----------
m : int
The order of the moment.
half_bandwidth : float
Half-bandwidth of the DOS of the 2D honeycomb lattice.
Returns
-------
dos_moment : float
The `m` th moment of the 2D honeycomb DOS.
Raises
------
NotImplementedError
Currently only implemented for a few specific moments `m`.
See Also
--------
gftool.lattice.honeycomb.dos
"""
if m % 2: # odd moments vanish due to symmetry
return 0
try:
return dos_moment_coefficients[m] * half_bandwidth**m
except KeyError as keyerr:
raise NotImplementedError('Calculation of arbitrary moments not implemented.') from keyerr
[docs]def dos_mp(eps, half_bandwidth=1):
r"""Multi-precision DOS of non-interacting 2D honeycomb lattice.
The DOS diverges at `eps=±half_bandwidth/3`.
This function is particularity suited to calculate integrals of the form
:math:`∫dϵ DOS(ϵ)f(ϵ)`. If you have problems with the convergence,
consider removing singularities, e.g. split the integral
.. math::
∫^0 dϵ DOS(ϵ)[f(ϵ) - f(-D/3)] + ∫_0 dϵ DOS(ϵ)[f(ϵ) - f(+D/3)] + [f(-D/3) + f(+D/3)]/2
where :math:`D` is the `half_bandwidth`, or symmetrize the integral.
The Green's function and therefore the DOS of the 2D honeycomb lattice can
be expressed in terms of the 2D triangular lattice
`gftool.lattice.triangular.dos_mp`, see [horiguchi1972]_.
Parameters
----------
eps : mpmath.mpf or mpf_like
DOS is evaluated at points `eps`.
half_bandwidth : mpmath.mpf or mpf_like
Half-bandwidth of the DOS, DOS(| `eps` | > `half_bandwidth`) = 0.
The `half_bandwidth` corresponds to the nearest neighbor hopping
:math:`t=2D/3`.
Returns
-------
dos_mp : mpmath.mpf
The value of the DOS.
See Also
--------
gftool.lattice.honeycomb.dos : vectorized version suitable for array evaluations
gftool.lattice.triangular.dos_mp
References
----------
.. [horiguchi1972] Horiguchi, T., 1972. Lattice Green’s Functions for the
Triangular and Honeycomb Lattices. Journal of Mathematical Physics 13,
1411–1419. https://doi.org/10.1063/1.1666155
Examples
--------
Calculated integrals
>>> from mpmath import mp
>>> mp.quad(gt.lattice.honeycomb.dos_mp, [-1, -1/3, 0, +1/3, +1])
mpf('1.0')
>>> eps = np.linspace(-1.5, 1.5, num=501)
>>> dos_mp = [gt.lattice.honeycomb.dos_mp(ee, half_bandwidth=1) for ee in eps]
>>> import matplotlib.pyplot as plt
>>> for pos in (-1/3, 0, +1/3):
... _ = plt.axvline(pos, color='black', linewidth=0.8)
>>> _ = plt.plot(eps, dos_mp)
>>> _ = plt.xlabel(r"$\epsilon/D$")
>>> _ = plt.ylabel(r"DOS * $D$")
>>> _ = plt.ylim(bottom=0)
>>> _ = plt.xlim(left=eps.min(), right=eps.max())
>>> plt.show()
"""
D_inv = mp.mpf('1.5') / mp.mpf(half_bandwidth)
eps_rel = mp.mpf(eps) * D_inv
t_dos = triangular.dos_mp(2*eps_rel**2 - mp.mpf('1.5'), half_bandwidth=mp.mpf('9/4'))
return 2 * D_inv * mp.fabs(eps_rel) * t_dos