Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add callback solver example using dyson for EWDMET #164

Merged
merged 7 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions examples/ewdmet/65-callback-solver-dyson.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import numpy as np
import pyscf
import pyscf.gto
import pyscf.scf
import pyscf.fci
import vayesta
import vayesta.ewf
from vayesta.misc.molecules import ring
from dyson import FCI


# User defined FCI solver - takes pyscf mf as input and returns RDMs
# The mf argment contains the hamiltonain in the orthonormal cluster basis
# Pyscf or other solvers may be used to solve the cluster problem and may return RDMs, CIID amplitudes or CCSD amplitudes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CIID -> CISD
Also, can you add "or (in this case) the Greens function moments of the cluster", to make it clear what is going on in this example.

def solver(mf):
fci_1h = FCI["1h"](mf)
fci_1p = FCI["1p"](mf)

# Use MBLGF
nmom_max = 4
th = fci_1h.build_gf_moments(nmom_max)
tp = fci_1p.build_gf_moments(nmom_max)

norb = mf.mo_coeff.shape[-1]
nelec = mf.mol.nelec
civec= fci_1h.c_ci
dm1, dm2 = pyscf.fci.direct_spin0.make_rdm12(civec, norb, nelec)
results = dict(dm1=dm1, dm2=dm2, hole_moments=th, particle_moments=tp, converged=True)
return results

natom = 10
mol = pyscf.gto.Mole()
mol.atom = ring("H", natom, 1.5)
mol.basis = "sto-3g"
mol.output = "pyscf.out"
mol.verbose = 5
mol.symmetry = True
mol.build()

# Hartree-Fock
mf = pyscf.scf.RHF(mol)
mf.kernel()

# Vayesta options
use_sym = True
nfrag = 1
bath_opts = dict(bathtype="ewdmet", order=1, max_order=1)

# Run vayesta with user defined solver
emb = vayesta.ewf.EWF(mf, solver="CALLBACK", energy_functional='dmet', bath_options=bath_opts, solver_options=dict(callback=solver))
emb.qpewdmet_scmf(proj=2, maxiter=10)
# Set up fragments
with emb.iao_fragmentation() as f:
if use_sym:
# Add rotational symmetry
with f.rotational_symmetry(order=natom//nfrag, axis=[0, 0, 1]):
f.add_atomic_fragment(range(nfrag))
else:
# Add all atoms as separate fragments
f.add_all_atomic_fragments()
emb.kernel()

print("Hartree-Fock energy : %s"%mf.e_tot)
print("DMET energy : %s"%emb.get_dmet_energy(part_cumulant=False, approx_cumulant=False))
print("DMET energy (part-cumulant): %s"%emb.get_dmet_energy(part_cumulant=True, approx_cumulant=False))
print("DMET energy (approx-cumulant): %s"%emb.get_dmet_energy(part_cumulant=True, approx_cumulant=True))

2 changes: 2 additions & 0 deletions examples/ewf/molecules/65-callback-solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from vayesta.misc.molecules import ring

# User defined FCI solver - takes pyscf mf as input and returns RDMs
# The mf argment contains the hamiltonain in the orthonormal cluster basis
# Pyscf or other solvers may be used to solve the cluster problem and may return RDMs, CIID amplitudes or CCSD amplitudes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CIID -> CISD

def solver(mf):
h1e = mf.get_hcore()
h2e = mf._eri
Expand Down
6 changes: 6 additions & 0 deletions vayesta/ewf/ewf.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,11 +310,17 @@ def get_e_corr(self, functional=None, **kwargs):
self.log.warning("functional='projected' is deprecated; use functional='wf' instead.")
functional = "wf"
if functional == "wf":
# CCSD projected energy expression
return self.get_wf_corr_energy(**kwargs)
if functional == "dm-t2only":
# Builds density matrices from projected amplitudes
return self.get_dm_corr_energy(t_as_lambda=True, **kwargs)
if functional == "dm":
# Builds density matrices from projected amplitudes
return self.get_dm_corr_energy(**kwargs)
if functional == 'dmet':
# Uses projected denisty matrices
return self.get_dmet_energy(**kwargs)
raise ValueError("Unknown energy functional: '%s'" % functional)

@mpi.with_allreduce()
Expand Down
Loading