LCOV - code coverage report
Current view: top level - src/common - wignernj_interface.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:9ccafda) Lines: 100.0 % 6 6
Test Date: 2026-10-15 00:55:44 Functions: 100.0 % 2 2

            Line data    Source code
       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 Interface to libwignernj for the angular momentum algebra
      10              : !> \note
      11              : !>      libwignernj carries out all intermediate arithmetic exactly, in a prime
      12              : !>      factorization representation, and rounds only once at the end. The
      13              : !>      returned coefficients are therefore correct to the last bit, whereas the
      14              : !>      factorial-ratio expressions that CP2K used before lost roughly one digit
      15              : !>      per two units of l.
      16              : !>
      17              : !>      The library takes all angular momenta as twice their value so that
      18              : !>      half-integers stay exact; the wrappers here take the plain integer l and
      19              : !>      m of a spherical harmonic and do the doubling.
      20              : !>
      21              : !>      The real spherical harmonics S(l,m) follow the Condon-Shortley
      22              : !>      convention
      23              : !>          S(l, 0)   = Y(l,0)
      24              : !>          S(l, m>0) = ( Y(l,-m) + (-1)^m Y(l,m) )/sqrt(2)
      25              : !>          S(l, m<0) = ( Y(l,m) - (-1)^|m| Y(l,-m) )*i/sqrt(2)
      26              : !>      which is the same convention as spherical_harmonics::y_lm, so no
      27              : !>      additional phase is needed on either side.
      28              : !>
      29              : !>      The interfaces below bind directly to the C API, so no compiler-specific
      30              : !>      Fortran module from libwignernj is required.
      31              : !> \par History
      32              : !>      09.2026 created [Susi Lehtola]
      33              : !> \author Susi Lehtola
      34              : ! **************************************************************************************************
      35              : MODULE wignernj_interface
      36              : 
      37              :    USE ISO_C_BINDING,                   ONLY: C_DOUBLE,&
      38              :                                               C_INT
      39              :    USE kinds,                           ONLY: dp
      40              : #include "../base/base_uses.f90"
      41              : 
      42              :    IMPLICIT NONE
      43              : 
      44              :    PRIVATE
      45              : 
      46              :    PUBLIC :: real_gaunt, complex_gaunt
      47              : 
      48              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'wignernj_interface'
      49              : 
      50              :    INTERFACE
      51              : ! **************************************************************************************************
      52              : !> \brief Gaunt coefficient of three complex spherical harmonics
      53              : !> \param tl1 twice the angular momentum of the first harmonic
      54              : !> \param tm1 twice the magnetic quantum number of the first harmonic
      55              : !> \param tl2 twice the angular momentum of the second harmonic
      56              : !> \param tm2 twice the magnetic quantum number of the second harmonic
      57              : !> \param tl3 twice the angular momentum of the third harmonic
      58              : !> \param tm3 twice the magnetic quantum number of the third harmonic
      59              : !> \return integral of Y(l1,m1)*Y(l2,m2)*Y(l3,m3) over the unit sphere
      60              : ! **************************************************************************************************
      61              :       FUNCTION gaunt_c(tl1, tm1, tl2, tm2, tl3, tm3) BIND(C, name="gaunt")
      62              :          IMPORT :: C_DOUBLE, C_INT
      63              :          INTEGER(KIND=C_INT), VALUE                      :: tl1, tm1, tl2, tm2, tl3, tm3
      64              :          REAL(KIND=C_DOUBLE)                             :: gaunt_c
      65              :       END FUNCTION gaunt_c
      66              : 
      67              : ! **************************************************************************************************
      68              : !> \brief Gaunt coefficient of three real spherical harmonics
      69              : !> \param tl1 twice the angular momentum of the first harmonic
      70              : !> \param tm1 twice the magnetic quantum number of the first harmonic
      71              : !> \param tl2 twice the angular momentum of the second harmonic
      72              : !> \param tm2 twice the magnetic quantum number of the second harmonic
      73              : !> \param tl3 twice the angular momentum of the third harmonic
      74              : !> \param tm3 twice the magnetic quantum number of the third harmonic
      75              : !> \return integral of S(l1,m1)*S(l2,m2)*S(l3,m3) over the unit sphere
      76              : ! **************************************************************************************************
      77              :       FUNCTION gaunt_real_c(tl1, tm1, tl2, tm2, tl3, tm3) BIND(C, name="gaunt_real")
      78              :          IMPORT :: C_DOUBLE, C_INT
      79              :          INTEGER(KIND=C_INT), VALUE                      :: tl1, tm1, tl2, tm2, tl3, tm3
      80              :          REAL(KIND=C_DOUBLE)                             :: gaunt_real_c
      81              :       END FUNCTION gaunt_real_c
      82              :    END INTERFACE
      83              : 
      84              : CONTAINS
      85              : 
      86              : ! **************************************************************************************************
      87              : !> \brief Gaunt coefficient of three real spherical harmonics,
      88              : !>        int S(l1,m1) S(l2,m2) S(l3,m3) dOmega
      89              : !> \param l1 angular momentum of the first harmonic
      90              : !> \param m1 magnetic quantum number of the first harmonic
      91              : !> \param l2 angular momentum of the second harmonic
      92              : !> \param m2 magnetic quantum number of the second harmonic
      93              : !> \param l3 angular momentum of the third harmonic
      94              : !> \param m3 magnetic quantum number of the third harmonic
      95              : !> \return the Gaunt coefficient, zero if the selection rules are violated
      96              : ! **************************************************************************************************
      97      1977912 :    FUNCTION real_gaunt(l1, m1, l2, m2, l3, m3) RESULT(g)
      98              :       INTEGER, INTENT(IN)                                :: l1, m1, l2, m2, l3, m3
      99              :       REAL(KIND=dp)                                      :: g
     100              : 
     101      1977912 :       g = REAL(gaunt_real_c(2*l1, 2*m1, 2*l2, 2*m2, 2*l3, 2*m3), KIND=dp)
     102              : 
     103      1977912 :    END FUNCTION real_gaunt
     104              : 
     105              : ! **************************************************************************************************
     106              : !> \brief Gaunt coefficient of three complex spherical harmonics,
     107              : !>        int Y(l1,m1) Y(l2,m2) Y(l3,m3) dOmega
     108              : !> \param l1 angular momentum of the first harmonic
     109              : !> \param m1 magnetic quantum number of the first harmonic
     110              : !> \param l2 angular momentum of the second harmonic
     111              : !> \param m2 magnetic quantum number of the second harmonic
     112              : !> \param l3 angular momentum of the third harmonic
     113              : !> \param m3 magnetic quantum number of the third harmonic
     114              : !> \return the Gaunt coefficient, zero if the selection rules are violated
     115              : ! **************************************************************************************************
     116       921600 :    FUNCTION complex_gaunt(l1, m1, l2, m2, l3, m3) RESULT(g)
     117              :       INTEGER, INTENT(IN)                                :: l1, m1, l2, m2, l3, m3
     118              :       REAL(KIND=dp)                                      :: g
     119              : 
     120       921600 :       g = REAL(gaunt_c(2*l1, 2*m1, 2*l2, 2*m2, 2*l3, 2*m3), KIND=dp)
     121              : 
     122       921600 :    END FUNCTION complex_gaunt
     123              : 
     124              : END MODULE wignernj_interface
        

Generated by: LCOV version 2.0-1