Source code for sisl.io.siesta.binaries

"""
Sile object for reading/writing SIESTA binary files
"""
from __future__ import print_function

import numpy as np

try:
    import _siesta
    found_module = True
except:
    found_module = False

# Import sile objects
from .sile import SileBinSIESTA
from ..sile import *

# Import the geometry object
from sisl import Geometry, Atom, SuperCell, Grid
from sisl.units.siesta import unit_convert
from sisl.physics import Hamiltonian


__all__ = ['TSHSSileSiesta']


[docs]class TSHSSileSiesta(SileBinSIESTA): """ TranSIESTA file object """
[docs] def read_supercell(self): """ Returns a SuperCell object from a siesta.TSHS file """ n_s = _siesta.read_tshs_sizes(self.file)[3] arr = _siesta.read_tshs_cell(self.file, n_s) nsc = np.array(arr[0].T, np.int32) cell = np.array(arr[1].T, np.float64) cell.shape = (3, 3) isc = np.array(arr[2].T, np.int32) isc.shape = (-1, 3) SC = SuperCell(cell, nsc=nsc) SC.sc_off = isc return SC
[docs] def read_geometry(self): """ Returns Geometry object from a siesta.TSHS file """ # Read supercell sc = self.read_supercell() na = _siesta.read_tshs_sizes(self.file)[1] arr = _siesta.read_tshs_geom(self.file, na) xyz = np.array(arr[0].T, np.float64) xyz.shape = (-1, 3) lasto = np.array(arr[1], np.int32) # Create all different atoms... # The TSHS file does not contain the # atomic numbers, so we will just # create them individually orbs = np.diff(lasto) # Get unique orbitals uorb = np.unique(orbs) # Create atoms atoms = [] for Z, orb in enumerate(uorb): atoms.append(Atom(Z+1, orbs=orb)) def get_atom(atoms, orbs): for atom in atoms: if atom.orbs == orbs: return atom atom = [] for i, orb in enumerate(orbs): atom.append(get_atom(atoms, orb)) # Create and return geometry object geom = Geometry(xyz, atom, sc=sc) return geom
[docs] def read_hamiltonian(self, **kwargs): """ Returns the electronic structure from the siesta.TSHS file """ # First read the geometry geom = self.read_geometry() # Now read the sizes used... sizes = _siesta.read_tshs_sizes(self.file) spin = sizes[0] no = sizes[2] nnz = sizes[4] ncol, col, dH, dS = _siesta.read_tshs_es(self.file, spin, no, nnz) # Create the Hamiltonian container H = Hamiltonian(geom, nnzpr=1, orthogonal=False, spin=spin) # Create the new sparse matrix H._data.ncol = np.array(ncol, np.int32) ptr = np.cumsum(ncol) ptr = np.insert(ptr, 0, 0) H._data.ptr = np.array(ptr, np.int32) # Correct fortran indices H._data.col = np.array(col, np.int32) - 1 H._data._nnz = len(col) H._data._D = np.empty([nnz, spin+1], np.float64) for i in range(spin): # this is because of the F-ordering H._data._D[:, i] = dH[:, i] H._data._D[:, spin] = dS[:] return H
if found_module: add_sile('TSHS', TSHSSileSiesta)