  SUBROUTINE tssub_advdif_macho3d(xe,sal,temp  &
#ifdef key_substance
                                 ,cv_wat        &
#endif
                                 )

   !&E---------------------------------------------------------------------
   !&E                 ***  ROUTINE tssub_advdif_macho3d  ***
   !&E
   !&E ** Purpose : call the good advection scheme depending of the cpp key
   !&E
   !&E ** Description : use macho splitting in 3 directions X,Y,Z
   !&E                  The tracer advection is computed in a different order at each time step:
   !&E                  along directions XYZ - XZY - YXZ - YZX - ZXY - ZYX
   !&E
   !&E ** Called by :
   !&E
   !&E ** External calls :
   !&E
   !&E ** Used ij-arrays : temp,sal,cv_wat
   !&E
   !&E ** Modified variables :
   !&E
   !&E ** Reference : Leonard B. P., Lock A. P. and M. K. MacVean (1996) :
   !&E                Conservative Explicit Unrestricted-Time-Step
   !&E                Multidimensional COnstancy-Preserving Advections Schemes.
   !&E                Monthly Weather Review, 124, 2588:2605
   !&E
   !&E                Debreu, Duhaut (2011) - Contrat PREVIMER 09/2 211 097
   !&E
   !&E ** History :
   !&E       !  2010-12  (V. Garnier) Original code
   !&E
   !&E---------------------------------------------------------------------

#include "toolcpp.h"

   !! Modules used
   USE parameters, ONLY : rsh,imin,imax,jmin,ljminm2,ljmaxp2,jmax,kmax,ljmin,ljmax, &
                          liminm2,liminm1,limaxp1,limaxp2,limin,limax,ljminm1,ljmaxp1
#ifdef key_substance
   USE parameters, ONLY : nb_var
#endif
   USE comvars2d,  ONLY : nbouc,ierrorlog,nbouc_macho
   USE comvarp2d,  ONLY : temp2,sal2,temp3,sal3
#ifdef key_substance
   USE comsubstance, ONLY : c2,c3
#endif

   !! * Arguments
   REAL(kind=rsh),DIMENSION(     liminm2:limaxp2,ljminm2:ljmaxp2),       INTENT(in) :: xe
   REAL(KIND=rsh),DIMENSION(kmax,liminm1:limaxp2,ljminm1:ljmaxp2),       INTENT(in) :: temp,sal
#ifdef key_substance
   REAL(KIND=rsh),DIMENSION(nb_var,kmax,liminm1:limaxp2,ljminm1:ljmaxp2),INTENT(in) :: cv_wat
#endif

   !! * Local declarations
   INTEGER :: nxyz

   !!----------------------------------------------------------------------
   !! * Executable part

   PRINT_DBG*, 'enter TSSUB_ADVDIF_MACHO3D.F90 routine'


   nxyz=MOD(nbouc+nbouc_macho,6)
   SELECT CASE (nxyz)

     CASE(1) ! XYZ

     CALL tssub_advx_macho(sal,temp,sal2,temp2   &
#ifdef key_substance
                                   ,cv_wat,c2    &
#endif
                                           )
     CALL tssub_advy_macho(sal2,temp2,sal3,temp3  &
#ifdef key_substance
                                      ,c2,c3      &
#endif
                                           )
     ! Advection along x
#ifdef key_tssub_adv_ultimatequickest
     CALL tssub_advdifx_uq(sal,temp             &
#elif key_tssub_adv_fifthorder
     CALL tssub_advdifx_fifthorder(sal,temp     &
#elif key_tssub_adv_fourthorder
     CALL tssub_advdifx_fourthorder(sal,temp     &
#else
     CALL tssub_advdifx_q(sal,temp              &
#endif
#ifdef key_substance
                                   ,cv_wat      &
#endif
                                        )

     ! Advection along y
#ifdef key_tssub_adv_ultimatequickest
     CALL tssub_advdify_uq(sal2,temp2           &
#elif key_tssub_adv_fifthorder
     CALL tssub_advdify_fifthorder(sal2,temp2   &
#elif key_tssub_adv_fourthorder
     CALL tssub_advdify_fourthorder(sal2,temp2   &
#else
     CALL tssub_advdify_q(sal2,temp2            &
#endif
#ifdef key_substance
                                   ,c2          &
#endif
                                        )

     ! Advection along z
#if defined key_tssub_wquickupwind
#if ! defined key_offline
     CALL ts_advz_quickupwind(xe,sal3,temp3)
#endif
#ifdef key_substance
     CALL sub_advz_quickupwind(xe,c3)
#endif
#elif defined key_tssub_wcompact
#if ! defined key_offline
     CALL ts_advz_compact(xe,sal3,temp3)
#endif
#ifdef key_substance
     CALL sub_advz_compact(xe,c3)
#endif

#endif

   CASE(2) ! XZY

     CALL tssub_advx_macho(sal,temp,sal2,temp2   &
#ifdef key_substance
                                   ,cv_wat,c2    &
#endif
                                           )
     CALL tssub_advz_macho(xe,sal2,temp2,sal3,temp3 &
#ifdef key_substance
                                      ,c2,c3     &
#endif
                                           )

     ! Advection along x
#ifdef key_tssub_adv_ultimatequickest
     CALL tssub_advdifx_uq(sal,temp              &
#elif key_tssub_adv_fifthorder
     CALL tssub_advdifx_fifthorder(sal,temp      &
#elif key_tssub_adv_fourthorder
     CALL tssub_advdifx_fourthorder(sal,temp     &
#else
     CALL tssub_advdifx_q(sal,temp               &
#endif
#ifdef key_substance
                                   ,cv_wat       &
#endif
                                        )

     ! Advection along y
#ifdef key_tssub_adv_ultimatequickest
     CALL tssub_advdify_uq(sal3,temp3            &
#elif key_tssub_adv_fifthorder
     CALL tssub_advdify_fifthorder(sal3,temp3    &
#elif key_tssub_adv_fourthorder
     CALL tssub_advdify_fourthorder(sal3,temp3   &
#else
     CALL tssub_advdify_q(sal3,temp3             &
#endif
#ifdef key_substance
                                   ,c3           &
#endif
                                        )

     ! Advection along z
#if defined key_tssub_wquickupwind
#if ! defined key_offline
     CALL ts_advz_quickupwind(xe,sal2,temp2)
#endif
#ifdef key_substance
     CALL sub_advz_quickupwind(xe,c2)
#endif
#elif defined key_tssub_wcompact
#if ! defined key_offline
     CALL ts_advz_compact(xe,sal2,temp2)
#endif
#ifdef key_substance
     CALL sub_advz_compact(xe,c2)
#endif

#endif

   CASE(3) ! YXZ

     CALL tssub_advy_macho(sal,temp,sal2,temp2   &
#ifdef key_substance
                                   ,cv_wat,c2    &
#endif
                                           )
     CALL tssub_advx_macho(sal2,temp2,sal3,temp3 &
#ifdef key_substance
                                      ,c2,c3     &
#endif
                                           )

     ! Advection along x
#ifdef key_tssub_adv_ultimatequickest
     CALL tssub_advdifx_uq(sal2,temp2            &
#elif key_tssub_adv_fifthorder
     CALL tssub_advdifx_fifthorder(sal2,temp2    &
#elif key_tssub_adv_fourthorder
     CALL tssub_advdifx_fourthorder(sal2,temp2   &
#else
     CALL tssub_advdifx_q(sal2,temp2             &
#endif
#ifdef key_substance
                                   ,c2           &
#endif
                                        )

     ! Advection along y
#ifdef key_tssub_adv_ultimatequickest
     CALL tssub_advdify_uq(sal,temp              &
#elif key_tssub_adv_fifthorder
     CALL tssub_advdify_fifthorder(sal,temp      &
#elif key_tssub_adv_fourthorder
     CALL tssub_advdify_fourthorder(sal,temp    &
#else
     CALL tssub_advdify_q(sal,temp               &
#endif
#ifdef key_substance
                                   ,cv_wat       &
#endif
                                        )

     ! Advection along z
#if defined key_tssub_wquickupwind
#if ! defined key_offline
     CALL ts_advz_quickupwind(xe,sal3,temp3)
#endif
#ifdef key_substance
     CALL sub_advz_quickupwind(xe,c3)
#endif
#elif defined key_tssub_wcompact
#if ! defined key_offline
     CALL ts_advz_compact(xe,sal3,temp3)
#endif
#ifdef key_substance
     CALL sub_advz_compact(xe,c3)
#endif

#endif

   CASE(4) ! YZX

     CALL tssub_advy_macho(sal,temp,sal2,temp2   &
#ifdef key_substance
                                   ,cv_wat,c2    &
#endif
                                           )
     CALL tssub_advz_macho(xe,sal2,temp2,sal3,temp3 &
#ifdef key_substance
                                      ,c2,c3     &
#endif
                                           )

     ! Advection along x
#ifdef key_tssub_adv_ultimatequickest
     CALL tssub_advdifx_uq(sal3,temp3            &
#elif key_tssub_adv_fifthorder
     CALL tssub_advdifx_fifthorder(sal3,temp3    &
#elif key_tssub_adv_fourthorder
     CALL tssub_advdifx_fourthorder(sal3,temp3   &
#else
     CALL tssub_advdifx_q(sal3,temp3             &
#endif
#ifdef key_substance
                                   ,c3           &
#endif
                                        )

     ! Advection along y
#ifdef key_tssub_adv_ultimatequickest
     CALL tssub_advdify_uq(sal,temp              &
#elif key_tssub_adv_fifthorder
     CALL tssub_advdify_fifthorder(sal,temp      &
#elif key_tssub_adv_fourthorder
     CALL tssub_advdify_fourthorder(sal,temp     &
#else
     CALL tssub_advdify_q(sal,temp               &
#endif
#ifdef key_substance
                                   ,cv_wat       &
#endif
                                        )

     ! Advection along z
#if defined key_tssub_wquickupwind
#if ! defined key_offline
     CALL ts_advz_quickupwind(xe,sal2,temp2)
#endif
#ifdef key_substance
     CALL sub_advz_quickupwind(xe,c2)
#endif
#elif defined key_tssub_wcompact
#if ! defined key_offline
     CALL ts_advz_compact(xe,sal2,temp2)
#endif
#ifdef key_substance
     CALL sub_advz_compact(xe,c2)
#endif
#endif

   CASE(5) ! ZXY

     CALL tssub_advz_macho(xe,sal,temp,sal2,temp2   &
#ifdef key_substance
                                      ,cv_wat,c2    &
#endif
                                           )
     CALL tssub_advx_macho(sal2,temp2,sal3,temp3 &
#ifdef key_substance
                                      ,c2,c3     &
#endif
                                           )

     ! Advection along x
#ifdef key_tssub_adv_ultimatequickest
     CALL tssub_advdifx_uq(sal2,temp2            &
#elif key_tssub_adv_fifthorder
     CALL tssub_advdifx_fifthorder(sal2,temp2    &
#elif key_tssub_adv_fourthorder
     CALL tssub_advdifx_fourthorder(sal2,temp2   &
#else
     CALL tssub_advdifx_q(sal2,temp2             &
#endif
#ifdef key_substance
                                   ,c2           &
#endif
                                        )

     ! Advection along y
#ifdef key_tssub_adv_ultimatequickest
     CALL tssub_advdify_uq(sal3,temp3            &
#elif key_tssub_adv_fifthorder
     CALL tssub_advdify_fifthorder(sal3,temp3    &
#elif key_tssub_adv_fourthorder
     CALL tssub_advdify_fourthorder(sal3,temp3   &
#else
     CALL tssub_advdify_q(sal3,temp3             &
#endif
#ifdef key_substance
                                   ,c3           &
#endif
                                        )

     ! Advection along z
#if defined key_tssub_wquickupwind
#if ! defined key_offline
     CALL ts_advz_quickupwind(xe,sal,temp)
#endif
#ifdef key_substance
     CALL sub_advz_quickupwind(xe,cv_wat)
#endif
#elif defined key_tssub_wcompact
#if ! defined key_offline
     CALL ts_advz_compact(xe,sal,temp)
#endif
#ifdef key_substance
     CALL sub_advz_compact(xe,cv_wat)
#endif
#endif

   CASE(0) ! ZYX

     CALL tssub_advz_macho(xe,sal,temp,sal2,temp2   &
#ifdef key_substance
                                      ,cv_wat,c2    &
#endif
                                           )
     CALL tssub_advy_macho(sal2,temp2,sal3,temp3 &
#ifdef key_substance
                                      ,c2,c3     &
#endif
                                           )

     ! Advection along x
#ifdef key_tssub_adv_ultimatequickest
     CALL tssub_advdifx_uq(sal3,temp3            &
#elif key_tssub_adv_fifthorder
     CALL tssub_advdifx_fifthorder(sal3,temp3    &
#elif key_tssub_adv_fourthorder
     CALL tssub_advdifx_fourthorder(sal3,temp3   &
#else
     CALL tssub_advdifx_q(sal3,temp3             &
#endif
#ifdef key_substance
                                   ,c3           &
#endif
                                        )

     ! Advection along y
#ifdef key_tssub_adv_ultimatequickest
     CALL tssub_advdify_uq(sal2,temp2            &
#elif key_tssub_adv_fifthorder
     CALL tssub_advdify_fifthorder(sal2,temp2    &
#elif key_tssub_adv_fourthorder
     CALL tssub_advdify_fourthorder(sal2,temp2    &
#else
     CALL tssub_advdify_q(sal2,temp2             &
#endif
#ifdef key_substance
                                   ,c2           &
#endif
                                        )

     ! Advection along z
#if defined key_tssub_wquickupwind
#if ! defined key_offline
     CALL ts_advz_quickupwind(xe,sal,temp)
#endif
#ifdef key_substance
     CALL sub_advz_quickupwind(xe,cv_wat)
#endif
#elif defined key_tssub_wcompact
#if ! defined key_offline
     CALL ts_advz_compact(xe,sal,temp)
#endif
#ifdef key_substance
     CALL sub_advz_compact(xe,cv_wat)
#endif
#endif

   CASE DEFAULT
     WRITE(ierrorlog,*) ' '
     WRITE(ierrorlog,*) ' routine TSSUB_ADVDIF_MACHO3D '
     WRITE(ierrorlog,*) ' you should never see this line '
     WRITE(ierrorlog,*) ' '
   END SELECT

   PRINT_DBG*, 'exit TSSUB_ADVDIF_MACHO3D.F90 routine'

  END SUBROUTINE tssub_advdif_macho3d
