Skip to content

Commit

Permalink
Merge pull request QMCPACK#4917 from markdewing/opt_eigen_filter
Browse files Browse the repository at this point in the history
Fix occasional optimizer failure via improved filter to accept more eigenvalues
  • Loading branch information
prckent authored Apr 29, 2024
2 parents 9d71a1e + 640bc00 commit efdf45b
Showing 1 changed file with 38 additions and 0 deletions.
38 changes: 38 additions & 0 deletions src/QMCDrivers/WFOpt/LinearMethod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,13 @@ LinearMethod::Real LinearMethod::getLowestEigenvector(Matrix<Real>& A, std::vect
{
APP_ABORT("Invalid Matrix Diagonalization Function!");
}

// Filter and sort to find desired eigenvalue.
// Filter accepts eigenvalues between E_0 and E_0 - 100.0,
// where E_0 is H(0,0), the current estimate for the VMC energy.
// Sort searches for eigenvalue closest to E_0 - 2.0

bool found_any_eigenvalue = false;
std::vector<std::pair<Real, int>> mappedEigenvalues(Nl);
for (int i = 0; i < Nl; i++)
{
Expand All @@ -203,13 +210,44 @@ LinearMethod::Real LinearMethod::getLowestEigenvector(Matrix<Real>& A, std::vect
{
mappedEigenvalues[i].first = (evi - zerozero + 2.0) * (evi - zerozero + 2.0);
mappedEigenvalues[i].second = i;
found_any_eigenvalue = true;
}
else
{
mappedEigenvalues[i].first = std::numeric_limits<Real>::max();
mappedEigenvalues[i].second = i;
}
}

// Sometimes there is no eigenvalue less than E_0, but there is one slightly higher.
// Run filter and sort again, except this time accept eigenvalues between E_0 + 100.0 and E_0 - 100.0.
// Since it's already been determined there are no eigenvalues below E_0, the sort
// finds the eigenvalue closest to E_0.
if (!found_any_eigenvalue)
{
app_log() << "No eigenvalues passed initial filter. Trying broader 100 a.u. filter" << std::endl;

bool found_higher_eigenvalue;
for (int i = 0; i < Nl; i++)
{
Real evi(alphar[i]);
if ((evi < zerozero + 1e2) && (evi > (zerozero - 1e2)))
{
mappedEigenvalues[i].first = (evi - zerozero + 2.0) * (evi - zerozero + 2.0);
mappedEigenvalues[i].second = i;
found_higher_eigenvalue = true;
}
else
{
mappedEigenvalues[i].first = std::numeric_limits<Real>::max();
mappedEigenvalues[i].second = i;
}
}
if (!found_higher_eigenvalue)
{
app_log() << "No eigenvalues passed second filter. Optimization is likely to fail." << std::endl;
}
}
std::sort(mappedEigenvalues.begin(), mappedEigenvalues.end());
// for (int i=0; i<4; i++) app_log()<<i<<": "<<alphar[mappedEigenvalues[i].second]<< std::endl;
for (int i = 0; i < Nl; i++)
Expand Down

0 comments on commit efdf45b

Please sign in to comment.