1#ifndef EXX_ROTATE_ABFS_HPP
2#define EXX_ROTATE_ABFS_HPP
11template <
typename Tdata>
17 this->multipole.resize(orb_in.size());
18 for (
size_t T = 0;
T != orb_in.size(); ++
T)
20 this->multipole[
T].resize(orb_in[
T].size());
21 for (
size_t L = 0; L != orb_in[
T].size(); ++L)
23 this->multipole[
T][L].resize(orb_in[
T][L].size());
24 for (
size_t N = 0;
N != orb_in[
T][L].size(); ++
N)
27 const int nr = orb_lm.
getNr();
28 double* integrated_func =
new double[nr];
29 for (
size_t ir = 0; ir != nr; ++ir)
30 integrated_func[ir] = orb_lm.
getPsi(ir) * std::pow(orb_lm.
getRadial(ir), 2 + L) / (2 * L + 1);
40template <
typename Tdata>
47 for (
int T = 0;
T != orb_in.size(); ++
T)
49 for (
int L = 0; L != orb_in[
T].size(); ++L)
51 for (
int N = 0;
N != orb_in[
T][L].size(); ++
N)
56 for (
int N2 = 0; N2 != orb_in[
T][L].size(); ++N2)
58 square += this->multipole[
T][L][N2] * this->multipole[
T][L][N2];
60 double norm = std::sqrt(square);
64 for (
int N2 = 0; N2 != orb_in[
T][L].size(); ++N2)
65 orb_lm_mod += orb_in[
T][L][N2] * this->multipole[
T][L][N2] /
norm;
69 for (
int N2 = 0; N2 != orb_in[
T][L].size(); ++N2)
73 orb_lm_mod += (1.0 - this->multipole[
T][L][
N] * this->multipole[
T][L][N2] / square)
79 += (-this->multipole[
T][L][
N] * this->multipole[
T][L][N2] / square) * orb_in[
T][L][N2];
83 orb_lm_old = orb_lm_mod;
87 this->multipole[
T][L][
N] =
norm;
88 std::cout <<
"Atom type " <<
T <<
", L " << L <<
", N " <<
N
89 <<
", multipole after rotation: " << this->multipole[
T][L][
N] << std::endl;
93 this->multipole[
T][L][
N] = 0.0;
102template <
typename Tdata>
106 for (
int i = l;
i > 1;
i -= 2)
113template <
typename Tdata>
122 return n * this->factorial(n - 1);
131template <
typename Tdata>
135 for (
int i = 2;
i <= n; ++
i)
140template <
typename Tdata>
151template <
typename Tdata>
156 const std::vector<double>& rly,
158 const double distance)
161 const double tiny2 = 1e-10;
162 const int L = l1 + l2;
167 for (
int M = -L; M <= L; ++M)
171 const double ylm_solid = rly.at(idxL);
172 const double ylm_real = (distance > tiny2) ? ylm_solid / pow(distance, l1 + l2) : ylm_solid;
174 if (std::abs(C) > 1e-14)
183template <
typename Tdata>
186 const std::vector<std::vector<std::vector<Numerical_Orbital_Lm>>>& orb_in,
187 const std::pair<std::vector<TA>, std::vector<std::vector<std::pair<
TA, std::array<Tcell, Ndim>>>>>& list_r,
188 const std::vector<double>& orb_cutoff,
191 std::map<
TA, std::map<
TAC, RI::Tensor<Tdata>>>& Vs_cut)
196 const double tiny1 = 1e-12;
203 for (
size_t T = 0;
T != orb_in.size(); ++
T)
205 Lmax = std::max(Lmax,
static_cast<int>(orb_in[
T].size()) - 1);
213 const auto list_A0 = list_r.first;
214 const auto list_A1 = list_r.second[0];
217 for (
size_t i0 = 0; i0 < list_A0.size(); ++i0)
219 const TA iat0 = list_A0[i0];
220 const int T1 = ucell.
iat2it[iat0];
221 const size_t I1 = ucell.
iat2ia[iat0];
222 const auto& tauA = ucell.
atoms[T1].
tau[I1];
223 const size_t sizeA = index[T1].count_size;
224 for (
size_t i1 = 0; i1 < list_A1.size(); ++i1)
226 const TA iat1 = list_A1[i1].first;
227 const int T2 = ucell.
iat2it[iat1];
228 const size_t I2 = ucell.
iat2ia[iat1];
229 const auto& tauB = ucell.
atoms[T2].
tau[I2];
230 const size_t sizeB = index[T2].count_size;
231 const auto R = list_A1[i1].second;
235 const double distance_true = (delta_R).
norm() * ucell.
lat0;
237 const double distance = (distance_true >= tiny1) ? distance_true : distance_true + tiny1;
239 double Rcut_lcao = orb_cutoff[T1] + orb_cutoff[T2];
242 if (distance < Rcut_lcao || distance >= Rcut_coul)
244 const auto JR = std::make_pair(iat1, R);
245 auto tmp_tensor = RI::Tensor<Tdata>({sizeA, sizeB});
246 for (
int L1 = 0; L1 != orb_in[T1].size(); ++L1)
248 for (
int L2 = 0; L2 != orb_in[T2].size(); ++L2)
250 std::vector<double> rly;
253 (delta_R * ucell.
lat0).x,
254 (delta_R * ucell.
lat0).y,
255 (delta_R * ucell.
lat0).z,
257 const double prefactor1 = std::pow(distance, L1 + L2 + 1);
258 for (
int M1 = -L1; M1 <= L1; ++M1)
260 const int index_M1 = M1 + L1;
261 for (
int M2 = -L2; M2 <= L2; ++M2)
263 const int index_M2 = M2 + L2;
264 const double prefactor = std::pow(-1, L2) * std::pow(
ModuleBase::TWO_PI, 1.5) / prefactor1;
265 const double clmlm = this->cal_cl1l2(L1, L2);
267 const double ylm = sum_triple_Y_YLM_real(L1, M1, L2, M2, rly, MGT0, distance);
275 for (
int N1 = 0; N1 != N1_max; ++N1)
277 for (
int N2 = 0; N2 != N2_max; ++N2)
279 double mom1 = this->multipole[T1][L1][N1];
280 const double mom2 = this->multipole[T2][L2][N2];
282 const size_t iA = index[T1][L1][N1][index_M1];
283 const size_t iB = index[T2][L2][N2][index_M2];
285 const double value = prefactor * mom1 * mom2 * clmlm * ylm;
316 const double width = 0.9;
318 double cutoff_factor = 1.0;
324 if (distance > 0.0 && width > 1.0)
327 cutoff_factor = 0.5 * std::erfc(std::log(distance / Rc) / std::log(width));
330 static int debug_count = 0;
331 if (debug_count < 10 && distance > Rc * 0.9 && distance < Rc * 1.2)
333 std::cout <<
"DEBUG: distance=" << distance <<
" Rc=" << Rc
334 <<
" cutoff_factor=" << cutoff_factor <<
" value=" << value
339 else if (distance <= 0.0)
347 cutoff_factor = (distance < Rc) ? 1.0 : 0.0;
354 tmp_tensor(iA, iB) = value * cutoff_factor;
380 Vws[T1][T2][delta_R] = tmp_tensor;
382 auto& target_inner = Vs_cut.at(iat0);
383 if (target_inner.find(JR) == target_inner.end())
385 target_inner.emplace(JR, tmp_tensor);
390 target_inner[JR] = tmp_tensor;
391 const auto J = JR.first;
392 const auto R = JR.second;
401template <
typename Tdata>
404 const std::vector<std::vector<std::vector<Numerical_Orbital_Lm>>>& orb_in,
405 const std::pair<std::vector<TA>, std::vector<std::vector<std::pair<
TA, std::array<Tcell, Ndim>>>>>& list_r,
406 const std::vector<double>& orb_cutoff,
409 std::map<
TA, std::map<
TAC, RI::Tensor<Tdata>>>& Vs_cut)
414 const double tiny1 = 1e-12;
418 const auto list_A0 = list_r.first;
419 const auto list_A1 = list_r.second[0];
423 for (
size_t i0 = 0; i0 < list_A0.size(); ++i0)
425 const TA iat0 = list_A0[i0];
426 const int T1 = ucell.
iat2it[iat0];
427 const size_t I1 = ucell.
iat2ia[iat0];
428 const auto& tauA = ucell.
atoms[T1].
tau[I1];
430 for (
size_t i1 = 0; i1 < list_A1.size(); ++i1)
432 const TA iat1 = list_A1[i1].first;
433 const int T2 = ucell.
iat2it[iat1];
434 const size_t I2 = ucell.
iat2ia[iat1];
435 const auto& tauB = ucell.
atoms[T2].
tau[I2];
436 const auto R = list_A1[i1].second;
441 const double distance_true = (delta_R).
norm() * ucell.
lat0;
442 const double distance = (distance_true >= tiny1) ? distance_true : distance_true + tiny1;
444 double Rcut_lcao = orb_cutoff[T1] + orb_cutoff[T2];
448 if (distance < Rcut_lcao || distance >= Rcut_coul)
452 if (Vws.find(T1) != Vws.end() && Vws[T1].find(T2) != Vws[T1].end())
454 auto& delta_R_map = Vws[T1][T2];
455 if (delta_R_map.find(delta_R) != delta_R_map.end())
457 RI::Tensor<Tdata>& tensor = delta_R_map[delta_R];
460 for (
int L1 = 0; L1 != orb_in[T1].size(); ++L1)
462 for (
int L2 = 0; L2 != orb_in[T2].size(); ++L2)
464 for (
int M1 = -L1; M1 <= L1; ++M1)
466 const int index_M1 = M1 + L1;
467 for (
int M2 = -L2; M2 <= L2; ++M2)
469 const int index_M2 = M2 + L2;
472 for (
int N1 = 1; N1 != orb_in[T1][L1].size(); ++N1)
474 const size_t iA = index[T1][L1][N1][index_M1];
475 for (
int N2 = 0; N2 != orb_in[T2][L2].size(); ++N2)
477 const size_t iB = index[T2][L2][N2][index_M2];
478 tensor(iA, iB) =
static_cast<Tdata
>(0);
481 for (
int N2 = 1; N2 != orb_in[T2][L2].size(); ++N2)
483 const size_t iB = index[T2][L2][N2][index_M2];
484 for (
int N1 = 0; N1 != orb_in[T1][L1].size(); ++N1)
486 const size_t iA = index[T1][L1][N1][index_M1];
487 tensor(iA, iB) =
static_cast<Tdata
>(0);
500 for (
auto& iat_inner_map : Vs_cut)
502 const TA iat0 = iat_inner_map.first;
503 const int T1 = ucell.
iat2it[iat0];
504 const size_t I1 = ucell.
iat2ia[iat0];
505 const auto& tauA = ucell.
atoms[T1].
tau[I1];
507 for (
auto& JR_tensor : iat_inner_map.second)
509 const TA iat1 = JR_tensor.first.first;
510 const int T2 = ucell.
iat2it[iat1];
511 const size_t I2 = ucell.
iat2ia[iat1];
512 const auto& tauB = ucell.
atoms[T2].
tau[I2];
513 const auto& R = JR_tensor.first.second;
518 const double distance_true = (delta_R).
norm() * ucell.
lat0;
519 const double distance = (distance_true >= tiny1) ? distance_true : distance_true + tiny1;
521 double Rcut_lcao = orb_cutoff[T1] + orb_cutoff[T2];
525 if (distance < Rcut_lcao || distance >= Rcut_coul)
528 RI::Tensor<Tdata>& tensor = JR_tensor.second;
531 for (
int L1 = 0; L1 != orb_in[T1].size(); ++L1)
533 for (
int L2 = 0; L2 != orb_in[T2].size(); ++L2)
535 for (
int M1 = -L1; M1 <= L1; ++M1)
537 const int index_M1 = M1 + L1;
538 for (
int M2 = -L2; M2 <= L2; ++M2)
540 const int index_M2 = M2 + L2;
543 for (
int N1 = 1; N1 != orb_in[T1][L1].size(); ++N1)
545 const size_t iA = index[T1][L1][N1][index_M1];
546 for (
int N2 = 0; N2 != orb_in[T2][L2].size(); ++N2)
548 const size_t iB = index[T2][L2][N2][index_M2];
549 tensor(iA, iB) =
static_cast<Tdata
>(0);
552 for (
int N2 = 1; N2 != orb_in[T2][L2].size(); ++N2)
554 const size_t iB = index[T2][L2][N2][index_M2];
555 for (
int N1 = 0; N1 != orb_in[T1][L1].size(); ++N1)
557 const size_t iA = index[T1][L1][N1][index_M1];
558 tensor(iA, iB) =
static_cast<Tdata
>(0);
571template <
typename Tdata>
575 auto format = std::scientific;
578 int nr = olp.shape[0];
579 int nc = olp.shape[1];
580 size_t nnz = nr * nc;
581 fs <<
"%%MatrixMarket matrix coordinate complex general" << std::endl;
582 fs <<
"%" << std::endl;
584 fs << nr <<
" " << nc <<
" " << nnz << std::endl;
586 for (
int i = 0;
i < nr;
i++)
588 for (
int j = 0; j < nc; j++)
592 fs <<
i + 1 <<
" " << j + 1 <<
" " << std::showpoint << format << std::setprecision(prec) << v <<
"\n";
599template <
typename Tdata>
601 RI::Tensor<std::complex<double>>& olp,
605 auto format = std::scientific;
608 int nr = olp.shape[0];
609 int nc = olp.shape[1];
610 size_t nnz = nr * nc;
611 fs <<
"%%MatrixMarket matrix coordinate complex general" << std::endl;
612 fs <<
"%" << std::endl;
614 fs << nr <<
" " << nc <<
" " << nnz << std::endl;
616 for (
int j = 0; j < nc; j++)
618 for (
int i = 0;
i < nr;
i++)
622 fs <<
i + 1 <<
" " << j + 1 <<
" " << std::showpoint << format << std::setprecision(prec) << v.real()
623 <<
" " << std::showpoint << format << std::setprecision(prec) << v.imag() <<
"\n";
const std::complex< double > i
Definition cal_pLpR.cpp:46
std::vector< ModuleBase::Vector3< double > > tau
Definition atom_spec.h:35
std::map< int, std::map< int, std::map< Abfs::Vector3_Order< double >, RI::Tensor< Tdata > > > > Vws
Definition LRI_CV.h:77
double cal_V_Rcut(const int it0, const int it1)
Definition LRI_CV.hpp:86
static void Simpson_Integral(const int mesh, const double *const func, const double *const rab, double &asum)
simpson integral.
Definition math_integral.cpp:66
static void rl_sph_harm(const int Lmax, const double x, const double y, const double z, std::vector< double > &rly)
Get the ylm real object (used in getting overlap)
Definition ylm.cpp:632
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
void out_pure_ri_tensor(const std::string fn, RI::Tensor< std::complex< double > > &olp, const double threshold)
Definition exx_rotate_abfs.hpp:600
double ln_factorial(int n) const
Definition exx_rotate_abfs.hpp:132
double sum_triple_Y_YLM_real(int l1, int m1, int l2, int m2, const std::vector< double > &rly, const ORB_gaunt_table &MGT, const double distance)
Definition exx_rotate_abfs.hpp:152
double dfact(const int &l) const
double factorial
Definition exx_rotate_abfs.hpp:103
std::pair< TA, TC > TAC
Definition exx_rotate_abfs.h:26
double cal_cl1l2(int l1, int l2) const
Definition exx_rotate_abfs.hpp:141
int TA
Definition exx_rotate_abfs.h:21
void cal_VR(const UnitCell &ucell, const std::vector< std::vector< std::vector< Numerical_Orbital_Lm > > > &orb_in, const std::pair< std::vector< TA >, std::vector< std::vector< std::pair< TA, std::array< Tcell, Ndim > > > > > &list_r, const std::vector< double > &orb_cutoff, const double Rc, LRI_CV< Tdata > &cv, std::map< TA, std::map< TAC, RI::Tensor< Tdata > > > &Vs_cut)
Definition exx_rotate_abfs.hpp:184
void rotate_abfs(std::vector< std::vector< std::vector< Numerical_Orbital_Lm > > > &orb_in)
Definition exx_rotate_abfs.hpp:41
void discard0_VR(const UnitCell &ucell, const std::vector< std::vector< std::vector< Numerical_Orbital_Lm > > > &orb_in, const std::pair< std::vector< TA >, std::vector< std::vector< std::pair< TA, std::array< Tcell, Ndim > > > > > &list_r, const std::vector< double > &orb_cutoff, const double Rc, LRI_CV< Tdata > &cv, std::map< TA, std::map< TAC, RI::Tensor< Tdata > > > &Vs_cut)
Definition exx_rotate_abfs.hpp:402
void cal_multipole(const std::vector< std::vector< std::vector< Numerical_Orbital_Lm > > > &orb_in)
Definition exx_rotate_abfs.hpp:12
int factorial(const int &n) const
Definition exx_rotate_abfs.hpp:114
Definition ORB_atomic_lm.h:21
const double * getPsi() const
Definition ORB_atomic_lm.h:137
const double * getRadial() const
Definition ORB_atomic_lm.h:124
const int & getNr() const
Definition ORB_atomic_lm.h:118
const double * getRab() const
Definition ORB_atomic_lm.h:128
Definition ORB_gaunt_table.h:9
void init_Gaunt(const int &lmax)
Definition ORB_gaunt_table.cpp:15
ModuleBase::realArray Gaunt_Coefficients
Definition ORB_gaunt_table.h:56
static int get_lm_index(const int l, const int m)
Definition ORB_gaunt_table.h:89
void init_Gaunt_CH(const int &Lmax)
Definition ORB_gaunt_table.cpp:183
int *& iat2it
Definition unitcell.h:75
Atom * atoms
Definition unitcell.h:45
double & lat0
Definition unitcell.h:56
ModuleBase::Matrix3 & latvec
Definition unitcell.h:63
int *& iat2ia
Definition unitcell.h:76
#define N
Definition exp.cpp:24
#define T
Definition exp.cpp:237
Exx_Info exx_info
Definition exx_info.cpp:8
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< Index_T > IndexLNM
Definition element_basis_index.h:42
std::vector< std::vector< NM > > Range
Definition element_basis_index.h:41
void WARNING_QUIT(const std::string &, const std::string &)
Combine the functions of WARNING and QUIT.
Definition test_delley.cpp:14
const double TWO_PI
Definition constants.h:21
const double PI_HALF
Definition constants.h:20
const double FOUR_PI
Definition constants.h:22
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
#define threshold
Definition sph_bessel_recursive_test.cpp:4
bool rotate_abfs
Definition exx_info.h:57
Exx_Info_RI info_ri
Definition exx_info.h:86
double norm(const Vec3 &v)
Definition test_partition.cpp:25