votca 2026-dev
Loading...
Searching...
No Matches
dftengine.h
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#pragma once
21#ifndef VOTCA_XTP_DFTENGINE_H
22#define VOTCA_XTP_DFTENGINE_H
23
24// Standard includes
25#include <map>
26
27// VOTCA includes
29
30// Local VOTCA includes
31#include "ERIs.h"
32#include "convergenceacc.h"
33#include "hirshfeldpartition.h"
34#include "uks_convergenceacc.h"
35
36#include "ecpaobasis.h"
37#include "extended_hueckel.h"
38#include "logger.h"
39#include "qmmolecule.h"
40#include "staticsite.h"
41#include "vxc_grid.h"
42#include "vxc_potential.h"
43
44namespace votca {
45namespace xtp {
46class Orbitals;
47class DFTEngineTestAccess;
48
63
73
74class DFTEngine {
75 public:
77 void Initialize(tools::Property& options);
78
80 void setLogger(Logger* pLog) { pLog_ = pLog; }
81
85 std::vector<std::unique_ptr<StaticSite> >* externalsites) {
86 externalsites_ = externalsites;
87 }
88
89 void setEwaldgrid(const Vxc_Grid& ewaldgrid) {
90 external_ewaldgrid_ = ewaldgrid;
91 has_ewaldgrid_ = true;
92 }
93
94 // The nuclei's share of the external Ewald potential, sum_A Z_A
95 // phi(R_A). Added to E0 alongside the grid's contribution to H0 -- the
96 // grid integrates against the DENSITY and so reaches the electrons
97 // only, exactly as IntegrateExternalMultipoles pairs its AO matrix with
98 // ExternalRepulsion for the multipole route.
99 void setEwaldNuclearEnergy(double energy) { ewald_nuclear_energy_ = energy; }
100
103 bool Evaluate(Orbitals& orb);
104
135 bool RunCDFT(Orbitals& orb, HirshfeldPartition::Constraint& constraint);
136
143
145 std::string getDFTBasisName() const { return dftbasis_name_; };
148 struct SpinDensity {
149 Eigen::MatrixXd alpha;
150 Eigen::MatrixXd beta;
151
153 Eigen::MatrixXd total() const { return alpha + beta; }
154
156 Eigen::MatrixXd spin() const { return alpha - beta; }
157 };
158
164
170
174
178
179 // development path RKS vs UKS
180 void setForceUKSPath(bool force) { force_uks_path_ = force; }
181
182 private:
184
187 void Prepare(Orbitals& orb, Index numofelectrons = -1);
188
192
194 Eigen::MatrixXd OrthogonalizeGuess(const Eigen::MatrixXd& GuessMOs) const;
196 void PrintMOs(const Eigen::VectorXd& MOEnergies, Log::Level level);
198 void PrintMOsUKS(const Eigen::VectorXd& alpha_energies,
199 const Eigen::VectorXd& beta_energies,
200 Log::Level level) const;
202 void CalcElDipole(const Orbitals& orb) const;
203
206 std::array<Eigen::MatrixXd, 2> CalcERIs_EXX(const Eigen::MatrixXd& MOCoeff,
207 const Eigen::MatrixXd& Dmat,
208 double error) const;
209
211 Eigen::MatrixXd CalcERIs(const Eigen::MatrixXd& Dmat, double error) const;
212
214 void ConfigOrbfile(Orbitals& orb);
219 Eigen::MatrixXd McWeenyPurification(Eigen::MatrixXd& Dmat_in,
220 AOOverlap& overlap);
221
223 Mat_p_Energy SetupH0(const QMMolecule& mol) const;
227 const QMMolecule& mol,
228 const std::vector<std::unique_ptr<StaticSite> >& multipoles) const;
232 const Orbitals& extdensity) const;
234 Eigen::MatrixXd IntegrateExternalField(const QMMolecule& mol) const;
235
241 const Mat_p_Energy& H0, const QMMolecule& mol,
242 const Vxc_Potential<Vxc_Grid>& vxcpotential) const;
243
245 Eigen::MatrixXd AtomicGuess(const QMMolecule& mol) const;
246
248 Eigen::VectorXd BuildEHTOrbitalEnergies(const QMMolecule& mol) const;
250 Eigen::MatrixXd BuildEHTHamiltonian(const QMMolecule& mol) const;
257 const Mat_p_Energy& H0, const QMMolecule& mol,
258 const Vxc_Potential<Vxc_Grid>& vxcpotential) const;
259
282
306 Eigen::MatrixXd RunAtomicDFT_unrestricted(
307 const QMAtom& uniqueAtom, bool use_hunds_rule_occupation = false) const;
308
323 std::map<std::string, Eigen::MatrixXd> ComputeHirshfeldReferenceDensities(
324 const QMMolecule& mol) const;
325
341 std::vector<Index> atom_indices;
342 // Relative to the fragment's own neutral reference state (the sum
343 // of its atoms' nuclear charges) -- e.g. +1.0 means one electron
344 // REMOVED (a cation). Converted to an absolute target electron
345 // count once, inside BuildCDFTConstraint, matching CP2K's own
346 // internal (absolute) TARGET convention exactly -- only the
347 // user-facing options syntax is charge-relative, per the earlier
348 // design discussion on this.
349 double target_charge = 0.0;
350 double initial_lambda = 0.0;
351 // "warmstart" (default) or "fresh" -- see this field's own XML
352 // help text (dftpackage.xml) for the full reasoning. Stored as
353 // the raw string, not a bool, so an invalid value (a typo, say)
354 // is caught by the XML schema's own choices="..." validation
355 // rather than silently defaulting to one behavior or the other.
356 std::string guess_strategy = "warmstart";
357 };
358
375 const QMMolecule& mol, const CDFTConstraintSpec& spec) const;
376
378 double NuclearRepulsion(const QMMolecule& mol) const;
381 double ExternalRepulsion(
382 const QMMolecule& mol,
383 const std::vector<std::unique_ptr<StaticSite> >& multipoles) const;
386 Eigen::MatrixXd SphericalAverageShells(const Eigen::MatrixXd& dmat,
387 const AOBasis& dftbasis) const;
388
391 void TruncateBasis(Orbitals& orb, std::vector<Index>& activeatoms,
392 Mat_p_Energy& H0,
393 Eigen::MatrixXd InitialActiveDensityMatrix,
394 Eigen::MatrixXd v_embedding,
395 Eigen::MatrixXd InitialInactiveMOs);
396
399 void TruncMOsFullBasis(Orbitals& orb, std::vector<Index> activeatoms,
400 std::vector<Index> numfuncpatom);
403 Eigen::MatrixXd InsertZeroCols(Eigen::MatrixXd MOsMatrix, Index startidx,
404 Index numofzerocols);
406 Eigen::MatrixXd InsertZeroRows(Eigen::MatrixXd MOsMatrix, Index startidx,
407 Index numofzerorows);
408
410 bool EvaluateClosedShell(Orbitals& orb, const Mat_p_Energy& H0,
411 const Vxc_Potential<Vxc_Grid>& vxcpotential);
412
415 bool EvaluateUKS(Orbitals& orb, const Mat_p_Energy& H0,
416 const Vxc_Potential<Vxc_Grid>& vxcpotential);
417
467 void ComputeAndStoreForces(Orbitals& orb, const Eigen::MatrixXd& Dmat,
468 const Vxc_Potential<Vxc_Grid>& vxcpotential) const;
469
481 Eigen::MatrixXd ComputeOverlapPulayGradientUKS(
482 const QMMolecule& mol, const tools::EigenSystem& MOs_alpha,
483 const tools::EigenSystem& MOs_beta) const;
484
493 Eigen::MatrixXd ComputeNonXCGradientUKS(
494 const QMMolecule& mol, const UKSConvergenceAcc::SpinDensity& Dspin,
495 const tools::EigenSystem& MOs_alpha,
496 const tools::EigenSystem& MOs_beta) const;
497
530 Orbitals& orb, const UKSConvergenceAcc::SpinDensity& Dspin,
531 const tools::EigenSystem& MOs_alpha, const tools::EigenSystem& MOs_beta,
532 const Vxc_Potential<Vxc_Grid>& vxcpotential) const;
533
535
536 // basis sets
537 std::string auxbasis_name_;
538 std::string dftbasis_name_;
539 std::string ecp_name_;
543
545 // Pre-screening
547
548 // numerical integration Vxc
549 std::string grid_name_;
550
551 // AO Matrices
553
554 std::string initial_guess_;
555
556 // Only read from options / actually used when initial_guess_ ==
557 // "dimer_guess" -- see BuildDimerGuessFromMonomerFiles's own header
558 // comment for what this guess does and why it exists.
561
562 // Convergence
566 // DIIS variables
568 // Electron repulsion integrals
570
571 // external charges
572 std::vector<std::unique_ptr<StaticSite> >* externalsites_ = nullptr;
573
574 // exchange and correlation
575 double ScaHFX_;
577
579 // integrate external density
580 std::string orbfilename_;
581 std::string gridquality_;
582 std::string state_;
583
585 QMMolecule("molecule made of atoms participating in Active region", 1);
586
587 Eigen::Vector3d extfield_ = Eigen::Vector3d::Zero();
589
593
594 // truncation
595 Eigen::MatrixXd H0_trunc_;
597 Eigen::MatrixXd v_embedding_trunc_;
601 double E_nuc_;
603 std::vector<Index> active_and_border_atoms_;
604 std::vector<Index> numfuncpatom_;
605
606 // QMEwald
608 bool has_ewaldgrid_ = false;
610 // Spin-DFT Extension
617 bool force_uks_path_ = false;
618 // Default false to preserve existing performance for callers not
619 // using this feature -- computing forces adds real, non-trivial cost
620 // (kinetic/nuclear-attraction/overlap derivatives, RI-J gradient, full
621 // XC gradient, RI-K for hybrids) to every converged SCF, so this must
622 // be explicit opt-in, not silently always-on. Settable via the
623 // <xtpdft> options block, which flows through unmodified from
624 // XTPDFT::RunDFT() (options_) straight into DFTEngine::Initialize --
625 // confirmed directly by reading XTPDFT::ParseSpecificOptions, which
626 // only extracts a single unrelated field (temporary_file) and does
627 // not filter/transform anything else -- so this option is
628 // automatically available through the full QMPackage/XTPDFT flow with
629 // no changes needed there.
630 bool compute_forces_ = false;
631
632 // Empty by default -- the ONLY thing a standard, non-CDFT run needs
633 // to know about this member is that it is empty, checked via a
634 // single, cheap constraints_.empty() guard inside
635 // EvaluateUKS's own Fock-matrix assembly (see that function's own
636 // comment at the point the constraint potential term is added).
637 // When empty, that guard means the added term is a complete no-op:
638 // the Hamiltonian is built exactly as it always was, with no
639 // measurable overhead and no change in behavior whatsoever for any
640 // run that never touches this member. Populated only by the
641 // (not yet implemented) outer Lagrange-multiplier optimization loop,
642 // which is expected to modify each Constraint's own lambda field in
643 // place between successive, warm-started calls into EvaluateUKS --
644 // per the design discussion this grew out of (CP2K's own documented
645 // approach: restart the inner SCF from the previous trial's
646 // converged density at each new lambda, rather than a cold start).
647 std::vector<HirshfeldPartition::Constraint> constraints_;
648
649 // CDFT outer-loop (Lagrange-multiplier) control, used only by
650 // RunCDFT below -- never read by the ordinary Evaluate/EvaluateUKS
651 // path at all, so these have no bearing on any standard run either.
652 // max_cdft_iterations_/cdft_population_tolerance_ are also settable
653 // from options (see Initialize()'s own cdft.max_iterations/
654 // cdft.population_tolerance parsing) when cdft.enabled=true; their
655 // defaults here are what a directly-constructed RunCDFT call (e.g.
656 // from a test, bypassing Initialize() entirely) gets instead.
659
660 bool cdft_enabled_ = false;
662};
663
664} // namespace xtp
665} // namespace votca
666
667#endif // VOTCA_XTP_DFTENGINE_H
class to manage program options with xml serialization functionality
Definition property.h:55
Container to hold Basisfunctions for all atoms.
Definition aobasis.h:42
Electronic ground-state via Density-Functional Theory.
Definition dftengine.h:74
Eigen::MatrixXd CalcERIs(const Eigen::MatrixXd &Dmat, double error) const
Build the Coulomb matrix contribution from the current density matrix.
Definition dftengine.cc:870
Eigen::MatrixXd ComputeOverlapPulayGradientUKS(const QMMolecule &mol, const tools::EigenSystem &MOs_alpha, const tools::EigenSystem &MOs_beta) const
Definition dftengine.cc:647
void setExternalcharges(std::vector< std::unique_ptr< StaticSite > > *externalsites)
Definition dftengine.h:84
bool EvaluateTruncatedActiveRegion(Orbitals &trunc_orb)
std::string auxbasis_name_
Definition dftengine.h:537
std::string getDFTBasisName() const
Return the configured AO basis-set name for the DFT calculation.
Definition dftengine.h:145
std::string gridquality_
Definition dftengine.h:581
tools::EigenSystem ModelPotentialGuess(const Mat_p_Energy &H0, const QMMolecule &mol, const Vxc_Potential< Vxc_Grid > &vxcpotential) const
Definition dftengine.cc:890
Mat_p_Energy IntegrateExternalMultipoles(const QMMolecule &mol, const std::vector< std::unique_ptr< StaticSite > > &multipoles) const
void setEwaldgrid(const Vxc_Grid &ewaldgrid)
Definition dftengine.h:89
friend class DFTEngineTestAccess
Definition dftengine.h:183
tools::EigenSystem IndependentElectronGuess(const Mat_p_Energy &H0) const
Generate an initial guess by diagonalizing the core Hamiltonian only.
Definition dftengine.cc:879
Eigen::MatrixXd InitialActiveDmat_trunc_
Definition dftengine.h:596
void TruncMOsFullBasis(Orbitals &orb, std::vector< Index > activeatoms, std::vector< Index > numfuncpatom)
Orbitals BuildDimerGuessFromMonomerFiles(const QMMolecule &dimer_mol) const
double cdft_population_tolerance_
Definition dftengine.h:658
void ComputeAndStoreForces(Orbitals &orb, const Eigen::MatrixXd &Dmat, const Vxc_Potential< Vxc_Grid > &vxcpotential) const
Definition dftengine.cc:426
bool EvaluateClosedShell(Orbitals &orb, const Mat_p_Energy &H0, const Vxc_Potential< Vxc_Grid > &vxcpotential)
Run the restricted closed-shell SCF loop and store the converged result.
void setLogger(Logger *pLog)
Attach the logger used for SCF progress and diagnostics.
Definition dftengine.h:80
void TruncateBasis(Orbitals &orb, std::vector< Index > &activeatoms, Mat_p_Energy &H0, Eigen::MatrixXd InitialActiveDensityMatrix, Eigen::MatrixXd v_embedding, Eigen::MatrixXd InitialInactiveMOs)
void PrintMOsUKS(const Eigen::VectorXd &alpha_energies, const Eigen::VectorXd &beta_energies, Log::Level level) const
Print separate alpha and beta orbital energies for a UKS calculation.
Definition dftengine.cc:328
std::string dftbasis_name_
Definition dftengine.h:538
bool EvaluateUKS(Orbitals &orb, const Mat_p_Energy &H0, const Vxc_Potential< Vxc_Grid > &vxcpotential)
Eigen::MatrixXd RunAtomicDFT_unrestricted(const QMAtom &uniqueAtom, bool use_hunds_rule_occupation=false) const
Mat_p_Energy IntegrateExternalDensity(const QMMolecule &mol, const Orbitals &extdensity) const
std::string ecp_name_
Definition dftengine.h:539
std::string grid_name_
Definition dftengine.h:549
bool EvaluateActiveRegion(Orbitals &orb)
void Prepare(Orbitals &orb, Index numofelectrons=-1)
Vxc_Grid external_ewaldgrid_
Definition dftengine.h:607
std::string initial_guess_
Definition dftengine.h:554
std::string orbfilename_
Definition dftengine.h:580
Eigen::MatrixXd AtomicGuess(const QMMolecule &mol) const
Build an atomic-density based initial guess in the AO basis.
Eigen::MatrixXd InsertZeroRows(Eigen::MatrixXd MOsMatrix, Index startidx, Index numofzerorows)
Insert zero rows into an MO coefficient matrix at the requested position.
Eigen::MatrixXd BuildEHTHamiltonian(const QMMolecule &mol) const
Build the extended-Hückel Hamiltonian for the current molecule.
Eigen::MatrixXd IntegrateExternalField(const QMMolecule &mol) const
Integrate a homogeneous external electric field into the AO basis.
Eigen::Vector3d extfield_
Definition dftengine.h:587
std::array< Eigen::MatrixXd, 2 > CalcERIs_EXX(const Eigen::MatrixXd &MOCoeff, const Eigen::MatrixXd &Dmat, double error) const
Definition dftengine.cc:853
Eigen::MatrixXd H0_trunc_
Definition dftengine.h:595
Index NumberOfRestrictedOccupiedOrbitals() const
Definition dftengine.h:167
HirshfeldPartition::Constraint BuildCDFTConstraint(const QMMolecule &mol, const CDFTConstraintSpec &spec) const
void Initialize(tools::Property &options)
Read DFT, grid, and SCF settings from the user options tree.
Definition dftengine.cc:101
std::string xc_functional_name_
Definition dftengine.h:576
void CalcElDipole(const Orbitals &orb) const
Evaluate and print the electronic dipole moment from the final density.
Definition dftengine.cc:388
double ExternalRepulsion(const QMMolecule &mol, const std::vector< std::unique_ptr< StaticSite > > &multipoles) const
ConvergenceAcc::options conv_opt_
Definition dftengine.h:565
void SetupInvariantMatrices()
Precompute AO matrices that remain unchanged throughout the SCF procedure.
tools::EigenSystem ExtendedHuckelDFTGuess(const Mat_p_Energy &H0, const QMMolecule &mol, const Vxc_Potential< Vxc_Grid > &vxcpotential) const
std::map< std::string, Eigen::MatrixXd > ComputeHirshfeldReferenceDensities(const QMMolecule &mol) const
std::string active_atoms_as_string_
Definition dftengine.h:590
void ComputeAndStoreForcesUKS(Orbitals &orb, const UKSConvergenceAcc::SpinDensity &Dspin, const tools::EigenSystem &MOs_alpha, const tools::EigenSystem &MOs_beta, const Vxc_Potential< Vxc_Grid > &vxcpotential) const
Definition dftengine.cc:748
void ConfigOrbfile(Orbitals &orb)
Propagate basis-set, XC, and metadata settings into the orbital container.
Eigen::VectorXd BuildEHTOrbitalEnergies(const QMMolecule &mol) const
Build orbital energies used in the extended-Hückel starting guess.
std::vector< HirshfeldPartition::Constraint > constraints_
Definition dftengine.h:647
QMMolecule activemol_
Definition dftengine.h:584
void PrintMOs(const Eigen::VectorXd &MOEnergies, Log::Level level)
Print a one-spin list of orbital energies and occupations to the logger.
Definition dftengine.cc:308
void setForceUKSPath(bool force)
Definition dftengine.h:180
std::vector< Index > numfuncpatom_
Definition dftengine.h:604
AOOverlap dftAOoverlap_
Definition dftengine.h:552
std::vector< Index > active_and_border_atoms_
Definition dftengine.h:603
void setEwaldNuclearEnergy(double energy)
Definition dftengine.h:99
Mat_p_Energy SetupH0(const QMMolecule &mol) const
Assemble the one-electron core Hamiltonian for the current molecule.
tools::EigenSystem ExtendedHuckelGuess(const QMMolecule &mol) const
bool IsRestrictedOpenShell() const
Definition dftengine.h:161
Eigen::MatrixXd OrthogonalizeGuess(const Eigen::MatrixXd &GuessMOs) const
Orthonormalize an initial MO guess with respect to the AO overlap matrix.
Eigen::MatrixXd v_embedding_trunc_
Definition dftengine.h:597
Eigen::MatrixXd SphericalAverageShells(const Eigen::MatrixXd &dmat, const AOBasis &dftbasis) const
ConvergenceAcc::options BuildConvergenceOptions() const
bool Evaluate(Orbitals &orb)
Definition dftengine.cc:911
CDFTConstraintSpec cdft_constraint_spec_
Definition dftengine.h:661
Eigen::MatrixXd ComputeNonXCGradientUKS(const QMMolecule &mol, const UKSConvergenceAcc::SpinDensity &Dspin, const tools::EigenSystem &MOs_alpha, const tools::EigenSystem &MOs_beta) const
Definition dftengine.cc:695
bool RunCDFT(Orbitals &orb, HirshfeldPartition::Constraint &constraint)
std::string dimer_guess_orbB_name_
Definition dftengine.h:560
SpinDensity BuildSpinDensity(const tools::EigenSystem &MOs) const
std::vector< std::unique_ptr< StaticSite > > * externalsites_
Definition dftengine.h:572
Eigen::MatrixXd McWeenyPurification(Eigen::MatrixXd &Dmat_in, AOOverlap &overlap)
Vxc_Potential< Vxc_Grid > SetupVxc(const QMMolecule &mol)
double NuclearRepulsion(const QMMolecule &mol) const
Compute the classical nucleus-nucleus repulsion energy.
ConvergenceAcc conv_accelerator_
Definition dftengine.h:567
Eigen::MatrixXd InsertZeroCols(Eigen::MatrixXd MOsMatrix, Index startidx, Index numofzerocols)
std::string dimer_guess_orbA_name_
Definition dftengine.h:559
Container to hold ECPs for all atoms.
Definition ecpaobasis.h:43
Takes a density matrix and and an auxiliary basis set and calculates the electron repulsion integrals...
Definition ERIs.h:35
Logger is used for thread-safe output of messages.
Definition logger.h:164
Container for molecular orbitals and derived one-particle data.
Definition orbitals.h:47
container for QM atoms
Definition qmatom.h:37
Provides a means for comparing floating point numbers.
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26
Level
be loud and noisy
Definition globals.h:28
Eigen::MatrixXd spin() const
Return the spin density P^alpha - P^beta.
Definition dftengine.h:156
Eigen::MatrixXd total() const
Return the total density P = P^alpha + P^beta.
Definition dftengine.h:153