Source code for wannierberri.system.system_random

import warnings
import numpy as np
from .system_R import System_R
from .system import num_cart_dim
from ..fourier.rvectors import Rvectors


[docs] class SystemRandom(System_R): """ Randomly generated system. Mainly for testing. Further can be symmetrized to get generic system with certain symmetries. Parameters: ----------- num_wann : int number of Wannier functions real_lattice : array( (3,3) ) real lattice vectors. inf None - generated randomly nRvec : int number of R-space vectors max_R: maximal coordinate in the R-vectors """ def __init__(self, num_wann, nRvec=10, real_lattice=None, max_R=5, **parameters): if "name" not in parameters: parameters["name"] = "random" super().__init__(**parameters) if real_lattice is None: while True: real_lattice = np.random.random((3, 3)) d = np.linalg.det(real_lattice) if abs(d) > 1e-2: if d < 0: real_lattice *= -1 break self.set_real_lattice(real_lattice) self.num_wann = num_wann assert (max_R * 2 + 1)**3 >= nRvec, "too many Rvectors or max_R too small" count = 0 iRvec = {(0, 0, 0)} while len(iRvec) < nRvec and count < 10: R_try = np.random.randint(low=-max_R, high=max_R + 1, size=(nRvec, 3)) R_try = set(tuple(R) for R in R_try) iRvec.update(R_try) if len(iRvec) < nRvec: warnings.warn(f"required number of R-vectors {nRvec} was not achieved. got only {len(iRvec)}") iRvec = np.array(list(iRvec)) norm = np.linalg.norm(iRvec, axis=1) srt = np.argsort(norm) self.iRvec = iRvec[srt][:nRvec] np.random.shuffle(self.iRvec) self.wannier_centers_cart = np.random.random((self.num_wann, 3)) self.rvec = Rvectors( lattice=self.real_lattice, iRvec=list(iRvec), shifts_left_red=self.wannier_centers_red, ) for key in self.needed_R_matrices: shape = (self.rvec.nRvec, self.num_wann, self.num_wann) + (3,) * num_cart_dim(key) im, re = [np.random.random(shape) for _ in (0, 1)] self.set_R_mat(key, im + 1j * re) if self.has_R_mat('AA'): AA = self.get_R_mat('AA') AA[self.rvec.iR0, self.range_wann, self.range_wann] = 0 self.do_at_end_of_init()