Skip to content

Commit 4dd1899

Browse files
author
abacus_fixer
committed
refactor(klist): extract this-free helpers into klist_io TU
Move the IBZ table formatters and line-mode interpolation out of klist.cpp into a new source_cell/klist_io.{h,cpp} (namespace KListIO): - ibz_kpt_table / ibz_wk_table: pure string formatting, unchanged output. - interp_line: this-free line-mode interpolation returning LineK {kpts, segids, nks_total}; K_Vectors::interpolate_k_between becomes a thin wrapper that sizes members and copies results back. klist.cpp: 926 -> 830 lines, quality score 6 -> 12; klist_io.cpp scores 100. reduce_by_symmetry and parse_kfile lose their largest this-free blocks. CMake: klist_io.cpp added to the cell library; 16 test targets that compile klist.cpp without linking cell_info also register klist_io.cpp. Verified: cmake --build build_max_para_test -j30 (exit 0) and ctest -R "MODULE_CELL_(klist|reciprocal_grid|qlist)|MODULE_IO_...| MODULE_ESTATE_...|MODULE_HSOLVER_pw|MODULE_LCAO_deltaspin" -> 27/27.
1 parent b834529 commit 4dd1899

14 files changed

Lines changed: 214 additions & 154 deletions

File tree

source/source_cell/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ add_library(
2222
read_atoms_helper.cpp
2323
read_orb.cpp
2424
klist.cpp
25+
klist_io.cpp
2526
reciprocal_grid.cpp
2627
parallel_kpoints.cpp
2728
cell_index.cpp

source/source_cell/klist.cpp

Lines changed: 11 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -4,77 +4,13 @@
44
*/
55
#include "klist.h"
66

7+
#include "klist_io.h"
78
#include "source_base/formatter.h"
89
#include "source_base/parallel_common.h"
910
#include "source_base/parallel_global.h"
1011
#include "source_base/parallel_reduce.h"
1112
#include "source_cell/module_symmetry/symmetry.h"
1213

13-
// Free formatting helpers for the IBZ reduction tables. Defined in this
14-
// file (not in a separate TU) because many test targets across the tree
15-
// compile klist.cpp alone; a separate TU would need registering everywhere.
16-
// Deliberately not static and not in an anonymous namespace.
17-
namespace KListSymm
18-
{
19-
20-
std::string ibz_kpt_table(const int nkstot,
21-
const std::vector<ModuleBase::Vector3<double>>& kvec_d,
22-
const std::vector<int>& ibz_index,
23-
const std::vector<ModuleBase::Vector3<double>>& kvec_d_ibz)
24-
{
25-
std::stringstream ss;
26-
ss << " " << std::setw(40) << "nkstot"
27-
<< " = " << nkstot << std::setw(66) << "ibzkpt" << std::endl;
28-
std::string table;
29-
table += "K-POINTS REDUCTION ACCORDING TO SYMMETRY\n";
30-
table += FmtCore::format("%8s%12s%12s%12s%8s%12s%12s%12s\n",
31-
"KPT",
32-
"DIRECT_X",
33-
"DIRECT_Y",
34-
"DIRECT_Z",
35-
"IBZ",
36-
"DIRECT_X",
37-
"DIRECT_Y",
38-
"DIRECT_Z");
39-
for (int i = 0; i < nkstot; ++i)
40-
{
41-
table += FmtCore::format("%8d%12.8f%12.8f%12.8f%8d%12.8f%12.8f%12.8f\n",
42-
i + 1,
43-
kvec_d[i].x,
44-
kvec_d[i].y,
45-
kvec_d[i].z,
46-
ibz_index[i] + 1,
47-
kvec_d_ibz[ibz_index[i]].x,
48-
kvec_d_ibz[ibz_index[i]].y,
49-
kvec_d_ibz[ibz_index[i]].z);
50-
}
51-
ss << table << std::endl;
52-
return ss.str();
53-
}
54-
55-
std::string ibz_wk_table(const int nkstot_ibz,
56-
const std::vector<ModuleBase::Vector3<double>>& kvec_d_ibz,
57-
const std::vector<double>& wk_ibz,
58-
const std::vector<int>& ibz2bz)
59-
{
60-
std::string table;
61-
table += "\n K-POINTS REDUCTION ACCORDING TO SYMMETRY\n";
62-
table += FmtCore::format("%8s%12s%12s%12s%8s%8s\n", "IBZ", "DIRECT_X", "DIRECT_Y", "DIRECT_Z", "WEIGHT", "ibz2bz");
63-
for (int ik = 0; ik < nkstot_ibz; ik++)
64-
{
65-
table += FmtCore::format("%8d%12.8f%12.8f%12.8f%8.4f%8d\n",
66-
ik + 1,
67-
kvec_d_ibz[ik].x,
68-
kvec_d_ibz[ik].y,
69-
kvec_d_ibz[ik].z,
70-
wk_ibz[ik],
71-
ibz2bz[ik]);
72-
}
73-
return table;
74-
}
75-
76-
} // namespace KListSymm
77-
7814
void K_Vectors::cal_ik_global()
7915
{
8016
const int my_pool = this->para_k.my_pool;
@@ -509,75 +445,18 @@ bool K_Vectors::parse_kfile(const std::string& fn, std::ofstream& ofs_running)
509445

510446
void K_Vectors::interpolate_k_between(std::ifstream& ifk, std::vector<ModuleBase::Vector3<double>>& kvec)
511447
{
512-
// how many special points.
513-
int nks_special = this->nkstot;
514-
515-
// number of points to the next k points
516-
std::vector<int> nkl(nks_special, 0);
517-
518-
// coordinates of special points.
519-
std::vector<ModuleBase::Vector3<double>> ks(nks_special);
520-
521-
// recalculate nkstot.
522-
nkstot = 0;
523-
/* ISSUE#3482: to distinguish different kline segments */
524-
std::vector<int> kpt_segids;
525-
kl_segids.clear();
526-
kl_segids.shrink_to_fit();
527-
int kpt_segid = 0;
528-
for (int iks = 0; iks < nks_special; iks++)
529-
{
530-
ifk >> ks[iks].x;
531-
ifk >> ks[iks].y;
532-
ifk >> ks[iks].z;
533-
ModuleBase::GlobalFunc::READ_VALUE(ifk, nkl[iks]);
534-
535-
if (nkl[iks] <= 0)
536-
{
537-
ModuleBase::WARNING_QUIT("K_Vectors::interpolate_k_between",
538-
"Line-mode interpolation counts must be positive.");
539-
}
540-
nkstot += nkl[iks];
541-
/* ISSUE#3482: to distinguish different kline segments */
542-
if ((nkl[iks] == 1) && (iks != (nks_special - 1))) {
543-
kpt_segid++;
544-
}
545-
kpt_segids.push_back(kpt_segid);
546-
}
547-
if (nkl[nks_special - 1] != 1)
548-
{
549-
ModuleBase::WARNING_QUIT("K_Vectors::interpolate_k_between",
550-
"The final line-mode k-point must have an interpolation count of 1.");
551-
}
448+
// Thin wrapper: the interpolation itself is the this-free KListIO::interp_line;
449+
// here we only size the member containers and copy the results back.
450+
const KListIO::LineK line = KListIO::interp_line(ifk, this->nkstot);
552451

553-
// std::cout << " nkstot = " << nkstot << std::endl;
554-
this->renew(nkstot * this->spin_mult); // mohan fix bug 2009-09-01
452+
this->nkstot = line.nks_total;
453+
this->renew(this->nkstot * this->spin_mult); // mohan fix bug 2009-09-01
555454

556-
int count = 0;
557-
for (int iks = 1; iks < nks_special; iks++)
455+
for (int i = 0; i < this->nkstot; i++)
558456
{
559-
double dxs = (ks[iks].x - ks[iks - 1].x) / nkl[iks - 1];
560-
double dys = (ks[iks].y - ks[iks - 1].y) / nkl[iks - 1];
561-
double dzs = (ks[iks].z - ks[iks - 1].z) / nkl[iks - 1];
562-
for (int is = 0; is < nkl[iks - 1]; is++)
563-
{
564-
kvec[count].x = ks[iks - 1].x + is * dxs;
565-
kvec[count].y = ks[iks - 1].y + is * dys;
566-
kvec[count].z = ks[iks - 1].z + is * dzs;
567-
kl_segids.push_back(kpt_segids[iks - 1]); /* ISSUE#3482: to distinguish different kline segments */
568-
++count;
569-
}
457+
kvec[i] = line.kpts[i];
570458
}
571-
572-
// deal with the last special k point.
573-
kvec[count].x = ks[nks_special - 1].x;
574-
kvec[count].y = ks[nks_special - 1].y;
575-
kvec[count].z = ks[nks_special - 1].z;
576-
kl_segids.push_back(kpt_segids[nks_special - 1]); /* ISSUE#3482: to distinguish different kline segments */
577-
++count;
578-
579-
assert(count == nkstot);
580-
assert(kl_segids.size() == nkstot); /* ISSUE#3482: to distinguish different kline segments */
459+
this->kl_segids = line.segids; /* ISSUE#3482: to distinguish different kline segments */
581460
}
582461

583462
void K_Vectors::update_use_ibz(const int& nkstot_ibz,
@@ -776,10 +655,10 @@ void K_Vectors::reduce_by_symmetry(const UnitCell& ucell,
776655
#endif
777656

778657
// output in kpoints file
779-
skpt = KListSymm::ibz_kpt_table(this->nkstot, this->kvec_d, this->ibz_index, kvec_d_ibz);
658+
skpt = KListIO::ibz_kpt_table(this->nkstot, this->kvec_d, this->ibz_index, kvec_d_ibz);
780659
ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "Number of irreducible k-points", nkstot_ibz);
781660

782-
GlobalV::ofs_running << KListSymm::ibz_wk_table(nkstot_ibz, kvec_d_ibz, wk_ibz, ibz2bz) << std::endl;
661+
GlobalV::ofs_running << KListIO::ibz_wk_table(nkstot_ibz, kvec_d_ibz, wk_ibz, ibz2bz) << std::endl;
783662

784663
// resize the kpoint container according to nkstot_ibz
785664
if (use_symm || this->get_is_mp())

source/source_cell/klist_io.cpp

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/**
2+
* @file klist_io.cpp
3+
* @brief this-free helpers extracted from K_Vectors (IBZ table formatting and
4+
* line-mode k-point interpolation). Kept separate from klist.cpp so the
5+
* logic is testable in isolation; klist.cpp only keeps thin wrappers.
6+
*/
7+
#include "klist_io.h"
8+
9+
#include "source_base/formatter.h"
10+
#include "source_base/global_function.h"
11+
12+
#include <sstream>
13+
14+
namespace KListIO
15+
{
16+
17+
std::string ibz_kpt_table(const int nkstot,
18+
const std::vector<ModuleBase::Vector3<double>>& kvec_d,
19+
const std::vector<int>& ibz_index,
20+
const std::vector<ModuleBase::Vector3<double>>& kvec_d_ibz)
21+
{
22+
std::stringstream ss;
23+
ss << " " << std::setw(40) << "nkstot"
24+
<< " = " << nkstot << std::setw(66) << "ibzkpt" << std::endl;
25+
std::string table;
26+
table += "K-POINTS REDUCTION ACCORDING TO SYMMETRY\n";
27+
table += FmtCore::format("%8s%12s%12s%12s%8s%12s%12s%12s\n",
28+
"KPT",
29+
"DIRECT_X",
30+
"DIRECT_Y",
31+
"DIRECT_Z",
32+
"IBZ",
33+
"DIRECT_X",
34+
"DIRECT_Y",
35+
"DIRECT_Z");
36+
for (int i = 0; i < nkstot; ++i)
37+
{
38+
table += FmtCore::format("%8d%12.8f%12.8f%12.8f%8d%12.8f%12.8f%12.8f\n",
39+
i + 1,
40+
kvec_d[i].x,
41+
kvec_d[i].y,
42+
kvec_d[i].z,
43+
ibz_index[i] + 1,
44+
kvec_d_ibz[ibz_index[i]].x,
45+
kvec_d_ibz[ibz_index[i]].y,
46+
kvec_d_ibz[ibz_index[i]].z);
47+
}
48+
ss << table << std::endl;
49+
return ss.str();
50+
}
51+
52+
std::string ibz_wk_table(const int nkstot_ibz,
53+
const std::vector<ModuleBase::Vector3<double>>& kvec_d_ibz,
54+
const std::vector<double>& wk_ibz,
55+
const std::vector<int>& ibz2bz)
56+
{
57+
std::string table;
58+
table += "\n K-POINTS REDUCTION ACCORDING TO SYMMETRY\n";
59+
table += FmtCore::format("%8s%12s%12s%12s%8s%8s\n", "IBZ", "DIRECT_X", "DIRECT_Y", "DIRECT_Z", "WEIGHT", "ibz2bz");
60+
for (int ik = 0; ik < nkstot_ibz; ik++)
61+
{
62+
table += FmtCore::format("%8d%12.8f%12.8f%12.8f%8.4f%8d\n",
63+
ik + 1,
64+
kvec_d_ibz[ik].x,
65+
kvec_d_ibz[ik].y,
66+
kvec_d_ibz[ik].z,
67+
wk_ibz[ik],
68+
ibz2bz[ik]);
69+
}
70+
return table;
71+
}
72+
73+
LineK interp_line(std::ifstream& ifk, const int nks_special)
74+
{
75+
// number of points to the next k points
76+
std::vector<int> nkl(nks_special, 0);
77+
78+
// coordinates of special points.
79+
std::vector<ModuleBase::Vector3<double>> ks(nks_special);
80+
81+
LineK out;
82+
std::vector<int> kpt_segids;
83+
int kpt_segid = 0;
84+
for (int iks = 0; iks < nks_special; iks++)
85+
{
86+
ifk >> ks[iks].x;
87+
ifk >> ks[iks].y;
88+
ifk >> ks[iks].z;
89+
ModuleBase::GlobalFunc::READ_VALUE(ifk, nkl[iks]);
90+
91+
if (nkl[iks] <= 0)
92+
{
93+
ModuleBase::WARNING_QUIT("KListIO::interp_line",
94+
"Line-mode interpolation counts must be positive.");
95+
}
96+
out.nks_total += nkl[iks];
97+
/* ISSUE#3482: to distinguish different kline segments */
98+
if ((nkl[iks] == 1) && (iks != (nks_special - 1))) {
99+
kpt_segid++;
100+
}
101+
kpt_segids.push_back(kpt_segid);
102+
}
103+
if (nkl[nks_special - 1] != 1)
104+
{
105+
ModuleBase::WARNING_QUIT("KListIO::interp_line",
106+
"The final line-mode k-point must have an interpolation count of 1.");
107+
}
108+
109+
out.kpts.resize(out.nks_total);
110+
out.segids.reserve(out.nks_total);
111+
112+
int count = 0;
113+
for (int iks = 1; iks < nks_special; iks++)
114+
{
115+
double dxs = (ks[iks].x - ks[iks - 1].x) / nkl[iks - 1];
116+
double dys = (ks[iks].y - ks[iks - 1].y) / nkl[iks - 1];
117+
double dzs = (ks[iks].z - ks[iks - 1].z) / nkl[iks - 1];
118+
for (int is = 0; is < nkl[iks - 1]; is++)
119+
{
120+
out.kpts[count].x = ks[iks - 1].x + is * dxs;
121+
out.kpts[count].y = ks[iks - 1].y + is * dys;
122+
out.kpts[count].z = ks[iks - 1].z + is * dzs;
123+
out.segids.push_back(kpt_segids[iks - 1]); /* ISSUE#3482 */
124+
++count;
125+
}
126+
}
127+
128+
// deal with the last special k point.
129+
out.kpts[count].x = ks[nks_special - 1].x;
130+
out.kpts[count].y = ks[nks_special - 1].y;
131+
out.kpts[count].z = ks[nks_special - 1].z;
132+
out.segids.push_back(kpt_segids[nks_special - 1]); /* ISSUE#3482 */
133+
++count;
134+
135+
assert(count == out.nks_total);
136+
assert(out.segids.size() == static_cast<size_t>(out.nks_total)); /* ISSUE#3482 */
137+
return out;
138+
}
139+
140+
} // namespace KListIO

source/source_cell/klist_io.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#ifndef KLIST_IO_H
2+
#define KLIST_IO_H
3+
4+
#include "source_base/vector3.h"
5+
6+
#include <fstream>
7+
#include <string>
8+
#include <vector>
9+
10+
/// this-free helpers extracted from K_Vectors, kept in a separate TU so they
11+
/// can be unit-tested and reused without dragging in the K_Vectors class.
12+
namespace KListIO
13+
{
14+
/// Render the IBZ reduction table ("IBZ" k-point -> originating k-point).
15+
std::string ibz_kpt_table(int nkstot,
16+
const std::vector<ModuleBase::Vector3<double>>& kvec_d,
17+
const std::vector<int>& ibz_index,
18+
const std::vector<ModuleBase::Vector3<double>>& kvec_d_ibz);
19+
20+
/// Render the IBZ weight table (IBZ k-point, weight, multiplicity, origin index).
21+
std::string ibz_wk_table(int nkstot_ibz,
22+
const std::vector<ModuleBase::Vector3<double>>& kvec_d_ibz,
23+
const std::vector<double>& wk_ibz,
24+
const std::vector<int>& ibz2bz);
25+
26+
/// Result of line-mode interpolation between special k-points.
27+
struct LineK
28+
{
29+
std::vector<ModuleBase::Vector3<double>> kpts; ///< interpolated k points
30+
std::vector<int> segids; ///< segment id per k point (ISSUE#3482)
31+
int nks_total = 0; ///< total interpolated k-point count
32+
};
33+
34+
/// Read the special k points and per-point interpolation counts from `ifk`,
35+
/// then linearly interpolate the line-mode k points. Pure function of the
36+
/// stream and `nks_special`; dies via WARNING_QUIT on malformed input.
37+
LineK interp_line(std::ifstream& ifk, int nks_special);
38+
} // namespace KListIO
39+
40+
#endif // KLIST_IO_H

source/source_cell/test/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ AddTest(
8686
AddTest(
8787
TARGET MODULE_CELL_klist_test
8888
LIBS base device symmetry
89-
SOURCES klist_test.cpp ../klist.cpp ../parallel_kpoints.cpp ../reciprocal_grid.cpp
89+
SOURCES klist_test.cpp ../klist.cpp ../klist_io.cpp ../parallel_kpoints.cpp ../reciprocal_grid.cpp
9090
)
9191

9292
AddTest(
@@ -110,7 +110,7 @@ AddTest(
110110
AddTest(
111111
TARGET MODULE_CELL_klist_test_para1
112112
LIBS base device symmetry
113-
SOURCES klist_test_para.cpp ../klist.cpp ../parallel_kpoints.cpp ../reciprocal_grid.cpp
113+
SOURCES klist_test_para.cpp ../klist.cpp ../klist_io.cpp ../parallel_kpoints.cpp ../reciprocal_grid.cpp
114114
)
115115

116116
add_test(NAME MODULE_CELL_klist_test_para4

0 commit comments

Comments
 (0)