105 CHARACTER(len=*),
PARAMETER :: routinen =
'compute_chebyshev'
106 REAL(kind=
dp),
PARAMETER :: scale_evals = 1.01_dp
108 CHARACTER(LEN=30) :: middle_name
109 CHARACTER(LEN=default_string_length) :: title
110 INTEGER :: handle, icheb, igrid, iinte, ispin, &
111 iwindow, n_gridpoint_dos, ncheb, &
112 ninte, nrows, nwindow, unit_cube, &
114 LOGICAL :: converged, write_cubes
115 REAL(kind=
dp) :: chev_t, chev_t_dos, dummy1, final, frob_matrix, initial, interval_a, &
116 interval_b, max_ev, min_ev, occ, orbital_occ, summa, t1, t2
117 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: chev_e, chev_es_dos, dos, dummy2, ev1, &
118 ev2, kernel_g, mu, sev1, sev2, trace_dm
119 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: aitchev_t, e_inte, gdensity, sqrt_vec
120 REAL(kind=
dp),
DIMENSION(:),
POINTER :: tmp_r
122 TYPE(dbcsr_type) :: matrix_dummy1, matrix_f, matrix_tmp1, &
123 matrix_tmp2, matrix_tmp3
124 TYPE(dbcsr_type),
DIMENSION(:),
POINTER :: matrix_dummy2
126 IF (.NOT. ls_scf_env%chebyshev%compute_chebyshev)
RETURN
128 CALL timeset(routinen, handle)
132 IF (logger%para_env%is_source())
THEN
138 ncheb = ls_scf_env%chebyshev%n_chebyshev
140 n_gridpoint_dos = ls_scf_env%chebyshev%n_gridpoint_dos
143 IF (write_cubes)
THEN
144 IF (
ASSOCIATED(ls_scf_env%chebyshev%min_energy))
DEALLOCATE (ls_scf_env%chebyshev%min_energy)
146 ALLOCATE (ls_scf_env%chebyshev%min_energy(
SIZE(tmp_r)))
147 ls_scf_env%chebyshev%min_energy = tmp_r
149 IF (
ASSOCIATED(ls_scf_env%chebyshev%max_energy))
DEALLOCATE (ls_scf_env%chebyshev%max_energy)
151 ALLOCATE (ls_scf_env%chebyshev%max_energy(
SIZE(tmp_r)))
152 ls_scf_env%chebyshev%max_energy = tmp_r
154 nwindow =
SIZE(ls_scf_env%chebyshev%min_energy)
159 ALLOCATE (ev1(1:nwindow))
160 ALLOCATE (ev2(1:nwindow))
161 ALLOCATE (sev1(1:nwindow))
162 ALLOCATE (sev2(1:nwindow))
163 ALLOCATE (trace_dm(1:nwindow))
164 ALLOCATE (matrix_dummy2(1:nwindow))
166 DO iwindow = 1, nwindow
167 ev1(iwindow) = ls_scf_env%chebyshev%min_energy(iwindow)
168 ev2(iwindow) = ls_scf_env%chebyshev%max_energy(iwindow)
171 IF (unit_nr > 0)
THEN
172 WRITE (unit_nr,
'()')
173 WRITE (unit_nr,
'(T2,A)')
"STARTING CHEBYSHEV CALCULATION"
177 CALL dbcsr_create(matrix_tmp1, template=ls_scf_env%matrix_s, matrix_type=dbcsr_type_no_symmetry)
178 CALL dbcsr_create(matrix_tmp2, template=ls_scf_env%matrix_s, matrix_type=dbcsr_type_no_symmetry)
179 CALL dbcsr_create(matrix_tmp3, template=ls_scf_env%matrix_s, matrix_type=dbcsr_type_no_symmetry)
180 CALL dbcsr_create(matrix_f, template=ls_scf_env%matrix_s, matrix_type=dbcsr_type_no_symmetry)
181 CALL dbcsr_create(matrix_dummy1, template=ls_scf_env%matrix_s, matrix_type=dbcsr_type_no_symmetry)
183 DO iwindow = 1, nwindow
184 CALL dbcsr_create(matrix_dummy2(iwindow), template=ls_scf_env%matrix_s, &
185 matrix_type=dbcsr_type_no_symmetry)
188 DO ispin = 1,
SIZE(ls_scf_env%matrix_ks)
190 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, ls_scf_env%matrix_s_sqrt_inv, ls_scf_env%matrix_ks(ispin), &
191 0.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
192 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_tmp1, ls_scf_env%matrix_s_sqrt_inv, &
193 0.0_dp, matrix_f, filter_eps=ls_scf_env%eps_filter)
196 CALL arnoldi_extremal(matrix_f, max_ev, min_ev, converged=converged, max_iter=ls_scf_env%max_iter_lanczos, &
197 threshold=ls_scf_env%eps_lanczos)
198 IF (unit_nr > 0)
WRITE (unit_nr,
'(T2,A,2F16.8,A,L2)') &
199 "smallest largest eigenvalue", min_ev, max_ev,
" converged ", converged
200 IF (nwindow > 0)
THEN
201 IF (unit_nr > 0)
WRITE (unit_nr,
'(T2,A,1000F16.8)')
"requested interval-min_energy", ev1(:)
202 IF (unit_nr > 0)
WRITE (unit_nr,
'(T2,A,1000F16.8)')
"requested interval-max_energy", ev2(:)
204 interval_a = (max_ev - min_ev)*scale_evals/2
205 interval_b = (max_ev + min_ev)/2
207 sev1(:) = (ev1(:) - interval_b)/interval_a
208 sev2(:) = (ev2(:) - interval_b)/interval_a
211 ALLOCATE (e_inte(1:ninte + 1, 1:nwindow))
212 ALLOCATE (sqrt_vec(1:ninte + 1, 1:nwindow))
214 DO iwindow = 1, nwindow
215 DO iinte = 1, ninte + 1
216 e_inte(iinte, iwindow) = sev1(iwindow) + ((sev2(iwindow) - sev1(iwindow))/ninte)*(iinte - 1)
217 sqrt_vec(iinte, iwindow) =
pi*sqrt(1.0_dp - e_inte(iinte, iwindow)*e_inte(iinte, iwindow))
223 ALLOCATE (aitchev_t(1:ncheb, 1:nwindow))
225 DO iwindow = 1, nwindow
227 CALL chebyshev_poly(initial, e_inte(1, iwindow), icheb)
228 CALL chebyshev_poly(final, e_inte(1, iwindow), icheb)
229 summa = (sev2(iwindow) - sev1(iwindow))/(2.0_dp*ninte)*(initial/sqrt_vec(1, iwindow) + final/sqrt_vec(ninte + 1, iwindow))
231 CALL chebyshev_poly(chev_t, e_inte(iinte, iwindow), icheb)
232 summa = summa + ((sev2(iwindow) - sev1(iwindow))/ninte)*(chev_t/sqrt_vec(iinte, iwindow))
234 aitchev_t(icheb, iwindow) = summa
240 CALL dbcsr_add_on_diag(matrix_f, -interval_b)
241 CALL dbcsr_scale(matrix_f, 1/interval_a)
244 CALL dbcsr_get_info(matrix=matrix_f, nfullrows_total=nrows)
245 CALL dbcsr_set(matrix_dummy1, 0.0_dp)
247 DO iwindow = 1, nwindow
248 CALL dbcsr_set(matrix_dummy2(iwindow), 0.0_dp)
251 ALLOCATE (mu(1:ncheb))
252 ALLOCATE (kernel_g(1:ncheb))
253 CALL kernel(kernel_g(1), 1, ncheb)
254 CALL kernel(kernel_g(2), 2, ncheb)
256 CALL dbcsr_set(matrix_tmp1, 0.0_dp)
257 CALL dbcsr_add_on_diag(matrix_tmp1, 1.0_dp)
258 CALL dbcsr_trace(matrix_tmp1, trace=mu(1))
259 CALL dbcsr_copy(matrix_tmp2, matrix_f)
260 CALL dbcsr_trace(matrix_tmp2, trace=mu(2))
262 DO iwindow = 1, nwindow
263 CALL dbcsr_copy(matrix_dummy1, matrix_tmp1)
264 CALL dbcsr_copy(matrix_dummy2(iwindow), matrix_tmp2)
265 CALL dbcsr_scale(matrix_dummy1, kernel_g(1)*aitchev_t(1, iwindow))
266 CALL dbcsr_scale(matrix_dummy2(iwindow), 2.0_dp*kernel_g(2)*aitchev_t(2, iwindow))
268 CALL dbcsr_add(matrix_dummy2(iwindow), matrix_dummy1, 1.0_dp, 1.0_dp)
271 DO icheb = 2, ncheb - 1
273 CALL dbcsr_multiply(
"N",
"N", 2.0_dp, matrix_f, matrix_tmp2, &
274 -1.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
275 CALL dbcsr_copy(matrix_tmp3, matrix_tmp1)
276 CALL dbcsr_copy(matrix_tmp1, matrix_tmp2)
277 CALL dbcsr_copy(matrix_tmp2, matrix_tmp3)
278 CALL dbcsr_trace(matrix_tmp2, trace=mu(icheb + 1))
279 CALL kernel(kernel_g(icheb + 1), icheb + 1, ncheb)
281 DO iwindow = 1, nwindow
283 CALL dbcsr_copy(matrix_dummy1, matrix_tmp2)
284 CALL dbcsr_scale(matrix_dummy1, 2.0_dp*kernel_g(icheb + 1)*aitchev_t(icheb + 1, iwindow))
285 CALL dbcsr_add(matrix_dummy2(iwindow), matrix_dummy1, 1.0_dp, 1.0_dp)
286 CALL dbcsr_trace(matrix_dummy2(iwindow), trace=trace_dm(iwindow))
290 occ = dbcsr_get_occupation(matrix_tmp1)
292 IF (unit_nr > 0 .AND. mod(icheb, 20) == 0)
THEN
294 IF (nwindow > 0)
THEN
295 WRITE (unit_nr,
'(T2,A,I5,1X,A,1X,F8.3,1X,A,1X,F8.6,1X,A,1X,1000F16.8)') &
296 "Iter.", icheb,
"time=", t2 - t1,
"occ=", occ,
"traces=", trace_dm(:)
298 WRITE (unit_nr,
'(T2,A,I5,1X,A,1X,F8.3,1X,A,1X,F8.6)') &
299 "Iter.", icheb,
"time=", t2 - t1,
"occ=", occ
304 DO iwindow = 1, nwindow
305 IF (
SIZE(ls_scf_env%matrix_ks) == 1)
THEN
310 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, ls_scf_env%matrix_s_sqrt_inv, matrix_dummy2(iwindow), &
311 0.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
312 CALL dbcsr_multiply(
"N",
"N", orbital_occ, matrix_tmp1, ls_scf_env%matrix_s_sqrt_inv, &
313 0.0_dp, matrix_tmp2, filter_eps=ls_scf_env%eps_filter)
314 CALL dbcsr_copy(matrix_dummy2(iwindow), matrix_tmp2)
318 CALL dbcsr_copy(matrix_tmp1, matrix_tmp2)
319 CALL dbcsr_add(matrix_tmp1, ls_scf_env%matrix_p(ispin), 1.0_dp, -1.0_dp)
320 frob_matrix = dbcsr_frobenius_norm(matrix_tmp1)
321 IF (unit_nr > 0)
WRITE (unit_nr, *)
"Difference between Chebyshev DM and LS DM", frob_matrix
326 ls_scf_env%chebyshev%print_key_cube),
cp_p_file)
327 IF (write_cubes)
THEN
328 DO iwindow = 1, nwindow
329 WRITE (middle_name,
"(A,I0)")
"E_DENSITY_WINDOW_", iwindow
330 WRITE (title,
"(A,1X,F16.8,1X,A,1X,F16.8)")
"Energy range : ", ev1(iwindow),
"to", ev2(iwindow)
332 "", extension=
".cube", &
333 middle_name=trim(middle_name), log_filename=.false.)
344 unit_dos =
cp_print_key_unit_nr(logger, ls_scf_env%chebyshev%print_key_dos,
"", extension=
".xy", &
345 middle_name=
"DOS", log_filename=.false.)
347 IF (unit_dos > 0)
THEN
348 ALLOCATE (dos(1:n_gridpoint_dos))
349 ALLOCATE (gdensity(1:n_gridpoint_dos, 1:nwindow))
350 ALLOCATE (chev_e(1:n_gridpoint_dos))
351 ALLOCATE (chev_es_dos(1:n_gridpoint_dos))
352 ALLOCATE (dummy2(1:nwindow))
353 DO igrid = 1, n_gridpoint_dos
354 chev_e(igrid) = min_ev + (igrid - 1)*(max_ev - min_ev)/(n_gridpoint_dos - 1)
355 chev_es_dos(igrid) = (chev_e(igrid) - interval_b)/interval_a
357 DO igrid = 1, n_gridpoint_dos
361 CALL chebyshev_poly(chev_t_dos, chev_es_dos(igrid), icheb)
362 dummy1 = dummy1 + kernel_g(icheb)*mu(icheb)*chev_t_dos
363 DO iwindow = 1, nwindow
364 dummy2(iwindow) = dummy2(iwindow) + kernel_g(icheb)*aitchev_t(icheb, iwindow)*chev_t_dos
367 dos(igrid) = 1.0_dp/(interval_a*nrows* &
368 (
pi*sqrt(1.0_dp - chev_es_dos(igrid)*chev_es_dos(igrid))))*(kernel_g(1)*mu(1) + 2.0_dp*dummy1)
369 DO iwindow = 1, nwindow
370 gdensity(igrid, iwindow) = kernel_g(1)*aitchev_t(1, iwindow) + 2.0_dp*dummy2(iwindow)
372 WRITE (unit_dos,
'(1000F16.8)') chev_e(igrid), dos(igrid), gdensity(igrid, :)
374 DEALLOCATE (chev_es_dos, chev_e, dos, gdensity)
379 CALL dbcsr_release(matrix_tmp1)
380 CALL dbcsr_release(matrix_tmp2)
381 CALL dbcsr_release(matrix_tmp3)
382 CALL dbcsr_release(matrix_f)
383 CALL dbcsr_release(matrix_dummy1)
385 DO iwindow = 1, nwindow
386 CALL dbcsr_release(matrix_dummy2(iwindow))
389 DEALLOCATE (ev1, ev2, sev1, sev2, matrix_dummy2)
392 DEALLOCATE (mu, kernel_g, aitchev_t, e_inte, sqrt_vec)
394 IF (unit_nr > 0)
WRITE (unit_nr,
'(T2,A)')
"ENDING CHEBYSHEV CALCULATION"
396 CALL timestop(handle)