10#include <spdlog/spdlog.h>
16int main(
int argc,
char **argv) {
23 bool download_missing =
false;
25 for (
int i = 1; i < argc; ++i) {
40 .restrict_quantum_number_n(58, 62)
41 .restrict_quantum_number_l(0, 2)
43 SPDLOG_INFO(
"Number of single-atom basis states: {}", basis->get_number_of_states());
60 .restrict_energy(min_energy, max_energy)
61 .restrict_quantum_number_m(1, 1)
63 SPDLOG_INFO(
"Number of two-atom basis states: {}", basis_pair->get_number_of_states());
65 std::vector<pairinteraction::SystemPair<double>> system_pairs;
66 system_pairs.reserve(5);
67 for (
int i = 1; i < 6; ++i) {
70 system_pairs.push_back(std::move(system));
78 for (
auto &system : system_pairs) {
84 std::vector<std::string> kets;
87 basis_pair->get_number_of_states() *
88 basis_pair->get_number_of_states());
91 kets.reserve(basis->get_number_of_states());
92 for (
const auto &ket : *basis_pair) {
95 kets.push_back(ss.str());
98 for (Eigen::Index i = 0; i < static_cast<Eigen::Index>(system_pairs.size()); ++i) {
99 eigenenergies.row(i) = system_pairs[i].get_eigenenergies() *
HARTREE_IN_GHZ;
102 system_pairs[i].get_eigenbasis()->get_coefficients().toDense().transpose();
103 eigenstates.row(i) = Eigen::Map<Eigen::VectorXd>(tmp.data(), tmp.size());
105 overlaps.row(i) = system_pairs[i].get_eigenbasis()->get_overlaps(ket, ket);
113 data_dir /
"reference_pair_potential/kets.txt";
114 SPDLOG_INFO(
"Reference kets: {}", reference_kets_file.string());
116 std::vector<std::string> reference_kets;
118 std::ifstream stream(reference_kets_file);
120 SPDLOG_ERROR(
"Could not open reference kets file");
123 reference_kets.reserve(basis_pair->get_number_of_states());
124 while (std::getline(stream, line)) {
125 reference_kets.push_back(line);
128 if (kets.size() != reference_kets.size()) {
129 SPDLOG_ERROR(
"Number of kets does not match reference data");
131 }
else if (kets != reference_kets) {
132 for (
size_t i = 0; i < kets.size(); ++i) {
133 SPDLOG_DEBUG(
"Ket: {} vs {}, match: {}", kets[i], reference_kets[i],
134 kets[i] == reference_kets[i]);
136 SPDLOG_ERROR(
"Kets do not match reference data");
143 data_dir /
"reference_pair_potential/eigenenergies.txt";
144 SPDLOG_INFO(
"Reference eigenenergies: {}", reference_eigenenergies_file.string());
146 Eigen::MatrixXd reference_eigenenergies(system_pairs.size(),
147 basis_pair->get_number_of_states());
148 stream = std::ifstream(reference_eigenenergies_file);
150 SPDLOG_ERROR(
"Could not open reference eigenenergies file");
153 for (Eigen::Index i = 0; i < static_cast<Eigen::Index>(system_pairs.size()); ++i) {
154 for (Eigen::Index j = 0;
155 j < static_cast<Eigen::Index>(basis_pair->get_number_of_states()); ++j) {
156 stream >> reference_eigenenergies(i, j);
160 if ((eigenenergies - reference_eigenenergies).array().abs().maxCoeff() >
162 for (Eigen::Index i = 0; i < eigenenergies.size(); ++i) {
163 SPDLOG_DEBUG(
"Eigenenergy: {} vs {}, delta: {}", eigenenergies(i),
164 reference_eigenenergies(i),
165 std::abs(eigenenergies(i) - reference_eigenenergies(i)));
167 SPDLOG_ERROR(
"Eigenenergies do not match reference data");
174 data_dir /
"reference_pair_potential/overlaps.txt";
175 SPDLOG_INFO(
"Reference overlaps: {}", reference_overlaps_file.string());
177 Eigen::MatrixXd reference_overlaps(system_pairs.size(), basis_pair->get_number_of_states());
178 stream = std::ifstream(reference_overlaps_file);
180 SPDLOG_ERROR(
"Could not open reference overlap file");
183 for (Eigen::Index i = 0; i < static_cast<Eigen::Index>(system_pairs.size()); ++i) {
184 for (Eigen::Index j = 0;
185 j < static_cast<Eigen::Index>(basis_pair->get_number_of_states()); ++j) {
186 stream >> reference_overlaps(i, j);
190 if ((overlaps - reference_overlaps).array().abs().maxCoeff() > 1e-5) {
191 for (Eigen::Index i = 0; i < overlaps.size(); ++i) {
192 SPDLOG_DEBUG(
"Overlap: {} vs {}, delta: {}", overlaps(i), reference_overlaps(i),
193 std::abs(overlaps(i) - reference_overlaps(i)));
195 SPDLOG_ERROR(
"Overlaps do not match reference data");
203 Eigen::VectorXd cumulative_norm =
204 (eigenstates.adjoint().array() * eigenstates.transpose().array()).colwise().sum();
205 if (!cumulative_norm.isApprox(Eigen::VectorXd::Constant(5, 19), 1e-5)) {
206 SPDLOG_ERROR(
"Eigenvectors are not orthonormal.");
210 return success ? 0 : 1;
Builder class for creating BasisAtom objects.
BasisAtomCreator< Scalar > & set_species(const std::string &value)
BasisPairCreator< Scalar > & add(const SystemAtom< Scalar > &system_atom)
Builder class for creating KetAtom objects.
KetAtomCreator & set_quantum_number_n(int value)
std::shared_ptr< const KetAtom > create(Database &database) const
KetAtomCreator & set_quantum_number_l(double value)
KetAtomCreator & set_species(const std::string &value)
KetAtomCreator & set_quantum_number_m(double value)
Type & set_distance_vector(const std::array< real_t, 3 > &vector)
Sorting get_sorter(const std::vector< TransformationType > &labels) const override
System< Derived > & transform(const Transformation< scalar_t > &transformation)
Matrix< Type, Dynamic, Dynamic > MatrixX
bool parse_data_dir(int &i, int argc, char **const argv, std::filesystem::path &data_dir)
bool parse_database_dir(int &i, int argc, char **const argv, std::filesystem::path &database_dir)
bool parse_download_missing(int &i, int argc, char **const argv, bool &download_missing)
void diagonalize(std::initializer_list< std::reference_wrapper< Derived > > systems, const DiagonalizerInterface< typename Derived::scalar_t > &diagonalizer, std::optional< typename Derived::real_t > min_eigenenergy={}, std::optional< typename Derived::real_t > max_eigenenergy={}, double rtol=1e-6)
constexpr double HARTREE_IN_GHZ
int main(int argc, char **argv)
constexpr double UM_IN_ATOMIC_UNITS