Line data Source code
1 : // SPDX-FileCopyrightText: 2024 PairInteraction Developers 2 : // SPDX-License-Identifier: LGPL-3.0-or-later 3 : 4 : #include "pairinteraction/basis/BasisAtomCreator.hpp" 5 : 6 : #include "pairinteraction/database/AtomDescriptionByRanges.hpp" 7 : #include "pairinteraction/database/Database.hpp" 8 : #include "pairinteraction/ket/KetAtom.hpp" 9 : 10 : namespace pairinteraction { 11 : template <typename Scalar> 12 1666 : BasisAtomCreator<Scalar>::BasisAtomCreator(Database &database) : database(database) {} 13 : 14 : template <typename Scalar> 15 425 : BasisAtomCreator<Scalar> &BasisAtomCreator<Scalar>::set_species(const std::string &value) { 16 425 : species.emplace(value); 17 425 : return *this; 18 : } 19 : 20 : template <typename Scalar> 21 57 : BasisAtomCreator<Scalar> &BasisAtomCreator<Scalar>::restrict_energy(real_t min, real_t max) { 22 57 : range_energy = {min, max}; 23 57 : return *this; 24 : } 25 : 26 : template <typename Scalar> 27 : BasisAtomCreator<Scalar> & 28 952 : BasisAtomCreator<Scalar>::restrict_quantum_number(const std::string &name, real_t min, real_t max) { 29 1077 : if ((name == "f" || name == "m") && 30 125 : (2 * min != std::rint(2 * min) || 2 * max != std::rint(2 * max))) { 31 0 : throw std::invalid_argument("Quantum number " + name + 32 : " must be an integer or half-integer."); 33 : } 34 952 : if (name == "parity" && ((min != 1 && min != -1) || (max != 1 && max != -1))) { 35 0 : throw std::invalid_argument("The parity must be +1 or -1."); 36 : } 37 952 : quantum_number_ranges[name] = {min, max}; 38 952 : return *this; 39 : } 40 : 41 : template <typename Scalar> 42 : BasisAtomCreator<Scalar> & 43 379 : BasisAtomCreator<Scalar>::set_quantum_number_standard_deviation_factor(real_t value) { 44 379 : if (value < 0) { 45 0 : throw std::invalid_argument( 46 : "The quantum number standard deviation factor must be non-negative."); 47 : } 48 379 : quantum_number_standard_deviation_factor = value; 49 379 : return *this; 50 : } 51 : 52 : template <typename Scalar> 53 : BasisAtomCreator<Scalar> & 54 2206 : BasisAtomCreator<Scalar>::add_ket(const std::shared_ptr<const ket_t> &ket) { 55 3091 : if (additional_ket_species.has_value() && 56 885 : additional_ket_species.value() != ket->get_species()) { 57 0 : throw std::invalid_argument("Species mismatch."); 58 : } 59 2206 : additional_ket_species.emplace(ket->get_species()); 60 2206 : additional_ket_ids.push_back(ket->get_id_in_database()); 61 2206 : return *this; 62 : } 63 : 64 : template <typename Scalar> 65 1662 : std::shared_ptr<const BasisAtom<Scalar>> BasisAtomCreator<Scalar>::create() const { 66 : 67 1742 : if (species.has_value() && additional_ket_species.has_value() && 68 80 : species.value() != additional_ket_species.value()) { 69 0 : throw std::invalid_argument("Species mismatch."); 70 : } 71 : 72 1662 : std::string extracted_species; 73 1662 : if (species.has_value()) { 74 421 : extracted_species = species.value(); 75 1241 : } else if (additional_ket_species.has_value()) { 76 1241 : extracted_species = additional_ket_species.value(); 77 : } else { 78 0 : throw std::runtime_error("Species not set."); 79 : } 80 : 81 1662 : AtomDescriptionByRanges description{range_energy, quantum_number_ranges, 82 1662 : quantum_number_standard_deviation_factor}; 83 : 84 3324 : return database.get_basis<Scalar>(extracted_species, description, additional_ket_ids); 85 1662 : } 86 : 87 : // Explicit instantiations 88 : template class BasisAtomCreator<double>; 89 : template class BasisAtomCreator<std::complex<double>>; 90 : } // namespace pairinteraction