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 template<typename TGint>
19 HamiltULR(std::string& xc_kernel,
20 const int& nspin,
21 const int& naos,
22 const std::vector<int>& nocc,
23 const std::vector<int>& nvirt,
24 const UnitCell& ucell_in,
25 const std::vector<double>& orb_cutoff,
26 Grid_Driver& gd_in,
27 const psi::Psi<T>& psi_ks_in,
28 const ModuleBase::matrix& eig_ks,
29#ifdef __EXX
30 std::weak_ptr<Exx_LRI<T>> exx_lri_in,
31 const double& exx_alpha,
32#endif
33 TGint* gint_in,
34 std::vector<std::shared_ptr<PotHxcLR>>& pot_in,
35 const K_Vectors& kv_in,
36 const std::vector<Parallel_2D>& pX_in,
37 const Parallel_2D& pc_in,
38 const Parallel_Orbitals& pmat_in) :nocc(nocc), nvirt(nvirt), pX(pX_in), nk(kv_in.get_nks() / nspin),
39 ldim(nk* pX[0].get_local_size() + nk * pX[1].get_local_size()),
40 gdim(nk* std::inner_product(nocc.begin(), nocc.end(), nvirt.begin(), 0))
41 {
42 ModuleBase::TITLE("HamiltULR", "HamiltULR");
43 this->DM_trans = LR_Util::make_unique<elecstate::DensityMatrix<T, T>>(&pmat_in, 1, kv_in.kvec_d, nk);
44 LR_Util::initialize_DMR(*this->DM_trans, pmat_in, ucell_in, gd_in, orb_cutoff);
45 // this->DM_trans->init_DMR(&gd_in, &ucell_in); // too large due to not restricted by orb_cutoff
46 this->ops.resize(4);
47
48 this->ops[0] = new OperatorLRDiag<T>(eig_ks.c, pX_in[0], nk, nocc[0], nvirt[0]);
49 this->ops[3] = new OperatorLRDiag<T>(eig_ks.c + nk * (nocc[0] + nvirt[0]), pX_in[1], nk, nocc[1], nvirt[1]);
50
51 auto newHxc = [&](const int& sl, const int& sr) { return new OperatorLRHxc<T>(nspin, naos, nocc, nvirt, psi_ks_in,
52 this->DM_trans, gint_in, pot_in[sl], ucell_in, orb_cutoff, gd_in, kv_in, pX_in, pc_in, pmat_in, { sl,sr }); };
53 this->ops[0]->add(newHxc(0, 0));
54 this->ops[1] = newHxc(0, 1);
55 this->ops[2] = newHxc(1, 0);
56 this->ops[3]->add(newHxc(1, 1));
57
58#ifdef __EXX
59 if (xc_kernel == "hf" || xc_kernel == "hse")
60 {
61 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) };
62 for (int is : {0, 1})
63 {
64 this->ops[(is << 1) + is]->add(new OperatorLREXX<T>(nspin, naos, nocc[is], nvirt[is], ucell_in, psi_ks_spin[is],
65 this->DM_trans, exx_lri_in, kv_in, pX_in[is], pc_in, pmat_in,
66 xc_kernel == "hf" ? 1.0 : exx_alpha));
67 }
68 }
69#endif
70
71 this->cal_dm_trans = [&, this](const int& is, const T* const X)->void
72 {
73 const auto psi_ks_is = LR_Util::get_psi_spin(psi_ks_in, is, nk);
74 // LR_Util::print_value(X, pX_in[is].get_local_size());
75#ifdef __MPI
76 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);
77 if (this->tdm_sym) for (auto& t : dm_trans_2d) LR_Util::matsym(t.data<T>(), naos, pmat_in);
78#else
79 std::vector<ct::Tensor> dm_trans_2d = cal_dm_trans_blas(X, psi_ks_is, nocc[is], nvirt[is], (T)1.0 / (T)nk);
80 if (this->tdm_sym) for (auto& t : dm_trans_2d) LR_Util::matsym(t.data<T>(), naos);
81#endif
82 // LR_Util::print_tensor<T>(dm_trans_2d[0], "DMtrans(k=0)", &pmat_in);
83 // tensor to vector, then set DMK
84 for (int ik = 0;ik < nk;++ik) { this->DM_trans->set_DMK_pointer(ik, dm_trans_2d[ik].data<T>()); }
85 };
86 }
88 {
89 for (auto& op : ops) { delete op; }
90 }
91 void hPsi(const T* const psi_in, T* const hpsi, const int ld_psi, const int& nband) const
92 {
93 ModuleBase::TITLE("HamiltULR", "hPsi");
94 assert(ld_psi == this->ldim);
95 const std::vector<int64_t> xdim_is = { nk * pX[0].get_local_size(), nk * pX[1].get_local_size() };
97 for (int ib = 0;ib < nband;++ib)
98 {
99 const int offset_band = ib * ld_psi;
100 for (int is_bj : {0, 1})
101 {
102 const int offset_bj = offset_band + is_bj * xdim_is[0];
103 cal_dm_trans(is_bj, psi_in + offset_bj); // calculate transition density matrix here
104 for (int is_ai : {0, 1})
105 {
106 const int offset_ai = offset_band + is_ai * xdim_is[0];
107 hamilt::Operator<T>* node(this->ops[(is_ai << 1) + is_bj]);
108 while (node != nullptr)
109 {
110 node->act(/*nband=*/1, xdim_is[is_bj], /*npol=*/1, psi_in + offset_bj, hpsi + offset_ai);
111 node = (hamilt::Operator<T>*)(node->next_op);
112 }
113 }
114 }
115 }
116 }
117 std::vector<T> matrix()const
118 {
119 ModuleBase::TITLE("HamiltULR", "matrix");
120 const std::vector<int> npairs = { this->nocc[0] * this->nvirt[0], this->nocc[1] * this->nvirt[1] };
121 const std::vector<int64_t> ldim_is = { nk * pX[0].get_local_size(), nk * pX[1].get_local_size() };
122 const std::vector<int> gdim_is = { nk * npairs[0], nk * npairs[1] };
123 std::vector<T> Amat_full(gdim * gdim);
124 for (int is_bj : {0, 1})
125 {
126 const int no = this->nocc[is_bj];
127 const int nv = this->nvirt[is_bj];
128 const auto& px = this->pX[is_bj];
129 const int loffset_bj = is_bj * ldim_is[0];
130 const int goffset_bj = is_bj * gdim_is[0];
131 for (int ik_bj = 0;ik_bj < nk;++ik_bj)
132 {
133 for (int j = 0;j < no;++j)
134 {
135 for (int b = 0;b < nv;++b)
136 {
137 const int gcol = goffset_bj + ik_bj * npairs[is_bj] + j * nv + b;//global
138 std::vector<T> X_bj(this->ldim, T(0));
139 const int lj = px.global2local_col(j);
140 const int lb = px.global2local_row(b);
141 const int lcol = loffset_bj + ik_bj * px.get_local_size() + lj * px.get_row_size() + lb;//local
142 if (px.in_this_processor(b, j)) { X_bj[lcol] = T(1); }
143 this->cal_dm_trans(is_bj, X_bj.data() + loffset_bj);
144 std::vector<T> Aloc_col(this->ldim, T(0)); // a col of A matrix (local)
145 for (int is_ai : {0, 1})
146 {
147 const int goffset_ai = is_ai * gdim_is[0];
148 const int loffset_ai = is_ai * ldim_is[0];
149 const auto& pax = this->pX[is_ai];
150 hamilt::Operator<T>* node(this->ops[(is_ai << 1) + is_bj]);
151 while (node != nullptr)
152 {
153 node->act(1, ldim_is[is_bj], /*npol=*/1, X_bj.data() + loffset_bj, Aloc_col.data() + loffset_ai);
154 node = (hamilt::Operator<T>*)(node->next_op);
155 }
156#ifdef __MPI
157 for (int ik_ai = 0;ik_ai < this->nk;++ik_ai)
158 {
159 LR_Util::gather_2d_to_full(pax, Aloc_col.data() + loffset_ai + ik_ai * pax.get_local_size(),
160 Amat_full.data() + gcol * gdim /*col, bj*/ + goffset_ai + ik_ai * npairs[is_ai]/*row, ai*/,
161 false, nv, no);
162 }
163#else
164 std::memcpy(Amat_full.data() + gcol * gdim + goffset_ai, Aloc_col.data() + goffset_ai, gdim_is[is_ai] * sizeof(T));
165#endif
166 }
167 }
168 }
169 }
170 }
171 std::cout << "Full A matrix:" << std::endl;
172 LR_Util::print_value(Amat_full.data(), gdim, gdim);
173 return Amat_full;
174 }
175
177 void global2local(T* lvec, const T* gvec, const int& nband) const
178 {
179 const std::vector<int> npairs = { this->nocc[0] * this->nvirt[0], this->nocc[1] * this->nvirt[1] };
180 const std::vector<int64_t> ldim_is = { nk * pX[0].get_local_size(), nk * pX[1].get_local_size() };
181 const std::vector<int> gdim_is = { nk * npairs[0], nk * npairs[1] };
182 for (int ib = 0;ib < nband;++ib)
183 {
184 const int loffset_b = ib * this->ldim;
185 const int goffset_b = ib * this->gdim;
186 for (int is : {0, 1})
187 {
188 const int loffset_bs = loffset_b + is * ldim_is[0];
189 const int goffset_bs = goffset_b + is * gdim_is[0];
190 for (int ik = 0;ik < nk;++ik)
191 {
192 const int loffset = loffset_bs + ik * pX[is].get_local_size();
193 const int goffset = goffset_bs + ik * npairs[is];
194 for (int lo = 0;lo < pX[is].get_col_size();++lo)
195 {
196 const int go = pX[is].local2global_col(lo);
197 for (int lv = 0;lv < pX[is].get_row_size();++lv)
198 {
199 const int gv = pX[is].local2global_row(lv);
200 lvec[loffset + lo * pX[is].get_row_size() + lv] = gvec[goffset + go * nvirt[is] + gv];
201 }
202 }
203 }
204 }
205 }
206 }
207
208 private:
209 const std::vector<int>& nocc;
210 const std::vector<int>& nvirt;
211
212 const std::vector<Parallel_2D>& pX;
213
214
215 const int nk = 1;
216 const int ldim = 1;
217 const int gdim = 1;
218
220 std::vector<hamilt::Operator<T>*> ops;
221
225 std::unique_ptr<elecstate::DensityMatrix<T, T>> DM_trans;
226
227 std::function<void(const int&, const T* const)> cal_dm_trans;
228 const bool tdm_sym = false;
229 };
230}
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:87
const int nk
Definition hamilt_ulr.hpp:215
std::unique_ptr< elecstate::DensityMatrix< T, T > > DM_trans
Definition hamilt_ulr.hpp:225
void hPsi(const T *const psi_in, T *const hpsi, const int ld_psi, const int &nband) const
Definition hamilt_ulr.hpp:91
const bool tdm_sym
whether to symmetrize the transition density matrix
Definition hamilt_ulr.hpp:228
std::vector< T > matrix() const
Definition hamilt_ulr.hpp:117
std::function< void(const int &, const T *const)> cal_dm_trans
Definition hamilt_ulr.hpp:227
const int ldim
Definition hamilt_ulr.hpp:216
const std::vector< int > & nvirt
Definition hamilt_ulr.hpp:210
void global2local(T *lvec, const T *gvec, const int &nband) const
copy global data (eigenvectors) to local memory
Definition hamilt_ulr.hpp:177
const std::vector< Parallel_2D > & pX
Definition hamilt_ulr.hpp:212
const std::vector< int > & nocc
Definition hamilt_ulr.hpp:209
std::vector< hamilt::Operator< T > * > ops
4 operator lists: uu, ud, du, dd
Definition hamilt_ulr.hpp:220
const int gdim
Definition hamilt_ulr.hpp:217
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, TGint *gint_in, 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:19
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:15
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:16
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:37
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_dngvd_test cpp endif() if(ENABLE_GOOGLEBENCH) AddTest(TARGET PERF_MODULE_HSOLVER_KERNELS LIBS parameter $
Definition CMakeLists.txt:10
Definition gint_template.h:6
const std::map< std::string, std::vector< double > > op
Definition vdwd3_autoset_xcparam.cpp:372