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

Generated by: LCOV version 1.16