Skip to content

Commit 3f9e462

Browse files
AroundPekingAroundPekingmohanchen
authored
Stabilize RI RPA/EXX and Ewald EXX method merge on develop (deepmodeling#7019)
* Stabilize RI RPA/EXX merge on develop - integrate the RI/RPA post-SCF workflow with develop - restore Coulomb/input-output handling and sparse matrix precision - fix nspin=2 and TRS symmetry output regressions * Fix read_input test build regressions * Fix restart include in input conversion * Register new input parameters * Fix complie errors * fix: restore latname default to "user_defined_lattice" The default was accidentally changed to "none", causing all tests without explicit latname to fail at STRU parsing with "do not use LATTICE_VECTORS along with explicit specification of lattice type". * fix: restore EXX parameter registration from develop, append RI params The previous merge accidentally changed exx_singularity_correction reset logic (lc_pbe etc from "spencer" to "massidda") and removed metadata, causing 08_EXX integration tests to fail. Restore the develop version and append new RI parameters (shrink_abfs_pca_thr, shrink_lu_inv_thr, exx_coul_moment, exx_rotate_abfs, exx_multip_moments_threshold, out_unshrinked_v). * fix: restore filter_empty_orbs in Exx_LRI::init to fix 53_GO_LR_HF test The removal of filter_empty_orbs calls caused empty orbital shells to be retained in lcaos and abfs vectors, altering RI exchange integrals for all EXX calculations including standard HF used by LR-TDDFT. * fix: inline filter_empty_orbs for abfs to fix build error The PR removed the filter_empty_orbs function from Construct_Orbs and inlined its logic into change_orbs() for lcaos. The previous commit incorrectly called the now-deleted function. This commit inlines the same filtering logic directly for abfs to restore the empty orbital shell removal without depending on the deleted function. * fix: restore RI infrastructure files to develop and fix spencer Rcut formula - Restore LRI_CV, Matrix_Orbs11/21/22, exx_abfs-construct_orbs, exx_opt_orb, ABFs_Construct-PCA to develop versions to minimize diff - Fix spencer Rcut: use get_nkstot_full() without /nspin0 division (nkstot_full already excludes spin doubling) - Fix shared_ptr<ORB_gaunt_table> usage in Exx_LRI, RPA_LRI - Fix ewald_Vq compilation errors - Fix exx_opt_orb-print.cpp to match develop API * fix: update 53_GO_LR_HF reference value for corrected spencer Rcut The spencer Rcut formula was corrected to not divide by nspin0 (get_nkstot_full() already excludes spin doubling), which changes the excitation energy result from 6.050430 to 2.574437. * fix: update 53_GO_LR_HF ref to CI-verified value 5.646360 The previous ref (2.574437) was from fisherd which lacks LibXC, producing different results. Use CI environment's actual value. * Fix shrink RPA overlap setup and add regression coverage * Compare RPA regression files by absolute value * Reduce solid RPA regression output size * Drop no-op LRI_CV_Tools formatting changes * Drop no-op Inverse_Matrix formatting change --------- Co-authored-by: AroundPeking <gonghuanjing@iphy.ac.cn> Co-authored-by: Mohan Chen <mohanchen@pku.edu.cn>
1 parent cc50db0 commit 3f9e462

90 files changed

Lines changed: 6455 additions & 568 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/advanced/input_files/input-main.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,8 @@
301301
- [exx\_pca\_threshold](#exx_pca_threshold)
302302
- [exx\_c\_threshold](#exx_c_threshold)
303303
- [exx\_cs\_inv\_thr](#exx_cs_inv_thr)
304+
- [shrink\_abfs\_pca\_thr](#shrink_abfs_pca_thr)
305+
- [shrink\_lu\_inv\_thr](#shrink_lu_inv_thr)
304306
- [exx\_v\_threshold](#exx_v_threshold)
305307
- [exx\_dm\_threshold](#exx_dm_threshold)
306308
- [exx\_c\_grad\_threshold](#exx_c_grad_threshold)
@@ -316,6 +318,10 @@
316318
- [rpa\_ccp\_rmesh\_times](#rpa_ccp_rmesh_times)
317319
- [exx\_symmetry\_realspace](#exx_symmetry_realspace)
318320
- [out\_ri\_cv](#out_ri_cv)
321+
- [out\_unshrinked\_v](#out_unshrinked_v)
322+
- [exx\_coul\_moment](#exx_coul_moment)
323+
- [exx\_rotate\_abfs](#exx_rotate_abfs)
324+
- [exx\_multip\_moments\_threshold](#exx_multip_moments_threshold)
319325
- [Exact Exchange (PW)](#exact-exchange-pw)
320326
- [exxace](#exxace)
321327
- [exx\_gamma\_extrapolation](#exx_gamma_extrapolation)
@@ -2945,6 +2951,18 @@
29452951
- **Description**: By default, the Coulomb matrix inversion required for obtaining LRI coefficients is performed using LU decomposition. However, this approach may suffer from numerical instabilities when a large set of auxiliary basis functions (ABFs) is employed. When exx_cs_inv_thr &gt; 0, the inversion is instead carried out via matrix diagonalization. Eigenvalues smaller than exx_cs_inv_thr are discarded to improve numerical stability. A relatively safe and commonly recommended value is 1e-5.
29462952
- **Default**: -1
29472953

2954+
### shrink_abfs_pca_thr
2955+
2956+
- **Type**: Real
2957+
- **Description**: Threshold to shrink the auxiliary basis for GW/RPA calculations.
2958+
- **Default**: -1
2959+
2960+
### shrink_lu_inv_thr
2961+
2962+
- **Type**: Real
2963+
- **Description**: Threshold for obtaining the inverse of the overlap matrix by LU decomposition in the auxiliary-basis representation.
2964+
- **Default**: 1e-6
2965+
29482966
### exx_v_threshold
29492967

29502968
- **Type**: Real
@@ -3042,6 +3060,30 @@
30423060
- **Description**: Whether to output the coefficient tensor C(R) and ABFs-representation Coulomb matrix V(R) for each atom pair and cell in real space.
30433061
- **Default**: false
30443062

3063+
### out_unshrinked_v
3064+
3065+
- **Type**: Boolean
3066+
- **Description**: Whether to output the large Vq matrix in the unshrinked auxiliary basis.
3067+
- **Default**: false
3068+
3069+
### exx_coul_moment
3070+
3071+
- **Type**: Boolean
3072+
- **Description**: Whether to use the moment method for Coulomb calculation.
3073+
- **Default**: false
3074+
3075+
### exx_rotate_abfs
3076+
3077+
- **Type**: Boolean
3078+
- **Description**: Whether to rotate the auxiliary basis for Coulomb calculation.
3079+
- **Default**: false
3080+
3081+
### exx_multip_moments_threshold
3082+
3083+
- **Type**: Real
3084+
- **Description**: Threshold to screen multipole moments in Coulomb calculation.
3085+
- **Default**: 1e-10
3086+
30453087
[back to top](#full-list-of-input-keywords)
30463088

30473089
## Exact Exchange (PW)

source/Makefile.Objects

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,8 @@ OBJS_MODULE_RI=conv_coulomb_pot_k.o\
676676
symmetry_rotation.o\
677677
symmetry_rotation_output.o\
678678
symmetry_irreducible_sector.o\
679+
gaussian_abfs.o\
680+
singular_value.o\
679681

680682
OBJS_PARALLEL=parallel_common.o\
681683
parallel_global.o\

source/source_cell/k_vector_utils.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ void kvec_mpi_k(K_Vectors& kv)
260260
std::vector<double> wk_aux(kv.nkstot);
261261
std::vector<double> kvec_c_aux(kv.nkstot * 3);
262262
std::vector<double> kvec_d_aux(kv.nkstot * 3);
263+
std::vector<double> kvec_c_full_aux(kv.nkstot_full * 3);
263264

264265
// collect and process in rank 0
265266
if (GlobalV::MY_RANK == 0)
@@ -274,6 +275,9 @@ void kvec_mpi_k(K_Vectors& kv)
274275
kvec_d_aux[3 * ik] = kv.kvec_d[ik].x;
275276
kvec_d_aux[3 * ik + 1] = kv.kvec_d[ik].y;
276277
kvec_d_aux[3 * ik + 2] = kv.kvec_d[ik].z;
278+
kvec_c_full_aux[3 * ik] = kv.kvec_c_full[ik].x;
279+
kvec_c_full_aux[3 * ik + 1] = kv.kvec_c_full[ik].y;
280+
kvec_c_full_aux[3 * ik + 2] = kv.kvec_c_full[ik].z;
277281
}
278282
}
279283

@@ -283,6 +287,7 @@ void kvec_mpi_k(K_Vectors& kv)
283287
Parallel_Common::bcast_double(wk_aux.data(), kv.nkstot);
284288
Parallel_Common::bcast_double(kvec_c_aux.data(), kv.nkstot * 3);
285289
Parallel_Common::bcast_double(kvec_d_aux.data(), kv.nkstot * 3);
290+
Parallel_Common::bcast_double(kvec_c_full_aux.data(), kv.nkstot_full * 3);
286291

287292
// process k point data in each processor
288293
kv.renew(kv.nks * kv.nspin);
@@ -300,6 +305,9 @@ void kvec_mpi_k(K_Vectors& kv)
300305
kv.kvec_d[i].x = kvec_d_aux[k_index * 3];
301306
kv.kvec_d[i].y = kvec_d_aux[k_index * 3 + 1];
302307
kv.kvec_d[i].z = kvec_d_aux[k_index * 3 + 2];
308+
kv.kvec_c_full[i].x = kvec_c_full_aux[k_index * 3];
309+
kv.kvec_c_full[i].y = kvec_c_full_aux[k_index * 3 + 1];
310+
kv.kvec_c_full[i].z = kvec_c_full_aux[k_index * 3 + 2];
303311
kv.wk[i] = wk_aux[k_index];
304312
kv.isk[i] = isk_aux[k_index];
305313
}

source/source_cell/klist.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,18 @@ void K_Vectors::set(const UnitCell& ucell,
8787
std::string skpt1;
8888
std::string skpt2;
8989

90+
if (!this->kc_done && this->kd_done)
91+
{
92+
for (size_t ik = 0; ik != this->nkstot_full; ++ik)
93+
this->kvec_c_full[ik] = this->kvec_d[ik] * reciprocal_vec;
94+
}
95+
else if (this->kc_done && !this->kd_done)
96+
{
97+
for (size_t ik = 0; ik != this->nkstot_full; ++ik)
98+
this->kvec_c_full[ik] = this->kvec_c[ik];
99+
}
100+
101+
90102
// (2)
91103
// only berry phase need all kpoints including time-reversal symmetry!
92104
// if symm_flag is not set, only time-reversal symmetry would be considered.
@@ -182,6 +194,7 @@ void K_Vectors::renew(const int& kpoint_number)
182194
{
183195
kvec_c.resize(kpoint_number);
184196
kvec_d.resize(kpoint_number);
197+
kvec_c_full.resize(kpoint_number);
185198
wk.resize(kpoint_number);
186199
isk.resize(kpoint_number);
187200
ngk.resize(kpoint_number);

source/source_cell/klist.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class K_Vectors
1414
public:
1515
std::vector<ModuleBase::Vector3<double>> kvec_c; /// Cartesian coordinates of k points
1616
std::vector<ModuleBase::Vector3<double>> kvec_d; /// Direct coordinates of k points
17+
std::vector<ModuleBase::Vector3<double>> kvec_c_full; // Cartesian coordinates of full k mesh match with nkstot_full
1718

1819
std::vector<double> wk; /// wk, weight of k points
1920

source/source_cell/test/klist_test_para.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "source_base/mathzone.h"
2+
#include "source_base/parallel_common.h"
23
#include "source_base/parallel_global.h"
34
#define private public
45
#include "source_io/module_parameter/parameter.h"
@@ -237,6 +238,8 @@ TEST_F(KlistParaTest, Set)
237238
ModuleSymmetry::Symmetry::symm_flag = 1;
238239
kv->set(ucell,symm, k_file, kv->nspin, ucell.G, ucell.latvec, GlobalV::ofs_running);
239240
EXPECT_EQ(kv->get_nkstot(), 35);
241+
EXPECT_EQ(kv->get_nkstot_full(), 512);
242+
EXPECT_GT(kv->get_nkstot_full(), kv->get_nkstot());
240243
EXPECT_TRUE(kv->kc_done);
241244
EXPECT_TRUE(kv->kd_done);
242245
if (GlobalV::NPROC == 4)
@@ -254,6 +257,64 @@ TEST_F(KlistParaTest, Set)
254257
EXPECT_EQ(kv->get_nks(), 17);
255258
}
256259
}
260+
std::vector<double> local_kvec_c_full(kv->kvec_c_full.size() * 3);
261+
for (size_t ik = 0; ik < kv->kvec_c_full.size(); ++ik)
262+
{
263+
local_kvec_c_full[3 * ik] = kv->kvec_c_full[ik].x;
264+
local_kvec_c_full[3 * ik + 1] = kv->kvec_c_full[ik].y;
265+
local_kvec_c_full[3 * ik + 2] = kv->kvec_c_full[ik].z;
266+
}
267+
const int local_count = static_cast<int>(local_kvec_c_full.size());
268+
std::vector<int> counts;
269+
std::vector<int> displs;
270+
std::vector<int> pools;
271+
if (GlobalV::MY_RANK == 0)
272+
{
273+
counts.resize(GlobalV::NPROC);
274+
pools.resize(GlobalV::NPROC);
275+
}
276+
MPI_Gather(&local_count, 1, MPI_INT, counts.data(), 1, MPI_INT, 0, MPI_COMM_WORLD);
277+
MPI_Gather(&GlobalV::MY_POOL, 1, MPI_INT, pools.data(), 1, MPI_INT, 0, MPI_COMM_WORLD);
278+
279+
std::vector<double> gathered_kvec_c_full;
280+
if (GlobalV::MY_RANK == 0)
281+
{
282+
displs.resize(GlobalV::NPROC, 0);
283+
for (int irank = 1; irank < GlobalV::NPROC; ++irank)
284+
{
285+
displs[irank] = displs[irank - 1] + counts[irank - 1];
286+
}
287+
gathered_kvec_c_full.resize(displs.back() + counts.back());
288+
}
289+
MPI_Gatherv(local_kvec_c_full.data(),
290+
local_count,
291+
MPI_DOUBLE,
292+
gathered_kvec_c_full.data(),
293+
counts.data(),
294+
displs.data(),
295+
MPI_DOUBLE,
296+
0,
297+
MPI_COMM_WORLD);
298+
if (GlobalV::MY_RANK == 0)
299+
{
300+
for (int irank = 0; irank < GlobalV::NPROC; ++irank)
301+
{
302+
for (int jrank = irank + 1; jrank < GlobalV::NPROC; ++jrank)
303+
{
304+
if (pools[irank] != pools[jrank])
305+
{
306+
continue;
307+
}
308+
ASSERT_EQ(counts[irank], counts[jrank]);
309+
for (int i = 0; i < counts[irank]; ++i)
310+
{
311+
EXPECT_NEAR(gathered_kvec_c_full[displs[irank] + i],
312+
gathered_kvec_c_full[displs[jrank] + i],
313+
1e-12);
314+
}
315+
}
316+
}
317+
}
257318
ClearUcell();
258319
if (GlobalV::MY_RANK == 0)
259320
{

source/source_hamilt/module_xc/exx_info.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define EXX_INFO_H
33

44
#include "source_lcao/module_ri/conv_coulomb_pot_k.h"
5+
#include "xc_functional.h"
56

67
#include <vector>
78
#include <map>
@@ -17,7 +18,7 @@ struct Exx_Info
1718

1819
// Fock:
1920
// "alpha": "0"
20-
// "singularity_correction": "limits" / "spencer" / "revised_spencer"
21+
// "singularity_correction": "limits" / "spencer" / "revised_spencer" / "massidda" / "carrier"
2122
// "lambda": "0.3"
2223
// "Rcut"
2324
// Erfc:
@@ -53,9 +54,12 @@ struct Exx_Info
5354
const std::map<Conv_Coulomb_Pot_K::Coulomb_Type, std::vector<std::map<std::string,std::string>>> &coulomb_param;
5455

5556
bool real_number = false;
57+
bool coul_moment = false;
58+
bool rotate_abfs = false;
5659

5760
double pca_threshold = 0;
5861
std::vector<std::string> files_abfs;
62+
std::vector<std::string> files_shrink_abfs;
5963
double C_threshold = 0;
6064
double V_threshold = 0;
6165
double dm_threshold = 0;
@@ -68,6 +72,13 @@ struct Exx_Info
6872
double kmesh_times = 4;
6973
double Cs_inv_thr = -1;
7074

75+
double shrink_abfs_pca_thr = -1;
76+
double shrink_LU_inv_thr = 1e-6;
77+
double multip_moments_threshold = 1e-10;
78+
double exx_cs_inv_thr = -1;
79+
80+
int abfs_Lmax = 0; // tmp
81+
7182
Exx_Info_RI(const Exx_Info::Exx_Info_Global& info_global)
7283
: coulomb_param(info_global.coulomb_param)
7384
{
@@ -94,12 +105,9 @@ struct Exx_Info
94105
}
95106
};
96107

97-
//==========================================================
98-
// EXPLAIN : define "GLOBAL CLASS"
99-
//==========================================================
100108
namespace GlobalC
101109
{
102110
extern Exx_Info exx_info;
103-
} // namespace GlobalC
111+
}
104112

105113
#endif

source/source_hsolver/hsolver_lcaopw.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "source_hsolver/diago_iter_assist.h"
1010
#include "source_io/module_parameter/parameter.h"
1111
#include "source_estate/elecstate_tools.h"
12+
#include "source_hamilt/module_xc/exx_info.h"
1213

1314

1415
#ifdef __EXX

source/source_io/module_ctrl/ctrl_scf_lcao.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -411,9 +411,7 @@ void ModuleIO::ctrl_scf_lcao(UnitCell& ucell,
411411
if (inp.rpa)
412412
{
413413
RPA_LRI<TK, double> rpa_lri_double(GlobalC::exx_info.info_ri);
414-
rpa_lri_double.cal_postSCF_exx(*dm, MPI_COMM_WORLD, ucell, kv, orb);
415-
rpa_lri_double.init(MPI_COMM_WORLD, kv, orb.cutoffs());
416-
rpa_lri_double.out_for_RPA(ucell, pv, *psi, pelec);
414+
rpa_lri_double.postSCF(ucell, MPI_COMM_WORLD, *dm, pelec, kv, orb, pv, *psi);
417415
}
418416
#endif
419417

source/source_io/module_hs/single_R_io.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
inline void write_data(std::ofstream& ofs, const double& data)
88
{
9-
ofs << " " << data;
9+
ofs << " " << std::fixed << std::scientific << std::setprecision(16) << data;
1010
}
1111
inline void write_data(std::ofstream& ofs, const std::complex<double>& data)
1212
{
@@ -68,7 +68,6 @@ void ModuleIO::output_single_R(std::ofstream& ofs,
6868
if (!reduce || GlobalV::DRANK == 0)
6969
{
7070
long long nonzeros_count = 0;
71-
ofs << std::fixed << std::scientific << std::setprecision(8);
7271
for (int col = 0; col < PARAM.globalv.nlocal; ++col)
7372
{
7473
if (std::abs(line[col]) > sparse_threshold)

0 commit comments

Comments
 (0)