LCOV - code coverage report
Current view: top level - src - qs_fb_atomic_halo_types.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:42dac4a) Lines: 80.7 % 233 188
Test Date: 2025-07-25 12:55:17 Functions: 71.4 % 28 20

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : MODULE qs_fb_atomic_halo_types
       9              : 
      10              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      11              :                                               get_atomic_kind
      12              :    USE cell_types,                      ONLY: cell_type,&
      13              :                                               pbc
      14              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      15              :                                               cp_logger_type
      16              :    USE cp_output_handling,              ONLY: cp_p_file,&
      17              :                                               cp_print_key_finished_output,&
      18              :                                               cp_print_key_should_output,&
      19              :                                               cp_print_key_unit_nr
      20              :    USE input_section_types,             ONLY: section_vals_type
      21              :    USE kinds,                           ONLY: default_string_length,&
      22              :                                               dp
      23              :    USE memory_utilities,                ONLY: reallocate
      24              :    USE message_passing,                 ONLY: mp_para_env_type
      25              :    USE particle_types,                  ONLY: particle_type
      26              :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      27              :                                               qs_kind_type
      28              :    USE string_utilities,                ONLY: compress
      29              :    USE util,                            ONLY: locate,&
      30              :                                               sort
      31              : #include "./base/base_uses.f90"
      32              : 
      33              :    IMPLICIT NONE
      34              : 
      35              :    PRIVATE
      36              : 
      37              : ! public types
      38              :    PUBLIC :: fb_atomic_halo_obj, &
      39              :              fb_atomic_halo_list_obj
      40              : 
      41              : ! public methods
      42              : !API
      43              :    PUBLIC :: fb_atomic_halo_release, &
      44              :              fb_atomic_halo_nullify, &
      45              :              fb_atomic_halo_has_data, &
      46              :              fb_atomic_halo_create, &
      47              :              fb_atomic_halo_init, &
      48              :              fb_atomic_halo_get, &
      49              :              fb_atomic_halo_set, &
      50              :              fb_atomic_halo_sort, &
      51              :              fb_atomic_halo_atom_global2halo, &
      52              :              fb_atomic_halo_nelectrons_estimate_Z, &
      53              :              fb_atomic_halo_cost, &
      54              :              fb_atomic_halo_build_halo_atoms, &
      55              :              fb_atomic_halo_list_release, &
      56              :              fb_atomic_halo_list_nullify, &
      57              :              fb_atomic_halo_list_has_data, &
      58              :              fb_atomic_halo_list_associate, &
      59              :              fb_atomic_halo_list_create, &
      60              :              fb_atomic_halo_list_get, &
      61              :              fb_atomic_halo_list_set, &
      62              :              fb_atomic_halo_list_write_info, &
      63              :              fb_build_pair_radii
      64              : 
      65              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_fb_atomic_halo_types'
      66              : 
      67              : ! **************************************************************************************************
      68              : !> \brief derived type containing the list of atoms in an atomic halo,
      69              : !>        used by filtered-basis diagonalisation method
      70              : !> \param owner_atom       : global atomic id of the atom this halo belongs to
      71              : !> \param owner_id_in_halo : index of the owner_atom in the halo_atoms array
      72              : !> \param natoms           : number of atoms in the halo
      73              : !> \param nelectrons       : estimate of total number of electrons in halo
      74              : !> \param halo_atoms       : the list of global id of atoms in the halo
      75              : !> \param sorted           : whether the halo_atoms list is sorted or not
      76              : !> \param cost             : computational cost for the atomic matrix associated
      77              : !>                           to this atomic halo
      78              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
      79              : ! **************************************************************************************************
      80              :    TYPE fb_atomic_halo_data
      81              :       INTEGER :: owner_atom = -1
      82              :       INTEGER :: owner_id_in_halo = -1
      83              :       INTEGER :: natoms = -1
      84              :       INTEGER :: nelectrons = -1
      85              :       INTEGER, DIMENSION(:), POINTER :: halo_atoms => NULL()
      86              :       LOGICAL :: sorted = .FALSE.
      87              :       REAL(KIND=dp) :: cost = -1.0_dp
      88              :    END TYPE fb_atomic_halo_data
      89              : 
      90              : ! **************************************************************************************************
      91              : !> \brief defines a fb_atomic_halo object
      92              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
      93              : ! **************************************************************************************************
      94              :    TYPE fb_atomic_halo_obj
      95              :       TYPE(fb_atomic_halo_data), POINTER, PRIVATE :: obj => NULL()
      96              :    END TYPE fb_atomic_halo_obj
      97              : 
      98              : ! **************************************************************************************************
      99              : !> \brief derived type describing an atomic halo list used by
     100              : !>        filtered-basis diagonalisation method
     101              : !> \param nhalos  : number of halos in the list
     102              : !> \param max_nhalos : maximum of the number of halos amongst all of the procs
     103              : !> \param halos   : halos(ihalo) gives the ihalo-th fb_atomic_halo object
     104              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     105              : ! **************************************************************************************************
     106              :    TYPE fb_atomic_halo_list_data
     107              :       INTEGER :: nhalos = -1
     108              :       INTEGER :: max_nhalos = -1
     109              :       TYPE(fb_atomic_halo_obj), DIMENSION(:), POINTER :: halos => NULL()
     110              :    END TYPE fb_atomic_halo_list_data
     111              : 
     112              : ! **************************************************************************************************
     113              : !> \brief defines a fb_atomic_halo_list object
     114              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     115              : ! **************************************************************************************************
     116              :    TYPE fb_atomic_halo_list_obj
     117              :       TYPE(fb_atomic_halo_list_data), POINTER, PRIVATE :: obj => NULL()
     118              :    END TYPE fb_atomic_halo_list_obj
     119              : 
     120              : CONTAINS
     121              : 
     122              : ! **************************************************************************************************
     123              : !> \brief Releases an fb_atomic_halo object
     124              : !> \param atomic_halo the fb_atomic_halo object, its content must
     125              : !>                     not be UNDEFINED, and the subroutine does nothing
     126              : !>                     if the content points to NULL
     127              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     128              : ! **************************************************************************************************
     129          114 :    SUBROUTINE fb_atomic_halo_release(atomic_halo)
     130              :       TYPE(fb_atomic_halo_obj), INTENT(INOUT)            :: atomic_halo
     131              : 
     132          114 :       IF (ASSOCIATED(atomic_halo%obj)) THEN
     133          114 :          IF (ASSOCIATED(atomic_halo%obj%halo_atoms)) THEN
     134              :             ! note that if there are other pointers associated to the memory pointed
     135              :             ! by atomic_halo%obj%halo_atoms, their behaviour becomes undefined per
     136              :             ! FORTRAN standard (and thus becomes compiler dependent and unreliable)
     137              :             ! after the following DEALLOCATE
     138          114 :             DEALLOCATE (atomic_halo%obj%halo_atoms)
     139              :          END IF
     140          114 :          DEALLOCATE (atomic_halo%obj)
     141              :       ELSE
     142            0 :          NULLIFY (atomic_halo%obj)
     143              :       END IF
     144          114 :    END SUBROUTINE fb_atomic_halo_release
     145              : 
     146              : ! **************************************************************************************************
     147              : !> \brief Nullifies a fb_atomic_halo object, note that it does not
     148              : !>        release the original object. This procedure is used to nullify
     149              : !>        the pointer contained in the object which is used to associate
     150              : !>        to the actual object content
     151              : !> \param atomic_halo the fb_atomic_halo object
     152              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     153              : ! **************************************************************************************************
     154          114 :    SUBROUTINE fb_atomic_halo_nullify(atomic_halo)
     155              :       TYPE(fb_atomic_halo_obj), INTENT(INOUT)            :: atomic_halo
     156              : 
     157          114 :       NULLIFY (atomic_halo%obj)
     158          114 :    END SUBROUTINE fb_atomic_halo_nullify
     159              : 
     160              : ! **************************************************************************************************
     161              : !> \brief Associates one fb_atomic_halo object to another
     162              : !> \param a the fb_atomic_halo object to be associated
     163              : !> \param b the fb_atomic_halo object that a is to be associated to
     164              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     165              : ! **************************************************************************************************
     166            0 :    SUBROUTINE fb_atomic_halo_associate(a, b)
     167              :       TYPE(fb_atomic_halo_obj), INTENT(OUT)              :: a
     168              :       TYPE(fb_atomic_halo_obj), INTENT(IN)               :: b
     169              : 
     170            0 :       a%obj => b%obj
     171            0 :    END SUBROUTINE fb_atomic_halo_associate
     172              : 
     173              : ! **************************************************************************************************
     174              : !> \brief Checks if a fb_atomic_halo object is associated with an actual
     175              : !>        data content or not
     176              : !> \param atomic_halo the fb_atomic_halo object
     177              : !> \return ...
     178              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     179              : ! **************************************************************************************************
     180          128 :    FUNCTION fb_atomic_halo_has_data(atomic_halo) RESULT(res)
     181              :       TYPE(fb_atomic_halo_obj), INTENT(IN)               :: atomic_halo
     182              :       LOGICAL                                            :: res
     183              : 
     184          128 :       res = ASSOCIATED(atomic_halo%obj)
     185          128 :    END FUNCTION fb_atomic_halo_has_data
     186              : 
     187              : ! **************************************************************************************************
     188              : !> \brief Creates and initialises an empty fb_atomic_halo object
     189              : !> \param atomic_halo the fb_atomic_halo object, its content must
     190              : !>                     be NULL and cannot be UNDEFINED
     191              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     192              : ! **************************************************************************************************
     193          114 :    SUBROUTINE fb_atomic_halo_create(atomic_halo)
     194              :       TYPE(fb_atomic_halo_obj), INTENT(INOUT)            :: atomic_halo
     195              : 
     196          114 :       CPASSERT(.NOT. ASSOCIATED(atomic_halo%obj))
     197          114 :       ALLOCATE (atomic_halo%obj)
     198          114 :       atomic_halo%obj%owner_atom = 0
     199          114 :       atomic_halo%obj%owner_id_in_halo = 0
     200          114 :       atomic_halo%obj%natoms = 0
     201          114 :       atomic_halo%obj%nelectrons = 0
     202              :       atomic_halo%obj%sorted = .FALSE.
     203          114 :       atomic_halo%obj%cost = 0.0_dp
     204              :       NULLIFY (atomic_halo%obj%halo_atoms)
     205          114 :    END SUBROUTINE fb_atomic_halo_create
     206              : 
     207              : ! **************************************************************************************************
     208              : !> \brief Initialises an fb_atomic_halo object, and makes it empty
     209              : !> \param atomic_halo the fb_atomic_halo object, its content must
     210              : !>                     not be NULL or UNDEFINED
     211              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     212              : ! **************************************************************************************************
     213           80 :    SUBROUTINE fb_atomic_halo_init(atomic_halo)
     214              :       TYPE(fb_atomic_halo_obj), INTENT(INOUT)            :: atomic_halo
     215              : 
     216           80 :       CPASSERT(ASSOCIATED(atomic_halo%obj))
     217              :       ! if halo_atoms are associated, then deallocate and de-associate
     218           80 :       IF (ASSOCIATED(atomic_halo%obj%halo_atoms)) THEN
     219           70 :          DEALLOCATE (atomic_halo%obj%halo_atoms)
     220              :       END IF
     221           80 :       atomic_halo%obj%owner_atom = 0
     222           80 :       atomic_halo%obj%owner_id_in_halo = 0
     223           80 :       atomic_halo%obj%natoms = 0
     224           80 :       atomic_halo%obj%nelectrons = 0
     225           80 :       atomic_halo%obj%sorted = .FALSE.
     226           80 :       atomic_halo%obj%cost = 0.0_dp
     227           80 :    END SUBROUTINE fb_atomic_halo_init
     228              : 
     229              : ! **************************************************************************************************
     230              : !> \brief Gets attributes from a fb_atomic_halo object, one should
     231              : !>        only access the data content in a fb_atomic_halo outside
     232              : !>        this module via this procedure.
     233              : !> \param atomic_halo the fb_atomic_halo object, its content must
     234              : !>                     not be NULL or UNDEFINED
     235              : !> \param owner_atom [OPTIONAL]: if present, outputs atmic_halo%obj%owner_atom
     236              : !> \param owner_id_in_halo ...
     237              : !> \param natoms [OPTIONAL]: if present, outputs atomic_halo%obj%natoms
     238              : !> \param nelectrons [OPTIONAL]: if present, outputs atomic_halo%obj%nelectrons
     239              : !> \param halo_atoms [OPTIONAL]: if present, outputs pointer
     240              : !>                               atomic_halo%obj%halo_atoms
     241              : !> \param sorted [OPTIONAL]: if present, outputs atomic_halo%obj%sorted
     242              : !> \param cost [OPTIONAL]: if present, outputs atomic_halo%obj%cost
     243              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     244              : ! **************************************************************************************************
     245         2408 :    SUBROUTINE fb_atomic_halo_get(atomic_halo, &
     246              :                                  owner_atom, &
     247              :                                  owner_id_in_halo, &
     248              :                                  natoms, &
     249              :                                  nelectrons, &
     250              :                                  halo_atoms, &
     251              :                                  sorted, &
     252              :                                  cost)
     253              :       TYPE(fb_atomic_halo_obj), INTENT(IN)               :: atomic_halo
     254              :       INTEGER, INTENT(OUT), OPTIONAL                     :: owner_atom, owner_id_in_halo, natoms, &
     255              :                                                             nelectrons
     256              :       INTEGER, DIMENSION(:), OPTIONAL, POINTER           :: halo_atoms
     257              :       LOGICAL, INTENT(OUT), OPTIONAL                     :: sorted
     258              :       REAL(KIND=dp), INTENT(OUT), OPTIONAL               :: cost
     259              : 
     260         2408 :       CPASSERT(ASSOCIATED(atomic_halo%obj))
     261         2408 :       IF (PRESENT(owner_atom)) owner_atom = atomic_halo%obj%owner_atom
     262         2408 :       IF (PRESENT(owner_id_in_halo)) owner_id_in_halo = atomic_halo%obj%owner_id_in_halo
     263         2408 :       IF (PRESENT(natoms)) natoms = atomic_halo%obj%natoms
     264         2408 :       IF (PRESENT(nelectrons)) nelectrons = atomic_halo%obj%nelectrons
     265         2408 :       IF (PRESENT(halo_atoms)) halo_atoms => atomic_halo%obj%halo_atoms
     266         2408 :       IF (PRESENT(sorted)) sorted = atomic_halo%obj%sorted
     267         2408 :       IF (PRESENT(cost)) cost = atomic_halo%obj%cost
     268         2408 :    END SUBROUTINE fb_atomic_halo_get
     269              : 
     270              : ! **************************************************************************************************
     271              : !> \brief Sets attributes in a fb_atomic_halo object, one should
     272              : !>        only set the data content in a fb_atomic_halo from outside
     273              : !>        this module via this procedure.
     274              : !> \param atomic_halo the fb_atomic_halo object, its content must
     275              : !>                     not be NULL or UNDEFINED
     276              : !> \param owner_atom [OPTIONAL]: if present, sets
     277              : !>                               atmic_halo%obj%owner_atom = owner_atom
     278              : !> \param owner_id_in_halo ...
     279              : !> \param natoms [OPTIONAL]: if present, sets atomic_halo%obj%natoms = natoms
     280              : !> \param nelectrons [OPTIONAL]: if present, sets atomic_halo%obj%nelectrons = nelectrons
     281              : !> \param halo_atoms [OPTIONAL]: if present, reallocates atomic_halo%obj%halo_atoms
     282              : !>                               to the size of halo_atoms, and copies
     283              : !>                               contents of halo_atoms to atomic_halo%obj%halo_atoms
     284              : !> \param sorted [OPTIONAL]: if present, sets atomic_halo%obj%sorted = sorted
     285              : !> \param cost [OPTIONAL]: if present, sets atomic_halo%obj%cost = cost
     286              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     287              : ! **************************************************************************************************
     288          224 :    SUBROUTINE fb_atomic_halo_set(atomic_halo, &
     289              :                                  owner_atom, &
     290              :                                  owner_id_in_halo, &
     291              :                                  natoms, &
     292              :                                  nelectrons, &
     293              :                                  halo_atoms, &
     294              :                                  sorted, &
     295              :                                  cost)
     296              :       TYPE(fb_atomic_halo_obj), INTENT(INOUT)            :: atomic_halo
     297              :       INTEGER, INTENT(IN), OPTIONAL                      :: owner_atom, owner_id_in_halo, natoms, &
     298              :                                                             nelectrons
     299              :       INTEGER, DIMENSION(:), OPTIONAL, POINTER           :: halo_atoms
     300              :       LOGICAL, INTENT(IN), OPTIONAL                      :: sorted
     301              :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: cost
     302              : 
     303          224 :       CPASSERT(ASSOCIATED(atomic_halo%obj))
     304          224 :       IF (PRESENT(owner_atom)) atomic_halo%obj%owner_atom = owner_atom
     305          224 :       IF (PRESENT(owner_id_in_halo)) atomic_halo%obj%owner_id_in_halo = owner_id_in_halo
     306          224 :       IF (PRESENT(natoms)) atomic_halo%obj%natoms = natoms
     307          224 :       IF (PRESENT(nelectrons)) atomic_halo%obj%nelectrons = nelectrons
     308          224 :       IF (PRESENT(halo_atoms)) THEN
     309          184 :          IF (ASSOCIATED(atomic_halo%obj%halo_atoms)) THEN
     310            0 :             DEALLOCATE (atomic_halo%obj%halo_atoms)
     311              :          END IF
     312          184 :          atomic_halo%obj%halo_atoms => halo_atoms
     313              :       END IF
     314          224 :       IF (PRESENT(nelectrons)) atomic_halo%obj%nelectrons = nelectrons
     315          224 :       IF (PRESENT(sorted)) atomic_halo%obj%sorted = sorted
     316          224 :       IF (PRESENT(cost)) atomic_halo%obj%cost = cost
     317          224 :    END SUBROUTINE fb_atomic_halo_set
     318              : 
     319              : ! **************************************************************************************************
     320              : !> \brief Sort the list of atomic indices in the halo in ascending order.
     321              : !>        The atomic_halo must not be empty
     322              : !> \param atomic_halo  the atomic_halo object
     323              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     324              : ! **************************************************************************************************
     325           40 :    SUBROUTINE fb_atomic_halo_sort(atomic_halo)
     326              :       TYPE(fb_atomic_halo_obj), INTENT(INOUT)            :: atomic_halo
     327              : 
     328           40 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: tmp_index
     329              : 
     330           40 :       CPASSERT(SIZE(atomic_halo%obj%halo_atoms) > 0)
     331          120 :       ALLOCATE (tmp_index(atomic_halo%obj%natoms))
     332           40 :       CALL sort(atomic_halo%obj%halo_atoms, atomic_halo%obj%natoms, tmp_index)
     333           40 :       DEALLOCATE (tmp_index)
     334           40 :       atomic_halo%obj%sorted = .TRUE.
     335           40 :    END SUBROUTINE fb_atomic_halo_sort
     336              : 
     337              : ! **************************************************************************************************
     338              : !> \brief Given a global atomic index, convert it to its index in a
     339              : !>        given atomic halo, if found.
     340              : !>        The atomic_halo object must already have been sorted
     341              : !> \param atomic_halo  the atomic_halo object
     342              : !> \param iatom_global  the global atomic index
     343              : !> \param iatom_halo  the atomic index inside the halo
     344              : !> \param found  returns true if given atom is in the halo, otherwise
     345              : !>                false
     346              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     347              : ! **************************************************************************************************
     348        36864 :    SUBROUTINE fb_atomic_halo_atom_global2halo(atomic_halo, &
     349              :                                               iatom_global, &
     350              :                                               iatom_halo, &
     351              :                                               found)
     352              :       TYPE(fb_atomic_halo_obj), INTENT(IN)               :: atomic_halo
     353              :       INTEGER, INTENT(IN)                                :: iatom_global
     354              :       INTEGER, INTENT(OUT)                               :: iatom_halo
     355              :       LOGICAL, INTENT(OUT)                               :: found
     356              : 
     357              :       CHARACTER(len=*), PARAMETER :: routineN = 'fb_atomic_halo_atom_global2halo'
     358              : 
     359              :       INTEGER                                            :: handle
     360              : 
     361        36864 :       CALL timeset(routineN, handle)
     362              : 
     363        36864 :       CPASSERT(atomic_halo%obj%sorted)
     364        36864 :       iatom_halo = locate(atomic_halo%obj%halo_atoms, iatom_global)
     365        36864 :       IF (iatom_halo == 0) THEN
     366            0 :          found = .FALSE.
     367              :       ELSE
     368        36864 :          found = .TRUE.
     369              :       END IF
     370              : 
     371        36864 :       CALL timestop(handle)
     372              : 
     373        36864 :    END SUBROUTINE fb_atomic_halo_atom_global2halo
     374              : 
     375              : ! **************************************************************************************************
     376              : !> \brief Estimates the total number of electrons in a halo using atomic
     377              : !>        numbers
     378              : !> \param atomic_halo the atomic_halo object
     379              : !> \param particle_set an array of cp2k particle set objects (this
     380              : !>                       gives atomic information)
     381              : !> \return estimate of electron number
     382              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     383              : ! **************************************************************************************************
     384           40 :    FUNCTION fb_atomic_halo_nelectrons_estimate_Z(atomic_halo, particle_set) RESULT(nelectrons)
     385              :       TYPE(fb_atomic_halo_obj), INTENT(IN)               :: atomic_halo
     386              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
     387              :       INTEGER                                            :: nelectrons
     388              : 
     389              :       INTEGER                                            :: iatom_global, iatom_halo, z
     390              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
     391              : 
     392           40 :       nelectrons = 0
     393           40 :       IF (ASSOCIATED(atomic_halo%obj)) THEN
     394          360 :          DO iatom_halo = 1, atomic_halo%obj%natoms
     395          320 :             iatom_global = atomic_halo%obj%halo_atoms(iatom_halo)
     396          320 :             atomic_kind => particle_set(iatom_global)%atomic_kind
     397              :             CALL get_atomic_kind(atomic_kind=atomic_kind, &
     398          320 :                                  z=z)
     399          360 :             nelectrons = nelectrons + z
     400              :          END DO
     401              :       END IF
     402           40 :    END FUNCTION fb_atomic_halo_nelectrons_estimate_Z
     403              : 
     404              : ! **************************************************************************************************
     405              : !> \brief Estimates the computational cost with respect to the filter matrix
     406              : !>        calculation associated to an atomic halo. Given the bottle neck
     407              : !>        of the filter matrix generation will be the diagoanlisation of the
     408              : !>        atomic matrices (each consists of atoms in an atomic halo), the cost
     409              : !>        can be estimated by counting the total number of contracted gaussians
     410              : !>        in the halo
     411              : !> \param atomic_halo  : the atomic_halo object in question
     412              : !> \param particle_set : an array of cp2k particle set objects, this
     413              : !>                       provides atomic information
     414              : !> \param qs_kind_set  : cp2k qs_kind objects, provides information on the
     415              : !>                       number of contracted gaussian functions each kind
     416              : !>                       has
     417              : !> \return : computation cost w.r.t. the filter matrix
     418              : !>                       calculation for this atomic halo
     419              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     420              : ! **************************************************************************************************
     421          120 :    FUNCTION fb_atomic_halo_cost(atomic_halo, &
     422          120 :                                 particle_set, &
     423          120 :                                 qs_kind_set) &
     424              :       RESULT(cost)
     425              :       TYPE(fb_atomic_halo_obj), INTENT(IN)               :: atomic_halo
     426              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
     427              :       TYPE(qs_kind_type), DIMENSION(:), INTENT(IN)       :: qs_kind_set
     428              :       REAL(KIND=dp)                                      :: cost
     429              : 
     430              :       INTEGER                                            :: iatom, ii, ikind, ncgf
     431              : 
     432          120 :       cost = 0.0_dp
     433         1080 :       DO ii = 1, atomic_halo%obj%natoms
     434          960 :          iatom = atomic_halo%obj%halo_atoms(ii)
     435              :          CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, &
     436          960 :                               kind_number=ikind)
     437              :          CALL get_qs_kind(qs_kind=qs_kind_set(ikind), &
     438          960 :                           ncgf=ncgf)
     439         1080 :          cost = cost + REAL(ncgf, dp)
     440              :       END DO
     441              :       ! diagonalisation is N**3 process, so cost must reflect that
     442          120 :       cost = cost**3
     443          120 :    END FUNCTION fb_atomic_halo_cost
     444              : 
     445              : ! **************************************************************************************************
     446              : !> \brief Builds halo atoms for a given (owner) atom
     447              : !> \param owner_atom   : the atom the halo is going to be built for
     448              : !> \param particle_set : an array of cp2k particle set objects, this
     449              : !>                       provides atomic information
     450              : !> \param cell         : cp2k cell object, used for resolving periodic
     451              : !>                       boundary conditions
     452              : !> \param pair_radii   : 2D array storing interaction radii between two kinds
     453              : !> \param halo_atoms   : must be NULL pointer on input, and outputs an
     454              : !>                       array of halo atoms corresponding to the owner atom
     455              : !> \param nhalo_atoms  : outputs number of halo atoms
     456              : !> \param owner_id_in_halo : the index of the owner atom in the halo_atoms list
     457              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     458              : ! **************************************************************************************************
     459          120 :    SUBROUTINE fb_atomic_halo_build_halo_atoms(owner_atom, &
     460          120 :                                               particle_set, &
     461              :                                               cell, &
     462          120 :                                               pair_radii, &
     463              :                                               halo_atoms, &
     464              :                                               nhalo_atoms, &
     465              :                                               owner_id_in_halo)
     466              :       INTEGER, INTENT(IN)                                :: owner_atom
     467              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
     468              :       TYPE(cell_type), POINTER                           :: cell
     469              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: pair_radii
     470              :       INTEGER, DIMENSION(:), POINTER                     :: halo_atoms
     471              :       INTEGER, INTENT(OUT)                               :: nhalo_atoms, owner_id_in_halo
     472              : 
     473              :       INTEGER                                            :: iatom, ikind, jatom, jkind, natoms_global
     474              :       LOGICAL                                            :: check_ok
     475              :       REAL(KIND=dp)                                      :: rij
     476              :       REAL(KIND=dp), DIMENSION(3)                        :: ri, rij_pbc, rj
     477              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
     478              : 
     479          120 :       check_ok = .NOT. ASSOCIATED(halo_atoms)
     480          120 :       CPASSERT(check_ok)
     481              : 
     482          120 :       NULLIFY (atomic_kind)
     483              : 
     484          120 :       iatom = owner_atom
     485          120 :       atomic_kind => particle_set(iatom)%atomic_kind
     486              :       CALL get_atomic_kind(atomic_kind=atomic_kind, &
     487          120 :                            kind_number=ikind)
     488          120 :       natoms_global = SIZE(particle_set)
     489          360 :       ALLOCATE (halo_atoms(natoms_global))
     490          120 :       owner_id_in_halo = 0
     491          120 :       nhalo_atoms = 0
     492         1080 :       DO jatom = 1, natoms_global
     493          960 :          atomic_kind => particle_set(jatom)%atomic_kind
     494              :          CALL get_atomic_kind(atomic_kind=atomic_kind, &
     495          960 :                               kind_number=jkind)
     496              :          ! calculate the minimum distance between iatom and
     497              :          ! jatom, taking account of the periodic boundary
     498              :          ! conditions
     499         3840 :          ri(1:3) = particle_set(iatom)%r(1:3)
     500         3840 :          rj(1:3) = particle_set(jatom)%r(1:3)
     501          960 :          rij_pbc = pbc(ri, rj, cell)
     502              :          rij = rij_pbc(1)*rij_pbc(1) + &
     503              :                rij_pbc(2)*rij_pbc(2) + &
     504          960 :                rij_pbc(3)*rij_pbc(3)
     505          960 :          rij = SQRT(rij)
     506         2040 :          IF (rij .LE. pair_radii(ikind, jkind)) THEN
     507              :             ! jatom is in iatom's halo
     508          960 :             nhalo_atoms = nhalo_atoms + 1
     509          960 :             halo_atoms(nhalo_atoms) = jatom
     510          960 :             IF (jatom == iatom) owner_id_in_halo = nhalo_atoms
     511              :          END IF
     512              :       END DO
     513          120 :       CALL reallocate(halo_atoms, 1, nhalo_atoms)
     514          120 :    END SUBROUTINE fb_atomic_halo_build_halo_atoms
     515              : 
     516              : ! **************************************************************************************************
     517              : !> \brief Releases an fb_atomic_halo_list object
     518              : !> \param atomic_halos the fb_atomic_halo object, its content must
     519              : !>                      not be UNDEFINED, and does nothing if it is NULL
     520              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     521              : ! **************************************************************************************************
     522           20 :    SUBROUTINE fb_atomic_halo_list_release(atomic_halos)
     523              :       TYPE(fb_atomic_halo_list_obj), INTENT(INOUT)       :: atomic_halos
     524              : 
     525              :       INTEGER                                            :: ii
     526              : 
     527           20 :       IF (ASSOCIATED(atomic_halos%obj)) THEN
     528           10 :          IF (ASSOCIATED(atomic_halos%obj%halos)) THEN
     529           50 :             DO ii = 1, SIZE(atomic_halos%obj%halos)
     530           50 :                CALL fb_atomic_halo_release(atomic_halos%obj%halos(ii))
     531              :             END DO
     532           10 :             DEALLOCATE (atomic_halos%obj%halos)
     533              :          END IF
     534           10 :          DEALLOCATE (atomic_halos%obj)
     535              :       ELSE
     536           10 :          NULLIFY (atomic_halos%obj)
     537              :       END IF
     538           20 :    END SUBROUTINE fb_atomic_halo_list_release
     539              : 
     540              : ! **************************************************************************************************
     541              : !> \brief Nullifies a fb_atomic_halo_list object, note that it does
     542              : !>        not release the original object. This procedure is used to
     543              : !>        nullify the pointer contained in the object which is used to
     544              : !>        associate to the actual object content
     545              : !> \param atomic_halos the fb_atomic_halo_list object
     546              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     547              : ! **************************************************************************************************
     548          100 :    SUBROUTINE fb_atomic_halo_list_nullify(atomic_halos)
     549              :       TYPE(fb_atomic_halo_list_obj), INTENT(INOUT)       :: atomic_halos
     550              : 
     551          100 :       NULLIFY (atomic_halos%obj)
     552          100 :    END SUBROUTINE fb_atomic_halo_list_nullify
     553              : 
     554              : ! **************************************************************************************************
     555              : !> \brief Checks if a fb_atomic_halo_list object is associated with
     556              : !>        an actual data content or not
     557              : !> \param atomic_halos the fb_atomic_halo_list object
     558              : !> \return ...
     559              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     560              : ! **************************************************************************************************
     561            0 :    FUNCTION fb_atomic_halo_list_has_data(atomic_halos) RESULT(res)
     562              :       TYPE(fb_atomic_halo_list_obj), INTENT(IN)          :: atomic_halos
     563              :       LOGICAL                                            :: res
     564              : 
     565            0 :       res = ASSOCIATED(atomic_halos%obj)
     566            0 :    END FUNCTION fb_atomic_halo_list_has_data
     567              : 
     568              : ! **************************************************************************************************
     569              : !> \brief Associates one fb_atomic_halo_list object to another
     570              : !> \param a the fb_atomic_halo_list object to be associated
     571              : !> \param b the fb_atomic_halo_list object that a is to be associated to
     572              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     573              : ! **************************************************************************************************
     574           90 :    SUBROUTINE fb_atomic_halo_list_associate(a, b)
     575              :       TYPE(fb_atomic_halo_list_obj), INTENT(OUT)         :: a
     576              :       TYPE(fb_atomic_halo_list_obj), INTENT(IN)          :: b
     577              : 
     578           90 :       a%obj => b%obj
     579           90 :    END SUBROUTINE fb_atomic_halo_list_associate
     580              : 
     581              : ! **************************************************************************************************
     582              : !> \brief Creates and initialises an empty fb_atomic_halo_list object
     583              : !> \param atomic_halos the fb_atomic_halo object, its content must
     584              : !>                      not be NULL or UNDEFINED
     585              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     586              : ! **************************************************************************************************
     587           10 :    SUBROUTINE fb_atomic_halo_list_create(atomic_halos)
     588              :       TYPE(fb_atomic_halo_list_obj), INTENT(INOUT)       :: atomic_halos
     589              : 
     590           10 :       CPASSERT(.NOT. ASSOCIATED(atomic_halos%obj))
     591           10 :       ALLOCATE (atomic_halos%obj)
     592           10 :       atomic_halos%obj%nhalos = 0
     593           10 :       atomic_halos%obj%max_nhalos = 0
     594              :       NULLIFY (atomic_halos%obj%halos)
     595           10 :    END SUBROUTINE fb_atomic_halo_list_create
     596              : 
     597              : ! **************************************************************************************************
     598              : !> \brief Initialises an fb_atomic_halo_list object and make it empty
     599              : !> \param atomic_halos the fb_atomic_halo object, its content must
     600              : !>                      not be NULL or UNDEFINED
     601              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     602              : ! **************************************************************************************************
     603            0 :    SUBROUTINE fb_atomic_halo_list_init(atomic_halos)
     604              :       TYPE(fb_atomic_halo_list_obj), INTENT(INOUT)       :: atomic_halos
     605              : 
     606              :       INTEGER                                            :: ii
     607              : 
     608            0 :       CPASSERT(ASSOCIATED(atomic_halos%obj))
     609              :       ! if the arrays are associated, then deallocate and de-associate
     610            0 :       IF (ASSOCIATED(atomic_halos%obj%halos)) THEN
     611            0 :          DO ii = 1, SIZE(atomic_halos%obj%halos)
     612            0 :             CALL fb_atomic_halo_release(atomic_halos%obj%halos(ii))
     613              :          END DO
     614            0 :          DEALLOCATE (atomic_halos%obj%halos)
     615              :       END IF
     616            0 :       atomic_halos%obj%nhalos = 0
     617            0 :       atomic_halos%obj%max_nhalos = 0
     618            0 :    END SUBROUTINE fb_atomic_halo_list_init
     619              : 
     620              : ! **************************************************************************************************
     621              : !> \brief Gets attributes from an fb_atomic_halo_list object, one should
     622              : !>        only access the data content in a fb_atomic_halo_list outside
     623              : !>        this module via this procedure.
     624              : !> \param atomic_halos the fb_atomic_halo object, its content must
     625              : !>                      not be NULL or UNDEFINED
     626              : !> \param nhalos [OPTIONAL]: if present, gives nhalos = atomic_halos%obj%nhalos
     627              : !> \param max_nhalos [OPTIONAL]: if present, gives max_nhalos = atomic_halos%obj%max_nhalos
     628              : !> \param halos [OPTIONAL]: if present, gives halos => atomic_halos%obj%halos
     629              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     630              : ! **************************************************************************************************
     631          138 :    SUBROUTINE fb_atomic_halo_list_get(atomic_halos, nhalos, max_nhalos, halos)
     632              :       TYPE(fb_atomic_halo_list_obj), INTENT(IN)          :: atomic_halos
     633              :       INTEGER, INTENT(OUT), OPTIONAL                     :: nhalos, max_nhalos
     634              :       TYPE(fb_atomic_halo_obj), DIMENSION(:), OPTIONAL, &
     635              :          POINTER                                         :: halos
     636              : 
     637          138 :       CPASSERT(ASSOCIATED(atomic_halos%obj))
     638          138 :       IF (PRESENT(nhalos)) nhalos = atomic_halos%obj%nhalos
     639          138 :       IF (PRESENT(max_nhalos)) max_nhalos = atomic_halos%obj%max_nhalos
     640          138 :       IF (PRESENT(halos)) halos => atomic_halos%obj%halos
     641          138 :    END SUBROUTINE fb_atomic_halo_list_get
     642              : 
     643              : ! **************************************************************************************************
     644              : !> \brief Sets attributes from an fb_atomic_halo_list object, one should
     645              : !>        only set the data content in a fb_atomic_halo_list outside
     646              : !>        this module via this procedure.
     647              : !> \param atomic_halos the fb_atomic_halo object, its content must
     648              : !>                      not be NULL or UNDEFINED
     649              : !> \param nhalos [OPTIONAL]: if present, sets atomic_halos%obj%nhalos = nhalos
     650              : !> \param max_nhalos [OPTIONAL]: if present, sets atomic_halos%obj%max_nhalos = max_nhalos
     651              : !> \param halos [OPTIONAL]: if present, reallocates atomic_halos%obj%halos
     652              : !>                          to the size of halos
     653              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     654              : ! **************************************************************************************************
     655           20 :    SUBROUTINE fb_atomic_halo_list_set(atomic_halos, nhalos, max_nhalos, halos)
     656              :       TYPE(fb_atomic_halo_list_obj), INTENT(INOUT)       :: atomic_halos
     657              :       INTEGER, INTENT(IN), OPTIONAL                      :: nhalos, max_nhalos
     658              :       TYPE(fb_atomic_halo_obj), DIMENSION(:), OPTIONAL, &
     659              :          POINTER                                         :: halos
     660              : 
     661              :       INTEGER                                            :: ihalo
     662              : 
     663           20 :       CPASSERT(ASSOCIATED(atomic_halos%obj))
     664           20 :       IF (PRESENT(nhalos)) atomic_halos%obj%nhalos = nhalos
     665           20 :       IF (PRESENT(max_nhalos)) atomic_halos%obj%max_nhalos = max_nhalos
     666           20 :       IF (PRESENT(halos)) THEN
     667           10 :          IF (ASSOCIATED(atomic_halos%obj%halos)) THEN
     668            0 :             DO ihalo = 1, SIZE(atomic_halos%obj%halos)
     669            0 :                CALL fb_atomic_halo_release(atomic_halos%obj%halos(ihalo))
     670              :             END DO
     671            0 :             DEALLOCATE (atomic_halos%obj%halos)
     672              :          END IF
     673           10 :          atomic_halos%obj%halos => halos
     674              :       END IF
     675           20 :    END SUBROUTINE fb_atomic_halo_list_set
     676              : 
     677              : ! **************************************************************************************************
     678              : !> \brief Writes out the atomic halo list from an fb_atomic_halo_list
     679              : !>        object using information
     680              : !> \param atomic_halos the fb_atomic_halo object
     681              : !> \param para_env pointer to a para_env_type object containing MPI info
     682              : !> \param fb_section pointer to the input section to filtered basis method
     683              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     684              : ! **************************************************************************************************
     685            0 :    SUBROUTINE fb_atomic_halo_list_write(atomic_halos, para_env, fb_section)
     686              :       TYPE(fb_atomic_halo_list_obj), INTENT(IN)          :: atomic_halos
     687              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     688              :       TYPE(section_vals_type), POINTER                   :: fb_section
     689              : 
     690              :       CHARACTER(LEN=default_string_length)               :: string
     691              :       INTEGER                                            :: ihalo, jatom, mype, nhalo_atoms, nhalos, &
     692              :                                                             owner_atom, print_unit
     693            0 :       INTEGER, DIMENSION(:), POINTER                     :: halo_atoms
     694              :       LOGICAL                                            :: new_file
     695              :       TYPE(cp_logger_type), POINTER                      :: logger
     696            0 :       TYPE(fb_atomic_halo_obj), DIMENSION(:), POINTER    :: halos
     697              : 
     698            0 :       NULLIFY (logger)
     699            0 :       logger => cp_get_default_logger()
     700              : 
     701            0 :       IF (BTEST(cp_print_key_should_output(logger%iter_info, fb_section, &
     702              :                                            "PRINT%ATOMIC_HALOS"), &
     703              :                 cp_p_file)) THEN
     704              :          print_unit = cp_print_key_unit_nr(logger=logger, &
     705              :                                            basis_section=fb_section, &
     706              :                                            print_key_path="PRINT%ATOMIC_HALOS", &
     707              :                                            extension=".out", &
     708              :                                            local=.TRUE., &
     709              :                                            log_filename=.FALSE., &
     710              :                                            file_position="REWIND", &
     711              :                                            file_action="WRITE", &
     712            0 :                                            is_new_file=new_file)
     713            0 :          mype = para_env%mepos
     714              :          ! print headline
     715            0 :          string = ""
     716              :          WRITE (UNIT=string, FMT="(A,I5,A)") &
     717            0 :             "ATOMIC HALOS IN (PROCESS ", mype, ")"
     718            0 :          CALL compress(string)
     719            0 :          IF (print_unit > 0) THEN
     720            0 :             WRITE (UNIT=print_unit, FMT="(/,/,T2,A)") TRIM(string)
     721              :             WRITE (UNIT=print_unit, FMT="(/,T2,A)") &
     722            0 :                "atom : list of atoms in the atomic halo"
     723              :          END IF
     724              :          ! print content
     725              :          CALL fb_atomic_halo_list_get(atomic_halos=atomic_halos, &
     726              :                                       nhalos=nhalos, &
     727            0 :                                       halos=halos)
     728            0 :          DO ihalo = 1, nhalos
     729              :             CALL fb_atomic_halo_get(halos(ihalo), &
     730              :                                     owner_atom=owner_atom, &
     731              :                                     natoms=nhalo_atoms, &
     732            0 :                                     halo_atoms=halo_atoms)
     733              :             WRITE (UNIT=print_unit, FMT="(2X,I6,A)", ADVANCE="no") &
     734            0 :                owner_atom, " : "
     735            0 :             DO jatom = 1, nhalo_atoms
     736              :                WRITE (UNIT=print_unit, FMT="(I6)", ADVANCE="no") &
     737            0 :                   halo_atoms(jatom)
     738              :             END DO
     739            0 :             WRITE (UNIT=print_unit) ""
     740              :          END DO
     741              :          ! finish
     742              :          CALL cp_print_key_finished_output(print_unit, logger, fb_section, &
     743            0 :                                            "PRINT%ATOMIC_HALOS")
     744              :       END IF
     745            0 :    END SUBROUTINE fb_atomic_halo_list_write
     746              : 
     747              : ! **************************************************************************************************
     748              : !> \brief Writes out the atomic halo list summary, no detailed neighbour lists,
     749              : !>        just average, min and max number of halo atoms in the halo list
     750              : !> \param atomic_halos : the fb_atomic_halo object
     751              : !> \param para_env     : pointer to a para_env_type object containing MPI info
     752              : !> \param scf_section  : pointer to the scf input section
     753              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     754              : ! **************************************************************************************************
     755           20 :    SUBROUTINE fb_atomic_halo_list_write_info(atomic_halos, para_env, scf_section)
     756              :       TYPE(fb_atomic_halo_list_obj), INTENT(IN)          :: atomic_halos
     757              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     758              :       TYPE(section_vals_type), POINTER                   :: scf_section
     759              : 
     760              :       INTEGER                                            :: ihalo, max_natoms, min_natoms, &
     761              :                                                             nhalo_atoms, nhalos, &
     762              :                                                             total_n_halo_atoms, total_n_halos, &
     763              :                                                             unit_nr
     764              :       REAL(KIND=dp)                                      :: ave_natoms
     765              :       TYPE(cp_logger_type), POINTER                      :: logger
     766           10 :       TYPE(fb_atomic_halo_obj), DIMENSION(:), POINTER    :: halos
     767              : 
     768           10 :       NULLIFY (logger, halos)
     769           20 :       logger => cp_get_default_logger()
     770              :       unit_nr = cp_print_key_unit_nr(logger, scf_section, &
     771              :                                      "PRINT%FILTER_MATRIX", &
     772           10 :                                      extension="")
     773              : 
     774              :       ! obtain data
     775              :       CALL fb_atomic_halo_list_get(atomic_halos=atomic_halos, &
     776              :                                    halos=halos, &
     777           10 :                                    nhalos=nhalos)
     778           10 :       max_natoms = 0
     779           10 :       min_natoms = HUGE(0)
     780           10 :       total_n_halo_atoms = 0
     781           10 :       total_n_halos = nhalos
     782           50 :       DO ihalo = 1, nhalos
     783              :          CALL fb_atomic_halo_get(atomic_halo=halos(ihalo), &
     784           40 :                                  natoms=nhalo_atoms)
     785           40 :          total_n_halo_atoms = total_n_halo_atoms + nhalo_atoms
     786           40 :          max_natoms = MAX(max_natoms, nhalo_atoms)
     787           50 :          min_natoms = MIN(min_natoms, nhalo_atoms)
     788              :       END DO
     789           10 :       CALL para_env%max(max_natoms)
     790           10 :       CALL para_env%min(min_natoms)
     791           10 :       CALL para_env%sum(total_n_halos)
     792           10 :       CALL para_env%sum(total_n_halo_atoms)
     793           10 :       ave_natoms = REAL(total_n_halo_atoms, dp)/REAL(total_n_halos, dp)
     794              :       ! write info
     795           10 :       IF (unit_nr > 0) THEN
     796              :          WRITE (UNIT=unit_nr, FMT="(/,A)") &
     797            5 :             " FILTER_MAT_DIAG| Atomic matrix neighbor lists information:"
     798              :          WRITE (UNIT=unit_nr, FMT="(A,I10)") &
     799            5 :             " FILTER_MAT_DIAG|   Number of atomic matrices: ", &
     800           10 :             total_n_halos
     801              :          WRITE (UNIT=unit_nr, &
     802              :                 FMT="(A,T45,A,T57,A,T69,A,T81,A)") &
     803            5 :             " FILTER_MAT_DIAG| ", "Average", "Max", "Min"
     804              :          WRITE (UNIT=unit_nr, &
     805              :                 FMT="(A,T45,F10.1,T57,I10,T69,I10,T81,I10)") &
     806            5 :             " FILTER_MAT_DIAG|   N neighbors per atom:", &
     807           10 :             ave_natoms, max_natoms, min_natoms
     808              :       END IF
     809              :       ! finish
     810              :       CALL cp_print_key_finished_output(unit_nr, logger, scf_section, &
     811           10 :                                         "PRINT%FILTER_MATRIX")
     812           10 :    END SUBROUTINE fb_atomic_halo_list_write_info
     813              : 
     814              : ! **************************************************************************************************
     815              : !> \brief Builds the required pair_radii array required for building the
     816              : !>        halo atoms from a given set of cut off radii
     817              : !> \param rcut   : rcut(ikind) is the cutoff radii for determining the halo
     818              : !>                 corresponding to atomic kind ikind
     819              : !> \param nkinds : total number of atomic kinds in rcut
     820              : !> \param pair_radii : output array pair_radii(ikind,jkind) gives the
     821              : !>                     corresponding interaction range between a pair of atoms
     822              : !>                     of kinds ikind and jkind
     823              : !> \author Lianheng Tong (LT) lianheng.tong@kcl.ac.uk
     824              : ! **************************************************************************************************
     825           20 :    PURE SUBROUTINE fb_build_pair_radii(rcut, nkinds, pair_radii)
     826              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: rcut
     827              :       INTEGER, INTENT(IN)                                :: nkinds
     828              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(OUT)        :: pair_radii
     829              : 
     830              :       INTEGER                                            :: ii, jj
     831              : 
     832           60 :       pair_radii = 0.0_dp
     833           40 :       DO ii = 1, nkinds
     834           60 :          DO jj = 1, nkinds
     835           40 :             pair_radii(ii, jj) = rcut(ii) + rcut(jj)
     836              :          END DO
     837              :       END DO
     838           20 :    END SUBROUTINE fb_build_pair_radii
     839              : 
     840            0 : END MODULE qs_fb_atomic_halo_types
        

Generated by: LCOV version 2.0-1