void BasisSet::processDensity(BasisShell &shell) { BasisSet *set = shell.set; unsigned int atomsSize = set->m_numAtoms; unsigned int basisSize = set->m_symmetry.size(); unsigned int matrixSize = set->m_density.rows(); std::vector<int> &basis = set->m_symmetry; vector<Vector3d> deltas; vector<double> dr2; deltas.reserve(atomsSize); dr2.reserve(atomsSize); // Calculate our position Vector3d pos = shell.tCube->position(shell.pos) * ANGSTROM_TO_BOHR; // Calculate the deltas for the position for (unsigned int i = 0; i < atomsSize; ++i) { deltas.push_back(pos - set->m_atomPos[i]); dr2.push_back(deltas[i].squaredNorm()); } // Calculate the basis set values at this point MatrixXd values(matrixSize, 1); for (unsigned int i = 0; i < basisSize; ++i) { unsigned int cAtom = set->m_atomIndices[i]; switch(basis[i]) { case S: pointS(shell.set, dr2[cAtom], i, values); break; case P: pointP(shell.set, deltas[cAtom], dr2[cAtom], i, values); break; case D: pointD(shell.set, deltas[cAtom], dr2[cAtom], i, values); break; case D5: pointD5(shell.set, deltas[cAtom], dr2[cAtom], i, values); break; default: // Not handled - return a zero contribution ; } } // Now calculate the value of the density at this point in space double rho = 0.0; for (unsigned int i = 0; i < matrixSize; ++i) { // Calculate the off-diagonal parts of the matrix for (unsigned int j = 0; j < i; ++j) { rho += 2.0 * set->m_density.coeffRef(i, j) * (values.coeffRef(i, 0) * values.coeffRef(j, 0)); } // Now calculate the matrix diagonal rho += set->m_density.coeffRef(i, i) * (values.coeffRef(i, 0) * values.coeffRef(i, 0)); } // Set the value shell.tCube->setValue(shell.pos, rho); }
/// This is the stuff we actually use right now - porting to new data structure void BasisSet::processPoint(BasisShell &shell) { BasisSet *set = shell.set; unsigned int atomsSize = set->m_numAtoms; unsigned int basisSize = set->m_symmetry.size(); std::vector<int> &basis = set->m_symmetry; vector<Vector3d> deltas; vector<double> dr2; deltas.reserve(atomsSize); dr2.reserve(atomsSize); unsigned int indexMO = shell.state-1; // Calculate our position Vector3d pos = shell.tCube->position(shell.pos) * ANGSTROM_TO_BOHR; // Calculate the deltas for the position for (unsigned int i = 0; i < atomsSize; ++i) { deltas.push_back(pos - set->m_atomPos[i]); dr2.push_back(deltas[i].squaredNorm()); } // Now calculate the value at this point in space double tmp = 0.0; for (unsigned int i = 0; i < basisSize; ++i) { switch(basis[i]) { case S: tmp += pointS(shell.set, i, dr2[set->m_atomIndices[i]], indexMO); break; case P: tmp += pointP(shell.set, i, deltas[set->m_atomIndices[i]], dr2[set->m_atomIndices[i]], indexMO); break; case D: tmp += pointD(shell.set, i, deltas[set->m_atomIndices[i]], dr2[set->m_atomIndices[i]], indexMO); break; case D5: tmp += pointD5(shell.set, i, deltas[set->m_atomIndices[i]], dr2[set->m_atomIndices[i]], indexMO); break; default: // Not handled - return a zero contribution ; } } // Set the value shell.tCube->setValue(shell.pos, tmp); }
inline vector<double> GaussianSetTools::calculateValues(const Vector3 &position) const { m_basis->initCalculation(); unsigned int atomsSize = static_cast<unsigned int>(m_molecule->atomCount()); size_t basisSize = m_basis->symmetry().size(); const std::vector<int> &basis = m_basis->symmetry(); const std::vector<unsigned int> &atomIndices = m_basis->atomIndices(); vector<Vector3> deltas; vector<double> dr2; deltas.reserve(atomsSize); dr2.reserve(atomsSize); // Calculate our position Vector3 pos(position * ANGSTROM_TO_BOHR); // Calculate the deltas for the position for (size_t i = 0; i < atomsSize; ++i) { deltas.push_back(pos - (m_molecule->atom(i).position3d() * ANGSTROM_TO_BOHR)); dr2.push_back(deltas[i].squaredNorm()); } // Allocate space for the values to be calculated. size_t matrixSize = m_basis->moMatrix().rows(); vector<double> values; values.resize(matrixSize, 0.0); // Now calculate the values at this point in space for (unsigned int i = 0; i < basisSize; ++i) { switch (basis[i]) { case GaussianSet::S: pointS(i, dr2[atomIndices[i]], values); break; case GaussianSet::P: pointP(i, deltas[atomIndices[i]], dr2[atomIndices[i]], values); break; case GaussianSet::D: pointD(i, deltas[atomIndices[i]], dr2[atomIndices[i]], values); break; case GaussianSet::D5: pointD5(i, deltas[atomIndices[i]], dr2[atomIndices[i]], values); break; default: // Not handled - return a zero contribution ; } } return values; }