Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion source/module_esolver/esolver_ks_pw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1065,7 +1065,28 @@ void ESolver_KS_PW<T, Device>::postprocess()
if (winput::out_spillage <= 2)
{
Numerical_Basis numerical_basis;
numerical_basis.output_overlap(this->psi[0], this->sf, this->kv, this->pw_wfc);
if(INPUT.bessel_nao_rcuts.size() == 1)
{
numerical_basis.output_overlap(this->psi[0], this->sf, this->kv, this->pw_wfc);
}
else
{
for(int i = 0; i < INPUT.bessel_nao_rcuts.size(); i++)
{
if(GlobalV::MY_RANK == 0) {std::cout << "update value: bessel_nao_rcut <- " << std::fixed << INPUT.bessel_nao_rcuts[i] << " a.u." << std::endl;}
INPUT.bessel_nao_rcut = INPUT.bessel_nao_rcuts[i];
numerical_basis.output_overlap(this->psi[0], this->sf, this->kv, this->pw_wfc);
std::string old_fname_header = winput::spillage_outdir + "/" + "orb_matrix.";
std::string new_fname_header = winput::spillage_outdir + "/" + "orb_matrix_rcut" + std::to_string(int(INPUT.bessel_nao_rcut)) + "deriv";
for(int derivative_order = 0; derivative_order <= 1; derivative_order++)
{
// rename generated files
std::string old_fname = old_fname_header + std::to_string(derivative_order) + ".dat";
std::string new_fname = new_fname_header + std::to_string(derivative_order) + ".dat";
std::rename(old_fname.c_str(), new_fname.c_str());
}
}
}
ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "BASIS OVERLAP (Q and S) GENERATION.");
}
}
Expand Down
33 changes: 32 additions & 1 deletion source/module_io/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2203,7 +2203,9 @@ bool Input::Read(const std::string& fn)
}
else if (strcmp("bessel_nao_rcut", word) == 0)
{
read_value(ifs, bessel_nao_rcut);
//read_value(ifs, bessel_nao_rcut);
read_value2stdvector(ifs, bessel_nao_rcuts);
bessel_nao_rcut = bessel_nao_rcuts[0]; // also compatible with old input file
}
else if (strcmp("bessel_nao_tolerence", word) == 0)
{
Expand Down Expand Up @@ -3563,6 +3565,12 @@ void Input::Bcast()
Parallel_Common::bcast_bool(bessel_nao_smooth);
Parallel_Common::bcast_double(bessel_nao_sigma);
Parallel_Common::bcast_string(bessel_nao_ecut);
/* newly support vector/list input of bessel_nao_rcut */
int nrcut = bessel_nao_rcuts.size();
Parallel_Common::bcast_int(nrcut);
if (GlobalV::MY_RANK != 0) bessel_nao_rcuts.resize(nrcut);
Parallel_Common::bcast_double(bessel_nao_rcuts.data(), nrcut);
/* end */
Parallel_Common::bcast_double(bessel_nao_rcut);
Parallel_Common::bcast_double(bessel_nao_tolerence);
Parallel_Common::bcast_int(bessel_descriptor_lmax);
Expand Down Expand Up @@ -4223,6 +4231,29 @@ void Input::strtolower(char* sa, char* sb)
sb[len] = '\0';
}

template <typename T>
void Input::read_value2stdvector(std::ifstream& ifs, std::vector<T>& var)
{
// reset var
var.clear(); var.shrink_to_fit();
std::string line;
std::getline(ifs, line); // read the whole rest of line
line = (line.find('#') == std::string::npos) ? line : line.substr(0, line.find('#')); // remove comments
std::vector<std::string> tmp;
std::string::size_type start = 0, end = 0;
while ((start = line.find_first_not_of(" \t\n", end)) != std::string::npos) // find the first not of delimiters but not reaches the end
{
end = line.find_first_of(" \t\n", start); // find the first of delimiters starting from start pos
tmp.push_back(line.substr(start, end - start)); // push back the substring
}
var.resize(tmp.size());
// capture "this"'s member function cast_string and iterate from tmp.begin() to tmp.end(), transform to var.begin()
std::transform(tmp.begin(), tmp.end(), var.begin(), [this](const std::string& s) { return cast_string<T>(s); });
}
template void Input::read_value2stdvector(std::ifstream& ifs, std::vector<int>& var);
template void Input::read_value2stdvector(std::ifstream& ifs, std::vector<double>& var);
template void Input::read_value2stdvector(std::ifstream& ifs, std::vector<std::string>& var);

// Conut how many types of atoms are listed in STRU
int Input::count_ntype(const std::string& fn)
{
Expand Down
16 changes: 15 additions & 1 deletion source/module_io/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <sstream>
#include <string>
#include <vector>
#include <type_traits>

#include "module_base/vector3.h"
#include "module_md/md_para.h"
Expand Down Expand Up @@ -546,6 +547,7 @@ class Input
double bessel_nao_sigma; // spherical bessel smearing_sigma
std::string bessel_nao_ecut; // energy cutoff for spherical bessel functions(Ry)
double bessel_nao_rcut; // radial cutoff for spherical bessel functions(a.u.)
std::vector<double> bessel_nao_rcuts;
double bessel_nao_tolerence; // tolerence for spherical bessel root
// the following are used when generating jle.orb
int bessel_descriptor_lmax; // lmax used in descriptor
Expand Down Expand Up @@ -628,7 +630,7 @@ class Input
{
ifs >> var;
std::string line;
getline(ifs, line);
getline(ifs, line); // read the rest of the line, directly discard it.
return;
}
void read_kspacing(std::ifstream &ifs)
Expand Down Expand Up @@ -658,6 +660,18 @@ class Input
// << std::endl;
};

/* I hope this function would be more and more useful if want to support
vector/list of input */
template <typename T>
void read_value2stdvector(std::ifstream& ifs, std::vector<T>& var);
template <typename T>
typename std::enable_if<std::is_same<T, double>::value, T>::type cast_string(const std::string& str) { return std::stod(str); }
template <typename T>
typename std::enable_if<std::is_same<T, int>::value, T>::type cast_string(const std::string& str) { return std::stoi(str); }
template <typename T>
typename std::enable_if<std::is_same<T, bool>::value, T>::type cast_string(const std::string& str) { return (str == "true" || str == "1"); }
template <typename T>
typename std::enable_if<std::is_same<T, std::string>::value, T>::type cast_string(const std::string& str) { return str; }
void strtolower(char *sa, char *sb);
void read_bool(std::ifstream &ifs, bool &var);
};
Expand Down
133 changes: 133 additions & 0 deletions source/module_io/test/input_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1646,7 +1646,140 @@ TEST_F(InputTest, Check)
*/
}

bool strcmp_inbuilt(const std::string& str1, const std::string& str2)
{
if(str1.size() != str2.size())
return false;
for(int i=0; i<str1.size(); i++)
{
if(str1[i] != str2[i])
return false;
}
return true;
}

TEST_F(InputTest, ReadValue2stdvector)
{
std::string input_file = "./support/INPUT_list";
std::ifstream ifs(input_file);
std::string word;
std::vector<int> value;
while(!ifs.eof())
{
ifs >> word;
if(strcmp_inbuilt(word, "bessel_nao_rcut_case0"))
{
value.clear(); value.shrink_to_fit();
INPUT.read_value2stdvector(ifs, value);
EXPECT_EQ(value.size(), 1);
EXPECT_EQ(value[0], 7);
}
if(strcmp_inbuilt(word, "bessel_nao_rcut_case1"))
{
value.clear(); value.shrink_to_fit();
INPUT.read_value2stdvector(ifs, value);
EXPECT_EQ(value.size(), 1);
EXPECT_EQ(value[0], 7);
}
if(strcmp_inbuilt(word, "bessel_nao_rcut_case2"))
{
value.clear(); value.shrink_to_fit();
INPUT.read_value2stdvector(ifs, value);
EXPECT_EQ(value.size(), 1);
EXPECT_EQ(value[0], 7);
}
if(strcmp_inbuilt(word, "bessel_nao_rcut_case3"))
{
value.clear(); value.shrink_to_fit();
INPUT.read_value2stdvector(ifs, value);
EXPECT_EQ(value.size(), 1);
EXPECT_EQ(value[0], 7);
}
if(strcmp_inbuilt(word, "bessel_nao_rcut_case4"))
{
value.clear(); value.shrink_to_fit();
INPUT.read_value2stdvector(ifs, value);
EXPECT_EQ(value.size(), 1);
EXPECT_EQ(value[0], 7);
}
if(strcmp_inbuilt(word, "bessel_nao_rcut_case5"))
{
value.clear(); value.shrink_to_fit();
INPUT.read_value2stdvector(ifs, value);
EXPECT_EQ(value.size(), 4);
EXPECT_EQ(value[0], 7);
EXPECT_EQ(value[1], 8);
EXPECT_EQ(value[2], 9);
EXPECT_EQ(value[3], 10);
}
if(strcmp_inbuilt(word, "bessel_nao_rcut_case6"))
{
value.clear(); value.shrink_to_fit();
INPUT.read_value2stdvector(ifs, value);
EXPECT_EQ(value.size(), 4);
EXPECT_EQ(value[0], 7);
EXPECT_EQ(value[1], 8);
EXPECT_EQ(value[2], 9);
EXPECT_EQ(value[3], 10);
}
if(strcmp_inbuilt(word, "bessel_nao_rcut_case7"))
{
value.clear(); value.shrink_to_fit();
INPUT.read_value2stdvector(ifs, value);
EXPECT_EQ(value.size(), 4);
EXPECT_EQ(value[0], 7);
EXPECT_EQ(value[1], 8);
EXPECT_EQ(value[2], 9);
EXPECT_EQ(value[3], 10);
}
if(strcmp_inbuilt(word, "bessel_nao_rcut_case8"))
{
value.clear(); value.shrink_to_fit();
INPUT.read_value2stdvector(ifs, value);
EXPECT_EQ(value.size(), 4);
EXPECT_EQ(value[0], 7);
EXPECT_EQ(value[1], 8);
EXPECT_EQ(value[2], 9);
EXPECT_EQ(value[3], 10);
}
std::vector<std::string> str_value;
if(strcmp_inbuilt(word, "bessel_nao_rcut_case9"))
{
str_value.clear(); str_value.shrink_to_fit();
INPUT.read_value2stdvector(ifs, str_value);
EXPECT_EQ(str_value.size(), 1);
EXPECT_EQ(str_value[0], "string1");
}
if(strcmp_inbuilt(word, "bessel_nao_rcut_case10"))
{
str_value.clear(); str_value.shrink_to_fit();
INPUT.read_value2stdvector(ifs, str_value);
EXPECT_EQ(str_value.size(), 4);
EXPECT_EQ(str_value[0], "string1");
EXPECT_EQ(str_value[1], "string2");
EXPECT_EQ(str_value[2], "string3");
EXPECT_EQ(str_value[3], "string4");
}
std::vector<double> double_value;
if(strcmp_inbuilt(word, "bessel_nao_rcut_case11"))
{
double_value.clear(); double_value.shrink_to_fit();
INPUT.read_value2stdvector(ifs, double_value);
EXPECT_EQ(double_value.size(), 1);
EXPECT_EQ(double_value[0], 1.23456789);
}
if(strcmp_inbuilt(word, "bessel_nao_rcut_case12"))
{
double_value.clear(); double_value.shrink_to_fit();
INPUT.read_value2stdvector(ifs, double_value);
EXPECT_EQ(double_value.size(), 4);
EXPECT_EQ(double_value[0], -1.23456789);
EXPECT_EQ(double_value[1], 2.3456789);
EXPECT_EQ(double_value[2], -3.456789);
EXPECT_EQ(double_value[3], 4.56789);
}
}
}
#undef private


Expand Down
13 changes: 13 additions & 0 deletions source/module_io/test/support/INPUT_list
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
bessel_nao_rcut_case0 7
bessel_nao_rcut_case1 7# case0: test whitespace, 1 value, 1 space between key and value, no comment, 0 space after value: w1100, case1: w1110
bessel_nao_rcut_case2 7 # w1111
bessel_nao_rcut_case3 7# t1110
bessel_nao_rcut_case4 7 # t1111
bessel_nao_rcut_case5 7 8 9 10# s4110
bessel_nao_rcut_case6 7 8 9 10 # s4111
bessel_nao_rcut_case7 7 8 9 10# t4t10
bessel_nao_rcut_case8 7 8 9 10 # t4t11
bessel_nao_rcut_case9 string1 # something
bessel_nao_rcut_case10 string1 string2 string3 string4
bessel_nao_rcut_case11 1.23456789
bessel_nao_rcut_case12 -1.23456789 2.3456789 -3.456789 4.56789