Skip to content

Commit 09b423e

Browse files
Cstandardlibclaude
andauthored
fix(sdft): add CT (Chebyshev Trace) iter_header for pure SDFT without diagonalization (#7388)
* fix(sdft): add CT (Chebyshev Trace) iter_header for pure SDFT without diagonalization Pure SDFT (nbands=0) does not perform KS diagonalization, yet the SCF iteration table borrowed the ks_solver label (CG/DA/etc.). Add a "CT" entry to iter_header_dict and use it when esolver_type=sdft with nbands=0. Mixed SDFT (nbands>0) keeps the actual ks_solver label since it still diagonalizes KS orbitals. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * test(sdft): add unit tests for SDFT iter_header CT label Verify pure SDFT (nbands=0) outputs "CT" in ITER column, and mixed SDFT (nbands>0) outputs the actual ks_solver label (e.g. "DA"). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 67a0e88 commit 09b423e

2 files changed

Lines changed: 70 additions & 2 deletions

File tree

source/source_estate/elecstate_print.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ void print_scf_iterinfo(const std::string& ks_solver,
5959
{"cusolver", "CU"},
6060
{"bpcg", "BP"},
6161
{"pexsi", "PE"},
62-
{"cusolvermp", "CM"}}; // I change the key of "cg_in_lcao" to "CG" because all the other are only two letters
62+
{"cusolvermp", "CM"},
63+
{"sdft", "CT"}}; // CT = Chebyshev Trace, for pure SDFT (nbands=0) where no H diagonalization is performed
6364
// ITER column
6465
std::vector<std::string> th_fmt = {" %-" + std::to_string(witer) + "s"}; // table header: th: ITER
6566
std::vector<std::string> td_fmt
@@ -374,7 +375,12 @@ void print_etot(const Magnetism& magnet,
374375
{
375376
drho.push_back(scf_thr_kin);
376377
}
377-
elecstate::print_scf_iterinfo(PARAM.inp.ks_solver,
378+
// Pure SDFT (nbands=0) uses Chebyshev trace (CT) since no H diagonalization is performed.
379+
// Mixed SDFT (nbands>0) still diagonalizes KS orbitals, so use the actual ks_solver label.
380+
const std::string iter_label = (PARAM.inp.esolver_type == "sdft" && PARAM.inp.nbands == 0)
381+
? "sdft"
382+
: PARAM.inp.ks_solver;
383+
elecstate::print_scf_iterinfo(iter_label,
378384
iter,
379385
6,
380386
mag,

source/source_estate/test/elecstate_print_test.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,3 +258,65 @@ TEST_F(ElecStatePrintTest, PrintEtotColorS4)
258258

259259
delete elecstate.charge;
260260
}
261+
262+
TEST_F(ElecStatePrintTest, PrintEtotSDFTPure)
263+
{
264+
bool converged = false;
265+
int iter = 1;
266+
double scf_thr = 0.1;
267+
double scf_thr_kin = 0.0;
268+
double duration = 2.0;
269+
double pw_diag_thr = 0.1;
270+
int avg_iter = 2;
271+
bool print = true;
272+
elecstate.charge = new Charge;
273+
elecstate.charge->nrxx = 100;
274+
elecstate.charge->nxyz = 1000;
275+
276+
PARAM.input.out_freq_elec = 1;
277+
PARAM.input.nspin = 1;
278+
GlobalV::MY_RANK = 0;
279+
// Pure SDFT: nbands=0, no KS diagonalization -> ITER column should show CT
280+
PARAM.input.esolver_type = "sdft";
281+
PARAM.input.nbands = 0;
282+
PARAM.input.ks_solver = "cg";
283+
284+
testing::internal::CaptureStdout();
285+
elecstate::print_etot(ucell.magnet, elecstate, converged, iter, scf_thr,
286+
scf_thr_kin, duration, pw_diag_thr, avg_iter, print);
287+
output = testing::internal::GetCapturedStdout();
288+
EXPECT_THAT(output, testing::HasSubstr("CT"));
289+
290+
delete elecstate.charge;
291+
}
292+
293+
TEST_F(ElecStatePrintTest, PrintEtotSDFTMixed)
294+
{
295+
bool converged = false;
296+
int iter = 1;
297+
double scf_thr = 0.1;
298+
double scf_thr_kin = 0.0;
299+
double duration = 2.0;
300+
double pw_diag_thr = 0.1;
301+
int avg_iter = 2;
302+
bool print = true;
303+
elecstate.charge = new Charge;
304+
elecstate.charge->nrxx = 100;
305+
elecstate.charge->nxyz = 1000;
306+
307+
PARAM.input.out_freq_elec = 1;
308+
PARAM.input.nspin = 1;
309+
GlobalV::MY_RANK = 0;
310+
// Mixed SDFT: nbands>0, still diagonalizes KS orbitals -> ITER column shows ks_solver label
311+
PARAM.input.esolver_type = "sdft";
312+
PARAM.input.nbands = 5;
313+
PARAM.input.ks_solver = "dav";
314+
315+
testing::internal::CaptureStdout();
316+
elecstate::print_etot(ucell.magnet, elecstate, converged, iter, scf_thr,
317+
scf_thr_kin, duration, pw_diag_thr, avg_iter, print);
318+
output = testing::internal::GetCapturedStdout();
319+
EXPECT_THAT(output, testing::HasSubstr("DA"));
320+
321+
delete elecstate.charge;
322+
}

0 commit comments

Comments
 (0)