Octopus 16.0
real-space, real-time, TDDFT code
set.hpp
Go to the documentation of this file.
1#ifndef PSEUDO_SET_HPP
2#define PSEUDO_SET_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 <fstream>
23#include <map>
24#include <string>
25
26#include "element.hpp"
27
28#include "detect_format.hpp"
29#include "psml.hpp"
30#include "psp8.hpp"
31#include "qso.hpp"
32#include "upf1.hpp"
33#include "upf2.hpp"
34#include <dirent.h>
35#include <iostream>
36
37namespace pseudopotential {
38
39class set {
40
41private:
45 int lmax_;
47 };
48
49 typedef std::map<std::string, element_values> element_map;
50
53
54public:
55 set(const std::string &dirname) {
56
57 // Load the element mapping file, or regenerate it if not present
58 load_element_map(dirname);
59
60 for (auto& [key, elem] : map_) {
61 elem.file_dir_ = dirname;
62 }
63
64 }
65
66 bool has(const element &el) const {
67 return map_.find(el.symbol()) != map_.end();
68 }
69
70 std::string file_path(const element &el) const {
71 return map_.at(el.symbol()).file_dir_ + "/" + map_.at(el.symbol()).file_rel_path_;
72 }
73
74 int lmax(const element &el) const { return map_.at(el.symbol()).lmax_; }
75
76 int llocal(const element &el) const { return map_.at(el.symbol()).llocal_; }
77
78 // Generate a mapping file that stores the map
79 void generate_element_map(const std::string &dirname) {
80
81 DIR *dir = opendir(dirname.c_str());
82
83 struct dirent *ent;
84 while ((ent = readdir(dir)) != NULL) {
85 const std::string filename(ent->d_name);
86 const std::string fullname = dirname + "/" + filename;
87
88 if (filename == "." || filename == "..")
89 continue;
90
91 pseudopotential::format format = detect_format(fullname);
92
95 continue;
96
97 // we open the pseudo just to get the species symbol, this could be done
98 // in a better way
99 pseudopotential::base *pseudo = NULL;
100
101 std::string symbol;
102
103 switch (format) {
105 pseudo = new pseudopotential::qso(fullname);
106 break;
108 pseudo = new pseudopotential::upf1(fullname, /*uniform_grid = */ true);
109 break;
111 pseudo = new pseudopotential::upf2(fullname, /*uniform_grid = */ true);
112 break;
114 pseudo = new pseudopotential::psml(fullname, /*uniform_grid = */ true);
115 break;
117 pseudo = new pseudopotential::psp8(fullname);
118 break;
119 default:
120 // get the symbol from the name
121 for (int ii = 0; ii < 3; ii++) {
122 char cc = filename[ii];
123 bool is_letter = (cc >= 'a' && cc <= 'z') || (cc >= 'A' && cc <= 'Z');
124 if (!is_letter)
125 break;
126 symbol.push_back(cc);
127 }
128 }
129
130 if (pseudo)
131 symbol = pseudo->symbol();
132
133 delete pseudo;
134
135 element_values vals;
136
137 vals.file_rel_path_ = filename;
138 vals.lmax_ = INVALID_L;
139 vals.llocal_ = INVALID_L;
140
141 map_[symbol] = vals;
142 }
143
144 std::ifstream defaults_file((dirname + "/set_defaults").c_str());
145
146 if (defaults_file) {
147 std::string line;
148
149 // first line are comments
150 getline(defaults_file, line);
151
152 while (true) {
153 std::string symbol;
154 defaults_file >> symbol;
155 if (defaults_file.eof())
156 break;
157
158 if (has(symbol)) {
159 int z;
160 std::string fname;
161
162 defaults_file >> fname;
163 defaults_file >> z;
164 defaults_file >> map_[symbol].lmax_;
165 defaults_file >> map_[symbol].llocal_;
166 }
167
168 getline(defaults_file, line);
169 }
170
171 defaults_file.close();
172 }
173 closedir(dir);
174
175 // Write the element mapping file
176 const std::string file_name = dirname + "/elements_map.dat";
177 std::ofstream map_file(file_name);
178
179 if (!map_file.is_open()) {
180 throw std::ios_base::failure("Failed to open file for writing: " + file_name);
181 }
182
183 for (const auto& [symbol, elem] : map_) {
184 map_file << trim(symbol) << " "
185 << trim(elem.file_rel_path_) << " "
186 << elem.lmax_ << " "
187 << elem.llocal_ << "\n";
188 }
189
190 map_file.close();
191
192 }
193
194 // Load the map from the mapping file
195 void load_element_map(const std::string &dirname) {
196
197 // If this occurs, it means that we have a new set or a modified one.
198 // The generated file then needs to be copied in the source share folder and be added to the repo.
199 // Else, the parsing occurs at each run (sub-optimal).
200
201 std::ifstream map_file((dirname + "/elements_map.dat").c_str());
202 if (!map_file) {
203 std::cerr << "Internal warning: cannot open file element_map.dat for the pseudopotential set."
204 << std::endl;
205 std::cerr << "This will be regenerated in the installation folder."
206 << std::endl;
207 generate_element_map(dirname);
208 return;
209 }
210
211 std::string symbol;
212 while (map_file >> symbol) {
213 element_values vals;
214 // I didn't test this line
215 if (!(map_file >> vals.file_rel_path_ >> vals.lmax_ >> vals.llocal_)) {
216 std::cerr << "Error parsing the file: " << vals.file_rel_path_ << std::endl;
217 break;
218 }
219 map_[symbol] = vals;
220 }
221
222 }
223
225 const std::string &chars = "\t\n\v\f\r ") {
226 str.erase(0, str.find_first_not_of(chars));
227 return str;
228 }
229
231 const std::string &chars = "\t\n\v\f\r ") {
232 str.erase(str.find_last_not_of(chars) + 1);
233 return str;
234 }
235
237 const std::string &chars = "\t\n\v\f\r ") {
238 return ltrim(rtrim(str, chars), chars);
239 }
240
241
242 // Iterator interface
243
244 class iterator {
245
246 private:
247 element_map::iterator map_it_;
248
249 public:
250 iterator(const element_map::iterator &map_it) : map_it_(map_it) {}
251
253 ++map_it_;
254 return *this;
255 }
256
257 friend bool operator!=(const iterator &a, const iterator &b) {
258 return a.map_it_ != b.map_it_;
259 }
260
261 element operator*() { return element(map_it_->first); }
262 };
263
264 iterator begin() { return iterator(map_.begin()); }
265 iterator end() { return iterator(map_.end()); }
266};
267
268} // namespace pseudopotential
269
270#endif
#define INVALID_L
Definition: base.hpp:28
Definition: base.hpp:86
virtual std::string symbol() const =0
Definition: element.hpp:34
const std::string & symbol() const
Definition: element.hpp:69
Definition: psml.hpp:36
Definition: psp8.hpp:34
Definition: qso.hpp:35
Definition: set.hpp:244
friend bool operator!=(const iterator &a, const iterator &b)
Definition: set.hpp:257
iterator(const element_map::iterator &map_it)
Definition: set.hpp:250
element_map::iterator map_it_
Definition: set.hpp:247
iterator & operator++()
Definition: set.hpp:252
element operator*()
Definition: set.hpp:261
Definition: set.hpp:39
int lmax(const element &el) const
Definition: set.hpp:74
static std::string trim(std::string str, const std::string &chars="\t\n\v\f\r ")
Definition: set.hpp:236
bool automatic_
Definition: set.hpp:52
std::map< std::string, element_values > element_map
Definition: set.hpp:49
iterator begin()
Definition: set.hpp:264
set(const std::string &dirname)
Definition: set.hpp:55
std::string file_path(const element &el) const
Definition: set.hpp:70
static std::string & ltrim(std::string &str, const std::string &chars="\t\n\v\f\r ")
Definition: set.hpp:224
element_map map_
Definition: set.hpp:51
static std::string & rtrim(std::string &str, const std::string &chars="\t\n\v\f\r ")
Definition: set.hpp:230
bool has(const element &el) const
Definition: set.hpp:66
iterator end()
Definition: set.hpp:265
void load_element_map(const std::string &dirname)
Definition: set.hpp:195
void generate_element_map(const std::string &dirname)
Definition: set.hpp:79
int llocal(const element &el) const
Definition: set.hpp:76
Definition: upf1.hpp:37
Definition: upf2.hpp:37
!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 * key
Definition: iihash_low.cc:40
Definition: anygrid.hpp:27
format
Definition: base.hpp:49
double const double const double * b
Definition: spline_low.cc:121
double const double * a
Definition: spline_low.cc:120
int lmax_
Definition: set.hpp:45
int llocal_
Definition: set.hpp:46
std::string file_rel_path_
Definition: set.hpp:43
std::string file_dir_
Definition: set.hpp:44