Line data Source code
1 : /*
2 : * Copyright (c) 2016 Sebastian Weber, Henri Menke. All rights reserved.
3 : *
4 : * This file is part of the pairinteraction library.
5 : *
6 : * The pairinteraction library is free software: you can redistribute it and/or modify
7 : * it under the terms of the GNU Lesser General Public License as published by
8 : * the Free Software Foundation, either version 3 of the License, or
9 : * (at your option) any later version.
10 : *
11 : * The pairinteraction library is distributed in the hope that it will be useful,
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : * GNU Lesser General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public License
17 : * along with the pairinteraction library. If not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include "State.hpp"
21 : #include "Constants.hpp"
22 : #include "MatrixElementCache.hpp"
23 : #include "QuantumDefect.hpp"
24 : #include "utils.hpp"
25 :
26 : #include <array>
27 : #include <cctype>
28 : #include <iomanip>
29 : #include <iostream>
30 : #include <string>
31 : #include <utility>
32 :
33 : namespace {
34 :
35 : struct getMomentumLabel {
36 : int l;
37 14 : getMomentumLabel(int l) : l(l) {}
38 : };
39 :
40 14 : inline std::ostream &operator<<(std::ostream &os, getMomentumLabel const &l) {
41 : static constexpr std::array const letters = {'S', 'P', 'D', 'F', 'G', 'H', 'I'};
42 14 : if (l.l < static_cast<int>(letters.size())) {
43 14 : os << letters[l.l];
44 : } else {
45 0 : os << l.l;
46 : }
47 14 : return os;
48 : }
49 :
50 : } // namespace
51 :
52 : ////////////////////////////////////////////////////////////////////
53 : /// Implementation of one-atom state ///////////////////////////////
54 : ////////////////////////////////////////////////////////////////////
55 :
56 256796 : StateOne::StateOne(std::string species, int n, int l, float j, float m)
57 256796 : : species(std::move(species)), n(n), l(l), j(j), m(m) {
58 256796 : this->analyzeSpecies();
59 256796 : hashvalue = 0;
60 256796 : utils::hash_combine(hashvalue, this->getSpecies());
61 256796 : utils::hash_combine(hashvalue, this->getN());
62 256796 : utils::hash_combine(hashvalue, this->getL());
63 256796 : utils::hash_combine(hashvalue, this->getJ());
64 256796 : utils::hash_combine(hashvalue, this->getM());
65 256796 : }
66 :
67 192 : StateOne::StateOne(std::string label)
68 192 : : species(std::move(label)), element(""), n(0), l(0), j(0), m(0), s(0) {
69 192 : hashvalue = std::hash<std::string>{}(this->getLabel());
70 192 : }
71 :
72 : // Methods for printing the state
73 14 : std::ostream &operator<<(std::ostream &out, const StateOne &state) {
74 14 : out << "|";
75 14 : if (state.isArtificial()) {
76 0 : out << state.getLabel();
77 : } else {
78 14 : out << state.getSpecies() << ", " << state.getN() << " " << getMomentumLabel(state.getL())
79 14 : << "_";
80 14 : if (std::ceil(state.getJ()) == state.getJ()) {
81 4 : out << state.getJ() << ", ";
82 4 : out << "mj=" << state.getM();
83 : } else {
84 10 : out << 2 * state.getJ() << "/2, ";
85 10 : out << "mj=" << 2 * state.getM() << "/2";
86 : }
87 : }
88 14 : out << ">";
89 14 : return out;
90 : }
91 :
92 1 : std::string StateOne::str() const {
93 2 : std::stringstream ss;
94 1 : ss << *this;
95 2 : return ss.str();
96 : }
97 :
98 : // Getters
99 1584936 : const int &StateOne::getN() const {
100 1584936 : this->shouldBeArtificial(false);
101 1584936 : return n;
102 : }
103 14367065 : const int &StateOne::getL() const {
104 14367065 : this->shouldBeArtificial(false);
105 14367065 : return l;
106 : }
107 15022099 : const float &StateOne::getJ() const {
108 15022099 : this->shouldBeArtificial(false);
109 15022099 : return j;
110 : }
111 15539400 : const float &StateOne::getM() const {
112 15539400 : this->shouldBeArtificial(false);
113 15539400 : return m;
114 : }
115 514312 : const float &StateOne::getS() const {
116 514312 : this->shouldBeArtificial(false);
117 514312 : return s;
118 : }
119 2001427 : const std::string &StateOne::getSpecies() const {
120 2001427 : this->shouldBeArtificial(false);
121 2001427 : return species;
122 : }
123 10 : const std::string &StateOne::getElement() const {
124 10 : this->shouldBeArtificial(false);
125 10 : return element;
126 : }
127 627 : double StateOne::getEnergy() const {
128 627 : this->shouldBeArtificial(false);
129 1254 : return energy_level(species, n, l, j);
130 : }
131 143209 : double StateOne::getEnergy(MatrixElementCache &cache) const {
132 143209 : this->shouldBeArtificial(false);
133 143209 : return energy_level(species, n, l, j, cache.getDefectDB());
134 : }
135 1 : double StateOne::getNStar() const {
136 1 : this->shouldBeArtificial(false);
137 2 : return nstar(species, n, l, j);
138 : }
139 14960 : double StateOne::getNStar(MatrixElementCache &cache) const {
140 14960 : this->shouldBeArtificial(false);
141 14960 : return nstar(species, n, l, j, cache.getDefectDB());
142 : }
143 202 : const std::string &StateOne::getLabel() const {
144 202 : this->shouldBeArtificial(true);
145 202 : return species;
146 : }
147 56055286 : bool StateOne::isArtificial() const { return (n == 0); }
148 463 : bool StateOne::isGeneralized() const {
149 463 : return (n == ARB) || (l == ARB) || (j == ARB) || (m == ARB);
150 : }
151 :
152 4434568 : const size_t &StateOne::getHash() const { return hashvalue; }
153 :
154 198398 : StateOne StateOne::getReflected() const {
155 198398 : return StateOne(this->getSpecies(), this->getN(), this->getL(), this->getJ(), -this->getM());
156 : }
157 :
158 : // Comparators
159 5019674 : bool StateOne::operator==(StateOne const &rhs) const {
160 5019674 : return (species == rhs.species) && (n == rhs.n) && (l == rhs.l) && (j == rhs.j) && (m == rhs.m);
161 : }
162 166 : bool StateOne::operator^(StateOne const &rhs) const {
163 332 : return (species == rhs.species) && (rhs.n == ARB || n == rhs.n) &&
164 392 : (rhs.l == ARB || l == rhs.l) && (rhs.j == ARB || j == rhs.j) &&
165 226 : (rhs.m == ARB || m == rhs.m);
166 : }
167 6 : bool StateOne::operator!=(StateOne const &rhs) const {
168 6 : return (species != rhs.species) || (n != rhs.n) || (l != rhs.l) || (j != rhs.j) || (m != rhs.m);
169 : }
170 50 : bool StateOne::operator<(const StateOne &rhs) const {
171 150 : return (species < rhs.species) ||
172 50 : ((species == rhs.species) &&
173 50 : ((n < rhs.n) ||
174 50 : ((n == rhs.n) &&
175 100 : ((l < rhs.l) || ((l == rhs.l) && ((j < rhs.j) || ((j == rhs.j) && (m < rhs.m))))))));
176 : }
177 0 : bool StateOne::operator<=(const StateOne &rhs) const { return (*this < rhs) || (*this == rhs); }
178 :
179 : // Utility methods
180 256796 : void StateOne::analyzeSpecies() {
181 256796 : s = 0.5;
182 256796 : element = species;
183 256796 : if (std::isdigit(species.back()) != 0) {
184 62 : s = ((species.back() - '0') - 1) / 2.;
185 62 : element = species.substr(0, species.size() - 1);
186 : }
187 256796 : }
188 49188248 : void StateOne::shouldBeArtificial(bool opinion) const {
189 49188248 : if (this->isArtificial() != opinion) {
190 0 : throw std::runtime_error("The state does not have this property.");
191 : }
192 49188248 : }
193 :
194 : ////////////////////////////////////////////////////////////////////
195 : /// Implementation of two-atom state ///////////////////////////////
196 : ////////////////////////////////////////////////////////////////////
197 :
198 25098 : StateTwo::StateTwo(std::array<std::string, 2> species, std::array<int, 2> n, std::array<int, 2> l,
199 25098 : std::array<float, 2> j, std::array<float, 2> m)
200 25098 : : state_array({{StateOne(species[0], n[0], l[0], j[0], m[0]),
201 50196 : StateOne(species[1], n[1], l[1], j[1], m[1])}}) {
202 25098 : hashvalue = 0;
203 25098 : utils::hash_combine(hashvalue, state_array[0].getHash());
204 25098 : utils::hash_combine(hashvalue, state_array[1].getHash());
205 25098 : }
206 93 : StateTwo::StateTwo(std::array<std::string, 2> label)
207 93 : : state_array({{StateOne(label[0]), StateOne(label[1])}}) {
208 93 : hashvalue = 0;
209 93 : utils::hash_combine(hashvalue, state_array[0].getHash());
210 93 : utils::hash_combine(hashvalue, state_array[1].getHash());
211 93 : }
212 2170671 : StateTwo::StateTwo(StateOne first_state, StateOne second_state)
213 2170671 : : state_array({{std::move(first_state), std::move(second_state)}}) {
214 2170671 : hashvalue = 0;
215 2170671 : utils::hash_combine(hashvalue, state_array[0].getHash());
216 2170671 : utils::hash_combine(hashvalue, state_array[1].getHash());
217 2170671 : }
218 :
219 : // Methods for printing the state
220 5 : std::ostream &operator<<(std::ostream &out, const StateTwo &state) {
221 5 : out << state.state_array[0] << state.state_array[1];
222 5 : return out;
223 : }
224 :
225 0 : std::string StateTwo::str() const {
226 0 : std::stringstream ss;
227 0 : ss << *this;
228 0 : return ss.str();
229 : }
230 :
231 : // Getters
232 8315 : std::array<int, 2> StateTwo::getN() const {
233 8315 : return {{state_array[0].getN(), state_array[1].getN()}};
234 : }
235 15795 : std::array<int, 2> StateTwo::getL() const {
236 15795 : return {{state_array[0].getL(), state_array[1].getL()}};
237 : }
238 8315 : std::array<float, 2> StateTwo::getJ() const {
239 8315 : return {{state_array[0].getJ(), state_array[1].getJ()}};
240 : }
241 1449 : std::array<float, 2> StateTwo::getM() const {
242 1449 : return {{state_array[0].getM(), state_array[1].getM()}};
243 : }
244 32 : std::array<float, 2> StateTwo::getS() const {
245 32 : return {{state_array[0].getS(), state_array[1].getS()}};
246 : }
247 8107 : std::array<std::string, 2> StateTwo::getSpecies() const {
248 8107 : return {{state_array[0].getSpecies(), state_array[1].getSpecies()}};
249 : }
250 2 : std::array<std::string, 2> StateTwo::getElement() const {
251 2 : return {{state_array[0].getElement(), state_array[1].getElement()}};
252 : }
253 216 : double StateTwo::getEnergy() const {
254 216 : return state_array[0].getEnergy() + state_array[1].getEnergy();
255 : }
256 70316 : double StateTwo::getEnergy(MatrixElementCache &cache) const {
257 70316 : return state_array[0].getEnergy(cache) + state_array[1].getEnergy(cache);
258 : }
259 0 : std::array<double, 2> StateTwo::getNStar() const {
260 0 : return {{state_array[0].getNStar(), state_array[1].getNStar()}};
261 : }
262 7480 : std::array<double, 2> StateTwo::getNStar(MatrixElementCache &cache) const {
263 7480 : return {{state_array[0].getNStar(cache), state_array[1].getNStar(cache)}};
264 : }
265 59 : double StateTwo::getLeRoyRadius(MatrixElementCache &cache) const {
266 : return 2 *
267 59 : (std::sqrt(cache.getRadial(state_array[0], state_array[0], 2)) +
268 59 : std::sqrt(cache.getRadial(state_array[1], state_array[1], 2)));
269 : }
270 2 : std::array<std::string, 2> StateTwo::getLabel() const {
271 2 : return {{state_array[0].getLabel(), state_array[1].getLabel()}};
272 : }
273 2 : std::array<bool, 2> StateTwo::isArtificial() const {
274 2 : return {{state_array[0].isArtificial(), state_array[1].isArtificial()}};
275 : }
276 169 : std::array<bool, 2> StateTwo::isGeneralized() const {
277 169 : return {{state_array[0].isGeneralized(), state_array[1].isGeneralized()}};
278 : }
279 :
280 426 : const int &StateTwo::getN(int idx) const { return state_array[idx].getN(); }
281 11295 : const int &StateTwo::getL(int idx) const { return state_array[idx].getL(); }
282 13573 : const float &StateTwo::getJ(int idx) const { return state_array[idx].getJ(); }
283 6331645 : const float &StateTwo::getM(int idx) const { return state_array[idx].getM(); }
284 4651 : const float &StateTwo::getS(int idx) const { return state_array[idx].getS(); }
285 124 : const std::string &StateTwo::getSpecies(int idx) const { return state_array[idx].getSpecies(); }
286 4 : const std::string &StateTwo::getElement(int idx) const { return state_array[idx].getElement(); }
287 0 : double StateTwo::getEnergy(int idx) const { return state_array[idx].getEnergy(); }
288 0 : double StateTwo::getEnergy(int idx, MatrixElementCache &cache) const {
289 0 : return state_array[idx].getEnergy(cache);
290 : }
291 0 : double StateTwo::getNStar(int idx) const { return state_array[idx].getNStar(); }
292 0 : double StateTwo::getNStar(int idx, MatrixElementCache &cache) const {
293 0 : return state_array[idx].getNStar(cache);
294 : }
295 4 : const std::string &StateTwo::getLabel(int idx) const { return state_array[idx].getLabel(); }
296 6250110 : bool StateTwo::isArtificial(int idx) const { return state_array[idx].isArtificial(); }
297 0 : bool StateTwo::isGeneralized(int idx) const { return state_array[idx].isGeneralized(); }
298 :
299 3345335 : const StateOne &StateTwo::getFirstState() const { return state_array[0]; }
300 938687 : const StateOne &StateTwo::getSecondState() const { return state_array[1]; }
301 :
302 2231762 : const size_t &StateTwo::getHash() const { return hashvalue; }
303 :
304 1 : StateTwo StateTwo::getReflected() const {
305 2 : return StateTwo(this->getSpecies(), this->getN(), this->getL(), this->getJ(),
306 3 : {{-this->getM(0), -this->getM(1)}});
307 : }
308 :
309 : // Comparators
310 2828604 : bool StateTwo::operator==(StateTwo const &rhs) const {
311 2828604 : return (state_array[0] == rhs.state_array[0]) && (state_array[1] == rhs.state_array[1]);
312 : }
313 4 : bool StateTwo::operator^(StateTwo const &rhs) const {
314 4 : return (state_array[0] ^ rhs.state_array[0]) && (state_array[1] ^ rhs.state_array[1]);
315 : }
316 2 : bool StateTwo::operator!=(StateTwo const &rhs) const {
317 2 : return (state_array[0] != rhs.state_array[0]) || (state_array[1] != rhs.state_array[1]);
318 : }
319 42 : bool StateTwo::operator<(const StateTwo &rhs) const {
320 64 : return (state_array[0] < rhs.state_array[0]) ||
321 64 : ((state_array[0] == rhs.state_array[0]) && (state_array[1] < rhs.state_array[1]));
322 : }
323 0 : bool StateTwo::operator<=(const StateTwo &rhs) const { return (*this < rhs) || (*this == rhs); }
|