17 USE dbcsr_api,
ONLY: &
18 dbcsr_add, dbcsr_add_on_diag, dbcsr_copy, dbcsr_create, dbcsr_deallocate_matrix, &
19 dbcsr_filter, dbcsr_frobenius_norm, dbcsr_multiply, dbcsr_p_type, dbcsr_scale, dbcsr_set, &
20 dbcsr_transposed, dbcsr_type, dbcsr_type_complex_8
22 #include "./base/base_uses.f90"
28 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'ls_matrix_exp'
64 B_re, B_im, beta, C_re, C_im, filter_eps)
65 CHARACTER(LEN=1),
INTENT(IN) :: transa, transb
66 REAL(kind=
dp),
INTENT(IN) :: alpha
67 TYPE(dbcsr_type),
INTENT(IN) :: a_re, a_im, b_re, b_im
68 REAL(kind=
dp),
INTENT(IN) :: beta
69 TYPE(dbcsr_type),
INTENT(INOUT) :: c_re, c_im
70 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: filter_eps
72 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_complex_dbcsr_gemm_3'
73 REAL(kind=
dp),
PARAMETER :: one = 1.0_dp, zero = 0.0_dp
75 CHARACTER(LEN=1) :: transa2, transb2
77 REAL(kind=
dp) :: alpha2, alpha3, alpha4
78 TYPE(dbcsr_type),
POINTER :: a_plus_b, ac, bd, c_plus_d
80 CALL timeset(routinen, handle)
89 IF (transa ==
"C")
THEN
96 IF (transb ==
"C")
THEN
107 CALL dbcsr_create(ac, template=a_re, matrix_type=
"N")
110 CALL dbcsr_create(bd, template=a_re, matrix_type=
"N")
113 CALL dbcsr_create(a_plus_b, template=a_re, matrix_type=
"N")
116 CALL dbcsr_create(c_plus_d, template=a_re, matrix_type=
"N")
119 CALL dbcsr_multiply(transa2, transb2, alpha, a_re, b_re, zero, ac, filter_eps=filter_eps)
120 CALL dbcsr_multiply(transa2, transb2, alpha2, a_im, b_im, zero, bd, filter_eps=filter_eps)
122 CALL dbcsr_add(a_plus_b, a_re, zero, alpha)
123 CALL dbcsr_add(a_plus_b, a_im, one, alpha3)
124 CALL dbcsr_add(c_plus_d, b_re, zero, alpha)
125 CALL dbcsr_add(c_plus_d, b_im, one, alpha4)
129 CALL dbcsr_multiply(transa2, transb2, one/alpha, a_plus_b, c_plus_d, beta, c_im, filter_eps=filter_eps)
132 CALL dbcsr_add(c_re, ac, beta, one)
134 CALL dbcsr_add(c_re, bd, one, one)
135 CALL dbcsr_filter(c_re, filter_eps)
137 CALL dbcsr_add(c_im, ac, one, -one)
139 CALL dbcsr_add(c_im, bd, one, one)
140 CALL dbcsr_filter(c_im, filter_eps)
143 CALL dbcsr_deallocate_matrix(ac)
144 CALL dbcsr_deallocate_matrix(bd)
145 CALL dbcsr_deallocate_matrix(a_plus_b)
146 CALL dbcsr_deallocate_matrix(c_plus_d)
148 CALL timestop(handle)
164 TYPE(dbcsr_p_type),
DIMENSION(2) :: exp_h
165 TYPE(dbcsr_type),
POINTER :: im_matrix
166 INTEGER,
INTENT(in) :: nsquare, ntaylor
167 REAL(kind=
dp),
INTENT(in) :: filter_eps
169 CHARACTER(len=*),
PARAMETER :: routinen =
'taylor_only_imaginary_dbcsr'
170 REAL(kind=
dp),
PARAMETER :: one = 1.0_dp, zero = 0.0_dp
172 INTEGER :: handle, i, nloop
173 REAL(kind=
dp) :: square_fac, tfac, tmp
174 TYPE(dbcsr_type),
POINTER :: t1, t2, tres_im, tres_re
176 CALL timeset(routinen, handle)
179 square_fac = 1.0_dp/(2.0_dp**real(nsquare,
dp))
184 CALL dbcsr_create(t1, template=im_matrix, matrix_type=
"N")
187 CALL dbcsr_create(t2, template=im_matrix, matrix_type=
"N")
190 CALL dbcsr_create(tres_re, template=im_matrix, matrix_type=
"N")
193 CALL dbcsr_create(tres_im, template=im_matrix, matrix_type=
"N")
196 CALL dbcsr_set(t1, zero)
197 CALL dbcsr_add_on_diag(t1, one)
198 CALL dbcsr_set(tres_re, zero)
199 CALL dbcsr_add_on_diag(tres_re, one)
200 CALL dbcsr_set(tres_im, zero)
202 nloop = ceiling(real(ntaylor,
dp)/2.0_dp)
206 CALL dbcsr_scale(t1, 1.0_dp/(real(i,
dp)*2.0_dp - 1.0_dp))
207 CALL dbcsr_filter(t1, filter_eps)
208 CALL dbcsr_multiply(
"N",
"N", square_fac, im_matrix, t1, zero, &
209 t2, filter_eps=filter_eps)
211 IF (mod(i, 2) == 0) tfac = -tfac
212 CALL dbcsr_add(tres_im, t2, one, tfac)
213 CALL dbcsr_scale(t2, 1.0_dp/(real(i,
dp)*2.0_dp))
214 CALL dbcsr_filter(t2, filter_eps)
215 CALL dbcsr_multiply(
"N",
"N", square_fac, im_matrix, t2, zero, &
216 t1, filter_eps=filter_eps)
218 IF (mod(i, 2) == 1) tfac = -tfac
219 CALL dbcsr_add(tres_re, t1, one, tfac)
223 IF (nsquare .GT. 0)
THEN
226 tres_re, tres_im, zero, exp_h(1)%matrix, exp_h(2)%matrix, &
227 filter_eps=filter_eps)
228 CALL dbcsr_copy(tres_re, exp_h(1)%matrix)
229 CALL dbcsr_copy(tres_im, exp_h(2)%matrix)
232 CALL dbcsr_copy(exp_h(1)%matrix, tres_re)
233 CALL dbcsr_copy(exp_h(2)%matrix, tres_im)
235 CALL dbcsr_deallocate_matrix(t1)
236 CALL dbcsr_deallocate_matrix(t2)
237 CALL dbcsr_deallocate_matrix(tres_re)
238 CALL dbcsr_deallocate_matrix(tres_im)
240 CALL timestop(handle)
258 TYPE(dbcsr_p_type),
DIMENSION(2) :: exp_h
259 TYPE(dbcsr_type),
POINTER :: re_part, im_part
260 INTEGER,
INTENT(in) :: nsquare, ntaylor
261 REAL(kind=
dp),
INTENT(in) :: filter_eps
263 CHARACTER(len=*),
PARAMETER :: routinen =
'taylor_full_complex_dbcsr'
264 COMPLEX(KIND=dp),
PARAMETER :: one = (1.0_dp, 0.0_dp), &
265 zero = (0.0_dp, 0.0_dp)
267 COMPLEX(KIND=dp) :: square_fac
269 TYPE(dbcsr_type),
POINTER :: t1, t2, t3, tres
271 CALL timeset(routinen, handle)
274 square_fac = cmplx(1.0_dp/(2.0_dp**real(nsquare,
dp)), 0.0_dp, kind=
dp)
279 CALL dbcsr_create(t1, template=re_part, matrix_type=
"N", &
280 data_type=dbcsr_type_complex_8)
283 CALL dbcsr_create(t2, template=re_part, matrix_type=
"N", &
284 data_type=dbcsr_type_complex_8)
287 CALL dbcsr_create(t3, template=re_part, matrix_type=
"N", &
288 data_type=dbcsr_type_complex_8)
291 CALL dbcsr_create(tres, template=re_part, matrix_type=
"N", &
292 data_type=dbcsr_type_complex_8)
295 CALL dbcsr_copy(t3, re_part)
296 CALL dbcsr_copy(tres, im_part)
297 CALL dbcsr_scale(tres, cmplx(0.0_dp, 1.0_dp, kind=
dp))
298 CALL dbcsr_add(t3, tres, one, one)
301 CALL dbcsr_set(t1, zero)
302 CALL dbcsr_add_on_diag(t1, one)
303 CALL dbcsr_set(tres, zero)
304 CALL dbcsr_add_on_diag(tres, one)
307 CALL dbcsr_scale(t1, one/cmplx(i*1.0_dp, 0.0_dp, kind=
dp))
308 CALL dbcsr_filter(t1, filter_eps)
309 CALL dbcsr_multiply(
"N",
"N", square_fac, t1, t3, &
310 zero, t2, filter_eps=filter_eps)
311 CALL dbcsr_add(tres, t2, one, one)
312 CALL dbcsr_copy(t1, t2)
315 IF (nsquare .GT. 0)
THEN
317 CALL dbcsr_multiply(
"N",
"N", one, tres, tres, zero, &
318 t2, filter_eps=filter_eps)
319 CALL dbcsr_copy(tres, t2)
323 CALL dbcsr_copy(exp_h(1)%matrix, tres, keep_imaginary=.false.)
324 CALL dbcsr_scale(tres, cmplx(0.0_dp, -1.0_dp, kind=
dp))
325 CALL dbcsr_copy(exp_h(2)%matrix, tres, keep_imaginary=.false.)
327 CALL dbcsr_deallocate_matrix(t1)
328 CALL dbcsr_deallocate_matrix(t2)
329 CALL dbcsr_deallocate_matrix(t3)
330 CALL dbcsr_deallocate_matrix(tres)
332 CALL timestop(handle)
349 TYPE(dbcsr_type),
POINTER :: propagator, density_re, density_im
350 REAL(kind=
dp),
INTENT(in) :: filter_eps, filter_eps_small, eps_exp
352 CHARACTER(len=*),
PARAMETER :: routinen =
'bch_expansion_imaginary_propagator'
353 REAL(kind=
dp),
PARAMETER :: one = 1.0_dp, zero = 0.0_dp
355 INTEGER :: handle, i, unit_nr
356 LOGICAL :: convergence
357 REAL(kind=
dp) :: alpha, max_alpha, prefac
358 TYPE(dbcsr_type),
POINTER :: comm, comm2, tmp, tmp2
360 CALL timeset(routinen, handle)
366 CALL dbcsr_create(tmp, template=propagator)
369 CALL dbcsr_create(tmp2, template=propagator)
372 CALL dbcsr_create(comm, template=propagator)
375 CALL dbcsr_create(comm2, template=propagator)
377 CALL dbcsr_copy(tmp, density_re)
378 CALL dbcsr_copy(tmp2, density_im)
380 convergence = .false.
383 CALL dbcsr_multiply(
"N",
"N", -prefac, propagator, tmp2, zero, comm, &
384 filter_eps=filter_eps_small)
385 CALL dbcsr_multiply(
"N",
"N", prefac, propagator, tmp, zero, comm2, &
386 filter_eps=filter_eps_small)
387 CALL dbcsr_transposed(tmp, comm)
388 CALL dbcsr_transposed(tmp2, comm2)
389 CALL dbcsr_add(comm, tmp, one, one)
390 CALL dbcsr_add(comm2, tmp2, one, -one)
391 CALL dbcsr_add(density_re, comm, one, one)
392 CALL dbcsr_add(density_im, comm2, one, one)
393 CALL dbcsr_copy(tmp, comm)
394 CALL dbcsr_copy(tmp2, comm2)
397 alpha = dbcsr_frobenius_norm(comm)
398 IF (alpha > max_alpha) max_alpha = alpha
399 alpha = dbcsr_frobenius_norm(comm2)
400 IF (alpha > max_alpha) max_alpha = alpha
401 IF (max_alpha < eps_exp) convergence = .true.
402 IF (convergence)
THEN
403 IF (unit_nr > 0)
WRITE (unit=unit_nr, fmt=
"((T3,A,I2,A))") &
404 "BCH converged after ", i,
" steps"
409 CALL dbcsr_filter(density_re, filter_eps)
410 CALL dbcsr_filter(density_im, filter_eps)
412 IF (.NOT. convergence) &
413 cpwarn(
"BCH method did not converge")
415 CALL dbcsr_deallocate_matrix(tmp)
416 CALL dbcsr_deallocate_matrix(tmp2)
417 CALL dbcsr_deallocate_matrix(comm)
418 CALL dbcsr_deallocate_matrix(comm2)
420 CALL timestop(handle)
438 filter_eps_small, eps_exp)
439 TYPE(dbcsr_type),
POINTER :: propagator_re, propagator_im, &
440 density_re, density_im
441 REAL(kind=
dp),
INTENT(in) :: filter_eps, filter_eps_small, eps_exp
443 CHARACTER(len=*),
PARAMETER :: routinen =
'bch_expansion_complex_propagator'
444 REAL(kind=
dp),
PARAMETER :: one = 1.0_dp, zero = 0.0_dp
446 INTEGER :: handle, i, unit_nr
447 LOGICAL :: convergence
448 REAL(kind=
dp) :: alpha, max_alpha, prefac
449 TYPE(dbcsr_type),
POINTER :: comm, comm2, tmp, tmp2
451 CALL timeset(routinen, handle)
457 CALL dbcsr_create(tmp, template=propagator_re)
460 CALL dbcsr_create(tmp2, template=propagator_re)
463 CALL dbcsr_create(comm, template=propagator_re)
466 CALL dbcsr_create(comm2, template=propagator_re)
468 CALL dbcsr_copy(tmp, density_re)
469 CALL dbcsr_copy(tmp2, density_im)
471 convergence = .false.
476 tmp, tmp2, zero, comm, comm2, filter_eps=filter_eps_small)
477 CALL dbcsr_transposed(tmp, comm)
478 CALL dbcsr_transposed(tmp2, comm2)
479 CALL dbcsr_add(comm, tmp, one, one)
480 CALL dbcsr_add(comm2, tmp2, one, -one)
481 CALL dbcsr_add(density_re, comm, one, one)
482 CALL dbcsr_add(density_im, comm2, one, one)
483 CALL dbcsr_copy(tmp, comm)
484 CALL dbcsr_copy(tmp2, comm2)
487 alpha = dbcsr_frobenius_norm(comm)
488 IF (alpha > max_alpha) max_alpha = alpha
489 alpha = dbcsr_frobenius_norm(comm2)
490 IF (alpha > max_alpha) max_alpha = alpha
491 IF (max_alpha < eps_exp) convergence = .true.
492 IF (convergence)
THEN
493 IF (unit_nr > 0)
WRITE (unit=unit_nr, fmt=
"((T3,A,I2,A))") &
494 "BCH converged after ", i,
" steps"
499 CALL dbcsr_filter(density_re, filter_eps)
500 CALL dbcsr_filter(density_im, filter_eps)
502 IF (.NOT. convergence) &
503 cpwarn(
"BCH method did not converge ")
505 CALL dbcsr_deallocate_matrix(tmp)
506 CALL dbcsr_deallocate_matrix(tmp2)
507 CALL dbcsr_deallocate_matrix(comm)
508 CALL dbcsr_deallocate_matrix(comm2)
510 CALL timestop(handle)
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
Defines the basic variable types.
integer, parameter, public dp
Routines for calculating a complex matrix exponential with dbcsr matrices. Based on the code in matri...
subroutine, public bch_expansion_imaginary_propagator(propagator, density_re, density_im, filter_eps, filter_eps_small, eps_exp)
The Baker-Campbell-Hausdorff expansion for a purely imaginary exponent (e.g. rtp) Works for a non uni...
subroutine, public taylor_only_imaginary_dbcsr(exp_H, im_matrix, nsquare, ntaylor, filter_eps)
specialized subroutine for purely imaginary matrix exponentials
subroutine, public taylor_full_complex_dbcsr(exp_H, re_part, im_part, nsquare, ntaylor, filter_eps)
subroutine for general complex matrix exponentials on input a separate dbcsr_type for real and comple...
subroutine, public bch_expansion_complex_propagator(propagator_re, propagator_im, density_re, density_im, filter_eps, filter_eps_small, eps_exp)
The Baker-Campbell-Hausdorff expansion for a complex exponent (e.g. rtp) Works for a non unitary prop...
subroutine, public cp_complex_dbcsr_gemm_3(transa, transb, alpha, A_re, A_im, B_re, B_im, beta, C_re, C_im, filter_eps)
Convenience function. Computes the matrix multiplications needed for the multiplication of complex sp...