Skip to content

Commit

Permalink
Merge pull request #36 from BoothGroup/active_space_redux
Browse files Browse the repository at this point in the history
Implements CCSDt
  • Loading branch information
obackhouse committed Oct 28, 2023
2 parents 6ea4eb1 + a33e57c commit d1ce771
Show file tree
Hide file tree
Showing 9 changed files with 15,552 additions and 2 deletions.
1 change: 1 addition & 0 deletions FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ The following table summarises the available methods and routines for the ansatz
| CCSDT | RUG | RUG | RUG | | | | RUG | RUG | - |
| CCSDTQ | g | g | | | | | | | - |
| CCSD(T) | RuG | RuG | | | | | | | - |
| CCSDt | RG | RG | | | | | | | - |
| CCSDt' | RUG | RUG | | | | | | | - |
| CC2 | RUG | RUG | RUG | | | | RUG | RUG | - |
| CC3 | RUG | RUG | | | | | | | - |
Expand Down
2 changes: 2 additions & 0 deletions ebcc/ansatz.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"QCISD": ("QCISD", "", 0, 0),
"DCD": ("DCD", "", 0, 0),
"DCSD": ("DCSD", "", 0, 0),
"CCSDt": ("CCSDt", "", 0, 0),
"CCSDt'": ("CCSDt'", "", 0, 0),
"CCSD-S-1-1": ("CCSD", "S", 1, 1),
"CCSD-SD-1-1": ("CCSD", "SD", 1, 1),
Expand Down Expand Up @@ -244,6 +245,7 @@ def fermionic_cluster_ranks(self, spin_type="G"):
"S": [("t1", "ov", 1)],
"D": [("t2", "oovv", 2)],
"T": [("t3", "ooovvv", 3)],
"t": [("t3", "ooOvvV", 3)],
"t'": [("t3", "OOOVVV", 3)],
}
if spin_type == "R":
Expand Down
1,550 changes: 1,550 additions & 0 deletions ebcc/codegen/GCCSDt.py

Large diffs are not rendered by default.

3,121 changes: 3,121 additions & 0 deletions ebcc/codegen/RCCSDt.py

Large diffs are not rendered by default.

10,413 changes: 10,413 additions & 0 deletions ebcc/codegen/UCCSDt.py

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions examples/04-ccsdt_active_space.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""
Example of a CCSDt' calculation with T3 amplitudes in an active
space.
Example of a CCSDt' and CCSDt calculations with T3 amplitudes in an
active space.
"""

import numpy as np
Expand Down Expand Up @@ -33,3 +33,7 @@
# Run a CCSDt' calculation
ccsdt = REBCC(mf, ansatz="CCSDt'", space=space)
ccsdt.kernel()

# Run a CCSDt calculation
ccsdt = REBCC(mf, ansatz="CCSDt", space=space)
ccsdt.kernel()
176 changes: 176 additions & 0 deletions tests/test_GCCSDt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
"""Tests for the GCCSDt model.
"""

import tempfile
import unittest

import numpy as np
import pytest
from pyscf import gto, lib, scf, fci

from ebcc import GEBCC, REBCC, Space, NullLogger, util


@pytest.mark.regression
class GCCSDt_Tests(unittest.TestCase):
"""Test GCCSDt against regression.
"""

def test_3_electron_exact_fully_active(self):
mol = gto.M(
atom="H 0 0 0; H 0 0 1",
basis="6-31g",
spin=1,
charge=-1,
verbose=0,
)
assert mol.nelectron == 3

mf = scf.UHF(mol)
mf.kernel()
gmf = mf.to_ghf()

space = Space(
gmf.mo_occ > 0,
np.zeros_like(gmf.mo_occ, dtype=bool),
np.ones_like(gmf.mo_occ, dtype=bool),
)

ccsdt = GEBCC(
gmf,
ansatz="CCSDt",
space=space,
conv_tol=1e-10,
log=NullLogger(),
)
ccsdt.kernel()
e1 = ccsdt.e_tot

ci = fci.FCI(mf)
ci.conv_tol = 1e-10
e2 = ci.kernel()[0]

self.assertAlmostEqual(e1, e2, 6)

def test_fully_active(self):
mol = gto.M(
atom="H 0 0 0; Li 0 0 1",
basis="sto3g",
verbose=0,
)

mf = scf.RHF(mol)
mf.kernel()
gmf = mf.to_ghf()

space = Space(
gmf.mo_occ > 0,
np.zeros_like(gmf.mo_occ, dtype=bool),
np.ones_like(gmf.mo_occ, dtype=bool),
)

ccsdt = GEBCC(
gmf,
ansatz="CCSDt",
space=space,
conv_tol=1e-10,
log=NullLogger(),
)
ccsdt.kernel()
e1 = ccsdt.e_tot

ccsdt = GEBCC(
gmf,
ansatz="CCSDT",
space=space,
conv_tol=1e-10,
log=NullLogger(),
)
ccsdt.kernel()
e2 = ccsdt.e_tot

self.assertAlmostEqual(e1, e2, 8)

def test_none_active(self):
mol = gto.M(
atom="H 0 0 0; Li 0 0 1",
basis="sto3g",
verbose=0,
)

mf = scf.RHF(mol)
mf.kernel()
gmf = mf.to_ghf()

space = Space(
gmf.mo_occ > 0,
np.zeros_like(gmf.mo_occ, dtype=bool),
np.zeros_like(gmf.mo_occ, dtype=bool),
)

ccsdt = GEBCC(
gmf,
ansatz="CCSDt",
space=space,
conv_tol=1e-10,
log=NullLogger(),
)
ccsdt.kernel()
e1 = ccsdt.e_tot

ccsdt = GEBCC(
gmf,
ansatz="CCSD",
space=space,
conv_tol=1e-10,
log=NullLogger(),
)
ccsdt.kernel()
e2 = ccsdt.e_tot

self.assertAlmostEqual(e1, e2, 8)

def test_dump(self):
mol = gto.M(
atom="H 0 0 0; H 0 0 1",
basis="6-31g",
spin=1,
charge=-1,
verbose=0,
)

mf = scf.UHF(mol)
mf.kernel()
gmf = mf.to_ghf()

active = np.zeros_like(gmf.mo_occ, dtype=bool)
active[np.where(gmf.mo_occ > 0)[0][-1]] = True
active[np.where(gmf.mo_occ == 0)[0][0]] = True
space = Space(
gmf.mo_occ > 0,
np.zeros_like(gmf.mo_occ, dtype=bool),
active,
)

ccsdt = GEBCC(
gmf,
ansatz="CCSDt",
space=space,
conv_tol=1e-10,
log=NullLogger(),
)
ccsdt.kernel()

file = "%s/ebcc.h5" % tempfile.gettempdir()
ccsdt.write(file)
ccsdt_load = GEBCC.read(file, log=NullLogger())

np.testing.assert_almost_equal(ccsdt_load.t1, ccsdt.t1)
np.testing.assert_almost_equal(ccsdt_load.t2, ccsdt.t2)
np.testing.assert_almost_equal(ccsdt_load.t3, ccsdt.t3)



if __name__ == "__main__":
print("Tests for GCCSDt")
unittest.main()
175 changes: 175 additions & 0 deletions tests/test_RCCSDt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
"""Tests for the RCCSDt model.
"""

import itertools
import tempfile
import unittest

import numpy as np
import pytest
import scipy
from pyscf import gto, lib, scf, fci

from ebcc import GEBCC, REBCC, Space, NullLogger, util


@pytest.mark.regression
class RCCSDt_Tests(unittest.TestCase):
"""Test RCCSDt against GCCSDt.
"""

@classmethod
def setUpClass(cls):
mol = gto.Mole()
mol.atom = "H 0 0 0; Li 0 0 1"
mol.basis = "6-31g"
mol.verbose = 0
mol.build()

mf = scf.RHF(mol)
mf.kernel()

active = np.zeros_like(mf.mo_occ, dtype=bool)
active[np.where(mf.mo_occ > 0)[0][-1]] = True
active[np.where(mf.mo_occ == 0)[0][0]] = True
space = Space(
mf.mo_occ > 0,
np.zeros_like(mf.mo_occ, dtype=bool),
active,
)

rccsdt = REBCC(
mf,
ansatz="CCSDt",
space=space,
log=NullLogger(),
)
rccsdt.options.e_tol = 1e-10
rccsdt.options.t_tol = 1e-8
rccsdt.kernel()

gmf = mf.to_ghf()

active = np.zeros_like(gmf.mo_occ, dtype=bool)
active[np.isclose(gmf.mo_energy, mf.mo_energy[np.where(mf.mo_occ > 0)[0][-1]])] = True
active[np.isclose(gmf.mo_energy, mf.mo_energy[np.where(mf.mo_occ == 0)[0][0]])] = True
space = Space(
gmf.mo_occ > 0,
np.zeros_like(gmf.mo_occ, dtype=bool),
active,
)

gccsdt = GEBCC(
gmf,
ansatz="CCSDt",
space=space,
log=NullLogger(),
)
gccsdt.options.e_tol = 1e-10
gccsdt.options.t_tol = 1e-8
gccsdt.kernel()

osort = list(itertools.chain(*zip(range(rccsdt.nocc), range(rccsdt.nocc, 2*rccsdt.nocc))))
vsort = list(itertools.chain(*zip(range(rccsdt.nvir), range(rccsdt.nvir, 2*rccsdt.nvir))))
fsort = list(itertools.chain(*zip(range(rccsdt.nmo), range(rccsdt.nmo, 2*rccsdt.nmo))))

cls.mf, cls.rccsdt, cls.gccsdt = mf, rccsdt, gccsdt
cls.osort, cls.vsort, cls.fsort = osort, vsort, fsort

@classmethod
def tearDownClass(cls):
del cls.mf, cls.rccsdt, cls.gccsdt
del cls.osort, cls.vsort, cls.fsort

def test_energy(self):
a = self.rccsdt.e_tot
b = self.gccsdt.e_tot
self.assertAlmostEqual(a, b, 6)

def test_t1(self):
a = scipy.linalg.block_diag(self.rccsdt.t1, self.rccsdt.t1)[self.osort][:, self.vsort]
b = self.gccsdt.t1
np.testing.assert_almost_equal(a, b, 6)


@pytest.mark.regression
class RCCSDt_Frozen_Tests(unittest.TestCase):
"""Test RCCSDt against GCCSDt with a frozen core approximation.
"""

@classmethod
def setUpClass(cls):
mol = gto.Mole()
mol.atom = "H 0 0 0; Li 0 0 1"
mol.basis = "6-31g"
mol.verbose = 0
mol.build()

mf = scf.RHF(mol)
mf.kernel()

active = np.zeros_like(mf.mo_occ, dtype=bool)
active[np.where(mf.mo_occ > 0)[0][-1]] = True
active[np.where(mf.mo_occ == 0)[0][0]] = True
frozen = np.zeros_like(mf.mo_occ, dtype=bool)
frozen[0] = True
space = Space(
mf.mo_occ > 0,
frozen,
active,
)

rccsdt = REBCC(
mf,
ansatz="CCSDt",
space=space,
log=NullLogger(),
)
rccsdt.options.e_tol = 1e-10
rccsdt.options.t_tol = 1e-8
rccsdt.kernel()

gmf = mf.to_ghf()

active = np.zeros_like(gmf.mo_occ, dtype=bool)
active[np.isclose(gmf.mo_energy, mf.mo_energy[np.where(mf.mo_occ > 0)[0][-1]])] = True
active[np.isclose(gmf.mo_energy, mf.mo_energy[np.where(mf.mo_occ == 0)[0][0]])] = True
frozen = np.zeros_like(gmf.mo_occ, dtype=bool)
frozen[np.isclose(gmf.mo_energy, mf.mo_energy[0])] = True
space = Space(
gmf.mo_occ > 0,
frozen,
active,
)

gccsdt = GEBCC(
gmf,
ansatz="CCSDt",
space=space,
log=NullLogger(),
)
gccsdt.options.e_tol = 1e-10
gccsdt.options.t_tol = 1e-8
gccsdt.kernel()

osort = list(itertools.chain(*zip(range(rccsdt.nocc), range(rccsdt.nocc, 2*rccsdt.nocc))))
vsort = list(itertools.chain(*zip(range(rccsdt.nvir), range(rccsdt.nvir, 2*rccsdt.nvir))))
fsort = list(itertools.chain(*zip(range(rccsdt.nmo), range(rccsdt.nmo, 2*rccsdt.nmo))))

cls.mf, cls.rccsdt, cls.gccsdt = mf, rccsdt, gccsdt
cls.osort, cls.vsort, cls.fsort = osort, vsort, fsort

@classmethod
def tearDownClass(cls):
del cls.mf, cls.rccsdt, cls.gccsdt
del cls.osort, cls.vsort, cls.fsort

def test_energy(self):
a = self.rccsdt.e_tot
b = self.gccsdt.e_tot
self.assertAlmostEqual(a, b, 6)


if __name__ == "__main__":
print("Tests for RCCSDt")
unittest.main()
Loading

0 comments on commit d1ce771

Please sign in to comment.