35 SUBROUTINE bloch_current(h, s, dh, ds, d, energies, current, status, coefficients)
36 COMPLEX(dp),
INTENT(IN) :: h(:, :), s(:, :), dh(:, :, :), &
37 ds(:, :, :), d(:, :, :)
38 REAL(
dp),
INTENT(OUT) :: energies(:)
39 COMPLEX(dp),
INTENT(OUT) :: current(:, :, :)
40 INTEGER,
INTENT(OUT) :: status
41 COMPLEX(dp),
INTENT(OUT),
OPTIONAL :: coefficients(:, :)
43 COMPLEX(dp),
ALLOCATABLE :: c(:, :)
45 REAL(
dp) :: residuals(2)
51 IF (
PRESENT(coefficients))
THEN
53 IF (any(shape(coefficients) /= [n, n]))
RETURN
57 IF (status /= 0)
RETURN
58 CALL bloch_current_from_frame(h, s, dh, ds, d, energies, c, current, 1.e-8_dp, residuals, status)
59 IF (status == 0 .AND.
PRESENT(coefficients)) coefficients = c
75 SUBROUTINE bloch_current_from_frame(h, s, dh, ds, d, energies, c, current, tolerance, residuals, status)
76 COMPLEX(dp),
INTENT(IN) :: h(:, :), s(:, :), dh(:, :, :), &
77 ds(:, :, :), d(:, :, :)
78 REAL(
dp),
INTENT(IN) :: energies(:)
79 COMPLEX(dp),
INTENT(IN) :: c(:, :)
80 COMPLEX(dp),
INTENT(OUT) :: current(:, :, :)
81 REAL(
dp),
INTENT(IN) :: tolerance
82 REAL(
dp),
INTENT(OUT) :: residuals(2)
83 INTEGER,
INTENT(OUT) :: status
85 COMPLEX(dp),
PARAMETER :: iu = (0.0_dp, 1.0_dp)
87 COMPLEX(dp),
ALLOCATABLE :: dc(:, :), hc(:, :), sc(:, :), v(:, :)
88 INTEGER :: axis, i, j, n
93 residuals = huge(1.0_dp)
95 IF (n < 1 .OR. any(shape(h) /= [n, n]) .OR. any(shape(s) /= [n, n]))
RETURN
96 IF (
SIZE(energies) /= n .OR. any(shape(current) /= [n, n, 3]))
RETURN
97 IF (any(shape(dh) /= [n, n, 3]) .OR. any(shape(ds) /= [n, n, 3]))
RETURN
98 IF (any(shape(d) /= [n, n, 3]))
RETURN
99 IF (any(shape(c) /= [n, n]))
RETURN
100 IF (.NOT. ieee_is_finite(tolerance) .OR. tolerance <= 0.0_dp .OR. tolerance >= 1.0_dp)
RETURN
101 IF (.NOT. all(ieee_is_finite(energies)))
RETURN
102 IF (.NOT. all(ieee_is_finite(real(c,
dp))) .OR. .NOT. all(ieee_is_finite(aimag(c))))
RETURN
103 IF (.NOT. all(ieee_is_finite(real(h,
dp))) .OR. .NOT. all(ieee_is_finite(aimag(h))))
RETURN
104 IF (.NOT. all(ieee_is_finite(real(s,
dp))) .OR. .NOT. all(ieee_is_finite(aimag(s))))
RETURN
105 IF (maxval(abs(h - conjg(transpose(h)))) > 1.e-9_dp*max(1.0_dp, maxval(abs(h))))
RETURN
106 IF (maxval(abs(s - conjg(transpose(s)))) > 1.e-9_dp*max(1.0_dp, maxval(abs(s))))
RETURN
107 IF (.NOT. finite(dh) .OR. .NOT. finite(ds) .OR. .NOT. finite(d))
RETURN
109 scale = max(tiny(1.0_dp), maxval(abs(dh(:, :, axis))))
110 IF (maxval(abs(dh(:, :, axis) - conjg(transpose(dh(:, :, axis))))) > 1.e-9_dp*scale)
RETURN
111 scale = max(tiny(1.0_dp), maxval(abs(ds(:, :, axis))))
112 IF (maxval(abs(ds(:, :, axis) - conjg(transpose(ds(:, :, axis))))) > 1.e-9_dp*scale)
RETURN
114 scale = max(1.0_dp, maxval(abs(ds(:, :, axis))), maxval(abs(d(:, :, axis))))
115 IF (maxval(abs(d(:, :, axis) - conjg(transpose(d(:, :, axis))) + iu*ds(:, :, axis))) &
116 > 1.e-9_dp*scale)
RETURN
119 ALLOCATE (hc(n, n), sc(n, n), dc(n, n), v(n, n))
120 sc(:, :) = matmul(conjg(transpose(c)), matmul(s, c))
121 hc(:, :) = matmul(conjg(transpose(c)), matmul(h, c))
123 sc(i, i) = sc(i, i) - 1.0_dp
124 hc(i, i) = hc(i, i) - energies(i)
126 residuals = [maxval(abs(sc)), maxval(abs(hc))/max(1.0_dp, maxval(abs(energies)))]
128 IF (.NOT. all(ieee_is_finite(residuals)) .OR. maxval(residuals) > tolerance)
RETURN
131 hc(:, :) = matmul(conjg(transpose(c)), matmul(dh(:, :, axis), c))
132 sc(:, :) = matmul(conjg(transpose(c)), matmul(ds(:, :, axis), c))
133 dc(:, :) = matmul(conjg(transpose(c)), matmul(d(:, :, axis), c))
136 v(i, j) = hc(i, j) - energies(i)*sc(i, j) + iu*(energies(i) - energies(j))*dc(i, j)
139 current(:, :, axis) = -iu*v
141 IF (.NOT. finite(current))
RETURN