Octopus 16.0
real-space, real-time, TDDFT code
psp8.hpp
Go to the documentation of this file.
1#ifndef PSEUDO_PSP8_HPP
2#define PSEUDO_PSP8_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 "element.hpp"
31
32namespace pseudopotential {
33
35
36public:
37 psp8(const std::string &filename) {
38
39 filename_ = filename;
40
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');
46
47 std::istringstream file(buffer);
48
50
51 // file size
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_;
56
57 // parse the header
58 file.seekg(0, std::ios::beg);
59 std::string line;
60
61 // line 1
62 getline(file, description_);
63
64 // line 2
65 double val;
66 file >> val;
67 atomic_number_ = round(val);
69 getline(file, line);
70
71 // line 3
72 int pspcod = -1;
73 file >> pspcod >> ixc_ >> lmax_ >> llocal_ >> mesh_size_;
74 if (pspcod != 8)
76 getline(file, line);
77
78 // line 4
79 file >> val;
80 file >> val;
81 nlcc_ = (val > 0.0);
82 getline(file, line);
83
84 // line 5
85 nprojectors_ = 0;
86 nchannels_ = 0;
87 for (int l = 0; l <= lmax_; l++) {
88 int np;
89 file >> np;
90 nprojl_.push_back(np);
91 nprojectors_ += np;
92 nchannels_ = std::max(nchannels_, np);
93 }
94 getline(file, line);
95
96 // line 6
97 int extension_switch;
98 file >> extension_switch;
99 getline(file, line);
100 has_density_ = extension_switch == 1;
101 has_soc_ = extension_switch == 2;
102
103 // there is an extra line for spin orbit stuff
104 if (has_soc_)
105 getline(file, line);
106
107 if (extension_switch > 2)
109
110 // the projectors and local potential
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]);
116
117 if (l == llocal_) {
119 continue;
120 }
121
122 if (nprojl_[l] == 0)
123 continue;
124
125 int read_l;
126 file >> read_l;
127
128 assert(read_l == l);
129
130 for (int iproj = 0; iproj < nprojl_[l]; iproj++) {
131 projectors_[l][iproj].resize(mesh_size_);
132 file >> ekb_[l][iproj];
133 }
134 getline(file, line);
135
136 for (int ip = 0; ip < mesh_size_; ip++) {
137 int read_ip;
138 double grid_point;
139 file >> read_ip >> grid_point;
140
141 assert(read_ip == ip + 1);
142
143 for (int iproj = 0; iproj < nprojl_[l]; iproj++)
144 file >> projectors_[l][iproj][ip];
145 getline(file, line);
146 }
147 }
148
149 // the local potential if it was not read before
150 if (llocal_ > lmax_)
152
153 // NLCC
154 if (nlcc_) {
156
157 for (int ip = 0; ip < mesh_size_; ip++) {
158 int read_ip;
159 double grid_point;
160 file >> read_ip >> grid_point >> nlcc_density_[ip];
161 assert(read_ip == ip + 1);
162 getline(file, line);
163 }
164 }
165
166 if (extension_switch == 1) {
167
168 density_.resize(mesh_size_);
169
170 for (int ip = 0; ip < mesh_size_; ip++) {
171 int read_ip;
172 double grid_point;
173 file >> read_ip >> grid_point >> density_[ip];
174 assert(read_ip == ip + 1);
175 getline(file, line);
176 }
177 }
178 }
179
182 }
183
184 int size() const { return file_size_; };
185
187
190 return el.symbol();
191 }
192
193 int atomic_number() const { return atomic_number_; }
194
195 double mass() const {
197 return el.mass();
198 }
199
200 double valence_charge() const { return valence_charge_; }
201
203 if (ixc_ > 0) {
204 if (ixc_ == 1)
206 if (ixc_ >= 2 && ixc_ <= 9)
208 if (ixc_ == 11 || ixc_ == 12)
210 } else {
211 return pseudopotential::exchange((-ixc_ + ixc_ % 1000) / 1000);
212 }
213
215 }
216
218 if (ixc_ > 0) {
219 if (ixc_ == 1)
221 if (ixc_ == 2)
223 if (ixc_ == 7)
225 if (ixc_ == 7 || ixc_ == 8)
227 if (ixc_ == 11)
229 if (ixc_ == 12)
231 } else {
232 return pseudopotential::correlation(-ixc_ % 1000);
233 }
234
236 }
237
238 int llocal() const {
239 if (llocal_ > lmax_)
240 return -1;
241 return llocal_;
242 }
243
244 int nchannels() const { return nchannels_; }
245
246 double mesh_spacing() const { return mesh_spacing_; }
247
248 int mesh_size() const { return mesh_size_; }
249
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];
255 }
256
257 int nprojectors() const { return nprojectors_; }
258
259 int nprojectors_per_l(int l) const {
260 return nprojl_[l];
261 }
262
263 void projector(int l, int i, std::vector<double> &proj) const {
264 proj.clear();
265
266 if (l > lmax_)
267 return;
268 if (i >= nprojl_[l])
269 return;
270
271 proj.resize(mesh_size_);
272 assert(mesh_size_ == projectors_[l][i].size());
273
274 for (int ip = 1; ip < mesh_size_; ip++)
275 proj[ip] = projectors_[l][i][ip] / (mesh_spacing() * ip);
276
278 }
279
280 double d_ij(int l, int i, int j) const {
281 if (i != j)
282 return 0.0;
283 if (i >= nprojl_[l])
284 return 0.0;
285 return ekb_[l][i];
286 }
287
288 bool has_radial_function(int l) const { return false; }
289
290 void radial_function(int l, std::vector<double> &function) const {
291 function.clear();
292 }
293
294 void radial_potential(int l, std::vector<double> &function) const {
295 function.clear();
296 }
297
298 bool has_nlcc() const { return nlcc_; }
299
300 bool has_total_angular_momentum() const { return has_soc_; }
301
302 void nlcc_density(std::vector<double> &density) const {
303 density.resize(mesh_size_);
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);
307 }
308
309 bool has_density() const { return has_density_; }
310
311 void density(std::vector<double> &density) const {
312 density.resize(mesh_size_);
313 assert(mesh_size_ == density_.size());
314 for (int ip = 0; ip < mesh_size_; ip++)
315 density[ip] = density_[ip] / (4.0 * M_PI);
316 }
317
318private:
319 void extrapolate_first_point(std::vector<double> &function_) const {
320
321 assert(function_.size() >= 4);
322
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];
329
330 // obtained from:
331 // http://www.wolframalpha.com/input/?i=solve+%7Bb*x1%5E2+%2B+c*x1+%2B+d+%3D%3D+f1,++b*x2%5E2+%2B+c*x2+%2B+d+%3D%3D+f2,+b*x3%5E2+%2B+c*x3+%2B+d+%3D%3D+f3+%7D++for+b,+c,+d
332
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);
336 }
337
338 void read_local_potential(std::istream &file) {
339 int read_llocal;
340 std::string line;
341
342 file >> read_llocal;
343
344 assert(llocal_ == read_llocal);
345 getline(file, line);
346
348 for (int ip = 0; ip < mesh_size_; ip++) {
349 int read_ip;
350 double grid_point;
351 file >> read_ip >> grid_point >> local_potential_[ip];
352 assert(read_ip == ip + 1);
353 getline(file, line);
354
355 if (ip == 1) {
356 mesh_spacing_ = grid_point;
357 }
358 }
359 }
360
365 int ixc_;
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_;
375 bool nlcc_;
376 std::vector<double> nlcc_density_;
378 std::vector<double> density_;
380};
381
382} // namespace pseudopotential
383
384#endif
Definition: base.hpp:86
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
const std::string & symbol() const
Definition: element.hpp:69
Definition: psp8.hpp:34
double d_ij(int l, int i, int j) const
Definition: psp8.hpp:280
int atomic_number_
Definition: psp8.hpp:363
bool has_radial_function(int l) const
Definition: psp8.hpp:288
bool has_nlcc() const
Definition: psp8.hpp:298
bool has_soc_
Definition: psp8.hpp:379
std::vector< double > nlcc_density_
Definition: psp8.hpp:376
int llocal() const
Definition: psp8.hpp:238
int nchannels() const
Definition: psp8.hpp:244
pseudopotential::format format() const
Definition: psp8.hpp:180
int llocal_
Definition: psp8.hpp:366
bool has_density_
Definition: psp8.hpp:377
int atomic_number() const
Definition: psp8.hpp:193
double valence_charge_
Definition: psp8.hpp:364
void radial_function(int l, std::vector< double > &function) const
Definition: psp8.hpp:290
int nchannels_
Definition: psp8.hpp:368
int mesh_size() const
Definition: psp8.hpp:248
void read_local_potential(std::istream &file)
Definition: psp8.hpp:338
std::vector< double > local_potential_
Definition: psp8.hpp:374
bool has_total_angular_momentum() const
Definition: psp8.hpp:300
std::string description() const
Definition: psp8.hpp:186
size_t file_size_
Definition: psp8.hpp:361
pseudopotential::exchange exchange() const
Definition: psp8.hpp:202
double mass() const
Definition: psp8.hpp:195
void nlcc_density(std::vector< double > &density) const
Definition: psp8.hpp:302
void local_potential(std::vector< double > &potential) const
Definition: psp8.hpp:250
double mesh_spacing() const
Definition: psp8.hpp:246
int nprojectors_
Definition: psp8.hpp:371
int mesh_size_
Definition: psp8.hpp:367
double mesh_spacing_
Definition: psp8.hpp:369
psp8(const std::string &filename)
Definition: psp8.hpp:37
std::vector< int > nprojl_
Definition: psp8.hpp:370
std::vector< std::vector< double > > ekb_
Definition: psp8.hpp:373
int nprojectors_per_l(int l) const
Definition: psp8.hpp:259
pseudopotential::correlation correlation() const
Definition: psp8.hpp:217
std::vector< std::vector< std::vector< double > > > projectors_
Definition: psp8.hpp:372
int ixc_
Definition: psp8.hpp:365
std::string description_
Definition: psp8.hpp:362
bool has_density() const
Definition: psp8.hpp:309
std::string symbol() const
Definition: psp8.hpp:188
int size() const
Definition: psp8.hpp:184
bool nlcc_
Definition: psp8.hpp:375
void projector(int l, int i, std::vector< double > &proj) const
Definition: psp8.hpp:263
void extrapolate_first_point(std::vector< double > &function_) const
Definition: psp8.hpp:319
void density(std::vector< double > &density) const
Definition: psp8.hpp:311
void radial_potential(int l, std::vector< double > &function) const
Definition: psp8.hpp:294
double valence_charge() const
Definition: psp8.hpp:200
int nprojectors() const
Definition: psp8.hpp:257
std::vector< double > density_
Definition: psp8.hpp:378
!The assertions are ignored if the code is compiled in not debug when !prints out the assertion the file
Definition: global.h:58
!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
void const fint * i
Definition: write_iter_low.cc:126