LCOV - code coverage report
Current view: top level - src - qs_neighbor_list_types.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:6d276e9) Lines: 92.9 % 312 290
Test Date: 2026-09-10 07:29:18 Functions: 63.6 % 33 21

            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 Define the neighbor list data types and the corresponding functionality
      10              : !> \par History
      11              : !>      - cleaned (23.07.2003,MK)
      12              : !>      - full refactoring, list iterators (20.10.2010, JGH)
      13              : !>      - add get_neighbor_list_set_p, return info for a set of neighborlists
      14              : !>                                                             (07.2014,JGH)
      15              : !> \author Matthias Krack (21.06.2000)
      16              : ! **************************************************************************************************
      17              : MODULE qs_neighbor_list_types
      18              : 
      19              :    USE kinds,                           ONLY: dp
      20              :    USE util,                            ONLY: locate,&
      21              :                                               sort
      22              : #include "./base/base_uses.f90"
      23              : 
      24              :    IMPLICIT NONE
      25              : 
      26              :    PRIVATE
      27              : 
      28              : ! *** Global parameters (in this module) ***
      29              : 
      30              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_neighbor_list_types'
      31              : 
      32              : ! *** Definition of the data types for a linked list of neighbors ***
      33              : 
      34              : ! **************************************************************************************************
      35              :    TYPE neighbor_node_type
      36              :       PRIVATE
      37              :       TYPE(neighbor_node_type), POINTER :: next_neighbor_node => NULL()
      38              :       REAL(dp), DIMENSION(3)            :: r = -1.0_dp
      39              :       INTEGER, DIMENSION(3)             :: cell = -1
      40              :       INTEGER                           :: neighbor = -1
      41              :    END TYPE neighbor_node_type
      42              : 
      43              : ! **************************************************************************************************
      44              :    TYPE neighbor_list_type
      45              :       PRIVATE
      46              :       TYPE(neighbor_list_type), POINTER :: next_neighbor_list => NULL()
      47              :       TYPE(neighbor_node_type), POINTER :: first_neighbor_node => NULL(), &
      48              :                                            last_neighbor_node => NULL()
      49              :       INTEGER                           :: atom = -1, nnode = -1
      50              :    END TYPE neighbor_list_type
      51              : 
      52              : ! **************************************************************************************************
      53              :    TYPE neighbor_list_set_type
      54              :       PRIVATE
      55              :       TYPE(neighbor_list_type), POINTER :: first_neighbor_list => NULL(), &
      56              :                                            last_neighbor_list => NULL()
      57              :       INTEGER                           :: nlist = -1
      58              :       LOGICAL                           :: symmetric = .FALSE.
      59              :    END TYPE neighbor_list_set_type
      60              : 
      61              : ! **************************************************************************************************
      62              :    TYPE neighbor_list_p_type
      63              :       TYPE(neighbor_list_type), POINTER :: neighbor_list => NULL()
      64              :    END TYPE neighbor_list_p_type
      65              : 
      66              : ! **************************************************************************************************
      67              :    TYPE neighbor_list_set_p_type
      68              :       TYPE(neighbor_list_set_type), POINTER                :: neighbor_list_set => NULL()
      69              :       INTEGER                                              :: nl_size = -1
      70              :       INTEGER                                              :: nl_start = -1
      71              :       INTEGER                                              :: nl_end = -1
      72              :       TYPE(neighbor_list_task_type), DIMENSION(:), POINTER :: nlist_task => NULL()
      73              :    END TYPE neighbor_list_set_p_type
      74              : 
      75              : ! **************************************************************************************************
      76              :    TYPE list_search_type
      77              :       PRIVATE
      78              :       INTEGER                               :: nlist = -1
      79              :       INTEGER, DIMENSION(:), POINTER        :: atom_list => NULL()
      80              :       INTEGER, DIMENSION(:), POINTER        :: atom_index => NULL()
      81              :       TYPE(neighbor_list_p_type), &
      82              :          DIMENSION(:), POINTER              :: neighbor_list => NULL()
      83              :    END TYPE list_search_type
      84              : 
      85              : ! **************************************************************************************************
      86              :    TYPE neighbor_list_task_type
      87              :       INTEGER                               :: iatom = -1, jatom = -1, &
      88              :                                                ikind = -1, jkind = -1, nkind = -1, &
      89              :                                                ilist = -1, nlist = -1, inode = -1, nnode = -1
      90              :       REAL(KIND=dp), DIMENSION(3)           :: r = -1.0_dp
      91              :       INTEGER, DIMENSION(3)                 :: cell = -1
      92              :       TYPE(neighbor_list_task_type), &
      93              :          POINTER                            :: next => NULL() ! Pointer for forming a linked list of tasks
      94              :    END TYPE neighbor_list_task_type
      95              : 
      96              :    INTERFACE nl_sub_iterate
      97              :       MODULE PROCEDURE nl_sub_iterate
      98              :       MODULE PROCEDURE nl_sub_iterate_ref
      99              :    END INTERFACE
     100              : 
     101              : ! **************************************************************************************************
     102              : ! Neighbor List Iterator
     103              : ! **************************************************************************************************
     104              :    TYPE neighbor_list_iterator_type
     105              :       PRIVATE
     106              :       INTEGER                               :: ikind = -1, jkind = -1, ilist = -1, inode = -1
     107              :       INTEGER                               :: nkind = -1, nlist = -1, nnode = -1
     108              :       INTEGER                               :: iatom = -1, jatom = -1
     109              :       TYPE(neighbor_list_set_p_type), &
     110              :          DIMENSION(:), POINTER               :: nl => NULL()
     111              :       TYPE(neighbor_list_type), POINTER     :: neighbor_list => NULL()
     112              :       TYPE(neighbor_node_type), POINTER     :: neighbor_node => NULL()
     113              :       TYPE(list_search_type), &
     114              :          DIMENSION(:), POINTER               :: list_search => NULL()
     115              :    END TYPE neighbor_list_iterator_type
     116              : 
     117              :    TYPE neighbor_list_iterator_p_type
     118              :       PRIVATE
     119              :       TYPE(neighbor_list_iterator_type), POINTER :: neighbor_list_iterator => NULL()
     120              :       INTEGER                                    :: last = -1
     121              :    END TYPE neighbor_list_iterator_p_type
     122              : ! **************************************************************************************************
     123              : 
     124              : ! *** Public data types ***
     125              : 
     126              :    PUBLIC :: neighbor_list_p_type, &
     127              :              neighbor_list_set_type, &
     128              :              neighbor_list_set_p_type, &
     129              :              neighbor_list_task_type
     130              : 
     131              : ! *** Public subroutines ***
     132              : 
     133              :    PUBLIC :: add_neighbor_list, &
     134              :              add_neighbor_node, &
     135              :              allocate_neighbor_list_set, &
     136              :              deallocate_neighbor_list_set, &
     137              :              release_neighbor_list_sets, &
     138              :              get_iterator_task, &
     139              :              get_neighbor_list_set, &
     140              :              get_neighbor_list_set_p
     141              : 
     142              : ! *** Iterator functions and types ***
     143              : 
     144              :    PUBLIC :: neighbor_list_iterator_p_type, &
     145              :              neighbor_list_iterator_create, &
     146              :              neighbor_list_iterator_release, &
     147              :              neighbor_list_iterate, &
     148              :              nl_set_sub_iterator, &
     149              :              nl_sub_iterate, &
     150              :              get_iterator_info
     151              : 
     152              : CONTAINS
     153              : 
     154              : ! **************************************************************************************************
     155              : !> \brief   Neighbor list iterator functions
     156              : !> \param iterator_set ...
     157              : !> \param nl ...
     158              : !> \param search ...
     159              : !> \param nthread ...
     160              : !> \date    28.07.2010
     161              : !> \author  jhu
     162              : !> \version 1.0
     163              : ! **************************************************************************************************
     164      4014580 :    SUBROUTINE neighbor_list_iterator_create(iterator_set, nl, search, nthread)
     165              :       TYPE(neighbor_list_iterator_p_type), &
     166              :          DIMENSION(:), POINTER                           :: iterator_set
     167              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     168              :          POINTER                                         :: nl
     169              :       LOGICAL, INTENT(IN), OPTIONAL                      :: search
     170              :       INTEGER, INTENT(IN), OPTIONAL                      :: nthread
     171              : 
     172              :       INTEGER                                            :: iatom, il, ilist, mthread, nlist
     173      4014580 :       TYPE(list_search_type), DIMENSION(:), POINTER      :: list_search
     174              :       TYPE(neighbor_list_iterator_type), POINTER         :: iterator
     175              :       TYPE(neighbor_list_type), POINTER                  :: neighbor_list
     176              : 
     177      4014580 :       mthread = 1
     178        92355 :       IF (PRESENT(nthread)) mthread = nthread
     179              : 
     180     16058320 :       ALLOCATE (iterator_set(0:mthread - 1))
     181              : 
     182      8029160 :       DO il = 0, mthread - 1
     183      4014580 :          ALLOCATE (iterator_set(il)%neighbor_list_iterator)
     184              : 
     185      4014580 :          iterator => iterator_set(il)%neighbor_list_iterator
     186              : 
     187      4014580 :          iterator%nl => nl
     188              : 
     189      4014580 :          iterator%ikind = 0
     190      4014580 :          iterator%jkind = 0
     191      4014580 :          iterator%nkind = NINT(SQRT(REAL(SIZE(nl), dp)))
     192              : 
     193      4014580 :          iterator%ilist = 0
     194      4014580 :          iterator%nlist = 0
     195      4014580 :          iterator%inode = 0
     196      4014580 :          iterator%nnode = 0
     197              : 
     198      4014580 :          iterator%iatom = 0
     199      4014580 :          iterator%jatom = 0
     200              : 
     201      4014580 :          NULLIFY (iterator%neighbor_list)
     202      4014580 :          NULLIFY (iterator%neighbor_node)
     203      8029160 :          NULLIFY (iterator%list_search)
     204              :       END DO
     205              : 
     206      8029160 :       iterator_set(:)%last = 0
     207              : 
     208      4014580 :       IF (PRESENT(search)) THEN
     209        46797 :          IF (search) THEN
     210       256026 :             ALLOCATE (list_search(SIZE(nl)))
     211       162432 :             DO il = 1, SIZE(nl)
     212       162432 :                IF (ASSOCIATED(nl(il)%neighbor_list_set)) THEN
     213       114503 :                   CALL get_neighbor_list_set(neighbor_list_set=nl(il)%neighbor_list_set, nlist=nlist)
     214       114503 :                   list_search(il)%nlist = nlist
     215       314130 :                   ALLOCATE (list_search(il)%atom_list(nlist))
     216       199627 :                   ALLOCATE (list_search(il)%atom_index(nlist))
     217       457171 :                   ALLOCATE (list_search(il)%neighbor_list(nlist))
     218              : 
     219       114503 :                   NULLIFY (neighbor_list)
     220       257544 :                   DO ilist = 1, nlist
     221       143041 :                      IF (.NOT. ASSOCIATED(neighbor_list)) THEN
     222        85124 :                         neighbor_list => first_list(nl(il)%neighbor_list_set)
     223              :                      ELSE
     224        57917 :                         neighbor_list => neighbor_list%next_neighbor_list
     225              :                      END IF
     226       143041 :                      CALL get_neighbor_list(neighbor_list=neighbor_list, atom=iatom)
     227       143041 :                      list_search(il)%atom_list(ilist) = iatom
     228       257544 :                      list_search(il)%neighbor_list(ilist)%neighbor_list => neighbor_list
     229              :                   END DO
     230       229006 :                   CALL sort(list_search(il)%atom_list, nlist, list_search(il)%atom_index)
     231              : 
     232              :                ELSE
     233         1132 :                   list_search(il)%nlist = -1
     234         1132 :                   NULLIFY (list_search(il)%atom_list, list_search(il)%atom_index, list_search(il)%neighbor_list)
     235              :                END IF
     236              :             END DO
     237        93594 :             DO il = 0, mthread - 1
     238        46797 :                iterator => iterator_set(il)%neighbor_list_iterator
     239        93594 :                iterator%list_search => list_search
     240              :             END DO
     241              :          END IF
     242              :       END IF
     243              : 
     244      4014580 :    END SUBROUTINE neighbor_list_iterator_create
     245              : 
     246              : ! **************************************************************************************************
     247              : !> \brief ...
     248              : !> \param iterator_set ...
     249              : ! **************************************************************************************************
     250      4014580 :    SUBROUTINE neighbor_list_iterator_release(iterator_set)
     251              :       TYPE(neighbor_list_iterator_p_type), &
     252              :          DIMENSION(:), POINTER                           :: iterator_set
     253              : 
     254              :       INTEGER                                            :: il, mthread
     255              :       TYPE(neighbor_list_iterator_type), POINTER         :: iterator
     256              : 
     257              : !all threads have the same search list
     258              : 
     259      4014580 :       iterator => iterator_set(0)%neighbor_list_iterator
     260      4014580 :       IF (ASSOCIATED(iterator%list_search)) THEN
     261       162432 :          DO il = 1, SIZE(iterator%list_search)
     262       162432 :             IF (iterator%list_search(il)%nlist >= 0) THEN
     263       114503 :                DEALLOCATE (iterator%list_search(il)%atom_list)
     264       114503 :                DEALLOCATE (iterator%list_search(il)%atom_index)
     265       114503 :                DEALLOCATE (iterator%list_search(il)%neighbor_list)
     266              :             END IF
     267              :          END DO
     268        46797 :          DEALLOCATE (iterator%list_search)
     269              :       END IF
     270              : 
     271      4014580 :       mthread = SIZE(iterator_set)
     272      8029160 :       DO il = 0, mthread - 1
     273      8029160 :          DEALLOCATE (iterator_set(il)%neighbor_list_iterator)
     274              :       END DO
     275      4014580 :       DEALLOCATE (iterator_set)
     276              : 
     277      4014580 :    END SUBROUTINE neighbor_list_iterator_release
     278              : 
     279              : ! **************************************************************************************************
     280              : !> \brief ...
     281              : !> \param iterator_set ...
     282              : !> \param ikind ...
     283              : !> \param jkind ...
     284              : !> \param iatom ...
     285              : !> \param mepos ...
     286              : ! **************************************************************************************************
     287      3888878 :    SUBROUTINE nl_set_sub_iterator(iterator_set, ikind, jkind, iatom, mepos)
     288              :       TYPE(neighbor_list_iterator_p_type), &
     289              :          DIMENSION(:), POINTER                           :: iterator_set
     290              :       INTEGER, INTENT(IN)                                :: ikind, jkind, iatom
     291              :       INTEGER, INTENT(IN), OPTIONAL                      :: mepos
     292              : 
     293              :       INTEGER                                            :: i, ij, ilist, me, nlist, nnode
     294              :       TYPE(list_search_type), POINTER                    :: list_search
     295              :       TYPE(neighbor_list_iterator_type), POINTER         :: iterator
     296              :       TYPE(neighbor_list_type), POINTER                  :: neighbor_list
     297              : 
     298      3888878 :       IF (PRESENT(mepos)) THEN
     299      3316218 :          me = mepos
     300              :       ELSE
     301              :          me = 0
     302              :       END IF
     303              : 
     304              :       ! Set up my thread-local iterator for the list of iatom / jkind nodes
     305              : 
     306      3888878 :       iterator => iterator_set(me)%neighbor_list_iterator
     307      3888878 :       ij = ikind + iterator%nkind*(jkind - 1)
     308      3888878 :       IF (ASSOCIATED(iterator%list_search)) THEN
     309      3888878 :          list_search => iterator%list_search(ij)
     310      3888878 :          nlist = list_search%nlist
     311      3888878 :          ilist = 0
     312      3888878 :          NULLIFY (neighbor_list)
     313      3888878 :          IF (nlist > 0) THEN
     314      3878246 :             i = locate(list_search%atom_list, iatom)
     315      3878246 :             i = list_search%atom_index(i)
     316      3878246 :             IF (i > 0) neighbor_list => list_search%neighbor_list(i)%neighbor_list
     317              :             ilist = i
     318              :          END IF
     319      3888878 :          IF (ASSOCIATED(neighbor_list)) THEN
     320      3878246 :             CALL get_neighbor_list(neighbor_list=neighbor_list, nnode=nnode)
     321              :          ELSE
     322        10632 :             nnode = 0
     323              :          END IF
     324              :       ELSE
     325            0 :          CPABORT("iterator%list_search is not available")
     326              :       END IF
     327              : 
     328      3888878 :       iterator%ikind = ikind
     329      3888878 :       iterator%jkind = jkind
     330              : 
     331      3888878 :       iterator%ilist = ilist
     332      3888878 :       iterator%nlist = nlist
     333      3888878 :       iterator%inode = 0
     334      3888878 :       iterator%nnode = nnode
     335              : 
     336      3888878 :       iterator%iatom = iatom
     337      3888878 :       iterator%jatom = 0
     338              : 
     339      3888878 :       iterator%neighbor_list => neighbor_list
     340      3888878 :       NULLIFY (iterator%neighbor_node)
     341              : 
     342      3888878 :    END SUBROUTINE nl_set_sub_iterator
     343              : 
     344              : ! **************************************************************************************************
     345              : !> \brief ...
     346              : !> \param iterator_set ...
     347              : !> \param mepos ...
     348              : !> \return ...
     349              : ! **************************************************************************************************
     350   2454332350 :    FUNCTION neighbor_list_iterate(iterator_set, mepos) RESULT(istat)
     351              :       TYPE(neighbor_list_iterator_p_type), &
     352              :          DIMENSION(:), POINTER                           :: iterator_set
     353              :       INTEGER, INTENT(IN), OPTIONAL                      :: mepos
     354              :       INTEGER                                            :: istat
     355              : 
     356              :       INTEGER                                            :: iab, last, me
     357              :       TYPE(neighbor_list_iterator_type), POINTER         :: iterator
     358              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     359   2454332350 :          POINTER                                         :: nl
     360              : 
     361            0 :       IF (SIZE(iterator_set) /= 1 .AND. .NOT. PRESENT(mepos)) THEN
     362            0 :          CPABORT("Parallel iterator calls must include 'mepos'")
     363              :       END IF
     364              : 
     365   2454332350 :       IF (PRESENT(mepos)) THEN
     366     11591924 :          me = mepos
     367              :       ELSE
     368              :          me = 0
     369              :       END IF
     370              : 
     371   2454332350 :       istat = 0
     372              : 
     373   4908664700 : !$OMP CRITICAL(neighbour_list_iterate_critical)
     374   2454332350 :       last = iterator_set(0)%last
     375   2454332350 :       IF (last /= me) THEN
     376            0 :          iterator_set(me)%neighbor_list_iterator = iterator_set(last)%neighbor_list_iterator
     377              :       END IF
     378   2454332350 :       iterator => iterator_set(me)%neighbor_list_iterator
     379   2454332350 :       nl => iterator%nl
     380              : 
     381   2454332350 :       IF (iterator%inode < iterator%nnode) THEN
     382              :          ! we can be sure that there is another node in this list
     383   2433185605 :          iterator%inode = iterator%inode + 1
     384   2433185605 :          iterator%neighbor_node => iterator%neighbor_node%next_neighbor_node
     385              :       ELSE
     386     21146745 :          iab = MAX(iterator%ikind + iterator%nkind*(iterator%jkind - 1), 0)
     387     12188436 :          kindloop: DO ! look for the next list with nnode /= 0
     388              :             listloop: DO
     389     34681217 :                IF (iterator%ilist >= iterator%nlist) EXIT listloop
     390     18524998 :                iterator%ilist = iterator%ilist + 1
     391     18524998 :                IF (ASSOCIATED(iterator%neighbor_list)) THEN
     392      9658468 :                   iterator%neighbor_list => iterator%neighbor_list%next_neighbor_list
     393              :                ELSE
     394      8866530 :                   iterator%neighbor_list => first_list(nl(iab)%neighbor_list_set)
     395              :                END IF
     396              :                CALL get_neighbor_list(neighbor_list=iterator%neighbor_list, atom=iterator%iatom, &
     397     18524998 :                                       nnode=iterator%nnode)
     398     34681217 :                IF (iterator%nnode > 0) EXIT kindloop
     399              :             END DO listloop
     400     33335181 :             IF (iab >= iterator%nkind**2) THEN
     401              :                istat = 1
     402              :                EXIT kindloop
     403              :             ELSE
     404     12188436 :                iab = iab + 1
     405     12188436 :                iterator%jkind = (iab - 1)/iterator%nkind + 1
     406     12188436 :                iterator%ikind = iab - iterator%nkind*(iterator%jkind - 1)
     407     12188436 :                iterator%ilist = 0
     408     12188436 :                IF (.NOT. ASSOCIATED(nl(iab)%neighbor_list_set)) THEN
     409              :                   iterator%ilist = 0
     410       149164 :                   iterator%nlist = 0
     411              :                ELSE
     412              :                   CALL get_neighbor_list_set(neighbor_list_set= &
     413     12039272 :                                              nl(iab)%neighbor_list_set, nlist=iterator%nlist)
     414     12039272 :                   iterator%ilist = 0
     415              :                END IF
     416     12188436 :                NULLIFY (iterator%neighbor_list)
     417              :             END IF
     418              :          END DO kindloop
     419     21146745 :          IF (istat == 0) THEN
     420     17178962 :             iterator%inode = 1
     421     17178962 :             iterator%neighbor_node => first_node(iterator%neighbor_list)
     422              :          END IF
     423              :       END IF
     424              :       IF (istat == 0) THEN
     425   2450364567 :          CALL get_neighbor_node(neighbor_node=iterator%neighbor_node, neighbor=iterator%jatom)
     426              :       END IF
     427              : 
     428              :       ! mark the last iterator updated
     429   4908664700 :       iterator_set(:)%last = me
     430              : !$OMP END CRITICAL(neighbour_list_iterate_critical)
     431              : 
     432   2454332350 :    END FUNCTION neighbor_list_iterate
     433              : 
     434              : ! **************************************************************************************************
     435              : !> \brief ...
     436              : !> \param iterator_set ...
     437              : !> \param mepos ...
     438              : !> \return ...
     439              : ! **************************************************************************************************
     440    238602049 :    FUNCTION nl_sub_iterate(iterator_set, mepos) RESULT(istat)
     441              :       TYPE(neighbor_list_iterator_p_type), &
     442              :          DIMENSION(:), POINTER                           :: iterator_set
     443              :       INTEGER, INTENT(IN), OPTIONAL                      :: mepos
     444              :       INTEGER                                            :: istat
     445              : 
     446              :       INTEGER                                            :: me
     447              :       TYPE(neighbor_list_iterator_type), POINTER         :: iterator
     448              : 
     449              :       ! Each thread's sub-iterator are independent, no need to synchronise with other threads
     450              : 
     451    238602049 :       IF (PRESENT(mepos)) THEN
     452    232453069 :          me = mepos
     453              :       ELSE
     454              :          me = 0
     455              :       END IF
     456              : 
     457    238602049 :       istat = 0
     458              : 
     459    238602049 :       iterator => iterator_set(me)%neighbor_list_iterator
     460              : 
     461    238602049 :       IF (ASSOCIATED(iterator%neighbor_list)) THEN
     462    238591417 :          IF (iterator%inode >= iterator%nnode) THEN
     463              :             ! end of loop
     464              :             istat = 1
     465    234931768 :          ELSE IF (iterator%inode == 0) THEN
     466      3579624 :             iterator%inode = 1
     467      3579624 :             iterator%neighbor_node => first_node(iterator%neighbor_list)
     468    231352144 :          ELSE IF (iterator%inode > 0) THEN
     469              :             ! we can be sure that there is another node in this list
     470    231352144 :             iterator%inode = iterator%inode + 1
     471    231352144 :             iterator%neighbor_node => iterator%neighbor_node%next_neighbor_node
     472              :          ELSE
     473            0 :             CPABORT("wrong")
     474              :          END IF
     475              :       ELSE
     476              :          ! no list available
     477              :          istat = 1
     478              :       END IF
     479              :       IF (istat == 0) THEN
     480    234931768 :          CALL get_neighbor_node(neighbor_node=iterator%neighbor_node, neighbor=iterator%jatom)
     481              :       END IF
     482              : 
     483    238602049 :    END FUNCTION nl_sub_iterate
     484              : 
     485              : ! **************************************************************************************************
     486              : !> \brief wrap nl_sub_iterate s.t. external loop over kinds and calls to nl_set_sub_iterator
     487              : !> are no longer needed. This fixes first atom of iter_sub to second atom of iter_ref.
     488              : !> \param iter_sub ...
     489              : !> \param iter_ref ...
     490              : !> \param mepos ...
     491              : !> \return ...
     492              : ! **************************************************************************************************
     493      5922917 :    RECURSIVE FUNCTION nl_sub_iterate_ref(iter_sub, iter_ref, mepos) RESULT(iter_stat)
     494              :       TYPE(neighbor_list_iterator_p_type), &
     495              :          DIMENSION(:), POINTER                           :: iter_sub, iter_ref
     496              :       INTEGER, INTENT(IN), OPTIONAL                      :: mepos
     497              :       INTEGER                                            :: iter_stat
     498              : 
     499              :       INTEGER                                            :: atom_ref, kind_ref, kind_sub, me, nkind
     500              :       TYPE(neighbor_list_iterator_type), POINTER         :: iterator
     501              : 
     502      5922917 :       IF (PRESENT(mepos)) THEN
     503            0 :          me = mepos
     504              :       ELSE
     505              :          me = 0
     506              :       END IF
     507              : 
     508      5922917 :       iterator => iter_sub(me)%neighbor_list_iterator
     509      5922917 :       kind_sub = iterator%jkind
     510              : 
     511      5922917 :       CALL get_iterator_info(iter_ref, jatom=atom_ref, jkind=kind_ref)
     512              : 
     513      5922917 :       IF (iterator%inode == 0) THEN
     514       218597 :          CALL nl_set_sub_iterator(iter_sub, kind_ref, MAX(kind_sub, 1), atom_ref)
     515              :       END IF
     516      5922917 :       iter_stat = nl_sub_iterate(iter_sub)
     517      5922917 :       IF (iter_stat == 0) RETURN
     518              : 
     519       218597 :       nkind = iterator%nkind
     520              : 
     521       218597 :       IF (kind_sub == nkind) THEN
     522       139549 :          CALL nl_set_sub_iterator(iter_sub, kind_ref, 1, atom_ref)
     523       139549 :          RETURN
     524              :       ELSE
     525        79048 :          kind_sub = kind_sub + 1
     526        79048 :          CALL nl_set_sub_iterator(iter_sub, kind_ref, kind_sub, atom_ref)
     527        79048 :          iter_stat = nl_sub_iterate_ref(iter_sub, iter_ref)
     528              :       END IF
     529              : 
     530        79048 :    END FUNCTION nl_sub_iterate_ref
     531              : 
     532              : ! **************************************************************************************************
     533              : !> \brief ...
     534              : !> \param iterator_set ...
     535              : !> \param mepos ...
     536              : !> \param ikind ...
     537              : !> \param jkind ...
     538              : !> \param nkind ...
     539              : !> \param ilist ...
     540              : !> \param nlist ...
     541              : !> \param inode ...
     542              : !> \param nnode ...
     543              : !> \param iatom ...
     544              : !> \param jatom ...
     545              : !> \param r ...
     546              : !> \param cell ...
     547              : ! **************************************************************************************************
     548   2762733806 :    SUBROUTINE get_iterator_info(iterator_set, mepos, &
     549              :                                 ikind, jkind, nkind, ilist, nlist, inode, nnode, iatom, jatom, r, cell)
     550              :       TYPE(neighbor_list_iterator_p_type), &
     551              :          DIMENSION(:), POINTER                           :: iterator_set
     552              :       INTEGER, INTENT(IN), OPTIONAL                      :: mepos
     553              :       INTEGER, OPTIONAL                                  :: ikind, jkind, nkind, ilist, nlist, &
     554              :                                                             inode, nnode, iatom, jatom
     555              :       REAL(dp), DIMENSION(3), OPTIONAL                   :: r
     556              :       INTEGER, DIMENSION(3), OPTIONAL                    :: cell
     557              : 
     558              :       INTEGER                                            :: me
     559              :       TYPE(neighbor_list_iterator_type), POINTER         :: iterator
     560              : 
     561   2762733806 :       CPASSERT(ASSOCIATED(iterator_set))
     562   2762733806 :       IF ((SIZE(iterator_set) /= 1) .AND. (.NOT. PRESENT(mepos))) THEN
     563            0 :          CPABORT("Parallel iterator calls must include 'mepos'")
     564              :       END IF
     565   2762733806 :       IF (PRESENT(mepos)) THEN
     566    240658423 :          me = mepos
     567              :       ELSE
     568              :          me = 0
     569              :       END IF
     570   2762733806 :       iterator => iterator_set(me)%neighbor_list_iterator
     571              : 
     572   2762733806 :       IF (PRESENT(ikind)) ikind = iterator%ikind
     573   2762733806 :       IF (PRESENT(jkind)) jkind = iterator%jkind
     574   2762733806 :       IF (PRESENT(nkind)) nkind = iterator%nkind
     575   2762733806 :       IF (PRESENT(ilist)) ilist = iterator%ilist
     576   2762733806 :       IF (PRESENT(nlist)) nlist = iterator%nlist
     577   2762733806 :       IF (PRESENT(inode)) inode = iterator%inode
     578   2762733806 :       IF (PRESENT(nnode)) nnode = iterator%nnode
     579   2762733806 :       IF (PRESENT(iatom)) iatom = iterator%iatom
     580   2762733806 :       IF (PRESENT(jatom)) jatom = iterator%jatom
     581   2762733806 :       IF (PRESENT(r)) THEN
     582    511506739 :          CALL get_neighbor_node(neighbor_node=iterator%neighbor_node, r=r)
     583              :       END IF
     584   2762733806 :       IF (PRESENT(cell)) THEN
     585    217714063 :          CALL get_neighbor_node(neighbor_node=iterator%neighbor_node, cell=cell)
     586              :       END IF
     587              : 
     588   2762733806 :    END SUBROUTINE get_iterator_info
     589              : 
     590              : ! **************************************************************************************************
     591              : !> \brief Captures the current state of the iterator in a neighbor_list_task_type
     592              : !> \param iterator_set the iterator / array of iterators (for multiple threads)
     593              : !> \param task the task structure which is returned
     594              : !> \param mepos OpenMP thread index
     595              : ! **************************************************************************************************
     596    476630312 :    SUBROUTINE get_iterator_task(iterator_set, task, mepos)
     597              :       TYPE(neighbor_list_iterator_p_type), &
     598              :          DIMENSION(:), POINTER                           :: iterator_set
     599              :       TYPE(neighbor_list_task_type), INTENT(OUT)         :: task
     600              :       INTEGER, INTENT(IN), OPTIONAL                      :: mepos
     601              : 
     602     59578789 :       IF (PRESENT(mepos)) THEN
     603              :          CALL get_iterator_info(iterator_set, mepos=mepos, ikind=task%ikind, jkind=task%jkind, &
     604              :                                 nkind=task%nkind, &
     605              :                                 ilist=task%ilist, nlist=task%nlist, &
     606              :                                 inode=task%inode, nnode=task%nnode, &
     607              :                                 iatom=task%iatom, jatom=task%jatom, &
     608            0 :                                 r=task%r, cell=task%cell)
     609              :       ELSE
     610              :          CALL get_iterator_info(iterator_set, ikind=task%ikind, jkind=task%jkind, &
     611              :                                 nkind=task%nkind, &
     612              :                                 ilist=task%ilist, nlist=task%nlist, &
     613              :                                 inode=task%inode, nnode=task%nnode, &
     614              :                                 iatom=task%iatom, jatom=task%jatom, &
     615     59578789 :                                 r=task%r, cell=task%cell)
     616              :       END IF
     617              : 
     618     59578789 :       NULLIFY (task%next)
     619              : 
     620     59578789 :    END SUBROUTINE get_iterator_task
     621              : 
     622              : ! **************************************************************************************************
     623              : !> \brief   Add a new neighbor list to a neighbor list set.
     624              : !> \param neighbor_list_set ...
     625              : !> \param atom ...
     626              : !> \param neighbor_list ...
     627              : !> \date    13.09.2000
     628              : !> \author  MK
     629              : !> \version 1.0
     630              : ! **************************************************************************************************
     631       844001 :    SUBROUTINE add_neighbor_list(neighbor_list_set, atom, neighbor_list)
     632              : 
     633              :       TYPE(neighbor_list_set_type), POINTER              :: neighbor_list_set
     634              :       INTEGER, INTENT(IN)                                :: atom
     635              :       TYPE(neighbor_list_type), POINTER                  :: neighbor_list
     636              : 
     637              :       TYPE(neighbor_list_type), POINTER                  :: new_neighbor_list
     638              : 
     639       844001 :       IF (ASSOCIATED(neighbor_list_set)) THEN
     640              : 
     641       844001 :          IF (ASSOCIATED(neighbor_list_set%last_neighbor_list)) THEN
     642              : 
     643              :             new_neighbor_list => &
     644       417086 :                neighbor_list_set%last_neighbor_list%next_neighbor_list
     645              : 
     646       417086 :             IF (.NOT. ASSOCIATED(new_neighbor_list)) THEN
     647              : 
     648              : !         *** Allocate a new neighbor list ***
     649              : 
     650       417086 :                ALLOCATE (new_neighbor_list)
     651              : 
     652              :                NULLIFY (new_neighbor_list%next_neighbor_list)
     653              :                NULLIFY (new_neighbor_list%first_neighbor_node)
     654              : 
     655              : !         *** Link the new neighbor list to the neighbor list set ***
     656              : 
     657       417086 :                neighbor_list_set%last_neighbor_list%next_neighbor_list => new_neighbor_list
     658              : 
     659              :             END IF
     660              : 
     661              :          ELSE
     662              : 
     663       426915 :             new_neighbor_list => neighbor_list_set%first_neighbor_list
     664              : 
     665       426915 :             IF (.NOT. ASSOCIATED(new_neighbor_list)) THEN
     666              : 
     667              : !         *** Allocate a new first neighbor list ***
     668              : 
     669       426915 :                ALLOCATE (new_neighbor_list)
     670              : 
     671              :                NULLIFY (new_neighbor_list%next_neighbor_list)
     672              :                NULLIFY (new_neighbor_list%first_neighbor_node)
     673              : 
     674              : !         *** Link the new first neighbor list to the neighbor list set ***
     675              : 
     676       426915 :                neighbor_list_set%first_neighbor_list => new_neighbor_list
     677              : 
     678              :             END IF
     679              : 
     680              :          END IF
     681              : 
     682              : !     *** Store the data set of the new neighbor list ***
     683              : 
     684       844001 :          NULLIFY (new_neighbor_list%last_neighbor_node)
     685       844001 :          new_neighbor_list%atom = atom
     686       844001 :          new_neighbor_list%nnode = 0
     687              : 
     688              : !     *** Update the pointer to the last neighbor ***
     689              : !     *** list of the neighbor list set           ***
     690              : 
     691       844001 :          neighbor_list_set%last_neighbor_list => new_neighbor_list
     692              : 
     693              : !     *** Increment the neighbor list counter ***
     694              : 
     695       844001 :          neighbor_list_set%nlist = neighbor_list_set%nlist + 1
     696              : 
     697              : !     *** Return a pointer to the new neighbor list ***
     698              : 
     699       844001 :          neighbor_list => new_neighbor_list
     700              : 
     701              :       ELSE
     702              : 
     703            0 :          CPABORT("The requested neighbor list set is not associated")
     704              : 
     705              :       END IF
     706              : 
     707       844001 :    END SUBROUTINE add_neighbor_list
     708              : 
     709              : ! **************************************************************************************************
     710              : !> \brief   Add a new neighbor list node to a neighbor list.
     711              : !> \param neighbor_list ...
     712              : !> \param neighbor ...
     713              : !> \param cell ...
     714              : !> \param r ...
     715              : !> \param exclusion_list ...
     716              : !> \param nkind ...
     717              : !> \date    23.06.2000
     718              : !> \author  MK
     719              : !> \version 1.0
     720              : ! **************************************************************************************************
     721     58525890 :    SUBROUTINE add_neighbor_node(neighbor_list, neighbor, cell, r, exclusion_list, nkind)
     722              : 
     723              :       TYPE(neighbor_list_type), POINTER                  :: neighbor_list
     724              :       INTEGER, INTENT(IN)                                :: neighbor
     725              :       INTEGER, DIMENSION(3), INTENT(IN)                  :: cell
     726              :       REAL(dp), DIMENSION(3), INTENT(IN)                 :: r
     727              :       INTEGER, DIMENSION(:), OPTIONAL, POINTER           :: exclusion_list
     728              :       INTEGER, INTENT(IN), OPTIONAL                      :: nkind
     729              : 
     730              :       INTEGER                                            :: iatom, my_nkind
     731              :       TYPE(neighbor_node_type), POINTER                  :: new_neighbor_node
     732              : 
     733     58525890 :       IF (ASSOCIATED(neighbor_list)) THEN
     734              : 
     735              : !     *** Check for exclusions ***
     736              : 
     737     58525890 :          IF (PRESENT(exclusion_list)) THEN
     738            0 :             IF (ASSOCIATED(exclusion_list)) THEN
     739            0 :                DO iatom = 1, SIZE(exclusion_list)
     740            0 :                   IF (exclusion_list(iatom) == 0) EXIT
     741            0 :                   IF (exclusion_list(iatom) == neighbor) RETURN
     742              :                END DO
     743              :             END IF
     744              :          END IF
     745              : 
     746     58525890 :          my_nkind = 0
     747     58525890 :          IF (PRESENT(nkind)) my_nkind = nkind
     748              : 
     749     58525890 :          IF (ASSOCIATED(neighbor_list%last_neighbor_node)) THEN
     750              : 
     751     57757660 :             new_neighbor_node => neighbor_list%last_neighbor_node%next_neighbor_node
     752              : 
     753     57757660 :             IF (.NOT. ASSOCIATED(new_neighbor_node)) THEN
     754              : 
     755              : !         *** Allocate a new neighbor node ***
     756              : 
     757    404303620 :                ALLOCATE (new_neighbor_node)
     758              : 
     759              :                NULLIFY (new_neighbor_node%next_neighbor_node)
     760              : 
     761              : !         *** Link the new neighbor node to the neighbor list ***
     762              : 
     763     57757660 :                neighbor_list%last_neighbor_node%next_neighbor_node => new_neighbor_node
     764              : 
     765              :             END IF
     766              : 
     767              :          ELSE
     768              : 
     769       768230 :             new_neighbor_node => neighbor_list%first_neighbor_node
     770              : 
     771       768230 :             IF (.NOT. ASSOCIATED(new_neighbor_node)) THEN
     772              : 
     773              : !         *** Allocate a new first neighbor node ***
     774              : 
     775      5377610 :                ALLOCATE (new_neighbor_node)
     776              : 
     777              :                NULLIFY (new_neighbor_node%next_neighbor_node)
     778              : 
     779              : !         *** Link the new first neighbor node to the neighbor list ***
     780              : 
     781       768230 :                neighbor_list%first_neighbor_node => new_neighbor_node
     782              : 
     783              :             END IF
     784              : 
     785              :          END IF
     786              : 
     787              : !     *** Store the data set of the new neighbor ***
     788              : 
     789     58525890 :          new_neighbor_node%neighbor = neighbor
     790    234103560 :          new_neighbor_node%cell(:) = cell(:)
     791    234103560 :          new_neighbor_node%r(:) = r(:)
     792              : 
     793              : !     *** Update the pointer to the last neighbor node of the neighbor list ***
     794              : 
     795     58525890 :          neighbor_list%last_neighbor_node => new_neighbor_node
     796              : 
     797              : !     *** Increment the neighbor node counter ***
     798              : 
     799     58525890 :          neighbor_list%nnode = neighbor_list%nnode + 1
     800              : 
     801              :       ELSE
     802              : 
     803            0 :          CPABORT("The requested neighbor list is not associated")
     804              : 
     805              :       END IF
     806              : 
     807              :    END SUBROUTINE add_neighbor_node
     808              : 
     809              : ! **************************************************************************************************
     810              : !> \brief   Allocate and initialize a set of neighbor lists.
     811              : !> \param neighbor_list_set ...
     812              : !> \param symmetric ...
     813              : !> \date    23.06.2000
     814              : !> \author MK
     815              : !> \version 1.0
     816              : ! **************************************************************************************************
     817       605635 :    SUBROUTINE allocate_neighbor_list_set(neighbor_list_set, symmetric)
     818              : 
     819              :       TYPE(neighbor_list_set_type), POINTER              :: neighbor_list_set
     820              :       LOGICAL, INTENT(IN)                                :: symmetric
     821              : 
     822              : !   *** Deallocate the old neighbor list set ***
     823              : 
     824       605635 :       IF (ASSOCIATED(neighbor_list_set)) THEN
     825            0 :          CALL deallocate_neighbor_list_set(neighbor_list_set)
     826              :       END IF
     827              : 
     828              : !   *** Allocate a set of neighbor lists ***
     829              : 
     830       605635 :       ALLOCATE (neighbor_list_set)
     831              : 
     832              :       NULLIFY (neighbor_list_set%first_neighbor_list)
     833              : 
     834              : !   *** Initialize the pointers to the first neighbor list ***
     835              : 
     836       605635 :       CALL init_neighbor_list_set(neighbor_list_set, symmetric)
     837              : 
     838       605635 :    END SUBROUTINE allocate_neighbor_list_set
     839              : 
     840              : ! **************************************************************************************************
     841              : !> \brief   Deallocate a neighbor list.
     842              : !> \param neighbor_list ...
     843              : !> \date    20.09.2002
     844              : !> \author  MK
     845              : !> \version 1.0
     846              : ! **************************************************************************************************
     847       844001 :    SUBROUTINE deallocate_neighbor_list(neighbor_list)
     848              : 
     849              :       TYPE(neighbor_list_type), POINTER                  :: neighbor_list
     850              : 
     851              :       TYPE(neighbor_node_type), POINTER                  :: neighbor_node, next_neighbor_node
     852              : 
     853       844001 :       IF (ASSOCIATED(neighbor_list)) THEN
     854              : 
     855       844001 :          neighbor_node => neighbor_list%first_neighbor_node
     856              : 
     857     59369891 :          DO WHILE (ASSOCIATED(neighbor_node))
     858     58525890 :             next_neighbor_node => neighbor_node%next_neighbor_node
     859     58525890 :             DEALLOCATE (neighbor_node)
     860     58525890 :             neighbor_node => next_neighbor_node
     861              :          END DO
     862              : 
     863       844001 :          DEALLOCATE (neighbor_list)
     864              : 
     865              :       END IF
     866              : 
     867       844001 :    END SUBROUTINE deallocate_neighbor_list
     868              : 
     869              : ! **************************************************************************************************
     870              : !> \brief   Deallocate a neighbor list set.
     871              : !> \param neighbor_list_set ...
     872              : !> \date    03.11.2000
     873              : !> \author  MK
     874              : !> \version 1.0
     875              : ! **************************************************************************************************
     876       665529 :    SUBROUTINE deallocate_neighbor_list_set(neighbor_list_set)
     877              :       TYPE(neighbor_list_set_type), POINTER              :: neighbor_list_set
     878              : 
     879              :       TYPE(neighbor_list_type), POINTER                  :: neighbor_list, next_neighbor_list
     880              : 
     881       665529 :       IF (ASSOCIATED(neighbor_list_set)) THEN
     882              : 
     883       605635 :          neighbor_list => neighbor_list_set%first_neighbor_list
     884              : 
     885      1449636 :          DO WHILE (ASSOCIATED(neighbor_list))
     886       844001 :             next_neighbor_list => neighbor_list%next_neighbor_list
     887       844001 :             CALL deallocate_neighbor_list(neighbor_list)
     888       844001 :             neighbor_list => next_neighbor_list
     889              :          END DO
     890              : 
     891       605635 :          DEALLOCATE (neighbor_list_set)
     892              : 
     893              :       END IF
     894              : 
     895       665529 :    END SUBROUTINE deallocate_neighbor_list_set
     896              : 
     897              : ! **************************************************************************************************
     898              : !> \brief   Return a pointer to the first neighbor list of a neighbor list set.
     899              : !> \param neighbor_list_set ...
     900              : !> \return ...
     901              : !> \date    13.09.2000
     902              : !> \author  MK
     903              : !> \version 1.0
     904              : ! **************************************************************************************************
     905      8951654 :    FUNCTION first_list(neighbor_list_set) RESULT(first_neighbor_list)
     906              : 
     907              :       TYPE(neighbor_list_set_type), POINTER              :: neighbor_list_set
     908              :       TYPE(neighbor_list_type), POINTER                  :: first_neighbor_list
     909              : 
     910      8951654 :       first_neighbor_list => neighbor_list_set%first_neighbor_list
     911              : 
     912      8951654 :    END FUNCTION first_list
     913              : 
     914              : ! **************************************************************************************************
     915              : !> \brief   Return a pointer to the first neighbor node of a neighbor list.
     916              : !> \param neighbor_list ...
     917              : !> \return ...
     918              : !> \date    23.06.2000,
     919              : !> \author  MK
     920              : !> \version 1.0
     921              : ! **************************************************************************************************
     922     20758586 :    FUNCTION first_node(neighbor_list) RESULT(first_neighbor_node)
     923              : 
     924              :       TYPE(neighbor_list_type), POINTER                  :: neighbor_list
     925              :       TYPE(neighbor_node_type), POINTER                  :: first_neighbor_node
     926              : 
     927     20758586 :       first_neighbor_node => neighbor_list%first_neighbor_node
     928              : 
     929     20758586 :    END FUNCTION first_node
     930              : 
     931              : ! **************************************************************************************************
     932              : !> \brief   Return the requested data of a neighbor list.
     933              : !> \param neighbor_list ...
     934              : !> \param atom ...
     935              : !> \param nnode ...
     936              : !> \date    13.09.2000
     937              : !> \author  MK
     938              : !> \version 1.0
     939              : ! **************************************************************************************************
     940     22546285 :    SUBROUTINE get_neighbor_list(neighbor_list, atom, nnode)
     941              : 
     942              :       TYPE(neighbor_list_type), POINTER                  :: neighbor_list
     943              :       INTEGER, INTENT(OUT), OPTIONAL                     :: atom, nnode
     944              : 
     945     22546285 :       IF (ASSOCIATED(neighbor_list)) THEN
     946              : 
     947     22546285 :          IF (PRESENT(atom)) atom = neighbor_list%atom
     948     22546285 :          IF (PRESENT(nnode)) nnode = neighbor_list%nnode
     949              : 
     950              :       ELSE
     951              : 
     952            0 :          CPABORT("The requested neighbor list is not associated")
     953              : 
     954              :       END IF
     955              : 
     956     22546285 :    END SUBROUTINE get_neighbor_list
     957              : 
     958              : ! **************************************************************************************************
     959              : !> \brief   Return the components of a neighbor list set.
     960              : !> \param neighbor_list_set ...
     961              : !> \param nlist ...
     962              : !> \param symmetric ...
     963              : !> \date    10.11.2000
     964              : !> \author  MK
     965              : !> \version 1.0
     966              : ! **************************************************************************************************
     967     12153775 :    SUBROUTINE get_neighbor_list_set(neighbor_list_set, nlist, symmetric)
     968              : 
     969              :       TYPE(neighbor_list_set_type), POINTER              :: neighbor_list_set
     970              :       INTEGER, INTENT(OUT), OPTIONAL                     :: nlist
     971              :       LOGICAL, INTENT(OUT), OPTIONAL                     :: symmetric
     972              : 
     973     12153775 :       IF (ASSOCIATED(neighbor_list_set)) THEN
     974              : 
     975     12153775 :          IF (PRESENT(nlist)) nlist = neighbor_list_set%nlist
     976     12153775 :          IF (PRESENT(symmetric)) symmetric = neighbor_list_set%symmetric
     977              : 
     978              :       ELSE
     979              : 
     980            0 :          CPABORT("The requested neighbor list set is not associated")
     981              : 
     982              :       END IF
     983              : 
     984     12153775 :    END SUBROUTINE get_neighbor_list_set
     985              : 
     986              : ! **************************************************************************************************
     987              : !> \brief   Return the components of the first neighbor list set.
     988              : !> \param neighbor_list_sets ...
     989              : !> \param nlist ...
     990              : !> \param symmetric ...
     991              : !> \date    07.2014
     992              : !> \author  JGH
     993              : !> \version 1.0
     994              : ! **************************************************************************************************
     995      3236347 :    SUBROUTINE get_neighbor_list_set_p(neighbor_list_sets, nlist, symmetric)
     996              : 
     997              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     998              :          POINTER                                         :: neighbor_list_sets
     999              :       INTEGER, INTENT(OUT), OPTIONAL                     :: nlist
    1000              :       LOGICAL, INTENT(OUT), OPTIONAL                     :: symmetric
    1001              : 
    1002              :       INTEGER                                            :: i
    1003              :       TYPE(neighbor_list_set_type), POINTER              :: neighbor_list_set
    1004              : 
    1005      3236347 :       IF (ASSOCIATED(neighbor_list_sets)) THEN
    1006              : 
    1007      3236347 :          NULLIFY (neighbor_list_set)
    1008      3236391 :          DO i = 1, SIZE(neighbor_list_sets)
    1009      3236391 :             neighbor_list_set => neighbor_list_sets(i)%neighbor_list_set
    1010      3236391 :             IF (ASSOCIATED(neighbor_list_set)) EXIT
    1011              :          END DO
    1012              : 
    1013      3236347 :          IF (ASSOCIATED(neighbor_list_set)) THEN
    1014      3236347 :             IF (PRESENT(nlist)) nlist = neighbor_list_set%nlist
    1015      3236347 :             IF (PRESENT(symmetric)) symmetric = neighbor_list_set%symmetric
    1016              :          ELSE
    1017              :             CALL cp_abort(__LOCATION__, "No neighbor list set is associated. "// &
    1018            0 :                           "Did you specify *all* required basis-sets, eg. for ADMM?")
    1019              :          END IF
    1020              : 
    1021              :       ELSE
    1022              : 
    1023            0 :          CPABORT("The requested neighbor list sets are not associated")
    1024              : 
    1025              :       END IF
    1026              : 
    1027      3236347 :    END SUBROUTINE get_neighbor_list_set_p
    1028              : 
    1029              : ! **************************************************************************************************
    1030              : !> \brief   Return the requested data of a neighbor node.
    1031              : !> \param neighbor_node ...
    1032              : !> \param neighbor ...
    1033              : !> \param cell ...
    1034              : !> \param r ...
    1035              : !> \date    23.06.2000
    1036              : !> \author  MK
    1037              : !> \version 1.0
    1038              : ! **************************************************************************************************
    1039   3414517137 :    SUBROUTINE get_neighbor_node(neighbor_node, neighbor, cell, r)
    1040              : 
    1041              :       TYPE(neighbor_node_type), POINTER                  :: neighbor_node
    1042              :       INTEGER, INTENT(OUT), OPTIONAL                     :: neighbor
    1043              :       INTEGER, DIMENSION(3), INTENT(OUT), OPTIONAL       :: cell
    1044              :       REAL(dp), DIMENSION(3), INTENT(OUT), OPTIONAL      :: r
    1045              : 
    1046   3414517137 :       IF (ASSOCIATED(neighbor_node)) THEN
    1047   3414517137 :          IF (PRESENT(neighbor)) neighbor = neighbor_node%neighbor
    1048   5460544093 :          IF (PRESENT(r)) r(:) = neighbor_node%r(:)
    1049   4285373389 :          IF (PRESENT(cell)) cell(:) = neighbor_node%cell(:)
    1050              :       ELSE
    1051            0 :          CPABORT("The requested neighbor node is not associated")
    1052              :       END IF
    1053              : 
    1054   3414517137 :    END SUBROUTINE get_neighbor_node
    1055              : 
    1056              : ! **************************************************************************************************
    1057              : !> \brief Initialize a neighbor list set. Nothing is (de)allocated here.
    1058              : !>         This routine is also used to prepare a neighbor list set for
    1059              : !>         overwriting.
    1060              : !> \param neighbor_list_set ...
    1061              : !> \param symmetric ...
    1062              : !> \date  20.09.2002
    1063              : !> \author  MK
    1064              : !> \version 1.0
    1065              : ! **************************************************************************************************
    1066       605635 :    SUBROUTINE init_neighbor_list_set(neighbor_list_set, symmetric)
    1067              : 
    1068              :       TYPE(neighbor_list_set_type), POINTER              :: neighbor_list_set
    1069              :       LOGICAL, INTENT(IN)                                :: symmetric
    1070              : 
    1071       605635 :       IF (ASSOCIATED(neighbor_list_set)) THEN
    1072              : 
    1073              :          ! *** Initialize the pointers to the last neighbor list ***
    1074       605635 :          NULLIFY (neighbor_list_set%last_neighbor_list)
    1075              : 
    1076              :          ! *** Initialize the neighbor list counter ***
    1077       605635 :          neighbor_list_set%nlist = 0
    1078              : 
    1079              :          ! *** Initialize the neighbor list build properties
    1080       605635 :          neighbor_list_set%symmetric = symmetric
    1081              : 
    1082              :       ELSE
    1083              : 
    1084            0 :          CPABORT("The requested neighbor list set is not associated")
    1085              : 
    1086              :       END IF
    1087              : 
    1088       605635 :    END SUBROUTINE init_neighbor_list_set
    1089              : 
    1090              : ! **************************************************************************************************
    1091              : !> \brief releases an array of neighbor_list_sets
    1092              : !> \param nlists ...
    1093              : !> \author Ole Schuett
    1094              : ! **************************************************************************************************
    1095       454243 :    SUBROUTINE release_neighbor_list_sets(nlists)
    1096              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    1097              :          POINTER                                         :: nlists
    1098              : 
    1099              :       INTEGER                                            :: i
    1100              : 
    1101       454243 :       IF (ASSOCIATED(nlists)) THEN
    1102       820080 :          DO i = 1, SIZE(nlists)
    1103       820080 :             CALL deallocate_neighbor_list_set(nlists(i)%neighbor_list_set)
    1104              :          END DO
    1105       154551 :          IF (ASSOCIATED(nlists(1)%nlist_task)) THEN
    1106       154551 :             DEALLOCATE (nlists(1)%nlist_task)
    1107              :          END IF
    1108       154551 :          DEALLOCATE (nlists)
    1109              :       END IF
    1110       454243 :    END SUBROUTINE release_neighbor_list_sets
    1111              : 
    1112            0 : END MODULE qs_neighbor_list_types
        

Generated by: LCOV version 2.0-1