def set_nsc(self, nsc=None, a=None, b=None, c=None): """ Sets the number of supercells in the 3 different cell directions nsc: list of int, optional number of supercells in each direction a: integer, optional number of supercells in the first unit-cell vector direction b: integer, optional number of supercells in the second unit-cell vector direction c: integer, optional number of supercells in the third unit-cell vector direction """ if not nsc is None: for i in range(3): if not nsc[i] is None: self.nsc[i] = nsc[i] if a: self.nsc[0] = a if b: self.nsc[1] = b if c: self.nsc[2] = c # Correct for misplaced number of unit-cells for i in range(3): if self.nsc[i] == 0: self.nsc[i] = 1 if np.sum(self.nsc % 2) != 3: raise ValueError( "Supercells has to be of un-even size. The primary cell counts " + "one, all others count 2") # We might use this very often, hence we store it self.n_s = _a.prodi(self.nsc) self._sc_off = _a.zerosi([self.n_s, 3]) self._isc_off = _a.zerosi(self.nsc) n = self.nsc # We define the following ones like this: def ret_range(val): i = val // 2 return range(-i, i + 1) x = ret_range(n[0]) y = ret_range(n[1]) z = ret_range(n[2]) i = 0 for iz in z: for iy in y: for ix in x: if ix == 0 and iy == 0 and iz == 0: continue # Increment index i += 1 # The offsets for the supercells in the # sparsity pattern self._sc_off[i, 0] = ix self._sc_off[i, 1] = iy self._sc_off[i, 2] = iz self._update_isc_off()
def read_geometry(self): """ Reading a geometry in regular Hamiltonian format """ cell = np.zeros([3, 3], np.float64) Z = [] xyz = [] nsc = _a.zerosi([3]) def Z2no(i, no): try: # pure atomic number return int(i), no except Exception: # both atomic number and no j = i.replace('[', ' ').replace(']', ' ').split() return int(j[0]), int(j[1]) # The format of the geometry file is keys = ['atoms', 'cell', 'supercell', 'nsc'] for _ in range(len(keys)): _, l = self.step_to(keys, case=False) l = l.strip() if 'supercell' in l.lower() or 'nsc' in l.lower(): # We have everything in one line l = l.split()[1:] for i in range(3): nsc[i] = int(l[i]) elif 'cell' in l.lower(): if 'begin' in l.lower(): for i in range(3): l = self.readline().split() cell[i, 0] = float(l[0]) cell[i, 1] = float(l[1]) cell[i, 2] = float(l[2]) self.readline() # step past the block else: # We have everything in one line l = l.split()[1:] for i in range(3): cell[i, i] = float(l[i]) # TODO incorporate rotations elif 'atoms' in l.lower(): l = self.readline() while not l.startswith('end'): ls = l.split() try: no = int(ls[4]) except Exception: no = 1 z, no = Z2no(ls[0], no) Z.append({'Z': z, 'orbital': [-1. for _ in range(no)]}) xyz.append([float(f) for f in ls[1:4]]) l = self.readline() xyz = _a.arrayd(xyz) xyz.shape = (-1, 3) self.readline() # step past the block # Create geometry with associated supercell and atoms geom = Geometry(xyz, atoms=Atom[Z], sc=SuperCell(cell, nsc)) return geom