21#ifndef _libint2_src_lib_libint_soad_fock_h_
22#define _libint2_src_lib_libint_soad_fock_h_
24#include <libint2/atom.h>
25#include <libint2/basis.h>
26#include <libint2/chemistry/sto3g_atomic_density.h>
44 for (
const auto &atom : atoms) {
45 const auto Z = atom.atomic_number;
50 Eigen::MatrixXd D = Eigen::MatrixXd::Zero(nao, nao);
52 for (
const auto &atom : atoms) {
53 const auto Z = atom.atomic_number;
55 for (
const auto &occ : occvec) {
56 D(ao_offset, ao_offset) = occ;
64Eigen::MatrixXd compute_2body_fock_general(
const BasisSet &obs,
65 const Eigen::MatrixXd &D,
67 bool D_is_shelldiagonal,
69 const auto n = obs.nbf();
70 const auto nshells = obs.size();
71 const auto n_D = D_bs.nbf();
72 assert(D.cols() == D.rows() && D.cols() == n_D);
74 Eigen::MatrixXd G = Eigen::MatrixXd ::Zero(n, n);
77 libint2::Engine engine(libint2::Operator::coulomb,
78 std::max(obs.max_nprim(), D_bs.max_nprim()),
79 std::max(obs.max_l(), D_bs.max_l()), 0);
80 engine.set_precision(precision);
81 auto shell2bf = obs.shell2bf();
82 auto shell2bf_D = D_bs.shell2bf();
84 const auto &buf = engine.results();
87 for (
auto s1 = 0l, s1234 = 0l; s1 != nshells; ++s1) {
88 auto bf1_first = shell2bf[s1];
89 auto n1 = obs[s1].size();
91 for (
auto s2 = 0; s2 <= s1; ++s2) {
92 auto bf2_first = shell2bf[s2];
93 auto n2 = obs[s2].size();
95 for (
auto s3 = 0; s3 < D_bs.size(); ++s3) {
96 auto bf3_first = shell2bf_D[s3];
97 auto n3 = D_bs[s3].size();
99 auto s4_begin = D_is_shelldiagonal ? s3 : 0;
100 auto s4_fence = D_is_shelldiagonal ? s3 + 1 : D_bs.size();
102 for (
auto s4 = s4_begin; s4 != s4_fence; ++s4, ++s1234) {
103 auto bf4_first = shell2bf_D[s4];
104 auto n4 = D_bs[s4].size();
108 auto s12_deg = (s1 == s2) ? 1.0 : 2.0;
111 auto s34_deg = (s3 == s4) ? 1.0 : 2.0;
112 auto s1234_deg = s12_deg * s34_deg;
114 engine.compute2<Operator::coulomb, BraKet::xx_xx, 0>(
115 obs[s1], obs[s2], D_bs[s3], D_bs[s4]);
116 const auto *buf_1234 = buf[0];
117 if (buf_1234 !=
nullptr) {
118 for (
auto f1 = 0, f1234 = 0; f1 != n1; ++f1) {
119 const auto bf1 = f1 + bf1_first;
120 for (
auto f2 = 0; f2 != n2; ++f2) {
121 const auto bf2 = f2 + bf2_first;
122 for (
auto f3 = 0; f3 != n3; ++f3) {
123 const auto bf3 = f3 + bf3_first;
124 for (
auto f4 = 0; f4 != n4; ++f4, ++f1234) {
125 const auto bf4 = f4 + bf4_first;
127 const auto value = buf_1234[f1234];
128 const auto value_scal_by_deg = value * s1234_deg;
129 G(bf1, bf2) += 2.0 * D(bf3, bf4) * value_scal_by_deg;
137 engine.compute2<Operator::coulomb, BraKet::xx_xx, 0>(
138 obs[s1], D_bs[s3], obs[s2], D_bs[s4]);
139 const auto *buf_1324 = buf[0];
140 if (buf_1324 ==
nullptr)
143 for (
auto f1 = 0, f1324 = 0; f1 != n1; ++f1) {
144 const auto bf1 = f1 + bf1_first;
145 for (
auto f3 = 0; f3 != n3; ++f3) {
146 const auto bf3 = f3 + bf3_first;
147 for (
auto f2 = 0; f2 != n2; ++f2) {
148 const auto bf2 = f2 + bf2_first;
149 for (
auto f4 = 0; f4 != n4; ++f4, ++f1324) {
150 const auto bf4 = f4 + bf4_first;
152 const auto value = buf_1324[f1324];
153 const auto value_scal_by_deg = value * s12_deg;
154 G(bf1, bf2) -= D(bf3, bf4) * value_scal_by_deg;
165 return 0.5 * (G + G.transpose());
168Eigen::MatrixXd compute_soad_fock(
const BasisSet &obs,
const BasisSet &minbs,
169 const std::vector<Atom> &atoms) {
173 auto F = compute_2body_fock_general(
174 obs, D, minbs,
true ,
175 std::numeric_limits<double>::epsilon()
Defaults definitions for various parameters assumed by Libint.
Definition algebra.cc:24
Eigen::MatrixXd compute_soad(const std::vector< Atom > &atoms)
computes Superposition-Of-Atomic-Densities guess for the molecular 1-RDM
Definition soad_fock.h:41
const std::vector< Real > & sto3g_ao_occupation_vector(size_t Z)
computes average orbital occupancies in the ground state of a neutral atoms
Definition sto3g_atomic_density.h:86
size_t sto3g_num_ao(size_t Z)
Definition sto3g_atomic_density.h:57