def type2_by_shell(mol, shls, ecpatm_id, ecpbas): ish, jsh = shls li = mol.bas_angular(ish) npi = mol.bas_nprim(ish) nci = mol.bas_nctr(ish) ai = mol.bas_exp(ish) ci = mol._libcint_ctr_coeff(ish) icart = (li + 1) * (li + 2) // 2 lj = mol.bas_angular(jsh) npj = mol.bas_nprim(jsh) ncj = mol.bas_nctr(jsh) aj = mol.bas_exp(jsh) cj = mol._libcint_ctr_coeff(jsh) jcart = (lj + 1) * (lj + 2) // 2 rc = mol.atom_coord(ecpatm_id) rcb = rc - mol.bas_coord(jsh) r_cb = numpy.linalg.norm(rcb) rca = rc - mol.bas_coord(ish) r_ca = numpy.linalg.norm(rca) #rs, ws = radi.treutler(99) rs, ws = radi.gauss_chebyshev(99) i_fac_cache = cache_fac(li, rca) j_fac_cache = cache_fac(lj, rcb) g1 = numpy.zeros((nci, ncj, icart, jcart)) for lc in range(5): # up to g function ecpbasi = ecpbas[ecpbas[:, ANG_OF] == lc] if len(ecpbasi) == 0: continue ur = rad_part(mol, ecpbasi, rs) * ws idx = abs(ur) > 1e-80 rur = numpy.array( [ur[idx] * rs[idx]**lab for lab in range(li + lj + 1)]) fi = facs_rad(mol, ish, lc, r_ca, rs)[:, :, idx].copy() fj = facs_rad(mol, jsh, lc, r_cb, rs)[:, :, idx].copy() angi = facs_ang(type2_ang_part(li, lc, -rca), li, lc, i_fac_cache) angj = facs_ang(type2_ang_part(lj, lc, -rcb), lj, lc, j_fac_cache) for ic in range(nci): for jc in range(ncj): rad_all = numpy.einsum('pr,ir,jr->pij', rur, fi[ic], fj[jc]) for i1 in range(li + 1): for j1 in range(lj + 1): g1[ic, jc] += numpy.einsum('pq,imp,jmq->ij', rad_all[i1 + j1], angi[i1], angj[j1]) g1 *= (numpy.pi * 4)**2 gsph = numpy.empty((nci, ncj, li * 2 + 1, lj * 2 + 1)) for ic in range(nci): for jc in range(ncj): tmp = c2s_bra(lj, g1[ic, jc].T.copy()) gsph[ic, jc] = c2s_bra(li, tmp.T.copy()) return gsph.transpose(0, 2, 1, 3).reshape(nci * (li * 2 + 1), -1)
def test_prune(self): grid = gen_grid.Grids(h2o) grid.prune = gen_grid.sg1_prune grid.atom_grid = { "H": (10, 50), "O": (10, 50), } grid.build(with_non0tab=False) self.assertAlmostEqual(numpy.linalg.norm(grid.coords), 202.17732600266302, 9) self.assertAlmostEqual(numpy.linalg.norm(grid.weights), 442.54536463517167, 9) grid.prune = gen_grid.nwchem_prune grid.build(with_non0tab=False) self.assertAlmostEqual(numpy.linalg.norm(grid.coords), 149.55023044392638, 9) self.assertAlmostEqual(numpy.linalg.norm(grid.weights), 586.36841824004455, 9) z = 16 rad, dr = radi.gauss_chebyshev(50) angs = gen_grid.sg1_prune(z, rad, 434, radii=radi.SG1RADII) self.assertAlmostEqual(lib.fp(angs), -291.0794420982329, 9) angs = gen_grid.nwchem_prune(z, rad, 434, radii=radi.BRAGG_RADII) self.assertAlmostEqual(lib.fp(angs), -180.12023039394498, 9) angs = gen_grid.nwchem_prune(z, rad, 26, radii=radi.BRAGG_RADII) self.assertTrue(numpy.all(angs == 26))
def test_bessel(self): rs = radi.gauss_chebyshev(99)[0] bessel1 = numpy.empty(8) for i, x in enumerate(rs): bessel0 = scipy.special.sph_in(7, x)[0] * numpy.exp(-x) libecp.ECPsph_ine(bessel1.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(7), ctypes.c_double(x)) self.assertTrue(numpy.allclose(bessel0, bessel1))
def test_bessel(self): rs = radi.gauss_chebyshev(99)[0] bessel1 = numpy.empty(8) for i,x in enumerate(rs): bessel0 = scipy.special.sph_in(7, x)[0] * numpy.exp(-x) libecp.ECPsph_ine(bessel1.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(7), ctypes.c_double(x)) self.assertTrue(numpy.allclose(bessel0, bessel1))
def type2_by_shell(mol, shls, ecpatm_id, ecpbas): ish, jsh = shls li = mol.bas_angular(ish) npi = mol.bas_nprim(ish) nci = mol.bas_nctr(ish) ai = mol.bas_exp(ish) ci = mol.bas_ctr_coeff(ish) icart = (li+1) * (li+2) // 2 lj = mol.bas_angular(jsh) npj = mol.bas_nprim(jsh) ncj = mol.bas_nctr(jsh) aj = mol.bas_exp(jsh) cj = mol.bas_ctr_coeff(jsh) jcart = (lj+1) * (lj+2) // 2 rc = mol.atom_coord(ecpatm_id) rcb = rc - mol.bas_coord(jsh) r_cb = numpy.linalg.norm(rcb) rca = rc - mol.bas_coord(ish) r_ca = numpy.linalg.norm(rca) #rs, ws = radi.treutler(99) rs, ws = radi.gauss_chebyshev(99) i_fac_cache = cache_fac(li, rca) j_fac_cache = cache_fac(lj, rcb) g1 = numpy.zeros((nci,ncj,icart,jcart)) for lc in range(5): # up to g function ecpbasi = ecpbas[ecpbas[:,ANG_OF] == lc] if len(ecpbasi) == 0: continue ur = rad_part(mol, ecpbasi, rs) * ws idx = abs(ur) > 1e-40 rur = numpy.array([ur[idx] * rs[idx]**lab for lab in range(li+lj+1)]) fi = facs_rad(mol, ish, lc, r_ca, rs)[:,:,idx].copy() fj = facs_rad(mol, jsh, lc, r_cb, rs)[:,:,idx].copy() angi = facs_ang(type2_ang_part(li, lc, -rca), li, lc, i_fac_cache) angj = facs_ang(type2_ang_part(lj, lc, -rcb), lj, lc, j_fac_cache) for ic in range(nci): for jc in range(ncj): rad_all = numpy.einsum('pr,ir,jr->pij', rur, fi[ic], fj[jc]) for i1 in range(li+1): for j1 in range(lj+1): g1[ic,jc] += numpy.einsum('pq,imp,jmq->ij', rad_all[i1+j1], angi[i1], angj[j1]) g1 *= (numpy.pi*4)**2 gsph = numpy.empty((nci,ncj,li*2+1,lj*2+1)) for ic in range(nci): for jc in range(ncj): tmp = c2s_bra(lj, g1[ic,jc].T.copy()) gsph[ic,jc] = c2s_bra(li, tmp.T.copy()) return gsph.transpose(0,2,1,3).reshape(nci*(li*2+1),-1)
def test_gauss_chebyshev(self): rs0, ws0 = radi.gauss_chebyshev(99) rs = numpy.empty_like(rs0) ws = numpy.empty_like(ws0) libecp.ECPgauss_chebyshev(rs.ctypes.data_as(ctypes.c_void_p), ws.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(99)) self.assertTrue(numpy.allclose(rs0, rs)) self.assertTrue(numpy.allclose(ws0, ws))
def test_rad_part(self): rs, ws = radi.gauss_chebyshev(99) ur0 = rad_part(mol, mol._ecpbas, rs) ecpshls = numpy.array(numpy.append(numpy.arange(len(mol._ecpbas)),-1), dtype=numpy.int32) ur1 = numpy.empty_like(ur0) libecp.ECPrad_part(ur1.ctypes.data_as(ctypes.c_void_p), rs.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(rs)), ctypes.c_int(1), ecpshls.ctypes.data_as(ctypes.c_void_p), mol._ecpbas.ctypes.data_as(ctypes.c_void_p), mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), mol._env.ctypes.data_as(ctypes.c_void_p)) self.assertTrue(numpy.allclose(ur0, ur1))
def test_rad_part(self): rs, ws = radi.gauss_chebyshev(99) ur0 = rad_part(mol, mol._ecpbas, rs) ur1 = numpy.empty_like(ur0) libecp.ECPrad_part(ur1.ctypes.data_as(ctypes.c_void_p), rs.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(0), ctypes.c_int(len(rs)), ctypes.c_int(1), (ctypes.c_int*2)(0, len(mol._ecpbas)), mol._ecpbas.ctypes.data_as(ctypes.c_void_p), mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), mol._env.ctypes.data_as(ctypes.c_void_p), lib.c_null_ptr()) self.assertTrue(numpy.allclose(ur0, ur1))
def test_rad_part(self): rs, ws = radi.gauss_chebyshev(99) ur0 = rad_part(mol, mol._ecpbas, rs) ur1 = numpy.empty_like(ur0) libecp.ECPrad_part(ur1.ctypes.data_as(ctypes.c_void_p), rs.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(0), ctypes.c_int(len(rs)), ctypes.c_int(1), (ctypes.c_int * 2)(0, len(mol._ecpbas)), mol._ecpbas.ctypes.data_as(ctypes.c_void_p), mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), mol._env.ctypes.data_as(ctypes.c_void_p), lib.c_null_ptr()) self.assertTrue(numpy.allclose(ur0, ur1))
def test_type1_rad(self): k = 1.621 aij = .792 rs, ws = radi.gauss_chebyshev(99) ur = rad_part(mol, mol._ecpbas, rs) * ws def gen_type1_rad(li): rad_all0 = type1_rad_part(li, k, aij, ur, rs) rad_all1 = numpy.zeros_like(rad_all0) libecp.type1_rad_part(rad_all1.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(li), ctypes.c_double(k), ctypes.c_double(aij), ur.ctypes.data_as(ctypes.c_void_p), rs.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(rs)), ctypes.c_int(1)) self.assertTrue(numpy.allclose(rad_all0, rad_all1)) for l in range(13): gen_type1_rad(l)
def test_rad_part(self): rs, ws = radi.gauss_chebyshev(99) ur0 = rad_part(mol, mol._ecpbas, rs) ecpshls = numpy.array(numpy.append(numpy.arange(len(mol._ecpbas)), -1), dtype=numpy.int32) ur1 = numpy.empty_like(ur0) libecp.ECPrad_part(ur1.ctypes.data_as(ctypes.c_void_p), rs.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(rs)), ctypes.c_int(1), ecpshls.ctypes.data_as(ctypes.c_void_p), mol._ecpbas.ctypes.data_as(ctypes.c_void_p), mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), mol._env.ctypes.data_as(ctypes.c_void_p)) self.assertTrue(numpy.allclose(ur0, ur1))
def test_type2_rad_part(self): rc = .8712 rs, ws = radi.gauss_chebyshev(99) def type2_facs_rad(ish, lc): facs0 = facs_rad(mol, ish, lc, rc, rs).transpose(0,2,1).copy() facs1 = numpy.empty_like(facs0) libecp.type2_facs_rad(facs1.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(ish), ctypes.c_int(lc), ctypes.c_double(rc), rs.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(rs)), ctypes.c_int(1), mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), mol._env.ctypes.data_as(ctypes.c_void_p)) self.assertTrue(numpy.allclose(facs0, facs1)) for ish in range(mol.nbas): for lc in range(5): type2_facs_rad(ish, lc)
def test_type2_rad_part(self): rc = .8712 rs, ws = radi.gauss_chebyshev(99) def type2_facs_rad(ish, lc): facs0 = facs_rad(mol, ish, lc, rc, rs).transpose(0, 2, 1).copy() facs1 = numpy.empty_like(facs0) libecp.type2_facs_rad(facs1.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(ish), ctypes.c_int(lc), ctypes.c_double(rc), rs.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(rs)), ctypes.c_int(1), mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), mol._env.ctypes.data_as(ctypes.c_void_p)) self.assertTrue(numpy.allclose(facs0, facs1)) for ish in range(mol.nbas): for lc in range(5): type2_facs_rad(ish, lc)
def test_prune(self): grid = gen_grid.Grids(h2o) grid.prune = gen_grid.sg1_prune grid.atom_grid = {"H": (10, 50), "O": (10, 50),} grid.build(with_non0tab=False) self.assertAlmostEqual(numpy.linalg.norm(grid.coords), 202.17732600266302, 9) self.assertAlmostEqual(numpy.linalg.norm(grid.weights), 442.54536463517167, 9) grid.prune = gen_grid.nwchem_prune grid.build(with_non0tab=False) self.assertAlmostEqual(numpy.linalg.norm(grid.coords), 149.55023044392638, 9) self.assertAlmostEqual(numpy.linalg.norm(grid.weights), 586.36841824004455, 9) z = 16 rad, dr = radi.gauss_chebyshev(50) angs = gen_grid.sg1_prune(z, rad, 434, radii=radi.SG1RADII) self.assertAlmostEqual(lib.finger(angs), -291.0794420982329, 9) angs = gen_grid.nwchem_prune(z, rad, 434, radii=radi.BRAGG_RADII) self.assertAlmostEqual(lib.finger(angs), -180.12023039394498, 9) angs = gen_grid.nwchem_prune(z, rad, 26, radii=radi.BRAGG_RADII) self.assertTrue(numpy.all(angs==26))
def so_by_shell(mol, shls, ecpatm_id, ecpbas): '''SO-ECP i/2 <Pauli_matrix dot l U(r)> ''' ish, jsh = shls li = mol.bas_angular(ish) npi = mol.bas_nprim(ish) nci = mol.bas_nctr(ish) ai = mol.bas_exp(ish) ci = mol._libcint_ctr_coeff(ish) icart = (li + 1) * (li + 2) // 2 lj = mol.bas_angular(jsh) npj = mol.bas_nprim(jsh) ncj = mol.bas_nctr(jsh) aj = mol.bas_exp(jsh) cj = mol._libcint_ctr_coeff(jsh) jcart = (lj + 1) * (lj + 2) // 2 rc = mol.atom_coord(ecpatm_id) rcb = rc - mol.bas_coord(jsh) r_cb = numpy.linalg.norm(rcb) rca = rc - mol.bas_coord(ish) r_ca = numpy.linalg.norm(rca) #rs, ws = radi.treutler(99) rs, ws = radi.gauss_chebyshev(99) i_fac_cache = cache_fac(li, rca) j_fac_cache = cache_fac(lj, rcb) g1 = numpy.zeros((nci, ncj, 3, icart, jcart), dtype=numpy.complex128) for lc in range(5): # up to g function ecpbasi = ecpbas[ecpbas[:, ANG_OF] == lc] if len(ecpbasi) == 0: continue ur = rad_part(mol, ecpbasi, rs) * ws idx = abs(ur) > 1e-80 rur = numpy.array( [ur[idx] * rs[idx]**lab for lab in range(li + lj + 1)]) fi = facs_rad(mol, ish, lc, r_ca, rs)[:, :, idx].copy() fj = facs_rad(mol, jsh, lc, r_cb, rs)[:, :, idx].copy() angi = facs_ang(type2_ang_part(li, lc, -rca), li, lc, i_fac_cache) angj = facs_ang(type2_ang_part(lj, lc, -rcb), lj, lc, j_fac_cache) # Note the factor 2/(2l+1) in JCP 82 2664 is not multiplied here # because the ECP parameter has been scaled by 2/(2l+1) in CRENBL jmm = angular_moment_matrix(lc) for ic in range(nci): for jc in range(ncj): rad_all = numpy.einsum('pr,ir,jr->pij', rur, fi[ic], fj[jc]) for i1 in range(li + 1): for j1 in range(lj + 1): g1[ic, jc] += numpy.einsum('pq,imp,jnq,lmn->lij', rad_all[i1 + j1], angi[i1], angj[j1], jmm) g1 *= (numpy.pi * 4)**2 gspinor = numpy.empty((nci, ncj, li * 4 + 2, lj * 4 + 2), dtype=numpy.complex128) for ic in range(nci): for jc in range(ncj): ui = numpy.asarray(gto.cart2spinor_l(li)) uj = numpy.asarray(gto.cart2spinor_l(lj)) s = lib.PauliMatrices * .5j gspinor[ic, jc] = numpy.einsum('sxy,spq,xpi,yqj->ij', s, g1[ic, jc], ui.conj(), uj) return gspinor.transpose(0, 2, 1, 3).reshape(nci * (li * 4 + 2), -1)
def type1_by_shell(mol, shls, ecpatm_id, ecpbas): ish, jsh = shls li = mol.bas_angular(ish) npi = mol.bas_nprim(ish) nci = mol.bas_nctr(ish) ai = mol.bas_exp(ish) ci = mol._libcint_ctr_coeff(ish) icart = (li + 1) * (li + 2) // 2 lj = mol.bas_angular(jsh) npj = mol.bas_nprim(jsh) ncj = mol.bas_nctr(jsh) aj = mol.bas_exp(jsh) cj = mol._libcint_ctr_coeff(jsh) jcart = (lj + 1) * (lj + 2) // 2 rc = mol.atom_coord(ecpatm_id) rca = rc - mol.bas_coord(ish) r2ca = numpy.dot(rca, rca) rcb = rc - mol.bas_coord(jsh) r2cb = numpy.dot(rcb, rcb) # Note the Mole._libcint_ctr_coeff are normalized to radial part cei = numpy.einsum('ij,i->ij', ci, numpy.exp(-ai * r2ca)) cej = numpy.einsum('ij,i->ij', cj, numpy.exp(-aj * r2cb)) #rs, ws = radi.treutler(99) rs, ws = radi.gauss_chebyshev(99) ur = rad_part(mol, ecpbas, rs) * ws rad_ang_all = numpy.zeros( (nci, ncj, li + lj + 1, li + lj + 1, li + lj + 1)) for ip in range(npi): for jp in range(npj): rij = ai[ip] * rca + aj[jp] * rcb aij = ai[ip] + aj[jp] k = 2 * numpy.linalg.norm(rij) rad_all = type1_rad_part(li + lj, k, aij, ur, rs) #ang_all = type1_ang_part(li+lj, -rij) #rad_ang = numpy.einsum('pl,lijk->pijk', rad_all, ang_all) rad_ang = type1_rad_ang(li + lj, rij, rad_all) for ic in range(nci): for jc in range(ncj): rad_ang_all[ic, jc] += rad_ang * cei[ip, ic] * cej[jp, jc] * ( 4 * numpy.pi)**2 ifac = type1_cache_fac(li, rca) jfac = type1_cache_fac(lj, rcb) g1 = numpy.zeros((nci, ncj, icart, jcart)) for ic in range(nci): for jc in range(ncj): for mi, (ix, iy, iz) in enumerate(loop_cart(li)): for mj, (jx, jy, jz) in enumerate(loop_cart(lj)): tmp = 0 for i1, i2, i3 in loop_xyz(ix, iy, iz): for j1, j2, j3 in loop_xyz(jx, jy, jz): fac = ifac[mi, i1, i2, i3] * jfac[mj, j1, j2, j3] tmp += fac * rad_ang_all[ic, jc, i1 + j1, i2 + j2, i3 + j3] g1[ic, jc, mi, mj] = tmp gsph = numpy.empty((nci, ncj, li * 2 + 1, lj * 2 + 1)) for ic in range(nci): for jc in range(ncj): tmp = c2s_bra(lj, g1[ic, jc].T.copy()) gsph[ic, jc] = c2s_bra(li, tmp.T.copy()) return gsph.transpose(0, 2, 1, 3).reshape(nci * (li * 2 + 1), -1)
def type1_by_shell(mol, shls, ecpatm_id, ecpbas): ish, jsh = shls li = mol.bas_angular(ish) npi = mol.bas_nprim(ish) nci = mol.bas_nctr(ish) ai = mol.bas_exp(ish) ci = mol.bas_ctr_coeff(ish) icart = (li+1) * (li+2) // 2 lj = mol.bas_angular(jsh) npj = mol.bas_nprim(jsh) ncj = mol.bas_nctr(jsh) aj = mol.bas_exp(jsh) cj = mol.bas_ctr_coeff(jsh) jcart = (lj+1) * (lj+2) // 2 rc = mol.atom_coord(ecpatm_id) rca = rc - mol.bas_coord(ish) r2ca = numpy.dot(rca, rca) rcb = rc - mol.bas_coord(jsh) r2cb = numpy.dot(rcb, rcb) # Note the Mole.bas_ctr_coeff are normalized to radial part cei = numpy.einsum('ij,i->ij', ci, numpy.exp(-ai * r2ca)) cej = numpy.einsum('ij,i->ij', cj, numpy.exp(-aj * r2cb)) #rs, ws = radi.treutler(99) rs, ws = radi.gauss_chebyshev(99) ur = rad_part(mol, ecpbas, rs) * ws rad_ang_all = numpy.zeros((nci,ncj,li+lj+1,li+lj+1,li+lj+1)) for ip in range(npi): for jp in range(npj): rij = ai[ip] * rca + aj[jp] * rcb aij = ai[ip] + aj[jp] k = 2*numpy.linalg.norm(rij) rad_all = type1_rad_part(li+lj, k, aij, ur, rs) #ang_all = type1_ang_part(li+lj, -rij) #rad_ang = numpy.einsum('pl,lijk->pijk', rad_all, ang_all) rad_ang = type1_rad_ang(li+lj, rij, rad_all) for ic in range(nci): for jc in range(ncj): rad_ang_all[ic,jc] += rad_ang * cei[ip,ic]*cej[jp,jc] * (4*numpy.pi)**2 ifac = type1_cache_fac(li, rca) jfac = type1_cache_fac(lj, rcb) g1 = numpy.zeros((nci,ncj,icart,jcart)) for ic in range(nci): for jc in range(ncj): for mi,(ix,iy,iz) in enumerate(loop_cart(li)): for mj,(jx,jy,jz) in enumerate(loop_cart(lj)): tmp = 0 for i1, i2, i3 in loop_xyz(ix, iy, iz): for j1, j2, j3 in loop_xyz(jx, jy, jz): fac = ifac[mi,i1,i2,i3] * jfac[mj,j1,j2,j3] tmp += fac * rad_ang_all[ic,jc,i1+j1,i2+j2,i3+j3] g1[ic,jc,mi,mj] = tmp gsph = numpy.empty((nci,ncj,li*2+1,lj*2+1)) for ic in range(nci): for jc in range(ncj): tmp = c2s_bra(lj, g1[ic,jc].T.copy()) gsph[ic,jc] = c2s_bra(li, tmp.T.copy()) return gsph.transpose(0,2,1,3).reshape(nci*(li*2+1),-1)