# #
# This file is distributed as part of the WannierBerri code #
# under the terms of the GNU General Public License. See the #
# file 'LICENSE' in the root directory of the WannierBerri #
# distribution, or http://www.gnu.org/copyleft/gpl.txt #
# #
# The WannierBerri code is hosted on GitHub: #
# https://github.com/stepan-tsirkin/wannier-berri #
# written by #
# Stepan Tsirkin, University of Zurich #
# #
# ------------------------------------------------------------
import numpy as np
from termcolor import cprint
from ..fourier.rvectors import Rvectors
from .system_R import System_R
# from .Rvec import Rvec
class System_tb_py(System_R):
"""This interface initializes the System class from a tight-binding
model packed by one of the available python modules (see below)
Parameters
----------
tbmodel :
name of the tight-binding model object.
module : str
name of the module 'pythtb' or 'tbmodels'
spin : bool
generate SS_R matrix (if PythTB model has spin)
Notes
-----
always uses use_wcc_phase=True, force_internal_terms_only=True
see also parameters of the :class:`~wannierberri.System`
"""
def __init__(self, model, module,
spin=False,
**parameters
):
names = {'tbmodels': 'TBmodels', 'pythtb': 'PythTB'}
super().__init__(spin=spin,
force_internal_terms_only=True,
name=f'model_{names[module]}',
**parameters)
if module == 'tbmodels':
# Extract the parameters from the model
real = model.uc
self.num_wann = model.size
if self.need_R_any(['SS', 'SHA', 'SA', 'SH', 'SRA', 'SR']):
raise ValueError(
f"System_{names[module]} class cannot be used for evaluation of spin properties")
self.spinors = False
positions = model.pos
iRvec = np.array([R[0] for R in model.hop.items()], dtype=int)
elif module == 'pythtb':
real = model._lat
positions = model._orb
if model._nspin == 1:
self.spinors = False
self.num_wann = model._norb
elif model._nspin == 2:
self.spinors = True
self.num_wann = model._norb * 2
positions = np.array(sum(([p, p] for p in positions), []))
else:
raise Exception("\n\nWrong value of nspin!")
print("number of wannier functions:", self.num_wann)
iRvec = np.array([R[-1] for R in model._hoppings], dtype=int)
else:
raise ValueError(f"unknown tight-binding module {module}")
self.dimr = real.shape[1]
self.norb = positions.shape[0]
wannier_centers_red = np.zeros((self.norb, 3))
wannier_centers_red[:, :self.dimr] = positions
self.real_lattice = np.eye(3, dtype=float)
self.real_lattice[:self.dimr, :self.dimr] = np.array(real)
self.wannier_centers_cart = wannier_centers_red.dot(self.real_lattice)
self.periodic[self.dimr:] = False
iRvec = [tuple(row) for row in iRvec]
iRvec = np.unique(iRvec, axis=0).astype('int32')
nR = iRvec.shape[0]
for i in range(3 - self.dimr):
column = np.zeros(nR, dtype='int32')
iRvec = np.column_stack((iRvec, column))
iRvec_neg = np.array([-r for r in iRvec])
iRvec = np.concatenate((iRvec, iRvec_neg), axis=0)
iRvec = np.unique(iRvec, axis=0)
# Find the R=[000] index (used later)
index0 = np.argwhere(np.all(([0, 0, 0] - iRvec) == 0, axis=1))
# make sure it exists; otherwise, add it manually
# add it manually
if index0.size == 0:
iRvec = np.column_stack((np.array([0, 0, 0]), iRvec.T)).T
index0 = 0
elif index0.size == 1:
print(f"R=0 found at position(s) {index0}")
index0 = index0[0][0]
else:
raise RuntimeError(f"wrong value of index0={index0}, with R_all={iRvec}")
self.rvec = Rvectors(lattice=self.real_lattice,
iRvec=iRvec,
shifts_left_red=wannier_centers_red,
dim=self.dimr)
# Define Ham_R matrix from hoppings
nRvec = self.rvec.nRvec
Ham_R = np.zeros((nRvec, self.num_wann, self.num_wann), dtype=complex)
iRvec = self.rvec.iRvec
if module == 'tbmodels':
for hop in model.hop.items():
R = np.array(hop[0], dtype=int)
hops = np.array(hop[1]).reshape((self.num_wann, self.num_wann))
iR = int(np.argwhere(np.all((R - iRvec[:, :self.dimr]) == 0, axis=1)))
inR = int(np.argwhere(np.all((-R - iRvec[:, :self.dimr]) == 0, axis=1)))
Ham_R[iR] += hops
Ham_R[inR] += np.conjugate(hops.T)
elif module == 'pythtb':
for nhop in model._hoppings:
i = nhop[1]
j = nhop[2]
iR = np.argwhere(np.all((nhop[-1] - self.rvec.iRvec[:, :self.dimr]) == 0, axis=1))[0][0]
inR = np.argwhere(np.all((-nhop[-1] - self.rvec.iRvec[:, :self.dimr]) == 0, axis=1))[0][0]
if model._nspin == 1:
Ham_R[iR, i, j] += nhop[0]
Ham_R[inR, j, i] += np.conjugate(nhop[0])
elif model._nspin == 2:
print("hopping :", nhop[0].shape, Ham_R.shape, iR,
Ham_R[iR, 2 * i:2 * i + 2, 2 * j:2 * j + 2].shape)
Ham_R[iR, 2 * i:2 * i + 2, 2 * j:2 * j + 2] += nhop[0]
Ham_R[inR, 2 * j:2 * j + 2, 2 * i:2 * i + 2] += np.conjugate(nhop[0].T)
# Set the onsite energies at H(R=[000])
for i in range(model._norb):
if model._nspin == 1:
Ham_R[index0, i, i] = model._site_energies[i]
elif model._nspin == 2:
Ham_R[index0, 2 * i:2 * i + 2, 2 * i:2 * i + 2] = model._site_energies[i]
if model._nspin == 2 and spin:
self.set_spin_pairs([(i, i + 1) for i in range(0, self.num_wann, 2)])
self.set_R_mat('Ham', Ham_R)
print(f"shape of Ham_R = {Ham_R.shape}")
self.do_at_end_of_init()
cprint(f"Reading the system from {names[module]} finished successfully", 'green', attrs=['bold'])
[docs]
class System_TBmodels(System_tb_py):
"""This interface initializes the System class from a tight-binding
model created with `TBmodels. <http://z2pack.ethz.ch/tbmodels/doc/1.3/index.html>`_
It defines the Hamiltonian matrix Ham_R (from hoppings matrix elements)
and the AA_R matrix (from orbital coordinates) used to calculate Berry
related quantities.
Parameters
----------
tbmodel :
name of the TBmodels tight-binding model object.
Notes
-----
see also parameters of the :class:`~wannierberri.System_tb_py`
"""
def __init__(self, tbmodel, **parameters):
super().__init__(tbmodel, module='tbmodels', **parameters)
[docs]
class System_PythTB(System_tb_py):
"""This interface is a way to initialize the System class from a tight-binding
model created with `PythTB. <http://www.physics.rutgers.edu/pythtb/>`_
It defines the Hamiltonian matrix Ham_R (from hoppings matrix elements)
and the AA_R matrix (from orbital coordinates) used to calculate
Berry related quantities.
Parameters
----------
ptb_model : class
name of the PythTB tight-binding model class.
Notes
-----
see also parameters of the :class:`~wannierberri.System_tb_py`
"""
def __init__(self, ptb_model, **parameters):
super().__init__(ptb_model, module='pythtb', **parameters)