6#ifndef LRI_CV_TOOLS_HPP
7#define LRI_CV_TOOLS_HPP
9#include "../../source_base/mathzone.h"
14#include <RI/global/Global_Func-1.h>
15#include <RI/global/Map_Operator.h>
16#include "../../source_pw/module_pwdft/global.h"
18template <
typename Tdata>
21 const double& threshold_condition_number)
29template <
typename Tdata>
30std::vector<std::vector<RI::Tensor<Tdata>>>
LRI_CV_Tools::cal_I(
const std::vector<std::vector<RI::Tensor<Tdata>>>& ms,
32 const double& threshold_condition_number)
37 return I.
output({ms[0][0].shape[0], ms[1][0].shape[0]}, {ms[0][0].shape[1], ms[0][1].shape[1]});
40template <
typename Tdata>
45template <
typename Tdata>
46std::array<RI::Tensor<Tdata>, 3>
48 return std::array<RI::Tensor<Tdata>, 3>{-dV[0].transpose(),
53template <
typename Tdata>
58template <
typename T, std::
size_t N>
60 for (
size_t i = 0; i < 3; ++i)
66template <
typename Tdata>
68 const RI::Tensor<Tdata>& t2) {
69 const size_t sa0 = t1.shape[0], sa1 = t2.shape[0], sl0 = t2.shape[1],
71 return (t1 * t2.reshape({sa1, sl0 * sl1})).reshape({sa0, sl0, sl1});
75 return std::array<T, 3>{
mul1(t1[0], t2),
mul1(t1[1], t2),
mul1(t1[2], t2)};
88template <
typename Tdata>
89std::vector<RI::Tensor<Tdata>>
91 const std::vector<RI::Tensor<Tdata>>& vec) {
92 const size_t sa0 = vec[0].shape[0], sa1 = vec[1].shape[0],
93 sl0 = vec[0].shape[1], sl1 = vec[0].shape[2];
94 const RI::Tensor<Tdata> vec0 = vec[0].reshape({sa0, sl0 * sl1}),
95 vec1 = vec[1].reshape({sa1, sl0 * sl1});
96 return std::vector<RI::Tensor<Tdata>>{
97 (mat[0][0] * vec0 + mat[0][1] * vec1).reshape({sa0, sl0, sl1}),
98 (mat[1][0] * vec0 + mat[1][1] * vec1).reshape({sa1, sl0, sl1})};
110template <
typename T1,
typename T2>
112 const std::array<T2, 3>& t2) {
113 return std::array<T2, 3>{
mul2(t1, t2[0]),
mul2(t1, t2[1]),
mul2(t1, t2[2])};
121template <
typename T,
typename TkeyA,
typename TkeyB,
typename Tvalue>
122std::map<TkeyA, std::map<TkeyB, Tvalue>>
124 const std::map<TkeyA, std::map<TkeyB, Tvalue>>& t2) {
125 std::map<TkeyA, std::map<TkeyB, Tvalue>> res;
126 for (
const auto& outerPair: t2) {
127 const TkeyA keyA = outerPair.first;
128 const std::map<TkeyB, Tvalue>& innerMap = outerPair.second;
129 std::map<TkeyB, Tvalue> newInnerMap;
131 for (
const auto& innerPair: innerMap) {
132 const TkeyB keyB = innerPair.first;
133 const Tvalue value = innerPair.second;
134 newInnerMap[keyB] =
mul2(t1, value);
137 res[keyA] = newInnerMap;
164template <
typename T, std::
size_t N>
165std::vector<std::array<T, N>>
167 const std::vector<std::array<T, N>>& v2) {
168 assert(v1.size() == v2.size());
169 std::vector<std::array<T, N>> v(v1.size());
170 for (std::size_t i = 0; i < v.size(); ++i)
171 for (std::size_t j = 0; j <
N; ++j)
172 v[i][j] = v1[i][j] - v2[i][j];
176template <
typename TkeyA,
typename TkeyB,
typename Tvalue, std::
size_t N>
178 std::map<TkeyA, std::map<TkeyB, std::array<Tvalue, N>>>& v1,
179 std::map<TkeyA, std::map<TkeyB, std::array<Tvalue, N>>>& v2) {
180 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N> v1_order
182 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N> v2_order
184 auto dv =
minus(v1_order, v2_order);
188template <
typename TkeyA,
typename TkeyB,
typename Tvalue, std::
size_t N>
190 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N>& v1,
191 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N>& v2) {
192 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N> dv;
193 for (
size_t i = 0; i !=
N; ++i)
194 dv[i] =
minus(v1[i], v2[i]);
198template <
typename TkeyA,
typename TkeyB,
typename Tvalue>
199std::map<TkeyA, std::map<TkeyB, Tvalue>>
201 std::map<TkeyA, std::map<TkeyB, Tvalue>>& v2) {
202 assert(v1.size() == v2.size());
203 using namespace RI::Map_Operator;
204 using namespace RI::Array_Operator;
206 std::map<TkeyA, std::map<TkeyB, Tvalue>> dv;
207 auto it1 = v1.begin();
208 auto it2 = v2.begin();
209 while (it1 != v1.end() && it2 != v2.end()) {
210 assert(it1->first == it2->first);
211 const TkeyA& keyA = it1->first;
212 const std::map<TkeyB, Tvalue>& map1 = it1->second;
213 const std::map<TkeyB, Tvalue>& map2 = it2->second;
214 dv[keyA] = map1 - map2;
221template <
typename T, std::
size_t N>
222std::vector<std::array<T, N>>
224 const std::vector<std::array<T, N>>& v2) {
225 assert(v1.size() == v2.size());
226 std::vector<std::array<T, N>> v(v1.size());
227 for (std::size_t i = 0; i < v.size(); ++i)
228 for (std::size_t j = 0; j <
N; ++j)
229 v[i][j] = v1[i][j] + v2[i][j];
233template <
typename TkeyA,
typename TkeyB,
typename Tvalue, std::
size_t N>
235 std::map<TkeyA, std::map<TkeyB, std::array<Tvalue, N>>>& v1,
236 std::map<TkeyA, std::map<TkeyB, std::array<Tvalue, N>>>& v2) {
237 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N> v1_order
239 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N> v2_order
241 auto dv =
add(v1_order, v2_order);
245template <
typename TkeyA,
typename TkeyB,
typename Tvalue, std::
size_t N>
247 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N>& v1,
248 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N>& v2) {
249 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N> dv;
250 for (
size_t i = 0; i !=
N; ++i)
251 dv[i] =
add(v1[i], v2[i]);
255template <
typename TkeyA,
typename TkeyB,
typename Tvalue>
256std::map<TkeyA, std::map<TkeyB, Tvalue>>
258 std::map<TkeyA, std::map<TkeyB, Tvalue>>& v2) {
259 assert(v1.size() == v2.size());
260 using namespace RI::Map_Operator;
261 using namespace RI::Array_Operator;
263 std::map<TkeyA, std::map<TkeyB, Tvalue>> dv;
264 auto it1 = v1.begin();
265 auto it2 = v2.begin();
266 while (it1 != v1.end() && it2 != v2.end()) {
267 assert(it1->first == it2->first);
268 const TkeyA& keyA = it1->first;
269 const std::map<TkeyB, Tvalue>& map1 = it1->second;
270 const std::map<TkeyB, Tvalue>& map2 = it2->second;
271 dv[keyA] = map1 + map2;
278template <
typename T, std::
size_t N>
280 std::array<T, N> v_out;
281 for (std::size_t i = 0; i <
N; ++i)
286template <
typename Tdata>
288 RI::Tensor<Tdata> c_out({c_in.shape[0], c_in.shape[2], c_in.shape[1]});
289 for (
size_t i0 = 0; i0 < c_in.shape[0]; ++i0)
290 for (
size_t i1 = 0; i1 < c_in.shape[1]; ++i1)
291 for (
size_t i2 = 0; i2 < c_in.shape[2]; ++i2)
292 c_out(i0, i2, i1) = c_in(i0, i1, i2);
296template <
typename T, std::
size_t N>
298 std::array<T, N> c_out;
299 for (
size_t i = 0; i <
N; ++i)
304template <
typename T, std::
size_t N>
305std::array<std::vector<T>,
N>
307 std::array<std::vector<T>,
N> ds;
308 for (
int ix = 0; ix <
N; ++ix) {
309 ds[ix].resize(ds_in.size());
310 for (
int iv = 0; iv < ds_in.size(); ++iv)
311 ds[ix][iv] = std::move(ds_in[iv][ix]);
316template <
typename T, std::
size_t N>
317std::vector<std::array<T, N>>
319 std::vector<std::array<T, N>> ds(ds_in[0].size());
320 for (
int ix = 0; ix <
N; ++ix) {
321 assert(ds.size() == ds_in[ix].size());
322 for (
int iv = 0; iv < ds.size(); ++iv)
323 ds[iv][ix] = std::move(ds_in[ix][iv]);
328template <
typename T, std::
size_t N>
330 std::vector<std::vector<std::array<T, N>>>&& ds_in) {
331 std::array<std::vector<std::vector<T>>,
N> ds;
332 for (
int ix = 0; ix <
N; ++ix) {
333 ds[ix].resize(ds_in.size());
334 for (
int i0 = 0; i0 < ds_in.size(); ++i0) {
335 ds[ix][i0].resize(ds_in[i0].size());
336 for (
int i1 = 0; i1 < ds_in[i0].size(); ++i1)
337 ds[ix][i0][i1] = std::move(ds_in[i0][i1][ix]);
343template <
typename TkeyA,
typename TkeyB,
typename Tvalue, std::
size_t N>
344std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N>
346 std::map<TkeyA, std::map<TkeyB, std::array<Tvalue, N>>>&& ds_in) {
347 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N> ds;
348 for (
auto& ds_A: ds_in)
349 for (
auto& ds_B: ds_A.second)
350 for (
int ix = 0; ix <
N; ++ix)
351 ds[ix][ds_A.first][ds_B.first] = std::move(ds_B.second[ix]);
355template <
typename TkeyA,
typename TkeyB,
typename Tvalue, std::
size_t N>
356std::map<TkeyA, std::map<TkeyB, std::array<Tvalue, N>>>
358 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N>&& ds_in) {
359 std::map<TkeyA, std::map<TkeyB, std::array<Tvalue, N>>> ds;
360 for (
int ix = 0; ix <
N; ++ix)
361 for (
auto& ds_A: ds_in[ix])
362 for (
auto& ds_B: ds_A.second)
363 ds[ds_A.first][ds_B.first][ix] = std::move(ds_B.second);
367template <
typename Tcell>
370 const std::vector<double>& orb_cutoff) {
373 Rcut_max = std::max(Rcut_max, orb_cutoff[
T]);
378 static_cast<Tcell
>(std::ceil(latvec_times.y)),
379 static_cast<Tcell
>(std::ceil(latvec_times.z))};
381 return std::array<Tcell,3>{period.
x, period.
y, period.
z};
384template<
typename TA,
typename Tcell,
typename Tdata>
385std::map<int,std::map<int,std::map<Abfs::Vector3_Order<double>,RI::Tensor<Tdata>>>>
388 const std::map<TA,std::map<std::pair<TA,std::array<Tcell,3>>,RI::Tensor<Tdata>>> &CVs)
390 std::map<int,std::map<int,std::map<Abfs::Vector3_Order<double>,RI::Tensor<Tdata>>>> CVws;
391 for(
const auto &CVs_A : CVs)
393 const TA iat0 = CVs_A.first;
394 const int it0 = ucell.
iat2it[iat0];
395 const int ia0 = ucell.
iat2ia[iat0];
397 for(
const auto &CVs_B : CVs_A.second)
399 const TA iat1 = CVs_B.first.first;
400 const int it1 = ucell.
iat2it[iat1];
401 const int ia1 = ucell.
iat2ia[iat1];
402 const std::array<int,3> &cell1 = CVs_B.first.second;
405 CVws[it0][it1][R_delta] = CVs_B.second;
411template <
typename TA,
typename Tcell,
typename Tdata>
412std::map<int, std::map<int, std::map<Abfs::Vector3_Order<double>, std::array<RI::Tensor<Tdata>, 3>>>>
LRI_CV_Tools::
414 const std::map<TA, std::map<std::pair<TA, std::array<Tcell, 3>>, std::array<RI::Tensor<Tdata>, 3>>>& dCVs)
416 std::map<int, std::map<int, std::map<Abfs::Vector3_Order<double>, std::array<RI::Tensor<Tdata>, 3>>>> dCVws;
417 for (
const auto& dCVs_A: dCVs)
419 const TA iat0 = dCVs_A.first;
420 const int it0 = ucell.
iat2it[iat0];
421 const int ia0 = ucell.
iat2ia[iat0];
423 for (
const auto& dCVs_B: dCVs_A.second)
425 const TA iat1 = dCVs_B.first.first;
426 const int it1 = ucell.
iat2it[iat1];
427 const int ia1 = ucell.
iat2ia[iat1];
428 const std::array<int, 3>& cell1 = dCVs_B.first.second;
432 dCVws[it0][it1][R_delta] = dCVs_B.second;
438template <
typename T, std::
size_t N>
441 const size_t ndim1) {
442 for (
size_t i = 0; i <
N; ++i) {
443 data[i] = RI::Tensor<T>({ndim0, ndim1});
447template <
typename T, std::
size_t N>
451 for (
size_t i = 0; i <
N; ++i)
452 data[i] += frac * val;
455template <
typename T, std::
size_t N>
459 const std::array<T, N>& val,
461 for (
size_t i = 0; i <
N; ++i) {
462 data[i](lmp, lmq) += frac * val[i];
466template <
typename T, std::
size_t N>
470 const std::array<RI::Tensor<T>,
N>& val,
474 for (
size_t i = 0; i <
N; ++i) {
475 data[i](lmp0, lmq0) += frac * val[i](lmp1, lmq1);
479template <
typename Tout,
typename Tin>
481 return RI::Global_Func::convert<Tout>(data);
484template <
typename Tout,
typename Tin, std::
size_t N>
485std::array<RI::Tensor<Tout>,
N>
487 std::array<RI::Tensor<Tout>,
N> out;
488 for (
size_t i = 0; i !=
N; ++i)
489 out[i] = RI::Global_Func::convert<Tout>(data[i]);
522template<
typename TA,
typename TC,
typename Tdata>
523std::array<std::array<std::map<TA,std::map<std::pair<TA,TC>,RI::Tensor<Tdata>>>,3>,3>
526 const std::array<std::map<TA,std::map<std::pair<TA,TC>,RI::Tensor<Tdata>>>,3> &dMs)
528 auto get_R_delta = [&](
const TA &iat0,
const std::pair<TA,TC> &A1) -> std::array<Tdata,3>
530 const TA iat1 = A1.first;
531 const TC &cell1 = A1.second;
532 const int it0 = ucell.
iat2it[iat0];
533 const int ia0 = ucell.
iat2ia[iat0];
534 const int it1 = ucell.
iat2it[iat1];
535 const int ia1 = ucell.
iat2ia[iat1];
539 return std::array<Tdata,3>{R_delta.
x, R_delta.
y, R_delta.
z};
541 constexpr int Npos = 3;
542 std::array<std::array<std::map<TA,std::map<std::pair<TA,TC>,RI::Tensor<Tdata>>>,Npos>,Npos> dMRs;
543 for(
int ipos0=0; ipos0<Npos; ++ipos0)
545 for(
int ipos1=0; ipos1<Npos; ++ipos1)
547 for(
const auto &dMs_A : dMs[ipos0])
549 const TA iat0 = dMs_A.first;
550 for(
const auto &dMs_B : dMs_A.second)
552 const std::pair<TA,TC> A1 = dMs_B.first;
553 const RI::Tensor<Tdata> &dM = dMs_B.second;
554 const std::array<Tdata,3> R_delta = get_R_delta(iat0, A1);
555 dMRs[ipos0][ipos1][iat0][A1] = dM * R_delta[ipos1];
Definition abfs-vector3_order.h:16
std::vector< ModuleBase::Vector3< double > > tau
Definition atom_spec.h:36
Definition Inverse_Matrix.h:15
Method
Definition Inverse_Matrix.h:18
void input(const RI::Tensor< Tdata > &m)
Definition Inverse_Matrix.hpp:166
RI::Tensor< Tdata > output() const
Definition Inverse_Matrix.hpp:218
void cal_inverse(const Method &method, const double &threshold_condition_number=0.)
Definition Inverse_Matrix.hpp:16
static ModuleBase::Vector3< T > latvec_projection(const std::array< ModuleBase::Vector3< T >, 3 > &latvec)
Definition mathzone.h:167
3 elements vector
Definition vector3.h:22
T x
Definition vector3.h:24
T y
Definition vector3.h:25
T z
Definition vector3.h:26
int *& iat2it
Definition unitcell.h:49
Atom * atoms
Definition unitcell.h:19
double & lat0
Definition unitcell.h:30
ModuleBase::Matrix3 & latvec
Definition unitcell.h:37
int & ntype
Definition unitcell.h:47
ModuleBase::Vector3< double > & a2
Definition unitcell.h:38
ModuleBase::Vector3< double > & a3
Definition unitcell.h:38
int *& iat2ia
Definition unitcell.h:50
ModuleBase::Vector3< double > & a1
Definition unitcell.h:38
#define N
Definition exp.cpp:24
#define T
Definition exp.cpp:237
ModuleBase::Vector3< Tcell > array3_to_Vector3(const std::array< Tcell, 3 > &v)
Definition RI_Util.h:38