@@ -16,22 +16,26 @@ 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+ template <Spin Sigma, typename WfnType, typename SpinWfnType >
2629void append_singles_asci_contributions (
27- double coeff, wfn_t < 2 * N> state_full, wfn_t <N> state_same,
30+ double coeff, WfnType state_full, SpinWfnType state_same,
2831 const std::vector<uint32_t >& occ_same,
2932 const std::vector<uint32_t >& vir_same,
3033 const std::vector<uint32_t >& occ_othr, const double * eps_same,
3134 const double * T_pq, const size_t LDT , const double * G_kpq, const size_t LDG ,
3235 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) {
36+ double E0 , const HamiltonianGeneratorBase<double >& ham_gen,
37+ asci_contrib_container<WfnType>& asci_contributions) {
38+ using wfn_traits = wavefunction_traits<WfnType>;
3539 const auto LDG2 = LDG * LDG ;
3640 const auto LDV2 = LDV * LDV ;
3741 for (auto i : occ_same)
@@ -47,8 +51,8 @@ void append_singles_asci_contributions(
4751 if (std::abs (h_el) < h_el_tol) continue ;
4852
4953 // Calculate Excited Determinant
50- auto ex_det = state_full;
51- ex_det. flip (i + NShift). flip (a + NShift );
54+ auto ex_det = wfn_traits:: template single_excitation_no_check<Sigma>(
55+ 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,
71- const std::vector<uint32_t >& ss_occ, const std::vector<uint32_t >& vir,
72- const std::vector<uint32_t >& os_occ, const double * eps_same,
73- 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) {
74+ double coeff, WfnType state_full, SpinWfnType state_same,
75+ SpinWfnType state_other, const std::vector<uint32_t >& ss_occ,
76+ const std::vector<uint32_t >& vir, const std::vector<uint32_t >& os_occ,
77+ const double * eps_same, const double * G, size_t LDG , double h_el_tol,
78+ double root_diag, double E0 ,
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,21 @@ 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 (
118+ SpinWfnType (0 ), i, j, a, b);
119+ const auto ex_det_spin = state_same ^ full_ex_spin;
120+
121+ // Calculate the sign in a canonical way
122+ double sign = doubles_sign (state_same, ex_det_spin, full_ex_spin);
123+
124+ // Calculate full excited determinant
125+ auto ex_det =
126+ wfn_traits::template from_spin<Sigma>(ex_det_spin, state_other);
127+ #endif
105128
106129 // Update sign of matrix element
107130 auto h_el = sign * G_aibj;
@@ -110,25 +133,27 @@ void append_ss_doubles_asci_contributions(
110133 auto h_diag =
111134 ham_gen.fast_diag_ss_double (eps_same[i], eps_same[j], eps_same[a],
112135 eps_same[b], i, j, a, b, root_diag);
113- h_el /= (E0 - h_diag);
136+ // h_el /= (E0 - h_diag);
114137
115138 // Append {det, c*h_el}
116- asci_contributions.push_back ({ex_det, coeff * h_el});
139+ asci_contributions.push_back ({ex_det, coeff * h_el, E0 - h_diag });
117140
118141 } // Restricted BJ loop
119142 } // AI Loop
120143}
121144
122- template <size_t N >
145+ template <typename WfnType, typename SpinWfnType >
123146void 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,
147+ double coeff, WfnType state_full, SpinWfnType state_alpha,
148+ SpinWfnType state_beta, const std::vector<uint32_t >& occ_alpha,
126149 const std::vector<uint32_t >& occ_beta,
127150 const std::vector<uint32_t >& vir_alpha,
128151 const std::vector<uint32_t >& vir_beta, const double * eps_alpha,
129152 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) {
153+ double root_diag, double E0 ,
154+ const HamiltonianGeneratorBase<double >& ham_gen,
155+ asci_contrib_container<WfnType>& asci_contributions) {
156+ using wfn_traits = wavefunction_traits<WfnType>;
132157 const size_t LDV2 = LDV * LDV ;
133158 for (auto i : occ_alpha)
134159 for (auto a : vir_alpha) {
@@ -144,17 +169,22 @@ void append_os_doubles_asci_contributions(
144169
145170 double sign_beta = single_excitation_sign (state_beta, b, j);
146171 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);
172+ // auto ex_det = state_full;
173+ // ex_det.flip(a).flip(i).flip(j + N).flip(b + N);
174+ auto ex_det =
175+ wfn_traits::template single_excitation_no_check<Spin::Alpha>(
176+ state_full, a, i);
177+ ex_det = wfn_traits::template single_excitation_no_check<Spin::Beta>(
178+ ex_det, b, j);
149179 auto h_el = sign * V_aibj;
150180
151181 // Evaluate fast diagonal element
152182 auto h_diag = ham_gen.fast_diag_os_double (eps_alpha[i], eps_beta[j],
153183 eps_alpha[a], eps_beta[b],
154184 i, j, a, b, root_diag);
155- h_el /= (E0 - h_diag);
185+ // h_el /= (E0 - h_diag);
156186
157- asci_contributions.push_back ({ex_det, coeff * h_el});
187+ asci_contributions.push_back ({ex_det, coeff * h_el, E0 - h_diag });
158188 } // BJ loop
159189 } // AI loop
160190}
0 commit comments