diff --git a/docs/advanced/input_files/input-main.md b/docs/advanced/input_files/input-main.md index 32d4eafc534..bfa0c9a3e02 100644 --- a/docs/advanced/input_files/input-main.md +++ b/docs/advanced/input_files/input-main.md @@ -302,6 +302,9 @@ - [Exact Exchange (PW)](#exact-exchange-pw) - [exxace](#exxace) - [exx\_gamma\_extrapolation](#exx_gamma_extrapolation) + - [ecutexx](#ecutexx) + - [exx_thr_type](#exx_thr_type) + - [exx_ene_thr](#exx_ene_thr) - [Molecular Dynamics](#molecular-dynamics) - [md\_type](#md_type) - [md\_nstep](#md_nstep) @@ -3101,6 +3104,26 @@ These variables are relevant when using hybrid functionals with *[basis_type](#b - **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. - **Default**: True +### ecutexx +- **Type**: Real +- **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. +- **Default**: same as *[ecutrho](#ecutrho)* +- **Unit**: Ry + +### exx_thr_type +- **Type**: String +- **Description**: The type of threshold used to judge whether the outer loop has converged in the separate loop EXX calculation. + - energy: use the change of exact exchange energy to judge convergence. + - 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. +- **Default**: `density` + +### exx_ene_thr +- **Type**: Real +- **Availability**: *[exx_thr_type](#exx_thr_type)*==`energy` +- **Description**: The threshold for the change of exact exchange energy to judge convergence of the outer loop in the separate loop EXX calculation. +- **Default**: 1e-5 +- **Unit**: Ry + ## Molecular dynamics These variables are used to control molecular dynamics calculations. For more information, please refer to [md.md](../md.md#molecular-dynamics) in detail. diff --git a/source/source_io/module_parameter/input_parameter.h b/source/source_io/module_parameter/input_parameter.h index 64392c8c343..9f5d452727e 100644 --- a/source/source_io/module_parameter/input_parameter.h +++ b/source/source_io/module_parameter/input_parameter.h @@ -656,6 +656,7 @@ struct Input_para bool exx_gamma_extrapolation = true; // gamma point extrapolation for exx, https://doi.org/10.1103/PhysRevB.79.205114 std::string exx_thr_type = "density"; // threshold type for exx outer loop, energy or density double exx_ene_thr = 1e-5; // threshold for exx outer loop when exx_thr_type = energy + double ecutexx = 0.0; // energy cutoff for exx calculation, Ry // ==== #Parameters (23.XC external parameterization) ======== /* diff --git a/source/source_io/read_input_item_other.cpp b/source/source_io/read_input_item_other.cpp index cdd23df1c9f..93bce67e35c 100644 --- a/source/source_io/read_input_item_other.cpp +++ b/source/source_io/read_input_item_other.cpp @@ -571,6 +571,18 @@ void ReadInput::item_others() }; this->add_item(item); } + { + Input_Item item("ecutexx"); + item.annotation = "energy cutoff for exx calculation, Ry"; + read_sync_double(input.ecutexx); + item.check_value = [](const Input_Item& item, const Parameter& para) { + if (para.input.ecutexx < 0) + { + ModuleBase::WARNING_QUIT("ReadInput", "ecutexx must >= 0"); + } + }; + this->add_item(item); + } } } // namespace ModuleIO \ No newline at end of file diff --git a/source/source_pw/module_pwdft/operator_pw/op_exx_pw.cpp b/source/source_pw/module_pwdft/operator_pw/op_exx_pw.cpp index 9a7737f821d..20a663b2454 100644 --- a/source/source_pw/module_pwdft/operator_pw/op_exx_pw.cpp +++ b/source/source_pw/module_pwdft/operator_pw/op_exx_pw.cpp @@ -76,15 +76,22 @@ OperatorEXXPW::OperatorEXXPW(const int* isk_in, tpiba = ucell->tpiba; Real tpiba2 = tpiba * tpiba; + // initialize rhopw_dev + double ecut_exx = PARAM.inp.ecutexx; + if (ecut_exx == 0.0) + { + ecut_exx = PARAM.inp.ecutrho; + } + rhopw_dev = new ModulePW::PW_Basis(wfcpw->get_device(), rhopw->get_precision()); rhopw_dev->fft_bundle.setfft(wfcpw->get_device(), rhopw->get_precision()); #ifdef __MPI rhopw_dev->initmpi(rhopw->poolnproc, rhopw->poolrank, rhopw->pool_world); #endif // here we can actually use different ecut to init the grids - rhopw_dev->initgrids(rhopw->lat0, rhopw->latvec, rhopw->gridecut_lat * rhopw->tpiba2); + rhopw_dev->initgrids(rhopw->lat0, rhopw->latvec, ecut_exx); rhopw_dev->initgrids(rhopw->lat0, rhopw->latvec, rhopw->nx, rhopw->ny, rhopw->nz); - rhopw_dev->initparameters(rhopw->gamma_only, rhopw->ggecut * rhopw->tpiba2, rhopw->distribution_type, rhopw->xprime); + rhopw_dev->initparameters(rhopw->gamma_only, ecut_exx, rhopw->distribution_type, rhopw->xprime); rhopw_dev->setuptransform(); rhopw_dev->collect_local_pw();