29 : pseudopotential_(pseudopotential), file_stream_(file_stream) {}
34 read_local_potential();
35 read_beta_projectors();
37 read_pseudo_wavefunctions();
38 read_atomic_charge_density();
39 read_core_charge_density();
44 using namespace upf_utilities;
45 find_tag(file_stream_,
"<PP_HEADER>");
47 std::getline(file_stream_, line);
48 std::getline(file_stream_, line);
50 std::istringstream stream(line);
51 stream >> pseudopotential_.
element;
53 std::getline(file_stream_, line);
55 std::istringstream stream(line);
58 std::string canonical_type = canonical_pseudopotential_type(token);
59 if (canonical_type ==
"PAW")
66 throw UnsupportedPseudopotentialTypeError(
67 "PAW pseudopotential not supported: UPF v1 header declares type PAW. "
68 "Q3 reads PAW datasets in UPF v2 format only; convert the file to v2, "
69 "or use an NC or US file instead.");
72 std::getline(file_stream_, line);
74 std::istringstream stream(line);
78 (token ==
"T" || token ==
"t" || token ==
".TRUE." || token ==
".true.");
80 std::getline(file_stream_, line);
82 std::getline(file_stream_, line);
84 std::istringstream stream(line);
87 std::getline(file_stream_, line);
88 std::getline(file_stream_, line);
89 std::getline(file_stream_, line);
91 std::istringstream stream(line);
94 std::getline(file_stream_, line);
96 std::istringstream stream(line);
99 std::getline(file_stream_, line);
101 std::istringstream stream(line);
105 std::getline(file_stream_, line);
106 for (
int wavefunction_index = 0;
108 wavefunction_index++)
109 std::getline(file_stream_, line);
111 check_header_is_usable();
125 void check_header_is_usable() {
126 auto reject = [
this](
const std::string& detail) {
127 throw std::runtime_error(
"Malformed UPF v1 file for element '" +
128 pseudopotential_.
element +
"': " + detail +
129 ". The PP_HEADER block is truncated or misaligned.");
132 reject(
"mesh size read as " + std::to_string(pseudopotential_.
mesh_size));
134 reject(
"valence charge read as " + std::to_string(pseudopotential_.
valence_charge));
136 reject(
"projector count read as " +
139 reject(
"maximum angular momentum read as " +
144 using namespace upf_utilities;
152 void read_local_potential() {
153 using namespace upf_utilities;
154 find_tag(file_stream_,
"<PP_LOCAL>");
159 void read_beta_projectors() {
160 using namespace upf_utilities;
161 find_tag(file_stream_,
"<PP_NONLOCAL>");
164 find_tag(file_stream_,
"<PP_BETA>");
166 std::string beta_line;
167 std::getline(file_stream_, beta_line);
169 std::istringstream stream(beta_line);
170 int projector_index, angular_momentum;
171 stream >> projector_index >> angular_momentum;
172 pseudopotential_.
projectors[beta_index].angular_momentum = angular_momentum;
175 std::getline(file_stream_, beta_line);
177 std::istringstream stream(beta_line);
179 stream >> cutoff_index;
180 pseudopotential_.
projectors[beta_index].number_of_radial_cutoff_points =
183 pseudopotential_.
projectors[beta_index].radial_values =
190 void read_d_matrix() {
191 using namespace upf_utilities;
193 int number_of_d_entries;
195 std::string dij_line;
196 std::getline(file_stream_, dij_line);
197 std::istringstream stream(dij_line);
198 stream >> number_of_d_entries;
203 for (
int entry_index = 0; entry_index < number_of_d_entries; entry_index++) {
204 int row_index, column_index;
206 file_stream_ >> row_index >> column_index >> value;
207 file_stream_.clear();
208 pseudopotential_.
d_ion_matrix[row_index - 1][column_index - 1] = value;
209 pseudopotential_.
d_ion_matrix[column_index - 1][row_index - 1] = value;
213 void read_pseudo_wavefunctions() {
214 using namespace upf_utilities;
215 find_tag(file_stream_,
"<PP_PSWFC>");
217 for (
int wavefunction_index = 0;
219 wavefunction_index++) {
222 std::getline(file_stream_, line);
223 }
while (
trim(line).empty());
224 std::istringstream stream(line);
226 int angular_momentum;
228 stream >> label >> angular_momentum >> occupations;
238 void read_atomic_charge_density() {
239 using namespace upf_utilities;
240 find_tag(file_stream_,
"<PP_RHOATOM>");
245 void read_core_charge_density() {
246 using namespace upf_utilities;
250 file_stream_.clear();
251 file_stream_.seekg(0);
252 if (
find_tag(file_stream_,
"<PP_NLCC>")) {
255 log::info(
" PP {}: NLCC core charge read ({} points)",
259 log::warn(
" PP {}: has_nlcc=true but PP_NLCC section not found",
265 Pseudopotential& pseudopotential_;
266 std::ifstream& file_stream_;