107 CHARACTER(len=*),
PARAMETER :: routinen =
'compute_chebyshev'
108 REAL(kind=
dp),
PARAMETER :: scale_evals = 1.01_dp
110 CHARACTER(LEN=30) :: middle_name
111 CHARACTER(LEN=default_string_length) :: title
112 INTEGER :: handle, icheb, igrid, iinte, ispin, &
113 iwindow, n_gridpoint_dos, ncheb, &
114 ninte, nrows, nwindow, unit_cube, &
116 LOGICAL :: converged, write_cubes
117 REAL(kind=
dp) :: chev_t, chev_t_dos, dummy1, final, frob_matrix, initial, interval_a, &
118 interval_b, max_ev, min_ev, occ, orbital_occ, summa, t1, t2
119 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: chev_e, chev_es_dos, dos, dummy2, ev1, &
120 ev2, kernel_g, mu, sev1, sev2, trace_dm
121 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: aitchev_t, e_inte, gdensity, sqrt_vec
122 REAL(kind=
dp),
DIMENSION(:),
POINTER :: tmp_r
124 TYPE(
dbcsr_type) :: matrix_dummy1, matrix_f, matrix_tmp1, &
125 matrix_tmp2, matrix_tmp3
126 TYPE(
dbcsr_type),
DIMENSION(:),
POINTER :: matrix_dummy2
128 IF (.NOT. ls_scf_env%chebyshev%compute_chebyshev)
RETURN
130 CALL timeset(routinen, handle)
134 IF (logger%para_env%is_source())
THEN
140 ncheb = ls_scf_env%chebyshev%n_chebyshev
142 n_gridpoint_dos = ls_scf_env%chebyshev%n_gridpoint_dos
145 IF (write_cubes)
THEN
146 IF (
ASSOCIATED(ls_scf_env%chebyshev%min_energy))
DEALLOCATE (ls_scf_env%chebyshev%min_energy)
148 ALLOCATE (ls_scf_env%chebyshev%min_energy(
SIZE(tmp_r)))
149 ls_scf_env%chebyshev%min_energy = tmp_r
151 IF (
ASSOCIATED(ls_scf_env%chebyshev%max_energy))
DEALLOCATE (ls_scf_env%chebyshev%max_energy)
153 ALLOCATE (ls_scf_env%chebyshev%max_energy(
SIZE(tmp_r)))
154 ls_scf_env%chebyshev%max_energy = tmp_r
156 nwindow =
SIZE(ls_scf_env%chebyshev%min_energy)
161 ALLOCATE (ev1(1:nwindow))
162 ALLOCATE (ev2(1:nwindow))
163 ALLOCATE (sev1(1:nwindow))
164 ALLOCATE (sev2(1:nwindow))
165 ALLOCATE (trace_dm(1:nwindow))
166 ALLOCATE (matrix_dummy2(1:nwindow))
168 DO iwindow = 1, nwindow
169 ev1(iwindow) = ls_scf_env%chebyshev%min_energy(iwindow)
170 ev2(iwindow) = ls_scf_env%chebyshev%max_energy(iwindow)
173 IF (unit_nr > 0)
THEN
174 WRITE (unit_nr,
'()')
175 WRITE (unit_nr,
'(T2,A)')
"STARTING CHEBYSHEV CALCULATION"
179 CALL dbcsr_create(matrix_tmp1, template=ls_scf_env%matrix_s, matrix_type=dbcsr_type_no_symmetry)
180 CALL dbcsr_create(matrix_tmp2, template=ls_scf_env%matrix_s, matrix_type=dbcsr_type_no_symmetry)
181 CALL dbcsr_create(matrix_tmp3, template=ls_scf_env%matrix_s, matrix_type=dbcsr_type_no_symmetry)
182 CALL dbcsr_create(matrix_f, template=ls_scf_env%matrix_s, matrix_type=dbcsr_type_no_symmetry)
183 CALL dbcsr_create(matrix_dummy1, template=ls_scf_env%matrix_s, matrix_type=dbcsr_type_no_symmetry)
185 DO iwindow = 1, nwindow
186 CALL dbcsr_create(matrix_dummy2(iwindow), template=ls_scf_env%matrix_s, &
187 matrix_type=dbcsr_type_no_symmetry)
190 DO ispin = 1,
SIZE(ls_scf_env%matrix_ks)
192 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, ls_scf_env%matrix_s_sqrt_inv, ls_scf_env%matrix_ks(ispin), &
193 0.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
194 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_tmp1, ls_scf_env%matrix_s_sqrt_inv, &
195 0.0_dp, matrix_f, filter_eps=ls_scf_env%eps_filter)
198 CALL arnoldi_extremal(matrix_f, max_ev, min_ev, converged=converged, max_iter=ls_scf_env%max_iter_lanczos, &
199 threshold=ls_scf_env%eps_lanczos)
200 IF (unit_nr > 0)
WRITE (unit_nr,
'(T2,A,2F16.8,A,L2)') &
201 "smallest largest eigenvalue", min_ev, max_ev,
" converged ", converged
202 IF (nwindow > 0)
THEN
203 IF (unit_nr > 0)
WRITE (unit_nr,
'(T2,A,1000F16.8)')
"requested interval-min_energy", ev1(:)
204 IF (unit_nr > 0)
WRITE (unit_nr,
'(T2,A,1000F16.8)')
"requested interval-max_energy", ev2(:)
206 interval_a = (max_ev - min_ev)*scale_evals/2
207 interval_b = (max_ev + min_ev)/2
209 sev1(:) = (ev1(:) - interval_b)/interval_a
210 sev2(:) = (ev2(:) - interval_b)/interval_a
213 ALLOCATE (e_inte(1:ninte + 1, 1:nwindow))
214 ALLOCATE (sqrt_vec(1:ninte + 1, 1:nwindow))
216 DO iwindow = 1, nwindow
217 DO iinte = 1, ninte + 1
218 e_inte(iinte, iwindow) = sev1(iwindow) + ((sev2(iwindow) - sev1(iwindow))/ninte)*(iinte - 1)
219 sqrt_vec(iinte, iwindow) =
pi*sqrt(1.0_dp - e_inte(iinte, iwindow)*e_inte(iinte, iwindow))
225 ALLOCATE (aitchev_t(1:ncheb, 1:nwindow))
227 DO iwindow = 1, nwindow
229 CALL chebyshev_poly(initial, e_inte(1, iwindow), icheb)
230 CALL chebyshev_poly(final, e_inte(1, iwindow), icheb)
231 summa = (sev2(iwindow) - sev1(iwindow))/(2.0_dp*ninte)*(initial/sqrt_vec(1, iwindow) + final/sqrt_vec(ninte + 1, iwindow))
233 CALL chebyshev_poly(chev_t, e_inte(iinte, iwindow), icheb)
234 summa = summa + ((sev2(iwindow) - sev1(iwindow))/ninte)*(chev_t/sqrt_vec(iinte, iwindow))
236 aitchev_t(icheb, iwindow) = summa
249 DO iwindow = 1, nwindow
250 CALL dbcsr_set(matrix_dummy2(iwindow), 0.0_dp)
253 ALLOCATE (mu(1:ncheb))
254 ALLOCATE (kernel_g(1:ncheb))
255 CALL kernel(kernel_g(1), 1, ncheb)
256 CALL kernel(kernel_g(2), 2, ncheb)
264 DO iwindow = 1, nwindow
266 CALL dbcsr_copy(matrix_dummy2(iwindow), matrix_tmp2)
267 CALL dbcsr_scale(matrix_dummy1, kernel_g(1)*aitchev_t(1, iwindow))
268 CALL dbcsr_scale(matrix_dummy2(iwindow), 2.0_dp*kernel_g(2)*aitchev_t(2, iwindow))
270 CALL dbcsr_add(matrix_dummy2(iwindow), matrix_dummy1, 1.0_dp, 1.0_dp)
273 DO icheb = 2, ncheb - 1
276 -1.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
281 CALL kernel(kernel_g(icheb + 1), icheb + 1, ncheb)
283 DO iwindow = 1, nwindow
286 CALL dbcsr_scale(matrix_dummy1, 2.0_dp*kernel_g(icheb + 1)*aitchev_t(icheb + 1, iwindow))
287 CALL dbcsr_add(matrix_dummy2(iwindow), matrix_dummy1, 1.0_dp, 1.0_dp)
288 CALL dbcsr_trace(matrix_dummy2(iwindow), trace=trace_dm(iwindow))
294 IF (unit_nr > 0 .AND. mod(icheb, 20) == 0)
THEN
296 IF (nwindow > 0)
THEN
297 WRITE (unit_nr,
'(T2,A,I5,1X,A,1X,F8.3,1X,A,1X,F8.6,1X,A,1X,1000F16.8)') &
298 "Iter.", icheb,
"time=", t2 - t1,
"occ=", occ,
"traces=", trace_dm(:)
300 WRITE (unit_nr,
'(T2,A,I5,1X,A,1X,F8.3,1X,A,1X,F8.6)') &
301 "Iter.", icheb,
"time=", t2 - t1,
"occ=", occ
306 DO iwindow = 1, nwindow
307 IF (
SIZE(ls_scf_env%matrix_ks) == 1)
THEN
312 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, ls_scf_env%matrix_s_sqrt_inv, matrix_dummy2(iwindow), &
313 0.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
314 CALL dbcsr_multiply(
"N",
"N", orbital_occ, matrix_tmp1, ls_scf_env%matrix_s_sqrt_inv, &
315 0.0_dp, matrix_tmp2, filter_eps=ls_scf_env%eps_filter)
316 CALL dbcsr_copy(matrix_dummy2(iwindow), matrix_tmp2)
321 CALL dbcsr_add(matrix_tmp1, ls_scf_env%matrix_p(ispin), 1.0_dp, -1.0_dp)
323 IF (unit_nr > 0)
WRITE (unit_nr, *)
"Difference between Chebyshev DM and LS DM", frob_matrix
328 ls_scf_env%chebyshev%print_key_cube),
cp_p_file)
329 IF (write_cubes)
THEN
330 DO iwindow = 1, nwindow
331 WRITE (middle_name,
"(A,I0)")
"E_DENSITY_WINDOW_", iwindow
332 WRITE (title,
"(A,1X,F16.8,1X,A,1X,F16.8)")
"Energy range : ", ev1(iwindow),
"to", ev2(iwindow)
334 "", extension=
".cube", &
335 middle_name=trim(middle_name), log_filename=.false.)
346 unit_dos =
cp_print_key_unit_nr(logger, ls_scf_env%chebyshev%print_key_dos,
"", extension=
".xy", &
347 middle_name=
"DOS", log_filename=.false.)
349 IF (unit_dos > 0)
THEN
350 ALLOCATE (dos(1:n_gridpoint_dos))
351 ALLOCATE (gdensity(1:n_gridpoint_dos, 1:nwindow))
352 ALLOCATE (chev_e(1:n_gridpoint_dos))
353 ALLOCATE (chev_es_dos(1:n_gridpoint_dos))
354 ALLOCATE (dummy2(1:nwindow))
355 DO igrid = 1, n_gridpoint_dos
356 chev_e(igrid) = min_ev + (igrid - 1)*(max_ev - min_ev)/(n_gridpoint_dos - 1)
357 chev_es_dos(igrid) = (chev_e(igrid) - interval_b)/interval_a
359 DO igrid = 1, n_gridpoint_dos
363 CALL chebyshev_poly(chev_t_dos, chev_es_dos(igrid), icheb)
364 dummy1 = dummy1 + kernel_g(icheb)*mu(icheb)*chev_t_dos
365 DO iwindow = 1, nwindow
366 dummy2(iwindow) = dummy2(iwindow) + kernel_g(icheb)*aitchev_t(icheb, iwindow)*chev_t_dos
369 dos(igrid) = 1.0_dp/(interval_a*nrows* &
370 (
pi*sqrt(1.0_dp - chev_es_dos(igrid)*chev_es_dos(igrid))))*(kernel_g(1)*mu(1) + 2.0_dp*dummy1)
371 DO iwindow = 1, nwindow
372 gdensity(igrid, iwindow) = kernel_g(1)*aitchev_t(1, iwindow) + 2.0_dp*dummy2(iwindow)
374 WRITE (unit_dos,
'(1000F16.8)') chev_e(igrid), dos(igrid), gdensity(igrid, :)
376 DEALLOCATE (chev_es_dos, chev_e, dos, gdensity)
387 DO iwindow = 1, nwindow
391 DEALLOCATE (ev1, ev2, sev1, sev2, matrix_dummy2)
394 DEALLOCATE (mu, kernel_g, aitchev_t, e_inte, sqrt_vec)
396 IF (unit_nr > 0)
WRITE (unit_nr,
'(T2,A)')
"ENDING CHEBYSHEV CALCULATION"
398 CALL timestop(handle)