diff --git a/examples/ewf/molecules/20-dump-clusters.py b/examples/ewf/molecules/20-dump-clusters.py index 8e6de86f5..b8ccc95b2 100644 --- a/examples/ewf/molecules/20-dump-clusters.py +++ b/examples/ewf/molecules/20-dump-clusters.py @@ -23,7 +23,7 @@ # Embedding class to form fragment, bath, and cluster spaces emb = vayesta.ewf.EWF( - mf, solver="Dump", bath_options=dict(threshold=1e-6), solver_options=dict(dumpfile="clusters-rhf.h5") + mf, solver="DUMP", bath_options=dict(threshold=1e-6), solver_options=dict(dumpfile="clusters-rhf.h5") ) emb.kernel() @@ -46,7 +46,7 @@ # Embedding class to form fragment, bath, and cluster spaces emb = vayesta.ewf.EWF( - mf, solver="Dump", bath_options=dict(threshold=1e-6), solver_options=dict(dumpfile="clusters-uhf.h5") + mf, solver="DUMP", bath_options=dict(threshold=1e-6), solver_options=dict(dumpfile="clusters-uhf.h5") ) emb.kernel() diff --git a/vayesta/core/fragmentation/cas.py b/vayesta/core/fragmentation/cas.py index 2f32547e8..adec11d48 100644 --- a/vayesta/core/fragmentation/cas.py +++ b/vayesta/core/fragmentation/cas.py @@ -88,7 +88,7 @@ def check_for_degen(energies, po, pv, name=""): # Shouldn't reach this as would require CAS to have more electrons than the full system. raise ValueError("CAS would contain more electrons than full system.") - if ogap < degen_tol: + if abs(ogap) < degen_tol: raise ValueError("Requested %sCAS splits degenerate occupied orbitals." % name) try: @@ -99,7 +99,7 @@ def check_for_degen(energies, po, pv, name=""): vgap = np.inf else: self.log.info("%sCAS virtual energy gap: %s", name, energy_string(vgap)) - if vgap < degen_tol: + if abs(vgap) < degen_tol: raise ValueError("Requested CAS splits degenerate virtual orbitals.") if self.emb.is_rhf: diff --git a/vayesta/core/screening/screening_crpa.py b/vayesta/core/screening/screening_crpa.py index 71490e5eb..f8fa88d03 100644 --- a/vayesta/core/screening/screening_crpa.py +++ b/vayesta/core/screening/screening_crpa.py @@ -181,14 +181,29 @@ def construct_loc_rot(f): rv = (rv, rv) rot_ova = einsum("Ij,Ab->IAjb", ro[0], rv[0]) - rot_ova = rot_ova.reshape((rot_ova.shape[0] * rot_ova.shape[1], -1)) + if rot_ova.size == 0: + rot_ova = np.empty((0, ro[0].shape[1]*rv[0].shape[1])) + else: + rot_ova = rot_ova.reshape((rot_ova.shape[0] * rot_ova.shape[1], -1)) rot_ovb = einsum("Ij,Ab->IAjb", ro[1], rv[1]) - rot_ovb = rot_ovb.reshape((rot_ovb.shape[0] * rot_ovb.shape[1], -1)) + if rot_ovb.size == 0: + rot_ovb = np.empty((0, ro[1].shape[1]*rv[1].shape[1])) + else: + rot_ovb = rot_ovb.reshape((rot_ovb.shape[0] * rot_ovb.shape[1], -1)) + return rot_ova, rot_ovb rot_loc = construct_loc_rot(f) - rot_ov = scipy.linalg.null_space(rot_loc[0]).T, scipy.linalg.null_space(rot_loc[1]).T + if rot_loc[0].size > 0: + rot_ov_a = scipy.linalg.null_space(rot_loc[0]).T + else: + rot_ov_a = np.eye(rot_loc[0].shape[1]) + if rot_loc[1].size > 0: + rot_ov_b = scipy.linalg.null_space(rot_loc[1]).T + else: + rot_ov_b = np.eye(rot_loc[1].shape[1]) + rot_ov = (rot_ov_a, rot_ov_b) if rot_ov[0].shape[0] == 0 and rot_ov[1].shape[0] == 0: log.warning("cRPA space contains no excitations! Interactions will be unscreened.") raise cRPAError("cRPA space contains no excitations!") diff --git a/vayesta/core/screening/screening_moment.py b/vayesta/core/screening/screening_moment.py index de1944a2e..be6447a3e 100644 --- a/vayesta/core/screening/screening_moment.py +++ b/vayesta/core/screening/screening_moment.py @@ -51,9 +51,10 @@ def build_screened_eris(emb, fragments=None, cderi_ov=None, store_m0=True, npoin r_virs = [f.get_overlap("mo[vir]|cluster[vir]") for f in fragments] target_rots, ovs_active = _get_target_rot(r_occs, r_virs) + # target_rots is a list of transformations to the local ph space, with alpha and beta blocked in the same matrix local_moments = calc_moms_RIRPA(emb.mf, target_rots, ovs_active, log, cderi_ov, npoints) # Could generate moments using N^6 moments instead, but just for debugging. - # local_moments, erpa = calc_moms_RPA(emb.mf, target_rots, ovs_active, log, cderi_ov, calc_e, npoints) + # local_moments, erpa = calc_moms_RPA(emb.mf, target_rots, ovs_active, log, cderi_ov, npoints) # Then construct the RPA coupling matrix A-B, given by the diagonal matrix of energy differences. no = np.array(sum(emb.mf.mo_occ.T > 0)) @@ -135,7 +136,7 @@ def calc_moms_RIRPA(mf, target_rots, ovs_active, log, cderi_ov, npoints): return local_moments -def calc_moms_RPA(mf, target_rots, ovs_active, log, cderi_ov, calc_e, npoints): +def calc_moms_RPA(mf, target_rots, ovs_active, log, cderi_ov, npoints): rpa = ssRPA(mf, log=log) erpa = rpa.kernel() mom0 = rpa.gen_moms(0)[0] @@ -244,7 +245,10 @@ def get_target_rot_spat(ro, rv): no = ro.shape[1] nv = rv.shape[1] ov_active = no * nv - rot = einsum("iJ,aB->JBia", ro, rv).reshape((ov_active, -1)) + if ov_active == 0: + rot = np.empty((0,ro.shape[0]*rv.shape[0])) + else: + rot = einsum("iJ,aB->JBia", ro, rv).reshape((ov_active, -1)) return rot, ov_active nfrag = len(r_active_occs) diff --git a/vayesta/rpa/ssrpa.py b/vayesta/rpa/ssrpa.py index 8494f3054..ba6af2792 100644 --- a/vayesta/rpa/ssrpa.py +++ b/vayesta/rpa/ssrpa.py @@ -95,18 +95,18 @@ def kernel(self, xc_kernel=None, alpha=1.0): XpY = np.einsum("n,pq,qn->pn", self.freqs_ss ** (-0.5), AmBrt, c) XmY = np.einsum("n,pq,qn->pn", self.freqs_ss ** (0.5), AmBrtinv, c) - nov = self.ova + nova = self.ova if self.ov_rot is not None: - nov = self.ov_rot[0].shape[0] + nova = self.ov_rot[0].shape[0] - self.XpY_ss = (XpY[:nov], XpY[nov:]) - self.XmY_ss = (XmY[:nov], XmY[nov:]) + self.XpY_ss = (XpY[:nova], XpY[nova:]) + self.XmY_ss = (XmY[:nova], XmY[nova:]) self.freqs_sf = None self.log.timing("Time to solve RPA problem: %s", time_string(timer() - t0)) if xc_kernel is None: - self.e_corr_ss = (sum(self.freqs_ss) - sum(eps[0] + eps[1]) - v.trace()) / 2 + self.e_corr_ss = (sum(self.freqs_ss) - sum(eps[0]) - sum(eps[1]) - v.trace()) / 2 else: self.e_corr_ss = self.calc_energy_correction(xc_kernel=xc_kernel, version=3) diff --git a/vayesta/rpa/ssurpa.py b/vayesta/rpa/ssurpa.py index 9d5823b34..3dd10c8e1 100644 --- a/vayesta/rpa/ssurpa.py +++ b/vayesta/rpa/ssurpa.py @@ -52,7 +52,7 @@ def _gen_eps(self): epsa = (epsa.T - self.mf.mo_energy[0][:nocc_a]).T epsa = epsa.reshape((self.ova,)) - epsb = np.zeros((nocc_a, nvir_a)) + epsb = np.zeros((nocc_b, nvir_b)) epsb = epsb + self.mf.mo_energy[1][nocc_b:] epsb = (epsb.T - self.mf.mo_energy[1][:nocc_b]).T epsb = epsb.reshape((self.ovb,)) @@ -63,18 +63,26 @@ def _gen_arrays(self, xc_kernel=None, alpha=1.0): epsa, epsb = self._gen_eps() if self.ov_rot is not None: - epsa = einsum("pn,n,qn->pq", self.ov_rot[0], epsa, self.ov_rot[0]) - try: - epsa, ca = scipy.linalg.eigh(epsa) - except Exception as e: - print(epsa) - raise e - epsb = einsum("pn,n,qn->pq", self.ov_rot[1], epsb, self.ov_rot[1]) - try: - epsb, cb = scipy.linalg.eigh(epsb) - except Exception as e: - print(epsb) - raise e + if self.ov_rot[0].size > 0: + epsa = einsum("pn,n,qn->pq", self.ov_rot[0], epsa, self.ov_rot[0]) + try: + epsa, ca = scipy.linalg.eigh(epsa) + except Exception as e: + print(epsa) + raise e + else: + epsa = np.empty((0)) + ca = np.empty((0,0)) + if self.ov_rot[1].size > 0: + epsb = einsum("pn,n,qn->pq", self.ov_rot[1], epsb, self.ov_rot[1]) + try: + epsb, cb = scipy.linalg.eigh(epsb) + except Exception as e: + print(epsb) + raise e + else: + epsb = np.empty((0)) + cb = np.empty((0,0)) self.ov_rot = (dot(ca.T, self.ov_rot[0]), dot(cb.T, self.ov_rot[1])) AmB = np.concatenate([epsa, epsb]) @@ -82,6 +90,9 @@ def _gen_arrays(self, xc_kernel=None, alpha=1.0): ApB = 2 * fullv * alpha if self.ov_rot is not None: fullrot = scipy.linalg.block_diag(self.ov_rot[0], self.ov_rot[1]) + #print("Alpha rot: ", self.ov_rot[0].shape) + #print("Beta rot: ", self.ov_rot[1].shape) + #print("Size of full rot: ",fullrot.shape) ApB = dot(fullrot, ApB, fullrot.T) # At this point AmB is just epsilon so add in.