Program Listing for File ri_utils.hpp
↰ Return to documentation for file (src/three_electron/ri_utils.hpp)
//
// Created by Zack Williams on 25/03/2024.
//
#ifndef RI_UTILS_HPP
#define RI_UTILS_HPP
#include "utils/linalg.hpp"
namespace uw12::three_el::ri {
struct ABSProjectors {
linalg::Mat s_inv_ri_ri;
linalg::Mat s_inv_ri_ao;
linalg::Mat s_inv_ao_ri;
linalg::Mat s_inv_ao_ao;
};
inline ABSProjectors calculate_abs_projectors(
const linalg::Mat& overlap_matrix,
const size_t n_ao,
const size_t n_ri,
const double eigen_ld_threshold = 1e-8,
const double linear_dependency_threshold = 1e-6
) {
using linalg::head_rows;
using linalg::tail_rows;
using linalg::transpose;
const auto [s_vals, s_vecs] = linalg::eigen_decomposition(
overlap_matrix, linear_dependency_threshold, eigen_ld_threshold
);
if (linalg::n_rows(s_vecs) != n_ao + n_ri) {
throw std::runtime_error("Total number of basis functions is inconsistent");
}
assert(linalg::n_cols(s_vecs) == linalg::n_elem(s_vals));
const linalg::Mat inv = linalg::inv_sym_pd(linalg::diagmat(s_vals));
return {
tail_rows(s_vecs, n_ri) * inv * transpose(tail_rows(s_vecs, n_ri)),
tail_rows(s_vecs, n_ri) * inv * transpose(head_rows(s_vecs, n_ao)),
head_rows(s_vecs, n_ao) * inv * transpose(tail_rows(s_vecs, n_ri)),
head_rows(s_vecs, n_ao) * inv * transpose(head_rows(s_vecs, n_ao))
};
}
} // namespace uw12::three_el::ri
#endif // RI_UTILS_HPP