Skip to content

Commit a1171cc

Browse files
authored
Merge branch 'develop' into 2026-07-30-c
2 parents a2703a2 + c5e066e commit a1171cc

28 files changed

Lines changed: 1517 additions & 216 deletions

.github/workflows/cuda.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ jobs:
5050
cmake --build build -j4
5151
cmake --install build
5252
53+
- name: Module_LCAO CUDA Unittests
54+
env:
55+
GTEST_COLOR: 'yes'
56+
OMP_NUM_THREADS: '2'
57+
run: |
58+
ctest --test-dir build -V --timeout 1700 -R '^(MODULE_LCAO_tddft_radial_interpolation_cuda_test|MODULE_LCAO_tddft_snap_psibeta_half_test)$'
59+
5360
- name: Test 11_PW_GPU
5461
run: |
5562
cd tests/11_PW_GPU

source/Makefile.Objects

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,8 +636,10 @@ OBJS_LCAO=evolve_elec.o\
636636
td_folding.o\
637637
td_info.o\
638638
velocity_op.o\
639+
radial_interpolation.o\
639640
snap_projector_half_tddft.o\
640641
snap_psibeta_half_tddft.o\
642+
snap_phialpha_half_tddft.o\
641643
solve_propagation.o\
642644
boundary_fix.o\
643645
upsi.o\

source/source_lcao/module_deepks/test/CMakeLists.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ set(DEEPKS_UNIT_COMMON_SOURCES
6262
../../../source_io/module_hs/cal_r_overlap_R.cpp
6363
../../../source_io/module_hs/single_R_io.cpp
6464
../../../source_io/module_hs/rr_sparse_writer.cpp
65+
../../module_rt/radial_interpolation.cpp
66+
../../module_rt/snap_projector_half_tddft.cpp
67+
../../module_rt/snap_phialpha_half_tddft.cpp
6568
../../module_rt/td_folding.cpp
6669
mock_berryphase.cpp
6770
mock_tdinfo.cpp
@@ -94,6 +97,9 @@ set(DEEPKS_UNIT_LIBS
9497
set(DEEPKS_UNIT_PHIALPHA_SOURCES
9598
deepks_test_phialpha.cpp
9699
)
100+
set(DEEPKS_UNIT_PHIALPHA_GRID_SOURCES
101+
deepks_test_phialpha_grid.cpp
102+
)
97103
set(DEEPKS_UNIT_PDM_SOURCES
98104
${DEEPKS_UNIT_PHIALPHA_SOURCES}
99105
deepks_test_pdm.cpp
@@ -157,6 +163,9 @@ function(configure_deepks_unit_target TARGET_NAME CHECK_NAME CASE_DIR)
157163
DEEPKS_UT_CASE_DIR="${CASE_DIR}"
158164
DEEPKS_UT_RUNNER=run_deepks_unit_${CHECK_NAME}
159165
)
166+
if("${CHECK_NAME}" STREQUAL "phialpha_grid_zero_field")
167+
target_compile_definitions(${TARGET_NAME} PRIVATE DEEPKS_UT_MODERN_ORBITAL_READER=1)
168+
endif()
160169
endfunction()
161170

162171
AddTest(
@@ -166,6 +175,13 @@ AddTest(
166175
)
167176
configure_deepks_unit_target(MODULE_LCAO_DEEPKS_phialpha_gamma phialpha NO_GO_deepks_UT)
168177

178+
AddTest(
179+
TARGET MODULE_LCAO_DEEPKS_phialpha_grid_gamma
180+
LIBS ${DEEPKS_UNIT_LIBS}
181+
SOURCES main_deepks.cpp ${DEEPKS_UNIT_PHIALPHA_GRID_SOURCES}
182+
)
183+
configure_deepks_unit_target(MODULE_LCAO_DEEPKS_phialpha_grid_gamma phialpha_grid_zero_field NO_GO_deepks_UT)
184+
169185
AddTest(
170186
TARGET MODULE_LCAO_DEEPKS_pdm_gamma
171187
LIBS ${DEEPKS_UNIT_LIBS}
@@ -264,6 +280,13 @@ AddTest(
264280
)
265281
configure_deepks_unit_target(MODULE_LCAO_DEEPKS_phialpha_multik phialpha NO_KP_deepks_UT)
266282

283+
AddTest(
284+
TARGET MODULE_LCAO_DEEPKS_phialpha_grid_multik
285+
LIBS ${DEEPKS_UNIT_LIBS}
286+
SOURCES main_deepks.cpp ${DEEPKS_UNIT_PHIALPHA_GRID_SOURCES}
287+
)
288+
configure_deepks_unit_target(MODULE_LCAO_DEEPKS_phialpha_grid_multik phialpha_grid_zero_field NO_KP_deepks_UT)
289+
267290
AddTest(
268291
TARGET MODULE_LCAO_DEEPKS_pdm_multik
269292
LIBS ${DEEPKS_UNIT_LIBS}

source/source_lcao/module_deepks/test/deepks_test.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class test_deepks
7171
elecstate::DensityMatrix<T, double>* p_elec_DM = nullptr;
7272

7373
// preparation
74-
void preparation();
74+
void preparation(bool use_modern_orbital_reader);
7575
void set_parameters(); // set some global variables
7676
void setup_cell();
7777

@@ -80,7 +80,7 @@ class test_deepks
8080

8181
void prep_neighbour();
8282
void setup_kpt();
83-
void set_orbs();
83+
void set_orbs(bool use_modern_orbital_reader);
8484

8585
// tranfer Matrix into vector<T>
8686
void set_dm_new();
@@ -91,6 +91,7 @@ class test_deepks
9191
// checking
9292
void check_dstable();
9393
void check_phialpha();
94+
void check_phialpha_grid_zero_field();
9495

9596
void read_dm(const int nks);
9697

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
#include "deepks_test_runner.h"
2+
3+
#include "source_lcao/module_deepks/deepks_iterate.h"
4+
#include "source_lcao/module_rt/snap_phialpha_half_tddft.h"
5+
#include "source_lcao/module_rt/snap_projector_half_tddft.h"
6+
7+
#include <algorithm>
8+
#include <cmath>
9+
#include <complex>
10+
#include <gtest/gtest.h>
11+
#include <iomanip>
12+
#include <iostream>
13+
#include <type_traits>
14+
15+
template <typename T>
16+
void test_deepks<T>::check_phialpha_grid_zero_field()
17+
{
18+
struct ComparisonStats
19+
{
20+
double max_real_diff = 0.0;
21+
double max_imag_abs = 0.0;
22+
double max_reference_abs = 0.0;
23+
double max_relative_diff = 0.0;
24+
double reference_at_max_diff = 0.0;
25+
int compared = 0;
26+
bool shape_mismatch = false;
27+
};
28+
29+
const ModuleBase::Vector3<double> zero_A(0.0, 0.0, 0.0);
30+
const auto compare_grid = [&](const int radial_grid_num, const int lebedev_grid_points) {
31+
ComparisonStats stats;
32+
module_rt::SnapIntegrationOptions options;
33+
options.radial_grid_num = radial_grid_num;
34+
options.lebedev_grid_points = lebedev_grid_points;
35+
36+
DeePKS_domain::iterate_ad1(
37+
ucell,
38+
Test_Deepks::GridD,
39+
ORB,
40+
false,
41+
[&](const int iat,
42+
const ModuleBase::Vector3<double>& tau0,
43+
const int ibt,
44+
const ModuleBase::Vector3<double>& tau1,
45+
const int start,
46+
const int nw_tot,
47+
ModuleBase::Vector3<int> dR) {
48+
const int T1 = ucell.iat2it[ibt];
49+
const Atom* atom1 = &ucell.atoms[T1];
50+
51+
auto all_indexes = ParaO.get_indexes_row(ibt);
52+
auto col_indexes = ParaO.get_indexes_col(ibt);
53+
all_indexes.insert(all_indexes.end(), col_indexes.begin(), col_indexes.end());
54+
std::sort(all_indexes.begin(), all_indexes.end());
55+
all_indexes.erase(std::unique(all_indexes.begin(), all_indexes.end()), all_indexes.end());
56+
57+
for (size_t iw1l = 0; iw1l < all_indexes.size(); iw1l += this->npol)
58+
{
59+
const int iw1 = all_indexes[iw1l] / this->npol;
60+
const int L1 = atom1->iw2l[iw1];
61+
const int N1 = atom1->iw2n[iw1];
62+
const int m1 = atom1->iw2m[iw1];
63+
const int M1 = (m1 % 2 == 0) ? -m1 / 2 : (m1 + 1) / 2;
64+
65+
std::vector<std::vector<std::complex<double>>> grid_nlm;
66+
module_rt::snap_phialpha_half_tddft(ORB,
67+
grid_nlm,
68+
tau1 * ucell.lat0,
69+
T1,
70+
L1,
71+
m1,
72+
N1,
73+
tau0 * ucell.lat0,
74+
zero_A,
75+
false,
76+
options);
77+
78+
std::vector<std::vector<double>> tci_nlm;
79+
const int T0_fixed = 0;
80+
overlap_orb_alpha_.snap(T1,
81+
L1,
82+
N1,
83+
M1,
84+
T0_fixed,
85+
(tau0 - tau1) * ucell.lat0,
86+
false,
87+
tci_nlm);
88+
89+
if (grid_nlm.empty() || tci_nlm.empty() || grid_nlm[0].size() != tci_nlm[0].size())
90+
{
91+
stats.shape_mismatch = true;
92+
return;
93+
}
94+
95+
for (size_t i = 0; i < grid_nlm[0].size(); ++i)
96+
{
97+
const double reference_abs = std::abs(tci_nlm[0][i]);
98+
const double real_diff = std::abs(grid_nlm[0][i].real() - tci_nlm[0][i]);
99+
if (real_diff > stats.max_real_diff)
100+
{
101+
stats.max_real_diff = real_diff;
102+
stats.reference_at_max_diff = tci_nlm[0][i];
103+
}
104+
stats.max_imag_abs = std::max(stats.max_imag_abs, std::abs(grid_nlm[0][i].imag()));
105+
stats.max_reference_abs = std::max(stats.max_reference_abs, reference_abs);
106+
if (reference_abs > 1.0e-8)
107+
{
108+
stats.max_relative_diff = std::max(stats.max_relative_diff, real_diff / reference_abs);
109+
}
110+
++stats.compared;
111+
}
112+
}
113+
});
114+
115+
const char* instance = std::is_same<T, double>::value ? "gamma" : "multik";
116+
std::cout << std::scientific << std::setprecision(12) << "phialpha " << instance << " grid "
117+
<< radial_grid_num << "x" << lebedev_grid_points
118+
<< ": max abs error = " << stats.max_real_diff
119+
<< " (reference = " << stats.reference_at_max_diff << ")"
120+
<< ", max reference = " << stats.max_reference_abs
121+
<< ", max imaginary magnitude = " << stats.max_imag_abs
122+
<< ", max relative error (|reference| > 1e-8) = " << stats.max_relative_diff
123+
<< std::defaultfloat << std::endl;
124+
125+
EXPECT_FALSE(stats.shape_mismatch) << "phialpha grid and two-center integration output shapes differ";
126+
EXPECT_GT(stats.compared, 0) << "No phialpha grid entries were compared";
127+
EXPECT_LE(stats.max_imag_abs, 1.0e-14) << "max reference abs = " << stats.max_reference_abs;
128+
return stats;
129+
};
130+
131+
const ComparisonStats default_grid = compare_grid(140, 110);
132+
const ComparisonStats dense_radial_grid = compare_grid(280, 110);
133+
const ComparisonStats dense_angular_grid = compare_grid(140, 590);
134+
135+
const bool is_gamma = std::is_same<T, double>::value;
136+
const double default_grid_tolerance = is_gamma ? 6.0e-5 : 1.0e-5;
137+
const double dense_angular_grid_tolerance = is_gamma ? 5.0e-6 : 4.0e-6;
138+
139+
// The 110-point angular rule limits both radial-grid cases. The 590-point
140+
// rule exposes the lower error reached by the corrected interpolation.
141+
EXPECT_LE(default_grid.max_real_diff, default_grid_tolerance);
142+
EXPECT_LE(dense_radial_grid.max_real_diff, default_grid_tolerance);
143+
EXPECT_NEAR(dense_radial_grid.max_real_diff, default_grid.max_real_diff, 2.0e-10);
144+
EXPECT_LE(dense_angular_grid.max_real_diff, dense_angular_grid_tolerance);
145+
EXPECT_LE(dense_angular_grid.max_real_diff, 0.5 * default_grid.max_real_diff);
146+
}
147+
148+
template void test_deepks<double>::check_phialpha_grid_zero_field();
149+
template void test_deepks<std::complex<double>>::check_phialpha_grid_zero_field();
150+
151+
template <typename T>
152+
void run_deepks_unit_phialpha_grid_zero_field(test_deepks<T>& test)
153+
{
154+
test.check_phialpha_grid_zero_field();
155+
}
156+
157+
template void run_deepks_unit_phialpha_grid_zero_field<double>(test_deepks<double>& test);
158+
template void run_deepks_unit_phialpha_grid_zero_field<std::complex<double>>(test_deepks<std::complex<double>>& test);

source/source_lcao/module_deepks/test/deepks_test_prep.cpp

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "deepks_test.h"
22
#include "source_base/global_variable.h"
3+
#include "source_basis/module_nao/two_center_bundle.h"
34
#include "source_cell/read_pseudo.h"
45
#include "source_hamilt/module_xc/exx_info.h"
56
#include "../../LCAO_nonlocal_info.h"
@@ -38,7 +39,7 @@ class TestParameters
3839
};
3940

4041
template <typename T>
41-
void test_deepks<T>::preparation()
42+
void test_deepks<T>::preparation(const bool use_modern_orbital_reader)
4243
{
4344
this->count_ntype();
4445
this->set_parameters();
@@ -52,7 +53,7 @@ void test_deepks<T>::preparation()
5253
this->setup_kpt();
5354

5455
this->set_ekcut();
55-
this->set_orbs();
56+
this->set_orbs(use_modern_orbital_reader);
5657
this->prep_neighbour();
5758

5859
this->ParaO.set_serial(this->nlocal, this->nlocal);
@@ -238,23 +239,41 @@ void test_deepks<T>::prep_neighbour()
238239
}
239240

240241
template <typename T>
241-
void test_deepks<T>::set_orbs()
242+
void test_deepks<T>::set_orbs(const bool use_modern_orbital_reader)
242243
{
243-
ORB.init(GlobalV::ofs_running,
244-
ucell.ntype,
245-
this->orbital_dir,
246-
ucell.orbital_fn.data(),
247-
ucell.descriptor_file,
248-
ucell.lmax,
249-
lcao_ecut,
250-
lcao_dk,
251-
lcao_dr,
252-
lcao_rmax,
253-
this->deepks_setorb,
254-
out_mat_r,
255-
this->out_element_info,
256-
this->cal_force,
257-
my_rank);
244+
std::string file_alpha = this->orbital_dir + ucell.descriptor_file;
245+
if (use_modern_orbital_reader)
246+
{
247+
TwoCenterBundle two_center_bundle;
248+
two_center_bundle.build_orb(ucell.ntype, ucell.orbital_fn.data(), this->orbital_dir);
249+
two_center_bundle.build_alpha(this->deepks_setorb, &file_alpha);
250+
two_center_bundle.to_LCAO_Orbitals(ORB, lcao_ecut, lcao_dk, lcao_dr, lcao_rmax, this->out_element_info, this->cal_force);
251+
252+
// Feed both integration paths with data from the same modern read.
253+
orb_ = *two_center_bundle.orb_;
254+
alpha_ = *two_center_bundle.alpha_;
255+
}
256+
else
257+
{
258+
ORB.init(GlobalV::ofs_running,
259+
ucell.ntype,
260+
this->orbital_dir,
261+
ucell.orbital_fn.data(),
262+
ucell.descriptor_file,
263+
ucell.lmax,
264+
lcao_ecut,
265+
lcao_dk,
266+
lcao_dr,
267+
lcao_rmax,
268+
this->deepks_setorb,
269+
out_mat_r,
270+
this->out_element_info,
271+
this->cal_force,
272+
my_rank);
273+
274+
orb_.build(ntype, ucell.orbital_fn.data());
275+
alpha_.build(1, &file_alpha);
276+
}
258277

259278
const std::string basis_type = "lcao";
260279
const bool out_element_info = this->out_element_info;
@@ -266,14 +285,12 @@ void test_deepks<T>::set_orbs()
266285
basis_type, out_element_info, lspinorb, nspin);
267286
ucell.infoNL.reset(lcao_nl);
268287

269-
orb_.build(ntype, ucell.orbital_fn.data());
270-
271-
std::string file_alpha = this->orbital_dir + ucell.descriptor_file;
272-
alpha_.build(1, &file_alpha);
273-
274288
double rmax = std::max(orb_.rcut_max(), alpha_.rcut_max());
275289
double cutoff = 2.0 * rmax;
276-
int nr = static_cast<int>(rmax / lcao_dr) + 1;
290+
// The focused grid-integration comparison needs the requested lcao_dr
291+
// spacing across the complete two-center tabulation range.
292+
const double tabulation_spacing = use_modern_orbital_reader ? 0.5 * lcao_dr : lcao_dr;
293+
int nr = static_cast<int>((use_modern_orbital_reader ? cutoff : rmax) / tabulation_spacing) + 1;
277294

278295
orb_.set_uniform_grid(true, nr, cutoff, 'i', true);
279296
alpha_.set_uniform_grid(true, nr, cutoff, 'i', true);

source/source_lcao/module_deepks/test/main_deepks.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
#error "DEEPKS_UT_RUNNER must be defined by CMake."
2828
#endif
2929

30+
#ifndef DEEPKS_UT_MODERN_ORBITAL_READER
31+
#define DEEPKS_UT_MODERN_ORBITAL_READER 0
32+
#endif
33+
3034
template <typename T>
3135
void DEEPKS_UT_RUNNER(test_deepks<T>& test);
3236

@@ -71,7 +75,7 @@ template <typename T>
7175
void run_typed_check()
7276
{
7377
test_deepks<T> test;
74-
test.preparation();
78+
test.preparation(DEEPKS_UT_MODERN_ORBITAL_READER != 0);
7579
if (testing::Test::HasFatalFailure())
7680
{
7781
return;

0 commit comments

Comments
 (0)