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

Added to_cisdtq functionality to RFCI wave function types for extract… #69

Merged
merged 77 commits into from
Apr 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
81a7715
Added to_cisdtq functionality to RFCI wave function types for extract…
Nov 3, 2022
5080b65
Added cisdtq -> ccsdtq functionality for restricted wave functions
Nov 4, 2022
9e306b9
pass in tuple for t4 and c4 arguments rather than individual spin sig…
Nov 4, 2022
847f0f5
Fix string format
Nov 4, 2022
5105d8a
Update example to non-deprecated practices
Nov 12, 2022
410a320
Add OBC 1D chain of atoms constructor
Nov 12, 2022
14de2a2
WIP
Nov 12, 2022
cdff3cb
Merge remote-tracking branch 'origin/v1.0.2a' into to_cisdtq
Nov 12, 2022
bf6d8d8
Complete code for ec-cc with all hamiltonian terms from child cluster.
Nov 14, 2022
da04535
Local external correction implemented and running. Now to debug...!
Nov 15, 2022
6d187ce
fix for 2e systems
Nov 15, 2022
b8262a8
ec-cc now exact for 4-electron systems and full FCI space. Seems to b…
Nov 15, 2022
4d7381f
Energy denominators now dealt with effectively outside the callback
Nov 17, 2022
ab487aa
Address Max comments on code style. Fix bug in external-ccsdv
Nov 17, 2022
b8fd264
Added alternate equations to check consistency of EC implementation. …
Nov 18, 2022
15d4fbf
Passed in ERIs sometimes fails, as they are stored as HDF5 file, rath…
Nov 18, 2022
31f5b79
Add tests for external correction, including Hubbard model and LiH (w…
Nov 18, 2022
befe789
Add example of EC-CCSD via local FCI clusters, both for a full system…
Nov 18, 2022
4b45e16
Add example of various external corrections on the Hubbard model. Wil…
Nov 18, 2022
d46d0db
Clean up ext-corr hubbard example
Nov 20, 2022
87d34bd
Allow external correction to be used along with scmf
Nov 21, 2022
75103a7
Update Hubbard EC-CC example to print out whether converged.
Nov 21, 2022
a5dec5b
Fix for use of delta-tailoring correction with symmetry-derived fragm…
Nov 22, 2022
b174b0e
Merge. Also include test for symmetry in external corrections
Nov 22, 2022
d949b68
Update EC-CC example to use symmetry correctly. Put note in external-…
Nov 22, 2022
2549eef
Tidying in response to PR comments.
Nov 22, 2022
c341e98
Merge remote-tracking branch 'origin/v1.0.2a' into to_cisdtq
Nov 23, 2022
c8e5b2a
Merge remote-tracking branch 'origin/v1.0.2a' into to_cisdtq
Nov 24, 2022
6aaff99
Update examples and tests for (single kernel) EC
Nov 24, 2022
b70ae52
Merge branch 'v1.0.2a' into to_cisdtq
Nov 24, 2022
90e7319
WIP to prep for UHF implementation
Jan 26, 2023
c2a04c0
Code to create packed C1 -> C4 UHF arrays. Need to unpack.
Jan 27, 2023
11089bd
Add unpacking for unrestricted C amplitudes via ebcc
obackhouse Jan 27, 2023
e847618
Implemented C to T conversion for UHF
obackhouse Jan 27, 2023
5ba4933
Adds routine to build external correction in UHF
obackhouse Jan 27, 2023
6e1b83a
Enable external correction for UHF
obackhouse Jan 27, 2023
1835603
Fixes for UHF external correction
obackhouse Jan 27, 2023
8ee1b3b
Some fixes for UHF external corrections
obackhouse Jan 27, 2023
d31532c
Forgot T4 contractions
obackhouse Jan 27, 2023
65289e1
Comment
Jan 27, 2023
779e95d
Resolve merge
Feb 7, 2023
822c69f
Merge branch 'master' into to_cisdtq
Feb 7, 2023
a6b3fbd
Fix bug in array sizes
obackhouse Feb 28, 2023
4b26d22
Merge branch 'to_cisdtq' of github.com:BoothGroup/Vayesta into to_cisdtq
Feb 28, 2023
6c6138d
Allow slicing for FCI vector with empty lists
Feb 28, 2023
9e7f0f9
Refactorises conversion UHF C->T conversion routines
obackhouse Mar 1, 2023
8262222
Fixes factors in ECCC contractions
obackhouse Mar 2, 2023
701dbe3
Bugfix for C_abaa amplitudes to get EC-CC (RHF) working.
Mar 2, 2023
4645f13
added tests for unrestricted ec-cc
Mar 13, 2023
c24dea2
Resolve minor comments
obackhouse Mar 14, 2023
cc198d3
Updated ec-cc unit tests with UHF, regression
Mar 16, 2023
a3d53b9
added a testsytem variation lih_631g
Mar 16, 2023
8def64f
Fix to example 25-externally-correct.
Mar 16, 2023
b5fb8a5
Changes filename of conversion routines
obackhouse Mar 17, 2023
f6db4e4
Merge branch 'to_cisdtq' of https://github.com/BoothGroup/Vayesta int…
obackhouse Mar 17, 2023
24898b2
Cleans up conversion routines
obackhouse Mar 17, 2023
5c52285
Refactoring and cleaning
obackhouse Mar 20, 2023
cb37eeb
More cleanup and addressing reviews
obackhouse Mar 20, 2023
9d003dd
Fix bug in integral unpacking
obackhouse Mar 20, 2023
9e4dc54
Move t3v terms into separate function
obackhouse Mar 20, 2023
ff11ba5
Starting UHF t3v (buggy)
obackhouse Mar 21, 2023
cabb987
Fixes bugs in UHF external-ccsdv
obackhouse Mar 23, 2023
c98b0c5
Cleans up tests
obackhouse Mar 23, 2023
c1bca35
Fixed bug with single-site embedding in AFM systems.
cjcscott Mar 24, 2023
b0e860d
Added test for dissociated H2 with symmetry broken, reference, as wel…
cjcscott Mar 24, 2023
4806b24
fixed UHF external-ccsdv regression tests
Mar 27, 2023
d9c63e5
Merge pull request #80 from BoothGroup/fix_AFM_single_site
ghb24 Mar 27, 2023
6c04dee
Removed many redundant tests, external-fciv tests
Apr 3, 2023
859b6bf
Trigger CI build
obackhouse Apr 5, 2023
f02001c
Address Max's comments
obackhouse Apr 5, 2023
544cc66
Merge branch 'v1.0.2a' into to_cisdtq
cjcscott Apr 12, 2023
7fe0cdf
Moved to not using density fitting for dissociated UHF test. Also ens…
cjcscott Apr 14, 2023
07f2773
Remove separate options 'external-ccsdv' and 'external-fciv'.
Apr 14, 2023
54e0fa3
Update externally corrected Hubbard model exammple too.
Apr 14, 2023
9f60bcb
TODO added to improve integral transformation for delta-tailoring
Apr 14, 2023
18aa87a
Fixes for tests.
Apr 15, 2023
0c962df
Merge pull request #88 from BoothGroup/fix_h2_dissoc_test
ghb24 Apr 15, 2023
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
1 change: 0 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ on:
push:
branches: [master, dev]
pull_request:
branches: [master, dev]
schedule:
- cron: '0 2 * * *'

Expand Down
6 changes: 6 additions & 0 deletions examples/ewf/molecules/04-bath-options.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import numpy as np
import pyscf
import pyscf.gto
import pyscf.scf
Expand Down Expand Up @@ -45,6 +46,11 @@
# of BNOs for a given threshold, and results in a smaller bath for a given threshold.
# Other options (not shown) include projecting out all couplings to the DMET bath space, or just projecting
# one index.
# The options below are default
emb_mp2_projdmet = vayesta.ewf.EWF(mf, bath_options=dict(bathtype='mp2', threshold=1e-4,
project_dmet_order=2, project_dmet_mode='squared-entropy'))
emb_mp2_projdmet.kernel()
assert(np.allclose(emb_mp2_projdmet.e_tot, emb_mp2.e_tot))
# To turn off this projection (which was not used in 10.1103/PhysRevX.12.011046),
# use `project_dmet_order = 0`:
bath = dict(bathtype='mp2', threshold=1e-4, project_dmet_order=0)
Expand Down
12 changes: 7 additions & 5 deletions examples/ewf/molecules/11-fragmentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,21 @@
mf.kernel()

# Embedded CCSD
emb_iao = vayesta.ewf.EWF(mf, bno_threshold=1e-6)
emb_iao = vayesta.ewf.EWF(mf, bath_options=dict(threshold=1e-6))
# If calling the kernel without initializing the fragmentation,
# IAO fragmentation is used automatically:
# It can be initialized manually by calling emb.iao_fragmentation()
# IAO fragmentation is used automatically.
# It can be initialized manually by calling:
with emb_iao.iao_fragmentation() as f:
f.add_all_atomic_fragments()
emb_iao.kernel()

emb_iaopao = vayesta.ewf.EWF(mf, bno_threshold=1e-6)
emb_iaopao = vayesta.ewf.EWF(mf, bath_options=dict(threshold=1e-6))
# To use IAO+PAOs, call emb.iaopao_fragmentation() before the kernel:
with emb_iaopao.iaopao_fragmentation() as f:
f.add_all_atomic_fragments()
emb_iaopao.kernel()

emb_sao = vayesta.ewf.EWF(mf, bno_threshold=1e-6)
emb_sao = vayesta.ewf.EWF(mf, bath_options=dict(threshold=1e-6))
# To use Lowdin AOs (SAOs), call emb.sao_fragmentation() before the kernel:
with emb_sao.sao_fragmentation() as f:
f.add_all_atomic_fragments()
Expand Down
62 changes: 62 additions & 0 deletions examples/ewf/molecules/25-externally-correct.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import numpy as np
import pyscf
import pyscf.gto
import pyscf.scf
import pyscf.cc
import pyscf.fci
import vayesta
import vayesta.ewf
from vayesta.misc import molecules

mol = pyscf.gto.Mole()
mol.atom = """
Se 0.0000 0.0000 0.2807
O 0.0000 1.3464 -0.5965
O 0.0000 -1.3464 -0.5965
"""
mol.basis = 'cc-pVDZ'
mol.output = 'pyscf.out'
mol.build()

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

# Reference full system CCSD:
cc = pyscf.cc.CCSD(mf)
cc.kernel()

# 1) Consider setup where you have a complete CCSD, externally corrected by local atomic fragment+DMET FCI clusters
emb = vayesta.ewf.EWF(mf)
with emb.iao_fragmentation() as f:
# Add all atomic FCI fragments with DMET bath
# Store the FCI wave functions as CCSDTQ types, so they can be used for correction later.
# These want to be flagged as 'auxiliary', as they are solved first, and then used as constraints for the
# non-auxiliary fragments.
fci_frags = f.add_all_atomic_fragments(solver='FCI', bath_options=dict(bathtype='dmet'), store_wf_type='CCSDTQ', auxiliary=True)
# Add single 'complete' CCSD fragment covering all IAOs
ccsd_frag = f.add_full_system(solver='CCSD', bath_options=dict(bathtype='full'))
# Setup the external correction from the CCSD fragment.
# Main option is 'projectors', which should be an integer between 0 and 2 (inclusive).
# The larger the number, the more fragment projectors are applied to the correcting T2 contributions, and less
# 'bath' correlation from the FCI clusters is used as a constraint in the external correction of the CCSD clusters.
# For multiple constraining fragments, proj=0 will double-count the correction due to overlapping bath spaces, and
# in this case, only proj=1 will be exact in the limit of enlarging (FCI) bath spaces.
# Note that there is also the option 'low_level_coul' (default True). For the important T3 * V contribution to the
# T2 amplitudes, this determines whether the V is expressed in the FCI or CCSD cluster space. The CCSD cluster is
# larger, and hence this is likely to be better (and is default), as the correction is longer-ranged (though slightly more expensive).
ccsd_frag.add_external_corrections(fci_frags, correction_type='external', projectors=1)
emb.kernel()
print('Total energy from full system CCSD tailored (CCSD Coulomb interaction) by atomic FCI fragments (projectors=1): {}'.format(emb.e_tot))

# 2) Now, we also fragment the CCSD spaces, and use BNOs. These CCSD fragments are individually externally corrected from the FCI clusters.
# Similar set up, but we now have multiple CCSD clusters.
emb = vayesta.ewf.EWF(mf)
with emb.iao_fragmentation() as f:
fci_frags = f.add_all_atomic_fragments(solver='FCI', bath_options=dict(bathtype='dmet'), store_wf_type='CCSDTQ', auxiliary=True)
ccsd_frags = f.add_all_atomic_fragments(solver='CCSD', bath_options=dict(bathtype='mp2', threshold=1.e-5))
# Now add external corrections to all CCSD clusters, and use 'external' correction, with 2 projectors and only contracting with the FCI integrals
for cc_frag in ccsd_frags:
cc_frag.add_external_corrections(fci_frags, correction_type='external', projectors=2, low_level_coul=False)
emb.kernel()
print('Total energy from embedded CCSD tailored (FCI Coulomb interaction) by atomic FCI fragments (projectors=2): {}'.format(emb.e_tot))
111 changes: 111 additions & 0 deletions examples/ewf/other/61-ext-corr-hubbard-1D.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import pyscf
import pyscf.cc
import pyscf.fci
import vayesta
import vayesta.ewf
import vayesta.lattmod

nsite = 10
nelectron = nsite
hubbard_u = 4.0
mol = vayesta.lattmod.Hubbard1D(nsite, nelectron=nelectron, hubbard_u=hubbard_u)
mf = vayesta.lattmod.LatticeMF(mol)
mf.kernel()
assert(mf.converged)

# Reference full system CCSD and FCI
cc = pyscf.cc.CCSD(mf)
cc.kernel()
fci = pyscf.fci.FCI(mf)
fci.threads = 1
fci.conv_tol = 1e-12
fci.davidson_only = True
fci.kernel()

# Perform embedded FCI with two sites
emb_simp = vayesta.ewf.EWF(mf, solver='FCI', bath_options=dict(bathtype='dmet'))
with emb_simp.site_fragmentation() as f:
f.add_atomic_fragment([0, 1], sym_factor=nsite/2, nelectron_target=2*nelectron/nsite)
emb_simp.kernel()

# Perform full system CCSD, externally corrected by two-site+DMET bath FCI level clusters
emb = vayesta.ewf.EWF(mf)
fci_frags = []
with emb.site_fragmentation() as f:
# Set up a two-site FCI fragmentation of full system as auxiliary clusters
# Ensure the right number of electrons on each fragment space of the FCI calculation.
fci_frags.append(f.add_atomic_fragment([0, 1], solver='FCI', bath_options=dict(bathtype='dmet'), store_wf_type='CCSDTQ', nelectron_target=2*nelectron/nsite, auxiliary=True))
# Add single 'complete' CCSD fragment covering all sites
ccsd_frag = f.add_full_system(solver='CCSD', bath_options=dict(bathtype='full'), solver_options=dict(solve_lambda=False, init_guess='CISD'))
# Add symmetry-derived FCI fragments to avoid multiple calculations
fci_frags.extend(fci_frags[0].add_tsymmetric_fragments(tvecs=[5, 1, 1])

e_extcorr = []
extcorr_conv = []
#Main options: 'projectors', which should be an integer between 0 and 2 (inclusive).
#The larger the number, the more fragment projectors are applied to the correcting T2 contributions, and less
#'bath' correlation from the FCI clusters is used as a constraint in the external correction of the CCSD clusters.
#NOTE that with multiple FCI fragments providing constraints and overlapping bath spaces, proj=0 will
#overcount the correction, so do not use with multiple FCI clusters. It will not e.g. tend to the right answer as
#the FCI bath space becomes complete (for which you must have proj=1). Only use with a single FCI fragment.
ccsd_frag.add_external_corrections(fci_frags, correction_type='external', projectors=1)
emb.kernel()
e_extcorr.append(emb.e_tot); extcorr_conv.append(emb.converged)

# For subsequent calculations where we have just changed the mode/projectors in the external tailoring, we want to avoid having
# to resolve the FCI fragments. Set them to inactive, so just the CCSD fragments will be resolved.
for fci_frag in fci_frags:
fci_frag.active = False

ccsd_frag.clear_external_corrections() # Clear any previous corrections applied
ccsd_frag.add_external_corrections(fci_frags, correction_type='external', projectors=2)
emb.kernel()
e_extcorr.append(emb.e_tot); extcorr_conv.append(emb.converged)

ccsd_frag.clear_external_corrections() # Clear any previous corrections applied
ccsd_frag.add_external_corrections(fci_frags, correction_type='external', projectors=1, low_level_coul=False)
emb.kernel()
e_extcorr.append(emb.e_tot); extcorr_conv.append(emb.converged)

ccsd_frag.clear_external_corrections() # Clear any previous corrections applied
ccsd_frag.add_external_corrections(fci_frags, correction_type='external', projectors=2, low_level_coul=False)
emb.kernel()
e_extcorr.append(emb.e_tot); extcorr_conv.append(emb.converged)

# Compare to a simpler tailoring
e_tailor = []
tailor_conv = []
ccsd_frag.clear_external_corrections()
ccsd_frag.add_external_corrections(fci_frags, correction_type='tailor', projectors=1)
emb.kernel()
e_tailor.append(emb.e_tot); tailor_conv.append(emb.converged)
ccsd_frag.clear_external_corrections()
ccsd_frag.add_external_corrections(fci_frags, correction_type='tailor', projectors=2)
emb.kernel()
e_tailor.append(emb.e_tot); tailor_conv.append(emb.converged)

# Compare to a delta-tailoring, where the correction is the difference between full-system
# CCSD and CCSD in the FCI cluster.
e_dtailor = []
dtailor_conv = []
ccsd_frag.clear_external_corrections()
ccsd_frag.add_external_corrections(fci_frags, correction_type='delta-tailor', projectors=1)
emb.kernel()
e_dtailor.append(emb.e_tot); dtailor_conv.append(emb.converged)
ccsd_frag.clear_external_corrections()
ccsd_frag.add_external_corrections(fci_frags, correction_type='delta-tailor', projectors=2)
emb.kernel()
e_dtailor.append(emb.e_tot); dtailor_conv.append(emb.converged)

print("E(MF)= %+16.8f Ha, conv = %s" % (mf.e_tot/nsite, mf.converged))
print("E(CCSD)= %+16.8f Ha, conv = %s" % (cc.e_tot/nsite, cc.converged))
print("E(FCI)= %+16.8f Ha, conv = %s" % (fci.e_tot/nsite, fci.converged))
print("E(Emb. FCI, 2-site)= %+16.8f Ha, conv = %s" % (emb_simp.e_tot/nsite, emb_simp.converged))
print("E(EC-CCSD, 2-site FCI, 1 proj, ccsd V)= %+16.8f Ha, conv = %s" % ((e_extcorr[0]/nsite), extcorr_conv[0]))
print("E(EC-CCSD, 2-site FCI, 2 proj, ccsd V)= %+16.8f Ha, conv = %s" % ((e_extcorr[1]/nsite), extcorr_conv[1]))
print("E(EC-CCSD, 2-site FCI, 1 proj, fci V)= %+16.8f Ha, conv = %s" % ((e_extcorr[2]/nsite), extcorr_conv[2]))
print("E(EC-CCSD, 2-site FCI, 2 proj, fci V)= %+16.8f Ha, conv = %s" % ((e_extcorr[3]/nsite), extcorr_conv[3]))
print("E(T-CCSD, 2-site FCI, 1 proj)= %+16.8f Ha, conv = %s" % ((e_tailor[0]/nsite), tailor_conv[0]))
print("E(T-CCSD, 2-site FCI, 2 proj)= %+16.8f Ha, conv = %s" % ((e_tailor[1]/nsite), tailor_conv[1]))
print("E(DT-CCSD, 2-site FCI, 1 proj)= %+16.8f Ha, conv = %s" % ((e_dtailor[0]/nsite), dtailor_conv[0]))
print("E(DT-CCSD, 2-site FCI, 2 proj)= %+16.8f Ha, conv = %s" % ((e_dtailor[1]/nsite), dtailor_conv[1]))
8 changes: 5 additions & 3 deletions vayesta/core/qemb/fragment.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,9 +333,11 @@ def cluster(self, value):
raise RuntimeError("Cannot set attribute cluster in symmetry derived fragment.")
self._cluster = value

def reset(self, reset_bath=True, reset_cluster=True, reset_eris=True):
self.log.debugv("Resetting %s (reset_bath= %r, reset_cluster= %r, reset_eris= %r)",
self, reset_bath, reset_cluster, reset_eris)
def reset(self, reset_bath=True, reset_cluster=True, reset_eris=True, reset_inactive=True):
self.log.debugv("Resetting %s (reset_bath= %r, reset_cluster= %r, reset_eris= %r, reset_inactive= %r)",
self, reset_bath, reset_cluster, reset_eris, reset_inactive)
if not reset_inactive and not self.active:
return
if reset_bath:
self._dmet_bath = None
self._bath_factory_occ = None
Expand Down
2 changes: 1 addition & 1 deletion vayesta/core/qemb/qemb.py
Original file line number Diff line number Diff line change
Expand Up @@ -1572,7 +1572,7 @@ def check_fragment_symmetry(self, dm1, symtol=1e-6):
for child in children:
charge_err, spin_err = parent.get_symmetry_error(child, dm1=dm1)
if (max(charge_err, spin_err) > symtol):
raise RuntimeError("%s and %s not symmetric! Errors: charge= %.2e spin= %.2e"
raise SymmetryError("%s and %s not symmetric! Errors: charge= %.2e spin= %.2e"
% (parent.name, child.name, charge_err, spin_err))
else:
self.log.debugv("Symmetry between %s and %s: Errors: charge= %.2e spin= %.2e",
Expand Down
7 changes: 6 additions & 1 deletion vayesta/core/scmf/scmf.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,12 @@ def kernel(self, *args, **kwargs):

dm1 = self.mf.make_rdm1()
# Check symmetry
self.emb.check_fragment_symmetry(dm1)
try:
self.emb.check_fragment_symmetry(dm1)
except SymmetryError:
self.log.error("Symmetry check failed in %s", self.name)
self.converged = False
break

# Check convergence
conv, de, ddm = self.check_convergence(e_tot, dm1, e_last, dm1_last)
Expand Down
20 changes: 19 additions & 1 deletion vayesta/core/types/wf/ccsdtq.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,35 @@ def CCSDTQ_WaveFunction(mo, *args, **kwargs):


class RCCSDTQ_WaveFunction(wf_types.WaveFunction):
# TODO: Contract T4's down to intermediates to reduce EC-CC memory overheads.
Copy link
Contributor

Choose a reason for hiding this comment

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

The RCCSDTQ_WaveFunction would not be the right place for contracting out T4s

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, I guess we would make a new wave function class, which has T1, T2, T3, and some additional intermediates. It wouldn't be part of the ccsdtq class (though I'm not sure what we would call it)...

Copy link
Contributor

Choose a reason for hiding this comment

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

It can be a specialized ExternalCorrection class

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, exactly, but inheriting from WaveFunction


def __init__(self, mo, t1, t2, t3, t4):
super().__init__(mo)
self.t1 = t1
self.t2 = t2
self.t3 = t3
self.t4 = t4
self._check_amps()

def _check_amps(self):
if not (isinstance(self.t4, tuple) and len(self.t4) == 2):
raise ValueError("t4 definition in RCCSDTQ wfn requires tuple of (abaa, abab) spin signatures")

def as_ccsdtq(self):
return self

def as_ccsd(self):
if self.projector is not None:
raise NotImplementedError
return wf_types.CCSD_WaveFunction(self.mo, self.t1, self.t2)

def as_cisd(self, c0=1.0):
return self.as_ccsd().as_cisd()

class UCCSDTQ_WaveFunction(RCCSDTQ_WaveFunction):
pass
def _check_amps(self):
if not (isinstance(self.t3, tuple) and len(self.t3) == 4):
raise ValueError("t4 definition in UCCSDTQ wfn requires tuple of (aaa, aba, bab, bbb) spin signatures")
if not (isinstance(self.t4, tuple) and len(self.t4) == 5):
raise ValueError(
"t4 definition in UCCSDTQ wfn requires tuple of (aaaa, aaab, abab, abbb, bbbb) spin signatures")
69 changes: 37 additions & 32 deletions vayesta/core/types/wf/cisdtq.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import vayesta
from vayesta.core.util import *
from vayesta.core.types import wf as wf_types
from vayesta.core.types.wf import t_to_c


def CISDTQ_WaveFunction(mo, *args, **kwargs):
Expand All @@ -21,43 +22,47 @@ def __init__(self, mo, c0, c1, c2, c3, c4):
self.c2 = c2
self.c3 = c3
self.c4 = c4
if not (isinstance(c4, tuple) and len(c4) == 2):
raise ValueError("c4 definition in RCISDTQ wfn requires tuple of (abaa, abab) spin signatures")

def as_ccsdtq(self):
t1 = self.c1/self.c0
t2 = self.c2/self.c0 - einsum('ia,jb->ijab', t1, t1)
raise NotImplementedError
# TODO:
# see also THE JOURNAL OF CHEMICAL PHYSICS 147, 154105 (2017)
t3 = self.c3/self.c0 # - C1*C2 - (C1^3)/3
t4 = self.c4/self.c0 # - C1*C3 - (C2^2)/2 - C1^2*C2 - (C1^4)/4
c1 = self.c1 / self.c0
c2 = self.c2 / self.c0
c3 = self.c3 / self.c0
c4 = tuple(c / self.c0 for c in self.c4)

t1 = t_to_c.t1_rhf(c1)
t2 = t_to_c.t2_rhf(t1, c2)
t3 = t_to_c.t3_rhf(t1, t2, c3)
t4 = t_to_c.t4_rhf(t1, t2, t3, c4)

return wf_types.RCCSDTQ_WaveFunction(self.mo, t1=t1, t2=t2, t3=t3, t4=t4)


class UCISDTQ_WaveFunction(RCISDTQ_WaveFunction):
class UCISDTQ_WaveFunction(wf_types.WaveFunction):

def __init__(self, mo, c0, c1, c2, c3, c4):
super().__init__(mo)
self.c0 = c0
self.c1 = c1
self.c2 = c2
self.c3 = c3
self.c4 = c4
if not (isinstance(c3, tuple) and len(c3) == 4):
raise ValueError("c4 definition in UCISDTQ wfn requires tuple of (aaa, aba, bab, bbb) spin signatures")
if not (isinstance(c4, tuple) and len(c4) == 5):
raise ValueError(
"c4 definition in UCISDTQ wfn requires tuple of (aaaa, aaab, abab, abbb, bbbb) spin signatures")

def as_ccsdtq(self):
c1a, c1b = self.c1
c2aa, c2ab, c2bb = self.c2
# TODO
#c3aaa, c3aab, ... = self.c3
#c4aaaa, c4aaab, ... = self.c4

# T1
t1a = c1a/self.c0
t1b = c1b/self.c0
# T2
t2aa = c2aa/self.c0 - einsum('ia,jb->ijab', t1a, t1a) + einsum('ib,ja->ijab', t1a, t1a)
t2bb = c2bb/self.c0 - einsum('ia,jb->ijab', t1b, t1b) + einsum('ib,ja->ijab', t1b, t1b)
t2ab = c2ab/self.c0 - einsum('ia,jb->ijab', t1a, t1b)
# T3
raise NotImplementedError
#t3aaa = c3aaa/self.c0 - einsum('ijab,kc->ijkabc', t2a, t1a) - ...
# T4
#t4aaaa = c4aaaa/self.c0 - einsum('ijkabc,ld->ijklabcd', t3a, t1a) - ...

t1 = (t1a, t1b)
t2 = (t2aa, t2ab, t2bb)
# TODO
#t3 = (t3aaa, t3aab, ...)
#t4 = (t4aaaa, t4aaab, ...)
c1 = tuple(c / self.c0 for c in self.c1)
c2 = tuple(c / self.c0 for c in self.c2)
c3 = tuple(c / self.c0 for c in self.c3)
c4 = tuple(c / self.c0 for c in self.c4)

t1 = t_to_c.t1_uhf(c1)
t2 = t_to_c.t2_uhf(t1, c2)
t3 = t_to_c.t3_uhf(t1, t2, c3)
t4 = t_to_c.t4_uhf(t1, t2, t3, c4)

return wf_types.UCCSDTQ_WaveFunction(self.mo, t1=t1, t2=t2, t3=t3, t4=t4)
Loading