(git:6344619)
Loading...
Searching...
No Matches
kubo_projected.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Finite projected-Hamiltonian current in a nonorthogonal, possibly spinor AO basis.
10!> \author Thomas D. Kuehne, tkuehne@cp2k.org
11! **************************************************************************************************
13 USE ieee_arithmetic, ONLY: ieee_is_finite
14#if defined(__HAS_IEEE_EXCEPTIONS)
15 USE ieee_exceptions, ONLY: ieee_all, ieee_get_halting_mode, ieee_set_halting_mode
16#endif
17 USE kinds, ONLY: dp
18 IMPLICIT NONE
19 PRIVATE
21CONTAINS
22! **************************************************************************************************
23!> \brief Compute C^dagger (H S^-1 X - X S^-1 H) C without forming S^-1.
24!> \param h Complete scalar/spinor covariant Hamiltonian, not an occupied-state projection
25!> \param s Positive definite overlap, with explicit spin blocks when applicable
26!> \param positions Three analytic covariant Cartesian first moments
27!> \param energies Eigenvalues of H C = S C E
28!> \param current Anti-Hermitian commutators in the eigenbasis; velocity is i*current in atomic units
29!> \param status 0 success; -1 invalid matrices; -2 ill-conditioned metric; positive LAPACK failure
30!> \note This is the commutator of projected operators. It is not the projection of the
31!> continuum commutator in an incomplete basis, nor a periodic Berry velocity.
32! **************************************************************************************************
33 SUBROUTINE projected_current(h, s, positions, energies, current, status)
34 COMPLEX(dp), INTENT(IN) :: h(:, :), s(:, :), positions(:, :, :)
35 REAL(dp), INTENT(OUT) :: energies(:)
36 COMPLEX(dp), INTENT(OUT) :: current(:, :, :)
37 INTEGER, INTENT(OUT) :: status
38
39 COMPLEX(dp), ALLOCATABLE :: c(:, :), moment(:, :)
40 INTEGER :: axis, i, j, n
41
42 status = -1
43 energies = 0.0_dp
44 current = 0.0_dp
45 n = SIZE(h, 1)
46 IF (n < 1 .OR. SIZE(h, 2) /= n .OR. any(shape(s) /= [n, n])) RETURN
47 IF (SIZE(energies) /= n .OR. any(shape(current) /= [n, n, 3])) RETURN
48 IF (any(shape(positions) /= [n, n, 3])) RETURN
49 IF (.NOT. valid_hermitian(h) .OR. .NOT. valid_hermitian(s)) RETURN
50 DO axis = 1, 3
51 IF (.NOT. valid_hermitian(positions(:, :, axis))) RETURN
52 END DO
53 ALLOCATE (c(n, n), moment(n, n))
54 CALL projected_eigensystem(h, s, energies, c, status)
55 IF (status /= 0) RETURN
56 status = -1
57 DO axis = 1, 3
58 moment(:, :) = matmul(conjg(transpose(c)), matmul(positions(:, :, axis), c))
59 DO j = 1, n
60 DO i = 1, n
61 current(i, j, axis) = (energies(i) - energies(j))*moment(i, j)
62 END DO
63 END DO
64 END DO
65 IF (.NOT. all(ieee_is_finite(real(current, dp)))) RETURN
66 IF (.NOT. all(ieee_is_finite(aimag(current)))) RETURN
67 status = 0
68 END SUBROUTINE projected_current
69! **************************************************************************************************
70!> \brief Complete generalized eigensystem with a positive, well-conditioned AO metric.
71!> \param h Hermitian covariant Hamiltonian
72!> \param s Hermitian positive definite overlap
73!> \param energies Complete spectrum
74!> \param c Metric-orthonormal eigenvectors
75!> \param status 0 success; -1 invalid matrices; -2 metric failure; positive LAPACK failure
76! **************************************************************************************************
77 SUBROUTINE projected_eigensystem(h, s, energies, c, status)
78 COMPLEX(dp), INTENT(IN) :: h(:, :), s(:, :)
79 REAL(dp), INTENT(OUT) :: energies(:)
80 COMPLEX(dp), INTENT(OUT) :: c(:, :)
81 INTEGER, INTENT(OUT) :: status
82
83 COMPLEX(dp), ALLOCATABLE :: b(:, :), work(:)
84 REAL(dp), ALLOCATABLE :: rwork(:)
85 INTEGER :: n, info
86#if defined(__HAS_IEEE_EXCEPTIONS)
87 LOGICAL :: halt(size(ieee_all))
88#endif
89
90 status = -1
91 energies = 0.0_dp
92 c = 0.0_dp
93 n = SIZE(h, 1)
94 IF (n < 1 .OR. SIZE(h, 2) /= n .OR. any(shape(s) /= [n, n])) RETURN
95 IF (SIZE(energies) /= n .OR. any(shape(c) /= [n, n])) RETURN
96 IF (.NOT. valid_hermitian(h) .OR. .NOT. valid_hermitian(s)) RETURN
97 ALLOCATE (b(n, n), work(max(1, 2*n)), rwork(max(1, 3*n)))
98 b(:, :) = s
99#if defined(__HAS_IEEE_EXCEPTIONS)
100 CALL ieee_get_halting_mode(ieee_all, halt)
101 CALL ieee_set_halting_mode(ieee_all, .false.)
102#endif
103 CALL zheev('N', 'U', n, b, n, energies, work, SIZE(work), rwork, info)
104#if defined(__HAS_IEEE_EXCEPTIONS)
105 CALL ieee_set_halting_mode(ieee_all, halt)
106#endif
107 status = abs(info) + 1
108 IF (info /= 0 .OR. .NOT. all(ieee_is_finite(energies))) RETURN
109 status = -2
110 IF (maxval(energies) <= 0.0_dp) RETURN
111 IF (minval(energies) <= 1.e-10_dp*maxval(energies)) RETURN
112 c = h
113 b(:, :) = s
114#if defined(__HAS_IEEE_EXCEPTIONS)
115 CALL ieee_set_halting_mode(ieee_all, .false.)
116#endif
117 CALL zhegv(1, 'V', 'U', n, c, n, b, n, energies, work, SIZE(work), rwork, info)
118#if defined(__HAS_IEEE_EXCEPTIONS)
119 CALL ieee_set_halting_mode(ieee_all, halt)
120#endif
121 status = abs(info) + 1
122 IF (info /= 0 .OR. .NOT. all(ieee_is_finite(energies))) RETURN
123 IF (.NOT. all(ieee_is_finite(real(c, dp)))) RETURN
124 IF (.NOT. all(ieee_is_finite(aimag(c)))) RETURN
125 status = 0
126 END SUBROUTINE projected_eigensystem
127! **************************************************************************************************
128!> \brief Reject nonfinite or non-Hermitian data instead of discarding a triangle.
129!> \param a Covariant matrix
130!> \return Whether both components are finite and Hermitian within tolerance
131! **************************************************************************************************
132 LOGICAL FUNCTION valid_hermitian(a) RESULT(valid)
133 COMPLEX(dp), INTENT(IN) :: a(:, :)
134
135 valid = all(ieee_is_finite(real(a, dp))) .AND. all(ieee_is_finite(aimag(a)))
136 IF (.NOT. valid) RETURN
137 valid = maxval(abs(a - conjg(transpose(a)))) <= 1.e-10_dp*max(tiny(1.0_dp), maxval(abs(a)))
138 END FUNCTION valid_hermitian
139END MODULE kubo_projected
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Finite projected-Hamiltonian current in a nonorthogonal, possibly spinor AO basis.
subroutine, public projected_current(h, s, positions, energies, current, status)
Compute C^dagger (H S^-1 X - X S^-1 H) C without forming S^-1.
subroutine, public projected_eigensystem(h, s, energies, c, status)
Complete generalized eigensystem with a positive, well-conditioned AO metric.