77#include " source_hamilt/module_hcontainer/hcontainer.h"
88#include " source_hamilt/module_hcontainer/hcontainer_funcs.h"
99
10+ bool Plus_U::is_adjacent_pair (const UnitCell& ucell,
11+ const Grid_Driver& gd,
12+ const int T1 ,
13+ const int T2 ,
14+ const ModuleBase::Vector3<double >& tau1,
15+ const ModuleBase::Vector3<double >& tau2) const
16+ {
17+ const ModuleBase::Vector3<double > dtau = tau2 - tau1;
18+ const double distance = dtau.norm () * ucell.lat0 ;
19+ const double rcut = orb_cutoff_[T1 ] + orb_cutoff_[T2 ];
20+ if (distance < rcut)
21+ {
22+ return true ;
23+ }
24+ // Three-body bridging: pair is not directly adjacent but shares a
25+ // common nonlocal projector center T0 that overlaps both orbitals.
26+ for (int ad0 = 0 ; ad0 < gd.getAdjacentNum () + 1 ; ++ad0)
27+ {
28+ const int T0 = gd.getType (ad0);
29+ const int I0 = gd.getNatom (ad0);
30+ const ModuleBase::Vector3<double > tau0 = gd.getAdjacentTau (ad0);
31+ const double distance1 = (tau0 - tau1).norm () * ucell.lat0 ;
32+ const double distance2 = (tau0 - tau2).norm () * ucell.lat0 ;
33+ const double rcut1 = orb_cutoff_[T1 ] + ucell.infoNL ->get_rcut_max (T0 );
34+ const double rcut2 = orb_cutoff_[T2 ] + ucell.infoNL ->get_rcut_max (T0 );
35+ if (distance1 < rcut1 && distance2 < rcut2)
36+ {
37+ return true ;
38+ }
39+ }
40+ return false ;
41+ }
42+
43+ int Plus_U::get_linear_index (const int mu,
44+ const int nu,
45+ const Parallel_Orbitals& pv) const
46+ {
47+ if (ModuleBase::GlobalFunc::IS_COLUMN_MAJOR_KS_SOLVER (this ->ks_solver ))
48+ {
49+ return mu + nu * pv.nrow ;
50+ }
51+ return mu * pv.ncol + nu;
52+ }
53+
1054void Plus_U::fold_dSR_gamma (const UnitCell& ucell,
1155 const Parallel_Orbitals& pv,
1256 const Grid_Driver* gd,
@@ -37,8 +81,7 @@ void Plus_U::fold_dSR_gamma(const UnitCell& ucell,
3781 }
3882
3983 int nnr = 0 ;
40- ModuleBase::Vector3<double > tau1, tau2, dtau;
41- ModuleBase::Vector3<double > dtau1, dtau2, tau0;
84+ ModuleBase::Vector3<double > tau1, tau2;
4285
4386 for (int T1 = 0 ; T1 < ucell.ntype ; ++T1 )
4487 {
@@ -52,68 +95,41 @@ void Plus_U::fold_dSR_gamma(const UnitCell& ucell,
5295 {
5396 const int T2 = gd->getType (ad);
5497 const int I2 = gd->getNatom (ad);
55- const int start2 = ucell.itiaiw2iwt (T2 , I2 , 0 );
5698 Atom* atom2 = &ucell.atoms [T2 ];
5799 tau2 = gd->getAdjacentTau (ad);
58- dtau = tau2 - tau1;
59- double distance = dtau.norm () * ucell.lat0 ;
60- double rcut = orb_cutoff_[T1 ] + orb_cutoff_[T2 ];
61- bool adj = false ;
62- if (distance < rcut)
63- {
64- adj = true ;
65- }
66- else if (distance >= rcut)
100+
101+ if (!is_adjacent_pair (ucell, *gd, T1 , T2 , tau1, tau2))
67102 {
68- for (int ad0 = 0 ; ad0 < gd->getAdjacentNum () + 1 ; ++ad0)
69- {
70- const int T0 = gd->getType (ad0);
71- const int I0 = gd->getNatom (ad0);
72- const int iat0 = ucell.itia2iat (T0 , I0 );
73- const int start0 = ucell.itiaiw2iwt (T0 , I0 , 0 );
74- tau0 = gd->getAdjacentTau (ad0);
75- dtau1 = tau0 - tau1;
76- dtau2 = tau0 - tau2;
77- double distance1 = dtau1.norm () * ucell.lat0 ;
78- double distance2 = dtau2.norm () * ucell.lat0 ;
79- double rcut1 = orb_cutoff_[T1 ] + ucell.infoNL ->get_rcut_max (T0 );
80- double rcut2 = orb_cutoff_[T2 ] + ucell.infoNL ->get_rcut_max (T0 );
81- if (distance1 < rcut1 && distance2 < rcut2)
82- {
83- adj = true ;
84- break ;
85- }
86- }
103+ continue ;
87104 }
88105
89- if (adj)
106+ const int start2 = ucell.itiaiw2iwt (T2 , I2 , 0 );
107+ for (int jj = 0 ; jj < atom1->nw * this ->npol ; ++jj)
90108 {
91- for (int jj = 0 ; jj < atom1->nw * this ->npol ; ++jj)
109+ const int jj0 = jj / this ->npol ;
110+ const int iw1_all = start1 + jj0;
111+ const int mu = pv.global2local_row (iw1_all);
112+ if (mu < 0 )
113+ {
114+ continue ;
115+ }
116+
117+ for (int kk = 0 ; kk < atom2->nw * this ->npol ; ++kk)
92118 {
93- const int jj0 = jj / this ->npol ;
94- const int iw1_all = start1 + jj0;
95- const int mu = pv.global2local_row (iw1_all);
96- if (mu < 0 )
97- {
98- continue ;
99- }
100-
101- for (int kk = 0 ; kk < atom2->nw * this ->npol ; ++kk)
119+ const int kk0 = kk / this ->npol ;
120+ const int iw2_all = start2 + kk0;
121+ const int nu = pv.global2local_col (iw2_all);
122+ if (nu < 0 )
102123 {
103- const int kk0 = kk / this ->npol ;
104- const int iw2_all = start2 + kk0;
105- const int nu = pv.global2local_col (iw2_all);
106- if (nu < 0 )
107- {
108- continue ;
109- }
110-
111- dSR_gamma[nu * pv.nrow + mu] += dS_ptr[nnr] * dh_r[nnr * 3 + dim2];
112-
113- ++nnr;
114- } // kk
115- } // jj
116- } // adj
124+ continue ;
125+ }
126+
127+ const int iic = get_linear_index (mu, nu, pv);
128+ dSR_gamma[iic] += dS_ptr[nnr] * dh_r[nnr * 3 + dim2];
129+
130+ ++nnr;
131+ } // kk
132+ } // jj
117133 } // ad
118134 } // I1
119135 } // T1
@@ -150,22 +166,16 @@ void Plus_U::folding_matrix_k(const UnitCell& ucell,
150166 }
151167
152168 int nnr = 0 ;
153- ModuleBase::Vector3<double > dtau;
154169 ModuleBase::Vector3<double > tau1;
155170 ModuleBase::Vector3<double > tau2;
156171
157- ModuleBase::Vector3<double > dtau1;
158- ModuleBase::Vector3<double > dtau2;
159- ModuleBase::Vector3<double > tau0;
160-
161172 for (int T1 = 0 ; T1 < ucell.ntype ; ++T1 )
162173 {
163174 Atom* atom1 = &ucell.atoms [T1 ];
164175 for (int I1 = 0 ; I1 < atom1->na ; ++I1 )
165176 {
166177 tau1 = atom1->tau [I1 ];
167178 gd.Find_atom (ucell, tau1, T1 , I1 );
168- Atom* atom1 = &ucell.atoms [T1 ];
169179 const int start1 = ucell.itiaiw2iwt (T1 , I1 , 0 );
170180
171181 // (2) search among all adjacent atoms.
@@ -176,100 +186,59 @@ void Plus_U::folding_matrix_k(const UnitCell& ucell,
176186 Atom* atom2 = &ucell.atoms [T2 ];
177187
178188 tau2 = gd.getAdjacentTau (ad);
179- dtau = tau2 - tau1;
180- double distance = dtau.norm () * ucell.lat0 ;
181- double rcut = orb_cutoff_[T1 ] + orb_cutoff_[T2 ];
182-
183- bool adj = false ;
184189
185- if (distance < rcut )
190+ if (! is_adjacent_pair (ucell, gd, T1 , T2 , tau1, tau2) )
186191 {
187- adj = true ;
192+ continue ;
188193 }
189- else if (distance >= rcut)
194+
195+ // (3) calculate the nu of atom (T2, I2)
196+ const int start2 = ucell.itiaiw2iwt (T2 , I2 , 0 );
197+ // ------------------------------------------------
198+ // exp(k dot dR)
199+ // dR is the index of box in Crystal coordinates
200+ // ------------------------------------------------
201+ ModuleBase::Vector3<double > dR (gd.getBox (ad).x , gd.getBox (ad).y , gd.getBox (ad).z );
202+ const double arg = (kvec_d * dR) * ModuleBase::TWO_PI ;
203+ const std::complex <double > kphase = std::complex <double >(cos (arg), sin (arg));
204+
205+ // --------------------------------------------------
206+ // calculate how many matrix elements are in
207+ // this processor.
208+ // --------------------------------------------------
209+ for (int ii = 0 ; ii < atom1->nw * this ->npol ; ii++)
190210 {
191- for (int ad0 = 0 ; ad0 < gd.getAdjacentNum () + 1 ; ++ad0)
211+ // the index of orbitals in this processor
212+ const int iw1_all = start1 + ii;
213+ const int mu = pv.global2local_row (iw1_all);
214+ if (mu < 0 )
192215 {
193- const int T0 = gd.getType (ad0);
194- const int I0 = gd.getNatom (ad0);
195-
196- tau0 = gd.getAdjacentTau (ad0);
197- dtau1 = tau0 - tau1;
198- dtau2 = tau0 - tau2;
216+ continue ;
217+ }
199218
200- double distance1 = dtau1.norm () * ucell.lat0 ;
201- double distance2 = dtau2.norm () * ucell.lat0 ;
219+ for (int jj = 0 ; jj < atom2->nw * this ->npol ; jj++)
220+ {
221+ int iw2_all = start2 + jj;
222+ const int nu = pv.global2local_col (iw2_all);
223+ if (nu < 0 )
224+ {
225+ continue ;
226+ }
202227
203- double rcut1 = orb_cutoff_[T1 ] + ucell.infoNL ->get_rcut_max (T0 );
204- double rcut2 = orb_cutoff_[T2 ] + ucell.infoNL ->get_rcut_max (T0 );
228+ const int iic = get_linear_index (mu, nu, pv);
205229
206- if (distance1 < rcut1 && distance2 < rcut2 )
230+ if (dim1 <= 3 )
207231 {
208- adj = true ;
209- break ;
232+ mat_k[iic] += mat_ptr[nnr] * kphase;
210233 }
211- }
212- }
213-
214- if (adj)
215- {
216- // (3) calculate the nu of atom (T2, I2)
217- const int start2 = ucell.itiaiw2iwt (T2 , I2 , 0 );
218- // ------------------------------------------------
219- // exp(k dot dR)
220- // dR is the index of box in Crystal coordinates
221- // ------------------------------------------------
222- ModuleBase::Vector3<double > dR (gd.getBox (ad).x , gd.getBox (ad).y , gd.getBox (ad).z );
223- const double arg = (kvec_d * dR) * ModuleBase::TWO_PI ;
224- const std::complex <double > kphase = std::complex <double >(cos (arg), sin (arg));
225-
226- // --------------------------------------------------
227- // calculate how many matrix elements are in
228- // this processor.
229- // --------------------------------------------------
230- for (int ii = 0 ; ii < atom1->nw * this ->npol ; ii++)
231- {
232- // the index of orbitals in this processor
233- const int iw1_all = start1 + ii;
234- const int mu = pv.global2local_row (iw1_all);
235- if (mu < 0 )
236- {
237- continue ;
238- }
239-
240- for (int jj = 0 ; jj < atom2->nw * this ->npol ; jj++)
234+ else
241235 {
242- int iw2_all = start2 + jj;
243- const int nu = pv.global2local_col (iw2_all);
244- if (nu < 0 )
245- {
246- continue ;
247- }
248-
249- int iic = 0 ;
250- if (ModuleBase::GlobalFunc::IS_COLUMN_MAJOR_KS_SOLVER (this ->ks_solver ))
251- {
252- iic = mu + nu * pv.nrow ;
253- }
254- else
255- {
256- iic = mu * pv.ncol + nu;
257- }
258-
259- if (dim1 <= 3 )
260- {
261- mat_k[iic] += mat_ptr[nnr] * kphase;
262- }
263- else
264- {
265- mat_k[iic] += mat_ptr[nnr] * fsr.DH_r [nnr * 3 + dim2] * kphase;
266- }
267-
268- ++nnr;
269- } // kk
270- } // jj
271- } // adj
236+ mat_k[iic] += mat_ptr[nnr] * fsr.DH_r [nnr * 3 + dim2] * kphase;
237+ }
272238
239+ ++nnr;
240+ } // jj
241+ } // ii
273242 } // ad
274243 } // I1
275244 } // T1
0 commit comments