示例#1
0
 def test_log_mesh_ion(self):
   from pyscf.nao.m_siesta_ion_xml import siesta_ion_xml
   import os
   dname = os.path.dirname(os.path.abspath(__file__))
   sp2ion = []
   sp2ion.append(siesta_ion_xml(dname+'/O.ion.xml'))
   sp2ion.append(siesta_ion_xml(dname+'/H.ion.xml'))
   lm = log_mesh_c().init_log_mesh_ion(sp2ion)
   self.assertEqual(lm.nr, 1024)
   self.assertAlmostEqual(lm.rr[0], 0.0050308261951499981)
   self.assertAlmostEqual(lm.rr[-1], 11.105004591662)
   self.assertAlmostEqual(lm.pp[-1], 63.271890905445957)
   self.assertAlmostEqual(lm.pp[0], 0.028663642914905942)
示例#2
0
 def test_log_mesh_ion(self):
   from pyscf.nao.m_siesta_ion_xml import siesta_ion_xml
   import os
   dname = os.path.dirname(os.path.abspath(__file__))
   sp2ion = []
   sp2ion.append(siesta_ion_xml(dname+'/O.ion.xml'))
   sp2ion.append(siesta_ion_xml(dname+'/H.ion.xml'))
   lm = log_mesh(sp2ion=sp2ion)
   self.assertEqual(lm.nr, 1024)
   self.assertAlmostEqual(lm.rr[0], 0.0050308261951499981)
   self.assertAlmostEqual(lm.rr[-1], 11.105004591662)
   self.assertAlmostEqual(lm.pp[-1], 63.271890905445957)
   self.assertAlmostEqual(lm.pp[0], 0.028663642914905942)
示例#3
0
 def test_ao_log_sp2ion(self):
     """ This is for initializing with SIESTA radial orbitals """
     import os
     dname = os.path.dirname(os.path.abspath(__file__))
     sp2ion = []
     sp2ion.append(siesta_ion_xml(dname + '/H.ion.xml'))
     sp2ion.append(siesta_ion_xml(dname + '/O.ion.xml'))
     ao = ao_log_c().init_ao_log_ion(sp2ion, nr=512, rmin=0.0025)
     self.assertEqual(ao.nr, 512)
     self.assertAlmostEqual(ao.rr[0], 0.0025)
     self.assertAlmostEqual(ao.rr[-1], 11.105004591662)
     self.assertAlmostEqual(ao.pp[-1], 63.271890905445957)
     self.assertAlmostEqual(ao.pp[0], 0.014244003769469984)
     self.assertEqual(len(ao.sp2nmult), 2)
     self.assertEqual(len(ao.sp_mu2j[1]), 5)
     self.assertEqual(ao.sp2charge[0], 1)
示例#4
0
 def test_ao_log_sp2ion(self):
   """ This is for initializing with SIESTA radial orbitals """
   import os
   dname = os.path.dirname(os.path.abspath(__file__))
   sp2ion = []
   sp2ion.append(siesta_ion_xml(dname+'/H.ion.xml'))
   sp2ion.append(siesta_ion_xml(dname+'/O.ion.xml'))
   ao = ao_log_c().init_ao_log_ion(sp2ion, nr=512, rmin=0.0025)
   self.assertEqual(ao.nr, 512)
   self.assertAlmostEqual(ao.rr[0], 0.0025)
   self.assertAlmostEqual(ao.rr[-1], 11.105004591662)
   self.assertAlmostEqual(ao.pp[-1], 63.271890905445957)
   self.assertAlmostEqual(ao.pp[0], 0.014244003769469984)
   self.assertEqual(len(ao.sp2nmult), 2)
   self.assertEqual(len(ao.sp_mu2j[1]), 5)
   self.assertEqual(ao.sp2charge[0], 1)
示例#5
0
    def test_prdred_eval(self):
        from pyscf.nao.m_prod_talman import prod_talman_c
        from pyscf.nao.m_ao_eval_libnao import ao_eval_libnao as ao_eval
        from pyscf.nao.m_csphar_talman_libnao import csphar_talman_libnao as csphar_jt
        from pyscf.nao.m_siesta_ion_xml import siesta_ion_xml
        from pyscf.nao import ao_log_c
        from numpy import sqrt, zeros, array

        import os

        dname = os.path.dirname(os.path.abspath(__file__))
        sp2ion = []
        sp2ion.append(siesta_ion_xml(dname + '/O.ion.xml'))

        aos = ao_log_c().init_ao_log_ion(sp2ion)
        jmx = aos.jmx
        pt = prod_talman_c(aos)

        spa, spb = 0, 0
        rav, rbv, rcv = array([0.0, 0.0, -1.0]), array([0.0, 0.0,
                                                        1.0]), zeros(3)
        coord = np.array(
            [0.4, 0.1, 0.22]
        )  # Point at which we will compute the expansion and the original product
        ylma, ylmb, ylmc = csphar_jt(coord - rav, jmx), csphar_jt(
            coord - rbv, jmx), csphar_jt(coord + rcv, pt.lbdmx)
        rcs = sqrt(sum((coord + rcv)**2))

        serr = 0.0
        merr = 0.0
        nval = 0
        for la, phia in zip(aos.sp_mu2j[spa], aos.psi_log[spa]):
            fa = pt.log_interp(phia, sqrt(sum((coord - rav)**2)))
            for lb, phib in zip(aos.sp_mu2j[spb], aos.psi_log[spb]):
                fb = pt.log_interp(phib, sqrt(sum((coord - rbv)**2)))

                jtb, clbdtb, lbdtb = pt.prdred_terms(la, lb)
                jtb, clbdtb, lbdtb, rhotb = pt.prdred_libnao(
                    phib, lb, rbv, phia, la, rav, rcv)
                rhointerp = pt.log_interp(rhotb, rcs)

                for ma in range(-la, la + 1):
                    aovala = ylma[la * (la + 1) + ma] * fa
                    for mb in range(-lb, lb + 1):
                        aovalb = ylmb[lb * (lb + 1) + mb] * fb

                        ffr, m = pt.prdred_further_scalar(
                            la, ma, lb, mb, rcv, jtb, clbdtb, lbdtb, rhointerp)
                        prdval = 0.0j
                        for j, fr in enumerate(ffr):
                            prdval = prdval + fr * ylmc[j * (j + 1) + m]

                        derr = abs(aovala * aovalb - prdval)
                        nval = nval + 1
                        serr = serr + derr
                        merr = max(merr, derr)

        self.assertTrue(merr < 1.0e-05)
        self.assertTrue(serr / nval < 1.0e-06)
示例#6
0
  def test_prdred_eval(self):
    from pyscf.nao.m_prod_talman import prod_talman_c
    from pyscf.nao.m_ao_eval_libnao import ao_eval_libnao as ao_eval
    from pyscf.nao.m_csphar_talman_libnao import csphar_talman_libnao as csphar_jt
    from pyscf.nao.m_siesta_ion_xml import siesta_ion_xml
    from pyscf.nao import ao_log_c
    from numpy import sqrt, zeros, array

    import os
    
    dname = os.path.dirname(os.path.abspath(__file__))
    sp2ion = []
    sp2ion.append(siesta_ion_xml(dname+'/O.ion.xml'))

    aos = ao_log_c().init_ao_log_ion(sp2ion)
    jmx = aos.jmx
    pt = prod_talman_c(aos)

    spa,spb=0,0
    rav,rbv,rcv = array([0.0,0.0,-1.0]),array([0.0,0.0,1.0]), zeros(3)
    coord = np.array([0.4, 0.1, 0.22]) # Point at which we will compute the expansion and the original product
    ylma,ylmb,ylmc = csphar_jt(coord-rav, jmx), csphar_jt(coord-rbv, jmx),csphar_jt(coord+rcv, pt.lbdmx)
    rcs = sqrt(sum((coord+rcv)**2))
 
    serr = 0.0
    merr = 0.0
    nval = 0
    for la,phia in zip(aos.sp_mu2j[spa], aos.psi_log[spa]):
      fa = pt.log_interp(phia, sqrt(sum((coord-rav)**2)))
      for lb,phib in zip(aos.sp_mu2j[spb], aos.psi_log[spb]):
        fb = pt.log_interp(phib, sqrt(sum((coord-rbv)**2)))

        jtb,clbdtb,lbdtb=pt.prdred_terms(la,lb)
        jtb,clbdtb,lbdtb,rhotb = pt.prdred_libnao(phib,lb,rbv,phia,la,rav,rcv)
        rhointerp = pt.log_interp(rhotb, rcs)
        
        for ma in range(-la,la+1):
          aovala = ylma[la*(la+1)+ma]*fa
          for mb in range(-lb,lb+1):
            aovalb = ylmb[lb*(lb+1)+mb]*fb

            ffr,m = pt.prdred_further_scalar(la,ma,lb,mb,rcv,jtb,clbdtb,lbdtb,rhointerp)
            prdval = 0.0j
            for j,fr in enumerate(ffr): prdval = prdval + fr*ylmc[j*(j+1)+m]

            derr = abs(aovala*aovalb-prdval)
            nval = nval + 1
            serr = serr + derr
            merr = max(merr, derr)

    self.assertTrue(merr<1.0e-05)
    self.assertTrue(serr/nval<1.0e-06)
示例#7
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
示例#8
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
示例#9
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
示例#10
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
示例#11
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