コード例 #1
0
    def read_force(self, displacement=None, na=None):
        """ Reads all displacement forces by multiplying with the displacement value

        Since the force constant file does not contain the non-displaced configuration
        this will only return forces on the displaced configurations minus the forces from
        the non-displaced configuration.

        This may be used in conjunction with phonopy by noticing that Siesta FC-runs does
        the displacements in reverse order (-x/+x vs. +x/-x). In this case one should reorder
        the elements like this:

        >>> fc = np.roll(fc, 1, axis=2)

        Parameters
        ----------
        displacement : float, optional
           the used displacement in the calculation, since Siesta 4.1-b4 this value
           is written in the FC file and hence not required.
           If prior Siesta versions are used and this is not supplied the 0.04 Bohr displacement
           will be assumed.
        na : int, optional
           number of atoms in geometry (for returning correct number of atoms), since Siesta 4.1-b4
           this value is written in the FC file and hence not required.
           If prior Siesta versions are used then the file is expected to only contain 1-atom displacement.

        Returns
        -------
        numpy.ndarray : (displaced atoms, d[xyz], [-+], total atoms, xyz)
             force constant matrix times the displacement, see `read_force_constant` for details regarding
             data layout.
        """
        if displacement is None:
            line = self.readline().split()
            self.fh.seek(0)
            try:
                displacement = float(line[-1])
            except:
                warn(f"{self.__class__.__name__}.read_force assumes displacement=0.04 Bohr!")
                displacement = 0.04 * unit_convert('Bohr', 'Ang')

        # Since the displacements changes sign (starting with a negative sign)
        # we can convert using this scheme
        displacement = np.repeat(displacement, 6).ravel()
        displacement[1::2] *= -1
        return self.read_force_constant(na) * displacement.reshape(1, 3, 2, 1, 1)
コード例 #2
0
def test_supercell(sisl_tmp):
    f = sisl_tmp('file.fdf', _dir)
    lines = [
        'Latticeconstant 1. Ang',
        '%block Latticevectors',
        ' 1. 1. 1.',
        ' 0. 0. 1.',
        ' 1. 0. 1.',
        '%endblock',
    ]
    with open(f, 'w') as fh:
        fh.write('\n'.join(lines))

    cell = np.array([[1.] * 3, [0, 0, 1], [1, 0, 1]])
    sc = fdfSileSiesta(f).read_supercell()
    assert np.allclose(sc.cell, cell)

    lines = [
        'Latticeconstant 1. Bohr',
        '%block Latticevectors',
        ' 1. 1. 1.',
        ' 0. 0. 1.',
        ' 1. 0. 1.',
        '%endblock',
    ]
    with open(f, 'w') as fh:
        fh.write('\n'.join(lines))

    sc = fdfSileSiesta(f).read_supercell()
    assert np.allclose(sc.cell, cell * unit_convert('Bohr', 'Ang'))

    cell = np.diag([2.] * 3)
    lines = [
        'Latticeconstant 2. Ang',
        '%block Latticeparameters',
        ' 1. 1. 1. 90. 90. 90.',
        '%endblock',
    ]
    with open(f, 'w') as fh:
        fh.write('\n'.join(lines))

    sc = fdfSileSiesta(f).read_supercell()
    assert np.allclose(sc.cell, cell)
コード例 #3
0
from sisl.unit.siesta import unit_convert
from sisl import Geometry, Atom, AtomGhost, Atoms, SuperCell, Grid, SphericalOrbital
from sisl.physics import SparseOrbitalBZ
from sisl.physics import DensityMatrix, EnergyDensityMatrix
from sisl.physics import DynamicalMatrix
from sisl.physics import Hamiltonian
from sisl.physics.overlap import Overlap
from ._help import *
try:
    from . import _siesta
except:
    pass

__all__ = ['ncSileSiesta']

Bohr2Ang = unit_convert('Bohr', 'Ang')
Ry2eV = unit_convert('Ry', 'eV')


@set_module("sisl.io.siesta")
class ncSileSiesta(SileCDFSiesta):
    """ Generic NetCDF output file containing a large variety of information """
    @lru_cache(maxsize=1)
    def read_supercell_nsc(self):
        """ Returns number of supercell connections """
        return np.array(self._value('nsc'), np.int32)

    @lru_cache(maxsize=1)
    def read_supercell(self):
        """ Returns a SuperCell object from a Siesta.nc file """
        cell = np.array(self._value('cell'), np.float64)
コード例 #4
0
ファイル: out.py プロジェクト: silsgs/sisl
from __future__ import print_function, division

import os
import numpy as np

from .sile import SileSiesta
from ..sile import *
from sisl.io._help import *

from sisl import Geometry, Atom, SuperCell
from sisl.utils.cmd import *
from sisl.unit.siesta import unit_convert

__all__ = ['outSileSiesta']

Bohr2Ang = unit_convert('Bohr', 'Ang')


def _ensure_species(species):
    """ Ensures that the species list is a list with entries (converts `None` to a list). """
    if species is None:
        return [Atom(i) for i in range(150)]
    return species


class outSileSiesta(SileSiesta):
    """ Output file from Siesta

    This enables reading the output quantities from the Siesta output.
    """
    _job_completed = False
コード例 #5
0
# Import sile objects
from ..sile import SileWarning
from .sile import SileCDFTBtrans
from sisl.messages import warn, info
from sisl.utils import *
import sisl._array as _a
from sisl._indices import indices

# Import the geometry object
from sisl import Geometry, Atom, SuperCell
from sisl.unit.siesta import unit_convert

__all__ = ['_ncSileTBtrans', '_devncSileTBtrans']


Bohr2Ang = unit_convert('Bohr', 'Ang')
Ry2eV = unit_convert('Ry', 'eV')
Ry2K = unit_convert('Ry', 'K')
eV2Ry = unit_convert('eV', 'Ry')


class _ncSileTBtrans(SileCDFTBtrans):
    r""" Common TBtrans NetCDF file object due to a lot of the files having common entries

    This enables easy read of the Geometry and SuperCells etc.
    """
    @lru_cache(maxsize=1)
    def read_supercell(self):
        """ Returns `SuperCell` object from this file """
        cell = _a.arrayd(np.copy(self.cell))
        cell.shape = (3, 3)
コード例 #6
0
def test_unit_convert_f2():
    with pytest.raises(ValueError):
        unit_convert('eV', 'kg')
コード例 #7
0
def test_unit_convert_f1():
    with pytest.raises(ValueError):
        unit_convert('eV', 'megaerg')
コード例 #8
0
def test_include(sisl_tmp):
    f = sisl_tmp('file.fdf', _dir)
    with open(f, 'w') as fh:
        fh.write('Flag1 date\n')
        fh.write('# Flag2 comment\n')
        fh.write('Flag2 date2\n')
        fh.write('# Flag3 is read through < from file hello\n')
        fh.write('Flag3 Sub < hello\n')
        fh.write('FakeInt 1\n')
        fh.write('Test 1. eV\n')
        fh.write(' %INCLUDE file2.fdf\n')
        fh.write('TestRy 1. Ry\n')
        fh.write('%block Hello < hello\n')
        fh.write('TestLast 1. eV\n')

    hello = sisl_tmp('hello', _dir)
    with open(hello, 'w') as fh:
        fh.write('Flag4 hello\n')
        fh.write('# Comments should be discarded\n')
        fh.write('Flag3 test\n')
        fh.write('Sub sub-test\n')

    file2 = sisl_tmp('file2.fdf', _dir)
    with open(file2, 'w') as fh:
        fh.write('Flag4 non\n')
        fh.write('FakeReal 2.\n')
        fh.write('  %incLude file3.fdf')

    file3 = sisl_tmp('file3.fdf', _dir)
    with open(file3, 'w') as fh:
        fh.write('Sub level\n')
        fh.write('Third level\n')
        fh.write('MyList [1 , 2 , 3]\n')

    fdf = fdfSileSiesta(f, base=sisl_tmp.getbase())
    assert fdf.includes() == [Path(hello), Path(file2), Path(file3)]
    assert fdf.get('Flag1') == 'date'
    assert fdf.get('Flag2') == 'date2'
    assert fdf.get('Flag3') == 'test'
    assert fdf.get('Flag4') == 'non'
    assert fdf.get('FLAG4') == 'non'
    assert fdf.get('Fakeint') == 1
    assert fdf.get('Fakeint', '0') == '1'
    assert fdf.get('Fakereal') == 2.
    assert fdf.get('Fakereal', 0.) == 2.
    assert fdf.get('test', 'eV') == pytest.approx(1.)
    assert fdf.get('test', with_unit=True)[0] == pytest.approx(1.)
    assert fdf.get('test', with_unit=True)[1] == 'eV'
    assert fdf.get('test',
                   unit='Ry') == pytest.approx(unit_convert('eV', 'Ry'))
    assert fdf.get('testRy') == pytest.approx(unit_convert('Ry', 'eV'))
    assert fdf.get('testRy', with_unit=True)[0] == pytest.approx(1.)
    assert fdf.get('testRy', with_unit=True)[1] == 'Ry'
    assert fdf.get('testRy', unit='Ry') == pytest.approx(1.)
    assert fdf.get('Sub') == 'sub-test'
    assert fdf.get('Third') == 'level'
    assert fdf.get('test-last', with_unit=True)[0] == pytest.approx(1.)
    assert fdf.get('test-last', with_unit=True)[1] == 'eV'

    # Currently lists are not implemented
    #assert np.allclose(fdf.get('MyList'), np.arange(3) + 1)
    #assert np.allclose(fdf.get('MyList', []), np.arange(3) + 1)

    # Read a block
    ll = open(sisl_tmp('hello', _dir)).readlines()
    ll.pop(1)
    assert fdf.get('Hello') == [l.replace('\n', '').strip() for l in ll]
コード例 #9
0
    return type(name, (obj, ), dic)


# Faster than class ... \ pass
tsgfSileSiesta = _type("tsgfSileSiesta", _gfSileSiesta)
gridSileSiesta = _type("gridSileSiesta", _gridSileSiesta, {'grid_unit': 1.})

if found_module:
    add_sile('TSHS', tshsSileSiesta)
    add_sile('onlyS', onlysSileSiesta)
    add_sile('TSDE', tsdeSileSiesta)
    add_sile('DM', dmSileSiesta)
    add_sile('HSX', hsxSileSiesta)
    add_sile('TSGF', tsgfSileSiesta)
    # These have unit-conversions
    BohrC2AngC = unit_convert('Bohr', 'Ang')**3
    Ry2eV = unit_convert('Ry', 'eV')
    add_sile(
        'RHO',
        _type("rhoSileSiesta", _gridSileSiesta,
              {'grid_unit': 1. / BohrC2AngC}))
    add_sile(
        'LDOS',
        _type("ldosSileSiesta", _gridSileSiesta,
              {'grid_unit': 1. / BohrC2AngC}))
    add_sile(
        'RHOINIT',
        _type("rhoinitSileSiesta", _gridSileSiesta,
              {'grid_unit': 1. / BohrC2AngC}))
    add_sile(
        'RHOXC',
コード例 #10
0
ファイル: binaries.py プロジェクト: fyalcin/sisl
except Exception as e:
    found_module = False

from sisl.messages import warn, SislError
from ..sile import add_sile, SileError
from .sile import SileBinSiesta

import sisl._array as _a
from sisl import Geometry, Atom, SuperCell, Grid
from sisl.unit.siesta import unit_convert
from sisl.physics.sparse import SparseOrbitalBZ
from sisl.physics import Hamiltonian, DensityMatrix, EnergyDensityMatrix
from ._help import *


Ang2Bohr = unit_convert('Ang', 'Bohr')
eV2Ry = unit_convert('eV', 'Ry')
Bohr2Ang = unit_convert('Bohr', 'Ang')
Ry2eV = unit_convert('Ry', 'eV')

__all__ = ['tshsSileSiesta', 'onlysSileSiesta', 'tsdeSileSiesta']
__all__ += ['hsxSileSiesta', 'dmSileSiesta']
__all__ += ['gridSileSiesta']
__all__ += ['tsgfSileSiesta']


class onlysSileSiesta(SileBinSiesta):
    """ Geometry and overlap matrix """

    def read_supercell(self):
        """ Returns a SuperCell object from a siesta.TSHS file """
コード例 #11
0
ファイル: basis.py プロジェクト: juijan/sisl
    def ArgumentParser(self, p=None, *args, **kwargs):
        """ Returns the arguments that is available for this Sile """
        #limit_args = kwargs.get('limit_arguments', True)
        short = kwargs.get('short', False)

        def opts(*args):
            if short:
                return args
            return [args[0]]

        # We limit the import to occur here
        import argparse

        Bohr2Ang = unit_convert('Bohr', 'Ang')
        Ry2eV = unit_convert('Bohr', 'Ang')

        # The first thing we do is adding the geometry to the NameSpace of the
        # parser.
        # This will enable custom actions to interact with the geometry in a
        # straight forward manner.
        # convert netcdf file to a dictionary
        ion_nc = PropertyDict()
        ion_nc.n = self._variable('orbnl_n')[:]
        ion_nc.l = self._variable('orbnl_l')[:]
        ion_nc.zeta = self._variable('orbnl_z')[:]
        ion_nc.pol = self._variable('orbnl_ispol')[:]
        ion_nc.orbital = self._variable('orb')[:]

        # this gets converted later
        delta = self._variable('delta')[:]
        r = aranged(ion_nc.orbital.shape[1]).reshape(1, -1) * delta.reshape(-1, 1)
        ion_nc.orbital *= r ** ion_nc.l.reshape(-1, 1) / Bohr2Ang * (3./2.)
        ion_nc.r = r * Bohr2Ang
        ion_nc.kb = PropertyDict()
        ion_nc.kb.n = self._variable('pjnl_n')[:]
        ion_nc.kb.l = self._variable('pjnl_l')[:]
        ion_nc.kb.e = self._variable('pjnl_ekb')[:] * Ry2eV
        ion_nc.kb.proj = self._variable('proj')[:]
        delta = self._variable('kbdelta')[:]
        r = aranged(ion_nc.kb.proj.shape[1]).reshape(1, -1) * delta.reshape(-1, 1)
        ion_nc.kb.proj *= r ** ion_nc.kb.l.reshape(-1, 1) / Bohr2Ang * (3./2.)
        ion_nc.kb.r = r * Bohr2Ang

        vna = self._variable('vna')
        r = aranged(vna[:].size) * vna.Vna_delta
        ion_nc.vna = PropertyDict()
        ion_nc.vna.v = vna[:] * Ry2eV * r / Bohr2Ang ** 3
        ion_nc.vna.r = r * Bohr2Ang

        # this is charge (not 1/sqrt(charge))
        chlocal = self._variable('chlocal')
        r = aranged(chlocal[:].size) * chlocal.Chlocal_delta
        ion_nc.chlocal = PropertyDict()
        ion_nc.chlocal.v = chlocal[:] * r / Bohr2Ang ** 3
        ion_nc.chlocal.r = r * Bohr2Ang

        vlocal = self._variable('reduced_vlocal')
        r = aranged(vlocal[:].size) * vlocal.Reduced_vlocal_delta
        ion_nc.vlocal = PropertyDict()
        ion_nc.vlocal.v = vlocal[:] * r / Bohr2Ang ** 3
        ion_nc.vlocal.r = r * Bohr2Ang

        if "core" in self.variables:
            # this is charge (not 1/sqrt(charge))
            core = self._variable('core')
            r = aranged(core[:].size) * core.Core_delta
            ion_nc.core = PropertyDict()
            ion_nc.core.v = core[:] * r / Bohr2Ang ** 3
            ion_nc.core.r = r * Bohr2Ang

        d = {
            "_data": ion_nc,
            "_kb_proj": False,
            "_l": True,
            "_n": True,
        }
        namespace = default_namespace(**d)

        # l-quantum number
        class lRange(argparse.Action):

            def __call__(self, parser, ns, value, option_string=None):
                value = (value
                         .replace("s", 0)
                         .replace("p", 1)
                         .replace("d", 2)
                         .replace("f", 3)
                         .replace("g", 4)
                )
                ns._l = strmap(int, value)[0]
        p.add_argument('-l',
                       action=lRange,
                       help='Denote the sub-section of l-shells that are plotted: "s,f"')

        # n quantum number
        class nRange(argparse.Action):

            def __call__(self, parser, ns, value, option_string=None):
                ns._n = strmap(int, value)[0]
        p.add_argument('-n',
                       action=nRange,
                       help='Denote the sub-section of n quantum numbers that are plotted: "2-4,6"')

        class Plot(argparse.Action):

            def __call__(self, parser, ns, value, option_string=None):
                import matplotlib.pyplot as plt

                # Retrieve values
                data = ns._data

                # We have these plots:
                #  - orbitals
                #  - projectors
                #  - chlocal
                #  - vna
                #  - vlocal
                #  - core (optional)

                # We'll plot them like this:
                #  orbitals | projectors
                #  vna + vlocal | chlocal + core
                #
                # Determine different n, l
                fig, axs = plt.subplots(2, 2)

                # Now plot different orbitals
                for n, l, zeta, pol, r, orb in zip(data.n, data.l, data.zeta,
                                                   data.pol, data.r, data.orbital):
                    if pol == 1:
                        pol = 'P'
                    else:
                        pol = ''
                    axs[0][0].plot(r, orb, label=f"n{n}l{l}Z{zeta}{pol}")
                axs[0][0].set_title("Orbitals")
                axs[0][0].set_xlabel("Distance [Ang]")
                axs[0][0].set_ylabel("Value [a.u.]")
                axs[0][0].legend()

                # plot projectors
                for n, l, e, r, proj in zip(
                        data.kb.n, data.kb.l, data.kb.e, data.kb.r, data.kb.proj):
                    axs[0][1].plot(r, proj, label=f"n{n}l{l} e={e:.5f}")
                axs[0][1].set_title("KB projectors")
                axs[0][1].set_xlabel("Distance [Ang]")
                axs[0][1].set_ylabel("Value [a.u.]")
                axs[0][1].legend()

                axs[1][0].plot(data.vna.r, data.vna.v, label='Vna')
                axs[1][0].plot(data.vlocal.r, data.vlocal.v, label='Vlocal')
                axs[1][0].set_title("Potentials")
                axs[1][0].set_xlabel("Distance [Ang]")
                axs[1][0].set_ylabel("Potential [eV]")
                axs[1][0].legend()

                axs[1][1].plot(data.chlocal.r, data.chlocal.v, label='Chlocal')
                if "core" in data:
                    axs[1][1].plot(data.core.r, data.core.v, label='core')
                axs[1][1].set_title("Charge")
                axs[1][1].set_xlabel("Distance [Ang]")
                axs[1][1].set_ylabel("Charge [Ang^3]")
                axs[1][1].legend()

                if value is None:
                    plt.show()
                else:
                    plt.savefig(value)
        p.add_argument(*opts('--plot', '-p'), action=Plot, nargs='?', metavar='FILE',
                       help='Plot the content basis set file, possibly saving plot to a file.')

        return p, namespace
コード例 #12
0
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import numpy as np

from .sile import SileCDFSiesta
from ..sile import add_sile, sile_raise_write

from sisl._internal import set_module
from sisl import Grid
from .siesta_grid import gridncSileSiesta
from sisl.unit.siesta import unit_convert

__all__ = ['tsvncSileSiesta']

_eV2Ry = unit_convert('eV', 'Ry')
_Ry2eV = 1. / _eV2Ry


@set_module("sisl.io.siesta")
class tsvncSileSiesta(gridncSileSiesta):
    """ TranSiesta potential input Grid file object

    This potential input file is mainly intended for the Hartree solution
    which complements N-electrode calculations in TranSiesta.

    See Also
    --------
    Grid.topyamg : intrinsic grid conversion to the Poisson equation
    """
    def read_grid(self, *args, **kwargs):
コード例 #13
0
from __future__ import print_function

import numpy as np

from .sile import SileCDFSiesta
from ..sile import *

from sisl import Grid
from sisl.unit.siesta import unit_convert

__all__ = ['tsvncSileSiesta']

Bohr2Ang = unit_convert('Bohr', 'Ang')
eV2Ry = unit_convert('eV', 'Ry')


class tsvncSileSiesta(SileCDFSiesta):
    """ TranSiesta potential input Grid file object

    This potential input file is mainly intended for the Hartree solution
    which complements N-electrode calculations in TranSiesta.

    See Also
    --------
    Grid.topyamg : intrinsic grid conversion to the Poisson equation
    """
    def read_grid(self, *args, **kwargs):
        """ Reads the TranSiesta potential input grid """
        # Create the grid
        na = len(self._dimension('a'))
        nb = len(self._dimension('b'))
コード例 #14
0
ファイル: test_unit_siesta.py プロジェクト: sjumzw/sisl
def test_unit_convert_f2():
    unit_convert('eV', 'kg')
コード例 #15
0
ファイル: test_unit_siesta.py プロジェクト: sjumzw/sisl
def test_unit_convert_f1():
    unit_convert('eV', 'megaerg')
コード例 #16
0
    def get(self, label, unit=None, default=None, with_unit=False):
        """ Retrieve fdf-keyword from the file

        Parameters
        ----------
        label : str
            the fdf-label to search for
        unit : str, optional
            unit of the physical quantity to return
        default : optional
            if the label is not found, this will be the returned value (default to ``None``)
        with_unit : bool, optional
            whether the physical quantity gets returned with the found unit in the fdf file.

        Returns
        -------
        value : the value of the fdf-label. If the label is a block, a `list` is returned, for
                a real value a `float` (or if the default is of `float`), for an integer, an
                `int` is returned.
        unit : if `with_unit` is true this will contain the associated unit if it is specified

        Examples
        --------
        >>> print(open(...).readlines()) # doctest: +SKIP
        LabeleV 1. eV # doctest: +SKIP
        LabelRy 1. Ry # doctest: +SKIP
        Label name # doctest: +SKIP
        FakeInt 1 # doctest: +SKIP
        %block Hello # doctest: +SKIP
        line 1 # doctest: +SKIP
        line2 # doctest: +SKIP
        %endblock # doctest: +SKIP
        >>> fdf.get('LabeleV') == 1. # default unit is eV # doctest: +SKIP
        >>> fdf.get('LabelRy') == unit.siesta.unit_convert('Ry', 'eV') # doctest: +SKIP
        >>> fdf.get('LabelRy', 'Ry') == 1. # doctest: +SKIP
        >>> fdf.get('LabelRy', with_unit=True) == (1., 'Ry') # doctest: +SKIP
        >>> fdf.get('FakeInt', default='0') == '1' # doctest: +SKIP
        >>> fdf.get('LabeleV', with_unit=True) == (1., 'eV') # doctest: +SKIP
        >>> fdf.get('Label', with_unit=True) == 'name' # no unit present on line # doctest: +SKIP
        >>> fdf.get('Hello') == ['line 1', 'line2'] # doctest: +SKIP
        """
        # Try and read a line
        value = self._read_label(label)

        # Simply return the default value if not found
        if value is None:
            return default

        # Figure out what it is
        t = self._type(value)

        # We will only do something if it is a real, int, or physical.
        # Else we simply return, as-is
        if t == 'r':
            if default is None:
                return float(value)
            t = type(default)
            return t(value)

        elif t == 'i':
            if default is None:
                return int(value)
            t = type(default)
            return t(value)

        elif t == 'p':
            value = value.split()
            if with_unit:
                # Simply return, as is. Let the user do whatever.
                return float(value[0]), value[1]
            if unit is None:
                default = unit_default(unit_group(value[1]))
            else:
                if unit_group(value[1]) != unit_group(unit):
                    raise ValueError(
                        "Requested unit for {} is not the same type. "
                        "Found/Requested {}/{}'".format(label, value[1], unit))
                default = unit
            return float(value[0]) * unit_convert(value[1], default)

        elif t == 'b':
            return value.lower() in _LOGICAL_TRUE

        return value