13#include "../../source_basis/module_ao/element_basis_index-ORB.h"
14#include "../../source_base/tool_title.h"
15#include "../../source_base/timer.h"
16#include "../../source_pw/module_pwdft/global.h"
17#include <RI/global/Global_Func-1.h>
20template<
typename Tdata>
23 pthread_rwlock_init(&rwlock_Vw,NULL);
24 pthread_rwlock_init(&rwlock_Cw,NULL);
25 pthread_rwlock_init(&rwlock_dVw,NULL);
26 pthread_rwlock_init(&rwlock_dCw,NULL);
29template<
typename Tdata>
32 pthread_rwlock_destroy(&rwlock_Vw);
33 pthread_rwlock_destroy(&rwlock_Cw);
34 pthread_rwlock_destroy(&rwlock_dVw);
35 pthread_rwlock_destroy(&rwlock_dCw);
39template<
typename Tdata>
43 const std::vector<std::vector<std::vector<Numerical_Orbital_Lm>>> &lcaos_in,
44 const std::vector<std::vector<std::vector<Numerical_Orbital_Lm>>> &abfs_in,
45 const std::vector<std::vector<std::vector<Numerical_Orbital_Lm>>> &abfs_ccp_in,
46 const double &kmesh_times,
47 std::shared_ptr<ORB_gaunt_table> MGT,
53 this->lcaos = lcaos_in;
55 this->abfs_ccp = abfs_ccp_in;
68 this->m_abfs_abfs.MGT = this->m_abfslcaos_lcaos.MGT = MGT;
69 this->m_abfs_abfs.init(
70 this->abfs_ccp, this->abfs,
71 ucell, orb, kmesh_times);
73 this->m_abfslcaos_lcaos.init(
74 this->abfs_ccp, this->lcaos, this->lcaos,
75 ucell, orb, kmesh_times);
77 this->m_abfs_abfs.init_radial_table();
79 this->m_abfslcaos_lcaos.init_radial_table();
85template <
typename Tdata>
87 return this->abfs_ccp_rcut[it0] + this->lcaos_rcut[it1];
90template <
typename Tdata>
92 return std::min(this->abfs_ccp_rcut[it0], this->lcaos_rcut[it0])
93 + this->lcaos_rcut[it1];
96template<
typename Tdata>
template<
typename Tresult>
99 const std::vector<TA>& list_A0,
100 const std::vector<TAC>& list_A1,
101 const std::map<std::string, bool>& flags,
104-> std::map<TA,std::map<TAC,Tresult>>
109 std::map<TA,std::map<TAC,Tresult>> Datas;
111 for(
size_t i0=0; i0<list_A0.size(); ++i0)
113 #pragma omp for schedule(dynamic) nowait
114 for(
size_t i1=0; i1<list_A1.size(); ++i1)
116 const TA iat0 = list_A0[i0];
117 const TA iat1 = list_A1[i1].first;
118 const TC &cell1 = list_A1[i1].second;
119 const int it0 = ucell.iat2it[iat0];
120 const int ia0 = ucell.iat2ia[iat0];
121 const int it1 = ucell.iat2it[iat1];
122 const int ia1 = ucell.iat2ia[iat1];
126 = std::min(func_cal_Rcut(it0, it1), func_cal_Rcut(it1, it0));
128 if( R_delta.
norm()*ucell.lat0 < Rcut )
130 const Tresult
Data = func_DPcal_data(it0, it1, R_delta, flags);
133 #pragma omp critical(LRI_CV_cal_datas)
134 Datas[list_A0[i0]][list_A1[i1]] =
Data;
144template<
typename Tdata>
147 const std::vector<TA> &list_A0,
148 const std::vector<TAC> &list_A1,
149 const std::map<std::string,bool> &flags)
150-> std::map<TA,std::map<TAC,RI::Tensor<Tdata>>>
154 func_DPcal_V = std::bind(
156 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
159 std::placeholders::_1,
160 std::placeholders::_2);
162 return this->cal_datas(ucell,list_A0, list_A1, flags, func_cal_Rcut, func_DPcal_V);
165template<
typename Tdata>
168 const std::vector<TA> &list_A0,
169 const std::vector<TAC> &list_A1,
170 const std::map<std::string,bool> &flags)
171-> std::map<TA, std::map<TAC, std::array<RI::Tensor<Tdata>, 3>>>
175 func_DPcal_dV = std::bind(
177 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
181 std::placeholders::_1,
182 std::placeholders::_2);
184 return this->cal_datas(ucell,list_A0, list_A1, flags, func_cal_Rcut, func_DPcal_dV);
187template<
typename Tdata>
190 const std::vector<TA> &list_A0,
191 const std::vector<TAC> &list_A1,
192 const std::map<std::string,bool> &flags)
194 std::map<TA, std::map<TAC, RI::Tensor<Tdata>>>,
195 std::map<TA, std::map<TAC, std::array<RI::Tensor<Tdata>, 3>>>>
199 func_DPcal_C_dC = std::bind(
201 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
204 std::placeholders::_1,
205 std::placeholders::_2);
207 std::map<TA,std::map<TAC, std::pair<RI::Tensor<Tdata>, std::array<RI::Tensor<Tdata>,3>>>>
208 Cs_dCs_tmp = this->cal_datas(ucell,list_A0, list_A1, flags, func_cal_Rcut, func_DPcal_C_dC);
210 std::map<TA, std::map<TAC, RI::Tensor<Tdata>>> Cs;
211 std::map<TA, std::map<TAC, std::array<RI::Tensor<Tdata>, 3>>> dCs;
212 for (
auto& Cs_dCs_A: Cs_dCs_tmp)
213 for (
auto& Cs_dCs_B: Cs_dCs_A.second) {
214 Cs[Cs_dCs_A.first][Cs_dCs_B.first]
215 = std::move(std::get<0>(Cs_dCs_B.second));
216 if (flags.at(
"cal_dC"))
217 dCs[Cs_dCs_A.first][Cs_dCs_B.first]
218 = std::move(std::get<1>(Cs_dCs_B.second));
220 return std::make_pair(Cs, dCs);
224template<
typename Tdata>
template<
typename To11,
typename Tfunc>
229 const bool &flag_writable_o11ws,
230 pthread_rwlock_t &rwlock_o11,
232 const Tfunc &func_cal_o11)
235 pthread_rwlock_rdlock(&rwlock_o11);
236 const To11 o11_read = RI::Global_Func::find(o11ws, it0, it1, R);
237 pthread_rwlock_unlock(&rwlock_o11);
245 pthread_rwlock_rdlock(&rwlock_o11);
246 const To11 o11_transform_read = RI::Global_Func::find(o11ws, it1, it0, Rm);
247 pthread_rwlock_unlock(&rwlock_o11);
252 if(flag_writable_o11ws)
254 pthread_rwlock_wrlock(&rwlock_o11);
255 o11ws[it0][it1][R] = o11;
256 pthread_rwlock_unlock(&rwlock_o11);
262 const To11 o11 = func_cal_o11(
264 this->index_abfs, this->index_abfs,
266 if(flag_writable_o11ws)
268 pthread_rwlock_wrlock(&rwlock_o11);
269 o11ws[it0][it1][R] = o11;
270 pthread_rwlock_unlock(&rwlock_o11);
277template<
typename Tdata>
283 const std::map<std::string,bool> &flags)
285 const auto cal_overlap_matrix = std::bind(
286 &Matrix_Orbs11::cal_overlap_matrix<Tdata>,
288 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7);
289 return this->DPcal_o11(it0, it1, R, flags.at(
"writable_Vws"), this->rwlock_Vw, this->Vws, cal_overlap_matrix);
292template<
typename Tdata>
293std::array<RI::Tensor<Tdata>, 3>
298 const std::map<std::string,bool> &flags)
303 const size_t size = this->index_abfs[it0].count_size;
304 const std::array<RI::Tensor<Tdata>, 3> dV = { RI::Tensor<Tdata>({size,size}), RI::Tensor<Tdata>({size,size}), RI::Tensor<Tdata>({size,size}) };
305 if(flags.at(
"writable_dVws"))
307 pthread_rwlock_wrlock(&this->rwlock_dVw);
308 this->dVws[it0][it1][R] = dV;
309 pthread_rwlock_unlock(&this->rwlock_dVw);
314 const auto cal_grad_overlap_matrix = std::bind(
315 &Matrix_Orbs11::cal_grad_overlap_matrix<Tdata>,
317 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7);
318 return this->DPcal_o11(it0, it1, R, flags.at(
"writable_dVws"), this->rwlock_dVw, this->dVws, cal_grad_overlap_matrix);
322template<
typename Tdata>
323std::pair<RI::Tensor<Tdata>, std::array<RI::Tensor<Tdata>,3>>
328 const std::map<std::string,bool> &flags)
333 pthread_rwlock_rdlock(&this->rwlock_Cw);
334 const RI::Tensor<Tdata> C_read = RI::Global_Func::find(this->Cws, it0, it1, R);
335 pthread_rwlock_unlock(&this->rwlock_Cw);
336 pthread_rwlock_rdlock(&this->rwlock_dCw);
337 const std::array<RI::Tensor<Tdata>,3> dC_read = RI::Global_Func::find(this->dCws, it0, it1, R);
338 pthread_rwlock_unlock(&this->rwlock_dCw);
341 if(!C_read.empty() && flag_finish_dC)
343 return std::make_pair(C_read, dC_read);
349 const RI::Tensor<Tdata>
350 A = this->m_abfslcaos_lcaos.template cal_overlap_matrix<Tdata>(
351 it0, it1, {0,0,0}, {0,0,0},
352 this->index_abfs, this->index_lcaos, this->index_lcaos,
354 const RI::Tensor<Tdata> V = this->DPcal_V(it0, it0, {0, 0, 0}, {{
"writable_Vws",
true}});
361 const RI::Tensor<Tdata> C = RI::Global_Func::convert<Tdata>(0.5) *
LRI_CV_Tools::mul1(L,A);
362 if(flags.at(
"writable_Cws"))
364 pthread_rwlock_wrlock(&this->rwlock_Cw);
365 this->Cws[it0][it1][{0,0,0}] = C;
366 pthread_rwlock_unlock(&this->rwlock_Cw);
371 return std::make_pair(C, dC_read);
375 const RI::Shape_Vector sizes = {this->index_abfs[it0].count_size,
376 this->index_lcaos[it0].count_size,
377 this->index_lcaos[it0].count_size};
378 const std::array<RI::Tensor<Tdata>,3>
379 dC({RI::Tensor<Tdata>({sizes}), RI::Tensor<Tdata>({sizes}), RI::Tensor<Tdata>({sizes})});
380 if(flags.at(
"writable_dCws"))
382 pthread_rwlock_wrlock(&this->rwlock_dCw);
383 this->dCws[it0][it1][{0,0,0}] = dC;
384 pthread_rwlock_unlock(&this->rwlock_dCw);
386 return std::make_pair(C, dC);
391 const std::vector<RI::Tensor<Tdata>>
392 A = {this->m_abfslcaos_lcaos.template cal_overlap_matrix<Tdata>(
393 it0, it1, {0,0,0}, R,
394 this->index_abfs, this->index_lcaos, this->index_lcaos,
396 this->m_abfslcaos_lcaos.template cal_overlap_matrix<Tdata>(
397 it1, it0, {0,0,0}, Rm,
398 this->index_abfs, this->index_lcaos, this->index_lcaos,
401 const std::vector<std::vector<RI::Tensor<Tdata>>>
402 V = {{DPcal_V(it0, it0, {0,0,0}, {{
"writable_Vws",
true}}),
403 DPcal_V(it0, it1, R, flags)},
404 {DPcal_V(it1, it0, Rm, flags),
405 DPcal_V(it1, it1, {0,0,0}, {{
"writable_Vws",
true}})}};
407 std::vector<std::vector<RI::Tensor<Tdata>>> L;
414 if(flags.at(
"writable_Cws"))
416 pthread_rwlock_wrlock(&this->rwlock_Cw);
417 this->Cws[it0][it1][R] = C[0];
419 pthread_rwlock_unlock(&this->rwlock_Cw);
424 return std::make_pair(C[0], dC_read);
428 const std::vector<std::array<RI::Tensor<Tdata>,3>>
429 dA = {this->m_abfslcaos_lcaos.template cal_grad_overlap_matrix<Tdata>(
430 it0, it1, {0,0,0}, R,
431 this->index_abfs, this->index_lcaos, this->index_lcaos,
434 this->m_abfslcaos_lcaos.template cal_grad_overlap_matrix<Tdata>(
435 it1, it0, {0,0,0}, Rm,
436 this->index_abfs, this->index_lcaos, this->index_lcaos,
439 const std::array<RI::Tensor<Tdata>,3> dV_01 = DPcal_dV(it0, it1, R, flags);
442 std::array<std::vector<RI::Tensor<Tdata>>,3>
447 std::vector<std::array<RI::Tensor<Tdata>,3>>{
450 const std::vector<std::array<RI::Tensor<Tdata>,3>>
452 if(flags.at(
"writable_dCws"))
454 pthread_rwlock_wrlock(&this->rwlock_dCw);
455 this->dCws[it0][it1][R] = dC[0];
457 pthread_rwlock_unlock(&this->rwlock_dCw);
459 return std::make_pair(C[0], dC[0]);
Definition abfs-vector3_order.h:16
static std::vector< double > get_Rcut(const std::vector< std::vector< std::vector< Numerical_Orbital_Lm > > > &orb_in)
Definition exx_abfs-construct_orbs.cpp:525
Definition Inverse_Matrix.h:15
std::array< RI::Tensor< Tdata >, 3 > DPcal_dV(const int it0, const int it1, const Abfs::Vector3_Order< double > &R, const std::map< std::string, bool > &flags)
Definition LRI_CV.hpp:294
std::pair< RI::Tensor< Tdata >, std::array< RI::Tensor< Tdata >, 3 > > DPcal_C_dC(const int it0, const int it1, const Abfs::Vector3_Order< double > &R, const std::map< std::string, bool > &flags)
Definition LRI_CV.hpp:324
RI::Tensor< Tdata > DPcal_V(const int it0, const int it1, const Abfs::Vector3_Order< double > &R, const std::map< std::string, bool > &flags)
Definition LRI_CV.hpp:279
std::map< TA, std::map< TAC, RI::Tensor< Tdata > > > cal_Vs(const UnitCell &ucell, const std::vector< TA > &list_A0, const std::vector< TAC > &list_A1, const std::map< std::string, bool > &flags)
Definition LRI_CV.hpp:145
std::function< double(const int it0, const int it1)> T_func_cal_Rcut
Definition LRI_CV.h:96
~LRI_CV()
Definition LRI_CV.hpp:30
std::map< TA, std::map< TAC, Tresult > > cal_datas(const UnitCell &ucell, const std::vector< TA > &list_A0, const std::vector< TAC > &list_A1, const std::map< std::string, bool > &flags, const T_func_cal_Rcut &func_cal_Rcut, const T_func_DPcal_data< Tresult > &func_DPcal_data)
std::function< Tresult(const int it0, const int it1, const Abfs::Vector3_Order< double > &R, const std::map< std::string, bool > &flags)> T_func_DPcal_data
Definition LRI_CV.h:95
LRI_CV()
Definition LRI_CV.hpp:21
int TA
Definition LRI_CV.h:27
std::pair< std::map< TA, std::map< TAC, RI::Tensor< Tdata > > >, std::map< TA, std::map< TAC, std::array< RI::Tensor< Tdata >, 3 > > > > cal_Cs_dCs(const UnitCell &ucell, const std::vector< TA > &list_A0, const std::vector< TAC > &list_A1, const std::map< std::string, bool > &flags)
Definition LRI_CV.hpp:188
void set_orbitals(const UnitCell &ucell, const LCAO_Orbitals &orb, const std::vector< std::vector< std::vector< Numerical_Orbital_Lm > > > &lcaos_in, const std::vector< std::vector< std::vector< Numerical_Orbital_Lm > > > &abfs_in, const std::vector< std::vector< std::vector< Numerical_Orbital_Lm > > > &abfs_ccp_in, const double &kmesh_times, std::shared_ptr< ORB_gaunt_table > MGT, const bool &init_C)
Definition LRI_CV.hpp:40
std::map< TA, std::map< TAC, std::array< RI::Tensor< Tdata >, 3 > > > cal_dVs(const UnitCell &ucell, const std::vector< TA > &list_A0, const std::vector< TAC > &list_A1, const std::map< std::string, bool > &flags)
Definition LRI_CV.hpp:166
std::array< int, 3 > TC
Definition LRI_CV.h:28
double cal_C_Rcut(const int it0, const int it1)
Definition LRI_CV.hpp:91
double cal_V_Rcut(const int it0, const int it1)
Definition LRI_CV.hpp:86
To11 DPcal_o11(const int it0, const int it1, const Abfs::Vector3_Order< double > &R, const bool &flag_writable_o11ws, pthread_rwlock_t &rwlock_o11, std::map< int, std::map< int, std::map< Abfs::Vector3_Order< double >, To11 > > > &o11ws, const Tfunc &func_cal_o11)
Definition LRI_CV.hpp:225
3 elements vector
Definition vector3.h:22
T norm(void) const
Get the norm of a Vector3.
Definition vector3.h:187
static void tick(const std::string &class_name_in, const std::string &name_in)
Use twice at a time: the first time, set start_flag to false; the second time, calculate the time dur...
Definition timer.cpp:62
Exx_Info exx_info
Definition test_xc.cpp:29
Range construct_range(const LCAO_Orbitals &orb)
Definition element_basis_index-ORB.cpp:10
IndexLNM construct_index(const Range &range)
Definition element_basis_index.cpp:12
std::vector< std::vector< NM > > Range
Definition element_basis_index.h:41
void TITLE(const std::string &class_name, const std::string &function_name, const bool disable)
Definition tool_title.cpp:18
ModuleBase::Vector3< Tcell > array3_to_Vector3(const std::array< Tcell, 3 > &v)
Definition RI_Util.h:38