@@ -57,7 +57,7 @@ namespace LR
5757 // kernel: excited state
5858 this ->ops = new OperatorLRHxc<T>(nspin, naos, nocc, nvirt, psi_ks,
5959 *this ->DM_trans , pot, ucell, orb_cutoff, gd, kv, pX, pc, pmat,
60- { 0 }, -2.0 , ATYPE ::CXC );
60+ { 0 }, T ( -2.0 ) , ATYPE ::CXC );
6161#ifdef __EXX
6262 if (exx_kernel_list ().count (xc_kernel))
6363 {
@@ -105,15 +105,27 @@ namespace LR
105105 // *this->DM_diff, pot_hxc_gs, ucell, orb_cutoff, gd, kv, pX, pc, pmat,
106106 // { 0 }, T(-2.0), ATYPE::CC_vo);
107107
108+ // $D^X$ is fed to the CXC operators TRANSPOSED.
109+ //
110+ // The RHS needs $K^{S/T}_{ba}[D^X]$ -- the same kernel the Casida equation was solved
111+ // with, which `HamiltLR` builds from the un-symmetrized $D^X$ (`tdm_sym = false`).
112+ // `CVCX_virt`/`CVCX_occ` give the kernel matrix with its two MO indices in
113+ // the opposite order to what this term needs, and since
114+ // $(K[D])^T = K[D^T]$,
115+ // transposing the density matrix on the way in restores it.
108116 this ->cal_dm_trans = [&, this ](const int & is, const T* X)->void
109117 {
110118 const auto psi_ks_is = LR_Util::get_psi_spin (psi_ks, is, this ->nk );
111119#ifdef __MPI
112120 std::vector<ct::Tensor> dm_trans_2d = cal_dm_trans_pblas (X, this ->pX [is], psi_ks_is, pc, naos, nocc[is], nvirt[is], pmat);
113- for (auto & t : dm_trans_2d) LR_Util::matsym (t.data <T>(), naos, pmat);
121+ for (auto & t : dm_trans_2d) LR_Util::mattrans (t.data <T>(), naos, pmat);
114122#else
115123 std::vector<ct::Tensor> dm_trans_2d = cal_dm_trans_blas (X, psi_ks_is, nocc[is], nvirt[is]);
116- for (auto & t : dm_trans_2d) LR_Util::matsym (t.data <T>(), naos);
124+ for (auto & t : dm_trans_2d)
125+ {
126+ T* d = t.data <T>();
127+ for (int u = 0 ;u < naos;++u) { for (int v = u + 1 ;v < naos;++v) { std::swap (d[u * naos + v], d[v * naos + u]); } }
128+ }
117129#endif
118130 for (int ik = 0 ;ik < this ->nk ;++ik) { this ->DM_trans ->set_DMK_pointer (ik, dm_trans_2d[ik].data <T>()); }
119131 };
0 commit comments