Skip to content

Commit ab382f7

Browse files
authored
Merge branch 'develop' into feature/container-blas-and-lapack
2 parents e82c17c + efaf1e3 commit ab382f7

File tree

5 files changed

+77
-20
lines changed

5 files changed

+77
-20
lines changed

docs/advanced/input_files/input-main.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,9 @@
302302
- [Exact Exchange (PW)](#exact-exchange-pw)
303303
- [exxace](#exxace)
304304
- [exx\_gamma\_extrapolation](#exx_gamma_extrapolation)
305+
- [ecutexx](#ecutexx)
306+
- [exx_thr_type](#exx_thr_type)
307+
- [exx_ene_thr](#exx_ene_thr)
305308
- [Molecular Dynamics](#molecular-dynamics)
306309
- [md\_type](#md_type)
307310
- [md\_nstep](#md_nstep)
@@ -3101,6 +3104,26 @@ These variables are relevant when using hybrid functionals with *[basis_type](#b
31013104
- **Description**: Whether to use the gamma point extrapolation method to calculate the Fock exchange operator. See [https://doi.org/10.1103/PhysRevB.79.205114](https://doi.org/10.1103/PhysRevB.79.205114) for details. Should be set to true most of the time.
31023105
- **Default**: True
31033106

3107+
### ecutexx
3108+
- **Type**: Real
3109+
- **Description**: The energy cutoff for EXX (Fock) exchange operator in plane wave basis calculations. Reducing `ecutexx` below `ecutrho` may significantly accelerate EXX computations. This speed improvement comes with a reduced numerical accuracy in the exchange energy calculation.
3110+
- **Default**: same as *[ecutrho](#ecutrho)*
3111+
- **Unit**: Ry
3112+
3113+
### exx_thr_type
3114+
- **Type**: String
3115+
- **Description**: The type of threshold used to judge whether the outer loop has converged in the separate loop EXX calculation.
3116+
- energy: use the change of exact exchange energy to judge convergence.
3117+
- density: if the change of charge density difference between two successive outer loop iterations is seen as converged according to *[scf_thr](#scf_thr)*, then the outer loop is seen as converged.
3118+
- **Default**: `density`
3119+
3120+
### exx_ene_thr
3121+
- **Type**: Real
3122+
- **Availability**: *[exx_thr_type](#exx_thr_type)*==`energy`
3123+
- **Description**: The threshold for the change of exact exchange energy to judge convergence of the outer loop in the separate loop EXX calculation.
3124+
- **Default**: 1e-5
3125+
- **Unit**: Ry
3126+
31043127
## Molecular dynamics
31053128

31063129
These variables are used to control molecular dynamics calculations. For more information, please refer to [md.md](../md.md#molecular-dynamics) in detail.

source/source_io/cal_pLpR.cpp

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,21 @@ ModuleIO::AngularMomentumCalculator::AngularMomentumCalculator(
150150

151151
// for neighbor list search
152152
double temp = -1.0;
153+
if (search_radius < rcut_max)
154+
{
155+
*ofs_ << "Find the `search_radius` from the input file being smaller than the \n"
156+
"`rcut_max` of the orbitals.\n"
157+
<< "Reset the `search_radius` (" << search_radius << ") "
158+
<< "to `rcut_max` ("<< rcut_max << ")."
159+
<< std::endl;
160+
// we don't really set, but use std::max to mask :)
161+
}
153162
temp = atom_arrange::set_sr_NL(*ofs_,
154163
PARAM.inp.out_level,
155-
search_radius,
164+
std::max(search_radius, rcut_max),
156165
ucell.infoNL.get_rcutmax_Beta(),
157166
PARAM.globalv.gamma_only_local);
158-
temp = std::max(temp, search_radius);
167+
temp = std::max(temp, std::max(search_radius, rcut_max));
159168
this->neighbor_searcher_ = std::unique_ptr<Grid_Driver>(new Grid_Driver(tdestructor, tgrid));
160169
atom_arrange::search(searchpbc,
161170
*ofs_,
@@ -190,24 +199,29 @@ void ModuleIO::AngularMomentumCalculator::kernel(
190199
fmtstr += "%" + std::to_string(precision*2) + "." + std::to_string(precision) + "e\n";
191200
FmtCore fmt(fmtstr);
192201

193-
ModuleBase::Vector3<double> ri, rj, dr;
202+
// placeholders
203+
std::complex<double> val = 0;
204+
ModuleBase::Vector3<double> taui; // the origin position
205+
ModuleBase::Vector3<double> dtau; // the displacement
206+
AdjacentAtomInfo adjinfo; // adjacent atom information carrier
194207
for (int it = 0; it < ucell.ntype; it++)
195208
{
196209
const Atom& atyp_i = ucell.atoms[it];
197210
for (int ia = 0; ia < atyp_i.na; ia++)
198211
{
199-
ri = atyp_i.tau[ia];
200-
neighbor_searcher_->Find_atom(ucell, ri, it, ia);
201-
for (int ia_adj = 0; ia_adj < neighbor_searcher_->getAdjacentNum(); ia_adj++)
212+
taui = ucell.get_tau(ucell.itia2iat(it, ia));
213+
neighbor_searcher_->Find_atom(ucell, taui, it, ia, &adjinfo);
214+
for (int ia_adj = 0; ia_adj < adjinfo.adj_num + 1; ia_adj++) // "+1" is to include itself
202215
{
203-
rj = neighbor_searcher_->getAdjacentTau(ia_adj);
204-
int jt = neighbor_searcher_->getType(ia_adj);
216+
int jt = adjinfo.ntype[ia_adj]; // ityp
217+
int ja = adjinfo.natom[ia_adj]; // iat with in atomtype
205218
const Atom& atyp_j = ucell.atoms[jt];
206-
int ja = neighbor_searcher_->getNatom(ia_adj);
207-
dr = (ri - rj) * ucell.lat0;
208-
const ModuleBase::Vector3<int> iR = neighbor_searcher_->getBox(ia_adj);
209-
// the two-center-integral
219+
const ModuleBase::Vector3<int> iR = adjinfo.box[ia_adj];
220+
dtau = ucell.cal_dtau(ucell.itia2iat(it, ia),
221+
ucell.itia2iat(jt, ja),
222+
iR) * ucell.lat0; // convert to unit of Bohr
210223

224+
// nested loop: calculate the two-center-integral
211225
for (int li = 0; li < atyp_i.nwl + 1; li++)
212226
{
213227
for (int iz = 0; iz < atyp_i.l_nchi[li]; iz++)
@@ -220,21 +234,20 @@ void ModuleIO::AngularMomentumCalculator::kernel(
220234
{
221235
for (int mj = -lj; mj <= lj; mj++)
222236
{
223-
std::complex<double> val = 0;
224237
if (dir == 'x')
225238
{
226239
val = cal_LxijR(calculator_,
227-
it, ia, li, iz, mi, jt, ja, lj, jz, mj, dr);
240+
it, ia, li, iz, mi, jt, ja, lj, jz, mj, dtau);
228241
}
229242
else if (dir == 'y')
230243
{
231244
val = cal_LyijR(calculator_,
232-
it, ia, li, iz, mi, jt, ja, lj, jz, mj, dr);
245+
it, ia, li, iz, mi, jt, ja, lj, jz, mj, dtau);
233246
}
234247
else if (dir == 'z')
235248
{
236249
val = cal_LzijR(calculator_,
237-
it, ia, li, iz, mi, jt, ja, lj, jz, mj, dr);
250+
it, ia, li, iz, mi, jt, ja, lj, jz, mj, dtau);
238251
}
239252

240253
*ofs << fmt.format(
@@ -266,7 +279,7 @@ void ModuleIO::AngularMomentumCalculator::calculate(
266279
}
267280
std::ofstream ofout;
268281
const std::string dir = "xyz";
269-
const std::string title = "# it ia il iz im iRx iRy iRz jt ja jl jz jm <a|L|b>\n"
282+
const std::string title = "# it ia il iz im iRx iRy iRz jt ja jl jz jm Re[<a|L|b>] Im[<a|L|b>]\n"
270283
"# it: atomtype index of the first atom\n"
271284
"# ia: atomic index of the first atom within the atomtype\n"
272285
"# il: angular momentum index of the first atom\n"
@@ -278,7 +291,8 @@ void ModuleIO::AngularMomentumCalculator::calculate(
278291
"# jl: angular momentum index of the second atom\n"
279292
"# jz: zeta function index of the second atom\n"
280293
"# jm: magnetic quantum number of the second atom\n"
281-
"# <a|L|b>: the value of the matrix element\n";
294+
"# Re[<a|L|b>], Im[<a|L|b>]: the real and imaginary parts "
295+
"of the value of the matrix element\n";
282296

283297
for (char d : dir)
284298
{

source/source_io/module_parameter/input_parameter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,7 @@ struct Input_para
656656
bool exx_gamma_extrapolation = true; // gamma point extrapolation for exx, https://doi.org/10.1103/PhysRevB.79.205114
657657
std::string exx_thr_type = "density"; // threshold type for exx outer loop, energy or density
658658
double exx_ene_thr = 1e-5; // threshold for exx outer loop when exx_thr_type = energy
659+
double ecutexx = 0.0; // energy cutoff for exx calculation, Ry
659660

660661
// ==== #Parameters (23.XC external parameterization) ========
661662
/*

source/source_io/read_input_item_other.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,18 @@ void ReadInput::item_others()
571571
};
572572
this->add_item(item);
573573
}
574+
{
575+
Input_Item item("ecutexx");
576+
item.annotation = "energy cutoff for exx calculation, Ry";
577+
read_sync_double(input.ecutexx);
578+
item.check_value = [](const Input_Item& item, const Parameter& para) {
579+
if (para.input.ecutexx < 0)
580+
{
581+
ModuleBase::WARNING_QUIT("ReadInput", "ecutexx must >= 0");
582+
}
583+
};
584+
this->add_item(item);
585+
}
574586

575587
}
576588
} // namespace ModuleIO

source/source_pw/module_pwdft/operator_pw/op_exx_pw.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,22 @@ OperatorEXXPW<T, Device>::OperatorEXXPW(const int* isk_in,
7676
tpiba = ucell->tpiba;
7777
Real tpiba2 = tpiba * tpiba;
7878

79+
// initialize rhopw_dev
80+
double ecut_exx = PARAM.inp.ecutexx;
81+
if (ecut_exx == 0.0)
82+
{
83+
ecut_exx = PARAM.inp.ecutrho;
84+
}
85+
7986
rhopw_dev = new ModulePW::PW_Basis(wfcpw->get_device(), rhopw->get_precision());
8087
rhopw_dev->fft_bundle.setfft(wfcpw->get_device(), rhopw->get_precision());
8188
#ifdef __MPI
8289
rhopw_dev->initmpi(rhopw->poolnproc, rhopw->poolrank, rhopw->pool_world);
8390
#endif
8491
// here we can actually use different ecut to init the grids
85-
rhopw_dev->initgrids(rhopw->lat0, rhopw->latvec, rhopw->gridecut_lat * rhopw->tpiba2);
92+
rhopw_dev->initgrids(rhopw->lat0, rhopw->latvec, ecut_exx);
8693
rhopw_dev->initgrids(rhopw->lat0, rhopw->latvec, rhopw->nx, rhopw->ny, rhopw->nz);
87-
rhopw_dev->initparameters(rhopw->gamma_only, rhopw->ggecut * rhopw->tpiba2, rhopw->distribution_type, rhopw->xprime);
94+
rhopw_dev->initparameters(rhopw->gamma_only, ecut_exx, rhopw->distribution_type, rhopw->xprime);
8895
rhopw_dev->setuptransform();
8996
rhopw_dev->collect_local_pw();
9097

0 commit comments

Comments
 (0)