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