From de3d057177fc6b686d2c483351ef15f1ebc640bc Mon Sep 17 00:00:00 2001 From: Chen Nuo <49788094+Cstandardlib@users.noreply.github.com> Date: Wed, 27 May 2026 18:03:59 +0800 Subject: [PATCH 1/2] 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 --- source/source_estate/elecstate_print.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/source/source_estate/elecstate_print.cpp b/source/source_estate/elecstate_print.cpp index 84c7972a41d..517c002dd6d 100644 --- a/source/source_estate/elecstate_print.cpp +++ b/source/source_estate/elecstate_print.cpp @@ -59,7 +59,8 @@ void print_scf_iterinfo(const std::string& ks_solver, {"cusolver", "CU"}, {"bpcg", "BP"}, {"pexsi", "PE"}, - {"cusolvermp", "CM"}}; // I change the key of "cg_in_lcao" to "CG" because all the other are only two letters + {"cusolvermp", "CM"}, + {"sdft", "CT"}}; // CT = Chebyshev Trace, for pure SDFT (nbands=0) where no H diagonalization is performed // ITER column std::vector th_fmt = {" %-" + std::to_string(witer) + "s"}; // table header: th: ITER std::vector td_fmt @@ -374,7 +375,12 @@ void print_etot(const Magnetism& magnet, { drho.push_back(scf_thr_kin); } - elecstate::print_scf_iterinfo(PARAM.inp.ks_solver, + // Pure SDFT (nbands=0) uses Chebyshev trace (CT) since no H diagonalization is performed. + // Mixed SDFT (nbands>0) still diagonalizes KS orbitals, so use the actual ks_solver label. + const std::string iter_label = (PARAM.inp.esolver_type == "sdft" && PARAM.inp.nbands == 0) + ? "sdft" + : PARAM.inp.ks_solver; + elecstate::print_scf_iterinfo(iter_label, iter, 6, mag, From 9f54280b5ebc9e37adb9bb70ad030605f23fddc8 Mon Sep 17 00:00:00 2001 From: Chen Nuo <49788094+Cstandardlib@users.noreply.github.com> Date: Thu, 28 May 2026 12:30:48 +0800 Subject: [PATCH 2/2] 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 --- .../test/elecstate_print_test.cpp | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/source/source_estate/test/elecstate_print_test.cpp b/source/source_estate/test/elecstate_print_test.cpp index 53dcbb0c589..55fb18dd605 100644 --- a/source/source_estate/test/elecstate_print_test.cpp +++ b/source/source_estate/test/elecstate_print_test.cpp @@ -258,3 +258,65 @@ TEST_F(ElecStatePrintTest, PrintEtotColorS4) delete elecstate.charge; } + +TEST_F(ElecStatePrintTest, PrintEtotSDFTPure) +{ + bool converged = false; + int iter = 1; + double scf_thr = 0.1; + double scf_thr_kin = 0.0; + double duration = 2.0; + double pw_diag_thr = 0.1; + int avg_iter = 2; + bool print = true; + elecstate.charge = new Charge; + elecstate.charge->nrxx = 100; + elecstate.charge->nxyz = 1000; + + PARAM.input.out_freq_elec = 1; + PARAM.input.nspin = 1; + GlobalV::MY_RANK = 0; + // Pure SDFT: nbands=0, no KS diagonalization -> ITER column should show CT + PARAM.input.esolver_type = "sdft"; + PARAM.input.nbands = 0; + PARAM.input.ks_solver = "cg"; + + testing::internal::CaptureStdout(); + elecstate::print_etot(ucell.magnet, elecstate, converged, iter, scf_thr, + scf_thr_kin, duration, pw_diag_thr, avg_iter, print); + output = testing::internal::GetCapturedStdout(); + EXPECT_THAT(output, testing::HasSubstr("CT")); + + delete elecstate.charge; +} + +TEST_F(ElecStatePrintTest, PrintEtotSDFTMixed) +{ + bool converged = false; + int iter = 1; + double scf_thr = 0.1; + double scf_thr_kin = 0.0; + double duration = 2.0; + double pw_diag_thr = 0.1; + int avg_iter = 2; + bool print = true; + elecstate.charge = new Charge; + elecstate.charge->nrxx = 100; + elecstate.charge->nxyz = 1000; + + PARAM.input.out_freq_elec = 1; + PARAM.input.nspin = 1; + GlobalV::MY_RANK = 0; + // Mixed SDFT: nbands>0, still diagonalizes KS orbitals -> ITER column shows ks_solver label + PARAM.input.esolver_type = "sdft"; + PARAM.input.nbands = 5; + PARAM.input.ks_solver = "dav"; + + testing::internal::CaptureStdout(); + elecstate::print_etot(ucell.magnet, elecstate, converged, iter, scf_thr, + scf_thr_kin, duration, pw_diag_thr, avg_iter, print); + output = testing::internal::GetCapturedStdout(); + EXPECT_THAT(output, testing::HasSubstr("DA")); + + delete elecstate.charge; +}