forked from abacusmodeling/abacus-develop
-
Notifications
You must be signed in to change notification settings - Fork 139
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature: enable ABACUS can finish SCF if charge density oscillation is found #5421
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
If anyone is unsure how to choose #include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
#include <cmath>
bool if_scf_oscillate(std::vector<double>& drho_history, const int iteration, const double drho, const int iternum_used, const double threshold)
{
if(threshold >= 0) // close the function
{
return false;
}
// add drho into history
drho_history[iteration - 1] = drho;
// check if the history is long enough
if(iteration < iternum_used)
{
return false;
}
// calculate the slope of the last iternum_used iterations' drho
double slope = 0.0;
// Least Squares Method
double sumX = 0, sumY = 0, sumXY = 0, sumXX = 0;
for (int i = iteration - iternum_used; i < iteration; i++)
{
sumX += i;
sumY += std::log10(drho_history[i]);
sumXY += i * std::log10(drho_history[i]);
sumXX += i * i;
}
double numerator = iternum_used * sumXY - sumX * sumY;
double denominator = iternum_used * sumXX - sumX * sumX;
if (denominator == 0) {
return false;
}
slope = numerator / denominator;
std::cout << iteration << "-th slope: " << slope << std::endl;
// if the slope is less than the threshold, return true
if(slope > threshold)
{
return true;
}
return false;
}
int main() {
std::string filename = "data.txt"; // 替换为你的文件名
std::ifstream file(filename);
std::vector<double> numbers;
std::string line;
if (file.is_open()) {
while (getline(file, line)) {
std::istringstream iss(line);
double number;
if (!(iss >> number)) { // 如果转换失败,跳过这个数字
continue;
}
numbers.push_back(number);
}
file.close();
} else {
std::cerr << "Unable to open file" << std::endl;
return 1;
}
int scf_nmax = 10;
int scf_os_ndim = 3;
double scf_thr_os = -0.05;
std::vector<double> drho_history;
drho_history.resize(scf_nmax);
bool oscillate = false;
for (int i = 1; i <= numbers.size(); i++) {
oscillate = if_scf_oscillate(drho_history, i, numbers[i-1], scf_os_ndim, scf_thr_os);
if (oscillate) {
std::cout << "Oscillation detected at iteration " << i << std::endl;
}
}
return 0;
} |
mohanchen
approved these changes
Nov 6, 2024
mohanchen
added
the
Features Needed
The features are indeed needed, and developers should have sophisticated knowledge
label
Nov 6, 2024
mohanchen
reviewed
Nov 6, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
Features Needed
The features are indeed needed, and developers should have sophisticated knowledge
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fix #5406
Motivation
For systems that are difficult to converge, the SCF process may exhibit oscillations in charge density, preventing further progress toward the specified convergence criteria and resulting in continuous oscillation until the maximum number of steps is reached; this greatly wastes computational resources. To address this issue, I have designed a new feature that allows ABACUS to terminate the SCF process early upon detecting oscillations, thus reducing subsequent meaningless calculations. The detection of oscillations is based on the slope of the logarithm of historical
drho
values.What's Changed?
scf_os_stop
. Iftrue
, SCF will stop if charge density oscillation is found. The default isfalse
scf_os_thr
. The default value is -0.01scf_os_ndim
to control the number of past iterations used in slope calculation. Generally speaking, if the number of oscillation steps persists beyond the steps considered for charge density mixingmixing_ndim
, the SCF is unlikely to break free from oscillations. So, I set the default value as the same asmixing_ndim
, you can change it.Charge_Mixing::if_scf_oscillate
to determine if oscillation happens.oscillate_esolver
, similar toconv_esolver
.