def lambda_check_overlap(self, overlap_funct=overlap_am, **kvargs): from pyscf.nao.m_ao_log import comp_moments """ Check the equality (p) = [p,ab] S^ab, i.e. scalar moments are recomputed with inversed vertex from the ao's overlap """ me = ao_matelem_c(self.ao_log) sp2mom0,sp2mom1 = comp_moments(self) mael,mxel=[],[] for sp,[lab,mom0_ref] in enumerate(zip(self.sp2lambda,sp2mom0)): ab = overlap_funct(me,sp,np.zeros(3),sp,np.zeros(3),**kvargs) mom0 = einsum('lab,ab->l', lab,ab) mael.append((abs(mom0-mom0_ref)).sum()/mom0.size); mxel.append((abs(mom0-mom0_ref)).max()) return mael,mxel
def lambda_check_coulomb(self): """ Check the equality (p|q)<q,cd> = [p,ab] <ab|q>(q|r)<r|cd> """ me = ao_matelem_c(self) mael,mxel=[],[] for sp,[pab,lab] in enumerate(zip(self.sp2vertex, self.sp2lambda)): pq = me.coulomb_am(sp,np.zeros(3), sp, np.zeros(3)) pcd_ref = einsum('pq,qab->pab', pq, pab) abcd = einsum('abq,qcd->abcd', einsum('pab,pq->abq', pab,pq), pab) pcd = einsum('lab,abcd->lcd', lab, abcd) mael.append(abs(pcd-pcd_ref).sum()/pcd.size); mxel.append(abs(pcd-pcd_ref).max()) return mael,mxel
def overlap_check(prod_log, overlap_funct=overlap_ni, **kvargs): """ Computes the allclose(), mean absolute error and maximal error of the overlap reproduced by the (local) vertex.""" from pyscf.nao.m_ao_matelem import ao_matelem_c me = ao_matelem_c(prod_log.rr, prod_log.pp).init_one_set(prod_log.ao_log) sp2mom0,sp2mom1 = prod_log.comp_moments() mael,mxel,acl=[],[],[] R0 = np.array([0.0,0.0,0.0]) for sp,[vertex,mom0] in enumerate(zip(prod_log.sp2vertex,sp2mom0)): oo_ref = overlap_funct(me,sp,R0,sp,R0,**kvargs) oo = np.einsum('pjk,p->jk', vertex, mom0) ac = np.allclose(oo_ref, oo, atol=prod_log.tol_loc*10, rtol=prod_log.tol_loc) mae = abs(oo_ref-oo).sum()/oo.size mxe = abs(oo_ref-oo).max() acl.append(ac); mael.append(mae); mxel.append(mxe) if not ac: print('overlap check:', sp, mae, mxe, prod_log.tol_loc) return mael,mxel,acl
def dipole_check(sv, prod_log, dipole_funct=dipole_ni, **kvargs): """ Computes the allclose(), mean absolute error and maximal error of the dipoles reproduced by the (local) vertex. """ from pyscf.nao.m_ao_matelem import ao_matelem_c from pyscf.nao.m_ao_log import comp_moments me = ao_matelem_c(prod_log.ao_log) sp2mom0,sp2mom1 = comp_moments(prod_log) mael,mxel,acl=[],[],[] for atm,[sp,coord] in enumerate(zip(sv.atom2sp,sv.atom2coord)): dip_moms = np.einsum('j,k->jk', sp2mom0[sp],coord)+sp2mom1[sp] koo2dipme = np.einsum('pab,pc->cab', prod_log.sp2vertex[sp],dip_moms) dipme_ref = dipole_funct(me,sp,coord,sp,coord, **kvargs) ac = np.allclose(dipme_ref, koo2dipme, atol=prod_log.tol_loc*10, rtol=prod_log.tol_loc) mae = abs(koo2dipme-dipme_ref).sum()/koo2dipme.size mxe = abs(koo2dipme-dipme_ref).max() acl.append(ac); mael.append(mae); mxel.append(mxe) if not ac: print('dipole check:', sp, mae, mxe, prod_log.tol_loc) return mael,mxel,acl
from pyscf.nao import system_vars_c, prod_log_c, conv_yzx2xyz_c, get_atom2bas_s, ao_matelem_c from pyscf.nao.m_system_vars import diag_check, overlap_check from pyscf.nao.m_prod_log import dipole_check from pyscf import gto import numpy as np mol = gto.M(atom='O 0 0 0; H 0 0 1; H 0 1 0', basis='ccpvdz') # coordinates in Angstrom! sv = system_vars_c().init_pyscf_gto(mol) prod_log = prod_log_c().init_prod_log_dp(sv.ao_log) print(prod_log.overlap_check()) print(prod_log.lambda_check_overlap()) print(dipole_check(sv, prod_log)) print('builtin simple center checks done \n') me = ao_matelem_c(prod_log) errmx = 0 for ia1 in range(sv.natoms): for ia2 in range(sv.natoms): n1, n2 = [sv.atom2s[ia + 1] - sv.atom2s[ia] for ia in [ia1, ia2]] mol3 = gto.Mole_pure(atom=[sv._atom[ia1], sv._atom[ia2]], basis=sv.basis, unit='bohr').build() bs = get_atom2bas_s(mol3._bas) ss = (bs[0], bs[1], bs[0], bs[1], bs[1], bs[2], bs[1], bs[2]) tci_ao = mol3.intor('cint2e_sph', shls_slice=ss).reshape(n1, n1, n2, n2) tci_ao = conv_yzx2xyz_c(mol3).conv_yzx2xyz_4d(tci_ao, 'pyscf2nao', ss)
grids = build_3dgrid(me, sp1,np.array(R1), sp2,np.array(R2), **kvargs) pf = grids.weights * ao_eval(me.ao2, np.array(R1), sp1, grids.coords) qv = ao_eval(me.ao2_hartree, np.array(R2), sp2, grids.coords) pq2eri = np.einsum('pr,qr->pq',pf,qv) return pq2eri if __name__=="__main__": from pyscf.nao import system_vars_c, ao_matelem_c from pyscf.nao.prod_log import prod_log as prod_log_c from pyscf.nao.m_eri2c import eri2c sv = system_vars_c(label='siesta') R0 = sv.atom2coord[0,:] prod_log = prod_log_c(ao_log=sv.ao_log) print(prod_log.sp2norbs) me_prod = ao_matelem_c(prod_log) vc_am = me_prod.coulomb_am(0, R0, 0, R0) print(vc_am.shape, vc_am.max(), vc_am.min()) vc_ni = eri2c(me_prod, 0, R0, 0, R0, level=5) print(vc_ni.shape, vc_ni.max(), vc_ni.min()) print(abs(vc_ni-vc_am).sum() / vc_am.size, abs(vc_ni-vc_am).max())
if __name__=='__main__': """ Computes coulomb overlaps (ab|cd) between 4 orbitals sitting on the same atom with GTO and compares to NAO """ from pyscf.nao import system_vars_c, prod_log_c, ao_matelem_c import numpy as np from timeit import default_timer as timer from scipy.sparse import csr_matrix mol = gto.M(atom='O 0 0 0; H 0 0 1; H 0 1 0', basis='ccpvtz') # coordinates in Angstrom! sv = system_vars_c(gto=mol) t1s = timer() prod_log = prod_log_c(sv.ao_log, tol=1e-5) print(timer() - t1s) t1s = timer() me = ao_matelem_c(prod_log) print(timer() - t1s) m1 = gto.Mole_pure() for ia,sp in enumerate(sv.atom2sp): pab2v=prod_log.sp2vertex[sp] n = pab2v.shape[1] pab_shape = [pab2v.shape[0], pab2v.shape[1]*pab2v.shape[2]] pab2v_csr = csr_matrix(pab2v.reshape(pab_shape)) print(pab2v_csr.getnnz(), pab_shape[0]*pab_shape[1]) t1s = timer() coul=me.coulomb_am(sp, [0.0,0.0,0.0], sp, [0.0,0.0,0.0]) t1s = timer() #fci1c = np.einsum('abq,qcd->abcd', np.einsum('pab,pq->abq', pab2v, coul), pab2v) qab2tci = coul*pab2v_csr