LCOV - code coverage report
Current view: top level - src - fist_nonbond_force.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:71c3ab0) Lines: 95.7 % 257 246
Test Date: 2026-07-25 06:35:44 Functions: 100.0 % 5 5

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \par History
      10              : !>      JGH (11 May 2001) : cleaning up of support structures
      11              : !>      CJM & HAF (27 July 2001): fixed bug with handling of cutoff larger than
      12              : !>                                half the boxsize.
      13              : !>      07.02.2005: getting rid of scaled_to_real calls in force loop (MK)
      14              : !>      22.06.2013: OpenMP parallelisation of pair interaction loop (MK)
      15              : !> \author CJM
      16              : ! **************************************************************************************************
      17              : MODULE fist_nonbond_force
      18              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      19              :                                               get_atomic_kind,&
      20              :                                               get_atomic_kind_set
      21              :    USE atprop_types,                    ONLY: atprop_type
      22              :    USE cell_types,                      ONLY: cell_type,&
      23              :                                               pbc
      24              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      25              :                                               cp_logger_type
      26              :    USE distribution_1d_types,           ONLY: distribution_1d_type
      27              :    USE ewald_environment_types,         ONLY: ewald_env_get,&
      28              :                                               ewald_environment_type
      29              :    USE fist_neighbor_list_types,        ONLY: fist_neighbor_type,&
      30              :                                               neighbor_kind_pairs_type
      31              :    USE fist_nonbond_env_types,          ONLY: fist_nonbond_env_get,&
      32              :                                               fist_nonbond_env_type,&
      33              :                                               pos_type
      34              :    USE kinds,                           ONLY: dp
      35              :    USE machine,                         ONLY: m_memory
      36              :    USE mathconstants,                   ONLY: oorootpi,&
      37              :                                               sqrthalf
      38              :    USE message_passing,                 ONLY: mp_comm_type
      39              :    USE pair_potential_coulomb,          ONLY: potential_coulomb
      40              :    USE pair_potential_types,            ONLY: &
      41              :         ace_type, allegro_type, deepmd_type, gal21_type, gal_type, mace_type, nequip_type, &
      42              :         nosh_nosh, nosh_sh, pair_potential_pp_type, pair_potential_single_type, sh_sh, &
      43              :         siepmann_type, tersoff_type
      44              :    USE particle_types,                  ONLY: particle_type
      45              :    USE shell_potential_types,           ONLY: get_shell,&
      46              :                                               shell_kind_type
      47              :    USE splines_methods,                 ONLY: potential_s
      48              :    USE splines_types,                   ONLY: spline_data_p_type,&
      49              :                                               spline_factor_type
      50              : #include "./base/base_uses.f90"
      51              : 
      52              :    IMPLICIT NONE
      53              : 
      54              :    PRIVATE
      55              : 
      56              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'fist_nonbond_force'
      57              :    LOGICAL, PARAMETER, PRIVATE :: debug_this_module = .FALSE.
      58              : 
      59              :    PUBLIC :: force_nonbond, &
      60              :              bonded_correct_gaussian
      61              : 
      62              : CONTAINS
      63              : 
      64              : ! **************************************************************************************************
      65              : !> \brief Calculates the force and the potential of the minimum image, and
      66              : !>      the pressure tensor
      67              : !> \param fist_nonbond_env ...
      68              : !> \param ewald_env ...
      69              : !> \param particle_set ...
      70              : !> \param cell ...
      71              : !> \param pot_nonbond ...
      72              : !> \param f_nonbond ...
      73              : !> \param pv_nonbond ...
      74              : !> \param fshell_nonbond ...
      75              : !> \param fcore_nonbond ...
      76              : !> \param atprop_env ...
      77              : !> \param atomic_kind_set ...
      78              : !> \param use_virial ...
      79              : ! **************************************************************************************************
      80        77140 :    SUBROUTINE force_nonbond(fist_nonbond_env, ewald_env, particle_set, cell, &
      81        77140 :                             pot_nonbond, f_nonbond, pv_nonbond, fshell_nonbond, fcore_nonbond, &
      82              :                             atprop_env, atomic_kind_set, use_virial)
      83              : 
      84              :       TYPE(fist_nonbond_env_type), POINTER               :: fist_nonbond_env
      85              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
      86              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
      87              :       TYPE(cell_type), POINTER                           :: cell
      88              :       REAL(KIND=dp), INTENT(OUT)                         :: pot_nonbond
      89              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: f_nonbond, pv_nonbond
      90              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(OUT), &
      91              :          OPTIONAL                                        :: fshell_nonbond, fcore_nonbond
      92              :       TYPE(atprop_type), POINTER                         :: atprop_env
      93              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind_set(:)
      94              :       LOGICAL, INTENT(IN)                                :: use_virial
      95              : 
      96              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'force_nonbond'
      97              : 
      98              :       INTEGER :: atom_a, atom_b, ewald_type, handle, i, iend, igrp, ikind, ilist, ipair, istart, &
      99              :          j, kind_a, kind_b, nkind, npairs, shell_a, shell_b, shell_type
     100        77140 :       INTEGER, DIMENSION(:, :), POINTER                  :: list
     101              :       LOGICAL                                            :: all_terms, do_multipoles, full_nl, &
     102              :                                                             shell_present
     103        77140 :       LOGICAL, ALLOCATABLE, DIMENSION(:)                 :: is_shell_kind
     104              :       REAL(KIND=dp) :: alpha, beta, beta_a, beta_b, energy, etot, fac_ei, fac_kind, fac_vdw, &
     105              :          fscalar, mm_radius_a, mm_radius_b, qcore_a, qcore_b, qeff_a, qeff_b, qshell_a, qshell_b, &
     106              :          rab2, rab2_com, rab2_max
     107        77140 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: mm_radius, qcore, qeff, qshell
     108              :       REAL(KIND=dp), DIMENSION(3)                        :: cell_v, cvi, fatom_a, fatom_b, fcore_a, &
     109              :                                                             fcore_b, fshell_a, fshell_b, rab, &
     110              :                                                             rab_cc, rab_com, rab_cs, rab_sc, rab_ss
     111              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: pv, pv_thread
     112              :       REAL(KIND=dp), DIMENSION(3, 4)                     :: rab_list
     113              :       REAL(KIND=dp), DIMENSION(4)                        :: rab2_list
     114        77140 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: ij_kind_full_fac
     115        77140 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: ei_interaction_cutoffs
     116              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
     117              :       TYPE(cp_logger_type), POINTER                      :: logger
     118              :       TYPE(fist_neighbor_type), POINTER                  :: nonbonded
     119              :       TYPE(neighbor_kind_pairs_type), POINTER            :: neighbor_kind_pair
     120              :       TYPE(pair_potential_pp_type), POINTER              :: potparm, potparm14
     121              :       TYPE(pair_potential_single_type), POINTER          :: pot
     122        77140 :       TYPE(pos_type), DIMENSION(:), POINTER              :: r_last_update, r_last_update_pbc, &
     123        77140 :                                                             rcore_last_update_pbc, &
     124        77140 :                                                             rshell_last_update_pbc
     125              :       TYPE(shell_kind_type), POINTER                     :: shell_kind
     126        77140 :       TYPE(spline_data_p_type), DIMENSION(:), POINTER    :: spline_data
     127              :       TYPE(spline_factor_type), POINTER                  :: spl_f
     128              : 
     129        77140 :       CALL timeset(routineN, handle)
     130        77140 :       NULLIFY (logger)
     131        77140 :       logger => cp_get_default_logger()
     132        77140 :       NULLIFY (pot, rshell_last_update_pbc, spl_f, ij_kind_full_fac)
     133              :       CALL fist_nonbond_env_get(fist_nonbond_env, nonbonded=nonbonded, &
     134              :                                 potparm14=potparm14, potparm=potparm, r_last_update=r_last_update, &
     135              :                                 r_last_update_pbc=r_last_update_pbc, natom_types=nkind, &
     136              :                                 rshell_last_update_pbc=rshell_last_update_pbc, &
     137              :                                 rcore_last_update_pbc=rcore_last_update_pbc, &
     138        77140 :                                 ij_kind_full_fac=ij_kind_full_fac)
     139              :       CALL ewald_env_get(ewald_env, alpha=alpha, ewald_type=ewald_type, &
     140              :                          do_multipoles=do_multipoles, &
     141        77140 :                          interaction_cutoffs=ei_interaction_cutoffs)
     142              : 
     143              :       ! Initializing the potential energy, pressure tensor and force
     144        77140 :       pot_nonbond = 0.0_dp
     145     32570732 :       f_nonbond(:, :) = 0.0_dp
     146              : 
     147        77140 :       IF (use_virial) THEN
     148       182962 :          pv_nonbond(:, :) = 0.0_dp
     149              :       END IF
     150        77140 :       shell_present = .FALSE.
     151        77140 :       IF (PRESENT(fshell_nonbond)) THEN
     152        10308 :          CPASSERT(PRESENT(fcore_nonbond))
     153      3076636 :          fshell_nonbond = 0.0_dp
     154      3076636 :          fcore_nonbond = 0.0_dp
     155              :          shell_present = .TRUE.
     156              :       END IF
     157              :       ! Load atomic kind information
     158       231420 :       ALLOCATE (mm_radius(nkind))
     159       154280 :       ALLOCATE (qeff(nkind))
     160       154280 :       ALLOCATE (qcore(nkind))
     161       154280 :       ALLOCATE (qshell(nkind))
     162       231420 :       ALLOCATE (is_shell_kind(nkind))
     163       304504 :       DO ikind = 1, nkind
     164       227364 :          atomic_kind => atomic_kind_set(ikind)
     165              :          CALL get_atomic_kind(atomic_kind, &
     166              :                               qeff=qeff(ikind), &
     167              :                               mm_radius=mm_radius(ikind), &
     168       227364 :                               shell=shell_kind)
     169       227364 :          is_shell_kind(ikind) = ASSOCIATED(shell_kind)
     170       304504 :          IF (ASSOCIATED(shell_kind)) THEN
     171              :             CALL get_shell(shell=shell_kind, &
     172              :                            charge_core=qcore(ikind), &
     173        19012 :                            charge_shell=qshell(ikind))
     174              :          ELSE
     175       208352 :             qcore(ikind) = 0.0_dp
     176       208352 :             qshell(ikind) = 0.0_dp
     177              :          END IF
     178              :       END DO
     179              :       ! Starting the force loop
     180      9307166 :       Lists: DO ilist = 1, nonbonded%nlists
     181      9230026 :          neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
     182      9230026 :          npairs = neighbor_kind_pair%npairs
     183      9230026 :          IF (npairs == 0) CYCLE Lists
     184      2523493 :          list => neighbor_kind_pair%list
     185     10093972 :          cvi = neighbor_kind_pair%cell_vector
     186     32805409 :          cell_v = MATMUL(cell%hmat, cvi)
     187     10899801 :          Kind_Group_Loop: DO igrp = 1, neighbor_kind_pair%ngrp_kind
     188      8299168 :             istart = neighbor_kind_pair%grp_kind_start(igrp)
     189      8299168 :             iend = neighbor_kind_pair%grp_kind_end(igrp)
     190              : !$OMP           PARALLEL DEFAULT(NONE) &
     191              : !$OMP                    PRIVATE(ipair,atom_a,atom_b,kind_a,kind_b,fac_kind,pot) &
     192              : !$OMP                    PRIVATE(fac_ei,fac_vdw,atomic_kind,full_nl,qcore_a,qshell_a) &
     193              : !$OMP                    PRIVATE(qeff_a,qcore_b,qshell_b,qeff_b,mm_radius_a,mm_radius_b) &
     194              : !$OMP                    PRIVATE(shell_kind,beta,beta_a,beta_b,spl_f,spline_data) &
     195              : !$OMP                    PRIVATE(shell_type,all_terms,rab_cc,rab_cs,rab_sc,rab_ss) &
     196              : !$OMP                    PRIVATE(rab_list,rab2_list,rab_com,rab2_com,pv,pv_thread) &
     197              : !$OMP                    PRIVATE(rab,rab2,rab2_max,fscalar,energy) &
     198              : !$OMP                    PRIVATE(shell_a,shell_b,etot,fatom_a,fatom_b) &
     199              : !$OMP                    PRIVATE(fcore_a,fcore_b,fshell_a,fshell_b,i,j) &
     200              : !$OMP                    SHARED(shell_present) &
     201              : !$OMP                    SHARED(istart,iend,list,particle_set,ij_kind_full_fac) &
     202              : !$OMP                    SHARED(neighbor_kind_pair,atomic_kind_set,fist_nonbond_env) &
     203              : !$OMP                    SHARED(potparm,potparm14,do_multipoles,r_last_update_pbc) &
     204              : !$OMP                    SHARED(use_virial,ei_interaction_cutoffs,alpha,cell_v) &
     205              : !$OMP                    SHARED(rcore_last_update_pbc,rshell_last_update_pbc) &
     206              : !$OMP                    SHARED(f_nonbond,fcore_nonbond,fshell_nonbond,logger) &
     207              : !$OMP                    SHARED(ewald_type,pot_nonbond,pv_nonbond,atprop_env) &
     208     17529194 : !$OMP                    SHARED(is_shell_kind,mm_radius,qcore,qeff,qshell)
     209              :             IF (use_virial) pv_thread(:, :) = 0.0_dp
     210              : !$OMP           DO
     211              :             Pairs: DO ipair = istart, iend
     212              :                atom_a = list(1, ipair)
     213              :                atom_b = list(2, ipair)
     214              :                ! Get actual atomic kinds, since atom_a is not always of
     215              :                ! kind_a and atom_b of kind_b, ie. they might be swapped.
     216              :                kind_a = particle_set(atom_a)%atomic_kind%kind_number
     217              :                kind_b = particle_set(atom_b)%atomic_kind%kind_number
     218              : 
     219              :                fac_kind = ij_kind_full_fac(kind_a, kind_b)
     220              :                ! take the proper potential
     221              :                pot => potparm%pot(kind_a, kind_b)%pot
     222              :                IF (ipair <= neighbor_kind_pair%nscale) THEN
     223              :                   IF (neighbor_kind_pair%is_onfo(ipair)) THEN
     224              :                      pot => potparm14%pot(kind_a, kind_b)%pot
     225              :                   END IF
     226              :                END IF
     227              : 
     228              :                ! Determine the scaling factors
     229              :                fac_ei = fac_kind
     230              :                fac_vdw = fac_kind
     231              :                full_nl = ANY(pot%type == tersoff_type) .OR. ANY(pot%type == siepmann_type) &
     232              :                          .OR. ANY(pot%type == gal_type) .OR. ANY(pot%type == gal21_type) &
     233              :                          .OR. ANY(pot%type == nequip_type) .OR. ANY(pot%type == allegro_type) &
     234              :                          .OR. ANY(pot%type == mace_type) &
     235              :                          .OR. ANY(pot%type == ace_type) .OR. ANY(pot%type == deepmd_type)
     236              :                IF ((.NOT. full_nl) .AND. (atom_a == atom_b)) THEN
     237              :                   fac_ei = 0.5_dp*fac_ei
     238              :                   fac_vdw = 0.5_dp*fac_vdw
     239              :                END IF
     240              :                ! decide which interactions to compute\b
     241              :                IF (do_multipoles .OR. (.NOT. fist_nonbond_env%do_electrostatics)) THEN
     242              :                   fac_ei = 0.0_dp
     243              :                END IF
     244              :                IF (ipair <= neighbor_kind_pair%nscale) THEN
     245              :                   fac_ei = fac_ei*neighbor_kind_pair%ei_scale(ipair)
     246              :                   fac_vdw = fac_vdw*neighbor_kind_pair%vdw_scale(ipair)
     247              :                END IF
     248              : 
     249              :                IF (fac_ei > 0.0_dp) THEN
     250              :                   ! Get the electrostatic parameters for the atoms a and b
     251              :                   mm_radius_a = mm_radius(kind_a)
     252              :                   mm_radius_b = mm_radius(kind_b)
     253              :                   IF (ASSOCIATED(fist_nonbond_env%charges)) THEN
     254              :                      qeff_a = fist_nonbond_env%charges(atom_a)
     255              :                      qeff_b = fist_nonbond_env%charges(atom_b)
     256              :                   ELSE
     257              :                      qeff_a = qeff(kind_a)
     258              :                      qeff_b = qeff(kind_b)
     259              :                   END IF
     260              :                   IF (is_shell_kind(kind_a)) THEN
     261              :                      qcore_a = qcore(kind_a)
     262              :                      qshell_a = qshell(kind_a)
     263              :                      IF ((qcore_a == 0.0_dp) .AND. (qshell_a == 0.0_dp)) fac_ei = 0.0_dp
     264              :                   ELSE
     265              :                      qcore_a = qeff_a
     266              :                      qshell_a = HUGE(0.0_dp)
     267              :                      IF (qeff_a == 0.0_dp) fac_ei = 0.0_dp
     268              :                   END IF
     269              :                   IF (is_shell_kind(kind_b)) THEN
     270              :                      qcore_b = qcore(kind_b)
     271              :                      qshell_b = qshell(kind_b)
     272              :                      IF ((qcore_b == 0.0_dp) .AND. (qshell_b == 0.0_dp)) fac_ei = 0.0_dp
     273              :                   ELSE
     274              :                      qcore_b = qeff_b
     275              :                      qshell_b = HUGE(0.0_dp)
     276              :                      IF (qeff_b == 0.0_dp) fac_ei = 0.0_dp
     277              :                   END IF
     278              :                   ! Derive beta parameters
     279              :                   beta = 0.0_dp
     280              :                   beta_a = 0.0_dp
     281              :                   beta_b = 0.0_dp
     282              :                   IF (mm_radius_a > 0) THEN
     283              :                      beta_a = sqrthalf/mm_radius_a
     284              :                   END IF
     285              :                   IF (mm_radius_b > 0) THEN
     286              :                      beta_b = sqrthalf/mm_radius_b
     287              :                   END IF
     288              :                   IF ((mm_radius_a > 0) .OR. (mm_radius_b > 0)) THEN
     289              :                      beta = sqrthalf/SQRT(mm_radius_a*mm_radius_a + mm_radius_b*mm_radius_b)
     290              :                   END IF
     291              :                END IF
     292              : 
     293              :                ! In case we have only manybody potentials and no charges, this
     294              :                ! pair of atom types can be ignored here.
     295              :                IF (pot%no_pp .AND. (fac_ei == 0.0)) CYCLE Pairs
     296              : 
     297              :                ! Setup spline_data set
     298              :                spl_f => pot%spl_f
     299              :                spline_data => pot%pair_spline_data
     300              :                shell_type = pot%shell_type
     301              :                IF (shell_type /= nosh_nosh) THEN
     302              :                   CPASSERT(.NOT. do_multipoles)
     303              :                   CPASSERT(shell_present)
     304              :                END IF
     305              :                rab2_max = pot%rcutsq
     306              : 
     307              :                ! compute the relative vector(s) for this pair
     308              :                IF (shell_type /= nosh_nosh) THEN
     309              :                   ! do shell
     310              :                   all_terms = .TRUE.
     311              :                   IF (shell_type == sh_sh) THEN
     312              :                      shell_a = particle_set(atom_a)%shell_index
     313              :                      shell_b = particle_set(atom_b)%shell_index
     314              :                      rab_cc = rcore_last_update_pbc(shell_b)%r - rcore_last_update_pbc(shell_a)%r
     315              :                      rab_cs = rshell_last_update_pbc(shell_b)%r - rcore_last_update_pbc(shell_a)%r
     316              :                      rab_sc = rcore_last_update_pbc(shell_b)%r - rshell_last_update_pbc(shell_a)%r
     317              :                      rab_ss = rshell_last_update_pbc(shell_b)%r - rshell_last_update_pbc(shell_a)%r
     318              :                      rab_list(1:3, 1) = rab_cc(1:3) + cell_v(1:3)
     319              :                      rab_list(1:3, 2) = rab_cs(1:3) + cell_v(1:3)
     320              :                      rab_list(1:3, 3) = rab_sc(1:3) + cell_v(1:3)
     321              :                      rab_list(1:3, 4) = rab_ss(1:3) + cell_v(1:3)
     322              :                   ELSE IF ((shell_type == nosh_sh) .AND. (particle_set(atom_a)%shell_index /= 0)) THEN
     323              :                      shell_a = particle_set(atom_a)%shell_index
     324              :                      shell_b = 0
     325              :                      rab_cc = r_last_update_pbc(atom_b)%r - rcore_last_update_pbc(shell_a)%r
     326              :                      rab_sc = 0.0_dp
     327              :                      rab_cs = 0.0_dp
     328              :                      rab_ss = r_last_update_pbc(atom_b)%r - rshell_last_update_pbc(shell_a)%r
     329              :                      rab_list(1:3, 1) = rab_cc(1:3) + cell_v(1:3)
     330              :                      rab_list(1:3, 2) = 0.0_dp
     331              :                      rab_list(1:3, 3) = 0.0_dp
     332              :                      rab_list(1:3, 4) = rab_ss(1:3) + cell_v(1:3)
     333              :                   ELSE IF ((shell_type == nosh_sh) .AND. (particle_set(atom_b)%shell_index /= 0)) THEN
     334              :                      shell_b = particle_set(atom_b)%shell_index
     335              :                      shell_a = 0
     336              :                      rab_cc = rcore_last_update_pbc(shell_b)%r - r_last_update_pbc(atom_a)%r
     337              :                      rab_sc = 0.0_dp
     338              :                      rab_cs = 0.0_dp
     339              :                      rab_ss = rshell_last_update_pbc(shell_b)%r - r_last_update_pbc(atom_a)%r
     340              :                      rab_list(1:3, 1) = rab_cc(1:3) + cell_v(1:3)
     341              :                      rab_list(1:3, 2) = 0.0_dp
     342              :                      rab_list(1:3, 3) = 0.0_dp
     343              :                      rab_list(1:3, 4) = rab_ss(1:3) + cell_v(1:3)
     344              :                   ELSE
     345              :                      rab_list(:, :) = 0.0_dp
     346              :                   END IF
     347              :                   ! Compute the term only if all the pairs (cc,cs,sc,ss) are within the cut-off
     348              :                   Check_terms: DO i = 1, 4
     349              :                      rab2_list(i) = rab_list(1, i)**2 + rab_list(2, i)**2 + rab_list(3, i)**2
     350              :                      IF (rab2_list(i) >= rab2_max) THEN
     351              :                         all_terms = .FALSE.
     352              :                         EXIT Check_terms
     353              :                      END IF
     354              :                   END DO Check_terms
     355              :                   rab_com = r_last_update_pbc(atom_b)%r - r_last_update_pbc(atom_a)%r
     356              :                ELSE
     357              :                   ! not do shell
     358              :                   rab_cc = r_last_update_pbc(atom_b)%r - r_last_update_pbc(atom_a)%r
     359              :                   rab_com = rab_cc
     360              :                   shell_a = 0
     361              :                   shell_b = 0
     362              :                   rab_list(:, :) = 0.0_dp
     363              :                END IF
     364              :                rab_com = rab_com + cell_v
     365              :                rab2_com = rab_com(1)**2 + rab_com(2)**2 + rab_com(3)**2
     366              : 
     367              :                ! compute the interactions for the current pair
     368              :                etot = 0.0_dp
     369              :                fatom_a(:) = 0.0_dp
     370              :                fatom_b(:) = 0.0_dp
     371              :                fcore_a(:) = 0.0_dp
     372              :                fcore_b(:) = 0.0_dp
     373              :                fshell_a(:) = 0.0_dp
     374              :                fshell_b(:) = 0.0_dp
     375              :                IF (use_virial) pv(:, :) = 0.0_dp
     376              :                IF (shell_type /= nosh_nosh) THEN
     377              :                   ! do shell
     378              :                   IF ((rab2_com <= rab2_max) .AND. all_terms) THEN
     379              :                      IF (fac_ei > 0) THEN
     380              :                         ! core-core or core-ion/ion-core: Coulomb only
     381              :                         rab = rab_list(:, 1)
     382              :                         rab2 = rab2_list(1)
     383              :                         fscalar = 0.0_dp
     384              :                         IF (shell_a == 0) THEN
     385              :                            ! atom a is a plain ion and can have beta_a > 0
     386              :                            energy = potential_coulomb(rab2, fscalar, fac_ei*qeff_a*qcore_b, &
     387              :                                                       ewald_type, alpha, beta_a, &
     388              :                                                       ei_interaction_cutoffs(2, kind_a, kind_b))
     389              :                            CALL add_force_nonbond(fatom_a, fcore_b, pv, fscalar, rab, use_virial)
     390              :                         ELSE IF (shell_b == 0) THEN
     391              :                            ! atom b is a plain ion and can have beta_b > 0
     392              :                            energy = potential_coulomb(rab2, fscalar, fac_ei*qcore_a*qeff_b, &
     393              :                                                       ewald_type, alpha, beta_b, &
     394              :                                                       ei_interaction_cutoffs(2, kind_b, kind_a))
     395              :                            CALL add_force_nonbond(fcore_a, fatom_b, pv, fscalar, rab, use_virial)
     396              :                         ELSE
     397              :                            ! core-core interaction is always pure point charge
     398              :                            energy = potential_coulomb(rab2, fscalar, fac_ei*qcore_a*qcore_b, &
     399              :                                                       ewald_type, alpha, 0.0_dp, &
     400              :                                                       ei_interaction_cutoffs(1, kind_a, kind_b))
     401              :                            CALL add_force_nonbond(fcore_a, fcore_b, pv, fscalar, rab, use_virial)
     402              :                         END IF
     403              :                         etot = etot + energy
     404              :                      END IF
     405              : 
     406              :                      IF (shell_type == sh_sh) THEN
     407              :                         ! shell-shell: VDW + Coulomb
     408              :                         rab = rab_list(:, 4)
     409              :                         rab2 = rab2_list(4)
     410              :                         fscalar = 0.0_dp
     411              :                         IF (fac_vdw > 0) THEN
     412              :                            energy = potential_s(spline_data, rab2, fscalar, spl_f, logger)
     413              :                            etot = etot + energy*fac_vdw
     414              :                            fscalar = fscalar*fac_vdw
     415              :                         END IF
     416              :                         IF (fac_ei > 0) THEN
     417              :                            ! note that potential_coulomb increments fscalar
     418              :                            energy = potential_coulomb(rab2, fscalar, fac_ei*qshell_a*qshell_b, &
     419              :                                                       ewald_type, alpha, beta, &
     420              :                                                       ei_interaction_cutoffs(3, kind_a, kind_b))
     421              :                            etot = etot + energy
     422              :                         END IF
     423              :                         CALL add_force_nonbond(fshell_a, fshell_b, pv, fscalar, rab, use_virial)
     424              : 
     425              :                         IF (fac_ei > 0) THEN
     426              :                            ! core-shell: Coulomb only
     427              :                            rab = rab_list(:, 2)
     428              :                            rab2 = rab2_list(2)
     429              :                            fscalar = 0.0_dp
     430              :                            ! swap kind_a and kind_b to get the right cutoff
     431              :                            energy = potential_coulomb(rab2, fscalar, fac_ei*qcore_a*qshell_b, &
     432              :                                                       ewald_type, alpha, beta_b, &
     433              :                                                       ei_interaction_cutoffs(2, kind_b, kind_a))
     434              :                            etot = etot + energy
     435              :                            CALL add_force_nonbond(fcore_a, fshell_b, pv, fscalar, rab, use_virial)
     436              : 
     437              :                            ! shell-core: Coulomb only
     438              :                            rab = rab_list(:, 3)
     439              :                            rab2 = rab2_list(3)
     440              :                            fscalar = 0.0_dp
     441              :                            energy = potential_coulomb(rab2, fscalar, fac_ei*qshell_a*qcore_b, &
     442              :                                                       ewald_type, alpha, beta_a, &
     443              :                                                       ei_interaction_cutoffs(2, kind_a, kind_b))
     444              :                            etot = etot + energy
     445              :                            CALL add_force_nonbond(fshell_a, fcore_b, pv, fscalar, rab, use_virial)
     446              :                         END IF
     447              :                      ELSE IF ((shell_type == nosh_sh) .AND. (shell_a == 0)) THEN
     448              :                         ! ion-shell: VDW + Coulomb
     449              :                         rab = rab_list(:, 4)
     450              :                         rab2 = rab2_list(4)
     451              :                         fscalar = 0.0_dp
     452              :                         IF (fac_vdw > 0) THEN
     453              :                            energy = potential_s(spline_data, rab2, fscalar, spl_f, logger)
     454              :                            etot = etot + energy*fac_vdw
     455              :                            fscalar = fscalar*fac_vdw
     456              :                         END IF
     457              :                         IF (fac_ei > 0) THEN
     458              :                            ! note that potential_coulomb increments fscalar
     459              :                            energy = potential_coulomb(rab2, fscalar, fac_ei*qeff_a*qshell_b, &
     460              :                                                       ewald_type, alpha, beta, &
     461              :                                                       ei_interaction_cutoffs(3, kind_a, kind_b))
     462              :                            etot = etot + energy
     463              :                         END IF
     464              :                         CALL add_force_nonbond(fatom_a, fshell_b, pv, fscalar, rab, use_virial)
     465              :                      ELSE IF ((shell_type == nosh_sh) .AND. (shell_b == 0)) THEN
     466              :                         ! shell-ion : VDW + Coulomb
     467              :                         rab = rab_list(:, 4)
     468              :                         rab2 = rab2_list(4)
     469              :                         fscalar = 0.0_dp
     470              :                         IF (fac_vdw > 0) THEN
     471              :                            energy = potential_s(spline_data, rab2, fscalar, spl_f, logger)
     472              :                            etot = etot + energy*fac_vdw
     473              :                            fscalar = fscalar*fac_vdw
     474              :                         END IF
     475              :                         IF (fac_ei > 0) THEN
     476              :                            ! note that potential_coulomb increments fscalar
     477              :                            energy = potential_coulomb(rab2, fscalar, fac_ei*qshell_a*qeff_b, &
     478              :                                                       ewald_type, alpha, beta, &
     479              :                                                       ei_interaction_cutoffs(3, kind_a, kind_b))
     480              :                            etot = etot + energy
     481              :                         END IF
     482              :                         CALL add_force_nonbond(fshell_a, fatom_b, pv, fscalar, rab, use_virial)
     483              :                      END IF
     484              :                   END IF
     485              :                ELSE
     486              :                   IF (rab2_com <= rab2_max) THEN
     487              :                      ! NO SHELL MODEL...
     488              :                      ! Ion-Ion: no shell model, VDW + coulomb
     489              :                      rab = rab_com
     490              :                      rab2 = rab2_com
     491              :                      fscalar = 0.0_dp
     492              :                      IF (fac_vdw > 0) THEN
     493              :                         energy = potential_s(spline_data, rab2, fscalar, spl_f, logger)
     494              :                         etot = etot + energy*fac_vdw
     495              :                         fscalar = fscalar*fac_vdw
     496              :                      END IF
     497              :                      IF (fac_ei > 0) THEN
     498              :                         ! note that potential_coulomb increments fscalar
     499              :                         energy = potential_coulomb(rab2, fscalar, fac_ei*qeff_a*qeff_b, &
     500              :                                                    ewald_type, alpha, beta, &
     501              :                                                    ei_interaction_cutoffs(3, kind_a, kind_b))
     502              :                         etot = etot + energy
     503              :                      END IF
     504              :                      CALL add_force_nonbond(fatom_a, fatom_b, pv, fscalar, rab, use_virial)
     505              :                   END IF
     506              :                END IF
     507              :                ! Nonbonded energy
     508              : !$OMP              ATOMIC
     509              :                pot_nonbond = pot_nonbond + etot
     510              :                IF (atprop_env%energy) THEN
     511              :                   ! Update atomic energies
     512              : !$OMP                 ATOMIC
     513              :                   atprop_env%atener(atom_a) = atprop_env%atener(atom_a) + 0.5_dp*etot
     514              : !$OMP                 ATOMIC
     515              :                   atprop_env%atener(atom_b) = atprop_env%atener(atom_b) + 0.5_dp*etot
     516              :                END IF
     517              :                ! Nonbonded forces
     518              :                DO i = 1, 3
     519              : !$OMP                 ATOMIC
     520              :                   f_nonbond(i, atom_a) = f_nonbond(i, atom_a) + fatom_a(i)
     521              : !$OMP                 ATOMIC
     522              :                   f_nonbond(i, atom_b) = f_nonbond(i, atom_b) + fatom_b(i)
     523              :                END DO
     524              :                IF (shell_a > 0) THEN
     525              :                   DO i = 1, 3
     526              : !$OMP                    ATOMIC
     527              :                      fcore_nonbond(i, shell_a) = fcore_nonbond(i, shell_a) + fcore_a(i)
     528              : !$OMP                    ATOMIC
     529              :                      fshell_nonbond(i, shell_a) = fshell_nonbond(i, shell_a) + fshell_a(i)
     530              :                   END DO
     531              :                END IF
     532              :                IF (shell_b > 0) THEN
     533              :                   DO i = 1, 3
     534              : !$OMP                    ATOMIC
     535              :                      fcore_nonbond(i, shell_b) = fcore_nonbond(i, shell_b) + fcore_b(i)
     536              : !$OMP                    ATOMIC
     537              :                      fshell_nonbond(i, shell_b) = fshell_nonbond(i, shell_b) + fshell_b(i)
     538              :                   END DO
     539              :                END IF
     540              :                ! Add the contribution of the current pair to the total pressure tensor
     541              :                IF (use_virial) THEN
     542              :                   DO i = 1, 3
     543              :                      DO j = 1, 3
     544              :                         pv_thread(j, i) = pv_thread(j, i) + pv(j, i)
     545              :                      END DO
     546              :                   END DO
     547              :                END IF
     548              :             END DO Pairs
     549              : !$OMP           END DO
     550              :             IF (use_virial) THEN
     551              :                DO i = 1, 3
     552              :                   DO j = 1, 3
     553              : !$OMP                    ATOMIC
     554              :                      pv_nonbond(j, i) = pv_nonbond(j, i) + pv_thread(j, i)
     555              :                   END DO
     556              :                END DO
     557              :             END IF
     558              : !$OMP           END PARALLEL
     559              :          END DO Kind_Group_Loop
     560              :       END DO Lists
     561              : 
     562              :       !sample peak memory
     563        77140 :       CALL m_memory()
     564              : 
     565        77140 :       DEALLOCATE (mm_radius)
     566        77140 :       DEALLOCATE (qeff)
     567        77140 :       DEALLOCATE (qcore)
     568        77140 :       DEALLOCATE (qshell)
     569        77140 :       DEALLOCATE (is_shell_kind)
     570              : 
     571        77140 :       CALL timestop(handle)
     572              : 
     573       231420 :    END SUBROUTINE force_nonbond
     574              : 
     575              :    ! **************************************************************************************************
     576              :    !> \brief Adds a non-bonding contribution to the total force and optionally to
     577              :    !>        the virial.
     578              :    ! **************************************************************************************************
     579              : ! **************************************************************************************************
     580              : !> \brief ...
     581              : !> \param f_nonbond_a ...
     582              : !> \param f_nonbond_b ...
     583              : !> \param pv ...
     584              : !> \param fscalar ...
     585              : !> \param rab ...
     586              : !> \param use_virial ...
     587              : ! **************************************************************************************************
     588    998729194 :    SUBROUTINE add_force_nonbond(f_nonbond_a, f_nonbond_b, pv, fscalar, rab, use_virial)
     589              : 
     590              :       REAL(KIND=dp), DIMENSION(3), INTENT(INOUT)         :: f_nonbond_a, f_nonbond_b
     591              :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(INOUT)      :: pv
     592              :       REAL(KIND=dp), INTENT(IN)                          :: fscalar
     593              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: rab
     594              :       LOGICAL, INTENT(IN)                                :: use_virial
     595              : 
     596              :       REAL(KIND=dp), DIMENSION(3)                        :: fr
     597              : 
     598    998729194 :       fr(1) = fscalar*rab(1)
     599    998729194 :       fr(2) = fscalar*rab(2)
     600    998729194 :       fr(3) = fscalar*rab(3)
     601    998729194 :       f_nonbond_a(1) = f_nonbond_a(1) - fr(1)
     602    998729194 :       f_nonbond_a(2) = f_nonbond_a(2) - fr(2)
     603    998729194 :       f_nonbond_a(3) = f_nonbond_a(3) - fr(3)
     604    998729194 :       f_nonbond_b(1) = f_nonbond_b(1) + fr(1)
     605    998729194 :       f_nonbond_b(2) = f_nonbond_b(2) + fr(2)
     606    998729194 :       f_nonbond_b(3) = f_nonbond_b(3) + fr(3)
     607    998729194 :       IF (use_virial) THEN
     608    350010144 :          pv(1, 1) = pv(1, 1) + rab(1)*fr(1)
     609    350010144 :          pv(1, 2) = pv(1, 2) + rab(1)*fr(2)
     610    350010144 :          pv(1, 3) = pv(1, 3) + rab(1)*fr(3)
     611    350010144 :          pv(2, 1) = pv(2, 1) + rab(2)*fr(1)
     612    350010144 :          pv(2, 2) = pv(2, 2) + rab(2)*fr(2)
     613    350010144 :          pv(2, 3) = pv(2, 3) + rab(2)*fr(3)
     614    350010144 :          pv(3, 1) = pv(3, 1) + rab(3)*fr(1)
     615    350010144 :          pv(3, 2) = pv(3, 2) + rab(3)*fr(2)
     616    350010144 :          pv(3, 3) = pv(3, 3) + rab(3)*fr(3)
     617              :       END IF
     618              : 
     619    998729194 :    END SUBROUTINE add_force_nonbond
     620              : 
     621              : ! **************************************************************************************************
     622              : !> \brief corrects electrostatics for bonded terms
     623              : !> \param fist_nonbond_env ...
     624              : !> \param atomic_kind_set ...
     625              : !> \param local_particles ...
     626              : !> \param particle_set ...
     627              : !> \param ewald_env ...
     628              : !> \param v_bonded_corr ...
     629              : !> \param pv_bc ...
     630              : !> \param shell_particle_set ...
     631              : !> \param core_particle_set ...
     632              : !> \param atprop_env ...
     633              : !> \param cell ...
     634              : !> \param use_virial ...
     635              : !> \par History
     636              : !>      Split routines to clean and to fix a bug with the tensor whose
     637              : !>      original definition was not correct for PBC.. [Teodoro Laino -06/2007]
     638              : ! **************************************************************************************************
     639       238004 :    SUBROUTINE bonded_correct_gaussian(fist_nonbond_env, atomic_kind_set, &
     640        59501 :                                       local_particles, particle_set, ewald_env, v_bonded_corr, pv_bc, &
     641              :                                       shell_particle_set, core_particle_set, atprop_env, cell, use_virial)
     642              : 
     643              :       TYPE(fist_nonbond_env_type), POINTER               :: fist_nonbond_env
     644              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind_set(:)
     645              :       TYPE(distribution_1d_type), POINTER                :: local_particles
     646              :       TYPE(particle_type), POINTER                       :: particle_set(:)
     647              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
     648              :       REAL(KIND=dp), INTENT(OUT)                         :: v_bonded_corr
     649              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(OUT)        :: pv_bc
     650              :       TYPE(particle_type), OPTIONAL, POINTER             :: shell_particle_set(:), &
     651              :                                                             core_particle_set(:)
     652              :       TYPE(atprop_type), POINTER                         :: atprop_env
     653              :       TYPE(cell_type), POINTER                           :: cell
     654              :       LOGICAL, INTENT(IN)                                :: use_virial
     655              : 
     656              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'bonded_correct_gaussian'
     657              : 
     658              :       INTEGER :: atom_a, atom_b, handle, iatom, iend, igrp, ilist, ipair, istart, kind_a, kind_b, &
     659              :          natoms_per_kind, nkind, npairs, shell_a, shell_b
     660        59501 :       INTEGER, DIMENSION(:, :), POINTER                  :: list
     661              :       LOGICAL                                            :: a_is_shell, b_is_shell, do_multipoles, &
     662              :                                                             full_nl, shell_adiabatic
     663              :       REAL(KIND=dp)                                      :: alpha, const, fac_cor, fac_ei, qcore_a, &
     664              :                                                             qcore_b, qeff_a, qeff_b, qshell_a, &
     665              :                                                             qshell_b
     666              :       REAL(KIND=dp), DIMENSION(3)                        :: rca, rcb, rsa, rsb
     667        59501 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: ij_kind_full_fac
     668              :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
     669              :       TYPE(fist_neighbor_type), POINTER                  :: nonbonded
     670              :       TYPE(mp_comm_type)                                 :: group
     671              :       TYPE(neighbor_kind_pairs_type), POINTER            :: neighbor_kind_pair
     672              :       TYPE(pair_potential_pp_type), POINTER              :: potparm, potparm14
     673              :       TYPE(pair_potential_single_type), POINTER          :: pot
     674              :       TYPE(shell_kind_type), POINTER                     :: shell_kind
     675              : 
     676        59501 :       CALL timeset(routineN, handle)
     677              : 
     678              :       ! Initializing values
     679       223561 :       IF (use_virial) pv_bc = 0.0_dp
     680        59501 :       v_bonded_corr = 0.0_dp
     681              : 
     682              :       CALL fist_nonbond_env_get(fist_nonbond_env, nonbonded=nonbonded, &
     683              :                                 potparm14=potparm14, potparm=potparm, &
     684        59501 :                                 ij_kind_full_fac=ij_kind_full_fac)
     685              :       CALL ewald_env_get(ewald_env, alpha=alpha, do_multipoles=do_multipoles, &
     686        59501 :                          group=group)
     687              :       ! Defining the constants
     688        59501 :       const = 2.0_dp*alpha*oorootpi
     689              : 
     690              :       CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, &
     691        59501 :                                shell_adiabatic=shell_adiabatic)
     692              : 
     693      4584592 :       Lists: DO ilist = 1, nonbonded%nlists
     694      4525091 :          neighbor_kind_pair => nonbonded%neighbor_kind_pairs(ilist)
     695      4525091 :          npairs = neighbor_kind_pair%nscale
     696      4525091 :          IF (npairs == 0) CYCLE Lists
     697        67393 :          list => neighbor_kind_pair%list
     698      2291124 :          Kind_Group_Loop: DO igrp = 1, neighbor_kind_pair%ngrp_kind
     699      2216361 :             istart = neighbor_kind_pair%grp_kind_start(igrp)
     700      2216361 :             IF (istart > npairs) THEN
     701              :                EXIT Kind_Group_Loop
     702              :             END IF
     703      2164230 :             iend = MIN(npairs, neighbor_kind_pair%grp_kind_end(igrp))
     704              : 
     705     11806107 :             Pairs: DO ipair = istart, iend
     706      5116786 :                atom_a = list(1, ipair)
     707      5116786 :                atom_b = list(2, ipair)
     708              :                ! Get actual atomic kinds, since atom_a is not always of
     709              :                ! kind_a and atom_b of kind_b, ie. they might be swapped.
     710      5116786 :                kind_a = particle_set(atom_a)%atomic_kind%kind_number
     711      5116786 :                kind_b = particle_set(atom_b)%atomic_kind%kind_number
     712              : 
     713              :                ! take the proper potential, only for full_nl test
     714      5116786 :                pot => potparm%pot(kind_a, kind_b)%pot
     715      5116786 :                IF (ipair <= neighbor_kind_pair%nscale) THEN
     716      5116786 :                   IF (neighbor_kind_pair%is_onfo(ipair)) THEN
     717       914446 :                      pot => potparm14%pot(kind_a, kind_b)%pot
     718              :                   END IF
     719              :                END IF
     720              : 
     721              :                ! Determine the scaling factors
     722      5116786 :                fac_ei = ij_kind_full_fac(kind_a, kind_b)
     723              :                full_nl = ANY(pot%type == tersoff_type) .OR. ANY(pot%type == siepmann_type) &
     724              :                          .OR. ANY(pot%type == gal_type) .OR. ANY(pot%type == gal21_type) &
     725              :                          .OR. ANY(pot%type == nequip_type) .OR. ANY(pot%type == allegro_type) &
     726              :                          .OR. ANY(pot%type == mace_type) &
     727     92102148 :                          .OR. ANY(pot%type == ace_type) .OR. ANY(pot%type == deepmd_type)
     728      5116786 :                IF ((.NOT. full_nl) .AND. (atom_a == atom_b)) THEN
     729            0 :                   fac_ei = fac_ei*0.5_dp
     730              :                END IF
     731      5116786 :                IF (ipair <= neighbor_kind_pair%nscale) THEN
     732      5116786 :                   fac_ei = fac_ei*neighbor_kind_pair%ei_scale(ipair)
     733              :                END IF
     734              :                ! The amount of correction is related to the
     735              :                ! amount of scaling as follows:
     736      5116786 :                fac_cor = 1.0_dp - fac_ei
     737      5116786 :                IF (fac_cor <= 0.0_dp) CYCLE Pairs
     738              : 
     739              :                ! Parameters for kind a
     740      5114405 :                atomic_kind => atomic_kind_set(kind_a)
     741      5114405 :                CALL get_atomic_kind(atomic_kind, qeff=qeff_a, shell=shell_kind)
     742      5114405 :                IF (ASSOCIATED(fist_nonbond_env%charges)) qeff_a = fist_nonbond_env%charges(atom_a)
     743      5114405 :                a_is_shell = ASSOCIATED(shell_kind)
     744      5114405 :                IF (a_is_shell) THEN
     745              :                   CALL get_shell(shell=shell_kind, charge_core=qcore_a, &
     746            8 :                                  charge_shell=qshell_a)
     747            8 :                   shell_a = particle_set(atom_a)%shell_index
     748           32 :                   rca = core_particle_set(shell_a)%r
     749           32 :                   rsa = shell_particle_set(shell_a)%r
     750              :                ELSE
     751      5114397 :                   qcore_a = qeff_a
     752      5114397 :                   qshell_a = HUGE(0.0_dp)
     753      5114397 :                   shell_a = 0
     754     20457588 :                   rca = particle_set(atom_a)%r
     755      5114397 :                   rsa = 0.0_dp
     756              :                END IF
     757              : 
     758              :                ! Parameters for kind b
     759      5114405 :                atomic_kind => atomic_kind_set(kind_b)
     760      5114405 :                CALL get_atomic_kind(atomic_kind, qeff=qeff_b, shell=shell_kind)
     761      5114405 :                IF (ASSOCIATED(fist_nonbond_env%charges)) qeff_b = fist_nonbond_env%charges(atom_b)
     762      5114405 :                b_is_shell = ASSOCIATED(shell_kind)
     763      5114405 :                IF (b_is_shell) THEN
     764              :                   CALL get_shell(shell=shell_kind, charge_core=qcore_b, &
     765          264 :                                  charge_shell=qshell_b)
     766          264 :                   shell_b = particle_set(atom_b)%shell_index
     767         1056 :                   rcb = core_particle_set(shell_b)%r
     768         1056 :                   rsb = shell_particle_set(shell_b)%r
     769              :                ELSE
     770      5114141 :                   qcore_b = qeff_b
     771      5114141 :                   qshell_b = HUGE(0.0_dp)
     772      5114141 :                   shell_b = 0
     773     20456564 :                   rcb = particle_set(atom_b)%r
     774      5114141 :                   rsb = 0.0_dp
     775              :                END IF
     776              : 
     777              :                ! First part: take care of core/ion-core/ion correction
     778      5114405 :                IF (a_is_shell .AND. b_is_shell) THEN
     779              :                   ! correct for core-core interaction
     780              :                   CALL bonded_correct_gaussian_low(rca, rcb, cell, &
     781              :                                                    v_bonded_corr, core_particle_set, core_particle_set, &
     782              :                                                    shell_a, shell_b, .TRUE., alpha, qcore_a, qcore_b, &
     783            0 :                                                    const, fac_cor, pv_bc, atprop_env, use_virial)
     784      5114405 :                ELSE IF (a_is_shell) THEN
     785              :                   ! correct for core-ion interaction
     786              :                   CALL bonded_correct_gaussian_low(rca, rcb, cell, &
     787              :                                                    v_bonded_corr, core_particle_set, particle_set, &
     788              :                                                    shell_a, atom_b, .TRUE., alpha, qcore_a, qcore_b, &
     789            8 :                                                    const, fac_cor, pv_bc, atprop_env, use_virial)
     790      5114397 :                ELSE IF (b_is_shell) THEN
     791              :                   ! correct for ion-core interaction
     792              :                   CALL bonded_correct_gaussian_low(rca, rcb, cell, &
     793              :                                                    v_bonded_corr, particle_set, core_particle_set, &
     794              :                                                    atom_a, shell_b, .TRUE., alpha, qcore_a, qcore_b, &
     795          264 :                                                    const, fac_cor, pv_bc, atprop_env, use_virial)
     796              :                ELSE
     797              :                   ! correct for ion-ion interaction
     798              :                   CALL bonded_correct_gaussian_low(rca, rcb, cell, &
     799              :                                                    v_bonded_corr, particle_set, particle_set, &
     800              :                                                    atom_a, atom_b, .TRUE., alpha, qcore_a, qcore_b, &
     801      5114133 :                                                    const, fac_cor, pv_bc, atprop_env, use_virial)
     802              :                END IF
     803              : 
     804              :                ! Second part: take care of shell-shell, shell-core/ion and
     805              :                ! core/ion-shell corrections
     806      5114405 :                IF (a_is_shell .AND. b_is_shell) THEN
     807              :                   ! correct for shell-shell interaction
     808              :                   CALL bonded_correct_gaussian_low(rsa, rsa, cell, &
     809              :                                                    v_bonded_corr, shell_particle_set, shell_particle_set, &
     810              :                                                    shell_a, shell_b, shell_adiabatic, alpha, qshell_a, &
     811            0 :                                                    qshell_b, const, fac_cor, pv_bc, atprop_env, use_virial)
     812              :                END IF
     813      5114405 :                IF (a_is_shell) THEN
     814            8 :                   IF (b_is_shell) THEN
     815              :                      ! correct for shell-core interaction
     816              :                      CALL bonded_correct_gaussian_low(rsa, rcb, cell, &
     817              :                                                       v_bonded_corr, shell_particle_set, core_particle_set, &
     818              :                                                       shell_a, shell_b, shell_adiabatic, alpha, qshell_a, qcore_b, &
     819            0 :                                                       const, fac_cor, pv_bc, atprop_env, use_virial)
     820              :                   ELSE
     821              :                      ! correct for shell-ion interaction
     822              :                      CALL bonded_correct_gaussian_low(rsa, rcb, cell, &
     823              :                                                       v_bonded_corr, shell_particle_set, particle_set, &
     824              :                                                       shell_a, atom_b, shell_adiabatic, alpha, qshell_a, qcore_b, &
     825            8 :                                                       const, fac_cor, pv_bc, atprop_env, use_virial)
     826              :                   END IF
     827              :                END IF
     828     17507445 :                IF (b_is_shell) THEN
     829          264 :                   IF (a_is_shell) THEN
     830              :                      ! correct for core-shell interaction
     831              :                      CALL bonded_correct_gaussian_low(rca, rsb, cell, &
     832              :                                                       v_bonded_corr, core_particle_set, shell_particle_set, &
     833              :                                                       shell_a, shell_b, shell_adiabatic, alpha, qcore_a, qshell_b, &
     834            0 :                                                       const, fac_cor, pv_bc, atprop_env, use_virial)
     835              :                   ELSE
     836              :                      ! correct for ion-shell interaction
     837              :                      CALL bonded_correct_gaussian_low(rca, rsb, cell, &
     838              :                                                       v_bonded_corr, particle_set, shell_particle_set, &
     839              :                                                       atom_a, shell_b, shell_adiabatic, alpha, qcore_a, qshell_b, &
     840          264 :                                                       const, fac_cor, pv_bc, atprop_env, use_virial)
     841              :                   END IF
     842              :                END IF
     843              :             END DO Pairs
     844              :          END DO Kind_Group_Loop
     845              :       END DO Lists
     846              : 
     847              :       ! Always correct core-shell interaction within one atom.
     848        59501 :       nkind = SIZE(atomic_kind_set)
     849       263483 :       DO kind_a = 1, nkind
     850              :          ! parameters for kind a
     851       203982 :          atomic_kind => atomic_kind_set(kind_a)
     852       203982 :          CALL get_atomic_kind(atomic_kind, shell=shell_kind)
     853       263483 :          IF (ASSOCIATED(shell_kind)) THEN
     854              :             CALL get_shell(shell=shell_kind, charge_core=qcore_a, &
     855        18992 :                            charge_shell=qshell_a)
     856              : 
     857        18992 :             natoms_per_kind = local_particles%n_el(kind_a)
     858       437043 :             DO iatom = 1, natoms_per_kind
     859              : 
     860              :                ! Data for atom a
     861       418051 :                atom_a = local_particles%list(kind_a)%array(iatom)
     862       418051 :                shell_a = particle_set(atom_a)%shell_index
     863      1672204 :                rca = core_particle_set(shell_a)%r
     864      1672204 :                rsa = shell_particle_set(shell_a)%r
     865              : 
     866              :                CALL bonded_correct_gaussian_low_sh(rca, rsa, cell, &
     867              :                                                    v_bonded_corr, core_particle_set, shell_particle_set, &
     868              :                                                    shell_a, shell_adiabatic, alpha, qcore_a, qshell_a, &
     869       437043 :                                                    const, pv_bc, atprop_env, use_virial)
     870              : 
     871              :             END DO
     872              :          END IF
     873              :       END DO
     874              : 
     875        59501 :       CALL group%sum(v_bonded_corr)
     876              : 
     877        59501 :       CALL timestop(handle)
     878              : 
     879        59501 :    END SUBROUTINE bonded_correct_gaussian
     880              : 
     881              : ! **************************************************************************************************
     882              : !> \brief ...
     883              : !> \param r1 ...
     884              : !> \param r2 ...
     885              : !> \param cell ...
     886              : !> \param v_bonded_corr ...
     887              : !> \param particle_set1 ...
     888              : !> \param particle_set2 ...
     889              : !> \param i ...
     890              : !> \param j ...
     891              : !> \param shell_adiabatic ...
     892              : !> \param alpha ...
     893              : !> \param q1 ...
     894              : !> \param q2 ...
     895              : !> \param const ...
     896              : !> \param fac_cor ...
     897              : !> \param pv_bc ...
     898              : !> \param atprop_env ...
     899              : !> \param use_virial ...
     900              : !> \par History
     901              : !>      Split routines to clean and to fix a bug with the tensor whose
     902              : !>      original definition was not correct for PBC..
     903              : !> \author Teodoro Laino
     904              : ! **************************************************************************************************
     905      5114677 :    SUBROUTINE bonded_correct_gaussian_low(r1, r2, cell, v_bonded_corr, &
     906              :                                           particle_set1, particle_set2, i, j, shell_adiabatic, alpha, q1, q2, &
     907              :                                           const, fac_cor, pv_bc, atprop_env, use_virial)
     908              :       REAL(KIND=dp), DIMENSION(3)                        :: r1, r2
     909              :       TYPE(cell_type), POINTER                           :: cell
     910              :       REAL(KIND=dp), INTENT(INOUT)                       :: v_bonded_corr
     911              :       TYPE(particle_type), POINTER                       :: particle_set1(:), particle_set2(:)
     912              :       INTEGER, INTENT(IN)                                :: i, j
     913              :       LOGICAL, INTENT(IN)                                :: shell_adiabatic
     914              :       REAL(KIND=dp), INTENT(IN)                          :: alpha, q1, q2, const, fac_cor
     915              :       REAL(KIND=dp), INTENT(INOUT)                       :: pv_bc(3, 3)
     916              :       TYPE(atprop_type), POINTER                         :: atprop_env
     917              :       LOGICAL, INTENT(IN)                                :: use_virial
     918              : 
     919              :       REAL(KIND=dp), PARAMETER :: ac1 = 0.254829592_dp, ac2 = -0.284496736_dp, &
     920              :          ac3 = 1.421413741_dp, ac4 = -1.453152027_dp, ac5 = 1.061405429_dp, pc = 0.3275911_dp
     921              : 
     922              :       INTEGER                                            :: iatom, jatom
     923              :       REAL(KIND=dp)                                      :: arg, dij, e_arg_arg, errf, fscalar, &
     924              :                                                             idij, rijsq, tc, vbc
     925              :       REAL(KIND=dp), DIMENSION(3)                        :: fij_com, rij
     926              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: fbc
     927              : 
     928     20458708 :       rij = r1 - r2
     929     20458708 :       rij = pbc(rij, cell)
     930      5114677 :       rijsq = rij(1)*rij(1) + rij(2)*rij(2) + rij(3)*rij(3)
     931      5114677 :       idij = 1.0_dp/SQRT(rijsq)
     932      5114677 :       dij = rijsq*idij
     933      5114677 :       arg = alpha*dij
     934      5114677 :       e_arg_arg = EXP(-arg**2)
     935      5114677 :       tc = 1.0_dp/(1.0_dp + pc*arg)
     936              : 
     937              :       ! Defining errf=1-erfc
     938      5114677 :       errf = 1.0_dp - ((((ac5*tc + ac4)*tc + ac3)*tc + ac2)*tc + ac1)*tc*e_arg_arg
     939              : 
     940              :       ! Getting the potential
     941      5114677 :       vbc = -q1*q2*idij*errf*fac_cor
     942      5114677 :       v_bonded_corr = v_bonded_corr + vbc
     943      5114677 :       IF (atprop_env%energy) THEN
     944          909 :          iatom = particle_set1(i)%atom_index
     945          909 :          atprop_env%atener(iatom) = atprop_env%atener(iatom) + 0.5_dp*vbc
     946          909 :          jatom = particle_set2(j)%atom_index
     947          909 :          atprop_env%atener(jatom) = atprop_env%atener(jatom) + 0.5_dp*vbc
     948              :       END IF
     949              : 
     950              :       ! Subtracting the force from the total force
     951      5114677 :       fscalar = q1*q2*idij**2*(idij*errf - const*e_arg_arg)*fac_cor
     952              : 
     953      5114677 :       particle_set1(i)%f(1) = particle_set1(i)%f(1) - fscalar*rij(1)
     954      5114677 :       particle_set1(i)%f(2) = particle_set1(i)%f(2) - fscalar*rij(2)
     955      5114677 :       particle_set1(i)%f(3) = particle_set1(i)%f(3) - fscalar*rij(3)
     956              : 
     957      5114677 :       particle_set2(j)%f(1) = particle_set2(j)%f(1) + fscalar*rij(1)
     958      5114677 :       particle_set2(j)%f(2) = particle_set2(j)%f(2) + fscalar*rij(2)
     959      5114677 :       particle_set2(j)%f(3) = particle_set2(j)%f(3) + fscalar*rij(3)
     960              : 
     961      5114677 :       IF (use_virial .AND. shell_adiabatic) THEN
     962      2155908 :          fij_com = fscalar*rij
     963       538977 :          fbc(1, 1) = -fij_com(1)*rij(1)
     964       538977 :          fbc(1, 2) = -fij_com(1)*rij(2)
     965       538977 :          fbc(1, 3) = -fij_com(1)*rij(3)
     966       538977 :          fbc(2, 1) = -fij_com(2)*rij(1)
     967       538977 :          fbc(2, 2) = -fij_com(2)*rij(2)
     968       538977 :          fbc(2, 3) = -fij_com(2)*rij(3)
     969       538977 :          fbc(3, 1) = -fij_com(3)*rij(1)
     970       538977 :          fbc(3, 2) = -fij_com(3)*rij(2)
     971       538977 :          fbc(3, 3) = -fij_com(3)*rij(3)
     972      7006701 :          pv_bc(:, :) = pv_bc(:, :) + fbc(:, :)
     973              :       END IF
     974              : 
     975      5114677 :    END SUBROUTINE bonded_correct_gaussian_low
     976              : 
     977              : ! **************************************************************************************************
     978              : !> \brief specific for shell models cleans the interaction core-shell on the same
     979              : !>      atom
     980              : !> \param r1 ...
     981              : !> \param r2 ...
     982              : !> \param cell ...
     983              : !> \param v_bonded_corr ...
     984              : !> \param core_particle_set ...
     985              : !> \param shell_particle_set ...
     986              : !> \param i ...
     987              : !> \param shell_adiabatic ...
     988              : !> \param alpha ...
     989              : !> \param q1 ...
     990              : !> \param q2 ...
     991              : !> \param const ...
     992              : !> \param pv_bc ...
     993              : !> \param atprop_env ...
     994              : !> \param use_virial ...
     995              : !> \par History
     996              : !>      Split routines to clean and to fix a bug with the tensor whose
     997              : !>      original definition was not correct for PBC..
     998              : !> \author Teodoro Laino
     999              : ! **************************************************************************************************
    1000       418051 :    SUBROUTINE bonded_correct_gaussian_low_sh(r1, r2, cell, v_bonded_corr, &
    1001              :                                              core_particle_set, shell_particle_set, i, shell_adiabatic, alpha, q1, q2, &
    1002              :                                              const, pv_bc, atprop_env, use_virial)
    1003              :       REAL(KIND=dp), DIMENSION(3)                        :: r1, r2
    1004              :       TYPE(cell_type), POINTER                           :: cell
    1005              :       REAL(KIND=dp), INTENT(INOUT)                       :: v_bonded_corr
    1006              :       TYPE(particle_type), POINTER                       :: core_particle_set(:), &
    1007              :                                                             shell_particle_set(:)
    1008              :       INTEGER, INTENT(IN)                                :: i
    1009              :       LOGICAL, INTENT(IN)                                :: shell_adiabatic
    1010              :       REAL(KIND=dp), INTENT(IN)                          :: alpha, q1, q2, const
    1011              :       REAL(KIND=dp), INTENT(INOUT)                       :: pv_bc(3, 3)
    1012              :       TYPE(atprop_type), POINTER                         :: atprop_env
    1013              :       LOGICAL, INTENT(IN)                                :: use_virial
    1014              : 
    1015              :       REAL(KIND=dp), PARAMETER :: ac1 = 0.254829592_dp, ac2 = -0.284496736_dp, &
    1016              :          ac3 = 1.421413741_dp, ac4 = -1.453152027_dp, ac5 = 1.061405429_dp, pc = 0.3275911_dp
    1017              : 
    1018              :       INTEGER                                            :: iatom
    1019              :       REAL(KIND=dp)                                      :: arg, dij, e_arg_arg, efac, errf, ffac, &
    1020              :                                                             fscalar, idij, rijsq, tc, tc2, tc4, vbc
    1021              :       REAL(KIND=dp), DIMENSION(3)                        :: fr, rij
    1022              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: fbc
    1023              : 
    1024      1672204 :       rij = r1 - r2
    1025      1672204 :       rij = pbc(rij, cell)
    1026       418051 :       rijsq = rij(1)*rij(1) + rij(2)*rij(2) + rij(3)*rij(3)
    1027       418051 :       dij = SQRT(rijsq)
    1028              :       ! Two possible limiting cases according the value of dij
    1029       418051 :       arg = alpha*dij
    1030              :       ! and this is a magic number.. it is related to the order expansion
    1031              :       ! and to the value of the polynomial coefficients
    1032       418051 :       IF (arg > 0.355_dp) THEN
    1033            0 :          idij = 1.0_dp/dij
    1034            0 :          e_arg_arg = EXP(-arg*arg)
    1035            0 :          tc = 1.0_dp/(1.0_dp + pc*arg)
    1036              :          ! defining errf = 1 - erfc
    1037            0 :          errf = 1.0_dp - ((((ac5*tc + ac4)*tc + ac3)*tc + ac2)*tc + ac1)*tc*e_arg_arg
    1038            0 :          efac = idij*errf
    1039            0 :          ffac = idij**2*(efac - const*e_arg_arg)
    1040              :       ELSE
    1041       418051 :          tc = arg*arg
    1042       418051 :          tc2 = tc*tc
    1043       418051 :          tc4 = tc2*tc2
    1044              :          efac = const*(1.0_dp - tc/3.0_dp + tc2/10.0_dp - tc*tc2/42.0_dp + tc4/216.0_dp - &
    1045       418051 :                        tc*tc4/1320.0_dp + tc2*tc4/9360.0_dp)
    1046              :          ffac = const*alpha**2*(2.0_dp/3.0_dp - 2.0_dp*tc/5.0_dp + tc2/7.0_dp - tc*tc2/27.0_dp + &
    1047       418051 :                                 tc4/132.0_dp - tc*tc4/780.0_dp)
    1048              :       END IF
    1049              : 
    1050              :       ! getting the potential
    1051       418051 :       vbc = -q1*q2*efac
    1052       418051 :       v_bonded_corr = v_bonded_corr + vbc
    1053       418051 :       IF (atprop_env%energy) THEN
    1054         1080 :          iatom = shell_particle_set(i)%atom_index
    1055         1080 :          atprop_env%atener(iatom) = atprop_env%atener(iatom) + vbc
    1056              :       END IF
    1057              : 
    1058              :       ! subtracting the force from the total force
    1059       418051 :       fscalar = q1*q2*ffac
    1060      1672204 :       fr(:) = fscalar*rij(:)
    1061              : 
    1062       418051 :       core_particle_set(i)%f(1) = core_particle_set(i)%f(1) - fr(1)
    1063       418051 :       core_particle_set(i)%f(2) = core_particle_set(i)%f(2) - fr(2)
    1064       418051 :       core_particle_set(i)%f(3) = core_particle_set(i)%f(3) - fr(3)
    1065              : 
    1066       418051 :       shell_particle_set(i)%f(1) = shell_particle_set(i)%f(1) + fr(1)
    1067       418051 :       shell_particle_set(i)%f(2) = shell_particle_set(i)%f(2) + fr(2)
    1068       418051 :       shell_particle_set(i)%f(3) = shell_particle_set(i)%f(3) + fr(3)
    1069              : 
    1070       418051 :       IF (use_virial .AND. shell_adiabatic) THEN
    1071       344084 :          fbc(1, 1) = -fr(1)*rij(1)
    1072       344084 :          fbc(1, 2) = -fr(1)*rij(2)
    1073       344084 :          fbc(1, 3) = -fr(1)*rij(3)
    1074       344084 :          fbc(2, 1) = -fr(2)*rij(1)
    1075       344084 :          fbc(2, 2) = -fr(2)*rij(2)
    1076       344084 :          fbc(2, 3) = -fr(2)*rij(3)
    1077       344084 :          fbc(3, 1) = -fr(3)*rij(1)
    1078       344084 :          fbc(3, 2) = -fr(3)*rij(2)
    1079       344084 :          fbc(3, 3) = -fr(3)*rij(3)
    1080      4473092 :          pv_bc(:, :) = pv_bc(:, :) + fbc(:, :)
    1081              :       END IF
    1082              : 
    1083       418051 :    END SUBROUTINE bonded_correct_gaussian_low_sh
    1084              : 
    1085              : END MODULE fist_nonbond_force
        

Generated by: LCOV version 2.0-1