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 2630742 : 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 2630742 : : Ket(energy), quantum_number_m(calculate_quantum_number_m(atomic_indices, atomic_bases)), 19 5261484 : atomic_indices(atomic_indices), atomic_bases(atomic_bases) { 20 2630742 : 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 2630742 : } 25 : 26 : template <typename Scalar> 27 2630742 : bool KetPair<Scalar>::has_quantum_number_m() const { 28 2630742 : return quantum_number_m != std::numeric_limits<real_t>::max(); 29 : } 30 : 31 : template <typename Scalar> 32 2762470 : typename KetPair<Scalar>::real_t KetPair<Scalar>::get_quantum_number_m() const { 33 2762470 : return quantum_number_m; 34 : } 35 : 36 : template <typename Scalar> 37 396 : std::vector<std::shared_ptr<const BasisAtom<Scalar>>> KetPair<Scalar>::get_atomic_states() const { 38 396 : std::vector<std::shared_ptr<const BasisAtom<Scalar>>> atomic_states; 39 396 : atomic_states.reserve(atomic_indices.size()); 40 1188 : for (size_t atom_index = 0; atom_index < atomic_indices.size(); ++atom_index) { 41 792 : atomic_states.push_back(atomic_bases[atom_index]->get_state(atomic_indices[atom_index])); 42 : } 43 396 : return atomic_states; 44 0 : } 45 : 46 : template <typename Scalar> 47 302 : bool KetPair<Scalar>::operator==(const KetPair<Scalar> &other) const { 48 602 : return Ket::operator==(other) && quantum_number_m == other.quantum_number_m && 49 602 : atomic_indices == other.atomic_indices && atomic_bases == other.atomic_bases; 50 : } 51 : 52 : template <typename Scalar> 53 2 : bool KetPair<Scalar>::operator!=(const KetPair<Scalar> &other) const { 54 2 : return !(*this == other); 55 : } 56 : 57 : template <typename Scalar> 58 224 : size_t KetPair<Scalar>::hash::operator()(const KetPair<Scalar> &k) const { 59 224 : size_t seed = typename Ket::hash()(k); 60 224 : utils::hash_combine(seed, k.quantum_number_m); 61 672 : for (const auto &index : k.atomic_indices) { 62 448 : utils::hash_combine(seed, index); 63 : } 64 672 : for (const auto &basis : k.atomic_bases) { 65 448 : utils::hash_combine(seed, reinterpret_cast<std::uintptr_t>(basis.get())); 66 : } 67 224 : return seed; 68 : } 69 : 70 : template <typename Scalar> 71 2630742 : typename KetPair<Scalar>::real_t KetPair<Scalar>::calculate_quantum_number_m( 72 : const std::vector<size_t> &indices, 73 : const std::vector<std::shared_ptr<const BasisAtom<Scalar>>> &bases) { 74 7892226 : for (const auto &basis : bases) { 75 5261484 : if (!basis->has_quantum_number_m()) { 76 0 : return std::numeric_limits<real_t>::max(); 77 : } 78 : } 79 2630742 : real_t total_quantum_number_m = 0; 80 7892226 : for (size_t i = 0; i < indices.size(); ++i) { 81 5261484 : total_quantum_number_m += bases[i]->get_quantum_number_m(indices[i]); 82 : } 83 2630742 : return total_quantum_number_m; 84 : } 85 : 86 : // Explicit instantiations 87 : template class KetPair<double>; 88 : template class KetPair<std::complex<double>>; 89 : } // namespace pairinteraction