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>
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)
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]);
38template<
typename Tdata,
typename Tmatrix>
41 const std::vector<const Tmatrix*>&mks_2D,
45-> std::vector<std::map<TA,std::map<TAC,RI::Tensor<Tdata>>>>
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);
58template<
typename Tdata,
typename Tmatrix>
60 const std::vector<const Tmatrix*>& mks_2D,
63-> std::vector<std::map<TA, std::map<TAC, RI::Tensor<Tdata>>>>
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);
70 const TC cell = {0, 0, 0};
72 std::vector<std::map<TA, std::map<TAC, RI::Tensor<Tdata>>>> mRs_a2D(nspin);
76 for (
int is_b = 0; is_b < nspin; ++is_b)
77 for (
int iat0 = 0; iat0 < ucell.nat; ++iat0)
80 std::vector<omp_lock_t> locks(ucell.nat);
85 for (
int is_k = 0; is_k < nspin_k.at(nspin); ++is_k)
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);
94 #pragma omp parallel for schedule(dynamic)
96 for (
int iwt0_2D = 0; iwt0_2D != mR_2D.shape[0]; ++iwt0_2D)
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;
103 const int it0 = ucell.iat2it[iat0];
104 for (
int iwt1_2D = 0; iwt1_2D != mR_2D.shape[1]; ++iwt1_2D)
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;
111 const int it1 = ucell.iat2it[iat1];
115 omp_set_lock(&locks[iat0]);
117 RI::Tensor<Tdata>& mR_a2D = mRs_a2D[is_b][iat0][{iat1, cell}];
120 mR_a2D = RI::Tensor<Tdata>(
121 {
static_cast<size_t>(ucell.atoms[it0].nw),
122 static_cast<size_t>(ucell.atoms[it1].nw)});
124 mR_a2D(iw0_b, iw1_b) = mR_2D(iwt0_2D, iwt1_2D);
126 omp_unset_lock(&locks[iat0]);
133 for (
auto& l : locks)
134 omp_destroy_lock(&l);
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();)
140 if (it->second.empty())
141 it = mRs_a2D[is_b].erase(it);
151template<
typename Tdata,
typename Tmatrix>
154 const std::vector<const Tmatrix*>& mks_2D,
158-> std::vector<std::map<TA, std::map<TAC, RI::Tensor<Tdata>>>>
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);
167 std::vector<std::map<TA, std::map<TAC, RI::Tensor<Tdata>>>> mRs_a2D(nspin);
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)
177 #pragma omp for schedule(dynamic)
178 for (
size_t icell = 0; icell < cells.size(); ++icell)
180 const TC& cell = cells[icell];
181 RI::Tensor<Tdata> mR_2D;
183 for (
const int ik : ik_list)
185 auto set_mR_2D = [&mR_2D](
auto&& mk_frac)
188 { mR_2D = RI::Global_Func::convert<Tdata>(mk_frac); }
190 { mR_2D = mR_2D + RI::Global_Func::convert<Tdata>(mk_frac); }
192 using Tdata_m =
typename Tmatrix::value_type;
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(
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))); }
202 { set_mR_2D(mk_2D * frac); }
206 for (
auto& isym_kvd : kv.kstars[ik % ik_list.size()])
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(
212 set_mR_2D(mk_2D * frac);
217 for(
int iwt0_2D=0; iwt0_2D!=mR_2D.shape[0]; ++iwt0_2D)
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;
224 const int it0 = ucell.iat2it[iat0];
225 for(
int iwt1_2D=0; iwt1_2D!=mR_2D.shape[1]; ++iwt1_2D)
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;
232 const int it1 = ucell.iat2it[iat1];
235 RI::Tensor<Tdata>& mR_a2D = mRs_a2D_thread[is_b][iat0][{iat1, cell}];
238 mR_a2D = RI::Tensor<Tdata>(
239 {
static_cast<size_t>(ucell.atoms[it0].nw),
240 static_cast<size_t>(ucell.atoms[it1].nw)});
242 mR_a2D(iw0_b, iw1_b) = mR_2D(iwt0_2D, iwt1_2D);
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)
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);
266template<
typename Tdata,
typename TK>
272 const std::vector<std::map<
TA,std::map<
TAC,RI::Tensor<Tdata>>>> &Hs,
279 const std::map<int, std::vector<int>> is_list = {{1,{0}}, {2,{kv.
isk[ik]}}, {4,{0,1,2,3}}};
284 for(
const auto &Hs_tmpA : Hs[is_b])
286 const TA &iat0 = Hs_tmpA.first;
287 for(
const auto &Hs_tmpB : Hs_tmpA.second)
289 const TA &iat1 = Hs_tmpB.first.first;
290 const TC &cell1 = Hs_tmpB.first.second;
291 const std::complex<double> frac = alpha
293 const RI::Tensor<Tdata> &H = Hs_tmpB.second;
294 for(
size_t iw0_b=0; iw0_b<H.shape[0]; ++iw0_b)
300 for(
size_t iw1_b=0; iw1_b<H.shape[1]; ++iw1_b)
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);
315template <
typename Tdata,
typename TK>
321 const std::vector<std::map<
TA, std::map<
TAC, RI::Tensor<Tdata>>>>& Hs,
329 const std::map<int, std::vector<int>> is_list = {{1, {0}}, {2, {kv.
isk[ik]}}, {4, {0, 1, 2, 3}}};
335 for (
const auto& Hs_tmpA : Hs[is_b])
337 const TA& iat0 = Hs_tmpA.first;
338 for (
const auto& Hs_tmpB : Hs_tmpA.second)
340 const TA& iat1 = Hs_tmpB.first.first;
341 const TC& cell1 = Hs_tmpB.first.second;
344 const double arg_td = At * dtau * ucell.
lat0;
346 const std::complex<double> frac
351 const RI::Tensor<Tdata>& H = Hs_tmpB.second;
352 for (
size_t iw0_b = 0; iw0_b < H.shape[0]; ++iw0_b)
359 for (
size_t iw1_b = 0; iw1_b < H.shape[1]; ++iw1_b)
368 RI::Global_Func::convert<TK>(H(iw0_b, iw1_b))
369 * RI::Global_Func::convert<TK>(frac),
380std::tuple<int,int,int>
383 const int iat = ucell.
iwt2iat[iwt];
384 const int iw = ucell.
iwt2iw[iwt];
388 return std::make_tuple(iat, iw, 0);
390 return std::make_tuple(iat, iw/2, iw%2);
392 throw std::invalid_argument(std::string(__FILE__)+
" line "+std::to_string(__LINE__));
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__));
413 return std::make_tuple(0, 0);
415 return std::make_tuple(is_b/2, is_b%2);
417 throw std::invalid_argument(std::string(__FILE__)+
" line "+std::to_string(__LINE__));
428 const int it = ucell.
iat2it[iat];
429 const int ia = ucell.
iat2ia[iat];
436 iw = iw_b*2+is_b;
break;
438 throw std::invalid_argument(std::string(__FILE__)+
" line "+std::to_string(__LINE__));
444template<
typename Tdata,
typename TR>
446 const int current_spin,
448 const std::vector<std::map<
TA, std::map<
TAC, RI::Tensor<Tdata>>>>& Hs,
452 const RI::Cell_Nearest<int, int, 3, double, 3>*
const cell_nearest)
456 const std::map<int, std::vector<int>> is_list = { {1,{0}}, {2,{current_spin}}, {4,{0,1,2,3}} };
459 int is0_b = 0, is1_b = 0;
461 for (
const auto& Hs_tmpA : Hs[is_hs])
463 const TA& iat0 = Hs_tmpA.first;
464 for (
const auto& Hs_tmpB : Hs_tmpA.second)
466 const TA& iat1 = Hs_tmpB.first.first;
467 const TC& cell = Hs_tmpB.first.second;
470 cell_nearest->get_cell_nearest_discrete(iat0, iat1, cell)
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)
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)
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)));
494template <
typename TA,
typename TAC,
typename T>
496 const std::map<
TA, std::map<TAC, T>>& Ds_in,
497 const std::set<TA>& s0,
498 const std::set<TA>& s1)
500 RI::Communicate_Map_Period::Judge_Map2_First<TA> judge;
503 return comm_map2(mpi_comm, Ds_in, judge);
506template <
typename TA,
typename TAC,
typename T,
typename Tjudge>
508 const std::map<
TA, std::map<TAC, T>>& Ds_in,
511 Comm::Comm_Assemble<std::tuple<TA, TAC>,
T, std::map<TA, std::map<TAC, T>>, Tjudge, std::map<TA, std::map<TAC, T>>>
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>;
521 std::map<TA, std::map<TAC, T>> Ds_out;
522 com.communicate(Ds_in, judge, Ds_out);
526template <
typename Tkey,
typename Tvalue>
529 using namespace RI::Array_Operator;
530 auto ptr = data.find(key);
531 if (ptr == data.end())
532 data[key] = std::move(value);
534 ptr->second = ptr->second + std::move(value);
537template <
typename Tkey0,
typename Tkey1,
typename Tvalue>
540 std::map<Tkey0, std::map<Tkey1, Tvalue>>& data)
542 set_value_add(std::move(std::get<1>(key)), std::move(value), data[std::get<0>(key)]);
545template <
typename Tkey,
typename Tvalue>
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();)
553 const Tkey& key_local = ptr_local->first;
554 const Tkey& key_recv = ptr_recv->first;
555 if (key_local == key_recv)
557 ptr_recv->second = ptr_recv->second + std::move(ptr_local->second);
561 else if (key_local < key_recv)
563 ptr_recv = data_recv.emplace_hint(ptr_recv, key_local, std::move(ptr_local->second));
571 for (; ptr_local != data_local.end(); ++ptr_local)
573 ptr_recv = data_recv.emplace_hint(ptr_recv, ptr_local->first, std::move(ptr_local->second));
577template <
typename Tkey0,
typename Tkey1,
typename Tvalue>
579 std::map<Tkey0, std::map<Tkey1, Tvalue>>& data_recv)
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();)
585 const Tkey0& key_local = ptr_local->first;
586 const Tkey0& key_recv = ptr_recv->first;
587 if (key_local == key_recv)
589 add_datas(std::move(ptr_local->second), ptr_recv->second);
593 else if (key_local < key_recv)
595 ptr_recv = data_recv.emplace_hint(ptr_recv, key_local, std::move(ptr_local->second));
603 for (; ptr_local != data_local.end(); ++ptr_local)
605 ptr_recv = data_recv.emplace_hint(ptr_recv, ptr_local->first, std::move(ptr_local->second));
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
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
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