29 : pseudopotential_(pseudopotential), content_(file_content) {}
33 int number_of_pairs = number_of_betas * number_of_betas;
36 number_of_betas, std::vector<Real>(number_of_betas, 0.0));
40 read_precomputed_qqq();
41 read_l_resolved_augmentation();
42 read_total_augmentation_fallback();
43 compute_missing_qqq_integrals();
47 void read_precomputed_qqq() {
48 using namespace upf_utilities;
51 auto position = content_.find(
"<PP_Q>");
52 if (position == std::string::npos)
53 position = content_.find(
"<PP_Q ");
54 if (position == std::string::npos)
57 auto end_position = content_.find(
"</PP_Q>", position);
58 if (end_position == std::string::npos)
61 auto tag_end = content_.find(
">", position);
62 std::string section = content_.substr(tag_end + 1, end_position - tag_end - 1);
63 std::vector<Real> qqq_flat = xml_data(section);
64 if (
static_cast<int>(qqq_flat.size()) >= number_of_betas * number_of_betas) {
65 for (
int row = 0; row < number_of_betas; row++) {
66 for (
int column = 0; column < number_of_betas; column++) {
68 qqq_flat[row * number_of_betas + column];
74 void read_l_resolved_augmentation() {
75 using namespace upf_utilities;
81 for (
auto& entry : pseudopotential_.augmentation_function_by_angular_momentum)
82 entry.resize(pseudopotential_.number_of_q_angular_momenta);
84 size_t search_position = 0;
85 while ((search_position = content_.find(
"<PP_QIJL", search_position)) !=
87 auto tag_end = content_.find(
">", search_position);
88 std::string tag_line = content_.substr(search_position, tag_end - search_position);
90 std::string angular_momentum_string =
xml_attribute(tag_line,
"angular_momentum");
91 std::string first_index_string =
xml_attribute(tag_line,
"first_index");
92 std::string second_index_string =
xml_attribute(tag_line,
"second_index");
93 if (first_index_string.empty() || second_index_string.empty() ||
94 angular_momentum_string.empty()) {
95 search_position = tag_end;
98 int beta_index_1 = std::stoi(first_index_string) - 1;
99 int beta_index_2 = std::stoi(second_index_string) - 1;
100 int angular_momentum = std::stoi(angular_momentum_string);
102 if (beta_index_1 < 0 || beta_index_1 >= number_of_betas || beta_index_2 < 0 ||
103 beta_index_2 >= number_of_betas || angular_momentum < 0 ||
105 search_position = tag_end;
110 auto space_position = tag_line.find(
" ");
111 std::string tag_name = tag_line.substr(1, space_position - 1);
112 std::string close_tag =
"</" + tag_name +
">";
114 auto close_position = content_.find(close_tag, search_position);
115 if (close_position != std::string::npos) {
116 std::string
section = content_.substr(tag_end + 1, close_position - tag_end - 1);
117 int pair_index = beta_index_1 * number_of_betas + beta_index_2;
118 int symmetric_pair_index = beta_index_2 * number_of_betas + beta_index_1;
120 data.resize(pseudopotential_.
mesh_size, 0.0);
124 [angular_momentum] = data;
127 if (angular_momentum == 0) {
133 search_position = tag_end;
137 void read_total_augmentation_fallback() {
138 using namespace upf_utilities;
166 size_t search_position = 0;
167 while ((search_position = content_.find(
"<PP_QIJ.", search_position)) !=
169 auto tag_end = content_.find(
">", search_position);
170 std::string tag_line = content_.substr(search_position, tag_end - search_position);
172 std::string first_index_string =
xml_attribute(tag_line,
"first_index");
173 std::string second_index_string =
xml_attribute(tag_line,
"second_index");
182 if (first_index_string.empty() || second_index_string.empty()) {
183 log::warn(
" PP: skipping augmentation block '{}' -- it carries no "
184 "first_index/second_index attributes to place it by",
186 search_position = tag_end;
189 int beta_index_1 = std::stoi(first_index_string) - 1;
190 int beta_index_2 = std::stoi(second_index_string) - 1;
192 if (beta_index_1 < 0 || beta_index_1 >= number_of_betas || beta_index_2 < 0 ||
193 beta_index_2 >= number_of_betas) {
194 search_position = tag_end;
198 int pair_index = beta_index_1 * number_of_betas + beta_index_2;
199 int symmetric_pair_index = beta_index_2 * number_of_betas + beta_index_1;
202 auto space_position = tag_line.find(
" ");
203 std::string tag_name = tag_line.substr(1, space_position - 1);
204 std::string close_tag =
"</" + tag_name +
">";
205 auto close_position = content_.find(close_tag, search_position);
206 if (close_position == std::string::npos) {
207 search_position = tag_end;
213 std::string
section = content_.substr(tag_end + 1, close_position - tag_end - 1);
224 std::string q_integral_string =
xml_attribute(tag_line,
"q_int");
225 if (!q_integral_string.empty()) {
227 std::stod(q_integral_string);
233 search_position = tag_end;
237 void compute_missing_qqq_integrals() {
241 for (
int beta_index_1 = 0; beta_index_1 < number_of_betas; beta_index_1++) {
242 for (
int beta_index_2 = beta_index_1; beta_index_2 < number_of_betas; beta_index_2++) {
254 .augmentation_function[beta_index_1 * number_of_betas + beta_index_2],
266 UltrasoftPseudopotential& pseudopotential_;
267 const std::string& content_;