Skip to content

Commit

Permalink
Prepare include/libint2 for Python bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
asadchev committed Jun 28, 2020
1 parent 67277d0 commit c7b15e1
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 65 deletions.
26 changes: 16 additions & 10 deletions include/libint2/basis.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -125,27 +125,27 @@ namespace libint2 {
auto canonical_name = canonicalize_name(name_);
// some basis sets use cartesian d shells by convention, the convention is taken from Gaussian09
auto force_cartesian_d = gaussian_cartesian_d_convention(canonical_name);

// parse the name into components
std::vector<std::string> basis_component_names = decompose_name_into_components(canonical_name);

// ref_shells[component_idx][Z] => vector of Shells
std::vector<std::vector<std::vector<libint2::Shell>>> component_basis_sets;
component_basis_sets.reserve(basis_component_names.size());

// read in ALL basis set components
for(const auto& basis_component_name: basis_component_names) {
auto file_dot_g94 = basis_lib_path + "/" + basis_component_name + ".g94";

// use same cartesian_d convention for all components!
component_basis_sets.emplace_back(read_g94_basis_library(file_dot_g94, force_cartesian_d, throw_if_no_match));
}

// for each atom find the corresponding basis components
for(auto a=0ul; a<atoms.size(); ++a) {

const std::size_t Z = atoms[a].atomic_number;

// add each component in order
for(auto comp_idx=0ul; comp_idx!=component_basis_sets.size(); ++comp_idx) {
const auto& component_basis_set = component_basis_sets[comp_idx];
Expand Down Expand Up @@ -202,6 +202,12 @@ namespace libint2 {
init();
}

explicit BasisSet(const std::vector<libint2::Shell> &shells)
: std::vector<libint2::Shell>(shells)
{
init();
}

/// forces solid harmonics/Cartesian Gaussians
/// @param solid if true, force all shells with L>1 to be solid harmonics, otherwise force all shells to Cartesian
void set_pure(bool solid) {
Expand Down Expand Up @@ -240,7 +246,7 @@ namespace libint2 {
std::vector<std::vector<long>> atom2shell(const std::vector<Atom>& atoms) const {
return atom2shell(atoms, *this);
}

/// Computes the map from \c shells to the corresponding atoms in \c atoms. Coordinates are compared bit-wise, i.e.
/// shell2atom[k] == l iff atoms[l].x == *this[k].O[0] && atoms[l].y == *this[k].O[1] && atoms[l].z == *this[k].O[2]
/// @param throw_if_no_match If true, and no atom matches the origin of a shell, throw a std::logic_error.
Expand Down Expand Up @@ -330,7 +336,7 @@ namespace libint2 {
}
return false;
}

/// decompose basis set name into components
std::vector<std::string> decompose_name_into_components(std::string name) {
std::vector<std::string> component_names;
Expand All @@ -345,7 +351,7 @@ namespace libint2 {

return component_names;
}

/** determines the path to the data directory, as follows:
* <ol>
* <li> specified by LIBINT_DATA_PATH environmental variable, if defined </li>
Expand Down Expand Up @@ -395,7 +401,7 @@ namespace libint2 {
}
return basis_path;
}

/// converts fortran scientific-notation floats that use d/D instead of e/E in \c str
/// @param[in,out] str string in which chars 'd' and 'D' are replaced with 'e' and 'E',
/// respectively
Expand Down
111 changes: 56 additions & 55 deletions include/libint2/solidharmonics.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,61 +99,6 @@ namespace libint2 {
return row_offset_[r+1] - row_offset_[r];
}

private:
std::vector<Real> values_; // elements
std::vector<unsigned short> row_offset_; // "pointer" to the beginning of each row
std::vector<unsigned char> colidx_; // column indices
signed char l_; // the angular momentum quantum number

void init() {
const unsigned short npure = 2*l_ + 1;
const unsigned short ncart = (l_ + 1) * (l_ + 2) / 2;
std::vector<Real> full_coeff(npure * ncart);

#if LIBINT_SHGSHELL_ORDERING == LIBINT_SHGSHELL_ORDERING_STANDARD
for(signed char pure_idx=0, m=-l_; pure_idx!=npure; ++pure_idx, ++m) {
#elif LIBINT_SHGSHELL_ORDERING == LIBINT_SHGSHELL_ORDERING_GAUSSIAN
for(signed char pure_idx=0, m=0; pure_idx!=npure; ++pure_idx, m=(m>0?-m:1-m)) {
#else
# error "unknown value of macro LIBINT_SHGSHELL_ORDERING"
#endif
signed char cart_idx = 0;
signed char lx, ly, lz;
FOR_CART(lx, ly, lz, l_)
full_coeff[pure_idx * ncart + cart_idx] = coeff(l_, m, lx, ly, lz);
//std::cout << "Solid(" << (int)l_ << "," << (int)m << ") += Cartesian(" << (int)lx << "," << (int)ly << "," << (int)lz << ") * " << full_coeff[pure_idx * ncart + cart_idx] << std::endl;
++cart_idx;
END_FOR_CART
}

// compress rows
// 1) count nonzeroes
size_t nnz = 0;
for(size_t i=0; i!=full_coeff.size(); ++i)
nnz += full_coeff[i] == 0.0 ? 0 : 1;
// 2) allocate
values_.resize(nnz);
colidx_.resize(nnz);
row_offset_.resize(npure+1);
// 3) copy
{
unsigned short pc = 0;
unsigned short cnt = 0;
for(unsigned short p=0; p!=npure; ++p) {
row_offset_[p] = cnt;
for(unsigned short c=0; c!=ncart; ++c, ++pc) {
if (full_coeff[pc] != 0.0) {
values_[cnt] = full_coeff[pc];
colidx_[cnt] = c;
++cnt;
}
}
}
row_offset_[npure] = cnt;
}
// done
}

/*!---------------------------------------------------------------------------------------------
Computes coefficient of a cartesian Gaussian in a real solid harmonic Gaussian
See IJQC 54, 83 (1995), eqn (15). If m is negative, imaginary part is computed, whereas
Expand Down Expand Up @@ -215,6 +160,62 @@ namespace libint2 {
return result;
}

private:
std::vector<Real> values_; // elements
std::vector<unsigned short> row_offset_; // "pointer" to the beginning of each row
std::vector<unsigned char> colidx_; // column indices
signed char l_; // the angular momentum quantum number

void init() {
const unsigned short npure = 2*l_ + 1;
const unsigned short ncart = (l_ + 1) * (l_ + 2) / 2;
std::vector<Real> full_coeff(npure * ncart);

#if LIBINT_SHGSHELL_ORDERING == LIBINT_SHGSHELL_ORDERING_STANDARD
for(signed char pure_idx=0, m=-l_; pure_idx!=npure; ++pure_idx, ++m) {
#elif LIBINT_SHGSHELL_ORDERING == LIBINT_SHGSHELL_ORDERING_GAUSSIAN
for(signed char pure_idx=0, m=0; pure_idx!=npure; ++pure_idx, m=(m>0?-m:1-m)) {
#else
# error "unknown value of macro LIBINT_SHGSHELL_ORDERING"
#endif
signed char cart_idx = 0;
signed char lx, ly, lz;
FOR_CART(lx, ly, lz, l_)
full_coeff[pure_idx * ncart + cart_idx] = coeff(l_, m, lx, ly, lz);
//std::cout << "Solid(" << (int)l_ << "," << (int)m << ") += Cartesian(" << (int)lx << "," << (int)ly << "," << (int)lz << ") * " << full_coeff[pure_idx * ncart + cart_idx] << std::endl;
++cart_idx;
END_FOR_CART
}

// compress rows
// 1) count nonzeroes
size_t nnz = 0;
for(size_t i=0; i!=full_coeff.size(); ++i)
nnz += full_coeff[i] == 0.0 ? 0 : 1;
// 2) allocate
values_.resize(nnz);
colidx_.resize(nnz);
row_offset_.resize(npure+1);
// 3) copy
{
unsigned short pc = 0;
unsigned short cnt = 0;
for(unsigned short p=0; p!=npure; ++p) {
row_offset_[p] = cnt;
for(unsigned short c=0; c!=ncart; ++c, ++pc) {
if (full_coeff[pc] != 0.0) {
values_[cnt] = full_coeff[pc];
colidx_[cnt] = c;
++cnt;
}
}
}
row_offset_[npure] = cnt;
}
// done
}


struct CtorHelperIter : public std::iterator<std::input_iterator_tag, SolidHarmonicsCoefficients> {
unsigned int l_;
using typename std::iterator<std::input_iterator_tag, SolidHarmonicsCoefficients>::value_type;
Expand Down

0 comments on commit c7b15e1

Please sign in to comment.