LCOV - code coverage report
Current view: top level - src/ket - KetAtom.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 78 101 77.2 %
Date: 2025-05-02 21:49:55 Functions: 14 26 53.8 %

          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        9376 : 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        9376 :                  size_t id_in_database)
      28        9376 :     : Ket(energy, f, m, p), species(std::move(species)), quantum_number_n(n), quantum_number_nu(nu),
      29        9376 :       quantum_number_nui_exp(nui_exp), quantum_number_nui_std(nui_std), quantum_number_l_exp(l_exp),
      30        9376 :       quantum_number_l_std(l_std), quantum_number_s_exp(s_exp), quantum_number_s_std(s_std),
      31        9376 :       quantum_number_j_exp(j_exp), quantum_number_j_std(j_std), quantum_number_l_ryd_exp(l_ryd_exp),
      32        9376 :       quantum_number_l_ryd_std(l_ryd_std), quantum_number_j_ryd_exp(j_ryd_exp),
      33        9376 :       quantum_number_j_ryd_std(j_ryd_std), is_j_total_momentum_(is_j_total_momentum),
      34        9376 :       is_calculated_with_mqdt_(is_calculated_with_mqdt),
      35        9376 :       underspecified_channel_contribution(underspecified_channel_contribution), database(database),
      36        9376 :       id_in_database(id_in_database) {}
      37             : 
      38           0 : Database &KetAtom::get_database() const { return database; }
      39             : 
      40        9326 : size_t KetAtom::get_id_in_database() const { return id_in_database; }
      41             : 
      42         251 : std::string KetAtom::get_label() const {
      43         251 :     size_t pos = species.find('_');
      44         251 :     std::string label = (pos != std::string::npos) ? species.substr(0, pos) : species;
      45         251 :     label[0] = static_cast<char>(std::toupper(label[0]));
      46             : 
      47         251 :     if (!is_calculated_with_mqdt_) {
      48         184 :         if (quantum_number_s_exp == 0) {
      49          15 :             label += "_singlet";
      50         169 :         } else if (quantum_number_s_exp == 1) {
      51           2 :             label += "_triplet";
      52         167 :         } 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         251 :     label += ":";
      59             : 
      60         251 :     if (is_calculated_with_mqdt_) {
      61          67 :         label += fmt::format("S={:.1f},nu={:.1f},L={:.1f},", quantum_number_s_exp,
      62         134 :                              quantum_number_nu, quantum_number_l_exp);
      63          67 :         label += this->is_j_total_momentum_ ? "J=" : "F=";
      64             :     } else {
      65         368 :         label += fmt::format("{:d},", quantum_number_n);
      66         184 :         if (quantum_number_l_exp == std::rint(quantum_number_l_exp) &&
      67         184 :             quantum_number_l_exp < quantum_number_l_labels.size()) {
      68         184 :             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         184 :         label += "_";
      73             :     }
      74             : 
      75         251 :     double total_momentum =
      76         251 :         this->is_j_total_momentum_ ? this->quantum_number_j_exp : this->quantum_number_f;
      77         251 :     if (total_momentum == std::rint(total_momentum)) {
      78          22 :         label += fmt::format("{:.0f}", total_momentum);
      79         229 :     } else if (2 * total_momentum == std::rint(2 * total_momentum)) {
      80         458 :         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         251 :     if (this->quantum_number_m == std::rint(this->quantum_number_m)) {
      87          44 :         label += fmt::format(",{:.0f}", this->quantum_number_m);
      88         229 :     } else if (2 * this->quantum_number_m == std::rint(2 * this->quantum_number_m)) {
      89         458 :         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         502 :     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         410 : const std::string &KetAtom::get_species() const { return species; }
     106             : 
     107          47 : int KetAtom::get_quantum_number_n() const { return quantum_number_n; }
     108             : 
     109          21 : 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          63 : double KetAtom::get_quantum_number_l() const { return quantum_number_l_exp; }
     114             : 
     115          15 : double KetAtom::get_quantum_number_s() const { return quantum_number_s_exp; }
     116             : 
     117           7 : double KetAtom::get_quantum_number_j() const { return quantum_number_j_exp; }
     118             : 
     119           4 : double KetAtom::get_quantum_number_l_ryd() const { return quantum_number_l_ryd_exp; }
     120             : 
     121           4 : 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           0 : 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         478 : bool KetAtom::operator==(const KetAtom &other) const {
     144         955 :     return Ket::operator==(other) && species == other.species &&
     145         477 :         quantum_number_n == other.quantum_number_n &&
     146         477 :         quantum_number_nu == other.quantum_number_nu &&
     147         477 :         quantum_number_nui_exp == other.quantum_number_nui_exp &&
     148         477 :         quantum_number_nui_std == other.quantum_number_nui_std &&
     149         477 :         quantum_number_l_exp == other.quantum_number_l_exp &&
     150         477 :         quantum_number_l_std == other.quantum_number_l_std &&
     151         477 :         quantum_number_s_exp == other.quantum_number_s_exp &&
     152         477 :         quantum_number_s_std == other.quantum_number_s_std &&
     153        1432 :         quantum_number_j_exp == other.quantum_number_j_exp &&
     154         955 :         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        9752 : size_t KetAtom::hash::operator()(const KetAtom &k) const {
     160        9752 :     size_t seed = typename Ket::hash()(k);
     161        9752 :     utils::hash_combine(seed, k.species);
     162        9752 :     utils::hash_combine(seed, k.quantum_number_n);
     163        9752 :     utils::hash_combine(seed, k.quantum_number_nu);
     164        9752 :     utils::hash_combine(seed, k.quantum_number_nui_exp);
     165        9752 :     utils::hash_combine(seed, k.quantum_number_nui_std);
     166        9752 :     utils::hash_combine(seed, k.quantum_number_l_exp);
     167        9752 :     utils::hash_combine(seed, k.quantum_number_l_std);
     168        9752 :     utils::hash_combine(seed, k.quantum_number_s_exp);
     169        9752 :     utils::hash_combine(seed, k.quantum_number_s_std);
     170        9752 :     utils::hash_combine(seed, k.quantum_number_j_exp);
     171        9752 :     utils::hash_combine(seed, k.quantum_number_j_std);
     172        9752 :     return seed;
     173             : }
     174             : 
     175             : } // namespace pairinteraction

Generated by: LCOV version 1.16