From d16ce188c70491d9c8ccd7e711afebb44deba55c Mon Sep 17 00:00:00 2001 From: Susi Lehtola Date: Fri, 2 Feb 2024 07:13:58 +0200 Subject: [PATCH 1/2] Add helper functions to evaluate exchange matrix with occupations given as armadillo vectors --- src/density_fitting.cpp | 8 ++++++++ src/density_fitting.h | 5 +++++ src/erichol.cpp | 8 ++++++++ src/erichol.h | 4 ++++ 4 files changed, 25 insertions(+) diff --git a/src/density_fitting.cpp b/src/density_fitting.cpp index 343ea4ce..27fd81c9 100644 --- a/src/density_fitting.cpp +++ b/src/density_fitting.cpp @@ -1095,6 +1095,10 @@ arma::mat DensityFit::calcK(const arma::mat & Corig, const std::vector & return K; } +arma::mat DensityFit::calcK(const arma::mat & Corig, const arma::vec & occo, size_t fitmem) const { + return calcK(Corig, arma::conv_to>::from(occo), fitmem); +} + arma::cx_mat DensityFit::calcK(const arma::cx_mat & Corig, const std::vector & occo, size_t fitmem) const { if(Corig.n_rows != Nbf) { std::ostringstream oss; @@ -1136,6 +1140,10 @@ arma::cx_mat DensityFit::calcK(const arma::cx_mat & Corig, const std::vector>::from(occo), fitmem); +} + size_t DensityFit::get_Norb() const { return Nbf; } diff --git a/src/density_fitting.h b/src/density_fitting.h index f2af04df..fe396b5b 100644 --- a/src/density_fitting.h +++ b/src/density_fitting.h @@ -155,6 +155,11 @@ class DensityFit { /// Get exchange matrix from orbitals with occupation numbers occs arma::cx_mat calcK(const arma::cx_mat & C, const std::vector & occs, size_t fitmem) const; + /// Get exchange matrix from orbitals with occupation numbers occs + arma::mat calcK(const arma::mat & C, const arma::vec & occs, size_t fitmem) const; + /// Get exchange matrix from orbitals with occupation numbers occs + arma::cx_mat calcK(const arma::cx_mat & C, const arma::vec & occs, size_t fitmem) const; + /// Get the number of orbital functions size_t get_Norb() const; /// Get the number of auxiliary functions diff --git a/src/erichol.cpp b/src/erichol.cpp index e36471fb..efdf2a21 100644 --- a/src/erichol.cpp +++ b/src/erichol.cpp @@ -768,6 +768,10 @@ arma::mat ERIchol::calcK(const arma::mat & C, const std::vector & occs) return K; } +arma::mat ERIchol::calcK(const arma::mat & C, const arma::vec & occs) const { + return calcK(C, arma::conv_to>::from(occs)); +} + arma::cx_mat ERIchol::calcK(const arma::cx_mat & C, const std::vector & occs) const { arma::cx_mat K(C.n_rows,C.n_rows); K.zeros(); @@ -788,6 +792,10 @@ arma::cx_mat ERIchol::calcK(const arma::cx_mat & C, const std::vector & return K; } +arma::cx_mat ERIchol::calcK(const arma::cx_mat & C, const arma::vec & occs) const { + return calcK(C, arma::conv_to>::from(occs)); +} + void ERIchol::B_matrix(arma::mat & Br) const { Br.zeros(Nbf*Nbf,B.n_cols); for(size_t P=0;P & occs) const; + /// Form exchange matrix + arma::mat calcK(const arma::mat & C, const arma::vec & occs) const; /// Form exchange matrix arma::cx_mat calcK(const arma::cx_vec & C) const; /// Form exchange matrix arma::cx_mat calcK(const arma::cx_mat & C, const std::vector & occs) const; + /// Form exchange matrix + arma::cx_mat calcK(const arma::cx_mat & C, const arma::vec & occs) const; /// Get full B matrix void B_matrix(arma::mat & B) const; From 774d7cd76eb5ddabb653e60d00fef4898e14ed95 Mon Sep 17 00:00:00 2001 From: Susi Lehtola Date: Fri, 2 Feb 2024 07:14:54 +0200 Subject: [PATCH 2/2] Move find_identical_nuclei() function from guess to a proper function in BasisSet --- src/basis.cpp | 94 ++++++++++++++++++++++++++++++++++++++++++++-- src/basis.h | 2 + src/guess.cpp | 81 +-------------------------------------- src/guess.h | 3 -- src/hirshfeld.cpp | 2 +- src/hirshfeldi.cpp | 2 +- 6 files changed, 96 insertions(+), 88 deletions(-) diff --git a/src/basis.cpp b/src/basis.cpp index 9a0f65c8..a7cbc8d9 100644 --- a/src/basis.cpp +++ b/src/basis.cpp @@ -1770,9 +1770,17 @@ arma::ivec BasisSet::get_m_values() const { arma::ivec BasisSet::unique_m_values() const { // Find unique m values arma::ivec mval(get_m_values()); - arma::uvec muni_idx(arma::find_unique(mval)); - arma::ivec muni(mval(muni_idx)); - return arma::sort(muni); + arma::sword mmin=0; + arma::sword mmax=arma::max(arma::abs(mval)); + + std::vector mvals; + mvals.push_back(0); + for(int am=1;am<=mmax;am++) { + mvals.push_back(-am); + mvals.push_back(am); + } + + return arma::conv_to::from(mvals); } std::map BasisSet::unique_m_map() const { @@ -4214,3 +4222,83 @@ arma::ivec m_classify(const arma::mat & C, const arma::ivec & mv) { return oclass; } + + std::vector< std::vector > BasisSet::find_identical_nuclei() const { + // Index list + std::vector< std::vector > ret; + + // Loop over nuclei + for(size_t i=0;i shi=get_funcs(i); + + // Check if there something already on the list + bool found=false; + for(size_t j=0;j shj=get_funcs(ret[j][0]); + + // Check nuclear type + if(get_symbol(i).compare(get_symbol(ret[j][0]))!=0) + continue; + // Check charge status + if(get_nucleus(i).Q != get_nucleus(ret[j][0]).Q) + continue; + + // Do comparison + if(shi.size()!=shj.size()) + continue; + else { + + bool same=true; + for(size_t ii=0;ii lhc=shi[ii].get_contr(); + std::vector rhc=shj[ii].get_contr(); + + if(lhc.size() != rhc.size()) { + same=false; + break; + } + for(size_t ic=0;ic tmp; + tmp.push_back(i); + + ret.push_back(tmp); + } + } + + return ret; +} diff --git a/src/basis.h b/src/basis.h index 3597ed5c..f6377b0f 100644 --- a/src/basis.h +++ b/src/basis.h @@ -496,6 +496,8 @@ class BasisSet { /// Find "identical" shells in basis set. std::vector< std::vector > find_identical_shells() const; + /// Find "identical" nuclei + std::vector< std::vector > find_identical_nuclei() const; }; /// Compute three-center overlap integral diff --git a/src/guess.cpp b/src/guess.cpp index 036573bd..4cb7137e 100644 --- a/src/guess.cpp +++ b/src/guess.cpp @@ -180,7 +180,7 @@ arma::mat atomic_guess_wrk(const BasisSet & basis, atomic_guess_t type, double K // the way that the basis sets coincide. // Get list of identical nuclei - std::vector< std::vector > idnuc=identical_nuclei(basis); + std::vector< std::vector > idnuc=basis.find_identical_nuclei(); // Amount of basis functions is size_t Nbf=basis.get_Nbf(); @@ -422,85 +422,6 @@ arma::mat minimal_basis_projection(const BasisSet & basis) { return atomic_guess_wrk(basis,FORM_MINBAS,0.0); } -std::vector< std::vector > identical_nuclei(const BasisSet & basis) { - // Returned list - std::vector< std::vector > ret; - - // Loop over nuclei - for(size_t i=0;i shi=basis.get_funcs(i); - - // Check if there something already on the list - bool found=false; - for(size_t j=0;j shj=basis.get_funcs(ret[j][0]); - - // Check nuclear type - if(basis.get_symbol(i).compare(basis.get_symbol(ret[j][0]))!=0) - continue; - // Check charge status - if(basis.get_nucleus(i).Q != basis.get_nucleus(ret[j][0]).Q) - continue; - - // Do comparison - if(shi.size()!=shj.size()) - continue; - else { - - bool same=true; - for(size_t ii=0;ii lhc=shi[ii].get_contr(); - std::vector rhc=shj[ii].get_contr(); - - if(lhc.size() != rhc.size()) { - same=false; - break; - } - for(size_t ic=0;ic tmp; - tmp.push_back(i); - - ret.push_back(tmp); - } - } - - return ret; -} bool operator<(const el_conf_t & lhs, const el_conf_t & rhs) { diff --git a/src/guess.h b/src/guess.h index e084cdaf..949f891f 100644 --- a/src/guess.h +++ b/src/guess.h @@ -72,9 +72,6 @@ arma::mat minimal_basis_projection(const BasisSet & basis); */ void atomic_guess(const BasisSet & basis, size_t inuc, const std::string & method, std::vector & shellidx, BasisSet & atbas, arma::vec & atE, arma::mat & atC, arma::mat & atP, arma::mat & atF, int Q); -/// Determine list of identical nuclei, determined by nucleus and basis set -std::vector< std::vector > identical_nuclei(const BasisSet & basis); - /// Electronic configuration typedef struct { /// Primary quantum number diff --git a/src/hirshfeld.cpp b/src/hirshfeld.cpp index 8e1c337b..a688d15b 100644 --- a/src/hirshfeld.cpp +++ b/src/hirshfeld.cpp @@ -132,7 +132,7 @@ void Hirshfeld::compute(const BasisSet & basis, std::string method) { atoms.resize(basis.get_Nnuc()); // Get list of identical nuclei - std::vector< std::vector > idnuc=identical_nuclei(basis); + std::vector< std::vector > idnuc=basis.find_identical_nuclei(); // Loop over list of identical nuclei for(size_t i=0;i > idnuc=identical_nuclei(basis); + std::vector< std::vector > idnuc=basis.find_identical_nuclei(); Timer t; if(verbose)