Octopus 16.0
real-space, real-time, TDDFT code
upf2.hpp
Go to the documentation of this file.
1#ifndef PSEUDO_UPF2_HPP
2#define PSEUDO_UPF2_HPP
3
4/*
5 Copyright (C) 2018 Xavier Andrade
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20*/
21
22#include <cassert>
23#include <cmath>
24#include <fstream>
25#include <iostream>
26#include <sstream>
27#include <vector>
28
29#include "anygrid.hpp"
30#include "base.hpp"
31#include <rapidxml.hpp>
32
33#include "element.hpp"
34
35namespace pseudopotential {
36
37class upf2 : public pseudopotential::upf {
38
39public:
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>()) {
44
45 filename_ = filename;
46
47 buffer_.push_back('\0');
48 doc_.parse<0>(&buffer_[0]);
49
50 root_node_ = doc_.first_node("UPF");
51
52 if (!root_node_)
54
55 if (root_node_->first_attribute("version")->value()[0] != '2')
57
58 std::string pseudo_type = root_node_->first_node("PP_HEADER")
59 ->first_attribute("pseudo_type")
60 ->value();
61
62 if (pseudo_type == "NC" || pseudo_type == "SL") {
64 } else if (pseudo_type == "USPP") {
66 } else if (pseudo_type == "PAW") {
68 } else {
70 }
71
72 assert(root_node_);
73
74 // Read the grid
75 {
76 rapidxml::xml_base<> *xmin =
77 root_node_->first_node("PP_MESH")->first_attribute("xmin");
78
79 start_point_ = 0;
80 if (xmin && fabs(value<double>(xmin)) > 1.0e-10)
81 start_point_ = 1;
82
83 rapidxml::xml_node<> *node =
84 root_node_->first_node("PP_MESH")->first_node("PP_R");
85
86 assert(node);
87
88 rapidxml::xml_attribute<> *size_attr = node->first_attribute("size");
89
90 // some files seems to have this information elsewhere
91 if (size_attr == NULL)
92 size_attr = root_node_->first_node("PP_MESH")->first_attribute("mesh");
93
94 if (size_attr == NULL)
96
97 int size = value<int>(size_attr);
98
99 grid_.resize(size + start_point_);
100 std::istringstream stst(node->value());
101 grid_[0] = 0.0;
102 for (int ii = 0; ii < size; ii++)
103 stst >> grid_[start_point_ + ii];
104
105 assert(fabs(grid_[0]) <= 1e-10);
106 }
107
108 {
109 rapidxml::xml_node<> *node =
110 root_node_->first_node("PP_MESH")->first_node("PP_RAB");
111
112 assert(node);
113
114 int size = get_size(node);
115
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];
121
122 mesh_size_ = 0;
123 for (double rr = 0.0; rr <= grid_[grid_.size() - 1]; rr += mesh_spacing())
124 mesh_size_++;
125 }
126
127 // calculate lmax (we can't trust the one given by the file :-/)
128
129 std::vector<bool> has_l(MAX_L, false);
130
131 lmax_ = 0;
132 nchannels_ = 0;
133
134 proj_l_.resize(nprojectors());
135 proj_c_.resize(nprojectors());
136
137 // projector info
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());
143
144 assert(node);
145
146 int read_l = value<int>(node->first_attribute("angular_momentum"));
147
148 lmax_ = std::max(lmax_, read_l);
149 proj_l_[iproj] = read_l;
150 has_l[read_l] = true;
151
152 // now calculate the channel index, by counting previous projectors with
153 // the same l
154 proj_c_[iproj] = 0;
155 for (int jproj = 0; jproj < iproj; jproj++)
156 if (read_l == proj_l_[jproj])
157 proj_c_[iproj]++;
158
159 nchannels_ = std::max(nchannels_, proj_c_[iproj] + 1);
160 }
161
162 assert(lmax_ >= 0);
163
164 llocal_ = -1;
165 for (int l = 0; l <= lmax_; l++)
166 if (!has_l[l])
167 llocal_ = l;
168
169 // Read dij once
170 {
171
172 rapidxml::xml_node<> *node =
173 root_node_->first_node("PP_NONLOCAL")->first_node("PP_DIJ");
174
175 assert(node);
176
177 dij_.resize((lmax_ + 1) * nchannels_ * nchannels_);
178
179 for (unsigned kk = 0; kk < dij_.size(); kk++)
180 dij_[kk] = 0.0;
181
182 std::istringstream stst(node->value());
183 for (int ii = 0; ii < nprojectors(); ii++) {
184 for (int jj = 0; jj < nprojectors(); jj++) {
185 double val;
186 stst >> val;
187
188 if (proj_l_[ii] != proj_l_[jj]) {
189 assert(fabs(val) < 1.0e-10);
190 continue;
191 }
192
193 val *= 0.5; // convert from Rydberg to Hartree
194 d_ij(proj_l_[ii], proj_c_[ii], proj_c_[jj]) = val;
195 }
196 }
197 }
198 }
199
202 }
203
204 int size() const { return buffer_.size(); };
205
207 return root_node_->first_node("PP_INFO")->value();
208 }
209
211 return element::trim(root_node_->first_node("PP_HEADER")
212 ->first_attribute("element")
213 ->value());
214 }
215
216 int atomic_number() const {
217 element el(symbol());
218 return el.atomic_number();
219 }
220
221 double mass() const {
222 element el(symbol());
223 return el.mass();
224 }
225
226 double valence_charge() const {
227 return value<double>(
228 root_node_->first_node("PP_HEADER")->first_attribute("z_valence"));
229 }
230
232 std::string functional = root_node_->first_node("PP_HEADER")
233 ->first_attribute("functional")
234 ->value();
235 if (functional == "PBE")
237 if (functional == "PBESOL")
239 if (functional == "SLA PW NOGX NOGC")
241 if (functional == "BLYP")
244 }
245
247 std::string functional = root_node_->first_node("PP_HEADER")
248 ->first_attribute("functional")
249 ->value();
250 if (functional == "PBE")
252 if (functional == "PBESOL")
254 if (functional == "SLA PW NOGX NOGC")
256 if (functional == "BLYP")
259 }
260
261 void local_potential(std::vector<double> &potential) const {
262 rapidxml::xml_node<> *node = root_node_->first_node("PP_LOCAL");
263
264 assert(node);
265
266 int size = get_size(node);
267
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; // Convert from Rydberg to Hartree
273 }
274 if (start_point_ > 0)
275 extrapolate_first_point(potential);
276
277 interpolate(potential);
278 }
279
280 int nprojectors() const {
281 return value<int>(
282 root_node_->first_node("PP_HEADER")->first_attribute("number_of_proj"));
283 }
284
285 int nprojectors_per_l(int l) const {
286
287 int nchannel = 0;
288 for (int jproj = 0; jproj < nprojectors(); jproj++)
289 if (proj_l_[jproj] == l)
290 nchannel = std::max(proj_c_[jproj]+1, nchannel);
291 return nchannel;
292 }
293
294 void projector(int l, int i, std::vector<double> &proj) const {
295 rapidxml::xml_node<> *node = NULL;
296
297 int iproj = 0;
298 while ((l != proj_l_[iproj] || i != proj_c_[iproj]) && iproj < nprojectors()) {
299 iproj++;
300 }
301 std::stringstream tag;
302 tag << "PP_BETA." << iproj+1;
303 node = root_node_->first_node("PP_NONLOCAL")->first_node(tag.str().c_str());
304
305 assert(node);
306
307 int size = get_size(node);
308
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_];
313
314 // the projectors come multiplied by r, so we have to divide and fix the
315 // first point
316 for (int ii = 1; ii < size + start_point_; ii++)
317 proj[ii] /= grid_[ii];
319
320 interpolate(proj);
321 }
322
323 bool has_radial_function(int l) const { return false; }
324
325 void radial_function(int l, std::vector<double> &function) const {
326 function.clear();
327 }
328
329 void radial_potential(int l, std::vector<double> &function) const {
330 function.clear();
331 }
332
333 bool has_nlcc() const { return root_node_->first_node("PP_NLCC"); }
334
335 void nlcc_density(std::vector<double> &density) const {
336 rapidxml::xml_node<> *node = root_node_->first_node("PP_NLCC");
337 assert(node);
338
339 int size = get_size(node);
340
341 density.resize(size + start_point_);
342
343 std::istringstream stst(node->value());
344 for (int ii = 0; ii < size; ii++)
345 stst >> density[start_point_ + ii];
347 // this charge does not come multiplied by anything
348
350 }
351
353 return root_node_->first_node("PP_SPIN_ORB");
354 }
355
356 void beta(int iproj, int &l, std::vector<double> &proj) const {
357 rapidxml::xml_node<> *node = NULL;
358
359 std::stringstream tag;
360 tag << "PP_BETA." << iproj + 1;
361 node = root_node_->first_node("PP_NONLOCAL")->first_node(tag.str().c_str());
362
363 assert(node);
364
365 l = value<int>(node->first_attribute("angular_momentum"));
366
367 int size = get_size(node);
368
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_];
373
374 // the projectors come multiplied by r, so we have to divide and fix the
375 // first point
376 for (int ii = 1; ii < size + start_point_; ii++)
377 proj[ii] /= grid_[ii];
379
380 interpolate(proj);
381 }
382
383 void dnm_zero(int nbeta, std::vector<std::vector<double>> &dnm) const {
384 dnm.resize(nbeta);
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];
389 }
390 }
391 }
392
393 bool has_density() const { return root_node_->first_node("PP_RHOATOM"); }
394
395 void density(std::vector<double> &val) const {
396 rapidxml::xml_node<> *node = root_node_->first_node("PP_RHOATOM");
397 assert(node);
398
399 int size = get_size(node);
400
401 val.resize(size + start_point_);
402
403 std::istringstream stst(node->value());
404 for (int ii = 0; ii < size; ii++)
405 stst >> val[start_point_ + ii];
406
407 // the density comes multiplied by 4\pi r
408 for (int ii = 1; ii < size + start_point_; ii++)
409 val[ii] /= 4.0 * M_PI * grid_[ii] * grid_[ii];
411
413 }
414
415 int nwavefunctions() const {
416 return value<int>(
417 root_node_->first_node("PP_HEADER")->first_attribute("number_of_wfc"));
418 }
419
420 void wavefunction(int index, int &n, int &l, double &occ,
421 std::vector<double> &proj) const {
422 rapidxml::xml_node<> *node = NULL;
423
424 std::stringstream tag;
425 tag << "PP_CHI." << index + 1;
426 node = root_node_->first_node("PP_PSWFC")->first_node(tag.str().c_str());
427
428 assert(node);
429
430 // not all files have "n", so we might have to parse the label
431 if (node->first_attribute("n")) {
432 n = value<int>(node->first_attribute("n"));
433 } else {
434 std::string label = node->first_attribute("label")->value();
435 n = atoi(label.substr(0, 1).c_str());
436 }
437
438 l = value<int>(node->first_attribute("l"));
439
440 occ = value<double>(node->first_attribute("occupation"));
441
442 int size = get_size(node);
443
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_];
448
449 // the wavefunctions come multiplied by r, so we have to divide and fix the
450 // first point
451 for (int ii = 1; ii < size + start_point_; ii++)
452 proj[ii] /= grid_[ii];
454
455 interpolate(proj);
456 }
457
458 // Retreive the value of 2*j for relativistic projectors
459 int projector_2j(int l, int ic) const {
460
461 if (l == 0)
462 return 1;
463
464 for (int iproj = 0; iproj < nprojectors(); iproj++) {
465 std::stringstream tag;
466 tag << "PP_RELBETA." << iproj + 1;
467
468 rapidxml::xml_node<> *node =
469 root_node_->first_node("PP_SPIN_ORB")->first_node(tag.str().c_str());
470 assert(node);
471
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 double j = atof(labelj.c_str());
476
477 return lrint(j * 2.0);
478 }
479 }
480
481 return -1;
482 }
483
484
485 // Retreive the value of 2*j for relativitstic wavefunctions
486 int wavefunction_2j(int ii) const {
487
488 std::stringstream tag;
489 tag << "PP_RELWFC." << ii;
490
491 rapidxml::xml_node<> *node =
492 root_node_->first_node("PP_SPIN_ORB")->first_node(tag.str().c_str());
493 assert(node);
494
495 std::string label = node->first_attribute("jchi")->value();
496 double j = atof(label.c_str());
497
498 return lrint(j * 2.0);
499 }
500
501
502private:
503 int get_size(const rapidxml::xml_node<> *node) const {
504 int size = grid_.size() - start_point_;
505
506 rapidxml::xml_attribute<> *size_attr = node->first_attribute("size");
507
508 if (size_attr != NULL)
509 size = value<int>(size_attr);
510
511 return size;
512 }
513
514 std::ifstream file_;
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_;
520};
521
522} // namespace pseudopotential
523
524#endif
#define MAX_L
Definition: base.hpp:27
std::vector< double > grid_
Definition: anygrid.hpp:81
double mesh_spacing() const
Definition: anygrid.hpp:34
int mesh_size_
Definition: anygrid.hpp:83
std::vector< double > grid_weights_
Definition: anygrid.hpp:82
void interpolate(std::vector< double > &function) const
Definition: anygrid.hpp:61
std::string filename_
Definition: base.hpp:175
pseudopotential::type type_
Definition: base.hpp:185
int lmax_
Definition: base.hpp:186
Definition: element.hpp:34
double mass() const
Definition: element.hpp:73
int atomic_number() const
Definition: element.hpp:71
static std::string trim(std::string str, const std::string &chars="\t\n\v\f\r ")
Definition: element.hpp:140
Definition: upf2.hpp:37
double mass() const
Definition: upf2.hpp:221
std::vector< char > buffer_
Definition: upf2.hpp:515
int nprojectors() const
Definition: upf2.hpp:280
std::string description() const
Definition: upf2.hpp:206
int projector_2j(int l, int ic) const
Definition: upf2.hpp:459
rapidxml::xml_document doc_
Definition: upf2.hpp:516
pseudopotential::format format() const
Definition: upf2.hpp:200
bool has_nlcc() const
Definition: upf2.hpp:333
void nlcc_density(std::vector< double > &density) const
Definition: upf2.hpp:335
void local_potential(std::vector< double > &potential) const
Definition: upf2.hpp:261
bool has_total_angular_momentum() const
Definition: upf2.hpp:352
std::ifstream file_
Definition: upf2.hpp:514
bool has_density() const
Definition: upf2.hpp:393
void density(std::vector< double > &val) const
Definition: upf2.hpp:395
std::vector< int > proj_c_
Definition: upf2.hpp:519
pseudopotential::exchange exchange() const
Definition: upf2.hpp:231
double valence_charge() const
Definition: upf2.hpp:226
int size() const
Definition: upf2.hpp:204
int nprojectors_per_l(int l) const
Definition: upf2.hpp:285
void dnm_zero(int nbeta, std::vector< std::vector< double > > &dnm) const
Definition: upf2.hpp:383
rapidxml::xml_node * root_node_
Definition: upf2.hpp:517
void projector(int l, int i, std::vector< double > &proj) const
Definition: upf2.hpp:294
int nwavefunctions() const
Definition: upf2.hpp:415
std::string symbol() const
Definition: upf2.hpp:210
int get_size(const rapidxml::xml_node<> *node) const
Definition: upf2.hpp:503
std::vector< int > proj_l_
Definition: upf2.hpp:518
upf2(const std::string &filename, bool uniform_grid=false)
Definition: upf2.hpp:40
pseudopotential::correlation correlation() const
Definition: upf2.hpp:246
void radial_function(int l, std::vector< double > &function) const
Definition: upf2.hpp:325
bool has_radial_function(int l) const
Definition: upf2.hpp:323
void wavefunction(int index, int &n, int &l, double &occ, std::vector< double > &proj) const
Definition: upf2.hpp:420
int atomic_number() const
Definition: upf2.hpp:216
int wavefunction_2j(int ii) const
Definition: upf2.hpp:486
void radial_potential(int l, std::vector< double > &function) const
Definition: upf2.hpp:329
void beta(int iproj, int &l, std::vector< double > &proj) const
Definition: upf2.hpp:356
Definition: upf.hpp:33
double d_ij(int l, int i, int j) const
Definition: upf.hpp:38
int llocal_
Definition: upf.hpp:80
void extrapolate_first_point(std::vector< double > &function_) const
Definition: upf.hpp:59
std::vector< double > dij_
Definition: upf.hpp:79
int start_point_
Definition: upf.hpp:81
int nchannels_
Definition: upf.hpp:82
!The assertions are ignored if the code is compiled in not debug when !prints out the assertion string
Definition: global.h:58
void const fint const fint * val
Definition: iihash_low.cc:41
Definition: anygrid.hpp:27
correlation
Definition: base.hpp:74
format
Definition: base.hpp:49
exchange
Definition: base.hpp:64
ptrdiff_t l
Definition: operate_inc.c:51
ptrdiff_t j
Definition: operate_inc.c:51
const int *restrict index
Definition: operate_inc.c:52
void const fint * i
Definition: write_iter_low.cc:126