Skip to content

Commit a8c5fbe

Browse files
committed
add output EDM(R) and some test funcs
1 parent 1a56745 commit a8c5fbe

File tree

2 files changed

+155
-0
lines changed

2 files changed

+155
-0
lines changed

source/module_lr/Grad/esolver_lr_grad.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,41 @@ inline void print_force(const std::vector<ModuleBase::matrix>& force, Tstream& o
2424
}
2525
}
2626
}
27+
28+
// check C_uaC_va-C_uiC_vi of lumo-homo, nocc=1, nk=1
29+
template<typename T>
30+
inline void test_dm_diff_H2(const T* dm, const psi::Psi<T>& c, const int nbasis)
31+
{
32+
std::cout << "difference dm cal: " << std::endl;
33+
LR_Util::print_value(dm, nbasis, nbasis);
34+
std::cout << "difference dm ref: " << std::endl;
35+
for (int i = 0;i < nbasis;++i)
36+
{
37+
for (int j = 0;j < nbasis;++j)
38+
{
39+
std::cout << c(0, 1, i) * c(0, 1, j) - c(0, 0, i) * c(0, 0, j) << " ";
40+
}
41+
std::cout << std::endl;
42+
}
43+
}
44+
45+
// check e_aC_uaC_va-e_iC_uiC_vi of lumo-homo, nocc=1, nk=1
46+
template<typename T>
47+
inline void test_edm_H2(const T* const edm, const double* const eig_ks, const psi::Psi<T>& c, const int nbasis)
48+
{
49+
std::cout << "edm cal: " << std::endl;
50+
LR_Util::print_value(edm, nbasis, nbasis);
51+
std::cout << "edm ref: " << std::endl;
52+
for (int i = 0;i < nbasis;++i)
53+
{
54+
for (int j = 0;j < nbasis;++j)
55+
{
56+
std::cout << eig_ks[1] * c(0, 1, i) * c(0, 1, j) - eig_ks[0] * c(0, 0, i) * c(0, 0, j) << " ";
57+
}
58+
std::cout << std::endl;
59+
}
60+
}
61+
2762
template<typename T, typename TR>
2863
void LR::ESolver_LR<T, TR>::init_pot_groundstate(const Charge& chg_gs)
2964
{
@@ -145,8 +180,21 @@ std::vector<ModuleBase::matrix> LR::ESolver_LR<T, TR>::cal_force(const int ispin
145180
this->gint_, pot_weak, pot_hxc_gs_weak,
146181
this->kv, this->gd, this->paraX_, this->paraC_, this->paraMat_,
147182
has_local_xc(this->xc_kernel));
183+
if (PARAM.inp.test_force && nocc[0] == 1)
184+
{
185+
const std::vector<ct::Tensor>& dm_diff = cal_dm_diff_pblas(this->X[0].template data<T>() + offset, this->paraX_[0], c, this->paraC_, this->nbasis, this->nocc[0], this->nvirt[0], this->paraMat_);
186+
// test_dm_diff_H2<T>(relaxed_diff_dm.get_DMK_pointer(0), c, this->nbasis);
187+
test_dm_diff_H2<T>(dm_diff[0].data<T>(), c, this->nbasis);
188+
test_edm_H2<T>(edm_k[0].data<T>(), this->eig_ks.c, c, this->nbasis);
189+
}
148190
elecstate::DensityMatrix<T, double> edm_real = LR_Util::build_dm_from_dmk<T, double>(edm_k,
149191
this->paraMat_, this->nk, this->kv.kvec_d, this->ucell, this->gd, this->orb_cutoff_);
192+
// print edm_real (R)
193+
if (PARAM.inp.test_force)
194+
{
195+
LR_Util::save_DMR(edm_real, "data-EDMR-sparse", this->paraMat_);
196+
// LR_Util::print_DMR(edm_real, this->ucell.nat, "edm_real (R) of istate " + std::to_string(istate));
197+
}
150198

151199
ModuleBase::matrix force_hxc_dmtrans = lr_force.cal_force_hxc_dmtrans(dm_trans_real, *this->pot[ispin]);
152200
std::cout << "Force (Hxc-DMTrans term) of state " << istate << ": " << std::endl;

source/module_lr/utils/lr_util_hcontainer.h

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include "module_base/parallel_reduce.h"
55
#include "module_base/macros.h"
66
#include <ATen/core/tensor.h>
7+
#include "module_parameter/parameter.h"
8+
#include "module_io/single_R_io.h"
79
namespace LR_Util
810
{
911
template <typename T>
@@ -189,4 +191,109 @@ namespace LR_Util
189191
if (cal_dmr) { dm.cal_DMR(); }
190192
return dm;
191193
}
194+
195+
namespace sparse_format
196+
{
197+
// ref: sparse_format::cal_HContainer_d/cd and sparse_format::cal_HSR
198+
// but more general(not depend on LCAO_HS_Arrays)
199+
template<typename TR>
200+
std::map<Abfs::Vector3_Order<int>, std::map<size_t, std::map<size_t, TR>>>
201+
get_sparse_format(
202+
const hamilt::HContainer<TR>& hR,
203+
const Parallel_Orbitals& pv,
204+
const double& sparse_thr = 1e-10)
205+
{
206+
std::map<Abfs::Vector3_Order<int>, std::map<size_t, std::map<size_t, TR>>> target;
207+
auto row_indexes = pv.get_indexes_row();
208+
auto col_indexes = pv.get_indexes_col();
209+
for (int iap = 0; iap < hR.size_atom_pairs(); ++iap) {
210+
int atom_i = hR.get_atom_pair(iap).get_atom_i();
211+
int atom_j = hR.get_atom_pair(iap).get_atom_j();
212+
int start_i = pv.atom_begin_row[atom_i];
213+
int start_j = pv.atom_begin_col[atom_j];
214+
int row_size = pv.get_row_size(atom_i);
215+
int col_size = pv.get_col_size(atom_j);
216+
for (int iR = 0; iR < hR.get_atom_pair(iap).get_R_size(); ++iR) {
217+
auto& matrix = hR.get_atom_pair(iap).get_HR_values(iR);
218+
const ModuleBase::Vector3<int> r_index
219+
= hR.get_atom_pair(iap).get_R_index(iR);
220+
Abfs::Vector3_Order<int> dR(r_index.x, r_index.y, r_index.z);
221+
for (int i = 0; i < row_size; ++i) {
222+
int mu = row_indexes[start_i + i];
223+
for (int j = 0; j < col_size; ++j) {
224+
int nu = col_indexes[start_j + j];
225+
const auto& value_tmp = matrix.get_value(i, j);
226+
if (std::abs(value_tmp) > sparse_thr) {
227+
target[dR][mu][nu] = value_tmp;
228+
}
229+
}
230+
}
231+
}
232+
}
233+
return target;
234+
}
235+
236+
//a more general version of save_HSR_sparse (not depend on LCAO_HS_Arrays)
237+
template<typename TR>
238+
void save_sparse(
239+
const std::map<Abfs::Vector3_Order<int>, std::map<size_t, std::map<size_t, TR>>>& smat,
240+
// const std::set<Abfs::Vector3_Order<int>>& all_R_coor,
241+
// const bool& binary,
242+
const std::string& filename,
243+
const Parallel_Orbitals& pv,
244+
const double& sparse_thr = 1e-10)
245+
{
246+
// calculate the total number of non-zero elements of the (nbasis, nbasis) matrix for each R
247+
std::vector<int> non_zero_counts(smat.size(), 0); // number of Rs
248+
int i = 0;
249+
for (const auto& Rij : smat)
250+
non_zero_counts[i++] = std::accumulate(Rij.second.begin(), Rij.second.end(), 0,
251+
[](int sum, const auto& line) { return sum + line.second.size(); });
252+
Parallel_Reduce::reduce_all(non_zero_counts.data(), non_zero_counts.size());
253+
254+
255+
std::string out_dir = PARAM.globalv.global_out_dir + filename;
256+
std::ofstream ofs;
257+
if (GlobalV::DRANK == 0)
258+
{
259+
ofs.open(out_dir);
260+
// if (binary) ofs.open(out_dir, std::ios::binary);
261+
ofs << "STEP: 0" << std::endl;
262+
ofs << "Matrix Dimension: " << PARAM.globalv.nlocal << std::endl;
263+
ofs << "Matrix number: " << non_zero_counts.size() << std::endl;
264+
}
265+
i = 0;
266+
for (const auto& Rij : smat)
267+
{
268+
const auto& R = Rij.first;
269+
ofs << R.x << " " << R.y << " " << R.z << " " << non_zero_counts[i++] << std::endl;
270+
ModuleIO::output_single_R(ofs, Rij.second, sparse_thr, false, pv);
271+
}
272+
if (GlobalV::DRANK == 0) { ofs.close(); }
273+
}
274+
}
275+
276+
template<typename TR>
277+
void save_HR(
278+
const hamilt::HContainer<TR>& hR,
279+
// const std::set<Abfs::Vector3_Order<int>>& all_R_coor,
280+
// const bool& binary,
281+
const std::string& filename,
282+
const Parallel_Orbitals& pv,
283+
const double& sparse_thr = 1e-10)
284+
{
285+
sparse_format::save_sparse(sparse_format::get_sparse_format(hR, pv, sparse_thr),
286+
filename, pv, sparse_thr);
287+
}
288+
289+
template <typename TK, typename TR>
290+
void save_DMR(const elecstate::DensityMatrix<TK, TR>& DMR,
291+
const std::string& filename,
292+
const Parallel_Orbitals& pv,
293+
const double& sparse_thr = 1e-10)
294+
{
295+
int is = 0;
296+
for (auto& dr : DMR.get_DMR_vector())
297+
save_HR(*dr, filename + "_s" + std::to_string(is), pv, sparse_thr);
298+
}
192299
}

0 commit comments

Comments
 (0)