1818// / nspin=4 (npol=2): spinor calculation;
1919// / occ_mat has a single matrix of size (2*tlp1) x (2*tlp1) per atom
2020// / storing all 4 Pauli blocks contiguously.
21- void Plus_U_Base::cal_occ_pw (const int iter,
22- const void * psi_in,
21+ void Plus_U_Base::cal_occ_pw (const void * psi_in,
2322 const ModuleBase::matrix& wg_in,
2423 const UnitCell& cell,
2524 Charge_Mixing* p_chgmix,
@@ -31,160 +30,12 @@ void Plus_U_Base::cal_occ_pw(const int iter,
3130
3231 if (this ->device == " cpu" )
3332 {
34- auto * onsite_p = projectors::OnsiteProjector<double , base_device::DEVICE_CPU >::get_instance ();
35- const psi::Psi<std::complex <double >>* psi_p = (const psi::Psi<std::complex <double >>*)psi_in;
36- const int nbands = psi_p->get_nbands ();
37- const int npol = psi_p->get_npol ();
38- for (int ik = 0 ; ik < psi_p->get_nk (); ik++)
39- {
40- int is = (this ->nspin == 2 ) ? isk[ik] : 0 ;
41- psi_p->fix_k (ik);
42- onsite_p->tabulate_atomic (ik);
43-
44- onsite_p->overlap_proj_psi (nbands*npol, psi_p->get_pointer ());
45- const std::complex <double >* becp = onsite_p->get_h_becp ();
46- int nkb = onsite_p->get_size_becp () / nbands / npol;
47-
48- int begin_ih = 0 ;
49- for (int iat = 0 ; iat < cell.nat ; iat++)
50- {
51- const int it = cell.iat2it [iat];
52- const int nh = onsite_p->get_nh (iat);
53- const int target_l = get_orbital_corr (it);
54- if (!has_correlated_orbital (it))
55- {
56- begin_ih += nh;
57- continue ;
58- }
59- const int m_begin = target_l * target_l;
60- const int tlp1 = 2 * target_l + 1 ;
61- const int tlp1_2 = tlp1 * tlp1;
62- if (this ->nspin == 4 )
63- {
64- for (int ib = 0 ;ib<nbands;ib++)
65- {
66- const double weight = wg_in (ik, ib);
67- int ind_m1m2 = 0 ;
68- for (int m1 = 0 ; m1 < tlp1; m1++)
69- {
70- const int index_m1 = ib*npol*nkb + begin_ih + m_begin + m1;
71- for (int m2 = 0 ; m2 < tlp1; m2++)
72- {
73- const int index_m2 = ib*npol*nkb + begin_ih + m_begin + m2;
74- std::complex <double > occ[4 ];
75- occ[0 ] = weight * conj (becp[index_m1]) * becp[index_m2];
76- occ[1 ] = weight * conj (becp[index_m1]) * becp[index_m2 + nkb];
77- occ[2 ] = weight * conj (becp[index_m1 + nkb]) * becp[index_m2];
78- occ[3 ] = weight * conj (becp[index_m1 + nkb]) * becp[index_m2 + nkb];
79- this ->occ_mat [iat][target_l][0 ][0 ].c [ind_m1m2] += (occ[0 ] + occ[3 ]).real ();
80- this ->occ_mat [iat][target_l][0 ][0 ].c [ind_m1m2 + tlp1_2] += (occ[1 ] + occ[2 ]).real ();
81- this ->occ_mat [iat][target_l][0 ][0 ].c [ind_m1m2 + 2 * tlp1_2] += (occ[1 ] - occ[2 ]).imag ();
82- this ->occ_mat [iat][target_l][0 ][0 ].c [ind_m1m2 + 3 * tlp1_2] += (occ[0 ] - occ[3 ]).real ();
83- ind_m1m2++;
84- }
85- }
86- }// ib
87- }
88- else // nspin=1 or nspin=2
89- {
90- for (int ib = 0 ;ib<nbands;ib++)
91- {
92- const double weight = wg_in (ik, ib);
93- int ind_m1m2 = 0 ;
94- for (int m1 = 0 ; m1 < tlp1; m1++)
95- {
96- const int index_m1 = ib*nkb + begin_ih + m_begin + m1;
97- for (int m2 = 0 ; m2 < tlp1; m2++)
98- {
99- const int index_m2 = ib*nkb + begin_ih + m_begin + m2;
100- this ->occ_mat [iat][target_l][0 ][is].c [ind_m1m2] += weight * (conj (becp[index_m1]) * becp[index_m2]).real ();
101- ind_m1m2++;
102- }
103- }
104- }// ib
105- }
106- begin_ih += nh;
107- }// iat
108-
109- }// ik
33+ this ->accumulate_occ_one_k <base_device::DEVICE_CPU >(psi_in, wg_in, cell, isk);
11034 }
11135#if defined(__CUDA) || defined(__ROCM)
11236 else
11337 {
114- auto * onsite_p = projectors::OnsiteProjector<double , base_device::DEVICE_GPU >::get_instance ();
115- const psi::Psi<std::complex <double >, base_device::DEVICE_GPU >* psi_p = (const psi::Psi<std::complex <double >, base_device::DEVICE_GPU >*)psi_in;
116- const int nbands = psi_p->get_nbands ();
117- const int npol = psi_p->get_npol ();
118- for (int ik = 0 ; ik < psi_p->get_nk (); ik++)
119- {
120- int is = (this ->nspin == 2 ) ? isk[ik] : 0 ;
121- psi_p->fix_k (ik);
122- onsite_p->tabulate_atomic (ik);
123-
124- onsite_p->overlap_proj_psi (nbands*npol, psi_p->get_pointer ());
125- const std::complex <double >* becp = onsite_p->get_h_becp ();
126- int nkb = onsite_p->get_size_becp () / nbands / npol;
127- int begin_ih = 0 ;
128- for (int iat = 0 ; iat < cell.nat ; iat++)
129- {
130- const int it = cell.iat2it [iat];
131- const int nh = onsite_p->get_nh (iat);
132- const int target_l = get_orbital_corr (it);
133- if (!has_correlated_orbital (it))
134- {
135- begin_ih += nh;
136- continue ;
137- }
138- const int m_begin = target_l * target_l;
139- const int tlp1 = 2 * target_l + 1 ;
140- const int tlp1_2 = tlp1 * tlp1;
141- if (this ->nspin == 4 )
142- {
143- for (int ib = 0 ;ib<nbands;ib++)
144- {
145- const double weight = wg_in (ik, ib);
146- int ind_m1m2 = 0 ;
147- for (int m1 = 0 ; m1 < tlp1; m1++)
148- {
149- const int index_m1 = ib*npol*nkb + begin_ih + m_begin + m1;
150- for (int m2 = 0 ; m2 < tlp1; m2++)
151- {
152- const int index_m2 = ib*npol*nkb + begin_ih + m_begin + m2;
153- std::complex <double > occ[4 ];
154- occ[0 ] = weight * conj (becp[index_m1]) * becp[index_m2];
155- occ[1 ] = weight * conj (becp[index_m1]) * becp[index_m2 + nkb];
156- occ[2 ] = weight * conj (becp[index_m1 + nkb]) * becp[index_m2];
157- occ[3 ] = weight * conj (becp[index_m1 + nkb]) * becp[index_m2 + nkb];
158- this ->occ_mat [iat][target_l][0 ][0 ].c [ind_m1m2] += (occ[0 ] + occ[3 ]).real ();
159- this ->occ_mat [iat][target_l][0 ][0 ].c [ind_m1m2 + tlp1_2] += (occ[1 ] + occ[2 ]).real ();
160- this ->occ_mat [iat][target_l][0 ][0 ].c [ind_m1m2 + 2 * tlp1_2] += (occ[1 ] - occ[2 ]).imag ();
161- this ->occ_mat [iat][target_l][0 ][0 ].c [ind_m1m2 + 3 * tlp1_2] += (occ[0 ] - occ[3 ]).real ();
162- ind_m1m2++;
163- }
164- }
165- }// ib
166- }
167- else // nspin=1 or nspin=2
168- {
169- for (int ib = 0 ;ib<nbands;ib++)
170- {
171- const double weight = wg_in (ik, ib);
172- int ind_m1m2 = 0 ;
173- for (int m1 = 0 ; m1 < tlp1; m1++)
174- {
175- const int index_m1 = ib*nkb + begin_ih + m_begin + m1;
176- for (int m2 = 0 ; m2 < tlp1; m2++)
177- {
178- const int index_m2 = ib*nkb + begin_ih + m_begin + m2;
179- this ->occ_mat [iat][target_l][0 ][is].c [ind_m1m2] += weight * (conj (becp[index_m1]) * becp[index_m2]).real ();
180- ind_m1m2++;
181- }
182- }
183- }// ib
184- }
185- begin_ih += nh;
186- }// iat
187- }// ik
38+ this ->accumulate_occ_one_k <base_device::DEVICE_GPU >(psi_in, wg_in, cell, isk);
18839 }
18940#endif
19041
@@ -347,3 +198,95 @@ void Plus_U_Base::cal_occ_pw(const int iter,
347198
348199 ModuleBase::timer::end (" Plus_U_Base" , " cal_occ_pw" );
349200}
201+
202+ template <typename Device>
203+ void Plus_U_Base::accumulate_occ_one_k (const void * psi_in,
204+ const ModuleBase::matrix& wg_in,
205+ const UnitCell& cell,
206+ const int * isk)
207+ {
208+ auto * onsite_p = projectors::OnsiteProjector<double , Device>::get_instance ();
209+ const psi::Psi<std::complex <double >, Device>* psi_p =
210+ (const psi::Psi<std::complex <double >, Device>*)psi_in;
211+ const int nbands = psi_p->get_nbands ();
212+ const int npol = psi_p->get_npol ();
213+ for (int ik = 0 ; ik < psi_p->get_nk (); ik++)
214+ {
215+ int is = (this ->nspin == 2 ) ? isk[ik] : 0 ;
216+ psi_p->fix_k (ik);
217+ onsite_p->tabulate_atomic (ik);
218+
219+ onsite_p->overlap_proj_psi (nbands*npol, psi_p->get_pointer ());
220+ const std::complex <double >* becp = onsite_p->get_h_becp ();
221+ int nkb = onsite_p->get_size_becp () / nbands / npol;
222+
223+ int begin_ih = 0 ;
224+ for (int iat = 0 ; iat < cell.nat ; iat++)
225+ {
226+ const int it = cell.iat2it [iat];
227+ const int nh = onsite_p->get_nh (iat);
228+ const int target_l = get_orbital_corr (it);
229+ if (!has_correlated_orbital (it))
230+ {
231+ begin_ih += nh;
232+ continue ;
233+ }
234+ const int m_begin = target_l * target_l;
235+ const int tlp1 = 2 * target_l + 1 ;
236+ const int tlp1_2 = tlp1 * tlp1;
237+ if (this ->nspin == 4 )
238+ {
239+ for (int ib = 0 ; ib < nbands; ib++)
240+ {
241+ const double weight = wg_in (ik, ib);
242+ int ind_m1m2 = 0 ;
243+ for (int m1 = 0 ; m1 < tlp1; m1++)
244+ {
245+ const int index_m1 = ib*npol*nkb + begin_ih + m_begin + m1;
246+ for (int m2 = 0 ; m2 < tlp1; m2++)
247+ {
248+ const int index_m2 = ib*npol*nkb + begin_ih + m_begin + m2;
249+ std::complex <double > occ[4 ];
250+ occ[0 ] = weight * conj (becp[index_m1]) * becp[index_m2];
251+ occ[1 ] = weight * conj (becp[index_m1]) * becp[index_m2 + nkb];
252+ occ[2 ] = weight * conj (becp[index_m1 + nkb]) * becp[index_m2];
253+ occ[3 ] = weight * conj (becp[index_m1 + nkb]) * becp[index_m2 + nkb];
254+ this ->occ_mat [iat][target_l][0 ][0 ].c [ind_m1m2] += (occ[0 ] + occ[3 ]).real ();
255+ this ->occ_mat [iat][target_l][0 ][0 ].c [ind_m1m2 + tlp1_2] += (occ[1 ] + occ[2 ]).real ();
256+ this ->occ_mat [iat][target_l][0 ][0 ].c [ind_m1m2 + 2 * tlp1_2] += (occ[1 ] - occ[2 ]).imag ();
257+ this ->occ_mat [iat][target_l][0 ][0 ].c [ind_m1m2 + 3 * tlp1_2] += (occ[0 ] - occ[3 ]).real ();
258+ ind_m1m2++;
259+ }
260+ }
261+ }
262+ }
263+ else // nspin=1 or nspin=2
264+ {
265+ for (int ib = 0 ; ib < nbands; ib++)
266+ {
267+ const double weight = wg_in (ik, ib);
268+ int ind_m1m2 = 0 ;
269+ for (int m1 = 0 ; m1 < tlp1; m1++)
270+ {
271+ const int index_m1 = ib*nkb + begin_ih + m_begin + m1;
272+ for (int m2 = 0 ; m2 < tlp1; m2++)
273+ {
274+ const int index_m2 = ib*nkb + begin_ih + m_begin + m2;
275+ this ->occ_mat [iat][target_l][0 ][is].c [ind_m1m2] += weight * (conj (becp[index_m1]) * becp[index_m2]).real ();
276+ ind_m1m2++;
277+ }
278+ }
279+ }
280+ }
281+ begin_ih += nh;
282+ }
283+ }
284+ }
285+
286+ // explicit instantiations
287+ template void Plus_U_Base::accumulate_occ_one_k<base_device::DEVICE_CPU >(
288+ const void *, const ModuleBase::matrix&, const UnitCell&, const int *);
289+ #if defined(__CUDA) || defined(__ROCM)
290+ template void Plus_U_Base::accumulate_occ_one_k<base_device::DEVICE_GPU >(
291+ const void *, const ModuleBase::matrix&, const UnitCell&, const int *);
292+ #endif
0 commit comments