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>
26template <
typename Tdata>
27std::vector<std::vector<RI::Tensor<Tdata>>>
32 return I.
output({ms[0][0].shape[0], ms[1][0].shape[0]},
33 {ms[0][0].shape[1], ms[0][1].shape[1]});
36template <
typename Tdata>
41template <
typename Tdata>
42std::array<RI::Tensor<Tdata>, 3>
44 return std::array<RI::Tensor<Tdata>, 3>{-dV[0].transpose(),
49template <
typename Tdata>
54template <
typename T, std::
size_t N>
56 for (
size_t i = 0; i < 3; ++i)
62template <
typename Tdata>
64 const RI::Tensor<Tdata>& t2) {
65 const size_t sa0 = t1.shape[0], sa1 = t2.shape[0], sl0 = t2.shape[1],
67 return (t1 * t2.reshape({sa1, sl0 * sl1})).reshape({sa0, sl0, sl1});
71 return std::array<T, 3>{
mul1(t1[0], t2),
mul1(t1[1], t2),
mul1(t1[2], t2)};
84template <
typename Tdata>
85std::vector<RI::Tensor<Tdata>>
87 const std::vector<RI::Tensor<Tdata>>& vec) {
88 const size_t sa0 = vec[0].shape[0], sa1 = vec[1].shape[0],
89 sl0 = vec[0].shape[1], sl1 = vec[0].shape[2];
90 const RI::Tensor<Tdata> vec0 = vec[0].reshape({sa0, sl0 * sl1}),
91 vec1 = vec[1].reshape({sa1, sl0 * sl1});
92 return std::vector<RI::Tensor<Tdata>>{
93 (mat[0][0] * vec0 + mat[0][1] * vec1).reshape({sa0, sl0, sl1}),
94 (mat[1][0] * vec0 + mat[1][1] * vec1).reshape({sa1, sl0, sl1})};
106template <
typename T1,
typename T2>
108 const std::array<T2, 3>& t2) {
109 return std::array<T2, 3>{
mul2(t1, t2[0]),
mul2(t1, t2[1]),
mul2(t1, t2[2])};
117template <
typename T,
typename TkeyA,
typename TkeyB,
typename Tvalue>
118std::map<TkeyA, std::map<TkeyB, Tvalue>>
120 const std::map<TkeyA, std::map<TkeyB, Tvalue>>& t2) {
121 std::map<TkeyA, std::map<TkeyB, Tvalue>> res;
122 for (
const auto& outerPair: t2) {
123 const TkeyA keyA = outerPair.first;
124 const std::map<TkeyB, Tvalue>& innerMap = outerPair.second;
125 std::map<TkeyB, Tvalue> newInnerMap;
127 for (
const auto& innerPair: innerMap) {
128 const TkeyB keyB = innerPair.first;
129 const Tvalue value = innerPair.second;
130 newInnerMap[keyB] =
mul2(t1, value);
133 res[keyA] = newInnerMap;
160template <
typename T, std::
size_t N>
161std::vector<std::array<T, N>>
163 const std::vector<std::array<T, N>>& v2) {
164 assert(v1.size() == v2.size());
165 std::vector<std::array<T, N>> v(v1.size());
166 for (std::size_t i = 0; i < v.size(); ++i)
167 for (std::size_t j = 0; j <
N; ++j)
168 v[i][j] = v1[i][j] - v2[i][j];
172template <
typename TkeyA,
typename TkeyB,
typename Tvalue, std::
size_t N>
174 std::map<TkeyA, std::map<TkeyB, std::array<Tvalue, N>>>& v1,
175 std::map<TkeyA, std::map<TkeyB, std::array<Tvalue, N>>>& v2) {
176 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N> v1_order
178 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N> v2_order
180 auto dv =
minus(v1_order, v2_order);
184template <
typename TkeyA,
typename TkeyB,
typename Tvalue, std::
size_t N>
186 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N>& v1,
187 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N>& v2) {
188 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N> dv;
189 for (
size_t i = 0; i !=
N; ++i)
190 dv[i] =
minus(v1[i], v2[i]);
194template <
typename TkeyA,
typename TkeyB,
typename Tvalue>
195std::map<TkeyA, std::map<TkeyB, Tvalue>>
197 std::map<TkeyA, std::map<TkeyB, Tvalue>>& v2) {
198 assert(v1.size() == v2.size());
199 using namespace RI::Map_Operator;
200 using namespace RI::Array_Operator;
202 std::map<TkeyA, std::map<TkeyB, Tvalue>> dv;
203 auto it1 = v1.begin();
204 auto it2 = v2.begin();
205 while (it1 != v1.end() && it2 != v2.end()) {
206 assert(it1->first == it2->first);
207 const TkeyA& keyA = it1->first;
208 const std::map<TkeyB, Tvalue>& map1 = it1->second;
209 const std::map<TkeyB, Tvalue>& map2 = it2->second;
210 dv[keyA] = map1 - map2;
217template <
typename T, std::
size_t N>
218std::vector<std::array<T, N>>
220 const std::vector<std::array<T, N>>& v2) {
221 assert(v1.size() == v2.size());
222 std::vector<std::array<T, N>> v(v1.size());
223 for (std::size_t i = 0; i < v.size(); ++i)
224 for (std::size_t j = 0; j <
N; ++j)
225 v[i][j] = v1[i][j] + v2[i][j];
229template <
typename TkeyA,
typename TkeyB,
typename Tvalue, std::
size_t N>
231 std::map<TkeyA, std::map<TkeyB, std::array<Tvalue, N>>>& v1,
232 std::map<TkeyA, std::map<TkeyB, std::array<Tvalue, N>>>& v2) {
233 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N> v1_order
235 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N> v2_order
237 auto dv =
add(v1_order, v2_order);
241template <
typename TkeyA,
typename TkeyB,
typename Tvalue, std::
size_t N>
243 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N>& v1,
244 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N>& v2) {
245 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N> dv;
246 for (
size_t i = 0; i !=
N; ++i)
247 dv[i] =
add(v1[i], v2[i]);
251template <
typename TkeyA,
typename TkeyB,
typename Tvalue>
252std::map<TkeyA, std::map<TkeyB, Tvalue>>
254 std::map<TkeyA, std::map<TkeyB, Tvalue>>& v2) {
255 assert(v1.size() == v2.size());
256 using namespace RI::Map_Operator;
257 using namespace RI::Array_Operator;
259 std::map<TkeyA, std::map<TkeyB, Tvalue>> dv;
260 auto it1 = v1.begin();
261 auto it2 = v2.begin();
262 while (it1 != v1.end() && it2 != v2.end()) {
263 assert(it1->first == it2->first);
264 const TkeyA& keyA = it1->first;
265 const std::map<TkeyB, Tvalue>& map1 = it1->second;
266 const std::map<TkeyB, Tvalue>& map2 = it2->second;
267 dv[keyA] = map1 + map2;
274template <
typename T, std::
size_t N>
276 std::array<T, N> v_out;
277 for (std::size_t i = 0; i <
N; ++i)
282template <
typename Tdata>
284 RI::Tensor<Tdata> c_out({c_in.shape[0], c_in.shape[2], c_in.shape[1]});
285 for (
size_t i0 = 0; i0 < c_in.shape[0]; ++i0)
286 for (
size_t i1 = 0; i1 < c_in.shape[1]; ++i1)
287 for (
size_t i2 = 0; i2 < c_in.shape[2]; ++i2)
288 c_out(i0, i2, i1) = c_in(i0, i1, i2);
292template <
typename T, std::
size_t N>
294 std::array<T, N> c_out;
295 for (
size_t i = 0; i <
N; ++i)
300template <
typename T, std::
size_t N>
301std::array<std::vector<T>,
N>
303 std::array<std::vector<T>,
N> ds;
304 for (
int ix = 0; ix <
N; ++ix) {
305 ds[ix].resize(ds_in.size());
306 for (
int iv = 0; iv < ds_in.size(); ++iv)
307 ds[ix][iv] = std::move(ds_in[iv][ix]);
312template <
typename T, std::
size_t N>
313std::vector<std::array<T, N>>
315 std::vector<std::array<T, N>> ds(ds_in[0].size());
316 for (
int ix = 0; ix <
N; ++ix) {
317 assert(ds.size() == ds_in[ix].size());
318 for (
int iv = 0; iv < ds.size(); ++iv)
319 ds[iv][ix] = std::move(ds_in[ix][iv]);
324template <
typename T, std::
size_t N>
326 std::vector<std::vector<std::array<T, N>>>&& ds_in) {
327 std::array<std::vector<std::vector<T>>,
N> ds;
328 for (
int ix = 0; ix <
N; ++ix) {
329 ds[ix].resize(ds_in.size());
330 for (
int i0 = 0; i0 < ds_in.size(); ++i0) {
331 ds[ix][i0].resize(ds_in[i0].size());
332 for (
int i1 = 0; i1 < ds_in[i0].size(); ++i1)
333 ds[ix][i0][i1] = std::move(ds_in[i0][i1][ix]);
339template <
typename TkeyA,
typename TkeyB,
typename Tvalue, std::
size_t N>
340std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N>
342 std::map<TkeyA, std::map<TkeyB, std::array<Tvalue, N>>>&& ds_in) {
343 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N> ds;
344 for (
auto& ds_A: ds_in)
345 for (
auto& ds_B: ds_A.second)
346 for (
int ix = 0; ix <
N; ++ix)
347 ds[ix][ds_A.first][ds_B.first] = std::move(ds_B.second[ix]);
351template <
typename TkeyA,
typename TkeyB,
typename Tvalue, std::
size_t N>
352std::map<TkeyA, std::map<TkeyB, std::array<Tvalue, N>>>
354 std::array<std::map<TkeyA, std::map<TkeyB, Tvalue>>,
N>&& ds_in) {
355 std::map<TkeyA, std::map<TkeyB, std::array<Tvalue, N>>> ds;
356 for (
int ix = 0; ix <
N; ++ix)
357 for (
auto& ds_A: ds_in[ix])
358 for (
auto& ds_B: ds_A.second)
359 ds[ds_A.first][ds_B.first][ix] = std::move(ds_B.second);
363template <
typename Tcell>
366 const std::vector<double>& orb_cutoff) {
369 Rcut_max = std::max(Rcut_max, orb_cutoff[
T]);
374 static_cast<Tcell
>(std::ceil(latvec_times.y)),
375 static_cast<Tcell
>(std::ceil(latvec_times.z))};
377 return std::array<Tcell,3>{period.
x, period.
y, period.
z};
380template<
typename TA,
typename Tcell,
typename Tdata>
381std::map<int,std::map<int,std::map<Abfs::Vector3_Order<double>,RI::Tensor<Tdata>>>>
384 const std::map<TA,std::map<std::pair<TA,std::array<Tcell,3>>,RI::Tensor<Tdata>>> &CVs)
386 std::map<int,std::map<int,std::map<Abfs::Vector3_Order<double>,RI::Tensor<Tdata>>>> CVws;
387 for(
const auto &CVs_A : CVs)
389 const TA iat0 = CVs_A.first;
390 const int it0 = ucell.
iat2it[iat0];
391 const int ia0 = ucell.
iat2ia[iat0];
393 for(
const auto &CVs_B : CVs_A.second)
395 const TA iat1 = CVs_B.first.first;
396 const int it1 = ucell.
iat2it[iat1];
397 const int ia1 = ucell.
iat2ia[iat1];
398 const std::array<int,3> &cell1 = CVs_B.first.second;
401 CVws[it0][it1][R_delta] = CVs_B.second;
407template <
typename TA,
typename Tcell,
typename Tdata>
408std::map<int, std::map<int, std::map<Abfs::Vector3_Order<double>, std::array<RI::Tensor<Tdata>, 3>>>>
LRI_CV_Tools::
410 const std::map<TA, std::map<std::pair<TA, std::array<Tcell, 3>>, std::array<RI::Tensor<Tdata>, 3>>>& dCVs)
412 std::map<int, std::map<int, std::map<Abfs::Vector3_Order<double>, std::array<RI::Tensor<Tdata>, 3>>>> dCVws;
413 for (
const auto& dCVs_A: dCVs)
415 const TA iat0 = dCVs_A.first;
416 const int it0 = ucell.
iat2it[iat0];
417 const int ia0 = ucell.
iat2ia[iat0];
419 for (
const auto& dCVs_B: dCVs_A.second)
421 const TA iat1 = dCVs_B.first.first;
422 const int it1 = ucell.
iat2it[iat1];
423 const int ia1 = ucell.
iat2ia[iat1];
424 const std::array<int, 3>& cell1 = dCVs_B.first.second;
428 dCVws[it0][it1][R_delta] = dCVs_B.second;
434template <
typename T, std::
size_t N>
437 const size_t ndim1) {
438 for (
size_t i = 0; i <
N; ++i) {
439 data[i] = RI::Tensor<T>({ndim0, ndim1});
443template <
typename T, std::
size_t N>
447 for (
size_t i = 0; i <
N; ++i)
448 data[i] += frac * val;
451template <
typename T, std::
size_t N>
455 const std::array<T, N>& val,
457 for (
size_t i = 0; i <
N; ++i) {
458 data[i](lmp, lmq) += frac * val[i];
462template <
typename T, std::
size_t N>
466 const std::array<RI::Tensor<T>,
N>& val,
470 for (
size_t i = 0; i <
N; ++i) {
471 data[i](lmp0, lmq0) += frac * val[i](lmp1, lmq1);
475template <
typename Tout,
typename Tin>
477 return RI::Global_Func::convert<Tout>(data);
480template <
typename Tout,
typename Tin, std::
size_t N>
481std::array<RI::Tensor<Tout>,
N>
483 std::array<RI::Tensor<Tout>,
N> out;
484 for (
size_t i = 0; i !=
N; ++i)
485 out[i] = RI::Global_Func::convert<Tout>(data[i]);
518template<
typename TA,
typename TC,
typename Tdata>
519std::array<std::array<std::map<TA,std::map<std::pair<TA,TC>,RI::Tensor<Tdata>>>,3>,3>
522 const std::array<std::map<TA,std::map<std::pair<TA,TC>,RI::Tensor<Tdata>>>,3> &dMs)
524 auto get_R_delta = [&](
const TA &iat0,
const std::pair<TA,TC> &A1) -> std::array<Tdata,3>
526 const TA iat1 = A1.first;
527 const TC &cell1 = A1.second;
528 const int it0 = ucell.
iat2it[iat0];
529 const int ia0 = ucell.
iat2ia[iat0];
530 const int it1 = ucell.
iat2it[iat1];
531 const int ia1 = ucell.
iat2ia[iat1];
535 return std::array<Tdata,3>{R_delta.
x, R_delta.
y, R_delta.
z};
537 constexpr int Npos = 3;
538 std::array<std::array<std::map<TA,std::map<std::pair<TA,TC>,RI::Tensor<Tdata>>>,Npos>,Npos> dMRs;
539 for(
int ipos0=0; ipos0<Npos; ++ipos0)
541 for(
int ipos1=0; ipos1<Npos; ++ipos1)
543 for(
const auto &dMs_A : dMs[ipos0])
545 const TA iat0 = dMs_A.first;
546 for(
const auto &dMs_B : dMs_A.second)
548 const std::pair<TA,TC> A1 = dMs_B.first;
549 const RI::Tensor<Tdata> &dM = dMs_B.second;
550 const std::array<Tdata,3> R_delta = get_R_delta(iat0, A1);
551 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:13
void cal_inverse(const Method &method)
Definition Inverse_Matrix.hpp:15
void input(const RI::Tensor< Tdata > &m)
Definition Inverse_Matrix.hpp:63
RI::Tensor< Tdata > output() const
Definition Inverse_Matrix.hpp:117
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:47
Atom * atoms
Definition unitcell.h:18
double & lat0
Definition unitcell.h:28
ModuleBase::Matrix3 & latvec
Definition unitcell.h:35
int & ntype
Definition unitcell.h:45
ModuleBase::Vector3< double > & a2
Definition unitcell.h:36
ModuleBase::Vector3< double > & a3
Definition unitcell.h:36
int *& iat2ia
Definition unitcell.h:48
ModuleBase::Vector3< double > & a1
Definition unitcell.h:36
#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