Octopus
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:
42 struct element_values {
43 std::string file_path_;
44 int lmax_;
45 int llocal_;
46 };
47
48 typedef std::map<std::string, element_values> element_map;
49
50 element_map map_;
51 bool automatic_;
52
53public:
54 set(const std::string &dirname) {
55
56 DIR *dir = opendir(dirname.c_str());
57
58 struct dirent *ent;
59 while ((ent = readdir(dir)) != NULL) {
60 const std::string filename(ent->d_name);
61 const std::string fullname = dirname + "/" + filename;
62
63 if (filename == "." || filename == "..")
64 continue;
65
66 pseudopotential::format format = detect_format(fullname);
67
68 if (format == pseudopotential::format::FILE_NOT_FOUND ||
69 format == pseudopotential::format::UNKNOWN)
70 continue;
71
72 // we open the pseudo just to get the species symbol, this could be done
73 // in a better way
74 pseudopotential::base *pseudo = NULL;
75
76 std::string symbol;
77
78 switch (format) {
79 case pseudopotential::format::QSO:
80 pseudo = new pseudopotential::qso(fullname);
81 break;
82 case pseudopotential::format::UPF1:
83 pseudo = new pseudopotential::upf1(fullname, /*uniform_grid = */ true);
84 break;
85 case pseudopotential::format::UPF2:
86 pseudo = new pseudopotential::upf2(fullname, /*uniform_grid = */ true);
87 break;
88 case pseudopotential::format::PSML:
89 pseudo = new pseudopotential::psml(fullname, /*uniform_grid = */ true);
90 break;
91 case pseudopotential::format::PSP8:
92 pseudo = new pseudopotential::psp8(fullname);
93 break;
94 default:
95 // get the symbol from the name
96 for (int ii = 0; ii < 3; ii++) {
97 char cc = filename[ii];
98 bool is_letter = (cc >= 'a' && cc <= 'z') || (cc >= 'A' && cc <= 'Z');
99 if (!is_letter)
100 break;
101 symbol.push_back(cc);
102 }
103 }
104
105 if (pseudo)
106 symbol = pseudo->symbol();
107
108 delete pseudo;
109
110 element_values vals;
111
112 vals.file_path_ = fullname;
113 vals.lmax_ = INVALID_L;
114 vals.llocal_ = INVALID_L;
115
116 map_[symbol] = vals;
117 }
118
119 std::ifstream defaults_file((dirname + "/set_defaults").c_str());
120
121 if (defaults_file) {
122 std::string line;
123
124 // first line are comments
125 getline(defaults_file, line);
126
127 while (true) {
128 std::string symbol;
129 defaults_file >> symbol;
130 if (defaults_file.eof())
131 break;
132
133 if (has(symbol)) {
134 int z;
135 std::string fname;
136
137 defaults_file >> fname;
138 defaults_file >> z;
139 defaults_file >> map_[symbol].lmax_;
140 defaults_file >> map_[symbol].llocal_;
141 }
142
143 getline(defaults_file, line);
144 }
145
146 defaults_file.close();
147 }
148 closedir(dir);
149 }
150
151 bool has(const element &el) const {
152 return map_.find(el.symbol()) != map_.end();
153 }
154
155 const std::string &file_path(const element &el) const {
156 return map_.at(el.symbol()).file_path_;
157 }
158
159 int lmax(const element &el) const { return map_.at(el.symbol()).lmax_; }
160
161 int llocal(const element &el) const { return map_.at(el.symbol()).llocal_; }
162
163 // Iterator interface
164
165 class iterator {
166
167 private:
168 element_map::iterator map_it_;
169
170 public:
171 iterator(const element_map::iterator &map_it) : map_it_(map_it) {}
172
173 iterator &operator++() {
174 ++map_it_;
175 return *this;
176 }
177
178 friend bool operator!=(const iterator &a, const iterator &b) {
179 return a.map_it_ != b.map_it_;
180 }
181
182 element operator*() { return element(map_it_->first); }
183 };
184
185 iterator begin() { return iterator(map_.begin()); }
186 iterator end() { return iterator(map_.end()); }
187};
188
189} // namespace pseudopotential
190
191#endif
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
Definition: global.h:46
type(oct_iterator_t), save iterator
struct __dirstream DIR
Definition: oct_f.c:4654
DIR DIR struct dirent * readdir(DIR *__dirp) __attribute__((__nonnull__(1)))
DIR * opendir(const char *__name) __attribute__((__nonnull__(1))) __attribute__((__malloc__)) __attribute__((__malloc__(closedir
int closedir(DIR *__dirp) __attribute__((__nonnull__(1)))