LCOV - code coverage report
Current view: top level - src/ket - KetAtom.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 77 101 76.2 %
Date: 2025-06-06 09:03:58 Functions: 13 26 50.0 %

          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       11804 : 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       11804 :                  size_t id_in_database)
      28       11804 :     : Ket(energy, f, m, p), species(std::move(species)), quantum_number_n(n), quantum_number_nu(nu),
      29       11804 :       quantum_number_nui_exp(nui_exp), quantum_number_nui_std(nui_std), quantum_number_l_exp(l_exp),
      30       11804 :       quantum_number_l_std(l_std), quantum_number_s_exp(s_exp), quantum_number_s_std(s_std),
      31       11804 :       quantum_number_j_exp(j_exp), quantum_number_j_std(j_std), quantum_number_l_ryd_exp(l_ryd_exp),
      32       11804 :       quantum_number_l_ryd_std(l_ryd_std), quantum_number_j_ryd_exp(j_ryd_exp),
      33       11804 :       quantum_number_j_ryd_std(j_ryd_std), is_j_total_momentum_(is_j_total_momentum),
      34       11804 :       is_calculated_with_mqdt_(is_calculated_with_mqdt),
      35       11804 :       underspecified_channel_contribution(underspecified_channel_contribution), database(database),
      36       11804 :       id_in_database(id_in_database) {}
      37             : 
      38           0 : Database &KetAtom::get_database() const { return database; }
      39             : 
      40       11713 : size_t KetAtom::get_id_in_database() const { return id_in_database; }
      41             : 
      42         256 : std::string KetAtom::get_label() const {
      43         256 :     size_t pos = species.find('_');
      44         256 :     std::string label = (pos != std::string::npos) ? species.substr(0, pos) : species;
      45         256 :     label[0] = static_cast<char>(std::toupper(label[0]));
      46             : 
      47         256 :     if (!is_calculated_with_mqdt_) {
      48         194 :         if (quantum_number_s_exp == 0) {
      49          14 :             label += "_singlet";
      50         180 :         } else if (quantum_number_s_exp == 1) {
      51           1 :             label += "_triplet";
      52         179 :         } 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         256 :     label += ":";
      59             : 
      60         256 :     if (is_calculated_with_mqdt_) {
      61          62 :         label += fmt::format("S={:.1f},nu={:.1f},L={:.1f},", quantum_number_s_exp,
      62         124 :                              quantum_number_nu, quantum_number_l_exp);
      63          62 :         label += this->is_j_total_momentum_ ? "J=" : "F=";
      64             :     } else {
      65         388 :         label += fmt::format("{:d},", quantum_number_n);
      66         194 :         if (quantum_number_l_exp == std::rint(quantum_number_l_exp) &&
      67         194 :             quantum_number_l_exp < quantum_number_l_labels.size()) {
      68         194 :             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         194 :         label += "_";
      73             :     }
      74             : 
      75         256 :     double total_momentum =
      76         256 :         this->is_j_total_momentum_ ? this->quantum_number_j_exp : this->quantum_number_f;
      77         256 :     if (total_momentum == std::rint(total_momentum)) {
      78          18 :         label += fmt::format("{:.0f}", total_momentum);
      79         238 :     } else if (2 * total_momentum == std::rint(2 * total_momentum)) {
      80         476 :         label += fmt::format("{:.0f}/2", 2 * total_momentum);
      81             :     } else {
      82           0 :         std::abort(); // can't happen because the total momentum is validated to be an integer
      83             :                       // or half-integer
      84             :     }
      85             : 
      86         256 :     if (this->quantum_number_m == std::rint(this->quantum_number_m)) {
      87          36 :         label += fmt::format(",{:.0f}", this->quantum_number_m);
      88         238 :     } else if (2 * this->quantum_number_m == std::rint(2 * this->quantum_number_m)) {
      89         476 :         label += fmt::format(",{:.0f}/2", 2 * this->quantum_number_m);
      90             :     } else {
      91           0 :         std::abort(); // can't happen because the quantum number m is validated to be an integer
      92             :                       // or half-integer
      93             :     }
      94             : 
      95         512 :     return label;
      96           0 : }
      97             : 
      98             : std::shared_ptr<KetAtom>
      99           0 : KetAtom::get_ket_for_different_quantum_number_m(double new_quantum_number_m) const {
     100           0 :     auto ket = *this;
     101           0 :     ket.quantum_number_m = new_quantum_number_m;
     102           0 :     return std::make_shared<KetAtom>(ket);
     103           0 : }
     104             : 
     105         508 : const std::string &KetAtom::get_species() const { return species; }
     106             : 
     107          54 : int KetAtom::get_quantum_number_n() const { return quantum_number_n; }
     108             : 
     109          15 : double KetAtom::get_quantum_number_nu() const { return quantum_number_nu; }
     110             : 
     111           0 : double KetAtom::get_quantum_number_nui() const { return quantum_number_nui_exp; }
     112             : 
     113          72 : double KetAtom::get_quantum_number_l() const { return quantum_number_l_exp; }
     114             : 
     115          11 : double KetAtom::get_quantum_number_s() const { return quantum_number_s_exp; }
     116             : 
     117           3 : double KetAtom::get_quantum_number_j() const { return quantum_number_j_exp; }
     118             : 
     119           0 : double KetAtom::get_quantum_number_l_ryd() const { return quantum_number_l_ryd_exp; }
     120             : 
     121           0 : double KetAtom::get_quantum_number_j_ryd() const { return quantum_number_j_ryd_exp; }
     122             : 
     123           0 : double KetAtom::get_quantum_number_nui_std() const { return quantum_number_nui_std; }
     124             : 
     125           0 : double KetAtom::get_quantum_number_l_std() const { return quantum_number_l_std; }
     126             : 
     127           0 : double KetAtom::get_quantum_number_s_std() const { return quantum_number_s_std; }
     128             : 
     129           0 : double KetAtom::get_quantum_number_j_std() const { return quantum_number_j_std; }
     130             : 
     131           0 : double KetAtom::get_quantum_number_l_ryd_std() const { return quantum_number_l_ryd_std; }
     132             : 
     133           0 : double KetAtom::get_quantum_number_j_ryd_std() const { return quantum_number_j_ryd_std; }
     134             : 
     135           0 : bool KetAtom::is_j_total_momentum() const { return is_j_total_momentum_; }
     136             : 
     137           6 : bool KetAtom::is_calculated_with_mqdt() const { return is_calculated_with_mqdt_; }
     138             : 
     139           0 : double KetAtom::get_underspecified_channel_contribution() const {
     140           0 :     return underspecified_channel_contribution;
     141             : }
     142             : 
     143         555 : bool KetAtom::operator==(const KetAtom &other) const {
     144        1104 :     return Ket::operator==(other) && species == other.species &&
     145         549 :         quantum_number_n == other.quantum_number_n &&
     146         549 :         quantum_number_nu == other.quantum_number_nu &&
     147         549 :         quantum_number_nui_exp == other.quantum_number_nui_exp &&
     148         549 :         quantum_number_nui_std == other.quantum_number_nui_std &&
     149         549 :         quantum_number_l_exp == other.quantum_number_l_exp &&
     150         549 :         quantum_number_l_std == other.quantum_number_l_std &&
     151         549 :         quantum_number_s_exp == other.quantum_number_s_exp &&
     152         549 :         quantum_number_s_std == other.quantum_number_s_std &&
     153        1653 :         quantum_number_j_exp == other.quantum_number_j_exp &&
     154        1104 :         quantum_number_j_std == other.quantum_number_j_std;
     155             : }
     156             : 
     157           1 : bool KetAtom::operator!=(const KetAtom &other) const { return !(*this == other); }
     158             : 
     159       12207 : size_t KetAtom::hash::operator()(const KetAtom &k) const {
     160       12207 :     size_t seed = typename Ket::hash()(k);
     161       12207 :     utils::hash_combine(seed, k.species);
     162       12207 :     utils::hash_combine(seed, k.quantum_number_n);
     163       12207 :     utils::hash_combine(seed, k.quantum_number_nu);
     164       12207 :     utils::hash_combine(seed, k.quantum_number_nui_exp);
     165       12207 :     utils::hash_combine(seed, k.quantum_number_nui_std);
     166       12207 :     utils::hash_combine(seed, k.quantum_number_l_exp);
     167       12207 :     utils::hash_combine(seed, k.quantum_number_l_std);
     168       12207 :     utils::hash_combine(seed, k.quantum_number_s_exp);
     169       12207 :     utils::hash_combine(seed, k.quantum_number_s_std);
     170       12207 :     utils::hash_combine(seed, k.quantum_number_j_exp);
     171       12207 :     utils::hash_combine(seed, k.quantum_number_j_std);
     172       12207 :     return seed;
     173             : }
     174             : 
     175             : } // namespace pairinteraction

Generated by: LCOV version 1.16