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"
79namespace 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