votca 2024.2-dev
Loading...
Searching...
No Matches
dftengine.cc
Go to the documentation of this file.
1/*
2 * Copyright 2009-2023 The VOTCA Development Team
3 * (http://www.votca.org)
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License")
6 *
7 * You may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19
20// Third party includes
21#include <algorithm>
22#include <boost/filesystem.hpp>
23#include <boost/format.hpp>
24
25// VOTCA includes
28
29// Local VOTCA includes
33#include "votca/xtp/aomatrix.h"
36#include "votca/xtp/dftengine.h"
38#include "votca/xtp/logger.h"
39#include "votca/xtp/mmregion.h"
40#include "votca/xtp/orbitals.h"
42
43namespace votca {
44namespace xtp {
45
47
48 const std::string key_xtpdft = "xtpdft";
49 dftbasis_name_ = options.get(".basisset").as<std::string>();
50
51 if (options.exists(".auxbasisset")) {
52 auxbasis_name_ = options.get(".auxbasisset").as<std::string>();
53 }
54
55 if (!auxbasis_name_.empty()) {
56 screening_eps_ = options.get(key_xtpdft + ".screening_eps").as<double>();
58 options.get(key_xtpdft + ".fock_matrix_reset").as<Index>();
59 }
60 if (options.exists(".ecp")) {
61 ecp_name_ = options.get(".ecp").as<std::string>();
62 }
63
64 initial_guess_ = options.get(".initial_guess").as<std::string>();
65
66 grid_name_ = options.get(key_xtpdft + ".integration_grid").as<std::string>();
67 xc_functional_name_ = options.get(".functional").as<std::string>();
68
69 if (options.exists(key_xtpdft + ".externaldensity")) {
72 options.get(key_xtpdft + ".externaldensity.orbfile").as<std::string>();
73 gridquality_ = options.get(key_xtpdft + ".externaldensity.gridquality")
74 .as<std::string>();
75 state_ =
76 options.get(key_xtpdft + ".externaldensity.state").as<std::string>();
77 }
78
79 if (options.exists(".externalfield")) {
81 extfield_ = options.get(".externalfield").as<Eigen::Vector3d>();
82 }
83
85 options.get(key_xtpdft + ".convergence.energy").as<double>();
87 options.get(key_xtpdft + ".convergence.error").as<double>();
88 max_iter_ =
89 options.get(key_xtpdft + ".convergence.max_iterations").as<Index>();
90
91 std::string method =
92 options.get(key_xtpdft + ".convergence.method").as<std::string>();
93 if (method == "DIIS") {
94 conv_opt_.usediis = true;
95 } else if (method == "mixing") {
96 conv_opt_.usediis = false;
97 }
98 if (!conv_opt_.usediis) {
100 conv_opt_.maxout = false;
101 }
103 options.get(key_xtpdft + ".convergence.mixing").as<double>();
105 options.get(key_xtpdft + ".convergence.levelshift").as<double>();
107 options.get(key_xtpdft + ".convergence.levelshift_end").as<double>();
109 options.get(key_xtpdft + ".convergence.DIIS_maxout").as<bool>();
111 options.get(key_xtpdft + ".convergence.DIIS_length").as<Index>();
113 options.get(key_xtpdft + ".convergence.DIIS_start").as<double>();
115 options.get(key_xtpdft + ".convergence.ADIIS_start").as<double>();
116
117 if (options.exists(key_xtpdft + ".dft_in_dft.activeatoms")) {
119 options.get(key_xtpdft + ".dft_in_dft.activeatoms").as<std::string>();
121 options.get(key_xtpdft + ".dft_in_dft.threshold").as<double>();
123 options.get(key_xtpdft + ".dft_in_dft.levelshift").as<double>();
124 truncate_ =
125 options.get(key_xtpdft + ".dft_in_dft.truncate_basis").as<bool>();
126 if (truncate_) {
128 options.get(key_xtpdft + ".dft_in_dft.truncation_threshold")
129 .as<double>();
130 }
131 }
132}
133
134void DFTEngine::PrintMOs(const Eigen::VectorXd& MOEnergies, Log::Level level) {
135 XTP_LOG(level, *pLog_) << " Orbital energies: " << std::flush;
136 XTP_LOG(level, *pLog_) << " index occupation energy(Hartree) " << std::flush;
137 for (Index i = 0; i < MOEnergies.size(); i++) {
138 Index occupancy = 0;
139 if (i < numofelectrons_ / 2) {
140 occupancy = 2;
141 }
142 XTP_LOG(level, *pLog_) << (boost::format(" %1$5d %2$1d %3$+1.10f") %
143 i % occupancy % MOEnergies(i))
144 .str()
145 << std::flush;
146 }
147 return;
148}
149
150void DFTEngine::CalcElDipole(const Orbitals& orb) const {
151 QMState state = QMState("n");
152 Eigen::Vector3d result = orb.CalcElDipole(state);
154 << TimeStamp() << " Electric Dipole is[e*bohr]:\n\t\t dx=" << result[0]
155 << "\n\t\t dy=" << result[1] << "\n\t\t dz=" << result[2] << std::flush;
156 return;
157}
158
159std::array<Eigen::MatrixXd, 2> DFTEngine::CalcERIs_EXX(
160 const Eigen::MatrixXd& MOCoeff, const Eigen::MatrixXd& Dmat,
161 double error) const {
162 if (!auxbasis_name_.empty()) {
163 if (conv_accelerator_.getUseMixing() || MOCoeff.rows() == 0) {
164 return ERIs_.CalculateERIs_EXX_3c(Eigen::MatrixXd::Zero(0, 0), Dmat);
165 } else {
166 Eigen::MatrixXd occblock = MOCoeff.leftCols(numofelectrons_ / 2);
167 return ERIs_.CalculateERIs_EXX_3c(occblock, Dmat);
168 }
169 } else {
170 return ERIs_.CalculateERIs_EXX_4c(Dmat, error);
171 }
172}
173
174Eigen::MatrixXd DFTEngine::CalcERIs(const Eigen::MatrixXd& Dmat,
175 double error) const {
176 if (!auxbasis_name_.empty()) {
177 return ERIs_.CalculateERIs_3c(Dmat);
178 } else {
179 return ERIs_.CalculateERIs_4c(Dmat, error);
180 }
181}
182
187
189 const Mat_p_Energy& H0, const QMMolecule& mol,
190 const Vxc_Potential<Vxc_Grid>& vxcpotential) const {
191 Eigen::MatrixXd Dmat = AtomicGuess(mol);
192 Mat_p_Energy e_vxc = vxcpotential.IntegrateVXC(Dmat);
194 << TimeStamp() << " Filled DFT Vxc matrix " << std::flush;
195
196 Eigen::MatrixXd H = H0.matrix() + e_vxc.matrix();
197
198 if (ScaHFX_ > 0) {
199 std::array<Eigen::MatrixXd, 2> both =
200 CalcERIs_EXX(Eigen::MatrixXd::Zero(0, 0), Dmat, 1e-12);
201 H += both[0];
202 H += ScaHFX_ * both[1];
203 } else {
204 H += CalcERIs(Dmat, 1e-12);
205 }
207}
208
210 Prepare(orb);
211 Mat_p_Energy H0 = SetupH0(orb.QMAtoms());
213 MOs.eigenvalues() = Eigen::VectorXd::Zero(H0.cols());
214 MOs.eigenvectors() = Eigen::MatrixXd::Zero(H0.rows(), H0.cols());
215 Vxc_Potential<Vxc_Grid> vxcpotential = SetupVxc(orb.QMAtoms());
216 ConfigOrbfile(orb);
217
218 if (initial_guess_ == "orbfile") {
220 << TimeStamp() << " Reading guess from orbitals object/file"
221 << std::flush;
222 MOs = orb.MOs();
224 } else {
226 << TimeStamp() << " Setup Initial Guess using: " << initial_guess_
227 << std::flush;
228 if (initial_guess_ == "independent") {
229 MOs = IndependentElectronGuess(H0);
230 } else if (initial_guess_ == "atom") {
231 MOs = ModelPotentialGuess(H0, orb.QMAtoms(), vxcpotential);
232 } else {
233 throw std::runtime_error("Initial guess method not known/implemented");
234 }
235 }
236
237 Eigen::MatrixXd Dmat = conv_accelerator_.DensityMatrix(MOs);
239 << TimeStamp() << " Guess Matrix gives N=" << std::setprecision(9)
240 << Dmat.cwiseProduct(dftAOoverlap_.Matrix()).sum() << " electrons."
241 << std::flush;
242
244 << TimeStamp() << " STARTING SCF cycle" << std::flush;
246 << " ----------------------------------------------"
247 "----------------------------"
248 << std::flush;
249
250 Eigen::MatrixXd J = Eigen::MatrixXd::Zero(Dmat.rows(), Dmat.cols());
251 Eigen::MatrixXd K;
252 if (ScaHFX_ > 0) {
253 K = Eigen::MatrixXd::Zero(Dmat.rows(), Dmat.cols());
254 }
255
256 double start_incremental_F_threshold = 1e-4;
257 if (!auxbasis_name_.empty()) {
258 start_incremental_F_threshold = 0.0; // Disable if RI is used
259 }
260 IncrementalFockBuilder incremental_fock(*pLog_, start_incremental_F_threshold,
262 incremental_fock.Configure(Dmat);
263
264 for (Index this_iter = 0; this_iter < max_iter_; this_iter++) {
265 XTP_LOG(Log::error, *pLog_) << std::flush;
266 XTP_LOG(Log::error, *pLog_) << TimeStamp() << " Iteration " << this_iter + 1
267 << " of " << max_iter_ << std::flush;
268 Mat_p_Energy e_vxc = vxcpotential.IntegrateVXC(Dmat);
270 << TimeStamp() << " Filled DFT Vxc matrix " << std::flush;
271
272 Eigen::MatrixXd H = H0.matrix() + e_vxc.matrix();
273 double Eone = Dmat.cwiseProduct(H0.matrix()).sum();
274 double Etwo = e_vxc.energy();
275 double exx = 0.0;
276
277 incremental_fock.Start(this_iter, conv_accelerator_.getDIIsError());
278 incremental_fock.resetMatrices(J, K, Dmat);
280 this_iter);
281
282 double integral_error =
283 std::min(conv_accelerator_.getDIIsError() * 1e-5, 1e-5);
284 if (ScaHFX_ > 0) {
285 std::array<Eigen::MatrixXd, 2> both = CalcERIs_EXX(
286 MOs.eigenvectors(), incremental_fock.getDmat_diff(), integral_error);
287 J += both[0];
288 H += J;
289 Etwo += 0.5 * Dmat.cwiseProduct(J).sum();
290 K += both[1];
291 H += 0.5 * ScaHFX_ * K;
292 exx = 0.25 * ScaHFX_ * Dmat.cwiseProduct(K).sum();
294 << TimeStamp() << " Filled F+K matrix " << std::flush;
295 } else {
296 J += CalcERIs(incremental_fock.getDmat_diff(), integral_error);
298 << TimeStamp() << " Filled F matrix " << std::flush;
299 H += J;
300 Etwo += 0.5 * Dmat.cwiseProduct(J).sum();
301 }
302
303 Etwo += exx;
304 double totenergy = Eone + H0.energy() + Etwo;
305 XTP_LOG(Log::info, *pLog_) << TimeStamp() << " Single particle energy "
306 << std::setprecision(12) << Eone << std::flush;
307 XTP_LOG(Log::info, *pLog_) << TimeStamp() << " Two particle energy "
308 << std::setprecision(12) << Etwo << std::flush;
310 << TimeStamp() << std::setprecision(12) << " Local Exc contribution "
311 << e_vxc.energy() << std::flush;
312 if (ScaHFX_ > 0) {
314 << TimeStamp() << std::setprecision(12)
315 << " Non local Ex contribution " << exx << std::flush;
316 }
318 << TimeStamp() << " Total Energy " << std::setprecision(12) << totenergy
319 << std::flush;
320
321 Dmat = conv_accelerator_.Iterate(Dmat, H, MOs, totenergy);
322 incremental_fock.UpdateDmats(Dmat, conv_accelerator_.getDIIsError(),
323 this_iter);
324
326
327 XTP_LOG(Log::info, *pLog_) << "\t\tGAP "
328 << MOs.eigenvalues()(numofelectrons_ / 2) -
329 MOs.eigenvalues()(numofelectrons_ / 2 - 1)
330 << std::flush;
331
334 << TimeStamp() << " Total Energy has converged to "
335 << std::setprecision(9) << conv_accelerator_.getDeltaE()
336 << "[Ha] after " << this_iter + 1
337 << " iterations. DIIS error is converged up to "
338 << conv_accelerator_.getDIIsError() << std::flush;
340 << TimeStamp() << " Final Single Point Energy "
341 << std::setprecision(12) << totenergy << " Ha" << std::flush;
342 XTP_LOG(Log::error, *pLog_) << TimeStamp() << std::setprecision(12)
343 << " Final Local Exc contribution "
344 << e_vxc.energy() << " Ha" << std::flush;
345 if (ScaHFX_ > 0) {
346 XTP_LOG(Log::error, *pLog_) << TimeStamp() << std::setprecision(12)
347 << " Final Non Local Ex contribution "
348 << exx << " Ha" << std::flush;
349 }
350
352 orb.setQMEnergy(totenergy);
353 orb.MOs() = MOs;
354 CalcElDipole(orb);
355 break;
356 } else if (this_iter == max_iter_ - 1) {
358 << TimeStamp() << " DFT calculation has not converged after "
359 << max_iter_
360 << " iterations. Use more iterations or another convergence "
361 "acceleration scheme."
362 << std::flush;
363 return false;
364 }
365 }
366 return true;
367}
368
370
371 AOKinetic dftAOkinetic;
372
373 dftAOkinetic.Fill(dftbasis_);
375 << TimeStamp() << " Filled DFT Kinetic energy matrix ." << std::flush;
376
377 AOMultipole dftAOESP;
378 dftAOESP.FillPotential(dftbasis_, mol);
380 << TimeStamp() << " Filled DFT nuclear potential matrix." << std::flush;
381
382 Eigen::MatrixXd H0 = dftAOkinetic.Matrix() + dftAOESP.Matrix();
384 << TimeStamp() << " Constructed independent particle hamiltonian "
385 << std::flush;
386 double E0 = NuclearRepulsion(mol);
387 XTP_LOG(Log::error, *pLog_) << TimeStamp() << " Nuclear Repulsion Energy is "
388 << std::setprecision(9) << E0 << std::flush;
389
390 if (!ecp_name_.empty()) {
391 AOECP dftAOECP;
392 dftAOECP.FillPotential(dftbasis_, ecp_);
393 H0 += dftAOECP.Matrix();
395 << TimeStamp() << " Filled DFT ECP matrix" << std::flush;
396 }
397
398 if (externalsites_ != nullptr) {
399 XTP_LOG(Log::error, *pLog_) << TimeStamp() << " " << externalsites_->size()
400 << " External sites" << std::flush;
401 bool has_quadrupoles = std::any_of(
402 externalsites_->begin(), externalsites_->end(),
403 [](const std::unique_ptr<StaticSite>& s) { return s->getRank() == 2; });
404 std::string header =
405 " Name Coordinates[a0] charge[e] dipole[e*a0] ";
406 if (has_quadrupoles) {
407 header += " quadrupole[e*a0^2]";
408 }
409 XTP_LOG(Log::error, *pLog_) << header << std::flush;
410 Index limit = 50;
411 Index counter = 0;
412 for (const std::unique_ptr<StaticSite>& site : *externalsites_) {
413 if (counter == limit) {
414 break;
415 }
416 std::string output =
417 (boost::format(" %1$s"
418 " %2$+1.4f %3$+1.4f %4$+1.4f"
419 " %5$+1.4f") %
420 site->getElement() % site->getPos()[0] % site->getPos()[1] %
421 site->getPos()[2] % site->getCharge())
422 .str();
423 const Eigen::Vector3d& dipole = site->getDipole();
424 output += (boost::format(" %1$+1.4f %2$+1.4f %3$+1.4f") % dipole[0] %
425 dipole[1] % dipole[2])
426 .str();
427 if (site->getRank() > 1) {
428 Eigen::VectorXd quadrupole = site->Q().tail<5>();
429 output +=
430 (boost::format(" %1$+1.4f %2$+1.4f %3$+1.4f %4$+1.4f %5$+1.4f") %
431 quadrupole[0] % quadrupole[1] % quadrupole[2] % quadrupole[3] %
432 quadrupole[4])
433 .str();
434 }
435 XTP_LOG(Log::error, *pLog_) << output << std::flush;
436 counter++;
437 }
438 if (counter == limit) {
440 << " ... (" << externalsites_->size() - limit
441 << " sites not displayed)\n"
442 << std::flush;
443 }
444
445 Mat_p_Energy ext_multipoles =
448 << TimeStamp() << " Nuclei-external site interaction energy "
449 << std::setprecision(9) << ext_multipoles.energy() << std::flush;
450 E0 += ext_multipoles.energy();
451 H0 += ext_multipoles.matrix();
452 }
453
455 Orbitals extdensity;
456 extdensity.ReadFromCpt(orbfilename_);
457 Mat_p_Energy extdensity_result = IntegrateExternalDensity(mol, extdensity);
458 E0 += extdensity_result.energy();
460 << TimeStamp() << " Nuclei-external density interaction energy "
461 << std::setprecision(9) << extdensity_result.energy() << std::flush;
462 H0 += extdensity_result.matrix();
463 }
464
466
468 << TimeStamp() << " Integrating external electric field with F[Hrt]="
469 << extfield_.transpose() << std::flush;
470 H0 += IntegrateExternalField(mol);
471 }
472
473 return Mat_p_Energy(E0, H0);
474}
475
479 << TimeStamp() << " Filled DFT Overlap matrix." << std::flush;
480
486
487 if (!auxbasis_name_.empty()) {
488 // prepare invariant part of electron repulsion integrals
491 << TimeStamp() << " Inverted AUX Coulomb matrix, removed "
492 << ERIs_.Removedfunctions() << " functions from aux basis"
493 << std::flush;
495 << TimeStamp()
496 << " Setup invariant parts of Electron Repulsion integrals "
497 << std::flush;
498 } else {
500 << TimeStamp() << " Calculating 4c diagonals. " << std::flush;
503 << TimeStamp() << " Calculated 4c diagonals. " << std::flush;
504 }
505
506 return;
507}
508
510 const QMAtom& uniqueAtom) const {
511 bool with_ecp = !ecp_name_.empty();
512 if (uniqueAtom.getElement() == "H" || uniqueAtom.getElement() == "He") {
513 with_ecp = false;
514 }
515
516 QMMolecule atom = QMMolecule("individual_atom", 0);
517 atom.push_back(uniqueAtom);
518
519 BasisSet basisset;
520 basisset.Load(dftbasis_name_);
521 AOBasis dftbasis;
522 dftbasis.Fill(basisset, atom);
523 Vxc_Grid grid;
524 grid.GridSetup(grid_name_, atom, dftbasis);
525 Vxc_Potential<Vxc_Grid> gridIntegration(grid);
526 gridIntegration.setXCfunctional(xc_functional_name_);
527
528 ECPAOBasis ecp;
529 if (with_ecp) {
530 ECPBasisSet ecps;
531 ecps.Load(ecp_name_);
532 ecp.Fill(ecps, atom);
533 }
534
535 Index numofelectrons = uniqueAtom.getNuccharge();
536 Index alpha_e = 0;
537 Index beta_e = 0;
538
539 if ((numofelectrons % 2) != 0) {
540 alpha_e = numofelectrons / 2 + numofelectrons % 2;
541 beta_e = numofelectrons / 2;
542 } else {
543 alpha_e = numofelectrons / 2;
544 beta_e = alpha_e;
545 }
546
547 AOOverlap dftAOoverlap;
548 AOKinetic dftAOkinetic;
549 AOMultipole dftAOESP;
550 AOECP dftAOECP;
551 ERIs ERIs_atom;
552
553 // DFT AOOverlap matrix
554
555 dftAOoverlap.Fill(dftbasis);
556 dftAOkinetic.Fill(dftbasis);
557
558 dftAOESP.FillPotential(dftbasis, atom);
559 ERIs_atom.Initialize_4c(dftbasis);
560
561 ConvergenceAcc Convergence_alpha;
562 ConvergenceAcc Convergence_beta;
565 opt_alpha.histlength = 20;
566 opt_alpha.levelshift = 0.1;
567 opt_alpha.levelshiftend = 0.0;
568 opt_alpha.usediis = true;
569 opt_alpha.adiis_start = 0.0;
570 opt_alpha.diis_start = 0.0;
571 opt_alpha.numberofelectrons = alpha_e;
572
573 ConvergenceAcc::options opt_beta = opt_alpha;
574 opt_beta.numberofelectrons = beta_e;
575
576 Logger log;
577 Convergence_alpha.Configure(opt_alpha);
578 Convergence_alpha.setLogger(&log);
579 Convergence_alpha.setOverlap(dftAOoverlap, 1e-8);
580 Convergence_beta.Configure(opt_beta);
581 Convergence_beta.setLogger(&log);
582 Convergence_beta.setOverlap(dftAOoverlap, 1e-8);
583 /**** Construct initial density ****/
584
585 Eigen::MatrixXd H0 = dftAOkinetic.Matrix() + dftAOESP.Matrix();
586 if (with_ecp) {
587 dftAOECP.FillPotential(dftbasis, ecp);
588 H0 += dftAOECP.Matrix();
589 }
590 tools::EigenSystem MOs_alpha = Convergence_alpha.SolveFockmatrix(H0);
591
592 Eigen::MatrixXd dftAOdmat_alpha = Convergence_alpha.DensityMatrix(MOs_alpha);
593 if (uniqueAtom.getElement() == "H") {
594 return dftAOdmat_alpha;
595 }
596 tools::EigenSystem MOs_beta = Convergence_beta.SolveFockmatrix(H0);
597 Eigen::MatrixXd dftAOdmat_beta = Convergence_beta.DensityMatrix(MOs_beta);
598
599 Index maxiter = 80;
600 for (Index this_iter = 0; this_iter < maxiter; this_iter++) {
601
602 Eigen::MatrixXd H_alpha = H0;
603 Eigen::MatrixXd H_beta = H_alpha;
604
605 double E_two_alpha = 0.0;
606 double E_two_beta = 0.0;
607
608 double integral_error = std::min(1e-5 * 0.5 *
609 (Convergence_alpha.getDIIsError() +
610 Convergence_beta.getDIIsError()),
611 1e-5);
612 if (ScaHFX_ > 0) {
613 std::array<Eigen::MatrixXd, 2> both_alpha =
614 ERIs_atom.CalculateERIs_EXX_4c(dftAOdmat_alpha, integral_error);
615
616 std::array<Eigen::MatrixXd, 2> both_beta =
617 ERIs_atom.CalculateERIs_EXX_4c(dftAOdmat_beta, integral_error);
618 Eigen::MatrixXd Hartree = both_alpha[0] + both_beta[0];
619 E_two_alpha += Hartree.cwiseProduct(dftAOdmat_alpha).sum();
620 E_two_beta += Hartree.cwiseProduct(dftAOdmat_beta).sum();
621 E_two_alpha += 0.5 * both_alpha[1].cwiseProduct(dftAOdmat_alpha).sum();
622 E_two_beta += 0.5 * both_beta[1].cwiseProduct(dftAOdmat_beta).sum();
623 H_alpha += Hartree + ScaHFX_ * both_alpha[1];
624 H_beta += Hartree + ScaHFX_ * both_beta[1];
625
626 } else {
627 Eigen::MatrixXd Hartree = ERIs_atom.CalculateERIs_4c(
628 dftAOdmat_alpha + dftAOdmat_beta, integral_error);
629 E_two_alpha += Hartree.cwiseProduct(dftAOdmat_alpha).sum();
630 E_two_beta += Hartree.cwiseProduct(dftAOdmat_beta).sum();
631 H_alpha += Hartree;
632 H_beta += Hartree;
633 }
634
635 Mat_p_Energy e_vxc_alpha = gridIntegration.IntegrateVXC(dftAOdmat_alpha);
636 H_alpha += e_vxc_alpha.matrix();
637 E_two_alpha += e_vxc_alpha.energy();
638
639 Mat_p_Energy e_vxc_beta = gridIntegration.IntegrateVXC(dftAOdmat_beta);
640 H_beta += e_vxc_beta.matrix();
641 E_two_beta += e_vxc_beta.energy();
642
643 double E_one_alpha = dftAOdmat_alpha.cwiseProduct(H0).sum();
644 double E_one_beta = dftAOdmat_beta.cwiseProduct(H0).sum();
645 double E_alpha = E_one_alpha + E_two_alpha;
646 double E_beta = E_one_beta + E_two_beta;
647 double totenergy = E_alpha + E_beta;
648 // evolve alpha
649 dftAOdmat_alpha =
650 Convergence_alpha.Iterate(dftAOdmat_alpha, H_alpha, MOs_alpha, E_alpha);
651 // evolve beta
652 dftAOdmat_beta =
653 Convergence_beta.Iterate(dftAOdmat_beta, H_beta, MOs_beta, E_beta);
654
656 << TimeStamp() << " Iter " << this_iter << " of " << maxiter << " Etot "
657 << totenergy << " diise_a " << Convergence_alpha.getDIIsError()
658 << " diise_b " << Convergence_beta.getDIIsError() << "\n\t\t a_gap "
659 << MOs_alpha.eigenvalues()(alpha_e) -
660 MOs_alpha.eigenvalues()(alpha_e - 1)
661 << " b_gap "
662 << MOs_beta.eigenvalues()(beta_e) - MOs_beta.eigenvalues()(beta_e - 1)
663 << " Nalpha="
664 << dftAOoverlap.Matrix().cwiseProduct(dftAOdmat_alpha).sum()
665 << " Nbeta=" << dftAOoverlap.Matrix().cwiseProduct(dftAOdmat_beta).sum()
666 << std::flush;
667
668 bool converged =
669 Convergence_alpha.isConverged() && Convergence_beta.isConverged();
670 if (converged || this_iter == maxiter - 1) {
671
672 if (converged) {
674 << TimeStamp() << " Converged after " << this_iter + 1
675 << " iterations" << std::flush;
676 } else {
678 << TimeStamp() << " Not converged after " << this_iter + 1
679 << " iterations. Unconverged density.\n\t\t\t"
680 << " DIIsError_alpha=" << Convergence_alpha.getDIIsError()
681 << " DIIsError_beta=" << Convergence_beta.getDIIsError()
682 << std::flush;
683 }
684 break;
685 }
686 }
687 Eigen::MatrixXd avgmatrix =
688 SphericalAverageShells(dftAOdmat_alpha + dftAOdmat_beta, dftbasis);
690 << TimeStamp() << " Atomic density Matrix for " << uniqueAtom.getElement()
691 << " gives N=" << std::setprecision(9)
692 << avgmatrix.cwiseProduct(dftAOoverlap.Matrix()).sum() << " electrons."
693 << std::flush;
694 return avgmatrix;
695}
696
697Eigen::MatrixXd DFTEngine::AtomicGuess(const QMMolecule& mol) const {
698
699 std::vector<std::string> elements = mol.FindUniqueElements();
701 << TimeStamp() << " Scanning molecule of size " << mol.size()
702 << " for unique elements" << std::flush;
703 QMMolecule uniqueelements = QMMolecule("uniqueelements", 0);
704 for (auto element : elements) {
705 uniqueelements.push_back(QMAtom(0, element, Eigen::Vector3d::Zero()));
706 }
707
708 XTP_LOG(Log::info, *pLog_) << TimeStamp() << " " << uniqueelements.size()
709 << " unique elements found" << std::flush;
710 std::vector<Eigen::MatrixXd> uniqueatom_guesses;
711 for (QMAtom& unique_atom : uniqueelements) {
713 << TimeStamp() << " Calculating atom density for "
714 << unique_atom.getElement() << std::flush;
715 Eigen::MatrixXd dmat_unrestricted = RunAtomicDFT_unrestricted(unique_atom);
716 uniqueatom_guesses.push_back(dmat_unrestricted);
717 }
718
719 Eigen::MatrixXd guess =
720 Eigen::MatrixXd::Zero(dftbasis_.AOBasisSize(), dftbasis_.AOBasisSize());
721 Index start = 0;
722 for (const QMAtom& atom : mol) {
723 Index index = 0;
724 for (; index < uniqueelements.size(); index++) {
725 if (atom.getElement() == uniqueelements[index].getElement()) {
726 break;
727 }
728 }
729 Eigen::MatrixXd& dmat_unrestricted = uniqueatom_guesses[index];
730 guess.block(start, start, dmat_unrestricted.rows(),
731 dmat_unrestricted.cols()) = dmat_unrestricted;
732 start += dmat_unrestricted.rows();
733 }
734
735 return guess;
736}
737
739 if (initial_guess_ == "orbfile") {
740
741 if (orb.hasDFTbasisName()) {
742 if (orb.getDFTbasisName() != dftbasis_name_) {
743 throw std::runtime_error(
744 (boost::format("Basisset Name in guess orb file "
745 "and in dftengine option file differ %1% vs %2%") %
747 .str());
748 }
749 } else {
751 << TimeStamp()
752 << " WARNING: "
753 "Orbital file has no basisset information,"
754 "using it as a guess might work or not for calculation with "
755 << dftbasis_name_ << std::flush;
756 }
757 }
758 // XTPDFT only with neutral, closed-shell systems
759 orb.setChargeAndSpin(0, 1);
760
763 orb.setScaHFX(ScaHFX_);
764 if (!ecp_name_.empty()) {
766 }
767 if (!auxbasis_name_.empty()) {
769 }
770
771 if (initial_guess_ == "orbfile") {
772 if (orb.hasECPName() || !ecp_name_.empty()) {
773 if (orb.getECPName() != ecp_name_) {
774 throw std::runtime_error(
775 (boost::format("ECPs in orb file: %1% and options %2% differ") %
776 orb.getECPName() % ecp_name_)
777 .str());
778 }
779 }
781 throw std::runtime_error(
782 (boost::format("Number of electron in guess orb file: %1% and in "
783 "dftengine: %2% differ.") %
785 .str());
786 }
787 if (orb.getBasisSetSize() != dftbasis_.AOBasisSize()) {
788 throw std::runtime_error(
789 (boost::format("Number of levels in guess orb file: "
790 "%1% and in dftengine: %2% differ.") %
792 .str());
793 }
794 } else {
797 }
798 return;
799}
800
801void DFTEngine::Prepare(Orbitals& orb, Index numofelectrons) {
802 QMMolecule& mol = orb.QMAtoms();
803
805 << TimeStamp() << " Using " << OPENMP::getMaxThreads() << " threads"
806 << std::flush;
807
808 if (XTP_HAS_MKL_OVERLOAD()) {
810 << TimeStamp() << " Using MKL overload for Eigen " << std::flush;
811 } else {
813 << TimeStamp()
814 << " Using native Eigen implementation, no BLAS overload "
815 << std::flush;
816 }
817
818 XTP_LOG(Log::error, *pLog_) << " Molecule Coordinates [A] " << std::flush;
819 for (const QMAtom& atom : mol) {
820 const Eigen::Vector3d pos = atom.getPos() * tools::conv::bohr2ang;
821 std::string output = (boost::format(" %1$s"
822 " %2$+1.4f %3$+1.4f %4$+1.4f") %
823 atom.getElement() % pos[0] % pos[1] % pos[2])
824 .str();
825
826 XTP_LOG(Log::error, *pLog_) << output << std::flush;
827 }
828
830 dftbasis_ = orb.getDftBasis();
831
833 << TimeStamp() << " Loaded DFT Basis Set " << dftbasis_name_ << " with "
834 << dftbasis_.AOBasisSize() << " functions" << std::flush;
835
836 if (!auxbasis_name_.empty()) {
837 BasisSet auxbasisset;
838 auxbasisset.Load(auxbasis_name_);
839 auxbasis_.Fill(auxbasisset, mol);
841 << TimeStamp() << " Loaded AUX Basis Set " << auxbasis_name_ << " with "
842 << auxbasis_.AOBasisSize() << " functions" << std::flush;
843 }
844 if (!ecp_name_.empty()) {
845 ECPBasisSet ecpbasisset;
846 ecpbasisset.Load(ecp_name_);
848 << TimeStamp() << " Loaded ECP library " << ecp_name_ << std::flush;
849
850 std::vector<std::string> results = ecp_.Fill(ecpbasisset, mol);
852 << TimeStamp() << " Filled ECP Basis" << std::flush;
853 if (results.size() > 0) {
854 std::string message = "";
855 for (const std::string& element : results) {
856 message += " " + element;
857 }
859 << TimeStamp() << " Found no ECPs for elements" << message
860 << std::flush;
861 }
862 }
863 if (numofelectrons < 0) {
864 for (const QMAtom& atom : mol) {
865 numofelectrons_ += atom.getNuccharge();
866 }
867 } else {
868 numofelectrons_ = numofelectrons;
869 }
870
871 // here number of electrons is actually the total number, everywhere else in
872 // votca it is just alpha_electrons
874 << TimeStamp() << " Total number of electrons: " << numofelectrons_
875 << std::flush;
876
878 return;
879}
880
883 if (ScaHFX_ > 0) {
885 << TimeStamp() << " Using hybrid functional with alpha=" << ScaHFX_
886 << std::flush;
887 }
888 Vxc_Grid grid;
889 grid.GridSetup(grid_name_, mol, dftbasis_);
890 Vxc_Potential<Vxc_Grid> vxc(grid);
893 << TimeStamp() << " Setup numerical integration grid " << grid_name_
894 << " for vxc functional " << xc_functional_name_ << std::flush;
896 << "\t\t "
897 << " with " << grid.getGridSize() << " points"
898 << " divided into " << grid.getBoxesSize() << " boxes" << std::flush;
899 return vxc;
900}
901
902double DFTEngine::NuclearRepulsion(const QMMolecule& mol) const {
903 double E_nucnuc = 0.0;
904
905 for (Index i = 0; i < mol.size(); i++) {
906 const Eigen::Vector3d& r1 = mol[i].getPos();
907 double charge1 = double(mol[i].getNuccharge());
908 for (Index j = 0; j < i; j++) {
909 const Eigen::Vector3d& r2 = mol[j].getPos();
910 double charge2 = double(mol[j].getNuccharge());
911 E_nucnuc += charge1 * charge2 / (r1 - r2).norm();
912 }
913 }
914 return E_nucnuc;
915}
916
917// spherically average the density matrix belonging to two shells
919 const Eigen::MatrixXd& dmat, const AOBasis& dftbasis) const {
920 Eigen::MatrixXd avdmat = Eigen::MatrixXd::Zero(dmat.rows(), dmat.cols());
921 for (const AOShell& shellrow : dftbasis) {
922 Index size_row = shellrow.getNumFunc();
923 Index start_row = shellrow.getStartIndex();
924 for (const AOShell& shellcol : dftbasis) {
925 Index size_col = shellcol.getNumFunc();
926 Index start_col = shellcol.getStartIndex();
927 Eigen::MatrixXd shelldmat =
928 dmat.block(start_row, start_col, size_row, size_col);
929 if (shellrow.getL() == shellcol.getL()) {
930 double diagavg = shelldmat.diagonal().sum() / double(shelldmat.rows());
931 Index offdiagelements =
932 shelldmat.rows() * shelldmat.cols() - shelldmat.cols();
933 double offdiagavg = (shelldmat.sum() - shelldmat.diagonal().sum()) /
934 double(offdiagelements);
935 avdmat.block(start_row, start_col, size_row, size_col).array() =
936 offdiagavg;
937 avdmat.block(start_row, start_col, size_row, size_col)
938 .diagonal()
939 .array() = diagavg;
940 } else {
941 double avg = shelldmat.sum() / double(shelldmat.size());
942 avdmat.block(start_row, start_col, size_row, size_col).array() = avg;
943 }
944 }
945 }
946 return avdmat;
947}
948
950 const QMMolecule& mol,
951 const std::vector<std::unique_ptr<StaticSite> >& multipoles) const {
952
953 if (multipoles.size() == 0) {
954 return 0;
955 }
956
957 double E_ext = 0;
958 eeInteractor interactor;
959 for (const QMAtom& atom : mol) {
960 StaticSite nucleus = StaticSite(atom, double(atom.getNuccharge()));
961 for (const std::unique_ptr<StaticSite>& site : *externalsites_) {
962 if ((site->getPos() - nucleus.getPos()).norm() < 1e-7) {
964 << " External site sits on nucleus, "
965 "interaction between them is ignored."
966 << std::flush;
967 continue;
968 }
969 E_ext += interactor.CalcStaticEnergy_site(*site, nucleus);
970 }
971 }
972 return E_ext;
973}
974
975Eigen::MatrixXd DFTEngine::IntegrateExternalField(const QMMolecule& mol) const {
976
977 AODipole dipole;
978 dipole.setCenter(mol.getPos());
979 dipole.Fill(dftbasis_);
980 Eigen::MatrixXd result =
981 Eigen::MatrixXd::Zero(dipole.Dimension(), dipole.Dimension());
982 for (Index i = 0; i < 3; i++) {
983 result -= dipole.Matrix()[i] * extfield_[i];
984 }
985 return result;
986}
987
989 const QMMolecule& mol,
990 const std::vector<std::unique_ptr<StaticSite> >& multipoles) const {
991
993 AOMultipole dftAOESP;
994
995 dftAOESP.FillPotential(dftbasis_, multipoles);
997 << TimeStamp() << " Filled DFT external multipole potential matrix"
998 << std::flush;
999 result.matrix() = dftAOESP.Matrix();
1000 result.energy() = ExternalRepulsion(mol, multipoles);
1001
1002 return result;
1003}
1004
1006 const QMMolecule& mol, const Orbitals& extdensity) const {
1007 BasisSet basis;
1008 basis.Load(extdensity.getDFTbasisName());
1009 AOBasis aobasis;
1010 aobasis.Fill(basis, extdensity.QMAtoms());
1011 Vxc_Grid grid;
1012 grid.GridSetup(gridquality_, extdensity.QMAtoms(), aobasis);
1013 DensityIntegration<Vxc_Grid> numint(grid);
1014 Eigen::MatrixXd dmat = extdensity.DensityMatrixFull(state_);
1015
1016 numint.IntegrateDensity(dmat);
1018 << TimeStamp() << " Calculated external density" << std::flush;
1019 Eigen::MatrixXd e_contrib = numint.IntegratePotential(dftbasis_);
1021 << TimeStamp() << " Calculated potential from electron density"
1022 << std::flush;
1023 AOMultipole esp;
1024 esp.FillPotential(dftbasis_, extdensity.QMAtoms());
1025
1026 double nuc_energy = 0.0;
1027 for (const QMAtom& atom : mol) {
1028 nuc_energy +=
1029 numint.IntegratePotential(atom.getPos()) * double(atom.getNuccharge());
1030 for (const QMAtom& extatom : extdensity.QMAtoms()) {
1031 const double dist = (atom.getPos() - extatom.getPos()).norm();
1032 nuc_energy +=
1033 double(atom.getNuccharge()) * double(extatom.getNuccharge()) / dist;
1034 }
1035 }
1037 << TimeStamp() << " Calculated potential from nuclei" << std::flush;
1039 << TimeStamp() << " Electrostatic: " << nuc_energy << std::flush;
1040 return Mat_p_Energy(nuc_energy, e_contrib + esp.Matrix());
1041}
1042
1044 const Eigen::MatrixXd& GuessMOs) const {
1045 Eigen::MatrixXd nonortho =
1046 GuessMOs.transpose() * dftAOoverlap_.Matrix() * GuessMOs;
1047 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(nonortho);
1048 Eigen::MatrixXd result = GuessMOs * es.operatorInverseSqrt();
1049 return result;
1050}
1051} // namespace xtp
1052} // namespace votca
const Eigen::VectorXd & eigenvalues() const
Definition eigensystem.h:30
const Eigen::MatrixXd & eigenvectors() const
Definition eigensystem.h:33
class to manage program options with xml serialization functionality
Definition property.h:55
Property & get(const std::string &key)
get existing property
Definition property.cc:79
bool exists(const std::string &key) const
check whether property exists
Definition property.cc:122
T as() const
return value as type
Definition property.h:283
Container to hold Basisfunctions for all atoms.
Definition aobasis.h:42
Index AOBasisSize() const
Definition aobasis.h:46
void Fill(const BasisSet &bs, const QMMolecule &atoms)
Definition aobasis.cc:85
Index Dimension() final
Definition aomatrix.h:91
void setCenter(const Eigen::Vector3d &r)
Definition aomatrix.h:94
const std::array< Eigen::MatrixXd, 3 > & Matrix() const
Definition aomatrix.h:92
void Fill(const AOBasis &aobasis) final
void FillPotential(const AOBasis &aobasis, const ECPAOBasis &ecp)
Definition aoecp.cc:59
void Fill(const AOBasis &aobasis) final
const Eigen::MatrixXd & Matrix() const
Definition aomatrix.h:41
void FillPotential(const AOBasis &aobasis, const QMMolecule &atoms)
void Fill(const AOBasis &aobasis) final
const Eigen::MatrixXd & Matrix() const
Definition aomatrix.h:52
const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > & Matrix() const
Definition aopotential.h:39
void push_back(const T &atom)
std::vector< std::string > FindUniqueElements() const
const Eigen::Vector3d & getPos() const
void Load(const std::string &name)
Definition basisset.cc:149
Eigen::MatrixXd DensityMatrix(const tools::EigenSystem &MOs) const
void Configure(const ConvergenceAcc::options &opt)
void setLogger(Logger *log)
Eigen::MatrixXd Iterate(const Eigen::MatrixXd &dmat, Eigen::MatrixXd &H, tools::EigenSystem &MOs, double totE)
tools::EigenSystem SolveFockmatrix(const Eigen::MatrixXd &H) const
void setOverlap(AOOverlap &S, double etol)
Eigen::MatrixXd CalcERIs(const Eigen::MatrixXd &Dmat, double error) const
Definition dftengine.cc:174
std::string auxbasis_name_
Definition dftengine.h:126
std::string gridquality_
Definition dftengine.h:164
tools::EigenSystem ModelPotentialGuess(const Mat_p_Energy &H0, const QMMolecule &mol, const Vxc_Potential< Vxc_Grid > &vxcpotential) const
Definition dftengine.cc:188
Mat_p_Energy IntegrateExternalMultipoles(const QMMolecule &mol, const std::vector< std::unique_ptr< StaticSite > > &multipoles) const
Definition dftengine.cc:988
tools::EigenSystem IndependentElectronGuess(const Mat_p_Energy &H0) const
Definition dftengine.cc:183
std::string dftbasis_name_
Definition dftengine.h:127
Mat_p_Energy IntegrateExternalDensity(const QMMolecule &mol, const Orbitals &extdensity) const
std::string ecp_name_
Definition dftengine.h:128
std::string grid_name_
Definition dftengine.h:138
Eigen::MatrixXd RunAtomicDFT_unrestricted(const QMAtom &uniqueAtom) const
Definition dftengine.cc:509
void Prepare(Orbitals &orb, Index numofelectrons=-1)
Definition dftengine.cc:801
std::string initial_guess_
Definition dftengine.h:143
std::string orbfilename_
Definition dftengine.h:163
Eigen::MatrixXd AtomicGuess(const QMMolecule &mol) const
Definition dftengine.cc:697
Eigen::MatrixXd IntegrateExternalField(const QMMolecule &mol) const
Definition dftengine.cc:975
Eigen::Vector3d extfield_
Definition dftengine.h:170
std::array< Eigen::MatrixXd, 2 > CalcERIs_EXX(const Eigen::MatrixXd &MOCoeff, const Eigen::MatrixXd &Dmat, double error) const
Definition dftengine.cc:159
void Initialize(tools::Property &options)
Definition dftengine.cc:46
std::string xc_functional_name_
Definition dftengine.h:159
void CalcElDipole(const Orbitals &orb) const
Definition dftengine.cc:150
double ExternalRepulsion(const QMMolecule &mol, const std::vector< std::unique_ptr< StaticSite > > &multipoles) const
Definition dftengine.cc:949
ConvergenceAcc::options conv_opt_
Definition dftengine.h:148
std::string active_atoms_as_string_
Definition dftengine.h:173
void ConfigOrbfile(Orbitals &orb)
Definition dftengine.cc:738
void PrintMOs(const Eigen::VectorXd &MOEnergies, Log::Level level)
Definition dftengine.cc:134
AOOverlap dftAOoverlap_
Definition dftengine.h:141
Mat_p_Energy SetupH0(const QMMolecule &mol) const
Definition dftengine.cc:369
Eigen::MatrixXd OrthogonalizeGuess(const Eigen::MatrixXd &GuessMOs) const
Eigen::MatrixXd SphericalAverageShells(const Eigen::MatrixXd &dmat, const AOBasis &dftbasis) const
Definition dftengine.cc:918
bool Evaluate(Orbitals &orb)
Definition dftengine.cc:209
std::vector< std::unique_ptr< StaticSite > > * externalsites_
Definition dftengine.h:155
Vxc_Potential< Vxc_Grid > SetupVxc(const QMMolecule &mol)
Definition dftengine.cc:881
double NuclearRepulsion(const QMMolecule &mol) const
Definition dftengine.cc:902
ConvergenceAcc conv_accelerator_
Definition dftengine.h:150
double IntegratePotential(const Eigen::Vector3d &rvector) const
double IntegrateDensity(const Eigen::MatrixXd &density_matrix)
Container to hold ECPs for all atoms.
Definition ecpaobasis.h:43
std::vector< std::string > Fill(const ECPBasisSet &bs, QMMolecule &atoms)
Definition ecpaobasis.cc:69
void Load(const std::string &name)
Takes a density matrix and and an auxiliary basis set and calculates the electron repulsion integrals...
Definition ERIs.h:35
Eigen::MatrixXd CalculateERIs_3c(const Eigen::MatrixXd &DMAT) const
Definition ERIs.cc:80
Index Removedfunctions() const
Definition ERIs.h:66
std::array< Eigen::MatrixXd, 2 > CalculateERIs_EXX_4c(const Eigen::MatrixXd &DMAT, double error) const
Definition ERIs.h:61
void Initialize_4c(const AOBasis &dftbasis)
Definition ERIs.cc:32
std::array< Eigen::MatrixXd, 2 > CalculateERIs_EXX_3c(const Eigen::MatrixXd &occMos, const Eigen::MatrixXd &DMAT) const
Definition ERIs.h:43
void Initialize(const AOBasis &dftbasis, const AOBasis &auxbasis)
Definition ERIs.cc:27
Eigen::MatrixXd CalculateERIs_4c(const Eigen::MatrixXd &DMAT, double error) const
Definition ERIs.h:56
void UpdateDmats(const Eigen::MatrixXd &dmat, double DiisError, Index Iteration)
void Configure(const Eigen::MatrixXd &dmat)
void resetMatrices(Eigen::MatrixXd &J, Eigen::MatrixXd &K, const Eigen::MatrixXd &dmat)
void Start(Index iteration, double DiisError)
void UpdateCriteria(double DiisError, Index Iteration)
const Eigen::MatrixXd & getDmat_diff() const
Logger is used for thread-safe output of messages.
Definition logger.h:164
Eigen::MatrixXd & matrix()
Definition eigen.h:80
double & energy()
Definition eigen.h:81
Index cols() const
Definition eigen.h:79
Index rows() const
Definition eigen.h:78
container for molecular orbitals
Definition orbitals.h:46
void setScaHFX(double ScaHFX)
Definition orbitals.h:294
Index getNumberOfAlphaElectrons() const
Definition orbitals.h:93
void setNumberOfAlphaElectrons(Index electrons)
Definition orbitals.h:96
Eigen::MatrixXd DensityMatrixFull(const QMState &state) const
Definition orbitals.cc:140
void SetupAuxBasis(std::string aux_basis_name)
Definition orbitals.cc:99
void setECPName(const std::string &ECP)
Definition orbitals.h:106
void setXCGrid(std::string grid)
Definition orbitals.h:187
void setNumberOfOccupiedLevels(Index occupied_levels)
Definition orbitals.h:78
Index getBasisSetSize() const
Definition orbitals.h:64
void setQMEnergy(double qmenergy)
Definition orbitals.h:195
bool hasECPName() const
Definition orbitals.h:102
const tools::EigenSystem & MOs() const
Definition orbitals.h:122
const QMMolecule & QMAtoms() const
Definition orbitals.h:172
void ReadFromCpt(const std::string &filename)
Definition orbitals.cc:692
void setChargeAndSpin(Index charge, Index spin)
Definition orbitals.h:161
bool hasDFTbasisName() const
Definition orbitals.h:198
const std::string & getECPName() const
Definition orbitals.h:104
const std::string & getDFTbasisName() const
Definition orbitals.h:202
void SetupDftBasis(std::string basis_name)
Definition orbitals.cc:90
Eigen::Vector3d CalcElDipole(const QMState &state) const
Definition orbitals.cc:242
const AOBasis & getDftBasis() const
Definition orbitals.h:208
void setXCFunctionalName(std::string functionalname)
Definition orbitals.h:182
container for QM atoms
Definition qmatom.h:37
const std::string & getElement() const
Definition qmatom.h:63
Index getNuccharge() const
Definition qmatom.h:69
Identifier for QMstates. Strings like S1 are converted into enum +zero indexed int.
Definition qmstate.h:132
Class to represent Atom/Site in electrostatic.
Definition staticsite.h:37
const Eigen::Vector3d & getPos() const
Definition staticsite.h:80
Timestamp returns the current time as a string Example: cout << TimeStamp()
Definition logger.h:224
Index getGridSize() const
Definition vxc_grid.h:41
void GridSetup(const std::string &type, const QMMolecule &atoms, const AOBasis &basis)
Definition vxc_grid.cc:229
Index getBoxesSize() const
Definition vxc_grid.h:42
Mat_p_Energy IntegrateVXC(const Eigen::MatrixXd &density_matrix) const
void setXCfunctional(const std::string &functional)
static double getExactExchange(const std::string &functional)
Mediates interaction between polar and static sites.
double CalcStaticEnergy_site(const StaticSite &site1, const StaticSite &site2) const
#define XTP_LOG(level, log)
Definition logger.h:40
const double bohr2ang
Definition constants.h:49
Index getMaxThreads()
Definition eigen.h:128
bool XTP_HAS_MKL_OVERLOAD()
Definition eigen.h:41
base class for all analysis tools
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26
Level
be loud and noisy
Definition globals.h:28