ABACUS develop
Atomic-orbital Based Ab-initio Computation at UStc
Loading...
Searching...
No Matches
RI_2D_Comm.hpp
Go to the documentation of this file.
1//=======================
2// AUTHOR : Peize Lin
3// DATE : 2022-08-17
4//=======================
5
6#ifndef RI_2D_COMM_HPP
7#define RI_2D_COMM_HPP
8#include "RI_2D_Comm.h"
9#include "RI_Util.h"
11#include "source_base/timer.h"
14#include <Comm/Comm_Assemble/Comm_Assemble.h>
15#include <Comm/example/Communicate_Map-1.h>
16#include <Comm/example/Communicate_Map-2.h>
17#include <RI/comm/example/Communicate_Map_Period.h>
18#include <RI/comm/mix/Communicate_Tensors_Map.h>
19#include <RI/global/Global_Func-2.h>
20
21#include <cmath>
22#include <string>
23#include <stdexcept>
24
25#ifdef _OPENMP
26#include <omp.h>
27#endif
28
29inline RI::Tensor<double> tensor_conj(const RI::Tensor<double>& t) { return t; }
30inline RI::Tensor<std::complex<double>> tensor_conj(const RI::Tensor<std::complex<double>>& t)
31{
32 RI::Tensor<std::complex<double>> r(t.shape);
33 for (int i = 0; i < t.data->size(); ++i) {
34 (*r.data)[i] = std::conj((*t.data)[i]);
35 }
36 return r;
37}
38template<typename Tdata, typename Tmatrix>
39auto RI_2D_Comm::split_m2D_ktoR(const UnitCell& ucell,
40 const K_Vectors & kv,
41 const std::vector<const Tmatrix*>&mks_2D,
42 const Parallel_2D & pv,
43 const int nspin,
44 const bool spgsym)
45-> std::vector<std::map<TA,std::map<TAC,RI::Tensor<Tdata>>>>
46{
47 ModuleBase::TITLE("RI_2D_Comm","split_m2D_ktoR");
48 ModuleBase::timer::start("RI_2D_Comm", "split_m2D_ktoR");
49 const TC period = RI_Util::get_Born_vonKarmen_period(kv);
50 std::vector<std::map<TA, std::map<TAC, RI::Tensor<Tdata>>>> mRs_a2D
51 = (period == TC{1, 1, 1})
52 ? RI_2D_Comm::split_m2D_ktoR_gamma<Tdata, Tmatrix>(ucell, mks_2D, pv, nspin)
53 : RI_2D_Comm::split_m2D_ktoR_k<Tdata, Tmatrix>(ucell, kv, mks_2D, pv, nspin, spgsym);
54 ModuleBase::timer::end("RI_2D_Comm", "split_m2D_ktoR");
55 return mRs_a2D;
56}
57
58template<typename Tdata, typename Tmatrix>
60 const std::vector<const Tmatrix*>& mks_2D,
61 const Parallel_2D& pv,
62 const int nspin)
63-> std::vector<std::map<TA, std::map<TAC, RI::Tensor<Tdata>>>>
64{
65 ModuleBase::TITLE("RI_2D_Comm","split_m2D_ktoR_gamma");
66 ModuleBase::timer::start("RI_2D_Comm", "split_m2D_ktoR_gamma");
67
68 const std::map<int,int> nspin_k = {{1,1}, {2,2}, {4,1}};
69 const double SPIN_multiple = std::map<int, double>{ {1,0.5}, {2,1}, {4,1} }.at(nspin); // why?
70 const TC cell = {0, 0, 0};
71
72 std::vector<std::map<TA, std::map<TAC, RI::Tensor<Tdata>>>> mRs_a2D(nspin);
73
74 #ifdef _OPENMP
75 // pre-init all outer maps mRs_a2D[is_b][iat] to avoid concurrent std::map rebalancing
76 for (int is_b = 0; is_b < nspin; ++is_b)
77 for (int iat0 = 0; iat0 < ucell.nat; ++iat0)
78 mRs_a2D[is_b][iat0];
79
80 std::vector<omp_lock_t> locks(ucell.nat);
81 for (auto& l : locks)
82 omp_init_lock(&l);
83 #endif
84
85 for (int is_k = 0; is_k < nspin_k.at(nspin); ++is_k)
86 {
87 using Tdata_m = typename Tmatrix::value_type;
88 RI::Tensor<Tdata_m> mk_2D
89 = RI_Util::Vector_to_Tensor<Tdata_m>(*mks_2D[is_k], pv.get_col_size(), pv.get_row_size());
90 const Tdata_m frac = RI::Global_Func::convert<Tdata_m>(SPIN_multiple);
91 RI::Tensor<Tdata> mR_2D = RI::Global_Func::convert<Tdata>(mk_2D * frac);
92
93 #ifdef _OPENMP
94 #pragma omp parallel for schedule(dynamic)
95 #endif
96 for (int iwt0_2D = 0; iwt0_2D != mR_2D.shape[0]; ++iwt0_2D)
97 {
98 const int iwt0 = ModuleBase::GlobalFunc::IS_COLUMN_MAJOR_KS_SOLVER(PARAM.inp.ks_solver)
99 ? pv.local2global_col(iwt0_2D)
100 : pv.local2global_row(iwt0_2D);
101 int iat0, iw0_b, is0_b;
102 std::tie(iat0, iw0_b, is0_b) = RI_2D_Comm::get_iat_iw_is_block(ucell, iwt0);
103 const int it0 = ucell.iat2it[iat0];
104 for (int iwt1_2D = 0; iwt1_2D != mR_2D.shape[1]; ++iwt1_2D)
105 {
106 const int iwt1 = ModuleBase::GlobalFunc::IS_COLUMN_MAJOR_KS_SOLVER(PARAM.inp.ks_solver)
107 ? pv.local2global_row(iwt1_2D)
108 : pv.local2global_col(iwt1_2D);
109 int iat1, iw1_b, is1_b;
110 std::tie(iat1, iw1_b, is1_b) = RI_2D_Comm::get_iat_iw_is_block(ucell, iwt1);
111 const int it1 = ucell.iat2it[iat1];
112
113 const int is_b = RI_2D_Comm::get_is_block(is_k, is0_b, is1_b);
114 #ifdef _OPENMP
115 omp_set_lock(&locks[iat0]);
116 #endif
117 RI::Tensor<Tdata>& mR_a2D = mRs_a2D[is_b][iat0][{iat1, cell}];
118 if (mR_a2D.empty())
119 {
120 mR_a2D = RI::Tensor<Tdata>(
121 {static_cast<size_t>(ucell.atoms[it0].nw),
122 static_cast<size_t>(ucell.atoms[it1].nw)});
123 }
124 mR_a2D(iw0_b, iw1_b) = mR_2D(iwt0_2D, iwt1_2D);
125 #ifdef _OPENMP
126 omp_unset_lock(&locks[iat0]);
127 #endif
128 }
129 }
130 }
131
132 #ifdef _OPENMP
133 for (auto& l : locks)
134 omp_destroy_lock(&l);
135
136 // prune empty inner maps created by pre-init
137 for (int is_b = 0; is_b < nspin; ++is_b)
138 for (auto it = mRs_a2D[is_b].begin(); it != mRs_a2D[is_b].end();)
139 {
140 if (it->second.empty())
141 it = mRs_a2D[is_b].erase(it);
142 else
143 ++it;
144 }
145 #endif
146
147 ModuleBase::timer::end("RI_2D_Comm", "split_m2D_ktoR_gamma");
148 return mRs_a2D;
149}
150
151template<typename Tdata, typename Tmatrix>
152auto RI_2D_Comm::split_m2D_ktoR_k(const UnitCell& ucell,
153 const K_Vectors& kv,
154 const std::vector<const Tmatrix*>& mks_2D,
155 const Parallel_2D& pv,
156 const int nspin,
157 const bool spgsym)
158-> std::vector<std::map<TA, std::map<TAC, RI::Tensor<Tdata>>>>
159{
160 ModuleBase::TITLE("RI_2D_Comm","split_m2D_ktoR_k");
161 ModuleBase::timer::start("RI_2D_Comm", "split_m2D_ktoR_k");
162
163 const TC period = RI_Util::get_Born_vonKarmen_period(kv);
164 const std::map<int,int> nspin_k = {{1,1}, {2,2}, {4,1}};
165 const double SPIN_multiple = std::map<int, double>{ {1,0.5}, {2,1}, {4,1} }.at(nspin); // why?
166
167 std::vector<std::map<TA, std::map<TAC, RI::Tensor<Tdata>>>> mRs_a2D(nspin);
168 #ifdef _OPENMP
169 #pragma omp parallel
170 #endif
171 {
172 std::vector<std::map<TA, std::map<TAC, RI::Tensor<Tdata>>>> mRs_a2D_thread(nspin);
173 for (int is_k = 0; is_k < nspin_k.at(nspin); ++is_k)
174 {
175 const std::vector<int> ik_list = RI_2D_Comm::get_ik_list(kv, is_k);
176 const auto cells = RI_Util::get_Born_von_Karmen_cells(period);
177 #pragma omp for schedule(dynamic)
178 for (size_t icell = 0; icell < cells.size(); ++icell)
179 {
180 const TC& cell = cells[icell];
181 RI::Tensor<Tdata> mR_2D;
182 int ik_full = 0;
183 for (const int ik : ik_list)
184 {
185 auto set_mR_2D = [&mR_2D](auto&& mk_frac)
186 {
187 if (mR_2D.empty())
188 { mR_2D = RI::Global_Func::convert<Tdata>(mk_frac); }
189 else
190 { mR_2D = mR_2D + RI::Global_Func::convert<Tdata>(mk_frac); }
191 };
192 using Tdata_m = typename Tmatrix::value_type;
193 if (!spgsym)
194 {
195 RI::Tensor<Tdata_m> mk_2D = RI_Util::Vector_to_Tensor<Tdata_m>(*mks_2D[ik], pv.get_col_size(), pv.get_row_size());
196 const Tdata_m frac = SPIN_multiple
197 * RI::Global_Func::convert<Tdata_m>(std::exp(
198 -ModuleBase::TWO_PI * ModuleBase::IMAG_UNIT * (kv.kvec_c[ik] * (RI_Util::array3_to_Vector3(cell) * ucell.latvec))));
199 if (static_cast<int>(std::round(SPIN_multiple * kv.wk[ik] * kv.get_nkstot_full())) == 2)
200 { set_mR_2D(mk_2D * (frac * 0.5) + tensor_conj(mk_2D * (frac * 0.5))); }
201 else
202 { set_mR_2D(mk_2D * frac); }
203 }
204 else
205 { // traverse kstar, ik means ik_ibz
206 for (auto& isym_kvd : kv.kstars[ik % ik_list.size()])
207 {
208 RI::Tensor<Tdata_m> mk_2D = RI_Util::Vector_to_Tensor<Tdata_m>(*mks_2D[ik_full + is_k * kv.get_nkstot_full()], pv.get_col_size(), pv.get_row_size());
209 const Tdata_m frac = SPIN_multiple
210 * RI::Global_Func::convert<Tdata_m>(std::exp(
211 -ModuleBase::TWO_PI * ModuleBase::IMAG_UNIT * ((isym_kvd.second * ucell.G) * (RI_Util::array3_to_Vector3(cell) * ucell.latvec))));
212 set_mR_2D(mk_2D * frac);
213 ++ik_full;
214 }
215 }
216 } // end for ik
217 for(int iwt0_2D=0; iwt0_2D!=mR_2D.shape[0]; ++iwt0_2D)
218 {
219 const int iwt0 =ModuleBase::GlobalFunc::IS_COLUMN_MAJOR_KS_SOLVER(PARAM.inp.ks_solver)
220 ? pv.local2global_col(iwt0_2D)
221 : pv.local2global_row(iwt0_2D);
222 int iat0, iw0_b, is0_b;
223 std::tie(iat0,iw0_b,is0_b) = RI_2D_Comm::get_iat_iw_is_block(ucell,iwt0);
224 const int it0 = ucell.iat2it[iat0];
225 for(int iwt1_2D=0; iwt1_2D!=mR_2D.shape[1]; ++iwt1_2D)
226 {
227 const int iwt1 =ModuleBase::GlobalFunc::IS_COLUMN_MAJOR_KS_SOLVER(PARAM.inp.ks_solver)
228 ? pv.local2global_row(iwt1_2D)
229 : pv.local2global_col(iwt1_2D);
230 int iat1, iw1_b, is1_b;
231 std::tie(iat1,iw1_b,is1_b) = RI_2D_Comm::get_iat_iw_is_block(ucell,iwt1);
232 const int it1 = ucell.iat2it[iat1];
233
234 const int is_b = RI_2D_Comm::get_is_block(is_k, is0_b, is1_b);
235 RI::Tensor<Tdata>& mR_a2D = mRs_a2D_thread[is_b][iat0][{iat1, cell}];
236 if (mR_a2D.empty())
237 {
238 mR_a2D = RI::Tensor<Tdata>(
239 {static_cast<size_t>(ucell.atoms[it0].nw),
240 static_cast<size_t>(ucell.atoms[it1].nw)});
241 }
242 mR_a2D(iw0_b, iw1_b) = mR_2D(iwt0_2D, iwt1_2D);
243 } // for iwt1_2D
244 } // end for iwt0_2D
245 } // end for icell
246 } // end for is_k
247
248 #ifdef _OPENMP
249 #pragma omp critical
250 #endif
251 {
252 for(int is=0; is<nspin; ++is)
253 for(auto &mRs_A : mRs_a2D_thread[is])
254 for(auto &mRs_B : mRs_A.second)
255 {
256 assert(mRs_a2D[is][mRs_A.first][mRs_B.first].empty());
257 mRs_a2D[is][mRs_A.first][mRs_B.first] = std::move(mRs_B.second);
258 }
259 }
260 } // end #pragma omp parallel
261 ModuleBase::timer::end("RI_2D_Comm", "split_m2D_ktoR_k");
262 return mRs_a2D;
263}
264
265
266template<typename Tdata, typename TK>
268 const UnitCell &ucell,
269 const K_Vectors &kv,
270 const int ik,
271 const double alpha,
272 const std::vector<std::map<TA,std::map<TAC,RI::Tensor<Tdata>>>> &Hs,
273 const Parallel_Orbitals& pv,
274 TK* hk)
275{
276 ModuleBase::TITLE("RI_2D_Comm","add_Hexx");
277 ModuleBase::timer::start("RI_2D_Comm", "add_Hexx");
278
279 const std::map<int, std::vector<int>> is_list = {{1,{0}}, {2,{kv.isk[ik]}}, {4,{0,1,2,3}}};
280 for(const int is_b : is_list.at(PARAM.inp.nspin))
281 {
282 int is0_b, is1_b;
283 std::tie(is0_b,is1_b) = RI_2D_Comm::split_is_block(is_b);
284 for(const auto &Hs_tmpA : Hs[is_b])
285 {
286 const TA &iat0 = Hs_tmpA.first;
287 for(const auto &Hs_tmpB : Hs_tmpA.second)
288 {
289 const TA &iat1 = Hs_tmpB.first.first;
290 const TC &cell1 = Hs_tmpB.first.second;
291 const std::complex<double> frac = alpha
292 * std::exp( ModuleBase::TWO_PI*ModuleBase::IMAG_UNIT * (kv.kvec_c[ik] * (RI_Util::array3_to_Vector3(cell1)*ucell.latvec)) );
293 const RI::Tensor<Tdata> &H = Hs_tmpB.second;
294 for(size_t iw0_b=0; iw0_b<H.shape[0]; ++iw0_b)
295 {
296 const int iwt0 = RI_2D_Comm::get_iwt(ucell,iat0, iw0_b, is0_b);
297 if (pv.global2local_row(iwt0) < 0) {
298 continue;
299 }
300 for(size_t iw1_b=0; iw1_b<H.shape[1]; ++iw1_b)
301 {
302 const int iwt1 = RI_2D_Comm::get_iwt(ucell,iat1, iw1_b, is1_b);
303 if (pv.global2local_col(iwt1) < 0) {
304 continue;
305 }
306 LCAO_domain::set_mat2d(iwt0, iwt1, RI::Global_Func::convert<TK>(H(iw0_b, iw1_b)) * RI::Global_Func::convert<TK>(frac), pv, hk);
307 }
308 }
309 }
310 }
311 }
312 ModuleBase::timer::end("RI_2D_Comm", "add_Hexx");
313}
314
315template <typename Tdata, typename TK>
317 const UnitCell& ucell,
318 const K_Vectors& kv,
319 const int ik,
320 const double alpha,
321 const std::vector<std::map<TA, std::map<TAC, RI::Tensor<Tdata>>>>& Hs,
322 const Parallel_Orbitals& pv,
324 TK* hk)
325{
326 ModuleBase::TITLE("RI_2D_Comm", "add_Hexx_td");
327 ModuleBase::timer::start("RI_2D_Comm", "add_Hexx_td");
328
329 const std::map<int, std::vector<int>> is_list = {{1, {0}}, {2, {kv.isk[ik]}}, {4, {0, 1, 2, 3}}};
330 for (const int is_b : is_list.at(PARAM.inp.nspin))
331 {
332 int is0_b = 0;
333 int is1_b = 0;
334 std::tie(is0_b, is1_b) = RI_2D_Comm::split_is_block(is_b);
335 for (const auto& Hs_tmpA : Hs[is_b])
336 {
337 const TA& iat0 = Hs_tmpA.first;
338 for (const auto& Hs_tmpB : Hs_tmpA.second)
339 {
340 const TA& iat1 = Hs_tmpB.first.first;
341 const TC& cell1 = Hs_tmpB.first.second;
343 const ModuleBase::Vector3<double> dtau = ucell.cal_dtau(iat0, iat1, r_index);
344 const double arg_td = At * dtau * ucell.lat0;
345
346 const std::complex<double> frac
347 = alpha
348 * std::exp(ModuleBase::IMAG_UNIT
349 * ((ModuleBase::TWO_PI * kv.kvec_c[ik] * (r_index * ucell.latvec)) + arg_td));
350
351 const RI::Tensor<Tdata>& H = Hs_tmpB.second;
352 for (size_t iw0_b = 0; iw0_b < H.shape[0]; ++iw0_b)
353 {
354 const int iwt0 = RI_2D_Comm::get_iwt(ucell, iat0, iw0_b, is0_b);
355 if (pv.global2local_row(iwt0) < 0)
356 {
357 continue;
358 }
359 for (size_t iw1_b = 0; iw1_b < H.shape[1]; ++iw1_b)
360 {
361 const int iwt1 = RI_2D_Comm::get_iwt(ucell, iat1, iw1_b, is1_b);
362 if (pv.global2local_col(iwt1) < 0)
363 {
364 continue;
365 }
367 iwt1,
368 RI::Global_Func::convert<TK>(H(iw0_b, iw1_b))
369 * RI::Global_Func::convert<TK>(frac),
370 pv,
371 hk);
372 }
373 }
374 }
375 }
376 }
377 ModuleBase::timer::end("RI_2D_Comm", "add_Hexx_td");
378}
379
380std::tuple<int,int,int>
381RI_2D_Comm::get_iat_iw_is_block(const UnitCell& ucell,const int& iwt)
382{
383 const int iat = ucell.iwt2iat[iwt];
384 const int iw = ucell.iwt2iw[iwt];
385 switch(PARAM.inp.nspin)
386 {
387 case 1: case 2:
388 return std::make_tuple(iat, iw, 0);
389 case 4:
390 return std::make_tuple(iat, iw/2, iw%2);
391 default:
392 throw std::invalid_argument(std::string(__FILE__)+" line "+std::to_string(__LINE__));
393 }
394}
395
396int RI_2D_Comm::get_is_block(const int is_k, const int is_row_b, const int is_col_b)
397{
398 switch(PARAM.inp.nspin)
399 {
400 case 1: return 0;
401 case 2: return is_k;
402 case 4: return is_row_b*2+is_col_b;
403 default: throw std::invalid_argument(std::string(__FILE__)+" line "+std::to_string(__LINE__));
404 }
405}
406
407std::tuple<int,int>
409{
410 switch(PARAM.inp.nspin)
411 {
412 case 1: case 2:
413 return std::make_tuple(0, 0);
414 case 4:
415 return std::make_tuple(is_b/2, is_b%2);
416 default:
417 throw std::invalid_argument(std::string(__FILE__)+" line "+std::to_string(__LINE__));
418 }
419}
420
421
422
424 const int iat,
425 const int iw_b,
426 const int is_b)
427{
428 const int it = ucell.iat2it[iat];
429 const int ia = ucell.iat2ia[iat];
430 int iw=-1;
431 switch(PARAM.inp.nspin)
432 {
433 case 1: case 2:
434 iw = iw_b; break;
435 case 4:
436 iw = iw_b*2+is_b; break;
437 default:
438 throw std::invalid_argument(std::string(__FILE__)+" line "+std::to_string(__LINE__));
439 }
440 const int iwt = ucell.itiaiw2iwt(it,ia,iw);
441 return iwt;
442}
443
444template<typename Tdata, typename TR>
446 const int current_spin,
447 const double alpha,
448 const std::vector<std::map<TA, std::map<TAC, RI::Tensor<Tdata>>>>& Hs,
449 const Parallel_Orbitals& pv,
450 const int npol,
452 const RI::Cell_Nearest<int, int, 3, double, 3>* const cell_nearest)
453{
454 ModuleBase::TITLE("RI_2D_Comm", "add_HexxR");
455 ModuleBase::timer::start("RI_2D_Comm", "add_HexxR");
456 const std::map<int, std::vector<int>> is_list = { {1,{0}}, {2,{current_spin}}, {4,{0,1,2,3}} };
457 for (const int is_hs : is_list.at(PARAM.inp.nspin))
458 {
459 int is0_b = 0, is1_b = 0;
460 std::tie(is0_b, is1_b) = RI_2D_Comm::split_is_block(is_hs);
461 for (const auto& Hs_tmpA : Hs[is_hs])
462 {
463 const TA& iat0 = Hs_tmpA.first;
464 for (const auto& Hs_tmpB : Hs_tmpA.second)
465 {
466 const TA& iat1 = Hs_tmpB.first.first;
467 const TC& cell = Hs_tmpB.first.second;
469 (cell_nearest ?
470 cell_nearest->get_cell_nearest_discrete(iat0, iat1, cell)
471 : cell));
472 hamilt::BaseMatrix<TR>* HlocR = hR.find_matrix(iat0, iat1, R.x, R.y, R.z);
473 auto row_indexes = pv.get_indexes_row(iat0);
474 auto col_indexes = pv.get_indexes_col(iat1);
475 const RI::Tensor<Tdata>& HexxR = (Tdata)alpha * Hs_tmpB.second;
476 for (int lw0_b = 0;lw0_b < row_indexes.size();lw0_b += npol) // block
477 {
478 const int& gw0 = row_indexes[lw0_b] / npol;
479 const int& lw0 = (npol == 2) ? (lw0_b + is0_b) : lw0_b;
480 for (int lw1_b = 0;lw1_b < col_indexes.size();lw1_b += npol)
481 {
482 const int& gw1 = col_indexes[lw1_b] / npol;
483 const int& lw1 = (npol == 2) ? (lw1_b + is1_b) : lw1_b;
484 HlocR->add_element(lw0, lw1, RI::Global_Func::convert<TR>(HexxR(gw0, gw1)));
485 }
486 }
487 }
488 }
489 }
490
491 ModuleBase::timer::end("RI_2D_Comm", "add_HexxR");
492}
493
494template <typename TA, typename TAC, typename T>
495std::map<TA, std::map<TAC, T>> RI_2D_Comm::comm_map2_first(const MPI_Comm& mpi_comm,
496 const std::map<TA, std::map<TAC, T>>& Ds_in,
497 const std::set<TA>& s0,
498 const std::set<TA>& s1)
499{
500 RI::Communicate_Map_Period::Judge_Map2_First<TA> judge;
501 judge.s0 = s0;
502 judge.s1 = s1;
503 return comm_map2(mpi_comm, Ds_in, judge);
504}
505
506template <typename TA, typename TAC, typename T, typename Tjudge>
507std::map<TA, std::map<TAC, T>> RI_2D_Comm::comm_map2(const MPI_Comm& mpi_comm,
508 const std::map<TA, std::map<TAC, T>>& Ds_in,
509 const Tjudge& judge)
510{
511 Comm::Comm_Assemble<std::tuple<TA, TAC>, T, std::map<TA, std::map<TAC, T>>, Tjudge, std::map<TA, std::map<TAC, T>>>
512 com(mpi_comm);
513
514 com.traverse_keys_provide = Comm::Communicate_Map::traverse_keys<TA, TAC, T>;
515 com.get_value_provide = Comm::Communicate_Map::get_value<TA, TAC, T>;
516 com.set_value_require = set_value_add<TA, TAC, T>;
517 com.flag_lock_set_value = Comm::Comm_Tools::Lock_Type::Copy_merge;
518 com.init_datas_local = Comm::Communicate_Map::init_datas_local<TA, TAC, T>;
519 com.add_datas = add_datas<TA, TAC, T>;
520
521 std::map<TA, std::map<TAC, T>> Ds_out;
522 com.communicate(Ds_in, judge, Ds_out);
523 return Ds_out;
524}
525
526template <typename Tkey, typename Tvalue>
527void RI_2D_Comm::set_value_add(Tkey&& key, Tvalue&& value, std::map<Tkey, Tvalue>& data)
528{
529 using namespace RI::Array_Operator;
530 auto ptr = data.find(key);
531 if (ptr == data.end())
532 data[key] = std::move(value);
533 else
534 ptr->second = ptr->second + std::move(value);
535}
536
537template <typename Tkey0, typename Tkey1, typename Tvalue>
538void RI_2D_Comm::set_value_add(std::tuple<Tkey0, Tkey1>&& key,
539 Tvalue&& value,
540 std::map<Tkey0, std::map<Tkey1, Tvalue>>& data)
541{
542 set_value_add(std::move(std::get<1>(key)), std::move(value), data[std::get<0>(key)]);
543}
544
545template <typename Tkey, typename Tvalue>
546void RI_2D_Comm::add_datas(std::map<Tkey, Tvalue>&& data_local, std::map<Tkey, Tvalue>& data_recv)
547{
548 using namespace RI::Array_Operator;
549 auto ptr_local = data_local.begin();
550 auto ptr_recv = data_recv.begin();
551 for (; ptr_local != data_local.end() && ptr_recv != data_recv.end();)
552 {
553 const Tkey& key_local = ptr_local->first;
554 const Tkey& key_recv = ptr_recv->first;
555 if (key_local == key_recv)
556 {
557 ptr_recv->second = ptr_recv->second + std::move(ptr_local->second);
558 ++ptr_local;
559 ++ptr_recv;
560 }
561 else if (key_local < key_recv)
562 {
563 ptr_recv = data_recv.emplace_hint(ptr_recv, key_local, std::move(ptr_local->second));
564 ++ptr_local;
565 }
566 else
567 {
568 ++ptr_recv;
569 }
570 }
571 for (; ptr_local != data_local.end(); ++ptr_local)
572 {
573 ptr_recv = data_recv.emplace_hint(ptr_recv, ptr_local->first, std::move(ptr_local->second));
574 }
575}
576
577template <typename Tkey0, typename Tkey1, typename Tvalue>
578void RI_2D_Comm::add_datas(std::map<Tkey0, std::map<Tkey1, Tvalue>>&& data_local,
579 std::map<Tkey0, std::map<Tkey1, Tvalue>>& data_recv)
580{
581 auto ptr_local = data_local.begin();
582 auto ptr_recv = data_recv.begin();
583 for (; ptr_local != data_local.end() && ptr_recv != data_recv.end();)
584 {
585 const Tkey0& key_local = ptr_local->first;
586 const Tkey0& key_recv = ptr_recv->first;
587 if (key_local == key_recv)
588 {
589 add_datas(std::move(ptr_local->second), ptr_recv->second);
590 ++ptr_local;
591 ++ptr_recv;
592 }
593 else if (key_local < key_recv)
594 {
595 ptr_recv = data_recv.emplace_hint(ptr_recv, key_local, std::move(ptr_local->second));
596 ++ptr_local;
597 }
598 else
599 {
600 ++ptr_recv;
601 }
602 }
603 for (; ptr_local != data_local.end(); ++ptr_local)
604 {
605 ptr_recv = data_recv.emplace_hint(ptr_recv, ptr_local->first, std::move(ptr_local->second));
606 }
607}
608
609#endif
RI::Tensor< double > tensor_conj(const RI::Tensor< double > &t)
Definition RI_2D_Comm.hpp:29
const std::complex< double > i
Definition cal_pLpR.cpp:46
Definition abfs-vector3_order.h:16
Definition klist.h:12
std::vector< int > isk
ngk, number of plane waves for each k point
Definition klist.h:21
std::vector< ModuleBase::Vector3< double > > kvec_c
Definition klist.h:14
3 elements vector
Definition vector3.h:24
T x
Definition vector3.h:26
T y
Definition vector3.h:27
T z
Definition vector3.h:28
static void start(void)
Start total time calculation.
Definition timer.cpp:44
static void end(const std::string &class_name_in, const std::string &name_in)
Definition timer.cpp:109
This class packs the basic information of 2D-block-cyclic parallel distribution of an arbitrary matri...
Definition parallel_2d.h:12
int global2local_col(const int igc) const
get the local index of a global index (col)
Definition parallel_2d.h:51
int global2local_row(const int igr) const
get the local index of a global index (row)
Definition parallel_2d.h:45
Definition parallel_orbitals.h:9
std::vector< int > get_indexes_col() const
Definition parallel_orbitals.cpp:154
std::vector< int > get_indexes_row() const
gather global indexes of orbitals in this processor get_indexes_row() : global indexes (~NLOCAL) of r...
Definition parallel_orbitals.cpp:140
const Input_para & inp
Definition parameter.h:26
Definition unitcell.h:15
int *& iat2it
Definition unitcell.h:75
Tiait itiaiw2iwt(const Tiait &it, const Tiait &ia, const Tiait &iw) const
Definition unitcell.h:96
double & lat0
Definition unitcell.h:56
ModuleBase::Matrix3 & latvec
Definition unitcell.h:63
int *& iwt2iw
Definition unitcell.h:78
int *& iat2ia
Definition unitcell.h:76
int *& iwt2iat
Definition unitcell.h:77
const ModuleBase::Vector3< double > cal_dtau(const int &iat1, const int &iat2, const ModuleBase::Vector3< int > &R) const
Definition unitcell.h:183
Definition base_matrix.h:20
void add_element(int mu, int nu, const T &value)
add a single element to the matrix
Definition base_matrix.h:57
Definition hcontainer.h:144
BaseMatrix< T > * find_matrix(int i, int j, int rx, int ry, int rz)
find BaseMatrix with atom index atom_i and atom_j and R index (rx, ry, rz) This interface can be used...
Definition hcontainer.cpp:286
#define T
Definition exp.cpp:237
void set_mat2d(const int &global_ir, const int &global_ic, const T &v, const Parallel_Orbitals &pv, T *mat)
Definition LCAO_set_mat2d.cpp:13
const double TWO_PI
Definition constants.h:21
const std::complex< double > IMAG_UNIT(0.0, 1.0)
void TITLE(const std::string &class_name, const std::string &function_name, const bool disable)
Definition tool_title.cpp:18
std::vector< int > get_ik_list(const K_Vectors &kv, const int is_k)
Definition RI_2D_Comm.cpp:65
int get_is_block(const int is_k, const int is_row_b, const int is_col_b)
Definition RI_2D_Comm.hpp:396
std::map< TA, std::map< TAC, T > > comm_map2(const MPI_Comm &mpi_comm, const std::map< TA, std::map< TAC, T > > &Ds_in, const Tjudge &judge)
Definition RI_2D_Comm.hpp:507
std::vector< std::map< TA, std::map< TAC, RI::Tensor< Tdata > > > > split_m2D_ktoR_gamma(const UnitCell &ucell, const std::vector< const Tmatrix * > &mks_2D, const Parallel_2D &pv, const int nspin)
std::vector< std::map< TA, std::map< TAC, RI::Tensor< Tdata > > > > split_m2D_ktoR(const UnitCell &ucell, const K_Vectors &kv, const std::vector< const Tmatrix * > &mks_2D, const Parallel_2D &pv, const int nspin, const bool spgsym=false)
int TA
Definition RI_2D_Comm.h:25
std::pair< TA, TC > TAC
Definition RI_2D_Comm.h:29
std::vector< std::map< TA, std::map< TAC, RI::Tensor< Tdata > > > > split_m2D_ktoR_k(const UnitCell &ucell, const K_Vectors &kv, const std::vector< const Tmatrix * > &mks_2D, const Parallel_2D &pv, const int nspin, const bool spgsym=false)
void set_value_add(Tkey &&key, Tvalue &&value, std::map< Tkey, Tvalue > &data)
Definition RI_2D_Comm.hpp:527
void add_Hexx_td(const UnitCell &ucell, const K_Vectors &kv, const int ik, const double alpha, const std::vector< std::map< TA, std::map< TAC, RI::Tensor< Tdata > > > > &Hs, const Parallel_Orbitals &pv, const ModuleBase::Vector3< double > &At, TK *hk)
Definition RI_2D_Comm.hpp:316
std::tuple< int, int > split_is_block(const int is_b)
Definition RI_2D_Comm.hpp:408
void add_HexxR(const int current_spin, const double alpha, const std::vector< std::map< TA, std::map< TAC, RI::Tensor< Tdata > > > > &Hs, const Parallel_Orbitals &pv, const int npol, hamilt::HContainer< TR > &HlocR, const RI::Cell_Nearest< int, int, 3, double, 3 > *const cell_nearest=nullptr)
Definition RI_2D_Comm.hpp:445
std::tuple< int, int, int > get_iat_iw_is_block(const UnitCell &ucell, const int &iwt)
Definition RI_2D_Comm.hpp:381
std::array< Tcell, Ndim > TC
Definition RI_2D_Comm.h:28
std::map< TA, std::map< TAC, T > > comm_map2_first(const MPI_Comm &mpi_comm, const std::map< TA, std::map< TAC, T > > &Ds_in, const std::set< TA > &s0, const std::set< TA > &s1)
Definition RI_2D_Comm.hpp:495
void add_Hexx(const UnitCell &ucell, const K_Vectors &kv, const int ik, const double alpha, const std::vector< std::map< TA, std::map< TAC, RI::Tensor< Tdata > > > > &Hs, const Parallel_Orbitals &pv, TK *hk)
Definition RI_2D_Comm.hpp:267
int get_iwt(const UnitCell &ucell, const int iat, const int iw_b, const int is_b)
Definition RI_2D_Comm.hpp:423
void add_datas(std::map< Tkey, Tvalue > &&data_local, std::map< Tkey, Tvalue > &data_recv)
Definition RI_2D_Comm.hpp:546
std::array< int, 3 > get_Born_vonKarmen_period(const K_Vectors &kv)
Definition RI_Util.hpp:16
std::vector< std::array< Tcell, Ndim > > get_Born_von_Karmen_cells(const std::array< Tcell, Ndim > &Born_von_Karman_period)
Definition RI_Util.hpp:34
ModuleBase::Vector3< Tcell > array3_to_Vector3(const std::array< Tcell, 3 > &v)
Definition RI_Util.h:38
Parameter PARAM
Definition parameter.cpp:3
std::array< int, 3 > TC
Definition ri_cv_io_test.cpp:9
std::string ks_solver
xiaohui add 2013-09-01
Definition input_parameter.h:77
int nspin
LDA ; LSDA ; non-linear spin.
Definition input_parameter.h:88