34#include "../base/base_uses.f90"
40 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'orbital_transformation_matrices'
43 REAL(KIND=
dp),
DIMENSION(:, :),
POINTER :: c2s => null(), slm => null(), &
44 slm_inv => null(), s2c => null()
45 END TYPE orbtramat_type
47 TYPE(orbtramat_type),
DIMENSION(:),
POINTER ::
orbtramat => null()
50 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: mat => null()
70 SUBROUTINE create_spherical_harmonics(maxl)
72 INTEGER,
INTENT(IN) :: maxl
74 INTEGER :: expo, i, ic, ic1, ic2, is, j, k, l, lx, &
75 lx1, lx2, ly, ly1, ly2, lz, lz1, lz2, &
77 REAL(kind=
dp) :: s, s1, s2
83 CALL cp_abort(__location__, &
84 "Spherical harmonics are already allocated. "// &
85 "Use the init routine for an update")
89 CALL cp_abort(__location__, &
90 "A negative maximum angular momentum quantum "// &
126 IF ((j >= 0) .AND. (
modulo(j, 2) == 0))
THEN
132 IF (((m < 0) .AND. (
modulo(abs(ma - lx), 2) == 1)) .OR. &
133 ((m > 0) .AND. (
modulo(abs(ma - lx), 2) == 0)))
THEN
134 expo = (ma - lx + 2*k)/2
135 s = (-1.0_dp)**expo*sqrt(2.0_dp)
136 ELSE IF ((m == 0) .AND. (
modulo(lx, 2) == 0))
THEN
145 (-1.0_dp)**i*
fac(2*l - 2*i)/
fac(l - ma - 2*i)*s2
164 ic1 =
co(lx1, ly1, lz1)
165 s1 = sqrt((
fac(lx1)*
fac(ly1)*
fac(lz1))/ &
170 ic2 =
co(lx2, ly2, lz2)
174 IF ((
modulo(lx, 2) == 0) .AND. &
175 (
modulo(ly, 2) == 0) .AND. &
176 (
modulo(lz, 2) == 0))
THEN
177 s2 = sqrt((
fac(lx2)*
fac(ly2)*
fac(lz2))/ &
193 s = sqrt(0.25_dp*
dfac(2*l + 1)/
pi)
216 END SUBROUTINE create_spherical_harmonics
256 INTEGER,
INTENT(IN) :: maxl
257 INTEGER :: output_unit
259 CHARACTER(LEN=78) :: headline
266 CALL cp_abort(__location__, &
267 "A negative maximum angular momentum quantum "// &
274 CALL create_spherical_harmonics(maxl)
278 IF (output_unit > 0)
THEN
285 headline =
"CARTESIAN ORBITAL TO SPHERICAL ORBITAL "// &
286 "TRANSFORMATION MATRIX"
287 CALL write_matrix(
orbtramat(l)%c2s, l, output_unit, headline)
289 headline =
"SPHERICAL ORBITAL TO CARTESIAN ORBITAL "// &
290 "TRANSFORMATION MATRIX"
291 CALL write_matrix(
orbtramat(l)%s2c, l, output_unit, headline)
293 headline =
"SPHERICAL HARMONICS"
294 CALL write_matrix(
orbtramat(l)%slm, l, output_unit, headline)
296 headline =
"INVERSE SPHERICAL HARMONICS"
297 CALL write_matrix(
orbtramat(l)%slm_inv, l, output_unit, headline)
301 WRITE (unit=output_unit, fmt=
"(A)")
""
320 REAL(kind=
dp),
DIMENSION(3, 3) :: rotmat
321 INTEGER,
INTENT(IN) :: lval
323 INTEGER :: l, m1, m2, ns
324 REAL(kind=
dp) :: s3, u, uf, v, vf, w, wf
325 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: r
326 REAL(kind=
dp),
DIMENSION(-1:1, -1:1) :: r1
327 REAL(kind=
dp),
DIMENSION(-2:2, -2:2) :: r2
328 REAL(kind=
dp),
DIMENSION(3, 3) :: t
332 ALLOCATE (orbrotmat(0:lval))
335 ALLOCATE (orbrotmat(l)%mat(ns, ns))
339 orbrotmat(0)%mat = 1.0_dp
342 t(1, 1:3) = rotmat(2, 1:3)
343 t(2, 1:3) = rotmat(3, 1:3)
344 t(3, 1:3) = rotmat(1, 1:3)
345 r1(-1:1, -1) = t(1:3, 2)
346 r1(-1:1, 0) = t(1:3, 3)
347 r1(-1:1, 1) = t(1:3, 1)
348 orbrotmat(1)%mat(1:3, 1:3) = r1(-1:1, -1:1)
353 r2(0, 0) = (3.0_dp*r1(0, 0)**2 - 1.0_dp)*0.5_dp
354 r2(0, 1) = s3*r1(0, 1)*r1(0, 0)
355 r2(0, -1) = s3*r1(0, -1)*r1(0, 0)
356 r2(0, -2) = s3*(r1(0, 1)**2 - r1(0, -1)**2)*0.5_dp
357 r2(0, -2) = s3*r1(0, 1)*r1(0, -1)
359 r2(1, 0) = s3*r1(1, 0)*r1(0, 0)
360 r2(1, 1) = r1(1, 1)*r1(0, 0) + r1(1, 0)*r1(0, 1)
361 r2(1, -1) = r1(1, -1)*r1(0, 0) + r1(1, 0)*r1(0, -1)
362 r2(1, 2) = r1(1, 1)*r1(0, 1) - r1(1, -1)*r1(0, -1)
363 r2(1, -2) = r1(1, 1)*r1(0, -1) + r1(1, -1)*r1(0, 1)
365 r2(-1, 0) = s3*r1(-1, 0)*r1(0, 0)
366 r2(-1, 1) = r1(-1, 1)*r1(0, 0) + r1(-1, 0)*r1(0, 1)
367 r2(-1, -1) = r1(-1, -1)*r1(0, 0) + r1(-1, 0)*r1(0, -1)
368 r2(-1, 2) = r1(-1, 1)*r1(0, 1) - r1(-1, -1)*r1(0, -1)
369 r2(-1, -2) = r1(-1, 1)*r1(0, -1) + r1(-1, -1)*r1(0, 1)
371 r2(2, 0) = s3*(r1(1, 0)**2 - r1(-1, 0)**2)*0.5_dp
372 r2(2, 1) = r1(1, 1)*r1(1, 0) - r1(-1, 1)*r1(-1, 0)
373 r2(2, -1) = r1(1, -1)*r1(1, 0) - r1(-1, -1)*r1(-1, 0)
374 r2(2, 2) = (r1(1, 1)**2 - r1(1, -1)**2 - r1(-1, 1)**2 + r1(-1, -1)**2)*0.5_dp
375 r2(2, -2) = r1(1, 1)*r1(1, -1) - r1(-1, 1)*r1(-1, -1)
377 r2(-2, 0) = s3*r1(1, 0)*r1(-1, 0)
378 r2(2, 1) = r1(1, 1)*r1(-1, 0) + r1(1, 0)*r1(-1, 1)
379 r2(2, -1) = r1(1, -1)*r1(-1, 0) + r1(1, 0)*r1(-1, -1)
380 r2(2, 2) = r1(1, 1)*r1(-1, 1) - r1(1, -1)*r1(-1, -1)
381 r2(2, -2) = r1(1, 1)*r1(-1, -1) + r1(1, -1)*r1(-1, 1)
383 orbrotmat(2)%mat(1:5, 1:5) = r2(-2:2, -2:2)
387 ALLOCATE (r(0:lval, -lval:lval, -lval:lval))
390 r(1, -1:1, -1:1) = r1(-1:1, -1:1)
391 r(2, -2:2, -2:2) = r2(-2:2, -2:2)
395 u = u_func(l, m1, m2)
396 v = v_func(l, m1, m2)
397 w = w_func(l, m1, m2)
398 CALL r_recursion(l, m1, m2, r1, r, lval, uf, vf, wf)
399 r(l, m1, m2) = u*uf + v*vf + w*wf
405 orbrotmat(l)%mat(1:ns, 1:ns) = r(l, -l:l, -l:l)
419 FUNCTION u_func(l, ma, mb)
RESULT(u)
423 IF (abs(mb) == l)
THEN
424 u = real((l + ma)*(l - ma), kind=
dp)/real(2*l*(2*l - 1), kind=
dp)
426 ELSE IF (abs(mb) < l)
THEN
427 u = real((l + ma)*(l - ma), kind=
dp)/real((l + mb)*(l - mb), kind=
dp)
430 cpabort(
"Illegal m value")
441 FUNCTION v_func(l, ma, mb)
RESULT(v)
445 INTEGER :: a1, a2, dm0
449 IF (abs(mb) == l)
THEN
450 a1 = (1 + dm0)*(l + abs(ma) - 1)*(l + abs(ma))
452 ELSE IF (abs(mb) < l)
THEN
453 a1 = (1 + dm0)*(l + abs(ma) - 1)*(l + abs(ma))
454 a2 = (l + mb)*(l - mb)
456 cpabort(
"Illegal m value")
458 v = 0.5_dp*sqrt(real(a1, kind=
dp)/real(a2, kind=
dp))*real(1 - 2*dm0, kind=
dp)
468 FUNCTION w_func(l, ma, mb)
RESULT(w)
472 INTEGER :: a1, a2, dm0
476 IF (abs(mb) == l)
THEN
477 a1 = (l - abs(ma) - 1)*(l - abs(ma))
479 ELSE IF (abs(mb) < l)
THEN
480 a1 = (l - abs(ma) - 1)*(l - abs(ma))
481 a2 = (l + mb)*(l - mb)
483 cpabort(
"Illegal m value")
485 w = -0.5_dp*sqrt(real(a1, kind=
dp)/real(a2, kind=
dp))*real(1 - dm0, kind=
dp)
499 FUNCTION p_func(i, l, mu, m, r1, r, lr)
RESULT(p)
500 INTEGER :: i, l, mu, m
501 REAL(kind=
dp),
DIMENSION(-1:1, -1:1) :: r1
503 REAL(kind=
dp),
DIMENSION(0:lr, -lr:lr, -lr:lr) :: r
507 p = r1(i, 1)*r(l - 1, mu, m) - r1(i, -1)*r(l - 1, mu, -m)
508 ELSE IF (m == -l)
THEN
509 p = r1(i, 1)*r(l - 1, mu, m) + r1(i, -1)*r(l - 1, mu, -m)
510 ELSE IF (abs(m) < l)
THEN
511 p = r1(i, 0)*r(l - 1, mu, m)
513 cpabort(
"Illegal m value")
529 SUBROUTINE r_recursion(l, ma, mb, r1, r, lr, u, v, w)
531 REAL(kind=
dp),
DIMENSION(-1:1, -1:1) :: r1
533 REAL(kind=
dp),
DIMENSION(0:lr, -lr:lr, -lr:lr) :: r
534 REAL(kind=
dp) :: u, v, w
539 u = p_func(0, l, 0, mb, r1, r, lr)
540 v = p_func(1, l, 1, mb, r1, r, lr) + p_func(-1, l, -1, mb, r1, r, lr)
542 ELSE IF (ma > 0)
THEN
544 IF (ma == 1) dd = 1.0_dp
545 u = p_func(0, l, ma, mb, r1, r, lr)
546 v = p_func(1, l, ma - 1, mb, r1, r, lr)*sqrt(1.0_dp + dd) - p_func(-1, l, -ma + 1, mb, r1, r, lr)*(1.0_dp - dd)
547 w = p_func(1, l, ma + 1, mb, r1, r, lr) + p_func(-1, l, -1 - ma, mb, r1, r, lr)
548 ELSE IF (ma < 0)
THEN
550 IF (ma == -1) dd = 1.0_dp
551 u = p_func(0, l, ma, mb, r1, r, lr)
552 v = p_func(1, l, ma + 1, mb, r1, r, lr)*(1.0_dp - dd) + p_func(-1, l, -ma - 1, mb, r1, r, lr)*sqrt(1.0_dp + dd)
553 w = p_func(1, l, ma - 1, mb, r1, r, lr) - p_func(-1, l, -ma + 1, mb, r1, r, lr)
566 IF (
ASSOCIATED(orbrotmat))
THEN
567 DO i = lbound(orbrotmat, 1), ubound(orbrotmat, 1)
568 IF (
ASSOCIATED(orbrotmat(i)%mat))
DEALLOCATE (orbrotmat(i)%mat)
570 DEALLOCATE (orbrotmat)
590 SUBROUTINE write_matrix(matrix, l, lunit, headline)
592 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: matrix
593 INTEGER,
INTENT(IN) :: l, lunit
594 CHARACTER(LEN=*),
INTENT(IN) :: headline
596 CHARACTER(12) :: symbol
597 CHARACTER(LEN=78) :: string
598 INTEGER :: from, i, ic, is, jc, lx, ly, lz, m, nc, &
603 WRITE (unit=lunit, fmt=
"(/,/,T2,A)") trim(headline)
611 to = min(nc, from + 2)
614 DO ly = l - lx, 0, -1
617 IF ((jc >= from) .AND. (jc <= to))
THEN
619 WRITE (unit=string(i:), fmt=
"(A18)") trim(symbol(3:12))
624 WRITE (unit=lunit, fmt=
"(/,T8,A)") trim(string)
629 WRITE (unit=lunit, fmt=
"(T4,A4,3(1X,F17.12))") &
630 symbol(3:6), (matrix(is, jc), jc=from, to)
634 END SUBROUTINE write_matrix
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
Defines the basic variable types.
integer, parameter, public dp
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
real(kind=dp), dimension(-1:2 *maxfac+1), parameter, public dfac
real(kind=dp), dimension(0:maxfac), parameter, public fac
Collection of simple mathematical functions and subroutines.
elemental real(kind=dp) function, public binomial(n, k)
The binomial coefficient n over k for 0 <= k <= n is calculated, otherwise zero is returned.
Provides Cartesian and spherical orbital pointers and indices.
integer, save, public current_maxl
integer, dimension(:, :, :), allocatable, public co
integer, dimension(:), allocatable, public nco
integer, dimension(:), allocatable, public nsoset
integer, dimension(:), allocatable, public ncoset
integer, dimension(:), allocatable, public nso
character(len=12) function, public cgf_symbol(n, lxyz)
Build a Cartesian orbital symbol (orbital labels for printing).
character(len=6) function, public sgf_symbol(n, l, m)
Build a spherical orbital symbol (orbital labels for printing).