-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #131 from BoothGroup/ewdmet_scmf
Implements quasiparticle EWDMET to obtain spectral functions from embedded calculations, making use of the Dyson package for moment based approaches to Green's function calculations.
- Loading branch information
Showing
20 changed files
with
1,539 additions
and
151 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -145,6 +145,9 @@ pyscf.out | |
# Vayesta log files | ||
vlog.txt | ||
verr.txt | ||
f*_pyscf.txt | ||
f*.out | ||
*.h5 | ||
|
||
# HDF5 files | ||
*.h5 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import numpy as np | ||
|
||
import vayesta | ||
import vayesta.ewf | ||
from vayesta.lattmod import Hubbard1D, LatticeRHF | ||
|
||
from dyson import MBLGF, AuxiliaryShift, FCI, MixedMBLGF, NullLogger, Lehmann | ||
|
||
nsite = 10 | ||
nelec = nsite | ||
u = 6 | ||
nfrag = 2 | ||
|
||
nmom_max_fci = (4,4) | ||
nmom_max_bath=1 | ||
|
||
|
||
|
||
|
||
hubbard = Hubbard1D(nsite=nsite, nelectron=nelec, hubbard_u=u, verbose=0) | ||
mf = LatticeRHF(hubbard) | ||
mf.kernel() | ||
|
||
# Full system FCI GF | ||
expr = FCI["1h"](mf) | ||
th = expr.build_gf_moments(nmom_max_fci[0]) | ||
expr = FCI["1p"](mf) | ||
tp = expr.build_gf_moments(nmom_max_fci[1]) | ||
|
||
solverh = MBLGF(th, log=NullLogger()) | ||
solverp = MBLGF(tp, log=NullLogger()) | ||
solver = MixedMBLGF(solverh, solverp) | ||
solver.kernel() | ||
se = solver.get_self_energy() | ||
solver = AuxiliaryShift(th[1]+tp[1], se, nelec, log=NullLogger()) | ||
solver.kernel() | ||
static_potential = se.as_static_potential(mf.mo_energy, eta=1e-2) | ||
gf = solver.get_greens_function() | ||
dm = gf.occupied().moment(0) * 2.0 | ||
nelec_gf = np.trace(dm) | ||
print("Exact GF nelec: %s"%nelec_gf) | ||
|
||
sc = mf.get_ovlp() @ mf.mo_coeff | ||
new_fock = sc @ (th[1] + tp[1] + static_potential) @ sc.T | ||
e, mo_coeff = np.linalg.eigh(new_fock) | ||
chempot = (e[nelec//2-1] + e[nelec//2] ) / 2 | ||
gf_static = Lehmann(e, mo_coeff, chempot=chempot) | ||
|
||
gap = lambda gf: gf.physical().virtual().energies[0] - gf.physical().occupied().energies[-1] | ||
dynamic_gap = gap(gf) | ||
static_gap = gap(gf_static) | ||
|
||
# QP-EwDMET GF | ||
opts = dict(sc=False, store_hist=True, aux_shift=True, store_scfs=True, diis=True, damping=0, static_potential_conv_tol=1e-6, use_sym=False, eta=1e-2) | ||
emb = vayesta.ewf.EWF(mf, solver='FCI', bath_options=dict(bathtype='full', dmet_threshold=1e-12), solver_options=dict(conv_tol=1e-15, n_moments=nmom_max_fci)) | ||
emb.qpewdmet_scmf(proj=1, maxiter=10, **opts) | ||
nimages = [nsite//nfrag, 1, 1] | ||
emb.symmetry.set_translations(nimages) | ||
with emb.site_fragmentation() as f: | ||
f.add_atomic_fragment(range(nfrag)) | ||
emb.kernel() | ||
|
||
emb_dynamic_gap = gap(emb.with_scmf.gf) | ||
emb_static_gap = gap(emb.with_scmf.gf_qp) | ||
print("Ran for %s iterations"%emb.with_scmf.iteration) | ||
print("Dynamic gap, FCI: %s Emb: %s"%(dynamic_gap, emb_dynamic_gap)) | ||
print("Static gap, FCI: %s Emb: %s"%(static_gap, emb_static_gap)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import numpy as np | ||
|
||
import vayesta | ||
import vayesta.ewf | ||
from vayesta.lattmod import Hubbard1D, LatticeRHF | ||
|
||
# Plot the spectrum | ||
from dyson.util import build_spectral_function | ||
import matplotlib.pyplot as plt | ||
|
||
nsite = 12 | ||
nelec = nsite | ||
nfrag = 2 | ||
u = 3 | ||
|
||
nmom_max_fci = (4,4) | ||
nmom_max_bath=1 | ||
|
||
|
||
hubbard = Hubbard1D(nsite=nsite, nelectron=nelec, hubbard_u=u, verbose=0) | ||
mf = LatticeRHF(hubbard) | ||
mf.kernel() | ||
|
||
emb = vayesta.ewf.EWF(mf, solver='FCI', bath_options=dict(bathtype='ewdmet', max_order=1, order=1, dmet_threshold=1e-10), solver_options=dict(conv_tol=1e-12, init_guess='cisd', n_moments=nmom_max_fci)) | ||
nimages = [nsite//nfrag, 1, 1] | ||
emb.symmetry.set_translations(nimages) | ||
with emb.site_fragmentation() as f: | ||
f.add_atomic_fragment(list(range(nfrag))) | ||
emb.qpewdmet_scmf(maxiter=100, proj=1) | ||
emb.kernel() | ||
gf, gf_qp = emb.with_scmf.get_greens_function() | ||
|
||
fig, ax = plt.subplots(2,1, figsize=(16,9)) | ||
|
||
grid = np.linspace(-5, 11, 1024) | ||
sf_hf = build_spectral_function(mf.mo_energy, np.eye(mf.mo_occ.size), grid, eta=0.1) | ||
ax[0].plot(grid, sf_hf, 'r-', label='HF') | ||
ax[1].plot(grid, sf_hf, 'r-', label='HF') | ||
|
||
sf_dynamic = build_spectral_function(gf.energies, gf.couplings, grid, eta=0.1) | ||
sf_static = build_spectral_function(gf_qp.energies, gf_qp.couplings, grid, eta=0.1) | ||
ax[0].plot(grid, sf_dynamic, "b-", label="QP-EwDMET (1 Proj, dynamic)") | ||
ax[1].plot(grid, sf_static, "g-", label="QP-EwDMET (1 Proj, static)") | ||
|
||
|
||
emb = vayesta.ewf.EWF(mf, solver='FCI', bath_options=dict(bathtype='ewdmet', max_order=1, order=1, dmet_threshold=1e-10), solver_options=dict(conv_tol=1e-12, init_guess='cisd', n_moments=nmom_max_fci)) | ||
nimages = [nsite//nfrag, 1, 1] | ||
emb.symmetry.set_translations(nimages) | ||
with emb.site_fragmentation() as f: | ||
f.add_atomic_fragment(list(range(nfrag))) | ||
emb.qpewdmet_scmf(maxiter=100, proj=2) | ||
emb.kernel() | ||
gf, gf_qp = emb.with_scmf.get_greens_function() | ||
|
||
sf_dynamic = build_spectral_function(gf.energies, gf.couplings, grid, eta=0.1) | ||
sf_static = build_spectral_function(gf_qp.energies, gf_qp.couplings, grid, eta=0.1) | ||
ax[0].plot(grid, sf_dynamic, "m-", label="QP-EwDMET (2 Proj, dynamic)") | ||
ax[1].plot(grid, sf_static, "y-", label="QP-EwDMET (2, Proj, static)") | ||
|
||
|
||
ax[0].set_title('U = %d'%u) | ||
ax[0].legend() | ||
ax[1].legend() | ||
|
||
plt.savefig("hubbard_spectral_function.png") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import numpy as np | ||
import vayesta | ||
import vayesta.ewf | ||
from vayesta.lattmod import Hubbard1D, LatticeRHF | ||
from vayesta.lattmod.bethe import hubbard1d_bethe_gap | ||
from dyson import Lehmann, FCI, CCSD | ||
|
||
u = 3 | ||
nsite = 128 | ||
nelec = nsite | ||
nfrag = 2 | ||
nmom_max_bath = 1 | ||
nmom_max_fci = (4,4) | ||
solv = 'FCI' | ||
EXPR = FCI if solv=='FCI' else CCSD | ||
hubbard = Hubbard1D(nsite=nsite, nelectron=nelec, hubbard_u=u, verbose=0) | ||
mf = LatticeRHF(hubbard) | ||
mf.kernel() | ||
|
||
chempot = (mf.mo_energy[nsite//2-1] + mf.mo_energy[nsite//2] ) / 2 | ||
gf_hf = Lehmann(mf.mo_energy, np.eye(mf.mo_coeff.shape[0]), chempot=chempot) | ||
|
||
|
||
emb = vayesta.ewf.EWF(mf, solver=solv, bath_options=dict(bathtype='ewdmet', max_order=nmom_max_bath, order=nmom_max_bath, dmet_threshold=1e-12), solver_options=dict(conv_tol=1e-12, n_moments=nmom_max_fci)) | ||
emb.qpewdmet_scmf(proj=2, maxiter=10) | ||
nimages = [nsite//nfrag, 1, 1] | ||
emb.symmetry.set_translations(nimages) | ||
with emb.site_fragmentation() as f: | ||
f.add_atomic_fragment(list(range(nfrag))) | ||
emb.kernel() | ||
|
||
gap = lambda gf: gf.physical().virtual().energies[0] - gf.physical().occupied().energies[-1] | ||
emb_dynamic_gap = gap(emb.with_scmf.gf) | ||
emb_static_gap = gap(emb.with_scmf.gf_qp) | ||
hf_gap = gap(gf_hf) | ||
bethe_gap = hubbard1d_bethe_gap(1,u, interval=(1,200)) | ||
|
||
print("Ran for %s iterations"%emb.with_scmf.iteration) | ||
print("Bethe ansatz gap: %s "%(bethe_gap)) | ||
print("Hartree-Fock gap: %s"%(hf_gap)) | ||
print("Dynamic GF gap: %s"%(emb_dynamic_gap)) | ||
print("Static GF gap: %s"%(emb_static_gap)) |
77 changes: 77 additions & 0 deletions
77
examples/ewdmet/10-sc-qp-ewdmet-hydrogen-ring-exact-limit.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import numpy as np | ||
import scipy | ||
|
||
import pyscf | ||
import pyscf.scf | ||
|
||
import vayesta | ||
import vayesta.ewf | ||
from vayesta.misc.molecules import ring | ||
from dyson import MBLGF, AuxiliaryShift, FCI, MixedMBLGF, NullLogger, Lehmann | ||
from dyson.util import build_spectral_function | ||
|
||
a = 1 | ||
natom = 10 | ||
nfrag = 1 | ||
maxiter = 100 | ||
nmom_max_fci = (4,4) | ||
nmom_max_bath=1 | ||
|
||
mol = pyscf.gto.Mole() | ||
mol.atom = ring('H', natom, a) | ||
mol.basis = 'sto-3g' | ||
mol.output = 'pyscf.out' | ||
mol.verbose = 4 | ||
mol.build() | ||
|
||
# Hartree-Fock | ||
mf = pyscf.scf.RHF(mol) | ||
mf.kernel() | ||
assert mf.converged | ||
chempot = (mf.mo_energy[natom//2-1] + mf.mo_energy[natom//2] ) / 2 | ||
gf_hf = Lehmann(mf.mo_energy, np.eye(mf.mo_coeff.shape[0]), chempot=chempot) | ||
|
||
# Full system FCI GF | ||
expr = FCI["1h"](mf) | ||
th = expr.build_gf_moments(nmom_max_fci[0]) | ||
expr = FCI["1p"](mf) | ||
tp = expr.build_gf_moments(nmom_max_fci[1]) | ||
|
||
solverh = MBLGF(th, log=NullLogger()) | ||
solverp = MBLGF(tp, log=NullLogger()) | ||
solver = MixedMBLGF(solverh, solverp) | ||
solver.kernel() | ||
se = solver.get_self_energy() | ||
solver = AuxiliaryShift(th[1]+tp[1], se, natom, log=NullLogger()) | ||
solver.kernel() | ||
static_potential = se.as_static_potential(mf.mo_energy, eta=1e-2) | ||
gf = solver.get_greens_function() | ||
dm = gf.occupied().moment(0) * 2.0 | ||
nelec_gf = np.trace(dm) | ||
print("Exact GF nelec: %s"%nelec_gf) | ||
|
||
sc = mf.get_ovlp() @ mf.mo_coeff | ||
new_fock = sc @ (th[1] + tp[1] + static_potential) @ sc.T | ||
e, mo_coeff = scipy.linalg.eigh(new_fock, mf.get_ovlp()) | ||
chempot = (e[natom//2-1] + e[natom//2] ) / 2 | ||
gf_static = Lehmann(e, np.eye(mf.mo_coeff.shape[0]), chempot=chempot) | ||
|
||
gap = lambda gf: gf.physical().virtual().energies[0] - gf.physical().occupied().energies[-1] | ||
dynamic_gap = gap(gf) | ||
static_gap = gap(gf_static) | ||
|
||
# QP-EwDMET GF | ||
emb = vayesta.ewf.EWF(mf, solver='FCI', bath_options=dict(bathtype='full', dmet_threshold=1e-12), solver_options=dict(conv_tol=1e-15, n_moments=nmom_max_fci)) | ||
emb.qpewdmet_scmf(proj=1, maxiter=maxiter) | ||
with emb.site_fragmentation() as f: | ||
with f.rotational_symmetry(order=int(natom/nfrag), axis='z') as rot: | ||
f.add_atomic_fragment(range(nfrag)) | ||
emb.kernel() | ||
|
||
hf_gap = gap(gf_hf) | ||
emb_dynamic_gap = gap(emb.with_scmf.gf) | ||
emb_static_gap = gap(emb.with_scmf.gf_qp) | ||
print("Ran for %s iterations"%emb.with_scmf.iteration) | ||
print("Hartree-Fock gap: %s"%hf_gap) | ||
print("Dynamic gap, FCI: %s Emb: %s"%(dynamic_gap, emb_dynamic_gap)) | ||
print("Static gap, FCI: %s Emb: %s"%(static_gap, emb_static_gap)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.