(git:d5c4d39)
Loading...
Searching...
No Matches
orbital_transformation_matrices_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!--------------------------------------------------------------------------------------------------!
8 USE kinds, ONLY: dp
14#include "../base/base_uses.f90"
15
16 IMPLICIT NONE
17
18 INTEGER, PARAMETER :: lmax = 5
19 REAL(kind=dp), PARAMETER :: eps = 1.0e-12_dp
20 REAL(kind=dp), DIMENSION(3, 3) :: rotmat
21 TYPE(orbrotmat_type), DIMENSION(:), POINTER :: orbrot => null()
22
23 CALL init_orbital_pointers(lmax)
24
25 rotmat = 0.0_dp
26 rotmat(1, 1) = 1.0_dp
27 rotmat(2, 2) = 1.0_dp
28 rotmat(3, 3) = 1.0_dp
29 CALL calculate_rotmat(orbrot, rotmat, lmax)
30 CALL check_identity(orbrot)
31 CALL check_orthogonal(orbrot)
32
33 CALL make_z_rotation(0.7_dp, rotmat)
34 CALL calculate_rotmat(orbrot, rotmat, lmax)
35 CALL check_orthogonal(orbrot)
36
37 CALL make_axis_rotation([1.0_dp, 2.0_dp, 3.0_dp], 0.37_dp, rotmat)
38 CALL calculate_rotmat(orbrot, rotmat, lmax)
39 CALL check_orthogonal(orbrot)
40
41 CALL release_rotmat(orbrot)
43
44CONTAINS
45
46! **************************************************************************************************
47!> \brief Check that the identity Cartesian rotation produces identity band matrices.
48!> \param orbrot ...
49! **************************************************************************************************
50 SUBROUTINE check_identity(orbrot)
51 TYPE(orbrotmat_type), DIMENSION(:), POINTER :: orbrot
52
53 INTEGER :: i, l, n
54 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: ref
55
56 DO l = lbound(orbrot, 1), ubound(orbrot, 1)
57 n = SIZE(orbrot(l)%mat, 1)
58 ALLOCATE (ref(n, n))
59 ref = 0.0_dp
60 DO i = 1, n
61 ref(i, i) = 1.0_dp
62 END DO
63 IF (maxval(abs(orbrot(l)%mat - ref)) > eps) THEN
64 cpabort("Bad identity rotation")
65 END IF
66 DEALLOCATE (ref)
67 END DO
68
69 END SUBROUTINE check_identity
70
71! **************************************************************************************************
72!> \brief Check orthogonality of all band rotation matrices.
73!> \param orbrot ...
74! **************************************************************************************************
75 SUBROUTINE check_orthogonal(orbrot)
76 TYPE(orbrotmat_type), DIMENSION(:), POINTER :: orbrot
77
78 INTEGER :: i, j, k, l, n
79 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: ident, prod
80
81 DO l = lbound(orbrot, 1), ubound(orbrot, 1)
82 n = SIZE(orbrot(l)%mat, 1)
83 ALLOCATE (ident(n, n), prod(n, n))
84 ident = 0.0_dp
85 DO i = 1, n
86 ident(i, i) = 1.0_dp
87 END DO
88 prod = 0.0_dp
89 DO j = 1, n
90 DO k = 1, n
91 DO i = 1, n
92 prod(i, j) = prod(i, j) + orbrot(l)%mat(i, k)*orbrot(l)%mat(j, k)
93 END DO
94 END DO
95 END DO
96 IF (maxval(abs(prod - ident)) > eps) THEN
97 cpabort("Bad rotation orthogonality")
98 END IF
99 DEALLOCATE (ident, prod)
100 END DO
101
102 END SUBROUTINE check_orthogonal
103
104! **************************************************************************************************
105!> \brief Build a Cartesian rotation around the z axis.
106!> \param angle ...
107!> \param rotmat ...
108! **************************************************************************************************
109 SUBROUTINE make_z_rotation(angle, rotmat)
110 REAL(kind=dp), INTENT(IN) :: angle
111 REAL(kind=dp), DIMENSION(3, 3), INTENT(OUT) :: rotmat
112
113 REAL(kind=dp) :: c, s
114
115 c = cos(angle)
116 s = sin(angle)
117 rotmat = 0.0_dp
118 rotmat(1, 1) = c
119 rotmat(1, 2) = -s
120 rotmat(2, 1) = s
121 rotmat(2, 2) = c
122 rotmat(3, 3) = 1.0_dp
123
124 END SUBROUTINE make_z_rotation
125
126! **************************************************************************************************
127!> \brief Build a Cartesian rotation around an arbitrary axis.
128!> \param axis ...
129!> \param angle ...
130!> \param rotmat ...
131! **************************************************************************************************
132 SUBROUTINE make_axis_rotation(axis, angle, rotmat)
133 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: axis
134 REAL(kind=dp), INTENT(IN) :: angle
135 REAL(kind=dp), DIMENSION(3, 3), INTENT(OUT) :: rotmat
136
137 REAL(kind=dp) :: c, norm, one_c, s, x, y, z
138
139 norm = sqrt(sum(axis**2))
140 cpassert(norm > 0.0_dp)
141 x = axis(1)/norm
142 y = axis(2)/norm
143 z = axis(3)/norm
144 c = cos(angle)
145 s = sin(angle)
146 one_c = 1.0_dp - c
147
148 rotmat(1, 1) = c + x*x*one_c
149 rotmat(1, 2) = x*y*one_c - z*s
150 rotmat(1, 3) = x*z*one_c + y*s
151 rotmat(2, 1) = y*x*one_c + z*s
152 rotmat(2, 2) = c + y*y*one_c
153 rotmat(2, 3) = y*z*one_c - x*s
154 rotmat(3, 1) = z*x*one_c - y*s
155 rotmat(3, 2) = z*y*one_c + x*s
156 rotmat(3, 3) = c + z*z*one_c
157
158 END SUBROUTINE make_axis_rotation
159
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Provides Cartesian and spherical orbital pointers and indices.
subroutine, public init_orbital_pointers(maxl)
Initialize or update the orbital pointers.
subroutine, public deallocate_orbital_pointers()
Deallocate the orbital pointers.
Calculation of the spherical harmonics and the corresponding orbital transformation matrices.
subroutine, public calculate_rotmat(orbrotmat, rotmat, lval)
Calculate rotation matrices for spherical harmonics up to value l Joseph Ivanic and Klaus Ruedenberg ...
subroutine, public release_rotmat(orbrotmat)
Release rotation matrices.
program orbital_transformation_matrices_unittest
subroutine check_identity(orbrot)
Check that the identity Cartesian rotation produces identity band matrices.