@@ -55,24 +55,10 @@ struct Lapack<double>
5555 const char uplo = ' U' ;
5656 const int lda = n;
5757 int info = 0 ;
58- int lwork = -1 ;
59- int liwork = -1 ;
60- std::vector<double > work (1 );
61- std::vector<int > iwork (1 );
62- dsyevd_ (&jobz, &uplo, &n, a, &lda, w,
63- work.data (), &lwork, iwork.data (), &liwork, &info);
64- if (info != 0 )
65- {
66- lwork = std::max (1 , 1 + 6 * n + 2 * n * n);
67- liwork = std::max (1 , 3 + 5 * n);
68- }
69- else
70- {
71- lwork = static_cast <int >(work[0 ]);
72- liwork = std::max (1 , iwork[0 ]);
73- }
74- work.assign (static_cast <size_t >(lwork), 0.0 );
75- iwork.assign (static_cast <size_t >(liwork), 0 );
58+ int lwork = std::max (1 , 1 + 6 * n + 2 * n * n);
59+ int liwork = std::max (1 , 3 + 5 * n);
60+ std::vector<double > work (static_cast <size_t >(lwork), 0.0 );
61+ std::vector<int > iwork (static_cast <size_t >(liwork), 0 );
7662 dsyevd_ (&jobz, &uplo, &n, a, &lda, w,
7763 work.data (), &lwork, iwork.data (), &liwork, &info);
7864 if (info != 0 )
@@ -87,24 +73,10 @@ struct Lapack<double>
8773 const int lda = n;
8874 const int ldb = n;
8975 int info = 0 ;
90- int lwork = -1 ;
91- int liwork = -1 ;
92- std::vector<double > work (1 );
93- std::vector<int > iwork (1 );
94- dsygvd_ (&itype, &jobz, &uplo, &n, a, &lda, b, &ldb, w,
95- work.data (), &lwork, iwork.data (), &liwork, &info);
96- if (info != 0 )
97- {
98- lwork = std::max (1 , 1 + 18 * n + 10 * n * n);
99- liwork = std::max (1 , 3 + 10 * n);
100- }
101- else
102- {
103- lwork = static_cast <int >(work[0 ]);
104- liwork = std::max (1 , iwork[0 ]);
105- }
106- work.assign (static_cast <size_t >(lwork), 0.0 );
107- iwork.assign (static_cast <size_t >(liwork), 0 );
76+ int lwork = std::max (1 , 1 + 18 * n + 10 * n * n);
77+ int liwork = std::max (1 , 3 + 10 * n);
78+ std::vector<double > work (static_cast <size_t >(lwork), 0.0 );
79+ std::vector<int > iwork (static_cast <size_t >(liwork), 0 );
10880 dsygvd_ (&itype, &jobz, &uplo, &n, a, &lda, b, &ldb, w,
10981 work.data (), &lwork, iwork.data (), &liwork, &info);
11082 if (info != 0 )
@@ -158,24 +130,10 @@ struct Lapack<float>
158130 const char uplo = ' U' ;
159131 const int lda = n;
160132 int info = 0 ;
161- int lwork = -1 ;
162- int liwork = -1 ;
163- std::vector<float > work (1 );
164- std::vector<int > iwork (1 );
165- ssyevd_ (&jobz, &uplo, &n, a, &lda, w,
166- work.data (), &lwork, iwork.data (), &liwork, &info);
167- if (info != 0 )
168- {
169- lwork = std::max (1 , 1 + 6 * n + 2 * n * n);
170- liwork = std::max (1 , 3 + 5 * n);
171- }
172- else
173- {
174- lwork = static_cast <int >(work[0 ]);
175- liwork = std::max (1 , iwork[0 ]);
176- }
177- work.assign (static_cast <size_t >(lwork), 0 .0f );
178- iwork.assign (static_cast <size_t >(liwork), 0 );
133+ int lwork = std::max (1 , 1 + 6 * n + 2 * n * n);
134+ int liwork = std::max (1 , 3 + 5 * n);
135+ std::vector<float > work (static_cast <size_t >(lwork), 0 .0f );
136+ std::vector<int > iwork (static_cast <size_t >(liwork), 0 );
179137 ssyevd_ (&jobz, &uplo, &n, a, &lda, w,
180138 work.data (), &lwork, iwork.data (), &liwork, &info);
181139 if (info != 0 )
@@ -190,24 +148,10 @@ struct Lapack<float>
190148 const int lda = n;
191149 const int ldb = n;
192150 int info = 0 ;
193- int lwork = -1 ;
194- int liwork = -1 ;
195- std::vector<float > work (1 );
196- std::vector<int > iwork (1 );
197- ssygvd_ (&itype, &jobz, &uplo, &n, a, &lda, b, &ldb, w,
198- work.data (), &lwork, iwork.data (), &liwork, &info);
199- if (info != 0 )
200- {
201- lwork = std::max (1 , 1 + 18 * n + 10 * n * n);
202- liwork = std::max (1 , 3 + 10 * n);
203- }
204- else
205- {
206- lwork = static_cast <int >(work[0 ]);
207- liwork = std::max (1 , iwork[0 ]);
208- }
209- work.assign (static_cast <size_t >(lwork), 0 .0f );
210- iwork.assign (static_cast <size_t >(liwork), 0 );
151+ int lwork = std::max (1 , 1 + 18 * n + 10 * n * n);
152+ int liwork = std::max (1 , 3 + 10 * n);
153+ std::vector<float > work (static_cast <size_t >(lwork), 0 .0f );
154+ std::vector<int > iwork (static_cast <size_t >(liwork), 0 );
211155 ssygvd_ (&itype, &jobz, &uplo, &n, a, &lda, b, &ldb, w,
212156 work.data (), &lwork, iwork.data (), &liwork, &info);
213157 if (info != 0 )
@@ -1063,6 +1007,9 @@ double DiagoPPCG<T, Device>::diag(const HPsiFunc& hpsi_func,
10631007 {
10641008 // Initialize with Rayleigh-Ritz.
10651009 rayleigh_ritz (psi_in, eigenvalue_in, active_cols, ethr_band);
1010+ // Recompute to keep hpsi/spi consistent with rotated psi.
1011+ apply_h (hpsi_func, psi_in, hpsi_.data (), ncol);
1012+ apply_s_current (psi_in, spsi_.data (), ncol);
10661013
10671014 Real trG = trace_of_active_projected (psi_in, active_cols);
10681015 Real trdif = static_cast <Real>(-1 );
@@ -1111,10 +1058,17 @@ double DiagoPPCG<T, Device>::diag(const HPsiFunc& hpsi_func,
11111058 update_one_block (psi_in, cols, l, use_p, subspace);
11121059 }
11131060
1061+ // Re-orthonormalize and recompute after psi modification.
1062+ chol_qr_active (psi_in, active_cols);
1063+ apply_h (hpsi_func, psi_in, hpsi_.data (), ncol);
1064+ apply_s_current (psi_in, spsi_.data (), ncol);
1065+
11141066 // Periodic Rayleigh-Ritz.
11151067 if (iter % rr_step_ == 0 )
11161068 {
11171069 rayleigh_ritz (psi_in, eigenvalue_in, active_cols, ethr_band);
1070+ apply_h (hpsi_func, psi_in, hpsi_.data (), ncol);
1071+ apply_s_current (psi_in, spsi_.data (), ncol);
11181072 trdif = static_cast <Real>(-1 );
11191073 trG = 0 ;
11201074 for (const int c : active_cols)
@@ -1158,6 +1112,8 @@ double DiagoPPCG<T, Device>::diag(const HPsiFunc& hpsi_func,
11581112 if (trdif >= 0 && trdif <= trtol)
11591113 {
11601114 rayleigh_ritz (psi_in, eigenvalue_in, active_cols, ethr_band);
1115+ apply_h (hpsi_func, psi_in, hpsi_.data (), ncol);
1116+ apply_s_current (psi_in, spsi_.data (), ncol);
11611117 trdif = static_cast <Real>(-1 );
11621118 }
11631119 }
@@ -1167,6 +1123,9 @@ double DiagoPPCG<T, Device>::diag(const HPsiFunc& hpsi_func,
11671123
11681124 if ((iter - 1 ) % rr_step_ != 0 )
11691125 rayleigh_ritz (psi_in, eigenvalue_in, active_cols, ethr_band);
1126+ // Final consistency: ensure hpsi/spi match the converged psi.
1127+ apply_h (hpsi_func, psi_in, hpsi_.data (), ncol);
1128+ apply_s_current (psi_in, spsi_.data (), ncol);
11701129 }
11711130 else // CONJUGATE_GRADIENT
11721131 {
0 commit comments