MODULE compute_transport_mod
   USE prec, ONLY: rstd
   IMPLICIT NONE
   PRIVATE
   SAVE

   PUBLIC :: compute_advect_horiz, compute_vlz, &
   &         compute_backward_traj, compute_gradq3d

   INTERFACE

      MODULE SUBROUTINE compute_advect_horiz(update_mass, diagflux_on, massp, fluxp, massq, fluxq, &
                                             qi, gradq3d, qfluxt, cc, qsat)
         LOGICAL, INTENT(IN)       :: update_mass, diagflux_on
         REAL(rstd), INTENT(INOUT) :: massp(:, :)      ! parent mass
         REAL(rstd), INTENT(IN)    :: fluxp(:, :)      ! parent mass flux
         REAL(rstd), INTENT(INOUT) :: massq(:, :)      ! tracer mass
         REAL(rstd), INTENT(OUT)   :: fluxq(:, :)      ! tracer mass flux
         REAL(rstd), INTENT(INOUT) :: qi(:, :)         ! tracer concentration
         REAL(rstd), INTENT(IN)    :: gradq3d(:, :, :) ! tracer gradient
         REAL(rstd), INTENT(INOUT) :: qfluxt(:, :)     ! time-integrated tracer flux
         REAL(rstd), INTENT(IN)    :: cc(:, :, :)      ! barycenter of quadrilateral, where q is evaluated (1-point quadrature)
         REAL(rstd), INTENT(IN), OPTIONAL    :: qsat(:, :)       ! saturating water vapor (kg/kg)
      END SUBROUTINE

      MODULE SUBROUTINE compute_vlz(update_mass, fac, halo, massp, fluxp, massq, fluxq, q, dzqw, adzqw, dzq)
         LOGICAL, INTENT(IN)       :: update_mass
         REAL(rstd), INTENT(IN)    :: fac
         INTEGER, INTENT(IN)       :: halo
         REAL(rstd), INTENT(INOUT) :: massp(:, :), massq(:, :) ! mass of parent (p) and tracer (q)
         REAL(rstd), INTENT(INOUT) :: fluxp(:, :), fluxq(:, :)  ! time-integrated flux of parent (p) and tracer (q)
         REAL(rstd), INTENT(INOUT) :: q(:, :)                 ! mass ratio of tracer
         ! temporary fields, need to be shared among OpenMP threads
         REAL(rstd), INTENT(INOUT) :: dzqw(:, :), &  ! vertical finite difference of q
         &                            adzqw(:, :), & ! abs(dzqw)
         &                            dzq(:, :)      ! limited slope of q
      END SUBROUTINE

      MODULE SUBROUTINE compute_backward_traj(normal, tangent, ue, tau, cc, &
        &                                     xyz_e, de, wee, le) ! metrics terms
         REAL(rstd), INTENT(IN)    :: normal(:, :)
         REAL(rstd), INTENT(IN)    :: tangent(:, :)
         REAL(rstd), INTENT(IN)    :: ue(:, :)
         REAL(rstd), INTENT(OUT)   :: cc(:, :, :) ! start of backward trajectory
         REAL(rstd), INTENT(IN)    :: tau
         ! metrics terms
         REAL(rstd), INTENT(IN)    :: xyz_e(:, :)
         REAL(rstd), INTENT(IN)    :: de(:)
         REAL(rstd), INTENT(IN)    :: wee(:, :)
         REAL(rstd), INTENT(IN)    :: le(:)
      END SUBROUTINE

      MODULE SUBROUTINE compute_gradq3d(qi, sqrt_leng, gradq3d, xyz_i, xyz_v)
         REAL(rstd), INTENT(IN)  :: qi(:, :)
         REAL(rstd), INTENT(IN)  :: sqrt_leng(:)
         REAL(rstd), INTENT(IN)  :: xyz_i(:, :)
         REAL(rstd), INTENT(IN)  :: xyz_v(:, :)
         REAL(rstd), INTENT(OUT) :: gradq3d(:, :, :)
      END SUBROUTINE compute_gradq3d

   END INTERFACE

END MODULE compute_transport_mod
