44 const Eigen::MatrixXd& density);
53 const Eigen::MatrixXd& occ_mo_coeffs);
66 Eigen::MatrixXd deriv = Eigen::MatrixXd::Zero(natoms, 3);
78 for (
Index a = 0; a < natoms; ++a) {
79 double Za =
static_cast<double>(mol[a].getNuccharge());
80 const Eigen::Vector3d& Ra = mol[a].
getPos();
81 Eigen::Vector3d sum = Eigen::Vector3d::Zero();
82 for (
Index b = 0; b < natoms; ++b) {
86 double Zb =
static_cast<double>(mol[b].getNuccharge());
87 const Eigen::Vector3d& Rb = mol[b].
getPos();
88 Eigen::Vector3d Rab_vec = Ra - Rb;
89 double Rab = Rab_vec.norm();
90 sum += Za * Zb * Rab_vec / (Rab * Rab * Rab);
92 deriv.row(a) = -sum.transpose();
104 std::vector<Eigen::MatrixXd> tensor =
106 Eigen::VectorXd d(n_aux_bf);
107 for (
Index p = 0; p < n_aux_bf; ++p) {
108 d(p) = (density.array() * tensor[p].array()).sum();
118 aocoulomb.
Fill(auxbasis);
119 const Eigen::MatrixXd&
V = aocoulomb.
Matrix();
120 Eigen::VectorXd c =
V.ldlt().solve(d);
134 std::vector<Eigen::MatrixXd> ddP_dR =
136 std::vector<AOMatrixDerivative> dV =
146 Eigen::MatrixXd grad = Eigen::MatrixXd::Zero(natoms, 3);
147 for (
Index a = 0; a < natoms; ++a) {
148 for (
Index xyz = 0; xyz < 3; ++xyz) {
149 double term1 = ddP_dR[a].row(xyz).dot(c);
150 double term2 = 0.5 * c.dot(dV[a][xyz] * c);
151 grad(a, xyz) = term1 - term2;
162 Index nocc = occ_mo_coeffs.cols();
164 std::vector<Eigen::MatrixXd> tensor =
168 aocoulomb.
Fill(auxbasis);
169 const Eigen::MatrixXd&
V = aocoulomb.
Matrix();
170 Eigen::LDLT<Eigen::MatrixXd> V_ldlt(
V);
172 std::vector<AOMatrixDerivative> dV =
183 std::vector<ThreeCenterDerivative> d3c_mo =
187 Eigen::MatrixXd grad = Eigen::MatrixXd::Zero(natoms, 3);
208 std::vector<Eigen::MatrixXd> tensor_half(n_aux_bf);
209 for (
Index p = 0; p < n_aux_bf; ++p) {
210 tensor_half[p] = tensor[p] * occ_mo_coeffs;
212 std::vector<std::vector<Eigen::VectorXd>> c_ij(
213 nocc, std::vector<Eigen::VectorXd>(nocc));
214 for (
Index i = 0; i < nocc; ++i) {
215 for (
Index j = 0; j < nocc; ++j) {
216 Eigen::VectorXd d(n_aux_bf);
217 for (
Index p = 0; p < n_aux_bf; ++p) {
218 d(p) = occ_mo_coeffs.col(i).dot(tensor_half[p].col(j));
220 c_ij[i][j] = V_ldlt.solve(d);
248#pragma omp parallel for
249 for (
Index a = 0; a < natoms; ++a) {
250 for (
Index xyz = 0; xyz < 3; ++xyz) {
251 double energy_term = 0.0;
252 double metric_term = 0.0;
253 for (
Index i = 0; i < nocc; ++i) {
254 for (
Index j = 0; j < nocc; ++j) {
255 const Eigen::VectorXd& c = c_ij[i][j];
262 Eigen::VectorXd dd(n_aux_bf);
263 for (
Index p = 0; p < n_aux_bf; ++p) {
264 dd(p) = d3c_mo[a][xyz][p](i, j);
266 energy_term += c.dot(dd);
267 metric_term += c.dot(dV[a][xyz] * c);
273 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
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.