-
Notifications
You must be signed in to change notification settings - Fork 434
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Draft] DLPNO-CCSD PR #2915
base: master
Are you sure you want to change the base?
[Draft] DLPNO-CCSD PR #2915
Conversation
Co-authored-by: TiborGY <tibor.gyori@chem.u-szeged.hu> Co-authored-by: Lori A. Burns <lori.burns@gmail.com>
Just implemented some of Lori and Tibor's suggestions. I have also implemented SC-LMP2 for "weak pairs" to reduce the cost of the LCCSD computation, per the Sparse Maps II paper. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Round 2, mostly more of the same: const correctness, a few unused variables, a docstring suggestion, and a possible suggestion to eliminate a bit of code duplication,
/* Utility function for making C_DGESV calls | ||
* | ||
* C_DGESV solves AX=B for X, given symmetric NxN matrix A and NxM matrix B | ||
* B is expected in fortran layout, which complicates the call when (M > 1) | ||
* The workaround used here is to switch the layout of B before and after the call | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/* Utility function for making C_DGESV calls | |
* | |
* C_DGESV solves AX=B for X, given symmetric NxN matrix A and NxM matrix B | |
* B is expected in fortran layout, which complicates the call when (M > 1) | |
* The workaround used here is to switch the layout of B before and after the call | |
*/ |
Moving this to the .h should make it more digestible for IDEs and doc generators.
|
||
void common_init(); | ||
|
||
// Helper functions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Helper functions | |
// Helper functions | |
/// @brief Utility function for making C_DGESV calls. C_DGESV solves AX=B for X, given symmetric NxN matrix A and NxM | |
/// matrix B, but B is expected in fortran layout, which complicates the call when (M > 1). | |
/// The workaround used here is to switch the layout of B before and after the call. | |
/// | |
/// @param A On entry, the n-by-n coefficient matrix A. On exit, the factors L and U from the factorization A = P*L*U; | |
/// the unit diagonal elements of L are not stored. | |
/// @param B On entry, the n-by-m matrix of right hand side matrix B. On exit, the n-by-m solution matrix X. | |
/// \ingroup DLPNO |
Moved here from the .cc, rewritten for machine-readability.
0); | ||
auto X = orthog.basis_to_orthog_basis(); | ||
|
||
int nmo_initial = X->rowspi(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int nmo_initial = X->rowspi(0); |
Unused variable
} | ||
|
||
auto flat = std::make_shared<Vector>("flattened matrix list", total_size); | ||
double* flatp = flat->pointer(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
double* flatp = flat->pointer(); | |
double* const flatp = flat->pointer(); |
The pointer itself can be const
void DLPNOBase::copy_flat_mats(SharedVector flat, std::vector<SharedMatrix>& mat_list) { | ||
double* flatp = flat->pointer(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
void DLPNOBase::copy_flat_mats(SharedVector flat, std::vector<SharedMatrix>& mat_list) { | |
double* flatp = flat->pointer(); | |
void DLPNOBase::copy_flat_mats(const SharedVector flat, std::vector<SharedMatrix>& mat_list) { | |
const double* const flatp = flat->pointer(); |
int centerU = basisset_->function_to_center(u); | ||
double p_uu = P_i->get(u, u); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int centerU = basisset_->function_to_center(u); | |
double p_uu = P_i->get(u, u); | |
const int centerU = basisset_->function_to_center(u); | |
const double p_uu = P_i->get(u, u); |
int centerV = basisset_->function_to_center(v); | ||
double p_vv = P_i->get(v, v); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int centerV = basisset_->function_to_center(v); | |
double p_vv = P_i->get(v, v); | |
const int centerV = basisset_->function_to_center(v); | |
const double p_vv = P_i->get(v, v); |
double p_vv = P_i->get(v, v); | ||
|
||
// off-diag pops (p_uv) split between u and v prop to diag pops | ||
double p_uv = P_i->get(u, v); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
double p_uv = P_i->get(u, v); | |
const double p_uv = P_i->get(u, v); |
psi4/src/psi4/dlpno/dlpnobase.cc
Outdated
if (options_.get_str("DLPNO_ALGORITHM") == "MP2") { | ||
for (size_t i = 0, ij = 0; i < naocc; i++) { | ||
for (size_t j = 0; j < naocc; j++) { | ||
bool overlap_big = (DOI_ij_->get(i, j) > options_.get_double("T_CUT_DO_ij")); | ||
bool energy_big = (fabs(dipole_pair_e_bound_->get(i, j)) > options_.get_double("T_CUT_PRE")); | ||
|
||
if (overlap_big || energy_big) { | ||
i_j_to_ij_[i].push_back(ij); | ||
ij_to_i_j_.push_back(std::make_pair(i, j)); | ||
ij++; | ||
} else { | ||
de_dipole_ += dipole_pair_e_->get(i, j); | ||
i_j_to_ij_[i].push_back(-1); | ||
} | ||
} | ||
} | ||
} else { | ||
for (size_t i = 0, ij = 0; i < naocc; i++) { | ||
for (size_t j = 0; j < naocc; j++) { | ||
bool overlap_big = (DOI_ij_->get(i, j) > options_.get_double("T_CUT_DO_ij")); | ||
bool energy_big = (fabs(dipole_pair_e_bound_->get(i, j)) > options_.get_double("T_CUT_PRE")); | ||
|
||
if ((i == j) || (overlap_big && energy_big)) { | ||
i_j_to_ij_[i].push_back(ij); | ||
ij_to_i_j_.push_back(std::make_pair(i, j)); | ||
ij++; | ||
} else { | ||
if (overlap_big || energy_big) | ||
weak_pairs_.push_back(std::make_pair(i,j)); | ||
else | ||
de_dipole_ += dipole_pair_e_->get(i, j); | ||
|
||
i_j_to_ij_[i].push_back(-1); | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (options_.get_str("DLPNO_ALGORITHM") == "MP2") { | |
for (size_t i = 0, ij = 0; i < naocc; i++) { | |
for (size_t j = 0; j < naocc; j++) { | |
bool overlap_big = (DOI_ij_->get(i, j) > options_.get_double("T_CUT_DO_ij")); | |
bool energy_big = (fabs(dipole_pair_e_bound_->get(i, j)) > options_.get_double("T_CUT_PRE")); | |
if (overlap_big || energy_big) { | |
i_j_to_ij_[i].push_back(ij); | |
ij_to_i_j_.push_back(std::make_pair(i, j)); | |
ij++; | |
} else { | |
de_dipole_ += dipole_pair_e_->get(i, j); | |
i_j_to_ij_[i].push_back(-1); | |
} | |
} | |
} | |
} else { | |
for (size_t i = 0, ij = 0; i < naocc; i++) { | |
for (size_t j = 0; j < naocc; j++) { | |
bool overlap_big = (DOI_ij_->get(i, j) > options_.get_double("T_CUT_DO_ij")); | |
bool energy_big = (fabs(dipole_pair_e_bound_->get(i, j)) > options_.get_double("T_CUT_PRE")); | |
if ((i == j) || (overlap_big && energy_big)) { | |
i_j_to_ij_[i].push_back(ij); | |
ij_to_i_j_.push_back(std::make_pair(i, j)); | |
ij++; | |
} else { | |
if (overlap_big || energy_big) | |
weak_pairs_.push_back(std::make_pair(i,j)); | |
else | |
de_dipole_ += dipole_pair_e_->get(i, j); | |
i_j_to_ij_[i].push_back(-1); | |
} | |
} | |
} | |
} | |
const bool DLPNO_MP2 = (options_.get_str("DLPNO_ALGORITHM") == "MP2"); | |
for (size_t i = 0, ij = 0; i < naocc; i++) { | |
for (size_t j = 0; j < naocc; j++) { | |
const bool overlap_big = (DOI_ij_->get(i, j) > options_.get_double("T_CUT_DO_ij")); | |
const bool energy_big = (fabs(dipole_pair_e_bound_->get(i, j)) > options_.get_double("T_CUT_PRE")); | |
if(DLPNO_MP2){ | |
if (overlap_big || energy_big) { | |
i_j_to_ij_[i].push_back(ij); | |
ij_to_i_j_.push_back(std::make_pair(i, j)); | |
ij++; | |
} else { | |
de_dipole_ += dipole_pair_e_->get(i, j); | |
i_j_to_ij_[i].push_back(-1); | |
} | |
}else{ | |
if ((i == j) || (overlap_big && energy_big)) { | |
i_j_to_ij_[i].push_back(ij); | |
ij_to_i_j_.push_back(std::make_pair(i, j)); | |
ij++; | |
} else { | |
if (overlap_big || energy_big) | |
weak_pairs_.push_back(std::make_pair(i, j)); | |
else | |
de_dipole_ += dipole_pair_e_->get(i, j); | |
i_j_to_ij_[i].push_back(-1); | |
} | |
} | |
} | |
} |
This would eliminate some code duplication. Thoughts?
} | ||
} | ||
|
||
int n_lmo_pairs = ij_to_i_j_.size(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int n_lmo_pairs = ij_to_i_j_.size(); | |
const int n_lmo_pairs = ij_to_i_j_.size(); |
One thing we will need to discuss up-front, is what to do with a DLPNO-CC Psi4NumPy implementation. I know @JonathonMisiewicz talked about this in a previous PR, and I see his point. It would be useful to have an easier-to-understand reference for DLPNO-CC somewhere, especially to help others understand the DLPNO formalism. A lot of the work done in this PR was previously prototyped in Python, so that gives us a start in a potential Psi4NumPy implementation. |
Description
HERE IT IS!!! This is a draft of the DLPNO-CCSD PR that will be coming in the next few months. The purpose of this is for the developers and research groups to be able to run and test DLPNO-CCSD before it is officially part of the code.
Credit to @JoseMadriaga for the derivations
LocalCCSD1to10.pdf
Useful References:
Original DLPNO-CCSD Paper
Sparse Maps II Paper
Example Input File
Results (Waterclusters in TZ)
[Speedups, relative to DF-CCSD]
[Percent Correlation Energy Recovered, relative to DF-CCSD, all >= 99.9%]
User API & Changelog headlines
Dev notes & details
Questions
Checklist
Status