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 355 : BasisAtomCreator<Scalar> &BasisAtomCreator<Scalar>::set_species(const std::string &value) { 13 355 : species.emplace(value); 14 355 : return *this; 15 : } 16 : 17 : template <typename Scalar> 18 43 : BasisAtomCreator<Scalar> &BasisAtomCreator<Scalar>::restrict_energy(real_t min, real_t max) { 19 43 : range_energy = {min, max}; 20 43 : return *this; 21 : } 22 : 23 : template <typename Scalar> 24 : BasisAtomCreator<Scalar> & 25 740 : BasisAtomCreator<Scalar>::restrict_quantum_number(const std::string &name, real_t min, real_t max) { 26 838 : if ((name == "f" || name == "m") && 27 98 : (2 * min != std::rint(2 * min) || 2 * max != std::rint(2 * max))) { 28 0 : throw std::invalid_argument("Quantum number " + name + 29 : " must be an integer or half-integer."); 30 : } 31 740 : if (name == "parity" && ((min != 1 && min != -1) || (max != 1 && max != -1))) { 32 0 : throw std::invalid_argument("The parity must be +1 or -1."); 33 : } 34 740 : quantum_number_ranges[name] = {min, max}; 35 740 : return *this; 36 : } 37 : 38 : template <typename Scalar> 39 : BasisAtomCreator<Scalar> & 40 324 : BasisAtomCreator<Scalar>::set_quantum_number_standard_deviation_factor(real_t value) { 41 324 : if (value < 0) { 42 0 : throw std::invalid_argument( 43 : "The quantum number standard deviation factor must be non-negative."); 44 : } 45 324 : quantum_number_standard_deviation_factor = value; 46 324 : return *this; 47 : } 48 : 49 : template <typename Scalar> 50 : BasisAtomCreator<Scalar> & 51 795 : BasisAtomCreator<Scalar>::add_ket(const std::shared_ptr<const ket_t> &ket) { 52 840 : if (additional_ket_species.has_value() && 53 45 : additional_ket_species.value() != ket->get_species()) { 54 0 : throw std::invalid_argument("Species mismatch."); 55 : } 56 795 : additional_ket_species.emplace(ket->get_species()); 57 795 : additional_ket_ids.push_back(ket->get_id_in_database()); 58 795 : return *this; 59 : } 60 : 61 : template <typename Scalar> 62 : std::shared_ptr<const BasisAtom<Scalar>> 63 1022 : BasisAtomCreator<Scalar>::create(Database &database) const { 64 : 65 1101 : if (species.has_value() && additional_ket_species.has_value() && 66 79 : species.value() != additional_ket_species.value()) { 67 0 : throw std::invalid_argument("Species mismatch."); 68 : } 69 : 70 1022 : std::string extracted_species; 71 1022 : if (species.has_value()) { 72 351 : extracted_species = species.value(); 73 671 : } else if (additional_ket_species.has_value()) { 74 671 : extracted_species = additional_ket_species.value(); 75 : } else { 76 0 : throw std::runtime_error("Species not set."); 77 : } 78 : 79 1022 : AtomDescriptionByRanges description{range_energy, quantum_number_ranges, 80 1022 : quantum_number_standard_deviation_factor}; 81 : 82 2044 : return database.get_basis<Scalar>(extracted_species, description, additional_ket_ids); 83 1022 : } 84 : 85 : // Explicit instantiations 86 : template class BasisAtomCreator<double>; 87 : template class BasisAtomCreator<std::complex<double>>; 88 : } // namespace pairinteraction