Line data Source code
1 : // SPDX-FileCopyrightText: 2024 PairInteraction Developers
2 : // SPDX-License-Identifier: LGPL-3.0-or-later
3 :
4 : #include "pairinteraction/ket/KetAtom.hpp"
5 :
6 : #include "pairinteraction/enums/Parity.hpp"
7 : #include "pairinteraction/utils/hash.hpp"
8 :
9 : #include <array>
10 : #include <cctype>
11 : #include <cmath>
12 : #include <fmt/core.h>
13 : #include <string>
14 : #include <string_view>
15 : #include <vector>
16 :
17 : namespace pairinteraction {
18 :
19 : constexpr std::array<std::string_view, 6> quantum_number_l_labels = {"S", "P", "D", "F", "G", "H"};
20 :
21 19944 : KetAtom::KetAtom(Private /*unused*/, double energy, double f, double m, Parity p,
22 : std::string species, int n, double nu, double nui_exp, double nui_std,
23 : double l_exp, double l_std, double s_exp, double s_std, double j_exp, double j_std,
24 : double l_ryd_exp, double l_ryd_std, double j_ryd_exp, double j_ryd_std,
25 : bool is_j_total_momentum, bool is_calculated_with_mqdt,
26 : double underspecified_channel_contribution, Database &database,
27 19944 : size_t id_in_database)
28 19944 : : Ket(energy, f, m, p), species(std::move(species)), quantum_number_n(n), quantum_number_nu(nu),
29 19944 : quantum_number_nui_exp(nui_exp), quantum_number_nui_std(nui_std), quantum_number_l_exp(l_exp),
30 19944 : quantum_number_l_std(l_std), quantum_number_s_exp(s_exp), quantum_number_s_std(s_std),
31 19944 : quantum_number_j_exp(j_exp), quantum_number_j_std(j_std), quantum_number_l_ryd_exp(l_ryd_exp),
32 19944 : quantum_number_l_ryd_std(l_ryd_std), quantum_number_j_ryd_exp(j_ryd_exp),
33 19944 : quantum_number_j_ryd_std(j_ryd_std), is_j_total_momentum_(is_j_total_momentum),
34 19944 : is_calculated_with_mqdt_(is_calculated_with_mqdt),
35 19944 : underspecified_channel_contribution(underspecified_channel_contribution), database(database),
36 19944 : id_in_database(id_in_database) {}
37 :
38 32 : Database &KetAtom::get_database() const { return database; }
39 :
40 19764 : size_t KetAtom::get_id_in_database() const { return id_in_database; }
41 :
42 448 : std::string KetAtom::get_label() const {
43 448 : size_t pos = species.find('_');
44 448 : std::string label = (pos != std::string::npos) ? species.substr(0, pos) : species;
45 448 : label[0] = static_cast<char>(std::toupper(label[0]));
46 :
47 448 : if (!is_calculated_with_mqdt_) {
48 391 : if (quantum_number_s_exp == 0) {
49 13 : label += "_singlet";
50 378 : } else if (quantum_number_s_exp == 1) {
51 0 : label += "_triplet";
52 378 : } else if (quantum_number_s_exp != 0.5) {
53 0 : throw std::runtime_error(
54 0 : "Invalid value for quantum number s in the single-channel description.");
55 : }
56 : }
57 :
58 448 : label += ":";
59 :
60 448 : if (is_calculated_with_mqdt_) {
61 57 : label += fmt::format("S={:.1f},nu={:.1f},L={:.1f},", quantum_number_s_exp,
62 114 : quantum_number_nu, quantum_number_l_exp);
63 57 : label += this->is_j_total_momentum_ ? "J=" : "F=";
64 : } else {
65 782 : label += fmt::format("{:d},", quantum_number_n);
66 391 : if (quantum_number_l_exp == std::rint(quantum_number_l_exp) &&
67 391 : quantum_number_l_exp < quantum_number_l_labels.size()) {
68 391 : label += quantum_number_l_labels.at(static_cast<size_t>(quantum_number_l_exp));
69 : } else {
70 0 : label += fmt::format("{:.0f}", quantum_number_l_exp);
71 : }
72 391 : label += "_";
73 : }
74 :
75 448 : if (this->quantum_number_f == std::rint(this->quantum_number_f)) {
76 28 : label += fmt::format("{:.0f}", this->quantum_number_f);
77 434 : } else if (2 * this->quantum_number_f == std::rint(2 * this->quantum_number_f)) {
78 868 : label += fmt::format("{:.0f}/2", 2 * this->quantum_number_f);
79 : } else {
80 0 : std::abort(); // can't happen because the total momentum is validated to be an integer
81 : // or half-integer
82 : }
83 :
84 448 : if (this->quantum_number_m == std::rint(this->quantum_number_m)) {
85 28 : label += fmt::format(",{:.0f}", this->quantum_number_m);
86 434 : } else if (2 * this->quantum_number_m == std::rint(2 * this->quantum_number_m)) {
87 868 : label += fmt::format(",{:.0f}/2", 2 * this->quantum_number_m);
88 : } else {
89 0 : std::abort(); // can't happen because the quantum number m is validated to be an integer
90 : // or half-integer
91 : }
92 :
93 448 : return label;
94 0 : }
95 :
96 : std::shared_ptr<KetAtom>
97 0 : KetAtom::get_ket_for_different_quantum_number_m(double new_quantum_number_m) const {
98 0 : auto ket = *this;
99 0 : ket.quantum_number_m = new_quantum_number_m;
100 0 : return std::make_shared<KetAtom>(ket);
101 0 : }
102 :
103 911 : const std::string &KetAtom::get_species() const { return species; }
104 :
105 107 : int KetAtom::get_quantum_number_n() const { return quantum_number_n; }
106 :
107 29 : double KetAtom::get_quantum_number_nu() const { return quantum_number_nu; }
108 :
109 0 : double KetAtom::get_quantum_number_nui() const { return quantum_number_nui_exp; }
110 :
111 130 : double KetAtom::get_quantum_number_l() const { return quantum_number_l_exp; }
112 :
113 20 : double KetAtom::get_quantum_number_s() const { return quantum_number_s_exp; }
114 :
115 4 : double KetAtom::get_quantum_number_j() const { return quantum_number_j_exp; }
116 :
117 0 : double KetAtom::get_quantum_number_l_ryd() const { return quantum_number_l_ryd_exp; }
118 :
119 0 : double KetAtom::get_quantum_number_j_ryd() const { return quantum_number_j_ryd_exp; }
120 :
121 0 : double KetAtom::get_quantum_number_nui_std() const { return quantum_number_nui_std; }
122 :
123 0 : double KetAtom::get_quantum_number_l_std() const { return quantum_number_l_std; }
124 :
125 0 : double KetAtom::get_quantum_number_s_std() const { return quantum_number_s_std; }
126 :
127 0 : double KetAtom::get_quantum_number_j_std() const { return quantum_number_j_std; }
128 :
129 0 : double KetAtom::get_quantum_number_l_ryd_std() const { return quantum_number_l_ryd_std; }
130 :
131 0 : double KetAtom::get_quantum_number_j_ryd_std() const { return quantum_number_j_ryd_std; }
132 :
133 0 : bool KetAtom::is_j_total_momentum() const { return is_j_total_momentum_; }
134 :
135 44 : bool KetAtom::is_calculated_with_mqdt() const { return is_calculated_with_mqdt_; }
136 :
137 0 : double KetAtom::get_underspecified_channel_contribution() const {
138 0 : return underspecified_channel_contribution;
139 : }
140 :
141 1401 : bool KetAtom::operator==(const KetAtom &other) const {
142 2730 : return Ket::operator==(other) && species == other.species &&
143 1329 : quantum_number_n == other.quantum_number_n &&
144 1329 : quantum_number_nu == other.quantum_number_nu &&
145 1329 : quantum_number_nui_exp == other.quantum_number_nui_exp &&
146 1329 : quantum_number_nui_std == other.quantum_number_nui_std &&
147 1329 : quantum_number_l_exp == other.quantum_number_l_exp &&
148 1329 : quantum_number_l_std == other.quantum_number_l_std &&
149 1329 : quantum_number_s_exp == other.quantum_number_s_exp &&
150 1329 : quantum_number_s_std == other.quantum_number_s_std &&
151 4059 : quantum_number_j_exp == other.quantum_number_j_exp &&
152 2730 : quantum_number_j_std == other.quantum_number_j_std;
153 : }
154 :
155 1 : bool KetAtom::operator!=(const KetAtom &other) const { return !(*this == other); }
156 :
157 20773 : size_t KetAtom::hash::operator()(const KetAtom &k) const {
158 20773 : size_t seed = typename Ket::hash()(k);
159 20773 : utils::hash_combine(seed, k.species);
160 20773 : utils::hash_combine(seed, k.quantum_number_n);
161 20773 : utils::hash_combine(seed, k.quantum_number_nu);
162 20773 : utils::hash_combine(seed, k.quantum_number_nui_exp);
163 20773 : utils::hash_combine(seed, k.quantum_number_nui_std);
164 20773 : utils::hash_combine(seed, k.quantum_number_l_exp);
165 20773 : utils::hash_combine(seed, k.quantum_number_l_std);
166 20773 : utils::hash_combine(seed, k.quantum_number_s_exp);
167 20773 : utils::hash_combine(seed, k.quantum_number_s_std);
168 20773 : utils::hash_combine(seed, k.quantum_number_j_exp);
169 20773 : utils::hash_combine(seed, k.quantum_number_j_std);
170 20773 : return seed;
171 : }
172 :
173 : } // namespace pairinteraction
|