LCOV - code coverage report
Current view: top level - src - manybody_eam.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:262480d) Lines: 101 101 100.0 %
Date: 2024-11-22 07:00:40 Functions: 3 3 100.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \par History
      10             : !>      EAM potential
      11             : !> \author CJM, I-Feng W. Kuo, Teodoro Laino
      12             : ! **************************************************************************************************
      13             : MODULE manybody_eam
      14             : 
      15             :    USE bibliography,                    ONLY: Foiles1986,&
      16             :                                               cite_reference
      17             :    USE cell_types,                      ONLY: cell_type
      18             :    USE fist_neighbor_list_types,        ONLY: fist_neighbor_type,&
      19             :                                               neighbor_kind_pairs_type
      20             :    USE fist_nonbond_env_types,          ONLY: eam_type,&
      21             :                                               fist_nonbond_env_get,&
      22             :                                               fist_nonbond_env_set,&
      23             :                                               fist_nonbond_env_type,&
      24             :                                               pos_type
      25             :    USE kinds,                           ONLY: dp
      26             :    USE message_passing,                 ONLY: mp_para_env_type
      27             :    USE pair_potential_types,            ONLY: ea_type,&
      28             :                                               eam_pot_type,&
      29             :                                               pair_potential_pp_type
      30             :    USE particle_types,                  ONLY: particle_type
      31             : #include "./base/base_uses.f90"
      32             : 
      33             :    IMPLICIT NONE
      34             : 
      35             :    PRIVATE
      36             :    PUBLIC :: get_force_eam, density_nonbond
      37             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'manybody_eam'
      38             : 
      39             : CONTAINS
      40             : 
      41             : ! **************************************************************************************************
      42             : !> \brief ...
      43             : !> \param fist_nonbond_env ...
      44             : !> \param particle_set ...
      45             : !> \param cell ...
      46             : !> \param para_env ...
      47             : !> \author CJM
      48             : ! **************************************************************************************************
      49       80931 :    SUBROUTINE density_nonbond(fist_nonbond_env, particle_set, cell, para_env)
      50             :       TYPE(fist_nonbond_env_type), POINTER               :: fist_nonbond_env
      51             :       TYPE(particle_type), DIMENSION(:), INTENT(INOUT)   :: particle_set
      52             :       TYPE(cell_type), POINTER                           :: cell
      53             :       TYPE(mp_para_env_type), POINTER                    :: para_env
      54             : 
      55             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'density_nonbond'
      56             : 
      57             :       INTEGER                                            :: atom_a, atom_b, handle, i, i_a, i_b, &
      58             :                                                             iend, igrp, ikind, ilist, ipair, &
      59             :                                                             iparticle, istart, jkind, kind_a, &
      60             :                                                             kind_b, nkinds, nparticle
      61       80931 :       INTEGER, ALLOCATABLE, DIMENSION(:, :)              :: eam_kinds_index
      62             :       LOGICAL                                            :: do_eam
      63             :       REAL(KIND=dp)                                      :: fac, rab2, rab2_max
      64             :       REAL(KIND=dp), DIMENSION(3)                        :: cell_v, rab
      65       80931 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: rho
      66             :       TYPE(eam_pot_type), POINTER                        :: eam_a, eam_b
      67       80931 :       TYPE(eam_type), DIMENSION(:), POINTER              :: eam_data
      68             :       TYPE(fist_neighbor_type), POINTER                  :: nonbonded
      69             :       TYPE(neighbor_kind_pairs_type), POINTER            :: neighbor_kind_pair
      70             :       TYPE(pair_potential_pp_type), POINTER              :: potparm
      71       80931 :       TYPE(pos_type), DIMENSION(:), POINTER              :: r_last_update, r_last_update_pbc
      72             : 
      73       80931 :       CALL timeset(routineN, handle)
      74       80931 :       do_eam = .FALSE.
      75             :       CALL fist_nonbond_env_get(fist_nonbond_env, nonbonded=nonbonded, &
      76             :                                 potparm=potparm, r_last_update=r_last_update, &
      77       80931 :                                 r_last_update_pbc=r_last_update_pbc, eam_data=eam_data)
      78       80931 :       nkinds = SIZE(potparm%pot, 1)
      79      323724 :       ALLOCATE (eam_kinds_index(nkinds, nkinds))
      80     3026325 :       eam_kinds_index = -1
      81      312192 :       DO ikind = 1, nkinds
      82     1784889 :          DO jkind = ikind, nkinds
      83     3176703 :             DO i = 1, SIZE(potparm%pot(ikind, jkind)%pot%type)
      84     2945442 :                IF (potparm%pot(ikind, jkind)%pot%type(i) == ea_type) THEN
      85             :                   ! At the moment we allow only 1 EAM per each kinds pair..
      86         692 :                   CPASSERT(eam_kinds_index(ikind, jkind) == -1)
      87         692 :                   CPASSERT(eam_kinds_index(jkind, ikind) == -1)
      88         692 :                   eam_kinds_index(ikind, jkind) = i
      89         692 :                   eam_kinds_index(jkind, ikind) = i
      90         692 :                   do_eam = .TRUE.
      91             :                END IF
      92             :             END DO
      93             :          END DO
      94             :       END DO
      95             : 
      96       80931 :       nparticle = SIZE(particle_set)
      97             : 
      98       80931 :       IF (do_eam) THEN
      99         284 :          IF (.NOT. ASSOCIATED(eam_data)) THEN
     100         246 :             ALLOCATE (eam_data(nparticle))
     101          12 :             CALL fist_nonbond_env_set(fist_nonbond_env, eam_data=eam_data)
     102             :          END IF
     103        7586 :          DO i = 1, nparticle
     104        7302 :             eam_data(i)%rho = 0.0_dp
     105        7586 :             eam_data(i)%f_embed = 0.0_dp
     106             :          END DO
     107             :       END IF
     108             : 
     109             :       ! Only if EAM potential are present
     110             :       IF (do_eam) THEN
     111             :          ! Add citation
     112         284 :          CALL cite_reference(Foiles1986)
     113         284 :          NULLIFY (eam_a, eam_b)
     114         852 :          ALLOCATE (rho(nparticle))
     115        7586 :          rho = 0._dp
     116             :          ! Starting the force loop
     117       46056 :          DO ilist = 1, nonbonded%nlists
     118       45772 :             neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
     119       45772 :             IF (neighbor_kind_pair%npairs == 0) CYCLE
     120       21866 :             Kind_Group_Loop: DO igrp = 1, neighbor_kind_pair%ngrp_kind
     121       13581 :                istart = neighbor_kind_pair%grp_kind_start(igrp)
     122       13581 :                iend = neighbor_kind_pair%grp_kind_end(igrp)
     123       13581 :                ikind = neighbor_kind_pair%ij_kind(1, igrp)
     124       13581 :                jkind = neighbor_kind_pair%ij_kind(2, igrp)
     125             : 
     126       13581 :                i = eam_kinds_index(ikind, jkind)
     127       13581 :                IF (i == -1) CYCLE
     128       13535 :                rab2_max = potparm%pot(ikind, jkind)%pot%rcutsq
     129      216560 :                cell_v = MATMUL(cell%hmat, REAL(neighbor_kind_pair%cell_vector, KIND=dp))
     130      217208 :                DO ipair = istart, iend
     131      157901 :                   atom_a = neighbor_kind_pair%list(1, ipair)
     132      157901 :                   atom_b = neighbor_kind_pair%list(2, ipair)
     133      157901 :                   fac = 1.0_dp
     134      157901 :                   IF (atom_a == atom_b) fac = 0.5_dp
     135      631604 :                   rab = r_last_update_pbc(atom_b)%r - r_last_update_pbc(atom_a)%r
     136      631604 :                   rab = rab + cell_v
     137      157901 :                   rab2 = rab(1)*rab(1) + rab(2)*rab(2) + rab(3)*rab(3)
     138      171436 :                   IF (rab2 <= rab2_max) THEN
     139       97493 :                      kind_a = particle_set(atom_a)%atomic_kind%kind_number
     140       97493 :                      kind_b = particle_set(atom_b)%atomic_kind%kind_number
     141       97493 :                      i_a = eam_kinds_index(kind_a, kind_a)
     142       97493 :                      i_b = eam_kinds_index(kind_b, kind_b)
     143       97493 :                      eam_a => potparm%pot(kind_a, kind_a)%pot%set(i_a)%eam
     144       97493 :                      eam_b => potparm%pot(kind_b, kind_b)%pot%set(i_b)%eam
     145       97493 :                      CALL get_rho_eam(eam_a, eam_b, rab2, atom_a, atom_b, rho, fac)
     146             :                   END IF
     147             :                END DO
     148             :             END DO Kind_Group_Loop
     149             :          END DO
     150       14888 :          CALL para_env%sum(rho)
     151        7586 :          DO iparticle = 1, nparticle
     152        7586 :             eam_data(iparticle)%rho = rho(iparticle)
     153             :          END DO
     154             : 
     155         284 :          DEALLOCATE (rho)
     156             :       END IF
     157       80931 :       DEALLOCATE (eam_kinds_index)
     158       80931 :       CALL timestop(handle)
     159             : 
     160       80931 :    END SUBROUTINE density_nonbond
     161             : 
     162             : ! **************************************************************************************************
     163             : !> \brief ...
     164             : !> \param eam_a ...
     165             : !> \param eam_b ...
     166             : !> \param rab2 ...
     167             : !> \param atom_a ...
     168             : !> \param atom_b ...
     169             : !> \param rho ...
     170             : !> \param fac ...
     171             : !> \author CJM
     172             : ! **************************************************************************************************
     173       97493 :    SUBROUTINE get_rho_eam(eam_a, eam_b, rab2, atom_a, atom_b, rho, fac)
     174             :       TYPE(eam_pot_type), POINTER                        :: eam_a, eam_b
     175             :       REAL(dp), INTENT(IN)                               :: rab2
     176             :       INTEGER, INTENT(IN)                                :: atom_a, atom_b
     177             :       REAL(dp), INTENT(INOUT)                            :: rho(:)
     178             :       REAL(dp), INTENT(IN)                               :: fac
     179             : 
     180             :       INTEGER                                            :: index
     181             :       REAL(dp)                                           :: qq, rab, rhoi, rhoj
     182             : 
     183       97493 :       rab = SQRT(rab2)
     184             : 
     185             :       ! Particle A
     186       97493 :       index = INT(rab/eam_b%drar) + 1
     187       97493 :       IF (index > eam_b%npoints) THEN
     188             :          index = eam_b%npoints
     189       97492 :       ELSEIF (index < 1) THEN
     190             :          index = 1
     191             :       END IF
     192       97493 :       qq = rab - eam_b%rval(index)
     193       97493 :       rhoi = eam_b%rho(index) + qq*eam_b%rhop(index)
     194             : 
     195             :       ! Particle B
     196       97493 :       index = INT(rab/eam_a%drar) + 1
     197       97493 :       IF (index > eam_a%npoints) THEN
     198             :          index = eam_a%npoints
     199       97492 :       ELSEIF (index < 1) THEN
     200             :          index = 1
     201             :       END IF
     202       97493 :       qq = rab - eam_a%rval(index)
     203       97493 :       rhoj = eam_a%rho(index) + qq*eam_a%rhop(index)
     204             : 
     205       97493 :       rho(atom_a) = rho(atom_a) + rhoi*fac
     206       97493 :       rho(atom_b) = rho(atom_b) + rhoj*fac
     207       97493 :    END SUBROUTINE get_rho_eam
     208             : 
     209             : ! **************************************************************************************************
     210             : !> \brief ...
     211             : !> \param rab2 ...
     212             : !> \param eam_a ...
     213             : !> \param eam_b ...
     214             : !> \param eam_data ...
     215             : !> \param atom_a ...
     216             : !> \param atom_b ...
     217             : !> \param f_eam ...
     218             : !> \author CJM
     219             : ! **************************************************************************************************
     220       97493 :    SUBROUTINE get_force_eam(rab2, eam_a, eam_b, eam_data, atom_a, atom_b, f_eam)
     221             :       REAL(dp), INTENT(IN)                               :: rab2
     222             :       TYPE(eam_pot_type), POINTER                        :: eam_a, eam_b
     223             :       TYPE(eam_type), INTENT(IN)                         :: eam_data(:)
     224             :       INTEGER, INTENT(IN)                                :: atom_a, atom_b
     225             :       REAL(dp), INTENT(OUT)                              :: f_eam
     226             : 
     227             :       INTEGER                                            :: index
     228             :       REAL(KIND=dp)                                      :: denspi, denspj, fcp, qq, rab
     229             : 
     230       97493 :       rab = SQRT(rab2)
     231             : 
     232             :       ! Particle A
     233       97493 :       index = INT(rab/eam_a%drar) + 1
     234       97493 :       IF (index > eam_a%npoints) THEN
     235             :          index = eam_a%npoints
     236       97492 :       ELSEIF (index < 1) THEN
     237             :          index = 1
     238             :       END IF
     239       97493 :       qq = rab - eam_a%rval(index)
     240       97493 :       IF (index == eam_a%npoints) THEN
     241           1 :          denspi = eam_a%rhop(index) + qq*(eam_a%rhop(index) - eam_a%rhop(index - 1))/eam_a%drar
     242             :       ELSE
     243       97492 :          denspi = eam_a%rhop(index) + qq*(eam_a%rhop(index + 1) - eam_a%rhop(index))/eam_a%drar
     244             :       END IF
     245             : 
     246             :       ! Particle B
     247       97493 :       index = INT(rab/eam_b%drar) + 1
     248       97493 :       IF (index > eam_b%npoints) THEN
     249             :          index = eam_b%npoints
     250       97492 :       ELSEIF (index < 1) THEN
     251             :          index = 1
     252             :       END IF
     253       97493 :       qq = rab - eam_b%rval(index)
     254       97493 :       IF (index == eam_b%npoints) THEN
     255           1 :          denspj = eam_b%rhop(index) + qq*(eam_b%rhop(index) - eam_b%rhop(index - 1))/eam_b%drar
     256             :       ELSE
     257       97492 :          denspj = eam_b%rhop(index) + qq*(eam_b%rhop(index + 1) - eam_b%rhop(index))/eam_b%drar
     258             :       END IF
     259             : 
     260       97493 :       fcp = denspj*eam_data(atom_a)%f_embed + denspi*eam_data(atom_b)%f_embed
     261       97493 :       f_eam = fcp/rab
     262       97493 :    END SUBROUTINE get_force_eam
     263             : 
     264             : END MODULE manybody_eam
     265             : 

Generated by: LCOV version 1.15