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

Refactors solver/__init__.py #141

Merged
merged 53 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
e60de41
Refactors solver/__init__.py
maxnus Sep 23, 2023
c7508f4
Fixes check_solver_config argument order
maxnus Sep 23, 2023
662d8d4
Fixes EBCC inconsistent solver exception
maxnus Sep 23, 2023
02df0f0
More fixes
maxnus Sep 23, 2023
6cff101
Testing with latest pyscf
basilib Feb 29, 2024
e611839
Add kwarg to function
basilib Mar 1, 2024
14fc95a
Fix bug for kUHF and consistent conversion of ROHF to UHF
basilib Mar 1, 2024
23cd4f4
Fixes for new pyscf SCF class hierarchy
basilib Mar 4, 2024
7433f55
Add kwarg for LatticeUHF
basilib Mar 4, 2024
59372be
Fix test for new SCF class hierarchy
basilib Mar 4, 2024
51ba7c3
Change nuclear energy
basilib Apr 2, 2024
e42af2f
Clean up
basilib Apr 4, 2024
996606e
More comments
basilib Apr 11, 2024
561d0e1
Add option to use DMET energy (democratic partitioning) in EWF
basilib Apr 11, 2024
ae1fded
Add dyson callback solver example
basilib Apr 11, 2024
78ae86f
Some comments for energy functionals
basilib Apr 11, 2024
5927da9
Updates comments
basilib Apr 12, 2024
6ccf11a
Fix typo
basilib Apr 12, 2024
40407e6
Update 65-callback-solver-dyson.py
basilib Apr 12, 2024
622ae39
Merge pull request #164 from BoothGroup/callback_solver
basilib Apr 12, 2024
aa0b8a8
Simplify MF spin type check
basilib Apr 12, 2024
6e44033
Change tolerence
basilib Apr 12, 2024
e1663db
Revert "Change nuclear energy"
basilib Apr 15, 2024
f617abc
Temporary change to check compatibility with old pyscf
basilib Apr 16, 2024
04c3ab8
Point to pyscf@master
basilib Apr 16, 2024
7023754
Merge pull request #156 from BoothGroup/Testing-with-latest-pyscf
basilib Apr 17, 2024
f9e323a
MPI support for 1RDM
basilib Apr 22, 2024
7ca8a1c
Add MF contrib after reduce
basilib Apr 22, 2024
9a5fde0
Add nreduce for dmet energy
Apr 23, 2024
c479945
UHF 1DM with MPI
Apr 23, 2024
0b3eb59
Democratically partitioned 2DM with MPI
basilib Apr 23, 2024
89fb850
UHF 2DM with MPI
basilib Apr 23, 2024
84a105e
Remove unused code
basilib Apr 23, 2024
559bf92
Update docstring
basilib Apr 24, 2024
4646a31
Update docstring
basilib Apr 24, 2024
ec4e31a
Merge pull request #166 from BoothGroup/mpi_rdm
basilib Apr 24, 2024
4dc442f
Set fragment converged property from callback results
maxbortone May 8, 2024
ea83e38
Merge pull request #167 from maxbortone/fix-callback-converged
basilib May 12, 2024
4af95c2
Calculate correlation energy when using callback solver
basilib May 14, 2024
96af4e9
Add callback solver example with CISD amplitudes
basilib May 14, 2024
fb9b948
Convert CISD amplitudes to CCSD amplitudes to use patitioned cumulant…
basilib May 14, 2024
b853823
Test callback solver with CISD amplitudes
basilib May 14, 2024
5a4c737
Merge pull request #168 from BoothGroup/callback_solver
basilib May 14, 2024
47a7a23
Callback solver with density fitting example
basilib May 16, 2024
8144953
Fix typo
basilib May 16, 2024
ab6c508
Merge pull request #169 from BoothGroup/callback_solver
basilib Jun 1, 2024
5742128
Fix typos
maxbortone Jun 7, 2024
ed3c9c5
Add support for directories in cluster mol output
maxbortone Jun 7, 2024
353847a
Merge pull request #172 from maxbortone/fix-typos
basilib Jul 31, 2024
eb3d025
Remove EBCC CCSDt test
basilib Jul 31, 2024
317e9b9
Merge pull request #171 from maxbortone/fix-clusmol-ouput
basilib Jul 31, 2024
a9d9621
Merge master
basilib Aug 18, 2024
7888e35
Fix solver captialisation
basilib Aug 20, 2024
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
68 changes: 68 additions & 0 deletions examples/ewdmet/65-callback-solver-dyson.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
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, CISD amplitudes or CCSD amplitudes
# Returning the cluster Green's function moments is also supported. They are calculated with Dyson 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))

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, CISD amplitudes or CCSD amplitudes
def solver(mf):
h1e = mf.get_hcore()
h2e = mf._eri
Expand Down Expand Up @@ -37,7 +39,7 @@ def solver(mf):
bath_opts = dict(bathtype="dmet")

# Run vayesta with user defined solver
emb = vayesta.ewf.EWF(mf, solver="CALLBACK", energy_functional='dm', bath_options=bath_opts, solver_options=dict(callback=solver))
emb = vayesta.ewf.EWF(mf, solver="CALLBACK", energy_functional='dmet', bath_options=bath_opts, solver_options=dict(callback=solver))
# Set up fragments
with emb.iao_fragmentation() as f:
if use_sym:
Expand Down
74 changes: 74 additions & 0 deletions examples/ewf/molecules/66-callback-solver-amplitudes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
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 vayesta.core.types.wf.t_to_c import t1_rhf, t2_rhf

# 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, CISD amplitudes or CCSD amplitudes
def solver(mf):
ci = pyscf.ci.CISD(mf)
energy, civec = ci.kernel()
c0, c1, c2 = ci.cisdvec_to_amplitudes(civec)

# To use CI amplitudues use return the following line and set energy_functional='wf' to use the projected energy in the EWF arguments below
# return dict(c0=c0, c1=c1, c2=c2, converged=True, energy=ci.e_corr)

# Convert CISD amplitudes to CCSD amplitudes to be able to make use of the patitioned cumulant energy functional
t1 = t1_rhf(c1/c0)
t2 = t2_rhf(t1, c2/c0)
return dict(t1=t1, t2=t2, l1=t1, l2=t2, converged=True, energy=ci.e_corr)

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()

# CISD
cisd = pyscf.ci.CISD(mf)
cisd.kernel()

# CCSD
ccsd = pyscf.cc.CCSD(mf)
ccsd.kernel()

# FCI
fci = pyscf.fci.FCI(mf)
fci.kernel()

# Vayesta options
use_sym = True
nfrag = 1
bath_opts = dict(bathtype="dmet")

# Run vayesta with user defined solver
emb = vayesta.ewf.EWF(mf, solver="CALLBACK", energy_functional='dm-t2only', bath_options=bath_opts, solver_options=dict(callback=solver))
# 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("CISD Energy : %s"%cisd.e_tot)
print("CCSD Energy : %s"%ccsd.e_tot)
print("FCI Energy : %s"%fci.e_tot)
print("Emb. Partitioned Cumulant : %s"%emb.e_tot)
58 changes: 58 additions & 0 deletions examples/ewf/solids/67-callback-solver-density-fitting.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import numpy as np

import pyscf
import pyscf.pbc
import pyscf.pbc.scf
import pyscf.pbc.cc
import pyscf.fci

import vayesta
import vayesta.ewf

# 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, CISD amplitudes or CCSD amplitudes
def solver(mf):
h1e = mf.get_hcore()
# Need to convert cderis into standard 4-index tensor when using denisty fitting for the mean-field
cderi = mf.with_df._cderi
cderi = pyscf.lib.unpack_tril(cderi)
h2e = np.einsum('Lpq,Lrs->pqrs', cderi, cderi)
norb = mf.mo_coeff.shape[-1]
nelec = mf.mol.nelec
energy, civec = pyscf.fci.direct_spin0.kernel(h1e, h2e, norb, nelec, conv_tol=1.e-14)
dm1, dm2 = pyscf.fci.direct_spin0.make_rdm12(civec, norb, nelec)
results = dict(dm1=dm1, dm2=dm2, converged=True)
return results

cell = pyscf.pbc.gto.Cell()
cell.a = 3.0 * np.eye(3)
cell.atom = "He 0 0 0"
cell.basis = "cc-pvdz"
#cell.exp_to_discard = 0.1
cell.build()

kmesh = [3, 3, 3]
kpts = cell.make_kpts(kmesh)

# --- Hartree-Fock
kmf = pyscf.pbc.scf.KRHF(cell, kpts)
kmf = kmf.rs_density_fit()
kmf.kernel()

# Vayesta options
nfrag = 1
bath_opts = dict(bathtype="mp2", dmet_threshold=1e-15)

# Run vayesta with user defined solver
emb = vayesta.ewf.EWF(kmf, solver="CALLBACK", energy_functional='dmet', bath_options=bath_opts, solver_options=dict(callback=solver))
# Set up fragments
with emb.iao_fragmentation() as f:
f.add_all_atomic_fragments()
emb.kernel()

print("Hartree-Fock energy : %s"%kmf.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: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ dependencies = [
"scipy>=1.1.0,<=1.10.0",
"h5py>=2.7",
"cvxpy>=1.1",
"pyscf @ git+https://github.com/pyscf/pyscf@e90d8342e29446365f8570682af4a65fe16be27c",
"pyscf @ git+https://github.com/pyscf/pyscf@master",
]
dynamic = ["version"]

Expand Down
2 changes: 1 addition & 1 deletion vayesta/core/qemb/fragment.py
Original file line number Diff line number Diff line change
Expand Up @@ -1160,7 +1160,7 @@ def check_solver(self, solver):
is_eb = "crpa_full" in self.opts.screening
else:
is_eb = False
check_solver_config(is_uhf, is_eb, solver, self.log)
check_solver_config(solver, is_uhf, is_eb, self.log)

def get_solver(self, solver=None):
if solver is None:
Expand Down
13 changes: 9 additions & 4 deletions vayesta/core/qemb/qemb.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ def init_mf(self, mf):
mf = copy.copy(mf)
self.log.debugv("type(mf)= %r", type(mf))
# If the mean-field has k-points, automatically fold to the supercell:
if getattr(mf, "kpts", None) is not None:
if isinstance(mf, pyscf.pbc.scf.khf.KSCF):
with log_time(self.log.timing, "Time for k->G folding of MOs: %s"):
mf = fold_scf(mf)
if isinstance(mf, FoldedSCF):
Expand Down Expand Up @@ -1263,7 +1263,7 @@ def make_rdm1_demo(self, *args, **kwargs):
def make_rdm2_demo(self, *args, **kwargs):
return make_rdm2_demo_rhf(self, *args, **kwargs)

def get_dmet_elec_energy(self, part_cumulant=True, approx_cumulant=True):
def get_dmet_elec_energy(self, part_cumulant=True, approx_cumulant=True, mpi_target=None):
"""Calculate electronic DMET energy via democratically partitioned density-matrices.

Parameters
Expand All @@ -1275,6 +1275,10 @@ def get_dmet_elec_energy(self, part_cumulant=True, approx_cumulant=True):
approx_cumulant: bool, optional
If True, the approximate cumulant, containing (delta 1-DM)-squared terms, is partitioned,
instead of the true cumulant, if `part_cumulant=True`. Default: True.
mpi_target: int or None, optional
If set to an integer, the result will only be available at the specified MPI rank.
If set to None, an MPI allreduce will be performed and the result will be available
at all MPI ranks. Default: None.

Returns
-------
Expand All @@ -1286,7 +1290,8 @@ def get_dmet_elec_energy(self, part_cumulant=True, approx_cumulant=True):
wx = x.symmetry_factor
e_dmet += wx * x.get_fragment_dmet_energy(part_cumulant=part_cumulant, approx_cumulant=approx_cumulant)
if mpi:
mpi.world.allreduce(e_dmet)
e_dmet = mpi.nreduce(e_dmet, target=mpi_target, logfunc=self.log.timingv)

if part_cumulant:
dm1 = self.make_rdm1_demo(ao_basis=True)
if not approx_cumulant:
Expand Down Expand Up @@ -1750,4 +1755,4 @@ def check_solver(self, solver):
is_eb = "crpa_full" in self.opts.screening
else:
is_eb = False
check_solver_config(is_uhf, is_eb, solver, self.log)
check_solver_config(solver, is_uhf, is_eb, self.log)
Loading
Loading