LCOV - code coverage report
Current view: top level - src/ket - KetAtom.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 74 101 73.3 %
Date: 2025-05-02 21:49:25 Functions: 11 26 42.3 %

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

Generated by: LCOV version 1.16