Beispiel #1
0
    def read_grid(self, name='gridfunc', idx=0, *args, **kwargs):
        """ Reads a grid in the current SIESTA.grid.nc file

        Enables the reading and processing of the grids created by SIESTA
        """
        # Swap as we swap back in the end
        sc = self.read_sc().swapaxes(0, 2)

        # Create the grid
        nx = len(self._dimension('n1'))
        ny = len(self._dimension('n2'))
        nz = len(self._dimension('n3'))

        if name is None:
            v = self._variable('gridfunc')
        else:
            v = self._variable(name)

        # Create the grid, SIESTA uses periodic, always
        grid = Grid([nz, ny, nx], bc=Grid.Periodic, sc=sc,
                    dtype=v.dtype)

        if len(v[:].shape) == 3:
            grid.grid = v[:, :, :]
        else:
            grid.grid = v[idx, :, :, :]

        # Read the grid, we want the z-axis to be the fastest
        # looping direction, hence x,y,z == 0,1,2
        return grid.swapaxes(0, 2)
def test_default(sisl_tmp):
    f = sisl_tmp('GRID.xsf', _dir)
    print(f)
    grid = Grid(0.2)
    grid.grid = np.random.rand(*grid.shape)
    grid.write(f)
    assert grid.geometry is None
def test_imaginary(sisl_tmp):
    f = sisl_tmp('GRID.xsf', _dir)
    geom = Geometry(np.random.rand(10, 3), np.random.randint(1, 70, 10), sc=[10, 10, 10, 45, 60, 90])
    grid = Grid(0.2, geometry=geom, dtype=np.complex128)
    grid.grid = np.random.rand(*grid.shape) + 1j*np.random.rand(*grid.shape)
    grid.write(f)
    assert not grid.geometry is None
Beispiel #4
0
    def read_grid(self, spin=0, *args, **kwargs):
        """ Read grid contained in the Grid file

        Parameters
        ----------
        spin : int or array_like, optional
           the spin-index for retrieving one of the components. If a vector
           is passed it refers to the fraction per indexed component. I.e.
           ``[0.5, 0.5]`` will return sum of half the first two components.
           Default to the first component.
        """
        # Read the sizes
        nspin, mesh = _siesta.read_grid_sizes(self.file)
        # Read the cell and grid
        cell = _siesta.read_grid_cell(self.file)
        grid = _siesta.read_grid(self.file, nspin, mesh[0], mesh[1], mesh[2])

        if isinstance(spin, Integral):
            grid = grid[:, :, :, spin]
        else:
            if len(spin) > grid.shape[0]:
                raise ValueError(self.__class__.__name__ + '.read_grid requires spin to be an integer or '
                                 'an array of length equal to the number of spin components.')
            g = grid[:, :, :, 0] * spin[0]
            for i, scale in enumerate(spin[1:]):
                g += grid[:, :, :, 1+i] * scale
            grid = g

        cell = np.array(cell.T, np.float64)
        cell.shape = (3, 3)

        g = Grid(mesh, sc=SuperCell(cell), dtype=np.float32)
        g.grid = np.array(grid.swapaxes(0, 2), np.float32) * self.grid_unit
        return g
Beispiel #5
0
    def read_grid(self):
        """ Returns `Grid` object from the CUBE file """
        geom = self.read_geom()

        # Now seek behind to read grid sizes
        self.fh.seek(0)

        # Skip headers and origo
        self.readline()
        self.readline()
        na = int(self.readline().split()[0])

        ngrid = [0] * 3
        for i in [0, 1, 2]:
            tmp = self.readline().split()
            ngrid[i] = int(tmp[0])

        # Read past the atoms
        for i in range(na):
            self.readline()

        grid = Grid(ngrid, dtype=np.float32, geom=geom)
        grid.grid = np.loadtxt(self.fh, dtype=grid.dtype)
        grid.grid.shape = ngrid

        return grid
Beispiel #6
0
    def read_grid(self):
        """ Returns `Grid` object from the CUBE file """
        geom = self.read_geom()

        # Now seek behind to read grid sizes
        self.fh.seek(0)

        # Skip headers and origo
        self.readline()
        self.readline()
        na = int(self.readline().split()[0])

        ngrid = [0] * 3
        for i in [0, 1, 2]:
            tmp = self.readline().split()
            ngrid[i] = int(tmp[0])

        # Read past the atoms
        for i in range(na):
            self.readline()

        grid = Grid(ngrid, dtype=np.float32, geom=geom)
        grid.grid = np.loadtxt(self.fh, dtype=grid.dtype)
        grid.grid.shape = ngrid

        return grid
Beispiel #7
0
def test_default_size(sisl_tmp):
    f = sisl_tmp('GRID.cube', _dir)
    grid = Grid(0.2, sc=2.0)
    grid.grid = np.random.rand(*grid.shape)
    grid.write(f)
    read = grid.read(f)
    assert np.allclose(grid.grid, read.grid)
    assert grid.geometry is None
    assert len(read.geometry) == 1
Beispiel #8
0
    def read_grid(self, name, idx=0):
        """ Reads a grid in the current SIESTA.nc file

        Enables the reading and processing of the grids created by SIESTA
        """
        # Swap as we swap back in the end
        geom = self.read_geom().swapaxes(0, 2)

        # Shorthand
        g = self.groups['GRID']

        # Create the grid
        nx = len(g.dimensions['nx'])
        ny = len(g.dimensions['ny'])
        nz = len(g.dimensions['nz'])

        # Shorthand variable name
        v = g.variables[name]

        # Create the grid, SIESTA uses periodic, always
        grid = Grid([nz, ny, nx], bc=Grid.Periodic, dtype=v.dtype)

        if len(v[:].shape) == 3:
            grid.grid = v[:, :, :]
        else:
            grid.grid = v[idx, :, :, :]

        try:
            u = v.unit
            if u == 'Ry':
                # Convert to ev
                grid *= Ry2eV
        except:
            # Simply, we have no units
            pass

        # Read the grid, we want the z-axis to be the fastest
        # looping direction, hence x,y,z == 0,1,2
        grid = grid.swapaxes(0, 2)
        grid.set_geom(geom)

        return grid
Beispiel #9
0
    def read_grid(self, name, idx=0):
        """ Reads a grid in the current SIESTA.nc file

        Enables the reading and processing of the grids created by SIESTA
        """
        # Swap as we swap back in the end
        geom = self.read_geom().swapaxes(0, 2)

        # Shorthand
        g = self.groups['GRID']

        # Create the grid
        nx = len(g.dimensions['nx'])
        ny = len(g.dimensions['ny'])
        nz = len(g.dimensions['nz'])

        # Shorthand variable name
        v = g.variables[name]

        # Create the grid, SIESTA uses periodic, always
        grid = Grid([nz, ny, nx], bc=Grid.Periodic, dtype=v.dtype)

        if len(v[:].shape) == 3:
            grid.grid = v[:, :, :]
        else:
            grid.grid = v[idx, :, :, :]

        try:
            u = v.unit
            if u == 'Ry':
                # Convert to ev
                grid *= Ry2eV
        except:
            # Simply, we have no units
            pass

        # Read the grid, we want the z-axis to be the fastest
        # looping direction, hence x,y,z == 0,1,2
        grid = grid.swapaxes(0, 2)
        grid.set_geom(geom)

        return grid
Beispiel #10
0
def test_geometry(sisl_tmp):
    f = sisl_tmp('GRID.cube', _dir)
    geom = Geometry(np.random.rand(10, 3), np.random.randint(1, 70, 10), sc=[10, 10, 10, 45, 60, 90])
    grid = Grid(0.2, geometry=geom)
    grid.grid = np.random.rand(*grid.shape)
    grid.write(f)
    read = grid.read(f)
    assert np.allclose(grid.grid, read.grid)
    assert not grid.geometry is None
    assert not read.geometry is None
    assert grid.geometry == read.geometry
Beispiel #11
0
def test_imaginary_fail_geometry(sisl_tmp):
    fr = sisl_tmp('GRID_real.cube', _dir)
    fi = sisl_tmp('GRID_imag.cube', _dir)
    geom = Geometry(np.random.rand(10, 3), np.random.randint(1, 70, 10), sc=[10, 10, 10, 45, 60, 90])
    grid = Grid(0.2, geometry=geom, dtype=np.complex128)
    grid.grid = np.random.rand(*grid.shape) + 1j*np.random.rand(*grid.shape)
    grid.write(fr)

    # Assert it fails on geometry
    grid2 = Grid(0.3, dtype=np.complex128)
    grid2.write(fi, imag=True)
    grid.read(fr, imag=fi)
Beispiel #12
0
    def read_grid(self, index=0, dtype=np.float64, *args, **kwargs):
        """ Read grid contained in the Grid file

        Parameters
        ----------
        index : int or array_like, optional
           the spin-index for retrieving one of the components. If a vector
           is passed it refers to the fraction per indexed component. I.e.
           ``[0.5, 0.5]`` will return sum of half the first two components.
           Default to the first component.
        dtype : numpy.float64, optional
           default data-type precision
        """
        index = kwargs.get('spin', index)
        # Read the sizes and cell
        nspin, mesh = self.read_grid_size()
        cell = _siesta.read_grid_cell(self.file)
        _bin_check(self, 'read_grid', 'could not read grid cell.')
        grid = _siesta.read_grid(self.file, nspin, mesh[0], mesh[1], mesh[2])
        _bin_check(self, 'read_grid', 'could not read grid.')

        if isinstance(index, Integral):
            grid = grid[:, :, :, index]
        else:
            if len(index) > grid.shape[0]:
                raise ValueError(
                    self.__class__.__name__ +
                    '.read_grid requires spin to be an integer or '
                    'an array of length equal to the number of spin components.'
                )
            # It is F-contiguous, hence the last index
            g = grid[:, :, :, 0] * index[0]
            for i, scale in enumerate(index[1:]):
                g += grid[:, :, :, 1 + i] * scale
            grid = g

        cell = np.array(cell.T, np.float64)
        cell.shape = (3, 3)

        # Simply create the grid (with no information)
        # We will overwrite the actual grid
        g = Grid([1, 1, 1], sc=SuperCell(cell))
        # NOTE: there is no need to swap-axes since the returned array is in F ordering
        #       and thus the first axis is the fast (x, y, z) is retained
        g.grid = (grid * self.grid_unit).astype(dtype=dtype,
                                                order='C',
                                                copy=False)
        return g
Beispiel #13
0
    def test_isosurface_non_orthogonal(self, setup):

        pytest.importorskip("skimage", reason="scikit-image not available")

        # If the grid is non-orthogonal, there should be 20 unique values
        # (10 for each (HERE), see test_isosurface_orthogonal)
        grid = Grid(0.1, sc=[[1, 0, 0], [0, 1, 0], [0, 2, 1]])

        grid.grid = np.tile([1, 2, 3, 4, 5, 4, 3, 2, 1, 0],
                            100).reshape(10, 10, 10)

        verts, *returns = grid.isosurface(2.5)

        # we have twice as many since the 3rd lattice vector has components in y
        assert np.unique(verts[:, 1]).shape == (20, )
        assert np.unique(verts[:, 2]).shape == (2, )
Beispiel #14
0
    def test_isosurface_orthogonal(self, setup):

        pytest.importorskip("skimage", reason="scikit-image not available")

        # Build an empty grid
        grid = Grid(0.1, sc=[[1, 0, 0], [0, 1, 0], [0, 0, 1]])

        # Fill it with some values that have a clear isosurface
        grid.grid = np.tile([1, 2, 3, 4, 5, 4, 3, 2, 1, 0],
                            100).reshape(10, 10, 10)

        # Calculate the isosurface for the value of 2.5
        verts, *returns = grid.isosurface(2.5)

        # The third dimension should contain only two coordinates
        # [1, 2, (HERE) 3, 4, 5, 4, 3, (HERE) 2, 1, 0]
        assert np.unique(verts[:, 1]).shape == (10, )
        assert np.unique(verts[:, 2]).shape == (2, )
Beispiel #15
0
    def read_grid(self, index=0, dtype=np.float64):
        """ Reads the charge density from the file and returns with a grid (plus geometry)

        Parameters
        ----------
        index : int, optional
           the index of the grid to read. For a spin-polarized VASP calculation 0 and 1 are
           allowed, UP/DOWN. For non-collinear 0, 1, 2 or 3 is allowed which equals,
           TOTAL, x, y, z charge density with the Cartesian directions equal to the charge
           magnetization.
        dtype : numpy.dtype, optional
           grid stored dtype

        Returns
        -------
        Grid : charge density grid with associated geometry
        """
        geom = self.read_geometry()
        V = geom.sc.volume

        # Now we are past the cell and geometry
        # We can now read the size of CHGCAR
        self.readline()
        nx, ny, nz = list(map(int, self.readline().split()))
        n = nx * ny * nz

        i = 0
        vals = []
        while i < n * (index + 1):
            dat = [float(l) for l in self.readline().split()]
            vals.append(dat)
            i += len(dat)
        vals = np.swapaxes(np.array(vals).reshape(nz, ny, nx), 0, 2)
        vals = vals[index * n:(index + 1) * n] / V

        # Create the grid with data
        # Since we populate the grid data afterwards there
        # is no need to create a bigger grid than necessary.
        grid = Grid([1, 1, 1], dtype=dtype, geometry=geom)
        grid.grid = vals

        return grid
Beispiel #16
0
def test_imaginary(sisl_tmp):
    fr = sisl_tmp('GRID_real.cube', _dir)
    fi = sisl_tmp('GRID_imag.cube', _dir)
    geom = Geometry(np.random.rand(10, 3), np.random.randint(1, 70, 10), sc=[10, 10, 10, 45, 60, 90])
    grid = Grid(0.2, geometry=geom, dtype=np.complex128)
    grid.grid = np.random.rand(*grid.shape) + 1j*np.random.rand(*grid.shape)
    grid.write(fr)
    grid.write(fi, imag=True)
    read = grid.read(fr)
    read_i = grid.read(fi)
    read.grid = read.grid + 1j*read_i.grid
    assert np.allclose(grid.grid, read.grid)
    assert not grid.geometry is None
    assert not read.geometry is None
    assert grid.geometry == read.geometry

    read = grid.read(fr, imag=fi)
    assert np.allclose(grid.grid, read.grid)

    read = grid.read(fr, imag=read_i)
    assert np.allclose(grid.grid, read.grid)
Beispiel #17
0
    def read_grid(self, name, spin=0, **kwargs):
        """ Reads a grid in the current Siesta.nc file

        Enables the reading and processing of the grids created by Siesta

        Parameters
        ----------
        name : str
           name of the grid variable to read
        spin : int or array_like, optional
           the spin-index for retrieving one of the components. If a vector
           is passed it refers to the fraction per indexed component. I.e.
           ``[0.5, 0.5]`` will return sum of half the first two components.
           Default to the first component.
        """
        spin = kwargs.get('index', spin)
        geom = self.read_geometry()

        # Shorthand
        g = self.groups['GRID']

        # Create the grid
        nx = len(g.dimensions['nx'])
        ny = len(g.dimensions['ny'])
        nz = len(g.dimensions['nz'])

        # Shorthand variable name
        v = g.variables[name]

        # Create the grid, Siesta uses periodic, always
        grid = Grid([nz, ny, nx],
                    bc=Grid.PERIODIC,
                    geometry=geom,
                    dtype=v.dtype)

        # Unit-conversion
        BohrC2AngC = Bohr2Ang**3

        unit = {
            'Rho': 1. / BohrC2AngC,
            'RhoInit': 1. / BohrC2AngC,
            'RhoTot': 1. / BohrC2AngC,
            'RhoDelta': 1. / BohrC2AngC,
            'RhoXC': 1. / BohrC2AngC,
            'RhoBader': 1. / BohrC2AngC,
            'Chlocal': 1. / BohrC2AngC,
        }.get(name, 1.)

        if len(v[:].shape) == 3:
            grid.grid = v[:, :, :] * unit
        elif isinstance(spin, Integral):
            grid.grid = v[spin, :, :, :] * unit
        else:
            if len(spin) > v.shape[0]:
                raise SileError(
                    self.__class__.__name__ +
                    '.read_grid requires spin to be an integer or '
                    'an array of length equal to the number of spin components.'
                )
            grid.grid[:, :, :] = v[0, :, :, :] * (spin[0] * unit)
            for i, scale in enumerate(spin[1:]):
                grid.grid[:, :, :] += v[1 + i, :, :, :] * (scale * unit)

        try:
            if v.unit == 'Ry':
                # Convert to ev
                grid *= Ry2eV
        except:
            # Allowed pass due to pythonic reading
            pass

        # Read the grid, we want the z-axis to be the fastest
        # looping direction, hence x,y,z == 0,1,2
        grid.grid = np.copy(np.swapaxes(grid.grid, 0, 2), order='C')

        return grid
Beispiel #18
0
    def read_grid(self, index=0, dtype=np.float64):
        """ Reads the potential (in eV) from the file and returns with a grid (plus geometry)

        Parameters
        ----------
        index : int or array_like, optional
           the index of the potential to read. For a spin-polarized VASP calculation 0 and 1 are
           allowed, UP/DOWN. For non-collinear 0, 1, 2 or 3 is allowed which equals,
           TOTAL, x, y, z total potential with the Cartesian directions equal to the potential
           for the magnetization directions. For array-like they refer to the fractional
           contributions for each corresponding index.
        dtype : numpy.dtype, optional
           grid stored dtype

        Returns
        -------
        Grid : potential with associated geometry
        """
        geom = self.read_geometry()
        V = geom.sc.volume

        # Now we are past the cell and geometry
        # We can now read the size of LOCPOT
        self.readline()
        nx, ny, nz = list(map(int, self.readline().split()))
        n = nx * ny * nz

        is_index = True
        if isinstance(index, Integral):
            max_index = index + 1
        else:
            is_index = False
            max_index = len(index)

        rl = self.readline
        vals = []
        vapp = vals.append

        i = 0
        while i < n * max_index:
            dat = [l for l in rl().split()]
            vapp(dat)
            i += len(dat)

            if i % n == 0 and i < n * max_index:
                # Each time a new spin-index is present, we need to read the coordinates
                j = 0
                while j < geom.na:
                    j += len(rl().split())

                # one line of nx, ny, nz
                rl()

        # Cut size before proceeding (otherwise it *may* fail)
        vals = np.array(vals).astype(dtype).ravel()
        if is_index:
            val = vals[n * index:n * (index + 1)].reshape(nz, ny, nx)
        else:
            vals = vals[:n * max_index].reshape(-1, nz, ny, nx)
            val = vals[0] * index[0]
            for i, scale in enumerate(index[1:]):
                val += vals[i + 1] * scale
        del vals

        # Make it C-ordered with nx, ny, nz
        val = np.swapaxes(val, 0, 2) / V

        # Create the grid with data
        # Since we populate the grid data afterwards there
        # is no need to create a bigger grid than necessary.
        grid = Grid([1, 1, 1], dtype=dtype, geometry=geom)
        grid.grid = val

        return grid
Beispiel #19
0
def test_default_size(sisl_tmp):
    f = sisl_tmp('GRID.xsf', _dir)
    grid = Grid(0.2, sc=2.0)
    grid.grid = np.random.rand(*grid.shape)
    grid.write(f)
    assert grid.geometry is None
Beispiel #20
0
    def read_grid(self, imag=None):
        """ Returns `Grid` object from the CUBE file

        Parameters
        ----------
        imag : str or Sile or Grid
            the imaginary part of the grid. If the geometries does not match
            an error will be raised.
        """
        if not imag is None:
            if not isinstance(imag, Grid):
                imag = Grid.read(imag)
        geom = self.read_geometry()
        if geom is None:
            self.fh.seek(0)
            sc = self.read_supercell()
        else:
            sc = geom.sc

        # Now seek behind to read grid sizes
        self.fh.seek(0)

        # Skip headers and origin
        self.readline()
        self.readline()
        na = int(self.readline().split()[0])

        ngrid = [0] * 3
        for i in [0, 1, 2]:
            tmp = self.readline().split()
            ngrid[i] = int(tmp[0])

        # Read past the atoms
        for i in range(na):
            self.readline()

        if geom is None:
            grid = Grid(ngrid, dtype=np.float64, sc=sc)
        else:
            grid = Grid(ngrid, dtype=np.float64, geometry=geom)
        grid.grid.shape = (-1, )

        # TODO check performance of this
        # We are currently doing this to enable reading
        #  1-column data and 6-column data.
        lines = [
            item for sublist in self.fh.readlines()
            for item in sublist.split()
        ]
        grid.grid[:] = np.array(lines).astype(grid.dtype)
        grid.grid.shape = ngrid

        if imag is None:
            return grid

        # We are expecting an imaginary part
        if not grid.geometry.equal(imag.geometry):
            raise SislError(
                str(self) + ' and its imaginary part does not have the same '
                'geometry. Hence a combined complex Grid cannot be formed.')
        if grid != imag:
            raise SislError(
                str(self) + ' and its imaginary part does not have the same '
                'shape. Hence a combined complex Grid cannot be formed.')

        # Now we have a complex grid
        grid.grid = grid.grid + 1j * imag.grid

        return grid