Source code for wannierberri.system.system_fplo

#                                                            #
# 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 ..fourier.rvectors import Rvectors

from ..utility import str2bool
from termcolor import cprint
from .system_R import System_R
from collections import defaultdict
from scipy.constants import physical_constants, angstrom

bohr = physical_constants['Bohr radius'][0] / angstrom


[docs] class System_fplo(System_R): """ System initialized from the `+hamdata` file written by `FPLO <https://www.fplo.de/>`__ code, Parameters ---------- hamdata : str name (and path) of the "+hamdata" file to be read mp_grid : [nk1,nk2,nk3] size of Monkhorst-Pack frid used in ab initio calculation. Needed for MDRS Notes ----- see also parameters of the :class:`~wannierberri.System` """ def __init__(self, hamdata="+hamdata", mp_grid=None, **parameters): if "name" not in parameters: parameters["name"] = "ASE" super().__init__(force_internal_terms_only=True, **parameters) self.seedname = hamdata.split("/")[-1].split("_")[0] f = open(hamdata, "r") allread = False while not allread: line = next(f) if line.startswith("end spin:"): break elif line.startswith("lattice_vectors:"): real_lattice_bohr = np.array([next(f).split() for _ in range(3)], dtype=float) inv_real_lattice = np.linalg.inv(real_lattice_bohr) elif line.startswith("nwan:"): self.num_wann = int(next(f)) elif line.startswith("nspin:"): nspin = int(next(f)) assert nspin == 1, "spin-polarized calculations arte not supported yeet" elif line.startswith("have_spin_info:"): have_spin = str2bool(next(f)) if (not have_spin) and self.need_R_any(['SS', 'SHA', 'SR', 'SH', 'SHR', 'SA']): raise ValueError("spin info required, but not contained in the file") elif line.startswith("wancenters:"): self.wannier_centers_cart = np.array([next(f).split() for _ in range(self.num_wann)], dtype=float) elif line.startswith("spin:"): ispin = int(next(f)) assert ispin == 1, f"spin = 1 expected, got {ispin}" Ham_R = defaultdict(lambda: np.zeros((self.num_wann, self.num_wann), dtype=complex)) if self.need_R_any('SS'): SS_R = defaultdict(lambda: np.zeros((self.num_wann, self.num_wann, 3), dtype=complex)) while True: line = next(f) if line.startswith("end spin:"): allread = True break elif line.startswith("Tij, Hij"): iw, jw = [int(x) for x in next(f).split()] iw -= 1 jw -= 1 arread = [] while True: line = next(f) if line.startswith("end Tij, Hij"): break arread.append(line.split()) if len(arread) == 0: continue arread = np.array(arread, dtype=float) Rvec_loc = arread[:, :3] + ( self.wannier_centers_cart[None, iw] - self.wannier_centers_cart[None, jw]) Rvec_loc = Rvec_loc.dot(inv_real_lattice) # should be integer now iRvec = np.array(np.round(Rvec_loc), dtype=int) assert (abs(iRvec - Rvec_loc).max() < 1e-8) iRvec = [tuple(ir) for ir in iRvec] for iR, a in zip(iRvec, arread): Ham_R[iR][iw, jw] = a[3] + 1j * a[4] if self.need_R_any('SS'): SS_R[iR][iw, jw, :] = a[5:11:2] + 1j * a[6:11:2] f.close() # Reading of file finished self.set_real_lattice(real_lattice_bohr * bohr) iRvec = list(Ham_R.keys()) self.set_R_mat('Ham', np.array([Ham_R[iR] for iR in iRvec])) if self.need_R_any('SS'): self.set_R_mat('SS', np.array([SS_R[iR] for iR in iRvec])) self.rvec = Rvectors(lattice=self.real_lattice, iRvec=iRvec, shifts_left_red=self.wannier_centers_red) self.do_at_end_of_init() print("FPLO system initialized") print(f"wannier_centers_cart: {self.wannier_centers_cart}") print(f"wannier_centers_red: {self.wannier_centers_red}") if mp_grid is not None: self.do_ws_dist(mp_grid=mp_grid) cprint(f"Reading the FPLO Wannier system from {hamdata} finished successfully", 'green', attrs=['bold'])