Program Listing for File convention.cpp¶
↰ Return to documentation for file (SeQuant/domain/mbpt/convention.cpp
)
//
// Created by Eduard Valeyev on 2019-04-01.
//
#include <SeQuant/domain/mbpt/convention.hpp>
#include <SeQuant/domain/mbpt/op.hpp>
#include <SeQuant/domain/mbpt/spin.hpp>
#include <SeQuant/core/context.hpp>
#include <SeQuant/core/index.hpp>
#include <SeQuant/core/tensor.hpp>
namespace sequant {
namespace mbpt {
void load(Convention conv) {
std::shared_ptr<IndexSpaceRegistry> isr;
switch (conv) {
case Convention::Minimal:
isr = make_min_sr_spaces();
break;
case Convention::SR:
isr = make_sr_spaces();
break;
case Convention::MR:
isr = make_mr_spaces();
break;
case Convention::F12:
isr = make_F12_sr_spaces();
break;
case Convention::QCiFS:
isr = make_legacy_spaces();
break;
}
set_default_context(sequant::Context(isr, Vacuum::SingleProduct));
}
void add_fermi_spin(std::shared_ptr<IndexSpaceRegistry>& isr) {
auto result = std::make_shared<IndexSpaceRegistry>();
for (auto&& space : *isr) {
if (space.base_key() != L"") {
IndexSpace spin_any(space.base_key(), space.type(), Spin::any,
space.approximate_size());
IndexSpace spin_up(spinannotation_add(space.base_key(), Spin::alpha),
space.type(), Spin::alpha, space.approximate_size());
IndexSpace spin_down(spinannotation_add(space.base_key(), Spin::beta),
space.type(), Spin::beta, space.approximate_size());
result->add(spin_any);
result->add(spin_up);
result->add(spin_down);
}
}
const bool nulltype_ok = true;
result->reference_occupied_space(isr->reference_occupied_space(nulltype_ok));
result->vacuum_occupied_space(isr->vacuum_occupied_space(nulltype_ok));
result->particle_space(isr->particle_space(nulltype_ok));
result->hole_space(isr->hole_space(nulltype_ok));
result->complete_space(isr->complete_space(nulltype_ok));
isr = std::move(result);
}
std::shared_ptr<IndexSpaceRegistry> make_min_sr_spaces() {
auto isr = std::make_shared<IndexSpaceRegistry>();
isr->add(L"i", 0b01, is_vacuum_occupied, is_reference_occupied, is_hole)
.add(L"a", 0b10, is_particle)
.add_union(L"p", {L"i", L"a"}, is_complete);
add_fermi_spin(isr);
return isr;
}
// Multireference supspace uses a subset of its occupied orbitals to define a
// vacuum occupied subspace.
// this leaves an active space which is partially occupied/unoccupied. This
// definition is convenient when coupled with SR vacuum.
std::shared_ptr<IndexSpaceRegistry> make_mr_spaces() {
auto isr = std::make_shared<IndexSpaceRegistry>();
isr->add(L"o", 0b00001)
.add(L"i", 0b00010)
.add(L"u", 0b00100)
.add(L"a", 0b01000)
.add(L"g", 0b10000)
.add_union(L"O", {L"o", L"i"}, is_vacuum_occupied)
.add_union(L"M", {L"o", L"i", L"u"}, is_reference_occupied)
.add_union(L"I", {L"i", L"u"}, is_hole)
.add_union(L"E", {L"u", L"a", L"g"})
.add_union(L"A", {L"u", L"a"}, is_particle)
.add_union(L"p", {L"M", L"E"}, is_complete);
add_fermi_spin(isr);
return isr;
}
std::shared_ptr<IndexSpaceRegistry> make_sr_spaces() {
auto isr = std::make_shared<IndexSpaceRegistry>();
isr->add(L"o", 0b0001)
.add(L"i", 0b0010, is_hole)
.add(L"a", 0b0100, is_particle)
.add(L"g", 0b1000)
.add_union(L"m", {L"o", L"i"}, is_vacuum_occupied, is_reference_occupied)
.add_union(L"e", {L"a", L"g"})
.add_union(L"x", {L"i", L"a"})
.add_union(L"p", {L"m", L"e"}, is_complete);
add_fermi_spin(isr);
return isr;
}
std::shared_ptr<IndexSpaceRegistry> make_F12_sr_spaces() {
auto isr = std::make_shared<IndexSpaceRegistry>();
isr->add(L"o", 0b00001)
.add(L"i", 0b00010, is_hole)
.add(L"a", 0b00100, is_particle)
.add(L"g", 0b01000)
.add(L"α'", 0b10000)
.add_union(L"m", {L"o", L"i"}, is_vacuum_occupied, is_reference_occupied)
.add_union(L"e", {L"a", L"g"})
.add_union(L"x", {L"i", L"a"})
.add_union(L"p", {L"m", L"e"})
.add_unIon(L"h", {L"x", L"g"})
.add_unIon(L"c", {L"g", L"α'"})
.add_union(L"α", {L"e", L"α'"})
.add_union(L"H", {L"i", L"α"})
.add_union(L"κ", {L"p", L"α'"}, is_complete);
add_fermi_spin(isr);
return isr;
}
std::shared_ptr<IndexSpaceRegistry> make_legacy_spaces(bool ignore_spin) {
auto isr = std::make_shared<IndexSpaceRegistry>();
isr->add(L"o", 0b0000001)
.add(L"n", 0b0000010)
.add(L"i", 0b0000100, is_hole)
.add(L"u", 0b0001000)
.add(L"a", 0b0010000, is_particle)
.add(L"g", 0b0100000)
.add(L"α'", 0b1000000)
.add_union(L"m", {L"o", L"n", L"i"}, is_vacuum_occupied,
is_reference_occupied)
.add_union(L"M", {L"m", L"u"})
.add_union(L"e", {L"a", L"g"})
.add_union(L"E", {L"u", L"e"})
.add_union(L"x", {L"i", L"u", L"a"})
.add_union(L"p", {L"m", L"x", L"e"})
.add_union(L"κ", {L"p", L"α'"}, is_complete);
if (!ignore_spin) add_fermi_spin(isr);
return isr;
}
std::pair<std::shared_ptr<IndexSpaceRegistry>,
std::shared_ptr<IndexSpaceRegistry>>
make_fermi_and_bose_spaces() {
auto isr = std::make_shared<IndexSpaceRegistry>();
isr->add(L"i", 0b001) // fermi occupied
.add(L"a", 0b010) // fermi unoccupied
.add_union(L"p", {L"i", L"a"}) // fermi all
;
add_fermi_spin(isr);
isr->add(L"β", 0b100); // bose
auto fermi_isr = std::make_shared<IndexSpaceRegistry>(isr->spaces());
fermi_isr->vacuum_occupied_space(L"i");
fermi_isr->reference_occupied_space(L"i");
fermi_isr->hole_space(L"i");
fermi_isr->particle_space(L"a");
fermi_isr->complete_space(L"p");
auto bose_isr = std::make_shared<IndexSpaceRegistry>(isr->spaces());
bose_isr->vacuum_occupied_space(IndexSpace::null);
bose_isr->reference_occupied_space(IndexSpace::null);
bose_isr->hole_space(IndexSpace::null);
bose_isr->particle_space(L"β");
bose_isr->complete_space(L"β");
return std::make_pair(std::move(fermi_isr), std::move(bose_isr));
}
} // namespace mbpt
} // namespace sequant