@@ -248,6 +248,48 @@ namespace ModuleSymmetry
248248 return HR_full;
249249 }
250250
251+ // (nspin=2 SSG) derive the opposite spin channel's FULL H(R) from a full H(R) by one spin-flip
252+ // coset op f=[C2_perp||g] (raw isym = nrotk, i.e. gmatrix_flip[0]). With SOC off the two spin
253+ // channels are independent real matrices, and f's spatial/orbital rotation is identical to a
254+ // unitary op (only the target spin channel differs), so the covariance is exactly the one used
255+ // by restore_HR: H_other[Z] = rotate_f( H_this[ f.Z ] ), with f.Z = rotate_apR_by_formula(f, Z).
256+ // f is a bijection on the full atom-pair set, so a single forward pass fills the whole channel.
257+ template <typename Tdata>
258+ std::map<int , std::map<std::pair<int , TC >, RI ::Tensor<Tdata>>> Symmetry_rotation::restore_HR_flip_nspin2 (
259+ const Symmetry& symm, const Atom* atoms, const Statistics& st, const char mode,
260+ const std::map<int , std::map<std::pair<int , TC >, RI ::Tensor<Tdata>>>& HR_full_this) const
261+ {
262+ ModuleBase::TITLE (" Symmetry_rotation" , " restore_HR_flip_nspin2" );
263+ ModuleBase::timer::start (" Symmetry_rotation" , " restore_HR_flip_nspin2" );
264+ assert (symm.spin_flip_nspin2 );
265+ assert (symm.nrotk_flip > 0 );
266+ const int isym_flip = symm.nrotk ; // flip op j=0, raw sector index nrotk (nrotk_anti==0 here)
267+ std::map<int , std::map<std::pair<int , TC >, RI ::Tensor<Tdata>>> HR_other;
268+ for (auto & tmp1 : HR_full_this)
269+ {
270+ const int & z1 = tmp1.first ;
271+ for (auto & tmp2 : tmp1.second )
272+ {
273+ const int & z2 = tmp2.first .first ;
274+ const TC & Rz = tmp2.first .second ;
275+ const TapR& src = this ->irs_ .rotate_apR_by_formula (symm, isym_flip, { { z1, z2 }, Rz });
276+ const int & s1 = src.first .first ;
277+ const int & s2 = src.first .second ;
278+ const TC & Rs = src.second ;
279+ // f is a bijection on the full apR set, so H_this[src] should exist; a missing entry
280+ // can only be a below-threshold drop, treated as zero (skip).
281+ auto it1 = HR_full_this.find (s1);
282+ if (it1 == HR_full_this.end ()) { continue ; }
283+ auto it2 = it1->second .find ({ s2, Rs });
284+ if (it2 == it1->second .end ()) { continue ; }
285+ HR_other[z1][{z2, Rz}] = rotate_atompair_serial (it2->second , isym_flip,
286+ atoms[st.iat2it [s1]], atoms[st.iat2it [s2]], mode);
287+ }
288+ }
289+ ModuleBase::timer::end (" Symmetry_rotation" , " restore_HR_flip_nspin2" );
290+ return HR_other;
291+ }
292+
251293 template <typename Tdata>
252294 inline void set_block (const int starti, const int startj, const RI ::Tensor<std::complex <double >>& block,
253295 RI ::Tensor<Tdata>& obj_tensor)
0 commit comments