Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
ef5faac
feat: initial implementation of OpRegistry
ajay-mk Dec 14, 2025
fc0fe2c
feat: introduce reserved labels and logic in mbpt namespace
ajay-mk Dec 23, 2025
0a2d2f5
refactor: move `OpClass` to op_registry.hpp
ajay-mk Dec 23, 2025
9841bb7
feat: implement more functionalities in `OpRegistry`
ajay-mk Dec 23, 2025
6b3952f
feat: introduce `mbpt::Context::Options`
ajay-mk Dec 23, 2025
fe9e0c1
feat(mbpt::Context): add support for `OpRegistry`
ajay-mk Dec 23, 2025
747c613
feat: add predefined OpRegistries
ajay-mk Dec 23, 2025
305c133
test: add `OpRegistry` unit tests
ajay-mk Dec 23, 2025
3ca9164
test: add `mbpt::Context` unit tests
ajay-mk Dec 23, 2025
f4d6a75
fix: update `mbpt::Context` initialization syntax in SRSO-PNO test case
ajay-mk Dec 23, 2025
081a556
Merge branch 'refs/heads/ajay/fix/mbpt-detail-ambiguity' into ajay/fe…
ajay-mk Dec 23, 2025
bca3e6b
fix: update `mbpt::Context` initialization in more places
ajay-mk Dec 23, 2025
3ab85e5
refactor: change initialization order in `mbpt::Context::Options`
ajay-mk Dec 24, 2025
8c207d9
feat: improve `mbpt::Context` setters, can use Options directly
ajay-mk Dec 24, 2025
1b2910b
feat: introduce `mbpt::to_op_class`
ajay-mk Dec 24, 2025
6ad45b3
feat: remove `OpType` enum and related objects
ajay-mk Dec 24, 2025
207fc59
feat: VEV methods are `OpType` free
ajay-mk Dec 24, 2025
2e78cde
feat: `CC` class is `OpType` free
ajay-mk Dec 24, 2025
453c883
fix(OpParams): default value of order should be 0
ajay-mk Dec 24, 2025
1b018a9
feat: `OpMaker` class is `OpType` free and supports arbitrary perturb…
ajay-mk Dec 24, 2025
9fa190b
feat(Operator): refactor constructors to use OpParams + Op is aware o…
ajay-mk Dec 24, 2025
a8e1a06
feat(to_latex): update the logic in `mbpt::Operator` overload
ajay-mk Dec 24, 2025
1c038fa
feat: move reserved labels and logic to a new header
ajay-mk Dec 24, 2025
557cb5b
feat: add [[nodiscard]] to `OpRegistry` methods
ajay-mk Dec 24, 2025
80662df
feat: add registry checks to built-in operators
ajay-mk Dec 24, 2025
b368b0d
fix: set spinor RDM label in tensor::ev_impl function
ajay-mk Dec 24, 2025
d96bdd2
test: add mbpt::Context setup in main, and fixup SRSO-PNO
ajay-mk Dec 24, 2025
9fd818d
test: update mbpt::Context related test cases
ajay-mk Dec 24, 2025
22e2075
integration: all CC examples set `mbpt::Context` correctly
ajay-mk Dec 24, 2025
dac60f8
integration: set RDM cumulant label in antisymmetrizer example
ajay-mk Dec 24, 2025
0b24f89
test: doc examples set `mbpt::Context` wherever needed
ajay-mk Dec 24, 2025
4499086
fix(RDM): replace optype2label with dedicated labels for RDMs and cum…
ajay-mk Dec 24, 2025
50279c3
fix(reserved): labels return reference to static storage so that view…
ajay-mk Dec 24, 2025
043ac25
test: update H_pt and T_pt calls to include order parameter
ajay-mk Dec 24, 2025
2641e62
fix: update include guards in `reserved.hpp`
ajay-mk Dec 24, 2025
37ec7a2
fix: consistent include style in docs example
ajay-mk Dec 24, 2025
792059e
fix: update namespacing in rdm.cpp, fixup 44990865
ajay-mk Dec 24, 2025
7c90db3
fix(python): Remove OpType from python interface
ajay-mk Dec 24, 2025
bbc8cda
fix: set MBPT context in eval examples
ajay-mk Dec 24, 2025
b1ef138
Merge remote-tracking branch 'refs/remotes/origin/master' into ajay/f…
ajay-mk Dec 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,9 @@ set(SeQuant_src
SeQuant/domain/mbpt/convention.hpp
SeQuant/domain/mbpt/models/cc.cpp
SeQuant/domain/mbpt/models/cc.hpp
SeQuant/domain/mbpt/reserved.hpp
SeQuant/domain/mbpt/op_registry.hpp
SeQuant/domain/mbpt/op_registry.cpp
SeQuant/domain/mbpt/op.cpp
SeQuant/domain/mbpt/op.hpp
SeQuant/domain/mbpt/op.ipp
Expand Down
95 changes: 93 additions & 2 deletions SeQuant/domain/mbpt/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,52 @@

namespace sequant::mbpt {

Context::Context(CSV csv) noexcept : csv_(csv) {}
/// forward declaration of OpClass
enum class OpClass;

Context::Context(Options options)
: csv_(options.csv),
op_registry_(options.op_registry_ptr
? std::move(options.op_registry_ptr)
: (options.op_registry
? std::make_shared<OpRegistry>(
std::move(options.op_registry.value()))
: nullptr)) {}

Context Context::clone() const {
Context ctx(*this);
ctx.op_registry_ = std::make_shared<OpRegistry>(op_registry_->clone());
return ctx;
}

CSV Context::csv() const { return csv_; }

std::shared_ptr<const OpRegistry> Context::op_registry() const {
return op_registry_;
}

std::shared_ptr<OpRegistry> Context::mutable_op_registry() {
return op_registry_;
}

Context& Context::set(const OpRegistry& op_registry) {
op_registry_ = std::make_shared<OpRegistry>(op_registry);
return *this;
}

Context& Context::set(std::shared_ptr<OpRegistry> op_registry) {
op_registry_ = std::move(op_registry);
return *this;
}

Context& Context::set(CSV csv) {
csv_ = csv;
return *this;
}

bool operator==(Context const& left, Context const& right) {
return left.csv() == right.csv();
return left.csv() == right.csv() &&
*(left.op_registry()) == *(right.op_registry());
}

bool operator!=(Context const& left, Context const& right) {
Expand All @@ -20,6 +62,10 @@ void set_default_mbpt_context(const Context& ctx) {
sequant::detail::set_implicit_context(ctx);
}

void set_default_mbpt_context(const Context::Options& options) {
return set_default_mbpt_context(Context(options));
}

void reset_default_mbpt_context() {
sequant::detail::reset_implicit_context<Context>();
}
Expand All @@ -29,4 +75,49 @@ set_scoped_default_mbpt_context(const Context& f) {
return sequant::detail::set_scoped_implicit_context(f);
}

[[nodiscard]] sequant::detail::ImplicitContextResetter<Context>
set_scoped_default_mbpt_context(const Context::Options& f) {
return sequant::detail::set_scoped_implicit_context(Context(f));
}

std::shared_ptr<OpRegistry> make_minimal_registry() {
auto registry = std::make_shared<OpRegistry>();

registry
->add(L"h", OpClass::gen) /// 1-body Hamiltonian
.add(L"g", OpClass::gen) /// 2-body Coulomb
.add(L"f", OpClass::gen) /// Fock operator
.add(L"θ", OpClass::gen) /// general fock space operator
.add(L"t", OpClass::ex) /// cluster operator
.add(L"λ", OpClass::deex) /// deexcitation cluster operator
.add(L"R", OpClass::ex) /// right-hand eigenstate
.add(L"L", OpClass::deex); /// left-hand eigenstate

return registry;
}

std::shared_ptr<OpRegistry> make_legacy_registry() {
auto registry = std::make_shared<OpRegistry>();

registry->add(L"h", OpClass::gen)
.add(L"f", OpClass::gen)
/// closed Fock operator (i.e. Fock operator due to fully-occupied
/// orbitals)
.add(L"f̃", OpClass::gen)
.add(L"g", OpClass::gen)
.add(L"θ", OpClass::gen)
.add(L"t", OpClass::ex)
.add(L"λ", OpClass::deex)
.add(L"R", OpClass::ex)
.add(L"L", OpClass::deex)
/// R12
.add(L"F", OpClass::gen)
.add(L"GR", OpClass::gen)
.add(L"C", OpClass::gen)
/// RDM and RDM Cumulant
.add(L"γ", OpClass::gen)
.add(L"κ", OpClass::gen);

return registry;
}
} // namespace sequant::mbpt
84 changes: 81 additions & 3 deletions SeQuant/domain/mbpt/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <SeQuant/domain/mbpt/fwd.hpp>

#include <SeQuant/core/utility/context.hpp>
#include <SeQuant/domain/mbpt/op_registry.hpp>

namespace sequant::mbpt {

Expand All @@ -20,13 +21,61 @@ class Context {
constexpr static auto csv = CSV::No;
};

/// @brief Construct a Formalism object
explicit Context(CSV csv_formalism = Defaults::csv) noexcept;
struct Options {
/// whether to use cluster-specific virtuals
CSV csv = Defaults::csv;
/// shared pointer to operator registry
std::shared_ptr<OpRegistry> op_registry_ptr = nullptr;
/// optional operator registry, use if no shared pointer is provided
std::optional<OpRegistry> op_registry = std::nullopt;
};

/// @brief makes default options for mbpt::Context
static Options make_default_options() { return Options{}; }

/// @brief Construct a Context object, uses default options if none are given
Context(Options options = make_default_options());

/// @brief destructor
~Context() = default;

/// @brief move constructor
Context(Context&&) = default;

/// @brief copy constructor
Context(Context const& other) = default;

/// @brief copy assignment
Context& operator=(Context const& other) = default;

/// @brief clones this object and its OpRegistry
Context clone() const;

/// @return the value of CSV in this context
CSV csv() const;

CSV csv() const { return csv_; }
/// @return a constant pointer to the OpRegistry for this context
/// @warning can be null when user did not provide one to Context (i.e., it
/// was default constructed)
std::shared_ptr<const OpRegistry> op_registry() const;

/// @return a pointer to the OpRegistry for this context
/// @warning can be null when user did not provide one to Context (i.e., it
/// was default constructed)
std::shared_ptr<OpRegistry> mutable_op_registry();

/// @brief sets the OpRegistry for this context
Context& set(const OpRegistry& op_registry);

/// @brief sets the OpRegistry for this context
Context& set(std::shared_ptr<OpRegistry> op_registry);

/// @brief sets whether to use cluster-specific virtuals
Context& set(CSV csv);

private:
CSV csv_ = Defaults::csv;
std::shared_ptr<OpRegistry> op_registry_;
};

bool operator==(Context const& left, Context const& right);
Expand All @@ -37,10 +86,39 @@ const Context& get_default_mbpt_context();

void set_default_mbpt_context(const Context& ctx);

void set_default_mbpt_context(const Context::Options& options);

void reset_default_mbpt_context();

[[nodiscard]] sequant::detail::ImplicitContextResetter<Context>
set_scoped_default_mbpt_context(const Context& ctx);

[[nodiscard]] sequant::detail::ImplicitContextResetter<Context>
set_scoped_default_mbpt_context(const Context::Options& options);

/// predefined operator registries

/// @brief makes a minimal operator registry with only essential operators for
/// MBPT
std::shared_ptr<OpRegistry> make_minimal_registry();

/// @brief make a legacy operator registry with SeQuant's old predefined
/// operators set
std::shared_ptr<OpRegistry> make_legacy_registry();

/// @brief converts an operator label to its OpClass using the default MBPT
/// context
/// @param op the operator label
/// @return the OpClass of the operator
inline OpClass to_op_class(const std::wstring& op) {
// check reserved labels first
if (ranges::contains(reserved::labels(), op)) {
return OpClass::gen; // all reserved labels are gen
} else {
return get_default_mbpt_context().op_registry()->to_class(op);
}
}

} // namespace sequant::mbpt

#endif // SEQUANT_DOMAIN_MBPT_CONTEXT_HPP
64 changes: 30 additions & 34 deletions SeQuant/domain/mbpt/models/cc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,12 @@ std::vector<ExprPtr> CC::λ(size_t commutator_rank) {
auto lhbar = simplify((One + Λ(N)) * hbar);

const auto op_connect = concat(default_op_connections(),
OpConnections<OpType>{{OpType::h, OpType::A},
{OpType::f, OpType::A},
{OpType::g, OpType::A},
{OpType::h, OpType::S},
{OpType::f, OpType::S},
{OpType::g, OpType::S}});
OpConnections<std::wstring>{{L"h", L"A"},
{L"f", L"A"},
{L"g", L"A"},
{L"h", L"S"},
{L"f", L"S"},
{L"g", L"S"}});

// 2. project onto each manifold, screen, lower to tensor form and wick it
std::vector<ExprPtr> result(N + 1);
Expand Down Expand Up @@ -168,10 +168,8 @@ std::vector<ExprPtr> CC::t_pt(size_t rank, size_t order,
// connect h1 with t
const auto op_connect =
concat(default_op_connections(),
OpConnections<OpType>{{OpType::h, OpType::t_1},
{OpType::f, OpType::t_1},
{OpType::g, OpType::t_1},
{OpType::h_1, OpType::t}});
OpConnections<std::wstring>{
{L"h", L"t¹"}, {L"f", L"t¹"}, {L"g", L"t¹"}, {L"h¹", L"t"}});

std::vector<ExprPtr> result(N + 1);
for (auto p = N; p >= 1; --p) {
Expand Down Expand Up @@ -218,20 +216,19 @@ std::vector<ExprPtr> CC::λ_pt(size_t rank, size_t order,
// projectors with {h,f,g}
// h1 with t
// h1 with projectors
const auto op_connect =
concat(default_op_connections(),
OpConnections<OpType>{{OpType::h, OpType::t_1},
{OpType::f, OpType::t_1},
{OpType::g, OpType::t_1},
{OpType::h_1, OpType::t},
{OpType::h, OpType::A},
{OpType::f, OpType::A},
{OpType::g, OpType::A},
{OpType::h, OpType::S},
{OpType::f, OpType::S},
{OpType::g, OpType::S},
{OpType::h_1, OpType::A},
{OpType::h_1, OpType::S}});
const auto op_connect = concat(default_op_connections(),
OpConnections<std::wstring>{{L"h", L"t¹"},
{L"f", L"t¹"},
{L"g", L"t¹"},
{L"h¹", L"t"},
{L"h", L"A"},
{L"f", L"A"},
{L"g", L"A"},
{L"h", L"S"},
{L"f", L"S"},
{L"g", L"S"},
{L"h¹", L"A"},
{L"h¹", L"S"}});

std::vector<ExprPtr> result(N + 1);
for (auto p = N; p >= 1; --p) {
Expand Down Expand Up @@ -262,10 +259,9 @@ std::vector<ExprPtr> CC::eom_r(nₚ np, nₕ nh) {

// connectivity:
// default connections + connect R with {h,f,g}
const auto op_connect = concat(default_op_connections(),
OpConnections<OpType>{{OpType::h, OpType::R},
{OpType::f, OpType::R},
{OpType::g, OpType::R}});
const auto op_connect = concat(
default_op_connections(),
OpConnections<std::wstring>{{L"h", L"R"}, {L"f", L"R"}, {L"g", L"R"}});

// initialize result vector
std::vector<ExprPtr> result;
Expand Down Expand Up @@ -305,12 +301,12 @@ std::vector<ExprPtr> CC::eom_l(nₚ np, nₕ nh) {
// connectivity:
// default connections + connect H with projectors
const auto op_connect = concat(default_op_connections(),
OpConnections<OpType>{{OpType::h, OpType::A},
{OpType::f, OpType::A},
{OpType::g, OpType::A},
{OpType::h, OpType::S},
{OpType::f, OpType::S},
{OpType::g, OpType::S}});
OpConnections<std::wstring>{{L"h", L"A"},
{L"f", L"A"},
{L"g", L"A"},
{L"h", L"S"},
{L"f", L"S"},
{L"g", L"S"}});

// initialize result vector
std::vector<ExprPtr> result;
Expand Down
2 changes: 1 addition & 1 deletion SeQuant/domain/mbpt/models/cc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class CC {
/// @param[in] op_connect list of pairs of operators to be connected. Default
/// is given by `mbpt::default_op_connections()`.
auto ref_av(const ExprPtr& expr,
const OpConnections<mbpt::OpType>& op_connect =
const OpConnections<std::wstring>& op_connect =
default_op_connections()) const {
return op::ref_av(expr, op_connect, this->use_topology(), this->screen());
}
Expand Down
Loading