예제 #1
0
  def __init__(self, nao, **kw):
    from pyscf.nao.m_fireball_get_HS_dat import fireball_get_HS_dat
    from pyscf.nao.m_siesta2blanko_csr import _siesta2blanko_csr
    
    self.cd = nao.cd
    atom2s = nao.atom2s
    
    self.fname = fname = kw['fname'] if 'fname' in kw else 'HS.dat'   
    i2aoao,i2h,i2s,i2x = fireball_get_HS_dat(self.cd, fname)
    ni = len(i2aoao)
    i2a = np.zeros((ni), dtype=int)
    i2b = np.zeros((ni), dtype=int)
    for i,aoao in enumerate(i2aoao):
      i2a[i] = atom2s[aoao[0]-1]+aoao[1]-1
      i2b[i] = atom2s[aoao[2]-1]+aoao[3]-1

    m = atom2s[-1]
    n = atom2s[-1]
    self.spin2h4_csr = [csr_matrix((i2h, (i2a, i2b)), shape=(m, n))]
    self.s4_csr = csr_matrix((i2s, (i2a, i2b)), shape=(m, n))
    self.x4_csr = [
       csr_matrix((i2x[:,0], (i2a, i2b)), shape=(m, n)),
       csr_matrix((i2x[:,1], (i2a, i2b)), shape=(m, n)),
       csr_matrix((i2x[:,2], (i2a, i2b)), shape=(m, n)) ]

    self.orb_sc2orb_uc = np.array(list(range(atom2s[-1])), dtype=int)

    o2m = nao.get_orb2m()
    _siesta2blanko_csr(o2m, self.s4_csr, self.orb_sc2orb_uc)

    _siesta2blanko_csr(o2m, self.spin2h4_csr[0], self.orb_sc2orb_uc)
예제 #2
0
    def init_siesta_xml(self, **kw):
        from pyscf.nao.m_siesta_xml import siesta_xml
        from pyscf.nao.m_siesta_wfsx import siesta_wfsx_c
        from pyscf.nao.m_siesta_ion_xml import siesta_ion_xml
        from pyscf.nao.m_siesta_hsx import siesta_hsx_c
        from timeit import default_timer as timer
        """
      Initialise system var using only the siesta files (siesta.xml in particular is needed)

      System variables:
      -----------------
        label (string): calculation label
        chdir (string): calculation directory
        xml_dict (dict): information extracted from the xml siesta output, see m_siesta_xml
        wfsx: class use to extract the information about wavefunctions, see m_siesta_wfsx
        hsx: class to store a sparse representation of hamiltonian and overlap, see m_siesta_hsx
        norbs_sc (integer): number of orbital
        ucell (array, float): unit cell
        sp2ion (list): species to ions, list of the species associated to the information from the ion files, see m_siesta_ion_xml
        ao_log: Atomic orbital on an logarithmic grid, see m_ao_log
        atom2coord (array, float): array containing the coordinates of each atom.
        natm, natoms (integer): number of atoms
        norbs (integer): number of orbitals
        nspin (integer): number of spin
        nkpoints (integer): number of kpoints
        fermi_energy (float): Fermi energy
        atom2sp (list): atom to specie, list associating the atoms to their specie number
        atom2s: atom -> first atomic orbital in a global orbital counting
        atom2mu_s: atom -> first multiplett (radial orbital) in a global counting of radial orbitals
        sp2symbol (list): list associating the species to their symbol
        sp2charge (list): list associating the species to their charge
        state (string): this is an internal information on the current status of the class
    """
        #label='siesta', cd='.', verbose=0,

        self.label = label = kw['label'] if 'label' in kw else 'siesta'
        self.cd = cd = kw['cd'] if 'cd' in kw else '.'
        self.verbose = verbose = kw['verbose'] if 'verbose' in kw else 0
        self.xml_dict = siesta_xml(cd + '/' + self.label + '.xml')
        self.wfsx = siesta_wfsx_c(**kw)
        self.hsx = siesta_hsx_c(fname=cd + '/' + self.label + '.HSX', **kw)
        self.norbs_sc = self.wfsx.norbs if self.hsx.orb_sc2orb_uc is None else len(
            self.hsx.orb_sc2orb_uc)
        self.ucell = self.xml_dict["ucell"]
        ##### The parameters as fields
        self.sp2ion = []
        for sp in self.wfsx.sp2strspecie:
            self.sp2ion.append(siesta_ion_xml(cd + '/' + sp + '.ion.xml'))

        _siesta_ion_add_sp2(self, self.sp2ion)
        self.ao_log = ao_log_c().init_ao_log_ion(self.sp2ion)

        self.atom2coord = self.xml_dict['atom2coord']
        self.natm = self.natoms = len(self.xml_dict['atom2sp'])
        self.norbs = self.wfsx.norbs
        self.nspin = self.wfsx.nspin
        self.nkpoints = self.wfsx.nkpoints
        self.fermi_energy = self.xml_dict['fermi_energy']

        strspecie2sp = {}
        # initialise a dictionary with species string as key
        # associated to the specie number
        for sp, strsp in enumerate(self.wfsx.sp2strspecie):
            strspecie2sp[strsp] = sp

        # list of atoms associated to them specie number
        self.atom2sp = np.empty((self.natm), dtype=np.int64)
        for o, atom in enumerate(self.wfsx.orb2atm):
            self.atom2sp[atom - 1] = strspecie2sp[self.wfsx.orb2strspecie[o]]

        self.atom2s = np.zeros((self.natm + 1), dtype=np.int64)
        for atom, sp in enumerate(self.atom2sp):
            self.atom2s[atom +
                        1] = self.atom2s[atom] + self.ao_log.sp2norbs[sp]

        # atom2mu_s list of atom associated to them multipletts (radial orbitals)
        self.atom2mu_s = np.zeros((self.natm + 1), dtype=np.int64)
        for atom, sp in enumerate(self.atom2sp):
            self.atom2mu_s[atom +
                           1] = self.atom2mu_s[atom] + self.ao_log.sp2nmult[sp]

        orb2m = self.get_orb2m()
        _siesta2blanko_csr(orb2m, self.hsx.s4_csr, self.hsx.orb_sc2orb_uc)

        for s in range(self.nspin):
            _siesta2blanko_csr(orb2m, self.hsx.spin2h4_csr[s],
                               self.hsx.orb_sc2orb_uc)

        #t1 = timer()
        for k in range(self.nkpoints):
            for s in range(self.nspin):
                for n in range(self.norbs):
                    _siesta2blanko_denvec(orb2m, self.wfsx.x[k, s, n, :, :])
        #t2 = timer(); print(t2-t1, 'rsh wfsx'); t1 = timer()

        self.sp2symbol = [
            str(ion['symbol'].replace(' ', '')) for ion in self.sp2ion
        ]
        self.sp2charge = self.ao_log.sp2charge
        self.init_libnao()
        self.state = 'should be useful for something'

        # Trying to be similar to mole object from pySCF
        self._xc_code = 'LDA,PZ'  # estimate how ?
        self._nelectron = self.hsx.nelec
        self.cart = False
        self.spin = self.nspin - 1
        self.stdout = sys.stdout
        self.symmetry = False
        self.symmetry_subgroup = None
        self._built = True
        self.max_memory = 20000
        self.incore_anyway = False
        self.nbas = self.atom2mu_s[-1]  # total number of radial orbitals
        self.mu2orb_s = np.zeros((self.nbas + 1), dtype=np.int64)
        for sp, mu_s in zip(self.atom2sp, self.atom2mu_s):
            for mu, j in enumerate(self.ao_log.sp_mu2j[sp]):
                self.mu2orb_s[mu_s + mu +
                              1] = self.mu2orb_s[mu_s + mu] + 2 * j + 1

        self._atom = [(self.sp2symbol[sp], list(self.atom2coord[ia, :]))
                      for ia, sp in enumerate(self.atom2sp)]
        return self
예제 #3
0
    def init_ase_atoms(self, Atoms, **kvargs):
        """ Initialise system vars using siesta file and Atom object from ASE."""
        from pyscf.nao.m_siesta_xml import siesta_xml
        from pyscf.nao.m_siesta_wfsx import siesta_wfsx_c
        from pyscf.nao.m_siesta_ion_xml import siesta_ion_xml
        from pyscf.nao.m_siesta_hsx import siesta_hsx_c

        self.label = 'ase' if label is None else label
        self.xml_dict = siesta_xml(self.label)
        self.wfsx = siesta_wfsx_c(self.label)
        self.hsx = siesta_hsx_c(self.label, **kvargs)
        self.norbs_sc = self.wfsx.norbs if self.hsx.orb_sc2orb_uc is None else len(
            self.hsx.orb_sc2orb_uc)

        try:
            import ase
        except:
            warn('no ASE installed: try via siesta.xml')
            self.init_siesta_xml(**kvargs)

        self.Atoms = Atoms

        ##### The parameters as fields
        self.sp2ion = []
        species = []
        for sp in Atoms.get_chemical_symbols():
            if sp not in species:
                species.append(sp)
                self.sp2ion.append(siesta_ion_xml(sp + '.ion.xml'))

        _add_mu_sp2(self, self.sp2ion)
        self.sp2ao_log = ao_log_c(self.sp2ion)

        self.natm = self.natoms = Atoms.get_positions().shape[0]
        self.norbs = self.wfsx.norbs
        self.nspin = self.wfsx.nspin
        self.nkpoints = self.wfsx.nkpoints

        strspecie2sp = {}
        for sp in range(len(self.wfsx.sp2strspecie)):
            strspecie2sp[self.wfsx.sp2strspecie[sp]] = sp

        self.atom2sp = np.empty((self.natoms), dtype='int64')
        for i, sp in enumerate(Atoms.get_chemical_symbols()):
            self.atom2sp[i] = strspecie2sp[sp]

        self.atom2s = np.zeros((sv.natm + 1), dtype=np.int64)
        for atom, sp in enumerate(sv.atom2sp):
            atom2s[atom + 1] = atom2s[atom] + self.ao_log.sp2norbs[sp]

        self.atom2mu_s = np.zeros((self.natm + 1), dtype=np.int64)
        for atom, sp in enumerate(self.atom2sp):
            self.atom2mu_s[atom +
                           1] = self.atom2mu_s[atom] + self.ao_log.sp2nmult[sp]

        orb2m = get_orb2m(self)
        _siesta2blanko_csr(orb2m, self.hsx.s4_csr, self.hsx.orb_sc2orb_uc)

        for s in range(self.nspin):
            _siesta2blanko_csr(orb2m, self.hsx.spin2h4_csr[s],
                               self.hsx.orb_sc2orb_uc)

        for k in range(self.nkpoints):
            for s in range(self.nspin):
                for n in range(self.norbs):
                    _siesta2blanko_denvec(orb2m, self.wfsx.X[k, s, n, :, :])

        self.sp2symbol = [
            str(ion['symbol'].replace(' ', '')) for ion in self.sp2ion
        ]
        self.sp2charge = self.ao_log.sp2charge
        self.nbas = self.atom2mu_s[-1]  # total number of radial orbitals
        self.mu2orb_s = np.zeros((self.nbas + 1), dtype=np.int64)
        for sp, mu_s in zip(self.atom2sp, self.atom2mu_s):
            for mu, j in enumerate(self.ao_log.sp_mu2j[sp]):
                self.mu2orb_s[mu_s + mu +
                              1] = self.mu2orb_s[mu_s + mu] + 2 * j + 1
        self.state = 'should be useful for something'
        return self
예제 #4
0
파일: nao.py 프로젝트: chrinide/pyscf
  def init_label(self, **kw):
    from pyscf.nao.m_siesta_xml import siesta_xml
    from pyscf.nao.m_siesta_wfsx import siesta_wfsx_c
    from pyscf.nao.m_siesta_ion_xml import siesta_ion_xml
    from pyscf.nao.m_siesta_hsx import siesta_hsx_c
    from timeit import default_timer as timer
    """
      Initialise system var using only the siesta files (siesta.xml in particular is needed)

      System variables:
      -----------------
        label (string): calculation label
        chdir (string): calculation directory
        xml_dict (dict): information extracted from the xml siesta output, see m_siesta_xml
        wfsx: class use to extract the information about wavefunctions, see m_siesta_wfsx
        hsx: class to store a sparse representation of hamiltonian and overlap, see m_siesta_hsx
        norbs_sc (integer): number of orbital
        ucell (array, float): unit cell
        sp2ion (list): species to ions, list of the species associated to the information from the ion files, see m_siesta_ion_xml
        ao_log: Atomic orbital on an logarithmic grid, see m_ao_log
        atom2coord (array, float): array containing the coordinates of each atom.
        natm, natoms (integer): number of atoms
        norbs (integer): number of orbitals
        nspin (integer): number of spin
        nkpoints (integer): number of kpoints
        fermi_energy (float): Fermi energy
        atom2sp (list): atom to specie, list associating the atoms to their specie number
        atom2s: atom -> first atomic orbital in a global orbital counting
        atom2mu_s: atom -> first multiplett (radial orbital) in a global counting of radial orbitals
        sp2symbol (list): list associating the species to their symbol
        sp2charge (list): list associating the species to their charge
        state (string): this is an internal information on the current status of the class
    """

    #label='siesta', cd='.', verbose=0, **kvargs

    self.label = label = kw['label'] if 'label' in kw else 'siesta'
    self.cd = cd = kw['cd'] if 'cd' in kw else '.'
    self.xml_dict = siesta_xml(cd+'/'+self.label+'.xml')
    self.wfsx = siesta_wfsx_c(**kw)
    self.hsx = siesta_hsx_c(fname=cd+'/'+self.label+'.HSX', **kw)
    self.norbs_sc = self.wfsx.norbs if self.hsx.orb_sc2orb_uc is None else len(self.hsx.orb_sc2orb_uc)
    self.ucell = self.xml_dict["ucell"]
    ##### The parameters as fields     
    self.sp2ion = []
    for sp in self.wfsx.sp2strspecie: self.sp2ion.append(siesta_ion_xml(cd+'/'+sp+'.ion.xml'))

    _siesta_ion_add_sp2(self, self.sp2ion)
    self.ao_log = ao_log_c().init_ao_log_ion(self.sp2ion, **kw)

    self.atom2coord = self.xml_dict['atom2coord']
    self.natm=self.natoms=len(self.xml_dict['atom2sp'])
    self.norbs  = self.wfsx.norbs 
    self.nspin  = self.wfsx.nspin
    self.nkpoints  = self.wfsx.nkpoints
    self.fermi_energy = self.xml_dict['fermi_energy']

    strspecie2sp = {}
    # initialise a dictionary with species string as key
    # associated to the specie number
    for sp,strsp in enumerate(self.wfsx.sp2strspecie): strspecie2sp[strsp] = sp
    
    # list of atoms associated to them specie number
    self.atom2sp = np.empty((self.natm), dtype=np.int64)
    for o,atom in enumerate(self.wfsx.orb2atm):
      self.atom2sp[atom-1] = strspecie2sp[self.wfsx.orb2strspecie[o]]

    self.atom2s = np.zeros((self.natm+1), dtype=np.int64)
    for atom,sp in enumerate(self.atom2sp):
        self.atom2s[atom+1]=self.atom2s[atom]+self.ao_log.sp2norbs[sp]

    # atom2mu_s list of atom associated to them multipletts (radial orbitals)
    self.atom2mu_s = np.zeros((self.natm+1), dtype=np.int64)
    for atom,sp in enumerate(self.atom2sp):
        self.atom2mu_s[atom+1]=self.atom2mu_s[atom]+self.ao_log.sp2nmult[sp]
    
    orb2m = self.get_orb2m()
    _siesta2blanko_csr(orb2m, self.hsx.s4_csr, self.hsx.orb_sc2orb_uc)

    for s in range(self.nspin):
      _siesta2blanko_csr(orb2m, self.hsx.spin2h4_csr[s], self.hsx.orb_sc2orb_uc)
    
    #t1 = timer()
    for k in range(self.nkpoints):
      for s in range(self.nspin):
        for n in range(self.norbs):
          _siesta2blanko_denvec(orb2m, self.wfsx.x[k,s,n,:,:])
    #t2 = timer(); print(t2-t1, 'rsh wfsx'); t1 = timer()

    
    self.sp2symbol = [str(ion['symbol'].replace(' ', '')) for ion in self.sp2ion]
    self.sp2charge = self.ao_log.sp2charge
    self.state = 'should be useful for something'

    # Trying to be similar to mole object from pySCF 
    self._xc_code   = 'LDA,PZ' # estimate how ? 
    self._nelectron = self.hsx.nelec
    self.cart = False
    self.spin = self.nspin-1
    self.stdout = sys.stdout
    self.symmetry = False
    self.symmetry_subgroup = None
    self._built = True 
    self.max_memory = 20000
    self.incore_anyway = False
    self.nbas = self.atom2mu_s[-1] # total number of radial orbitals
    self.mu2orb_s = np.zeros((self.nbas+1), dtype=np.int64)
    for sp,mu_s in zip(self.atom2sp,self.atom2mu_s):
      for mu,j in enumerate(self.ao_log.sp_mu2j[sp]): self.mu2orb_s[mu_s+mu+1] = self.mu2orb_s[mu_s+mu] + 2*j+1
        
    self._atom = [(self.sp2symbol[sp], list(self.atom2coord[ia,:])) for ia,sp in enumerate(self.atom2sp)]
    return self
예제 #5
0
파일: nao.py 프로젝트: zzy2014/pyscf
    def init_wfsx_fname(self, **kw):
        """  Initialise system var starting with a given WFSX file  """
        from pyscf.nao.m_tools import read_xyz
        from pyscf.nao.m_fermi_energy import fermi_energy
        from pyscf.nao.m_siesta_xml import siesta_xml
        from pyscf.nao.m_siesta_wfsx import siesta_wfsx_c
        from pyscf.nao.m_siesta_ion_xml import siesta_ion_xml
        from pyscf.nao.m_siesta_hsx import siesta_hsx_c
        from timeit import default_timer as timer

        self.label = label = kw['label'] if 'label' in kw else 'siesta'
        self.cd = cd = kw['cd'] if 'cd' in kw else '.'

        fname = kw['wfsx_fname'] if 'wfsx_fname' in kw else None
        self.wfsx = siesta_wfsx_c(fname=fname, **kw)
        self.hsx = siesta_hsx_c(fname=cd + '/' + self.label + '.HSX', **kw)
        self.norbs_sc = self.wfsx.norbs if self.hsx.orb_sc2orb_uc is None else len(
            self.hsx.orb_sc2orb_uc)
        self.natm = self.natoms = max(self.wfsx.orb2atm)
        self.norbs = len(self.wfsx.orb2atm)
        self.norbs_sc = self.norbs
        self.nspin = self.wfsx.nspin
        self.ucell = 30.0 * np.eye(3)
        self.nkpoints = self.wfsx.nkpoints

        self.sp2ion = []
        for sp in self.wfsx.sp2strspecie:
            self.sp2ion.append(siesta_ion_xml(cd + '/' + sp + '.ion.xml'))
        _siesta_ion_add_sp2(self, self.sp2ion)
        #self.ao_log = ao_log_c().init_ao_log_ion(self.sp2ion, **kw)
        self.ao_log = ao_log(sp2ion=self.sp2ion, **kw)
        self.kb_log = ao_log(sp2ion=self.sp2ion, fname='kbs', **kw)

        strspecie2sp = {}
        # initialise a dictionary with species string as a key associated to the specie number
        for sp, strsp in enumerate(self.wfsx.sp2strspecie):
            strspecie2sp[strsp] = sp

        # list of atoms associated to them specie number
        self.atom2sp = np.empty((self.natm), dtype=np.int64)
        for o, atom in enumerate(self.wfsx.orb2atm):
            self.atom2sp[atom - 1] = strspecie2sp[self.wfsx.orb2strspecie[o]]

        self.atom2s = np.zeros((self.natm + 1), dtype=np.int64)
        for atom, sp in enumerate(self.atom2sp):
            self.atom2s[atom +
                        1] = self.atom2s[atom] + self.ao_log.sp2norbs[sp]

        # atom2mu_s list of atom associated to them multipletts (radial orbitals)
        self.atom2mu_s = np.zeros((self.natm + 1), dtype=np.int64)
        for atom, sp in enumerate(self.atom2sp):
            self.atom2mu_s[atom +
                           1] = self.atom2mu_s[atom] + self.ao_log.sp2nmult[sp]

        self.nbas = self.atom2mu_s[-1]  # total number of radial orbitals
        self.mu2orb_s = np.zeros((self.nbas + 1), dtype=np.int64)
        for sp, mu_s in zip(self.atom2sp, self.atom2mu_s):
            for mu, j in enumerate(self.ao_log.sp_mu2j[sp]):
                self.mu2orb_s[mu_s + mu +
                              1] = self.mu2orb_s[mu_s + mu] + 2 * j + 1

        #t1 = timer()
        orb2m = self.get_orb2m()
        _siesta2blanko_csr(orb2m, self.hsx.s4_csr, self.hsx.orb_sc2orb_uc)

        for s in range(self.nspin):
            _siesta2blanko_csr(orb2m, self.hsx.spin2h4_csr[s],
                               self.hsx.orb_sc2orb_uc)

        for k in range(self.nkpoints):
            for s in range(self.nspin):
                for n in range(self.norbs):
                    _siesta2blanko_denvec(orb2m, self.wfsx.x[k, s, n, :, :])
        #t2 = timer(); print(t2-t1, 'rsh wfsx'); t1 = timer()

        # Get self.atom2coord via .xml or .xyz files
        try:
            self.xml_dict = siesta_xml(cd + '/' + self.label + '.xml')
            self.atom2coord = self.xml_dict['atom2coord']
            self.fermi_energy = self.xml_dict['fermi_energy']
        except:
            print(__name__,
                  'no siesta.xml file --> excepting with siesta.xyz file')
            a2sym, a2coord = read_xyz(cd + '/' + self.label + '.xyz')
            self.atom2coord = a2coord * 1.8897259886
            # cross-check of loaded .xyz file:
            atom2sym_ref = np.array([
                self.sp2ion[sp]['symbol'].strip()
                for atom, sp in enumerate(self.atom2sp)
            ])
            for ia, (a1, a2) in enumerate(zip(a2sym, atom2sym_ref)):
                if a1 != a2:
                    raise RuntimeError('.xyz wrong? %d %s %s ' % (ia, a1, a2))
            self.fermi_energy = fermi_energy(self.wfsx.ksn2e, self.hsx.nelec,
                                             self.hsx.telec)

        self.sp2symbol = [
            str(ion['symbol'].replace(' ', '')) for ion in self.sp2ion
        ]
        self.sp2charge = self.ao_log.sp2charge

        # Trying to be similar to mole object from pySCF
        self._xc_code = 'LDA,PZ'  # estimate how ?
        self._nelectron = self.hsx.nelec
        self.cart = False
        self.spin = self.nspin - 1
        self.stdout = sys.stdout
        self.symmetry = False
        self.symmetry_subgroup = None
        self._built = True
        self.max_memory = 20000
        self.incore_anyway = False
        self._atom = [(self.sp2symbol[sp], list(self.atom2coord[ia, :]))
                      for ia, sp in enumerate(self.atom2sp)]
        self.state = 'should be useful for something'
        return self
예제 #6
0
  def init_ase_atoms(self, Atoms, **kvargs):
    """ Initialise system vars using siesta file and Atom object from ASE."""
    from pyscf.nao.m_siesta_xml import siesta_xml
    from pyscf.nao.m_siesta_wfsx import siesta_wfsx_c
    from pyscf.nao.m_siesta_ion_xml import siesta_ion_xml
    from pyscf.nao.m_siesta_hsx import siesta_hsx_c

    self.label = 'ase' if label is None else label
    self.xml_dict = siesta_xml(self.label)
    self.wfsx = siesta_wfsx_c(self.label)
    self.hsx = siesta_hsx_c(self.label, **kvargs)
    self.norbs_sc = self.wfsx.norbs if self.hsx.orb_sc2orb_uc is None else len(self.hsx.orb_sc2orb_uc)

    try:
      import ase
    except:
      warn('no ASE installed: try via siesta.xml')
      self.init_siesta_xml(**kvargs)

    self.Atoms = Atoms
   
    ##### The parameters as fields     
    self.sp2ion = []
    species = []
    for sp in Atoms.get_chemical_symbols():
      if sp not in species:
        species.append(sp)
        self.sp2ion.append(siesta_ion_xml(sp+'.ion.xml'))
    
    _add_mu_sp2(self, self.sp2ion)
    self.sp2ao_log = ao_log_c(self.sp2ion)
  
    self.natm=self.natoms= Atoms.get_positions().shape[0]
    self.norbs  = self.wfsx.norbs
    self.nspin  = self.wfsx.nspin
    self.nkpoints  = self.wfsx.nkpoints

    strspecie2sp = {}
    for sp in range(len(self.wfsx.sp2strspecie)): strspecie2sp[self.wfsx.sp2strspecie[sp]] = sp
    
    self.atom2sp = np.empty((self.natoms), dtype='int64')
    for i, sp in enumerate(Atoms.get_chemical_symbols()):
      self.atom2sp[i] = strspecie2sp[sp]
    
    self.atom2s = np.zeros((sv.natm+1), dtype=np.int64)
    for atom,sp in enumerate(sv.atom2sp): atom2s[atom+1]=atom2s[atom]+self.ao_log.sp2norbs[sp]

    self.atom2mu_s = np.zeros((self.natm+1), dtype=np.int64)
    for atom,sp in enumerate(self.atom2sp): self.atom2mu_s[atom+1]=self.atom2mu_s[atom]+self.ao_log.sp2nmult[sp]

    orb2m = get_orb2m(self)
    _siesta2blanko_csr(orb2m, self.hsx.s4_csr, self.hsx.orb_sc2orb_uc)

    for s in range(self.nspin):
      _siesta2blanko_csr(orb2m, self.hsx.spin2h4_csr[s], self.hsx.orb_sc2orb_uc)
    
    for k in range(self.nkpoints):
      for s in range(self.nspin):
        for n in range(self.norbs):
          _siesta2blanko_denvec(orb2m, self.wfsx.X[k,s,n,:,:])

    self.sp2symbol = [str(ion['symbol'].replace(' ', '')) for ion in self.sp2ion]
    self.sp2charge = self.ao_log.sp2charge
    self.nbas = self.atom2mu_s[-1] # total number of radial orbitals
    self.mu2orb_s = np.zeros((self.nbas+1), dtype=np.int64)
    for sp,mu_s in zip(self.atom2sp,self.atom2mu_s):
      for mu,j in enumerate(self.ao_log.sp_mu2j[sp]): self.mu2orb_s[mu_s+mu+1] = self.mu2orb_s[mu_s+mu] + 2*j+1
    self.state = 'should be useful for something'
    return self