ABACUS develop
Atomic-orbital Based Ab-initio Computation at UStc
Loading...
Searching...
No Matches
hamilt_ulr.hpp
Go to the documentation of this file.
1#pragma once
7#ifdef __EXX
9#endif
10namespace LR
11{
14 template<typename T>
16 {
17 public:
18 HamiltULR(std::string& xc_kernel,
19 const int& nspin,
20 const int& naos,
21 const std::vector<int>& nocc,
22 const std::vector<int>& nvirt,
23 const UnitCell& ucell_in,
24 const std::vector<double>& orb_cutoff,
25 Grid_Driver& gd_in,
26 const psi::Psi<T>& psi_ks_in,
27 const ModuleBase::matrix& eig_ks,
28#ifdef __EXX
29 std::weak_ptr<Exx_LRI<T>> exx_lri_in,
30 const double& exx_alpha,
31#endif
32 std::vector<std::shared_ptr<PotHxcLR>>& pot_in,
33 const K_Vectors& kv_in,
34 const std::vector<Parallel_2D>& pX_in,
35 const Parallel_2D& pc_in,
36 const Parallel_Orbitals& pmat_in) :nocc(nocc), nvirt(nvirt), pX(pX_in), nk(kv_in.get_nks() / nspin),
37 ldim(nk* pX[0].get_local_size() + nk * pX[1].get_local_size()),
38 gdim(nk* std::inner_product(nocc.begin(), nocc.end(), nvirt.begin(), 0))
39 {
40 ModuleBase::TITLE("HamiltULR", "HamiltULR");
41 this->DM_trans = LR_Util::make_unique<elecstate::DensityMatrix<T, T>>(&pmat_in, 1, kv_in.kvec_d, nk);
42 LR_Util::initialize_DMR(*this->DM_trans, pmat_in, ucell_in, gd_in, orb_cutoff);
43 // this->DM_trans->init_DMR(&gd_in, &ucell_in); // too large due to not restricted by orb_cutoff
44 this->ops.resize(4);
45
46 this->ops[0] = new OperatorLRDiag<T>(eig_ks.c, pX_in[0], nk, nocc[0], nvirt[0]);
47 this->ops[3] = new OperatorLRDiag<T>(eig_ks.c + nk * (nocc[0] + nvirt[0]), pX_in[1], nk, nocc[1], nvirt[1]);
48
49 auto newHxc = [&](const int& sl, const int& sr) { return new OperatorLRHxc<T>(nspin, naos, nocc, nvirt, psi_ks_in,
50 this->DM_trans, pot_in[sl], ucell_in, orb_cutoff, gd_in, kv_in, pX_in, pc_in, pmat_in, { sl,sr }); };
51 this->ops[0]->add(newHxc(0, 0));
52 this->ops[1] = newHxc(0, 1);
53 this->ops[2] = newHxc(1, 0);
54 this->ops[3]->add(newHxc(1, 1));
55
56#ifdef __EXX
57 if (xc_kernel == "hf" || xc_kernel == "hse")
58 {
59 std::vector<psi::Psi<T>> psi_ks_spin = { LR_Util::get_psi_spin(psi_ks_in, 0, nk), LR_Util::get_psi_spin(psi_ks_in, 1, nk) };
60 for (int is : {0, 1})
61 {
62 this->ops[(is << 1) + is]->add(new OperatorLREXX<T>(nspin, naos, nocc[is], nvirt[is], ucell_in, psi_ks_spin[is],
63 this->DM_trans, exx_lri_in, kv_in, pX_in[is], pc_in, pmat_in,
64 xc_kernel == "hf" ? 1.0 : exx_alpha));
65 }
66 }
67#endif
68
69 this->cal_dm_trans = [&, this](const int& is, const T* const X)->void
70 {
71 const auto psi_ks_is = LR_Util::get_psi_spin(psi_ks_in, is, nk);
72 // LR_Util::print_value(X, pX_in[is].get_local_size());
73#ifdef __MPI
74 std::vector<ct::Tensor> dm_trans_2d = cal_dm_trans_pblas(X, pX[is], psi_ks_is, pc_in, naos, nocc[is], nvirt[is], pmat_in, (T)1.0 / (T)nk);
75 if (this->tdm_sym) for (auto& t : dm_trans_2d) LR_Util::matsym(t.data<T>(), naos, pmat_in);
76#else
77 std::vector<ct::Tensor> dm_trans_2d = cal_dm_trans_blas(X, psi_ks_is, nocc[is], nvirt[is], (T)1.0 / (T)nk);
78 if (this->tdm_sym) for (auto& t : dm_trans_2d) LR_Util::matsym(t.data<T>(), naos);
79#endif
80 // LR_Util::print_tensor<T>(dm_trans_2d[0], "DMtrans(k=0)", &pmat_in);
81 // tensor to vector, then set DMK
82 for (int ik = 0;ik < nk;++ik) { this->DM_trans->set_DMK_pointer(ik, dm_trans_2d[ik].data<T>()); }
83 };
84 }
86 {
87 for (auto& op : ops) { delete op; }
88 }
89 void hPsi(const T* const psi_in, T* const hpsi, const int ld_psi, const int& nband) const
90 {
91 ModuleBase::TITLE("HamiltULR", "hPsi");
92 assert(ld_psi == this->ldim);
93 const std::vector<int64_t> xdim_is = { nk * pX[0].get_local_size(), nk * pX[1].get_local_size() };
95 for (int ib = 0;ib < nband;++ib)
96 {
97 const int offset_band = ib * ld_psi;
98 for (int is_bj : {0, 1})
99 {
100 const int offset_bj = offset_band + is_bj * xdim_is[0];
101 cal_dm_trans(is_bj, psi_in + offset_bj); // calculate transition density matrix here
102 for (int is_ai : {0, 1})
103 {
104 const int offset_ai = offset_band + is_ai * xdim_is[0];
105 hamilt::Operator<T>* node(this->ops[(is_ai << 1) + is_bj]);
106 while (node != nullptr)
107 {
108 node->act(/*nband=*/1, xdim_is[is_bj], /*npol=*/1, psi_in + offset_bj, hpsi + offset_ai);
109 node = (hamilt::Operator<T>*)(node->next_op);
110 }
111 }
112 }
113 }
114 }
115 std::vector<T> matrix()const
116 {
117 ModuleBase::TITLE("HamiltULR", "matrix");
118 const std::vector<int> npairs = { this->nocc[0] * this->nvirt[0], this->nocc[1] * this->nvirt[1] };
119 const std::vector<int64_t> ldim_is = { nk * pX[0].get_local_size(), nk * pX[1].get_local_size() };
120 const std::vector<int> gdim_is = { nk * npairs[0], nk * npairs[1] };
121 std::vector<T> Amat_full(gdim * gdim);
122 for (int is_bj : {0, 1})
123 {
124 const int no = this->nocc[is_bj];
125 const int nv = this->nvirt[is_bj];
126 const auto& px = this->pX[is_bj];
127 const int loffset_bj = is_bj * ldim_is[0];
128 const int goffset_bj = is_bj * gdim_is[0];
129 for (int ik_bj = 0;ik_bj < nk;++ik_bj)
130 {
131 for (int j = 0;j < no;++j)
132 {
133 for (int b = 0;b < nv;++b)
134 {
135 const int gcol = goffset_bj + ik_bj * npairs[is_bj] + j * nv + b;//global
136 std::vector<T> X_bj(this->ldim, T(0));
137 const int lj = px.global2local_col(j);
138 const int lb = px.global2local_row(b);
139 const int lcol = loffset_bj + ik_bj * px.get_local_size() + lj * px.get_row_size() + lb;//local
140 if (px.in_this_processor(b, j)) { X_bj[lcol] = T(1); }
141 this->cal_dm_trans(is_bj, X_bj.data() + loffset_bj);
142 std::vector<T> Aloc_col(this->ldim, T(0)); // a col of A matrix (local)
143 for (int is_ai : {0, 1})
144 {
145 const int goffset_ai = is_ai * gdim_is[0];
146 const int loffset_ai = is_ai * ldim_is[0];
147 const auto& pax = this->pX[is_ai];
148 hamilt::Operator<T>* node(this->ops[(is_ai << 1) + is_bj]);
149 while (node != nullptr)
150 {
151 node->act(1, ldim_is[is_bj], /*npol=*/1, X_bj.data() + loffset_bj, Aloc_col.data() + loffset_ai);
152 node = (hamilt::Operator<T>*)(node->next_op);
153 }
154#ifdef __MPI
155 for (int ik_ai = 0;ik_ai < this->nk;++ik_ai)
156 {
157 LR_Util::gather_2d_to_full(pax, Aloc_col.data() + loffset_ai + ik_ai * pax.get_local_size(),
158 Amat_full.data() + gcol * gdim /*col, bj*/ + goffset_ai + ik_ai * npairs[is_ai]/*row, ai*/,
159 false, nv, no);
160 }
161#else
162 std::memcpy(Amat_full.data() + gcol * gdim + goffset_ai, Aloc_col.data() + goffset_ai, gdim_is[is_ai] * sizeof(T));
163#endif
164 }
165 }
166 }
167 }
168 }
169 std::cout << "Full A matrix:" << std::endl;
170 LR_Util::print_value(Amat_full.data(), gdim, gdim);
171 return Amat_full;
172 }
173
175 void global2local(T* lvec, const T* gvec, const int& nband) const
176 {
177 const std::vector<int> npairs = { this->nocc[0] * this->nvirt[0], this->nocc[1] * this->nvirt[1] };
178 const std::vector<int64_t> ldim_is = { nk * pX[0].get_local_size(), nk * pX[1].get_local_size() };
179 const std::vector<int> gdim_is = { nk * npairs[0], nk * npairs[1] };
180 for (int ib = 0;ib < nband;++ib)
181 {
182 const int loffset_b = ib * this->ldim;
183 const int goffset_b = ib * this->gdim;
184 for (int is : {0, 1})
185 {
186 const int loffset_bs = loffset_b + is * ldim_is[0];
187 const int goffset_bs = goffset_b + is * gdim_is[0];
188 for (int ik = 0;ik < nk;++ik)
189 {
190 const int loffset = loffset_bs + ik * pX[is].get_local_size();
191 const int goffset = goffset_bs + ik * npairs[is];
192 for (int lo = 0;lo < pX[is].get_col_size();++lo)
193 {
194 const int go = pX[is].local2global_col(lo);
195 for (int lv = 0;lv < pX[is].get_row_size();++lv)
196 {
197 const int gv = pX[is].local2global_row(lv);
198 lvec[loffset + lo * pX[is].get_row_size() + lv] = gvec[goffset + go * nvirt[is] + gv];
199 }
200 }
201 }
202 }
203 }
204 }
205
206 private:
207 const std::vector<int>& nocc;
208 const std::vector<int>& nvirt;
209
210 const std::vector<Parallel_2D>& pX;
211
212
213 const int nk = 1;
214 const int ldim = 1;
215 const int gdim = 1;
216
218 std::vector<hamilt::Operator<T>*> ops;
219
223 std::unique_ptr<elecstate::DensityMatrix<T, T>> DM_trans;
224
225 std::function<void(const int&, const T* const)> cal_dm_trans;
226 const bool tdm_sym = false;
227 };
228}
Definition Exx_LRI.h:51
Definition sltk_grid_driver.h:43
Definition klist.h:13
std::vector< ModuleBase::Vector3< double > > kvec_d
Cartesian coordinates of k points.
Definition klist.h:16
Definition hamilt_ulr.hpp:16
~HamiltULR()
Definition hamilt_ulr.hpp:85
const int nk
Definition hamilt_ulr.hpp:213
std::unique_ptr< elecstate::DensityMatrix< T, T > > DM_trans
Definition hamilt_ulr.hpp:223
void hPsi(const T *const psi_in, T *const hpsi, const int ld_psi, const int &nband) const
Definition hamilt_ulr.hpp:89
const bool tdm_sym
whether to symmetrize the transition density matrix
Definition hamilt_ulr.hpp:226
HamiltULR(std::string &xc_kernel, const int &nspin, const int &naos, const std::vector< int > &nocc, const std::vector< int > &nvirt, const UnitCell &ucell_in, const std::vector< double > &orb_cutoff, Grid_Driver &gd_in, const psi::Psi< T > &psi_ks_in, const ModuleBase::matrix &eig_ks, std::vector< std::shared_ptr< PotHxcLR > > &pot_in, const K_Vectors &kv_in, const std::vector< Parallel_2D > &pX_in, const Parallel_2D &pc_in, const Parallel_Orbitals &pmat_in)
Definition hamilt_ulr.hpp:18
std::vector< T > matrix() const
Definition hamilt_ulr.hpp:115
std::function< void(const int &, const T *const)> cal_dm_trans
Definition hamilt_ulr.hpp:225
const int ldim
Definition hamilt_ulr.hpp:214
const std::vector< int > & nvirt
Definition hamilt_ulr.hpp:208
void global2local(T *lvec, const T *gvec, const int &nband) const
copy global data (eigenvectors) to local memory
Definition hamilt_ulr.hpp:175
const std::vector< Parallel_2D > & pX
Definition hamilt_ulr.hpp:210
const std::vector< int > & nocc
Definition hamilt_ulr.hpp:207
std::vector< hamilt::Operator< T > * > ops
4 operator lists: uu, ud, du, dd
Definition hamilt_ulr.hpp:218
const int gdim
Definition hamilt_ulr.hpp:215
Diag part of A operator: [AX]_iak = (e_ak - e_ik) X_iak.
Definition operator_lr_diag.h:13
Definition Exx_LRI.h:37
Hxc part of A operator for LR-TDDFT.
Definition operator_lr_hxc.h:13
Definition matrix.h:19
double * c
Definition matrix.h:25
This class packs the basic information of 2D-block-cyclic parallel distribution of an arbitrary matri...
Definition parallel_2d.h:12
Definition parallel_orbitals.h:9
Definition unitcell.h:17
Definition operator.h:38
Operator * next_op
interface type 3: return a Psi-type HPsi
Definition operator.h:84
virtual void add(Operator *next)
virtual void act(const int nbands, const int nbasis, const int npol, const T *tmpsi_in, T *tmhpsi, const int ngk_ik=0, const bool is_first_node=false) const
Definition operator.h:66
Definition psi.h:37
#define T
Definition exp.cpp:237
psi::Psi< T > get_psi_spin(const psi::Psi< T > &psi_in, const int &is, const int &nk)
get the Psi wrapper of the selected spin from the Psi object
Definition lr_util.hpp:100
void matsym(const T *in, const int n, T *out)
Definition lr_util.hpp:70
void initialize_DMR(elecstate::DensityMatrix< T, TR > &dm, const Parallel_Orbitals &pmat, const UnitCell &ucell, const Grid_Driver &gd, const std::vector< double > &orb_cutoff)
Definition lr_util_hcontainer.h:81
void gather_2d_to_full(const Parallel_2D &pv, const T *submat, T *fullmat, bool col_first, int global_nrow, int global_ncol)
gather 2d matrix to full matrix the defination of row and col is consistent with setup_2d_division
Definition lr_util.hpp:148
int print_value(const T *ptr, const int &size)
Definition lr_util_print.h:58
Definition esolver_ks_lcao.h:19
std::vector< container::Tensor > cal_dm_trans_pblas(const T *const X_istate, const Parallel_2D &px, const psi::Psi< T > &c, const Parallel_2D &pc, const int naos, const int nocc, const int nvirt, const Parallel_2D &pmat, const T factor=(T) 1.0, const MO_TYPE type=MO_TYPE::VO)
calculate the 2d-block transition density matrix in AO basis using p?gemm
std::vector< container::Tensor > cal_dm_trans_blas(const T *const X_istate, const psi::Psi< T > &c, const int &nocc, const int &nvirt, const T factor=(T) 1.0, const MO_TYPE type=MO_TYPE::VO)
calculate the 2d-block transition density matrix in AO basis using ?gemm
void TITLE(const std::string &class_name, const std::string &function_name, const bool disable)
Definition tool_title.cpp:18
base device SOURCES math_hegvd_test cpp endif() if(ENABLE_GOOGLEBENCH) AddTest(TARGET PERF_MODULE_HSOLVER_KERNELS LIBS parameter $
Definition CMakeLists.txt:10
const std::map< std::string, std::vector< double > > op
Definition vdwd3_autoset_xcparam.cpp:375