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 "StateOld.hpp"
21 : #include "Constants.hpp"
22 : #include "QuantumDefect.hpp"
23 :
24 : #include <array>
25 : #include <cctype>
26 : #include <iomanip>
27 : #include <iostream>
28 : #include <string>
29 : #include <utility>
30 :
31 : namespace {
32 :
33 : struct getMomentumLabel {
34 : int l;
35 0 : getMomentumLabel(int l) : l(l) {}
36 : };
37 :
38 0 : inline std::ostream &operator<<(std::ostream &os, getMomentumLabel const &l) {
39 : static constexpr std::array const letters = {'S', 'P', 'D', 'F', 'G', 'H', 'I'};
40 0 : if (l.l < static_cast<int>(letters.size())) {
41 0 : os << letters[l.l];
42 : } else {
43 0 : os << l.l;
44 : }
45 0 : return os;
46 : }
47 :
48 : } // namespace
49 :
50 : ///+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
51 : /// Implementation of StateOne +++++++++++++++++++++++++++++++++++++
52 : ///+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
53 :
54 95236 : StateOneOld::StateOneOld(std::string element, int n, int l, float j, float m)
55 95236 : : StateOld(0), species(std::move(element)), n(n), l(l), j(j), m(m) {
56 95236 : this->analyzeSpecies();
57 95236 : }
58 :
59 8 : StateOneOld::StateOneOld() : StateOld(0), species("") { this->analyzeSpecies(); }
60 :
61 102074 : StateOneOld::StateOneOld(idx_t idx, int n, int l, float j, float m)
62 102074 : : StateOld(idx), n(n), l(l), j(j), m(m) {
63 102074 : this->analyzeSpecies();
64 102074 : }
65 :
66 0 : StateOneOld::StateOneOld(int n, int l, float j, float m) : StateOld(0), n(n), l(l), j(j), m(m) {
67 0 : this->analyzeSpecies();
68 0 : }
69 :
70 0 : std::ostream &operator<<(std::ostream &out, const StateOneOld &state) {
71 0 : out << "|" << state.species << ", ";
72 :
73 0 : out << state.n << " ";
74 :
75 0 : out << getMomentumLabel(state.l) << "_";
76 :
77 0 : if (std::ceil(state.j) == state.j) {
78 0 : out << state.j << ", ";
79 0 : out << "mj=" << state.m << ">";
80 : } else {
81 0 : out << 2 * state.j << "/2, ";
82 0 : out << "mj=" << 2 * state.m << "/2>";
83 : }
84 :
85 0 : return out;
86 : }
87 :
88 100482 : bool StateOneOld::operator==(StateOneOld const &rhs) const {
89 : // TODO use elements, too?
90 100482 : return (n == rhs.n) && (l == rhs.l) && (j == rhs.j) && (m == rhs.m);
91 : }
92 :
93 0 : bool StateOneOld::operator^(
94 : StateOneOld const &rhs) const { // subset // TODO is there a better operator to use?
95 0 : return (rhs.n == ARB || n == rhs.n) && (rhs.l == ARB || l == rhs.l) &&
96 0 : (rhs.j == ARB || j == rhs.j) && (rhs.m == ARB || m == rhs.m);
97 : }
98 :
99 0 : bool StateOneOld::operator!=(StateOneOld const &rhs) const {
100 0 : return ((n != rhs.n) || (l != rhs.l) || (j != rhs.j) || (m != rhs.m));
101 : }
102 :
103 18369 : bool StateOneOld::operator<(const StateOneOld &rhs) const {
104 : // TODO use elements, too?
105 31775 : return ((n < rhs.n) ||
106 13406 : ((n == rhs.n) &&
107 28879 : ((l < rhs.l) || ((l == rhs.l) && ((j < rhs.j) || ((j == rhs.j) && (m < rhs.m)))))));
108 : }
109 :
110 0 : double StateOneOld::getEnergy() const { return energy_level(species, n, l, j); }
111 :
112 0 : double StateOneOld::getNStar() const { return nstar(species, n, l, j); }
113 :
114 0 : std::string StateOneOld::getSpecies() const { return species; }
115 :
116 0 : int StateOneOld::getN() const { return n; }
117 :
118 0 : int StateOneOld::getL() const { return l; }
119 :
120 0 : float StateOneOld::getJ() const { return j; }
121 :
122 0 : float StateOneOld::getM() const { return m; }
123 :
124 : ////////////////////////////////////////////////////////////////////
125 : /// Utility methods ////////////////////////////////////////////////
126 : ////////////////////////////////////////////////////////////////////
127 :
128 197314 : void StateOneOld::analyzeSpecies() {
129 197314 : s = 0.5;
130 197314 : element = species;
131 :
132 197314 : if (!species.empty() && std::isdigit(species.back()) != 0) {
133 0 : s = ((species.back() - '0') - 1) / 2.;
134 0 : element = species.substr(0, species.size() - 1);
135 : }
136 197314 : }
137 :
138 : ///+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
139 : /// Implementation of StateTwo +++++++++++++++++++++++++++++++++++++
140 : ///+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
141 :
142 11 : StateTwoOld::StateTwoOld()
143 22 : : StateOld(0), species({{"", ""}}), n({{0, 0}}), l({{0, 0}}), j({{0, 0}}), m({{0, 0}}) {
144 11 : this->analyzeSpecies();
145 11 : }
146 :
147 0 : StateTwoOld::StateTwoOld(std::array<std::string, 2> element, std::array<int, 2> n,
148 0 : std::array<int, 2> l, std::array<float, 2> j, std::array<float, 2> m)
149 0 : : StateOld(0), species(std::move(element)), n(n), l(l), j(j), m(m) {
150 0 : this->analyzeSpecies();
151 0 : }
152 :
153 16349 : StateTwoOld::StateTwoOld(const StateOneOld &s1, const StateOneOld &s2)
154 49047 : : StateOld(0), species({{s1.species, s2.species}}), n({{s1.n, s2.n}}), l({{s1.l, s2.l}}),
155 16349 : j({{s1.j, s2.j}}), m({{s1.m, s2.m}}) {
156 16349 : this->analyzeSpecies();
157 16349 : }
158 :
159 0 : StateTwoOld::StateTwoOld(idx_t idx, std::array<int, 2> n, std::array<int, 2> l,
160 0 : std::array<float, 2> j, std::array<float, 2> m)
161 0 : : StateOld(idx), n(n), l(l), j(j), m(m) {
162 0 : this->analyzeSpecies();
163 0 : }
164 :
165 118316 : StateTwoOld::StateTwoOld(std::array<int, 2> n, std::array<int, 2> l, std::array<float, 2> j,
166 118316 : std::array<float, 2> m)
167 118316 : : StateOld(0), n(n), l(l), j(j), m(m) {
168 118316 : this->analyzeSpecies();
169 118316 : }
170 :
171 100352 : StateTwoOld::StateTwoOld(idx_t idx, const StateOneOld &a, const StateOneOld &b)
172 100352 : : StateOld(idx), n({{a.n, b.n}}), l({{a.l, b.l}}), j({{a.j, b.j}}), m({{a.m, b.m}}) {
173 100352 : this->analyzeSpecies();
174 100352 : }
175 :
176 0 : StateOneOld StateTwoOld::getFirstState() const {
177 0 : return StateOneOld(species[0], n[0], l[0], j[0], m[0]);
178 : }
179 0 : void StateTwoOld::setFirstState(StateOneOld const &s) {
180 0 : species[0] = s.species;
181 0 : n[0] = s.n;
182 0 : l[0] = s.l;
183 0 : j[0] = s.j;
184 0 : m[0] = s.m;
185 0 : }
186 :
187 0 : StateOneOld StateTwoOld::getSecondState() const {
188 0 : return StateOneOld(species[1], n[1], l[1], j[1], m[1]);
189 : }
190 0 : void StateTwoOld::setSecondState(StateOneOld const &s) {
191 0 : species[1] = s.species;
192 0 : n[1] = s.n;
193 0 : l[1] = s.l;
194 0 : j[1] = s.j;
195 0 : m[1] = s.m;
196 0 : }
197 :
198 60922 : StateOneOld StateTwoOld::first() const { return StateOneOld(species[0], n[0], l[0], j[0], m[0]); }
199 34314 : StateOneOld StateTwoOld::second() const { return StateOneOld(species[1], n[1], l[1], j[1], m[1]); }
200 :
201 0 : std::ostream &operator<<(std::ostream &out, const StateTwoOld &state) {
202 0 : out << "|";
203 0 : for (size_t i = 0; i < 2; ++i) {
204 0 : out << state.species[i] << ", ";
205 :
206 0 : out << state.n[i] << " ";
207 :
208 0 : out << getMomentumLabel(state.l[i]) << "_";
209 :
210 0 : if (std::ceil(state.j[i]) == state.j[i]) {
211 0 : out << state.j[i] << ", ";
212 0 : out << "mj=" << state.m[i] << ">";
213 : } else {
214 0 : out << 2 * state.j[i] << "/2, ";
215 0 : out << "mj=" << 2 * state.m[i] << "/2";
216 : }
217 :
218 0 : if (i == 0) {
219 0 : out << "; ";
220 : }
221 : }
222 0 : out << ">";
223 0 : return out;
224 : }
225 :
226 182191 : bool StateTwoOld::operator==(const StateTwoOld &rhs) const {
227 301662 : return (n[0] == rhs.n[0]) && (l[0] == rhs.l[0]) && (j[0] == rhs.j[0]) && (m[0] == rhs.m[0]) &&
228 301662 : (n[1] == rhs.n[1]) && (l[1] == rhs.l[1]) && (j[1] == rhs.j[1]) && (m[1] == rhs.m[1]);
229 : }
230 :
231 0 : bool StateTwoOld::operator^(
232 : const StateTwoOld &rhs) const { // subset // TODO is there a better operator to use?
233 0 : return (rhs.n[0] == ARB || n[0] == rhs.n[0]) && (rhs.l[0] == ARB || l[0] == rhs.l[0]) &&
234 0 : (rhs.j[0] == ARB || j[0] == rhs.j[0]) && (rhs.m[0] == ARB || m[0] == rhs.m[0]) &&
235 0 : (rhs.n[1] == ARB || n[1] == rhs.n[1]) && (rhs.l[1] == ARB || l[1] == rhs.l[1]) &&
236 0 : (rhs.j[1] == ARB || j[1] == rhs.j[1]) && (rhs.m[1] == ARB || m[1] == rhs.m[1]);
237 : }
238 :
239 0 : bool StateTwoOld::operator!=(const StateTwoOld &rhs) const {
240 0 : return (n[0] != rhs.n[0]) || (l[0] != rhs.l[0]) || (j[0] != rhs.j[0]) || (m[0] != rhs.m[0]) ||
241 0 : (n[1] != rhs.n[1]) || (l[1] != rhs.l[1]) || (j[1] != rhs.j[1]) || (m[1] != rhs.m[1]);
242 : }
243 :
244 0 : bool StateTwoOld::operator<(const StateTwoOld &rhs) const {
245 0 : return ((this->first() < rhs.first()) ||
246 0 : ((this->first() == rhs.first()) && (this->second() < rhs.second())));
247 : }
248 :
249 29467 : StateTwoOld StateTwoOld::order() { // TODO use element, too?
250 49818 : if ((n[0] < n[1]) ||
251 20351 : ((n[0] == n[1]) &&
252 7314 : ((l[0] < l[1]) ||
253 5496 : ((l[0] == l[1]) && ((j[0] < j[1]) || ((j[0] == j[1]) && (m[0] <= m[1]))))))) {
254 13118 : return *this;
255 : }
256 32698 : return StateTwoOld(this->second(), this->first());
257 : }
258 :
259 0 : double StateTwoOld::getEnergy() const {
260 0 : return this->first().getEnergy() + this->second().getEnergy();
261 : }
262 :
263 0 : std::array<double, 2> StateTwoOld::getNStar() const {
264 0 : return {{this->first().getNStar(), this->second().getNStar()}};
265 : }
266 :
267 0 : std::array<std::string, 2> StateTwoOld::getSpecies() const { return species; }
268 :
269 0 : std::array<int, 2> StateTwoOld::getN() const { return n; }
270 :
271 0 : std::array<int, 2> StateTwoOld::getL() const { return l; }
272 :
273 0 : std::array<float, 2> StateTwoOld::getJ() const { return j; }
274 :
275 0 : std::array<float, 2> StateTwoOld::getM() const { return m; }
276 :
277 : ////////////////////////////////////////////////////////////////////
278 : /// Utility methods ////////////////////////////////////////////////
279 : ////////////////////////////////////////////////////////////////////
280 :
281 235028 : void StateTwoOld::analyzeSpecies() {
282 705084 : for (size_t i = 0; i < 2; ++i) {
283 470056 : s[i] = 0.5;
284 470056 : element[i] = species[i];
285 :
286 470056 : if (!species[i].empty() && std::isdigit(species[i].back()) != 0) {
287 0 : s[i] = ((species[i].back() - '0') - 1) / 2.;
288 0 : element[i] = species[i].substr(0, species[i].size() - 1);
289 : }
290 : }
291 235028 : }
|