Skip to content

Commit

Permalink
Fix FCI wfn_symmetry example (fix pyscf#1726); simplify the fci direc…
Browse files Browse the repository at this point in the history
…t_spin0_symm implementation
  • Loading branch information
sunqm committed Aug 17, 2024
1 parent af38ac0 commit 182fef0
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 43 deletions.
12 changes: 8 additions & 4 deletions examples/fci/13-wfn_symmetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
#

'''
Assign FCI wavefunction symmetry
Assign FCI wavefunction symmetry.
This example demonstrates only the solver that utlizes the D2h (and its
subgroup) symmetry. For molecules with cylindrical symmetry, a special solver is
available, as shown in 03-cylindrical_symmetry.py
'''

import numpy
Expand Down Expand Up @@ -42,7 +46,7 @@
ncore = mo_core.shape[1]
nelec = mol.nelectron - ncore * 2
fs = fci.direct_spin0_symm.FCI(mol)
fs.wfnsym = 'A2'
fs.wfnsym = 'A1'
e, c = fs.kernel(h1, h2, norb, nelec, ecore=ecore, orbsym=orbsym, verbose=5)
print('Energy of %s state %.12f' % (fs.wfnsym, e))

Expand All @@ -61,7 +65,7 @@
h2 = ao2mo.kernel(mol, mo_cas)
orbsym = scf.hf_symm.get_orbsym(mol, m.mo_coeff)[cas_idx]
fs = fci.direct_spin0_symm.FCI(mol)
fs.wfnsym = 'A2'
fs.wfnsym = 'A1'
e, c = fs.kernel(h1, h2, norb, nelec, ecore=ecore, orbsym=orbsym)
print('Energy of %s state %.12f' % (fs.wfnsym, e))

Expand All @@ -79,7 +83,7 @@
h2 = mc.get_h2eff(mo)
orbsym = scf.hf_symm.get_orbsym(mol, m.mo_coeff)[cas_idx]
fs = fci.direct_spin0_symm.FCI(mol)
fs.wfnsym = 'A2'
fs.wfnsym = 'A1'
e, c = fs.kernel(h1, h2, norb, nelec, ecore=ecore, orbsym=orbsym)
print('Energy of %s state %.12f' % (fs.wfnsym, e))

Expand Down
50 changes: 11 additions & 39 deletions pyscf/fci/direct_spin0_symm.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,48 +103,18 @@ def get_init_guess(norb, nelec, nroots, hdiag, orbsym, wfnsym=0):

def get_init_guess_cyl_sym(norb, nelec, nroots, hdiag, orbsym, wfnsym=0):
neleca, nelecb = direct_spin1._unpack_nelec(nelec)
strsa = cistring.gen_strings4orblist(range(norb), neleca)
airreps_d2h = direct_spin1_symm._gen_strs_irrep(strsa, orbsym)
a_ls = direct_spin1_symm._strs_angular_momentum(strsa, orbsym)

wfnsym_in_d2h = wfnsym % 10
wfn_momentum = symm.basis.linearmole_irrep2momentum(wfnsym)
na = len(strsa)
hdiag = hdiag.reshape(na,na)
degen = orbsym.degen_mapping
na = cistring.num_strings(norb, neleca)
ci0_guess = direct_spin1_symm.get_init_guess_cyl_sym(
norb, nelec, nroots, hdiag, orbsym, wfnsym)
ci0 = []
iroot = 0
wfn_ungerade = wfnsym_in_d2h >= 4
a_ungerade = airreps_d2h >= 4
sym_allowed = a_ungerade[:,None] == a_ungerade ^ wfn_ungerade
# total angular momentum == wfn_momentum
sym_allowed &= a_ls[:,None] == wfn_momentum - a_ls
idx = numpy.arange(na)
sym_allowed[idx[:,None] < idx] = False

idx_a, idx_b = numpy.where(sym_allowed)
for k in hdiag[idx_a,idx_b].argsort():
addra, addrb = idx_a[k], idx_b[k]
ca = direct_spin1_symm._cyl_sym_csf2civec(strsa, addra, orbsym, degen)
cb = direct_spin1_symm._cyl_sym_csf2civec(strsa, addrb, orbsym, degen)
if wfn_momentum > 0 or wfnsym in (0, 5):
x = ca.real[:,None] * cb.real
x-= ca.imag[:,None] * cb.imag
else:
x = ca.imag[:,None] * cb.real
x+= ca.real[:,None] * cb.imag
if addra == addrb:
norm = numpy.linalg.norm(x)
else:
x = x + x.T
norm = numpy.linalg.norm(x)
if norm < 1e-3:
continue
for x in ci0_guess:
x = x.reshape(na, na)
x = x + x.T
norm = numpy.linalg.norm(x)
if norm < 1e-3:
continue
x *= 1./norm
ci0.append(x.ravel().view(direct_spin1.FCIvector))
iroot += 1
if iroot >= nroots:
break

if len(ci0) == 0:
raise lib.exceptions.WfnSymmetryError(
Expand All @@ -154,6 +124,8 @@ def get_init_guess_cyl_sym(norb, nelec, nroots, hdiag, orbsym, wfnsym=0):

class FCISolver(direct_spin0.FCISolver):

_keys = {'wfnsym', 'sym_allowed_idx'}

davidson_only = getattr(__config__, 'fci_direct_spin1_symm_FCI_davidson_only', True)
pspace_size = getattr(__config__, 'fci_direct_spin1_symm_FCI_pspace_size', 400)

Expand Down

0 comments on commit 182fef0

Please sign in to comment.