Beispiel #1
0
    def init_gto(self, **kw):
        """Interpret previous pySCF calculation"""
        from pyscf.lib import logger

        gto = kw['gto']
        self.stdout = sys.stdout
        self.symmetry = False
        self.symmetry_subgroup = None
        self.cart = False
        self._nelectron = gto.nelectron
        self._built = True
        self.max_memory = 20000

        self.spin = gto.spin
        #print(__name__, 'dir(gto)', dir(gto), gto.nelec)
        self.nspin = 1 if gto.spin == 0 else 2  # this can be wrong and has to be redetermined at in the mean-field class (mf)
        self.label = kw['label'] if 'label' in kw else 'pyscf'
        self.mol = gto  # Only some data must be copied, not the whole object. Otherwise, an eventual deepcopy(...) may fail.
        self.natm = self.natoms = gto.natm
        a2s = [gto.atom_symbol(ia) for ia in range(gto.natm)]
        self.sp2symbol = sorted(list(set(a2s)))
        self.nspecies = len(self.sp2symbol)
        self.atom2sp = np.empty((gto.natm), dtype=np.int64)
        for ia, sym in enumerate(a2s):
            self.atom2sp[ia] = self.sp2symbol.index(sym)

        self.sp2charge = [-999] * self.nspecies
        for ia, sp in enumerate(self.atom2sp):
            self.sp2charge[sp] = gto.atom_charge(ia)
        self.ao_log = ao_log_c().init_ao_log_gto_suggest_mesh(nao=self, **kw)
        self.atom2coord = np.zeros((self.natm, 3))
        for ia, coord in enumerate(gto.atom_coords()):
            self.atom2coord[ia, :] = coord  # must be in Bohr already?
        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]
        self.norbs = self.norbs_sc = self.atom2s[-1]
        self.ucell = 30.0 * np.eye(3)
        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._atom = gto._atom
        self.basis = gto.basis
        ### implement when needed  self.init_libnao()
        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.sp_mu2j = self.ao_log.sp_mu2j
        self.nkpoints = 1
        return self
    def init_pyscf_gto(self, gto, label='pyscf', verbose=0, **kw):
        """Interpret previous pySCF calculation"""
        from pyscf.lib import logger

        self.verbose = verbose
        self.stdout = sys.stdout
        self.symmetry = False
        self.symmetry_subgroup = None
        self.cart = False
        self._nelectron = gto.nelectron
        self._built = True
        self.max_memory = 20000

        self.label = label
        self.mol = gto  # Only some data must be copied, not the whole object. Otherwise, an eventual deepcopy(...) may fail.
        self.natm = self.natoms = gto.natm
        a2s = [gto.atom_symbol(ia) for ia in range(gto.natm)]
        self.sp2symbol = sorted(list(set(a2s)))
        self.nspecies = len(self.sp2symbol)
        self.atom2sp = np.empty((gto.natm), dtype=np.int64)
        for ia, sym in enumerate(a2s):
            self.atom2sp[ia] = self.sp2symbol.index(sym)

        self.sp2charge = [-999] * self.nspecies
        for ia, sp in enumerate(self.atom2sp):
            self.sp2charge[sp] = gto.atom_charge(ia)
        self.ao_log = ao_log_c().init_ao_log_gto_suggest_mesh(gto=gto,
                                                              nao=self,
                                                              **kw)
        self.atom2coord = np.zeros((self.natm, 3))
        for ia, coord in enumerate(gto.atom_coords()):
            self.atom2coord[ia, :] = coord  # must be in Bohr already?
        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]
        self.norbs = self.norbs_sc = self.atom2s[-1]
        self.spin = gto.spin if hasattr(gto, 'spin') else 0
        self.nspin = self.spin + 1
        self.ucell = 20.0 * np.eye(3)
        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._atom = gto._atom
        self.basis = gto.basis
        self.init_libnao()
        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
Beispiel #3
0
def ao_log_hartree_lap_libnao(ao):
    """
    Computes radial parts of Hartree potentials generated by the radial orbitals using Laplace transform (r_>, r_<)
    Uses a call to Fortran version of the calculation.
    Args: 
      self: class instance of ao_log_c
    Result:
      ao_pot with respective radial parts
  """
    from ctypes import POINTER, c_double, c_int64
    from pyscf.nao.m_ao_log import ao_log_c
    from pyscf.nao.m_libnao import libnao

    libnao.ao_hartree_lap.argtypes = (
        POINTER(c_double),  # rr(nr)
        POINTER(c_int64),  # nmult
        POINTER(c_double),  # mu2ff(nr,nmult)
        POINTER(c_int64),  # nr
        POINTER(c_int64),  # mu2j
        POINTER(c_double))  # mu2vh(nr,nmult)

    ao_pot = ao_log_c(ao_log=ao)

    rr = np.require(ao.rr, dtype=c_double, requirements='C')
    for sp in range(ao.nspecies):
        mu2j = np.require(ao.sp_mu2j[sp], dtype=c_int64, requirements='C')
        ff_rad = np.require(ao.psi_log[sp], dtype=c_double, requirements='C')
        ff_pot = np.require(ao_pot.psi_log[sp],
                            dtype=c_double,
                            requirements='CW')

        libnao.ao_hartree_lap(rr.ctypes.data_as(POINTER(c_double)),
                              c_int64(ao.sp2nmult[sp]),
                              ff_rad.ctypes.data_as(POINTER(c_double)),
                              c_int64(ao.nr),
                              mu2j.ctypes.data_as(POINTER(c_int64)),
                              ff_pot.ctypes.data_as(POINTER(c_double)))

        ao_pot.psi_log[sp] = ff_pot
        for mu, am in enumerate(ao.sp_mu2j[sp]):
            ao_pot.psi_log_rl[sp][mu, :] = ao_pot.psi_log[sp][mu, :] / (ao.rr**
                                                                        am)

    for sp in range(ao.nspecies):
        ao_pot.sp_mu2rcut[sp].fill(ao.rr[-1])
    ao_pot.sp2rcut.fill(ao.rr[-1])

    return ao_pot
Beispiel #4
0
  def init_gto(self, **kw):
    """Interpret previous pySCF calculation"""
    from pyscf.lib import logger

    gto = kw['gto']
    self.stdout = sys.stdout
    self.symmetry = False
    self.symmetry_subgroup = None
    self.cart = False
    self._nelectron = gto.nelectron
    self._built = True
    self.max_memory = 20000

    self.spin = gto.spin
    #print(__name__, 'dir(gto)', dir(gto), gto.nelec)
    self.nspin = 1 if gto.spin==0 else 2 # this can be wrong and has to be redetermined at in the mean-field class (mf)
    self.label = kw['label'] if 'label' in kw else 'pyscf'
    self.mol=gto # Only some data must be copied, not the whole object. Otherwise, an eventual deepcopy(...) may fail.
    self.natm=self.natoms = gto.natm
    a2s = [gto.atom_symbol(ia) for ia in range(gto.natm) ]
    self.sp2symbol = sorted(list(set(a2s)))
    self.nspecies = len(self.sp2symbol)
    self.atom2sp = np.empty((gto.natm), dtype=np.int64)
    for ia,sym in enumerate(a2s): self.atom2sp[ia] = self.sp2symbol.index(sym)

    self.sp2charge = [-999]*self.nspecies
    for ia,sp in enumerate(self.atom2sp): self.sp2charge[sp]=gto.atom_charge(ia)
    self.ao_log = ao_log_c().init_ao_log_gto_suggest_mesh(nao=self, **kw)
    self.atom2coord = np.zeros((self.natm, 3))
    for ia,coord in enumerate(gto.atom_coords()): self.atom2coord[ia,:]=coord # must be in Bohr already?
    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]
    self.norbs = self.norbs_sc = self.atom2s[-1]
    self.ucell = 30.0*np.eye(3)
    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._atom = gto._atom
    self.basis = gto.basis
    ### implement when needed  self.init_libnao()
    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.sp_mu2j = self.ao_log.sp_mu2j
    self.nkpoints = 1
    return self
  def init_pyscf_gto(self, gto, label='pyscf', verbose=0, **kw):
    """Interpret previous pySCF calculation"""
    from pyscf.lib import logger

    self.verbose = verbose
    self.stdout = sys.stdout
    self.symmetry = False
    self.symmetry_subgroup = None
    self.cart = False
    self._nelectron = gto.nelectron
    self._built = True
    self.max_memory = 20000

    self.label = label
    self.mol=gto # Only some data must be copied, not the whole object. Otherwise, an eventual deepcopy(...) may fail.
    self.natm=self.natoms = gto.natm
    a2s = [gto.atom_symbol(ia) for ia in range(gto.natm) ]
    self.sp2symbol = sorted(list(set(a2s)))
    self.nspecies = len(self.sp2symbol)
    self.atom2sp = np.empty((gto.natm), dtype=np.int64)
    for ia,sym in enumerate(a2s): self.atom2sp[ia] = self.sp2symbol.index(sym)

    self.sp2charge = [-999]*self.nspecies
    for ia,sp in enumerate(self.atom2sp): self.sp2charge[sp]=gto.atom_charge(ia)
    self.ao_log = ao_log_c().init_ao_log_gto_suggest_mesh(gto=gto, nao=self, **kw)
    self.atom2coord = np.zeros((self.natm, 3))
    for ia,coord in enumerate(gto.atom_coords()): self.atom2coord[ia,:]=coord # must be in Bohr already?
    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]
    self.norbs = self.norbs_sc = self.atom2s[-1]
    self.spin = gto.spin if hasattr(gto, 'spin') else 0
    self.nspin = self.spin + 1
    self.ucell = 20.0*np.eye(3)
    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._atom = gto._atom
    self.basis = gto.basis
    self.init_libnao()
    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
Beispiel #6
0
    def init_pyscf_gto(self, gto, label='pyscf', **kvargs):
        """Interpret previous pySCF calculation"""
        from pyscf.lib import logger

        self.verbose = logger.NOTE  # To be similar to Mole object...
        self.stdout = sys.stdout
        self.symmetry = False
        self.symmetry_subgroup = None

        self.label = label
        self.mol = gto  # Only some data must be copied, not the whole object. Otherwise, an eventual deepcopy(...) may fail.
        self.natm = self.natoms = gto.natm
        a2s = [gto.atom_symbol(ia) for ia in range(gto.natm)]
        self.sp2symbol = sorted(list(set(a2s)))
        self.nspecies = len(self.sp2symbol)
        self.atom2sp = np.empty((gto.natm), dtype='int64')
        for ia, sym in enumerate(a2s):
            self.atom2sp[ia] = self.sp2symbol.index(sym)

        self.sp2charge = [-999] * self.nspecies
        for ia, sp in enumerate(self.atom2sp):
            self.sp2charge[sp] = gto.atom_charge(ia)
        self.ao_log = ao_log_c().init_ao_log_gto_suggest_mesh(
            gto, self, **kvargs)
        self.atom2coord = np.zeros((self.natm, 3))
        for ia, coord in enumerate(gto.atom_coords()):
            self.atom2coord[ia, :] = coord  # must be in Bohr already?
        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]
        self.norbs = self.norbs_sc = self.atom2s[-1]
        self.nspin = 1
        self.ucell = 20.0 * np.eye(3)
        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._atom = gto._atom
        self.basis = gto.basis
        self.init_libnao()
        self.state = 'should be useful for something'
        return self
    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
    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
Beispiel #9
0
  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
Beispiel #10
0
def fireball_import(self, **kw):
    """ Calls  """
    from pyscf.nao.m_ao_log import ao_log_c
    from pyscf.nao.m_fireball_get_cdcoeffs_dat import fireball_get_ucell_cdcoeffs_dat
    #label, cd
    self.label = label = kw['fireball'] if 'fireball' in kw else 'out'
    self.cd = cd = kw['cd'] if 'cd' in kw else '.'
    #print('self.label', self.label)
    fstdout = open(self.cd + '/' + self.label, "r")
    s = fstdout.readlines()
    fstdout.close()

    try:
        fl = [l for l in s if 'tempfe =' in l][0]
        self.telec = float(fl.split(
            '=')[1]) / 11604.0 / 27.2114  # Electron temperature in Hartree
    except:
        raise RuntimeError(
            "tempfe = is not found in Fireball's standard output. Stop...")

    try:
        fl = [l for l in s if 'Fermi Level = ' in l][-1]
        self.fermi_energy = float(
            fl.split('=')[1]) / 27.2114  # Fermi energy in Hartree
    except:
        raise RuntimeError(
            "Fermi Level = is not found in Fireball's standard output. Stop..."
        )

    # Read information about species from the standard output
    ssll = [i for i, l in enumerate(s)
            if "Information for this species" in l]  # starting lines in stdout
    self.nspecies = len(ssll)
    self.sp2ion = []
    for sl in ssll:
        ion = {}
        scut = s[sl:sl + 20]
        for iline, line in enumerate(scut):
            if "- Element" in line: ion["symbol"] = line.split()[0]
            elif "- Atomic energy" in line:
                ion["atomic_energy"] = float(line.split()[0])
            elif "- Nuclear Z" in line:
                ion["z"] = int(line.split()[0])
            elif "- Atomic Mass" in line:
                ion["mass"] = float(line.split()[0])
            elif "- Number of shells" in line and "(Pseudopotential)" not in line:
                ion["npao"] = int(line.split()[0])
                ion["pao2j"] = list(map(int, scut[iline + 1].split()))
            elif "- Number of shells (Pseudopotential)" in line:
                ion["nshpp"] = int(line.split()[0])
                ion["shpp2j"] = list(map(int, scut[iline + 1].split()))
            elif "- Radial cutoffs (Pseudopotential)" in line:
                ion["rcutpp"] = float(line.split()[0])
                ion["pao2occ"] = list(map(float, scut[iline + 1].split()))
                ion["pao2rcut"] = list(map(float, scut[iline + 2].split()))
                ion["pao2fname"] = scut[iline + 3].split()
            elif "============" in line:
                break
        self.sp2ion.append(ion)
    self.sp2charge = [ion["z"] for ion in self.sp2ion]
    self.sp2valence = [sum(ion["pao2occ"]) for ion in self.sp2ion]

    # Read the radial functions from the Fdata/basis/fname.*wf*
    for sp, ion in enumerate(self.sp2ion):
        pao2npts = []
        pao2delta = []
        pao2ff = []
        for pao, [fname, j, occp] in enumerate(
                zip(ion["pao2fname"], ion["pao2j"], ion["pao2occ"])):
            f = open(self.cd + '/Fdata/' + fname, "r")
            ll = f.readlines()
            f.close()
            #print(fname.split('/')[2].split(".")[0], ll[0].split('.')[0].strip())
            #print(fname.split('/')[2].split(".")[1], ll[0].split('.')[1].strip())
            assert fname.split('/')[2].split(".")[0] == ll[0].split(
                '.')[0].strip()
            assert fname.split('/')[2].split(".")[1][0:3] == ll[0].split(
                '.')[1].strip()[0:3]
            z = int(ll[1].split()[0])
            assert z == ion["z"]
            atom_name = ll[1].split()[1].strip()
            npts = int(ll[2])
            pao2npts.append(npts)
            [rc1, rc2, occ] = list(map(float, ll[3].split()))
            assert rc1 > 0.0
            assert rc2 > 0.0
            assert occ == occp
            delta = rc1 / npts
            pao2delta.append(delta)
            assert int(ll[4]) == j
            ff = []
            for line in ll[5:]:
                ff += list(map(float, line.replace("D", "E").split()))
            pao2ff.append(ff)
            #print(z, rc1, rc2, occ, atom_name, fname, ion["pao2rcut"][pao],delta)
        self.sp2ion[sp]["pao2npts"] = pao2npts
        self.sp2ion[sp]["pao2delta"] = pao2delta
        self.sp2ion[sp]["pao2ff"] = pao2ff

    # Convert to init_ao_log_ion-compatible
    for sp, ion in enumerate(self.sp2ion):
        ioncompat = ion
        data = []
        for i, [d, ff, npts, j] in enumerate(
                zip(ion["pao2delta"], ion["pao2ff"], ion["pao2npts"],
                    ion["pao2j"])):
            rr = np.linspace(0.0, npts * d, npts)
            norm = (np.array(ff)**2 * rr**2).sum() * (rr[1] - rr[0])
            ff = [ff[0] / np.sqrt(norm)
                  ] + [f / r / np.sqrt(norm) for f, r in zip(ff, rr) if r > 0]
            data.append(np.array([rr, ff]).T)
            norm = (np.array(ff)**2 * rr**2).sum() * (rr[1] - rr[0])
            print(__name__, 'norm', norm)

        paos = {
            "npaos":
            ion["npao"],
            "delta":
            ion["pao2delta"],
            "cutoff":
            ion["pao2rcut"],
            "npts":
            ion["pao2npts"],
            "data":
            data,
            "orbital": [{
                "l": j,
                "population": occ
            } for occ, j in zip(ion["pao2occ"], ion["pao2j"])]
        }
        ioncompat["paos"] = paos
        ioncompat["vna"] = None
        ioncompat["valence"] = sum(ion["pao2occ"])
        self.sp2ion[sp] = ioncompat

    self.ao_log = ao_log_c().init_ao_log_ion(self.sp2ion, **kw)
    self.sp_mu2j = [mu2j for mu2j in self.ao_log.sp_mu2j]

    #self.ao_log.view()

    f = open(self.cd + '/answer.bas', "r")
    lsa = f.readlines()
    f.close()
    self.natm = self.natoms = int(lsa[0])  # number of atoms
    atom2znuc = [int(l.split()[0]) for l in lsa[1:]]  # atom --> nuclear charge
    self.atom2coord = [list(map(float,
                                l.split()[1:]))
                       for l in lsa[1:]]  # coordinates
    self.atom2coord = np.array(self.atom2coord)
    assert self.natoms == len(atom2znuc)
    assert self.natoms == len(self.atom2coord)
    self.atom2sp = [self.sp2charge.index(znuc)
                    for znuc in atom2znuc]  # atom --> nuclear charge
    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]
    self.norbs = self.atom2s[-1]
    self.norbs_sc = self.norbs

    self.ucell = fireball_get_ucell_cdcoeffs_dat(self.cd)

    # 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]

    nelec = 0.0
    for sp in self.atom2sp:
        nelec += self.sp2valence[sp]
    self._nelectron = nelec

    #print(self.atom2sp)
    #print(self.sp2charge)
    #print(self.atom2coord)
    #print(self.telec)
    #print(self.atom2s)
    #print(self.atom2mu_s)

    self.nspin = 1  # just a guess
    return self
Beispiel #11
0
def system_vars_gpaw(self, calc, label="gpaw", chdir='.', **kvargs):
    """
    Initialise system variables with gpaw inputs:
    Input parameters:
    -----------------
      calc: GPAW object
      kvargs: optional arguments, need a list of precise arguments somewhere
  """
    from pyscf.lib import logger
    from pyscf.lib.parameters import ELEMENTS as chemical_symbols
    from pyscf.nao.m_gpaw_wfsx import gpaw_wfsx_c
    from pyscf.nao.m_gpaw_hsx import gpaw_hsx_c
    from pyscf.nao.m_ao_log import ao_log_c
    import ase.units as units

    self.label = label
    self.chdir = '.'
    self.verbose = logger.NOTE

    self.ao_log = ao_log_c().init_ao_log_gpaw(calc.setups)
    self.atom2coord = calc.get_atoms().get_positions() / units.Bohr
    self.natm = self.natoms = len(self.atom2coord)

    self.atom2sp = np.array(
        [self.ao_log.sp2key.index(key) for key in calc.setups.id_a],
        dtype=np.int64)
    self.ucell = calc.atoms.get_cell() / units.Bohr
    self.norbs = calc.setups.nao
    self.norbs_sc = self.norbs
    self.nspin = calc.get_number_of_spins()
    self.nkpoints = 1
    self.fermi_energy = float(
        calc.get_fermi_level() /
        units.Ha)  # ensure that fermi_energy is float type
    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]

    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.sp2symbol = [chemical_symbols[Z] for Z in self.ao_log.sp2charge]
    self.sp2charge = self.ao_log.sp2charge
    self.wfsx = gpaw_wfsx_c(calc)

    self.hsx = gpaw_hsx_c(self, calc)

    #print(self.atom2coord)
    #print(self.natoms)
    #print(self.atom2sp)
    #print(self.norbs)
    #print(self.nspin)
    #print(self.nkpoints)
    #print(self.fermi_energy)
    #print(self.atom2s)
    #print(self.atom2mu_s)
    #print(self.sp2symbol)
    #print(self.sp2charge)

    self.state = 'should be useful for something'

    return self
Beispiel #12
0
        # pointer to sp_mu2rcut
        svn[i] = s + 1
        i += 1
        f = s + nrt
        svn[s:f] = conc(self.psi_log).reshape(nrt)
        s = f
        # pointer to psi_log
        svn[i] = s + 1
        i += 1
        f = s + nms
        svn[s:f] = conc(self.sp_mu2s)
        s = f
        # pointer to sp_mu2s
        svn[i] = s + 1
        # this is a terminator to simple operation
        return svn


#
#
#
if __name__ == "__main__":
    from pyscf import gto
    from pyscf.nao.m_ao_log import ao_log_c
    """ Interpreting small Gaussian calculation """
    mol = gto.M(atom='O 0 0 0; H 0 0 1; H 0 1 0',
                basis='ccpvdz')  # coordinates in Angstrom!
    ao_log = ao_log_c(gto=mol)

    print(ao_log.sp2norbs)
Beispiel #13
0
    svn[i] = self.jmx;   i+=1;
    svn[i] = conc(self.psi_log).sum(); i+=1;
    # Pointers to data
    i = 99
    s = 199
    svn[i] = s+1; i+=1; f=s+nr;  svn[s:f] = self.rr; s=f; # pointer to rr
    svn[i] = s+1; i+=1; f=s+nr;  svn[s:f] = self.pp; s=f; # pointer to pp
    svn[i] = s+1; i+=1; f=s+nsp; svn[s:f] = self.sp2nmult; s=f; # pointer to sp2nmult
    svn[i] = s+1; i+=1; f=s+nsp; svn[s:f] = self.sp2rcut;  s=f; # pointer to sp2rcut
    svn[i] = s+1; i+=1; f=s+nsp; svn[s:f] = self.sp2norbs; s=f; # pointer to sp2norbs
    svn[i] = s+1; i+=1; f=s+nsp; svn[s:f] = self.sp2charge; s=f; # pointer to sp2charge    
    svn[i] = s+1; i+=1; f=s+nmt; svn[s:f] = conc(self.sp_mu2j); s=f; # pointer to sp_mu2j
    svn[i] = s+1; i+=1; f=s+nmt; svn[s:f] = conc(self.sp_mu2rcut); s=f; # pointer to sp_mu2rcut
    svn[i] = s+1; i+=1; f=s+nrt; svn[s:f] = conc(self.psi_log).reshape(nrt); s=f; # pointer to psi_log
    svn[i] = s+1; i+=1; f=s+nms; svn[s:f] = conc(self.sp_mu2s); s=f; # pointer to sp_mu2s
    svn[i] = s+1; # this is a terminator to simple operation
    return svn

#
#
#
if __name__=="__main__":
  from pyscf import gto
  from pyscf.nao.m_ao_log import ao_log_c
  """ Interpreting small Gaussian calculation """
  mol = gto.M(atom='O 0 0 0; H 0 0 1; H 0 1 0', basis='ccpvdz') # coordinates in Angstrom!
  ao_log = ao_log_c(gto=mol)
  
  print(ao_log.sp2norbs)
  
  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
Beispiel #15
0
def system_vars_gpaw(self, **kw):
  """
    Initialise system variables with gpaw inputs:
    Input parameters:
    -----------------
      calc: GPAW object
      kvargs: optional arguments, need a list of precise arguments somewhere
  """
  from pyscf.lib import logger
  from pyscf.lib.parameters import ELEMENTS as chemical_symbols
  from pyscf.nao.m_gpaw_wfsx import gpaw_wfsx_c
  from pyscf.nao.m_gpaw_hsx import gpaw_hsx_c
  from pyscf.nao.m_ao_log import ao_log_c
  import ase.units as units

  #gpaw=calc, label="gpaw", chdir='.', **kvargs
  self.gpaw = calc = kw['gpaw']
  self.label = kw['label'] if 'label' in kw else 'gpaw'
  self.chdir = kw['cd'] if 'cd' in kw else '.'
  self.verbose = logger.NOTE
  
  self.ao_log = ao_log_c().init_ao_log_gpaw(calc.setups)
  self.atom2coord = calc.get_atoms().get_positions()/units.Bohr
  self.natm = self.natoms = len(self.atom2coord)
  
  self.atom2sp = np.array([list(self.ao_log.sp2key).index(key) for key in calc.setups.id_a], dtype=np.int64)
  self.ucell = calc.atoms.get_cell()/units.Bohr
  self.norbs = calc.setups.nao
  self.norbs_sc = self.norbs
  self.nspin = calc.get_number_of_spins()
  self.nkpoints  = 1
  self.fermi_energy = float(calc.get_fermi_level()/units.Ha) # ensure that fermi_energy is float type
  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]

  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.sp2symbol = [chemical_symbols[Z] for Z in self.ao_log.sp2charge]
  self.sp2charge = self.ao_log.sp2charge
  self.wfsx = gpaw_wfsx_c(calc)

  self.hsx = gpaw_hsx_c(self, calc)

  #print(self.atom2coord)
  #print(self.natoms)
  #print(self.atom2sp)
  #print(self.norbs)
  #print(self.nspin)
  #print(self.nkpoints)
  #print(self.fermi_energy)
  #print(self.atom2s)
  #print(self.atom2mu_s)
  #print(self.sp2symbol)
  #print(self.sp2charge)

  self.state = 'should be useful for something'

  return self