! ================================================================================
!> Compute the forces due to born repulsion potential
subroutine forces_@PBC@(localwork, box, molecules, ions, xyz_ions, force)
   implicit none
   ! Parameters
   ! ----------
   type(MW_localwork_t), intent(in) :: localwork
   type(MW_box_t), intent(in) :: box
   type(MW_molecule_t), intent(in) :: molecules(:)
   type(MW_ion_t), intent(in) :: ions(:)
   real(wp), intent(in) :: xyz_ions(:,:)
   real(wp), intent(inout) :: force(:,:)

   ! Locals
   ! ------
   integer :: num_molecule_types, imoltype, imol
   integer :: num_born_repulsions, ibond
   integer :: iatype, ibtype, ia, ib
   real(wp) :: a, b, c
   real(wp) :: dx, dy, dz, drnorm2, drnorm
   real(wp) :: k, fab, eta

   a = box%length(1)
   b = box%length(2)
   c = box%length(3)

   num_molecule_types = size(molecules,1)

   do imoltype = 1, num_molecule_types
      num_born_repulsions = molecules(imoltype)%num_born_repulsions
      if (num_born_repulsions > 0) then
         do imol = localwork%molecules_istart(imoltype), localwork%molecules_iend(imoltype)
            do ibond = 1, num_born_repulsions
               ! bond parameters
               k = molecules(imoltype)%born_repulsions_energy(ibond)
               eta = molecules(imoltype)%born_repulsions_eta(ibond)

               iatype = molecules(imoltype)%born_repulsions_sites(1,ibond)
               ibtype = molecules(imoltype)%born_repulsions_sites(2,ibond)

               ia = ions(iatype)%offset + imol
               ib = ions(ibtype)%offset + imol

               call minimum_image_displacement_@PBC@(a, b, c, &
                     xyz_ions(ia,1), xyz_ions(ia,2), xyz_ions(ia,3), &
                     xyz_ions(ib,1), xyz_ions(ib,2), xyz_ions(ib,3), &
                     dx, dy, dz, drnorm2)

               drnorm = sqrt(drnorm2)
               fab = k * eta * exp(-eta * drnorm) / drnorm

               force(ib,1) = force(ib,1) + dx * fab
               force(ib,2) = force(ib,2) + dy * fab
               force(ib,3) = force(ib,3) + dz * fab

               force(ia,1) = force(ia,1) - dx * fab
               force(ia,2) = force(ia,2) - dy * fab
               force(ia,3) = force(ia,3) - dz * fab

            end do
         end do
      end if
   end do

end subroutine forces_@PBC@

! ================================================================================
!> Compute the energy due to born repulsion potential
subroutine energy_@PBC@(localwork, box, molecules, ions, xyz_ions, h)
   implicit none
   ! Parameters
   ! ----------
   type(MW_localwork_t), intent(in) :: localwork
   type(MW_box_t), intent(in) :: box
   type(MW_molecule_t), intent(in) :: molecules(:)
   type(MW_ion_t), intent(in) :: ions(:)
   real(wp), intent(in) :: xyz_ions(:,:)
   real(wp), intent(inout) :: h

   ! Locals
   ! ------
   integer :: num_molecule_types, imoltype, imol
   integer :: num_born_repulsions, ibond
   integer :: iatype, ibtype, ia, ib
   real(wp) :: a, b, c
   real(wp) :: drnorm2, drnorm
   real(wp) :: k, eta, Uab

   a = box%length(1)
   b = box%length(2)
   c = box%length(3)

   num_molecule_types = size(molecules,1)

   do imoltype = 1, num_molecule_types
      num_born_repulsions = molecules(imoltype)%num_born_repulsions
      if (num_born_repulsions > 0) then
         do imol = localwork%molecules_istart(imoltype), localwork%molecules_iend(imoltype)
            do ibond = 1, num_born_repulsions
               ! bond parameters
               k = molecules(imoltype)%born_repulsions_energy(ibond)
               eta = molecules(imoltype)%born_repulsions_eta(ibond)

               iatype = molecules(imoltype)%born_repulsions_sites(1,ibond)
               ibtype = molecules(imoltype)%born_repulsions_sites(2,ibond)

               ia = ions(iatype)%offset + imol
               ib = ions(ibtype)%offset + imol

               call minimum_image_distance_@PBC@(a, b, c, &
                     xyz_ions(ia,1), xyz_ions(ia,2), xyz_ions(ia,3), &
                     xyz_ions(ib,1), xyz_ions(ib,2), xyz_ions(ib,3), &
                     drnorm2)

               drnorm = sqrt(drnorm2)
               Uab = k * exp(-eta * drnorm)
               h = h + Uab
            end do
         end do
      end if
   end do

end subroutine energy_@PBC@

