LCOV - code coverage report
Current view: top level - src - qs_fb_atomic_halo_types.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:4dc10b3) Lines: 188 233 80.7 %
Date: 2024-11-21 06:45:46 Functions: 20 28 71.4 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : 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 1.15