LCOV - code coverage report
Current view: top level - pairinteraction - State.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 177 195 90.8 %
Date: 2024-04-29 00:41:50 Functions: 63 72 87.5 %

          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); }

Generated by: LCOV version 1.14