Skip to content

Commit

Permalink
Estimate cutoff distance based on current basis set
Browse files Browse the repository at this point in the history
Signed-off-by: Geoff Hutchison <[email protected]>
  • Loading branch information
ghutchis committed Dec 28, 2023
1 parent 84cb4b0 commit 94f8a95
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 10 deletions.
58 changes: 50 additions & 8 deletions avogadro/core/gaussiansettools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ namespace Avogadro::Core {

GaussianSetTools::GaussianSetTools(Molecule* mol) : m_molecule(mol)
{
if (m_molecule)
if (m_molecule) {
m_basis = dynamic_cast<GaussianSet*>(m_molecule->basisSet());
m_cutoffDistances.resize(7, 0.0); // s, p, d, f, g, h, i (for now)
calculateCutoffs();
}
}

GaussianSetTools::~GaussianSetTools() {}
Expand Down Expand Up @@ -132,10 +135,50 @@ bool GaussianSetTools::isValid() const

inline bool GaussianSetTools::isSmall(double val) const
{
if (val > -1e-12 && val < 1e-12)
return true;
else
return false;
return std::abs(val) < 1e-12;
}

inline void GaussianSetTools::calculateCutoffs()
{
// Guesstimate a distance we can ignore the exp(-alpha * r^2) term
// .. because it's negligible
// This will depend on the angular momentum of the basis function
// .. so we calculate it for whatever L values in this basis set

const double threshold = 0.03 * 0.001; // 0.1% of a typical isovalue
const double maxDistance = 15.0; // 15 Angstroms

// get the exponents and normalized coefficients
const std::vector<double>& exponents = m_basis->gtoA();
const std::vector<double>& coefficients = m_basis->gtoCN();
const std::vector<int>& sym = m_basis->symmetry();

// we loop through the "symmetry" (i.e., L values in this basis set)
for (size_t i = 0; i < sym.size(); ++i) {
int L = symToL[sym[i]];

// this is a hack, since not all coefficients will be the same
// .. but it's a good approximation since they'll be similar
unsigned int cIndex = m_basis->cIndices()[i];
const double coeff = std::abs(coefficients[cIndex]);
const double preFactor = coeff * std::pow(r, L);

Check notice on line 164 in avogadro/core/gaussiansettools.cpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

avogadro/core/gaussiansettools.cpp#L164

Variable 'preFactor' is assigned a value that is never used.

// now loop through all exponents for this L value
// (e.g., multiple terms - we don't know which is the most diffuse)
for (unsigned int j = m_basis->gtoIndices()[i];
j < m_basis->gtoIndices()[i + 1]; ++j) {
double alpha = exponents[j];
double r = std::sqrt(L / (2 * alpha));
double value = prefactor * std::exp(-alpha * r * r);

Check notice on line 172 in avogadro/core/gaussiansettools.cpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

avogadro/core/gaussiansettools.cpp#L172

Variable 'value' is assigned a value that is never used.

while (value > threshold && r < maxDistance) {
r += 0.25;
value = prefactor * std::exp(-alpha * r * r);

Check notice on line 176 in avogadro/core/gaussiansettools.cpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

avogadro/core/gaussiansettools.cpp#L176

Variable 'value' is assigned a value that is never used.
}

m_cutoffDistances[L] = std::max(m_cutoffDistances[L], r * r);
}
}
}

inline vector<double> GaussianSetTools::calculateValues(
Expand Down Expand Up @@ -169,9 +212,8 @@ inline vector<double> GaussianSetTools::calculateValues(
// Now calculate the values at this point in space
for (unsigned int i = 0; i < basisSize; ++i) {
// bail early if the distance is too big
// TODO: this should be smarter and use the exponents
// .. and angular momentum
if (dr2[atomIndices[i]] > 100.0)
double cutoff = m_cutoffDistances[symToL[basis[i]]];
if (dr2[atomIndices[i]] > cutoff)
continue;

switch (basis[i]) {
Expand Down
13 changes: 11 additions & 2 deletions avogadro/core/gaussiansettools.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,14 @@ class AVOGADROCORE_EXPORT GaussianSetTools
Molecule* m_molecule;
GaussianSet* m_basis;
BasisSet::ElectronType m_type = BasisSet::Paired;
std::vector<double> m_cutoffDistances;

Check notice on line 102 in avogadro/core/gaussiansettools.h

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

avogadro/core/gaussiansettools.h#L102

class member 'GaussianSetTools::m_cutoffDistances' is never used.

bool isSmall(double value) const;

// get the cutoff distance for the given angular momentum
// .. and the current basis set (exponents)
void calculateCutoffs();

/**
* @brief Calculate the values at this position in space. The public calculate
* functions call this function to prepare values before multiplying by the
Expand All @@ -122,9 +127,13 @@ class AVOGADROCORE_EXPORT GaussianSetTools
std::vector<double>& values) const;
void pointF7(unsigned int index, const Vector3& delta, double dr2,
std::vector<double>& values) const;

// map from symmetry to angular momentum
// S, SP, P, D, D5, F, F7, G, G9, etc.
const int symToL[13] = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6 };

Check notice on line 133 in avogadro/core/gaussiansettools.h

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

avogadro/core/gaussiansettools.h#L133

class member 'GaussianSetTools::symToL' is never used.
};

} // End Core namespace
} // End Avogadro namespace
} // namespace Core
} // namespace Avogadro

#endif // AVOGADRO_CORE_GAUSSIANSETTOOLS_H

0 comments on commit 94f8a95

Please sign in to comment.