21#ifndef _libint2_src_lib_libint_dfbs_generator_h_
22#define _libint2_src_lib_libint_dfbs_generator_h_
25#include <libint2/atom.h>
26#include <libint2/basis.h>
27#include <libint2/boys.h>
28#include <libint2/pivoted_cholesky.h>
31#include <Eigen/Eigenvalues>
42inline std::vector<Shell>
uncontract(
const std::vector<Shell> &shells) {
43 std::vector<Shell> primitive_shells;
44 for (
const auto &contracted_shell : shells) {
45 for (
size_t p = 0; p < contracted_shell.nprim(); p++) {
46 const auto prim_shell = contracted_shell.extract_primitive(p,
true);
49 if (std::find(primitive_shells.begin(), primitive_shells.end(),
50 prim_shell) == primitive_shells.end())
51 primitive_shells.emplace_back(std::move(prim_shell));
54 return primitive_shells;
70 const auto alpha1 = shell1.
alpha[0];
71 const auto alpha2 = shell2.
alpha[0];
72 const auto l1 = shell1.
contr[0].l;
73 const auto l2 = shell2.
contr[0].l;
74 const auto prefactor =
78 return prefactor * (alpha1 + alpha2);
89 const std::vector<Shell> &primitive_shells) {
91 for (
size_t i = 0; i < primitive_shells.size(); ++i) {
92 for (
size_t j = 0; j <= i; ++j) {
93 const auto li = primitive_shells[i].contr[0].l;
94 const auto lj = primitive_shells[j].contr[0].l;
95 for (
auto L = std::abs(li - lj); L <= li + lj; L++) {
96 const auto alpha = libint2::svector<double>(
97 {
alpha_eff(primitive_shells[i], primitive_shells[j], L)});
98 libint2::svector<Shell::Contraction> contr_;
102 contr1.coeff = {1.0};
103 contr_.push_back(contr1);
104 assert(primitive_shells[i].O == primitive_shells[j].O);
105 const auto shell =
Shell(alpha, contr_, primitive_shells[i].O);
117 const std::vector<libint2::Shell> &shells) {
118 std::vector<size_t> result;
119 result.reserve(shells.size());
122 for (
auto &&shell : shells) {
135 const std::vector<Shell> &shells) {
136 const auto n = nbf(shells);
137 Eigen::MatrixXd result = Eigen::MatrixXd::Zero(n, n);
138 using libint2::Engine;
139 const auto oper = libint2::Operator::coulomb;
140 const auto braket = libint2::BraKet::xs_xs;
141 Engine engine(oper, max_nprim(shells), max_l(shells), 0,
142 std::numeric_limits<scalar_type>::epsilon(),
146 const auto &buf = engine.results();
147 for (
size_t s1 = 0; s1 != shells.size(); ++s1) {
148 auto bf1 = shell2bf[s1];
149 auto n1 = shells[s1].size();
150 for (
size_t s2 = 0; s2 <= s1; ++s2) {
151 auto bf2 = shell2bf[s2];
152 auto n2 = shells[s2].size();
153 engine.compute(shells[s1], shells[s2]);
154 Eigen::Map<const Eigen::MatrixXd> buf_mat(buf[0], n1, n2);
155 result.block(bf1, bf2, n1, n2) = buf_mat;
156 if (s1 != s2) result.block(bf2, bf1, n2, n1) = buf_mat.transpose();
167 const std::vector<Shell> &shells) {
168 int lmax = max_l(shells);
169 std::vector<std::vector<Shell>> sorted_shells;
170 sorted_shells.resize(lmax + 1);
171 for (
auto &&shell : shells) {
172 auto l = shell.contr[0].l;
173 sorted_shells[l].push_back(shell);
175 return sorted_shells;
190 const std::vector<Shell> &shells,
const double cholesky_threshold) {
191 const auto n = shells.size();
194 const auto L = shells[0].contr[0].l;
195 const auto nbf = libint2::nbf(
197 for (
size_t i = 0; i < n; ++i) {
198 for (
size_t j = 0; j < 2 * L + 1;
201 shell_indices.push_back(i);
203 assert(shell_indices.size() == nbf);
205 std::vector<size_t> pivot(nbf);
206 for (
auto i = 0; i < nbf; ++i) {
212 Eigen::MatrixXd C_off_diag = C;
213 auto col_sum = C_off_diag.colwise().sum();
215 std::sort(pivot.begin(), pivot.end(), [&col_sum](
size_t i1,
size_t i2) {
216 return col_sum[i1] < col_sum[i2];
221 std::vector<Shell> reduced_shells;
222 for (
size_t i = 0; i < reduced_pivots.size(); ++i) {
224 if (std::find(reduced_shells.begin(), reduced_shells.end(),
225 shells[shell_indices[reduced_pivots[i]]]) ==
226 reduced_shells.end())
227 reduced_shells.push_back(shells[shell_indices[reduced_pivots[i]]]);
229 return reduced_shells;
251 const double cholesky_threshold = 1e-7) {
253 const auto atom_bs = BasisSet(obs_name, {atom});
254 const auto obs_shells = atom_bs.shells();
259 cholesky_threshold_ = cholesky_threshold;
268 const double cholesky_threshold = 1e-7) {
271 cholesky_threshold_ = cholesky_threshold;
286 if (reduced_shells_computed_)
287 return reduced_shells_;
289 const auto candidate_splitted_in_L =
291 for (
size_t i = 0; i < candidate_splitted_in_L.size(); ++i) {
292 std::vector<Shell> reduced_shells_L;
293 if (candidate_splitted_in_L[i].size() > 1)
295 candidate_splitted_in_L[i], cholesky_threshold_);
297 reduced_shells_L = candidate_splitted_in_L[i];
298 reduced_shells_.insert(reduced_shells_.end(), reduced_shells_L.begin(),
299 reduced_shells_L.end());
301 reduced_shells_computed_ =
true;
303 return reduced_shells_;
313 double cholesky_threshold_;
314 std::vector<Shell> candidate_shells_;
315 std::vector<Shell> reduced_shells_;
316 bool reduced_shells_computed_ =
false;
This class produces density fitting basis sets for an atom from products of AO basis functions and el...
Definition dfbs_generator.h:238
std::vector< Shell > reduced_shells()
returns a set of shells reduced via pivoted Cholesky decomposition of the Coulomb matrix of the produ...
Definition dfbs_generator.h:285
std::vector< Shell > candidate_shells()
returns the candidate shells (full set of product functions)
Definition dfbs_generator.h:279
const BasisSet reduced_basis()
returns a BasisSet of shells reduced via pivoted Cholesky decomposition of the Coulomb matrix of the ...
Definition dfbs_generator.h:310
DFBasisSetGenerator(std::string obs_name, const Atom &atom, const double cholesky_threshold=1e-7)
constructor for DFBasisSetGenerator class, generates density fitting basis set from products of AO ba...
Definition dfbs_generator.h:250
DFBasisSetGenerator(const std::vector< Shell > &shells, const double cholesky_threshold=1e-7)
constructor for DFBasisSetGenerator class, generates density fitting basis set from products of AO sh...
Definition dfbs_generator.h:267
std::vector< Shell > uncontract(const std::vector< Shell > &shells)
Uncontracts a set of shells.
Definition dfbs_generator.h:42
double alpha_eff(const Shell &shell1, const Shell &shell2, const int L)
Computes an effective exponent for a product of two primitive gaussians as as described in J.
Definition dfbs_generator.h:69
std::vector< Shell > pivoted_cholesky_in_L(const std::vector< Shell > &shells, const double cholesky_threshold)
Computes the reduced set of product functions via pivoted Cholesky decomposition as described in J.
Definition dfbs_generator.h:189
std::vector< size_t > map_shell_to_basis_function(const std::vector< libint2::Shell > &shells)
returns a hash map of shell indices to basis function indices
Definition dfbs_generator.h:116
double gamma_function(const double x)
returns
Definition dfbs_generator.h:58
std::vector< std::vector< Shell > > split_by_L(const std::vector< Shell > &shells)
Splits a set of shells by angular momentum.
Definition dfbs_generator.h:166
std::vector< Shell > product_functions(const std::vector< Shell > &primitive_shells)
Creates a set of product functions from a set of primitive shells.
Definition dfbs_generator.h:88
Eigen::MatrixXd compute_coulomb_matrix(const std::vector< Shell > &shells)
Computes the Coulomb matrix for a set of shells.
Definition dfbs_generator.h:134
Defaults definitions for various parameters assumed by Libint.
Definition algebra.cc:24
@ Conservative
conservative screening:
std::vector< size_t > pivoted_cholesky(const Eigen::MatrixXd &A, const double tolerance, const std::vector< size_t > &pivot)
computes the pivoted Cholesky decomposition of a symmetric positive definite matrix
Definition pivoted_cholesky.h:36
__libint2_engine_inline libint2::any default_params(const Operator &oper)
the runtime version of operator_traits<oper>::default_params()
Definition engine.impl.h:116
contracted Gaussian = angular momentum + sph/cart flag + contraction coefficients
Definition shell.h:725
generally-contracted Solid-Harmonic/Cartesion Gaussian Shell
Definition shell.h:720
svector< Contraction > contr
contractions
Definition shell.h:742
svector< real_t > alpha
exponents
Definition shell.h:741