32namespace pseudopotential {
34class psp8 :
public pseudopotential::base {
41 std::ifstream original_file(filename.c_str());
42 std::string buffer((std::istreambuf_iterator<char>(original_file)),
43 std::istreambuf_iterator<char>());
44 std::replace(buffer.begin(), buffer.end(),
'D',
'E');
45 std::replace(buffer.begin(), buffer.end(),
'd',
'e');
47 std::istringstream
file(buffer);
49 type_ = pseudopotential::type::KLEINMAN_BYLANDER;
52 file.seekg(0, std::ios::beg);
53 std::streampos file_size_ =
file.tellg();
54 file.seekg(0, std::ios::end);
55 file_size_ =
file.tellg() - file_size_;
58 file.seekg(0, std::ios::beg);
62 getline(
file, description_);
67 atomic_number_ = round(val);
68 file >> valence_charge_;
73 file >> pspcod >> ixc_ >> lmax_ >> llocal_ >> mesh_size_;
75 throw status::UNKNOWN_FORMAT;
87 for (
int l = 0;
l <= lmax_;
l++) {
90 nprojl_.push_back(np);
92 nchannels_ = std::max(nchannels_, np);
98 file >> extension_switch;
100 has_density_ = extension_switch == 1;
101 has_soc_ = extension_switch == 2;
107 if (extension_switch > 2)
108 throw status::FORMAT_NOT_SUPPORTED;
111 projectors_.resize(lmax_ + 1);
112 ekb_.resize(lmax_ + 1);
113 for (
int l = 0;
l <= lmax_;
l++) {
114 projectors_[
l].resize(nprojl_[
l]);
115 ekb_[
l].resize(nprojl_[
l]);
118 read_local_potential(
file);
130 for (
int iproj = 0; iproj < nprojl_[
l]; iproj++) {
131 projectors_[
l][iproj].resize(mesh_size_);
132 file >> ekb_[
l][iproj];
136 for (
int ip = 0; ip < mesh_size_; ip++) {
139 file >> read_ip >> grid_point;
141 assert(read_ip == ip + 1);
143 for (
int iproj = 0; iproj < nprojl_[
l]; iproj++)
144 file >> projectors_[
l][iproj][ip];
151 read_local_potential(
file);
155 nlcc_density_.resize(mesh_size_);
157 for (
int ip = 0; ip < mesh_size_; ip++) {
160 file >> read_ip >> grid_point >> nlcc_density_[ip];
161 assert(read_ip == ip + 1);
166 if (extension_switch == 1) {
168 density_.resize(mesh_size_);
170 for (
int ip = 0; ip < mesh_size_; ip++) {
173 file >> read_ip >> grid_point >> density_[ip];
174 assert(read_ip == ip + 1);
180 pseudopotential::format format()
const {
181 return pseudopotential::format::PSP8;
184 int size()
const {
return file_size_; };
186 std::string description()
const {
return description_; }
189 pseudopotential::element el(atomic_number_);
193 int atomic_number()
const {
return atomic_number_; }
195 double mass()
const {
196 pseudopotential::element el(atomic_number_);
200 double valence_charge()
const {
return valence_charge_; }
202 pseudopotential::exchange exchange()
const {
205 return pseudopotential::exchange::NONE;
206 if (ixc_ >= 2 && ixc_ <= 9)
207 return pseudopotential::exchange::LDA;
208 if (ixc_ == 11 || ixc_ == 12)
209 return pseudopotential::exchange::PBE;
211 return pseudopotential::exchange((-ixc_ + ixc_ % 1000) / 1000);
214 return pseudopotential::exchange::UNKNOWN;
217 pseudopotential::correlation correlation()
const {
220 return pseudopotential::correlation::LDA_XC_TETER93;
222 return pseudopotential::correlation::LDA_PZ;
224 return pseudopotential::correlation::LDA_PW;
225 if (ixc_ == 7 || ixc_ == 8)
226 return pseudopotential::correlation::NONE;
228 return pseudopotential::correlation::PBE;
230 return pseudopotential::correlation::NONE;
232 return pseudopotential::correlation(-ixc_ % 1000);
235 return pseudopotential::correlation::UNKNOWN;
244 int nchannels()
const {
return nchannels_; }
246 double mesh_spacing()
const {
return mesh_spacing_; }
248 int mesh_size()
const {
return mesh_size_; }
250 void local_potential(std::vector<double> &potential)
const {
251 potential.resize(mesh_size_);
252 assert(mesh_size_ == local_potential_.size());
253 for (
int ip = 0; ip < mesh_size_; ip++)
254 potential[ip] = local_potential_[ip];
257 int nprojectors()
const {
return nprojectors_; }
259 int nprojectors_per_l(
int l)
const {
263 void projector(
int l,
int i, std::vector<double> &proj)
const {
271 proj.resize(mesh_size_);
272 assert(mesh_size_ == projectors_[
l][
i].size());
274 for (
int ip = 1; ip < mesh_size_; ip++)
275 proj[ip] = projectors_[
l][
i][ip] / (mesh_spacing() * ip);
277 extrapolate_first_point(proj);
280 double d_ij(
int l,
int i,
int j)
const {
288 bool has_radial_function(
int l)
const {
return false; }
290 void radial_function(
int l, std::vector<double> &function)
const {
294 void radial_potential(
int l, std::vector<double> &function)
const {
298 bool has_nlcc()
const {
return nlcc_; }
300 bool has_total_angular_momentum()
const {
return has_soc_; }
302 void nlcc_density(std::vector<double> &
density)
const {
304 assert(mesh_size_ == nlcc_density_.size());
305 for (
int ip = 0; ip < mesh_size_; ip++)
306 density[ip] = nlcc_density_[ip] / (4.0 * M_PI);
309 bool has_density()
const {
return has_density_; }
313 assert(mesh_size_ == density_.size());
314 for (
int ip = 0; ip < mesh_size_; ip++)
315 density[ip] = density_[ip] / (4.0 * M_PI);
319 void extrapolate_first_point(std::vector<double> &function_)
const {
321 assert(function_.size() >= 4);
323 double x1 = mesh_spacing();
324 double x2 = 2 * mesh_spacing();
325 double x3 = 3 * mesh_spacing();
326 double f1 = function_[1];
327 double f2 = function_[2];
328 double f3 = function_[3];
333 function_[0] =
f1 * x2 * x3 * (x2 - x3) +
f2 * x1 * x3 * (x3 - x1) +
334 f3 * x1 * x2 * (x1 - x2);
335 function_[0] /= (x1 - x2) * (x1 - x3) * (x2 - x3);
338 void read_local_potential(std::istream &
file) {
344 assert(llocal_ == read_llocal);
347 local_potential_.resize(mesh_size_);
348 for (
int ip = 0; ip < mesh_size_; ip++) {
351 file >> read_ip >> grid_point >> local_potential_[ip];
352 assert(read_ip == ip + 1);
356 mesh_spacing_ = grid_point;
364 double valence_charge_;
369 double mesh_spacing_;
370 std::vector<int> nprojl_;
372 std::vector<std::vector<std::vector<double>>> projectors_;
373 std::vector<std::vector<double>> ekb_;
374 std::vector<double> local_potential_;
376 std::vector<double> nlcc_density_;
378 std::vector<double> density_;
if write to the Free Software Franklin Fifth USA !If the compiler accepts long Fortran it is better to use that and build all the preprocessor definitions in one line In !this the debuggers will provide the right line numbers !If the compiler accepts line number then CARDINAL and ACARDINAL !will put them just a new line or a ampersand plus a new line !These macros should be used in macros that span several lines They should by !put immedialty before a line where a compilation error might occur and at the !end of the macro !Note that the cardinal and newline words are substituted by the program !preprocess pl by the ampersand and by a real new line just before compilation !The assertions are ignored if the code is compiled in not debug when !prints out the assertion the file
if write to the Free Software Franklin Fifth USA !If the compiler accepts long Fortran it is better to use that and build all the preprocessor definitions in one line In !this the debuggers will provide the right line numbers !If the compiler accepts line number then CARDINAL and ACARDINAL !will put them just a new line or a ampersand plus a new line !These macros should be used in macros that span several lines They should by !put immedialty before a line where a compilation error might occur and at the !end of the macro !Note that the cardinal and newline words are substituted by the program !preprocess pl by the ampersand and by a real new line just before compilation !The assertions are ignored if the code is compiled in not debug when !prints out the assertion string
integer, parameter, public density
integer, parameter, public mass