11#include " cal_ldos.h"
22#include " cube_io.h"
3+ #include " module_base/blas_connector.h"
4+ #include " module_base/scalapack_connector.h"
35
4- void ModuleIO::cal_ldos (const elecstate::ElecStatePW<std::complex <double >>* pelec,
5- const psi::Psi<std::complex <double >>& psi,
6- const Parallel_Grid& pgrid,
7- const UnitCell& ucell)
6+ #include < type_traits>
7+
8+ namespace ModuleIO
9+ {
10+ template <typename T>
11+ void Cal_ldos<T>::cal_ldos_pw(const elecstate::ElecStatePW<std::complex <double >>* pelec,
12+ const psi::Psi<std::complex <double >>& psi,
13+ const Parallel_Grid& pgrid,
14+ const UnitCell& ucell)
815{
916 // energy range for ldos (efermi as reference)
1017 const double emin = PARAM.inp .stm_bias < 0 ? PARAM.inp .stm_bias : 0 ;
@@ -16,13 +23,13 @@ void ModuleIO::cal_ldos(const elecstate::ElecStatePW<std::complex<double>>* pele
1623 for (int ik = 0 ; ik < pelec->klist ->get_nks (); ++ik)
1724 {
1825 psi.fix_k (ik);
19- double efermi = pelec->eferm .get_efval (pelec->klist ->isk [ik]);
26+ const double efermi = pelec->eferm .get_efval (pelec->klist ->isk [ik]);
2027 int nbands = psi.get_nbands ();
2128
2229 for (int ib = 0 ; ib < nbands; ib++)
2330 {
2431 pelec->basis ->recip2real (&psi (ib, 0 ), wfcr.data (), ik);
25- double eigenval = (pelec->ekb (ik, ib) - efermi) * ModuleBase::Ry_to_eV;
32+ const double eigenval = (pelec->ekb (ik, ib) - efermi) * ModuleBase::Ry_to_eV;
2633 if (eigenval >= emin && eigenval <= emax)
2734 {
2835 for (int ir = 0 ; ir < pelec->basis ->nrxx ; ir++)
@@ -38,5 +45,90 @@ void ModuleIO::cal_ldos(const elecstate::ElecStatePW<std::complex<double>>* pele
3845 << " LDOS_" << PARAM.inp .stm_bias << " eV"
3946 << " .cube" ;
4047
41- ModuleIO::write_vdata_palgrid (pgrid, ldos.data (), 0 , PARAM.inp .nspin , 0 , fn.str (), 0 , &ucell, 11 , 0 );
48+ const int precision = PARAM.inp .out_ldos [1 ];
49+ ModuleIO::write_vdata_palgrid (pgrid, ldos.data (), 0 , PARAM.inp .nspin , 0 , fn.str (), 0 , &ucell, precision, 0 );
50+ }
51+
52+ #ifdef __LCAO
53+ template <typename T>
54+ void Cal_ldos<T>::cal_ldos_lcao(const elecstate::ElecStateLCAO<T>* pelec,
55+ const psi::Psi<T>& psi,
56+ const Parallel_Grid& pgrid,
57+ const UnitCell& ucell)
58+ {
59+ // energy range for ldos (efermi as reference)
60+ const double emin = PARAM.inp .stm_bias < 0 ? PARAM.inp .stm_bias : 0 ;
61+ const double emax = PARAM.inp .stm_bias > 0 ? PARAM.inp .stm_bias : 0 ;
62+
63+ // calulate dm-like
64+ const int nbands_local = psi.get_nbands ();
65+ const int nbasis_local = psi.get_nbasis ();
66+
67+ // psi.T * wk * psi.conj()
68+ // result[ik](iw1,iw2) = \sum_{ib} psi[ik](ib,iw1).T * wk(k) * psi[ik](ib,iw2).conj()
69+ for (int ik = 0 ; ik < psi.get_nk (); ++ik)
70+ {
71+ psi.fix_k (ik);
72+ const double efermi = pelec->eferm .get_efval (pelec->klist ->isk [ik]);
73+
74+ // T* dmk_pointer = DM.get_DMK_pointer(ik);
75+
76+ psi::Psi<T> wk_psi (1 , psi.get_nbands (), psi.get_nbasis (), psi.get_nbasis (), true );
77+ const T* ppsi = psi.get_pointer ();
78+ T* pwk_psi = wk_psi.get_pointer ();
79+
80+ // #ifdef _OPENMP
81+ // #pragma omp parallel for schedule(static, 1024)
82+ // #endif
83+ // for (int i = 0; i < wk_psi.size(); ++i)
84+ // {
85+ // pwk_psi[i] = my_conj(ppsi[i]);
86+ // }
87+
88+ // int ib_global = 0;
89+ // for (int ib_local = 0; ib_local < nbands_local; ++ib_local)
90+ // {
91+ // while (ib_local != ParaV->global2local_col(ib_global))
92+ // {
93+ // ++ib_global;
94+ // if (ib_global >= wg.nc)
95+ // {
96+ // ModuleBase::WARNING_QUIT("cal_ldos", "please check global2local_col!");
97+ // }
98+ // }
99+
100+ // const double eigenval = (pelec->ekb(ik, ib_global) - efermi) * ModuleBase::Ry_to_eV;
101+ // if (eigenval >= emin && eigenval <= emax)
102+ // {
103+ // for (int ir = 0; ir < pelec->basis->nrxx; ir++)
104+ // ldos[ir] += pelec->klist->wk[ik] * norm(wfcr[ir]);
105+ // }
106+
107+ // double* wg_wfc_pointer = &(wk_psi(0, ib_local, 0));
108+ // BlasConnector::scal(nbasis_local, pelec->klist->wk[ik], wg_wfc_pointer, 1);
109+ // }
110+
111+ // // C++: dm(iw1,iw2) = psi(ib,iw1).T * wk_psi(ib,iw2)
112+ // #ifdef __MPI
113+ // psiMulPsiMpi(wk_psi, psi, dmk_pointer, ParaV->desc_wfc, ParaV->desc);
114+ // #else
115+ // psiMulPsi(wk_psi, psi, dmk_pointer);
116+ // #endif
117+ }
118+ }
119+
120+ double my_conj (double x)
121+ {
122+ return x;
42123}
124+
125+ std::complex <double > my_conj (const std::complex <double >& z)
126+ {
127+ return {z.real (), -z.imag ()};
128+ }
129+
130+ #endif
131+
132+ template class Cal_ldos <double >; // Gamma_only case
133+ template class Cal_ldos <std::complex <double >>; // multi-k case
134+ } // namespace ModuleIO
0 commit comments