-
Notifications
You must be signed in to change notification settings - Fork 0
/
fci_simple.py
66 lines (61 loc) · 2.14 KB
/
fci_simple.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import numpy
from pyscf import gto, scf, ao2mo
from pyscf.fci import cistring
from pyscf.fci import fci_slow
import time
from mpmath import mp
def fci_partition_all(mol, m, T, mu, lam = 1.0):
beta = 1.0 / T
norb = m.mo_coeff.shape[1]
Z = mp.mpf(0.0)
f = m.get_fock()
hprime = f + lam*(m.get_hcore() - f)
for nalpha in range(0,norb + 1):
for nbeta in range(0,norb + 1):
#print(nalpha,nbeta)
nel = nalpha + nbeta
nelec = (nalpha,nbeta)
h1e = reduce(numpy.dot, (m.mo_coeff.T, hprime, m.mo_coeff))
eri = ao2mo.kernel(m._eri, m.mo_coeff, compact=False)
eri = eri.reshape(norb,norb,norb,norb)
eri = lam*eri
h2e = fci_slow.absorb_h1e(h1e, eri, norb, nelec, .5)
na = cistring.num_strings(norb, nalpha)
nb = cistring.num_strings(norb, nbeta)
N = na*nb
assert(N < 2000)
H = numpy.zeros((N,N))
I = numpy.identity(N)
for i in range(N):
hc = fci_slow.contract_2e(h2e,I[:,i],norb,nelec)
#hc = fci_slow.contract_1e(h1e,I[:,i],norb,nelec)
hc.reshape(-1)
H[:,i] = hc
e,v = numpy.linalg.eigh(H)
#print(e[0] + mol.energy_nuc())
for j in range(N):
ex = mp.mpf(beta*(nel*mu - e[j]))
Z += mp.exp(ex)
return Z
# only for RHF
def fci_simple(mol, m, lam = 1.0):
norb = m.mo_coeff.shape[1]
nelec = mol.nelectron
f = m.get_fock()
hprime = f + lam*(m.get_hcore() - f)
h1e = reduce(numpy.dot, (m.mo_coeff.T, hprime, m.mo_coeff))
eri = ao2mo.kernel(m._eri, m.mo_coeff, compact=False)
eri = lam*eri.reshape(norb,norb,norb,norb)
h2e = fci_slow.absorb_h1e(h1e, eri, norb, nelec, .5)
na = cistring.num_strings(norb, nelec//2)
N = na*na
assert(N < 2000)
H = numpy.zeros((N,N))
I = numpy.identity(N)
for i in range(N):
hc = fci_slow.contract_2e(h2e,I[:,i],norb,nelec)
hc.reshape(-1)
H[:,i] = hc
e,v = numpy.linalg.eigh(H)
#print(e[0] + mol.energy_nuc())
return e[0] + mol.energy_nuc()