(git:691081d)
Loading...
Searching...
No Matches
topology_curvature.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 Gauge-covariant C1/C2 plaquette kernels, independent of the state representation.
10!> \note C2 is the second Chern character pairing, not generally the second Chern class.
11! **************************************************************************************************
13 USE ieee_arithmetic, ONLY: ieee_is_finite
14 USE kinds, ONLY: dp
16
17 IMPLICIT NONE
18 PRIVATE
19 REAL(KIND=dp), PARAMETER :: pi = 3.1415926535897932384626433832795_dp, unitary_tol = 1.e-8_dp
21CONTAINS
22
23! **************************************************************************************************
24!> \brief Polar-unitarize a physical link, retaining its minimum singular value.
25!> \param overlap Raw selected-state overlap matrix
26!> \param link Unitary polar factor
27!> \param minimum Smallest singular value of the raw overlap
28!> \param status Zero on success; nonzero for an invalid or singular link
29!> \param tolerance Minimum allowed singular value
30! **************************************************************************************************
31 SUBROUTINE polar_link(overlap, link, minimum, status, tolerance)
32 COMPLEX(KIND=dp), INTENT(IN) :: overlap(:, :)
33 COMPLEX(KIND=dp), INTENT(OUT) :: link(:, :)
34 REAL(kind=dp), INTENT(OUT) :: minimum
35 INTEGER, INTENT(OUT) :: status
36 REAL(kind=dp), INTENT(IN) :: tolerance
37
38 INTEGER :: i
39
40 link(:, :) = 0.0_dp
41 DO i = 1, min(SIZE(link, 1), SIZE(link, 2))
42 link(i, i) = 1.0_dp
43 END DO
44 CALL wilson_step(link, overlap, minimum, status, tolerance)
45 END SUBROUTINE polar_link
46
47! **************************************************************************************************
48!> \brief Oriented plaquette U_mu(x) U_nu(x+mu) U_mu(x+nu)^dagger U_nu(x)^dagger.
49!> \param u_mu Link in direction mu based at x
50!> \param u_nu_at_mu Link in direction nu based at x+mu
51!> \param u_mu_at_nu Link in direction mu based at x+nu
52!> \param u_nu Link in direction nu based at x
53!> \param p Oriented unitary plaquette based at x
54! **************************************************************************************************
55 SUBROUTINE link_plaquette(u_mu, u_nu_at_mu, u_mu_at_nu, u_nu, p)
56 COMPLEX(KIND=dp), INTENT(IN) :: u_mu(:, :), u_nu_at_mu(:, :), &
57 u_mu_at_nu(:, :), u_nu(:, :)
58 COMPLEX(KIND=dp), INTENT(OUT) :: p(:, :)
59
60 p(:, :) = matmul(matmul(u_mu, u_nu_at_mu), matmul(conjg(transpose(u_mu_at_nu)), conjg(transpose(u_nu))))
61 END SUBROUTINE link_plaquette
62
63! **************************************************************************************************
64!> \brief Local contribution to C1 or C2. Report unrounded values and reject unresolved phases.
65!> \param plaquettes Order 12 for C1; 12,13,14,23,24,34 for C2; all based at the same vertex
66!> \param ndim Parameter dimension, 2 or 4
67!> \param phase_limit Maximum allowed principal plaquette phase, strictly between zero and pi
68!> \param value Unrounded local contribution
69!> \param maximum Maximum absolute plaquette phase
70!> \param status Zero on success, negative invalid/unresolved input, positive LAPACK failure
71! **************************************************************************************************
72 SUBROUTINE curvature_density(plaquettes, ndim, phase_limit, value, maximum, status)
73 COMPLEX(KIND=dp), INTENT(IN) :: plaquettes(:, :, :)
74 INTEGER, INTENT(IN) :: ndim
75 REAL(kind=dp), INTENT(IN) :: phase_limit
76 REAL(kind=dp), INTENT(OUT) :: value, maximum
77 INTEGER, INTENT(OUT) :: status
78
79 COMPLEX(KIND=dp), ALLOCATABLE :: a(:, :), e(:), f(:, :, :), term(:, :), &
80 v(:, :), work(:)
81 INTEGER :: i, j, n, np, sdim
82 LOGICAL, ALLOCATABLE :: bwork(:)
83 REAL(kind=dp) :: determinant_phase
84 REAL(kind=dp), ALLOCATABLE :: phase(:), rwork(:)
85
86 status = -1
87 value = 0.0_dp
88 maximum = 0.0_dp
89 IF (ndim /= 2 .AND. ndim /= 4) RETURN
90 IF (.NOT. ieee_is_finite(phase_limit)) RETURN
91 IF (phase_limit <= 0.0_dp .OR. phase_limit >= pi) RETURN
92 n = SIZE(plaquettes, 1)
93 np = ndim*(ndim - 1)/2
94 IF (n < 1 .OR. SIZE(plaquettes, 2) /= n .OR. SIZE(plaquettes, 3) /= np) RETURN
95 IF (.NOT. all(ieee_is_finite(real(plaquettes, dp)))) RETURN
96 IF (.NOT. all(ieee_is_finite(aimag(plaquettes)))) RETURN
97 ALLOCATE (a(n, n), v(n, n), e(n), work(4*n), rwork(n), phase(n), bwork(n), f(n, n, np), term(n, n))
98 DO j = 1, np
99 a(:, :) = plaquettes(:, :, j)
100 term(:, :) = matmul(conjg(transpose(a)), a)
101 DO i = 1, n
102 term(i, i) = term(i, i) - 1.0_dp
103 END DO
104 IF (maxval(abs(term)) > unitary_tol) THEN
105 status = -2
106 RETURN
107 END IF
108 CALL zgees('V', 'N', select_none, n, a, n, sdim, e, v, n, work, SIZE(work), rwork, bwork, status)
109 IF (status /= 0) RETURN
110 phase(:) = atan2(aimag(e), real(e, dp))
111 IF (ndim == 2) THEN
112 determinant_phase = atan2(sin(sum(phase)), cos(sum(phase)))
113 maximum = abs(determinant_phase)
114 value = -determinant_phase/(2.0_dp*pi)
115 ELSE
116 maximum = max(maximum, maxval(abs(phase)))
117 a(:, :) = v
118 DO i = 1, n
119 a(:, i) = cmplx(0.0_dp, phase(i), dp)*v(:, i)
120 END DO
121 f(:, :, j) = matmul(a, conjg(transpose(v)))
122 END IF
123 IF (maximum >= phase_limit) THEN
124 status = -3
125 RETURN
126 END IF
127 END DO
128 IF (ndim == 4) THEN
129 term(:, :) = matmul(f(:, :, 1), f(:, :, 6)) - matmul(f(:, :, 2), f(:, :, 5)) + matmul(f(:, :, 3), f(:, :, 4))
130 DO i = 1, n
131 value = value - real(term(i, i), dp)/(4.0_dp*pi*pi)
132 END DO
133 END IF
134 status = 0
135 END SUBROUTINE curvature_density
136
137! **************************************************************************************************
138!> \brief Unused eigenvalue-selection callback for an unsorted complex Schur decomposition.
139!> \param z Eigenvalue supplied by LAPACK
140!> \return Always false; no eigenvalue reordering is requested
141! **************************************************************************************************
142 LOGICAL FUNCTION select_none(z)
143 COMPLEX(KIND=dp), INTENT(IN) :: z
144
145 select_none = .false.
146 IF (.NOT. ieee_is_finite(real(z, dp))) select_none = .false.
147 END FUNCTION select_none
148END MODULE topology_curvature
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Gauge-covariant C1/C2 plaquette kernels, independent of the state representation.
subroutine, public polar_link(overlap, link, minimum, status, tolerance)
Polar-unitarize a physical link, retaining its minimum singular value.
subroutine, public link_plaquette(u_mu, u_nu_at_mu, u_mu_at_nu, u_nu, p)
Oriented plaquette U_mu(x) U_nu(x+mu) U_mu(x+nu)^dagger U_nu(x)^dagger.
subroutine, public curvature_density(plaquettes, ndim, phase_limit, value, maximum, status)
Local contribution to C1 or C2. Report unrounded values and reject unresolved phases.
Local Wilson-loop linear algebra, independent of the electronic-structure representation....
subroutine, public wilson_step(product, overlap, minimum_sv, status, sv_tol)
Multiply by the unitary polar factor of an overlap. Reject rank-deficient links.