@@ -16,22 +16,27 @@ namespace macis {
1616template <typename WfnT>
1717struct asci_contrib {
1818 WfnT state;
19- double rv;
19+ double c_times_matel;
20+ double h_diag;
21+
22+ auto rv () const { return c_times_matel / h_diag; }
2023};
2124
2225template <typename WfnT>
2326using asci_contrib_container = std::vector<asci_contrib<WfnT>>;
2427
25- template <size_t N, size_t NShift>
28+
29+ template <Spin Sigma, typename WfnType, typename SpinWfnType>
2630void append_singles_asci_contributions (
27- double coeff, wfn_t < 2 * N> state_full, wfn_t <N> state_same,
31+ double coeff, WfnType state_full, SpinWfnType state_same,
2832 const std::vector<uint32_t >& occ_same,
2933 const std::vector<uint32_t >& vir_same,
3034 const std::vector<uint32_t >& occ_othr, const double * eps_same,
3135 const double * T_pq, const size_t LDT, const double * G_kpq, const size_t LDG,
3236 const double * V_kpq, const size_t LDV, double h_el_tol, double root_diag,
33- double E0 , HamiltonianGenerator<2 * N>& ham_gen,
34- asci_contrib_container<wfn_t <2 * N>>& asci_contributions) {
37+ double E0 , const HamiltonianGeneratorBase<double >& ham_gen,
38+ asci_contrib_container<WfnType>& asci_contributions) {
39+ using wfn_traits = wavefunction_traits<WfnType>;
3540 const auto LDG2 = LDG * LDG;
3641 const auto LDV2 = LDV * LDV;
3742 for (auto i : occ_same)
@@ -47,8 +52,7 @@ void append_singles_asci_contributions(
4752 if (std::abs (h_el) < h_el_tol) continue ;
4853
4954 // Calculate Excited Determinant
50- auto ex_det = state_full;
51- ex_det.flip (i + NShift).flip (a + NShift);
55+ auto ex_det = wfn_traits::template single_excitation_no_check<Sigma>(state_full, i, a);
5256
5357 // Calculate Excitation Sign in a Canonical Way
5458 auto sign = single_excitation_sign (state_same, a, i);
@@ -57,22 +61,25 @@ void append_singles_asci_contributions(
5761 // Calculate fast diagonal matrix element
5862 auto h_diag =
5963 ham_gen.fast_diag_single (eps_same[i], eps_same[a], i, a, root_diag);
60- h_el /= (E0 - h_diag);
64+ // h_el /= (E0 - h_diag);
6165
6266 // Append to return values
63- asci_contributions.push_back ({ex_det, coeff * h_el});
67+ asci_contributions.push_back ({ex_det, coeff * h_el, E0 - h_diag });
6468
6569 } // Loop over single extitations
6670}
6771
68- template <size_t N, size_t NShift >
72+ template <Spin Sigma, typename WfnType, typename SpinWfnType >
6973void append_ss_doubles_asci_contributions (
70- double coeff, wfn_t <2 * N> state_full, wfn_t <N> state_spin,
74+ double coeff, WfnType state_full, SpinWfnType state_same,
75+ SpinWfnType state_other,
7176 const std::vector<uint32_t >& ss_occ, const std::vector<uint32_t >& vir,
7277 const std::vector<uint32_t >& os_occ, const double * eps_same,
7378 const double * G, size_t LDG, double h_el_tol, double root_diag, double E0 ,
74- HamiltonianGenerator<2 * N>& ham_gen,
75- asci_contrib_container<wfn_t <2 * N>>& asci_contributions) {
79+ const HamiltonianGeneratorBase<double >& ham_gen,
80+ asci_contrib_container<WfnType>& asci_contributions) {
81+ using wfn_traits = wavefunction_traits<WfnType>;
82+ using spin_wfn_traits = wavefunction_traits<SpinWfnType>;
7683 const size_t nocc = ss_occ.size ();
7784 const size_t nvir = vir.size ();
7885
@@ -92,6 +99,7 @@ void append_ss_doubles_asci_contributions(
9299
93100 if (std::abs (G_aibj) < h_el_tol) continue ;
94101
102+ #if 0
95103 // Calculate excited determinant string (spin)
96104 const auto full_ex_spin = wfn_t<N>(0).flip(i).flip(j).flip(a).flip(b);
97105 auto ex_det_spin = state_spin ^ full_ex_spin;
@@ -102,6 +110,19 @@ void append_ss_doubles_asci_contributions(
102110 // Calculate full excited determinant
103111 const auto full_ex = expand_bitset<2 * N>(full_ex_spin) << NShift;
104112 auto ex_det = state_full ^ full_ex;
113+ #else
114+ // TODO: Can this be made faster since the orbital indices are known
115+ // in advance?
116+ // Compute excited determinant (spin)
117+ const auto full_ex_spin = spin_wfn_traits::double_excitation_no_check (SpinWfnType (0 ), i,j,a,b);
118+ const auto ex_det_spin = state_same ^ full_ex_spin;
119+
120+ // Calculate the sign in a canonical way
121+ double sign = doubles_sign (state_same, ex_det_spin, full_ex_spin);
122+
123+ // Calculate full excited determinant
124+ auto ex_det = wfn_traits::template from_spin<Sigma>(ex_det_spin, state_other);
125+ #endif
105126
106127 // Update sign of matrix element
107128 auto h_el = sign * G_aibj;
@@ -110,25 +131,26 @@ void append_ss_doubles_asci_contributions(
110131 auto h_diag =
111132 ham_gen.fast_diag_ss_double (eps_same[i], eps_same[j], eps_same[a],
112133 eps_same[b], i, j, a, b, root_diag);
113- h_el /= (E0 - h_diag);
134+ // h_el /= (E0 - h_diag);
114135
115136 // Append {det, c*h_el}
116- asci_contributions.push_back ({ex_det, coeff * h_el});
137+ asci_contributions.push_back ({ex_det, coeff * h_el, E0 - h_diag });
117138
118139 } // Restricted BJ loop
119140 } // AI Loop
120141}
121142
122- template <size_t N >
143+ template <typename WfnType, typename SpinWfnType >
123144void append_os_doubles_asci_contributions (
124- double coeff, wfn_t < 2 * N> state_full, wfn_t <N> state_alpha,
125- wfn_t <N> state_beta, const std::vector<uint32_t >& occ_alpha,
145+ double coeff, WfnType state_full, SpinWfnType state_alpha,
146+ SpinWfnType state_beta, const std::vector<uint32_t >& occ_alpha,
126147 const std::vector<uint32_t >& occ_beta,
127148 const std::vector<uint32_t >& vir_alpha,
128149 const std::vector<uint32_t >& vir_beta, const double * eps_alpha,
129150 const double * eps_beta, const double * V, size_t LDV, double h_el_tol,
130- double root_diag, double E0 , HamiltonianGenerator<2 * N>& ham_gen,
131- asci_contrib_container<wfn_t <2 * N>>& asci_contributions) {
151+ double root_diag, double E0 , const HamiltonianGeneratorBase<double >& ham_gen,
152+ asci_contrib_container<WfnType>& asci_contributions) {
153+ using wfn_traits = wavefunction_traits<WfnType>;
132154 const size_t LDV2 = LDV * LDV;
133155 for (auto i : occ_alpha)
134156 for (auto a : vir_alpha) {
@@ -144,17 +166,19 @@ void append_os_doubles_asci_contributions(
144166
145167 double sign_beta = single_excitation_sign (state_beta, b, j);
146168 double sign = sign_alpha * sign_beta;
147- auto ex_det = state_full;
148- ex_det.flip (a).flip (i).flip (j + N).flip (b + N);
169+ // auto ex_det = state_full;
170+ // ex_det.flip(a).flip(i).flip(j + N).flip(b + N);
171+ auto ex_det = wfn_traits::template single_excitation_no_check<Spin::Alpha>(state_full, a, i);
172+ ex_det = wfn_traits::template single_excitation_no_check<Spin::Beta>(ex_det, b, j);
149173 auto h_el = sign * V_aibj;
150174
151175 // Evaluate fast diagonal element
152176 auto h_diag = ham_gen.fast_diag_os_double (eps_alpha[i], eps_beta[j],
153177 eps_alpha[a], eps_beta[b],
154178 i, j, a, b, root_diag);
155- h_el /= (E0 - h_diag);
179+ // h_el /= (E0 - h_diag);
156180
157- asci_contributions.push_back ({ex_det, coeff * h_el});
181+ asci_contributions.push_back ({ex_det, coeff * h_el, E0 - h_diag });
158182 } // BJ loop
159183 } // AI loop
160184}
0 commit comments