39 const Eigen::MatrixXd& density);
43 const Eigen::MatrixXd& occ_mo_coeffs);
52 Eigen::MatrixXd deriv = Eigen::MatrixXd::Zero(natoms, 3);
58 for (
Index a = 0; a < natoms; ++a) {
59 double Za =
static_cast<double>(mol[a].getNuccharge());
60 const Eigen::Vector3d& Ra = mol[a].
getPos();
61 Eigen::Vector3d sum = Eigen::Vector3d::Zero();
62 for (
Index b = 0; b < natoms; ++b) {
66 double Zb =
static_cast<double>(mol[b].getNuccharge());
67 const Eigen::Vector3d& Rb = mol[b].
getPos();
68 Eigen::Vector3d Rab_vec = Ra - Rb;
69 double Rab = Rab_vec.norm();
70 sum += Za * Zb * Rab_vec / (Rab * Rab * Rab);
72 deriv.row(a) = -sum.transpose();
84 std::vector<Eigen::MatrixXd> tensor =
86 Eigen::VectorXd d(n_aux_bf);
87 for (
Index p = 0; p < n_aux_bf; ++p) {
88 d(p) = (density.array() * tensor[p].array()).sum();
95 aocoulomb.
Fill(auxbasis);
96 const Eigen::MatrixXd&
V = aocoulomb.
Matrix();
99 Eigen::VectorXd c = V_chol.
ok() ? Eigen::VectorXd(V_chol.
Solve(d))
100 : Eigen::VectorXd(
V.ldlt().solve(d));
105 std::vector<Eigen::MatrixXd> ddP_dR =
107 std::vector<AOMatrixDerivative> dV =
113 Eigen::MatrixXd grad = Eigen::MatrixXd::Zero(natoms, 3);
114 for (
Index a = 0; a < natoms; ++a) {
115 for (
Index xyz = 0; xyz < 3; ++xyz) {
116 double term1 = ddP_dR[a].row(xyz).dot(c);
117 double term2 = 0.5 * c.dot(dV[a][xyz] * c);
118 grad(a, xyz) = term1 - term2;
129 Index nocc = occ_mo_coeffs.cols();
131 std::vector<Eigen::MatrixXd> tensor =
135 aocoulomb.
Fill(auxbasis);
136 const Eigen::MatrixXd&
V = aocoulomb.
Matrix();
139 Eigen::LDLT<Eigen::MatrixXd> V_ldlt;
144 std::vector<AOMatrixDerivative> dV =
149 std::vector<ThreeCenterDerivative> d3c_mo =
153 Eigen::MatrixXd grad = Eigen::MatrixXd::Zero(natoms, 3);
162 std::vector<Eigen::MatrixXd> tensor_half(n_aux_bf);
163 for (
Index p = 0; p < n_aux_bf; ++p) {
164 tensor_half[p] = tensor[p] * occ_mo_coeffs;
166 std::vector<std::vector<Eigen::VectorXd>> c_ij(
167 nocc, std::vector<Eigen::VectorXd>(nocc));
168 for (
Index i = 0; i < nocc; ++i) {
169 for (
Index j = 0; j < nocc; ++j) {
170 Eigen::VectorXd d(n_aux_bf);
171 for (
Index p = 0; p < n_aux_bf; ++p) {
172 d(p) = occ_mo_coeffs.col(i).dot(tensor_half[p].col(j));
174 c_ij[i][j] = V_chol.
ok() ? Eigen::VectorXd(V_chol.
Solve(d))
175 : Eigen::VectorXd(V_ldlt.solve(d));
185#pragma omp parallel for
186 for (
Index a = 0; a < natoms; ++a) {
187 for (
Index xyz = 0; xyz < 3; ++xyz) {
188 double energy_term = 0.0;
189 double metric_term = 0.0;
190 for (
Index i = 0; i < nocc; ++i) {
191 for (
Index j = 0; j < nocc; ++j) {
192 const Eigen::VectorXd& c = c_ij[i][j];
194 Eigen::VectorXd dd(n_aux_bf);
195 for (
Index p = 0; p < n_aux_bf; ++p) {
196 dd(p) = d3c_mo[a][xyz][p](i, j);
198 energy_term += c.dot(dd);
199 metric_term += c.dot(dV[a][xyz] * c);
203 grad(a, xyz) = -2.0 * (energy_term - 0.5 * metric_term);
Container to hold Basisfunctions for all atoms.
Index AOBasisSize() const
const std::vector< Index > & getFuncPerAtom() const
void Fill(const AOBasis &aobasis) final
const Eigen::MatrixXd & Matrix() const
const Eigen::Vector3d & getPos() const
Eigen::MatrixXd Solve(const Eigen::MatrixXd &B) const
A^-1 B.
static Eigen::MatrixXd RIKGradient(const Eigen::MatrixXd &occ_mo_coeffs, const AOBasis &auxbasis, const AOBasis &dftbasis)
static Eigen::MatrixXd NuclearRepulsionDerivative(const QMMolecule &mol)
static Eigen::MatrixXd RIJGradient(const Eigen::MatrixXd &density, const AOBasis &auxbasis, const AOBasis &dftbasis)
Charge transport classes.
std::vector< AOMatrixDerivative > ComputeCoulombMetricDerivatives(const AOBasis &aobasis)
std::vector< ThreeCenterDerivative > ComputeThreeCenterDerivatives(const AOBasis &auxbasis, const AOBasis &dftbasis)
std::vector< ThreeCenterDerivative > ComputeThreeCenterDerivativesMOTransformed(const AOBasis &auxbasis, const AOBasis &dftbasis, const Eigen::MatrixXd &occ_mo_coeffs)
std::vector< Eigen::MatrixXd > ComputeThreeCenterIntegrals(const AOBasis &auxbasis, const AOBasis &dftbasis)
std::vector< Eigen::MatrixXd > ComputeThreeCenterDerivativeContraction(const AOBasis &auxbasis, const AOBasis &dftbasis, const Eigen::MatrixXd &density)
std::array< std::vector< Eigen::MatrixXd >, 3 > ThreeCenterDerivative
std::array< Eigen::MatrixXd, 3 > AOMatrixDerivative
ThreeCenterDerivative ComputeThreeCenterDerivativesForAtom(const AOBasis &auxbasis, const AOBasis &dftbasis, Index target_atom)
Provides a means for comparing floating point numbers.