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