23 USE dbcsr_api,
ONLY: &
24 dbcsr_add, dbcsr_add_on_diag, dbcsr_copy, dbcsr_create, dbcsr_frobenius_norm, &
25 dbcsr_get_info, dbcsr_get_occupation, dbcsr_multiply, dbcsr_release, dbcsr_scale, &
26 dbcsr_set, dbcsr_trace, dbcsr_type, dbcsr_type_no_symmetry
37 #include "./base/base_uses.f90"
43 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'dm_ls_chebyshev'
58 SUBROUTINE chebyshev_poly(value, x, n)
59 REAL(KIND=
dp),
INTENT(OUT) ::
value
60 REAL(KIND=
dp),
INTENT(IN) :: x
61 INTEGER,
INTENT(IN) :: n
66 value = cos((n - 1)*acos(x))
68 END SUBROUTINE chebyshev_poly
79 SUBROUTINE kernel(value, n, nc)
80 REAL(KIND=
dp),
INTENT(OUT) ::
value
81 INTEGER,
INTENT(IN) :: n, nc
88 value = 1.0_dp/(nc + 1.0_dp)*((nc - (n - 1) + 1.0_dp)* &
89 cos(
pi*(n - 1)/(nc + 1.0_dp)) + sin(
pi*(n - 1)/(nc + 1.0_dp))*1.0_dp/tan(
pi/(nc + 1.0_dp)))
102 TYPE(qs_environment_type),
POINTER :: qs_env
103 TYPE(ls_scf_env_type) :: ls_scf_env
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
121 TYPE(cp_logger_type),
POINTER :: logger
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)
arnoldi iteration using dbcsr
subroutine, public arnoldi_extremal(matrix_a, max_ev, min_ev, converged, threshold, max_iter)
simple wrapper to estimate extremal eigenvalues with arnoldi, using the old lanczos interface this hi...
various routines to log and control the output. The idea is that decisions about where to log should ...
recursive integer function, public cp_logger_get_default_unit_nr(logger, local, skip_not_ionode)
asks the default unit number of the given logger. try to use cp_logger_get_unit_nr
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
integer, parameter, public cp_p_file
integer function, public cp_print_key_should_output(iteration_info, basis_section, print_key_path, used_print_key, first_time)
returns what should be done with the given property if btest(res,cp_p_store) then the property should...
Routines using linear scaling chebyshev methods.
subroutine, public compute_chebyshev(qs_env, ls_scf_env)
compute properties based on chebyshev expansion
Routines for a linear scaling quickstep SCF run based on the density matrix, with a focus on the inte...
subroutine, public write_matrix_to_cube(qs_env, ls_scf_env, matrix_p_ls, unit_nr, title, stride)
...
Types needed for a linear scaling quickstep SCF run based on the density matrix.
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
Machine interface based on Fortran 2003 and POSIX.
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi