def init_ao_log_ion(self, sp2ion, **kw): """ Reads data from a previous SIESTA calculation, interpolates the orbitals on a single log mesh. """ from pyscf.nao.m_log_interp import log_interp_c from pyscf.nao.m_siesta_ion_interp import siesta_ion_interp from pyscf.nao.m_siesta_ion_add_sp2 import _siesta_ion_add_sp2 from pyscf.nao.m_spline_diff2 import spline_diff2 from pyscf.nao.m_spline_interp import spline_interp import numpy as np self.init_log_mesh_ion(sp2ion, **kw) #print(__name__, self.nr) #print(__name__, self.rr) #print(__name__, self.rmax) #print(__name__, self.rmin) #print(__name__, self.kmax) self.interp_rr,self.interp_pp = log_interp_c(self.rr), log_interp_c(self.pp) _siesta_ion_add_sp2(self, sp2ion) # adds the fields for counting, .nspecies etc. self.jmx = max([mu2j.max() for mu2j in self.sp_mu2j]) self.sp2norbs = np.array([mu2s[self.sp2nmult[sp]] for sp,mu2s in enumerate(self.sp_mu2s)], dtype='int64') self.sp2ion = sp2ion rr = self.rr nr = len(rr) #print(__name__, 'self.jmx', self.jmx) #print(__name__, 'self.sp2norbs', self.sp2norbs) #print(__name__, 'self.sp2norbs', dir(self)) #print(__name__, 'self.sp_mu2j', self.sp_mu2j) #print(__name__, 'self.sp_mu2rcut', self.sp_mu2rcut) #print(__name__, 'self.sp_mu2s', self.sp_mu2s) self.psi_log = siesta_ion_interp(rr, sp2ion, 1) self.psi_log_rl = siesta_ion_interp(rr, sp2ion, 0) self.sp2vna = [] # Interpolate a Neutral-atom potential V_NA(r) for each specie for ion in sp2ion: vna = np.zeros(nr) if ion["vna"] is not None: h,dat = ion["vna"]["delta"], ion["vna"]["data"][0][:, 1] yy_diff2 = spline_diff2(h, dat, 0.0, 1.0e301) for ir,r in enumerate(rr): vna[ir] = spline_interp(h, dat, yy_diff2, r) self.sp2vna.append(vna*0.5) # given in Rydberg? self.sp_mu2rcut = [ np.array(ion["paos"]["cutoff"]) for ion in sp2ion] self.sp2rcut = np.array([np.amax(rcuts) for rcuts in self.sp_mu2rcut]) self.sp2charge = [int(ion['z']) for ion in self.sp2ion] self.sp2valence = [int(ion['valence']) for ion in self.sp2ion] #call sp2ion_to_psi_log(sv%sp2ion, sv%rr, sv%psi_log) #call init_psi_log_rl(sv%psi_log, sv%rr, sv%uc%mu_sp2j, sv%uc%sp2nmult, sv%psi_log_rl) #call sp2ion_to_core(sv%sp2ion, sv%rr, sv%core_log, sv%sp2has_core, sv%sp2rcut_core) return self
def init_ao_log_ion(self, **kw): """ Reads data from a previous SIESTA calculation, interpolates the Pseudo-Atomic Orbitals on a single log mesh. """ from pyscf.nao.m_log_interp import log_interp_c from pyscf.nao.m_spline_diff2 import spline_diff2 from pyscf.nao.m_spline_interp import spline_interp self.interp_rr,self.interp_pp = log_interp_c(self.rr), log_interp_c(self.pp) sp2ion = self.sp2ion = kw['sp2ion'] fname = kw['fname'] if 'fname' in kw else 'paos' if fname in sp2ion[0]: self.siesta_ion_interp(sp2ion, fname=fname) self.sp2vna = [None]*len(sp2ion) # Interpolate a Neutral-Atom potential V_NA(r) for each specie self.sp2rcut_vna = np.zeros(len(sp2ion)) for isp, ion in enumerate(sp2ion): if "vna" not in ion.keys(): continue if ion["vna"] is None: continue self.sp2rcut_vna[isp] = ion["vna"]["cutoff"] h,dat = ion["vna"]["delta"][0], ion["vna"]["data"][0][:,1] d2 = spline_diff2(h, dat, 0.0, 1.0e301) self.sp2vna[isp] = np.array([0.5*spline_interp(h, dat, d2, r) for r in self.rr]) # given in Rydberg in sp2ion self.sp2chlocal = [None]*len(sp2ion) # Interpolate the atomic charges for each specie self.sp2rcut_chlocal = np.zeros(len(sp2ion)) for isp, ion in enumerate(sp2ion): if "chlocal" not in ion.keys(): continue if ion["chlocal"] is None: continue self.sp2rcut_chlocal[isp] = ion["chlocal"]["cutoff"] h,dat = ion["chlocal"]["delta"][0], ion["chlocal"]["data"][0][:,1] d2 = spline_diff2(h, dat, 0.0, 1.0e301) self.sp2chlocal[isp] = np.array([spline_interp(h, dat, d2, r) for r in self.rr]) return self
def siesta_ion_interp(rr, sp2ion, fj=1): """ Interpolation of orbitals given on linear grid in the ion dictionary """ nr = len(rr) assert(nr>2) nsp = len(sp2ion) nmultmax = max([len(sp2ion[sp]["paos"]["orbital"]) for sp in range(nsp)]) smr2ro_log = [] #numpy.zeros((nsp,nmultmax,nr), dtype='float64', order='F') for sp,ion in enumerate(sp2ion): nmu = len(sp2ion[sp]["paos"]["orbital"]) smr2ro_log.append(np.zeros((nmu,nr))) for mu,dat in enumerate(ion["paos"]["data"]): #print(__name__, 'dat.shape', dat.shape, dat[0:4,0], dat[0:4,1]) j, h = ion["paos"]['orbital'][mu]['l'], ion["paos"]["delta"][mu] yy_diff2 = spline_diff2(h, dat[:, 1], 0.0, 1.0e301) for ir in range(nr): smr2ro_log[sp][mu,ir] = spline_interp(h,dat[:, 1],yy_diff2,rr[ir])*(rr[ir]**(fj*j)) return smr2ro_log
def siesta_ion_interp(rr, sp2ion, fj=1): """ Interpolation of orbitals given on linear grid in the ion dictionary """ nr = len(rr) assert (nr > 2) nsp = len(sp2ion) nmultmax = max([len(sp2ion[sp]["paos"]["orbital"]) for sp in range(nsp)]) smr2ro_log = [ ] #numpy.zeros((nsp,nmultmax,nr), dtype='float64', order='F') for sp, ion in enumerate(sp2ion): nmu = len(sp2ion[sp]["paos"]["orbital"]) smr2ro_log.append(np.zeros((nmu, nr))) for mu, dat in enumerate(ion["paos"]["data"]): #print(__name__, 'dat.shape', dat.shape, dat[0:4,0], dat[0:4,1]) j, h = ion["paos"]['orbital'][mu]['l'], ion["paos"]["delta"][mu] yy_diff2 = spline_diff2(h, dat[:, 1], 0.0, 1.0e301) for ir in range(nr): smr2ro_log[sp][mu, ir] = spline_interp( h, dat[:, 1], yy_diff2, rr[ir]) * (rr[ir]**(fj * j)) return smr2ro_log
def siesta_ion_interp(self, sp2ion, fname='paos'): from pyscf.nao.m_get_sp_mu2s import get_sp_mu2s from pyscf.nao.m_spline_diff2 import spline_diff2 from pyscf.nao.m_spline_interp import spline_interp """ Interpolation of orbitals or projectors given on linear grid in the ion dictionary rr : is the grid on which we want the function sp2ion : list of dictionaries fname : function name, can be 'paos' or 'kbs' """ rr, nr, nsp = self.rr, len(self.rr), len(sp2ion) pname = {'paos': 'orbital', 'kbs': 'projector'}[fname] self.nspecies = len(sp2ion) self.sp2nmult = np.zeros(self.nspecies, dtype='int64') self.sp_mu2rcut = [None]*self.nspecies self.sp_mu2j = [None]*self.nspecies self.sp_mu2s = [None]*self.nspecies self.sp2norbs = np.zeros(self.nspecies, dtype='int64') self.sp2rcut = np.zeros(self.nspecies) self.sp2charge = np.zeros(self.nspecies, dtype='int64') self.sp2valence = np.zeros(self.nspecies, dtype='int64') for isp, ion in enumerate(sp2ion): if ion[fname] is None: continue self.sp2nmult[isp] = len(ion[fname]['data']) self.sp_mu2rcut[isp] = np.array(ion[fname]["cutoff"]) self.sp_mu2j[isp] = np.array([o["l"] for o in ion[fname][pname]], dtype='int64') mu2s = np.zeros(self.sp2nmult[isp]+1, dtype='int64') for mu in range(self.sp2nmult[isp]): mu2s[mu+1] = sum(2*self.sp_mu2j[isp][0:mu+1]+1) self.sp_mu2s[isp] = mu2s self.sp2norbs[isp] = self.sp_mu2s[isp][self.sp2nmult[isp]] self.sp2rcut[isp] = np.amax(self.sp_mu2rcut[isp]) self.sp2charge[isp] = int(self.sp2ion[isp]['z']) self.sp2valence[isp] = int(self.sp2ion[isp]['valence']) self.jmx = max([mu2j.max() for mu2j in self.sp_mu2j if mu2j is not None]) if fname=='kbs': self.sp_mu2vkb = [None]*self.nspecies for isp, ion in enumerate(sp2ion): if ion[fname] is None: continue self.sp_mu2vkb[isp] = np.array([0.5*p['ref_energy'] for p in ion['kbs']['projector'] ]) self.psi_log_rl = [None]*self.nspecies for isp, ion in enumerate(sp2ion): if ion[fname] is None: continue ff = np.zeros((len(ion[fname][pname]), nr)) for mu,(h,dat) in enumerate(zip(ion[fname]["delta"],ion[fname]["data"])): diff2 = spline_diff2(h, dat[:,1], 0.0, 1.0e301) for i, r in enumerate(rr): ff[mu,i] = spline_interp(h, dat[:,1], diff2, r) self.psi_log_rl[isp] = ff self.psi_log = [None]*self.nspecies for isp, (mu2ff, mu2j) in enumerate(zip(self.psi_log_rl, self.sp_mu2j)): if mu2ff is None: continue gg = np.zeros((len(mu2j), nr)) for mu,(ff,j) in enumerate(zip(mu2ff,mu2j)): gg[mu] = ff*(rr**j) self.psi_log[isp] = gg
def init_ao_log_ion(self, sp2ion, **kw): """ Reads data from a previous SIESTA calculation, interpolates the orbitals on a single log mesh. """ from pyscf.nao.m_log_interp import log_interp_c from pyscf.nao.m_siesta_ion_interp import siesta_ion_interp from pyscf.nao.m_siesta_ion_add_sp2 import _siesta_ion_add_sp2 from pyscf.nao.m_spline_diff2 import spline_diff2 from pyscf.nao.m_spline_interp import spline_interp import numpy as np self.init_log_mesh_ion(sp2ion, **kw) #print(__name__, self.nr) #print(__name__, self.rr) #print(__name__, self.rmax) #print(__name__, self.rmin) #print(__name__, self.kmax) self.interp_rr, self.interp_pp = log_interp_c(self.rr), log_interp_c( self.pp) _siesta_ion_add_sp2( self, sp2ion) # adds the fields for counting, .nspecies etc. self.jmx = max([mu2j.max() for mu2j in self.sp_mu2j]) self.sp2norbs = np.array( [mu2s[self.sp2nmult[sp]] for sp, mu2s in enumerate(self.sp_mu2s)], dtype='int64') self.sp2ion = sp2ion rr = self.rr nr = len(rr) #print(__name__, 'self.jmx', self.jmx) #print(__name__, 'self.sp2norbs', self.sp2norbs) #print(__name__, 'self.sp2norbs', dir(self)) #print(__name__, 'self.sp_mu2j', self.sp_mu2j) #print(__name__, 'self.sp_mu2rcut', self.sp_mu2rcut) #print(__name__, 'self.sp_mu2s', self.sp_mu2s) self.psi_log = siesta_ion_interp(rr, sp2ion, 1) self.psi_log_rl = siesta_ion_interp(rr, sp2ion, 0) self.sp2vna = [ ] # Interpolate a Neutral-atom potential V_NA(r) for each specie for ion in sp2ion: vna = np.zeros(nr) if ion["vna"] is not None: h, dat = ion["vna"]["delta"], ion["vna"]["data"][0][:, 1] yy_diff2 = spline_diff2(h, dat, 0.0, 1.0e301) for ir, r in enumerate(rr): vna[ir] = spline_interp(h, dat, yy_diff2, r) self.sp2vna.append(vna * 0.5) # given in Rydberg? self.sp_mu2rcut = [np.array(ion["paos"]["cutoff"]) for ion in sp2ion] self.sp2rcut = np.array([np.amax(rcuts) for rcuts in self.sp_mu2rcut]) self.sp2charge = [int(ion['z']) for ion in self.sp2ion] self.sp2valence = [int(ion['valence']) for ion in self.sp2ion] #call sp2ion_to_psi_log(sv%sp2ion, sv%rr, sv%psi_log) #call init_psi_log_rl(sv%psi_log, sv%rr, sv%uc%mu_sp2j, sv%uc%sp2nmult, sv%psi_log_rl) #call sp2ion_to_core(sv%sp2ion, sv%rr, sv%core_log, sv%sp2has_core, sv%sp2rcut_core) return self