31#include <rapidxml.hpp>
35namespace pseudopotential {
37class upf2 :
public pseudopotential::upf {
40 upf2(
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 root_node_ = doc_.first_node(
"UPF");
53 throw status::FORMAT_NOT_SUPPORTED;
55 if (root_node_->first_attribute(
"version")->value()[0] !=
'2')
56 throw status::FORMAT_NOT_SUPPORTED;
58 std::string pseudo_type = root_node_->first_node(
"PP_HEADER")
59 ->first_attribute(
"pseudo_type")
62 if (pseudo_type ==
"NC" || pseudo_type ==
"SL") {
63 type_ = pseudopotential::type::KLEINMAN_BYLANDER;
64 }
else if (pseudo_type ==
"USPP") {
65 throw status::UNSUPPORTED_TYPE_ULTRASOFT;
66 }
else if (pseudo_type ==
"PAW") {
67 throw status::UNSUPPORTED_TYPE_PAW;
69 throw status::UNSUPPORTED_TYPE;
76 rapidxml::xml_base<> *xmin =
77 root_node_->first_node(
"PP_MESH")->first_attribute(
"xmin");
80 if (xmin &&
fabs(value<double>(xmin)) > 1.0e-10)
83 rapidxml::xml_node<> *node =
84 root_node_->first_node(
"PP_MESH")->first_node(
"PP_R");
88 rapidxml::xml_attribute<> *size_attr = node->first_attribute(
"size");
91 if (size_attr == NULL)
92 size_attr = root_node_->first_node(
"PP_MESH")->first_attribute(
"mesh");
94 if (size_attr == NULL)
95 throw status::FORMAT_NOT_SUPPORTED;
97 int size = value<int>(size_attr);
99 grid_.resize(size + start_point_);
100 std::istringstream stst(node->value());
102 for (
int ii = 0; ii < size; ii++)
103 stst >> grid_[start_point_ + ii];
105 assert(
fabs(grid_[0]) <= 1e-10);
109 rapidxml::xml_node<> *node =
110 root_node_->first_node(
"PP_MESH")->first_node(
"PP_RAB");
114 int size = get_size(node);
116 grid_weights_.resize(size + start_point_);
117 std::istringstream stst(node->value());
118 grid_weights_[0] = 0.5 * (grid_[1] - grid_[0]);
119 for (
int ii = 0; ii < size; ii++)
120 stst >> grid_weights_[start_point_ + ii];
123 for (
double rr = 0.0; rr <= grid_[grid_.size() - 1]; rr += mesh_spacing())
129 std::vector<bool> has_l(MAX_L,
false);
134 proj_l_.resize(nprojectors());
135 proj_c_.resize(nprojectors());
138 for (
int iproj = 0; iproj < nprojectors(); iproj++) {
139 std::ostringstream tag;
140 tag <<
"PP_BETA." << iproj + 1;
141 rapidxml::xml_node<> *node =
142 root_node_->first_node(
"PP_NONLOCAL")->first_node(tag.str().c_str());
146 int read_l = value<int>(node->first_attribute(
"angular_momentum"));
148 lmax_ = std::max(lmax_, read_l);
149 proj_l_[iproj] = read_l;
150 has_l[read_l] =
true;
155 for (
int jproj = 0; jproj < iproj; jproj++)
156 if (read_l == proj_l_[jproj])
159 nchannels_ = std::max(nchannels_, proj_c_[iproj] + 1);
165 for (
int l = 0;
l <= lmax_;
l++)
172 rapidxml::xml_node<> *node =
173 root_node_->first_node(
"PP_NONLOCAL")->first_node(
"PP_DIJ");
177 dij_.resize((lmax_ + 1) * nchannels_ * nchannels_);
179 for (
unsigned kk = 0; kk < dij_.size(); kk++)
182 std::istringstream stst(node->value());
183 for (
int ii = 0; ii < nprojectors(); ii++) {
184 for (
int jj = 0; jj < nprojectors(); jj++) {
188 if (proj_l_[ii] != proj_l_[jj]) {
189 assert(
fabs(val) < 1.0e-10);
194 d_ij(proj_l_[ii], proj_c_[ii], proj_c_[jj]) = val;
200 pseudopotential::format format()
const {
201 return pseudopotential::format::UPF2;
204 int size()
const {
return buffer_.size(); };
207 return root_node_->first_node(
"PP_INFO")->value();
211 return element::trim(root_node_->first_node(
"PP_HEADER")
212 ->first_attribute(
"element")
216 int atomic_number()
const {
217 element el(symbol());
218 return el.atomic_number();
221 double mass()
const {
222 element el(symbol());
226 double valence_charge()
const {
227 return value<double>(
228 root_node_->first_node(
"PP_HEADER")->first_attribute(
"z_valence"));
231 pseudopotential::exchange exchange()
const {
232 std::string functional = root_node_->first_node(
"PP_HEADER")
233 ->first_attribute(
"functional")
235 if (functional ==
"PBE")
236 return pseudopotential::exchange::PBE;
237 if (functional ==
"PBESOL")
238 return pseudopotential::exchange::PBE_SOL;
239 if (functional ==
"SLA PW NOGX NOGC")
240 return pseudopotential::exchange::LDA;
241 if (functional ==
"BLYP")
242 return pseudopotential::exchange::B88;
243 return pseudopotential::exchange::UNKNOWN;
246 pseudopotential::correlation correlation()
const {
247 std::string functional = root_node_->first_node(
"PP_HEADER")
248 ->first_attribute(
"functional")
250 if (functional ==
"PBE")
251 return pseudopotential::correlation::PBE;
252 if (functional ==
"PBESOL")
253 return pseudopotential::correlation::PBE_SOL;
254 if (functional ==
"SLA PW NOGX NOGC")
255 return pseudopotential::correlation::LDA_PW;
256 if (functional ==
"BLYP")
257 return pseudopotential::correlation::LYP;
258 return pseudopotential::correlation::UNKNOWN;
261 void local_potential(std::vector<double> &potential)
const {
262 rapidxml::xml_node<> *node = root_node_->first_node(
"PP_LOCAL");
266 int size = get_size(node);
268 potential.resize(size + start_point_);
269 std::istringstream stst(node->value());
270 for (
int ii = 0; ii < size; ii++) {
271 stst >> potential[ii + start_point_];
272 potential[ii + start_point_] *= 0.5;
274 if (start_point_ > 0)
275 extrapolate_first_point(potential);
277 interpolate(potential);
280 int nprojectors()
const {
282 root_node_->first_node(
"PP_HEADER")->first_attribute(
"number_of_proj"));
285 int nprojectors_per_l(
int l)
const {
288 for (
int jproj = 0; jproj < nprojectors(); jproj++)
289 if (proj_l_[jproj] ==
l)
290 nchannel = std::max(proj_c_[jproj]+1, nchannel);
294 void projector(
int l,
int i, std::vector<double> &proj)
const {
295 rapidxml::xml_node<> *node = NULL;
298 while ((
l != proj_l_[iproj] ||
i != proj_c_[iproj]) && iproj < nprojectors()) {
301 std::stringstream tag;
302 tag <<
"PP_BETA." << iproj+1;
303 node = root_node_->first_node(
"PP_NONLOCAL")->first_node(tag.str().c_str());
307 int size = get_size(node);
309 proj.resize(size + start_point_);
310 std::istringstream stst(node->value());
311 for (
int ii = 0; ii < size; ii++)
312 stst >> proj[ii + start_point_];
316 for (
int ii = 1; ii < size + start_point_; ii++)
317 proj[ii] /= grid_[ii];
318 extrapolate_first_point(proj);
323 bool has_radial_function(
int l)
const {
return false; }
325 void radial_function(
int l, std::vector<double> &function)
const {
329 void radial_potential(
int l, std::vector<double> &function)
const {
333 bool has_nlcc()
const {
return root_node_->first_node(
"PP_NLCC"); }
335 void nlcc_density(std::vector<double> &
density)
const {
336 rapidxml::xml_node<> *node = root_node_->first_node(
"PP_NLCC");
339 int size = get_size(node);
341 density.resize(size + start_point_);
343 std::istringstream stst(node->value());
344 for (
int ii = 0; ii < size; ii++)
345 stst >>
density[start_point_ + ii];
346 extrapolate_first_point(
density);
352 bool has_total_angular_momentum()
const {
353 return root_node_->first_node(
"PP_SPIN_ORB");
356 void beta(
int iproj,
int &
l, std::vector<double> &proj)
const {
357 rapidxml::xml_node<> *node = NULL;
359 std::stringstream tag;
360 tag <<
"PP_BETA." << iproj + 1;
361 node = root_node_->first_node(
"PP_NONLOCAL")->first_node(tag.str().c_str());
365 l = value<int>(node->first_attribute(
"angular_momentum"));
367 int size = get_size(node);
369 proj.resize(size + start_point_);
370 std::istringstream stst(node->value());
371 for (
int ii = 0; ii < size; ii++)
372 stst >> proj[ii + start_point_];
376 for (
int ii = 1; ii < size + start_point_; ii++)
377 proj[ii] /= grid_[ii];
378 extrapolate_first_point(proj);
383 void dnm_zero(
int nbeta, std::vector<std::vector<double>> &dnm)
const {
385 for (
int i = 0;
i < nbeta;
i++) {
386 dnm[
i].resize(nbeta);
387 for (
int j = 0;
j < nbeta;
j++) {
388 dnm[
i][
j] = dij_[
i * nbeta +
j];
393 bool has_density()
const {
return root_node_->first_node(
"PP_RHOATOM"); }
395 void density(std::vector<double> &val)
const {
396 rapidxml::xml_node<> *node = root_node_->first_node(
"PP_RHOATOM");
399 int size = get_size(node);
401 val.resize(size + start_point_);
403 std::istringstream stst(node->value());
404 for (
int ii = 0; ii < size; ii++)
405 stst >> val[start_point_ + ii];
408 for (
int ii = 1; ii < size + start_point_; ii++)
409 val[ii] /= 4.0 * M_PI * grid_[ii] * grid_[ii];
410 extrapolate_first_point(val);
415 int nwavefunctions()
const {
417 root_node_->first_node(
"PP_HEADER")->first_attribute(
"number_of_wfc"));
420 void wavefunction(
int index,
int &n,
int &
l,
double &occ,
421 std::vector<double> &proj)
const {
422 rapidxml::xml_node<> *node = NULL;
424 std::stringstream tag;
425 tag <<
"PP_CHI." <<
index + 1;
426 node = root_node_->first_node(
"PP_PSWFC")->first_node(tag.str().c_str());
431 if (node->first_attribute(
"n")) {
432 n = value<int>(node->first_attribute(
"n"));
434 std::string label = node->first_attribute(
"label")->value();
435 n = atoi(label.substr(0, 1).c_str());
438 l = value<int>(node->first_attribute(
"l"));
440 occ = value<double>(node->first_attribute(
"occupation"));
442 int size = get_size(node);
444 proj.resize(size + start_point_);
445 std::istringstream stst(node->value());
446 for (
int ii = 0; ii < size; ii++)
447 stst >> proj[ii + start_point_];
451 for (
int ii = 1; ii < size + start_point_; ii++)
452 proj[ii] /= grid_[ii];
453 extrapolate_first_point(proj);
459 int projector_2j(
int l,
int ic)
const {
464 for (
int iproj = 0; iproj < nprojectors(); iproj++) {
465 std::stringstream tag;
466 tag <<
"PP_RELBETA." << iproj + 1;
468 rapidxml::xml_node<> *node =
469 root_node_->first_node(
"PP_SPIN_ORB")->first_node(tag.str().c_str());
472 std::string labell = node->first_attribute(
"lll")->value();
473 if(atoi(labell.c_str()) ==
l && proj_c_[iproj] == ic){
474 std::string labelj = node->first_attribute(
"jjj")->value();
475 float j = atof(labelj.c_str());
477 return lrint(
j * 2.0);
486 int wavefunction_2j(
int ii)
const {
488 std::stringstream tag;
489 tag <<
"PP_RELWFC." << ii;
491 rapidxml::xml_node<> *node =
492 root_node_->first_node(
"PP_SPIN_ORB")->first_node(tag.str().c_str());
495 std::string label = node->first_attribute(
"jchi")->value();
496 float j = atof(label.c_str());
498 return lrint(
j * 2.0);
503 int get_size(
const rapidxml::xml_node<> *node)
const {
504 int size = grid_.size() - start_point_;
506 rapidxml::xml_attribute<> *size_attr = node->first_attribute(
"size");
508 if (size_attr != NULL)
509 size = value<int>(size_attr);
515 std::vector<char> buffer_;
516 rapidxml::xml_document<> doc_;
517 rapidxml::xml_node<> *root_node_;
518 std::vector<int> proj_l_;
519 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