ABACUS develop
Atomic-orbital Based Ab-initio Computation at UStc
Loading...
Searching...
No Matches
diago_mock.h
Go to the documentation of this file.
1#include<random>
2#include "mpi.h"
5
6namespace DIAGOTEST
7{
8 std::vector<double> hmatrix_d;
9 std::vector<double> hmatrix_local_d;
10 std::vector<std::complex<double>> hmatrix;
11 std::vector<std::complex<double>> hmatrix_local;
12 std::vector<std::complex<float>> hmatrix_f;
13 std::vector<std::complex<float>> hmatrix_local_f;
14 int h_nr;
15 int h_nc;
16 int npw;
17 int* npw_local; //number of plane wave distributed to each process
18
19 void readh(std::ifstream& inf, std::vector<double>& hm)
20 {
21 int npw_;
22 inf >> npw_;
23 DIAGOTEST::npw = npw_;
24 hm.resize(npw * npw);
25 h_nr = npw;
26 h_nc = npw;
27 for (int i = 0;i < npw;i++)
28 {
29 for (int j = i;j < npw;j++)
30 {
31 inf >> hm[i * npw + j];
32 if (i != j) { hm[j * npw + i] = hm[i * npw + j]; }
33 }
34 }
35 }
36
37 void readh(std::ifstream& inf, std::vector<std::complex<double>>& hm)
38 {
39 int npw_;
40 inf >> npw_;
41 DIAGOTEST::npw = npw_;
42 hm.resize(npw * npw);
43 h_nr = npw;
44 h_nc = npw;
45 for(int i=0;i<npw;i++)
46 {
47 for(int j=i;j<npw;j++)
48 {
49 inf >> hm[i * npw + j];
50 if (i != j) {hm[j * npw + i] = conj(hm[i * npw + j]);}
51 }
52 double real = hm[i * npw + i].real();
53 hm[i * npw + i] = std::complex<double> {real,0.0};
54 }
55 }
56
57 void readh(std::ifstream &inf, std::vector<std::complex<float>> &hm)
58 {
59 int npw_;
60 inf >> npw_;
61 DIAGOTEST::npw = npw_;
62 hm.resize(npw * npw);
63 h_nr = npw;
64 h_nc = npw;
65 for(int i=0;i<npw;i++)
66 {
67 for(int j=i;j<npw;j++)
68 {
69 inf >> hm[i * npw + j];
70 if (i != j) {hm[j * npw + i] = conj(hm[i * npw + j]);}
71 }
72 float real = hm[i * npw + i].real();
73 hm[i * npw + i] = std::complex<float> {real,0.0};
74 }
75 }
76
77 template<class T>
78 void divide_psi(T *psi, T *psi_local)
79 {
80 int nprocs=1, mypnum=0;
81#ifdef __MPI
82 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
83 MPI_Comm_rank(MPI_COMM_WORLD, &mypnum);
84#endif
85
86 if(mypnum == 0)
87 {
88 for(int j=0;j<npw_local[0];j++) { psi_local[j] = psi[j];
89}
90#ifdef __MPI
91 int start_point = npw_local[0];
92 for(int j=1;j<nprocs;j++)
93 {
94 if (std::is_same<T, double>::value) {
95 MPI_Send(&(psi[start_point]),npw_local[j],MPI_DOUBLE,j,0,MPI_COMM_WORLD);
96 } else if(std::is_same<T, std::complex<double>>::value) {
97 MPI_Send(&(psi[start_point]),npw_local[j],MPI_DOUBLE_COMPLEX,j,0,MPI_COMM_WORLD);
98 } else if (std::is_same<T, float>::value) {
99 MPI_Send(&(psi[start_point]), npw_local[j], MPI_FLOAT, j, 0, MPI_COMM_WORLD);
100 } else if (std::is_same<T, std::complex<float>>::value) {
101 MPI_Send(&(psi[start_point]), npw_local[j], MPI_C_FLOAT_COMPLEX, j, 0, MPI_COMM_WORLD);
102}
103 start_point += npw_local[j];
104 }
105 }
106 else
107 {
108 int recv_len = mypnum < (npw%nprocs) ? npw/nprocs + 1 : npw/nprocs;
109 if (std::is_same<T, double>::value) {
110 MPI_Recv(psi_local, npw_local[mypnum],MPI_DOUBLE,0,0,MPI_COMM_WORLD, MPI_STATUS_IGNORE);
111 } else if(std::is_same<T, std::complex<double>>::value) {
112 MPI_Recv(psi_local, npw_local[mypnum], MPI_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
113 } else if (std::is_same<T, float>::value) {
114 MPI_Recv(psi_local, npw_local[mypnum], MPI_FLOAT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
115 } else if (std::is_same<T, std::complex<float>>::value) {
116 MPI_Recv(psi_local, npw_local[mypnum], MPI_C_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
117}
118#endif
119 }
120 }
121 template void divide_psi<double>(double* psi, double* psi_local);
122 template void divide_psi<std::complex<double>>(std::complex<double>* psi, std::complex<double>* psi_local);
123 template void divide_psi<std::complex<float>>(std::complex<float>* psi, std::complex<float>* psi_local);
124#ifdef __MPI
125 void cal_division(int &npw)
126 {
127 int nprocs, mypnum;
128 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
129 MPI_Comm_rank(MPI_COMM_WORLD, &mypnum);
130 for(int i=0;i<nprocs;i++)
131 {
132 if(i<npw%nprocs) { npw_local[i] = npw/nprocs + 1;
133 } else { npw_local[i] = npw/nprocs;
134}
135 }
136 }
137
138 template<typename T>
139 void divide_hpsi(psi::Psi<T>& psi, psi::Psi<T>& psi_local, std::vector<T>& hmatrix, std::vector<T>& hmatrix_local)
140 {
141 int nprocs, mypnum;
142 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
143 MPI_Comm_rank(MPI_COMM_WORLD, &mypnum);
144
145 int npw = psi.get_nbasis();
146 int nbands = psi.get_nbands();
147 int nk = psi.get_nk();
148
149 hmatrix_local.resize(npw * npw_local[mypnum]);
150 h_nc = npw_local[mypnum];
151 h_nr = npw;
152 psi_local.resize(nk,nbands,npw_local[mypnum]);
153 for(int i=0;i<npw;i++)
154 {
155 divide_psi<T>(&(hmatrix[i * npw]), &(hmatrix_local[i * npw_local[mypnum]]));
156 if(i<nbands)
157 {
158 for(int k=0;k<nk;k++)
159 {
160 psi.fix_k(k);
161 psi_local.fix_k(k);
162 divide_psi<T>(psi.get_pointer(i), psi_local.get_pointer(i));
163 }
164 }
165 }
166 }
167#endif
168}
169
170#include "source_base/macros.h"
171template<typename T>
172class HPsi
173{
192 using Real = typename GetTypeReal<T>::type;
193 public:
196 HPsi(){};
197 ~HPsi() {delete [] precondition;}
198
199 void create(int nbd,int npw, int sparsity=7)
200 {
201 this->nband = nbd;
202 this->npw = npw;
203 this->sparsity = sparsity;
205 }
206
207 //return the matrix
208 Real* precond() { return precondition; }
209 std::vector<T> hamilt() { return hmatrix; }
210 //ModuleBase::ComplexMatrix psi() {return psimatrix;}
212 {
214 int* ngk = nullptr;
215 psi::Psi<T> psitmp(1, nband, npw, npw, true);
216 for(int i=0;i<nband;i++)
217 {
218 for(int j=0;j<npw;j++) { psitmp(0,i,j) = psimatrix[i * npw + j];
219}
220 }
221 return psitmp;
222 };
223
224 //generate the Hermite matrix
226
227 //generate the psi matrix
228 void genpsi();
229
230 //generate precondition
232 {
233 precondition = new Real[npw];
234 std::default_random_engine e(1000);
235 std::uniform_int_distribution<unsigned> u(min, max);
236 for (int i = 0;i < npw;i++)
237 {
238 precondition[i] = 1.0 + static_cast<Real>(u(e)) / max;
239 }
240 }
241
242private:
243 int npw;
244 int nband;
245 std::vector<T> hmatrix;
246 std::vector<T> psimatrix;
248 int min = 0;
249 int max = 9999;
251};
252
253template<>
255{
256 hmatrix.resize(npw * npw);
257 DIAGOTEST::h_nr = npw;
258 DIAGOTEST::h_nc = npw;
259 std::default_random_engine e(100);
260 std::uniform_int_distribution<unsigned> u(min, max);
261 if (sparsity < 0) { sparsity = 0;
262}
263 if (sparsity > 10) { sparsity = 10;
264}
265 for (int i = 0;i < npw;i++)
266 {
267 for (int j = 0;j <= i;j++)
268 {
269 double mincoef = 0.0;
270 double realp = pow(-1.0, u(e) % 2) * static_cast<double>(u(e)) / max;
271 if (int(u(e) % 10) > int(sparsity - 1)) { mincoef = 1.0;
272}
273 if (i == j) {
274 hmatrix[i * npw + j] = realp;
275 } else {
276 hmatrix[j * npw + i] = hmatrix[i * npw + j] = mincoef * realp;
277}
278 }
279 }
280}
281template<>
282void HPsi<std::complex<double>>::genhmatrix()
283{
284 hmatrix.resize(npw * npw);
285 DIAGOTEST::h_nr = npw;
286 DIAGOTEST::h_nc = npw;
287 std::default_random_engine e(100);
288 std::uniform_int_distribution<unsigned> u(min, max);
289 if (sparsity < 0) { sparsity = 0;
290}
291 if (sparsity > 10) { sparsity = 10;
292}
293 for (int i = 0;i < npw;i++)
294 {
295 for (int j = 0;j <= i;j++)
296 {
297 double mincoef = 0.0;
298 double realp = pow(-1.0, u(e) % 2) * static_cast<double>(u(e)) / max;
299 //double imagp= pow(-1.0,u(e)%2) * static_cast<double>(u(e))/max;
300 if (int(u(e) % 10) > int(sparsity - 1)) { mincoef = 1.0;
301}
302 if (i == j)
303 {
304 hmatrix[i * npw + j] = std::complex<double>{ realp,0.0 };
305 }
306 else
307 {
308 //hmatrix(i,j) = mincoef*std::complex<double>{realp,imagp};
309 hmatrix[i * npw + j] = mincoef * std::complex<double>{ realp, 0.0 };
310 hmatrix[j * npw + i] = conj(hmatrix[i * npw + j]);
311 }
312 }
313 }
314}
315template<>
316void HPsi<std::complex<float>>::genhmatrix()
317{
318 hmatrix.resize(npw * npw);
319 DIAGOTEST::h_nr = npw;
320 DIAGOTEST::h_nc = npw;
321 std::default_random_engine e(100);
322 std::uniform_int_distribution<unsigned> u(min, max);
323 if (sparsity < 0) { sparsity = 0;
324}
325 if (sparsity > 10) { sparsity = 10;
326}
327 for (int i = 0;i < npw;i++)
328 {
329 for (int j = 0;j <= i;j++)
330 {
331 float mincoef = 0.0;
332 float realp = pow(-1.0, u(e) % 2) * static_cast<float>(u(e)) / max;
333 if (int(u(e) % 10) > int(sparsity - 1)) { mincoef = 1.0;
334}
335 if (i == j)
336 {
337 hmatrix[i * npw + j] = std::complex<float>{ realp,0.0 };
338 }
339 else
340 {
341 hmatrix[i * npw + j] = mincoef * std::complex<float>{ realp, 0.0 };
342 hmatrix[j * npw + i] = conj(hmatrix[i * npw + j]);
343 }
344 }
345 }
346}
347
348template<>
350{
351 {
352 psimatrix.resize(nband * npw);
353 std::default_random_engine e(10);
354 std::uniform_int_distribution<unsigned> u(min, max);
355 for (int i = 0;i < nband;i++) {
356 for (int j = 0;j < npw;j++) {
357 psimatrix[i * npw + j] = pow(-1.0, u(e) % 2) * static_cast<double>(u(e)) / max;
358}
359}
360 }
361}
362template<>
364{
365 {
366 psimatrix.resize(nband * npw);
367 std::default_random_engine e(10);
368 std::uniform_int_distribution<unsigned> u(min, max);
369 for (int i = 0;i < nband;i++)
370 {
371 for (int j = 0;j < npw;j++)
372 {
373 double realp = pow(-1.0, u(e) % 2) * static_cast<double>(u(e)) / max;
374 //double imagp=pow(-1.0,u(e)%2) * static_cast<double>(u(e))/max;
375 double imagp = 0.0;
376 psimatrix[i * npw + j] = std::complex<double>{ realp,imagp };
377 }
378 }
379 }
380}
381template<>
383{
384 {
385 psimatrix.resize(nband * npw);
386 std::default_random_engine e(10);
387 std::uniform_int_distribution<unsigned> u(min, max);
388 for (int i = 0;i < nband;i++)
389 {
390 for (int j = 0;j < npw;j++)
391 {
392 float realp = pow(-1.0, u(e) % 2) * static_cast<float>(u(e)) / max;
393 float imagp = 0.0;
394 psimatrix[i * npw + j] = std::complex<float>{ realp,imagp };
395 }
396 }
397 }
398}
399
400template class HPsi<double>;
401template class HPsi<std::complex<double>>;
402template class HPsi<std::complex<float>>;
403
404//totally same as the original function
405template <>
407 double* spsi,
408 const int nrow,
409 const int npw,
410 const int nbands) const
411{
412 for (size_t i = 0; i < static_cast<size_t>(nbands * nrow); i++)
413 {
414 spsi[i] = psi_in[i];
415 }
416 return;
417}
418template <>
419void hamilt::HamiltPW<std::complex<double>, base_device::DEVICE_CPU>::sPsi(const std::complex<double>* psi_in,
420 std::complex<double>* spsi,
421 const int nrow,
422 const int npw,
423 const int nbands) const
424{
425 for (size_t i = 0; i < static_cast<size_t>(nbands * nrow); i++)
426 {
427 spsi[i] = psi_in[i];
428 }
429 return;
430}
431template <>
432void hamilt::HamiltPW<std::complex<float>, base_device::DEVICE_CPU>::sPsi(const std::complex<float>* psi_in,
433 std::complex<float>* spsi,
434 const int nrow,
435 const int npw,
436 const int nbands) const
437{
438 for (size_t i = 0; i < static_cast<size_t>(nbands * nrow); i++)
439 {
440 spsi[i] = psi_in[i];
441 }
442 return;
443}
444
445//Mock function h_psi
447template<typename T>
449{
451 {
452 if(this->hpsi != nullptr)
453 {
454 delete this->hpsi;
455 this->hpsi = nullptr;
456 }
457 }
458 virtual void act
459 (
460 const int nbands,
461 const int nbasis,
462 const int npol,
463 const T* tmpsi_in,
464 T* tmhpsi,
465 const int ngk_ik = 0,
466 const bool is_first_node = false)const;
467};
468template<>
470 const int nbands,
471 const int nbasis,
472 const int npol,
473 const double* tmpsi_in,
474 double* tmhpsi,
475 const int ngk_ik,
476 const bool is_first_node)const
477{
478 int nprocs = 1, mypnum = 0;
479#ifdef __MPI
480 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
481 MPI_Comm_rank(MPI_COMM_WORLD, &mypnum);
482#endif
483
484 double* hpsi0 = new double[DIAGOTEST::npw];
485 for (int m = 0; m < nbands; m++)
486 {
487 for (int i = 0;i < DIAGOTEST::npw;i++)
488 {
489 hpsi0[i] = 0.0;
490 for (int j = 0;j < (DIAGOTEST::npw_local[mypnum]);j++)
491 {
492 hpsi0[i] += DIAGOTEST::hmatrix_local_d[i * DIAGOTEST::h_nc + j] * tmpsi_in[j];
493 }
494 }
496 DIAGOTEST::divide_psi<double>(hpsi0, tmhpsi);
497 tmhpsi += nbasis;
498 tmpsi_in += nbasis;
499 }
500 delete[] hpsi0;
501}
502template<>
504 const int nbands,
505 const int nbasis,
506 const int npol,
507 const std::complex<double>* tmpsi_in,
508 std::complex<double>* tmhpsi,
509 const int ngk_ik,
510 const bool is_first_node)const
511{
512 int nprocs = 1, mypnum = 0;
513#ifdef __MPI
514 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
515 MPI_Comm_rank(MPI_COMM_WORLD, &mypnum);
516#endif
517
518 std::complex<double>* hpsi0 = new std::complex<double>[DIAGOTEST::npw];
519 for (int m = 0; m < nbands; m++)
520 {
521 for (int i = 0;i < DIAGOTEST::npw;i++)
522 {
523 hpsi0[i] = 0.0;
524 for (int j = 0;j < (DIAGOTEST::npw_local[mypnum]);j++)
525 {
526 hpsi0[i] += DIAGOTEST::hmatrix_local[i * DIAGOTEST::h_nc + j] * tmpsi_in[j];
527 }
528 }
530 DIAGOTEST::divide_psi<std::complex<double>>(hpsi0, tmhpsi);
531 tmhpsi += nbasis;
532 tmpsi_in += nbasis;
533 }
534 delete[] hpsi0;
535}
536template<>
538 const int nbands,
539 const int nbasis,
540 const int npol,
541 const std::complex<float>* tmpsi_in,
542 std::complex<float>* tmhpsi,
543 const int ngk_ik,
544 const bool is_first_node)const
545{
546 int nprocs = 1, mypnum = 0;
547#ifdef __MPI
548 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
549 MPI_Comm_rank(MPI_COMM_WORLD, &mypnum);
550#endif
551
552 std::complex<float>* hpsi0 = new std::complex<float>[DIAGOTEST::npw];
553 for (int m = 0; m < nbands; m++)
554 {
555 for (int i = 0;i < DIAGOTEST::npw;i++)
556 {
557 hpsi0[i] = 0.0;
558 for (int j = 0;j < (DIAGOTEST::npw_local[mypnum]);j++)
559 {
560 hpsi0[i] += DIAGOTEST::hmatrix_local_f[i * DIAGOTEST::h_nc + j] * tmpsi_in[j];
561 }
562 }
564 DIAGOTEST::divide_psi<std::complex<float>>(hpsi0, tmhpsi);
565 tmhpsi += nbasis;
566 tmpsi_in += nbasis;
567 }
568 delete[] hpsi0;
569}
570template<> void hamilt::HamiltPW<double>::updateHk(const int ik)
571{
572 return;
573}
574
579
581{
582 delete this->ops;
583}
584
585template<> void hamilt::HamiltPW<std::complex<double>>::updateHk(const int ik)
586{
587 return;
588}
589
594
596{
597 delete this->ops;
598}
599
600template<> void hamilt::HamiltPW<std::complex<float>>::updateHk(const int ik)
601{
602 return;
603}
604
609
611{
612 delete this->ops;
613}
#define min(x, y)
Definition branred.cpp:18
#define max(x, y)
Definition branred.cpp:17
Definition diago_mock.h:173
int npw
Definition diago_mock.h:243
std::vector< T > psimatrix
Definition diago_mock.h:246
Real * precond()
Definition diago_mock.h:208
void genhmatrix()
std::vector< T > hamilt()
Definition diago_mock.h:209
HPsi()
Definition diago_mock.h:196
void create(int nbd, int npw, int sparsity=7)
Definition diago_mock.h:199
int nband
Definition diago_mock.h:244
int sparsity
Definition diago_mock.h:250
std::vector< T > hmatrix
Definition diago_mock.h:245
void genprecondition()
Definition diago_mock.h:231
HPsi(int nband, int npw, int sparsity=7)
Definition diago_mock.h:194
~HPsi()
Definition diago_mock.h:197
void genpsi()
int max
Definition diago_mock.h:249
typename GetTypeReal< T >::type Real
Definition diago_mock.h:192
Real * precondition
Definition diago_mock.h:247
int min
Definition diago_mock.h:248
psi::Psi< T > psi()
Definition diago_mock.h:211
Definition klist.h:13
Special pw_basis class. It includes different k-points.
Definition pw_basis_k.h:57
Definition diago_mock.h:449
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
~OperatorMock()
Definition diago_mock.h:450
Definition structure_factor.h:11
Definition unitcell.h:16
Definition potential_new.h:48
Definition hamilt_pw.h:18
void updateHk(const int ik) override
for target K point, update consequence of hPsi() and matrix()
Definition hamilt_pw.cpp:148
~HamiltPW()
Definition hamilt_pw.cpp:139
HamiltPW(elecstate::Potential *pot_in, ModulePW::PW_Basis_K *wfc_basis, K_Vectors *p_kv, pseudopot_cell_vnl *nlpp, const UnitCell *ucell)
Definition hamilt_pw.cpp:21
void sPsi(const T *psi_in, T *spsi, const int nrow, const int npw, const int nbands) const override
Definition hamilt_pw.cpp:236
Definition operator.h:38
psi::Psi< T, Device > * hpsi
Definition operator.h:112
bool is_first_node
Definition operator.h:109
Definition VNL_in_pw.h:21
Definition psi.h:37
void resize(const int nks_in, const int nbands_in, const int nbasis_in)
Definition psi.cpp:254
T * get_pointer() const
Definition psi.cpp:272
void fix_k(const int ik) const
Definition psi.cpp:364
#define T
Definition exp.cpp:237
Definition diago_mock.h:7
std::vector< std::complex< float > > hmatrix_f
Definition diago_mock.h:12
std::vector< std::complex< double > > hmatrix
Definition diago_mock.h:10
int npw
Definition diago_mock.h:16
int h_nc
Definition diago_mock.h:15
void cal_division(int &npw)
Definition diago_mock.h:125
void divide_psi(T *psi, T *psi_local)
Definition diago_mock.h:78
void readh(std::ifstream &inf, std::vector< double > &hm)
Definition diago_mock.h:19
std::vector< double > hmatrix_d
Definition diago_mock.h:8
int * npw_local
Definition diago_mock.h:17
std::vector< std::complex< float > > hmatrix_local_f
Definition diago_mock.h:13
std::vector< double > hmatrix_local_d
Definition diago_mock.h:9
std::vector< std::complex< double > > hmatrix_local
Definition diago_mock.h:11
template void divide_psi< double >(double *psi, double *psi_local)
int h_nr
Definition diago_mock.h:14
void divide_hpsi(psi::Psi< T > &psi, psi::Psi< T > &psi_local, std::vector< T > &hmatrix, std::vector< T > &hmatrix_local)
Definition diago_mock.h:139
void reduce_pool(T &object)
Definition depend_mock.cpp:15
Definition exx_lip.h:23
double conj(double a)
Definition operator_lr_hxc.cpp:14
T type
Definition macros.h:8