Octopus 16.0
real-space, real-time, TDDFT code
upf1.hpp
Go to the documentation of this file.
1#ifndef PSEUDO_UPF1_HPP
2#define PSEUDO_UPF1_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 "base.hpp"
30#include "upf.hpp"
31#include <rapidxml.hpp>
32
33#include "element.hpp"
34
35namespace pseudopotential {
36
37class upf1 : public pseudopotential::upf {
38
39public:
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>()) {
44
45 filename_ = filename;
46
47 buffer_.push_back('\0');
48 doc_.parse<0>(&buffer_[0]);
49
50 std::istringstream header(doc_.first_node("PP_HEADER")->value());
51
52 std::string line;
53
54 int version_number;
55 header >> version_number;
56 getline(header, line);
57
58 header >> symbol_;
60 getline(header, line);
61
62 std::string pseudo_type;
63 header >> pseudo_type;
64 getline(header, line);
65
66 // nlcc tag
67 getline(header, line);
68
69 getline(header, xc_functional_);
70
71 header >> zval_;
72 getline(header, line);
73
74 // total energy
75 getline(header, line);
76
77 // cutoff
78 getline(header, line);
79
80 // skip lmax
81 getline(header, line);
82
83 int size;
84 header >> size;
85 getline(header, line);
86
87 header >> nwavefunctions_;
88 header >> nprojectors_;
89 getline(header, line);
90
91 std::transform(pseudo_type.begin(), pseudo_type.end(), pseudo_type.begin(),
92 ::tolower);
93
94 if (pseudo_type == "nc" || pseudo_type == "sl") {
96 } else if (pseudo_type == "uspp") {
98 } else if (pseudo_type == "paw") {
100 } else {
102 }
103
104 // Read the grid
105 {
106 rapidxml::xml_node<> *node =
107 doc_.first_node("PP_MESH")->first_node("PP_R");
108 assert(node);
109
110 std::istringstream stst(node->value());
111
112 // check whether the first point is zero or not
113 double xmin;
114 stst >> xmin;
115
116 start_point_ = 0;
117 if (xmin > 1.0e-10)
118 start_point_ = 1;
119
120 grid_.resize(size + start_point_);
121
122 grid_[0] = 0.0;
123 grid_[start_point_] = xmin;
124 for (int ii = 0; ii < size - 1; ii++)
125 stst >> grid_[1 + start_point_ + ii];
126
127 assert(fabs(grid_[0]) <= 1e-10);
128
129 mesh_size_ = 0;
130 for (double rr = 0.0; rr <= grid_[grid_.size() - 1]; rr += mesh_spacing())
131 mesh_size_++;
132 }
133
134 {
135 rapidxml::xml_node<> *node =
136 doc_.first_node("PP_MESH")->first_node("PP_R");
137 assert(node);
138
139 std::istringstream stst(node->value());
140
142
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];
146 }
147
148 // lmax and lloc
149 {
150
151 proj_l_.resize(nprojectors());
152 proj_c_.resize(nprojectors());
153
154 rapidxml::xml_node<> *node =
155 doc_.first_node("PP_NONLOCAL")->first_node("PP_BETA");
156
157 std::vector<bool> has_l(MAX_L, false);
158
159 lmax_ = 0;
160 nchannels_ = 0;
161 int iproj = 0;
162 while (node) {
163
164 std::string line;
165 std::istringstream stst(node->value());
166
167 int read_i, read_l;
168
169 stst >> read_i >> read_l;
170
171 read_i--;
172
173 assert(iproj == read_i);
174
175 lmax_ = std::max(lmax_, read_l);
176 has_l[read_l] = true;
177 proj_l_[iproj] = read_l;
178 proj_c_[iproj] = 0;
179 for (int jproj = 0; jproj < iproj; jproj++)
180 if (read_l == proj_l_[jproj])
181 proj_c_[iproj]++;
182
183 nchannels_ = std::max(nchannels_, proj_c_[iproj] + 1);
184
185 node = node->next_sibling("PP_BETA");
186 iproj++;
187 }
188
189 assert(lmax_ >= 0);
190
191 llocal_ = -1;
192 for (int l = 0; l <= lmax_; l++)
193 if (!has_l[l])
194 llocal_ = l;
195 }
196
197 // Read dij
198 {
199 rapidxml::xml_node<> *node =
200 doc_.first_node("PP_NONLOCAL")->first_node("PP_DIJ");
201
202 assert(node);
203
204 dij_.resize(nchannels() * nchannels() * (lmax_ + 1));
205
206 for (unsigned kk = 0; kk < dij_.size(); kk++)
207 dij_[kk] = 0.0;
208
209 std::istringstream stst(node->value());
210
211 int nnonzero;
212
213 stst >> nnonzero;
214 getline(stst, line);
215
216 for (int kk = 0; kk < nnonzero; kk++) {
217 int ii, jj;
218 double val;
219 stst >> ii >> jj >> val;
220 val *= 2.0; // convert from 1/Rydberg to 1/Hartree
221 ii--;
222 jj--;
223
224 assert(proj_l_[ii] == proj_l_[jj]);
225
226 d_ij(proj_l_[ii], proj_c_[ii], proj_c_[jj]) = val;
227 }
228 }
229 }
230
233 }
234
235 int size() const { return buffer_.size(); };
236
238 return doc_.first_node("PP_INFO")->value();
239 }
240
241 std::string symbol() const { return symbol_; }
242
243 int atomic_number() const {
244 element el(symbol());
245 return el.atomic_number();
246 }
247
248 double mass() const {
249 element el(symbol());
250 return el.mass();
251 }
252
253 double valence_charge() const { return zval_; }
254
256 if (xc_functional_ == "PBE")
258 if (xc_functional_ == "PBESOL")
260 if (xc_functional_ == "SLA PW NOGX NOGC")
262 if (xc_functional_ == "BLYP")
265 }
266
268 if (xc_functional_ == "PBE")
270 if (xc_functional_ == "PBESOL")
272 if (xc_functional_ == "SLA PW NOGX NOGC")
274 if (xc_functional_ == "BLYP")
277 }
278
279 void local_potential(std::vector<double> &potential) const {
280 rapidxml::xml_node<> *node = doc_.first_node("PP_LOCAL");
281
282 assert(node);
283
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; // Convert from Rydberg to Hartree
289 }
290 if (start_point_ > 0)
291 extrapolate_first_point(potential);
292
293 interpolate(potential);
294 }
295
296 int nprojectors() const { return nprojectors_; }
297
298 int nprojectors_per_l(int l) const {
299
300 int nchannel = 0;
301 for (int jproj = 0; jproj < nprojectors(); jproj++)
302 if (proj_l_[jproj] == l)
303 nchannel = std::max(proj_c_[jproj]+1, nchannel);
304 return nchannel;
305 }
306
307
308 void projector(int l, int i, std::vector<double> &proj) const {
309 proj.clear();
310
311 rapidxml::xml_node<> *node =
312 doc_.first_node("PP_NONLOCAL")->first_node("PP_BETA");
313
314 assert(node);
315
316 int iproj = 0;
317 while (l != proj_l_[iproj] || i != proj_c_[iproj]) {
318 iproj++;
319 node = node->next_sibling("PP_BETA");
320
321 if (!node)
322 return;
323 }
324
325 std::string line;
326 std::istringstream stst(node->value());
327
328 int read_i, read_l, size;
329
330 stst >> read_i >> read_l;
331 getline(stst, line);
332
333 assert(read_l == proj_l_[iproj]);
334
335 stst >> size;
336 getline(stst, line);
337
338 assert(size >= 0);
339 assert(size <= int(grid_.size()));
340
341 proj.resize(grid_.size());
342
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;
347
348 // the projectors come in Rydberg and multiplied by r, so we have to divide
349 // and fix the first point
350 for (unsigned ii = 1; ii < proj.size(); ii++)
351 proj[ii] /= 2.0 * grid_[ii];
353
354 interpolate(proj);
355 }
356
357 bool has_radial_function(int l) const { return false; }
358
359 void radial_function(int l, std::vector<double> &function) const {
360 function.clear();
361 }
362
363 void radial_potential(int l, std::vector<double> &function) const {
364 function.clear();
365 }
366
367 bool has_nlcc() const { return doc_.first_node("PP_NLCC"); }
368
369 void nlcc_density(std::vector<double> &density) const {
370 rapidxml::xml_node<> *node = doc_.first_node("PP_NLCC");
371 assert(node);
372 std::istringstream stst(node->value());
373
374 density.resize(grid_.size());
375
376 for (unsigned ii = 0; ii < grid_.size() - start_point_; ii++)
377 stst >> density[start_point_ + ii];
379 // this charge does not come multiplied by anything
380
382 }
383
384 bool has_density() const { return doc_.first_node("PP_RHOATOM"); }
385
386 void density(std::vector<double> &val) const {
387 rapidxml::xml_node<> *node = doc_.first_node("PP_RHOATOM");
388 assert(node);
389
390 val.resize(grid_.size());
391
392 std::istringstream stst(node->value());
393 for (unsigned ii = 0; ii < grid_.size() - start_point_; ii++)
394 stst >> val[start_point_ + ii];
395
396 // the density comes multiplied by 4\pi r
397 for (unsigned ii = 1; ii < val.size(); ii++)
398 val[ii] /= 4.0 * M_PI * grid_[ii] * grid_[ii];
400
402 }
403
404 int nwavefunctions() const { return nwavefunctions_; }
405
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");
409
410 assert(node);
411
412 std::istringstream stst(node->value());
413
414 std::string line;
415
416 // skip until the correct wavefunction
417 for (int ii = 0; ii < index; ii++) {
418 double tmp;
419
420 stst >> line;
421 getline(stst, line);
422 for (unsigned ii = 0; ii < grid_.size() - start_point_; ii++)
423 stst >> tmp;
424 }
425
426 std::string label;
427 stst >> label >> l >> occ;
428 getline(stst, line);
429
430 if (label == "s") {
431 n = 1;
432 } else {
433 n = atoi(label.substr(0, 1).c_str());
434 }
435
436 proj.resize(grid_.size());
437
438 for (unsigned ii = 0; ii < grid_.size() - start_point_; ii++)
439 stst >> proj[ii + start_point_];
440
441 // the wavefunctions come multiplied by r, so we have to divide and fix the
442 // first point
443 for (unsigned ii = 1; ii < grid_.size() - start_point_; ii++)
444 proj[ii] /= grid_[ii];
446
447 interpolate(proj);
448 }
449
451 return doc_.first_node("PP_ADDINFO");
452 }
453
454 int projector_2j(int l, int ic) const {
455
456 if (l == 0)
457 return 1;
458
459 rapidxml::xml_node<> *node = doc_.first_node("PP_ADDINFO");
460 assert(node);
461
462 std::istringstream stst(node->value());
463
464 for (int iwf = 0; iwf < nwavefunctions_; iwf++) {
465 std::string line;
466 stst >> line;
467 getline(stst, line);
468 }
469
470 for (int iproj = 0; iproj < nprojectors_; iproj++) {
471 int read_l;
472
473 stst >> read_l;
474
475 assert(read_l == proj_l_[iproj]);
476
477 if (proj_l_[iproj] == l && proj_c_[iproj] == ic) {
478 double read_j;
479 stst >> read_j;
480 return lrint(read_j * 2.0);
481 } else {
482 std::string line;
483 getline(stst, line);
484 }
485 }
486
487 assert(false);
488 return 0;
489 }
490
491 int wavefunction_2j(int ii) const {
492
493 assert(ii >= 0 && ii <= nwavefunctions_);
494
495 rapidxml::xml_node<> *node = doc_.first_node("PP_ADDINFO");
496 assert(node);
497
498 std::istringstream stst(node->value());
499
500 double j;
501 for (int iwf = 0; iwf < ii; iwf++) {
502 std::string label;
503 int n, l;
504 double occ;
505 stst >> label >> n >> l >> j >> occ;
506 }
507
508 return lrint(j * 2.0);
509 }
510
511private:
512 std::ifstream file_;
513 std::vector<char> buffer_;
514 rapidxml::xml_document<> doc_;
515
518 double zval_;
521 std::vector<int> proj_l_;
522 std::vector<int> proj_c_;
523};
524
525} // namespace pseudopotential
526
527#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: upf1.hpp:37
int nwavefunctions() const
Definition: upf1.hpp:404
bool has_density() const
Definition: upf1.hpp:384
std::vector< char > buffer_
Definition: upf1.hpp:513
int nprojectors_
Definition: upf1.hpp:520
int nprojectors_per_l(int l) const
Definition: upf1.hpp:298
std::string description() const
Definition: upf1.hpp:237
void local_potential(std::vector< double > &potential) const
Definition: upf1.hpp:279
int nwavefunctions_
Definition: upf1.hpp:519
double valence_charge() const
Definition: upf1.hpp:253
std::vector< int > proj_l_
Definition: upf1.hpp:521
std::ifstream file_
Definition: upf1.hpp:512
std::string symbol() const
Definition: upf1.hpp:241
pseudopotential::correlation correlation() const
Definition: upf1.hpp:267
pseudopotential::format format() const
Definition: upf1.hpp:231
bool has_total_angular_momentum() const
Definition: upf1.hpp:450
double mass() const
Definition: upf1.hpp:248
void density(std::vector< double > &val) const
Definition: upf1.hpp:386
std::vector< int > proj_c_
Definition: upf1.hpp:522
bool has_nlcc() const
Definition: upf1.hpp:367
bool has_radial_function(int l) const
Definition: upf1.hpp:357
int projector_2j(int l, int ic) const
Definition: upf1.hpp:454
rapidxml::xml_document doc_
Definition: upf1.hpp:514
upf1(const std::string &filename, bool uniform_grid=false)
Definition: upf1.hpp:40
int nprojectors() const
Definition: upf1.hpp:296
double zval_
Definition: upf1.hpp:518
int atomic_number() const
Definition: upf1.hpp:243
void radial_potential(int l, std::vector< double > &function) const
Definition: upf1.hpp:363
pseudopotential::exchange exchange() const
Definition: upf1.hpp:255
void nlcc_density(std::vector< double > &density) const
Definition: upf1.hpp:369
void projector(int l, int i, std::vector< double > &proj) const
Definition: upf1.hpp:308
int wavefunction_2j(int ii) const
Definition: upf1.hpp:491
void wavefunction(int index, int &n, int &l, double &occ, std::vector< double > &proj) const
Definition: upf1.hpp:406
std::string xc_functional_
Definition: upf1.hpp:517
int size() const
Definition: upf1.hpp:235
void radial_function(int l, std::vector< double > &function) const
Definition: upf1.hpp:359
std::string symbol_
Definition: upf1.hpp:516
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 nchannels() const
Definition: upf.hpp:49
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