   !================================================================================
   !> Minimum image displacement between atoms 1 and a list of atoms 2
   !!
   !! Given a box with 2D periodic boundary conditions, this
   !! subroutine computes the minimum image displacement between atoms
   !! 1 and atoms 2. That is the displacement with the minimum
   !! distance between 1 and any of the images of 2.
   !!
   !! In fortran, int() returns the integer part of a real number. It
   !! is different from floor() in particular for negative numbers
   !! int(3.5) = 3 and int(-3.5) = -3
   !!
   elemental subroutine minimum_image_displacement_3DPBC(a, b, c, &
         x_1, y_1, z_1, x_2, y_2, z_2, dx, dy, dz, drnorm2)
      implicit none
      ! Parameter
      ! ---------
      real(wp), intent(in) :: a, b, c       !< box length parameters
      real(wp), intent(in) :: x_1, y_1, z_1 !< xyz atom 1 position
      real(wp), intent(in) :: x_2, y_2, z_2 !< xyz atom 2 positions

      real(wp), intent(out) :: dx, dy, dz   !< minimum image displacement vector
      real(wp), intent(out) :: drnorm2      !< square of minimum image distance

      ! Locals
      ! ------
      integer :: scale

      dx = x_2 - x_1
      scale = floor(dx / a + 0.5_wp)
      dx = dx - a*real(scale,wp)

      dy = y_2 - y_1
      scale = floor(dy / b + 0.5_wp)
      dy = dy - b*real(scale,wp)

      dz = z_2 - z_1
      scale = floor(dz / c + 0.5_wp)
      dz = dz - c*real(scale,wp)

      drnorm2 = (dx*dx + dy*dy + dz*dz)

   end subroutine minimum_image_displacement_3DPBC
