Skip to content

Commit 5caae6c

Browse files
committed
feat: introduce CC::hbar()
Need access to hbar expression sometimes. Also makes sense to centralize the hbar construction.
1 parent 55ec5a6 commit 5caae6c

2 files changed

Lines changed: 30 additions & 24 deletions

File tree

SeQuant/domain/mbpt/models/cc.cpp

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,25 @@ bool CC::screen() const { return screen_; }
5555

5656
bool CC::use_topology() const { return use_topology_; }
5757

58-
std::vector<ExprPtr> CC::t(size_t pmax, size_t pmin) {
59-
pmax = (pmax == std::numeric_limits<size_t>::max() ? N : pmax);
58+
ExprPtr CC::hbar(std::optional<size_t> truncation_rank) const {
6059
const bool skip_singles = ansatz_ == Ansatz::oT || ansatz_ == Ansatz::oU;
60+
// if truncation_rank is not provided, use hbar_comm_rank if provided,
61+
// otherwise default to 4 (traditional CC)
62+
const auto def_truncation = hbar_comm_rank_ ? hbar_comm_rank_.value() : 4;
63+
const auto truncation =
64+
truncation_rank ? truncation_rank.value() : def_truncation;
65+
66+
auto hbar =
67+
mbpt::lst(H(), T(N, skip_singles), truncation, {.unitary = unitary()});
68+
return hbar;
69+
}
6170

71+
std::vector<ExprPtr> CC::t(size_t pmax, size_t pmin) {
72+
pmax = (pmax == std::numeric_limits<size_t>::max() ? N : pmax);
6273
SEQUANT_ASSERT(pmax >= pmin && "pmax should be >= pmin");
63-
const auto commutator_rank = hbar_comm_rank_.value_or(4);
6474

6575
// 1. construct hbar(op) in canonical form
66-
auto hbar = mbpt::lst(H(), T(N, skip_singles), commutator_rank,
67-
{.unitary = unitary()});
76+
auto hbar = this->hbar();
6877

6978
// connectivity: empty for unitary ansatz, default otherwise
7079
const auto connectivity = this->unitary()
@@ -113,15 +122,9 @@ std::vector<ExprPtr> CC::t(size_t pmax, size_t pmin) {
113122

114123
std::vector<ExprPtr> CC::λ() {
115124
SEQUANT_ASSERT(!unitary() && "there is no need for CC::λ for unitary ansatz");
116-
const bool skip_singles = ansatz_ == Ansatz::oT;
117-
118-
const auto commutator_rank =
119-
hbar_comm_rank_.value_or(4); // default truncation rank is 4
120125

121126
// construct hbar
122-
SEQUANT_ASSERT(commutator_rank >= 1 &&
123-
"commutator_rank should be at least 1");
124-
auto hbar = mbpt::lst(H(), T(N, skip_singles), commutator_rank - 1);
127+
auto hbar = this->hbar(hbar_comm_rank_.value_or(4) - 1);
125128

126129
auto lhbar = simplify((1 + Λ(N)) * hbar);
127130

@@ -201,8 +204,7 @@ std::vector<ExprPtr> CC::tʼ(size_t rank, size_t order,
201204
3); // notice 3 instead of 4 here, this is because of the commutator with
202205
// T'(1). In case 4 is used, it will generate more terms but they
203206
// will not contribute.
204-
const auto hbar =
205-
mbpt::lst(H(), T(N), hbar_truncate_at, {.unitary = unitary()});
207+
const auto hbar = this->hbar(hbar_truncate_at);
206208

207209
ExprPtr hbar_pert;
208210
if (unitary()) {
@@ -251,8 +253,7 @@ std::vector<ExprPtr> CC::λʼ(size_t rank, size_t order,
251253
"CC::λʼ: only traditional ansatz is supported");
252254

253255
// construct hbar
254-
const auto hbar_truncate_at = hbar_comm_rank_.value_or(4);
255-
const auto hbar = mbpt::lst(H(), T(N), hbar_truncate_at);
256+
const auto hbar = this->hbar();
256257

257258
// construct h1_bar
258259
// truncate h1_bar at rank 2 for one-body perturbation operator and at rank 4
@@ -264,7 +265,7 @@ std::vector<ExprPtr> CC::λʼ(size_t rank, size_t order,
264265

265266
// construct [hbar, T(1)]
266267
const auto hbar_pert =
267-
mbpt::lst(H(), T(N), 3) * Tʼ(N, {.order = order, .nbatch = nbatch});
268+
this->hbar(3) * Tʼ(N, {.order = order, .nbatch = nbatch});
268269

269270
// [Eq. 35, WIREs Comput Mol Sci. 2019; 9:e1406]
270271
const auto expr = simplify((1 + Λ(N)) * (h1_bar + hbar_pert) +
@@ -309,12 +310,9 @@ std::vector<ExprPtr> CC::eom_r(nₚ np, nₕ nh) {
309310
SEQUANT_ASSERT(hbar_comm_rank_ &&
310311
"hbar_comm_rank must be specified for unitary ansatz "
311312
"in CC::eom_r");
312-
const bool skip_singles = ansatz_ == Ansatz::oT || ansatz_ == Ansatz::oU;
313313

314314
// construct hbar
315-
const auto hbar_truncate_at = hbar_comm_rank_.value_or(4);
316-
const auto hbar = mbpt::lst(H(), T(N, skip_singles), hbar_truncate_at,
317-
{.unitary = unitary()});
315+
const auto hbar = this->hbar();
318316

319317
// construct [hbar, R]
320318
ExprPtr hbar_R;
@@ -362,11 +360,9 @@ std::vector<ExprPtr> CC::eom_l(nₚ np, nₕ nh) {
362360
SEQUANT_ASSERT(
363361
get_default_context().spbasis() != SPBasis::Spinfree &&
364362
"spin-free basis does not support non particle-conserving cases");
365-
const bool skip_singles = ansatz_ == Ansatz::oT;
366363

367364
// construct hbar
368-
const auto hbar_truncate_at = hbar_comm_rank_.value_or(4);
369-
const auto hbar = mbpt::lst(H(), T(N, skip_singles), hbar_truncate_at);
365+
const auto hbar = this->hbar();
370366

371367
// L * hbar
372368
const auto L_hbar = L(np, nh) * hbar;

SeQuant/domain/mbpt/models/cc.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,16 @@ class CC {
7070
/// @return whether topological optimization is used in WickTheorem
7171
[[nodiscard]] bool use_topology() const;
7272

73+
/// @brief computes similarity transformed Hamiltonian, \f$ \bar{H} =
74+
/// e^{-\hat{\sigma}} \hat{H} e^{\hat{\sigma}} \f$. The form of \f$ \sigma \f$
75+
/// depends on the Ansatz choice.
76+
/// @param truncation_rank maximum order of nested commutators to include in
77+
/// the expansion; if not specified, will use the value of `hbar_comm_rank`.
78+
/// If that is also not specified, will use 4 as the default value. If
79+
/// provided, will override all defaults.
80+
[[nodiscard]] ExprPtr hbar(
81+
std::optional<size_t> truncation_rank = std::nullopt) const;
82+
7383
/// @brief derives t amplitude equations, \f$ \langle P|\bar{H}|0 \rangle = 0
7484
/// \f$
7585
/// @param pmax highest particle rank of the projector manifold `\f \langle P

0 commit comments

Comments
 (0)