Skip to content

Commit e8782cc

Browse files
Merge 0b82008 into c103c74
2 parents c103c74 + 0b82008 commit e8782cc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1523
-921
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#pragma once
2+
3+
#include <macis/wfn/raw_bitset.hpp>
4+
namespace macis {
5+
6+
template <typename WfnTraits>
7+
class alpha_constraint {
8+
9+
public:
10+
using wfn_traits = WfnTraits;
11+
using wfn_type = typename WfnTraits::wfn_type;
12+
using spin_wfn_type = spin_wfn_t<wfn_type>;
13+
using spin_wfn_traits = wavefunction_traits<spin_wfn_type>;
14+
using constraint_type = spin_wfn_type;
15+
16+
private:
17+
constraint_type C_;
18+
constraint_type B_;
19+
uint32_t C_min_;
20+
uint32_t count_;
21+
22+
public:
23+
24+
alpha_constraint(constraint_type C, constraint_type B, uint32_t C_min) :
25+
C_(C), B_(B), C_min_(C_min), count_(spin_wfn_traits::count(C)) {}
26+
27+
alpha_constraint(const alpha_constraint&) = default;
28+
alpha_constraint& operator=(const alpha_constraint&) = default;
29+
30+
alpha_constraint(alpha_constraint&& other) noexcept = default;
31+
alpha_constraint& operator=(alpha_constraint&&) noexcept = default;
32+
33+
34+
inline auto C() const { return C_; }
35+
inline auto B() const { return B_; }
36+
inline auto C_min() const { return C_min_; }
37+
inline auto count() const { return count_; }
38+
39+
40+
inline spin_wfn_type c_mask_union(spin_wfn_type state) const {
41+
return state & C_;
42+
}
43+
inline spin_wfn_type b_mask_union(spin_wfn_type state) const {
44+
return state & B_;
45+
}
46+
47+
inline spin_wfn_type symmetric_difference(spin_wfn_type state) const {
48+
return state ^ C_;
49+
}
50+
inline spin_wfn_type symmetric_difference(wfn_type state) const {
51+
return symmetric_difference(wfn_traits::alpha_string(state));
52+
}
53+
54+
template <typename WfnType>
55+
inline auto overlap(WfnType state) const {
56+
return spin_wfn_traits::count(c_mask_union(state));
57+
}
58+
59+
template <typename WfnType>
60+
inline bool satisfies_constraint(WfnType state) const {
61+
return overlap(state) == count_ and
62+
spin_wfn_traits::count(symmetric_difference(state) >> C_min_) == 0;
63+
}
64+
65+
66+
67+
};
68+
69+
70+
}

include/macis/asci/determinant_contributions.hpp

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,27 @@ namespace macis {
1616
template <typename WfnT>
1717
struct 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

2225
template <typename WfnT>
2326
using 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>
2630
void 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>
6973
void 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>
123144
void 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

Comments
 (0)