31#include <rapidxml.hpp>
35namespace pseudopotential {
37class upf1 :
public pseudopotential::upf {
40 upf1(
const std::string &filename,
bool uniform_grid =
false)
41 : pseudopotential::upf(uniform_grid), file_(filename.c_str()),
42 buffer_((std::istreambuf_iterator<char>(file_)),
43 std::istreambuf_iterator<char>()) {
47 buffer_.push_back(
'\0');
48 doc_.parse<0>(&buffer_[0]);
50 std::istringstream header(doc_.first_node(
"PP_HEADER")->value());
55 header >> version_number;
56 getline(header, line);
59 symbol_ = element::trim(symbol_);
60 getline(header, line);
63 header >> pseudo_type;
64 getline(header, line);
67 getline(header, line);
69 getline(header, xc_functional_);
72 getline(header, line);
75 getline(header, line);
78 getline(header, line);
81 getline(header, line);
85 getline(header, line);
87 header >> nwavefunctions_;
88 header >> nprojectors_;
89 getline(header, line);
91 std::transform(pseudo_type.begin(), pseudo_type.end(), pseudo_type.begin(),
94 if (pseudo_type ==
"nc" || pseudo_type ==
"sl") {
95 type_ = pseudopotential::type::KLEINMAN_BYLANDER;
96 }
else if (pseudo_type ==
"uspp") {
97 throw status::UNSUPPORTED_TYPE_ULTRASOFT;
98 }
else if (pseudo_type ==
"paw") {
99 throw status::UNSUPPORTED_TYPE_PAW;
101 throw status::UNSUPPORTED_TYPE;
106 rapidxml::xml_node<> *node =
107 doc_.first_node(
"PP_MESH")->first_node(
"PP_R");
110 std::istringstream stst(node->value());
120 grid_.resize(size + start_point_);
123 grid_[start_point_] = xmin;
124 for (
int ii = 0; ii < size - 1; ii++)
125 stst >> grid_[1 + start_point_ + ii];
127 assert(
fabs(grid_[0]) <= 1e-10);
130 for (
double rr = 0.0; rr <= grid_[grid_.size() - 1]; rr += mesh_spacing())
135 rapidxml::xml_node<> *node =
136 doc_.first_node(
"PP_MESH")->first_node(
"PP_R");
139 std::istringstream stst(node->value());
141 grid_weights_.resize(size + start_point_);
143 grid_weights_[0] = 0.5 * (grid_[1] - grid_[0]);
144 for (
int ii = 0; ii < size; ii++)
145 stst >> grid_weights_[start_point_ + ii];
151 proj_l_.resize(nprojectors());
152 proj_c_.resize(nprojectors());
154 rapidxml::xml_node<> *node =
155 doc_.first_node(
"PP_NONLOCAL")->first_node(
"PP_BETA");
157 std::vector<bool> has_l(MAX_L,
false);
165 std::istringstream stst(node->value());
169 stst >> read_i >> read_l;
173 assert(iproj == read_i);
175 lmax_ = std::max(lmax_, read_l);
176 has_l[read_l] =
true;
177 proj_l_[iproj] = read_l;
179 for (
int jproj = 0; jproj < iproj; jproj++)
180 if (read_l == proj_l_[jproj])
183 nchannels_ = std::max(nchannels_, proj_c_[iproj] + 1);
185 node = node->next_sibling(
"PP_BETA");
192 for (
int l = 0;
l <= lmax_;
l++)
199 rapidxml::xml_node<> *node =
200 doc_.first_node(
"PP_NONLOCAL")->first_node(
"PP_DIJ");
204 dij_.resize(nchannels() * nchannels() * (lmax_ + 1));
206 for (
unsigned kk = 0; kk < dij_.size(); kk++)
209 std::istringstream stst(node->value());
216 for (
int kk = 0; kk < nnonzero; kk++) {
219 stst >> ii >> jj >> val;
224 assert(proj_l_[ii] == proj_l_[jj]);
226 d_ij(proj_l_[ii], proj_c_[ii], proj_c_[jj]) = val;
231 pseudopotential::format format()
const {
232 return pseudopotential::format::UPF2;
235 int size()
const {
return buffer_.size(); };
238 return doc_.first_node(
"PP_INFO")->value();
243 int atomic_number()
const {
244 element el(symbol());
245 return el.atomic_number();
248 double mass()
const {
249 element el(symbol());
253 double valence_charge()
const {
return zval_; }
255 pseudopotential::exchange exchange()
const {
256 if (xc_functional_ ==
"PBE")
257 return pseudopotential::exchange::PBE;
258 if (xc_functional_ ==
"PBESOL")
259 return pseudopotential::exchange::PBE_SOL;
260 if (xc_functional_ ==
"SLA PW NOGX NOGC")
261 return pseudopotential::exchange::LDA;
262 if (xc_functional_ ==
"BLYP")
263 return pseudopotential::exchange::B88;
264 return pseudopotential::exchange::UNKNOWN;
267 pseudopotential::correlation correlation()
const {
268 if (xc_functional_ ==
"PBE")
269 return pseudopotential::correlation::PBE;
270 if (xc_functional_ ==
"PBESOL")
271 return pseudopotential::correlation::PBE_SOL;
272 if (xc_functional_ ==
"SLA PW NOGX NOGC")
273 return pseudopotential::correlation::LDA_PW;
274 if (xc_functional_ ==
"BLYP")
275 return pseudopotential::correlation::LYP;
276 return pseudopotential::correlation::UNKNOWN;
279 void local_potential(std::vector<double> &potential)
const {
280 rapidxml::xml_node<> *node = doc_.first_node(
"PP_LOCAL");
284 potential.resize(grid_.size());
285 std::istringstream stst(node->value());
286 for (
unsigned ii = 0; ii < grid_.size() - start_point_; ii++) {
287 stst >> potential[ii + start_point_];
288 potential[ii + start_point_] *= 0.5;
290 if (start_point_ > 0)
291 extrapolate_first_point(potential);
293 interpolate(potential);
296 int nprojectors()
const {
return nprojectors_; }
298 int nprojectors_per_l(
int l)
const {
301 for (
int jproj = 0; jproj < nprojectors(); jproj++)
302 if (proj_l_[jproj] ==
l)
303 nchannel = std::max(proj_c_[jproj]+1, nchannel);
308 void projector(
int l,
int i, std::vector<double> &proj)
const {
311 rapidxml::xml_node<> *node =
312 doc_.first_node(
"PP_NONLOCAL")->first_node(
"PP_BETA");
317 while (
l != proj_l_[iproj] ||
i != proj_c_[iproj]) {
319 node = node->next_sibling(
"PP_BETA");
326 std::istringstream stst(node->value());
328 int read_i, read_l, size;
330 stst >> read_i >> read_l;
333 assert(read_l == proj_l_[iproj]);
339 assert(size <=
int(grid_.size()));
341 proj.resize(grid_.size());
343 for (
int ii = 0; ii < size; ii++)
344 stst >> proj[ii + start_point_];
345 for (
unsigned ii = size; ii < grid_.size() - start_point_; ii++)
346 proj[ii + start_point_] = 0.0;
350 for (
unsigned ii = 1; ii < proj.size(); ii++)
351 proj[ii] /= 2.0 * grid_[ii];
352 extrapolate_first_point(proj);
357 bool has_radial_function(
int l)
const {
return false; }
359 void radial_function(
int l, std::vector<double> &function)
const {
363 void radial_potential(
int l, std::vector<double> &function)
const {
367 bool has_nlcc()
const {
return doc_.first_node(
"PP_NLCC"); }
369 void nlcc_density(std::vector<double> &
density)
const {
370 rapidxml::xml_node<> *node = doc_.first_node(
"PP_NLCC");
372 std::istringstream stst(node->value());
376 for (
unsigned ii = 0; ii < grid_.size() - start_point_; ii++)
377 stst >>
density[start_point_ + ii];
378 extrapolate_first_point(
density);
384 bool has_density()
const {
return doc_.first_node(
"PP_RHOATOM"); }
386 void density(std::vector<double> &val)
const {
387 rapidxml::xml_node<> *node = doc_.first_node(
"PP_RHOATOM");
390 val.resize(grid_.size());
392 std::istringstream stst(node->value());
393 for (
unsigned ii = 0; ii < grid_.size() - start_point_; ii++)
394 stst >> val[start_point_ + ii];
397 for (
unsigned ii = 1; ii < val.size(); ii++)
398 val[ii] /= 4.0 * M_PI * grid_[ii] * grid_[ii];
399 extrapolate_first_point(val);
404 int nwavefunctions()
const {
return nwavefunctions_; }
406 void wavefunction(
int index,
int &n,
int &
l,
double &occ,
407 std::vector<double> &proj)
const {
408 rapidxml::xml_node<> *node = doc_.first_node(
"PP_PSWFC");
412 std::istringstream stst(node->value());
417 for (
int ii = 0; ii <
index; ii++) {
422 for (
unsigned ii = 0; ii < grid_.size() - start_point_; ii++)
427 stst >> label >>
l >> occ;
433 n = atoi(label.substr(0, 1).c_str());
436 proj.resize(grid_.size());
438 for (
unsigned ii = 0; ii < grid_.size() - start_point_; ii++)
439 stst >> proj[ii + start_point_];
443 for (
unsigned ii = 1; ii < grid_.size() - start_point_; ii++)
444 proj[ii] /= grid_[ii];
445 extrapolate_first_point(proj);
450 bool has_total_angular_momentum()
const {
451 return doc_.first_node(
"PP_ADDINFO");
454 int projector_2j(
int l,
int ic)
const {
459 rapidxml::xml_node<> *node = doc_.first_node(
"PP_ADDINFO");
462 std::istringstream stst(node->value());
464 for (
int iwf = 0; iwf < nwavefunctions_; iwf++) {
470 for (
int iproj = 0; iproj < nprojectors_; iproj++) {
475 assert(read_l == proj_l_[iproj]);
477 if (proj_l_[iproj] ==
l && proj_c_[iproj] == ic) {
480 return lrint(read_j * 2.0);
491 int wavefunction_2j(
int ii)
const {
493 assert(ii >= 0 && ii <= nwavefunctions_);
495 rapidxml::xml_node<> *node = doc_.first_node(
"PP_ADDINFO");
498 std::istringstream stst(node->value());
501 for (
int iwf = 0; iwf < ii; iwf++) {
505 stst >> label >> n >>
l >>
j >> occ;
508 return lrint(
j * 2.0);
513 std::vector<char> buffer_;
514 rapidxml::xml_document<> doc_;
521 std::vector<int> proj_l_;
522 std::vector<int> proj_c_;
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
double fabs(double __x) __attribute__((__nothrow__
integer, parameter, public density
integer, parameter, public mass
const int *restrict index