Skip to content
This repository has been archived by the owner on Sep 28, 2021. It is now read-only.

Incremental fmatrix #716

Merged
merged 26 commits into from
Jul 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b96e12e
incremental fmatrix and option changes
jenswehnerteaching Oct 20, 2020
fcd30ba
merged and fixed
JensWehner Jan 16, 2021
a5170f7
Merge branch 'libecpint' into incremental_fmatrix
JensWehner Jan 16, 2021
d46e445
fixed settings
JensWehner Jan 16, 2021
5db14bb
merged
JensWehner Jun 18, 2021
c9bbc20
refactored incremental fock
JensWehner Jun 28, 2021
996cc91
Merge branch 'master' into incremental_fmatrix
JensWehner Jun 28, 2021
03eaf49
Merge branch 'master' into incremental_fmatrix
JensWehner Jun 28, 2021
7e97e58
Update CHANGELOG.rst
votca-bot Jun 28, 2021
fcf4fcf
Format code using clang-format version 12.0.0 (Fedora 12.0.0-2.fc34)
votca-bot Jun 28, 2021
deb6063
added tests
JensWehner Jun 28, 2021
8423389
Merge branch 'incremental_fmatrix' of https://github.com/votca/xtp in…
JensWehner Jun 28, 2021
810d242
added defaults
JensWehner Jun 28, 2021
72ce365
Format code using clang-format version 12.0.0 (Fedora 12.0.0-2.fc34)
votca-bot Jun 28, 2021
8d8606b
made options clearer
JensWehner Jun 28, 2021
064f0ba
Merge branch 'incremental_fmatrix' of https://github.com/votca/xtp in…
JensWehner Jun 28, 2021
6a12080
updated logging output
JensWehner Jun 28, 2021
bfa20e8
Format code using clang-format version 12.0.0 (Fedora 12.0.0-2.fc34)
votca-bot Jun 28, 2021
206daf7
remove cout
JensWehner Jun 29, 2021
2b4adbf
Merge branch 'incremental_fmatrix' of https://github.com/votca/xtp in…
JensWehner Jun 29, 2021
9c6aa7a
Format code using clang-format version 12.0.0 (Fedora 12.0.0-2.fc34)
votca-bot Jun 29, 2021
bafeab8
fixed test
JensWehner Jun 29, 2021
7efdb4e
large fingers
JensWehner Jun 29, 2021
2ef45e2
Format code using clang-format version 12.0.0 (Fedora 12.0.0-2.fc34)
votca-bot Jun 29, 2021
5197861
Update CHANGELOG.rst
JensWehner Jun 30, 2021
769095e
Merge branch 'master' into incremental_fmatrix
JensWehner Jul 1, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Version 2022-dev
- updated benchmark (#714)
- reworked commandline options (#715)
- renamed cmd line arguments in xtp_parallel (#718)
- added incremental Fock matrix building (#716)
- disable codeql check in GitHub Actions (#720)

Version 2021.1 (released XX.03.21)
Expand Down
106 changes: 106 additions & 0 deletions include/votca/xtp/IncrementalFockBuilder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* Copyright 2009-2020 The VOTCA Development Team
* (http://www.votca.org)
*
* Licensed under the Apache License, Version 2.0 (the "License")
*
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#pragma once
#ifndef VOTCA_XTP_INCREMENTALFOCKBUILDER_H
#define VOTCA_XTP_INCREMENTALFOCKBUILDER_H

#include "votca/xtp/logger.h"
#include <votca/tools/types.h>
namespace votca {
namespace xtp {

// Small Wrapper class to build incremental fock matrix
class IncrementalFockBuilder {
public:
IncrementalFockBuilder(Logger& log, double start_threshold,
Index fock_matrix_reset)
: log_(log),
start_incremental_F_threshold_(start_threshold),
fock_matrix_reset_(fock_matrix_reset) {}

void Configure(const Eigen::MatrixXd& dmat) {
Ddiff_ = dmat;
Dlast_ = dmat;
}

void Start(Index iteration, double DiisError) {
if (!incremental_Fbuild_started_ &&
DiisError < start_incremental_F_threshold_) {
incremental_Fbuild_started_ = true;
reset_incremental_fock_formation_ = false;
last_reset_iteration_ = iteration - 1;
next_reset_threshold_ = DiisError / 10.0;
XTP_LOG(Log::error, log_)
<< TimeStamp() << " Using incremental 4c build from here"
<< std::flush;
}
Comment on lines +44 to +53
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this if have an else with an error something like "already started"? Or can we do without the if?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I now see how you use it in the loop, but I don't understand the logic now, it seems that as soon as you have called Start incremental_Fbuild_started will be true and will not be turned to false again? In that case this function block only executes once, so why not call it once?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because we want to start it in the middle of the iterations, when the threshold is reached and not before we start the SCF. So each SCF cycle before it starts it has to be checked if it should start.

}

void resetMatrices(Eigen::MatrixXd& J, Eigen::MatrixXd& K,
const Eigen::MatrixXd& dmat) {
if (reset_incremental_fock_formation_ || !incremental_Fbuild_started_) {
J.setZero();
K.setZero();
Ddiff_ = dmat;
}
}

const Eigen::MatrixXd& getDmat_diff() const { return Ddiff_; }

void UpdateCriteria(double DiisError, Index Iteration) {
if (reset_incremental_fock_formation_ && incremental_Fbuild_started_) {
reset_incremental_fock_formation_ = false;
last_reset_iteration_ = Iteration;
next_reset_threshold_ = DiisError / 10.0;
XTP_LOG(Log::error, log_)
<< TimeStamp() << " Reset incremental 4c build" << std::flush;
}
}

void UpdateDmats(const Eigen::MatrixXd& dmat, double DiisError,
Index Iteration) {
if (DiisError < next_reset_threshold_ ||
Iteration - last_reset_iteration_ > fock_matrix_reset_) {
reset_incremental_fock_formation_ = true;
}
Ddiff_ = dmat - Dlast_;
Dlast_ = dmat;
}

private:
Logger& log_;
double start_incremental_F_threshold_; // Diis error from which to start
// using incremental builds
Index fock_matrix_reset_; // After how many iterations the fock matrix should
// be reset regardless

Eigen::MatrixXd Ddiff_;
Eigen::MatrixXd Dlast_;

bool reset_incremental_fock_formation_ = false;
bool incremental_Fbuild_started_ = false;
double next_reset_threshold_ = 0.0;
Index last_reset_iteration_ = 0;
}; // namespace xtp

} // namespace xtp
} // namespace votca

#endif // VOTCA_XTP_INCREMENTALFOCKBUILDER_H
3 changes: 1 addition & 2 deletions include/votca/xtp/dftengine.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,7 @@ class DFTEngine {

bool with_ecp_;

std::string four_center_method_; // direct | cache

Index fock_matrix_reset_;
// Pre-screening
double screening_eps_;

Expand Down
3 changes: 1 addition & 2 deletions share/xtp/data/qmpackage_defaults.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,9 @@
<method help="This is automatically fill with the functional and basis set"/>
</orca>
<xtpdft>
<with_screening help="screening" default="true" choices="bool">true</with_screening>
<use_external_density help="whether or not to use a precomputed external density" default="false" choices="bool"/>
<screening_eps help="screening eps" default="1e-9" choices="float+">1e-9</screening_eps>
<four_center_method help="method to compute the four-center integrals" default="cache" choices="cache,direct,RI">RI</four_center_method>
<fock_matrix_reset help="how often the fock matrix should be reset" default="5" choices="int+">5</fock_matrix_reset>
<convergence>
<energy help="DeltaE at which calculation is converged" unit="hartree" choices="float+" default="1E-7">1e-7</energy>
<method help="Main method to use for convergence accelertation" choices="DIIS,mixing" default="DIIS">DIIS</method>
Expand Down
75 changes: 51 additions & 24 deletions src/libxtp/dftengine/dftengine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <votca/tools/elements.h>

// Local VOTCA includes
#include "votca/xtp/IncrementalFockBuilder.h"
#include "votca/xtp/aomatrix.h"
#include "votca/xtp/aopotential.h"
#include "votca/xtp/density_integration.h"
Expand All @@ -34,7 +35,6 @@
#include "votca/xtp/logger.h"
#include "votca/xtp/mmregion.h"
#include "votca/xtp/orbitals.h"

using boost::format;
using namespace boost::filesystem;
using namespace std;
Expand All @@ -54,13 +54,11 @@ void DFTEngine::Initialize(Property& options) {
auxbasis_name_ = options.get(key + ".auxbasisset").as<string>();
}

four_center_method_ =
options.get(key_xtpdft + ".four_center_method").as<std::string>();

if (four_center_method_ != "RI") {
if (!auxbasis_name_.empty()) {
screening_eps_ = options.get(key_xtpdft + ".screening_eps").as<double>();
fock_matrix_reset_ =
options.get(key_xtpdft + ".fock_matrix_reset").as<Index>();
}

if (options.get(key + ".use_ecp").as<bool>()) {
ecp_name_ = options.get(key + ".ecp").as<string>();
with_ecp_ = true;
Expand Down Expand Up @@ -153,7 +151,7 @@ void DFTEngine::CalcElDipole(const Orbitals& orb) const {
std::array<Eigen::MatrixXd, 2> DFTEngine::CalcERIs_EXX(
const Eigen::MatrixXd& MOCoeff, const Eigen::MatrixXd& Dmat,
double error) const {
if (four_center_method_ == "RI") {
if (!auxbasis_name_.empty()) {
if (conv_accelerator_.getUseMixing() || MOCoeff.rows() == 0) {
return ERIs_.CalculateERIs_EXX_3c(Eigen::MatrixXd::Zero(0, 0), Dmat);
} else {
Expand All @@ -168,7 +166,7 @@ std::array<Eigen::MatrixXd, 2> DFTEngine::CalcERIs_EXX(

Eigen::MatrixXd DFTEngine::CalcERIs(const Eigen::MatrixXd& Dmat,
double error) const {
if (four_center_method_ == "RI") {
if (!auxbasis_name_.empty()) {
return ERIs_.CalculateERIs_3c(Dmat);
} else {
return ERIs_.CalculateERIs_4c(Dmat, error);
Expand Down Expand Up @@ -240,6 +238,20 @@ bool DFTEngine::Evaluate(Orbitals& orb) {
"----------------------------"
<< flush;

Eigen::MatrixXd J = Eigen::MatrixXd::Zero(Dmat.rows(), Dmat.cols());
Eigen::MatrixXd K;
if (ScaHFX_ > 0) {
K = Eigen::MatrixXd::Zero(Dmat.rows(), Dmat.cols());
}

double start_incremental_F_threshold = 1e-4;
if (!auxbasis_name_.empty()) {
start_incremental_F_threshold = 0.0; // Disable if RI is used
}
IncrementalFockBuilder incremental_fock(*pLog_, start_incremental_F_threshold,
fock_matrix_reset_);
incremental_fock.Configure(Dmat);

for (Index this_iter = 0; this_iter < max_iter_; this_iter++) {
XTP_LOG(Log::error, *pLog_) << flush;
XTP_LOG(Log::error, *pLog_) << TimeStamp() << " Iteration " << this_iter + 1
Expand All @@ -254,20 +266,29 @@ bool DFTEngine::Evaluate(Orbitals& orb) {
double Etwo = e_vxc.energy();
double exx = 0.0;

incremental_fock.Start(this_iter, conv_accelerator_.getDIIsError());
incremental_fock.resetMatrices(J, K, Dmat);
incremental_fock.UpdateCriteria(conv_accelerator_.getDIIsError(),
this_iter);

double integral_error =
std::min(conv_accelerator_.getDIIsError() * 1e-5, 1e-5);
if (ScaHFX_ > 0) {
std::array<Eigen::MatrixXd, 2> both =
CalcERIs_EXX(MOs.eigenvectors(), Dmat, 1e-12);
H += both[0];
Etwo += 0.5 * Dmat.cwiseProduct(both[0]).sum();
H += 0.5 * ScaHFX_ * both[1];
exx = ScaHFX_ / 4 * Dmat.cwiseProduct(both[1]).sum();
std::array<Eigen::MatrixXd, 2> both = CalcERIs_EXX(
MOs.eigenvectors(), incremental_fock.getDmat_diff(), integral_error);
J += both[0];
H += J;
Etwo += 0.5 * Dmat.cwiseProduct(J).sum();
K += both[1];
H += 0.5 * ScaHFX_ * K;
exx = 0.25 * ScaHFX_ * Dmat.cwiseProduct(K).sum();
XTP_LOG(Log::info, *pLog_)
<< TimeStamp() << " Filled F+K matrix " << flush;
} else {
Eigen::MatrixXd Hartree = CalcERIs(Dmat, 1e-12);
J += CalcERIs(incremental_fock.getDmat_diff(), integral_error);
XTP_LOG(Log::info, *pLog_) << TimeStamp() << " Filled F matrix " << flush;
H += Hartree;
Etwo += 0.5 * Dmat.cwiseProduct(Hartree).sum();
H += J;
Etwo += 0.5 * Dmat.cwiseProduct(J).sum();
}

Etwo += exx;
Expand All @@ -288,6 +309,8 @@ bool DFTEngine::Evaluate(Orbitals& orb) {
<< std::setprecision(12) << totenergy << flush;

Dmat = conv_accelerator_.Iterate(Dmat, H, MOs, totenergy);
incremental_fock.UpdateDmats(Dmat, conv_accelerator_.getDIIsError(),
this_iter);

PrintMOs(MOs.eigenvalues(), Log::info);

Expand Down Expand Up @@ -439,7 +462,7 @@ void DFTEngine::SetupInvariantMatrices() {
conv_accelerator_.setOverlap(dftAOoverlap_, 1e-8);
conv_accelerator_.PrintConfigOptions();

if (four_center_method_ == "RI") {
if (!auxbasis_name_.empty()) {
// prepare invariant part of electron repulsion integrals
ERIs_.Initialize(dftbasis_, auxbasis_);
XTP_LOG(Log::info, *pLog_)
Expand Down Expand Up @@ -558,12 +581,16 @@ Eigen::MatrixXd DFTEngine::RunAtomicDFT_unrestricted(
double E_two_alpha = 0.0;
double E_two_beta = 0.0;

double integral_error = std::min(1e-5 * 0.5 *
(Convergence_alpha.getDIIsError() +
Convergence_beta.getDIIsError()),
1e-5);
if (ScaHFX_ > 0) {
std::array<Eigen::MatrixXd, 2> both_alpha =
ERIs_atom.CalculateERIs_EXX_4c(dftAOdmat_alpha, 1e-15);
ERIs_atom.CalculateERIs_EXX_4c(dftAOdmat_alpha, integral_error);

std::array<Eigen::MatrixXd, 2> both_beta =
ERIs_atom.CalculateERIs_EXX_4c(dftAOdmat_beta, 1e-15);
ERIs_atom.CalculateERIs_EXX_4c(dftAOdmat_beta, integral_error);
Eigen::MatrixXd Hartree = both_alpha[0] + both_beta[0];
E_two_alpha += Hartree.cwiseProduct(dftAOdmat_alpha).sum();
E_two_beta += Hartree.cwiseProduct(dftAOdmat_beta).sum();
Expand All @@ -573,8 +600,8 @@ Eigen::MatrixXd DFTEngine::RunAtomicDFT_unrestricted(
H_beta += Hartree + ScaHFX_ * both_beta[1];

} else {
Eigen::MatrixXd Hartree =
ERIs_atom.CalculateERIs_4c(dftAOdmat_alpha + dftAOdmat_beta, 1e-15);
Eigen::MatrixXd Hartree = ERIs_atom.CalculateERIs_4c(
dftAOdmat_alpha + dftAOdmat_beta, integral_error);
E_two_alpha += Hartree.cwiseProduct(dftAOdmat_alpha).sum();
E_two_beta += Hartree.cwiseProduct(dftAOdmat_beta).sum();
H_alpha += Hartree;
Expand Down Expand Up @@ -708,7 +735,7 @@ void DFTEngine::ConfigOrbfile(Orbitals& orb) {
if (with_ecp_) {
orb.setECPName(ecp_name_);
}
if (four_center_method_ == "RI") {
if (!auxbasis_name_.empty()) {
orb.setAuxbasisName(auxbasis_name_);
}

Expand Down Expand Up @@ -772,7 +799,7 @@ void DFTEngine::Prepare(QMMolecule& mol) {
<< TimeStamp() << " Loaded DFT Basis Set " << dftbasis_name_ << " with "
<< dftbasis_.AOBasisSize() << " functions" << flush;

if (four_center_method_ == "RI") {
if (!auxbasis_name_.empty()) {
BasisSet auxbasisset;
auxbasisset.Load(auxbasis_name_);
auxbasis_.Fill(auxbasisset, mol);
Expand Down
1 change: 0 additions & 1 deletion src/libxtp/qmpackage.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ using std::flush;
tools::Property QMPackage::ParseCommonOptions(const tools::Property& options) {

std::string key = "package";

settings_.read_property(options, key);

if (tools::VotcaShareSet()) {
Expand Down
2 changes: 1 addition & 1 deletion src/libxtp/qmpackages/xtpdft.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ namespace xtp {
using namespace std;

void XTPDFT::Initialize(const tools::Property& options) {
const std::string& job_name =
const std::string job_name =
options.ifExistsReturnElseReturnDefault<std::string>("job_name", "votca");
log_file_name_ = job_name + ".orb";
mo_file_name_ = log_file_name_;
Expand Down
1 change: 1 addition & 0 deletions src/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ if(ENABLE_TESTING)
list(APPEND test_cases test_orbreorder)
list(APPEND test_cases test_molden)
list(APPEND test_cases test_gaussianwriter)
list(APPEND test_cases test_incrementalfockbuilder)
if(USE_CUDA)
list(APPEND test_cases test_cudapipeline)
list(APPEND test_cases test_cudamatrix)
Expand Down
19 changes: 7 additions & 12 deletions src/tests/test_dftengine.cc
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@


/*
* Copyright 2009-2020 The VOTCA Development Team (http://www.votca.org)
*
Expand Down Expand Up @@ -31,14 +33,6 @@ using namespace votca::xtp;
BOOST_AUTO_TEST_SUITE(dftengine_test)

QMMolecule Water() {
std::ofstream xyzfile("molecule.xyz");
xyzfile << "3" << std::endl;
xyzfile << "Water molecule" << std::endl;
xyzfile << "O 0.00000 0.00000 0.11779" << std::endl;
xyzfile << "H 0.00000 0.75545 -0.47116" << std::endl;
xyzfile << "H 0.00000 -0.75545 -0.47116" << std::endl;

xyzfile.close();
QMMolecule mol(" ", 1);
mol.LoadFromFile(std::string(XTP_TEST_DATA_FOLDER) + "/espfit/molecule.xyz");
return mol;
Expand Down Expand Up @@ -119,7 +113,7 @@ BOOST_AUTO_TEST_CASE(dft_full) {
Orbitals orb;
orb.QMAtoms() = Water();

std::ofstream xml("dftengine.xml");
std::ofstream xml("dftengine2.xml");
xml << "<package>" << std::endl;
xml << "<spin>1</spin>" << std::endl;
xml << "<name>xtp</name>" << std::endl;
Expand All @@ -134,7 +128,7 @@ BOOST_AUTO_TEST_CASE(dft_full) {
xml << "<use_external_density>false</use_external_density>" << std::endl;
xml << "<with_screening choices=\"bool\">true</with_screening>\n";
xml << "<screening_eps choices=\"float+\">1e-9</screening_eps>\n";
xml << "<four_center_method>cache</four_center_method>\n";
xml << "<fock_matrix_reset>5</fock_matrix_reset>\n";
xml << "<convergence>" << std::endl;
xml << " <energy>1e-7</energy>" << std::endl;
xml << " <method>DIIS</method>" << std::endl;
Expand All @@ -156,7 +150,7 @@ BOOST_AUTO_TEST_CASE(dft_full) {
xml << "</package>" << std::endl;
xml.close();
votca::tools::Property prop;
prop.LoadFromXML("dftengine.xml");
prop.LoadFromXML("dftengine2.xml");

Logger log;
dft.setLogger(&log);
Expand Down Expand Up @@ -234,7 +228,8 @@ BOOST_AUTO_TEST_CASE(density_guess) {
xml << "<use_external_density>false</use_external_density>" << std::endl;
xml << "<with_screening choices=\"bool\">true</with_screening>\n";
xml << "<screening_eps choices=\"float+\">1e-9</screening_eps>\n";
xml << "<four_center_method>cache</four_center_method>\n";
xml << "<four_center_method>direct</four_center_method>\n";
xml << "<fock_matrix_reset>5</fock_matrix_reset>\n";
xml << "<convergence>" << std::endl;
xml << " <energy>1e-7</energy>" << std::endl;
xml << " <method>DIIS</method>" << std::endl;
Expand Down
Loading