Skip to content

Commit af6ee17

Browse files
authored
Merge branch 'develop' into 2026-08-12
2 parents defb912 + 5bc38d7 commit af6ee17

20 files changed

Lines changed: 710 additions & 30 deletions

File tree

source/source_estate/module_pot/pot_xc.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "pot_xc.h"
22

33
#include "source_base/timer.h"
4+
#include "source_base/constants.h"
45
#include "source_hamilt/module_xc/xc_functional.h"
56
#include "source_io/module_parameter/parameter.h"
67

source/source_hamilt/module_xc/libxc_abacus.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,16 @@ namespace XC_Functional_Libxc
105105
const double tpiba,
106106
const Charge* const chr);
107107

108+
extern void cal_gdr_and_lapl(
109+
const int nspin,
110+
const std::size_t nrxx,
111+
const std::vector<double> &rho,
112+
const double tpiba,
113+
const Charge* const chr,
114+
std::vector<std::vector<ModuleBase::Vector3<double>>> &gdr,
115+
std::vector<double> &lapl,
116+
const bool need_laplacian = true);
117+
108118
// converting grho (abacus=>libxc)
109119
extern std::vector<double> convert_sigma(
110120
const std::vector<std::vector<ModuleBase::Vector3<double>>> &gdr);
@@ -214,11 +224,13 @@ namespace XC_Functional_Libxc
214224
const std::vector<int> &func_id,
215225
const double &rho,
216226
const double &grho,
227+
const double &lapl_rho,
217228
const double &atau,
218229
double &sxc,
219230
double &v1xc,
220231
double &v2xc,
221232
double &v3xc,
233+
double &vlaplxc,
222234
const double &hybrid_alpha,
223235
const double &hse_omega);
224236

@@ -228,6 +240,8 @@ namespace XC_Functional_Libxc
228240
double rhodw,
229241
ModuleBase::Vector3<double> gdr1,
230242
ModuleBase::Vector3<double> gdr2,
243+
double laplup,
244+
double lapldw,
231245
double tauup,
232246
double taudw,
233247
double &sxc,
@@ -238,6 +252,8 @@ namespace XC_Functional_Libxc
238252
double &v2xcud,
239253
double &v3xcup,
240254
double &v3xcdw,
255+
double &vlaplxcup,
256+
double &vlaplxcdw,
241257
const double &hybrid_alpha,
242258
const double &hse_omega);
243259

source/source_hamilt/module_xc/libxc_mgga_wrap.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,20 @@ void XC_Functional_Libxc::tau_xc(
1717
const std::vector<int>& func_id,
1818
const double& rho,
1919
const double& grho,
20+
const double& lapl_rho,
2021
const double& atau,
2122
double& sxc,
2223
double& v1xc,
2324
double& v2xc,
2425
double& v3xc,
26+
double& vlaplxc,
2527
const double& hybrid_alpha,
2628
const double& hse_omega)
2729
{
2830
double s = 0.0;
2931
double v1 = 0.0;
3032
double v2 = 0.0;
3133
double v3 = 0.0;
32-
double lapl_rho = grho;
3334
double vlapl_rho = 0.0;
3435
std::vector<xc_func_type> funcs = XC_Functional_Libxc::init_func(
3536
/* func_id = */ func_id,
@@ -41,6 +42,7 @@ void XC_Functional_Libxc::tau_xc(
4142
v1xc = 0.0;
4243
v2xc = 0.0;
4344
v3xc = 0.0;
45+
vlaplxc = 0.0;
4446

4547
for (xc_func_type& func : funcs)
4648
{
@@ -52,12 +54,14 @@ void XC_Functional_Libxc::tau_xc(
5254
v1 *= (1.0 - hybrid_alpha);
5355
v2 *= (1.0 - hybrid_alpha);
5456
v3 *= (1.0 - hybrid_alpha);
57+
vlapl_rho *= (1.0 - hybrid_alpha);
5558
}
5659
#endif
5760
sxc += s * rho;
5861
v2xc += v2 * 2.0;
5962
v1xc += v1;
6063
v3xc += v3;
64+
vlaplxc += vlapl_rho;
6165
}
6266
XC_Functional_Libxc::finish_func(funcs);
6367

@@ -71,6 +75,8 @@ void XC_Functional_Libxc::tau_xc_spin(
7175
double rhodw,
7276
ModuleBase::Vector3<double> gdr1,
7377
ModuleBase::Vector3<double> gdr2,
78+
double laplup,
79+
double lapldw,
7480
double tauup,
7581
double taudw,
7682
double& sxc,
@@ -81,6 +87,8 @@ void XC_Functional_Libxc::tau_xc_spin(
8187
double& v2xcud,
8288
double& v3xcup,
8389
double& v3xcdw,
90+
double& vlaplxcup,
91+
double& vlaplxcdw,
8492
const double& hybrid_alpha,
8593
const double& hse_omega)
8694
{
@@ -92,10 +100,13 @@ void XC_Functional_Libxc::tau_xc_spin(
92100
v2xcud = 0.0;
93101
v3xcup = 0.0;
94102
v3xcdw = 0.0;
103+
vlaplxcup = 0.0;
104+
vlaplxcdw = 0.0;
95105

96106
const std::array<double, 2> rho = {rhoup, rhodw};
97107
const std::array<double, 3> grho = {gdr1.norm2(), gdr1 * gdr2, gdr2.norm2()};
98108
const std::array<double, 2> tau = {tauup, taudw};
109+
const std::array<double, 2> lapl = {laplup, lapldw};
99110

100111
std::vector<xc_func_type> funcs = XC_Functional_Libxc::init_func(
101112
/* func_id = */ func_id,
@@ -125,12 +136,11 @@ void XC_Functional_Libxc::tau_xc_spin(
125136
double s = 0.0;
126137
std::array<double, 2> v1xc = {0.0, 0.0};
127138
std::array<double, 2> v3xc = {0.0, 0.0};
128-
std::array<double, 2> lapl = {0.0, 0.0};
129-
std::array<double, 2> vlapl = {0.0, 0.0};
139+
std::array<double, 2> vlapl_out = {0.0, 0.0};
130140
std::array<double, 3> v2xc = {0.0, 0.0, 0.0};
131141
// call Libxc function: xc_mgga_exc_vxc
132142
xc_mgga_exc_vxc(&func, 1, rho.data(), grho.data(), lapl.data(), tau.data(), &s,
133-
v1xc.data(), v2xc.data(), vlapl.data(), v3xc.data());
143+
v1xc.data(), v2xc.data(), vlapl_out.data(), v3xc.data());
134144

135145
#ifdef __EXX
136146
if (func.info->number == XC_MGGA_X_SCAN && XC_Functional::get_func_type() == 5)
@@ -143,6 +153,8 @@ void XC_Functional_Libxc::tau_xc_spin(
143153
v2xc[2] *= (1.0 - hybrid_alpha);
144154
v3xc[0] *= (1.0 - hybrid_alpha);
145155
v3xc[1] *= (1.0 - hybrid_alpha);
156+
vlapl_out[0] *= (1.0 - hybrid_alpha);
157+
vlapl_out[1] *= (1.0 - hybrid_alpha);
146158
}
147159
#endif
148160

@@ -154,6 +166,8 @@ void XC_Functional_Libxc::tau_xc_spin(
154166
v2xcdw += 2.0 * v2xc[2] * sgn[1];
155167
v3xcup += v3xc[0] * sgn[0];
156168
v3xcdw += v3xc[1] * sgn[1];
169+
vlaplxcup += vlapl_out[0] * sgn[0];
170+
vlaplxcdw += vlapl_out[1] * sgn[1];
157171
}
158172
}
159173

source/source_hamilt/module_xc/libxc_pot.cpp

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <xc.h>
1616

1717
#include <vector>
18+
#include <complex>
1819

1920
std::tuple<double,double,ModuleBase::matrix> XC_Functional_Libxc::v_xc_libxc( // Peize Lin update for nspin==4 at 2023.01.14
2021
const std::vector<int> &func_id,
@@ -225,13 +226,12 @@ std::tuple<double,double,ModuleBase::matrix,ModuleBase::matrix> XC_Functional_Li
225226
ModuleBase::TITLE("XC_Functional_Libxc","v_xc_meta");
226227
ModuleBase::timer::start("XC_Functional_Libxc","v_xc_meta");
227228

228-
double e2 = 2.0;
229-
230229
//output of the subroutine
231230
double etxc = 0.0;
232231
double vtxc = 0.0;
233232
ModuleBase::matrix v(nspin,nrxx);
234233
ModuleBase::matrix vofk(nspin,nrxx);
234+
ModuleBase::matrix voflapl(nspin,nrxx);
235235

236236
//----------------------------------------------------------
237237
// xc_func_type is defined in Libxc package
@@ -246,8 +246,10 @@ std::tuple<double,double,ModuleBase::matrix,ModuleBase::matrix> XC_Functional_Li
246246
/* hse_omega = */ hse_omega);
247247

248248
const std::vector<double> rho = XC_Functional_Libxc::convert_rho(nspin, nrxx, chr);
249-
const std::vector<std::vector<ModuleBase::Vector3<double>>> gdr
250-
= XC_Functional_Libxc::cal_gdr(nspin, nrxx, rho, tpiba, chr);
249+
const bool need_laplacian = XC_Functional::get_need_laplacian();
250+
std::vector<std::vector<ModuleBase::Vector3<double>>> gdr;
251+
std::vector<double> lapl;
252+
XC_Functional_Libxc::cal_gdr_and_lapl(nspin, nrxx, rho, tpiba, chr, gdr, lapl, need_laplacian);
251253
const std::vector<double> sigma = XC_Functional_Libxc::convert_sigma(gdr);
252254

253255
//converting kin_r
@@ -328,7 +330,7 @@ std::tuple<double,double,ModuleBase::matrix,ModuleBase::matrix> XC_Functional_Li
328330
nrxx_thread,
329331
rho.data() + ir_start * nspin,
330332
sigma.data() + ir_start * ((1==nspin)?1:3),
331-
sigma.data() + ir_start * ((1==nspin)?1:3),
333+
lapl.data() + ir_start * nspin,
332334
kin_r.data() + ir_start * nspin,
333335
exc.data() + ir_start,
334336
vrho.data() + ir_start * nspin,
@@ -441,7 +443,7 @@ std::tuple<double,double,ModuleBase::matrix,ModuleBase::matrix> XC_Functional_Li
441443
}
442444
vtxc -= rvtxc;
443445

444-
//process vtau
446+
//process vtau and vlapl
445447
#ifdef _OPENMP
446448
#pragma omp parallel for collapse(2) schedule(static, 1024)
447449
#endif
@@ -453,9 +455,41 @@ std::tuple<double,double,ModuleBase::matrix,ModuleBase::matrix> XC_Functional_Li
453455
if (func.info->number == XC_MGGA_X_SCAN && XC_Functional::get_func_type() == 5)
454456
{
455457
vtau[ir*nspin+is] *= (1.0 - XC_Functional::get_hybrid_alpha());
458+
vlapl[ir*nspin+is] *= (1.0 - XC_Functional::get_hybrid_alpha());
456459
}
457460
#endif
458461
vofk(is,ir) += vtau[ir*nspin+is] * sgn[ir*nspin+is];
462+
voflapl(is,ir) += vlapl[ir*nspin+is] * sgn[ir*nspin+is];
463+
}
464+
}
465+
}
466+
467+
// v_xc += nabla^2(vlapl) where vlapl = d(rho*eps_xc)/d(nabla^2 rho)
468+
if (need_laplacian)
469+
{
470+
const int ng = chr->rhopw->npw;
471+
const double tpiba2 = tpiba * tpiba;
472+
std::vector<std::complex<double>> lapl_tmp(chr->rhopw->nmaxgr);
473+
for(int is = 0; is < voflapl.nr; is++)
474+
{
475+
for(int ir = 0; ir < nrxx; ir++)
476+
lapl_tmp[ir] = std::complex<double>(voflapl(is, ir), 0.0);
477+
for(int ig = ng; ig < chr->rhopw->nmaxgr; ig++)
478+
lapl_tmp[ig] = std::complex<double>(0.0, 0.0);
479+
chr->rhopw->real2recip(lapl_tmp.data(), lapl_tmp.data());
480+
for(int ig = 0; ig < ng; ig++)
481+
{
482+
double g2 = 0.0;
483+
for(int i = 0; i < 3; i++)
484+
g2 += chr->rhopw->gcar[ig][i] * chr->rhopw->gcar[ig][i];
485+
lapl_tmp[ig] *= -g2 * tpiba2;
486+
}
487+
chr->rhopw->recip2real(lapl_tmp.data(), lapl_tmp.data());
488+
for(int ir = 0; ir < nrxx; ir++)
489+
{
490+
double vlapl_corr = ModuleBase::e2 * lapl_tmp[ir].real();
491+
v(is, ir) += vlapl_corr;
492+
vtxc += vlapl_corr * chr->rho[is][ir];
459493
}
460494
}
461495
}

source/source_hamilt/module_xc/libxc_setup.cpp

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,10 @@
1717

1818
bool not_supported_xc_with_laplacian(const std::string& xc_func_in)
1919
{
20-
// see Pyscf: https://github.com/pyscf/pyscf/blob/master/pyscf/dft/libxc.py#L1062
21-
// ABACUS issue: https://github.com/deepmodeling/abacus-develop/issues/5372
22-
const std::vector<std::string> not_supported = {
23-
"MGGA_XC_CC06",
24-
"MGGA_C_CS",
25-
"MGGA_X_BR89",
26-
"MGGA_X_MK00"
27-
};
28-
for (const std::string& s : not_supported)
29-
{
30-
if (xc_func_in.find(s) != std::string::npos)
31-
{
32-
return true;
33-
}
34-
}
20+
// Laplacian of density is now supported for meta-GGA functionals.
21+
// The following functionals were previously blocked but are now supported:
22+
// MGGA_XC_CC06, MGGA_C_CS, MGGA_X_BR89, MGGA_X_MK00
23+
// Ensure PW stress path handles vlapl contribution correctly if using PW basis.
3524
return false;
3625
}
3726

@@ -179,6 +168,23 @@ XC_Functional_Libxc::set_xc_type_libxc(const std::string& xc_func_in)
179168
ModuleBase::WARNING_QUIT("XC_Functional::set_xc_type_libxc", message);
180169
}
181170

171+
// warn if any functional needs Laplacian of density
172+
{
173+
std::vector<xc_func_type> tmp_funcs = XC_Functional_Libxc::init_func(func_id, XC_UNPOLARIZED, 0.0, 0.0);
174+
for (auto& f : tmp_funcs)
175+
{
176+
if (f.info->flags & XC_FLAGS_NEEDS_LAPLACIAN)
177+
{
178+
std::cout << " WARNING: XC functional \"" << f.info->name
179+
<< "\" requires Laplacian of density (nabla^2 rho)."
180+
<< " This may require a higher energy cutoff for numerical stability."
181+
<< std::endl;
182+
break;
183+
}
184+
}
185+
XC_Functional_Libxc::finish_func(tmp_funcs);
186+
}
187+
182188
// return
183189
return std::make_pair(func_type, func_id);
184190
}

source/source_hamilt/module_xc/libxc_tools.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,37 @@ XC_Functional_Libxc::cal_gdr(
8888
return gdr;
8989
}
9090

91+
void XC_Functional_Libxc::cal_gdr_and_lapl(
92+
const int nspin,
93+
const std::size_t nrxx,
94+
const std::vector<double> &rho,
95+
const double tpiba,
96+
const Charge* const chr,
97+
std::vector<std::vector<ModuleBase::Vector3<double>>> &gdr,
98+
std::vector<double> &lapl,
99+
const bool need_laplacian)
100+
{
101+
gdr.resize(nspin);
102+
lapl.assign(nrxx * nspin, 0.0);
103+
for( int is=0; is!=nspin; ++is )
104+
{
105+
std::vector<double> rhor(nrxx);
106+
for(std::size_t ir=0; ir<nrxx; ++ir)
107+
rhor[ir] = rho[ir*nspin+is];
108+
std::vector<std::complex<double>> rhog(chr->rhopw->npw);
109+
chr->rhopw->real2recip(rhor.data(), rhog.data());
110+
gdr[is].resize(nrxx);
111+
XC_Functional::grad_rho(rhog.data(), gdr[is].data(), chr->rhopw, tpiba);
112+
if (need_laplacian)
113+
{
114+
std::vector<double> lapl_spin(nrxx);
115+
XC_Functional::laplacian_rho(rhog.data(), lapl_spin.data(), chr->rhopw, tpiba);
116+
for(std::size_t ir=0; ir<nrxx; ++ir)
117+
lapl[ir*nspin+is] = lapl_spin[ir];
118+
}
119+
}
120+
}
121+
91122
// converting grho (abacus=>libxc)
92123
std::vector<double> XC_Functional_Libxc::convert_sigma(
93124
const std::vector<std::vector<ModuleBase::Vector3<double>>> &gdr)

source/source_hamilt/module_xc/test/CMakeLists.txt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,43 @@ AddTest(
8383
../../../source_base/module_fft/fft_cpu.cpp
8484
${FFT_SRC}
8585
)
86+
87+
AddTest(
88+
TARGET MODULE_HAMILT_XCTest_SCANL_LAPL
89+
LIBS parameter MPI::MPI_CXX Libxc::xc
90+
SOURCES test_xc6.cpp ../xc_functional.cpp ../xc_lda_wrap.cpp
91+
../xc_gga_wrap.cpp
92+
../libxc_setup.cpp
93+
../libxc_lda_wrap.cpp
94+
../libxc_gga_wrap.cpp
95+
../libxc_mgga_wrap.cpp
96+
../xc_gga_corr.cpp ../xc_lda_corr.cpp
97+
../xc_gga_exch.cpp ../xc_lda_exch.cpp ../xc_hcth.cpp
98+
)
99+
100+
if (USE_CUDA)
101+
list(APPEND FFT_SRC ../../../source_base/module_fft/fft_cuda.cpp)
102+
endif()
103+
if (USE_ROCM)
104+
list(APPEND FFT_SRC ../../../source_base/module_fft/fft_rocm.cpp)
105+
endif()
106+
AddTest(
107+
TARGET MODULE_HAMILT_XCTest_LAPL
108+
LIBS parameter MPI::MPI_CXX Libxc::xc psi device container
109+
SOURCES test_xc7.cpp ../xc_grad.cpp ../xc_functional.cpp
110+
../xc_lda_wrap.cpp ../xc_gga_wrap.cpp
111+
../libxc_setup.cpp
112+
../libxc_lda_wrap.cpp
113+
../libxc_gga_wrap.cpp
114+
../libxc_mgga_wrap.cpp
115+
../xc_gga_corr.cpp ../xc_lda_corr.cpp ../xc_gga_exch.cpp
116+
../xc_lda_exch.cpp ../xc_hcth.cpp
117+
../../../source_base/matrix.cpp
118+
../../../source_base/memory_recorder.cpp
119+
../../../source_base/libm/branred.cpp
120+
../../../source_base/libm/sincos.cpp
121+
../../../source_base/module_external/blas_connector_base.cpp ../../../source_base/module_external/blas_connector_vector.cpp ../../../source_base/module_external/blas_connector_matrix.cpp
122+
../../../source_base/module_fft/fft_bundle.cpp
123+
../../../source_base/module_fft/fft_cpu.cpp
124+
${FFT_SRC}
125+
)

0 commit comments

Comments
 (0)