Skip to content

Commit a02d7c7

Browse files
Feature: velocity matrix correction for meta-gga xc functionals (#7391)
* INIT MGGA VELOCITY * Test * Revert "Test" This reverts commit bed1ff6. * Fix times 2 * Fix(pw): address meta-gga velocity review comments * Feature(pw): add meta-gga velocity conductivity switch * Docs(pw): clarify meta-gga velocity correction * Fix(pw): guard meta-gga velocity data * Style(pw): use ASCII in velocity comments
1 parent 2a46653 commit a02d7c7

11 files changed

Lines changed: 188 additions & 10 deletions

File tree

docs/advanced/input_files/input-main.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@
502502
- [cond\_smear](#cond_smear)
503503
- [cond\_fwhm](#cond_fwhm)
504504
- [cond\_nonlocal](#cond_nonlocal)
505+
- [cond\_mgga\_vel](#cond_mgga_vel)
505506
- [Implicit solvation model](#implicit-solvation-model)
506507
- [imp\_sol](#imp_sol)
507508
- [eb\_k](#eb_k)
@@ -4471,6 +4472,13 @@
44714472
- False: .
44724473
- **Default**: True
44734474

4475+
### cond_mgga_vel
4476+
4477+
- **Type**: Boolean
4478+
- **Availability**: [basis_type](#basis_type) = `pw`
4479+
- **Description**: Whether to include the meta-GGA velocity correction from the $v_\tau$ term when calculating velocity matrix $\bra{\psi_i}\hat{v}\ket{\psi_j}$.
4480+
- **Default**: True
4481+
44744482
[back to top](#full-list-of-input-keywords)
44754483

44764484
## Implicit solvation model

source/source_io/module_ctrl/ctrl_output_pw.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ void ModuleIO::ctrl_runner_pw(UnitCell& ucell,
334334
inp.cond_dw,
335335
inp.cond_dt,
336336
inp.cond_nonlocal,
337+
inp.cond_mgga_vel,
337338
pelec->wg);
338339
}
339340

source/source_io/module_parameter/input_parameter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,7 @@ struct Input_para
467467
int cond_smear = 1; ///< smearing method for conductivities 1: Gaussian 2: Lorentzian
468468
double cond_fwhm = 0.4; ///< FWHM for conductivities
469469
bool cond_nonlocal = true; ///< if calculate nonlocal effects
470+
bool cond_mgga_vel = true; ///< if calculate meta-GGA velocity correction
470471

471472
bool berry_phase = false; ///< berry phase calculation: calculate berry phase or not
472473
int gdir = 3; ///< berry phase calculation: calculate the polarization in

source/source_io/module_parameter/read_input_item_postprocess.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,12 @@ void ReadInput::item_postprocess()
275275
read_sync_bool(input.cond_nonlocal);
276276
this->add_item(item);
277277
}
278+
{
279+
Input_Item item("cond_mgga_vel");
280+
item.annotation = "Meta-GGA velocity correction for conductivities";
281+
read_sync_bool(input.cond_mgga_vel);
282+
this->add_item(item);
283+
}
278284

279285
// berry_wannier
280286
{

source/source_io/test/read_input_ptest.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ TEST_F(InputParaTest, ParaRead)
7373
EXPECT_EQ(param.inp.cond_dtbatch, 2);
7474
EXPECT_DOUBLE_EQ(param.inp.cond_fwhm, 0.3);
7575
EXPECT_TRUE(param.inp.cond_nonlocal);
76+
EXPECT_TRUE(param.inp.cond_mgga_vel);
7677
EXPECT_FALSE(param.inp.berry_phase);
7778
EXPECT_EQ(param.inp.ocp_kb.size(), 2);
7879
EXPECT_EQ(param.inp.ocp_kb[0], 1);

source/source_io/test/support/INPUT

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ cond_dt 0.07 #control the t interval
9191
cond_dtbatch 2 #control dt batch
9292
cond_fwhm 0.3 #FWHM for conductivities
9393
cond_nonlocal 1 #Nonlocal effects for conductivities
94+
cond_mgga_vel 1 #Meta-GGA velocity correction for conductivities
9495

9596
#Parameters (4.Relaxation)
9697
ks_solver genelpa #cg; dav; lapack; genelpa; scalapack_gvx; cusolver
@@ -391,3 +392,7 @@ nsc 50 #Maximal number of spin-constrained iteration
391392
nsc_min 4 #Minimum number of spin-constrained iteration
392393
alpha_trial 0.02 #Initial trial step size for lambda in eV/uB^2
393394
sccut 4 #Maximal step size for lambda in eV/uB
395+
396+
#Parameters (23. Time-dependent orbital-free DFT)
397+
of_cd 0 #0: no CD potential; 1: add CD potential
398+
of_mCD_alpha 1.0 # parameter of modified CD potential

source/source_pw/module_pwdft/elecond.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
#include "source_base/parallel_device.h"
88
#include "source_base/parallel_reduce.h"
99
#include "source_estate/occupy.h"
10+
#include "source_estate/module_pot/potential_new.h"
11+
#include "source_hamilt/module_xc/xc_functional.h"
12+
#include "source_base/module_device/types.h"
1013
#include "source_io/module_output/binstream.h"
1114
#include "source_io/module_parameter/parameter.h"
1215

@@ -51,6 +54,7 @@ void EleCond<FPTYPE, Device>::KG(const int& smear_type,
5154
const double& dw_in,
5255
const double& dt_in,
5356
const bool& nonlocal,
57+
const bool& mgga_vel,
5458
ModuleBase::matrix& wg)
5559
{
5660
//-----------------------------------------------------------
@@ -86,7 +90,29 @@ void EleCond<FPTYPE, Device>::KG(const int& smear_type,
8690
std::vector<double> ct12(nt, 0);
8791
std::vector<double> ct22(nt, 0);
8892

89-
hamilt::Velocity<FPTYPE, Device> velop(this->p_wfcpw, this->p_kv->isk.data(), this->p_ppcell, this->p_ucell, nonlocal);
93+
using Real = typename GetTypeReal<FPTYPE>::type;
94+
const Real* vtau_ptr = (mgga_vel && this->p_elec != nullptr && this->p_elec->pot != nullptr)
95+
? this->p_elec->pot->template get_vofk_smooth_data<Real>()
96+
: nullptr;
97+
const int vtau_col = (mgga_vel && this->p_elec != nullptr && this->p_elec->pot != nullptr)
98+
? this->p_elec->pot->get_vofk_smooth().nc
99+
: 0;
100+
const int vtau_row = (mgga_vel && this->p_elec != nullptr && this->p_elec->pot != nullptr)
101+
? this->p_elec->pot->get_vofk_smooth().nr
102+
: 0;
103+
if (mgga_vel && XC_Functional::get_ked_flag() && (vtau_ptr == nullptr || vtau_col <= 0 || vtau_row <= 0))
104+
{
105+
ModuleBase::WARNING_QUIT("EleCond::KG",
106+
"meta-GGA velocity correction is requested, but v_tau data is unavailable");
107+
}
108+
hamilt::Velocity<FPTYPE, Device> velop(this->p_wfcpw,
109+
this->p_kv->isk.data(),
110+
this->p_ppcell,
111+
this->p_ucell,
112+
nonlocal,
113+
vtau_ptr,
114+
vtau_col,
115+
vtau_row);
90116
double decut = (wcut + fwhmin) / ModuleBase::Ry_to_eV;
91117
std::cout << "Recommended dt: " << 0.25 * M_PI / decut << " a.u." << std::endl;
92118
for (int ik = 0; ik < nk; ++ik)

source/source_pw/module_pwdft/elecond.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class EleCond
3434
* @param dw_in \omega step
3535
* @param dt_in time step
3636
* @param nonlocal whether to include the nonlocal potential corrections for velocity operator
37+
* @param mgga_vel whether to include the meta-GGA velocity correction
3738
* @param wg wg(ik,ib) occupation for the ib-th band in the ik-th kpoint
3839
*/
3940
void KG(const int& smear_type,
@@ -42,6 +43,7 @@ class EleCond
4243
const double& dw_in,
4344
const double& dt_in,
4445
const bool& nonlocal,
46+
const bool& mgga_vel,
4547
ModuleBase::matrix& wg);
4648

4749
protected:
@@ -99,4 +101,4 @@ class EleCond
99101
double* ct22);
100102
};
101103

102-
#endif // ELECOND_H
104+
#endif // ELECOND_H

source/source_pw/module_pwdft/op_pw_vel.cpp

Lines changed: 96 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include "source_base/kernels/math_kernel_op.h"
44
#include "source_base/parallel_reduce.h"
55
#include "source_base/timer.h"
6+
#include "source_hamilt/module_xc/xc_functional.h"
7+
#include "source_pw/module_pwdft/kernels/meta_op.h"
68
namespace hamilt
79
{
810

@@ -11,7 +13,10 @@ Velocity<FPTYPE, Device>::Velocity(const ModulePW::PW_Basis_K* wfcpw_in,
1113
const int* isk_in,
1214
pseudopot_cell_vnl* ppcell_in,
1315
const UnitCell* ucell_in,
14-
const bool nonlocal_in)
16+
const bool nonlocal_in,
17+
const typename GetTypeReal<FPTYPE>::type* vtau_in,
18+
const int vtau_col_in,
19+
const int vtau_row_in)
1520
{
1621
if (wfcpw_in == nullptr || isk_in == nullptr || ppcell_in == nullptr || ucell_in == nullptr)
1722
{
@@ -23,6 +28,9 @@ Velocity<FPTYPE, Device>::Velocity(const ModulePW::PW_Basis_K* wfcpw_in,
2328
this->ucell = ucell_in;
2429
this->nonlocal = nonlocal_in;
2530
this->tpiba = ucell_in->tpiba;
31+
this->vtau_ = vtau_in;
32+
this->vtau_col_ = vtau_col_in;
33+
this->vtau_row_ = vtau_row_in;
2634
if (this->nonlocal)
2735
{
2836
this->ppcell->initgradq_vnl(*this->ucell);
@@ -37,6 +45,8 @@ Velocity<FPTYPE, Device>::~Velocity()
3745
delmem_var_op()(this->gz_);
3846
delmem_complex_op()(vkb_);
3947
delmem_complex_op()(gradvkb_);
48+
delmem_complex_op()(porter1_);
49+
delmem_complex_op()(porter2_);
4050
}
4151

4252
template <typename FPTYPE, typename Device>
@@ -93,6 +103,7 @@ void Velocity<FPTYPE, Device>::act(const psi::Psi<std::complex<FPTYPE>, Device>*
93103
const int npw = this->wfcpw->npwk[this->ik];
94104
const int max_npw = this->wfcpw->npwk_max;
95105
const int npol = psi_in->get_npol();
106+
using Real = typename GetTypeReal<FPTYPE>::type;
96107

97108
std::vector<FPTYPE*> gtmp_ptr = {this->gx_, this->gy_, this->gz_};
98109
// -------------
@@ -110,6 +121,89 @@ void Velocity<FPTYPE, Device>::act(const psi::Psi<std::complex<FPTYPE>, Device>*
110121
}
111122
}
112123

124+
// ---------------------------------------------
125+
// meta-GGA velocity correction
126+
// V_tau = -(1/2) div(v_tau grad), whose plane-wave matrix element is
127+
// <k+G|V_tau|k+G'> = (1/2) v_tau(G-G') (k+G) dot (k+G').
128+
// Therefore
129+
// i[V_tau, r_\alpha]_{G,G'} =
130+
// (1/2) v_tau(G-G') [2k_alpha + G_alpha + G'_alpha].
131+
// In real space this is implemented as
132+
// -i/2 [\partial_\alpha(v_tau psi) + v_tau \partial_\alpha psi].
133+
// ---------------------------------------------
134+
if (this->vtau_ != nullptr && this->vtau_col_ > 0 && XC_Functional::get_ked_flag())
135+
{
136+
if (this->porter1_ == nullptr)
137+
{
138+
resmem_complex_op()(this->porter1_, this->wfcpw->nmaxgr);
139+
}
140+
if (this->porter2_ == nullptr)
141+
{
142+
resmem_complex_op()(this->porter2_, this->wfcpw->nmaxgr);
143+
}
144+
int current_spin = 0;
145+
if (this->vtau_row_ > 1)
146+
{
147+
current_spin = this->isk[this->ik];
148+
if (current_spin < 0 || current_spin >= this->vtau_row_)
149+
{
150+
ModuleBase::WARNING_QUIT("Velocity", "invalid spin index for meta-GGA velocity correction");
151+
}
152+
}
153+
const Real* vtau_spin = this->vtau_ + current_spin * this->vtau_col_;
154+
Complex minus_half_i(0.0, -0.5);
155+
for (int ib = 0; ib < n_npwx; ++ib)
156+
{
157+
const Complex* bandpsi = psi0 + ib * max_npw;
158+
this->wfcpw->recip_to_real(this->ctx, bandpsi, this->porter1_, this->ik);
159+
ModuleBase::vector_mul_vector_op<Complex, Device>()(this->vtau_col_,
160+
this->porter1_,
161+
this->porter1_,
162+
vtau_spin);
163+
this->wfcpw->real_to_recip(this->ctx, this->porter1_, this->porter1_, this->ik);
164+
for (int id = 0; id < 3; ++id)
165+
{
166+
// term1: partial_id (v_tau * psi)
167+
meta_pw_op<Real, Device>()(this->ctx,
168+
this->ik,
169+
id,
170+
npw,
171+
max_npw,
172+
this->tpiba,
173+
this->wfcpw->template get_gcar_data<Real>(),
174+
this->wfcpw->template get_kvec_c_data<Real>(),
175+
this->porter1_,
176+
this->porter2_,
177+
false);
178+
ModuleBase::scal_op<Real, Device>()(npw, &minus_half_i, this->porter2_, 1);
179+
Complex* vpsi_slice = vpsi + id * n_npwx * max_npw + ib * max_npw;
180+
Complex one = 1.0;
181+
ModuleBase::axpy_op<Complex, Device>()(npw, &one, this->porter2_, 1, vpsi_slice, 1);
182+
183+
// term2: v_tau * partial_id psi
184+
meta_pw_op<Real, Device>()(this->ctx,
185+
this->ik,
186+
id,
187+
npw,
188+
max_npw,
189+
this->tpiba,
190+
this->wfcpw->template get_gcar_data<Real>(),
191+
this->wfcpw->template get_kvec_c_data<Real>(),
192+
bandpsi,
193+
this->porter2_,
194+
false);
195+
this->wfcpw->recip_to_real(this->ctx, this->porter2_, this->porter2_, this->ik);
196+
ModuleBase::vector_mul_vector_op<Complex, Device>()(this->vtau_col_,
197+
this->porter2_,
198+
this->porter2_,
199+
vtau_spin);
200+
this->wfcpw->real_to_recip(this->ctx, this->porter2_, this->porter2_, this->ik);
201+
ModuleBase::scal_op<Real, Device>()(npw, &minus_half_i, this->porter2_, 1);
202+
ModuleBase::axpy_op<Complex, Device>()(npw, &one, this->porter2_, 1, vpsi_slice, 1);
203+
}
204+
}
205+
}
206+
113207
// ---------------------------------------------
114208
// i[V_NL, r] = (\nabla_q+\nabla_q')V_{NL}(q,q')
115209
// |\beta><\beta|\psi>
@@ -334,4 +428,4 @@ template class Velocity<double, base_device::DEVICE_GPU>;
334428
template class Velocity<float, base_device::DEVICE_GPU>;
335429
#endif
336430

337-
} // namespace hamilt
431+
} // namespace hamilt

source/source_pw/module_pwdft/op_pw_vel.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define VELOCITY_PW_H
33
#include "op_pw.h"
44
#include "source_cell/unitcell.h"
5+
#include "source_base/module_device/types.h"
56
#include "source_pw/module_pwdft/vnl_pw.h"
67
#include "source_basis/module_pw/pw_basis_k.h"
78
namespace hamilt
@@ -17,7 +18,10 @@ class Velocity
1718
const int* isk_in,
1819
pseudopot_cell_vnl* ppcell_in,
1920
const UnitCell* ucell_in,
20-
const bool nonlocal_in = true
21+
const bool nonlocal_in = true,
22+
const typename GetTypeReal<FPTYPE>::type* vtau_in = nullptr,
23+
const int vtau_col_in = 0,
24+
const int vtau_row_in = 0
2125
);
2226

2327
~Velocity();
@@ -54,7 +58,13 @@ class Velocity
5458
int ik=0;
5559

5660
double tpiba=0.0;
57-
61+
const typename GetTypeReal<FPTYPE>::type* vtau_ = nullptr; ///< [CPU] meta-GGA vtau on real grid (nspin x nrxx_smooth)
62+
int vtau_col_ = 0; ///< number of grid points per spin for vtau
63+
int vtau_row_ = 0; ///< number of spin channels stored in vtau_
64+
mutable std::complex<FPTYPE>* porter1_ = nullptr; ///< workspace on real grid / recip grid
65+
mutable std::complex<FPTYPE>* porter2_ = nullptr; ///< workspace on real grid / recip grid
66+
Device* ctx = {};
67+
5868
private:
5969
FPTYPE* gx_ = nullptr; ///<[Device, npwx] x component of G+K
6070
FPTYPE* gy_ = nullptr; ///<[Device, npwx] y component of G+K
@@ -76,4 +86,4 @@ class Velocity
7686
using syncmem_complex_h2d_op = base_device::memory::synchronize_memory_op<std::complex<FPTYPE>, Device, base_device::DEVICE_CPU>;
7787
};
7888
}
79-
#endif
89+
#endif

0 commit comments

Comments
 (0)