LCOV - code coverage report
Current view: top level - src/ket - KetPair.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 48 53 90.6 %
Date: 2026-06-19 12:50:25 Functions: 16 20 80.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/KetPair.hpp"
       5             : 
       6             : #include "pairinteraction/basis/BasisAtom.hpp"
       7             : #include "pairinteraction/ket/KetAtom.hpp"
       8             : #include "pairinteraction/utils/hash.hpp"
       9             : 
      10             : #include <limits>
      11             : #include <string>
      12             : 
      13             : namespace pairinteraction {
      14             : template <typename Scalar>
      15     2900412 : KetPair<Scalar>::KetPair(
      16             :     Private /*unused*/, std::initializer_list<size_t> atomic_indices,
      17             :     std::initializer_list<std::shared_ptr<const BasisAtom<Scalar>>> atomic_bases, real_t energy)
      18     2900412 :     : Ket(energy), quantum_number_m(calculate_quantum_number_m(atomic_indices, atomic_bases)),
      19     5800824 :       atomic_indices(atomic_indices), atomic_bases(atomic_bases) {
      20     2900412 :     if (atomic_indices.size() != atomic_bases.size()) {
      21           0 :         throw std::invalid_argument(
      22             :             "The number of atomic indices, and atomic bases must be the same.");
      23             :     }
      24     2900412 : }
      25             : 
      26             : template <typename Scalar>
      27     2900412 : bool KetPair<Scalar>::has_quantum_number_m() const {
      28     2900412 :     return quantum_number_m != std::numeric_limits<real_t>::max();
      29             : }
      30             : 
      31             : template <typename Scalar>
      32     3033000 : typename KetPair<Scalar>::real_t KetPair<Scalar>::get_quantum_number_m() const {
      33     3033000 :     return quantum_number_m;
      34             : }
      35             : 
      36             : template <typename Scalar>
      37         118 : std::string KetPair<Scalar>::get_label() const {
      38         118 :     constexpr real_t numerical_precision = 100 * std::numeric_limits<real_t>::epsilon();
      39             : 
      40         118 :     std::string label;
      41         118 :     std::string separator;
      42         354 :     for (size_t atom_index = 0; atom_index < atomic_indices.size(); ++atom_index) {
      43         236 :         const auto &basis = atomic_bases[atom_index];
      44         236 :         size_t idx = atomic_indices[atom_index];
      45             :         Scalar coefficient =
      46         236 :             basis->get_coefficients().coeff(basis->get_corresponding_ket_index(idx), idx);
      47         236 :         std::string optional_tilde = (std::abs(coefficient - 1.0) > numerical_precision) ? "~" : "";
      48         236 :         label += separator + optional_tilde + basis->get_corresponding_ket(idx)->get_label();
      49         236 :         separator = "; ";
      50             :     }
      51         236 :     return label;
      52         118 : }
      53             : 
      54             : template <typename Scalar>
      55             : std::shared_ptr<KetPair<Scalar>>
      56           0 : KetPair<Scalar>::get_ket_for_different_quantum_number_m(real_t /*new_quantum_number_m*/) const {
      57             :     // If we use symmetrized states so that the quantum_number_f is the total
      58             :     // angular quantum number, the quantum_number_m is the magnetic quantum number
      59             :     // corresponding to the total angular quantum number and we can implement this
      60             :     // method.
      61           0 :     throw std::runtime_error("Not implemented.");
      62             : }
      63             : 
      64             : template <typename Scalar>
      65         270 : std::vector<std::shared_ptr<const BasisAtom<Scalar>>> KetPair<Scalar>::get_atomic_states() const {
      66         270 :     std::vector<std::shared_ptr<const BasisAtom<Scalar>>> atomic_states;
      67         270 :     atomic_states.reserve(atomic_indices.size());
      68         810 :     for (size_t atom_index = 0; atom_index < atomic_indices.size(); ++atom_index) {
      69         540 :         atomic_states.push_back(atomic_bases[atom_index]->get_state(atomic_indices[atom_index]));
      70             :     }
      71         270 :     return atomic_states;
      72           0 : }
      73             : 
      74             : template <typename Scalar>
      75           6 : bool KetPair<Scalar>::operator==(const KetPair<Scalar> &other) const {
      76          10 :     return Ket::operator==(other) && quantum_number_m == other.quantum_number_m &&
      77          10 :         atomic_indices == other.atomic_indices && atomic_bases == other.atomic_bases;
      78             : }
      79             : 
      80             : template <typename Scalar>
      81           4 : bool KetPair<Scalar>::operator!=(const KetPair<Scalar> &other) const {
      82           4 :     return !(*this == other);
      83             : }
      84             : 
      85             : template <typename Scalar>
      86     2833091 : size_t KetPair<Scalar>::hash::operator()(const KetPair<Scalar> &k) const {
      87     2833091 :     size_t seed = typename Ket::hash()(k);
      88     2833091 :     utils::hash_combine(seed, k.quantum_number_m);
      89     8499273 :     for (const auto &index : k.atomic_indices) {
      90     5666182 :         utils::hash_combine(seed, index);
      91             :     }
      92     8499273 :     for (const auto &basis : k.atomic_bases) {
      93     5666182 :         utils::hash_combine(seed, reinterpret_cast<std::uintptr_t>(basis.get()));
      94             :     }
      95     2833091 :     return seed;
      96             : }
      97             : 
      98             : template <typename Scalar>
      99     2900412 : typename KetPair<Scalar>::real_t KetPair<Scalar>::calculate_quantum_number_m(
     100             :     const std::vector<size_t> &indices,
     101             :     const std::vector<std::shared_ptr<const BasisAtom<Scalar>>> &bases) {
     102     8701236 :     for (const auto &basis : bases) {
     103     5800824 :         if (!basis->has_quantum_number_m()) {
     104           0 :             return std::numeric_limits<real_t>::max();
     105             :         }
     106             :     }
     107     2900412 :     real_t total_quantum_number_m = 0;
     108     8701236 :     for (size_t i = 0; i < indices.size(); ++i) {
     109     5800824 :         total_quantum_number_m += bases[i]->get_quantum_number_m(indices[i]);
     110             :     }
     111     2900412 :     return total_quantum_number_m;
     112             : }
     113             : 
     114             : // Explicit instantiations
     115             : template class KetPair<double>;
     116             : template class KetPair<std::complex<double>>;
     117             : } // namespace pairinteraction

Generated by: LCOV version 1.16