(git:f2099e5)
Loading...
Searching...
No Matches
topology_curvature_unittest.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
9 USE kinds, ONLY: dp
13
14 IMPLICIT NONE
15 REAL(kind=dp), PARAMETER :: pi = 3.1415926535897932384626433832795_dp, tolerance = 1.e-11_dp
16 COMPLEX(KIND=dp) :: p(2, 2, 6), q(2, 2, 6), g(2, 2), link(2, 2)
17 REAL(kind=dp) :: value, maximum, minimum, coarse, fine
18 INTEGER :: i, status
19 p(:, :, :) = 0.0_dp
20 DO i = 1, 6
21 p(1, 1, i) = 1.0_dp
22 p(2, 2, i) = 1.0_dp
23 END DO
24 p(1, 1, 1) = exp(cmplx(0.0_dp, 0.2_dp, dp))
25 p(2, 2, 1) = exp(cmplx(0.0_dp, -0.1_dp, dp))
26 p(1, 1, 6) = exp(cmplx(0.0_dp, 0.3_dp, dp))
27 p(2, 2, 6) = exp(cmplx(0.0_dp, 0.4_dp, dp))
28 CALL curvature_density(p, 4, pi/2.0_dp, value, maximum, status)
29 IF (status /= 0 .OR. abs(value - 0.02_dp/(4.0_dp*pi*pi)) > tolerance) error stop 'Incorrect C2 product trace'
30 g(1, :) = [cmplx(1.0_dp, 0.0_dp, dp), cmplx(0.0_dp, 1.0_dp, dp)]/sqrt(2.0_dp)
31 g(2, :) = [cmplx(0.0_dp, 1.0_dp, dp), cmplx(1.0_dp, 0.0_dp, dp)]/sqrt(2.0_dp)
32 DO i = 1, 6
33 q(:, :, i) = matmul(conjg(transpose(g)), matmul(p(:, :, i), g))
34 END DO
35 CALL curvature_density(q, 4, pi/2.0_dp, value, maximum, status)
36 IF (status /= 0 .OR. abs(value - 0.02_dp/(4.0_dp*pi*pi)) > tolerance) error stop 'C2 gauge covariance failed'
37 CALL curvature_density(p(:, :, 1:1), 2, pi/2.0_dp, value, maximum, status)
38 IF (status /= 0 .OR. abs(value + 0.1_dp/(2.0_dp*pi)) > tolerance) error stop 'Incorrect determinant C1 phase'
39 CALL curvature_density(p, 4, 0.1_dp, value, maximum, status)
40 IF (status /= -3) error stop 'Unresolved C2 phase accepted'
41 p(:, :, 1) = 0.0_dp
42 CALL polar_link(p(:, :, 1), link, minimum, status, tolerance)
43 IF (status == 0) error stop 'Singular link accepted'
44 CALL curvature_density(p, 4, pi/2.0_dp, value, maximum, status)
45 IF (status /= -2) error stop 'Nonunitary plaquette accepted'
46 CALL dirac_pairing(6, coarse)
47 CALL dirac_pairing(8, fine)
48 IF (abs(fine + 1.0_dp) >= abs(coarse + 1.0_dp)) error stop 'C2 Dirac refinement failed'
49 IF (abs(fine + 0.742412846261164_dp) > 1.e-6_dp) error stop 'Incorrect non-Abelian Dirac C2'
50CONTAINS
51
52! **************************************************************************************************
53!> \brief Non-Abelian occupied doublet of the 4D Dirac model, exact C2=-1 at mass -3.
54!> \param n ...
55!> \param RESULT ...
56! **************************************************************************************************
57 SUBROUTINE dirac_pairing(n, RESULT)
58 INTEGER, INTENT(IN) :: n
59 REAL(KIND=dp), INTENT(OUT) :: result
60
61 COMPLEX(KIND=dp) :: gamma(4, 4, 5), h(4, 4), id(2, 2), &
62 overlap(2, 2), plaquettes(2, 2, 6), &
63 sx(2, 2), sy(2, 2), sz(2, 2), work(32)
64 COMPLEX(KIND=dp), ALLOCATABLE :: links(:, :, :, :), states(:, :, :)
65 INTEGER :: at_mu, at_nu, d, INDEX(4), mu, nu, &
66 other, p, rem, status, v
67 REAL(KIND=dp) :: evals(4), k(4), local_value, maximum, &
68 minimum, rwork(12)
69
70 sx = 0.0_dp
71 sx(1, 2) = 1.0_dp
72 sx(2, 1) = 1.0_dp
73 sy = cmplx(0.0_dp, 1.0_dp, dp)*sx
74 sy(1, 2) = -sy(1, 2)
75 sz = 0.0_dp
76 sz(1, 1) = 1.0_dp
77 sz(2, 2) = -1.0_dp
78 id = 0.0_dp
79 id(1, 1) = 1.0_dp
80 id(2, 2) = 1.0_dp
81 CALL tensor(sx, sx, gamma(:, :, 1))
82 CALL tensor(sx, sy, gamma(:, :, 2))
83 CALL tensor(sx, sz, gamma(:, :, 3))
84 CALL tensor(sy, id, gamma(:, :, 4))
85 CALL tensor(sz, id, gamma(:, :, 5))
86 ALLOCATE (states(4, 2, n**4), links(2, 2, 4, n**4))
87 DO v = 1, n**4
88 rem = v - 1
89 DO d = 1, 4
90 index(d) = mod(rem, n)
91 rem = rem/n
92 END DO
93 k = 2.0_dp*pi*real(index, dp)/real(n, dp)
94 h = cmplx(0.0_dp, 0.0_dp, dp)
95 DO d = 1, 4
96 h = h + sin(k(d))*gamma(:, :, d)
97 END DO
98 h = h + (-3.0_dp + sum(cos(k)))*gamma(:, :, 5)
99 CALL zheev('V', 'U', 4, h, 4, evals, work, SIZE(work), rwork, status)
100 IF (status /= 0) error stop 'Dirac eigensolver failed'
101 states(:, :, v) = h(:, 1:2)
102 END DO
103 DO v = 1, n**4
104 DO d = 1, 4
105 other = neighbour(v, d, n)
106 overlap = matmul(conjg(transpose(states(:, :, v))), states(:, :, other))
107 CALL polar_link(overlap, links(:, :, d, v), minimum, status, tolerance)
108 IF (status /= 0) error stop 'Singular Dirac link'
109 END DO
110 END DO
111 result = 0.0_dp
112 DO v = 1, n**4
113 p = 0
114 DO mu = 1, 4
115 DO nu = mu + 1, 4
116 p = p + 1
117 at_mu = neighbour(v, mu, n)
118 at_nu = neighbour(v, nu, n)
119 CALL link_plaquette(links(:, :, mu, v), links(:, :, nu, at_mu), links(:, :, mu, at_nu), &
120 links(:, :, nu, v), plaquettes(:, :, p))
121 END DO
122 END DO
123 CALL curvature_density(plaquettes, 4, pi/2.0_dp, local_value, maximum, status)
124 IF (status /= 0) error stop 'Invalid Dirac plaquette'
125 result = result + local_value
126 END DO
127 END SUBROUTINE dirac_pairing
128
129! **************************************************************************************************
130!> \brief Periodic forward neighbour in a first-axis-fastest mesh.
131!> \param v ...
132!> \param d ...
133!> \param n ...
134!> \return ...
135! **************************************************************************************************
136 INTEGER FUNCTION neighbour(v, d, n) RESULT(other)
137 INTEGER, INTENT(IN) :: v, d, n
138
139 INTEGER :: coordinate, stride
140
141 stride = n**(d - 1)
142 coordinate = mod((v - 1)/stride, n)
143 other = v + stride
144 IF (coordinate == n - 1) other = other - n*stride
145 END FUNCTION neighbour
146
147! **************************************************************************************************
148!> \brief Kronecker product of two 2x2 matrices.
149!> \param a ...
150!> \param b ...
151!> \param c ...
152! **************************************************************************************************
153 SUBROUTINE tensor(a, b, c)
154 COMPLEX(KIND=dp), INTENT(IN) :: a(2, 2), b(2, 2)
155 COMPLEX(KIND=dp), INTENT(OUT) :: c(4, 4)
156
157 INTEGER :: i, j
158
159 DO j = 1, 2
160 DO i = 1, 2
161 c(2*i - 1:2*i, 2*j - 1:2*j) = a(i, j)*b
162 END DO
163 END DO
164 END SUBROUTINE tensor
Calculation of the incomplete Gamma function F_n(t) for multi-center integrals over Cartesian Gaussia...
Definition gamma.F:15
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.
subroutine dirac_pairing(n, result)
Non-Abelian occupied doublet of the 4D Dirac model, exact C2=-1 at mass -3.
program topology_curvature_unittest