LCOV - code coverage report
Current view: top level - src/aobasis - orbital_pointers.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:4dc10b3) Lines: 81 87 93.1 %
Date: 2024-11-21 06:45:46 Functions: 3 3 100.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief Provides Cartesian and spherical orbital pointers and indices
      10             : !> \par History
      11             : !>      - reallocate eliminated (17.07.2002,MK)
      12             : !>      - restructured and cleaned (20.05.2004,MK)
      13             : !> \author Matthias Krack (07.06.2000)
      14             : ! **************************************************************************************************
      15             : MODULE orbital_pointers
      16             : 
      17             : ! co    : Cartesian orbital pointer for a orbital shell.
      18             : ! coset : Cartesian orbital pointer for a set of orbitals.
      19             : ! nco   : Number of Cartesian orbitals for the angular momentum quantum
      20             : !         number l.
      21             : ! ncoset: Number of Cartesian orbitals up to the angular momentum quantum
      22             : !         number l.
      23             : ! nso   : Number of spherical orbitals for the angular momentum quantum
      24             : !         number l.
      25             : ! nsoset: Number of spherical orbitals up to the angular momentum quantum
      26             : !         number l.
      27             : 
      28             : !$ USE OMP_LIB, ONLY: omp_get_level
      29             : 
      30             : #include "../base/base_uses.f90"
      31             : 
      32             :    IMPLICIT NONE
      33             : 
      34             :    PRIVATE
      35             : 
      36             : ! *** Global parameters ***
      37             : 
      38             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'orbital_pointers'
      39             : 
      40             :    INTEGER, SAVE :: current_maxl = -1
      41             : 
      42             :    INTEGER, DIMENSION(:), ALLOCATABLE     :: nco, ncoset, nso, nsoset
      43             :    INTEGER, DIMENSION(:, :), ALLOCATABLE   :: indco, indso, indso_inv
      44             :    INTEGER, DIMENSION(:, :), ALLOCATABLE   :: so, soset
      45             :    INTEGER, DIMENSION(:, :, :), ALLOCATABLE :: co, coset
      46             : 
      47             : ! *** Public subroutines ***
      48             : 
      49             :    PUBLIC :: deallocate_orbital_pointers, &
      50             :              init_orbital_pointers
      51             : 
      52             : ! *** Public variables ***
      53             : 
      54             :    PUBLIC :: co, &
      55             :              coset, &
      56             :              current_maxl, &
      57             :              indco, &
      58             :              indso, &
      59             :              indso_inv, &
      60             :              nco, &
      61             :              ncoset, &
      62             :              nso, &
      63             :              nsoset, &
      64             :              soset
      65             : 
      66             : CONTAINS
      67             : 
      68             : ! **************************************************************************************************
      69             : !> \brief  Allocate and initialize the orbital pointers.
      70             : !> \param maxl ...
      71             : !> \date   20.05.2004
      72             : !> \author MK
      73             : !> \version 1.0
      74             : ! **************************************************************************************************
      75        8991 :    SUBROUTINE create_orbital_pointers(maxl)
      76             :       INTEGER, INTENT(IN)                                :: maxl
      77             : 
      78             :       INTEGER                                            :: iso, l, lx, ly, lz, m
      79             : 
      80        8991 :       IF (current_maxl > -1) THEN
      81             :          CALL cp_abort(__LOCATION__, &
      82             :                        "Orbital pointers are already allocated. "// &
      83           0 :                        "Use the init routine for an update")
      84             :       END IF
      85             : 
      86        8991 :       IF (maxl < 0) THEN
      87             :          CALL cp_abort(__LOCATION__, &
      88             :                        "A negative maximum angular momentum quantum "// &
      89           0 :                        "number is invalid")
      90             :       END IF
      91             : 
      92        8991 : !$    IF (omp_get_level() > 0) &
      93           0 : !$       CPABORT("create_orbital_pointers is not thread-safe")
      94             : 
      95             : !   *** Number of Cartesian orbitals for each l ***
      96             : 
      97       26973 :       ALLOCATE (nco(-1:maxl))
      98             : 
      99        8991 :       nco(-1) = 0
     100             : 
     101       70535 :       DO l = 0, maxl
     102       70535 :          nco(l) = (l + 1)*(l + 2)/2
     103             :       END DO
     104             : 
     105             : !   *** Number of Cartesian orbitals up to l ***
     106             : 
     107       26973 :       ALLOCATE (ncoset(-1:maxl))
     108             : 
     109        8991 :       ncoset(-1) = 0
     110             : 
     111       70535 :       DO l = 0, maxl
     112       70535 :          ncoset(l) = ncoset(l - 1) + nco(l)
     113             :       END DO
     114             : 
     115             : !   *** Build the Cartesian orbital pointer and the shell orbital pointer ***
     116             : 
     117       44955 :       ALLOCATE (co(0:maxl, 0:maxl, 0:maxl))
     118             : 
     119     4535279 :       co(:, :, :) = 0
     120             : 
     121       44955 :       ALLOCATE (coset(-1:maxl, -1:maxl, -1:maxl))
     122             : 
     123     6245904 :       coset(:, :, :) = 0
     124             : 
     125      670249 :       coset(-1, :, :) = 1
     126      670249 :       coset(:, -1, :) = 1
     127      670249 :       coset(:, :, -1) = 1
     128             : 
     129       70535 :       DO lx = 0, maxl
     130      529179 :          DO ly = 0, maxl
     131     4526288 :             DO lz = 0, maxl
     132     4006100 :                l = lx + ly + lz
     133     4006100 :                IF (l > maxl) CYCLE
     134      917520 :                co(lx, ly, lz) = 1 + (l - lx)*(l - lx + 1)/2 + lz
     135     4464744 :                coset(lx, ly, lz) = ncoset(l - 1) + co(lx, ly, lz)
     136             :             END DO
     137             :          END DO
     138             :       END DO
     139             : 
     140       26973 :       ALLOCATE (indco(3, ncoset(maxl)))
     141             : 
     142     3679071 :       indco(:, :) = 0
     143             : 
     144       70535 :       DO l = 0, maxl
     145      330629 :          DO lx = 0, l
     146     1239158 :             DO ly = 0, l - lx
     147      917520 :                lz = l - lx - ly
     148     3930174 :                indco(1:3, coset(lx, ly, lz)) = (/lx, ly, lz/)
     149             :             END DO
     150             :          END DO
     151             :       END DO
     152             : 
     153             : !   *** Number of spherical orbitals for each l ***
     154             : 
     155       26973 :       ALLOCATE (nso(-1:maxl))
     156             : 
     157        8991 :       nso(-1) = 0
     158             : 
     159       70535 :       DO l = 0, maxl
     160       70535 :          nso(l) = 2*l + 1
     161             :       END DO
     162             : 
     163             : !   *** Number of spherical orbitals up to l ***
     164             : 
     165       26973 :       ALLOCATE (nsoset(-1:maxl))
     166        8991 :       nsoset(-1) = 0
     167             : 
     168       70535 :       DO l = 0, maxl
     169       70535 :          nsoset(l) = nsoset(l - 1) + nso(l)
     170             :       END DO
     171             : 
     172       26973 :       ALLOCATE (indso(2, nsoset(maxl)))
     173             :       ! indso_inv: inverse to indso
     174       35964 :       ALLOCATE (indso_inv(0:maxl, -maxl:maxl))
     175             : 
     176     1384923 :       indso(:, :) = 0
     177      978832 :       indso_inv(:, :) = 0
     178             : 
     179             :       iso = 0
     180       70535 :       DO l = 0, maxl
     181      529179 :          DO m = -l, l
     182      458644 :             iso = iso + 1
     183     1375932 :             indso(1:2, iso) = (/l, m/)
     184      520188 :             indso_inv(l, m) = iso
     185             :          END DO
     186             :       END DO
     187             : 
     188       62937 :       ALLOCATE (so(0:maxl, -maxl:maxl), soset(0:maxl, -maxl:maxl))
     189             : 
     190      978832 :       soset(:, :) = 0
     191       70535 :       DO l = 0, maxl
     192      529179 :          DO m = -l, l
     193      458644 :             so(l, m) = nso(l) - (l - m)
     194      520188 :             soset(l, m) = nsoset(l - 1) + nso(l) - (l - m)
     195             :          END DO
     196             :       END DO
     197             : 
     198             : !   *** Save initialization status ***
     199             : 
     200        8991 :       current_maxl = maxl
     201             : 
     202        8991 :    END SUBROUTINE create_orbital_pointers
     203             : 
     204             : ! **************************************************************************************************
     205             : !> \brief   Deallocate the orbital pointers.
     206             : !> \date    20.05.2005
     207             : !> \author  MK
     208             : !> \version 1.0
     209             : ! **************************************************************************************************
     210       17923 :    SUBROUTINE deallocate_orbital_pointers()
     211             : 
     212       17923 : !$    IF (omp_get_level() > 0) &
     213           0 : !$       CPABORT("deallocate_orbital_pointers is not thread-safe")
     214             : 
     215       17923 :       IF (current_maxl > -1) THEN
     216             : 
     217        8991 :          DEALLOCATE (co)
     218             : 
     219        8991 :          DEALLOCATE (coset)
     220             : 
     221        8991 :          DEALLOCATE (indco)
     222             : 
     223        8991 :          DEALLOCATE (indso)
     224             : 
     225        8991 :          DEALLOCATE (indso_inv)
     226             : 
     227        8991 :          DEALLOCATE (nco)
     228             : 
     229        8991 :          DEALLOCATE (ncoset)
     230             : 
     231        8991 :          DEALLOCATE (nso)
     232             : 
     233        8991 :          DEALLOCATE (nsoset)
     234             : 
     235        8991 :          DEALLOCATE (so)
     236             : 
     237        8991 :          DEALLOCATE (soset)
     238             : 
     239        8991 :          current_maxl = -1
     240             : 
     241             :       END IF
     242             : 
     243       17923 :    END SUBROUTINE deallocate_orbital_pointers
     244             : 
     245             : ! **************************************************************************************************
     246             : !> \brief   Initialize or update the orbital pointers.
     247             : !> \param maxl ...
     248             : !> \date    07.06.2000
     249             : !> \author  MK
     250             : !> \version 1.0
     251             : ! **************************************************************************************************
     252     3054813 :    SUBROUTINE init_orbital_pointers(maxl)
     253             :       INTEGER, INTENT(IN)                                :: maxl
     254             : 
     255     3054813 : !$    IF (omp_get_level() > 0) &
     256           0 : !$       CPABORT("init_orbital_pointers is not thread-safe")
     257             : 
     258     3054813 :       IF (maxl < 0) THEN
     259             :          CALL cp_abort(__LOCATION__, &
     260             :                        "A negative maximum angular momentum quantum "// &
     261           0 :                        "number is invalid")
     262             :       END IF
     263             : 
     264             : !   *** Check, if the current initialization is sufficient ***
     265             : 
     266     3054813 :       IF (maxl > current_maxl) THEN
     267        8991 :          CALL deallocate_orbital_pointers()
     268        8991 :          CALL create_orbital_pointers(maxl)
     269             :       END IF
     270             : 
     271     3054813 :    END SUBROUTINE init_orbital_pointers
     272             : 
     273             : END MODULE orbital_pointers

Generated by: LCOV version 1.15