Skip to content

Commit 8a3ea2a

Browse files
authored
Feature: output symmetry information for LibRPA (#6435)
* output symmetry information for RPA and GW * .dat -> .txt
1 parent 2f59a6f commit 8a3ea2a

File tree

11 files changed

+152
-16
lines changed

11 files changed

+152
-16
lines changed

docs/advanced/input_files/input-main.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1978,6 +1978,7 @@ These variables are used to control the output of properties.
19781978

19791979
- **Type**: Boolean
19801980
- **Description**: Generate output files used in rpa calculations.
1981+
- **Note**: If [`symmetry`](#symmetry) is set to 1, additional files containing the necessary information for exploiting symmetry in the subsequent rpa calculation will be output: `irreducible_sector.txt`, `symrot_k.txt` and `symrot_R.txt`
19811982
- **Default**: False
19821983

19831984
### out_pchg

source/Makefile.Objects

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,7 @@ OBJS_MODULE_RI=conv_coulomb_pot_k.o\
677677
Mix_DMk_2D.o\
678678
Mix_Matrix.o\
679679
symmetry_rotation.o\
680+
symmetry_rotation_output.o\
680681
symmetry_irreducible_sector.o\
681682

682683
OBJS_PARALLEL=parallel_common.o\

source/source_lcao/module_ri/Exx_LRI_interface.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ void Exx_LRI_Interface<T, Tdata>::exx_before_all_runners(
139139
this->symrot_.find_irreducible_sector(
140140
ucell.symm, ucell.atoms, ucell.st,
141141
RI_Util::get_Born_von_Karmen_cells(period), period, ucell.lat);
142-
// this->symrot_.set_Cs_rotation(this->exx_ptr->get_abfs_nchis());
142+
this->symrot_.set_abfs_Lmax(GlobalC::exx_info.info_ri.abfs_Lmax);
143143
this->symrot_.cal_Ms(kv, ucell, pv);
144144
}
145145
}

source/source_lcao/module_ri/RPA_LRI.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,15 @@ void RPA_LRI<T, Tdata>::cal_postSCF_exx(const elecstate::DensityMatrix<T, Tdata>
9090
if (exx_spacegroup_symmetry)
9191
{
9292
const std::array<Tcell, Ndim> period = RI_Util::get_Born_vonKarmen_period(kv);
93+
const auto& Rs = RI_Util::get_Born_von_Karmen_cells(period);
9394
symrot.find_irreducible_sector(ucell.symm, ucell.atoms, ucell.st,
94-
RI_Util::get_Born_von_Karmen_cells(period), period, ucell.lat);
95+
Rs, period, ucell.lat);
96+
// set Lmax of the rotation matrices to max(l_ao, l_abf), to support rotation under ABF
97+
symrot.set_abfs_Lmax(GlobalC::exx_info.info_ri.abfs_Lmax);
9598
symrot.cal_Ms(kv, ucell, *dm.get_paraV_pointer());
99+
// output Ts (symrot_R.txt) and Ms (symrot_k.txt)
100+
ModuleSymmetry::print_symrot_info_R(symrot, ucell.symm, ucell.lmax, Rs);
101+
ModuleSymmetry::print_symrot_info_k(symrot, kv, ucell);
96102
mix_DMk_2D.mix(symrot.restore_dm(kv, dm.get_DMK_vector(), *dm.get_paraV_pointer()), true);
97103
}
98104
else { mix_DMk_2D.mix(dm.get_DMK_vector(), true); }

source/source_lcao/module_ri/module_exx_symmetry/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ if (ENABLE_LIBRI)
44
irreducible_sector.cpp
55
irreducible_sector_bvk.cpp
66
symmetry_rotation.cpp
7+
symmetry_rotation_output.cpp
78
)
89
add_library(
910
module_exx_symmetry

source/source_lcao/module_ri/module_exx_symmetry/irreducible_sector.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ namespace ModuleSymmetry
148148
if(GlobalV::MY_RANK == 0)
149149
{
150150
std::ofstream ofs;
151-
ofs.open(PARAM.globalv.global_out_dir + "irreducible_sector.dat");
151+
ofs.open(PARAM.globalv.global_out_dir + "irreducible_sector.txt");
152152
for (auto& irap_irR : this->irreducible_sector_)
153153
{
154154
for (auto& irR : irap_irR.second){ofs << "atompair (" << irap_irR.first.first << ", " << irap_irR.first.second << "), R = (" << irR[0] << ", " << irR[1] << ", " << irR[2] << ") \n";}

source/source_lcao/module_ri/module_exx_symmetry/irreducible_sector.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,17 @@ namespace ModuleSymmetry
6868
const ModuleBase::Matrix3& gmatd, const TCdouble gtransd,
6969
const TCdouble& posd_a1, const TCdouble& posd_a2)const;
7070

71+
// Getting calculated return lattice
72+
TCdouble get_return_lattice(const int iat, const int isym) const
73+
{
74+
if (iat < 0 || iat >= static_cast<int>(this->return_lattice_.size())) {
75+
throw std::out_of_range("Invalid atom index in get_return_lattice");
76+
}
77+
if (isym < 0 || isym >= static_cast<int>(this->return_lattice_[iat].size())) {
78+
throw std::out_of_range("Invalid symmetry index in get_return_lattice");
79+
}
80+
return this->return_lattice_[iat][isym];
81+
}
7182
protected:
7283
void cal_return_lattice_all(const Symmetry& symm, const Atom* atoms, const Statistics& st);
7384

source/source_lcao/module_ri/module_exx_symmetry/symmetry_rotation.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ namespace ModuleSymmetry
1616
{
1717
this->reduce_Cs_ = true;
1818
this->abfs_l_nchi_ = abfs_l_nchi;
19-
this->abfs_Lmax_ = 0;
20-
for (auto& abfs_T : abfs_l_nchi) { this->abfs_Lmax_ = std::max(this->abfs_Lmax_, static_cast<int>(abfs_T.size()) - 1);
21-
}
19+
for (auto& abfs_T : abfs_l_nchi) { this->abfs_Lmax_ = std::max(this->abfs_Lmax_, static_cast<int>(abfs_T.size()) - 1); }
2220
}
2321
void Symmetry_rotation::cal_Ms(const K_Vectors& kv,
2422
//const std::vector<std::map<int, TCdouble>>& kstars,
@@ -36,9 +34,8 @@ namespace ModuleSymmetry
3634
}
3735
// 1. calculate the rotation matrix in real spherical harmonics representation for each symmetry operation: [T_l (isym)]_mm'
3836
std::vector<ModuleBase::Matrix3> gmatc(nsym_);
39-
for (int i = 0;i < nsym_;++i) { gmatc[i] = this->irs_.direct_to_cartesian(ucell.symm.gmatrix[i], ucell.latvec);
40-
}
41-
this->cal_rotmat_Slm(gmatc.data(), reduce_Cs_ ? std::max(this->abfs_Lmax_, ucell.lmax) : ucell.lmax);
37+
for (int i = 0;i < nsym_;++i) { gmatc[i] = this->irs_.direct_to_cartesian(ucell.symm.gmatrix[i], ucell.latvec); }
38+
this->cal_rotmat_Slm(gmatc.data(), std::max(this->abfs_Lmax_, ucell.lmax));
4239

4340
// 2. calculate the rotation matrix in AO-representation for each ibz_kpoint and symmetry operation: M(k, isym)
4441
auto restrict_kpt = [](const TCdouble& kvec, const double& symm_prec) -> TCdouble
@@ -47,12 +44,9 @@ namespace ModuleSymmetry
4744
kvec_res.x = fmod(kvec.x + 100.5 - 0.5 * symm_prec, 1) - 0.5 + 0.5 * symm_prec;
4845
kvec_res.y = fmod(kvec.y + 100.5 - 0.5 * symm_prec, 1) - 0.5 + 0.5 * symm_prec;
4946
kvec_res.z = fmod(kvec.z + 100.5 - 0.5 * symm_prec, 1) - 0.5 + 0.5 * symm_prec;
50-
if (std::abs(kvec_res.x) < symm_prec) { kvec_res.x = 0.0;
51-
}
52-
if (std::abs(kvec_res.y) < symm_prec) { kvec_res.y = 0.0;
53-
}
54-
if (std::abs(kvec_res.z) < symm_prec) { kvec_res.z = 0.0;
55-
}
47+
if (std::abs(kvec_res.x) < symm_prec) { kvec_res.x = 0.0; }
48+
if (std::abs(kvec_res.y) < symm_prec) { kvec_res.y = 0.0; }
49+
if (std::abs(kvec_res.z) < symm_prec) { kvec_res.z = 0.0; }
5650
return kvec_res;
5751
};
5852
int nks_ibz = kv.kstars.size(); // kv.nks = 2 * kv.nks_ibz when nspin=2

source/source_lcao/module_ri/module_exx_symmetry/symmetry_rotation.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,21 @@ namespace ModuleSymmetry
2727
{
2828
return this->irs_.get_return_lattice(symm, gmatd, gtransd, posd_a1, posd_a2);
2929
}
30+
TCdouble get_return_lattice(const int iat, const int isym) const
31+
{
32+
return this->irs_.get_return_lattice(iat, isym);
33+
}
34+
/// the rotation matrix under the basis of S_l^m. size: [nsym][lmax][nm*nm]
35+
const std::vector<std::vector<RI::Tensor<std::complex<double>>>>& rotmat_Slm = this->rotmat_Slm_;
36+
const int& abfs_Lmax = this->abfs_Lmax_;
3037
//--------------------------------------------------------------------------------
3138
// setters
3239
void find_irreducible_sector(const Symmetry& symm, const Atom* atoms, const Statistics& st,
3340
const std::vector<TC>& Rs, const TC& period, const Lattice& lat)
3441
{
3542
this->irs_.find_irreducible_sector(symm, atoms, st, Rs, period, lat);
3643
}
44+
void set_abfs_Lmax(const int l) { this->abfs_Lmax_ = l; }
3745
void set_Cs_rotation(const std::vector<std::vector<int>>& abfs_l_nchi);
3846
//--------------------------------------------------------------------------------
3947
/// functions to contruct rotation matrix in AO-representation
@@ -167,6 +175,20 @@ namespace ModuleSymmetry
167175
Irreducible_Sector irs_;
168176

169177
};
178+
179+
template<typename T> std::string vec3_fmt(const T& x, const T& y, const T& z)
180+
{
181+
return "(" + std::to_string(x) + " " + std::to_string(y) + " " + std::to_string(z) + ")";
182+
}
183+
template<typename T> std::string vec3_fmt(const ModuleBase::Vector3<T>& v)
184+
{
185+
return vec3_fmt(v.x, v.y, v.z);
186+
}
187+
// output k stars and the rotation matrices of Bloch orbitals
188+
void print_symrot_info_k(const ModuleSymmetry::Symmetry_rotation& symrot,
189+
const K_Vectors& kv, const UnitCell& ucell);
190+
void print_symrot_info_R(const Symmetry_rotation& symrot, const Symmetry& symm,
191+
const int lmax_ao, const std::vector<TC>& Rs);
170192
}
171193

172194
#include "symmetry_rotation_R.hpp"
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#include "./symmetry_rotation.h"
2+
namespace ModuleSymmetry
3+
{
4+
std::string mat3_fmt(const ModuleBase::Matrix3& m)
5+
{
6+
auto s = [](auto x) { return std::to_string(x); };
7+
return s(m.e11) + " " + s(m.e12) + " " + s(m.e13) + "\n" +
8+
s(m.e21) + " " + s(m.e22) + " " + s(m.e23) + "\n" +
9+
s(m.e31) + " " + s(m.e32) + " " + s(m.e33);
10+
}
11+
12+
// needs to calculate Ts from l=0 to l=max(l_ao,l_abf) before
13+
14+
void print_symrot_info_R(const Symmetry_rotation& symrot, const Symmetry& symm,
15+
const int lmax_ao, const std::vector<TC>& Rs)
16+
{
17+
ModuleBase::TITLE("ModuleSymmetry", "print_symrot_info_R");
18+
std::ofstream ofs(PARAM.globalv.global_out_dir + "symrot_R.txt");
19+
// Print the irreducible sector (to be optimized)
20+
ofs << "Number of irreducible sector: " << symrot.get_irreducible_sector().size() << std::endl;
21+
ofs << "Lmax of AOs: " << lmax_ao << "\n";
22+
ofs << "Lmax of ABFs: " << symrot.abfs_Lmax << "\n";
23+
// print AO rotation matrix T
24+
ofs << "Format:\n"
25+
<< "The index of the symmetry operation\n"
26+
<< "The rotation matrix of this symmetry operation (3*3)\n"
27+
<< "(The translation vector of this symmetry operation)\n"
28+
<< "Orbital rotation matrix (T) of each angular momentum with size ((2l + 1) * (2l + 1)) \n\n";
29+
const int lmax = std::max(lmax_ao, symrot.abfs_Lmax);
30+
for (int isym = 0;isym < symm.nrotk;++isym)
31+
{
32+
ofs << isym << "\n" << mat3_fmt(symm.gmatrix[isym]) << "\n"
33+
<< vec3_fmt(symm.gtrans[isym]) << "\n";
34+
for (int l=0;l <= lmax;++l)
35+
{
36+
const int nm = 2 * l + 1;
37+
// ofs << "l = " << l << ", nm = " << nm << "\n";
38+
const auto& T_block = symrot.rotmat_Slm[isym][l];
39+
for (int m1 = 0;m1 < nm;++m1)
40+
{
41+
for (int m2 = 0;m2 < nm;++m2)
42+
{
43+
//note: the order of m in orbitals may be different from increasing
44+
//note: is Ts row- or col-major ?
45+
ofs << T_block(m1, m2);
46+
}
47+
ofs << "\n";
48+
}
49+
}
50+
}
51+
ofs.close();
52+
}
53+
54+
void print_symrot_info_k(const Symmetry_rotation& symrot, const K_Vectors& kv, const UnitCell& ucell)
55+
{
56+
ModuleBase::TITLE("Symmetry_rotation", "print_symrot_info_k");
57+
std::ofstream ofs(PARAM.globalv.global_out_dir + "symrot_k.txt");
58+
ofs << "Number of IBZ k-points (k stars): " << kv.kstars.size() << std::endl;
59+
ofs << "Format:\n" << "The symmetry operation index to the irreducible k-point. For the irreducible k-points, isym=0.\n\n"
60+
<< "(The direct coordinate of the original k-point)\n"
61+
<< "For each atom: \n"
62+
<< "- Original index->transformed index, type and the Lmax\n"
63+
<< "- Bloch orbital rotation matrix (M) of the given operation and atom, for each angular momentum\n\n";
64+
for (int istar = 0;istar < kv.kstars.size();++istar)
65+
{
66+
ofs << "Star " << istar + 1 << " of IBZ k-point " << vec3_fmt(kv.kstars[istar].at(0)) << ":\n";
67+
for (const auto& isym_kvd : kv.kstars[istar])
68+
{
69+
const int& isym = isym_kvd.first;
70+
ofs << isym << "\n" << vec3_fmt(isym_kvd.second) << "\n";
71+
for (int iat1 =0;iat1 < ucell.nat;++iat1)
72+
{
73+
const int it = ucell.iat2it[iat1]; // it1=it2
74+
const int lmax = ucell.atoms[it].nwl;
75+
const int iat2 = ucell.symm.get_rotated_atom(isym, iat1);
76+
const double arg = 2 * ModuleBase::PI * isym_kvd.second * symrot.get_return_lattice(iat1,isym);
77+
std::complex<double>phase_factor = std::complex<double>(std::cos(arg), std::sin(arg));
78+
ofs << "atom " << iat1 + 1 << " -> " << iat2 + 1 << " of type " << it + 1 << " with Lmax= " << lmax << "\n";
79+
for (int l = 0;l < lmax + 1;++l)
80+
{
81+
const int nm = 2 * l + 1;
82+
const auto& m_block = symrot.rotmat_Slm[isym][l];
83+
for (int m1 = 0;m1 < nm;++m1)
84+
{
85+
// const int m1_start = m2 * nm;
86+
for (int m2 = 0;m2 < nm;++m2)
87+
{
88+
ofs << phase_factor * m_block(m1, m2); // row-major
89+
}
90+
ofs << "\n";
91+
}
92+
}// end l
93+
} // end iat
94+
} // end (k, op)
95+
ofs << "\n";
96+
} // end star
97+
ofs.close();
98+
ModuleBase::timer::tick("Symmetry_rotation", "print_symrot_info_k");
99+
}
100+
}

0 commit comments

Comments
 (0)