Esempio n. 1
0
 def test_zeta_Z_deprecate(self):
     rf = r_f(6)
     r = np.linspace(0, 6, 999).reshape(-1, 3)
     o = AtomicOrbital(l=1, m=1, spherical=rf)
     with pytest.deprecated_call():
         assert o.Z == o.zeta
     with pytest.deprecated_call():
         o = AtomicOrbital(l=1, m=1, spherical=rf, Z=1)
Esempio n. 2
0
 def test_phi1(self):
     rf = r_f(6)
     r = np.linspace(0, 6, 999).reshape(-1, 3)
     for l in range(5):
         so = SphericalOrbital(l, rf)
         for m in range(-l, l + 1):
             o = AtomicOrbital(l=l, m=m, spherical=rf)
             assert np.allclose(so.psi(r, m), o.psi(r))
Esempio n. 3
0
 def test_init4(self):
     rf = r_f(6)
     o1 = AtomicOrbital(2, 1, 0, 1, True, rf)
     o2 = AtomicOrbital('pzP', rf)
     o3 = AtomicOrbital('pzZP', rf)
     o4 = AtomicOrbital('pzZ1P', rf)
     o5 = AtomicOrbital('2pzZ1P', rf)
     assert o1 == o2
     assert o1 == o3
     assert o1 == o4
     assert o1 == o5
Esempio n. 4
0
 def test_pickle1(self):
     import pickle as p
     rf = r_f(6)
     o0 = AtomicOrbital(2, 1, 0, 1, True, rf, tag='hello', q0=1.)
     o1 = AtomicOrbital(l=1, m=0, Z=1, P=False, spherical=rf)
     p0 = p.dumps(o0)
     p1 = p.dumps(o1)
     l0 = p.loads(p0)
     l1 = p.loads(p1)
     assert o0 == l0
     assert o1 == l1
     assert o0 != l1
     assert o1 != l0
Esempio n. 5
0
 def test_radial1(self):
     rf = r_f(6)
     r = np.linspace(0, 6, 100)
     for l in range(5):
         so = SphericalOrbital(l, rf)
         sor = so.radial(r)
         for m in range(-l, l + 1):
             o = AtomicOrbital(l=l, m=m, spherical=rf)
             assert np.allclose(sor, o.radial(r))
             o.set_radial(rf[0], rf[1])
             assert np.allclose(sor, o.radial(r))
Esempio n. 6
0
 def test_init1(self):
     rf = r_f(6)
     a = []
     a.append(AtomicOrbital(2, 1, 0, 1, True, rf))
     a.append(AtomicOrbital(l=1, m=0, Z=1, P=True, spherical=rf))
     f = interp.interp1d(rf[0], rf[1], fill_value=(0., 0.), bounds_error=False, kind='cubic')
     a.append(AtomicOrbital(l=1, m=0, Z=1, P=True, spherical=f))
     a.append(AtomicOrbital('pzP', f))
     a.append(AtomicOrbital('pzP', rf))
     a.append(AtomicOrbital('2pzP', rf))
     for i in range(len(a) - 1):
         for j in range(i+1, len(a)):
             assert a[i] == a[j] and a[i].equal(a[j], psi=True, radial=True)
    def read_data(self, as_dataarray=False):
        r""" Returns data associated with the PDOS file

        For spin-polarized calculations the returned values are up/down, orbitals, energy.
        For non-collinear calculations the returned values are sum/x/y/z, orbitals, energy.

        Parameters
        ----------
        as_dataarray: bool, optional
           If True the returned PDOS is a `xarray.DataArray` with energy, spin
           and orbital information as coordinates in the data.
           The geometry, unit and Fermi level are stored as attributes in the
           DataArray.

        Returns
        -------
        geom : Geometry instance with positions, atoms and orbitals. The
               orbitals of these atoms are `AtomicOrbital` instances.
        E : the energies at which the PDOS has been evaluated at (if the Fermi-level is present the energies
            are shifted to :math:`E - E_F = 0`, this will *only* be done from Siesta 4.0.2 and later).
        PDOS : an array of DOS, for non-polarized calculations it has dimension ``(atom.no, len(E))``,
               else it has dimension ``(nspin, atom.no, len(E))``.
        DataArray : if `as_dataarray` is True, only this data array is returned, in this case
               all data can be post-processed using the `xarray` selection routines.
        """
        # Get the element-tree
        ET = ElementTree('pdos', self.file)
        root = ET.getroot()

        # Get number of orbitals
        nspin = int(root.find('nspin').text)
        # Try and find the fermi-level
        Ef = root.find('fermi_energy')
        E = arrayd(list(map(float, root.find('energy_values').text.split())))
        if Ef is not None:
            Ef = float(Ef.text)
            E -= Ef
        ne = len(E)

        # All coordinate, atoms and species data
        xyz = []
        atoms = []
        atom_species = []

        def ensure_size(ia):
            while len(atom_species) <= ia:
                atom_species.append(None)
                xyz.append(None)

        def ensure_size_orb(ia, i):
            while len(atoms) <= ia:
                atoms.append([])
            while len(atoms[ia]) <= i:
                atoms[ia].append(None)

        if nspin == 4:

            def process(D):
                tmp = np.empty(D.shape[0], D.dtype)
                tmp[:] = D[:, 3]
                D[:, 3] = D[:, 0] - D[:, 1]
                D[:, 0] = D[:, 0] + D[:, 1]
                D[:, 1] = D[:, 2]
                D[:, 2] = tmp[:]
                return D
        else:

            def process(D):
                return D

        if as_dataarray:
            import xarray as xr
            if nspin == 1:
                spin = ['sum']
            elif nspin == 2:
                spin = ['up', 'down']
            elif nspin == 4:
                spin = ['sum', 'x', 'y' 'z']

            # Dimensions of the PDOS data-array
            dims = ['E', 'spin', 'n', 'l', 'm', 'zeta', 'polarization']

            shape = (ne, nspin, 1, 1, 1, 1, 1)

            def to(o, DOS):
                # Coordinates for this dataarray
                coords = [E, spin, [o.n], [o.l], [o.m], [o.Z], [o.P]]

                return xr.DataArray(data=process(DOS).reshape(shape),
                                    dims=dims,
                                    coords=coords,
                                    name='PDOS')

        else:

            def to(o, DOS):
                return process(DOS)

        D = []
        for orb in root.findall('orbital'):

            # Short-hand function to retrieve integers for the attributes
            def oi(name):
                return int(orb.get(name))

            # Get indices
            ia = oi('atom_index') - 1
            i = oi('index') - 1

            species = orb.get('species')

            # Create the atomic orbital
            try:
                Z = oi('Z')
            except:
                try:
                    Z = PeriodicTable().Z(species)
                except:
                    # Unknown
                    Z = -1

            try:
                P = orb.get('P') == 'true'
            except:
                P = False

            ensure_size(ia)
            xyz[ia] = list(map(float, orb.get('position').split()))
            atom_species[ia] = Z

            # Construct the atomic orbital
            O = AtomicOrbital(n=oi('n'), l=oi('l'), m=oi('m'), Z=oi('z'), P=P)

            # We know that the index is far too high. However,
            # this ensures a consecutive orbital
            ensure_size_orb(ia, i)
            atoms[ia][i] = O

            # it is formed like : spin-1, spin-2 (however already in eV)
            DOS = arrayd(list(map(float,
                                  orb.find('data').text.split()))).reshape(
                                      -1, nspin)

            if as_dataarray:
                if len(D) == 0:
                    D = to(O, DOS)
                else:
                    D = D.combine_first(to(O, DOS))
            else:
                D.append(process(DOS))

        # Now we need to parse the data
        # First reduce the atom
        atoms = [[o for o in a if o] for a in atoms]
        atoms = Atoms([Atom(Z, os) for Z, os in zip(atom_species, atoms)])
        geom = Geometry(arrayd(xyz) * Bohr2Ang, atoms)

        if as_dataarray:
            # Add attributes
            D.attrs['geometry'] = geom
            D.attrs['units'] = '1/eV'
            if Ef is None:
                D.attrs['Ef'] = 'Unknown'
            else:
                D.attrs['Ef'] = Ef

            return D

        return geom, E, np.moveaxis(np.stack(D, axis=0), 2, 0)
Esempio n. 8
0
 def test_init5(self):
     with pytest.raises(ValueError):
         AtomicOrbital(5, 5, 0)
Esempio n. 9
0
 def test_init3(self):
     rf = r_f(6)
     for l in range(5):
         a = AtomicOrbital(l=l, m=0, spherical=rf)
         a.name()
         a.name(True)
         str(a)
         a = AtomicOrbital(l=l, m=0, P=True, spherical=rf, tag='hello')
         a.name()
         a.name(True)
         str(a)
Esempio n. 10
0
 def test_init2(self):
     assert AtomicOrbital('pzP') == AtomicOrbital(n=2, l=1, m=0, P=True)
Esempio n. 11
0
 def test_init5(self):
     AtomicOrbital(5, 5, 0)
Esempio n. 12
0
 def test_init2(self):
     AtomicOrbital('pzP')
Esempio n. 13
0
 def test_zeta_Z_deprecate(self):
     rf = r_f(6)
     r = np.linspace(0, 6, 999).reshape(-1, 3)
     o = AtomicOrbital(l=1, m=1, spherical=rf)
     assert o.Z == o.zeta