diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/001_pgd1/PRE_PGD1.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/001_pgd1/PRE_PGD1.nam
new file mode 100644
index 0000000000000000000000000000000000000000..3ae48e8b0f44fc5ea746497eca9a0a0b2277c131
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/001_pgd1/PRE_PGD1.nam
@@ -0,0 +1,13 @@
+&NAM_CONFZ
+ NB_PROCIO_W=1 ,
+ !MPI_BUFFER_SIZE=40
+/
+&NAM_PGDFILE CPGDFILE="PGD00128" /
+&NAM_PGD_SCHEMES CNATURE='ISBA', CSEA='SEAFLX', CTOWN='NONE', CWATER='NONE' /
+&NAM_CONF_PROJ XLAT0=-11.5, XLON0=130.7, XRPK=0., XBETA=0. /
+&NAM_CONF_PROJ_GRID XLATCEN=-11.5, XLONCEN=130.7, NIMAX=128, NJMAX=128,
+                    XDX=1600.00000, XDY=1600.00000 /
+&NAM_COVER     YCOVER='ECOCLIMAP_v2.0', YCOVERFILETYPE='DIRECT' /
+&NAM_ZS        YZS='gtopo30', YZSFILETYPE='DIRECT' /
+&NAM_ISBA  YCLAY='CLAY_HWSD_MOY', YCLAYFILETYPE='DIRECT',
+           YSAND='SAND_HWSD_MOY', YSANDFILETYPE='DIRECT' /
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/001_pgd1/get_pgd_files b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/001_pgd1/get_pgd_files
new file mode 100755
index 0000000000000000000000000000000000000000..56726933a0f7608e0c4918f42e80d5aea76b669d
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/001_pgd1/get_pgd_files
@@ -0,0 +1,30 @@
+#
+#     Modif
+#     J.Escobar 11/04/2014 get PGD files from 'dir_open' directory ( without psswd )
+#     J.Escobar 25/04/2013 get LICENCE files
+#
+PREP_PGD_FILES=${PREP_PGD_FILES:-"$HOME/PREP_PGD_FILES_WWW"} ; export PREP_PGD_FILES
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo "!!!!            WARNING                  !!!!"
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo 
+echo you need 3GO to download this files in
+echo 
+echo PREP_PGD_FILES=$PREP_PGD_FILES  
+echo 
+echo if OK press ENTER  else CTRL-C
+read RIEN
+set -x
+mkdir -p $PREP_PGD_FILES
+cd $PREP_PGD_FILES
+PGD_URL="http://mesonh.aero.obs-mip.fr/mesonh/dir_open/dir_PGDFILES"
+WGET="wget"
+export PGD_URL
+for file in LICENSE_ECOCLIMAP.txt LICENSE_soil_data.txt \
+            gtopo30.dir gtopo30.hdr \
+            SAND_HWSD_MOY.hdr SAND_HWSD_MOY.dir CLAY_HWSD_MOY.hdr CLAY_HWSD_MOY.dir \
+            ECOCLIMAP_v2.0.hdr ECOCLIMAP_v2.0.dir
+do
+[ -f $file ] || ( ${WGET} -c -nd $PGD_URL/$file.gz ; gunzip $file.gz ; ) 
+done
+
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/001_pgd1/run_prep_pgd_xyz b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/001_pgd1/run_prep_pgd_xyz
new file mode 100755
index 0000000000000000000000000000000000000000..5c34e67e3f8ec036121d636d3d9c8cc5fadf197e
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/001_pgd1/run_prep_pgd_xyz
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+export MPIRUN="Mpirun -np 4"
+
+
+PREP_PGD_FILES=${PREP_PGD_FILES:-"$HOME/PREP_PGD_FILES_WWW"} ; export PREP_PGD_FILES
+#
+if [ ! -d $PREP_PGD_FILES ]
+then
+cat << EOF
+
+Your directory  PREP_PGD_FILES=$PREP_PGD_FILES
+
+containing the files gtopo30*, ECOCLIMAP_v2.0* 
+doesn't exist ( or was not found !!! )
+use the script 'get_pgd_files' to download 
+this files from the MESONH WEB PAGES !!!
+( or change the variable PREP_PGD_FILES ... )
+
+After fixing it , run this script again !!!
+ 
+EOF
+exit 1
+else
+set -x 
+#
+rm -f OUTPUT_LISTING0 pipe_name
+rm -f gtopo30.???  sand_fao.???  clay_fao.???
+rm -f SAND_HWSD_MOY.??? ECOCLIMAP_v2.0.??? ecoclimats_v2.???
+rm -f PGD00128.*
+#
+ln -sf $PREP_PGD_FILES/*.dir $PREP_PGD_FILES/*.hdr .
+#
+time ${MPIRUN} PREP_PGD${XYZ}
+fi
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/002_prep_ideal_case/PRE_IDEA1.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/002_prep_ideal_case/PRE_IDEA1.nam
new file mode 100644
index 0000000000000000000000000000000000000000..3baef58caeae016c444e5f7c447f821726afb861
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/002_prep_ideal_case/PRE_IDEA1.nam
@@ -0,0 +1,226 @@
+&NAM_CONFZ
+ !NB_PROCIO_R=1 ,
+ !NB_PROCIO_W=1 ,
+ !MPI_BUFFER_SIZE=40
+/
+
+&NAM_REAL_PGD
+            CPGD_FILE ="PGD00128" ,
+            LREAD_ZS =.TRUE., LREAD_GROUND_PARAM =.TRUE.
+/
+&NAM_DIMn_PRE NIMAX=40, NJMAX=32 /
+&NAM_CONF_PRE LCARTESIAN=.FALSE.
+              CIDEAL='RSOU' CZS='FLAT'
+              NVERB=0 /
+&NAM_CONFn LUSERV= T /
+&NAM_LUNITn CINIFILE = "DA0128" , CINIFILEPGD = "PGD00128" /
+&NAM_DYNn_PRE
+  CPRESOPT= 'ZRESI' ,
+  NITR=4 XRELAX=1. /
+&NAM_LBCn_PRE CLBCX= 2*'OPEN' CLBCY= 2*'OPEN' /
+&NAM_VPROF_PRE CTYPELOC='IJGRID' NILOC=1 NJLOC=1
+               CFUNU='ZZZ' CFUNV='ZZZ'
+               LGEOSBAL=.FALSE. /
+&NAM_VER_GRID NKMAX=126, YZGRID_TYPE='FUNCTN',
+       ZDZGRD=40., ZDZTOP=210., ZZMAX_STRGRD=2500.,
+       ZSTRGRD=7., ZSTRTOP=7. /
+&NAM_GRn_PRE
+   CSURF='EXTE'
+   ! CSURF='NONE'
+  /
+&NAM_PREP_ISBA XTG_SURF= 311., XTG_ROOT= 303., XTG_DEEP= 302.,
+               XHUG_SURF= 0.16, XHUG_ROOT= 0.16, XHUG_DEEP= 0.16 /
+&NAM_PREP_SEAFLUX XSST_UNIF= 304. /
+  RSOU
+ 2005 11 30 0
+ 'PUVTHDMR'
+  0.0000000E+00
+   100300.0    
+   303.3000    
+  1.9630000E-02
+          92
+   100000.0       3.637668      -3.637668    
+   99900.00       2.572220      -4.455216    
+   99100.00      -4.612377      0.4035313    
+   96600.00       5.124864     -0.4483674    
+   93000.00       5.836996      -2.009839    
+   92800.00       5.801031      -2.111402    
+   92500.00       5.466062      -1.464627    
+   85000.00      0.1345103      -1.537459    
+   81400.00     -0.9020693      -1.849517    
+   71800.00      -2.797467       1.304481    
+   70000.00      -4.472232       1.198331    
+   60500.00      -3.289776      -1.464702    
+   59900.00      -3.208611      -1.634869    
+   56900.00      -2.329535      -2.025034    
+   55600.00      -2.105100      -2.257443    
+   50100.00     -0.5325915      -1.987659    
+   50000.00     -0.2679967      -1.519885    
+   49500.00      0.2507798      -2.042438    
+   46700.00       5.466062       1.464627    
+   45300.00       5.594935       2.608961    
+   44800.00       5.450725       2.898202    
+   43700.00       4.994327       3.628591    
+   42200.00       4.561049       4.891127    
+   41900.00       4.387573       5.047325    
+   41800.00       4.298817       5.123130    
+   40000.00       6.305391       5.290851    
+   39000.00       5.970908       4.027428    
+   38600.00       5.671552       3.543979    
+   38300.00       5.346259       3.086664    
+   35500.00       2.976104       3.546782    
+   32700.00       4.455215       2.572220    
+   31400.00       3.712562       4.270814    
+   30700.00       3.086664       5.346259    
+   30000.00       3.540875       5.056894    
+   28800.00       3.786532       4.205370    
+   26700.00       3.329551       2.419061    
+   25000.00       2.797467       1.304481    
+   24400.00       2.819808       1.255459    
+   23800.00       2.841289       1.206056    
+   21400.00       3.424857       1.112804    
+   20000.00       3.478403      0.9320353    
+   19300.00       3.383935       1.231651    
+   17400.00       3.411947       2.301387    
+   15000.00       2.950729       4.214078    
+   12700.00       2.167201       2.875973    
+   10200.00       1.322713       1.576348    
+   10000.00      0.4466614       2.533142    
+   9120.000      -3.306782       3.940869    
+   8700.000      -7.950636       2.130367    
+   8200.000      -8.712269      0.7622259    
+   8000.000      -9.224754     -0.8070621    
+   7600.000      -4.009694      -2.314998    
+   7300.000      -5.066284     -0.8933228    
+   7000.000      -4.196201      -1.956721    
+   6700.000      -1.013257      0.1786647    
+   6400.000      -2.107039       1.475365    
+   6340.000      -2.558960       1.726041    
+   5480.000      -13.17234       2.322640    
+   5300.000      -15.37459       1.345105    
+   5000.000      -12.81216      -1.120920    
+   4900.000      -12.66571      -2.233307    
+   4860.000      -12.25463      -1.504677    
+   4700.000      -10.76221      0.9415731    
+   4500.000      -11.37801       7.966970    
+   3800.000      -25.11183       2.197004    
+   3600.000      -22.54940      -1.972818    
+   3200.000      -22.72465      -4.417223    
+   3000.000      -22.36116      -5.991656    
+   2490.000      -21.48829      -2.258509    
+   2300.000      -21.07936     -0.7361050    
+   2200.000      -20.57776     -1.7989648E-06
+   2080.000      -19.00834     -0.9961855    
+   2000.000      -17.93702      -1.569287    
+   1600.000      -14.74927      -10.32755    
+   1500.000      -13.52109      -6.304989    
+   1430.000      -16.89510      -4.527030    
+   1400.000      -18.23862      -3.215962    
+   1300.000      -15.46941      -5.630407    
+   1200.000      -5.594935       2.608962    
+   1190.000      -5.671552       3.543979    
+   1100.000       1.786646       10.13257    
+   1050.000      -3.736842       7.333968    
+   1020.000      -5.435582       4.725079    
+   1000.000      -5.594935       2.608962    
+   950.0000      -4.347303       8.176087    
+   900.0000       2.143975       12.15908    
+   889.9999       1.031246       11.78719    
+   800.0000      -4.728969       4.728969    
+   760.0000       2.890712       7.154763    
+   710.0000       8.644947      -3.318484    
+   700.0000       7.487652      -6.282886    
+   600.0000      -4.214078      -2.950729    
+          91
+   100000.0       303.1000      1.8050000E-02
+   99900.00       303.1000      1.8040001E-02
+   99100.00       303.1000      1.7969999E-02
+   96600.00       303.1000      1.7729999E-02
+   93000.00       303.0000      1.7370002E-02
+   92800.00       303.1000      1.6980000E-02
+   92500.00       303.2000      1.6400000E-02
+   85000.00       307.1000      1.1190000E-02
+   81400.00       309.6000      6.6700005E-03
+   71800.00       312.3000      6.5600001E-03
+   70000.00       312.9000      6.5400004E-03
+   60500.00       316.2000      6.1800000E-03
+   59900.00       318.1000      5.3400006E-03
+   56900.00       318.7000      4.9899998E-03
+   55600.00       322.2000      3.3100001E-03
+   50100.00       325.5000      2.6000000E-03
+   50000.00       325.5000      2.5800001E-03
+   49500.00       325.7000      3.1700002E-03
+   46700.00       328.6000      1.4500001E-03
+   45300.00       330.1000      9.4000006E-04
+   44800.00       330.1000      1.9600000E-03
+   43700.00       331.0000      2.1500003E-03
+   42200.00       332.2000      1.9400001E-03
+   41900.00       332.9000      9.6000003E-04
+   41800.00       333.0000      9.7000005E-04
+   40000.00       334.2000      1.1600000E-03
+   39000.00       334.6000      1.0300000E-03
+   38600.00       335.6000      6.5000000E-04
+   38300.00       335.8000      6.0000003E-04
+   35500.00       338.2000      2.5000001E-04
+   32700.00       340.8000      9.0000009E-05
+   31400.00       342.0000      5.0000002E-05
+   30700.00       342.1000      4.0000003E-05
+   30000.00       342.3000      4.0000003E-05
+   28800.00       342.3000      1.2000000E-04
+   26700.00       344.8000      1.0000001E-05
+   25000.00       345.4000      1.0000001E-05
+   24400.00       346.3000      2.0000001E-05
+   23800.00       346.4000      9.0000009E-05
+   21400.00       348.1000      1.0000001E-05
+   20000.00       348.8000      1.0000001E-05
+   19300.00       348.9000      2.0000001E-05
+   17400.00       351.5000      1.0000001E-05
+   15000.00       354.0000      7.1596442E-06
+   12700.00       355.7000      4.4376361E-06
+   10200.00       364.6000      1.4789329E-06
+   10000.00       365.4000      1.2422363E-06
+   9120.000       371.6000      1.2919259E-06
+   8700.000       379.9000      1.5496893E-06
+   8200.000       390.6000      1.8819877E-06
+   8000.000       395.1000      2.0217396E-06
+   7600.000       404.7000      2.3198761E-06
+   7300.000       412.3000      2.4844724E-06
+   7000.000       420.4000      2.4844724E-06
+   6700.000       431.1000      2.4844724E-06
+   6400.000       442.4000      2.4844724E-06
+   6340.000       444.8000      2.4844724E-06
+   5480.000       467.8000      2.4844724E-06
+   5300.000       471.0000      2.4844724E-06
+   5000.000       476.5000      2.4844724E-06
+   4900.000       477.6000      2.4844724E-06
+   4860.000       478.0000      2.4844724E-06
+   4700.000       485.1000      2.4844724E-06
+   4500.000       494.6000      2.4844724E-06
+   3800.000       532.9000      2.4844724E-06
+   3600.000       545.6000      2.4844724E-06
+   3200.000       574.4000      2.4844724E-06
+   3000.000       585.1000      2.4844724E-06
+   2490.000       624.0000      2.4844724E-06
+   2300.000       648.9000      2.4844724E-06
+   2200.000       655.4000      2.4844724E-06
+   2080.000       663.6000      2.4844724E-06
+   2000.000       673.5000      2.4844724E-06
+   1600.000       726.4000      2.4844724E-06
+   1500.000       742.5000      2.4844724E-06
+   1430.000       750.7000      2.4844724E-06
+   1400.000       759.0000      2.4844724E-06
+   1300.000       788.6000      2.4844724E-06
+   1200.000       821.7000      2.4844724E-06
+   1190.000       825.2000      2.4844724E-06
+   1100.000       833.9000      2.4844724E-06
+   1050.000       839.0000      2.4844724E-06
+   1020.000       845.3000      2.4844724E-06
+   1000.000       851.6000      2.4844724E-06
+   950.0000       877.0000      2.4844724E-06
+   900.0000       885.6000      2.4844724E-06
+   889.9999       887.3000      2.4844724E-06
+   800.0000       926.6000      2.4844724E-06
+   760.0000       946.0000      2.4844724E-06
+   710.0000       958.0000      2.4844724E-06
+   700.0000       963.1000      2.4844724E-06
+   600.0000       20.30000      2.4844724E-06
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/002_prep_ideal_case/run_prep_ideal_xyz b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/002_prep_ideal_case/run_prep_ideal_xyz
new file mode 100755
index 0000000000000000000000000000000000000000..cc04c8357ad94625ece1e7492b5d68fdb8caad26
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/002_prep_ideal_case/run_prep_ideal_xyz
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+NP=${NP:-16}
+NPS=${NPS:-4}
+
+export ACC_DEVICE_TYPE=HOST
+export MPIRUN="Mpirun -tag-output -report-bindings --mca mpi_cuda_support 0 -map-by ppr:${NPS}:socket -bind-to none -np ${NP} set_core_device_impair"
+
+#
+set -x
+set -e
+#
+rm -f OUTPUT_LISTING1 pipe_name file_for_xtransfer
+rm -f PGD00128.*
+rm -f DA0128.*
+#
+ln -sf ../001_pgd1/PGD00128.* .
+#
+time ${MPIRUN} PREP_IDEAL_CASE${XYZ}
+#
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/003_mesonh_step1/EXSEG1.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/003_mesonh_step1/EXSEG1.nam
new file mode 100644
index 0000000000000000000000000000000000000000..cbfeca7d31195ad0c0dfbc8ba72acc279b1083f4
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/003_mesonh_step1/EXSEG1.nam
@@ -0,0 +1,53 @@
+&NAM_CONFZ
+ ! NB_PROCIO_R=1 ,
+ ! NB_PROCIO_W=1 ,
+ ! LMNH_MPI_BSEND = T ,
+ ! MPI_BUFFER_SIZE = 40
+/
+
+&NAM_LUNITn  CINIFILE = "DA0128" , CINIFILEPGD = "PGD00128" /
+&NAM_CONFn  LUSERV = T, LUSERC = T, LUSERR = T, LUSERI = T,
+            LUSERS = T, LUSERG = T, LUSERH = F, LUSECI = T /
+&NAM_DYNn  XTSTEP = 15.00000 , 
+           CPRESOPT = "ZRESI", NITR = 12
+           !CPRESOPT = "ZSOLV", NITR = 12
+           XRELAX = 1., LHORELAX_UVWTH = T, LHORELAX_RV = T, LVE_RELAX = T,
+           NRIMX = 6, NRIMY = 6, XRIMKMAX = 0.0005, XT4DIFU =  4000 /
+&NAM_ADVn  CUVW_ADV_SCHEME = "WENO_K", CMET_ADV_SCHEME = "PPM_01",
+           CSV_ADV_SCHEME = "PPM_01" /
+&NAM_PARAMn  CTURB = "TKEL" ! "NONE" ! "TKEL", 
+             CRAD = "ECMW", 
+             CCLOUD = "ICE3" ! "NONE" ! "ICE3",
+             CDCONV = "NONE", CSCONV = "NONE" /
+&NAM_PARAM_RADn  XDTRAD = 1800., XDTRAD_CLONLY = 1800., LCLEAR_SKY = F,
+                 NRAD_COLNBR = 500 /
+&NAM_PARAM_MFSHALLn XIMPL_MF = 1, CMF_UPDRAFT = "EDKF", CMF_CLOUD = "NONE",
+                    LMIXUV = T, LMF_FLX = F /
+&NAM_LBCn  CLBCX = 2*"OPEN", CLBCY = 2*"OPEN", XCPHASE = 20. /
+&NAM_TURBn  XIMPL = 1., CTURBLEN = "DEAR", CTURBDIM = "3DIM",
+            LTURB_FLX = F, LTURB_DIAG = F, CSUBG_AUCV = "NONE", LSIGMAS = F,
+            LSIG_CONV = F,  LSUBG_COND = F /
+&NAM_CH_MNHCn /
+&NAM_CONF  CCONF = "START",  LFLAT = F, CEQNSYS = "DUR",
+           LLG=F, NMODEL = 1, NVERB = 0, CEXP = "D0128",
+           CSEG = "DAR01", CSPLIT = "BSPLITTING" 
+           NHALO=1
+           /
+&NAM_DYN  XSEGLEN =  14400.0000 ! 150. ! 14400.0000 , LCORIO = T,
+          LNUMDIFU = F, LNUMDIFTH = F,
+          XALKTOP = 0.001, XALZBOT = 22000. /
+&NAM_BLANK /
+&NAM_NESTING /
+&NAM_BACKUP
+ XBAK_TIME(1,1) = 3600.00000 ! 150. ! 3600.00000
+ XBAK_TIME(1,2) = 7200.00000
+ XBAK_TIME(1,3) = 10800.0000
+ XBAK_TIME(1,4) = 14400.0000
+ XBAK_TIME(1,5) = 18000.0000
+ XBAK_TIME(1,6) = 21600.0000
+ /
+&NAM_ISBAn /
+&NAM_SEAFLUXn /
+&NAM_DIAG_SURFn LSURF_BUDGET=T /
+&NAM_DIAG_ISBAn /
+&NAM_DIAG_SURF_ATMn /
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/003_mesonh_step1/parameters_mg.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/003_mesonh_step1/parameters_mg.nam
new file mode 100644
index 0000000000000000000000000000000000000000..5d76f4dff351b9c8873c37072d3f1f0747877d70
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/003_mesonh_step1/parameters_mg.nam
@@ -0,0 +1,118 @@
+! *********************************************************************
+! *********************************************************************
+! **                                                                 **
+! **    Parameter file for geometric multigrid code                  **
+! **                                                                 **
+! *********************************************************************
+! *********************************************************************
+!
+! *********************************************************************
+! * General parameters
+! *********************************************************************
+&parameters_general
+  savefields = .F.              ! Save fields to disk?
+/
+
+! *********************************************************************
+! * General solver parameters
+! *********************************************************************
+&parameters_solver
+  LUseO = F ,
+  LUseT = T ,
+  solvertype = 1,            ! Solver type:
+                             !   1 : Richardson iteration
+                             !   2 : Conjugate gradient
+  resreduction = 1e-1 ! 1.0d-10  ! Required relative residual reduction
+  maxiter = 5 ! 50               ! Maximal number of iterations
+/
+
+! *********************************************************************
+! * Conjugate gradient parameters
+! *********************************************************************
+&parameters_conjugategradient
+  verbose = 10,                  ! Verbosity level
+  maxiter = 5,                ! Maximal number of iterations
+  resreduction = 1.0e-1,        ! Target residual reduction
+  n_prec = 1                    ! Number of smoother applications in
+                                ! preconditioner (N.B.: Using 0 is
+                                ! inefficient, as the identity is used
+                                ! for preconditioning, instead of using
+                                ! unpreconditioned CG.)
+/
+
+! *********************************************************************
+! * Grid parameters
+! *********************************************************************
+&parameters_grid
+  n = 128 , ! 64,      ! Number of horizontal grid cells
+  nz = 72,     ! Number of vertical grid cells
+  L = 204800.0 ! 16000.0 metre * 256 pt grille ! 1.0,      ! Size in horizontal direction
+  H =  19200.0 ! 150.0 metre * 128 niveaux ! 0.01,     ! Size in vertical direction
+  vertbc = 2,   ! Boundary conditions at top and bottom of the
+                ! atmosphere. 1 = DIRICHLET, 2 = NEUMANN
+                ! Note that Neumann boundary conditions only work
+                ! for coarsening in the horizontal only, as they are
+                ! not yet implemented in the prolongation operator.
+  graded = .F.  ! Is the grid graded in the vertical direction?
+/
+
+! *********************************************************************
+! * Parallel communication parameters
+! *********************************************************************
+&parameters_communication
+  halo_size = 1  ! Size of halos (has to be 1 or 2)
+/
+
+! *********************************************************************
+! * Model parameters
+! *********************************************************************
+!
+! parameters of the Helmholtz operator
+!
+! -omega2*(d^2/dy^2 + d^2/dy^2 + lambda2*d^2/dz^2) u + delta u = RHS
+!
+&parameters_model
+  omega2 = 1.0,
+  lambda2 = 1.0 ! 100.0,  ! Vertical coupling
+  delta = 0.0d0       ! Size of constant term
+/
+
+! *********************************************************************
+! * Smoother parameters
+! *********************************************************************
+!
+! parameters of the smoother
+!
+&parameters_smoother
+  smoother = 3,                 ! Smoother method
+                                !   3 = line SOR
+                                !   4 = line SSOR
+                                !   6 = line Jacobi
+  ordering = 2,                 ! Ordering of grid points (for smoother)
+
+                                !   1 = lexicographic
+                                !   2 = red-black ordering
+ !rho = 0.6666666666666666d0    ! Overrelaxation parameter
+ rho = 0.8d0    ! Overrelaxation parameter
+/
+
+! *********************************************************************
+! * Multigrid parameters
+! *********************************************************************
+&parameters_multigrid
+  verbose = 10,                  ! Verbosity level
+  n_lev = 8,                    ! Number of levels
+  lev_split = 3,                ! First level where data is pulled together
+  n_presmooth = 1,              ! Number of presmoothing steps
+  n_postsmooth = 1,             ! Number of postsmoothing steps
+  n_coarsegridsmooth = 1,       ! Number of smoothing steps on coarsest level
+  prolongation = 2  ! 2 best after modif !!           ! Prologation method
+                                !   1 = constant interpolation
+                                !   2 = (tri-) linear interpolation
+  restriction = 1,              ! Restriction method
+                                !   1 = cell average
+                                !   2 = Khalil         
+  coarsegridsolver = 1          ! Solver on coarsest grid
+                                !   1 = use smoother
+                                !   2 = Conjugate gradient
+/
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/003_mesonh_step1/run_mesonh_step1_xyz b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/003_mesonh_step1/run_mesonh_step1_xyz
new file mode 100755
index 0000000000000000000000000000000000000000..d676734a931960542ae88ddc28a34cf7a11b509a
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/003_mesonh_step1/run_mesonh_step1_xyz
@@ -0,0 +1,23 @@
+
+
+#export PGI_ACC_POOL_ALLOC=0
+export PGI_ACC_SYNCHRONOUS=1
+
+NP=${NP:-16}
+NPS=${NPS:-4}
+
+export MPIRUN=${MPIRUN:-"Mpirun -tag-output -bind-to none -map-by ppr:${NPS}:socket -x PGI_ACC_POOL_ALLOC -x PGI_ACC_SYNCHRONOUS -np ${NP} set_core_device_impair "}
+
+
+#
+set -x
+set -e
+#
+rm -f DA0128.*
+rm -f PGD00128.*
+rm -f D0128.1.DAR01.* OUTPUT_LISTING* pipe_name
+#
+ln -sf ../001_pgd1/PGD00128.{des,nc} .
+ln -sf ../002_prep_ideal_case/DA0128.{des,nc} .
+#
+time ${MPIRUN} MESONH${XYZ}
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/004_mesonh_step2/EXSEG1.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/004_mesonh_step2/EXSEG1.nam
new file mode 100644
index 0000000000000000000000000000000000000000..f2dcd82899ee955178d92a7bf90d484ac6c78920
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/004_mesonh_step2/EXSEG1.nam
@@ -0,0 +1,59 @@
+&NAM_CONFIO 
+    LIO_ALLOW_NO_BACKUP = T , LIO_NO_WRITE = T 
+/
+&NAM_CONFZ
+ ! NB_PROCIO_R=1 ,
+ ! NB_PROCIO_W=1 ,
+  LMNH_MPI_BSEND = F ,
+ ! MPI_BUFFER_SIZE = 40
+ !NZ_PROC=1
+/
+
+&NAM_LUNITn  CINIFILE = "D0128.1.DAR01.004" , CINIFILEPGD = "PGD00128" /
+&NAM_CONFn  LUSERV = T, LUSERC = T, LUSERR = T, LUSERI = T,
+            LUSERS = T, LUSERG = T, LUSERH = F, LUSECI = T /
+&NAM_DYNn  XTSTEP = 15.00000 , 
+           CPRESOPT = "ZRESI", 
+           !CPRESOPT = "ZSOLV", 
+           NITR = 12,
+           XRELAX = 1., LHORELAX_UVWTH = T, LHORELAX_RV = T, LVE_RELAX = T,
+           NRIMX = 6, NRIMY = 6, XRIMKMAX = 0.0005, XT4DIFU =  4000 /
+&NAM_ADVn  CUVW_ADV_SCHEME = "WENO_K", CMET_ADV_SCHEME = "PPM_01",
+           CSV_ADV_SCHEME = "PPM_01" /
+&NAM_PARAMn  CTURB = "TKEL", ! "NONE" , ! "TKEL", 
+             CRAD = "ECMWF",
+	     CCLOUD = "ICE3", ! "NONE" , ! "ICE3",
+             CDCONV = "NONE", CSCONV = "NONE" /
+&NAM_PARAM_RADn  XDTRAD = 1800., XDTRAD_CLONLY = 1800., LCLEAR_SKY = F,
+                 NRAD_COLNBR = 500 /
+&NAM_PARAM_MFSHALLn XIMPL_MF = 1, CMF_UPDRAFT = "EDKF", CMF_CLOUD = "NONE",
+                    LMIXUV = T, LMF_FLX = F /
+&NAM_LBCn  CLBCX = 2*"OPEN", CLBCY = 2*"OPEN", XCPHASE = 20. /
+&NAM_TURBn  XIMPL = 1., CTURBLEN = "DEAR", CTURBDIM = "3DIM",
+            LTURB_FLX = F, LTURB_DIAG = F, CSUBG_AUCV = "NONE", LSIGMAS = F,
+            LSIG_CONV = F,  LSUBG_COND = F /
+&NAM_CH_MNHCn /
+&NAM_CONF  CCONF = "RESTA",  LFLAT = F, CEQNSYS = "DUR",
+           LLG=F, NMODEL = 1, NVERB = 0, CEXP = "D0128",
+           CSEG = "DAR02", CSPLIT = "BSPLITTING" 
+           NHALO=1 
+           LCHECK = F /
+&NAM_DYN  XSEGLEN = 150.0 ! 150.0000 , 
+          LCORIO = T,
+          LNUMDIFU = F, LNUMDIFTH = F,
+          XALKTOP = 0.001, XALZBOT = 22000. /
+&NAM_BLANK /
+&NAM_NESTING /
+&NAM_BACKUP
+ XBAK_TIME(1,1) = 150.0 ! 3600.00000 ! 75. ! 3600.00000
+ XBAK_TIME(1,2) = 7200.00000
+ XBAK_TIME(1,3) = 10800.0000
+ XBAK_TIME(1,4) = 14400.0000
+ XBAK_TIME(1,5) = 18000.0000
+ XBAK_TIME(1,6) = 21600.0000
+ /
+&NAM_ISBAn /
+&NAM_SEAFLUXn /
+&NAM_DIAG_SURFn LSURF_BUDGET=T /
+&NAM_DIAG_ISBAn /
+&NAM_DIAG_SURF_ATMn /
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/004_mesonh_step2/MESONH_HOST2005 b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/004_mesonh_step2/MESONH_HOST2005
new file mode 100755
index 0000000000000000000000000000000000000000..07ad9fb226bfd7e7cc764749cb644e595ee25b13
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/004_mesonh_step2/MESONH_HOST2005
@@ -0,0 +1,5 @@
+#!/bin/bash
+export ACC_DEVICE=HOST
+ACC_DEVICE_TYPE=${ACC_DEVICE}
+exec /home/escj/DEV/MNH-55X-dev-OPENACC-juan-03/src/dir_obj-LXnvhpc2005-R8I4-MNH-V5-4-2-MPIAUTO-${OPTLEVEL}/ZSOLVER/MESONH
+
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/004_mesonh_step2/mppdb.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/004_mesonh_step2/mppdb.nam
new file mode 100644
index 0000000000000000000000000000000000000000..39cb2adaff74600f63d7f252fc0a4429c9c2b67d
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/004_mesonh_step2/mppdb.nam
@@ -0,0 +1,7 @@
+&NAM_MPPDB
+MPPDB_DEBUG = .F. ,
+MPPDB_NBSON = 1 ,
+MPPDB_EXEC = "/home/escj/DEV/MNH-55X-dev-OPENACC-juan-03/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/004_mesonh_step2/MESONH_HOST2005" ,
+MPPDB_WDIR = "/home/escj/DEV/MNH-55X-dev-OPENACC-juan-03/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/004_mesonh_step2/dir_clone" ,
+MPPDB_CHECK_LB = .F. 
+/ 
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/004_mesonh_step2/parameters_mg.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/004_mesonh_step2/parameters_mg.nam
new file mode 100644
index 0000000000000000000000000000000000000000..5d76f4dff351b9c8873c37072d3f1f0747877d70
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/004_mesonh_step2/parameters_mg.nam
@@ -0,0 +1,118 @@
+! *********************************************************************
+! *********************************************************************
+! **                                                                 **
+! **    Parameter file for geometric multigrid code                  **
+! **                                                                 **
+! *********************************************************************
+! *********************************************************************
+!
+! *********************************************************************
+! * General parameters
+! *********************************************************************
+&parameters_general
+  savefields = .F.              ! Save fields to disk?
+/
+
+! *********************************************************************
+! * General solver parameters
+! *********************************************************************
+&parameters_solver
+  LUseO = F ,
+  LUseT = T ,
+  solvertype = 1,            ! Solver type:
+                             !   1 : Richardson iteration
+                             !   2 : Conjugate gradient
+  resreduction = 1e-1 ! 1.0d-10  ! Required relative residual reduction
+  maxiter = 5 ! 50               ! Maximal number of iterations
+/
+
+! *********************************************************************
+! * Conjugate gradient parameters
+! *********************************************************************
+&parameters_conjugategradient
+  verbose = 10,                  ! Verbosity level
+  maxiter = 5,                ! Maximal number of iterations
+  resreduction = 1.0e-1,        ! Target residual reduction
+  n_prec = 1                    ! Number of smoother applications in
+                                ! preconditioner (N.B.: Using 0 is
+                                ! inefficient, as the identity is used
+                                ! for preconditioning, instead of using
+                                ! unpreconditioned CG.)
+/
+
+! *********************************************************************
+! * Grid parameters
+! *********************************************************************
+&parameters_grid
+  n = 128 , ! 64,      ! Number of horizontal grid cells
+  nz = 72,     ! Number of vertical grid cells
+  L = 204800.0 ! 16000.0 metre * 256 pt grille ! 1.0,      ! Size in horizontal direction
+  H =  19200.0 ! 150.0 metre * 128 niveaux ! 0.01,     ! Size in vertical direction
+  vertbc = 2,   ! Boundary conditions at top and bottom of the
+                ! atmosphere. 1 = DIRICHLET, 2 = NEUMANN
+                ! Note that Neumann boundary conditions only work
+                ! for coarsening in the horizontal only, as they are
+                ! not yet implemented in the prolongation operator.
+  graded = .F.  ! Is the grid graded in the vertical direction?
+/
+
+! *********************************************************************
+! * Parallel communication parameters
+! *********************************************************************
+&parameters_communication
+  halo_size = 1  ! Size of halos (has to be 1 or 2)
+/
+
+! *********************************************************************
+! * Model parameters
+! *********************************************************************
+!
+! parameters of the Helmholtz operator
+!
+! -omega2*(d^2/dy^2 + d^2/dy^2 + lambda2*d^2/dz^2) u + delta u = RHS
+!
+&parameters_model
+  omega2 = 1.0,
+  lambda2 = 1.0 ! 100.0,  ! Vertical coupling
+  delta = 0.0d0       ! Size of constant term
+/
+
+! *********************************************************************
+! * Smoother parameters
+! *********************************************************************
+!
+! parameters of the smoother
+!
+&parameters_smoother
+  smoother = 3,                 ! Smoother method
+                                !   3 = line SOR
+                                !   4 = line SSOR
+                                !   6 = line Jacobi
+  ordering = 2,                 ! Ordering of grid points (for smoother)
+
+                                !   1 = lexicographic
+                                !   2 = red-black ordering
+ !rho = 0.6666666666666666d0    ! Overrelaxation parameter
+ rho = 0.8d0    ! Overrelaxation parameter
+/
+
+! *********************************************************************
+! * Multigrid parameters
+! *********************************************************************
+&parameters_multigrid
+  verbose = 10,                  ! Verbosity level
+  n_lev = 8,                    ! Number of levels
+  lev_split = 3,                ! First level where data is pulled together
+  n_presmooth = 1,              ! Number of presmoothing steps
+  n_postsmooth = 1,             ! Number of postsmoothing steps
+  n_coarsegridsmooth = 1,       ! Number of smoothing steps on coarsest level
+  prolongation = 2  ! 2 best after modif !!           ! Prologation method
+                                !   1 = constant interpolation
+                                !   2 = (tri-) linear interpolation
+  restriction = 1,              ! Restriction method
+                                !   1 = cell average
+                                !   2 = Khalil         
+  coarsegridsolver = 1          ! Solver on coarsest grid
+                                !   1 = use smoother
+                                !   2 = Conjugate gradient
+/
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/004_mesonh_step2/run_mesonh_step2_xyz b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/004_mesonh_step2/run_mesonh_step2_xyz
new file mode 100755
index 0000000000000000000000000000000000000000..03470ed7a719790e446b249af6d459944b6f46f4
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/004_mesonh_step2/run_mesonh_step2_xyz
@@ -0,0 +1,26 @@
+#!/bin/bash
+#
+#
+set -x
+
+#export PGI_ACC_POOL_ALLOC=0
+export PGI_ACC_SYNCHRONOUS=1
+#export NVCOMPILER_ACC_POOL_ALLOC=0
+
+NP=${NP:-16}
+NPS=${NPS:-4}
+
+export MPIRUN=${MPIRUN:-"Mpirun -tag-output -report-bindings -bind-to none -map-by ppr:${NPS}:socket -x NVCOMPILER_ACC_POOL_ALLOC_MAXSIZE -x NVCOMPILER_ACC_POOL_ALLOC  -x PGI_ACC_POOL_ALLOC -x PGI_ACC_SYNCHRONOUS -np ${NP} set_core_device_impair "}
+
+rm -f DA0128.*
+rm -f PGD00128.*
+rm -f D0128.1.DAR0?.* OUTPUT_LISTING1 pipe_name
+#
+ln -sf ../001_pgd1/PGD00128.* .
+ln -sf ../002_prep_ideal_case/DA0128.* .
+ln -sf ../003_mesonh_step1/D0128.1.DAR0?.* .
+#
+
+time ${MPIRUN} MESONH${XYZ}
+
+
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/004_mesonh_step2/run_mesonh_step2_xyz_mppdb b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/004_mesonh_step2/run_mesonh_step2_xyz_mppdb
new file mode 100755
index 0000000000000000000000000000000000000000..cd0f51b0bbd9e31776fa4e1cdb6abfbdb977a7f9
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/004_mesonh_step2/run_mesonh_step2_xyz_mppdb
@@ -0,0 +1,48 @@
+#!/bin/bash
+#
+#
+ 
+set -x
+DIRCLONE=dir_clone
+mkdir -p ${DIRCLONE}
+
+export PGI_ACC_POOL_ALLOC=0
+#export PGI_ACC_POOL_SIZE=100MB
+
+export NP=${NP:-1}
+
+export MPIRUN=${MPIRUN:-Mpirun -tag-output -np ${NP}}
+
+#export PGI_ACC_NOTIFY=$(( 1+2+4+8+16+32 )) PGI_ACC_DEBUG=$(( 1+2+4+8+16+32 )) 
+#export PGI_ACC_TIME=1
+
+export PGI_ACC_SYNCHRONOUS=1
+
+(
+cd  ${DIRCLONE}
+#
+rm -f DA0128.*
+rm -f PGD00128.*
+rm -f D0128.1.DAR0?.* OUTPUT_LISTING1 pipe_name
+#
+cp ../EXSEG1.nam .
+ln -sf ../../001_pgd1/PGD00128.* .
+ln -sf ../../002_prep_ideal_case/DA0128.* .
+ln -sf ../../003_mesonh_step1/D0128.1.DAR01.* .
+#
+)
+
+#
+rm -f DA0128.*
+rm -f PGD00128.*
+rm -f D0128.1.DAR0?.* OUTPUT_LISTING1 pipe_name
+#
+ln -sf ../001_pgd1/PGD00128.* .
+ln -sf ../002_prep_ideal_case/DA0128.* .
+ln -sf ../003_mesonh_step1/D0128.1.DAR0?.* .
+#
+
+killall -r 'MESONH.*'
+time ${MPIRUN} MESONH${XYZ}
+
+
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/005_mg_main_mnh_all/parameters_mg.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/005_mg_main_mnh_all/parameters_mg.nam
new file mode 120000
index 0000000000000000000000000000000000000000..adeab0e1859deb44804ccc14f23c2ccb35775079
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/005_mg_main_mnh_all/parameters_mg.nam
@@ -0,0 +1 @@
+../004_mesonh_step2/parameters_mg.nam
\ No newline at end of file
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/005_mg_main_mnh_all/run_mg_main_mnh_all_xyz b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/005_mg_main_mnh_all/run_mg_main_mnh_all_xyz
new file mode 100755
index 0000000000000000000000000000000000000000..c3694f2de5a11d8600af4cf5874b3248c26057f4
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_128x128_MNH-55X/005_mg_main_mnh_all/run_mg_main_mnh_all_xyz
@@ -0,0 +1,18 @@
+#!/bin/bash
+#
+#
+set -x
+
+#export PGI_ACC_POOL_ALLOC=0
+export PGI_ACC_SYNCHRONOUS=1
+#export NVCOMPILER_ACC_POOL_ALLOC=0
+
+NP=${NP:-16}
+NPS=${NPS:-4}
+
+export MPIRUN=${MPIRUN:-"Mpirun -tag-output -report-bindings -bind-to none -map-by ppr:${NPS}:socket -x NVCOMPILER_ACC_POOL_ALLOC_MAXSIZE -x NVCOMPILER_ACC_POOL_ALLOC  -x PGI_ACC_POOL_ALLOC -x PGI_ACC_SYNCHRONOUS -np ${NP} set_core_device_impair "}
+
+
+time ${MPIRUN} MG_MAIN_MNH_ALL${XYZ}
+
+
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/001_pgd1/PRE_PGD1.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/001_pgd1/PRE_PGD1.nam
new file mode 100644
index 0000000000000000000000000000000000000000..a7edb249a9cc07b565c80de0c7b74d6a9528e220
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/001_pgd1/PRE_PGD1.nam
@@ -0,0 +1,13 @@
+&NAM_CONFZ
+ NB_PROCIO_W=1 ,
+ !MPI_BUFFER_SIZE=40
+/
+&NAM_PGDFILE CPGDFILE="PGD00256" /
+&NAM_PGD_SCHEMES CNATURE='ISBA', CSEA='SEAFLX', CTOWN='NONE', CWATER='NONE' /
+&NAM_CONF_PROJ XLAT0=-11.5, XLON0=130.7, XRPK=0., XBETA=0. /
+&NAM_CONF_PROJ_GRID XLATCEN=-11.5, XLONCEN=130.7, NIMAX=256, NJMAX=256,
+                    XDX=800.00000, XDY=800.00000 /
+&NAM_COVER     YCOVER='ECOCLIMAP_v2.0', YCOVERFILETYPE='DIRECT' /
+&NAM_ZS        YZS='gtopo30', YZSFILETYPE='DIRECT' /
+&NAM_ISBA  YCLAY='CLAY_HWSD_MOY', YCLAYFILETYPE='DIRECT',
+           YSAND='SAND_HWSD_MOY', YSANDFILETYPE='DIRECT' /
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/001_pgd1/get_pgd_files b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/001_pgd1/get_pgd_files
new file mode 100755
index 0000000000000000000000000000000000000000..56726933a0f7608e0c4918f42e80d5aea76b669d
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/001_pgd1/get_pgd_files
@@ -0,0 +1,30 @@
+#
+#     Modif
+#     J.Escobar 11/04/2014 get PGD files from 'dir_open' directory ( without psswd )
+#     J.Escobar 25/04/2013 get LICENCE files
+#
+PREP_PGD_FILES=${PREP_PGD_FILES:-"$HOME/PREP_PGD_FILES_WWW"} ; export PREP_PGD_FILES
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo "!!!!            WARNING                  !!!!"
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo 
+echo you need 3GO to download this files in
+echo 
+echo PREP_PGD_FILES=$PREP_PGD_FILES  
+echo 
+echo if OK press ENTER  else CTRL-C
+read RIEN
+set -x
+mkdir -p $PREP_PGD_FILES
+cd $PREP_PGD_FILES
+PGD_URL="http://mesonh.aero.obs-mip.fr/mesonh/dir_open/dir_PGDFILES"
+WGET="wget"
+export PGD_URL
+for file in LICENSE_ECOCLIMAP.txt LICENSE_soil_data.txt \
+            gtopo30.dir gtopo30.hdr \
+            SAND_HWSD_MOY.hdr SAND_HWSD_MOY.dir CLAY_HWSD_MOY.hdr CLAY_HWSD_MOY.dir \
+            ECOCLIMAP_v2.0.hdr ECOCLIMAP_v2.0.dir
+do
+[ -f $file ] || ( ${WGET} -c -nd $PGD_URL/$file.gz ; gunzip $file.gz ; ) 
+done
+
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/001_pgd1/run_prep_pgd_xyz b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/001_pgd1/run_prep_pgd_xyz
new file mode 100755
index 0000000000000000000000000000000000000000..c4b8da5bf37afca5b11f863c02bd21ae92cd9ea0
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/001_pgd1/run_prep_pgd_xyz
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+export ACC_DEVICE_TYPE=HOST
+export MPIRUN="Mpirun -tag-output -report-bindings -bind-to none -np 4 set_core_device_impair "
+
+
+PREP_PGD_FILES=${PREP_PGD_FILES:-"$HOME/PREP_PGD_FILES_WWW"} ; export PREP_PGD_FILES
+#
+if [ ! -d $PREP_PGD_FILES ]
+then
+cat << EOF
+
+Your directory  PREP_PGD_FILES=$PREP_PGD_FILES
+
+containing the files gtopo30*, ECOCLIMAP_v2.0* 
+doesn't exist ( or was not found !!! )
+use the script 'get_pgd_files' to download 
+this files from the MESONH WEB PAGES !!!
+( or change the variable PREP_PGD_FILES ... )
+
+After fixing it , run this script again !!!
+ 
+EOF
+exit 1
+else
+set -x 
+#
+rm -f OUTPUT_LISTING0 pipe_name
+rm -f gtopo30.???  sand_fao.???  clay_fao.???
+rm -f SAND_HWSD_MOY.??? ECOCLIMAP_v2.0.??? ecoclimats_v2.???
+rm -f PGD00256.*
+#
+ln -sf $PREP_PGD_FILES/*.dir $PREP_PGD_FILES/*.hdr .
+#
+time ${MPIRUN} PREP_PGD${XYZ}
+fi
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/002_prep_ideal_case/PRE_IDEA1.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/002_prep_ideal_case/PRE_IDEA1.nam
new file mode 100644
index 0000000000000000000000000000000000000000..0f9bb438c273171b5f5d94e36e1c2a51e42f29a0
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/002_prep_ideal_case/PRE_IDEA1.nam
@@ -0,0 +1,226 @@
+&NAM_CONFZ
+ !NB_PROCIO_R=1 ,
+ !NB_PROCIO_W=1 ,
+ !MPI_BUFFER_SIZE=40
+/
+
+&NAM_REAL_PGD
+            CPGD_FILE ="PGD00256" ,
+            LREAD_ZS =.TRUE., LREAD_GROUND_PARAM =.TRUE.
+/
+&NAM_DIMn_PRE NIMAX=40, NJMAX=32 /
+&NAM_CONF_PRE LCARTESIAN=.FALSE.
+              CIDEAL='RSOU' CZS='FLAT'
+              NVERB=0 /
+&NAM_CONFn LUSERV= T /
+&NAM_LUNITn CINIFILE = "DA0256" , CINIFILEPGD = "PGD00256" /
+&NAM_DYNn_PRE
+  CPRESOPT= 'ZRESI' ,
+  NITR=4 XRELAX=1. /
+&NAM_LBCn_PRE CLBCX= 2*'OPEN' CLBCY= 2*'OPEN' /
+&NAM_VPROF_PRE CTYPELOC='IJGRID' NILOC=1 NJLOC=1
+               CFUNU='ZZZ' CFUNV='ZZZ'
+               LGEOSBAL=.FALSE. /
+&NAM_VER_GRID NKMAX=126, YZGRID_TYPE='FUNCTN',
+       ZDZGRD=40., ZDZTOP=210., ZZMAX_STRGRD=2500.,
+       ZSTRGRD=7., ZSTRTOP=7. /
+&NAM_GRn_PRE
+   CSURF='EXTE'
+   ! CSURF='NONE'
+  /
+&NAM_PREP_ISBA XTG_SURF= 311., XTG_ROOT= 303., XTG_DEEP= 302.,
+               XHUG_SURF= 0.16, XHUG_ROOT= 0.16, XHUG_DEEP= 0.16 /
+&NAM_PREP_SEAFLUX XSST_UNIF= 304. /
+  RSOU
+ 2005 11 30 0
+ 'PUVTHDMR'
+  0.0000000E+00
+   100300.0    
+   303.3000    
+  1.9630000E-02
+          92
+   100000.0       3.637668      -3.637668    
+   99900.00       2.572220      -4.455216    
+   99100.00      -4.612377      0.4035313    
+   96600.00       5.124864     -0.4483674    
+   93000.00       5.836996      -2.009839    
+   92800.00       5.801031      -2.111402    
+   92500.00       5.466062      -1.464627    
+   85000.00      0.1345103      -1.537459    
+   81400.00     -0.9020693      -1.849517    
+   71800.00      -2.797467       1.304481    
+   70000.00      -4.472232       1.198331    
+   60500.00      -3.289776      -1.464702    
+   59900.00      -3.208611      -1.634869    
+   56900.00      -2.329535      -2.025034    
+   55600.00      -2.105100      -2.257443    
+   50100.00     -0.5325915      -1.987659    
+   50000.00     -0.2679967      -1.519885    
+   49500.00      0.2507798      -2.042438    
+   46700.00       5.466062       1.464627    
+   45300.00       5.594935       2.608961    
+   44800.00       5.450725       2.898202    
+   43700.00       4.994327       3.628591    
+   42200.00       4.561049       4.891127    
+   41900.00       4.387573       5.047325    
+   41800.00       4.298817       5.123130    
+   40000.00       6.305391       5.290851    
+   39000.00       5.970908       4.027428    
+   38600.00       5.671552       3.543979    
+   38300.00       5.346259       3.086664    
+   35500.00       2.976104       3.546782    
+   32700.00       4.455215       2.572220    
+   31400.00       3.712562       4.270814    
+   30700.00       3.086664       5.346259    
+   30000.00       3.540875       5.056894    
+   28800.00       3.786532       4.205370    
+   26700.00       3.329551       2.419061    
+   25000.00       2.797467       1.304481    
+   24400.00       2.819808       1.255459    
+   23800.00       2.841289       1.206056    
+   21400.00       3.424857       1.112804    
+   20000.00       3.478403      0.9320353    
+   19300.00       3.383935       1.231651    
+   17400.00       3.411947       2.301387    
+   15000.00       2.950729       4.214078    
+   12700.00       2.167201       2.875973    
+   10200.00       1.322713       1.576348    
+   10000.00      0.4466614       2.533142    
+   9120.000      -3.306782       3.940869    
+   8700.000      -7.950636       2.130367    
+   8200.000      -8.712269      0.7622259    
+   8000.000      -9.224754     -0.8070621    
+   7600.000      -4.009694      -2.314998    
+   7300.000      -5.066284     -0.8933228    
+   7000.000      -4.196201      -1.956721    
+   6700.000      -1.013257      0.1786647    
+   6400.000      -2.107039       1.475365    
+   6340.000      -2.558960       1.726041    
+   5480.000      -13.17234       2.322640    
+   5300.000      -15.37459       1.345105    
+   5000.000      -12.81216      -1.120920    
+   4900.000      -12.66571      -2.233307    
+   4860.000      -12.25463      -1.504677    
+   4700.000      -10.76221      0.9415731    
+   4500.000      -11.37801       7.966970    
+   3800.000      -25.11183       2.197004    
+   3600.000      -22.54940      -1.972818    
+   3200.000      -22.72465      -4.417223    
+   3000.000      -22.36116      -5.991656    
+   2490.000      -21.48829      -2.258509    
+   2300.000      -21.07936     -0.7361050    
+   2200.000      -20.57776     -1.7989648E-06
+   2080.000      -19.00834     -0.9961855    
+   2000.000      -17.93702      -1.569287    
+   1600.000      -14.74927      -10.32755    
+   1500.000      -13.52109      -6.304989    
+   1430.000      -16.89510      -4.527030    
+   1400.000      -18.23862      -3.215962    
+   1300.000      -15.46941      -5.630407    
+   1200.000      -5.594935       2.608962    
+   1190.000      -5.671552       3.543979    
+   1100.000       1.786646       10.13257    
+   1050.000      -3.736842       7.333968    
+   1020.000      -5.435582       4.725079    
+   1000.000      -5.594935       2.608962    
+   950.0000      -4.347303       8.176087    
+   900.0000       2.143975       12.15908    
+   889.9999       1.031246       11.78719    
+   800.0000      -4.728969       4.728969    
+   760.0000       2.890712       7.154763    
+   710.0000       8.644947      -3.318484    
+   700.0000       7.487652      -6.282886    
+   600.0000      -4.214078      -2.950729    
+          91
+   100000.0       303.1000      1.8050000E-02
+   99900.00       303.1000      1.8040001E-02
+   99100.00       303.1000      1.7969999E-02
+   96600.00       303.1000      1.7729999E-02
+   93000.00       303.0000      1.7370002E-02
+   92800.00       303.1000      1.6980000E-02
+   92500.00       303.2000      1.6400000E-02
+   85000.00       307.1000      1.1190000E-02
+   81400.00       309.6000      6.6700005E-03
+   71800.00       312.3000      6.5600001E-03
+   70000.00       312.9000      6.5400004E-03
+   60500.00       316.2000      6.1800000E-03
+   59900.00       318.1000      5.3400006E-03
+   56900.00       318.7000      4.9899998E-03
+   55600.00       322.2000      3.3100001E-03
+   50100.00       325.5000      2.6000000E-03
+   50000.00       325.5000      2.5800001E-03
+   49500.00       325.7000      3.1700002E-03
+   46700.00       328.6000      1.4500001E-03
+   45300.00       330.1000      9.4000006E-04
+   44800.00       330.1000      1.9600000E-03
+   43700.00       331.0000      2.1500003E-03
+   42200.00       332.2000      1.9400001E-03
+   41900.00       332.9000      9.6000003E-04
+   41800.00       333.0000      9.7000005E-04
+   40000.00       334.2000      1.1600000E-03
+   39000.00       334.6000      1.0300000E-03
+   38600.00       335.6000      6.5000000E-04
+   38300.00       335.8000      6.0000003E-04
+   35500.00       338.2000      2.5000001E-04
+   32700.00       340.8000      9.0000009E-05
+   31400.00       342.0000      5.0000002E-05
+   30700.00       342.1000      4.0000003E-05
+   30000.00       342.3000      4.0000003E-05
+   28800.00       342.3000      1.2000000E-04
+   26700.00       344.8000      1.0000001E-05
+   25000.00       345.4000      1.0000001E-05
+   24400.00       346.3000      2.0000001E-05
+   23800.00       346.4000      9.0000009E-05
+   21400.00       348.1000      1.0000001E-05
+   20000.00       348.8000      1.0000001E-05
+   19300.00       348.9000      2.0000001E-05
+   17400.00       351.5000      1.0000001E-05
+   15000.00       354.0000      7.1596442E-06
+   12700.00       355.7000      4.4376361E-06
+   10200.00       364.6000      1.4789329E-06
+   10000.00       365.4000      1.2422363E-06
+   9120.000       371.6000      1.2919259E-06
+   8700.000       379.9000      1.5496893E-06
+   8200.000       390.6000      1.8819877E-06
+   8000.000       395.1000      2.0217396E-06
+   7600.000       404.7000      2.3198761E-06
+   7300.000       412.3000      2.4844724E-06
+   7000.000       420.4000      2.4844724E-06
+   6700.000       431.1000      2.4844724E-06
+   6400.000       442.4000      2.4844724E-06
+   6340.000       444.8000      2.4844724E-06
+   5480.000       467.8000      2.4844724E-06
+   5300.000       471.0000      2.4844724E-06
+   5000.000       476.5000      2.4844724E-06
+   4900.000       477.6000      2.4844724E-06
+   4860.000       478.0000      2.4844724E-06
+   4700.000       485.1000      2.4844724E-06
+   4500.000       494.6000      2.4844724E-06
+   3800.000       532.9000      2.4844724E-06
+   3600.000       545.6000      2.4844724E-06
+   3200.000       574.4000      2.4844724E-06
+   3000.000       585.1000      2.4844724E-06
+   2490.000       624.0000      2.4844724E-06
+   2300.000       648.9000      2.4844724E-06
+   2200.000       655.4000      2.4844724E-06
+   2080.000       663.6000      2.4844724E-06
+   2000.000       673.5000      2.4844724E-06
+   1600.000       726.4000      2.4844724E-06
+   1500.000       742.5000      2.4844724E-06
+   1430.000       750.7000      2.4844724E-06
+   1400.000       759.0000      2.4844724E-06
+   1300.000       788.6000      2.4844724E-06
+   1200.000       821.7000      2.4844724E-06
+   1190.000       825.2000      2.4844724E-06
+   1100.000       833.9000      2.4844724E-06
+   1050.000       839.0000      2.4844724E-06
+   1020.000       845.3000      2.4844724E-06
+   1000.000       851.6000      2.4844724E-06
+   950.0000       877.0000      2.4844724E-06
+   900.0000       885.6000      2.4844724E-06
+   889.9999       887.3000      2.4844724E-06
+   800.0000       926.6000      2.4844724E-06
+   760.0000       946.0000      2.4844724E-06
+   710.0000       958.0000      2.4844724E-06
+   700.0000       963.1000      2.4844724E-06
+   600.0000       20.30000      2.4844724E-06
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/002_prep_ideal_case/run_prep_ideal_xyz b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/002_prep_ideal_case/run_prep_ideal_xyz
new file mode 100755
index 0000000000000000000000000000000000000000..6493fd00e6f6d69c0ec9de8b6588c82c816bd577
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/002_prep_ideal_case/run_prep_ideal_xyz
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+NP=${NP:-16}
+NPS=${NPS:-4}
+
+export ACC_DEVICE_TYPE=HOST
+export MPIRUN="Mpirun -tag-output -report-bindings --mca mpi_cuda_support 0 -map-by ppr:${NPS}:socket -bind-to none -np ${NP} set_core_device_impair"
+
+#
+set -x
+set -e
+#
+rm -f OUTPUT_LISTING1 pipe_name file_for_xtransfer
+rm -f PGD00256.*
+rm -f DA0256.*
+#
+ln -sf ../001_pgd1/PGD00256.* .
+#
+time ${MPIRUN} PREP_IDEAL_CASE${XYZ}
+#
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/003_mesonh_step1/EXSEG1.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/003_mesonh_step1/EXSEG1.nam
new file mode 100644
index 0000000000000000000000000000000000000000..1f733b80a6013aaa15ffc2721e7b9076b87bd5b8
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/003_mesonh_step1/EXSEG1.nam
@@ -0,0 +1,53 @@
+&NAM_CONFZ
+ ! NB_PROCIO_R=1 ,
+ ! NB_PROCIO_W=1 ,
+ ! LMNH_MPI_BSEND = T ,
+  MPI_BUFFER_SIZE = 200
+/
+
+&NAM_LUNITn  CINIFILE = "DA0256" , CINIFILEPGD = "PGD00256" /
+&NAM_CONFn  LUSERV = T, LUSERC = T, LUSERR = T, LUSERI = T,
+            LUSERS = T, LUSERG = T, LUSERH = F, LUSECI = T /
+&NAM_DYNn  XTSTEP = 15.00000 , 
+           CPRESOPT = "ZRESI", NITR = 12
+           !CPRESOPT = "ZSOLV", NITR = 12
+           XRELAX = 1., LHORELAX_UVWTH = T, LHORELAX_RV = T, LVE_RELAX = T,
+           NRIMX = 6, NRIMY = 6, XRIMKMAX = 0.0005, XT4DIFU =  4000 /
+&NAM_ADVn  CUVW_ADV_SCHEME = "WENO_K", CMET_ADV_SCHEME = "PPM_01",
+           CSV_ADV_SCHEME = "PPM_01" /
+&NAM_PARAMn  CTURB = "TKEL" ! "NONE" ! "TKEL", 
+             CRAD = "ECMW", 
+             CCLOUD = "ICE3" ! "NONE" ! "ICE3",
+             CDCONV = "NONE", CSCONV = "NONE" /
+&NAM_PARAM_RADn  XDTRAD = 1800., XDTRAD_CLONLY = 1800., LCLEAR_SKY = F,
+                 NRAD_COLNBR = 500 /
+&NAM_PARAM_MFSHALLn XIMPL_MF = 1, CMF_UPDRAFT = "EDKF", CMF_CLOUD = "NONE",
+                    LMIXUV = T, LMF_FLX = F /
+&NAM_LBCn  CLBCX = 2*"OPEN", CLBCY = 2*"OPEN", XCPHASE = 20. /
+&NAM_TURBn  XIMPL = 1., CTURBLEN = "DEAR", CTURBDIM = "3DIM",
+            LTURB_FLX = F, LTURB_DIAG = F, CSUBG_AUCV = "NONE", LSIGMAS = F,
+            LSIG_CONV = F,  LSUBG_COND = F /
+&NAM_CH_MNHCn /
+&NAM_CONF  CCONF = "START",  LFLAT = F, CEQNSYS = "DUR",
+           LLG=F, NMODEL = 1, NVERB = 0, CEXP = "D0256",
+           CSEG = "DAR01", CSPLIT = "BSPLITTING" 
+           NHALO=1
+           /
+&NAM_DYN  XSEGLEN =  14400.0000 ! 21600.0000 ! 150. ! 14400.0000 , LCORIO = T,
+          LNUMDIFU = F, LNUMDIFTH = F,
+          XALKTOP = 0.001, XALZBOT = 22000. /
+&NAM_BLANK /
+&NAM_NESTING /
+&NAM_BACKUP
+ XBAK_TIME(1,1) = 3600.00000 ! 150. ! 3600.00000
+ XBAK_TIME(1,2) = 7200.00000
+ XBAK_TIME(1,3) = 10800.0000
+ XBAK_TIME(1,4) = 14400.0000
+ XBAK_TIME(1,5) = 18000.0000
+ XBAK_TIME(1,6) = 21600.0000
+ /
+&NAM_ISBAn /
+&NAM_SEAFLUXn /
+&NAM_DIAG_SURFn LSURF_BUDGET=T /
+&NAM_DIAG_ISBAn /
+&NAM_DIAG_SURF_ATMn /
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/003_mesonh_step1/parameters_mg.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/003_mesonh_step1/parameters_mg.nam
new file mode 100644
index 0000000000000000000000000000000000000000..209e1d572e4d230aa3a8ad8fd4fc9450a5652197
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/003_mesonh_step1/parameters_mg.nam
@@ -0,0 +1,120 @@
+! *********************************************************************
+! *********************************************************************
+! **                                                                 **
+! **    Parameter file for geometric multigrid code                  **
+! **                                                                 **
+! *********************************************************************
+! *********************************************************************
+!
+! *********************************************************************
+! * General parameters
+! *********************************************************************
+&parameters_general
+  savefields = .F.              ! Save fields to disk?
+/
+
+! *********************************************************************
+! * General solver parameters
+! *********************************************************************
+&parameters_solver
+  LUseO = F ,
+  LUseT = T ,
+  solvertype = 1,            ! Solver type:
+                             !   1 : Richardson iteration
+                             !   2 : Conjugate gradient
+  resreduction = 1e-1 ! 1.0d-15  ! Required relative residual reduction
+  maxiter = 5                ! Maximal number of iterations
+/
+
+! *********************************************************************
+! * Conjugate gradient parameters
+! *********************************************************************
+&parameters_conjugategradient
+  verbose = 10,                  ! Verbosity level
+  maxiter = 5,                ! Maximal number of iterations
+  resreduction = 1.0e-1,        ! Target residual reduction
+  n_prec = 1                    ! Number of smoother applications in
+                                ! preconditioner (N.B.: Using 0 is
+                                ! inefficient, as the identity is used
+                                ! for preconditioning, instead of using
+                                ! unpreconditioned CG.)
+/
+
+! *********************************************************************
+! * Grid parameters
+! *********************************************************************
+&parameters_grid
+  n = 256 , ! 64,      ! Number of horizontal grid cells
+  nz = 128,     ! Number of vertical grid cells
+  L = 204800.0 ! 8000.0 metre * 256 pt grille ! 1.0,      ! Size in horizontal direction
+  H =  19200.0 ! 150.0 metre * 128 niveaux ! 0.01,     ! Size in vertical direction
+  vertbc = 2,   ! Boundary conditions at top and bottom of the
+                ! atmosphere. 1 = DIRICHLET, 2 = NEUMANN
+                ! Note that Neumann boundary conditions only work
+                ! for coarsening in the horizontal only, as they are
+                ! not yet implemented in the prolongation operator.
+  graded = .F.  ! Is the grid graded in the vertical direction?
+/
+
+! *********************************************************************
+! * Parallel communication parameters
+! *********************************************************************
+&parameters_communication
+  halo_size = 1  ! Size of halos (has to be 1 or 2)
+/
+
+! *********************************************************************
+! * Model parameters
+! *********************************************************************
+!
+! parameters of the Helmholtz operator
+!
+! -omega2*(d^2/dy^2 + d^2/dy^2 + lambda2*d^2/dz^2) u + delta u = RHS
+!
+&parameters_model
+  omega2 = 1.0,
+  lambda2 = 1.0 ! 100.0,  ! Vertical coupling
+  delta = 0.0d0       ! Size of constant term
+/
+
+! *********************************************************************
+! * Smoother parameters
+! *********************************************************************
+!
+! parameters of the smoother
+!
+&parameters_smoother
+  smoother = 3,                 ! Smoother method
+                                !   3 = line SOR
+                                !   4 = line SSOR
+                                !   6 = line Jacobi
+  ordering = 2,                 ! Ordering of grid points (for smoother)
+
+                                !   1 = lexicographic
+                                !   2 = red-black ordering
+!  rho = 0.5d0                   ! Overrelaxation parameter
+ !rho = 0.6666666666666666d0    ! Overrelaxation parameter
+ rho = 0.8d0    ! Overrelaxation parameter
+! rho = 1.0d0                   ! Overrelaxation parameter
+/
+
+! *********************************************************************
+! * Multigrid parameters
+! *********************************************************************
+&parameters_multigrid
+  verbose = 10,                  ! Verbosity level
+  n_lev = 9,                    ! Number of levels
+  lev_split = 5,                ! First level where data is pulled together
+  n_presmooth = 1,              ! Number of presmoothing steps
+  n_postsmooth = 1,             ! Number of postsmoothing steps
+  n_coarsegridsmooth = 1,       ! Number of smoothing steps on coarsest level
+  prolongation = 2  ! 2 best after modif !!           ! Prologation method
+                                !   1 = constant interpolation
+                                !   2 = (tri-) linear interpolation
+  restriction = 1,              ! Restriction method
+                                !   1 = cell average
+                                !   2 = Khalil         
+  coarsegridsolver = 1          ! Solver on coarsest grid
+                                !   1 = use smoother
+                                !   2 = Conjugate gradient
+/
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/003_mesonh_step1/run_mesonh_step1_xyz b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/003_mesonh_step1/run_mesonh_step1_xyz
new file mode 100755
index 0000000000000000000000000000000000000000..2526cfb89e68ce8b7e9cb46f87f68aab266c35d4
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/003_mesonh_step1/run_mesonh_step1_xyz
@@ -0,0 +1,23 @@
+
+
+#export PGI_ACC_POOL_ALLOC=0
+export PGI_ACC_SYNCHRONOUS=1
+
+NP=${NP:-16}
+NPS=${NPS:-4}
+
+export MPIRUN=${MPIRUN:-"Mpirun -tag-output  -map-by ppr:${NPS}:socket -bind-to none -x PGI_ACC_POOL_ALLOC -x PGI_ACC_SYNCHRONOUS -np ${NP} set_core_device_impair "}
+
+
+#
+set -x
+set -e
+#
+rm -f DA0256.*
+rm -f PGD00256.*
+rm -f D0256.1.DAR01.* OUTPUT_LISTING* pipe_name
+#
+ln -sf ../001_pgd1/PGD00256.{des,nc} .
+ln -sf ../002_prep_ideal_case/DA0256.{des,nc} .
+#
+time ${MPIRUN} MESONH${XYZ}
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/004_mesonh_step2/EXSEG1.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/004_mesonh_step2/EXSEG1.nam
new file mode 100644
index 0000000000000000000000000000000000000000..c20340edb8d4fd2ba9b4f4b3b6974b72553f674e
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/004_mesonh_step2/EXSEG1.nam
@@ -0,0 +1,59 @@
+&NAM_CONFIO 
+    LIO_ALLOW_NO_BACKUP = T , LIO_NO_WRITE = T 
+/
+&NAM_CONFZ
+ ! NB_PROCIO_R=1 ,
+ ! NB_PROCIO_W=1 ,
+  LMNH_MPI_BSEND = F ,
+ ! MPI_BUFFER_SIZE = 40
+ !NZ_PROC=1
+/
+
+&NAM_LUNITn  CINIFILE = "D0256.1.DAR01.004" , CINIFILEPGD = "PGD00256" /
+&NAM_CONFn  LUSERV = T, LUSERC = T, LUSERR = T, LUSERI = T,
+            LUSERS = T, LUSERG = T, LUSERH = F, LUSECI = T /
+&NAM_DYNn  XTSTEP = 15.00000 , 
+           CPRESOPT = "ZRESI", 
+           !CPRESOPT = "ZSOLV", 
+           NITR = 12,
+           XRELAX = 1., LHORELAX_UVWTH = T, LHORELAX_RV = T, LVE_RELAX = T,
+           NRIMX = 6, NRIMY = 6, XRIMKMAX = 0.0005, XT4DIFU =  4000 /
+&NAM_ADVn  CUVW_ADV_SCHEME = "WENO_K", CMET_ADV_SCHEME = "PPM_01",
+           CSV_ADV_SCHEME = "PPM_01" /
+&NAM_PARAMn  CTURB = "TKEL", ! "NONE" , ! "TKEL", 
+             CRAD = "ECMWF",
+	     CCLOUD = "ICE3", ! "NONE" , ! "ICE3",
+             CDCONV = "NONE", CSCONV = "NONE" /
+&NAM_PARAM_RADn  XDTRAD = 1800., XDTRAD_CLONLY = 1800., LCLEAR_SKY = F,
+                 NRAD_COLNBR = 500 /
+&NAM_PARAM_MFSHALLn XIMPL_MF = 1, CMF_UPDRAFT = "EDKF", CMF_CLOUD = "NONE",
+                    LMIXUV = T, LMF_FLX = F /
+&NAM_LBCn  CLBCX = 2*"OPEN", CLBCY = 2*"OPEN", XCPHASE = 20. /
+&NAM_TURBn  XIMPL = 1., CTURBLEN = "DEAR", CTURBDIM = "3DIM",
+            LTURB_FLX = F, LTURB_DIAG = F, CSUBG_AUCV = "NONE", LSIGMAS = F,
+            LSIG_CONV = F,  LSUBG_COND = F /
+&NAM_CH_MNHCn /
+&NAM_CONF  CCONF = "RESTA",  LFLAT = F, CEQNSYS = "DUR",
+           LLG=F, NMODEL = 1, NVERB = 0, CEXP = "D0256",
+           CSEG = "DAR02", CSPLIT = "BSPLITTING" 
+           NHALO=1 
+           LCHECK = F /
+&NAM_DYN  XSEGLEN = 150.0 ! 150.0000 , 
+          LCORIO = T,
+          LNUMDIFU = F, LNUMDIFTH = F,
+          XALKTOP = 0.001, XALZBOT = 22000. /
+&NAM_BLANK /
+&NAM_NESTING /
+&NAM_BACKUP
+ XBAK_TIME(1,1) = 150.0 ! 3600.00000 ! 75. ! 3600.00000
+ XBAK_TIME(1,2) = 7200.00000
+ XBAK_TIME(1,3) = 10800.0000
+ XBAK_TIME(1,4) = 14400.0000
+ XBAK_TIME(1,5) = 18000.0000
+ XBAK_TIME(1,6) = 21600.0000
+ /
+&NAM_ISBAn /
+&NAM_SEAFLUXn /
+&NAM_DIAG_SURFn LSURF_BUDGET=T /
+&NAM_DIAG_ISBAn /
+&NAM_DIAG_SURF_ATMn /
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/004_mesonh_step2/parameters_mg.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/004_mesonh_step2/parameters_mg.nam
new file mode 100644
index 0000000000000000000000000000000000000000..209e1d572e4d230aa3a8ad8fd4fc9450a5652197
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/004_mesonh_step2/parameters_mg.nam
@@ -0,0 +1,120 @@
+! *********************************************************************
+! *********************************************************************
+! **                                                                 **
+! **    Parameter file for geometric multigrid code                  **
+! **                                                                 **
+! *********************************************************************
+! *********************************************************************
+!
+! *********************************************************************
+! * General parameters
+! *********************************************************************
+&parameters_general
+  savefields = .F.              ! Save fields to disk?
+/
+
+! *********************************************************************
+! * General solver parameters
+! *********************************************************************
+&parameters_solver
+  LUseO = F ,
+  LUseT = T ,
+  solvertype = 1,            ! Solver type:
+                             !   1 : Richardson iteration
+                             !   2 : Conjugate gradient
+  resreduction = 1e-1 ! 1.0d-15  ! Required relative residual reduction
+  maxiter = 5                ! Maximal number of iterations
+/
+
+! *********************************************************************
+! * Conjugate gradient parameters
+! *********************************************************************
+&parameters_conjugategradient
+  verbose = 10,                  ! Verbosity level
+  maxiter = 5,                ! Maximal number of iterations
+  resreduction = 1.0e-1,        ! Target residual reduction
+  n_prec = 1                    ! Number of smoother applications in
+                                ! preconditioner (N.B.: Using 0 is
+                                ! inefficient, as the identity is used
+                                ! for preconditioning, instead of using
+                                ! unpreconditioned CG.)
+/
+
+! *********************************************************************
+! * Grid parameters
+! *********************************************************************
+&parameters_grid
+  n = 256 , ! 64,      ! Number of horizontal grid cells
+  nz = 128,     ! Number of vertical grid cells
+  L = 204800.0 ! 8000.0 metre * 256 pt grille ! 1.0,      ! Size in horizontal direction
+  H =  19200.0 ! 150.0 metre * 128 niveaux ! 0.01,     ! Size in vertical direction
+  vertbc = 2,   ! Boundary conditions at top and bottom of the
+                ! atmosphere. 1 = DIRICHLET, 2 = NEUMANN
+                ! Note that Neumann boundary conditions only work
+                ! for coarsening in the horizontal only, as they are
+                ! not yet implemented in the prolongation operator.
+  graded = .F.  ! Is the grid graded in the vertical direction?
+/
+
+! *********************************************************************
+! * Parallel communication parameters
+! *********************************************************************
+&parameters_communication
+  halo_size = 1  ! Size of halos (has to be 1 or 2)
+/
+
+! *********************************************************************
+! * Model parameters
+! *********************************************************************
+!
+! parameters of the Helmholtz operator
+!
+! -omega2*(d^2/dy^2 + d^2/dy^2 + lambda2*d^2/dz^2) u + delta u = RHS
+!
+&parameters_model
+  omega2 = 1.0,
+  lambda2 = 1.0 ! 100.0,  ! Vertical coupling
+  delta = 0.0d0       ! Size of constant term
+/
+
+! *********************************************************************
+! * Smoother parameters
+! *********************************************************************
+!
+! parameters of the smoother
+!
+&parameters_smoother
+  smoother = 3,                 ! Smoother method
+                                !   3 = line SOR
+                                !   4 = line SSOR
+                                !   6 = line Jacobi
+  ordering = 2,                 ! Ordering of grid points (for smoother)
+
+                                !   1 = lexicographic
+                                !   2 = red-black ordering
+!  rho = 0.5d0                   ! Overrelaxation parameter
+ !rho = 0.6666666666666666d0    ! Overrelaxation parameter
+ rho = 0.8d0    ! Overrelaxation parameter
+! rho = 1.0d0                   ! Overrelaxation parameter
+/
+
+! *********************************************************************
+! * Multigrid parameters
+! *********************************************************************
+&parameters_multigrid
+  verbose = 10,                  ! Verbosity level
+  n_lev = 9,                    ! Number of levels
+  lev_split = 5,                ! First level where data is pulled together
+  n_presmooth = 1,              ! Number of presmoothing steps
+  n_postsmooth = 1,             ! Number of postsmoothing steps
+  n_coarsegridsmooth = 1,       ! Number of smoothing steps on coarsest level
+  prolongation = 2  ! 2 best after modif !!           ! Prologation method
+                                !   1 = constant interpolation
+                                !   2 = (tri-) linear interpolation
+  restriction = 1,              ! Restriction method
+                                !   1 = cell average
+                                !   2 = Khalil         
+  coarsegridsolver = 1          ! Solver on coarsest grid
+                                !   1 = use smoother
+                                !   2 = Conjugate gradient
+/
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/004_mesonh_step2/run_mesonh_step2_xyz b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/004_mesonh_step2/run_mesonh_step2_xyz
new file mode 100755
index 0000000000000000000000000000000000000000..4ed5fb5e7a97f97e04e8be9b56d1e0fbdacb2558
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/004_mesonh_step2/run_mesonh_step2_xyz
@@ -0,0 +1,26 @@
+#!/bin/bash
+#
+#
+set -x
+
+#export PGI_ACC_POOL_ALLOC=0
+export PGI_ACC_SYNCHRONOUS=1
+#export NVCOMPILER_ACC_POOL_ALLOC=0
+
+NP=${NP:-16}
+NPS=${NPS:-4}
+
+export MPIRUN=${MPIRUN:-"Mpirun -tag-output -report-bindings -bind-to none -map-by ppr:${NPS}:socket -x NVCOMPILER_ACC_POOL_ALLOC_MAXSIZE -x NVCOMPILER_ACC_POOL_ALLOC  -x PGI_ACC_POOL_ALLOC -x PGI_ACC_SYNCHRONOUS -np ${NP} set_core_device_impair "}
+
+rm -f DA0256.*
+rm -f PGD00256.*
+rm -f D0256.1.DAR0?.* OUTPUT_LISTING1 pipe_name
+#
+ln -sf ../001_pgd1/PGD00256.* .
+ln -sf ../002_prep_ideal_case/DA0256.* .
+ln -sf ../003_mesonh_step1/D0256.1.DAR0?.* .
+#
+
+time ${MPIRUN} MESONH${XYZ}
+
+
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/005_mg_main_mnh_all/parameters_mg.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/005_mg_main_mnh_all/parameters_mg.nam
new file mode 120000
index 0000000000000000000000000000000000000000..adeab0e1859deb44804ccc14f23c2ccb35775079
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/005_mg_main_mnh_all/parameters_mg.nam
@@ -0,0 +1 @@
+../004_mesonh_step2/parameters_mg.nam
\ No newline at end of file
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/005_mg_main_mnh_all/run_mg_main_mnh_all_xyz b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/005_mg_main_mnh_all/run_mg_main_mnh_all_xyz
new file mode 100755
index 0000000000000000000000000000000000000000..c3694f2de5a11d8600af4cf5874b3248c26057f4
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_256x256_MNH-55X/005_mg_main_mnh_all/run_mg_main_mnh_all_xyz
@@ -0,0 +1,18 @@
+#!/bin/bash
+#
+#
+set -x
+
+#export PGI_ACC_POOL_ALLOC=0
+export PGI_ACC_SYNCHRONOUS=1
+#export NVCOMPILER_ACC_POOL_ALLOC=0
+
+NP=${NP:-16}
+NPS=${NPS:-4}
+
+export MPIRUN=${MPIRUN:-"Mpirun -tag-output -report-bindings -bind-to none -map-by ppr:${NPS}:socket -x NVCOMPILER_ACC_POOL_ALLOC_MAXSIZE -x NVCOMPILER_ACC_POOL_ALLOC  -x PGI_ACC_POOL_ALLOC -x PGI_ACC_SYNCHRONOUS -np ${NP} set_core_device_impair "}
+
+
+time ${MPIRUN} MG_MAIN_MNH_ALL${XYZ}
+
+
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/001_pgd1/PRE_PGD1.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/001_pgd1/PRE_PGD1.nam
new file mode 100644
index 0000000000000000000000000000000000000000..07f27620734c560d2eeede6cb11f8ca3ccb8770b
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/001_pgd1/PRE_PGD1.nam
@@ -0,0 +1,13 @@
+&NAM_CONFZ
+ NB_PROCIO_W=1 ,
+ !MPI_BUFFER_SIZE=40
+/
+&NAM_PGDFILE CPGDFILE="PGD00512" NHALO=0 /
+&NAM_PGD_SCHEMES CNATURE='ISBA', CSEA='SEAFLX', CTOWN='NONE', CWATER='NONE' /
+&NAM_CONF_PROJ XLAT0=-11.5, XLON0=130.7, XRPK=0., XBETA=0. /
+&NAM_CONF_PROJ_GRID XLATCEN=-11.5, XLONCEN=130.7, NIMAX=512, NJMAX=512,
+                    XDX=400.00000, XDY=400.00000 /
+&NAM_COVER     YCOVER='ECOCLIMAP_v2.0', YCOVERFILETYPE='DIRECT' /
+&NAM_ZS        YZS='gtopo30', YZSFILETYPE='DIRECT' /
+&NAM_ISBA  YCLAY='CLAY_HWSD_MOY', YCLAYFILETYPE='DIRECT',
+           YSAND='SAND_HWSD_MOY', YSANDFILETYPE='DIRECT' /
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/001_pgd1/get_pgd_files b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/001_pgd1/get_pgd_files
new file mode 100755
index 0000000000000000000000000000000000000000..56726933a0f7608e0c4918f42e80d5aea76b669d
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/001_pgd1/get_pgd_files
@@ -0,0 +1,30 @@
+#
+#     Modif
+#     J.Escobar 11/04/2014 get PGD files from 'dir_open' directory ( without psswd )
+#     J.Escobar 25/04/2013 get LICENCE files
+#
+PREP_PGD_FILES=${PREP_PGD_FILES:-"$HOME/PREP_PGD_FILES_WWW"} ; export PREP_PGD_FILES
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo "!!!!            WARNING                  !!!!"
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo 
+echo you need 3GO to download this files in
+echo 
+echo PREP_PGD_FILES=$PREP_PGD_FILES  
+echo 
+echo if OK press ENTER  else CTRL-C
+read RIEN
+set -x
+mkdir -p $PREP_PGD_FILES
+cd $PREP_PGD_FILES
+PGD_URL="http://mesonh.aero.obs-mip.fr/mesonh/dir_open/dir_PGDFILES"
+WGET="wget"
+export PGD_URL
+for file in LICENSE_ECOCLIMAP.txt LICENSE_soil_data.txt \
+            gtopo30.dir gtopo30.hdr \
+            SAND_HWSD_MOY.hdr SAND_HWSD_MOY.dir CLAY_HWSD_MOY.hdr CLAY_HWSD_MOY.dir \
+            ECOCLIMAP_v2.0.hdr ECOCLIMAP_v2.0.dir
+do
+[ -f $file ] || ( ${WGET} -c -nd $PGD_URL/$file.gz ; gunzip $file.gz ; ) 
+done
+
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/001_pgd1/run_prep_pgd_xyz b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/001_pgd1/run_prep_pgd_xyz
new file mode 100755
index 0000000000000000000000000000000000000000..342c7e22cf511ecaa4bb018bf4e51d45b47757e3
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/001_pgd1/run_prep_pgd_xyz
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+export ACC_DEVICE_TYPE=HOST
+
+NP=${NP:-16}
+NPS=${NPS:-1}
+
+export MPIRUN=${MPIRUN:-"Mpirun -tag-output --mca mpi_cuda_support 0 -map-by ppr:${NPS}:socket -bind-to none -np ${NP} set_core_device_impair "}
+
+
+PREP_PGD_FILES=${PREP_PGD_FILES:-"$HOME/PREP_PGD_FILES_WWW"} ; export PREP_PGD_FILES
+#
+if [ ! -d $PREP_PGD_FILES ]
+then
+cat << EOF
+
+Your directory  PREP_PGD_FILES=$PREP_PGD_FILES
+
+containing the files gtopo30*, ECOCLIMAP_v2.0* 
+doesn't exist ( or was not found !!! )
+use the script 'get_pgd_files' to download 
+this files from the MESONH WEB PAGES !!!
+( or change the variable PREP_PGD_FILES ... )
+
+After fixing it , run this script again !!!
+ 
+EOF
+exit 1
+else
+set -x 
+#
+rm -f OUTPUT_LISTING0 pipe_name
+rm -f gtopo30.???  sand_fao.???  clay_fao.???
+rm -f SAND_HWSD_MOY.??? ECOCLIMAP_v2.0.??? ecoclimats_v2.???
+rm -f PGD00512.*
+#
+ln -sf $PREP_PGD_FILES/*.dir $PREP_PGD_FILES/*.hdr .
+#
+time ${MPIRUN} PREP_PGD${XYZ}
+fi
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/002_prep_ideal_case/PRE_IDEA1.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/002_prep_ideal_case/PRE_IDEA1.nam
new file mode 100644
index 0000000000000000000000000000000000000000..5b3f7253b15aba7334130cfad5fab26c738e3793
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/002_prep_ideal_case/PRE_IDEA1.nam
@@ -0,0 +1,226 @@
+&NAM_CONFZ
+ !NB_PROCIO_R=1 ,
+ !NB_PROCIO_W=1 ,
+ MPI_BUFFER_SIZE=200
+/
+
+&NAM_REAL_PGD
+            CPGD_FILE ="PGD00512" ,
+            LREAD_ZS =.TRUE., LREAD_GROUND_PARAM =.TRUE.
+/
+&NAM_DIMn_PRE NIMAX=40, NJMAX=32 /
+&NAM_CONF_PRE LCARTESIAN=.FALSE.
+              CIDEAL='RSOU' CZS='FLAT'
+              NVERB=0 /
+&NAM_CONFn LUSERV= T /
+&NAM_LUNITn CINIFILE = "DA0512" , CINIFILEPGD = "PGD00512" /
+&NAM_DYNn_PRE
+  CPRESOPT= 'ZRESI' ,
+  NITR=4 XRELAX=1. /
+&NAM_LBCn_PRE CLBCX= 2*'OPEN' CLBCY= 2*'OPEN' /
+&NAM_VPROF_PRE CTYPELOC='IJGRID' NILOC=1 NJLOC=1
+               CFUNU='ZZZ' CFUNV='ZZZ'
+               LGEOSBAL=.FALSE. /
+&NAM_VER_GRID NKMAX=126, YZGRID_TYPE='FUNCTN',
+       ZDZGRD=40., ZDZTOP=210., ZZMAX_STRGRD=2500.,
+       ZSTRGRD=7., ZSTRTOP=7. /
+&NAM_GRn_PRE
+   CSURF='EXTE'
+   ! CSURF='NONE'
+  /
+&NAM_PREP_ISBA XTG_SURF= 311., XTG_ROOT= 303., XTG_DEEP= 302.,
+               XHUG_SURF= 0.16, XHUG_ROOT= 0.16, XHUG_DEEP= 0.16 /
+&NAM_PREP_SEAFLUX XSST_UNIF= 304. /
+  RSOU
+ 2005 11 30 0
+ 'PUVTHDMR'
+  0.0000000E+00
+   100300.0    
+   303.3000    
+  1.9630000E-02
+          92
+   100000.0       3.637668      -3.637668    
+   99900.00       2.572220      -4.455216    
+   99100.00      -4.612377      0.4035313    
+   96600.00       5.124864     -0.4483674    
+   93000.00       5.836996      -2.009839    
+   92800.00       5.801031      -2.111402    
+   92500.00       5.466062      -1.464627    
+   85000.00      0.1345103      -1.537459    
+   81400.00     -0.9020693      -1.849517    
+   71800.00      -2.797467       1.304481    
+   70000.00      -4.472232       1.198331    
+   60500.00      -3.289776      -1.464702    
+   59900.00      -3.208611      -1.634869    
+   56900.00      -2.329535      -2.025034    
+   55600.00      -2.105100      -2.257443    
+   50100.00     -0.5325915      -1.987659    
+   50000.00     -0.2679967      -1.519885    
+   49500.00      0.2507798      -2.042438    
+   46700.00       5.466062       1.464627    
+   45300.00       5.594935       2.608961    
+   44800.00       5.450725       2.898202    
+   43700.00       4.994327       3.628591    
+   42200.00       4.561049       4.891127    
+   41900.00       4.387573       5.047325    
+   41800.00       4.298817       5.123130    
+   40000.00       6.305391       5.290851    
+   39000.00       5.970908       4.027428    
+   38600.00       5.671552       3.543979    
+   38300.00       5.346259       3.086664    
+   35500.00       2.976104       3.546782    
+   32700.00       4.455215       2.572220    
+   31400.00       3.712562       4.270814    
+   30700.00       3.086664       5.346259    
+   30000.00       3.540875       5.056894    
+   28800.00       3.786532       4.205370    
+   26700.00       3.329551       2.419061    
+   25000.00       2.797467       1.304481    
+   24400.00       2.819808       1.255459    
+   23800.00       2.841289       1.206056    
+   21400.00       3.424857       1.112804    
+   20000.00       3.478403      0.9320353    
+   19300.00       3.383935       1.231651    
+   17400.00       3.411947       2.301387    
+   15000.00       2.950729       4.214078    
+   12700.00       2.167201       2.875973    
+   10200.00       1.322713       1.576348    
+   10000.00      0.4466614       2.533142    
+   9120.000      -3.306782       3.940869    
+   8700.000      -7.950636       2.130367    
+   8200.000      -8.712269      0.7622259    
+   8000.000      -9.224754     -0.8070621    
+   7600.000      -4.009694      -2.314998    
+   7300.000      -5.066284     -0.8933228    
+   7000.000      -4.196201      -1.956721    
+   6700.000      -1.013257      0.1786647    
+   6400.000      -2.107039       1.475365    
+   6340.000      -2.558960       1.726041    
+   5480.000      -13.17234       2.322640    
+   5300.000      -15.37459       1.345105    
+   5000.000      -12.81216      -1.120920    
+   4900.000      -12.66571      -2.233307    
+   4860.000      -12.25463      -1.504677    
+   4700.000      -10.76221      0.9415731    
+   4500.000      -11.37801       7.966970    
+   3800.000      -25.11183       2.197004    
+   3600.000      -22.54940      -1.972818    
+   3200.000      -22.72465      -4.417223    
+   3000.000      -22.36116      -5.991656    
+   2490.000      -21.48829      -2.258509    
+   2300.000      -21.07936     -0.7361050    
+   2200.000      -20.57776     -1.7989648E-06
+   2080.000      -19.00834     -0.9961855    
+   2000.000      -17.93702      -1.569287    
+   1600.000      -14.74927      -10.32755    
+   1500.000      -13.52109      -6.304989    
+   1430.000      -16.89510      -4.527030    
+   1400.000      -18.23862      -3.215962    
+   1300.000      -15.46941      -5.630407    
+   1200.000      -5.594935       2.608962    
+   1190.000      -5.671552       3.543979    
+   1100.000       1.786646       10.13257    
+   1050.000      -3.736842       7.333968    
+   1020.000      -5.435582       4.725079    
+   1000.000      -5.594935       2.608962    
+   950.0000      -4.347303       8.176087    
+   900.0000       2.143975       12.15908    
+   889.9999       1.031246       11.78719    
+   800.0000      -4.728969       4.728969    
+   760.0000       2.890712       7.154763    
+   710.0000       8.644947      -3.318484    
+   700.0000       7.487652      -6.282886    
+   600.0000      -4.214078      -2.950729    
+          91
+   100000.0       303.1000      1.8050000E-02
+   99900.00       303.1000      1.8040001E-02
+   99100.00       303.1000      1.7969999E-02
+   96600.00       303.1000      1.7729999E-02
+   93000.00       303.0000      1.7370002E-02
+   92800.00       303.1000      1.6980000E-02
+   92500.00       303.2000      1.6400000E-02
+   85000.00       307.1000      1.1190000E-02
+   81400.00       309.6000      6.6700005E-03
+   71800.00       312.3000      6.5600001E-03
+   70000.00       312.9000      6.5400004E-03
+   60500.00       316.2000      6.1800000E-03
+   59900.00       318.1000      5.3400006E-03
+   56900.00       318.7000      4.9899998E-03
+   55600.00       322.2000      3.3100001E-03
+   50100.00       325.5000      2.6000000E-03
+   50000.00       325.5000      2.5800001E-03
+   49500.00       325.7000      3.1700002E-03
+   46700.00       328.6000      1.4500001E-03
+   45300.00       330.1000      9.4000006E-04
+   44800.00       330.1000      1.9600000E-03
+   43700.00       331.0000      2.1500003E-03
+   42200.00       332.2000      1.9400001E-03
+   41900.00       332.9000      9.6000003E-04
+   41800.00       333.0000      9.7000005E-04
+   40000.00       334.2000      1.1600000E-03
+   39000.00       334.6000      1.0300000E-03
+   38600.00       335.6000      6.5000000E-04
+   38300.00       335.8000      6.0000003E-04
+   35500.00       338.2000      2.5000001E-04
+   32700.00       340.8000      9.0000009E-05
+   31400.00       342.0000      5.0000002E-05
+   30700.00       342.1000      4.0000003E-05
+   30000.00       342.3000      4.0000003E-05
+   28800.00       342.3000      1.2000000E-04
+   26700.00       344.8000      1.0000001E-05
+   25000.00       345.4000      1.0000001E-05
+   24400.00       346.3000      2.0000001E-05
+   23800.00       346.4000      9.0000009E-05
+   21400.00       348.1000      1.0000001E-05
+   20000.00       348.8000      1.0000001E-05
+   19300.00       348.9000      2.0000001E-05
+   17400.00       351.5000      1.0000001E-05
+   15000.00       354.0000      7.1596442E-06
+   12700.00       355.7000      4.4376361E-06
+   10200.00       364.6000      1.4789329E-06
+   10000.00       365.4000      1.2422363E-06
+   9120.000       371.6000      1.2919259E-06
+   8700.000       379.9000      1.5496893E-06
+   8200.000       390.6000      1.8819877E-06
+   8000.000       395.1000      2.0217396E-06
+   7600.000       404.7000      2.3198761E-06
+   7300.000       412.3000      2.4844724E-06
+   7000.000       420.4000      2.4844724E-06
+   6700.000       431.1000      2.4844724E-06
+   6400.000       442.4000      2.4844724E-06
+   6340.000       444.8000      2.4844724E-06
+   5480.000       467.8000      2.4844724E-06
+   5300.000       471.0000      2.4844724E-06
+   5000.000       476.5000      2.4844724E-06
+   4900.000       477.6000      2.4844724E-06
+   4860.000       478.0000      2.4844724E-06
+   4700.000       485.1000      2.4844724E-06
+   4500.000       494.6000      2.4844724E-06
+   3800.000       532.9000      2.4844724E-06
+   3600.000       545.6000      2.4844724E-06
+   3200.000       574.4000      2.4844724E-06
+   3000.000       585.1000      2.4844724E-06
+   2490.000       624.0000      2.4844724E-06
+   2300.000       648.9000      2.4844724E-06
+   2200.000       655.4000      2.4844724E-06
+   2080.000       663.6000      2.4844724E-06
+   2000.000       673.5000      2.4844724E-06
+   1600.000       726.4000      2.4844724E-06
+   1500.000       742.5000      2.4844724E-06
+   1430.000       750.7000      2.4844724E-06
+   1400.000       759.0000      2.4844724E-06
+   1300.000       788.6000      2.4844724E-06
+   1200.000       821.7000      2.4844724E-06
+   1190.000       825.2000      2.4844724E-06
+   1100.000       833.9000      2.4844724E-06
+   1050.000       839.0000      2.4844724E-06
+   1020.000       845.3000      2.4844724E-06
+   1000.000       851.6000      2.4844724E-06
+   950.0000       877.0000      2.4844724E-06
+   900.0000       885.6000      2.4844724E-06
+   889.9999       887.3000      2.4844724E-06
+   800.0000       926.6000      2.4844724E-06
+   760.0000       946.0000      2.4844724E-06
+   710.0000       958.0000      2.4844724E-06
+   700.0000       963.1000      2.4844724E-06
+   600.0000       20.30000      2.4844724E-06
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/002_prep_ideal_case/run_prep_ideal_xyz b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/002_prep_ideal_case/run_prep_ideal_xyz
new file mode 100755
index 0000000000000000000000000000000000000000..1a85e665eccd99a35eb1c4498766beba6593b344
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/002_prep_ideal_case/run_prep_ideal_xyz
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+NP=${NP:-16}
+NPS=${NPS:-4}
+
+export ACC_DEVICE_TYPE=HOST
+export MPIRUN="Mpirun -tag-output -report-bindings --mca mpi_cuda_support 0 -map-by ppr:${NPS}:socket -bind-to none -np ${NP} set_core_device_impair"
+
+#
+set -x
+set -e
+#
+rm -f OUTPUT_LISTING1 pipe_name file_for_xtransfer
+rm -f PGD00512.*
+rm -f DA0512.*
+#
+ln -sf ../001_pgd1/PGD00512.* .
+#
+time ${MPIRUN} PREP_IDEAL_CASE${XYZ}
+#
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/003_mesonh_step1/EXSEG1.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/003_mesonh_step1/EXSEG1.nam
new file mode 100644
index 0000000000000000000000000000000000000000..878afa281253ff16017a9c0177e961b3675533fc
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/003_mesonh_step1/EXSEG1.nam
@@ -0,0 +1,54 @@
+&NAM_CONFZ
+ ! NB_PROCIO_R=1 ,
+ ! NB_PROCIO_W=1 ,
+ ! LMNH_MPI_BSEND = T ,
+  MPI_BUFFER_SIZE = 1000
+/
+
+&NAM_LUNITn  CINIFILE = "DA0512" , CINIFILEPGD = "PGD00512" /
+&NAM_CONFn  LUSERV = T, LUSERC = T, LUSERR = T, LUSERI = T,
+            LUSERS = T, LUSERG = T, LUSERH = F, LUSECI = T /
+&NAM_DYNn  XTSTEP = 10.0 , 
+           CPRESOPT = "ZRESI", NITR = 12
+           !CPRESOPT = "ZSOLV", NITR = 12
+           XRELAX = 1., LHORELAX_UVWTH = T, LHORELAX_RV = T, LVE_RELAX = T,
+           NRIMX = 6, NRIMY = 6, XRIMKMAX = 0.0005, XT4DIFU =  4000 /
+&NAM_ADVn  CUVW_ADV_SCHEME = "WENO_K", CMET_ADV_SCHEME = "PPM_01",
+           CSV_ADV_SCHEME = "PPM_01" /
+&NAM_PARAMn  CTURB = "TKEL" ! "NONE" ! "TKEL", 
+             CRAD = "ECMW", 
+             CCLOUD = "ICE3" ! "NONE" ! "ICE3",
+             CDCONV = "NONE", CSCONV = "NONE" /
+&NAM_PARAM_RADn  XDTRAD = 1800., XDTRAD_CLONLY = 1800., LCLEAR_SKY = F,
+                 NRAD_COLNBR = 500 /
+&NAM_PARAM_MFSHALLn XIMPL_MF = 1, CMF_UPDRAFT = "EDKF", CMF_CLOUD = "NONE",
+                    LMIXUV = T, LMF_FLX = F /
+&NAM_LBCn  CLBCX = 2*"OPEN", CLBCY = 2*"OPEN", XCPHASE = 20. /
+&NAM_TURBn  XIMPL = 1., CTURBLEN = "DEAR", CTURBDIM = "3DIM",
+            LTURB_FLX = F, LTURB_DIAG = F, CSUBG_AUCV = "NONE", LSIGMAS = F,
+            LSIG_CONV = F,  LSUBG_COND = F /
+&NAM_CH_MNHCn /
+&NAM_CONF  CCONF = "START",  LFLAT = F, CEQNSYS = "DUR",
+           LLG=F, NMODEL = 1, NVERB = 0, CEXP = "D0512",
+           CSEG = "DAR01", CSPLIT = "BSPLITTING" 
+           NHALO=1
+           /
+&NAM_DYN  XSEGLEN = 14400.0000 ! 100. ! 14400.0000 ,
+          LCORIO = T,
+          LNUMDIFU = F, LNUMDIFTH = F,
+          XALKTOP = 0.001, XALZBOT = 22000. /
+&NAM_BLANK /
+&NAM_NESTING /
+&NAM_BACKUP
+ XBAK_TIME(1,1) = 3600.00000 ! 100. ! 3600.00000
+ XBAK_TIME(1,2) = 7200.00000
+ XBAK_TIME(1,3) = 10800.0000
+ XBAK_TIME(1,4) = 14400.0000
+ XBAK_TIME(1,5) = 18000.0000
+ XBAK_TIME(1,6) = 21600.0000
+ /
+&NAM_ISBAn /
+&NAM_SEAFLUXn /
+&NAM_DIAG_SURFn LSURF_BUDGET=T /
+&NAM_DIAG_ISBAn /
+&NAM_DIAG_SURF_ATMn /
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/003_mesonh_step1/parameters_mg.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/003_mesonh_step1/parameters_mg.nam
new file mode 100644
index 0000000000000000000000000000000000000000..1a5d92f6f3e36ecd068964fd6fdf580cb1940fe6
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/003_mesonh_step1/parameters_mg.nam
@@ -0,0 +1,118 @@
+! *********************************************************************
+! *********************************************************************
+! **                                                                 **
+! **    Parameter file for geometric multigrid code                  **
+! **                                                                 **
+! *********************************************************************
+! *********************************************************************
+!
+! *********************************************************************
+! * General parameters
+! *********************************************************************
+&parameters_general
+  savefields = .F.              ! Save fields to disk?
+/
+
+! *********************************************************************
+! * General solver parameters
+! *********************************************************************
+&parameters_solver
+  LUseO = F ,
+  LUseT = T ,
+  solvertype = 1,            ! Solver type:
+                             !   1 : Richardson iteration
+                             !   2 : Conjugate gradient
+  resreduction = 1e-1 ! 1.0d-15  ! Required relative residual reduction
+  maxiter = 5                ! Maximal number of iterations
+/
+
+! *********************************************************************
+! * Conjugate gradient parameters
+! *********************************************************************
+&parameters_conjugategradient
+  verbose = 10,                  ! Verbosity level
+  maxiter = 5,                ! Maximal number of iterations
+  resreduction = 1.0e-1,        ! Target residual reduction
+  n_prec = 1                    ! Number of smoother applications in
+                                ! preconditioner (N.B.: Using 0 is
+                                ! inefficient, as the identity is used
+                                ! for preconditioning, instead of using
+                                ! unpreconditioned CG.)
+/
+
+! *********************************************************************
+! * Grid parameters
+! *********************************************************************
+&parameters_grid
+  n = 512 , ! 64,      ! Number of horizontal grid cells
+  nz = 128,     ! Number of vertical grid cells
+  L = 204800.0 ! 400.0 metre * 512 pt grille ! 1.0,      ! Size in horizontal direction
+  H =  25600.0 ! 200.0 metre * 128 niveaux ! 0.01,     ! Size in vertical direction
+  vertbc = 2,   ! Boundary conditions at top and bottom of the
+                ! atmosphere. 1 = DIRICHLET, 2 = NEUMANN
+                ! Note that Neumann boundary conditions only work
+                ! for coarsening in the horizontal only, as they are
+                ! not yet implemented in the prolongation operator.
+  graded = .F.  ! Is the grid graded in the vertical direction?
+/
+
+! *********************************************************************
+! * Parallel communication parameters
+! *********************************************************************
+&parameters_communication
+  halo_size = 1  ! Size of halos (has to be 1 or 2)
+/
+
+! *********************************************************************
+! * Model parameters
+! *********************************************************************
+!
+! parameters of the Helmholtz operator
+!
+! -omega2*(d^2/dy^2 + d^2/dy^2 + lambda2*d^2/dz^2) u + delta u = RHS
+!
+&parameters_model
+  omega2 = 1.0,
+  lambda2 = 1.0 ! 100.0,  ! Vertical coupling
+  delta = 0.0d0       ! Size of constant term
+/
+
+! *********************************************************************
+! * Smoother parameters
+! *********************************************************************
+!
+! parameters of the smoother
+!
+&parameters_smoother
+  smoother = 3,                 ! Smoother method
+                                !   3 = line SOR
+                                !   4 = line SSOR
+                                !   6 = line Jacobi
+  ordering = 2,                 ! Ordering of grid points (for smoother)
+
+                                !   1 = lexicographic
+                                !   2 = red-black ordering
+!rho = 0.6666666666666666d0    ! Overrelaxation parameter
+ rho = 0.8d0    ! Overrelaxation parameter
+/
+
+! *********************************************************************
+! * Multigrid parameters
+! *********************************************************************
+&parameters_multigrid
+  verbose = 10,                  ! Verbosity level
+  n_lev = 10,                    ! Number of levels
+  lev_split = 5,                ! First level where data is pulled together
+  n_presmooth = 1,              ! Number of presmoothing steps
+  n_postsmooth = 1,             ! Number of postsmoothing steps
+  n_coarsegridsmooth = 1,       ! Number of smoothing steps on coarsest level
+  prolongation = 2  ! 2 best after modif !!           ! Prologation method
+                                !   1 = constant interpolation
+                                !   2 = (tri-) linear interpolation
+  restriction = 1,              ! Restriction method
+                                !   1 = cell average
+                                !   2 = Khalil         
+  coarsegridsolver = 1          ! Solver on coarsest grid
+                                !   1 = use smoother
+                                !   2 = Conjugate gradient
+/
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/003_mesonh_step1/run_mesonh_step1_xyz b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/003_mesonh_step1/run_mesonh_step1_xyz
new file mode 100755
index 0000000000000000000000000000000000000000..1a3cfc09ce327c8c20cc728df069ac08e720c746
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/003_mesonh_step1/run_mesonh_step1_xyz
@@ -0,0 +1,23 @@
+
+
+#export PGI_ACC_POOL_ALLOC=0
+export PGI_ACC_SYNCHRONOUS=1
+
+NP=${NP:-16}
+NPS=${NPS:-4}
+
+export MPIRUN=${MPIRUN:-"Mpirun -tag-output -report-bindings -bind-to none -map-by ppr:${NPS}:socket -x PGI_ACC_POOL_ALLOC -x PGI_ACC_SYNCHRONOUS -np ${NP} set_core_device_impair "}
+
+
+#
+set -x
+set -e
+#
+rm -f DA0512.*
+rm -f PGD00512.*
+rm -f D0512.1.DAR01.* OUTPUT_LISTING* pipe_name
+#
+ln -sf ../001_pgd1/PGD00512.{des,nc} .
+ln -sf ../002_prep_ideal_case/DA0512.{des,nc} .
+#
+time ${MPIRUN} MESONH${XYZ}
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/004_mesonh_step2/EXSEG1.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/004_mesonh_step2/EXSEG1.nam
new file mode 100644
index 0000000000000000000000000000000000000000..8b73157a9f279cde77f15e96c489f18570dfb1dc
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/004_mesonh_step2/EXSEG1.nam
@@ -0,0 +1,59 @@
+&NAM_CONFIO 
+    LIO_ALLOW_NO_BACKUP = T , LIO_NO_WRITE = T 
+/
+&NAM_CONFZ
+ ! NB_PROCIO_R=1 ,
+ ! NB_PROCIO_W=1 ,
+ ! LMNH_MPI_BSEND = T ,
+  MPI_BUFFER_SIZE = 1000
+/
+
+&NAM_LUNITn  CINIFILE = "D0512.1.DAR01.004" ! "D0512.1.DAR01.003" ,
+             CINIFILEPGD = "PGD00512" /
+&NAM_CONFn  LUSERV = T, LUSERC = T, LUSERR = T, LUSERI = T,
+            LUSERS = T, LUSERG = T, LUSERH = F, LUSECI = T /
+&NAM_DYNn  XTSTEP = 10.00000 , 
+           CPRESOPT = "ZRESI", 
+           !CPRESOPT = "ZSOLV", 
+           NITR = 12,
+           XRELAX = 1., LHORELAX_UVWTH = T, LHORELAX_RV = T, LVE_RELAX = T,
+           NRIMX = 6, NRIMY = 6, XRIMKMAX = 0.0005, XT4DIFU =  4000 /
+&NAM_ADVn  CUVW_ADV_SCHEME = "WENO_K", CMET_ADV_SCHEME = "PPM_01",
+           CSV_ADV_SCHEME = "PPM_01" /
+&NAM_PARAMn  CTURB = "TKEL", ! "NONE" , ! "TKEL", 
+             CRAD = "ECMWF",
+	     CCLOUD = "ICE3", ! "NONE" , ! "ICE3",
+             CDCONV = "NONE", CSCONV = "NONE" /
+&NAM_PARAM_RADn  XDTRAD = 1800., XDTRAD_CLONLY = 1800., LCLEAR_SKY = F,
+                 NRAD_COLNBR = 500 /
+&NAM_PARAM_MFSHALLn XIMPL_MF = 1, CMF_UPDRAFT = "EDKF", CMF_CLOUD = "NONE",
+                    LMIXUV = T, LMF_FLX = F /
+&NAM_LBCn  CLBCX = 2*"OPEN", CLBCY = 2*"OPEN", XCPHASE = 20. /
+&NAM_TURBn  XIMPL = 1., CTURBLEN = "DEAR", CTURBDIM = "3DIM",
+            LTURB_FLX = F, LTURB_DIAG = F, CSUBG_AUCV = "NONE", LSIGMAS = F,
+            LSIG_CONV = F,  LSUBG_COND = F /
+&NAM_CH_MNHCn /
+&NAM_CONF  CCONF = "RESTA",  LFLAT = F, CEQNSYS = "DUR",
+           LLG=F, NMODEL = 1, NVERB = 0, CEXP = "D0512",
+           CSEG = "DAR02", CSPLIT = "BSPLITTING" 
+           NHALO=1 
+           LCHECK = F /
+&NAM_DYN  XSEGLEN = 100.0 ! 150.0000 , 
+          LCORIO = T,
+          LNUMDIFU = F, LNUMDIFTH = F,
+          XALKTOP = 0.001, XALZBOT = 22000. /
+&NAM_BLANK /
+&NAM_NESTING /
+&NAM_BACKUP
+ XBAK_TIME(1,1) = 100.0 ! 3600.00000 ! 3600.00000
+ XBAK_TIME(1,2) = 7200.00000
+ XBAK_TIME(1,3) = 10800.0000
+ XBAK_TIME(1,4) = 14400.0000
+ XBAK_TIME(1,5) = 18000.0000
+ XBAK_TIME(1,6) = 21600.0000
+ /
+&NAM_ISBAn /
+&NAM_SEAFLUXn /
+&NAM_DIAG_SURFn LSURF_BUDGET=T /
+&NAM_DIAG_ISBAn /
+&NAM_DIAG_SURF_ATMn /
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/004_mesonh_step2/parameters_mg.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/004_mesonh_step2/parameters_mg.nam
new file mode 100644
index 0000000000000000000000000000000000000000..1a5d92f6f3e36ecd068964fd6fdf580cb1940fe6
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/004_mesonh_step2/parameters_mg.nam
@@ -0,0 +1,118 @@
+! *********************************************************************
+! *********************************************************************
+! **                                                                 **
+! **    Parameter file for geometric multigrid code                  **
+! **                                                                 **
+! *********************************************************************
+! *********************************************************************
+!
+! *********************************************************************
+! * General parameters
+! *********************************************************************
+&parameters_general
+  savefields = .F.              ! Save fields to disk?
+/
+
+! *********************************************************************
+! * General solver parameters
+! *********************************************************************
+&parameters_solver
+  LUseO = F ,
+  LUseT = T ,
+  solvertype = 1,            ! Solver type:
+                             !   1 : Richardson iteration
+                             !   2 : Conjugate gradient
+  resreduction = 1e-1 ! 1.0d-15  ! Required relative residual reduction
+  maxiter = 5                ! Maximal number of iterations
+/
+
+! *********************************************************************
+! * Conjugate gradient parameters
+! *********************************************************************
+&parameters_conjugategradient
+  verbose = 10,                  ! Verbosity level
+  maxiter = 5,                ! Maximal number of iterations
+  resreduction = 1.0e-1,        ! Target residual reduction
+  n_prec = 1                    ! Number of smoother applications in
+                                ! preconditioner (N.B.: Using 0 is
+                                ! inefficient, as the identity is used
+                                ! for preconditioning, instead of using
+                                ! unpreconditioned CG.)
+/
+
+! *********************************************************************
+! * Grid parameters
+! *********************************************************************
+&parameters_grid
+  n = 512 , ! 64,      ! Number of horizontal grid cells
+  nz = 128,     ! Number of vertical grid cells
+  L = 204800.0 ! 400.0 metre * 512 pt grille ! 1.0,      ! Size in horizontal direction
+  H =  25600.0 ! 200.0 metre * 128 niveaux ! 0.01,     ! Size in vertical direction
+  vertbc = 2,   ! Boundary conditions at top and bottom of the
+                ! atmosphere. 1 = DIRICHLET, 2 = NEUMANN
+                ! Note that Neumann boundary conditions only work
+                ! for coarsening in the horizontal only, as they are
+                ! not yet implemented in the prolongation operator.
+  graded = .F.  ! Is the grid graded in the vertical direction?
+/
+
+! *********************************************************************
+! * Parallel communication parameters
+! *********************************************************************
+&parameters_communication
+  halo_size = 1  ! Size of halos (has to be 1 or 2)
+/
+
+! *********************************************************************
+! * Model parameters
+! *********************************************************************
+!
+! parameters of the Helmholtz operator
+!
+! -omega2*(d^2/dy^2 + d^2/dy^2 + lambda2*d^2/dz^2) u + delta u = RHS
+!
+&parameters_model
+  omega2 = 1.0,
+  lambda2 = 1.0 ! 100.0,  ! Vertical coupling
+  delta = 0.0d0       ! Size of constant term
+/
+
+! *********************************************************************
+! * Smoother parameters
+! *********************************************************************
+!
+! parameters of the smoother
+!
+&parameters_smoother
+  smoother = 3,                 ! Smoother method
+                                !   3 = line SOR
+                                !   4 = line SSOR
+                                !   6 = line Jacobi
+  ordering = 2,                 ! Ordering of grid points (for smoother)
+
+                                !   1 = lexicographic
+                                !   2 = red-black ordering
+!rho = 0.6666666666666666d0    ! Overrelaxation parameter
+ rho = 0.8d0    ! Overrelaxation parameter
+/
+
+! *********************************************************************
+! * Multigrid parameters
+! *********************************************************************
+&parameters_multigrid
+  verbose = 10,                  ! Verbosity level
+  n_lev = 10,                    ! Number of levels
+  lev_split = 5,                ! First level where data is pulled together
+  n_presmooth = 1,              ! Number of presmoothing steps
+  n_postsmooth = 1,             ! Number of postsmoothing steps
+  n_coarsegridsmooth = 1,       ! Number of smoothing steps on coarsest level
+  prolongation = 2  ! 2 best after modif !!           ! Prologation method
+                                !   1 = constant interpolation
+                                !   2 = (tri-) linear interpolation
+  restriction = 1,              ! Restriction method
+                                !   1 = cell average
+                                !   2 = Khalil         
+  coarsegridsolver = 1          ! Solver on coarsest grid
+                                !   1 = use smoother
+                                !   2 = Conjugate gradient
+/
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/004_mesonh_step2/run_mesonh_step2_xyz b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/004_mesonh_step2/run_mesonh_step2_xyz
new file mode 100755
index 0000000000000000000000000000000000000000..c10adb44e1c80d1049209cbdf0b33c94c6f17127
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/004_mesonh_step2/run_mesonh_step2_xyz
@@ -0,0 +1,26 @@
+#!/bin/bash
+#
+#
+set -x
+
+#export PGI_ACC_POOL_ALLOC=0
+export PGI_ACC_SYNCHRONOUS=1
+#export NVCOMPILER_ACC_POOL_ALLOC=0
+
+NP=${NP:-16}
+NPS=${NPS:-4}
+
+export MPIRUN=${MPIRUN:-"Mpirun -tag-output -report-bindings -bind-to none -map-by ppr:${NPS}:socket -x NVCOMPILER_ACC_POOL_ALLOC_MAXSIZE -x NVCOMPILER_ACC_POOL_ALLOC  -x PGI_ACC_POOL_ALLOC -x PGI_ACC_SYNCHRONOUS -np ${NP} set_core_device_impair "}
+
+rm -f DA0512.*
+rm -f PGD00512.*
+rm -f D0512.1.DAR0?.* OUTPUT_LISTING1 pipe_name
+#
+ln -sf ../001_pgd1/PGD00512.* .
+ln -sf ../002_prep_ideal_case/DA0512.* .
+ln -sf ../003_mesonh_step1/D0512.1.DAR0?.* .
+#
+
+time ${MPIRUN} MESONH${XYZ}
+
+
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/005_mg_main_mnh_all/parameters_mg.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/005_mg_main_mnh_all/parameters_mg.nam
new file mode 120000
index 0000000000000000000000000000000000000000..adeab0e1859deb44804ccc14f23c2ccb35775079
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/005_mg_main_mnh_all/parameters_mg.nam
@@ -0,0 +1 @@
+../004_mesonh_step2/parameters_mg.nam
\ No newline at end of file
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/005_mg_main_mnh_all/run_mg_main_mnh_all_xyz b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/005_mg_main_mnh_all/run_mg_main_mnh_all_xyz
new file mode 100755
index 0000000000000000000000000000000000000000..c3694f2de5a11d8600af4cf5874b3248c26057f4
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_512x512_MNH-55X/005_mg_main_mnh_all/run_mg_main_mnh_all_xyz
@@ -0,0 +1,18 @@
+#!/bin/bash
+#
+#
+set -x
+
+#export PGI_ACC_POOL_ALLOC=0
+export PGI_ACC_SYNCHRONOUS=1
+#export NVCOMPILER_ACC_POOL_ALLOC=0
+
+NP=${NP:-16}
+NPS=${NPS:-4}
+
+export MPIRUN=${MPIRUN:-"Mpirun -tag-output -report-bindings -bind-to none -map-by ppr:${NPS}:socket -x NVCOMPILER_ACC_POOL_ALLOC_MAXSIZE -x NVCOMPILER_ACC_POOL_ALLOC  -x PGI_ACC_POOL_ALLOC -x PGI_ACC_SYNCHRONOUS -np ${NP} set_core_device_impair "}
+
+
+time ${MPIRUN} MG_MAIN_MNH_ALL${XYZ}
+
+
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/001_pgd1/PRE_PGD1.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/001_pgd1/PRE_PGD1.nam
new file mode 100644
index 0000000000000000000000000000000000000000..98c1fb75ddf67ed2c004f85e38e92503dcaf6303
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/001_pgd1/PRE_PGD1.nam
@@ -0,0 +1,13 @@
+&NAM_CONFZ
+ NB_PROCIO_W=1 ,
+ !MPI_BUFFER_SIZE=40
+/
+&NAM_PGDFILE CPGDFILE="PGD00064" /
+&NAM_PGD_SCHEMES CNATURE='ISBA', CSEA='SEAFLX', CTOWN='NONE', CWATER='NONE' /
+&NAM_CONF_PROJ XLAT0=-11.5, XLON0=130.7, XRPK=0., XBETA=0. /
+&NAM_CONF_PROJ_GRID XLATCEN=-11.5, XLONCEN=130.7, NIMAX=64, NJMAX=64,
+                    XDX=3200.00000, XDY=3200.00000 /
+&NAM_COVER     YCOVER='ECOCLIMAP_v2.0', YCOVERFILETYPE='DIRECT' /
+&NAM_ZS        YZS='gtopo30', YZSFILETYPE='DIRECT' /
+&NAM_ISBA  YCLAY='CLAY_HWSD_MOY', YCLAYFILETYPE='DIRECT',
+           YSAND='SAND_HWSD_MOY', YSANDFILETYPE='DIRECT' /
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/001_pgd1/get_pgd_files b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/001_pgd1/get_pgd_files
new file mode 100755
index 0000000000000000000000000000000000000000..56726933a0f7608e0c4918f42e80d5aea76b669d
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/001_pgd1/get_pgd_files
@@ -0,0 +1,30 @@
+#
+#     Modif
+#     J.Escobar 11/04/2014 get PGD files from 'dir_open' directory ( without psswd )
+#     J.Escobar 25/04/2013 get LICENCE files
+#
+PREP_PGD_FILES=${PREP_PGD_FILES:-"$HOME/PREP_PGD_FILES_WWW"} ; export PREP_PGD_FILES
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo "!!!!            WARNING                  !!!!"
+echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+echo 
+echo you need 3GO to download this files in
+echo 
+echo PREP_PGD_FILES=$PREP_PGD_FILES  
+echo 
+echo if OK press ENTER  else CTRL-C
+read RIEN
+set -x
+mkdir -p $PREP_PGD_FILES
+cd $PREP_PGD_FILES
+PGD_URL="http://mesonh.aero.obs-mip.fr/mesonh/dir_open/dir_PGDFILES"
+WGET="wget"
+export PGD_URL
+for file in LICENSE_ECOCLIMAP.txt LICENSE_soil_data.txt \
+            gtopo30.dir gtopo30.hdr \
+            SAND_HWSD_MOY.hdr SAND_HWSD_MOY.dir CLAY_HWSD_MOY.hdr CLAY_HWSD_MOY.dir \
+            ECOCLIMAP_v2.0.hdr ECOCLIMAP_v2.0.dir
+do
+[ -f $file ] || ( ${WGET} -c -nd $PGD_URL/$file.gz ; gunzip $file.gz ; ) 
+done
+
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/001_pgd1/run_prep_pgd_xyz b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/001_pgd1/run_prep_pgd_xyz
new file mode 100755
index 0000000000000000000000000000000000000000..827253ef48a7fd218717d6e6305133e583f428a6
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/001_pgd1/run_prep_pgd_xyz
@@ -0,0 +1,46 @@
+#!/bin/bash
+#BSUB -a openmpi
+#BSUB -J Hector_80x64
+#BSUB -n 4 
+#BSUB -q normal
+#BSUB -R "span[ptile=4]"
+#BSUB -o Sortie_Hector_80x64%J 
+#BSUB -W 01:00
+#
+
+#
+#. /linkhome/rech/yiu/ryiu001/MNH-V5-1-4/conf/profile_mesonh-LXgfortranI4-MNH-V5-1-4-OMPI1-10-MPIAUTO-O2
+
+export MPIRUN="Mpirun -np 1"
+#export MPIRUN="Exec totalview"
+
+PREP_PGD_FILES=${PREP_PGD_FILES:-"$HOME/PREP_PGD_FILES_WWW"} ; export PREP_PGD_FILES
+#
+if [ ! -d $PREP_PGD_FILES ]
+then
+cat << EOF
+
+Your directory  PREP_PGD_FILES=$PREP_PGD_FILES
+
+containing the files gtopo30*, ECOCLIMAP_v2.0* 
+doesn't exist ( or was not found !!! )
+use the script 'get_pgd_files' to download 
+this files from the MESONH WEB PAGES !!!
+( or change the variable PREP_PGD_FILES ... )
+
+After fixing it , run this script again !!!
+ 
+EOF
+exit 1
+else
+set -x 
+#
+rm -f OUTPUT_LISTING0 pipe_name
+rm -f gtopo30.???  sand_fao.???  clay_fao.???
+rm -f SAND_HWSD_MOY.??? ECOCLIMAP_v2.0.??? ecoclimats_v2.???
+rm -f PGD00064.*
+#
+ln -sf $PREP_PGD_FILES/*.dir $PREP_PGD_FILES/*.hdr .
+#
+time ${MPIRUN} PREP_PGD${XYZ}
+fi
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/002_prep_ideal_case/PRE_IDEA1.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/002_prep_ideal_case/PRE_IDEA1.nam
new file mode 100644
index 0000000000000000000000000000000000000000..d5542562c0c89612f6eda02f5a35001fb7924fe3
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/002_prep_ideal_case/PRE_IDEA1.nam
@@ -0,0 +1,226 @@
+&NAM_CONFZ
+ !NB_PROCIO_R=1 ,
+ !NB_PROCIO_W=1 ,
+ !MPI_BUFFER_SIZE=40
+/
+
+&NAM_REAL_PGD
+            CPGD_FILE ="PGD00064" ,
+            LREAD_ZS =.TRUE., LREAD_GROUND_PARAM =.TRUE.
+/
+&NAM_DIMn_PRE NIMAX=40, NJMAX=32 /
+&NAM_CONF_PRE LCARTESIAN=.FALSE.
+              CIDEAL='RSOU' CZS='FLAT'
+              NVERB=0 /
+&NAM_CONFn LUSERV= T /
+&NAM_LUNITn CINIFILE = "DA0064" , CINIFILEPGD = "PGD00064" /
+&NAM_DYNn_PRE
+  CPRESOPT= 'ZRESI' ,
+  NITR=4 XRELAX=1. /
+&NAM_LBCn_PRE CLBCX= 2*'OPEN' CLBCY= 2*'OPEN' /
+&NAM_VPROF_PRE CTYPELOC='IJGRID' NILOC=1 NJLOC=1
+               CFUNU='ZZZ' CFUNV='ZZZ'
+               LGEOSBAL=.FALSE. /
+&NAM_VER_GRID NKMAX=126, YZGRID_TYPE='FUNCTN',
+       ZDZGRD=40., ZDZTOP=210., ZZMAX_STRGRD=2500.,
+       ZSTRGRD=7., ZSTRTOP=7. /
+&NAM_GRn_PRE
+   CSURF='EXTE'
+   ! CSURF='NONE'
+  /
+&NAM_PREP_ISBA XTG_SURF= 311., XTG_ROOT= 303., XTG_DEEP= 302.,
+               XHUG_SURF= 0.16, XHUG_ROOT= 0.16, XHUG_DEEP= 0.16 /
+&NAM_PREP_SEAFLUX XSST_UNIF= 304. /
+  RSOU
+ 2005 11 30 0
+ 'PUVTHDMR'
+  0.0000000E+00
+   100300.0    
+   303.3000    
+  1.9630000E-02
+          92
+   100000.0       3.637668      -3.637668    
+   99900.00       2.572220      -4.455216    
+   99100.00      -4.612377      0.4035313    
+   96600.00       5.124864     -0.4483674    
+   93000.00       5.836996      -2.009839    
+   92800.00       5.801031      -2.111402    
+   92500.00       5.466062      -1.464627    
+   85000.00      0.1345103      -1.537459    
+   81400.00     -0.9020693      -1.849517    
+   71800.00      -2.797467       1.304481    
+   70000.00      -4.472232       1.198331    
+   60500.00      -3.289776      -1.464702    
+   59900.00      -3.208611      -1.634869    
+   56900.00      -2.329535      -2.025034    
+   55600.00      -2.105100      -2.257443    
+   50100.00     -0.5325915      -1.987659    
+   50000.00     -0.2679967      -1.519885    
+   49500.00      0.2507798      -2.042438    
+   46700.00       5.466062       1.464627    
+   45300.00       5.594935       2.608961    
+   44800.00       5.450725       2.898202    
+   43700.00       4.994327       3.628591    
+   42200.00       4.561049       4.891127    
+   41900.00       4.387573       5.047325    
+   41800.00       4.298817       5.123130    
+   40000.00       6.305391       5.290851    
+   39000.00       5.970908       4.027428    
+   38600.00       5.671552       3.543979    
+   38300.00       5.346259       3.086664    
+   35500.00       2.976104       3.546782    
+   32700.00       4.455215       2.572220    
+   31400.00       3.712562       4.270814    
+   30700.00       3.086664       5.346259    
+   30000.00       3.540875       5.056894    
+   28800.00       3.786532       4.205370    
+   26700.00       3.329551       2.419061    
+   25000.00       2.797467       1.304481    
+   24400.00       2.819808       1.255459    
+   23800.00       2.841289       1.206056    
+   21400.00       3.424857       1.112804    
+   20000.00       3.478403      0.9320353    
+   19300.00       3.383935       1.231651    
+   17400.00       3.411947       2.301387    
+   15000.00       2.950729       4.214078    
+   12700.00       2.167201       2.875973    
+   10200.00       1.322713       1.576348    
+   10000.00      0.4466614       2.533142    
+   9120.000      -3.306782       3.940869    
+   8700.000      -7.950636       2.130367    
+   8200.000      -8.712269      0.7622259    
+   8000.000      -9.224754     -0.8070621    
+   7600.000      -4.009694      -2.314998    
+   7300.000      -5.066284     -0.8933228    
+   7000.000      -4.196201      -1.956721    
+   6700.000      -1.013257      0.1786647    
+   6400.000      -2.107039       1.475365    
+   6340.000      -2.558960       1.726041    
+   5480.000      -13.17234       2.322640    
+   5300.000      -15.37459       1.345105    
+   5000.000      -12.81216      -1.120920    
+   4900.000      -12.66571      -2.233307    
+   4860.000      -12.25463      -1.504677    
+   4700.000      -10.76221      0.9415731    
+   4500.000      -11.37801       7.966970    
+   3800.000      -25.11183       2.197004    
+   3600.000      -22.54940      -1.972818    
+   3200.000      -22.72465      -4.417223    
+   3000.000      -22.36116      -5.991656    
+   2490.000      -21.48829      -2.258509    
+   2300.000      -21.07936     -0.7361050    
+   2200.000      -20.57776     -1.7989648E-06
+   2080.000      -19.00834     -0.9961855    
+   2000.000      -17.93702      -1.569287    
+   1600.000      -14.74927      -10.32755    
+   1500.000      -13.52109      -6.304989    
+   1430.000      -16.89510      -4.527030    
+   1400.000      -18.23862      -3.215962    
+   1300.000      -15.46941      -5.630407    
+   1200.000      -5.594935       2.608962    
+   1190.000      -5.671552       3.543979    
+   1100.000       1.786646       10.13257    
+   1050.000      -3.736842       7.333968    
+   1020.000      -5.435582       4.725079    
+   1000.000      -5.594935       2.608962    
+   950.0000      -4.347303       8.176087    
+   900.0000       2.143975       12.15908    
+   889.9999       1.031246       11.78719    
+   800.0000      -4.728969       4.728969    
+   760.0000       2.890712       7.154763    
+   710.0000       8.644947      -3.318484    
+   700.0000       7.487652      -6.282886    
+   600.0000      -4.214078      -2.950729    
+          91
+   100000.0       303.1000      1.8050000E-02
+   99900.00       303.1000      1.8040001E-02
+   99100.00       303.1000      1.7969999E-02
+   96600.00       303.1000      1.7729999E-02
+   93000.00       303.0000      1.7370002E-02
+   92800.00       303.1000      1.6980000E-02
+   92500.00       303.2000      1.6400000E-02
+   85000.00       307.1000      1.1190000E-02
+   81400.00       309.6000      6.6700005E-03
+   71800.00       312.3000      6.5600001E-03
+   70000.00       312.9000      6.5400004E-03
+   60500.00       316.2000      6.1800000E-03
+   59900.00       318.1000      5.3400006E-03
+   56900.00       318.7000      4.9899998E-03
+   55600.00       322.2000      3.3100001E-03
+   50100.00       325.5000      2.6000000E-03
+   50000.00       325.5000      2.5800001E-03
+   49500.00       325.7000      3.1700002E-03
+   46700.00       328.6000      1.4500001E-03
+   45300.00       330.1000      9.4000006E-04
+   44800.00       330.1000      1.9600000E-03
+   43700.00       331.0000      2.1500003E-03
+   42200.00       332.2000      1.9400001E-03
+   41900.00       332.9000      9.6000003E-04
+   41800.00       333.0000      9.7000005E-04
+   40000.00       334.2000      1.1600000E-03
+   39000.00       334.6000      1.0300000E-03
+   38600.00       335.6000      6.5000000E-04
+   38300.00       335.8000      6.0000003E-04
+   35500.00       338.2000      2.5000001E-04
+   32700.00       340.8000      9.0000009E-05
+   31400.00       342.0000      5.0000002E-05
+   30700.00       342.1000      4.0000003E-05
+   30000.00       342.3000      4.0000003E-05
+   28800.00       342.3000      1.2000000E-04
+   26700.00       344.8000      1.0000001E-05
+   25000.00       345.4000      1.0000001E-05
+   24400.00       346.3000      2.0000001E-05
+   23800.00       346.4000      9.0000009E-05
+   21400.00       348.1000      1.0000001E-05
+   20000.00       348.8000      1.0000001E-05
+   19300.00       348.9000      2.0000001E-05
+   17400.00       351.5000      1.0000001E-05
+   15000.00       354.0000      7.1596442E-06
+   12700.00       355.7000      4.4376361E-06
+   10200.00       364.6000      1.4789329E-06
+   10000.00       365.4000      1.2422363E-06
+   9120.000       371.6000      1.2919259E-06
+   8700.000       379.9000      1.5496893E-06
+   8200.000       390.6000      1.8819877E-06
+   8000.000       395.1000      2.0217396E-06
+   7600.000       404.7000      2.3198761E-06
+   7300.000       412.3000      2.4844724E-06
+   7000.000       420.4000      2.4844724E-06
+   6700.000       431.1000      2.4844724E-06
+   6400.000       442.4000      2.4844724E-06
+   6340.000       444.8000      2.4844724E-06
+   5480.000       467.8000      2.4844724E-06
+   5300.000       471.0000      2.4844724E-06
+   5000.000       476.5000      2.4844724E-06
+   4900.000       477.6000      2.4844724E-06
+   4860.000       478.0000      2.4844724E-06
+   4700.000       485.1000      2.4844724E-06
+   4500.000       494.6000      2.4844724E-06
+   3800.000       532.9000      2.4844724E-06
+   3600.000       545.6000      2.4844724E-06
+   3200.000       574.4000      2.4844724E-06
+   3000.000       585.1000      2.4844724E-06
+   2490.000       624.0000      2.4844724E-06
+   2300.000       648.9000      2.4844724E-06
+   2200.000       655.4000      2.4844724E-06
+   2080.000       663.6000      2.4844724E-06
+   2000.000       673.5000      2.4844724E-06
+   1600.000       726.4000      2.4844724E-06
+   1500.000       742.5000      2.4844724E-06
+   1430.000       750.7000      2.4844724E-06
+   1400.000       759.0000      2.4844724E-06
+   1300.000       788.6000      2.4844724E-06
+   1200.000       821.7000      2.4844724E-06
+   1190.000       825.2000      2.4844724E-06
+   1100.000       833.9000      2.4844724E-06
+   1050.000       839.0000      2.4844724E-06
+   1020.000       845.3000      2.4844724E-06
+   1000.000       851.6000      2.4844724E-06
+   950.0000       877.0000      2.4844724E-06
+   900.0000       885.6000      2.4844724E-06
+   889.9999       887.3000      2.4844724E-06
+   800.0000       926.6000      2.4844724E-06
+   760.0000       946.0000      2.4844724E-06
+   710.0000       958.0000      2.4844724E-06
+   700.0000       963.1000      2.4844724E-06
+   600.0000       20.30000      2.4844724E-06
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/002_prep_ideal_case/run_prep_ideal_xyz b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/002_prep_ideal_case/run_prep_ideal_xyz
new file mode 100755
index 0000000000000000000000000000000000000000..2cdc37f2a30123c4eb10d6e7fe0c9991ad1dc6c4
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/002_prep_ideal_case/run_prep_ideal_xyz
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+NP=${NP:-16}
+NPS=${NPS:-4}
+
+export ACC_DEVICE_TYPE=HOST
+export MPIRUN="Mpirun -tag-output -report-bindings --mca mpi_cuda_support 0 -map-by ppr:${NPS}:socket -bind-to none -np ${NP} set_core_device_impair"
+
+#
+set -x
+set -e
+#
+rm -f OUTPUT_LISTING1 pipe_name file_for_xtransfer
+rm -f PGD00064.*
+rm -f DA0064.*
+#
+ln -sf ../001_pgd1/PGD00064.* .
+#
+time ${MPIRUN} PREP_IDEAL_CASE${XYZ}
+#
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/003_mesonh_step1/EXSEG1.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/003_mesonh_step1/EXSEG1.nam
new file mode 100644
index 0000000000000000000000000000000000000000..0898b916f1f8f098f34bdeffa2a342f7296dcd8e
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/003_mesonh_step1/EXSEG1.nam
@@ -0,0 +1,55 @@
+&NAM_CONFZ
+ ! NB_PROCIO_R=1 ,
+ ! NB_PROCIO_W=1 ,
+ ! LMNH_MPI_BSEND = T ,
+ ! MPI_BUFFER_SIZE = 40
+/
+
+&NAM_LUNITn  CINIFILE = "DA0064" , CINIFILEPGD = "PGD00064" /
+&NAM_CONFn  LUSERV = T, LUSERC = T, LUSERR = T, LUSERI = T,
+            LUSERS = T, LUSERG = T, LUSERH = F, LUSECI = T /
+&NAM_DYNn  XTSTEP = 15.00000 , 
+           CPRESOPT = "ZRESI", NITR = 12
+           !CPRESOPT = "ZSOLV", NITR = 12
+           XRELAX = 1., LHORELAX_UVWTH = T, LHORELAX_RV = T, LVE_RELAX = T,
+           NRIMX = 6, NRIMY = 6, XRIMKMAX = 0.0005, XT4DIFU =  4000 /
+&NAM_ADVn  CUVW_ADV_SCHEME = "WENO_K", CMET_ADV_SCHEME = "PPM_01",
+           CSV_ADV_SCHEME = "PPM_01" /
+&NAM_PARAMn  CTURB = "TKEL" ! "NONE" ! "TKEL", 
+             CRAD = "ECMW" ! "NONE " ! "FIXE" ! "ECMW", 
+             CCLOUD = "ICE3" ! "NONE" ! "ICE3",
+             CDCONV = "NONE", CSCONV = "NONE" /
+&NAM_PARAM_RADn  XDTRAD = 1800., XDTRAD_CLONLY = 1800., LCLEAR_SKY = F,
+                 NRAD_COLNBR = 500 /
+&NAM_PARAM_MFSHALLn XIMPL_MF = 1, CMF_UPDRAFT = "EDKF", CMF_CLOUD = "NONE",
+                    LMIXUV = T, LMF_FLX = F /
+&NAM_LBCn  CLBCX = 2*"OPEN", CLBCY = 2*"OPEN", XCPHASE = 20. /
+&NAM_TURBn  XIMPL = 1., CTURBLEN = "DEAR", CTURBDIM = "3DIM",
+            LTURB_FLX = F, LTURB_DIAG = F, CSUBG_AUCV = "NONE", LSIGMAS = F,
+            LSIG_CONV = F,  LSUBG_COND = F /
+&NAM_CH_MNHCn /
+&NAM_CONF  CCONF = "START",  LFLAT = F, CEQNSYS = "DUR",
+           LLG=F, NMODEL = 1, NVERB = 0, CEXP = "D0064",
+           CSEG = "DAR01", CSPLIT = "BSPLITTING" 
+           NHALO=1
+           LCHECK=F
+           /
+&NAM_DYN  XSEGLEN =  14400.0000  ! 150. ! 21600.0000 
+          LCORIO = T,
+          LNUMDIFU = F, LNUMDIFTH = F,
+          XALKTOP = 0.001, XALZBOT = 22000. /
+&NAM_BLANK /
+&NAM_NESTING /
+&NAM_BACKUP
+ XBAK_TIME(1,1) = 3600.00000 ! 150. 
+ XBAK_TIME(1,2) = 7200.00000
+ XBAK_TIME(1,3) = 10800.0000
+ XBAK_TIME(1,4) = 14400.0000
+ XBAK_TIME(1,5) = 18000.0000
+ XBAK_TIME(1,6) = 21600.0000
+ /
+&NAM_ISBAn /
+&NAM_SEAFLUXn /
+&NAM_DIAG_SURFn LSURF_BUDGET=T /
+&NAM_DIAG_ISBAn /
+&NAM_DIAG_SURF_ATMn /
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/003_mesonh_step1/MESONH_HOST2005 b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/003_mesonh_step1/MESONH_HOST2005
new file mode 100755
index 0000000000000000000000000000000000000000..f81d930cef2e920eca3ab0fa0b8c3f4a18ce5cb3
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/003_mesonh_step1/MESONH_HOST2005
@@ -0,0 +1,5 @@
+#!/bin/bash
+export ACC_DEVICE=HOST
+ACC_DEVICE_TYPE=${ACC_DEVICE}
+exec /home/escj/DEV/MNH-55X-dev-OPENACC-juan-03/exe/MESONH${XYZ}
+
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/003_mesonh_step1/mppdb.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/003_mesonh_step1/mppdb.nam
new file mode 100644
index 0000000000000000000000000000000000000000..3c7a9f6aa3a9a8d6f7cbcee9dfc444d31a62d63e
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/003_mesonh_step1/mppdb.nam
@@ -0,0 +1,8 @@
+&NAM_MPPDB
+MPPDB_DEBUG = .F. ,
+MPPDB_NBSON = 1 ,
+!MPPDB_HOST = "localhost" ,
+MPPDB_EXEC = "/home/escj/DEV/MNH-55X-dev-OPENACC-juan-03/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/003_mesonh_step1/MESONH_HOST2005" ,
+MPPDB_WDIR = "/home/escj/DEV/MNH-55X-dev-OPENACC-juan-03/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/003_mesonh_step1/dir_clone" ,
+MPPDB_CHECK_LB = .F. 
+/ 
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/003_mesonh_step1/parameters_mg.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/003_mesonh_step1/parameters_mg.nam
new file mode 100644
index 0000000000000000000000000000000000000000..da6e1ac67e7e9cd235de8d628379403ef298c3ad
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/003_mesonh_step1/parameters_mg.nam
@@ -0,0 +1,117 @@
+! *********************************************************************
+! *********************************************************************
+! **                                                                 **
+! **    Parameter file for geometric multigrid code                  **
+! **                                                                 **
+! *********************************************************************
+! *********************************************************************
+!
+! *********************************************************************
+! * General parameters
+! *********************************************************************
+&parameters_general
+  savefields = .F.              ! Save fields to disk?
+/
+
+! *********************************************************************
+! * General solver parameters
+! *********************************************************************
+&parameters_solver
+  LUseO = T ,
+  LUseT = F ,
+  solvertype = 1,            ! Solver type:
+                             !   1 : Richardson iteration
+                             !   2 : Conjugate gradient
+  resreduction =   1e-1  ! 1.0d-10 ! Required relative residual reduction
+  maxiter = 5 ! 50                ! Maximal number of iterations
+/
+
+! *********************************************************************
+! * Conjugate gradient parameters
+! *********************************************************************
+&parameters_conjugategradient
+  verbose = 10                 ! Verbosity level
+  maxiter = 5,                ! Maximal number of iterations
+  resreduction = 1.0e-1,        ! Target residual reduction
+  n_prec = 1                    ! Number of smoother applications in
+                                ! preconditioner (N.B.: Using 0 is
+                                ! inefficient, as the identity is used
+                                ! for preconditioning, instead of using
+                                ! unpreconditioned CG.)
+/
+
+! *********************************************************************
+! * Grid parameters
+! *********************************************************************
+&parameters_grid
+  n =  64,      ! Number of horizontal grid cells
+  nz = 128,     ! Number of vertical grid cells
+  L = 204800.0  ! 32000.0 metre * 64 pt grille ! 1.0,      ! Size in horizontal direction
+  H =  19200.0  ! 150.0 metre * 128 niveaux ! 0.01,     ! Size in vertical direction
+  vertbc = 2,   ! Boundary conditions at top and bottom of the
+                ! atmosphere. 1 = DIRICHLET, 2 = NEUMANN
+                ! Note that Neumann boundary conditions only work
+                ! for coarsening in the horizontal only, as they are
+                ! not yet implemented in the prolongation operator.
+  graded = .F.  ! Is the grid graded in the vertical direction?
+/
+
+! *********************************************************************
+! * Parallel communication parameters
+! *********************************************************************
+&parameters_communication
+  halo_size = 1  ! Size of halos (has to be 1 or 2)
+/
+
+! *********************************************************************
+! * Model parameters
+! *********************************************************************
+!
+! parameters of the Helmholtz operator
+!
+! -omega2*(d^2/dy^2 + d^2/dy^2 + lambda2*d^2/dz^2) u + delta u = RHS
+!
+&parameters_model
+  omega2 = 1.0,
+  lambda2 = 1.0 ! 100.0,  ! Vertical coupling
+  delta = 0.0d0       ! Size of constant term
+/
+
+! *********************************************************************
+! * Smoother parameters
+! *********************************************************************
+!
+! parameters of the smoother
+!
+&parameters_smoother
+  smoother = 3,                 ! Smoother method
+                                !   3 = line SOR
+                                !   4 = line SSOR
+                                !   6 = line Jacobi
+  ordering = 2,                 ! Ordering of grid points (for smoother)
+                                !   1 = lexicographic
+                                !   2 = red-black ordering
+ !rho = 0.6666666666666666d0    ! Overrelaxation parameter
+ rho = 0.8d0    ! Overrelaxation parameter
+/
+
+! *********************************************************************
+! * Multigrid parameters
+! *********************************************************************
+&parameters_multigrid
+  verbose = 10,                  ! Verbosity level
+  n_lev = 7,                    ! Number of levels
+  lev_split = 3,                ! First level where data is pulled together
+  n_presmooth = 1,              ! Number of presmoothing steps
+  n_postsmooth = 1,             ! Number of postsmoothing steps
+  n_coarsegridsmooth = 1,       ! Number of smoothing steps on coarsest level
+  prolongation = 2  ! 2 best after modif !!           ! Prologation method
+                                !   1 = constant interpolation
+                                !   2 = (tri-) linear interpolation
+  restriction = 1,              ! Restriction method
+                                !   1 = cell average
+                                !   2 = Khalil         
+  coarsegridsolver = 1          ! Solver on coarsest grid
+                                !   1 = use smoother
+                                !   2 = Conjugate gradient
+/
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/003_mesonh_step1/run_mesonh_step1_xyz b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/003_mesonh_step1/run_mesonh_step1_xyz
new file mode 100755
index 0000000000000000000000000000000000000000..b139bee388f05c7a19e396a1aa2d6d5d020fbc3a
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/003_mesonh_step1/run_mesonh_step1_xyz
@@ -0,0 +1,23 @@
+
+
+#export PGI_ACC_POOL_ALLOC=0
+export PGI_ACC_SYNCHRONOUS=1
+
+NP=${NP:-16}
+NPS=${NPS:-4}
+
+export MPIRUN=${MPIRUN:-"Mpirun -tag-output -bind-to none -map-by ppr:${NPS}:socket -x PGI_ACC_POOL_ALLOC -x PGI_ACC_SYNCHRONOUS -np ${NP} set_core_device_impair "}
+
+
+#
+set -x
+set -e
+#
+rm -f DA0064.*
+rm -f PGD00064.*
+rm -f D0064.1.DAR01.* OUTPUT_LISTING* pipe_name
+#
+ln -sf ../001_pgd1/PGD00064.{des,nc} .
+ln -sf ../002_prep_ideal_case/DA0064.{des,nc} .
+#
+time ${MPIRUN} MESONH${XYZ}
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/003_mesonh_step1/run_mesonh_step1_xyz_mppdb b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/003_mesonh_step1/run_mesonh_step1_xyz_mppdb
new file mode 100755
index 0000000000000000000000000000000000000000..dc87ac29b2da19c0c0ddca9d7902e0e5d16c9f20
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/003_mesonh_step1/run_mesonh_step1_xyz_mppdb
@@ -0,0 +1,33 @@
+#!/bin/bash
+#
+set -x
+#
+
+export MPIRUN=${MPIRUN:-"Mpirun --mca btl ^openib -tag-output -report-bindings -bind-to core -x ACC_DEVICE_TYPE=HOST -np 1 "}
+
+DIR_CLONE=dir_clone
+
+mkdir -p ${DIR_CLONE}
+
+(
+
+cd ${DIR_CLONE}
+ 
+rm -f DA0064.*
+rm -f PGD00064.*
+rm -f D0064.1.DAR01.* OUTPUT_LISTING* pipe_name
+#
+ln -sf ../../001_pgd1/PGD00064.{des,nc} .
+ln -sf ../../002_prep_ideal_case/DA0064.{des,nc} .
+cp ../EXSEG1.nam .
+
+)
+
+rm -f DA0064.*
+rm -f PGD00064.*
+rm -f D0064.1.DAR01.* OUTPUT_LISTING* pipe_name
+#
+ln -sf ../001_pgd1/PGD00064.{des,nc} .
+ln -sf ../002_prep_ideal_case/DA0064.{des,nc} .
+#
+time ${MPIRUN} MESONH${XYZ}
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/004_mesonh_step2/EXSEG1.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/004_mesonh_step2/EXSEG1.nam
new file mode 100644
index 0000000000000000000000000000000000000000..a46063ee7c62303314fc9fc60781fdbb0b17ed81
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/004_mesonh_step2/EXSEG1.nam
@@ -0,0 +1,60 @@
+&NAM_CONFIO 
+    LIO_ALLOW_NO_BACKUP = T , LIO_NO_WRITE = T 
+/
+&NAM_CONFZ
+ ! NB_PROCIO_R=1 ,
+ ! NB_PROCIO_W=1 ,
+  LMNH_MPI_BSEND = F ,
+ ! MPI_BUFFER_SIZE = 40
+ !NZ_PROC=1
+/
+
+&NAM_LUNITn  CINIFILE = "D0064.1.DAR01.004" , CINIFILEPGD = "PGD00064" /
+&NAM_CONFn  LUSERV = T, LUSERC = T, LUSERR = T, LUSERI = T,
+            LUSERS = T, LUSERG = T, LUSERH = F, LUSECI = T /
+&NAM_DYNn  XTSTEP = 15.00000 , 
+           CPRESOPT = "ZRESI", 
+           !CPRESOPT = "ZSOLV", 
+           NITR = 12,
+           XRELAX = 1., LHORELAX_UVWTH = T, LHORELAX_RV = T, LVE_RELAX = T,
+           NRIMX = 6, NRIMY = 6, XRIMKMAX = 0.0005, XT4DIFU =  4000 /
+&NAM_ADVn  CUVW_ADV_SCHEME = "WENO_K", CMET_ADV_SCHEME = "PPM_01",
+           CSV_ADV_SCHEME = "PPM_01" /
+&NAM_PARAMn  CTURB = "TKEL", ! "NONE" , ! "TKEL", 
+             CRAD = "ECMWF",
+	     CCLOUD = "ICE3", ! "NONE" , ! "ICE3",
+             CDCONV = "NONE", CSCONV = "NONE" /
+&NAM_PARAM_RADn  XDTRAD = 1800., XDTRAD_CLONLY = 1800., LCLEAR_SKY = F,
+                 NRAD_COLNBR = 500 /
+&NAM_PARAM_MFSHALLn XIMPL_MF = 1, CMF_UPDRAFT = "EDKF", CMF_CLOUD = "NONE",
+                    LMIXUV = T, LMF_FLX = F /
+&NAM_LBCn  CLBCX = 2*"OPEN", CLBCY = 2*"OPEN", XCPHASE = 20. /
+&NAM_TURBn  XIMPL = 1., CTURBLEN = "DEAR", CTURBDIM = "3DIM",
+            LTURB_FLX = F, LTURB_DIAG = F, CSUBG_AUCV = "NONE", LSIGMAS = F,
+            LSIG_CONV = F,  LSUBG_COND = F /
+&NAM_CH_MNHCn /
+&NAM_CONF  CCONF = "RESTA" ! "START" ! "RESTA",  
+           LFLAT = F, CEQNSYS = "DUR",
+           LLG=F, NMODEL = 1, NVERB = 0, CEXP = "D0064",
+           CSEG = "DAR02", CSPLIT = "BSPLITTING" 
+           NHALO=1 
+           LCHECK = F /
+&NAM_DYN  XSEGLEN = 150.0 ! 150.0000 , 
+          LCORIO = T,
+          LNUMDIFU = F, LNUMDIFTH = F,
+          XALKTOP = 0.001, XALZBOT = 22000. /
+&NAM_BLANK /
+&NAM_NESTING /
+&NAM_BACKUP
+ XBAK_TIME(1,1) = 150.0 ! 3600.00000 ! 75. ! 3600.00000
+ XBAK_TIME(1,2) = 7200.00000
+ XBAK_TIME(1,3) = 10800.0000
+ XBAK_TIME(1,4) = 14400.0000
+ XBAK_TIME(1,5) = 18000.0000
+ XBAK_TIME(1,6) = 21600.0000
+ /
+&NAM_ISBAn /
+&NAM_SEAFLUXn /
+&NAM_DIAG_SURFn LSURF_BUDGET=T /
+&NAM_DIAG_ISBAn /
+&NAM_DIAG_SURF_ATMn /
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/004_mesonh_step2/MESONH_HOST2005 b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/004_mesonh_step2/MESONH_HOST2005
new file mode 100755
index 0000000000000000000000000000000000000000..07ad9fb226bfd7e7cc764749cb644e595ee25b13
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/004_mesonh_step2/MESONH_HOST2005
@@ -0,0 +1,5 @@
+#!/bin/bash
+export ACC_DEVICE=HOST
+ACC_DEVICE_TYPE=${ACC_DEVICE}
+exec /home/escj/DEV/MNH-55X-dev-OPENACC-juan-03/src/dir_obj-LXnvhpc2005-R8I4-MNH-V5-4-2-MPIAUTO-${OPTLEVEL}/ZSOLVER/MESONH
+
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/004_mesonh_step2/mppdb.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/004_mesonh_step2/mppdb.nam
new file mode 100644
index 0000000000000000000000000000000000000000..19b2bcc6e70fa54b8b1d84b2b6ba7e8c677fdcb9
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/004_mesonh_step2/mppdb.nam
@@ -0,0 +1,7 @@
+&NAM_MPPDB
+MPPDB_DEBUG = .F. ,
+MPPDB_NBSON = 1 ,
+MPPDB_EXEC = "/home/escj/DEV/MNH-55X-dev-OPENACC-juan-03/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/004_mesonh_step2/MESONH_HOST2005" ,
+MPPDB_WDIR = "/home/escj/DEV/MNH-55X-dev-OPENACC-juan-03/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/004_mesonh_step2/dir_clone" ,
+MPPDB_CHECK_LB = .F. 
+/ 
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/004_mesonh_step2/parameters_mg.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/004_mesonh_step2/parameters_mg.nam
new file mode 100644
index 0000000000000000000000000000000000000000..da6e1ac67e7e9cd235de8d628379403ef298c3ad
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/004_mesonh_step2/parameters_mg.nam
@@ -0,0 +1,117 @@
+! *********************************************************************
+! *********************************************************************
+! **                                                                 **
+! **    Parameter file for geometric multigrid code                  **
+! **                                                                 **
+! *********************************************************************
+! *********************************************************************
+!
+! *********************************************************************
+! * General parameters
+! *********************************************************************
+&parameters_general
+  savefields = .F.              ! Save fields to disk?
+/
+
+! *********************************************************************
+! * General solver parameters
+! *********************************************************************
+&parameters_solver
+  LUseO = T ,
+  LUseT = F ,
+  solvertype = 1,            ! Solver type:
+                             !   1 : Richardson iteration
+                             !   2 : Conjugate gradient
+  resreduction =   1e-1  ! 1.0d-10 ! Required relative residual reduction
+  maxiter = 5 ! 50                ! Maximal number of iterations
+/
+
+! *********************************************************************
+! * Conjugate gradient parameters
+! *********************************************************************
+&parameters_conjugategradient
+  verbose = 10                 ! Verbosity level
+  maxiter = 5,                ! Maximal number of iterations
+  resreduction = 1.0e-1,        ! Target residual reduction
+  n_prec = 1                    ! Number of smoother applications in
+                                ! preconditioner (N.B.: Using 0 is
+                                ! inefficient, as the identity is used
+                                ! for preconditioning, instead of using
+                                ! unpreconditioned CG.)
+/
+
+! *********************************************************************
+! * Grid parameters
+! *********************************************************************
+&parameters_grid
+  n =  64,      ! Number of horizontal grid cells
+  nz = 128,     ! Number of vertical grid cells
+  L = 204800.0  ! 32000.0 metre * 64 pt grille ! 1.0,      ! Size in horizontal direction
+  H =  19200.0  ! 150.0 metre * 128 niveaux ! 0.01,     ! Size in vertical direction
+  vertbc = 2,   ! Boundary conditions at top and bottom of the
+                ! atmosphere. 1 = DIRICHLET, 2 = NEUMANN
+                ! Note that Neumann boundary conditions only work
+                ! for coarsening in the horizontal only, as they are
+                ! not yet implemented in the prolongation operator.
+  graded = .F.  ! Is the grid graded in the vertical direction?
+/
+
+! *********************************************************************
+! * Parallel communication parameters
+! *********************************************************************
+&parameters_communication
+  halo_size = 1  ! Size of halos (has to be 1 or 2)
+/
+
+! *********************************************************************
+! * Model parameters
+! *********************************************************************
+!
+! parameters of the Helmholtz operator
+!
+! -omega2*(d^2/dy^2 + d^2/dy^2 + lambda2*d^2/dz^2) u + delta u = RHS
+!
+&parameters_model
+  omega2 = 1.0,
+  lambda2 = 1.0 ! 100.0,  ! Vertical coupling
+  delta = 0.0d0       ! Size of constant term
+/
+
+! *********************************************************************
+! * Smoother parameters
+! *********************************************************************
+!
+! parameters of the smoother
+!
+&parameters_smoother
+  smoother = 3,                 ! Smoother method
+                                !   3 = line SOR
+                                !   4 = line SSOR
+                                !   6 = line Jacobi
+  ordering = 2,                 ! Ordering of grid points (for smoother)
+                                !   1 = lexicographic
+                                !   2 = red-black ordering
+ !rho = 0.6666666666666666d0    ! Overrelaxation parameter
+ rho = 0.8d0    ! Overrelaxation parameter
+/
+
+! *********************************************************************
+! * Multigrid parameters
+! *********************************************************************
+&parameters_multigrid
+  verbose = 10,                  ! Verbosity level
+  n_lev = 7,                    ! Number of levels
+  lev_split = 3,                ! First level where data is pulled together
+  n_presmooth = 1,              ! Number of presmoothing steps
+  n_postsmooth = 1,             ! Number of postsmoothing steps
+  n_coarsegridsmooth = 1,       ! Number of smoothing steps on coarsest level
+  prolongation = 2  ! 2 best after modif !!           ! Prologation method
+                                !   1 = constant interpolation
+                                !   2 = (tri-) linear interpolation
+  restriction = 1,              ! Restriction method
+                                !   1 = cell average
+                                !   2 = Khalil         
+  coarsegridsolver = 1          ! Solver on coarsest grid
+                                !   1 = use smoother
+                                !   2 = Conjugate gradient
+/
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/004_mesonh_step2/run_mesonh_step2_xyz b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/004_mesonh_step2/run_mesonh_step2_xyz
new file mode 100755
index 0000000000000000000000000000000000000000..a193cf5fec9815f718964f29cfab06aeb9aaf670
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/004_mesonh_step2/run_mesonh_step2_xyz
@@ -0,0 +1,26 @@
+#!/bin/bash
+#
+#
+set -x
+
+#export PGI_ACC_POOL_ALLOC=0
+export PGI_ACC_SYNCHRONOUS=1
+#export NVCOMPILER_ACC_POOL_ALLOC=0
+
+NP=${NP:-16}
+NPS=${NPS:-4}
+
+export MPIRUN=${MPIRUN:-"Mpirun -tag-output -report-bindings -bind-to none -map-by ppr:${NPS}:socket -x NVCOMPILER_ACC_POOL_ALLOC_MAXSIZE -x NVCOMPILER_ACC_POOL_ALLOC  -x PGI_ACC_POOL_ALLOC -x PGI_ACC_SYNCHRONOUS -np ${NP} set_core_device_impair "}
+
+rm -f DA0064.*
+rm -f PGD00064.*
+rm -f D0064.1.DAR0?.* OUTPUT_LISTING1 pipe_name
+#
+ln -sf ../001_pgd1/PGD00064.* .
+ln -sf ../002_prep_ideal_case/DA0064.* .
+ln -sf ../003_mesonh_step1/D0064.1.DAR0?.* .
+#
+
+time ${MPIRUN} MESONH${XYZ}
+
+
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/004_mesonh_step2/run_mesonh_step2_xyz_mppdb b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/004_mesonh_step2/run_mesonh_step2_xyz_mppdb
new file mode 100755
index 0000000000000000000000000000000000000000..6418882ea5c933e6a77676ac1f8380356c3a19c4
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/004_mesonh_step2/run_mesonh_step2_xyz_mppdb
@@ -0,0 +1,48 @@
+#!/bin/bash
+#
+#
+ 
+set -x
+DIRCLONE=dir_clone
+mkdir -p ${DIRCLONE}
+
+export PGI_ACC_POOL_ALLOC=0
+#export PGI_ACC_POOL_SIZE=100MB
+
+export NP=${NP:-1}
+
+export MPIRUN=${MPIRUN:-Mpirun -tag-output -np ${NP}}
+
+#export PGI_ACC_NOTIFY=$(( 1+2+4+8+16+32 )) PGI_ACC_DEBUG=$(( 1+2+4+8+16+32 )) 
+#export PGI_ACC_TIME=1
+
+export PGI_ACC_SYNCHRONOUS=1
+
+(
+cd  ${DIRCLONE}
+#
+rm -f DA0064.*
+rm -f PGD00064.*
+rm -f D0064.1.DAR0?.* OUTPUT_LISTING1 pipe_name
+#
+cp ../EXSEG1.nam .
+ln -sf ../../001_pgd1/PGD00064.* .
+ln -sf ../../002_prep_ideal_case/DA0064.* .
+ln -sf ../../003_mesonh_step1/D0064.1.DAR01.* .
+#
+)
+
+#
+rm -f DA0064.*
+rm -f PGD00064.*
+rm -f D0064.1.DAR0?.* OUTPUT_LISTING1 pipe_name
+#
+ln -sf ../001_pgd1/PGD00064.* .
+ln -sf ../002_prep_ideal_case/DA0064.* .
+ln -sf ../003_mesonh_step1/D0064.1.DAR0?.* .
+#
+
+killall -r 'MESONH.*'
+time ${MPIRUN} MESONH${XYZ}
+
+
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/005_mg_main_mnh_all/parameters_mg.nam b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/005_mg_main_mnh_all/parameters_mg.nam
new file mode 120000
index 0000000000000000000000000000000000000000..adeab0e1859deb44804ccc14f23c2ccb35775079
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/005_mg_main_mnh_all/parameters_mg.nam
@@ -0,0 +1 @@
+../004_mesonh_step2/parameters_mg.nam
\ No newline at end of file
diff --git a/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/005_mg_main_mnh_all/run_mg_main_mnh_all_xyz b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/005_mg_main_mnh_all/run_mg_main_mnh_all_xyz
new file mode 100755
index 0000000000000000000000000000000000000000..c3694f2de5a11d8600af4cf5874b3248c26057f4
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/004_Hector_64x64_MNH-55X/005_mg_main_mnh_all/run_mg_main_mnh_all_xyz
@@ -0,0 +1,18 @@
+#!/bin/bash
+#
+#
+set -x
+
+#export PGI_ACC_POOL_ALLOC=0
+export PGI_ACC_SYNCHRONOUS=1
+#export NVCOMPILER_ACC_POOL_ALLOC=0
+
+NP=${NP:-16}
+NPS=${NPS:-4}
+
+export MPIRUN=${MPIRUN:-"Mpirun -tag-output -report-bindings -bind-to none -map-by ppr:${NPS}:socket -x NVCOMPILER_ACC_POOL_ALLOC_MAXSIZE -x NVCOMPILER_ACC_POOL_ALLOC  -x PGI_ACC_POOL_ALLOC -x PGI_ACC_SYNCHRONOUS -np ${NP} set_core_device_impair "}
+
+
+time ${MPIRUN} MG_MAIN_MNH_ALL${XYZ}
+
+
diff --git a/MY_RUN/BENCH/CINES_MNH55X/Clean_MNH_files b/MY_RUN/BENCH/CINES_MNH55X/Clean_MNH_files
new file mode 100755
index 0000000000000000000000000000000000000000..e866afc41566ac11d859b95cff80967138c6b4fa
--- /dev/null
+++ b/MY_RUN/BENCH/CINES_MNH55X/Clean_MNH_files
@@ -0,0 +1,5 @@
+#!/bin/bash
+find . -name '*.des' -o  -name '*.nc' -o -name '*.lfi' -o -name '*OUT*' -o -iname 'sorti*' \
+    -o -name '*.dir'  -o -name '*.hdr' -o -name 'core' -o -name file_for_xtransfer \
+    -o -name PRESSURE -o -name 'REMAP*' -o -name 'fort.*' -o -name 'timing.txt*' | xargs -n1 rm -f
+find . -type d -name 'dir_*' | xargs -n1 rm -fr
diff --git a/bin/set_core_device b/bin/set_core_device
new file mode 100755
index 0000000000000000000000000000000000000000..da13274537617e4d83a4237e17d37b321a5e1512
--- /dev/null
+++ b/bin/set_core_device
@@ -0,0 +1,51 @@
+#!/bin/bash
+
+#set -e
+#Numactl='numactl --physcpubind '
+Numactl='taskset -c '
+
+if [[ "x${SLURM_HINT}" != *nomultithread* ]]
+then
+HYP_FAC=2
+else
+HYP_FAC=1
+fi
+
+#NB_DEVICE=$( echo ${SLURM_STEP_GPUS//,/ } | wc -w )
+NB_DEVICE=$( nvidia-smi -L | grep GPU | wc -l )
+[ ${NB_DEVICE} -eq 0 ] && NB_DEVICE=1
+
+export IP=${OMPI_COMM_WORLD_RANK:-${SLURM_PROCID}}
+export LIP=${OMPI_COMM_WORLD_LOCAL_RANK:-${SLURM_LOCALID}}
+export NP=${OMPI_COMM_WORLD_SIZE:-${SLURM_NTASKS}}
+export NN=${OMPI_MCA_orte_num_nodes:-${SLURM_NNODES}}
+
+export NPN=$(( NP / NN ))
+#export NB_HYP=${SLURM_CPUS_ON_NODE}
+export NB_HYP=${SLURM_JOB_CPUS_PER_NODE/(*)/}
+export NB_CORE=$(( ${NB_HYP} / HYP_FAC ))
+export NPC=$(( NB_CORE / NPN ))
+CORE=$(( LIP * NPC ))
+
+export HALF=$(( 1+ ( NPN -1 ) / 2 ))
+export SOC=$(( 1 *( LIP / HALF ) ))
+export RANK_SOC=$(( LIP % HALF ))
+export CORE_IMP=$(( SOC + 2*NPC*RANK_SOC ))
+
+export SURBOOK=$(( NPN / NB_DEVICE ))
+
+if [ ${SURBOOK} == 0 ]
+then
+export ACC_DEVICE_NUM=$(( LIP * 2 ))
+else
+export ACC_DEVICE_NUM=$(( LIP / SURBOOK ))
+fi
+
+echo IP=${IP} LIP=${LIP} NP=${NP} NN=${NN} NPN=${NPN} NPC=${NPC} HOST=`hostname` NB_CORE=${NB_CORE} CORE=${CORE} CORE_IMP=${CORE_IMP} HALF=$HALF SOC=$SOC RS=${RANK_SOC} ND=${NB_DEVICE} CD=${ACC_DEVICE_NUM} 
+
+#EXEC=exec 
+${EXEC} ${Numactl} ${CORE} $*
+
+#exec $*
+#$*
+
diff --git a/bin/set_core_device_impair b/bin/set_core_device_impair
new file mode 100755
index 0000000000000000000000000000000000000000..fa32268b8261f661a3fc64872c5ada90da2a1ad2
--- /dev/null
+++ b/bin/set_core_device_impair
@@ -0,0 +1,51 @@
+#!/bin/bash
+
+#set -e
+#Numactl='numactl --physcpubind '
+Numactl='taskset -c '
+
+if [[ "x${SLURM_HINT}" != *nomultithread* ]]
+then
+HYP_FAC=1
+else
+HYP_FAC=1
+fi
+
+#NB_DEVICE=$( echo ${SLURM_STEP_GPUS//,/ } | wc -w )
+NB_DEVICE=$( nvidia-smi -L | grep GPU | wc -l )
+[ ${NB_DEVICE} -eq 0 ] && NB_DEVICE=1
+
+export IP=${OMPI_COMM_WORLD_RANK:-${SLURM_PROCID}}
+export LIP=${OMPI_COMM_WORLD_LOCAL_RANK:-${SLURM_LOCALID}}
+export NP=${OMPI_COMM_WORLD_SIZE:-${SLURM_NTASKS}}
+export NN=${OMPI_MCA_orte_num_nodes:-${SLURM_NNODES}}
+
+export NPN=$(( NP / NN ))
+#export NB_HYP=${SLURM_CPUS_ON_NODE}
+export NB_HYP=${SLURM_JOB_CPUS_PER_NODE/(*)/}
+export NB_CORE=$(( ${NB_HYP} / HYP_FAC ))
+export NPC=$(( NB_CORE / NPN ))
+CORE=$(( LIP * NPC ))
+
+export HALF=$(( 1+ ( NPN -1 ) / 2 ))
+export SOC=$(( 1 *( LIP / HALF ) ))
+export RANK_SOC=$(( LIP % HALF ))
+export CORE_IMP=$(( SOC + 2*NPC*RANK_SOC ))
+
+export SURBOOK=$(( NPN / NB_DEVICE ))
+
+if [ ${SURBOOK} == 0 ]
+then
+export ACC_DEVICE_NUM=$(( LIP * 2 ))
+else
+export ACC_DEVICE_NUM=$(( LIP / SURBOOK ))
+fi
+
+echo IP=${IP} LIP=${LIP} NP=${NP} NN=${NN} NPN=${NPN} NPC=${NPC} HOST=`hostname` NB_CORE=${NB_CORE} CORE=${CORE} CORE_IMP=${CORE_IMP} HALF=$HALF SOC=$SOC RS=${RANK_SOC} ND=${NB_DEVICE} CD=${ACC_DEVICE_NUM} 
+
+#EXEC=exec 
+${EXEC} ${Numactl} ${CORE_IMP} $*
+
+#exec $*
+#$*
+
diff --git a/src/LIB/BITREP/modi_bitrep.f90 b/src/LIB/BITREP/modi_bitrep.f90
index c20d803c34d4003f0783c8582c66a3de20508dba..690baf97b1fe35f09cba7f3b586342883fa1b45a 100644
--- a/src/LIB/BITREP/modi_bitrep.f90
+++ b/src/LIB/BITREP/modi_bitrep.f90
@@ -1,8 +1,15 @@
 MODULE MODI_BITREP
+!
+!    MODIFICATIONS
+!    -------------  
+! J.Escobar : 12/08/2020: for ifort18 , add intent(in) on pure function
+!-----------------------------------------------------------------
 !
   USE, INTRINSIC :: ISO_C_BINDING
 !  
   IMPLICIT NONE
+
+  REAL , PARAMETER, PRIVATE :: XPI = 3.1415926535897932384626433832795
 !
 CONTAINS
 !
@@ -16,8 +23,8 @@ INTERFACE
   PURE FUNCTION BR_ATAN_C(PIN) BIND(C,NAME="br_atan")
 !$acc routine seq
     IMPORT C_DOUBLE
-    REAL(KIND=C_DOUBLE)       :: BR_ATAN_C
-    REAL(KIND=C_DOUBLE),VALUE :: PIN
+    REAL(KIND=C_DOUBLE)                  :: BR_ATAN_C
+    REAL(KIND=C_DOUBLE),VALUE,INTENT(IN) :: PIN
   END FUNCTION
 END INTERFACE
 !
@@ -36,8 +43,8 @@ INTERFACE
   PURE FUNCTION BR_EXP_C(PIN) BIND(C,NAME="br_exp")
 !$acc routine seq
     IMPORT C_DOUBLE
-    REAL(KIND=C_DOUBLE)       :: BR_EXP_C
-    REAL(KIND=C_DOUBLE),VALUE :: PIN
+    REAL(KIND=C_DOUBLE)                  :: BR_EXP_C
+    REAL(KIND=C_DOUBLE),VALUE,INTENT(IN) :: PIN
   END FUNCTION
 END INTERFACE
 !
@@ -56,8 +63,8 @@ INTERFACE
   PURE FUNCTION BR_LOG_C(PIN) BIND(C,NAME="br_log")
 !$acc routine seq
     IMPORT C_DOUBLE
-    REAL(KIND=C_DOUBLE)       :: BR_LOG_C
-    REAL(KIND=C_DOUBLE),VALUE :: PIN
+    REAL(KIND=C_DOUBLE)                  :: BR_LOG_C
+    REAL(KIND=C_DOUBLE),VALUE,INTENT(IN) :: PIN
   END FUNCTION
 END INTERFACE
 !
@@ -107,4 +114,87 @@ BR_P4 = PVAL * PVAL * PVAL * PVAL
 !
 END FUNCTION BR_P4
 !
+ELEMENTAL FUNCTION BR_SIN(PVAL)
+!$acc routine seq
+!
+REAL, INTENT(IN) :: PVAL
+REAL             :: BR_SIN
+!
+INTERFACE
+  PURE FUNCTION BR_SIN_C(PIN) BIND(C,NAME="br_sin")
+!$acc routine seq
+    IMPORT C_DOUBLE
+    REAL(KIND=C_DOUBLE)                  :: BR_SIN_C
+    REAL(KIND=C_DOUBLE),VALUE,INTENT(IN) :: PIN
+  END FUNCTION
+END INTERFACE
+!
+BR_SIN = BR_SIN_C(REAL(PVAL,KIND=C_DOUBLE))
+!
+END FUNCTION BR_SIN
+!
+ELEMENTAL FUNCTION BR_ASIN(PVAL)
+!$acc routine seq
+!
+REAL, INTENT(IN) :: PVAL
+REAL             :: BR_ASIN
+!
+INTERFACE
+  PURE FUNCTION BR_ASIN_C(PIN) BIND(C,NAME="br_asin")
+!$acc routine seq
+    IMPORT C_DOUBLE
+    REAL(KIND=C_DOUBLE)                  :: BR_ASIN_C
+    REAL(KIND=C_DOUBLE),VALUE,INTENT(IN) :: PIN
+  END FUNCTION
+END INTERFACE
+!
+BR_ASIN = BR_ASIN_C(REAL(PVAL,KIND=C_DOUBLE))
+!
+END FUNCTION BR_ASIN
+!
+ELEMENTAL FUNCTION BR_COS(PVAL)
+!$acc routine seq
+!
+REAL, INTENT(IN) :: PVAL
+REAL             :: BR_COS
+!
+INTERFACE
+  PURE FUNCTION BR_COS_C(PIN) BIND(C,NAME="br_cos")
+!$acc routine seq
+    IMPORT C_DOUBLE
+    REAL(KIND=C_DOUBLE)                  :: BR_COS_C
+    REAL(KIND=C_DOUBLE),VALUE,INTENT(IN) :: PIN
+  END FUNCTION
+END INTERFACE
+!
+BR_COS = BR_COS_C(REAL(PVAL,KIND=C_DOUBLE))
+!
+END FUNCTION BR_COS
+!
+ELEMENTAL FUNCTION BR_ATAN2(PA,PB)
+!$acc routine seq
+!
+REAL, INTENT(IN) :: PA,PB
+REAL             :: BR_ATAN2
+!
+if (PB > 0.0) then 
+   BR_ATAN2 = br_atan(PA/PB);
+   
+else if ((PB < 0.0) .and. (PA >= 0.0)) then
+   BR_ATAN2 = br_atan(PA/PB) + XPI;
+   
+else if ((PB < 0.0) .and. (PA < 0.0)) then
+   BR_ATAN2 = br_atan(PA/PB) - XPI;
+   
+else if ((PB == 0.0) .and. (PA > 0.0)) then
+   BR_ATAN2 = XPI / 2.0 ;
+   
+else if ((PB == 0.0) .and. (PA < 0.0)) then
+   BR_ATAN2 = 0.0 - (XPI / 2.0 );
+   
+else if ((PB == 0.0) .and. (PA == 0.0)) then
+   BR_ATAN2 = 0;               ! represents undefined
+end if
+!
+  END FUNCTION BR_ATAN2
 END MODULE MODI_BITREP
diff --git a/src/LIB/SURCOUCHE/src/mode_device.f90 b/src/LIB/SURCOUCHE/src/mode_device.f90
index 4fabf5c9884c2ec2dafa859a7ef8f72049c90548..6b56e3921fdcedad18eefe96810f1ae26121d7b1 100644
--- a/src/LIB/SURCOUCHE/src/mode_device.f90
+++ b/src/LIB/SURCOUCHE/src/mode_device.f90
@@ -245,6 +245,8 @@ CONTAINS
     REAL    :: ZVALUE
     CHARACTER(LEN=:),ALLOCATABLE :: YNAME
 
+    RETURN
+    
     IF (PRESENT(PVALUE)) THEN
       ZVALUE = PVALUE
     ELSE
@@ -294,6 +296,8 @@ print *,'Initializing ',trim(YNAME),' on host'
     REAL    :: ZVALUE
     CHARACTER(LEN=:),ALLOCATABLE :: YNAME
 
+    RETURN
+    
     IF (PRESENT(PVALUE)) THEN
       ZVALUE = PVALUE
     ELSE
@@ -343,6 +347,8 @@ print *,'Initializing ',trim(YNAME),' on host'
     REAL    :: ZVALUE
     CHARACTER(LEN=:),ALLOCATABLE :: YNAME
 
+    RETURN
+    
     IF (PRESENT(PVALUE)) THEN
       ZVALUE = PVALUE
     ELSE
diff --git a/src/LIB/SURCOUCHE/src/mode_mnh_world.f90 b/src/LIB/SURCOUCHE/src/mode_mnh_world.f90
index 06d027e8a59ef393d3fb925c5948316a41d92bd0..7047c45b8500d3fb44e51210305b753b139e27e8 100644
--- a/src/LIB/SURCOUCHE/src/mode_mnh_world.f90
+++ b/src/LIB/SURCOUCHE/src/mode_mnh_world.f90
@@ -35,6 +35,7 @@ CONTAINS
     !JUANZ
 #ifdef MNH_OPENACC
     USE OPENACC
+    USE MODE_OPENACC_SET_DEVICE
 #endif
     !USE IEEE_ARITHMETIC
 
@@ -57,6 +58,11 @@ CONTAINS
     !JUANZ
     INTEGER :: ILU
 
+#ifdef MNH_OPENACC
+  CHARACTER(LEN=28)  :: CID_GPU
+  INTEGER            :: ID_GPU,N_GPU
+#endif
+  
 #if 0
     !Try to initialise device memory by creating a big array
     REAL,dimension(:,:,:),allocatable :: big
@@ -77,6 +83,26 @@ CONTAINS
     KINFO_ll = 0
     CALL MPI_INITIALIZED(GISINIT, KINFO_ll)
     IF (.NOT. GISINIT) THEN
+       
+#ifdef MNH_OPENACC
+       !
+       ! I nvidia gpu set the good one <-> ACC_DEVICE_NUM
+       ! to avoid duplication of memory be allocating each mpi task all GPU
+       !
+       N_GPU = acc_get_num_devices(acc_device_nvidia)
+       IF ( N_GPU > 0 ) THEN
+          CALL GET_ENVIRONMENT_VARIABLE("ACC_DEVICE_NUM",CID_GPU)
+          read(CID_GPU,'(I5)') ID_GPU    
+          print*,"CID_GPU=",CID_GPU," ID_GPU=",ID_GPU
+          CALL acc_set_device_num(ID_GPU,acc_device_nvidia)
+          !
+          ! get current device type for bug in atomic / nvhpc21.X
+          CALL MNH_OPENACC_GET_DEVICE_AT_INIT()
+          !
+       END IF
+!!$  ! acc init
+#endif
+  
 #ifdef MNH_GA
        CALL MPI_INIT(KINFO_ll)
 #else
diff --git a/src/LIB/SURCOUCHE/src/mode_mppdb.f90 b/src/LIB/SURCOUCHE/src/mode_mppdb.f90
index 47073588d50647e110bda3700ea3c3948c663600..28b3d7cbbb229b182a0f30d753e5def5ab16b47e 100644
--- a/src/LIB/SURCOUCHE/src/mode_mppdb.f90
+++ b/src/LIB/SURCOUCHE/src/mode_mppdb.f90
@@ -1164,7 +1164,8 @@ MODULE MODE_MPPDB
     REAL                                                   :: ZPRECISION
     REAL,DIMENSION(NMAXPAS)                                :: MAX_DIFF, MAX_VAL
     REAL,DIMENSION(SIZE(PTAB,1),SIZE(PTAB,2),SIZE(PTAB,3)) :: ZTAB
-    REAL,DIMENSION(:,:,:),ALLOCATABLE,TARGET               :: TAB_ll,TAB_SON_ll
+    REAL,DIMENSION(:,:,:,:),ALLOCATABLE,TARGET             :: TAB_ll
+    REAL,DIMENSION(:,:,:),ALLOCATABLE,TARGET               :: TAB_SON_ll
 
 #ifdef MNH_SP4
     !pas de mpi_spawn sur IBM-SP ni MPI_ARGV_NULL etc ...
@@ -1227,8 +1228,8 @@ MODULE MODE_MPPDB
           IIU_ll = IIMAX_ll+2*JPHEXT
           IJU_ll = IJMAX_ll+2*JPHEXT
           IKU_ll = SIZE(PTAB,3)
-          IF (.NOT. ALLOCATED(TAB_ll))      ALLOCATE(TAB_ll(IIU_ll,IJU_ll,IKU_ll))
-          CALL GATHERALL_FIELD_ll('XY',ZTAB,TAB_ll,IINFO_ll)
+          IF (.NOT. ALLOCATED(TAB_ll))      ALLOCATE(TAB_ll(IIU_ll,IJU_ll,IKU_ll,NPAS_ll))
+          CALL GATHERALL_FIELD_ll('XY',ZTAB,TAB_ll(:,:,:,IPAS),IINFO_ll)
 
           IF (MPPDB_IRANK_WORLD.EQ.0) THEN
              !
@@ -1255,18 +1256,18 @@ MODULE MODE_MPPDB
              CALL MPI_RECV(TAB_SON_ll,SIZE(TAB_SON_ll),MNHREAL_MPI,I_FIRST_SON, &
                   NTAG,MPPDB_INTRA_COMM,MPI_STATUS_IGNORE,IINFO_ll)
              !
-             TAB_ll      = ABS ( TAB_ll - TAB_SON_ll )
+             TAB_ll(:,:,:,IPAS)      = ABS ( TAB_ll(:,:,:,IPAS) - TAB_SON_ll(:,:,:) )
              !
              ! Set corners values to zero if we want to check the halos without the corners
              IF ( MPPDB_CHECK_LB .AND. .NOT.MPPDB_CHECK_LB_CORNERS ) THEN
-                TAB_ll(1:JPHEXT,             1:JPHEXT,             1:IKU_ll) = 0d0
-                TAB_ll(1:JPHEXT,             1:JPHEXT,             1:IKU_ll) = 0d0
-                TAB_ll(1:JPHEXT,             IJU_ll-JPHEXT:IJU_ll, 1:IKU_ll) = 0d0
-                TAB_ll(1:JPHEXT,             IJU_ll-JPHEXT:IJU_ll, 1:IKU_ll) = 0d0
-                TAB_ll(IIU_ll-JPHEXT:IIU_ll, 1:JPHEXT,             1:IKU_ll) = 0d0
-                TAB_ll(IIU_ll-JPHEXT:IIU_ll, 1:JPHEXT,             1:IKU_ll) = 0d0
-                TAB_ll(IIU_ll-JPHEXT:IIU_ll, IJU_ll-JPHEXT:IJU_ll, 1:IKU_ll) = 0d0
-                TAB_ll(IIU_ll-JPHEXT:IIU_ll, IJU_ll-JPHEXT:IJU_ll, 1:IKU_ll) = 0d0
+                TAB_ll(1:JPHEXT,             1:JPHEXT,             1:IKU_ll,IPAS) = 0d0
+                TAB_ll(1:JPHEXT,             1:JPHEXT,             1:IKU_ll,IPAS) = 0d0
+                TAB_ll(1:JPHEXT,             IJU_ll-JPHEXT:IJU_ll, 1:IKU_ll,IPAS) = 0d0
+                TAB_ll(1:JPHEXT,             IJU_ll-JPHEXT:IJU_ll, 1:IKU_ll,IPAS) = 0d0
+                TAB_ll(IIU_ll-JPHEXT:IIU_ll, 1:JPHEXT,             1:IKU_ll,IPAS) = 0d0
+                TAB_ll(IIU_ll-JPHEXT:IIU_ll, 1:JPHEXT,             1:IKU_ll,IPAS) = 0d0
+                TAB_ll(IIU_ll-JPHEXT:IIU_ll, IJU_ll-JPHEXT:IJU_ll, 1:IKU_ll,IPAS) = 0d0
+                TAB_ll(IIU_ll-JPHEXT:IIU_ll, IJU_ll-JPHEXT:IJU_ll, 1:IKU_ll,IPAS) = 0d0
                 TAB_SON_ll(1:JPHEXT,             1:JPHEXT,             1:IKU_ll) = 0d0
                 TAB_SON_ll(1:JPHEXT,             1:JPHEXT,             1:IKU_ll) = 0d0
                 TAB_SON_ll(1:JPHEXT,             IJU_ll-JPHEXT:IJU_ll, 1:IKU_ll) = 0d0
@@ -1290,7 +1291,7 @@ MODULE MODE_MPPDB
 
              MAX_VAL(IPAS)  = MAXVAL( ABS (TAB_SON_ll(IIB_SON_ll-IDIFF_HEXT:IIE_SON_ll+IDIFF_HEXT,&
                                                    IJB_SON_ll-IDIFF_HEXT:IJE_SON_ll+IDIFF_HEXT,1:IKU_SON_ll) ) )
-             MAX_DIFF(IPAS) = MAXVAL( TAB_ll(IIB_ll-IDIFF_HEXT:IIE_ll+IDIFF_HEXT,IJB_ll-IDIFF_HEXT:IJE_ll+IDIFF_HEXT,1:IKU_ll))
+             MAX_DIFF(IPAS) = MAXVAL( TAB_ll(IIB_ll-IDIFF_HEXT:IIE_ll+IDIFF_HEXT,IJB_ll-IDIFF_HEXT:IJE_ll+IDIFF_HEXT,1:IKU_ll,IPAS))
              !
              IF ( MAX_VAL(IPAS) .EQ. 0.0 ) THEN
                ZDIV=1.0
@@ -1306,7 +1307,7 @@ MODULE MODE_MPPDB
              END IF
              !flush(unit=OUTPUT_UNIT)
              !
-             DEALLOCATE(TAB_ll,TAB_SON_ll)
+             !DEALLOCATE(TAB_ll,TAB_SON_ll)
              !
           END IF
        ELSE
@@ -1317,8 +1318,8 @@ MODULE MODE_MPPDB
           IIU_ll = IIMAX_ll+2*JPHEXT
           IJU_ll = IJMAX_ll+2*JPHEXT
           IKU_ll = SIZE(PTAB,3)
-          IF (.NOT. ALLOCATED(TAB_ll)) ALLOCATE(TAB_ll(IIU_ll,IJU_ll,IKU_ll))
-          CALL GATHERALL_FIELD_ll('XY',ZTAB,TAB_ll,IINFO_ll)
+          IF (.NOT. ALLOCATED(TAB_ll)) ALLOCATE(TAB_ll(IIU_ll,IJU_ll,IKU_ll,NPAS_ll))
+          CALL GATHERALL_FIELD_ll('XY',ZTAB,TAB_ll(:,:,:,IPAS),IINFO_ll)
           !
           ! SON WORLD
           !
@@ -1331,7 +1332,7 @@ MODULE MODE_MPPDB
              CALL MPI_BSEND(IHEXT_SON_ll,1,MNHINT_MPI,I_FIRST_FATHER, &
                   NTAG, MPPDB_INTRA_COMM, IINFO_ll)
 
-             CALL MPI_BSEND(TAB_ll,SIZE(TAB_ll),MNHREAL_MPI,I_FIRST_FATHER, &
+             CALL MPI_BSEND(TAB_ll(:,:,:,IPAS),SIZE(TAB_ll(:,:,:,IPAS)),MNHREAL_MPI,I_FIRST_FATHER, &
                   NTAG, MPPDB_INTRA_COMM, IINFO_ll)
           END IF
        END IF
@@ -1402,6 +1403,7 @@ MODULE MODE_MPPDB
       ELSE
         CALL PRINT_MSG(NVERB_WARNING,'GEN','MPPDB_CHECK3D_REAL','NPAS_ll>2 not (yet) implemented')
       END IF
+     DEALLOCATE(TAB_ll,TAB_SON_ll)
     END IF
 #endif
   END SUBROUTINE MPPDB_CHECK3D_REAL
@@ -1666,7 +1668,7 @@ MODULE MODE_MPPDB
                 OK(IPAS) = .TRUE.
              END IF
              !
-             DEALLOCATE(TAB_ll,TAB_SON_ll)
+             !DEALLOCATE(TAB_ll,TAB_SON_ll)
              !
           END IF
        ELSE
@@ -1774,6 +1776,7 @@ MODULE MODE_MPPDB
       ELSE
         CALL PRINT_MSG(NVERB_WARNING,'GEN','MPPDB_CHECK2D_REAL','NPAS_ll>2 not (yet) implemented')
       END IF
+      DEALLOCATE(TAB_ll,TAB_SON_ll)
     END IF
 #endif
   END SUBROUTINE MPPDB_CHECK2D_REAL
diff --git a/src/MNH/advection_metsv.f90 b/src/MNH/advection_metsv.f90
index 6988a5a4f8ce4842fdda9543a6ffa8808287a3f7..4d98bbde12095e7dc982a4fdcba7b870b906bb14 100644
--- a/src/MNH/advection_metsv.f90
+++ b/src/MNH/advection_metsv.f90
@@ -174,7 +174,8 @@ use mode_argslist_ll,    only: ADD3DFIELD_ll, ADD4DFIELD_ll, CLEANLIST_ll, LIST_
 use mode_budget,         only: Budget_store_init, Budget_store_end
 #ifdef MNH_OPENACC
 USE MODE_DEVICE
-USE MODE_MNH_ZWORK, ONLY : ZT3D, MNH_GET_ZT3D , MNH_REL_ZT3D
+USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_ZT3D, MNH_ALLOCATE_ZT4D, MNH_CHECK_IN_ZT3D, MNH_CHECK_OUT_ZT3D, &
+                               MNH_GET_ZT3D, MNH_REL_ZT3D, MNH_REL_ZT4D, ZT3D
 #endif
 use mode_exchange_ll,    only: UPDATE_HALO_ll
 USE MODE_IO_FIELD_WRITE, only: IO_Field_write
@@ -242,45 +243,64 @@ REAL, DIMENSION(:,:,:),   INTENT(OUT)   :: PRTKES_ADV  ! Advection TKE source te
 !*       0.2   declarations of local variables
 !
 !
-REAL, DIMENSION(:,:,:),allocatable :: ZRUCPPM
-REAL, DIMENSION(:,:,:),allocatable :: ZRVCPPM
-REAL, DIMENSION(:,:,:),allocatable :: ZRWCPPM
+REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRUCPPM
+REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRVCPPM
+REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRWCPPM
                                                   ! contravariant
                                                   ! components
                                                   ! of momentum
-REAL, DIMENSION(:,:,:),allocatable :: ZCFLU
-REAL, DIMENSION(:,:,:),allocatable :: ZCFLV
-REAL, DIMENSION(:,:,:),allocatable :: ZCFLW
+REAL, DIMENSION(:,:,:),pointer , contiguous :: ZCFLU
+REAL, DIMENSION(:,:,:),pointer , contiguous :: ZCFLV
+REAL, DIMENSION(:,:,:),pointer , contiguous :: ZCFLW
 !                                                 ! CFL numbers on each direction
-REAL, DIMENSION(:,:,:),allocatable :: ZCFL
+REAL, DIMENSION(:,:,:),pointer , contiguous :: ZCFL
 !                                                 ! CFL number
+#ifdef MNH_OPENACC
+INTEGER :: IZRUCPPM,IZRVCPPM,IZRWCPPM,IZCFLU,IZCFLV,IZCFLW,IZCFL
+#endif
 !
 REAL :: ZCFLU_MAX, ZCFLV_MAX, ZCFLW_MAX, ZCFL_MAX ! maximum CFL numbers
 !
-REAL, DIMENSION(:,:,:),allocatable :: ZTH
-REAL, DIMENSION(:,:,:),allocatable :: ZTKE
-REAL, DIMENSION(:,:,:),allocatable :: ZRTHS_OTHER
-REAL, DIMENSION(:,:,:),allocatable :: ZRTKES_OTHER
-REAL, DIMENSION(:,:,:),allocatable :: ZRTHS_PPM
-REAL, DIMENSION(:,:,:),allocatable :: ZRTKES_PPM
-REAL, DIMENSION(:,:,:,:),allocatable :: ZR
-REAL, DIMENSION(:,:,:,:),allocatable :: ZSV
-REAL, DIMENSION(:,:,:,:),allocatable :: ZSNWC
-REAL, DIMENSION(:,:,:,:),allocatable :: ZSNWC_INIT
-REAL, DIMENSION(:,:,:,:),allocatable :: ZRSNWCS
+REAL, DIMENSION(:,:,:),pointer , contiguous :: ZTH
+REAL, DIMENSION(:,:,:),pointer , contiguous :: ZTKE
+REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRTHS_OTHER
+REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRTKES_OTHER
+REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRTHS_PPM
+REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRTKES_PPM
+#ifdef MNH_OPENACC
+INTEGER :: IZTH,IZTKE,IZRTHS_OTHER,IZRTKES_OTHER,IZRTHS_PPM,IZRTKES_PPM
+#endif
+REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZR
+REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZSV
+REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZSNWC
+REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZSNWC_INIT
+REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRSNWCS
+#ifdef MNH_OPENACC
+INTEGER :: IZR,IZSV,IZSNWC,IZSNWC_INIT,IZRSNWCS
+#endif
 ! Guess at the sub time step
-REAL, DIMENSION(:,:,:,:),allocatable :: ZRRS_OTHER
-REAL, DIMENSION(:,:,:,:),allocatable :: ZRSVS_OTHER
-REAL, DIMENSION(:,:,:,:),allocatable :: ZRSNWCS_OTHER
+REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRRS_OTHER
+REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRSVS_OTHER
+REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRSNWCS_OTHER
+#ifdef MNH_OPENACC
+INTEGER :: IZRRS_OTHER,IZRSVS_OTHER,IZRSNWCS_OTHER
+#endif
 ! Tendencies since the beginning of the time step
-REAL, DIMENSION(:,:,:,:),allocatable :: ZRRS_PPM
-REAL, DIMENSION(:,:,:,:),allocatable :: ZRSVS_PPM
-REAL, DIMENSION(:,:,:,:),allocatable :: ZRSNWCS_PPM
+REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRRS_PPM
+REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRSVS_PPM
+REAL, DIMENSION(:,:,:,:),pointer , contiguous :: ZRSNWCS_PPM
+#ifdef MNH_OPENACC
+INTEGER :: IZRRS_PPM,IZRSVS_PPM,IZRSNWCS_PPM   
+#endif
 ! Guess at the end of the sub time step
-REAL, DIMENSION(:,:,:),allocatable :: ZRHOX1,ZRHOX2
-REAL, DIMENSION(:,:,:),allocatable :: ZRHOY1,ZRHOY2
-REAL, DIMENSION(:,:,:),allocatable :: ZRHOZ1,ZRHOZ2
-REAL, DIMENSION(:,:,:),allocatable :: ZT,ZEXN,ZLV,ZLS,ZCPH
+REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRHOX1,ZRHOX2
+REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRHOY1,ZRHOY2
+REAL, DIMENSION(:,:,:),pointer , contiguous :: ZRHOZ1,ZRHOZ2
+REAL, DIMENSION(:,:,:),pointer , contiguous :: ZT,ZEXN,ZLV,ZLS,ZCPH
+#ifdef MNH_OPENACC
+INTEGER :: IZRHOX1,IZRHOX2,IZRHOY1,IZRHOY2,IZRHOZ1,IZRHOZ2 &
+          ,IZT,IZEXN,IZLV,IZLS,IZCPH 
+#endif
 
 ! Temporary advected rhodj for PPM routines
 !
@@ -301,6 +321,9 @@ INTEGER             :: IIB, IIE, IJB, IJE,IKB,IKE
 INTEGER :: IZ1, IZ2
 #endif
 TYPE(TFIELDDATA) :: TZFIELD
+!
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JK
 !-------------------------------------------------------------------------------
 !$acc data present( PUT, PVT, PWT, PTHT, PTKET, PRHODJ, PPABST, PRT, PSVT, PTHVREF, &
 !$acc &             PDXX, PDYY, PDZZ, PDZX, PDZY, PRTHS, PRTKES, PRRS, PRSVS, PRTHS_CLD, PRRS_CLD, PRSVS_CLD, PRTKES_ADV )
@@ -332,43 +355,87 @@ IF (MPPDB_INITIALIZED) THEN
   CALL MPPDB_CHECK(PRSVS,"ADVECTION_METSV beg:PRSVS")
 END IF
 
-allocate( ZRUCPPM      ( SIZE(PUT,  1), SIZE(PUT,  2), SIZE(PUT,  3) )               )
-allocate( ZRVCPPM      ( SIZE(PUT,  1), SIZE(PUT,  2), SIZE(PUT,  3) )               )
-allocate( ZRWCPPM      ( SIZE(PUT,  1), SIZE(PUT,  2), SIZE(PUT,  3) )               )
-allocate( ZCFLU        ( SIZE(PUT,  1), SIZE(PUT,  2), SIZE(PUT,  3) )               )
-allocate( ZCFLV        ( SIZE(PUT,  1), SIZE(PUT,  2), SIZE(PUT,  3) )               )
-allocate( ZCFLW        ( SIZE(PUT,  1), SIZE(PUT,  2), SIZE(PUT,  3) )               )
-allocate( ZCFL         ( SIZE(PUT,  1), SIZE(PUT,  2), SIZE(PUT,  3) )               )
-allocate( ZTH          ( SIZE(PTHT, 1), SIZE(PTHT, 2), SIZE(PTHT, 3) )               )
-allocate( ZTKE         ( SIZE(PTKET,1), SIZE(PTKET,2), SIZE(PTKET,3) )               )
-allocate( ZRTHS_OTHER  ( SIZE(PTHT, 1), SIZE(PTHT, 2), SIZE(PTHT, 3) )               )
-allocate( ZRTKES_OTHER ( SIZE(PTKET,1), SIZE(PTKET,2), SIZE(PTKET,3) )               )
-allocate( ZRTHS_PPM    ( SIZE(PTHT, 1), SIZE(PTHT, 2), SIZE(PTHT, 3) )               )
-allocate( ZRTKES_PPM   ( SIZE(PTKET,1), SIZE(PTKET,2), SIZE(PTKET,3) )               )
-allocate( ZR           ( SIZE(PRT,  1), SIZE(PRT,  2), SIZE(PRT,  3), SIZE(PRT, 4) ) )
-allocate( ZSV          ( SIZE(PSVT, 1), SIZE(PSVT, 2), SIZE(PSVT, 3), SIZE(PSVT,4) ) )
-allocate( ZSNWC        ( SIZE(PSVT, 1), SIZE(PSVT, 2), SIZE(PSVT, 3), NBLOWSNOW_2D ) )
-allocate( ZSNWC_INIT   ( SIZE(PSVT, 1), SIZE(PSVT, 2), SIZE(PSVT, 3), NBLOWSNOW_2D ) )
-allocate( ZRSNWCS      ( SIZE(PSVT, 1), SIZE(PSVT, 2), SIZE(PSVT, 3), NBLOWSNOW_2D ) )
-allocate( ZRRS_OTHER   ( SIZE(PRT,  1), SIZE(PRT,  2), SIZE(PRT,  3), SIZE(PRT, 4) ) )
-allocate( ZRSVS_OTHER  ( SIZE(PSVT, 1), SIZE(PSVT, 2), SIZE(PSVT, 3), SIZE(PSVT,4) ) )
-allocate( ZRSNWCS_OTHER( SIZE(PSVT, 1), SIZE(PSVT, 2), SIZE(PSVT, 3), NBLOWSNOW_2D ) )
-allocate( ZRRS_PPM     ( SIZE(PRT,  1), SIZE(PRT,  2), SIZE(PRT,  3), SIZE(PRT, 4) ) )
-allocate( ZRSVS_PPM    ( SIZE(PSVT, 1), SIZE(PSVT, 2), SIZE(PSVT, 3), SIZE(PSVT,4) ) )
-allocate( ZRSNWCS_PPM  ( SIZE(PSVT, 1), SIZE(PSVT, 2), SIZE(PSVT, 3), NBLOWSNOW_2D ) )
-allocate( ZRHOX1       ( SIZE(PUT,  1), SIZE(PUT,  2), SIZE(PUT,  3) )               )
-allocate( ZRHOX2       ( SIZE(PUT,  1), SIZE(PUT,  2), SIZE(PUT,  3) )               )
-allocate( ZRHOY1       ( SIZE(PUT,  1), SIZE(PUT,  2), SIZE(PUT,  3) )               )
-allocate( ZRHOY2       ( SIZE(PUT,  1), SIZE(PUT,  2), SIZE(PUT,  3) )               )
-allocate( ZRHOZ1       ( SIZE(PUT,  1), SIZE(PUT,  2), SIZE(PUT,  3) )               )
-allocate( ZRHOZ2       ( SIZE(PUT,  1), SIZE(PUT,  2), SIZE(PUT,  3) )               )
-allocate( ZT           ( SIZE(PUT,  1), SIZE(PUT,  2), SIZE(PUT,  3) )               )
-allocate( ZEXN         ( SIZE(PUT,  1), SIZE(PUT,  2), SIZE(PUT,  3) )               )
-allocate( ZLV          ( SIZE(PUT,  1), SIZE(PUT,  2), SIZE(PUT,  3) )               )
-allocate( ZLS          ( SIZE(PUT,  1), SIZE(PUT,  2), SIZE(PUT,  3) )               )
-allocate( ZCPH         ( SIZE(PUT,  1), SIZE(PUT,  2), SIZE(PUT,  3) )               )
+JIU =  size(PUT, 1 )
+JJU =  size(PUT, 2 )
+JKU =  size(PUT, 3 )
+
+
+#ifndef MNH_OPENACC
+allocate( ZRUCPPM      ( JIU,JJU,JKU )               )
+allocate( ZRVCPPM      ( JIU,JJU,JKU )               )
+allocate( ZRWCPPM      ( JIU,JJU,JKU )               )
+allocate( ZCFLU        ( JIU,JJU,JKU )               )
+allocate( ZCFLV        ( JIU,JJU,JKU )               )
+allocate( ZCFLW        ( JIU,JJU,JKU )               )
+allocate( ZCFL         ( JIU,JJU,JKU )               )
+allocate( ZTH          ( JIU,JJU,JKU )               )
+allocate( ZTKE         ( JIU,JJU,SIZE(PTKET,3))      )
+allocate( ZRTHS_OTHER  ( JIU,JJU,JKU )               )
+allocate( ZRTKES_OTHER ( JIU,JJU,SIZE(PTKET,3))      )
+allocate( ZRTHS_PPM    ( JIU,JJU,JKU )               )
+allocate( ZRTKES_PPM   ( JIU,JJU,SIZE(PTKET,3))      )
+allocate( ZR           ( JIU,JJU,JKU, SIZE(PRT, 4) ) )
+allocate( ZSV          ( JIU,JJU,JKU, SIZE(PSVT,4) ) )
+allocate( ZSNWC        ( JIU,JJU,JKU, NBLOWSNOW_2D ) )
+allocate( ZSNWC_INIT   ( JIU,JJU,JKU, NBLOWSNOW_2D ) )
+allocate( ZRSNWCS      ( JIU,JJU,JKU, NBLOWSNOW_2D ) )
+allocate( ZRRS_OTHER   ( JIU,JJU,JKU, SIZE(PRT, 4) ) )
+allocate( ZRSVS_OTHER  ( JIU,JJU,JKU, SIZE(PSVT,4) ) )
+allocate( ZRSNWCS_OTHER( JIU,JJU,JKU, NBLOWSNOW_2D ) )
+allocate( ZRRS_PPM     ( JIU,JJU,JKU, SIZE(PRT, 4) ) )
+allocate( ZRSVS_PPM    ( JIU,JJU,JKU, SIZE(PSVT,4) ) )
+allocate( ZRSNWCS_PPM  ( JIU,JJU,JKU, NBLOWSNOW_2D ) )
+allocate( ZRHOX1       ( JIU,JJU,JKU )               )
+allocate( ZRHOX2       ( JIU,JJU,JKU )               )
+allocate( ZRHOY1       ( JIU,JJU,JKU )               )
+allocate( ZRHOY2       ( JIU,JJU,JKU )               )
+allocate( ZRHOZ1       ( JIU,JJU,JKU )               )
+allocate( ZRHOZ2       ( JIU,JJU,JKU )               )
+allocate( ZT           ( JIU,JJU,JKU )               )
+allocate( ZEXN         ( JIU,JJU,JKU )               )
+allocate( ZLV          ( JIU,JJU,JKU )               )
+allocate( ZLS          ( JIU,JJU,JKU )               )
+allocate( ZCPH         ( JIU,JJU,JKU )               )
+#else
+CALL MNH_CHECK_IN_ZT3D("ADVECTION_METSV")
+IZRUCPPM       = MNH_ALLOCATE_ZT3D( ZRUCPPM      , JIU,JJU,JKU                )
+IZRVCPPM       = MNH_ALLOCATE_ZT3D( ZRVCPPM      , JIU,JJU,JKU                )
+IZRWCPPM       = MNH_ALLOCATE_ZT3D( ZRWCPPM      , JIU,JJU,JKU                )
+IZCFLU         = MNH_ALLOCATE_ZT3D( ZCFLU        , JIU,JJU,JKU                )
+IZCFLV         = MNH_ALLOCATE_ZT3D( ZCFLV        , JIU,JJU,JKU                )
+IZCFLW         = MNH_ALLOCATE_ZT3D( ZCFLW        , JIU,JJU,JKU                )
+IZCFL          = MNH_ALLOCATE_ZT3D( ZCFL         , JIU,JJU,JKU                )
+IZTH           = MNH_ALLOCATE_ZT3D( ZTH          , JIU,JJU,JKU                )
+IZTKE          = MNH_ALLOCATE_ZT3D( ZTKE         , JIU,JJU,SIZE(PTKET,3)      )
+IZRTHS_OTHER   = MNH_ALLOCATE_ZT3D( ZRTHS_OTHER  , JIU,JJU,JKU                )
+IZRTKES_OTHER  = MNH_ALLOCATE_ZT3D( ZRTKES_OTHER , JIU,JJU,SIZE(PTKET,3)      )
+IZRTHS_PPM     = MNH_ALLOCATE_ZT3D( ZRTHS_PPM    , JIU,JJU,JKU                )
+IZRTKES_PPM    = MNH_ALLOCATE_ZT3D( ZRTKES_PPM   , JIU,JJU,SIZE(PTKET,3)      )
+IZR            = MNH_ALLOCATE_ZT4D( ZR           , JIU,JJU,JKU, SIZE(PRT, 4)  )
+IZSV           = MNH_ALLOCATE_ZT4D( ZSV          , JIU,JJU,JKU, SIZE(PSVT,4)  )
+IZSNWC         = MNH_ALLOCATE_ZT4D( ZSNWC        , JIU,JJU,JKU, NBLOWSNOW_2D  )
+IZSNWC_INIT    = MNH_ALLOCATE_ZT4D( ZSNWC_INIT   , JIU,JJU,JKU, NBLOWSNOW_2D  )
+IZRSNWCS       = MNH_ALLOCATE_ZT4D( ZRSNWCS      , JIU,JJU,JKU, NBLOWSNOW_2D  )
+IZRRS_OTHER    = MNH_ALLOCATE_ZT4D( ZRRS_OTHER   , JIU,JJU,JKU, SIZE(PRT, 4)  )
+IZRSVS_OTHER   = MNH_ALLOCATE_ZT4D( ZRSVS_OTHER  , JIU,JJU,JKU, SIZE(PSVT,4)  )
+IZRSNWCS_OTHER = MNH_ALLOCATE_ZT4D( ZRSNWCS_OTHER, JIU,JJU,JKU, NBLOWSNOW_2D  )
+IZRRS_PPM      = MNH_ALLOCATE_ZT4D( ZRRS_PPM     , JIU,JJU,JKU, SIZE(PRT, 4)  )
+IZRSVS_PPM     = MNH_ALLOCATE_ZT4D( ZRSVS_PPM    , JIU,JJU,JKU, SIZE(PSVT,4)  )
+IZRSNWCS_PPM   = MNH_ALLOCATE_ZT4D( ZRSNWCS_PPM  , JIU,JJU,JKU, NBLOWSNOW_2D  )
+IZRHOX1        = MNH_ALLOCATE_ZT3D( ZRHOX1       , JIU,JJU,JKU                )
+IZRHOX2        = MNH_ALLOCATE_ZT3D( ZRHOX2       , JIU,JJU,JKU                )
+IZRHOY1        = MNH_ALLOCATE_ZT3D( ZRHOY1       , JIU,JJU,JKU                )
+IZRHOY2        = MNH_ALLOCATE_ZT3D( ZRHOY2       , JIU,JJU,JKU                )
+IZRHOZ1        = MNH_ALLOCATE_ZT3D( ZRHOZ1       , JIU,JJU,JKU                )
+IZRHOZ2        = MNH_ALLOCATE_ZT3D( ZRHOZ2       , JIU,JJU,JKU                )
+IZT            = MNH_ALLOCATE_ZT3D( ZT           , JIU,JJU,JKU                )
+IZEXN          = MNH_ALLOCATE_ZT3D( ZEXN         , JIU,JJU,JKU                )
+IZLV           = MNH_ALLOCATE_ZT3D( ZLV          , JIU,JJU,JKU                )
+IZLS           = MNH_ALLOCATE_ZT3D( ZLS          , JIU,JJU,JKU                )
+IZCPH          = MNH_ALLOCATE_ZT3D( ZCPH         , JIU,JJU,JKU                )
+#endif
 
-!$acc data create( ZRUCPPM, ZRVCPPM, ZRWCPPM, ZCFLU, ZCFLV, ZCFLW, ZCFL, ZTH,                        &
+!$acc data present( ZRUCPPM, ZRVCPPM, ZRWCPPM, ZCFLU, ZCFLV, ZCFLW, ZCFL, ZTH,                        &
 !$acc &            ZTKE, ZRTHS_OTHER, ZRTKES_OTHER, ZRTHS_PPM, ZRTKES_PPM,                           &
 !$acc &            ZR, ZSV, ZSNWC, ZSNWC_INIT, ZRSNWCS, ZRRS_OTHER, ZRSVS_OTHER, ZRSNWCS_OTHER,      &
 !$acc &            ZRRS_PPM, ZRSVS_PPM, ZRSNWCS_PPM, ZRHOX1, ZRHOX2, ZRHOY1, ZRHOY2, ZRHOZ1, ZRHOZ2, &
@@ -473,8 +540,9 @@ END IF
 !*       2.2 computes CFL numbers
 !
 !PW: not necessary: data already on device due to contrav_device !$acc update device(ZRUCPPM,ZRVCPPM,ZRWCPPM)
-!$acc kernels
+! acc kernels
 IF (.NOT. L1D) THEN
+  !$acc kernels 
   ZCFLU(:,:,:) = 0.0 ; ZCFLV(:,:,:) = 0.0 ;  ZCFLW(:,:,:) = 0.0
   ZCFLU(IIB:IIE,IJB:IJE,:) = ABS(ZRUCPPM(IIB:IIE,IJB:IJE,:) * PTSTEP)
   ZCFLV(IIB:IIE,IJB:IJE,:) = ABS(ZRVCPPM(IIB:IIE,IJB:IJE,:) * PTSTEP)
@@ -499,29 +567,49 @@ IF (.NOT. L1D) THEN
     WHERE (XIBM_LS(IIB:IIE,IJB:IJE,:,3).GT.(-XIBM_EPSI)) ZCFLV(IIB:IIE,IJB:IJE,:)=0.
     WHERE (XIBM_LS(IIB:IIE,IJB:IJE,:,4).GT.(-XIBM_EPSI)) ZCFLW(IIB:IIE,IJB:IJE,:)=0.
   ENDIF
+  !$acc end kernels
 #ifndef MNH_BITREP
   IF (.NOT. L2D) THEN
-    ZCFL(:,:,:)  = SQRT(ZCFLU(:,:,:)**2+ZCFLV(:,:,:)**2+ZCFLW(:,:,:)**2)
+     !$acc kernels 
+     ZCFL(:,:,:)  = SQRT(ZCFLU(:,:,:)**2+ZCFLV(:,:,:)**2+ZCFLW(:,:,:)**2)
+     !$acc end kernels
   ELSE
-    ZCFL(:,:,:)  = SQRT(ZCFLU(:,:,:)**2+ZCFLW(:,:,:)**2)
+     !$acc kernels
+     ZCFL(:,:,:)  = SQRT(ZCFLU(:,:,:)**2+ZCFLW(:,:,:)**2)
+     !$acc end kernels
   END IF
 #else
   IF (.NOT. L2D) THEN
-    ZCFL(:,:,:)  = SQRT(BR_P2(ZCFLU(:,:,:))+BR_P2(ZCFLV(:,:,:))+BR_P2(ZCFLW(:,:,:)))
+     !$acc kernels
+     !$acc loop independent collapse(3)
+     DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU )
+        ZCFL(JI,JJ,JK)  = SQRT(BR_P2(ZCFLU(JI,JJ,JK))+BR_P2(ZCFLV(JI,JJ,JK))+BR_P2(ZCFLW(JI,JJ,JK)))
+     END DO
+     !$acc end kernels
   ELSE
-    ZCFL(:,:,:)  = SQRT(BR_P2(ZCFLU(:,:,:))+BR_P2(ZCFLW(:,:,:)))
+     !$acc kernels
+     !$acc loop independent collapse(3)
+     DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU )
+        ZCFL(JI,JJ,JK)  = SQRT(BR_P2(ZCFLU(JI,JJ,JK))+BR_P2(ZCFLW(JI,JJ,JK)))
+     END DO
+     !$acc end kernels
   END IF
-#endif
+#endif 
 ELSE
+   !$acc kernels
    ZCFLU(:,:,:) = 0.0 ; ZCFLV(:,:,:) = 0.0 ;  ZCFLW(:,:,:) = 0.0
    ZCFLW(IIB:IIE,IJB:IJE,:) = ABS(ZRWCPPM(IIB:IIE,IJB:IJE,:) * PTSTEP)
 #ifndef MNH_BITREP
    ZCFL(:,:,:) = SQRT(ZCFLW(:,:,:)**2)
 #else
-   ZCFL(:,:,:) = SQRT(BR_P2(ZCFLW(:,:,:)))
+   !$acc loop independent collapse(3)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU )
+      ZCFL(JI,JJ,JK) = SQRT(BR_P2(ZCFLW(JI,JJ,JK)))
+   END DO
 #endif
+   !$acc end kernels
 END IF
-!$acc end kernels
+! acc end kernels
 !
 !* prints in the file the 3D Courant numbers (one should flag this)
 !
@@ -721,6 +809,7 @@ END IF
 !
 ! Exchanges on processors
 !
+#ifndef MNH_OPENACC
 NULLIFY(TZFIELDS0_ll)
 !!$IF(NHALO == 1) THEN
   CALL ADD3DFIELD_ll( TZFIELDS0_ll, ZRTHS_OTHER, 'ADVECTION_METSV::ZRTHS_OTHER' )
@@ -731,8 +820,23 @@ NULLIFY(TZFIELDS0_ll)
   CALL UPDATE_HALO_ll(TZFIELDS0_ll,IINFO_ll)
   CALL CLEANLIST_ll(TZFIELDS0_ll)
 !!$END IF
-!PW: TODO: update only what is needed...
-!$acc update device(ZRTHS_OTHER,ZRTKES_OTHER,ZRRS_OTHER,ZRSVS_OTHER)
+#else
+  CALL GET_HALO_D(ZRTHS_OTHER, HNAME='ADVECTION_METSV::ZRTHS_OTHER')
+  IF (GTKE) CALL GET_HALO_D(ZRTKES_OTHER,HNAME='ADVECTION_METSV::ZRTKES_OTHER')
+  DO JR=1,KRR
+     CALL GET_HALO_D(ZRRS_OTHER(:,:,:,JR),HNAME='ADVECTION_METSV::ZRRS_OTHER')
+  END DO
+  DO JSV = 1, KSV
+     CALL GET_HALO_D(ZRSVS_OTHER(:,:,:,JSV),HNAME='ADVECTION_METSV::ZRSVS_OTHER')
+  END DO
+  DO JSV = 1,NBLOWSNOW_2D
+     CALL GET_HALO_D(ZRSNWCS_OTHER(:,:,:,JSV),HNAME='ADVECTION_METSV::ZRSNWCS_OTHER')
+  END DO
+  !PW: TODO: update only what is needed...
+  ! acc update device(ZRTHS_OTHER,ZRTKES_OTHER,ZRRS_OTHER,ZRSVS_OTHER)
+#endif
+  
+
 !
 !
 
@@ -748,11 +852,13 @@ CALL PPM_RHODJ(HLBCX,HLBCY, ZRUCPPM, ZRVCPPM, ZRWCPPM,              &
 !* values of the fields at the beginning of the time splitting loop
 !$acc kernels
 ZTH(:,:,:)  = PTHT(:,:,:)
-ZTKE(:,:,:) = PTKET(:,:,:)
 IF (KRR /=0 ) ZR(:,:,:,:)  = PRT(:,:,:,:)
 IF (KSV /=0 ) ZSV(:,:,:,:) = PSVT(:,:,:,:)
 !
-IF (GTKE)    PRTKES_ADV(:,:,:)  = 0.
+IF (GTKE)  THEN
+   PRTKES_ADV(:,:,:)  = 0.
+   ZTKE(:,:,:) = PTKET(:,:,:)
+END IF
 !$acc end kernels
 !
 IF(LBLOWSNOW) THEN
@@ -793,29 +899,44 @@ DO JSPL=1,KSPLIT
 !
 ! Tendencies of PPM
 !
-!$acc kernels
+! acc kernels
+   !$acc kernels
    PRTHS(:,:,:)                      = PRTHS     (:,:,:)   + ZRTHS_PPM (:,:,:)   / KSPLIT
    IF (GTKE)     PRTKES_ADV(:,:,:)   = PRTKES_ADV(:,:,:)   + ZRTKES_PPM(:,:,:)   / KSPLIT
    IF (KRR /=0)  PRRS      (:,:,:,:) = PRRS      (:,:,:,:) + ZRRS_PPM  (:,:,:,:) / KSPLIT
    IF (KSV /=0 ) PRSVS     (:,:,:,:) = PRSVS     (:,:,:,:) + ZRSVS_PPM (:,:,:,:) / KSPLIT
+   !$acc end kernels
 !
    IF (JSPL<KSPLIT) THEN
 !
 !  Guesses of the field inside the time splitting loop
 !
+   !$acc kernels   
    ZTH(:,:,:) = ZTH(:,:,:) + ( ZRTHS_PPM(:,:,:) + ZRTHS_OTHER(:,:,:) + PRTHS_CLD(:,:,:)) * &
-           ZTSTEP_PPM / PRHODJ(:,:,:)
-   IF (GTKE) ZTKE(:,:,:) = ZTKE(:,:,:) + ( ZRTKES_PPM(:,:,:) + ZRTKES_OTHER(:,:,:) ) * ZTSTEP_PPM / PRHODJ(:,:,:)
-   DO JR = 1, KRR
-    ZR(:,:,:,JR) = ZR(:,:,:,JR) + ( ZRRS_PPM(:,:,:,JR) + ZRRS_OTHER(:,:,:,JR) + PRRS_CLD(:,:,:,JR) ) &
-                    * ZTSTEP_PPM / PRHODJ(:,:,:)
-   END DO
+        ZTSTEP_PPM / PRHODJ(:,:,:)
+   !$acc end kernels
+   IF (GTKE) THEN
+      !$acc kernels
+      ZTKE(:,:,:) = ZTKE(:,:,:) + ( ZRTKES_PPM(:,:,:) + ZRTKES_OTHER(:,:,:) ) * ZTSTEP_PPM / PRHODJ(:,:,:)
+      !$acc end kernels
+   END IF
+   !$acc kernels
+   !$acc loop independent collapse(4)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU, JR=1:KRR )
+      ZR(JI,JJ,JK,JR) = ZR(JI,JJ,JK,JR) + ( ZRRS_PPM(JI,JJ,JK,JR) + ZRRS_OTHER(JI,JJ,JK,JR) + PRRS_CLD(JI,JJ,JK,JR) ) &
+           * ZTSTEP_PPM / PRHODJ(JI,JJ,JK)
+   END DO !CONCURRENT 
+   !$acc loop seq
    DO JSV = 1, KSV
-    ZSV(:,:,:,JSV) = ZSV(:,:,:,JSV) + ( ZRSVS_PPM(:,:,:,JSV) + ZRSVS_OTHER(:,:,:,JSV) +  &
-                     PRSVS_CLD(:,:,:,JSV) ) * ZTSTEP_PPM / PRHODJ(:,:,:)
+      !$acc loop independent collapse(3)
+      DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+         ZSV(JI,JJ,JK,JSV) = ZSV(JI,JJ,JK,JSV) + ( ZRSVS_PPM(JI,JJ,JK,JSV) + ZRSVS_OTHER(JI,JJ,JK,JSV) +  &
+              PRSVS_CLD(JI,JJ,JK,JSV) ) * ZTSTEP_PPM / PRHODJ(JI,JJ,JK)
+      END DO !CONCURRENT 
    END DO
+   !$acc end kernels
    END IF
-!$acc end kernels
+! acc end kernels
 
 !PW: bug PGI 18.10: not necessary for PRRS,PRSVS but error with decriptor not present
 !$acc update self(PRRS,PRSVS)
@@ -868,6 +989,7 @@ DO JSPL=1,KSPLIT
 !
 !  Exchanges fields between processors
 !
+#ifndef MNH_OPENACC   
    NULLIFY(TZFIELDS1_ll)
 !!$   IF(NHALO == 1) THEN
     CALL ADD3DFIELD_ll( TZFIELDS1_ll, ZTH, 'ZTH' )
@@ -878,7 +1000,21 @@ DO JSPL=1,KSPLIT
     CALL UPDATE_HALO_ll(TZFIELDS1_ll,IINFO_ll)
     CALL CLEANLIST_ll(TZFIELDS1_ll)
 !!$   END IF
-   END IF
+#else
+    CALL GET_HALO_D(ZTH,HNAME='ZTH')
+    IF (GTKE) CALL GET_HALO_D(ZTKE,HNAME='ADVECTION_METSV::ZTKE')
+    DO JR=1,KRR
+       CALL GET_HALO_D(ZR(:,:,:,JR),HNAME='ADVECTION_METSV::ZR')
+    END DO
+    DO JSV = 1, KSV
+       CALL GET_HALO_D(ZSV(:,:,:,JSV),HNAME='ADVECTION_METSV::ZSV')
+    END DO
+    DO JSV = 1,NBLOWSNOW_2D
+       CALL GET_HALO_D(ZSNWC(:,:,:,JSV),HNAME='ADVECTION_METSV::ZSNWC')
+    END DO
+#endif
+    
+ END IF
 !
 END DO
 !
@@ -954,6 +1090,33 @@ END IF
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate ( ZRUCPPM, ZRVCPPM, ZRWCPPM, ZCFLU, ZCFLV, ZCFLW, ZCFL, ZTH,                       &
+            ZTKE, ZRTHS_OTHER, ZRTKES_OTHER, ZRTHS_PPM, ZRTKES_PPM,                           &
+            ZR, ZSV, ZSNWC, ZSNWC_INIT, ZRSNWCS, ZRRS_OTHER, ZRSVS_OTHER, ZRSNWCS_OTHER,      &
+            ZRRS_PPM, ZRSVS_PPM, ZRSNWCS_PPM, ZRHOX1, ZRHOX2, ZRHOY1, ZRHOY2, ZRHOZ1, ZRHOZ2, &
+            ZT, ZEXN, ZLV, ZLS, ZCPH                                                          )
+#else
+CALL MNH_REL_ZT3D ( IZRHOX1, IZRHOX2, IZRHOY1, IZRHOY2, IZRHOZ1, IZRHOZ2, &
+     IZT, IZEXN, IZLV, IZLS, IZCPH                         )
+
+CALL MNH_REL_ZT4D ( NBLOWSNOW_2D , IZRSNWCS_PPM )
+CALL MNH_REL_ZT4D ( SIZE(PSVT,4) , IZRSVS_PPM )
+CALL MNH_REL_ZT4D ( SIZE(PRT, 4) , IZRRS_PPM )
+CALL MNH_REL_ZT4D ( NBLOWSNOW_2D , IZRSNWCS_OTHER )
+CALL MNH_REL_ZT4D ( SIZE(PSVT,4) , IZRSVS_OTHER )
+CALL MNH_REL_ZT4D ( SIZE(PRT, 4) , IZRRS_OTHER )
+CALL MNH_REL_ZT4D ( NBLOWSNOW_2D , IZRSNWCS )
+CALL MNH_REL_ZT4D ( NBLOWSNOW_2D , IZSNWC_INIT )
+CALL MNH_REL_ZT4D ( NBLOWSNOW_2D , IZSNWC )
+CALL MNH_REL_ZT4D ( SIZE(PSVT,4) , IZSV )
+CALL MNH_REL_ZT4D ( SIZE(PRT, 4) , IZR ) 
+
+CALL MNH_REL_ZT3D ( IZRUCPPM, IZRVCPPM, IZRWCPPM, IZCFLU, IZCFLV, IZCFLW, IZCFL, IZTH, &
+                    IZTKE, IZRTHS_OTHER, IZRTKES_OTHER, IZRTHS_PPM, IZRTKES_PPM        )
+CALL MNH_CHECK_OUT_ZT3D("ADVECTION_METSV")
+#endif
+
 !$acc end data
 
 END SUBROUTINE ADVECTION_METSV
diff --git a/src/MNH/advection_uvw.f90 b/src/MNH/advection_uvw.f90
index d005a36253abda9e818988769e609c91e7d85763..9451c5fbf499ed7621af282cf45f439484ea4a35 100644
--- a/src/MNH/advection_uvw.f90
+++ b/src/MNH/advection_uvw.f90
@@ -117,6 +117,7 @@ USE MODI_CONTRAV
 #ifndef MNH_OPENACC
 USE MODI_SHUMAN
 #else
+USE MODI_GET_HALO,    ONLY: GET_HALO_D
 USE MODI_SHUMAN_DEVICE
 #endif
 !
@@ -245,7 +246,7 @@ ALLOCATE( ZMZM_RHODJ( SIZE(PUT,1), SIZE(PUT,2), SIZE(PUT,3) ) )
 
 !$acc data create( zrut, zrvt, zrwt, zruct, zrvct, zrwct, zu, zv, zw,                &
 !$acc &            zrus_other, zrvs_other, zrws_other, zrus_adv, zrvs_adv, zrws_adv, &
-!$acc &            zrus_adv, zrvs_adv, zrws_adv, zmxm_rhodj, zmym_rhodj, zmzm_rhodj  )
+!$acc &            zmxm_rhodj, zmym_rhodj, zmzm_rhodj  )
 
 #ifdef MNH_OPENACC
 #if 0
@@ -327,8 +328,9 @@ ZRUT(:,:,:) = PUT(:,:,:) * ZMXM_RHODJ(:,:,:)
 ZRVT(:,:,:) = PVT(:,:,:) * ZMYM_RHODJ(:,:,:)
 ZRWT(:,:,:) = PWT(:,:,:) * ZMZM_RHODJ(:,:,:)
 !$acc end kernels
-!$acc update self(ZRUT,ZRVT)
+
 !
+#ifndef MNH_OPENACC
 NULLIFY(TZFIELD_ll)
 !!$IF(NHALO == 1) THEN
   CALL ADD3DFIELD_ll( TZFIELD_ll, ZRUT, 'ADVECTION_UVW::ZRUT' )
@@ -336,7 +338,14 @@ NULLIFY(TZFIELD_ll)
   CALL UPDATE_HALO_ll(TZFIELD_ll,IINFO_ll)
   CALL CLEANLIST_ll(TZFIELD_ll)
 !!$END IF
-!$acc update device(ZRUT,ZRVT)
+#else
+! acc update self(ZRUT,ZRVT)  
+  CALL GET_HALO_D(ZRUT,HNAME='ADVECTION_UVW::ZRUT')
+  CALL GET_HALO_D(ZRVT,HNAME='ADVECTION_UVW::ZRVT')
+! acc update device(ZRUT,ZRVT)
+#endif
+  
+
 !
 #ifndef MNH_OPENACC
 CALL CONTRAV (HLBCX,HLBCY,ZRUT,ZRVT,ZRWT,PDXX,PDYY,PDZZ,PDZX,PDZY,ZRUCT,ZRVCT,ZRWCT,4)
@@ -346,7 +355,8 @@ CALL CONTRAV_DEVICE (HLBCX,HLBCY,ZRUT,ZRVT,ZRWT,PDXX,PDYY,PDZZ,PDZX,PDZY,ZRUCT,Z
 !Not necessary: already done in contrav_device !$acc update self(ZRUCT,ZRVCT,ZRWCT)
 #endif
 !
-NULLIFY(TZFIELDS_ll)
+#ifndef MNH_OPENACC
+  NULLIFY(TZFIELDS_ll)
 !!$IF(NHALO == 1) THEN
   CALL ADD3DFIELD_ll( TZFIELDS_ll, ZRWCT, 'ADVECTION_UVW::ZRWCT' )
   CALL ADD3DFIELD_ll( TZFIELDS_ll, ZRUCT, 'ADVECTION_UVW::ZRUCT' )
@@ -354,7 +364,14 @@ NULLIFY(TZFIELDS_ll)
   CALL UPDATE_HALO_ll(TZFIELDS_ll,IINFO_ll)
   CALL CLEANLIST_ll(TZFIELDS_ll)
 !!$END IF
-!$acc update device(ZRUCT,ZRVCT,ZRWCT) !Needed in advecuvw_weno_k called by advecuvw_rk
+#else
+  CALL GET_HALO_D(ZRUCT,HNAME='ADVECTION_UVW::ZRUCT')
+  CALL GET_HALO_D(ZRVCT,HNAME='ADVECTION_UVW::ZRVCT')
+  CALL GET_HALO_D(ZRWCT,HNAME='ADVECTION_UVW::ZRWCT')
+! acc update device(ZRUCT,ZRVCT,ZRWCT) !Needed in advecuvw_weno_k called by advecuvw_rk
+#endif
+  
+
 !
 !-------------------------------------------------------------------------------
 !
@@ -383,7 +400,8 @@ CALL ADV_BOUNDARIES_DEVICE (HLBCX, HLBCY, ZRWS_OTHER)
 ZRWS_OTHER(:,:,IKE+1) = 0.
 !$acc end kernels
 
-!$acc update self(ZRUS_OTHER,ZRVS_OTHER,ZRWS_OTHER)
+#ifndef MNH_OPENACC
+
 NULLIFY(TZFIELDS0_ll)
 !!$IF(NHALO == 1) THEN
   CALL ADD3DFIELD_ll( TZFIELDS0_ll, ZRUS_OTHER, 'ADVECTION_UVW::ZRUS_OTHER' )
@@ -392,7 +410,15 @@ NULLIFY(TZFIELDS0_ll)
   CALL UPDATE_HALO_ll(TZFIELDS0_ll,IINFO_ll)
   CALL CLEANLIST_ll(TZFIELDS0_ll)
 !!$END IF
-!$acc update device(ZRUS_OTHER,ZRVS_OTHER,ZRWS_OTHER)
+#else
+! acc update self(ZRUS_OTHER,ZRVS_OTHER,ZRWS_OTHER)
+  CALL GET_HALO_D(ZRUS_OTHER,HNAME='ADVECTION_UVW::ZRUS_OTHER' )
+  CALL GET_HALO_D(ZRVS_OTHER,HNAME='ADVECTION_UVW::ZRVS_OTHER' )
+  CALL GET_HALO_D(ZRWS_OTHER,HNAME='ADVECTION_UVW::ZRWS_OTHER' )
+! acc update device(ZRUS_OTHER,ZRVS_OTHER,ZRWS_OTHER)
+#endif
+  
+
 !
 !
 !
diff --git a/src/MNH/advecuvw_rk.f90 b/src/MNH/advecuvw_rk.f90
index b70ee322f63cc7e0793adcdc1354e7749ea3e8c3..20bc33af57e7d31b8becad374bffc72331e69454 100644
--- a/src/MNH/advecuvw_rk.f90
+++ b/src/MNH/advecuvw_rk.f90
@@ -475,11 +475,18 @@ RKLOOP: DO JS = 1, ISPL
   CALL ADV_BOUNDARIES_DEVICE (HLBCX, HLBCY, ZVT, PVT, 'V' )
   CALL ADV_BOUNDARIES_DEVICE (HLBCX, HLBCY, ZWT, PWT, 'W' )
 #endif
-!
-!$acc update self(ZUT,ZVT,ZWT)
+  !
+#ifndef MNH_OPENACC      
   CALL UPDATE_HALO_ll(TZFIELDMT_ll,IINFO_ll)
   CALL UPDATE_HALO2_ll(TZFIELDMT_ll, TZHALO2MT_ll, IINFO_ll)
-!$acc update device(ZUT,ZVT,ZWT)
+#else
+! acc update self(ZUT,ZVT,ZWT)
+  CALL GET_HALO_D(ZUT,HNAME='ZUT')
+  CALL GET_HALO_D(ZVT,HNAME='ZVT')
+  CALL GET_HALO_D(ZWT,HNAME='ZWT')
+  CALL UPDATE_HALO2_ll(TZFIELDMT_ll, TZHALO2MT_ll, IINFO_ll)
+! acc update device(ZUT,ZVT,ZWT)       
+#endif
 !
 !*       4.     Advection with WENO
 !        --------------------------
@@ -532,12 +539,18 @@ RKLOOP: DO JS = 1, ISPL
   NULLIFY(TZFIELDS4_ll)
 !
   write ( ynum, '( I3 )' ) js
+#ifndef MNH_OPENACC
   CALL ADD3DFIELD_ll( TZFIELDS4_ll, ZRUS(:,:,:,JS), 'ADVECUVW_RK::ZRUS(:,:,:,'//trim( adjustl( ynum ) )//')' )
   CALL ADD3DFIELD_ll( TZFIELDS4_ll, ZRVS(:,:,:,JS), 'ADVECUVW_RK::ZRVS(:,:,:,'//trim( adjustl( ynum ) )//')' )
   CALL ADD3DFIELD_ll( TZFIELDS4_ll, ZRWS(:,:,:,JS), 'ADVECUVW_RK::ZRWS(:,:,:,'//trim( adjustl( ynum ) )//')' )
   CALL UPDATE_HALO_ll(TZFIELDS4_ll,IINFO_ll)
   CALL CLEANLIST_ll(TZFIELDS4_ll)
-!$acc update device(ZRUS(:,:,:,JS),ZRVS(:,:,:,JS),ZRWS(:,:,:,JS))
+#else
+  CALL GET_HALO_D(ZRUS(:,:,:,JS),HNAME='ADVECUVW_RK::ZRUS(:,:,:,'//trim( adjustl( ynum ) )//')' )
+  CALL GET_HALO_D(ZRVS(:,:,:,JS),HNAME='ADVECUVW_RK::ZRVS(:,:,:,'//trim( adjustl( ynum ) )//')' )
+  CALL GET_HALO_D(ZRWS(:,:,:,JS),HNAME='ADVECUVW_RK::ZRWS(:,:,:,'//trim( adjustl( ynum ) )//')' )
+! acc update device(ZRUS(:,:,:,JS),ZRVS(:,:,:,JS),ZRWS(:,:,:,JS))
+#endif
 !
   IF (LIBM .AND. CIBM_ADV=='FREEZE') THEN 
     WHERE(XIBM_LS(:,:,:,2).GT.-XIBM_EPSI) ZRUS(:,:,:,JS)=ZUT(:,:,:)*PMXM_RHODJ(:,:,:)/PTSTEP
diff --git a/src/MNH/compare_with_pgd_domain.f90 b/src/MNH/compare_with_pgd_domain.f90
index 028dc1f804370fa98bc4321bc5a5892b50cc1776..8b698bb4085aa8070ac29d84115d294c68f39bec 100644
--- a/src/MNH/compare_with_pgd_domain.f90
+++ b/src/MNH/compare_with_pgd_domain.f90
@@ -178,6 +178,7 @@ IF (     (ABS(PLAT0-XLAT0)>ZEPS*MAX(1.,ABS(XLAT0)))                      &
   WRITE(ILUOUT0,*) '  | INPUT FILE AND PHYSIOGRAPHIC DATA DOMAINS ARE DIFFERENTS |'
   WRITE(ILUOUT0,*) '  +----------------------------------------------------------+'
   WRITE(ILUOUT0,*)
+  WRITE(ILUOUT0,*)
 !callabortstop
   CALL PRINT_MSG(NVERB_FATAL,'GEN','COMPARE_WITH_PGD_DOMAIN','')
 ENDIF
diff --git a/src/MNH/dyn_sources.f90 b/src/MNH/dyn_sources.f90
index 052eeebc48a26257ef84181bf9b6dca44471d888..72251666504f6ea74f20a6e3f75aaa44e2b7af29 100644
--- a/src/MNH/dyn_sources.f90
+++ b/src/MNH/dyn_sources.f90
@@ -253,7 +253,8 @@ IF ((.NOT.L1D).AND.(.NOT.LCARTESIAN) )  THEN
                       & MYF(PVT) * ZWORK1 - MZF(PWT) , &
                       & MYF(PVT) , MZF(PWT) , MXM(PWT) , MYM(PWT) )
     CALL MPPDB_CHECK3DM("DYN_SOOURCES:SUITE",PRECISION,&
-         &  MXM(ZRVT),MXM(PVT),MXM(PWT),MXM(ZWORK1),MXM(ZWORK2),MXM(ZWORK3)  )
+         &  MXM(ZRVT),MXM(PVT),MXM(PWT),MXM(ZWORK1),MXM(ZWORK2),MXM(ZWORK3),&
+         &  ZRUT,ZRVT,PRUS,PRVS,PRWS )
 !
     PRUS(:,:,:) = PRUS                                              &
     + MXM( MYF(ZRVT*PVT) * ZWORK2 * ZWORK3 )                        &
@@ -293,6 +294,9 @@ IF (LCORIO)   THEN
 
     ZWORK1(:,:,:) = SPREAD( PCORIOX(:,:),DIM=3,NCOPIES=IKU) * PRHODJ(:,:,:) 
     ZWORK2(:,:,:) = SPREAD( PCORIOY(:,:),DIM=3,NCOPIES=IKU) * PRHODJ(:,:,:)
+    !
+    CALL MPPDB_CHECK3DM("DYN_SOOURCES:CORIOLIS",PRECISION,&
+         & ZWORK1,ZWORK2,ZWORK3 )
 !
     PRUS(:,:,:) = PRUS - MXM( ZWORK2 * MZF(PWT) )
 !
diff --git a/src/MNH/emoist.f90 b/src/MNH/emoist.f90
index 8fd26c4d75ed756d0091aae1de2d446e3467c898..142586b908ca18c7794f4171e876997dd8b4b77b 100644
--- a/src/MNH/emoist.f90
+++ b/src/MNH/emoist.f90
@@ -41,7 +41,6 @@ END SUBROUTINE EMOIST
 END INTERFACE
 !
 END MODULE MODI_EMOIST
-!
 !   ############################################################################
 #ifndef MNH_OPENACC
 FUNCTION EMOIST(KRR,KRRI,PTHLM,PRM,PLOCPEXNM,PAMOIST,PSRCM) RESULT(PEMOIST)
@@ -101,8 +100,11 @@ SUBROUTINE EMOIST(KRR,KRRI,PTHLM,PRM,PLOCPEXNM,PAMOIST,PSRCM,PEMOIST)
 USE MODD_CST
 USE MODD_DYN_n, ONLY : LOCEAN
 
+#ifdef MNH_OPENACC
+USE  MODE_MNH_ZWORK
+#endif
 use mode_mppdb
-!
+
 IMPLICIT NONE
 !
 !*       0.1 declarations of arguments and result
@@ -127,10 +129,15 @@ REAL,DIMENSION(:,:,:),  INTENT(OUT):: PEMOIST ! result
 !
 !*       0.2 declarations of local variables
 !
-REAL,DIMENSION(:,:,:), allocatable :: ZA, ZRW
+REAL,DIMENSION(:,:,:), pointer,contiguous :: ZA, ZRW
+#ifdef MNH_OPENACC
+INTEGER                                   :: IZA,IZRW
+#endif
 !                ZA = coeft A, ZRW = total mixing ratio rw 
 REAL                                  :: ZDELTA  ! = Rv/Rd - 1
 INTEGER                               :: JRR     ! moist loop counter
+INTEGER                               :: JIU,JJU,JKU
+INTEGER                               :: JI,JJ,JK
 !
 !---------------------------------------------------------------------------
 
@@ -145,83 +152,111 @@ if ( mppdb_initialized ) then
   call Mppdb_check( psrcm,     "Emoist beg:psrcm"     )
 end if
 
-allocate( za  ( size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zrw ( size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
+JIU =  size( pthlm, 1 )
+JJU =  size( pthlm, 2 )
+JKU =  size( pthlm, 3 )
+
+#ifndef MNH_OPENACC
+allocate( za  (JIU,JJU,JKU) )
+allocate( zrw (JIU,JJU,JKU ) )
+#else
+IZA  = MNH_ALLOCATE_ZT3D( za  , JIU,JJU,JKU )
+IZRW = MNH_ALLOCATE_ZT3D( zrw , JIU,JJU,JKU )
+#endif
 
-!$acc data create( za, zrw )
+!$acc data present( za, zrw )
 
 !
 !*       1. COMPUTE EMOIST
 !           --------------
-!$acc kernels
 IF (LOCEAN) THEN
  IF ( KRR == 0 ) THEN                                ! Unsalted
+!$acc kernels
    PEMOIST(:,:,:) = 0.
- ELSE
+!$acc end kernels
+ELSE
+!$acc kernels
    PEMOIST(:,:,:) = 1.                              ! Salted case
+!$acc end kernels
  END IF
 !
 ELSE
 !
  IF ( KRR == 0 ) THEN                                ! dry case
-   PEMOIST(:,:,:) = 0.
+!$acc kernels
+   PEMOIST(1:JIU,1:JJU,1:JKU) = 0.
+!$acc end kernels
  ELSE IF ( KRR == 1 ) THEN                           ! only vapor
+!$acc kernels
   ZDELTA = (XRV/XRD) - 1.
-  PEMOIST(:,:,:) = ZDELTA*PTHLM(:,:,:)
+  PEMOIST(1:JIU,1:JJU,1:JKU) = ZDELTA*PTHLM(1:JIU,1:JJU,1:JKU)
+!$acc end kernels
  ELSE                                                ! liquid water & ice present
+!$acc kernels
   ZDELTA = (XRV/XRD) - 1.
-  ZRW(:,:,:) = PRM(:,:,:,1)
-!
-  IF ( KRRI>0) THEN  ! rc and ri case  
-    ZRW(:,:,:) = ZRW(:,:,:) + PRM(:,:,:,3)
-    DO JRR=5,KRR
-      ZRW(:,:,:) = ZRW(:,:,:) + PRM(:,:,:,JRR)
-    ENDDO
-    ZA(:,:,:) = 1. + (                                    &  ! Compute A
-              (1.+ZDELTA) * (PRM(:,:,:,1) - PRM(:,:,:,2) - PRM(:,:,:,4)) &
-              -ZRW(:,:,:)                                                &
-                     )  /  (1. + ZRW(:,:,:)) 
+  ZRW(1:JIU,1:JJU,1:JKU) = PRM(1:JIU,1:JJU,1:JKU,1)
+!$acc end kernels
+!
+  IF ( KRRI>0) THEN  ! rc and ri case
+!$acc kernels      
+   ZRW(1:JIU,1:JJU,1:JKU) = ZRW(1:JIU,1:JJU,1:JKU) + PRM(1:JIU,1:JJU,1:JKU,3)
+   !$acc loop seq  
+   DO JRR=5,KRR
+      ZRW(1:JIU,1:JJU,1:JKU) = ZRW(1:JIU,1:JJU,1:JKU) + PRM(1:JIU,1:JJU,1:JKU,JRR)
+   ENDDO
+   !$acc loop independent collapse(3)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+      ZA(JI,JJ,JK) = 1. + (                                    &  ! Compute A
+           (1.+ZDELTA) * (PRM(JI,JJ,JK,1) - PRM(JI,JJ,JK,2) - PRM(JI,JJ,JK,4)) &
+           -ZRW(JI,JJ,JK)                                                &
+           )  /  (1. + ZRW(JI,JJ,JK))
+   END DO !CONCURRENT  
   !
   !   Emoist = ZB + ZC * Amoist
   !   ZB is computed from line 1 to line 2
   !   ZC is computed from line 3 to line 5
   !   Amoist* 2 * SRC is computed at line 6
   !
-    PEMOIST(:,:,:) = ZDELTA * (PTHLM(:,:,:) + PLOCPEXNM(:,:,:)*(               &
-                                                    PRM(:,:,:,2)+PRM(:,:,:,4)))&
-                            / (1. + ZRW(:,:,:))                                &
-        +( PLOCPEXNM(:,:,:) * ZA(:,:,:)                                        &
-               -(1.+ZDELTA) * (PTHLM(:,:,:) + PLOCPEXNM(:,:,:)*(               &
-                                                    PRM(:,:,:,2)+PRM(:,:,:,4)))&
-                            / (1. + ZRW(:,:,:))                                &
-         ) * PAMOIST(:,:,:) * 2. * PSRCM(:,:,:)
-  ELSE
-    DO JRR=3,KRR
-      ZRW(:,:,:) = ZRW(:,:,:) + PRM(:,:,:,JRR)
-    ENDDO
-    ZA(:,:,:) = 1. + (                                    &  ! Compute ZA
-              (1.+ZDELTA) * (PRM(:,:,:,1) - PRM(:,:,:,2)) &
-              -ZRW(:,:,:)                                 &
-                     )  /  (1. + ZRW(:,:,:)) 
+    PEMOIST(1:JIU,1:JJU,1:JKU) = ZDELTA * (PTHLM(1:JIU,1:JJU,1:JKU) + PLOCPEXNM(1:JIU,1:JJU,1:JKU)*(               &
+                                                    PRM(1:JIU,1:JJU,1:JKU,2)+PRM(1:JIU,1:JJU,1:JKU,4)))&
+                            / (1. + ZRW(1:JIU,1:JJU,1:JKU))                                &
+        +( PLOCPEXNM(1:JIU,1:JJU,1:JKU) * ZA(1:JIU,1:JJU,1:JKU)                                        &
+               -(1.+ZDELTA) * (PTHLM(1:JIU,1:JJU,1:JKU) + PLOCPEXNM(1:JIU,1:JJU,1:JKU)*(               &
+                                                    PRM(1:JIU,1:JJU,1:JKU,2)+PRM(1:JIU,1:JJU,1:JKU,4)))&
+                            / (1. + ZRW(1:JIU,1:JJU,1:JKU))                                &
+                            ) * PAMOIST(1:JIU,1:JJU,1:JKU) * 2. * PSRCM(1:JIU,1:JJU,1:JKU)
+!$acc end kernels    
+ ELSE
+!$acc kernels
+   !$acc loop seq
+   DO JRR=3,KRR
+      ZRW(1:JIU,1:JJU,1:JKU) = ZRW(1:JIU,1:JJU,1:JKU) + PRM(1:JIU,1:JJU,1:JKU,JRR)
+   ENDDO
+   !$acc loop independent collapse(3)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+      ZA(JI,JJ,JK) = 1. + (                                    &  ! Compute ZA
+           (1.+ZDELTA) * (PRM(JI,JJ,JK,1) - PRM(JI,JJ,JK,2)) &
+           -ZRW(JI,JJ,JK)                                 &
+           )  /  (1. + ZRW(JI,JJ,JK))
+   END DO !CONCURRENT 
   !
   !   Emoist = ZB + ZC * Amoist
   !   ZB is computed from line 1 to line 2
   !   ZC is computed from line 3 to line 5
   !   Amoist* 2 * SRC is computed at line 6
   !
-    PEMOIST(:,:,:) = ZDELTA * (PTHLM(:,:,:) + PLOCPEXNM(:,:,:)*PRM(:,:,:,2))   &
-                            / (1. + ZRW(:,:,:))                                &
-        +( PLOCPEXNM(:,:,:) * ZA(:,:,:)                                        &
-               -(1.+ZDELTA) * (PTHLM(:,:,:) + PLOCPEXNM(:,:,:)*PRM(:,:,:,2))   &
-                            / (1. + ZRW(:,:,:))                                &
-         ) * PAMOIST(:,:,:) * 2. * PSRCM(:,:,:)
+    PEMOIST(1:JIU,1:JJU,1:JKU) = ZDELTA * (PTHLM(1:JIU,1:JJU,1:JKU) + PLOCPEXNM(1:JIU,1:JJU,1:JKU)*PRM(1:JIU,1:JJU,1:JKU,2))   &
+                            / (1. + ZRW(1:JIU,1:JJU,1:JKU))                                &
+        +( PLOCPEXNM(1:JIU,1:JJU,1:JKU) * ZA(1:JIU,1:JJU,1:JKU)                                        &
+               -(1.+ZDELTA) * (PTHLM(1:JIU,1:JJU,1:JKU) + PLOCPEXNM(1:JIU,1:JJU,1:JKU)*PRM(1:JIU,1:JJU,1:JKU,2))   &
+                            / (1. + ZRW(1:JIU,1:JJU,1:JKU))                                &
+                            ) * PAMOIST(1:JIU,1:JJU,1:JKU) * 2. * PSRCM(1:JIU,1:JJU,1:JKU)
+!$acc end kernels
   END IF
  END IF
 !
 END IF
-!$acc end kernels
-
-deallocate( za, zrw )
+! acc end kernels
 
 if ( mppdb_initialized ) then
   !Check all out arrays
@@ -230,6 +265,12 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate( za, zrw )
+#else
+CALL MNH_REL_ZT3D(  iza, izrw )
+#endif
+
 !$acc end data
 
 !---------------------------------------------------------------------------
diff --git a/src/MNH/etheta.f90 b/src/MNH/etheta.f90
index 34fd3015eb65017b47f80b0e090d9821ae90b18b..9e0099214e182cf8ffd02dc763f4a1731aaa3c7f 100644
--- a/src/MNH/etheta.f90
+++ b/src/MNH/etheta.f90
@@ -103,8 +103,11 @@ SUBROUTINE ETHETA(KRR,KRRI,PTHLM,PRM,PLOCPEXNM,PATHETA,PSRCM,PETHETA)
 USE MODD_CST
 USE MODD_DYN_n, ONLY : LOCEAN
 
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK, ONLY: MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D
+#endif
 use mode_mppdb
-!
+
 IMPLICIT NONE
 !
 !*       0.1 declarations of arguments and result
@@ -132,8 +135,11 @@ REAL, DIMENSION(:,:,:),  INTENT(OUT):: PETHETA ! result
 !
 !*       0.2 declarations of local variables
 !
-REAL,DIMENSION(:,:,:), allocatable :: ZA, ZRW
+REAL,DIMENSION(:,:,:), pointer , contiguous :: ZA, ZRW
 !                ZA = coeft A, ZRW = total mixing ratio rw
+#ifdef MNH_OPENACC
+INTEGER  :: IZA, IZRW
+#endif
 REAL                                  :: ZDELTA  ! = Rv/Rd - 1
 INTEGER                               :: JRR     ! moist loop counter
 !
@@ -150,73 +156,90 @@ if ( mppdb_initialized ) then
   call Mppdb_check( psrcm,     "Etheta beg:psrcm"     )
 end if
 
+#ifndef MNH_OPENACC
 allocate( za  ( size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
 allocate( zrw ( size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
+#else
+iza  = MNH_ALLOCATE_ZT3D( za  , size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) )
+izrw = MNH_ALLOCATE_ZT3D( zrw , size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) )
+#endif
 
-!$acc data create( za, zrw )
+!$acc data present( za, zrw )
 
 !
 !*       1. COMPUTE ETHETA
 !           --------------
 !
 !
-!$acc kernels
 IF (LOCEAN) THEN                                    ! ocean case
+!$acc kernels
    PETHETA(:,:,:) =  1.
-ELSE   
- IF ( KRR == 0.) THEN                                ! dry case
-  PETHETA(:,:,:) = 1.
- ELSE IF ( KRR == 1 ) THEN                           ! only vapor
-  ZDELTA = (XRV/XRD) - 1.
-  PETHETA(:,:,:) = 1. + ZDELTA*PRM(:,:,:,1)
- ELSE                                                ! liquid water & ice present
-  ZDELTA = (XRV/XRD) - 1.
-  ZRW(:,:,:) = PRM(:,:,:,1)
-!
-  IF ( KRRI>0 ) THEN  ! rc and ri case
-    ZRW(:,:,:) = ZRW(:,:,:) + PRM(:,:,:,3)
-    DO JRR=5,KRR
-      ZRW(:,:,:) = ZRW(:,:,:) + PRM(:,:,:,JRR)
-    ENDDO
-    ZA(:,:,:) = 1. + (                                    &  ! Compute A
-              (1.+ZDELTA) * (PRM(:,:,:,1) - PRM(:,:,:,2) - PRM(:,:,:,4)) &
-              -ZRW(:,:,:)                                                &
-                     )  /  (1. + ZRW(:,:,:))
-  !
-  !   Etheta = ZA + ZC * Atheta  
-  !   ZC is computed from line 2 to line 5
-  !   - Atheta * 2. * SRC is computed at line 6 
-  !
-    PETHETA(:,:,:) = ZA(:,:,:)                                                 &
-        +( PLOCPEXNM(:,:,:) * ZA(:,:,:)                                        &
-               -(1.+ZDELTA) * (PTHLM(:,:,:) + PLOCPEXNM(:,:,:)*(               &
-                                                    PRM(:,:,:,2)+PRM(:,:,:,4)))&
-                            / (1. + ZRW(:,:,:))                                &
-         ) * PATHETA(:,:,:) * 2. * PSRCM(:,:,:)
-  ELSE
-    DO JRR=3,KRR
-      ZRW(:,:,:) = ZRW(:,:,:) + PRM(:,:,:,JRR)
-    ENDDO
-    ZA(:,:,:) = 1. + (                                    &  ! Compute A
-              (1.+ZDELTA) * (PRM(:,:,:,1) - PRM(:,:,:,2)) &
-              -ZRW(:,:,:)                                 &
-                     )  /  (1. + ZRW(:,:,:))
-  !
-  !   Etheta = ZA + ZC * Atheta  
-  !   ZC is computed from line 2 to line 5
-  !   - Atheta * 2. * SRC is computed at line 6 
-  !
-    PETHETA(:,:,:) = ZA(:,:,:)                                                 &
-        +( PLOCPEXNM(:,:,:) * ZA(:,:,:)                                        &
-               -(1.+ZDELTA) * (PTHLM(:,:,:) + PLOCPEXNM(:,:,:)*PRM(:,:,:,2))   &
-                            / (1. + ZRW(:,:,:))                                &
-         ) * PATHETA(:,:,:) * 2. * PSRCM(:,:,:)
-  END IF
- END IF
-END IF
+!$acc end kernels
+ELSE
+! acc kernels
+  IF ( KRR == 0 ) THEN                               ! dry case
+!$acc kernels
+    PETHETA(:,:,:) = 1.
+!$acc end kernels
+  ELSE IF ( KRR == 1 ) THEN                           ! only vapor
+!$acc kernels
+    ZDELTA = (XRV/XRD) - 1.
+    PETHETA(:,:,:) = 1. + ZDELTA*PRM(:,:,:,1)
+!$acc end kernels
+  ELSE                                                ! liquid water & ice present
+!$acc kernels
+    ZDELTA = (XRV/XRD) - 1.
+    ZRW(:,:,:) = PRM(:,:,:,1)
 !$acc end kernels
 
-deallocate( za, zrw )
+    IF ( KRRI>0 ) THEN  ! rc and ri case
+      !$acc kernels
+      ZRW(:,:,:) = ZRW(:,:,:) + PRM(:,:,:,3)
+      !$acc loop seq
+      DO JRR=5,KRR
+        ZRW(:,:,:) = ZRW(:,:,:) + PRM(:,:,:,JRR)
+      ENDDO
+      ZA(:,:,:) = 1. + (                                    &  ! Compute A
+                (1.+ZDELTA) * (PRM(:,:,:,1) - PRM(:,:,:,2) - PRM(:,:,:,4)) &
+                -ZRW(:,:,:)                                                &
+                       )  /  (1. + ZRW(:,:,:))
+    !
+    !   Etheta = ZA + ZC * Atheta
+    !   ZC is computed from line 2 to line 5
+    !   - Atheta * 2. * SRC is computed at line 6
+    !
+      PETHETA(:,:,:) = ZA(:,:,:)                                                 &
+          +( PLOCPEXNM(:,:,:) * ZA(:,:,:)                                        &
+                 -(1.+ZDELTA) * (PTHLM(:,:,:) + PLOCPEXNM(:,:,:)*(               &
+                                                      PRM(:,:,:,2)+PRM(:,:,:,4)))&
+                              / (1. + ZRW(:,:,:))                                &
+           ) * PATHETA(:,:,:) * 2. * PSRCM(:,:,:)
+      !$acc end kernels
+    ELSE
+      !$acc kernels
+      !$acc loop seq
+      DO JRR=3,KRR
+        ZRW(:,:,:) = ZRW(:,:,:) + PRM(:,:,:,JRR)
+      ENDDO
+      ZA(:,:,:) = 1. + (                                    &  ! Compute A
+                (1.+ZDELTA) * (PRM(:,:,:,1) - PRM(:,:,:,2)) &
+                -ZRW(:,:,:)                                 &
+                       )  /  (1. + ZRW(:,:,:))
+    !
+    !   Etheta = ZA + ZC * Atheta
+    !   ZC is computed from line 2 to line 5
+    !   - Atheta * 2. * SRC is computed at line 6
+    !
+      PETHETA(:,:,:) = ZA(:,:,:)                                                 &
+          +( PLOCPEXNM(:,:,:) * ZA(:,:,:)                                        &
+                 -(1.+ZDELTA) * (PTHLM(:,:,:) + PLOCPEXNM(:,:,:)*PRM(:,:,:,2))   &
+                              / (1. + ZRW(:,:,:))                                &
+           ) * PATHETA(:,:,:) * 2. * PSRCM(:,:,:)
+      !$acc end kernels
+    END IF
+  END IF
+! acc end kernels
+END IF
 
 if ( mppdb_initialized ) then
   !Check all out arrays
@@ -225,6 +248,12 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate (za, zrw)
+#else
+CALL MNH_REL_ZT3D(iza, izrw)
+#endif
+
 !$acc end data
 
 !---------------------------------------------------------------------------
diff --git a/src/MNH/get_halo.f90 b/src/MNH/get_halo.f90
index 34daa24a1edd7ab984b153f8ed91f0fec92fa0bc..16aa1f8ed6f4c2474130ddf2f3118e9c9899392f 100644
--- a/src/MNH/get_halo.f90
+++ b/src/MNH/get_halo.f90
@@ -16,6 +16,9 @@ INTERFACE
    SUBROUTINE GET_HALO2(PSRC, TP_PSRC_HALO2_ll, HNAME)
      !
      USE MODD_ARGSLIST_ll, ONLY : HALO2LIST_ll
+     !
+     IMPLICIT NONE
+     !
      REAL, DIMENSION(:,:,:), INTENT(IN)  :: PSRC    ! variable at t
      TYPE(HALO2LIST_ll), POINTER         :: TP_PSRC_HALO2_ll          ! halo2 for SRC
      character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
@@ -25,6 +28,7 @@ END INTERFACE
 !
 INTERFACE 
    SUBROUTINE GET_HALO(PSRC, HDIR, HNAME)
+     IMPLICIT NONE
      !
      REAL, DIMENSION(:,:,:), INTENT(IN)  :: PSRC    ! variable at t
      CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
@@ -36,6 +40,7 @@ END INTERFACE
 #ifdef MNH_OPENACC
 INTERFACE
    SUBROUTINE GET_HALO_D(PSRC, HDIR, HNAME)
+     IMPLICIT NONE
      !
      REAL, DIMENSION(:,:,:), INTENT(INOUT)   :: PSRC    ! variable at t
      CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
@@ -43,16 +48,40 @@ INTERFACE
      !
    END SUBROUTINE GET_HALO_D
 END INTERFACE
-#endif
 !
 INTERFACE
-SUBROUTINE DEL_HALO2_ll(TPHALO2LIST)
-!
-USE MODD_ARGSLIST_ll, ONLY : HALO2LIST_ll
-TYPE(HALO2LIST_ll), POINTER :: TPHALO2LIST ! list of HALO2_lls
-!
-END SUBROUTINE DEL_HALO2_ll
+   SUBROUTINE GET_HALO_START_D(PSRC,KNB_REQ,KREQ,HDIR)
+     IMPLICIT NONE
+     !
+     REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC    ! variable at t
+     !$acc declare present (PSRC)
+     INTEGER                               :: KNB_REQ ,  KREQ(8)
+     CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
+     !
+   END SUBROUTINE GET_HALO_START_D
+END INTERFACE
+INTERFACE
+   SUBROUTINE GET_HALO_STOP_D(PSRC,KNB_REQ,KREQ,HDIR)
+     IMPLICIT NONE
+     REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC    ! variable at t
+     !$acc declare present (PSRC)
+     INTEGER                               :: KNB_REQ , KREQ(8)
+     CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
+   END SUBROUTINE GET_HALO_STOP_D
+END INTERFACE
+#endif
 !
+INTERFACE
+   SUBROUTINE DEL_HALO2_ll(TPHALO2LIST)
+     !
+     USE MODD_ARGSLIST_ll, ONLY : HALO2LIST_ll
+     !
+     IMPLICIT NONE
+     !
+     TYPE(HALO2LIST_ll), POINTER :: TPHALO2LIST ! list of HALO2_lls
+     !
+   END SUBROUTINE DEL_HALO2_ll
+   !
 END INTERFACE
 !
 END MODULE MODI_GET_HALO
@@ -132,17 +161,417 @@ END SUBROUTINE GET_HALO
 !-----------------------------------------------------------------------
 #ifdef MNH_OPENACC
 MODULE MODD_HALO_D
-IMPLICIT NONE 
-REAL, SAVE , ALLOCATABLE, DIMENSION(:,:,:)  :: ZNORTH_IN, ZSOUTH_IN, ZWEST_IN, ZEAST_IN
-REAL, SAVE , ALLOCATABLE, DIMENSION(:,:,:)  :: ZNORTH_OUT, ZSOUTH_OUT, ZWEST_OUT, ZEAST_OUT
+  
+  IMPLICIT NONE
+  
+  REAL, SAVE , ALLOCATABLE, DIMENSION(:,:,:)  :: ZNORTH_IN, ZSOUTH_IN, ZWEST_IN, ZEAST_IN
+  REAL, SAVE , ALLOCATABLE, DIMENSION(:,:,:)  :: ZNORTH_OUT, ZSOUTH_OUT, ZWEST_OUT, ZEAST_OUT
+  
+  LOGICAL, SAVE                               :: GFIRST_GET_HALO_D = .TRUE.
+  
+  LOGICAL, SAVE     :: GFIRST_INIT_HALO_D = .TRUE.
+  INTEGER, SAVE     :: IHALO_1  
+  INTEGER, SAVE     :: NP_NORTH,NP_SOUTH,NP_WEST,NP_EAST
+
+CONTAINS
+  
+  SUBROUTINE INIT_HALO_D()
+
+    USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU
+    USE MODE_MNH_ZWORK, ONLY : IIB,IJB ,IIE,IJE 
+    USE MODE_MNH_ZWORK, ONLY : GWEST , GEAST, GSOUTH , GNORTH
+    USE MODD_CONF, ONLY      : NHALO
 
-LOGICAL, SAVE                               :: GFIRST_GET_HALO_D = .TRUE.
+    USE MODD_VAR_ll, ONLY    : IP,NPROC,NP1,NP2
+
+
+    IMPLICIT NONE
+
+    IF (GFIRST_INIT_HALO_D) THEN 
+       !
+       IHALO_1 = NHALO-1
+       !      
+       ALLOCATE  ( ZSOUTH_IN ( IIB:IIE   , IJB:IJB+IHALO_1   , IKU ) )
+       ALLOCATE  ( ZNORTH_IN ( IIB:IIE   , IJE-IHALO_1:IJE   , IKU ) )
+       ALLOCATE  ( ZWEST_IN  ( IIB:IIB+IHALO_1   , IJB:IJE   , IKU ) )
+       ALLOCATE  ( ZEAST_IN  ( IIE-IHALO_1:IIE   , IJB:IJE   , IKU ) )
+       !$acc enter data create (ZNORTH_IN, ZSOUTH_IN, ZWEST_IN, ZEAST_IN)
+       !
+       ALLOCATE  ( ZSOUTH_OUT (   IIB:IIE   , 1:IJB-1 , IKU ) )
+       ALLOCATE  ( ZNORTH_OUT (   IIB:IIE   , IJE+1:IJU , IKU ) )
+       ALLOCATE  ( ZWEST_OUT  ( 1:IIB-1 ,   IJB:IJE   , IKU ) )
+       ALLOCATE  ( ZEAST_OUT  ( IIE+1:IIU ,   IJB:IJE   , IKU ) )
+       !$acc enter data create (ZNORTH_OUT, ZSOUTH_OUT, ZWEST_OUT, ZEAST_OUT)
+
+       IF (.NOT. GWEST ) THEN
+          NP_WEST = ( IP-1 -1 ) + 1
+       ELSE
+          NP_WEST = 0
+       ENDIF
+       IF (.NOT. GEAST ) THEN
+          NP_EAST = ( IP-1 +1 ) + 1
+       ELSE
+          NP_EAST = 0
+       ENDIF
+       IF (.NOT. GSOUTH ) THEN
+          NP_SOUTH =  ( IP-1 -NP1 ) + 1
+       ELSE
+          NP_SOUTH = 0
+       ENDIF
+       IF (.NOT. GNORTH ) THEN
+          NP_NORTH =  ( IP-1 +NP1 ) + 1
+       ELSE
+          NP_NORTH = 0
+       ENDIF
+
+       !print*,"PROC=",IP, GWEST,NP_WEST, GEAST,NP_EAST, GSOUTH,NP_SOUTH ,  GNORTH,NP_NORTH
+       
+       GFIRST_INIT_HALO_D = .FALSE.
+       
+    END IF
+
+  END SUBROUTINE INIT_HALO_D
 
 END MODULE MODD_HALO_D
+!     #########################
+      SUBROUTINE GET_HALO_D(PSRC,HDIR,HNAME)
+!     #########################
+#define MNH_GPUDIRECT
+!
+USE MODD_HALO_D
+
+!USE MODE_MNH_ZWORK, ONLY : GWEST , GEAST, GSOUTH , GNORTH
+!USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU
+!USE MODE_MNH_ZWORK, ONLY : IIB,IJB ,IIE,IJE 
+!!
+!USE MODE_DEVICE
+USE MODE_MPPDB
+USE MODI_GET_HALO, ONLY : GET_HALO_START_D,GET_HALO_STOP_D
+!
+IMPLICIT NONE
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC    ! variable at t
+!$acc declare present (PSRC)
+CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
+character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+!
+INTEGER            :: INB_REQ , IREQ(8)
+!
+CALL GET_HALO_START_D(PSRC,INB_REQ,IREQ,HDIR)
+CALL GET_HALO_STOP_D(PSRC,INB_REQ,IREQ,HDIR)
+!
+END SUBROUTINE GET_HALO_D
+!     #########################
+      SUBROUTINE GET_HALO_START_D(PSRC,KNB_REQ,KREQ,HDIR)
+!     #########################
+#define MNH_GPUDIRECT
+!
+USE MODD_HALO_D
+
+USE MODE_MNH_ZWORK, ONLY : GWEST , GEAST, GSOUTH , GNORTH
+USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU
+USE MODE_MNH_ZWORK, ONLY : IIB,IJB ,IIE,IJE 
+!
+USE MODD_VAR_ll, ONLY : NMNH_COMM_WORLD
+USE MODD_MPIF,    ONLY : MPI_STATUSES_IGNORE
+USE MODD_PRECISION,  ONLY : MNHREAL_MPI
+!
+USE MODE_DEVICE
+USE MODE_MPPDB
+!
+IMPLICIT NONE
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC    ! variable at t
+!$acc declare present (PSRC)
+INTEGER                               :: KNB_REQ ,  KREQ(8)
+CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
+!
+INTEGER                          :: IERROR                 ! error return code 
+
+INTEGER,PARAMETER :: IS_WEST=1 , IS_EAST=2, IS_SOUTH=3, IS_NORTH=4
+LOGICAL      :: LX , LY
+INTEGER      :: NB_REQ, IERR
+!
+
+CALL INIT_HALO_D()
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+!$acc data present (ZNORTH_IN, ZSOUTH_IN, ZWEST_IN, ZEAST_IN) &
+!$acc present (ZNORTH_OUT, ZSOUTH_OUT, ZWEST_OUT, ZEAST_OUT)
+
+LX = .FALSE.
+LY = .FALSE. 
+
+IF (.NOT. PRESENT(HDIR) ) THEN
+LX = .TRUE.
+LY = .TRUE.
+ELSE
+!!$LX = ( HDIR == "01_X"  .OR. HDIR == "S0_X" )
+!!$LY = ( HDIR == "01_Y"  .OR. HDIR == "S0_Y" )
+LX = ( HDIR == "01_X" .OR. HDIR == "S0_X" .OR. HDIR == "S0_Y" )
+LY = ( HDIR == "01_Y" .OR. HDIR == "S0_Y" .OR. HDIR == "S0_X" )
+!!$print *,"IIB=",IIB," HDIR=",HDIR," LX=",LX," LY=",LY ; call flush(6)
+END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+NB_REQ = 0
+
+!
+! Post the recieve of Zxxxx_IN buffer first via MPI(Gpu_direct)
+!
+
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZWEST_OUT)
+#endif
+      NB_REQ = NB_REQ + 1
+      CALL MPI_IRECV(ZWEST_OUT,SIZE(ZWEST_OUT),MNHREAL_MPI,NP_WEST-1,1000+IS_EAST,NMNH_COMM_WORLD,KREQ(NB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   END IF
+   IF (.NOT.GEAST) THEN 
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZEAST_OUT)
+#endif
+      NB_REQ = NB_REQ + 1
+      CALL MPI_IRECV(ZEAST_OUT,SIZE(ZEAST_OUT),MNHREAL_MPI,NP_EAST-1,1000+IS_WEST,NMNH_COMM_WORLD,KREQ(NB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZSOUTH_OUT)
+#endif
+      NB_REQ = NB_REQ + 1
+      CALL MPI_IRECV(ZSOUTH_OUT,SIZE(ZSOUTH_OUT),MNHREAL_MPI,NP_SOUTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,KREQ(NB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZNORTH_OUT)
+#endif
+      NB_REQ = NB_REQ + 1
+      CALL MPI_IRECV(ZNORTH_OUT,SIZE(ZNORTH_OUT),MNHREAL_MPI,NP_NORTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,KREQ(NB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+!
+! Copy the halo(async) on the device PSRC to Zxxxx_IN buffer 
+!
+
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+      !$acc kernels async(IS_WEST)
+      ZWEST_IN ( IIB:IIB+IHALO_1  ,    IJB:IJE  , : )  = PSRC( IIB:IIB+IHALO_1  ,  IJB:IJE  , : )
+      !$acc end kernels
+   END IF
+   IF (.NOT.GEAST) THEN
+      !$acc kernels async(IS_EAST)
+      ZEAST_IN ( IIE-IHALO_1:IIE  ,    IJB:IJE  , : )  = PSRC( IIE-IHALO_1:IIE  ,  IJB:IJE  , : )
+      !$acc end kernels
+   ENDIF
+END IF
+
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+      !$acc kernels async(IS_SOUTH)
+      ZSOUTH_IN ( IIB:IIE  ,    IJB:IJB+IHALO_1  , : ) = PSRC( IIB:IIE  ,    IJB:IJB+IHALO_1  , : )
+      !$acc end kernels
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+      !$acc kernels async(IS_NORTH)
+      ZNORTH_IN ( IIB:IIE  ,    IJE-IHALO_1:IJE  , : ) = PSRC( IIB:IIE  ,    IJE-IHALO_1:IJE  , : )
+      !$acc end kernels
+   ENDIF   
+ENDIF
+
+!$acc wait
+
+!
+! Send  Zxxxx_IN buffer via MPI(Gpu_direct)
+!
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZWEST_IN)
+#else
+      !$acc update host(ZWEST_IN)
+#endif
+      NB_REQ = NB_REQ + 1
+      CALL MPI_ISEND(ZWEST_IN,SIZE(ZWEST_IN)  ,MNHREAL_MPI,NP_WEST-1,1000+IS_WEST,NMNH_COMM_WORLD,KREQ(NB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   END IF
+   IF (.NOT.GEAST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZEAST_IN)
+#else
+      !$acc update host(ZEAST_IN)
+#endif
+      NB_REQ = NB_REQ + 1
+      CALL MPI_ISEND(ZEAST_IN,SIZE(ZEAST_IN)  ,MNHREAL_MPI,NP_EAST-1,1000+IS_EAST,NMNH_COMM_WORLD,KREQ(NB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZSOUTH_IN)
+#else
+      !$acc update host(ZSOUTH_IN)
+#endif
+      NB_REQ = NB_REQ + 1
+      CALL MPI_ISEND(ZSOUTH_IN,SIZE(ZSOUTH_IN)  ,MNHREAL_MPI,NP_SOUTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,KREQ(NB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZNORTH_IN)
+#else
+      !$acc update host(ZNORTH_IN)
+#endif
+      NB_REQ = NB_REQ + 1
+      CALL MPI_ISEND(ZNORTH_IN,SIZE(ZNORTH_IN)  ,MNHREAL_MPI,NP_NORTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,KREQ(NB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF   
+ENDIF
+
+!$acc end data
+
+KNB_REQ = NB_REQ
+!
+END SUBROUTINE GET_HALO_START_D
+!
+!     #########################
+      SUBROUTINE GET_HALO_STOP_D(PSRC,KNB_REQ,KREQ,HDIR)
+!     #########################
+#define MNH_GPUDIRECT
+!
+USE MODD_HALO_D
+
+USE MODE_MNH_ZWORK, ONLY : GWEST , GEAST, GSOUTH , GNORTH
+USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU
+USE MODE_MNH_ZWORK, ONLY : IIB,IJB ,IIE,IJE 
+!
+USE MODD_VAR_ll, ONLY : NMNH_COMM_WORLD
+USE MODD_MPIF,    ONLY : MPI_STATUSES_IGNORE
+USE MODD_PRECISION,  ONLY : MNHREAL_MPI
+!
+USE MODE_DEVICE
+USE MODE_MPPDB
+!
+IMPLICIT NONE
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC    ! variable at t
+!$acc declare present (PSRC)
+INTEGER                               :: KNB_REQ , KREQ(8)
+CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
+!
+INTEGER                          :: IERROR                 ! error return code 
+
+INTEGER,PARAMETER :: IS_WEST=1 , IS_EAST=2, IS_SOUTH=3, IS_NORTH=4
+LOGICAL      :: LX , LY
+INTEGER      :: NB_REQ, IERR
+!
+
+CALL INIT_HALO_D()
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+!$acc data present (ZNORTH_IN, ZSOUTH_IN, ZWEST_IN, ZEAST_IN) &
+!$acc present (ZNORTH_OUT, ZSOUTH_OUT, ZWEST_OUT, ZEAST_OUT)
+
+LX = .FALSE.
+LY = .FALSE. 
+
+IF (.NOT. PRESENT(HDIR) ) THEN
+LX = .TRUE.
+LY = .TRUE.
+ELSE
+!!$LX = ( HDIR == "01_X"  .OR. HDIR == "S0_X" )
+!!$LY = ( HDIR == "01_Y"  .OR. HDIR == "S0_Y" )
+LX = ( HDIR == "01_X" .OR. HDIR == "S0_X" .OR. HDIR == "S0_Y" )
+LY = ( HDIR == "01_Y" .OR. HDIR == "S0_Y" .OR. HDIR == "S0_X" )
+!!$print *,"IIB=",IIB," HDIR=",HDIR," LX=",LX," LY=",LY ; call flush(6)
+END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+NB_REQ = KNB_REQ
+
+CALL MPI_WAITALL(NB_REQ,KREQ,MPI_STATUSES_IGNORE,IERR)
+
+!
+!   Copy back the Zxxx_OUT buffer recv via MPI(gpu_direct) to PSRC halo
+! 
+
+IF (LX) THEN
+   IF (.NOT.GWEST) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZWEST_OUT) async(IS_WEST)
+#endif
+   !$acc kernels async(IS_WEST)
+   PSRC( 1:IIB-1  ,      IJB:IJE      , : ) = ZWEST_OUT( 1:IIB-1  ,   IJB:IJE    , : )
+   !$acc end kernels
+   ENDIF
+   IF (.NOT.GEAST) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZEAST_OUT) async(IS_EAST)
+#endif
+   !$acc kernels async(IS_EAST)
+   PSRC( IIE+1:IIU  ,      IJB:IJE      , : ) = ZEAST_OUT( IIE+1:IIU  ,   IJB:IJE    , : )  
+   !$acc end kernels
+   ENDIF
+END IF
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZSOUTH_OUT) async(IS_SOUTH)
+#endif
+   !$acc kernels async(IS_SOUTH)
+   PSRC(      IIB:IIE       ,  1:IJB-1 , : ) = ZSOUTH_OUT(  IIB:IIE     , 1:IJB-1  , : )
+   !$acc end kernels
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZNORTH_OUT) async(IS_NORTH)
+#endif
+   !$acc kernels async(IS_NORTH)
+   PSRC(      IIB:IIE       , IJE+1:IJU , : ) = ZNORTH_OUT (  IIB:IIE     , IJE+1:IJU  , : )
+   !$acc end kernels
+   ENDIF
+END IF
+!$acc wait
+
+!$acc end data
+!
+END SUBROUTINE GET_HALO_STOP_D
 !-------------------------------------------------------------------------------
 !     ########################################
-      SUBROUTINE GET_HALO_D(PSRC, HDIR, HNAME)
+      SUBROUTINE GET_HALO_DD(PSRC, HDIR, HNAME)
 !     ########################################
+#define MNH_GPUDIRECT
 !
 USE MODD_HALO_D
 USE MODE_ll
@@ -155,6 +584,11 @@ USE MODE_MNH_ZWORK, ONLY : GWEST , GEAST, GSOUTH , GNORTH
 USE MODD_CONF, ONLY : NHALO
 USE MODE_DEVICE
 USE MODE_MPPDB
+
+USE MODD_VAR_ll, ONLY    : IP,NPROC,NP1,NP2
+USE MODD_VAR_ll, ONLY : NMNH_COMM_WORLD
+USE MODD_MPIF,    ONLY : MPI_STATUSES_IGNORE
+USE MODD_PRECISION,  ONLY : MNHREAL_MPI
 !
 IMPLICIT NONE
 !
@@ -169,20 +603,21 @@ INTEGER, SAVE :: IIB,IJB    ! Begining useful area in x,y,z directions
 INTEGER, SAVE :: IIE,IJE    ! End useful area in x,y,z directions
 
 INTEGER,SAVE      :: IIU,IJU,IKU
-INTEGER,SAVE      :: IHALO_1
+
 INTEGER,PARAMETER :: IS_WEST=1 , IS_EAST=2, IS_SOUTH=3, IS_NORTH=4
 
+INTEGER, SAVE :: IIBX,IJBX   ! Extended Begining useful area in x,y,z directions
+INTEGER, SAVE :: IIEX,IJEX   ! Extended End useful area in x,y,z directions
+
 LOGICAL      :: LX , LY
 
-!
-!LOGICAL, SAVE                               :: GFIRST_GET_HALO_D = .TRUE.
-!
+INTEGER      :: INB_REQ , IREQ(8)
+INTEGER      :: IERR
+
+if ( NPROC == 1 ) RETURN
 
 !$acc data present ( PSRC )
 
-!JUANCHECK3D IF (GSMONOPROC) RETURN
-!
-#define _PW_NOINTERM
 NULLIFY( TZ_PSRC_ll)
 !
 IF (GFIRST_GET_HALO_D ) THEN 
@@ -195,34 +630,48 @@ IF (GFIRST_GET_HALO_D ) THEN
    !
    IHALO_1 = NHALO-1
    !
-#ifndef _PW_NOINTERM
-   ALLOCATE  ( ZSOUTH_IN ( IIB:IIE   , IJB:IJB+IHALO_1   , IKU ) )
-   ALLOCATE  ( ZNORTH_IN ( IIB:IIE   , IJE-IHALO_1:IJE   , IKU ) )
-   ALLOCATE  ( ZWEST_IN  ( IIB:IIB+IHALO_1   , IJB:IJE   , IKU ) )
-   ALLOCATE  ( ZEAST_IN  ( IIE-IHALO_1:IIE   , IJB:IJE   , IKU ) )
+!!$   IIBX= 1 ; IIEX= IIU ; IJBX= 1 ;  IJEX= IJU
+   IIBX= IIB ; IIEX= IIE ; IJBX= IJB ; IJEX= IJE   
+
+   ALLOCATE  ( ZSOUTH_IN ( IIBX:IIEX   , IJB:IJB+IHALO_1   , IKU ) )
+   ALLOCATE  ( ZNORTH_IN ( IIBX:IIEX   , IJE-IHALO_1:IJE   , IKU ) )
+   ALLOCATE  ( ZWEST_IN  ( IIB:IIB+IHALO_1   , IJBX:IJEX   , IKU ) )
+   ALLOCATE  ( ZEAST_IN  ( IIE-IHALO_1:IIE   , IJBX:IJEX   , IKU ) )
    !$acc enter data create (ZNORTH_IN, ZSOUTH_IN, ZWEST_IN, ZEAST_IN)
    !
-   ALLOCATE  ( ZSOUTH_OUT (   IIB:IIE   , 1:IJB-1 , IKU ) )
-   ALLOCATE  ( ZNORTH_OUT (   IIB:IIE   , IJE+1:IJU , IKU ) )
-   ALLOCATE  ( ZWEST_OUT  ( 1:IIB-1 ,   IJB:IJE   , IKU ) )
-   ALLOCATE  ( ZEAST_OUT  ( IIE+1:IIU ,   IJB:IJE   , IKU ) )
+   ALLOCATE  ( ZSOUTH_OUT (   IIBX:IIEX   , 1:IJB-1 , IKU ) )
+   ALLOCATE  ( ZNORTH_OUT (   IIBX:IIEX   , IJE+1:IJU , IKU ) )
+   ALLOCATE  ( ZWEST_OUT  ( 1:IIB-1 ,   IJBX:IJEX   , IKU ) )
+   ALLOCATE  ( ZEAST_OUT  ( IIE+1:IIU ,   IJBX:IJEX   , IKU ) )
    !$acc enter data create (ZNORTH_OUT, ZSOUTH_OUT, ZWEST_OUT, ZEAST_OUT)
 
-   CALL INIT_ON_HOST_AND_DEVICE(ZSOUTH_IN,-1e99,'GET_HALO_D::ZSOUTH_IN')
-   CALL INIT_ON_HOST_AND_DEVICE(ZNORTH_IN,-1e99,'GET_HALO_D::ZNORTH_IN')
-   CALL INIT_ON_HOST_AND_DEVICE(ZWEST_IN,-1e99,'GET_HALO_D::ZWEST_IN')
-   CALL INIT_ON_HOST_AND_DEVICE(ZEAST_IN,-1e99,'GET_HALO_D::ZEAST_IN')
-
-   CALL INIT_ON_HOST_AND_DEVICE(ZSOUTH_OUT,-1e99,'GET_HALO_D::ZSOUTH_OUT')
-   CALL INIT_ON_HOST_AND_DEVICE(ZNORTH_OUT,-1e99,'GET_HALO_D::ZNORTH_OUT')
-   CALL INIT_ON_HOST_AND_DEVICE(ZWEST_OUT,-1e99,'GET_HALO_D::ZWEST_OUT')
-   CALL INIT_ON_HOST_AND_DEVICE(ZEAST_OUT,-1e99,'GET_HALO_D::ZEAST_OUT')
-#endif
-
+   IF (.NOT. GWEST ) THEN
+      NP_WEST = ( IP-1 -1 ) + 1
+   ELSE
+      NP_WEST = 0
+   ENDIF
+   IF (.NOT. GEAST ) THEN
+      NP_EAST = ( IP-1 +1 ) + 1
+   ELSE
+      NP_EAST = 0
+   ENDIF
+   IF (.NOT. GSOUTH ) THEN
+      NP_SOUTH =  ( IP-1 -NP1 ) + 1
+   ELSE
+      NP_SOUTH = 0
+   ENDIF
+   IF (.NOT. GNORTH ) THEN
+      NP_NORTH =  ( IP-1 +NP1 ) + 1
+   ELSE
+      NP_NORTH = 0
+   ENDIF
+   
+   !print*,"PROC=",IP, GWEST,NP_WEST, GEAST,NP_EAST, GSOUTH,NP_SOUTH ,  GNORTH,NP_NORTH
+       
    GFIRST_GET_HALO_D = .FALSE.
+   
 END IF 
 
-
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
 LX = .FALSE.
@@ -232,162 +681,215 @@ IF (.NOT. PRESENT(HDIR) ) THEN
 LX = .TRUE.
 LY = .TRUE.
 ELSE
-LX = ( HDIR == "01_X" .OR. HDIR == "S0_X" )
-LY = ( HDIR == "01_Y" .OR. HDIR == "S0_Y" )
+   !
+   !  Problem of reproductibility in ppm_s0_x/y if only S0_X or S0_Y
+   !  so add S0_X + S0_Y for ppm_s0*
+   !
+!!$LX = ( HDIR == "01_X" .OR. HDIR == "S0_X" )
+!!$LY = ( HDIR == "01_Y" .OR. HDIR == "S0_Y" )
+LX = ( HDIR == "01_X" .OR. HDIR == "S0_X" .OR. HDIR == "S0_Y" )
+LY = ( HDIR == "01_Y" .OR. HDIR == "S0_Y" .OR. HDIR == "S0_X" )
+END IF
+
+!!$LX = .TRUE.
+!!$LY = .TRUE.
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+INB_REQ = 0
+
+!
+! Post the recieve of Zxxxx_IN buffer first via MPI(Gpu_direct)
+!
+
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZWEST_OUT)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_IRECV(ZWEST_OUT,SIZE(ZWEST_OUT),MNHREAL_MPI,NP_WEST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   END IF
+   IF (.NOT.GEAST) THEN 
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZEAST_OUT)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_IRECV(ZEAST_OUT,SIZE(ZEAST_OUT),MNHREAL_MPI,NP_EAST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZSOUTH_OUT)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_IRECV(ZSOUTH_OUT,SIZE(ZSOUTH_OUT),MNHREAL_MPI,NP_SOUTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZNORTH_OUT)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_IRECV(ZNORTH_OUT,SIZE(ZNORTH_OUT),MNHREAL_MPI,NP_NORTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
 END IF
 
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+!Copy the halo on the device PSRC to Zxxxx_IN
 
-!Copy the halo on the device PSRC to Zxxxx_IN and put it in the PSRC copy on the host
-#ifndef _PW_NOINTERM
 IF (LX) THEN
    IF (.NOT. GWEST) THEN
    !$acc kernels async(IS_WEST)
-   ZWEST_IN ( IIB:IIB+IHALO_1  ,    IJB:IJE  , : )  = PSRC( IIB:IIB+IHALO_1  ,  IJB:IJE  , : )
+   ZWEST_IN ( IIB:IIB+IHALO_1  ,    IJBX:IJEX  , : )  = PSRC( IIB:IIB+IHALO_1  ,  IJBX:IJEX  , : )
    !$acc end kernels
-   !$acc update host(ZWEST_IN) async(IS_WEST)
-   END IF
+      END IF
    IF (.NOT.GEAST) THEN
    !$acc kernels async(IS_EAST)
-   ZEAST_IN ( IIE-IHALO_1:IIE  ,    IJB:IJE  , : )  = PSRC( IIE-IHALO_1:IIE  ,  IJB:IJE  , : )
+   ZEAST_IN ( IIE-IHALO_1:IIE  ,    IJBX:IJEX  , : )  = PSRC( IIE-IHALO_1:IIE  ,  IJBX:IJEX  , : )
    !$acc end kernels
-   !$acc update host(ZEAST_IN) async(IS_EAST)
-   ENDIF
+      ENDIF
 END IF
 IF (LY) THEN
    IF (.NOT.GSOUTH) THEN
    !$acc kernels async(IS_SOUTH)
-   ZSOUTH_IN ( IIB:IIE  ,    IJB:IJB+IHALO_1  , : ) = PSRC( IIB:IIE  ,    IJB:IJB+IHALO_1  , : )
+   ZSOUTH_IN ( IIBX:IIEX  ,    IJB:IJB+IHALO_1  , : ) = PSRC( IIBX:IIEX  ,    IJB:IJB+IHALO_1  , : )
    !$acc end kernels
-   !$acc update host(ZSOUTH_IN) async(IS_SOUTH)
-   ENDIF
+      ENDIF
    IF (.NOT.GNORTH) THEN
    !$acc kernels async(IS_NORTH)
-   ZNORTH_IN ( IIB:IIE  ,    IJE-IHALO_1:IJE  , : ) = PSRC( IIB:IIE  ,    IJE-IHALO_1:IJE  , : )
+   ZNORTH_IN ( IIBX:IIEX  ,    IJE-IHALO_1:IJE  , : ) = PSRC( IIBX:IIEX  ,    IJE-IHALO_1:IJE  , : )
    !$acc end kernels
-   !$acc update host(ZNORTH_IN) async(IS_NORTH)
    ENDIF
 ENDIF
 !$acc wait
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! Send  Zxxxx_IN buffer via MPI(Gpu_direct) or copy to host
+!
 IF (LX) THEN
    IF (.NOT. GWEST) THEN
-   PSRC( IIB:IIB+IHALO_1  , IJB:IJE  , : )   = ZWEST_IN  ( IIB:IIB+IHALO_1   , IJB:IJE   , : )
-   ENDIF
-   IF (.NOT.GEAST) THEN 
-   PSRC( IIE-IHALO_1:IIE  , IJB:IJE  , : )   = ZEAST_IN  ( IIE-IHALO_1:IIE   , IJB:IJE   , : )
-   ENDIF
-END IF
-IF (LY) THEN
-   IF (.NOT.GSOUTH) THEN
-   PSRC( IIB:IIE  , IJB:IJB+IHALO_1  , : ) = ZSOUTH_IN ( IIB:IIE  ,    IJB:IJB+IHALO_1  , : )
-   ENDIF
-   IF (.NOT.GNORTH) THEN
-   PSRC( IIB:IIE  , IJE-IHALO_1:IJE  , : ) = ZNORTH_IN ( IIB:IIE  ,    IJE-IHALO_1:IJE  , : )
-   ENDIF
-ENDIF
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZWEST_IN)
 #else
-IF (LX) THEN
-   IF (.NOT. GWEST) THEN
-   !$acc update host(PSRC( IIB:IIB+IHALO_1  , IJB:IJE  , : ))
-   ENDIF
+      !$acc update host(ZWEST_IN)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_ISEND(ZWEST_IN,SIZE(ZWEST_IN)  ,MNHREAL_MPI,NP_WEST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   END IF
    IF (.NOT.GEAST) THEN
-   !$acc update host(PSRC( IIE-IHALO_1:IIE  , IJB:IJE  , : ))
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZEAST_IN)
+#else
+      !$acc update host(ZEAST_IN)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_ISEND(ZEAST_IN,SIZE(ZEAST_IN)  ,MNHREAL_MPI,NP_EAST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
    ENDIF
 END IF
+
 IF (LY) THEN
    IF (.NOT.GSOUTH) THEN
-   !$acc update host(PSRC( IIB:IIE  , IJB:IJB+IHALO_1  , : ))
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZSOUTH_IN)
+#else
+      !$acc update host(ZSOUTH_IN)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_ISEND(ZSOUTH_IN,SIZE(ZSOUTH_IN)  ,MNHREAL_MPI,NP_SOUTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
    ENDIF
    IF (.NOT.GNORTH) THEN
-   !$acc update host(PSRC( IIB:IIE  , IJE-IHALO_1:IJE  , : ))
-   ENDIF
-ENDIF
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZNORTH_IN)
+#else
+      !$acc update host(ZNORTH_IN)
 #endif
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-if ( present ( hname ) ) then
-  yname = hname
-else
-  yname = 'PSRC'
-end if
-
-IF (LX .OR. LY) THEN
-  CALL ADD3DFIELD_ll( TZ_PSRC_ll, PSRC, 'GET_HALO::'//trim( yname ) )
-  CALL UPDATE_HALO_ll(TZ_PSRC_ll,IERROR, HDIR=HDIR )
-  CALL CLEANLIST_ll(TZ_PSRC_ll)
-ELSE
-  !Necessary to allow comparisons/checks with standard GET_HALO
-  CALL MPPDB_CHECK(PSRC,"UPDATE_HALO_ll::GET_HALO::"//trim( yname ))
+      INB_REQ = INB_REQ + 1
+      CALL MPI_ISEND(ZNORTH_IN,SIZE(ZNORTH_IN)  ,MNHREAL_MPI,NP_NORTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF   
 ENDIF
 
-!Copy the halo on the host PSRC to Zxxxx_OUT and put it in the PSRC copy on the device
-#ifndef _PW_NOINTERM
-IF (LX) THEN
-   IF (.NOT.GWEST) THEN
-   ZWEST_OUT( 1:IIB-1  ,   IJB:IJE    , : )  = PSRC( 1:IIB-1  ,   IJB:IJE    , : )
-   ENDIF
-   IF (.NOT.GEAST) THEN
-   ZEAST_OUT( IIE+1:IIU  ,   IJB:IJE    , : )  = PSRC( IIE+1:IIU  ,   IJB:IJE    , : )
-   ENDIF
-END IF
-IF (LY) THEN
-   IF (.NOT.GSOUTH) THEN
-   ZSOUTH_OUT (  IIB:IIE     , 1:IJB-1  , : ) = PSRC(  IIB:IIE     , 1:IJB-1  , : )
-   ENDIF
-   IF (.NOT.GNORTH) THEN
-   ZNORTH_OUT (  IIB:IIE     , IJE+1:IJU  , : ) = PSRC(  IIB:IIE     , IJE+1:IJU  , : )
-   ENDIF
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+IF ( INB_REQ > 0 ) THEN
+   CALL MPI_WAITALL(INB_REQ,IREQ,MPI_STATUSES_IGNORE,IERR)
 END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Is update halo
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
 IF (LX) THEN
    IF (.NOT.GWEST) THEN
+#ifndef MNH_GPUDIRECT
    !$acc update device(ZWEST_OUT) async(IS_WEST)
+#endif
    !$acc kernels async(IS_WEST)
-   PSRC( 1:IIB-1  ,      IJB:IJE      , : ) = ZWEST_OUT( 1:IIB-1  ,   IJB:IJE    , : )
+   PSRC( 1:IIB-1  ,      IJBX:IJEX      , : ) = ZWEST_OUT( 1:IIB-1  ,   IJBX:IJEX    , : )
    !$acc end kernels
    ENDIF
    IF (.NOT.GEAST) THEN
+#ifndef MNH_GPUDIRECT
    !$acc update device(ZEAST_OUT) async(IS_EAST)
+#endif
    !$acc kernels async(IS_EAST)
-   PSRC( IIE+1:IIU  ,      IJB:IJE      , : ) = ZEAST_OUT( IIE+1:IIU  ,   IJB:IJE    , : )  
+   PSRC( IIE+1:IIU  ,      IJBX:IJEX      , : ) = ZEAST_OUT( IIE+1:IIU  ,   IJBX:IJEX    , : )  
    !$acc end kernels
    ENDIF
 END IF
 IF (LY) THEN
    IF (.NOT.GSOUTH) THEN
+#ifndef MNH_GPUDIRECT
    !$acc update device(ZSOUTH_OUT) async(IS_SOUTH)
+#endif
    !$acc kernels async(IS_SOUTH)
-   PSRC(      IIB:IIE       ,  1:IJB-1 , : ) = ZSOUTH_OUT(  IIB:IIE     , 1:IJB-1  , : )
+   PSRC(      IIBX:IIEX       ,  1:IJB-1 , : ) = ZSOUTH_OUT(  IIBX:IIEX     , 1:IJB-1  , : )
    !$acc end kernels
    ENDIF
    IF (.NOT.GNORTH) THEN
+#ifndef MNH_GPUDIRECT
    !$acc update device(ZNORTH_OUT) async(IS_NORTH)
+#endif
    !$acc kernels async(IS_NORTH)
-   PSRC(      IIB:IIE       , IJE+1:IJU , : ) = ZNORTH_OUT (  IIB:IIE     , IJE+1:IJU  , : )
+   PSRC(      IIBX:IIEX       , IJE+1:IJU , : ) = ZNORTH_OUT (  IIBX:IIEX     , IJE+1:IJU  , : )
    !$acc end kernels
    ENDIF
 END IF
 !$acc wait
-#else
-IF (LX) THEN
-   IF (.NOT.GWEST) THEN
-   !$acc update device(PSRC( 1:IIB-1  ,   IJB:IJE    , : ))
-   ENDIF
-   IF (.NOT.GEAST) THEN
-   !$acc update device(PSRC( IIE+1:IIU  ,   IJB:IJE    , : ))
-   ENDIF
-END IF
-IF (LY) THEN
-   IF (.NOT.GSOUTH) THEN
-   !$acc update device(PSRC(  IIB:IIE     , 1:IJB-1  , : ))
-   ENDIF
-   IF (.NOT.GNORTH) THEN
-   !$acc update device(PSRC(  IIB:IIE     , IJE+1:IJU  , : ))
-   ENDIF
-END IF
-#endif
 
 !$acc end data
 
-END SUBROUTINE GET_HALO_D
+END SUBROUTINE GET_HALO_DD
 #endif
 !-----------------------------------------------------------------------
 !
diff --git a/src/MNH/gradient_u.f90 b/src/MNH/gradient_u.f90
index 0dde760c72d5da4f05a92966896012bd80da9846..a45e5903fb4c98852ee5dd750be323a72c7a8074 100644
--- a/src/MNH/gradient_u.f90
+++ b/src/MNH/gradient_u.f90
@@ -31,7 +31,7 @@ REAL, DIMENSION(:,:,:), INTENT(IN) :: PDXX     ! metric coefficient dxx
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ     ! metric coefficient dzz
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZX     ! metric coefficient dzx
 !
-REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)), INTENT(OUT) :: PGX_U_M_DEVICE ! result mass point
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PGX_U_M_DEVICE ! result mass point
 !
 END SUBROUTINE GX_U_M_DEVICE
 #endif
@@ -58,7 +58,7 @@ REAL, DIMENSION(:,:,:), INTENT(IN) :: PDYY     ! metric coefficient dyy
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ     ! metric coefficient dzz
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZY     ! metric coefficient dzy
 !
-REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)), INTENT(OUT) :: PGY_U_UV_DEVICE ! result UV point
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PGY_U_UV_DEVICE ! result UV point
 !
 END SUBROUTINE GY_U_UV_DEVICE
 #endif
@@ -81,7 +81,7 @@ INTEGER,                INTENT(IN) :: KL       ! +1 if grid goes from ground to
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PA       ! variable at the U point
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ     ! metric coefficient dzz
 !
-REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)), INTENT(OUT) :: PGZ_U_UW_DEVICE ! result UW point
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PGZ_U_UW_DEVICE ! result UW point
 !
 END SUBROUTINE GZ_U_UW_DEVICE
 #endif
@@ -201,6 +201,8 @@ END FUNCTION GX_U_M
 USE MODI_SHUMAN_DEVICE
 USE MODD_CONF
 !
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D
+!
 IMPLICIT NONE
 !
 !
@@ -213,24 +215,28 @@ REAL, DIMENSION(:,:,:), INTENT(IN) :: PDXX     ! metric coefficient dxx
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ     ! metric coefficient dzz
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZX     ! metric coefficient dzx
 !
-REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)), INTENT(OUT) :: PGX_U_M_DEVICE ! result mass point
-!
-REAL, DIMENSION(:,:,:), allocatable ::  ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE
-!
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PGX_U_M_DEVICE ! result mass point
 !
 !*       0.2   declaration of local variables
 !
-!              NONE
+REAL, DIMENSION(:,:,:), pointer , contiguous ::  ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE
+INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE
 !
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ,JK
 !----------------------------------------------------------------------------
 
 !$acc data present( PA, PDXX, PDZZ, PDZX, PGX_U_M_DEVICE )
 
-allocate( ztmp1_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
-allocate( ztmp2_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
-allocate( ztmp3_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
+JIU =  size(pa, 1 )
+JJU =  size(pa, 2 )
+JKU =  size(pa, 3 )
+
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU )
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU )
+iztmp3_device = MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU,JKU )
 
-!$acc data create( ztmp1_device, ztmp2_device, ztmp3_device )
+!$acc data present( ztmp1_device, ztmp2_device, ztmp3_device )
 
 !
 !*       1.    DEFINITION of GX_U_M_DEVICE
@@ -239,11 +245,17 @@ IF (.NOT. LFLAT) THEN
   CALL DXF_DEVICE(PA,ZTMP1_DEVICE)
   CALL DZM_DEVICE(KKA,KKU,KL,PA,ZTMP2_DEVICE)
   !$acc kernels
-  ZTMP3_DEVICE(:,:,:) = PDZX(:,:,:) * ZTMP2_DEVICE(:,:,:)
+  !$acc loop independent collapse(3)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP3_DEVICE(JI,JJ,JK) = PDZX(JI,JJ,JK) * ZTMP2_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT
   !$acc end kernels
   CALL MXF_DEVICE(ZTMP3_DEVICE,ZTMP2_DEVICE)
   !$acc kernels
-  ZTMP3_DEVICE(:,:,:) = ZTMP2_DEVICE(:,:,:) / PDZZ(:,:,:)
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP3_DEVICE(JI,JJ,JK) = ZTMP2_DEVICE(JI,JJ,JK) / PDZZ(JI,JJ,JK)
+  END DO !CONCURRENT
   !$acc end kernels
   CALL MZF_DEVICE(KKA,KKU,KL,ZTMP3_DEVICE,ZTMP2_DEVICE)
   CALL MXF_DEVICE(PDXX,ZTMP3_DEVICE)
@@ -260,6 +272,8 @@ END IF
 
 !$acc end data
 
+CALL MNH_REL_ZT3D(iztmp1_device,iztmp2_device,iztmp3_device)
+
 !$acc end data
 
 !----------------------------------------------------------------------------
@@ -375,6 +389,8 @@ END FUNCTION GY_U_UV
 USE MODI_SHUMAN_DEVICE
 USE MODD_CONF
 !
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D
+!
 IMPLICIT NONE
 !
 !
@@ -387,24 +403,30 @@ REAL, DIMENSION(:,:,:), INTENT(IN) :: PDYY     ! metric coefficient dyy
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ     ! metric coefficient dzz
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZY     ! metric coefficient dzy
 !
-REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)), INTENT(OUT) :: PGY_U_UV_DEVICE ! result UV point
-!
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PGY_U_UV_DEVICE ! result UV point
 !
 !
 !*       0.2   declaration of local variables
 !
-!              NONE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE
+INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE
+!
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ,JK
 !
 !----------------------------------------------------------------------------
 
 !$acc data present( PA, PDYY, PDZZ, PDZY, PGY_U_UV_DEVICE )
 
-allocate( ztmp1_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
-allocate( ztmp2_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
-allocate( ztmp3_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
+JIU =  size(pa, 1 )
+JJU =  size(pa, 2 )
+JKU =  size(pa, 3 )
+
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU )
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU )
+iztmp3_device = MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU,JKU )
 
-!$acc data create( ztmp1_device, ztmp2_device, ztmp3_device )
+!$acc data present( ztmp1_device, ztmp2_device, ztmp3_device )
 
 !
 !*       1.    DEFINITION of GY_U_UV_DEVICE
@@ -414,18 +436,27 @@ IF (.NOT. LFLAT) THEN
   CALL DZM_DEVICE(KKA,KKU,KL,PA,ZTMP1_DEVICE)
   CALL MXM_DEVICE(PDZZ,ZTMP2_DEVICE)
   !$acc kernels
-  ZTMP3_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:)/ZTMP2_DEVICE(:,:,:)
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP3_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK)/ZTMP2_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT    
   !$acc end kernels
   CALL MYM_DEVICE(ZTMP3_DEVICE,ZTMP1_DEVICE)
   CALL MXM_DEVICE(PDZY,ZTMP2_DEVICE)
   !$acc kernels
-  ZTMP3_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:)*ZTMP2_DEVICE(:,:,:)
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP3_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK)*ZTMP2_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
   !$acc end kernels
   CALL MZF_DEVICE(KKA,KKU,KL, ZTMP3_DEVICE,ZTMP2_DEVICE )
   CALL DYM_DEVICE(PA,ZTMP1_DEVICE)
   CALL MXM_DEVICE(PDYY,ZTMP3_DEVICE)
   !$acc kernels
-  PGY_U_UV_DEVICE(:,:,:)=  ( ZTMP1_DEVICE(:,:,:) - ZTMP2_DEVICE(:,:,:) ) / ZTMP3_DEVICE(:,:,:)
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     PGY_U_UV_DEVICE(JI,JJ,JK)=  ( ZTMP1_DEVICE(JI,JJ,JK) - ZTMP2_DEVICE(JI,JJ,JK) ) / ZTMP3_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
   !$acc end kernels
 ELSE
   CALL DYM_DEVICE(PA,ZTMP1_DEVICE)
@@ -437,6 +468,8 @@ END IF
 
 !$acc end data
 
+CALL MNH_REL_ZT3D(iztmp1_device,iztmp2_device,iztmp3_device)
+
 !$acc end data
 
 !----------------------------------------------------------------------------
@@ -535,6 +568,7 @@ END FUNCTION GZ_U_UW
 !
 !
 USE MODI_SHUMAN_DEVICE
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D
 !
 IMPLICIT NONE
 !
@@ -546,23 +580,26 @@ INTEGER,                INTENT(IN) :: KL       ! +1 if grid goes from ground to
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PA       ! variable at the U point
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ     ! metric coefficient dzz
 !
-REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)), INTENT(OUT) :: PGZ_U_UW_DEVICE ! result UW point
-!
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE, ZTMP2_DEVICE
-!
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PGZ_U_UW_DEVICE ! result UW point
 !
 !*       0.2   declaration of local variables
 !
-!              NONE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE, ZTMP2_DEVICE
+INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE
 !
+INTEGER  :: JIU,JJU,JKU
 !----------------------------------------------------------------------------
 
 !$acc data present( PA, PDZZ, PGZ_U_UW_DEVICE )
 
-allocate( ztmp1_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
-allocate( ztmp2_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
+JIU =  size(pa, 1 )
+JJU =  size(pa, 2 )
+JKU =  size(pa, 3 )
 
-!$acc data create( ztmp1_device, ztmp2_device )
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU )
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU )
+
+!$acc data present( ztmp1_device, ztmp2_device )
 
 !
 !*       1.    DEFINITION of GZ_U_UW_DEVICE
@@ -576,6 +613,8 @@ PGZ_U_UW_DEVICE(:,:,:)= ZTMP1_DEVICE(:,:,:) / ZTMP2_DEVICE(:,:,:)
 
 !$acc end data
 
+CALL MNH_REL_ZT3D(iztmp1_device,iztmp2_device)
+
 !$acc end data
 
 !----------------------------------------------------------------------------
diff --git a/src/MNH/gradient_v.f90 b/src/MNH/gradient_v.f90
index 18730e274a0fbc3390eb5c6e906a24b9c3ee53de..2a7742d33000c42fd2bef1244aca99363badef59 100644
--- a/src/MNH/gradient_v.f90
+++ b/src/MNH/gradient_v.f90
@@ -32,7 +32,7 @@ REAL, DIMENSION(:,:,:), INTENT(IN) :: PDYY     ! metric coefficient dyy
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ     ! metric coefficient dzz
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZY     ! metric coefficient dzy
 !
-REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)), INTENT(OUT) :: PGY_V_M_DEVICE ! result mass point
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PGY_V_M_DEVICE ! result mass point
 !
 END SUBROUTINE GY_V_M_DEVICE
 #endif
@@ -60,7 +60,7 @@ REAL, DIMENSION(:,:,:), INTENT(IN) :: PDXX     ! metric coefficient dxx
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ     ! metric coefficient dzz
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZX     ! metric coefficient dzx
 !
-REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)), INTENT(OUT) :: PGX_V_UV_DEVICE ! result UV point
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PGX_V_UV_DEVICE ! result UV point
 !
 END SUBROUTINE GX_V_UV_DEVICE
 #endif
@@ -84,7 +84,7 @@ INTEGER,                INTENT(IN) :: KL       ! +1 if grid goes from ground to
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PA       ! variable at the V point
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ     ! metric coefficient dzz
 !
-REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)), INTENT(OUT) :: PGZ_V_VW_DEVICE ! result VW point
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PGZ_V_VW_DEVICE ! result VW point
 !
 END SUBROUTINE GZ_V_VW_DEVICE
 #endif
@@ -94,8 +94,6 @@ END INTERFACE
 !
 END MODULE MODI_GRADIENT_V
 !
-!
-!
 !     #######################################################
       FUNCTION GY_V_M(PA,PDYY,PDZZ,PDZY)      RESULT(PGY_V_M)
 !     #######################################################
@@ -201,6 +199,7 @@ END FUNCTION GY_V_M
 !
 USE MODI_SHUMAN_DEVICE
 USE MODD_CONF
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D
 !
 IMPLICIT NONE
 !
@@ -214,9 +213,13 @@ REAL, DIMENSION(:,:,:), INTENT(IN) :: PDYY     ! metric coefficient dyy
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ     ! metric coefficient dzz
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZY     ! metric coefficient dzy
 !
-REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)), INTENT(OUT) :: PGY_V_M_DEVICE ! result mass point
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PGY_V_M_DEVICE ! result mass point
 !
-REAL, DIMENSION(:,:,:), allocatable ::  ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous ::  ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE
+INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE
+!
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ,JK
 !
 !*       0.2   declaration of local variables
 !
@@ -226,11 +229,15 @@ REAL, DIMENSION(:,:,:), allocatable ::  ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE
 
 !$acc data present( PA, PDYY, PDZZ, PDZY, PGY_V_M_DEVICE )
 
-allocate( ztmp1_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
-allocate( ztmp2_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
-allocate( ztmp3_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
+JIU =  size(pa, 1 )
+JJU =  size(pa, 2 )
+JKU =  size(pa, 3 )
+
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU )
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU )
+iztmp3_device = MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU,JKU )
 
-!$acc data create( ztmp1_device, ztmp2_device, ztmp3_device )
+!$acc data present( ztmp1_device, ztmp2_device, ztmp3_device )
 
 !
 !*       1.    DEFINITION of GY_V_M_DEVICE
@@ -239,13 +246,19 @@ allocate( ztmp3_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
 IF (.NOT. LFLAT) THEN
   CALL DYF_DEVICE(PA,ZTMP1_DEVICE)
   CALL DZM_DEVICE(KKA,KKU,KL,PA,ZTMP2_DEVICE)
-!$acc kernels
-  ZTMP3_DEVICE(:,:,:) = PDZY(:,:,:)*ZTMP2_DEVICE(:,:,:)
-!$acc end kernels
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP3_DEVICE(JI,JJ,JK) = PDZY(JI,JJ,JK)*ZTMP2_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT
+  !$acc end kernels
   CALL MYF_DEVICE(ZTMP3_DEVICE,ZTMP2_DEVICE)
-!$acc kernels
-  ZTMP3_DEVICE(:,:,:) = ZTMP2_DEVICE(:,:,:)/PDZZ(:,:,:)
-!$acc end kernels
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP3_DEVICE(JI,JJ,JK) = ZTMP2_DEVICE(JI,JJ,JK)/PDZZ(JI,JJ,JK)
+  END DO !CONCURRENT
+  !$acc end kernels
   CALL MZF_DEVICE(KKA,KKU,KL,ZTMP3_DEVICE,ZTMP2_DEVICE)
   CALL MYF_DEVICE(PDYY,ZTMP3_DEVICE)
 !$acc kernels
@@ -261,6 +274,8 @@ END IF
 
 !$acc end data
 
+CALL MNH_REL_ZT3D(iztmp1_device,iztmp2_device,iztmp3_device)
+
 !$acc end data
 
 !----------------------------------------------------------------------------
@@ -374,6 +389,7 @@ END FUNCTION GX_V_UV
 !
 USE MODI_SHUMAN_DEVICE
 USE MODD_CONF
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D
 !
 IMPLICIT NONE
 !
@@ -387,48 +403,61 @@ REAL, DIMENSION(:,:,:), INTENT(IN) :: PDXX     ! metric coefficient dxx
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ     ! metric coefficient dzz
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZX     ! metric coefficient dzx
 !
-REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)), INTENT(OUT) :: PGX_V_UV_DEVICE ! result UV point
-!
-REAL, DIMENSION(:,:,:), allocatable ::  ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE
-!
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PGX_V_UV_DEVICE ! result UV point
 !
 !*       0.2   declaration of local variables
 !
-!              NONE
+REAL, DIMENSION(:,:,:), pointer , contiguous ::  ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE
+INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE
+!
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ,JK
 !
 !----------------------------------------------------------------------------
 
 !$acc data present( PA, PDXX, PDZZ, PDZX, PGX_V_UV_DEVICE )
 
-allocate( ztmp1_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
-allocate( ztmp2_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
-allocate( ztmp3_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
-allocate( ztmp4_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
+JIU =  size(pa, 1 )
+JJU =  size(pa, 2 )
+JKU =  size(pa, 3 )
+
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU )
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU )
+iztmp3_device = MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU,JKU )
+iztmp4_device = MNH_ALLOCATE_ZT3D( ztmp4_device,JIU,JJU,JKU )
 
-!$acc data create( ztmp1_device, ztmp2_device, ztmp3_device, ztmp4_device )
+!$acc data present( ztmp1_device, ztmp2_device, ztmp3_device, ztmp4_device )
 
 !
 !*       1.    DEFINITION of GX_V_UV_DEVICE
 !              ---------------------
 !
 IF (.NOT. LFLAT) THEN
-  
   CALL DXM_DEVICE(PA,ZTMP1_DEVICE)
   CALL MYM_DEVICE(PDZZ,ZTMP2_DEVICE)
   CALL DZM_DEVICE(KKA,KKU,KL,PA,ZTMP3_DEVICE)
-!$acc kernels
-  ZTMP4_DEVICE(:,:,:) = ZTMP3_DEVICE(:,:,:) / ZTMP2_DEVICE(:,:,:)
-!$acc end kernels
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP4_DEVICE(JI,JJ,JK) = ZTMP3_DEVICE(JI,JJ,JK) / ZTMP2_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
+  !$acc end kernels
   CALL MXM_DEVICE(ZTMP4_DEVICE,ZTMP2_DEVICE)
   CALL MYM_DEVICE(PDZX,ZTMP3_DEVICE)
-!$acc kernels
-  ZTMP4_DEVICE(:,:,:) = ZTMP2_DEVICE(:,:,:) *ZTMP3_DEVICE(:,:,:)
-!$acc end kernels
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP4_DEVICE(JI,JJ,JK) = ZTMP2_DEVICE(JI,JJ,JK) *ZTMP3_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
+  !$acc end kernels
   CALL MZF_DEVICE(KKA,KKU,KL,ZTMP4_DEVICE,ZTMP2_DEVICE)
   CALL MYM_DEVICE(PDXX,ZTMP3_DEVICE)
-!$acc kernels
-  PGX_V_UV_DEVICE(:,:,:)= ( ZTMP1_DEVICE(:,:,:) - ZTMP2_DEVICE(:,:,:) ) / ZTMP3_DEVICE(:,:,:)
-!$acc end kernels
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     PGX_V_UV_DEVICE(JI,JJ,JK)= ( ZTMP1_DEVICE(JI,JJ,JK) - ZTMP2_DEVICE(JI,JJ,JK) ) / ZTMP3_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
+  !$acc end kernels
 ELSE
   CALL DXM_DEVICE(PA,ZTMP1_DEVICE)
   CALL MYM_DEVICE(PDXX,ZTMP2_DEVICE)
@@ -439,6 +468,8 @@ END IF
 
 !$acc end data
 
+CALL MNH_REL_ZT3D(iztmp1_device,iztmp2_device,iztmp3_device,iztmp4_device)
+
 !$acc end data
 
 !----------------------------------------------------------------------------
@@ -538,6 +569,8 @@ END FUNCTION GZ_V_VW
 !
 !
 USE MODI_SHUMAN_DEVICE
+USE MODI_SHUMAN
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D
 !
 IMPLICIT NONE
 !
@@ -549,22 +582,26 @@ INTEGER,                INTENT(IN) :: KL       ! +1 if grid goes from ground to
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PA       ! variable at the V point
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ     ! metric coefficient dzz
 !
-REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)), INTENT(OUT) :: PGZ_V_VW_DEVICE ! result VW point
-!
-REAL, DIMENSION(:,:,:), allocatable ::  ZTMP1_DEVICE, ZTMP2_DEVICE
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PGZ_V_VW_DEVICE ! result VW point
 !
 !*       0.2   declaration of local variables
 !
-!              NONE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE, ZTMP2_DEVICE
+INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE
 !
+INTEGER  :: JIU,JJU,JKU
 !----------------------------------------------------------------------------
 
 !$acc data present( PA, PDZZ, PGZ_V_VW_DEVICE )
 
-allocate( ztmp1_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
-allocate( ztmp2_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
+JIU =  size(pa, 1 )
+JJU =  size(pa, 2 )
+JKU =  size(pa, 3 )
 
-!$acc data create( ztmp1_device, ztmp2_device )
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU )
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU )
+
+!$acc data present( ztmp1_device, ztmp2_device )
 
 !
 !*       1.    DEFINITION of GZ_V_VW_DEVICE
@@ -578,9 +615,12 @@ PGZ_V_VW_DEVICE(:,:,:)= ZTMP1_DEVICE(:,:,:) / ZTMP2_DEVICE(:,:,:)
 
 !$acc end data
 
+CALL MNH_REL_ZT3D(iztmp1_device,iztmp2_device)
+
 !$acc end data
 
 !----------------------------------------------------------------------------
 !
 END SUBROUTINE GZ_V_VW_DEVICE
 #endif
+
diff --git a/src/MNH/gradient_w.f90 b/src/MNH/gradient_w.f90
index 83ecb6721ca5b624d53e8bf6dd6f5e3354499593..f49ddab87bdd5ec92a0742325d4926829de7cac7 100644
--- a/src/MNH/gradient_w.f90
+++ b/src/MNH/gradient_w.f90
@@ -28,7 +28,7 @@ INTEGER,                INTENT(IN) :: KL       ! +1 if grid goes from ground to
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PA       ! variable at the W point
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ     ! metric coefficient dzz
 !
-REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)),  INTENT(OUT) :: PGZ_W_M_DEVICE ! result mass point
+REAL, DIMENSION(:,:,:),  INTENT(OUT) :: PGZ_W_M_DEVICE ! result mass point
 !
 END SUBROUTINE GZ_W_M_DEVICE
 #endif
@@ -56,7 +56,7 @@ REAL, DIMENSION(:,:,:), INTENT(IN) :: PDXX     ! metric coefficient dxx
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ     ! metric coefficient dzz
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZX     ! metric coefficient dzx
 !
-REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)),  INTENT(OUT) :: PGX_W_UW_DEVICE ! result UW point
+REAL, DIMENSION(:,:,:),  INTENT(OUT) :: PGX_W_UW_DEVICE ! result UW point
 !
 END SUBROUTINE GX_W_UW_DEVICE
 #endif
@@ -84,7 +84,7 @@ REAL, DIMENSION(:,:,:), INTENT(IN) :: PDYY     ! metric coefficient dyy
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ     ! metric coefficient dzz
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZY     ! metric coefficient dzy
 !
-REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)),  INTENT(OUT) :: PGY_W_VW_DEVICE ! result VW point
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PGY_W_VW_DEVICE ! result VW point
 !
 END SUBROUTINE GY_W_VW_DEVICE
 #endif
@@ -93,9 +93,7 @@ END SUBROUTINE GY_W_VW_DEVICE
 END INTERFACE
 !
 END MODULE MODI_GRADIENT_W
-!
-!
-!
+!  
 !     #######################################################
       FUNCTION GZ_W_M(PA,PDZZ)      RESULT(PGZ_W_M)
 !     #######################################################
@@ -181,6 +179,8 @@ END FUNCTION GZ_W_M
 !
 !
 USE MODI_SHUMAN_DEVICE
+USE MODI_SHUMAN
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D
 !
 IMPLICIT NONE
 !
@@ -192,20 +192,26 @@ INTEGER,                INTENT(IN) :: KL       ! +1 if grid goes from ground to
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PA       ! variable at the W point
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ     ! metric coefficient dzz
 !
-REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)),  INTENT(OUT) :: PGZ_W_M_DEVICE ! result mass point
+REAL, DIMENSION(:,:,:),  INTENT(OUT) :: PGZ_W_M_DEVICE ! result mass point
 !
 !*       0.2   declaration of local variables
 !
-REAL, DIMENSION(:,:,:), allocatable ::  ZTMP1_DEVICE, ZTMP2_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous ::  ZTMP1_DEVICE, ZTMP2_DEVICE
+INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE
 !
+INTEGER  :: JIU,JJU,JKU
 !----------------------------------------------------------------------------
 
 !$acc data present( PA, PDZZ, PGZ_W_M_DEVICE )
 
-allocate( ztmp1_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
-allocate( ztmp2_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
+JIU =  size(pa, 1 )
+JJU =  size(pa, 2 )
+JKU =  size(pa, 3 )
+
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU )
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU )
 
-!$acc data create( ztmp1_device, ztmp2_device )
+!$acc data present( ztmp1_device, ztmp2_device )
 
 !
 !*       1.    DEFINITION of GZ_W_M_DEVICE
@@ -219,6 +225,8 @@ PGZ_W_M_DEVICE(:,:,:)= ZTMP1_DEVICE(:,:,:)/ZTMP2_DEVICE(:,:,:)
 
 !$acc end data
 
+CALL MNH_REL_ZT3D(iztmp1_device,iztmp2_device)
+
 !$acc end data
 
 !----------------------------------------------------------------------------
@@ -323,6 +331,7 @@ END FUNCTION GX_W_UW
 !
 USE MODI_SHUMAN_DEVICE
 USE MODD_CONF
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D
 !
 IMPLICIT NONE
 !
@@ -336,23 +345,29 @@ REAL, DIMENSION(:,:,:), INTENT(IN) :: PDXX     ! metric coefficient dxx
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ     ! metric coefficient dzz
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZX     ! metric coefficient dzx
 !
-REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)),  INTENT(OUT) :: PGX_W_UW_DEVICE ! result UW point
+REAL, DIMENSION(:,:,:),  INTENT(OUT) :: PGX_W_UW_DEVICE ! result UW point
 !
 !*       0.2   declaration of local variables
 !
-REAL, DIMENSION(:,:,:), allocatable ::  ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE, ZTMP5_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous ::  ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE, ZTMP5_DEVICE
+INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE,IZTMP4_DEVICE,IZTMP5_DEVICE
 !
+INTEGER  :: JIU,JJU,JKU
 !----------------------------------------------------------------------------
 
 !$acc data present( PA, PDXX, PDZZ, PDZX, PGX_W_UW_DEVICE )
 
-allocate( ztmp1_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
-allocate( ztmp2_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
-allocate( ztmp3_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
-allocate( ztmp4_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
-allocate( ztmp5_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
+JIU =  size(pa, 1 )
+JJU =  size(pa, 2 )
+JKU =  size(pa, 3 )
 
-!$acc data create( ztmp1_device, ztmp2_device, ztmp3_device, ztmp4_device, ztmp5_device )
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU )
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU )
+iztmp3_device = MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU,JKU )
+iztmp4_device = MNH_ALLOCATE_ZT3D( ztmp4_device,JIU,JJU,JKU )
+iztmp5_device = MNH_ALLOCATE_ZT3D( ztmp5_device,JIU,JJU,JKU )
+
+!$acc data present( ztmp1_device, ztmp2_device, ztmp3_device, ztmp4_device, ztmp5_device )
 
 !
 !*       1.    DEFINITION of GX_W_UW_DEVICE
@@ -383,6 +398,8 @@ END IF
 
 !$acc end data
 
+CALL MNH_REL_ZT3D( iztmp1_device, iztmp2_device, iztmp3_device, iztmp4_device, iztmp5_device )
+
 !$acc end data
 
 !----------------------------------------------------------------------------
@@ -487,6 +504,7 @@ END FUNCTION GY_W_VW
 !
 USE MODI_SHUMAN_DEVICE
 USE MODD_CONF
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D
 !
 IMPLICIT NONE
 !
@@ -500,23 +518,30 @@ REAL, DIMENSION(:,:,:), INTENT(IN) :: PDYY     ! metric coefficient dyy
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ     ! metric coefficient dzz
 REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZY     ! metric coefficient dzy
 !
-REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)),  INTENT(OUT) :: PGY_W_VW_DEVICE ! result VW point
+REAL, DIMENSION(:,:,:),  INTENT(OUT) :: PGY_W_VW_DEVICE ! result VW point
 !
 !*       0.2   declaration of local variables
 !
-REAL, DIMENSION(:,:,:), allocatable ::  ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE, ZTMP5_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous ::  ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE, ZTMP5_DEVICE
+INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE,IZTMP4_DEVICE,IZTMP5_DEVICE
+!
+INTEGER  :: JIU,JJU,JKU
 !
 !----------------------------------------------------------------------------
 
 !$acc data present( PA, PDYY, PDZZ, PDZY, PGY_W_VW_DEVICE )
 
-allocate( ztmp1_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
-allocate( ztmp2_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
-allocate( ztmp3_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
-allocate( ztmp4_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
-allocate( ztmp5_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) )
+JIU =  size(pa, 1 )
+JJU =  size(pa, 2 )
+JKU =  size(pa, 3 )
 
-!$acc data create( ztmp1_device, ztmp2_device, ztmp3_device, ztmp4_device, ztmp5_device )
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU )
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU )
+iztmp3_device = MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU,JKU )
+iztmp4_device = MNH_ALLOCATE_ZT3D( ztmp4_device,JIU,JJU,JKU )
+iztmp5_device = MNH_ALLOCATE_ZT3D( ztmp5_device,JIU,JJU,JKU )
+
+!$acc data present( ztmp1_device, ztmp2_device, ztmp3_device, ztmp4_device, ztmp5_device )
 
 !
 !*       1.    DEFINITION of GY_W_VW_DEVICE
@@ -547,9 +572,12 @@ END IF
 
 !$acc end data
 
+CALL MNH_REL_ZT3D( iztmp1_device, iztmp2_device, iztmp3_device, iztmp4_device, iztmp5_device )
+
 !$acc end data
 
 !----------------------------------------------------------------------------
 !
 END SUBROUTINE GY_W_VW_DEVICE
 #endif
+
diff --git a/src/MNH/gravity_impl.f90 b/src/MNH/gravity_impl.f90
index 600520cf575b0d5009a6c73815914a30dc6bfc1e..3b6366dda85cf55c331ffd63875f16d1270784e2 100644
--- a/src/MNH/gravity_impl.f90
+++ b/src/MNH/gravity_impl.f90
@@ -127,6 +127,9 @@ REAL, DIMENSION(:,:,:,:), allocatable :: ZR
 !
 INTEGER :: JR
 !
+INTEGER  :: JI,JJ,JK
+INTEGER  :: JIU,JJU,JKU
+!
 !-------------------------------------------------------------------------------
 
 !$acc data present( PTHT, PRHODJ, PRT, PTHVREF, PRWS, PRTHS, PRRS, PRTHS_CLD, PRRS_CLD )
@@ -145,6 +148,10 @@ IF (MPPDB_INITIALIZED) THEN
   CALL MPPDB_CHECK(PRWS,     "GRAVITY_IMPL beg:PRWS")
 END IF
 
+JIU =  size(ptht, 1 )
+JJU =  size(ptht, 2 )
+JKU =  size(ptht, 3 )
+
 allocate( zrws_grav( size( ptht, 1 ), size( ptht, 2 ), size( ptht, 3 ) ) )
 allocate( zth      ( size( ptht, 1 ), size( ptht, 2 ), size( ptht, 3 ) ) )
 allocate( zr       ( size( prt,  1 ), size( prt,  2 ), size( prt,  3 ), size( prt, 4 ) ) )
@@ -156,9 +163,10 @@ if ( lbudget_w ) call Budget_store_init( tbudgets(NBUDGET_W), 'GRAV', prws(:, :,
 ! guess of Theta at future time-step
 !$acc kernels
 ZTH(:,:,:) = (PRTHS(:,:,:) + PRTHS_CLD(:,:,:)) / PRHODJ(:,:,:) * PTSTEP
-DO JR = 1, KRR
- ZR(:,:,:,JR) = (PRRS(:,:,:,JR) + PRRS_CLD(:,:,:,JR)) / PRHODJ(:,:,:) * PTSTEP
-END DO
+!
+DO CONCURRENT (  JI=1:JIU,JJ=1:JJU,JK=1:JKU , JR = 1:KRR )
+ ZR(JI,JJ,JK,JR) = (PRRS(JI,JJ,JK,JR) + PRRS_CLD(JI,JJ,JK,JR)) / PRHODJ(JI,JJ,JK) * PTSTEP
+END DO ! CONCURRENT
 !$acc end kernels
 !
 #ifndef MNH_OPENACC
diff --git a/src/MNH/ini_dynamics.f90 b/src/MNH/ini_dynamics.f90
index e4d00f5bb6aa29d04e9ce3cdb3cf10e0ae4187cb..13ea80bc10b5480c3e8fb1e0d16f77034c2288fa 100644
--- a/src/MNH/ini_dynamics.f90
+++ b/src/MNH/ini_dynamics.f90
@@ -296,6 +296,13 @@ USE MODI_ZDIFFUSETUP
 !
 USE MODE_ll
 USE MODE_TYPE_ZDIFFU
+#ifdef MNH_BITREP
+USE MODI_BITREP
+#define SIN BR_SIN
+#define COS BR_COS
+#endif
+!
+USE MODE_MPPDB
 !
 IMPLICIT NONE
 !
@@ -474,6 +481,11 @@ IF (.NOT.LCARTESIAN) THEN
                  / COS(PLAT(:,:)*ZCDR)
   PCURVY (:,:)   = SIN(ZGAMMA(:,:)) * (SIN(PLAT(:,:)*ZCDR) -XRPK)         &
                  / COS(PLAT(:,:)*ZCDR)
+  !
+  CALL MPPDB_CHECK2D(PCORIOX,"ini_dynamics:PCORIOX",PRECISION)
+  CALL MPPDB_CHECK2D(PCORIOY,"ini_dynamics:PCORIOY",PRECISION)
+  CALL MPPDB_CHECK2D(PCORIOZ,"ini_dynamics:PCORIOZ",PRECISION)
+  !
 ELSE
   ZMBETA = - (XBETA*ZCDR)
   PCORIOX(:,:) = - 2. * XOMEGA * COS(XLAT0*ZCDR) * SIN(ZMBETA)
diff --git a/src/MNH/ini_modeln.f90 b/src/MNH/ini_modeln.f90
index 48b3a7348e239e3db4e139c6687184d781a7365c..3103dd95135169a32c2cd4cf34401ca1020cdd11 100644
--- a/src/MNH/ini_modeln.f90
+++ b/src/MNH/ini_modeln.f90
@@ -855,6 +855,7 @@ ALLOCATE(XRUS_PRES(IIU,IJU,IKU)); XRUS_PRES = 0.0
 ALLOCATE(XRVS_PRES(IIU,IJU,IKU)); XRVS_PRES = 0.0
 ALLOCATE(XRWS_PRES(IIU,IJU,IKU)); XRWS_PRES = 0.0
 ALLOCATE(XRTHS(IIU,IJU,IKU))    ; XRTHS = 0.0
+!$acc enter data copyin(XRTHS)
 ALLOCATE(XRTHS_CLD(IIU,IJU,IKU)); XRTHS_CLD = 0.0
 
 IF ( LIBM ) THEN
@@ -1017,6 +1018,7 @@ ALLOCATE(XDYY(IIU,IJU,IKU))
 ALLOCATE(XDZX(IIU,IJU,IKU))
 ALLOCATE(XDZY(IIU,IJU,IKU))
 ALLOCATE(XDZZ(IIU,IJU,IKU))
+!$acc enter data create(XDXX,XDYY,XDZZ,XDZX,XDZY)
 !
 !*       3.3   Modules MODD_REF and  MODD_REF_n
 !
@@ -1037,6 +1039,7 @@ ALLOCATE(XRHODREF(IIU,IJU,IKU))
 ALLOCATE(XTHVREF(IIU,IJU,IKU))
 ALLOCATE(XEXNREF(IIU,IJU,IKU))
 ALLOCATE(XRHODJ(IIU,IJU,IKU))
+!$acc enter data create(XRHODJ)
 IF (CEQNSYS=='DUR' .AND. LUSERV) THEN
   ALLOCATE(XRVREF(IIU,IJU,IKU))
 ELSE
diff --git a/src/MNH/ini_radiations.f90 b/src/MNH/ini_radiations.f90
index 883179c8b2dd82f38644f08aec0f048b9684bb41..9317321fa3b9c0a31bdfbffc3c11b7241a5dc01e 100644
--- a/src/MNH/ini_radiations.f90
+++ b/src/MNH/ini_radiations.f90
@@ -130,6 +130,11 @@ USE MODE_IO_FIELD_READ, only: IO_Field_read
 USE MODE_ll
 !
 USE MODI_SHUMAN
+#ifdef MNH_BITREP
+USE MODI_BITREP
+#define ATAN BR_ATAN
+#define ATAN2 BR_ATAN2
+#endif
 !
 IMPLICIT NONE
 !
diff --git a/src/MNH/ini_rain_ice.f90 b/src/MNH/ini_rain_ice.f90
index 62cabad5b587f48a6cd6d443c088c8c7cea8c2ca..d8200edbe6da802faa57c592f620033f47ce36fb 100644
--- a/src/MNH/ini_rain_ice.f90
+++ b/src/MNH/ini_rain_ice.f90
@@ -102,6 +102,8 @@ END MODULE MODI_INI_RAIN_ICE
 !!      S. Riette 2016-11: new ICE3/ICE4 options
 !!      P. Wautelet 22/01/2019 bug correction: incorrect write
 !  P. Wautelet 26/04/2019: replace non-standard FLOAT function by REAL function
+!       J. Escobar 12/08/2020: Openacc PB, data partially present => add enter data on XGAMINC* , XKER_SDRYG
+!       J. Escobar 13/08/2020: Openacc PB , missing enter/update data rain_ice_fast_rs/g         
 !
 !-------------------------------------------------------------------------------
 !
@@ -673,9 +675,18 @@ XGAMINC_BOUND_MIN = 1.0E-1 ! Minimal value of (Lbda * D_cs^lim)**alpha
 XGAMINC_BOUND_MAX = 1.0E7  ! Maximal value of (Lbda * D_cs^lim)**alpha
 ZRATE = EXP(LOG(XGAMINC_BOUND_MAX/XGAMINC_BOUND_MIN)/REAL(NGAMINC-1))
 !
-IF( .NOT.ALLOCATED(XGAMINC_RIM1) ) ALLOCATE( XGAMINC_RIM1(NGAMINC) )
-IF( .NOT.ALLOCATED(XGAMINC_RIM2) ) ALLOCATE( XGAMINC_RIM2(NGAMINC) )
-IF( .NOT.ALLOCATED(XGAMINC_RIM4) ) ALLOCATE( XGAMINC_RIM4(NGAMINC) )
+IF( .NOT.ALLOCATED(XGAMINC_RIM1) ) THEN
+   ALLOCATE( XGAMINC_RIM1(NGAMINC) )
+   !$acc enter data create (XGAMINC_RIM1)
+END IF
+IF( .NOT.ALLOCATED(XGAMINC_RIM2) ) THEN
+   ALLOCATE( XGAMINC_RIM2(NGAMINC) )
+   !$acc enter data create (XGAMINC_RIM2)
+END IF
+IF( .NOT.ALLOCATED(XGAMINC_RIM4) ) THEN
+   ALLOCATE( XGAMINC_RIM4(NGAMINC) )
+   !$acc enter data create (XGAMINC_RIM4)
+END IF
 !
 DO J1=1,NGAMINC
   ZBOUND = XGAMINC_BOUND_MIN*ZRATE**(J1-1)
@@ -684,6 +695,8 @@ DO J1=1,NGAMINC
   XGAMINC_RIM4(J1) = GAMMA_INC(XNUS+XBG/XALPHAS      ,ZBOUND)
 END DO
 !
+!$acc update device (XGAMINC_RIM1,XGAMINC_RIM2,XGAMINC_RIM4)
+!
 XRIMINTP1 = XALPHAS / LOG(ZRATE)
 XRIMINTP2 = 1.0 + XRIMINTP1*LOG( XDCSLIM/(XGAMINC_BOUND_MIN)**(1.0/XALPHAS) )
 !
@@ -725,14 +738,24 @@ IND      = 50    ! Interval number, collection efficiency and infinite diameter
 ZESR     = 1.0   ! factor used to integrate the dimensional distributions when
 ZFDINFTY = 20.0  ! computing the kernels XKER_RACCSS, XKER_RACCS and XKER_SACCRG
 !
-IF( .NOT.ALLOCATED(XKER_RACCSS) ) ALLOCATE( XKER_RACCSS(NACCLBDAS,NACCLBDAR) )
-IF( .NOT.ALLOCATED(XKER_RACCS ) ) ALLOCATE( XKER_RACCS (NACCLBDAS,NACCLBDAR) )
-IF( .NOT.ALLOCATED(XKER_SACCRG) ) ALLOCATE( XKER_SACCRG(NACCLBDAR,NACCLBDAS) )
+IF( .NOT.ALLOCATED(XKER_RACCSS) ) THEN
+   ALLOCATE( XKER_RACCSS(NACCLBDAS,NACCLBDAR) )
+   !$acc enter data create(XKER_RACCSS)
+END IF
+IF( .NOT.ALLOCATED(XKER_RACCS ) ) THEN
+   ALLOCATE( XKER_RACCS (NACCLBDAS,NACCLBDAR) )
+   !$acc enter data create(XKER_RACCS)
+END IF
+IF( .NOT.ALLOCATED(XKER_SACCRG) ) THEN
+   ALLOCATE( XKER_SACCRG(NACCLBDAR,NACCLBDAS) )
+   !$acc enter data create(XKER_SACCRG)
+END IF
 !
 CALL READ_XKER_RACCS (KACCLBDAS,KACCLBDAR,KND,                                &
                       PALPHAS,PNUS,PALPHAR,PNUR,PESR,PBS,PBR,PCS,PDS,PCR,PDR, &
                       PACCLBDAS_MAX,PACCLBDAR_MAX,PACCLBDAS_MIN,PACCLBDAR_MIN,&
                       PFDINFTY                                                )
+!
 IF( (KACCLBDAS/=NACCLBDAS) .OR. (KACCLBDAR/=NACCLBDAR) .OR. (KND/=IND) .OR. &
     (PALPHAS/=XALPHAS) .OR. (PNUS/=XNUS)                               .OR. &
     (PALPHAR/=XALPHAR) .OR. (PNUR/=XNUR)                               .OR. &
@@ -753,6 +776,8 @@ IF( (KACCLBDAS/=NACCLBDAS) .OR. (KACCLBDAR/=NACCLBDAR) .OR. (KND/=IND) .OR. &
                  ZESR, XBS, XCS, XDS, XCR, XDR,                              &
                  XACCLBDAS_MAX, XACCLBDAR_MAX, XACCLBDAS_MIN, XACCLBDAR_MIN, &
                  ZFDINFTY, XKER_SACCRG,  XAG, XBS, XAS                       )
+  !$acc update device(XKER_RACCSS,XKER_RACCS,XKER_SACCRG)
+  !
   WRITE(UNIT=KLUOUT,FMT='("*****************************************")')
   WRITE(UNIT=KLUOUT,FMT='("**** UPDATE NEW SET OF RACSS KERNELS ****")')
   WRITE(UNIT=KLUOUT,FMT='("**** UPDATE NEW SET OF RACS  KERNELS ****")')
@@ -814,6 +839,9 @@ IF( (KACCLBDAS/=NACCLBDAS) .OR. (KACCLBDAR/=NACCLBDAR) .OR. (KND/=IND) .OR. &
                        PALPHAS,PNUS,PALPHAR,PNUR,PESR,PBS,PBR,PCS,PDS,PCR,PDR, &
                        PACCLBDAS_MAX,PACCLBDAR_MAX,PACCLBDAS_MIN,PACCLBDAR_MIN,&
                        PFDINFTY,XKER_RACCSS,XKER_RACCS,XKER_SACCRG             )
+  !
+  !$acc update device(XKER_RACCSS,XKER_RACCS,XKER_SACCRG)
+  !
   WRITE(UNIT=KLUOUT,FMT='(" Read XKER_RACCSS")')
   WRITE(UNIT=KLUOUT,FMT='(" Read XKER_RACCS ")')
   WRITE(UNIT=KLUOUT,FMT='(" Read XKER_SACCRG")')
@@ -935,12 +963,17 @@ IND      = 50    ! Interval number, collection efficiency and infinite diameter
 ZEGS     = 1.0   ! factor used to integrate the dimensional distributions when
 ZFDINFTY = 20.0  ! computing the kernels XKER_SDRYG
 !
-IF( .NOT.ALLOCATED(XKER_SDRYG) ) ALLOCATE( XKER_SDRYG(NDRYLBDAG,NDRYLBDAS) )
+IF( .NOT.ALLOCATED(XKER_SDRYG) ) THEN
+   ALLOCATE( XKER_SDRYG(NDRYLBDAG,NDRYLBDAS) )
+   !$acc enter data create(XKER_SDRYG)
+END IF
 !
 CALL READ_XKER_SDRYG (KDRYLBDAG,KDRYLBDAS,KND,                              &
                    PALPHAG,PNUG,PALPHAS,PNUS,PEGS,PBS,PCG,PDG,PCS,PDS,      &
                    PDRYLBDAG_MAX,PDRYLBDAS_MAX,PDRYLBDAG_MIN,PDRYLBDAS_MIN, &
                    PFDINFTY                                                 )
+!$acc update device(XKER_SDRYG)
+!
 IF( (KDRYLBDAG/=NDRYLBDAG) .OR. (KDRYLBDAS/=NDRYLBDAS) .OR. (KND/=IND) .OR. &
     (PALPHAG/=XALPHAG) .OR. (PNUG/=XNUG)                               .OR. &
     (PALPHAS/=XALPHAS) .OR. (PNUS/=XNUS)                               .OR. &
@@ -953,6 +986,8 @@ IF( (KDRYLBDAG/=NDRYLBDAG) .OR. (KDRYLBDAS/=NDRYLBDAS) .OR. (KND/=IND) .OR. &
                 ZEGS, XBS, XCG, XDG, XCS, XDS,                              &
                 XDRYLBDAG_MAX, XDRYLBDAS_MAX, XDRYLBDAG_MIN, XDRYLBDAS_MIN, &
                 ZFDINFTY, XKER_SDRYG                                        )
+  !$acc update device(XKER_SDRYG)
+  !
   WRITE(UNIT=KLUOUT,FMT='("*****************************************")')
   WRITE(UNIT=KLUOUT,FMT='("**** UPDATE NEW SET OF SDRYG KERNELS ****")')
   WRITE(UNIT=KLUOUT,FMT='("*****************************************")')
@@ -993,6 +1028,8 @@ IF( (KDRYLBDAG/=NDRYLBDAG) .OR. (KDRYLBDAS/=NDRYLBDAS) .OR. (KND/=IND) .OR. &
                      PALPHAG,PNUG,PALPHAS,PNUS,PEGS,PBS,PCG,PDG,PCS,PDS,      &
                      PDRYLBDAG_MAX,PDRYLBDAS_MAX,PDRYLBDAG_MIN,PDRYLBDAS_MIN, &
                      PFDINFTY,XKER_SDRYG                                      )
+  !$acc update device(XKER_SDRYG)
+  !
   WRITE(UNIT=KLUOUT,FMT='(" Read XKER_SDRYG")')
 END IF
 !
@@ -1001,7 +1038,10 @@ IND      = 50    ! Number of interval used to integrate the dimensional
 ZEGR     = 1.0   ! distributions when computing the kernel XKER_RDRYG
 ZFDINFTY = 20.0
 !
-IF( .NOT.ALLOCATED(XKER_RDRYG) ) ALLOCATE( XKER_RDRYG(NDRYLBDAG,NDRYLBDAR) )
+IF( .NOT.ALLOCATED(XKER_RDRYG) ) THEN
+   ALLOCATE( XKER_RDRYG(NDRYLBDAG,NDRYLBDAR) )
+   !$acc enter data create(XKER_RDRYG)
+END IF
 !
 CALL READ_XKER_RDRYG (KDRYLBDAG,KDRYLBDAR,KND,                              &
                    PALPHAG,PNUG,PALPHAR,PNUR,PEGR,PBR,PCG,PDG,PCR,PDR,      &
@@ -1019,6 +1059,7 @@ IF( (KDRYLBDAG/=NDRYLBDAG) .OR. (KDRYLBDAR/=NDRYLBDAR) .OR. (KND/=IND) .OR. &
                 ZEGR, XBR, XCG, XDG, XCR, XDR,                              &
                 XDRYLBDAG_MAX, XDRYLBDAR_MAX, XDRYLBDAG_MIN, XDRYLBDAR_MIN, &
                 ZFDINFTY, XKER_RDRYG                                        )
+  !$acc update device(XKER_RDRYG)
   WRITE(UNIT=KLUOUT,FMT='("*****************************************")')
   WRITE(UNIT=KLUOUT,FMT='("**** UPDATE NEW SET OF RDRYG KERNELS ****")')
   WRITE(UNIT=KLUOUT,FMT='("*****************************************")')
@@ -1059,6 +1100,7 @@ IF( (KDRYLBDAG/=NDRYLBDAG) .OR. (KDRYLBDAR/=NDRYLBDAR) .OR. (KND/=IND) .OR. &
                      PALPHAG,PNUG,PALPHAR,PNUR,PEGR,PBR,PCG,PDG,PCR,PDR,      &
                      PDRYLBDAG_MAX,PDRYLBDAR_MAX,PDRYLBDAG_MIN,PDRYLBDAR_MIN, &
                      PFDINFTY,XKER_RDRYG                                      )
+  !$acc update device(XKER_RDRYG)
   WRITE(UNIT=KLUOUT,FMT='(" Read XKER_RDRYG")')
 END IF
 !
diff --git a/src/MNH/modd_metricsn.f90 b/src/MNH/modd_metricsn.f90
index 8a9b5711169cda8e71f89cba6792054d95e236d4..9777112cf10a7ae607ed55bfa8b9912cd76d64c0 100644
--- a/src/MNH/modd_metricsn.f90
+++ b/src/MNH/modd_metricsn.f90
@@ -48,7 +48,7 @@ TYPE(METRICS_t), DIMENSION(JPMODELMAX), TARGET, SAVE :: METRICS_MODEL
 
 REAL, DIMENSION(:,:,:), POINTER, contiguous :: XDXX=>NULL(),XDZX=>NULL(), &
                                   XDYY=>NULL(),XDZY=>NULL(),XDZZ=>NULL()
-!$acc declare create(XDXX,XDYY,XDZZ,XDZX,XDZY)
+! acc declare create(XDXX,XDYY,XDZZ,XDZX,XDZY)
 
 CONTAINS
 
diff --git a/src/MNH/modd_refn.f90 b/src/MNH/modd_refn.f90
index 45981ba791acd92414962b2fd040e4b6eeb14434..9ebcc958ad3398ae6f78177c43eba57f265e2851 100644
--- a/src/MNH/modd_refn.f90
+++ b/src/MNH/modd_refn.f90
@@ -69,7 +69,7 @@ REAL, DIMENSION(:,:,:), POINTER, contiguous :: XTHVREF=>NULL()
 REAL, DIMENSION(:,:,:), POINTER :: XRVREF=>NULL()
 REAL, DIMENSION(:,:,:), POINTER, contiguous :: XEXNREF=>NULL()
 REAL, DIMENSION(:,:,:), POINTER, contiguous :: XRHODJ=>NULL()
-!$acc declare create (XRHODJ)
+! acc declare create (XRHODJ)
 REAL, POINTER :: XREFMASS=>NULL()
 REAL, POINTER :: XMASS_O_PHI0=>NULL()
 REAL, POINTER :: XLINMASS=>NULL()
diff --git a/src/MNH/mode_mnh_zwork.f90 b/src/MNH/mode_mnh_zwork.f90
index e94ced87e6e228072921babfb43980533eece795..95fc395d786492dc2b7a6cac48345b07d05ef94c 100644
--- a/src/MNH/mode_mnh_zwork.f90
+++ b/src/MNH/mode_mnh_zwork.f90
@@ -19,7 +19,7 @@ MODULE MODE_MNH_ZWORK
   !
   INTEGER,SAVE                    :: IJS,IJN, IIW,IIA
   !
-  INTEGER, SAVE                   :: IIU,IJU,IKU
+  INTEGER, SAVE                   :: IIU,IJU,IKU,IIJKU
   LOGICAL, SAVE                   :: GWEST , GEAST
   LOGICAL, SAVE                   :: GSOUTH , GNORTH
 
@@ -30,18 +30,48 @@ MODULE MODE_MNH_ZWORK
 
   REAL, SAVE, ALLOCATABLE , DIMENSION(:,:,:) :: ZUNIT3D
 
-  INTEGER, parameter                        :: JPMAX_T3D = 40
+  INTEGER, parameter                        :: JPMAX_T3D = 100
   INTEGER , ALLOCATABLE, DIMENSION (:)      :: NT3D_POOL
-  INTEGER                                   :: NT3D_TOP , NT3D_TOP_MAX = 0  
+  INTEGER                                   :: NT3D_TOP , NT3D_TOP_MAX = 0
+  INTEGER                                   :: NT3D_TOP_CURRENT(JPMAX_T3D+1) ,  NT3D_TOP_CURRENT_INDEX = 0
   !REAL    , ALLOCATABLE, DIMENSION(:,:,:,:) , TARGET :: ZT3D_A1,ZT3D_A2,ZT3D_A3,ZT3D_A4
   !REAL    , POINTER    , DIMENSION(:,:,:,:)          :: ZT3D
-  REAL,SAVE    , ALLOCATABLE, DIMENSION(:,:,:,:)          :: ZT3D
+  REAL,SAVE    , ALLOCATABLE, TARGET , DIMENSION(:,:,:,:)          :: ZT3D
+
+  REAL,SAVE    , ALLOCATABLE, TARGET , DIMENSION(:)                :: ZT1D_OSIZE
+  REAL,SAVE    , ALLOCATABLE, TARGET , DIMENSION(:,:)              :: ZT2D_OSIZE
+  REAL,SAVE    , ALLOCATABLE, TARGET , DIMENSION(:,:,:)            :: ZT3D_OSIZE
+  REAL,SAVE    , ALLOCATABLE, TARGET , DIMENSION(:,:,:,:)          :: ZT4D_OSIZE
+  
+
   TYPE TMODEL
       REAL    , POINTER, DIMENSION(:,:,:,:) :: X
   END TYPE TMODEL
 
   TYPE(TMODEL) , DIMENSION(10) :: MODEL
 
+  INTEGER, parameter                        :: JPMAX_T3D_G = 12
+  INTEGER , ALLOCATABLE, DIMENSION (:)      :: NT3D_POOL_G
+  INTEGER                                   :: NT3D_TOP_G , NT3D_TOP_G_MAX = 0  
+  LOGICAL,SAVE    , ALLOCATABLE, TARGET , DIMENSION(:,:,:,:)       :: GT3D
+  LOGICAL,SAVE    , ALLOCATABLE, TARGET , DIMENSION(:,:)           :: GT2D_OSIZE
+
+  INTEGER, parameter                        :: JPMAX_T3D_I = 4
+  INTEGER , ALLOCATABLE, DIMENSION (:)      :: NT3D_POOL_I
+  INTEGER                                   :: NT3D_TOP_I , NT3D_TOP_I_MAX = 0  
+  INTEGER,SAVE    , ALLOCATABLE, TARGET , DIMENSION(:,:,:,:)       :: IT3D
+
+  INTEGER, parameter                        :: JPMAX_T1D_R = 60
+  INTEGER , ALLOCATABLE, DIMENSION (:)      :: NT1D_POOL_R
+  INTEGER                                   :: NT1D_TOP_R , NT1D_TOP_R_MAX = 0  
+  REAL,SAVE    , ALLOCATABLE, TARGET , DIMENSION(:,:)       :: ZT1D 
+  
+  INTEGER, parameter                        :: JPMAX_T1D_I = 30
+  INTEGER , ALLOCATABLE, DIMENSION (:)      :: NT1D_POOL_I
+  INTEGER                                   :: NT1D_TOP_I , NT1D_TOP_I_MAX = 0  
+  INTEGER,SAVE    , ALLOCATABLE, TARGET , DIMENSION(:,:)       :: IT1D
+  INTEGER,SAVE    , ALLOCATABLE, TARGET , DIMENSION(:)         :: IT1D_OSIZE
+  
 CONTAINS
 
   SUBROUTINE MNH_ALLOC_ZWORK(IMODEL)
@@ -64,6 +94,7 @@ CONTAINS
        !
        CALL GET_DIM_EXT_ll('B',IIU,IJU)     
        IKU=NKMAX + 2* JPVEXT
+       IIJKU = IIU*IJU*IKU
        !
        ! Computation bound
        !
@@ -93,18 +124,76 @@ CONTAINS
        ALLOCATE (ZUNIT3D(IIU,IJU,IKU))
        !$acc enter data create(ZUNIT3D)
 
+!----- Real pool
+       
        !ALLOCATE (ZT3D_A1(IIU,IJU,IKU,JPMAX_T3D))
        !MODEL(1)%X => ZT3D_A1
        !ZT3D => MODEL(1)%X
        ALLOCATE (ZT3D(IIU,IJU,IKU,JPMAX_T3D))
        !$acc enter data create(ZT3D)
 
+       ALLOCATE (ZT1D_OSIZE(0))
+       ALLOCATE (ZT2D_OSIZE(IIU,0))
+       ALLOCATE (ZT3D_OSIZE(IIU,IJU,0))
+       ALLOCATE (ZT4D_OSIZE(IIU,IJU,IKU,0))
+       !$acc enter data create(ZT1D_OSIZE,ZT2D_OSIZE,ZT3D_OSIZE,ZT4D_OSIZE)      
+
        ALLOCATE (NT3D_POOL(JPMAX_T3D))
        NT3D_TOP = 0
        DO JI = 1, JPMAX_T3D
           NT3D_POOL(JI) = JI
        END DO
 
+!------ Logical pool
+       
+       ALLOCATE (GT3D(IIU,IJU,IKU,JPMAX_T3D_G))
+       !$acc enter data create(GT3D)
+
+       ALLOCATE (GT2D_OSIZE(IIU,0))
+       !$acc enter data create(GT2D_OSIZE)
+
+       ALLOCATE (NT3D_POOL_G(JPMAX_T3D_G))
+       NT3D_TOP_G = 0
+       DO JI = 1, JPMAX_T3D_G
+          NT3D_POOL_G(JI) = JI
+       END DO
+
+!------ Integer pool
+       
+       ALLOCATE (IT3D(IIU,IJU,IKU,JPMAX_T3D_I))
+       !$acc enter data create(IT3D)
+
+       ALLOCATE (NT3D_POOL_I(JPMAX_T3D_I))
+       NT3D_TOP_I = 0
+       DO JI = 1, JPMAX_T3D_I
+          NT3D_POOL_I(JI) = JI
+       END DO
+
+!------ Real 1D pool 
+       
+       ALLOCATE (ZT1D(IIU*IJU*IKU,JPMAX_T1D_R))
+       !$acc enter data create(ZT1D)
+
+       ALLOCATE (NT1D_POOL_R(JPMAX_T1D_R))
+       NT1D_TOP_R = 0
+       DO JI = 1, JPMAX_T1D_R
+          NT1D_POOL_R(JI) = JI
+       END DO
+
+!------ Integer 1D pool
+       
+       ALLOCATE (IT1D(IIU*IJU*IKU,JPMAX_T1D_I))
+       ALLOCATE (IT1D_OSIZE(0))
+       !$acc enter data create(IT1D,IT1D_OSIZE)
+
+       ALLOCATE (NT1D_POOL_I(JPMAX_T1D_I))
+       NT1D_TOP_I = 0
+       DO JI = 1, JPMAX_T1D_I
+          NT1D_POOL_I(JI) = JI
+       END DO       
+       
+!------ Default values
+       
        !$acc kernels 
 
        ZPSRC_HALO2_WEST = XUNDEF
@@ -113,12 +202,18 @@ CONTAINS
        ZUNIT3D = 1.0
 
        ZT3D  =  XUNDEF
+       ZT1D  =  XUNDEF
+
+       IT3D  = 0.0
+       IT1D  = 0.0
+
+       GT3D  = .FALSE.
 
        !$acc end kernels
 
        !$acc update host (ZPSRC_HALO2_WEST,ZPSRC_HALO2_SOUTH)
        !$acc update host (ZUNIT3D)
-       !$acc update host (ZT3D)
+       !$acc update host (ZT3D,ZT1D)
 
     END IF
 
@@ -131,17 +226,15 @@ CONTAINS
     INTEGER :: KTEMP
 
     IF (NT3D_TOP == JPMAX_T3D ) THEN
+      WRITE( *, '( " MNH_GET_ZT3D_N0: NT3D_TOP too big (increaze JPMAX_T3D) , NT3D_TOP=",I4 )' ) NT3D_TOP
       call Print_msg( NVERB_FATAL, 'GEN', 'MNH_GET_ZT3D_N0', 'NT3D_TOP too big (increaze JPMAX_T3D)' )
     ELSE
        NT3D_TOP = NT3D_TOP + 1
        KTEMP = NT3D_POOL(NT3D_TOP)
-       IF (  NT3D_POOL(NT3D_TOP) == -1 ) THEN
-         call Print_msg( NVERB_FATAL, 'GEN', 'MNH_GET_ZT3D_N0', 'slice already reserved' )
-       END IF
-       NT3D_POOL(NT3D_TOP) = -1
+       NT3D_POOL(NT3D_TOP) = - KTEMP
        IF (  NT3D_TOP > NT3D_TOP_MAX ) THEN
           NT3D_TOP_MAX = NT3D_TOP
-          WRITE( *, '( " MNH_GET_ZT3D: NT3D_TOP_MAX=",I4," KTEMP=",I4 )' ) NT3D_TOP_MAX,KTEMP
+          !WRITE( *, '( " MNH_GET_ZT3D: NT3D_TOP_MAX=",I4," KTEMP=",I4 )' ) NT3D_TOP_MAX,KTEMP
        END IF
     ENDIF
     !WRITE( *, '( "MNH_GET_ZT3D: reserving ZT3D (",I4,")" )' ) KTEMP
@@ -176,7 +269,6 @@ CONTAINS
     IF (PRESENT(KTEMP17)) CALL MNH_GET_ZT3D_N0(KTEMP17)
     IF (PRESENT(KTEMP18)) CALL MNH_GET_ZT3D_N0(KTEMP18)
 
-
   END SUBROUTINE MNH_GET_ZT3D
 
   SUBROUTINE MNH_GET_ZT4D(KSIZE,KBEG,KEND)
@@ -189,16 +281,17 @@ CONTAINS
     INTEGER :: JI
 
     IF (NT3D_TOP + KSIZE > JPMAX_T3D ) THEN
-      call Print_msg( NVERB_FATAL, 'GEN', 'MNH_GET_ZT4D', 'NT3D_TOP too big (increaze JPMAX_T3D)' )
+      WRITE( *, '( " MNH_GET_ZT4D: NT3D_TOP+KSIZE too big (increaze JPMAX_T3D) , NT3D_TOP=",I4 )' ) NT3D_TOP+KSIZE
+      call Print_msg( NVERB_FATAL, 'GEN', 'MNH_GET_ZT4D', 'NT3D_TOP+ KSIZE too big (increaze JPMAX_T3D)' )
     ELSE
        KBEG = NT3D_TOP + 1
        KEND = NT3D_TOP + KSIZE
        NT3D_TOP = NT3D_TOP + KSIZE
        DO JI = KBEG, KEND
-         IF (NT3D_POOL(JI) == -1) THEN
+         IF (NT3D_POOL(JI) <= 0 ) THEN           
            call Print_msg( NVERB_FATAL, 'GEN', 'MNH_GET_ZT4D', 'trying to use area already reserved' )
          END IF
-         NT3D_POOL(JI) = -1
+         NT3D_POOL(JI) = -JI
        END DO
        IF ( NT3D_TOP > NT3D_TOP_MAX ) THEN
           NT3D_TOP_MAX = NT3D_TOP
@@ -215,50 +308,59 @@ CONTAINS
 
     INTEGER :: KTEMP
 
+    IF ( KTEMP .EQ. 0 ) THEN
+       ! Special case Zero size array do nothing
+       RETURN
+    ELSE
+    
     IF ( ( NT3D_TOP > JPMAX_T3D ) .OR. ( NT3D_TOP < 1 ) ) THEN
       call Print_msg( NVERB_FATAL, 'GEN', 'MNH_REL_ZT3D_N0', 'invalid value for NT3D_TOP' )
     ELSE
       NT3D_POOL(KTEMP) = KTEMP
       IF (KTEMP == NT3D_TOP) THEN
         NT3D_TOP = NT3D_TOP - 1
-        DO WHILE (NT3D_TOP > 0 )
-          if ( NT3D_POOL(NT3D_TOP) == -1 ) exit
-          NT3D_TOP = NT3D_TOP - 1
-        END DO
+     ELSE
+        WRITE( *, '( "MNH_REL_ZT3D: releasing ZT3D (",2I8,")" )' ) KTEMP, NT3D_TOP
+        call Print_msg( NVERB_FATAL, 'GEN', 'MNH_REL_ZT3D_N0', 'invalid value for KTEMP <> NT3D_TOP' )
       END IF
     ENDIF
     !WRITE( *, '( "MNH_REL_ZT3D: releasing ZT3D (",I4,")" )' ) KTEMP
+    ENDIF
 
   END SUBROUTINE MNH_REL_ZT3D_N0
 
   SUBROUTINE MNH_REL_ZT3D(KTEMP1,KTEMP2,KTEMP3,KTEMP4,KTEMP5,KTEMP6,KTEMP7,KTEMP8,KTEMP9, &
-                          KTEMP10,KTEMP11,KTEMP12,KTEMP13,KTEMP14,KTEMP15,KTEMP16,KTEMP17,KTEMP18)
+                          KTEMP10,KTEMP11,KTEMP12,KTEMP13,KTEMP14,KTEMP15,KTEMP16,KTEMP17,KTEMP18, &
+                          KTEMP19,KTEMP20)
 
     IMPLICIT NONE
 
     INTEGER          :: KTEMP1
     INTEGER,OPTIONAL :: KTEMP2,KTEMP3,KTEMP4,KTEMP5,KTEMP6,KTEMP7,KTEMP8,KTEMP9
     INTEGER,OPTIONAL :: KTEMP10,KTEMP11,KTEMP12,KTEMP13,KTEMP14,KTEMP15,KTEMP16,KTEMP17,KTEMP18
+    INTEGER,OPTIONAL :: KTEMP19,KTEMP20
 
-                          CALL MNH_REL_ZT3D_N0(KTEMP1)
-    IF (PRESENT(KTEMP2))  CALL MNH_REL_ZT3D_N0(KTEMP2)
-    IF (PRESENT(KTEMP3))  CALL MNH_REL_ZT3D_N0(KTEMP3)
-    IF (PRESENT(KTEMP4))  CALL MNH_REL_ZT3D_N0(KTEMP4)
-    IF (PRESENT(KTEMP5))  CALL MNH_REL_ZT3D_N0(KTEMP5)
-    IF (PRESENT(KTEMP6))  CALL MNH_REL_ZT3D_N0(KTEMP6)
-    IF (PRESENT(KTEMP7))  CALL MNH_REL_ZT3D_N0(KTEMP7)
-    IF (PRESENT(KTEMP8))  CALL MNH_REL_ZT3D_N0(KTEMP8)
-    IF (PRESENT(KTEMP9))  CALL MNH_REL_ZT3D_N0(KTEMP9)
-    IF (PRESENT(KTEMP10)) CALL MNH_REL_ZT3D_N0(KTEMP10)
-    IF (PRESENT(KTEMP11)) CALL MNH_REL_ZT3D_N0(KTEMP11)
-    IF (PRESENT(KTEMP12)) CALL MNH_REL_ZT3D_N0(KTEMP12)
-    IF (PRESENT(KTEMP13)) CALL MNH_REL_ZT3D_N0(KTEMP13)
-    IF (PRESENT(KTEMP14)) CALL MNH_REL_ZT3D_N0(KTEMP14)
-    IF (PRESENT(KTEMP15)) CALL MNH_REL_ZT3D_N0(KTEMP15)
-    IF (PRESENT(KTEMP16)) CALL MNH_REL_ZT3D_N0(KTEMP16)
-    IF (PRESENT(KTEMP17)) CALL MNH_REL_ZT3D_N0(KTEMP17)
+    IF (PRESENT(KTEMP20)) CALL MNH_REL_ZT3D_N0(KTEMP20)
+    IF (PRESENT(KTEMP19)) CALL MNH_REL_ZT3D_N0(KTEMP19)
     IF (PRESENT(KTEMP18)) CALL MNH_REL_ZT3D_N0(KTEMP18)
-
+    IF (PRESENT(KTEMP17)) CALL MNH_REL_ZT3D_N0(KTEMP17)
+    IF (PRESENT(KTEMP16)) CALL MNH_REL_ZT3D_N0(KTEMP16)
+    IF (PRESENT(KTEMP15)) CALL MNH_REL_ZT3D_N0(KTEMP15)
+    IF (PRESENT(KTEMP14)) CALL MNH_REL_ZT3D_N0(KTEMP14)
+    IF (PRESENT(KTEMP13)) CALL MNH_REL_ZT3D_N0(KTEMP13)
+    IF (PRESENT(KTEMP12)) CALL MNH_REL_ZT3D_N0(KTEMP12)
+    IF (PRESENT(KTEMP11)) CALL MNH_REL_ZT3D_N0(KTEMP11)
+    IF (PRESENT(KTEMP10)) CALL MNH_REL_ZT3D_N0(KTEMP10)
+    IF (PRESENT(KTEMP9))  CALL MNH_REL_ZT3D_N0(KTEMP9)
+    IF (PRESENT(KTEMP8))  CALL MNH_REL_ZT3D_N0(KTEMP8)
+    IF (PRESENT(KTEMP7))  CALL MNH_REL_ZT3D_N0(KTEMP7)
+    IF (PRESENT(KTEMP6))  CALL MNH_REL_ZT3D_N0(KTEMP6)
+    IF (PRESENT(KTEMP5))  CALL MNH_REL_ZT3D_N0(KTEMP5)
+    IF (PRESENT(KTEMP4))  CALL MNH_REL_ZT3D_N0(KTEMP4)
+    IF (PRESENT(KTEMP3))  CALL MNH_REL_ZT3D_N0(KTEMP3)
+    IF (PRESENT(KTEMP2))  CALL MNH_REL_ZT3D_N0(KTEMP2)
+                          CALL MNH_REL_ZT3D_N0(KTEMP1)
+    
   END SUBROUTINE MNH_REL_ZT3D
 
   SUBROUTINE MNH_REL_ZT4D(KSIZE,KBEG)
@@ -271,8 +373,11 @@ CONTAINS
     character(len=16) :: ytxt1, ytxt2
     INTEGER :: JI
 
+    IF ( KSIZE .EQ. 0 ) THEN
+       ! special case of O zero 4D array => ZT4D_OSIZE
+       RETURN
+    END IF
     IF ( KBEG + KSIZE -1 /= NT3D_TOP ) THEN
-!PW TODO: implement holes management
       write( ytxt1, '( I4, "-", I4 )' ) kbeg, kbeg + ksize - 1
       write( ytxt2, '( I4 )' )          NT3D_TOP
       call Print_msg( NVERB_ERROR, 'GEN', 'MNH_REL_ZT4D', 'trying to free area (' // trim( ytxt1 ) // &
@@ -283,17 +388,584 @@ CONTAINS
     END IF
 
     DO JI = KBEG, KBEG+KSIZE-1
-      IF (NT3D_POOL(JI) /= -1) THEN
-      call Print_msg( NVERB_ERROR, 'GEN', 'MNH_REL_ZT4D', 'trying to free area not reserved' )
+       IF (NT3D_POOL(JI) /= - JI ) THEN        
+          call Print_msg( NVERB_ERROR, 'GEN', 'MNH_REL_ZT4D', 'trying to free area not reserved' )
+       ELSE
+          NT3D_POOL(JI) = JI
       END IF
-      NT3D_POOL(JI) = JI
     END DO
     NT3D_TOP = NT3D_TOP - KSIZE
     !WRITE( *, '( "MNH_REL_ZT4D: releasing ZT3D (",I4,I4,")" )' ) KBEG,KBEG+KSIZE-1
 
   END SUBROUTINE MNH_REL_ZT4D
 
+  FUNCTION MNH_ALLOCATE_ZT3D(PTAB,KI,KJ,KK) RESULT (KINDEX)
+    
+    REAL, POINTER, CONTIGUOUS , DIMENSION(:,:,:), INTENT(INOUT) :: PTAB
+    INTEGER , INTENT(IN)    :: KI,KJ,KK
+    INTEGER                 :: KINDEX
+
+    !local
+
+    IF ( (KI .EQ. IIU) .AND. (KJ .EQ. IJU) ) THEN
+       CALL MNH_GET_ZT3D_N0(KINDEX)
+       IF       (KK .LE. IKU)  THEN           
+          PTAB => ZT3D(:,:,1:KK,KINDEX)
+       ELSE IF (KK .EQ.0 )  THEN
+          PTAB => ZT3D_OSIZE
+       ELSE
+          call Print_msg( NVERB_ERROR, 'GEN', 'MNH_ALLOCATE_ZT3D', ' Size mismatsh ' )
+       END IF
+    ELSE
+       call Print_msg( NVERB_ERROR, 'GEN', 'MNH_ALLOCATE_ZT3D', ' Size mismatsh ' )
+    END IF
+       
+  END FUNCTION MNH_ALLOCATE_ZT3D
+
+    FUNCTION MNH_ALLOCATE_ZT4D(PTAB,KI,KJ,KK,KL) RESULT (KINDEX_BEG)
+    
+    REAL, POINTER, CONTIGUOUS , DIMENSION(:,:,:,:), INTENT(INOUT) :: PTAB
+    INTEGER , INTENT(IN)    :: KI,KJ,KK,KL
+    INTEGER                 :: KINDEX_BEG
+
+    !local
+
+    INTEGER                 :: KINDEX_END
+
+    IF ( (KI .EQ. IIU) .AND. (KJ .EQ. IJU) .AND. (KK .EQ. IKU) ) THEN
+       IF ( KL .GE. 1 ) THEN
+          CALL MNH_GET_ZT4D(KL,KINDEX_BEG,KINDEX_END)
+          PTAB => ZT3D(:,:,:,KINDEX_BEG:KINDEX_END)
+       ELSE
+          PTAB => ZT4D_OSIZE
+          KINDEX_BEG = 0
+       END IF
+    ELSE
+       call Print_msg( NVERB_ERROR, 'GEN', 'MNH_ALLOCATE_ZT4D', ' Size mismatsh ' )
+    END IF
+       
+  END FUNCTION MNH_ALLOCATE_ZT4D
+
+  FUNCTION MNH_ALLOCATE_ZT2D(PTAB,KI,KJ) RESULT (KINDEX)
+    
+    REAL, POINTER, CONTIGUOUS , DIMENSION(:,:), INTENT(INOUT) :: PTAB
+    INTEGER , INTENT(IN)    :: KI,KJ
+    INTEGER                 :: KINDEX
+
+    !local
+
+    IF (KI .EQ. IIU) THEN
+       CALL MNH_GET_ZT3D_N0(KINDEX)
+       IF (KJ .EQ. IJU) THEN 
+          PTAB => ZT3D(:,:,1,KINDEX)
+       ELSE IF (KJ .EQ. 0)  THEN
+          PTAB => ZT2D_OSIZE
+       ELSE
+          call Print_msg( NVERB_ERROR, 'GEN', 'MNH_ALLOCATE_ZT2D', ' Size mismatsh ' )
+       END IF
+    ELSE
+       call Print_msg( NVERB_ERROR, 'GEN', 'MNH_ALLOCATE_ZT2D', ' Size mismatsh ' )
+    END IF
+       
+  END FUNCTION MNH_ALLOCATE_ZT2D
+
+  FUNCTION MNH_ALLOCATE_ZT3DP(PTAB,KI,KJ,KKB,KKE) RESULT (KINDEX)
+    
+    REAL, POINTER, CONTIGUOUS , DIMENSION(:,:,:), INTENT(INOUT) :: PTAB
+    INTEGER , INTENT(IN)    :: KI,KJ,KKB,KKE
+    INTEGER                 :: KINDEX
+
+    !local
+
+    IF ( (KI .EQ. IIU) .AND. (KJ .EQ. IJU) .AND. (KKB .LE. IKU) .AND. (KKE  .LE. IKU) ) THEN 
+       CALL MNH_GET_ZT3D_N0(KINDEX)
+       PTAB(1:,1:,KKB:) => ZT3D(:,:,KKB:KKE,KINDEX)
+    ELSE
+       call Print_msg( NVERB_ERROR, 'GEN', 'MNH_ALLOCATE_ZT3DP', ' Size mismatsh ' )
+    END IF
+       
+  END FUNCTION MNH_ALLOCATE_ZT3DP
+
+!-------- Logical Pool Managment
+  
+    SUBROUTINE MNH_GET_GT3D_N0(KTEMP)
+
+    IMPLICIT NONE
+
+    INTEGER :: KTEMP
+
+    IF (NT3D_TOP_G == JPMAX_T3D_G ) THEN
+      WRITE( *, '( " MNH_GET_GT3D_N0: NT3D_TOP_G too big (increaze JPMAX_T3D_G) , NT3D_TOP_G=",I4 )' ) NT3D_TOP_G
+      call Print_msg( NVERB_FATAL, 'GEN', 'MNH_GET_GT3D_N0', 'NT3D_TOP_G too big (increaze JPMAX_T3D_G)' )
+    ELSE
+       NT3D_TOP_G = NT3D_TOP_G + 1
+       KTEMP = NT3D_POOL_G(NT3D_TOP_G)
+       NT3D_POOL_G(NT3D_TOP_G) = - KTEMP
+       IF (  NT3D_TOP_G > NT3D_TOP_G_MAX ) THEN
+          NT3D_TOP_G_MAX = NT3D_TOP_G
+          !WRITE( *, '( " MNH_GET_GT3D: NT3D_TOP_G_MAX=",I4," KTEMP=",I4 )' ) NT3D_TOP_G_MAX,KTEMP
+       END IF
+    ENDIF
+    !WRITE( *, '( "MNH_GET_GT3D: reserving GT3D (",I4,")" )' ) KTEMP
+
+  END SUBROUTINE MNH_GET_GT3D_N0
+
+  SUBROUTINE MNH_GET_GT3D(KTEMP1,KTEMP2,KTEMP3,KTEMP4,KTEMP5,KTEMP6,KTEMP7,KTEMP8,KTEMP9, &
+                          KTEMP10,KTEMP11,KTEMP12,KTEMP13,KTEMP14,KTEMP15,KTEMP16,KTEMP17,KTEMP18)
+
+    IMPLICIT NONE
+
+    INTEGER          :: KTEMP1
+    INTEGER,OPTIONAL :: KTEMP2,KTEMP3,KTEMP4,KTEMP5,KTEMP6,KTEMP7,KTEMP8,KTEMP9
+    INTEGER,OPTIONAL :: KTEMP10,KTEMP11,KTEMP12,KTEMP13,KTEMP14,KTEMP15,KTEMP16,KTEMP17,KTEMP18
+
+                          CALL MNH_GET_GT3D_N0(KTEMP1)
+    IF (PRESENT(KTEMP2))  CALL MNH_GET_GT3D_N0(KTEMP2)
+    IF (PRESENT(KTEMP3))  CALL MNH_GET_GT3D_N0(KTEMP3)
+    IF (PRESENT(KTEMP4))  CALL MNH_GET_GT3D_N0(KTEMP4)
+    IF (PRESENT(KTEMP5))  CALL MNH_GET_GT3D_N0(KTEMP5)
+    IF (PRESENT(KTEMP6))  CALL MNH_GET_GT3D_N0(KTEMP6)
+    IF (PRESENT(KTEMP7))  CALL MNH_GET_GT3D_N0(KTEMP7)
+    IF (PRESENT(KTEMP8))  CALL MNH_GET_GT3D_N0(KTEMP8)
+    IF (PRESENT(KTEMP9))  CALL MNH_GET_GT3D_N0(KTEMP9)
+    IF (PRESENT(KTEMP10)) CALL MNH_GET_GT3D_N0(KTEMP10)
+    IF (PRESENT(KTEMP11)) CALL MNH_GET_GT3D_N0(KTEMP11)
+    IF (PRESENT(KTEMP12)) CALL MNH_GET_GT3D_N0(KTEMP12)
+    IF (PRESENT(KTEMP13)) CALL MNH_GET_GT3D_N0(KTEMP13)
+    IF (PRESENT(KTEMP14)) CALL MNH_GET_GT3D_N0(KTEMP14)
+    IF (PRESENT(KTEMP15)) CALL MNH_GET_GT3D_N0(KTEMP15)
+    IF (PRESENT(KTEMP16)) CALL MNH_GET_GT3D_N0(KTEMP16)
+    IF (PRESENT(KTEMP17)) CALL MNH_GET_GT3D_N0(KTEMP17)
+    IF (PRESENT(KTEMP18)) CALL MNH_GET_GT3D_N0(KTEMP18)
+
+  END SUBROUTINE MNH_GET_GT3D
+
+    SUBROUTINE MNH_REL_GT3D_N0(KTEMP)
+
+    IMPLICIT NONE
+
+    INTEGER :: KTEMP
+
+    IF ( ( NT3D_TOP_G > JPMAX_T3D_G ) .OR. ( NT3D_TOP_G < 1 ) ) THEN
+      call Print_msg( NVERB_FATAL, 'GEN', 'MNH_REL_GT3D_N0', 'invalid value for NT3D_TOP_G' )
+    ELSE
+      NT3D_POOL_G(KTEMP) = KTEMP
+      IF (KTEMP == NT3D_TOP_G) THEN
+        NT3D_TOP_G = NT3D_TOP_G - 1
+     ELSE
+        WRITE( *, '( "MNH_REL_GT3D: releasing GT3D (",2I8,")" )' ) KTEMP, NT3D_TOP_G
+        call Print_msg( NVERB_FATAL, 'GEN', 'MNH_REL_GT3D_N0', 'invalid value for KTEMP <> NT3D_TOP_G' )
+      END IF
+    ENDIF
+    !WRITE( *, '( "MNH_REL_GT3D: releasing GT3D (",I4,")" )' ) KTEMP
+
+  END SUBROUTINE MNH_REL_GT3D_N0
+
+  SUBROUTINE MNH_REL_GT3D(KTEMP1,KTEMP2,KTEMP3,KTEMP4,KTEMP5,KTEMP6,KTEMP7,KTEMP8,KTEMP9, &
+                          KTEMP10,KTEMP11,KTEMP12,KTEMP13,KTEMP14,KTEMP15,KTEMP16,KTEMP17,KTEMP18, &
+                          KTEMP19,KTEMP20)
+
+    IMPLICIT NONE
+
+    INTEGER          :: KTEMP1
+    INTEGER,OPTIONAL :: KTEMP2,KTEMP3,KTEMP4,KTEMP5,KTEMP6,KTEMP7,KTEMP8,KTEMP9
+    INTEGER,OPTIONAL :: KTEMP10,KTEMP11,KTEMP12,KTEMP13,KTEMP14,KTEMP15,KTEMP16,KTEMP17,KTEMP18
+    INTEGER,OPTIONAL :: KTEMP19,KTEMP20
+
+    IF (PRESENT(KTEMP20)) CALL MNH_REL_GT3D_N0(KTEMP20)
+    IF (PRESENT(KTEMP19)) CALL MNH_REL_GT3D_N0(KTEMP19)
+    IF (PRESENT(KTEMP18)) CALL MNH_REL_GT3D_N0(KTEMP18)
+    IF (PRESENT(KTEMP17)) CALL MNH_REL_GT3D_N0(KTEMP17)
+    IF (PRESENT(KTEMP16)) CALL MNH_REL_GT3D_N0(KTEMP16)
+    IF (PRESENT(KTEMP15)) CALL MNH_REL_GT3D_N0(KTEMP15)
+    IF (PRESENT(KTEMP14)) CALL MNH_REL_GT3D_N0(KTEMP14)
+    IF (PRESENT(KTEMP13)) CALL MNH_REL_GT3D_N0(KTEMP13)
+    IF (PRESENT(KTEMP12)) CALL MNH_REL_GT3D_N0(KTEMP12)
+    IF (PRESENT(KTEMP11)) CALL MNH_REL_GT3D_N0(KTEMP11)
+    IF (PRESENT(KTEMP10)) CALL MNH_REL_GT3D_N0(KTEMP10)
+    IF (PRESENT(KTEMP9))  CALL MNH_REL_GT3D_N0(KTEMP9)
+    IF (PRESENT(KTEMP8))  CALL MNH_REL_GT3D_N0(KTEMP8)
+    IF (PRESENT(KTEMP7))  CALL MNH_REL_GT3D_N0(KTEMP7)
+    IF (PRESENT(KTEMP6))  CALL MNH_REL_GT3D_N0(KTEMP6)
+    IF (PRESENT(KTEMP5))  CALL MNH_REL_GT3D_N0(KTEMP5)
+    IF (PRESENT(KTEMP4))  CALL MNH_REL_GT3D_N0(KTEMP4)
+    IF (PRESENT(KTEMP3))  CALL MNH_REL_GT3D_N0(KTEMP3)
+    IF (PRESENT(KTEMP2))  CALL MNH_REL_GT3D_N0(KTEMP2)
+    CALL MNH_REL_GT3D_N0(KTEMP1)
+    
+  END SUBROUTINE MNH_REL_GT3D
+
+    FUNCTION MNH_ALLOCATE_GT3D(PTAB,KI,KJ,KK) RESULT (KINDEX)
+    
+    LOGICAL, POINTER, CONTIGUOUS , DIMENSION(:,:,:), INTENT(INOUT) :: PTAB
+    INTEGER , INTENT(IN)    :: KI,KJ,KK
+    INTEGER                 :: KINDEX
+
+    !local
+
+    IF ( (KI .EQ. IIU) .AND. (KJ .EQ. IJU) .AND. (KK .EQ. IKU) ) THEN 
+       CALL MNH_GET_GT3D_N0(KINDEX)
+       PTAB => GT3D(:,:,:,KINDEX)
+    ELSE
+       call Print_msg( NVERB_ERROR, 'GEN', 'MNH_ALLOCATE_GT3D', ' Size mismatsh ' )
+    END IF
+       
+  END FUNCTION MNH_ALLOCATE_GT3D
+
+  FUNCTION MNH_ALLOCATE_GT2D(PTAB,KI,KJ) RESULT (KINDEX)
+    
+    LOGICAL, POINTER, CONTIGUOUS , DIMENSION(:,:), INTENT(INOUT) :: PTAB
+    INTEGER , INTENT(IN)    :: KI,KJ
+    INTEGER                 :: KINDEX
+
+    !local
+
+    IF (KI .EQ. IIU) THEN
+       CALL MNH_GET_GT3D_N0(KINDEX)
+       IF (KJ .EQ. IJU) THEN 
+          PTAB => GT3D(:,:,1,KINDEX)
+       ELSE IF (KJ .EQ. 0)  THEN
+          PTAB => GT2D_OSIZE
+       ELSE
+          call Print_msg( NVERB_ERROR, 'GEN', 'MNH_ALLOCATE_GT2D', ' Size mismatsh ' )
+       END IF
+    ELSE
+       call Print_msg( NVERB_ERROR, 'GEN', 'MNH_ALLOCATE_GT2D', ' Size mismatsh ' )
+    END IF
+       
+  END FUNCTION MNH_ALLOCATE_GT2D
+
+  !------------ End Logical Pool
+
+    !-------- Real 1D Pool Managment
+  
+    SUBROUTINE MNH_GET_ZT1D_N0(KTEMP)
+
+    IMPLICIT NONE
+
+    INTEGER :: KTEMP
+
+    IF (NT1D_TOP_R == JPMAX_T1D_R ) THEN
+      WRITE( *, '( " MNH_GET_ZT1D_N0: NT1D_TOP_R too big (increaze JPMAX_T1D_R) , NT1D_TOP_R=",I4 )' ) NT1D_TOP_R
+      call Print_msg( NVERB_FATAL, 'GEN', 'MNH_GET_ZT1D_N0', 'NT1D_TOP_R too big (increaze JPMAX_T1D_R)' )
+    ELSE
+       NT1D_TOP_R = NT1D_TOP_R + 1
+       KTEMP = NT1D_POOL_R(NT1D_TOP_R)
+       NT1D_POOL_R(NT1D_TOP_R) = - KTEMP
+       IF (  NT1D_TOP_R > NT1D_TOP_R_MAX ) THEN
+          NT1D_TOP_R_MAX = NT1D_TOP_R
+          !WRITE( *, '( " MNH_GET_ZT1D: NT1D_TOP_R_MAX=",I4," KTEMP=",I4 )' ) NT1D_TOP_R_MAX,KTEMP
+       END IF
+    ENDIF
+    !WRITE( *, '( "MNH_GET_ZT1D: reserving ZT1D (",I4,")" )' ) KTEMP
+
+  END SUBROUTINE MNH_GET_ZT1D_N0
+
+  SUBROUTINE MNH_GET_ZT1D(KTEMP1,KTEMP2,KTEMP3,KTEMP4,KTEMP5,KTEMP6,KTEMP7,KTEMP8,KTEMP9, &
+                          KTEMP10,KTEMP11,KTEMP12,KTEMP13,KTEMP14,KTEMP15,KTEMP16,KTEMP17,KTEMP18)
+
+    IMPLICIT NONE
+
+    INTEGER          :: KTEMP1
+    INTEGER,OPTIONAL :: KTEMP2,KTEMP3,KTEMP4,KTEMP5,KTEMP6,KTEMP7,KTEMP8,KTEMP9
+    INTEGER,OPTIONAL :: KTEMP10,KTEMP11,KTEMP12,KTEMP13,KTEMP14,KTEMP15,KTEMP16,KTEMP17,KTEMP18
+
+                          CALL MNH_GET_ZT1D_N0(KTEMP1)
+    IF (PRESENT(KTEMP2))  CALL MNH_GET_ZT1D_N0(KTEMP2)
+    IF (PRESENT(KTEMP3))  CALL MNH_GET_ZT1D_N0(KTEMP3)
+    IF (PRESENT(KTEMP4))  CALL MNH_GET_ZT1D_N0(KTEMP4)
+    IF (PRESENT(KTEMP5))  CALL MNH_GET_ZT1D_N0(KTEMP5)
+    IF (PRESENT(KTEMP6))  CALL MNH_GET_ZT1D_N0(KTEMP6)
+    IF (PRESENT(KTEMP7))  CALL MNH_GET_ZT1D_N0(KTEMP7)
+    IF (PRESENT(KTEMP8))  CALL MNH_GET_ZT1D_N0(KTEMP8)
+    IF (PRESENT(KTEMP9))  CALL MNH_GET_ZT1D_N0(KTEMP9)
+    IF (PRESENT(KTEMP10)) CALL MNH_GET_ZT1D_N0(KTEMP10)
+    IF (PRESENT(KTEMP11)) CALL MNH_GET_ZT1D_N0(KTEMP11)
+    IF (PRESENT(KTEMP12)) CALL MNH_GET_ZT1D_N0(KTEMP12)
+    IF (PRESENT(KTEMP13)) CALL MNH_GET_ZT1D_N0(KTEMP13)
+    IF (PRESENT(KTEMP14)) CALL MNH_GET_ZT1D_N0(KTEMP14)
+    IF (PRESENT(KTEMP15)) CALL MNH_GET_ZT1D_N0(KTEMP15)
+    IF (PRESENT(KTEMP16)) CALL MNH_GET_ZT1D_N0(KTEMP16)
+    IF (PRESENT(KTEMP17)) CALL MNH_GET_ZT1D_N0(KTEMP17)
+    IF (PRESENT(KTEMP18)) CALL MNH_GET_ZT1D_N0(KTEMP18)
+
+  END SUBROUTINE MNH_GET_ZT1D
+
+    SUBROUTINE MNH_REL_ZT1D_N0(KTEMP)
+
+    IMPLICIT NONE
+
+    INTEGER :: KTEMP
+
+    IF ( ( NT1D_TOP_R > JPMAX_T1D_R ) .OR. ( NT1D_TOP_R < 1 ) ) THEN
+      call Print_msg( NVERB_FATAL, 'GEN', 'MNH_REL_ZT1D_N0', 'invalid value for NT1D_TOP_R' )
+    ELSE
+      NT1D_POOL_R(KTEMP) = KTEMP
+      IF (KTEMP == NT1D_TOP_R) THEN
+        NT1D_TOP_R = NT1D_TOP_R - 1
+     ELSE
+        WRITE( *, '( "MNH_REL_ZT1D_N0: invalid value for KTEMP <> NT1D_TOP_R  (",2I8,")" )' ) KTEMP, NT1D_TOP_R
+        FLUSH(6)
+        call Print_msg( NVERB_FATAL, 'GEN', 'MNH_REL_ZT1D_N0', 'invalid value for KTEMP <> NT1D_TOP_R' )
+      END IF
+    ENDIF
+    !WRITE( *, '( "MNH_REL_ZT1D_N0: releasing ZT1D (",I4,")" )' ) KTEMP
+
+  END SUBROUTINE MNH_REL_ZT1D_N0
+
+  SUBROUTINE MNH_REL_ZT1D(KTEMP1,KTEMP2,KTEMP3,KTEMP4,KTEMP5,KTEMP6,KTEMP7,KTEMP8,KTEMP9, &
+                          KTEMP10,KTEMP11,KTEMP12,KTEMP13,KTEMP14,KTEMP15,KTEMP16,KTEMP17,KTEMP18, &
+                          KTEMP19,KTEMP20)
+
+    IMPLICIT NONE
+
+    INTEGER          :: KTEMP1
+    INTEGER,OPTIONAL :: KTEMP2,KTEMP3,KTEMP4,KTEMP5,KTEMP6,KTEMP7,KTEMP8,KTEMP9
+    INTEGER,OPTIONAL :: KTEMP10,KTEMP11,KTEMP12,KTEMP13,KTEMP14,KTEMP15,KTEMP16,KTEMP17,KTEMP18
+    INTEGER,OPTIONAL :: KTEMP19,KTEMP20
+
+    IF (PRESENT(KTEMP20)) CALL MNH_REL_ZT1D_N0(KTEMP20)
+    IF (PRESENT(KTEMP19)) CALL MNH_REL_ZT1D_N0(KTEMP19)
+    IF (PRESENT(KTEMP18)) CALL MNH_REL_ZT1D_N0(KTEMP18)
+    IF (PRESENT(KTEMP17)) CALL MNH_REL_ZT1D_N0(KTEMP17)
+    IF (PRESENT(KTEMP16)) CALL MNH_REL_ZT1D_N0(KTEMP16)
+    IF (PRESENT(KTEMP15)) CALL MNH_REL_ZT1D_N0(KTEMP15)
+    IF (PRESENT(KTEMP14)) CALL MNH_REL_ZT1D_N0(KTEMP14)
+    IF (PRESENT(KTEMP13)) CALL MNH_REL_ZT1D_N0(KTEMP13)
+    IF (PRESENT(KTEMP12)) CALL MNH_REL_ZT1D_N0(KTEMP12)
+    IF (PRESENT(KTEMP11)) CALL MNH_REL_ZT1D_N0(KTEMP11)
+    IF (PRESENT(KTEMP10)) CALL MNH_REL_ZT1D_N0(KTEMP10)
+    IF (PRESENT(KTEMP9))  CALL MNH_REL_ZT1D_N0(KTEMP9)
+    IF (PRESENT(KTEMP8))  CALL MNH_REL_ZT1D_N0(KTEMP8)
+    IF (PRESENT(KTEMP7))  CALL MNH_REL_ZT1D_N0(KTEMP7)
+    IF (PRESENT(KTEMP6))  CALL MNH_REL_ZT1D_N0(KTEMP6)
+    IF (PRESENT(KTEMP5))  CALL MNH_REL_ZT1D_N0(KTEMP5)
+    IF (PRESENT(KTEMP4))  CALL MNH_REL_ZT1D_N0(KTEMP4)
+    IF (PRESENT(KTEMP3))  CALL MNH_REL_ZT1D_N0(KTEMP3)
+    IF (PRESENT(KTEMP2))  CALL MNH_REL_ZT1D_N0(KTEMP2)
+    CALL MNH_REL_ZT1D_N0(KTEMP1)
+    
+  END SUBROUTINE MNH_REL_ZT1D
+
+  FUNCTION MNH_ALLOCATE_ZT1D(PTAB,KI) RESULT (KINDEX)
+    
+    REAL, POINTER, CONTIGUOUS , DIMENSION(:), INTENT(INOUT) :: PTAB
+    INTEGER , INTENT(IN)    :: KI
+    INTEGER                 :: KINDEX
+
+    !local
+
+    IF (KI .EQ. IIJKU) THEN 
+       CALL MNH_GET_ZT1D_N0(KINDEX)
+       PTAB => ZT1D(:,KINDEX)
+    ELSE
+       call Print_msg( NVERB_ERROR, 'GEN', 'MNH_ALLOCATE_ZT1D', ' Size mismatsh ' )
+    END IF
+    !WRITE( *, '( "MNH_ALLOCATE_ZT1D: KI=(",I4,") , KINDEX=(",I4,")" )' ) KI,KINDEX
+    !FLUSH(6) 
+       
+  END FUNCTION MNH_ALLOCATE_ZT1D
+
+  FUNCTION MNH_ALLOCATE_ZT1DP(PTAB,KI) RESULT (KINDEX)
+    
+    REAL, POINTER, CONTIGUOUS , DIMENSION(:), INTENT(INOUT) :: PTAB
+    INTEGER , INTENT(IN)    :: KI
+    INTEGER                 :: KINDEX
+
+    !local
+
+    IF (KI .LE. IIJKU) THEN 
+       CALL MNH_GET_ZT1D_N0(KINDEX)
+       IF (KI .NE. 0) THEN
+          PTAB(1:KI) => ZT1D(:,KINDEX)
+       ELSE
+          PTAB => ZT1D_OSIZE
+       END IF
+    ELSE
+       call Print_msg( NVERB_ERROR, 'GEN', 'MNH_ALLOCATE_ZT1DP', ' Size mismatsh ' )
+    END IF
+    !WRITE( *, '( "MNH_ALLOCATE_ZT1DP: KI=(",I9,") , KINDEX=(",I4,")" )' ) KI,KINDEX
+    
+  END FUNCTION MNH_ALLOCATE_ZT1DP
+
+  ! End Real 1D management
+  
+  !-------- Integer 1D Pool Managment
+  
+    SUBROUTINE MNH_GET_IT1D_N0(KTEMP)
+
+    IMPLICIT NONE
+
+    INTEGER :: KTEMP
+
+    IF (NT1D_TOP_I == JPMAX_T1D_I ) THEN
+      WRITE( *, '( " MNH_GET_IT1D_N0: NT1D_TOP_I too big (increaze JPMAX_T1D_I) , NT1D_TOP_I=",I4 )' ) NT1D_TOP_I
+      call Print_msg( NVERB_FATAL, 'GEN', 'MNH_GET_IT1D_N0', 'NT1D_TOP_I too big (increaze JPMAX_T1D_I)' )
+    ELSE
+       NT1D_TOP_I = NT1D_TOP_I + 1
+       KTEMP = NT1D_POOL_I(NT1D_TOP_I)
+       NT1D_POOL_I(NT1D_TOP_I) = - KTEMP
+       IF (  NT1D_TOP_I > NT1D_TOP_I_MAX ) THEN
+          NT1D_TOP_I_MAX = NT1D_TOP_I
+          !WRITE( *, '( " MNH_GET_IT1D: NT1D_TOP_I_MAX=",I4," KTEMP=",I4 )' ) NT1D_TOP_I_MAX,KTEMP
+       END IF
+    ENDIF
+    !WRITE( *, '( "MNH_GET_IT1D: reserving IT1D (",I4,")" )' ) KTEMP
+
+  END SUBROUTINE MNH_GET_IT1D_N0
+
+  SUBROUTINE MNH_GET_IT1D(KTEMP1,KTEMP2,KTEMP3,KTEMP4,KTEMP5,KTEMP6,KTEMP7,KTEMP8,KTEMP9, &
+                          KTEMP10,KTEMP11,KTEMP12,KTEMP13,KTEMP14,KTEMP15,KTEMP16,KTEMP17,KTEMP18)
+
+    IMPLICIT NONE
+
+    INTEGER          :: KTEMP1
+    INTEGER,OPTIONAL :: KTEMP2,KTEMP3,KTEMP4,KTEMP5,KTEMP6,KTEMP7,KTEMP8,KTEMP9
+    INTEGER,OPTIONAL :: KTEMP10,KTEMP11,KTEMP12,KTEMP13,KTEMP14,KTEMP15,KTEMP16,KTEMP17,KTEMP18
+
+                          CALL MNH_GET_IT1D_N0(KTEMP1)
+    IF (PRESENT(KTEMP2))  CALL MNH_GET_IT1D_N0(KTEMP2)
+    IF (PRESENT(KTEMP3))  CALL MNH_GET_IT1D_N0(KTEMP3)
+    IF (PRESENT(KTEMP4))  CALL MNH_GET_IT1D_N0(KTEMP4)
+    IF (PRESENT(KTEMP5))  CALL MNH_GET_IT1D_N0(KTEMP5)
+    IF (PRESENT(KTEMP6))  CALL MNH_GET_IT1D_N0(KTEMP6)
+    IF (PRESENT(KTEMP7))  CALL MNH_GET_IT1D_N0(KTEMP7)
+    IF (PRESENT(KTEMP8))  CALL MNH_GET_IT1D_N0(KTEMP8)
+    IF (PRESENT(KTEMP9))  CALL MNH_GET_IT1D_N0(KTEMP9)
+    IF (PRESENT(KTEMP10)) CALL MNH_GET_IT1D_N0(KTEMP10)
+    IF (PRESENT(KTEMP11)) CALL MNH_GET_IT1D_N0(KTEMP11)
+    IF (PRESENT(KTEMP12)) CALL MNH_GET_IT1D_N0(KTEMP12)
+    IF (PRESENT(KTEMP13)) CALL MNH_GET_IT1D_N0(KTEMP13)
+    IF (PRESENT(KTEMP14)) CALL MNH_GET_IT1D_N0(KTEMP14)
+    IF (PRESENT(KTEMP15)) CALL MNH_GET_IT1D_N0(KTEMP15)
+    IF (PRESENT(KTEMP16)) CALL MNH_GET_IT1D_N0(KTEMP16)
+    IF (PRESENT(KTEMP17)) CALL MNH_GET_IT1D_N0(KTEMP17)
+    IF (PRESENT(KTEMP18)) CALL MNH_GET_IT1D_N0(KTEMP18)
+
+  END SUBROUTINE MNH_GET_IT1D
+
+    SUBROUTINE MNH_REL_IT1D_N0(KTEMP)
+
+    IMPLICIT NONE
+
+    INTEGER :: KTEMP
+
+    IF ( ( NT1D_TOP_I > JPMAX_T1D_I ) .OR. ( NT1D_TOP_I < 1 ) ) THEN
+      call Print_msg( NVERB_FATAL, 'GEN', 'MNH_REL_IT1D_N0', 'invalid value for NT1D_TOP_I' )
+    ELSE
+      NT1D_POOL_I(KTEMP) = KTEMP
+      IF (KTEMP == NT1D_TOP_I) THEN
+        NT1D_TOP_I = NT1D_TOP_I - 1
+     ELSE
+        WRITE( *, '( "MNH_REL_IT1D_N0: invalid value for KTEMP <> NT1D_TOP_I  (",2I8,")" )' ) KTEMP, NT1D_TOP_I
+        FLUSH(6)
+        call Print_msg( NVERB_FATAL, 'GEN', 'MNH_REL_IT1D_N0', 'invalid value for KTEMP <> NT1D_TOP_R' )
+      END IF
+    ENDIF
+    !WRITE( *, '( "MNH_REL_IT1D_N0: releasing IT1D (",I4,")" )' ) KTEMP
+
+  END SUBROUTINE MNH_REL_IT1D_N0
+
+  SUBROUTINE MNH_REL_IT1D(KTEMP1,KTEMP2,KTEMP3,KTEMP4,KTEMP5,KTEMP6,KTEMP7,KTEMP8,KTEMP9, &
+                          KTEMP10,KTEMP11,KTEMP12,KTEMP13,KTEMP14,KTEMP15,KTEMP16,KTEMP17,KTEMP18, &
+                          KTEMP19,KTEMP20)
+
+    IMPLICIT NONE
+
+    INTEGER          :: KTEMP1
+    INTEGER,OPTIONAL :: KTEMP2,KTEMP3,KTEMP4,KTEMP5,KTEMP6,KTEMP7,KTEMP8,KTEMP9
+    INTEGER,OPTIONAL :: KTEMP10,KTEMP11,KTEMP12,KTEMP13,KTEMP14,KTEMP15,KTEMP16,KTEMP17,KTEMP18
+    INTEGER,OPTIONAL :: KTEMP19,KTEMP20
+
+    IF (PRESENT(KTEMP20)) CALL MNH_REL_IT1D_N0(KTEMP20)
+    IF (PRESENT(KTEMP19)) CALL MNH_REL_IT1D_N0(KTEMP19)
+    IF (PRESENT(KTEMP18)) CALL MNH_REL_IT1D_N0(KTEMP18)
+    IF (PRESENT(KTEMP17)) CALL MNH_REL_IT1D_N0(KTEMP17)
+    IF (PRESENT(KTEMP16)) CALL MNH_REL_IT1D_N0(KTEMP16)
+    IF (PRESENT(KTEMP15)) CALL MNH_REL_IT1D_N0(KTEMP15)
+    IF (PRESENT(KTEMP14)) CALL MNH_REL_IT1D_N0(KTEMP14)
+    IF (PRESENT(KTEMP13)) CALL MNH_REL_IT1D_N0(KTEMP13)
+    IF (PRESENT(KTEMP12)) CALL MNH_REL_IT1D_N0(KTEMP12)
+    IF (PRESENT(KTEMP11)) CALL MNH_REL_IT1D_N0(KTEMP11)
+    IF (PRESENT(KTEMP10)) CALL MNH_REL_IT1D_N0(KTEMP10)
+    IF (PRESENT(KTEMP9))  CALL MNH_REL_IT1D_N0(KTEMP9)
+    IF (PRESENT(KTEMP8))  CALL MNH_REL_IT1D_N0(KTEMP8)
+    IF (PRESENT(KTEMP7))  CALL MNH_REL_IT1D_N0(KTEMP7)
+    IF (PRESENT(KTEMP6))  CALL MNH_REL_IT1D_N0(KTEMP6)
+    IF (PRESENT(KTEMP5))  CALL MNH_REL_IT1D_N0(KTEMP5)
+    IF (PRESENT(KTEMP4))  CALL MNH_REL_IT1D_N0(KTEMP4)
+    IF (PRESENT(KTEMP3))  CALL MNH_REL_IT1D_N0(KTEMP3)
+    IF (PRESENT(KTEMP2))  CALL MNH_REL_IT1D_N0(KTEMP2)
+    CALL MNH_REL_IT1D_N0(KTEMP1)
+    
+  END SUBROUTINE MNH_REL_IT1D
+
+  FUNCTION MNH_ALLOCATE_IT1D(PTAB,KI) RESULT (KINDEX)
+    
+    INTEGER, POINTER, CONTIGUOUS , DIMENSION(:), INTENT(INOUT) :: PTAB
+    INTEGER , INTENT(IN)    :: KI
+    INTEGER                 :: KINDEX
+
+    !local
+
+    IF (KI .EQ. IIJKU) THEN 
+       CALL MNH_GET_IT1D_N0(KINDEX)
+       PTAB => IT1D(:,KINDEX)
+    ELSE
+       call Print_msg( NVERB_ERROR, 'GEN', 'MNH_ALLOCATE_IT1D', ' Size mismatsh ' )
+    END IF
+    !WRITE( *, '( "MNH_ALLOCATE_IT1D: KI=(",I4,") , KINDEX=(",I4,")" )' ) KI,KINDEX
+    !FLUSH(6) 
+       
+  END FUNCTION MNH_ALLOCATE_IT1D
+
+  FUNCTION MNH_ALLOCATE_IT1DP(PTAB,KI) RESULT (KINDEX)
+    
+    INTEGER, POINTER, CONTIGUOUS , DIMENSION(:), INTENT(INOUT) :: PTAB
+    INTEGER , INTENT(IN)    :: KI
+    INTEGER                 :: KINDEX
+
+    !local
+
+    IF (KI .LE. IIJKU) THEN 
+       CALL MNH_GET_IT1D_N0(KINDEX)
+       IF (KI .NE. 0) THEN
+          PTAB(1:KI) => IT1D(:,KINDEX)
+       ELSE
+          PTAB => IT1D_OSIZE
+       END IF
+    ELSE
+       call Print_msg( NVERB_ERROR, 'GEN', 'MNH_ALLOCATE_IT1DP', ' Size mismatsh ' )
+    END IF
+    !WRITE( *, '( "MNH_ALLOCATE_IT1DP: KI=(",I9,") , KINDEX=(",I4,")" )' ) KI,KINDEX
+    
+  END FUNCTION MNH_ALLOCATE_IT1DP
+
+  ! End Integer 1D management
+
+  SUBROUTINE MNH_CHECK_IN_ZT3D(HSUB)
+    IMPLICIT NONE
+
+    CHARACTER(LEN=*) :: HSUB
+
+    !print*,"MNH_CHECK_IN_ZT3D => " , NT3D_TOP_CURRENT_INDEX+1 ,  HSUB
+    NT3D_TOP_CURRENT_INDEX = NT3D_TOP_CURRENT_INDEX + 1
+    NT3D_TOP_CURRENT(NT3D_TOP_CURRENT_INDEX) = NT3D_TOP
+  END SUBROUTINE MNH_CHECK_IN_ZT3D
+
+  SUBROUTINE MNH_CHECK_OUT_ZT3D(HSUB)
+    IMPLICIT NONE
 
+    CHARACTER(LEN=*) :: HSUB
+    
+    !print*,"MNH_CHECK_OUT_ZT3D <= " ,  NT3D_TOP_CURRENT_INDEX , HSUB
+    IF ( NT3D_TOP_CURRENT(NT3D_TOP_CURRENT_INDEX) .NE.  NT3D_TOP ) THEN
+        WRITE( *, '( "MNH_CHECK_OUT_ZT3D : NT3D_TOP_CURRENT .NE. NT3D_TOP (",2I8,")" )' )  NT3D_TOP_CURRENT ,  NT3D_TOP
+        call Print_msg( NVERB_ERROR, 'GEN', 'MNH_CHECK_OUT_ZT3D', ' CHECK IN/OUT MISTASK ' )
+     ELSE
+        NT3D_TOP_CURRENT_INDEX = NT3D_TOP_CURRENT_INDEX - 1
+    END IF 
+  END SUBROUTINE MNH_CHECK_OUT_ZT3D
 
 END MODULE MODE_MNH_ZWORK
 #endif
diff --git a/src/MNH/mode_openacc.f90 b/src/MNH/mode_openacc.f90
new file mode 100644
index 0000000000000000000000000000000000000000..10f1d683dc6f2c449f042de73f266da4a32d80de
--- /dev/null
+++ b/src/MNH/mode_openacc.f90
@@ -0,0 +1,7 @@
+#ifdef _FAKEOPENACC
+MODULE OPENACC
+END MODULE OPENACC
+#else
+MODULE OPENACC_FAKEOPENACC
+END MODULE OPENACC_FAKEOPENACC
+#endif
diff --git a/src/MNH/mode_openacc_set_device.f90 b/src/MNH/mode_openacc_set_device.f90
new file mode 100644
index 0000000000000000000000000000000000000000..bd440f9809d4c832c1ebac8b11ea6419e58cff7a
--- /dev/null
+++ b/src/MNH/mode_openacc_set_device.f90
@@ -0,0 +1,113 @@
+!define NO_SWAP_DEVICE
+#ifdef NO_SWAP_DEVICE
+#define SWAP_DEVICE_RETURN return
+#else
+#define SWAP_DEVICE_RETURN
+#endif
+MODULE MODE_OPENACC_SET_DEVICE
+
+#ifndef _FAKEOPENACC  
+  USE openacc , ONLY : acc_device_kind , acc_device_nvidia, acc_device_host
+#endif
+  
+  IMPLICIT NONE
+
+#ifndef _FAKEOPENACC  
+  INTEGER(kind=acc_device_kind) :: mnh_idevice_type_at_init = -1000
+  INTEGER(kind=acc_device_kind) :: mnh_idevice_type_current = -1
+#endif  
+
+  integer :: iswitch_cpu_gpu = 5
+  
+CONTAINS
+  
+  SUBROUTINE MNH_OPENACC_GET_DEVICE_AT_INIT()
+
+#ifndef _FAKEOPENACC     
+    USE&
+         openacc , ONLY : acc_get_device_type,acc_device_kind
+    
+    IMPLICIT NONE
+    
+    INTEGER(kind=acc_device_kind) :: idevice_type
+
+    SWAP_DEVICE_RETURN
+
+    if ( mnh_idevice_type_at_init .EQ. -1000 ) then
+       mnh_idevice_type_at_init = acc_get_device_type()
+       mnh_idevice_type_current = mnh_idevice_type_at_init
+       print*,'mnh_idevice_type_at_init=',mnh_idevice_type_at_init
+    end if
+#endif
+    
+  END SUBROUTINE MNH_OPENACC_GET_DEVICE_AT_INIT
+  
+  SUBROUTINE MNH_OPENACC_GET_DEVICE()
+
+#ifndef _FAKEOPENACC    
+    USE&
+         openacc , ONLY : acc_get_device_type,acc_device_kind
+    
+    IMPLICIT NONE
+    
+    INTEGER(kind=acc_device_kind) :: idevice_type
+
+    SWAP_DEVICE_RETURN
+    
+    idevice_type = acc_get_device_type()
+    mnh_idevice_type_current = idevice_type
+    print*,'idevice_type=',idevice_type
+#endif
+    
+  END SUBROUTINE MNH_OPENACC_GET_DEVICE
+  
+  SUBROUTINE MNH_OPENACC_SET_DEVICE_HOST()
+
+#ifndef _FAKEOPENACC    
+    USE&
+         openacc , ONLY : acc_set_device_type,acc_device_host,acc_get_device_type
+    
+    IMPLICIT NONE
+
+    SWAP_DEVICE_RETURN
+
+    call acc_set_device_type(acc_device_host)
+    mnh_idevice_type_current = acc_device_host
+    
+#endif
+    
+  END SUBROUTINE MNH_OPENACC_SET_DEVICE_HOST
+  
+  SUBROUTINE MNH_OPENACC_SET_DEVICE_NVIDIA()
+
+#ifndef _FAKEOPENACC    
+    USE&
+         openacc , ONLY : acc_set_device_type,acc_device_nvidia,acc_get_device_type
+    
+    IMPLICIT NONE
+
+    SWAP_DEVICE_RETURN
+    
+    call acc_set_device_type(acc_device_nvidia)
+    mnh_idevice_type_current = acc_device_nvidia
+#endif
+    
+  END SUBROUTINE MNH_OPENACC_SET_DEVICE_NVIDIA
+
+ SUBROUTINE MNH_OPENACC_SET_DEVICE_DEFAULT()
+
+#ifndef _FAKEOPENACC
+    USE&
+         openacc , ONLY : acc_set_device_type,acc_device_nvidia,acc_get_device_type
+    
+    IMPLICIT NONE
+
+    SWAP_DEVICE_RETURN
+
+    call acc_set_device_type(mnh_idevice_type_at_init)
+    mnh_idevice_type_current = mnh_idevice_type_at_init
+#endif
+   
+  END SUBROUTINE MNH_OPENACC_SET_DEVICE_DEFAULT
+
+END MODULE MODE_OPENACC_SET_DEVICE
diff --git a/src/MNH/mode_prandtl.f90 b/src/MNH/mode_prandtl.f90
index e9cfa91ece9b6ec247e5d05ad0dd9eecd78f6bc6..5fa00542e1e3e920d35624c7816886f43813ce6c 100644
--- a/src/MNH/mode_prandtl.f90
+++ b/src/MNH/mode_prandtl.f90
@@ -16,6 +16,7 @@ USE MODD_PARAMETERS, ONLY : JPVEXT_TURB
 
 #ifdef MNH_OPENACC
 use mode_msg
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_GT3D , MNH_REL_GT3D
 #endif
 
 #ifdef MNH_BITREP
@@ -38,9 +39,18 @@ REAL, DIMENSION(:,:,:), INTENT(IN)    :: PF_LIM  ! Value of F when Phi3 is
 !                                                ! larger than Phi_lim
 REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PF      ! function F to smooth
 !
+#ifndef MNH_OPENACC
 REAL, DIMENSION(SIZE(PF,1),SIZE(PF,2),SIZE(PF,3)) :: ZCOEF
+#else
+REAL, DIMENSION(:,:,:), pointer,contiguous ::  ZCOEF
+INTEGER ::  IZCOEF
+#endif
 
-!$acc data present( PPHI3, PF_LIM, PF ) create( ZCOEF )
+#ifdef MNH_OPENACC
+ IZCOEF = MNH_ALLOCATE_ZT3D( ZCOEF , SIZE(PF,1),SIZE(PF,2),SIZE(PF,3) )
+#endif
+
+!$acc data present( PPHI3, PF_LIM, PF ) present( ZCOEF )
 
 !* adds a artificial correction to smooth the function near the discontinuity
 !  point at Phi3 = Phi_lim
@@ -57,6 +67,10 @@ PF(:,:,:) =     ZCOEF(:,:,:)   * PF    &
 
 !$acc end data
 
+#ifdef MNH_OPENACC
+CALL MNH_REL_ZT3D(IZCOEF)
+#endif
+
 END SUBROUTINE SMOOTH_TURB_FUNCT
 !----------------------------------------------------------------------------
 #ifndef MNH_OPENACC
@@ -78,44 +92,71 @@ SUBROUTINE PHI3(PREDTH1,PREDR1,PRED2TH3,PRED2R3,PRED2THR3,HTURBDIM,OUSERV,PPHI3)
 #endif
 !
   INTEGER                               :: IKB, IKE
-  LOGICAL,DIMENSION(:,:,:), allocatable :: PHI3LOGIC
-  REAL,   DIMENSION(:,:,:), allocatable :: ZW1, ZW2
+  LOGICAL,DIMENSION(:,:,:),  pointer , contiguous :: GPHI3LOGIC
+  REAL,   DIMENSION(:,:,:),  pointer , contiguous :: ZW1, ZW2
+#ifdef MNH_OPENACC
+  INTEGER                                         :: IGPHI3LOGIC, IZW1, IZW2
+#endif
 
+  INTEGER  :: JIU,JJU,JKU
+  INTEGER  :: JI,JJ,JK
+  
 !$acc data present( PREDTH1, PREDR1, PRED2TH3, PRED2R3, PRED2THR3, PPHI3 )
 
 IKB = 1+JPVEXT_TURB
 IKE = SIZE(PREDTH1,3)-JPVEXT_TURB
 
+JIU =  size( predth1, 1 )
+JJU =  size( predth1, 2 )
+JKU =  size( predth1, 3 )
+
+#ifndef MNH_OPENACC
 allocate( zw1      ( size( predth1, 1 ), size( predth1, 2 ), size( predth1, 3 ) ) )
 allocate( zw2      ( size( predth1, 1 ), size( predth1, 2 ), size( predth1, 3 ) ) )
-allocate( phi3logic( size( predth1, 1 ), size( predth1, 2 ), size( predth1, 3 ) ) )
+allocate( gphi3logic( size( predth1, 1 ), size( predth1, 2 ), size( predth1, 3 ) ) )
+#else
+izw1        = MNH_ALLOCATE_ZT3D( zw1       , JIU,JJU,JKU )
+izw2        = MNH_ALLOCATE_ZT3D( zw2       , JIU,JJU,JKU )
+igphi3logic = MNH_ALLOCATE_GT3D( gphi3logic, JIU,JJU,JKU )
+#endif
 
-!$acc data create( zw1, zw2, phi3logic )
+!$acc data present( zw1, zw2, gphi3logic )
 
 !$acc kernels
 IF (HTURBDIM=='3DIM') THEN
         !* 3DIM case
   IF (OUSERV) THEN
-    ZW1(:,:,:) = 1. + 1.5* (PREDTH1(:,:,:)+PREDR1(:,:,:)) +      &
 #ifndef MNH_BITREP
-                   ( 0.5 * (PREDTH1(:,:,:)**2+PREDR1(:,:,:)**2)  &
-#else
-                   ( 0.5 * (BR_P2(PREDTH1(:,:,:))+BR_P2(PREDR1(:,:,:)))  &
-#endif
-                         + PREDTH1(:,:,:) * PREDR1(:,:,:)        &
-                   )
+    DO CONCURRENT (JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZW1(JI,JJ,JK) = 1. + 1.5* (PREDTH1(JI,JJ,JK)+PREDR1(JI,JJ,JK)) +     &
+                         ( 0.5 * (PREDTH1(JI,JJ,JK)**2+PREDR1(JI,JJ,JK)**2) &
+                                + PREDTH1(JI,JJ,JK) * PREDR1(JI,JJ,JK)      &
+                         )
+    END DO
+#else
+    DO CONCURRENT (JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZW1(JI,JJ,JK) = 1. + 1.5* (PREDTH1(JI,JJ,JK)+PREDR1(JI,JJ,JK)) +      &
+                   ( 0.5 * (BR_P2(PREDTH1(JI,JJ,JK))+BR_P2(PREDR1(JI,JJ,JK)))  &
+                         + PREDTH1(JI,JJ,JK) * PREDR1(JI,JJ,JK)        &
+                         )
+    END DO
+#endif    
     ZW2(:,:,:) = 0.5 * (PRED2TH3(:,:,:)-PRED2R3(:,:,:))
     PPHI3(:,:,:)= 1. -                                          &
     ( ( (1.+PREDR1(:,:,:)) *                                   &
         (PRED2THR3(:,:,:) + PRED2TH3(:,:,:)) / PREDTH1(:,:,:)  &
       ) + ZW2(:,:,:)                                           &
     ) / ZW1(:,:,:)
-  ELSE
-    ZW1(:,:,:) = 1. + 1.5* PREDTH1(:,:,:) + &
-#ifndef MNH_BITREP
-                 0.5* PREDTH1(:,:,:)**2
+ ELSE
+#ifndef MNH_BITREP    
+    DO CONCURRENT (JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZW1(JI,JJ,JK) = 1. + 1.5* PREDTH1(JI,JJ,JK) + &    
+                    0.5* PREDTH1(JI,JJ,JK)**2
 #else
-                 0.5* BR_P2(PREDTH1(:,:,:))
+    DO CONCURRENT (JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZW1(JI,JJ,JK) = 1. + 1.5* PREDTH1(JI,JJ,JK) + &    
+                    0.5* BR_P2(PREDTH1(JI,JJ,JK))
+ END DO
 #endif
     ZW2(:,:,:) = 0.5* PRED2TH3(:,:,:)
     PPHI3(:,:,:)= 1. -                                       &
@@ -125,8 +166,8 @@ IF (HTURBDIM=='3DIM') THEN
 !WARNING: BUG PGI (tested up to PGI 16.10): necessary to use a logical mask
 !because the compiler does not manage correctly the .OR. in the WHERE
   !WHERE( PPHI3 <= 0. .OR. PPHI3 > XPHI_LIM )
-  PHI3LOGIC = (PPHI3 <= 0. .OR. PPHI3 > XPHI_LIM)
-  WHERE( PHI3LOGIC )
+  GPHI3LOGIC = (PPHI3 <= 0. .OR. PPHI3 > XPHI_LIM)
+  WHERE( GPHI3LOGIC )
     PPHI3 = XPHI_LIM
   END WHERE
 
@@ -145,6 +186,13 @@ PPHI3(:,:,IKE+1)=PPHI3(:,:,IKE)
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate ( zw1,zw2,gphi3logic)
+#else
+CALL MNH_REL_ZT3D(IZW1,IZW2)
+CALL MNH_REL_GT3D(IGPHI3LOGIC)
+#endif
+
 !$acc end data
 
 #ifndef MNH_OPENACC
@@ -173,13 +221,20 @@ SUBROUTINE PSI_SV(PREDTH1,PREDR1,PREDS1,PRED2THS,PRED2RS,PPHI3,PPSI3,PPSI_SV)
 !
   INTEGER :: IKB, IKE
   INTEGER :: JSV
-  LOGICAL, DIMENSION(:,:,:), allocatable :: PSILOGIC
+  LOGICAL, DIMENSION(:,:,:),  pointer , contiguous :: GPSILOGIC
+#ifdef MNH_OPENACC
+  INTEGER                                          :: IGPSILOGIC
+#endif
 
 !$acc data present( PREDTH1, PREDR1, PREDS1, PRED2THS, PRED2RS, PPHI3, PPSI3, PPSI_SV )
 
-allocate( psilogic( size( pred2ths, 1 ), size( pred2ths, 2 ), size( pred2ths, 3 ) ) )
+#ifndef MNH_OPENACC  
+allocate( gpsilogic( size( pred2ths, 1 ), size( pred2ths, 2 ), size( pred2ths, 3 ) ) )
+#else
+igpsilogic = MNH_ALLOCATE_GT3D( gpsilogic , size( pred2ths, 1 ), size( pred2ths, 2 ), size( pred2ths, 3 ) )
+#endif  
 
-!$acc data create( psilogic )
+!$acc data present( gpsilogic )
 
 IKB = 1+JPVEXT_TURB
 IKE = SIZE(PREDTH1,3)-JPVEXT_TURB
@@ -197,8 +252,8 @@ DO JSV=1,SIZE(PPSI_SV,4)
 !because the compiler does not manage correctly the .AND. in the WHERE
 !Failure during execution
   !WHERE ( (PPSI_SV(:,:,:,JSV) <=0.).AND. (PREDTH1+PREDR1) <= 0. )
-  PSILOGIC = ((PPSI_SV(:,:,:,JSV) <=0.).AND. (PREDTH1+PREDR1) <= 0. )
-  WHERE ( PSILOGIC )
+  GPSILOGIC = ((PPSI_SV(:,:,:,JSV) <=0.).AND. (PREDTH1+PREDR1) <= 0. )
+  WHERE ( GPSILOGIC )
     PPSI_SV(:,:,:,JSV)=XPHI_LIM
   END WHERE
   PPSI_SV(:,:,:,JSV) = MAX( 1.E-4, MIN(XPHI_LIM,PPSI_SV(:,:,:,JSV)) )
@@ -210,6 +265,12 @@ END DO
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate( gpsilogic )
+#else
+CALL MNH_REL_GT3D(IGPSILOGIC)
+#endif
+
 !$acc end data
 
 #ifndef MNH_OPENACC
@@ -400,16 +461,17 @@ SUBROUTINE D_PHI3DTDZ2_O_DDTDZ(PPHI3,PREDTH1,PREDR1,PRED2TH3,PRED2THR3,PDTDZ,HTU
 #endif
   INTEGER :: IKB, IKE
 #ifdef MNH_OPENACC
-  REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE
+  REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE
+  INTEGER  :: IZTMP1_DEVICE
 #endif
 
 !$acc data present( PPHI3, PREDTH1, PREDR1, PRED2TH3, PRED2THR3, PDTDZ, PD_PHI3DTDZ2_O_DDTDZ )
 
 #ifdef MNH_OPENACC
-allocate( ztmp1_device(size( predth1, 1 ), size( predth1, 2 ), size( predth1, 3 ) ) )
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device, size( predth1, 1 ), size( predth1, 2 ), size( predth1, 3 ) )
 #endif
 
-!$acc data create( ztmp1_device )
+!$acc data present( ztmp1_device )
 
 IKB = 1+JPVEXT_TURB
 IKE = SIZE(PREDTH1,3)-JPVEXT_TURB
@@ -483,6 +545,10 @@ PD_PHI3DTDZ2_O_DDTDZ(:,:,IKE+1)=PD_PHI3DTDZ2_O_DDTDZ(:,:,IKE)
 
 !$acc end data
 
+#ifdef MNH_OPENACC
+CALL MNH_REL_ZT3D( iztmp1_device )
+#endif
+
 !$acc end data
 
 #ifndef MNH_OPENACC
diff --git a/src/MNH/modeln.f90 b/src/MNH/modeln.f90
index 3ad1f6d48935f03b92625175642e0eeb33d481eb..1d7902e71600f36c4b02a2ec3ba29123cd61a2ec 100644
--- a/src/MNH/modeln.f90
+++ b/src/MNH/modeln.f90
@@ -1602,13 +1602,16 @@ ZTIME1 = ZTIME2
 XTIME_BU_PROCESS = 0.
 XTIME_LES_BU_PROCESS = 0.
 !
+!$acc update device(XRTHS)
+!
 !$acc data create (XUT, XVT, XWT)                                         &
 !$acc &    copyin (XTHT, XPABST, XRT, XSVT, XRTHS_CLD, XRRS_CLD, XTHVREF) &
-!$acc &    copy   (XRTHS, XRRS, XRUS, XRVS, XRWS)                         &
+!$acc &    copy   (XRRS, XRUS, XRVS, XRWS)                         &
 !$acc &    copy   (XRWS_PRES)                                             & !XRWS_PRES copy and not copyout (hidden in UPDATE_HALO)
 !$acc &    present(XDXX, XDYY, XDZZ, XDZX, XDZY, XRHODJ)
 !
 !$acc update device(XUT, XVT, XWT, XRHODJ)
+
 !
 !
 !$acc data copyin (XTKET, XRSVS_CLD) &
@@ -1624,6 +1627,8 @@ CALL ADVECTION_METSV ( TZBAKFILE, CUVW_ADV_SCHEME,                     &
                  XRTHS_CLD, XRRS_CLD, XRSVS_CLD, XRTKEMS               )
 !$acc end data
 !
+!$acc update host(XRTHS)
+!
 CALL SECOND_MNH2(ZTIME2)
 !
 XT_ADV = XT_ADV + ZTIME2 - ZTIME1 - XTIME_LES_BU_PROCESS - XTIME_BU_PROCESS
@@ -1901,6 +1906,9 @@ IF (CCLOUD /= 'NONE' .AND. CELEC == 'NONE') THEN
 !$acc &            XINPRC, XINPRR, XINPRS, XINPRG, XINPRH, XINDEP,                               &
 !$acc &            XHLC_HRC, XHLC_HCF, XHLI_HRI, XHLI_HCF)                                       &
 !$acc &    copyout(XSRCT, XRAINFR)
+
+!$acc update device ( XRTHS )
+  
   IF (CSURF=='EXTE') THEN
     ALLOCATE (ZSEA(SIZE(XRHODJ,1),SIZE(XRHODJ,2)))
     ALLOCATE (ZTOWN(SIZE(XRHODJ,1),SIZE(XRHODJ,2)))
@@ -1952,6 +1960,9 @@ IF (CCLOUD /= 'NONE' .AND. CELEC == 'NONE') THEN
                           XHLC_HRC, XHLC_HCF, XHLI_HRI, XHLI_HCF               )
   END IF
 !$acc end data
+
+!$acc update host(XRTHS)
+  
   XRTHS_CLD(:, :, : )    = XRTHS(:, :, : )    - XRTHS_CLD(:, :, : )
   XRRS_CLD (:, :, :, : ) = XRRS (:, :, :, : ) - XRRS_CLD (:, :, :, : )
   XRSVS_CLD(:, :, :, : ) = XRSVS(:, :, :, : ) - XRSVS_CLD(:, :, :, : )
diff --git a/src/MNH/ppm.f90 b/src/MNH/ppm.f90
index bbfb03a46a9d816096ff70da3be9a12cc1f95a55..9d1f1e611442938ce2be15e478ba071ce05e7bb0 100644
--- a/src/MNH/ppm.f90
+++ b/src/MNH/ppm.f90
@@ -2704,9 +2704,9 @@ ENDIF
 #ifndef MNH_OPENACC
 CALL  GET_HALO(ZPHAT, HNAME='ZPHAT')
 #else
-!$acc update self(ZPHAT)
-CALL GET_HALO(ZPHAT(:,:,:), HDIR="Z0_X", HNAME='ZPHAT')
-!$acc update device(ZPHAT)
+! acc update self(ZPHAT)
+!CALL GET_HALO_D(ZPHAT(:,:,:), HDIR="Z0_X", HNAME='ZPHAT')
+! acc update device(ZPHAT)
 #endif
 !
 !$acc kernels
@@ -2739,9 +2739,9 @@ CALL GET_HALO(ZPHAT(:,:,:), HDIR="Z0_X", HNAME='ZPHAT')
 #ifndef MNH_OPENACC
 CALL GET_HALO(ZFPOS, HNAME='ZFPOS') ! JUAN
 #else
-!$acc update self(ZFPOS)
-CALL GET_HALO(ZFPOS(:,:,:), HDIR="Z0_X", HNAME='ZFPOS') ! JUAN
-!$acc update device(ZFPOS)
+! acc update self(ZFPOS)
+!CALL GET_HALO_D(ZFPOS(:,:,:), HDIR="Z0_X", HNAME='ZFPOS') ! JUAN
+! acc update device(ZFPOS)
 #endif
 !
 !$acc kernels
@@ -2767,9 +2767,9 @@ CALL GET_HALO(ZFPOS(:,:,:), HDIR="Z0_X", HNAME='ZFPOS') ! JUAN
 #ifndef MNH_OPENACC
    CALL GET_HALO(ZFNEG, HNAME='ZFNEG') ! JUAN
 #else
-!$acc update self(ZFNEG)
-CALL GET_HALO(ZFNEG, HDIR="Z0_X", HNAME='ZFNEG') ! JUAN
-!$acc update device(ZFNEG)
+! acc update self(ZFNEG)
+!CALL GET_HALO_D(ZFNEG, HDIR="Z0_X", HNAME='ZFNEG') ! JUAN
+! acc update device(ZFNEG)
 #endif
 !
 !$acc kernels
@@ -3039,7 +3039,7 @@ IF ( L2D ) THEN
   CALL MPPDB_CHECK(PR,"PPM_S0_Y end:PR")
 !   RETURN
 ELSE !not L2D
-!
+   !   
 CALL GET_HALO2(PSRC, TZ_PSRC_HALO2_ll, HNAME='PSRC')
 ZPSRC_HALO2_SOUTH(:,:) = TZ_PSRC_HALO2_ll%HALO2%SOUTH(:,:)
 !$acc update device (ZPSRC_HALO2_SOUTH)
@@ -3150,9 +3150,9 @@ CASE ('OPEN')
 #ifndef MNH_OPENACC
 CALL  GET_HALO(ZPHAT, HNAME='ZPHAT')
 #else
-!$acc update self(ZPHAT)
-CALL  GET_HALO(ZPHAT(:,:,:), HDIR="Z0_Y", HNAME='ZPHAT')
-!$acc update device(ZPHAT)
+! acc update self(ZPHAT)
+!CALL  GET_HALO_D(ZPHAT(:,:,:), HDIR="Z0_Y", HNAME='ZPHAT')
+! acc update device(ZPHAT)
 #endif
 !
 !$acc kernels
@@ -3187,9 +3187,9 @@ CALL  GET_HALO(ZPHAT(:,:,:), HDIR="Z0_Y", HNAME='ZPHAT')
 #ifndef MNH_OPENACC
 CALL GET_HALO(ZFPOS, HNAME='ZFPOS') ! JUAN
 #else
-!$acc update self(ZFPOS)
-CALL GET_HALO(ZFPOS(:,:,:), HDIR="Z0_Y", HNAME='ZFPOS') ! JUAN
-!$acc update device(ZFPOS)
+! acc update self(ZFPOS)
+!CALL GET_HALO_D(ZFPOS(:,:,:), HDIR="Z0_Y", HNAME='ZFPOS') ! JUAN
+! acc update device(ZFPOS)
 #endif
 !
 !$acc kernels
@@ -3216,9 +3216,9 @@ CALL GET_HALO(ZFPOS(:,:,:), HDIR="Z0_Y", HNAME='ZFPOS') ! JUAN
 #ifndef MNH_OPENACC
    CALL GET_HALO(ZFNEG, HNAME='ZFNEG') ! JUAN
 #else
-!$acc update self(ZFNEG)
-   CALL GET_HALO(ZFNEG, HDIR="Z0_Y", HNAME='ZFNEG') ! JUAN
-!$acc update device(ZFNEG)
+! acc update self(ZFNEG)
+!   CALL GET_HALO_D(ZFNEG, HDIR="Z0_Y", HNAME='ZFNEG') ! JUAN
+! acc update device(ZFNEG)
 #endif
 !
 !$acc kernels
diff --git a/src/MNH/ppm_met.f90 b/src/MNH/ppm_met.f90
index f9f2d3e6c88d45055141df3efaa9c99bb350780b..76cebf49b03a496a32f8a592b08912b71ba6770e 100644
--- a/src/MNH/ppm_met.f90
+++ b/src/MNH/ppm_met.f90
@@ -170,7 +170,7 @@ END IF
 !*       1.     COMPUTES THE DOMAIN DIMENSIONS
 !               ------------------------------
 !
-GTKEALLOC = SIZE(PTKET,1) /= 0
+GTKEALLOC = SIZE(PTKET) /= 0
 !
 !-------------------------------------------------------------------------------
 !
diff --git a/src/MNH/prandtl.f90 b/src/MNH/prandtl.f90
index 9442f71eb20b9b0ecad3ac894793d7dd0d7c80ed..ebe407a91ff106f5a3848955f86c1fe4e8176757 100644
--- a/src/MNH/prandtl.f90
+++ b/src/MNH/prandtl.f90
@@ -73,8 +73,6 @@ END INTERFACE
 !
 END MODULE MODI_PRANDTL
 !
-!
-!
 !     ###########################################################
       SUBROUTINE PRANDTL(KKA,KKU,KKL,KRR,KRRI,OTURB_DIAG,      &
                          HTURBDIM,                             &
@@ -220,6 +218,11 @@ USE MODI_SHUMAN
 USE MODI_SHUMAN_DEVICE
 #endif
 !
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, &
+      MNH_CHECK_IN_ZT3D,MNH_CHECK_OUT_ZT3D
+#endif
+!
 IMPLICIT NONE
 !
 !
@@ -272,7 +275,11 @@ REAL, DIMENSION(:,:,:), INTENT(OUT)  ::  PEMOIST ! coefficient E_moist
 !
 !       0.2  declaration of local variables
 !
-REAL, DIMENSION(:,:,:), allocatable :: ZW1, ZW2 ! work arrays
+REAL, DIMENSION(:,:,:),  pointer , contiguous :: ZW1
+REAL, DIMENSION(:,:,:),  pointer , contiguous :: ZW2 ! work arrays
+#ifdef MNH_OPENACC
+INTEGER                                      :: IZW1, IZW2
+#endif
 !                                                     
 INTEGER :: IKB      ! vertical index value for the first inner mass point
 INTEGER :: IKE      ! vertical index value for the last inner mass point
@@ -283,13 +290,17 @@ INTEGER :: JLOOP
 REAL    :: ZMINVAL
 !
 #ifdef MNH_OPENACC
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP2_DEVICE
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP3_DEVICE
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP4_DEVICE
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP5_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP2_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP3_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP4_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP5_DEVICE
+INTEGER   :: IZTMP1_DEVICE,IZTMP2_DEVICE,IZTMP3_DEVICE,IZTMP4_DEVICE,IZTMP5_DEVICE
 #endif
 TYPE(TFIELDDATA)  :: TZFIELD
+!
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ,JK
 ! ---------------------------------------------------------------------------
 
 !$acc data present( PDXX, PDYY, PDZZ, PDZX, PDZY,                                               &
@@ -318,18 +329,28 @@ if ( mppdb_initialized ) then
   call Mppdb_check( psrcm,     "Prandtl beg:psrcm"     )
 end if
 
-allocate( zw1(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zw2(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
+JIU =  size( pthlm, 1 )
+JJU =  size( pthlm, 2 )
+JKU =  size( pthlm, 3 )
+
+#ifndef MNH_OPENACC
+allocate( zw1(JIU,JJU,JKU ) )
+allocate( zw2(JIU,JJU,JKU ) )
+#else
+CALL MNH_CHECK_IN_ZT3D("PRANDTL")
+izw1 = MNH_ALLOCATE_ZT3D( zw1, JIU,JJU,JKU )
+izw2 = MNH_ALLOCATE_ZT3D( zw2, JIU,JJU,JKU )
+#endif
 
 #ifdef MNH_OPENACC
-allocate( ztmp1_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp2_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp3_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp4_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp5_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device, JIU,JJU,JKU )
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device, JIU,JJU,JKU )
+iztmp3_device = MNH_ALLOCATE_ZT3D( ztmp3_device, JIU,JJU,JKU )
+iztmp4_device = MNH_ALLOCATE_ZT3D( ztmp4_device, JIU,JJU,JKU )
+iztmp5_device = MNH_ALLOCATE_ZT3D( ztmp5_device, JIU,JJU,JKU )
 #endif
 
-!$acc data create( zw1, zw2, ztmp1_device, ztmp2_device, ztmp3_device, ztmp4_device, ztmp5_device )
+!$acc data present( zw1, zw2, ztmp1_device, ztmp2_device, ztmp3_device, ztmp4_device, ztmp5_device )
 
 !
 !*      1.  DEFAULT VALUES,  1D REDELSPERGER NUMBERS 
@@ -396,17 +417,17 @@ ELSE
   IF (KRR /= 0) THEN                ! moist case
     CALL GZ_M_W_DEVICE(KKA,KKU,KKL,PTHLM,PDZZ,ZTMP1_DEVICE)
 !$acc kernels async
-    PREDTH1(:,:,:)= XCTV*PBLL_O_E(:,:,:) * PETHETA(:,:,:) * ZTMP1_DEVICE
+    PREDTH1(:,:,:)= XCTV*PBLL_O_E(:,:,:) * PETHETA(:,:,:) * ZTMP1_DEVICE(:,:,:)
 !$acc end kernels  
     CALL GZ_M_W_DEVICE(KKA,KKU,KKL,PRM(:,:,:,1),PDZZ,ZTMP2_DEVICE)
 !$acc kernels async
-    PREDR1(:,:,:) = XCTV*PBLL_O_E(:,:,:) * PEMOIST(:,:,:) * ZTMP2_DEVICE
+    PREDR1(:,:,:) = XCTV*PBLL_O_E(:,:,:) * PEMOIST(:,:,:) * ZTMP2_DEVICE(:,:,:)
 !$acc end kernels  
 !$acc wait
   ELSE                              ! dry case
     CALL GZ_M_W_DEVICE(KKA,KKU,KKL,PTHLM,PDZZ,ZTMP1_DEVICE)
 !$acc kernels
-    PREDTH1(:,:,:)= XCTV*PBLL_O_E(:,:,:)  * ZTMP1_DEVICE
+    PREDTH1(:,:,:)= XCTV*PBLL_O_E(:,:,:)  * ZTMP1_DEVICE(:,:,:)
     PREDR1(:,:,:) = 0.
 !$acc end kernels
   END IF
@@ -416,48 +437,66 @@ END IF
 !       3. Limits on 1D Redelperger numbers
 !          --------------------------------
 !
-!$acc kernels
 ZMINVAL = (1.-1./XPHI_LIM)
 !
-ZW1 = 1.
-ZW2 = 1.
-!
-WHERE (PREDTH1+PREDR1<-ZMINVAL)
-  ZW1 = (-ZMINVAL) / (PREDTH1+PREDR1)
+!$acc kernels
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZW1(JI,JJ,JK) = 1.
+   ZW2(JI,JJ,JK) = 1.
+END DO
+
+WHERE (PREDTH1(:,:,:)+PREDR1(:,:,:) < -ZMINVAL)
+  ZW1(:,:,:) = (-ZMINVAL) / (PREDTH1(:,:,:)+PREDR1(:,:,:))
 END WHERE
-!
-WHERE (PREDTH1<-ZMINVAL)
-  ZW2 = (-ZMINVAL) / (PREDTH1)
+
+WHERE (PREDTH1(:,:,:) < -ZMINVAL)
+  ZW2(:,:,:) = (-ZMINVAL) / (PREDTH1(:,:,:))
 END WHERE
-ZW2 = MIN(ZW1,ZW2)
-!
-ZW1 = 1.
-WHERE (PREDR1<-ZMINVAL)
-  ZW1 = (-ZMINVAL) / (PREDR1)
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZW2(JI,JJ,JK) = MIN( ZW1(JI,JJ,JK),ZW2(JI,JJ,JK) )
+END DO
+
+ZW1(:,:,:) = 1.
+WHERE (PREDR1(:,:,:)<-ZMINVAL)
+  ZW1(:,:,:) = (-ZMINVAL) / (PREDR1(:,:,:))
 END WHERE
-ZW1 = MIN(ZW2,ZW1)
+
+!!$ZW1(:,:,:) = MIN(ZW2(:,:,:),ZW1(:,:,:))
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZW1(JI,JJ,JK) = MIN( ZW2(JI,JJ,JK),ZW1(JI,JJ,JK) )
+END DO
 !
+!$acc end kernels
 !
 !       3. Modification of Mixing length and dissipative length
 !          ----------------------------------------------------
 !
-PBLL_O_E(:,:,:) = PBLL_O_E(:,:,:) * ZW1(:,:,:)
-PREDTH1 (:,:,:) = PREDTH1 (:,:,:) * ZW1(:,:,:)
-PREDR1  (:,:,:) = PREDR1  (:,:,:) * ZW1(:,:,:)
+!$acc kernels
+!
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   PBLL_O_E(JI,JJ,JK) = PBLL_O_E(JI,JJ,JK) * ZW1(JI,JJ,JK)
+   PREDTH1 (JI,JJ,JK) = PREDTH1 (JI,JJ,JK) * ZW1(JI,JJ,JK)
+   PREDR1  (JI,JJ,JK) = PREDR1  (JI,JJ,JK) * ZW1(JI,JJ,JK)
+END DO !CONCURRENT
 !
 !       4. Threshold for very small (in absolute value) Redelperger numbers
 !          ----------------------------------------------------------------
 !
-ZW2=SIGN(1.,PREDTH1(:,:,:))
+ZW2(:,:,:)=SIGN(1.,PREDTH1(:,:,:))
 PREDTH1(:,:,:)= ZW2(:,:,:) * MAX(XMNH_TINY_12, ZW2(:,:,:)*PREDTH1(:,:,:))
+!$acc end kernels
 !
 IF (.NOT.LOCEAN) THEN
   IF (KRR /= 0) THEN                ! dry case
+!$acc kernels
     ZW2=SIGN(1.,PREDR1(:,:,:))
     PREDR1(:,:,:)= ZW2(:,:,:) * MAX(XMNH_TINY_12, ZW2(:,:,:)*PREDR1(:,:,:))
+!$acc end kernels
   END IF
 END IF
-!$acc end kernels
+
 !
 !---------------------------------------------------------------------------
 !
@@ -471,14 +510,14 @@ END DO
 DO JSV=1,ISV
   CALL GZ_M_W_DEVICE(KKA,KKU,KKL,PSVM(:,:,:,JSV),PDZZ,ZTMP1_DEVICE)
 !$acc kernels
-  PREDS1(:,:,:,JSV)=XCTV*PBLL_O_E(:,:,:)*ZTMP1_DEVICE
+  PREDS1(:,:,:,JSV)=XCTV*PBLL_O_E(:,:,:)*ZTMP1_DEVICE(:,:,:)
 !$acc end kernels
 END DO
 #endif
 !
 !$acc kernels
 DO JSV=1,ISV
-  ZW2=SIGN(1.,PREDS1(:,:,:,JSV))
+  ZW2(:,:,:)=SIGN(1.,PREDS1(:,:,:,JSV))
   PREDS1(:,:,:,JSV)= ZW2(:,:,:) * MAX(XMNH_TINY_12, ZW2(:,:,:)*PREDS1(:,:,:,JSV))
 END DO
 !$acc end kernels
@@ -490,7 +529,7 @@ END DO
 !
 IF(HTURBDIM=='1DIM') THEN        ! 1D case
 !
-!$acc kernels async
+!$acc kernels ! async
 #ifndef MNH_BITREP
   PRED2TH3(:,:,:)  = PREDTH1(:,:,:)**2
 #else
@@ -498,7 +537,7 @@ IF(HTURBDIM=='1DIM') THEN        ! 1D case
 #endif
 !$acc end kernels
 !
-!$acc kernels async
+!$acc kernels ! async
 #ifndef MNH_BITREP
   PRED2R3(:,:,:)   = PREDR1(:,:,:) **2
 #else
@@ -506,10 +545,10 @@ IF(HTURBDIM=='1DIM') THEN        ! 1D case
 #endif
 !$acc end kernels
 !
-!$acc kernels async
+!$acc kernels ! async
   PRED2THR3(:,:,:) = PREDTH1(:,:,:) * PREDR1(:,:,:)
 !$acc end kernels
-!$acc wait
+! acc wait
 !
 ELSE IF (L2D) THEN                      ! 3D case in a 2D model
 !
@@ -527,17 +566,27 @@ ELSE IF (L2D) THEN                      ! 3D case in a 2D model
     CALL GX_M_M_DEVICE(KKA,KKU,KKL,PTHLM,PDXX,PDZZ,PDZX,ZTMP1_DEVICE)
 !$acc kernels
 #ifndef MNH_BITREP
-    ZTMP1_DEVICE = ZTMP1_DEVICE**2
+!$acc loop independent collapse(3)    
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)    
+      ZTMP1_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK)**2
+    END DO !CONCURRENT   
 #else
-    ZTMP1_DEVICE = BR_P2(ZTMP1_DEVICE)
+!$acc loop independent collapse(3)    
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)    
+      ZTMP1_DEVICE(JI,JJ,JK) = BR_P2(ZTMP1_DEVICE(JI,JJ,JK))
+    END DO !CONCURRENT   
 #endif
 !$acc end kernels
     CALL MZM_DEVICE(ZTMP1_DEVICE,ZTMP2_DEVICE )
-!$acc kernels async
+!$acc kernels ! async
 #ifndef MNH_BITREP
-    PRED2TH3(:,:,:)= PREDTH1(:,:,:)**2+(XCTV*PBLL_O_E(:,:,:)*PETHETA(:,:,:) )**2 * ZTMP2_DEVICE
+    PRED2TH3(:,:,:) = PREDTH1(:,:,:)**2 &
+                                + (XCTV*PBLL_O_E(:,:,:)*PETHETA(:,:,:) )**2 &
+                                * ZTMP2_DEVICE(:,:,:)
 #else
-    PRED2TH3(:,:,:)= BR_P2(PREDTH1(:,:,:))+BR_P2(XCTV*PBLL_O_E(:,:,:)*PETHETA(:,:,:) ) * ZTMP2_DEVICE
+    PRED2TH3(:,:,:) = BR_P2(PREDTH1(:,:,:)) &
+                                + BR_P2(XCTV*PBLL_O_E(:,:,:)*PETHETA(:,:,:) ) &
+                                * ZTMP2_DEVICE(:,:,:)
 #endif
     PRED2TH3(:,:,IKB)=PRED2TH3(:,:,IKB+KKL)
 !$acc end kernels
@@ -545,28 +594,40 @@ ELSE IF (L2D) THEN                      ! 3D case in a 2D model
 !
 #ifndef MNH_OPENACC
 #ifndef MNH_BITREP
-    PRED2R3(:,:,:)= PREDR1(:,:,:)**2 + (XCTV*PBLL_O_E(:,:,:)*PEMOIST(:,:,:))**2 * &
-        MZM( GX_M_M(PRM(:,:,:,1),PDXX,PDZZ,PDZX)**2 )
+    PRED2R3(:,:,:) = PREDR1(:,:,:)**2  &
+                               + (XCTV*PBLL_O_E(:,:,:)*PEMOIST(:,:,:))**2 &
+                               * MZM( GX_M_M(PRM(:,:,:,1),PDXX,PDZZ,PDZX)**2 )
 #else
-    PRED2R3(:,:,:)= BR_P2(PREDR1(:,:,:)) + BR_P2(XCTV*PBLL_O_E(:,:,:)*PEMOIST(:,:,:)) * &
-        MZM( BR_P2(GX_M_M(PRM(:,:,:,1),PDXX,PDZZ,PDZX)) )
+    PRED2R3(:,:,:) = BR_P2(PREDR1(:,:,:)) &
+                               + BR_P2(XCTV*PBLL_O_E(:,:,:)*PEMOIST(:,:,:)) &
+                               * MZM( BR_P2(GX_M_M(PRM(:,:,:,1),PDXX,PDZZ,PDZX)) )
 #endif
     PRED2R3(:,:,IKB)=PRED2R3(:,:,IKB+KKL)
 #else
     CALL GX_M_M_DEVICE(KKA,KKU,KKL,PRM(:,:,:,1),PDXX,PDZZ,PDZX,ZTMP1_DEVICE)
 !$acc kernels
 #ifndef MNH_BITREP
-    ZTMP1_DEVICE = ZTMP1_DEVICE**2
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP1_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK)**2
+    END DO !CONCURRENT   
 #else
-    ZTMP1_DEVICE = BR_P2(ZTMP1_DEVICE)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP1_DEVICE(JI,JJ,JK) = BR_P2(ZTMP1_DEVICE(JI,JJ,JK))
+    END DO !CONCURRENT   
 #endif
 !$acc end kernels
     CALL MZM_DEVICE(ZTMP1_DEVICE,ZTMP2_DEVICE )
-!$acc kernels async
+!$acc kernels ! async
 #ifndef MNH_BITREP
-    PRED2R3(:,:,:)= PREDR1(:,:,:)**2 + (XCTV*PBLL_O_E(:,:,:)*PEMOIST(:,:,:))**2 * ZTMP2_DEVICE
+    PRED2R3(:,:,:) = PREDR1(:,:,:)**2 &
+                               + (XCTV*PBLL_O_E(:,:,:)*PEMOIST(:,:,:))**2 &
+                               * ZTMP2_DEVICE(:,:,:)
 #else
-    PRED2R3(:,:,:)= BR_P2(PREDR1(:,:,:)) + BR_P2(XCTV*PBLL_O_E(:,:,:)*PEMOIST(:,:,:)) * ZTMP2_DEVICE
+    PRED2R3(:,:,:) = BR_P2(PREDR1(:,:,:)) &
+                               + BR_P2(XCTV*PBLL_O_E(:,:,:)*PEMOIST(:,:,:)) &
+                               * ZTMP2_DEVICE(:,:,:)
 #endif
     PRED2R3(:,:,IKB)=PRED2R3(:,:,IKB+KKL)
 !$acc end kernels
@@ -574,9 +635,11 @@ ELSE IF (L2D) THEN                      ! 3D case in a 2D model
 !
 #ifndef MNH_OPENACC
 #ifndef MNH_BITREP
-    PRED2THR3(:,:,:)= PREDR1(:,:,:) * PREDTH1(:,:,:) +  XCTV**2*PBLL_O_E(:,:,:)**2 *   &
+    PRED2THR3(:,:,:) = PREDR1(:,:,:) * PREDTH1(:,:,:) &
+                                 +  XCTV**2*PBLL_O_E(:,:,:)**2 *   &
 #else
-    PRED2THR3(:,:,:)= PREDR1(:,:,:) * PREDTH1(:,:,:) +  BR_P2(XCTV)*BR_P2(PBLL_O_E(:,:,:)) *   &
+                                 PRED2THR3(:,:,:) = PREDR1(:,:,:) * PREDTH1(:,:,:) &
+                                 +  BR_P2(XCTV)*BR_P2(PBLL_O_E(:,:,:)) *   &
 #endif
                   PEMOIST(:,:,:) * PETHETA(:,:,:) *                         &
       MZM( GX_M_M(PRM(:,:,:,1),PDXX,PDZZ,PDZX)*     &
@@ -586,19 +649,28 @@ ELSE IF (L2D) THEN                      ! 3D case in a 2D model
     CALL GX_M_M_DEVICE(KKA,KKU,KKL,PRM(:,:,:,1),PDXX,PDZZ,PDZX,ZTMP1_DEVICE)
     CALL GX_M_M_DEVICE(KKA,KKU,KKL,PTHLM       ,PDXX,PDZZ,PDZX,ZTMP2_DEVICE)
 !$acc kernels
-    ZTMP1_DEVICE = ZTMP1_DEVICE * ZTMP2_DEVICE
+!$acc loop independent collapse(3)    
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)    
+      ZTMP1_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * ZTMP2_DEVICE(JI,JJ,JK)
+    END DO
 !$acc end kernels
     CALL MZM_DEVICE(ZTMP1_DEVICE,ZTMP2_DEVICE)
-!$acc kernels async
+!$acc kernels ! async
 #ifndef MNH_BITREP
-    PRED2THR3(:,:,:)= PREDR1(:,:,:) * PREDTH1(:,:,:) +  XCTV**2*PBLL_O_E(:,:,:)**2 *   &
+    PRED2THR3(:,:,:)= PREDR1(:,:,:) * PREDTH1(:,:,:) &
+                                + XCTV**2*PBLL_O_E(:,:,:)**2   &
+                                * PEMOIST(:,:,:) * PETHETA(:,:,:) &
+                                * ZTMP2_DEVICE(:,:,:)
 #else
-    PRED2THR3(:,:,:)= PREDR1(:,:,:) * PREDTH1(:,:,:) +  BR_P2(XCTV)*BR_P2(PBLL_O_E(:,:,:)) *   &
-#endif
-                  PEMOIST(:,:,:) * PETHETA(:,:,:) * ZTMP2_DEVICE
+!$acc loop independent collapse(3)    
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)           
+      PRED2THR3(JI,JJ,JK)= PREDR1(JI,JJ,JK) * PREDTH1(JI,JJ,JK) +  BR_P2(XCTV)*BR_P2(PBLL_O_E(JI,JJ,JK)) *   &
+           PEMOIST(JI,JJ,JK) * PETHETA(JI,JJ,JK) * ZTMP2_DEVICE(JI,JJ,JK)
+    END DO
+#endif                
     PRED2THR3(:,:,IKB)=PRED2THR3(:,:,IKB+KKL)
 !$acc end kernels
-!$acc wait
+! acc wait
 #endif
 !
   ELSE                 ! dry 3D case in a 2D model
@@ -618,17 +690,23 @@ call Print_msg( NVERB_WARNING, 'GEN', 'PRANDTL', 'OpenACC: L2D=.T. and KRR=0 not
     CALL GX_M_M_DEVICE(KKA,KKU,KKL,PTHLM,PDXX,PDZZ,PDZX,ZTMP1_DEVICE)
 !$acc kernels
 #ifndef MNH_BITREP
-    ZTMP1_DEVICE = ZTMP1_DEVICE**2
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP1_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK)**2
+    END DO !CONCURRENT 
 #else
-    ZTMP1_DEVICE = BR_P2(ZTMP1_DEVICE)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP1_DEVICE(JI,JJ,JK) = BR_P2(ZTMP1_DEVICE(JI,JJ,JK))
+    END DO !CONCURRENT 
 #endif
 !$acc end kernels
     CALL MZM_DEVICE(ZTMP1_DEVICE,ZTMP2_DEVICE)
 !$acc kernels
 #ifndef MNH_BITREP
-    PRED2TH3(:,:,:) = PREDTH1(:,:,:)**2 +  XCTV**2*PBLL_O_E(:,:,:)**2 * ZTMP2_DEVICE
+    PRED2TH3(:,:,:) = PREDTH1(:,:,:)**2 +  XCTV**2*PBLL_O_E(:,:,:)**2 * &
+                                  ZTMP2_DEVICE(:,:,:)
 #else
-    PRED2TH3(:,:,:) = BR_P2(PREDTH1(:,:,:)) +  BR_P2(XCTV)*BR_P2(PBLL_O_E(:,:,:)) * ZTMP2_DEVICE
+    PRED2TH3(:,:,:) = BR_P2(PREDTH1(:,:,:)) +  BR_P2(XCTV)*BR_P2(PBLL_O_E(:,:,:)) * &
+                                  ZTMP2_DEVICE(:,:,:)
 #endif
 !PW: merge kernels + remove async to prevent compiler crash...(bug PGI 19.10)
 ! !$acc end kernels
@@ -653,13 +731,15 @@ ELSE                                 ! 3D case in a 3D model
   IF (KRR /= 0) THEN                 ! moist 3D case
 #ifndef MNH_OPENACC
 #ifndef MNH_BITREP
-    PRED2TH3(:,:,:)= PREDTH1(:,:,:)**2 +  ( XCTV*PBLL_O_E(:,:,:)*PETHETA(:,:,:) )**2 * &
-      MZM( GX_M_M(PTHLM,PDXX,PDZZ,PDZX)**2 &
-      + GY_M_M(PTHLM,PDYY,PDZZ,PDZY)**2 )
+     PRED2TH3(:,:,:) = PREDTH1(:,:,:)**2  &
+                                 +  ( XCTV*PBLL_O_E(:,:,:)*PETHETA(:,:,:) )**2 &
+                                 *  MZM( GX_M_M(PTHLM,PDXX,PDZZ,PDZX)**2 &
+                                 +  GY_M_M(PTHLM,PDYY,PDZZ,PDZY)**2 )
 #else
-    PRED2TH3(:,:,:)= BR_P2(PREDTH1(:,:,:)) +  BR_P2( XCTV*PBLL_O_E(:,:,:)*PETHETA(:,:,:) ) * &
-      MZM( BR_P2(GX_M_M(PTHLM,PDXX,PDZZ,PDZX)) &
-      + BR_P2(GY_M_M(PTHLM,PDYY,PDZZ,PDZY)) )
+     PRED2TH3(:,:,:) = BR_P2(PREDTH1(:,:,:)) &
+                                 +  BR_P2( XCTV*PBLL_O_E(:,:,:)*PETHETA(:,:,:) ) &
+                                 *  MZM( BR_P2(GX_M_M(PTHLM,PDXX,PDZZ,PDZX)) &
+                                 +  BR_P2(GY_M_M(PTHLM,PDYY,PDZZ,PDZY)) )
 #endif
     PRED2TH3(:,:,IKB)=PRED2TH3(:,:,IKB+KKL)
 #else
@@ -667,17 +747,27 @@ ELSE                                 ! 3D case in a 3D model
     CALL GY_M_M_DEVICE(KKA,KKU,KKL,PTHLM,PDYY,PDZZ,PDZY,ZTMP2_DEVICE)
 !$acc kernels
 #ifndef MNH_BITREP
-    ZTMP1_DEVICE = ZTMP1_DEVICE**2 + ZTMP2_DEVICE**2
+!$acc loop independent collapse(3)    
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)    
+      ZTMP1_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK)**2 + ZTMP2_DEVICE(JI,JJ,JK)**2
+    END DO
 #else
-    ZTMP1_DEVICE = BR_P2(ZTMP1_DEVICE) + BR_P2(ZTMP2_DEVICE)
+!$acc loop independent collapse(3)    
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)    
+      ZTMP1_DEVICE(JI,JJ,JK) = BR_P2(ZTMP1_DEVICE(JI,JJ,JK)) + BR_P2(ZTMP2_DEVICE(JI,JJ,JK))
+    END DO
 #endif
 !$acc end kernels
     CALL MZM_DEVICE(ZTMP1_DEVICE,ZTMP2_DEVICE)
 !$acc kernels
 #ifndef MNH_BITREP
-    PRED2TH3(:,:,:)= PREDTH1(:,:,:)**2 +  ( XCTV*PBLL_O_E(:,:,:)*PETHETA(:,:,:) )**2 * ZTMP2_DEVICE
+    PRED2TH3(:,:,:) = PREDTH1(:,:,:)**2 &
+                                +  ( XCTV*PBLL_O_E(:,:,:)*PETHETA(:,:,:) )**2 &
+                                *   ZTMP2_DEVICE(:,:,:)
 #else
-    PRED2TH3(:,:,:)= BR_P2(PREDTH1(:,:,:)) +  BR_P2( XCTV*PBLL_O_E(:,:,:)*PETHETA(:,:,:) ) * ZTMP2_DEVICE
+    PRED2TH3(:,:,:) = BR_P2(PREDTH1(:,:,:)) &
+                                + BR_P2( XCTV*PBLL_O_E(:,:,:)*PETHETA(:,:,:) ) &
+                                * ZTMP2_DEVICE(:,:,:)
 #endif
     PRED2TH3(:,:,IKB)=PRED2TH3(:,:,IKB+KKL)
 !$acc end kernels
@@ -685,13 +775,15 @@ ELSE                                 ! 3D case in a 3D model
 !
 #ifndef MNH_OPENACC
 #ifndef MNH_BITREP
-    PRED2R3(:,:,:)= PREDR1(:,:,:)**2 + (XCTV*PBLL_O_E(:,:,:)*PEMOIST(:,:,:))**2 *      &
-        MZM( GX_M_M(PRM(:,:,:,1),PDXX,PDZZ,PDZX)**2 + &
-        GY_M_M(PRM(:,:,:,1),PDYY,PDZZ,PDZY)**2 )
+    PRED2R3(:,:,:) = PREDR1(:,:,:)**2 &
+                               + (XCTV*PBLL_O_E(:,:,:)*PEMOIST(:,:,:))**2 &
+                               * MZM( GX_M_M(PRM(:,:,:,1),PDXX,PDZZ,PDZX)**2  &
+                               + GY_M_M(PRM(:,:,:,1),PDYY,PDZZ,PDZY)**2 )
 #else
-    PRED2R3(:,:,:)= BR_P2(PREDR1(:,:,:)) + BR_P2(XCTV*PBLL_O_E(:,:,:)*PEMOIST(:,:,:)) *      &
-        MZM( BR_P2(GX_M_M(PRM(:,:,:,1),PDXX,PDZZ,PDZX)) + &
-        BR_P2(GY_M_M(PRM(:,:,:,1),PDYY,PDZZ,PDZY)) )
+    PRED2R3(:,:,:) = BR_P2(PREDR1(:,:,:)) &
+                               + BR_P2(XCTV*PBLL_O_E(:,:,:)*PEMOIST(:,:,:)) &
+                               * MZM( BR_P2(GX_M_M(PRM(:,:,:,1),PDXX,PDZZ,PDZX)) &
+                               +BR_P2(GY_M_M(PRM(:,:,:,1),PDYY,PDZZ,PDZY)) )
 #endif
     PRED2R3(:,:,IKB)=PRED2R3(:,:,IKB+KKL)
 #else
@@ -699,31 +791,43 @@ ELSE                                 ! 3D case in a 3D model
     CALL GY_M_M_DEVICE(KKA,KKU,KKL,PRM(:,:,:,1),PDYY,PDZZ,PDZY,ZTMP2_DEVICE)
 !$acc kernels
 #ifndef MNH_BITREP
-    ZTMP1_DEVICE = ZTMP1_DEVICE**2 + ZTMP2_DEVICE**2
+!$acc loop independent collapse(3)    
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)    
+      ZTMP1_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK)**2 + ZTMP2_DEVICE(JI,JJ,JK)**2
+    END DO   
 #else
-    ZTMP1_DEVICE = BR_P2(ZTMP1_DEVICE) + BR_P2(ZTMP2_DEVICE)
+!$acc loop independent collapse(3)    
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)    
+      ZTMP1_DEVICE(JI,JJ,JK) = BR_P2(ZTMP1_DEVICE(JI,JJ,JK)) + BR_P2(ZTMP2_DEVICE(JI,JJ,JK))
+    END DO   
 #endif
 !$acc end kernels
     CALL MZM_DEVICE(ZTMP1_DEVICE,ZTMP2_DEVICE)
 !$acc kernels
 #ifndef MNH_BITREP
-    PRED2R3(:,:,:)= PREDR1(:,:,:)**2 + (XCTV*PBLL_O_E(:,:,:)*PEMOIST(:,:,:))**2 * ZTMP2_DEVICE
+    PRED2R3(:,:,:) = PREDR1(:,:,:)**2 &
+                               + (XCTV*PBLL_O_E(:,:,:)*PEMOIST(:,:,:))**2 &
+                               *  ZTMP2_DEVICE(:,:,:)
 #else
-    PRED2R3(:,:,:)= BR_P2(PREDR1(:,:,:)) + BR_P2(XCTV*PBLL_O_E(:,:,:)*PEMOIST(:,:,:)) * ZTMP2_DEVICE
+    PRED2R3(:,:,:) = BR_P2(PREDR1(:,:,:)) &
+                               + BR_P2(XCTV*PBLL_O_E(:,:,:)*PEMOIST(:,:,:)) &
+                               * ZTMP2_DEVICE(:,:,:)
 #endif
 !$acc end kernels
-!$acc kernels async
+!$acc kernels ! async
     PRED2R3(:,:,IKB)=PRED2R3(:,:,IKB+KKL)
 !$acc end kernels
 #endif
 !
 #ifndef MNH_OPENACC
 #ifndef MNH_BITREP
-    PRED2THR3(:,:,:)= PREDR1(:,:,:) * PREDTH1(:,:,:) +  XCTV**2*PBLL_O_E(:,:,:)**2 *   &
+    PRED2THR3(:,:,:) = PREDR1(:,:,:) * PREDTH1(:,:,:) &
+                                +  XCTV**2*PBLL_O_E(:,:,:)**2 *  &
 #else
-    PRED2THR3(:,:,:)= PREDR1(:,:,:) * PREDTH1(:,:,:) +  BR_P2(XCTV)*BR_P2(PBLL_O_E(:,:,:)) *   &
+                                PRED2THR3(:,:,:) = PREDR1(:,:,:) * PREDTH1(:,:,:) &
+                                +  BR_P2(XCTV)*BR_P2(PBLL_O_E(:,:,:)) * &
 #endif
-         PEMOIST(:,:,:) * PETHETA(:,:,:) *                            &
+         PEMOIST(:,:,:) * PETHETA(:,:,:) *  &
          MZM( GX_M_M(PRM(:,:,:,1),PDXX,PDZZ,PDZX)*   &
          GX_M_M(PTHLM,PDXX,PDZZ,PDZX)+                           &
          GY_M_M(PRM(:,:,:,1),PDYY,PDZZ,PDZY)*                    &
@@ -735,21 +839,27 @@ ELSE                                 ! 3D case in a 3D model
     CALL GY_M_M_DEVICE(KKA,KKU,KKL,PRM(:,:,:,1),PDYY,PDZZ,PDZY,ZTMP3_DEVICE)
     CALL GY_M_M_DEVICE(KKA,KKU,KKL,PTHLM       ,PDYY,PDZZ,PDZY,ZTMP4_DEVICE)
 !$acc kernels
-    ZTMP1_DEVICE = ZTMP1_DEVICE*ZTMP2_DEVICE+ZTMP3_DEVICE*ZTMP4_DEVICE
+!$acc loop independent collapse(3)    
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)    
+      ZTMP1_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK)*ZTMP2_DEVICE(JI,JJ,JK)+ &
+                                      ZTMP3_DEVICE(JI,JJ,JK)*ZTMP4_DEVICE(JI,JJ,JK)
+    END DO    
 !$acc end kernels
     CALL MZM_DEVICE(ZTMP1_DEVICE,ZTMP2_DEVICE)
 !$acc kernels
 #ifndef MNH_BITREP
-    PRED2THR3(:,:,:)= PREDR1(:,:,:) * PREDTH1(:,:,:) +  XCTV**2*PBLL_O_E(:,:,:)**2 *   &
+    PRED2THR3(:,:,:)= PREDR1(:,:,:) * PREDTH1(:,:,:) &
+                                +  XCTV**2*PBLL_O_E(:,:,:)**2 *   &
 #else
-    PRED2THR3(:,:,:)= PREDR1(:,:,:) * PREDTH1(:,:,:) +  BR_P2(XCTV)*BR_P2(PBLL_O_E(:,:,:)) *   &
+    PRED2THR3(:,:,:)= PREDR1(:,:,:) * PREDTH1(:,:,:) &
+                                +  BR_P2(XCTV)*BR_P2(PBLL_O_E(:,:,:)) *   &
 #endif
-         PEMOIST(:,:,:) * PETHETA(:,:,:) * ZTMP2_DEVICE
+         PEMOIST(:,:,:) * PETHETA(:,:,:) * ZTMP2_DEVICE(:,:,:)
 !$acc end kernels
-!$acc kernels async
+!$acc kernels ! async
     PRED2THR3(:,:,IKB)=PRED2THR3(:,:,IKB+KKL)
 !$acc end kernels
-!$acc wait
+! acc wait
 #endif
 !
   ELSE                 ! dry 3D case in a 3D model
@@ -771,32 +881,40 @@ call Print_msg( NVERB_WARNING, 'GEN', 'PRANDTL', 'OpenACC: L2D=.F. and KRR=0 not
     CALL GY_M_M_DEVICE(KKA,KKU,KKL,PTHLM,PDYY,PDZZ,PDZY,ZTMP2_DEVICE)
 !$acc kernels
 #ifndef MNH_BITREP
-    ZTMP1_DEVICE = ZTMP1_DEVICE**2 + ZTMP2_DEVICE**2
+!$acc loop independent collapse(3)    
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)  
+      ZTMP1_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK)**2 + ZTMP2_DEVICE(JI,JJ,JK)**2
+    END DO   
 #else
-    ZTMP1_DEVICE = BR_P2(ZTMP1_DEVICE) + BR_P2(ZTMP2_DEVICE)
+!$acc loop independent collapse(3)    
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)  
+      ZTMP1_DEVICE(JI,JJ,JK) = BR_P2(ZTMP1_DEVICE(JI,JJ,JK)) + BR_P2(ZTMP2_DEVICE(JI,JJ,JK))
+    END DO   
 #endif
 !$acc end kernels
     CALL MZM_DEVICE(ZTMP1_DEVICE,ZTMP2_DEVICE)
 !$acc kernels
 #ifndef MNH_BITREP
-    PRED2TH3(:,:,:) = PREDTH1(:,:,:)**2 +  XCTV**2*PBLL_O_E(:,:,:)**2 * ZTMP2_DEVICE
+    PRED2TH3(:,:,:) = PREDTH1(:,:,:)**2 +  XCTV**2*PBLL_O_E(:,:,:)**2 &
+                                * ZTMP2_DEVICE(:,:,:)
 #else
-    PRED2TH3(:,:,:) = BR_P2(PREDTH1(:,:,:)) +  BR_P2(XCTV)*BR_P2(PBLL_O_E(:,:,:)) * ZTMP2_DEVICE
+    PRED2TH3(:,:,:) = BR_P2(PREDTH1(:,:,:)) +  BR_P2(XCTV)*BR_P2(PBLL_O_E(:,:,:)) &
+                                * ZTMP2_DEVICE(:,:,:)
 #endif
 !$acc end kernels
 #endif
-!$acc kernels async
+!$acc kernels ! async
     PRED2TH3(:,:,IKB)=PRED2TH3(:,:,IKB+KKL)
 !$acc end kernels
 !
-!$acc kernels async
+!$acc kernels ! async
     PRED2R3(:,:,:) = 0.
 !$acc end kernels
 !
-!$acc kernels async
+!$acc kernels ! async
     PRED2THR3(:,:,:) = 0.
 !$acc end kernels
-!$acc wait
+! acc wait
 !
   END IF
 !
@@ -810,16 +928,20 @@ END IF   ! end of the if structure on the turbulence dimensionnality
 !
 IF(HTURBDIM=='1DIM') THEN
 !        1D case
-!$acc kernels
   DO JSV=1,ISV
+    !$acc kernels
     PRED2THS3(:,:,:,JSV)  = PREDS1(:,:,:,JSV) * PREDTH1(:,:,:)
+    !$acc end kernels
     IF (KRR /= 0) THEN
+      !$acc kernels
       PRED2RS3(:,:,:,JSV)   = PREDR1(:,:,:) *PREDS1(:,:,:,JSV)
+      !$acc end kernels
     ELSE
+      !$acc kernels
       PRED2RS3(:,:,:,JSV)   = 0.
+      !$acc end kernels
     END IF
   ENDDO
-!$acc end kernels
 !
 ELSE  IF (L2D) THEN ! 3D case in a 2D model
 !
@@ -857,9 +979,9 @@ ELSE  IF (L2D) THEN ! 3D case in a 2D model
   IF (LOCEAN) THEN
 !$acc kernels
 #ifndef MNH_BITREP
-    ZTMP1_DEVICE = (XG * XALPHAOC *PLM * PLEPS / PTKEM)**2
+    ZTMP1_DEVICE(:,:,:) = (XG * XALPHAOC *PLM * PLEPS / PTKEM)**2
 #else
-    ZTMP1_DEVICE = BR_P2(XG * XALPHAOC *PLM * PLEPS / PTKEM)
+    ZTMP1_DEVICE(:,:,:) = BR_P2(XG * XALPHAOC *PLM * PLEPS / PTKEM)
 #endif
 !$acc end kernels
     CALL MZM_DEVICE(ZTMP1_DEVICE,ZW1)
@@ -872,9 +994,9 @@ ELSE  IF (L2D) THEN ! 3D case in a 2D model
     DO JSV=1,ISV
 !$acc kernels
 #ifndef MNH_BITREP
-      ZTMP1_DEVICE = (XG / PTHVREF * PLM * PLEPS / PTKEM)**2
+      ZTMP1_DEVICE(:,:,:) = (XG / PTHVREF * PLM * PLEPS / PTKEM)**2
 #else
-      ZTMP1_DEVICE = BR_P2(XG / PTHVREF * PLM * PLEPS / PTKEM)
+      ZTMP1_DEVICE(:,:,:) = BR_P2(XG / PTHVREF * PLM * PLEPS / PTKEM)
 #endif
 !$acc end kernels
       CALL MZM_DEVICE(ZTMP1_DEVICE,ZW1)
@@ -895,11 +1017,11 @@ ELSE  IF (L2D) THEN ! 3D case in a 2D model
       CALL GX_M_M_DEVICE(KKA,KKU,KKL,PSVM(:,:,:,JSV),PDXX,PDZZ,PDZX,ZTMP1_DEVICE)
       CALL GX_M_M_DEVICE(KKA,KKU,KKL,PTHLM          ,PDXX,PDZZ,PDZX,ZTMP2_DEVICE)
 !$acc kernels
-      ZTMP1_DEVICE = ZTMP1_DEVICE*ZTMP2_DEVICE
+      ZTMP1_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:)*ZTMP2_DEVICE(:,:,:)
 !$acc end kernels
       CALL MZM_DEVICE(ZTMP1_DEVICE,ZTMP2_DEVICE)
 !$acc kernels
-      PRED2THS3(:,:,:,JSV) = PREDTH1(:,:,:) * PREDS1(:,:,:,JSV) + ZW1 * ZTMP2_DEVICE
+      PRED2THS3(:,:,:,JSV) = PREDTH1(:,:,:) * PREDS1(:,:,:,JSV) + ZW1(:,:,:) * ZTMP2_DEVICE(:,:,:)
 !$acc end kernels
 #endif
 !
@@ -914,12 +1036,12 @@ ELSE  IF (L2D) THEN ! 3D case in a 2D model
         CALL GX_M_M_DEVICE(KKA,KKU,KKL,PSVM(:,:,:,JSV),PDXX,PDZZ,PDZX,ZTMP1_DEVICE)
         CALL GX_M_M_DEVICE(KKA,KKU,KKL,PRM(:,:,:,1)   ,PDXX,PDZZ,PDZX,ZTMP2_DEVICE)
 !$acc kernels
-        ZTMP1_DEVICE = ZTMP1_DEVICE*ZTMP2_DEVICE
+        ZTMP1_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:)*ZTMP2_DEVICE(:,:,:)
 !$acc end kernels
         CALL MZM_DEVICE(ZTMP1_DEVICE,ZTMP2_DEVICE)
 !$acc kernels
         PRED2RS3(:,:,:,JSV) = PREDR1(:,:,:) * PREDS1(:,:,:,JSV)   +        &
-                         ZW1 * PEMOIST * ZTMP2_DEVICE
+                         ZW1(:,:,:) * PEMOIST * ZTMP2_DEVICE(:,:,:)
 !$acc end kernels
 #endif
       ELSE
@@ -951,22 +1073,22 @@ ELSE ! 3D case in a 3D model
   DO JSV=1,ISV
 !$acc kernels
 #ifndef MNH_BITREP
-    ZTMP1_DEVICE = (XG / PTHVREF * PLM * PLEPS / PTKEM)**2
+    ZTMP1_DEVICE(:,:,:) = (XG / PTHVREF * PLM * PLEPS / PTKEM)**2
 #else
-    ZTMP1_DEVICE = BR_P2(XG / PTHVREF * PLM * PLEPS / PTKEM)
+    ZTMP1_DEVICE(:,:,:) = BR_P2(XG / PTHVREF * PLM * PLEPS / PTKEM)
 #endif
 !$acc end kernels
     CALL MZM_DEVICE(ZTMP1_DEVICE,ZW1)
     IF (KRR /= 0) THEN
 !$acc kernels
-      ZW1 = ZW1*PETHETA
+      ZW1(:,:,:) = ZW1(:,:,:)*PETHETA
 !$acc end kernels
     END IF
 #endif
 !
 #ifndef MNH_OPENACC
     PRED2THS3(:,:,:,JSV) = PREDTH1(:,:,:) * PREDS1(:,:,:,JSV)   +        &
-                       ZW1*                                              &
+                       ZW1(:,:,:)*                                              &
                        MZM(GX_M_M(PSVM(:,:,:,JSV),PDXX,PDZZ,PDZX)*       &
                            GX_M_M(PTHLM,PDXX,PDZZ,PDZX)                  &
                           +GY_M_M(PSVM(:,:,:,JSV),PDYY,PDZZ,PDZY)*       &
@@ -978,11 +1100,13 @@ ELSE ! 3D case in a 3D model
     CALL GY_M_M_DEVICE(KKA,KKU,KKL,PSVM(:,:,:,JSV),PDYY,PDZZ,PDZY,ZTMP3_DEVICE)
     CALL GY_M_M_DEVICE(KKA,KKU,KKL,PTHLM          ,PDYY,PDZZ,PDZY,ZTMP4_DEVICE)
 !$acc kernels
-      ZTMP1_DEVICE = ZTMP1_DEVICE*ZTMP2_DEVICE+ZTMP3_DEVICE*ZTMP4_DEVICE
+    ZTMP1_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:)*ZTMP2_DEVICE(:,:,:)+&
+                                      ZTMP3_DEVICE(:,:,:)*ZTMP4_DEVICE(:,:,:)
 !$acc end kernels
       CALL MZM_DEVICE(ZTMP1_DEVICE,ZTMP2_DEVICE)
 !$acc kernels
-    PRED2THS3(:,:,:,JSV) = PREDTH1(:,:,:) * PREDS1(:,:,:,JSV) + ZW1 * ZTMP2_DEVICE
+    PRED2THS3(:,:,:,JSV) = PREDTH1(:,:,:) * PREDS1(:,:,:,JSV) + &
+                           ZW1(:,:,:) * ZTMP2_DEVICE(:,:,:)
 !$acc end kernels
 #endif
 !
@@ -1001,12 +1125,13 @@ ELSE ! 3D case in a 3D model
       CALL GY_M_M_DEVICE(KKA,KKU,KKL,PSVM(:,:,:,JSV),PDYY,PDZZ,PDZY,ZTMP3_DEVICE)
       CALL GY_M_M_DEVICE(KKA,KKU,KKL,PRM(:,:,:,1)   ,PDYY,PDZZ,PDZY,ZTMP4_DEVICE)
 !$acc kernels
-      ZTMP1_DEVICE = ZTMP1_DEVICE*ZTMP2_DEVICE+ZTMP3_DEVICE*ZTMP4_DEVICE
+      ZTMP1_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:)*ZTMP2_DEVICE(:,:,:)+&
+                                        ZTMP3_DEVICE(:,:,:)*ZTMP4_DEVICE(:,:,:)
 !$acc end kernels
       CALL MZM_DEVICE(ZTMP1_DEVICE,ZTMP2_DEVICE)
 !$acc kernels
       PRED2RS3(:,:,:,JSV) = PREDR1(:,:,:) * PREDS1(:,:,:,JSV)   +        &
-                       ZW1 * PEMOIST * ZTMP2_DEVICE
+                       ZW1(:,:,:) * PEMOIST * ZTMP2_DEVICE(:,:,:)
 !$acc end kernels
 #endif
     ELSE
@@ -1109,8 +1234,16 @@ end if
 
 !$acc end data
 
+#ifdef MNH_OPENACC
+CALL MNH_REL_ZT3D(IZW1, IZW2,IZTMP1_DEVICE,IZTMP2_DEVICE,IZTMP3_DEVICE,IZTMP4_DEVICE,IZTMP5_DEVICE)
+CALL MNH_CHECK_OUT_ZT3D("PRANDTL")
+#else
+DEALLOCATE(ZW1,ZW2)
+#endif
+
 !$acc end data
 
 !---------------------------------------------------------------------------
 !
 END SUBROUTINE PRANDTL
+
diff --git a/src/MNH/rain_ice.f90 b/src/MNH/rain_ice.f90
index ddad84fccc481cda99545ccd86bb1f0254cdab33..247faecdba54cfbdef61648118b6fe57151358eb 100644
--- a/src/MNH/rain_ice.f90
+++ b/src/MNH/rain_ice.f90
@@ -254,6 +254,11 @@ use mode_tools_ll,                     only: GET_INDICE_ll
 USE MODI_BITREP
 #endif
 USE MODI_ICE4_RAINFR_VERT
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_ZT1DP , MNH_REL_ZT1D , &
+                            MNH_ALLOCATE_GT3D , MNH_REL_GT3D, &
+                            MNH_ALLOCATE_IT1D , MNH_REL_IT1D
+#endif
 
 IMPLICIT NONE
 !
@@ -332,33 +337,45 @@ INTEGER                           :: IKB,IKTB,IKT  !
 INTEGER                           :: IKE,IKTE      !
 !
 INTEGER                           :: IMICRO
-INTEGER, DIMENSION(:), ALLOCATABLE :: I1,I2,I3 ! Used to replace the COUNT
+INTEGER, DIMENSION(:), POINTER, CONTIGUOUS :: I1,I2,I3 ! Used to replace the COUNT
+#ifdef MNH_OPENACC
+INTEGER :: II1,II2,II3
+#endif
 INTEGER                           :: JL       ! and PACK intrinsics
-LOGICAL, DIMENSION(:,:,:), ALLOCATABLE &
-                                  :: GMICRO ! Test where to compute all processes
+LOGICAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS &
+                                         :: GMICRO ! Test where to compute all processes
+#ifdef MNH_OPENACC
+INTEGER :: IGMICRO
+#endif
 REAL                              :: ZINVTSTEP
 REAL                              :: ZCOEFFRCM
-REAL, DIMENSION(:), ALLOCATABLE   :: ZRVT    ! Water vapor m.r. at t
-REAL, DIMENSION(:), ALLOCATABLE   :: ZRCT    ! Cloud water m.r. at t
-REAL, DIMENSION(:), ALLOCATABLE   :: ZRRT    ! Rain water m.r. at t
-REAL, DIMENSION(:), ALLOCATABLE   :: ZRIT    ! Pristine ice m.r. at t
-REAL, DIMENSION(:), ALLOCATABLE   :: ZRST    ! Snow/aggregate m.r. at t
-REAL, DIMENSION(:), ALLOCATABLE   :: ZRGT    ! Graupel m.r. at t
-REAL, DIMENSION(:), ALLOCATABLE   :: ZRHT    ! Hail m.r. at t
-REAL, DIMENSION(:), ALLOCATABLE   :: ZCIT    ! Pristine ice conc. at t
-!
-REAL, DIMENSION(:), ALLOCATABLE   :: ZRVS    ! Water vapor m.r. source
-REAL, DIMENSION(:), ALLOCATABLE   :: ZRCS    ! Cloud water m.r. source
-REAL, DIMENSION(:), ALLOCATABLE   :: ZRRS    ! Rain water m.r. source
-REAL, DIMENSION(:), ALLOCATABLE   :: ZRIS    ! Pristine ice m.r. source
-REAL, DIMENSION(:), ALLOCATABLE   :: ZRSS    ! Snow/aggregate m.r. source
-REAL, DIMENSION(:), ALLOCATABLE   :: ZRGS    ! Graupel m.r. source
-REAL, DIMENSION(:), ALLOCATABLE   :: ZRHS    ! Hail m.r. source
-REAL, DIMENSION(:), ALLOCATABLE   :: ZTHS    ! Theta source
-REAL, DIMENSION(:), ALLOCATABLE   :: ZTHT    ! Potential temperature
-REAL, DIMENSION(:), ALLOCATABLE   :: ZTHLT   ! Liquid potential temperature
-!
-REAL, DIMENSION(:), ALLOCATABLE   :: ZRHODREF, &      ! RHO Dry REFerence
+REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRVT    ! Water vapor m.r. at t
+REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRCT    ! Cloud water m.r. at t
+REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRRT    ! Rain water m.r. at t
+REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRIT    ! Pristine ice m.r. at t
+REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRST    ! Snow/aggregate m.r. at t
+REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRGT    ! Graupel m.r. at t
+REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRHT    ! Hail m.r. at t
+REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZCIT    ! Pristine ice conc. at t
+#ifdef MNH_OPENACC
+INTEGER :: IZRVT,IZRCT,IZRRT,IZRIT,IZRST,IZRGT,IZRHT,IZCIT
+#endif
+!
+REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRVS    ! Water vapor m.r. source
+REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRCS    ! Cloud water m.r. source
+REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRRS    ! Rain water m.r. source
+REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRIS    ! Pristine ice m.r. source
+REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRSS    ! Snow/aggregate m.r. source
+REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRGS    ! Graupel m.r. source
+REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRHS    ! Hail m.r. source
+REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZTHS    ! Theta source
+REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZTHT    ! Potential temperature
+REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZTHLT   ! Liquid potential temperature
+#ifdef MNH_OPENACC
+INTEGER :: IZRVS,IZRCS,IZRRS,IZRIS,IZRSS,IZRGS,IZRHS,IZTHS,IZTHT,IZTHLT
+#endif
+!
+REAL, DIMENSION(:), POINTER, CONTIGUOUS   :: ZRHODREF, &      ! RHO Dry REFerence
                                      ZRHODJ,   &      ! RHO times Jacobian
                                      ZZT,      &      ! Temperature
                                      ZPRES,    &      ! Pressure
@@ -395,12 +412,27 @@ REAL, DIMENSION(:), ALLOCATABLE   :: ZRHODREF, &      ! RHO Dry REFerence
                                      ZHLC_LRCLOCAL    ! HLCLOUDS : LWC that is Low  LWC local in LCF
                                                       !    note that ZRC/CF = ZHLC_HRCLOCAL+ ZHLC_LRCLOCAL
                                                       !                     = ZHLC_HRC/HCF+ ZHLC_LRC/LCF
-REAL, DIMENSION(:,:),   ALLOCATABLE :: ZZW1 ! Work arrays
-REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZRR, ZRS, ZRG ! work arrays
 #ifdef MNH_OPENACC
-REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZRS_ZERO, ZRG_ZERO ! work arrays filled with zeros
+INTEGER :: IZRHODREF,IZZT,IZPRES,IZEXNREF,IZSIGMA_RC,IZCF,IZRF
+INTEGER :: IZHLC_HCF,IZHLC_LCF,IZHLC_HRC,IZHLC_LRC,IZHLC_RCMAX
+INTEGER :: IZRCRAUTC,IZHLC_HRCLOCAL,IZHLC_LRCLOCAL
+INTEGER :: IZZW,IZLSFACT,IZLVFACT,IZUSW,IZSSI,IZLBDAR,IZLBDAR_RF
+INTEGER :: IZLBDAS,IZLBDAG,IZLBDAH,IZRDRYG,IZRWETG,IZAI,IZCJ
+INTEGER :: IZKA,IZDV,IZRHODJ
+#endif
+
+REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRR, ZRS, ZRG ! work arrays
+#ifdef MNH_OPENACC
+REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRS_ZERO, ZRG_ZERO ! work arrays filled with zeros
 #endif
-REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZT ! Temperature
+REAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZT ! Temperature
+#ifdef MNH_OPENACC
+INTEGER :: IZRR, IZRS, IZRG, IZRS_ZERO, IZRG_ZERO, IZT
+#endif
+
+INTEGER :: IIU,IJU,IKU, IIJKU
+!
+LOGICAl :: GPDF_SIGM
 !
 ! IN variables
 !
@@ -462,18 +494,36 @@ IF ( KRR == 7 ) THEN
 END IF
 #endif
 
+IIU =  size(PEXNREF, 1 )
+IJU =  size(PEXNREF, 2 )
+IKU =  size(PEXNREF, 3 )
+IIJKU = IIU * IJU * IKU
+
+#ifndef MNH_OPENACC
 ALLOCATE( I1(SIZE(PEXNREF)), I2(SIZE(PEXNREF)), I3(SIZE(PEXNREF)) )
-ALLOCATE( GMICRO(SIZE(PEXNREF,1),SIZE(PEXNREF,2),SIZE(PEXNREF,3)) )
-ALLOCATE( ZRR   (SIZE(PEXNREF,1),SIZE(PEXNREF,2),SIZE(PEXNREF,3)) )
-ALLOCATE( ZRS   (SIZE(PEXNREF,1),SIZE(PEXNREF,2),SIZE(PEXNREF,3)) )
-ALLOCATE( ZRG   (SIZE(PEXNREF,1),SIZE(PEXNREF,2),SIZE(PEXNREF,3)) )
-#ifdef MNH_OPENACC
-ALLOCATE( ZRS_ZERO(SIZE(PEXNREF,1),SIZE(PEXNREF,2),SIZE(PEXNREF,3)) )
-ALLOCATE( ZRG_ZERO(SIZE(PEXNREF,1),SIZE(PEXNREF,2),SIZE(PEXNREF,3)) )
+#else
+II1 = MNH_ALLOCATE_IT1D( I1, IIJKU )
+II2 = MNH_ALLOCATE_IT1D( I2, IIJKU )
+II3 = MNH_ALLOCATE_IT1D( I3, IIJKU )
+#endif
+
+#ifndef MNH_OPENACC
+ALLOCATE( GMICRO(IIU,IJU,IKU) )
+ALLOCATE( ZRR   (IIU,IJU,IKU) )
+ALLOCATE( ZRS   (IIU,IJU,IKU) )
+ALLOCATE( ZRG   (IIU,IJU,IKU) )
+ALLOCATE( ZT    (IIU,IJU,IKU) )
+#else
+IGMICRO   = MNH_ALLOCATE_GT3D( GMICRO,  IIU,IJU,IKU )
+IZRR      = MNH_ALLOCATE_ZT3D( ZRR,     IIU,IJU,IKU )
+IZRS      = MNH_ALLOCATE_ZT3D( ZRS,     IIU,IJU,IKU )
+IZRG      = MNH_ALLOCATE_ZT3D( ZRG,     IIU,IJU,IKU )
+IZRS_ZERO = MNH_ALLOCATE_ZT3D( ZRS_ZERO,IIU,IJU,IKU )
+IZRG_ZERO = MNH_ALLOCATE_ZT3D( ZRG_ZERO,IIU,IJU,IKU )
+IZT       = MNH_ALLOCATE_ZT3D( ZT,      IIU,IJU,IKU )
 #endif
-ALLOCATE( ZT    (SIZE(PEXNREF,1),SIZE(PEXNREF,2),SIZE(PEXNREF,3)) )
 
-!$acc data create( I1, I2, I3, GMICRO, ZRR, ZRS, ZRG, ZRS_ZERO, ZRG_ZERO, ZT )
+!$acc data present( I1, I2, I3, GMICRO, ZRR, ZRS, ZRG, ZRS_ZERO, ZRG_ZERO, ZT )
 
 !-------------------------------------------------------------------------------
 !
@@ -492,6 +542,7 @@ IKTE=IKT-JPVEXT
 !
 ZINVTSTEP=1./PTSTEP
 !
+GPDF_SIGM =  ( HSUBG_AUCV == 'PDF ' .AND. CSUBG_PR_PDF == 'SIGM' )
 !
 !
 !*       2.     COMPUTES THE SLOW COLD PROCESS SOURCES
@@ -533,6 +584,7 @@ CALL COUNTJV_DEVICE(GMICRO(:,:,:),I1(:),I2(:),I3(:),IMICRO)
 #endif
 
 IF( IMICRO >= 0 ) THEN
+#ifndef MNH_OPENACC   
   ALLOCATE(ZRVT(IMICRO))
   ALLOCATE(ZRCT(IMICRO))
   ALLOCATE(ZRRT(IMICRO))
@@ -595,30 +647,96 @@ IF( IMICRO >= 0 ) THEN
   ALLOCATE(ZCJ(IMICRO))
   ALLOCATE(ZKA(IMICRO))
   ALLOCATE(ZDV(IMICRO))
-  IF ( KRR == 7 ) THEN
-    ALLOCATE(ZZW1(IMICRO,7))
-  ELSE IF( KRR == 6 ) THEN
-    ALLOCATE(ZZW1(IMICRO,6))
-  ENDIF
 !
   IF (LBU_ENABLE .OR. LLES_CALL .OR. LCHECK ) THEN
     ALLOCATE(ZRHODJ(IMICRO))
   ELSE
     ALLOCATE(ZRHODJ(0))
   END IF
+#else
+IZRVT  = MNH_ALLOCATE_ZT1DP(ZRVT,IMICRO)
+IZRCT  = MNH_ALLOCATE_ZT1DP(ZRCT,IMICRO)
+IZRRT  = MNH_ALLOCATE_ZT1DP(ZRRT,IMICRO)
+IZRIT  = MNH_ALLOCATE_ZT1DP(ZRIT,IMICRO)
+IZRST  = MNH_ALLOCATE_ZT1DP(ZRST,IMICRO)
+IZRGT  = MNH_ALLOCATE_ZT1DP(ZRGT,IMICRO)
+  IF ( KRR == 7 ) THEN
+IZRHT    = MNH_ALLOCATE_ZT1DP(ZRHT,IMICRO)
+  ELSE
+IZRHT    = MNH_ALLOCATE_ZT1DP(ZRHT,0)
+  END IF
+IZCIT  = MNH_ALLOCATE_ZT1DP(ZCIT,IMICRO)
+IZRVS  = MNH_ALLOCATE_ZT1DP(ZRVS,IMICRO)
+IZRCS  = MNH_ALLOCATE_ZT1DP(ZRCS,IMICRO)
+IZRRS  = MNH_ALLOCATE_ZT1DP(ZRRS,IMICRO)
+IZRIS  = MNH_ALLOCATE_ZT1DP(ZRIS,IMICRO)
+IZRSS  = MNH_ALLOCATE_ZT1DP(ZRSS,IMICRO)
+IZRGS  = MNH_ALLOCATE_ZT1DP(ZRGS,IMICRO)
+  IF ( KRR == 7 ) THEN
+IZRHS    = MNH_ALLOCATE_ZT1DP(ZRHS,IMICRO)
+  ELSE
+IZRHS    = MNH_ALLOCATE_ZT1DP(ZRHS,0)
+  END IF
+IZTHS  = MNH_ALLOCATE_ZT1DP(ZTHS,IMICRO)
+IZTHT  = MNH_ALLOCATE_ZT1DP(ZTHT,IMICRO)
+IZTHLT  = MNH_ALLOCATE_ZT1DP(ZTHLT,IMICRO)
+IZRHODREF  = MNH_ALLOCATE_ZT1DP(ZRHODREF,IMICRO)
+IZZT  = MNH_ALLOCATE_ZT1DP(ZZT,IMICRO)
+IZPRES  = MNH_ALLOCATE_ZT1DP(ZPRES,IMICRO)
+IZEXNREF  = MNH_ALLOCATE_ZT1DP(ZEXNREF,IMICRO)
+IZSIGMA_RC  = MNH_ALLOCATE_ZT1DP(ZSIGMA_RC,IMICRO)
+IZCF  = MNH_ALLOCATE_ZT1DP(ZCF,IMICRO)
+IZRF  = MNH_ALLOCATE_ZT1DP(ZRF,IMICRO)
+IZHLC_HCF  = MNH_ALLOCATE_ZT1DP(ZHLC_HCF,IMICRO)
+IZHLC_LCF  = MNH_ALLOCATE_ZT1DP(ZHLC_LCF,IMICRO)
+IZHLC_HRC  = MNH_ALLOCATE_ZT1DP(ZHLC_HRC,IMICRO)
+IZHLC_LRC  = MNH_ALLOCATE_ZT1DP(ZHLC_LRC,IMICRO)
+IZHLC_RCMAX  = MNH_ALLOCATE_ZT1DP(ZHLC_RCMAX,IMICRO)
+IZRCRAUTC  = MNH_ALLOCATE_ZT1DP(ZRCRAUTC,IMICRO)
+IZHLC_HRCLOCAL  = MNH_ALLOCATE_ZT1DP(ZHLC_HRCLOCAL,IMICRO)
+IZHLC_LRCLOCAL  = MNH_ALLOCATE_ZT1DP(ZHLC_LRCLOCAL,IMICRO)
+!
+IZZW  = MNH_ALLOCATE_ZT1DP(ZZW,IMICRO)
+IZLSFACT  = MNH_ALLOCATE_ZT1DP(ZLSFACT,IMICRO)
+IZLVFACT  = MNH_ALLOCATE_ZT1DP(ZLVFACT,IMICRO)
+IZUSW  = MNH_ALLOCATE_ZT1DP(ZUSW,IMICRO)
+IZSSI  = MNH_ALLOCATE_ZT1DP(ZSSI,IMICRO)
+IZLBDAR  = MNH_ALLOCATE_ZT1DP(ZLBDAR,IMICRO)
+IZLBDAR_RF  = MNH_ALLOCATE_ZT1DP(ZLBDAR_RF,IMICRO)
+IZLBDAS  = MNH_ALLOCATE_ZT1DP(ZLBDAS,IMICRO)
+IZLBDAG  = MNH_ALLOCATE_ZT1DP(ZLBDAG,IMICRO)
+  IF ( KRR == 7 ) THEN
+IZLBDAH    = MNH_ALLOCATE_ZT1DP(ZLBDAH,IMICRO)
+  ELSE
+IZLBDAH    = MNH_ALLOCATE_ZT1DP(ZLBDAH,0)
+  END IF
+IZRDRYG  = MNH_ALLOCATE_ZT1DP(ZRDRYG,IMICRO)
+IZRWETG  = MNH_ALLOCATE_ZT1DP(ZRWETG,IMICRO)
+IZAI  = MNH_ALLOCATE_ZT1DP(ZAI,IMICRO)
+IZCJ  = MNH_ALLOCATE_ZT1DP(ZCJ,IMICRO)
+IZKA  = MNH_ALLOCATE_ZT1DP(ZKA,IMICRO)
+IZDV  = MNH_ALLOCATE_ZT1DP(ZDV,IMICRO)
+!
+  IF (LBU_ENABLE .OR. LLES_CALL .OR. LCHECK ) THEN
+IZRHODJ    = MNH_ALLOCATE_ZT1DP(ZRHODJ,IMICRO)
+  ELSE
+IZRHODJ    = MNH_ALLOCATE_ZT1DP(ZRHODJ,0)
+  END IF
+#endif
+ 
 
-!$acc data create(    ZRVT, ZRCT, ZRRT, ZRIT, ZRST, ZRGT, ZRHT,                                 &
+!$acc data present(   ZRVT, ZRCT, ZRRT, ZRIT, ZRST, ZRGT, ZRHT,                                 &
 !$acc &               ZCIT, ZRVS,  ZRCS, ZRRS, ZRIS, ZRSS, ZRGS, ZRHS, ZTHS, ZTHT, ZTHLT,       &
 !$acc &               ZRHODREF, ZZT, ZPRES, ZEXNREF, ZSIGMA_RC, ZCF, ZRF,                                  &
 !$acc &               ZHLC_HCF, ZHLC_LCF, ZHLC_HRC, ZHLC_LRC, ZHLC_RCMAX, ZRCRAUTC,             &
 !$acc &               ZHLC_HRCLOCAL, ZHLC_LRCLOCAL, ZZW, ZLSFACT, ZLVFACT, ZUSW, ZSSI, &
 !$acc &               ZLBDAR, ZLBDAR_RF, ZLBDAS, ZLBDAG, ZLBDAH, ZRDRYG, ZRWETG,                &
-!$acc &               ZAI, ZCJ, ZKA, ZDV, ZZW1, ZRHODJ                                        )
+!$acc &               ZAI, ZCJ, ZKA, ZDV,  ZRHODJ                                        ) 
 
 !
 !$acc kernels
 !$acc loop independent
-  DO JL=1,IMICRO
+  DO CONCURRENT ( JL=1:IMICRO )
     ZRVT(JL) = PRVT(I1(JL),I2(JL),I3(JL))
     ZRCT(JL) = PRCT(I1(JL),I2(JL),I3(JL))
     ZRRT(JL) = PRRT(I1(JL),I2(JL),I3(JL))
@@ -653,25 +771,36 @@ IF( IMICRO >= 0 ) THEN
     ENDDO
   ENDIF
 !
-  IF ( HSUBG_AUCV == 'PDF ' .AND. CSUBG_PR_PDF == 'SIGM' ) THEN
+  IF ( GPDF_SIGM ) THEN
 !$acc loop independent
     DO JL=1,IMICRO
       ZSIGMA_RC(JL) = PSIGS(I1(JL),I2(JL),I3(JL)) * 2.
 !     ZSIGMA_RC(JL) = MAX(PSIGS(I1(JL),I2(JL),I3(JL)) * 2., 1.E-12)
     END DO
   END IF
-!
-  ZZW(:)  = ZEXNREF(:)*( XCPD+XCPV*ZRVT(:)+XCL*(ZRCT(:)+ZRRT(:)) &
-                                    +XCI*(ZRIT(:)+ZRST(:)+ZRGT(:)) )
-  ZLSFACT(:) = (XLSTT+(XCPV-XCI)*(ZZT(:)-XTT))/ZZW(:) ! L_s/(Pi_ref*C_ph)
-  ZLVFACT(:) = (XLVTT+(XCPV-XCL)*(ZZT(:)-XTT))/ZZW(:) ! L_v/(Pi_ref*C_ph)
-
+  !
+  !$acc loop independent
+  DO CONCURRENT ( JL=1:IMICRO )
+     ZZW(JL)  = ZEXNREF(JL)*( XCPD+XCPV*ZRVT(JL)+XCL*(ZRCT(JL)+ZRRT(JL)) &
+          +XCI*(ZRIT(JL)+ZRST(JL)+ZRGT(JL)) )
+     ZLSFACT(JL) = (XLSTT+(XCPV-XCI)*(ZZT(JL)-XTT))/ZZW(JL) ! L_s/(Pi_ref*C_ph)
+     ZLVFACT(JL) = (XLVTT+(XCPV-XCL)*(ZZT(JL)-XTT))/ZZW(JL) ! L_v/(Pi_ref*C_ph)
+  END DO
+  
 #ifndef MNH_BITREP
-  ZZW(:) = EXP( XALPI - XBETAI/ZZT(:) - XGAMI*ALOG(ZZT(:) ) )
+  !$acc loop independent
+  DO CONCURRENT ( JL=1:IMICRO )
+     ZZW(JL) = EXP( XALPI - XBETAI/ZZT(JL) - XGAMI*BR_LOG(ZZT(JL) ) )
+     ZSSI(JL) = ZRVT(JL)*( ZPRES(JL)-ZZW(JL) ) / ( (XMV/XMD) * ZZW(JL) ) - 1.0
+  END DO
 #else
-  ZZW(:) = BR_EXP( XALPI - XBETAI/ZZT(:) - XGAMI*BR_LOG(ZZT(:) ) )
+  !$acc loop independent
+  DO CONCURRENT ( JL=1:IMICRO )
+     ZZW(JL) = BR_EXP( XALPI - XBETAI/ZZT(JL) - XGAMI*BR_LOG(ZZT(JL) ) )
+     ZSSI(JL) = ZRVT(JL)*( ZPRES(JL)-ZZW(JL) ) / ( (XMV/XMD) * ZZW(JL) ) - 1.0
+  END DO
 #endif
-  ZSSI(:) = ZRVT(:)*( ZPRES(:)-ZZW(:) ) / ( (XMV/XMD) * ZZW(:) ) - 1.0
+  
                                                     ! Supersaturation over ice
   !
   IF (LBU_ENABLE .OR. LLES_CALL) THEN
@@ -683,7 +812,10 @@ IF( IMICRO >= 0 ) THEN
 !
   !Cloud water split between high and low content part is done here
   !according to autoconversion option
-  ZRCRAUTC(:)   = XCRIAUTC/ZRHODREF(:) ! Autoconversion rc threshold
+  !$acc loop independent
+  DO CONCURRENT ( JL=1:IMICRO )
+     ZRCRAUTC(JL)   = XCRIAUTC/ZRHODREF(JL) ! Autoconversion rc threshold
+  END DO
 !$acc end kernels
 #ifdef MNH_OPENACC
   IF (LBU_ENABLE .OR. LLES_CALL) THEN
@@ -694,7 +826,7 @@ IF( IMICRO >= 0 ) THEN
 !$acc kernels
     !Cloud water is entirely in low or high part
 !$acc loop independent private(JL)
-    DO JL=1,IMICRO
+    DO CONCURRENT ( JL=1:IMICRO )
       IF (ZRCT(JL) > ZRCRAUTC(JL)) THEN
         ZHLC_HCF(JL) = 1.
         ZHLC_LCF(JL) = 0.0
@@ -924,26 +1056,45 @@ IF( IMICRO >= 0 ) THEN
 !
 !$acc kernels
   !ZLBDAR will be used when we consider rain diluted over the grid box
-  WHERE( ZRRT(:)>0.0 )
-#ifndef MNH_BITREP
-    ZLBDAR(:)  = XLBR*( ZRHODREF(:)*MAX( ZRRT(:),XRTMIN(3) ) )**XLBEXR
+#ifndef MNH_BITREP  
+!$acc loop independent
+  DO CONCURRENT ( JL=1:IMICRO )
+    IF ( ZRRT(JL)>0.0 ) THEN
+      ZLBDAR(JL)  = XLBR * ( ZRHODREF(JL) * MAX( ZRRT(JL), XRTMIN(3) ) )**XLBEXR
+    ELSE
+      ZLBDAR(JL)  = 0.
+   END IF
+  END DO ! CONCURRENT
 #else
-    ZLBDAR(:)  = XLBR * BR_POW( ZRHODREF(:) * MAX( ZRRT(:), XRTMIN(3) ), XLBEXR )
-#endif
-  ELSEWHERE
-    ZLBDAR(:)  = 0.
-  END WHERE
+!$acc loop independent
+  DO CONCURRENT ( JL=1:IMICRO )
+    IF ( ZRRT(JL)>0.0 ) THEN
+      ZLBDAR(JL)  = XLBR * BR_POW( ZRHODREF(JL) * MAX( ZRRT(JL), XRTMIN(3) ), XLBEXR )
+    ELSE
+      ZLBDAR(JL)  = 0.
+   END IF
+  END DO ! CONCURRENT
+#endif 
   !ZLBDAR_RF will be used when we consider rain concentrated in its fraction
-  WHERE( ZRRT(:)>0.0 .AND. ZRF(:)>0.0 )
-#ifndef MNH_BITREP
-    ZLBDAR_RF(:)  = XLBR*( ZRHODREF(:) *MAX( ZRRT(:)/ZRF(:)  , XRTMIN(3) ) )**XLBEXR
+#ifndef MNH_BITREP  
+!$acc loop independent
+  DO CONCURRENT ( JL=1:IMICRO )
+    IF ( ZRRT(JL)>0.0 .AND. ZRF(JL)>0.0 ) THEN
+      ZLBDAR_RF(JL)  = XLBR * ( ZRHODREF(JL) * MAX( ZRRT(JL)/ZRF(JL), XRTMIN(3) ) )**XLBEXR
+    ELSE
+      ZLBDAR_RF(JL)  = 0.
+    END IF
+  END DO ! CONCURRENT
 #else
-    ZLBDAR_RF(:)  = XLBR * BR_POW( ZRHODREF(:) * MAX( ZRRT(:)/ZRF(:), XRTMIN(3) ), XLBEXR )
-#endif
-  ELSEWHERE
-    ZLBDAR_RF(:)  = 0.
-  END WHERE
-
+!$acc loop independent
+  DO CONCURRENT ( JL=1:IMICRO )
+    IF ( ZRRT(JL)>0.0 .AND. ZRF(JL)>0.0 ) THEN
+      ZLBDAR_RF(JL)  = XLBR * BR_POW( ZRHODREF(JL) * MAX( ZRRT(JL)/ZRF(JL), XRTMIN(3) ), XLBEXR )
+    ELSE
+      ZLBDAR_RF(JL)  = 0.
+    END IF
+  END DO ! CONCURRENT
+#endif 
   !Not necessary but useful for verifications
   ZUSW(:) = XNEGUNDEF
 !$acc end kernels
@@ -1033,12 +1184,9 @@ IF( IMICRO >= 0 ) THEN
 !$acc end kernels
 
 !$acc end data
-
-
-!
 !
 !
-  DEALLOCATE(ZZW1)
+#ifndef MNH_OPENACC   
   DEALLOCATE(ZDV)
   DEALLOCATE(ZCJ)
   DEALLOCATE(ZRDRYG)
@@ -1089,6 +1237,16 @@ IF( IMICRO >= 0 ) THEN
   DEALLOCATE(ZRCRAUTC)
   DEALLOCATE(ZHLC_HRCLOCAL)
   DEALLOCATE(ZHLC_LRCLOCAL)
+#else
+  CALL MNH_REL_ZT1D(IZKA,IZDV,IZRHODJ)
+  CALL MNH_REL_ZT1D(IZLBDAS,IZLBDAG,IZLBDAH,IZRDRYG,IZRWETG,IZAI,IZCJ)
+  CALL MNH_REL_ZT1D(IZZW,IZLSFACT,IZLVFACT,IZUSW,IZSSI,IZLBDAR,IZLBDAR_RF)
+  CALL MNH_REL_ZT1D(IZRCRAUTC,IZHLC_HRCLOCAL,IZHLC_LRCLOCAL)
+  CALL MNH_REL_ZT1D(IZHLC_HCF,IZHLC_LCF,IZHLC_HRC,IZHLC_LRC,IZHLC_RCMAX)
+  CALL MNH_REL_ZT1D(IZRHODREF,IZZT,IZPRES,IZEXNREF,IZSIGMA_RC,IZCF,IZRF)
+  CALL MNH_REL_ZT1D(IZRVS,IZRCS,IZRRS,IZRIS,IZRSS,IZRGS,IZRHS,IZTHS,IZTHT,IZTHLT)
+  CALL MNH_REL_ZT1D(IZRVT,IZRCT,IZRRT,IZRIT,IZRST,IZRGT,IZRHT,IZCIT)
+#endif
 END IF
 !
 !-------------------------------------------------------------------------------
@@ -1147,10 +1305,18 @@ IF (MPPDB_INITIALIZED) THEN
   IF (PRESENT(PFPR))   CALL MPPDB_CHECK(PFPR,"RAIN_ICE end:PFPR")
 END IF
 !
-! !$acc end data
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+DEALLOCATE ( I1,I2,I3 )
+DEALLOCATE ( GMICRO, ZRR, ZRS, ZRG, ZT )
+#else
+CALL MNH_REL_IT1D(II1, II2, II3)
+CALL MNH_REL_GT3D ( IGMICRO )
+CALL MNH_REL_ZT3D ( IZRR, IZRS, IZRG, IZRS_ZERO, IZRG_ZERO, IZT )
+#endif
+
 !$acc end data
 
 !-------------------------------------------------------------------------------
diff --git a/src/MNH/rain_ice_fast_rg.f90 b/src/MNH/rain_ice_fast_rg.f90
index fbba910e7cac15307712dfb2b976de78938f722d..ffb7d664ef9c765ab734d14ffd1065152fc214af 100644
--- a/src/MNH/rain_ice_fast_rg.f90
+++ b/src/MNH/rain_ice_fast_rg.f90
@@ -9,6 +9,9 @@
 !  P. Wautelet 03/06/2019: remove PACK/UNPACK intrinsics (to get more performance and better OpenACC support)
 !  P. Wautelet 05/06/2019: optimisations
 !  P. Wautelet    02/2020: use the new data structures and subroutines for budgets
+!  J. Escobar  11/08/2020: Bypass PGI/NVHPC OPENACC BUG, error 700: Illegal address during kernel execution => DO CONCURRENT
+!  J. Escobar  12/08/2020: Bypass PGI/NVHPC OPENACC BUG data partially present => enter data in ini_rain_ce & DO CONCURRENT
+!  J. Escobar  13/08/2020: Openacc PB , missing enter/update data rain_ice_fast_rs/g
 !-----------------------------------------------------------------
 MODULE MODE_RAIN_ICE_FAST_RG
 
@@ -100,6 +103,7 @@ REAL,    DIMENSION(:),   ALLOCATABLE :: ZVEC1,ZVEC2,ZVEC3 ! Work vectors for int
 REAL,    DIMENSION(:),   ALLOCATABLE :: ZVECLBDAG, ZVECLBDAR, ZVECLBDAS
 REAL,    DIMENSION(:,:), ALLOCATABLE :: ZZW1              ! Work arrays
 !
+INTEGER                              :: JLU
 !-------------------------------------------------------------------------------
 !
 ! IN variables
@@ -114,7 +118,11 @@ REAL,    DIMENSION(:,:), ALLOCATABLE :: ZZW1              ! Work arrays
 !
 ! OUT variables
 !
-!$acc &             PRDRYG, PRWETG )
+!$acc &             PRDRYG, PRWETG, &
+!
+! use variables
+!
+!$acc &              XKER_SDRYG,XKER_RDRYG )
 
 IF (MPPDB_INITIALIZED) THEN
   !Check all IN arrays
@@ -147,8 +155,13 @@ IF (MPPDB_INITIALIZED) THEN
   CALL MPPDB_CHECK(PRHS,"RAIN_ICE_FAST_RG beg:PRHS")
   CALL MPPDB_CHECK(PTHS,"RAIN_ICE_FAST_RG beg:PTHS")
   CALL MPPDB_CHECK(PUSW,"RAIN_ICE_FAST_RG beg:PUSW")
+  !Check use variable
+  CALL MPPDB_CHECK(XKER_SDRYG,"RAIN_ICE_FAST_RG beg:XKER_SDRYG")
+  CALL MPPDB_CHECK(XKER_SDRYG,"RAIN_ICE_FAST_RG beg:XKER_RDRYG")
 END IF
 !
+JLU = size(PRHODREF) 
+!
 ALLOCATE( I1   (size(PRHODREF)) )
 ALLOCATE( GWORK(size(PRHODREF)) )
 ALLOCATE( ZZW  (size(PRHODREF)) )
@@ -162,29 +175,45 @@ ALLOCATE( ZZW1 (size(PRHODREF),7) )
 !$acc kernels
   ZZW1(:,:) = 0.0
   GWORK(:) = PRIT(:)>XRTMIN(4) .AND. PRRT(:)>XRTMIN(3) .AND. PRIS(:)>0.0 .AND. PRRS(:)>0.0
-  WHERE( GWORK(:) )
 #ifndef MNH_BITREP
-    ZZW1(:,3) = MIN( PRIS(:),XICFRR * PRIT(:)                & ! RICFRRG
-                                    * PLBDAR(:)**XEXICFRR    &
-                                    * PRHODREF(:)**(-XCEXVT) )
-    ZZW1(:,4) = MIN( PRRS(:),XRCFRI * PCIT(:)                & ! RRCFRIG
-                                    * PLBDAR(:)**XEXRCFRI    &
-                                    * PRHODREF(:)**(-XCEXVT-1.) )
+  !$acc loop independent
+  DO CONCURRENT ( JL=1:JLU )
+    IF ( GWORK(JL) ) THEN
+      ZZW1(JL,3) = MIN( PRIS(JL),XICFRR * PRIT(JL)                & ! RICFRRG
+                                      * PLBDAR(JL)**XEXICFRR      &
+                                      * PRHODREF(JL)**(-XCEXVT) )
+      ZZW1(JL,4) = MIN( PRRS(JL),XRCFRI * PCIT(JL)                & ! RRCFRIG
+                                      * PLBDAR(JL)**XEXRCFRI      &
+                                      * PRHODREF(JL)**(-XCEXVT-1.) )
+      PRIS(JL) = PRIS(JL) - ZZW1(JL,3)
+      PRRS(JL) = PRRS(JL) - ZZW1(JL,4)
+      PRGS(JL) = PRGS(JL) + ZZW1(JL,3)+ZZW1(JL,4)
+      PTHS(JL) = PTHS(JL) + ZZW1(JL,4)*(PLSFACT(JL)-PLVFACT(JL)) ! f(L_f*RRCFRIG)
+    END IF
+ END DO ! CONCURRENT
 #else
-    ZZW1(:,3) = MIN( PRIS(:),XICFRR * PRIT(:)                     & ! RICFRRG
-                                    * BR_POW(PLBDAR(:),XEXICFRR)  &
-                                    * BR_POW(PRHODREF(:),-XCEXVT) )
-    ZZW1(:,4) = MIN( PRRS(:),XRCFRI * PCIT(:)                     & ! RRCFRIG
-                                    * BR_POW(PLBDAR(:),XEXRCFRI)  &
-                                    * BR_POW(PRHODREF(:),-XCEXVT-1.) )
-#endif
-    PRIS(:) = PRIS(:) - ZZW1(:,3)
-    PRRS(:) = PRRS(:) - ZZW1(:,4)
-    PRGS(:) = PRGS(:) + ZZW1(:,3)+ZZW1(:,4)
-    PTHS(:) = PTHS(:) + ZZW1(:,4)*(PLSFACT(:)-PLVFACT(:)) ! f(L_f*RRCFRIG)
-  END WHERE
+  !$acc loop independent
+  DO CONCURRENT ( JL=1:JLU )
+    IF ( GWORK(JL) ) THEN
+       ZZW1(JL,3) = MIN( PRIS(JL),XICFRR * PRIT(JL)                     & ! RICFRRG
+            * BR_POW(PLBDAR(JL),XEXICFRR)  &
+            * BR_POW(PRHODREF(JL),-XCEXVT) )
+       ZZW1(JL,4) = MIN( PRRS(JL),XRCFRI * PCIT(JL)                     & ! RRCFRIG
+            * BR_POW(PLBDAR(JL),XEXRCFRI)  &
+            * BR_POW(PRHODREF(JL),-XCEXVT-1.) )
+       PRIS(JL) = PRIS(JL) - ZZW1(JL,3)
+       PRRS(JL) = PRRS(JL) - ZZW1(JL,4)
+       PRGS(JL) = PRGS(JL) + ZZW1(JL,3)+ZZW1(JL,4)
+       PTHS(JL) = PTHS(JL) + ZZW1(JL,4)*(PLSFACT(JL)-PLVFACT(JL)) ! f(L_f*RRCFRIG)
+    END IF
+ END DO ! CONCURRENT
+#endif 
 !$acc end kernels
 
+IF (MPPDB_INITIALIZED) THEN
+   CALL MPPDB_CHECK(PRRS,"RAIN_ICE_FAST_RG 6.1:PRRS")
+END IF
+
   if ( lbudget_th ) call Budget_store_add( tbudgets(NBUDGET_TH), 'CFRZ', Unpack (  zzw1(:, 4) * ( plsfact(:) - plvfact(:) ) &
                                                                      * prhodj(:), mask = omicro(:,:,:), field = 0. ) )
   if ( lbudget_rr ) call Budget_store_add( tbudgets(NBUDGET_RR), 'CFRZ', Unpack ( -zzw1(:, 4)                * prhodj(:), &
@@ -237,6 +266,9 @@ ALLOCATE( ZZW1 (size(PRHODREF),7) )
 #endif
   END WHERE
 !$acc end kernels
+IF (MPPDB_INITIALIZED) THEN
+   CALL MPPDB_CHECK(ZZW1,"RAIN_ICE_FAST_RG 6.2:ZZW1")
+END IF   
 !
 !*       6.2.1  accretion of aggregates on the graupeln
 !
@@ -294,17 +326,17 @@ ALLOCATE( ZZW1 (size(PRHODREF),7) )
 !*       6.2.5  perform the bilinear interpolation of the normalized
 !               SDRYG-kernel
 !
-!$acc loop independent
-    DO JJ = 1,IGDRY
+    !$acc loop independent
+    DO CONCURRENT ( JJ = 1:IGDRY )
       ZVEC3(JJ) =  (  XKER_SDRYG(IVEC1(JJ)+1,IVEC2(JJ)+1)* ZVEC2(JJ)          &
                     - XKER_SDRYG(IVEC1(JJ)+1,IVEC2(JJ)  )*(ZVEC2(JJ) - 1.0) ) &
                                                          * ZVEC1(JJ) &
                  - (  XKER_SDRYG(IVEC1(JJ)  ,IVEC2(JJ)+1)* ZVEC2(JJ)          &
                     - XKER_SDRYG(IVEC1(JJ)  ,IVEC2(JJ)  )*(ZVEC2(JJ) - 1.0) ) &
                                                          * (ZVEC1(JJ) - 1.0)
-    END DO
+    END DO ! CONCURRENT
 !
-!$acc loop independent
+    !$acc loop independent , private (JL) 
     DO JJ = 1, IGDRY
       JL = I1(JJ)
 #ifndef MNH_BITREP
@@ -326,7 +358,10 @@ ALLOCATE( ZZW1 (size(PRHODREF),7) )
 #endif
     END DO
 !$acc end kernels
-
+IF (MPPDB_INITIALIZED) THEN
+    CALL MPPDB_CHECK(ZZW1,"RAIN_ICE_FAST_RG 6.2.5:ZZW1")
+    CALL MPPDB_CHECK(ZVEC3,"RAIN_ICE_FAST_RG 6.2.5:ZVEC3")
+END IF    
 !$acc end data
     DEALLOCATE(ZVECLBDAS)
     DEALLOCATE(ZVECLBDAG)
@@ -392,17 +427,17 @@ ALLOCATE( ZZW1 (size(PRHODREF),7) )
 !*       6.2.10 perform the bilinear interpolation of the normalized
 !               RDRYG-kernel
 !
-!$acc loop independent
-    DO JJ = 1,IGDRY
+    !$acc loop independent
+    DO CONCURRENT (JJ = 1:IGDRY )
       ZVEC3(JJ) =  (  XKER_RDRYG(IVEC1(JJ)+1,IVEC2(JJ)+1)* ZVEC2(JJ)          &
                     - XKER_RDRYG(IVEC1(JJ)+1,IVEC2(JJ)  )*(ZVEC2(JJ) - 1.0) ) &
                                                                   * ZVEC1(JJ) &
                  - (  XKER_RDRYG(IVEC1(JJ)  ,IVEC2(JJ)+1)* ZVEC2(JJ)          &
                     - XKER_RDRYG(IVEC1(JJ)  ,IVEC2(JJ)  )*(ZVEC2(JJ) - 1.0) ) &
                                                          * (ZVEC1(JJ) - 1.0)
-    END DO
+    END DO ! CONCURRENT
 !
-!$acc loop independent
+    !$acc loop independent , private (JL)
     DO JJ = 1, IGDRY
       JL = I1(JJ)
 #ifndef MNH_BITREP
@@ -422,7 +457,10 @@ ALLOCATE( ZZW1 (size(PRHODREF),7) )
 #endif
     END DO
 !$acc end kernels
-
+IF (MPPDB_INITIALIZED) THEN
+    CALL MPPDB_CHECK(ZZW1,"RAIN_ICE_FAST_RG 6.2.10:ZZW1")
+    CALL MPPDB_CHECK(ZVEC3,"RAIN_ICE_FAST_RG 6.2.10:ZVEC3")
+END IF    
 !$acc end data
     DEALLOCATE(ZVECLBDAR)
     DEALLOCATE(ZVECLBDAG)
@@ -440,38 +478,55 @@ ALLOCATE( ZZW1 (size(PRHODREF),7) )
 !
   PRWETG(:) = 0.0
   GWORK(:) = PRGT(:)>XRTMIN(6)
-  WHERE( GWORK(:) )
-#ifndef MNH_BITREP
-    ZZW1(:,5) = MIN( PRIS(:),                                    &
-                ZZW1(:,2) / (XCOLIG*EXP(XCOLEXIG*(PZT(:)-XTT)) ) ) ! RIWETG
-    ZZW1(:,6) = MIN( PRSS(:),                                    &
-                ZZW1(:,3) / (XCOLSG*EXP(XCOLEXSG*(PZT(:)-XTT)) ) ) ! RSWETG
-#else
-    ZZW1(:,5) = MIN( PRIS(:),                                    &
-                ZZW1(:,2) / (XCOLIG*BR_EXP(XCOLEXIG*(PZT(:)-XTT)) ) ) ! RIWETG
-    ZZW1(:,6) = MIN( PRSS(:),                                    &
-                ZZW1(:,3) / (XCOLSG*BR_EXP(XCOLEXSG*(PZT(:)-XTT)) ) ) ! RSWETG
-#endif
-!
-    ZZW(:) = PRVT(:)*PPRES(:)/((XMV/XMD)+PRVT(:)) ! Vapor pressure
-    ZZW(:) =   PKA(:)*(XTT-PZT(:)) +                              &
-             ( PDV(:)*(XLVTT + ( XCPV - XCL ) * ( PZT(:) - XTT )) &
-                           *(XESTT-ZZW(:))/(XRV*PZT(:))           )
-!
-! compute RWETG
-!
-    PRWETG(:)=MAX( 0.0,                                               &
-#ifndef MNH_BITREP
-                 ( ZZW(:) * ( X0DEPG*       PLBDAG(:)**XEX0DEPG +     &
-                              X1DEPG*PCJ(:)*PLBDAG(:)**XEX1DEPG ) +   &
+#ifndef MNH_BITREP  
+!$acc loop independent
+  DO CONCURRENT ( JL=1:JLU )
+    IF ( GWORK(JL) ) THEN
+       ZZW1(JL,5) = MIN( PRIS(JL),                                    &
+            ZZW1(JL,2) / (XCOLIG*EXP(XCOLEXIG*(PZT(JL)-XTT)) ) ) ! RIWETG
+       ZZW1(JL,6) = MIN( PRSS(JL),                                    &
+            ZZW1(JL,3) / (XCOLSG*EXP(XCOLEXSG*(PZT(JL)-XTT)) ) ) ! RSWETG
+       !
+       ZZW(JL) = PRVT(JL)*PPRES(JL)/((XMV/XMD)+PRVT(JL)) ! Vapor pressure
+       ZZW(JL) =   PKA(JL)*(XTT-PZT(JL)) +                              &
+            ( PDV(JL)*(XLVTT + ( XCPV - XCL ) * ( PZT(JL) - XTT )) &
+            *(XESTT-ZZW(JL))/(XRV*PZT(JL))           )
+       !
+       ! compute RWETG
+       !
+       PRWETG(JL)=MAX( 0.0,                                        &
+            ( ZZW(JL) * ( X0DEPG*        PLBDAG(JL)**XEX0DEPG +    &
+                          X1DEPG*PCJ(JL)*PLBDAG(JL)**XEX1DEPG ) +  &
+            ( ZZW1(JL,5)+ZZW1(JL,6) ) *                            &
+            ( PRHODREF(JL)*(XLMTT+(XCI-XCL)*(XTT-PZT(JL)))   ) ) / &
+            ( PRHODREF(JL)*(XLMTT-XCL*(XTT-PZT(JL))) )   )
+    END IF
+  END DO ! CONCURRENT
 #else
-                 ( ZZW(:) * ( X0DEPG*       BR_POW(PLBDAG(:),XEX0DEPG) +     &
-                              X1DEPG*PCJ(:)*BR_POW(PLBDAG(:),XEX1DEPG) ) +   &
-#endif
-                 ( ZZW1(:,5)+ZZW1(:,6) ) *                            &
-                 ( PRHODREF(:)*(XLMTT+(XCI-XCL)*(XTT-PZT(:)))   ) ) / &
-                            ( PRHODREF(:)*(XLMTT-XCL*(XTT-PZT(:))) )   )
-  END WHERE
+!$acc loop independent
+  DO CONCURRENT ( JL=1:JLU )
+    IF ( GWORK(JL) ) THEN
+       ZZW1(JL,5) = MIN( PRIS(JL),                                    &
+            ZZW1(JL,2) / (XCOLIG*BR_EXP(XCOLEXIG*(PZT(JL)-XTT)) ) ) ! RIWETG
+       ZZW1(JL,6) = MIN( PRSS(JL),                                    &
+            ZZW1(JL,3) / (XCOLSG*BR_EXP(XCOLEXSG*(PZT(JL)-XTT)) ) ) ! RSWETG
+       !
+       ZZW(JL) = PRVT(JL)*PPRES(JL)/((XMV/XMD)+PRVT(JL)) ! Vapor pressure
+       ZZW(JL) =   PKA(JL)*(XTT-PZT(JL)) +                              &
+            ( PDV(JL)*(XLVTT + ( XCPV - XCL ) * ( PZT(JL) - XTT )) &
+            *(XESTT-ZZW(JL))/(XRV*PZT(JL))           )
+       !
+       ! compute RWETG
+       !
+       PRWETG(JL)=MAX( 0.0,                                               &
+            ( ZZW(JL) * ( X0DEPG*       BR_POW(PLBDAG(JL),XEX0DEPG) +     &
+            X1DEPG*PCJ(JL)*BR_POW(PLBDAG(JL),XEX1DEPG) ) +   &
+            ( ZZW1(JL,5)+ZZW1(JL,6) ) *                            &
+            ( PRHODREF(JL)*(XLMTT+(XCI-XCL)*(XTT-PZT(JL)))   ) ) / &
+            ( PRHODREF(JL)*(XLMTT-XCL*(XTT-PZT(JL))) )   )
+    END IF
+  END DO ! CONCURRENT
+#endif 
 !
 !*       6.4    Select Wet or Dry case
 !
@@ -518,6 +573,10 @@ ALLOCATE( ZZW1 (size(PRHODREF),7) )
   END IF
 !$acc end kernels
 
+IF (MPPDB_INITIALIZED) THEN
+   CALL MPPDB_CHECK(PRRS,"RAIN_ICE_FAST_RG 6.4:PRRS")
+END IF
+
   if ( lbudget_th ) call Budget_store_end( tbudgets(NBUDGET_TH), 'WETG', Unpack ( pths(:) * prhodj(:), &
                                            mask = omicro(:,:,:), field = 0. ) )
   if ( lbudget_rc ) call Budget_store_end( tbudgets(NBUDGET_RC), 'WETG', Unpack ( prcs(:) * prhodj(:), &
@@ -561,6 +620,10 @@ ALLOCATE( ZZW1 (size(PRHODREF),7) )
   END WHERE
 !$acc end kernels
 
+IF (MPPDB_INITIALIZED) THEN
+   CALL MPPDB_CHECK(PRRS,"RAIN_ICE_FAST_RG 6.4b:PRRS")
+END IF
+
   if ( lbudget_th ) call Budget_store_end( tbudgets(NBUDGET_TH), 'DRYG', Unpack ( pths(:) * prhodj(:), &
                                            mask = omicro(:,:,:), field = 0. ) )
   if ( lbudget_rc ) call Budget_store_end( tbudgets(NBUDGET_RC), 'DRYG', Unpack ( prcs(:) * prhodj(:), &
@@ -583,31 +646,57 @@ ALLOCATE( ZZW1 (size(PRHODREF),7) )
 !
 !$acc kernels
   GWORK(:) = PRGT(:)>XRTMIN(6) .AND. PRGS(:)>0.0 .AND. PZT(:)>XTT
-  WHERE( GWORK(:) )
-    ZZW(:) = PRVT(:)*PPRES(:)/((XMV/XMD)+PRVT(:)) ! Vapor pressure
-    ZZW(:) =  PKA(:)*(XTT-PZT(:)) +                                 &
-               ( PDV(:)*(XLVTT + ( XCPV - XCL ) * ( PZT(:) - XTT )) &
-                           *(XESTT-ZZW(:))/(XRV*PZT(:))             )
+#ifndef MNH_BITREP
+  !$acc loop independent
+  DO CONCURRENT ( JL=1:JLU )
+    IF ( GWORK(JL) ) THEN
+      ZZW(JL) = PRVT(JL)*PPRES(JL)/((XMV/XMD)+PRVT(JL)) ! Vapor pressure
+      ZZW(JL) =  PKA(JL)*(XTT-PZT(JL)) +                                &
+                 ( PDV(JL)*(XLVTT + ( XCPV - XCL ) * ( PZT(JL) - XTT )) &
+                             *(XESTT-ZZW(JL))/(XRV*PZT(JL))             )
 !
 ! compute RGMLTR
 !
-    ZZW(:)  = MIN( PRGS(:), MAX( 0.0,( -ZZW(:) *                     &
-#ifndef MNH_BITREP
-                           ( X0DEPG*       PLBDAG(:)**XEX0DEPG +     &
-                             X1DEPG*PCJ(:)*PLBDAG(:)**XEX1DEPG ) -   &
+      ZZW(JL)  = MIN( PRGS(JL), MAX( 0.0,( -ZZW(JL) *                   &
+                             ( X0DEPG*       PLBDAG(JL)**XEX0DEPG +     &
+                               X1DEPG*PCJ(JL)*PLBDAG(JL)**XEX1DEPG ) -  &
+                                       ( ZZW1(JL,1)+ZZW1(JL,4) ) *      &
+                                ( PRHODREF(JL)*XCL*(XTT-PZT(JL))) ) /   &
+                                               ( PRHODREF(JL)*XLMTT ) ) )
+      PRRS(JL) = PRRS(JL) + ZZW(JL)
+      PRGS(JL) = PRGS(JL) - ZZW(JL)
+      PTHS(JL) = PTHS(JL) - ZZW(JL)*(PLSFACT(JL)-PLVFACT(JL)) ! f(L_f*(-RGMLTR))
+    END IF
+  END DO ! CONCURRENT
 #else
-                           ( X0DEPG*       BR_POW(PLBDAG(:),XEX0DEPG) +     &
-                             X1DEPG*PCJ(:)*BR_POW(PLBDAG(:),XEX1DEPG) ) -   &
-#endif
-                                     ( ZZW1(:,1)+ZZW1(:,4) ) *       &
-                              ( PRHODREF(:)*XCL*(XTT-PZT(:))) ) /    &
-                                             ( PRHODREF(:)*XLMTT ) ) )
-    PRRS(:) = PRRS(:) + ZZW(:)
-    PRGS(:) = PRGS(:) - ZZW(:)
-    PTHS(:) = PTHS(:) - ZZW(:)*(PLSFACT(:)-PLVFACT(:)) ! f(L_f*(-RGMLTR))
-  END WHERE
+  !$acc loop independent
+  DO CONCURRENT ( JL=1:JLU )
+    IF ( GWORK(JL) ) THEN
+       ZZW(JL) = PRVT(JL)*PPRES(JL)/((XMV/XMD)+PRVT(JL)) ! Vapor pressure
+       ZZW(JL) =  PKA(JL)*(XTT-PZT(JL)) +                                 &
+            ( PDV(JL)*(XLVTT + ( XCPV - XCL ) * ( PZT(JL) - XTT )) &
+            *(XESTT-ZZW(JL))/(XRV*PZT(JL))             )
+       !
+       ! compute RGMLTR
+       !
+       ZZW(JL)  = MIN( PRGS(JL), MAX( 0.0,( -ZZW(JL) *                     &
+            ( X0DEPG*       BR_POW(PLBDAG(JL),XEX0DEPG) +     &
+            X1DEPG*PCJ(JL)*BR_POW(PLBDAG(JL),XEX1DEPG) ) -   &
+            ( ZZW1(JL,1)+ZZW1(JL,4) ) *       &
+            ( PRHODREF(JL)*XCL*(XTT-PZT(JL))) ) /    &
+            ( PRHODREF(JL)*XLMTT ) ) )
+       PRRS(JL) = PRRS(JL) + ZZW(JL)
+       PRGS(JL) = PRGS(JL) - ZZW(JL)
+       PTHS(JL) = PTHS(JL) - ZZW(JL)*(PLSFACT(JL)-PLVFACT(JL)) ! f(L_f*(-RGMLTR))
+    END IF
+  END DO ! CONCURRENT
+#endif 
 !$acc end kernels
 
+IF (MPPDB_INITIALIZED) THEN
+   CALL MPPDB_CHECK(PRRS,"RAIN_ICE_FAST_RG 6.5:PRRS")
+END IF
+
   if ( lbudget_th ) call Budget_store_add( tbudgets(NBUDGET_TH), 'GMLT', Unpack ( -zzw(:) * ( plsfact(:) - plvfact(:) ) &
                                                                      * prhodj(:), mask = omicro(:,:,:), field = 0. ) )
   if ( lbudget_rr ) call Budget_store_add( tbudgets(NBUDGET_RR), 'GMLT', Unpack (  zzw(:) * prhodj(:), &
diff --git a/src/MNH/rain_ice_fast_ri.f90 b/src/MNH/rain_ice_fast_ri.f90
index ab6247526371ac8e96a74774ab31155988fba7d2..359c31e8a92246e442e3f18aef4d694cb2b9736d 100644
--- a/src/MNH/rain_ice_fast_ri.f90
+++ b/src/MNH/rain_ice_fast_ri.f90
@@ -61,7 +61,9 @@ REAL,     DIMENSION(:),     INTENT(INOUT) :: PTHS     ! Theta source
 !
 LOGICAL, DIMENSION(:), ALLOCATABLE :: GWORK
 REAL,    DIMENSION(:), ALLOCATABLE :: ZZW  ! Work array
+REAL,    DIMENSION(:), ALLOCATABLE :: ZLBEXI
 !
+INTEGER :: JL,JLU
 !-------------------------------------------------------------------------------
 !
 ! IN variables
@@ -97,10 +99,13 @@ IF (MPPDB_INITIALIZED) THEN
   CALL MPPDB_CHECK(PTHS,"RAIN_ICE_FAST_RI beg:PTHS")
 END IF
 !
+JLU = size(PRHODREF)
+!
 ALLOCATE( GWORK(size(PRHODREF)) )
 ALLOCATE( ZZW  (size(PRHODREF)) )
+ALLOCATE( ZLBEXI   (size(PRHODREF)) )
 
-!$acc data create( GWORK, ZZW )
+!$acc data create( GWORK, ZZW , ZLBEXI )
 
 !
 !*       7.1    cloud ice melting
@@ -134,20 +139,41 @@ ALLOCATE( ZZW  (size(PRHODREF)) )
 !$acc kernels
   zzw(:) = 0.
   GWORK(:) = PRCS(:)>0.0 .AND. PSSI(:)>0.0 .AND. PRIT(:)>XRTMIN(4) .AND. PCIT(:)>0.0
-  WHERE( GWORK(:) )
 #ifndef MNH_BITREP
+  WHERE( GWORK(:) )
     ZZW(:) = MIN(1.E8,XLBI*( PRHODREF(:)*PRIT(:)/PCIT(:) )**XLBEXI) ! Lbda_i
     ZZW(:) = MIN( PRCS(:),( PSSI(:) / (PRHODREF(:)*PAI(:)) ) * PCIT(:) * &
                   ( X0DEPI/ZZW(:) + X2DEPI*PCJ(:)*PCJ(:)/ZZW(:)**(XDI+2.0) ) )
+    PRCS(:) = PRCS(:) - ZZW(:)
+    PRIS(:) = PRIS(:) + ZZW(:)
+    PTHS(:) = PTHS(:) + ZZW(:)*(PLSFACT(:)-PLVFACT(:)) ! f(L_f*(RCBERI))
+ END WHERE
 #else
-    ZZW(:) = MIN(1.E8,XLBI*BR_POW( PRHODREF(:)*PRIT(:)/PCIT(:), XLBEXI ) ) ! Lbda_i
+
+!!$ Le DO concurrent n'est pas bit-reproductible BUG NVHPC 20.7
+!!$ DO CONCURRENT ( JL=1:JLU )
+!!$    ZLBEXI(JL) = XLBEXI
+!!$    IF ( GWORK(JL)  ) THEN
+!!$       ZZW(JL) = MIN(1.E8,XLBI*BR_POW( PRHODREF(JL)*PRIT(JL)/PCIT(JL), ZLBEXI(JL) ) ) ! Lbda_i
+!!$       ZZW(JL) = MIN( PRCS(JL),( PSSI(JL) / (PRHODREF(JL)*PAI(JL)) ) * PCIT(JL) * &
+!!$            ( X0DEPI/ZZW(JL) + X2DEPI*PCJ(JL)*PCJ(JL)/BR_POW(ZZW(JL),XDI+2.0) ) )
+!!$       PRCS(JL) = PRCS(JL) - ZZW(JL)
+!!$       PRIS(JL) = PRIS(JL) + ZZW(JL)
+!!$       PTHS(JL) = PTHS(JL) + ZZW(JL)*(PLSFACT(JL)-PLVFACT(JL)) ! f(L_f*(RCBERI))
+!!$    END IF
+!!$ END DO ! CONCURRENT
+ 
+ WHERE( GWORK(:) )
+    ZLBEXI(:) = XLBEXI
+    ZZW(:) = MIN(1.E8,XLBI*BR_POW( PRHODREF(:)*PRIT(:)/PCIT(:), ZLBEXI(:) ) ) ! Lbda_i
     ZZW(:) = MIN( PRCS(:),( PSSI(:) / (PRHODREF(:)*PAI(:)) ) * PCIT(:) * &
-                  ( X0DEPI/ZZW(:) + X2DEPI*PCJ(:)*PCJ(:)/BR_POW(ZZW(:),XDI+2.0) ) )
-#endif
+         ( X0DEPI/ZZW(:) + X2DEPI*PCJ(:)*PCJ(:)/BR_POW(ZZW(:),XDI+2.0) ) )
     PRCS(:) = PRCS(:) - ZZW(:)
     PRIS(:) = PRIS(:) + ZZW(:)
     PTHS(:) = PTHS(:) + ZZW(:)*(PLSFACT(:)-PLVFACT(:)) ! f(L_f*(RCBERI))
-  END WHERE
+ END WHERE
+ 
+#endif 
 !$acc end kernels
 
   if ( lbudget_th ) call Budget_store_add( tbudgets(NBUDGET_TH), 'BERFI', Unpack (  zzw(:) * ( plsfact(:) - plvfact(:) ) &
diff --git a/src/MNH/rain_ice_fast_rs.f90 b/src/MNH/rain_ice_fast_rs.f90
index e12d8727eeb50f36a085f2289f1f753febfd6f7d..203fab9b8df1b7623feadedfe0d97d0c50b9f6eb 100644
--- a/src/MNH/rain_ice_fast_rs.f90
+++ b/src/MNH/rain_ice_fast_rs.f90
@@ -9,6 +9,9 @@
 !  P. Wautelet 03/06/2019: remove PACK/UNPACK intrinsics (to get more performance and better OpenACC support)
 !  P. Wautelet 05/06/2019: optimisations
 !  P. Wautelet    02/2020: use the new data structures and subroutines for budgets
+!  J. Escobar  11/08/2020: Bypass PGI/NVHPC OPENACC BUG, error 700: Illegal address during kernel execution => DO CONCURRENT
+!  J. Escobar  12/08/2020: Bypass PGI/NVHPC OPENACC BUG data partially present => enter data in ini_rain_ce & DO CONCURRENT
+!  J. Escobar  13/08/2020: Openacc PB , missing enter/update data rain_ice_fast_rs/g
 !  P. Wautelet 19/02/2021: bugfix: RIM and ACC terms for budgets are now correctly stored
 !-----------------------------------------------------------------
 MODULE MODE_RAIN_ICE_FAST_RS
@@ -91,6 +94,8 @@ REAL,    DIMENSION(:), ALLOCATABLE :: ZVEC1,ZVEC2,ZVEC3 ! Work vectors for inter
 REAL,    DIMENSION(:), ALLOCATABLE :: ZVECLBDAR, ZVECLBDAS
 REAL,    DIMENSION(:), ALLOCATABLE :: ZZW1, ZZW2, ZZW3, ZZW4 ! Work arrays
 !
+INTEGER                            :: JJU
+!
 !-------------------------------------------------------------------------------
 !
 ! IN variables
@@ -101,12 +106,17 @@ REAL,    DIMENSION(:), ALLOCATABLE :: ZZW1, ZZW2, ZZW3, ZZW4 ! Work arrays
 !
 ! INOUT variables
 !
-!$acc &             PRCS, PRRS, PRSS, PRGS, PTHS )
+!$acc &             PRCS, PRRS, PRSS, PRGS, PTHS , &
+!
+! use variable
+!$acc &             XGAMINC_RIM1,XGAMINC_RIM2, &
+!$acc &             XKER_RACCSS,XKER_RACCS,XKER_SACCRG )
 !
 ! OUT variables
 !
 !NONE
-
+!
+!
 IF (MPPDB_INITIALIZED) THEN
   !Check all IN arrays
   CALL MPPDB_CHECK(OMICRO,"RAIN_ICE_FAST_RS beg:OMICRO")
@@ -131,12 +141,16 @@ IF (MPPDB_INITIALIZED) THEN
   CALL MPPDB_CHECK(PRSS,"RAIN_ICE_FAST_RS beg:PRSS")
   CALL MPPDB_CHECK(PRGS,"RAIN_ICE_FAST_RS beg:PRGS")
   CALL MPPDB_CHECK(PTHS,"RAIN_ICE_FAST_RS beg:PTHS")
+  !Check use variables
+  CALL MPPDB_CHECK(XKER_RACCSS,"RAIN_ICE_FAST_RS beg:XKER_RACCSS")
 END IF
 !
 ALLOCATE( I1   (size(PRHODREF)) )
 ALLOCATE( GWORK(size(PRHODREF)) )
 ALLOCATE( ZZW  (size(PRHODREF)) )
 
+JJU = size(PRHODREF)
+
 !$acc data create( I1, GWORK, ZZW )
 !
 !*       5.1    cloud droplet riming of the aggregates
@@ -193,13 +207,21 @@ CALL COUNTJV_DEVICE( GWORK(:), I1(:), IGRIM )
 !        5.1.3  perform the linear interpolation of the normalized
 !               "2+XDS"-moment of the incomplete gamma function
 !
-    ZVEC1(1:IGRIM) =   XGAMINC_RIM1( IVEC2(1:IGRIM)+1 )* ZVEC2(1:IGRIM)      &
-                     - XGAMINC_RIM1( IVEC2(1:IGRIM)   )*(ZVEC2(1:IGRIM) - 1.0)
+    !$acc loop independent
+    DO CONCURRENT (JJ=1:IGRIM)
+       ZVEC1(JJ) =   XGAMINC_RIM1( IVEC2(JJ)+1 )* ZVEC2(JJ)      &
+                   - XGAMINC_RIM1( IVEC2(JJ)   )*(ZVEC2(JJ) - 1.0)
+    END DO ! CONCURRENT
 !
 !        5.1.4  riming of the small sized aggregates
 !
-!$acc loop independent
-    DO JJ = 1, IGRIM
+    !$acc loop independent , private (JL)
+    DO CONCURRENT ( JJ = 1:IGRIM ) &
+#if defined(MNH_OPENACC) && !defined(_FAKEOPENACC)      
+         LOCAL(JL)
+#else
+ & !     LOCAL(JL)     
+#endif              
       JL = I1(JJ)
 #ifndef MNH_BITREP
       ZZW1(JJ) = MIN( PRCS(JL),                           &
@@ -215,19 +237,37 @@ CALL COUNTJV_DEVICE( GWORK(:), I1(:), IGRIM )
       PRCS(JL) = PRCS(JL) - ZZW1(JJ)
       PRSS(JL) = PRSS(JL) + ZZW1(JJ)
       PTHS(JL) = PTHS(JL) + ZZW1(JJ)*(PLSFACT(JL)-PLVFACT(JL)) ! f(L_f*(RCRIMSS))
-    END DO
+   END DO ! CONCURRENT
+   !
+!$acc end kernels   
+IF (MPPDB_INITIALIZED) THEN
+   CALL MPPDB_CHECK(ZZW1,"RAIN_ICE_FAST_RS 5.1.4:ZZW1")   
+   CALL MPPDB_CHECK(PRCS,"RAIN_ICE_FAST_RS 5.1.4:PRCS")
+   CALL MPPDB_CHECK(PRSS,"RAIN_ICE_FAST_RS 5.1.4:PRSS")
+   CALL MPPDB_CHECK(PTHS,"RAIN_ICE_FAST_RS 5.1.4:PTHS")
+END IF
+!$acc kernels
 !
 !        5.1.5  perform the linear interpolation of the normalized
 !               "XBS"-moment of the incomplete gamma function
 !
-    ZVEC1(1:IGRIM) =  XGAMINC_RIM2( IVEC2(1:IGRIM)+1 )* ZVEC2(1:IGRIM)      &
-                    - XGAMINC_RIM2( IVEC2(1:IGRIM)   )*(ZVEC2(1:IGRIM) - 1.0)
+    !$acc loop independent
+    DO CONCURRENT (JJ=1:IGRIM)
+       ZVEC1(JJ) =  XGAMINC_RIM2( IVEC2(JJ)+1 )* ZVEC2(JJ)      &
+                  - XGAMINC_RIM2( IVEC2(JJ)   )*(ZVEC2(JJ) - 1.0)
+    END DO ! CONCURRENT
 !
 !        5.1.6  riming-conversion of the large sized aggregates into graupeln
 !
-!
-!$acc loop independent
-    DO JJ = 1, IGRIM
+    !
+    !$acc loop independent , private (JL)
+    DO CONCURRENT (JJ = 1:IGRIM ) &
+#if defined(MNH_OPENACC) && !defined(_FAKEOPENACC)
+         LOCAL(JL)
+#else
+ & !     LOCAL(JL)  
+#endif
+       
       JL = I1(JJ)
       IF ( PRSS(JL) > 0.0 ) THEN
 #ifndef MNH_BITREP
@@ -254,9 +294,18 @@ CALL COUNTJV_DEVICE( GWORK(:), I1(:), IGRIM )
         PRGS(JL) = PRGS(JL) + ZZW2(JJ)+ZZW3(JJ)
         PTHS(JL) = PTHS(JL) + ZZW2(JJ)*(PLSFACT(JL)-PLVFACT(JL)) ! f(L_f*(RCRIMSG))
       END IF
-    END DO
+   END DO ! CONCURRENT
 !$acc end kernels
 
+IF (MPPDB_INITIALIZED) THEN
+   CALL MPPDB_CHECK(ZZW1,"RAIN_ICE_FAST_RS 5.1.5:ZZW1")
+   CALL MPPDB_CHECK(ZZW2,"RAIN_ICE_FAST_RS 5.1.5:ZZW2")
+   CALL MPPDB_CHECK(ZZW3,"RAIN_ICE_FAST_RS 5.1.5:ZZW3")
+   CALL MPPDB_CHECK(PRCS,"RAIN_ICE_FAST_RS 5.1.5:PRCS")
+   CALL MPPDB_CHECK(PRSS,"RAIN_ICE_FAST_RS 5.1.5:PRSS")
+   CALL MPPDB_CHECK(PRGS,"RAIN_ICE_FAST_RS 5.1.5:PRGS")
+   CALL MPPDB_CHECK(PTHS,"RAIN_ICE_FAST_RS 5.1.5:PTHS")
+END IF
 !$acc end data
 
     !Remark: not possible to use Budget_store_add here
@@ -346,19 +395,25 @@ CALL COUNTJV_DEVICE( GWORK(:), I1(:), IGRIM )
 !               RACCSS-kernel
 !
 !$acc loop independent
-    DO JJ = 1,IGACC
+    DO CONCURRENT ( JJ = 1:IGACC )
       ZVEC3(JJ) =  (  XKER_RACCSS(IVEC1(JJ)+1,IVEC2(JJ)+1)* ZVEC2(JJ)          &
                     - XKER_RACCSS(IVEC1(JJ)+1,IVEC2(JJ)  )*(ZVEC2(JJ) - 1.0) ) &
                                                           * ZVEC1(JJ) &
                  - (  XKER_RACCSS(IVEC1(JJ)  ,IVEC2(JJ)+1)* ZVEC2(JJ)          &
                     - XKER_RACCSS(IVEC1(JJ)  ,IVEC2(JJ)  )*(ZVEC2(JJ) - 1.0) ) &
                                                           * (ZVEC1(JJ) - 1.0)
-    END DO
+    END DO ! CONCURRENT
 !
 !        5.2.4  raindrop accretion on the small sized aggregates
 !
-!$acc loop independent
-    DO JJ = 1, IGACC
+!$acc loop independent , private (JL)
+    DO CONCURRENT ( JJ = 1:IGACC ) &
+#if defined(MNH_OPENACC) && !defined(_FAKEOPENACC)     
+         LOCAL(JL)
+#else
+ & !     LOCAL(JL)  
+#endif       
+ 
       JL = I1(JJ)
 #ifndef MNH_BITREP
       ZZW2(JJ) =                                                          & !! coef of RRACCS
@@ -377,43 +432,60 @@ CALL COUNTJV_DEVICE( GWORK(:), I1(:), IGRIM )
       PRRS(JL) = PRRS(JL) - ZZW4(JJ)
       PRSS(JL) = PRSS(JL) + ZZW4(JJ)
       PTHS(JL) = PTHS(JL) + ZZW4(JJ)*(PLSFACT(JL)-PLVFACT(JL)) ! f(L_f*(RRACCSS))
-    END DO
+   END DO ! CONCURRENT
+!$acc end kernels
+IF (MPPDB_INITIALIZED) THEN
+   CALL MPPDB_CHECK(ZVEC1,"RAIN_ICE_FAST_RS 5.2.4:IVEC1")
+   CALL MPPDB_CHECK(ZVEC2,"RAIN_ICE_FAST_RS 5.2.4:IVEC2")
+   CALL MPPDB_CHECK(ZVEC1,"RAIN_ICE_FAST_RS 5.2.4:ZVEC1")
+   CALL MPPDB_CHECK(ZVEC2,"RAIN_ICE_FAST_RS 5.2.4:ZVEC2")
+   CALL MPPDB_CHECK(ZVEC3,"RAIN_ICE_FAST_RS 5.2.4:ZVEC3")   
+   CALL MPPDB_CHECK(ZZW2,"RAIN_ICE_FAST_RS 5.2.4:ZZW2")   
+   CALL MPPDB_CHECK(ZZW4,"RAIN_ICE_FAST_RS 5.2.4:ZZW4")   
+   CALL MPPDB_CHECK(PRRS,"RAIN_ICE_FAST_RS 5.2.4:PRRS")
+END IF   
+!$acc kernels    
 !
 !        5.2.4b perform the bilinear interpolation of the normalized
 !               RACCS-kernel
 !
-!$acc loop independent
-    DO JJ = 1,IGACC
+    !$acc loop independent
+    DO CONCURRENT (JJ = 1:IGACC )
       ZVEC3(JJ) =  (   XKER_RACCS(IVEC2(JJ)+1,IVEC1(JJ)+1)* ZVEC1(JJ)          &
                     -  XKER_RACCS(IVEC2(JJ)+1,IVEC1(JJ)  )*(ZVEC1(JJ) - 1.0) ) &
                                                                    * ZVEC2(JJ) &
                  - (   XKER_RACCS(IVEC2(JJ)  ,IVEC1(JJ)+1)* ZVEC1(JJ)          &
                     -  XKER_RACCS(IVEC2(JJ)  ,IVEC1(JJ)  )*(ZVEC1(JJ) - 1.0) ) &
                                                            * (ZVEC2(JJ) - 1.0)
-    END DO
-!$acc loop independent
+    END DO ! CONCURRENT
     DO JJ = 1, IGACC
       ZZW2(JJ) = ZZW2(JJ) * ZVEC3(JJ)
     END DO
                                                                        !! RRACCS!
 !        5.2.5  perform the bilinear interpolation of the normalized
 !               SACCRG-kernel
-!
-!$acc loop independent
-    DO JJ = 1,IGACC
+    !
+    !$acc loop independent
+    DO CONCURRENT (JJ = 1:IGACC )
       ZVEC3(JJ) =  (  XKER_SACCRG(IVEC2(JJ)+1,IVEC1(JJ)+1)* ZVEC1(JJ)          &
                     - XKER_SACCRG(IVEC2(JJ)+1,IVEC1(JJ)  )*(ZVEC1(JJ) - 1.0) ) &
                                                           * ZVEC2(JJ) &
                  - (  XKER_SACCRG(IVEC2(JJ)  ,IVEC1(JJ)+1)* ZVEC1(JJ)          &
                     - XKER_SACCRG(IVEC2(JJ)  ,IVEC1(JJ)  )*(ZVEC1(JJ) - 1.0) ) &
                                                           * (ZVEC2(JJ) - 1.0)
-    END DO
+    END DO ! CONCURRENT
 !
 !        5.2.6  raindrop accretion-conversion of the large sized aggregates
 !               into graupeln
-!
-!$acc loop independent
-    DO JJ = 1, IGACC
+    !
+    !$acc loop independent , private (JL)
+    DO CONCURRENT ( JJ = 1:IGACC ) &
+#if defined(MNH_OPENACC) && !defined(_FAKEOPENACC)     
+         LOCAL(JL)
+#else
+ & !     LOCAL(JL)     
+#endif       
+ 
       JL = I1(JJ)
       IF ( PRSS(JL) > 0.0 ) THEN
         ZZW2(JJ) = MAX( MIN( PRRS(JL),ZZW2(JJ)-ZZW4(JJ) ),0.0 )       ! RRACCSG
@@ -438,7 +510,7 @@ CALL COUNTJV_DEVICE( GWORK(:), I1(:), IGRIM )
                                 ! f(L_f*(RRACCSG))
         END IF
       END IF
-    END DO
+    END DO ! CONCURRENT
 !$acc end kernels
 
 !$acc end data
@@ -471,32 +543,35 @@ CALL COUNTJV_DEVICE( GWORK(:), I1(:), IGRIM )
 !$acc kernels
   zzw(:) = 0.
   GWORK(:) = PRST(:)>XRTMIN(5) .AND. PRSS(:)>0.0 .AND. PZT(:)>XTT
-  WHERE( GWORK(:) )
-    ZZW(:) = PRVT(:)*PPRES(:)/((XMV/XMD)+PRVT(:)) ! Vapor pressure
-    ZZW(:) =  PKA(:)*(XTT-PZT(:)) +                                 &
-               ( PDV(:)*(XLVTT + ( XCPV - XCL ) * ( PZT(:) - XTT )) &
-                           *(XESTT-ZZW(:))/(XRV*PZT(:))             )
+  !$acc loop independent
+  DO CONCURRENT (JJ=1:JJU)
+   IF ( GWORK(JJ) ) THEN
+    ZZW(JJ) = PRVT(JJ)*PPRES(JJ)/((XMV/XMD)+PRVT(JJ)) ! Vapor pressure
+    ZZW(JJ) =  PKA(JJ)*(XTT-PZT(JJ)) +                                 &
+               ( PDV(JJ)*(XLVTT + ( XCPV - XCL ) * ( PZT(JJ) - XTT )) &
+                           *(XESTT-ZZW(JJ))/(XRV*PZT(JJ))             )
 !
 ! compute RSMLT
 !
 #ifndef MNH_BITREP
-    ZZW(:)  = MIN( PRSS(:), XFSCVMG*MAX( 0.0,( -ZZW(:) *             &
-                           ( X0DEPS*       PLBDAS(:)**XEX0DEPS +     &
-                             X1DEPS*PCJ(:)*PLBDAS(:)**XEX1DEPS ) ) / &
-                                             ( PRHODREF(:)*XLMTT ) ) )
+    ZZW(JJ)  = MIN( PRSS(JJ), XFSCVMG*MAX( 0.0,( -ZZW(JJ) *             &
+                           ( X0DEPS*       PLBDAS(JJ)**XEX0DEPS +     &
+                             X1DEPS*PCJ(JJ)*PLBDAS(JJ)**XEX1DEPS ) ) / &
+                                             ( PRHODREF(JJ)*XLMTT ) ) )
 #else
-    ZZW(:)  = MIN( PRSS(:), XFSCVMG*MAX( 0.0,( -ZZW(:) *                    &
-                           ( X0DEPS*       BR_POW(PLBDAS(:),XEX0DEPS) +     &
-                             X1DEPS*PCJ(:)*BR_POW(PLBDAS(:),XEX1DEPS) ) ) / &
-                                             ( PRHODREF(:)*XLMTT ) ) )
+    ZZW(JJ)  = MIN( PRSS(JJ), XFSCVMG*MAX( 0.0,( -ZZW(JJ) *                    &
+                           ( X0DEPS*       BR_POW(PLBDAS(JJ),XEX0DEPS) +     &
+                             X1DEPS*PCJ(JJ)*BR_POW(PLBDAS(JJ),XEX1DEPS) ) ) / &
+                                             ( PRHODREF(JJ)*XLMTT ) ) )
 #endif
 !
 ! note that RSCVMG = RSMLT*XFSCVMG but no heat is exchanged (at the rate RSMLT)
 ! because the graupeln produced by this process are still icy!!!
 !
-    PRSS(:) = PRSS(:) - ZZW(:)
-    PRGS(:) = PRGS(:) + ZZW(:)
-  END WHERE
+    PRSS(JJ) = PRSS(JJ) - ZZW(JJ)
+    PRGS(JJ) = PRGS(JJ) + ZZW(JJ)
+  END IF
+ END DO ! CONCURRENT
 !$acc end kernels
 
   if ( lbudget_rs ) call Budget_store_add( tbudgets(NBUDGET_RS), 'CMEL', &
diff --git a/src/MNH/rain_ice_nucleation.f90 b/src/MNH/rain_ice_nucleation.f90
index e98cbede16cfb6bb7033e9980efd1b3f258ffd00..330bbba3cf6d8c2a0915bbcf14b000c27fb37be2 100644
--- a/src/MNH/rain_ice_nucleation.f90
+++ b/src/MNH/rain_ice_nucleation.f90
@@ -45,6 +45,12 @@ use mode_tools,           only: Countjv_device
 use modi_bitrep
 #endif
 
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_ZT1DP , MNH_REL_ZT1D , &
+                            MNH_ALLOCATE_GT3D , MNH_REL_GT3D, &
+                            MNH_ALLOCATE_IT1D ,MNH_ALLOCATE_IT1DP , MNH_REL_IT1D  
+#endif
+
 IMPLICIT NONE
 !
 !*       0.1   Declarations of dummy arguments :
@@ -75,17 +81,33 @@ REAL, DIMENSION(:,:,:), OPTIONAL, INTENT(IN)    :: PRHT    ! Hail m.r. at t
 !
 INTEGER                                :: INEGT
 INTEGER                                :: JL       ! and PACK intrinsics
-INTEGER, DIMENSION(:),     allocatable :: I1,I2,I3 ! Used to replace the COUNT
-LOGICAL, DIMENSION(:,:,:), allocatable :: GNEGT    ! Test where to compute the HEN process
+INTEGER, DIMENSION(:),     POINTER, CONTIGUOUS :: I1,I2,I3 ! Used to replace the COUNT
+#ifdef MNH_OPENACC
+INTEGER :: II1,II2,II3
+#endif
+LOGICAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: GNEGT    ! Test where to compute the HEN process
+#ifdef MNH_OPENACC
+INTEGER :: IGNEGT
+#endif
 REAL                                   :: ZZWMAX
-REAL,    DIMENSION(:), ALLOCATABLE     :: ZRVT     ! Water vapor m.r. at t
-REAL,    DIMENSION(:), ALLOCATABLE     :: ZCIT     ! Pristine ice conc. at t
-REAL,    DIMENSION(:), ALLOCATABLE     :: ZZT,   & ! Temperature
+REAL,    DIMENSION(:), POINTER, CONTIGUOUS     :: ZRVT     ! Water vapor m.r. at t
+REAL,    DIMENSION(:), POINTER, CONTIGUOUS     :: ZCIT     ! Pristine ice conc. at t
+REAL,    DIMENSION(:), POINTER, CONTIGUOUS     :: ZZT,   & ! Temperature
                                           ZPRES, & ! Pressure
                                           ZZW,   & ! Work array
                                           ZUSW,  & ! Undersaturation over water
                                           ZSSI     ! Supersaturation over ice
-REAL,    DIMENSION(:,:,:), allocatable :: ZW      ! work array
+#ifdef MNH_OPENACC
+INTEGER :: IZRVT,IZCIT,IZZT,IZPRES,IZZW,IZUSW,IZSSI
+#endif
+REAL,    DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZW      ! work array
+#ifdef MNH_OPENACC
+INTEGER :: IZW
+#endif
+
+INTEGER :: JIU,JJU,JKU, JIJKU
+
+INTEGER :: JI,JJ,JK
 !
 !-------------------------------------------------------------------------------
 !
@@ -123,13 +145,26 @@ IF (MPPDB_INITIALIZED) THEN
   CALL MPPDB_CHECK(PRIS,"RAIN_ICE_NUCLEATION beg:PRIS")
 END IF
 
-allocate( i1( size( pexnref ) ) )
-allocate( i2( size( pexnref ) ) )
-allocate( i3( size( pexnref ) ) )
-allocate( gnegt( size( pexnref, 1 ), size( pexnref, 2 ), size( pexnref, 3 ) ) )
-allocate( zw   ( size( pexnref, 1 ), size( pexnref, 2 ), size( pexnref, 3 ) ) )
+JIU =  size(PEXNREF, 1 )
+JJU =  size(PEXNREF, 2 )
+JKU =  size(PEXNREF, 3 )
+JIJKU = JIU * JJU * JKU
 
-!$acc data create( i1, i2, i3, gnegt, zw )
+#ifndef MNH_OPENACC
+allocate( i1( JIJKU ) )
+allocate( i2( JIJKU ) )
+allocate( i3( JIJKU ) )
+allocate( gnegt( JIU,JJU,JKU ) )
+allocate( zw   ( JIU,JJU,JKU ) )
+#else
+II1 = MNH_ALLOCATE_IT1D( i1, JIJKU )
+II2 = MNH_ALLOCATE_IT1D( i2, JIJKU )
+II3 = MNH_ALLOCATE_IT1D( i3, JIJKU )
+IGNEGT = MNH_ALLOCATE_GT3D( gnegt, JIU,JJU,JKU  )
+IZW = MNH_ALLOCATE_ZT3D( zw   , JIU,JJU,JKU  )
+#endif
+
+!$acc data present( i1, i2, i3, gnegt, zw )
 
 if ( lbudget_th ) call Budget_store_init( tbudgets(NBUDGET_TH), 'HENU', pths(:, :, :) * prhodj(:, :, :) )
 if ( lbudget_rv ) call Budget_store_init( tbudgets(NBUDGET_RV), 'HENU', prvs(:, :, :) * prhodj(:, :, :) )
@@ -141,7 +176,10 @@ if ( lbudget_ri ) call Budget_store_init( tbudgets(NBUDGET_RI), 'HENU', pris(:,
 #ifndef MNH_BITREP
 PT(:,:,:) = PTHT(:,:,:) * ( PPABST(:,:,:) / XP00 ) ** ( XRD / XCPD )
 #else
-PT(:,:,:) = PTHT(:,:,:) * BR_POW( PPABST(:,:,:) / XP00, XRD / XCPD )
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   PT(JI,JJ,JK) = PTHT(JI,JJ,JK) * BR_POW( PPABST(JI,JJ,JK) / XP00, XRD / XCPD )
+END DO
 #endif
 !
 !  optimization by looking for locations where
@@ -156,73 +194,122 @@ INEGT = COUNTJV( GNEGT(:,:,:),I1(:),I2(:),I3(:))
 CALL COUNTJV_DEVICE(GNEGT(:,:,:),I1(:),I2(:),I3(:),INEGT)
 #endif
 IF( INEGT >= 1 ) THEN
-  ALLOCATE(ZRVT(INEGT)) ;
-  ALLOCATE(ZCIT(INEGT)) ;
-  ALLOCATE(ZZT(INEGT))  ;
-  ALLOCATE(ZPRES(INEGT));
+#ifndef MNH_OPENACC   
+  ALLOCATE(ZRVT(INEGT)) 
+  ALLOCATE(ZCIT(INEGT)) 
+  ALLOCATE(ZZT(INEGT))  
+  ALLOCATE(ZPRES(INEGT))
   ALLOCATE(ZZW(INEGT))
   ALLOCATE(ZUSW(INEGT))
   ALLOCATE(ZSSI(INEGT))
-!$acc data create( zrvt, zcit, zzt, zpres, zzw, zusw, zssi )
+#else
+  IZRVT   = MNH_ALLOCATE_ZT1DP(ZRVT,INEGT) 
+  IZCIT   = MNH_ALLOCATE_ZT1DP(ZCIT,INEGT) 
+  IZZT    = MNH_ALLOCATE_ZT1DP(ZZT,INEGT)  
+  IZPRES  = MNH_ALLOCATE_ZT1DP(ZPRES,INEGT)
+  IZZW    = MNH_ALLOCATE_ZT1DP(ZZW,INEGT)
+  IZUSW   = MNH_ALLOCATE_ZT1DP(ZUSW,INEGT)
+  IZSSI   = MNH_ALLOCATE_ZT1DP(ZSSI,INEGT)  
+#endif
+  
+!$acc data present( zrvt, zcit, zzt, zpres, zzw, zusw, zssi )
 
-!$acc kernels
-  DO JL=1,INEGT
+  !$acc kernels 
+  !$acc loop independent
+  DO CONCURRENT ( JL=1:INEGT )
     ZRVT(JL)  = PRVT  (I1(JL),I2(JL),I3(JL))
     ZCIT(JL)  = PCIT  (I1(JL),I2(JL),I3(JL))
     ZZT(JL)   = PT    (I1(JL),I2(JL),I3(JL))
     ZPRES(JL) = PPABST(I1(JL),I2(JL),I3(JL))
   ENDDO
 #ifndef MNH_BITREP
-  ZZW(1:INEGT) = EXP( XALPI - XBETAI/ZZT(1:INEGT) - XGAMI*ALOG(ZZT(1:INEGT) ) )           ! es_i
+  !$acc loop independent
+  DO CONCURRENT ( JL=1:INEGT )
+    ZZW(JL) = EXP( XALPI - XBETAI/ZZT(JL) - XGAMI*BR_LOG(ZZT(JL) ) )      ! es_i
+  END DO
 #else
-  ZZW(1:INEGT) = BR_EXP( XALPI - XBETAI/ZZT(1:INEGT) - XGAMI*BR_LOG(ZZT(1:INEGT) ) )      ! es_i
+  !$acc loop independent
+  DO CONCURRENT ( JL=1:INEGT )
+    ZZW(JL) = BR_EXP( XALPI - XBETAI/ZZT(JL) - XGAMI*BR_LOG(ZZT(JL) ) )      ! es_i
+  END DO
 #endif
-  ZZW(1:INEGT) = MIN(ZPRES(1:INEGT)/2., ZZW(1:INEGT))             ! safety limitation
-  ZSSI(1:INEGT) = ZRVT(1:INEGT)*( ZPRES(1:INEGT)-ZZW(1:INEGT) ) / ( (XMV/XMD) * ZZW(1:INEGT) ) - 1.0
-                                                    ! Supersaturation over ice
+  !$acc loop independent
+  DO CONCURRENT ( JL=1:INEGT )
+    ZZW(JL) = MIN(ZPRES(JL)/2., ZZW(JL))             ! safety limitation
+    ZSSI(JL) = ZRVT(JL)*( ZPRES(JL)-ZZW(JL) ) / ( (XMV/XMD) * ZZW(JL) ) - 1.0
+                         ! Supersaturation over ice
+  END DO
 #ifndef MNH_BITREP
-  ZUSW(1:INEGT) = EXP( XALPW - XBETAW/ZZT(1:INEGT) - XGAMW*ALOG(ZZT(1:INEGT) ) )          ! es_w
+  !$acc loop independent
+  DO CONCURRENT ( JL=1:INEGT )
+    ZUSW(JL) = EXP( XALPW - XBETAW/ZZT(JL) - XGAMW*BR_LOG(ZZT(JL) ) )     ! es_w
+    ZUSW(JL) = MIN(ZPRES(JL)/2.,ZUSW(JL))            ! safety limitation
+    ZUSW(JL) = ( ZUSW(JL)/ZZW(JL) )*( (ZPRES(JL)-ZZW(JL))/(ZPRES(JL)-ZUSW(JL)) ) - 1.0
+                       ! Supersaturation of saturated water vapor over ice
+  END DO
 #else
-  ZUSW(1:INEGT) = BR_EXP( XALPW - XBETAW/ZZT(1:INEGT) - XGAMW*BR_LOG(ZZT(1:INEGT) ) )     ! es_w
-#endif
-  ZUSW(1:INEGT) = MIN(ZPRES(1:INEGT)/2.,ZUSW(1:INEGT))            ! safety limitation
-  ZUSW(1:INEGT) = ( ZUSW(1:INEGT)/ZZW(1:INEGT) )*( (ZPRES(1:INEGT)-ZZW(1:INEGT))/(ZPRES(1:INEGT)-ZUSW(1:INEGT)) ) - 1.0
-                           ! Supersaturation of saturated water vapor over ice
+  !$acc loop independent
+  DO CONCURRENT ( JL=1:INEGT )
+    ZUSW(JL) = BR_EXP( XALPW - XBETAW/ZZT(JL) - XGAMW*BR_LOG(ZZT(JL) ) )     ! es_w
+    ZUSW(JL) = MIN(ZPRES(JL)/2.,ZUSW(JL))            ! safety limitation
+    ZUSW(JL) = ( ZUSW(JL)/ZZW(JL) )*( (ZPRES(JL)-ZZW(JL))/(ZPRES(JL)-ZUSW(JL)) ) - 1.0
+                       ! Supersaturation of saturated water vapor over ice
+  END DO
+#endif  
 !
 !*       3.1     compute the heterogeneous nucleation source: RVHENI
 !
 !*       3.1.1   compute the cloud ice concentration
 !
-  ZZW(1:INEGT) = 0.0
-  ZSSI(1:INEGT) = MIN( ZSSI(1:INEGT), ZUSW(1:INEGT) ) ! limitation of SSi according to SSw=0
-  WHERE( (ZZT(1:INEGT)<XTT-5.0) .AND. (ZSSI(1:INEGT)>0.0) )
+!$acc loop independent
+DO CONCURRENT ( JL=1:INEGT )
+  ZZW(JL) = 0.0
+  ZSSI(JL) = MIN( ZSSI(JL), ZUSW(JL) ) ! limitation of SSi according to SSw=0
+  IF ( (ZZT(JL)<XTT-5.0) .AND. (ZSSI(JL)>0.0) ) THEN
 #ifndef MNH_BITREP
-    ZZW(1:INEGT) = XNU20 * EXP( XALPHA2*ZSSI(1:INEGT)-XBETA2 )
+    ZZW(JL) = XNU20 * EXP( XALPHA2*ZSSI(JL)-XBETA2 )
 #else
-    ZZW(1:INEGT) = XNU20 * BR_EXP( XALPHA2*ZSSI(1:INEGT)-XBETA2 )
+    ZZW(JL) = XNU20 * BR_EXP( XALPHA2*ZSSI(JL)-XBETA2 )
 #endif
-  END WHERE
-  WHERE( (ZZT(1:INEGT)<=XTT-2.0) .AND. (ZZT(1:INEGT)>=XTT-5.0) .AND. (ZSSI(1:INEGT)>0.0) )
+ END IF
+END DO
 #ifndef MNH_BITREP
-    ZZW(1:INEGT) = MAX( XNU20 * EXP( -XBETA2 ),XNU10 * EXP( -XBETA1*(ZZT(1:INEGT)-XTT) ) * &
-                               ( ZSSI(1:INEGT)/ZUSW(1:INEGT) )**XALPHA1 )
+ !$acc loop independent
+ DO CONCURRENT ( JL=1:INEGT )
+    IF ( (ZZT(JL)<=XTT-2.0) .AND. (ZZT(JL)>=XTT-5.0) .AND. (ZSSI(JL)>0.0) ) THEN
+       ZZW(JL) = MAX( XNU20 * EXP( -XBETA2 ),XNU10 * EXP( -XBETA1*(ZZT(JL)-XTT) ) * &
+            ( ZSSI(JL)/ZUSW(JL) )**XALPHA1 )
+    END IF
+ END DO ! CONCURRENT
 #else
-    ZZW(1:INEGT) = MAX( XNU20 * BR_EXP( -XBETA2 ),XNU10 * BR_EXP( -XBETA1*(ZZT(1:INEGT)-XTT) ) * &
-                               BR_POW( ZSSI(1:INEGT)/ZUSW(1:INEGT),XALPHA1 ) )
+ !$acc loop independent
+ DO CONCURRENT ( JL=1:INEGT )
+    IF ( (ZZT(JL)<=XTT-2.0) .AND. (ZZT(JL)>=XTT-5.0) .AND. (ZSSI(JL)>0.0) ) THEN
+       ZZW(JL) = MAX( XNU20 * BR_EXP( -XBETA2 ),XNU10 * BR_EXP( -XBETA1*(ZZT(JL)-XTT) ) * &
+            BR_POW( ZSSI(JL)/ZUSW(JL),XALPHA1 ) )
+    END IF
+ END DO ! CONCURRENT
 #endif
-  END WHERE
-  ZZW(1:INEGT) = ZZW(1:INEGT) - ZCIT(1:INEGT)
+ ! WARNING COMPILER BUG NVHPC20.X/3 <-> if array syntaxe ZZW(1:INEGT) = ZZW(1:INEGT)
+ !$acc loop independent
+ DO CONCURRENT ( JL=1:INEGT )
+    ZZW(JL) = ZZW(JL) - ZCIT(JL)
+ END DO
   ZZWMAX = MAXVAL(ZZW(1:INEGT))
 !$acc end kernels
-!$acc kernels
+
   IF( ZZWMAX > 0.0 ) THEN
+  !$acc kernels     
 !
 !*       3.1.2   update the r_i and r_v mixing ratios
-!
-    ZZW(1:INEGT) = MIN( ZZW(1:INEGT),50.E3 ) ! limitation provisoire a 50 l^-1
+     !
+  !$acc loop independent
+  DO CONCURRENT ( JL=1:INEGT )
+     ZZW(JL) = MIN( ZZW(JL),50.E3 ) ! limitation provisoire a 50 l^-1
+  END DO
     ZW(:,:,:) = 0.0
-!$acc loop independent
-    DO JL=1, INEGT
+    !$acc loop independent
+    DO CONCURRENT ( JL=1:INEGT )
       ZW(I1(JL), I2(JL), I3(JL)) = ZZW( JL )
     END DO
     ZW(:,:,:) = MAX( ZW(:,:,:) ,0.0 ) *XMNU0/(PRHODREF(:,:,:)*PTSTEP)
@@ -238,16 +325,21 @@ IF( INEGT >= 1 ) THEN
                    + XCI*(PRIT(:,:,:)+PRST(:,:,:)+PRGT(:,:,:)))*PEXNREF(:,:,:) )
     END IF
                                  ! f(L_s*(RVHENI))
-    ZZW(1:INEGT) = MAX( ZZW(1:INEGT)+ZCIT(1:INEGT),ZCIT(1:INEGT) )
+    !$acc loop independent
+    DO CONCURRENT ( JL=1:INEGT )
+       ZZW(JL) = MAX( ZZW(JL)+ZCIT(JL),ZCIT(JL) )
+    END DO
     PCIT(:,:,:) = MAX( PCIT(:,:,:), 0.0 )
-!$acc loop independent
-    DO JL = 1, INEGT
+    !$acc loop independent
+    DO CONCURRENT ( JL=1:INEGT )
       PCIT(I1(JL), I2(JL), I3(JL)) = MAX( ZZW( JL ), PCIT(I1(JL), I2(JL), I3(JL)), 0.0 )
-    END DO
-  END IF
-!$acc end kernels
+   END DO
+  !$acc end kernels
+END IF
 
 !$acc end data
+  
+#ifndef MNH_OPENACC
   DEALLOCATE(ZSSI)
   DEALLOCATE(ZUSW)
   DEALLOCATE(ZZW)
@@ -255,6 +347,10 @@ IF( INEGT >= 1 ) THEN
   DEALLOCATE(ZZT)
   DEALLOCATE(ZCIT)
   DEALLOCATE(ZRVT)
+#else
+  CALL MNH_REL_ZT1D(izrvt, izcit, izzt, izpres, izzw, izusw, izssi)
+#endif  
+  
 END IF
 !
 !*       3.1.3   budget storage
@@ -273,6 +369,13 @@ IF (MPPDB_INITIALIZED) THEN
   CALL MPPDB_CHECK(PT,"RAIN_ICE_NUCLEATION end:PT")
 END IF
 
+#ifndef MNH_OPENACC
+deallocate (i1, i2, i3, gnegt, zw )
+#else
+CALL MNH_REL_IT1D(ii1, ii2, ii3)
+CALL MNH_REL_GT3D(IGNEGT)
+CALL MNH_REL_ZT3D(IZW)
+#endif
 !$acc end data
 
 !$acc end data
diff --git a/src/MNH/rain_ice_sedimentation_split.f90 b/src/MNH/rain_ice_sedimentation_split.f90
index b826e9f75fa1bd0f5a6e983b4bd02ff2a4a8ed21..8fdf9a95d5a843f4e719e357e34e5d64de7e31f2 100644
--- a/src/MNH/rain_ice_sedimentation_split.f90
+++ b/src/MNH/rain_ice_sedimentation_split.f90
@@ -51,6 +51,12 @@ use mode_tools,           only: Countjv_device
 USE MODI_BITREP
 #endif
 
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_ALLOCATE_ZT2D, MNH_REL_ZT3D, MNH_ALLOCATE_ZT1DP , MNH_REL_ZT1D , &
+                            MNH_ALLOCATE_GT3D , MNH_ALLOCATE_GT2D, MNH_REL_GT3D, &
+                            MNH_ALLOCATE_IT1D , MNH_REL_IT1D
+#endif
+
 IMPLICIT NONE
 !
 !*       0.1   Declarations of dummy arguments :
@@ -99,21 +105,32 @@ INTEGER                                :: ISEDIMR, ISEDIMC, ISEDIMI, ISEDIMS, IS
 INTEGER                                :: JI, JJ, JK    ! Loop indices on grid
 INTEGER                                :: JN            ! Temporal loop index for the rain sedimentation
 INTEGER                                :: JL
-INTEGER, DIMENSION(:),     ALLOCATABLE :: IC1, IC2, IC3 ! Used to replace the COUNT
-INTEGER, DIMENSION(:),     ALLOCATABLE :: IR1, IR2, IR3 ! Used to replace the COUNT
-INTEGER, DIMENSION(:),     ALLOCATABLE :: IS1, IS2, IS3 ! Used to replace the COUNT
-INTEGER, DIMENSION(:),     ALLOCATABLE :: II1, II2, II3 ! Used to replace the COUNT
-INTEGER, DIMENSION(:),     ALLOCATABLE :: IG1, IG2, IG3 ! Used to replace the COUNT
-INTEGER, DIMENSION(:),     ALLOCATABLE :: IH1, IH2, IH3 ! Used to replace the COUNT
+INTEGER, DIMENSION(:),     POINTER, CONTIGUOUS :: IC1, IC2, IC3 ! Used to replace the COUNT
+INTEGER, DIMENSION(:),     POINTER, CONTIGUOUS :: IR1, IR2, IR3 ! Used to replace the COUNT
+INTEGER, DIMENSION(:),     POINTER, CONTIGUOUS :: IS1, IS2, IS3 ! Used to replace the COUNT
+#ifdef MNH_OPENACC
+INTEGER :: IIC1, IIC2, IIC3, IIR1, IIR2, IIR3, IIS1, IIS2, IIS3
+#endif
+INTEGER, DIMENSION(:),     POINTER, CONTIGUOUS :: II1, II2, II3 ! Used to replace the COUNT
+INTEGER, DIMENSION(:),     POINTER, CONTIGUOUS :: IG1, IG2, IG3 ! Used to replace the COUNT
+INTEGER, DIMENSION(:),     POINTER, CONTIGUOUS :: IH1, IH2, IH3 ! Used to replace the COUNT
+#ifdef MNH_OPENACC
+INTEGER :: III1, III2, III3, IIG1, IIG2, IIG3, IIH1, IIH2, IIH3
+#endif
+
 LOGICAL                                :: GPRESENT_PFPR, GPRESENT_PSEA
-LOGICAL, DIMENSION(:,:),   ALLOCATABLE :: GDEP
-LOGICAL, DIMENSION(:,:,:), ALLOCATABLE :: GSEDIMR, GSEDIMC, GSEDIMI, GSEDIMS, GSEDIMG, GSEDIMH ! Where to compute the SED processes
+LOGICAL, DIMENSION(:,:),   POINTER, CONTIGUOUS :: GDEP
+LOGICAL, DIMENSION(:,:,:), POINTER, CONTIGUOUS :: GSEDIMR, GSEDIMC, GSEDIMI, GSEDIMS, GSEDIMG, GSEDIMH ! Where to compute the SED processes
+#ifdef MNH_OPENACC
+INTEGER :: IGDEP,IGSEDIMR, IGSEDIMC, IGSEDIMI, IGSEDIMS, IGSEDIMG, IGSEDIMH
+#endif
 REAL                                   :: ZINVTSTEP
 REAL                                   :: ZTSPLITR            ! Small time step for rain sedimentation
 REAL                                   :: ZTMP1, ZTMP2, ZTMP3 ! Intermediate variables
 REAL                                   :: ZRHODREFLOC         ! RHO Dry REFerence
 REAL                                   :: ZRSLOC, ZRTLOC      ! Intermediate variables
-REAL,    DIMENSION(:), ALLOCATABLE     :: ZRTMIN
+REAL,    DIMENSION(:), POINTER, CONTIGUOUS     :: ZRTMIN
+
 ! XRTMIN = Minimum value for the mixing ratio
 ! ZRTMIN = Minimum value for the source (tendency)
 REAL                                   :: ZCC,      & ! terminal velocity
@@ -124,15 +141,24 @@ REAL                                   :: ZCC,      & ! terminal velocity
                                           ZWLBDA,   & ! Free mean path
                                           ZZT,      & ! Temperature
                                           ZPRES       ! Pressure
-REAL,    DIMENSION(:,:),   ALLOCATABLE :: ZCONC_TMP   ! Weighted concentration
-REAL,    DIMENSION(:,:,:), ALLOCATABLE :: ZCONC3D     ! Doplet condensation
-REAL,    DIMENSION(:,:),   ALLOCATABLE :: ZOMPSEA,ZTMP1_2D,ZTMP2_2D,ZTMP3_2D,ZTMP4_2D !Work arrays
-REAL,    DIMENSION(:,:,:), ALLOCATABLE :: ZRAY,   &   ! Cloud Mean radius
+REAL,    DIMENSION(:,:),   POINTER, CONTIGUOUS :: ZCONC_TMP   ! Weighted concentration
+REAL,    DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZCONC3D     ! Doplet condensation
+REAL,    DIMENSION(:,:),   POINTER, CONTIGUOUS :: ZOMPSEA,ZTMP1_2D,ZTMP2_2D,ZTMP3_2D,ZTMP4_2D !Work arrays
+REAL,    DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZRAY,   &   ! Cloud Mean radius
                                           ZLBC,   &   ! XLBC weighted by sea fraction
                                           ZFSEDC
-REAL,    DIMENSION(:,:,:), ALLOCATABLE :: ZPRCS,ZPRRS,ZPRSS,ZPRGS,ZPRHS   ! Mixing ratios created during the time step
-REAL,    DIMENSION(:,:,:), ALLOCATABLE :: ZW          ! Work array
-REAL,    DIMENSION(:,:,:), ALLOCATABLE :: ZWSED       ! sedimentation fluxes
+#ifdef MNH_OPENACC
+INTEGER :: IZCONC_TMP,IZCONC3D,IZOMPSEA,IZTMP1_2D,IZTMP2_2D,IZTMP3_2D,IZTMP4_2D,IZRAY,IZLBC,IZFSEDC
+#endif
+
+REAL,    DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZPRCS,ZPRRS,ZPRSS,ZPRGS,ZPRHS   ! Mixing ratios created during the time step
+REAL,    DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZW          ! Work array
+REAL,    DIMENSION(:,:,:), POINTER, CONTIGUOUS :: ZWSED       ! sedimentation fluxes
+#ifdef MNH_OPENACC
+INTEGER :: IZPRCS,IZPRRS,IZPRSS,IZPRGS,IZPRHS,IZW,IZWSED
+#endif
+
+INTEGER :: IIU,IJU,IKU, IIJKU
 !
 !-------------------------------------------------------------------------------
 !
@@ -176,45 +202,103 @@ IF (MPPDB_INITIALIZED) THEN
   CALL MPPDB_CHECK(PRGS,"RAIN_ICE_SEDIMENTATION_SPLIT beg:PRGS")
   IF (PRESENT(PRHS)) CALL MPPDB_CHECK(PRHS,"RAIN_ICE_SEDIMENTATION_SPLIT beg:PRHS")
 END IF
+
+IIU =  size(PRCS, 1 )
+IJU =  size(PRCS, 2 )
+IKU =  size(PRCS, 3 )
+IIJKU = IIU * IJU * IKU
+
 !
-ALLOCATE( IC1(size(PRCS)), IC2(size(PRCS)), IC3(size(PRCS)) )
-ALLOCATE( IR1(size(PRCS)), IR2(size(PRCS)), IR3(size(PRCS)) )
-ALLOCATE( IS1(size(PRCS)), IS2(size(PRCS)), IS3(size(PRCS)) )
-ALLOCATE( II1(size(PRCS)), II2(size(PRCS)), II3(size(PRCS)) )
-ALLOCATE( IG1(size(PRCS)), IG2(size(PRCS)), IG3(size(PRCS)) )
-ALLOCATE( IH1(size(PRCS)), IH2(size(PRCS)), IH3(size(PRCS)) )
-ALLOCATE( GDEP(SIZE(PRCS,1),SIZE(PRCS,2)) )
-ALLOCATE( GSEDIMR(SIZE(PRCS,1),SIZE(PRCS,2),SIZE(PRCS,3)) )
-ALLOCATE( GSEDIMC(SIZE(PRCS,1),SIZE(PRCS,2),SIZE(PRCS,3)) )
-ALLOCATE( GSEDIMI(SIZE(PRCS,1),SIZE(PRCS,2),SIZE(PRCS,3)) )
-ALLOCATE( GSEDIMS(SIZE(PRCS,1),SIZE(PRCS,2),SIZE(PRCS,3)) )
-ALLOCATE( GSEDIMG(SIZE(PRCS,1),SIZE(PRCS,2),SIZE(PRCS,3)) )
-ALLOCATE( GSEDIMH(SIZE(PRCS,1),SIZE(PRCS,2),SIZE(PRCS,3)) )
+#ifndef MNH_OPENACC
+ALLOCATE( IC1(IIJKU), IC2(IIJKU), IC3(IIJKU) )
+ALLOCATE( IR1(IIJKU), IR2(IIJKU), IR3(IIJKU) )
+ALLOCATE( IS1(IIJKU), IS2(IIJKU), IS3(IIJKU) )
+ALLOCATE( II1(IIJKU), II2(IIJKU), II3(IIJKU) )
+ALLOCATE( IG1(IIJKU), IG2(IIJKU), IG3(IIJKU) )
+ALLOCATE( IH1(IIJKU), IH2(IIJKU), IH3(IIJKU) )
+#else
+IIC1 = MNH_ALLOCATE_IT1D(IC1,IIJKU)
+IIC2 = MNH_ALLOCATE_IT1D(IC2,IIJKU)
+IIC3 = MNH_ALLOCATE_IT1D(IC3,IIJKU)
+IIR1 = MNH_ALLOCATE_IT1D(IR1,IIJKU)
+IIR2 = MNH_ALLOCATE_IT1D(IR2,IIJKU)
+IIR3 = MNH_ALLOCATE_IT1D(IR3,IIJKU)
+IIS1 = MNH_ALLOCATE_IT1D(IS1,IIJKU)
+IIS2 = MNH_ALLOCATE_IT1D(IS2,IIJKU)
+IIS3 = MNH_ALLOCATE_IT1D(IS3,IIJKU)
+III1 = MNH_ALLOCATE_IT1D(II1,IIJKU)
+III2 = MNH_ALLOCATE_IT1D(II2,IIJKU)
+III3 = MNH_ALLOCATE_IT1D(II3,IIJKU) 
+IIG1 = MNH_ALLOCATE_IT1D(IG1,IIJKU)
+IIG2 = MNH_ALLOCATE_IT1D(IG2,IIJKU)
+IIG3 = MNH_ALLOCATE_IT1D(IG3,IIJKU)
+IIH1 = MNH_ALLOCATE_IT1D(IH1,IIJKU)
+IIH2 = MNH_ALLOCATE_IT1D(IH2,IIJKU)
+IIH3 = MNH_ALLOCATE_IT1D(IH3,IIJKU)
+#endif
+#ifndef MNH_OPENACC
+ALLOCATE( GDEP(IIU,IJU) )
+ALLOCATE( GSEDIMR(IIU,IJU,IKU) )
+ALLOCATE( GSEDIMC(IIU,IJU,IKU) )
+ALLOCATE( GSEDIMI(IIU,IJU,IKU) )
+ALLOCATE( GSEDIMS(IIU,IJU,IKU) )
+ALLOCATE( GSEDIMG(IIU,IJU,IKU) )
+ALLOCATE( GSEDIMH(IIU,IJU,IKU) )
+#else
+IGDEP    = MNH_ALLOCATE_GT2D( GDEP,IIU,IJU )
+IGSEDIMR = MNH_ALLOCATE_GT3D( GSEDIMR,IIU,IJU,IKU )
+IGSEDIMC = MNH_ALLOCATE_GT3D( GSEDIMC,IIU,IJU,IKU )
+IGSEDIMI = MNH_ALLOCATE_GT3D( GSEDIMI,IIU,IJU,IKU )
+IGSEDIMS = MNH_ALLOCATE_GT3D( GSEDIMS,IIU,IJU,IKU )
+IGSEDIMG = MNH_ALLOCATE_GT3D( GSEDIMG,IIU,IJU,IKU )
+IGSEDIMH = MNH_ALLOCATE_GT3D( GSEDIMH,IIU,IJU,IKU )
+#endif
 ALLOCATE( ZRTMIN(SIZE(XRTMIN)) )
-ALLOCATE( ZCONC_TMP(SIZE(PRCS,1),SIZE(PRCS,2)) )
-ALLOCATE( ZOMPSEA  (SIZE(PRCS,1),SIZE(PRCS,2)) )
-ALLOCATE( ZTMP1_2D (SIZE(PRCS,1),SIZE(PRCS,2)) )
-ALLOCATE( ZTMP2_2D (SIZE(PRCS,1),SIZE(PRCS,2)) )
-ALLOCATE( ZTMP3_2D (SIZE(PRCS,1),SIZE(PRCS,2)) )
-ALLOCATE( ZTMP4_2D (SIZE(PRCS,1),SIZE(PRCS,2)) )
-ALLOCATE( ZCONC3D(SIZE(PRCS,1),SIZE(PRCS,2),SIZE(PRCS,3)) )
-ALLOCATE( ZRAY   (SIZE(PRCS,1),SIZE(PRCS,2),SIZE(PRCS,3)) )
-ALLOCATE( ZLBC   (SIZE(PRCS,1),SIZE(PRCS,2),SIZE(PRCS,3)) )
-ALLOCATE( ZFSEDC (SIZE(PRCS,1),SIZE(PRCS,2),SIZE(PRCS,3)) )
-ALLOCATE( ZPRCS  (SIZE(PRCS,1),SIZE(PRCS,2),SIZE(PRCS,3)) )
-ALLOCATE( ZPRRS  (SIZE(PRCS,1),SIZE(PRCS,2),SIZE(PRCS,3)) )
-ALLOCATE( ZPRSS  (SIZE(PRCS,1),SIZE(PRCS,2),SIZE(PRCS,3)) )
-ALLOCATE( ZPRGS  (SIZE(PRCS,1),SIZE(PRCS,2),SIZE(PRCS,3)) )
-ALLOCATE( ZPRHS  (SIZE(PRCS,1),SIZE(PRCS,2),SIZE(PRCS,3)) )
-ALLOCATE( ZW     (SIZE(PRCS,1),SIZE(PRCS,2),SIZE(PRCS,3)) )
-ALLOCATE( ZWSED  (SIZE(PRCS,1),SIZE(PRCS,2),0:SIZE(PRCS,3)+1) )
-
-!$acc data create( IC1, IC2, IC3, IR1, IR2, IR3, IS1, IS2, IS3, II1, II2, II3, IG1, IG2, IG3, IH1, IH2, IH3, &
-!$acc &            GDEP, GSEDIMR, GSEDIMC,  GSEDIMI,  GSEDIMS,  GSEDIMG,  GSEDIMH,                           &
-!$acc &            ZRTMIN, ZCONC_TMP,                                                                        &
+#ifndef MNH_OPENACC
+ALLOCATE( ZCONC_TMP(IIU,IJU) )
+ALLOCATE( ZOMPSEA  (IIU,IJU) )
+ALLOCATE( ZTMP1_2D (IIU,IJU) )
+ALLOCATE( ZTMP2_2D (IIU,IJU) )
+ALLOCATE( ZTMP3_2D (IIU,IJU) )
+ALLOCATE( ZTMP4_2D (IIU,IJU) )
+ALLOCATE( ZCONC3D(IIU,IJU,IKU) )
+ALLOCATE( ZRAY   (IIU,IJU,IKU) )
+ALLOCATE( ZLBC   (IIU,IJU,IKU) )
+ALLOCATE( ZFSEDC (IIU,IJU,IKU) )
+ALLOCATE( ZPRCS  (IIU,IJU,IKU) )
+ALLOCATE( ZPRRS  (IIU,IJU,IKU) )
+ALLOCATE( ZPRSS  (IIU,IJU,IKU) )
+ALLOCATE( ZPRGS  (IIU,IJU,IKU) )
+ALLOCATE( ZPRHS  (IIU,IJU,IKU) )
+ALLOCATE( ZW     (IIU,IJU,IKU) )
+ALLOCATE( ZWSED  (IIU,IJU,0:IKU+1) )
+#else
+IZCONC_TMP = MNH_ALLOCATE_ZT2D( ZCONC_TMP,IIU,IJU )
+IZOMPSEA   = MNH_ALLOCATE_ZT2D( ZOMPSEA  ,IIU,IJU )
+IZTMP1_2D  = MNH_ALLOCATE_ZT2D( ZTMP1_2D ,IIU,IJU )
+IZTMP2_2D  = MNH_ALLOCATE_ZT2D( ZTMP2_2D ,IIU,IJU )
+IZTMP3_2D  = MNH_ALLOCATE_ZT2D( ZTMP3_2D ,IIU,IJU )
+IZTMP4_2D  = MNH_ALLOCATE_ZT2D( ZTMP4_2D ,IIU,IJU )
+IZCONC3D   = MNH_ALLOCATE_ZT3D( ZCONC3D,IIU,IJU,IKU )
+IZRAY      = MNH_ALLOCATE_ZT3D( ZRAY   ,IIU,IJU,IKU )
+IZLBC      = MNH_ALLOCATE_ZT3D( ZLBC   ,IIU,IJU,IKU )
+IZFSEDC    = MNH_ALLOCATE_ZT3D( ZFSEDC ,IIU,IJU,IKU )
+IZPRCS     = MNH_ALLOCATE_ZT3D( ZPRCS  ,IIU,IJU,IKU )
+IZPRRS     = MNH_ALLOCATE_ZT3D( ZPRRS  ,IIU,IJU,IKU )
+IZPRSS     = MNH_ALLOCATE_ZT3D( ZPRSS  ,IIU,IJU,IKU )
+IZPRGS     = MNH_ALLOCATE_ZT3D( ZPRGS  ,IIU,IJU,IKU )
+IZPRHS     = MNH_ALLOCATE_ZT3D( ZPRHS  ,IIU,IJU,IKU )
+IZW = MNH_ALLOCATE_ZT3D( ZW     ,IIU,IJU,IKU )
+ALLOCATE( ZWSED  (IIU,IJU,0:IKU+1) )
+#endif
+
+!$acc data present( IC1, IC2, IC3, IR1, IR2, IR3, IS1, IS2, IS3, II1, II2, II3, IG1, IG2, IG3, IH1, IH2, IH3,&
+!$acc &            GDEP, GSEDIMR, GSEDIMC,  GSEDIMI,  GSEDIMS,  GSEDIMG,  GSEDIMH )                          &
+!$acc &    create( ZRTMIN , ZWSED )                                                                          &
+!$acc &    present(ZCONC_TMP,                                                                                &
 !$acc &            ZOMPSEA, ZTMP1_2D, ZTMP2_2D, ZTMP3_2D, ZTMP4_2D, ZCONC3D,                                 &
 !$acc &            ZRAY, ZLBC, ZFSEDC,                                                                       &
-!$acc &            ZPRCS, ZPRRS, ZPRSS, ZPRGS, ZPRHS, ZW, ZWSED                                              )
+!$acc &            ZPRCS, ZPRRS, ZPRSS, ZPRGS, ZPRHS, ZW                                                     )
 
 IF ( PRESENT( PFPR ) ) THEN
   GPRESENT_PFPR = .TRUE.
@@ -369,18 +453,21 @@ DO JN = 1 , KSPLITR
     IF ( KRR == 7 ) PRHS(:,:,:) = PRHS(:,:,:) + ZPRHS(:,:,:) * ZTSPLITR
   END IF
   !
-  IF ( OSEDIC ) GSEDIMC(KIB:KIE,KJB:KJE,KKTB:KKTE) =                &
-                   PRCS(KIB:KIE,KJB:KJE,KKTB:KKTE) > ZRTMIN(2)
-  GSEDIMR(KIB:KIE,KJB:KJE,KKTB:KKTE) =                            &
-                   PRRS(KIB:KIE,KJB:KJE,KKTB:KKTE) > ZRTMIN(3)
-  GSEDIMI(KIB:KIE,KJB:KJE,KKTB:KKTE) =                            &
-                   PRIS(KIB:KIE,KJB:KJE,KKTB:KKTE) > ZRTMIN(4)
-  GSEDIMS(KIB:KIE,KJB:KJE,KKTB:KKTE) =                            &
-                   PRSS(KIB:KIE,KJB:KJE,KKTB:KKTE) > ZRTMIN(5)
-  GSEDIMG(KIB:KIE,KJB:KJE,KKTB:KKTE) =                            &
-                   PRGS(KIB:KIE,KJB:KJE,KKTB:KKTE) > ZRTMIN(6)
-  IF ( KRR == 7 ) GSEDIMH(KIB:KIE,KJB:KJE,KKTB:KKTE) =            &
-                   PRHS(KIB:KIE,KJB:KJE,KKTB:KKTE) > ZRTMIN(7)
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=KIB:KIE,JJ=KJB:KJE,JK=KKTB:KKTE )
+  IF ( OSEDIC ) GSEDIMC(JI,JJ,JK) =                &
+                   PRCS(JI,JJ,JK) > ZRTMIN(2)
+  GSEDIMR(JI,JJ,JK) =                            &
+                   PRRS(JI,JJ,JK) > ZRTMIN(3)
+  GSEDIMI(JI,JJ,JK) =                            &
+                   PRIS(JI,JJ,JK) > ZRTMIN(4)
+  GSEDIMS(JI,JJ,JK) =                            &
+                   PRSS(JI,JJ,JK) > ZRTMIN(5)
+  GSEDIMG(JI,JJ,JK) =                            &
+                   PRGS(JI,JJ,JK) > ZRTMIN(6)
+  IF ( KRR == 7 ) GSEDIMH(JI,JJ,JK) =            &
+       PRHS(JI,JJ,JK) > ZRTMIN(7)
+  END DO ! CONCURRENT
 !$acc end kernels
 !
 #ifndef MNH_OPENACC
@@ -673,6 +760,27 @@ END IF
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+DEALLOCATE(IC1, IC2, IC3, IR1, IR2, IR3, IS1, IS2, IS3, II1, II2, II3, IG1, IG2, IG3, IH1, IH2, IH3)
+#else
+CALL MNH_REL_IT1D(IIC1, IIC2, IIC3, IIR1, IIR2, IIR3, IIS1, IIS2, IIS3,&
+                  III1, III2, III3, IIG1, IIG2, IIG3, IIH1, IIH2, IIH3)
+#endif
+#ifndef MNH_OPENACC
+DEALLOCATE(GDEP, GSEDIMR, GSEDIMC,  GSEDIMI,  GSEDIMS,  GSEDIMG,  GSEDIMH)
+#else
+CALL MNH_REL_GT3D(IGDEP, IGSEDIMR, IGSEDIMC,  IGSEDIMI,  IGSEDIMS,  IGSEDIMG,  IGSEDIMH)
+#endif
+DEALLOCATE(ZRTMIN)
+#ifndef MNH_OPENACC
+DEALLOCATE(ZCONC_TMP,ZOMPSEA, ZTMP1_2D, ZTMP2_2D, ZTMP3_2D, ZTMP4_2D, ZCONC3D)
+DEALLOCATE(ZRAY, ZLBC, ZFSEDC,ZPRCS, ZPRRS, ZPRSS, ZPRGS, ZPRHS, ZW)
+#else
+CALL MNH_REL_ZT3D(IZRAY, IZLBC, IZFSEDC,IZPRCS, IZPRRS, IZPRSS, IZPRGS, IZPRHS, IZW)
+CALL MNH_REL_ZT3D(IZCONC_TMP,IZOMPSEA, IZTMP1_2D, IZTMP2_2D, IZTMP3_2D, IZTMP4_2D, IZCONC3D)
+#endif
+DEALLOCATE(ZWSED)
+
 !$acc end data
 
 END SUBROUTINE RAIN_ICE_SEDIMENTATION_SPLIT
diff --git a/src/MNH/rain_ice_slow.f90 b/src/MNH/rain_ice_slow.f90
index 2e4375102be35f9325762b62c581de6d8dbb34ed..3f54aa8877adf7b4b9d4cca8750bdecaedc26119 100644
--- a/src/MNH/rain_ice_slow.f90
+++ b/src/MNH/rain_ice_slow.f90
@@ -80,6 +80,7 @@ REAL,    DIMENSION(:), ALLOCATABLE :: ZCRIAUTI ! Snow-to-ice autoconversion thre
 REAL,    DIMENSION(:), ALLOCATABLE :: ZZW      ! Work array
 real,    dimension(:), ALLOCATABLE :: zz_diff
 !
+INTEGER                            :: JL,JLU
 !-------------------------------------------------------------------------------
 !
 ! IN variables
@@ -119,6 +120,8 @@ IF (MPPDB_INITIALIZED) THEN
   CALL MPPDB_CHECK(PTHS,"RAIN_ICE_SLOW beg:PTHS")
 END IF
 !
+JLU = size(PRHODREF)
+!
 ALLOCATE( GWORK   (size(PRHODREF)) )
 ALLOCATE( ZZW     (size(PRHODREF)) )
 ALLOCATE( ZCRIAUTI(size(PRHODREF)) )
@@ -212,33 +215,37 @@ ALLOCATE( zz_diff (size(PLSFACT))  )
 !*       3.4.3  compute the deposition on r_s: RVDEPS
 !
   GWORK(:) = PRST(:)>0.0
-  WHERE ( GWORK(:) )
-#ifndef MNH_BITREP
-    PLBDAS(:)  = MIN( XLBDAS_MAX,                                           &
-                      XLBS*( PRHODREF(:)*MAX( PRST(:),XRTMIN(5) ) )**XLBEXS )
+  !$acc loop independent
+  DO CONCURRENT ( JL=1:JLU )
+    IF ( GWORK(JL) ) THEN
+      PLBDAS(JL)  = MIN( XLBDAS_MAX,                                           &
+#ifndef MNH_BITREP  
+                         XLBS*( PRHODREF(JL)*MAX( PRST(JL),XRTMIN(5) ) )**XLBEXS )
 #else
-    PLBDAS(:)  = MIN( XLBDAS_MAX,                                           &
-                      XLBS*BR_POW( PRHODREF(:)*MAX( PRST(:),XRTMIN(5) ),XLBEXS ) )
+                         XLBS*BR_POW( PRHODREF(JL)*MAX( PRST(JL),XRTMIN(5) ),XLBEXS ) )
 #endif
-  ELSEWHERE
-    PLBDAS(:) = 0.
-  END WHERE
+    ELSE
+      PLBDAS(JL) = 0.
+    END IF
+  END DO ! CONCURRENT
   ZZW(:) = 0.0
   GWORK(:) = (PRST(:)>XRTMIN(5)) .AND. (PRSS(:)>0.0)
-  WHERE ( GWORK(:) )
-#ifndef MNH_BITREP
-    ZZW(:) = ( PSSI(:)/(PRHODREF(:)*PAI(:)) ) *                               &
-             ( X0DEPS*PLBDAS(:)**XEX0DEPS + X1DEPS*PCJ(:)*PLBDAS(:)**XEX1DEPS )
+ !$acc loop independent
+ DO CONCURRENT ( JL=1:JLU )
+    IF ( GWORK(JL) ) THEN
+       ZZW(JL) = ( PSSI(JL)/(PRHODREF(JL)*PAI(JL)) ) *                               &
+#ifndef MNH_BITREP  
+            ( X0DEPS*PLBDAS(JL)**XEX0DEPS + X1DEPS*PCJ(JL)*PLBDAS(JL)**XEX1DEPS )
 #else
-    ZZW(:) = ( PSSI(:)/(PRHODREF(:)*PAI(:)) ) *                               &
-             ( X0DEPS*BR_POW(PLBDAS(:),XEX0DEPS) + X1DEPS*PCJ(:)*BR_POW(PLBDAS(:),XEX1DEPS) )
+            ( X0DEPS*BR_POW(PLBDAS(JL),XEX0DEPS) + X1DEPS*PCJ(JL)*BR_POW(PLBDAS(JL),XEX1DEPS) )
 #endif
-    ZZW(:) =         MIN( PRVS(:),ZZW(:)      )*(0.5+SIGN(0.5,ZZW(:))) &
-                   - MIN( PRSS(:),ABS(ZZW(:)) )*(0.5-SIGN(0.5,ZZW(:)))
-    PRSS(:) = PRSS(:) + ZZW(:)
-    PRVS(:) = PRVS(:) - ZZW(:)
-    PTHS(:) = PTHS(:) + ZZW(:)*PLSFACT(:)
-  END WHERE
+       ZZW(JL) =         MIN( PRVS(JL),ZZW(JL)      )*(0.5+SIGN(0.5,ZZW(JL))) &
+            - MIN( PRSS(JL),ABS(ZZW(JL)) )*(0.5-SIGN(0.5,ZZW(JL)))
+       PRSS(JL) = PRSS(JL) + ZZW(JL)
+       PRVS(JL) = PRVS(JL) - ZZW(JL)
+       PTHS(JL) = PTHS(JL) + ZZW(JL)*PLSFACT(JL)
+    END IF
+ END DO
 !$acc end kernels
 
   if ( lbudget_th ) call Budget_store_add( tbudgets(NBUDGET_TH), 'DEPS', &
@@ -253,21 +260,24 @@ ALLOCATE( zz_diff (size(PLSFACT))  )
 !$acc kernels
   ZZW(:) = 0.0
   GWORK(:) = PRIT(:)>XRTMIN(4) .AND. PRST(:)>XRTMIN(5) .AND. PRIS(:)>0.0
-  WHERE ( GWORK(:) )
-#ifndef MNH_BITREP
-    ZZW(:) = MIN( PRIS(:),XFIAGGS * EXP( XCOLEXIS*(PZT(:)-XTT) ) &
-                                  * PRIT(:)                      &
-                                  * PLBDAS(:)**XEXIAGGS          &
-                                  * PRHODREF(:)**(-XCEXVT)       )
+  !$acc loop independent
+  DO CONCURRENT ( JL=1:JLU )
+    IF ( GWORK(JL) ) THEN
+#ifndef MNH_BITREP  
+      ZZW(JL) = MIN( PRIS(JL),XFIAGGS * EXP( XCOLEXIS*(PZT(JL)-XTT) ) &
+                                      * PRIT(JL)                      &
+                                      * PLBDAS(JL)**XEXIAGGS          &
+                                      * PRHODREF(JL)**(-XCEXVT)       )
 #else
-    ZZW(:) = MIN( PRIS(:),XFIAGGS * BR_EXP( XCOLEXIS*(PZT(:)-XTT) ) &
-                                  * PRIT(:)                         &
-                                  * BR_POW(PLBDAS(:),XEXIAGGS)      &
-                                  * BR_POW(PRHODREF(:),-XCEXVT)     )
+      ZZW(JL) = MIN( PRIS(JL),XFIAGGS * BR_EXP( XCOLEXIS*(PZT(JL)-XTT) ) &
+                                      * PRIT(JL)                         &
+                                      * BR_POW(PLBDAS(JL),XEXIAGGS)      &
+                                      * BR_POW(PRHODREF(JL),-XCEXVT)     )
 #endif
-    PRSS(:)  = PRSS(:)  + ZZW(:)
-    PRIS(:)  = PRIS(:)  - ZZW(:)
-  END WHERE
+      PRSS(JL)  = PRSS(JL)  + ZZW(JL)
+      PRIS(JL)  = PRIS(JL)  - ZZW(JL)
+   END IF
+  END DO ! CONCURRENT
 !$acc end kernels
 
   if ( lbudget_ri ) call Budget_store_add( tbudgets(NBUDGET_RI), 'AGGS', &
@@ -308,31 +318,36 @@ ALLOCATE( zz_diff (size(PLSFACT))  )
 !
 !$acc kernels
   GWORK(:) = PRGT(:)>0.0
-  WHERE ( GWORK(:) )
-#ifndef MNH_BITREP
-    PLBDAG(:)  = XLBG*( PRHODREF(:)*MAX( PRGT(:),XRTMIN(6) ) )**XLBEXG
+  !$acc loop independent
+  DO CONCURRENT ( JL=1:JLU )
+    IF ( GWORK(JL) ) THEN
+#ifndef MNH_BITREP  
+      PLBDAG(JL)  = XLBG*( PRHODREF(JL)*MAX( PRGT(JL),XRTMIN(6) ) )**XLBEXG
 #else
-    PLBDAG(:)  = XLBG*BR_POW( PRHODREF(:)*MAX( PRGT(:),XRTMIN(6) ), XLBEXG)
+      PLBDAG(JL)  = XLBG*BR_POW( PRHODREF(JL)*MAX( PRGT(JL),XRTMIN(6) ), XLBEXG)
 #endif
-  ELSEWHERE
-    PLBDAG(:) = 0.
-  END WHERE
+    ELSE
+      PLBDAG(JL) = 0.
+    END IF
+  END DO ! CONCURRENT
   ZZW(:) = 0.0
   GWORK(:) = PRGT(:)>XRTMIN(6) .AND. PRGS(:)>0.0
-  WHERE ( GWORK(:) )
-#ifndef MNH_BITREP
-    ZZW(:) = ( PSSI(:)/(PRHODREF(:)*PAI(:)) ) *                               &
-             ( X0DEPG*PLBDAG(:)**XEX0DEPG + X1DEPG*PCJ(:)*PLBDAG(:)**XEX1DEPG )
+  !$acc loop independent
+  DO CONCURRENT ( JL=1:JLU )
+    IF ( GWORK(JL) ) THEN
+      ZZW(JL) = ( PSSI(JL)/(PRHODREF(JL)*PAI(JL)) ) *                               &
+#ifndef MNH_BITREP  
+                ( X0DEPG*PLBDAG(JL)**XEX0DEPG + X1DEPG*PCJ(JL)*PLBDAG(JL)**XEX1DEPG )
 #else
-    ZZW(:) = ( PSSI(:)/(PRHODREF(:)*PAI(:)) ) *                               &
-             ( X0DEPG*BR_POW(PLBDAG(:),XEX0DEPG) + X1DEPG*PCJ(:)*BR_POW(PLBDAG(:),XEX1DEPG) )
+                ( X0DEPG*BR_POW(PLBDAG(JL),XEX0DEPG) + X1DEPG*PCJ(JL)*BR_POW(PLBDAG(JL),XEX1DEPG) )
 #endif
-    ZZW(:) =         MIN( PRVS(:),ZZW(:)      )*(0.5+SIGN(0.5,ZZW(:))) &
-                   - MIN( PRGS(:),ABS(ZZW(:)) )*(0.5-SIGN(0.5,ZZW(:)))
-    PRGS(:) = PRGS(:) + ZZW(:)
-    PRVS(:) = PRVS(:) - ZZW(:)
-    PTHS(:) = PTHS(:) + ZZW(:)*PLSFACT(:)
-  END WHERE
+      ZZW(JL) =   MIN( PRVS(JL),ZZW(JL)      )*(0.5+SIGN(0.5,ZZW(JL))) &
+                - MIN( PRGS(JL),ABS(ZZW(JL)) )*(0.5-SIGN(0.5,ZZW(JL)))
+      PRGS(JL) = PRGS(JL) + ZZW(JL)
+      PRVS(JL) = PRVS(JL) - ZZW(JL)
+      PTHS(JL) = PTHS(JL) + ZZW(JL)*PLSFACT(JL)
+    END IF
+  END DO ! CONCURRENT
 !$acc end kernels
 
   if ( lbudget_th ) call Budget_store_add( tbudgets(NBUDGET_TH), 'DEPG', &
diff --git a/src/MNH/rain_ice_warm.f90 b/src/MNH/rain_ice_warm.f90
index 714d6a9659894772ced2711f5cb1543de290b2ba..4dbce215476eab85e53f8c1e702e31136fb9678a 100644
--- a/src/MNH/rain_ice_warm.f90
+++ b/src/MNH/rain_ice_warm.f90
@@ -90,6 +90,8 @@ REAL,    DIMENSION(:), ALLOCATABLE :: ZZW2 ! Work array
 REAL,    DIMENSION(:), ALLOCATABLE :: ZZW3 ! Work array
 REAL,    DIMENSION(:), ALLOCATABLE :: ZZW4 ! Work array
 !
+INTEGER :: JLU
+!
 !-------------------------------------------------------------------------------
 !
 ! IN variables
@@ -140,6 +142,8 @@ IF (MPPDB_INITIALIZED) THEN
   CALL MPPDB_CHECK(PEVAP3D,"RAIN_ICE_WARM beg:PEVAP3D")
 END IF
 !
+JLU = size(PRHODREF)
+!
 ALLOCATE( GWORK(size(PRHODREF)) )
 ALLOCATE( ZZW  (size(PRHODREF)) )
 ALLOCATE( ZZW2 (size(PRHODREF)) )
@@ -173,20 +177,21 @@ ALLOCATE( ZZW4 (size(PRHODREF)) )
 !$acc kernels
       !CLoud water and rain are diluted over the grid box
       GWORK(:) = PRCT(:)>XRTMIN(2) .AND. PRRT(:)>XRTMIN(3) .AND. PRCS(:)>0.0
-      WHERE( GWORK(:) )
-#ifndef MNH_BITREP
-        ZZW(:) = MIN( PRCS(:), XFCACCR * PRCT(:) &
-                 * PLBDAR(:)**XEXCACCR           &
-                 * PRHODREF(:)**(-XCEXVT) )
+     !$acc loop independent
+     DO CONCURRENT ( JL=1:JLU )
+        IF ( GWORK(JL) )  THEN
+           ZZW(JL) = MIN( PRCS(JL), XFCACCR * PRCT(JL) &
+#ifndef MNH_BITREP       
+                * PLBDAR(JL)**XEXCACCR    &
+                * PRHODREF(JL)**(-XCEXVT) )
 #else
-        ZZW(:) = MIN( PRCS(:), XFCACCR * PRCT(:) &
-                 * BR_POW(PLBDAR(:),XEXCACCR)    &
-                 * BR_POW(PRHODREF(:),-XCEXVT) )
-
+                * BR_POW(PLBDAR(JL),XEXCACCR)  &
+                * BR_POW(PRHODREF(JL),-XCEXVT) )
 #endif
-        PRCS(:) = PRCS(:) - ZZW(:)
-        PRRS(:) = PRRS(:) + ZZW(:)
-      END WHERE
+           PRCS(JL) = PRCS(JL) - ZZW(JL)
+           PRRS(JL) = PRRS(JL) + ZZW(JL)
+        END IF
+     END DO ! CONCURRENT
 !$acc end kernels
 
     ELSEIF (CSUBG_RC_RR_ACCR=='PRFR') THEN
@@ -203,38 +208,42 @@ ALLOCATE( ZZW4 (size(PRHODREF)) )
       ! => min(PCF, PRF)-PHLC_HCF
       ZZW(:) = 0.
       GWORK(:) = PHLC_HRC(:)>XRTMIN(2) .AND. PRRT(:)>XRTMIN(3) .AND. PRCS(:)>0.0 .AND. PHLC_HCF(:)>0
-      WHERE( GWORK(:) )
-        !Accretion due to rain falling in high cloud content
-#ifndef MNH_BITREP
-        ZZW(:) = XFCACCR * ( PHLC_HRC(:)/PHLC_HCF(:) ) &
-               * PLBDAR_RF(:)**XEXCACCR                &
-               * PRHODREF(:)**(-XCEXVT)                &
-               * PHLC_HCF
+     !$acc loop independent
+     DO CONCURRENT ( JL=1:JLU )
+        IF ( GWORK(JL) ) THEN
+           !Accretion due to rain falling in high cloud content
+           ZZW(JL) = XFCACCR * ( PHLC_HRC(JL)/PHLC_HCF(JL) ) &
+#ifndef MNH_BITREP      
+                * PLBDAR_RF(JL)**XEXCACCR         &
+                * PRHODREF(JL)**(-XCEXVT)         &
 #else
-        ZZW(:) = XFCACCR * ( PHLC_HRC(:)/PHLC_HCF(:) ) &
-               * BR_POW(PLBDAR_RF(:),XEXCACCR)         &
-               * BR_POW(PRHODREF(:),-XCEXVT)           &
-               * PHLC_HCF
+                * BR_POW(PLBDAR_RF(JL),XEXCACCR)         &
+                * BR_POW(PRHODREF(JL),-XCEXVT)           &
 #endif
-      END WHERE
-      GWORK(:) = PHLC_LRC(:)>XRTMIN(2) .AND. PRRT(:)>XRTMIN(3) .AND. PRCS(:)>0.0 .AND. PHLC_LCF(:)>0
-      WHERE( GWORK(:) )
+                * PHLC_HCF(JL)
+        END IF
+     END DO ! CONCURRENT
+     GWORK(:) = PHLC_LRC(:)>XRTMIN(2) .AND. PRRT(:)>XRTMIN(3) .AND. PRCS(:)>0.0 .AND. PHLC_LCF(:)>0
+ !$acc loop independent
+ DO CONCURRENT ( JL=1:JLU )
+    IF ( GWORK(JL) ) THEN     
         !We add acrretion due to rain falling in low cloud content
 #ifndef MNH_BITREP
-        ZZW(:) = ZZW(:) + XFCACCR * ( PHLC_LRC(:)/PHLC_LCF(:) ) &
-                        * PLBDAR_RF(:)**XEXCACCR                &
-                        * PRHODREF(:)**(-XCEXVT)                &
-                        * (MIN(PCF(:), PRF(:))-PHLC_HCF(:))
+        ZZW(JL) = ZZW(JL) + XFCACCR * ( PHLC_LRC(JL)/PHLC_LCF(JL) ) &
+                        * PLBDAR_RF(JL)**XEXCACCR                &
+                        * PRHODREF(JL)**(-XCEXVT)                &
+                        * (MIN(PCF(JL), PRF(JL))-PHLC_HCF(JL))
 #else
-        ZZW(:) = ZZW(:) + XFCACCR * ( PHLC_LRC(:)/PHLC_LCF(:) ) &
-                        * BR_POW(PLBDAR_RF(:),XEXCACCR)         &
-                        * BR_POW(PRHODREF(:),-XCEXVT)           &
-                        * (MIN(PCF(:), PRF(:))-PHLC_HCF(:))
+        ZZW(JL) = ZZW(JL) + XFCACCR * ( PHLC_LRC(JL)/PHLC_LCF(JL) ) &
+                        * BR_POW(PLBDAR_RF(JL),XEXCACCR)         &
+                        * BR_POW(PRHODREF(JL),-XCEXVT)           &
+                        * (MIN(PCF(JL), PRF(JL))-PHLC_HCF(JL))
 #endif
-      END WHERE
-      ZZW(:)=MIN(PRCS(:), ZZW(:))
-      PRCS(:) = PRCS(:) - ZZW(:)
-      PRRS(:) = PRRS(:) + ZZW(:)
+      END IF
+      ZZW(JL)=MIN(PRCS(JL), ZZW(JL))
+      PRCS(JL) = PRCS(JL) - ZZW(JL)
+      PRRS(JL) = PRRS(JL) + ZZW(JL)
+   END DO ! CONCURRENT
 !$acc end kernels
 
     ELSE
@@ -254,31 +263,50 @@ ALLOCATE( ZZW4 (size(PRHODREF)) )
 
     IF (CSUBG_RR_EVAP=='NONE') THEN
 !$acc kernels
-      !Evaporation only when there's no cloud (RC must be 0)
+       !Evaporation only when there's no cloud (RC must be 0)
        GWORK(:) = PRRT(:)>XRTMIN(3) .AND. PRCT(:)<=XRTMIN(2)
+#ifndef MNH_BITREP       
        WHERE( GWORK(:) )
-#ifndef MNH_BITREP
           ZZW(:)  = EXP( XALPW - XBETAW/PZT(:) - XGAMW*ALOG(PZT(:) ) ) ! es_w
-#else
-          ZZW(:)  = BR_EXP( XALPW - XBETAW/PZT(:) - XGAMW*BR_LOG(PZT(:) ) ) ! es_w
-#endif
           PUSW(:) = 1.0 - PRVT(:)*( PPRES(:)-ZZW(:) ) / ( (XMV/XMD) * ZZW(:) )
                                                         ! Undersaturation over water
-#ifndef MNH_BITREP
           ZZW(:) = ( XLVTT+(XCPV-XCL)*(PZT(:)-XTT) )**2 / ( PKA(:)*XRV*PZT(:)**2 ) &
                + ( XRV*PZT(:) ) / ( PDV(:)*ZZW(:) )
           ZZW(:) = MIN( PRRS(:),( MAX( 0.0,PUSW(:) )/(PRHODREF(:)*ZZW(:)) ) *      &
             ( X0EVAR*PLBDAR(:)**XEX0EVAR+X1EVAR*PCJ(:)*PLBDAR(:)**XEX1EVAR ) )
-#else
-          ZZW(:) = BR_P2( XLVTT+(XCPV-XCL)*(PZT(:)-XTT) ) / ( PKA(:)*XRV*BR_P2(PZT(:)) ) &
-               + ( XRV*PZT(:) ) / ( PDV(:)*ZZW(:) )
-          ZZW(:) = MIN( PRRS(:),( MAX( 0.0,PUSW(:) )/(PRHODREF(:)*ZZW(:)) ) *            &
-            ( X0EVAR*BR_POW(PLBDAR(:),XEX0EVAR)+X1EVAR*PCJ(:)*BR_POW(PLBDAR(:),XEX1EVAR) ) )
-#endif
           PRRS(:) = PRRS(:) - ZZW(:)
           PRVS(:) = PRVS(:) + ZZW(:)
           PTHS(:) = PTHS(:) - ZZW(:)*PLVFACT(:)
        END WHERE
+#else
+       !$acc loop independent
+       DO CONCURRENT ( JL=1:JLU )
+          IF ( GWORK(JL) ) THEN
+#ifndef MNH_BITREP       
+             ZZW(JL)  = EXP( XALPW - XBETAW/PZT(JL) - XGAMW*LOG(PZT(JL) ) ) ! es_w
+#else
+             ZZW(JL)  = BR_EXP( XALPW - XBETAW/PZT(JL) - XGAMW*BR_LOG(PZT(JL) ) ) ! es_w
+#endif
+             PUSW(JL) = 1.0 - PRVT(JL)*( PPRES(JL)-ZZW(JL) ) / ( (XMV/XMD) * ZZW(JL) )
+             ! Undersaturation over water
+#ifndef MNH_BITREP       
+             ZZW(JL) = ( XLVTT+(XCPV-XCL)*(PZT(JL)-XTT) )**2 / ( PKA(JL)*XRV*PZT(JL)**2 ) &
+#else
+             ZZW(JL) = BR_P2( XLVTT+(XCPV-XCL)*(PZT(JL)-XTT) ) / ( PKA(JL)*XRV*BR_P2(PZT(JL)) ) &
+#endif
+                  + ( XRV*PZT(JL) ) / ( PDV(JL)*ZZW(JL) )
+             ZZW(JL) = MIN( PRRS(JL),( MAX( 0.0,PUSW(JL) )/(PRHODREF(JL)*ZZW(JL)) ) *            &
+#ifndef MNH_BITREP       
+                  ( X0EVAR*PLBDAR(JL)**XEX0EVAR+X1EVAR*PCJ(JL)*PLBDAR(JL)**XEX1EVAR ) )
+#else
+                  ( X0EVAR*BR_POW(PLBDAR(JL),XEX0EVAR)+X1EVAR*PCJ(JL)*BR_POW(PLBDAR(JL),XEX1EVAR) ) )
+#endif
+             PRRS(JL) = PRRS(JL) - ZZW(JL)
+             PRVS(JL) = PRVS(JL) + ZZW(JL)
+             PTHS(JL) = PTHS(JL) - ZZW(JL)*PLVFACT(JL)
+          END IF
+       END DO ! CONCURRENT
+#endif       
 !$acc end kernels
     ELSEIF (CSUBG_RR_EVAP=='CLFR' .OR. CSUBG_RR_EVAP=='PRFR') THEN
 #ifdef MNH_OPENACC
@@ -304,43 +332,46 @@ ALLOCATE( ZZW4 (size(PRHODREF)) )
       !On utiliserait la bonne version suivant l'option NONE, CLFR... dans l'évaporation et ailleurs
 
       GWORK(:) = PRRT(:)>XRTMIN(3) .AND. ZZW4(:)>PCF(:)
-      WHERE(  GWORK(:) )
+      !$acc loop independent
+      DO CONCURRENT ( JL=1:JLU )
+        IF ( GWORK(JL) ) THEN
         ! outside the cloud (environment) the use of T^u (unsaturated) instead of T
         ! Bechtold et al. 1993
         !
         ! T^u = T_l = theta_l * (T/theta)
-        ZZW2(:) =  PTHLT(:) * PZT(:) / PTHT(:)
+        ZZW2(JL) =  PTHLT(JL) * PZT(JL) / PTHT(JL)
         !
         ! es_w with new T^u
 #ifndef MNH_BITREP
-        ZZW(:)  = EXP( XALPW - XBETAW/ZZW2(:) - XGAMW*ALOG(ZZW2(:) ) )
+        ZZW(JL)  = EXP( XALPW - XBETAW/ZZW2(JL) - XGAMW*ALOG(ZZW2(JL) ) )
 #else
-        ZZW(:)  = BR_EXP( XALPW - XBETAW/ZZW2(:) - XGAMW*BR_LOG(ZZW2(:) ) )
+        ZZW(JL)  = BR_EXP( XALPW - XBETAW/ZZW2(JL) - XGAMW*BR_LOG(ZZW2(JL) ) )
 #endif
         !
         ! S, Undersaturation over water (with new theta^u)
-        PUSW(:) = 1.0 - PRVT(:)*( PPRES(:)-ZZW(:) ) / ( (XMV/XMD) * ZZW(:) )
+        PUSW(JL) = 1.0 - PRVT(JL)*( PPRES(JL)-ZZW(JL) ) / ( (XMV/XMD) * ZZW(JL) )
         !
 #ifndef MNH_BITREP
-        ZZW(:) = ( XLVTT+(XCPV-XCL)*(ZZW2(:)-XTT) )**2 / ( PKA(:)*XRV*ZZW2(:)**2 ) &
-               + ( XRV*ZZW2(:) ) / ( PDV(:)*ZZW(:) )
+        ZZW(JL) = ( XLVTT+(XCPV-XCL)*(ZZW2(JL)-XTT) )**2 / ( PKA(JL)*XRV*ZZW2(JL)**2 ) &
+               + ( XRV*ZZW2(JL) ) / ( PDV(JL)*ZZW(JL) )
         !
-        ZZW(:) = MAX( 0.0,PUSW(:) )/(PRHODREF(:)*ZZW(:))  *      &
-               ( X0EVAR*ZZW3(:)**XEX0EVAR+X1EVAR*PCJ(:)*ZZW3(:)**XEX1EVAR )
+        ZZW(JL) = MAX( 0.0,PUSW(JL) )/(PRHODREF(JL)*ZZW(JL))  *      &
+               ( X0EVAR*ZZW3(JL)**XEX0EVAR+X1EVAR*PCJ(JL)*ZZW3(JL)**XEX1EVAR )
 #else
-        ZZW(:) = BR_P2( XLVTT+(XCPV-XCL)*(ZZW2(:)-XTT) ) / ( PKA(:)*XRV*BR_P2(ZZW2(:)) ) &
-               + ( XRV*ZZW2(:) ) / ( PDV(:)*ZZW(:) )
+        ZZW(JL) = BR_P2( XLVTT+(XCPV-XCL)*(ZZW2(JL)-XTT) ) / ( PKA(JL)*XRV*BR_P2(ZZW2(JL)) ) &
+               + ( XRV*ZZW2(JL) ) / ( PDV(JL)*ZZW(JL) )
         !
-        ZZW(:) = MAX( 0.0,PUSW(:) )/(PRHODREF(:)*ZZW(:))  *      &
-               ( X0EVAR*BR_POW(ZZW3(:),XEX0EVAR)+X1EVAR*PCJ(:)*BR_POW(ZZW3(:),XEX1EVAR) )
+        ZZW(JL) = MAX( 0.0,PUSW(JL) )/(PRHODREF(JL)*ZZW(JL))  *      &
+               ( X0EVAR*BR_POW(ZZW3(JL),XEX0EVAR)+X1EVAR*PCJ(JL)*BR_POW(ZZW3(JL),XEX1EVAR) )
 #endif
         !
-        ZZW(:) = MIN( PRRS(:),  ZZW(:) *( ZZW4(:) - PCF(:) ) )
+        ZZW(JL) = MIN( PRRS(JL),  ZZW(JL) *( ZZW4(JL) - PCF(JL) ) )
         !
-        PRRS(:) = PRRS(:) - ZZW(:)
-        PRVS(:) = PRVS(:) + ZZW(:)
-        PTHS(:) = PTHS(:) - ZZW(:)*PLVFACT(:)
-      END WHERE
+        PRRS(JL) = PRRS(JL) - ZZW(JL)
+        PRVS(JL) = PRVS(JL) + ZZW(JL)
+        PTHS(JL) = PTHS(JL) - ZZW(JL)*PLVFACT(JL)
+        END IF
+     END DO ! CONCURRENT
 !$acc end kernels
 
     ELSE
diff --git a/src/MNH/resolved_cloud.f90 b/src/MNH/resolved_cloud.f90
index 97e4c00d98fde746fbf0bd180ca9cfc80877865c..0872d6db517852e8c35dc4c19a369bed6885e7d5 100644
--- a/src/MNH/resolved_cloud.f90
+++ b/src/MNH/resolved_cloud.f90
@@ -338,6 +338,10 @@ USE MODI_SHUMAN
 USE MODI_SHUMAN_DEVICE
 #endif
 USE MODI_SLOW_TERMS
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_ZT4D , MNH_REL_ZT4D , MNH_ALLOCATE_ZT2D , &
+                            MNH_ALLOCATE_GT3D , MNH_REL_GT3D
+#endif
 !
 IMPLICIT NONE
 !
@@ -469,9 +473,12 @@ INTEGER :: IKL
 INTEGER :: IINFO_ll      ! return code of parallel routine
 INTEGER :: JI,JJ,JK,JL
 !
-REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZDZZ
-REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZEXN
-REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZZZ
+REAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS :: ZDZZ
+REAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS :: ZEXN
+REAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS :: ZZZ
+#ifdef MNH_OPENACC
+INTEGER :: IZDZZ, IZEXN, IZZZ
+#endif
                                     ! model layer height
 ! REAL  :: ZMASSTOT                   ! total mass  for one water category
 !                                     ! including the negative values
@@ -481,18 +488,26 @@ REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZZZ
 !
 INTEGER                               :: ISVBEG ! first scalar index for microphysics
 INTEGER                               :: ISVEND ! last  scalar index for microphysics
-REAL, DIMENSION(:),       ALLOCATABLE :: ZRSMIN ! Minimum value for tendencies
-LOGICAL, DIMENSION(:,:,:), ALLOCATABLE :: LLMICRO ! mask to limit computation
-REAL, DIMENSION(:,:,:,:), ALLOCATABLE :: ZFPR
+REAL, DIMENSION(:),        ALLOCATABLE          :: ZRSMIN ! Minimum value for tendencies
+LOGICAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS :: LLMICRO ! mask to limit computation
+REAL, DIMENSION(:,:,:,:),  POINTER , CONTIGUOUS :: ZFPR
+#ifdef MNH_OPENACC
+INTEGER :: ILLMICRO, IZFPR
+#endif
 !
 INTEGER                               :: JMOD, JMOD_IFN
 LOGICAL                               :: GWEST,GEAST,GNORTH,GSOUTH
 ! BVIE work array waiting for PINPRI
-REAL, DIMENSION(:,:), ALLOCATABLE :: ZINPRI
-REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZICEFR
-REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZPRCFR
-REAL, DIMENSION(:,:,:),   ALLOCATABLE :: ZTHSSTEP
-REAL, DIMENSION(:,:,:,:), ALLOCATABLE :: ZRSSTEP
+REAL, DIMENSION(:,:),     POINTER , CONTIGUOUS :: ZINPRI
+REAL, DIMENSION(:,:,:),   POINTER , CONTIGUOUS :: ZICEFR
+REAL, DIMENSION(:,:,:),   POINTER , CONTIGUOUS :: ZPRCFR
+REAL, DIMENSION(:,:,:),   POINTER , CONTIGUOUS :: ZTHSSTEP
+REAL, DIMENSION(:,:,:,:), POINTER , CONTIGUOUS :: ZRSSTEP
+#ifdef MNH_OPENACC
+INTEGER :: IZINPRI, IZICEFR, IZPRCFR, IZTHSSTEP, IZRSSTEP
+#endif
+!
+INTEGER  :: JIU,JJU,JKU
 !
 !------------------------------------------------------------------------------
 !
@@ -566,28 +581,62 @@ IF (MPPDB_INITIALIZED) THEN
   CALL MPPDB_CHECK(PHLI_HCF,"RESOLVED_CLOUD beg:PHLI_HCF")
 END IF
 !
-allocate ( LLMICRO  ( SIZE(PZZ,1),  SIZE(PZZ,2),  SIZE(PZZ,3)  ) )
-allocate ( ZDZZ     ( SIZE(PZZ,1),  SIZE(PZZ,2),  SIZE(PZZ,3)  ) )
-allocate ( ZZZ      ( SIZE(PZZ,1),  SIZE(PZZ,2),  SIZE(PZZ,3)  ) )
-allocate ( ZINPRI   ( SIZE(PZZ,1),  SIZE(PZZ,2) ) )
+JIU =  size(PZZ, 1 )
+JJU =  size(PZZ, 2 )
+JKU =  size(PZZ, 3 )
+!
+#ifndef MNH_OPENACC
+allocate ( LLMICRO  ( JIU,JJU,JKU  ) )
+allocate ( ZDZZ     ( JIU,JJU,JKU  ) )
+
+if ( hcloud == 'ICE3' .or. hcloud == 'ICE4' ) then
+  allocate ( ZEXN   ( JIU,JJU,JKU  ) )
+  allocate ( ZFPR   ( JIU,JJU,JKU,KRR ) )
+else
+  allocate ( ZEXN   ( 0,0,0 ) )
+  allocate ( ZFPR   ( 0,0,0,0 ) )
+end if
+
+if ( hcloud == 'LIMA' .and. lptsplit ) then
+  allocate( ZICEFR  ( JIU,JJU,JKU  ) )
+  allocate( ZPRCFR  ( JIU,JJU,JKU  ) )
+else
+  allocate( ZICEFR  (0, 0, 0) )
+  allocate( ZPRCFR  (0, 0, 0) )
+end if
+
+allocate ( ZZZ      ( JIU,JJU,JKU  ) )
+allocate ( ZINPRI   ( JIU,JJU ) )
 allocate ( ZTHSSTEP ( SIZE(PTHS,1), SIZE(PTHS,2), SIZE(PTHS,3) ) )
 allocate ( ZRSSTEP  ( SIZE(PRS,1),  SIZE(PRS,2),  SIZE(PRS,3), SIZE(PRS,4) ) )
+#else
+ILLMICRO  = MNH_ALLOCATE_GT3D ( LLMICRO   ,JIU,JJU,JKU )
+IZDZZ     = MNH_ALLOCATE_ZT3D ( ZDZZ      ,JIU,JJU,JKU )
 
-IF ( HCLOUD == 'ICE3' .OR. HCLOUD == 'ICE4' ) THEN
-  ALLOCATE( ZFPR( SIZE(PZZ,1), SIZE(PZZ,2), SIZE(PZZ,3), KRR ) )
-ELSE
-  ALLOCATE( ZFPR(0, 0, 0, 0) )
-END IF
+if ( hcloud == 'ICE3' .or. hcloud == 'ICE4' ) then
+  IZEXN     = MNH_ALLOCATE_ZT3D ( ZEXN    ,JIU,JJU,JKU )
+  IZFPR     = MNH_ALLOCATE_ZT3D ( ZFPR    ,JIU,JJU,JKU )
+else
+  IZEXN     = MNH_ALLOCATE_ZT3D ( ZEXN    ,0,0,0 )
+  IZFPR     = MNH_ALLOCATE_ZT3D ( ZFPR    ,0,0,0 )
+end if
+
+if ( hcloud == 'LIMA' .and. lptsplit ) then
+  IZICEFR   = MNH_ALLOCATE_ZT3D ( ZICEFR  ,JIU,JJU,JKU )
+  IZPRCFR   = MNH_ALLOCATE_ZT3D ( ZPRCFR  ,JIU,JJU,JKU )
+else
+  IZICEFR   = MNH_ALLOCATE_ZT3D ( ZICEFR  ,0,0,0 )
+  IZPRCFR   = MNH_ALLOCATE_ZT3D ( ZPRCFR  ,0,0,0 )
+end if
+
+IZZZ      = MNH_ALLOCATE_ZT3D ( ZZZ       ,JIU,JJU,JKU )
+IZINPRI   = MNH_ALLOCATE_ZT2D ( ZINPRI    ,JIU,JJU )
+IZTHSSTEP = MNH_ALLOCATE_ZT3D ( ZTHSSTEP , SIZE(PTHS,1), SIZE(PTHS,2), SIZE(PTHS,3) )
+IZRSSTEP  = MNH_ALLOCATE_ZT4D ( ZRSSTEP  , SIZE(PRS,1),  SIZE(PRS,2), SIZE(PRS,3), SIZE(PRS,4) )
+#endif
 
-IF ( HCLOUD == 'LIMA' .and. LPTSPLIT ) THEN
-  ALLOCATE( ZICEFR( SIZE(PZZ,1), SIZE(PZZ,2), SIZE(PZZ,3) ) )
-  ALLOCATE( ZPRCFR( SIZE(PZZ,1), SIZE(PZZ,2), SIZE(PZZ,3) ) )
-ELSE
-  ALLOCATE( ZICEFR(0, 0, 0) )
-  ALLOCATE( ZPRCFR(0, 0, 0) )
-END IF
 
-!$acc data create(LLMICRO,ZDZZ,ZZZ,ZINPRI,ZTHSSTEP,ZRSSTEP, ZFPR, ZICEFR, ZPRCFR)
+!$acc data present( LLMICRO, ZDZZ, ZEXN, ZFPR, ZICEFR, ZPRCFR, ZZZ, ZINPRI, ZTHSSTEP, ZRSSTEP )
 
 CALL GET_INDICE_ll (IIB,IJB,IIE,IJE)
 IKA=1
@@ -627,11 +676,12 @@ END IF
 !*       2.     TRANSFORMATION INTO PHYSICAL TENDENCIES
 !               ---------------------------------------
 !
-!$acc kernels present(PTHS,PRS,PRHODJ,PPABST)
+!$acc kernels ! present(PTHS,PRS,PRHODJ,PPABST,ZEXN,ZLV,ZLS,ZCPH)
 PTHS(:,:,:) = PTHS(:,:,:) / PRHODJ(:,:,:)
-DO JRR = 1,KRR
-  PRS(:,:,:,JRR)  = PRS(:,:,:,JRR) / PRHODJ(:,:,:)
-END DO
+!
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU ,JRR = 1:KRR )
+  PRS(JI,JJ,JK,JRR)  = PRS(JI,JJ,JK,JRR) / PRHODJ(JI,JJ,JK)
+END DO ! CONCURRENT
 !
 IF (HCLOUD=='C2R2' .OR. HCLOUD=='C3R5' .OR. HCLOUD=='KHKO' .OR. HCLOUD=='LIMA') THEN
   DO JSV = ISVBEG, ISVEND
@@ -1196,10 +1246,17 @@ call Sources_neg_correct( hcloud, 'NECON', krr, ptstep, ppabst, ptht, prt, pths,
 !               ---------------------------------------
 !
 !$acc kernels
-PTHS(:,:,:) = PTHS(:,:,:) * PRHODJ(:,:,:)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   PTHS(JI,JJ,JK) = PTHS(JI,JJ,JK) * PRHODJ(JI,JJ,JK)
+END DO ! CONCURRENT
+!$acc end kernels
 !
-DO JRR = 1,KRR
-  PRS(:,:,:,JRR)  = PRS(:,:,:,JRR) * PRHODJ(:,:,:)
+!$acc kernels
+!$acc loop seq
+DO JRR=1,KRR
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU )
+      PRS(JI,JJ,JK,JRR)  = PRS(JI,JJ,JK,JRR) * PRHODJ(JI,JJ,JK)
+   END DO ! CONCURRENT
 END DO
 !$acc end kernels
 !
@@ -1243,6 +1300,23 @@ END IF
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate (LLMICRO)
+deallocate (ZDZZ,ZEXN,ZZZ)
+deallocate (ZINPRI)
+deallocate (ZTHSSTEP)
+deallocate (ZRSSTEP)
+#else
+CALL MNH_REL_ZT4D(SIZE(PRS,4) , IZRSSTEP )
+CALL MNH_REL_ZT3D ( IZTHSSTEP )
+CALL MNH_REL_ZT3D ( IZINPRI )
+CALL MNH_REL_ZT3D ( IZDZZ,IZZZ )
+CALL MNH_REL_ZT3D ( IZEXN, IZFPR )
+CALL MNH_REL_ZT3D ( IZICEFR, IZPRCFR )
+
+CALL MNH_REL_GT3D ( ILLMICRO )
+#endif
+
 !$acc end data
 
 !-------------------------------------------------------------------------------
diff --git a/src/MNH/set_ref.f90 b/src/MNH/set_ref.f90
index 3fbd530b720dad8acead062a8a9854cfbc3950a0..2fbb25ee08b0c3fffee800db82afdbb494f5c00d 100644
--- a/src/MNH/set_ref.f90
+++ b/src/MNH/set_ref.f90
@@ -167,6 +167,9 @@ USE MODE_IO_FIELD_READ, only: IO_Field_read
 USE MODE_ll
 USE MODE_MPPDB
 USE MODE_REPRO_SUM
+#ifdef MNH_BITREP
+USE MODI_BITREP
+#endif
 !
 IMPLICIT NONE
 !
@@ -415,7 +418,11 @@ ZCVD_O_RD = (XCPD / XRD) - 1.
 IF (LBOUSS) THEN
   ZRHOREF(:,:,:) = PRHODREF(:,:,:)
 ELSE
-  ZRHOREF(:,:,:) = PEXNREF(:,:,:) ** ZCVD_O_RD * XP00 / ( XRD * PTHVREF(:,:,:) )
+#ifndef MNH_BITREP   
+   ZRHOREF(:,:,:) = PEXNREF(:,:,:) ** ZCVD_O_RD * XP00 / ( XRD * PTHVREF(:,:,:) )
+#else
+   ZRHOREF(:,:,:) = BR_POW ( PEXNREF(:,:,:) , ZCVD_O_RD ) * XP00 / ( XRD * PTHVREF(:,:,:) )
+#endif   
   ZRHOREF(:,:,1)=ZRHOREF(:,:,2)  ! this avoids to obtain erroneous values for
                                   ! rv at this last point
 END IF
diff --git a/src/MNH/shuman_device.f90 b/src/MNH/shuman_device.f90
index 380868f8cc95d982977a15fcdba51f6fc462e987..0ca7755d45e1c1a13b5a8fdd76e592e27413fd53 100644
--- a/src/MNH/shuman_device.f90
+++ b/src/MNH/shuman_device.f90
@@ -167,6 +167,7 @@ IKU = SIZE(PA,3)
 !
 #ifndef _OPT_LINEARIZED_LOOPS
 !$acc kernels present(PMXF,PA)
+!$acc loop independent collapse(3)
 DO JK = 1, IKU
   DO JJ = 1, IJU
     DO JI = 1 + 1, IIU
@@ -292,6 +293,7 @@ IKU = SIZE(PA,3)
 !
 #ifndef _OPT_LINEARIZED_LOOPS
 !$acc kernels present(PA,PMXM)
+!$acc loop independent collapse(3)
 DO JK = 1, IKU
   DO JJ = 1, IJU
     DO JI = 1 + 1, IIU
@@ -300,6 +302,7 @@ DO JK = 1, IKU
   ENDDO
 ENDDO
 !
+!$acc loop independent collapse(2)
 DO JK = 1, IKU
   DO JJ=1,IJU
     PMXM(1,JJ,JK)    = PMXM(IIU-2*JPHEXT+1,JJ,JK)  	!TODO: voir si ce n'est pas plutot JPHEXT+1
@@ -418,6 +421,7 @@ IKU = SIZE(PA,3)
 !
 !$acc kernels present(PA,PMYF)
 #ifndef _OPT_LINEARIZED_LOOPS
+!$acc loop independent collapse(3)
 DO JK=1,IKU
   DO JJ=1,IJU-1
     DO JI=1,IIU !TODO: remplacer le 1 par JPHEXT ?
@@ -534,6 +538,7 @@ IKU = SIZE(PA,3)
 !
 #ifndef _OPT_LINEARIZED_LOOPS
 !$acc kernels present(PA,PMYM)
+!$acc loop independent collapse(3)
 DO JK=1,IKU
   DO JJ=2,IJU !TODO: remplacer le 1+1 par 1+JPHEXT ?
     DO JI=1,IIU
@@ -870,6 +875,7 @@ IKU = SIZE(PA,3)
 !
 #ifndef _OPT_LINEARIZED_LOOPS
 !$acc kernels present(PA,PDXF)
+!$acc loop independent collapse(3)
 DO JK=1,IKU
   DO JJ=1,IJU
     DO JI=1+1,IIU
@@ -878,6 +884,7 @@ DO JK=1,IKU
   END DO
 END DO
 !
+!$acc loop independent collapse(2)
 DO JK=1,IKU
   DO JJ=1,IJU
     PDXF(IIU,JJ,JK)    = PDXF(2*JPHEXT,JJ,JK) 
@@ -994,6 +1001,7 @@ IKU = SIZE(PA,3)
 !
 #ifndef _OPT_LINEARIZED_LOOPS
 !$acc kernels present(PA,PDXM)
+!$acc loop independent collapse(3)
 DO JK=1,IKU
   DO JJ=1,IJU
     DO JI=1+1,IIU !TODO: remplacer le 1 par JPHEXT ?
@@ -1002,6 +1010,7 @@ DO JK=1,IKU
   END DO
 END DO
 !
+!$acc loop independent collapse(2)
 DO JK=1,IKU
   DO JJ=1,IJU
     PDXM(1,JJ,JK)    = PDXM(IIU-2*JPHEXT+1,JJ,JK)   !TODO: remplacer -2*JPHEXT+1 par -JPHEXT ?
@@ -1119,6 +1128,7 @@ IKU = SIZE(PA,3)
 !
 !$acc kernels present(PA,PDYF)
 #ifndef _OPT_LINEARIZED_LOOPS
+!$acc loop independent collapse(3)
 DO JK=1,IKU
   DO JJ=1,IJU-1 !TODO: remplacer le 1 par JPHEXT ?
     DO JI=1,IIU
@@ -1232,6 +1242,7 @@ IKU=SIZE(PA,3)
 !
 #ifndef _OPT_LINEARIZED_LOOPS
 !$acc kernels present(PA,PDYM)
+!$acc loop independent collapse(3)
 DO JK=1,IKU
   DO JJ=2,IJU !TODO: remplacer le 2 par JPHEXT+1 ?
     DO JI=1,IIU
@@ -1240,9 +1251,6 @@ DO JK=1,IKU
   END DO
 END DO
 !
-DO JJ=1,JPHEXT
-   PDYM(:,JJ,:) = PDYM(:,IJU-2*JPHEXT+JJ,:) ! for reprod JPHEXT <> 1
-END DO
 #else
 JIJKOR  = 1 + IIU
 JIJKEND = IIU*IJU*IKU
@@ -1345,6 +1353,7 @@ IKU = SIZE(PA,3)
 !
 #ifndef _OPT_LINEARIZED_LOOPS
 !$acc kernels present(PA,PDZF)
+!$acc loop independent collapse(3)
 DO JK=1,IKU-1 !TODO: remplacer le 1 par JPHEXT ?
   DO JJ=1,IJU
     DO JI=1,IIU
@@ -1459,6 +1468,7 @@ IKU = SIZE(PA,3)
 !
 #ifndef _OPT_LINEARIZED_LOOPS
 !$acc kernels present(PA,PDZM)
+!$acc loop independent collapse(3)
 DO JK=2,IKU !TODO: remplacer le 1+1 par 1+JPHEXT ?
   DO JJ=1,IJU
     DO JI=1,IIU
diff --git a/src/MNH/tke_eps_sources.f90 b/src/MNH/tke_eps_sources.f90
index ce2489c2675f766fefa4f0f034fafb09e8e89539..ea34bc2e164c9f09804156174ed51520d79469c6 100644
--- a/src/MNH/tke_eps_sources.f90
+++ b/src/MNH/tke_eps_sources.f90
@@ -186,6 +186,9 @@ USE MODE_ARGSLIST_ll,    ONLY: ADD3DFIELD_ll, CLEANLIST_ll
 use mode_budget,         only: Budget_store_add, Budget_store_end, Budget_store_init
 USE MODE_EXCHANGE_ll,    ONLY: UPDATE_HALO_ll
 USE MODE_IO_FIELD_WRITE, only: IO_Field_write
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK,      ONLY: MNH_ALLOCATE_ZT3D, MNH_REL_ZT3D
+#endif
 use mode_mppdb
 !
 #ifdef MNH_BITREP
@@ -243,7 +246,7 @@ REAL, DIMENSION(:,:,:),  INTENT(OUT)  ::  PDISS        ! Dissipati prod. of TKE
 !
 !*       0.2  declaration of local variables
 !
-REAL, DIMENSION(:,:,:), allocatable ::         &
+REAL, DIMENSION(:,:,:), pointer , contiguous ::         &
        ZA,       & ! under diagonal elements of the tri-diagonal matrix involved
                    ! in the temporal implicit scheme
        ZRES,     & ! treated variable at t+ deltat when the turbu-
@@ -253,6 +256,9 @@ REAL, DIMENSION(:,:,:), allocatable ::         &
        ZFLX,     & ! horizontal or vertical flux of the treated variable
        ZSOURCE,  & ! source of evolution for the treated variable
        ZKEFF       ! effectif diffusion coeff = LT * SQRT( TKE )
+#ifdef MNH_OPENACC
+INTEGER ::  IZA,IZRES,IZFLX,IZSOURCE,IZKEFF
+#endif
 INTEGER             :: IIB,IIE,IJB,IJE,IKB,IKE
                                     ! Index values for the Beginning and End
                                     ! mass points of the domain 
@@ -263,8 +269,12 @@ INTEGER                :: IINFO_ll       ! return code of parallel routine
 TYPE(TFIELDDATA) :: TZFIELD
 !
 #ifdef MNH_OPENACC
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE
+INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE
 #endif
+!
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ,JK
 !----------------------------------------------------------------------------
 
 !$acc data present( PTKEM, PLM, PLEPS, PDP, PTRH,              &
@@ -294,20 +304,32 @@ if ( mppdb_initialized ) then
   call Mppdb_check( prthls, "Tke_eps_sources beg:prthls" )
 end if
 
-allocate( za     (size( ptkem, 1 ), size( ptkem, 2 ), size( ptkem, 3 ) ) )
-allocate( zres   (size( ptkem, 1 ), size( ptkem, 2 ), size( ptkem, 3 ) ) )
-allocate( zflx   (size( ptkem, 1 ), size( ptkem, 2 ), size( ptkem, 3 ) ) )
-allocate( zsource(size( ptkem, 1 ), size( ptkem, 2 ), size( ptkem, 3 ) ) )
-allocate( zkeff  (size( ptkem, 1 ), size( ptkem, 2 ), size( ptkem, 3 ) ) )
+JIU =  size(ptkem, 1 )
+JJU =  size(ptkem, 2 )
+JKU =  size(ptkem, 3 )
+
+#ifndef MNH_OPENACC
+allocate( za     (JIU,JJU,JKU ) )
+allocate( zres   (JIU,JJU,JKU ) )
+allocate( zflx   (JIU,JJU,JKU ) )
+allocate( zsource(JIU,JJU,JKU ) )
+allocate( zkeff  (JIU,JJU,JKU ) )
+#else
+iza      = MNH_ALLOCATE_ZT3D( za     ,JIU,JJU,JKU)
+izres    = MNH_ALLOCATE_ZT3D( zres   ,JIU,JJU,JKU)
+izflx    = MNH_ALLOCATE_ZT3D( zflx   ,JIU,JJU,JKU)
+izsource = MNH_ALLOCATE_ZT3D( zsource,JIU,JJU,JKU)
+izkeff   = MNH_ALLOCATE_ZT3D( zkeff  ,JIU,JJU,JKU)
+#endif
 
 #ifdef MNH_OPENACC
-allocate( ztmp1_device(size( ptkem, 1 ), size( ptkem, 2 ), size( ptkem, 3 ) ) )
-allocate( ztmp2_device(size( ptkem, 1 ), size( ptkem, 2 ), size( ptkem, 3 ) ) )
-allocate( ztmp3_device(size( ptkem, 1 ), size( ptkem, 2 ), size( ptkem, 3 ) ) )
-allocate( ztmp4_device(size( ptkem, 1 ), size( ptkem, 2 ), size( ptkem, 3 ) ) )
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU)
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU)
+iztmp3_device = MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU,JKU)
+iztmp4_device = MNH_ALLOCATE_ZT3D( ztmp4_device,JIU,JJU,JKU)
 #endif
 
-!$acc data create( ZA, ZRES, ZFLX, ZSOURCE, ZKEFF, ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE )
+!$acc data present( ZA, ZRES, ZFLX, ZSOURCE, ZKEFF, ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE )
 
 NULLIFY(TZFIELDDISS_ll)
 !
@@ -325,7 +347,10 @@ IKE=KKU-JPVEXT_TURB*KKL
 #ifndef MNH_BITREP
 ZKEFF(:,:,:) = PLM(:,:,:) * SQRT(PTKEM(:,:,:))
 #else
-ZKEFF(:,:,:) = PLM(:,:,:) * BR_POW(PTKEM(:,:,:),0.5)
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZKEFF(JI,JJ,JK) = PLM(JI,JJ,JK) * BR_POW(PTKEM(JI,JJ,JK),0.5)
+END DO
 #endif
 !
 !$acc end kernels
@@ -361,11 +386,17 @@ PDP(:,:,IKB) = PDP(:,:,IKB) * (1. + PDZZ(:,:,IKB+KKL)/PDZZ(:,:,IKB))
 #ifndef MNH_BITREP
 ZFLX(:,:,:) = XCED * SQRT(PTKEM(:,:,:)) / PLEPS(:,:,:)
 #else
-ZFLX(:,:,:) = XCED * BR_POW(PTKEM(:,:,:),0.5) / PLEPS(:,:,:)
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZFLX(JI,JJ,JK) = XCED * BR_POW(PTKEM(JI,JJ,JK),0.5) / PLEPS(JI,JJ,JK)
+END DO
 #endif
-ZSOURCE(:,:,:) = ( PRTKES(:,:,:) +  PRTKESM(:,:,:) ) / PRHODJ(:,:,:) &
-   - PTKEM(:,:,:) / PTSTEP &
-   + PDP(:,:,:) + PTP(:,:,:) + PTR(:,:,:) - PEXPL * ZFLX(:,:,:) * PTKEM(:,:,:)
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZSOURCE(JI,JJ,JK) = ( PRTKES(JI,JJ,JK) + PRTKESM(JI,JJ,JK) ) / PRHODJ(JI,JJ,JK) &
+        - PTKEM(JI,JJ,JK) / PTSTEP &
+        + PDP(JI,JJ,JK) + PTP(JI,JJ,JK) + PTR(JI,JJ,JK) - PEXPL * ZFLX(JI,JJ,JK) * PTKEM(JI,JJ,JK)
+END DO !CONCURRENT
 !$acc end kernels
 !
 !*       2.2  implicit vertical TKE transport
@@ -388,7 +419,10 @@ CALL MZM_DEVICE(PRHODJ,ZTMP2_DEVICE) !Warning: re-used later
 #ifndef MNH_BITREP
 ZA(:,:,:)     = - PTSTEP * XCET * ZTMP1_DEVICE(:,:,:) * ZTMP2_DEVICE(:,:,:) / PDZZ(:,:,:)**2
 #else
-ZA(:,:,:)     = - PTSTEP * XCET * ZTMP1_DEVICE(:,:,:) * ZTMP2_DEVICE(:,:,:) / BR_P2(PDZZ(:,:,:))
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZA(JI,JJ,JK)     = - PTSTEP * XCET * ZTMP1_DEVICE(JI,JJ,JK) * ZTMP2_DEVICE(JI,JJ,JK) / BR_P2(PDZZ(JI,JJ,JK))
+END DO !CONCURRENT   
 #endif
 !$acc end kernels
 #endif
@@ -401,13 +435,16 @@ CALL TRIDIAG_TKE(KKA,KKU,KKL,PTKEM,ZA,PTSTEP,PEXPL,PIMPL,PRHODJ,&
 CALL GET_HALO(ZRES)
 #else
 !$acc kernels
-ZTMP3_DEVICE(:,:,:) = PTSTEP*ZFLX(:,:,:)
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZTMP3_DEVICE(JI,JJ,JK) = PTSTEP*ZFLX(JI,JJ,JK)
+END DO !CONCURRENT   
 !$acc end kernels
 CALL TRIDIAG_TKE(KKA,KKU,KKL,PTKEM,ZA,PTSTEP,PEXPL,PIMPL,PRHODJ,&
             & ZSOURCE,ZTMP3_DEVICE,ZRES)
-!$acc update self(ZRES)
-CALL GET_HALO(ZRES)
-!$acc update device(ZRES)
+! acc update self(ZRES)
+CALL GET_HALO_D(ZRES)
+! acc update device(ZRES)
 #endif
 !
 !* diagnose the dissipation
@@ -625,6 +662,12 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate( ZA, ZRES, ZFLX, ZSOURCE, ZKEFF )
+#else
+CALL MNH_REL_ZT3D( IZA, IZRES, IZFLX, IZSOURCE, IZKEFF, IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE )
+#endif
+
 !$acc end data
 
 END SUBROUTINE TKE_EPS_SOURCES
diff --git a/src/MNH/tools.f90 b/src/MNH/tools.f90
index 2a3b27f35497530e954db5e2cdfb29fe4581d9d9..0899dea5f2e1855711ab6b32b47f6fe9436c0ce6 100644
--- a/src/MNH/tools.f90
+++ b/src/MNH/tools.f90
@@ -1,4 +1,4 @@
-!MNH_LIC Copyright 2019-2020 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC Copyright 2019-2021 CNRS, Meteo-France and Universite Paul Sabatier
 !MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
 !MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
 !MNH_LIC for details. version 1.
@@ -22,6 +22,7 @@ module mode_tools
 !  P. Wautelet 05/06/2019: add Countjv_device
 !  P. Wautelet 20/06/2019: add Countjv1d, Countjv1d_device and Countjv2d_device subroutines
 !  P. Wautelet 17/01/2020: move Quicksort to tools.f90
+!  J. Escobar  25/08/2021: nvhpc21.X bug on 'atomic' in host -> switch to version without atomic on HOST    
 
 implicit none
 
@@ -110,6 +111,9 @@ end function Countjv3d
 #ifdef MNH_OPENACC
 subroutine Countjv1d_device(ltab, i1,ic)
   use mode_mppdb, only: mppdb_initialized
+#ifndef _FAKEOPENACC
+  use MODE_OPENACC_SET_DEVICE, only : mnh_idevice_type_current, acc_device_nvidia
+#endif
 
   logical, dimension(:), intent(in)  :: ltab ! Mask
   integer, dimension(:), intent(out) :: i1   ! Positions of elements with 'true' value
@@ -120,15 +124,20 @@ subroutine Countjv1d_device(ltab, i1,ic)
 
 !$acc data present( ltab, i1 )
 
-if ( .not. mppdb_initialized ) then
-!$acc kernels
+#ifndef _FAKEOPENACC
+if ( (.not. mppdb_initialized ) .and. (mnh_idevice_type_current .eq. acc_device_nvidia ) ) then
+#else
+if (.not. mppdb_initialized ) then
+#endif
 
+ic = 0
+   
+!$acc kernels
+   
 !To allow comparisons... (i1 is not fully used)
 !Can be removed in production
 !   i1(:) = -999
-
-  ic = 0
-
+  
 !Warning: if "independent" is set, content of i1, i2 and i3 can vary between 2
 ! different runs of this subroutine BUT final result should be the same
 !Comment the following line + atomic directives to have consistent values for debugging
@@ -146,13 +155,13 @@ if ( .not. mppdb_initialized ) then
 !$acc end kernels
 
 else
-
+   
+ic = 0
+   
 !$acc kernels
 
 !To allow comparisons... (i1 is not fully used)
-  i1(:) = -999
-
-  ic = 0
+!!$  i1(:) = -999
 
   do ji = 1, size( ltab, 1 )
     if ( ltab(ji ) ) then
@@ -172,6 +181,9 @@ end subroutine Countjv1d_device
 
 subroutine Countjv2d_device(ltab, i1, i2, ic)
   use mode_mppdb, only: mppdb_initialized
+#ifndef _FAKEOPENACC
+  use MODE_OPENACC_SET_DEVICE, only : mnh_idevice_type_current, acc_device_nvidia
+#endif
 
   logical, dimension(:,:), intent(in)  :: ltab   ! Mask
   integer, dimension(:),   intent(out) :: i1, i2 ! Positions of elements with 'true' value
@@ -182,7 +194,14 @@ subroutine Countjv2d_device(ltab, i1, i2, ic)
 
 !$acc data present( ltab, i1, i2 )
 
-if ( .not. mppdb_initialized ) then
+#ifndef _FAKEOPENACC
+if ( (.not. mppdb_initialized ) .and. (mnh_idevice_type_current .eq. acc_device_nvidia ) ) then
+#else
+if (.not. mppdb_initialized ) then
+#endif
+
+ic = 0   
+     
 !$acc kernels
 
 !To allow comparisons... (i1/i2 are not fully used)
@@ -190,8 +209,6 @@ if ( .not. mppdb_initialized ) then
 !   i1(:) = -999
 !   i2(:) = -999
 
-  ic = 0
-
 !Warning: if "independent" is set, content of i1, i2 and i3 can vary between 2
 ! different runs of this subroutine BUT final result should be the same
 !Comment the following line + atomic directives to have consistent values for debugging
@@ -213,14 +230,14 @@ if ( .not. mppdb_initialized ) then
 
 else
 
+ic = 0
+   
 !$acc kernels
 
 !To allow comparisons... (i1/i2 are not fully used)
   i1(:) = -999
   i2(:) = -999
 
-  ic = 0
-
   do jj = 1, size( ltab, 2 )
     do ji = 1, size( ltab, 1 )
       if ( ltab(ji, jj ) ) then
@@ -242,6 +259,9 @@ end subroutine Countjv2d_device
 
 subroutine Countjv3d_device(ltab, i1, i2, i3, ic)
   use mode_mppdb, only: mppdb_initialized
+#ifndef _FAKEOPENACC
+  use MODE_OPENACC_SET_DEVICE, only : mnh_idevice_type_current, acc_device_nvidia
+#endif
 
   logical, dimension(:,:,:), intent(in)  :: ltab       ! Mask
   integer, dimension(:),     intent(out) :: i1, i2, i3 ! Positions of elements with 'true' value
@@ -252,7 +272,14 @@ subroutine Countjv3d_device(ltab, i1, i2, i3, ic)
 
 !$acc data present( ltab, i1, i2, i3 )
 
-if ( .not. mppdb_initialized ) then
+#ifndef _FAKEOPENACC
+if ( (.not. mppdb_initialized ) .and. (mnh_idevice_type_current .eq. acc_device_nvidia ) ) then
+#else
+if (.not. mppdb_initialized ) then
+#endif
+
+ic = 0
+   
 !$acc kernels
 
 !To allow comparisons... (i1/i2/i3 are not fully used)
@@ -261,8 +288,6 @@ if ( .not. mppdb_initialized ) then
 !   i2(:) = -999
 !   i3(:) = -999
 
-  ic = 0
-
 !Warning: if "independent" is set, content of i1, i2 and i3 can vary between 2
 ! different runs of this subroutine BUT final result should be the same
 !Comment the following line + atomic directives to have consistent values for debugging
@@ -287,14 +312,14 @@ if ( .not. mppdb_initialized ) then
 
 else
 
+ic = 0  
+
 !$acc kernels
 
 !To allow comparisons... (i1/i2/i3 are not fully used)
-  i1(:) = -999
-  i2(:) = -999
-  i3(:) = -999
-
-  ic = 0
+!!$  i1(:) = -999
+!!$  i2(:) = -999
+!!$  i3(:) = -999
 
   do jk = 1, size( ltab, 3 )
     do jj = 1, size( ltab, 2 )
diff --git a/src/MNH/tridiag_thermo.f90 b/src/MNH/tridiag_thermo.f90
index ff79d84bbfa90beb40c23634c906b798af4aa4a9..d3d3c1b005602a7341eabb34f704bd9b7f7567ae 100644
--- a/src/MNH/tridiag_thermo.f90
+++ b/src/MNH/tridiag_thermo.f90
@@ -6,8 +6,9 @@
 !     ###################
       MODULE MODI_TRIDIAG_THERMO
 !     ###################
+!        
 INTERFACE
-!
+!        
        SUBROUTINE TRIDIAG_THERMO(KKA,KKU,KKL,PVARM,PF,PDFDDTDZ,PTSTEP,PIMPL,  &
                                  PDZZ,PRHODJ,PVARP             )
 !
@@ -30,9 +31,6 @@ END INTERFACE
 !
 END MODULE MODI_TRIDIAG_THERMO 
 !
-!
-!
-
 !      #################################################
        SUBROUTINE TRIDIAG_THERMO(KKA,KKU,KKL,PVARM,PF,PDFDDTDZ,PTSTEP,PIMPL,  &
                                  PDZZ,PRHODJ,PVARP             )
@@ -159,6 +157,11 @@ USE MODI_SHUMAN_DEVICE
 USE MODI_BITREP
 #endif
 !
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D , MNH_ALLOCATE_ZT2D, &
+                            MNH_CHECK_IN_ZT3D,MNH_CHECK_OUT_ZT3D
+#endif
+!
 IMPLICIT NONE
 !
 !
@@ -179,12 +182,18 @@ REAL, DIMENSION(:,:,:), INTENT(OUT):: PVARP   ! variable at t+1      at mass poi
 !
 !*       0.2 declarations of local variables
 !
-REAL, DIMENSION(:,:,:), allocatable :: ZRHODJ_DFDDTDZ_O_DZ2
-REAL, DIMENSION(:,:,:), allocatable :: ZMZM_RHODJ
-REAL, DIMENSION(:,:,:), allocatable :: ZA, ZB, ZC
-REAL, DIMENSION(:,:,:), allocatable :: ZY ,ZGAM
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZRHODJ_DFDDTDZ_O_DZ2
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZMZM_RHODJ
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZA, ZB, ZC
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZY ,ZGAM
                                          ! RHS of the equation, 3D work array
-REAL, DIMENSION(:,:), allocatable   :: ZBET
+#ifdef MNH_OPENACC
+INTEGER :: IZRHODJ_DFDDTDZ_O_DZ2,IZMZM_RHODJ,IZA,IZB,IZC,IZY,IZGAM
+#endif
+REAL, DIMENSION(:,:), pointer , contiguous   :: ZBET
+#ifdef MNH_OPENACC
+INTEGER :: IZBET
+#endif
                                          ! 2D work array
 INTEGER             :: JI,JJ,JK      ! loop counter
 INTEGER             :: IKB,IKE       ! inner vertical limits
@@ -193,8 +202,12 @@ INTEGER             :: IKTB,IKTE    ! start, end of k loops in physical domain
 !
 !
 #ifdef MNH_OPENACC
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE
+INTEGER :: IZTMP1_DEVICE
 #endif
+
+INTEGER  :: JIU,JJU,JKU
+
 ! ---------------------------------------------------------------------------
 
 !$acc data present( PVARM, PF, PDFDDTDZ, PDZZ, PRHODJ, PVARP )
@@ -208,20 +221,36 @@ if ( mppdb_initialized ) then
   call Mppdb_check( prhodj,   "Tridiag_thermo beg:prhodj"   )
 end if
 
-allocate( zrhodj_dfddtdz_o_dz2(size( pvarm, 1 ), size( pvarm, 2 ), size( pvarm, 3 ) ) )
-allocate( zmzm_rhodj          (size( pvarm, 1 ), size( pvarm, 2 ), size( pvarm, 3 ) ) )
-allocate( za                  (size( pvarm, 1 ), size( pvarm, 2 ), size( pvarm, 3 ) ) )
-allocate( zb                  (size( pvarm, 1 ), size( pvarm, 2 ), size( pvarm, 3 ) ) )
-allocate( zc                  (size( pvarm, 1 ), size( pvarm, 2 ), size( pvarm, 3 ) ) )
-allocate( zy                  (size( pvarm, 1 ), size( pvarm, 2 ), size( pvarm, 3 ) ) )
-allocate( zgam                (size( pvarm, 1 ), size( pvarm, 2 ), size( pvarm, 3 ) ) )
-allocate( zbet                (size( pvarm, 1 ), size( pvarm, 2 ) ) )
+JIU =  size( pvarm, 1 )
+JJU =  size( pvarm, 2 )
+JKU =  size( pvarm, 3 )
+
+#ifndef MNH_OPENACC
+allocate( zrhodj_dfddtdz_o_dz2(JIU,JJU,JKU ) )
+allocate( zmzm_rhodj          (JIU,JJU,JKU ) )
+allocate( za                  (JIU,JJU,JKU ) )
+allocate( zb                  (JIU,JJU,JKU ) )
+allocate( zc                  (JIU,JJU,JKU ) )
+allocate( zy                  (JIU,JJU,JKU ) )
+allocate( zgam                (JIU,JJU,JKU ) )
+allocate( zbet                (JIU,JJU ) )
+#else
+CALL MNH_CHECK_IN_ZT3D("TRIDIAG_THERMO")
+izrhodj_dfddtdz_o_dz2 = MNH_ALLOCATE_ZT3D( zrhodj_dfddtdz_o_dz2,JIU,JJU,JKU )
+izmzm_rhodj           = MNH_ALLOCATE_ZT3D( zmzm_rhodj          ,JIU,JJU,JKU )
+iza                   = MNH_ALLOCATE_ZT3D( za                  ,JIU,JJU,JKU )
+izb                   = MNH_ALLOCATE_ZT3D( zb                  ,JIU,JJU,JKU )
+izc                   = MNH_ALLOCATE_ZT3D( zc                  ,JIU,JJU,JKU )
+izy                   = MNH_ALLOCATE_ZT3D( zy                  ,JIU,JJU,JKU )
+izgam                 = MNH_ALLOCATE_ZT3D( zgam                ,JIU,JJU,JKU )
+izbet                 = MNH_ALLOCATE_ZT2D( zbet                ,JIU,JJU )
+#endif
 
 #ifdef MNH_OPENACC
-allocate( ztmp1_device(size( pvarm, 1 ), size( pvarm, 2 ), size( pvarm, 3 ) ) )
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU )
 #endif
 
-!$acc data create( zrhodj_dfddtdz_o_dz2, zmzm_rhodj, za, zb, zc, zy, zgam, zbet, ztmp1_device )
+!$acc data present( zrhodj_dfddtdz_o_dz2, zmzm_rhodj, za, zb, zc, zy, zgam, zbet, ztmp1_device )
 !
 !*      1.  Preliminaries
 !           -------------
@@ -231,60 +260,71 @@ IKTB=1+JPVEXT_TURB
 IKTE=IKT-JPVEXT_TURB
 IKB=KKA+JPVEXT_TURB*KKL
 IKE=KKU-JPVEXT_TURB*KKL
-
 !
 #ifndef MNH_OPENACC
 ZMZM_RHODJ = MZM(PRHODJ)
 #else
 CALL MZM_DEVICE(PRHODJ,ZMZM_RHODJ)
 #endif
-!$acc kernels async
+!$acc kernels ! async
 #ifndef MNH_BITREP
 ZRHODJ_DFDDTDZ_O_DZ2 = ZMZM_RHODJ*PDFDDTDZ/PDZZ**2
 #else
-ZRHODJ_DFDDTDZ_O_DZ2 = ZMZM_RHODJ*PDFDDTDZ/BR_P2(PDZZ)
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU) 
+   ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,JK) = ZMZM_RHODJ(JI,JJ,JK)*PDFDDTDZ(JI,JJ,JK)/BR_P2(PDZZ(JI,JJ,JK))
+END DO !CONCURRENT   
 #endif
 !$acc end kernels
 !
-!$acc kernels async
+!$acc kernels ! async
 ZA=0.
 ZB=0.
 ZC=0.
 ZY=0.
 !$acc end kernels
-!$acc wait
+! acc wait
 !
 !
 !*      2.  COMPUTE THE RIGHT HAND SIDE
 !           ---------------------------
 !
-!$acc kernels async
-ZY(:,:,IKB) = PRHODJ(:,:,IKB)*PVARM(:,:,IKB)/PTSTEP                  &
-    - ZMZM_RHODJ(:,:,IKB+KKL) * PF(:,:,IKB+KKL)/PDZZ(:,:,IKB+KKL)    &
-    + ZMZM_RHODJ(:,:,IKB  ) * PF(:,:,IKB  )/PDZZ(:,:,IKB  )          &
-    + ZRHODJ_DFDDTDZ_O_DZ2(:,:,IKB+KKL) * PIMPL * PVARM(:,:,IKB+KKL) &
-    - ZRHODJ_DFDDTDZ_O_DZ2(:,:,IKB+KKL) * PIMPL * PVARM(:,:,IKB  )
+!$acc kernels ! async
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+ZY(JI,JJ,IKB) = PRHODJ(JI,JJ,IKB)*PVARM(JI,JJ,IKB)/PTSTEP                  &
+    - ZMZM_RHODJ(JI,JJ,IKB+KKL) * PF(JI,JJ,IKB+KKL)/PDZZ(JI,JJ,IKB+KKL)    &
+    + ZMZM_RHODJ(JI,JJ,IKB  ) * PF(JI,JJ,IKB  )/PDZZ(JI,JJ,IKB  )          &
+    + ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,IKB+KKL) * PIMPL * PVARM(JI,JJ,IKB+KKL) &
+    - ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,IKB+KKL) * PIMPL * PVARM(JI,JJ,IKB  )
+END DO !CONCURRENT
 !$acc end kernels
 !
-!$acc kernels async
-  ZY(:,:,IKTB+1:IKTE-1) = PRHODJ(:,:,IKTB+1:IKTE-1)*PVARM(:,:,IKTB+1:IKTE-1)/PTSTEP                 &
-    - ZMZM_RHODJ(:,:,IKTB+1+KKL:IKTE-1+KKL) * PF(:,:,IKTB+1+KKL:IKTE-1+KKL)/PDZZ(:,:,IKTB+1+KKL:IKTE-1+KKL)     &
-    + ZMZM_RHODJ(:,:,IKTB+1:IKTE-1  ) * PF(:,:,IKTB+1:IKTE-1  )/PDZZ(:,:,IKTB+1:IKTE-1  )           &
-    + ZRHODJ_DFDDTDZ_O_DZ2(:,:,IKTB+1+KKL:IKTE-1+KKL) * PIMPL * PVARM(:,:,IKTB+1+KKL:IKTE-1+KKL) &
-    - ZRHODJ_DFDDTDZ_O_DZ2(:,:,IKTB+1+KKL:IKTE-1+KKL) * PIMPL * PVARM(:,:,IKTB+1:IKTE-1  )   &
-    - ZRHODJ_DFDDTDZ_O_DZ2(:,:,IKTB+1:IKTE-1    ) * PIMPL * PVARM(:,:,IKTB+1:IKTE-1  )   &
-    + ZRHODJ_DFDDTDZ_O_DZ2(:,:,IKTB+1:IKTE-1    ) * PIMPL * PVARM(:,:,IKTB+1-KKL:IKTE-1-KKL)
+!$acc kernels ! async
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=IKTB+1:IKTE-1)
+  ZY(JI,JJ,JK) = PRHODJ(JI,JJ,JK)*PVARM(JI,JJ,JK)/PTSTEP                 &
+    - ZMZM_RHODJ(JI,JJ,JK+KKL) * PF(JI,JJ,JK+KKL)/PDZZ(JI,JJ,JK+KKL)     &
+    + ZMZM_RHODJ(JI,JJ,JK  ) * PF(JI,JJ,JK  )/PDZZ(JI,JJ,JK  )           &
+    + ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,JK+KKL) * PIMPL * PVARM(JI,JJ,JK+KKL) &
+    - ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,JK+KKL) * PIMPL * PVARM(JI,JJ,JK  )   &
+    - ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,JK    ) * PIMPL * PVARM(JI,JJ,JK  )   &
+    + ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,JK    ) * PIMPL * PVARM(JI,JJ,JK-KKL)
+END DO !CONCURRENT
 !$acc end kernels
 ! 
-!$acc kernels async
-ZY(:,:,IKE) = PRHODJ(:,:,IKE)*PVARM(:,:,IKE)/PTSTEP               &
-    - ZMZM_RHODJ(:,:,IKE+KKL) * PF(:,:,IKE+KKL)/PDZZ(:,:,IKE+KKL) &
-    + ZMZM_RHODJ(:,:,IKE  ) * PF(:,:,IKE  )/PDZZ(:,:,IKE  )       &
-    - ZRHODJ_DFDDTDZ_O_DZ2(:,:,IKE ) * PIMPL * PVARM(:,:,IKE  )   &
-    + ZRHODJ_DFDDTDZ_O_DZ2(:,:,IKE ) * PIMPL * PVARM(:,:,IKE-KKL)
+!$acc kernels ! async
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+ZY(JI,JJ,IKE) = PRHODJ(JI,JJ,IKE)*PVARM(JI,JJ,IKE)/PTSTEP               &
+    - ZMZM_RHODJ(JI,JJ,IKE+KKL) * PF(JI,JJ,IKE+KKL)/PDZZ(JI,JJ,IKE+KKL) &
+    + ZMZM_RHODJ(JI,JJ,IKE  ) * PF(JI,JJ,IKE  )/PDZZ(JI,JJ,IKE  )       &
+    - ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,IKE ) * PIMPL * PVARM(JI,JJ,IKE  )   &
+    + ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,IKE ) * PIMPL * PVARM(JI,JJ,IKE-KKL)
+END DO !CONCURRENT
 !$acc end kernels
 !
-!$acc wait
+! acc wait
 !
 !*       3.  INVERSION OF THE TRIDIAGONAL SYSTEM
 !            -----------------------------------
@@ -294,77 +334,102 @@ IF ( PIMPL > 1.E-10 ) THEN
 !*       3.1 arrays A, B, C
 !            --------------
 !
-!$acc kernels async
-  ZB(:,:,IKB) =   PRHODJ(:,:,IKB)/PTSTEP                   &
-                - ZRHODJ_DFDDTDZ_O_DZ2(:,:,IKB+KKL) * PIMPL
+!$acc kernels ! async
+!$acc loop independent collapse(2)   
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)   
+  ZB(JI,JJ,IKB) =   PRHODJ(JI,JJ,IKB)/PTSTEP                   &
+                - ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,IKB+KKL) * PIMPL
+END DO !CONCURRENT 
 !$acc end kernels
 !
-!$acc kernels async
-  ZC(:,:,IKB) =   ZRHODJ_DFDDTDZ_O_DZ2(:,:,IKB+KKL) * PIMPL
+!$acc kernels ! async
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+  ZC(JI,JJ,IKB) =   ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,IKB+KKL) * PIMPL
+END DO !CONCURRENT
 !$acc end kernels
 !
-!$acc kernels async
-  ZA(:,:,IKTB+1:IKTE-1) =   ZRHODJ_DFDDTDZ_O_DZ2(:,:,IKTB+1:IKTE-1) * PIMPL
-  ZB(:,:,IKTB+1:IKTE-1) =   PRHODJ(:,:,IKTB+1:IKTE-1)/PTSTEP                        &
-                          - ZRHODJ_DFDDTDZ_O_DZ2(:,:,IKTB+1+KKL:IKTE-1+KKL) * PIMPL &
-                          - ZRHODJ_DFDDTDZ_O_DZ2(:,:,IKTB+1:IKTE-1) * PIMPL
-  ZC(:,:,IKTB+1:IKTE-1) =   ZRHODJ_DFDDTDZ_O_DZ2(:,:,IKTB+1+KKL:IKTE-1+KKL) * PIMPL
+!$acc kernels ! async
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=IKTB+1:IKTE-1)
+  ZA(JI,JJ,JK) =   ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,JK) * PIMPL
+  ZB(JI,JJ,JK) =   PRHODJ(JI,JJ,JK)/PTSTEP                        &
+                          - ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,JK+KKL) * PIMPL &
+                          - ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,JK) * PIMPL
+  ZC(JI,JJ,JK) =   ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,JK+KKL) * PIMPL
+END DO !CONCURRENT
 !$acc end kernels
 !
-!$acc kernels async
-  ZA(:,:,IKE) =   ZRHODJ_DFDDTDZ_O_DZ2(:,:,IKE  ) * PIMPL
-  ZB(:,:,IKE) =   PRHODJ(:,:,IKE)/PTSTEP                   &
-                - ZRHODJ_DFDDTDZ_O_DZ2(:,:,IKE  ) * PIMPL
+!$acc kernels ! async
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+  ZA(JI,JJ,IKE) =   ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,IKE  ) * PIMPL
+  ZB(JI,JJ,IKE) =   PRHODJ(JI,JJ,IKE)/PTSTEP                   &
+                - ZRHODJ_DFDDTDZ_O_DZ2(JI,JJ,IKE  ) * PIMPL
+END DO !CONCURRENT
 !$acc end kernels
 !
-!$acc wait
+! acc wait
 !
 !
 !*       3.2 going up
 !            --------
 !
 !$acc kernels
-  ZBET(:,:) = ZB(:,:,IKB)  ! bet = b(ikb)
-  PVARP(:,:,IKB) = ZY(:,:,IKB) / ZBET(:,:)
-
-  !
-  DO JK = IKB+KKL,IKE-KKL,KKL
-!$acc loop collapse(2) independent
-    DO JJ=1,SIZE(ZGAM,2)
-      DO JI=1,SIZE(ZGAM,1)
-        ZGAM(JI,JJ,JK) = ZC(JI,JJ,JK-KKL) / ZBET(JI,JJ)  
-                                                    ! gam(k) = c(k-1) / bet
-        ZBET(JI,JJ)    = ZB(JI,JJ,JK) - ZA(JI,JJ,JK) * ZGAM(JI,JJ,JK)
-                                                    ! bet = b(k) - a(k)* gam(k)  
-        PVARP(JI,JJ,JK)= ( ZY(JI,JJ,JK) - ZA(JI,JJ,JK) * PVARP(JI,JJ,JK-KKL) ) / ZBET(JI,JJ)
-                                        ! res(k) = (y(k) -a(k)*res(k-1))/ bet 
-      END DO
-    END DO
-  END DO 
-  ! special treatment for the last level
-  DO JJ=1,SIZE(ZGAM,2)
-    DO JI=1,SIZE(ZGAM,1)
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+  ZBET(JI,JJ) = ZB(JI,JJ,IKB)  ! bet = b(ikb)
+  PVARP(JI,JJ,IKB) = ZY(JI,JJ,IKB) / ZBET(JI,JJ)
+END DO !CONCURRENT
+!
+!$acc loop seq
+DO JK = IKB+KKL,IKE-KKL,KKL
+   !$acc loop independent collapse(2)
+   ! acc loop gang, vector collapse(2)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+   !DO JJ=1,JJU
+   !   DO JI=1,JIU     
+      ZGAM(JI,JJ,JK) = ZC(JI,JJ,JK-KKL) / ZBET(JI,JJ)  
+      ! gam(k) = c(k-1) / bet
+      ZBET(JI,JJ)    = ZB(JI,JJ,JK) - ZA(JI,JJ,JK) * ZGAM(JI,JJ,JK)
+      ! bet = b(k) - a(k)* gam(k)  
+      PVARP(JI,JJ,JK)= ( ZY(JI,JJ,JK) - ZA(JI,JJ,JK) * PVARP(JI,JJ,JK-KKL) ) / ZBET(JI,JJ)
+      ! res(k) = (y(k) -a(k)*res(k-1))/ bet
+   !   END DO
+   !END DO
+   END DO !CONCURRENT 
+END DO
+! special treatment for the last level
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
       ZGAM(JI,JJ,IKE) = ZC(JI,JJ,IKE-KKL) / ZBET(JI,JJ) 
-                                                    ! gam(k) = c(k-1) / bet
+      ! gam(k) = c(k-1) / bet
       ZBET(JI,JJ)     = ZB(JI,JJ,IKE) - ZA(JI,JJ,IKE) * ZGAM(JI,JJ,IKE)
-                                                    ! bet = b(k) - a(k)* gam(k)  
+      ! bet = b(k) - a(k)* gam(k)  
       PVARP(JI,JJ,IKE)= ( ZY(JI,JJ,IKE) - ZA(JI,JJ,IKE) * PVARP(JI,JJ,IKE-KKL) ) / ZBET(JI,JJ)
-                                       ! res(k) = (y(k) -a(k)*res(k-1))/ bet 
-    END DO
-  END DO
+      ! res(k) = (y(k) -a(k)*res(k-1))/ bet 
+END DO !CONCURRENT
 !
 !*       3.3 going down
 !            ----------
 !
-  DO JK = IKE-KKL,IKB,-1*KKL
-    PVARP(:,:,JK) = PVARP(:,:,JK) - ZGAM(:,:,JK+KKL) * PVARP(:,:,JK+KKL)
-  END DO
+!$acc loop seq
+DO JK = IKE-KKL,IKB,-1*KKL
+   !$acc loop independent collapse(2)
+   ! acc loop gang, vector collapse(2)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+      PVARP(JI,JJ,JK) = PVARP(JI,JJ,JK) - ZGAM(JI,JJ,JK+KKL) * PVARP(JI,JJ,JK+KKL)
+   END DO !CONCURRENT
+END DO
 !$acc end kernels
 !
 ELSE
 ! 
 !$acc kernels
-  PVARP(:,:,IKTB:IKTE) = ZY(:,:,IKTB:IKTE) * PTSTEP / PRHODJ(:,:,IKTB:IKTE)
+!$acc loop independent collapse(3)   
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=IKTB:IKTE)   
+   PVARP(JI,JJ,JK) = ZY(JI,JJ,JK) * PTSTEP / PRHODJ(JI,JJ,JK)
+END DO !CONCURRENT
 !$acc end kernels
 !
 END IF 
@@ -374,8 +439,11 @@ END IF
 !            ----------------------------------------
 !
 !$acc kernels
-PVARP(:,:,KKA)=PVARP(:,:,IKB)
-PVARP(:,:,KKU)=PVARP(:,:,IKE)
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+   PVARP(JI,JJ,KKA)=PVARP(JI,JJ,IKB)
+   PVARP(JI,JJ,KKU)=PVARP(JI,JJ,IKE)
+END DO !CONCURRENT
 !$acc end kernels
 
 if ( mppdb_initialized ) then
@@ -385,6 +453,14 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate (zrhodj_dfddtdz_o_dz2,zmzm_rhodj,za,zb,zc,zy,zgam,zbet)
+#else
+CALL MNH_REL_ZT3D(IZRHODJ_DFDDTDZ_O_DZ2,IZMZM_RHODJ,IZA,IZB,IZC,IZY,IZGAM,&
+                  IZBET,iztmp1_device)
+CALL MNH_CHECK_OUT_ZT3D("TRIDIAG_THERMO")
+#endif
+
 !$acc end data
 
 !-------------------------------------------------------------------------------
diff --git a/src/MNH/tridiag_tke.f90 b/src/MNH/tridiag_tke.f90
index 9c9fb543957c150bcd05263d679b19adc4c318fa..516196038b1b51e932a07528317f72cadac6fa32 100644
--- a/src/MNH/tridiag_tke.f90
+++ b/src/MNH/tridiag_tke.f90
@@ -142,6 +142,11 @@ END MODULE MODI_TRIDIAG_TKE
 USE MODD_PARAMETERS
 USE MODE_MPPDB
 !
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D , MNH_ALLOCATE_ZT2D, &
+      MNH_CHECK_IN_ZT3D,MNH_CHECK_OUT_ZT3D
+#endif
+!
 IMPLICIT NONE
 !
 !
@@ -167,9 +172,13 @@ INTEGER             :: JI,JJ,JK      ! loop counters
 INTEGER             :: IKB,IKE       ! inner vertical limits
 INTEGER             :: IKT          ! array size in k direction
 INTEGER             :: IKTB,IKTE    ! start, end of k loops in physical domain
-REAL, DIMENSION(:,:,:), allocatable :: ZY ,ZGAM ! RHS of the equation, 3D work array
-REAL, DIMENSION(:,:),   allocatable :: ZBET     ! 2D work array
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZY ,ZGAM ! RHS of the equation, 3D work array
+REAL, DIMENSION(:,:),   pointer , contiguous :: ZBET     ! 2D work array
+#ifdef MNH_OPENACC
+INTEGER :: IZY ,IZGAM, IZBET
+#endif
 !
+INTEGER  :: JIU,JJU,JKU
 ! ---------------------------------------------------------------------------
 
 !$acc data present( PVARM, PA, PRHODJ, PSOURCE, PDIAG, PVARP )
@@ -183,11 +192,22 @@ if ( mppdb_initialized ) then
   call Mppdb_check( pdiag,   "Tridiag_tke beg:pdiag"   )
 end if
 
-allocate( zy  (size( pvarm, 1 ), size( pvarm, 2 ), size( pvarm, 3 ) ) )
-allocate( zgam(size( pvarm, 1 ), size( pvarm, 2 ), size( pvarm, 3 ) ) )
-allocate( zbet(size( pvarm, 1 ), size( pvarm, 2 ) ) )
+JIU =  size( pvarm, 1 )
+JJU =  size( pvarm, 2 )
+JKU =  size( pvarm, 3 )
+
+#ifndef MNH_OPENACC
+allocate( zy  (JIU,JJU,JKU ) )
+allocate( zgam(JIU,JJU,JKU ) )
+allocate( zbet(JIU,JJU ) )
+#else
+CALL MNH_CHECK_IN_ZT3D("TRIDIAG_TKE")
+izy   = MNH_ALLOCATE_ZT3D( zy  ,JIU,JJU,JKU )
+izgam = MNH_ALLOCATE_ZT3D( zgam,JIU,JJU,JKU )
+izbet = MNH_ALLOCATE_ZT2D( zbet,JIU,JJU )
+#endif
 
-!$acc data create( ZY, ZGAM, ZBET )
+!$acc data present( ZY, ZGAM, ZBET )
 
 !
 !*      1.  COMPUTE THE RIGHT HAND SIDE
@@ -202,20 +222,29 @@ IKE=KKU-JPVEXT_TURB*KKL
 
 !
 !
-ZY(:,:,IKB) = PVARM(:,:,IKB)  + PTSTEP*PSOURCE(:,:,IKB) -   &
-  PEXPL / PRHODJ(:,:,IKB) * PA(:,:,IKB+KKL) * (PVARM(:,:,IKB+KKL) - PVARM(:,:,IKB))
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+   ZY(JI,JJ,IKB) = PVARM(JI,JJ,IKB)  + PTSTEP*PSOURCE(JI,JJ,IKB) -   &
+        PEXPL / PRHODJ(JI,JJ,IKB) * PA(JI,JJ,IKB+KKL) * (PVARM(JI,JJ,IKB+KKL) - PVARM(JI,JJ,IKB))
+END DO !CONCURRENT
 !
 DO JK=IKTB+1,IKTE-1
-  ZY(:,:,JK)= PVARM(:,:,JK)  + PTSTEP*PSOURCE(:,:,JK) -               &
-      PEXPL / PRHODJ(:,:,JK) *                                           &
-                             ( PVARM(:,:,JK-KKL)*PA(:,:,JK)                &
-                              -PVARM(:,:,JK)*(PA(:,:,JK)+PA(:,:,JK+KKL))   &
-                              +PVARM(:,:,JK+KKL)*PA(:,:,JK+KKL)              &
-                             ) 
+   !$acc loop independent collapse(2)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+      ZY(JI,JJ,JK)= PVARM(JI,JJ,JK)  + PTSTEP*PSOURCE(JI,JJ,JK) -               &
+           PEXPL / PRHODJ(JI,JJ,JK) *                                           &
+           ( PVARM(JI,JJ,JK-KKL)*PA(JI,JJ,JK)                &
+           -PVARM(JI,JJ,JK)*(PA(JI,JJ,JK)+PA(JI,JJ,JK+KKL))   &
+           +PVARM(JI,JJ,JK+KKL)*PA(JI,JJ,JK+KKL)              &
+           )
+   END DO !CONCURRENT
 END DO
-! 
-ZY(:,:,IKE)= PVARM(:,:,IKE) + PTSTEP*PSOURCE(:,:,IKE) +               &
-  PEXPL / PRHODJ(:,:,IKE) * PA(:,:,IKE) * (PVARM(:,:,IKE)-PVARM(:,:,IKE-KKL))
+!
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+   ZY(JI,JJ,IKE)= PVARM(JI,JJ,IKE) + PTSTEP*PSOURCE(JI,JJ,IKE) +               &
+        PEXPL / PRHODJ(JI,JJ,IKE) * PA(JI,JJ,IKE) * (PVARM(JI,JJ,IKE)-PVARM(JI,JJ,IKE-KKL))
+END DO !CONCURRENT
 !
 !
 !*       2.  INVERSION OF THE TRIDIAGONAL SYSTEM
@@ -225,15 +254,19 @@ IF ( PIMPL > 1.E-10 ) THEN
 !
   !
   !  going up
+   !
+  !$acc loop independent collapse(2)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU) 
+     ZBET(JI,JJ) = 1. + PIMPL * (PDIAG(JI,JJ,IKB)-PA(JI,JJ,IKB+KKL) / PRHODJ(JI,JJ,IKB))
+     ! bet = b(ikb)
+     PVARP(JI,JJ,IKB) = ZY(JI,JJ,IKB) / ZBET(JI,JJ)
+  END DO !CONCURRENT
   !
-  ZBET(:,:) = 1. + PIMPL * (PDIAG(:,:,IKB)-PA(:,:,IKB+KKL) / PRHODJ(:,:,IKB))
-                                                    ! bet = b(ikb)
-  PVARP(:,:,IKB) = ZY(:,:,IKB) / ZBET(:,:)                
-  !
+  !$acc loop  seq
   DO JK = IKB+KKL,IKE-KKL,KKL
-!$acc loop collapse(2) independent
-    DO JJ=1,SIZE(ZGAM,2)
-      DO JI=1,SIZE(ZGAM,1)
+   !$acc loop gang, vector collapse(2) independent
+    DO JJ=1,JJU
+      DO JI=1,JIU
         ZGAM(JI,JJ,JK) = PIMPL * PA(JI,JJ,JK) / PRHODJ(JI,JJ,JK-KKL) / ZBET(JI,JJ)  
                                                     ! gam(k) = c(k-1) / bet
         ZBET(JI,JJ)    = 1. + PIMPL * ( PDIAG(JI,JJ,JK) -                 &
@@ -249,26 +282,36 @@ IF ( PIMPL > 1.E-10 ) THEN
     END DO
   END DO 
   ! special treatment for the last level
-  ZGAM(:,:,IKE) = PIMPL * PA(:,:,IKE) / PRHODJ(:,:,IKE-KKL) / ZBET(:,:) 
-                                                    ! gam(k) = c(k-1) / bet
-  ZBET(:,:)    = 1. + PIMPL * ( PDIAG(:,:,IKE) -                   &
-         (  PA(:,:,IKE) * (1. + ZGAM(:,:,IKE)) ) / PRHODJ(:,:,IKE) &
-                              )  
-                                                    ! bet = b(k) - a(k)* gam(k)  
-  PVARP(:,:,IKE)= ( ZY(:,:,IKE) - PIMPL * PA(:,:,IKE) / PRHODJ(:,:,IKE) &
-                                * PVARP(:,:,IKE-KKL)                      &
-                 ) / ZBET(:,:)
-                                       ! res(k) = (y(k) -a(k)*res(k-1))/ bet 
+  !$acc loop independent collapse(2)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+     ZGAM(JI,JJ,IKE) = PIMPL * PA(JI,JJ,IKE) / PRHODJ(JI,JJ,IKE-KKL) / ZBET(JI,JJ) 
+     ! gam(k) = c(k-1) / bet
+     ZBET(JI,JJ)    = 1. + PIMPL * ( PDIAG(JI,JJ,IKE) -                   &
+          (  PA(JI,JJ,IKE) * (1. + ZGAM(JI,JJ,IKE)) ) / PRHODJ(JI,JJ,IKE) &
+          )  
+     ! bet = b(k) - a(k)* gam(k)  
+     PVARP(JI,JJ,IKE)= ( ZY(JI,JJ,IKE) - PIMPL * PA(JI,JJ,IKE) / PRHODJ(JI,JJ,IKE) &
+          * PVARP(JI,JJ,IKE-KKL)                      &
+          ) / ZBET(JI,JJ)
+     ! res(k) = (y(k) -a(k)*res(k-1))/ bet
+  END DO !CONCURRENT
   !
   !  going down
   !
+  !$acc loop seq
   DO JK = IKE-KKL,IKB,-1*KKL
-    PVARP(:,:,JK) = PVARP(:,:,JK) - ZGAM(:,:,JK+KKL) * PVARP(:,:,JK+KKL) 
+     !$acc loop gang, vector collapse(2)
+     DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+        PVARP(JI,JJ,JK) = PVARP(JI,JJ,JK) - ZGAM(JI,JJ,JK+KKL) * PVARP(JI,JJ,JK+KKL)
+     END DO !CONCURRENT   
   END DO
 !
 ELSE
-! 
-  PVARP(:,:,IKTB:IKTE) = ZY(:,:,IKTB:IKTE)
+  !
+  !$acc loop independent collapse(2)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU) 
+     PVARP(JI,JJ,IKTB:IKTE) = ZY(JI,JJ,IKTB:IKTE)
+  END DO !CONCURRENT   
 !
 END IF 
 !
@@ -276,8 +319,11 @@ END IF
 !*       3.  FILL THE UPPER AND LOWER EXTERNAL VALUES
 !            ----------------------------------------
 !
-PVARP(:,:,KKA)=PVARP(:,:,IKB)
-PVARP(:,:,KKU)=PVARP(:,:,IKE)
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+   PVARP(JI,JJ,KKA)=PVARP(JI,JJ,IKB)
+   PVARP(JI,JJ,KKU)=PVARP(JI,JJ,IKE)
+END DO !CONCURRENT
 !$acc end kernels
 
 if ( mppdb_initialized ) then
@@ -287,6 +333,13 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate( ZY, ZGAM, ZBET )
+#else
+CALL MNH_REL_ZT3D( IZY, IZGAM, IZBET )
+CALL MNH_CHECK_OUT_ZT3D("TRIDIAG_TKE")
+#endif
+
 !$acc end data
 
 !-------------------------------------------------------------------------------
diff --git a/src/MNH/tridiag_w.f90 b/src/MNH/tridiag_w.f90
index 74d7775d5a4cad97fd039d7fde96f85575ee4f0b..5a62150367d5d5db1ae4195f3977aef71b9319b9 100644
--- a/src/MNH/tridiag_w.f90
+++ b/src/MNH/tridiag_w.f90
@@ -161,6 +161,10 @@ USE MODI_SHUMAN_DEVICE
 USE MODI_BITREP
 #endif
 !
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D , MNH_ALLOCATE_ZT2D
+#endif
+!
 IMPLICIT NONE
 !
 !
@@ -177,15 +181,20 @@ REAL, DIMENSION(:,:,:), INTENT(OUT):: PVARP   ! variable at t+1      at flux poi
 !
 !*       0.2 declarations of local variables
 !
-REAL, DIMENSION(:,:,:), allocatable :: ZRHODJ_DFDDWDZ_O_DZ2
-REAL, DIMENSION(:,:,:), allocatable :: ZMZM_RHODJ
-REAL, DIMENSION(:,:,:), allocatable :: ZA, ZB, ZC
-REAL, DIMENSION(:,:,:), allocatable :: ZY ,ZGAM ! RHS of the equation, 3D work array
-REAL, DIMENSION(:,:),   allocatable :: ZBET     ! 2D work array
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZRHODJ_DFDDWDZ_O_DZ2
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZMZM_RHODJ
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZA, ZB, ZC
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZY ,ZGAM ! RHS of the equation, 3D work array
+REAL, DIMENSION(:,:),   pointer , contiguous :: ZBET     ! 2D work array
+#ifdef MNH_OPENACC
+INTEGER :: IZRHODJ_DFDDWDZ_O_DZ2,IZMZM_RHODJ,IZA, IZB, IZC,IZY ,IZGAM,IZBET
+#endif
 !
 INTEGER                              :: JK            ! loop counter
 INTEGER                              :: IKB,IKE       ! inner vertical limits
 !
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ
 ! ---------------------------------------------------------------------------
 
 !$acc data present( PVARM, PF, PDFDDWDZ, PMZF_DZZ, PRHODJ, PVARP )
@@ -199,16 +208,31 @@ if ( mppdb_initialized ) then
   call Mppdb_check( prhodj,   "Tridiag_w beg:prhodj"   )
 end if
 
-allocate( zrhodj_dfddwdz_o_dz2(size( pvarm, 1 ), size( pvarm, 2 ), size( pvarm, 3 ) ) )
-allocate( zmzm_rhodj          (size( pvarm, 1 ), size( pvarm, 2 ), size( pvarm, 3 ) ) )
-allocate( za                  (size( pvarm, 1 ), size( pvarm, 2 ), size( pvarm, 3 ) ) )
-allocate( zb                  (size( pvarm, 1 ), size( pvarm, 2 ), size( pvarm, 3 ) ) )
-allocate( zc                  (size( pvarm, 1 ), size( pvarm, 2 ), size( pvarm, 3 ) ) )
-allocate( zy                  (size( pvarm, 1 ), size( pvarm, 2 ), size( pvarm, 3 ) ) )
-allocate( zgam                (size( pvarm, 1 ), size( pvarm, 2 ), size( pvarm, 3 ) ) )
-allocate( zbet                (size( pvarm, 1 ), size( pvarm, 2 ) ) )
+JIU =  size( pvarm, 1 )
+JJU =  size( pvarm, 2 )
+JKU =  size( pvarm, 3 )
+
+#ifndef MNH_OPENACC
+allocate( zrhodj_dfddwdz_o_dz2(JIU,JJU,JKU ) )
+allocate( zmzm_rhodj          (JIU,JJU,JKU ) )
+allocate( za                  (JIU,JJU,JKU ) )
+allocate( zb                  (JIU,JJU,JKU ) )
+allocate( zc                  (JIU,JJU,JKU ) )
+allocate( zy                  (JIU,JJU,JKU ) )
+allocate( zgam                (JIU,JJU,JKU ) )
+allocate( zbet                (JIU,JJU ) )
+#else
+izrhodj_dfddwdz_o_dz2 = MNH_ALLOCATE_ZT3D( zrhodj_dfddwdz_o_dz2,JIU,JJU,JKU )
+izmzm_rhodj           = MNH_ALLOCATE_ZT3D( zmzm_rhodj          ,JIU,JJU,JKU )
+iza                   = MNH_ALLOCATE_ZT3D( za                  ,JIU,JJU,JKU )
+izb                   = MNH_ALLOCATE_ZT3D( zb                  ,JIU,JJU,JKU )
+izc                   = MNH_ALLOCATE_ZT3D( zc                  ,JIU,JJU,JKU )
+izy                   = MNH_ALLOCATE_ZT3D( zy                  ,JIU,JJU,JKU )
+izgam                 = MNH_ALLOCATE_ZT3D( zgam                ,JIU,JJU,JKU )
+izbet                 = MNH_ALLOCATE_ZT2D( zbet                ,JIU,JJU )
+#endif 
 
-!$acc data create( ZRHODJ_DFDDWDZ_O_DZ2, ZMZM_RHODJ, ZA, ZB, ZC, ZY, ZGAM, ZBET )
+!$acc data present( ZRHODJ_DFDDWDZ_O_DZ2, ZMZM_RHODJ, ZA, ZB, ZC, ZY, ZGAM, ZBET )
 
 !
 !*      1.  Preliminaries
@@ -222,22 +246,24 @@ ZMZM_RHODJ  = MZM(PRHODJ)
 #else
 CALL MZM_DEVICE(PRHODJ,ZMZM_RHODJ)
 #endif
-!$acc kernels async 
+!$acc kernels ! async 
 #ifndef MNH_BITREP
 ZRHODJ_DFDDWDZ_O_DZ2 = PRHODJ*PDFDDWDZ/PMZF_DZZ**2
 #else
-ZRHODJ_DFDDWDZ_O_DZ2 = PRHODJ*PDFDDWDZ/BR_P2(PMZF_DZZ)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZRHODJ_DFDDWDZ_O_DZ2(JI,JJ,JK) = PRHODJ(JI,JJ,JK)*PDFDDWDZ(JI,JJ,JK)/BR_P2(PMZF_DZZ(JI,JJ,JK))
+END DO !CONCURRENT   
 #endif
 !$acc end kernels
 !
-!$acc kernels async
+!$acc kernels ! async
 ZA=0.
 ZB=0.
 ZC=0.
 ZY=0.
 !$acc end kernels
 !
-!$acc wait
+! acc wait
 !
 !
 !*      2.  COMPUTE THE RIGHT HAND SIDE
@@ -258,31 +284,40 @@ ZY=0.
 !!        + PRHODJ(k-1) * PDFDDWDZ(k-1) * PVARM(k-1)/BR_P2(PMZF_DZZ(k-1))
 !!#endif
 !
-!$acc kernels async
-ZY(:,:,IKB) = ZMZM_RHODJ(:,:,IKB)*PVARM(:,:,IKB)/PTSTEP              &
-    - PRHODJ(:,:,IKB  ) * PF(:,:,IKB  )/PMZF_DZZ(:,:,IKB  )           &
-    + PRHODJ(:,:,IKB-1) * PF(:,:,IKB-1)/PMZF_DZZ(:,:,IKB-1)           &
-    + ZRHODJ_DFDDWDZ_O_DZ2(:,:,IKB) * PVARM(:,:,IKB+1)&
-    - ZRHODJ_DFDDWDZ_O_DZ2(:,:,IKB) * PVARM(:,:,IKB  )
+!$acc kernels ! async
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+   ZY(JI,JJ,IKB) = ZMZM_RHODJ(JI,JJ,IKB)*PVARM(JI,JJ,IKB)/PTSTEP              &
+        - PRHODJ(JI,JJ,IKB  ) * PF(JI,JJ,IKB  )/PMZF_DZZ(JI,JJ,IKB  )           &
+        + PRHODJ(JI,JJ,IKB-1) * PF(JI,JJ,IKB-1)/PMZF_DZZ(JI,JJ,IKB-1)           &
+        + ZRHODJ_DFDDWDZ_O_DZ2(JI,JJ,IKB) * PVARM(JI,JJ,IKB+1)&
+        - ZRHODJ_DFDDWDZ_O_DZ2(JI,JJ,IKB) * PVARM(JI,JJ,IKB  )
+END DO !CONCURRENT
 !$acc end kernels
 !
-!$acc kernels async
-  ZY(:,:,IKB+1:IKE-1) = ZMZM_RHODJ(:,:,IKB+1:IKE-1)*PVARM(:,:,IKB+1:IKE-1)/PTSTEP               &
-    - PRHODJ(:,:,IKB+1:IKE-1  ) * PF(:,:,IKB+1:IKE-1  )/PMZF_DZZ(:,:,IKB+1:IKE-1  )              &
-    + PRHODJ(:,:,IKB:IKE-2) * PF(:,:,IKB:IKE-2)/PMZF_DZZ(:,:,IKB:IKE-2)              &
-    + ZRHODJ_DFDDWDZ_O_DZ2(:,:,IKB+1:IKE-1  ) * PVARM(:,:,IKB+2:IKE)  &
-    - ZRHODJ_DFDDWDZ_O_DZ2(:,:,IKB+1:IKE-1  ) * PVARM(:,:,IKB+1:IKE-1  )  &
-    - ZRHODJ_DFDDWDZ_O_DZ2(:,:,IKB:IKE-2) * PVARM(:,:,IKB+1:IKE-1  )  &
-    + ZRHODJ_DFDDWDZ_O_DZ2(:,:,IKB:IKE-2) * PVARM(:,:,IKB:IKE-2)
+!$acc kernels ! async
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=IKB+1:IKE-1)
+  ZY(JI,JJ,JK) = ZMZM_RHODJ(JI,JJ,JK)*PVARM(JI,JJ,JK)/PTSTEP               &
+       - PRHODJ(JI,JJ,JK  ) * PF(JI,JJ,JK  )/PMZF_DZZ(JI,JJ,JK  )          &
+       + PRHODJ(JI,JJ,JK-1) * PF(JI,JJ,JK-1)/PMZF_DZZ(JI,JJ,JK-1)              &
+       + ZRHODJ_DFDDWDZ_O_DZ2(JI,JJ,JK  ) * PVARM(JI,JJ,JK+1)  &
+       - ZRHODJ_DFDDWDZ_O_DZ2(JI,JJ,JK  ) * PVARM(JI,JJ,JK  )  &
+       - ZRHODJ_DFDDWDZ_O_DZ2(JI,JJ,JK-1) * PVARM(JI,JJ,JK  )  &
+       + ZRHODJ_DFDDWDZ_O_DZ2(JI,JJ,JK-1) * PVARM(JI,JJ,JK-1)
+END DO !CONCURRENT  
 !$acc end kernels
 ! 
-!$acc kernels async
-ZY(:,:,IKE) = ZMZM_RHODJ(:,:,IKE)*PVARM(:,:,IKE)/PTSTEP              &
-    - PRHODJ(:,:,IKE  ) * PF(:,:,IKE  )/PMZF_DZZ(:,:,IKE  )           &
-    + PRHODJ(:,:,IKE-1) * PF(:,:,IKE-1)/PMZF_DZZ(:,:,IKE-1)           &
-    - ZRHODJ_DFDDWDZ_O_DZ2(:,:,IKE  ) * PVARM(:,:,IKE )  &
-    - ZRHODJ_DFDDWDZ_O_DZ2(:,:,IKE-1) * PVARM(:,:,IKE  ) &
-    + ZRHODJ_DFDDWDZ_O_DZ2(:,:,IKE-1) * PVARM(:,:,IKE-1)
+!$acc kernels ! async
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+   ZY(JI,JJ,IKE) = ZMZM_RHODJ(JI,JJ,IKE)*PVARM(JI,JJ,IKE)/PTSTEP              &
+        - PRHODJ(JI,JJ,IKE  ) * PF(JI,JJ,IKE  )/PMZF_DZZ(JI,JJ,IKE  )           &
+        + PRHODJ(JI,JJ,IKE-1) * PF(JI,JJ,IKE-1)/PMZF_DZZ(JI,JJ,IKE-1)           &
+        - ZRHODJ_DFDDWDZ_O_DZ2(JI,JJ,IKE  ) * PVARM(JI,JJ,IKE )  &
+        - ZRHODJ_DFDDWDZ_O_DZ2(JI,JJ,IKE-1) * PVARM(JI,JJ,IKE  ) &
+        + ZRHODJ_DFDDWDZ_O_DZ2(JI,JJ,IKE-1) * PVARM(JI,JJ,IKE-1)
+END DO !CONCURRENT
 !$acc end kernels
 !
 !*       3.  INVERSION OF THE TRIDIAGONAL SYSTEM
@@ -298,71 +333,101 @@ ZY(:,:,IKE) = ZMZM_RHODJ(:,:,IKE)*PVARM(:,:,IKE)/PTSTEP              &
 !!        - PRHODJ(k-1) * PDFDDWDZ(k-1)/PMZF_DZZ(k-1)**2
 !! c(k) = + PRHODJ(k)   * PDFDDWDZ(k)/PMZF_DZZ(k)**2
 !
-!$acc kernels async
-  ZB(:,:,IKB) =   ZMZM_RHODJ(:,:,IKB)/PTSTEP      &
-                - ZRHODJ_DFDDWDZ_O_DZ2(:,:,IKB)
+!$acc kernels ! async
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+  ZB(JI,JJ,IKB) =   ZMZM_RHODJ(JI,JJ,IKB)/PTSTEP      &
+       - ZRHODJ_DFDDWDZ_O_DZ2(JI,JJ,IKB)
+END DO !CONCURRENT  
 !$acc end kernels
-!$acc kernels async
-  ZC(:,:,IKB) =   ZRHODJ_DFDDWDZ_O_DZ2(:,:,IKB)
+!$acc kernels ! async
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+   ZC(JI,JJ,IKB) =   ZRHODJ_DFDDWDZ_O_DZ2(JI,JJ,IKB)
+END DO !CONCURRENT   
 !$acc end kernels
 
-!$acc kernels async
-    ZA(:,:,IKB+1:IKE-1) =   ZRHODJ_DFDDWDZ_O_DZ2(:,:,IKB:IKE-2)
-    ZB(:,:,IKB+1:IKE-1) =   ZMZM_RHODJ(:,:,IKB+1:IKE-1)/PTSTEP      &
-                 - ZRHODJ_DFDDWDZ_O_DZ2(:,:,IKB+1:IKE-1  ) &
-                 - ZRHODJ_DFDDWDZ_O_DZ2(:,:,IKB:IKE-2)
-    ZC(:,:,IKB+1:IKE-1) =   ZRHODJ_DFDDWDZ_O_DZ2(:,:,IKB+1:IKE-1  )
+!$acc kernels ! async
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=IKB+1:IKE-1)
+    ZA(JI,JJ,JK) =   ZRHODJ_DFDDWDZ_O_DZ2(JI,JJ,JK-1)
+    ZB(JI,JJ,JK) =   ZMZM_RHODJ(JI,JJ,JK)/PTSTEP      &
+                 - ZRHODJ_DFDDWDZ_O_DZ2(JI,JJ,JK  ) &
+                 - ZRHODJ_DFDDWDZ_O_DZ2(JI,JJ,JK-1)
+    ZC(JI,JJ,JK) =   ZRHODJ_DFDDWDZ_O_DZ2(JI,JJ,JK  )
+END DO !CONCURRENT    
 !$acc end kernels
 
-!$acc kernels async
-  ZA(:,:,IKE) =   ZRHODJ_DFDDWDZ_O_DZ2(:,:,IKE-1)
+!$acc kernels ! async
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+   ZA(JI,JJ,IKE) =   ZRHODJ_DFDDWDZ_O_DZ2(JI,JJ,IKE-1)
+END DO !CONCURRENT   
 !$acc end kernels
-!$acc kernels async
-  ZB(:,:,IKE) =   ZMZM_RHODJ(:,:,IKE)/PTSTEP      &
-                - ZRHODJ_DFDDWDZ_O_DZ2(:,:,IKE  ) &
-                - ZRHODJ_DFDDWDZ_O_DZ2(:,:,IKE-1)
+!$acc kernels ! async
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+  ZB(JI,JJ,IKE) =   ZMZM_RHODJ(JI,JJ,IKE)/PTSTEP      &
+                - ZRHODJ_DFDDWDZ_O_DZ2(JI,JJ,IKE  ) &
+                - ZRHODJ_DFDDWDZ_O_DZ2(JI,JJ,IKE-1)
+END DO !CONCURRENT  
 !$acc end kernels
 !
 !
-!$acc wait
+! acc wait
 !
 !*       3.2 going up
 !            --------
 !
 !$acc kernels
-  ZBET(:,:) = ZB(:,:,IKB)  ! bet = b(ikb)
-  PVARP(:,:,IKB) = ZY(:,:,IKB) / ZBET(:,:)
-
-  !
-  DO JK = IKB+1,IKE-1
-    ZGAM(:,:,JK) = ZC(:,:,JK-1) / ZBET(:,:)  
-                                                    ! gam(k) = c(k-1) / bet
-    ZBET(:,:)    = ZB(:,:,JK) - ZA(:,:,JK) * ZGAM(:,:,JK)
-                                                    ! bet = b(k) - a(k)* gam(k)  
-    PVARP(:,:,JK)= ( ZY(:,:,JK) - ZA(:,:,JK) * PVARP(:,:,JK-1) ) / ZBET(:,:)
-                                        ! res(k) = (y(k) -a(k)*res(k-1))/ bet 
-  END DO 
-  ! special treatment for the last level
-  ZGAM(:,:,IKE) = ZC(:,:,IKE-1) / ZBET(:,:) 
-                                                    ! gam(k) = c(k-1) / bet
-  ZBET(:,:)     = ZB(:,:,IKE) - ZA(:,:,IKE) * ZGAM(:,:,IKE)
-                                                    ! bet = b(k) - a(k)* gam(k)  
-  PVARP(:,:,IKE)= ( ZY(:,:,IKE) - ZA(:,:,IKE) * PVARP(:,:,IKE-1) ) / ZBET(:,:)
-                                       ! res(k) = (y(k) -a(k)*res(k-1))/ bet 
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+  ZBET(JI,JJ) = ZB(JI,JJ,IKB)  ! bet = b(ikb)
+  PVARP(JI,JJ,IKB) = ZY(JI,JJ,IKB) / ZBET(JI,JJ)
+END DO !CONCURRENT
+!
+!$acc loop seq
+DO JK = IKB+1,IKE-1
+   !$acc loop independent collapse(2)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+      ZGAM(JI,JJ,JK) = ZC(JI,JJ,JK-1) / ZBET(JI,JJ)  
+      ! gam(k) = c(k-1) / bet
+      ZBET(JI,JJ)    = ZB(JI,JJ,JK) - ZA(JI,JJ,JK) * ZGAM(JI,JJ,JK)
+      ! bet = b(k) - a(k)* gam(k)  
+      PVARP(JI,JJ,JK)= ( ZY(JI,JJ,JK) - ZA(JI,JJ,JK) * PVARP(JI,JJ,JK-1) ) / ZBET(JI,JJ)
+      ! res(k) = (y(k) -a(k)*res(k-1))/ bet
+   END DO !CONCURRENT
+END DO
+! special treatment for the last level
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+   ZGAM(JI,JJ,IKE) = ZC(JI,JJ,IKE-1) / ZBET(JI,JJ) 
+   ! gam(k) = c(k-1) / bet
+   ZBET(JI,JJ)     = ZB(JI,JJ,IKE) - ZA(JI,JJ,IKE) * ZGAM(JI,JJ,IKE)
+   ! bet = b(k) - a(k)* gam(k)  
+   PVARP(JI,JJ,IKE)= ( ZY(JI,JJ,IKE) - ZA(JI,JJ,IKE) * PVARP(JI,JJ,IKE-1) ) / ZBET(JI,JJ)
+   ! res(k) = (y(k) -a(k)*res(k-1))/ bet
+END DO !CONCURRENT  
 !
 !*       3.3 going down
 !            ----------
 !
-  DO JK = IKE-1,IKB,-1
-    PVARP(:,:,JK) = PVARP(:,:,JK) - ZGAM(:,:,JK+1) * PVARP(:,:,JK+1)
-  END DO
+!$acc loop seq
+DO JK = IKE-1,IKB,-1
+   !$acc loop independent collapse(2)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+      PVARP(JI,JJ,JK) = PVARP(JI,JJ,JK) - ZGAM(JI,JJ,JK+1) * PVARP(JI,JJ,JK+1)
+   END DO !CONCURRENT   
+END DO
 !
 !
 !*       4.  FILL THE UPPER AND LOWER EXTERNAL VALUES
 !            ----------------------------------------
 !
-PVARP(:,:,IKB-1)=PVARP(:,:,IKB)
-PVARP(:,:,IKE+1)=0.
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+   PVARP(JI,JJ,IKB-1)=PVARP(JI,JJ,IKB)
+   PVARP(JI,JJ,IKE+1)=0.
+END DO !CONCURRENT
 !$acc end kernels
 
 if ( mppdb_initialized ) then
@@ -372,6 +437,13 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate (ZRHODJ_DFDDWDZ_O_DZ2, ZMZM_RHODJ, ZA, ZB, ZC, ZY, ZGAM, ZBET)
+#else
+CALL MNH_REL_ZT3D(IZRHODJ_DFDDWDZ_O_DZ2, IZMZM_RHODJ, IZA, IZB, IZC, IZY, IZGAM, IZBET)
+#endif
+
+
 !$acc end data
 
 !-------------------------------------------------------------------------------
diff --git a/src/MNH/tridiag_wind.f90 b/src/MNH/tridiag_wind.f90
index b7819835b38b0caf679e27ab10b1e7f32bba5c09..e0f6a1e417f7f3917388eec58d4dac7a2d8d45dc 100644
--- a/src/MNH/tridiag_wind.f90
+++ b/src/MNH/tridiag_wind.f90
@@ -32,7 +32,6 @@ END INTERFACE
 END MODULE MODI_TRIDIAG_WIND
 !
 !
-!
 !      #############################################################
        SUBROUTINE TRIDIAG_WIND(KKA,KKU,KKL,PVARM,PA,PCOEFS,PTSTEP,PEXPL,PIMPL, &
                                              PRHODJA,PSOURCE,PVARP )
@@ -149,6 +148,11 @@ USE MODD_PARAMETERS
 
 use mode_mppdb
 
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D , MNH_ALLOCATE_ZT2D, &
+     MNH_CHECK_IN_ZT3D,MNH_CHECK_OUT_ZT3D
+#endif
+
 IMPLICIT NONE
 !
 !
@@ -174,8 +178,13 @@ INTEGER             :: JI,JJ,JK      ! loop counters
 INTEGER             :: IKB,IKE       ! inner vertical limits
 INTEGER             :: IKT          ! array size in k direction
 INTEGER             :: IKTB,IKTE    ! start, end of k loops in physical domain
-REAL, DIMENSION(:,:,:), allocatable :: ZY ,ZGAM ! RHS of the equation, 3D work array
-REAL, DIMENSION(:,:),   allocatable :: ZBET     ! 2D work array
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZY ,ZGAM ! RHS of the equation, 3D work array
+REAL, DIMENSION(:,:),   pointer , contiguous :: ZBET     ! 2D work array
+#ifdef MNH_OPENACC
+INTEGER :: IZY ,IZGAM, IZBET
+#endif
+!
+INTEGER  :: JIU,JJU,JKU
 !
 ! ---------------------------------------------------------------------------
 
@@ -190,11 +199,22 @@ if ( mppdb_initialized ) then
   call Mppdb_check( psource, "Tridiag_wind beg:psource" )
 end if
 
-allocate( zy  (size( pvarm, 1 ), size( pvarm, 2 ), size( pvarm, 3 ) ) )
-allocate( zgam(size( pvarm, 1 ), size( pvarm, 2 ), size( pvarm, 3 ) ) )
-allocate( zbet(size( pvarm, 1 ), size( pvarm, 2 ) ) )
+JIU =  size( pvarm, 1 )
+JJU =  size( pvarm, 2 )
+JKU =  size( pvarm, 3 )
+
+#ifndef MNH_OPENACC
+allocate( zy  (JIU,JJU,JKU ) )
+allocate( zgam(JIU,JJU,JKU ) )
+allocate( zbet(JIU,JJU ) )
+#else
+CALL MNH_CHECK_IN_ZT3D("TRIDIAG_WIND")
+izy   = MNH_ALLOCATE_ZT3D( zy  ,JIU,JJU,JKU )
+izgam = MNH_ALLOCATE_ZT3D( zgam,JIU,JJU,JKU )
+izbet = MNH_ALLOCATE_ZT2D( zbet,JIU,JJU )
+#endif
 
-!$acc data create( ZY, ZGAM, ZBET )
+!$acc data present( ZY, ZGAM, ZBET )
 
 !
 !*      1.  COMPUTE THE RIGHT HAND SIDE
@@ -208,26 +228,32 @@ IKE=KKU-JPVEXT_TURB*KKL
 
 !
 ! 
-!$acc kernels async
-ZY(:,:,IKB) = PVARM(:,:,IKB)  + PTSTEP*PSOURCE(:,:,IKB) -   &
-  PEXPL / PRHODJA(:,:,IKB) * PA(:,:,IKB+KKL) * (PVARM(:,:,IKB+KKL) - PVARM(:,:,IKB))
+!$acc kernels ! async
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+ZY(JI,JJ,IKB) = PVARM(JI,JJ,IKB)  + PTSTEP*PSOURCE(JI,JJ,IKB) -   &
+     PEXPL / PRHODJA(JI,JJ,IKB) * PA(JI,JJ,IKB+KKL) * (PVARM(JI,JJ,IKB+KKL) - PVARM(JI,JJ,IKB))
+END DO !CONCURRENT
 !$acc end kernels
 !
-!$acc kernels async
-  ZY(:,:,IKTB+1:IKTE-1)= PVARM(:,:,IKTB+1:IKTE-1)  + PTSTEP*PSOURCE(:,:,IKTB+1:IKTE-1) -               &
-      PEXPL / PRHODJA(:,:,IKTB+1:IKTE-1) *                                          &
-                             ( PVARM(:,:,IKTB+1-KKL:IKTE-1-KKL)*PA(:,:,IKTB+1:IKTE-1)                &
-                              -PVARM(:,:,IKTB+1:IKTE-1)*(PA(:,:,IKTB+1:IKTE-1)+PA(:,:,IKTB+1+KKL:IKTE-1+KKL))   &
-                              +PVARM(:,:,IKTB+1+KKL:IKTE-1+KKL)*PA(:,:,IKTB+1+KKL:IKTE-1+KKL)              &
-                             ) 
+!$acc kernels ! async
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=IKTB+1:IKTE-1)
+  ZY(JI,JJ,JK)= PVARM(JI,JJ,JK)  + PTSTEP*PSOURCE(JI,JJ,JK) -               &
+      PEXPL / PRHODJA(JI,JJ,JK) *                                          &
+                             ( PVARM(JI,JJ,JK-KKL)*PA(JI,JJ,JK)                &
+                              -PVARM(JI,JJ,JK)*(PA(JI,JJ,JK)+PA(JI,JJ,JK+KKL))   &
+                              +PVARM(JI,JJ,JK+KKL)*PA(JI,JJ,JK+KKL)              &
+                              )
+END DO !CONCURRENT  
 !$acc end kernels
 ! 
-!$acc kernels async
-ZY(:,:,IKE)= PVARM(:,:,IKE) + PTSTEP*PSOURCE(:,:,IKE) +               &
-  PEXPL / PRHODJA(:,:,IKE) * PA(:,:,IKE) * (PVARM(:,:,IKE)-PVARM(:,:,IKE-KKL))
+!$acc kernels ! async
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+ZY(JI,JJ,IKE)= PVARM(JI,JJ,IKE) + PTSTEP*PSOURCE(JI,JJ,IKE) +               &
+     PEXPL / PRHODJA(JI,JJ,IKE) * PA(JI,JJ,IKE) * (PVARM(JI,JJ,IKE)-PVARM(JI,JJ,IKE-KKL))
+END DO !CONCURRENT
 !$acc end kernels
 !
-!$acc wait
+! acc wait
 !
 !
 !*       2.  INVERSION OF THE TRIDIAGONAL SYSTEM
@@ -238,50 +264,61 @@ IF ( PIMPL > 1.E-10 ) THEN
   !
   !  going up
   !
-!$acc kernels
-  ZBET(:,:) = 1. - PIMPL * (  PA(:,:,IKB+KKL) / PRHODJA(:,:,IKB) &  
-                            + PCOEFS(:,:) *  PTSTEP        )   ! bet = b(ikb)
-  PVARP(:,:,IKB) = ZY(:,:,IKB) / ZBET(:,:)                
+   !$acc kernels
+   !$acc loop independent collapse(2)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+      ZBET(JI,JJ) = 1. - PIMPL * (  PA(JI,JJ,IKB+KKL) / PRHODJA(JI,JJ,IKB) &  
+           + PCOEFS(JI,JJ) *  PTSTEP        )   ! bet = b(ikb)
+      PVARP(JI,JJ,IKB) = ZY(JI,JJ,IKB) / ZBET(JI,JJ)
+  END DO !CONCURRENT
   !
+  !$acc loop  seq
   DO JK = IKB+KKL,IKE-KKL,KKL
-!$acc loop collapse(2) independent
-    DO JJ=1,SIZE(ZGAM,2)
-      DO JI=1,SIZE(ZGAM,1)
+     !$acc loop independent gang, vector collapse(2)
+     DO  CONCURRENT ( JJ=1:JJU , JI=1:JIU )  
         ZGAM(JI,JJ,JK) = PIMPL * PA(JI,JJ,JK) / PRHODJA(JI,JJ,JK-KKL) / ZBET(JI,JJ)  
-                                                    ! gam(k) = c(k-1) / bet
+        ! gam(k) = c(k-1) / bet
         ZBET(JI,JJ)    = 1. - PIMPL * (  PA(JI,JJ,JK) * (1. + ZGAM(JI,JJ,JK))  &
-                                 + PA(JI,JJ,JK+KKL)                      &
-                                ) / PRHODJA(JI,JJ,JK)  
-                                                    ! bet = b(k) - a(k)* gam(k)  
+             + PA(JI,JJ,JK+KKL)                      &
+             ) / PRHODJA(JI,JJ,JK)  
+        ! bet = b(k) - a(k)* gam(k)  
         PVARP(JI,JJ,JK)= ( ZY(JI,JJ,JK) - PIMPL * PA(JI,JJ,JK) / PRHODJA(JI,JJ,JK) &
-                    * PVARP(JI,JJ,JK-KKL)                                  &
-                   ) / ZBET(JI,JJ)
-                                        ! res(k) = (y(k) -a(k)*res(k-1))/ bet 
-      END DO
-    END DO
+             * PVARP(JI,JJ,JK-KKL)                                  &
+             ) / ZBET(JI,JJ)
+        ! res(k) = (y(k) -a(k)*res(k-1))/ bet 
+     END DO ! CONCURRENT
   END DO
   ! special treatment for the last level
-  ZGAM(:,:,IKE) = PIMPL * PA(:,:,IKE) / PRHODJA(:,:,IKE-KKL) / ZBET(:,:) 
-                                                    ! gam(k) = c(k-1) / bet
-  ZBET(:,:)    = 1. - PIMPL * (  PA(:,:,IKE) * (1. + ZGAM(:,:,IKE))  &
-                              ) / PRHODJA(:,:,IKE)  
-                                                    ! bet = b(k) - a(k)* gam(k)  
-  PVARP(:,:,IKE)= ( ZY(:,:,IKE) - PIMPL * PA(:,:,IKE) / PRHODJA(:,:,IKE) &
-                                 * PVARP(:,:,IKE-KKL)                      &
-                  ) / ZBET(:,:)
-                                        ! res(k) = (y(k) -a(k)*res(k-1))/ bet 
+  !$acc loop independent gang, vector collapse(2)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+     ZGAM(JI,JJ,IKE) = PIMPL * PA(JI,JJ,IKE) / PRHODJA(JI,JJ,IKE-KKL) / ZBET(JI,JJ) 
+     ! gam(k) = c(k-1) / bet
+     ZBET(JI,JJ)    = 1. - PIMPL * (  PA(JI,JJ,IKE) * (1. + ZGAM(JI,JJ,IKE))  &
+          ) / PRHODJA(JI,JJ,IKE)  
+     ! bet = b(k) - a(k)* gam(k)  
+     PVARP(JI,JJ,IKE)= ( ZY(JI,JJ,IKE) - PIMPL * PA(JI,JJ,IKE) / PRHODJA(JI,JJ,IKE) &
+          * PVARP(JI,JJ,IKE-KKL)                      &
+          ) / ZBET(JI,JJ)
+     ! res(k) = (y(k) -a(k)*res(k-1))/ bet
+  END DO !CONCURRENT
   !
   !  going down 
   !
+  !$acc loop seq
   DO JK = IKE-KKL,IKB,-1*KKL
-    PVARP(:,:,JK) = PVARP(:,:,JK) - ZGAM(:,:,JK+KKL) * PVARP(:,:,JK+KKL) 
+     !$acc loop gang, vector collapse(2)
+      DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+         PVARP(JI,JJ,JK) = PVARP(JI,JJ,JK) - ZGAM(JI,JJ,JK+KKL) * PVARP(JI,JJ,JK+KKL)
+      END DO !CONCURRENT   
   END DO
 !$acc end kernels
 !
 ELSE
 ! 
-!$acc kernels
-  PVARP(:,:,IKTB:IKTE) = ZY(:,:,IKTB:IKTE)
+   !$acc kernels
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=IKTB:IKTE)
+      PVARP(JI,JJ,JK) = ZY(JI,JJ,JK)
+   END DO !CONCURRENT   
 !$acc end kernels
 !
 END IF 
@@ -291,8 +328,10 @@ END IF
 !            ----------------------------------------
 !
 !$acc kernels
-PVARP(:,:,KKA)=PVARP(:,:,IKB)
-PVARP(:,:,KKU)=PVARP(:,:,IKE)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU)
+   PVARP(JI,JJ,KKA)=PVARP(JI,JJ,IKB)
+   PVARP(JI,JJ,KKU)=PVARP(JI,JJ,IKE)
+END DO !CONCURRENT
 !$acc end kernels
 
 if ( mppdb_initialized ) then
@@ -302,6 +341,13 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate ( zy,zgam,zbet )
+#else
+CALL MNH_REL_ZT3D( izy,izgam,izbet )
+CALL MNH_CHECK_OUT_ZT3D("TRIDIAG_WIND")
+#endif
+
 !$acc end data
 
 !-------------------------------------------------------------------------------
diff --git a/src/MNH/turb.f90 b/src/MNH/turb.f90
index 115e9ce588ed13373c02869c843631d8b5da27ac..d431deaed59e82d4bcd614d31637a9bc66120750 100644
--- a/src/MNH/turb.f90
+++ b/src/MNH/turb.f90
@@ -8,7 +8,10 @@ module mode_turb
 !###############
 
 #ifdef MNH_OPENACC
-use mode_msg
+  use mode_msg
+  USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_ZT3DP , MNH_ALLOCATE_ZT2D, &
+       MNH_ALLOCATE_ZT4D , MNH_REL_ZT4D , &
+       MNH_CHECK_IN_ZT3D,MNH_CHECK_OUT_ZT3D
 #endif
 
 #ifdef MNH_BITREP
@@ -403,7 +406,7 @@ REAL, DIMENSION(:,:,:), INTENT(OUT)  :: PLEM  ! Mixing length
 !
 !       0.2  declaration of local variables
 !
-REAL, ALLOCATABLE, DIMENSION(:,:,:) ::&
+REAL, POINTER , CONTIGUOUS, DIMENSION(:,:,:) ::&
           ZCP,                        &  ! Cp at t-1
           ZEXN,                       &  ! EXN at t-1
           ZT,                         &  ! T at t-1
@@ -417,10 +420,15 @@ REAL, ALLOCATABLE, DIMENSION(:,:,:) ::&
           ZMWTH,ZMWR,ZMTH2,ZMR2,ZMTHR,&  ! 3rd order moments
           ZFWTH,ZFWR,ZFTH2,ZFR2,ZFTHR,&  ! opposite of verticale derivate of 3rd order moments
           ZTHLM                          ! initial potential temp.
+#ifdef MNH_OPENACC
+INTEGER :: IZCP,IZEXN,IZT,IZLOCPEXNM,IZLEPS,IZTRH,IZATHETA,IZAMOIST &
+          ,IZCOEF_DISS,IZFRAC_ICE,IZMWTH,IZMWR,IZMTH2,IZMR2,IZMTHR &
+          ,IZFWTH,IZFWR,IZFTH2,IZFR2,IZFTHR,IZTHLM
+#endif
 !
-REAL, ALLOCATABLE, DIMENSION(:,:,:,:) ::     &
+REAL, POINTER , CONTIGUOUS, DIMENSION(:,:,:,:) ::     &
           ZRM                            ! initial mixing ratio
-REAL, ALLOCATABLE, DIMENSION(:,:) ::  ZTAU11M,ZTAU12M,  &
+REAL, POINTER , CONTIGUOUS, DIMENSION(:,:) ::  ZTAU11M,ZTAU12M,  &
                                                  ZTAU22M,ZTAU33M,  &
             ! tangential surface fluxes in the axes following the orography
                                                  ZUSLOPE,ZVSLOPE,  &
@@ -435,9 +443,16 @@ REAL, ALLOCATABLE, DIMENSION(:,:) ::  ZTAU11M,ZTAU12M,  &
 !
             ! Virtual Potential Temp. used
             ! in the Deardorff mixing length computation
-REAL, DIMENSION(:,:,:), ALLOCATABLE  :: &
+#ifdef MNH_OPENACC
+INTEGER :: IZRM,IZTAU11M,IZTAU12M,IZTAU22M,IZTAU33M,IZUSLOPE,IZVSLOPE &
+          ,IZCDUEFF,IZUSTAR,IZLMO,IZRVM,IZSFRV
+#endif
+REAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS  :: &
           ZLVOCPEXNM,ZLSOCPEXNM,      &  ! Lv/Cp/EXNREF and Ls/Cp/EXNREF at t-1
           ZATHETA_ICE,ZAMOIST_ICE        ! coefficients for s = f (Thetal,Rnp)
+#ifdef MNH_OPENACC
+INTEGER :: IZLVOCPEXNM,IZLSOCPEXNM,IZATHETA_ICE,IZAMOIST_ICE
+#endif
 !
 REAL                :: ZEXPL        ! 1-PIMPL deg of expl.
 REAL                :: ZRVORD       ! RV/RD
@@ -454,14 +469,21 @@ REAL                :: ZALPHA       ! work coefficient :
 !                                   !   BL89 mixing length near the surface
 !
 REAL :: ZTIME1, ZTIME2
-REAL, DIMENSION(:,:,:), allocatable :: ZTT,ZEXNE,ZLV,ZCPH
-REAL, DIMENSION(:,:,:), allocatable :: ZSHEAR, ZDUDZ, ZDVDZ
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTT,ZEXNE,ZLV,ZCPH
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZSHEAR, ZDUDZ, ZDVDZ
+#ifdef MNH_OPENACC
+INTEGER :: IZTT,IZEXNE,IZLV,IZCPH,IZSHEAR, IZDUDZ, IZDVDZ
+#endif
 TYPE(TFIELDDATA) :: TZFIELD
 !
 #ifdef MNH_OPENACC
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE,ZTMP2_DEVICE,ZTMP3_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE,ZTMP2_DEVICE,ZTMP3_DEVICE
+INTEGER :: IZTMP1_DEVICE,IZTMP2_DEVICE,IZTMP3_DEVICE
 #endif
 !
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JLU_ZRM, JLU_TURB, JJU_ORMC01, JKU_CLOUD, JKU_TURB
+!
 !------------------------------------------------------------------------------------------
 !
 ! IN variables
@@ -528,70 +550,144 @@ if ( mppdb_initialized ) then
   call Mppdb_check( prsvs,      "Turb beg:prsvs"      )
 end if
 
-ALLOCATE (ZCP       (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-ALLOCATE (ZEXN      (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-ALLOCATE (ZT        (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-ALLOCATE (ZLOCPEXNM (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-ALLOCATE (ZLEPS     (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-ALLOCATE (ZTRH      (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-ALLOCATE (ZATHETA   (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-ALLOCATE (ZAMOIST   (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-ALLOCATE (ZCOEF_DISS(SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-ALLOCATE (ZFRAC_ICE (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-
-ALLOCATE (ZMWTH     (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-ALLOCATE (ZMWR      (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-ALLOCATE (ZMTH2     (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-ALLOCATE (ZMR2      (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-ALLOCATE (ZMTHR     (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-
-ALLOCATE (ZFWTH     (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-ALLOCATE (ZFWR      (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-ALLOCATE (ZFTH2     (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-ALLOCATE (ZFR2      (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-ALLOCATE (ZFTHR     (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-ALLOCATE (ZTHLM     (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-
-IF ( HTURBLEN == 'BL89' .OR. HTURBLEN == 'RM17' .OR. HTURBLEN == 'ADAP' .OR. ORMC01 ) &
-  ALLOCATE ( ZRM(SIZE(PRT,1),SIZE(PRT,2),SIZE(PRT,3),SIZE(PRT,4)) )
-
-ALLOCATE ( ZTAU11M(SIZE(PTHLT,1),SIZE(PTHLT,2)) )
-ALLOCATE ( ZTAU12M(SIZE(PTHLT,1),SIZE(PTHLT,2)) )
-ALLOCATE ( ZTAU22M(SIZE(PTHLT,1),SIZE(PTHLT,2)) )
-ALLOCATE ( ZTAU33M(SIZE(PTHLT,1),SIZE(PTHLT,2)) )
-ALLOCATE ( ZUSLOPE(SIZE(PTHLT,1),SIZE(PTHLT,2)) )
-ALLOCATE ( ZVSLOPE(SIZE(PTHLT,1),SIZE(PTHLT,2)) )
-ALLOCATE ( ZCDUEFF(SIZE(PTHLT,1),SIZE(PTHLT,2)) )
-ALLOCATE ( ZLMO   (SIZE(PTHLT,1),SIZE(PTHLT,2)) )
-IF (ORMC01) then
-  ALLOCATE ( ZUSTAR (SIZE(PTHLT,1),SIZE(PTHLT,2)) )
-  ALLOCATE ( ZRVM   (SIZE(PTHLT,1),SIZE(PTHLT,2)) )
-  ALLOCATE ( ZSFRV  (SIZE(PTHLT,1),SIZE(PTHLT,2)) )
-end if
+JIU =  size(pthlt, 1 )
+JJU =  size(pthlt, 2 )
+JKU =  size(pthlt, 3 )
 
-IF ( HCLOUD == 'KHKO' .OR. HCLOUD == 'C2R2' ) then
-  allocate( ztt   (size( put, 1 ), size( put, 2 ), size( put, 3 ) ) )
-  allocate( zexne (size( put, 1 ), size( put, 2 ), size( put, 3 ) ) )
-  allocate( zlv   (size( put, 1 ), size( put, 2 ), size( put, 3 ) ) )
-  allocate( zcph  (size( put, 1 ), size( put, 2 ), size( put, 3 ) ) )
-end if
-IF ( HTURBLEN == 'BL89' .OR. HTURBLEN == 'RM17' .OR. HTURBLEN == 'ADAP' ) then
-  allocate( zshear(size( put, 1 ), size( put, 2 ), size( put, 3 ) ) )
-end if
-IF ( HTURBLEN == 'RM17' .OR. HTURBLEN == 'ADAP' ) then
-  allocate( zdudz (size( put, 1 ), size( put, 2 ), size( put, 3 ) ) )
-  allocate( zdvdz (size( put, 1 ), size( put, 2 ), size( put, 3 ) ) )
-end if
+#ifndef MNH_OPENACC
+ALLOCATE (ZCP       (JIU,JJU,JKU) )
+ALLOCATE (ZEXN      (JIU,JJU,JKU) )
+ALLOCATE (ZT        (JIU,JJU,JKU) )
+ALLOCATE (ZLOCPEXNM (JIU,JJU,JKU) )
+ALLOCATE (ZLEPS     (JIU,JJU,JKU) )
+ALLOCATE (ZTRH      (JIU,JJU,JKU) )
+ALLOCATE (ZATHETA   (JIU,JJU,JKU) )
+ALLOCATE (ZAMOIST   (JIU,JJU,JKU) )
+ALLOCATE (ZCOEF_DISS(JIU,JJU,JKU) )
+ALLOCATE (ZFRAC_ICE (JIU,JJU,JKU) )
+
+ALLOCATE (ZMWTH     (JIU,JJU,JKU) )
+ALLOCATE (ZMWR      (JIU,JJU,JKU) )
+ALLOCATE (ZMTH2     (JIU,JJU,JKU) )
+ALLOCATE (ZMR2      (JIU,JJU,JKU) )
+ALLOCATE (ZMTHR     (JIU,JJU,JKU) )
+
+ALLOCATE (ZFWTH     (JIU,JJU,JKU) )
+ALLOCATE (ZFWR      (JIU,JJU,JKU) )
+ALLOCATE (ZFTH2     (JIU,JJU,JKU) )
+ALLOCATE (ZFR2      (JIU,JJU,JKU) )
+ALLOCATE (ZFTHR     (JIU,JJU,JKU) )
+ALLOCATE (ZTHLM     (JIU,JJU,JKU) )
+
+JLU_TURB = 0 
+IF ( HTURBLEN == 'BL89' .OR. HTURBLEN == 'RM17' .OR. ORMC01 ) JLU_TURB = SIZE(PRT,4)
+ALLOCATE ( ZRM(JIU,JJU,JKU, JLU_TURB ) )
+
+ALLOCATE ( ZTAU11M(JIU,JJU) )
+ALLOCATE ( ZTAU12M(JIU,JJU) )
+ALLOCATE ( ZTAU22M(JIU,JJU) )
+ALLOCATE ( ZTAU33M(JIU,JJU) )
+ALLOCATE ( ZUSLOPE(JIU,JJU) )
+ALLOCATE ( ZVSLOPE(JIU,JJU) )
+ALLOCATE ( ZCDUEFF(JIU,JJU) )
+ALLOCATE ( ZLMO   (JIU,JJU) )
+
+JJU_ORMC01 = 0
+IF (ORMC01) JJU_ORMC01 = SIZE(PTHLT,2)
+ALLOCATE ( ZUSTAR (JIU,JJU_ORMC01) )
+ALLOCATE ( ZRVM   (JIU,JJU_ORMC01) )
+ALLOCATE ( ZSFRV  (JIU,JJU_ORMC01) )
+
+JKU_CLOUD = 0 
+IF ( HCLOUD == 'KHKO' .OR. HCLOUD == 'C2R2' ) JKU_CLOUD = size( put, 3 )
+allocate( ztt   (JIU,JJU, JKU_CLOUD ) )
+allocate( zexne (JIU,JJU, JKU_CLOUD ) )
+allocate( zlv   (JIU,JJU, JKU_CLOUD ) )
+allocate( zcph  (JIU,JJU, JKU_CLOUD ) )
+
+JKU_TURB = 0  
+IF ( HTURBLEN == 'BL89' .OR. HTURBLEN == 'RM17' ) JKU_TURB = size( put, 3 )
+allocate( zshear(JIU,JJU, JKU_TURB ) )
+
+JKU_TURB = 0
+IF ( HTURBLEN == 'RM17' ) JKU_TURB = size( put, 3 )
+allocate( zdudz (JIU,JJU, JKU_TURB ) )
+allocate( zdvdz (JIU,JJU, JKU_TURB ) )
+
+#else
+CALL MNH_CHECK_IN_ZT3D("TURB")
+IZCP =  MNH_ALLOCATE_ZT3D (ZCP       ,JIU,JJU,JKU )
+IZEXN =  MNH_ALLOCATE_ZT3D (ZEXN      ,JIU,JJU,JKU )
+IZT =  MNH_ALLOCATE_ZT3D (ZT        ,JIU,JJU,JKU )
+IZLOCPEXNM =  MNH_ALLOCATE_ZT3D (ZLOCPEXNM ,JIU,JJU,JKU )
+IZLEPS =  MNH_ALLOCATE_ZT3D (ZLEPS     ,JIU,JJU,JKU )
+IZTRH =  MNH_ALLOCATE_ZT3D (ZTRH      ,JIU,JJU,JKU )
+IZATHETA =  MNH_ALLOCATE_ZT3D (ZATHETA   ,JIU,JJU,JKU )
+IZAMOIST =  MNH_ALLOCATE_ZT3D (ZAMOIST   ,JIU,JJU,JKU )
+IZCOEF_DISS =  MNH_ALLOCATE_ZT3D (ZCOEF_DISS,JIU,JJU,JKU )
+IZFRAC_ICE =  MNH_ALLOCATE_ZT3D (ZFRAC_ICE ,JIU,JJU,JKU )
+
+IZMWTH =  MNH_ALLOCATE_ZT3D (ZMWTH     ,JIU,JJU,JKU )
+IZMWR =  MNH_ALLOCATE_ZT3D (ZMWR      ,JIU,JJU,JKU )
+IZMTH2 =  MNH_ALLOCATE_ZT3D (ZMTH2     ,JIU,JJU,JKU )
+IZMR2 =  MNH_ALLOCATE_ZT3D (ZMR2      ,JIU,JJU,JKU )
+IZMTHR =  MNH_ALLOCATE_ZT3D (ZMTHR     ,JIU,JJU,JKU )
+
+IZFWTH =  MNH_ALLOCATE_ZT3D (ZFWTH     ,JIU,JJU,JKU )
+IZFWR =  MNH_ALLOCATE_ZT3D (ZFWR      ,JIU,JJU,JKU )
+IZFTH2 =  MNH_ALLOCATE_ZT3D (ZFTH2     ,JIU,JJU,JKU )
+IZFR2 =  MNH_ALLOCATE_ZT3D (ZFR2      ,JIU,JJU,JKU )
+IZFTHR =  MNH_ALLOCATE_ZT3D (ZFTHR     ,JIU,JJU,JKU )
+IZTHLM =  MNH_ALLOCATE_ZT3D (ZTHLM     ,JIU,JJU,JKU )
+
+JLU_ZRM = 0 
+IF ( HTURBLEN == 'BL89' .OR. HTURBLEN == 'RM17' .OR. ORMC01 ) JLU_ZRM = SIZE(PRT,4)
+IZRM =  MNH_ALLOCATE_ZT4D ( ZRM,JIU,JJU,JKU, JLU_ZRM  )
+
+IZTAU11M =  MNH_ALLOCATE_ZT2D ( ZTAU11M,JIU,JJU )
+IZTAU12M =  MNH_ALLOCATE_ZT2D ( ZTAU12M,JIU,JJU )
+IZTAU22M =  MNH_ALLOCATE_ZT2D ( ZTAU22M,JIU,JJU )
+IZTAU33M =  MNH_ALLOCATE_ZT2D ( ZTAU33M,JIU,JJU )
+IZUSLOPE =  MNH_ALLOCATE_ZT2D ( ZUSLOPE,JIU,JJU )
+IZVSLOPE =  MNH_ALLOCATE_ZT2D ( ZVSLOPE,JIU,JJU )
+IZCDUEFF =  MNH_ALLOCATE_ZT2D ( ZCDUEFF,JIU,JJU )
+IZLMO =  MNH_ALLOCATE_ZT2D ( ZLMO   ,JIU,JJU )
+
+JJU_ORMC01 = 0
+IF (ORMC01) JJU_ORMC01 = SIZE(PTHLT,2)
+IZUSTAR =  MNH_ALLOCATE_ZT2D ( ZUSTAR ,JIU,JJU_ORMC01 )
+IZRVM =  MNH_ALLOCATE_ZT2D ( ZRVM   ,JIU,JJU_ORMC01 )
+IZSFRV =  MNH_ALLOCATE_ZT2D ( ZSFRV  ,JIU,JJU_ORMC01 )
+
+JKU_CLOUD = 0 
+IF ( HCLOUD == 'KHKO' .OR. HCLOUD == 'C2R2' ) JKU_CLOUD = size( put, 3 )
+iztt =  MNH_ALLOCATE_ZT3D( ztt   ,JIU,JJU,JKU_CLOUD )
+izexne =  MNH_ALLOCATE_ZT3D( zexne ,JIU,JJU,JKU_CLOUD )
+izlv =  MNH_ALLOCATE_ZT3D( zlv   ,JIU,JJU,JKU_CLOUD )
+izcph =  MNH_ALLOCATE_ZT3D( zcph  ,JIU,JJU,JKU_CLOUD )
+
+JKU_TURB = 0  
+IF ( HTURBLEN == 'BL89' .OR. HTURBLEN == 'RM17' ) JKU_TURB = size( put, 3 )
+izshear =  MNH_ALLOCATE_ZT3D( zshear,JIU,JJU, JKU_TURB )
+
+JKU_TURB = 0
+IF ( HTURBLEN == 'RM17' ) JKU_TURB = size( put, 3 )
+izdudz =  MNH_ALLOCATE_ZT3D( zdudz ,JIU,JJU, JKU_TURB )
+izdvdz =  MNH_ALLOCATE_ZT3D( zdvdz ,JIU,JJU, JKU_TURB )
+
+#endif
 
 #ifdef MNH_OPENACC
-allocate( ztmp1_device(size( pthlt, 1 ), size( pthlt, 2 ), size( pthlt, 3 ) ) )
-IF (HTURBDIM=="1DIM") then
-  allocate( ztmp2_device(size( pthlt, 1 ), size( pthlt, 2 ), size( pthlt, 3 ) ) )
-  allocate( ztmp3_device(size( pthlt, 1 ), size( pthlt, 2 ), size( pthlt, 3 ) ) )
-end if
+iztmp1_device =  MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU )
+
+JKU_TURB = 0
+IF (HTURBDIM=="1DIM") JKU_TURB = size( pthlt, 3 )
+iztmp2_device =  MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU, JKU_TURB )
+iztmp3_device =  MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU, JKU_TURB )
+
 #endif
 
-!$acc data create( zcp, zexn, zt, zlocpexnm, zleps, ztrh,         &
+!$acc data present( zcp, zexn, zt, zlocpexnm, zleps, ztrh,         &
 !$acc &            zatheta, zamoist, zcoef_diss, zfrac_ice,       &
 !$acc &            zmwth, zmwr, zmth2, zmr2, zmthr,               &
 !$acc &            zfwth, zfwr, zfth2, zfr2, zfthr, zthlm,        &
@@ -640,10 +736,13 @@ ZTRH(:, :, : ) = XUNDEF
 ZCP(:,:,:)=XCPD
 !
 IF (KRR > 0) ZCP(:,:,:) = ZCP(:,:,:) + XCPV * PRT(:,:,:,1)
+! PGI20.5 BUG or reproductibility problem , with pointer this loop on JRR parallelize whitout reduction 
+!$acc loop seq
 DO JRR = 2,1+KRRL                          ! loop on the liquid components  
   ZCP(:,:,:)  = ZCP(:,:,:) + XCL * PRT(:,:,:,JRR)
 END DO
 !
+!$acc loop seq
 DO JRR = 2+KRRL,1+KRRL+KRRI                ! loop on the solid components   
   ZCP(:,:,:)  = ZCP(:,:,:)  + XCI * PRT(:,:,:,JRR)
 END DO
@@ -684,10 +783,10 @@ IF (KRRL >=1) THEN
 !*       2.5 Lv/Cph/Exn
 !
   IF ( KRRI >= 1 ) THEN 
-    ALLOCATE(ZLVOCPEXNM(SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)))
-    ALLOCATE(ZLSOCPEXNM(SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)))
-    ALLOCATE(ZAMOIST_ICE(SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)))
-    ALLOCATE(ZATHETA_ICE(SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)))
+    ALLOCATE(ZLVOCPEXNM(JIU,JJU,JKU))
+    ALLOCATE(ZLSOCPEXNM(JIU,JJU,JKU))
+    ALLOCATE(ZAMOIST_ICE(JIU,JJU,JKU))
+    ALLOCATE(ZATHETA_ICE(JIU,JJU,JKU))
 
 !$acc enter data create( zlvocpexnm, zlsocpexnm )
 !$acc data create( zamoist_ice, zatheta_ice )
@@ -958,8 +1057,11 @@ ENDIF
   ZCDUEFF(:,:) =-SQRT ( (PSFU(:,:)**2 + PSFV(:,:)**2) /                  &
                         (XMNH_TINY + ZUSLOPE(:,:)**2 + ZVSLOPE(:,:)**2 ) )
 #else
-  ZCDUEFF(:,:) =-SQRT ( (BR_P2(PSFU(:,:)) + BR_P2(PSFV(:,:))) /                  &
-                        (XMNH_TINY + BR_P2(ZUSLOPE(:,:)) + BR_P2(ZVSLOPE(:,:)) ) )
+  !$acc loop independent collapse(2)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+     ZCDUEFF(JI,JJ) =-SQRT ( (BR_P2(PSFU(JI,JJ)) + BR_P2(PSFV(JI,JJ))) /                  &
+                    (XMNH_TINY + BR_P2(ZUSLOPE(JI,JJ)) + BR_P2(ZVSLOPE(JI,JJ)) ) )
+  END DO
 #endif
 !$acc end kernels
 !
@@ -1488,6 +1590,36 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate( zcp, zexn, zt, zlocpexnm, zleps, ztrh,         &
+            zatheta, zamoist, zcoef_diss, zfrac_ice,       &
+            zmwth, zmwr, zmth2, zmr2, zmthr,               &
+            zfwth, zfwr, zfth2, zfr2, zfthr, zthlm,        &
+            zrm,                                           &
+            ztau11m, ztau12m, ztau22m, ztau33m,            &
+            zuslope, zvslope, zcdueff, zlmo,               &
+            zustar, zrvm, zsfrv,                           &
+            ztt, zexne, zlv, zcph, zshear,  zdudz,  zdvdz  )
+#else
+
+CALL MNH_REL_ZT3D ( iztt, izexne, izlv, izcph, izshear,  izdudz,  izdvdz, &
+     iztmp1_device, iztmp2_device, iztmp3_device       )
+
+CALL MNH_REL_ZT3D ( iztau11m, iztau12m, iztau22m, iztau33m,   &
+                    izuslope, izvslope, izcdueff, izlmo,      &
+                    izustar, izrvm, izsfrv                   )
+
+CALL MNH_REL_ZT3D ( izrm)
+
+CALL MNH_REL_ZT3D ( izmwth, izmwr, izmth2, izmr2, izmthr,        &
+                    izfwth, izfwr, izfth2, izfr2, izfthr, izthlm )
+
+CALL MNH_REL_ZT3D ( izcp, izexn, izt, izlocpexnm, izleps, iztrh, &
+                    izatheta, izamoist, izcoef_diss, izfrac_ice  )
+
+CALL MNH_CHECK_OUT_ZT3D("TURB")
+#endif
+
 !$acc end data
 
 !----------------------------------------------------------------------------
@@ -1629,8 +1761,11 @@ REAL, DIMENSION(:,:,:), INTENT(OUT)   :: PAMOIST,PATHETA
 !*       0.2   Declarations of local variables
 !
 REAL                :: ZEPS         ! XMV / XMD
-real, dimension(:,:,:), allocatable :: zrvsat
-real, dimension(:,:,:), allocatable :: zdrvsatdt
+real, dimension(:,:,:), pointer , contiguous :: zrvsat
+real, dimension(:,:,:), pointer , contiguous :: zdrvsatdt
+#ifdef MNH_OPENACC
+INTEGER :: izrvsat, izdrvsatdt
+#endif
 !
 !-------------------------------------------------------------------------------
 
@@ -1643,10 +1778,15 @@ real, dimension(:,:,:), allocatable :: zdrvsatdt
     call Mppdb_check( pcp,  "Compute_function_thermo beg:pcp"  )
   end if
 
+#ifndef MNH_OPENACC  
   allocate( zrvsat   ( size( pexn, 1 ), size( pexn, 2 ), size( pexn, 3 ) ) )
   allocate( zdrvsatdt( size( pexn, 1 ), size( pexn, 2 ), size( pexn, 3 ) ) )
+#else
+izrvsat    = MNH_ALLOCATE_ZT3D( zrvsat   , size( pexn, 1 ), size( pexn, 2 ), size( pexn, 3 ) ) 
+izdrvsatdt = MNH_ALLOCATE_ZT3D( zdrvsatdt, size( pexn, 1 ), size( pexn, 2 ), size( pexn, 3 ) )
+#endif
 
-!$acc data create( zrvsat, zdrvsatdt )
+!$acc data present( zrvsat, zdrvsatdt )
 
   ZEPS = XMV / XMD
 !
@@ -1663,7 +1803,9 @@ real, dimension(:,:,:), allocatable :: zdrvsatdt
 #ifndef MNH_BITREP
   ZRVSAT(:,:,:) =  EXP( PALP - PBETA/PT(:,:,:) - PGAM*ALOG( PT(:,:,:) ) )
 #else
-  ZRVSAT(:,:,:) =  BR_EXP( PALP - PBETA/PT(:,:,:) - PGAM*BR_LOG( PT(:,:,:) ) )
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZRVSAT(JI,JJ,JK) =  BR_EXP( PALP - PBETA/PT(JI,JJ,JK) - PGAM*BR_LOG( PT(JI,JJ,JK) ) )
+  END DO
 #endif
 !
 !*      1.3 saturation  mixing ratio at t
@@ -1702,7 +1844,7 @@ real, dimension(:,:,:), allocatable :: zdrvsatdt
   PLOCPEXN(:,:,:) = PLOCPEXN(:,:,:) / PEXN(:,:,:)
 !$acc end kernels
 
-  deallocate( zrvsat, zdrvsatdt )
+
 
   if ( mppdb_initialized ) then
     !Check all out arrays
@@ -1713,6 +1855,12 @@ real, dimension(:,:,:), allocatable :: zdrvsatdt
 
 !$acc end data
 
+#ifndef MNH_OPENACC 
+  deallocate( zrvsat, zdrvsatdt )
+#else
+  CALL MNH_REL_ZT3D(izrvsat, izdrvsatdt )
+#endif
+ 
 !$acc end data
 
 END SUBROUTINE COMPUTE_FUNCTION_THERMO
@@ -1772,10 +1920,10 @@ IMPLICIT NONE
 REAL :: ZPENTE            ! Slope of the amplification straight line
 REAL :: ZCOEF_AMPL_CEI_NUL! Ordonnate at the origin of the
                           ! amplification straight line
-real, dimension(:,:,:), allocatable :: zcoef_ampl
+real, dimension(:,:,:), pointer , contiguous :: zcoef_ampl
                           ! Amplification coefficient of the mixing length
                           ! when the instability criterium is verified 
-real, dimension(:,:,:), allocatable :: zlm_cloud
+real, dimension(:,:,:), pointer , contiguous :: zlm_cloud
                           ! Turbulent mixing length in the clouds
 !
 !-------------------------------------------------------------------------------
@@ -1966,7 +2114,7 @@ REAL                :: ZALPHA       ! proportionnality constant between Dz/2 and
 !                                   ! BL89 mixing length near the surface
 REAL                :: ZD           ! distance to the surface
 #ifdef MNH_OPENACC
-real, dimension(:,:,:), allocatable :: ztmp1_device, ztmp2_device
+real, dimension(:,:,:), pointer , contiguous :: ztmp1_device, ztmp2_device
 #endif
 !
 !-------------------------------------------------------------------------------
@@ -2192,16 +2340,21 @@ REAL                :: ZALPHA       ! proportionnality constant between Dz/2 and
 !                                   ! BL89 mixing length near the surface
 REAL                :: ZD           ! distance to the surface
 REAL                :: ZVAR         ! Intermediary variable
-REAL, DIMENSION(:,:), ALLOCATABLE ::   ZWORK2D
+REAL, DIMENSION(:,:), POINTER , CONTIGUOUS ::   ZWORK2D
 !
-REAL, DIMENSION(:,:,:), ALLOCATABLE ::     &
+REAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS ::     &
             ZDTHLDZ,ZDRTDZ,     &!dtheta_l/dz, drt_dz used for computing the stablity
 !                                ! criterion
             ZETHETA,ZEMOIST             !coef ETHETA and EMOIST
+#ifdef MNH_OPENACC
+INTEGER :: IZWORK2D,IZDTHLDZ,IZDRTDZ,IZETHETA,IZEMOIST
+#endif
 !
 #ifdef MNH_OPENACC
-REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZTMP1_DEVICE,ZTMP2_DEVICE
+REAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS :: ZTMP1_DEVICE,ZTMP2_DEVICE
+INTEGER :: IZTMP1_DEVICE,IZTMP2_DEVICE
 #endif
+INTEGER  :: JIU,JJU,JKU
 !----------------------------------------------------------------------------
 
 !$acc data present( PDXX, PDYY, PDZZ, PZZ, PDIRCOSZW, PTHLT, PTHVREF, PTKET, PSRCT, PRT, PLOCPEXNM, PATHETA, PAMOIST, PLM )
@@ -2223,18 +2376,31 @@ if ( mppdb_initialized ) then
   call Mppdb_check( pamoist,   "Dear beg:pamoist"   )
 end if
 
+JIU =  size(pthlt, 1 )
+JJU =  size(pthlt, 2 )
+JKU =  size(pthlt, 3 )
+
 !-------------------------------------------------------------------------------
-allocate( ZWORK2D(SIZE(PLM,1),SIZE(PLM,2)) )
-allocate( ZDTHLDZ(SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-allocate( ZDRTDZ (SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-allocate( ZETHETA(SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-allocate( ZEMOIST(SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
+#ifndef MNH_OPENACC
+allocate( ZWORK2D(JIU,JJU) )
+allocate( ZDTHLDZ(JIU,JJU,JKU) )
+allocate( ZDRTDZ (JIU,JJU,JKU) )
+allocate( ZETHETA(JIU,JJU,JKU) )
+allocate( ZEMOIST(JIU,JJU,JKU) )
+#else
+IZWORK2D = MNH_ALLOCATE_ZT2D( ZWORK2D,JIU,JJU)
+IZDTHLDZ = MNH_ALLOCATE_ZT3D( ZDTHLDZ,JIU,JJU,JKU)
+IZDRTDZ  = MNH_ALLOCATE_ZT3D( ZDRTDZ ,JIU,JJU,JKU)
+IZETHETA = MNH_ALLOCATE_ZT3D( ZETHETA,JIU,JJU,JKU)
+IZEMOIST = MNH_ALLOCATE_ZT3D( ZEMOIST,JIU,JJU,JKU)
+#endif
+
 #ifdef MNH_OPENACC
-allocate( ZTMP1_DEVICE(SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
-allocate( ZTMP2_DEVICE(SIZE(PTHLT,1),SIZE(PTHLT,2),SIZE(PTHLT,3)) )
+IZTMP1_DEVICE = MNH_ALLOCATE_ZT3D( ZTMP1_DEVICE,JIU,JJU,JKU)
+IZTMP2_DEVICE = MNH_ALLOCATE_ZT3D( ZTMP2_DEVICE,JIU,JJU,JKU)
 #endif
 
-!$acc data create( zwork2d, zdthldz, zdrtdz, zetheta, zemoist, &
+!$acc data present(zwork2d, zdthldz, zdrtdz, zetheta, zemoist, &
 !$acc &            ztmp1_device, ztmp2_device )
 
 !
@@ -2254,6 +2420,10 @@ IF ( HTURBDIM /= '1DIM' ) THEN  ! 3D turbulence scheme
 !$acc kernels
     PLM(:,:,:) = SQRT( PLM(:,:,:)*ZTMP1_DEVICE )
 !$acc end kernels
+    if ( mppdb_initialized ) then
+       call Mppdb_check( ZTMP1_DEVICE , "Dear mid: ZTMP1_DEVICE=Mxf" )
+       call Mppdb_check( plm, "Dear mid:plm" )
+    end if
 #endif
   ELSE
 !PW: "BUG" PGI : results different on CPU and GPU due to the power function
@@ -2269,6 +2439,11 @@ IF ( HTURBDIM /= '1DIM' ) THEN  ! 3D turbulence scheme
 !$acc kernels
     PLM(:,:,:) = (PLM(:,:,:)*ZTMP1_DEVICE*ZTMP2_DEVICE ) ** (1./3.)
 !$acc end kernels
+    if ( mppdb_initialized ) then
+       call Mppdb_check( ZTMP1_DEVICE , "Dear mid: ZTMP1_DEVICE=Mxf" )
+       call Mppdb_check( ZTMP2_DEVICE , "Dear mid: ZTMP2_DEVICE=Myf" )
+       call Mppdb_check( plm, "Dear mid:plm" )
+    end if
 #endif
 !
 #else
@@ -2278,9 +2453,17 @@ IF ( HTURBDIM /= '1DIM' ) THEN  ! 3D turbulence scheme
 #else
     CALL MXF_DEVICE(PDXX,ZTMP1_DEVICE)
     CALL MYF_DEVICE(PDYY,ZTMP2_DEVICE)
+    if ( mppdb_initialized ) then
+       call Mppdb_check( ZTMP1_DEVICE , "Dear mid: ZTMP1_DEVICE=Mxf" )
+       call Mppdb_check( ZTMP2_DEVICE , "Dear mid: ZTMP2_DEVICE=Myf" )
+       call Mppdb_check( plm, "Dear mid1:plm" )
+    end if
 !$acc kernels
     PLM(:,:,:) = BR_POW( PLM(:,:,:)*ZTMP1_DEVICE    *ZTMP2_DEVICE     , 1./3. )
 !$acc end kernels
+    if ( mppdb_initialized ) then
+       call Mppdb_check( plm, "Dear mid2:plm" )
+    end if
 #endif
 #endif
   END IF
@@ -2403,6 +2586,13 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate(zwork2d, zdthldz, zdrtdz, zetheta, zemoist ) 
+#else
+CALL MNH_REL_ZT3D(izwork2d, izdthldz, izdrtdz, izetheta, izemoist, &
+                iztmp1_device, iztmp2_device )
+#endif
+
 !$acc end data
 
 END SUBROUTINE DEAR
diff --git a/src/MNH/turb_hor_dyn_corr.f90 b/src/MNH/turb_hor_dyn_corr.f90
index 469bc39ba71a7d941b431d41b612f7887dd2c3ac..6104f0aa88f7488563e6aa6f6171ed1664d79d76 100644
--- a/src/MNH/turb_hor_dyn_corr.f90
+++ b/src/MNH/turb_hor_dyn_corr.f90
@@ -134,6 +134,7 @@ END MODULE MODI_TURB_HOR_DYN_CORR
 !!                      M.Moge  04/2016 Use openACC directives to port the TURB part of Meso-NH on GPU
 !!  Philippe Wautelet: 05/2016-04/2018: new data structures and calls for I/O
 !  P. Wautelet 20/05/2019: add name argument to ADDnFIELD_ll + new ADD4DFIELD_ll subroutine
+!  J.Escobar 13/08/2020: PGI/NVHPC BUG , extend DO CONCURRENT to 3D indexes        
 !! --------------------------------------------------------------------------
 !
 !*      0. DECLARATIONS
@@ -171,6 +172,9 @@ USE MODE_MPPDB
 #ifdef MNH_BITREP
 USE MODI_BITREP
 #endif
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_ZT3DP , MNH_ALLOCATE_ZT2D
+#endif
 !
 IMPLICIT NONE
 !
@@ -225,30 +229,40 @@ REAL, DIMENSION(:,:,:),   INTENT(INOUT) ::  PDP,PTP      ! TKE production terms
 !
 !*       0.2  declaration of local variables
 !
-REAL, DIMENSION(:,:,:), allocatable :: ZFLX,ZWORK ! work arrays, PK is the turb. mixing coef.
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZFLX,ZWORK ! work arrays, PK is the turb. mixing coef.
 !
-REAL, DIMENSION(:,:),   allocatable ::ZDIRSINZW
+REAL, DIMENSION(:,:),   pointer , contiguous :: ZDIRSINZW
       ! sinus of the angle between the vertical and the normal to the orography
+#ifdef MNH_OPENACC
+INTEGER :: IZFLX,IZWORK,IZDIRSINZW
+#endif
 INTEGER             :: IKB,IKE
                                     ! Index values for the Beginning and End
                                     ! mass points of the domain  
 INTEGER             :: IKU                                   
 INTEGER             :: JSV          ! scalar loop counter
 !
-REAL, DIMENSION(:,:,:), allocatable :: GX_U_M_PUM
-REAL, DIMENSION(:,:,:), allocatable :: GY_V_M_PVM
-REAL, DIMENSION(:,:,:), allocatable :: GZ_W_M_PWM
-REAL, DIMENSION(:,:,:), allocatable :: GZ_W_M_ZWP
-REAL, DIMENSION(:,:,:), allocatable :: ZMZF_DZZ   ! MZF(PDZZ)
-REAL, DIMENSION(:,:,:), allocatable :: ZDFDDWDZ   ! formal derivative of the
+REAL, DIMENSION(:,:,:), pointer , contiguous :: GX_U_M_PUM
+REAL, DIMENSION(:,:,:), pointer , contiguous :: GY_V_M_PVM
+REAL, DIMENSION(:,:,:), pointer , contiguous :: GZ_W_M_PWM
+REAL, DIMENSION(:,:,:), pointer , contiguous :: GZ_W_M_ZWP
+#ifdef MNH_OPENACC
+INTEGER :: IGX_U_M_PUM,IGY_V_M_PVM,IGZ_W_M_PWM,IGZ_W_M_ZWP
+#endif
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZMZF_DZZ   ! MZF(PDZZ)
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZDFDDWDZ   ! formal derivative of the
 !                                                 ! flux (variable: dW/dz)
-REAL, DIMENSION(:,:,:), allocatable :: ZWP        ! W at future   time-step
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZWP        ! W at future   time-step
 !
-REAL, DIMENSION(:,:,:), allocatable :: ZDU_DZ_DZS_DX ! du/dz*dzs/dx surf
-REAL, DIMENSION(:,:,:), allocatable :: ZDV_DZ_DZS_DY ! dv/dz*dzs/dy surf
-REAL, DIMENSION(:,:,:), allocatable :: ZDU_DX        ! du/dx        surf
-REAL, DIMENSION(:,:,:), allocatable :: ZDV_DY        ! dv/dy        surf
-REAL, DIMENSION(:,:,:), allocatable :: ZDW_DZ        ! dw/dz        surf
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZDU_DZ_DZS_DX ! du/dz*dzs/dx surf
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZDV_DZ_DZS_DY ! dv/dz*dzs/dy surf
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZDU_DX        ! du/dx        surf
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZDV_DY        ! dv/dy        surf
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZDW_DZ        ! dw/dz        surf
+#ifdef MNH_OPENACC
+INTEGER :: IZMZF_DZZ,IZDFDDWDZ,IZWP,IZDU_DZ_DZS_DX,IZDV_DZ_DZS_DY &
+           ,IZDU_DX,IZDV_DY,IZDW_DZ 
+#endif
 !
 INTEGER                :: IINFO_ll      ! return code of parallel routine
 TYPE(LIST_ll), POINTER :: TZFIELDS_ll   ! list of fields to exchange
@@ -256,14 +270,21 @@ TYPE(LIST_ll), POINTER :: TZFIELDS_ll   ! list of fields to exchange
 REAL :: ZTIME1, ZTIME2
 
 
-REAL, DIMENSION(:,:,:), allocatable :: ZCOEFF , ZDZZ
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZCOEFF , ZDZZ
                                     ! coefficients for the uncentred gradient 
                                     ! computation near the ground
+#ifdef MNH_OPENACC
+INTEGER  :: IZCOEFF , IZDZZ
+#endif
 !
 #ifdef MNH_OPENACC
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE
+INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE
 #endif
 TYPE(TFIELDDATA) :: TZFIELD
+!
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ,JK
 ! --------------------------------------------------------------------------
 
 !$acc data present( PK, PINV_PDZZ, PDXX, PDYY, PDZZ, PDZX, PDZY, PZZ, PDIRCOSZW,     &
@@ -309,36 +330,64 @@ if ( mppdb_initialized ) then
   call Mppdb_check( ptp,    "Turb_hor_dyn_corr beg:ptp"    )
 end if
 
-allocate( zflx (size( pum, 1 ), size( pum, 2 ), size( pum, 3 ) ) )
-allocate( zwork(size( pum, 1 ), size( pum, 2 ), size( pum, 3 ) ) )
+JIU =  size(pum, 1 )
+JJU =  size(pum, 2 )
+JKU =  size(pum, 3 )
 
-allocate( zdirsinzw(size( pum, 1 ), size( pum, 2 ) ) )
+#ifndef MNH_OPENACC
+allocate( zflx (JIU,JJU,JKU ) )
+allocate( zwork(JIU,JJU,JKU ) )
+
+allocate( zdirsinzw(JIU,JJU ) )
+
+allocate( gx_u_m_pum(JIU,JJU,JKU ) )
+allocate( gy_v_m_pvm(JIU,JJU,JKU ) )
+allocate( gz_w_m_pwm(JIU,JJU,JKU ) )
+allocate( gz_w_m_zwp(JIU,JJU,JKU ) )
+allocate( zmzf_dzz  (JIU,JJU,JKU ) )
+allocate( zdfddwdz  (JIU,JJU,JKU ) )
+allocate( zwp       (JIU,JJU,JKU ) )
+
+allocate( zdu_dz_dzs_dx(JIU,JJU, 1 ) )
+allocate( zdv_dz_dzs_dy(JIU,JJU, 1 ) )
+allocate( zdu_dx       (JIU,JJU, 1 ) )
+allocate( zdv_dy       (JIU,JJU, 1 ) )
+allocate( zdw_dz       (JIU,JJU, 1 ) )
+
+allocate( zcoeff(JIU,JJU, 1 + jpvext : 3 + jpvext ) )
+allocate( zdzz  (JIU,JJU, 1 + jpvext : 3 + jpvext ) )
+#else
+izflx          = MNH_ALLOCATE_ZT3D( zflx ,JIU,JJU,JKU )
+izwork         = MNH_ALLOCATE_ZT3D( zwork,JIU,JJU,JKU )
+
+izdirsinzw     = MNH_ALLOCATE_ZT2D( zdirsinzw,JIU,JJU )
 
-allocate( gx_u_m_pum(size( pum, 1 ), size( pum, 2 ), size( pum, 3 ) ) )
-allocate( gy_v_m_pvm(size( pvm, 1 ), size( pvm, 2 ), size( pvm, 3 ) ) )
-allocate( gz_w_m_pwm(size( pwm, 1 ), size( pwm, 2 ), size( pwm, 3 ) ) )
-allocate( gz_w_m_zwp(size( pwm, 1 ), size( pwm, 2 ), size( pwm, 3 ) ) )
-allocate( zmzf_dzz  (size( pwm, 1 ), size( pwm, 2 ), size( pwm, 3 ) ) )
-allocate( zdfddwdz  (size( pwm, 1 ), size( pwm, 2 ), size( pwm, 3 ) ) )
-allocate( zwp       (size( pwm, 1 ), size( pwm, 2 ), size( pwm, 3 ) ) )
+igx_u_m_pum    = MNH_ALLOCATE_ZT3D( gx_u_m_pum,JIU,JJU,JKU )
+igy_v_m_pvm    = MNH_ALLOCATE_ZT3D( gy_v_m_pvm,JIU,JJU,JKU )
+igz_w_m_pwm    = MNH_ALLOCATE_ZT3D( gz_w_m_pwm,JIU,JJU,JKU )
+igz_w_m_zwp    = MNH_ALLOCATE_ZT3D( gz_w_m_zwp,JIU,JJU,JKU )
+izmzf_dzz      = MNH_ALLOCATE_ZT3D( zmzf_dzz  ,JIU,JJU,JKU )
+izdfddwdz      = MNH_ALLOCATE_ZT3D( zdfddwdz  ,JIU,JJU,JKU )
+izwp           = MNH_ALLOCATE_ZT3D( zwp       ,JIU,JJU,JKU )
 
-allocate( zdu_dz_dzs_dx(size( pwm, 1 ), size( pwm, 2 ), 1 ) )
-allocate( zdv_dz_dzs_dy(size( pwm, 1 ), size( pwm, 2 ), 1 ) )
-allocate( zdu_dx       (size( pwm, 1 ), size( pwm, 2 ), 1 ) )
-allocate( zdv_dy       (size( pwm, 1 ), size( pwm, 2 ), 1 ) )
-allocate( zdw_dz       (size( pwm, 1 ), size( pwm, 2 ), 1 ) )
+izdu_dz_dzs_dx = MNH_ALLOCATE_ZT3DP( zdu_dz_dzs_dx,JIU,JJU, 1 , 1 )
+izdv_dz_dzs_dy = MNH_ALLOCATE_ZT3DP( zdv_dz_dzs_dy,JIU,JJU, 1 , 1 )
+izdu_dx        = MNH_ALLOCATE_ZT3DP( zdu_dx       ,JIU,JJU, 1 , 1 )
+izdv_dy        = MNH_ALLOCATE_ZT3DP( zdv_dy       ,JIU,JJU, 1 , 1 )
+izdw_dz        = MNH_ALLOCATE_ZT3DP( zdw_dz       ,JIU,JJU, 1 , 1 )
 
-allocate( zcoeff(size( pdzz, 1 ), size( pdzz, 2 ), 1 + jpvext : 3 + jpvext ) )
-allocate( zdzz  (size( pdzz, 1 ), size( pdzz, 2 ), 1 + jpvext : 3 + jpvext ) )
+izcoeff        = MNH_ALLOCATE_ZT3DP( zcoeff,JIU,JJU, 1 + jpvext , 3 + jpvext )
+izdzz          = MNH_ALLOCATE_ZT3DP( zdzz  ,JIU,JJU, 1 + jpvext , 3 + jpvext )
+#endif
 
 #ifdef MNH_OPENACC
-allocate( ztmp1_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp2_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp3_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp4_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU )
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU )
+iztmp3_device = MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU,JKU )
+iztmp4_device = MNH_ALLOCATE_ZT3D( ztmp4_device,JIU,JJU,JKU )
 #endif
 
-!$acc data create( ZFLX, ZWORK, ZDIRSINZW, ZCOEFF, ZDZZ,                  &
+!$acc data present(ZFLX, ZWORK, ZDIRSINZW, ZCOEFF, ZDZZ,                  &
 !$acc &            GX_U_M_PUM, GY_V_M_PVM, GZ_W_M_PWM, GZ_W_M_ZWP,        &
 !$acc &            ZMZF_DZZ, ZDFDDWDZ, ZWP,                               &
 !$acc &            ZDU_DZ_DZS_DX, ZDV_DZ_DZS_DY, ZDU_DX, ZDV_DY, ZDW_DZ,  &
@@ -358,7 +407,10 @@ IKU = SIZE(PUM,3)
 #ifndef MNH_BITREP
 ZDIRSINZW(:,:) = SQRT( 1. - PDIRCOSZW(:,:)**2 )
 #else
-ZDIRSINZW(:,:) = SQRT( 1. - BR_P2(PDIRCOSZW(:,:)) )
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+   ZDIRSINZW(JI,JJ) = SQRT( 1. - BR_P2(PDIRCOSZW(JI,JJ)) )
+END DO
 #endif
 !$acc end kernels
 !
@@ -391,13 +443,16 @@ CALL ADD3DFIELD_ll( TZFIELDS_ll, ZFLX, 'TURB_HOR_DYN_CORR::ZFLX' )
 !
 ! Computes the U variance
 IF (.NOT. L2D) THEN
-  !$acc kernels async(2)
-  ZFLX(:,:,:)= (2./3.) * PTKEM                                  &
-    - XCMFS * PK *( (4./3.) * GX_U_M_PUM                        &
-                   -(2./3.) * ( GY_V_M_PVM                      &
-                               +GZ_W_M_PWM                ) ) 
-  !$acc end kernels
-  !!  &   to be tested later
+   !$acc kernels async(2)
+   !$acc loop independent collapse(3)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+      ZFLX(JI,JJ,JK)= (2./3.) * PTKEM(JI,JJ,JK)                            &
+           - XCMFS * PK(JI,JJ,JK) *( (4./3.) * GX_U_M_PUM(JI,JJ,JK)        &
+           -(2./3.) * ( GY_V_M_PVM(JI,JJ,JK)                     &
+           +GZ_W_M_PWM(JI,JJ,JK)                ) )
+   END DO !CONCURRENT
+   !$acc end kernels
+   !!  &   to be tested later
   !!  + XCMFB *  PLM / SQRT(PTKEM) * (-2./3.) * PTP 
 ELSE
   !$acc kernels async(2)
@@ -566,14 +621,17 @@ ZFLX(:,:,IKB-1) =                                                            &
       PVSLOPEM(:,:) * PCOSSLOPE(:,:)    * PSINSLOPE(:,:) * ZDIRSINZW(:,:)    &
     - PUSLOPEM(:,:) * PCOSSLOPE(:,:)**2 * ZDIRSINZW(:,:) * PDIRCOSZW(:,:)    )
 #else
-ZFLX(:,:,IKB-1) =                                                             &
-        PTAU11M(:,:) * BR_P2(PCOSSLOPE(:,:)) * BR_P2(PDIRCOSZW(:,:))          &
-  -2. * PTAU12M(:,:) * PCOSSLOPE(:,:)* PSINSLOPE(:,:) * PDIRCOSZW(:,:)        &
-  +     PTAU22M(:,:) * BR_P2(PSINSLOPE(:,:))                                  &
-  +     PTAU33M(:,:) * BR_P2(PCOSSLOPE(:,:)) * BR_P2(ZDIRSINZW(:,:))          &
-  +2. * PCDUEFF(:,:) *      (                                                 &
-      PVSLOPEM(:,:) * PCOSSLOPE(:,:)    * PSINSLOPE(:,:) * ZDIRSINZW(:,:)     &
-    - PUSLOPEM(:,:) * BR_P2(PCOSSLOPE(:,:)) * ZDIRSINZW(:,:) * PDIRCOSZW(:,:) )
+!$acc loop independent collapse(2)   
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+ZFLX(JI,JJ,IKB-1) =                                                             &
+        PTAU11M(JI,JJ) * BR_P2(PCOSSLOPE(JI,JJ)) * BR_P2(PDIRCOSZW(JI,JJ))          &
+  -2. * PTAU12M(JI,JJ) * PCOSSLOPE(JI,JJ)* PSINSLOPE(JI,JJ) * PDIRCOSZW(JI,JJ)        &
+  +     PTAU22M(JI,JJ) * BR_P2(PSINSLOPE(JI,JJ))                                  &
+  +     PTAU33M(JI,JJ) * BR_P2(PCOSSLOPE(JI,JJ)) * BR_P2(ZDIRSINZW(JI,JJ))          &
+  +2. * PCDUEFF(JI,JJ) *      (                                                 &
+      PVSLOPEM(JI,JJ) * PCOSSLOPE(JI,JJ)    * PSINSLOPE(JI,JJ) * ZDIRSINZW(JI,JJ)     &
+      - PUSLOPEM(JI,JJ) * BR_P2(PCOSSLOPE(JI,JJ)) * ZDIRSINZW(JI,JJ) * PDIRCOSZW(JI,JJ) )
+END DO ! CONCURRENT
 #endif
 !$acc end kernels
 ! 
@@ -636,7 +694,10 @@ END IF
 #else
 CALL MXF_DEVICE(PDXX, ZTMP1_DEVICE)
 !$acc kernels async(10)
-ZTMP2_DEVICE = PRHODJ * ZFLX / ZTMP1_DEVICE
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZTMP2_DEVICE(JI,JJ,JK) = PRHODJ(JI,JJ,JK) * ZFLX(JI,JJ,JK) / ZTMP1_DEVICE(JI,JJ,JK)
+END DO !CONCURRENT
 !$acc end kernels
 !
 !!! wait for the computation of ZTMP2_DEVICE and the update of ZFLX
@@ -646,33 +707,45 @@ CALL DXM_DEVICE(ZTMP2_DEVICE, ZTMP3_DEVICE)
 IF (.NOT. LFLAT) THEN
   CALL MZM_DEVICE(PDXX,ZTMP1_DEVICE)
   !$acc kernels
-  ZTMP2_DEVICE = PRHODJ * ZFLX
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = PRHODJ(JI,JJ,JK) * ZFLX(JI,JJ,JK)
+  END DO !CONCURRENT
   !$acc end kernels
   CALL MZM_DEVICE(ZTMP2_DEVICE,ZTMP4_DEVICE)
   !$acc kernels
-  ZTMP2_DEVICE = ZTMP4_DEVICE * PINV_PDZZ
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = ZTMP4_DEVICE(JI,JJ,JK) * PINV_PDZZ(JI,JJ,JK)
+  END DO !CONCURRENT   
   !$acc end kernels
   CALL MXM_DEVICE( ZTMP2_DEVICE, ZTMP4_DEVICE )
   !$acc kernels
-  ZTMP2_DEVICE = PDZX / ZTMP1_DEVICE * ZTMP4_DEVICE
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = PDZX(JI,JJ,JK) / ZTMP1_DEVICE(JI,JJ,JK) * ZTMP4_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
   !$acc end kernels
   CALL DZF_DEVICE(1,IKU,1,ZTMP2_DEVICE,ZTMP1_DEVICE)
   !$acc kernels async(1)
-  PRUS(:,:,:)=PRUS                                            &
-              -ZTMP3_DEVICE                &
-              +ZTMP1_DEVICE
+  PRUS(:,:,:)=PRUS(:,:,:)                                           &
+              -ZTMP3_DEVICE(:,:,:)                &
+              +ZTMP1_DEVICE(:,:,:)
   !$acc end kernels
 ELSE
   !$acc kernels async(1)
-  PRUS(:,:,:)=PRUS - ZTMP3_DEVICE
+  PRUS(:,:,:)=PRUS(:,:,:) - ZTMP3_DEVICE(:,:,:)
   !$acc end kernels
 END IF
 #endif
 !
 IF (KSPLT==1) THEN
   ! Contribution to the dynamic production of TKE:
-  !$acc kernels async(2)
-  ZWORK(:,:,:)     = - ZFLX(:,:,:) * GX_U_M_PUM
+   !$acc kernels async(2)
+   !$acc loop independent collapse(3)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+      ZWORK(JI,JJ,JK)     = - ZFLX(JI,JJ,JK) * GX_U_M_PUM(JI,JJ,JK)
+   END DO !CONCURRENT
   !$acc end kernels
   !
   ! evaluate the dynamic production at w(IKB+1) in PDP(IKB)
@@ -719,12 +792,15 @@ END IF
 !
 ! Computes the V variance
 IF (.NOT. L2D) THEN
-  !$acc kernels async(3)
-  ZFLX(:,:,:)= (2./3.) * PTKEM                                  &
-    - XCMFS * PK *( (4./3.) * GY_V_M_PVM                        &
-                   -(2./3.) * ( GX_U_M_PUM                      &
-                               +GZ_W_M_PWM                ) )  
-  !$acc end kernels
+   !$acc kernels async(3)
+   !$acc loop independent collapse(3)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+      ZFLX(JI,JJ,JK)= (2./3.) * PTKEM(JI,JJ,JK)                                  &
+           - XCMFS * PK(JI,JJ,JK) *( (4./3.) * GY_V_M_PVM(JI,JJ,JK)                        &
+           -(2./3.) * ( GX_U_M_PUM(JI,JJ,JK)                      &
+           +GZ_W_M_PWM(JI,JJ,JK)                ) )
+   END DO !CONCURRENT
+   !$acc end kernels
   !! &  to be tested
   !!  + XCMFB *  PLM / SQRT(PTKEM) * (-2./3.) * PTP 
   !
@@ -768,14 +844,17 @@ ZFLX(:,:,IKB-1) =                                                            &
       PUSLOPEM(:,:) * PSINSLOPE(:,:)**2 * ZDIRSINZW(:,:) * PDIRCOSZW(:,:)    &
     + PVSLOPEM(:,:) * PCOSSLOPE(:,:)    * PSINSLOPE(:,:) * ZDIRSINZW(:,:)    )
 #else
-ZFLX(:,:,IKB-1) =                                                             &
-        PTAU11M(:,:) * BR_P2(PSINSLOPE(:,:)) * BR_P2(PDIRCOSZW(:,:))          &
-  +2. * PTAU12M(:,:) * PCOSSLOPE(:,:)* PSINSLOPE(:,:) * PDIRCOSZW(:,:)        &
-  +     PTAU22M(:,:) * BR_P2(PCOSSLOPE(:,:))                                  &
-  +     PTAU33M(:,:) * BR_P2(PSINSLOPE(:,:)) * BR_P2(ZDIRSINZW(:,:))          &
-  -2. * PCDUEFF(:,:)*       (                                                 &
-      PUSLOPEM(:,:) * BR_P2(PSINSLOPE(:,:)) * ZDIRSINZW(:,:) * PDIRCOSZW(:,:) &
-    + PVSLOPEM(:,:) * PCOSSLOPE(:,:)    * PSINSLOPE(:,:) * ZDIRSINZW(:,:)     )
+!$acc loop independent collapse(2)   
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+ZFLX(JI,JJ,IKB-1) =                                                             &
+        PTAU11M(JI,JJ) * BR_P2(PSINSLOPE(JI,JJ)) * BR_P2(PDIRCOSZW(JI,JJ))          &
+  +2. * PTAU12M(JI,JJ) * PCOSSLOPE(JI,JJ)* PSINSLOPE(JI,JJ) * PDIRCOSZW(JI,JJ)        &
+  +     PTAU22M(JI,JJ) * BR_P2(PCOSSLOPE(JI,JJ))                                  &
+  +     PTAU33M(JI,JJ) * BR_P2(PSINSLOPE(JI,JJ)) * BR_P2(ZDIRSINZW(JI,JJ))          &
+  -2. * PCDUEFF(JI,JJ)*       (                                                 &
+      PUSLOPEM(JI,JJ) * BR_P2(PSINSLOPE(JI,JJ)) * ZDIRSINZW(JI,JJ) * PDIRCOSZW(JI,JJ) &
+      + PVSLOPEM(JI,JJ) * PCOSSLOPE(JI,JJ)    * PSINSLOPE(JI,JJ) * ZDIRSINZW(JI,JJ)     )
+END DO ! CONCURRENT
 #endif
 !$acc end kernels
 ! 
@@ -833,7 +912,10 @@ IF (.NOT. L2D) THEN
 #else
   CALL MYF_DEVICE(PDYY, ZTMP1_DEVICE)
   !$acc kernels async(10)
-  ZTMP2_DEVICE = PRHODJ * ZFLX / ZTMP1_DEVICE
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = PRHODJ(JI,JJ,JK) * ZFLX(JI,JJ,JK) / ZTMP1_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
   !$acc end kernels
   !
   !!! wait for the computation of ZTMP2_DEVICE and the update of ZFLX
@@ -843,31 +925,46 @@ IF (.NOT. L2D) THEN
   IF (.NOT. LFLAT) THEN
     CALL MZM_DEVICE(PDYY,ZTMP1_DEVICE)
     !$acc kernels
-    ZTMP2_DEVICE = PRHODJ * ZFLX
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = PRHODJ(JI,JJ,JK) * ZFLX(JI,JJ,JK)
+    END DO !CONCURRENT   
     !$acc end kernels
     CALL MZM_DEVICE(ZTMP2_DEVICE,ZTMP4_DEVICE)
     !$acc kernels
-    ZTMP2_DEVICE = ZTMP4_DEVICE * PINV_PDZZ
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZTMP4_DEVICE(JI,JJ,JK) * PINV_PDZZ(JI,JJ,JK)
+    END DO !CONCURRENT   
     !$acc end kernels
     CALL MYM_DEVICE( ZTMP2_DEVICE,ZTMP4_DEVICE )
     !$acc kernels
-    ZTMP2_DEVICE = PDZY / ZTMP1_DEVICE * ZTMP4_DEVICE
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = PDZY(JI,JJ,JK) / ZTMP1_DEVICE(JI,JJ,JK) * ZTMP4_DEVICE(JI,JJ,JK)
+    END DO !CONCURRENT   
     !$acc end kernels
     CALL DZF_DEVICE(1,IKU,1,ZTMP2_DEVICE,ZTMP4_DEVICE )
     !$acc kernels async(1)
-    PRVS(:,:,:)=PRVS                                          &
-                -ZTMP3_DEVICE              &
-                +ZTMP4_DEVICE
+    PRVS(:,:,:)=PRVS(:,:,:)                                          &
+                -ZTMP3_DEVICE(:,:,:)              &
+                +ZTMP4_DEVICE(:,:,:)
     !$acc end kernels
   ELSE
-    !$acc kernels async(1)
-    PRVS(:,:,:)=PRVS - ZTMP3_DEVICE
+     !$acc kernels async(1)
+     !$acc loop independent collapse(3)
+     DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+        PRVS(JI,JJ,JK)=PRVS(JI,JJ,JK) - ZTMP3_DEVICE(JI,JJ,JK)
+     END DO !CONCURRENT    
     !$acc end kernels
   END IF
 ! Contribution to the dynamic production of TKE:
   IF (KSPLT==1) THEN
-    !$acc kernels async(2)
-    ZWORK(:,:,:)     = - ZFLX(:,:,:) * GY_V_M_PVM
+     !$acc kernels async(2)
+     !$acc loop independent collapse(3)
+     DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+        ZWORK(JI,JJ,JK) = - ZFLX(JI,JJ,JK) * GY_V_M_PVM(JI,JJ,JK)
+     END DO !CONCURRENT   
     !$acc end kernels
   ENDIF
 #endif
@@ -919,11 +1016,14 @@ END IF
 !
 ! Computes the W variance
 IF (.NOT. L2D) THEN
-  !$acc kernels async(2)
-  ZFLX(:,:,:)= (2./3.) * PTKEM                                  &
-    - XCMFS * PK *( (4./3.) * GZ_W_M_PWM                        &
-                   -(2./3.) * ( GX_U_M_PUM                      &
-                               +GY_V_M_PVM                ) ) 
+   !$acc kernels async(2)
+   !$acc loop independent collapse(3)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+      ZFLX(JI,JJ,JK) = (2./3.) * PTKEM(JI,JJ,JK)                                  &
+           - XCMFS * PK(JI,JJ,JK) *( (4./3.) * GZ_W_M_PWM(JI,JJ,JK)                        &
+           -(2./3.) * ( GX_U_M_PUM(JI,JJ,JK)                      &
+           +GY_V_M_PVM(JI,JJ,JK)                ) )
+   END DO !CONCURRENT
   !$acc end kernels
   !!  &  to be tested
   !!    -2.* XCMFB *  PLM / SQRT(PTKEM) * (-2./3.) * PTP 
@@ -956,15 +1056,20 @@ ZFLX(:,:,IKB)   = (2./3.) * PTKEM(:,:,IKB)                           &
 !  (-2./3.) * PTP(:,:,IKB:IKB)
 ! extrapolates this flux under the ground with the surface flux
 !$acc kernels async(3)
-ZFLX(:,:,IKB-1) =                                                     &
 #ifndef MNH_BITREP
+ZFLX(:,:,IKB-1) = &    
         PTAU11M(:,:) * ZDIRSINZW(:,:)**2                                &
   +     PTAU33M(:,:) * PDIRCOSZW(:,:)**2                                &
+  +2. * PCDUEFF(:,:)* PUSLOPEM(:,:)  * ZDIRSINZW(:,:) * PDIRCOSZW(:,:)
 #else
-        PTAU11M(:,:) * BR_P2(ZDIRSINZW(:,:))                                &
-  +     PTAU33M(:,:) * BR_P2(PDIRCOSZW(:,:))                                &
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )        
+ZFLX(JI,JJ,IKB-1) = &
+        PTAU11M(JI,JJ) * BR_P2(ZDIRSINZW(JI,JJ))                                &
+  +     PTAU33M(JI,JJ) * BR_P2(PDIRCOSZW(JI,JJ))                                &
+  +2. * PCDUEFF(JI,JJ)* PUSLOPEM(JI,JJ)  * ZDIRSINZW(JI,JJ) * PDIRCOSZW(JI,JJ)
+END DO ! CONCURRENT        
 #endif
-  +2. * PCDUEFF(:,:)* PUSLOPEM(:,:)  * ZDIRSINZW(:,:) * PDIRCOSZW(:,:) 
 !$acc end kernels
   ! 
 !
@@ -1031,15 +1136,21 @@ GZ_W_M_ZWP = GZ_W_M(ZWP,PDZZ)
 CALL GZ_W_M_DEVICE(1,IKU,1,ZWP,PDZZ,GZ_W_M_ZWP)
 #endif
 !$acc kernels async(2)
-ZFLX(:,:,IKB+1:)=ZFLX(:,:,IKB+1:) &
-  - XCMFS * PK(:,:,IKB+1:) * (4./3.) * (GZ_W_M_ZWP(:,:,IKB+1:) - GZ_W_M_PWM(:,:,IKB+1:))
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=IKB+1:JKU)
+   ZFLX(JI,JJ,JK)=ZFLX(JI,JJ,JK) &
+        - XCMFS * PK(JI,JJ,JK) * (4./3.) * (GZ_W_M_ZWP(JI,JJ,JK) - GZ_W_M_PWM(JI,JJ,JK))
+END DO !CONCURRENT
 !$acc end kernels
 !
 IF (KSPLT==1) THEN
-  !Contribution to the dynamic production of TKE:
-  !$acc kernels async(2)
-  ZWORK(:,:,:) = - ZFLX(:,:,:) * GZ_W_M_ZWP
-  !$acc end kernels
+   !Contribution to the dynamic production of TKE:
+   !$acc kernels async(2)
+   !$acc loop independent collapse(3)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+      ZWORK(JI,JJ,JK) = - ZFLX(JI,JJ,JK) * GZ_W_M_ZWP(JI,JJ,JK)
+   END DO !CONCURRENT   
+   !$acc end kernels
   !
   ! evaluate the dynamic production at w(IKB+1) in PDP(IKB)
   !
@@ -1169,6 +1280,22 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+DEALLOCATE (ZFLX, ZWORK, ZDIRSINZW, ZCOEFF, ZDZZ,                  &
+            GX_U_M_PUM, GY_V_M_PVM, GZ_W_M_PWM, GZ_W_M_ZWP,        &
+            ZMZF_DZZ, ZDFDDWDZ, ZWP,                               &
+            ZDU_DZ_DZS_DX, ZDV_DZ_DZS_DY, ZDU_DX, ZDV_DY, ZDW_DZ   )
+#else
+CALL MNH_REL_ZT3D(IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE )
+CALL MNH_REL_ZT3D(IZFLX, IZWORK, IZDIRSINZW,          &
+            IGX_U_M_PUM, IGY_V_M_PVM, IGZ_W_M_PWM, IGZ_W_M_ZWP,        &
+            IZMZF_DZZ, IZDFDDWDZ, IZWP,                                &
+            IZDU_DZ_DZS_DX, IZDV_DZ_DZS_DY, IZDU_DX, IZDV_DY, IZDW_DZ, &
+            IZCOEFF, IZDZZ             )
+
+#endif
+     
+
 !$acc end data
 
 END SUBROUTINE TURB_HOR_DYN_CORR
diff --git a/src/MNH/turb_hor_splt.f90 b/src/MNH/turb_hor_splt.f90
index e0bf14aa321c9fd93648b616e02303cbdde96d88..cee813251d9d999bb434389f18290fa654caff4c 100644
--- a/src/MNH/turb_hor_splt.f90
+++ b/src/MNH/turb_hor_splt.f90
@@ -268,6 +268,10 @@ USE MODI_SHUMAN_DEVICE
 USE MODI_TURB_HOR
 USE MODI_TURB_HOR_TKE
 !
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_ZT3DP , MNH_ALLOCATE_ZT2D, &
+                            MNH_ALLOCATE_ZT4D , MNH_REL_ZT4D
+#endif
 !
 IMPLICIT NONE
 !
@@ -343,12 +347,15 @@ REAL, DIMENSION(:,:,:),   INTENT(INOUT) ::  PSIGS
 !
 !*       0.2  declaration of local variables
 !
-REAL,ALLOCATABLE,DIMENSION(:,:,:) :: ZK           ! Turbulent diffusion doef.
+REAL,POINTER , CONTIGUOUS,DIMENSION(:,:,:) :: ZK           ! Turbulent diffusion doef.
                                                   ! ZK = PLM * SQRT(PTKEM)
-REAL,ALLOCATABLE,DIMENSION(:,:,:) :: ZINV_PDXX    ! 1./PDXX
-REAL,ALLOCATABLE,DIMENSION(:,:,:) :: ZINV_PDYY    ! 1./PDYY
-REAL,ALLOCATABLE,DIMENSION(:,:,:) :: ZINV_PDZZ    ! 1./PDZZ
-REAL,ALLOCATABLE,DIMENSION(:,:,:) :: ZMZM_PRHODJ  ! MZM(PRHODJ)
+REAL,POINTER , CONTIGUOUS,DIMENSION(:,:,:) :: ZINV_PDXX    ! 1./PDXX
+REAL,POINTER , CONTIGUOUS,DIMENSION(:,:,:) :: ZINV_PDYY    ! 1./PDYY
+REAL,POINTER , CONTIGUOUS,DIMENSION(:,:,:) :: ZINV_PDZZ    ! 1./PDZZ
+REAL,POINTER , CONTIGUOUS,DIMENSION(:,:,:) :: ZMZM_PRHODJ  ! MZM(PRHODJ)
+#ifdef MNH_OPENACC
+INTEGER :: IZK,IZINV_PDXX,IZINV_PDYY,IZINV_PDZZ,IZMZM_PRHODJ
+#endif
 !
 INTEGER :: JSPLT ! current split
 !
@@ -358,15 +365,23 @@ INTEGER :: JRR, JSV
 INTEGER :: ISV
 INTEGER :: IINFO_ll
 !
-REAL,ALLOCATABLE,DIMENSION(:,:,:)   :: ZUM, ZVM, ZWM, ZTHLM, ZTKEM
-REAL,ALLOCATABLE,DIMENSION(:,:,:,:) :: ZRM, ZSVM
-REAL,ALLOCATABLE,DIMENSION(:,:,:)   :: ZRUS, ZRVS, ZRWS, ZRTHLS
-REAL,ALLOCATABLE,DIMENSION(:,:,:,:) :: ZRRS, ZRSVS
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ,JK
+!
+REAL,POINTER , CONTIGUOUS,DIMENSION(:,:,:)   :: ZUM, ZVM, ZWM, ZTHLM, ZTKEM
+REAL,POINTER , CONTIGUOUS,DIMENSION(:,:,:,:) :: ZRM, ZSVM
+REAL,POINTER , CONTIGUOUS,DIMENSION(:,:,:)   :: ZRUS, ZRVS, ZRWS, ZRTHLS
+REAL,POINTER , CONTIGUOUS,DIMENSION(:,:,:,:) :: ZRRS, ZRSVS
+#ifdef MNH_OPENACC
+INTEGER :: IZUM, IZVM, IZWM, IZTHLM, IZTKEM, IZRM, IZSVM &
+         , IZRUS, IZRVS, IZRWS, IZRTHLS, IZRRS, IZRSVS
+#endif
 !
 TYPE(LIST_ll), POINTER, SAVE :: TZFIELDS_ll
 !
 #ifdef MNH_OPENACC
-REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZTMP1_DEVICE,ZTMP2_DEVICE
+REAL, DIMENSION(:,:,:), POINTER , CONTIGUOUS :: ZTMP1_DEVICE,ZTMP2_DEVICE
+INTEGER :: IZTMP1_DEVICE,IZTMP2_DEVICE
 #endif
 ! ---------------------------------------------------------------------------
 
@@ -441,17 +456,30 @@ IKE = SIZE(PUM,3) - JPVEXT
 CALL GET_INDICE_ll (IIB,IJB,IIE,IJE)
 ISV=SIZE(PSVM,4)
 !
-ALLOCATE(ZK(SIZE(PTHLM,1),SIZE(PTHLM,2),SIZE(PTHLM,3)))
-ALLOCATE(ZINV_PDXX(SIZE(PDXX,1),SIZE(PDXX,2),SIZE(PDXX,3)))
-ALLOCATE(ZINV_PDYY(SIZE(PDYY,1),SIZE(PDYY,2),SIZE(PDYY,3)))
-ALLOCATE(ZINV_PDZZ(SIZE(PDZZ,1),SIZE(PDZZ,2),SIZE(PDZZ,3)))
-ALLOCATE(ZMZM_PRHODJ(SIZE(PRHODJ,1),SIZE(PRHODJ,2),SIZE(PRHODJ,3)))
+JIU =  size(pthlm, 1 )
+JJU =  size(pthlm, 2 )
+JKU =  size(pthlm, 3 )
+!
+#ifndef MNH_OPENACC
+ALLOCATE(ZK(JIU,JJU,JKU))
+ALLOCATE(ZINV_PDXX(JIU,JJU,JKU))
+ALLOCATE(ZINV_PDYY(JIU,JJU,JKU))
+ALLOCATE(ZINV_PDZZ(JIU,JJU,JKU))
+ALLOCATE(ZMZM_PRHODJ(JIU,JJU,JKU))
+#else
+IZK          = MNH_ALLOCATE_ZT3D(ZK, JIU,JJU,JKU)
+IZINV_PDXX   = MNH_ALLOCATE_ZT3D(ZINV_PDXX, JIU,JJU,JKU)
+IZINV_PDYY   = MNH_ALLOCATE_ZT3D(ZINV_PDYY, JIU,JJU,JKU)
+IZINV_PDZZ   = MNH_ALLOCATE_ZT3D(ZINV_PDZZ, JIU,JJU,JKU)
+IZMZM_PRHODJ = MNH_ALLOCATE_ZT3D(ZMZM_PRHODJ, JIU,JJU,JKU)
+#endif
+
 #ifdef MNH_OPENACC
-allocate( ZTMP1_DEVICE( SIZE( PTHLM, 1 ), SIZE( PTHLM, 2 ), SIZE( PTHLM, 3 ) ) )
-allocate( ZTMP2_DEVICE( SIZE( PTHLM, 1 ), SIZE( PTHLM, 2 ), SIZE( PTHLM, 3 ) ) )
+IZTMP1_DEVICE = MNH_ALLOCATE_ZT3D( ZTMP1_DEVICE, JIU,JJU,JKU )
+IZTMP2_DEVICE = MNH_ALLOCATE_ZT3D( ZTMP2_DEVICE, JIU,JJU,JKU )
 #endif
 
-!$acc data create( ZK, ZINV_PDXX, ZINV_PDYY, ZINV_PDZZ, ZMZM_PRHODJ, &
+!$acc data present( ZK, ZINV_PDXX, ZINV_PDYY, ZINV_PDZZ, ZMZM_PRHODJ, &
 !$acc &            ZTMP1_DEVICE, ZTMP2_DEVICE )
 
 !$acc kernels
@@ -478,7 +506,8 @@ IF (KSPLIT>1 .AND. CPROGRAM=='MESONH') THEN
 !
 !*       2.1  allocations
 !             -----------
-!
+   !
+#ifndef MNH_OPENACC   
   ALLOCATE(ZUM(SIZE(PUM,1),SIZE(PUM,2),SIZE(PUM,3)))
   ALLOCATE(ZVM(SIZE(PVM,1),SIZE(PVM,2),SIZE(PVM,3)))
   ALLOCATE(ZWM(SIZE(PWM,1),SIZE(PWM,2),SIZE(PWM,3)))
@@ -492,7 +521,28 @@ IF (KSPLIT>1 .AND. CPROGRAM=='MESONH') THEN
   ALLOCATE(ZRSVS(SIZE(PRSVS,1),SIZE(PRSVS,2),SIZE(PRSVS,3),SIZE(PRSVS,4)))
   ALLOCATE(ZRTHLS(SIZE(PRTHLS,1),SIZE(PRTHLS,2),SIZE(PRTHLS,3)))
   ALLOCATE(ZRRS(SIZE(PRRS,1),SIZE(PRRS,2),SIZE(PRRS,3),SIZE(PRRS,4)))
-!$acc data create( zum, zvm, zwm, zsvm, zthlm, ztkem, zrm, zrus, zrvs, zrws, zrsvs, zrthls, zrrs )
+#else
+  IZUM    = MNH_ALLOCATE_ZT3D(ZUM,JIU,JJU,JKU)
+  IZVM    = MNH_ALLOCATE_ZT3D(ZVM,JIU,JJU,JKU)
+  IZWM    = MNH_ALLOCATE_ZT3D(ZWM,JIU,JJU,JKU)
+  
+  IZTHLM  = MNH_ALLOCATE_ZT3D(ZTHLM,JIU,JJU,JKU)
+  IZTKEM  = MNH_ALLOCATE_ZT3D(ZTKEM,JIU,JJU,JKU)
+  
+  IZRUS   = MNH_ALLOCATE_ZT3D(ZRUS,JIU,JJU,JKU)
+  IZRVS   = MNH_ALLOCATE_ZT3D(ZRVS,JIU,JJU,JKU)
+  IZRWS   = MNH_ALLOCATE_ZT3D(ZRWS,JIU,JJU,JKU)
+  
+  IZRTHLS = MNH_ALLOCATE_ZT3D(ZRTHLS,JIU,JJU,JKU)
+
+  IZSVM   = MNH_ALLOCATE_ZT4D(ZSVM,JIU,JJU,JKU, SIZE(PSVM,4) )
+  IZRM    = MNH_ALLOCATE_ZT4D(ZRM,JIU,JJU,JKU, SIZE(PRM,4) )
+  IZRSVS  = MNH_ALLOCATE_ZT4D(ZRSVS,JIU,JJU,JKU, SIZE(PRSVS,4) )
+  IZRRS   = MNH_ALLOCATE_ZT4D(ZRRS,JIU,JJU,JKU, SIZE(PRRS,4) )
+  
+#endif
+  
+!$acc data present( zum, zvm, zwm, zsvm, zthlm, ztkem, zrm, zrus, zrvs, zrws, zrsvs, zrthls, zrrs )
 !
 !
 !*       2.2  list for parallel exchanges
@@ -698,6 +748,7 @@ IF (KSPLIT>1 .AND. CPROGRAM=='MESONH') THEN
 !             -------------
 !
 !$acc end data
+#ifndef MNH_OPENACC  
   DEALLOCATE(ZUM)
   DEALLOCATE(ZVM)
   DEALLOCATE(ZWM)
@@ -711,6 +762,14 @@ IF (KSPLIT>1 .AND. CPROGRAM=='MESONH') THEN
   DEALLOCATE(ZRSVS)
   DEALLOCATE(ZRTHLS)
   DEALLOCATE(ZRRS)
+#else
+  CALL MNH_REL_ZT4D (SIZE(PRRS,4)  , IZRRS  )
+  CALL MNH_REL_ZT4D (SIZE(PRSVS,4) , IZRSVS )
+  CALL MNH_REL_ZT4D (SIZE(PRM,4)   , IZRM   )
+  CALL MNH_REL_ZT4D (SIZE(PSVM,4)  , IZSVM  )
+  CALL MNH_REL_ZT3D ( izum, izvm, izwm, izthlm, iztkem, izrus, izrvs, izrws, izrthls)
+#endif
+  
   !
   CALL CLEANLIST_ll(TZFIELDS_ll)
 !
@@ -751,14 +810,15 @@ END IF
 !
 !$acc end data
 
+#ifndef MNH_OPENACC
 DEALLOCATE(ZK)
 DEALLOCATE(ZINV_PDXX)
 DEALLOCATE(ZINV_PDYY)
 DEALLOCATE(ZINV_PDZZ)
 DEALLOCATE(ZMZM_PRHODJ)
-#ifdef MNH_OPENACC
-deallocate( ZTMP1_DEVICE )
-deallocate( ZTMP2_DEVICE )
+#else
+CALL MNH_REL_ZT3D(IZK, IZINV_PDXX, IZINV_PDYY, IZINV_PDZZ, IZMZM_PRHODJ, &
+                  IZTMP1_DEVICE, IZTMP2_DEVICE )
 #endif
 
 if ( mppdb_initialized ) then
diff --git a/src/MNH/turb_hor_sv_flux.f90 b/src/MNH/turb_hor_sv_flux.f90
index 723c8d56727e5c205015d5ea9c4fa0225ca15028..e49e71fe1c8671c5eb1014e64463bc027f178f9e 100644
--- a/src/MNH/turb_hor_sv_flux.f90
+++ b/src/MNH/turb_hor_sv_flux.f90
@@ -136,6 +136,10 @@ USE MODI_LES_MEAN_SUBGRID
 !
 USE MODI_SECOND_MNH
 !
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_ZT3DP , MNH_ALLOCATE_ZT2D
+#endif
+!
 IMPLICIT NONE
 !
 !
@@ -171,8 +175,8 @@ REAL, DIMENSION(:,:,:,:), INTENT(INOUT) ::  PRSVS        ! var. at t+1 -split-
 !
 !*       0.2  declaration of local variables
 !
-REAL, DIMENSION(:,:,:), allocatable :: ZFLXX, ZFLXY ! work arrays
-REAL, DIMENSION(:,:,:), allocatable :: ZWORK2D
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZFLXX, ZFLXY ! work arrays
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZWORK2D
 !
 REAL :: ZCSV          !constant for the scalar flux
 
@@ -181,7 +185,10 @@ INTEGER             :: IKB,IKE
                                     ! mass points of the domain  
 INTEGER             :: JSV          ! loop counter
 INTEGER             :: ISV          ! number of scalar var.
-REAL, DIMENSION(:,:,:), allocatable :: ZCOEFF
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZCOEFF
+#ifdef MNH_OPENACC
+INTEGER :: IZFLXX, IZFLXY, IZWORK2D, IZCOEFF
+#endif
                                     ! coefficients for the uncentred gradient 
                                     ! computation near the ground
 !
@@ -190,9 +197,13 @@ TYPE(TFIELDDATA) :: TZFIELD
 REAL :: ZTIME1, ZTIME2
 !
 #ifdef MNH_OPENACC
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, &
-                                       ZTMP4_DEVICE, ZTMP5_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, &
+     ZTMP4_DEVICE, ZTMP5_DEVICE
+INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE, IZTMP5_DEVICE
 #endif
+!
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ,JK
 ! ---------------------------------------------------------------------------
 
 !$acc data present( PK, PINV_PDXX, PINV_PDYY, PINV_PDZZ, PMZM_PRHODJ, &
@@ -225,22 +236,35 @@ if ( mppdb_initialized ) then
   call Mppdb_check( prsvs, "Turb_hor_sv_flux beg:prsvs" )
 end if
 
-allocate( zflxx(size( psvm, 1 ), size( psvm, 2 ), size( psvm, 3 ) ) )
-allocate( zflxy(size( psvm, 1 ), size( psvm, 2 ), size( psvm, 3 ) ) )
+JIU =  size(psvm, 1 )
+JJU =  size(psvm, 2 )
+JKU =  size(psvm, 3 )
+
+#ifndef MNH_OPENACC
+allocate( zflxx(JIU,JJU,JKU ) )
+allocate( zflxy(JIU,JJU,JKU ) )
+
+allocate( zwork2d(JIU,JJU, 1 ) )
+
+allocate( zcoeff(JIU,JJU, 1 + jpvext : 3 + jpvext ) )
+#else
+izflxx   = MNH_ALLOCATE_ZT3D( zflxx,JIU,JJU,JKU)
+izflxy   = MNH_ALLOCATE_ZT3D( zflxy,JIU,JJU,JKU)
 
-allocate( zwork2d(size( psvm, 1 ), size( psvm, 2 ), 1 ) )
+izwork2d = MNH_ALLOCATE_ZT3DP( zwork2d,JIU,JJU, 1 , 1 )
 
-allocate( zcoeff(size( pdzz, 1 ), size( pdzz, 2 ), 1 + jpvext : 3 + jpvext ) )
+izcoeff  = MNH_ALLOCATE_ZT3DP( zcoeff,JIU,JJU, 1 + jpvext , 3 + jpvext )
+#endif
 
 #ifdef MNH_OPENACC
-allocate( ztmp1_device(size( psvm, 1 ), size( psvm, 2 ), size( psvm, 3 ) ) )
-allocate( ztmp2_device(size( psvm, 1 ), size( psvm, 2 ), size( psvm, 3 ) ) )
-allocate( ztmp3_device(size( psvm, 1 ), size( psvm, 2 ), size( psvm, 3 ) ) )
-allocate( ztmp4_device(size( psvm, 1 ), size( psvm, 2 ), size( psvm, 3 ) ) )
-allocate( ztmp5_device(size( psvm, 1 ), size( psvm, 2 ), size( psvm, 3 ) ) )
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU)
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU)
+iztmp3_device = MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU,JKU)
+iztmp4_device = MNH_ALLOCATE_ZT3D( ztmp4_device,JIU,JJU,JKU)
+iztmp5_device = MNH_ALLOCATE_ZT3D( ztmp5_device,JIU,JJU,JKU)
 #endif
 
-!$acc data create( ZFLXX, ZFLXY, ZWORK2D, ZCOEFF, &
+!$acc data present( ZFLXX, ZFLXY, ZWORK2D, ZCOEFF, &
 !$acc &            ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE, ZTMP5_DEVICE )
 
 !
@@ -615,6 +639,13 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate( ZFLXX, ZFLXY, ZWORK2D, ZCOEFF )
+#else
+CALL MNH_REL_ZT3D ( IZFLXX, IZFLXY, IZWORK2D, IZCOEFF, &
+          IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE, IZTMP5_DEVICE )
+#endif
+
 !$acc end data
 
 END SUBROUTINE TURB_HOR_SV_FLUX
diff --git a/src/MNH/turb_hor_thermo_corr.f90 b/src/MNH/turb_hor_thermo_corr.f90
index 400520860235aa1634cc874ac880e242244386cc..bc9c94a5ce33e0cbd1a1eb7814f1f4d0e61e6062 100644
--- a/src/MNH/turb_hor_thermo_corr.f90
+++ b/src/MNH/turb_hor_thermo_corr.f90
@@ -150,6 +150,11 @@ USE MODI_SECOND_MNH
 USE MODI_BITREP
 #endif
 !
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_ZT3DP , MNH_ALLOCATE_ZT2D, &
+                            MNH_ALLOCATE_ZT4D , MNH_REL_ZT4D
+#endif
+!
 IMPLICIT NONE
 !
 !
@@ -196,12 +201,15 @@ REAL, DIMENSION(:,:,:),   INTENT(INOUT) ::  PSIGS
 !
 !*       0.2  declaration of local variables
 !
-REAL, DIMENSION(:,:,:), allocatable :: ZFLX,ZWORK,ZA ! work arrays
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZFLX,ZWORK,ZA ! work arrays
 !   
 INTEGER             :: IKB,IKE
                                     ! Index values for the Beginning and End
                                     ! mass points of the domain  
-REAL, DIMENSION(:,:,:), allocatable :: ZCOEFF
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZCOEFF
+#ifdef MNH_OPENACC
+INTEGER :: IZFLX,IZWORK,IZA,IZCOEFF
+#endif
                                     ! coefficients for the uncentred gradient 
                                     ! computation near the ground
 REAL :: ZTIME1, ZTIME2
@@ -209,10 +217,14 @@ TYPE(TFIELDDATA) :: TZFIELD
 !
 #ifdef MNH_OPENACC
 INTEGER :: IKU
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP5_DEVICE, ZTMP6_DEVICE, ZTMP7_DEVICE, ZTMP8_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP5_DEVICE, ZTMP6_DEVICE, ZTMP7_DEVICE, ZTMP8_DEVICE
+INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE ,&
+           IZTMP5_DEVICE, IZTMP6_DEVICE, IZTMP7_DEVICE, IZTMP8_DEVICE
 #endif
 !
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ,JK
 ! ---------------------------------------------------------------------------
 
 !$acc data present( PINV_PDXX, PINV_PDYY,               &
@@ -247,24 +259,36 @@ if ( mppdb_initialized ) then
   call Mppdb_check( psigs, "Turb_hor_thermo_corr beg:psigs" )
 end if
 
-allocate( zflx (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zwork(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( za   (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
+JIU =  size(pthlm, 1 )
+JJU =  size(pthlm, 2 )
+JKU =  size(pthlm, 3 )
+
+#ifndef MNH_OPENACC
+allocate( zflx (JIU,JJU,JKU ) )
+allocate( zwork(JIU,JJU,JKU ) )
+allocate( za   (JIU,JJU,JKU ) )
 
-allocate( zcoeff(size( pdzz, 1 ), size( pdzz, 2 ), 1 + jpvext : 3 + jpvext ) )
+allocate( zcoeff(JIU,JJU, 1 + jpvext : 3 + jpvext ) )
+#else
+izflx  = MNH_ALLOCATE_ZT3D( zflx ,JIU,JJU,JKU )
+izwork = MNH_ALLOCATE_ZT3D( zwork ,JIU,JJU,JKU )
+iza    = MNH_ALLOCATE_ZT3D( za ,JIU,JJU,JKU )
+
+izcoeff= MNH_ALLOCATE_ZT3DP( zcoeff,JIU,JJU, 1 + jpvext , 3 + jpvext )
+#endif
 
 #ifdef MNH_OPENACC
-allocate( ztmp1_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp2_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp3_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp4_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp5_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp6_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp7_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp8_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
+iztmp1_device= MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU  )
+iztmp2_device= MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU  )
+iztmp3_device= MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU,JKU  )
+iztmp4_device= MNH_ALLOCATE_ZT3D( ztmp4_device,JIU,JJU,JKU  )
+iztmp5_device= MNH_ALLOCATE_ZT3D( ztmp5_device,JIU,JJU,JKU  )
+iztmp6_device= MNH_ALLOCATE_ZT3D( ztmp6_device,JIU,JJU,JKU  )
+iztmp7_device= MNH_ALLOCATE_ZT3D( ztmp7_device,JIU,JJU,JKU  )
+iztmp8_device= MNH_ALLOCATE_ZT3D( ztmp8_device,JIU,JJU,JKU  )
 #endif
 
-!$acc data create( ZFLX, ZWORK, ZA, ZCOEFF,                                    &
+!$acc data present( ZFLX, ZWORK, ZA, ZCOEFF,                                    &
 !$acc &            ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE, &
 !$acc &            ZTMP5_DEVICE, ZTMP6_DEVICE, ZTMP7_DEVICE, ZTMP8_DEVICE  )
 
@@ -460,7 +484,9 @@ IF ( ( KRRL > 0 .AND. OSUBG_COND) .OR. ( OTURB_FLX .AND. tpfile%lopened ) &
     CALL LES_MEAN_SUBGRID( ZTMP1_DEVICE, X_LES_SUBGRID_ThlPz, .TRUE. )
     !
 !$acc end data
+    
 #endif
+
     CALL SECOND_MNH(ZTIME2)
     XTIME_LES = XTIME_LES + ZTIME2 - ZTIME1
   END IF
@@ -491,7 +517,8 @@ IF ( ( KRRL > 0 .AND. OSUBG_COND) .OR. ( OTURB_FLX .AND. tpfile%lopened ) &
       CALL GY_M_M_DEVICE(1,IKU,1,PTHLM       ,PDYY,PDZZ,PDZY,ZTMP3_DEVICE)
       CALL GY_M_M_DEVICE(1,IKU,1,PRM(:,:,:,1),PDYY,PDZZ,PDZY,ZTMP4_DEVICE)
 !$acc kernels
-      ZFLX(:,:,:)=PLM(:,:,:) * PLEPS(:,:,:) * (ZTMP1_DEVICE(:,:,:)*ZTMP2_DEVICE(:,:,:)+ZTMP3_DEVICE(:,:,:)*ZTMP4_DEVICE(:,:,:) ) * (XCHT1+XCHT2)
+      ZFLX(:,:,:)=PLM(:,:,:) * PLEPS(:,:,:) * (ZTMP1_DEVICE(:,:,:)*ZTMP2_DEVICE(:,:,:) &
+                 +ZTMP3_DEVICE(:,:,:)*ZTMP4_DEVICE(:,:,:) ) * (XCHT1+XCHT2)
 !$acc end kernels
     ELSE
       CALL GX_M_M_DEVICE(1,IKU,1,PTHLM       ,PDXX,PDZZ,PDZX,ZTMP1_DEVICE)
@@ -861,6 +888,14 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate (zflx,zwork,za,zcoeff)
+#else
+CALL MNH_REL_ZT3D    ( IZFLX, IZWORK, IZA, IZCOEFF,                                    &
+                       IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE, &
+                       IZTMP5_DEVICE, IZTMP6_DEVICE, IZTMP7_DEVICE, IZTMP8_DEVICE  )
+#endif
+
 !$acc end data
 
 END SUBROUTINE TURB_HOR_THERMO_CORR
diff --git a/src/MNH/turb_hor_thermo_flux.f90 b/src/MNH/turb_hor_thermo_flux.f90
index 17c3b5324093d83448177426c2e1e14f8218445a..768eade63a9c16ffe0aa0015e0495a0c5bd6acd8 100644
--- a/src/MNH/turb_hor_thermo_flux.f90
+++ b/src/MNH/turb_hor_thermo_flux.f90
@@ -151,6 +151,12 @@ USE MODI_LES_MEAN_SUBGRID
 !
 USE MODI_SECOND_MNH
 !
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_ZT3DP , MNH_ALLOCATE_ZT2D, &
+     MNH_ALLOCATE_ZT4D , MNH_REL_ZT4D, &
+     MNH_CHECK_IN_ZT3D,MNH_CHECK_OUT_ZT3D
+#endif
+!
 IMPLICIT NONE
 !
 !
@@ -203,23 +209,32 @@ REAL, DIMENSION(:,:,:,:), INTENT(INOUT) ::  PRRS         ! var. at t+1 -split-
 !
 !*       0.2  declaration of local variables
 !
-REAL, DIMENSION(:,:,:), allocatable :: ZFLX,ZFLXC ! work arrays
-!! REAL, DIMENSION(:,:,:), allocatable :: ZVPTV
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZFLX,ZFLXC ! work arrays
+!! REAL, DIMENSION(:,:,:), pointer , contiguous :: ZVPTV
 INTEGER             :: IKB,IKE,IKU
                                     ! Index values for the Beginning and End
                                     ! mass points of the domain  
-REAL, DIMENSION(:,:,:), allocatable :: ZCOEFF
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZCOEFF
                                     ! coefficients for the uncentred gradient 
                                     ! computation near the ground
+#ifdef MNH_OPENACC
+INTEGER :: IZFLX,IZFLXC,IZCOEFF
+#endif
 !
 REAL :: ZTIME1, ZTIME2
 !
 #ifdef MNH_OPENACC
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP5_DEVICE, ZTMP6_DEVICE, ZTMP7_DEVICE, ZTMP8_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP5_DEVICE, ZTMP6_DEVICE, ZTMP7_DEVICE, ZTMP8_DEVICE
+INTEGER ::  IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE, &
+            IZTMP5_DEVICE, IZTMP6_DEVICE, IZTMP7_DEVICE, IZTMP8_DEVICE
 #endif
 !
 TYPE(TFIELDDATA) :: TZFIELD
+!
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ,JK
+!
 ! ---------------------------------------------------------------------------
 
 !$acc data present( PK, PINV_PDXX, PINV_PDYY, PINV_PDZZ, PMZM_PRHODJ, &
@@ -259,24 +274,38 @@ if ( mppdb_initialized ) then
   call Mppdb_check( prrs,   "Turb_hor_thermo_flux beg:prrs"   )
 end if
 
-allocate( zflx (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zflxc(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-! allocate( zvptv(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
+JIU =  size(pthlm, 1 )
+JJU =  size(pthlm, 2 )
+JKU =  size(pthlm, 3 )
 
-allocate( zcoeff(size( pdzz, 1 ), size( pdzz, 2 ), 1 + jpvext : 3 + jpvext ) )
+#ifndef MNH_OPENACC
+allocate( zflx (JIU,JJU,JKU) )
+allocate( zflxc(JIU,JJU,JKU) )
+! allocate( zvptv(JIU,JJU,JKU) )
+
+allocate( zcoeff(JIU,JJU, 1 + jpvext : 3 + jpvext ) )
+#else
+CALL  MNH_CHECK_IN_ZT3D("TURB_HOR_THERMO_FLUX")
+izflx  = MNH_ALLOCATE_ZT3D( zflx ,JIU,JJU,JKU )
+izflxc = MNH_ALLOCATE_ZT3D( zflxc,JIU,JJU,JKU )
+! izvptv= MNH_ALLOCATE_ZT3D( zvptv,JIU,JJU,JKU )
+
+izcoeff= MNH_ALLOCATE_ZT3DP( zcoeff,JIU,JJU, 1 + jpvext , 3 + jpvext )
+
+#endif
 
 #ifdef MNH_OPENACC
-allocate( ztmp1_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp2_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp3_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp4_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp5_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp6_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp7_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp8_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
+iztmp1_device= MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU  )
+iztmp2_device= MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU  )
+iztmp3_device= MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU,JKU  )
+iztmp4_device= MNH_ALLOCATE_ZT3D( ztmp4_device,JIU,JJU,JKU  )
+iztmp5_device= MNH_ALLOCATE_ZT3D( ztmp5_device,JIU,JJU,JKU  )
+iztmp6_device= MNH_ALLOCATE_ZT3D( ztmp6_device,JIU,JJU,JKU  )
+iztmp7_device= MNH_ALLOCATE_ZT3D( ztmp7_device,JIU,JJU,JKU  )
+iztmp8_device= MNH_ALLOCATE_ZT3D( ztmp8_device,JIU,JJU,JKU  )
 #endif
 
-!$acc data create( ZFLX, ZFLXC, ZCOEFF,                                    &
+!$acc data present( ZFLX, ZFLXC, ZCOEFF,                                    &
 !$acc &            ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE, &
 !$acc &            ZTMP5_DEVICE, ZTMP6_DEVICE, ZTMP7_DEVICE, ZTMP8_DEVICE  )
 
@@ -311,7 +340,10 @@ ZFLX(:,:,IKE+1) = ZFLX(:,:,IKE)
 CALL MXM_DEVICE( PK, ZTMP1_DEVICE )
 CALL GX_M_U_DEVICE(1,IKU,1,PTHLM,PDXX,PDZZ,PDZX,ZTMP2_DEVICE)
 !$acc kernels
-ZFLX(:,:,:)     = -XCSHF * ZTMP1_DEVICE(:,:,:) * ZTMP2_DEVICE(:,:,:)
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZFLX(JI,JJ,JK)     = -XCSHF * ZTMP1_DEVICE(JI,JJ,JK) * ZTMP2_DEVICE(JI,JJ,JK)
+END DO
 ZFLX(:,:,IKE+1) = ZFLX(:,:,IKE) 
 !$acc end kernels
 #endif
@@ -350,7 +382,10 @@ ZFLX(:,:,IKB-1:IKB-1) = 2. * MXM(  SPREAD( PSFTHM(:,:)* PDIRCOSXW(:,:), 3,1) )
                        - ZFLX(:,:,IKB:IKB)
 #else
 !$acc kernels
- ZTMP1_DEVICE(:,:,1) = PSFTHM(:,:)* PDIRCOSXW(:,:)
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+   ZTMP1_DEVICE(JI,JJ,1) = PSFTHM(JI,JJ)* PDIRCOSXW(JI,JJ)
+END DO
 !$acc end kernels
   CALL MXM_DEVICE( ZTMP1_DEVICE(:,:,1:1), ZTMP2_DEVICE(:,:,1:1) )
 !$acc kernels
@@ -371,20 +406,32 @@ END IF
 #else
 IF (.NOT. LFLAT) THEN
   CALL MXM_DEVICE(PRHODJ, ZTMP1_DEVICE)
-!$acc kernels
-  ZTMP2_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) * ZFLX(:,:,:) * PINV_PDXX(:,:,:)
-!$acc end kernels
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * ZFLX(JI,JJ,JK) * PINV_PDXX(JI,JJ,JK)
+  END DO
+  !$acc end kernels
   CALL DXF_DEVICE(ZTMP2_DEVICE, ZTMP3_DEVICE)
-!$acc kernels
-  ZTMP2_DEVICE(:,:,:) = ZFLX(:,:,:) * PINV_PDXX(:,:,:)
-!$acc end kernels
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = ZFLX(JI,JJ,JK) * PINV_PDXX(JI,JJ,JK)
+  END DO
+  !$acc end kernels
   CALL MZM_DEVICE(ZTMP2_DEVICE,ZTMP4_DEVICE)
-!$acc kernels
-  ZTMP2_DEVICE(:,:,:) = PDZX(:,:,:)*ZTMP4_DEVICE(:,:,:)
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)  
+     ZTMP2_DEVICE(JI,JJ,JK) = PDZX(JI,JJ,JK)*ZTMP4_DEVICE(JI,JJ,JK)
+  END DO
 !$acc end kernels
   CALL MXF_DEVICE(ZTMP2_DEVICE, ZTMP4_DEVICE)
 !$acc kernels
-  ZTMP2_DEVICE(:,:,:) = PMZM_PRHODJ(:,:,:) * ZTMP4_DEVICE(:,:,:) * PINV_PDZZ(:,:,:)
+!$acc loop independent collapse(3)  
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZTMP2_DEVICE(JI,JJ,JK) = PMZM_PRHODJ(JI,JJ,JK) * ZTMP4_DEVICE(JI,JJ,JK) * PINV_PDZZ(JI,JJ,JK)
+END DO
 !$acc end kernels
   CALL DZF_DEVICE(1,IKU,1,ZTMP2_DEVICE,ZTMP4_DEVICE )
 !$acc kernels
@@ -602,7 +649,9 @@ IF (KSPLT==1 .AND. LLES_CALL) THEN
     CALL LES_MEAN_SUBGRID( ZTMP3_DEVICE,X_LES_RES_ddxa_Rt_SBG_UaThl , .TRUE. )
   END IF
 !$acc end data
+ 
 #endif
+
   CALL SECOND_MNH(ZTIME2)
   XTIME_LES = XTIME_LES + ZTIME2 - ZTIME1
 END IF
@@ -725,7 +774,10 @@ END IF
   CALL MXM_DEVICE( PK, ZTMP1_DEVICE )
   CALL GX_M_U_DEVICE(1,IKU,1,PRM(:,:,:,1),PDXX,PDZZ,PDZX,ZTMP2_DEVICE)
 !$acc kernels
-  ZFLX(:,:,:)     = -XCHF * ZTMP1_DEVICE * ZTMP2_DEVICE(:,:,:)
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZFLX(JI,JJ,JK)     = -XCHF * ZTMP1_DEVICE(JI,JJ,JK) * ZTMP2_DEVICE(JI,JJ,JK)
+END DO
   ZFLX(:,:,IKE+1) = ZFLX(:,:,IKE) 
 !$acc end kernels
 !
@@ -761,23 +813,38 @@ END IF
   IF (.NOT. LFLAT) THEN
     CALL MXM_DEVICE(PRHODJ,ZTMP1_DEVICE)
     !$acc kernels
-    ZTMP2_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) * ZFLX(:,:,:) * PINV_PDXX(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * ZFLX(JI,JJ,JK) * PINV_PDXX(JI,JJ,JK)
+    END DO
     !$acc end kernels
     CALL DXF_DEVICE( ZTMP2_DEVICE, ZTMP3_DEVICE )
     !$acc kernels
-    ZTMP2_DEVICE(:,:,:) = ZFLX(:,:,:) * PINV_PDXX(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZFLX(JI,JJ,JK) * PINV_PDXX(JI,JJ,JK)
+    END DO
     !$acc end kernels
     CALL MZM_DEVICE(ZTMP2_DEVICE,ZTMP4_DEVICE)
     !$acc kernels
-    ZTMP2_DEVICE(:,:,:) = PDZX(:,:,:)*ZTMP4_DEVICE(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = PDZX(JI,JJ,JK)*ZTMP4_DEVICE(JI,JJ,JK)
+    END DO
     !$acc end kernels
     CALL MXF_DEVICE(ZTMP2_DEVICE,ZTMP4_DEVICE)
     !$acc kernels
-    ZTMP2_DEVICE(:,:,:) = PMZM_PRHODJ(:,:,:) * ZTMP4_DEVICE(:,:,:) * PINV_PDZZ(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = PMZM_PRHODJ(JI,JJ,JK) * ZTMP4_DEVICE(JI,JJ,JK) * PINV_PDZZ(JI,JJ,JK)
+    END DO
     !$acc end kernels
     CALL DZF_DEVICE(1,IKU,1, ZTMP2_DEVICE, ZTMP4_DEVICE)
     !$acc kernels
-    PRRS(:,:,:,1) = PRRS(:,:,:,1) - ZTMP3_DEVICE(:,:,:) + ZTMP4_DEVICE(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)    
+       PRRS(JI,JJ,JK,1) = PRRS(JI,JJ,JK,1) - ZTMP3_DEVICE(JI,JJ,JK) + ZTMP4_DEVICE(JI,JJ,JK)
+    END DO
     !$acc end kernels
   ELSE
     CALL MXM_DEVICE(PRHODJ,ZTMP1_DEVICE)
@@ -1085,7 +1152,10 @@ END IF
   CALL MYM_DEVICE( PK, ZTMP1_DEVICE )
   CALL GY_M_V_DEVICE(1,IKU,1,PTHLM,PDYY,PDZZ,PDZY,ZTMP2_DEVICE)
   !$acc kernels
-  ZFLX(:,:,:)     = -XCSHF * ZTMP1_DEVICE(:,:,:) * ZTMP2_DEVICE(:,:,:)
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZFLX(JI,JJ,JK)     = -XCSHF * ZTMP1_DEVICE(JI,JJ,JK) * ZTMP2_DEVICE(JI,JJ,JK)
+  END DO
   ZFLX(:,:,IKE+1) = ZFLX(:,:,IKE) 
   !$acc end kernels
 ELSE
@@ -1129,23 +1199,38 @@ IF (.NOT. L2D) THEN
   IF (.NOT. LFLAT) THEN
     CALL MYM_DEVICE(PRHODJ, ZTMP1_DEVICE)
     !$acc kernels
-    ZTMP2_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) * ZFLX(:,:,:) * PINV_PDYY(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * ZFLX(JI,JJ,JK) * PINV_PDYY(JI,JJ,JK)
+    END DO
     !$acc end kernels
     CALL DYF_DEVICE( ZTMP2_DEVICE, ZTMP3_DEVICE )
     !$acc kernels
-    ZTMP1_DEVICE(:,:,:) = ZFLX(:,:,:) * PINV_PDYY(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP1_DEVICE(JI,JJ,JK) = ZFLX(JI,JJ,JK) * PINV_PDYY(JI,JJ,JK)
+    END DO
     !$acc end kernels
     CALL MZM_DEVICE(ZTMP1_DEVICE, ZTMP2_DEVICE)
     !$acc kernels
-    ZTMP1_DEVICE(:,:,:) = PDZY(:,:,:)*ZTMP2_DEVICE(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP1_DEVICE(JI,JJ,JK) = PDZY(JI,JJ,JK)*ZTMP2_DEVICE(JI,JJ,JK)
+    END DO
     !$acc end kernels
     CALL MYF_DEVICE(ZTMP1_DEVICE, ZTMP2_DEVICE)
     !$acc kernels
-    ZTMP1_DEVICE(:,:,:) = PMZM_PRHODJ(:,:,:) * ZTMP2_DEVICE(:,:,:) * PINV_PDZZ(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP1_DEVICE(JI,JJ,JK) = PMZM_PRHODJ(JI,JJ,JK) * ZTMP2_DEVICE(JI,JJ,JK) * PINV_PDZZ(JI,JJ,JK)
+    END DO
     !$acc end kernels
     CALL DZF_DEVICE(1,IKU,1, ZTMP1_DEVICE, ZTMP2_DEVICE )
     !$acc kernels
-    PRTHLS(:,:,:) = PRTHLS(:,:,:) - ZTMP3_DEVICE(:,:,:) + ZTMP2_DEVICE(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       PRTHLS(JI,JJ,JK) = PRTHLS(JI,JJ,JK) - ZTMP3_DEVICE(JI,JJ,JK) + ZTMP2_DEVICE(JI,JJ,JK)
+    END DO
     !$acc end kernels
   ELSE
     CALL MYM_DEVICE(PRHODJ, ZTMP1_DEVICE)
@@ -1434,7 +1519,10 @@ IF (KRR/=0) THEN
     CALL MYM_DEVICE( PK, ZTMP1_DEVICE )
     CALL GY_M_V_DEVICE(1,IKU,1,PRM(:,:,:,1),PDYY,PDZZ,PDZY, ZTMP2_DEVICE)
     !$acc kernels
-    ZFLX(:,:,:)     = -XCHF * ZTMP1_DEVICE(:,:,:) * ZTMP2_DEVICE(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZFLX(JI,JJ,JK)     = -XCHF * ZTMP1_DEVICE(JI,JJ,JK) * ZTMP2_DEVICE(JI,JJ,JK)
+    END DO !CONCURRENT
     ZFLX(:,:,IKE+1) = ZFLX(:,:,IKE) 
     !$acc end kernels
   ELSE
@@ -1477,25 +1565,40 @@ IF (KRR/=0) THEN
     IF (.NOT. LFLAT) THEN
       CALL MYM_DEVICE(PRHODJ, ZTMP1_DEVICE)
       !$acc kernels
-      ZTMP2_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) * ZFLX(:,:,:) * PINV_PDYY(:,:,:)
+      !$acc loop independent collapse(3)
+      DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+         ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * ZFLX(JI,JJ,JK) * PINV_PDYY(JI,JJ,JK)
+      END DO
       !$acc end kernels
       CALL DYF_DEVICE( ZTMP2_DEVICE, ZTMP3_DEVICE )
       !
       !$acc kernels
-      ZTMP1_DEVICE(:,:,:) = ZFLX(:,:,:) * PINV_PDYY(:,:,:)
+      !$acc loop independent collapse(3)
+      DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+         ZTMP1_DEVICE(JI,JJ,JK) = ZFLX(JI,JJ,JK) * PINV_PDYY(JI,JJ,JK)
+      END DO
       !$acc end kernels
       CALL MZM_DEVICE(ZTMP1_DEVICE,ZTMP2_DEVICE)
       !$acc kernels
-      ZTMP1_DEVICE(:,:,:) = PDZY(:,:,:)*ZTMP2_DEVICE(:,:,:)
+      !$acc loop independent collapse(3)
+      DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+         ZTMP1_DEVICE(JI,JJ,JK) = PDZY(JI,JJ,JK)*ZTMP2_DEVICE(JI,JJ,JK)
+      END DO
       !$acc end kernels
       CALL MYF_DEVICE(ZTMP1_DEVICE,ZTMP2_DEVICE)
       !$acc kernels
-      ZTMP1_DEVICE(:,:,:) = PMZM_PRHODJ(:,:,:) * ZTMP2_DEVICE(:,:,:) * PINV_PDZZ(:,:,:)
+      !$acc loop independent collapse(3)
+      DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+         ZTMP1_DEVICE(JI,JJ,JK) = PMZM_PRHODJ(JI,JJ,JK) * ZTMP2_DEVICE(JI,JJ,JK) * PINV_PDZZ(JI,JJ,JK)
+      END DO
       !$acc end kernels
       CALL DZF_DEVICE(1,IKU,1,ZTMP1_DEVICE,ZTMP2_DEVICE )
       !
       !$acc kernels
-      PRRS(:,:,:,1) = PRRS(:,:,:,1) - ZTMP3_DEVICE(:,:,:) + ZTMP2_DEVICE(:,:,:)
+      !$acc loop independent collapse(3)
+      DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+         PRRS(JI,JJ,JK,1) = PRRS(JI,JJ,JK,1) - ZTMP3_DEVICE(JI,JJ,JK) + ZTMP2_DEVICE(JI,JJ,JK)
+      END DO
       !$acc end kernels
     ELSE
       CALL MYM_DEVICE(PRHODJ, ZTMP1_DEVICE)
@@ -1699,6 +1802,15 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate (zflx,zflxc,zcoeff)
+#else
+CALL MNH_REL_ZT3D ( IZFLX, IZFLXC, IZCOEFF,                                    &
+                    IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE, &
+                    IZTMP5_DEVICE, IZTMP6_DEVICE, IZTMP7_DEVICE, IZTMP8_DEVICE  )
+CALL MNH_CHECK_OUT_ZT3D("TURB_HOR_THERMO_FLUX")
+#endif
+
 !$acc end data
 
 END SUBROUTINE TURB_HOR_THERMO_FLUX
diff --git a/src/MNH/turb_hor_tke.f90 b/src/MNH/turb_hor_tke.f90
index f98d8de25d5d3fed9a3663e56b23796428a9463f..c5db45b264f6b9f0873232ff6b2adaff8e978855 100644
--- a/src/MNH/turb_hor_tke.f90
+++ b/src/MNH/turb_hor_tke.f90
@@ -98,7 +98,11 @@ USE MODI_GRADIENT_M
 USE MODI_LES_MEAN_SUBGRID
 !
 USE MODI_SECOND_MNH
-!
+
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_ZT3DP , MNH_ALLOCATE_ZT2D
+#endif
+
 IMPLICIT NONE
 !
 !
@@ -125,17 +129,24 @@ REAL, DIMENSION(:,:,:),   INTENT(OUT)   ::  PTRH     ! horizontal transport of T
 !
 INTEGER :: IKB, IKU
 !
-REAL, DIMENSION(:,:,:), allocatable :: ZCOEFF
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZCOEFF
                                     ! coefficients for the uncentred gradient 
                                     ! computation near the ground
 !
-REAL, DIMENSION(:,:,:), allocatable :: ZFLX
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZFLX
+#ifdef MNH_OPENACC
+INTEGER :: IZCOEFF,IZFLX
+#endif
 !
 REAL :: ZTIME1, ZTIME2
 !
 #ifdef MNH_OPENACC
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE
+INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE
 #endif
+!
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ,JK
 ! ---------------------------------------------------------------------------
 
 !$acc data present( PDXX, PDYY, PDZZ, PDZX, PDZY,                    &
@@ -161,18 +172,29 @@ if ( mppdb_initialized ) then
   call Mppdb_check( ptrh, "Turb_hor_tke beg:ptrh" )
 end if
 
-allocate( zflx (size( ptkem, 1 ), size( ptkem, 2 ), size( ptkem, 3 ) ) )
+JIU =  size(ptkem, 1 )
+JJU =  size(ptkem, 2 )
+JKU =  size(ptkem, 3 )
+
+#ifndef MNH_OPENACC
+allocate( zflx (JIU,JJU,JKU ) )
+
+allocate( zcoeff(JIU,JJU, 1 + jpvext : 3 + jpvext ) )
+#else
+izflx   = MNH_ALLOCATE_ZT3D( zflx ,JIU,JJU,JKU )
+
+izcoeff = MNH_ALLOCATE_ZT3DP( zcoeff,JIU,JJU, 1 + jpvext , 3 + jpvext )
+#endif
 
-allocate( zcoeff(size( pdzz, 1 ), size( pdzz, 2 ), 1 + jpvext : 3 + jpvext ) )
 
 #ifdef MNH_OPENACC
-allocate( ztmp1_device(size( ptkem, 1 ), size( ptkem, 2 ), size( ptkem, 3 ) ) )
-allocate( ztmp2_device(size( ptkem, 1 ), size( ptkem, 2 ), size( ptkem, 3 ) ) )
-allocate( ztmp3_device(size( ptkem, 1 ), size( ptkem, 2 ), size( ptkem, 3 ) ) )
-allocate( ztmp4_device(size( ptkem, 1 ), size( ptkem, 2 ), size( ptkem, 3 ) ) )
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU)
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU)
+iztmp3_device = MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU,JKU)
+iztmp4_device = MNH_ALLOCATE_ZT3D( ztmp4_device,JIU,JJU,JKU)
 #endif
 
-!$acc data create( ZCOEFF, ZFLX, &
+!$acc data present( ZCOEFF, ZFLX, &
 !$acc &            ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE )
 
 !
@@ -206,14 +228,20 @@ ZFLX = -XCET * MXM(PK) * GX_M_U(1,IKU,1,PTKEM,PDXX,PDZZ,PDZX) ! < u'e >
 CALL MXM_DEVICE(PK,ZTMP1_DEVICE)
 CALL GX_M_U_DEVICE(1,IKU,1,PTKEM,PDXX,PDZZ,PDZX,ZTMP2_DEVICE)
 !$acc kernels
-ZFLX = -XCET * ZTMP1_DEVICE * ZTMP2_DEVICE ! < u'e >
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZFLX(JI,JJ,JK) = -XCET * ZTMP1_DEVICE(JI,JJ,JK) * ZTMP2_DEVICE(JI,JJ,JK) ! < u'e >
+END DO !CONCURRENT    
 #endif
 !
 ! special case near the ground ( uncentred gradient )
 !
-ZFLX(:,:,IKB) =  ZCOEFF(:,:,IKB+2)*PTKEM(:,:,IKB+2)                     &
-               + ZCOEFF(:,:,IKB+1)*PTKEM(:,:,IKB+1)                     &
-               + ZCOEFF(:,:,IKB  )*PTKEM(:,:,IKB  )     
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+   ZFLX(JI,JJ,IKB) =  ZCOEFF(JI,JJ,IKB+2)*PTKEM(JI,JJ,IKB+2)                     &
+                 + ZCOEFF(JI,JJ,IKB+1)*PTKEM(JI,JJ,IKB+1)                     &
+                 + ZCOEFF(JI,JJ,IKB  )*PTKEM(JI,JJ,IKB  )
+END DO
 !$acc end kernels 
 !
 #ifndef MNH_OPENACC
@@ -263,23 +291,38 @@ END IF
 IF (.NOT. LFLAT) THEN
   CALL MXM_DEVICE(PRHODJ,ZTMP1_DEVICE)
   !$acc kernels
-  ZTMP2_DEVICE = ZTMP1_DEVICE * ZFLX * PINV_PDXX
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * ZFLX(JI,JJ,JK) * PINV_PDXX(JI,JJ,JK)
+  END DO !CONCURRENT   
   !$acc end kernels 
   CALL DXF_DEVICE(ZTMP2_DEVICE,ZTMP1_DEVICE)
   !$acc kernels
-  ZTMP2_DEVICE = ZFLX*PINV_PDXX
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = ZFLX(JI,JJ,JK)*PINV_PDXX(JI,JJ,JK)
+  END DO !CONCURRENT   
   !$acc end kernels 
   CALL MZM_DEVICE(ZTMP2_DEVICE,ZTMP3_DEVICE)
   !$acc kernels
-  ZTMP2_DEVICE = PDZX * ZTMP3_DEVICE
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = PDZX(JI,JJ,JK) * ZTMP3_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
   !$acc end kernels 
   CALL MXF_DEVICE( ZTMP2_DEVICE,ZTMP3_DEVICE)
   !$acc kernels
-  ZTMP2_DEVICE = PMZM_PRHODJ * ZTMP3_DEVICE * PINV_PDZZ
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = PMZM_PRHODJ(JI,JJ,JK) * ZTMP3_DEVICE(JI,JJ,JK) * PINV_PDZZ(JI,JJ,JK)
+  END DO !CONCURRENT   
   !$acc end kernels 
   CALL DZF_DEVICE(1,IKU,1,ZTMP2_DEVICE,ZTMP3_DEVICE)
   !$acc kernels
-  PTRH =-( ZTMP1_DEVICE - ZTMP3_DEVICE ) /PRHODJ
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     PTRH(JI,JJ,JK) =-( ZTMP1_DEVICE(JI,JJ,JK) - ZTMP3_DEVICE(JI,JJ,JK) ) /PRHODJ(JI,JJ,JK)
+  END DO !CONCURRENT   
   !$acc end kernels 
 ELSE
   CALL MXM_DEVICE(PRHODJ,ZTMP1_DEVICE)
@@ -319,12 +362,17 @@ IF (.NOT. L2D) THEN
 #else
   CALL MYM_DEVICE(PK,ZTMP1_DEVICE)
   CALL GY_M_V_DEVICE(1,IKU,1,PTKEM,PDYY,PDZZ,PDZY,ZTMP2_DEVICE)
-!$acc kernels
-  ZFLX =-XCET * ZTMP1_DEVICE * ZTMP2_DEVICE ! < v'e >
+  !$acc kernels
+  !$acc loop independent collapse(3)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+      ZFLX(JI,JJ,JK) =-XCET * ZTMP1_DEVICE(JI,JJ,JK) * ZTMP2_DEVICE(JI,JJ,JK) ! < v'e >
+   END DO !CONCURRENT   
+   !$acc end kernels  
 #endif
 !
 ! special case near the ground ( uncentred gradient )
 !
+!$acc kernels  
   ZFLX(:,:,IKB) =  ZCOEFF(:,:,IKB+2)*PTKEM(:,:,IKB+2)                     &
                  + ZCOEFF(:,:,IKB+1)*PTKEM(:,:,IKB+1)                     &
                  + ZCOEFF(:,:,IKB  )*PTKEM(:,:,IKB  )     
@@ -379,23 +427,39 @@ IF (.NOT. L2D) THEN
   IF (.NOT. LFLAT) THEN
     CALL MYM_DEVICE(PRHODJ,ZTMP1_DEVICE)
     !$acc kernels
-    ZTMP2_DEVICE = ZTMP1_DEVICE * ZFLX * PINV_PDYY
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * ZFLX(JI,JJ,JK) * PINV_PDYY(JI,JJ,JK)
+    END DO !CONCURRENT   
     !$acc end kernels 
     CALL DYF_DEVICE(ZTMP2_DEVICE,ZTMP1_DEVICE)
     !$acc kernels
-    ZTMP2_DEVICE = ZFLX*PINV_PDYY
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZFLX(JI,JJ,JK)*PINV_PDYY(JI,JJ,JK)
+    END DO !CONCURRENT   
     !$acc end kernels 
     CALL MZM_DEVICE(ZTMP2_DEVICE,ZTMP3_DEVICE)
     !$acc kernels
-    ZTMP2_DEVICE = PDZY * ZTMP3_DEVICE
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = PDZY(JI,JJ,JK) * ZTMP3_DEVICE(JI,JJ,JK)
+    END DO !CONCURRENT   
     !$acc end kernels 
     CALL MYF_DEVICE(ZTMP2_DEVICE,ZTMP3_DEVICE)
     !$acc kernels
-    ZTMP2_DEVICE = PMZM_PRHODJ * ZTMP3_DEVICE * PINV_PDZZ
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = PMZM_PRHODJ(JI,JJ,JK) * ZTMP3_DEVICE(JI,JJ,JK) * PINV_PDZZ(JI,JJ,JK)
+    END DO !CONCURRENT   
     !$acc end kernels 
     CALL DZF_DEVICE(1,IKU,1,ZTMP2_DEVICE,ZTMP3_DEVICE)
     !$acc kernels
-    PTRH = PTRH - (  ZTMP1_DEVICE - ZTMP3_DEVICE ) /PRHODJ
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       PTRH(JI,JJ,JK) = PTRH(JI,JJ,JK) - (  ZTMP1_DEVICE(JI,JJ,JK) - ZTMP3_DEVICE(JI,JJ,JK) ) &
+            /PRHODJ(JI,JJ,JK)
+    END DO !CONCURRENT   
     !$acc end kernels 
   ELSE
     CALL MYM_DEVICE(PRHODJ,ZTMP1_DEVICE)
@@ -434,6 +498,13 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate( ZCOEFF, ZFLX )
+#else
+CALL MNH_REL_ZT3D( IZFLX, IZCOEFF, &
+                   IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE )
+#endif
+
 !$acc end data
 
 !----------------------------------------------------------------------------
diff --git a/src/MNH/turb_hor_uv.f90 b/src/MNH/turb_hor_uv.f90
index 1703f6ce3d5168b9e76cf331eef5466b2facaa74..b987f77fddcf1da56a202c4de8447b7b0057a25e 100644
--- a/src/MNH/turb_hor_uv.f90
+++ b/src/MNH/turb_hor_uv.f90
@@ -154,6 +154,10 @@ USE MODI_SECOND_MNH
 USE MODI_BITREP
 #endif
 !
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_ZT3DP , MNH_ALLOCATE_ZT2D
+#endif
+!
 IMPLICIT NONE
 !
 !
@@ -203,30 +207,38 @@ REAL, DIMENSION(:,:,:),   INTENT(INOUT) ::  PDP          ! TKE production terms
 !
 !*       0.2  declaration of local variables
 !
-REAL, DIMENSION(:,:,:), allocatable :: ZFLX,ZWORK ! work arrays
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZFLX,ZWORK ! work arrays
 !
-REAL, DIMENSION(:,:),   allocatable :: ZDIRSINZW
+REAL, DIMENSION(:,:),   pointer , contiguous :: ZDIRSINZW
       ! sinus of the angle between the vertical and the normal to the orography
 INTEGER             :: IKB,IKE
                                     ! Index values for the Beginning and End
                                     ! mass points of the domain  
 !
-REAL, DIMENSION(:,:,:), allocatable :: GY_U_UV_PUM
-REAL, DIMENSION(:,:,:), allocatable :: GX_V_UV_PVM
+REAL, DIMENSION(:,:,:), pointer , contiguous :: GY_U_UV_PUM
+REAL, DIMENSION(:,:,:), pointer , contiguous :: GX_V_UV_PVM
+#ifdef MNH_OPENACC
+INTEGER :: IZFLX,IZWORK,IZDIRSINZW,IGY_U_UV_PUM,IGX_V_UV_PVM
+#endif
 !
 REAL :: ZTIME1, ZTIME2
 !
 #ifdef MNH_OPENACC
 INTEGER :: IKU
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP2_DEVICE
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP3_DEVICE
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP4_DEVICE
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP5_DEVICE
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP6_DEVICE
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP7_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP2_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP3_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP4_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP5_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP6_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP7_DEVICE
+INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE,&
+           IZTMP5_DEVICE,IZTMP6_DEVICE,IZTMP7_DEVICE
 #endif
 TYPE(TFIELDDATA) :: TZFIELD
+!
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ,JK
 ! ---------------------------------------------------------------------------
 
 !$acc data present( PK, PINV_PDXX, PINV_PDYY, PINV_PDZZ, PMZM_PRHODJ, PDXX, PDYY, PDZZ, PDZX, PDZY,       &
@@ -265,25 +277,39 @@ if ( mppdb_initialized ) then
   call Mppdb_check( pdp,    "Turb_hor_uv beg:pdp"    )
 end if
 
-allocate( zflx (size( pum, 1 ), size( pum, 2 ), size( pum, 3 ) ) )
-allocate( zwork(size( pum, 1 ), size( pum, 2 ), size( pum, 3 ) ) )
+JIU =  size(pum, 1 )
+JJU =  size(pum, 2 )
+JKU =  size(pum, 3 )
+
+#ifndef MNH_OPENACC
+allocate( zflx (JIU,JJU,JKU ) )
+allocate( zwork(JIU,JJU,JKU ) )
+
+allocate( zdirsinzw(JIU,JJU ) )
 
-allocate( zdirsinzw(size( pum, 1 ), size( pum, 2 ) ) )
+allocate( gy_u_uv_pum(JIU,JJU,JKU ) )
+allocate( gx_v_uv_pvm(JIU,JJU,JKU ) )
+#else
+izflx = MNH_ALLOCATE_ZT3D( zflx ,JIU,JJU,JKU )
+izwork = MNH_ALLOCATE_ZT3D( zwork,JIU,JJU,JKU )
+
+izdirsinzw = MNH_ALLOCATE_ZT2D( zdirsinzw,JIU,JJU )
 
-allocate( gy_u_uv_pum(size( pum, 1 ), size( pum, 2 ), size( pum, 3 ) ) )
-allocate( gx_v_uv_pvm(size( pvm, 1 ), size( pvm, 2 ), size( pvm, 3 ) ) )
+igy_u_uv_pum = MNH_ALLOCATE_ZT3D( gy_u_uv_pum,JIU,JJU,JKU )
+igx_v_uv_pvm = MNH_ALLOCATE_ZT3D( gx_v_uv_pvm,JIU,JJU,JKU )
+#endif
 
 #ifdef MNH_OPENACC
-allocate( ztmp1_device(size( pum, 1 ), size( pum, 2 ), size( pum, 3 ) ) )
-allocate( ztmp2_device(size( pum, 1 ), size( pum, 2 ), size( pum, 3 ) ) )
-allocate( ztmp3_device(size( pum, 1 ), size( pum, 2 ), size( pum, 3 ) ) )
-allocate( ztmp4_device(size( pum, 1 ), size( pum, 2 ), size( pum, 3 ) ) )
-allocate( ztmp5_device(size( pum, 1 ), size( pum, 2 ), size( pum, 3 ) ) )
-allocate( ztmp6_device(size( pum, 1 ), size( pum, 2 ), size( pum, 3 ) ) )
-allocate( ztmp7_device(size( pum, 1 ), size( pum, 2 ), size( pum, 3 ) ) )
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU )
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU )
+iztmp3_device = MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU,JKU )
+iztmp4_device = MNH_ALLOCATE_ZT3D( ztmp4_device,JIU,JJU,JKU )
+iztmp5_device = MNH_ALLOCATE_ZT3D( ztmp5_device,JIU,JJU,JKU )
+iztmp6_device = MNH_ALLOCATE_ZT3D( ztmp6_device,JIU,JJU,JKU )
+iztmp7_device = MNH_ALLOCATE_ZT3D( ztmp7_device,JIU,JJU,JKU )
 #endif
 
-!$acc data create( ZFLX, ZWORK, ZDIRSINZW, GY_U_UV_PUM, GX_V_UV_PVM,       &
+!$acc data present( ZFLX, ZWORK, ZDIRSINZW, GY_U_UV_PUM, GX_V_UV_PVM,       &
 !$acc &            ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE, &
 !$acc &            ZTMP5_DEVICE, ZTMP6_DEVICE, ZTMP7_DEVICE                )
 
@@ -298,11 +324,14 @@ IKU = NKMAX + 2 * JPVEXT
 #endif
 !
 !$acc kernels
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
 #ifndef MNH_BITREP
-ZDIRSINZW(:,:) = SQRT( 1. - PDIRCOSZW(:,:)**2 )
+  ZDIRSINZW(JI,JJ) = SQRT( 1. - PDIRCOSZW(JI,JJ)**2 )
 #else
-ZDIRSINZW(:,:) = SQRT( 1. - BR_P2(PDIRCOSZW(:,:)) )
+  ZDIRSINZW(JI,JJ) = SQRT( 1. - BR_P2(PDIRCOSZW(JI,JJ)) )
 #endif
+END DO
 !$acc end kernels
 !
 #ifndef MNH_OPENACC
@@ -333,7 +362,10 @@ CALL MXM_DEVICE(PK,ZTMP1_DEVICE)
 CALL MYM_DEVICE(ZTMP1_DEVICE,ZTMP2_DEVICE)
 IF (.NOT. L2D) THEN
   !$acc kernels
-  ZFLX(:,:,:)= - XCMFS * ZTMP2_DEVICE * (GY_U_UV_PUM + GX_V_UV_PVM)
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+    ZFLX(JI,JJ,JK)= - XCMFS * ZTMP2_DEVICE(JI,JJ,JK) * (GY_U_UV_PUM(JI,JJ,JK) + GX_V_UV_PVM(JI,JJ,JK))
+  END DO !CONCURRENT   
   !$acc end kernels
 ELSE
   !$acc kernels
@@ -426,16 +458,19 @@ ZFLX(:,:,IKB-1) =                                                           &
           PDIRCOSZW(:,:) * ZDIRSINZW(:,:)                                     &
     +PVSLOPEM(:,:) * (PCOSSLOPE(:,:)**2 - PSINSLOPE(:,:)**2) * ZDIRSINZW(:,:) )
 #else
-ZFLX(:,:,IKB-1) =                                                           &
-   PTAU11M(:,:) * PCOSSLOPE(:,:) * PSINSLOPE(:,:) * BR_P2(PDIRCOSZW(:,:))     &
-  +PTAU12M(:,:) * (BR_P2(PCOSSLOPE(:,:)) - BR_P2(PSINSLOPE(:,:))) *           &
-                  BR_P2(PDIRCOSZW(:,:))                                       &
-  -PTAU22M(:,:) * PCOSSLOPE(:,:) * PSINSLOPE(:,:)                             &
-  +PTAU33M(:,:) * PCOSSLOPE(:,:) * PSINSLOPE(:,:) * BR_P2(ZDIRSINZW(:,:))     &
-  -PCDUEFF(:,:) * (                                                           &
-    2. * PUSLOPEM(:,:) * PCOSSLOPE(:,:) * PSINSLOPE(:,:) *                    &
-          PDIRCOSZW(:,:) * ZDIRSINZW(:,:)                                     &
-    +PVSLOPEM(:,:) * (BR_P2(PCOSSLOPE(:,:)) - BR_P2(PSINSLOPE(:,:))) * ZDIRSINZW(:,:) )
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+ZFLX(JI,JJ,IKB-1) =                                                           &
+   PTAU11M(JI,JJ) * PCOSSLOPE(JI,JJ) * PSINSLOPE(JI,JJ) * BR_P2(PDIRCOSZW(JI,JJ))     &
+  +PTAU12M(JI,JJ) * (BR_P2(PCOSSLOPE(JI,JJ)) - BR_P2(PSINSLOPE(JI,JJ))) *           &
+                  BR_P2(PDIRCOSZW(JI,JJ))                                       &
+  -PTAU22M(JI,JJ) * PCOSSLOPE(JI,JJ) * PSINSLOPE(JI,JJ)                             &
+  +PTAU33M(JI,JJ) * PCOSSLOPE(JI,JJ) * PSINSLOPE(JI,JJ) * BR_P2(ZDIRSINZW(JI,JJ))     &
+  -PCDUEFF(JI,JJ) * (                                                           &
+    2. * PUSLOPEM(JI,JJ) * PCOSSLOPE(JI,JJ) * PSINSLOPE(JI,JJ) *                    &
+          PDIRCOSZW(JI,JJ) * ZDIRSINZW(JI,JJ)                                     &
+          +PVSLOPEM(JI,JJ) * (BR_P2(PCOSSLOPE(JI,JJ)) - BR_P2(PSINSLOPE(JI,JJ))) * ZDIRSINZW(JI,JJ) )
+END DO ! CONCURRENT
 #endif
 !$acc end kernels
 !  
@@ -481,35 +516,56 @@ END IF
 #else
 CALL MYM_DEVICE(PRHODJ,ZTMP1_DEVICE)
 !$acc kernels
-ZTMP2_DEVICE = ZTMP1_DEVICE * PINV_PDYY
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * PINV_PDYY(JI,JJ,JK)
+END DO !CONCURRENT   
 !$acc end kernels
 CALL MXM_DEVICE(ZTMP2_DEVICE,ZTMP1_DEVICE) 
 !$acc kernels
-ZTMP2_DEVICE = ZFLX * ZTMP1_DEVICE
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZTMP2_DEVICE(JI,JJ,JK) = ZFLX(JI,JJ,JK) * ZTMP1_DEVICE(JI,JJ,JK)
+END DO !CONCURRENT   
 !$acc end kernels
 CALL DYF_DEVICE(ZTMP2_DEVICE,ZTMP1_DEVICE)
 IF (.NOT. LFLAT) THEN
   CALL MZM_DEVICE(ZFLX,ZTMP2_DEVICE)
   CALL MZM_DEVICE(PDYY,ZTMP3_DEVICE)
-!$acc kernels
-  ZTMP4_DEVICE = PDZY/ZTMP3_DEVICE
-!$acc end kernels
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP4_DEVICE(JI,JJ,JK) = PDZY(JI,JJ,JK)/ZTMP3_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
+  !$acc end kernels
   CALL MXM_DEVICE(ZTMP4_DEVICE,ZTMP5_DEVICE)
-!$acc kernels
-  ZTMP4_DEVICE = ZTMP2_DEVICE*ZTMP5_DEVICE
-!$acc end kernels
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP4_DEVICE(JI,JJ,JK) = ZTMP2_DEVICE(JI,JJ,JK)*ZTMP5_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
+  !$acc end kernels
   CALL MYF_DEVICE(ZTMP4_DEVICE,ZTMP2_DEVICE)
-!$acc kernels
-  ZTMP3_DEVICE = PMZM_PRHODJ * PINV_PDZZ
-!$acc end kernels
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP3_DEVICE(JI,JJ,JK) = PMZM_PRHODJ(JI,JJ,JK) * PINV_PDZZ(JI,JJ,JK)
+  END DO !CONCURRENT   
+  !$acc end kernels
   CALL MXM_DEVICE(ZTMP3_DEVICE,ZTMP4_DEVICE)
-!$acc kernels
-  ZTMP5_DEVICE = ZTMP2_DEVICE*ZTMP4_DEVICE
-!$acc end kernels
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP5_DEVICE(JI,JJ,JK) = ZTMP2_DEVICE(JI,JJ,JK)*ZTMP4_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT    
+  !$acc end kernels
   CALL DZF_DEVICE(1,IKU,1,ZTMP5_DEVICE,ZTMP3_DEVICE)
-!$acc kernels
-  PRUS(:,:,:) = PRUS(:,:,:) - ZTMP1_DEVICE + ZTMP3_DEVICE
-!$acc end kernels
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     PRUS(JI,JJ,JK) = PRUS(JI,JJ,JK) - ZTMP1_DEVICE(JI,JJ,JK) + ZTMP3_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
+  !$acc end kernels
 ELSE
 !$acc kernels
   PRUS(:,:,:) = PRUS(:,:,:) - ZTMP1_DEVICE
@@ -530,35 +586,56 @@ END IF
 #else
 CALL MXM_DEVICE(PRHODJ,ZTMP1_DEVICE)
 !$acc kernels
-ZTMP2_DEVICE = ZTMP1_DEVICE * PINV_PDXX
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * PINV_PDXX(JI,JJ,JK)
+END DO !CONCURRENT   
 !$acc end kernels
 CALL MYM_DEVICE(ZTMP2_DEVICE,ZTMP1_DEVICE) 
 !$acc kernels
-ZTMP2_DEVICE = ZFLX * ZTMP1_DEVICE
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZTMP2_DEVICE(JI,JJ,JK) = ZFLX(JI,JJ,JK) * ZTMP1_DEVICE(JI,JJ,JK)
+END DO !CONCURRENT   
 !$acc end kernels
 CALL DXF_DEVICE(ZTMP2_DEVICE,ZTMP1_DEVICE)
 IF (.NOT. LFLAT) THEN
   CALL MZM_DEVICE(ZFLX,ZTMP2_DEVICE)
   CALL MZM_DEVICE(PDXX,ZTMP3_DEVICE)
-!$acc kernels
-  ZTMP4_DEVICE = PDZX/ZTMP3_DEVICE
-!$acc end kernels
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP4_DEVICE(JI,JJ,JK) = PDZX(JI,JJ,JK)/ZTMP3_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
+  !$acc end kernels
   CALL MYM_DEVICE(ZTMP4_DEVICE,ZTMP5_DEVICE)
-!$acc kernels
-  ZTMP4_DEVICE = ZTMP2_DEVICE*ZTMP5_DEVICE
-!$acc end kernels
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP4_DEVICE(JI,JJ,JK) = ZTMP2_DEVICE(JI,JJ,JK)*ZTMP5_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
+  !$acc end kernels
   CALL MXF_DEVICE(ZTMP4_DEVICE,ZTMP2_DEVICE)
-!$acc kernels
-  ZTMP3_DEVICE = PMZM_PRHODJ * PINV_PDZZ
-!$acc end kernels
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP3_DEVICE(JI,JJ,JK) = PMZM_PRHODJ(JI,JJ,JK) * PINV_PDZZ(JI,JJ,JK)
+  END DO !CONCURRENT   
+  !$acc end kernels
   CALL MYM_DEVICE(ZTMP3_DEVICE,ZTMP4_DEVICE)
-!$acc kernels
-  ZTMP5_DEVICE = ZTMP2_DEVICE*ZTMP4_DEVICE
-!$acc end kernels
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP5_DEVICE(JI,JJ,JK) = ZTMP2_DEVICE(JI,JJ,JK)*ZTMP4_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
+  !$acc end kernels
   CALL DZF_DEVICE(1,IKU,1,ZTMP5_DEVICE,ZTMP3_DEVICE)
-!$acc kernels
-  PRVS(:,:,:) = PRVS(:,:,:) - ZTMP1_DEVICE + ZTMP3_DEVICE
-!$acc end kernels
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     PRVS(JI,JJ,JK) = PRVS(JI,JJ,JK) - ZTMP1_DEVICE(JI,JJ,JK) + ZTMP3_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
+  !$acc end kernels
 ELSE
 !$acc kernels
   PRVS(:,:,:) = PRVS(:,:,:) - ZTMP1_DEVICE
@@ -580,8 +657,11 @@ IF (KSPLT==1) THEN
   ENDIF
 #else
   IF (.NOT. L2D) THEN
-!$acc kernels
-    ZTMP1_DEVICE = ZFLX * (GY_U_UV_PUM + GX_V_UV_PVM)
+     !$acc kernels
+     !$acc loop independent collapse(3)
+     DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+        ZTMP1_DEVICE(JI,JJ,JK) = ZFLX(JI,JJ,JK) * (GY_U_UV_PUM(JI,JJ,JK) + GX_V_UV_PVM(JI,JJ,JK))
+     END DO !CONCURRENT   
 !$acc end kernels
   ELSE
 !$acc kernels
@@ -590,9 +670,12 @@ IF (KSPLT==1) THEN
   ENDIF
   CALL MYF_DEVICE(ZTMP1_DEVICE,ZTMP2_DEVICE)
   CALL MXF_DEVICE(ZTMP2_DEVICE,ZTMP1_DEVICE)
-!$acc kernels
-  ZWORK(:,:,:) = - ZTMP1_DEVICE
-!$acc end kernels
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZWORK(JI,JJ,JK) = - ZTMP1_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
+  !$acc end kernels
 #endif
   !
   ! evaluate the dynamic production at w(IKB+1) in PDP(IKB)
@@ -614,9 +697,9 @@ IF (KSPLT==1) THEN
         ) / MXF(MYM( 0.5*(PDXX(:,:,IKB:IKB)+PDXX(:,:,IKB+1:IKB+1)) ) )&
     ) 
 #else
-!$acc kernels
+  !$acc kernels
   ZTMP1_DEVICE(:,:,1) = 0.5 * (ZFLX(:,:,IKB+1)+ZFLX(:,:,IKB))
-!$acc end kernels
+  !$acc end kernels
   CALL MYF_DEVICE(ZTMP1_DEVICE(:,:,1:1),ZTMP2_DEVICE(:,:,1:1))
   CALL MXF_DEVICE(ZTMP2_DEVICE(:,:,1:1),ZTMP1_DEVICE(:,:,1:1))
   !
@@ -714,6 +797,15 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate ( ZFLX, ZWORK, ZDIRSINZW, GY_U_UV_PUM, GX_V_UV_PVM )
+#else
+CALL MNH_REL_ZT3D ( IZFLX, IZWORK, IZDIRSINZW, IGY_U_UV_PUM, IGX_V_UV_PVM, &
+            IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE, &
+            IZTMP5_DEVICE, IZTMP6_DEVICE, IZTMP7_DEVICE                )
+#endif
+     
+
 !$acc end data
 
 END SUBROUTINE TURB_HOR_UV
diff --git a/src/MNH/turb_hor_uw.f90 b/src/MNH/turb_hor_uw.f90
index f6e5b972cc48f6448a60f8926e8b3f8ce09b2c13..eed50515aed65393f3986ab1b9faba7fca70af2d 100644
--- a/src/MNH/turb_hor_uw.f90
+++ b/src/MNH/turb_hor_uw.f90
@@ -137,7 +137,11 @@ USE MODI_COEFJ
 USE MODI_LES_MEAN_SUBGRID
 !
 USE MODI_SECOND_MNH
-!
+
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_ZT3DP , MNH_ALLOCATE_ZT2D
+#endif
+
 IMPLICIT NONE
 !
 !
@@ -175,24 +179,31 @@ REAL, DIMENSION(:,:,:),   INTENT(INOUT) ::  PDP          ! TKE production terms
 !
 !*       0.2  declaration of local variables
 !
-REAL, DIMENSION(:,:,:), allocatable :: ZFLX,ZWORK ! work arrays
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZFLX,ZWORK ! work arrays
 !
 INTEGER             :: IKB,IKE,IKU
                                     ! Index values for the Beginning and End
                                     ! mass points of the domain  
 INTEGER             :: JSV          ! scalar loop counter
 !
-REAL, DIMENSION(:,:,:), allocatable :: GX_W_UW_PWM
+REAL, DIMENSION(:,:,:), pointer , contiguous :: GX_W_UW_PWM
+#ifdef MNH_OPENACC
+INTEGER :: IZFLX,IZWORK,IGX_W_UW_PWM
+#endif
 !
 REAL :: ZTIME1, ZTIME2
 !
 #ifdef MNH_OPENACC
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP2_DEVICE
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP3_DEVICE
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP4_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP2_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP3_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP4_DEVICE
+INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE
 #endif
 TYPE(TFIELDDATA) :: TZFIELD
+!
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ,JK
 ! ---------------------------------------------------------------------------
 
 !$acc data present( PK, PINV_PDXX, PINV_PDZZ, PMZM_PRHODJ, PDXX, PDZZ, PDZX, &
@@ -224,19 +235,30 @@ if ( mppdb_initialized ) then
   call Mppdb_check( pdp,  "Turb_hor_uw beg:pdp"  )
 end if
 
-allocate( zflx (size( pwm, 1 ), size( pwm, 2 ), size( pwm, 3 ) ) )
-allocate( zwork(size( pwm, 1 ), size( pwm, 2 ), size( pwm, 3 ) ) )
+JIU =  size(pwm, 1 )
+JJU =  size(pwm, 2 )
+JKU =  size(pwm, 3 )
+
+#ifndef MNH_OPENACC
+allocate( zflx (JIU,JJU,JKU ) )
+allocate( zwork(JIU,JJU,JKU ) )
+
+allocate( gx_w_uw_pwm(JIU,JJU,JKU ) )
+#else
+izflx        = MNH_ALLOCATE_ZT3D( zflx ,JIU,JJU,JKU)
+izwork       = MNH_ALLOCATE_ZT3D( zwork,JIU,JJU,JKU)
 
-allocate( gx_w_uw_pwm(size( pwm, 1 ), size( pwm, 2 ), size( pwm, 3 ) ) )
+igx_w_uw_pwm = MNH_ALLOCATE_ZT3D( gx_w_uw_pwm,JIU,JJU,JKU)
+#endif
 
 #ifdef MNH_OPENACC
-allocate( ztmp1_device(size( pwm, 1 ), size( pwm, 2 ), size( pwm, 3 ) ) )
-allocate( ztmp2_device(size( pwm, 1 ), size( pwm, 2 ), size( pwm, 3 ) ) )
-allocate( ztmp3_device(size( pwm, 1 ), size( pwm, 2 ), size( pwm, 3 ) ) )
-allocate( ztmp4_device(size( pwm, 1 ), size( pwm, 2 ), size( pwm, 3 ) ) )
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU)
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU)
+iztmp3_device = MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU,JKU)
+iztmp4_device = MNH_ALLOCATE_ZT3D( ztmp4_device,JIU,JJU,JKU)
 #endif
 
-!$acc data create( ZFLX, ZWORK, GX_W_UW_PWM, &
+!$acc data present( ZFLX, ZWORK, GX_W_UW_PWM, &
 !$acc &            ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE )
 
 !
@@ -267,7 +289,10 @@ ZFLX(:,:,:) =                                                      &
 CALL MZM_DEVICE(PK,ZTMP1_DEVICE)
 CALL MXM_DEVICE(ZTMP1_DEVICE,ZTMP2_DEVICE)
 !$acc kernels
-ZFLX(:,:,:) = - XCMFS * ZTMP2_DEVICE * GX_W_UW_PWM
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZFLX(JI,JJ,JK) = - XCMFS * ZTMP2_DEVICE(JI,JJ,JK) * GX_W_UW_PWM(JI,JJ,JK)
+END DO !CONCURRENT   
 #endif
 !!         &  to be tested
 !!  - (2./3.) * XCMFB * MZM( ZVPTU * MXM( PLM / SQRT(PTKEM) * XG / PTHVREF ) )
@@ -305,11 +330,17 @@ PRUS(:,:,:) = PRUS(:,:,:) - DZF( ZFLX* MXM( PMZM_PRHODJ ) / MXM( PDZZ ) )
 CALL MXM_DEVICE( PMZM_PRHODJ, ZTMP1_DEVICE )
 CALL MXM_DEVICE( PDZZ, ZTMP2_DEVICE )
 !$acc kernels
-ZTMP3_DEVICE = ZFLX* ZTMP1_DEVICE / ZTMP2_DEVICE
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZTMP3_DEVICE(JI,JJ,JK) = ZFLX(JI,JJ,JK)* ZTMP1_DEVICE(JI,JJ,JK) / ZTMP2_DEVICE(JI,JJ,JK)
+END DO !CONCURRENT   
 !$acc end kernels
 CALL DZF_DEVICE(1,IKU,1, ZTMP3_DEVICE, ZTMP1_DEVICE )
 !$acc kernels
-PRUS(:,:,:) = PRUS(:,:,:) - ZTMP1_DEVICE(:,:,:)
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   PRUS(JI,JJ,JK) = PRUS(JI,JJ,JK) - ZTMP1_DEVICE(JI,JJ,JK)
+END DO !CONCURRENT   
 !$acc end kernels
 #endif
 !
@@ -325,32 +356,50 @@ END IF
 #else
   CALL MXM_DEVICE(PRHODJ,ZTMP1_DEVICE)
   !$acc kernels
-  ZTMP2_DEVICE = ZTMP1_DEVICE * PINV_PDXX
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * PINV_PDXX(JI,JJ,JK)
+  END DO !CONCURRENT   
   !$acc end kernels
   CALL MZM_DEVICE(ZTMP2_DEVICE, ZTMP1_DEVICE)
   !$acc kernels
-  ZTMP2_DEVICE = ZTMP1_DEVICE * ZFLX
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * ZFLX(JI,JJ,JK)
+  END DO !CONCURRENT   
   !$acc end kernels
   CALL DXF_DEVICE( ZTMP2_DEVICE,ZTMP1_DEVICE)
 IF (.NOT. LFLAT) THEN
-  !$acc kernels
-  ZTMP2_DEVICE = ZFLX*PDZX
-  !$acc end kernels
-  CALL MZF_DEVICE(1,IKU,1, ZTMP2_DEVICE, ZTMP3_DEVICE )
-  !$acc kernels
-  ZTMP2_DEVICE = ZTMP3_DEVICE*PINV_PDXX
-  !$acc end kernels
-  CALL MXF_DEVICE( ZTMP2_DEVICE, ZTMP3_DEVICE )
-  CALL MZF_DEVICE(1,IKU,1,PDZZ, ZTMP2_DEVICE)
-  !$acc kernels
-  ZTMP4_DEVICE = PRHODJ * ZTMP3_DEVICE / ZTMP2_DEVICE
-  !$acc end kernels
-  CALL DZM_DEVICE(1,IKU,1, ZTMP4_DEVICE, ZTMP2_DEVICE )
-  !$acc kernels
-  PRWS(:,:,:) = PRWS(:,:,:)                              &
-        - ZTMP1_DEVICE           &
-        + ZTMP2_DEVICE
-  !$acc end kernels
+   !$acc kernels
+   !$acc loop independent collapse(3)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+      ZTMP2_DEVICE(JI,JJ,JK) = ZFLX(JI,JJ,JK)*PDZX(JI,JJ,JK)
+   END DO !CONCURRENT   
+   !$acc end kernels
+   CALL MZF_DEVICE(1,IKU,1, ZTMP2_DEVICE, ZTMP3_DEVICE )
+   !$acc kernels
+   !$acc loop independent collapse(3)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = ZTMP3_DEVICE(JI,JJ,JK)*PINV_PDXX(JI,JJ,JK)
+   END DO !CONCURRENT  
+   !$acc end kernels
+   CALL MXF_DEVICE( ZTMP2_DEVICE, ZTMP3_DEVICE )
+   CALL MZF_DEVICE(1,IKU,1,PDZZ, ZTMP2_DEVICE)
+   !$acc kernels
+   !$acc loop independent collapse(3)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+      ZTMP4_DEVICE(JI,JJ,JK) = PRHODJ(JI,JJ,JK) * ZTMP3_DEVICE(JI,JJ,JK) / ZTMP2_DEVICE(JI,JJ,JK)
+   END DO !CONCURRENT   
+   !$acc end kernels
+   CALL DZM_DEVICE(1,IKU,1, ZTMP4_DEVICE, ZTMP2_DEVICE )
+   !$acc kernels
+   !$acc loop independent collapse(3)
+   DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+      PRWS(JI,JJ,JK) = PRWS(JI,JJ,JK)         &
+           - ZTMP1_DEVICE(JI,JJ,JK)           &
+           + ZTMP2_DEVICE(JI,JJ,JK)
+   END DO !CONCURRENT
+   !$acc end kernels
 ELSE 
   !$acc kernels
   PRWS(:,:,:) = PRWS(:,:,:) - ZTMP1_DEVICE
@@ -368,12 +417,18 @@ IF (KSPLT==1) THEN
 #else
   CALL GZ_U_UW_DEVICE(1,IKU,1,PUM,PDZZ,ZTMP1_DEVICE)
   !$acc kernels
-  ZTMP2_DEVICE = ZFLX *( ZTMP1_DEVICE + GX_W_UW_PWM )
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = ZFLX(JI,JJ,JK) *( ZTMP1_DEVICE(JI,JJ,JK) + GX_W_UW_PWM(JI,JJ,JK) )
+  END DO !CONCURRENT   
   !$acc end kernels
   CALL MXF_DEVICE( ZTMP2_DEVICE,ZTMP1_DEVICE )
   CALL MZF_DEVICE(1,IKU,1, ZTMP1_DEVICE, ZTMP2_DEVICE )
   !$acc kernels
-  ZWORK(:,:,:) = -ZTMP2_DEVICE(:,:,:)
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZWORK(JI,JJ,JK) = -ZTMP2_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
   !$acc end kernels
 #endif
   !
@@ -514,6 +569,13 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate( ZFLX, ZWORK, GX_W_UW_PWM )
+#else
+CALL MNH_REL_ZT3D ( IZFLX, IZWORK, IGX_W_UW_PWM, &
+                    IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE )
+#endif
+
 !$acc end data
 
 END SUBROUTINE TURB_HOR_UW
diff --git a/src/MNH/turb_hor_vw.f90 b/src/MNH/turb_hor_vw.f90
index 0bc690ba35dbafc05a8bbeaae49e2797ceff88b3..98342494cc0485c71bab8a1a64618f65c8615b94 100644
--- a/src/MNH/turb_hor_vw.f90
+++ b/src/MNH/turb_hor_vw.f90
@@ -136,7 +136,11 @@ USE MODI_COEFJ
 USE MODI_LES_MEAN_SUBGRID
 !
 USE MODI_SECOND_MNH
-!
+
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_ZT3DP , MNH_ALLOCATE_ZT2D
+#endif
+
 IMPLICIT NONE
 !
 !
@@ -173,24 +177,31 @@ REAL, DIMENSION(:,:,:),   INTENT(INOUT) ::  PDP          ! TKE production terms
 !
 !*       0.2  declaration of local variables
 !
-REAL, DIMENSION(:,:,:), allocatable :: ZFLX,ZWORK ! work arrays
-!! REAL, DIMENSION(:,:,:), allocatable :: ZVPTV
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZFLX,ZWORK ! work arrays
+!! REAL, DIMENSION(:,:,:), pointer , contiguous :: ZVPTV
 INTEGER             :: IKB,IKE,IKU
                                     ! Index values for the Beginning and End
                                     ! mass points of the domain  
 INTEGER             :: JSV          ! scalar loop counter
 !
-REAL, DIMENSION(:,:,:), allocatable :: GY_W_VW_PWM
+REAL, DIMENSION(:,:,:), pointer , contiguous :: GY_W_VW_PWM
+#ifdef MNH_OPENACC
+INTEGER :: IZFLX,IZWORK,IGY_W_VW_PWM
+#endif
 !
 REAL :: ZTIME1, ZTIME2
 !
 #ifdef MNH_OPENACC
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP2_DEVICE
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP3_DEVICE
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP4_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP2_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP3_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP4_DEVICE
+INTEGER :: IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE
 #endif
 TYPE(TFIELDDATA) :: TZFIELD
+!
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ,JK
 ! ---------------------------------------------------------------------------
 
 !$acc data present( PK, PINV_PDYY, PINV_PDZZ, PMZM_PRHODJ, PDYY, PDZZ, PDZY, &
@@ -221,19 +232,30 @@ if ( mppdb_initialized ) then
   call Mppdb_check( pdp,  "Turb_hor_vw beg:pdp"  )
 end if
 
-allocate( zflx (size( pwm, 1 ), size( pwm, 2 ), size( pwm, 3 ) ) )
-allocate( zwork(size( pwm, 1 ), size( pwm, 2 ), size( pwm, 3 ) ) )
+JIU =  size(pwm, 1 )
+JJU =  size(pwm, 2 )
+JKU =  size(pwm, 3 )
+
+#ifndef MNH_OPENACC
+allocate( zflx (JIU,JJU,JKU ) )
+allocate( zwork(JIU,JJU,JKU ) )
 
-allocate( gy_w_vw_pwm(size( pwm, 1 ), size( pwm, 2 ), size( pwm, 3 ) ) )
+allocate( gy_w_vw_pwm(JIU,JJU,JKU ) )
+#else
+izflx        = MNH_ALLOCATE_ZT3D( zflx ,JIU,JJU,JKU)
+izwork       = MNH_ALLOCATE_ZT3D( zwork,JIU,JJU,JKU)
+
+igy_w_vw_pwm = MNH_ALLOCATE_ZT3D( gy_w_vw_pwm,JIU,JJU,JKU)
+#endif
 
 #ifdef MNH_OPENACC
-allocate( ztmp1_device(size( pwm, 1 ), size( pwm, 2 ), size( pwm, 3 ) ) )
-allocate( ztmp2_device(size( pwm, 1 ), size( pwm, 2 ), size( pwm, 3 ) ) )
-allocate( ztmp3_device(size( pwm, 1 ), size( pwm, 2 ), size( pwm, 3 ) ) )
-allocate( ztmp4_device(size( pwm, 1 ), size( pwm, 2 ), size( pwm, 3 ) ) )
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU)
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU)
+iztmp3_device = MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU,JKU)
+iztmp4_device = MNH_ALLOCATE_ZT3D( ztmp4_device,JIU,JJU,JKU)
 #endif
 
-!$acc data create( ZFLX, ZWORK, GY_W_VW_PWM, &
+!$acc data present( ZFLX, ZWORK, GY_W_VW_PWM, &
 !$acc &            ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE )
 
 !
@@ -266,9 +288,12 @@ IF (.NOT. L2D) THEN
 #else
   CALL MZM_DEVICE(PK,ZTMP1_DEVICE)
   CALL MYM_DEVICE(ZTMP1_DEVICE,ZTMP2_DEVICE)
-!$acc kernels
-  ZFLX(:,:,:) = - XCMFS * ZTMP2_DEVICE * GY_W_VW_PWM
-!$acc end kernels
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZFLX(JI,JJ,JK) = - XCMFS * ZTMP2_DEVICE(JI,JJ,JK) * GY_W_VW_PWM(JI,JJ,JK)
+  END DO !CONCURRENT
+  !$acc end kernels
 #endif
 ELSE
 !$acc kernels
@@ -312,11 +337,17 @@ IF (.NOT. L2D) THEN
   CALL MYM_DEVICE( PMZM_PRHODJ, ZTMP1_DEVICE )
   CALL MYM_DEVICE( PDZZ, ZTMP2_DEVICE )
   !$acc kernels
-  ZTMP3_DEVICE = ZFLX* ZTMP1_DEVICE / ZTMP2_DEVICE
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP3_DEVICE(JI,JJ,JK) = ZFLX(JI,JJ,JK)* ZTMP1_DEVICE(JI,JJ,JK) / ZTMP2_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
   !$acc end kernels
   CALL DZF_DEVICE(1,IKU,1, ZTMP3_DEVICE, ZTMP1_DEVICE )
   !$acc kernels
-  PRVS(:,:,:) = PRVS(:,:,:) - ZTMP1_DEVICE
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     PRVS(JI,JJ,JK) = PRVS(JI,JJ,JK) - ZTMP1_DEVICE(JI,JJ,JK)
+  END DO !CONCURRENT   
   !$acc end kernels
 ENDIF
 #endif
@@ -337,30 +368,48 @@ IF (.NOT. L2D) THEN
   IF (.NOT. LFLAT) THEN
     CALL MYM_DEVICE(PRHODJ, ZTMP1_DEVICE)
     !$acc kernels
-    ZTMP2_DEVICE = ZTMP1_DEVICE * PINV_PDYY
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * PINV_PDYY(JI,JJ,JK)
+    END DO !CONCURRENT  
     !$acc end kernels
     CALL MZM_DEVICE(ZTMP2_DEVICE, ZTMP1_DEVICE)
     !$acc kernels
-    ZTMP2_DEVICE = ZTMP1_DEVICE * ZFLX
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * ZFLX(JI,JJ,JK)
+    END DO !CONCURRENT   
     !$acc end kernels
     CALL DYF_DEVICE( ZTMP2_DEVICE, ZTMP1_DEVICE )
     !$acc kernels
-    ZTMP2_DEVICE = ZFLX*PDZY
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK)  = ZFLX(JI,JJ,JK) *PDZY(JI,JJ,JK) 
+    END DO !CONCURRENT   
     !$acc end kernels
     CALL MZF_DEVICE(1,IKU,1,ZTMP2_DEVICE,ZTMP3_DEVICE )
     !$acc kernels
-    ZTMP2_DEVICE = ZTMP3_DEVICE * PINV_PDYY
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZTMP3_DEVICE(JI,JJ,JK) * PINV_PDYY(JI,JJ,JK)
+    END DO !CONCURRENT  
     !$acc end kernels
     CALL MYF_DEVICE(ZTMP2_DEVICE,ZTMP3_DEVICE)
     CALL MZF_DEVICE(1,IKU,1,PDZZ,ZTMP2_DEVICE)
     !$acc kernels
-    ZTMP4_DEVICE = PRHODJ * ZTMP3_DEVICE / ZTMP2_DEVICE
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP4_DEVICE(JI,JJ,JK) = PRHODJ(JI,JJ,JK) * ZTMP3_DEVICE(JI,JJ,JK) / ZTMP2_DEVICE(JI,JJ,JK)
+    END DO !CONCURRENT   
     !$acc end kernels
     CALL DZM_DEVICE(1,IKU,1,ZTMP4_DEVICE,ZTMP2_DEVICE)
     !$acc kernels
-    PRWS(:,:,:) = PRWS(:,:,:)  &
-          - ZTMP1_DEVICE          &
-          + ZTMP2_DEVICE
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       PRWS(JI,JJ,JK) = PRWS(JI,JJ,JK)  &
+            - ZTMP1_DEVICE(JI,JJ,JK)          &
+            + ZTMP2_DEVICE(JI,JJ,JK)
+    END DO !CONCURRENT
     !$acc end kernels
   ELSE
     CALL MYM_DEVICE(PRHODJ, ZTMP1_DEVICE)
@@ -389,12 +438,18 @@ IF (KSPLT==1) THEN
 #else
     CALL GZ_V_VW_DEVICE(1,IKU,1,PVM,PDZZ,ZTMP1_DEVICE)
     !$acc kernels
-    ZTMP2_DEVICE = ZFLX *( ZTMP1_DEVICE + GY_W_VW_PWM )
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZFLX(JI,JJ,JK) *( ZTMP1_DEVICE(JI,JJ,JK) + GY_W_VW_PWM(JI,JJ,JK) )
+    END DO !CONCURRENT   
     !$acc end kernels
     CALL MYF_DEVICE(ZTMP2_DEVICE,ZTMP1_DEVICE)
     CALL MZF_DEVICE(1,IKU,1,ZTMP1_DEVICE,ZTMP2_DEVICE)
     !$acc kernels
-    ZWORK(:,:,:) = -ZTMP2_DEVICE
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZWORK(JI,JJ,JK) = -ZTMP2_DEVICE(JI,JJ,JK)
+    END DO !CONCURRENT   
     !$acc end kernels
 #endif
   !
@@ -543,6 +598,13 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate( ZFLX, ZWORK, GY_W_VW_PWM )
+#else
+CALL MNH_REL_ZT3D ( IZFLX, IZWORK, IGY_W_VW_PWM, &
+                    IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE )
+#endif
+
 !$acc end data
 
 END SUBROUTINE TURB_HOR_VW
diff --git a/src/MNH/turb_ver.f90 b/src/MNH/turb_ver.f90
index 0f4e3e0b2d9894f0e21f7a7d8a40c081d1ad49be..904059b7c4648f7a679aac2f293083122de1d9e3 100644
--- a/src/MNH/turb_ver.f90
+++ b/src/MNH/turb_ver.f90
@@ -342,6 +342,10 @@ USE MODE_PRANDTL
 !
 USE MODI_SECOND_MNH
 !
+#ifdef MNH_OPENACC
+USE  MODE_MNH_ZWORK, ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_ZT4D , MNH_REL_ZT4D
+#endif
+!
 IMPLICIT NONE
 !
 !*      0.1  declarations of arguments
@@ -431,7 +435,7 @@ REAL, DIMENSION(:,:,:,:),INTENT(OUT) :: PWSV       ! scalar flux
 !
 !*       0.2  declaration of local variables
 !
-REAL, DIMENSION(:,:,:), allocatable ::  &
+REAL, DIMENSION(:,:,:), pointer,contiguous ::  &
        ZBETA,    & ! buoyancy coefficient
        ZSQRT_TKE,& ! sqrt(e)
        ZDTH_DZ,  & ! d(th)/dz
@@ -453,11 +457,20 @@ REAL, DIMENSION(:,:,:), allocatable ::  &
        ZTHLP,    & ! guess of potential temperature due to vert. turbulent flux
        ZRP         ! guess of total water due to vert. turbulent flux
 
-REAL, DIMENSION(:,:,:,:), allocatable ::  &
+#ifdef MNH_OPENACC
+INTEGER :: izbeta,izsqrt_tke,izdth_dz,izdr_dz,izred2th3,izred2r3,izred2thr3, &
+           izbll_o_e,izetheta,izemoist,izredth1,izredr1,izphi3,izpsi3, &
+           izd,izwthv,izwu,izwv,izthlp,izrp
+#endif
+
+REAL, DIMENSION(:,:,:,:), pointer , contiguous ::  &
        ZPSI_SV,  & ! Prandtl number for scalars
        ZREDS1,   & ! 1D Redelsperger number R_sv
        ZRED2THS, & ! 3D Redelsperger number R*2_thsv
        ZRED2RS     ! 3D Redelsperger number R*2_rsv
+#ifdef MNH_OPENACC
+INTEGER :: IZPSI_SV,IZREDS1,IZRED2THS,IZRED2RS
+#endif
 !
 LOGICAL :: GUSERV    ! flag to use water vapor
 INTEGER :: IKB,IKE   ! index value for the Beginning
@@ -468,6 +481,9 @@ REAL    :: ZTIME2
 !
 TYPE(TFIELDDATA) :: TZFIELD
 !
+INTEGER                               :: JIU,JJU,JKU
+INTEGER                               :: JI,JJ,JK
+!
 !----------------------------------------------------------------------------
 
 !$acc data present( PDXX, PDYY, PDZZ, PDZX, PDZY, PDIRCOSZW, PZZ,                   &
@@ -539,33 +555,67 @@ if ( mppdb_initialized ) then
   call Mppdb_check( prrs,       "Turb_ver beg:prrs"       )
 end if
 
-allocate( zbeta    (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zsqrt_tke(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zdth_dz  (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zdr_dz   (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zred2th3 (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zred2r3  (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zred2thr3(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zbll_o_e (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zetheta  (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zemoist  (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zredth1  (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zredr1   (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zphi3    (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zpsi3    (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zd       (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zwthv    (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zwu      (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zwv      (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zthlp    (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zrp      (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
+JIU =  size( pthlm, 1 )
+JJU =  size( pthlm, 2 )
+JKU =  size( pthlm, 3 )
+
+#ifndef MNH_OPENACC
+allocate( zbeta    (JIU,JJU,JKU) )
+allocate( zsqrt_tke(JIU,JJU,JKU) )
+allocate( zdth_dz  (JIU,JJU,JKU) )
+allocate( zdr_dz   (JIU,JJU,JKU) )
+allocate( zred2th3 (JIU,JJU,JKU) )
+allocate( zred2r3  (JIU,JJU,JKU) )
+allocate( zred2thr3(JIU,JJU,JKU) )
+allocate( zbll_o_e (JIU,JJU,JKU) )
+allocate( zetheta  (JIU,JJU,JKU) )
+allocate( zemoist  (JIU,JJU,JKU) )
+allocate( zredth1  (JIU,JJU,JKU) )
+allocate( zredr1   (JIU,JJU,JKU) )
+allocate( zphi3    (JIU,JJU,JKU) )
+allocate( zpsi3    (JIU,JJU,JKU) )
+allocate( zd       (JIU,JJU,JKU) )
+allocate( zwthv    (JIU,JJU,JKU) )
+allocate( zwu      (JIU,JJU,JKU) )
+allocate( zwv      (JIU,JJU,JKU) )
+allocate( zthlp    (JIU,JJU,JKU) )
+allocate( zrp      (JIU,JJU,JKU) )
+#else
+izbeta     = MNH_ALLOCATE_ZT3D( zbeta    ,JIU,JJU,JKU )
+izsqrt_tke = MNH_ALLOCATE_ZT3D( zsqrt_tke,JIU,JJU,JKU )
+izdth_dz   = MNH_ALLOCATE_ZT3D( zdth_dz  ,JIU,JJU,JKU )
+izdr_dz    = MNH_ALLOCATE_ZT3D( zdr_dz   ,JIU,JJU,JKU )
+izred2th3  = MNH_ALLOCATE_ZT3D( zred2th3 ,JIU,JJU,JKU )
+izred2r3   = MNH_ALLOCATE_ZT3D( zred2r3  ,JIU,JJU,JKU )
+izred2thr3 = MNH_ALLOCATE_ZT3D( zred2thr3,JIU,JJU,JKU )
+izbll_o_e  = MNH_ALLOCATE_ZT3D( zbll_o_e ,JIU,JJU,JKU )
+izetheta   = MNH_ALLOCATE_ZT3D( zetheta  ,JIU,JJU,JKU )
+izemoist   = MNH_ALLOCATE_ZT3D( zemoist  ,JIU,JJU,JKU )
+izredth1   = MNH_ALLOCATE_ZT3D( zredth1  ,JIU,JJU,JKU )
+izredr1    = MNH_ALLOCATE_ZT3D( zredr1   ,JIU,JJU,JKU )
+izphi3     = MNH_ALLOCATE_ZT3D( zphi3    ,JIU,JJU,JKU )
+izpsi3     = MNH_ALLOCATE_ZT3D( zpsi3    ,JIU,JJU,JKU )
+izd        = MNH_ALLOCATE_ZT3D( zd       ,JIU,JJU,JKU )
+izwthv     = MNH_ALLOCATE_ZT3D( zwthv    ,JIU,JJU,JKU )
+izwu       = MNH_ALLOCATE_ZT3D( zwu      ,JIU,JJU,JKU )
+izwv       = MNH_ALLOCATE_ZT3D( zwv      ,JIU,JJU,JKU )
+izthlp     = MNH_ALLOCATE_ZT3D( zthlp    ,JIU,JJU,JKU )
+izrp       = MNH_ALLOCATE_ZT3D( zrp      ,JIU,JJU,JKU )
+#endif
 
-allocate( zpsi_sv (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ), nsv ) )
-allocate( zreds1  (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ), nsv ) )
-allocate( zred2ths(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ), nsv ) )
-allocate( zred2rs (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ), nsv ) )
+#ifndef MNH_OPENACC
+allocate( zpsi_sv (JIU,JJU,JKU, nsv ) )
+allocate( zreds1  (JIU,JJU,JKU, nsv ) )
+allocate( zred2ths(JIU,JJU,JKU, nsv ) )
+allocate( zred2rs (JIU,JJU,JKU, nsv ) )
+#else
+izpsi_sv  = MNH_ALLOCATE_ZT4D( zpsi_sv ,JIU,JJU,JKU, nsv )
+izreds1   = MNH_ALLOCATE_ZT4D( zreds1  ,JIU,JJU,JKU, nsv )
+izred2ths = MNH_ALLOCATE_ZT4D( zred2ths,JIU,JJU,JKU, nsv )
+izred2rs  = MNH_ALLOCATE_ZT4D( zred2rs ,JIU,JJU,JKU, nsv )
+#endif
 
-!$acc data create(  ZBETA, ZSQRT_TKE, ZDTH_DZ, ZDR_DZ, ZRED2TH3, ZRED2R3, ZRED2THR3,&
+!$acc data present (ZBETA, ZSQRT_TKE, ZDTH_DZ, ZDR_DZ, ZRED2TH3, ZRED2R3, ZRED2THR3,&
 !$acc &             ZBLL_O_E, ZETHETA, ZEMOIST, ZREDTH1, ZREDR1,                    &
 !$acc &             ZPHI3, ZPSI3, ZD, ZWTHV, ZWU, ZWV, ZTHLP, ZRP,                  &
 !$acc &             ZPSI_SV, ZREDS1, ZRED2THS, ZRED2RS )
@@ -629,7 +679,10 @@ ENDIF
 ! Denominator factor in 3rd order terms
 !
 !$acc kernels
-ZD(:,:,:) = (1.+ZREDTH1(:,:,:)+ZREDR1(:,:,:)) * (1.+0.5*(ZREDTH1(:,:,:)+ZREDR1(:,:,:)))
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZD(JI,JJ,JK) = (1.+ZREDTH1(JI,JJ,JK)+ZREDR1(JI,JJ,JK)) * (1.+0.5*(ZREDTH1(JI,JJ,JK)+ZREDR1(JI,JJ,JK)))
+END DO   
 !$acc end kernels
 !
 ! Phi3 and Psi3 Prandtl numbers
@@ -858,6 +911,24 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+DEALLOCATE(zbeta,zsqrt_tke,zdth_dz,zdr_dz,zred2th3,zred2r3,zred2thr3, &
+           zbll_o_e,zetheta,zemoist,zredth1,zredr1,zphi3,zpsi3, &
+           zd,zwthv,zwu,zwv,zthlp,zrp)
+#else
+CALL MNH_REL_ZT3D(izbeta,izsqrt_tke,izdth_dz,izdr_dz,izred2th3,izred2r3,izred2thr3, &
+           izbll_o_e,izetheta,izemoist,izredth1,izredr1,izphi3,izpsi3, &
+           izd,izwthv,izwu,izwv,izthlp,izrp)
+#endif
+
+#ifndef MNH_OPENACC
+DEALLOCATE(zpsi_sv,zreds1,zred2ths,zred2rs)
+#else
+CALL MNH_REL_ZT4D (nsv  , izred2rs  )
+CALL MNH_REL_ZT4D (nsv  , izred2ths  )
+CALL MNH_REL_ZT4D (nsv  , izreds1  )
+CALL MNH_REL_ZT4D (nsv  , izpsi_sv  )
+#endif
 !$acc end data
 
 !----------------------------------------------------------------------------
diff --git a/src/MNH/turb_ver_dyn_flux.f90 b/src/MNH/turb_ver_dyn_flux.f90
index 27e9cb248ffb494df16215b8e57b441b2b916f71..e7c6ae4ae4b0cd222b7d873a9036e670890d5d92 100644
--- a/src/MNH/turb_ver_dyn_flux.f90
+++ b/src/MNH/turb_ver_dyn_flux.f90
@@ -80,7 +80,6 @@ END INTERFACE
 !
 END MODULE MODI_TURB_VER_DYN_FLUX
 !
-!
 !     ###############################################################
       SUBROUTINE TURB_VER_DYN_FLUX(KKA,KKU,KKL,                     &
                       OTURB_FLX,KRR,                                &
@@ -321,6 +320,10 @@ use mode_mppdb
 USE MODE_MSG
 #endif
 !
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_ZT3DP , MNH_ALLOCATE_ZT2D
+#endif
+
 IMPLICIT NONE
 !
 !*      0.1  declarations of arguments
@@ -379,11 +382,11 @@ REAL, DIMENSION(:,:,:), INTENT(OUT)  ::  PDP          ! Dynamic TKE production t
 !*       0.2  declaration of local variables
 !
 !
-REAL, DIMENSION(:,:), allocatable  :: ZDIRSINZW ! sinus of the angle
+REAL, DIMENSION(:,:), pointer , contiguous  :: ZDIRSINZW ! sinus of the angle
                    ! between the normal and the vertical at the surface
-REAL, DIMENSION(:,:,:), allocatable :: ZCOEFS    ! coeff. for the
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZCOEFS    ! coeff. for the
                    ! implicit scheme for the wind at the surface
-REAL, DIMENSION(:,:,:), allocatable ::  &
+REAL, DIMENSION(:,:,:), pointer , contiguous ::  &
        ZA, &       ! under diagonal elements of the tri-diagonal matrix involved
                    ! in the temporal implicit scheme (also used to store coefficient
                    ! J in Section 5)
@@ -393,25 +396,35 @@ REAL, DIMENSION(:,:,:), allocatable ::  &
        ZFLXZ,  &   ! vertical flux of the treated variable
        ZSOURCE,  & ! source of evolution for the treated variable
        ZKEFF       ! effectif diffusion coeff = LT * SQRT( TKE )
+#ifdef MNH_OPENACC
+INTEGER :: IZDIRSINZW,IZCOEFS,IZA,IZRES,IZFLXZ,IZSOURCE,IZKEFF
+#endif
 INTEGER             :: IIB,IIE, &   ! I index values for the Beginning and End
                        IJB,IJE, &   ! mass points of the domain in the 3 direct.
                        IKB,IKE      !
 INTEGER             :: IKT          ! array size in k direction
 INTEGER             :: IKTB,IKTE    ! start, end of k loops in physical domain
 INTEGER             :: JSV          ! scalar loop counter
-REAL, DIMENSION(:,:,:), allocatable :: ZCOEFFLXU, &
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZCOEFFLXU, &
                                     ZCOEFFLXV, ZUSLOPEM, ZVSLOPEM
                                     ! coefficients for the surface flux
                                     ! evaluation and copy of PUSLOPEM and
-                                    ! PVSLOPEM in local 3D arrays 
+                                    ! PVSLOPEM in local 3D arrays
+#ifdef MNH_OPENACC
+INTEGER :: IZCOEFFLXU,IZCOEFFLXV,IZUSLOPEM,IZVSLOPEM
+#endif
 INTEGER             :: IIU,IJU      ! size of array in x,y,z directions
 !
 REAL :: ZTIME1, ZTIME2
 !
 #ifdef MNH_OPENACC
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE,ZTMP2_DEVICE,ZTMP3_DEVICE,ZTMP4_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE,ZTMP2_DEVICE,ZTMP3_DEVICE,ZTMP4_DEVICE
+INTEGER :: IZTMP1_DEVICE,IZTMP2_DEVICE,IZTMP3_DEVICE,IZTMP4_DEVICE
 #endif
 TYPE(TFIELDDATA) :: TZFIELD
+!
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ,JK
 !----------------------------------------------------------------------------
 
 !$acc data present( PDXX, PDYY, PDZZ, PDZX, PDZY, PDIRCOSZW,             &
@@ -454,29 +467,50 @@ if ( mppdb_initialized ) then
   call Mppdb_check( prws, "Turb_ver_dyn_flux beg:prws" )
 end if
 
-allocate( zdirsinzw(size( pum, 1 ), size( pum, 2 ) ) )
+JIU =  size(pum, 1 )
+JJU =  size(pum, 2 )
+JKU =  size(pum, 3 )
+
+#ifndef MNH_OPENACC
+allocate( zdirsinzw(JIU,JJU ) )
+
+allocate( zcoefs   (JIU,JJU, 1 ) )
+
+allocate( za       (JIU,JJU,JKU ) )
+allocate( zres     (JIU,JJU,JKU ) )
+allocate( zflxz    (JIU,JJU,JKU ) )
+allocate( zsource  (JIU,JJU,JKU ) )
+allocate( zkeff    (JIU,JJU,JKU ) )
+
+allocate( zcoefflxu(JIU,JJU, 1 ) )
+allocate( zcoefflxv(JIU,JJU, 1 ) )
+allocate( zuslopem (JIU,JJU, 1 ) )
+allocate( zvslopem (JIU,JJU, 1 ) )
+#else
+izdirsinzw = MNH_ALLOCATE_ZT2D( zdirsinzw,JIU,JJU  )
 
-allocate( zcoefs   (size( pum, 1 ), size( pum, 2 ), 1 ) )
+izcoefs    = MNH_ALLOCATE_ZT3DP( zcoefs   ,JIU,JJU, 1 , 1  )
 
-allocate( za       (size( pum, 1 ), size( pum, 2 ), size( pum, 3 ) ) )
-allocate( zres     (size( pum, 1 ), size( pum, 2 ), size( pum, 3 ) ) )
-allocate( zflxz    (size( pum, 1 ), size( pum, 2 ), size( pum, 3 ) ) )
-allocate( zsource  (size( pum, 1 ), size( pum, 2 ), size( pum, 3 ) ) )
-allocate( zkeff    (size( pum, 1 ), size( pum, 2 ), size( pum, 3 ) ) )
+iza        = MNH_ALLOCATE_ZT3D( za       ,JIU,JJU,JKU  )
+izres      = MNH_ALLOCATE_ZT3D( zres     ,JIU,JJU,JKU  )
+izflxz     = MNH_ALLOCATE_ZT3D( zflxz    ,JIU,JJU,JKU  )
+izsource   = MNH_ALLOCATE_ZT3D( zsource  ,JIU,JJU,JKU  )
+izkeff     = MNH_ALLOCATE_ZT3D( zkeff    ,JIU,JJU,JKU  )
 
-allocate( zcoefflxu(size( pdzz, 1 ), size( pdzz, 2 ), 1 ) )
-allocate( zcoefflxv(size( pdzz, 1 ), size( pdzz, 2 ), 1 ) )
-allocate( zuslopem (size( pdzz, 1 ), size( pdzz, 2 ), 1 ) )
-allocate( zvslopem (size( pdzz, 1 ), size( pdzz, 2 ), 1 ) )
+izcoefflxu = MNH_ALLOCATE_ZT3DP( zcoefflxu,JIU,JJU, 1 , 1  )
+izcoefflxv = MNH_ALLOCATE_ZT3DP( zcoefflxv,JIU,JJU, 1 , 1  )
+izuslopem  = MNH_ALLOCATE_ZT3DP( zuslopem ,JIU,JJU, 1 , 1  )
+izvslopem  = MNH_ALLOCATE_ZT3DP( zvslopem ,JIU,JJU, 1 , 1  )
+#endif
 
 #ifdef MNH_OPENACC
-allocate( ztmp1_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp2_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp3_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp4_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU  )
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU  )
+iztmp3_device = MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU,JKU  )
+iztmp4_device = MNH_ALLOCATE_ZT3D( ztmp4_device,JIU,JJU,JKU  )
 #endif
 
-!$acc data create( zdirsinzw, zcoefs, za, zres, zflxz, zsource, zkeff, zcoefflxu, zcoefflxv, zuslopem, zvslopem, &
+!$acc data present( zdirsinzw, zcoefs, za, zres, zflxz, zsource, zkeff, zcoefflxu, zcoefflxv, zuslopem, zvslopem, &
 !$acc &            ztmp1_device, ztmp2_device, ztmp3_device, ztmp4_device )
 
                                     !
@@ -500,7 +534,10 @@ ZSOURCE(:,:,:) = 0.
 #ifndef MNH_BITREP
 ZDIRSINZW(:,:) = SQRT(1.-PDIRCOSZW(:,:)**2)
 #else
-ZDIRSINZW(:,:) = SQRT(1.-BR_P2(PDIRCOSZW(:,:)))
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+   ZDIRSINZW(JI,JJ) = SQRT(1.-BR_P2(PDIRCOSZW(JI,JJ)))
+END DO
 #endif
 !  compute the coefficients for the uncentred gradient computation near the 
 !  ground
@@ -545,7 +582,10 @@ CALL MXM_DEVICE( PDZZ, ZTMP4_DEVICE )
 #ifndef MNH_BITREP
 ZA(:,:,:) = -PTSTEP * XCMFS * ZTMP1_DEVICE(:,:,:) * ZTMP3_DEVICE(:,:,:) / ZTMP4_DEVICE(:,:,:)**2
 #else
-ZA(:,:,:) = -PTSTEP * XCMFS * ZTMP1_DEVICE(:,:,:) * ZTMP3_DEVICE(:,:,:) / BR_P2(ZTMP4_DEVICE(:,:,:))
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZA(JI,JJ,JK) = -PTSTEP * XCMFS * ZTMP1_DEVICE(JI,JJ,JK) * ZTMP3_DEVICE(JI,JJ,JK) / BR_P2(ZTMP4_DEVICE(JI,JJ,JK))
+END DO
 #endif
 !$acc end kernels
 #endif
@@ -558,21 +598,31 @@ ZA(:,:,:) = -PTSTEP * XCMFS * ZTMP1_DEVICE(:,:,:) * ZTMP3_DEVICE(:,:,:) / BR_P2(
 !$acc kernels
 #ifndef MNH_BITREP
 ZCOEFFLXU(:,:,1) = PCDUEFF(:,:) * (PDIRCOSZW(:,:)**2 - ZDIRSINZW(:,:)**2) &
+     * PCOSSLOPE(:,:)
 #else
-ZCOEFFLXU(:,:,1) = PCDUEFF(:,:) * (BR_P2(PDIRCOSZW(:,:)) - BR_P2(ZDIRSINZW(:,:))) &
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )     
+   ZCOEFFLXU(JI,JJ,1) = PCDUEFF(JI,JJ) * (BR_P2(PDIRCOSZW(JI,JJ)) - BR_P2(ZDIRSINZW(JI,JJ))) &
+        * PCOSSLOPE(JI,JJ)
+END DO
 #endif
-                                   * PCOSSLOPE(:,:)
-ZCOEFFLXV(:,:,1) = PCDUEFF(:,:) * PDIRCOSZW(:,:) * PSINSLOPE(:,:)
-
-! prepare the implicit scheme coefficients for the surface flux
-ZCOEFS(:,:,1)=  ZCOEFFLXU(:,:,1) * PCOSSLOPE(:,:) * PDIRCOSZW(:,:)  &
-                 +ZCOEFFLXV(:,:,1) * PSINSLOPE(:,:)
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+   ZCOEFFLXV(JI,JJ,1) = PCDUEFF(JI,JJ) * PDIRCOSZW(JI,JJ) * PSINSLOPE(JI,JJ)
+   
+   ! prepare the implicit scheme coefficients for the surface flux
+   ZCOEFS(JI,JJ,1)=  ZCOEFFLXU(JI,JJ,1) * PCOSSLOPE(JI,JJ) * PDIRCOSZW(JI,JJ)  &
+        +ZCOEFFLXV(JI,JJ,1) * PSINSLOPE(JI,JJ)
+END DO
 !
 ! average this flux to be located at the U,W vorticity point
 #ifndef MNH_OPENACC
 ZCOEFS(:,:,1:1)=MXM(ZCOEFS(:,:,1:1) / PDZZ(:,:,IKB:IKB) )
 #else
-ZTMP1_DEVICE(:,:,1) = ZCOEFS(:,:,1) / PDZZ(:,:,IKB)
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+   ZTMP1_DEVICE(JI,JJ,1) = ZCOEFS(JI,JJ,1) / PDZZ(JI,JJ,IKB)
+END DO
 !$acc end kernels
 CALL MXM_DEVICE(ZTMP1_DEVICE(:,:,1:1),ZCOEFS(:,:,1:1))
 #endif
@@ -664,6 +714,7 @@ PRUS(:,:,:)=PRUS(:,:,:)+MXM(PRHODJ(:,:,:))*(ZRES(:,:,:)-PUM(:,:,:))/PTSTEP
 #else
 !$acc kernels
 PRUS(:,:,:)=PRUS(:,:,:)+ZTMP1_DEVICE(:,:,:)*(ZRES(:,:,:)-PUM(:,:,:))/PTSTEP
+!$acc end kernels
 #endif
 !
 !
@@ -675,13 +726,20 @@ PRUS(:,:,:)=PRUS(:,:,:)+ZTMP1_DEVICE(:,:,:)*(ZRES(:,:,:)-PUM(:,:,:))/PTSTEP
 ZFLXZ(:,:,:)     = -XCMFS * MXM(ZKEFF) * &
                   DZM (PIMPL*ZRES + PEXPL*PUM) / MXM(PDZZ)
 #else
-ZTMP2_DEVICE(:,:,:) = PIMPL*ZRES(:,:,:) + PEXPL*PUM(:,:,:)
+!$acc kernels
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZTMP2_DEVICE(JI,JJ,JK) = PIMPL*ZRES(JI,JJ,JK) + PEXPL*PUM(JI,JJ,JK)
+END DO
 !$acc end kernels
 CALL MXM_DEVICE(ZKEFF,ZTMP1_DEVICE)
 CALL DZM_DEVICE(KKA,KKU,KKL,ZTMP2_DEVICE,ZTMP3_DEVICE)
 CALL MXM_DEVICE(PDZZ,ZTMP4_DEVICE)
 !$acc kernels
-ZFLXZ(:,:,:)     = -XCMFS * ZTMP1_DEVICE(:,:,:) * ZTMP3_DEVICE(:,:,:) / ZTMP4_DEVICE(:,:,:)
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZFLXZ(JI,JJ,JK)     = -XCMFS * ZTMP1_DEVICE(JI,JJ,JK) * ZTMP3_DEVICE(JI,JJ,JK) / ZTMP4_DEVICE(JI,JJ,JK)
+END DO
 !$acc end kernels
 #endif
 !
@@ -742,7 +800,10 @@ PDP(:,:,:) = - MZF( MXF ( ZFLXZ * GZ_U_UW(PUM,PDZZ) )  )
 #else
 CALL GZ_U_UW_DEVICE(KKA,KKU,KKL,PUM,PDZZ,ZTMP1_DEVICE)
 !$acc kernels
-ZTMP2_DEVICE(:,:,:) = ZFLXZ(:,:,:) * ZTMP1_DEVICE(:,:,:)
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU )
+   ZTMP2_DEVICE(JI,JJ,JK) = ZFLXZ(JI,JJ,JK) * ZTMP1_DEVICE(JI,JJ,JK)
+END DO
 !$acc end kernels
 CALL MXF_DEVICE( ZTMP2_DEVICE,ZTMP3_DEVICE )
 CALL MZF_DEVICE(KKA,KKU,KKL, ZTMP3_DEVICE, ZTMP4_DEVICE )
@@ -837,26 +898,41 @@ IF(HTURBDIM=='3DIM') THEN
   END IF
 #else
   CALL MXM_DEVICE(PRHODJ,ZTMP1_DEVICE)
-!$acc kernels
-  ZTMP2_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) /PDXX(:,:,:)
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) /PDXX(JI,JJ,JK)
+  END DO
 !$acc end kernels
   CALL MZM_DEVICE(ZTMP2_DEVICE,ZTMP3_DEVICE )
-!$acc kernels
-  ZTMP2_DEVICE(:,:,:) = ZTMP3_DEVICE(:,:,:) * ZFLXZ(:,:,:)
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU) 
+     ZTMP2_DEVICE(JI,JJ,JK) = ZTMP3_DEVICE(JI,JJ,JK) * ZFLXZ(JI,JJ,JK)
+  END DO
 !$acc end kernels
   CALL DXF_DEVICE( ZTMP2_DEVICE,ZTMP1_DEVICE )
   IF (.NOT. LFLAT) THEN
     CALL MZF_DEVICE(KKA,KKU,KKL,PDZZ,ZTMP2_DEVICE )
     !$acc kernels
-    ZTMP3_DEVICE(:,:,:) = ZFLXZ(:,:,:)*PDZX(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP3_DEVICE(JI,JJ,JK) = ZFLXZ(JI,JJ,JK)*PDZX(JI,JJ,JK)
+    END DO
     !$acc end kernels
     CALL MZF_DEVICE(KKA,KKU,KKL, ZTMP3_DEVICE,ZTMP4_DEVICE )
     !$acc kernels
-    ZTMP3_DEVICE(:,:,:) = ZTMP4_DEVICE(:,:,:) / PDXX(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP3_DEVICE(JI,JJ,JK) = ZTMP4_DEVICE(JI,JJ,JK) / PDXX(JI,JJ,JK)
+    END DO   
     !$acc end kernels
     CALL MXF_DEVICE( ZTMP3_DEVICE,ZTMP4_DEVICE )
     !$acc kernels
-    ZTMP3_DEVICE(:,:,:) = PRHODJ(:,:,:) / ZTMP2_DEVICE(:,:,:) * ZTMP4_DEVICE(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP3_DEVICE(JI,JJ,JK) = PRHODJ(JI,JJ,JK) / ZTMP2_DEVICE(JI,JJ,JK) * ZTMP4_DEVICE(JI,JJ,JK)
+    END DO
     !$acc end kernels
     CALL DZM_DEVICE(KKA,KKU,KKL, ZTMP3_DEVICE,ZTMP2_DEVICE)
     !$acc kernels
@@ -875,13 +951,19 @@ IF(HTURBDIM=='3DIM') THEN
   ZA(:,:,:)=-MZF( MXF ( ZFLXZ * GX_W_UW( PWM,PDXX,PDZZ,PDZX) )  )
 #else
   CALL GX_W_UW_DEVICE(KKA,KKU,KKL, PWM,PDXX,PDZZ,PDZX,ZTMP1_DEVICE)
-!$acc kernels
-  ZTMP2_DEVICE(:,:,:) = ZFLXZ(:,:,:) * ZTMP1_DEVICE(:,:,:)
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP2_DEVICE(JI,JJ,JK) = ZFLXZ(JI,JJ,JK) * ZTMP1_DEVICE(JI,JJ,JK)
+  END DO
 !$acc end kernels
   CALL MXF_DEVICE(ZTMP2_DEVICE,ZTMP1_DEVICE)
   CALL MZF_DEVICE(KKA,KKU,KKL, ZTMP1_DEVICE,ZTMP2_DEVICE )
-!$acc kernels
-  ZA(:,:,:)=-ZTMP2_DEVICE(:,:,:)
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZA(JI,JJ,JK)=-ZTMP2_DEVICE(JI,JJ,JK)
+  END DO
 !$acc end kernels
 #endif
   !
@@ -1029,7 +1111,10 @@ CALL MYM_DEVICE(ZTMP3_DEVICE,ZTMP4_DEVICE)
 #ifndef MNH_BITREP
 ZA(:,:,:)    = - PTSTEP * XCMFS * ZTMP1_DEVICE(:,:,:) * ZTMP4_DEVICE(:,:,:) / ZTMP2_DEVICE(:,:,:)**2
 #else
-ZA(:,:,:)    = - PTSTEP * XCMFS * ZTMP1_DEVICE(:,:,:) * ZTMP4_DEVICE(:,:,:) / BR_P2(ZTMP2_DEVICE(:,:,:))
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZA(JI,JJ,JK)    = - PTSTEP * XCMFS * ZTMP1_DEVICE(JI,JJ,JK) * ZTMP4_DEVICE(JI,JJ,JK) / BR_P2(ZTMP2_DEVICE(JI,JJ,JK))
+END DO
 #endif
 #endif
 !
@@ -1040,21 +1125,31 @@ ZA(:,:,:)    = - PTSTEP * XCMFS * ZTMP1_DEVICE(:,:,:) * ZTMP4_DEVICE(:,:,:) / BR
 ! wind following the slope
 #ifndef MNH_BITREP
 ZCOEFFLXU(:,:,1) = PCDUEFF(:,:) * (PDIRCOSZW(:,:)**2 - ZDIRSINZW(:,:)**2) &
+                                   * PSINSLOPE(:,:)
 #else
-ZCOEFFLXU(:,:,1) = PCDUEFF(:,:) * (BR_P2(PDIRCOSZW(:,:)) - BR_P2(ZDIRSINZW(:,:))) &
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+ZCOEFFLXU(JI,JJ,1) = PCDUEFF(JI,JJ) * (BR_P2(PDIRCOSZW(JI,JJ)) - BR_P2(ZDIRSINZW(JI,JJ))) &
+     * PSINSLOPE(JI,JJ)
+END DO
 #endif
-                                   * PSINSLOPE(:,:)
 ZCOEFFLXV(:,:,1) = PCDUEFF(:,:) * PDIRCOSZW(:,:) * PCOSSLOPE(:,:)
 
 ! prepare the implicit scheme coefficients for the surface flux
-ZCOEFS(:,:,1)=  ZCOEFFLXU(:,:,1) * PSINSLOPE(:,:) * PDIRCOSZW(:,:)  &
-               +ZCOEFFLXV(:,:,1) * PCOSSLOPE(:,:)
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+ZCOEFS(JI,JJ,1)=  ZCOEFFLXU(JI,JJ,1) * PSINSLOPE(JI,JJ) * PDIRCOSZW(JI,JJ)  &
+     +ZCOEFFLXV(JI,JJ,1) * PCOSSLOPE(JI,JJ)
+END DO
 !
 ! average this flux to be located at the V,W vorticity point
 #ifndef MNH_OPENACC
 ZCOEFS(:,:,1:1)=MYM(ZCOEFS(:,:,1:1) / PDZZ(:,:,IKB:IKB) )
 #else
-ZTMP1_DEVICE(:,:,1:1) = ZCOEFS(:,:,1:1) / PDZZ(:,:,IKB:IKB)
+!$acc loop independent collapse(2)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+   ZTMP1_DEVICE(JI,JJ,1) = ZCOEFS(JI,JJ,1) / PDZZ(JI,JJ,IKB)
+END DO
 !$acc end kernels
 CALL MYM_DEVICE(ZTMP1_DEVICE(:,:,1:1),ZCOEFS(:,:,1:1) )
 #endif
@@ -1157,13 +1252,19 @@ ZFLXZ(:,:,IKB:IKB)   =   MYM(PDZZ(:,:,IKB:IKB))  *                       &
   ) / 0.5 / ( 1. + MYM(PRHODJ(:,:,KKA:KKA)) / MYM(PRHODJ(:,:,IKB:IKB)) )
 #else
 !$acc kernels
-ZTMP1_DEVICE(:,:,:) = PIMPL*ZRES(:,:,:) + PEXPL*PVM(:,:,:)
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZTMP1_DEVICE(JI,JJ,JK) = PIMPL*ZRES(JI,JJ,JK) + PEXPL*PVM(JI,JJ,JK)
+END DO
 !$acc end kernels
 CALL DZM_DEVICE(KKA,KKU,KKL,ZTMP1_DEVICE,ZTMP2_DEVICE)
 CALL MYM_DEVICE(PDZZ,ZTMP3_DEVICE)
 CALL MYM_DEVICE(ZKEFF,ZTMP1_DEVICE)
 !$acc kernels
-ZFLXZ(:,:,:)   = -XCMFS * ZTMP1_DEVICE(:,:,:) * ZTMP2_DEVICE(:,:,:) / ZTMP3_DEVICE(:,:,:)
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZFLXZ(JI,JJ,JK)   = -XCMFS * ZTMP1_DEVICE(JI,JJ,JK) * ZTMP2_DEVICE(JI,JJ,JK) / ZTMP3_DEVICE(JI,JJ,JK)
+END DO
 !$acc end kernels
 !
 CALL MYM_DEVICE(PDZZ(:,:,IKB:IKB),ZTMP1_DEVICE(:,:,1:1))
@@ -1216,12 +1317,18 @@ ZA(:,:,:) = - MZF( MYF ( ZFLXZ * GZ_V_VW(PVM,PDZZ) ) )
 #else
 CALL GZ_V_VW_DEVICE(KKA,KKU,KKL,PVM,PDZZ,ZTMP1_DEVICE)
 !$acc kernels
-ZTMP2_DEVICE(:,:,:) = ZFLXZ(:,:,:) * ZTMP1_DEVICE(:,:,:)
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZTMP2_DEVICE(JI,JJ,JK) = ZFLXZ(JI,JJ,JK) * ZTMP1_DEVICE(JI,JJ,JK)
+END DO
 !$acc end kernels
 CALL MYF_DEVICE( ZTMP2_DEVICE, ZTMP3_DEVICE )
 CALL MZF_DEVICE(KKA,KKU,KKL, ZTMP3_DEVICE, ZTMP1_DEVICE )
 !$acc kernels
-ZA(:,:,:) = - ZTMP1_DEVICE(:,:,:)
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZA(JI,JJ,JK) = - ZTMP1_DEVICE(JI,JJ,JK)
+END DO   
 !$acc end kernels
 #endif
 !
@@ -1311,26 +1418,41 @@ IF(HTURBDIM=='3DIM') THEN
 #else
   IF (.NOT. L2D) THEN 
     CALL MYM_DEVICE(PRHODJ,ZTMP1_DEVICE)
-!$acc kernels
-    ZTMP2_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) /PDYY(:,:,:)
-!$acc end kernels
+    !$acc kernels
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) /PDYY(JI,JJ,JK)
+    END DO
+    !$acc end kernels
     CALL MZM_DEVICE(ZTMP2_DEVICE,ZTMP1_DEVICE)
-!$acc kernels
-    ZTMP2_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) * ZFLXZ(:,:,:)
-!$acc end kernels
+    !$acc kernels
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * ZFLXZ(JI,JJ,JK)
+    END DO
+    !$acc end kernels
     CALL DYF_DEVICE( ZTMP2_DEVICE,ZTMP1_DEVICE )
     IF (.NOT. LFLAT) THEN
       CALL MZF_DEVICE(KKA,KKU,KKL,PDZZ,ZTMP2_DEVICE )
       !$acc kernels
-      ZTMP3_DEVICE(:,:,:) = ZFLXZ(:,:,:)*PDZY(:,:,:)
+      !$acc loop independent collapse(3)
+      DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+         ZTMP3_DEVICE(JI,JJ,JK) = ZFLXZ(JI,JJ,JK)*PDZY(JI,JJ,JK)
+      END DO
       !$acc end kernels
       CALL MZF_DEVICE(KKA,KKU,KKL,ZTMP3_DEVICE,ZTMP4_DEVICE)
       !$acc kernels
-      ZTMP3_DEVICE(:,:,:) = ZTMP4_DEVICE(:,:,:) / PDYY(:,:,:)
+      !$acc loop independent collapse(3)
+      DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+         ZTMP3_DEVICE(JI,JJ,JK) = ZTMP4_DEVICE(JI,JJ,JK) / PDYY(JI,JJ,JK)
+      END DO
       !$acc end kernels
       CALL MYF_DEVICE(ZTMP3_DEVICE,ZTMP4_DEVICE)
       !$acc kernels
-      ZTMP3_DEVICE(:,:,:) =  PRHODJ(:,:,:) / ZTMP2_DEVICE(:,:,:) * ZTMP4_DEVICE(:,:,:)
+      !$acc loop independent collapse(3)
+      DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+         ZTMP3_DEVICE(JI,JJ,JK) =  PRHODJ(JI,JJ,JK) / ZTMP2_DEVICE(JI,JJ,JK) * ZTMP4_DEVICE(JI,JJ,JK)
+      END DO
       !$acc end kernels
       CALL DZM_DEVICE(KKA,KKU,KKL,ZTMP3_DEVICE, ZTMP4_DEVICE)
       !$acc kernels
@@ -1350,14 +1472,20 @@ IF(HTURBDIM=='3DIM') THEN
     ZA(:,:,:) = - MZF( MYF ( ZFLXZ(:,:,:) * GY_W_VW( PWM,PDYY,PDZZ,PDZY) )  )
 #else
     CALL GY_W_VW_DEVICE(KKA,KKU,KKL, PWM,PDYY,PDZZ,PDZY,ZTMP1_DEVICE)
-!$acc kernels
-    ZTMP2_DEVICE(:,:,:) = ZFLXZ(:,:,:) * ZTMP1_DEVICE(:,:,:)
-!$acc end kernels
+    !$acc kernels
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZFLXZ(JI,JJ,JK) * ZTMP1_DEVICE(JI,JJ,JK)
+    END DO
+    !$acc end kernels
     CALL MYF_DEVICE(ZTMP2_DEVICE,ZTMP1_DEVICE)
     CALL MZF_DEVICE(KKA,KKU,KKL,ZTMP1_DEVICE,ZTMP2_DEVICE  )
-!$acc kernels
-    ZA(:,:,:) = - ZTMP2_DEVICE(:,:,:)
-!$acc end kernels
+    !$acc kernels
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZA(JI,JJ,JK) = - ZTMP2_DEVICE(JI,JJ,JK)
+    END DO
+    !$acc end kernels
 #endif
   !
   ! evaluate the dynamic production at w(IKB+KKL) in PDP(IKB)
@@ -1508,6 +1636,12 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate (zdirsinzw,zcoefs,za,zres,zflxz,zsource,zkeff,zcoefflxu,zcoefflxv,zuslopem,zvslopem)
+#else
+CALL MNH_REL_ZT3D(izdirsinzw,izcoefs,iza,izres,izflxz,izsource,izkeff,izcoefflxu,izcoefflxv,izuslopem,izvslopem,&
+                  iztmp1_device,iztmp2_device,iztmp3_device,iztmp4_device)
+#endif
 !$acc end data
 
 !----------------------------------------------------------------------------
diff --git a/src/MNH/turb_ver_thermo_corr.f90 b/src/MNH/turb_ver_thermo_corr.f90
index 0bbbd7f376613bd879e944eb7b711635984260e9..4b7898b182b55adf67b9bd362f63d30c1f609354 100644
--- a/src/MNH/turb_ver_thermo_corr.f90
+++ b/src/MNH/turb_ver_thermo_corr.f90
@@ -317,6 +317,10 @@ USE MODI_SECOND_MNH
 USE MODI_BITREP
 #endif
 !
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_GT3D , MNH_REL_GT3D , MNH_ALLOCATE_ZT3DP
+#endif
+
 IMPLICIT NONE
 !
 !*      0.1  declarations of arguments
@@ -380,18 +384,24 @@ REAL, DIMENSION(:,:,:),   INTENT(OUT)  ::  PSIGS     ! Vert. part of Sigma_s at
 !*       0.2  declaration of local variables
 !
 !
-REAL, DIMENSION(:,:,:), allocatable ::  &
+REAL, DIMENSION(:,:,:), pointer , contiguous ::  &
        ZFLXZ,    & ! vertical flux of the treated variable
        ZKEFF,    & ! effectif diffusion coeff = LT * SQRT( TKE )
        ZF,       & ! Flux in dTh/dt =-dF/dz (evaluated at t-1)(or rt instead of Th)
        ZDFDDTDZ, & ! dF/d(dTh/dz)
        ZDFDDRDZ    ! dF/d(dr/dz)
+#ifdef MNH_OPENACC
+INTEGER :: IZFLXZ,IZKEFF,IZF,IZDFDDTDZ,IZDFDDRDZ
+#endif
 INTEGER             :: IKB,IKE      ! I index values for the Beginning and End
                                     ! mass points of the domain in the 3 direct.
 INTEGER             :: I1,I2        ! For ZCOEFF allocation
-REAL, DIMENSION(:,:,:),ALLOCATABLE  :: ZCOEFF
+REAL, DIMENSION(:,:,:),POINTER , CONTIGUOUS  :: ZCOEFF
                                     ! coefficients for the uncentred gradient 
                                     ! computation near the ground
+#ifdef MNH_OPENACC
+INTEGER            :: IZCOEFF
+#endif
 !
 REAL :: ZTIME1, ZTIME2
 !
@@ -403,10 +413,15 @@ LOGICAL :: GFWR     ! flag to use w'2r'
 LOGICAL :: GFTHR    ! flag to use w'th'r'
 !
 #ifdef MNH_OPENACC
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE,ZTMP2_DEVICE,ZTMP3_DEVICE,ZTMP4_DEVICE
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP5_DEVICE,ZTMP6_DEVICE,ZTMP7_DEVICE,ZTMP8_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE,ZTMP2_DEVICE,ZTMP3_DEVICE,ZTMP4_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP5_DEVICE,ZTMP6_DEVICE,ZTMP7_DEVICE,ZTMP8_DEVICE
+INTEGER  :: IZTMP1_DEVICE,IZTMP2_DEVICE,IZTMP3_DEVICE,IZTMP4_DEVICE
+INTEGER  :: IZTMP5_DEVICE,IZTMP6_DEVICE,IZTMP7_DEVICE,IZTMP8_DEVICE
 #endif
 TYPE(TFIELDDATA) :: TZFIELD
+!
+INTEGER  :: JIU,JJU,JKU
+INTEGER  :: JI,JJ,JK
 !----------------------------------------------------------------------------
 
 !$acc data present( PDZZ,                                            &
@@ -462,26 +477,41 @@ IKE=KKU-JPVEXT_TURB*KKL
 I1=MIN(KKA+JPVEXT_TURB*KKL,KKA+JPVEXT_TURB*KKL+2*KKL)
 I2=MAX(KKA+JPVEXT_TURB*KKL,KKA+JPVEXT_TURB*KKL+2*KKL)
 
-allocate( zflxz     (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zkeff     (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zf        (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zdfddtdz  (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zdfddrdz  (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
+JIU =  size( pthlm, 1 )
+JJU =  size( pthlm, 2 )
+JKU =  size( pthlm, 3 )
+
+#ifndef MNH_OPENACC
+allocate( zflxz     (JIU,JJU,JKU) )
+allocate( zkeff     (JIU,JJU,JKU) )
+allocate( zf        (JIU,JJU,JKU) )
+allocate( zdfddtdz  (JIU,JJU,JKU) )
+allocate( zdfddrdz  (JIU,JJU,JKU) )
+
+allocate( zcoeff(JIU,JJU, i1 : i2 ) )
+#else
+izflxz    = MNH_ALLOCATE_ZT3D( zflxz     ,JIU,JJU,JKU )
+izkeff    = MNH_ALLOCATE_ZT3D( zkeff     ,JIU,JJU,JKU )
+izf       = MNH_ALLOCATE_ZT3D( zf        ,JIU,JJU,JKU )
+izdfddtdz = MNH_ALLOCATE_ZT3D( zdfddtdz  ,JIU,JJU,JKU )
+izdfddrdz = MNH_ALLOCATE_ZT3D( zdfddrdz  ,JIU,JJU,JKU )
 
-allocate( zcoeff(size( pdzz, 1 ), size( pdzz, 2 ), i1 : i2 ) )
+izcoeff   = MNH_ALLOCATE_ZT3DP( zcoeff,JIU,JJU, i1 , i2 )
+
+#endif
 
 #ifdef MNH_OPENACC
-allocate( ztmp1_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp2_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp3_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp4_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp5_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp6_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp7_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp8_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU )
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU )
+iztmp3_device = MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU,JKU )
+iztmp4_device = MNH_ALLOCATE_ZT3D( ztmp4_device,JIU,JJU,JKU )
+iztmp5_device = MNH_ALLOCATE_ZT3D( ztmp5_device,JIU,JJU,JKU )
+iztmp6_device = MNH_ALLOCATE_ZT3D( ztmp6_device,JIU,JJU,JKU )
+iztmp7_device = MNH_ALLOCATE_ZT3D( ztmp7_device,JIU,JJU,JKU )
+iztmp8_device = MNH_ALLOCATE_ZT3D( ztmp8_device,JIU,JJU,JKU )
 #endif
 
-!$acc data create( zflxz, zkeff, zf, zdfddtdz, zdfddrdz, zcoeff,           &
+!$acc data present( zflxz, zkeff, zf, zdfddtdz, zdfddrdz, zcoeff,           &
 !$acc &            ztmp1_device, ztmp2_device, ztmp3_device, ztmp4_device, &
 !$acc &            ztmp5_device, ztmp6_device, ztmp7_device, ztmp8_device  )
 
@@ -542,13 +572,19 @@ END IF
 #ifndef MNH_BITREP
   ZTMP1_DEVICE(:,:,:) = PPHI3(:,:,:)*PDTH_DZ(:,:,:)**2
 #else
-  ZTMP1_DEVICE(:,:,:) = PPHI3(:,:,:)*BR_P2(PDTH_DZ(:,:,:))
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP1_DEVICE(JI,JJ,JK) = PPHI3(JI,JJ,JK)*BR_P2(PDTH_DZ(JI,JJ,JK))
+  END DO
 #endif
   !$acc end kernels
   CALL MZF_DEVICE(KKA,KKU,KKL,ZTMP1_DEVICE(:,:,:),ZTMP2_DEVICE(:,:,:))
   !$acc kernels
-  ZF      (:,:,:) = XCTV*PLM(:,:,:)*PLEPS(:,:,:)*ZTMP2_DEVICE(:,:,:)
-  ZDFDDTDZ(:,:,:) = 0.     ! this term, because of discretization, is treated separately
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZF      (JI,JJ,JK) = XCTV*PLM(JI,JJ,JK)*PLEPS(JI,JJ,JK)*ZTMP2_DEVICE(JI,JJ,JK) 
+  END DO
+  ZDFDDTDZ(:,:,:) = 0.     ! this term, because of discretization, is treated separately 
   !$acc end kernels
 #endif
   !
@@ -681,14 +717,23 @@ END IF
   !             *DZM(PTHLP(:,:,:) - PTHLM(:,:,:)) / PDZZ(:,:,:)                                        ) &
         + PIMPL * ZDFDDTDZ(:,:,:) * MZF(DZM(PTHLP(:,:,:) - PTHLM(:,:,:)) / PDZZ(:,:,:) )
 #else
+  !$acc kernels  
   ZTMP1_DEVICE(:,:,:) = PTHLP(:,:,:) - PTHLM(:,:,:)
+  !$acc end kernels
   CALL DZM_DEVICE(KKA,KKU,KKL,ZTMP1_DEVICE(:,:,:),ZTMP2_DEVICE(:,:,:))
-  ZTMP3_DEVICE(:,:,:) = ZTMP2_DEVICE(:,:,:) / PDZZ(:,:,:)
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZTMP3_DEVICE(JI,JJ,JK) = ZTMP2_DEVICE(JI,JJ,JK) / PDZZ(JI,JJ,JK)
+  END DO
+  !$acc end kernels
   CALL MZF_DEVICE(KKA,KKU,KKL,ZTMP3_DEVICE(:,:,:),ZTMP4_DEVICE(:,:,:) )
-  
-!$acc kernels
-  ZFLXZ(:,:,:)   = ZF(:,:,:)                                                              &
-        + PIMPL * ZDFDDTDZ(:,:,:) * ZTMP4_DEVICE(:,:,:)
+  !$acc kernels
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZFLXZ(JI,JJ,JK)   = ZF(JI,JJ,JK)                                                              &
+          + PIMPL * ZDFDDTDZ(JI,JJ,JK) * ZTMP4_DEVICE(JI,JJ,JK)
+  END DO
 #endif
   !
   ! special case near the ground ( uncentred gradient )
@@ -705,17 +750,20 @@ END IF
       +ZCOEFF(:,:,IKB      )*PTHLP(:,:,IKB  )   )**2          &
    ) 
 #else
-  ZFLXZ(:,:,IKB) = XCTV * PPHI3(:,:,IKB+KKL) * PLM(:,:,IKB)   &
-     * PLEPS(:,:,IKB)                                         &
+  !$acc loop independent collapse(2)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+  ZFLXZ(JI,JJ,IKB) = XCTV * PPHI3(JI,JJ,IKB+KKL) * PLM(JI,JJ,IKB)   &
+     * PLEPS(JI,JJ,IKB)                                         &
   *( PEXPL *                                                  &
-     BR_P2( ZCOEFF(:,:,IKB+2*KKL)*PTHLM(:,:,IKB+2*KKL)        &
-      +ZCOEFF(:,:,IKB+KKL  )*PTHLM(:,:,IKB+KKL  )             & 
-      +ZCOEFF(:,:,IKB      )*PTHLM(:,:,IKB  )   )             &
+     BR_P2( ZCOEFF(JI,JJ,IKB+2*KKL)*PTHLM(JI,JJ,IKB+2*KKL)        &
+      +ZCOEFF(JI,JJ,IKB+KKL  )*PTHLM(JI,JJ,IKB+KKL  )             & 
+      +ZCOEFF(JI,JJ,IKB      )*PTHLM(JI,JJ,IKB  )   )             &
     +PIMPL *                                                  &
-     BR_P2( ZCOEFF(:,:,IKB+2*KKL)*PTHLP(:,:,IKB+2*KKL)        &
-      +ZCOEFF(:,:,IKB+KKL  )*PTHLP(:,:,IKB+KKL  )             &
-      +ZCOEFF(:,:,IKB      )*PTHLP(:,:,IKB  )   )             &
-   ) 
+     BR_P2( ZCOEFF(JI,JJ,IKB+2*KKL)*PTHLP(JI,JJ,IKB+2*KKL)        &
+      +ZCOEFF(JI,JJ,IKB+KKL  )*PTHLP(JI,JJ,IKB+KKL  )             &
+      +ZCOEFF(JI,JJ,IKB      )*PTHLP(JI,JJ,IKB  )   )             &
+      )
+   END DO
 #endif
   !
   ZFLXZ(:,:,KKA) = ZFLXZ(:,:,IKB) 
@@ -804,8 +852,13 @@ END IF
 !$acc end kernels
     CALL MZF_DEVICE(KKA,KKU,KKL,ZTMP1_DEVICE(:,:,:),ZTMP2_DEVICE(:,:,:))
 !$acc kernels
-    ZF      (:,:,:) = XCTV*PLM(:,:,:)*PLEPS(:,:,:)*ZTMP2_DEVICE(:,:,:)
+!$acc loop independent collapse(3)    
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+      ZF      (JI,JJ,JK) = XCTV*PLM(JI,JJ,JK)*PLEPS(JI,JJ,JK)*ZTMP2_DEVICE(JI,JJ,JK)
+    END DO
+!$acc end kernels    
 #endif
+!$acc kernels   
     ZDFDDTDZ(:,:,:) = 0.     ! this term, because of discretization, is treated separately
     ZDFDDRDZ(:,:,:) = 0.     ! this term, because of discretization, is treated separately
 !$acc end kernels
@@ -988,8 +1041,12 @@ END IF
     CALL DZM_DEVICE(KKA,KKU,KKL,ZTMP1_DEVICE(:,:,:),ZTMP3_DEVICE(:,:,:))
     CALL DZM_DEVICE(KKA,KKU,KKL,ZTMP2_DEVICE(:,:,:),ZTMP4_DEVICE(:,:,:))
     !$acc kernels
-    ZTMP1_DEVICE(:,:,:) = ZTMP3_DEVICE(:,:,:) / PDZZ(:,:,:)
-    ZTMP2_DEVICE(:,:,:) = ZTMP4_DEVICE(:,:,:) / PDZZ(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP1_DEVICE(JI,JJ,JK) = ZTMP3_DEVICE(JI,JJ,JK) / PDZZ(JI,JJ,JK)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZTMP4_DEVICE(JI,JJ,JK) / PDZZ(JI,JJ,JK)      
+    END DO
+
     !$acc end kernels
     CALL D_PHI3DTDZ_O_DDTDZ(PPHI3(:,:,:),PREDTH1(:,:,:),PREDR1(:,:,:),PRED2TH3(:,:,:),PRED2THR3(:,:,:), &
                             HTURBDIM,GUSERV,ZTMP3_DEVICE(:,:,:)) ! d(phi3*dthdz)/ddthdz term
@@ -1007,8 +1064,13 @@ END IF
     CALL DZM_DEVICE(KKA,KKU,KKL,ZTMP8_DEVICE(:,:,:),ZTMP1_DEVICE(:,:,:))
     !!!
     !$acc kernels
-    ZTMP7_DEVICE(:,:,:) =   ( ZTMP3_DEVICE(:,:,:) + ZTMP4_DEVICE(:,:,:)) * PDR_DZ(:,:,:)  * ZTMP2_DEVICE(:,:,:) / PDZZ(:,:,:) &
-                   + ( ZTMP5_DEVICE(:,:,:) + ZTMP6_DEVICE(:,:,:)) * PDTH_DZ(:,:,:) * ZTMP1_DEVICE(:,:,:) / PDZZ(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP7_DEVICE(JI,JJ,JK) =   ( ZTMP3_DEVICE(JI,JJ,JK) + ZTMP4_DEVICE(JI,JJ,JK)) * PDR_DZ(JI,JJ,JK)  &
+                              * ZTMP2_DEVICE(JI,JJ,JK) / PDZZ(JI,JJ,JK) &
+                              + ( ZTMP5_DEVICE(JI,JJ,JK) + ZTMP6_DEVICE(JI,JJ,JK)) * PDTH_DZ(JI,JJ,JK) &
+                              * ZTMP1_DEVICE(JI,JJ,JK) / PDZZ(JI,JJ,JK)
+    END DO
     !$acc end kernels
     !!!
     !$acc kernels
@@ -1018,38 +1080,47 @@ END IF
     CALL DZM_DEVICE(KKA,KKU,KKL,ZTMP1_DEVICE(:,:,:),ZTMP3_DEVICE(:,:,:))
     CALL DZM_DEVICE(KKA,KKU,KKL,ZTMP2_DEVICE(:,:,:),ZTMP4_DEVICE(:,:,:))
     !$acc kernels
-    ZTMP1_DEVICE(:,:,:) = ZTMP3_DEVICE(:,:,:) / PDZZ(:,:,:)
-    ZTMP2_DEVICE(:,:,:) = ZTMP4_DEVICE(:,:,:) /PDZZ(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP1_DEVICE(JI,JJ,JK) = ZTMP3_DEVICE(JI,JJ,JK) / PDZZ(JI,JJ,JK)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZTMP4_DEVICE(JI,JJ,JK) /PDZZ(JI,JJ,JK)
+    END DO
     !$acc end kernels
     !!!
     CALL MZF_DEVICE(KKA,KKU,KKL,ZTMP7_DEVICE(:,:,:),ZTMP3_DEVICE(:,:,:))
     CALL MZF_DEVICE(KKA,KKU,KKL,ZTMP1_DEVICE(:,:,:), ZTMP4_DEVICE(:,:,:) )
     CALL MZF_DEVICE(KKA,KKU,KKL,ZTMP2_DEVICE(:,:,:), ZTMP5_DEVICE(:,:,:) )
     !$acc kernels
-    ZFLXZ(:,:,:)   = ZF(:,:,:)                           &
-        + PIMPL * XCTV*PLM(:,:,:)*PLEPS(:,:,:)*0.5 * ZTMP3_DEVICE(:,:,:)  &
-        + PIMPL * ZDFDDTDZ(:,:,:) * ZTMP4_DEVICE(:,:,:)            &
-        + PIMPL * ZDFDDRDZ(:,:,:) * ZTMP5_DEVICE(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZFLXZ(JI,JJ,JK)   = ZF(JI,JJ,JK)                           &
+            + PIMPL * XCTV*PLM(JI,JJ,JK)*PLEPS(JI,JJ,JK)*0.5 * ZTMP3_DEVICE(JI,JJ,JK)  &
+            + PIMPL * ZDFDDTDZ(JI,JJ,JK) * ZTMP4_DEVICE(JI,JJ,JK)            &
+            + PIMPL * ZDFDDRDZ(JI,JJ,JK) * ZTMP5_DEVICE(JI,JJ,JK)
+    END DO
 #endif
     !
     ! special case near the ground ( uncentred gradient )
-    ZFLXZ(:,:,IKB) =                                            & 
-    (XCHT1 * PPHI3(:,:,IKB+KKL) + XCHT2 * PPSI3(:,:,IKB+KKL))   &
+    !$acc loop independent collapse(2)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+    ZFLXZ(JI,JJ,IKB) =                                            & 
+    (XCHT1 * PPHI3(JI,JJ,IKB+KKL) + XCHT2 * PPSI3(JI,JJ,IKB+KKL))   &
     *( PEXPL *                                                  &
-       ( ZCOEFF(:,:,IKB+2*KKL)*PTHLM(:,:,IKB+2*KKL)             &
-        +ZCOEFF(:,:,IKB+KKL  )*PTHLM(:,:,IKB+KKL  )             & 
-        +ZCOEFF(:,:,IKB      )*PTHLM(:,:,IKB      ))            &
-      *( ZCOEFF(:,:,IKB+2*KKL)*PRM(:,:,IKB+2*KKL,1)             &
-        +ZCOEFF(:,:,IKB+KKL  )*PRM(:,:,IKB+KKL,1  )             & 
-        +ZCOEFF(:,:,IKB      )*PRM(:,:,IKB  ,1    ))            &
+       ( ZCOEFF(JI,JJ,IKB+2*KKL)*PTHLM(JI,JJ,IKB+2*KKL)             &
+        +ZCOEFF(JI,JJ,IKB+KKL  )*PTHLM(JI,JJ,IKB+KKL  )             & 
+        +ZCOEFF(JI,JJ,IKB      )*PTHLM(JI,JJ,IKB      ))            &
+      *( ZCOEFF(JI,JJ,IKB+2*KKL)*PRM(JI,JJ,IKB+2*KKL,1)             &
+        +ZCOEFF(JI,JJ,IKB+KKL  )*PRM(JI,JJ,IKB+KKL,1  )             & 
+        +ZCOEFF(JI,JJ,IKB      )*PRM(JI,JJ,IKB  ,1    ))            &
       +PIMPL *                                                  &
-       ( ZCOEFF(:,:,IKB+2*KKL)*PTHLP(:,:,IKB+2*KKL)             &
-        +ZCOEFF(:,:,IKB+KKL  )*PTHLP(:,:,IKB+KKL  )             &
-        +ZCOEFF(:,:,IKB      )*PTHLP(:,:,IKB      ))            &
-      *( ZCOEFF(:,:,IKB+2*KKL)*PRP(:,:,IKB+2*KKL  )             &
-        +ZCOEFF(:,:,IKB+KKL  )*PRP(:,:,IKB+KKL    )             & 
-        +ZCOEFF(:,:,IKB      )*PRP(:,:,IKB        ))            &
-     ) 
+       ( ZCOEFF(JI,JJ,IKB+2*KKL)*PTHLP(JI,JJ,IKB+2*KKL)             &
+        +ZCOEFF(JI,JJ,IKB+KKL  )*PTHLP(JI,JJ,IKB+KKL  )             &
+        +ZCOEFF(JI,JJ,IKB      )*PTHLP(JI,JJ,IKB      ))            &
+      *( ZCOEFF(JI,JJ,IKB+2*KKL)*PRP(JI,JJ,IKB+2*KKL  )             &
+        +ZCOEFF(JI,JJ,IKB+KKL  )*PRP(JI,JJ,IKB+KKL    )             & 
+        +ZCOEFF(JI,JJ,IKB      )*PRP(JI,JJ,IKB        ))            &
+        )
+    END DO
     !    
     ZFLXZ(:,:,KKA) = ZFLXZ(:,:,IKB) 
     !
@@ -1145,12 +1216,18 @@ END IF
 #ifndef MNH_BITREP
     ZTMP1_DEVICE(:,:,:) = PPSI3(:,:,:)*PDR_DZ(:,:,:)**2
 #else
-    ZTMP1_DEVICE(:,:,:) = PPSI3(:,:,:)*BR_P2(PDR_DZ(:,:,:))
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP1_DEVICE(JI,JJ,JK) = PPSI3(JI,JJ,JK)*BR_P2(PDR_DZ(JI,JJ,JK))
+    END DO
 #endif
     !$acc end kernels
     CALL MZF_DEVICE(KKA,KKU,KKL,ZTMP1_DEVICE(:,:,:),ZTMP2_DEVICE(:,:,:))
     !$acc kernels
-    ZF      (:,:,:) = XCTV*PLM(:,:,:)*PLEPS(:,:,:)*ZTMP2_DEVICE(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZF      (JI,JJ,JK) = XCTV*PLM(JI,JJ,JK)*PLEPS(JI,JJ,JK)*ZTMP2_DEVICE(JI,JJ,JK)
+    END DO
 #endif
     ZDFDDRDZ(:,:,:) = 0.     ! this term, because of discretization, is treated separately
     !$acc end kernels
@@ -1293,17 +1370,26 @@ END IF
     !$acc end kernels
     CALL DZM_DEVICE(KKA,KKU,KKL,ZTMP2_DEVICE(:,:,:),ZTMP3_DEVICE(:,:,:))
     !$acc kernels
-    ZTMP2_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) * ZTMP3_DEVICE(:,:,:) / PDZZ(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * ZTMP3_DEVICE(JI,JJ,JK) / PDZZ(JI,JJ,JK)
+    END DO
     !$acc end kernels
     CALL MZF_DEVICE(KKA,KKU,KKL,ZTMP2_DEVICE(:,:,:),ZTMP1_DEVICE(:,:,:))
     !$acc kernels
-    ZTMP2_DEVICE(:,:,:) = ZTMP3_DEVICE(:,:,:) / PDZZ(:,:,:)
+    !$acc loop independent collapse(3)    
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZTMP2_DEVICE(JI,JJ,JK) = ZTMP3_DEVICE(JI,JJ,JK) / PDZZ(JI,JJ,JK)
+    END DO
     !$acc end kernels
     CALL MZF_DEVICE(KKA,KKU,KKL,ZTMP2_DEVICE(:,:,:),ZTMP3_DEVICE(:,:,:))
     !$acc kernels
-    ZFLXZ(:,:,:)   = ZF(:,:,:)                        &
-          + PIMPL * XCTV*PLM(:,:,:)*PLEPS(:,:,:) * ZTMP1_DEVICE(:,:,:) &
-          + PIMPL * ZDFDDRDZ(:,:,:) * ZTMP3_DEVICE(:,:,:)
+    !$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+       ZFLXZ(JI,JJ,JK)   = ZF(JI,JJ,JK)                        &
+            + PIMPL * XCTV*PLM(JI,JJ,JK)*PLEPS(JI,JJ,JK) * ZTMP1_DEVICE(JI,JJ,JK) &
+            + PIMPL * ZDFDDRDZ(JI,JJ,JK) * ZTMP3_DEVICE(JI,JJ,JK)
+    END DO
 #endif
     !
     ! special case near the ground ( uncentred gradient )
@@ -1320,17 +1406,20 @@ END IF
         +ZCOEFF(:,:,IKB      )*PRP(:,:,IKB      ))**2           &
      ) 
 #else
-    ZFLXZ(:,:,IKB) = XCHV * PPSI3(:,:,IKB+KKL) * PLM(:,:,IKB)   &
-        * PLEPS(:,:,IKB)                                        &
+    !$acc loop independent collapse(2)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU )
+    ZFLXZ(JI,JJ,IKB) = XCHV * PPSI3(JI,JJ,IKB+KKL) * PLM(JI,JJ,IKB)   &
+        * PLEPS(JI,JJ,IKB)                                        &
     *( PEXPL *                                                  &
-       BR_P2( ZCOEFF(:,:,IKB+2*KKL)*PRM(:,:,IKB+2*KKL,1)        &
-        +ZCOEFF(:,:,IKB+KKL  )*PRM(:,:,IKB+KKL,1  )             & 
-        +ZCOEFF(:,:,IKB      )*PRM(:,:,IKB  ,1    ))            &
+       BR_P2( ZCOEFF(JI,JJ,IKB+2*KKL)*PRM(JI,JJ,IKB+2*KKL,1)        &
+        +ZCOEFF(JI,JJ,IKB+KKL  )*PRM(JI,JJ,IKB+KKL,1  )             & 
+        +ZCOEFF(JI,JJ,IKB      )*PRM(JI,JJ,IKB  ,1    ))            &
       +PIMPL *                                                  &
-       BR_P2( ZCOEFF(:,:,IKB+2*KKL)*PRP(:,:,IKB+2*KKL)          &
-        +ZCOEFF(:,:,IKB+KKL  )*PRP(:,:,IKB+KKL  )               &
-        +ZCOEFF(:,:,IKB      )*PRP(:,:,IKB      ))              &
-     ) 
+       BR_P2( ZCOEFF(JI,JJ,IKB+2*KKL)*PRP(JI,JJ,IKB+2*KKL)          &
+        +ZCOEFF(JI,JJ,IKB+KKL  )*PRP(JI,JJ,IKB+KKL  )               &
+        +ZCOEFF(JI,JJ,IKB      )*PRP(JI,JJ,IKB      ))              &
+        )
+    END DO
 #endif
     !
     ZFLXZ(:,:,KKA) = ZFLXZ(:,:,IKB) 
@@ -1415,6 +1504,14 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+deallocate( zflxz, zkeff, zf , zdfddtdz , zdfddrdz , zcoeff )
+#else
+CALL MNH_REL_ZT3D(IZFLXZ,IZKEFF,IZF,IZDFDDTDZ,IZDFDDRDZ,IZCOEFF,&
+                  IZTMP1_DEVICE,IZTMP2_DEVICE,IZTMP3_DEVICE,IZTMP4_DEVICE,&
+                  IZTMP5_DEVICE,IZTMP6_DEVICE,IZTMP7_DEVICE,IZTMP8_DEVICE )
+#endif
+
 !$acc end data
 
 !----------------------------------------------------------------------------
diff --git a/src/MNH/turb_ver_thermo_flux.f90 b/src/MNH/turb_ver_thermo_flux.f90
index b67905978d035d03cdaedef696926cb914efd9cf..e79a2a5d6b840d76c29be310e9311af453d98de0 100644
--- a/src/MNH/turb_ver_thermo_flux.f90
+++ b/src/MNH/turb_ver_thermo_flux.f90
@@ -375,6 +375,10 @@ USE MODE_PRANDTL
 !
 USE MODI_SECOND_MNH
 !
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D, MNH_ALLOCATE_GT3D , MNH_REL_GT3D
+#endif
+
 IMPLICIT NONE
 !
 !*      0.1  declarations of arguments
@@ -502,7 +506,7 @@ LOGICAL :: GFR2     ! flag to use w'r'2
 LOGICAL :: GFWR     ! flag to use w'2r'
 LOGICAL :: GFTHR    ! flag to use w'th'r'
 !
-REAL, DIMENSION(:,:,:), allocatable ::  &
+REAL, DIMENSION(:,:,:), pointer , contiguous ::  &
        ZA,         & ! work variable for wrc or LES computation
        ZFLXZ,      & ! vertical flux of the treated variable
        ZSOURCE,    & ! source of evolution for the treated variable
@@ -510,16 +514,23 @@ REAL, DIMENSION(:,:,:), allocatable ::  &
        ZF,         & ! Flux in dTh/dt =-dF/dz (evaluated at t-1)(or rt instead of Th)
        ZDFDDTDZ,   & ! dF/d(dTh/dz)
        ZDFDDRDZ,   & ! dF/d(dr/dz)
-       Z3RDMOMENT, &  ! 3 order term in flux or variance equation
+       Z3RDMOMENT, & ! 3 order term in flux or variance equation
        ZF_NEW,     &
        ZRWTHL,     &
        ZRWRNP,     &
        ZCLD_THOLD
-REAL, DIMENSION(:,:,:), allocatable  :: ZALT
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZALT
+#ifdef MNH_OPENACC
+INTEGER :: IZA, IZFLXZ, IZSOURCE, IZKEFF, IZF, IZDFDDTDZ, IZDFDDRDZ, IZ3RDMOMENT, IZF_NEW, IZRWTHL, IZRWRNP, IZCLD_THOLD, IZALT
+#endif
 #ifdef MNH_OPENACC
-REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE,ZTMP2_DEVICE,ZTMP3_DEVICE,ZTMP4_DEVICE
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZTMP1_DEVICE,ZTMP2_DEVICE,ZTMP3_DEVICE,ZTMP4_DEVICE
+INTEGER :: IZTMP1_DEVICE,IZTMP2_DEVICE,IZTMP3_DEVICE,IZTMP4_DEVICE
 #endif
 TYPE(TFIELDDATA) :: TZFIELD
+
+INTEGER  :: JIU,JJU,JKU
+
 !----------------------------------------------------------------------------
 
 !$acc data present( PDZZ, PDIRCOSZW, PZZ,                            &
@@ -581,31 +592,50 @@ if ( mppdb_initialized ) then
   call Mppdb_check( prrs,      "Turb_ver_thermo_flux beg:prrs"      )
 end if
 
-allocate( za        (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zflxz     (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zsource   (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zkeff     (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zf        (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zdfddtdz  (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( zdfddrdz  (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( z3rdmoment(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ZF_NEW    (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ZRWTHL    (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ZRWRNP    (size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ZCLD_THOLD(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
+JIU =  size( pthlm, 1 )
+JJU =  size( pthlm, 2 )
+JKU =  size( pthlm, 3 )
 
-Allocate( ZALT(Size( XZS, 1 ), Size( XZS, 2 ), KKU ) )
+#ifndef MNH_OPENACC
+allocate( za        (JIU,JJU,JKU ) )
+allocate( zflxz     (JIU,JJU,JKU ) )
+allocate( zsource   (JIU,JJU,JKU ) )
+allocate( zkeff     (JIU,JJU,JKU ) )
+allocate( zf        (JIU,JJU,JKU ) )
+allocate( zdfddtdz  (JIU,JJU,JKU ) )
+allocate( zdfddrdz  (JIU,JJU,JKU ) )
+allocate( z3rdmoment(JIU,JJU,JKU ) )
+allocate( zf_new    (JIU,JJU,JKU ) )
+allocate( zrwthl    (JIU,JJU,JKU ) )
+allocate( zrwrnp    (JIU,JJU,JKU ) )
+allocate( zcld_thold(JIU,JJU,JKU ) )
+allocate( zalt      (JIU,JJU,JKU ) )
+#else
+iza         = MNH_ALLOCATE_ZT3D( za        ,JIU,JJU,JKU  )
+izflxz      = MNH_ALLOCATE_ZT3D( zflxz     ,JIU,JJU,JKU  )
+izsource    = MNH_ALLOCATE_ZT3D( zsource   ,JIU,JJU,JKU  )
+izkeff      = MNH_ALLOCATE_ZT3D( zkeff     ,JIU,JJU,JKU  )
+izf         = MNH_ALLOCATE_ZT3D( zf        ,JIU,JJU,JKU  )
+izdfddtdz   = MNH_ALLOCATE_ZT3D( zdfddtdz  ,JIU,JJU,JKU  )
+izdfddrdz   = MNH_ALLOCATE_ZT3D( zdfddrdz  ,JIU,JJU,JKU  )
+iz3rdmoment = MNH_ALLOCATE_ZT3D( z3rdmoment,JIU,JJU,JKU  )
+izf_new     = MNH_ALLOCATE_ZT3D( zf_new    ,JIU,JJU,JKU  )
+izrwthl     = MNH_ALLOCATE_ZT3D( zrwthl    ,JIU,JJU,JKU  )
+izrwrnp     = MNH_ALLOCATE_ZT3D( zrwrnp    ,JIU,JJU,JKU  )
+izcld_thold = MNH_ALLOCATE_ZT3D( zcld_thold,JIU,JJU,JKU  )
+izalt       = MNH_ALLOCATE_ZT3D( zalt      ,JIU,JJU,JKU  )
+#endif
 
 #ifdef MNH_OPENACC
-allocate( ztmp1_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp2_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp3_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
-allocate( ztmp4_device(size( pthlm, 1 ), size( pthlm, 2 ), size( pthlm, 3 ) ) )
+iztmp1_device = MNH_ALLOCATE_ZT3D( ztmp1_device,JIU,JJU,JKU  )
+iztmp2_device = MNH_ALLOCATE_ZT3D( ztmp2_device,JIU,JJU,JKU  )
+iztmp3_device = MNH_ALLOCATE_ZT3D( ztmp3_device,JIU,JJU,JKU  )
+iztmp4_device = MNH_ALLOCATE_ZT3D( ztmp4_device,JIU,JJU,JKU  )
 #endif
 
-!$acc data create( ZA, ZFLXZ, ZSOURCE, ZKEFF, ZF, ZDFDDTDZ, ZDFDDRDZ, Z3RDMOMENT,  &
-!$acc &            ZF_NEW, ZRWTHL, ZRWRNP, ZCLD_THOLD, ZALT,                       &
-!$acc &            ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE )
+!$acc data present( ZA, ZFLXZ, ZSOURCE, ZKEFF, ZF, ZDFDDTDZ, ZDFDDRDZ, Z3RDMOMENT,  &
+!$acc &             ZF_NEW, ZRWTHL, ZRWRNP, ZCLD_THOLD, ZALT,                       &
+!$acc &             ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE, ZTMP4_DEVICE )
 
 !
 !*       1.   PRELIMINARIES
@@ -712,12 +742,18 @@ ZDFDDTDZ(:,:,:) = -XCSHF*ZKEFF(:,:,:)*D_PHI3DTDZ_O_DDTDZ(PPHI3,PREDTH1,PREDR1,PR
 #else
 CALL DZM_DEVICE(KKA,KKU,KKL,PTHLM,ZTMP1_DEVICE)
 !$acc kernels
-ZF      (:,:,:) = -XCSHF*PPHI3(:,:,:)*ZKEFF(:,:,:)*ZTMP1_DEVICE(:,:,:)/PDZZ(:,:,:)
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZF      (JI,JJ,JK) = -XCSHF*PPHI3(JI,JJ,JK)*ZKEFF(JI,JJ,JK)*ZTMP1_DEVICE(JI,JJ,JK)/PDZZ(JI,JJ,JK)
+END DO    
 !$acc end kernels
 !
 CALL D_PHI3DTDZ_O_DDTDZ(PPHI3,PREDTH1,PREDR1,PRED2TH3,PRED2THR3,HTURBDIM,GUSERV,ZTMP2_DEVICE)
 !$acc kernels
-ZDFDDTDZ(:,:,:) = -XCSHF*ZKEFF(:,:,:)*ZTMP2_DEVICE(:,:,:)
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZDFDDTDZ(JI,JJ,JK) = -XCSHF*ZKEFF(JI,JJ,JK)*ZTMP2_DEVICE(JI,JJ,JK)
+END DO   
 !$acc end kernels
 #endif
 !
@@ -937,7 +973,10 @@ ZTMP1_DEVICE(:,:,:) = PTHLP(:,:,:) - PTHLM(:,:,:)
 !$acc end kernels
 CALL DZM_DEVICE(KKA,KKU,KKL,ZTMP1_DEVICE,ZTMP2_DEVICE)
 !$acc kernels
-ZFLXZ(:,:,:)   = ZF(:,:,:) + PIMPL * ZDFDDTDZ(:,:,:) * ZTMP2_DEVICE(:,:,:) / PDZZ(:,:,:)
+!$acc loop independent collapse(3)
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+   ZFLXZ(JI,JJ,JK)   =  ZF(JI,JJ,JK) + PIMPL * ZDFDDTDZ(JI,JJ,JK) * ZTMP2_DEVICE(JI,JJ,JK) / PDZZ(JI,JJ,JK)
+END DO
 !$acc end kernels
 #endif
 ! replace the flux by the Leonard terms
@@ -1006,7 +1045,10 @@ ELSE
   IF (KRR /= 0) THEN
     CALL MZM_DEVICE(PETHETA,ZTMP1_DEVICE)
 !$acc kernels
-    ZTMP2_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) * ZFLXZ(:,:,:)
+!$acc loop independent collapse(3)  
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+      ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * ZFLXZ(JI,JJ,JK)
+    END DO
 !$acc end kernels
     CALL MZF_DEVICE(KKA,KKU,KKL, ZTMP2_DEVICE,ZTMP3_DEVICE)
 !$acc kernels
@@ -1146,8 +1188,12 @@ IF (LLES_CALL) THEN
   END IF
   !* diagnostic of mixing coefficient for heat
   CALL DZM_DEVICE(KKA,KKU,KKL,PTHLP,ZA)
-!$acc kernels
-  WHERE (ZA(:,:,:)==0.) ZA(:,:,:)=1.E-6
+  !$acc kernels
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     IF  (ZA(JI,JJ,JK)==0.) THEN
+        ZA(JI,JJ,JK)=1.E-6
+     END IF
+  END DO
   ZA(:,:,:) = - ZFLXZ(:,:,:) / ZA(:,:,:) * PDZZ(:,:,:)
   ZA(:,:,IKB) = XCSHF*PPHI3(:,:,IKB)*ZKEFF(:,:,IKB)
   !Copy ZA into ZTMP1_DEVICE to prevent aliasing in the following call to MZF_DEVICE
@@ -1188,12 +1234,18 @@ IF (KRR /= 0) THEN
 #else
   CALL DZM_DEVICE(KKA,KKU,KKL,PRM(:,:,:,1),ZTMP1_DEVICE)
   !$acc kernels
-  ZF      (:,:,:) = -XCSHF*PPSI3(:,:,:)*ZKEFF(:,:,:)*ZTMP1_DEVICE(:,:,:)/PDZZ(:,:,:)
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZF      (JI,JJ,JK) = -XCSHF*PPSI3(JI,JJ,JK)*ZKEFF(JI,JJ,JK)*ZTMP1_DEVICE(JI,JJ,JK)/PDZZ(JI,JJ,JK)
+  END DO
   !$acc end kernels
   CALL D_PSI3DRDZ_O_DDRDZ(PPSI3,PREDR1,PREDTH1,PRED2R3,PRED2THR3,HTURBDIM,GUSERV,ZTMP1_DEVICE)
 !CALL D_PHI3DRDZ_O_DDRDZ_DEVICE(PPSI3,PREDR1,PREDTH1,PRED2R3,PRED2THR3,HTURBDIM,GUSERV,ZTMP1_DEVICE)
   !$acc kernels
-  ZDFDDRDZ(:,:,:) = -XCSHF*ZKEFF(:,:,:)*ZTMP1_DEVICE(:,:,:)
+  !$acc loop independent collapse(3)
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     ZDFDDRDZ(JI,JJ,JK) = -XCSHF*ZKEFF(JI,JJ,JK)*ZTMP1_DEVICE(JI,JJ,JK)
+  END DO
   !$acc end kernels
 #endif
   !
@@ -1417,7 +1469,10 @@ IF (KRR /= 0) THEN
 !$acc end kernels
   CALL DZM_DEVICE(KKA,KKU,KKL,ZTMP1_DEVICE,ZTMP2_DEVICE)
 !$acc kernels
-  ZFLXZ(:,:,:)   = ZF(:,:,:) + PIMPL * ZDFDDRDZ(:,:,:) *ZTMP2_DEVICE(:,:,:) / PDZZ(:,:,:)
+!$acc loop independent collapse(3)  
+DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)  
+   ZFLXZ(JI,JJ,JK)   = ZF(JI,JJ,JK) + PIMPL * ZDFDDRDZ(JI,JJ,JK) *ZTMP2_DEVICE(JI,JJ,JK) / PDZZ(JI,JJ,JK)
+END DO
 !$acc end kernels
 #endif
   !
@@ -1475,11 +1530,17 @@ IF (KRR /= 0) THEN
 #else
     CALL MZM_DEVICE(PEMOIST,ZTMP1_DEVICE)
 !$acc kernels
-    ZTMP2_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:) * ZFLXZ(:,:,:)
+!$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+      ZTMP2_DEVICE(JI,JJ,JK) = ZTMP1_DEVICE(JI,JJ,JK) * ZFLXZ(JI,JJ,JK)
+    END DO
 !$acc end kernels
     CALL MZF_DEVICE(KKA,KKU,KKL, ZTMP2_DEVICE, ZTMP3_DEVICE )
 !$acc kernels
-    ZA(:,:,:)   =  PBETA(:,:,:) * ZTMP3_DEVICE(:,:,:)
+!$acc loop independent collapse(3)
+    DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+      ZA(JI,JJ,JK)   =  PBETA(JI,JJ,JK) * ZTMP3_DEVICE(JI,JJ,JK)
+    END DO
 #endif
     ZA(:,:,IKB) =  PBETA(:,:,IKB) * PEMOIST(:,:,IKB) *   &
                    0.5 * ( ZFLXZ (:,:,IKB) + ZFLXZ (:,:,IKB+KKL) )
@@ -1493,9 +1554,13 @@ IF (KRR /= 0) THEN
   PWTHV          = PWTHV          + MZM(PEMOIST) * ZFLXZ
 #else
   CALL MZM_DEVICE(PEMOIST,ZTMP1_DEVICE)
-!$acc kernels
-  PWTHV(:,:,:)   = PWTHV(:,:,:)   + ZTMP1_DEVICE * ZFLXZ
+  !$acc kernels
+  DO CONCURRENT ( JI=1:JIU,JJ=1:JJU,JK=1:JKU)
+     PWTHV(JI,JJ,JK)          = PWTHV(JI,JJ,JK)          + ZTMP1_DEVICE(JI,JJ,JK) * ZFLXZ(JI,JJ,JK)
+  END DO
+  !$acc end kernels
 #endif
+  !$acc kernels
   PWTHV(:,:,IKB) = PWTHV(:,:,IKB) + PEMOIST(:,:,IKB) * ZFLXZ(:,:,IKB)
 !$acc end kernels
   IF (LOCEAN) THEN
@@ -1714,6 +1779,14 @@ end if
 
 !$acc end data
 
+#ifndef MNH_OPENACC
+Deallocate( za, zflxz, zsource, zkeff, zf, zdfddtdz, zdfddrdz, z3rdmoment, zf_new, zrwthl, zrwrnp, zcld_thold, zalt )
+#else
+CALL MNH_REL_ZT3D( IZA, IZFLXZ, IZSOURCE, IZKEFF, IZF, IZDFDDTDZ, IZDFDDRDZ, IZ3RDMOMENT, &
+                   IZF_NEW, IZRWTHL, IZRWRNP, IZCLD_THOLD, IZALT,                         &
+                   IZTMP1_DEVICE, IZTMP2_DEVICE, IZTMP3_DEVICE, IZTMP4_DEVICE             )
+#endif
+
 !$acc end data
 
 !----------------------------------------------------------------------------
diff --git a/src/MNH/unpack_1d_2d.f90 b/src/MNH/unpack_1d_2d.f90
index ebfd7e2137bb83464cda4275e71a872d4ba7dfda..aa5f8d9a426c674d7eea29ec2800acbd017eef19 100644
--- a/src/MNH/unpack_1d_2d.f90
+++ b/src/MNH/unpack_1d_2d.f90
@@ -228,6 +228,7 @@ END SUBROUTINE UNPACK_1D_2D_FROML2D
 !!    MODIFICATIONS
 !!    -------------
 !!      Original    21/01/03
+!!   J.Escobar 24/07/2020 : nvhpc20.5 BUG , reshape wrong without (:,:) in O2 ?!        
 !-------------------------------------------------------------------------------
 !
 !*       0.    DECLARATIONS
@@ -261,7 +262,7 @@ DO JI=1,SIZE(P1D)
   Z1D(KM(JI)) = P1D(JI) 
 ENDDO
 !
-P2D=RESHAPE(Z1D, (/ SIZE(P2D,1), SIZE(P2D,2) /) )
+P2D(:,:)=RESHAPE(Z1D, (/ SIZE(P2D,1), SIZE(P2D,2) /) )
 DEALLOCATE(Z1D)
 !-------------------------------------------------------------------------------
 !
diff --git a/src/MNH_OPENACC_SHUMAN_MACRO.CPP b/src/MNH_OPENACC_SHUMAN_MACRO.CPP
new file mode 100644
index 0000000000000000000000000000000000000000..bd89169588dc601d7e553790e384c7116cbbc9e6
--- /dev/null
+++ b/src/MNH_OPENACC_SHUMAN_MACRO.CPP
@@ -0,0 +1,12 @@
+#define MxF(PA) (0.5*(PA+EOSHIFT(PA,+1,DIM=1))) 
+#define MxM(PA) (0.5*(PA+EOSHIFT(PA,-1,DIM=1)))
+#define MyF(PA) (0.5*(PA+EOSHIFT(PA,+1,DIM=2)))
+#define MyM(PA) (0.5*(PA+EOSHIFT(PA,-1,DIM=2)))
+#define MzF(PA) (0.5*(PA+EOSHIFT(PA,+1,DIM=3)))
+#define MzM(PA) (0.5*(PA+EOSHIFT(PA,-1,DIM=3)))
+#define DxF(PA) (EOSHIFT(PA,+1,DIM=1)-PA)
+#define DxM(PA) (PA-EOSHIFT(PA,-1,DIM=1))
+#define DyF(PA) (EOSHIFT(PA,+1,DIM=2)-PA)
+#define DyM(PA) (PA-EOSHIFT(PA,-1,DIM=2))
+#define DzF(PA) (EOSHIFT(PA,+1,DIM=3)-PA)
+#define DzM(PA) (PA-EOSHIFT(PA,-1,DIM=3))
diff --git a/src/Makefile b/src/Makefile
index 03c5d4492c4f7bc0cba2db78ed82a3ad46a152ae..796bcc55f18303c2f29b006dafd4cb06d182ea34 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -342,7 +342,7 @@ NETCDF_OPT ?= ${OPT_BASE_I4:-$OPT_BASE}
 #
 cdf : $(CDF_MOD)
 $(CDF_MOD) :
-	cd ${DIR_LIBAEC} && ./configure --disable-shared --prefix=${CDF_PATH} --libdir=${CDF_PATH}/lib64 CC="$(CC)" CFLAGS="$(HDF_OPT)" && \
+	cd ${DIR_LIBAEC} && ./configure --disable-shared --prefix=${CDF_PATH} --libdir=${CDF_PATH}/lib64 CC="$(CC)" CFLAGS="$(HDF_OPT)" ${CDF_CONF} && \
 	$(MAKE) && $(MAKE) install && $(MAKE) clean
 	cd ${DIR_HDF} && ./configure --enable-fortran --disable-shared --prefix=${CDF_PATH} --libdir=${CDF_PATH}/lib64 --with-szlib=${CDF_PATH}/include,${CDF_PATH}/lib64 \
 	CC="$(CC)" CFLAGS="$(HDF_OPT)" FC="$(FC)" FCFLAGS="$(NETCDF_OPT)" LDFLAGS="-L${CDF_PATH}/lib64" LIBS="-lsz -laec -lz" && \
diff --git a/src/Rules.LXgfortran.mk b/src/Rules.LXgfortran.mk
index f9ba987e6c59b96ec7070d54fe7c9a56683f7501..871219c5445bdc2760f5916f2276babd9964f488 100644
--- a/src/Rules.LXgfortran.mk
+++ b/src/Rules.LXgfortran.mk
@@ -22,6 +22,11 @@ OPT_I8    = -fdefault-integer-8
 OPT_R8    = -fdefault-real-8 -fdefault-double-8
 OPT_OPENACC = -fopenacc
 #
+ifeq "$(VER_USER)" "ZSOLVER"
+CPPFLAGS  += -DCARTESIANGEOMETRY -DPIECEWISELINEAR
+#  -DOVERLAPCOMMS
+PROG_LIST += MG_MAIN MG_MAIN_MNH_ALL
+endif
 #
 # Real/Integer 4/8 option
 #
@@ -52,6 +57,13 @@ OPT0      = $(OPT_BASE) $(OPT_PERF0) $(OPT_CHECK)
 OPT_NOCB  = $(OPT_BASE) $(OPT_PERF0)
 CFLAGS    += -g -O0
 endif
+ifeq "$(OPTLEVEL)" "OPENACCDEFONLY"
+CPPFLAGS    += -DMNH_OPENACC -D_FAKEOPENACC
+OPT       = $(OPT_BASE) $(OPT_PERF0) $(OPT_CHECK)
+OPT0      = $(OPT_BASE) $(OPT_PERF0) $(OPT_CHECK)
+OPT_NOCB  = $(OPT_BASE) $(OPT_PERF0)
+CFLAGS    += -g -O0
+endif
 #
 ifeq "$(OPTLEVEL)" "OPENACC"
 CPPFLAGS    += -DMNH_OPENACC -fopenacc
@@ -103,6 +115,11 @@ endif
 HDF_CONF= CFLAGS=-std=c99
 HDF_OPT ?= -fPIC
 NETCDF_OPT ?= -fPIC
+#if MNH_BITREP exists => compile with the BITREP library
+ifeq "$(MNH_BITREP)" "YES"
+CPPFLAGS_MNH += -DMNH_BITREP
+endif
+
 #
 ## LIBTOOLS flags
 #
diff --git a/src/Rules.LXifort.mk b/src/Rules.LXifort.mk
index b7f8e24bdb1236b64d9c9ed0346b2a463f8066b9..b667f42703360d2ee7e0d9ae062470c379bb9e05 100644
--- a/src/Rules.LXifort.mk
+++ b/src/Rules.LXifort.mk
@@ -9,7 +9,8 @@
 ##########################################################
 #OBJDIR_PATH=/home/escj/azertyuiopqsdfghjklm/wxcvbn/azertyuiopqsdfghjklmwxcvbn
 #
-OPT_BASE   =  -g -w -assume nosource_include -assume byterecl -fpe0 -ftz -fpic -traceback  -fp-model precise -switch fe_inline_all_arg_copy_inout -fno-common 
+OPT_BASE   =  -g -w -assume nosource_include -assume byterecl -fpe0 -ftz -fpic -traceback -fp-model consistent -switch fe_inline_all_arg_copy_inout -fno-common 
+# -fimf-arch-consistency 
 OPT_PERF0  =  -O0
 OPT_PERF2  =  -O2
 OPT_PERF3  =  -O3 -xHost
@@ -44,6 +45,12 @@ OPT0      = $(OPT_BASE) $(OPT_PERF0) $(OPT_CHECK)
 OPT_NOCB  = $(OPT_BASE) $(OPT_PERF0)
 CFLAGS   += -g
 endif
+ifeq "$(OPTLEVEL)" "OPENACCDEFONLY"
+CPPFLAGS    += -DMNH_OPENACC -D_FAKEOPENACC
+OPT       = $(OPT_BASE) $(OPT_PERF2) 
+OPT0      = $(OPT_BASE) $(OPT_PERF0) 
+OPT_NOCB  = $(OPT_BASE) $(OPT_PERF2)
+endif
 ifeq "$(OPTLEVEL)" "O2"
 OPT       = $(OPT_BASE) $(OPT_PERF2)
 OPT0      = $(OPT_BASE) $(OPT_PERF0)
@@ -189,6 +196,11 @@ HDF_CONF= CFLAGS=-std=c99
 HDF_OPT ?= -fPIC
 NETCDF_OPT ?= -fPIC
 #
+#if MNH_BITREP exists => compile with the BITREP library
+ifeq "$(MNH_BITREP)" "YES"
+CPPFLAGS_MNH += -DMNH_BITREP
+endif
+#
 # LIBTOOLS flags
 #
 #if MNH_TOOLS exists => compile the tools
diff --git a/src/Rules.LXnvhpc2005.mk b/src/Rules.LXnvhpc2005.mk
new file mode 100644
index 0000000000000000000000000000000000000000..c362e60e94f8b3b4a6275e5d1bfc275b68ea11ff
--- /dev/null
+++ b/src/Rules.LXnvhpc2005.mk
@@ -0,0 +1,282 @@
+#MNH_LIC Copyright 1994-2019 CNRS, Meteo-France and Universite Paul Sabatier
+#MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+#MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
+#MNH_LIC for details. version 1.
+##########################################################
+#                                                        #
+# Compiler Options                                       #
+#                                                        #
+##########################################################
+#OBJDIR_PATH=${WORKDIR}
+#
+# Processor type
+#TP= -tp=sandybridge
+#TP= -tp=px
+TP= -tp=p7-64
+#
+#Version of CUDA
+#(8.0 at least if compute capability >= 6.0)
+CUDALEVEL=cuda10.1
+#
+#Compute capability of GPU
+#
+#OPT_CPTCAP=cc35,cc50,cc70
+OPT_CPTCAP=cc35,cc50,cc60,cc70
+#Aeropc45: cc50
+#Nuwa: cc35
+#Ouessant Firestone K80: cc35
+#Ouessant Minsky P100: cc60
+#
+#Compiler info level
+#OPT_INFO = -Minfo=ftn,accel,inline,ipa,loop,lre,mp,opt,par,unified,vect,ccff
+OPT_INFO = -Minfo=accel
+#
+#Compiler profiling options
+#OPT_PROF = -Mprof=ccff
+#
+#PW: if -Ktrap=fp: nvprof/pgprof do not work   OPT_BASE   =  -Ktrap=fp ...
+#PW: -g: big impact on performance
+OPT_BASE   =  $(TP) -Mbackslash -Mextend -Kieee -nofma  -Mallocatable=95
+#
+OPT_PERF0  =  -O0
+OPT_PERF1  =  -O1
+OPT_PERF2  =  -O2
+#
+OPT_MANAGED    = -Mframe -Mnostack_arrays -Mallocatable=95 -acc=host,gpu -gpu=nofma,$(OPT_CPTCAP),$(CUDALEVEL),managed $(OPT_INFO) $(OPT_PROF)
+OPT_MULTICORE  = -acc=multicore $(OPT_INFO) $(OPT_PROF)
+OPT_NOOPENACC  = -acc=host $(OPT_INFO) $(OPT_PROF)
+OPT_OPENACC    = -Mframe -Mnostack_arrays -Mallocatable=95 -acc=host,gpu -gpu=nofma,$(OPT_CPTCAP),$(CUDALEVEL) $(OPT_INFO) $(OPT_PROF)
+#
+OPT_CHECK  =  -C #-Mchkfpstk -Mchkptr
+OPT_I8     =  -i8
+OPT_R8     =  -r8
+#
+ifeq "$(VER_USER)" "ZSOLVER"
+CPPFLAGS  += -DCARTESIANGEOMETRY -DOVERLAPCOMMS -DPIECEWISELINEAR
+PROG_LIST += MG_MAIN MG_MAIN_MNH_ALL
+endif
+#
+IGNORE_OBJS += pgprof.o
+#
+# Real/integer 4/8 option
+#
+MNH_REAL  ?=8
+MNH_INT   ?=4
+#
+ifneq "$(MNH_REAL)" "4"
+OPT_BASE           += $(OPT_R8)
+endif
+#
+OPT_BASE_I4       := $(OPT_BASE)
+ifeq "$(MNH_INT)" "8"
+OPT_BASE          += $(OPT_I8)
+LFI_INT           ?=8
+else
+LFI_INT           ?=4
+endif
+#
+#
+OPT       = $(OPT_BASE) $(OPT_PERF2)
+OPT0      = $(OPT_BASE) $(OPT_PERF0)
+OPT_NOCB  = $(OPT_BASE) $(OPT_PERF2)
+#
+ifeq "$(OPTLEVEL)" "DEBUG"
+OPT       = -g $(OPT_BASE) $(OPT_PERF0) $(OPT_CHECK)
+OPT0      = -g $(OPT_BASE) $(OPT_PERF0) $(OPT_CHECK)
+OPT_NOCB  = -g $(OPT_BASE) $(OPT_PERF0)
+endif
+#
+ifeq "$(OPTLEVEL)" "MANAGED"
+CPPFLAGS    += -DMNH_OPENACC
+OPT       = -g $(OPT_BASE) $(OPT_MANAGED) $(OPT_PERF2)
+OPT0      = -g $(OPT_BASE) $(OPT_MANAGED) $(OPT_PERF0)
+OPT_NOCB  = -g $(OPT_BASE) $(OPT_MANAGED) $(OPT_PERF2) 
+CXXFLAGS = -g -acc -Kieee -Mnofma $(OPT_MANAGED)
+OBJS_REPROD= spll_mode_sum_ll.o
+$(OBJS_REPROD) : OPT = $(OPT_BASE) $(OPT_MANAGED) $(OPT_PERF2) -Mvect=nosimd -Minfo=all -g
+endif
+#
+ifeq "$(OPTLEVEL)" "MANAGEDO2"
+CPPFLAGS    += -DMNH_OPENACC
+OPT       = $(OPT_BASE) $(OPT_MANAGED) $(OPT_PERF2)
+OPT0      = $(OPT_BASE) $(OPT_MANAGED) $(OPT_PERF0)
+OPT_NOCB  = $(OPT_BASE) $(OPT_MANAGED) $(OPT_PERF2) 
+CXXFLAGS = -acc -Kieee -Mnofma $(OPT_MANAGED) -gpu=nofma
+OBJS_REPROD= spll_mode_sum_ll.o
+$(OBJS_REPROD) : OPT = $(OPT_BASE) $(OPT_MANAGED) $(OPT_PERF2) -Mvect=nosimd -Minfo=all
+OBJS_OPENACC = spll_modd_halo_d.o
+$(OBJS_OPENACC) : OPT = $(OPT_BASE) $(OPT_OPENACC) $(OPT_PERF2)
+endif
+#
+ifeq "$(OPTLEVEL)" "MULTICORE"
+CPPFLAGS    += -DMNH_OPENACC
+OPT       = $(OPT_BASE) $(OPT_MULTICORE) 
+OPT0      = $(OPT_BASE) $(OPT_MULTICORE) $(OPT_PERF0)
+OPT_NOCB  = $(OPT_BASE) $(OPT_MULTICORE) 
+CXXFLAGS = -acc -Kieee -Mnofma $(OPT_MULTICORE)
+endif
+#
+ifeq "$(OPTLEVEL)" "OPENACC"
+CPPFLAGS    += -DMNH_OPENACC
+# -imacros MNH_OPENACC_SHUMAN_MACRO.CPP
+OPT       = -g $(OPT_BASE) $(OPT_OPENACC) $(OPT_PERF0)
+OPT0      = -g $(OPT_BASE) $(OPT_OPENACC) $(OPT_PERF0)
+OPT_NOCB  = -g $(OPT_BASE) $(OPT_OPENACC) $(OPT_PERF0) 
+CXXFLAGS =  -g -acc -Kieee -Mnofma $(OPT_OPENACC)
+OBJS_REPROD= spll_mode_sum_ll.o
+$(OBJS_REPROD) : OPT = $(OPT_BASE) $(OPT_OPENACC) $(OPT_PERF2) -Mvect=nosimd -Minfo=all -g
+endif
+ifeq "$(OPTLEVEL)" "OPENACCO2"
+CPPFLAGS    += -DMNH_OPENACC
+OPT       = $(OPT_BASE) $(OPT_OPENACC) $(OPT_PERF2)
+OPT0      = $(OPT_BASE) $(OPT_OPENACC) $(OPT_PERF0)
+OPT_NOCB  = $(OPT_BASE) $(OPT_OPENACC) $(OPT_PERF2) 
+CXXFLAGS = -acc -Kieee -Mnofma $(OPT_OPENACC)
+OBJS_REPROD= spll_mode_sum_ll.o
+$(OBJS_REPROD) : OPT = $(OPT_BASE) $(OPT_OPENACC) $(OPT_PERF2) -Mvect=nosimd -Minfo=all 
+endif
+#
+ifeq "$(OPTLEVEL)" "OPENACCDEFONLY"
+CPPFLAGS    += -DMNH_OPENACC -D_FAKEOPENACC
+OPT       = $(OPT_BASE) $(OPT_NOOPENACC) $(OPT_PERF2)
+OPT0      = $(OPT_BASE) $(OPT_NOOPENACC) $(OPT_PERF0)
+OPT_NOCB  = $(OPT_BASE) $(OPT_NOOPENACC) $(OPT_PERF2)
+CXXFLAGS = -Kieee -Mnofma $(OPT_NOOPENACC) 
+OBJS_REPROD= spll_mode_sum_ll.o
+$(OBJS_REPROD) : OPT = $(OPT_BASE) $(OPT_NOOPENACC) $(OPT_PERF2) -Mvect=nosimd -Minfo=all 
+endif
+#
+ifeq "$(OPTLEVEL)" "NOOPENACC"
+#CPPFLAGS   += -D_OPT_LINEARIZED_LOOPS
+OPT       = $(OPT_BASE) $(OPT_NOOPENACC) $(OPT_PERF2)
+OPT0      = $(OPT_BASE) $(OPT_NOOPENACC) $(OPT_PERF0)
+OPT_NOCB  = $(OPT_BASE) $(OPT_NOOPENACC) $(OPT_PERF2)
+CXXFLAGS = -Kieee -Mnofma $(OPT_NOOPENACC)
+OBJS_REPROD= spll_mode_sum_ll.o
+$(OBJS_REPROD) : OPT = $(OPT_BASE) $(OPT_NOOPENACC) $(OPT_PERF2) -Mvect=nosimd -Minfo=all -g
+endif
+#
+CC = pgcc
+CXXFLAGS += $(TP)
+CFLAGS   += $(TP)
+FC = pgf90
+ifeq "$(VER_MPI)" "MPIAUTO"
+F90 = mpif90
+CC = mpicc
+CXX = mpicxx
+else
+F90 = pgf90
+CC = pgcc
+CXX = pgcxx
+endif
+#
+F77FLAGS  =  $(OPT)
+F77 = $(F90)
+F90FLAGS  =  $(OPT)
+FX90 = $(F90)
+FX90FLAGS =  $(OPT)
+#
+LDFLAGS    =   -Wl,-warn-once $(OPT)
+#
+# preprocessing flags 
+#
+CPP = cpp -P -traditional -Wcomment -D_OPENACC=201711
+#
+CPPFLAGS_SURFEX    =
+CPPFLAGS_SURCOUCHE +=
+CPPFLAGS_RAD       =
+CPPFLAGS_NEWLFI    = -DSWAPIO -DLINUX -DLFI_INT=${LFI_INT}
+CPPFLAGS_MNH       = -DMNH -DMNH_PGI -DSFX_MNH
+CPPFLAGS_MNH      += -Uvector -Upixel
+#
+# Gribex flags
+#
+TARGET_GRIBEX=linux
+CNAME_GRIBEX=_pgf77
+GRIBAPI_CONF="CPP=cpp"
+#
+# Netcdf/HDF5 flags
+#
+#HDF_CONF= CXXFLAGS=$(TP)
+HDF_OPT ?= $(TP)
+NETCDF_OPT ?= $(TP)
+CDF_CONF="CPP=cpp"
+HDF_CONF="CPP=cpp"
+#
+# BITREP flags
+#
+#if MNH_BITREP exists => compile with the BITREP library
+MNH_BITREP = YES
+ifeq "$(MNH_BITREP)" "YES"
+CPPFLAGS_MNH += -DMNH_BITREP
+endif
+#
+# LIBTOOLS flags
+#
+#if MNH_TOOLS exists => compile the tools
+MNH_TOOLS = yes
+#
+## COMPRESS flag
+#
+#if MNH_COMPRESS exists => compile the COMPRESS library (for LFI files)
+MNH_COMPRESS=yes
+#
+## S4PY flag
+#
+#if MNH_S4PY exists => compile the libs4py library (for epygram)
+#MNH_S4PY=no
+#
+##########################################################
+#                                                        #
+# Source of MESONH PACKAGE  Distribution                 #
+#                                                        #
+##########################################################
+#DIR_SURFEX   += ARCH_SRC/surfex.MNH-462
+
+OBJS_NOCB +=  spll_isba.o
+#
+include Makefile.MESONH.mk
+#
+##########################################################
+#                                                        #
+# extra VPATH, Compilation flag modification             #
+#         systeme module , etc ...                       #
+#         external precompiled module librairie          #
+#         etc ...                                        #
+#                                                        #
+##########################################################
+OBJS_O1 += spll_modd_isba_n.o spll_mode_construct_ll.o \
+         spll_init_surf_atm_n.o spll_mode_scatter_ll.o spll_convert_patch_teb.o \
+         spll_define_mask_n.o spll_del1dfield_ll.o spll_mode_fm.o spll_mode_gather_ll.o \
+         spll_convect_updraft.o spll_convect_updraft_shal.o \
+         spll_mode_dustopt.o spll_mode_saltopt.o \
+         spll_aeroopt_get.o spll_write_lfifm1_for_diag_supp.o spll_write_lfifm1_for_diag.o spll_write_lfifm_n.o \
+
+#spll_unpack_1d_2d_from2d.o
+#spll_pack_isba_patch_n.o 
+#spll_phys_param_n.o
+$(OBJS_O1) : OPT = $(OPT_BASE) $(OPT_PERF1)
+
+OBJS_O0= spll_mode_mppdb.o \
+         spll_fft55.o spll_fft.o spll_flat_invz.o \
+         spll_mode_repro_sum.o \
+         spll_modd_les_n.o
+
+#         spll_fast_terms.o 
+#         spll_modd_ch_solver_n.o \
+#         spll_modd_dummy_gr_field_n.o spll_modd_dyn_n.o 
+# spll_mode_sum_ll.o
+$(OBJS_O0) : OPT = -g $(OPT_BASE) $(OPT_PERF0)
+
+OBJS_O2= spll_mode_device.o
+$(OBJS_O2) : OPT = $(OPT_BASE) $(OPT_OPENACC) $(OPT_PERF2)
+
+ifneq "$(findstring 8,$(LFI_INT))" ""
+OBJS_I8=spll_NEWLFI_ALL.o
+$(OBJS_I8) : OPT = $(OPT_BASE) $(OPT_PERF2) $(OPT_I8)
+endif
+
+ifeq "$(MNH_INT)" "8"
+OBJS_I4=spll_modd_netcdf.o
+$(OBJS_I4) : OPT = $(OPT_BASE_I4)
+endif
diff --git a/src/Rules.LXpgi2004.mk b/src/Rules.LXpgi2004.mk
new file mode 100644
index 0000000000000000000000000000000000000000..d3c5f1039a3b326e369807bf0a590ce2adddb7b5
--- /dev/null
+++ b/src/Rules.LXpgi2004.mk
@@ -0,0 +1,279 @@
+#MNH_LIC Copyright 1994-2019 CNRS, Meteo-France and Universite Paul Sabatier
+#MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+#MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
+#MNH_LIC for details. version 1.
+##########################################################
+#                                                        #
+# Compiler Options                                       #
+#                                                        #
+##########################################################
+#OBJDIR_PATH=${WORKDIR}
+#
+# Processor type
+#TP= -tp=sandybridge
+#TP= -tp=px
+TP= -tp=p7-64
+#
+#Version of CUDA
+#(8.0 at least if compute capability >= 6.0)
+CUDALEVEL=cuda10.1
+#
+#Compute capability of GPU
+#
+OPT_CPTCAP=cc35,cc50,cc60,cc70
+#Aeropc45: cc50
+#Nuwa: cc35
+#Ouessant Firestone K80: cc35
+#Ouessant Minsky P100: cc60
+#
+#Compiler info level
+#OPT_INFO = -Minfo=ftn,accel,inline,ipa,loop,lre,mp,opt,par,unified,vect,ccff
+OPT_INFO = -Minfo=accel
+#
+#Compiler profiling options
+#OPT_PROF = -Mprof=ccff
+#
+#PW: if -Ktrap=fp: nvprof/pgprof do not work   OPT_BASE   =  -Ktrap=fp ...
+#PW: -g: big impact on performance
+OPT_BASE   =  $(TP) -Mbackslash -Mextend -Kieee -nofma  -Mallocatable=95
+#
+OPT_PERF0  =  -O0
+OPT_PERF1  =  -O1
+OPT_PERF2  =  -O2
+#
+OPT_MANAGED   = -Mframe -Mnostack_arrays -Mallocatable=95 -ta=host,tesla:nofma,$(OPT_CPTCAP),$(CUDALEVEL),managed $(OPT_INFO) $(OPT_PROF)
+OPT_MULTICORE = -ta=multicore $(OPT_INFO) $(OPT_PROF)
+OPT_NOOPENACC = -ta=host $(OPT_INFO) $(OPT_PROF)
+OPT_OPENACC   = -Mframe -Mnostack_arrays -Mallocatable=95 -ta=host,tesla:nofma,$(OPT_CPTCAP),$(CUDALEVEL) $(OPT_INFO) $(OPT_PROF)
+#
+OPT_CHECK  =  -C #-Mchkfpstk -Mchkptr
+OPT_I8     =  -i8
+OPT_R8     =  -r8
+#
+ifeq "$(VER_USER)" "ZSOLVER"
+CPPFLAGS  += -DCARTESIANGEOMETRY -DOVERLAPCOMMS -DPIECEWISELINEAR
+PROG_LIST += MG_MAIN MG_MAIN_MNH_ALL
+endif
+#
+IGNORE_OBJS += pgprof.o
+#
+# Real/integer 4/8 option
+#
+MNH_REAL  ?=8
+MNH_INT   ?=4
+#
+ifneq "$(MNH_REAL)" "4"
+OPT_BASE           += $(OPT_R8)
+endif
+#
+OPT_BASE_I4       := $(OPT_BASE)
+ifeq "$(MNH_INT)" "8"
+OPT_BASE          += $(OPT_I8)
+LFI_INT           ?=8
+else
+LFI_INT           ?=4
+endif
+#
+#
+OPT       = $(OPT_BASE) $(OPT_PERF2)
+OPT0      = $(OPT_BASE) $(OPT_PERF0)
+OPT_NOCB  = $(OPT_BASE) $(OPT_PERF2)
+#
+ifeq "$(OPTLEVEL)" "DEBUG"
+OPT       = -g $(OPT_BASE) $(OPT_PERF0) $(OPT_CHECK)
+OPT0      = -g $(OPT_BASE) $(OPT_PERF0) $(OPT_CHECK)
+OPT_NOCB  = -g $(OPT_BASE) $(OPT_PERF0)
+endif
+#
+ifeq "$(OPTLEVEL)" "MANAGED"
+CPPFLAGS    += -DMNH_OPENACC
+OPT       = -g $(OPT_BASE) $(OPT_MANAGED) $(OPT_PERF2)
+OPT0      = -g $(OPT_BASE) $(OPT_MANAGED) $(OPT_PERF0)
+OPT_NOCB  = -g $(OPT_BASE) $(OPT_MANAGED) $(OPT_PERF2) 
+CXXFLAGS = -g -acc -Kieee -Mnofma $(OPT_MANAGED)
+OBJS_REPROD= spll_mode_sum_ll.o
+$(OBJS_REPROD) : OPT = $(OPT_BASE) $(OPT_MANAGED) $(OPT_PERF2) -Mvect=nosimd -Minfo=all -g
+endif
+#
+ifeq "$(OPTLEVEL)" "MANAGEDO2"
+CPPFLAGS    += -DMNH_OPENACC
+OPT       = $(OPT_BASE) $(OPT_MANAGED) $(OPT_PERF2)
+OPT0      = $(OPT_BASE) $(OPT_MANAGED) $(OPT_PERF0)
+OPT_NOCB  = $(OPT_BASE) $(OPT_MANAGED) $(OPT_PERF2) 
+CXXFLAGS = -acc -Kieee -Mnofma $(OPT_MANAGED)
+OBJS_REPROD= spll_mode_sum_ll.o
+$(OBJS_REPROD) : OPT = $(OPT_BASE) $(OPT_MANAGED) $(OPT_PERF2) -Mvect=nosimd -Minfo=all
+OBJS_OPENACC = spll_modd_halo_d.o
+$(OBJS_OPENACC) : OPT = $(OPT_BASE) $(OPT_OPENACC) $(OPT_PERF2)
+endif
+#
+ifeq "$(OPTLEVEL)" "MULTICORE"
+CPPFLAGS    += -DMNH_OPENACC
+OPT       = $(OPT_BASE) $(OPT_MULTICORE) 
+OPT0      = $(OPT_BASE) $(OPT_MULTICORE) $(OPT_PERF0)
+OPT_NOCB  = $(OPT_BASE) $(OPT_MULTICORE) 
+CXXFLAGS = -acc -Kieee -Mnofma $(OPT_MULTICORE)
+endif
+#
+ifeq "$(OPTLEVEL)" "OPENACC"
+CPPFLAGS    += -DMNH_OPENACC
+# -imacros MNH_OPENACC_SHUMAN_MACRO.CPP
+OPT       = -g $(OPT_BASE) $(OPT_OPENACC) $(OPT_PERF0)
+OPT0      = -g $(OPT_BASE) $(OPT_OPENACC) $(OPT_PERF0)
+OPT_NOCB  = -g $(OPT_BASE) $(OPT_OPENACC) $(OPT_PERF0) 
+CXXFLAGS =  -g -acc -Kieee -Mnofma $(OPT_OPENACC)
+OBJS_REPROD= spll_mode_sum_ll.o
+$(OBJS_REPROD) : OPT = $(OPT_BASE) $(OPT_OPENACC) $(OPT_PERF2) -Mvect=nosimd -Minfo=all -g
+endif
+ifeq "$(OPTLEVEL)" "OPENACCO2"
+CPPFLAGS    += -DMNH_OPENACC
+OPT       = $(OPT_BASE) $(OPT_OPENACC) $(OPT_PERF2)
+OPT0      = $(OPT_BASE) $(OPT_OPENACC) $(OPT_PERF0)
+OPT_NOCB  = $(OPT_BASE) $(OPT_OPENACC) $(OPT_PERF2) 
+CXXFLAGS = -acc -Kieee -Mnofma $(OPT_OPENACC)
+OBJS_REPROD= spll_mode_sum_ll.o
+$(OBJS_REPROD) : OPT = $(OPT_BASE) $(OPT_OPENACC) $(OPT_PERF2) -Mvect=nosimd -Minfo=all 
+endif
+#
+ifeq "$(OPTLEVEL)" "OPENACCDEFONLY"
+CPPFLAGS    += -DMNH_OPENACC -D_FAKEOPENACC
+OPT       = $(OPT_BASE) $(OPT_NOOPENACC) $(OPT_PERF2)
+OPT0      = $(OPT_BASE) $(OPT_NOOPENACC) $(OPT_PERF0)
+OPT_NOCB  = $(OPT_BASE) $(OPT_NOOPENACC) $(OPT_PERF2)
+CXXFLAGS = -Kieee -Mnofma $(OPT_NOOPENACC) 
+OBJS_REPROD= spll_mode_sum_ll.o
+$(OBJS_REPROD) : OPT = $(OPT_BASE) $(OPT_NOOPENACC) $(OPT_PERF2) -Mvect=nosimd -Minfo=all 
+endif
+#
+ifeq "$(OPTLEVEL)" "NOOPENACC"
+#CPPFLAGS   += -D_OPT_LINEARIZED_LOOPS
+OPT       = $(OPT_BASE) $(OPT_NOOPENACC) $(OPT_PERF2)
+OPT0      = $(OPT_BASE) $(OPT_NOOPENACC) $(OPT_PERF0)
+OPT_NOCB  = $(OPT_BASE) $(OPT_NOOPENACC) $(OPT_PERF2)
+CXXFLAGS = -Kieee -Mnofma $(OPT_NOOPENACC)
+OBJS_REPROD= spll_mode_sum_ll.o
+$(OBJS_REPROD) : OPT = $(OPT_BASE) $(OPT_NOOPENACC) $(OPT_PERF2) -Mvect=nosimd -Minfo=all -g
+endif
+#
+CC = pgcc
+CXXFLAGS += $(TP)
+CFLAGS   += $(TP)
+FC = pgf90
+ifeq "$(VER_MPI)" "MPIAUTO"
+F90 = mpif90
+CC = mpicc
+CXX = mpicxx
+else
+F90 = pgf90
+CC = pgcc
+CXX = pgcxx
+endif
+#
+F77FLAGS  =  $(OPT)
+F77 = $(F90)
+F90FLAGS  =  $(OPT)
+FX90 = $(F90)
+FX90FLAGS =  $(OPT)
+#
+LDFLAGS    =   -Wl,-warn-once $(OPT)
+#
+# preprocessing flags 
+#
+CPP = cpp -P -traditional -Wcomment -D_OPENACC=201711
+#
+CPPFLAGS_SURFEX    =
+CPPFLAGS_SURCOUCHE +=
+CPPFLAGS_RAD       =
+CPPFLAGS_NEWLFI    = -DSWAPIO -DLINUX -DLFI_INT=${LFI_INT}
+CPPFLAGS_MNH       = -DMNH -DMNH_PGI -DSFX_MNH
+CPPFLAGS_MNH      += -Uvector -Upixel
+#
+# Gribex flags
+#
+TARGET_GRIBEX=linux
+CNAME_GRIBEX=_pgf77
+GRIBAPI_CONF="CPP=cpp"
+CDF_CONF="CPP=cpp"
+#
+# Netcdf/HDF5 flags
+#
+HDF_OPT ?= $(TP)
+NETCDF_OPT ?= $(TP)
+#
+# BITREP flags
+#
+#if MNH_BITREP exists => compile with the BITREP library
+MNH_BITREP = YES
+ifeq "$(MNH_BITREP)" "YES"
+CPPFLAGS_MNH += -DMNH_BITREP
+endif
+#
+# LIBTOOLS flags
+#
+#if MNH_TOOLS exists => compile the tools
+MNH_TOOLS = yes
+#
+## COMPRESS flag
+#
+#if MNH_COMPRESS exists => compile the COMPRESS library (for LFI files)
+MNH_COMPRESS=yes
+#
+## S4PY flag
+#
+#if MNH_S4PY exists => compile the libs4py library (for epygram)
+#MNH_S4PY=no
+#
+##########################################################
+#                                                        #
+# Source of MESONH PACKAGE  Distribution                 #
+#                                                        #
+##########################################################
+#DIR_SURFEX   += ARCH_SRC/surfex.MNH-462
+
+OBJS_NOCB +=  spll_isba.o
+#
+include Makefile.MESONH.mk
+#
+##########################################################
+#                                                        #
+# extra VPATH, Compilation flag modification             #
+#         systeme module , etc ...                       #
+#         external precompiled module librairie          #
+#         etc ...                                        #
+#                                                        #
+##########################################################
+OBJS_O1 += spll_modd_isba_n.o spll_mode_construct_ll.o \
+         spll_init_surf_atm_n.o spll_mode_scatter_ll.o spll_convert_patch_teb.o \
+         spll_define_mask_n.o spll_del1dfield_ll.o spll_mode_fm.o spll_mode_gather_ll.o \
+         spll_convect_updraft.o spll_convect_updraft_shal.o \
+         spll_mode_dustopt.o spll_mode_saltopt.o \
+         spll_aeroopt_get.o spll_write_lfifm1_for_diag_supp.o spll_write_lfifm1_for_diag.o spll_write_lfifm_n.o \
+
+#spll_unpack_1d_2d_from2d.o
+#spll_pack_isba_patch_n.o 
+#spll_phys_param_n.o
+$(OBJS_O1) : OPT = $(OPT_BASE) $(OPT_PERF1)
+
+OBJS_O0= spll_mode_mppdb.o \
+         spll_fft55.o spll_fft.o spll_flat_invz.o \
+         spll_mode_repro_sum.o \
+         spll_modd_les_n.o
+
+#         spll_fast_terms.o 
+#         spll_modd_ch_solver_n.o \
+#         spll_modd_dummy_gr_field_n.o spll_modd_dyn_n.o 
+# spll_mode_sum_ll.o
+$(OBJS_O0) : OPT = -g $(OPT_BASE) $(OPT_PERF0)
+
+OBJS_O2= spll_mode_device.o
+$(OBJS_O2) : OPT = $(OPT_BASE) $(OPT_OPENACC) $(OPT_PERF2)
+
+ifneq "$(findstring 8,$(LFI_INT))" ""
+OBJS_I8=spll_NEWLFI_ALL.o
+$(OBJS_I8) : OPT = $(OPT_BASE) $(OPT_PERF2) $(OPT_I8)
+endif
+
+ifeq "$(MNH_INT)" "8"
+OBJS_I4=spll_modd_netcdf.o
+$(OBJS_I4) : OPT = $(OPT_BASE_I4)
+endif
diff --git a/src/ZSOLVER/anel_balancen.f90 b/src/ZSOLVER/anel_balancen.f90
new file mode 100644
index 0000000000000000000000000000000000000000..c1659356c3616b260ddda416eb328e07ddb3faca
--- /dev/null
+++ b/src/ZSOLVER/anel_balancen.f90
@@ -0,0 +1,334 @@
+!MNH_LIC Copyright 1994-2020 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+!     ##########################
+      MODULE MODI_ANEL_BALANCE_n
+!     ##########################
+!
+INTERFACE
+!
+SUBROUTINE ANEL_BALANCE_n(PRESIDUAL)
+!
+REAL, OPTIONAL                 :: PRESIDUAL
+END SUBROUTINE ANEL_BALANCE_n
+!
+END INTERFACE
+!
+END MODULE MODI_ANEL_BALANCE_n
+!
+!
+!
+!     ################################
+      SUBROUTINE ANEL_BALANCE_n(PRESIDUAL)
+!
+!     ################################
+!
+!
+!!****  *ANEL_BALANCE_n* - routine to apply an anelastic correction
+!!                   
+!!
+!!    PURPOSE
+!!    -------
+!       The purpose of this routine is to  fulfill the anelastic balance
+!    in case of non-vanishing orography
+!
+!
+!
+!!**  METHOD
+!!    ------
+!!      The coefficients for the flat operator are first computed. Then the
+!!    pressure equation is solved and the pressure gradient is added to the wind
+!!    components in order to render this wind field non-divergent.
+!!
+!!    EXTERNAL
+!!    --------
+!!    TRID     : to compute coefficients for the flat operator
+!!    PRESSURE : to solve the pressure equation and add the pressure term to
+!!               wind
+!!    MXM,MYM,MZM : to average a field at mass point in the x,y,z directions
+!!
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------
+!!
+!!      Module MODD_CONF    : contains configuration variables for all models.
+!!         NVERB : verbosity level for output-listing
+!!
+!!      Module MODD_GRID_n  : contains grid variables
+!!         XMAP,XXHAT,XYHAT,XZZ
+!!
+!!      Module MODD_REF_n   : contains reference state variables 
+!!         XRHODJ,XTHVREF,XEXNREF,XRHODREF,XRVREF
+!!
+!!      Module MODD_REF_n   : contains reference state variables 
+!!         XLINMASS : lineic mass along the lateral boundaries
+!!
+!!      Module MODD_FIELD_n : contains prognostic variables
+!!         XUT,XVT,XWT,XTHT,XRT
+!! 
+!!      Module MODD_DYN_n : contains parameters for the dynamics
+!!         CPRESOPT : option for the pressure solver
+!!         NITR     : number of iterations for the solver
+!!         XRELAX   : relaxation coefficient used in the Richardson method
+!! 
+!!      Module MODD_LBC_n : contains parameters relative to the boundaries
+!!         CLBCX    : choice of lateral boundary condition along x
+!!         CLBCY    : choice of lateral boundary condition along y
+!!
+!!    REFERENCE
+!!    ---------
+!!      NONE
+!!
+!!
+!!    AUTHOR
+!!    ------
+!!      V. Ducrocq       * Meteo France *
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original     6/09/94
+!!      J. Stein     4/11/94  put the pressure solver parameters in namelist
+!!      J. Stein     2/12/94  source cleaning
+!!      J.P. Lafore 03/01/95  call to PRESSURE to account for absolute pressure
+!!      J. Stein    17/01/95  bug in the pressure call
+!!      J. Stein    15/03/95  remove R from the historical variables
+!!      J.Stein and J.P. lafore 17/04/96 new version including the way to choose
+!!            the model number and the instant where the projection is performed
+!!      Stein,Lafore 14/01/97 new anelastic equations
+!!      M.Faivre    2014
+!!      M.Moge      08/2015   removing UPDATE_HALO_ll(XRHODJ) + EXTRAPOL on ZRU and ZRV in part 3.1
+!!      J.Escobar : 15/09/2015 : WENO5 & JPHEXT <> 1 
+!!  Philippe Wautelet: 05/2016-04/2018: new data structures and calls for I/O
+!  P. Wautelet 20/05/2019: add name argument to ADDnFIELD_ll + new ADD4DFIELD_ll subroutine
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+!
+!
+USE MODE_ll
+USE MODE_MODELN_HANDLER
+!
+USE MODD_CONF    ! declarative modules
+USE MODD_PARAMETERS
+USE MODD_GRID_n
+USE MODD_DIM_n
+USE MODD_METRICS_n
+USE MODD_REF_n
+USE MODD_FIELD_n
+USE MODD_DYN_n
+USE MODD_LBC_n
+!
+USE MODI_TRIDZ    ! interface modules
+USE MODI_PRESSUREZ
+USE MODE_SPLITTINGZ_ll
+USE MODI_SHUMAN
+!
+USE MODD_ARGSLIST_ll, ONLY : LIST_ll
+USE MODE_MPPDB
+USE MODE_EXTRAPOL
+!
+IMPLICIT NONE
+!
+!*       0.1   Declarations of arguments :
+!
+REAL, OPTIONAL                 :: PRESIDUAL
+!
+!*       0.2   Declarations of local variables :
+!
+INTEGER :: IRESP                  ! return code
+INTEGER :: IIY,IJY                ! same variable for Y decomposition
+INTEGER :: ITCOUNT                ! counter value of temporal loop set to 1 ( this
+                                  ! means that no guess of the pressure is available for
+                                  ! the pressure solver
+REAL    :: ZDXHATM                   ! mean grid increment in the x direction
+REAL    :: ZDYHATM                   ! mean grid increment in the y direction
+REAL, DIMENSION (SIZE(XRHODJ,3)) :: ZRHOM   !  mean of XRHODJ on the plane x y
+                                            !  localized at a mass level
+!
+REAL, DIMENSION(SIZE(XRHODJ,3))    :: ZAF,ZCF  ! vector giving the nonvanishing
+REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZBFY    ! elements of the tri-diag matrix
+                                               ! in the pressure equation
+REAL, DIMENSION(:), ALLOCATABLE   :: ZTRIGSX   ! arrays of sin or cos values for
+REAL, DIMENSION(:), ALLOCATABLE   :: ZTRIGSY   ! the FFT in x and y directions
+INTEGER, DIMENSION(19)            :: IIFAXX    ! decomposition in prime numbers
+INTEGER, DIMENSION(19)            :: IIFAXY    ! for the FFT in x and y
+                                               ! directions
+REAL, DIMENSION(SIZE(XRHODJ,1),SIZE(XRHODJ,2),SIZE(XRHODJ,3)) :: ZPABST
+                                               ! Potential at time t
+REAL, DIMENSION(SIZE(XRHODJ,1),SIZE(XRHODJ,2),SIZE(XRHODJ,3)) :: ZRU,ZRV,ZRW
+                                               ! Rhod * (U,V,W)
+REAL, DIMENSION(SIZE(XRHODJ,1),SIZE(XRHODJ,2),SIZE(XRHODJ,3)) :: ZTH
+REAL, DIMENSION(:,:,:,:), ALLOCATABLE :: ZRR
+!
+INTEGER                       ::       IRR     ! Total number of water variables
+INTEGER                       ::       IRRL    ! Number of liquid water variables
+INTEGER                       ::       IRRI    ! Number of solid water variables
+REAL                          ::  ZDRYMASST    ! Mass of dry air Md
+REAL                          ::  ZREFMASS     ! Total mass of the ref. atmosphere
+REAL                          ::  ZMASS_O_PHI0 ! Mass / Phi0
+LOGICAL                       ::  GCLOSE_OUT   ! switch for the LFI writing
+CHARACTER (LEN= 28)           ::  YFMFILE      ! virtual FM file
+INTEGER                       ::  IMI          ! model index
+!JUAN
+INTEGER                               ::  IIU_B,IJU_B,IKU
+INTEGER                               ::  IIU_SXP2_YP1_Z_ll,IJU_SXP2_YP1_Z_ll,IKU_SXP2_YP1_Z_ll
+REAL, DIMENSION(:,:,:), ALLOCATABLE   ::  ZBFB,ZBF_SXP2_YP1_Z   
+REAL, DIMENSION(:,:,:), ALLOCATABLE   :: ZAF_ZS,ZBF_ZS,ZCF_ZS
+REAL, DIMENSION(:,:)  , ALLOCATABLE   :: ZDXATH_ZS,ZDYATH_ZS
+REAL, DIMENSION(:,:,:), ALLOCATABLE   :: ZRHO_ZS    
+REAL, DIMENSION(:),     ALLOCATABLE   :: ZA_K,ZB_K,ZC_K,ZD_K                 
+!JUAN
+!
+INTEGER :: IINFO_ll
+TYPE(LIST_ll), POINTER :: TZFIELDS_ll=>NULL()   ! list of fields to exchange
+!
+!-------------------------------------------------------------------------------
+!
+!*       1.     PROLOGUE  :
+!               --------
+!
+CALL GET_DIM_EXT_ll('Y',IIY,IJY)
+IF (L2D) THEN
+  ALLOCATE(ZBFY(IIY,IJY,SIZE(XRHODJ,3)))
+ELSE
+  ALLOCATE(ZBFY(IJY,IIY,SIZE(XRHODJ,3)))
+ENDIF
+ALLOCATE(ZTRIGSX(3*(NIMAX_ll+2*JPHEXT)))
+ALLOCATE(ZTRIGSY(3*(NJMAX_ll+2*JPHEXT)))
+!JUAN Z_SPLITING
+IKU=SIZE(XRHODJ,3)
+CALL GET_DIM_EXT_ll('B',IIU_B,IJU_B)
+ALLOCATE(ZBFB(IIU_B,IJU_B,IKU))
+!
+ALLOCATE(ZAF_ZS(IIU_B,IJU_B,IKU))
+ALLOCATE(ZBF_ZS(IIU_B,IJU_B,IKU))
+ALLOCATE(ZCF_ZS(IIU_B,IJU_B,IKU))
+ALLOCATE(ZDXATH_ZS(IIU_B,IJU_B))
+ALLOCATE(ZDYATH_ZS(IIU_B,IJU_B))
+ALLOCATE(ZRHO_ZS(IIU_B,IJU_B,IKU))
+ALLOCATE(ZA_K(IKU))
+ALLOCATE(ZB_K(IKU))
+ALLOCATE(ZC_K(IKU))
+ALLOCATE(ZD_K(IKU))
+!
+CALL GET_DIM_EXTZ_ll('SXP2_YP1_Z',IIU_SXP2_YP1_Z_ll,IJU_SXP2_YP1_Z_ll,IKU_SXP2_YP1_Z_ll)
+ALLOCATE(ZBF_SXP2_YP1_Z(IIU_SXP2_YP1_Z_ll,IJU_SXP2_YP1_Z_ll,IKU_SXP2_YP1_Z_ll))
+!
+!JUAN Z_SPLITING
+CALL MPPDB_CHECK3D(XRHODJ,"anel_balancen1-::XRHODJ",PRECISION)
+CALL MPPDB_CHECK3D(XUT,"anel_balancen1-::XUT",PRECISION)
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.     PRESSURE SOLVER INITIALIZATION :
+!               -------------------------------
+!
+!
+CALL TRIDZ(CLBCX,CLBCY,XMAP,XDXHAT,XDYHAT,CPRESOPT,                     &
+          ZDXHATM,ZDYHATM,ZRHOM,                                        &
+          ZAF,ZCF,ZTRIGSX,ZTRIGSY,IIFAXX,IIFAXY,XRHODJ,XTHVREF,XZZ,ZBFY,&
+          ZBFB,ZBF_SXP2_YP1_Z,                                          &
+          ZAF_ZS,ZBF_ZS,ZCF_ZS,                                         &
+          ZDXATH_ZS,ZDYATH_ZS,ZRHO_ZS,                      &
+          ZA_K,ZB_K,ZC_K,ZD_K) !JUAN  FULL ZSOLVER
+CALL MPPDB_CHECK3D(XRHODJ,"anel_balancen1-after TRIDZ::XRHODJ",PRECISION)
+!
+!-------------------------------------------------------------------------------
+!
+!*       3.      ANELASTIC CORRECTION :
+!                ---------------------
+!
+!
+!*       3.1     multiplication by RHODJ
+!
+!$20140710 UPHALO on XRHODJ
+!CALL ADD3DFIELD_ll( TZFIELDS_ll, XRHODJ, 'ANEL_BALANCE_n::XRHODJ' )
+!CALL UPDATE_HALO_ll(TZFIELDS_ll,IINFO_ll)
+!CALL CLEANLIST_ll(TZFIELDS_ll)
+CALL MPPDB_CHECK3D(XRHODJ,"anel_balancen3.1-after update halo::XRHODJ",PRECISION)
+CALL MPPDB_CHECK3D(XUT,"anel_balancen3.1-after update halo::XUT",PRECISION)
+CALL MPPDB_CHECK3D(XWT,"anel_balancen3.1-after update halo::XWT",PRECISION)
+!
+ZRU(:,:,:) = MXM(XRHODJ) * XUT(:,:,:)
+ZRV(:,:,:) = MYM(XRHODJ) * XVT(:,:,:)
+ZRW(:,:,:) = MZM(XRHODJ) * XWT(:,:,:)
+ZTH(:,:,:) = XTHT(:,:,:)
+ALLOCATE(ZRR(SIZE(XRHODJ,1),SIZE(XRHODJ,2),SIZE(XRHODJ,3),SIZE(XRT,4)))
+ZRR(:,:,:,:) = XRT(:,:,:,:)
+!20131112 appli update_halo_ll
+CALL ADD3DFIELD_ll( TZFIELDS_ll, ZRU, 'ANEL_BALANCE_n::ZRU' )
+CALL ADD3DFIELD_ll( TZFIELDS_ll, ZRV, 'ANEL_BALANCE_n::ZRV' )
+CALL ADD3DFIELD_ll( TZFIELDS_ll, ZRW, 'ANEL_BALANCE_n::ZRW' )
+CALL ADD3DFIELD_ll( TZFIELDS_ll, ZTH, 'ANEL_BALANCE_n::ZTH' )
+CALL UPDATE_HALO_ll(TZFIELDS_ll,IINFO_ll)
+CALL CLEANLIST_ll(TZFIELDS_ll)
+CALL MPPDB_CHECK3D(ZRU,"anel_balancen3.1-after1stupdhalo::ZRU",PRECISION)
+!$20131125 add extrapol on ZRU to have correct boundaries
+!CALL EXTRAPOL('W',ZRU)  ! ZRU boundaries now correct
+CALL MPPDB_CHECK3D(ZRU,"anel_balancen3.1-afterextrapol W::ZRU",PRECISION)
+!20131126 add extrapol on ZRV to have correct boundaries
+!CALL EXTRAPOL('S',ZRV)  ! ZRV boundaries now correct
+CALL MPPDB_CHECK3D(ZRV,"anel_balancen3.1-afterextrapol S::ZRV",PRECISION)
+CALL MPPDB_CHECK3D(ZRW,"anel_balancen3.1-afterextrapol S::ZRW",PRECISION)
+!
+!
+!
+!
+!*       3.2     satisfy the anelastic constraint
+!
+ITCOUNT      =-1     ! no first guess of the pressure is available
+ZPABST(:,:,:)= 0.    !       ==================CAUTION=====================
+ZDRYMASST    = 0.    !      |   Initialization necessary for the           |
+ZREFMASS     = 0.    !      |  computation of the absolute pressure,       |
+ZMASS_O_PHI0 = 1.    !      |  which is here not needed                    |
+IRR  = 0             !      |                                              |
+IRRL = 0             !      |                                              |
+IRRI = 0             !       ==============================================
+GCLOSE_OUT=.FALSE.
+YFMFILE='UNUSED'
+!
+IMI = GET_CURRENT_MODEL_INDEX()
+CALL PRESSUREZ(CLBCX,CLBCY,CPRESOPT,NITR,LITRADJ,ITCOUNT,XRELAX,IMI,  &
+               XRHODJ,XDXX,XDYY,XDZZ,XDZX,XDZY,ZDXHATM,ZDYHATM,ZRHOM, &
+               ZAF,ZBFY,ZCF,ZTRIGSX,ZTRIGSY,IIFAXX,IIFAXY,            &
+               IRR,IRRL,IRRI,ZDRYMASST,ZREFMASS,ZMASS_O_PHI0,         &
+               ZTH,ZRR,XRHODREF,XTHVREF,XRVREF,XEXNREF, XLINMASS,     &
+               ZRU,ZRV,ZRW,ZPABST,                                    &
+               ZBFB,ZBF_SXP2_YP1_Z,                                   &
+               XAF_ZS,XBF_ZS,XCF_ZS,                                  &
+               XDXATH_ZS,XDYATH_ZS,XRHO_ZS,                           &
+               XA_K,XB_K,XC_K,XD_K,                                   &
+               PRESIDUAL                          )
+!
+CALL MPPDB_CHECK3D(XRHODJ,"anel_balancen3.2-after pressurez halo::XRHODJ",PRECISION)
+CALL MPPDB_CHECK3D(ZRU,"anel_balancen3.2-after pressurez::ZRU",PRECISION)
+CALL MPPDB_CHECK3D(ZRV,"anel_balancen3.2-after pressurez::ZRV",PRECISION)
+!
+DEALLOCATE(ZBFY,ZTRIGSX,ZTRIGSY,ZRR,ZBF_SXP2_YP1_Z)
+!*       3.2     return to the historical variables
+!
+!20131112 appli update_halo_ll and associated operations
+XUT(:,:,:) = ZRU(:,:,:) / MXM(XRHODJ)
+XVT(:,:,:) = ZRV(:,:,:) / MYM(XRHODJ)
+XWT(:,:,:) = ZRW(:,:,:) / MZM(XRHODJ)
+!20131112 appli update_halo_ll to XUT,XVT,XWT
+CALL ADD3DFIELD_ll( TZFIELDS_ll, XUT, 'ANEL_BALANCE_n::XUT' )
+CALL ADD3DFIELD_ll( TZFIELDS_ll, XVT, 'ANEL_BALANCE_n::XVT' )
+CALL ADD3DFIELD_ll( TZFIELDS_ll, XWT, 'ANEL_BALANCE_n::XWT' )
+CALL UPDATE_HALO_ll(TZFIELDS_ll,IINFO_ll)
+CALL CLEANLIST_ll(TZFIELDS_ll)
+CALL MPPDB_CHECK3D(XUT,"anel_balancen3.2-afterupdhalo::XUT",PRECISION)
+CALL MPPDB_CHECK3D(XVT,"anel_balancen3.2-afterupdhalo::XVT",PRECISION)
+!20131125 apply extrapol to fix boundary issue in //
+CALL EXTRAPOL('W',XUT)
+CALL EXTRAPOL('S',XVT)
+CALL MPPDB_CHECK3D(XUT,"anel_balancen3.2-after extrapolW::XUT",PRECISION)
+CALL MPPDB_CHECK3D(XVT,"anel_balancen3.2-after extrapolS::XVT",PRECISION)
+!
+!
+!-------------------------------------------------------------------------------
+!
+END SUBROUTINE ANEL_BALANCE_n
diff --git a/src/ZSOLVER/contrav.f90 b/src/ZSOLVER/contrav.f90
new file mode 100644
index 0000000000000000000000000000000000000000..ebef79590bb7b5f6faa48cb6a8a680d0525a4f3e
--- /dev/null
+++ b/src/ZSOLVER/contrav.f90
@@ -0,0 +1,896 @@
+!MNH_LIC Copyright 1994-2020 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+!     ####################
+      MODULE MODI_CONTRAV
+!     ####################
+!
+INTERFACE
+!
+      SUBROUTINE CONTRAV(HLBCX,HLBCY,PRUT,PRVT,PRWT,PDXX,PDYY,PDZZ,PDZX,PDZY,  &
+                         PRUCT,PRVCT,PRWCT,KADV_ORDER                       )
+!
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX  ! X direction LBC type
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY  ! Y direction LBC type                         
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PRUT       ! Cartesian comp along x
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PRVT       ! Cartesian comp along y
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PRWT       ! Cartesian comp along z
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PDXX       ! Metric coefficients
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PDYY       ! Metric coefficients
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PDZZ       ! Metric coefficients
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PDZX       ! Metric coefficients
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PDZY       ! Metric coefficients
+REAL, DIMENSION(:,:,:),  INTENT(OUT)   ::  PRUCT      ! Contrav comp along x-bar
+REAL, DIMENSION(:,:,:),  INTENT(OUT)   ::  PRVCT      ! Contrav comp along y-bar
+REAL, DIMENSION(:,:,:),  INTENT(OUT)   ::  PRWCT      ! Contrav comp along z-bar
+INTEGER,                 INTENT(IN)    ::  KADV_ORDER ! Order of the advection scheme
+!
+END SUBROUTINE CONTRAV
+!
+#ifdef MNH_OPENACC
+      SUBROUTINE CONTRAV_DEVICE(HLBCX,HLBCY,PRUT,PRVT,PRWT,PDXX,PDYY,PDZZ,PDZX,PDZY,  &
+                         PRUCT,PRVCT,PRWCT,KADV_ORDER,Z1,Z2,ODATA_ON_DEVICE     )
+!
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX  ! X direction LBC type
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY  ! Y direction LBC type
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PRUT       ! Cartesian comp along x
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PRVT       ! Cartesian comp along y
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PRWT       ! Cartesian comp along z
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PDXX       ! Metric coefficients
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PDYY       ! Metric coefficients
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PDZZ       ! Metric coefficients
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PDZX       ! Metric coefficients
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PDZY       ! Metric coefficients
+REAL, DIMENSION(:,:,:),  INTENT(OUT)   ::  PRUCT      ! Contrav comp along x-bar
+REAL, DIMENSION(:,:,:),  INTENT(OUT)   ::  PRVCT      ! Contrav comp along y-bar
+REAL, DIMENSION(:,:,:),  INTENT(OUT)   ::  PRWCT      ! Contrav comp along z-bar
+INTEGER,                 INTENT(IN)    ::  KADV_ORDER ! Order of the advection scheme
+REAL, DIMENSION(:,:,:),  INTENT(OUT)   :: Z1,Z2       ! Work arrays
+LOGICAL, OPTIONAL,       INTENT(IN)    :: ODATA_ON_DEVICE ! Is some of the data on the accelerator device
+!
+!
+END SUBROUTINE CONTRAV_DEVICE
+#endif
+!
+END INTERFACE
+!
+END MODULE MODI_CONTRAV 
+!
+!
+!
+!     ##############################################################
+      SUBROUTINE CONTRAV(HLBCX,HLBCY,PRUT,PRVT,PRWT,PDXX,PDYY,PDZZ,PDZX,PDZY,  &
+                         PRUCT,PRVCT,PRWCT,KADV_ORDER                        )
+!     ##############################################################
+!
+!!****  *CONTRAV * - computes the contravariant components from the
+!!       cartesian components
+!!
+!!    PURPOSE
+!!    -------
+!       This routine computes the contravariant components of vector
+!     defined by its cartesian components (U,V,W) , using the following
+!     formulae:
+!     UC = U / DXX
+!     VC = V / DYY
+!               (     ----------x    ----------y )  
+!               (           ---z           ---z  )
+!           1   (            U              V    )
+!     WC = ---  ( W - DZX * ---    - DZY * ---   )
+!          DZZ  (           DXX            DYY   )
+!
+!  
+!       In the no-topography case, WC = W / DZZ
+!
+!
+!!**  METHOD
+!!    ------
+!!      We employ the Shuman operators to compute the averages. The metric
+!!    coefficients PDXX, PDYY, PDZX, PDZY, PDZZ are dummy arguments
+!!
+!!
+!!    EXTERNAL 
+!!    --------
+!!
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------
+!!
+!!      Module MODD_CONF   : contains configuration variable 
+!!           LFLAT : Logical for topography
+!!                  = .TRUE.  if Zs = 0 (Flat terrain)
+!!
+!!    REFERENCE
+!!    ---------
+!!      Book2 of documentation (subroutine CONTRAV)
+!!
+!!
+!!    AUTHOR
+!!    ------
+!!      J.L. Redelsperger     * CNRM *
+!!	J.-P. Pinty      * Laboratoire d'Aerologie*
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original   27/07/94
+!!      Corrections 3/08/94 (by J.P. Lafore)
+!!      Corrections 17/10/94 (by J.P. Lafore) WC modified for w-advection
+!!      Corrections 19/01/11 (by J.P. Pinty) WC 4th order
+!!      Corrections 28/03/11 (by V.Masson) // of WC 4th order
+!!      J.Escobar 21/03/2013: for HALOK comment all NHALO=1 test
+!  P. Wautelet 20/05/2019: add name argument to ADDnFIELD_ll + new ADD4DFIELD_ll subroutine
+!----------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+USE MODD_CONF
+USE MODD_PARAMETERS
+USE MODD_GRID_n, ONLY: XZZ
+!
+USE MODD_ARGSLIST_ll, ONLY : HALO2LIST_ll
+USE MODE_ll
+!
+USE MODI_GET_HALO
+!
+USE MODE_MPPDB
+!
+IMPLICIT NONE
+!
+!*       0.1   declarations of arguments    
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX ! X direction LBC type
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY ! Y direction LBC type
+!
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PRUT     ! Cartesian comp along x
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PRVT     ! Cartesian comp along y
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PRWT     ! Cartesian comp along z
+!
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PDXX     ! Metric coefficients
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PDYY     ! Metric coefficients
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PDZZ     ! Metric coefficients
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PDZX     ! Metric coefficients
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PDZY     ! Metric coefficients
+!
+!
+REAL, DIMENSION(:,:,:),  INTENT(OUT)   ::  PRUCT    ! Contrav comp along x-bar
+REAL, DIMENSION(:,:,:),  INTENT(OUT)   ::  PRVCT    ! Contrav comp along y-bar
+REAL, DIMENSION(:,:,:),  INTENT(OUT)   ::  PRWCT    ! Contrav comp along z-bar
+INTEGER,                 INTENT(IN)    ::  KADV_ORDER ! Order of the advection scheme
+!
+!
+!*       0.2   declarations of local variables
+!              
+REAL, DIMENSION(SIZE(PDXX,1),SIZE(PDXX,2),SIZE(PDXX,3)):: Z1,Z2
+INTEGER :: IIB,IIE,IJB,IJE,IKB,IKE
+INTEGER :: IIU, IJU, IKU
+INTEGER:: IW,IE,IS,IN   ! Coordinate of forth order diffusion area
+!
+TYPE(LIST_ll),      POINTER :: TZFIELD_U, TZFIELD_V, TZFIELD_DZX, TZFIELD_DZY
+TYPE(HALO2LIST_ll), POINTER :: TZHALO2_U, TZHALO2_V, TZHALO2_DZX, TZHALO2_DZY
+INTEGER                     :: IINFO_ll
+!-----------------------------------------------------------------------
+!
+!*       1.    Compute the horizontal contravariant components
+!              -----------------------------------------------
+!
+IF (MPPDB_INITIALIZED) THEN
+  !Check all IN arrays
+  CALL MPPDB_CHECK(PRUT,"CONTRAV beg:PRUT")
+  CALL MPPDB_CHECK(PRVT,"CONTRAV beg:PRVT")
+  CALL MPPDB_CHECK(PRWT,"CONTRAV beg:PRWT")
+  CALL MPPDB_CHECK(PDXX,"CONTRAV beg:PDXX")
+  CALL MPPDB_CHECK(PDYY,"CONTRAV beg:PDYY")
+  CALL MPPDB_CHECK(PDZZ,"CONTRAV beg:PDZZ")
+  CALL MPPDB_CHECK(PDZX,"CONTRAV beg:PDZX")
+  CALL MPPDB_CHECK(PDZY,"CONTRAV beg:PDZY")
+END IF
+!
+IIU= SIZE(PDXX,1)
+IJU= SIZE(PDXX,2)
+IKU= SIZE(PDXX,3)
+!
+CALL GET_INDICE_ll( IIB,IJB,IIE,IJE)
+!
+IKB=1+JPVEXT
+IKE=IKU - JPVEXT
+!
+PRUCT(:,:,:) = PRUT(:,:,:) / PDXX(:,:,:)
+PRVCT(:,:,:) = PRVT(:,:,:) / PDYY(:,:,:)
+!
+IF (KADV_ORDER == 4 ) THEN
+ IF( .NOT. LFLAT) THEN 
+  NULLIFY(TZFIELD_U)
+  NULLIFY(TZFIELD_V)
+  CALL ADD3DFIELD_ll( TZFIELD_U, PRUCT, 'CONTRAV::PRUCT' )
+  CALL ADD3DFIELD_ll( TZFIELD_V, PRVCT, 'CONTRAV::PRVCT' )
+  CALL UPDATE_HALO_ll(TZFIELD_U,IINFO_ll)
+  CALL UPDATE_HALO_ll(TZFIELD_V,IINFO_ll)
+!!$ IF( NHALO==1 ) THEN 
+  NULLIFY(TZFIELD_DZX)
+  NULLIFY(TZFIELD_DZY)
+  CALL ADD3DFIELD_ll( TZFIELD_DZX, PDZX, 'CONTRAV::PDZX' )
+  CALL ADD3DFIELD_ll( TZFIELD_DZY, PDZY, 'CONTRAV::PDZY' )
+  NULLIFY(TZHALO2_U)
+  NULLIFY(TZHALO2_V)
+  NULLIFY(TZHALO2_DZX)
+  NULLIFY(TZHALO2_DZY)
+  CALL INIT_HALO2_ll(TZHALO2_U,1,IIU,IJU,IKU)
+  CALL INIT_HALO2_ll(TZHALO2_V,1,IIU,IJU,IKU)
+  CALL INIT_HALO2_ll(TZHALO2_DZX,1,IIU,IJU,IKU)
+  CALL INIT_HALO2_ll(TZHALO2_DZY,1,IIU,IJU,IKU)
+  CALL UPDATE_HALO2_ll(TZFIELD_U, TZHALO2_U, IINFO_ll)
+  CALL UPDATE_HALO2_ll(TZFIELD_V, TZHALO2_V, IINFO_ll)
+  CALL UPDATE_HALO2_ll(TZFIELD_DZX, TZHALO2_DZX, IINFO_ll)
+  CALL UPDATE_HALO2_ll(TZFIELD_DZY, TZHALO2_DZY, IINFO_ll)
+!!$ END IF
+ END IF
+END IF
+!
+!
+!*       2.    Compute the vertical contravariant components (flat case)
+!              ------------------------------------
+!
+IF (LFLAT) THEN
+  PRWCT(:,:,:) = PRWT(:,:,:) / PDZZ(:,:,:)
+  RETURN
+END IF
+!
+!*       3.    Compute the vertical contravariant components (general case)
+!              ------------------------------------
+!
+Z1 = 0.
+Z2 = 0.
+!
+IF (KADV_ORDER == 2 ) THEN
+!
+  Z1(IIB:IIE,:,IKB:IKE+1)=                                             &
+      (PRUCT(IIB:IIE,:,IKB:IKE+1)+PRUCT(IIB:IIE,:,IKB-1:IKE) )         &
+       *PDZX(IIB:IIE,:,IKB:IKE+1) *0.25                                &
+     +(PRUCT(IIB+1:IIE+1,:,IKB:IKE+1)+PRUCT(IIB+1:IIE+1,:,IKB-1:IKE) ) &
+       *PDZX(IIB+1:IIE+1,:,IKB:IKE+1) *0.25   
+                        
+  Z2(:,IJB:IJE,IKB:IKE+1)=                                             &
+      (PRVCT(:,IJB:IJE,IKB:IKE+1)+PRVCT(:,IJB:IJE,IKB-1:IKE) )         &
+       *PDZY(:,IJB:IJE,IKB:IKE+1) *0.25                                &
+     +(PRVCT(:,IJB+1:IJE+1,IKB:IKE+1)+PRVCT(:,IJB+1:IJE+1,IKB-1:IKE) ) &
+       *PDZY(:,IJB+1:IJE+1,IKB:IKE+1) *0.25   
+  PRWCT=0.             
+  PRWCT(IIB:IIE,IJB:IJE,IKB:IKE+1) =                 &
+      (   PRWT(IIB:IIE,IJB:IJE,IKB:IKE+1)            &
+        - Z1(IIB:IIE,IJB:IJE,IKB:IKE+1)              &
+        - Z2(IIB:IIE,IJB:IJE,IKB:IKE+1)              &
+      ) / PDZZ(IIB:IIE,IJB:IJE,IKB:IKE+1)  
+!
+ELSE IF (KADV_ORDER == 4 ) THEN
+!
+!!$   IF (NHALO == 1) THEN
+      IF ( LWEST_ll() .AND. HLBCX(1)/='CYCL' ) THEN
+         IW=IIB+2 -1
+      ELSE
+         IW=IIB+1 -1
+      END IF
+      IE=IIE-1
+!!$   ELSE
+!!$      IF (LWEST_ll()) THEN
+!!$         IW=IIB+1
+!!$      ELSE
+!!$         IW=IIB
+!!$      END IF
+!!$      IF (LEAST_ll() .AND. HLBCX(2)/='CYCL' ) THEN
+!!$         IE=IIE-1
+!!$      ELSE
+!!$         IE=IIE
+!!$      END IF
+!!$   END IF
+   !
+!!$   IF(NHALO == 1) THEN
+      IF ( LSOUTH_ll() .AND. HLBCY(1)/='CYCL' ) THEN
+         IS=IJB+2 -1
+      ELSE
+         IS=IJB+1 -1
+      END IF
+      IN=IJE-1
+!!$   ELSE
+!!$      IF (LSOUTH_ll()) THEN
+!!$         IS=IJB+1
+!!$      ELSE
+!!$         IS=IJB
+!!$      END IF
+!!$      IF (LNORTH_ll() .AND. HLBCY(2)/='CYCL' ) THEN
+!!$         IN=IJE-1
+!!$      ELSE
+!!$         IN=IJE
+!!$      END IF
+!!$   END IF
+   !
+   !
+   !*       3.1    interior of the process subdomain
+!
+!
+   Z1(IW:IE,:,IKB:IKE+1)=                                               &
+       7.0*( (PRUCT(IW:IE,:,IKB:IKE+1)+PRUCT(IW:IE,:,IKB-1:IKE)) &
+            *( 9.0*PDZX(IW:IE,:,IKB:IKE+1)-(PDZX(IW+1:IE+1,:,IKB:IKE+1) &
+                  +PDZX(IW:IE,:,IKB:IKE+1)+PDZX(IW-1:IE-1,:,IKB:IKE+1))/3.0)/8.0 * 0.5 &
+           +(PRUCT(IW+1:IE+1,:,IKB:IKE+1)+PRUCT(IW+1:IE+1,:,IKB-1:IKE)) &
+            *( 9.0*PDZX(IW+1:IE+1,:,IKB:IKE+1)-(PDZX(IW+2:IE+2,:,IKB:IKE+1) &
+                  +PDZX(IW+1:IE+1,:,IKB:IKE+1)+PDZX(IW:IE,:,IKB:IKE+1))/3.0)/8.0 * 0.5 )/12.0 &
+          -( (PRUCT(IW-1:IE-1,:,IKB:IKE+1)+PRUCT(IW-1:IE-1,:,IKB-1:IKE)) &
+            *PDZX(IW-1:IE-1,:,IKB:IKE+1) *0.5 &
+            +(PRUCT(IW+2:IE+2,:,IKB:IKE+1)+PRUCT(IW+2:IE+2,:,IKB-1:IKE)) &
+            *PDZX(IW+2:IE+2,:,IKB:IKE+1) *0.5)/12.0
+
+!
+   Z2(:,IS:IN,IKB:IKE+1)=                                               &
+       7.0*( (PRVCT(:,IS:IN,IKB:IKE+1)+PRVCT(:,IS:IN,IKB-1:IKE)) &
+            *( 9.0*PDZY(:,IS:IN,IKB:IKE+1)-(PDZY(:,IS+1:IN+1,IKB:IKE+1) &
+                  +PDZY(:,IS:IN,IKB:IKE+1)+PDZY(:,IS-1:IN-1,IKB:IKE+1))/3.0)/8.0 * 0.5 &
+           +(PRVCT(:,IS+1:IN+1,IKB:IKE+1)+PRVCT(:,IS+1:IN+1,IKB-1:IKE)) &
+            *( 9.0*PDZY(:,IS+1:IN+1,IKB:IKE+1)-(PDZY(:,IS+2:IN+2,IKB:IKE+1) &
+                  +PDZY(:,IS+1:IN+1,IKB:IKE+1)+PDZY(:,IS:IN,IKB:IKE+1))/3.0)/8.0 * 0.5 )/12.0 &
+          -( (PRVCT(:,IS-1:IN-1,IKB:IKE+1)+PRVCT(:,IS-1:IN-1,IKB-1:IKE)) &
+            *PDZY(:,IS-1:IN-1,IKB:IKE+1) *0.5 &
+            +(PRVCT(:,IS+2:IN+2,IKB:IKE+1)+PRVCT(:,IS+2:IN+2,IKB-1:IKE)) &
+            *PDZY(:,IS+2:IN+2,IKB:IKE+1) *0.5)/12.0
+!
+!*       3.2    limits of the process subdomain (inside the whole domain or in cyclic conditions)
+!
+!!$  IF (NHALO==1) THEN
+
+   Z1(IIE,:,IKB:IKE+1)=                                               &
+       7.0*( (PRUCT(IIE,:,IKB:IKE+1)+PRUCT(IIE,:,IKB-1:IKE)) &
+            *( 9.0*PDZX(IIE,:,IKB:IKE+1)-(PDZX(IIE+1,:,IKB:IKE+1) &
+                  +PDZX(IIE,:,IKB:IKE+1)+PDZX(IIE-1,:,IKB:IKE+1))/3.0)/8.0 * 0.5 &
+           +(PRUCT(IIE+1,:,IKB:IKE+1)+PRUCT(IIE+1,:,IKB-1:IKE)) &
+            *( 9.0*PDZX(IIE+1,:,IKB:IKE+1)-(TZHALO2_DZX%HALO2%EAST(:,IKB:IKE+1) &
+                  +PDZX(IIE+1,:,IKB:IKE+1)+PDZX(IIE,:,IKB:IKE+1))/3.0)/8.0 * 0.5 )/12.0 &
+          -( (PRUCT(IIE-1,:,IKB:IKE+1)+PRUCT(IIE-1,:,IKB-1:IKE)) &
+            *PDZX(IIE-1,:,IKB:IKE+1) *0.5 &
+            +(TZHALO2_U%HALO2%EAST(:,IKB:IKE+1)+TZHALO2_U%HALO2%EAST(:,IKB-1:IKE)) &
+            *TZHALO2_DZX%HALO2%EAST(:,IKB:IKE+1) *0.5)/12.0
+!
+   Z2(:,IJE,IKB:IKE+1)=                                               &
+       7.0*( (PRVCT(:,IJE,IKB:IKE+1)+PRVCT(:,IJE,IKB-1:IKE)) &
+            *( 9.0*PDZY(:,IJE,IKB:IKE+1)-(PDZY(:,IJE+1,IKB:IKE+1) &
+                  +PDZY(:,IJE,IKB:IKE+1)+PDZY(:,IJE-1,IKB:IKE+1))/3.0)/8.0 * 0.5 &
+           +(PRVCT(:,IJE+1,IKB:IKE+1)+PRVCT(:,IJE+1,IKB-1:IKE)) &
+            *( 9.0*PDZY(:,IJE+1,IKB:IKE+1)-(TZHALO2_DZY%HALO2%NORTH(:,IKB:IKE+1) &
+                  +PDZY(:,IJE+1,IKB:IKE+1)+PDZY(:,IJE,IKB:IKE+1))/3.0)/8.0 * 0.5 )/12.0 &
+          -( (PRVCT(:,IJE-1,IKB:IKE+1)+PRVCT(:,IJE-1,IKB-1:IKE)) &
+            *PDZY(:,IJE-1,IKB:IKE+1) *0.5 &
+            +(TZHALO2_V%HALO2%NORTH(:,IKB:IKE+1)+TZHALO2_V%HALO2%NORTH(:,IKB-1:IKE)) &
+            *TZHALO2_DZY%HALO2%NORTH(:,IKB:IKE+1) *0.5)/12.0
+!!$  END IF
+!
+!*       3.3    non-CYCLIC CASE IN THE X DIRECTION: 2nd order case
+!
+  IF (HLBCX(1)/='CYCL' .AND. LWEST_ll()) THEN
+!
+   Z1(IIB,:,IKB:IKE+1)=                                     &
+       (PRUCT(IIB,:,IKB:IKE+1)+PRUCT(IIB,:,IKB-1:IKE) )     &
+        *PDZX(IIB,:,IKB:IKE+1) *0.25                        &
+      +(PRUCT(IIB+1,:,IKB:IKE+1)+PRUCT(IIB+1,:,IKB-1:IKE) ) &
+        *PDZX(IIB+1,:,IKB:IKE+1) *0.25   
+  END IF
+!
+  IF (HLBCX(2)/='CYCL' .AND. LEAST_ll()) THEN
+!
+   Z1(IIE,:,IKB:IKE+1)=                                     &
+       (PRUCT(IIE,:,IKB:IKE+1)+PRUCT(IIE,:,IKB-1:IKE) )     &
+        *PDZX(IIE,:,IKB:IKE+1) *0.25                        &
+      +(PRUCT(IIE+1,:,IKB:IKE+1)+PRUCT(IIE+1,:,IKB-1:IKE) ) &
+        *PDZX(IIE+1,:,IKB:IKE+1) *0.25   
+  END IF
+!
+!*       3.4    non-CYCLIC CASE IN THE Y DIRECTION: 2nd order case
+!
+  IF (HLBCY(1)/='CYCL' .AND. LSOUTH_ll()) THEN
+!
+   Z2(:,IJB,IKB:IKE+1)=                                     &
+       (PRVCT(:,IJB,IKB:IKE+1)+PRVCT(:,IJB,IKB-1:IKE) )     &
+        *PDZY(:,IJB,IKB:IKE+1) *0.25                        &
+      +(PRVCT(:,IJB+1,IKB:IKE+1)+PRVCT(:,IJB+1,IKB-1:IKE) ) &
+        *PDZY(:,IJB+1,IKB:IKE+1) *0.25   
+!
+  END IF
+!
+  IF (HLBCY(2)/='CYCL' .AND. LNORTH_ll()) THEN
+!
+   Z2(:,IJE,IKB:IKE+1)=                                     &
+       (PRVCT(:,IJE,IKB:IKE+1)+PRVCT(:,IJE,IKB-1:IKE) )     &
+        *PDZY(:,IJE,IKB:IKE+1) *0.25                        &
+      +(PRVCT(:,IJE+1,IKB:IKE+1)+PRVCT(:,IJE+1,IKB-1:IKE) ) &
+        *PDZY(:,IJE+1,IKB:IKE+1) *0.25   
+!
+  END IF
+!
+!*       3.5    Vertical contyravariant wind
+!
+!
+!!$  CALL GET_HALO(Z1)
+!!$  CALL GET_HALO(Z2)
+!!$
+!!$  CALL MPPDB_CHECK3DM("contrav ::Z1/Z2/ PDZZ",PRECISION,Z1,Z2,PDZZ)                    
+  PRWCT=0.             
+  PRWCT(IIB:IIE,IJB:IJE,IKB:IKE+1) =                 &
+     (   PRWT(IIB:IIE,IJB:IJE,IKB:IKE+1)            &
+       - Z1(IIB:IIE,IJB:IJE,IKB:IKE+1)              &
+       - Z2(IIB:IIE,IJB:IJE,IKB:IKE+1)              &
+     ) / PDZZ(IIB:IIE,IJB:IJE,IKB:IKE+1)  
+!
+END IF
+!
+PRWCT(:,:,1) = - PRWCT(:,:,3)     ! Mirror hypothesis
+!
+IF (KADV_ORDER == 4 ) THEN
+  CALL CLEANLIST_ll(TZFIELD_U)
+  CALL CLEANLIST_ll(TZFIELD_V)
+!!$  IF (NHALO==1) THEN
+    CALL CLEANLIST_ll(TZFIELD_DZX)
+    CALL CLEANLIST_ll(TZFIELD_DZY)
+    CALL DEL_HALO2_ll(TZHALO2_U)
+    CALL DEL_HALO2_ll(TZHALO2_V)
+    CALL DEL_HALO2_ll(TZHALO2_DZX)
+    CALL DEL_HALO2_ll(TZHALO2_DZY)
+!!$  END IF
+END IF
+!-----------------------------------------------------------------------
+IF (MPPDB_INITIALIZED) THEN
+  !Check all OUT arrays
+  CALL MPPDB_CHECK(PRUCT,"CONTRAV end:PRUCT")
+  CALL MPPDB_CHECK(PRVCT,"CONTRAV end:PRVCT")
+  CALL MPPDB_CHECK(PRWCT,"CONTRAV end:PRWCT")
+END IF
+!
+END SUBROUTINE CONTRAV
+!
+#ifdef MNH_OPENACC
+!     ##############################################################
+      SUBROUTINE CONTRAV_DEVICE(HLBCX,HLBCY,PRUT,PRVT,PRWT,PDXX,PDYY,PDZZ,PDZX,PDZY,  &
+                         PRUCT,PRVCT,PRWCT,KADV_ORDER,Z1,Z2,ODATA_ON_DEVICE     )
+!     ##############################################################
+!
+!!****  *CONTRAV * - computes the contravariant components from the
+!!       cartesian components
+!!
+!!    PURPOSE
+!!    -------
+!       This routine computes the contravariant components of vector
+!     defined by its cartesian components (U,V,W) , using the following
+!     formulae:
+!     UC = U / DXX
+!     VC = V / DYY
+!               (     ----------x    ----------y )  
+!               (           ---z           ---z  )
+!           1   (            U              V    )
+!     WC = ---  ( W - DZX * ---    - DZY * ---   )
+!          DZZ  (           DXX            DYY   )
+!
+!  
+!       In the no-topography case, WC = W / DZZ
+!
+!
+!!**  METHOD
+!!    ------
+!!      We employ the Shuman operators to compute the averages. The metric
+!!    coefficients PDXX, PDYY, PDZX, PDZY, PDZZ are dummy arguments
+!!
+!!
+!!    EXTERNAL 
+!!    --------
+!!      MXF, MYF, MZM         : Shuman functions (mean operators)
+!!       
+!!      Module MODI_SHUMAN    : Interface for Shuman functions   
+!!
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------
+!!
+!!      Module MODD_CONF   : contains configuration variable 
+!!           LFLAT : Logical for topography
+!!                  = .TRUE.  if Zs = 0 (Flat terrain)
+!!
+!!    REFERENCE
+!!    ---------
+!!      Book2 of documentation (subroutine CONTRAV)
+!!
+!!
+!!    AUTHOR
+!!    ------
+!!      J.L. Redelsperger     * CNRM *
+!!	J.-P. Pinty      * Laboratoire d'Aerologie*
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original   27/07/94
+!!      Corrections 3/08/94 (by J.P. Lafore)
+!!      Corrections 17/10/94 (by J.P. Lafore) WC modified for w-advection
+!!      Corrections 19/01/11 (by J.P. Pinty) WC 4th order
+!!      Corrections 28/03/11 (by V.Masson) // of WC 4th order
+!!      J.Escobar 21/03/2013: for HALOK comment all NHALO=1 test
+!  P. Wautelet 26/06/2019: optimisation for GPU + improve readability
+!----------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+USE MODD_ARGSLIST_ll, ONLY: HALO2LIST_ll
+USE MODD_CONF
+USE MODD_GRID_n,      ONLY: XZZ
+USE MODD_PARAMETERS
+!
+USE MODE_ll
+USE MODE_MPPDB
+#ifdef MNH_OPENACC
+use mode_msg
+#endif
+!
+USE MODI_GET_HALO
+USE MODI_SHUMAN
+!
+IMPLICIT NONE
+!
+!*       0.1   declarations of arguments    
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX ! X direction LBC type
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY ! Y direction LBC type
+!
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PRUT     ! Cartesian comp along x
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PRVT     ! Cartesian comp along y
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PRWT     ! Cartesian comp along z
+!
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PDXX     ! Metric coefficients
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PDYY     ! Metric coefficients
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PDZZ     ! Metric coefficients
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PDZX     ! Metric coefficients
+REAL, DIMENSION(:,:,:),  INTENT(IN)    ::  PDZY     ! Metric coefficients
+!
+!
+REAL, DIMENSION(:,:,:),  INTENT(OUT)   ::  PRUCT    ! Contrav comp along x-bar
+REAL, DIMENSION(:,:,:),  INTENT(OUT)   ::  PRVCT    ! Contrav comp along y-bar
+REAL, DIMENSION(:,:,:),  INTENT(OUT)   ::  PRWCT    ! Contrav comp along z-bar
+INTEGER,                 INTENT(IN)    ::  KADV_ORDER ! Order of the advection scheme
+REAL, DIMENSION(:,:,:),  INTENT(OUT)   :: Z1,Z2       ! Work arrays
+LOGICAL,   OPTIONAL,     INTENT(IN)    :: ODATA_ON_DEVICE ! Is some of the data on the accelerator device
+!
+!
+!*       0.2   declarations of local variables
+!
+integer                             :: ji, jj, jk
+INTEGER                             :: IIB, IIE, IJB, IJE, IKB, IKE
+INTEGER                             :: IIU, IJU, IKU
+INTEGER                             :: IW, IE, IS, IN   ! Coordinate of fourth order diffusion area
+INTEGER                             :: IINFO_ll
+LOGICAL                             :: GDATA_ON_DEVICE
+real                                :: ZTMP1, ZTMP2 ! Intermediate work variables
+REAL,   DIMENSION(:,:), POINTER , CONTIGUOUS :: ZU_EAST, ZV_NORTH, ZDZX_EAST, ZDZY_NORTH
+TYPE(LIST_ll),          POINTER     :: TZFIELD_U, TZFIELD_V, TZFIELD_DZX, TZFIELD_DZY
+TYPE(HALO2LIST_ll),     POINTER     :: TZHALO2_U, TZHALO2_V, TZHALO2_DZX, TZHALO2_DZY
+!
+LOGICAL :: GWEST,GEAST,GSOUTH,GNORTH
+!
+!$acc data present( PRUT, PRVT, PRWT, PDXX, PDYY, PDZZ, PDZX, PDZY, PRUCT, PRVCT, PRWCT, Z1, Z2 )
+
+IF ( PRESENT(ODATA_ON_DEVICE) ) THEN
+  GDATA_ON_DEVICE = ODATA_ON_DEVICE
+ELSE
+  GDATA_ON_DEVICE = .FALSE.
+END IF
+!-----------------------------------------------------------------------
+!
+!*       1.    Compute the horizontal contravariant components
+!              -----------------------------------------------
+!
+IF (MPPDB_INITIALIZED) THEN
+  !Check all IN arrays
+  CALL MPPDB_CHECK(PRUT,"CONTRAV beg:PRUT")
+  CALL MPPDB_CHECK(PRVT,"CONTRAV beg:PRVT")
+  CALL MPPDB_CHECK(PRWT,"CONTRAV beg:PRWT")
+  CALL MPPDB_CHECK(PDXX,"CONTRAV beg:PDXX")
+  CALL MPPDB_CHECK(PDYY,"CONTRAV beg:PDYY")
+  CALL MPPDB_CHECK(PDZZ,"CONTRAV beg:PDZZ")
+  CALL MPPDB_CHECK(PDZX,"CONTRAV beg:PDZX")
+  CALL MPPDB_CHECK(PDZY,"CONTRAV beg:PDZY")
+END IF
+!
+IIU= SIZE(PDXX,1)
+IJU= SIZE(PDXX,2)
+IKU= SIZE(PDXX,3)
+!
+GWEST  = ( HLBCX(1) /= 'CYCL' .AND. LWEST_ll() )
+GEAST  = ( HLBCX(2) /= 'CYCL' .AND. LEAST_ll() )
+GSOUTH = ( HLBCY(1) /= 'CYCL' .AND. LSOUTH_ll() )
+GNORTH = ( HLBCY(2) /= 'CYCL' .AND. LNORTH_ll() )
+!
+CALL GET_INDICE_ll( IIB,IJB,IIE,IJE)
+!
+IKB=1+JPVEXT
+IKE=IKU - JPVEXT
+!
+IF (GDATA_ON_DEVICE) THEN
+!PW TODO:remplacer (ailleurs aussi...) 1/PDXX... par PINV_PDXX (fait pour la turbulence...) cfr MNH/turb_hor_splt.f90
+!$acc kernels
+  PRUCT(:,:,:) = PRUT(:,:,:) / PDXX(:,:,:)
+  PRVCT(:,:,:) = PRVT(:,:,:) / PDYY(:,:,:)
+!$acc end kernels
+!$acc update self(PRUCT,PRVCT)
+ELSE
+  PRUCT(:,:,:) = PRUT(:,:,:) / PDXX(:,:,:)
+  PRVCT(:,:,:) = PRVT(:,:,:) / PDYY(:,:,:)
+END IF
+!
+IF (KADV_ORDER == 4 ) THEN
+ IF( .NOT. LFLAT) THEN 
+!!$  NULLIFY(TZFIELD_U)
+!!$  NULLIFY(TZFIELD_V)
+!!$  CALL ADD3DFIELD_ll( TZFIELD_U, PRUCT, 'CONTRAV::PRUCT' )
+!!$  CALL ADD3DFIELD_ll( TZFIELD_V, PRVCT, 'CONTRAV::PRVCT' )
+!!$  CALL UPDATE_HALO_ll(TZFIELD_U,IINFO_ll)
+!!$  CALL UPDATE_HALO_ll(TZFIELD_V,IINFO_ll)
+!!$ !!$ IF( NHALO==1 ) THEN 
+!!$  NULLIFY(TZFIELD_DZX)
+!!$  NULLIFY(TZFIELD_DZY)
+!!$  CALL ADD3DFIELD_ll( TZFIELD_DZX, PDZX, 'CONTRAV::PDZX' )
+!!$  CALL ADD3DFIELD_ll( TZFIELD_DZY, PDZY, 'CONTRAV::PDZY' )
+!!$  NULLIFY(TZHALO2_U)
+!!$  NULLIFY(TZHALO2_V)
+!!$  NULLIFY(TZHALO2_DZX)
+!!$  NULLIFY(TZHALO2_DZY)
+!!$  CALL INIT_HALO2_ll(TZHALO2_U,1,IIU,IJU,IKU)
+!!$  CALL INIT_HALO2_ll(TZHALO2_V,1,IIU,IJU,IKU)
+!!$  CALL INIT_HALO2_ll(TZHALO2_DZX,1,IIU,IJU,IKU)
+!!$  CALL INIT_HALO2_ll(TZHALO2_DZY,1,IIU,IJU,IKU)
+!!$  CALL UPDATE_HALO2_ll(TZFIELD_U, TZHALO2_U, IINFO_ll)
+!!$  CALL UPDATE_HALO2_ll(TZFIELD_V, TZHALO2_V, IINFO_ll)
+!!$  CALL UPDATE_HALO2_ll(TZFIELD_DZX, TZHALO2_DZX, IINFO_ll)
+!!$  CALL UPDATE_HALO2_ll(TZFIELD_DZY, TZHALO2_DZY, IINFO_ll)
+  !
+  CALL GET_HALO2_D(PRUCT,TZHALO2_U,'CONTRAV::PRUCT')
+  CALL GET_HALO2_D(PRVCT,TZHALO2_V,'CONTRAV::PRVCT')
+  CALL GET_HALO2_D(PDZX,TZHALO2_DZX,'CONTRAV::PDZX')
+  CALL GET_HALO2_D(PDZY,TZHALO2_DZY,'CONTRAV::PDZY')
+  
+!!$!$acc update device(PRUCT,PRVCT)
+!!$ !!$ END IF
+!
+  !PW: necessary because pointers does not work with OpenACC (PGI 16.1)
+!!$  ALLOCATE(ZU_EAST(IJU,IKU),ZV_NORTH(IIU,IKU),ZDZX_EAST(IJU,IKU),ZDZY_NORTH(IIU,IKU))
+!!$  !$acc enter data create( zu_east, zv_north, zdzx_east, zdzy_north )
+!!$  !$acc kernels
+  ZU_EAST => TZHALO2_U%HALO2%EAST
+  ZDZX_EAST => TZHALO2_DZX%HALO2%EAST
+  ZV_NORTH => TZHALO2_V%HALO2%NORTH
+  ZDZY_NORTH => TZHALO2_DZY%HALO2%NORTH
+!!$  !$acc end kernels
+!!$!$acc update device(ZU_EAST,ZV_NORTH,ZDZX_EAST,ZDZY_NORTH)
+ END IF
+END IF
+!
+!
+!*       2.    Compute the vertical contravariant components (flat case)
+!              ------------------------------------
+!
+FLAT: IF (LFLAT) THEN
+  IF (GDATA_ON_DEVICE) THEN
+!$acc kernels
+    PRWCT(:,:,:) = PRWT(:,:,:) / PDZZ(:,:,:)
+!$acc end kernels
+!$acc update self(PRWCT)
+  ELSE
+    PRWCT(:,:,:) = PRWT(:,:,:) / PDZZ(:,:,:)
+  END IF
+ELSE
+!
+!*       3.    Compute the vertical contravariant components (general case)
+!              ------------------------------------
+!
+! Z1(:,:,:) = 0.
+! Z2(:,:,:) = 0.   
+!
+IF (KADV_ORDER == 2 ) THEN
+#ifdef MNH_OPENACC
+  call Print_msg( NVERB_WARNING, 'GEN', 'CONTRAV', 'OpenACC: KADV_ORDER=2 and LFLAT=.TRUE. not yet tested' )
+#endif
+!$acc kernels  
+!
+!$acc loop independent collapse(3)
+  do concurrent (ji=iib:iie,jj=1:iju,jk=ikb:ike+1)
+     Z1(ji, jj, jk ) =   ( PRUCT(ji,     jj, jk ) + PRUCT(ji,     jj, jk - 1 ) ) * PDZX (ji,     jj, jk ) * 0.25 &
+                       + ( PRUCT(ji + 1, jj, jk ) + PRUCT(ji + 1, jj, jk - 1 ) ) * PDZX (ji + 1, jj, jk ) * 0.25
+  end do
+!$acc loop independent collapse(3)
+  do concurrent (ji=1:iiu,jj=ijb:ije,jk=ikb:ike+1)
+     Z2(ji, jj, jk ) =   ( PRVCT(ji, jj,     jk) + PRVCT( ji, jj,    jk - 1) ) * PDZY(ji, jj,     jk) * 0.25 &
+                       + ( PRVCT(ji, jj + 1, jk) + PRVCT( ji, jj + 1,jk - 1) ) * PDZY(ji, jj + 1, jk) * 0.25
+  end do
+
+  PRWCT(:,:,:)=0.
+
+!$acc loop independent collapse(3)
+  do concurrent (ji=iib:iie,jj=ijb:ije,jk=ikb:ike+1)
+     PRWCT(ji ,jj, jk ) = ( PRWT(ji ,jj, jk ) - Z1(ji ,jj, jk ) - Z2(ji ,jj, jk ) ) / PDZZ(ji ,jj, jk )
+  end do
+!
+!$acc end kernels  
+ELSE IF (KADV_ORDER == 4 ) THEN
+!
+!!$   IF (NHALO == 1) THEN
+      IF ( GWEST ) THEN
+         IW=IIB+2 -1
+      ELSE
+         IW=IIB+1 -1
+      END IF
+      IE=IIE-1
+!!$   ELSE
+!!$      IF (LWEST_ll()) THEN
+!!$         IW=IIB+1
+!!$      ELSE
+!!$         IW=IIB
+!!$      END IF
+!!$      IF (LEAST_ll() .AND. HLBCX(2)/='CYCL' ) THEN
+!!$         IE=IIE-1
+!!$      ELSE
+!!$         IE=IIE
+!!$      END IF
+!!$   END IF
+   !
+!!$   IF(NHALO == 1) THEN
+      IF ( GSOUTH ) THEN
+         IS=IJB+2 -1
+      ELSE
+         IS=IJB+1 -1
+      END IF
+      IN=IJE-1
+!!$   ELSE
+!!$      IF (LSOUTH_ll()) THEN
+!!$         IS=IJB+1
+!!$      ELSE
+!!$         IS=IJB
+!!$      END IF
+!!$      IF (LNORTH_ll() .AND. HLBCY(2)/='CYCL' ) THEN
+!!$         IN=IJE-1
+!!$      ELSE
+!!$         IN=IJE
+!!$      END IF
+!!$   END IF
+   !
+   !
+   !*       3.1    interior of the process subdomain
+!$acc kernels      
+!
+!
+!PW: OpenACC remarks: *computing only ztmp2 and reusing it at next iteration works
+!                      but ji loop can not be collapsed -> 10x slower on GPU
+!                     *ztmp1 and ztmp2 are not necessary but improve readability (no impact on performance)
+!$acc loop independent collapse(3) private(ztmp1, ztmp2)
+  do concurrent(ji=IW:IE,jj=1:iju,jk=IKB:IKE+1)
+        ztmp1 = ( 9.0 * PDZX(ji,   jj, jk ) - ( PDZX(ji+1, jj, jk ) + PDZX(ji,   jj, jk ) + PDZX(ji-1, jj, jk ) ) / 3.0 ) / 16.0
+        ztmp2 = ( 9.0 * PDZX(ji+1, jj, jk ) - ( PDZX(ji+2, jj, jk ) + PDZX(ji+1, jj, jk ) + PDZX(ji,   jj, jk ) ) / 3.0 ) / 16.0
+        Z1(ji, jj, jk ) =  7.0 * (  ( PRUCT(ji,   jj, jk ) + PRUCT(ji,   jj, jk-1 ) ) * ztmp1                        &
+                                  + ( PRUCT(ji+1, jj, jk ) + PRUCT(ji+1, jj, jk-1 ) ) * ztmp2               ) / 12.0 &
+                         - 0.5 * (  ( PRUCT(ji-1, jj, jk ) + PRUCT(ji-1, jj, jk-1 ) ) * PDZX(ji-1, jj, jk)           &
+                                  + ( PRUCT(ji+2, jj, jk ) + PRUCT(ji+2, jj, jk-1 ) ) * PDZX(ji+2, jj, jk)  ) / 12.0
+  end do
+!
+!$acc loop independent collapse(3)
+  do concurrent(ji=1:iiu,jj=is:in,jk=IKB:IKE+1)
+        ztmp1 = ( 9.0 * PDZY(ji, jj,   jk ) - ( PDZY(ji, jj+1, jk ) + PDZY(ji, jj,   jk ) + PDZY(ji, jj-1, jk ) ) / 3.0 ) / 16.0
+        ztmp2 = ( 9.0 * PDZY(ji, jj+1, jk ) - ( PDZY(ji, jj+2, jk ) + PDZY(ji, jj+1, jk ) + PDZY(ji, jj,   jk ) ) / 3.0 ) / 16.0
+        Z2(ji, jj, jk ) =  7.0 * (  ( PRVCT(ji, jj,   jk ) + PRVCT(ji, jj,   jk-1 ) ) * ztmp1                         &
+                                  + ( PRVCT(ji, jj+1, jk ) + PRVCT(ji, jj+1, jk-1 ) ) * ztmp2                ) / 12.0 &
+                         - 0.5 * (  ( PRVCT(ji, jj-1, jk ) + PRVCT(ji, jj-1, jk-1 ) ) * PDZY(ji, jj-1, jk )           &
+                                  + ( PRVCT(ji, jj+2, jk ) + PRVCT(ji, jj+2, jk-1 ) ) * PDZY(ji, jj+2, jk )  ) / 12.0
+  end do
+!$acc end kernels     
+!
+!*       3.2    limits of the process subdomain (inside the whole domain or in cyclic conditions)
+!
+!!$  IF (NHALO==1) THEN
+!$acc parallel loop independent collapse(2) async
+    do concurrent(jj=1:iju,jk=IKB:IKE+1)
+      ztmp1 = ( 9.0 * PDZX(IIE,   jj, jk ) - ( PDZX(IIE+1, jj, jk ) + PDZX(IIE,   jj, jk ) + PDZX(IIE-1, jj, jk ) ) / 3.0 ) / 16.0
+      ztmp2 = ( 9.0 * PDZX(IIE+1, jj, jk ) - ( ZDZX_EAST(jj, jk )   + PDZX(IIE+1, jj, jk ) + PDZX(IIE,   jj, jk ) ) / 3.0 ) / 16.0
+      Z1(IIE, jj, jk ) =  7.0 * (  ( PRUCT(IIE,   jj, jk ) + PRUCT(IIE,   jj, jk-1 ) ) * ztmp1                        &
+                                 + ( PRUCT(IIE+1, jj, jk ) + PRUCT(IIE+1, jj, jk-1 ) ) * ztmp2               ) / 12.0 &
+                        - 0.5 * (  ( PRUCT(IIE-1, jj, jk ) + PRUCT(IIE-1, jj, jk-1 ) ) * PDZX(IIE-1, jj, jk)          &
+                                 + ( ZU_EAST     (jj, jk ) + ZU_EAST     (jj, jk-1 ) ) * ZDZX_EAST  (jj, jk)  ) / 12.0
+    end do
+!
+!$acc parallel loop independent collapse(2) async
+    do concurrent(ji=1:iiu,jk=IKB:IKE+1)
+      ztmp1 = ( 9.0 * PDZY(ji, IJE,   jk) - ( PDZY      (ji, IJE+1, jk) + PDZY(ji, IJE,   jk) + PDZY(ji, IJE-1, jk) ) / 3.0 ) / 16.0
+      ztmp2 = ( 9.0 * PDZY(ji, IJE+1, jk) - ( ZDZY_NORTH(ji,        jk) + PDZY(ji, IJE+1, jk) + PDZY(ji, IJE,   jk) ) / 3.0 ) / 16.0
+      Z2(ji, IJE, jk ) =  7.0 * (  ( PRVCT   (ji, IJE,   jk ) + PRVCT   (ji, IJE,   jk-1 ) ) * ztmp1                               &
+                                 + ( PRVCT   (ji, IJE+1, jk ) + PRVCT   (ji, IJE+1, jk-1 ) ) * ztmp2                      ) / 12.0 &
+                        - 0.5 * (  ( PRVCT   (ji, IJE-1, jk ) + PRVCT   (ji, IJE-1, jk-1 ) ) * PDZY      (ji, IJE-1, jk )          &
+                                 + ( ZV_NORTH(ji,        jk ) + ZV_NORTH(ji,        jk-1 ) ) * ZDZY_NORTH(ji,        jk ) ) / 12.0
+   end do
+!$acc wait
+!!$  END IF
+!
+!*       3.3    non-CYCLIC CASE IN THE X DIRECTION: 2nd order case
+!
+   IF ( GWEST ) THEN
+    !$acc kernels async  
+    Z1(IIB, :, IKB:IKE+1 ) =  ( PRUCT(IIB,   :, IKB:IKE+1 ) + PRUCT(IIB,   :, IKB-1:IKE ) ) * PDZX(IIB,   :, IKB:IKE+1 ) * 0.25 &
+                            + ( PRUCT(IIB+1, :, IKB:IKE+1 ) + PRUCT(IIB+1, :, IKB-1:IKE ) ) * PDZX(IIB+1, :, IKB:IKE+1 ) * 0.25
+    !$acc end kernels
+  END IF
+!
+  IF ( GEAST ) THEN
+    !$acc kernels async 
+    Z1(IIE, :, IKB:IKE+1 ) =  ( PRUCT(IIE,   :, IKB:IKE+1 ) + PRUCT(IIE,   :, IKB-1:IKE ) ) * PDZX(IIE,   :, IKB:IKE+1 ) * 0.25 &
+                            + ( PRUCT(IIE+1, :, IKB:IKE+1 ) + PRUCT(IIE+1, :, IKB-1:IKE ) ) * PDZX(IIE+1, :, IKB:IKE+1 ) * 0.25
+    !$acc end kernels
+ END IF
+!
+!*       3.4    non-CYCLIC CASE IN THE Y DIRECTION: 2nd order case
+!
+ IF ( GSOUTH ) THEN
+    !$acc kernels async
+    Z2(:, IJB, IKB:IKE+1 ) =  ( PRVCT(:, IJB,   IKB:IKE+1 ) + PRVCT(:, IJB,   IKB-1:IKE ) ) * PDZY(:, IJB,   IKB:IKE+1 ) * 0.25 &
+                            + ( PRVCT(:, IJB+1, IKB:IKE+1 ) + PRVCT(:, IJB+1, IKB-1:IKE ) ) * PDZY(:, IJB+1, IKB:IKE+1 ) * 0.25
+    !$acc end kernels
+ END IF
+!
+ IF ( GNORTH ) THEN
+     !$acc kernels async
+    Z2(:, IJE, IKB:IKE+1 ) =  ( PRVCT(:, IJE,   IKB:IKE+1 ) + PRVCT(:, IJE,   IKB-1:IKE ) ) * PDZY(:, IJE,   IKB:IKE+1 ) * 0.25 &
+                            + ( PRVCT(:, IJE+1, IKB:IKE+1 ) + PRVCT(:, IJE+1, IKB-1:IKE ) ) * PDZY(:, IJE+1, IKB:IKE+1 ) * 0.25
+    !$acc end kernels
+ END IF
+!$acc wait 
+!
+!*       3.5    Vertical contyravariant wind
+!
+!
+!$acc kernels  
+!!$  CALL GET_HALO(Z1)
+!!$  CALL GET_HALO(Z2)
+!!$
+!!$  CALL MPPDB_CHECK3DM("contrav_device ::Z1/Z2/ PDZZ",PRECISION,Z1,Z2,PDZZ)
+  PRWCT(:,:,:)=0.
+!$acc loop independent collapse(3)
+  do concurrent (ji=iib:iie,jj=ijb:ije,jk=ikb:ike+1)
+        PRWCT(ji ,jj, jk ) = ( PRWT(ji ,jj, jk ) - Z1(ji ,jj, jk ) - Z2(ji ,jj, jk ) ) / PDZZ(ji ,jj, jk )
+  end do
+!$acc end kernels 
+!
+!
+END IF
+!
+!$acc kernels
+PRWCT(:,:,1) = - PRWCT(:,:,3)     ! Mirror hypothesis
+!$acc end kernels
+!$acc update self(PRWCT)
+!
+IF (KADV_ORDER == 4 ) THEN
+!!$!$acc exit data delete( zu_east, zv_north, zdzx_east, zdzy_north )
+!!$  DEALLOCATE(ZU_EAST,ZV_NORTH,ZDZX_EAST,ZDZY_NORTH)
+!!$  CALL CLEANLIST_ll(TZFIELD_U)
+!!$  CALL CLEANLIST_ll(TZFIELD_V)
+!!$ !!$  IF (NHALO==1) THEN
+!!$    CALL CLEANLIST_ll(TZFIELD_DZX)
+!!$    CALL CLEANLIST_ll(TZFIELD_DZY)
+    CALL DEL_HALO2_ll(TZHALO2_U)
+    CALL DEL_HALO2_ll(TZHALO2_V)
+    CALL DEL_HALO2_ll(TZHALO2_DZX)
+    CALL DEL_HALO2_ll(TZHALO2_DZY)
+!!$ !!$  END IF
+END IF
+
+END IF FLAT
+!-----------------------------------------------------------------------
+IF (MPPDB_INITIALIZED) THEN
+  !Check all OUT arrays
+  CALL MPPDB_CHECK(PRUCT,"CONTRAV end:PRUCT")
+  CALL MPPDB_CHECK(PRVCT,"CONTRAV end:PRVCT")
+  CALL MPPDB_CHECK(PRWCT,"CONTRAV end:PRWCT")
+END IF
+
+!$acc end data
+
+END SUBROUTINE CONTRAV_DEVICE
+#endif
diff --git a/src/ZSOLVER/dotprod.f90 b/src/ZSOLVER/dotprod.f90
new file mode 100644
index 0000000000000000000000000000000000000000..ec920cc5191fe74c3876981858b20aeb001a996c
--- /dev/null
+++ b/src/ZSOLVER/dotprod.f90
@@ -0,0 +1,188 @@
+!MNH_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt  
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+!--------------- special set of characters for RCS information
+!-----------------------------------------------------------------
+! $Source$ $Revision$
+! MASDEV4_7 solver 2006/05/18 13:07:25
+!-----------------------------------------------------------------
+!     ###################
+      MODULE MODI_DOTPROD
+!     ###################
+!
+INTERFACE
+!
+      FUNCTION DOTPROD(PA,PB,HLBCX,HLBCY)  RESULT(PDOTPROD)
+!  
+IMPLICIT NONE
+!
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PA, PB     ! input vectors
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX    ! x-direction LBC type 
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY    ! y-direction LBC type 
+!
+REAL :: PDOTPROD                                     ! dot product
+!
+END FUNCTION DOTPROD
+!
+END INTERFACE
+!
+END MODULE MODI_DOTPROD
+!
+!
+!
+!     #####################################################
+      FUNCTION DOTPROD(PA,PB,HLBCX,HLBCY)  RESULT(PDOTPROD)
+!     #####################################################
+!
+!!****  *DOTPROD* -  compute the dot product of two vectors
+!!
+!!    PURPOSE
+!!    -------
+!       The purpose of this function  is to compute dot product of the vectors 
+!     stored in the arrays PA, PB. The elements of PA and PB are localized at
+!     mass points.
+!
+!!**  METHOD
+!!    ------ 
+!!      The scalar product DOTPROD  of 2 vectors  A and B is defined by : 
+!!        DOTPROD = SUM( A(i,j,k)* B(i,j,k) )
+!!    The bounds for the summation depend on the l.b.c.
+!!
+!!    EXTERNAL
+!!    --------
+!!      NONE
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------
+!!      Module MODD_PARAMETERS: declaration of parameter variables
+!!        JPHEXT, JPVEXT: define the number of marginal points out of the 
+!!        physical domain along horizontal and vertical directions respectively
+!!     Module MODD_CONF: model configurations
+!!        L2D: logical switch for 2D model version
+!!
+!!    REFERENCE
+!!    ---------
+!!      Book2 of documentation of Meso-NH (function DOTPROD)
+!!
+!!    AUTHOR
+!!    ------
+!!	P. Hereil and J. Stein      * Meteo France *
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original    25/07/94 
+!!      J.-P. Pinty 12/11/99 Parallelization
+!!
+!-------------------------------------------------------------------------------
+!
+!*      0.     DECLARATIONS
+!              ------------
+!
+USE MODD_PARAMETERS
+USE MODD_CONF
+!
+USE MODE_ll
+!JUAN
+USE MODE_REPRO_SUM
+!JUAN
+!
+IMPLICIT NONE
+!
+!*      0.1   Declarations of arguments and result
+!             ------------------------------------
+!
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PA, PB     ! input vectors
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX    ! x-direction LBC type 
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY    ! y-direction LBC type 
+!
+REAL :: PDOTPROD                                     ! dot product
+!
+!*       0.2   Declarations of local variables
+!              -------------------------------
+!
+INTEGER :: JK,JI,JJ                         ! loop indexes
+!
+INTEGER :: IIB          ! indice I for the first inner mass point along x
+INTEGER :: IIE          ! indice I for the last inner mass point along x
+INTEGER :: IJB          ! indice J for the first inner mass point along y
+INTEGER :: IJE          ! indice J for the last inner mass point along y
+INTEGER :: IKB          ! indice K for the first inner mass point along z
+INTEGER :: IKE          ! indice K for the last inner mass point along z
+!
+INTEGER :: ILBXB,ILBYB,ILBXE,ILBYE          ! loop indices depending on the
+                                            ! lateral boundary conditions
+!
+INTEGER  :: IINFO_ll
+!JUAN16
+REAL, ALLOCATABLE, DIMENSION(:,:)     :: ZDOTPROD
+!JUAN16
+!
+!-------------------------------------------------------------------------------
+!
+!*       1.    COMPUTE LOOP BOUNDS
+!              -------------------
+!
+CALL GET_INDICE_ll(IIB,IJB,IIE,IJE)
+!
+IKB=1+JPVEXT
+IKE=SIZE(PA,3) - JPVEXT
+!
+IF(HLBCX(1)/='CYCL' .AND. LWEST_ll()) THEN
+  ILBXB = IIB-1    ! non cyclic condition at the physical boundary
+ELSE
+  ILBXB = IIB
+ENDIF
+!
+IF(HLBCX(2)/='CYCL' .AND. LEAST_ll()) THEN
+  ILBXE = IIE+1    ! non cyclic condition at the physical boundary
+ELSE
+  ILBXE = IIE
+ENDIF
+!
+ILBYB = IJB
+ILBYE = IJE
+!
+IF (.NOT.L2D) THEN        ! 3d version
+  IF(HLBCY(1)/='CYCL' .AND. LSOUTH_ll()) THEN
+    ILBYB = IJB-1    ! non cyclic condition at the physical boundary
+  ELSE
+    ILBYB = IJB
+  ENDIF
+!
+  IF(HLBCY(2)/='CYCL' .AND. LNORTH_ll()) THEN
+    ILBYE = IJE+1    ! non cyclic condition at the physical boundary
+  ELSE
+    ILBYE = IJE
+  ENDIF
+ELSE                      ! 2d version
+  ILBYB = IJB
+  ILBYE = IJB
+ENDIF
+!
+!*       2.    COMPUTE THE DOT PRODUCT 
+!              -----------------------
+!
+!JUAN16
+ALLOCATE(ZDOTPROD(ILBXB:ILBXE,ILBYB:ILBYE))
+!$acc kernels
+ZDOTPROD    = 0.
+!$acc loop seq
+DO JK = IKB-1,IKE+1
+   !$acc loop independent collapse(2) 
+   DO JJ = ILBYB,ILBYE
+      DO JI = ILBXB,ILBXE
+         ZDOTPROD(JI,JJ) = ZDOTPROD(JI,JJ) + PA(JI,JJ,JK) * PB(JI,JJ,JK)
+      END DO
+   END DO
+END DO
+!$acc end kernels
+PDOTPROD = SUM_DD_R2_ll(ZDOTPROD)
+!JUAN16
+!
+!-------------------------------------------------------------------------------
+!
+END FUNCTION DOTPROD
diff --git a/src/ZSOLVER/flat_inv.f90 b/src/ZSOLVER/flat_inv.f90
new file mode 100644
index 0000000000000000000000000000000000000000..38fd8718dff9fbfb46dee6c8b59de4b1b6d8d94a
--- /dev/null
+++ b/src/ZSOLVER/flat_inv.f90
@@ -0,0 +1,702 @@
+!MNH_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt  
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+!--------------- special set of characters for RCS information
+!-----------------------------------------------------------------
+! $Source$ $Revision$
+! MASDEV4_7 solver 2006/05/18 13:07:25
+!-----------------------------------------------------------------
+!     ####################
+      MODULE MODI_FLAT_INV
+!     ####################
+!
+INTERFACE
+!
+      SUBROUTINE FLAT_INV(HLBCX,HLBCY,PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF, &
+      PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,PY,PF_1_Y)
+!
+!  
+IMPLICIT NONE
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX    ! x-direction LBC type 
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY    ! y-direction LBC type 
+!
+REAL, INTENT(IN) :: PDXHATM                     ! mean grid increment in the x
+                                                ! direction
+REAL, INTENT(IN) :: PDYHATM                     ! mean grid increment in the y
+                                                ! direction
+!
+REAL, DIMENSION (:), INTENT(IN) :: PRHOM         !  mean of XRHODJ on the plane x y 
+                                                 !  localized at a mass level
+!
+REAL, DIMENSION(:), INTENT(IN)     :: PAF,PCF    ! vectors giving the nonvanishing
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PBF        ! elements of the tri-diag. 
+                                                 ! matrix in the pressure eq.
+!
+                                                 ! arrays of sin or cos values
+                                                 ! for the FFT :
+REAL, DIMENSION(:), INTENT(IN) :: PTRIGSX        ! - along x
+REAL, DIMENSION(:), INTENT(IN) :: PTRIGSY        ! - along y
+!
+                                                 ! decomposition in prime 
+                                                 ! numbers for the FFT:
+INTEGER, DIMENSION(19), INTENT(IN) :: KIFAXX      ! - along x
+INTEGER, DIMENSION(19), INTENT(IN) :: KIFAXY      ! - along y
+!
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PY         ! RHS of the equation
+!                                                         
+REAL, DIMENSION(:,:,:), INTENT(OUT):: PF_1_Y     ! solution of the equation
+!
+END SUBROUTINE FLAT_INV
+!
+END INTERFACE
+!
+END MODULE MODI_FLAT_INV
+!     ######################################################################
+      SUBROUTINE FLAT_INV(HLBCX,HLBCY,PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF,   &
+      PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,PY,PF_1_Y)
+!     ######################################################################
+!
+!!****  *FLAT_INV * - Invert the flat quasi-laplacian operator
+!!
+!!    PURPOSE
+!!    -------
+!       This routine solves the following equation:
+!                    F ( F_1_Y ) =  Y 
+!     where F represents the quasi-laplacian without orography. The solution is 
+!     F_1_Y.
+!
+!!**  METHOD
+!!    ------
+!!      The horizontal part of F is inverted with a FFT transform. For each 
+!!    horizontal direction, the FFT form depends on the lateral boundary 
+!!    conditions :
+!!    - CRAY intrinsic function RFFTMLT in the cyclic case 
+!!    - fast cosine transform called FFT55 for all other boundary condtions.
+!!    Then, in the wavenumber space, we invert for each 
+!!    horizontal mode i,j a tridiagonal matrix by a classical double sweep 
+!!    method.  The singular mean mode (i,j)=(0,0) corresponds to the 
+!!    undetermination of the pressure to within a constant and is treated apart.
+!!    To fix this degree of freedom, we set the horizontal mean value of the 
+!!    pressure perturbation to 0 at the upper level of the model. 
+!!       
+!!    EXTERNAL
+!!    --------
+!!      Subroutine FFT55 : aplly multiple fast real staggered (shifted) 
+!!    cosine transform
+!!      Subroutine RFFTMLT : apply real-to-complex or complex-to-real Fast 
+!!    Fourier Transform (FFT) on multiple input vectors.
+!!      Subroutine FFT991  : equivalent to RFFTMLT
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------ 
+!!      Module MODD_PARAMETERS: declaration of parameter variables
+!!        JPHEXT, JPVEXT: define the number of marginal points out of the 
+!!        physical domain along horizontal and vertical directions respectively
+!!      Module MODD_CONF: model configurations
+!!        L2D: logical for 2D model version
+!!
+!!    REFERENCE
+!!    ---------
+!!      Book2 of documentation (subroutine FLAT_INV)     
+!!
+!!    AUTHOR
+!!    ------
+!!	P. Hereil and J. Stein       * Meteo France *
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original    20/07/94 
+!!      Revision  Jabouille (juillet 96) replace the CRAY intrinsic function
+!!                             RFFTMLT by the arpege routine FFT991
+!!                  17/07/97  ( J. Stein and V. Masson) initialize the corner
+!!                             verticals
+!!                  17/07/97  ( J. Stein and V. Masson) initialize the corner
+!!                             verticals
+!!      Revision  Jabouille (septembre 97) suppress the particular case for
+!!                                         tridiagonal inversion
+!!                Stein     ( January 98 ) faster computation for the unused 
+!!                                points under the ground and out of the domain  
+!!      Modification   Lugato, Guivarch (June 1998) Parallelisation
+!!                     Escobar, Stein   (July 2000) optimisation
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+!
+USE MODD_PARAMETERS
+USE MODD_CONF
+!
+USE MODE_ll
+USE MODD_ARGSLIST_ll, ONLY : LIST_ll
+!
+USE MODI_FFT55
+!
+IMPLICIT NONE
+!
+!*       0.1   declarations of arguments
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX    ! x-direction LBC type 
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY    ! y-direction LBC type 
+!
+REAL, INTENT(IN) :: PDXHATM                     ! mean grid increment in the x
+                                                ! direction
+REAL, INTENT(IN) :: PDYHATM                     ! mean grid increment in the y
+                                                ! direction
+!
+REAL, DIMENSION (:), INTENT(IN) :: PRHOM         !  mean of XRHODJ on the plane x y 
+                                                 !  localized at a mass level
+!
+REAL, DIMENSION(:), INTENT(IN)     :: PAF,PCF    ! vectors giving the nonvanishing
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PBF        ! elements of the tri-diag. 
+                                                 ! matrix in the pressure eq.
+!
+                                                 ! arrays of sin or cos values
+                                                 ! for the FFT :
+REAL, DIMENSION(:), INTENT(IN) :: PTRIGSX        ! - along x
+REAL, DIMENSION(:), INTENT(IN) :: PTRIGSY        ! - along y
+!
+                                                 ! decomposition in prime 
+                                                 ! numbers for the FFT:
+INTEGER, DIMENSION(19), INTENT(IN) :: KIFAXX      ! - along x
+INTEGER, DIMENSION(19), INTENT(IN) :: KIFAXY      ! - along y
+!
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PY         ! RHS of the equation
+!                                                         
+REAL, DIMENSION(:,:,:), INTENT(OUT):: PF_1_Y     ! solution of the equation
+!
+!*       0.2   declaration of local variables
+!
+REAL, DIMENSION(SIZE(PY,1),SIZE(PY,2),SIZE(PY,3)) :: ZY ! work array to store 
+                                                    ! the RHS of the equation
+!
+!REAL, DIMENSION(SIZE(PY,1),SIZE(PY,2),SIZE(PY,3)) :: ZWORK ! work array used by 
+! the FFT. It has been enlarged in order to be sufficient for 2D and 3D cases
+!
+REAL, DIMENSION(SIZE(PBF,1),SIZE(PBF,2),SIZE(PBF,3)) :: ZAF ! work array to
+!                                                        ! expand PAF
+INTEGER :: IIB          ! indice I for the first inner mass point along x
+INTEGER :: IIE          ! indice I for the last inner mass point along x
+INTEGER :: IIMAX        ! number of inner mass points along the x direction
+INTEGER :: IJB          ! indice J for the first inner mass point along y
+INTEGER :: IJE          ! indice J for the last inner mass point along y
+INTEGER :: IJMAX        ! number of inner mass points along the y direction
+INTEGER :: IKB          ! indice K for the first inner mass point along z
+INTEGER :: IKE          ! indice K for the last inner mass point along z
+INTEGER :: IKU          ! size of the arrays along z
+INTEGER :: IKMAX        ! number of inner mass points along the z direction
+!
+REAL :: ZDXM2,ZDYM2     ! respectively equal to PDXHATM*PDXHATM 
+                        ! and PDYHATM*PDYHATM                         
+INTEGER :: JI,JJ,JK     ! loop indexes along x, y, z respectively
+!
+!
+INTEGER :: IIE_INT,IJE_INT   ! highest indice I  and J values for the x y modes.
+                             ! They  depend on the l.b.c. !
+!
+INTEGER :: ILOTX,ILOTY ! number of data vectors along x, y resp. computed 
+                       ! in parallel during the FFT process 
+!
+INTEGER :: INC1X,INC1Y ! increment within each data vector for the FFT along
+                       ! x, y resp.
+!
+INTEGER :: INC2X,INC2Y ! increment between the start of one data vector and 
+                       ! the next for the FFT along x,y resp.
+!
+!
+REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZWORKX ! work array used by
+! the FFT. It has been enlarged in order to be sufficient for 2D and 3D cases
+REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZWORKY ! work array used by
+! the FFT. It has been enlarged in order to be sufficient for 2D and 3D cases
+!
+REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZGAM
+                                                        ! intermediate arrays
+REAL, DIMENSION(:,:), ALLOCATABLE   :: ZBETX            ! for the tridiag.
+                                                        ! matrix inversion
+REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZBAND_X  ! array in X slices distribution
+REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZBAND_Y  ! array in Y slices distribution
+REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZBAND_YR ! array in Y slices distribution
+!
+INTEGER :: IINFO_ll           ! return code of parallel routine
+!
+INTEGER :: IIX,IJX,IIY,IJY ! dimensions of the extended x or y slices subdomain
+!
+REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZBAND_YT  ! array in Y slices distribution transpose
+REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZBAND_YRT ! array in Y slices distribution transpose
+!-------------------------------------------------------------------------------
+!
+!*       1.    COMPUTE LOOP BOUNDS
+!              -------------------
+!
+CALL GET_PHYSICAL_ll(IIB,IJB,IIE,IJE)
+CALL GET_DIM_EXT_ll('X',IIX,IJX)
+CALL GET_DIM_EXT_ll('Y',IIY,IJY)
+IIMAX = IIX-2*JPHEXT
+IJMAX = IJY-2*JPHEXT
+!
+IKU=SIZE(PY,3)
+IKB=1+JPVEXT
+IKE=IKU - JPVEXT
+IKMAX=IKE-IKB+1
+!
+!!
+ALLOCATE(ZBAND_X(IIX,IJX,IKU))
+ALLOCATE(ZBAND_Y(IIY,IJY,IKU))
+ALLOCATE(ZBAND_YR(IIY,IJY,IKU))
+ALLOCATE(ZWORKX(IIX,IJX,IKU))
+ALLOCATE(ZWORKY(IIY,IJY,IKU))
+ALLOCATE(ZBETX(IIY,IJY))
+ALLOCATE(ZGAM(IIY,IJY,IKU))
+IF (.NOT. L2D) THEN
+  ALLOCATE(ZBAND_YT(IJY,IIY,IKU))
+  ALLOCATE(ZBAND_YRT(IJY,IIY,IKU))
+END IF
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.    COMPUTE THE ARRAY INCREMENTS FOR THE FFT
+!              ----------------------------------------
+!
+IF(.NOT. L2D) THEN
+!
+  ILOTX = IJX*IKU
+  INC1X = 1
+  INC2X = IIX
+!
+  ILOTY = IIY*IKU
+  INC1Y = 1
+  INC2Y = IJY
+!
+ELSE
+!
+  ILOTX = IKU
+  INC1X = 1
+  INC2X = IIX*IJX
+ENDIF
+!
+!-------------------------------------------------------------------------------
+!
+!*      3.    FORM HOMOGENEOUS BOUNDARY CONDITIONS FOR A NONCYCLIC CASE
+!             ---------------------------------------------------------
+!
+!
+!*      3.1 copy the RHS in a local array REMAP functions will shift the indices for the FFT
+!
+PF_1_Y = 0.
+ZY = PY
+!
+!*      3.2 form homogeneous boundary condition used by the FFT for non-periodic
+!           cases
+!
+!  modify the RHS in the x direction
+!
+IF (HLBCX(1) /= 'CYCL') THEN
+!
+  IF (LWEST_ll(HSPLITTING='B')) THEN
+    DO JK=IKB,IKE                    
+      DO JJ = IJB, IJE
+        ZY(IIB,JJ,JK)     = ZY(IIB,JJ,JK)     + PY(IIB-1,JJ,JK)
+      END DO
+    END DO
+  END IF
+!
+  IF (LEAST_ll(HSPLITTING='B')) THEN
+    DO JK=IKB,IKE
+      DO JJ = IJB, IJE
+        ZY(IIE,JJ,JK)     = ZY(IIE,JJ,JK)     - PY(IIE+1,JJ,JK)
+      END DO
+    END DO
+  END IF
+END IF
+!
+! modify the RHS in the same way along y
+!
+IF (HLBCY(1) /= 'CYCL'.AND. (.NOT. L2D)) THEN
+  IF (LSOUTH_ll(HSPLITTING='B')) THEN
+    DO JK=IKB,IKE
+      DO JI = IIB, IIE
+        ZY(JI,IJB,JK)     = ZY(JI,IJB,JK)     + PY(JI,IJB-1,JK)
+      END DO
+    END DO
+  END IF
+!
+  IF (LNORTH_ll(HSPLITTING='B')) THEN
+    DO JK=IKB,IKE
+      DO JI = IIB, IIE
+        ZY(JI,IJE,JK)     = ZY(JI,IJE,JK)     - PY(JI,IJE+1,JK)
+      END DO
+    END DO
+  END IF
+END IF
+!
+!
+!*      3.3 2way structure -> xslice structure, + data shift
+!
+ZBAND_X=0.
+CALL REMAP_2WAY_X_ll(ZY,ZBAND_X,IINFO_ll)
+!
+!  
+!-------------------------------------------------------------------------------
+!
+!*      4.    APPLY A REAL TO COMPLEX FFT
+!             ---------------------------
+!
+!
+IF (HLBCX(1) == 'CYCL') THEN
+  CALL FFT991(ZBAND_X(1,1,IKB-1),ZWORKX,PTRIGSX,KIFAXX,INC1X,INC2X,  &
+              IIMAX,ILOTX,-1 )
+ELSE
+  CALL FFT55(ZBAND_X(1,1,IKB-1),ZWORKX,PTRIGSX,KIFAXX,INC1X,INC2X,  &
+             IIMAX,ILOTX,-1 )
+END IF  
+!
+!
+ZBAND_Y=0.
+CALL REMAP_X_Y_ll(ZBAND_X,ZBAND_Y,IINFO_ll)
+!
+IF (.NOT. L2D) THEN                                 
+!
+! array transposition I --> J
+!
+  CALL FAST_TRANSPOSE(ZBAND_Y,ZBAND_YT,IIY,IJY,IKU)
+!
+  IF (HLBCY(1) == 'CYCL') THEN
+      CALL FFT991(ZBAND_YT(1,1,IKB-1),ZWORKY,PTRIGSY,KIFAXY,INC1Y,INC2Y,  &
+                  IJMAX,ILOTY,-1 )
+  ELSE
+      CALL FFT55(ZBAND_YT(1,1,IKB-1),ZWORKY,PTRIGSY,KIFAXY,INC1Y,INC2Y,  &
+                  IJMAX,ILOTY,-1 )
+  END IF 
+!
+END IF                                        
+!
+!       singular matrix case : the last term is computed by setting the 
+!       average of the pressure field equal to zero.
+IF (LWEST_ll(HSPLITTING='Y')) THEN
+  IF (L2D) THEN
+    ZBAND_Y(1,1,IKE+1)=0
+  ELSE
+    ZBAND_YT(1,1,IKE+1)=0.
+  END IF
+END IF
+!
+!-------------------------------------------------------------------------------
+!
+!*      5.    MATRIX INVERSION FOR THE FLAT OPERATOR
+!             --------------------------------------
+!
+CALL FAST_SPREAD(PAF,ZAF,IIY,IJY,IKU)
+!
+IF (LWEST_ll(HSPLITTING='Y')) THEN
+   ZAF(1,1,IKE+1)=0. !singular matrix corresponding to the horizontal average
+END IF
+!
+IF (L2D) THEN
+  CALL FAST_SUBSTITUTION_2D(ZBAND_YR,ZBETX,PBF,ZGAM,PCF,ZAF &
+                           ,ZBAND_Y,IIY,IJY,IKU)
+ELSE
+  CALL FAST_SUBSTITUTION_3D(ZBAND_YRT,ZBETX,PBF,ZGAM,PCF,ZAF &
+                      ,ZBAND_YT,IIY,IJY,IKU)
+END IF
+!  
+!
+!-------------------------------------------------------------------------------
+!
+!*      6.    APPLY A COMPLEX TO REAL FFT
+!             ---------------------------
+!
+!  
+IF (.NOT. L2D) THEN
+  IF (HLBCY(1) == 'CYCL') THEN
+    CALL FFT991( ZBAND_YRT(1,1,IKB-1),ZWORKY,PTRIGSY,KIFAXY,INC1Y,INC2Y,  &
+                  IJMAX,ILOTY,+1 )
+  ELSE
+      CALL FFT55( ZBAND_YRT(1,1,IKB-1),ZWORKY,PTRIGSY,KIFAXY,INC1Y,INC2Y,  &
+                  IJMAX,ILOTY,+1 )
+  END IF 
+  ! array transposition J --> I
+  CALL FAST_TRANSPOSE(ZBAND_YRT,ZBAND_YR,IJY,IIY,IKU)
+ENDIF
+!
+! Transposition Y-> X
+!
+ZBAND_X=0.
+CALL REMAP_Y_X_ll(ZBAND_YR,ZBAND_X,IINFO_ll)
+!
+!
+IF (HLBCX(1) == 'CYCL') THEN
+    CALL FFT991( ZBAND_X(1,1,IKB-1),ZWORKX,PTRIGSX,KIFAXX,INC1X,INC2X,  &
+                IIMAX,ILOTX,+1 )
+ELSE
+    CALL FFT55( ZBAND_X(1,1,IKB-1),ZWORKX,PTRIGSX,KIFAXX,INC1X,INC2X,  &
+                IIMAX,ILOTX,+1 )
+END IF  
+!
+!-------------------------------------------------------------------------------
+!
+!*      7.    RETURN TO A NON HOMOGENEOUS NEUMAN CONDITION FOR NON-CYCLIC CASES
+!             -----------------------------------------------------------------
+!
+!*      7.1   Transposition + shift X -> 2way
+!
+CALL REMAP_X_2WAY_ll(ZBAND_X,PF_1_Y,IINFO_ll)
+!
+!*      7.2 complete the lateral boundaries
+!
+IF (HLBCX(1) /= 'CYCL') THEN
+!
+!*      7.2.1 return to a non-homogeneous case in the x direction
+! 
+  ZDXM2 = PDXHATM*PDXHATM
+!
+  IF (LWEST_ll(HSPLITTING='B')) THEN
+    DO JK=IKB,IKE
+      DO JJ = IJB,IJE
+        PF_1_Y(IIB-1,JJ,JK) = PF_1_Y(IIB,JJ,JK) - PY(IIB-1,JJ,JK)*ZDXM2/PRHOM(JK)
+      END DO
+    END DO
+  END IF
+!
+  IF (LEAST_ll(HSPLITTING='B')) THEN
+    DO JK=IKB,IKE
+      DO JJ = IJB,IJE
+        PF_1_Y(IIE+1,JJ,JK) = PF_1_Y(IIE,JJ,JK) + PY(IIE+1,JJ,JK)*ZDXM2/PRHOM(JK)
+      END DO
+    END DO
+  END IF
+!
+!    we set the solution at the corner point by the condition:
+!    dxm ( P ) = 0
+  IF (LWEST_ll(HSPLITTING='B')) THEN
+    DO JJ = IJB,IJE
+      PF_1_Y(IIB-1,JJ,IKB-1) = PF_1_Y(IIB,JJ,IKB-1) 
+      PF_1_Y(IIB-1,JJ,IKE+1) = PF_1_Y(IIB,JJ,IKE+1)
+    END DO
+  END IF
+  IF (LEAST_ll(HSPLITTING='B')) THEN
+    DO JJ = IJB,IJE
+      PF_1_Y(IIE+1,JJ,IKB-1) = PF_1_Y(IIE,JJ,IKB-1)
+      PF_1_Y(IIE+1,JJ,IKE+1) = PF_1_Y(IIE,JJ,IKE+1)
+    END DO
+  END IF
+!
+ELSE
+!
+!*      7.2.2 periodize the pressure function field along the x direction
+!
+! in fact this part is useless because it is done in the routine
+! REMAP_X_2WAY.
+!
+END IF
+!
+IF (.NOT.L2D) THEN
+  IF (HLBCY(1) /= 'CYCL') THEN
+!
+!*      7.2.3 return to a non-homogeneous case in the y direction
+!
+    ZDYM2 = PDYHATM*PDYHATM 
+!
+    IF (LSOUTH_ll(HSPLITTING='B')) THEN
+      DO JK=IKB,IKE
+        DO JI = IIB,IIE
+          PF_1_Y(JI,IJB-1,JK) = PF_1_Y(JI,IJB,JK) - PY(JI,IJB-1,JK)*ZDYM2/PRHOM(JK)
+        END DO
+      END DO
+    END IF
+!
+    IF (LNORTH_ll(HSPLITTING='B')) THEN
+      DO JK=IKB,IKE
+        DO JI = IIB,IIE
+          PF_1_Y(JI,IJE+1,JK) = PF_1_Y(JI,IJE,JK) + PY(JI,IJE+1,JK)*ZDYM2/PRHOM(JK)
+        END DO
+      END DO
+    END IF
+!    we set the solution at the corner point by the condition:
+!    dym ( P )  = 0
+!
+    IF (LSOUTH_ll(HSPLITTING='B')) THEN
+      DO JI = IIB,IIE
+        PF_1_Y(JI,IJB-1,IKB-1) = PF_1_Y(JI,IJB,IKB-1)
+        PF_1_Y(JI,IJB-1,IKE+1) = PF_1_Y(JI,IJB,IKE+1)
+      END DO
+    END IF
+!
+    IF (LNORTH_ll(HSPLITTING='B')) THEN
+      DO JI = IIB,IIE
+        PF_1_Y(JI,IJE+1,IKB-1) = PF_1_Y(JI,IJE,IKB-1)
+        PF_1_Y(JI,IJE+1,IKE+1) = PF_1_Y(JI,IJE,IKE+1)
+      END DO
+    END IF
+  ELSE
+!
+!*      7.2.4 periodize the pressure function field along the y direction
+!
+!
+! in fact this part is useless because it is done in the routine
+! REMAP_X_2WAY.
+!
+  END IF
+!
+END IF
+!
+IF (.NOT. L2D .AND. HLBCX(1)/='CYCL' .AND. HLBCY(1)/='CYCL') THEN
+! the following verticals are not used
+  IF ( (LWEST_ll(HSPLITTING='B')).AND.(LSOUTH_ll(HSPLITTING='B')) ) THEN
+    PF_1_Y(IIB-1,IJB-1,:)=PF_1_Y(IIB,IJB,:)
+  END IF
+!
+  IF ( (LWEST_ll(HSPLITTING='B')).AND.(LNORTH_ll(HSPLITTING='B')) ) THEN
+    PF_1_Y(IIB-1,IJE+1,:)=PF_1_Y(IIB,IJE,:)
+  END IF
+!
+  IF ( (LEAST_ll(HSPLITTING='B')).AND.(LSOUTH_ll(HSPLITTING='B')) ) THEN
+    PF_1_Y(IIE+1,IJB-1,:)=PF_1_Y(IIE,IJB,:)
+  END IF
+!
+  IF ( (LEAST_ll(HSPLITTING='B')).AND.(LNORTH_ll(HSPLITTING='B')) ) THEN
+    PF_1_Y(IIE+1,IJE+1,:)=PF_1_Y(IIE,IJE,:)
+  END IF
+END IF
+!
+DEALLOCATE(ZBAND_X)
+DEALLOCATE(ZBAND_Y)
+IF (.NOT. L2D) THEN
+  DEALLOCATE(ZBAND_YT)
+  DEALLOCATE(ZBAND_YRT)
+END IF
+DEALLOCATE(ZBAND_YR)
+DEALLOCATE(ZWORKX)
+DEALLOCATE(ZWORKY)
+DEALLOCATE(ZBETX)
+DEALLOCATE(ZGAM)
+!
+!-------------------------------------------------------------------------------
+!
+CONTAINS
+  SUBROUTINE FAST_TRANSPOSE(PX,PXT,KNI,KNJ,KNK)
+    INTEGER                      :: KNI,KNJ,KNK ! 3D dimension of X and XT
+    REAL, DIMENSION(KNI*KNJ,KNK) :: PX
+    REAL, DIMENSION(KNJ*KNI,KNK) :: PXT
+    !
+    INTEGER                      :: IJI,II,IJ,IIJ ! index in array X and XT
+    INTEGER                      :: JK
+!
+    DO JK=1,KNK
+       ! PERMUTATION(PX,PXT)
+       !CDIR NODEP
+       !OCL NOVREC
+       DO IJI = 1, KNJ*KNI
+          ! I,J Indice in XT array from linearised index IJI
+          II   = 1 +    (IJI-1)/KNJ
+          IJ   = IJI - (II-1)*KNJ 
+          ! linearised index in X
+          IIJ = II + (IJ-1)*KNI 
+          ! transposition
+          PXT(IJI,JK) = PX(IIJ,JK)
+       
+       END DO
+    END DO
+!    
+END SUBROUTINE FAST_TRANSPOSE
+
+SUBROUTINE FAST_SUBSTITUTION_3D(PBAND_YR,PBETX,PPBF,PGAM,PPCF,PAF &
+                            ,PBAND_Y,KIY,KJY,KKU)
+INTEGER                        :: KIY,KJY,KKU
+REAL, DIMENSION (KIY*KJY,KKU)  :: PBAND_YR,PBAND_Y,PPBF,PGAM,PAF
+REAL, DIMENSION (KIY*KJY)      :: PBETX
+REAL, DIMENSION (KKU)          :: PPCF
+INTEGER                        :: JK
+!
+!
+!       initialization 
+!
+!
+PBAND_YR = 0.0
+PBETX(:) = PPBF(:,IKB-1)
+PBAND_YR(:,IKB-1) = PBAND_Y(:,IKB-1)  &
+                                      / PBETX(:)
+!
+!        decomposition and forward substitution
+!
+DO JK = IKB,IKE+1
+  PGAM(:,JK) = PPCF(JK-1) / PBETX(:)
+!
+  PBETX(:) = PPBF(:,JK) -              &      
+                 PAF(:,JK)*PGAM(:,JK)
+!
+  PBAND_YR(:,JK) = ( PBAND_Y(:,JK) -  &
+       PAF(:,JK)*PBAND_YR(:,JK- 1) )  &
+                                /PBETX(:)
+!
+END DO
+!
+!       backsubstitution
+!
+DO JK = IKE,IKB-1,-1
+  PBAND_YR(:,JK) = PBAND_YR(:,JK) -    &
+          PGAM(:,JK+1)*PBAND_YR(:,JK+1)
+END DO
+!  
+!
+END SUBROUTINE FAST_SUBSTITUTION_3D
+!
+SUBROUTINE FAST_SUBSTITUTION_2D(PBAND_YR,PBETX,PPBF,PGAM,PPCF,PAF &
+                            ,PBAND_Y,KIY,KJY,KKU)
+INTEGER                        :: KIY,KJY,KKU
+REAL, DIMENSION (KIY,KJY,KKU)  :: PBAND_YR,PBAND_Y,PPBF,PGAM,PAF
+REAL, DIMENSION (KIY,KJY)      :: PBETX
+REAL, DIMENSION (KKU)          :: PPCF
+INTEGER                        :: JK
+!
+!
+!       initialization 
+!
+!
+PBAND_YR = 0.0
+PBETX(:,1) = PPBF(:,1,IKB-1)
+PBAND_YR(:,1,IKB-1) = PBAND_Y(:,1,IKB-1)  &
+                                     / PBETX(:,1)
+!
+!        decomposition and forward substitution
+!
+DO JK = IKB,IKE+1
+  PGAM(:,1,JK) = PPCF(JK-1) / PBETX(:,1)
+!
+  PBETX(:,1) = PPBF(:,1,JK) -              &      
+                 PAF(:,1,JK)*PGAM(:,1,JK)
+!
+  PBAND_YR(:,1,JK) = ( PBAND_Y(:,1,JK) -  &
+       PAF(:,1,JK)*PBAND_YR(:,1,JK- 1) )  &
+                                /PBETX(:,1)
+!
+END DO
+!
+!       backsubstitution
+!
+DO JK = IKE,IKB-1,-1
+  PBAND_YR(:,1,JK) = PBAND_YR(:,1,JK) -    &
+          PGAM(:,1,JK+1)*PBAND_YR(:,1,JK+1)
+END DO
+!  
+!
+END SUBROUTINE FAST_SUBSTITUTION_2D
+
+SUBROUTINE FAST_SPREAD(PTAB1D,PTAB3D,KIY,KJY,KKU)
+INTEGER                        :: KIY,KJY,KKU
+REAL, DIMENSION (KKU)          :: PTAB1D
+REAL, DIMENSION (KIY*KJY,KKU)  :: PTAB3D
+
+INTEGER                        :: JIJ,JK
+!
+DO JK=1,KKU
+   DO JIJ=1,KIY*KJY
+      PTAB3D(JIJ,JK) = PTAB1D(JK)
+   ENDDO
+ENDDO
+!
+END SUBROUTINE FAST_SPREAD
+!
+!------------------------------------------------------------------------------  
+END SUBROUTINE FLAT_INV
diff --git a/src/ZSOLVER/gdiv.f90 b/src/ZSOLVER/gdiv.f90
new file mode 100644
index 0000000000000000000000000000000000000000..5bfd218bf519a7bf8bbbcae521aeffcf7e33ff0e
--- /dev/null
+++ b/src/ZSOLVER/gdiv.f90
@@ -0,0 +1,353 @@
+!MNH_LIC Copyright 1994-2020 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+!     ################
+      MODULE MODI_GDIV
+!     ################
+!
+INTERFACE
+!
+      SUBROUTINE GDIV(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PU,PV,PW,PGDIV)
+!  
+IMPLICIT NONE
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX    ! x-direction LBC type 
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY    ! y-direction LBC type
+! 
+                                                 ! Metric coefficients:       
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDXX      ! d*xx 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDYY      ! d*yy 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZX      ! d*zx 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZY      ! d*zy 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZZ      ! d*zz
+!
+                                                 ! Field components
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PU        ! along x             
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PV        ! along y
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PW        ! along z
+!
+REAL, DIMENSION(:,:,:), INTENT(OUT)    :: PGDIV     ! divergence at 
+                                                    ! a mass point
+!
+END SUBROUTINE GDIV 
+!
+END INTERFACE
+!
+END MODULE MODI_GDIV
+!
+!     ####################################################################
+      SUBROUTINE GDIV(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PU,PV,PW,PGDIV)
+!     ####################################################################
+!
+!!****  *GDIV * - Compute J times the divergence of 1/J times a vector defined 
+!!      by its cartesian components 
+!!
+!!    PURPOSE
+!!    -------
+!       The purpose of this function is to compute J times the divergence of 
+!     1/J times a vector which cartesian components are (U, V, W). The result
+!     is localized at a mass point: 
+!    
+!                    GDIV = dxf (UC) + dyf (VC) + dzf (WC)
+!       
+!     where UC, VC, WC are the contravariant components of the vector.
+!     The array is completed outside the physical domain by the value of the
+!     normal component at the boundary. 
+!
+!!**  METHOD
+!!    ------
+!!      First, we compute the contravariant components by using 
+!!    the suboutine CONTRAV (The metric coefficients are dummy arguments). Then 
+!!    we use the Shuman finite difference operators DXF, DYF, DZF to compute 
+!!    the divergence. The result is localized at a mass point.
+!!
+!!    EXTERNAL
+!!    --------
+!!      SUBROUTINE CONTRAV : compute the contavariant components 
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------ 
+!!      Module MODD_PARAMETERS: declaration of parameter variables
+!!        JPHEXT, JPVEXT: define the number of marginal points out of the 
+!!        physical domain along horizontal and vertical directions respectively
+!!     Module MODD_CONF: model configurations
+!!        L2D: logical for 2D model version
+!!      Module MODI_SHUMAN : interface for the Shuman operators
+!!      Module MODI_CONTRAV : interface for the contravariant components
+!!
+!!    REFERENCE
+!!    ---------
+!!      Book2 of documentation (routine GDIV)
+!!      
+!!
+!!    AUTHOR
+!!    ------
+!!	P. Hereil and J. Stein       * Meteo France *
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original    11/07/94 
+!!                  17/07/97  ( J. Stein and V. Masson) initialize the corner
+!!                             verticals
+!!                  30/09/97  ( J. Stein ) bug correction for the case of
+!!                             non-vanishing oro. at the open lbc
+!!     Modification 15/06/98  (D.Lugato, R.Guivarch) Parallelisation
+!!                  22/08/02  (P Jabouille) simplification of parallel coding
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+!
+USE MODD_PARAMETERS
+USE MODD_CONF
+USE MODI_CONTRAV
+!
+USE MODE_ll
+!
+#ifdef MNH_OPENACC
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D
+#endif
+!
+IMPLICIT NONE
+!
+!*       0.1   declarations of arguments
+! 
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX    ! x-direction LBC type 
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY    ! y-direction LBC type
+! 
+                                                 ! Metric coefficients:       
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDXX      ! d*xx 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDYY      ! d*yy 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZX      ! d*zx 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZY      ! d*zy 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZZ      ! d*zz
+!
+                                                 ! Field components
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PU        ! along x             
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PV        ! along y
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PW        ! along z
+!
+REAL, DIMENSION(:,:,:), INTENT(OUT)     :: PGDIV             ! divergence at 
+                                                             ! a mass point
+!
+!*       0.2   declarations of local variables
+!
+                                         ! Contravariant components along:
+REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZUC      ! x
+REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZVC      ! y 
+REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZWC      ! z 
+REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: Z1,Z2,Z3 !work arrays
+INTEGER :: IZUC,IZVC,IZWC,IZ1,IZ2,IZ3
+!
+INTEGER :: IIB          ! indice I for the first inner mass point along x
+INTEGER :: IIE          ! indice I for the last inner mass point along x
+INTEGER :: IJB          ! indice J for the first inner mass point along y
+INTEGER :: IJE          ! indice J for the last inner mass point along y
+INTEGER :: IKB          ! indice K for the first inner mass point along z
+INTEGER :: IKE          ! indice K for the last inner mass point along z
+!
+INTEGER :: JI,JJ,JK                         ! loop indexes
+!
+#ifdef MNH_OPENACC
+INTEGER :: IIU,IJU,IKU
+!
+REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZTMP1,ZTMP2
+INTEGER :: IZTMP1,IZTMP2
+#endif
+!
+LOGICAL :: GWEST,GEAST,GSOUTH,GNORTH
+!
+!-------------------------------------------------------------------------------
+!
+!*       1.    COMPUTE LOOP BOUNDS
+!              -------------------
+!
+!
+CALL GET_INDICE_ll(IIB,IJB,IIE,IJE)
+IKB=1+JPVEXT
+IKE=SIZE(PU,3) - JPVEXT
+!
+!
+IIU=SIZE(PU,1)
+IJU=SIZE(PU,2)
+IKU=SIZE(PU,3)
+!
+#ifndef MNH_OPENACC
+ALLOCATE(ZUC(IIU,IJU,IKU),ZVC(IIU,IJU,IKU),ZWC(IIU,IJU,IKU))
+ALLOCATE(Z1(IIU,IJU,IKU),Z2(IIU,IJU,IKU),Z2(IIU,IJU,IKU))
+#else
+IZUC = MNH_ALLOCATE_ZT3D(ZUC,IIU,IJU,IKU  )
+IZVC = MNH_ALLOCATE_ZT3D(ZVC,IIU,IJU,IKU  )
+IZWC = MNH_ALLOCATE_ZT3D(ZWC,IIU,IJU,IKU  )
+IZ1 = MNH_ALLOCATE_ZT3D(Z1,IIU,IJU,IKU  )
+IZ2 = MNH_ALLOCATE_ZT3D(Z2,IIU,IJU,IKU  )
+IZ3 = MNH_ALLOCATE_ZT3D(Z3,IIU,IJU,IKU  )
+!
+IZTMP1 = MNH_ALLOCATE_ZT3D( ZTMP1,IIU,IJU,IKU  )
+IZTMP2 = MNH_ALLOCATE_ZT3D( ZTMP2,IIU,IJU,IKU  )
+#endif
+!
+GWEST  = ( HLBCX(1) /= 'CYCL' .AND. LWEST_ll() )
+GEAST  = ( HLBCX(2) /= 'CYCL' .AND. LEAST_ll() )
+GSOUTH = ( .NOT. L2D .AND. HLBCY(1) /= 'CYCL' .AND. LSOUTH_ll() )
+GNORTH = ( .NOT. L2D .AND. HLBCY(2) /= 'CYCL' .AND. LNORTH_ll() )
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.    COMPUTE THE CONTRAVARIANT COMPONENTS
+!              ------------------------------------
+!
+!*       2.1   prepare the boundary conditions
+!
+!
+!$acc kernels
+ DO CONCURRENT ( JI=1:IIU,JJ=1:IJU )
+    PU(JI,JJ,IKB-1)=PU(JI,JJ,IKB)
+    PU(JI,JJ,IKE+1)=PU(JI,JJ,IKE)
+    PV(JI,JJ,IKB-1)=PV(JI,JJ,IKB)
+    PV(JI,JJ,IKE+1)=PV(JI,JJ,IKE)
+ END DO
+!$acc end kernels
+! 
+!
+!*       2.1   compute the contravariant components
+!
+#ifndef MNH_OPENACC   
+CALL CONTRAV(HLBCX,HLBCY,PU,PV,PW,PDXX,PDYY,PDZZ,PDZX,PDZY,ZUC,ZVC,ZWC,4)
+#else
+CALL CONTRAV_DEVICE(HLBCX,HLBCY,PU,PV,PW,PDXX,PDYY,PDZZ,PDZX,PDZY,ZUC,ZVC,ZWC,4, &
+     ZTMP1,ZTMP2,ODATA_ON_DEVICE=.TRUE.)
+#endif
+!
+!-------------------------------------------------------------------------------
+!
+!*       3.    COMPUTE THE DIVERGENCE 
+!              ----------------------
+!
+!$acc kernels
+PGDIV=0. !usefull for the four corners and halo zones
+!
+Z1(IIB:IIE,:,:)=ZUC(IIB+1:IIE+1,:,:)-ZUC(IIB:IIE,:,:)
+Z2(:,IJB:IJE,:)=ZVC(:,IJB+1:IJE+1,:)-ZVC(:,IJB:IJE,:)
+Z3(:,:,IKB:IKE)=ZWC(:,:,IKB+1:IKE+1)-ZWC(:,:,IKB:IKE)
+!
+PGDIV(IIB:IIE,IJB:IJE,IKB:IKE)= Z1(IIB:IIE,IJB:IJE,IKB:IKE) +  &
+                                Z2(IIB:IIE,IJB:IJE,IKB:IKE) +  &
+                                Z3(IIB:IIE,IJB:IJE,IKB:IKE) 
+                               ! only the divergences computed 
+                               ! in the inner mass points are meaningful
+!$acc end kernels
+!
+!-------------------------------------------------------------------------------
+!
+!*       4.    SET DIVERGENCE AT THE OUTER POINTS
+!              ----------------------------------
+!
+!*       4.1   set divergence at the upper and lower boundary
+!
+!   we set the divergence equal to the vertical contravariant component above
+!   and under the physical domain
+!$acc kernels async
+DO JJ=IJB,IJE
+  DO JI=IIB,IIE
+    PGDIV(JI,JJ,IKB-1)=ZWC(JI,JJ,IKB)
+    PGDIV(JI,JJ,IKE+1)=ZWC(JI,JJ,IKE+1)
+  END DO
+END DO
+!$acc end kernels
+!
+!*       4.2   set divergence at the lateral boundaries
+!
+!   we set the divergence equal to the horizontal contravariant component at 
+!   the right and the left of the physical domain in both horizontal directions
+!   for non-periodic cases
+!
+IF( GWEST ) THEN
+   !$acc kernels async
+   DO JK=IKB,IKE
+      DO JJ=IJB,IJE
+         PGDIV(IIB-1,JJ,JK)=ZUC(IIB,JJ,JK)
+      END DO
+   END DO
+   !$acc end kernels
+END IF
+!
+IF( GEAST ) THEN
+   !$acc kernels async
+   DO JK=IKB,IKE
+      DO JJ=IJB,IJE
+         PGDIV(IIE+1,JJ,JK)=ZUC(IIE+1,JJ,JK)
+      END DO
+   END DO
+   !$acc end kernels
+END IF
+!
+!
+IF ( GSOUTH ) THEN
+   !$acc kernels async
+   DO JK=IKB,IKE
+      DO JI=IIB,IIE
+         PGDIV(JI,IJB-1,JK)=ZVC(JI,IJB,JK)
+      END DO
+   END DO
+   !$acc end kernels
+END IF
+!
+IF ( GNORTH ) THEN
+   !$acc kernels async
+   DO JK=IKB,IKE
+      DO JI=IIB,IIE
+         PGDIV(JI,IJE+1,JK)=ZVC(JI,IJE+1,JK)
+      END DO
+   END DO
+   !$acc end kernels
+END IF
+!
+! wait on GPU for all boundary condition update
+!$acc wait
+!
+!*       4.3   set divergence at the corner points  
+!
+! it is the following of the condition of copy the horizontal component
+! under the bottom of the model
+!
+IF( GWEST ) THEN
+   !$acc kernels async
+   PGDIV(IIB-1,IJB:IJE,IKB-1)=PGDIV(IIB-1,IJB:IJE,IKB)
+   PGDIV(IIB-1,IJB:IJE,IKE+1)=PGDIV(IIB-1,IJB:IJE,IKE)
+   !$acc end kernels
+END IF
+!
+IF ( GEAST ) THEN
+   !$acc kernels async
+   PGDIV(IIE+1,IJB:IJE,IKB-1)=PGDIV(IIE+1,IJB:IJE,IKB)
+   PGDIV(IIE+1,IJB:IJE,IKE+1)=PGDIV(IIE+1,IJB:IJE,IKE)
+   !$acc end kernels
+END IF
+!
+IF ( GSOUTH ) THEN
+   !$acc kernels async
+   PGDIV(IIB:IIE,IJB-1,IKB-1)=PGDIV(IIB:IIE,IJB-1,IKB)
+   PGDIV(IIB:IIE,IJB-1,IKE+1)=PGDIV(IIB:IIE,IJB-1,IKE)
+   !$acc end kernels
+END IF
+!
+IF ( GNORTH ) THEN
+   !$acc kernels async
+   PGDIV(IIB:IIE,IJE+1,IKB-1)=PGDIV(IIB:IIE,IJE+1,IKB)
+   PGDIV(IIB:IIE,IJE+1,IKE+1)=PGDIV(IIB:IIE,IJE+1,IKE)
+   !$acc end kernels
+END IF
+!
+! wait on GPU for all corner update
+!$acc wait
+!
+#ifdef MNH_OPENACC
+CALL MNH_REL_ZT3D (IZUC,IZVC,IZWC,IZ1,IZ2,IZ3,IZTMP1,IZTMP2)
+#endif
+!
+!-------------------------------------------------------------------------------
+!
+END SUBROUTINE GDIV
diff --git a/src/ZSOLVER/get_halo.f90 b/src/ZSOLVER/get_halo.f90
new file mode 100644
index 0000000000000000000000000000000000000000..784b664f64a3842ce6a230d8fad1f047258b2fa3
--- /dev/null
+++ b/src/ZSOLVER/get_halo.f90
@@ -0,0 +1,1274 @@
+!MNH_LIC Copyright 1994-2019 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+! Modifications:
+!  P. Wautelet 20/05/2019: add name argument to ADDnFIELD_ll + new ADD4DFIELD_ll subroutine
+!  P. Wautelet 18/07/2019: add optional dummy argument with name of the field
+!-----------------------------------------------------------------
+!     ####################
+      MODULE MODI_GET_HALO
+!     ####################
+!
+INTERFACE
+   SUBROUTINE GET_HALO2(PSRC, TP_PSRC_HALO2_ll, HNAME)
+     !
+     USE MODD_ARGSLIST_ll, ONLY : HALO2LIST_ll
+     !
+     IMPLICIT NONE
+     !
+     REAL, DIMENSION(:,:,:), INTENT(IN)  :: PSRC    ! variable at t
+     TYPE(HALO2LIST_ll), POINTER         :: TP_PSRC_HALO2_ll          ! halo2 for SRC
+     character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+     !
+   END SUBROUTINE GET_HALO2
+END INTERFACE
+!
+INTERFACE 
+   SUBROUTINE GET_HALO(PSRC, HDIR, HNAME)
+     IMPLICIT NONE
+     !
+     REAL, DIMENSION(:,:,:), INTENT(IN)  :: PSRC    ! variable at t
+     CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
+     character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+     !
+   END SUBROUTINE GET_HALO
+END INTERFACE
+! 
+#ifdef MNH_OPENACC
+INTERFACE
+   SUBROUTINE GET_HALO2_D(PSRC, TP_PSRC_HALO2_ll, HNAME)
+     !
+     USE MODD_ARGSLIST_ll, ONLY : HALO2LIST_ll
+     !
+     IMPLICIT NONE
+     !
+     REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+     TYPE(HALO2LIST_ll), POINTER         :: TP_PSRC_HALO2_ll          ! halo2 for SRC
+     character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+     !
+   END SUBROUTINE GET_HALO2_D
+END INTERFACE
+INTERFACE
+   SUBROUTINE GET_HALO2_DD(PSRC, TP_PSRC_HALO2_ll, HNAME)
+     !
+     USE MODD_ARGSLIST_ll, ONLY : HALO2LIST_ll
+     !
+     IMPLICIT NONE
+     !
+     REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+     TYPE(HALO2LIST_ll), POINTER         :: TP_PSRC_HALO2_ll          ! halo2 for SRC
+     character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+     !
+   END SUBROUTINE GET_HALO2_DD
+END INTERFACE
+INTERFACE
+   SUBROUTINE GET_HALO_D(PSRC, HDIR, HNAME)
+     IMPLICIT NONE
+     !
+     REAL, DIMENSION(:,:,:), INTENT(INOUT)   :: PSRC    ! variable at t
+     CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
+     character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+     !
+   END SUBROUTINE GET_HALO_D
+END INTERFACE
+!
+INTERFACE
+   SUBROUTINE GET_HALO_START_D(PSRC,KNB_REQ,KREQ,HDIR)
+     IMPLICIT NONE
+     !
+     REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC    ! variable at t
+     !$acc declare present (PSRC)
+     INTEGER                               :: KNB_REQ ,  KREQ(8)
+     CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
+     !
+   END SUBROUTINE GET_HALO_START_D
+END INTERFACE
+INTERFACE
+   SUBROUTINE GET_HALO_STOP_D(PSRC,KNB_REQ,KREQ,HDIR)
+     IMPLICIT NONE
+     REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC    ! variable at t
+     !$acc declare present (PSRC)
+     INTEGER                               :: KNB_REQ , KREQ(8)
+     CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
+   END SUBROUTINE GET_HALO_STOP_D
+END INTERFACE
+INTERFACE
+   SUBROUTINE GET_HALO_DD(PSRC, HDIR, HNAME)
+     IMPLICIT NONE
+     !
+     REAL, DIMENSION(:,:,:), INTENT(INOUT)   :: PSRC    ! variable at t
+     CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
+     character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+     !
+   END SUBROUTINE GET_HALO_DD
+END INTERFACE
+#endif
+!
+INTERFACE
+   SUBROUTINE DEL_HALO2_ll(TPHALO2LIST)
+     !
+     USE MODD_ARGSLIST_ll, ONLY : HALO2LIST_ll
+     !
+     IMPLICIT NONE
+     !
+     TYPE(HALO2LIST_ll), POINTER :: TPHALO2LIST ! list of HALO2_lls
+     !
+   END SUBROUTINE DEL_HALO2_ll
+   !
+END INTERFACE
+!
+END MODULE MODI_GET_HALO
+!
+!     ###################################################
+      SUBROUTINE GET_HALO2(PSRC, TP_PSRC_HALO2_ll, HNAME)
+!     ###################################################
+!
+USE MODE_ll
+USE MODD_ARGSLIST_ll, ONLY : LIST_ll, HALO2LIST_ll
+!
+IMPLICIT NONE
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+TYPE(HALO2LIST_ll), POINTER         :: TP_PSRC_HALO2_ll          ! halo2 for SRC
+character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+!
+character(len=:), allocatable    :: yname
+INTEGER                          :: IIU,IJU,IKU            ! domain sizes
+TYPE(LIST_ll)     , POINTER      :: TZ_PSRC_ll               ! halo
+INTEGER                          :: IERROR                 ! error return code 
+!
+IIU = SIZE(PSRC,1)
+IJU = SIZE(PSRC,2)
+IKU = SIZE(PSRC,3)
+
+if ( present ( hname ) ) then
+  yname = hname
+else
+  yname = 'PSRC'
+end if
+
+NULLIFY( TZ_PSRC_ll,TP_PSRC_HALO2_ll)
+CALL INIT_HALO2_ll(TP_PSRC_HALO2_ll,1,IIU,IJU,IKU)
+!
+CALL ADD3DFIELD_ll( TZ_PSRC_ll, PSRC, 'GET_HALO2::'//trim( yname ) )
+CALL UPDATE_HALO_ll(TZ_PSRC_ll,IERROR)
+CALL UPDATE_HALO2_ll(TZ_PSRC_ll,TP_PSRC_HALO2_ll,IERROR)
+!
+!   clean local halo list
+!
+CALL CLEANLIST_ll(TZ_PSRC_ll)
+!
+END SUBROUTINE GET_HALO2
+!-------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------
+!     ######################################
+      SUBROUTINE GET_HALO(PSRC, HDIR, HNAME)
+!     ######################################
+!
+USE MODE_ll
+USE MODD_ARGSLIST_ll, ONLY : LIST_ll
+!
+IMPLICIT NONE
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
+character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+!
+character(len=:), allocatable    :: yname
+TYPE(LIST_ll)     , POINTER      :: TZ_PSRC_ll               ! halo
+INTEGER                          :: IERROR                 ! error return code 
+!
+NULLIFY( TZ_PSRC_ll)
+
+if ( present ( hname ) ) then
+  yname = hname
+else
+  yname = 'PSRC'
+end if
+
+CALL ADD3DFIELD_ll( TZ_PSRC_ll, PSRC, 'GET_HALO::'//trim( yname ) )
+CALL UPDATE_HALO_ll(TZ_PSRC_ll,IERROR, HDIR=HDIR )
+CALL CLEANLIST_ll(TZ_PSRC_ll)
+!
+END SUBROUTINE GET_HALO
+!-----------------------------------------------------------------------
+#ifdef MNH_OPENACC
+MODULE MODD_HALO_D
+  
+  IMPLICIT NONE
+  
+  REAL, SAVE , ALLOCATABLE, DIMENSION(:,:,:)  :: ZNORTH_IN, ZSOUTH_IN, ZWEST_IN, ZEAST_IN
+  REAL, SAVE , ALLOCATABLE, DIMENSION(:,:,:)  :: ZNORTH_OUT, ZSOUTH_OUT, ZWEST_OUT, ZEAST_OUT
+
+  REAL, SAVE , ALLOCATABLE, DIMENSION(:,:)  :: ZNORTH2_IN, ZSOUTH2_IN, ZWEST2_IN, ZEAST2_IN
+  REAL, SAVE , ALLOCATABLE, DIMENSION(:,:)  :: ZNORTH2_OUT, ZSOUTH2_OUT, ZWEST2_OUT, ZEAST2_OUT
+  
+  LOGICAL, SAVE                               :: GFIRST_GET_HALO_D = .TRUE.
+  
+  LOGICAL, SAVE     :: GFIRST_INIT_HALO_D = .TRUE.
+  INTEGER, SAVE     :: IHALO_1  
+  INTEGER, SAVE     :: NP_NORTH,NP_SOUTH,NP_WEST,NP_EAST
+
+CONTAINS
+  
+  SUBROUTINE INIT_HALO_D()
+
+    USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU
+    USE MODE_MNH_ZWORK, ONLY : IIB,IJB ,IIE,IJE 
+    USE MODE_MNH_ZWORK, ONLY : GWEST , GEAST, GSOUTH , GNORTH
+    USE MODD_CONF, ONLY      : NHALO
+
+    USE MODD_VAR_ll, ONLY    : IP,NPROC,NP1,NP2
+
+
+    IMPLICIT NONE
+
+    IF (GFIRST_INIT_HALO_D) THEN 
+       !
+       IHALO_1 = NHALO-1
+       !
+       !  Init HALO
+       !
+       ALLOCATE  ( ZSOUTH_IN ( IIB:IIE   , IJB:IJB+IHALO_1   , IKU ) )
+       ALLOCATE  ( ZNORTH_IN ( IIB:IIE   , IJE-IHALO_1:IJE   , IKU ) )
+       ALLOCATE  ( ZWEST_IN  ( IIB:IIB+IHALO_1   , IJB:IJE   , IKU ) )
+       ALLOCATE  ( ZEAST_IN  ( IIE-IHALO_1:IIE   , IJB:IJE   , IKU ) )
+       !$acc enter data create (ZNORTH_IN, ZSOUTH_IN, ZWEST_IN, ZEAST_IN)
+       !
+       ALLOCATE  ( ZSOUTH_OUT (   IIB:IIE   , 1:IJB-1 , IKU ) )
+       ALLOCATE  ( ZNORTH_OUT (   IIB:IIE   , IJE+1:IJU , IKU ) )
+       ALLOCATE  ( ZWEST_OUT  ( 1:IIB-1 ,   IJB:IJE   , IKU ) )
+       ALLOCATE  ( ZEAST_OUT  ( IIE+1:IIU ,   IJB:IJE   , IKU ) )
+       !$acc enter data create (ZNORTH_OUT, ZSOUTH_OUT, ZWEST_OUT, ZEAST_OUT)
+       !
+       !  Init HALO2
+       !
+       ALLOCATE  ( ZSOUTH2_IN ( IIU , IKU ) )
+       ALLOCATE  ( ZNORTH2_IN ( IIU , IKU ) )
+       ALLOCATE  ( ZWEST2_IN  ( IJU , IKU ) )
+       ALLOCATE  ( ZEAST2_IN  ( IJU , IKU ) )
+       !$acc enter data create (ZNORTH2_IN, ZSOUTH2_IN, ZWEST2_IN, ZEAST2_IN)
+       !
+       ALLOCATE  ( ZSOUTH2_OUT ( IIU , IKU ) )
+       ALLOCATE  ( ZNORTH2_OUT ( IIU , IKU ) )
+       ALLOCATE  ( ZWEST2_OUT  ( IJU , IKU ) )
+       ALLOCATE  ( ZEAST2_OUT  ( IJU , IKU ) )
+       !$acc enter data create (ZNORTH2_OUT, ZSOUTH2_OUT, ZWEST2_OUT, ZEAST2_OUT)       
+
+       IF (.NOT. GWEST ) THEN
+          NP_WEST = ( IP-1 -1 ) + 1
+       ELSE
+          NP_WEST = 0
+       ENDIF
+       IF (.NOT. GEAST ) THEN
+          NP_EAST = ( IP-1 +1 ) + 1
+       ELSE
+          NP_EAST = 0
+       ENDIF
+       IF (.NOT. GSOUTH ) THEN
+          NP_SOUTH =  ( IP-1 -NP1 ) + 1
+       ELSE
+          NP_SOUTH = 0
+       ENDIF
+       IF (.NOT. GNORTH ) THEN
+          NP_NORTH =  ( IP-1 +NP1 ) + 1
+       ELSE
+          NP_NORTH = 0
+       ENDIF
+
+       !print*,"PROC=",IP, GWEST,NP_WEST, GEAST,NP_EAST, GSOUTH,NP_SOUTH ,  GNORTH,NP_NORTH
+       
+       GFIRST_INIT_HALO_D = .FALSE.
+       
+    END IF
+
+  END SUBROUTINE INIT_HALO_D
+
+END MODULE MODD_HALO_D
+!     #########################
+      SUBROUTINE GET_HALO_D(PSRC,HDIR,HNAME)
+!     #########################
+#define MNH_GPUDIRECT
+!
+USE MODD_HALO_D
+
+!USE MODE_MNH_ZWORK, ONLY : GWEST , GEAST, GSOUTH , GNORTH
+!USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU
+!USE MODE_MNH_ZWORK, ONLY : IIB,IJB ,IIE,IJE 
+!!
+!USE MODE_DEVICE
+USE MODE_MPPDB
+USE MODI_GET_HALO, ONLY : GET_HALO_START_D,GET_HALO_STOP_D
+!
+IMPLICIT NONE
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC    ! variable at t
+!$acc declare present (PSRC)
+CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
+character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+!
+INTEGER            :: INB_REQ , IREQ(8)
+!
+CALL GET_HALO_START_D(PSRC,INB_REQ,IREQ,HDIR)
+CALL GET_HALO_STOP_D(PSRC,INB_REQ,IREQ,HDIR)
+!
+END SUBROUTINE GET_HALO_D
+!     #########################
+      SUBROUTINE GET_HALO_START_D(PSRC,KNB_REQ,KREQ,HDIR)
+!     #########################
+#define MNH_GPUDIRECT
+!
+USE MODD_HALO_D
+
+USE MODE_MNH_ZWORK, ONLY : GWEST , GEAST, GSOUTH , GNORTH
+USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU
+USE MODE_MNH_ZWORK, ONLY : IIB,IJB ,IIE,IJE 
+!
+USE MODD_VAR_ll, ONLY : NMNH_COMM_WORLD
+USE MODD_MPIF,    ONLY : MPI_STATUSES_IGNORE
+USE MODD_PRECISION,  ONLY : MNHREAL_MPI
+!
+USE MODE_DEVICE
+USE MODE_MPPDB
+!
+IMPLICIT NONE
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC    ! variable at t
+!$acc declare present (PSRC)
+INTEGER                               :: KNB_REQ ,  KREQ(8)
+CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
+!
+INTEGER                          :: IERROR                 ! error return code 
+
+INTEGER,PARAMETER :: IS_WEST=1 , IS_EAST=2, IS_SOUTH=3, IS_NORTH=4
+LOGICAL      :: LX , LY
+INTEGER      :: NB_REQ, IERR
+!
+
+CALL INIT_HALO_D()
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+!$acc data present (ZNORTH_IN, ZSOUTH_IN, ZWEST_IN, ZEAST_IN) &
+!$acc present (ZNORTH_OUT, ZSOUTH_OUT, ZWEST_OUT, ZEAST_OUT)
+
+LX = .FALSE.
+LY = .FALSE. 
+
+IF (.NOT. PRESENT(HDIR) ) THEN
+LX = .TRUE.
+LY = .TRUE.
+ELSE
+!!$LX = ( HDIR == "01_X"  .OR. HDIR == "S0_X" )
+!!$LY = ( HDIR == "01_Y"  .OR. HDIR == "S0_Y" )
+LX = ( HDIR == "01_X" .OR. HDIR == "S0_X" .OR. HDIR == "S0_Y" )
+LY = ( HDIR == "01_Y" .OR. HDIR == "S0_Y" .OR. HDIR == "S0_X" )
+!!$print *,"IIB=",IIB," HDIR=",HDIR," LX=",LX," LY=",LY ; call flush(6)
+END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+NB_REQ = 0
+
+!
+! Post the recieve of Zxxxx_IN buffer first via MPI(Gpu_direct)
+!
+
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZWEST_OUT)
+#endif
+      NB_REQ = NB_REQ + 1
+      CALL MPI_IRECV(ZWEST_OUT,SIZE(ZWEST_OUT),MNHREAL_MPI,NP_WEST-1,1000+IS_EAST,NMNH_COMM_WORLD,KREQ(NB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   END IF
+   IF (.NOT.GEAST) THEN 
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZEAST_OUT)
+#endif
+      NB_REQ = NB_REQ + 1
+      CALL MPI_IRECV(ZEAST_OUT,SIZE(ZEAST_OUT),MNHREAL_MPI,NP_EAST-1,1000+IS_WEST,NMNH_COMM_WORLD,KREQ(NB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZSOUTH_OUT)
+#endif
+      NB_REQ = NB_REQ + 1
+      CALL MPI_IRECV(ZSOUTH_OUT,SIZE(ZSOUTH_OUT),MNHREAL_MPI,NP_SOUTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,KREQ(NB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZNORTH_OUT)
+#endif
+      NB_REQ = NB_REQ + 1
+      CALL MPI_IRECV(ZNORTH_OUT,SIZE(ZNORTH_OUT),MNHREAL_MPI,NP_NORTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,KREQ(NB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+!
+! Copy the halo(async) on the device PSRC to Zxxxx_IN buffer 
+!
+
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+      !$acc kernels async(IS_WEST)
+      ZWEST_IN ( IIB:IIB+IHALO_1  ,    IJB:IJE  , : )  = PSRC( IIB:IIB+IHALO_1  ,  IJB:IJE  , : )
+      !$acc end kernels
+   END IF
+   IF (.NOT.GEAST) THEN
+      !$acc kernels async(IS_EAST)
+      ZEAST_IN ( IIE-IHALO_1:IIE  ,    IJB:IJE  , : )  = PSRC( IIE-IHALO_1:IIE  ,  IJB:IJE  , : )
+      !$acc end kernels
+   ENDIF
+END IF
+
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+      !$acc kernels async(IS_SOUTH)
+      ZSOUTH_IN ( IIB:IIE  ,    IJB:IJB+IHALO_1  , : ) = PSRC( IIB:IIE  ,    IJB:IJB+IHALO_1  , : )
+      !$acc end kernels
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+      !$acc kernels async(IS_NORTH)
+      ZNORTH_IN ( IIB:IIE  ,    IJE-IHALO_1:IJE  , : ) = PSRC( IIB:IIE  ,    IJE-IHALO_1:IJE  , : )
+      !$acc end kernels
+   ENDIF   
+ENDIF
+
+!$acc wait
+
+!
+! Send  Zxxxx_IN buffer via MPI(Gpu_direct)
+!
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZWEST_IN)
+#else
+      !$acc update host(ZWEST_IN)
+#endif
+      NB_REQ = NB_REQ + 1
+      CALL MPI_ISEND(ZWEST_IN,SIZE(ZWEST_IN)  ,MNHREAL_MPI,NP_WEST-1,1000+IS_WEST,NMNH_COMM_WORLD,KREQ(NB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   END IF
+   IF (.NOT.GEAST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZEAST_IN)
+#else
+      !$acc update host(ZEAST_IN)
+#endif
+      NB_REQ = NB_REQ + 1
+      CALL MPI_ISEND(ZEAST_IN,SIZE(ZEAST_IN)  ,MNHREAL_MPI,NP_EAST-1,1000+IS_EAST,NMNH_COMM_WORLD,KREQ(NB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZSOUTH_IN)
+#else
+      !$acc update host(ZSOUTH_IN)
+#endif
+      NB_REQ = NB_REQ + 1
+      CALL MPI_ISEND(ZSOUTH_IN,SIZE(ZSOUTH_IN)  ,MNHREAL_MPI,NP_SOUTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,KREQ(NB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZNORTH_IN)
+#else
+      !$acc update host(ZNORTH_IN)
+#endif
+      NB_REQ = NB_REQ + 1
+      CALL MPI_ISEND(ZNORTH_IN,SIZE(ZNORTH_IN)  ,MNHREAL_MPI,NP_NORTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,KREQ(NB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF   
+ENDIF
+
+!$acc end data
+
+KNB_REQ = NB_REQ
+!
+END SUBROUTINE GET_HALO_START_D
+!
+!     #########################
+      SUBROUTINE GET_HALO_STOP_D(PSRC,KNB_REQ,KREQ,HDIR)
+!     #########################
+#define MNH_GPUDIRECT
+!
+USE MODD_HALO_D
+
+USE MODE_MNH_ZWORK, ONLY : GWEST , GEAST, GSOUTH , GNORTH
+USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU
+USE MODE_MNH_ZWORK, ONLY : IIB,IJB ,IIE,IJE 
+!
+USE MODD_VAR_ll, ONLY : NMNH_COMM_WORLD
+USE MODD_MPIF,    ONLY : MPI_STATUSES_IGNORE
+USE MODD_PRECISION,  ONLY : MNHREAL_MPI
+!
+USE MODE_DEVICE
+USE MODE_MPPDB
+!
+IMPLICIT NONE
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC    ! variable at t
+!$acc declare present (PSRC)
+INTEGER                               :: KNB_REQ , KREQ(8)
+CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
+!
+INTEGER                          :: IERROR                 ! error return code 
+
+INTEGER,PARAMETER :: IS_WEST=1 , IS_EAST=2, IS_SOUTH=3, IS_NORTH=4
+LOGICAL      :: LX , LY
+INTEGER      :: NB_REQ, IERR
+!
+
+CALL INIT_HALO_D()
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+!$acc data present (ZNORTH_IN, ZSOUTH_IN, ZWEST_IN, ZEAST_IN) &
+!$acc present (ZNORTH_OUT, ZSOUTH_OUT, ZWEST_OUT, ZEAST_OUT)
+
+LX = .FALSE.
+LY = .FALSE. 
+
+IF (.NOT. PRESENT(HDIR) ) THEN
+LX = .TRUE.
+LY = .TRUE.
+ELSE
+!!$LX = ( HDIR == "01_X"  .OR. HDIR == "S0_X" )
+!!$LY = ( HDIR == "01_Y"  .OR. HDIR == "S0_Y" )
+LX = ( HDIR == "01_X" .OR. HDIR == "S0_X" .OR. HDIR == "S0_Y" )
+LY = ( HDIR == "01_Y" .OR. HDIR == "S0_Y" .OR. HDIR == "S0_X" )
+!!$print *,"IIB=",IIB," HDIR=",HDIR," LX=",LX," LY=",LY ; call flush(6)
+END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+NB_REQ = KNB_REQ
+
+CALL MPI_WAITALL(NB_REQ,KREQ,MPI_STATUSES_IGNORE,IERR)
+
+!
+!   Copy back the Zxxx_OUT buffer recv via MPI(gpu_direct) to PSRC halo
+! 
+
+IF (LX) THEN
+   IF (.NOT.GWEST) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZWEST_OUT) async(IS_WEST)
+#endif
+   !$acc kernels async(IS_WEST)
+   PSRC( 1:IIB-1  ,      IJB:IJE      , : ) = ZWEST_OUT( 1:IIB-1  ,   IJB:IJE    , : )
+   !$acc end kernels
+   ENDIF
+   IF (.NOT.GEAST) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZEAST_OUT) async(IS_EAST)
+#endif
+   !$acc kernels async(IS_EAST)
+   PSRC( IIE+1:IIU  ,      IJB:IJE      , : ) = ZEAST_OUT( IIE+1:IIU  ,   IJB:IJE    , : )  
+   !$acc end kernels
+   ENDIF
+END IF
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZSOUTH_OUT) async(IS_SOUTH)
+#endif
+   !$acc kernels async(IS_SOUTH)
+   PSRC(      IIB:IIE       ,  1:IJB-1 , : ) = ZSOUTH_OUT(  IIB:IIE     , 1:IJB-1  , : )
+   !$acc end kernels
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZNORTH_OUT) async(IS_NORTH)
+#endif
+   !$acc kernels async(IS_NORTH)
+   PSRC(      IIB:IIE       , IJE+1:IJU , : ) = ZNORTH_OUT (  IIB:IIE     , IJE+1:IJU  , : )
+   !$acc end kernels
+   ENDIF
+END IF
+!$acc wait
+
+!$acc end data
+!
+END SUBROUTINE GET_HALO_STOP_D
+!-------------------------------------------------------------------------------
+!     ########################################
+      SUBROUTINE GET_HALO_DD(PSRC, HDIR, HNAME)
+!     ########################################
+#define MNH_GPUDIRECT
+!
+USE MODD_HALO_D
+USE MODE_ll
+USE MODD_ARGSLIST_ll, ONLY : LIST_ll
+USE MODD_PARAMETERS, ONLY : JPHEXT
+!
+USE MODD_IO,        ONLY : GSMONOPROC
+USE MODE_MNH_ZWORK, ONLY : GWEST , GEAST, GSOUTH , GNORTH
+!
+USE MODD_CONF, ONLY : NHALO
+USE MODE_DEVICE
+USE MODE_MPPDB
+
+USE MODD_VAR_ll, ONLY    : IP,NPROC,NP1,NP2
+USE MODD_VAR_ll, ONLY : NMNH_COMM_WORLD
+USE MODD_MPIF,    ONLY : MPI_STATUSES_IGNORE
+USE MODD_PRECISION,  ONLY : MNHREAL_MPI
+!
+USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU
+USE MODE_MNH_ZWORK, ONLY : IIB,IJB ,IIE,IJE 
+!
+IMPLICIT NONE
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC    ! variable at t
+CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction
+character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+!
+character(len=:), allocatable    :: yname
+TYPE(LIST_ll)     , POINTER      :: TZ_PSRC_ll               ! halo
+INTEGER                          :: IERROR                 ! error return code 
+
+INTEGER,PARAMETER :: IS_WEST=1 , IS_EAST=2, IS_SOUTH=3, IS_NORTH=4
+
+LOGICAL      :: LX , LY
+
+INTEGER      :: INB_REQ , IREQ(8)
+INTEGER      :: IERR
+
+if ( NPROC == 1 ) RETURN
+
+CALL INIT_HALO_D()
+
+!$acc data present ( PSRC )
+
+NULLIFY( TZ_PSRC_ll)
+!
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+LX = .FALSE.
+LY = .FALSE. 
+
+IF (.NOT. PRESENT(HDIR) ) THEN
+LX = .TRUE.
+LY = .TRUE.
+ELSE
+   !
+   !  Problem of reproductibility in ppm_s0_x/y if only S0_X or S0_Y
+   !  so add S0_X + S0_Y for ppm_s0*
+   !
+!!$LX = ( HDIR == "01_X" .OR. HDIR == "S0_X" )
+!!$LY = ( HDIR == "01_Y" .OR. HDIR == "S0_Y" )
+LX = ( HDIR == "01_X" .OR. HDIR == "S0_X" .OR. HDIR == "S0_Y" )
+LY = ( HDIR == "01_Y" .OR. HDIR == "S0_Y" .OR. HDIR == "S0_X" )
+END IF
+
+!!$LX = .TRUE.
+!!$LY = .TRUE.
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+INB_REQ = 0
+
+!
+! Post the recieve of Zxxxx_IN buffer first via MPI(Gpu_direct)
+!
+
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZWEST_OUT)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_IRECV(ZWEST_OUT,SIZE(ZWEST_OUT),MNHREAL_MPI,NP_WEST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   END IF
+   IF (.NOT.GEAST) THEN 
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZEAST_OUT)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_IRECV(ZEAST_OUT,SIZE(ZEAST_OUT),MNHREAL_MPI,NP_EAST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZSOUTH_OUT)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_IRECV(ZSOUTH_OUT,SIZE(ZSOUTH_OUT),MNHREAL_MPI,NP_SOUTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZNORTH_OUT)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_IRECV(ZNORTH_OUT,SIZE(ZNORTH_OUT),MNHREAL_MPI,NP_NORTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+!Copy the halo on the device PSRC to Zxxxx_IN
+
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+   !$acc kernels async(IS_WEST)
+   ZWEST_IN ( IIB:IIB+IHALO_1  ,    IJB:IJE  , : )  = PSRC( IIB:IIB+IHALO_1  ,  IJB:IJE  , : )
+   !$acc end kernels
+      END IF
+   IF (.NOT.GEAST) THEN
+   !$acc kernels async(IS_EAST)
+   ZEAST_IN ( IIE-IHALO_1:IIE  ,    IJB:IJE  , : )  = PSRC( IIE-IHALO_1:IIE  ,  IJB:IJE  , : )
+   !$acc end kernels
+      ENDIF
+END IF
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+   !$acc kernels async(IS_SOUTH)
+   ZSOUTH_IN ( IIB:IIE  ,    IJB:IJB+IHALO_1  , : ) = PSRC( IIB:IIE  ,    IJB:IJB+IHALO_1  , : )
+   !$acc end kernels
+      ENDIF
+   IF (.NOT.GNORTH) THEN
+   !$acc kernels async(IS_NORTH)
+   ZNORTH_IN ( IIB:IIE  ,    IJE-IHALO_1:IJE  , : ) = PSRC( IIB:IIE  ,    IJE-IHALO_1:IJE  , : )
+   !$acc end kernels
+   ENDIF
+ENDIF
+!$acc wait
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! Send  Zxxxx_IN buffer via MPI(Gpu_direct) or copy to host
+!
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZWEST_IN)
+#else
+      !$acc update host(ZWEST_IN)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_ISEND(ZWEST_IN,SIZE(ZWEST_IN)  ,MNHREAL_MPI,NP_WEST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   END IF
+   IF (.NOT.GEAST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZEAST_IN)
+#else
+      !$acc update host(ZEAST_IN)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_ISEND(ZEAST_IN,SIZE(ZEAST_IN)  ,MNHREAL_MPI,NP_EAST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZSOUTH_IN)
+#else
+      !$acc update host(ZSOUTH_IN)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_ISEND(ZSOUTH_IN,SIZE(ZSOUTH_IN)  ,MNHREAL_MPI,NP_SOUTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZNORTH_IN)
+#else
+      !$acc update host(ZNORTH_IN)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_ISEND(ZNORTH_IN,SIZE(ZNORTH_IN)  ,MNHREAL_MPI,NP_NORTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF   
+ENDIF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+IF ( INB_REQ > 0 ) THEN
+   CALL MPI_WAITALL(INB_REQ,IREQ,MPI_STATUSES_IGNORE,IERR)
+END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Is update halo
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+IF (LX) THEN
+   IF (.NOT.GWEST) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZWEST_OUT) async(IS_WEST)
+#endif
+   !$acc kernels async(IS_WEST)
+   PSRC( 1:IIB-1  ,      IJB:IJE      , : ) = ZWEST_OUT( 1:IIB-1  ,   IJB:IJE    , : )
+   !$acc end kernels
+   ENDIF
+   IF (.NOT.GEAST) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZEAST_OUT) async(IS_EAST)
+#endif
+   !$acc kernels async(IS_EAST)
+   PSRC( IIE+1:IIU  ,      IJB:IJE      , : ) = ZEAST_OUT( IIE+1:IIU  ,   IJB:IJE    , : )  
+   !$acc end kernels
+   ENDIF
+END IF
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZSOUTH_OUT) async(IS_SOUTH)
+#endif
+   !$acc kernels async(IS_SOUTH)
+   PSRC(      IIB:IIE       ,  1:IJB-1 , : ) = ZSOUTH_OUT(  IIB:IIE     , 1:IJB-1  , : )
+   !$acc end kernels
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZNORTH_OUT) async(IS_NORTH)
+#endif
+   !$acc kernels async(IS_NORTH)
+   PSRC(      IIB:IIE       , IJE+1:IJU , : ) = ZNORTH_OUT (  IIB:IIE     , IJE+1:IJU  , : )
+   !$acc end kernels
+   ENDIF
+END IF
+!$acc wait
+
+!$acc end data
+
+END SUBROUTINE GET_HALO_DD
+
+!-------------------------------------------------------------------------------
+!     ########################################
+      SUBROUTINE GET_HALO2_DD(PSRC, TP_PSRC_HALO2_ll, HNAME)
+!     ########################################
+#define MNH_GPUDIRECT
+!
+USE MODD_HALO_D
+USE MODE_ll
+USE MODD_ARGSLIST_ll, ONLY : LIST_ll
+USE MODD_PARAMETERS, ONLY : JPHEXT
+!
+USE MODD_IO,        ONLY : GSMONOPROC
+USE MODE_MNH_ZWORK, ONLY : GWEST , GEAST, GSOUTH , GNORTH
+USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU
+USE MODE_MNH_ZWORK, ONLY : IIB,IJB ,IIE,IJE
+!
+USE MODD_CONF, ONLY : NHALO
+USE MODE_DEVICE
+USE MODE_MPPDB
+!
+USE MODD_VAR_ll,     ONLY : IP,NPROC,NP1,NP2
+USE MODD_VAR_ll,     ONLY : NMNH_COMM_WORLD
+USE MODD_MPIF,       ONLY : MPI_STATUSES_IGNORE
+USE MODD_PRECISION,  ONLY : MNHREAL_MPI
+!
+IMPLICIT NONE
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC    ! variable at t
+TYPE(HALO2LIST_ll), POINTER  :: TP_PSRC_HALO2_ll  ! halo2 for SRC
+character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+!
+character(len=:), allocatable    :: yname
+INTEGER                          :: IERROR                 ! error return code 
+
+INTEGER,PARAMETER :: IS_WEST=1 , IS_EAST=2, IS_SOUTH=3, IS_NORTH=4
+
+LOGICAL      :: LX , LY
+
+INTEGER      :: INB_REQ , IREQ(8)
+INTEGER      :: IERR
+
+REAL , DIMENSION(:,:) , POINTER , CONTIGUOUS :: ZH2_EAST,ZH2_WEST,ZH2_NORTH,ZH2_SOUTH
+
+if ( NPROC == 1 ) RETURN
+
+!$acc data present ( PSRC ) &
+!$acc present (ZNORTH2_IN, ZSOUTH2_IN, ZWEST2_IN, ZEAST2_IN) &
+!$acc present (ZNORTH2_OUT, ZSOUTH2_OUT, ZWEST2_OUT, ZEAST2_OUT)
+!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+LX = .TRUE.
+LY = .TRUE.
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+INB_REQ = 0
+
+!
+! Post the recieve of Zxxxx_IN buffer first via MPI(Gpu_direct)
+!
+
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZWEST2_OUT)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_IRECV(ZWEST2_OUT,SIZE(ZWEST2_OUT),MNHREAL_MPI,NP_WEST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   END IF
+   IF (.NOT.GEAST) THEN 
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZEAST2_OUT)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_IRECV(ZEAST2_OUT,SIZE(ZEAST2_OUT),MNHREAL_MPI,NP_EAST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZSOUTH2_OUT)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_IRECV(ZSOUTH2_OUT,SIZE(ZSOUTH2_OUT),MNHREAL_MPI,NP_SOUTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZNORTH2_OUT)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_IRECV(ZNORTH2_OUT,SIZE(ZNORTH2_OUT),MNHREAL_MPI,NP_NORTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+!Copy the halo on the device PSRC to Zxxxx_IN
+
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+   !$acc kernels async(IS_WEST)
+!!$      ZWEST2_IN ( IIB:IIB+IHALO_1  ,    IJB:IJE  , : )  = PSRC( IIB:IIB+IHALO_1  ,  IJB:IJE  , : )
+      ZWEST2_IN ( : , : )  = PSRC( IIB+1  , : , : )
+   !$acc end kernels
+      END IF
+   IF (.NOT.GEAST) THEN
+   !$acc kernels async(IS_EAST)
+!!$      ZEAST2_IN ( IIE-IHALO_1:IIE  ,    IJB:IJE  , : )  = PSRC( IIE-IHALO_1:IIE  ,  IJB:IJE  , : )
+      ZEAST2_IN ( : , : )  = PSRC( IIE-1 ,  :  , : )
+   !$acc end kernels
+      ENDIF
+END IF
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+   !$acc kernels async(IS_SOUTH)
+!!$   ZSOUTH2_IN ( IIB:IIE  ,    IJB:IJB+IHALO_1  , : ) = PSRC( IIB:IIE  ,    IJB:IJB+IHALO_1  , : )
+      ZSOUTH2_IN ( : , : ) = PSRC( : , IJB+1 , : )
+   !$acc end kernels
+      ENDIF
+   IF (.NOT.GNORTH) THEN
+   !$acc kernels async(IS_NORTH)
+!!$      ZNORTH2_IN ( IIB:IIE  ,    IJE-IHALO_1:IJE  , : ) = PSRC( IIB:IIE  ,    IJE-IHALO_1:IJE  , : )
+      ZNORTH2_IN ( : , : ) = PSRC( : , IJE-1  , : )      
+   !$acc end kernels
+   ENDIF
+ENDIF
+!$acc wait
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! Send  Zxxxx2_IN buffer via MPI(Gpu_direct) or copy to host
+!
+IF (LX) THEN
+   IF (.NOT. GWEST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZWEST2_IN)
+#else
+      !$acc update host(ZWEST2_IN)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_ISEND(ZWEST2_IN,SIZE(ZWEST2_IN)  ,MNHREAL_MPI,NP_WEST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   END IF
+   IF (.NOT.GEAST) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZEAST2_IN)
+#else
+      !$acc update host(ZEAST2_IN)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_ISEND(ZEAST2_IN,SIZE(ZEAST2_IN)  ,MNHREAL_MPI,NP_EAST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+END IF
+
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZSOUTH2_IN)
+#else
+      !$acc update host(ZSOUTH2_IN)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_ISEND(ZSOUTH2_IN,SIZE(ZSOUTH2_IN)  ,MNHREAL_MPI,NP_SOUTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifdef MNH_GPUDIRECT
+      !$acc host_data use_device(ZNORTH2_IN)
+#else
+      !$acc update host(ZNORTH2_IN)
+#endif
+      INB_REQ = INB_REQ + 1
+      CALL MPI_ISEND(ZNORTH2_IN,SIZE(ZNORTH2_IN)  ,MNHREAL_MPI,NP_NORTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR)
+#ifdef MNH_GPUDIRECT
+      !$acc end host_data
+#endif
+   ENDIF   
+ENDIF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+IF ( INB_REQ > 0 ) THEN
+   CALL MPI_WAITALL(INB_REQ,IREQ,MPI_STATUSES_IGNORE,IERR)
+END IF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Is update halo
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+IF (LX) THEN
+   IF (.NOT.GWEST) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZWEST2_OUT) async(IS_WEST)
+#endif
+   ZH2_WEST => TP_PSRC_HALO2_ll%HALO2%WEST  
+   !$acc kernels async(IS_WEST)
+!!$      PSRC( 1:IIB-1  ,      IJB:IJE      , : ) = ZWEST2_OUT( 1:IIB-1  ,   IJB:IJE    , : )
+      ZH2_WEST( : , : ) = ZWEST2_OUT( : , : )      
+   !$acc end kernels
+   ENDIF
+   IF (.NOT.GEAST) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZEAST2_OUT) async(IS_EAST)
+#endif
+      ZH2_EAST => TP_PSRC_HALO2_ll%HALO2%EAST
+   !$acc kernels async(IS_EAST)
+!!$      PSRC( IIE+1:IIU  ,      IJB:IJE      , : ) = ZEAST2_OUT( IIE+1:IIU  ,   IJB:IJE    , : )
+      ZH2_EAST( : , : ) = ZEAST2_OUT( : , : )
+   !$acc end kernels
+   ENDIF
+END IF
+IF (LY) THEN
+   IF (.NOT.GSOUTH) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZSOUTH2_OUT) async(IS_SOUTH)
+#endif
+   ZH2_SOUTH => TP_PSRC_HALO2_ll%HALO2%SOUTH    
+   !$acc kernels async(IS_SOUTH)
+!!$      PSRC(      IIB:IIE       ,  1:IJB-1 , : ) = ZSOUTH2_OUT(  IIB:IIE     , 1:IJB-1  , : )
+     ZH2_SOUTH( : , : ) = ZSOUTH2_OUT( : , : )  
+   !$acc end kernels
+   ENDIF
+   IF (.NOT.GNORTH) THEN
+#ifndef MNH_GPUDIRECT
+   !$acc update device(ZNORTH2_OUT) async(IS_NORTH)
+#endif
+   ZH2_NORTH => TP_PSRC_HALO2_ll%HALO2%NORTH
+   !$acc kernels async(IS_NORTH)
+!!$      PSRC(      IIB:IIE       , IJE+1:IJU , : ) = ZNORTH2_OUT (  IIB:IIE     , IJE+1:IJU  , : )
+     ZH2_NORTH( : , : ) = ZNORTH2_OUT ( : , : )      
+   !$acc end kernels
+   ENDIF
+END IF
+!$acc wait
+
+!$acc end data
+
+END SUBROUTINE GET_HALO2_DD
+!
+!     ###################################################
+      SUBROUTINE GET_HALO2_D(PSRC, TP_PSRC_HALO2_ll, HNAME)
+!     ###################################################
+!
+USE MODE_ll
+USE MODD_ARGSLIST_ll, ONLY : LIST_ll, HALO2LIST_ll
+USE MODI_GET_HALO, ONLY : GET_HALO_D,GET_HALO_DD,GET_HALO2_DD
+!
+IMPLICIT NONE
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT)  :: PSRC    ! variable at t
+TYPE(HALO2LIST_ll), POINTER         :: TP_PSRC_HALO2_ll          ! halo2 for SRC
+character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added
+!
+character(len=:), allocatable    :: yname
+INTEGER                          :: IIU,IJU,IKU            ! domain sizes
+TYPE(LIST_ll)     , POINTER      :: TZ_PSRC_ll               ! halo
+INTEGER                          :: IERROR                 ! error return code 
+!
+IIU = SIZE(PSRC,1)
+IJU = SIZE(PSRC,2)
+IKU = SIZE(PSRC,3)
+
+if ( present ( hname ) ) then
+  yname = hname
+else
+  yname = 'PSRC'
+end if
+
+CALL GET_HALO_DD(PSRC,HNAME=yname)
+
+!!$NULLIFY( TZ_PSRC_ll,TP_PSRC_HALO2_ll)
+CALL INIT_HALO2_ll(TP_PSRC_HALO2_ll,1,IIU,IJU,IKU)
+!
+!!$CALL ADD3DFIELD_ll( TZ_PSRC_ll, PSRC, 'GET_HALO2_D::'//trim( yname ) )
+!!$CALL UPDATE_HALO2_ll(TZ_PSRC_ll,TP_PSRC_HALO2_ll,IERROR)
+CALL GET_HALO2_DD(PSRC,TP_PSRC_HALO2_ll,'GET_HALO2_DD::'//trim( yname ) )
+!
+!   clean local halo list
+!
+!!$CALL CLEANLIST_ll(TZ_PSRC_ll)
+!
+END SUBROUTINE GET_HALO2_D
+!
+#endif
+!-----------------------------------------------------------------------
+!
+!
+!     ####################################
+      SUBROUTINE DEL_HALO2_ll(TPHALO2LIST)
+!     ####################################
+!
+!!****  *DEL_HALO2_ll* delete the second layer of the halo
+!!
+!!
+!!    Purpose
+!!    -------
+!       The purpose of this routine is to deallocate the 
+!     TPHALO2LIST variable which contains the second layer of the
+!     halo for each variable.
+! 
+!!    Implicit Arguments
+!!    ------------------
+!     Module MODD_ARGSLIST_ll
+!       type HALO2LIST_ll
+!!
+!!    Reference
+!!    ---------
+! 
+!!    Author
+!!    ------
+!     J. Escobar                 * LA - CNRS *
+!
+!     Modification :
+!     -------------
+!     Juan  11/03/2010 : Memory Leak add DEALLOCATE(TZHALO2LIST%HALO2)     
+! 
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+!
+  USE MODD_ARGSLIST_ll, ONLY : HALO2LIST_ll
+!
+  IMPLICIT NONE
+!
+!*       0.1   Declarations of dummy arguments :
+!
+  TYPE(HALO2LIST_ll), POINTER :: TPHALO2LIST ! list of HALO2_lls
+!
+!
+!*       0.2   Declarations of local variables :
+!
+  TYPE(HALO2LIST_ll), POINTER :: TZHALO2LIST
+!
+!-------------------------------------------------------------------------------
+!
+!*       1.    Deallocate the list of HALO2_lls
+!
+  TZHALO2LIST => TPHALO2LIST
+!
+  DO WHILE(ASSOCIATED(TZHALO2LIST))
+!
+    TPHALO2LIST => TZHALO2LIST%NEXT
+    DEALLOCATE(TZHALO2LIST%HALO2%WEST)
+    DEALLOCATE(TZHALO2LIST%HALO2%EAST)
+    DEALLOCATE(TZHALO2LIST%HALO2%SOUTH)
+    DEALLOCATE(TZHALO2LIST%HALO2%NORTH)
+    DEALLOCATE(TZHALO2LIST%HALO2)
+    DEALLOCATE(TZHALO2LIST)
+    TZHALO2LIST => TPHALO2LIST
+!
+  ENDDO
+!
+!-------------------------------------------------------------------------------
+!
+      END SUBROUTINE DEL_HALO2_ll
diff --git a/src/ZSOLVER/ini_dynamics.f90 b/src/ZSOLVER/ini_dynamics.f90
new file mode 100644
index 0000000000000000000000000000000000000000..40aa0eb77eb2b9006ff0fba76d8f24366581a555
--- /dev/null
+++ b/src/ZSOLVER/ini_dynamics.f90
@@ -0,0 +1,640 @@
+!MNH_LIC Copyright 1994-2018 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt  
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+!     ########################
+      MODULE MODI_INI_DYNAMICS
+!     ########################
+INTERFACE
+SUBROUTINE INI_DYNAMICS(PLON,PLAT,PRHODJ,PTHVREF,PMAP,PZZ,                   &
+               PDXHAT,PDYHAT,PZHAT,HLBCX,HLBCY,PTSTEP,HPRESOPT,              &
+               OVE_RELAX,OVE_RELAX_GRD,OHORELAX_UVWTH,OHORELAX_RV,           &
+               OHORELAX_RC,OHORELAX_RR,OHORELAX_RI,OHORELAX_RS,OHORELAX_RG,  &
+               OHORELAX_RH,OHORELAX_TKE,OHORELAX_SV,                         &
+               OHORELAX_SVC2R2,OHORELAX_SVC1R3,OHORELAX_SVELEC,OHORELAX_SVLG,&
+               OHORELAX_SVCHEM,OHORELAX_SVAER,OHORELAX_SVDST,OHORELAX_SVSLT, &
+               OHORELAX_SVPP,OHORELAX_SVCS,  OHORELAX_SVCHIC,OHORELAX_SVSNW, &
+#ifdef MNH_FOREFIRE
+               OHORELAX_SVFF,                                                &
+#endif
+               PRIMKMAX,KRIMX,KRIMY,PALKTOP,PALKGRD,PALZBOT,PALZBAS,         &
+               PT4DIFU,PT4DIFTH,PT4DIFSV,                                    &
+               PCORIOX,PCORIOY,PCORIOZ,PCURVX,PCURVY,                        &
+               PDXHATM,PDYHATM,PRHOM,PAF,PBFY,PCF,                           &
+               PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,                                &
+               PALK,PALKW,KALBOT,PALKBAS,PALKWBAS,KALBAS,                    &
+               OMASK_RELAX,PKURELAX, PKVRELAX, PKWRELAX,                     &
+               PDK2U,PDK4U,PDK2TH,PDK4TH,PDK2SV,PDK4SV,OZDIFFU,PZDIFFU_HALO2,& 
+               PBFB,                                                         &
+               PBF_SXP2_YP1_Z,                                               &
+               PAF_ZS,PBF_ZS,PCF_ZS,                                         &
+               PDXATH_ZS,PDYATH_ZS,PRHO_ZS,                                  &
+               A_K,B_K,C_K,D_K) !JUAN FULL ZSOLVER
+!  intent in arguments
+!
+USE MODE_TYPE_ZDIFFU
+IMPLICIT NONE
+!
+REAL, DIMENSION(:,:),   INTENT(IN)        :: PLON,PLAT !Longitude and latitude
+REAL, DIMENSION(:,:,:), INTENT(IN)        :: PRHODJ    ! rho J
+REAL, DIMENSION(:,:,:), INTENT(IN)        :: PTHVREF   ! virtual potential 
+                                      ! temperature of the reference state
+REAL, DIMENSION(:,:),   INTENT(IN)        :: PMAP      ! Map factor
+REAL, DIMENSION(:,:,:), INTENT(IN)        :: PZZ       ! height 
+REAL, DIMENSION(:),     INTENT(IN)        :: PDXHAT     ! Stretching in x direction
+REAL, DIMENSION(:),     INTENT(IN)        :: PDYHAT     ! Stretching in y direction
+REAL, DIMENSION(:),     INTENT(IN)        :: PZHAT     ! Gal-Chen Height   
+CHARACTER(LEN=4), DIMENSION(:), INTENT(IN) :: HLBCX    ! x-direction LBC type
+CHARACTER(LEN=4), DIMENSION(:), INTENT(IN) :: HLBCY    ! y-direction LBC type
+LOGICAL,                INTENT(IN)        :: OVE_RELAX ! logical
+             ! switch to activate the VErtical  RELAXation
+LOGICAL,                INTENT(IN)        :: OVE_RELAX_GRD ! logical
+             ! switch to activate the VErtical  RELAXation (ground layer)
+LOGICAL,            INTENT(IN) :: OHORELAX_UVWTH  ! switch for the 
+                       ! horizontal relaxation for U,V,W,TH
+LOGICAL,            INTENT(IN) :: OHORELAX_RV     ! switch for the 
+                       ! horizontal relaxation for Rv
+LOGICAL,            INTENT(IN) :: OHORELAX_RC     ! switch for the 
+                       ! horizontal relaxation for Rc
+LOGICAL,            INTENT(IN) :: OHORELAX_RR     ! switch for the 
+                       ! horizontal relaxation for Rr
+LOGICAL,            INTENT(IN) :: OHORELAX_RI     ! switch for the 
+                       ! horizontal relaxation for Ri
+LOGICAL,            INTENT(IN) :: OHORELAX_RS     ! switch for the 
+                       ! horizontal relaxation for Rs
+LOGICAL,            INTENT(IN) :: OHORELAX_RG     ! switch for the 
+                       ! horizontal relaxation for Rg
+LOGICAL,            INTENT(IN) :: OHORELAX_RH     ! switch for the 
+                       ! horizontal relaxation for Rh
+LOGICAL,            INTENT(IN) :: OHORELAX_TKE    ! switch for the 
+                       ! horizontal relaxation for tke
+LOGICAL,DIMENSION(:),INTENT(IN):: OHORELAX_SV     ! switch for the 
+                       ! horizontal relaxation for sv variables
+LOGICAL,             INTENT(IN):: OHORELAX_SVC2R2 ! switch for the 
+                       ! horizontal relaxation for c2r2 variables
+LOGICAL,             INTENT(IN):: OHORELAX_SVC1R3 ! switch for the 
+                       ! horizontal relaxation for c1r3 variables
+LOGICAL,             INTENT(IN):: OHORELAX_SVELEC ! switch for the 
+                       ! horizontal relaxation for elec variables
+LOGICAL,             INTENT(IN):: OHORELAX_SVLG   ! switch for the 
+                       ! horizontal relaxation for lg variables
+LOGICAL,             INTENT(IN):: OHORELAX_SVCHEM ! switch for the 
+                       ! horizontal relaxation for chem variables
+LOGICAL,             INTENT(IN):: OHORELAX_SVCHIC ! switch for the 
+                       ! horizontal relaxation for ice chem variables
+LOGICAL,             INTENT(IN):: OHORELAX_SVAER  ! switch for the 
+                       ! horizontal relaxation for aer variables
+LOGICAL,             INTENT(IN):: OHORELAX_SVDST  ! switch for the 
+                       ! horizontal relaxation for dst variables
+LOGICAL,             INTENT(IN):: OHORELAX_SVSLT  ! switch for the 
+                       ! horizontal relaxation for slt variables
+LOGICAL,             INTENT(IN):: OHORELAX_SVPP   ! switch for the 
+                       ! horizontal relaxation for passive pollutants
+LOGICAL,             INTENT(IN):: OHORELAX_SVSNW   ! switch for the
+                       ! horizontal relaxation for blowing snow variables    
+#ifdef MNH_FOREFIRE
+LOGICAL,             INTENT(IN):: OHORELAX_SVFF   ! switch for the 
+                       ! horizontal relaxation for ForeFire variables
+#endif
+LOGICAL,             INTENT(IN):: OHORELAX_SVCS   ! switch for the 
+                       ! horizontal relaxation for conditional sampling
+REAL,                    INTENT(IN)    :: PRIMKMAX !Max. value of the horiz.
+                                     ! relaxation coefficients
+INTEGER,                INTENT(IN)     :: KRIMX,KRIMY ! Number of points in 
+                                     ! the rim zone in the x and y directions 
+REAL,     INTENT(IN)   :: PALKTOP    ! Damping coef. at the top of the absorbing
+                                     ! layer
+REAL,     INTENT(IN)   :: PALKGRD    ! Damping coef. at the top of the absorbing
+                                     ! layer                                    
+REAL,     INTENT(IN)   :: PALZBOT    ! Height of the absorbing layer base
+REAL,     INTENT(IN)   :: PALZBAS    ! Height of the absorbing layer base
+REAL,     INTENT(IN)   :: PT4DIFU    ! Damping time scale for 2*dx wavelength
+                                     ! specified for the 4nd order num. diffusion
+                                     ! for momentum
+REAL,     INTENT(IN)   :: PT4DIFTH   ! for meteorological scalar variables
+REAL,     INTENT(IN)   :: PT4DIFSV   ! for tracer scalar variables
+
+REAL,     INTENT(IN)   :: PTSTEP     ! Time step
+CHARACTER (LEN=5), INTENT(IN) :: HPRESOPT        ! choice of the pressure solver
+!
+!  intent out arguments
+!
+REAL, INTENT(OUT) :: PDXHATM                     ! mean grid increment in the x
+                                                 ! direction
+REAL, INTENT(OUT) :: PDYHATM                     ! mean grid increment in the y
+                                                 ! direction
+!
+REAL, DIMENSION (:), INTENT(OUT) :: PRHOM        !  mean of XRHODJ on the plane x y 
+                                                 !  localized at a mass level
+!
+REAL, DIMENSION(:,:), INTENT(OUT) :: PCORIOX,PCORIOY ! Hor. Coriolis parameters
+REAL, DIMENSION(:,:), INTENT(OUT) :: PCORIOZ         ! Vert. Coriolis parameter 
+REAL, DIMENSION(:,:), INTENT(OUT) :: PCURVX,PCURVY   ! Curvature coefficients
+! 
+REAL, DIMENSION(:),     INTENT(OUT) :: PAF ! vectors giving the non-vanishing        
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PBFY ! elements of the tri-diag matrix        
+                                            ! on an y-slice of global physical domain
+REAL, DIMENSION(:),     INTENT(OUT) :: PCF ! in the pressure equation
+REAL, DIMENSION(:),     INTENT(OUT) :: PTRIGSX ! Arrays for sinus or cosinus 
+REAL, DIMENSION(:),     INTENT(OUT) :: PTRIGSY ! values for the FFT in x and
+                                               ! y directions
+INTEGER, DIMENSION(:),  INTENT(OUT) :: KIFAXX  ! Decomposition in prime numbers
+INTEGER, DIMENSION(:),  INTENT(OUT) :: KIFAXY  ! for the FFT in x and y
+                                               ! direction      
+INTEGER          ,  INTENT(OUT)  :: KALBOT     ! Vertical index corresponding
+                                               ! to the absorbing layer base
+!  
+REAL, DIMENSION(:),   INTENT(OUT) :: PALK  ! Function of the absorbing
+                                           ! layer damping coefficient
+                                           ! defined for  u,v,and theta
+REAL, DIMENSION(:),   INTENT(OUT) :: PALKW ! Idem but defined for w    
+INTEGER          ,  INTENT(OUT)  :: KALBAS     ! Vertical index corresponding
+                                               ! to the absorbing layer base
+!  
+REAL, DIMENSION(:),   INTENT(OUT) :: PALKBAS  ! Function of the absorbing
+                                           ! layer damping coefficient
+                                           ! defined for  u,v,and theta
+REAL, DIMENSION(:),   INTENT(OUT) :: PALKWBAS ! Idem but defined for w
+LOGICAL, DIMENSION(:,:),  INTENT(OUT)   :: OMASK_RELAX  ! True where the 
+                                           ! lateral relax. has to be performed
+REAL, DIMENSION(:,:),     INTENT(OUT)   :: PKURELAX  !  Horizontal relaxation
+REAL, DIMENSION(:,:),     INTENT(OUT)   :: PKVRELAX  !  coefficients for the
+REAL, DIMENSION(:,:),     INTENT(OUT)   :: PKWRELAX  ! u, v and mass locations
+REAL,                 INTENT(OUT) :: PDK2U ! 2nd order num. diffusion coef. /dx2
+REAL,                 INTENT(OUT) :: PDK4U ! 4nd order num. diffusion coef. /dx4
+                                           ! for momentum
+REAL,                 INTENT(OUT) :: PDK2TH! for meteorological scalar variables
+REAL,                 INTENT(OUT) :: PDK4TH! 
+REAL,                 INTENT(OUT) :: PDK2SV! for tracer scalar variables
+REAL,                 INTENT(OUT) :: PDK4SV! 
+!
+LOGICAL, INTENT(IN) :: OZDIFFU
+TYPE(TYPE_ZDIFFU_HALO2)                       :: PZDIFFU_HALO2
+!
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PBFB ! elements of the tri-diag matrix
+                                            ! on an b-slice of global physical domain
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PBF_SXP2_YP1_Z ! elements of the tri-diag. SXP2_YP1_Z-slide 
+                                                   ! matrix in the pressure eq.
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PAF_ZS,PBF_ZS,PCF_ZS
+REAL, DIMENSION(:,:)  , INTENT(OUT) :: PDXATH_ZS,PDYATH_ZS
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PRHO_ZS
+REAL, DIMENSION(:)    , INTENT(OUT) :: A_K,B_K,C_K,D_K
+
+END SUBROUTINE INI_DYNAMICS
+!
+END INTERFACE
+!
+END MODULE MODI_INI_DYNAMICS
+!     ######################################################################
+SUBROUTINE INI_DYNAMICS(PLON,PLAT,PRHODJ,PTHVREF,PMAP,PZZ,                   &
+               PDXHAT,PDYHAT,PZHAT,HLBCX,HLBCY,PTSTEP,HPRESOPT,              &
+               OVE_RELAX,OVE_RELAX_GRD,OHORELAX_UVWTH,OHORELAX_RV,           &
+               OHORELAX_RC,OHORELAX_RR,OHORELAX_RI,OHORELAX_RS,OHORELAX_RG,  &
+               OHORELAX_RH,OHORELAX_TKE,OHORELAX_SV,                         &
+               OHORELAX_SVC2R2,OHORELAX_SVC1R3,OHORELAX_SVELEC,OHORELAX_SVLG,&
+               OHORELAX_SVCHEM,OHORELAX_SVAER,OHORELAX_SVDST,OHORELAX_SVSLT, &
+               OHORELAX_SVPP,OHORELAX_SVCS,  OHORELAX_SVCHIC,OHORELAX_SVSNW, &
+#ifdef MNH_FOREFIRE
+               OHORELAX_SVFF,                                                &
+#endif
+               PRIMKMAX,KRIMX,KRIMY,PALKTOP,PALKGRD,PALZBOT,PALZBAS,         &
+               PT4DIFU,PT4DIFTH,PT4DIFSV,                                    &
+               PCORIOX,PCORIOY,PCORIOZ,PCURVX,PCURVY,                        &
+               PDXHATM,PDYHATM,PRHOM,PAF,PBFY,PCF,                           &
+               PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,                                &
+               PALK,PALKW,KALBOT,PALKBAS,PALKWBAS,KALBAS,                    &
+               OMASK_RELAX,PKURELAX, PKVRELAX, PKWRELAX,                     &
+               PDK2U,PDK4U,PDK2TH,PDK4TH,PDK2SV,PDK4SV,OZDIFFU,PZDIFFU_HALO2,& 
+               PBFB,                                                         &
+               PBF_SXP2_YP1_Z,                                               &
+               PAF_ZS,PBF_ZS,PCF_ZS,                                         &
+               PDXATH_ZS,PDYATH_ZS,PRHO_ZS,                                  &
+               A_K,B_K,C_K,D_K) !JUAN FULL ZSOLVER  
+!     ######################################################################
+!
+!!****  *INI_DYNAMICS* - routine to initialize the parameters for the dynamics
+!!
+!!    PURPOSE
+!!    -------
+!       The purpose of this routine is to set or compute the parameters used
+!     by the MESONH dynamics : 
+!              * Coriolis parameters
+!              * Curvature coefficients
+!              * Pressure solver coefficients
+!              * Absorbing layer coefficients
+!              * Numerical difussion coefficients
+!
+!!**  METHOD
+!!    ------
+!!      - Coriolis parameters and curvature terms :
+!!           Horizontal Coriolis parameters are not initialized if thinshell
+!!    approximation is made (LTHINSHELL=.TRUE.).
+!!           Curvature coefficients are not initialized if Cartesian geometry
+!!    (LCARTESIAN=.TRUE.)  
+!!      - Coefficients and variables for pressure solver :
+!!          This is done by TRID
+!!      - Coefficients and variables for the absorbing layer 
+!!          ( upper and lateral) : This is done by RELAXDEF
+!!      - Coefficients for the numerical diffusion
+!!      
+!!    EXTERNAL
+!!    --------   
+!!      TRID    : to initialize pressure solver
+!!      RELAXDEF: to compute the relaxation coefficients
+!!      GET_DIM_EXT_ll : get extended sub-domain sizes
+!!
+!!     Module MODI_TRID   : interface for routine TRID
+!!     Module MODI_RELAXDEF : interface for routine RELAXDEF
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------ 
+!!      Module MODD_CONF  : contains declaration of configuration variables
+!!        
+!!         LTHINSHELL : Logical for  THINSHELL approximation                
+!!                     .TRUE.  = thinshell approximation
+!!         LCARTESIAN : Logical for cartesian geometry :
+!!                     .TRUE.  = cartesian geometry 
+!!         L1D        : Logical for 1D configuration :
+!!                     .TRUE.  = 1D model 
+!!
+!!      Module MODD_CST   : contains physical constants 
+!!
+!!         XPI        : Pi
+!!         XOMEGA     : Earth rotation
+!!
+!!      Module MODD_GRID  : contains grid variables
+!!
+!!         XLON0      :  Reference longitude for the conformal projection
+!!         XLAT0      :  Reference latitude for the conformal projection  
+!!         XBETA      :  Rotation angle for the conformal projection
+!!         XRPK       :  Projection parameter for the conformal projection
+!!
+!!    REFERENCE
+!!    ---------
+!!      Book2 of documentation (routine INI_DYNAMICS)
+!!      
+!!
+!!    AUTHOR
+!!    ------
+!!	V. Ducrocq       * Meteo France *
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original        01/07/94 
+!!      Modification    18/10/94 (J. Stein) to add the abs. layer
+!!      Modification    16/11/94 (Lafore+Pinty) to add the num. diffusion
+!!      Modification    06/12/94  (J.Stein) add the switch LABSLAYER
+!!      Modification    12/12/94  (J.Stein) add the lateral relaxation 
+!!      Modification    16/01/95  (J.Stein) conditional CALL to trid for 1D case
+!!      Modification    13/08/98  (N.Asencio) add parallel code
+!!      Modification    20/05/06  Remove KEPS
+!!      Modification    07/2013   (Bosseur & Filippi) Adds Forefire
+!!  Philippe Wautelet: 05/2016-04/2018: new data structures and calls for I/O
+!!     Vionnet 07/2017 : blow snow
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------ 
+USE MODD_CONF
+USE MODD_CST
+USE MODD_GRID
+USE MODD_LUNIT_n, ONLY: TLUOUT
+!
+USE MODI_RELAXDEF
+! USE MODI_TRID
+USE MODI_TRIDZ
+USE MODI_ZDIFFUSETUP
+!
+USE MODE_ll
+USE MODE_TYPE_ZDIFFU
+#ifdef MNH_BITREP
+USE MODI_BITREP
+#define SIN BR_SIN
+#define COS BR_COS
+#endif
+!
+USE MODE_MPPDB
+!
+IMPLICIT NONE
+!
+!*       0.1   declarations of argument
+!
+!  intent in arguments
+!
+REAL, DIMENSION(:,:),   INTENT(IN)        :: PLON,PLAT !Longitude and latitude
+REAL, DIMENSION(:,:,:), INTENT(IN)        :: PRHODJ    ! rho J
+REAL, DIMENSION(:,:,:), INTENT(IN)        :: PTHVREF   ! virtual potential 
+                                      ! temperature of the reference state
+REAL, DIMENSION(:,:),   INTENT(IN)        :: PMAP      ! Map factor
+REAL, DIMENSION(:,:,:), INTENT(IN)        :: PZZ       ! height 
+REAL, DIMENSION(:),     INTENT(IN)        :: PDXHAT     ! Stretching in x direction
+REAL, DIMENSION(:),     INTENT(IN)        :: PDYHAT     ! Stretching in y direction
+REAL, DIMENSION(:),     INTENT(IN)        :: PZHAT     ! Gal-Chen Height   
+CHARACTER(LEN=4), DIMENSION(:), INTENT(IN) :: HLBCX    ! x-direction LBC type
+CHARACTER(LEN=4), DIMENSION(:), INTENT(IN) :: HLBCY    ! y-direction LBC type
+LOGICAL,                INTENT(IN)        :: OVE_RELAX ! logical
+             ! switch to activate the VErtical  RELAXation 
+LOGICAL,                INTENT(IN)        :: OVE_RELAX_GRD ! logical
+             ! switch to activate the VErtical  RELAXation (ground layer)       
+LOGICAL,            INTENT(IN) :: OHORELAX_UVWTH  ! switch for the 
+                       ! horizontal relaxation for U,V,W,TH
+LOGICAL,            INTENT(IN) :: OHORELAX_RV     ! switch for the 
+                       ! horizontal relaxation for Rv
+LOGICAL,            INTENT(IN) :: OHORELAX_RC     ! switch for the 
+                       ! horizontal relaxation for Rc
+LOGICAL,            INTENT(IN) :: OHORELAX_RR     ! switch for the 
+                       ! horizontal relaxation for Rr
+LOGICAL,            INTENT(IN) :: OHORELAX_RI     ! switch for the 
+                       ! horizontal relaxation for Ri
+LOGICAL,            INTENT(IN) :: OHORELAX_RS     ! switch for the 
+                       ! horizontal relaxation for Rs
+LOGICAL,            INTENT(IN) :: OHORELAX_RG     ! switch for the 
+                       ! horizontal relaxation for Rg
+LOGICAL,            INTENT(IN) :: OHORELAX_RH     ! switch for the 
+                       ! horizontal relaxation for Rh
+LOGICAL,            INTENT(IN) :: OHORELAX_TKE    ! switch for the 
+                       ! horizontal relaxation for tke
+LOGICAL,DIMENSION(:),INTENT(IN):: OHORELAX_SV     ! switch for the 
+                       ! horizontal relaxation for sv variables
+LOGICAL,             INTENT(IN):: OHORELAX_SVC2R2 ! switch for the 
+                       ! horizontal relaxation for c2r2 variables
+LOGICAL,             INTENT(IN):: OHORELAX_SVC1R3 ! switch for the 
+                       ! horizontal relaxation for c1r3 variables
+LOGICAL,             INTENT(IN):: OHORELAX_SVELEC ! switch for the 
+                       ! horizontal relaxation for elec variables
+LOGICAL,             INTENT(IN):: OHORELAX_SVLG   ! switch for the 
+                       ! horizontal relaxation for lg variables
+LOGICAL,             INTENT(IN):: OHORELAX_SVCHEM ! switch for the 
+                       ! horizontal relaxation for chem variables
+LOGICAL,             INTENT(IN):: OHORELAX_SVCHIC ! switch for the
+                       ! horizontal relaxation for ice chem variables
+LOGICAL,             INTENT(IN):: OHORELAX_SVAER  ! switch for the 
+                       ! horizontal relaxation for aer variables
+LOGICAL,             INTENT(IN):: OHORELAX_SVDST  ! switch for the 
+                       ! horizontal relaxation for dst variables
+LOGICAL,             INTENT(IN):: OHORELAX_SVSLT  ! switch for the 
+                       ! horizontal relaxation for slt variables
+LOGICAL,             INTENT(IN):: OHORELAX_SVPP   ! switch for the 
+                       ! horizontal relaxation for passive pollutants
+LOGICAL,             INTENT(IN):: OHORELAX_SVSNW   ! switch for the
+                       ! horizontal relaxation for blowing snow variables
+#ifdef MNH_FOREFIRE
+LOGICAL,             INTENT(IN):: OHORELAX_SVFF   ! switch for the 
+                       ! horizontal relaxation for ForeFire variables
+#endif
+LOGICAL,             INTENT(IN):: OHORELAX_SVCS   ! switch for the 
+                       ! horizontal relaxation for conditional sampling
+REAL,                    INTENT(IN)    :: PRIMKMAX !Max. value of the horiz.
+                                     ! relaxation coefficients
+INTEGER,                INTENT(IN)     :: KRIMX,KRIMY ! Number of points in 
+                                     ! the rim zone in the x and y directions 
+REAL,     INTENT(IN)   :: PALKTOP    ! Damping coef. at the top of the absorbing
+                                     ! layer
+REAL,     INTENT(IN)   :: PALZBOT    ! Height of the absorbing layer base
+REAL,     INTENT(IN)   :: PALKGRD    ! Damping coef. at the top of the absorbing
+                                     ! layer
+REAL,     INTENT(IN)   :: PALZBAS    ! Height of the absorbing layer base
+REAL,     INTENT(IN)   :: PT4DIFU    ! Damping time scale for 2*dx wavelength
+                                     ! specified for the 4nd order num. diffusion
+                                     ! for momentum
+REAL,     INTENT(IN)   :: PT4DIFTH   ! for meteorological scalar variables
+REAL,     INTENT(IN)   :: PT4DIFSV   ! for tracer scalar variables
+
+REAL,     INTENT(IN)   :: PTSTEP     ! Time step
+CHARACTER (LEN=5), INTENT(IN) :: HPRESOPT        ! choice of the pressure solver
+!
+!  intent out arguments
+!
+REAL, INTENT(OUT) :: PDXHATM                     ! mean grid increment in the x
+                                                 ! direction
+REAL, INTENT(OUT) :: PDYHATM                     ! mean grid increment in the y
+                                                 ! direction
+!
+REAL, DIMENSION (:), INTENT(OUT) :: PRHOM        !  mean of XRHODJ on the plane x y 
+                                                 !  localized at a mass level
+!
+REAL, DIMENSION(:,:), INTENT(OUT) :: PCORIOX,PCORIOY ! Hor. Coriolis parameters
+REAL, DIMENSION(:,:), INTENT(OUT) :: PCORIOZ         ! Vert. Coriolis parameter 
+REAL, DIMENSION(:,:), INTENT(OUT) :: PCURVX,PCURVY   ! Curvature coefficients
+! 
+REAL, DIMENSION(:),     INTENT(OUT) :: PAF ! vectors giving the non-vanishing        
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PBFY ! elements of the tri-diag matrix
+                                            ! on an y-slice of global physical domain
+REAL, DIMENSION(:),     INTENT(OUT) :: PCF ! in the pressure equation
+REAL, DIMENSION(:),     INTENT(OUT) :: PTRIGSX ! Arrays for sinus or cosinus 
+REAL, DIMENSION(:),     INTENT(OUT) :: PTRIGSY ! values for the FFT in x and
+                                               ! y directions
+INTEGER, DIMENSION(:),  INTENT(OUT) :: KIFAXX  ! Decomposition in prime numbers
+INTEGER, DIMENSION(:),  INTENT(OUT) :: KIFAXY  ! for the FFT in x and y
+                                               ! direction      
+INTEGER          ,  INTENT(OUT)  :: KALBOT     ! Vertical index corresponding
+                                               ! to the absorbing layer base
+!  
+REAL, DIMENSION(:),   INTENT(OUT) :: PALK  ! Function of the absorbing
+                                           ! layer damping coefficient
+                                           ! defined for  u,v,and theta
+REAL, DIMENSION(:),   INTENT(OUT) :: PALKW ! Idem but defined for w     
+INTEGER          ,  INTENT(OUT)  :: KALBAS     ! Vertical index corresponding
+                                               ! to the absorbing layer base
+!  
+REAL, DIMENSION(:),   INTENT(OUT) :: PALKBAS  ! Function of the absorbing
+                                           ! layer damping coefficient
+                                           ! defined for  u,v,and theta
+REAL, DIMENSION(:),   INTENT(OUT) :: PALKWBAS ! Idem but defined for w
+LOGICAL, DIMENSION(:,:),  INTENT(OUT)   :: OMASK_RELAX  ! True where the 
+                                           ! lateral relax. has to be performed
+REAL, DIMENSION(:,:),     INTENT(OUT)   :: PKURELAX  !  Horizontal relaxation
+REAL, DIMENSION(:,:),     INTENT(OUT)   :: PKVRELAX  !  coefficients for the
+REAL, DIMENSION(:,:),     INTENT(OUT)   :: PKWRELAX  ! u, v and mass locations
+REAL,                 INTENT(OUT) :: PDK2U ! 2nd order num. diffusion coef. /dx2
+REAL,                 INTENT(OUT) :: PDK4U ! 4nd order num. diffusion coef. /dx4
+                                           ! for momentum
+REAL,                 INTENT(OUT) :: PDK2TH! for meteorological scalar variables
+REAL,                 INTENT(OUT) :: PDK4TH! 
+REAL,                 INTENT(OUT) :: PDK2SV! for tracer scalar variables
+REAL,                 INTENT(OUT) :: PDK4SV! 
+LOGICAL, INTENT(IN) :: OZDIFFU
+TYPE(TYPE_ZDIFFU_HALO2)                       :: PZDIFFU_HALO2
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PBFB ! elements of the tri-diag matrix
+                                            ! on an b-slice of global physical domain
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PBF_SXP2_YP1_Z ! elements of the tri-diag. SXP2_YP1_Z-slide 
+                                                   ! matrix in the pressure eq.
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PAF_ZS,PBF_ZS,PCF_ZS
+REAL, DIMENSION(:,:)  , INTENT(OUT) :: PDXATH_ZS,PDYATH_ZS
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PRHO_ZS
+REAL, DIMENSION(:)    , INTENT(OUT) :: A_K,B_K,C_K,D_K
+!
+!*       0.2   declarations of local variables
+!
+REAL, DIMENSION(SIZE(PRHODJ,1),SIZE(PRHODJ,2)) :: ZGAMMA ! Gamma =K(lambda-lambda0) - beta
+REAL                                       :: ZMBETA ! -beta
+REAL                                       :: ZCDR   ! to convert degrees in
+                                                     ! radians 
+INTEGER                                    :: ILUOUT ! Logical unit number for output_listing file
+INTEGER                                    :: IIU,IJU !  Upper bounds in x,y directions
+LOGICAL                                    :: GHORELAX
+LOGICAL, DIMENSION(7) :: GHORELAXR ! local array of logical
+#ifdef MNH_FOREFIRE
+LOGICAL, DIMENSION(13):: GHORELAXSV! local array of logical
+#else
+LOGICAL, DIMENSION(12):: GHORELAXSV! local array of logical
+#endif
+!
+!-------------------------------------------------------------------------------
+!
+!*       1.    COMPUTES CORIOLIS PARAMETERS AND CURVATURE COEFFICIENTS
+!              -------------------------------------------------------
+! 
+ZCDR = XPI/180.
+IF (.NOT.LCARTESIAN) THEN
+  ZGAMMA(:,:) = XRPK * ((PLON(:,:) - XLON0)*ZCDR) - (XBETA*ZCDR)
+  IF (.NOT.LTHINSHELL) THEN    
+    PCORIOX(:,:) = - 2. * XOMEGA * COS(PLAT(:,:)*ZCDR) * SIN(ZGAMMA(:,:))
+    PCORIOY(:,:) =   2. * XOMEGA * COS(PLAT(:,:)*ZCDR) * COS(ZGAMMA(:,:))
+  END IF
+  PCORIOZ(:,:)   =   2. * XOMEGA * SIN(PLAT(:,:)*ZCDR) 
+  PCURVX (:,:)   = COS(ZGAMMA(:,:)) * (SIN(PLAT(:,:)*ZCDR) -XRPK)         &
+                 / COS(PLAT(:,:)*ZCDR)
+  PCURVY (:,:)   = SIN(ZGAMMA(:,:)) * (SIN(PLAT(:,:)*ZCDR) -XRPK)         &
+                 / COS(PLAT(:,:)*ZCDR)
+  !
+  CALL MPPDB_CHECK2D(PCORIOX,"ini_dynamics:PCORIOX",PRECISION)
+  CALL MPPDB_CHECK2D(PCORIOY,"ini_dynamics:PCORIOY",PRECISION)
+  CALL MPPDB_CHECK2D(PCORIOZ,"ini_dynamics:PCORIOZ",PRECISION)
+  !
+ELSE
+  ZMBETA = - (XBETA*ZCDR)
+  PCORIOX(:,:) = - 2. * XOMEGA * COS(XLAT0*ZCDR) * SIN(ZMBETA)
+  PCORIOY(:,:) =   2. * XOMEGA * COS(XLAT0*ZCDR) * COS(ZMBETA)
+  PCORIOZ(:,:) =   2. * XOMEGA * SIN(XLAT0*ZCDR) 
+END IF           
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.    INITIALIZATION OF PRESSURE SOLVER
+!              ---------------------------------
+!
+IF (.NOT.L1D) THEN
+! CALL TRID(HLBCX,HLBCY,                                                  &
+!           PMAP,PDXHAT,PDYHAT,PDXHATM,PDYHATM,PRHOM,PAF,                 &
+!           PCF,PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,                            &
+!           PRHODJ,PTHVREF,PZZ,PBFY)
+  CALL TRIDZ(HLBCX,HLBCY,                                                 &
+            PMAP,PDXHAT,PDYHAT,HPRESOPT,                                  &
+            PDXHATM,PDYHATM,PRHOM,PAF,                                    &
+            PCF,PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,                            &
+            PRHODJ,PTHVREF,PZZ,PBFY,PBFB,                                 &
+            PBF_SXP2_YP1_Z,                                               &
+            PAF_ZS,PBF_ZS,PCF_ZS,                                         &
+            PDXATH_ZS,PDYATH_ZS,PRHO_ZS,                                  &
+            A_K,B_K,C_K,D_K) !JUAN  FULL ZSOLVER
+END IF
+!
+!
+!
+!-------------------------------------------------------------------------------
+!
+!*       3.    COMPUTE THE ABSORBING LAYER COEFFICIENTS
+!              ----------------------------------------
+!
+GHORELAXR(1) = OHORELAX_RV
+GHORELAXR(2) = OHORELAX_RC
+GHORELAXR(3) = OHORELAX_RR
+GHORELAXR(4) = OHORELAX_RI
+GHORELAXR(5) = OHORELAX_RS
+GHORELAXR(6) = OHORELAX_RG
+GHORELAXR(7) = OHORELAX_RH
+!
+GHORELAXSV(1) = OHORELAX_SVC2R2
+GHORELAXSV(2) = OHORELAX_SVC1R3
+GHORELAXSV(3) = OHORELAX_SVELEC
+GHORELAXSV(4) = OHORELAX_SVLG
+GHORELAXSV(5) = OHORELAX_SVCHEM
+GHORELAXSV(6) = OHORELAX_SVAER
+GHORELAXSV(7) = OHORELAX_SVDST
+GHORELAXSV(8) = OHORELAX_SVSLT
+GHORELAXSV(9) = OHORELAX_SVPP
+GHORELAXSV(10)= OHORELAX_SVCS
+GHORELAXSV(11) = OHORELAX_SVCHIC
+GHORELAXSV(12) = OHORELAX_SVSNW
+#ifdef MNH_FOREFIRE
+GHORELAXSV(13) = OHORELAX_SVFF
+#endif
+!
+GHORELAX=ANY(GHORELAXR) .OR. ANY(GHORELAXSV) .OR. ANY(OHORELAX_SV) &
+                        .OR. OHORELAX_UVWTH  .OR. OHORELAX_TKE 
+!
+IF (GHORELAX .OR. OVE_RELAX.OR.OVE_RELAX_GRD) THEN
+  CALL RELAXDEF( OVE_RELAX,OVE_RELAX_GRD,OHORELAX_UVWTH,OHORELAX_RV,  &
+     OHORELAX_RC,OHORELAX_RR,OHORELAX_RI,OHORELAX_RS,OHORELAX_RG,     &
+     OHORELAX_RH,OHORELAX_TKE,OHORELAX_SV,                            &
+     OHORELAX_SVC2R2,OHORELAX_SVC1R3,OHORELAX_SVELEC,OHORELAX_SVLG,   &
+     OHORELAX_SVCHEM, OHORELAX_SVAER, OHORELAX_SVDST, OHORELAX_SVSLT, &
+     OHORELAX_SVPP, OHORELAX_SVCS, OHORELAX_SVCHIC,OHORELAX_SVSNW,    &
+     PALKTOP,PALKGRD, PALZBOT,PALZBAS,                                &
+     PZZ, PZHAT, PTSTEP,                                              &
+     PRIMKMAX,KRIMX,KRIMY,                                            &
+     PALK, PALKW, KALBOT,                                             &
+     PALKBAS, PALKWBAS, KALBAS,                                       &
+     OMASK_RELAX,PKURELAX, PKVRELAX, PKWRELAX                         )
+END IF
+!
+!
+!
+!-------------------------------------------------------------------------------
+!
+!*       4.    COMPUTE THE NUMERICAL DIFFUSION COEFFICIENTS
+!              --------------------------------------------
+!
+PDK4U = 1.0/(16.0*PT4DIFU) ! The damping rate for the 2*dx wavelength is the same
+PDK2U = 2.0*PDK4U          ! for the 2nd and the 4th order diffusion schemes
+                           ! for momentum
+PDK4TH= 1.0/(16.0*PT4DIFTH) ! for meteorological scalar variables                       
+PDK2TH= 2.0*PDK4TH         
+PDK4SV= 1.0/(16.0*PT4DIFSV) ! for tracer scalar variables                       
+PDK2SV= 2.0*PDK4SV         
+!
+! Call ZDIFFUSETUP if OZDIFFU is true (parameters for truly horizontal diffusion)
+!
+IF (OZDIFFU) THEN
+  CALL ZDIFFUSETUP (PZZ,&
+                    PZDIFFU_HALO2)
+ENDIF
+!
+!-------------------------------------------------------------------------------
+!
+!*       5.    PRINT ON OUTPUT_LISTING
+!              -----------------------
+!
+IF (NVERB >= 10) THEN
+  CALL GET_DIM_EXT_ll ('B',IIU,IJU)
+  ILUOUT = TLUOUT%NLU
+!
+  WRITE(ILUOUT,*) 'INI_DYNAMICS : Some PCORIOZ values'
+  WRITE(ILUOUT,*) '(1,1)          (IIU/2,IJU/2)         (IIU,IJU)  '
+  WRITE(ILUOUT,*) PCORIOZ(1,1),PCORIOZ(IIU/2,IJU/2),PCORIOZ(IIU,IJU) 
+!
+  IF (.NOT.LTHINSHELL) THEN
+    WRITE(ILUOUT,*) 'INI_DYNAMICS : Some PCORIOX values'
+    WRITE(ILUOUT,*) '(1,1)          (IIU/2,IJU/2)         (IIU,IJU)  '
+    WRITE(ILUOUT,*) PCORIOX(1,1),PCORIOX(IIU/2,IJU/2),PCORIOX(IIU,IJU) 
+!
+    WRITE(ILUOUT,*) 'INI_DYNAMICS : Some PCORIOY values'
+    WRITE(ILUOUT,*) '(1,1)          (IIU/2,IJU/2)         (IIU,IJU)  '
+    WRITE(ILUOUT,*) PCORIOY(1,1),PCORIOY(IIU/2,IJU/2),PCORIOY(IIU,IJU) 
+  END IF
+!
+  IF ( .NOT. LCARTESIAN ) THEN
+    WRITE(ILUOUT,*) 'INI_DYNAMICS : Some PCURVX values'
+    WRITE(ILUOUT,*) '(1,1)          (IIU/2,IJU/2)         (IIU,IJU)  '
+    WRITE(ILUOUT,*) PCURVX(1,1),PCURVX(IIU/2,IJU/2),PCURVX(IIU,IJU)
+! 
+    WRITE(ILUOUT,*) 'INI_DYNAMICS : Some PCURVY values'
+    WRITE(ILUOUT,*) '(1,1)          (IIU/2,IJU/2)         (IIU,IJU)  '
+    WRITE(ILUOUT,*) PCURVY(1,1),PCURVY(IIU/2,IJU/2),PCURVY(IIU,IJU) 
+  END IF
+END IF
+!-------------------------------------------------------------------------------
+!
+END SUBROUTINE INI_DYNAMICS
diff --git a/src/ZSOLVER/ini_modeln.f90 b/src/ZSOLVER/ini_modeln.f90
new file mode 100644
index 0000000000000000000000000000000000000000..8203f0ada7d3d47b9a065697b8587553b551aa77
--- /dev/null
+++ b/src/ZSOLVER/ini_modeln.f90
@@ -0,0 +1,2525 @@
+!MNH_LIC Copyright 1994-2019 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+!     #######################
+      MODULE MODI_INI_MODEL_n
+!     #######################
+!
+INTERFACE
+!
+       SUBROUTINE INI_MODEL_n(KMI,TPINIFILE)
+!
+USE MODD_IO, ONLY: TFILEDATA
+!
+INTEGER,          INTENT(IN)   :: KMI       ! Model Index
+TYPE(TFILEDATA),  INTENT(IN)   :: TPINIFILE ! Initial file
+!
+END SUBROUTINE INI_MODEL_n
+!
+END INTERFACE
+!
+END MODULE MODI_INI_MODEL_n
+!     ############################################
+      SUBROUTINE INI_MODEL_n(KMI,TPINIFILE)
+!     ############################################
+!
+!!****  *INI_MODEL_n* - routine to initialize the nested model _n
+!!
+!!    PURPOSE
+!!    -------
+!       The purpose of this routine is to initialize the variables
+!     of the nested model _n.
+!
+!!**  METHOD
+!!    ------
+!!      The initialization of the model _n is performed as follows :
+!!       - Memory for arrays are then allocated :
+!!            * If  turbulence kinetic energy variable is not needed
+!!    (CTURB='NONE'),  XTKET, XTKEM and XTKES are zero-size arrays.
+!!            * If  dissipation of TKE variable is not needed
+!!    (CTURBLEN /='KEPS'),  XEPST, XEPSM and XREPSS are zero-size arrays.
+!!            * Memory for mixing ratio arrays is allocated according to the
+!!     value of logicals LUSERn (the number NRR of moist variables is deduced).
+!!            * The latitude (XLAT), longitude (XLON) and map factor (XMAP)
+!!     arrays are zero-size arrays if Cartesian geometry (LCARTESIAN=.TRUE.)
+!!            * Memory for reference state without orography ( XRHODREFZ and
+!!     XTHVREFZ) is only allocated in INI_MODEL1
+!!            * The horizontal Coriolis parameters (XCORIOX and XCORIOY) arrays
+!!     are  zero-size arrays if thinshell approximation (LTHINSHELL=.TRUE.)
+!!            * The Curvature coefficients (XCURVX and XCURVY) arrays
+!!     are zero-size arrays if Cartesian geometry (LCARTESIAN=.TRUE.)
+!!            * Memory for the Jacobian (ZJ) local array is allocated
+!!     (This variable is computed in SET_GRID and used in SET_REF).
+!!       - The spatial and temporal grid variables are initialized by SET_GRID.
+!!       - The metric coefficients are computed by METRICS (they are using in
+!!     the SET-REF call).
+!!       - The prognostic variables and are read in initial
+!!    LFIFM file (in READ_FIELD)
+!!       - The reference state variables  are initialized by SET_REF.
+!!       - The temporal indexes of the outputs are computed by SET_OUTPUT_TIMES
+!!       - The large scale sources are computed in case of coupling case by
+!!    INI_CPL.
+!!       - The initialization of the parameters needed for the dynamics
+!!         of the model n is realized in INI_DYNAMICS.
+!!       - Then the initial file (DESFM+LFIFM files) is closed by IO_File_close.
+!!       - The initialization of the parameters needed for the ECMWF radiation
+!!         code is realized in INI_RADIATIONS.
+!!       - The contents of the scalar variables are overwritten by
+!!         the chemistry initialization subroutine CH_INIT_FIELDn when
+!!         the flags LUSECHEM and LCH_INIT_FIELD are set to TRUE.
+!!         This allows easy initialization of the chemical fields at a
+!!         restart of the model.
+!!
+!!    EXTERNAL
+!!    --------
+!!      SET_DIM     : to initialize dimensions
+!!      SET_GRID    : to initialize grid
+!!      METRICS     : to compute metric coefficients
+!!      READ_FIELD  : to initialize field
+!!      FMCLOS      : to close a FM-file
+!!      SET_REF     : to initialize reference state for anelastic approximation
+!!      INI_DYNAMICS: to initialize parameters for the dynamics
+!!      INI_TKE_EPS : to initialize the TKE 
+!!      SET_DIRCOS  : to compute the director cosinus of the orography
+!!      INI_RADIATIONS : to initialize radiation computations
+!!      CH_INIT_CCS: to initialize the chemical core system
+!!      CH_INIT_FIELDn: to (re)initialize the scalar variables
+!!      INI_DEEP_CONVECTION : to initialize the deep convection scheme
+!!      CLEANLIST_ll : deaalocate a list
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------
+!!
+!!      Module MODD_PARAMETERS : contains declaration of parameter variables
+!!         JPHEXT : Horizontal external points number
+!!         JPVEXT : Vertical external points number
+!!
+!!      Module MODD_MODD_DYN   : contains declaration of parameters
+!!                               for the dynamics
+!!      Module MODD_CONF       : contains declaration of configuration variables
+!!                               for all models
+!!         NMODEL     : Number of nested models
+!!         NVERB      : Level of informations on output-listing
+!!                          0 for minimum  prints
+!!                          5 for intermediate level of prints
+!!                         10 for maximum  prints
+!!
+!!      Module MODD_REF        : contains declaration of reference state
+!!                               variables for all models
+!!      Module MODD_FIELD_n    : contains declaration of prognostic fields
+!!      Module MODD_LSFIELD_n  : contains declaration of Larger Scale fields
+!!      Module MODD_GRID_n     : contains declaration of spatial grid variables
+!!      Module MODD_TIME_n     : contains declaration of temporal grid variables
+!!      Module MODD_REF_n      : contains declaration of reference state
+!!                               variables
+!!      Module MODD_CURVCOR_n  : contains declaration of curvature and Coriolis
+!!                               variables
+!!      Module MODD_BUDGET     : contains declarations of the budget parameters
+!!      Module MODD_RADIATIONS_n:contains declaration of the variables of the
+!!                               radiation interface scheme
+!!      Module MODD_STAND_ATM  : contains declaration of the 5 standard
+!!                               atmospheres used for the ECMWF-radiation code
+!!      Module MODD_FRC        : contains declaration of the control variables
+!!                               and of the forcing fields
+!!      Module MODD_CH_MNHC_n   : contains the control parameters for chemistry
+!!      Module MODD_DEEP_CONVECTION_n: contains declaration of the variables of
+!!                                     the deep convection scheme
+!!
+!!
+!!
+!!
+!!      Module MODN_CONF_n     : contains declaration of namelist NAM_CONFn and 
+!!                             uses module MODD_CONF_n (configuration variables)
+!!      Module MODN_LUNIT_n    : contains declaration of namelist NAM_LUNITn and
+!!                             uses module MODD_LUNIT_n (Logical units)
+!!      Module MODN_DYN_n      : contains declaration of namelist NAM_DYNn and
+!!                             uses module MODD_DYN_n (control of dynamics)
+!!      Module MODN_PARAM_n    : contains declaration of namelist NAM_PARAMn and
+!!                             uses module MODD_PARAM_n (control of physical
+!!                             parameterization)
+!!      Module MODN_LBC_n      : contains declaration of namelist NAM_LBCn and 
+!!                             uses module MODD_LBC_n (lateral boundaries)
+!!      Module MODN_TURB_n     : contains declaration of namelist NAM_TURBn and 
+!!                             uses module MODD_TURB_n (turbulence scheme)
+!!      Module MODN_PARAM_RAD_n: contains declaration of namelist NAM_PARAM_RADn
+!!
+!!    REFERENCE
+!!    ---------
+!!      Book2 of documentation (routine INI_MODEL_n)
+!!
+!!
+!!    AUTHOR
+!!    ------
+!!      V. Ducrocq       * Meteo France *
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original     10/06/94
+!!      Modification 17/10/94  (Stein)  For LCORIO
+!!      Modification 20/10/94  (Stein)  For SET_GRID and NAMOUTN
+!!      Modification 26/10/94  (Stein)  Modifications of the namelist names
+!!      Modification 10/11/94  (Lafore) allocatation of tke fields
+!!      Modification 22/11/94  (Stein)  change the READ_FIELDS call ( add
+!!                                      pressure function
+!!      Modification 06/12/94  (Stein)  add the LS fields
+!!                   12/12/94  (Stein)  rename END_INI in INI_DYNAMICS
+!!      Modification 09/01/95  (Stein)  add the turbulence scheme
+!!      Modification Jan 19, 1995 (J. Cuxart) add the TKE initialization
+!!                   Jan 23, 1995 (J. Stein ) remove the condition
+!!                             LTHINSHELL=T LCARTESIAN=T => stop
+!!      Modification Feb 16, 1995 (I.Mallet) add the METRICS call and
+!!                                      change the SET_REF call (add
+!!                                      the lineic mass)
+!!      Modification Mar 10, 1995 (I. Mallet) add the COUPLING initialization
+!!                   June 29,1995 (Ph. Hereil, J. Stein) add the budget init.
+!!      Modification Sept. 1, 1995 (S. Belair) Reading of the surface variables
+!!                                 and parameters for ISBA (i.e., add a
+!!                                 CALL READ_GR_FIELD)
+!!      Modification 18/08/95     (J.P.Lafore)   time step change case
+!!                   25/09/95     (J. Cuxart and J.Stein)   add LES variables
+!!                                and the diachronic file initialization
+!!      Modification Sept 20,1995 (Lafore) coupling for the dry mass Md
+!!      Modification Sept. 12, 1995 (J.-P. Pinty) add the initialization of
+!!                                      the ECMWF radiation code
+!!      Modification Sept. 13, 1995 (J.-P. Pinty) control the allocation of the
+!!                                      arrays of MODD_GR_FIELD_n
+!!      Modification Nove. 17, 1995 (J.Stein) control of the control !! 
+!!                   March 01, 1996 (J. Stein) add the cloud fraction    
+!!                   April 03, 1996 (J. Stein) unify the ISBA and TSZ0 cases
+!!      Modification 13/12/95 (M. Georgelin) add the forcing variables in
+!!                                           the call read_field, and their
+!!                                           allocation.
+!!                   Mai   23, 1996 (J. Stein) allocate XSEA in the TSZ0 case
+!!                   June  11, 1996 (V. Masson) add XSILT and XLAKE of
+!!                                              MODD_GR_FIELD_n
+!!                   August 7, 1996 (K. Suhre)  add (re)initialization of
+!!                                              chemistry
+!!                   Octo. 11, 1996 (J. Stein ) add XSRCT and XSRCM
+!!                   October 8, 1996 (J. Cuxart, E. Sanchez) Moist LES diagnostics
+!!                                     and control on TKE initialization.
+!!      Modification 19/12/96 (J.-P. Pinty) add the ice parameterization and
+!!                                          the precipitation fields
+!!      Modification 11/01/97 (J.-P. Pinty) add the deep convection
+!!                   Nov.   1, 1996 (V. Masson) Read the vertical grid kind
+!!                   Nov.  20, 1996 (V. Masson) control of convection calling time
+!!                   July  16, 1996 (J.P.Lafore) update of EXSEG file reading
+!!                   Oct.  08, 1996 (J.P.Lafore, V.Masson)
+!!                                       MY_NAME and DAD_NAME reading and check
+!!                   Oct.  30, 1996 (J.P.Lafore) resolution ratio reading for nesting
+!!                                       and Bikhardt interpolation coef. initialization
+!!                   Nov.  22, 1996 (J.P.Lafore) allocation of LS sources for nesting
+!!                   Feb.  26, 1997 (J.P.Lafore) allocation of "surfacic" LS fields
+!!                   March 10, 1997 (J.P.Lafore) forcing only for model 1
+!!                   June  22, 1997 (J. Stein)   add the absolute pressure
+!!                   July  09, 1997 (V. Masson)  add directional z0 and SSO
+!!                   Aug.  18, 1997 (V. Masson)  consistency between storage
+!!                                               type and CCONF
+!!                   Dec.  22, 1997 (J. Stein)   add the LS field spawning
+!!                   Jan.  24, 1998 (P.Bechtold) change MODD_FRC and MODD_DEEP_CONVECTION
+!!                   Dec.  24, 1997 (V.Masson)   directional z0 parameters
+!!                   Aug.  13, 1998 (V. Ducrocq P Jabouille)   //
+!!                   Mai.  26, 1998 (J. Stein)   remove NXEND,NYEND
+!!                   Feb.   1, 1999 (J. Stein)   compute the Bikhardt
+!!                                       interpolation coeff. before the call to set_grid
+!!                   April  5, 1999 (V. Ducrocq) change the DXRATIO_ALL init.
+!!                   April  12, 1999 (J. Stein)  cleaning + INI_SPAWN_LS
+!!                   Apr.   7, 1999 (P Jabouille) store the metric coefficients
+!!                                                in modd_metrics_n
+!!                   Jui.   15,1999 (P Jabouille) split the routines in two parts
+!!                   Jan.   04,2000 (V. Masson)   removes the TSZ0 case
+!!                   Apr.   15,2000 (P Jabouille) parallelization of grid nesting
+!!                   Aug.   20,2000 (J Stein    ) tranpose XBFY
+!!                   Jui    01,2000 (F.solmon )   adapatation for patch approach
+!!                   Jun.   15,2000 (J.-P. Pinty) add C2R2 initialization
+!!                   Nov.  15,2000 (V.Masson) use of ini_modeln in prep_real_case
+!!                   Nov.  15,2000 (V.Masson) call of LES routines
+!!                   Nov.  15,2000 (V.Masson) aircraft and balloon initialization routines
+!!                   Jan.  22,2001 (D.Gazen) update_nsv set NSV_* var. for current model
+!!                   Mar.  04,2002 (V.Ducrocq) initialization to temporal series
+!!                   Mar.  15,2002 (F.Solmon) modification of ini_radiation interface
+!!                   Nov.  29,2002 (JP Pinty) add C3R5, ICE2, ICE4, ELEC
+!!                   Jan.  2004    (V.Masson) externalization of surface
+!!                   May   2006    Remove KEPS
+!!                   Apr.  2010    (M. Leriche) add pH for aqueous phase chemistry
+!!                   Jul.  2010    (M. Leriche) add Ice phase chemistry
+!!                   Oct.  2010  (J.Escobar) check if local domain not to small for NRIMX NRIMY
+!!                   Nov.  2010  (J.Escobar) PGI BUG , add SIZE(CSV) to init_ground routine
+!!                   Nov.  2009    (C. Barthe) add call to INI_ELEC_n
+!!                   Mar.  2010    (M. Chong) add small ions 
+!!                   Apr.  2011    (M. Chong) correction of RESTART (ELEC)
+!!                   June  2011  (B.Aouizerats) Prognostic aerosols
+!!                   June  2011  (P.Aumond) Drag of the vegetation  
+!!                                         + Mean fields
+!!                   July  2013  (Bosseur & Filippi) Adds Forefire
+!!                   P. Tulet      Nov 2014 accumulated moles of aqueous species that fall at the surface   
+!!                   JAn.  2015  (F. Brosse) bug in allocate XACPRAQ
+!!                   Dec 2014 (C.Lac) : For reproducibility START/RESTA
+!!                   J.Escobar : 15/09/2015 : WENO5 & JPHEXT <> 1 
+!!                   V. Masson     Feb 2015 replaces, for aerosols, cover fractions by sea, town, bare soil fractions
+!!                   J.Escobar : 19/04/2016 : Pb IOZ/NETCDF , missing OPARALLELIO=.FALSE. for PGD files
+!!                   J.Escobar : 01/06/2016 : correct check limit of NRIM versus local subdomain size IDIM
+!!                   06/2016     (G.Delautier) phasage surfex 8
+!!                   Modification    01/2016  (JP Pinty) Add LIMA
+!!                   Aug.  2016 (J.Pianezze) Add SFX_OASIS_READ_NAM function from SurfEx
+!!                   M.Leriche 2016 Chemistry
+!!                   10/2016 M.Mazoyer New KHKO output fields
+!!                      10/2016 (C.Lac) Add max values
+!!       F. Brosse   Oct.  2016 add prod/loss terms computation for chemistry       
+!!                   M.Leriche 2016 Chemistry
+!!                   M.Leriche 10/02/17 prevent negative values in LBX(Y)SVS 
+!!                   M.Leriche 01/07/2017 Add DIAG chimical surface fluxes
+!!                   09/2017 Q.Rodier add LTEND_UV_FRC
+!!                   02/2018 Q.Libois ECRAD
+!!  Philippe Wautelet: 05/2016-04/2018: new data structures and calls for I/O
+!!                   V. Vionnet : 18/07/2017 : add blowing snow scheme 
+!!                   01/18 J.Colin Add DRAG 
+!  P. Wautelet 29/01/2019: bug: add missing zero-size allocations
+!  P. Wautelet 07/02/2019: force TYPE to a known value for IO_File_add2list
+!  P. Wautelet 13/02/2019: initialize XALBUV even if no radiation (needed in CH_INTERP_JVALUES)
+!  P. Wautelet 13/02/2019: removed PPABSM and PTSTEP dummy arguments of READ_FIELD
+!  P. Wautelet 14/02/2019: remove CLUOUT/CLUOUT0 and associated variables
+!  P. Wautelet 14/02/2019: remove HINIFILE dummy argument from INI_RADIATIONS_ECMWF/ECRAD
+!!                   02/2019 C.Lac add rain fraction as an output field
+!!      Bielli S. 02/2019  Sea salt : significant sea wave height influences salt emission; 5 salt modes
+!  P. Wautelet 14/03/2019: correct ZWS when variable not present in file (set to XZWS_DEFAULT)
+!  P. Wautelet 10/04/2019: replace ABORT and STOP calls by Print_msg
+!  P. Wautelet 19/04/2019: removed unused dummy arguments and variables
+!  P. Wautelet 07/06/2019: allocate lookup tables for optical properties only when needed
+!---------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+!
+#ifdef MNH_ECRAD
+USE YOERDI,                 only: RCCO2
+#endif
+
+USE MODD_2D_FRC
+USE MODD_ADVFRC_n
+USE MODD_ADV_n
+use MODD_AEROSET,           only: POLYTAU, POLYSSA, POLYG
+USE MODD_ARGSLIST_ll,       only: LIST_ll
+USE MODD_BIKHARDT_n
+USE MODD_BLOWSNOW
+USE MODD_BLOWSNOW_n
+USE MODD_BUDGET
+USE MODD_CH_AERO_n,         only: XSOLORG,XMI
+USE MODD_CH_AEROSOL,        only: LORILAM
+USE MODD_CH_BUDGET_n
+USE MODD_CH_FLX_n,          only: XCHFLX
+USE MODD_CH_M9_n,           only:NNONZEROTERMS
+USE MODD_CH_MNHC_n,         only: LUSECHEM, LUSECHAQ, LUSECHIC, LCH_INIT_FIELD, &
+                                  LCH_CONV_LINOX, XCH_TUV_DOBNEW, LCH_PH
+USE MODD_CH_PH_n
+USE MODD_CH_PRODLOSSTOT_n
+USE MODD_CLOUD_MF_n
+USE MODD_CONF
+USE MODD_CONF_n
+USE MODD_CST
+USE MODD_CTURB
+USE MODD_CURVCOR_n
+USE MODD_DEEP_CONVECTION_n
+USE MODD_DEF_EDDY_FLUX_n   ! for VT and WT fluxes
+USE MODD_DEF_EDDYUV_FLUX_n ! FOR UV
+USE MODD_DIAG_FLAG,         only: LCHEMDIAG, CSPEC_BU_DIAG
+USE MODD_DIM_n
+USE MODD_DRAG_n
+USE MODD_DRAGTREE
+USE MODD_DUST
+use MODD_DUST_OPT_LKT,      only: NMAX_RADIUS_LKT_DUST=>NMAX_RADIUS_LKT, NMAX_SIGMA_LKT_DUST=>NMAX_SIGMA_LKT,               &
+                                  NMAX_WVL_SW_DUST=>NMAX_WVL_SW,                                                            &
+                                  XEXT_COEFF_WVL_LKT_DUST=>XEXT_COEFF_WVL_LKT, XEXT_COEFF_550_LKT_DUST=>XEXT_COEFF_550_LKT, &
+                                  XPIZA_LKT_DUST=>XPIZA_LKT, XCGA_LKT_DUST=>XCGA_LKT
+USE MODD_DYN
+USE MODD_DYN_n
+USE MODD_DYNZD
+USE MODD_DYNZD_n
+USE MODD_ELEC_n,            only: XCION_POS_FW, XCION_NEG_FW
+USE MODD_FIELD_n
+#ifdef MNH_FOREFIRE
+USE MODD_FOREFIRE
+USE MODD_FOREFIRE_n
+#endif
+USE MODD_FRC
+USE MODD_FRC_n
+USE MODD_GET_n
+USE MODD_GRID_n
+USE MODD_GRID,              only: XLONORI,XLATORI
+USE MODD_IO,                only: CIO_DIR, TFILEDATA, TFILE_DUMMY
+USE MODD_IO_SURF_MNH,       only: IO_SURF_MNH_MODEL
+USE MODD_LATZ_EDFLX
+USE MODD_LBC_n,             only: CLBCX, CLBCY
+USE MODD_LSFIELD_n
+USE MODD_LUNIT_n
+USE MODD_MEAN_FIELD
+USE MODD_MEAN_FIELD_n
+USE MODD_METRICS_n
+USE MODD_MNH_SURFEX_n
+USE MODD_NESTING,           only: CDAD_NAME, NDAD, NDT_2_WAY, NDTRATIO, NDXRATIO_ALL, NDYRATIO_ALL
+USE MODD_NSV
+USE MODD_NSV
+USE MODD_NUDGING_n,         only: LNUDGING
+USE MODD_OUT_n
+USE MODD_PARAMETERS
+USE MODD_PARAM_KAFR_n
+USE MODD_PARAM_MFSHALL_n
+USE MODD_PARAM_n
+USE MODD_PARAM_RAD_n,       only: CAER, CAOP, CLW
+USE MODD_PASPOL
+USE MODD_PASPOL_n
+USE MODD_PAST_FIELD_n
+use modd_precision,         only: LFIINT
+USE MODD_RADIATIONS_n
+USE MODD_REF
+USE MODD_REF_n
+USE MODD_RELFRC_n
+use MODD_SALT,              only: LSALT
+use MODD_SALT_OPT_LKT,      only: NMAX_RADIUS_LKT_SALT=>NMAX_RADIUS_LKT, NMAX_SIGMA_LKT_SALT=>NMAX_SIGMA_LKT,               &
+                                  NMAX_WVL_SW_SALT=>NMAX_WVL_SW,                                                            &
+                                  XEXT_COEFF_WVL_LKT_SALT=>XEXT_COEFF_WVL_LKT, XEXT_COEFF_550_LKT_SALT=>XEXT_COEFF_550_LKT, &
+                                  XPIZA_LKT_SALT=>XPIZA_LKT, XCGA_LKT_SALT=>XCGA_LKT
+USE MODD_SERIES,            only: LSERIES
+USE MODD_SHADOWS_n
+USE MODD_STAND_ATM,         only: XSTROATM, XSMLSATM, XSMLWATM, XSPOSATM, XSPOWATM
+USE MODD_TIME
+USE MODD_TIME_n
+USE MODD_TURB_CLOUD,        only: NMODEL_CLOUD, CTURBLEN_CLOUD,XCEI
+USE MODD_TURB_n
+USE MODD_VAR_ll,            only: IP
+
+USE MODE_GATHER_ll
+USE MODE_INI_ONE_WAY_n
+USE MODE_IO
+USE MODE_IO_FIELD_READ,     only: IO_Field_read
+USE MODE_IO_FILE,           only: IO_File_open
+USE MODE_IO_MANAGE_STRUCT,  only: IO_File_add2list
+USE MODE_ll
+USE MODE_MODELN_HANDLER
+USE MODE_MPPDB
+USE MODE_MSG
+USE MODE_SPLITTINGZ_ll,     only: GET_DIM_EXTZ_ll
+USE MODE_TYPE_ZDIFFU
+
+USE MODI_CH_AER_MOD_INIT
+USE MODI_CH_INIT_BUDGET_n
+USE MODI_CH_INIT_FIELD_n
+USE MODI_CH_INIT_JVALUES
+USE MODI_CH_INIT_PRODLOSSTOT_n
+USE MODI_GET_SIZEX_LB
+USE MODI_GET_SIZEY_LB
+USE MODI_INI_AEROSET1
+USE MODI_INI_AEROSET2
+USE MODI_INI_AEROSET3
+USE MODI_INI_AEROSET4
+USE MODI_INI_AEROSET5
+USE MODI_INI_AEROSET6
+USE MODI_INI_AIRCRAFT_BALLOON
+USE MODI_INI_AIRCRAFT_BALLOON
+USE MODI_INI_BIKHARDT_n
+USE MODI_INI_BUDGET
+USE MODI_INI_CPL
+USE MODI_INI_DEEP_CONVECTION
+USE MODI_INI_DRAG
+USE MODI_INI_DYNAMICS
+USE MODI_INI_ELEC_n
+USE MODI_INI_LES_N
+USE MODI_INI_LG
+USE MODI_INI_LW_SETUP
+USE MODI_INI_MICRO_n
+USE MODI_INI_POSPROFILER_n
+USE MODI_INI_RADIATIONS
+USE MODI_INI_RADIATIONS_ECMWF
+USE MODI_INI_RADIATIONS_ECRAD
+USE MODI_INI_SERIES_N
+USE MODI_INI_SPAWN_LS_n
+USE MODI_INI_SURF_RAD
+USE MODI_INI_SURFSTATION_n
+USE MODI_INI_SW_SETUP
+USE MODI_INIT_AEROSOL_PROPERTIES
+#ifdef MNH_FOREFIRE
+USE MODI_INIT_FOREFIRE_n
+#endif
+USE MODI_INIT_GROUND_PARAM_n
+USE MODI_INI_TKE_EPS
+USE MODI_METRICS
+USE MODI_MNHGET_SURF_PARAM_n
+USE MODI_MNHREAD_ZS_DUMMY_n
+USE MODI_READ_FIELD
+USE MODI_SET_DIRCOS
+USE MODI_SET_GRID
+USE MODI_SET_REF
+#ifdef CPLOASIS
+USE MODI_SFX_OASIS_READ_NAM
+#endif
+USE MODI_SUNPOS_n
+USE MODI_SURF_SOLAR_GEOM
+USE MODI_UPDATE_METRICS
+USE MODI_UPDATE_NSV
+!
+IMPLICIT NONE
+!
+!*       0.1   declarations of arguments
+!
+!
+INTEGER,          INTENT(IN)   :: KMI       ! Model Index
+TYPE(TFILEDATA),  INTENT(IN)   :: TPINIFILE ! Initial file
+!
+!*       0.2   declarations of local variables
+!
+REAL, PARAMETER :: NALBUV_DEFAULT = 0.01 ! Arbitrary low value for XALBUV
+!
+INTEGER             :: JSV     ! Loop index
+INTEGER             :: IRESP   ! Return code of FM routines
+INTEGER             :: ILUOUT  ! Logical unit number of output-listing
+CHARACTER(LEN=28)   :: YNAME
+INTEGER             :: IIU     ! Upper dimension in x direction (local)
+INTEGER             :: IJU     ! Upper dimension in y direction (local)
+INTEGER             :: IIU_ll  ! Upper dimension in x direction (global)
+INTEGER             :: IJU_ll  ! Upper dimension in y direction (global)
+INTEGER             :: IKU     ! Upper dimension in z direction
+REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZJ ! Jacobian
+LOGICAL             :: GINIDCONV ! logical switch for the deep convection
+                               ! initialization
+LOGICAL             :: GINIRAD ! logical switch for the radiation
+                               ! initialization
+!
+!
+TYPE(LIST_ll), POINTER :: TZINITHALO2D_ll ! pointer for the list of 2D fields
+                                      !  which must be communicated in INIT
+TYPE(LIST_ll), POINTER :: TZINITHALO3D_ll ! pointer for the list of 3D fields
+                                      !  which must be communicated in INIT
+!
+INTEGER :: IISIZEXF,IJSIZEXF,IISIZEXFU,IJSIZEXFU     ! dimensions of the
+INTEGER :: IISIZEX4,IJSIZEX4,IISIZEX2,IJSIZEX2       ! West-east LB arrays
+INTEGER :: IISIZEYF,IJSIZEYF,IISIZEYFV,IJSIZEYFV     ! dimensions of the
+INTEGER :: IISIZEY4,IJSIZEY4,IISIZEY2,IJSIZEY2       ! North-south LB arrays
+INTEGER :: IINFO_ll  ! Return code of //routines
+INTEGER :: IIY,IJY
+INTEGER :: IIU_B,IJU_B
+INTEGER :: IIU_SXP2_YP1_Z_ll,IJU_SXP2_YP1_Z_ll,IKU_SXP2_YP1_Z_ll
+!
+REAL, DIMENSION(:,:),   ALLOCATABLE :: ZCO2   ! CO2 concentration near the surface
+REAL, DIMENSION(:,:),   ALLOCATABLE :: ZSEA   ! sea fraction
+REAL, DIMENSION(:,:),   ALLOCATABLE :: ZTOWN  ! town fraction
+REAL, DIMENSION(:,:),   ALLOCATABLE :: ZBARE  ! bare soil fraction
+!
+REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZDIR_ALB ! direct albedo
+REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZSCA_ALB ! diffuse albedo
+REAL, DIMENSION(:,:,:),   ALLOCATABLE :: ZEMIS    ! emissivity
+REAL, DIMENSION(:,:),   ALLOCATABLE :: ZTSRAD   ! surface temperature
+!
+!
+INTEGER, DIMENSION(:,:),ALLOCATABLE :: IINDEX   ! indices of non-zero terms
+INTEGER, DIMENSION(:),ALLOCATABLE   :: IIND
+INTEGER                             :: JM
+!
+!------------------------------------------
+! Dummy pointers needed to correct an ifort Bug
+REAL, DIMENSION(:), POINTER :: DPTR_XZHAT
+REAL, DIMENSION(:), POINTER :: DPTR_XBMX1,DPTR_XBMX2,DPTR_XBMX3,DPTR_XBMX4
+REAL, DIMENSION(:), POINTER :: DPTR_XBMY1,DPTR_XBMY2,DPTR_XBMY3,DPTR_XBMY4
+REAL, DIMENSION(:), POINTER :: DPTR_XBFX1,DPTR_XBFX2,DPTR_XBFX3,DPTR_XBFX4
+REAL, DIMENSION(:), POINTER :: DPTR_XBFY1,DPTR_XBFY2,DPTR_XBFY3,DPTR_XBFY4
+CHARACTER(LEN=4), DIMENSION(:), POINTER :: DPTR_CLBCX,DPTR_CLBCY
+INTEGER, DIMENSION(:,:,:), POINTER :: DPTR_NKLIN_LBXU,DPTR_NKLIN_LBYU,DPTR_NKLIN_LBXV,DPTR_NKLIN_LBYV
+INTEGER, DIMENSION(:,:,:), POINTER :: DPTR_NKLIN_LBXW,DPTR_NKLIN_LBYW,DPTR_NKLIN_LBXM,DPTR_NKLIN_LBYM
+REAL, DIMENSION(:,:,:), POINTER :: DPTR_XCOEFLIN_LBXU,DPTR_XCOEFLIN_LBYU
+REAL, DIMENSION(:,:,:), POINTER :: DPTR_XCOEFLIN_LBXV,DPTR_XCOEFLIN_LBYV
+REAL, DIMENSION(:,:,:), POINTER :: DPTR_XCOEFLIN_LBXW,DPTR_XCOEFLIN_LBYW
+REAL, DIMENSION(:,:,:), POINTER :: DPTR_XCOEFLIN_LBXM,DPTR_XCOEFLIN_LBYM
+REAL, DIMENSION(:,:,:),   POINTER :: DPTR_XLBXUM,DPTR_XLBYUM,DPTR_XLBXVM,DPTR_XLBYVM
+REAL, DIMENSION(:,:,:),   POINTER :: DPTR_XLBXWM,DPTR_XLBYWM,DPTR_XLBXTHM,DPTR_XLBYTHM
+REAL, DIMENSION(:,:,:),   POINTER :: DPTR_XLBXTKEM,DPTR_XLBYTKEM
+REAL, DIMENSION(:,:,:,:),   POINTER :: DPTR_XLBXSVM,DPTR_XLBYSVM                
+REAL, DIMENSION(:,:,:,:), POINTER :: DPTR_XLBXRM,DPTR_XLBYRM
+REAL, DIMENSION(:,:,:),   POINTER ::  DPTR_XZZ
+REAL, DIMENSION(:,:,:), POINTER ::   DPTR_XLSUM,DPTR_XLSVM,DPTR_XLSWM,DPTR_XLSTHM,DPTR_XLSRVM
+REAL, DIMENSION(:,:,:), POINTER ::   DPTR_XLSUS,DPTR_XLSVS,DPTR_XLSWS,DPTR_XLSTHS,DPTR_XLSRVS
+REAL, DIMENSION(:,:),   POINTER ::   DPTR_XLSZWSM,DPTR_XLSZWSS
+!
+INTEGER                         ::  IIB,IJB,IIE,IJE,IDIMX,IDIMY,IMI
+!
+!-------------------------------------------------------------------------------
+!
+!*       0.    PROLOGUE
+!              --------
+! Compute relaxation coefficients without changing INI_DYNAMICS nor RELAXDEF
+!
+IF (CCLOUD == 'LIMA') THEN
+  LHORELAX_SVC1R3=LHORELAX_SVLIMA
+END IF
+!
+!
+NULLIFY(TZINITHALO2D_ll)
+NULLIFY(TZINITHALO3D_ll)
+!
+!*       1.    RETRIEVE LOGICAL UNIT NUMBER
+!              ----------------------------
+!
+ILUOUT = TLUOUT%NLU
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.   END OF READING
+!             --------------
+!*       2.1  Read number of forcing fields
+!
+IF (LFORCING) THEN ! Retrieve the number of time-dependent forcings.
+  CALL IO_Field_read(TPINIFILE,'FRC',NFRC,IRESP)
+  IF ( (IRESP /= 0) .OR. (NFRC <=0) ) THEN
+    WRITE(ILUOUT,'(A/A)') &
+     "INI_MODEL_n ERROR: you want to read forcing variables from FMfile", &
+     "                   but no fields have been found by IO_Field_read"
+!callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','INI_MODEL_n','')
+  END IF
+END IF
+!
+! Modif PP for time evolving adv forcing
+  IF ( L2D_ADV_FRC ) THEN ! Retrieve the number of time-dependent forcings.
+    WRITE(ILUOUT,FMT=*) "INI_MODEL_n ENTER ADV_FORCING"
+    CALL IO_Field_read(TPINIFILE,'NADVFRC1',NADVFRC,IRESP)
+    IF ( (IRESP /= 0) .OR. (NADVFRC <=0) ) THEN
+      WRITE(ILUOUT,'(A/A)') &
+      "INI_MODELn ERROR: you want to read forcing ADV variables from FMfile", &
+      "                   but no fields have been found by IO_Field_read"
+    !callabortstop
+      CALL PRINT_MSG(NVERB_FATAL,'GEN','INI_MODEL_n','')
+    END IF
+    WRITE(ILUOUT,*) 'NADVFRC = ', NADVFRC
+END IF
+!
+IF ( L2D_REL_FRC ) THEN ! Retrieve the number of time-dependent forcings.
+    WRITE(ILUOUT,FMT=*) "INI_MODEL_n ENTER REL_FORCING"
+    CALL IO_Field_read(TPINIFILE,'NRELFRC1',NRELFRC,IRESP)
+    IF ( (IRESP /= 0) .OR. (NRELFRC <=0) ) THEN
+      WRITE(ILUOUT,'(A/A)') &
+      "INI_MODELn ERROR: you want to read forcing REL variables from FMfile", &
+      "                   but no fields have been found by IO_Field_read"
+    !callabortstop
+      CALL PRINT_MSG(NVERB_FATAL,'GEN','INI_MODEL_n','')
+    END IF
+    WRITE(ILUOUT,*) 'NRELFRC = ', NRELFRC
+END IF
+!*       2.2  Checks the position of vertical absorbing layer
+!
+IKU=NKMAX+2*JPVEXT
+!
+ALLOCATE(XZHAT(IKU))
+CALL IO_Field_read(TPINIFILE,'ZHAT',XZHAT)
+CALL IO_Field_read(TPINIFILE,'ZTOP',XZTOP)
+IF (XALZBOT>=XZHAT(IKU) .AND. LVE_RELAX) THEN
+  WRITE(ILUOUT,FMT=*) "INI_MODEL_n ERROR: you want to use vertical relaxation"
+  WRITE(ILUOUT,FMT=*) "                  but bottom of layer XALZBOT(",XALZBOT,")"
+  WRITE(ILUOUT,FMT=*) "                  is upper than model top    (",XZHAT(IKU),")"
+!callabortstop
+  CALL PRINT_MSG(NVERB_FATAL,'GEN','INI_MODEL_n','')
+END IF
+IF (LVE_RELAX) THEN
+ IF (XALZBOT>=XZHAT(IKU-4) ) THEN
+  WRITE(ILUOUT,FMT=*) "INI_MODEL_n WARNING: you want to use vertical relaxation"
+  WRITE(ILUOUT,FMT=*) "                    but the layer defined by XALZBOT(",XALZBOT,")"
+  WRITE(ILUOUT,FMT=*) "                    contains less than 5 model levels"
+ END IF
+END IF
+DEALLOCATE(XZHAT)
+!
+!*       2.3  Compute sizes of arrays of the extended sub-domain
+!
+CALL GET_DIM_EXT_ll('B',IIU,IJU)
+IIU_ll=NIMAX_ll + 2 * JPHEXT
+IJU_ll=NJMAX_ll + 2 * JPHEXT
+! initialize NIMAX and NJMAX for not updated versions regarding the parallelism
+! spawning,...
+CALL GET_DIM_PHYS_ll('B',NIMAX,NJMAX)
+!
+CALL GET_INDICE_ll( IIB,IJB,IIE,IJE)
+IDIMX = IIE - IIB + 1
+IDIMY = IJE - IJB + 1
+!
+NRR=0
+NRRL=0
+NRRI=0
+IF (CGETRVT /= 'SKIP' ) THEN
+  NRR = NRR+1
+  IDX_RVT = NRR
+END IF
+IF (CGETRCT /= 'SKIP' ) THEN
+  NRR = NRR+1
+  NRRL = NRRL+1
+  IDX_RCT = NRR
+END IF
+IF (CGETRRT /= 'SKIP' ) THEN
+  NRR = NRR+1
+  NRRL = NRRL+1
+  IDX_RRT = NRR
+END IF
+IF (CGETRIT /= 'SKIP' ) THEN
+  NRR = NRR+1
+  NRRI = NRRI+1
+  IDX_RIT = NRR
+END IF
+IF (CGETRST /= 'SKIP' ) THEN
+  NRR = NRR+1
+  NRRI = NRRI+1
+  IDX_RST = NRR
+END IF
+IF (CGETRGT /= 'SKIP' ) THEN
+  NRR = NRR+1
+  NRRI = NRRI+1
+  IDX_RGT = NRR
+END IF
+IF (CGETRHT /= 'SKIP' ) THEN
+  NRR = NRR+1
+  NRRI = NRRI+1
+  IDX_RHT = NRR
+END IF
+IF (NVERB >= 5) THEN
+  WRITE (UNIT=ILUOUT,FMT='("THERE ARE ",I2," WATER VARIABLES")') NRR
+  WRITE (UNIT=ILUOUT,FMT='("THERE ARE ",I2," LIQUID VARIABLES")') NRRL
+  WRITE (UNIT=ILUOUT,FMT='("THERE ARE ",I2," SOLID VARIABLES")') NRRI
+END IF
+!
+!*       2.4  Update NSV and floating indices for the current model
+!
+! 
+CALL UPDATE_NSV(KMI) 
+!
+!-------------------------------------------------------------------------------
+!
+!*       3.    ALLOCATE  MEMORY
+!              -----------------
+!
+!*       3.1   Module MODD_FIELD_n
+!
+IF (LMEAN_FIELD) THEN
+!
+  MEAN_COUNT = 0
+!
+  ALLOCATE(XUM_MEAN(IIU,IJU,IKU))      ; XUM_MEAN  = 0.0
+  ALLOCATE(XVM_MEAN(IIU,IJU,IKU))      ; XVM_MEAN  = 0.0
+  ALLOCATE(XWM_MEAN(IIU,IJU,IKU))      ; XWM_MEAN  = 0.0
+  ALLOCATE(XTHM_MEAN(IIU,IJU,IKU))     ; XTHM_MEAN = 0.0
+  ALLOCATE(XTEMPM_MEAN(IIU,IJU,IKU))   ; XTEMPM_MEAN = 0.0
+  IF (CTURB/='NONE') THEN
+    ALLOCATE(XTKEM_MEAN(IIU,IJU,IKU))
+    XTKEM_MEAN = 0.0
+  ELSE
+    ALLOCATE(XTKEM_MEAN(0,0,0))
+  END IF
+  ALLOCATE(XPABSM_MEAN(IIU,IJU,IKU))   ; XPABSM_MEAN = 0.0
+!
+  ALLOCATE(XU2_MEAN(IIU,IJU,IKU))      ; XU2_MEAN  = 0.0
+  ALLOCATE(XV2_MEAN(IIU,IJU,IKU))      ; XV2_MEAN  = 0.0
+  ALLOCATE(XW2_MEAN(IIU,IJU,IKU))      ; XW2_MEAN  = 0.0
+  ALLOCATE(XTH2_MEAN(IIU,IJU,IKU))     ; XTH2_MEAN = 0.0
+  ALLOCATE(XTEMP2_MEAN(IIU,IJU,IKU))   ; XTEMP2_MEAN = 0.0
+  ALLOCATE(XPABS2_MEAN(IIU,IJU,IKU))   ; XPABS2_MEAN = 0.0
+!
+  ALLOCATE(XUM_MAX(IIU,IJU,IKU))      ; XUM_MAX  = -1.E20
+  ALLOCATE(XVM_MAX(IIU,IJU,IKU))      ; XVM_MAX  = -1.E20
+  ALLOCATE(XWM_MAX(IIU,IJU,IKU))      ; XWM_MAX  = -1.E20
+  ALLOCATE(XTHM_MAX(IIU,IJU,IKU))     ; XTHM_MAX = 0.0
+  ALLOCATE(XTEMPM_MAX(IIU,IJU,IKU))   ; XTEMPM_MAX = 0.0
+  IF (CTURB/='NONE') THEN
+    ALLOCATE(XTKEM_MAX(IIU,IJU,IKU))
+    XTKEM_MAX = 0.0
+  ELSE
+    ALLOCATE(XTKEM_MAX(0,0,0))
+  END IF
+  ALLOCATE(XPABSM_MAX(IIU,IJU,IKU))   ; XPABSM_MAX = 0.0
+ELSE
+  ALLOCATE(XUM_MEAN(0,0,0))
+  ALLOCATE(XVM_MEAN(0,0,0))
+  ALLOCATE(XWM_MEAN(0,0,0))
+  ALLOCATE(XTHM_MEAN(0,0,0))
+  ALLOCATE(XTEMPM_MEAN(0,0,0))
+  ALLOCATE(XTKEM_MEAN(0,0,0))
+  ALLOCATE(XPABSM_MEAN(0,0,0))
+!
+  ALLOCATE(XU2_MEAN(0,0,0))
+  ALLOCATE(XV2_MEAN(0,0,0))
+  ALLOCATE(XW2_MEAN(0,0,0))
+  ALLOCATE(XTH2_MEAN(0,0,0))
+  ALLOCATE(XTEMP2_MEAN(0,0,0))
+  ALLOCATE(XPABS2_MEAN(0,0,0))
+!
+  ALLOCATE(XUM_MAX(0,0,0))
+  ALLOCATE(XVM_MAX(0,0,0))
+  ALLOCATE(XWM_MAX(0,0,0))
+  ALLOCATE(XTHM_MAX(0,0,0))
+  ALLOCATE(XTEMPM_MAX(0,0,0))
+  ALLOCATE(XTKEM_MAX(0,0,0))
+  ALLOCATE(XPABSM_MAX(0,0,0))
+END IF
+!
+IF ((CUVW_ADV_SCHEME(1:3)=='CEN') .AND. (CTEMP_SCHEME == 'LEFR') ) THEN
+  ALLOCATE(XUM(IIU,IJU,IKU))
+  ALLOCATE(XVM(IIU,IJU,IKU))
+  ALLOCATE(XWM(IIU,IJU,IKU))
+  ALLOCATE(XDUM(IIU,IJU,IKU))
+  ALLOCATE(XDVM(IIU,IJU,IKU))
+  ALLOCATE(XDWM(IIU,IJU,IKU))
+  IF (CCONF == 'START') THEN
+    XUM  = 0.0
+    XVM  = 0.0
+    XWM  = 0.0
+    XDUM  = 0.0
+    XDVM  = 0.0
+    XDWM  = 0.0
+  END IF
+ELSE
+  ALLOCATE(XUM(0,0,0))
+  ALLOCATE(XVM(0,0,0))
+  ALLOCATE(XWM(0,0,0))
+  ALLOCATE(XDUM(0,0,0))
+  ALLOCATE(XDVM(0,0,0))
+  ALLOCATE(XDWM(0,0,0))
+END IF
+!
+ALLOCATE(XUT(IIU,IJU,IKU))      ; XUT  = 0.0
+ALLOCATE(XVT(IIU,IJU,IKU))      ; XVT  = 0.0
+ALLOCATE(XWT(IIU,IJU,IKU))      ; XWT  = 0.0
+ALLOCATE(XTHT(IIU,IJU,IKU))     ; XTHT = 0.0
+ALLOCATE(XRUS(IIU,IJU,IKU))     ; XRUS = 0.0
+ALLOCATE(XRVS(IIU,IJU,IKU))     ; XRVS = 0.0
+ALLOCATE(XRWS(IIU,IJU,IKU))     ; XRWS = 0.0
+ALLOCATE(XRUS_PRES(IIU,IJU,IKU)); XRUS_PRES = 0.0
+ALLOCATE(XRVS_PRES(IIU,IJU,IKU)); XRVS_PRES = 0.0
+ALLOCATE(XRWS_PRES(IIU,IJU,IKU)); XRWS_PRES = 0.0
+ALLOCATE(XRTHS(IIU,IJU,IKU))    ; XRTHS = 0.0
+!$acc enter data copyin(XRTHS)
+ALLOCATE(XRTHS_CLD(IIU,IJU,IKU)); XRTHS_CLD = 0.0
+IF (CTURB /= 'NONE') THEN
+  ALLOCATE(XTKET(IIU,IJU,IKU))
+  ALLOCATE(XRTKES(IIU,IJU,IKU))
+  ALLOCATE(XRTKEMS(IIU,IJU,IKU)); XRTKEMS = 0.0
+  ALLOCATE(XWTHVMF(IIU,IJU,IKU))
+  ALLOCATE(XDYP(IIU,IJU,IKU))
+  ALLOCATE(XTHP(IIU,IJU,IKU))
+  ALLOCATE(XTR(IIU,IJU,IKU))
+  ALLOCATE(XDISS(IIU,IJU,IKU))
+  ALLOCATE(XLEM(IIU,IJU,IKU))
+  XTKEMIN=XKEMIN
+  XCED   =XCEDIS
+ELSE
+  ALLOCATE(XTKET(0,0,0))
+  ALLOCATE(XRTKES(0,0,0))
+  ALLOCATE(XRTKEMS(0,0,0))
+  ALLOCATE(XWTHVMF(0,0,0))
+  ALLOCATE(XDYP(0,0,0))
+  ALLOCATE(XTHP(0,0,0))
+  ALLOCATE(XTR(0,0,0))
+  ALLOCATE(XDISS(0,0,0))
+  ALLOCATE(XLEM(0,0,0))
+END IF
+IF (CTOM == 'TM06') THEN
+  ALLOCATE(XBL_DEPTH(IIU,IJU))
+ELSE
+  ALLOCATE(XBL_DEPTH(0,0))
+END IF
+IF (LRMC01) THEN
+  ALLOCATE(XSBL_DEPTH(IIU,IJU))
+ELSE
+  ALLOCATE(XSBL_DEPTH(0,0))
+END IF
+!
+ALLOCATE(XPABSM(IIU,IJU,IKU)) ; XPABSM = 0.0
+ALLOCATE(XPABST(IIU,IJU,IKU)) ; XPABST = 0.0
+!
+ALLOCATE(XRT(IIU,IJU,IKU,NRR)) ;     XRT = 0.0
+ALLOCATE(XRRS(IIU,IJU,IKU,NRR)) ;    XRRS = 0.0
+ALLOCATE(XRRS_CLD(IIU,IJU,IKU,NRR)); XRRS_CLD = 0.0
+!
+IF (CTURB /= 'NONE' .AND. NRR>1) THEN
+  ALLOCATE(XSRCT(IIU,IJU,IKU))
+  ALLOCATE(XSIGS(IIU,IJU,IKU))
+ELSE
+  ALLOCATE(XSRCT(0,0,0))
+  ALLOCATE(XSIGS(0,0,0))
+END IF
+!
+IF (NRR>1) THEN
+  ALLOCATE(XCLDFR(IIU,IJU,IKU))
+  ALLOCATE(XRAINFR(IIU,IJU,IKU))
+ELSE
+  ALLOCATE(XCLDFR(0,0,0))
+  ALLOCATE(XRAINFR(0,0,0))
+END IF
+!
+ALLOCATE(XSVT(IIU,IJU,IKU,NSV)) ;     XSVT  = 0.
+ALLOCATE(XRSVS(IIU,IJU,IKU,NSV));     XRSVS = 0.
+ALLOCATE(XRSVS_CLD(IIU,IJU,IKU,NSV)); XRSVS_CLD = 0.0
+ALLOCATE(XZWS(IIU,IJU)) ;             XZWS(:,:) = XZWS_DEFAULT
+!
+IF (LPASPOL) THEN
+  ALLOCATE( XATC(IIU,IJU,IKU,NSV_PP) )
+  XATC = 0.
+ELSE
+  ALLOCATE( XATC(0,0,0,0))
+END IF
+!
+IF(LBLOWSNOW) THEN
+  ALLOCATE(XSNWCANO(IIU,IJU,NBLOWSNOW_2D))
+  ALLOCATE(XRSNWCANOS(IIU,IJU,NBLOWSNOW_2D))
+  XSNWCANO(:,:,:) = 0.0
+  XRSNWCANOS(:,:,:) = 0.0
+ELSE
+  ALLOCATE(XSNWCANO(0,0,0))
+  ALLOCATE(XRSNWCANOS(0,0,0))
+END IF
+!
+!*       3.2   Module MODD_GRID_n and MODD_METRICS_n
+!
+IF (LCARTESIAN) THEN
+  ALLOCATE(XLON(0,0))
+  ALLOCATE(XLAT(0,0))
+  ALLOCATE(XMAP(0,0))
+ELSE
+  ALLOCATE(XLON(IIU,IJU))
+  ALLOCATE(XLAT(IIU,IJU))
+  ALLOCATE(XMAP(IIU,IJU))
+END IF
+ALLOCATE(XXHAT(IIU))
+ALLOCATE(XDXHAT(IIU))
+ALLOCATE(XYHAT(IJU))
+ALLOCATE(XDYHAT(IJU))
+ALLOCATE(XZS(IIU,IJU))
+ALLOCATE(XZSMT(IIU,IJU))
+ALLOCATE(XZZ(IIU,IJU,IKU))
+ALLOCATE(XZHAT(IKU))
+ALLOCATE(XDIRCOSZW(IIU,IJU))
+ALLOCATE(XDIRCOSXW(IIU,IJU))
+ALLOCATE(XDIRCOSYW(IIU,IJU))
+ALLOCATE(XCOSSLOPE(IIU,IJU))
+ALLOCATE(XSINSLOPE(IIU,IJU))
+!
+ALLOCATE(XDXX(IIU,IJU,IKU))
+ALLOCATE(XDYY(IIU,IJU,IKU))
+ALLOCATE(XDZX(IIU,IJU,IKU))
+ALLOCATE(XDZY(IIU,IJU,IKU))
+ALLOCATE(XDZZ(IIU,IJU,IKU))
+!$acc enter data create(XDXX,XDYY,XDZZ,XDZX,XDZY)
+!
+!*       3.3   Modules MODD_REF and  MODD_REF_n
+!
+IF (KMI == 1) THEN
+  ALLOCATE(XRHODREFZ(IKU),XTHVREFZ(IKU))
+ELSE
+  !Do not allocate XRHODREFZ and XTHVREFZ because they are the same on all grids (not 'n' variables)
+END IF
+ALLOCATE(XRHODREF(IIU,IJU,IKU))
+ALLOCATE(XTHVREF(IIU,IJU,IKU))
+ALLOCATE(XEXNREF(IIU,IJU,IKU))
+ALLOCATE(XRHODJ(IIU,IJU,IKU))
+!$acc enter data create(XRHODJ)
+IF (CEQNSYS=='DUR' .AND. LUSERV) THEN
+  ALLOCATE(XRVREF(IIU,IJU,IKU))
+ELSE
+  ALLOCATE(XRVREF(0,0,0))
+END IF
+!
+!*       3.4   Module MODD_CURVCOR_n
+!
+IF (LTHINSHELL) THEN
+  ALLOCATE(XCORIOX(0,0))
+  ALLOCATE(XCORIOY(0,0))
+ELSE
+  ALLOCATE(XCORIOX(IIU,IJU))
+  ALLOCATE(XCORIOY(IIU,IJU))
+END IF
+  ALLOCATE(XCORIOZ(IIU,IJU))
+IF (LCARTESIAN) THEN
+  ALLOCATE(XCURVX(0,0))
+  ALLOCATE(XCURVY(0,0))
+ELSE
+  ALLOCATE(XCURVX(IIU,IJU))
+  ALLOCATE(XCURVY(IIU,IJU))
+END IF
+!
+!*       3.5   Module MODD_DYN_n
+!
+CALL GET_DIM_EXT_ll('Y',IIY,IJY)
+IF (L2D) THEN
+  ALLOCATE(XBFY(IIY,IJY,IKU))
+ELSE
+  ALLOCATE(XBFY(IJY,IIY,IKU)) ! transposition needed by the optimisation of the
+                              ! FFT solver
+END IF
+CALL GET_DIM_EXT_ll('B',IIU_B,IJU_B)
+ALLOCATE(XBFB(IIU_B,IJU_B,IKU))
+ALLOCATE(XAF_ZS(IIU_B,IJU_B,IKU))
+ALLOCATE(XBF_ZS(IIU_B,IJU_B,IKU))
+ALLOCATE(XCF_ZS(IIU_B,IJU_B,IKU))
+ALLOCATE(XDXATH_ZS(IIU_B,IJU_B))
+ALLOCATE(XDYATH_ZS(IIU_B,IJU_B))
+ALLOCATE(XRHO_ZS(IIU_B,IJU_B,IKU))
+ALLOCATE(XA_K(IKU))
+ALLOCATE(XB_K(IKU))
+ALLOCATE(XC_K(IKU))
+ALLOCATE(XD_K(IKU))
+
+CALL GET_DIM_EXTZ_ll('SXP2_YP1_Z',IIU_SXP2_YP1_Z_ll,IJU_SXP2_YP1_Z_ll,IKU_SXP2_YP1_Z_ll)
+ALLOCATE(XBF_SXP2_YP1_Z(IIU_SXP2_YP1_Z_ll,IJU_SXP2_YP1_Z_ll,IKU_SXP2_YP1_Z_ll))
+ALLOCATE(XAF(IKU),XCF(IKU))
+ALLOCATE(XTRIGSX(3*IIU_ll))
+ALLOCATE(XTRIGSY(3*IJU_ll))
+ALLOCATE(XRHOM(IKU))
+ALLOCATE(XALK(IKU))
+ALLOCATE(XALKW(IKU))
+ALLOCATE(XALKBAS(IKU))
+ALLOCATE(XALKWBAS(IKU))
+!
+IF ( LHORELAX_UVWTH .OR. LHORELAX_RV .OR.                                  &
+     LHORELAX_RC .OR. LHORELAX_RR .OR. LHORELAX_RI  .OR. LHORELAX_RS  .OR. &
+     LHORELAX_RG .OR. LHORELAX_RH .OR. LHORELAX_TKE .OR.                   &
+     ANY(LHORELAX_SV) ) THEN
+  ALLOCATE(XKURELAX(IIU,IJU))
+  ALLOCATE(XKVRELAX(IIU,IJU))
+  ALLOCATE(XKWRELAX(IIU,IJU))
+  ALLOCATE(LMASK_RELAX(IIU,IJU))
+ELSE
+  ALLOCATE(XKURELAX(0,0))
+  ALLOCATE(XKVRELAX(0,0))
+  ALLOCATE(XKWRELAX(0,0))
+  ALLOCATE(LMASK_RELAX(0,0))
+END IF
+!
+! Additional fields for truly horizontal diffusion (Module MODD_DYNZD$n)
+IF (LZDIFFU) THEN
+  CALL INIT_TYPE_ZDIFFU_HALO2(XZDIFFU_HALO2)
+ELSE
+  CALL INIT_TYPE_ZDIFFU_HALO2(XZDIFFU_HALO2,0)
+ENDIF
+!
+!*       3.6   Larger Scale variables (Module MODD_LSFIELD$n)
+!
+!
+! upper relaxation part
+!
+ALLOCATE(XLSUM(IIU,IJU,IKU))    ; XLSUM  = 0.0
+ALLOCATE(XLSVM(IIU,IJU,IKU))    ; XLSVM  = 0.0
+ALLOCATE(XLSWM(IIU,IJU,IKU))    ; XLSWM  = 0.0
+ALLOCATE(XLSTHM(IIU,IJU,IKU))   ; XLSTHM = 0.0
+IF ( NRR > 0 ) THEN
+  ALLOCATE(XLSRVM(IIU,IJU,IKU)) ; XLSRVM = 0.0
+ELSE
+  ALLOCATE(XLSRVM(0,0,0))
+END IF
+ALLOCATE(XLSZWSM(IIU,IJU)) ; XLSZWSM = -1.
+!
+!  lbc part
+!
+IF ( L1D) THEN                         ! 1D case
+!
+  NSIZELBX_ll=0
+  NSIZELBXU_ll=0
+  NSIZELBY_ll=0
+  NSIZELBYV_ll=0
+  NSIZELBXTKE_ll=0
+  NSIZELBXR_ll=0
+  NSIZELBXSV_ll=0
+  NSIZELBYTKE_ll=0
+  NSIZELBYR_ll=0
+  NSIZELBYSV_ll=0
+  ALLOCATE(XLBXUM(0,0,0))
+  ALLOCATE(XLBYUM(0,0,0))
+  ALLOCATE(XLBXVM(0,0,0))
+  ALLOCATE(XLBYVM(0,0,0))
+  ALLOCATE(XLBXWM(0,0,0))
+  ALLOCATE(XLBYWM(0,0,0))
+  ALLOCATE(XLBXTHM(0,0,0))
+  ALLOCATE(XLBYTHM(0,0,0))
+  ALLOCATE(XLBXTKEM(0,0,0))
+  ALLOCATE(XLBYTKEM(0,0,0))
+  ALLOCATE(XLBXRM(0,0,0,0))
+  ALLOCATE(XLBYRM(0,0,0,0))
+  ALLOCATE(XLBXSVM(0,0,0,0))
+  ALLOCATE(XLBYSVM(0,0,0,0))
+!
+ELSEIF( L2D ) THEN                         ! 2D case
+!
+  NSIZELBY_ll=0
+  NSIZELBYV_ll=0
+  NSIZELBYTKE_ll=0
+  NSIZELBYR_ll=0
+  NSIZELBYSV_ll=0
+  ALLOCATE(XLBYUM(0,0,0))
+  ALLOCATE(XLBYVM(0,0,0))
+  ALLOCATE(XLBYWM(0,0,0))
+  ALLOCATE(XLBYTHM(0,0,0))
+  ALLOCATE(XLBYTKEM(0,0,0))
+  ALLOCATE(XLBYRM(0,0,0,0))
+  ALLOCATE(XLBYSVM(0,0,0,0))
+!
+  CALL GET_SIZEX_LB(NIMAX_ll,NJMAX_ll,NRIMX,  &
+       IISIZEXF,IJSIZEXF,IISIZEXFU,IJSIZEXFU, &
+       IISIZEX4,IJSIZEX4,IISIZEX2,IJSIZEX2)
+!
+  IF ( LHORELAX_UVWTH ) THEN
+    NSIZELBX_ll=2*NRIMX+2*JPHEXT
+    NSIZELBXU_ll=2*NRIMX+2*JPHEXT
+    ALLOCATE(XLBXUM(IISIZEXFU,IJSIZEXFU,IKU))
+    ALLOCATE(XLBXVM(IISIZEXF,IJSIZEXF,IKU))
+    ALLOCATE(XLBXWM(IISIZEXF,IJSIZEXF,IKU))
+    ALLOCATE(XLBXTHM(IISIZEXF,IJSIZEXF,IKU))
+  ELSE
+    NSIZELBX_ll=2*JPHEXT      ! 2
+    NSIZELBXU_ll=2*(JPHEXT+1) ! 4
+    ALLOCATE(XLBXUM(IISIZEX4,IJSIZEX4,IKU))
+    ALLOCATE(XLBXVM(IISIZEX2,IJSIZEX2,IKU))
+    ALLOCATE(XLBXWM(IISIZEX2,IJSIZEX2,IKU))
+    ALLOCATE(XLBXTHM(IISIZEX2,IJSIZEX2,IKU))
+  END IF
+!
+  IF (CTURB /= 'NONE') THEN
+    IF ( LHORELAX_TKE) THEN
+      NSIZELBXTKE_ll=2* NRIMX+2*JPHEXT
+      ALLOCATE(XLBXTKEM(IISIZEXF,IJSIZEXF,IKU))
+    ELSE
+      NSIZELBXTKE_ll=2*JPHEXT  ! 2
+      ALLOCATE(XLBXTKEM(IISIZEX2,IJSIZEX2,IKU))
+    END IF
+  ELSE
+    NSIZELBXTKE_ll=0
+    ALLOCATE(XLBXTKEM(0,0,0))
+  END IF
+  !
+  IF ( NRR > 0 ) THEN
+    IF (LHORELAX_RV .OR. LHORELAX_RC .OR. LHORELAX_RR .OR. LHORELAX_RI    &
+         .OR. LHORELAX_RS .OR. LHORELAX_RG .OR. LHORELAX_RH               &
+       ) THEN
+      NSIZELBXR_ll=2* NRIMX+2*JPHEXT
+      ALLOCATE(XLBXRM(IISIZEXF,IJSIZEXF,IKU,NRR))
+    ELSE
+      NSIZELBXR_ll=2*JPHEXT  ! 2
+      ALLOCATE(XLBXRM(IISIZEX2,IJSIZEX2,IKU,NRR))
+    ENDIF
+  ELSE
+    NSIZELBXR_ll=0
+    ALLOCATE(XLBXRM(0,0,0,0))
+  END IF
+  !
+  IF ( NSV > 0 ) THEN
+    IF ( ANY( LHORELAX_SV(:)) ) THEN
+      NSIZELBXSV_ll=2* NRIMX+2*JPHEXT
+      ALLOCATE(XLBXSVM(IISIZEXF,IJSIZEXF,IKU,NSV))
+    ELSE
+      NSIZELBXSV_ll=2*JPHEXT  ! 2
+      ALLOCATE(XLBXSVM(IISIZEX2,IJSIZEX2,IKU,NSV))
+    END IF
+  ELSE
+    NSIZELBXSV_ll=0
+    ALLOCATE(XLBXSVM(0,0,0,0))
+  END IF
+!
+ELSE                                   ! 3D case
+!
+!
+  CALL GET_SIZEX_LB(NIMAX_ll,NJMAX_ll,NRIMX,               &
+                    IISIZEXF,IJSIZEXF,IISIZEXFU,IJSIZEXFU, &
+                    IISIZEX4,IJSIZEX4,IISIZEX2,IJSIZEX2)
+  CALL GET_SIZEY_LB(NIMAX_ll,NJMAX_ll,NRIMY,               &
+                    IISIZEYF,IJSIZEYF,IISIZEYFV,IJSIZEYFV, &
+                    IISIZEY4,IJSIZEY4,IISIZEY2,IJSIZEY2)
+!
+! check if local domain not to small for NRIMX NRIMY
+!
+  IF ( CLBCX(1) /= 'CYCL' )  THEN
+     IF ( NRIMX .GT. IDIMX )   THEN
+        WRITE(*,'(A,I8,A/A,2I8,/A)') "Processor=", IP-1, &
+             " :: INI_MODEL_n ERROR:  ( NRIMX  > IDIMX )  ", &
+             " Local domain to small for relaxation NRIMX,IDIMX ", &
+             NRIMX,IDIMX ,&
+             " change relaxation parameters or number of processors "
+        call Print_msg(NVERB_FATAL,'GEN','INI_MODEL_n','')
+     END IF
+  END IF
+  IF ( CLBCY(1) /= 'CYCL' ) THEN
+     IF ( NRIMY .GT. IDIMY )  THEN
+        WRITE(*,'(A,I8,A/A,2I8,/A)') "Processor=", IP-1, &
+             " :: INI_MODEL_n ERROR:  ( NRIMY > IDIMY )  ", &
+             " Local domain to small for relaxation NRIMY,IDIMY ", &
+             NRIMY,IDIMY ,&
+             " change relaxation parameters or number of processors "
+        call Print_msg(NVERB_FATAL,'GEN','INI_MODEL_n','')
+     END IF
+  END IF
+IF ( LHORELAX_UVWTH ) THEN
+    NSIZELBX_ll=2*NRIMX+2*JPHEXT
+    NSIZELBXU_ll=2*NRIMX+2*JPHEXT
+    NSIZELBY_ll=2*NRIMY+2*JPHEXT
+    NSIZELBYV_ll=2*NRIMY+2*JPHEXT
+    ALLOCATE(XLBXUM(IISIZEXFU,IJSIZEXFU,IKU))
+    ALLOCATE(XLBYUM(IISIZEYF,IJSIZEYF,IKU))
+    ALLOCATE(XLBXVM(IISIZEXF,IJSIZEXF,IKU))
+    ALLOCATE(XLBYVM(IISIZEYFV,IJSIZEYFV,IKU))
+    ALLOCATE(XLBXWM(IISIZEXF,IJSIZEXF,IKU))
+    ALLOCATE(XLBYWM(IISIZEYF,IJSIZEYF,IKU))
+    ALLOCATE(XLBXTHM(IISIZEXF,IJSIZEXF,IKU))
+    ALLOCATE(XLBYTHM(IISIZEYF,IJSIZEYF,IKU))
+  ELSE
+    NSIZELBX_ll=2*JPHEXT  ! 2
+    NSIZELBXU_ll=2*(JPHEXT+1) ! 4
+    NSIZELBY_ll=2*JPHEXT  ! 2
+    NSIZELBYV_ll=2*(JPHEXT+1) ! 4
+    ALLOCATE(XLBXUM(IISIZEX4,IJSIZEX4,IKU))
+    ALLOCATE(XLBYUM(IISIZEY2,IJSIZEY2,IKU))
+    ALLOCATE(XLBXVM(IISIZEX2,IJSIZEX2,IKU))
+    ALLOCATE(XLBYVM(IISIZEY4,IJSIZEY4,IKU))
+    ALLOCATE(XLBXWM(IISIZEX2,IJSIZEX2,IKU))
+    ALLOCATE(XLBYWM(IISIZEY2,IJSIZEY2,IKU))
+    ALLOCATE(XLBXTHM(IISIZEX2,IJSIZEX2,IKU))
+    ALLOCATE(XLBYTHM(IISIZEY2,IJSIZEY2,IKU))
+  END IF
+  !
+  IF (CTURB /= 'NONE') THEN
+    IF ( LHORELAX_TKE) THEN
+      NSIZELBXTKE_ll=2*NRIMX+2*JPHEXT
+      NSIZELBYTKE_ll=2*NRIMY+2*JPHEXT
+      ALLOCATE(XLBXTKEM(IISIZEXF,IJSIZEXF,IKU))
+      ALLOCATE(XLBYTKEM(IISIZEYF,IJSIZEYF,IKU))
+    ELSE
+      NSIZELBXTKE_ll=2*JPHEXT  ! 2
+      NSIZELBYTKE_ll=2*JPHEXT  ! 2
+      ALLOCATE(XLBXTKEM(IISIZEX2,IJSIZEX2,IKU))
+      ALLOCATE(XLBYTKEM(IISIZEY2,IJSIZEY2,IKU))
+    END IF
+  ELSE
+    NSIZELBXTKE_ll=0
+    NSIZELBYTKE_ll=0
+    ALLOCATE(XLBXTKEM(0,0,0))
+    ALLOCATE(XLBYTKEM(0,0,0))
+  END IF
+  !
+  IF ( NRR > 0 ) THEN
+    IF (LHORELAX_RV .OR. LHORELAX_RC .OR. LHORELAX_RR .OR. LHORELAX_RI    &
+          .OR. LHORELAX_RS .OR. LHORELAX_RG .OR. LHORELAX_RH              &
+       ) THEN
+      NSIZELBXR_ll=2*NRIMX+2*JPHEXT
+      NSIZELBYR_ll=2*NRIMY+2*JPHEXT
+      ALLOCATE(XLBXRM(IISIZEXF,IJSIZEXF,IKU,NRR))
+      ALLOCATE(XLBYRM(IISIZEYF,IJSIZEYF,IKU,NRR))
+    ELSE
+      NSIZELBXR_ll=2*JPHEXT  ! 2
+      NSIZELBYR_ll=2*JPHEXT  ! 2
+      ALLOCATE(XLBXRM(IISIZEX2,IJSIZEX2,IKU,NRR))
+      ALLOCATE(XLBYRM(IISIZEY2,IJSIZEY2,IKU,NRR))
+    ENDIF
+  ELSE
+    NSIZELBXR_ll=0
+    NSIZELBYR_ll=0
+    ALLOCATE(XLBXRM(0,0,0,0))
+    ALLOCATE(XLBYRM(0,0,0,0))
+  END IF
+  !
+  IF ( NSV > 0 ) THEN
+    IF ( ANY( LHORELAX_SV(:)) ) THEN
+      NSIZELBXSV_ll=2*NRIMX+2*JPHEXT
+      NSIZELBYSV_ll=2*NRIMY+2*JPHEXT
+      ALLOCATE(XLBXSVM(IISIZEXF,IJSIZEXF,IKU,NSV))
+      ALLOCATE(XLBYSVM(IISIZEYF,IJSIZEYF,IKU,NSV))
+    ELSE
+      NSIZELBXSV_ll=2*JPHEXT  ! 2
+      NSIZELBYSV_ll=2*JPHEXT  ! 2
+      ALLOCATE(XLBXSVM(IISIZEX2,IJSIZEX2,IKU,NSV))
+      ALLOCATE(XLBYSVM(IISIZEY2,IJSIZEY2,IKU,NSV))
+    END IF
+  ELSE
+    NSIZELBXSV_ll=0
+    NSIZELBYSV_ll=0
+    ALLOCATE(XLBXSVM(0,0,0,0))
+    ALLOCATE(XLBYSVM(0,0,0,0))
+  END IF
+END IF      ! END OF THE IF STRUCTURE ON THE MODEL DIMENSION
+!
+!
+IF ( KMI > 1 ) THEN 
+  ! it has been assumed that the THeta field used the largest rim area compared
+  ! to the others prognostic variables, if it is not the case, you must change
+  ! these lines
+  ALLOCATE(XCOEFLIN_LBXM(SIZE(XLBXTHM,1),SIZE(XLBXTHM,2),SIZE(XLBXTHM,3)))
+  ALLOCATE(   NKLIN_LBXM(SIZE(XLBXTHM,1),SIZE(XLBXTHM,2),SIZE(XLBXTHM,3)))
+  ALLOCATE(XCOEFLIN_LBYM(SIZE(XLBYTHM,1),SIZE(XLBYTHM,2),SIZE(XLBYTHM,3)))
+  ALLOCATE(   NKLIN_LBYM(SIZE(XLBYTHM,1),SIZE(XLBYTHM,2),SIZE(XLBYTHM,3)))
+  ALLOCATE(XCOEFLIN_LBXU(SIZE(XLBXUM,1),SIZE(XLBXUM,2),SIZE(XLBXUM,3)))
+  ALLOCATE(   NKLIN_LBXU(SIZE(XLBXUM,1),SIZE(XLBXUM,2),SIZE(XLBXUM,3)))
+  ALLOCATE(XCOEFLIN_LBYU(SIZE(XLBYUM,1),SIZE(XLBYUM,2),SIZE(XLBYUM,3)))
+  ALLOCATE(   NKLIN_LBYU(SIZE(XLBYUM,1),SIZE(XLBYUM,2),SIZE(XLBYUM,3)))
+  ALLOCATE(XCOEFLIN_LBXV(SIZE(XLBXVM,1),SIZE(XLBXVM,2),SIZE(XLBXVM,3)))
+  ALLOCATE(   NKLIN_LBXV(SIZE(XLBXVM,1),SIZE(XLBXVM,2),SIZE(XLBXVM,3)))
+  ALLOCATE(XCOEFLIN_LBYV(SIZE(XLBYVM,1),SIZE(XLBYVM,2),SIZE(XLBYVM,3)))
+  ALLOCATE(   NKLIN_LBYV(SIZE(XLBYVM,1),SIZE(XLBYVM,2),SIZE(XLBYVM,3)))
+  ALLOCATE(XCOEFLIN_LBXW(SIZE(XLBXWM,1),SIZE(XLBXWM,2),SIZE(XLBXWM,3)))
+  ALLOCATE(   NKLIN_LBXW(SIZE(XLBXWM,1),SIZE(XLBXWM,2),SIZE(XLBXWM,3)))
+  ALLOCATE(XCOEFLIN_LBYW(SIZE(XLBYWM,1),SIZE(XLBYWM,2),SIZE(XLBYWM,3)))
+  ALLOCATE(   NKLIN_LBYW(SIZE(XLBYWM,1),SIZE(XLBYWM,2),SIZE(XLBYWM,3)))
+ELSE
+  ALLOCATE(XCOEFLIN_LBXM(0,0,0))
+  ALLOCATE(   NKLIN_LBXM(0,0,0))
+  ALLOCATE(XCOEFLIN_LBYM(0,0,0))
+  ALLOCATE(   NKLIN_LBYM(0,0,0))
+  ALLOCATE(XCOEFLIN_LBXU(0,0,0))
+  ALLOCATE(   NKLIN_LBXU(0,0,0))
+  ALLOCATE(XCOEFLIN_LBYU(0,0,0))
+  ALLOCATE(   NKLIN_LBYU(0,0,0))
+  ALLOCATE(XCOEFLIN_LBXV(0,0,0))
+  ALLOCATE(   NKLIN_LBXV(0,0,0))
+  ALLOCATE(XCOEFLIN_LBYV(0,0,0))
+  ALLOCATE(   NKLIN_LBYV(0,0,0))
+  ALLOCATE(XCOEFLIN_LBXW(0,0,0))
+  ALLOCATE(   NKLIN_LBXW(0,0,0))
+  ALLOCATE(XCOEFLIN_LBYW(0,0,0))
+  ALLOCATE(   NKLIN_LBYW(0,0,0))
+END IF
+!
+!  allocation of the LS fields for vertical relaxation and numerical diffusion
+IF( .NOT. LSTEADYLS )  THEN
+!
+  ALLOCATE(XLSUS(SIZE(XLSUM,1),SIZE(XLSUM,2),SIZE(XLSUM,3)))
+  ALLOCATE(XLSVS(SIZE(XLSVM,1),SIZE(XLSVM,2),SIZE(XLSVM,3)))
+  ALLOCATE(XLSWS(SIZE(XLSWM,1),SIZE(XLSWM,2),SIZE(XLSWM,3)))
+  ALLOCATE(XLSTHS(SIZE(XLSTHM,1),SIZE(XLSTHM,2),SIZE(XLSTHM,3)))
+  ALLOCATE(XLSRVS(SIZE(XLSRVM,1),SIZE(XLSRVM,2),SIZE(XLSRVM,3)))
+  ALLOCATE(XLSZWSS(SIZE(XLSZWSM,1),SIZE(XLSZWSM,2)))
+!
+ELSE
+!
+  ALLOCATE(XLSUS(0,0,0))
+  ALLOCATE(XLSVS(0,0,0))
+  ALLOCATE(XLSWS(0,0,0))
+  ALLOCATE(XLSTHS(0,0,0))
+  ALLOCATE(XLSRVS(0,0,0))
+  ALLOCATE(XLSZWSS(0,0))
+!
+END IF
+!  allocation of the LB fields for horizontal relaxation and Lateral Boundaries
+IF( .NOT. ( LSTEADYLS .AND. KMI==1 ) )  THEN
+!
+  ALLOCATE(XLBXTKES(SIZE(XLBXTKEM,1),SIZE(XLBXTKEM,2),SIZE(XLBXTKEM,3)))
+  ALLOCATE(XLBYTKES(SIZE(XLBYTKEM,1),SIZE(XLBYTKEM,2),SIZE(XLBYTKEM,3)))
+  ALLOCATE(XLBXUS(SIZE(XLBXUM,1),SIZE(XLBXUM,2),SIZE(XLBXUM,3)))
+  ALLOCATE(XLBYUS(SIZE(XLBYUM,1),SIZE(XLBYUM,2),SIZE(XLBYUM,3)))
+  ALLOCATE(XLBXVS(SIZE(XLBXVM,1),SIZE(XLBXVM,2),SIZE(XLBXVM,3)))
+  ALLOCATE(XLBYVS(SIZE(XLBYVM,1),SIZE(XLBYVM,2),SIZE(XLBYVM,3)))
+  ALLOCATE(XLBXWS(SIZE(XLBXWM,1),SIZE(XLBXWM,2),SIZE(XLBXWM,3)))
+  ALLOCATE(XLBYWS(SIZE(XLBYWM,1),SIZE(XLBYWM,2),SIZE(XLBYWM,3)))
+  ALLOCATE(XLBXTHS(SIZE(XLBXTHM,1),SIZE(XLBXTHM,2),SIZE(XLBXTHM,3)))
+  ALLOCATE(XLBYTHS(SIZE(XLBYTHM,1),SIZE(XLBYTHM,2),SIZE(XLBYTHM,3)))
+  ALLOCATE(XLBXRS(SIZE(XLBXRM,1),SIZE(XLBXRM,2),SIZE(XLBXRM,3),SIZE(XLBXRM,4)))
+  ALLOCATE(XLBYRS(SIZE(XLBYRM,1),SIZE(XLBYRM,2),SIZE(XLBYRM,3),SIZE(XLBYRM,4)))
+  ALLOCATE(XLBXSVS(SIZE(XLBXSVM,1),SIZE(XLBXSVM,2),SIZE(XLBXSVM,3),SIZE(XLBXSVM,4)))
+  ALLOCATE(XLBYSVS(SIZE(XLBYSVM,1),SIZE(XLBYSVM,2),SIZE(XLBYSVM,3),SIZE(XLBYSVM,4)))
+!
+ELSE
+!
+  ALLOCATE(XLBXTKES(0,0,0))
+  ALLOCATE(XLBYTKES(0,0,0))
+  ALLOCATE(XLBXUS(0,0,0))
+  ALLOCATE(XLBYUS(0,0,0))
+  ALLOCATE(XLBXVS(0,0,0))
+  ALLOCATE(XLBYVS(0,0,0))
+  ALLOCATE(XLBXWS(0,0,0))
+  ALLOCATE(XLBYWS(0,0,0))
+  ALLOCATE(XLBXTHS(0,0,0))
+  ALLOCATE(XLBYTHS(0,0,0))
+  ALLOCATE(XLBXRS(0,0,0,0))
+  ALLOCATE(XLBYRS(0,0,0,0))
+  ALLOCATE(XLBXSVS(0,0,0,0))
+  ALLOCATE(XLBYSVS(0,0,0,0))
+!
+END IF
+!
+!
+!*       3.7   Module MODD_RADIATIONS_n (except XOZON and XAER)
+!
+! Initialization of SW bands
+NSWB_OLD = 6 ! Number of bands in ECMWF original scheme (from Fouquart et Bonnel (1980))
+             ! then modified through INI_RADIATIONS_ECMWF but remains equal to 6 practically
+IF (CRAD == 'ECRA') THEN
+    NSWB_MNH = 14
+ELSE
+    NSWB_MNH = NSWB_OLD
+END IF
+
+NLWB_MNH = 16 ! For XEMIS initialization (should be spectral in the future)
+
+
+ALLOCATE(XSW_BANDS (NSWB_MNH)) 
+ALLOCATE(XLW_BANDS (NLWB_MNH)) 
+ALLOCATE(XZENITH   (IIU,IJU))
+ALLOCATE(XAZIM     (IIU,IJU))
+ALLOCATE(XALBUV    (IIU,IJU))
+XALBUV(:,:) = NALBUV_DEFAULT !Set to an arbitrary low value (XALBUV is needed in CH_INTERP_JVALUES even if no radiation)
+ALLOCATE(XDIRSRFSWD(IIU,IJU,NSWB_MNH))
+ALLOCATE(XSCAFLASWD(IIU,IJU,NSWB_MNH))
+ALLOCATE(XFLALWD   (IIU,IJU))
+!
+IF (CRAD /= 'NONE') THEN
+  ALLOCATE(XSLOPANG(IIU,IJU))
+  ALLOCATE(XSLOPAZI(IIU,IJU))
+  ALLOCATE(XDTHRAD(IIU,IJU,IKU))
+  ALLOCATE(XDIRFLASWD(IIU,IJU,NSWB_MNH))
+  ALLOCATE(XDIR_ALB(IIU,IJU,NSWB_MNH))
+  ALLOCATE(XSCA_ALB(IIU,IJU,NSWB_MNH))
+  ALLOCATE(XEMIS  (IIU,IJU,NLWB_MNH))
+  ALLOCATE(XTSRAD (IIU,IJU))    ; XTSRAD = 0.0
+  ALLOCATE(XSEA (IIU,IJU))
+  ALLOCATE(XZS_XY (IIU,IJU))
+  ALLOCATE(NCLEARCOL_TM1(IIU,IJU))
+  ALLOCATE(XSWU(IIU,IJU,IKU))
+  ALLOCATE(XSWD(IIU,IJU,IKU))
+  ALLOCATE(XLWU(IIU,IJU,IKU))
+  ALLOCATE(XLWD(IIU,IJU,IKU))
+  ALLOCATE(XDTHRADSW(IIU,IJU,IKU))
+  ALLOCATE(XDTHRADLW(IIU,IJU,IKU))
+  ALLOCATE(XRADEFF(IIU,IJU,IKU))
+ELSE
+  ALLOCATE(XSLOPANG(0,0))
+  ALLOCATE(XSLOPAZI(0,0))
+  ALLOCATE(XDTHRAD(0,0,0))
+  ALLOCATE(XDIRFLASWD(0,0,0))
+  ALLOCATE(XDIR_ALB(0,0,0))
+  ALLOCATE(XSCA_ALB(0,0,0))
+  ALLOCATE(XEMIS  (0,0,0))
+  ALLOCATE(XTSRAD (0,0))
+  ALLOCATE(XSEA (0,0))
+  ALLOCATE(XZS_XY (0,0))
+  ALLOCATE(NCLEARCOL_TM1(0,0))
+  ALLOCATE(XSWU(0,0,0))
+  ALLOCATE(XSWD(0,0,0))
+  ALLOCATE(XLWU(0,0,0))
+  ALLOCATE(XLWD(0,0,0))
+  ALLOCATE(XDTHRADSW(0,0,0))
+  ALLOCATE(XDTHRADLW(0,0,0))
+  ALLOCATE(XRADEFF(0,0,0))
+END IF
+
+IF (CRAD == 'ECMW' .OR. CRAD == 'ECRA') THEN
+  ALLOCATE(XSTROATM(31,6))
+  ALLOCATE(XSMLSATM(31,6))
+  ALLOCATE(XSMLWATM(31,6))
+  ALLOCATE(XSPOSATM(31,6))
+  ALLOCATE(XSPOWATM(31,6))
+  ALLOCATE(XSTATM(31,6))
+ELSE
+  ALLOCATE(XSTROATM(0,0))
+  ALLOCATE(XSMLSATM(0,0))
+  ALLOCATE(XSMLWATM(0,0))
+  ALLOCATE(XSPOSATM(0,0))
+  ALLOCATE(XSPOWATM(0,0))
+  ALLOCATE(XSTATM(0,0))
+END IF
+!
+!*       3.8   Module MODD_DEEP_CONVECTION_n
+!
+IF (CDCONV /= 'NONE' .OR. CSCONV == 'KAFR') THEN
+  ALLOCATE(NCOUNTCONV(IIU,IJU))
+  ALLOCATE(XDTHCONV(IIU,IJU,IKU))
+  ALLOCATE(XDRVCONV(IIU,IJU,IKU))
+  ALLOCATE(XDRCCONV(IIU,IJU,IKU))
+  ALLOCATE(XDRICONV(IIU,IJU,IKU))
+  ALLOCATE(XPRCONV(IIU,IJU))
+  ALLOCATE(XPACCONV(IIU,IJU))
+  ALLOCATE(XPRSCONV(IIU,IJU))
+  ! diagnostics
+  IF (LCH_CONV_LINOX) THEN
+    ALLOCATE(XIC_RATE(IIU,IJU))
+    ALLOCATE(XCG_RATE(IIU,IJU))
+    ALLOCATE(XIC_TOTAL_NUMBER(IIU,IJU))
+    ALLOCATE(XCG_TOTAL_NUMBER(IIU,IJU))
+  ELSE
+    ALLOCATE(XIC_RATE(0,0))
+    ALLOCATE(XCG_RATE(0,0))
+    ALLOCATE(XIC_TOTAL_NUMBER(0,0))
+    ALLOCATE(XCG_TOTAL_NUMBER(0,0))
+  END IF
+  IF ( LDIAGCONV )  THEN
+    ALLOCATE(XUMFCONV(IIU,IJU,IKU))
+    ALLOCATE(XDMFCONV(IIU,IJU,IKU))
+    ALLOCATE(XPRLFLXCONV(IIU,IJU,IKU))
+    ALLOCATE(XPRSFLXCONV(IIU,IJU,IKU))
+    ALLOCATE(XCAPE(IIU,IJU))
+    ALLOCATE(NCLTOPCONV(IIU,IJU))
+    ALLOCATE(NCLBASCONV(IIU,IJU))
+  ELSE
+    ALLOCATE(XUMFCONV(0,0,0))
+    ALLOCATE(XDMFCONV(0,0,0))
+    ALLOCATE(XPRLFLXCONV(0,0,0))
+    ALLOCATE(XPRSFLXCONV(0,0,0))
+    ALLOCATE(XCAPE(0,0))
+    ALLOCATE(NCLTOPCONV(0,0))
+    ALLOCATE(NCLBASCONV(0,0))
+  END IF
+ELSE
+  ALLOCATE(NCOUNTCONV(0,0))
+  ALLOCATE(XDTHCONV(0,0,0))
+  ALLOCATE(XDRVCONV(0,0,0))
+  ALLOCATE(XDRCCONV(0,0,0))
+  ALLOCATE(XDRICONV(0,0,0))
+  ALLOCATE(XPRCONV(0,0))
+  ALLOCATE(XPACCONV(0,0))
+  ALLOCATE(XPRSCONV(0,0))
+  ALLOCATE(XIC_RATE(0,0))
+  ALLOCATE(XCG_RATE(0,0))
+  ALLOCATE(XIC_TOTAL_NUMBER(0,0))
+  ALLOCATE(XCG_TOTAL_NUMBER(0,0))
+  ALLOCATE(XUMFCONV(0,0,0))
+  ALLOCATE(XDMFCONV(0,0,0))
+  ALLOCATE(XPRLFLXCONV(0,0,0))
+  ALLOCATE(XPRSFLXCONV(0,0,0))
+  ALLOCATE(XCAPE(0,0))
+  ALLOCATE(NCLTOPCONV(0,0))
+  ALLOCATE(NCLBASCONV(0,0))
+END IF
+!
+IF ((CDCONV == 'KAFR' .OR. CSCONV == 'KAFR') &
+    .AND. LSUBG_COND .AND. LSIG_CONV) THEN
+  ALLOCATE(XMFCONV(IIU,IJU,IKU))
+ELSE
+  ALLOCATE(XMFCONV(0,0,0))
+ENDIF
+!
+IF ((CDCONV == 'KAFR' .OR. CSCONV == 'KAFR') &
+    .AND. LCHTRANS .AND. NSV > 0 ) THEN
+  ALLOCATE(XDSVCONV(IIU,IJU,IKU,NSV))
+ELSE
+  ALLOCATE(XDSVCONV(0,0,0,0))
+END IF
+!
+ALLOCATE(XCF_MF(IIU,IJU,IKU)) ; XCF_MF=0.0
+ALLOCATE(XRC_MF(IIU,IJU,IKU)) ; XRC_MF=0.0
+ALLOCATE(XRI_MF(IIU,IJU,IKU)) ; XRI_MF=0.0
+!
+!*       3.9   Local variables
+!
+ALLOCATE(ZJ(IIU,IJU,IKU))
+!
+!*      3.10 Forcing variables (Module MODD_FRC)
+!
+IF (KMI == 1) THEN
+  IF ( LFORCING ) THEN
+    ALLOCATE(TDTFRC(NFRC))
+    ALLOCATE(XUFRC(IKU,NFRC))
+    ALLOCATE(XVFRC(IKU,NFRC))
+    ALLOCATE(XWFRC(IKU,NFRC))
+    ALLOCATE(XTHFRC(IKU,NFRC))
+    ALLOCATE(XRVFRC(IKU,NFRC))
+    ALLOCATE(XTENDTHFRC(IKU,NFRC))
+    ALLOCATE(XTENDRVFRC(IKU,NFRC))
+    ALLOCATE(XGXTHFRC(IKU,NFRC))
+    ALLOCATE(XGYTHFRC(IKU,NFRC))
+    ALLOCATE(XPGROUNDFRC(NFRC))
+    ALLOCATE(XTENDUFRC(IKU,NFRC))
+    ALLOCATE(XTENDVFRC(IKU,NFRC))
+  ELSE
+    ALLOCATE(TDTFRC(0))
+    ALLOCATE(XUFRC(0,0))
+    ALLOCATE(XVFRC(0,0))
+    ALLOCATE(XWFRC(0,0))
+    ALLOCATE(XTHFRC(0,0))
+    ALLOCATE(XRVFRC(0,0))
+    ALLOCATE(XTENDTHFRC(0,0))
+    ALLOCATE(XTENDRVFRC(0,0))
+    ALLOCATE(XGXTHFRC(0,0))
+    ALLOCATE(XGYTHFRC(0,0))
+    ALLOCATE(XPGROUNDFRC(0))
+    ALLOCATE(XTENDUFRC(0,0))
+    ALLOCATE(XTENDVFRC(0,0))
+  END IF
+  IF ( LFORCING ) THEN
+    ALLOCATE(XWTFRC(IIU,IJU,IKU))
+    ALLOCATE(XUFRC_PAST(IIU,IJU,IKU)) ; XUFRC_PAST = XUNDEF
+    ALLOCATE(XVFRC_PAST(IIU,IJU,IKU)) ; XVFRC_PAST = XUNDEF
+  ELSE
+    ALLOCATE(XWTFRC(0,0,0))
+    ALLOCATE(XUFRC_PAST(0,0,0))
+    ALLOCATE(XVFRC_PAST(0,0,0))
+  END IF
+ELSE
+  !Do not allocate because they are the same on all grids (not 'n' variables)
+END IF
+! ----------------------------------------------------------------------
+!
+IF (L2D_ADV_FRC) THEN
+  WRITE(ILUOUT,*) 'L2D_ADV_FRC IS SET TO', L2D_ADV_FRC
+  WRITE(ILUOUT,*) 'ADV FRC WILL BE SET'
+  ALLOCATE(TDTADVFRC(NADVFRC))
+  ALLOCATE(XDTHFRC(IIU,IJU,IKU,NADVFRC))  ; XDTHFRC=0.
+  ALLOCATE(XDRVFRC(IIU,IJU,IKU,NADVFRC))  ; XDRVFRC=0.
+ELSE
+  ALLOCATE(TDTADVFRC(0))
+  ALLOCATE(XDTHFRC(0,0,0,0))
+  ALLOCATE(XDRVFRC(0,0,0,0))
+ENDIF
+
+IF (L2D_REL_FRC) THEN
+  WRITE(ILUOUT,*) 'L2D_REL_FRC IS SET TO', L2D_REL_FRC
+  WRITE(ILUOUT,*) 'REL FRC WILL BE SET'
+  ALLOCATE(TDTRELFRC(NRELFRC))
+  ALLOCATE(XTHREL(IIU,IJU,IKU,NRELFRC))  ; XTHREL=0.
+  ALLOCATE(XRVREL(IIU,IJU,IKU,NRELFRC))  ; XRVREL=0.
+ELSE
+  ALLOCATE(TDTRELFRC(0))
+  ALLOCATE(XTHREL(0,0,0,0))
+  ALLOCATE(XRVREL(0,0,0,0))
+ENDIF
+!
+!*      4.11 BIS: Eddy fluxes allocation
+!
+IF ( LTH_FLX ) THEN
+  ALLOCATE(XVTH_FLUX_M(IIU,IJU,IKU)) ; XVTH_FLUX_M = 0.
+  ALLOCATE(XWTH_FLUX_M(IIU,IJU,IKU)) ; XWTH_FLUX_M = 0.
+  IF (KMI /= 1) THEN
+    ALLOCATE(XRTHS_EDDY_FLUX(IIU,IJU,IKU))
+    XRTHS_EDDY_FLUX = 0.
+  ELSE
+    ALLOCATE(XRTHS_EDDY_FLUX(0,0,0))
+  ENDIF
+ELSE
+  ALLOCATE(XVTH_FLUX_M(0,0,0))
+  ALLOCATE(XWTH_FLUX_M(0,0,0))
+  ALLOCATE(XRTHS_EDDY_FLUX(0,0,0))
+END IF
+!
+IF ( LUV_FLX) THEN
+  ALLOCATE(XVU_FLUX_M(IIU,IJU,IKU)) ; XVU_FLUX_M  = 0.
+  IF (KMI /= 1) THEN
+    ALLOCATE(XRVS_EDDY_FLUX(IIU,IJU,IKU))
+    XRVS_EDDY_FLUX = 0.
+  ELSE
+    ALLOCATE(XRVS_EDDY_FLUX(0,0,0))
+  ENDIF
+ELSE
+  ALLOCATE(XVU_FLUX_M(0,0,0))
+  ALLOCATE(XRVS_EDDY_FLUX(0,0,0))
+END IF
+!
+!*      3.11   Module MODD_ICE_CONC_n
+!
+IF (     (CCLOUD == 'ICE3'.OR.CCLOUD == 'ICE4') .AND.   &
+     (CPROGRAM == 'DIAG  '.OR.CPROGRAM == 'MESONH')) THEN
+  ALLOCATE(XCIT(IIU,IJU,IKU))
+ELSE
+  ALLOCATE(XCIT(0,0,0))
+END IF
+!
+IF ( CCLOUD == 'KHKO' .OR. CCLOUD == 'C2R2') THEN
+   ALLOCATE(XSUPSAT(IIU,IJU,IKU))
+   ALLOCATE(XNACT(IIU,IJU,IKU))
+   ALLOCATE(XNPRO(IIU,IJU,IKU))
+   ALLOCATE(XSSPRO(IIU,IJU,IKU))
+ELSE
+   ALLOCATE(XSUPSAT(0,0,0))
+   ALLOCATE(XNACT(0,0,0))
+   ALLOCATE(XNPRO(0,0,0))
+   ALLOCATE(XSSPRO(0,0,0))
+END IF
+!
+!*      3.12   Module MODD_TURB_CLOUD
+!
+IF (.NOT.(ALLOCATED(XCEI))) ALLOCATE(XCEI(0,0,0))
+IF (KMI == NMODEL_CLOUD .AND. CTURBLEN_CLOUD/='NONE' ) THEN
+  DEALLOCATE(XCEI)
+  ALLOCATE(XCEI(IIU,IJU,IKU))
+ENDIF
+!
+!*      3.13  Module MODD_CH_PH_n
+!
+IF (LUSECHAQ.AND.(CPROGRAM == 'DIAG  '.OR.CPROGRAM == 'MESONH')) THEN
+  IF (LCH_PH) THEN
+    ALLOCATE(XPHC(IIU,IJU,IKU))
+    IF (NRRL==2) THEN
+      ALLOCATE(XPHR(IIU,IJU,IKU))
+      ALLOCATE(XACPHR(IIU,IJU))
+      XACPHR(:,:) =  0.
+    ENDIF
+  ENDIF
+  IF (NRRL==2) THEN
+    ALLOCATE(XACPRAQ(IIU,IJU,NSV_CHAC/2))
+    XACPRAQ(:,:,:) = 0.
+  ENDIF
+ENDIF
+IF (.NOT.(ASSOCIATED(XPHC))) ALLOCATE(XPHC(0,0,0))
+IF (.NOT.(ASSOCIATED(XPHR))) ALLOCATE(XPHR(0,0,0))
+IF (.NOT.(ASSOCIATED(XACPHR))) ALLOCATE(XACPHR(0,0))
+IF (.NOT.(ASSOCIATED(XACPRAQ))) ALLOCATE(XACPRAQ(0,0,0))
+IF ((LUSECHEM).AND.(CPROGRAM == 'DIAG  ')) THEN
+  ALLOCATE(XCHFLX(IIU,IJU,NSV_CHEM))
+  XCHFLX(:,:,:) = 0.
+ELSE
+  ALLOCATE(XCHFLX(0,0,0))
+END IF
+!
+!*          3.14 Module MODD_DRAG
+!
+IF (LDRAG) THEN
+  ALLOCATE(XDRAG(IIU,IJU))
+ELSE
+  ALLOCATE(XDRAG(0,0))
+ENDIF
+!
+!-------------------------------------------------------------------------------
+!
+!*       4.    INITIALIZE BUDGET VARIABLES
+!              ---------------------------
+!
+IF ( CBUTYPE /= "NONE" .AND. NBUMOD == KMI ) THEN
+  CALL INI_BUDGET(ILUOUT,XTSTEP,NSV,NRR,                                      &
+             LNUMDIFU,LNUMDIFTH,LNUMDIFSV,                                    &
+             LHORELAX_UVWTH,LHORELAX_RV, LHORELAX_RC,LHORELAX_RR,             &
+             LHORELAX_RI,LHORELAX_RS,LHORELAX_RG, LHORELAX_RH,LHORELAX_TKE,   &
+             LHORELAX_SV,LVE_RELAX,LCHTRANS,LNUDGING,LDRAGTREE,LDEPOTREE,     &
+             CRAD,CDCONV,CSCONV,CTURB,CTURBDIM,CCLOUD                         )
+END IF
+!
+!-------------------------------------------------------------------------------
+!
+!
+!*       5.    INITIALIZE INTERPOLATION COEFFICIENTS
+!
+CALL INI_BIKHARDT_n (NDXRATIO_ALL(KMI),NDYRATIO_ALL(KMI),KMI)
+!
+!-------------------------------------------------------------------------------
+!
+!*       6.     BUILT THE GENERIC OUTPUT NAME
+!               ----------------------------
+!
+IF (KMI == 1) THEN
+  DO IMI = 1 , NMODEL
+    WRITE(IO_SURF_MNH_MODEL(IMI)%COUTFILE,'(A,".",I1,".",A)') CEXP,IMI,TRIM(ADJUSTL(CSEG))
+    WRITE(YNAME, '(A,".",I1,".",A)') CEXP,IMI,TRIM(ADJUSTL(CSEG))//'.000'
+    CALL IO_File_add2list(LUNIT_MODEL(IMI)%TDIAFILE,YNAME,'MNHDIACHRONIC','WRITE', &
+                          HDIRNAME=CIO_DIR,                                        &
+                          KLFINPRAR=INT(50,KIND=LFIINT),KLFITYPE=1,KLFIVERB=NVERB, &
+                          TPDADFILE=LUNIT_MODEL(NDAD(IMI))%TDIAFILE )
+  END DO
+  !
+  TDIAFILE => LUNIT_MODEL(KMI)%TDIAFILE !Necessary because no call to GOTO_MODEL before needing it
+  !
+  IF (CPROGRAM=='MESONH') THEN
+    IF ( NDAD(KMI) == 1)  CDAD_NAME(KMI) = CEXP//'.1.'//CSEG
+    IF ( NDAD(KMI) == 2)  CDAD_NAME(KMI) = CEXP//'.2.'//CSEG
+    IF ( NDAD(KMI) == 3)  CDAD_NAME(KMI) = CEXP//'.3.'//CSEG
+    IF ( NDAD(KMI) == 4)  CDAD_NAME(KMI) = CEXP//'.4.'//CSEG
+    IF ( NDAD(KMI) == 5)  CDAD_NAME(KMI) = CEXP//'.5.'//CSEG
+    IF ( NDAD(KMI) == 6)  CDAD_NAME(KMI) = CEXP//'.6.'//CSEG
+    IF ( NDAD(KMI) == 7)  CDAD_NAME(KMI) = CEXP//'.7.'//CSEG
+    IF ( NDAD(KMI) == 8)  CDAD_NAME(KMI) = CEXP//'.8.'//CSEG
+  END IF
+ELSE
+  ALLOCATE(XUM(0,0,0))
+  ALLOCATE(XVM(0,0,0))
+  ALLOCATE(XWM(0,0,0))
+  ALLOCATE(XDUM(0,0,0))
+  ALLOCATE(XDVM(0,0,0))
+  ALLOCATE(XDWM(0,0,0))
+END IF
+!
+!-------------------------------------------------------------------------------
+!
+!*       7.    INITIALIZE GRIDS AND METRIC COEFFICIENTS
+!              ----------------------------------------
+!
+CALL SET_GRID(KMI,TPINIFILE,IKU,NIMAX_ll,NJMAX_ll,                       &
+              XTSTEP,XSEGLEN,                                            &
+              XLONORI,XLATORI,XLON,XLAT,                                 &
+              XXHAT,XYHAT,XDXHAT,XDYHAT, XMAP,                           &
+              XZS,XZZ,XZHAT,XZTOP,LSLEVE,XLEN1,XLEN2,XZSMT,              &
+              ZJ,                                                        &
+              TDTMOD,TDTCUR,NSTOP,NBAK_NUMB,NOUT_NUMB,TBACKUPN,TOUTPUTN)
+!
+CALL METRICS(XMAP,XDXHAT,XDYHAT,XZZ,XDXX,XDYY,XDZX,XDZY,XDZZ)
+!
+!* update halos of metric coefficients
+!
+!
+CALL UPDATE_METRICS(CLBCX,CLBCY,XDXX,XDYY,XDZX,XDZY,XDZZ)
+!
+!
+CALL SET_DIRCOS(CLBCX,CLBCY,XDXX,XDYY,XDZX,XDZY,TZINITHALO2D_ll,   &
+                XDIRCOSXW,XDIRCOSYW,XDIRCOSZW,XCOSSLOPE,XSINSLOPE  )
+!
+! grid nesting initializations
+IF ( KMI == 1 ) THEN
+  XTSTEP_MODEL1=XTSTEP
+END IF
+!
+NDT_2_WAY(KMI)=4
+!
+!-------------------------------------------------------------------------------
+!
+!*      8.    INITIALIZE DATA FOR JVALUES AND AEROSOLS 
+!
+IF ( LUSECHEM .OR. LCHEMDIAG ) THEN
+  IF ((KMI==1).AND.(CPROGRAM == "MESONH".OR.CPROGRAM == "DIAG  "))  &
+    CALL CH_INIT_JVALUES(TDTCUR%TDATE%DAY, TDTCUR%TDATE%MONTH,      &
+                         TDTCUR%TDATE%YEAR, ILUOUT, XCH_TUV_DOBNEW)
+!
+  IF (LORILAM) THEN
+    CALL CH_AER_MOD_INIT
+  ENDIF
+END IF
+IF (.NOT.(ASSOCIATED(XMI))) ALLOCATE(XMI(0,0,0,0))
+IF (.NOT.(ASSOCIATED(XSOLORG))) ALLOCATE(XSOLORG(0,0,0,0))
+!
+IF (CCLOUD=='LIMA') CALL INIT_AEROSOL_PROPERTIES
+!
+!-------------------------------------------------------------------------------
+!
+!*       9.    INITIALIZE THE PROGNOSTIC FIELDS
+!              --------------------------------
+!
+CALL MPPDB_CHECK3D(XUT,"INI_MODEL_N-before read_field::XUT",PRECISION)
+CALL READ_FIELD(TPINIFILE,IIU,IJU,IKU,                                        &
+                CGETTKET,CGETRVT,CGETRCT,CGETRRT,CGETRIT,CGETCIT,CGETZWS,     &
+                CGETRST,CGETRGT,CGETRHT,CGETSVT,CGETSRCT,CGETSIGS,CGETCLDFR,  &
+                CGETBL_DEPTH,CGETSBL_DEPTH,CGETPHC,CGETPHR,CUVW_ADV_SCHEME,   &
+                CTEMP_SCHEME,NSIZELBX_ll,NSIZELBXU_ll,NSIZELBY_ll,NSIZELBYV_ll,&
+                NSIZELBXTKE_ll,NSIZELBYTKE_ll,                                &
+                NSIZELBXR_ll,NSIZELBYR_ll,NSIZELBXSV_ll,NSIZELBYSV_ll,        &
+                XUM,XVM,XWM,XDUM,XDVM,XDWM,                                   &
+                XUT,XVT,XWT,XTHT,XPABST,XTKET,XRTKEMS,                        &
+                XRT,XSVT,XZWS,XCIT,XDRYMASST,                                 &
+                XSIGS,XSRCT,XCLDFR,XBL_DEPTH,XSBL_DEPTH,XWTHVMF,XPHC,XPHR,    &
+                XLSUM,XLSVM,XLSWM,XLSTHM,XLSRVM,XLSZWSM,                      &
+                XLBXUM,XLBXVM,XLBXWM,XLBXTHM,XLBXTKEM,                        &
+                XLBXRM,XLBXSVM,                                               &
+                XLBYUM,XLBYVM,XLBYWM,XLBYTHM,XLBYTKEM,                        &
+                XLBYRM,XLBYSVM,                                               &
+                NFRC,TDTFRC,XUFRC,XVFRC,XWFRC,XTHFRC,XRVFRC,                  &
+                XTENDTHFRC,XTENDRVFRC,XGXTHFRC,XGYTHFRC,                      &
+                XPGROUNDFRC, XATC,                                            &
+                XTENDUFRC, XTENDVFRC,                                         &
+                NADVFRC,TDTADVFRC,XDTHFRC,XDRVFRC,                            &
+                NRELFRC,TDTRELFRC,XTHREL,XRVREL,                              &
+                XVTH_FLUX_M,XWTH_FLUX_M,XVU_FLUX_M,                           &
+                XRUS_PRES,XRVS_PRES,XRWS_PRES,XRTHS_CLD,XRRS_CLD,XRSVS_CLD    )
+!
+!-------------------------------------------------------------------------------
+!
+!
+!*        10.  INITIALIZE REFERENCE STATE
+!              ---------------------------
+!
+!
+CALL SET_REF(KMI,TPINIFILE,                         &
+             XZZ,XZHAT,ZJ,XDXX,XDYY,CLBCX,CLBCY,    &
+             XREFMASS,XMASS_O_PHI0,XLINMASS,        &
+             XRHODREF,XTHVREF,XRVREF,XEXNREF,XRHODJ )
+!
+!-------------------------------------------------------------------------------
+!
+!*       10.1    INITIALIZE THE TURBULENCE VARIABLES
+!               -----------------------------------
+!
+IF ((CTURB == 'TKEL').AND.(CCONF=='START')) THEN
+  CALL MPPDB_CHECK3D(XUT,"INI_MODEL_N-before ini_tke_eps::XUT",PRECISION)
+  CALL INI_TKE_EPS(CGETTKET,XTHVREF,XZZ, &
+                   XUT,XVT,XTHT,                  &
+                   XTKET,TZINITHALO3D_ll    )
+  CALL MPPDB_CHECK3D(XUT,"INI_MODEL_N-after ini_tke_eps::XUT",PRECISION)
+END IF
+!
+!
+!*       10.2   INITIALIZE THE LES VARIABLES
+!               ----------------------------
+!
+CALL INI_LES_n
+!
+!-------------------------------------------------------------------------------
+!
+!*       11.    INITIALIZE THE SOURCE OF TOTAL DRY MASS Md
+!               ------------------------------------------
+!
+IF((KMI==1).AND.LSTEADYLS) THEN
+  XDRYMASSS = 0.
+END IF
+!
+!-------------------------------------------------------------------------------
+!
+!*       12.    INITIALIZE THE MICROPHYSICS                   
+!               ----------------------------
+!
+IF (CELEC == 'NONE') THEN
+  CALL INI_MICRO_n(TPINIFILE,ILUOUT)
+!
+!-------------------------------------------------------------------------------
+!
+!*       13.    INITIALIZE THE ATMOSPHERIC ELECTRICITY                   
+!               --------------------------------------
+!
+ELSE
+  CALL INI_ELEC_n(ILUOUT, CELEC, CCLOUD, TPINIFILE, &
+                  XTSTEP, XZZ,                      &
+                  XDXX, XDYY, XDZZ, XDZX, XDZY      )
+!
+  WRITE (UNIT=ILUOUT,&
+  FMT='(/,"ELECTRIC VARIABLES ARE BETWEEN INDEX",I2," AND ",I2)')&
+  NSV_ELECBEG, NSV_ELECEND
+! 
+    IF( CGETSVT(NSV_ELECBEG)=='INIT' ) THEN
+      XSVT(:,:,:,NSV_ELECBEG) = XCION_POS_FW(:,:,:)                  ! Nb/kg
+      XSVT(:,:,:,NSV_ELECEND) = XCION_NEG_FW(:,:,:)
+!
+      XSVT(:,:,:,NSV_ELECBEG+1:NSV_ELECEND-1) = 0.0
+    ELSE  ! Convert elec_variables per m3 into elec_variables per kg of air
+      DO JSV = NSV_ELECBEG, NSV_ELECEND
+         XSVT(:,:,:,JSV) = XSVT(:,:,:,JSV) / XRHODREF(:,:,:)
+      ENDDO
+    END IF
+END IF
+!
+!-------------------------------------------------------------------------------
+!
+!*       14.   INITIALIZE THE LARGE SCALE SOURCES
+!              ----------------------------------
+!
+IF ((KMI==1).AND.(.NOT. LSTEADYLS)) THEN
+  CALL MPPDB_CHECK3D(XUT,"INI_MODEL_N-before ini_cpl::XUT",PRECISION)
+  CALL INI_CPL(NSTOP,XTSTEP,LSTEADYLS,CCONF,                                  &
+               CGETTKET,                                                      &
+               CGETRVT,CGETRCT,CGETRRT,CGETRIT,                               &
+               CGETRST,CGETRGT,CGETRHT,CGETSVT,LCH_INIT_FIELD,                &
+               NSV,NIMAX_ll,NJMAX_ll,                                         &
+               NSIZELBX_ll,NSIZELBXU_ll,NSIZELBY_ll,NSIZELBYV_ll,             &
+               NSIZELBXTKE_ll,NSIZELBYTKE_ll,                                 &
+               NSIZELBXR_ll,NSIZELBYR_ll,NSIZELBXSV_ll,NSIZELBYSV_ll,         &
+               XLSUM,XLSVM,XLSWM,XLSTHM,XLSRVM,XLSZWSM,XDRYMASST,             &
+               XLBXUM,XLBXVM,XLBXWM,XLBXTHM,XLBXTKEM,XLBXRM,XLBXSVM,          &
+               XLBYUM,XLBYVM,XLBYWM,XLBYTHM,XLBYTKEM,XLBYRM,XLBYSVM,          &
+               XLSUS,XLSVS,XLSWS,XLSTHS,XLSRVS,XLSZWSS,XDRYMASSS,             &
+               XLBXUS,XLBXVS,XLBXWS,XLBXTHS,XLBXTKES,XLBXRS,XLBXSVS,          &
+               XLBYUS,XLBYVS,XLBYWS,XLBYTHS,XLBYTKES,XLBYRS,XLBYSVS           )
+  CALL MPPDB_CHECK3D(XUT,"INI_MODEL_N-after ini_cpl::XUT",PRECISION)
+!
+      DO JSV=NSV_CHEMBEG,NSV_CHEMEND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+      !
+      DO JSV=NSV_LNOXBEG,NSV_LNOXEND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+      !
+      DO JSV=NSV_AERBEG,NSV_AEREND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+      !
+      DO JSV=NSV_DSTBEG,NSV_DSTEND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+      !
+      DO JSV=NSV_DSTDEPBEG,NSV_DSTDEPEND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+      !
+      DO JSV=NSV_SLTBEG,NSV_SLTEND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+      !
+      DO JSV=NSV_SLTDEPBEG,NSV_SLTDEPEND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+      !
+      DO JSV=NSV_PPBEG,NSV_PPEND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+      !
+#ifdef MNH_FOREFIRE
+      DO JSV=NSV_FFBEG,NSV_FFEND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+      !
+#endif
+      DO JSV=NSV_CSBEG,NSV_CSEND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+!
+END IF
+ALLOCATE(XLSZWSM(IIU,IJU)) ; XLSZWSM = -1.
+!
+IF ( KMI > 1) THEN
+  ! Use dummy pointers to correct an ifort BUG
+  DPTR_XBMX1=>XBMX1
+  DPTR_XBMX2=>XBMX2
+  DPTR_XBMX3=>XBMX3
+  DPTR_XBMX4=>XBMX4
+  DPTR_XBMY1=>XBMY1
+  DPTR_XBMY2=>XBMY2
+  DPTR_XBMY3=>XBMY3
+  DPTR_XBMY4=>XBMY4
+  DPTR_XBFX1=>XBFX1
+  DPTR_XBFX2=>XBFX2
+  DPTR_XBFX3=>XBFX3
+  DPTR_XBFX4=>XBFX4
+  DPTR_XBFY1=>XBFY1
+  DPTR_XBFY2=>XBFY2
+  DPTR_XBFY3=>XBFY3
+  DPTR_XBFY4=>XBFY4
+  DPTR_CLBCX=>CLBCX
+  DPTR_CLBCY=>CLBCY
+  !
+  DPTR_XZZ=>XZZ
+  DPTR_XZHAT=>XZHAT
+  DPTR_XLSUM=>XLSUM
+  DPTR_XLSVM=>XLSVM
+  DPTR_XLSWM=>XLSWM
+  DPTR_XLSTHM=>XLSTHM
+  DPTR_XLSRVM=>XLSRVM
+  DPTR_XLSZWSM=>XLSZWSM
+  DPTR_XLSUS=>XLSUS
+  DPTR_XLSVS=>XLSVS
+  DPTR_XLSWS=>XLSWS
+  DPTR_XLSTHS=>XLSTHS
+  DPTR_XLSRVS=>XLSRVS
+  DPTR_XLSZWSS=>XLSZWSS
+  !
+  DPTR_NKLIN_LBXU=>NKLIN_LBXU
+  DPTR_XCOEFLIN_LBXU=>XCOEFLIN_LBXU
+  DPTR_NKLIN_LBYU=>NKLIN_LBYU
+  DPTR_XCOEFLIN_LBYU=>XCOEFLIN_LBYU
+  DPTR_NKLIN_LBXV=>NKLIN_LBXV
+  DPTR_XCOEFLIN_LBXV=>XCOEFLIN_LBXV
+  DPTR_NKLIN_LBYV=>NKLIN_LBYV
+  DPTR_XCOEFLIN_LBYV=>XCOEFLIN_LBYV
+  DPTR_NKLIN_LBXW=>NKLIN_LBXW
+  DPTR_XCOEFLIN_LBXW=>XCOEFLIN_LBXW
+  DPTR_NKLIN_LBYW=>NKLIN_LBYW
+  DPTR_XCOEFLIN_LBYW=>XCOEFLIN_LBYW
+  DPTR_NKLIN_LBXM=>NKLIN_LBXM
+  DPTR_XCOEFLIN_LBXM=>XCOEFLIN_LBXM
+  DPTR_NKLIN_LBYM=>NKLIN_LBYM
+  DPTR_XCOEFLIN_LBYM=>XCOEFLIN_LBYM
+  !
+  CALL INI_SPAWN_LS_n(NDAD(KMI),XTSTEP,KMI,                                 &
+       DPTR_XBMX1,DPTR_XBMX2,DPTR_XBMX3,DPTR_XBMX4,DPTR_XBMY1,DPTR_XBMY2,DPTR_XBMY3,DPTR_XBMY4,      &
+       DPTR_XBFX1,DPTR_XBFX2,DPTR_XBFX3,DPTR_XBFX4,DPTR_XBFY1,DPTR_XBFY2,DPTR_XBFY3,DPTR_XBFY4,      &
+       NDXRATIO_ALL(KMI),NDYRATIO_ALL(KMI),                  &
+       DPTR_CLBCX,DPTR_CLBCY,DPTR_XZZ,DPTR_XZHAT,                                &
+       LSLEVE,XLEN1,XLEN2,                                   &
+       DPTR_XLSUM,DPTR_XLSVM,DPTR_XLSWM,DPTR_XLSTHM,DPTR_XLSRVM,DPTR_XLSZWSM,         &
+       DPTR_XLSUS,DPTR_XLSVS,DPTR_XLSWS,DPTR_XLSTHS,DPTR_XLSRVS,DPTR_XLSZWSS,                      &       
+       DPTR_NKLIN_LBXU,DPTR_XCOEFLIN_LBXU,DPTR_NKLIN_LBYU,DPTR_XCOEFLIN_LBYU,    &
+       DPTR_NKLIN_LBXV,DPTR_XCOEFLIN_LBXV,DPTR_NKLIN_LBYV,DPTR_XCOEFLIN_LBYV,    &
+       DPTR_NKLIN_LBXW,DPTR_XCOEFLIN_LBXW,DPTR_NKLIN_LBYW,DPTR_XCOEFLIN_LBYW,    &
+       DPTR_NKLIN_LBXM,DPTR_XCOEFLIN_LBXM,DPTR_NKLIN_LBYM,DPTR_XCOEFLIN_LBYM     )
+  !
+  DPTR_XLBXUM=>XLBXUM
+  DPTR_XLBYUM=>XLBYUM
+  DPTR_XLBXVM=>XLBXVM
+  DPTR_XLBYVM=>XLBYVM
+  DPTR_XLBXWM=>XLBXWM
+  DPTR_XLBYWM=>XLBYWM
+  DPTR_XLBXTHM=>XLBXTHM
+  DPTR_XLBYTHM=>XLBYTHM
+  DPTR_XLBXTKEM=>XLBXTKEM
+  DPTR_XLBYTKEM=>XLBYTKEM
+  DPTR_XLBXRM=>XLBXRM
+  DPTR_XLBYRM=>XLBYRM
+  DPTR_XLBXSVM=>XLBXSVM
+  DPTR_XLBYSVM=>XLBYSVM
+  CALL INI_ONE_WAY_n(NDAD(KMI),KMI,                                                             &
+       DPTR_XBMX1,DPTR_XBMX2,DPTR_XBMX3,DPTR_XBMX4,DPTR_XBMY1,DPTR_XBMY2,DPTR_XBMY3,DPTR_XBMY4, &
+       DPTR_XBFX1,DPTR_XBFX2,DPTR_XBFX3,DPTR_XBFX4,DPTR_XBFY1,DPTR_XBFY2,DPTR_XBFY3,DPTR_XBFY4, &
+       NDXRATIO_ALL(KMI),NDYRATIO_ALL(KMI),                                                     &
+       DPTR_CLBCX,DPTR_CLBCY,NRIMX,NRIMY,                                                       &
+       DPTR_NKLIN_LBXU,DPTR_XCOEFLIN_LBXU,DPTR_NKLIN_LBYU,DPTR_XCOEFLIN_LBYU,                   &
+       DPTR_NKLIN_LBXV,DPTR_XCOEFLIN_LBXV,DPTR_NKLIN_LBYV,DPTR_XCOEFLIN_LBYV,                   &
+       DPTR_NKLIN_LBXW,DPTR_XCOEFLIN_LBXW,DPTR_NKLIN_LBYW,DPTR_XCOEFLIN_LBYW,                   &
+       DPTR_NKLIN_LBXM,DPTR_XCOEFLIN_LBXM,DPTR_NKLIN_LBYM,DPTR_XCOEFLIN_LBYM,                   &
+       CCLOUD, LUSECHAQ, LUSECHIC,                                                              &
+       DPTR_XLBXUM,DPTR_XLBYUM,DPTR_XLBXVM,DPTR_XLBYVM,DPTR_XLBXWM,DPTR_XLBYWM,                 &
+       DPTR_XLBXTHM,DPTR_XLBYTHM,                                                               &
+       DPTR_XLBXTKEM,DPTR_XLBYTKEM,                                                             &
+       DPTR_XLBXRM,DPTR_XLBYRM,DPTR_XLBXSVM,DPTR_XLBYSVM                                        )
+END IF
+!
+!
+!-------------------------------------------------------------------------------
+!
+!*       15.    INITIALIZE THE SCALAR VARIABLES
+!               -------------------------------
+!
+IF (LLG .AND. LINIT_LG .AND. CPROGRAM=='MESONH') &
+  CALL INI_LG(XXHAT,XYHAT,XZZ,XSVT,XLBXSVM,XLBYSVM)
+
+!
+!-------------------------------------------------------------------------------
+!
+!*       16.    INITIALIZE THE PARAMETERS FOR THE DYNAMICS
+!               ------------------------------------------
+!
+CALL INI_DYNAMICS(XLON,XLAT,XRHODJ,XTHVREF,XMAP,XZZ,XDXHAT,XDYHAT,            &
+             XZHAT,CLBCX,CLBCY,XTSTEP,CPRESOPT,                               &
+             LVE_RELAX,LVE_RELAX_GRD,LHORELAX_UVWTH,LHORELAX_RV,              &
+             LHORELAX_RC,LHORELAX_RR,LHORELAX_RI,LHORELAX_RS,LHORELAX_RG,     &
+             LHORELAX_RH,LHORELAX_TKE,LHORELAX_SV,                            &
+             LHORELAX_SVC2R2,LHORELAX_SVC1R3,LHORELAX_SVELEC,LHORELAX_SVLG,   &
+             LHORELAX_SVCHEM,LHORELAX_SVAER,LHORELAX_SVDST,LHORELAX_SVSLT,    &
+             LHORELAX_SVPP,LHORELAX_SVCS,LHORELAX_SVCHIC,LHORELAX_SVSNW,      &
+#ifdef MNH_FOREFIRE
+             LHORELAX_SVFF,                                                   &
+#endif
+             XRIMKMAX,NRIMX,NRIMY,                                            &
+             XALKTOP,XALKGRD,XALZBOT,XALZBAS,                                 &
+             XT4DIFU,XT4DIFTH,XT4DIFSV,                                       &
+             XCORIOX,XCORIOY,XCORIOZ,XCURVX,XCURVY,                           &
+             XDXHATM,XDYHATM,XRHOM,XAF,XBFY,XCF,XTRIGSX,XTRIGSY,NIFAXX,NIFAXY,&
+             XALK,XALKW,NALBOT,XALKBAS,XALKWBAS,NALBAS,                       &
+             LMASK_RELAX,XKURELAX,XKVRELAX,XKWRELAX,                          &
+             XDK2U,XDK4U,XDK2TH,XDK4TH,XDK2SV,XDK4SV,                         &
+             LZDIFFU,XZDIFFU_HALO2,                                           &
+             XBFB,XBF_SXP2_YP1_Z,                                             &
+             XAF_ZS,XBF_ZS,XCF_ZS,                                            &
+             XDXATH_ZS,XDYATH_ZS,XRHO_ZS,                                     &
+             XA_K,XB_K,XC_K,XD_K                                              ) 
+!
+!
+!*      16.1 Initialize the XDRAG array
+!              -------------
+IF (LDRAG) THEN
+   CALL INI_DRAG(LMOUNT,XZS,XHSTART,NSTART,XDRAG)
+ENDIF
+!-------------------------------------------------------------------------------
+!
+!*      17.    SURFACE FIELDS
+!              --------------
+!
+!*      17.1   Radiative setup
+!              ---------------
+!
+IF (CRAD   /= 'NONE') THEN
+  IF (CGETRAD =='INIT') THEN
+    GINIRAD  =.TRUE.
+  ELSE
+    GINIRAD  =.FALSE.
+  END IF
+  CALL INI_RADIATIONS(TPINIFILE,GINIRAD,TDTCUR,TDTEXP,XZZ, &
+                      XDXX, XDYY,                         &
+                      XSINDEL,XCOSDEL,XTSIDER,XCORSOL,    &
+                      XSLOPANG,XSLOPAZI,                  &
+                      XDTHRAD,XDIRFLASWD,XSCAFLASWD,      &
+                      XFLALWD,XDIRSRFSWD,NCLEARCOL_TM1,   &
+                      XZENITH,XAZIM,                      &
+                      TDTRAD_FULL,TDTRAD_CLONLY,          &
+                      TZINITHALO2D_ll,                    &
+                      XRADEFF,XSWU,XSWD,XLWU,             &
+                      XLWD,XDTHRADSW,XDTHRADLW           )
+  !
+  IF (GINIRAD) CALL SUNPOS_n(XZENITH,PAZIMSOL=XAZIM)
+  CALL SURF_SOLAR_GEOM    (XZS, XZS_XY)
+  !
+  ALLOCATE(XXHAT_ll                 (IIU_ll))
+  ALLOCATE(XYHAT_ll                 (IJU_ll))
+  ALLOCATE(XZS_ll                   (IIU_ll,IJU_ll))
+  ALLOCATE(XZS_XY_ll                (IIU_ll,IJU_ll))
+  !
+  CALL GATHERALL_FIELD_ll('XY',XZS,XZS_ll,IRESP)
+  CALL GATHERALL_FIELD_ll('XY',XZS_XY,XZS_XY_ll,IRESP)
+  CALL GATHERALL_FIELD_ll('XX',XXHAT,XXHAT_ll,IRESP)
+  CALL GATHERALL_FIELD_ll('YY',XYHAT,XYHAT_ll,IRESP)
+  XZS_MAX_ll=MAXVAL(XZS_ll)
+ELSE
+  XAZIM       = XPI
+  XZENITH     = XPI/2.
+  XDIRSRFSWD  = 0.
+  XSCAFLASWD  = 0.
+  XFLALWD     = 300.  ! W/m2
+  XTSIDER     = 0.
+END IF
+!
+!
+CALL INI_SW_SETUP (CRAD,NSWB_MNH,XSW_BANDS)
+CALL INI_LW_SETUP (CRAD,NLWB_MNH,XLW_BANDS)
+!
+!
+!       17.1.1 Special initialisation for CO2 content
+!              CO2 (molar mass=44) horizontally and vertically homogeneous at 360 ppm
+!
+XCCO2 = 360.0E-06 * 44.0E-03 / XMD
+#ifdef MNH_ECRAD
+RCCO2 = 360.0E-06 * 44.0E-03 / XMD
+#endif
+!
+!
+!*      17.2   Externalized surface fields
+!              ---------------------------
+!
+ALLOCATE(ZCO2(IIU,IJU))
+ZCO2(:,:) = XCCO2
+!
+
+ALLOCATE(ZDIR_ALB(IIU,IJU,NSWB_MNH))
+ALLOCATE(ZSCA_ALB(IIU,IJU,NSWB_MNH))
+ALLOCATE(ZEMIS  (IIU,IJU,NLWB_MNH))
+ALLOCATE(ZTSRAD (IIU,IJU))
+!
+IF ((TPINIFILE%NMNHVERSION(1)==4 .AND. TPINIFILE%NMNHVERSION(2)>=6) .OR. TPINIFILE%NMNHVERSION(1)>4) THEN
+  CALL IO_Field_read(TPINIFILE,'SURF',CSURF)
+ELSE
+  CSURF = "EXTE"
+END IF
+!
+!
+IF (CSURF=='EXTE' .AND. (CPROGRAM=='MESONH' .OR. CPROGRAM=='DIAG  ')) THEN
+  ! ouverture du fichier PGD
+  IF  ( LEN_TRIM(CINIFILEPGD) > 0 ) THEN
+    CALL IO_File_add2list(TINIFILEPGD,TRIM(CINIFILEPGD),'PGD','READ',KLFITYPE=2,KLFIVERB=NVERB)
+    CALL IO_File_open(TINIFILEPGD,KRESP=IRESP)
+    LUNIT_MODEL(KMI)%TINIFILEPGD => TINIFILEPGD
+    IF (IRESP/=0) THEN
+      WRITE(ILUOUT,FMT=*) "INI_MODEL_n ERROR TO OPEN THE FILE CINIFILEPGD=",CINIFILEPGD
+      WRITE(ILUOUT,FMT=*) "CHECK YOUR NAMELIST NAM_LUNITn"
+    !callabortstop
+      CALL PRINT_MSG(NVERB_FATAL,'GEN','INI_MODEL_n','')
+    ENDIF
+  ELSE
+  ! case after a spawning
+    CINIFILEPGD = TPINIFILE%CNAME
+  END IF
+  !
+  CALL GOTO_SURFEX(KMI)
+#ifdef CPLOASIS
+  CALL SFX_OASIS_READ_NAM(CPROGRAM,XTSTEP)
+  WRITE(*,*) 'SFX-OASIS: READ NAM_SFX_SEA_CPL OK'
+#endif
+  !* initialization of surface
+  CALL INIT_GROUND_PARAM_n ('ALL',SIZE(CSV),CSV,ZCO2,                             &
+                            XZENITH,XAZIM,XSW_BANDS,XLW_BANDS,ZDIR_ALB,ZSCA_ALB,  &
+                            ZEMIS,ZTSRAD                                )
+  !
+  IF (SIZE(XEMIS)>0) THEN
+    XDIR_ALB = ZDIR_ALB
+    XSCA_ALB = ZSCA_ALB
+    XEMIS    = ZEMIS
+    XTSRAD   = ZTSRAD
+    CALL MNHGET_SURF_PARAM_n (PSEA=XSEA)                          
+  END IF
+ELSE
+  !* fields not physically necessary, but must be initialized
+  IF (SIZE(XEMIS)>0) THEN
+    XDIR_ALB = 0.
+    XSCA_ALB = 0.
+    XEMIS    = 1.
+    XTSRAD   = XTT
+    XSEA     = 1.
+  END IF
+
+END IF
+IF (CSURF=='EXTE' .AND. (CPROGRAM=='SPAWN ')) THEN
+  ! ouverture du fichier PGD
+  CALL IO_File_add2list(TINIFILEPGD,TRIM(CINIFILEPGD),'PGD','READ',KLFITYPE=2,KLFIVERB=NVERB)
+  CALL IO_File_open(TINIFILEPGD,KRESP=IRESP)
+  LUNIT_MODEL(KMI)%TINIFILEPGD => TINIFILEPGD
+  IF (IRESP/=0) THEN
+    WRITE(ILUOUT,FMT=*) "INI_MODEL_n ERROR TO OPEN THE FILE CINIFILEPGD=",CINIFILEPGD
+    WRITE(ILUOUT,FMT=*) "CHECK YOUR NAMELIST NAM_LUNIT2_SPA"
+    !callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','INI_MODEL_n','')
+  ENDIF
+ENDIF
+!
+IF (.NOT.ASSOCIATED(TINIFILEPGD)) TINIFILEPGD => TFILE_DUMMY
+!
+  !* special case after spawning in prep_real_case
+IF (CSURF=='EXRM' .AND. CPROGRAM=='REAL  ') CSURF = 'EXTE'
+!
+DEALLOCATE(ZDIR_ALB)
+DEALLOCATE(ZSCA_ALB)
+DEALLOCATE(ZEMIS   )
+DEALLOCATE(ZTSRAD  )
+!
+DEALLOCATE(ZCO2)
+!
+!
+!* in a RESTART case, reads surface radiative quantities in the MESONH file
+!
+IF ((CRAD  == 'ECMW' .OR. CRAD  == 'ECRA') .AND. CGETRAD=='READ') THEN
+  CALL INI_SURF_RAD(TPINIFILE, XDIR_ALB, XSCA_ALB, XEMIS, XTSRAD)
+END IF
+!
+!
+!*      17.3   Mesonh fields
+!              -------------
+!
+IF (CPROGRAM/='REAL  ') CALL MNHREAD_ZS_DUMMY_n(TINIFILEPGD)
+!
+!-------------------------------------------------------------------------------
+!
+!*       18.    INITIALIZE THE PARAMETERS FOR THE PHYSICS
+!               -----------------------------------------
+!
+IF (CRAD   == 'ECMW') THEN
+!
+!* get cover mask for aerosols
+!
+  IF (CPROGRAM=='MESONH' .OR. CPROGRAM=='DIAG  ') THEN
+    ALLOCATE(ZSEA(IIU,IJU))
+    ALLOCATE(ZTOWN(IIU,IJU))
+    ALLOCATE(ZBARE(IIU,IJU))
+    IF (CSURF=='EXTE') THEN
+      CALL GOTO_SURFEX(KMI)
+      CALL MNHGET_SURF_PARAM_n(PSEA=ZSEA,PTOWN=ZTOWN,PBARE=ZBARE)
+    ELSE
+      ZSEA (:,:) = 1.
+      ZTOWN(:,:) = 0.
+      ZBARE(:,:) = 0.
+    END IF
+!
+    IF ( CAOP=='EXPL' .AND. LDUST ) THEN
+      ALLOCATE( XEXT_COEFF_WVL_LKT_DUST( NMAX_RADIUS_LKT_DUST, NMAX_SIGMA_LKT_DUST, NMAX_WVL_SW_DUST ) )
+      ALLOCATE( XEXT_COEFF_550_LKT_DUST( NMAX_RADIUS_LKT_DUST, NMAX_SIGMA_LKT_DUST )                   )
+      ALLOCATE( XPIZA_LKT_DUST         ( NMAX_RADIUS_LKT_DUST, NMAX_SIGMA_LKT_DUST, NMAX_WVL_SW_DUST ) )
+      ALLOCATE( XCGA_LKT_DUST          ( NMAX_RADIUS_LKT_DUST, NMAX_SIGMA_LKT_DUST, NMAX_WVL_SW_DUST ) )
+    END IF
+!
+    IF ( CAOP=='EXPL' .AND. LSALT ) THEN
+      ALLOCATE( XEXT_COEFF_WVL_LKT_SALT( NMAX_RADIUS_LKT_SALT, NMAX_SIGMA_LKT_SALT, NMAX_WVL_SW_SALT ) )
+      ALLOCATE( XEXT_COEFF_550_LKT_SALT( NMAX_RADIUS_LKT_SALT, NMAX_SIGMA_LKT_SALT )                   )
+      ALLOCATE( XPIZA_LKT_SALT         ( NMAX_RADIUS_LKT_SALT, NMAX_SIGMA_LKT_SALT, NMAX_WVL_SW_SALT ) )
+      ALLOCATE( XCGA_LKT_SALT          ( NMAX_RADIUS_LKT_SALT, NMAX_SIGMA_LKT_SALT, NMAX_WVL_SW_SALT ) )
+    END IF
+!
+    CALL INI_RADIATIONS_ECMWF (XZHAT,XPABST,XTHT,XTSRAD,XLAT,XLON,TDTCUR,TDTEXP,       &
+                               CLW,NDLON,NFLEV,NFLUX,NRAD,NSWB_OLD,CAER,NAER,NSTATM,   &
+                               XSTATM,ZSEA,ZTOWN,ZBARE,XOZON, XAER,XDST_WL, LSUBG_COND )
+!
+    DEALLOCATE(ZSEA,ZTOWN,ZBARE)
+    ALLOCATE (XAER_CLIM(SIZE(XAER,1),SIZE(XAER,2),SIZE(XAER,3),SIZE(XAER,4)))
+    XAER_CLIM(:,:,:,:) =XAER(:,:,:,:)
+!
+  END IF
+
+ELSE IF (CRAD   == 'ECRA') THEN
+#ifdef MNH_ECRAD
+!* get cover mask for aerosols
+!
+  IF (CPROGRAM=='MESONH' .OR. CPROGRAM=='DIAG  ') THEN
+    ALLOCATE(ZSEA(IIU,IJU))
+    ALLOCATE(ZTOWN(IIU,IJU))
+    ALLOCATE(ZBARE(IIU,IJU))
+    IF (CSURF=='EXTE') THEN
+      CALL GOTO_SURFEX(KMI)
+      CALL MNHGET_SURF_PARAM_n(PSEA=ZSEA,PTOWN=ZTOWN,PBARE=ZBARE)
+    ELSE
+      ZSEA (:,:) = 1.
+      ZTOWN(:,:) = 0.
+      ZBARE(:,:) = 0.
+    END IF
+!
+    CALL INI_RADIATIONS_ECRAD (XZHAT,XPABST,XTHT,XTSRAD,XLAT,XLON,TDTCUR,TDTEXP,       &
+                               CLW,NDLON,NFLEV,NFLUX,NRAD,NSWB_OLD,CAER,NAER,NSTATM,   &
+                               XSTATM,ZSEA,ZTOWN,ZBARE,XOZON, XAER,XDST_WL, LSUBG_COND )
+
+    DEALLOCATE(ZSEA,ZTOWN,ZBARE)
+    ALLOCATE (XAER_CLIM(SIZE(XAER,1),SIZE(XAER,2),SIZE(XAER,3),SIZE(XAER,4)))
+    XAER_CLIM(:,:,:,:) = XAER(:,:,:,:)
+!
+  END IF
+#endif
+ELSE
+  ALLOCATE (XOZON(0,0,0))
+  ALLOCATE (XAER(0,0,0,0))
+  ALLOCATE (XDST_WL(0,0,0,0))
+  ALLOCATE (XAER_CLIM(0,0,0,0))  
+END IF
+!
+!
+!
+IF (CDCONV /= 'NONE' .OR. CSCONV == 'KAFR') THEN
+  IF (CGETCONV=='INIT') THEN
+    GINIDCONV=.TRUE.
+  ELSE
+    GINIDCONV=.FALSE.
+  END IF
+!
+!  commensurability between convection calling time and time step
+!
+  XDTCONV=XTSTEP*REAL( INT( (MIN(XDTCONV,1800.)+1.E-10)/XTSTEP ) )
+  XDTCONV=MAX( XDTCONV, XTSTEP )
+  IF (NVERB>=10) THEN
+    WRITE(ILUOUT,*) 'XDTCONV has been set to : ',XDTCONV
+  END IF
+  CALL INI_DEEP_CONVECTION (TPINIFILE,GINIDCONV,TDTCUR,                      &
+                           NCOUNTCONV,XDTHCONV,XDRVCONV,XDRCCONV,            &
+                           XDRICONV,XPRCONV,XPRSCONV,XPACCONV,               &
+                           XUMFCONV,XDMFCONV,XMFCONV,XPRLFLXCONV,XPRSFLXCONV,&
+                           XCAPE,NCLTOPCONV,NCLBASCONV,                      &
+                           TDTDCONV, CGETSVCONV, XDSVCONV,                   &
+                           LCH_CONV_LINOX, XIC_RATE, XCG_RATE,               &
+                           XIC_TOTAL_NUMBER, XCG_TOTAL_NUMBER                )
+
+END IF
+!
+!-------------------------------------------------------------------------------
+!
+!
+!*      19.    ALLOCATION OF THE TEMPORAL SERIES
+!              ---------------------------------
+!
+IF (LSERIES .AND. CPROGRAM/='DIAG  ') CALL INI_SERIES_n
+!
+!-------------------------------------------------------------------------------
+!
+!
+!*      20.   (re)initialize scalar variables
+!             -------------------------------
+!
+!
+IF ( LUSECHEM .OR. LCHEMDIAG ) THEN
+  IF (CPROGRAM=='MESONH'.AND.CCONF=='RESTA') LCH_INIT_FIELD =.FALSE.
+  IF (CPROGRAM=='MESONH'.OR. CPROGRAM=='DIAG  ' .OR. CPROGRAM=='IDEAL ') &
+        CALL CH_INIT_FIELD_n(KMI, ILUOUT, NVERB)
+END IF
+!
+!-------------------------------------------------------------------------------
+!
+!*      21.    UPDATE HALO
+!              -----------
+!
+!
+CALL UPDATE_HALO_ll(TZINITHALO3D_ll,IINFO_ll)
+CALL UPDATE_HALO_ll(TZINITHALO2D_ll,IINFO_ll)
+CALL CLEANLIST_ll(TZINITHALO3D_ll)
+CALL CLEANLIST_ll(TZINITHALO2D_ll)
+!
+!
+!-------------------------------------------------------------------------------
+!
+!*      22.    DEALLOCATION
+!              -------------
+!
+DEALLOCATE(ZJ)
+!
+DEALLOCATE(XSTROATM)
+DEALLOCATE(XSMLSATM)
+DEALLOCATE(XSMLWATM)
+DEALLOCATE(XSPOSATM)
+DEALLOCATE(XSPOWATM)
+!
+!-------------------------------------------------------------------------------
+!
+!*      23.     BALLOON and AIRCRAFT initializations
+!              ------------------------------------
+!
+CALL INI_AIRCRAFT_BALLOON(TPINIFILE,XTSTEP, TDTSEG, XSEGLEN, NRR, NSV, &
+                          IKU,CTURB=="TKEL" ,                          &
+                          XLATORI, XLONORI                             )
+!
+!-------------------------------------------------------------------------------
+!
+!*      24.     STATION initializations
+!              -----------------------
+!
+CALL INI_SURFSTATION_n(XTSTEP, TDTSEG, XSEGLEN, NRR, NSV, &
+                       CTURB=="TKEL" ,                    &
+                       XLATORI, XLONORI                   )
+!
+!-------------------------------------------------------------------------------
+!
+!*      25.     PROFILER initializations
+!              ------------------------
+!
+CALL INI_POSPROFILER_n(XTSTEP, TDTSEG, XSEGLEN, NRR, NSV,  &
+                       CTURB=="TKEL",                      &
+                       XLATORI, XLONORI                    )
+!
+!-------------------------------------------------------------------------------
+!
+!*      26.     Prognostic aerosols          
+!              ------------------------
+!
+IF ( ( CRAD=='ECMW' .OR. CRAD=='ECRA' ) .AND. CAOP=='EXPL' .AND. LORILAM ) THEN
+  ALLOCATE(POLYTAU(6,10,8,6,13))
+  ALLOCATE(POLYSSA(6,10,8,6,13))
+  ALLOCATE(POLYG  (6,10,8,6,13))
+  CALL INI_AEROSET1
+  CALL INI_AEROSET2
+  CALL INI_AEROSET3
+  CALL INI_AEROSET4
+  CALL INI_AEROSET5
+  CALL INI_AEROSET6
+END IF
+#ifdef MNH_FOREFIRE
+! 
+!-------------------------------------------------------------------------------
+!
+!*      27.    FOREFIRE initializations
+!              ------------------------
+!
+
+! Coupling with ForeFire if resolution is low enough
+!---------------------------------------------------
+IF ( LFOREFIRE .AND. 0.5*(XXHAT(2)-XXHAT(1)+XYHAT(2)-XYHAT(1)) < COUPLINGRES ) THEN
+  FFCOUPLING = .TRUE.
+ELSE
+  FFCOUPLING = .FALSE.
+ENDIF
+
+! Initializing the ForeFire variables
+!------------------------------------
+IF ( LFOREFIRE ) THEN
+  CALL INIT_FOREFIRE_n(KMI, ILUOUT, IP &
+        , TDTCUR%TDATE%YEAR, TDTCUR%TDATE%MONTH, TDTCUR%TDATE%DAY, TDTCUR%TIME, XTSTEP)
+END IF
+#endif
+
+!-------------------------------------------------------------------------------
+!
+!*      30.   Total production/Loss for chemical species
+!
+IF (LCHEMDIAG)  THEN
+  CALL CH_INIT_PRODLOSSTOT_n(ILUOUT)
+  IF (NEQ_PLT>0) THEN
+    ALLOCATE(XPROD(IIU,IJU,IKU,NEQ_PLT))
+    ALLOCATE(XLOSS(IIU,IJU,IKU,NEQ_PLT))
+    XPROD=0.0
+    XLOSS=0.0
+  ELSE
+    ALLOCATE(XPROD(0,0,0,0))
+    ALLOCATE(XLOSS(0,0,0,0))
+  END IF
+ELSE
+  ALLOCATE(XPROD(0,0,0,0))
+  ALLOCATE(XLOSS(0,0,0,0))
+END IF
+!
+!-------------------------------------------------------------------------------
+!
+!*     31. Extended production/loss terms for chemical species
+!
+IF (LCHEMDIAG) THEN
+  CALL CH_INIT_BUDGET_n(ILUOUT)
+  IF (NEQ_BUDGET>0) THEN
+    ALLOCATE(IINDEX(2,NNONZEROTERMS))
+    ALLOCATE(IIND(NEQ_BUDGET))
+    CALL CH_NONZEROTERMS(KMI,IINDEX,NNONZEROTERMS)
+    ALLOCATE(XTCHEM(NEQ_BUDGET))
+    DO JM=1,NEQ_BUDGET
+      IIND(JM)=COUNT((IINDEX(1,:))==NSPEC_BUDGET(JM))
+      ALLOCATE(XTCHEM(JM)%NB_REAC(IIND(JM)))
+      ALLOCATE(XTCHEM(JM)%XB_REAC(IIU,IJU,IKU,IIND(JM)))
+    END DO
+    DEALLOCATE(IIND)
+    DEALLOCATE(IINDEX)
+  ELSE
+    ALLOCATE(XTCHEM(0))
+  END IF
+ELSE
+  ALLOCATE(XTCHEM(0))
+END IF
+
+END SUBROUTINE INI_MODEL_n
+
diff --git a/src/ZSOLVER/ini_spectren.f90 b/src/ZSOLVER/ini_spectren.f90
new file mode 100644
index 0000000000000000000000000000000000000000..4783443207ecf52aa183b97da09c2f4014f94b58
--- /dev/null
+++ b/src/ZSOLVER/ini_spectren.f90
@@ -0,0 +1,941 @@
+!MNH_LIC Copyright 2015-2019 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+!     #######################
+      MODULE MODI_INI_SPECTRE_n
+!     #######################
+!
+INTERFACE
+!
+       SUBROUTINE INI_SPECTRE_n(KMI,TPINIFILE)
+!
+       USE MODD_IO, ONLY: TFILEDATA
+!
+       INTEGER,           INTENT(IN) :: KMI       ! Model index 
+       TYPE(TFILEDATA),   INTENT(IN) :: TPINIFILE ! Initial file
+!
+END SUBROUTINE INI_SPECTRE_n
+!
+END INTERFACE
+!
+END MODULE MODI_INI_SPECTRE_n
+!     #######################################
+      SUBROUTINE INI_SPECTRE_n(KMI,TPINIFILE)
+!     #######################################
+!
+!!****  *INI_SPECTRE_n* - routine to initialize SPECTRE (based on ini_modeln.f90)
+!!
+!!
+!!    AUTHOR
+!!    ------
+!!      J.P Chaboureau       * L.A*
+!!      10/2016 (C.Lac) Cleaning of the modules
+!!  Philippe Wautelet: 05/2016-04/2018: new data structures and calls for I/O
+!  P. Wautelet 08/02/2019: allocate to zero-size non associated pointers
+!  P. Wautelet 14/02/2019: remove CLUOUT/CLUOUT0 and associated variables
+!  S. Bielli      02/2019: sea salt: significant sea wave height influences salt emission; 5 salt modes
+!  P. Wautelet 10/04/2019: replace ABORT and STOP calls by Print_msg
+!  P. Wautelet 19/04/2019: removed unused dummy arguments and variables
+!
+!---------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+!
+USE MODD_ADV_n
+USE MODD_ARGSLIST_ll,   ONLY: LIST_ll
+USE MODD_BIKHARDT_n
+USE MODD_BUDGET
+USE MODD_CH_MNHC_n,     ONLY: LUSECHAQ, LUSECHIC, LCH_INIT_FIELD
+USE MODD_CH_PH_n
+USE MODD_CLOUD_MF_n
+USE MODD_CST
+USE MODD_CONF
+USE MODD_CONF_n
+USE MODD_CTURB
+USE MODD_CURVCOR_n
+USE MODD_DEEP_CONVECTION_n
+USE MODD_DIM_n
+USE MODD_DRAGTREE
+USE MODD_DUST
+USE MODD_DYN
+USE MODD_DYN_n
+USE MODD_DYNZD
+USE MODD_DYNZD_n
+USE MODD_FIELD_n
+USE MODD_FRC
+USE MODD_FRC_n
+USE MODD_GET_n
+USE MODD_GRID,          ONLY: XLONORI,XLATORI
+USE MODD_GRID_n
+USE MODD_IO,            ONLY: TFILEDATA
+USE MODD_LBC_n,         only: CLBCX, CLBCY
+USE MODD_LSFIELD_n
+USE MODD_LUNIT_n,       ONLY: COUTFILE, TLUOUT
+USE MODD_MEAN_FIELD
+USE MODD_MEAN_FIELD_n
+USE MODD_METRICS_n
+USE MODD_NESTING,       only: NDAD, NDT_2_WAY, NDXRATIO_ALL, NDYRATIO_ALL
+USE MODD_NSV
+USE MODD_OUT_n
+USE MODD_PARAMETERS
+USE MODD_PARAM_KAFR_n
+USE MODD_PARAM_MFSHALL_n
+USE MODD_PARAM_n
+USE MODD_PASPOL
+USE MODD_PASPOL_n
+USE MODD_BLOWSNOW
+USE MODD_BLOWSNOW_n
+USE MODD_PAST_FIELD_n
+USE MODD_RADIATIONS_n
+USE MODD_REF
+USE MODD_REF_n
+USE MODD_SHADOWS_n
+USE MODD_SPECTRE
+USE MODD_TIME
+USE MODD_TIME_n
+USE MODD_TURB_n
+USE MODD_VAR_ll,        ONLY: IP
+!
+USE MODE_GATHER_ll
+USE MODE_INI_ONE_WAY_n
+USE MODE_IO_FIELD_READ, only: IO_Field_read
+USE MODE_ll
+USE MODE_MODELN_HANDLER
+USE MODE_MSG
+USE MODE_SPLITTINGZ_ll, ONLY: GET_DIM_EXTZ_ll
+USE MODE_TYPE_ZDIFFU
+!
+USE MODI_INI_BIKHARDT_n
+USE MODI_INI_CPL
+USE MODI_INI_DYNAMICS
+USE MODI_INI_SPAWN_LS_n
+USE MODI_GET_SIZEX_LB
+USE MODI_GET_SIZEY_LB
+USE MODI_SET_GRID
+USE MODI_METRICS
+USE MODI_SET_REF
+USE MODI_UPDATE_METRICS
+USE MODI_UPDATE_NSV
+!
+IMPLICIT NONE
+!
+!*       0.1   declarations of arguments
+!
+!
+INTEGER,           INTENT(IN) :: KMI       ! Model index 
+TYPE(TFILEDATA),   INTENT(IN) :: TPINIFILE ! Initial file
+!
+!*       0.2   declarations of local variables
+!
+INTEGER             :: ILUOUT  ! Logical unit number of output-listing
+INTEGER             :: IIU     ! Upper dimension in x direction (local)
+INTEGER             :: IJU     ! Upper dimension in y direction (local)
+INTEGER             :: IIU_ll  ! Upper dimension in x direction (global)
+INTEGER             :: IJU_ll  ! Upper dimension in y direction (global)
+INTEGER             :: IKU     ! Upper dimension in z direction
+REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZJ ! Jacobian
+!
+!
+TYPE(LIST_ll), POINTER :: TZINITHALO2D_ll ! pointer for the list of 2D fields
+                                      !  which must be communicated in INIT
+TYPE(LIST_ll), POINTER :: TZINITHALO3D_ll ! pointer for the list of 3D fields
+                                      !  which must be communicated in INIT
+!
+INTEGER :: IISIZEXF,IJSIZEXF,IISIZEXFU,IJSIZEXFU     ! dimensions of the
+INTEGER :: IISIZEX4,IJSIZEX4,IISIZEX2,IJSIZEX2       ! West-east LB arrays
+INTEGER :: IISIZEYF,IJSIZEYF,IISIZEYFV,IJSIZEYFV     ! dimensions of the
+INTEGER :: IISIZEY4,IJSIZEY4,IISIZEY2,IJSIZEY2       ! North-south LB arrays
+INTEGER :: IINFO_ll  ! Return code of //routines
+INTEGER :: IIY,IJY
+INTEGER :: IIU_B,IJU_B
+INTEGER :: IIU_SXP2_YP1_Z_ll,IJU_SXP2_YP1_Z_ll,IKU_SXP2_YP1_Z_ll
+!
+!------------------------------------------
+! Dummy pointers needed to correct an ifort Bug
+REAL, DIMENSION(:), POINTER :: DPTR_XZHAT
+REAL, DIMENSION(:), POINTER :: DPTR_XBMX1,DPTR_XBMX2,DPTR_XBMX3,DPTR_XBMX4
+REAL, DIMENSION(:), POINTER :: DPTR_XBMY1,DPTR_XBMY2,DPTR_XBMY3,DPTR_XBMY4
+REAL, DIMENSION(:), POINTER :: DPTR_XBFX1,DPTR_XBFX2,DPTR_XBFX3,DPTR_XBFX4
+REAL, DIMENSION(:), POINTER :: DPTR_XBFY1,DPTR_XBFY2,DPTR_XBFY3,DPTR_XBFY4
+CHARACTER(LEN=4), DIMENSION(:), POINTER :: DPTR_CLBCX,DPTR_CLBCY
+INTEGER, DIMENSION(:,:,:), POINTER :: DPTR_NKLIN_LBXU,DPTR_NKLIN_LBYU,DPTR_NKLIN_LBXV,DPTR_NKLIN_LBYV
+INTEGER, DIMENSION(:,:,:), POINTER :: DPTR_NKLIN_LBXW,DPTR_NKLIN_LBYW,DPTR_NKLIN_LBXM,DPTR_NKLIN_LBYM
+REAL, DIMENSION(:,:,:), POINTER :: DPTR_XCOEFLIN_LBXU,DPTR_XCOEFLIN_LBYU
+REAL, DIMENSION(:,:,:), POINTER :: DPTR_XCOEFLIN_LBXV,DPTR_XCOEFLIN_LBYV
+REAL, DIMENSION(:,:,:), POINTER :: DPTR_XCOEFLIN_LBXW,DPTR_XCOEFLIN_LBYW
+REAL, DIMENSION(:,:,:), POINTER :: DPTR_XCOEFLIN_LBXM,DPTR_XCOEFLIN_LBYM
+REAL, DIMENSION(:,:,:),   POINTER :: DPTR_XLBXUM,DPTR_XLBYUM,DPTR_XLBXVM,DPTR_XLBYVM
+REAL, DIMENSION(:,:,:),   POINTER :: DPTR_XLBXWM,DPTR_XLBYWM,DPTR_XLBXTHM,DPTR_XLBYTHM
+REAL, DIMENSION(:,:,:),   POINTER :: DPTR_XLBXTKEM,DPTR_XLBYTKEM
+REAL, DIMENSION(:,:,:,:),   POINTER :: DPTR_XLBXSVM,DPTR_XLBYSVM                
+REAL, DIMENSION(:,:,:,:), POINTER :: DPTR_XLBXRM,DPTR_XLBYRM
+REAL, DIMENSION(:,:,:),   POINTER ::  DPTR_XZZ
+REAL, DIMENSION(:,:,:), POINTER ::   DPTR_XLSUM,DPTR_XLSVM,DPTR_XLSWM,DPTR_XLSTHM,DPTR_XLSRVM
+REAL, DIMENSION(:,:,:), POINTER ::   DPTR_XLSUS,DPTR_XLSVS,DPTR_XLSWS,DPTR_XLSTHS,DPTR_XLSRVS
+REAL, DIMENSION(:,:),   POINTER ::   DPTR_XLSZWSS,DPTR_XLSZWSM
+!
+!-------------------------------------------------------------------------------
+!
+!*       0.    PROLOGUE
+!              --------
+!
+NULLIFY(TZINITHALO2D_ll)
+NULLIFY(TZINITHALO3D_ll)
+!
+!*       1.    RETRIEVE LOGICAL UNIT NUMBER
+!              ----------------------------
+!
+ILUOUT = TLUOUT%NLU
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.   END OF READING
+!             --------------
+!*       2.1  Read number of forcing fields
+!
+!*       2.2  Checks the position of vertical absorbing layer
+!
+IKU=NKMAX+2*JPVEXT
+!
+ALLOCATE(XZHAT(IKU))
+CALL IO_Field_read(TPINIFILE,'ZHAT',XZHAT)
+CALL IO_Field_read(TPINIFILE,'ZTOP',XZTOP)
+IF (XALZBOT>=XZHAT(IKU) .AND. LVE_RELAX) THEN
+  WRITE(ILUOUT,FMT=*) "INI_SPECTRE_n ERROR: you want to use vertical relaxation"
+  WRITE(ILUOUT,FMT=*) "                  but bottom of layer XALZBOT(",XALZBOT,")"
+  WRITE(ILUOUT,FMT=*) "                  is upper than model top    (",XZHAT(IKU),")"
+!callabortstop
+  CALL PRINT_MSG(NVERB_FATAL,'GEN','INI_SPECTRE_n','')
+END IF
+IF (LVE_RELAX) THEN
+ IF (XALZBOT>=XZHAT(IKU-4) ) THEN
+  WRITE(ILUOUT,FMT=*) "INI_SPECTRE_n WARNING: you want to use vertical relaxation"
+  WRITE(ILUOUT,FMT=*) "                    but the layer defined by XALZBOT(",XALZBOT,")"
+  WRITE(ILUOUT,FMT=*) "                    contains less than 5 model levels"
+ END IF
+END IF
+DEALLOCATE(XZHAT)
+!
+!*       2.3  Compute sizes of arrays of the extended sub-domain
+!
+CALL GET_DIM_EXT_ll('B',IIU,IJU)
+IIU_ll=NIMAX_ll + 2 * JPHEXT
+IJU_ll=NJMAX_ll + 2 * JPHEXT
+! initialize NIMAX and NJMAX for not updated versions regarding the parallelism
+! spawning,...
+CALL GET_DIM_PHYS_ll('B',NIMAX,NJMAX)
+!
+NRR=1
+NRRL=0
+NRRI=0
+IF (NVERB >= 5) THEN
+  WRITE (UNIT=ILUOUT,FMT='("THERE ARE ",I2," WATER VARIABLES")') NRR
+  WRITE (UNIT=ILUOUT,FMT='("THERE ARE ",I2," LIQUID VARIABLES")') NRRL
+  WRITE (UNIT=ILUOUT,FMT='("THERE ARE ",I2," SOLID VARIABLES")') NRRI
+END IF
+!
+!*       2.3  Update NSV and floating indices for the current model
+!
+! 
+CALL UPDATE_NSV(KMI) 
+!
+!-------------------------------------------------------------------------------
+!
+!*       3.    ALLOCATE  MEMORY
+!              -----------------
+!
+!*       3.2   Module MODD_GRID_n and MODD_METRICS_n
+!
+IF (LCARTESIAN) THEN
+  ALLOCATE(XLON(0,0))
+  ALLOCATE(XLAT(0,0))
+  ALLOCATE(XMAP(0,0))
+ELSE
+  ALLOCATE(XLON(IIU,IJU))
+  ALLOCATE(XLAT(IIU,IJU))
+  ALLOCATE(XMAP(IIU,IJU))
+END IF
+ALLOCATE(XXHAT(IIU))
+ALLOCATE(XDXHAT(IIU))
+ALLOCATE(XYHAT(IJU))
+ALLOCATE(XDYHAT(IJU))
+ALLOCATE(XZS(IIU,IJU))
+ALLOCATE(XZSMT(IIU,IJU))
+ALLOCATE(XZZ(IIU,IJU,IKU))
+ALLOCATE(XZHAT(IKU))
+!
+ALLOCATE(XDXX(IIU,IJU,IKU))
+ALLOCATE(XDYY(IIU,IJU,IKU))
+ALLOCATE(XDZX(IIU,IJU,IKU))
+ALLOCATE(XDZY(IIU,IJU,IKU))
+ALLOCATE(XDZZ(IIU,IJU,IKU))
+!
+!*       3.3   Modules MODD_REF and  MODD_REF_n
+!
+IF (KMI == 1) THEN
+  ALLOCATE(XRHODREFZ(IKU),XTHVREFZ(IKU))
+END IF
+ALLOCATE(XRHODREF(IIU,IJU,IKU))
+ALLOCATE(XTHVREF(IIU,IJU,IKU))
+ALLOCATE(XEXNREF(IIU,IJU,IKU))
+ALLOCATE(XRHODJ(IIU,IJU,IKU))
+IF (CEQNSYS=='DUR' .AND. LUSERV) THEN
+  ALLOCATE(XRVREF(IIU,IJU,IKU))
+ELSE
+  ALLOCATE(XRVREF(0,0,0))
+END IF
+!
+!*       3.4   Module MODD_CURVCOR_n
+!
+IF (LTHINSHELL) THEN
+  ALLOCATE(XCORIOX(0,0))
+  ALLOCATE(XCORIOY(0,0))
+ELSE
+  ALLOCATE(XCORIOX(IIU,IJU))
+  ALLOCATE(XCORIOY(IIU,IJU))
+END IF
+  ALLOCATE(XCORIOZ(IIU,IJU))
+IF (LCARTESIAN) THEN
+  ALLOCATE(XCURVX(0,0))
+  ALLOCATE(XCURVY(0,0))
+ELSE
+  ALLOCATE(XCURVX(IIU,IJU))
+  ALLOCATE(XCURVY(IIU,IJU))
+END IF
+!
+!*       3.5   Module MODD_DYN_n
+!
+CALL GET_DIM_EXT_ll('Y',IIY,IJY)
+IF (L2D) THEN
+  ALLOCATE(XBFY(IIY,IJY,IKU))
+ELSE
+  ALLOCATE(XBFY(IJY,IIY,IKU)) ! transposition needed by the optimisition of the
+                              ! FFT solver
+END IF
+CALL GET_DIM_EXT_ll('B',IIU_B,IJU_B)
+ALLOCATE(XBFB(IIU_B,IJU_B,IKU))
+CALL GET_DIM_EXTZ_ll('SXP2_YP1_Z',IIU_SXP2_YP1_Z_ll,IJU_SXP2_YP1_Z_ll,IKU_SXP2_YP1_Z_ll)
+ALLOCATE(XBF_SXP2_YP1_Z(IIU_SXP2_YP1_Z_ll,IJU_SXP2_YP1_Z_ll,IKU_SXP2_YP1_Z_ll))
+ALLOCATE(XAF(IKU),XCF(IKU))
+ALLOCATE(XTRIGSX(3*IIU_ll))
+ALLOCATE(XTRIGSY(3*IJU_ll))
+ALLOCATE(XRHOM(IKU))
+ALLOCATE(XALK(IKU))
+ALLOCATE(XALKW(IKU))
+!
+IF ( LHORELAX_UVWTH .OR. LHORELAX_RV .OR.                                  &
+     LHORELAX_RC .OR. LHORELAX_RR .OR. LHORELAX_RI  .OR. LHORELAX_RS  .OR. &
+     LHORELAX_RG .OR. LHORELAX_RH .OR. LHORELAX_TKE .OR.                   &
+     ANY(LHORELAX_SV) ) THEN
+  ALLOCATE(XKURELAX(IIU,IJU))
+  ALLOCATE(XKVRELAX(IIU,IJU))
+  ALLOCATE(XKWRELAX(IIU,IJU))
+  ALLOCATE(LMASK_RELAX(IIU,IJU))
+ELSE
+  ALLOCATE(XKURELAX(0,0))
+  ALLOCATE(XKVRELAX(0,0))
+  ALLOCATE(XKWRELAX(0,0))
+  ALLOCATE(LMASK_RELAX(0,0))
+END IF
+!
+! Additional fields for truly horizontal diffusion (Module MODD_DYNZD$n)
+IF (LZDIFFU) THEN
+  CALL INIT_TYPE_ZDIFFU_HALO2(XZDIFFU_HALO2)
+ELSE
+  CALL INIT_TYPE_ZDIFFU_HALO2(XZDIFFU_HALO2,0)
+ENDIF
+!
+!*       3.6   Larger Scale variables (Module MODD_LSFIELD$n)
+!
+!
+! upper relaxation part
+!
+ALLOCATE(XLSUM(IIU,IJU,IKU))    ; XLSUM  = 0.0
+ALLOCATE(XLSVM(IIU,IJU,IKU))    ; XLSVM  = 0.0
+ALLOCATE(XLSWM(IIU,IJU,IKU))    ; XLSWM  = 0.0
+ALLOCATE(XLSTHM(IIU,IJU,IKU))   ; XLSTHM = 0.0
+IF ( NRR > 0 ) THEN
+  ALLOCATE(XLSRVM(IIU,IJU,IKU)) ; XLSRVM = 0.0
+ELSE
+  ALLOCATE(XLSRVM(0,0,0))
+END IF
+!
+!  lbc part
+!
+IF ( L1D) THEN                         ! 1D case
+!
+  NSIZELBX_ll=0
+  NSIZELBXU_ll=0
+  NSIZELBY_ll=0
+  NSIZELBYV_ll=0
+  NSIZELBXTKE_ll=0
+  NSIZELBXR_ll=0
+  NSIZELBXSV_ll=0
+  NSIZELBYTKE_ll=0
+  NSIZELBYR_ll=0
+  NSIZELBYSV_ll=0
+  ALLOCATE(XLBXUM(0,0,0))
+  ALLOCATE(XLBYUM(0,0,0))
+  ALLOCATE(XLBXVM(0,0,0))
+  ALLOCATE(XLBYVM(0,0,0))
+  ALLOCATE(XLBXWM(0,0,0))
+  ALLOCATE(XLBYWM(0,0,0))
+  ALLOCATE(XLBXTHM(0,0,0))
+  ALLOCATE(XLBYTHM(0,0,0))
+  ALLOCATE(XLBXTKEM(0,0,0))
+  ALLOCATE(XLBYTKEM(0,0,0))
+  ALLOCATE(XLBXRM(0,0,0,0))
+  ALLOCATE(XLBYRM(0,0,0,0))
+  ALLOCATE(XLBXSVM(0,0,0,0))
+  ALLOCATE(XLBYSVM(0,0,0,0))
+!
+ELSEIF( L2D ) THEN                         ! 2D case
+!
+  NSIZELBY_ll=0
+  NSIZELBYV_ll=0
+  NSIZELBYTKE_ll=0
+  NSIZELBYR_ll=0
+  NSIZELBYSV_ll=0
+  ALLOCATE(XLBYUM(0,0,0))
+  ALLOCATE(XLBYVM(0,0,0))
+  ALLOCATE(XLBYWM(0,0,0))
+  ALLOCATE(XLBYTHM(0,0,0))
+  ALLOCATE(XLBYTKEM(0,0,0))
+  ALLOCATE(XLBYRM(0,0,0,0))
+  ALLOCATE(XLBYSVM(0,0,0,0))
+!
+  CALL GET_SIZEX_LB(NIMAX_ll,NJMAX_ll,NRIMX,               &
+                    IISIZEXF,IJSIZEXF,IISIZEXFU,IJSIZEXFU, &
+                    IISIZEX4,IJSIZEX4,IISIZEX2,IJSIZEX2)
+!
+  IF ( LHORELAX_UVWTH ) THEN
+    NSIZELBX_ll=2*NRIMX+2
+    NSIZELBXU_ll=2*NRIMX+2
+    ALLOCATE(XLBXUM(IISIZEXFU,IJSIZEXFU,IKU))
+    ALLOCATE(XLBXVM(IISIZEXF,IJSIZEXF,IKU))
+    ALLOCATE(XLBXWM(IISIZEXF,IJSIZEXF,IKU))
+    ALLOCATE(XLBXTHM(IISIZEXF,IJSIZEXF,IKU))
+  ELSE
+    NSIZELBX_ll=2
+    NSIZELBXU_ll=4
+    ALLOCATE(XLBXUM(IISIZEX4,IJSIZEX4,IKU))
+    ALLOCATE(XLBXVM(IISIZEX2,IJSIZEX2,IKU))
+    ALLOCATE(XLBXWM(IISIZEX2,IJSIZEX2,IKU))
+    ALLOCATE(XLBXTHM(IISIZEX2,IJSIZEX2,IKU))
+  END IF
+!
+  IF (CTURB /= 'NONE') THEN
+    IF ( LHORELAX_TKE) THEN
+      NSIZELBXTKE_ll=2* NRIMX+2
+      ALLOCATE(XLBXTKEM(IISIZEXF,IJSIZEXF,IKU))
+    ELSE
+      NSIZELBXTKE_ll=2
+      ALLOCATE(XLBXTKEM(IISIZEX2,IJSIZEX2,IKU))
+    END IF
+  ELSE
+    NSIZELBXTKE_ll=0
+    ALLOCATE(XLBXTKEM(0,0,0))
+  END IF
+  !
+  IF ( NRR > 0 ) THEN
+    IF (LHORELAX_RV .OR. LHORELAX_RC .OR. LHORELAX_RR .OR. LHORELAX_RI    &
+         .OR. LHORELAX_RS .OR. LHORELAX_RG .OR. LHORELAX_RH               &
+       ) THEN
+      NSIZELBXR_ll=2* NRIMX+2
+      ALLOCATE(XLBXRM(IISIZEXF,IJSIZEXF,IKU,NRR))
+    ELSE
+      NSIZELBXR_ll=2
+      ALLOCATE(XLBXRM(IISIZEX2,IJSIZEX2,IKU,NRR))
+    ENDIF
+  ELSE
+    NSIZELBXR_ll=0
+    ALLOCATE(XLBXRM(0,0,0,0))
+  END IF
+  !
+  IF ( NSV > 0 ) THEN
+    IF ( ANY( LHORELAX_SV(:)) ) THEN
+      NSIZELBXSV_ll=2* NRIMX+2
+      ALLOCATE(XLBXSVM(IISIZEXF,IJSIZEXF,IKU,NSV))
+    ELSE
+      NSIZELBXSV_ll=2
+      ALLOCATE(XLBXSVM(IISIZEX2,IJSIZEX2,IKU,NSV))
+    END IF
+  ELSE
+    NSIZELBXSV_ll=0
+    ALLOCATE(XLBXSVM(0,0,0,0))
+  END IF
+!
+ELSE                                   ! 3D case
+!
+!
+  CALL GET_SIZEX_LB(NIMAX_ll,NJMAX_ll,NRIMX,               &
+                    IISIZEXF,IJSIZEXF,IISIZEXFU,IJSIZEXFU, &
+                    IISIZEX4,IJSIZEX4,IISIZEX2,IJSIZEX2)
+  CALL GET_SIZEY_LB(NIMAX_ll,NJMAX_ll,NRIMY,               &
+                    IISIZEYF,IJSIZEYF,IISIZEYFV,IJSIZEYFV, &
+                    IISIZEY4,IJSIZEY4,IISIZEY2,IJSIZEY2)
+!
+! check if local domain not to small for NRIMX NRIMY
+!
+  IF ( CLBCX(1) /= 'CYCL' )  THEN
+     IF ( NRIMX+2*JPHEXT .GE. IIU )   THEN
+        WRITE(*,'(A,I8,A/A,2I8,/A)') "Processor=", IP-1, &
+             " :: INI_SPECTRE_n ERROR:  ( NRIMX+2*JPHEXT >= IIU )  ", &
+             " Local domain to small for relaxation NRIMX+2*JPHEXT,IIU ", &
+             NRIMX+2*JPHEXT,IIU ,&
+             " change relaxation parameters or number of processors "
+        call Print_msg(NVERB_FATAL,'GEN','INI_SPECTRE_n','')
+     END IF
+  END IF
+  IF ( CLBCY(1) /= 'CYCL' ) THEN
+     IF ( NRIMY+2*JPHEXT .GE. IJU )  THEN
+        WRITE(*,'(A,I8,A/A,2I8,/A)') "Processor=", IP-1, &
+             " :: INI_SPECTRE_n ERROR:  ( NRIMY+2*JPHEXT >= IJU )  ", &
+             " Local domain to small for relaxation NRIMY+2*JPHEXT,IJU ", &
+             NRIMY+2*JPHEXT,IJU ,&
+             " change relaxation parameters or number of processors "
+        call Print_msg(NVERB_FATAL,'GEN','INI_SPECTRE_n','')
+     END IF
+  END IF
+IF ( LHORELAX_UVWTH ) THEN
+    NSIZELBX_ll=2*NRIMX+2
+    NSIZELBXU_ll=2*NRIMX+2
+    NSIZELBY_ll=2*NRIMY+2
+    NSIZELBYV_ll=2*NRIMY+2
+    ALLOCATE(XLBXUM(IISIZEXFU,IJSIZEXFU,IKU))
+    ALLOCATE(XLBYUM(IISIZEYF,IJSIZEYF,IKU))
+    ALLOCATE(XLBXVM(IISIZEXF,IJSIZEXF,IKU))
+    ALLOCATE(XLBYVM(IISIZEYFV,IJSIZEYFV,IKU))
+    ALLOCATE(XLBXWM(IISIZEXF,IJSIZEXF,IKU))
+    ALLOCATE(XLBYWM(IISIZEYF,IJSIZEYF,IKU))
+    ALLOCATE(XLBXTHM(IISIZEXF,IJSIZEXF,IKU))
+    ALLOCATE(XLBYTHM(IISIZEYF,IJSIZEYF,IKU))
+  ELSE
+    NSIZELBX_ll=2
+    NSIZELBXU_ll=4
+    NSIZELBY_ll=2
+    NSIZELBYV_ll=4
+    ALLOCATE(XLBXUM(IISIZEX4,IJSIZEX4,IKU))
+    ALLOCATE(XLBYUM(IISIZEY2,IJSIZEY2,IKU))
+    ALLOCATE(XLBXVM(IISIZEX2,IJSIZEX2,IKU))
+    ALLOCATE(XLBYVM(IISIZEY4,IJSIZEY4,IKU))
+    ALLOCATE(XLBXWM(IISIZEX2,IJSIZEX2,IKU))
+    ALLOCATE(XLBYWM(IISIZEY2,IJSIZEY2,IKU))
+    ALLOCATE(XLBXTHM(IISIZEX2,IJSIZEX2,IKU))
+    ALLOCATE(XLBYTHM(IISIZEY2,IJSIZEY2,IKU))
+  END IF
+  !
+  IF (CTURB /= 'NONE') THEN
+    IF ( LHORELAX_TKE) THEN
+      NSIZELBXTKE_ll=2*NRIMX+2
+      NSIZELBYTKE_ll=2*NRIMY+2
+      ALLOCATE(XLBXTKEM(IISIZEXF,IJSIZEXF,IKU))
+      ALLOCATE(XLBYTKEM(IISIZEYF,IJSIZEYF,IKU))
+    ELSE
+      NSIZELBXTKE_ll=2
+      NSIZELBYTKE_ll=2
+      ALLOCATE(XLBXTKEM(IISIZEX2,IJSIZEX2,IKU))
+      ALLOCATE(XLBYTKEM(IISIZEY2,IJSIZEY2,IKU))
+    END IF
+  ELSE
+    NSIZELBXTKE_ll=0
+    NSIZELBYTKE_ll=0
+    ALLOCATE(XLBXTKEM(0,0,0))
+    ALLOCATE(XLBYTKEM(0,0,0))
+  END IF
+  !
+  IF ( NRR > 0 ) THEN
+    IF (LHORELAX_RV .OR. LHORELAX_RC .OR. LHORELAX_RR .OR. LHORELAX_RI    &
+          .OR. LHORELAX_RS .OR. LHORELAX_RG .OR. LHORELAX_RH              &
+       ) THEN
+      NSIZELBXR_ll=2*NRIMX+2
+      NSIZELBYR_ll=2*NRIMY+2
+      ALLOCATE(XLBXRM(IISIZEXF,IJSIZEXF,IKU,NRR))
+      ALLOCATE(XLBYRM(IISIZEYF,IJSIZEYF,IKU,NRR))
+    ELSE
+      NSIZELBXR_ll=2
+      NSIZELBYR_ll=2
+      ALLOCATE(XLBXRM(IISIZEX2,IJSIZEX2,IKU,NRR))
+      ALLOCATE(XLBYRM(IISIZEY2,IJSIZEY2,IKU,NRR))
+    ENDIF
+  ELSE
+    NSIZELBXR_ll=0
+    NSIZELBYR_ll=0
+    ALLOCATE(XLBXRM(0,0,0,0))
+    ALLOCATE(XLBYRM(0,0,0,0))
+  END IF
+  !
+  IF ( NSV > 0 ) THEN
+    IF ( ANY( LHORELAX_SV(:)) ) THEN
+      NSIZELBXSV_ll=2*NRIMX+2
+      NSIZELBYSV_ll=2*NRIMY+2
+      ALLOCATE(XLBXSVM(IISIZEXF,IJSIZEXF,IKU,NSV))
+      ALLOCATE(XLBYSVM(IISIZEYF,IJSIZEYF,IKU,NSV))
+    ELSE
+      NSIZELBXSV_ll=2
+      NSIZELBYSV_ll=2
+      ALLOCATE(XLBXSVM(IISIZEX2,IJSIZEX2,IKU,NSV))
+      ALLOCATE(XLBYSVM(IISIZEY2,IJSIZEY2,IKU,NSV))
+    END IF
+  ELSE
+    NSIZELBXSV_ll=0
+    NSIZELBYSV_ll=0
+    ALLOCATE(XLBXSVM(0,0,0,0))
+    ALLOCATE(XLBYSVM(0,0,0,0))
+  END IF
+END IF      ! END OF THE IF STRUCTURE ON THE MODEL DIMENSION
+!
+!
+IF ( KMI > 1 ) THEN 
+  ! it has been assumed that the THeta field used the largest rim area compared
+  ! to the others prognostic variables, if it is not the case, you must change
+  ! these lines
+  ALLOCATE(XCOEFLIN_LBXM(SIZE(XLBXTHM,1),SIZE(XLBXTHM,2),SIZE(XLBXTHM,3)))
+  ALLOCATE(   NKLIN_LBXM(SIZE(XLBXTHM,1),SIZE(XLBXTHM,2),SIZE(XLBXTHM,3)))
+  ALLOCATE(XCOEFLIN_LBYM(SIZE(XLBYTHM,1),SIZE(XLBYTHM,2),SIZE(XLBYTHM,3)))
+  ALLOCATE(   NKLIN_LBYM(SIZE(XLBYTHM,1),SIZE(XLBYTHM,2),SIZE(XLBYTHM,3)))
+  ALLOCATE(XCOEFLIN_LBXU(SIZE(XLBXUM,1),SIZE(XLBXUM,2),SIZE(XLBXUM,3)))
+  ALLOCATE(   NKLIN_LBXU(SIZE(XLBXUM,1),SIZE(XLBXUM,2),SIZE(XLBXUM,3)))
+  ALLOCATE(XCOEFLIN_LBYU(SIZE(XLBYUM,1),SIZE(XLBYUM,2),SIZE(XLBYUM,3)))
+  ALLOCATE(   NKLIN_LBYU(SIZE(XLBYUM,1),SIZE(XLBYUM,2),SIZE(XLBYUM,3)))
+  ALLOCATE(XCOEFLIN_LBXV(SIZE(XLBXVM,1),SIZE(XLBXVM,2),SIZE(XLBXVM,3)))
+  ALLOCATE(   NKLIN_LBXV(SIZE(XLBXVM,1),SIZE(XLBXVM,2),SIZE(XLBXVM,3)))
+  ALLOCATE(XCOEFLIN_LBYV(SIZE(XLBYVM,1),SIZE(XLBYVM,2),SIZE(XLBYVM,3)))
+  ALLOCATE(   NKLIN_LBYV(SIZE(XLBYVM,1),SIZE(XLBYVM,2),SIZE(XLBYVM,3)))
+  ALLOCATE(XCOEFLIN_LBXW(SIZE(XLBXWM,1),SIZE(XLBXWM,2),SIZE(XLBXWM,3)))
+  ALLOCATE(   NKLIN_LBXW(SIZE(XLBXWM,1),SIZE(XLBXWM,2),SIZE(XLBXWM,3)))
+  ALLOCATE(XCOEFLIN_LBYW(SIZE(XLBYWM,1),SIZE(XLBYWM,2),SIZE(XLBYWM,3)))
+  ALLOCATE(   NKLIN_LBYW(SIZE(XLBYWM,1),SIZE(XLBYWM,2),SIZE(XLBYWM,3)))
+END IF
+!
+!  allocation of the LS fields for vertical relaxation and numerical diffusion
+IF( .NOT. LSTEADYLS )  THEN
+!
+  ALLOCATE(XLSUS(SIZE(XLSUM,1),SIZE(XLSUM,2),SIZE(XLSUM,3)))
+  ALLOCATE(XLSVS(SIZE(XLSVM,1),SIZE(XLSVM,2),SIZE(XLSVM,3)))
+  ALLOCATE(XLSWS(SIZE(XLSWM,1),SIZE(XLSWM,2),SIZE(XLSWM,3)))
+  ALLOCATE(XLSTHS(SIZE(XLSTHM,1),SIZE(XLSTHM,2),SIZE(XLSTHM,3)))
+  ALLOCATE(XLSRVS(SIZE(XLSRVM,1),SIZE(XLSRVM,2),SIZE(XLSRVM,3)))
+!
+ELSE
+!
+  ALLOCATE(XLSUS(0,0,0))
+  ALLOCATE(XLSVS(0,0,0))
+  ALLOCATE(XLSWS(0,0,0))
+  ALLOCATE(XLSTHS(0,0,0))
+  ALLOCATE(XLSRVS(0,0,0))
+!
+END IF
+!  allocation of the LB fields for horizontal relaxation and Lateral Boundaries
+IF( .NOT. ( LSTEADYLS .AND. KMI==1 ) )  THEN
+!
+  ALLOCATE(XLBXTKES(SIZE(XLBXTKEM,1),SIZE(XLBXTKEM,2),SIZE(XLBXTKEM,3)))
+  ALLOCATE(XLBYTKES(SIZE(XLBYTKEM,1),SIZE(XLBYTKEM,2),SIZE(XLBYTKEM,3)))
+  ALLOCATE(XLBXUS(SIZE(XLBXUM,1),SIZE(XLBXUM,2),SIZE(XLBXUM,3)))
+  ALLOCATE(XLBYUS(SIZE(XLBYUM,1),SIZE(XLBYUM,2),SIZE(XLBYUM,3)))
+  ALLOCATE(XLBXVS(SIZE(XLBXVM,1),SIZE(XLBXVM,2),SIZE(XLBXVM,3)))
+  ALLOCATE(XLBYVS(SIZE(XLBYVM,1),SIZE(XLBYVM,2),SIZE(XLBYVM,3)))
+  ALLOCATE(XLBXWS(SIZE(XLBXWM,1),SIZE(XLBXWM,2),SIZE(XLBXWM,3)))
+  ALLOCATE(XLBYWS(SIZE(XLBYWM,1),SIZE(XLBYWM,2),SIZE(XLBYWM,3)))
+  ALLOCATE(XLBXTHS(SIZE(XLBXTHM,1),SIZE(XLBXTHM,2),SIZE(XLBXTHM,3)))
+  ALLOCATE(XLBYTHS(SIZE(XLBYTHM,1),SIZE(XLBYTHM,2),SIZE(XLBYTHM,3)))
+  ALLOCATE(XLBXRS(SIZE(XLBXRM,1),SIZE(XLBXRM,2),SIZE(XLBXRM,3),SIZE(XLBXRM,4)))
+  ALLOCATE(XLBYRS(SIZE(XLBYRM,1),SIZE(XLBYRM,2),SIZE(XLBYRM,3),SIZE(XLBYRM,4)))
+  ALLOCATE(XLBXSVS(SIZE(XLBXSVM,1),SIZE(XLBXSVM,2),SIZE(XLBXSVM,3),SIZE(XLBXSVM,4)))
+  ALLOCATE(XLBYSVS(SIZE(XLBYSVM,1),SIZE(XLBYSVM,2),SIZE(XLBYSVM,3),SIZE(XLBYSVM,4)))
+!
+ELSE
+!
+  ALLOCATE(XLBXTKES(0,0,0))
+  ALLOCATE(XLBYTKES(0,0,0))
+  ALLOCATE(XLBXUS(0,0,0))
+  ALLOCATE(XLBYUS(0,0,0))
+  ALLOCATE(XLBXVS(0,0,0))
+  ALLOCATE(XLBYVS(0,0,0))
+  ALLOCATE(XLBXWS(0,0,0))
+  ALLOCATE(XLBYWS(0,0,0))
+  ALLOCATE(XLBXTHS(0,0,0))
+  ALLOCATE(XLBYTHS(0,0,0))
+  ALLOCATE(XLBXRS(0,0,0,0))
+  ALLOCATE(XLBYRS(0,0,0,0))
+  ALLOCATE(XLBXSVS(0,0,0,0))
+  ALLOCATE(XLBYSVS(0,0,0,0))
+!
+END IF
+!
+!*       3.9   Local variables
+!
+ALLOCATE(ZJ(IIU,IJU,IKU))
+!
+!-------------------------------------------------------------------------------
+!
+!
+!*       5.    INITIALIZE INTERPOLATION COEFFICIENTS
+!
+CALL INI_BIKHARDT_n (NDXRATIO_ALL(KMI),NDYRATIO_ALL(KMI),KMI)
+!
+!-------------------------------------------------------------------------------
+!
+!*       6.    INITIALIZE GRIDS AND METRIC COEFFICIENTS
+!              ----------------------------------------
+!
+CALL SET_GRID(KMI,TPINIFILE,IKU,NIMAX_ll,NJMAX_ll,                       &
+              XTSTEP,XSEGLEN,                                            &
+              XLONORI,XLATORI,XLON,XLAT,                                 &
+              XXHAT,XYHAT,XDXHAT,XDYHAT, XMAP,                           &
+              XZS,XZZ,XZHAT,XZTOP,LSLEVE,XLEN1,XLEN2,XZSMT,              &
+              ZJ,                                                        &
+              TDTMOD,TDTCUR,NSTOP,NBAK_NUMB,NOUT_NUMB,TBACKUPN,TOUTPUTN)
+!
+CALL METRICS(XMAP,XDXHAT,XDYHAT,XZZ,XDXX,XDYY,XDZX,XDZY,XDZZ)
+!
+!* update halos of metric coefficients
+!
+!
+CALL UPDATE_METRICS(CLBCX,CLBCY,XDXX,XDYY,XDZX,XDZY,XDZZ)
+!
+!
+! grid nesting initializations
+IF ( KMI == 1 ) THEN
+  XTSTEP_MODEL1=XTSTEP
+END IF
+!
+NDT_2_WAY(KMI)=4
+!
+!-------------------------------------------------------------------------------
+!
+!*       8.    INITIALIZE THE PROGNOSTIC FIELDS
+!              --------------------------------
+!
+
+IF (LSPECTRE_U) THEN
+  ALLOCATE(XUT(IIU,IJU,IKU))      ; XUT  = 0.0
+  CALL IO_Field_read(TPINIFILE,'UT',XUT)
+END IF
+!
+IF (LSPECTRE_V) THEN
+  ALLOCATE(XVT(IIU,IJU,IKU))      ; XVT  = 0.0
+  CALL IO_Field_read(TPINIFILE,'VT',XVT)
+END IF
+!
+IF (LSPECTRE_W) THEN  
+  ALLOCATE(XWT(IIU,IJU,IKU))      ; XWT  = 0.0
+  CALL IO_Field_read(TPINIFILE,'WT',XWT)
+END IF
+!
+IF (LSPECTRE_TH) THEN
+  ALLOCATE(XTHT(IIU,IJU,IKU))     ; XTHT = 0.0
+  CALL IO_Field_read(TPINIFILE,'THT',XTHT)
+END IF
+!
+IF (LSPECTRE_RV) THEN
+  ALLOCATE(XRT(IIU,IJU,IKU,NRR))
+  CALL IO_Field_read(TPINIFILE,'RVT',XRT(:,:,:,1))
+END IF
+!
+!-------------------------------------------------------------------------------
+!
+!
+!*        9.   INITIALIZE REFERENCE STATE
+!              ---------------------------
+!
+!
+CALL SET_REF(KMI,TPINIFILE,                        &
+             XZZ,XZHAT,ZJ,XDXX,XDYY,CLBCX,CLBCY,   &
+             XREFMASS,XMASS_O_PHI0,XLINMASS,       &
+             XRHODREF,XTHVREF,XRVREF,XEXNREF,XRHODJ)
+!-------------------------------------------------------------------------------
+!
+!*       11.    INITIALIZE THE SOURCE OF TOTAL DRY MASS Md
+!               ------------------------------------------
+!
+IF((KMI==1).AND.LSTEADYLS) THEN
+  XDRYMASSS = 0.
+END IF
+!
+!
+!-------------------------------------------------------------------------------
+!
+!*       14.   INITIALIZE THE LARGE SCALE SOURCES
+!              ----------------------------------
+!
+IF ((KMI==1).AND.(.NOT. LSTEADYLS)) THEN
+  IF (LSPECTRE_LSU.OR.LSPECTRE_LSV.OR.LSPECTRE_LSW.OR. &
+      LSPECTRE_LSRV.OR.LSPECTRE_LSTH) THEN 
+    CALL INI_CPL(NSTOP,XTSTEP,LSTEADYLS,CCONF,                                &
+               CGETTKET,                                                      &
+               CGETRVT,CGETRCT,CGETRRT,CGETRIT,                               &
+               CGETRST,CGETRGT,CGETRHT,CGETSVT,LCH_INIT_FIELD,                &
+               NSV,NIMAX_ll,NJMAX_ll,                                         &
+               NSIZELBX_ll,NSIZELBXU_ll,NSIZELBY_ll,NSIZELBYV_ll,             &
+               NSIZELBXTKE_ll,NSIZELBYTKE_ll,                                 &
+               NSIZELBXR_ll,NSIZELBYR_ll,NSIZELBXSV_ll,NSIZELBYSV_ll,         &
+               XLSUM,XLSVM,XLSWM,XLSTHM,XLSRVM,XLSZWSM,XDRYMASST,             &
+               XLBXUM,XLBXVM,XLBXWM,XLBXTHM,XLBXTKEM,XLBXRM,XLBXSVM,          &
+               XLBYUM,XLBYVM,XLBYWM,XLBYTHM,XLBYTKEM,XLBYRM,XLBYSVM,          &
+               XLSUS,XLSVS,XLSWS,XLSTHS,XLSRVS,XLSZWSS,XDRYMASSS,             &
+               XLBXUS,XLBXVS,XLBXWS,XLBXTHS,XLBXTKES,XLBXRS,XLBXSVS,          &
+               XLBYUS,XLBYVS,XLBYWS,XLBYTHS,XLBYTKES,XLBYRS,XLBYSVS           )
+  END IF
+END IF
+!
+IF ( KMI > 1) THEN
+  ! Use dummy pointers to correct an ifort BUG
+  DPTR_XBMX1=>XBMX1
+  DPTR_XBMX2=>XBMX2
+  DPTR_XBMX3=>XBMX3
+  DPTR_XBMX4=>XBMX4
+  DPTR_XBMY1=>XBMY1
+  DPTR_XBMY2=>XBMY2
+  DPTR_XBMY3=>XBMY3
+  DPTR_XBMY4=>XBMY4
+  DPTR_XBFX1=>XBFX1
+  DPTR_XBFX2=>XBFX2
+  DPTR_XBFX3=>XBFX3
+  DPTR_XBFX4=>XBFX4
+  DPTR_XBFY1=>XBFY1
+  DPTR_XBFY2=>XBFY2
+  DPTR_XBFY3=>XBFY3
+  DPTR_XBFY4=>XBFY4
+  DPTR_CLBCX=>CLBCX
+  DPTR_CLBCY=>CLBCY
+  !
+  DPTR_XZZ=>XZZ
+  DPTR_XZHAT=>XZHAT
+  DPTR_XLSUM=>XLSUM
+  DPTR_XLSVM=>XLSVM
+  DPTR_XLSWM=>XLSWM
+  DPTR_XLSTHM=>XLSTHM
+  DPTR_XLSRVM=>XLSRVM
+  DPTR_XLSZWSM=>XLSZWSM
+  DPTR_XLSUS=>XLSUS
+  DPTR_XLSVS=>XLSVS
+  DPTR_XLSWS=>XLSWS
+  DPTR_XLSTHS=>XLSTHS
+  DPTR_XLSRVS=>XLSRVS
+  DPTR_XLSZWSS=>XLSZWSS
+  !
+  DPTR_NKLIN_LBXU=>NKLIN_LBXU
+  DPTR_XCOEFLIN_LBXU=>XCOEFLIN_LBXU
+  DPTR_NKLIN_LBYU=>NKLIN_LBYU
+  DPTR_XCOEFLIN_LBYU=>XCOEFLIN_LBYU
+  DPTR_NKLIN_LBXV=>NKLIN_LBXV
+  DPTR_XCOEFLIN_LBXV=>XCOEFLIN_LBXV
+  DPTR_NKLIN_LBYV=>NKLIN_LBYV
+  DPTR_XCOEFLIN_LBYV=>XCOEFLIN_LBYV
+  DPTR_NKLIN_LBXW=>NKLIN_LBXW
+  DPTR_XCOEFLIN_LBXW=>XCOEFLIN_LBXW
+  DPTR_NKLIN_LBYW=>NKLIN_LBYW
+  DPTR_XCOEFLIN_LBYW=>XCOEFLIN_LBYW
+  DPTR_NKLIN_LBXM=>NKLIN_LBXM
+  DPTR_XCOEFLIN_LBXM=>XCOEFLIN_LBXM
+  DPTR_NKLIN_LBYM=>NKLIN_LBYM
+  DPTR_XCOEFLIN_LBYM=>XCOEFLIN_LBYM
+  !
+  CALL INI_SPAWN_LS_n(NDAD(KMI),XTSTEP,KMI,                                 &
+       DPTR_XBMX1,DPTR_XBMX2,DPTR_XBMX3,DPTR_XBMX4,DPTR_XBMY1,DPTR_XBMY2,DPTR_XBMY3,DPTR_XBMY4,      &
+       DPTR_XBFX1,DPTR_XBFX2,DPTR_XBFX3,DPTR_XBFX4,DPTR_XBFY1,DPTR_XBFY2,DPTR_XBFY3,DPTR_XBFY4,      &
+       NDXRATIO_ALL(KMI),NDYRATIO_ALL(KMI),                  &
+       DPTR_CLBCX,DPTR_CLBCY,DPTR_XZZ,DPTR_XZHAT,                                &
+       LSLEVE,XLEN1,XLEN2,                                   &
+       DPTR_XLSUM,DPTR_XLSVM,DPTR_XLSWM,DPTR_XLSTHM,DPTR_XLSRVM,DPTR_XLSZWSM,         &
+       DPTR_XLSUS,DPTR_XLSVS,DPTR_XLSWS,DPTR_XLSTHS,DPTR_XLSRVS,DPTR_XLSZWSS,         &
+       DPTR_NKLIN_LBXU,DPTR_XCOEFLIN_LBXU,DPTR_NKLIN_LBYU,DPTR_XCOEFLIN_LBYU,    &
+       DPTR_NKLIN_LBXV,DPTR_XCOEFLIN_LBXV,DPTR_NKLIN_LBYV,DPTR_XCOEFLIN_LBYV,    &
+       DPTR_NKLIN_LBXW,DPTR_XCOEFLIN_LBXW,DPTR_NKLIN_LBYW,DPTR_XCOEFLIN_LBYW,    &
+       DPTR_NKLIN_LBXM,DPTR_XCOEFLIN_LBXM,DPTR_NKLIN_LBYM,DPTR_XCOEFLIN_LBYM     )
+  !
+  DPTR_XLBXUM=>XLBXUM
+  DPTR_XLBYUM=>XLBYUM
+  DPTR_XLBXVM=>XLBXVM
+  DPTR_XLBYVM=>XLBYVM
+  DPTR_XLBXWM=>XLBXWM
+  DPTR_XLBYWM=>XLBYWM
+  DPTR_XLBXTHM=>XLBXTHM
+  DPTR_XLBYTHM=>XLBYTHM
+  DPTR_XLBXTKEM=>XLBXTKEM
+  DPTR_XLBYTKEM=>XLBYTKEM
+  DPTR_XLBXRM=>XLBXRM
+  DPTR_XLBYRM=>XLBYRM
+  DPTR_XLBXSVM=>XLBXSVM
+  DPTR_XLBYSVM=>XLBYSVM
+  CALL INI_ONE_WAY_n(NDAD(KMI),KMI,                                                             &
+       DPTR_XBMX1,DPTR_XBMX2,DPTR_XBMX3,DPTR_XBMX4,DPTR_XBMY1,DPTR_XBMY2,DPTR_XBMY3,DPTR_XBMY4, &
+       DPTR_XBFX1,DPTR_XBFX2,DPTR_XBFX3,DPTR_XBFX4,DPTR_XBFY1,DPTR_XBFY2,DPTR_XBFY3,DPTR_XBFY4, &
+       NDXRATIO_ALL(KMI),NDYRATIO_ALL(KMI),                                                     &
+       DPTR_CLBCX,DPTR_CLBCY,NRIMX,NRIMY,                                                       &
+       DPTR_NKLIN_LBXU,DPTR_XCOEFLIN_LBXU,DPTR_NKLIN_LBYU,DPTR_XCOEFLIN_LBYU,                   &
+       DPTR_NKLIN_LBXV,DPTR_XCOEFLIN_LBXV,DPTR_NKLIN_LBYV,DPTR_XCOEFLIN_LBYV,                   &
+       DPTR_NKLIN_LBXW,DPTR_XCOEFLIN_LBXW,DPTR_NKLIN_LBYW,DPTR_XCOEFLIN_LBYW,                   &
+       DPTR_NKLIN_LBXM,DPTR_XCOEFLIN_LBXM,DPTR_NKLIN_LBYM,DPTR_XCOEFLIN_LBYM,                   &
+       CCLOUD, LUSECHAQ, LUSECHIC,                                                              &
+       DPTR_XLBXUM,DPTR_XLBYUM,DPTR_XLBXVM,DPTR_XLBYVM,DPTR_XLBXWM,DPTR_XLBYWM,                 &
+       DPTR_XLBXTHM,DPTR_XLBYTHM,                                                               &
+       DPTR_XLBXTKEM,DPTR_XLBYTKEM,                                                             &
+       DPTR_XLBXRM,DPTR_XLBYRM,DPTR_XLBXSVM,DPTR_XLBYSVM                                        )
+END IF
+!
+!
+!*       16.    BUILT THE GENERIC OUTPUT NAME
+!               ----------------------------
+!
+WRITE(COUTFILE,'(A,".",I1,".",A)') CEXP,KMI,TRIM(ADJUSTL(CSEG))
+
+!-------------------------------------------------------------------------------
+!
+!*       17.    INITIALIZE THE PARAMETERS FOR THE DYNAMICS
+!               ------------------------------------------
+!
+!Allocate to zero size to not pass unallocated pointers
+ALLOCATE(XALKBAS(0))
+ALLOCATE(XALKWBAS(0))
+!
+CALL INI_DYNAMICS(XLON,XLAT,XRHODJ,XTHVREF,XMAP,XZZ,XDXHAT,XDYHAT,            &
+             XZHAT,CLBCX,CLBCY,XTSTEP,CPRESOPT,                               &
+             LVE_RELAX,LVE_RELAX_GRD,LHORELAX_UVWTH,LHORELAX_RV,              &
+             LHORELAX_RC,LHORELAX_RR,LHORELAX_RI,LHORELAX_RS,LHORELAX_RG,     &
+             LHORELAX_RH,LHORELAX_TKE,LHORELAX_SV,                            &
+             LHORELAX_SVC2R2,LHORELAX_SVC1R3,LHORELAX_SVELEC,LHORELAX_SVLG,   &
+             LHORELAX_SVCHEM,LHORELAX_SVAER,LHORELAX_SVDST,LHORELAX_SVSLT,    &
+             LHORELAX_SVPP,LHORELAX_SVCS,LHORELAX_SVCHIC,LHORELAX_SVSNW,      &
+#ifdef MNH_FOREFIRE
+             LHORELAX_SVFF,                                                   &
+#endif
+             XRIMKMAX,NRIMX,NRIMY,                                            &
+             XALKTOP,XALKGRD,XALZBOT,XALZBAS,                                 &
+             XT4DIFU,XT4DIFTH,XT4DIFSV,                                       &
+             XCORIOX,XCORIOY,XCORIOZ,XCURVX,XCURVY,                           &
+             XDXHATM,XDYHATM,XRHOM,XAF,XBFY,XCF,XTRIGSX,XTRIGSY,NIFAXX,NIFAXY,&
+             XALK,XALKW,NALBOT,XALKBAS,XALKWBAS,NALBAS,                       &
+             LMASK_RELAX,XKURELAX,XKVRELAX,XKWRELAX,                          &
+             XDK2U,XDK4U,XDK2TH,XDK4TH,XDK2SV,XDK4SV,                         &
+             LZDIFFU,XZDIFFU_HALO2,                                           &
+             XBFB,XBF_SXP2_YP1_Z,                                             &
+             XAF_ZS,XBF_ZS,XCF_ZS,                                            &
+             XDXATH_ZS,XDYATH_ZS,XRHO_ZS,                                     &
+             XA_K,XB_K,XC_K,XD_K) 
+!
+!-------------------------------------------------------------------------------
+!
+!*      22.    UPDATE HALO
+!              -----------
+!
+!
+CALL UPDATE_HALO_ll(TZINITHALO3D_ll,IINFO_ll)
+CALL UPDATE_HALO_ll(TZINITHALO2D_ll,IINFO_ll)
+CALL CLEANLIST_ll(TZINITHALO3D_ll)
+CALL CLEANLIST_ll(TZINITHALO2D_ll)
+!
+!
+!-------------------------------------------------------------------------------
+!
+!*      23.    DEALLOCATION
+!              -------------
+!
+DEALLOCATE(ZJ)
+!
+
+END SUBROUTINE INI_SPECTRE_n
diff --git a/src/ZSOLVER/mass_leak.f90 b/src/ZSOLVER/mass_leak.f90
new file mode 100644
index 0000000000000000000000000000000000000000..9ffe52c67bd2b3bceed6459854309e30d6eb4468
--- /dev/null
+++ b/src/ZSOLVER/mass_leak.f90
@@ -0,0 +1,289 @@
+!MNH_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt  
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+!--------------- special set of characters for RCS information
+!-----------------------------------------------------------------
+! $Source$ $Revision$
+! MASDEV4_7 solver 2006/05/18 14:41:09
+!-----------------------------------------------------------------
+!####################
+MODULE MODI_MASS_LEAK
+!####################
+!
+INTERFACE
+!
+          SUBROUTINE MASS_LEAK (PDXX,PDYY,HLBCX,HLBCY,PLINMASS,PRHODJ,PRUS,PRVS)
+!
+REAL, DIMENSION(:,:,:),         INTENT(IN) :: PDXX    ! metric coefficient dxx
+REAL, DIMENSION(:,:,:),         INTENT(IN) :: PDYY    ! metric coefficient dyy
+CHARACTER(LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX   ! type of lateral boundary
+!                                                     ! condition (i=IB, i=IE+1)
+CHARACTER(LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY   ! type of lateral boundary
+!                                                     ! condition (j=JB, j=JE+1)
+REAL,                          INTENT(IN) :: PLINMASS ! lineic mass through open
+!                                                     ! boundaries
+REAL, DIMENSION(:,:,:),        INTENT(IN)  :: PRHODJ  ! rhodref*J
+REAL, DIMENSION(:,:,:),        INTENT(INOUT) :: PRUS  ! Horizontal
+REAL, DIMENSION(:,:,:),        INTENT(INOUT) :: PRVS  ! momentum  tendencies
+!
+END SUBROUTINE MASS_LEAK
+!
+END INTERFACE
+!
+END MODULE MODI_MASS_LEAK
+!
+!     #####################################################################
+      SUBROUTINE MASS_LEAK(PDXX,PDYY,HLBCX,HLBCY,PLINMASS,PRHODJ,PRUS,PRVS)
+!     #####################################################################
+!
+!!***   *MASS_LEAK* - assures global non-divergence condition
+!!
+!!    PURPOSE
+!!    -------
+!!
+!!      This routine changes the horizontal reference dry mass fluxes through
+!!    the open boundary condition faces to set the global divergence in the
+!!    model domain to zero.
+!!
+!!**  METHOD
+!!    ------
+!!
+!!  1) The leak term is computed as:
+!!
+!!          --                     -- IE+1   --                     -- JE+1
+!!          | JE KE                 |        | IE KE                 |
+!!          | _  _                  |        | _  _                  |
+!!          | \  \    1        _ _  |        | \  \    1        _ _  |
+!!   ZLEAK= | /  /   --- PRUS dydz  |   +    | /  /   --- PRVS dxdz  |
+!!          | -  -   dxx            |        | -  -   dyy            |
+!!          | JB KB                 |        | IB KB                 |
+!!          --                     -- i=IB   --                     -- j=JB
+!!
+!!  2) Then the correction wind value ZRUSTOP is found as
+!!               ZLEAK
+!!    ZRUSTOP= ----------
+!!              PLINMASS
+!!
+!!     where PLINMASS is the lineic mass through the open lateral boundaries.
+!!
+!!  3) This horizontal wind correction is applied on the normal wind of
+!!     open lateral boundaries only.
+!!
+!!
+!!    EXTERNAL
+!!    --------
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------
+!!
+!!      Module MODD_PARAMETERS : contains declaration of parameter variables
+!!
+!!         JPHEXT   : Horizontal external points number
+!!         JPVEXT   : Vertical external points number
+!!
+!!    REFERENCE
+!!    ---------
+!!
+!!      book2
+!!
+!!    AUTHOR
+!!    ------
+!!
+!!      V. Masson   Meteo-France
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original     09/02/95
+!!      Modification 20/10/97  (J.P.Lafore) introduction of 'DAVI' type of lbc
+!!                  15/06/98  (D.Lugato, R.Guivarch) Parallelisation
+!!                   05/06    Suppression of Davies type of lbc
+!!
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+!
+USE MODD_PARAMETERS
+!
+USE MODE_ll
+!JUAN
+USE MODE_REPRO_SUM
+!JUAN
+!
+IMPLICIT NONE
+!
+!*       0.1   declarations of dummy arguments
+!
+REAL, DIMENSION(:,:,:),        INTENT(IN) :: PDXX    ! metric coefficient dxx
+REAL, DIMENSION(:,:,:),        INTENT(IN) :: PDYY    ! metric coefficient dyy
+CHARACTER(LEN=4), DIMENSION(2),INTENT(IN) :: HLBCX   ! type of lateral boundary
+!                                                    ! condition (i=IB, i=IE+1)
+CHARACTER(LEN=4), DIMENSION(2),INTENT(IN) :: HLBCY   ! type of lateral boundary
+!                                                    ! condition (j=JB, j=JE+1)
+REAL,                          INTENT(IN) :: PLINMASS! lineic mass through open
+!                                                    ! boundaries
+REAL, DIMENSION(:,:,:),        INTENT(IN) :: PRHODJ  ! rhodref*J
+REAL, DIMENSION(:,:,:),        INTENT(INOUT) :: PRUS ! Horizontal
+REAL, DIMENSION(:,:,:),        INTENT(INOUT) :: PRVS ! momentum  tendencies
+!
+!*       0.2   declarations of local variables
+!
+!JUAN16
+REAL                               :: ZLEAK     ! total leak of mass
+REAL, ALLOCATABLE, DIMENSION (:,:) :: ZLEAK_W_2D , ZLEAK_E_2D , ZLEAK_S_2D , ZLEAK_N_2D
+!JUAN16
+
+REAL                :: ZUSTOP     ! wind correction!
+INTEGER             :: IIB        ! indice I Beginning in x direction
+INTEGER             :: IJB        ! indice J Beginning in y direction
+INTEGER             :: IKB        ! indice K Beginning in z direction
+INTEGER             :: IIE        ! indice I End       in x direction
+INTEGER             :: IJE        ! indice J End       in y direction
+INTEGER             :: IKE        ! indice K End       in z direction
+INTEGER             :: JI         ! Loop index in x direction
+INTEGER             :: JJ         ! Loop index in y direction
+INTEGER             :: JK         ! Loop index in z direction
+!
+INTEGER             :: IINFO_ll   ! return code of parallel routine
+!
+LOGICAL :: GWEST,GEAST,GSOUTH,GNORTH
+REAL    :: ZLEAK_W,ZLEAK_E,ZLEAK_S,ZLEAK_N
+!
+!-------------------------------------------------------------------------------
+!
+!*       1.    COMPUTE DIMENSIONS OF ARRAYS AND OTHER INDICES:
+!              ----------------------------------------------
+!
+CALL GET_INDICE_ll(IIB,IJB,IIE,IJE)
+!
+IKB = 1 + JPVEXT
+IKE = SIZE(PRUS,3) - JPVEXT
+!
+GWEST  = ( HLBCX(1) /= 'CYCL' .AND. LWEST_ll() )
+GEAST  = ( HLBCX(2) /= 'CYCL' .AND. LEAST_ll() )
+GSOUTH = ( HLBCY(1) /= 'CYCL' .AND. LSOUTH_ll() )
+GNORTH = ( HLBCY(2) /= 'CYCL' .AND. LNORTH_ll() )
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.    COMPUTATION OF LEAK
+!              -------------------
+!
+ZLEAK=0.
+ZLEAK_E=0.
+ZLEAK_W=0.
+ZLEAK_S=0.
+ZLEAK_N=0.
+!
+IF( HLBCY(1) /= 'CYCL' ) THEN
+   ALLOCATE( ZLEAK_W_2D(IIB:IIB,IJB:IJE))
+   ALLOCATE( ZLEAK_E_2D(IIE+1:IIE+1,IJB:IJE))   
+   !$acc kernels async
+   ZLEAK_W_2D = 0.0   
+   IF( GWEST ) THEN
+      DO JK=IKB,IKE
+         DO JJ=IJB,IJE
+            ZLEAK_W_2D(IIB,JJ) = ZLEAK_W_2D(IIB,JJ) - 1./PDXX(IIB,JJ,JK) *PRUS(IIB,JJ,JK)
+         END DO
+      END DO
+   END IF
+   !$acc end kernels
+   !
+   !$acc kernels async   
+   ZLEAK_E_2D = 0.0
+   IF( GEAST ) THEN   
+      DO JK=IKB,IKE
+         DO JJ=IJB,IJE
+            ZLEAK_E_2D(IIE+1,JJ) = ZLEAK_E_2D(IIE+1,JJ) + 1./PDXX(IIE+1,JJ,JK)*PRUS(IIE+1,JJ,JK)
+         END DO
+      END DO       
+   END IF
+   !$acc end kernels
+   !
+   !$acc wait
+   !
+   ZLEAK_W = SUM_DD_R2_ll(ZLEAK_W_2D)
+   ZLEAK_E = SUM_DD_R2_ll(ZLEAK_E_2D)
+END IF
+!
+IF( HLBCY(1) /= 'CYCL' ) THEN
+   ALLOCATE( ZLEAK_S_2D(IIB:IIE,IJB:IJB))
+   ALLOCATE( ZLEAK_N_2D(IIB:IIE,IJE+1:IJE+1))
+   !
+   !$acc kernels async
+   ZLEAK_S_2D = 0.0 
+   IF( GSOUTH ) THEN
+      DO JI=IIB,IIE
+         DO JK=IKB,IKE
+            ZLEAK_S_2D(JI,IJB) = ZLEAK_S_2D(JI,IJB) - 1./PDYY(JI,IJB,JK) *PRVS(JI,IJB,JK)
+         END DO
+      END DO
+   END IF
+   !$acc end kernels
+   !
+   !$acc kernels async
+   ZLEAK_N_2D = 0.0
+   IF ( GNORTH ) THEN
+      DO JI=IIB,IIE
+         DO JK=IKB,IKE
+            ZLEAK_N_2D(JI,IJE+1) = ZLEAK_N_2D(JI,IJE+1)  + 1./PDYY(JI,IJE+1,JK)*PRVS(JI,IJE+1,JK)
+         END DO
+      END DO
+   END IF
+   !$acc end kernels
+   !
+   !$acc wait
+   !
+   ZLEAK_S = SUM_DD_R2_ll(ZLEAK_S_2D)
+   ZLEAK_N = SUM_DD_R2_ll(ZLEAK_N_2D)   
+!
+END IF
+!
+ZLEAK = ZLEAK_E + ZLEAK_W + ZLEAK_S + ZLEAK_N
+!!$ZLEAK = ZLEAK_E
+!!$ZLEAK = ZLEAK + ZLEAK_W
+!!$ZLEAK = ZLEAK + ZLEAK_S
+!!$ZLEAK = ZLEAK + ZLEAK_N
+!
+!CALL REDUCESUM_ll(ZLEAK,IINFO_ll)	! we do the reducesum_ll in SUM_DD_R2_ll so we do not do it here
+!
+!-------------------------------------------------------------------------------
+!
+!*       3.    CORRECTION OF WIND ON OPEN BOUNDARIES
+!              -------------------------------------
+!
+ZUSTOP=ZLEAK
+ZUSTOP=ZUSTOP/PLINMASS
+!
+IF (HLBCX(1)=='OPEN' .AND. LWEST_ll() ) THEN
+   !$acc kernels async
+   PRUS(IIB,:,:)=PRUS(IIB,:,:)+ZUSTOP*0.5*(PRHODJ(IIB,:,:)+PRHODJ(IIB-1,:,:))
+   !$acc end kernels
+END IF
+!
+IF (HLBCX(2)=='OPEN' .AND. LEAST_ll() ) THEN
+   !$acc kernels async
+   PRUS(IIE+1,:,:)=PRUS(IIE+1,:,:)-ZUSTOP*0.5*(PRHODJ(IIE+1,:,:)+PRHODJ(IIE,:,:))
+   !$acc end kernels
+END IF
+!
+IF (HLBCY(1)=='OPEN' .AND. LSOUTH_ll() ) THEN
+   !$acc kernels async
+   PRVS(:,IJB,:)=PRVS(:,IJB,:)+ZUSTOP*0.5*(PRHODJ(:,IJB,:)+PRHODJ(:,IJB-1,:))
+   !$acc end kernels
+END IF
+!
+IF (HLBCY(2)=='OPEN' .AND. LNORTH_ll() ) THEN
+   !$acc kernels async
+   PRVS(:,IJE+1,:)=PRVS(:,IJE+1,:)-ZUSTOP*0.5*(PRHODJ(:,IJE+1,:)+PRHODJ(:,IJE,:))
+   !$acc end kernels
+END IF
+!
+!$acc wait
+!
+!
+!-------------------------------------------------------------------------------
+!
+END SUBROUTINE MASS_LEAK
diff --git a/src/ZSOLVER/modd_dynn.f90 b/src/ZSOLVER/modd_dynn.f90
new file mode 100644
index 0000000000000000000000000000000000000000..445105291501c6f96285c0eb1654124d801036a5
--- /dev/null
+++ b/src/ZSOLVER/modd_dynn.f90
@@ -0,0 +1,402 @@
+!MNH_LIC Copyright 1994-2018 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt  
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+!     #################
+      MODULE MODD_DYN_n
+!     #################
+!
+!!****  *MODD_DYN$n* - declaration of dynamic control variables 
+!!
+!!    PURPOSE
+!!    -------
+!       The purpose of this declarative module is to declare the dynamic
+!     control variables.    
+!
+!!
+!!**  IMPLICIT ARGUMENTS
+!!    ------------------
+!!      None 
+!!
+!!    REFERENCE
+!!    ---------
+!!      Book2 of documentation of Meso-NH (module MODD_DYNn)
+!!      Technical Specifications Report of the Meso-NH (chapters 2 and 3)
+!!          
+!!    AUTHOR
+!!    ------
+!!	V. Ducrocq   *Meteo France*
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original    18/05/94                      
+!!      Modifications 16/11/94   (Lafore+Pinty)  For NUM_DIFF
+!!      Modifications 06/01/95   (Lafore)        For LSTEADY_DMASS
+!!      Modifications 28/07/96   (Masson)        Supress LSTEADY_DMASS
+!!      Modifications 15/03/98   (Stein)         Add LHO_RELAX for each variables 
+!!      Modifications 22/01/01   (Gazen)         Add LHORELAX_SVC2R2, _SVCHEM, _SVLG
+!!      Modifications 29/11/02   (Pinty)         Add  LHORELAX_SVC1R3, _SVELEC
+!!      Modifications    07/05   (P.Tulet)       Add  relaxation for dust and aerosol
+!!      Modifications    05/07   (C.Lac)         Separation of num diffusion
+!!      Modifications    07/10   (M.Leriche)     Add relaxation for ice phase chemical
+!!      Modification    01/2016  (JP Pinty) Add LIMA
+!!  Philippe Wautelet: 05/2016-04/2018: new data structures and calls for I/O
+!!      Modification    07/2017  (V. Vionnet)    Add blowing snow variable
+!-------------------------------------------------------------------------------
+!
+!*       0.   DECLARATIONS
+!             ------------
+!
+USE MODD_PARAMETERS, ONLY: JPMODELMAX, JPSVMAX
+IMPLICIT NONE
+
+TYPE DYN_t
+!
+  INTEGER :: NSTOP          ! Number of time step
+  REAL    :: XTSTEP         ! Time step
+!
+!++++++++++++++++++++++++++++++++++
+!PART USED BY THE PRESSURE SOLVER
+!++++++++++++++++++++++++++++++++++
+!
+  REAL, DIMENSION(:,:,:), POINTER :: XBFY=>NULL()     ! Vectors giving the non
+  REAL, DIMENSION(:,:,:), POINTER :: XBFB=>NULL()     ! Vectors giving the non
+  REAL, DIMENSION(:,:,:), POINTER :: XBF_SXP2_YP1_Z=>NULL()     ! Vectors giving the non
+  REAL, DIMENSION(:,:,:), POINTER :: XBF=>NULL()      ! vanishing elements of the 
+  REAL, DIMENSION(:),     POINTER :: XAF=>NULL(),XCF=>NULL() ! tri-diag matrix in the pressure equation
+  REAL, DIMENSION(:,:,:), POINTER :: XAF_ZS=>NULL(),XBF_ZS=>NULL(),XCF_ZS=>NULL() ! coef for Zsolver   
+  REAL, DIMENSION(:,:)  , POINTER :: XDXATH_ZS=>NULL(),XDYATH_ZS=>NULL()
+  REAL, DIMENSION(:,:,:), POINTER :: XRHO_ZS=>NULL()
+  REAL, DIMENSION(:),     POINTER :: XA_K=>NULL(),XB_K=>NULL(),XC_K=>NULL(),XD_K=>NULL()
+!
+                                                   ! Arrays of sinus or cosinus
+                                                   ! values for the FFT 
+  REAL, DIMENSION(:),   POINTER :: XTRIGSX=>NULL()  ! in x-direction   
+  REAL, DIMENSION(:),   POINTER :: XTRIGSY=>NULL()  ! in y-direction   
+  INTEGER, DIMENSION(:),POINTER :: NIFAXX =>NULL()  ! Decomposition in prime numbers 
+  INTEGER, DIMENSION(:),POINTER :: NIFAXY =>NULL()  ! for the FFT in x and y directions 
+  CHARACTER(LEN=5)       :: CPRESOPT     ! Choice of the pressure solver
+  INTEGER                :: NITR         ! Number of iterations for the 
+                                            ! pressure solver
+  LOGICAL                :: LITRADJ      ! Choice to adjust the number of 
+                                            !solver iterations during
+                                            !the simulation
+  LOGICAL                :: LRES         ! Choice of a different residual
+                                         ! divergence limit
+  REAL                   :: XRES         ! Value of residual divergence limit
+  REAL                   :: XRELAX       ! relaxation coefficient for the
+                                         ! Richardson's method
+!
+  REAL :: XDXHATM                        ! mean grid increment in the 
+  REAL :: XDYHATM                        ! x and  y directions
+
+  REAL, DIMENSION (:), POINTER  :: XRHOM=>NULL()  !  mean of XRHODJ on the plane x y 
+                                                 !  localized at a mass level
+!
+!++++++++++++++++++++++++++++++++++
+!PART USED BY THE ABSORBING LAYERS 
+!++++++++++++++++++++++++++++++++++
+!
+  INTEGER      :: NALBOT     ! Vertical index corresponding to the     
+                                ! absorbing layer base
+!  
+  INTEGER      :: NALBAS     ! Vertical index corresponding to the     
+                                ! absorbing layer base
+!                                
+  REAL, DIMENSION(:),   POINTER :: XALK=>NULL()  ! Function of the absorbing
+                                ! layer damping coefficient defined for
+                                !   u,v,and theta
+  REAL, DIMENSION(:),   POINTER :: XALKW=>NULL() ! Idem but defined for w 
+!
+  REAL, DIMENSION(:),   POINTER :: XALKBAS=>NULL()  ! Function of the absorbing
+                                ! layer damping coefficient defined for
+                                !   u,v,and theta
+  REAL, DIMENSION(:),   POINTER :: XALKWBAS=>NULL() ! Idem but defined for w 
+!
+  LOGICAL ::  LVE_RELAX ! switch to activate the VErtical RELAXation
+  LOGICAL ::  LVE_RELAX_GRD ! switch to activate the VErtical RELAXation
+!
+!                            switch to activate the HOrizontal RELAXation
+!  LOGICAL :: LHORELAX_UVWTH
+!
+  LOGICAL :: LHORELAX_RV, LHORELAX_RC, LHORELAX_RR, LHORELAX_RI
+  LOGICAL :: LHORELAX_RS, LHORELAX_RG, LHORELAX_RH
+!
+!  LOGICAL :: LHORELAX_TKE
+!
+  LOGICAL :: LHORELAX_SVC2R2
+  LOGICAL :: LHORELAX_SVC1R3
+  LOGICAL :: LHORELAX_SVLIMA
+  LOGICAL :: LHORELAX_SVELEC
+  LOGICAL :: LHORELAX_SVCHEM
+  LOGICAL :: LHORELAX_SVCHIC
+  LOGICAL :: LHORELAX_SVLG
+  LOGICAL :: LHORELAX_SVDST
+  LOGICAL :: LHORELAX_SVSLT
+  LOGICAL :: LHORELAX_SVAER
+  LOGICAL :: LHORELAX_SVPP 
+#ifdef MNH_FOREFIRE
+  LOGICAL :: LHORELAX_SVFF
+#endif
+  LOGICAL :: LHORELAX_SVCS 
+  LOGICAL :: LHORELAX_SVSNW  
+  LOGICAL, DIMENSION(:),POINTER :: LHORELAX_SV =>NULL()
+!
+  REAL    :: XRIMKMAX   ! Max. value of the horiz. relaxation coeff.
+!  INTEGER :: NRIMX,NRIMY! Number of points in the lateral absorbing
+                           ! layer in the x and y directions 
+! sizes of the West-east total LB area
+  INTEGER :: NSIZELBX_ll,NSIZELBXU_ll      ! for T,V,W and u 
+  INTEGER :: NSIZELBXTKE_ll                ! for TKE       
+  INTEGER :: NSIZELBXR_ll,NSIZELBXSV_ll    ! for Rx and SV    
+! sizes of the North-south total LB area
+  INTEGER :: NSIZELBY_ll,NSIZELBYV_ll      ! for T,U,W  and v
+  INTEGER :: NSIZELBYTKE_ll                ! for TKE       
+  INTEGER :: NSIZELBYR_ll,NSIZELBYSV_ll    ! for Rx and SV    
+  LOGICAL, DIMENSION(:,:),  POINTER   :: LMASK_RELAX=>NULL()  ! Mask for lateral
+                           ! relaxation: True where it has to be performed
+  REAL, DIMENSION(:,:),     POINTER   :: XKURELAX=>NULL() ! Horizontal relaxation
+  REAL, DIMENSION(:,:),     POINTER   :: XKVRELAX=>NULL() ! coefficients for the
+  REAL, DIMENSION(:,:),     POINTER   :: XKWRELAX=>NULL() ! u, v and mass locations
+!
+!++++++++++++++++++++++++++++++++++++
+!PART USED BY THE NUMERICAL DIFFUSION
+!++++++++++++++++++++++++++++++++++++
+!
+  REAL              :: XT4DIFU ! Damping time scale for 2*dx wavelength
+                               ! specified for the 4nd order num. diffusion
+                               ! for momentum
+  REAL              :: XT4DIFTH! for theta and mixing ratios                  
+  REAL              :: XT4DIFSV! for scalar variables                         
+  REAL              :: XDK2U   ! 2nd order num. diffusion coef. /dx2
+                               ! for momentum
+  REAL              :: XDK4U   ! 4nd order num. diffusion coef. /dx4
+                               ! for momentum
+  REAL              :: XDK2TH  ! for theta and mixing ratios                                        
+  REAL              :: XDK4TH  ! for theta and mixing ratios           
+  REAL              :: XDK2SV  ! for scalar variables                                                               
+  REAL              :: XDK4SV  ! for scalar variables                  
+!
+END TYPE DYN_t
+
+TYPE(DYN_t), DIMENSION(JPMODELMAX), TARGET, SAVE :: DYN_MODEL
+LOGICAL    , DIMENSION(JPMODELMAX),         SAVE :: DYN_FIRST_CALL = .TRUE.
+
+INTEGER, POINTER :: NSTOP=>NULL()
+REAL, POINTER :: XTSTEP=>NULL()
+REAL, DIMENSION(:,:,:), POINTER :: XBFY=>NULL()
+REAL, DIMENSION(:,:,:), POINTER :: XBFB=>NULL()
+REAL, DIMENSION(:,:,:), POINTER :: XBF_SXP2_YP1_Z=>NULL()
+REAL, DIMENSION(:,:,:), POINTER :: XBF=>NULL()
+REAL, DIMENSION(:),     POINTER :: XAF=>NULL(),XCF=>NULL()
+REAL, DIMENSION(:,:,:), POINTER :: XAF_ZS=>NULL(),XBF_ZS=>NULL(),XCF_ZS=>NULL()
+REAL, DIMENSION(:,:)  , POINTER :: XDXATH_ZS=>NULL(),XDYATH_ZS=>NULL()
+REAL, DIMENSION(:,:,:), POINTER :: XRHO_ZS=>NULL() 
+REAL, DIMENSION(:),     POINTER :: XA_K=>NULL(),XB_K=>NULL(),XC_K=>NULL(),XD_K=>NULL()
+REAL, DIMENSION(:),   POINTER :: XTRIGSX=>NULL()
+REAL, DIMENSION(:),   POINTER :: XTRIGSY=>NULL()
+INTEGER, DIMENSION(:), POINTER :: NIFAXX=>NULL()
+INTEGER, DIMENSION(:), POINTER :: NIFAXY=>NULL()
+CHARACTER(LEN=5), POINTER :: CPRESOPT=>NULL()
+INTEGER, POINTER :: NITR=>NULL()
+LOGICAL, POINTER :: LITRADJ=>NULL()
+LOGICAL, POINTER :: LRES=>NULL()
+REAL, POINTER :: XRES=>NULL()
+REAL, POINTER :: XRELAX=>NULL()
+REAL, POINTER :: XDXHATM=>NULL()
+REAL, POINTER :: XDYHATM=>NULL()
+REAL, DIMENSION (:), POINTER  :: XRHOM=>NULL()
+INTEGER, POINTER :: NALBOT=>NULL()
+REAL, DIMENSION(:),   POINTER :: XALK=>NULL()
+REAL, DIMENSION(:),   POINTER :: XALKW=>NULL()
+INTEGER, POINTER :: NALBAS=>NULL()
+REAL, DIMENSION(:),   POINTER :: XALKBAS=>NULL()
+REAL, DIMENSION(:),   POINTER :: XALKWBAS=>NULL()
+LOGICAL, POINTER :: LVE_RELAX=>NULL()
+LOGICAL, POINTER :: LVE_RELAX_GRD=>NULL()
+LOGICAL, POINTER :: LHORELAX_UVWTH=>NULL()
+LOGICAL, POINTER :: LHORELAX_RV=>NULL(), LHORELAX_RC=>NULL(), LHORELAX_RR=>NULL(), LHORELAX_RI=>NULL()
+LOGICAL, POINTER :: LHORELAX_RS=>NULL(), LHORELAX_RG=>NULL(), LHORELAX_RH=>NULL()
+LOGICAL, POINTER :: LHORELAX_TKE=>NULL()
+LOGICAL, POINTER :: LHORELAX_SVC2R2=>NULL()
+LOGICAL, POINTER :: LHORELAX_SVC1R3=>NULL()
+LOGICAL, POINTER :: LHORELAX_SVLIMA=>NULL()
+LOGICAL, POINTER :: LHORELAX_SVELEC=>NULL()
+LOGICAL, POINTER :: LHORELAX_SVCHEM=>NULL()
+LOGICAL, POINTER :: LHORELAX_SVCHIC=>NULL()
+LOGICAL, POINTER :: LHORELAX_SVLG=>NULL()
+LOGICAL, POINTER :: LHORELAX_SVDST=>NULL()
+LOGICAL, POINTER :: LHORELAX_SVSLT=>NULL()
+LOGICAL, POINTER :: LHORELAX_SVAER=>NULL()
+LOGICAL, POINTER :: LHORELAX_SVPP=>NULL()
+#ifdef MNH_FOREFIRE
+LOGICAL, POINTER :: LHORELAX_SVFF=>NULL()
+#endif
+LOGICAL, POINTER :: LHORELAX_SVCS=>NULL()
+LOGICAL, POINTER :: LHORELAX_SVSNW=>NULL()
+LOGICAL, DIMENSION(:), POINTER :: LHORELAX_SV=>NULL()
+REAL, POINTER :: XRIMKMAX=>NULL()
+INTEGER, POINTER :: NRIMX=>NULL(),NRIMY=>NULL()
+INTEGER, POINTER :: NSIZELBX_ll=>NULL(),NSIZELBXU_ll=>NULL()
+INTEGER, POINTER :: NSIZELBXTKE_ll=>NULL()
+INTEGER, POINTER :: NSIZELBXR_ll=>NULL(),NSIZELBXSV_ll=>NULL()
+INTEGER, POINTER :: NSIZELBY_ll=>NULL(),NSIZELBYV_ll=>NULL()
+INTEGER, POINTER :: NSIZELBYTKE_ll=>NULL()
+INTEGER, POINTER :: NSIZELBYR_ll=>NULL(),NSIZELBYSV_ll=>NULL()
+LOGICAL, DIMENSION(:,:),  POINTER   :: LMASK_RELAX=>NULL()
+REAL, DIMENSION(:,:),     POINTER   :: XKURELAX=>NULL()
+REAL, DIMENSION(:,:),     POINTER   :: XKVRELAX=>NULL()
+REAL, DIMENSION(:,:),     POINTER   :: XKWRELAX=>NULL()
+REAL, POINTER :: XT4DIFU=>NULL()
+REAL, POINTER :: XDK2U=>NULL()
+REAL, POINTER :: XDK4U=>NULL()
+REAL, POINTER :: XT4DIFTH=>NULL()
+REAL, POINTER :: XDK2TH=>NULL()
+REAL, POINTER :: XDK4TH=>NULL()
+REAL, POINTER :: XT4DIFSV=>NULL()
+REAL, POINTER :: XDK2SV=>NULL()
+REAL, POINTER :: XDK4SV=>NULL()
+
+CONTAINS
+
+SUBROUTINE DYN_GOTO_MODEL(KFROM, KTO)
+INTEGER, INTENT(IN) :: KFROM, KTO
+!
+IF (DYN_FIRST_CALL(KTO)) THEN
+ALLOCATE (DYN_MODEL(KTO)%NIFAXX(19))
+ALLOCATE (DYN_MODEL(KTO)%NIFAXY(19))
+ALLOCATE (DYN_MODEL(KTO)%LHORELAX_SV(JPSVMAX))
+DYN_FIRST_CALL(KTO) = .FALSE.
+ENDIF
+! Save current state for allocated arrays
+DYN_MODEL(KFROM)%XBFY=>XBFY
+DYN_MODEL(KFROM)%XBFB=>XBFB
+DYN_MODEL(KFROM)%XBF_SXP2_YP1_Z=>XBF_SXP2_YP1_Z
+DYN_MODEL(KFROM)%XBF=>XBF
+DYN_MODEL(KFROM)%XAF=>XAF
+DYN_MODEL(KFROM)%XCF=>XCF
+
+DYN_MODEL(KFROM)%XAF_ZS=>XAF_ZS
+DYN_MODEL(KFROM)%XBF_ZS=>XBF_ZS
+DYN_MODEL(KFROM)%XCF_ZS=>XCF_ZS
+
+DYN_MODEL(KFROM)%XDXATH_ZS=>XDXATH_ZS
+DYN_MODEL(KFROM)%XDYATH_ZS=>XDYATH_ZS
+DYN_MODEL(KFROM)%XRHO_ZS=>XRHO_ZS
+DYN_MODEL(KFROM)%XA_K=>XA_K
+DYN_MODEL(KFROM)%XB_K=>XB_K
+DYN_MODEL(KFROM)%XC_K=>XC_K
+DYN_MODEL(KFROM)%XD_K=>XD_K
+
+DYN_MODEL(KFROM)%XTRIGSX=>XTRIGSX
+DYN_MODEL(KFROM)%XTRIGSY=>XTRIGSY
+DYN_MODEL(KFROM)%XRHOM=>XRHOM
+DYN_MODEL(KFROM)%XALK=>XALK
+DYN_MODEL(KFROM)%XALKW=>XALKW
+DYN_MODEL(KFROM)%XALKBAS=>XALKBAS
+DYN_MODEL(KFROM)%XALKWBAS=>XALKWBAS
+DYN_MODEL(KFROM)%LMASK_RELAX=>LMASK_RELAX
+DYN_MODEL(KFROM)%XKURELAX=>XKURELAX
+DYN_MODEL(KFROM)%XKVRELAX=>XKVRELAX
+DYN_MODEL(KFROM)%XKWRELAX=>XKWRELAX
+!
+! Current model is set to model KTO
+NSTOP=>DYN_MODEL(KTO)%NSTOP
+XTSTEP=>DYN_MODEL(KTO)%XTSTEP
+XBFY=>DYN_MODEL(KTO)%XBFY
+XBFB=>DYN_MODEL(KTO)%XBFB
+XBF_SXP2_YP1_Z=>DYN_MODEL(KTO)%XBF_SXP2_YP1_Z
+XBF=>DYN_MODEL(KTO)%XBF
+XAF=>DYN_MODEL(KTO)%XAF
+XCF=>DYN_MODEL(KTO)%XCF
+
+XAF_ZS=>DYN_MODEL(KTO)%XAF_ZS
+XBF_ZS=>DYN_MODEL(KTO)%XBF_ZS
+XCF_ZS=>DYN_MODEL(KTO)%XCF_ZS
+
+XDXATH_ZS=>DYN_MODEL(KFROM)%XDXATH_ZS
+XDYATH_ZS=>DYN_MODEL(KFROM)%XDYATH_ZS
+XRHO_ZS=>DYN_MODEL(KFROM)%XRHO_ZS
+XA_K=>DYN_MODEL(KFROM)%XA_K
+XB_K=>DYN_MODEL(KFROM)%XB_K
+XC_K=>DYN_MODEL(KFROM)%XC_K
+XD_K=>DYN_MODEL(KFROM)%XD_K
+
+XTRIGSX=>DYN_MODEL(KTO)%XTRIGSX
+XTRIGSY=>DYN_MODEL(KTO)%XTRIGSY
+NIFAXX=>DYN_MODEL(KTO)%NIFAXX
+NIFAXY=>DYN_MODEL(KTO)%NIFAXY
+CPRESOPT=>DYN_MODEL(KTO)%CPRESOPT
+NITR=>DYN_MODEL(KTO)%NITR
+LITRADJ=>DYN_MODEL(KTO)%LITRADJ
+LRES=>DYN_MODEL(KTO)%LRES          
+XRES=>DYN_MODEL(KTO)%XRES
+XRELAX=>DYN_MODEL(KTO)%XRELAX
+XDXHATM=>DYN_MODEL(KTO)%XDXHATM
+XDYHATM=>DYN_MODEL(KTO)%XDYHATM
+XRHOM=>DYN_MODEL(KTO)%XRHOM
+NALBOT=>DYN_MODEL(KTO)%NALBOT
+XALK=>DYN_MODEL(KTO)%XALK
+XALKW=>DYN_MODEL(KTO)%XALKW
+NALBAS=>DYN_MODEL(KTO)%NALBAS
+XALKBAS=>DYN_MODEL(KTO)%XALKBAS
+XALKWBAS=>DYN_MODEL(KTO)%XALKWBAS
+LVE_RELAX=>DYN_MODEL(KTO)%LVE_RELAX
+LVE_RELAX_GRD=>DYN_MODEL(KTO)%LVE_RELAX_GRD
+!LHORELAX_UVWTH=>DYN_MODEL(KTO)%LHORELAX_UVWTH !Done in FIELDLIST_GOTO_MODEL
+LHORELAX_RV=>DYN_MODEL(KTO)%LHORELAX_RV
+LHORELAX_RC=>DYN_MODEL(KTO)%LHORELAX_RC
+LHORELAX_RR=>DYN_MODEL(KTO)%LHORELAX_RR
+LHORELAX_RI=>DYN_MODEL(KTO)%LHORELAX_RI
+LHORELAX_RS=>DYN_MODEL(KTO)%LHORELAX_RS
+LHORELAX_RG=>DYN_MODEL(KTO)%LHORELAX_RG
+LHORELAX_RH=>DYN_MODEL(KTO)%LHORELAX_RH
+!LHORELAX_TKE=>DYN_MODEL(KTO)%LHORELAX_TKE !Done in FIELDLIST_GOTO_MODEL
+LHORELAX_SVC2R2=>DYN_MODEL(KTO)%LHORELAX_SVC2R2
+LHORELAX_SVC1R3=>DYN_MODEL(KTO)%LHORELAX_SVC1R3
+LHORELAX_SVLIMA=>DYN_MODEL(KTO)%LHORELAX_SVLIMA
+LHORELAX_SVELEC=>DYN_MODEL(KTO)%LHORELAX_SVELEC
+LHORELAX_SVCHEM=>DYN_MODEL(KTO)%LHORELAX_SVCHEM
+LHORELAX_SVCHIC=>DYN_MODEL(KTO)%LHORELAX_SVCHIC
+LHORELAX_SVLG=>DYN_MODEL(KTO)%LHORELAX_SVLG
+LHORELAX_SVDST=>DYN_MODEL(KTO)%LHORELAX_SVDST
+LHORELAX_SVSLT=>DYN_MODEL(KTO)%LHORELAX_SVSLT
+LHORELAX_SVAER=>DYN_MODEL(KTO)%LHORELAX_SVAER
+LHORELAX_SVPP=>DYN_MODEL(KTO)%LHORELAX_SVPP
+#ifdef MNH_FOREFIRE
+LHORELAX_SVFF=>DYN_MODEL(KTO)%LHORELAX_SVFF
+#endif
+LHORELAX_SVCS=>DYN_MODEL(KTO)%LHORELAX_SVCS
+LHORELAX_SVSNW=>DYN_MODEL(KTO)%LHORELAX_SVSNW
+LHORELAX_SV=>DYN_MODEL(KTO)%LHORELAX_SV
+XRIMKMAX=>DYN_MODEL(KTO)%XRIMKMAX
+!NRIMX=>DYN_MODEL(KTO)%NRIMX !Done in FIELDLIST_GOTO_MODEL
+!NRIMY=>DYN_MODEL(KTO)%NRIMY !Done in FIELDLIST_GOTO_MODEL
+NSIZELBX_ll=>DYN_MODEL(KTO)%NSIZELBX_ll
+NSIZELBXU_ll=>DYN_MODEL(KTO)%NSIZELBXU_ll
+NSIZELBXTKE_ll=>DYN_MODEL(KTO)%NSIZELBXTKE_ll
+NSIZELBXR_ll=>DYN_MODEL(KTO)%NSIZELBXR_ll
+NSIZELBXSV_ll=>DYN_MODEL(KTO)%NSIZELBXSV_ll
+NSIZELBY_ll=>DYN_MODEL(KTO)%NSIZELBY_ll
+NSIZELBYV_ll=>DYN_MODEL(KTO)%NSIZELBYV_ll
+NSIZELBYTKE_ll=>DYN_MODEL(KTO)%NSIZELBYTKE_ll
+NSIZELBYR_ll=>DYN_MODEL(KTO)%NSIZELBYR_ll
+NSIZELBYSV_ll=>DYN_MODEL(KTO)%NSIZELBYSV_ll
+LMASK_RELAX=>DYN_MODEL(KTO)%LMASK_RELAX
+XKURELAX=>DYN_MODEL(KTO)%XKURELAX
+XKVRELAX=>DYN_MODEL(KTO)%XKVRELAX
+XKWRELAX=>DYN_MODEL(KTO)%XKWRELAX
+XT4DIFU=>DYN_MODEL(KTO)%XT4DIFU
+XDK2U=>DYN_MODEL(KTO)%XDK2U
+XDK4U=>DYN_MODEL(KTO)%XDK4U
+XT4DIFTH=>DYN_MODEL(KTO)%XT4DIFTH
+XDK2TH=>DYN_MODEL(KTO)%XDK2TH
+XDK4TH=>DYN_MODEL(KTO)%XDK4TH
+XT4DIFSV=>DYN_MODEL(KTO)%XT4DIFSV
+XDK2SV=>DYN_MODEL(KTO)%XDK2SV
+XDK4SV=>DYN_MODEL(KTO)%XDK4SV
+
+END SUBROUTINE DYN_GOTO_MODEL
+
+END MODULE MODD_DYN_n
diff --git a/src/ZSOLVER/modeln.f90 b/src/ZSOLVER/modeln.f90
new file mode 100644
index 0000000000000000000000000000000000000000..a65e4e58abd7369dc942b9d7956f844df1cfa6dc
--- /dev/null
+++ b/src/ZSOLVER/modeln.f90
@@ -0,0 +1,2257 @@
+!MNH_LIC Copyright 1994-2020 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+!     ###################
+      MODULE MODI_MODEL_n
+!     ###################
+!
+INTERFACE
+!
+       SUBROUTINE MODEL_n(KTCOUNT,OEXIT)
+!
+INTEGER, INTENT(IN)   :: KTCOUNT  ! temporal loop index of model KMODEL
+LOGICAL, INTENT(INOUT):: OEXIT    ! switch for the end of the temporal loop
+!
+END SUBROUTINE MODEL_n
+!
+END INTERFACE
+!
+END MODULE MODI_MODEL_n
+
+!     ################################### 
+      SUBROUTINE MODEL_n(KTCOUNT, OEXIT) 
+!     ###################################
+!
+!!****  *MODEL_n * -monitor of the model version _n 
+!!
+!!    PURPOSE
+!!    -------
+!       The purpose of this routine is to build up a typical model version
+!     by sequentially calling the specialized routines.
+!
+!!**  METHOD
+!!    ------
+!!      Some preliminary initializations are performed in the first section.
+!!    Then, specialized routines are called to update the guess of the future
+!!    instant XRxxS of the variable xx by adding the effects of all the
+!!    different sources of evolution.
+!!
+!!              (guess of xx at t+dt) * Rhod_ref * Jacobian
+!!      XRxxS = -------------------------------------------
+!!                           2 dt
+!!
+!!      At this level, the informations are transferred with a USE association
+!!    from the INIT step, where the modules have been previously filled. The
+!!    transfer to the subroutines computing each source term is performed by
+!!    argument in order to avoid repeated compilations of these subroutines.
+!!      This monitor model_n, must therefore be duplicated for each model,
+!!    model1 corresponds in this case to the outermost model, model2 is used
+!!    for the first level of gridnesting,....  
+!!      The effect of all parameterizations is computed in PHYS_PARAM_n, which
+!!    is itself a monitor. This is due to a possible large number of
+!!    parameterizations, which can be activated and therefore, will require a
+!!    very large list of arguments. To circumvent this problem, we transfer by
+!!    a USE association, the necessary informations in this monitor, which will
+!!    dispatch the pertinent information to every parametrization.
+!!      Some elaborated diagnostics, LES tools, budget storages are also called
+!!    at this level because they require informations about the fields at every
+!!    timestep.
+!!
+!!
+!!    EXTERNAL
+!!    --------
+!!      Subroutine IO_File_open: to open a file
+!!      Subroutine WRITE_DESFM: to write the descriptive part of a FMfile
+!!      Subroutine WRITE_LFIFM: to write the binary part of a FMfile
+!!      Subroutine SET_MASK   : to compute all the masks selected for budget
+!!                         computations
+!!      Subroutine BOUNDARIES   : set the fields at the marginal points in every
+!!                         directions according the selected boundary conditions
+!!      Subroutine INITIAL_GUESS: initializes the guess of the future instant
+!!      Subroutine LES_FLX_SPECTRA: computes the resolved fluxes and the
+!!                     spectra of some quantities when running in LES mode.
+!!      Subroutine ADVECTION: computes the advection terms.
+!!      Subroutine DYN_SOURCES: computes the curvature, Coriolis, gravity terms.
+!!      Subroutine NUM_DIFF: applies the fourth order numerical diffusion.
+!!      Subroutine RELAXATION: performs the relaxation to Larger Scale fields
+!!                             in the upper levels and outermost vertical planes
+!!      Subroutine PHYS_PARAM_n : computes the parameterized physical terms
+!!      Subroutine RAD_BOUND: prepares the velocity normal components for the bc.
+!!      Subroutine RESOLVED_CLOUD : computes the sources terms for water in any
+!!                                  form
+!!      Subroutine PRESSURE : computes the pressure gradient term and the
+!!                            absolute pressure
+!!      Subroutine EXCHANGE : updates the halo of each subdomains
+!!      Subroutine ENDSTEP : advances in time the  fields.
+!!      Subroutines UVW_LS_COUPLING and SCALAR_LS_COUPLING:
+!!                                 compute the large scale fields, used to
+!!                                 couple Model_n with outer informations.
+!!      Subroutine ENDSTEP_BUDGET: writes the budget informations.
+!!      Subroutine IO_File_close: closes a file
+!!      Subroutine DATETIME_CORRECTDATE: transform the current time in GMT
+!!      Subroutine FORCING : computes forcing terms
+!!      Subroutine ADD3DFIELD_ll : add a field to 3D-list
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------
+!!          MODD_DYN
+!!          MODD_CONF
+!!          MODD_NESTING
+!!          MODD_BUDGET
+!!          MODD_PARAMETERS
+!!          MODD_CONF_n
+!!          MODD_CURVCOR_n
+!!          MODD_DYN_n
+!!          MODD_DIM_n
+!!          MODD_ADV_n
+!!          MODD_FIELD_n
+!!          MODD_LSFIELD_n
+!!          MODD_GRID_n
+!!          MODD_METRICS_n
+!!          MODD_LBC_n
+!!          MODD_PARAM_n
+!!          MODD_REF_n
+!!          MODD_LUNIT_n
+!!          MODD_OUT_n
+!!          MODD_TIME_n
+!!          MODD_TURB_n
+!!          MODD_CLOUDPAR_n
+!!          MODD_TIME
+!!
+!!    REFERENCE
+!!    ---------
+!!
+!!    AUTHOR
+!!    ------
+!!      J.-P. Pinty                  * LA *
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original    15/09/94
+!!      Modification 20/10/94  (J.Stein) for the outputs and abs_layers routines
+!!      Modification 10/11/94  (J.Stein) change ABS_LAYER_FIELDS call
+!!      Modification 16/11/94  (J.Stein) add call to the renormalization
+!!      Modification 17/11/94  (J.-P. Lafore and J.-P. Pinty) call NUM_DIFF
+!!      Modification 08/12/94  (J.Stein) cleaning + remove (RENORM + ABS_LAYER..
+!!                             ..) + add RELAXATION + LS fiels in the arguments
+!!      Modification 19/12/94  (J.Stein) switch for the num diff
+!!      Modification 22/12/94  (J.Stein) update tdtcur + change dyn_source call
+!!      Modification 05/01/95  (J.Stein) add the parameterization monitor
+!!      Modification 09/01/95  (J.Stein) add the 1D switch
+!!      Modification 10/01/95  (J.Stein) displace the TDTCUR computation
+!!      Modification 03/01/95  (J.-P. Lafore) Absolute pressure diagnosis
+!!      Modification Jan 19, 1995 (J. Cuxart) Shunt the DYN_SOURCES in 1D cases.
+!!      Modification Jan 24, 1995 (J. Stein)  Interchange Boundaries and
+!!                           Initial_guess to correct a bug in 2D configuration
+!!      Modification Feb 02, 1995 (I.Mallet) update BOUNDARIES and RAD_BOUND
+!!                                           calls
+!!      Modification Mar 10, 1995 (I.Mallet) add call to SET_COUPLING
+!!                   March,21, 1995 (J. Stein) remove R from the historical var.
+!!                   March,26, 1995 (J. Stein) add the EPS variable
+!!                   April 18, 1995 (J. Cuxart) add the LES call
+!!                   Sept 20,1995 (Lafore) coupling for the dry mass Md
+!!                   Nov   2,1995 (Stein) displace the temporal counter increase
+!!                   Jan   2,1996 (Stein) rm the test on the temporal counter
+!!      Modification Feb   5,1996 (J. Vila) implementation new advection
+!!                                          schemes for scalars
+!!      Modification Feb  20,1996 (J.Stein) doctor norm
+!!                   Dec95 - Jul96 (Georgelin, Pinty, Mari, Suhre) FORCING
+!!                   June 17,1996 (Vincent, Lafore, Jabouille)
+!!                                        statistics of computing time
+!!                   Aug 8, 1996 (K. Suhre) add chemistry
+!!                   October 12, 1996 (J. Stein) save the PSRC value
+!!                   Sept 05,1996 (V.Masson) print of loop index for debugging
+!!                                           purposes
+!!                   July 22,1996 (Lafore) improve write of computing time statistics
+!!                   July 29,1996 (Lafore) nesting introduction
+!!                   Aug.  1,1996 (Lafore) synchronization between models
+!!                   Sept. 4,1996 (Lafore) modification of call to routine SET_COUPLING
+!!                                         now splitted in 2 routines
+!!                                         (UVW_LS_COUPLING and SCALAR_LS_COUPLING)
+!!                   Sept  5,1996 (V.Masson) print of loop index for debugging
+!!                                           purposes
+!!                   Sept 25,1996 (V.Masson) test for coupling performed here
+!!                   Oct. 29,1996 (Lafore)   one-way nesting implementation
+!!                   Oct. 12,1996 (J. Stein) save the PSRC value
+!!                   Dec. 12,1996 (Lafore)   change call to RAD_BOUND
+!!                   Dec. 21,1996 (Lafore)   two-way nesting implementation
+!!                   Mar. 12,1997 (Lafore)   introduction of "surfacic" LS fields
+!!                   Nov 18, 1996 (J.-P. Pinty) FORCING revisited (translation)
+!!                   Dec 04, 1996 (J.-P. Pinty) include mixed-phase clouds
+!!                   Dec 20, 1996 (J.-P. Pinty) update the budgets
+!!                   Dec 23, 1996 (J.-P. Pinty) add the diachronic file control
+!!                   Jan 11, 1997 (J.-P. Pinty) add the deep convection control
+!!                   Dec  20,1996 (V.Masson) call boundaries before the writing
+!!                   Fev 25, 1997 (P.Jabouille) modify the LES tools
+!!                   April 3,1997 (Lafore)      merging of the nesting
+!!                                              developments on MASTER3
+!!                   Jul.  8,1997 (Lafore)  print control for nesting (NVERB>=7)
+!!                   Jul. 28,1997 (Masson)  supress LSTEADY_DMASS
+!!                   Aug. 19,1997 (Lafore)  full Clark's formulation introduction
+!!                   Sept 26,1997 (Lafore)  LS source calculation at restart
+!!                                          (temporarily test to have LS at instant t)
+!!                   Jan. 28,1998 (Bechtold) add SST forcing
+!!                   fev. 10,1998 (Lafore)  RHODJ computation and storage for budget
+!!                   Jul. 10,1998 (Stein )  sequentiel loop for nesting
+!!                   Apr. 07,1999 (Stein )  cleaning of the nesting subroutines
+!!                   oct. 20,1998 (Jabouille) //
+!!                   oct. 20,2000 (J.-P. Pinty) add the C2R2 scheme
+!!                   fev. 01,2001 (D.Gazen) add module MODD_NSV for NSV variables
+!!                   mar,  4,2002 (V.Ducrocq) call to temporal series
+!!                   mar, 8, 2001 (V. Masson) advection of perturbation of theta in neutral cases.
+!!                   Nov, 6, 2002 (V. Masson) time counters for budgets & LES
+!!                   mars 20,2001 (Pinty)   add ICE4 and C3R5 options
+!!                   jan. 2004    (Masson)  surface externalization
+!!                   sept 2004 (M. Tomasini) Cloud mixing length modification
+!!                   june 2005 (P. Tulet)  add aerosols / dusts
+!!                   Jul. 2005 (N. Asencio)  two_way and phys_param calls: 
+!!                             Add the surface parameters : precipitating 
+!!                             hydrometeors, Short and Long Wave , MASKkids array 
+!!                   Fev. 2006 (M. Leriche) add aqueous phase chemistry
+!!                   april 2006 (T.Maric) Add halo related to 4th order advection scheme
+!!                   May 2006 Remove KEPS
+!!                   Oct 2008 (C.Lac) FIT for variables advected with PPM
+!!                   July 2009 : Displacement of surface diagnostics call to be
+!!                               coherent with  surface diagnostics obtained with DIAG
+!!                   10/11/2009 (P. Aumond) Add mean moments
+!!                   Nov, 12, 2009 (C. Barthe) add cloud electrification and lightning flashes
+!!                   July 2010 (M. Leriche) add ice phase chemical species
+!!                   April 2011 (C.Lac) : Remove instant M 
+!!                   April 2011 (C.Lac, V.Masson) : Time splitting for advection
+!!      J.Escobar 21/03/2013: for HALOK comment all NHALO=1 test
+!!       P. Tulet      Nov 2014 accumulated moles of aqueous species that fall at the surface   
+!!                   Dec 2014 (C.Lac) : For reproducibility START/RESTA
+!!      J.Escobar 20/04/2015: missing UPDATE_HALO before UPDATE_HALO2
+!!              July, 2015 (O.Nuissier/F.Duffourg) Add microphysics diagnostic for
+!!                                      aircraft, ballon and profiler
+!!       C.Lac    11/09/2015: correction of the budget due to FIT temporal scheme
+!!      J.Escobar : 15/09/2015 : WENO5 & JPHEXT <> 1
+!!                   Sep 2015 (S. Bielli) : Remove YDADFILE from argument call 
+!                              of write_phys_param
+!!      J.Escobar : 19/04/2016 : Pb IOZ/NETCDF , missing OPARALLELIO=.FALSE. for PGD files
+!!      M.Mazoyer : 04/2016      DTHRAD used for radiative cooling when LACTIT
+!!!      Modification    01/2016  (JP Pinty) Add LIMA
+!!  06/2016     (G.Delautier) phasage surfex 8
+!!      M.Leriche : 03/2016 Move computation of accumulated chem. in rain to ch_monitor
+!!                  09/2016 Add filter on negative values on AERDEP SV before relaxation
+!!                  10/2016  (C.Lac) _ Correction on the flag for Strang splitting
+!!                                  to insure reproducibility between START and RESTA
+!!                                  _  Add OSPLIT_WENO
+!!                                  _ Add droplet deposition 
+!!                   10/2016 (M.Mazoyer) New KHKO output fields
+!!      P.Wautelet : 11/07/2016 : removed MNH_NCWRIT define
+!!                   09/2017 Q.Rodier add LTEND_UV_FRC
+!!                   10/2017 (C.Lac) Necessity to have chemistry processes as
+!!                            the las process modifying XRSVS
+!!  01/2018      (G.Delautier) SURFEX 8.1
+!!  03/2018     (P.Wautelet)   replace ADD_FORECAST_TO_DATE by DATETIME_CORRECTDATE
+!!  Philippe Wautelet: 05/2016-04/2018: new data structures and calls for I/O
+!!                  07/2017  (V. Vionnet) : Add blowing snow scheme 
+!!      S. Riette : 11/2016 Add ZPABST to keep pressure constant during timestep
+!!                   01/2018 (C.Lac) Add VISCOSITY
+!!  Philippe Wautelet: 21/01/2019: add LIO_ALLOW_NO_BACKUP and LIO_NO_WRITE to modd_io_ll
+!                                  to allow to disable writes (for bench purposes)
+!  P. Wautelet 07/02/2019: remove OPARALLELIO argument from open and close files subroutines
+!                          (nsubfiles_ioz is now determined in IO_File_add2list)
+!!                   02/2019 C.Lac add rain fraction as an output field
+!!      Bielli S. 02/2019  Sea salt : significant sea wave height influences salt emission; 5 salt modes
+!  P. Wautelet 28/03/2019: use MNHTIME for time measurement variables
+!  P. Wautelet 28/03/2019: use TFILE instead of unit number for set_iluout_timing
+!  P. Wautelet 19/04/2019: removed unused dummy arguments and variables
+!  P. Wautelet 26/04/2019: replace non-standard FLOAT function by REAL function
+!  P. Wautelet 20/05/2019: add name argument to ADDnFIELD_ll + new ADD4DFIELD_ll subroutine
+!  J. Escobar  09/07/2019: norme Doctor -> Rename Module Type variable TZ -> T
+!  J. Escobar  09/07/2019: for bug in management of XLSZWSM variable, add/use specific 2D TLSFIELD2D_ll pointer
+!  P. Wautelet 23/07/2019: OpenACC: move data creations from resolved_cloud to modeln and optimize updates
+!  J. Escobar  27/09/2019: add missing report timing of RESOLVED_ELEC
+!!-------------------------------------------------------------------------------
+!
+!*       0.     DECLARATIONS
+!               ------------
+!
+USE MODD_2D_FRC
+USE MODD_ADV_n
+USE MODD_AIRCRAFT_BALLOON
+USE MODD_BAKOUT
+USE MODD_BIKHARDT_n
+USE MODD_BLANK
+USE MODD_BUDGET
+USE MODD_CH_AERO_n,      ONLY: XSOLORG, XMI
+USE MODD_CH_MNHC_n,      ONLY: LUSECHEM,LCH_CONV_LINOX,LUSECHAQ,LUSECHIC, &
+                               LCH_INIT_FIELD
+USE MODD_CLOUD_MF_n
+USE MODD_VISCOSITY
+USE MODD_DRAG_n
+USE MODD_CLOUDPAR_n
+USE MODD_CONF
+USE MODD_CONF_n
+USE MODD_CURVCOR_n
+USE MODD_DEEP_CONVECTION_n
+USE MODD_DIM_n
+USE MODD_DUST,           ONLY: LDUST
+USE MODD_DYN
+USE MODD_DYN_n
+USE MODD_DYNZD
+USE MODD_DYNZD_n
+USE MODD_ELEC_DESCR
+USE MODD_FIELD_n
+USE MODD_FRC
+USE MODD_FRC_n
+USE MODD_GET_n
+USE MODD_GRID,           ONLY: XLONORI,XLATORI
+USE MODD_GRID_n
+USE MODD_ICE_C1R3_DESCR, ONLY: XRTMIN_C1R3=>XRTMIN
+USE MODD_IO,             ONLY: LIO_NO_WRITE, TFILEDATA, TFILE_SURFEX, TFILE_DUMMY
+USE MODD_LBC_n
+USE MODD_LES
+USE MODD_LES_BUDGET
+USE MODD_LIMA_PRECIP_SCAVENGING_n
+USE MODD_LSFIELD_n
+USE MODD_LUNIT,          ONLY: TLUOUT0,TOUTDATAFILE
+USE MODD_LUNIT_n,        ONLY: TDIAFILE,TINIFILE,TINIFILEPGD,TLUOUT
+USE MODD_MEAN_FIELD
+USE MODD_MEAN_FIELD_n
+USE MODD_METRICS_n
+USE MODD_MNH_SURFEX_n
+USE MODD_NESTING
+USE MODD_NSV
+USE MODD_NUDGING_n
+USE MODD_OUT_n
+USE MODD_PARAM_C1R3,     ONLY: NSEDI => LSEDI, NHHONI => LHHONI
+USE MODD_PARAM_C2R2,     ONLY: NSEDC => LSEDC, NRAIN => LRAIN, NACTIT => LACTIT,LACTTKE,LDEPOC
+USE MODD_PARAMETERS
+USE MODD_PARAM_ICE,      ONLY: LWARM,LSEDIC,LCONVHG,LDEPOSC
+USE MODD_PARAM_LIMA,     ONLY: MSEDC => LSEDC, MWARM => LWARM, MRAIN => LRAIN, &
+                               MACTIT => LACTIT, LSCAV, LCOLD,                 &
+                               MSEDI => LSEDI, MHHONI => LHHONI, LHAIL,        &
+                               XRTMIN_LIMA=>XRTMIN, MACTTKE=>LACTTKE
+USE MODD_BLOWSNOW_n
+USE MODD_BLOWSNOW
+USE MODD_PARAM_MFSHALL_n
+USE MODD_PARAM_n
+USE MODD_PAST_FIELD_n
+USE MODD_PRECIP_n
+use modd_precision,      only: MNHTIME
+USE MODD_PROFILER_n
+USE MODD_RADIATIONS_n,   ONLY: XTSRAD,XSCAFLASWD,XDIRFLASWD,XDIRSRFSWD, XAER, XDTHRAD
+USE MODD_RAIN_ICE_DESCR, ONLY: XRTMIN
+USE MODD_REF_n
+USE MODD_SALT,           ONLY: LSALT
+USE MODD_SERIES,         ONLY: LSERIES
+USE MODD_SERIES_n,       ONLY: NFREQSERIES
+USE MODD_STATION_n
+USE MODD_SUB_MODEL_n
+USE MODD_TIME
+USE MODD_TIME_n
+USE MODD_TIMEZ
+USE MODD_TURB_CLOUD,     ONLY: NMODEL_CLOUD,CTURBLEN_CLOUD,XCEI
+USE MODD_TURB_n
+!
+USE MODE_DATETIME
+USE MODE_ELEC_ll
+USE MODE_GRIDCART
+USE MODE_GRIDPROJ
+USE MODE_IO_FIELD_WRITE,   only: IO_Field_user_write, IO_Fieldlist_write, IO_Header_write
+USE MODE_IO_FILE,          only: IO_File_close, IO_File_open
+USE MODE_IO_MANAGE_STRUCT, only: IO_File_add2list
+USE MODE_ll
+USE MODE_MNH_TIMING
+USE MODE_MODELN_HANDLER
+USE MODE_MPPDB
+USE MODE_ONE_WAY_n
+!
+USE MODI_ADVECTION_METSV
+USE MODI_ADVECTION_UVW
+USE MODI_ADVECTION_UVW_CEN
+USE MODI_ADV_FORCING_n
+USE MODI_AER_MONITOR_n
+USE MODI_AIRCRAFT_BALLOON
+USE MODI_BLOWSNOW
+USE MODI_BOUNDARIES
+USE MODI_BUDGET_FLAGS
+USE MODI_CART_COMPRESS
+USE MODI_CH_MONITOR_n
+USE MODI_DIAG_SURF_ATM_N
+USE MODI_DYN_SOURCES
+USE MODI_END_DIAG_IN_RUN
+USE MODI_ENDSTEP
+USE MODI_ENDSTEP_BUDGET
+USE MODI_EXCHANGE
+USE MODI_FORCING
+USE MODI_FORC_SQUALL_LINE
+USE MODI_FORC_WIND
+USE MODI_GET_HALO
+USE MODI_GRAVITY_IMPL
+USE MODI_INI_DIAG_IN_RUN
+USE MODI_INI_LG
+USE MODI_INI_MEAN_FIELD
+USE MODI_INITIAL_GUESS
+USE MODI_LES_INI_TIMESTEP_n
+USE MODI_LES_N
+USE MODI_VISCOSITY
+USE MODI_LIMA_PRECIP_SCAVENGING
+USE MODI_LS_COUPLING
+USE MODI_MASK_COMPRESS
+USE MODI_MEAN_FIELD
+USE MODI_MENU_DIACHRO
+USE MODI_MNHGET_SURF_PARAM_n
+USE MODI_MNHWRITE_ZS_DUMMY_n
+USE MODI_NUDGING
+USE MODI_NUM_DIFF
+USE MODI_PHYS_PARAM_n
+USE MODI_PRESSUREZ
+USE MODI_PROFILER_n
+USE MODI_RAD_BOUND
+USE MODI_RELAX2FW_ION 
+USE MODI_RELAXATION
+USE MODI_REL_FORCING_n
+USE MODI_RESOLVED_CLOUD
+USE MODI_RESOLVED_ELEC_n
+USE MODI_SERIES_N
+USE MODI_SETLB_LG
+USE MODI_SET_MASK
+USE MODI_SHUMAN
+USE MODI_SPAWN_LS_n
+USE MODI_STATION_n
+USE MODI_TURB_CLOUD_INDEX
+USE MODI_TWO_WAY
+USE MODI_UPDATE_NSV
+USE MODI_WRITE_AIRCRAFT_BALLOON
+USE MODI_WRITE_DESFM_n
+USE MODI_WRITE_DIAG_SURF_ATM_N
+USE MODI_WRITE_LES_n
+USE MODI_WRITE_LFIFM_n
+USE MODI_WRITE_LFIFMN_FORDIACHRO_n
+USE MODI_WRITE_PROFILER_n
+USE MODI_WRITE_SERIES_n
+USE MODI_WRITE_STATION_n
+USE MODI_WRITE_SURF_ATM_N
+!
+IMPLICIT NONE
+!
+!*       0.1   declarations of arguments
+!
+!
+!
+INTEGER, INTENT(IN)   :: KTCOUNT
+LOGICAL, INTENT(INOUT):: OEXIT
+!
+!*       0.2   declarations of local variables
+!
+INTEGER :: ILUOUT      ! Logical unit number for the output listing
+INTEGER :: IIU,IJU,IKU ! array size in first, second and third dimensions
+INTEGER :: IIB,IIE,IJB,IJE ! index values for the physical subdomain
+INTEGER :: JSV,JRR     ! Loop index for scalar and moist variables
+INTEGER  :: INBVAR              ! number of HALO2_lls to allocate
+INTEGER  :: IINFO_ll            ! return code of parallel routine
+INTEGER :: IVERB                ! LFI verbosity level
+LOGICAL :: GSTEADY_DMASS        ! conditional call to mass computation
+!
+                                ! for computing time analysis
+REAL(kind=MNHTIME), DIMENSION(2) :: ZTIME, ZTIME1, ZTIME2, ZEND, ZTOT, ZALL, ZTOT_PT
+REAL(kind=MNHTIME), DIMENSION(2) :: ZTIME_STEP,ZTIME_STEP_PTS
+CHARACTER                 :: YMI
+INTEGER                   :: IPOINTS
+CHARACTER(len=16)         :: YTCOUNT,YPOINTS
+!
+INTEGER :: ISYNCHRO          ! model synchronic index relative to its father
+                             ! = 1  for the first time step in phase with DAD
+                             ! = 0  for the last  time step (out of phase)
+INTEGER      :: IMI ! Current model index
+REAL, DIMENSION(:,:),ALLOCATABLE          :: ZSEA
+REAL, DIMENSION(:,:),ALLOCATABLE          :: ZTOWN
+! Dummy pointers needed to correct an ifort Bug
+REAL, DIMENSION(:), POINTER :: DPTR_XZHAT
+REAL, DIMENSION(:), POINTER :: DPTR_XBMX1,DPTR_XBMX2,DPTR_XBMX3,DPTR_XBMX4
+REAL, DIMENSION(:), POINTER :: DPTR_XBMY1,DPTR_XBMY2,DPTR_XBMY3,DPTR_XBMY4
+REAL, DIMENSION(:), POINTER :: DPTR_XBFX1,DPTR_XBFX2,DPTR_XBFX3,DPTR_XBFX4
+REAL, DIMENSION(:), POINTER :: DPTR_XBFY1,DPTR_XBFY2,DPTR_XBFY3,DPTR_XBFY4
+CHARACTER(LEN=4), DIMENSION(:), POINTER :: DPTR_CLBCX,DPTR_CLBCY
+INTEGER, DIMENSION(:,:,:), POINTER :: DPTR_NKLIN_LBXU,DPTR_NKLIN_LBYU,DPTR_NKLIN_LBXV,DPTR_NKLIN_LBYV
+INTEGER, DIMENSION(:,:,:), POINTER :: DPTR_NKLIN_LBXW,DPTR_NKLIN_LBYW,DPTR_NKLIN_LBXM,DPTR_NKLIN_LBYM
+REAL, DIMENSION(:,:,:), POINTER :: DPTR_XCOEFLIN_LBXU,DPTR_XCOEFLIN_LBYU
+REAL, DIMENSION(:,:,:), POINTER :: DPTR_XCOEFLIN_LBXV,DPTR_XCOEFLIN_LBYV
+REAL, DIMENSION(:,:,:), POINTER :: DPTR_XCOEFLIN_LBXW,DPTR_XCOEFLIN_LBYW
+REAL, DIMENSION(:,:,:), POINTER :: DPTR_XCOEFLIN_LBXM,DPTR_XCOEFLIN_LBYM
+REAL, DIMENSION(:,:,:),   POINTER :: DPTR_XLBXUM,DPTR_XLBYUM,DPTR_XLBXVM,DPTR_XLBYVM
+REAL, DIMENSION(:,:,:),   POINTER :: DPTR_XLBXWM,DPTR_XLBYWM,DPTR_XLBXTHM,DPTR_XLBYTHM
+REAL, DIMENSION(:,:,:),   POINTER :: DPTR_XLBXTKEM,DPTR_XLBYTKEM
+REAL, DIMENSION(:,:,:,:),   POINTER :: DPTR_XLBXSVM,DPTR_XLBYSVM                
+REAL, DIMENSION(:,:,:,:), POINTER :: DPTR_XLBXRM,DPTR_XLBYRM
+REAL, DIMENSION(:,:,:),   POINTER ::  DPTR_XZZ
+REAL, DIMENSION(:,:,:), POINTER :: DPTR_XLSUM,DPTR_XLSVM,DPTR_XLSWM,DPTR_XLSTHM,DPTR_XLSRVM
+REAL, DIMENSION(:,:,:), POINTER :: DPTR_XLSUS,DPTR_XLSVS,DPTR_XLSWS,DPTR_XLSTHS,DPTR_XLSRVS
+REAL, DIMENSION(:,:),   POINTER :: DPTR_XLSZWSM,DPTR_XLSZWSS
+REAL, DIMENSION(:,:,:), POINTER :: DPTR_XLBXUS,DPTR_XLBYUS,DPTR_XLBXVS,DPTR_XLBYVS
+REAL, DIMENSION(:,:,:), POINTER :: DPTR_XLBXWS,DPTR_XLBYWS,DPTR_XLBXTHS,DPTR_XLBYTHS
+REAL, DIMENSION(:,:,:), POINTER :: DPTR_XLBXTKES,DPTR_XLBYTKES
+REAL, DIMENSION(:,:,:,:), POINTER :: DPTR_XLBXRS,DPTR_XLBYRS,DPTR_XLBXSVS,DPTR_XLBYSVS
+!
+REAL, DIMENSION(:,:,:), POINTER :: DPTR_XRHODJ,DPTR_XUM,DPTR_XVM,DPTR_XWM,DPTR_XTHM
+REAL, DIMENSION(:,:,:), POINTER :: DPTR_XTKEM,DPTR_XRUS,DPTR_XRVS,DPTR_XRWS,DPTR_XRTHS
+REAL, DIMENSION(:,:,:), POINTER :: DPTR_XRTKES,DPTR_XDIRFLASWD,DPTR_XSCAFLASWD,DPTR_XDIRSRFSWD
+REAL, DIMENSION(:,:,:,:), POINTER :: DPTR_XRM,DPTR_XSVM,DPTR_XRRS,DPTR_XRSVS
+REAL, DIMENSION(:,:), POINTER :: DPTR_XINPRC,DPTR_XINPRR,DPTR_XINPRS,DPTR_XINPRG
+REAL, DIMENSION(:,:), POINTER :: DPTR_XINPRH,DPTR_XPRCONV,DPTR_XPRSCONV
+LOGICAL, DIMENSION(:,:),POINTER :: DPTR_GMASKkids
+!
+! REAL, DIMENSION(SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3))           :: ZSPEEDC
+! REAL, DIMENSION(SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3))           :: ZSPEEDR
+! REAL, DIMENSION(SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3))           :: ZSPEEDS
+! REAL, DIMENSION(SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3))           :: ZSPEEDG
+! REAL, DIMENSION(SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3))           :: ZSPEEDH
+! REAL, DIMENSION(SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3))           :: ZINPRC3D
+! REAL, DIMENSION(SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3))           :: ZINPRS3D
+! REAL, DIMENSION(SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3))           :: ZINPRG3D
+! REAL, DIMENSION(SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3))           :: ZINPRH3D
+!
+LOGICAL :: KWARM
+LOGICAL :: KRAIN
+LOGICAL :: KSEDC
+LOGICAL :: KACTIT
+LOGICAL :: KSEDI
+LOGICAL :: KHHONI
+!
+REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZRUS,ZRVS,ZRWS
+REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZPABST !To give pressure at t
+                                                     ! (and not t+1) to resolved_cloud
+REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZJ
+!
+TYPE(LIST_ll), POINTER :: TZFIELDC_ll   ! list of fields to exchange
+TYPE(HALO2LIST_ll), POINTER :: TZHALO2C_ll   ! list of fields to exchange
+LOGICAL :: GCLD                     ! conditionnal call for dust wet deposition
+LOGICAL :: GCLOUD_ONLY              ! conditionnal radiation computations for
+                                !      the only cloudy columns
+REAL, DIMENSION(:,:,:,:), ALLOCATABLE :: ZWETDEPAER
+
+
+!
+TYPE(TFILEDATA),POINTER :: TZBAKFILE, TZOUTFILE
+! TYPE(TFILEDATA),SAVE    :: TZDIACFILE
+!-------------------------------------------------------------------------------
+!
+TZBAKFILE=> NULL()
+TZOUTFILE=> NULL()
+
+allocate( ZRUS  (SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3)) )
+allocate( ZRVS  (SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3)) )
+allocate( ZRWS  (SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3)) )
+allocate( ZPABST(SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3)) )
+allocate( ZJ    (SIZE(XTHT,1),SIZE(XTHT,2),SIZE(XTHT,3)) )
+allocate( ZWETDEPAER(SIZE(XRSVS,1), SIZE(XRSVS,2), SIZE(XRSVS,3), NSV_AER) )
+
+!$acc data create( zrws )
+
+!
+!*       0.    MICROPHYSICAL SCHEME
+!              ------------------- 
+SELECT CASE(CCLOUD)
+CASE('C2R2','KHKO','C3R5')
+  KWARM  = .TRUE.        
+  KRAIN  = NRAIN
+  KSEDC  = NSEDC
+  KACTIT = NACTIT
+!
+  KSEDI  = NSEDI
+  KHHONI = NHHONI
+CASE('LIMA')
+  KWARM  = MWARM        
+  KRAIN  = MRAIN
+  KSEDC  = MSEDC
+  KACTIT = MACTIT
+!
+  KSEDI  = MSEDI
+  KHHONI = MHHONI
+CASE('ICE3','ICE4') !default values
+  KWARM  = LWARM        
+  KRAIN  = .TRUE.
+  KSEDC  = .TRUE.
+  KACTIT = .FALSE.
+!
+  KSEDI  = .TRUE.
+  KHHONI = .FALSE.
+END SELECT
+!
+!
+!*        1    PRELIMINARY
+!              ------------
+IMI = GET_CURRENT_MODEL_INDEX()
+!
+!*       1.0   update NSV_* variables for current model
+!              ----------------------------------------
+!
+CALL UPDATE_NSV(IMI)
+!
+!*       1.1   RECOVER THE LOGICAL UNIT NUMBER FOR THE OUTPUT PRINTS
+!
+ILUOUT = TLUOUT%NLU
+!
+!*       1.2   SET ARRAY SIZE
+!
+CALL GET_DIM_EXT_ll('B',IIU,IJU)
+IKU=NKMAX+2*JPVEXT
+CALL GET_INDICE_ll (IIB,IJB,IIE,IJE)
+!
+IF (IMI==1) THEN
+  GSTEADY_DMASS=LSTEADYLS
+ELSE
+  GSTEADY_DMASS=.FALSE.
+END IF
+!
+!*       1.3   OPEN THE DIACHRONIC FILE
+!
+IF (KTCOUNT == 1) THEN
+!
+  NULLIFY(TFIELDS_ll,TLSFIELD_ll,TFIELDT_ll)
+  NULLIFY(TLSFIELD2D_ll)
+  NULLIFY(THALO2T_ll)
+  NULLIFY(TLSHALO2_ll)
+  NULLIFY(TFIELDSC_ll)
+!
+  ALLOCATE(XWT_ACT_NUC(SIZE(XWT,1),SIZE(XWT,2),SIZE(XWT,3)))
+  ALLOCATE(GMASKkids(SIZE(XWT,1),SIZE(XWT,2)))
+!
+! initialization of the FM file backup/output number
+  IBAK=0
+  IOUT=0
+!
+  IF ( .NOT. LIO_NO_WRITE ) THEN
+    CALL IO_File_open(TDIAFILE)
+!
+    CALL IO_Header_write(TDIAFILE)
+    CALL WRITE_DESFM_n(IMI,TDIAFILE)
+    CALL WRITE_LFIFMN_FORDIACHRO_n(TDIAFILE)
+  END IF
+!
+!*       1.4   Initialization of the list of fields for the halo updates
+!
+!                 a) Sources terms
+!
+  CALL ADD3DFIELD_ll( TFIELDS_ll, XRUS,      'MODEL_n::XRUS' )
+  CALL ADD3DFIELD_ll( TFIELDS_ll, XRVS,      'MODEL_n::XRVS' )
+  CALL ADD3DFIELD_ll( TFIELDS_ll, XRWS,      'MODEL_n::XRWS' )
+  CALL ADD3DFIELD_ll( TFIELDS_ll, XRTHS,     'MODEL_n::XRTHS' )
+  CALL ADD3DFIELD_ll( TFIELDS_ll, XRUS_PRES, 'MODEL_n::XRUS_PRES' )
+  CALL ADD3DFIELD_ll( TFIELDS_ll, XRVS_PRES, 'MODEL_n::XRVS_PRES' )
+  CALL ADD3DFIELD_ll( TFIELDS_ll, XRWS_PRES, 'MODEL_n::XRWS_PRES' )
+  CALL ADD3DFIELD_ll( TFIELDS_ll, XRTHS_CLD, 'MODEL_n::XRTHS_CLD' )
+  IF (SIZE(XRTKES,1) /= 0) CALL ADD3DFIELD_ll( TFIELDS_ll, XRTKES, 'MODEL_n::XRTKES' )
+  CALL ADD4DFIELD_ll( TFIELDS_ll, XRRS     (:,:,:,1:NRR), 'MODEL_n::XRRS' )
+  CALL ADD4DFIELD_ll( TFIELDS_ll, XRRS_CLD (:,:,:,1:NRR), 'MODEL_n::XRRS_CLD' )
+  CALL ADD4DFIELD_ll( TFIELDS_ll, XRSVS    (:,:,:,1:NSV), 'MODEL_n::XRSVS')
+  CALL ADD4DFIELD_ll( TFIELDS_ll, XRSVS_CLD(:,:,:,1:NSV), 'MODEL_n::XRSVS_CLD')
+  IF (SIZE(XSRCT,1) /= 0) CALL ADD3DFIELD_ll( TFIELDS_ll, XSRCT, 'MODEL_n::XSRCT' )
+  !
+  IF ((LNUMDIFU .OR. LNUMDIFTH .OR. LNUMDIFSV) ) THEN
+  !
+  !                 b) LS fields
+  !
+    CALL ADD3DFIELD_ll( TLSFIELD_ll,   XLSUM,   'MODEL_n::XLSUM'   )
+    CALL ADD3DFIELD_ll( TLSFIELD_ll,   XLSVM,   'MODEL_n::XLSVM'   )
+    CALL ADD3DFIELD_ll( TLSFIELD_ll,   XLSWM,   'MODEL_n::XLSWM'   )
+    CALL ADD3DFIELD_ll( TLSFIELD_ll,   XLSTHM,  'MODEL_n::XLSTHM'  )
+    CALL ADD2DFIELD_ll( TLSFIELD2D_ll, XLSZWSM, 'MODEL_n::XLSZWSM' )
+    IF (NRR >= 1) THEN
+      CALL ADD3DFIELD_ll( TLSFIELD_ll, XLSRVM, 'MODEL_n::XLSRVM' )
+    ENDIF
+  !
+  !                 c) Fields at t
+  !
+    CALL ADD3DFIELD_ll( TFIELDT_ll, XUT,  'MODEL_n::XUT'  )
+    CALL ADD3DFIELD_ll( TFIELDT_ll, XVT,  'MODEL_n::XVT'  )
+    CALL ADD3DFIELD_ll( TFIELDT_ll, XWT,  'MODEL_n::XWT'  )
+    CALL ADD3DFIELD_ll( TFIELDT_ll, XTHT, 'MODEL_n::XTHT' )
+    IF (SIZE(XRTKES,1) /= 0) CALL ADD3DFIELD_ll( TFIELDT_ll, XTKET, 'MODEL_n::XTKET' )
+    CALL ADD4DFIELD_ll(TFIELDT_ll, XRT (:,:,:,1:NRR), 'MODEL_n::XSV'  )
+    CALL ADD4DFIELD_ll(TFIELDT_ll, XSVT(:,:,:,1:NSV), 'MODEL_n::XSVT' )
+  !
+  !*       1.5   Initialize the list of fields for the halo updates (2nd layer)
+  !
+    INBVAR = 4+NRR+NSV
+    IF (SIZE(XRTKES,1) /= 0) INBVAR=INBVAR+1
+    CALL INIT_HALO2_ll(THALO2T_ll,INBVAR,IIU,IJU,IKU)
+    CALL INIT_HALO2_ll(TLSHALO2_ll,4+MIN(1,NRR),IIU,IJU,IKU)
+  !
+  !*       1.6   Initialise the 2nd layer of the halo of the LS fields
+  !
+    IF ( LSTEADYLS ) THEN
+       CALL UPDATE_HALO_ll(TLSFIELD_ll, IINFO_ll)
+       CALL UPDATE_HALO_ll(TLSFIELD2D_ll,IINFO_ll) 
+       CALL UPDATE_HALO2_ll(TLSFIELD_ll, TLSHALO2_ll, IINFO_ll)
+    END IF
+  END IF
+  !
+!
+  !
+  XT_START     = 0.0_MNHTIME
+  !
+  XT_STORE     = 0.0_MNHTIME
+  XT_BOUND     = 0.0_MNHTIME
+  XT_GUESS     = 0.0_MNHTIME
+  XT_FORCING   = 0.0_MNHTIME
+  XT_NUDGING   = 0.0_MNHTIME
+  XT_ADV       = 0.0_MNHTIME
+  XT_ADVUVW    = 0.0_MNHTIME
+  XT_GRAV      = 0.0_MNHTIME
+  XT_SOURCES   = 0.0_MNHTIME
+  !
+  XT_DIFF      = 0.0_MNHTIME
+  XT_RELAX     = 0.0_MNHTIME
+  XT_PARAM     = 0.0_MNHTIME
+  XT_SPECTRA   = 0.0_MNHTIME
+  XT_HALO      = 0.0_MNHTIME
+  XT_VISC      = 0.0_MNHTIME
+  XT_RAD_BOUND = 0.0_MNHTIME
+  XT_PRESS     = 0.0_MNHTIME
+  !
+  XT_CLOUD     = 0.0_MNHTIME
+  XT_STEP_SWA  = 0.0_MNHTIME
+  XT_STEP_MISC = 0.0_MNHTIME
+  XT_COUPL     = 0.0_MNHTIME
+  XT_1WAY      = 0.0_MNHTIME
+  XT_STEP_BUD  = 0.0_MNHTIME
+  !
+  XT_RAD       = 0.0_MNHTIME
+  XT_DCONV     = 0.0_MNHTIME
+  XT_GROUND    = 0.0_MNHTIME
+  XT_TURB      = 0.0_MNHTIME
+  XT_MAFL      = 0.0_MNHTIME
+  XT_DRAG      = 0.0_MNHTIME
+  XT_TRACER    = 0.0_MNHTIME
+  XT_SHADOWS   = 0.0_MNHTIME
+  XT_ELEC      = 0.0_MNHTIME
+  XT_CHEM      = 0.0_MNHTIME
+  XT_2WAY      = 0.0_MNHTIME
+  !
+END IF
+!
+!*       1.7   Allocation of arrays for observation diagnostics
+!
+CALL INI_DIAG_IN_RUN(IIU,IJU,IKU,LFLYER,LSTATION,LPROFILER)
+!
+!
+CALL SECOND_MNH2(ZEND)
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.    ONE-WAY NESTING AND LARGE SCALE FIELD REFRESH
+!              ---------------------------------------------
+!
+!
+CALL SECOND_MNH2(ZTIME1)
+!
+ISYNCHRO = MODULO (KTCOUNT, NDTRATIO(IMI) )      ! test of synchronisation
+!
+
+
+IF (IMI/=1 .AND. NDAD(IMI)/=IMI .AND. (ISYNCHRO==1 .OR. NDTRATIO(IMI) == 1) ) THEN     
+!                                                                        
+  ! Use dummy pointers to correct an ifort BUG
+  DPTR_XBMX1=>XBMX1
+  DPTR_XBMX2=>XBMX2
+  DPTR_XBMX3=>XBMX3
+  DPTR_XBMX4=>XBMX4
+  DPTR_XBMY1=>XBMY1
+  DPTR_XBMY2=>XBMY2
+  DPTR_XBMY3=>XBMY3
+  DPTR_XBMY4=>XBMY4
+  DPTR_XBFX1=>XBFX1
+  DPTR_XBFX2=>XBFX2
+  DPTR_XBFX3=>XBFX3
+  DPTR_XBFX4=>XBFX4
+  DPTR_XBFY1=>XBFY1
+  DPTR_XBFY2=>XBFY2
+  DPTR_XBFY3=>XBFY3
+  DPTR_XBFY4=>XBFY4
+  DPTR_CLBCX=>CLBCX
+  DPTR_CLBCY=>CLBCY
+  !
+  DPTR_XZZ=>XZZ
+  DPTR_XZHAT=>XZHAT
+  DPTR_XCOEFLIN_LBXM=>XCOEFLIN_LBXM
+  DPTR_XLSTHM=>XLSTHM
+  DPTR_XLSRVM=>XLSRVM
+  DPTR_XLSUM=>XLSUM
+  DPTR_XLSVM=>XLSVM
+  DPTR_XLSWM=>XLSWM
+  DPTR_XLSZWSM=>XLSZWSM
+  DPTR_XLSTHS=>XLSTHS
+  DPTR_XLSRVS=>XLSRVS
+  DPTR_XLSUS=>XLSUS
+  DPTR_XLSVS=>XLSVS
+  DPTR_XLSWS=>XLSWS
+  DPTR_XLSZWSS=>XLSZWSS
+  !
+  IF ( LSTEADYLS                     ) THEN
+    NCPL_CUR=0
+  ELSE
+    IF (NCPL_CUR/=1) THEN
+      IF ( KTCOUNT+1 == NCPL_TIMES(NCPL_CUR-1,IMI)  ) THEN
+        !
+        !  LS sources are interpolated from the LS field 
+        ! values of model DAD(IMI)
+        CALL SPAWN_LS_n(NDAD(IMI),XTSTEP,IMI,                        &
+             DPTR_XBMX1,DPTR_XBMX2,DPTR_XBMX3,DPTR_XBMX4,DPTR_XBMY1,DPTR_XBMY2,DPTR_XBMY3,DPTR_XBMY4,        &
+             DPTR_XBFX1,DPTR_XBFX2,DPTR_XBFX3,DPTR_XBFX4,DPTR_XBFY1,DPTR_XBFY2,DPTR_XBFY3,DPTR_XBFY4,        &
+             NDXRATIO_ALL(IMI),NDYRATIO_ALL(IMI),                    &
+             DPTR_CLBCX,DPTR_CLBCY,DPTR_XZZ,DPTR_XZHAT,LSLEVE,XLEN1,XLEN2,DPTR_XCOEFLIN_LBXM, &
+             DPTR_XLSTHM,DPTR_XLSRVM,DPTR_XLSUM,DPTR_XLSVM,DPTR_XLSWM,DPTR_XLSZWSM,                        &
+             DPTR_XLSTHS,DPTR_XLSRVS,DPTR_XLSUS,DPTR_XLSVS,DPTR_XLSWS, DPTR_XLSZWSS                         )
+      END IF
+    END IF
+    !
+  END IF
+  !
+  DPTR_NKLIN_LBXU=>NKLIN_LBXU
+  DPTR_XCOEFLIN_LBXU=>XCOEFLIN_LBXU
+  DPTR_NKLIN_LBYU=>NKLIN_LBYU
+  DPTR_XCOEFLIN_LBYU=>XCOEFLIN_LBYU
+  DPTR_NKLIN_LBXV=>NKLIN_LBXV
+  DPTR_XCOEFLIN_LBXV=>XCOEFLIN_LBXV
+  DPTR_NKLIN_LBYV=>NKLIN_LBYV
+  DPTR_XCOEFLIN_LBYV=>XCOEFLIN_LBYV
+  DPTR_NKLIN_LBXW=>NKLIN_LBXW
+  DPTR_XCOEFLIN_LBXW=>XCOEFLIN_LBXW
+  DPTR_NKLIN_LBYW=>NKLIN_LBYW
+  DPTR_XCOEFLIN_LBYW=>XCOEFLIN_LBYW
+  !
+  DPTR_NKLIN_LBXM=>NKLIN_LBXM
+  DPTR_XCOEFLIN_LBXM=>XCOEFLIN_LBXM
+  DPTR_NKLIN_LBYM=>NKLIN_LBYM
+  DPTR_XCOEFLIN_LBYM=>XCOEFLIN_LBYM
+  !
+  DPTR_XLBXUM=>XLBXUM
+  DPTR_XLBYUM=>XLBYUM
+  DPTR_XLBXVM=>XLBXVM
+  DPTR_XLBYVM=>XLBYVM
+  DPTR_XLBXWM=>XLBXWM
+  DPTR_XLBYWM=>XLBYWM
+  DPTR_XLBXTHM=>XLBXTHM
+  DPTR_XLBYTHM=>XLBYTHM
+  DPTR_XLBXTKEM=>XLBXTKEM
+  DPTR_XLBYTKEM=>XLBYTKEM
+  DPTR_XLBXRM=>XLBXRM
+  DPTR_XLBYRM=>XLBYRM
+  DPTR_XLBXSVM=>XLBXSVM
+  DPTR_XLBYSVM=>XLBYSVM
+  !  
+  DPTR_XLBXUS=>XLBXUS
+  DPTR_XLBYUS=>XLBYUS
+  DPTR_XLBXVS=>XLBXVS
+  DPTR_XLBYVS=>XLBYVS
+  DPTR_XLBXWS=>XLBXWS
+  DPTR_XLBYWS=>XLBYWS
+  DPTR_XLBXTHS=>XLBXTHS
+  DPTR_XLBYTHS=>XLBYTHS
+  DPTR_XLBXTKES=>XLBXTKES
+  DPTR_XLBYTKES=>XLBYTKES
+  DPTR_XLBXRS=>XLBXRS
+  DPTR_XLBYRS=>XLBYRS
+  DPTR_XLBXSVS=>XLBXSVS
+  DPTR_XLBYSVS=>XLBYSVS
+  !
+  CALL ONE_WAY_n(NDAD(IMI),XTSTEP,IMI,KTCOUNT,                   &
+       DPTR_XBMX1,DPTR_XBMX2,DPTR_XBMX3,DPTR_XBMX4,DPTR_XBMY1,DPTR_XBMY2,DPTR_XBMY3,DPTR_XBMY4,        &
+       DPTR_XBFX1,DPTR_XBFX2,DPTR_XBFX3,DPTR_XBFX4,DPTR_XBFY1,DPTR_XBFY2,DPTR_XBFY3,DPTR_XBFY4,        &
+       NDXRATIO_ALL(IMI),NDYRATIO_ALL(IMI),NDTRATIO(IMI),         &
+       DPTR_CLBCX,DPTR_CLBCY,NRIMX,NRIMY,                                &
+       DPTR_NKLIN_LBXU,DPTR_XCOEFLIN_LBXU,DPTR_NKLIN_LBYU,DPTR_XCOEFLIN_LBYU,      &
+       DPTR_NKLIN_LBXV,DPTR_XCOEFLIN_LBXV,DPTR_NKLIN_LBYV,DPTR_XCOEFLIN_LBYV,      &
+       DPTR_NKLIN_LBXW,DPTR_XCOEFLIN_LBXW,DPTR_NKLIN_LBYW,DPTR_XCOEFLIN_LBYW,      &
+       DPTR_NKLIN_LBXM,DPTR_XCOEFLIN_LBXM,DPTR_NKLIN_LBYM,DPTR_XCOEFLIN_LBYM,      &
+       GSTEADY_DMASS,CCLOUD,LUSECHAQ,LUSECHIC,                           &
+       DPTR_XLBXUM,DPTR_XLBYUM,DPTR_XLBXVM,DPTR_XLBYVM,DPTR_XLBXWM,DPTR_XLBYWM,              &
+       DPTR_XLBXTHM,DPTR_XLBYTHM,                                        &
+       DPTR_XLBXTKEM,DPTR_XLBYTKEM,                                      &
+       DPTR_XLBXRM,DPTR_XLBYRM,DPTR_XLBXSVM,DPTR_XLBYSVM,                          &
+       XDRYMASST,XDRYMASSS,                                    &
+       DPTR_XLBXUS,DPTR_XLBYUS,DPTR_XLBXVS,DPTR_XLBYVS,DPTR_XLBXWS,DPTR_XLBYWS,              &
+       DPTR_XLBXTHS,DPTR_XLBYTHS,                                        &
+       DPTR_XLBXTKES,DPTR_XLBYTKES,                                      &
+       DPTR_XLBXRS,DPTR_XLBYRS,DPTR_XLBXSVS,DPTR_XLBYSVS                           )
+  !
+END IF
+!
+CALL SECOND_MNH2(ZTIME2)                                                  
+XT_1WAY = XT_1WAY + ZTIME2 - ZTIME1                                
+!
+!-------------------------------------------------------------------------------
+!
+!*       3.    LATERAL BOUNDARY CONDITIONS EXCEPT FOR NORMAL VELOCITY
+!              ------------------------------------------------------
+!
+ZTIME1=ZTIME2
+!
+!*       3.1   Set the lagragian variables values at the LB
+!
+IF( LLG .AND. IMI==1 ) CALL SETLB_LG
+!
+IF (CCONF == "START" .OR. (CCONF == "RESTA" .AND. KTCOUNT /= 1 )) THEN
+CALL BOUNDARIES (                                                   &
+            XTSTEP,CLBCX,CLBCY,NRR,NSV,KTCOUNT,                     &
+            XLBXUM,XLBXVM,XLBXWM,XLBXTHM,XLBXTKEM,XLBXRM,XLBXSVM,   &
+            XLBYUM,XLBYVM,XLBYWM,XLBYTHM,XLBYTKEM,XLBYRM,XLBYSVM,   &
+            XLBXUS,XLBXVS,XLBXWS,XLBXTHS,XLBXTKES,XLBXRS,XLBXSVS,   &
+            XLBYUS,XLBYVS,XLBYWS,XLBYTHS,XLBYTKES,XLBYRS,XLBYSVS,   &
+            XRHODJ,                                                 &
+            XUT, XVT, XWT, XTHT, XTKET, XRT, XSVT, XSRCT            )
+END IF
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_BOUND = XT_BOUND + ZTIME2 - ZTIME1
+!
+!-------------------------------------------------------------------------------
+!* initializes surface number
+IF (CSURF=='EXTE') CALL GOTO_SURFEX(IMI)
+!-------------------------------------------------------------------------------
+!
+!*       4.    STORAGE IN A SYNCHRONOUS FILE
+!              -----------------------------
+!
+ZTIME1 = ZTIME2
+!
+IF (IBAK < NBAK_NUMB ) THEN
+  IF (KTCOUNT == TBACKUPN(IBAK+1)%NSTEP) THEN
+    IBAK=IBAK+1
+    GCLOSE_OUT=.TRUE.
+    !
+    TZBAKFILE => TBACKUPN(IBAK)%TFILE
+    IVERB    = TZBAKFILE%NLFIVERB
+    !
+    CALL IO_File_open(TZBAKFILE)
+    !
+    CALL WRITE_DESFM_n(IMI,TZBAKFILE)
+    CALL IO_Header_write(TBACKUPN(IBAK)%TFILE)
+    CALL WRITE_LFIFM_n(TBACKUPN(IBAK)%TFILE,TBACKUPN(IBAK)%TFILE%TDADFILE%CNAME)
+    TOUTDATAFILE => TZBAKFILE
+    CALL MNHWRITE_ZS_DUMMY_n(TZBAKFILE)
+    IF (CSURF=='EXTE') THEN
+      TFILE_SURFEX => TZBAKFILE
+      CALL GOTO_SURFEX(IMI)
+      CALL WRITE_SURF_ATM_n(YSURF_CUR,'MESONH','ALL',.FALSE.)
+      NULLIFY(TFILE_SURFEX)
+    END IF
+    !
+    ! Reinitialize Lagragian variables at every model backup
+    IF (LLG .AND. LINIT_LG .AND. CINIT_LG=='FMOUT') THEN
+      CALL INI_LG(XXHAT,XYHAT,XZZ,XSVT,XLBXSVM,XLBYSVM)
+      IF (IVERB>=5) THEN
+        WRITE(UNIT=ILUOUT,FMT=*) '************************************'
+        WRITE(UNIT=ILUOUT,FMT=*) '*** Lagrangian variables refreshed after ',TRIM(TZBAKFILE%CNAME),' backup'
+        WRITE(UNIT=ILUOUT,FMT=*) '************************************'
+      END IF
+    END IF
+    ! Reinitialise mean variables
+    IF (LMEAN_FIELD) THEN
+       CALL INI_MEAN_FIELD
+    END IF
+!
+  ELSE
+    !Necessary to have a 'valid' CNAME when calling some subroutines
+    TZBAKFILE => TFILE_DUMMY
+  END IF
+ELSE
+  !Necessary to have a 'valid' CNAME when calling some subroutines
+  TZBAKFILE => TFILE_DUMMY
+END IF
+!
+IF (IOUT < NOUT_NUMB ) THEN
+  IF (KTCOUNT == TOUTPUTN(IOUT+1)%NSTEP) THEN
+    IOUT=IOUT+1
+    !
+    TZOUTFILE => TOUTPUTN(IOUT)%TFILE
+    !
+    CALL IO_File_open(TZOUTFILE)
+    !
+    CALL IO_Header_write(TZOUTFILE)
+    CALL IO_Fieldlist_write(TOUTPUTN(IOUT))
+    CALL IO_Field_user_write(TOUTPUTN(IOUT))
+    !
+    CALL IO_File_close(TZOUTFILE)
+    !
+  END IF
+END IF
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_STORE = XT_STORE + ZTIME2 - ZTIME1
+!
+!-------------------------------------------------------------------------------
+!
+!*       5.    INITIALIZATION OF THE BUDGET VARIABLES
+!              --------------------------------------
+!
+IF (NBUMOD==IMI) THEN
+  LBU_ENABLE = CBUTYPE /='NONE'.AND. CBUTYPE /='SKIP' 
+ELSE
+  LBU_ENABLE = .FALSE.
+END IF
+!
+IF (NBUMOD==IMI .AND. CBUTYPE=='MASK' ) THEN
+  CALL SET_MASK
+  IF (LBU_RU)   XBURHODJU(:,NBUTIME,:) = XBURHODJU(:,NBUTIME,:)    &
+                            + MASK_COMPRESS(MXM(XRHODJ))
+  IF (LBU_RV)   XBURHODJV(:,NBUTIME,:) = XBURHODJV(:,NBUTIME,:)    &
+                            + MASK_COMPRESS(MYM(XRHODJ))
+  IF (LBU_RW)   XBURHODJW(:,NBUTIME,:) = XBURHODJW(:,NBUTIME,:)    &
+                            + MASK_COMPRESS(MZM(XRHODJ))
+  IF (ALLOCATED(XBURHODJ))                                         &
+                XBURHODJ (:,NBUTIME,:) = XBURHODJ (:,NBUTIME,:)    &
+                              + MASK_COMPRESS(XRHODJ)
+END IF
+!
+IF (NBUMOD==IMI .AND. CBUTYPE=='CART' ) THEN
+  IF (LBU_RU)   XBURHODJU(:,:,:) = XBURHODJU(:,:,:)    &
+                + CART_COMPRESS(MXM(XRHODJ))
+  IF (LBU_RV)   XBURHODJV(:,:,:) = XBURHODJV(:,:,:)    &
+                + CART_COMPRESS(MYM(XRHODJ))
+  IF (LBU_RW)   XBURHODJW(:,:,:) = XBURHODJW(:,:,:)    &
+                + CART_COMPRESS(MZM(XRHODJ))
+  IF (ALLOCATED(XBURHODJ))                             &
+                XBURHODJ (:,:,:) = XBURHODJ (:,:,:)    &
+                + CART_COMPRESS(XRHODJ)
+END IF
+!
+CALL BUDGET_FLAGS(LUSERV, LUSERC, LUSERR,         &
+                  LUSERI, LUSERS, LUSERG, LUSERH  )
+!
+XTIME_BU   = 0.0
+!
+!-------------------------------------------------------------------------------
+!
+!*       6.    INITIALIZATION OF THE FIELD TENDENCIES
+!              --------------------------------------
+!
+ZTIME1 = ZTIME2
+XTIME_BU_PROCESS = 0.
+!
+CALL INITIAL_GUESS ( NRR, NSV, KTCOUNT, XRHODJ,IMI, XTSTEP,                 &
+                     XRUS, XRVS, XRWS, XRTHS, XRRS, XRTKES, XRSVS,          &
+                     XUT, XVT, XWT, XTHT, XRT, XTKET, XSVT )
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_GUESS = XT_GUESS + ZTIME2 - ZTIME1 - XTIME_BU_PROCESS
+!
+!-------------------------------------------------------------------------------
+!
+!*       7.    INITIALIZATION OF THE LES FOR CURRENT TIME-STEP
+!              -----------------------------------------------
+!
+XTIME_LES_BU   = 0.0
+XTIME_LES      = 0.0
+IF (LLES) CALL LES_INI_TIMESTEP_n(KTCOUNT)
+!
+!-------------------------------------------------------------------------------
+!
+!*       8.    TWO-WAY INTERACTIVE GRID-NESTING
+!              --------------------------------
+!
+!
+CALL SECOND_MNH2(ZTIME1)
+XTIME_BU_PROCESS = 0.
+XTIME_LES_BU_PROCESS = 0.
+!
+GMASKkids(:,:)=.FALSE.
+!
+IF (NMODEL>1) THEN
+  ! correct an ifort bug
+  DPTR_XRHODJ=>XRHODJ
+  DPTR_XUM=>XUT
+  DPTR_XVM=>XVT
+  DPTR_XWM=>XWT
+  DPTR_XTHM=>XTHT
+  DPTR_XRM=>XRT
+  DPTR_XTKEM=>XTKET
+  DPTR_XSVM=>XSVT
+  DPTR_XRUS=>XRUS
+  DPTR_XRVS=>XRVS
+  DPTR_XRWS=>XRWS
+  DPTR_XRTHS=>XRTHS
+  DPTR_XRRS=>XRRS
+  DPTR_XRTKES=>XRTKES
+  DPTR_XRSVS=>XRSVS
+  DPTR_XINPRC=>XINPRC
+  DPTR_XINPRR=>XINPRR
+  DPTR_XINPRS=>XINPRS
+  DPTR_XINPRG=>XINPRG
+  DPTR_XINPRH=>XINPRH
+  DPTR_XPRCONV=>XPRCONV
+  DPTR_XPRSCONV=>XPRSCONV
+  DPTR_XDIRFLASWD=>XDIRFLASWD
+  DPTR_XSCAFLASWD=>XSCAFLASWD
+  DPTR_XDIRSRFSWD=>XDIRSRFSWD
+  DPTR_GMASKkids=>GMASKkids
+  !
+  CALL TWO_WAY(     NRR,NSV,KTCOUNT,DPTR_XRHODJ,IMI,XTSTEP,                                    &
+       DPTR_XUM ,DPTR_XVM ,DPTR_XWM , DPTR_XTHM, DPTR_XRM,DPTR_XSVM,                           &
+       DPTR_XRUS,DPTR_XRVS,DPTR_XRWS,DPTR_XRTHS,DPTR_XRRS,DPTR_XRSVS,                          &
+       DPTR_XINPRC,DPTR_XINPRR,DPTR_XINPRS,DPTR_XINPRG,DPTR_XINPRH,DPTR_XPRCONV,DPTR_XPRSCONV, &
+       DPTR_XDIRFLASWD,DPTR_XSCAFLASWD,DPTR_XDIRSRFSWD,DPTR_GMASKkids           )
+END IF
+!
+CALL SECOND_MNH2(ZTIME2)
+XT_2WAY = XT_2WAY + ZTIME2 - ZTIME1 - XTIME_LES_BU_PROCESS - XTIME_BU_PROCESS
+!
+!-------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------
+!
+!*       10.    FORCING
+!               -------
+!
+!
+ZTIME1 = ZTIME2
+XTIME_BU_PROCESS = 0.
+XTIME_LES_BU_PROCESS = 0.
+IF (LCARTESIAN) THEN
+  CALL SM_GRIDCART(XXHAT,XYHAT,XZHAT,XZS,LSLEVE,XLEN1,XLEN2,XZSMT,XDXHAT,XDYHAT,XZZ,ZJ)
+  XMAP=1.
+ELSE
+  CALL SM_GRIDPROJ(XXHAT,XYHAT,XZHAT,XZS,LSLEVE,XLEN1,XLEN2,XZSMT,XLATORI,XLONORI, &
+                   XMAP,XLAT,XLON,XDXHAT,XDYHAT,XZZ,ZJ)
+END IF
+!
+IF ( LFORCING ) THEN
+  CALL FORCING(XTSTEP,LUSERV,XRHODJ,XCORIOZ,XZHAT,XZZ,TDTCUR,&
+               XUFRC_PAST, XVFRC_PAST,                &
+               XUT,XVT,XWT,XTHT,XTKET,XRT,XSVT,       &
+               XRUS,XRVS,XRWS,XRTHS,XRTKES,XRRS,XRSVS,IMI,ZJ)
+END IF
+!
+IF ( L2D_ADV_FRC ) THEN 
+  CALL ADV_FORCING_n(XRHODJ,TDTCUR,XTHT,XRT,XZZ,XRTHS,XRRS)
+END IF
+IF ( L2D_REL_FRC ) THEN 
+  CALL REL_FORCING_n(XRHODJ,TDTCUR,XTHT,XRT,XZZ,XRTHS,XRRS)
+END IF
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_FORCING = XT_FORCING + ZTIME2 - ZTIME1 &
+             - XTIME_LES_BU_PROCESS - XTIME_BU_PROCESS
+!
+!-------------------------------------------------------------------------------
+!
+!*       11.    NUDGING
+!               -------
+!
+!
+ZTIME1 = ZTIME2
+XTIME_BU_PROCESS = 0.
+XTIME_LES_BU_PROCESS = 0.
+!
+IF ( LNUDGING ) THEN
+  CALL NUDGING(LUSERV,XRHODJ,XTNUDGING,         &
+               XUT,XVT,XWT,XTHT,XRT,            &
+               XLSUM,XLSVM,XLSWM,XLSTHM,XLSRVM, &
+               XRUS,XRVS,XRWS,XRTHS,XRRS)
+
+END IF
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_NUDGING = XT_NUDGING + ZTIME2 - ZTIME1 &
+             - XTIME_LES_BU_PROCESS - XTIME_BU_PROCESS
+!
+!-------------------------------------------------------------------------------
+!
+!*       12.    DYNAMICAL SOURCES
+!               -----------------
+!
+ZTIME1 = ZTIME2
+XTIME_BU_PROCESS = 0.
+XTIME_LES_BU_PROCESS = 0.
+!
+IF( LTRANS ) THEN
+  XUT(:,:,:) = XUT(:,:,:) + XUTRANS
+  XVT(:,:,:) = XVT(:,:,:) + XVTRANS
+END IF
+!
+CALL DYN_SOURCES( NRR,NRRL, NRRI,                              &
+                  XUT, XVT, XWT, XTHT, XRT,                    &
+                  XCORIOX, XCORIOY, XCORIOZ, XCURVX, XCURVY,   &
+                  XRHODJ, XZZ, XTHVREF, XEXNREF,               &
+                  XRUS, XRVS, XRWS, XRTHS                      )
+!
+IF( LTRANS ) THEN
+  XUT(:,:,:) = XUT(:,:,:) - XUTRANS
+  XVT(:,:,:) = XVT(:,:,:) - XVTRANS
+END IF
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_SOURCES = XT_SOURCES + ZTIME2 - ZTIME1 &
+             - XTIME_LES_BU_PROCESS - XTIME_BU_PROCESS
+!
+!-------------------------------------------------------------------------------
+!
+!*       13.    NUMERICAL DIFFUSION
+!               -------------------
+!
+ZTIME1 = ZTIME2
+XTIME_BU_PROCESS = 0.
+XTIME_LES_BU_PROCESS = 0.
+!
+IF ( LNUMDIFU .OR. LNUMDIFTH .OR. LNUMDIFSV ) THEN
+!
+  CALL UPDATE_HALO_ll(TFIELDT_ll, IINFO_ll)
+  CALL UPDATE_HALO2_ll(TFIELDT_ll, THALO2T_ll, IINFO_ll)
+  IF ( .NOT. LSTEADYLS ) THEN
+     CALL UPDATE_HALO_ll(TLSFIELD_ll, IINFO_ll)
+     CALL UPDATE_HALO_ll(TLSFIELD2D_ll,IINFO_ll) 
+     CALL UPDATE_HALO2_ll(TLSFIELD_ll, TLSHALO2_ll, IINFO_ll)
+  END IF
+  CALL NUM_DIFF ( CLBCX, CLBCY, NRR, NSV,                               &
+                  XDK2U, XDK4U, XDK2TH, XDK4TH, XDK2SV, XDK4SV, IMI,    &
+                  XUT, XVT, XWT, XTHT, XTKET, XRT, XSVT,                &
+                  XLSUM,XLSVM,XLSWM,XLSTHM,XLSRVM,XRHODJ,               &
+                  XRUS, XRVS, XRWS, XRTHS, XRTKES, XRRS, XRSVS,         &
+                  LZDIFFU,LNUMDIFU, LNUMDIFTH, LNUMDIFSV,               &
+                  THALO2T_ll, TLSHALO2_ll,XZDIFFU_HALO2      )
+END IF
+!
+DO JSV = NSV_CHEMBEG,NSV_CHEMEND
+  XRSVS(:,:,:,JSV) = MAX(XRSVS(:,:,:,JSV),0.)
+END DO
+DO JSV = NSV_CHICBEG,NSV_CHICEND
+  XRSVS(:,:,:,JSV) = MAX(XRSVS(:,:,:,JSV),0.)
+END DO
+DO JSV = NSV_AERBEG,NSV_AEREND
+  XRSVS(:,:,:,JSV) = MAX(XRSVS(:,:,:,JSV),0.)
+END DO
+DO JSV = NSV_LNOXBEG,NSV_LNOXEND
+  XRSVS(:,:,:,JSV) = MAX(XRSVS(:,:,:,JSV),0.)
+END DO
+DO JSV = NSV_DSTBEG,NSV_DSTEND
+  XRSVS(:,:,:,JSV) = MAX(XRSVS(:,:,:,JSV),0.)
+END DO
+DO JSV = NSV_SLTBEG,NSV_SLTEND
+  XRSVS(:,:,:,JSV) = MAX(XRSVS(:,:,:,JSV),0.)
+END DO
+DO JSV = NSV_PPBEG,NSV_PPEND
+  XRSVS(:,:,:,JSV) = MAX(XRSVS(:,:,:,JSV),0.)
+END DO
+#ifdef MNH_FOREFIRE
+DO JSV = NSV_FFBEG,NSV_FFEND
+  XRSVS(:,:,:,JSV) = MAX(XRSVS(:,:,:,JSV),0.)
+END DO
+#endif
+DO JSV = NSV_CSBEG,NSV_CSEND
+  XRSVS(:,:,:,JSV) = MAX(XRSVS(:,:,:,JSV),0.)
+END DO
+DO JSV = NSV_DSTDEPBEG,NSV_DSTDEPEND
+  XRSVS(:,:,:,JSV) = MAX(XRSVS(:,:,:,JSV),0.)
+END DO
+DO JSV = NSV_SLTDEPBEG,NSV_SLTDEPEND
+  XRSVS(:,:,:,JSV) = MAX(XRSVS(:,:,:,JSV),0.)
+END DO
+DO JSV = NSV_AERDEPBEG,NSV_AERDEPEND
+  XRSVS(:,:,:,JSV) = MAX(XRSVS(:,:,:,JSV),0.)
+END DO
+DO JSV = NSV_SNWBEG,NSV_SNWEND
+  XRSVS(:,:,:,JSV) = MAX(XRSVS(:,:,:,JSV),0.)
+END DO
+IF (CELEC .NE. 'NONE') THEN
+  XRSVS(:,:,:,NSV_ELECBEG) = MAX(XRSVS(:,:,:,NSV_ELECBEG),0.)
+  XRSVS(:,:,:,NSV_ELECEND) = MAX(XRSVS(:,:,:,NSV_ELECEND),0.)
+END IF
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_DIFF = XT_DIFF + ZTIME2 - ZTIME1 &
+          - XTIME_LES_BU_PROCESS - XTIME_BU_PROCESS
+!
+!-------------------------------------------------------------------------------
+!
+!*       14.    UPPER AND LATERAL RELAXATION
+!               ----------------------------
+!
+ZTIME1 = ZTIME2
+XTIME_BU_PROCESS = 0.
+XTIME_LES_BU_PROCESS = 0.
+!
+IF(LVE_RELAX .OR. LVE_RELAX_GRD .OR. LHORELAX_UVWTH .OR. LHORELAX_RV .OR.&
+   LHORELAX_RC .OR. LHORELAX_RR .OR. LHORELAX_RI .OR. LHORELAX_RS .OR.   &
+   LHORELAX_RG .OR. LHORELAX_RH .OR. LHORELAX_TKE .OR.                   &
+   ANY(LHORELAX_SV)) THEN
+  CALL RELAXATION (LVE_RELAX,LVE_RELAX_GRD,LHORELAX_UVWTH,LHORELAX_RV,LHORELAX_RC,   &
+                   LHORELAX_RR,LHORELAX_RI,LHORELAX_RS,LHORELAX_RG,    &
+                   LHORELAX_RH,LHORELAX_TKE,LHORELAX_SV,               &
+                   LHORELAX_SVC2R2,LHORELAX_SVC1R3,                    &
+                   LHORELAX_SVELEC,LHORELAX_SVLG,                      &
+                   LHORELAX_SVCHEM,LHORELAX_SVCHIC,LHORELAX_SVAER,     &
+                   LHORELAX_SVDST,LHORELAX_SVSLT,LHORELAX_SVPP,        &
+                   LHORELAX_SVCS,LHORELAX_SVSNW,                       &
+#ifdef MNH_FOREFIRE
+                   LHORELAX_SVFF,                                      &
+#endif
+                   KTCOUNT,NRR,NSV,XTSTEP,XRHODJ,                      &
+                   XUT, XVT, XWT, XTHT, XRT, XSVT, XTKET,              &
+                   XLSUM, XLSVM, XLSWM, XLSTHM,                        &
+                   XLBXUM, XLBXVM, XLBXWM, XLBXTHM,                    &
+                   XLBXRM, XLBXSVM, XLBXTKEM,                          &
+                   XLBYUM, XLBYVM, XLBYWM, XLBYTHM,                    &
+                   XLBYRM, XLBYSVM, XLBYTKEM,                          &
+                   NALBOT, XALK, XALKW,                                &
+                   NALBAS, XALKBAS, XALKWBAS,                          &
+                   LMASK_RELAX,XKURELAX, XKVRELAX, XKWRELAX,           &
+                   NRIMX,NRIMY,                                        &
+                   XRUS, XRVS, XRWS, XRTHS, XRRS, XRSVS, XRTKES        )
+END IF
+
+IF (CELEC.NE.'NONE' .AND. LRELAX2FW_ION) THEN
+   CALL RELAX2FW_ION (KTCOUNT, IMI, XTSTEP, XRHODJ, XSVT, NALBOT,      &
+                      XALK, LMASK_RELAX, XKWRELAX, XRSVS )   
+END IF                      
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_RELAX = XT_RELAX + ZTIME2 - ZTIME1 &
+           - XTIME_LES_BU_PROCESS - XTIME_BU_PROCESS
+!
+!-------------------------------------------------------------------------------
+!
+!*       15.    PARAMETRIZATIONS' MONITOR
+!               -------------------------
+!
+ZTIME1 = ZTIME2
+!
+CALL PHYS_PARAM_n(KTCOUNT,TZBAKFILE, GCLOSE_OUT,                &
+                  XT_RAD,XT_SHADOWS,XT_DCONV,XT_GROUND,XT_MAFL, &
+                  XT_DRAG,XT_TURB,XT_TRACER,                    &
+                  ZTIME,ZWETDEPAER,GMASKkids,GCLOUD_ONLY)
+!
+IF (CDCONV/='NONE') THEN
+  XPACCONV = XPACCONV + XPRCONV * XTSTEP
+  IF (LCH_CONV_LINOX) THEN
+    XIC_TOTAL_NUMBER = XIC_TOTAL_NUMBER + XIC_RATE * XTSTEP
+    XCG_TOTAL_NUMBER = XCG_TOTAL_NUMBER + XCG_RATE * XTSTEP
+  END IF
+END IF
+!
+IF (IBAK>0 .AND. IBAK <= NBAK_NUMB ) THEN
+  IF (KTCOUNT == TBACKUPN(IBAK)%NSTEP) THEN
+    IF (CSURF=='EXTE') THEN
+      CALL GOTO_SURFEX(IMI)
+      CALL DIAG_SURF_ATM_n(YSURF_CUR,'MESONH')
+      TFILE_SURFEX => TZBAKFILE
+      CALL WRITE_DIAG_SURF_ATM_n(YSURF_CUR,'MESONH','ALL')
+      NULLIFY(TFILE_SURFEX)
+    END IF
+  END IF
+END IF
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_PARAM = XT_PARAM + ZTIME2 - ZTIME1 - XTIME_LES - ZTIME
+!
+!-------------------------------------------------------------------------------
+!
+!*       16.    TEMPORAL SERIES
+!               ---------------
+!
+ZTIME1 = ZTIME2
+!
+IF (LSERIES) THEN
+  IF ( MOD (KTCOUNT-1,NFREQSERIES) == 0 ) CALL SERIES_n
+END IF
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_STEP_MISC = XT_STEP_MISC + ZTIME2 - ZTIME1
+!
+!-------------------------------------------------------------------------------
+!
+!*       17.    LARGE SCALE FIELD REFRESH
+!               -------------------------
+!
+ZTIME1 = ZTIME2
+!
+IF (.NOT. LSTEADYLS) THEN
+  IF (  IMI==1                             .AND.      &
+    NCPL_CUR < NCPL_NBR                              ) THEN
+    IF (KTCOUNT+1 == NCPL_TIMES(NCPL_CUR,1)          ) THEN
+                                  ! The next current time reachs a
+      NCPL_CUR=NCPL_CUR+1         ! coupling one, LS sources are refreshed
+      !
+      CALL LS_COUPLING(XTSTEP,GSTEADY_DMASS,CCONF,                          &
+             CGETTKET,                                                      &
+             CGETRVT,CGETRCT,CGETRRT,CGETRIT,                               &
+             CGETRST,CGETRGT,CGETRHT,CGETSVT,LCH_INIT_FIELD, NSV,           &
+             NIMAX_ll,NJMAX_ll,                                             &
+             NSIZELBX_ll,NSIZELBXU_ll,NSIZELBY_ll,NSIZELBYV_ll,             &
+             NSIZELBXTKE_ll,NSIZELBYTKE_ll,                                 &
+             NSIZELBXR_ll,NSIZELBYR_ll,NSIZELBXSV_ll,NSIZELBYSV_ll,         &
+             XLSUM,XLSVM,XLSWM,XLSTHM,XLSRVM,XLSZWSM,XDRYMASST,             &
+             XLBXUM,XLBXVM,XLBXWM,XLBXTHM,XLBXTKEM,XLBXRM,XLBXSVM,          &
+             XLBYUM,XLBYVM,XLBYWM,XLBYTHM,XLBYTKEM,XLBYRM,XLBYSVM,          &
+             XLSUS,XLSVS,XLSWS,XLSTHS,XLSRVS,XLSZWSS,XDRYMASSS,             &
+             XLBXUS,XLBXVS,XLBXWS,XLBXTHS,XLBXTKES,XLBXRS,XLBXSVS,          &
+             XLBYUS,XLBYVS,XLBYWS,XLBYTHS,XLBYTKES,XLBYRS,XLBYSVS           )
+      !
+      DO JSV=NSV_CHEMBEG,NSV_CHEMEND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+      !
+      DO JSV=NSV_LNOXBEG,NSV_LNOXEND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+      !
+      DO JSV=NSV_AERBEG,NSV_AEREND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+      !
+      DO JSV=NSV_DSTBEG,NSV_DSTEND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+      !
+      DO JSV=NSV_DSTDEPBEG,NSV_DSTDEPEND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+      !
+      DO JSV=NSV_SLTBEG,NSV_SLTEND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+      !
+      DO JSV=NSV_SLTDEPBEG,NSV_SLTDEPEND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+      !
+      DO JSV=NSV_PPBEG,NSV_PPEND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+      !
+#ifdef MNH_FOREFIRE
+      DO JSV=NSV_FFBEG,NSV_FFEND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+      !
+#endif
+      DO JSV=NSV_CSBEG,NSV_CSEND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+      !
+      DO JSV=NSV_SNWBEG,NSV_SNWEND
+        XLBXSVS(:,:,:,JSV)=MAX(XLBXSVS(:,:,:,JSV),0.)
+        XLBYSVS(:,:,:,JSV)=MAX(XLBYSVS(:,:,:,JSV),0.)
+      ENDDO
+      !
+     END IF
+  END IF
+END IF
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_COUPL = XT_COUPL + ZTIME2 - ZTIME1
+!
+!-------------------------------------------------------------------------------
+!
+!
+!
+!*      8 Bis . Blowing snow scheme
+!              ---------
+!
+IF(LBLOWSNOW) THEN
+ CALL BLOWSNOW(CLBCX,CLBCY,XTSTEP,NRR,XPABST,XTHT,XRT,XZZ,XRHODREF,  &
+                     XRHODJ,XEXNREF,XRRS,XRTHS,XSVT,XRSVS,XSNWSUBL3D )
+ENDIF
+!
+!-----------------------------------------------------------------------
+!
+!*       8 Ter  VISCOSITY (no-slip condition inside)
+!              ---------
+!
+!
+IF ( LVISC ) THEN
+!
+ZTIME1 = ZTIME2
+!
+   CALL VISCOSITY(CLBCX, CLBCY, NRR, NSV, XMU_V,XPRANDTL,         &
+                  LVISC_UVW,LVISC_TH,LVISC_SV,LVISC_R,            &
+                  LDRAG,    &
+                  XUT, XVT, XWT, XTHT, XRT, XSVT,                 &
+                  XRHODJ, XDXX, XDYY, XDZZ, XDZX, XDZY,           &
+                  XRUS, XRVS, XRWS, XRTHS, XRRS, XRSVS,XDRAG )
+!
+ENDIF
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_VISC = XT_VISC + ZTIME2 - ZTIME1
+!!
+!-------------------------------------------------------------------------------
+!
+!*       9.    ADVECTION
+!              ---------
+!
+ZTIME1 = ZTIME2
+XTIME_BU_PROCESS = 0.
+XTIME_LES_BU_PROCESS = 0.
+!
+!$acc update device(XRTHS)
+!
+!$acc data create (XUT, XVT, XWT)                                         &
+!$acc &    copyin (XTHT, XPABST, XRT, XSVT, XRTHS_CLD, XRRS_CLD, XTHVREF) &
+!$acc &    copy   (XRRS, XRUS, XRVS, XRWS)                         &
+!$acc &    copy   (XRWS_PRES)                                             & !XRWS_PRES copy and not copyout (hidden in UPDATE_HALO)
+!$acc &    present(XDXX, XDYY, XDZZ, XDZX, XDZY, XRHODJ)
+!
+!$acc update device(XUT, XVT, XWT, XRHODJ)
+
+!
+!
+!$acc data copyin (XTKET, XRSVS_CLD) &
+!$acc &    copy   (XRTKES, XRSVS)    &
+!$acc &    copyout(XRTKEMS)
+CALL ADVECTION_METSV ( TZBAKFILE, GCLOSE_OUT,CUVW_ADV_SCHEME,          &
+                 CMET_ADV_SCHEME, CSV_ADV_SCHEME, CCLOUD, NSPLIT,      &
+                 LSPLIT_CFL, XSPLIT_CFL, LCFL_WRIT,                    &
+                 CLBCX, CLBCY, NRR, NSV, TDTCUR, XTSTEP,               &
+                 XUT, XVT, XWT, XTHT, XRT, XTKET, XSVT, XPABST,        &
+                 XTHVREF, XRHODJ, XDXX, XDYY, XDZZ, XDZX, XDZY,        &
+                 XRTHS, XRRS, XRTKES, XRSVS,                           &
+                 XRTHS_CLD, XRRS_CLD, XRSVS_CLD, XRTKEMS               )
+!$acc end data
+!
+!$acc update host(XRTHS)
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_ADV = XT_ADV + ZTIME2 - ZTIME1 - XTIME_LES_BU_PROCESS - XTIME_BU_PROCESS
+!
+!-------------------------------------------------------------------------------
+ZTIME1 = ZTIME2
+XTIME_BU_PROCESS = 0.
+XTIME_LES_BU_PROCESS = 0.
+!
+!$acc kernels
+ZRWS(:,:,:) = XRWS(:,:,:)
+!$acc end kernels
+!
+CALL GRAVITY_IMPL ( CLBCX, CLBCY, NRR, NRRL, NRRI,XTSTEP,            &
+                 XTHT, XRT, XTHVREF, XRHODJ, XRWS, XRTHS, XRRS,      &
+                 XRTHS_CLD, XRRS_CLD                                 )
+!
+! At the initial instant the difference with the ref state creates a 
+! vertical velocity production that must not be advected as it is 
+! compensated by the pressure gradient
+!
+IF (KTCOUNT == 1 .AND. CCONF=='START') THEN
+!$acc kernels
+  XRWS_PRES(:,:,:) = ZRWS(:,:,:) - XRWS(:,:,:)
+!$acc end kernels
+END IF
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_GRAV = XT_GRAV + ZTIME2 - ZTIME1 - XTIME_LES_BU_PROCESS - XTIME_BU_PROCESS
+! 
+ZTIME1 = ZTIME2
+XTIME_BU_PROCESS = 0.
+XTIME_LES_BU_PROCESS = 0.
+!
+IF ((CUVW_ADV_SCHEME(1:3)=='CEN') .AND. (CTEMP_SCHEME == 'LEFR')) THEN
+  IF (CUVW_ADV_SCHEME=='CEN4TH') THEN
+    NULLIFY(TZFIELDC_ll)
+    NULLIFY(TZHALO2C_ll)
+      CALL ADD3DFIELD_ll( TZFIELDC_ll, XUT, 'MODEL_n::XUT' )
+      CALL ADD3DFIELD_ll( TZFIELDC_ll, XVT, 'MODEL_n::XVT' )
+      CALL ADD3DFIELD_ll( TZFIELDC_ll, XWT, 'MODEL_n::XWT' )
+      CALL INIT_HALO2_ll(TZHALO2C_ll,3,IIU,IJU,IKU)
+      CALL UPDATE_HALO_ll(TZFIELDC_ll,IINFO_ll)
+      CALL UPDATE_HALO2_ll(TZFIELDC_ll, TZHALO2C_ll, IINFO_ll)
+!$acc update device(XUT, XVT, XWT)
+  END IF
+!$acc data copyin(XUM, XVM, XWM)    &
+!$acc &    copy  (XDUM, XDVM, XDWM)
+ CALL ADVECTION_UVW_CEN(CUVW_ADV_SCHEME,                           &
+                           CLBCX, CLBCY,                           &
+                           XTSTEP, KTCOUNT,                        &
+                           XUM, XVM, XWM, XDUM, XDVM, XDWM,        &
+                           XUT, XVT, XWT,                          &
+                           XRHODJ, XDXX, XDYY, XDZZ, XDZX, XDZY,   &
+                           XRUS,XRVS, XRWS,                        &
+                           TZHALO2C_ll                             )
+!$acc end data
+  IF (CUVW_ADV_SCHEME=='CEN4TH') THEN
+    CALL CLEANLIST_ll(TZFIELDC_ll)
+    NULLIFY(TZFIELDC_ll)
+    CALL  DEL_HALO2_ll(TZHALO2C_ll)
+    NULLIFY(TZHALO2C_ll)
+  END IF
+ELSE
+
+!$acc data copyin(XRUS_PRES, XRVS_PRES)
+  CALL ADVECTION_UVW(CUVW_ADV_SCHEME, CTEMP_SCHEME,                  &
+                 NWENO_ORDER, LSPLIT_WENO,                           &
+                 CLBCX, CLBCY, XTSTEP,                               &
+                 XUT, XVT, XWT,                                      &
+                 XRHODJ, XDXX, XDYY, XDZZ, XDZX, XDZY,               &
+                 XRUS, XRVS, XRWS,                                   &
+                 XRUS_PRES, XRVS_PRES, XRWS_PRES                     )
+!$acc end data
+END IF
+!
+!$acc end data
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_ADVUVW = XT_ADVUVW + ZTIME2 - ZTIME1 - XTIME_LES_BU_PROCESS - XTIME_BU_PROCESS
+!
+!-------------------------------------------------------------------------------
+!
+IF (NMODEL_CLOUD==IMI .AND. CTURBLEN_CLOUD/='NONE') THEN
+  CALL TURB_CLOUD_INDEX(XTSTEP,TZBAKFILE,                         &
+                        LTURB_DIAG,GCLOSE_OUT,NRRI,               &
+                        XRRS,XRT,XRHODJ,XDXX,XDYY,XDZZ,XDZX,XDZY, &
+                        XCEI )
+END IF
+!
+!-------------------------------------------------------------------------------
+!
+!*       18.    LATERAL BOUNDARY CONDITION FOR THE NORMAL VELOCITY
+!               --------------------------------------------------
+!
+ZTIME1 = ZTIME2
+!
+ZRUS=XRUS
+ZRVS=XRVS
+ZRWS=XRWS
+!
+  CALL RAD_BOUND (CLBCX,CLBCY,CTURB,XCARPKMAX,           &
+                XTSTEP,                                  &
+                XDXHAT, XDYHAT, XZHAT,                   &
+                XUT, XVT,                                &
+                XLBXUM, XLBYVM, XLBXUS, XLBYVS,          &
+                XCPHASE, XCPHASE_PBL, XRHODJ,            &
+                XTKET,XRUS, XRVS, XRWS                   )
+ZRUS=XRUS-ZRUS
+ZRVS=XRVS-ZRVS
+ZRWS=XRWS-ZRWS
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_RAD_BOUND = XT_RAD_BOUND + ZTIME2 - ZTIME1
+!
+!-------------------------------------------------------------------------------
+!
+!*       19.    PRESSURE COMPUTATION
+!               --------------------
+!
+ZTIME1 = ZTIME2
+XTIME_BU_PROCESS = 0.
+XTIME_LES_BU_PROCESS = 0.
+!
+ZPABST = XPABST
+!
+IF(.NOT. L1D) THEN
+!
+  XRUS_PRES = XRUS
+  XRVS_PRES = XRVS
+  XRWS_PRES = XRWS
+!
+  CALL PRESSUREZ( CLBCX,CLBCY,CPRESOPT,NITR,LITRADJ,KTCOUNT, XRELAX,IMI, &
+                  XRHODJ,XDXX,XDYY,XDZZ,XDZX,XDZY,XDXHATM,XDYHATM,XRHOM, &
+                  XAF,XBFY,XCF,XTRIGSX,XTRIGSY,NIFAXX,NIFAXY,            &
+                  NRR,NRRL,NRRI,XDRYMASST,XREFMASS,XMASS_O_PHI0,         &
+                  XTHT,XRT,XRHODREF,XTHVREF,XRVREF,XEXNREF, XLINMASS,    &
+                  XRUS, XRVS, XRWS, XPABST,                              &
+                  XBFB,                                                  &
+                  XBF_SXP2_YP1_Z,                                        &
+                  XAF_ZS,XBF_ZS,XCF_ZS,                                  &
+                  XDXATH_ZS,XDYATH_ZS,XRHO_ZS,                           &
+                  XA_K,XB_K,XC_K,XD_K) !JUAN FULL ZSOLVER
+!
+  XRUS_PRES = XRUS - XRUS_PRES + ZRUS
+  XRVS_PRES = XRVS - XRVS_PRES + ZRVS
+  XRWS_PRES = XRWS - XRWS_PRES + ZRWS
+!
+END IF
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_PRESS = XT_PRESS + ZTIME2 - ZTIME1 &
+           - XTIME_LES_BU_PROCESS - XTIME_BU_PROCESS
+!
+!-------------------------------------------------------------------------------
+!
+!*       20.    CHEMISTRY/AEROSOLS
+!               ------------------
+!
+ZTIME1 = ZTIME2
+XTIME_BU_PROCESS = 0.
+XTIME_LES_BU_PROCESS = 0.
+!
+IF (LUSECHEM) THEN
+  CALL CH_MONITOR_n(ZWETDEPAER,KTCOUNT,XTSTEP, ILUOUT, NVERB)
+END IF
+!
+! For inert aerosol (dust and sea salt) => aer_monitor_n
+IF ((LDUST).OR.(LSALT)) THEN
+!
+! tests to see if any cloud exists
+!   
+    GCLD=.TRUE.
+    IF (GCLD .AND. NRR.LE.3 ) THEN 
+      IF( MAXVAL(XCLDFR(:,:,:)).LE. 1.E-10 .AND. GCLOUD_ONLY ) THEN
+          GCLD = .FALSE.                ! only the cloudy verticals would be 
+                                        ! refreshed but there is no clouds 
+      END IF
+    END IF
+!
+    IF (GCLD .AND. NRR.GE.4 ) THEN 
+      IF( CCLOUD(1:3)=='ICE' )THEN
+        IF( MAXVAL(XRT(:,:,:,2)).LE.XRTMIN(2) .AND.             &
+            MAXVAL(XRT(:,:,:,4)).LE.XRTMIN(4) .AND. GCLOUD_ONLY ) THEN
+            GCLD = .FALSE.            ! only the cloudy verticals would be 
+                                      ! refreshed but there is no cloudwater and ice
+        END IF
+      END IF
+      IF( CCLOUD=='C3R5' )THEN
+        IF( MAXVAL(XRT(:,:,:,2)).LE.XRTMIN_C1R3(2) .AND.             &
+            MAXVAL(XRT(:,:,:,4)).LE.XRTMIN_C1R3(4) .AND. GCLOUD_ONLY ) THEN
+            GCLD = .FALSE.            ! only the cloudy verticals would be 
+                                      ! refreshed but there is no cloudwater and ice
+        END IF
+      END IF
+      IF( CCLOUD=='LIMA' )THEN
+        IF( MAXVAL(XRT(:,:,:,2)).LE.XRTMIN_LIMA(2) .AND.             &
+            MAXVAL(XRT(:,:,:,4)).LE.XRTMIN_LIMA(4) .AND. GCLOUD_ONLY ) THEN
+            GCLD = .FALSE.            ! only the cloudy verticals would be 
+                                      ! refreshed but there is no cloudwater and ice
+        END IF
+      END IF
+    END IF
+
+!
+        CALL AER_MONITOR_n(KTCOUNT,XTSTEP, ILUOUT, NVERB, GCLD)
+END IF
+!
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_CHEM = XT_CHEM + ZTIME2 - ZTIME1 &
+      - XTIME_LES_BU_PROCESS - XTIME_BU_PROCESS
+!
+ZTIME = ZTIME + XTIME_LES_BU_PROCESS + XTIME_BU_PROCESS
+
+!-------------------------------------------------------------------------------
+!
+!*       20.    WATER MICROPHYSICS
+!               ------------------
+!
+ZTIME1 = ZTIME2
+XTIME_BU_PROCESS = 0.
+XTIME_LES_BU_PROCESS = 0.
+!
+IF (CCLOUD /= 'NONE' .AND. CELEC == 'NONE') THEN
+!
+  IF (CCLOUD == 'C2R2' .OR. CCLOUD == 'KHKO' .OR. CCLOUD == 'C3R5' &
+                                             .OR. CCLOUD == "LIMA" ) THEN
+    IF ( LFORCING ) THEN
+      XWT_ACT_NUC(:,:,:) = XWT(:,:,:) + XWTFRC(:,:,:)
+    ELSE
+      XWT_ACT_NUC(:,:,:) = XWT(:,:,:)
+    END IF
+    IF (CTURB /= 'NONE' ) THEN
+     IF ( ((CCLOUD=='C2R2'.OR.CCLOUD=='KHKO').AND.LACTTKE) .OR. (CCLOUD=='LIMA'.AND.MACTTKE) ) THEN 
+       XWT_ACT_NUC(:,:,:) = XWT_ACT_NUC(:,:,:) +  (2./3. * XTKET(:,:,:))**0.5
+     ELSE
+       XWT_ACT_NUC(:,:,:) = XWT_ACT_NUC(:,:,:) 
+     ENDIF
+    ENDIF
+  ELSE
+    XWT_ACT_NUC(:,:,:) = 0.
+  END IF
+!
+  XRTHS_CLD(:, :, : )    = XRTHS(:, :, : )
+  XRRS_CLD (:, :, :, : ) = XRRS(:, :, :, : )
+  XRSVS_CLD(:, :, :, : ) = XRSVS(:, :, :, : )
+!$acc data present(XRHODJ)                                                                       &
+!$acc &    copyin (XZZ, XRHODREF, XEXNREF, ZPABST, XTHT, XSIGS, VSIGQSAT, XMFCONV, XTHM, XPABSM, &
+!$acc &            XRCM, XWT_ACT_NUC, XDTHRAD, XCF_MF, XRC_MF, XRI_MF,                           &
+!$acc &            XSOLORG, XMI)                                                                 &
+!$acc &    copy   (XSUPSAT, XNACT, XNPRO, XSSPRO,                                                &
+!$acc &            XRT, XRRS, XSVT, XRSVS, XCLDFR, XCIT, XINPRR3D, XEVAP3D,               &
+!$acc &            XINPRC, XINPRR, XINPRS, XINPRG, XINPRH, XINDEP)                               &
+!$acc &    copyout(XSRCT, XRAINFR)
+
+!$acc update device ( XRTHS )
+  
+  IF (CSURF=='EXTE') THEN
+    ALLOCATE (ZSEA(SIZE(XRHODJ,1),SIZE(XRHODJ,2)))
+    ALLOCATE (ZTOWN(SIZE(XRHODJ,1),SIZE(XRHODJ,2)))
+    ZSEA(:,:) = 0.
+    ZTOWN(:,:)= 0.
+    CALL MNHGET_SURF_PARAM_n (PSEA=ZSEA(:,:),PTOWN=ZTOWN(:,:))
+!$acc data copyin(ZSEA, ZTOWN )
+    CALL RESOLVED_CLOUD ( CCLOUD, CACTCCN, CSCONV, CMF_CLOUD, NRR, NSPLITR,    &
+                          NSPLITG, IMI, KTCOUNT,                               &
+                          CLBCX,CLBCY,TZBAKFILE, CRAD, CTURBDIM,               &
+                          GCLOSE_OUT, LSUBG_COND,LSIGMAS,CSUBG_AUCV,XTSTEP,    &
+                          XZZ, XRHODJ, XRHODREF, XEXNREF,                      &
+                          ZPABST, XTHT,XRT,XSIGS,VSIGQSAT,XMFCONV,XTHM,XRCM,   &
+                          XPABSM, XWT_ACT_NUC,XDTHRAD, XRTHS, XRRS,            &
+                          XSVT, XRSVS,                                         &
+                          XSRCT, XCLDFR,XCIT,                                  &
+                          LSEDIC,KACTIT, KSEDC, KSEDI, KRAIN, KWARM, KHHONI,   &
+                          LCONVHG, XCF_MF,XRC_MF, XRI_MF,                      &
+!                           XINPRC,ZINPRC3D,XINPRR, XINPRR3D, XEVAP3D,             &
+!                           XINPRS,ZINPRS3D, XINPRG,ZINPRG3D, XINPRH,ZINPRH3D,   &
+                          XINPRC,XINPRR, XINPRR3D, XEVAP3D,             &
+                          XINPRS, XINPRG,XINPRH,   &
+!                           XSOLORG, XMI,ZSPEEDC, ZSPEEDR, ZSPEEDS, ZSPEEDG, ZSPEEDH, &
+                          XSOLORG, XMI, &
+                          XINDEP, XSUPSAT, XNACT, XNPRO,XSSPRO, XRAINFR,       &
+                          ZSEA, ZTOWN                                          )
+!$acc end data
+    DEALLOCATE(ZTOWN)
+  ELSE
+    CALL RESOLVED_CLOUD ( CCLOUD, CACTCCN, CSCONV, CMF_CLOUD, NRR, NSPLITR,    &
+                          NSPLITG, IMI, KTCOUNT,                               &
+                          CLBCX,CLBCY,TZBAKFILE, CRAD, CTURBDIM,               &
+                          GCLOSE_OUT, LSUBG_COND,LSIGMAS,CSUBG_AUCV,           &
+                          XTSTEP,XZZ, XRHODJ, XRHODREF, XEXNREF,               &
+                          ZPABST, XTHT,XRT,XSIGS,VSIGQSAT,XMFCONV,XTHM,XRCM,   &
+                          XPABSM, XWT_ACT_NUC,XDTHRAD, XRTHS, XRRS,            &
+                          XSVT, XRSVS,                                         &
+                          XSRCT, XCLDFR,XCIT,                                  &
+                          LSEDIC,KACTIT, KSEDC, KSEDI, KRAIN, KWARM, KHHONI,   &
+                          LCONVHG, XCF_MF,XRC_MF, XRI_MF,                      &
+!                           XINPRC,ZINPRC3D,XINPRR, XINPRR3D, XEVAP3D,             &
+!                           XINPRS,ZINPRS3D, XINPRG,ZINPRG3D, XINPRH,ZINPRH3D,   &
+                          XINPRC,XINPRR, XINPRR3D, XEVAP3D,             &
+                          XINPRS, XINPRG,XINPRH,   &
+!                           XSOLORG, XMI,ZSPEEDC, ZSPEEDR, ZSPEEDS, ZSPEEDG, ZSPEEDH, &
+                          XSOLORG, XMI, &
+                          XINDEP, XSUPSAT, XNACT, XNPRO,XSSPRO, XRAINFR        )
+  END IF
+!$acc end data
+
+!$acc update host(XRTHS)
+  
+  XRTHS_CLD(:, :, : )    = XRTHS(:, :, : )    - XRTHS_CLD(:, :, : )
+  XRRS_CLD (:, :, :, : ) = XRRS (:, :, :, : ) - XRRS_CLD (:, :, :, : )
+  XRSVS_CLD(:, :, :, : ) = XRSVS(:, :, :, : ) - XRSVS_CLD(:, :, :, : )
+!
+  IF (CCLOUD /= 'REVE' ) THEN
+    XACPRR = XACPRR + XINPRR * XTSTEP
+          IF ( (CCLOUD(1:3) == 'ICE' .AND. LSEDIC ) .OR.                     &
+        ((CCLOUD == 'C2R2' .OR. CCLOUD == 'C3R5' .OR. CCLOUD == 'KHKO' &
+                           .OR. CCLOUD == 'LIMA' ) .AND. KSEDC ) )    THEN
+      XACPRC = XACPRC + XINPRC * XTSTEP
+      IF (LDEPOSC .OR. LDEPOC) XACDEP = XACDEP + XINDEP * XTSTEP
+    END IF
+    IF (CCLOUD(1:3) == 'ICE' .OR. CCLOUD == 'C3R5' .OR. &
+                                 (CCLOUD == 'LIMA' .AND. LCOLD ) ) THEN
+      XACPRS = XACPRS + XINPRS * XTSTEP
+      XACPRG = XACPRG + XINPRG * XTSTEP
+      IF (CCLOUD == 'ICE4' .OR. (CCLOUD == 'LIMA' .AND. LHAIL)) XACPRH = XACPRH + XINPRH * XTSTEP          
+    END IF
+!
+! Lessivage des CCN et IFN nucléables par Slinn
+!
+    IF (LSCAV .AND. (CCLOUD == 'LIMA')) THEN
+      CALL LIMA_PRECIP_SCAVENGING(CCLOUD, ILUOUT, KTCOUNT,XTSTEP,XRT(:,:,:,3), &
+                              XRHODREF, XRHODJ, XZZ, XPABST, XTHT,             &
+                              XSVT(:,:,:,NSV_LIMA_BEG:NSV_LIMA_END),           &
+                              XRSVS(:,:,:,NSV_LIMA_BEG:NSV_LIMA_END), XINPAP   )
+!
+      XACPAP(:,:) = XACPAP(:,:) + XINPAP(:,:) * XTSTEP
+    END IF
+  END IF
+!
+! It is necessary that SV_C2R2 and SV_C1R3 are contiguous in the preceeding CALL
+!
+END IF
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_CLOUD = XT_CLOUD + ZTIME2 - ZTIME1 &
+           - XTIME_LES_BU_PROCESS - XTIME_BU_PROCESS
+!
+!-------------------------------------------------------------------------------
+!
+!*       21.    CLOUD ELECTRIFICATION AND LIGHTNING FLASHES
+!               -------------------------------------------
+!
+ZTIME1 = ZTIME2
+XTIME_BU_PROCESS = 0.
+XTIME_LES_BU_PROCESS = 0.
+!
+IF (CELEC /= 'NONE' .AND. (CCLOUD(1:3) == 'ICE')) THEN
+  XWT_ACT_NUC(:,:,:) = 0.
+!
+  XRTHS_CLD = XRTHS
+  XRRS_CLD  = XRRS
+  XRSVS_CLD = XRSVS
+  IF (CSURF=='EXTE') THEN
+    ALLOCATE (ZSEA(SIZE(XRHODJ,1),SIZE(XRHODJ,2)))
+    ALLOCATE (ZTOWN(SIZE(XRHODJ,1),SIZE(XRHODJ,2)))
+    ZSEA(:,:) = 0.
+    ZTOWN(:,:)= 0.
+    CALL MNHGET_SURF_PARAM_n (PSEA=ZSEA(:,:),PTOWN=ZTOWN(:,:))
+    CALL RESOLVED_ELEC_n (CCLOUD, CSCONV, CMF_CLOUD,                     &
+                          NRR, NSPLITR, IMI, KTCOUNT, OEXIT,             &
+                          CLBCX, CLBCY, CRAD, CTURBDIM,                  &
+                          LSUBG_COND, LSIGMAS,VSIGQSAT,CSUBG_AUCV,       &
+                          XTSTEP, XZZ, XRHODJ, XRHODREF, XEXNREF,        &
+                          ZPABST, XTHT, XRTHS, XWT,  XRT, XRRS,          &
+                          XSVT, XRSVS, XCIT,                             &
+                          XSIGS, XSRCT, XCLDFR, XMFCONV, XCF_MF, XRC_MF, &
+                          XRI_MF, LSEDIC, LWARM,                         &
+                          XINPRC, XINPRR, XINPRR3D, XEVAP3D,             &
+                          XINPRS, XINPRG, XINPRH,                        &
+                          ZSEA, ZTOWN                                    )
+    DEALLOCATE(ZTOWN)
+  ELSE
+    CALL RESOLVED_ELEC_n (CCLOUD, CSCONV, CMF_CLOUD,                     &
+                          NRR, NSPLITR, IMI, KTCOUNT, OEXIT,             &
+                          CLBCX, CLBCY, CRAD, CTURBDIM,                  &
+                          LSUBG_COND, LSIGMAS,VSIGQSAT, CSUBG_AUCV,      &
+                          XTSTEP, XZZ, XRHODJ, XRHODREF, XEXNREF,        &
+                          ZPABST, XTHT, XRTHS, XWT,                      &
+                          XRT, XRRS, XSVT, XRSVS, XCIT,                  &
+                          XSIGS, XSRCT, XCLDFR, XMFCONV, XCF_MF, XRC_MF, &
+                          XRI_MF, LSEDIC, LWARM,                         &
+                          XINPRC, XINPRR, XINPRR3D, XEVAP3D,             &
+                          XINPRS, XINPRG, XINPRH                         )
+  END IF
+  XRTHS_CLD = XRTHS - XRTHS_CLD
+  XRRS_CLD  = XRRS  - XRRS_CLD
+  XRSVS_CLD = XRSVS - XRSVS_CLD
+!
+  XACPRR = XACPRR + XINPRR * XTSTEP
+  IF ((CCLOUD(1:3) == 'ICE' .AND. LSEDIC)) & 
+       XACPRC = XACPRC + XINPRC * XTSTEP
+  IF (CCLOUD(1:3) == 'ICE') THEN
+    XACPRS = XACPRS + XINPRS * XTSTEP
+    XACPRG = XACPRG + XINPRG * XTSTEP
+    IF (CCLOUD == 'ICE4') XACPRH = XACPRH + XINPRH * XTSTEP          
+  END IF
+END IF
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_ELEC = XT_ELEC + ZTIME2 - ZTIME1 &
+           - XTIME_LES_BU_PROCESS - XTIME_BU_PROCESS
+!
+!-------------------------------------------------------------------------------
+!
+!*       21.    L.E.S. COMPUTATIONS
+!               -------------------
+!
+ZTIME1 = ZTIME2
+!
+CALL LES_n
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_SPECTRA = XT_SPECTRA + ZTIME2 - ZTIME1 + XTIME_LES_BU + XTIME_LES
+!
+!-------------------------------------------------------------------------------
+!
+!*       21. bis    MEAN_UM
+!               --------------------
+!
+IF (LMEAN_FIELD) THEN
+   CALL MEAN_FIELD(XUT, XVT, XWT, XTHT, XTKET, XPABST)
+END IF
+!
+!-------------------------------------------------------------------------------
+!
+!*       22.    UPDATE HALO OF EACH SUBDOMAINS FOR TIME T+DT
+!               --------------------------------------------
+!
+ZTIME1 = ZTIME2
+!
+CALL EXCHANGE (XTSTEP,NRR,NSV,XRHODJ,TFIELDS_ll,     &
+               XRUS, XRVS,XRWS,XRTHS,XRRS,XRTKES,XRSVS)
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_HALO = XT_HALO + ZTIME2 - ZTIME1
+!
+!-------------------------------------------------------------------------------
+!
+!*       23.    TEMPORAL SWAPPING
+!               -----------------
+!
+ZTIME1 = ZTIME2
+XTIME_BU_PROCESS = 0.
+!
+CALL ENDSTEP  ( XTSTEP,NRR,NSV,KTCOUNT,IMI,               &
+                CUVW_ADV_SCHEME,CTEMP_SCHEME,XRHODJ,      &
+                XRUS,XRVS,XRWS,XDRYMASSS,                 &
+                XRTHS,XRRS,XRTKES,XRSVS,                  &
+                XLSUS,XLSVS,XLSWS,                        &
+                XLSTHS,XLSRVS,XLSZWSS,                    &
+                XLBXUS,XLBXVS,XLBXWS,                     &
+                XLBXTHS,XLBXRS,XLBXTKES,XLBXSVS,          &
+                XLBYUS,XLBYVS,XLBYWS,                     &
+                XLBYTHS,XLBYRS,XLBYTKES,XLBYSVS,          &
+                XUM,XVM,XWM,XZWS,                         &
+                XUT,XVT,XWT,XPABST,XDRYMASST,             &
+                XTHT, XRT, XTHM, XRCM, XPABSM,XTKET, XSVT,&
+                XLSUM,XLSVM,XLSWM,                        &
+                XLSTHM,XLSRVM,XLSZWSM,                    &
+                XLBXUM,XLBXVM,XLBXWM,                     &
+                XLBXTHM,XLBXRM,XLBXTKEM,XLBXSVM,          &
+                XLBYUM,XLBYVM,XLBYWM,                     &
+                XLBYTHM,XLBYRM,XLBYTKEM,XLBYSVM           )
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_STEP_SWA = XT_STEP_SWA + ZTIME2 - ZTIME1 - XTIME_BU_PROCESS
+!
+!-------------------------------------------------------------------------------
+!
+!*       24.1    BALLOON and AIRCRAFT
+!               --------------------
+!
+ZTIME1 = ZTIME2
+!
+IF (LFLYER)                                                                   &
+  CALL AIRCRAFT_BALLOON(XTSTEP,                                               &
+                      TDTEXP, TDTMOD, TDTSEG, TDTCUR,                         &
+                      XXHAT, XYHAT, XZZ, XMAP, XLONORI, XLATORI,              &
+                      XUT, XVT, XWT, XPABST, XTHT, XRT, XSVT, XTKET, XTSRAD,  &
+                      XRHODREF,XCIT,PSEA=ZSEA(:,:))
+
+
+!-------------------------------------------------------------------------------
+!
+!*       24.2    STATION (observation diagnostic)
+!               --------------------------------
+!
+IF (LSTATION)                                                            &
+  CALL STATION_n(XTSTEP,                                                 &
+                 TDTEXP, TDTMOD, TDTSEG, TDTCUR,                         &
+                 XXHAT, XYHAT, XZZ,                                      &
+                 XUT, XVT, XWT, XTHT, XRT, XSVT, XTKET, XTSRAD, XPABST   )
+!
+!---------------------------------------------------------
+!
+!*       24.3    PROFILER (observation diagnostic)
+!               ---------------------------------
+!
+IF (LPROFILER)                                                           &
+  CALL PROFILER_n(XTSTEP,                                                &
+                  TDTEXP, TDTMOD, TDTSEG, TDTCUR,                        &
+                  XXHAT, XYHAT, XZZ,XRHODREF,                            &
+                  XUT, XVT, XWT, XTHT, XRT, XSVT, XTKET, XTSRAD, XPABST, &
+                  XAER, XCLDFR, XCIT)
+!
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_STEP_MISC = XT_STEP_MISC + ZTIME2 - ZTIME1
+!
+!-------------------------------------------------------------------------------
+!
+!*       24.4   deallocation of observation diagnostics
+!               ---------------------------------------
+!
+CALL END_DIAG_IN_RUN
+!
+!-------------------------------------------------------------------------------
+!
+!
+!*       25.    STORAGE OF BUDGET FIELDS
+!               ------------------------
+!
+ZTIME1 = ZTIME2
+!
+IF ( .NOT. LIO_NO_WRITE ) THEN
+  IF (NBUMOD==IMI .AND. CBUTYPE/='NONE') THEN
+    CALL ENDSTEP_BUDGET(TDIAFILE,KTCOUNT,TDTCUR,TDTMOD,XTSTEP,NSV)
+  END IF
+END IF
+!
+CALL SECOND_MNH2(ZTIME2)
+!
+XT_STEP_BUD = XT_STEP_BUD + ZTIME2 - ZTIME1 + XTIME_BU
+!
+!-------------------------------------------------------------------------------
+!
+!*       26.    FM FILE CLOSURE
+!               ---------------
+!
+IF (GCLOSE_OUT) THEN
+  GCLOSE_OUT=.FALSE.
+  CALL IO_File_close(TZBAKFILE)
+END IF
+!
+!-------------------------------------------------------------------------------
+!
+!*       27.    CURRENT TIME REFRESH
+!               --------------------
+!
+TDTCUR%TIME=TDTCUR%TIME + XTSTEP
+CALL DATETIME_CORRECTDATE(TDTCUR)
+!
+!-------------------------------------------------------------------------------
+!
+!*       28.    CPU ANALYSIS
+!               ------------
+!
+CALL SECOND_MNH2(ZTIME2)
+XT_START=XT_START+ZTIME2-ZEND
+!
+!
+IF ( KTCOUNT == NSTOP .AND. IMI==1) THEN
+  OEXIT=.TRUE.
+END IF
+!
+IF (OEXIT) THEN
+!
+  IF ( .NOT. LIO_NO_WRITE ) THEN
+    IF (LSERIES) CALL WRITE_SERIES_n(TDIAFILE)
+    CALL WRITE_AIRCRAFT_BALLOON(TDIAFILE)
+    CALL WRITE_STATION_n(TDIAFILE)
+    CALL WRITE_PROFILER_n(TDIAFILE)
+    CALL WRITE_LES_n(TDIAFILE,' ')
+    CALL WRITE_LES_n(TDIAFILE,'A')
+    CALL WRITE_LES_n(TDIAFILE,'E')
+    CALL WRITE_LES_n(TDIAFILE,'H')
+    CALL MENU_DIACHRO(TDIAFILE,'END')
+    CALL IO_File_close(TDIAFILE)
+  END IF
+  !
+  CALL IO_File_close(TINIFILE)
+  IF (CSURF=="EXTE") CALL IO_File_close(TINIFILEPGD)
+!
+!*       28.1   print statistics!
+!
+  ! Set File Timing OUTPUT
+  !
+  CALL SET_ILUOUT_TIMING(TLUOUT)
+  !
+  ! Compute global time
+  !
+  CALL TIME_STAT_ll(XT_START,ZTOT)
+  !
+  CALL TIME_HEADER_ll(IMI)
+  !
+  CALL TIME_STAT_ll(XT_1WAY,ZTOT,       ' ONE WAY','=')
+  CALL TIME_STAT_ll(XT_BOUND,ZTOT,      ' BOUNDARIES','=')
+  CALL TIME_STAT_ll(XT_STORE,ZTOT,      ' STORE-FIELDS','=')
+    CALL TIME_STAT_ll(TIMEZ%T_WRIT3D_SEND,ZTOT,    '   W3D_SEND ','-')
+    CALL TIME_STAT_ll(TIMEZ%T_WRIT3D_RECV,ZTOT,    '   W3D_RECV ','-')
+    CALL TIME_STAT_ll(TIMEZ%T_WRIT3D_WRIT,ZTOT,    '   W3D_WRIT ','-')
+    CALL TIME_STAT_ll(TIMEZ%T_WRIT3D_WAIT,ZTOT,    '   W3D_WAIT ','-')
+    CALL TIME_STAT_ll(TIMEZ%T_WRIT3D_ALL ,ZTOT,    '   W3D_ALL ','-')
+    CALL TIME_STAT_ll(TIMEZ%T_WRIT2D_GATH,ZTOT,    '   W2D_GATH ','-')
+    CALL TIME_STAT_ll(TIMEZ%T_WRIT2D_WRIT,ZTOT,    '   W2D_WRIT ','-')
+    CALL TIME_STAT_ll(TIMEZ%T_WRIT2D_ALL ,ZTOT,    '   W2D_ALL ','-')
+  CALL TIME_STAT_ll(XT_GUESS,ZTOT,      ' INITIAL_GUESS','=')
+  CALL TIME_STAT_ll(XT_2WAY,ZTOT,       ' TWO WAY','=')
+  CALL TIME_STAT_ll(XT_ADV,ZTOT,        ' ADVECTION MET','=')
+  CALL TIME_STAT_ll(XT_ADVUVW,ZTOT,     ' ADVECTION UVW','=')
+  CALL TIME_STAT_ll(XT_GRAV,ZTOT,       ' GRAVITY','=')
+  CALL TIME_STAT_ll(XT_FORCING,ZTOT,    ' FORCING','=')
+  CALL TIME_STAT_ll(XT_NUDGING,ZTOT,    ' NUDGING','=')
+  CALL TIME_STAT_ll(XT_SOURCES,ZTOT,    ' DYN_SOURCES','=')
+  CALL TIME_STAT_ll(XT_DIFF,ZTOT,       ' NUM_DIFF','=')
+  CALL TIME_STAT_ll(XT_RELAX,ZTOT,      ' RELAXATION','=')
+  !
+  CALL  TIMING_LEGEND() 
+  !
+  CALL TIME_STAT_ll(XT_PARAM,ZTOT,      ' PHYS_PARAM','=')
+    CALL TIME_STAT_ll(XT_RAD,ZTOT,      '   RAD       = '//CRAD  ,'-')
+    CALL TIME_STAT_ll(XT_SHADOWS,ZTOT,  '   SHADOWS'             ,'-')
+    CALL TIME_STAT_ll(XT_DCONV,ZTOT,    '   DEEP CONV = '//CDCONV,'-')
+    CALL TIME_STAT_ll(XT_GROUND,ZTOT,   '   GROUND'              ,'-')
+    CALL TIME_STAT_ll(XT_TURB,ZTOT,     '   TURB      = '//CTURB ,'-')
+    CALL TIME_STAT_ll(XT_MAFL,ZTOT,     '   MAFL      = '//CSCONV,'-')
+    CALL TIME_STAT_ll(XT_CHEM,ZTOT,     '   CHIMIE'              ,'-')
+  CALL  TIMING_LEGEND()
+  CALL TIME_STAT_ll(XT_COUPL,ZTOT,      ' SET_COUPLING','=')
+  CALL TIME_STAT_ll(XT_RAD_BOUND,ZTOT,  ' RAD_BOUND','=')
+  !
+  CALL  TIMING_LEGEND()
+  ! 
+  CALL TIME_STAT_ll(XT_PRESS,ZTOT,      ' PRESSURE ','=','F')
+  !JUAN Z_SPLITTING
+    CALL TIME_STAT_ll(TIMEZ%T_MAP_B_SX_YP2_ZP1,ZTOT,          '   REMAP       B=>FFTXZ'  ,'-','F')
+    CALL TIME_STAT_ll(TIMEZ%T_MAP_SX_YP2_ZP1_SXP2_Y_ZP1,ZTOT, '   REMAP   FFTXZ=>FFTYZ'  ,'-','F')
+    CALL TIME_STAT_ll(TIMEZ%T_MAP_SXP2_Y_ZP1_B,ZTOT,          '   REMAP   FTTYZ=>B'      ,'-','F')
+    CALL TIME_STAT_ll(TIMEZ%T_MAP_SXP2_Y_ZP1_SXP2_YP1_Z,ZTOT, '   REMAP   FFTYZ=>SUBZ'   ,'-','F')
+    CALL TIME_STAT_ll(TIMEZ%T_MAP_B_SXP2_Y_ZP1,ZTOT,          '   REMAP       B=>FFTYZ-1','-','F')
+    CALL TIME_STAT_ll(TIMEZ%T_MAP_SXP2_YP1_Z_SXP2_Y_ZP1,ZTOT, '   REMAP    SUBZ=>FFTYZ-1','-','F')
+    CALL TIME_STAT_ll(TIMEZ%T_MAP_SXP2_Y_ZP1_SX_YP2_ZP1,ZTOT, '   REMAP FFTYZ-1=>FFTXZ-1','-','F')
+    CALL TIME_STAT_ll(TIMEZ%T_MAP_SX_YP2_ZP1_B,ZTOT,          '   REMAP FFTXZ-1=>B     ' ,'-','F')
+  ! JUAN P1/P2
+  CALL TIME_STAT_ll(XT_CLOUD,ZTOT,      ' RESOLVED_CLOUD','=')
+  CALL TIME_STAT_ll(XT_ELEC,ZTOT,      ' RESOLVED_ELEC','=')
+  CALL TIME_STAT_ll(XT_HALO,ZTOT,       ' EXCHANGE_HALO','=')
+  CALL TIME_STAT_ll(XT_STEP_SWA,ZTOT,   ' ENDSTEP','=')
+  CALL TIME_STAT_ll(XT_STEP_BUD,ZTOT,   ' BUDGETS','=')
+  CALL TIME_STAT_ll(XT_SPECTRA,ZTOT,    ' LES','=')
+  CALL TIME_STAT_ll(XT_STEP_MISC,ZTOT,  ' MISCELLANEOUS','=')
+  !
+  ! sum of call subroutine
+  !
+  ZALL   = XT_1WAY + XT_BOUND   + XT_STORE   + XT_GUESS    +  XT_2WAY   + &
+           XT_ADV  + XT_FORCING + XT_NUDGING + XT_SOURCES  +  XT_DIFF   + &
+           XT_ADVUVW  + XT_GRAV +                                         &
+           XT_RELAX+ XT_PARAM   + XT_COUPL   + XT_RAD_BOUND+XT_PRESS    + &
+           XT_CLOUD+ XT_ELEC    + XT_HALO    + XT_SPECTRA + XT_STEP_SWA + &
+           XT_STEP_MISC+ XT_STEP_BUD
+  CALL TIME_STAT_ll(ZALL,ZTOT,          ' SUM(CALL)','=')
+  CALL  TIMING_SEPARATOR('=')
+  !
+  ! Gobale Stat
+  !
+  WRITE(ILUOUT,FMT=*)
+  WRITE(ILUOUT,FMT=*)
+  CALL  TIMING_LEGEND() 
+  !
+  ! MODELN all included
+  !
+  CALL  TIMING_SEPARATOR('+')
+  CALL  TIMING_SEPARATOR('+')  
+  WRITE(YMI,FMT="(I0)") IMI
+  CALL TIME_STAT_ll(XT_START,ZTOT,      ' MODEL'//YMI,'+')
+  CALL  TIMING_SEPARATOR('+')
+  CALL  TIMING_SEPARATOR('+')
+  CALL  TIMING_SEPARATOR('+')
+  !
+  ! Timing/ Steps
+  !
+  ZTIME_STEP     =  XT_START / REAL(KTCOUNT)
+  WRITE(YTCOUNT,FMT="(I0)") KTCOUNT
+  CALL TIME_STAT_ll(ZTIME_STEP,ZTOT,     ' SECOND/STEP='//YTCOUNT,'=')
+  !
+  ! Timing/Step/Points
+  !
+  IPOINTS = NIMAX_ll*NJMAX_ll*NKMAX
+  WRITE(YPOINTS,FMT="(I0)") IPOINTS
+  ZTIME_STEP_PTS =  ZTIME_STEP / REAL(IPOINTS) * 1e6
+  CALL TIME_STAT_ll(ZTIME_STEP_PTS,ZTOT_PT)
+  CALL TIME_STAT_ll(ZTIME_STEP_PTS,ZTOT_PT,  ' MICROSEC/STP/PT='//YPOINTS,'-')
+  !
+  CALL  TIMING_SEPARATOR('=')
+  !
+  !
+  !
+  CALL IO_File_close(TLUOUT)
+  IF (IMI==NMODEL) CALL IO_File_close(TLUOUT0)
+END IF
+
+!$acc end data
+
+END SUBROUTINE MODEL_n
diff --git a/src/ZSOLVER/pressurez.f90 b/src/ZSOLVER/pressurez.f90
new file mode 100644
index 0000000000000000000000000000000000000000..a637645ae4e9cd3df13f6ec93fbff5a551d4338b
--- /dev/null
+++ b/src/ZSOLVER/pressurez.f90
@@ -0,0 +1,928 @@
+!MNH_LIC Copyright 1994-2020 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+!###################
+MODULE MODI_PRESSUREZ
+!###################
+!
+INTERFACE
+!
+      SUBROUTINE PRESSUREZ(                                                &
+      HLBCX,HLBCY,HPRESOPT,KITR,OITRADJ,KTCOUNT,PRELAX,KMI,                &
+      PRHODJ,PDXX,PDYY,PDZZ,PDZX,PDZY,PDXHATM,PDYHATM,PRHOT,               &
+      PAF,PBF,PCF,PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,                           &
+      KRR,KRRL,KRRI,PDRYMASST,PREFMASS,PMASS_O_PHI0,                       &
+      PTHT,PRT,PRHODREF,PTHVREF,PRVREF,PEXNREF,PLINMASS,                   &
+      PRUS,PRVS,PRWS,PPABST,                                               &
+      PBFB,                                                                &
+      PBF_SXP2_YP1_Z,                                                      &
+      PAF_ZS,PBF_ZS,PCF_ZS,                                                &
+      PDXATH_ZS,PDYATH_ZS,PRHO_ZS,                                         &
+      A_K,B_K,C_K,D_K,                                                     &
+      PRESIDUAL) !JUAN  FULL ZSOLVER                                        
+!
+IMPLICIT NONE
+!
+CHARACTER (LEN=*), DIMENSION(:), INTENT(IN) :: HLBCX    ! x-direction LBC type
+CHARACTER (LEN=*), DIMENSION(:), INTENT(IN) :: HLBCY    ! y-direction LBC type
+!
+CHARACTER (LEN=5), INTENT(IN) :: HPRESOPT        ! choice of the pressure solver
+!
+INTEGER, INTENT(INOUT) :: KITR                   ! number of iterations for the
+                                                 ! pressure solver
+LOGICAL, INTENT(IN) :: OITRADJ                   ! switch to adjust or not KITR
+INTEGER, INTENT(IN) :: KTCOUNT                   ! counter value of the
+                                                 ! model temporal loop
+INTEGER, INTENT(IN) :: KMI                       ! Model index
+REAL, INTENT(IN)    :: PRELAX                    ! relaxation coefficient for
+                                                 ! the Richardson's method
+!
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHODJ     ! density of reference state
+                                                 ! * J
+!
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PDXX,PDYY,PDZZ,PDZX,PDZY ! metric coefficients
+!
+REAL, INTENT(IN) :: PDXHATM                     ! mean grid increment in the x
+                                                ! direction
+REAL, INTENT(IN) :: PDYHATM                     ! mean grid increment in the y
+                                                ! direction
+!
+REAL, DIMENSION (:), INTENT(IN) :: PRHOT         !  mean of XRHODJ on the plane x y
+                                                 !  localized at a mass level
+!
+REAL, DIMENSION(:), INTENT(IN)     :: PAF,PCF    ! vectors giving the nonvanishing
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PBF        ! elements of the tri-diag. y-slide
+                                                 ! matrix in the pressure eq.
+!
+                                                 ! arrays of sin or cos values
+                                                 ! for the FFT :
+REAL, DIMENSION(:), INTENT(IN) :: PTRIGSX        ! - along x
+REAL, DIMENSION(:), INTENT(IN) :: PTRIGSY        ! - along y
+!
+                                                 ! decomposition in prime
+                                                 ! numbers for the FFT:
+INTEGER, DIMENSION(19), INTENT(IN) :: KIFAXX      ! - along x
+INTEGER, DIMENSION(19), INTENT(IN) :: KIFAXY      ! - along y
+!
+!
+INTEGER,                  INTENT(IN)    :: KRR   ! Total number of water var.
+INTEGER,                  INTENT(IN)    :: KRRL  ! Number of liquid water var.
+INTEGER,                  INTENT(IN)    :: KRRI  ! Number of ice water var.
+!
+REAL,                     INTENT(IN)    :: PDRYMASST   ! Mass of dry air and of
+REAL,                     INTENT(IN)    :: PREFMASS    ! the ref. atmosphere
+REAL,                     INTENT(IN)    :: PMASS_O_PHI0 !    Mass / Phi0
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PTHT       ! Temperature and water
+REAL, DIMENSION(:,:,:,:), INTENT(IN)    :: PRT        !  variables at time t
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRHODREF    ! dry Density
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PTHVREF     ! Virtual Temperature
+                                                       ! of the reference state
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRVREF      ! mixing ratio of the
+                                                       ! reference state
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PEXNREF     ! Exner function
+                                                       ! of the reference state
+REAL,                     INTENT(IN)    :: PLINMASS    ! lineic mass through
+                                                       ! open boundaries
+!
+REAL,       INTENT(INOUT) :: PRUS(:,:,:)         ! source term along x
+REAL,       INTENT(INOUT) :: PRVS(:,:,:)         ! source term along y
+REAL,       INTENT(INOUT) :: PRWS(:,:,:)         ! source term along z
+!
+REAL,       INTENT(INOUT)   :: PPABST(:,:,:)        ! pressure(t)
+!
+!JUAN Z_SPLITING
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PBFB       ! elements of the tri-diag b-slide .
+                                                 ! matrix in the pressure eq.
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PBF_SXP2_YP1_Z       ! elements of the tri-diag. SXP2_YP1_Z-slide 
+                                                   ! matrix in the pressure eq.
+
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PAF_ZS,PBF_ZS,PCF_ZS
+REAL, DIMENSION(:,:)  , INTENT(IN) :: PDXATH_ZS,PDYATH_ZS
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHO_ZS
+REAL, DIMENSION(:)    , INTENT(IN) :: A_K,B_K,C_K,D_K
+
+REAL, OPTIONAL                     :: PRESIDUAL
+!JUAN Z_SPLITING
+END SUBROUTINE PRESSUREZ
+!
+END INTERFACE
+!
+END MODULE MODI_PRESSUREZ
+!     ######################################################################
+      SUBROUTINE PRESSUREZ(                                                &
+      HLBCX,HLBCY,HPRESOPT,KITR,OITRADJ,KTCOUNT,PRELAX,KMI,                &
+      PRHODJ,PDXX,PDYY,PDZZ,PDZX,PDZY,PDXHATM,PDYHATM,PRHOT,               &
+      PAF,PBF,PCF,PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,                           &
+      KRR,KRRL,KRRI,PDRYMASST,PREFMASS,PMASS_O_PHI0,                       &
+      PTHT,PRT,PRHODREF,PTHVREF,PRVREF,PEXNREF,PLINMASS,                   &
+      PRUS,PRVS,PRWS,PPABST,                                               &
+      PBFB,                                                                &
+      PBF_SXP2_YP1_Z,                                                      &
+      PAF_ZS,PBF_ZS,PCF_ZS,                                                &
+      PDXATH_ZS,PDYATH_ZS,PRHO_ZS,                                         &
+      A_K,B_K,C_K,D_K,                                                     &
+      PRESIDUAL) !JUAN FULL ZSOLVER
+!     ######################################################################
+!
+!!****  *PRESSUREZ * - solve the pressure equation and add the pressure term
+!!      to the sources
+!!
+!!    PURPOSE
+!!    -------
+!       The purpose of this routine is to solve the pressure equation:
+!     with either the conjugate gradient method or the Richardson's method.
+!     The pressure gradient is added to the sources in order
+!     to nullify the divergence of the momentum* Thetavref*(1+Rvref)
+!     at the time t+dt.
+!
+!!**  METHOD
+!!    ------
+!!     The divergence of the sources  ( RHS of the pressure equation ) is
+!!    computed. The pressure equation is then solved by either CG method,
+!!    either Richardson's method, or an exact method. Finally, the pressure
+!!    gradient is added to the sources RUS, RVS, RWS.
+!!    Finally, the absolute pressure is diagnozed from the total mass
+!!    included in the simulation domain.
+!!
+!!    EXTERNAL
+!!    --------
+!!      Subroutine MASS_LEAK : assures global non-divergence condition in the
+!!                             case of open boundaries
+!!      Subroutine FLAT_INV  : solve the pressure equation for the case
+!!                             without orography
+!!      Subroutine RICHARDSON: solve the pressure equation with the
+!!                             Richardson's method
+!!      Subroutine CONJGRAD  : solve the pressure equation with the Conjugate
+!!                             Gradient algorithm
+!!      Function   GX_M_U : compute the gradient along x
+!!      Function   GY_M_V : compute the gradient along y
+!!      Function   GZ_M_W : compute the gradient along z
+!!      Subroutine GDIV     : compute J times the divergence of 1/J times a vector
+!!      Function MXM: compute an average in the x direction for a variable
+!!      at a mass localization
+!!      Function MYM: compute an average in the y direction for a variable
+!!      at a mass localization
+!!      Function MZM: compute an average in the z direction for a variable
+!!      at a mass localization
+!!      Subroutine P_ABS   : compute the constant for PABS and therefore, the
+!!      absolute pressure function
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------
+!!      Module MODD_CONF: model configuration
+!!        LFLAT: logical switch for zero orography
+!!        L2D  : logical switch for two-dimensional configuration
+!!        LCARTESIAN : logical switch for cartesian geometry
+!!      Module MODD_PARAMETERS: declaration of parameter variables
+!!        JPHEXT, JPVEXT: define the number of marginal points out of the
+!!        physical domain along horizontal and vertical directions respectively
+!!      Module MODD_CST: physical constants
+!!        XCPD
+!!
+!!    REFERENCE
+!!    ---------
+!!      Book2 of documentation (subroutine PRESSURE) + Book1 (  )
+!!
+!!    AUTHOR
+!!    ------
+!!      P. Hereil and J. Stein       * Meteo France *
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original      05/07/94
+!!      Modification  03/01/95  (Lafore)  To add the absolute pressure diagnosis
+!!      Modification  31/01/95  (Stein)   Copy of the pressure function in the
+!!                                        2D case in the two outermost planes
+!!      Modification  16/02/95  (Mallet)  Add the call to MASS_LEAK
+!!      Modification  16/03/95  (Stein)  change the argument list of the
+!!                              gradient and remove R from the historical var.
+!!      Modification  30/06/95  (Stein)  Add a test not to compute the absolute
+!!                              pressure in the Boussinesq case
+!!                    16/10/95 (J. Stein) change the budget calls
+!!                    29/01/96 (J. Stein) call iterative resolution for
+!!                              non-cartessian geometry
+!!                    19/12/96 (J.-P. Pinty) update the budget calls
+!!                    14/01/97 (Stein,Lafore) New anelastic equations
+!!                    17/12/97 ( Stein )include the case of non-vanishing
+!!                              orography at the lbc
+!!                    26/03/98 (Stein,Jabouille) fix the value of the corner point
+!!                    15/06/98  (D.Lugato, R.Guivarch) Parallelisation
+!!                    25/08/99 (J.-P. Pinty) add CRESI option to CPRESOPT
+!!                    06/11/02 (V. Masson) update the budget calls
+!!                    24/08/2005 (J. escobar) BUG : remove IIE+1, IJE+1 out of bound
+!!                                references in parallel run
+!!                    08/2010 (V.Masson, C.Lac) Add UPDATE_HALO
+!!                    11/2010 (V.Masson, C.Lac) PPABST, must not be cyclic => add temp array
+!!                                             to save it before UPDATE_HALO
+!!                    07/2011 (J.escobar ) Bypass Bug with ifort11/12 on  HLBCX,HLBCY 
+!!                    09/2001 (J.escobar ) reintroduce correctly the GMAXLOC_ll call 
+!!                    11/2010 (V.Masson, C.Lac) PPABST must not be cyclic => add temp array
+!!                                             to save it before UPDATE_HALO
+!!                    02/2013 (J.Escobar ) add a test on abs(err) > 100.O for BG without controle of NAN
+!!                    2012    (V.Masson)  Modif update_halo due to CONTRAV
+!!                    2014    (C.Lac) correction for 3D run with LBOUSS=.TRUE.
+!!   J.Escobar : 15/09/2015 : WENO5 & JPHEXT <> 1 
+!!   J.escobar : check nb proc versus ZRESI & min(DIMX,DIMY)
+!!  Philippe Wautelet: 05/2016-04/2018: new data structures and calls for I/O
+!!  Philippe Wautelet: 22/01/2019: use standard FLUSH statement instead of non standard intrinsics
+!  P. Wautelet 10/04/2019: replace ABORT and STOP calls by Print_msg
+!  P. Wautelet 20/05/2019: add name argument to ADDnFIELD_ll + new ADD4DFIELD_ll subroutine
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+!
+USE MODD_ARGSLIST_ll, ONLY: LIST_ll
+USE MODD_BUDGET
+USE MODD_CST
+USE MODD_CONF
+USE MODD_DYN_n,       ONLY: LRES, XRES
+USE MODD_LUNIT_n,     ONLY: TLUOUT
+USE MODD_MPIF
+USE MODD_PARAMETERS
+use modd_precision,   only: MNHREAL_MPI
+USE MODD_REF,         ONLY: LBOUSS
+USE MODD_VAR_ll,      ONLY: NMNH_COMM_WORLD , NPROC
+!
+USE MODE_ll
+USE MODE_MPPDB
+USE MODE_MSG
+USE MODE_SUM2_ll,     ONLY: GMAXLOC_ll
+!
+USE MODI_BUDGET
+USE MODI_CONJGRAD
+USE MODI_ZCONJGRAD
+USE MODI_CONRESOL
+USE MODI_CONRESOLZ
+USE MODI_FLAT_INV
+USE MODI_ZSOLVER
+USE MODI_FLAT_INVZ
+USE MODI_GDIV
+USE MODI_GRADIENT_M
+USE MODI_MASS_LEAK
+USE MODI_P_ABS
+USE MODI_RICHARDSON
+USE MODI_SHUMAN
+#ifdef MNH_OPENACC
+USE MODI_SHUMAN_DEVICE
+USE MODI_GET_HALO
+#endif
+!
+#ifdef MNH_BITREP
+USE MODI_BITREP
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D
+#endif
+!
+IMPLICIT NONE
+!
+!*       0.1   declarations of arguments
+!
+  CHARACTER (LEN=*), DIMENSION(:), INTENT(IN) :: HLBCX    ! x-direction LBC type
+  CHARACTER (LEN=*), DIMENSION(:), INTENT(IN) :: HLBCY    ! y-direction LBC type
+!
+CHARACTER (LEN=5), INTENT(IN) :: HPRESOPT        ! choice of the pressure solver
+!
+INTEGER, INTENT(INOUT) :: KITR                   ! number of iterations for the
+                                                 ! pressure solver
+LOGICAL, INTENT(IN) :: OITRADJ                   ! switch to adjust or not KITR
+INTEGER, INTENT(IN) :: KTCOUNT                   ! counter value of the
+                                                 ! model temporal loop
+INTEGER, INTENT(IN) :: KMI                       ! Model index
+REAL, INTENT(IN)    :: PRELAX                    ! relaxation coefficient for
+                                                 ! the Richardson's method
+!
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHODJ     ! density of reference state
+                                                 ! * J
+!
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PDXX,PDYY,PDZZ,PDZX,PDZY ! metric coefficients
+!
+REAL, INTENT(IN) :: PDXHATM                     ! mean grid increment in the x
+                                                ! direction
+REAL, INTENT(IN) :: PDYHATM                     ! mean grid increment in the y
+                                                ! direction
+!
+REAL, DIMENSION (:), INTENT(IN) :: PRHOT         !  mean of XRHODJ on the plane x y
+                                                 !  localized at a mass level
+!
+REAL, DIMENSION(:), INTENT(IN)     :: PAF,PCF    ! vectors giving the nonvanishing
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PBF        ! elements of the tri-diag y-slide .
+                                                 ! matrix in the pressure eq.
+!
+                                                 ! arrays of sin or cos values
+                                                 ! for the FFT :
+REAL, DIMENSION(:), INTENT(IN) :: PTRIGSX        ! - along x
+REAL, DIMENSION(:), INTENT(IN) :: PTRIGSY        ! - along y
+!
+                                                 ! decomposition in prime
+                                                 ! numbers for the FFT:
+INTEGER, DIMENSION(19), INTENT(IN) :: KIFAXX      ! - along x
+INTEGER, DIMENSION(19), INTENT(IN) :: KIFAXY      ! - along y
+!
+INTEGER,                  INTENT(IN)    :: KRR   ! Total number of water var.
+INTEGER,                  INTENT(IN)    :: KRRL  ! Number of liquid water var.
+INTEGER,                  INTENT(IN)    :: KRRI  ! Number of ice water var.
+!
+REAL,                     INTENT(IN)    :: PDRYMASST   ! Mass of dry air and of
+REAL,                     INTENT(IN)    :: PREFMASS    ! the ref. atmosphere
+REAL,                     INTENT(IN)    :: PMASS_O_PHI0 !    Mass / Phi0
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PTHT       ! Temperature and water
+REAL, DIMENSION(:,:,:,:), INTENT(IN)    :: PRT        !  variables at time t
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRHODREF    ! dry Density
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PTHVREF     ! Virtual Temperature
+                                                       ! of the reference state
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRVREF      ! mixing ratio of the
+                                                       ! reference state
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PEXNREF     ! Exner function
+                                                       ! of the reference state
+REAL,                     INTENT(IN)    :: PLINMASS    ! lineic mass through
+                                                       ! open boundaries
+!
+REAL,       INTENT(INOUT) :: PRUS(:,:,:)         ! source term along x
+REAL,       INTENT(INOUT) :: PRVS(:,:,:)         ! source term along y
+REAL,       INTENT(INOUT) :: PRWS(:,:,:)         ! source term along z
+!
+REAL,       INTENT(INOUT)   :: PPABST(:,:,:)        ! pressure(t)
+!
+!JUAN Z_SPLITING
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PBFB       ! elements of the tri-diag b-slide .
+                                                 ! matrix in the pressure eq.
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PBF_SXP2_YP1_Z       ! elements of the tri-diag. SXP2_YP1_Z-slide 
+                                                   ! matrix in the pressure eq.
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PAF_ZS,PBF_ZS,PCF_ZS
+REAL, DIMENSION(:,:)  , INTENT(IN) :: PDXATH_ZS,PDYATH_ZS
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHO_ZS
+REAL, DIMENSION(:)    , INTENT(IN) :: A_K,B_K,C_K,D_K
+
+REAL, OPTIONAL                     :: PRESIDUAL
+!JUAN Z_SPLITING
+!
+!*       0.2   declarations of local variables
+!
+!                                                           Metric coefficients:
+!
+REAL, DIMENSION(SIZE(PPABST,1),SIZE(PPABST,2),SIZE(PPABST,3)) :: ZDV_SOURCE
+!                                                   ! divergence of the sources
+!
+INTEGER :: IIB          ! indice I for the first inner mass point along x
+INTEGER :: IIE          ! indice I for the last inner mass point along x
+INTEGER :: IJB          ! indice J for the first inner mass point along y
+INTEGER :: IJE          ! indice J for the last inner mass point along y
+INTEGER :: IKB          ! indice K for the first inner mass point along z
+INTEGER :: IKE          ! indice K for the last inner mass point along z
+INTEGER :: ILUOUT       ! Logical unit of output listing
+INTEGER :: IRESP        ! Return code of FM routines
+!
+REAL, DIMENSION(SIZE(PPABST,1),SIZE(PPABST,2),SIZE(PPABST,3)) :: ZTHETAV, &
+                        ! virtual potential temperature
+                                                                 ZPHIT
+                        ! MAE + DUR => Exner function perturbation
+                        ! LHE       => Exner function perturbation * CPD * THVREF
+!
+REAL            :: ZRV_OV_RD !  XRV / XRD
+REAL                  :: ZMAXVAL, ZMAXRES, ZMAX,ZMAX_ll ! for print
+INTEGER, DIMENSION(3) :: IMAXLOC ! purpose
+INTEGER         :: JWATER          ! loop index on water species
+INTEGER         :: IIU,IJU,IKU     ! array sizes in I,J,K
+INTEGER         :: JK              ! loop index on the vertical levels
+INTEGER         :: JI,JJ
+!
+REAL, DIMENSION(SIZE(PDXX,1),SIZE(PDXX,3)) :: ZPABS_S ! local pressure on southern side
+REAL, DIMENSION(SIZE(PDXX,1),SIZE(PDXX,3)) :: ZPABS_N ! local pressure on northern side
+REAL, DIMENSION(SIZE(PDYY,2),SIZE(PDXX,3)) :: ZPABS_E ! local pressure on eastern side
+REAL, DIMENSION(SIZE(PDYY,2),SIZE(PDXX,3)) :: ZPABS_W ! local pressure on western side
+INTEGER :: IINFO_ll,KINFO
+TYPE(LIST_ll), POINTER :: TZFIELDS_ll, TZFIELDS2_ll  ! list of fields to exchange
+!
+INTEGER :: IIB_I,IIE_I,IJB_I,IJE_I
+INTEGER :: IIMAX_ll,IJMAX_ll
+!
+REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZPRHODJ,ZMXM_PRHODJ,ZMZM_PRHODJ,ZGZ_M_W
+INTEGER :: IZPRHODJ,IZMXM_PRHODJ,IZMZM_PRHODJ,IZGZ_M_W
+REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZMYM_PRHODJ
+INTEGER :: IZMYM_PRHODJ
+!
+!
+LOGICAL :: GWEST,GEAST,GSOUTH,GNORTH
+LOGICAL :: GSOUTH2D,GNORTH2D,GPRVREF0
+!
+!------------------------------------------------------------------------------
+!-------------------------------------------------------------------------------
+!
+!*       1.      PRELIMINARIES
+!                -------------
+!
+ILUOUT = TLUOUT%NLU
+!
+CALL GET_GLOBALDIMS_ll (IIMAX_ll,IJMAX_ll)
+IF ( ( MIN(IIMAX_ll,IJMAX_ll) < NPROC  ) .AND. ( HPRESOPT /= 'ZRESI' ) .AND. ( HPRESOPT /= 'ZSOLV' )) THEN
+   WRITE(UNIT=ILUOUT,FMT=*) 'ERROR IN PRESSUREZ:: YOU WANT TO USE TO MANY PROCESSOR WITHOUT CPRESOPT="ZRESI/ZSOLV" '
+   WRITE(UNIT=ILUOUT,FMT=*) 'MIN(IIMAX_ll,IJMAX_ll)=',MIN(IIMAX_ll,IJMAX_ll),' < NPROC =', NPROC
+   WRITE(UNIT=ILUOUT,FMT=*) 'YOU HAVE TO SET CPRESOPT="ZRESI => JOB ABORTED '
+   CALL PRINT_MSG(NVERB_FATAL,'GEN','PRESSUREZ','')
+ENDIF
+CALL GET_PHYSICAL_ll(IIB,IJB,IIE,IJE)
+CALL GET_DIM_EXT_ll('B',IIU,IJU)
+!
+IKB= 1+JPVEXT
+IKU= SIZE(PPABST,3)
+IKE= IKU - JPVEXT
+!
+GWEST  = ( HLBCX(1) /= 'CYCL' .AND. LWEST_ll() )
+GEAST  = ( HLBCX(2) /= 'CYCL' .AND. LEAST_ll() )
+GSOUTH = ( .NOT. L2D .AND. HLBCY(1) /= 'CYCL' .AND. LSOUTH_ll() )
+GNORTH = ( .NOT. L2D .AND. HLBCY(2) /= 'CYCL' .AND. LNORTH_ll() )
+GSOUTH2D = ( L2D .AND. LSOUTH_ll() )
+GNORTH2D = ( L2D .AND. LNORTH_ll() )
+!
+GPRVREF0 =  ( SIZE(PRVREF,1) == 0 )
+!
+IZPRHODJ     = MNH_ALLOCATE_ZT3D( ZPRHODJ,IIU,IJU,IKU  )
+IZMXM_PRHODJ = MNH_ALLOCATE_ZT3D( ZMXM_PRHODJ,IIU,IJU,IKU  )
+IZMZM_PRHODJ = MNH_ALLOCATE_ZT3D( ZMZM_PRHODJ,IIU,IJU,IKU  )
+IZGZ_M_W     = MNH_ALLOCATE_ZT3D( ZGZ_M_W,IIU,IJU,IKU  )
+IZMYM_PRHODJ = MNH_ALLOCATE_ZT3D( ZMYM_PRHODJ,IIU,IJU,IKU  )
+!
+!$acc kernels
+ZPABS_S(:,:) = 0.
+ZPABS_N(:,:) = 0.
+ZPABS_E(:,:) = 0.
+ZPABS_W(:,:) = 0.
+!$acc end kernels
+!
+!
+!-------------------------------------------------------------------------------
+!
+!*       3.    COMPUTE THE LINEIC MASS
+!              -----------------------
+!
+IF ( ANY(HLBCX(:)=='OPEN') .OR. ANY(HLBCY(:)=='OPEN') ) THEN                     
+  CALL MASS_LEAK(PDXX,PDYY,HLBCX,HLBCY,PLINMASS,PRHODJ,PRUS,PRVS)
+END IF
+!
+!-------------------------------------------------------------------------------
+!
+!*       4.    COMPUTE THE FORCING TERM FOR THE PRESSURE EQUATION
+!              --------------------------------------------------
+!
+!
+CALL MPPDB_CHECK3D(PRUS,"pressurez 4-before update_halo_ll::PRUS",PRECISION)
+CALL MPPDB_CHECK3D(PRVS,"pressurez 4-before update_halo_ll::PRVS",PRECISION)
+CALL MPPDB_CHECK3D(PRWS,"pressurez 4-before update_halo_ll::PRWS",PRECISION)
+#ifndef MNH_OPENACC
+NULLIFY(TZFIELDS_ll)
+CALL ADD3DFIELD_ll( TZFIELDS_ll, PRUS, 'PRESSUREZ::PRUS' )
+CALL ADD3DFIELD_ll( TZFIELDS_ll, PRVS, 'PRESSUREZ::PRVS' )
+CALL ADD3DFIELD_ll( TZFIELDS_ll, PRWS, 'PRESSUREZ::PRWS' )
+CALL UPDATE_HALO_ll(TZFIELDS_ll,IINFO_ll)
+CALL CLEANLIST_ll(TZFIELDS_ll)
+#else
+CALL GET_HALO_D(PRUS,HNAME='PRESSUREZ::PRUS' )
+CALL GET_HALO_D(PRVS,HNAME='PRESSUREZ::PRVS' )
+CALL GET_HALO_D(PRWS,HNAME='PRESSUREZ::PRWS' )
+#endif
+CALL MPPDB_CHECK3D(PRUS,"pressurez 4-after update_halo_ll::PRUS",PRECISION)
+CALL MPPDB_CHECK3D(PRVS,"pressurez 4-after update_halo_ll::PRVS",PRECISION)
+CALL MPPDB_CHECK3D(PRWS,"pressurez 4-after update_halo_ll::PRWS",PRECISION)
+!
+CALL GDIV(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRUS,PRVS,PRWS,ZDV_SOURCE)
+!
+! The non-homogenous Neuman problem is transformed in an homogenous Neuman
+! problem in the non-periodic cases
+IF ( GWEST ) THEN
+   !$acc kernels async
+   ZDV_SOURCE(IIB-1,:,:) = 0.
+   !$acc end kernels
+END IF
+IF ( GEAST ) THEN
+   !$acc kernels async
+   ZDV_SOURCE(IIE+1,:,:) = 0.
+   !$acc end kernels
+END IF
+IF ( GSOUTH ) THEN
+   !$acc kernels async
+   ZDV_SOURCE(:,IJB-1,:) = 0.
+   !$acc end kernels
+END IF
+IF ( GNORTH ) THEN
+   !$acc kernels async
+   ZDV_SOURCE(:,IJE+1,:) = 0.
+   !$acc end kernels
+END IF
+!$acc wait
+!
+!-------------------------------------------------------------------------------
+!
+!*       5.    SOLVE THE PRESSURE EQUATION
+!              ---------------------------
+!
+!
+!*       5.1   Compute the virtual theta and the pressure perturbation
+!              -------------------------------------------------------
+!
+IF(CEQNSYS=='MAE' .OR. CEQNSYS=='DUR') THEN
+  !$acc kernels 
+  IF(KRR > 0) THEN
+  !
+  !   compute the ratio : 1 + total water mass / dry air mass
+    ZRV_OV_RD = XRV / XRD
+    ZTHETAV(:,:,:) = 1. + PRT(:,:,:,1)
+    DO JWATER = 2 , 1+KRRL+KRRI
+      ZTHETAV(:,:,:) = ZTHETAV(:,:,:) + PRT(:,:,:,JWATER)
+    END DO
+  !   compute the virtual potential temperature when water is present in any
+  !   form
+    ZTHETAV(:,:,:) = PTHT(:,:,:) * (1. + PRT(:,:,:,1) * ZRV_OV_RD) / ZTHETAV(:,:,:)
+  ELSE
+  !   compute the virtual potential temperature when water is absent
+    ZTHETAV(:,:,:) = PTHT(:,:,:)
+  END IF
+  !$acc end kernels
+  !
+#ifndef MNH_OPENACC   
+  ZPHIT(:,:,:)=(PPABST(:,:,:)/XP00)**(XRD/XCPD)-PEXNREF(:,:,:)
+#else
+  !$acc kernels
+  ZPHIT(:,:,:)=BR_POW((PPABST(:,:,:)/XP00),(XRD/XCPD))-PEXNREF(:,:,:)
+  !$acc end kernels
+#endif  
+  !
+ELSEIF(CEQNSYS=='LHE') THEN
+  ZPHIT(:,:,:)= ((PPABST(:,:,:)/XP00)**(XRD/XCPD)-PEXNREF(:,:,:))   &
+               * XCPD * PTHVREF(:,:,:)
+  !
+END IF
+!
+IF(CEQNSYS=='LHE'.AND. LFLAT .AND. LCARTESIAN) THEN
+   ! flat cartesian LHE case -> exact solution
+ IF ( HPRESOPT /= "ZRESI" ) THEN
+  CALL FLAT_INV(HLBCX,HLBCY,PDXHATM,PDYHATM,PRHOT,PAF,PBF,PCF,         &
+               PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,ZDV_SOURCE,ZPHIT)
+ ELSE
+  CALL FLAT_INVZ(HLBCX,HLBCY,PDXHATM,PDYHATM,PRHOT,PAF,PBF,PCF,         &
+               PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,ZDV_SOURCE,ZPHIT,& 
+               PBFB,&
+               PBF_SXP2_YP1_Z)
+ ENDIF
+ELSE
+  SELECT CASE(HPRESOPT)
+  CASE('RICHA')     ! Richardson's method
+!
+    CALL RICHARDSON(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,ZTHETAV,      &
+    PDXHATM,PDYHATM,PRHOT,PAF,PBF,PCF,PTRIGSX,PTRIGSY,                        &
+    KIFAXX,KIFAXY,KITR,KTCOUNT,PRELAX,ZDV_SOURCE,ZPHIT)
+!
+   CASE('CGRAD')     ! Conjugate Gradient method
+     CALL CONJGRAD(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,ZTHETAV,       &
+     PDXHATM,PDYHATM,PRHOT,PAF,PBF,PCF,PTRIGSX,PTRIGSY,                       &
+     KIFAXX,KIFAXY,KITR,ZDV_SOURCE,ZPHIT)
+  CASE('ZGRAD')     ! Conjugate Gradient method
+     CALL ZCONJGRAD(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,ZTHETAV,       &
+     PDXHATM,PDYHATM,PRHOT,PAF,PBF,PCF,PTRIGSX,PTRIGSY,                       &
+     KIFAXX,KIFAXY,KITR,ZDV_SOURCE,ZPHIT)
+!
+  CASE('CRESI')     ! Conjugate Residual method
+    CALL CONRESOL(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,ZTHETAV,       &
+    PDXHATM,PDYHATM,PRHOT,PAF,PBF,PCF,PTRIGSX,PTRIGSY,                       &
+    KIFAXX,KIFAXY,KITR,ZDV_SOURCE,ZPHIT)
+!
+  CASE('ZSOLV')     ! Conjugate Residual method
+    CALL ZSOLVER(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,ZTHETAV,       &
+    PDXHATM,PDYHATM,PRHOT,PAF,PBF,PCF,PTRIGSX,PTRIGSY,                      &
+    KIFAXX,KIFAXY,KITR,ZDV_SOURCE,ZPHIT,                                    &
+    PAF_ZS,PBF_ZS,PCF_ZS,                                                   &
+    PDXATH_ZS,PDYATH_ZS,PRHO_ZS,PBFB,                                       &
+    A_K,B_K,C_K,D_K)
+!
+  CASE('ZRESI')     ! Conjugate Residual method
+    CALL CONRESOLZ(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,ZTHETAV,       &
+    PDXHATM,PDYHATM,PRHOT,PAF,PBF,PCF,PTRIGSX,PTRIGSY,                       &
+    KIFAXX,KIFAXY,KITR,ZDV_SOURCE,ZPHIT,                                     &
+    PBFB,&
+    PBF_SXP2_YP1_Z) !JUAN Z_SPLITING
+  END SELECT
+END IF
+!
+!-------------------------------------------------------------------------------
+!
+!*       6.    ADD THE PRESSURE GRADIENT TO THE SOURCES
+!              ----------------------------------------
+!
+IF ( GWEST ) THEN
+   !$acc kernels async
+   ZPHIT(IIB-1,:,IKB-1) = ZPHIT(IIB,:,IKB-1)
+   !$acc end kernels
+END IF
+IF ( GEAST ) THEN
+   !$acc kernels async
+   ZPHIT(IIE+1,:,IKB-1) = ZPHIT(IIE,:,IKB-1)
+   !$acc end kernels
+END IF
+IF ( GSOUTH ) THEN
+   !$acc kernels async
+   ZPHIT(:,IJB-1,IKB-1) = ZPHIT(:,IJB,IKB-1)
+   !$acc end kernels
+END IF
+IF ( GNORTH ) THEN
+   !$acc kernels async
+   ZPHIT(:,IJE+1,IKB-1) = ZPHIT(:,IJE,IKB-1)
+   !$acc end kernels
+END IF
+IF ( GSOUTH2D ) THEN
+   !$acc kernels async
+   ZPHIT(:,IJB-1,:) = ZPHIT(:,IJB,:)
+   !$acc end kernels
+END IF
+IF ( GNORTH2D ) THEN
+   !$acc kernels async
+   ZPHIT(:,IJE+1,:) = ZPHIT(:,IJB,:)
+   !$acc end kernels
+END IF
+!$acc wait
+!
+#ifndef MNH_OPENACC
+ZDV_SOURCE = GX_M_U(1,IKU,1,ZPHIT,PDXX,PDZZ,PDZX)
+#else
+CALL GX_M_U_DEVICE(1,IKU,1,ZPHIT,PDXX,PDZZ,PDZX,ZDV_SOURCE)
+#endif
+!
+IF ( GWEST ) THEN
+!!!!!!!!!!!!!!!!  FUJI  compiler directive !!!!!!!!!!
+!!!!!!!!!!!!!!!!  FUJI  compiler directive !!!!!!!!!!
+   !$acc kernels
+    DO JK=2,IKU-1
+      ZDV_SOURCE(IIB,:,JK)=                                                    &
+       (ZPHIT(IIB,:,JK) - ZPHIT(IIB-1,:,JK) - 0.5 * (                              &
+        PDZX(IIB,:,JK)   * (ZPHIT(IIB,:,JK)-ZPHIT(IIB,:,JK-1)) / PDZZ(IIB,:,JK)      &
+       +PDZX(IIB,:,JK+1) * (ZPHIT(IIB,:,JK+1)-ZPHIT(IIB,:,JK)) / PDZZ(IIB,:,JK+1)    &
+                                              )                              &
+       ) / PDXX(IIB,:,JK)
+   END DO
+   !$acc end kernels
+ENDIF
+  !
+IF( GEAST ) THEN
+   !$acc kernels
+    DO JK=2,IKU-1
+      ZDV_SOURCE(IIE+1,:,JK)=                                                   &
+        (ZPHIT(IIE+1,:,JK) - ZPHIT(IIE+1-1,:,JK) - 0.5 * (                        &
+         PDZX(IIE+1,:,JK)   * (ZPHIT(IIE+1-1,:,JK)-ZPHIT(IIE+1-1,:,JK-1))           &
+                          / PDZZ(IIE+1-1,:,JK)                                  &
+        +PDZX(IIE+1,:,JK+1) * (ZPHIT(IIE+1-1,:,JK+1)-ZPHIT(IIE+1-1,:,JK))           &
+                          / PDZZ(IIE+1-1,:,JK+1)                                &
+                                                     )                        &
+        ) / PDXX(IIE+1,:,JK)
+   END DO
+   !$acc end kernels
+END IF
+!
+CALL MPPDB_CHECK3DM("before MXM PRESSUREZ :PRU/V/WS",PRECISION,PRUS,PRVS,PRWS)
+IF(CEQNSYS=='MAE' .OR. CEQNSYS=='DUR') THEN  
+!!$  PRUS = PRUS - MXM(PRHODJ * XCPD * ZTHETAV) * ZDV_SOURCE
+!!$  PRWS = PRWS - MZM(PRHODJ * XCPD * ZTHETAV) * GZ_M_W(1,IKU,1,ZPHIT,PDZZ)
+  !$acc kernels 
+  ZPRHODJ = PRHODJ * XCPD * ZTHETAV
+  !$acc end kernels 
+  CALL MXM_DEVICE(ZPRHODJ, ZMXM_PRHODJ)
+  CALL MZM_DEVICE(ZPRHODJ, ZMZM_PRHODJ)
+  CALL GZ_M_W_DEVICE(1,IKU,1,ZPHIT,PDZZ,ZGZ_M_W)
+  !$acc kernels
+  PRUS = PRUS - ZMXM_PRHODJ * ZDV_SOURCE
+  PRWS = PRWS - ZMZM_PRHODJ * ZGZ_M_W
+  !$acc end kernels
+ELSEIF(CEQNSYS=='LHE') THEN
+  PRUS = PRUS - MXM(PRHODJ) * ZDV_SOURCE
+  PRWS = PRWS - MZM(PRHODJ) * GZ_M_W(1,IKU,1,ZPHIT,PDZZ)
+END IF
+!
+IF(.NOT. L2D) THEN
+  !
+#ifndef MNH_OPENACC    
+   ZDV_SOURCE = GY_M_V(1,IKU,1,ZPHIT,PDYY,PDZZ,PDZY)
+#else
+   CALL GY_M_V_DEVICE(1,IKU,1,ZPHIT,PDYY,PDZZ,PDZY,ZDV_SOURCE)
+#endif
+!
+   IF ( GSOUTH ) THEN
+!!!!!!!!!!!!!!!!  FUJI  compiler directive !!!!!!!!!!
+!!!!!!!!!!!!!!!!  FUJI  compiler directive !!!!!!!!!!
+      !$acc kernels async
+      DO JK=2,IKU-1
+        ZDV_SOURCE(:,IJB,JK)=                                                  &
+         (ZPHIT(:,IJB,JK) - ZPHIT(:,IJB-1,JK) - 0.5 * (                            &
+          PDZY(:,IJB,JK)   * (ZPHIT(:,IJB,JK)-ZPHIT(:,IJB,JK-1)) / PDZZ(:,IJB,JK)    &
+         +PDZY(:,IJB,JK+1) * (ZPHIT(:,IJB,JK+1)-ZPHIT(:,IJB,JK)) / PDZZ(:,IJB,JK+1)  &
+                                                )                            &
+         ) / PDYY(:,IJB,JK)
+     END DO
+     !$acc end kernels
+    END IF
+    !
+    IF ( GNORTH ) THEN
+      !$acc kernels async
+      DO JK=2,IKU-1
+        ZDV_SOURCE(:,IJE+1,JK)=                                                &
+         (ZPHIT(:,IJE+1,JK) - ZPHIT(:,IJE+1-1,JK) - 0.5 * (                      &
+          PDZY(:,IJE+1,JK)   * (ZPHIT(:,IJE+1-1,JK)-ZPHIT(:,IJE+1-1,JK-1))         &
+                           / PDZZ(:,IJE+1-1,JK)                                &
+         +PDZY(:,IJE+1,JK+1) * (ZPHIT(:,IJE+1-1,JK+1)-ZPHIT(:,IJE+1-1,JK))         &
+                           / PDZZ(:,IJE+1-1,JK+1)                              &
+                                                      )                      &
+        ) / PDYY(:,IJE+1,JK)
+     END DO
+     !$acc end kernels
+  END IF
+!$acc wait  
+!
+  CALL MPPDB_CHECK3DM("before MYM PRESSUREZ :PRU/V/WS",PRECISION,PRUS,PRVS,PRWS)
+  IF(CEQNSYS=='MAE' .OR. CEQNSYS=='DUR') THEN
+!!$     PRVS = PRVS - MYM(PRHODJ * XCPD * ZTHETAV) * ZDV_SOURCE
+     CALL MYM_DEVICE(ZPRHODJ,ZMYM_PRHODJ)
+     !$acc kernels
+     PRVS = PRVS - ZMYM_PRHODJ * ZDV_SOURCE
+     !$acc end kernels
+  ELSEIF(CEQNSYS=='LHE') THEN
+    PRVS = PRVS - MYM(PRHODJ) * ZDV_SOURCE
+  END IF
+END IF
+!
+!! same boundary conditions as in gdiv ... !! (provisory coding)
+!! (necessary when NVERB=1)
+!!
+    !$acc kernels
+    PRUS(:,:,IKB-1)=PRUS(:,:,IKB)
+    PRUS(:,:,IKE+1)=PRUS(:,:,IKE)
+    PRVS(:,:,IKB-1)=PRVS(:,:,IKB)
+    PRVS(:,:,IKE+1)=PRVS(:,:,IKE)
+    !$acc end kernels
+!
+#ifndef MNH_OPENACC    
+NULLIFY(TZFIELDS2_ll)
+CALL ADD3DFIELD_ll( TZFIELDS2_ll, PRUS, 'PRESSUREZ::PRUS' )
+CALL ADD3DFIELD_ll( TZFIELDS2_ll, PRVS, 'PRESSUREZ::PRVS' )
+CALL ADD3DFIELD_ll( TZFIELDS2_ll, PRWS, 'PRESSUREZ::PRWS' )
+CALL UPDATE_HALO_ll(TZFIELDS2_ll,IINFO_ll)
+CALL CLEANLIST_ll(TZFIELDS2_ll)
+#else
+CALL GET_HALO_D(PRUS,HNAME='PRESSUREZ::PRUS' )
+CALL GET_HALO_D(PRVS,HNAME='PRESSUREZ::PRVS' )
+CALL GET_HALO_D(PRWS,HNAME='PRESSUREZ::PRWS' )
+#endif
+!
+!  compute the residual divergence
+CALL GDIV(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRUS,PRVS,PRWS,ZDV_SOURCE)
+!
+IF ( CEQNSYS=='DUR' ) THEN
+   IF ( GPRVREF0 ) THEN
+    !$acc kernels  
+    ZDV_SOURCE=ZDV_SOURCE/PRHODJ/XTH00*PRHODREF*PTHVREF
+    !$acc end kernels  
+ ELSE
+    !$acc kernels
+    ZDV_SOURCE=ZDV_SOURCE/PRHODJ/XTH00*PRHODREF*PTHVREF*(1.+PRVREF)
+    !$acc end kernels
+  END IF
+ELSEIF( CEQNSYS=='MAE' .OR. CEQNSYS=='LHE' ) THEN
+  ZDV_SOURCE=ZDV_SOURCE/PRHODJ*PRHODREF
+END IF
+!
+ZMAXVAL=MAX_ll(ABS(ZDV_SOURCE),IINFO_ll)
+!JUANZ
+IF (PRESENT(PRESIDUAL)) PRESIDUAL = ZMAXVAL
+!JUANZ
+IMAXLOC=GMAXLOC_ll( ABS(ZDV_SOURCE) )
+!
+WRITE(ILUOUT,*) 'residual divergence / 2 DT', ZMAXVAL,     &
+                ' located at ',   IMAXLOC
+FLUSH(unit=ILUOUT)
+IF (ABS(ZMAXVAL) .GT. 100.0 ) THEN
+   call Print_msg( NVERB_FATAL, 'GEN', 'PRESSUREZ', 'something wrong with pressure: abs(residual) > 100.0' )
+END IF
+! number of iterations adjusted
+IF (LRES) THEN
+   ZMAXRES = XRES
+ELSEIF (LFLAT .AND. LCARTESIAN) THEN
+  ZMAXRES = XRES_FLAT_CART
+ELSE
+  ZMAXRES = XRES_OTHER
+END IF
+!
+IF (OITRADJ) THEN
+  IF (ZMAXVAL>10.*ZMAXRES) THEN
+    KITR=KITR+2
+    WRITE(ILUOUT,*) 'NITR adjusted to ', KITR
+  ELSE IF (ZMAXVAL<ZMAXRES) THEN
+    KITR=MAX(KITR-1,1)
+    WRITE(ILUOUT,*) 'NITR adjusted to ', KITR
+  ENDIF
+ENDIF
+!
+!*       7.    STORAGE OF THE FIELDS IN BUDGET ARRAYS
+!              --------------------------------------
+!
+IF (LBUDGET_U) CALL BUDGET (PRUS,1,'PRES_BU_RU')
+IF (LBUDGET_V) CALL BUDGET (PRVS,2,'PRES_BU_RV')
+IF (LBUDGET_W) CALL BUDGET (PRWS,3,'PRES_BU_RW')
+!
+!-------------------------------------------------------------------------------
+!
+!*       8.    ABSOLUTE PRESSURE COMPUTATION
+!              -----------------------------
+!
+ZMAX = MAXVAL(ABS ( PRHODREF(:,:,IKB)-PRHODREF(:,:,IKE)) )
+CALL MPI_ALLREDUCE(ZMAX, ZMAX_ll, 1, MNHREAL_MPI, MPI_MAX,  &
+                   NMNH_COMM_WORLD, KINFO)
+!IF (      ABS(PRHODREF(IIB,IJB,IKB)-PRHODREF(IIB,IJB,IKE)) > 1.E-12 &
+!  .AND. KTCOUNT >0 ) THEN
+IF ((ZMAX_ll > 1.E-12) .AND. KTCOUNT >0 ) THEN 
+!IF (  KTCOUNT >0 .AND. .NOT.LBOUSS ) THEN
+  CALL P_ABS   ( KRR, KRRL, KRRI, PDRYMASST, PREFMASS, PMASS_O_PHI0, &
+                 PTHT, PRT, PRHODJ, PRHODREF, ZTHETAV, PTHVREF,      &
+                 PRVREF, PEXNREF,  ZPHIT                             )
+!
+  IF(CEQNSYS=='MAE' .OR. CEQNSYS=='DUR') THEN
+#ifndef MNH_OPENACC 
+     PPABST(:,:,:)=XP00*(ZPHIT+PEXNREF)**(XCPD/XRD)
+#else
+     !$acc kernels
+     PPABST(:,:,:)=XP00*BR_POW((ZPHIT+PEXNREF),(XCPD/XRD))
+     !$acc end kernels
+#endif
+  ELSEIF(CEQNSYS=='LHE') THEN
+    PPABST(:,:,:)=XP00*(ZPHIT/(XCPD*PTHVREF)+PEXNREF)**(XCPD/XRD)
+  ENDIF
+!
+  IF( GWEST ) THEN
+     !$acc kernels async
+     ZPABS_W(:,:)= PPABST(IIB,:,:)
+     !$acc end kernels
+  END IF
+!
+  IF ( GEAST ) THEN
+     !$acc kernels async
+     ZPABS_E(:,:)= PPABST(IIE+1,:,:)
+     !$acc end kernels
+  END IF
+!
+  IF( GSOUTH ) THEN
+     !$acc kernels async
+     ZPABS_S(:,:)= PPABST(:,IJB,:)
+     !$acc end kernels
+  END IF
+!
+  IF ( GNORTH ) THEN
+     !$acc kernels async
+     ZPABS_N(:,:)= PPABST(:,IJE+1,:)
+     !$acc end kernels
+  END IF
+  !
+  !$acc wait
+  !
+#ifndef MNH_OPENACC  
+  CALL ADD3DFIELD_ll( TZFIELDS_ll, PPABST, 'PRESSUREZ::PPABST' )
+  CALL UPDATE_HALO_ll(TZFIELDS_ll,IINFO_ll)
+  CALL CLEANLIST_ll(TZFIELDS_ll)
+#else
+  CALL GET_HALO_D( PPABST,HNAME='PRESSUREZ::PPABST' )
+#endif
+  
+!
+  IF( GWEST ) THEN
+     !$acc kernels async
+     PPABST(IIB,:,:) = ZPABS_W(:,:)
+     !$acc end kernels
+  END IF
+!
+  IF ( GEAST ) THEN
+     !$acc kernels async
+     PPABST(IIE+1,:,:) = ZPABS_E(:,:)
+     !$acc end kernels
+  END IF
+!
+  IF( GSOUTH ) THEN
+     !$acc kernels async
+     PPABST(:,IJB,:) = ZPABS_S(:,:)
+     !$acc end kernels
+  END IF
+!
+  IF ( GNORTH ) THEN
+     !$acc kernels async
+     PPABST(:,IJE+1,:) = ZPABS_N(:,:)
+     !$acc end kernels
+  END IF
+!
+!$acc wait  
+!
+END IF
+!
+#ifdef MNH_OPENACC
+CALL MNH_REL_ZT3D ( IZPRHODJ,IZMXM_PRHODJ,IZMZM_PRHODJ,IZGZ_M_W,IZMYM_PRHODJ )
+#endif
+!-------------------------------------------------------------------------------
+!
+END SUBROUTINE PRESSUREZ
diff --git a/src/ZSOLVER/qlap.f90 b/src/ZSOLVER/qlap.f90
new file mode 100644
index 0000000000000000000000000000000000000000..5f76e50d9b5f77db9717497307716ce2d7e2fef0
--- /dev/null
+++ b/src/ZSOLVER/qlap.f90
@@ -0,0 +1,568 @@
+!MNH_LIC Copyright 1994-2020 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+!     ################
+      MODULE MODI_QLAP
+!     ################
+!
+INTERFACE
+!
+      FUNCTION QLAP(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,PTHETAV,PY)  &
+               RESULT(PQLAP)
+!  
+IMPLICIT NONE
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX    ! x-direction LBC type 
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY    ! y-direction LBC type 
+!
+                                                 ! Metric coefficients:
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDXX      ! d*xx 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDYY      ! d*yy 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZX      ! d*zx 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZY      ! d*zy 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZZ      ! d*zz
+!
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHODJ    ! density of reference * J
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PTHETAV   ! virtual potential temp. at time t
+!
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PY        ! field components
+!
+REAL, DIMENSION(SIZE(PY,1),SIZE(PY,2),SIZE(PY,3)) :: PQLAP ! final divergence 
+!
+END FUNCTION QLAP
+!
+!
+#ifdef MNH_OPENACC
+SUBROUTINE QLAP_DEVICE(PQLAP,HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,PTHETAV,PY)  
+!  
+IMPLICIT NONE
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PQLAP ! final divergence   
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX    ! x-direction LBC type 
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY    ! y-direction LBC type 
+!
+                                                 ! Metric coefficients:
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDXX      ! d*xx 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDYY      ! d*yy 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZX      ! d*zx 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZY      ! d*zy 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZZ      ! d*zz
+!
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHODJ    ! density of reference * J
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PTHETAV   ! virtual potential temp. at time t
+!
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PY        ! field components
+!
+
+!
+END SUBROUTINE QLAP_DEVICE
+#endif
+END INTERFACE
+!
+END MODULE MODI_QLAP
+!
+!
+!
+!     #########################################################################
+      FUNCTION QLAP(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,PTHETAV,PY)  &
+               RESULT(PQLAP)
+!     #########################################################################
+!
+!!****  *QLAP * - compute the complete quasi-laplacien QLAP of a field P 
+!!
+!!    PURPOSE
+!!    -------
+!       This function computes the quasi-laplacien QLAP of the scalar field P
+!     localized at a mass point, with non-vanishing orography.
+!     The result is localized at a mass point and defined by: 
+!                    for Durran and MAE anelastic equations
+!                                   (                        ( GX_M_U (PY) )  )                 
+!                    PQLAP   = GDIV ( rho * CPd * Thetav * J ( GX_M_V (PY) )  )
+!                                   (                        ( GX_M_W (PY) )  )  
+!                    or for Lipps and Hemler
+!                                   (                        ( GX_M_U (PY) )  )                 
+!                    PQLAP   = GDIV ( rho                * J ( GX_M_V (PY) )  )
+!                                   (                        ( GX_M_W (PY) )  )  
+!     Where GX_M_.. are the cartesian components of the gradient of PY and
+!     GDIV is the operator acting on a vector AA: 
+!                   
+!                   GDIV ( AA ) = J * divergence (1/J  AA  ) 
+!     
+!!**  METHOD
+!!    ------
+!!      First, we compute the gradients along x, y , z of the P field. The 
+!!    result is multiplied by rhod * CPd * Thetav or  rhod depending on the 
+!!    chosen anelastic system where the suffixes indicate 
+!!    d dry and v for virtual.
+!!      Then, the pseudo-divergence ( J * DIV (1/J o ) ) is computed by the 
+!!    subroutine GDIV. The result is localized at a mass point.
+!!
+!!    EXTERNAL
+!!    --------
+!!      Function GX_M_U : compute the gradient along x 
+!!      Function GY_M_V : compute the gradient along y 
+!!      Function GZ_M_W : compute the gradient along z 
+!!      FUNCTION MXM: compute an average in the x direction for a variable  
+!!      at a mass localization
+!!      FUNCTION MYM: compute an average in the y direction for a variable  
+!!      at a mass localization
+!!      FUNCTION MZM: compute an average in the z direction for a variable  
+!!      at a mass localization
+!!      Subroutine GDIV : compute J times the divergence of 1/J times a vector
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------ 
+!!      Module MODD_PARAMETERS: JPHEXT, JPVEXT
+!!      Module MODD_CONF: L2D,CEQNSYS
+!!      Module MODD_CST : XCPD
+!!
+!!    REFERENCE
+!!    ---------
+!!      Pressure solver documentation ( Scientific documentation )
+!!
+!!    AUTHOR
+!!    ------
+!!	P. Hereil and J. Stein       * Meteo France *
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original       11/07/94 
+!!      Modification   16/03/95 change the argument list of the gradient
+!!                     14/01/97 New anelastic equation ( Stein )
+!!                     17/12/97 include the case of non-vanishing orography
+!!                              at the lbc ( Stein )
+!!                     06/12 V.Masson : update_halo due to CONTRAV changes
+!!   J.Escobar : 15/09/2015 : WENO5 & JPHEXT <> 1  
+!  P. Wautelet 20/05/2019: add name argument to ADDnFIELD_ll + new ADD4DFIELD_ll subroutine
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+!
+USE MODE_ll
+!
+USE MODD_PARAMETERS
+USE MODD_CONF
+USE MODD_CST
+USE MODI_GDIV
+USE MODI_GRADIENT_M
+USE MODI_SHUMAN
+!
+USE MODE_MPPDB
+!
+IMPLICIT NONE
+!
+!*       0.1   declarations of arguments
+!
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX    ! x-direction LBC type 
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY    ! y-direction LBC type 
+!
+                                                 ! Metric coefficients:
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDXX      ! d*xx 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDYY      ! d*yy 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZX      ! d*zx 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZY      ! d*zy 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZZ      ! d*zz
+!
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHODJ    ! density of reference * J
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PTHETAV   ! virtual potential temp. at time t
+!
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PY        ! field components
+!
+REAL, DIMENSION(SIZE(PY,1),SIZE(PY,2),SIZE(PY,3)) :: PQLAP ! final divergence 
+!
+!*       0.2   declarations of local variables
+!
+REAL, DIMENSION(SIZE(PY,1),SIZE(PY,2),SIZE(PY,3)) :: ZU ! rho*J*gradient along x
+!
+REAL, DIMENSION(SIZE(PY,1),SIZE(PY,2),SIZE(PY,3)) :: ZV ! rho*J*gradient along y
+!
+REAL, DIMENSION(SIZE(PY,1),SIZE(PY,2),SIZE(PY,3)) :: ZW ! rho*J*gradient along z
+!
+INTEGER                          :: IIU,IJU,IKU         ! I,J,K array sizes
+INTEGER                          :: JK,JJ,JI            ! vertical loop index
+TYPE(LIST_ll), POINTER :: TZFIELDS_ll   ! list of fields to exchange
+INTEGER :: IINFO_ll
+INTEGER :: IIB,IIE,IJB,IJE
+!-------------------------------------------------------------------------------
+!
+!
+!*       1.    COMPUTE THE GRADIENT COMPONENTS
+!              -------------------------------
+!
+CALL GET_DIM_EXT_ll('B',IIU,IJU)
+CALL GET_INDICE_ll (IIB,IJB,IIE,IJE)
+IKU=SIZE(PY,3)
+!
+ZU = GX_M_U(1,IKU,1,PY,PDXX,PDZZ,PDZX)
+CALL MPPDB_CHECK3D(ZU,'QLAP::ZU',PRECISION)
+!
+IF ( HLBCX(1) /= 'CYCL' .AND. LWEST_ll() ) THEN
+  DO JK=2,IKU-1
+    DO JJ=1,IJU
+      ZU(IIB,JJ,JK)=  (PY(IIB,JJ,JK) - PY(IIB-1,JJ,JK) - 0.5 * (                  &
+       PDZX(IIB,JJ,JK)   * (PY(IIB,JJ,JK)-PY(IIB,JJ,JK-1)) / PDZZ(IIB,JJ,JK)      &
+      +PDZX(IIB,JJ,JK+1) * (PY(IIB,JJ,JK+1)-PY(IIB,JJ,JK)) / PDZZ(IIB,JJ,JK+1)    &  
+                                      )    ) / PDXX(IIB,JJ,JK)
+    END DO
+  END DO
+END IF
+CALL MPPDB_CHECK3D(ZU,'QLAP::ZU/W',PRECISION)
+!
+IF ( HLBCX(1) /= 'CYCL' .AND. LEAST_ll() ) THEN
+  DO JK=2,IKU-1
+    DO JJ=1,IJU
+      ZU(IIE+1,JJ,JK)=  (PY(IIE+1,JJ,JK) - PY(IIE+1-1,JJ,JK) - 0.5 * (                    &
+        PDZX(IIE+1,JJ,JK)   * (PY(IIE+1-1,JJ,JK)-PY(IIE+1-1,JJ,JK-1)) / PDZZ(IIE+1-1,JJ,JK)  &
+       +PDZX(IIE+1,JJ,JK+1) * (PY(IIE+1-1,JJ,JK+1)-PY(IIE+1-1,JJ,JK)) / PDZZ(IIE+1-1,JJ,JK+1)&  
+                                            ) ) / PDXX(IIE+1,JJ,JK)
+    END DO
+  END DO
+END IF
+CALL MPPDB_CHECK3D(ZU,'QLAP::ZU/E',PRECISION)
+!
+IF(.NOT. L2D) THEN 
+!
+  ZV = GY_M_V(1,IKU,1,PY,PDYY,PDZZ,PDZY)
+  CALL MPPDB_CHECK3D(ZV,'QLAP::ZV',PRECISION)
+!
+  IF ( HLBCY(1) /= 'CYCL' .AND. LSOUTH_ll() ) THEN 
+    DO JK=2,IKU-1
+      DO JI=1,IIU
+        ZV(JI,IJB,JK)=   (PY(JI,IJB,JK) - PY(JI,IJB-1,JK) - 0.5 * (                  &
+          PDZY(JI,IJB,JK)   * (PY(JI,IJB,JK)-PY(JI,IJB,JK-1)) / PDZZ(JI,IJB,JK)      &
+         +PDZY(JI,IJB,JK+1) * (PY(JI,IJB,JK+1)-PY(JI,IJB,JK)) / PDZZ(JI,IJB,JK+1)    &  
+                                            )   ) / PDYY(JI,IJB,JK) 
+      END DO
+    END DO
+  END IF
+  CALL MPPDB_CHECK3D(ZV,'QLAP::ZV/S',PRECISION)
+  IF ( HLBCY(1) /= 'CYCL' .AND. LNORTH_ll() ) THEN
+!
+    DO JK=2,IKU-1
+      DO JI=1,IIU
+        ZV(JI,IJE+1,JK)=    (PY(JI,IJE+1,JK) - PY(JI,IJE+1-1,JK) - 0.5 * (                  &
+          PDZY(JI,IJE+1,JK)   * (PY(JI,IJE+1-1,JK)-PY(JI,IJE+1-1,JK-1)) / PDZZ(JI,IJE+1-1,JK)  &
+         +PDZY(JI,IJE+1,JK+1) * (PY(JI,IJE+1-1,JK+1)-PY(JI,IJE+1-1,JK)) / PDZZ(JI,IJE+1-1,JK+1)&
+                                                )  ) / PDYY(JI,IJE+1,JK) 
+      END DO
+    END DO
+  END IF
+ CALL MPPDB_CHECK3D(ZV,'QLAP::ZV/N',PRECISION)
+!
+ELSE
+  ZV=0.
+ENDIF
+!
+IF ( CEQNSYS == 'DUR' .OR. CEQNSYS == 'MAE' ) THEN
+  ZU = MXM(PRHODJ * XCPD * PTHETAV) *  ZU
+  IF(.NOT. L2D) THEN 
+    ZV = MYM(PRHODJ * XCPD * PTHETAV) *  ZV
+  END IF
+  ZW = MZM(PRHODJ * XCPD * PTHETAV) *  GZ_M_W(1,IKU,1,PY,PDZZ)
+ELSEIF ( CEQNSYS == 'LHE' ) THEN 
+  ZU = MXM(PRHODJ) * ZU
+  IF(.NOT. L2D) THEN 
+    ZV = MYM(PRHODJ) * ZV
+  ENDIF
+  ZW = MZM(PRHODJ) * GZ_M_W(1,IKU,1,PY,PDZZ)
+END IF
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.    COMPUTE THE DIVERGENCE  
+!              ----------------------
+!
+NULLIFY(TZFIELDS_ll)
+CALL ADD3DFIELD_ll( TZFIELDS_ll, ZU, 'QLAP::ZU' )
+CALL ADD3DFIELD_ll( TZFIELDS_ll, ZV, 'QLAP::ZV' )
+CALL ADD3DFIELD_ll( TZFIELDS_ll, ZW, 'QLAP::ZW' )
+CALL UPDATE_HALO_ll(TZFIELDS_ll,IINFO_ll)
+CALL CLEANLIST_ll(TZFIELDS_ll)
+!
+CALL GDIV(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,ZU,ZV,ZW,PQLAP)    
+!
+!-------------------------------------------------------------------------------
+!
+END FUNCTION QLAP
+
+#ifdef MNH_OPENACC
+!     #########################################################################
+      SUBROUTINE QLAP_DEVICE(PQLAP,HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,PTHETAV,PY) 
+!     #########################################################################
+!
+!!****  *QLAP * - compute the complete quasi-laplacien QLAP of a field P 
+!!
+!!    PURPOSE
+!!    -------
+!       This function computes the quasi-laplacien QLAP of the scalar field P
+!     localized at a mass point, with non-vanishing orography.
+!     The result is localized at a mass point and defined by: 
+!                    for Durran and MAE anelastic equations
+!                                   (                        ( GX_M_U (PY) )  )                 
+!                    PQLAP   = GDIV ( rho * CPd * Thetav * J ( GX_M_V (PY) )  )
+!                                   (                        ( GX_M_W (PY) )  )  
+!                    or for Lipps and Hemler
+!                                   (                        ( GX_M_U (PY) )  )                 
+!                    PQLAP   = GDIV ( rho                * J ( GX_M_V (PY) )  )
+!                                   (                        ( GX_M_W (PY) )  )  
+!     Where GX_M_.. are the cartesian components of the gradient of PY and
+!     GDIV is the operator acting on a vector AA: 
+!                   
+!                   GDIV ( AA ) = J * divergence (1/J  AA  ) 
+!     
+!!**  METHOD
+!!    ------
+!!      First, we compute the gradients along x, y , z of the P field. The 
+!!    result is multiplied by rhod * CPd * Thetav or  rhod depending on the 
+!!    chosen anelastic system where the suffixes indicate 
+!!    d dry and v for virtual.
+!!      Then, the pseudo-divergence ( J * DIV (1/J o ) ) is computed by the 
+!!    subroutine GDIV. The result is localized at a mass point.
+!!
+!!    EXTERNAL
+!!    --------
+!!      Function GX_M_U : compute the gradient along x 
+!!      Function GY_M_V : compute the gradient along y 
+!!      Function GZ_M_W : compute the gradient along z 
+!!      FUNCTION MXM: compute an average in the x direction for a variable  
+!!      at a mass localization
+!!      FUNCTION MYM: compute an average in the y direction for a variable  
+!!      at a mass localization
+!!      FUNCTION MZM: compute an average in the z direction for a variable  
+!!      at a mass localization
+!!      Subroutine GDIV : compute J times the divergence of 1/J times a vector
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------ 
+!!      Module MODD_PARAMETERS: JPHEXT, JPVEXT
+!!      Module MODD_CONF: L2D,CEQNSYS
+!!      Module MODD_CST : XCPD
+!!
+!!    REFERENCE
+!!    ---------
+!!      Pressure solver documentation ( Scientific documentation )
+!!
+!!    AUTHOR
+!!    ------
+!!	P. Hereil and J. Stein       * Meteo France *
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original       11/07/94 
+!!      Modification   16/03/95 change the argument list of the gradient
+!!                     14/01/97 New anelastic equation ( Stein )
+!!                     17/12/97 include the case of non-vanishing orography
+!!                              at the lbc ( Stein )
+!!                     06/12 V.Masson : update_halo due to CONTRAV changes
+!!   J.Escobar : 15/09/2015 : WENO5 & JPHEXT <> 1  
+!  P. Wautelet 20/05/2019: add name argument to ADDnFIELD_ll + new ADD4DFIELD_ll subroutine
+!-------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+!
+USE MODE_ll
+!
+USE MODD_PARAMETERS
+USE MODD_CONF
+USE MODD_CST
+USE MODI_GDIV
+USE MODI_GRADIENT_M
+USE MODI_SHUMAN
+USE MODI_SHUMAN_DEVICE
+!
+USE MODE_MPPDB
+!
+USE MODE_MNH_ZWORK , ONLY : MNH_ALLOCATE_ZT3D , MNH_REL_ZT3D
+!
+USE MODI_GET_HALO
+!
+IMPLICIT NONE
+!
+!*       0.1   declarations of arguments
+!
+!
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PQLAP ! final divergence   
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX    ! x-direction LBC type 
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY    ! y-direction LBC type 
+!
+                                                 ! Metric coefficients:
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDXX      ! d*xx 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDYY      ! d*yy 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZX      ! d*zx 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZY      ! d*zy 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZZ      ! d*zz
+!
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHODJ    ! density of reference * J
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PTHETAV   ! virtual potential temp. at time t
+!
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PY        ! field components
+!
+!*       0.2   declarations of local variables
+!
+REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZU ! rho*J*gradient along x
+!
+REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZV ! rho*J*gradient along y
+!
+REAL, DIMENSION(:,:,:) , POINTER , CONTIGUOUS :: ZW ! rho*J*gradient along z
+!
+INTEGER :: IZU,IZV,IZW
+!
+INTEGER                          :: IIU,IJU,IKU         ! I,J,K array sizes
+INTEGER                          :: JK,JJ,JI            ! vertical loop index
+TYPE(LIST_ll), POINTER :: TZFIELDS_ll   ! list of fields to exchange
+INTEGER :: IINFO_ll
+INTEGER :: IIB,IIE,IJB,IJE
+!
+REAL, DIMENSION(:,:,:), pointer , contiguous :: ZMXM,ZMYM,ZMZM,ZRHODJ,ZGZMW
+INTEGER :: IZMXM,IZMYM,IZMZM,IZRHODJ,IZGZMW
+!
+LOGICAL :: GWEST,GEAST,GSOUTH,GNORTH
+!-------------------------------------------------------------------------------
+!
+!
+!*       1.    COMPUTE THE GRADIENT COMPONENTS
+!              -------------------------------
+!
+CALL GET_DIM_EXT_ll('B',IIU,IJU)
+CALL GET_INDICE_ll (IIB,IJB,IIE,IJE)
+IKU=SIZE(PY,3)
+!
+GWEST  = ( HLBCX(1) /= 'CYCL' .AND. LWEST_ll() )
+GEAST  = ( HLBCX(2) /= 'CYCL' .AND. LEAST_ll() )
+GSOUTH = ( HLBCY(1) /= 'CYCL' .AND. LSOUTH_ll() )
+GNORTH = ( HLBCY(2) /= 'CYCL' .AND. LNORTH_ll() )
+!
+IZU = MNH_ALLOCATE_ZT3D( ZU,IIU,IJU,IKU  )
+IZV = MNH_ALLOCATE_ZT3D( ZV,IIU,IJU,IKU  )   
+IZW = MNH_ALLOCATE_ZT3D( ZW,IIU,IJU,IKU  )
+!
+IZMXM = MNH_ALLOCATE_ZT3D( ZMXM,IIU,IJU,IKU  )
+IZMYM = MNH_ALLOCATE_ZT3D( ZMYM,IIU,IJU,IKU  )
+IZMZM = MNH_ALLOCATE_ZT3D( ZMZM,IIU,IJU,IKU  )
+IZRHODJ = MNH_ALLOCATE_ZT3D( ZRHODJ ,IIU,IJU,IKU  )
+IZGZMW  = MNH_ALLOCATE_ZT3D( ZGZMW  ,IIU,IJU,IKU  )
+!
+CALL GX_M_U_DEVICE(1,IKU,1,PY,PDXX,PDZZ,PDZX,ZU)
+CALL MPPDB_CHECK3D(ZU,'QLAP::ZU',PRECISION)
+!
+IF ( GWEST ) THEN
+   !$acc kernels async
+   DO JK=2,IKU-1
+      DO JJ=1,IJU
+         ZU(IIB,JJ,JK)=  (PY(IIB,JJ,JK) - PY(IIB-1,JJ,JK) - 0.5 * (                  &
+              PDZX(IIB,JJ,JK)   * (PY(IIB,JJ,JK)-PY(IIB,JJ,JK-1)) / PDZZ(IIB,JJ,JK)      &
+              +PDZX(IIB,JJ,JK+1) * (PY(IIB,JJ,JK+1)-PY(IIB,JJ,JK)) / PDZZ(IIB,JJ,JK+1)    &  
+              )    ) / PDXX(IIB,JJ,JK)
+      END DO
+   END DO
+   !$acc end kernels
+END IF
+!
+IF ( GEAST ) THEN
+   !$acc kernels async
+   DO JK=2,IKU-1
+      DO JJ=1,IJU
+         ZU(IIE+1,JJ,JK)=  (PY(IIE+1,JJ,JK) - PY(IIE+1-1,JJ,JK) - 0.5 * (                    &
+              PDZX(IIE+1,JJ,JK)   * (PY(IIE+1-1,JJ,JK)-PY(IIE+1-1,JJ,JK-1)) / PDZZ(IIE+1-1,JJ,JK)  &
+              +PDZX(IIE+1,JJ,JK+1) * (PY(IIE+1-1,JJ,JK+1)-PY(IIE+1-1,JJ,JK)) / PDZZ(IIE+1-1,JJ,JK+1)&  
+              ) ) / PDXX(IIE+1,JJ,JK)
+      END DO
+   END DO
+   !$acc end kernels
+END IF
+!$acc wait
+!
+CALL MPPDB_CHECK3D(ZU,'QLAP::ZU/W',PRECISION)
+CALL MPPDB_CHECK3D(ZU,'QLAP::ZU/E',PRECISION)
+!
+IF(.NOT. L2D) THEN 
+!
+  CALL GY_M_V_DEVICE(1,IKU,1,PY,PDYY,PDZZ,PDZY,ZV)
+  CALL MPPDB_CHECK3D(ZV,'QLAP::ZV',PRECISION)
+!
+  IF ( GSOUTH ) THEN
+     !$acc kernels async
+     DO JK=2,IKU-1
+        DO JI=1,IIU
+           ZV(JI,IJB,JK)=   (PY(JI,IJB,JK) - PY(JI,IJB-1,JK) - 0.5 * (                  &
+                PDZY(JI,IJB,JK)   * (PY(JI,IJB,JK)-PY(JI,IJB,JK-1)) / PDZZ(JI,IJB,JK)      &
+                +PDZY(JI,IJB,JK+1) * (PY(JI,IJB,JK+1)-PY(JI,IJB,JK)) / PDZZ(JI,IJB,JK+1)    &  
+                )   ) / PDYY(JI,IJB,JK) 
+        END DO
+     END DO
+     !$acc end kernels
+  END IF
+
+  
+  IF ( GNORTH ) THEN
+     !$acc kernels async
+     DO JK=2,IKU-1
+        DO JI=1,IIU
+           ZV(JI,IJE+1,JK)=    (PY(JI,IJE+1,JK) - PY(JI,IJE+1-1,JK) - 0.5 * ( &
+                PDZY(JI,IJE+1,JK)   * (PY(JI,IJE+1-1,JK)-PY(JI,IJE+1-1,JK-1)) &
+                                      / PDZZ(JI,IJE+1-1,JK)  &
+               +PDZY(JI,IJE+1,JK+1) * (PY(JI,IJE+1-1,JK+1)-PY(JI,IJE+1-1,JK)) &
+                                      / PDZZ(JI,IJE+1-1,JK+1)&
+                )  ) / PDYY(JI,IJE+1,JK) 
+        END DO
+     END DO
+     !$acc end kernels
+  END IF
+  !$acc wait
+  CALL MPPDB_CHECK3D(ZV,'QLAP::ZV/S',PRECISION)  
+  CALL MPPDB_CHECK3D(ZV,'QLAP::ZV/N',PRECISION)
+!
+ELSE
+  ZV=0.
+ENDIF
+!
+IF ( CEQNSYS == 'DUR' .OR. CEQNSYS == 'MAE' ) THEN
+   !$acc kernels
+   ZRHODJ = PRHODJ * XCPD * PTHETAV
+   !$acc end kernels
+   CALL MXM_DEVICE (ZRHODJ, ZMXM )
+   !$acc kernels
+   ZU = ZMXM *  ZU
+   !$acc end kernels
+  IF(.NOT. L2D) THEN 
+     CALL MYM_DEVICE (ZRHODJ, ZMYM )
+     !$acc kernels
+     ZV = ZMYM * ZV
+     !$acc end kernels
+  END IF
+  CALL MZM_DEVICE (ZRHODJ, ZMZM )
+  CALL GZ_M_W_DEVICE(1,IKU,1,PY,PDZZ,ZGZMW)
+  !$acc kernels
+  ZW = ZMZM * ZGZMW
+  !$acc end kernels
+ELSEIF ( CEQNSYS == 'LHE' ) THEN 
+  ZU = MXM(PRHODJ) * ZU
+  IF(.NOT. L2D) THEN 
+    ZV = MYM(PRHODJ) * ZV
+  ENDIF
+  ZW = MZM(PRHODJ) * GZ_M_W(1,IKU,1,PY,PDZZ)
+END IF
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.    COMPUTE THE DIVERGENCE  
+!              ----------------------
+!
+CALL GET_HALO_D(ZU,HNAME='QLAP::ZU')
+CALL GET_HALO_D(ZV,HNAME='QLAP::ZV')
+CALL GET_HALO_D(ZW,HNAME='QLAP::ZW')
+!
+CALL GDIV(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,ZU,ZV,ZW,PQLAP)    
+!
+CALL MNH_REL_ZT3D (  IZU,IZV,IZW, IZMXM,IZMYM,IZMZM,IZRHODJ,IZGZMW )
+!-------------------------------------------------------------------------------
+!
+END SUBROUTINE QLAP_DEVICE
+#endif
diff --git a/src/ZSOLVER/read_exsegn.f90 b/src/ZSOLVER/read_exsegn.f90
new file mode 100644
index 0000000000000000000000000000000000000000..85e867132c14957b8d40a881ad9fe9d337879228
--- /dev/null
+++ b/src/ZSOLVER/read_exsegn.f90
@@ -0,0 +1,2853 @@
+!MNH_LIC Copyright 1994-2019 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+!     ###################### 
+      MODULE MODI_READ_EXSEG_n
+!     ######################
+!
+INTERFACE
+!
+      SUBROUTINE READ_EXSEG_n(KMI,TPEXSEGFILE,HCONF,OFLAT,OUSERV,                  &
+                   OUSERC,OUSERR,OUSERI,OUSECI,OUSERS,OUSERG,OUSERH,               &
+                   OUSECHEM,OUSECHAQ,OUSECHIC,OCH_PH,OCH_CONV_LINOX,OSALT,         &
+                   ODEPOS_SLT, ODUST,ODEPOS_DST, OCHTRANS,                         &
+                   OORILAM,ODEPOS_AER, OLG,OPASPOL,                                &
+#ifdef MNH_FOREFIRE
+                   OFOREFIRE,                                                      &
+#endif
+                   OLNOX_EXPLICIT,                                                 &
+                   OCONDSAMP,OBLOWSNOW,                                            &
+                   KRIMX,KRIMY, KSV_USER,                                          &
+                   HTURB,HTOM,ORMC01,HRAD,HDCONV,HSCONV,HCLOUD,HELEC,              &
+                   HEQNSYS,PTSTEP_ALL,HSTORAGE_TYPE,HINIFILEPGD                    )
+!
+USE MODD_IO,   ONLY: TFILEDATA
+!
+INTEGER,            INTENT(IN) :: KMI    ! Model index
+TYPE(TFILEDATA),    INTENT(IN) :: TPEXSEGFILE ! EXSEG file
+!     The following variables are read by READ_DESFM in DESFM descriptor : 
+CHARACTER (LEN=*),  INTENT(IN) :: HCONF  ! configuration var. linked to FMfile
+LOGICAL,            INTENT(IN) :: OFLAT  ! Logical for zero orography
+LOGICAL,            INTENT(IN) :: OUSERV,OUSERC,OUSERR,OUSERI,OUSERS, &
+                                  OUSERG,OUSERH  ! kind of moist variables in 
+                                                 ! FMfile
+LOGICAL,            INTENT(IN) :: OUSECI         ! ice concentration in
+                                                 ! FMfile
+LOGICAL,            INTENT(IN) :: OUSECHEM       ! Chemical FLAG in FMFILE
+LOGICAL,            INTENT(IN) :: OUSECHAQ       ! Aqueous chemical FLAG in FMFILE
+LOGICAL,            INTENT(IN) :: OUSECHIC       ! Ice chemical FLAG in FMFILE
+LOGICAL,            INTENT(IN) :: OCH_PH         ! pH FLAG in FMFILE
+LOGICAL,            INTENT(IN) :: OCH_CONV_LINOX ! LiNOx FLAG in FMFILE
+LOGICAL,            INTENT(IN) :: ODUST          ! Dust FLAG in FMFILE
+LOGICAL,DIMENSION(:), INTENT(IN)  :: ODEPOS_DST  ! Dust wet deposition FLAG in FMFILE     
+LOGICAL,DIMENSION(:), INTENT(IN)  :: ODEPOS_SLT  ! Sea Salt wet deposition FLAG in FMFILE     
+LOGICAL,DIMENSION(:), INTENT(IN)  :: ODEPOS_AER  ! Orilam wet deposition FLAG in FMFILE     
+LOGICAL,            INTENT(IN) :: OSALT          ! Sea Salt FLAG in FMFILE
+LOGICAL,            INTENT(IN) :: OORILAM        ! Orilam FLAG in FMFILE
+LOGICAL,            INTENT(IN) :: OPASPOL        ! Passive pollutant FLAG in FMFILE
+#ifdef MNH_FOREFIRE
+LOGICAL,            INTENT(IN) :: OFOREFIRE      ! ForeFire FLAG in FMFILE
+#endif
+LOGICAL,            INTENT(IN) :: OLNOX_EXPLICIT ! explicit LNOx FLAG in FMFILE
+LOGICAL,            INTENT(IN) :: OCONDSAMP      ! Conditional sampling FLAG in FMFILE
+LOGICAL,            INTENT(IN) :: OBLOWSNOW     ! Blowing snow FLAG in FMFILE
+LOGICAL,            INTENT(IN) :: OCHTRANS       ! LCHTRANS FLAG in FMFILE
+
+LOGICAL,            INTENT(IN) :: OLG            ! lagrangian FLAG in FMFILE
+INTEGER,            INTENT(IN) :: KRIMX, KRIMY   ! number of points for the
+                       ! horizontal relaxation for the outermost verticals
+INTEGER,            INTENT(IN) :: KSV_USER    ! number of additional scalar
+                                         ! variables in FMfile 
+CHARACTER (LEN=*),  INTENT(IN) :: HTURB  ! Kind of turbulence parameterization
+                                         ! used to  produce FMFILE
+CHARACTER (LEN=*),  INTENT(IN) :: HTOM   ! Kind of third order moment
+LOGICAL,            INTENT(IN) :: ORMC01 ! flag for RMC01 SBL computations
+CHARACTER (LEN=*),  INTENT(IN) :: HRAD   ! Kind of radiation scheme
+CHARACTER (LEN=4),  INTENT(IN) :: HDCONV ! Kind of deep convection scheme
+CHARACTER (LEN=4),  INTENT(IN) :: HSCONV ! Kind of shallow convection scheme
+CHARACTER (LEN=4),  INTENT(IN) :: HCLOUD ! Kind of microphysical scheme
+CHARACTER (LEN=4),  INTENT(IN) :: HELEC  ! Kind of electrical scheme
+CHARACTER (LEN=*),  INTENT(IN) :: HEQNSYS! type of equations' system
+REAL,DIMENSION(:),  INTENT(INOUT):: PTSTEP_ALL ! Time STEP of ALL models
+CHARACTER (LEN=*),  INTENT(IN) :: HSTORAGE_TYPE ! type of initial file
+CHARACTER (LEN=*),  INTENT(IN) :: HINIFILEPGD ! name of PGD file
+!
+END SUBROUTINE READ_EXSEG_n
+!
+END INTERFACE
+!
+END MODULE MODI_READ_EXSEG_n
+!
+!
+!     #########################################################################
+      SUBROUTINE READ_EXSEG_n(KMI,TPEXSEGFILE,HCONF,OFLAT,OUSERV,                  &
+                   OUSERC,OUSERR,OUSERI,OUSECI,OUSERS,OUSERG,OUSERH,               &
+                   OUSECHEM,OUSECHAQ,OUSECHIC,OCH_PH,OCH_CONV_LINOX,OSALT,         &
+                   ODEPOS_SLT, ODUST,ODEPOS_DST, OCHTRANS,                         &
+                   OORILAM,ODEPOS_AER, OLG,OPASPOL,                                &
+#ifdef MNH_FOREFIRE
+                   OFOREFIRE,                                                      &
+#endif
+                   OLNOX_EXPLICIT,                                                 &
+                   OCONDSAMP, OBLOWSNOW,                                           &
+                   KRIMX,KRIMY, KSV_USER,                                          &
+                   HTURB,HTOM,ORMC01,HRAD,HDCONV,HSCONV,HCLOUD,HELEC,              &
+                   HEQNSYS,PTSTEP_ALL,HSTORAGE_TYPE,HINIFILEPGD                    )
+!     #########################################################################
+!
+!!****  *READ_EXSEG_n * - routine to read  the descriptor file EXSEG
+!!
+!!    PURPOSE
+!!    -------
+!       The purpose of this routine is to read the descriptor file called 
+!     EXSEG and to control the coherence with FMfile data . 
+!       
+!!
+!!**  METHOD
+!!    ------
+!!      The descriptor file is read. Namelists (NAMXXXn) which contain
+!!    variables linked to one nested model are at the beginning of the file.
+!!    Namelists (NAMXXX) which contain variables common to all models
+!!    are at the end of the file. When the  model index is different from 1, 
+!!    the end of the file (namelists NAMXXX) is not read. 
+!!
+!!      Coherence between the initial file (description read in DESFM file)
+!!    and the segment to perform (description read in EXSEG file)
+!!    is checked for segment achievement  configurations 
+!!    or  postprocessing configuration. The get indicators are set according 
+!!      to the following check :
+!!
+!!      - segment achievement and preinit configurations :
+!!
+!!       * if there is no turbulence kinetic energy in  initial
+!!      file (HTURB='NONE'), and the segment to perform requires a turbulence
+!!      parameterization (CTURB /= 'NONE'), the get indicators for turbulence 
+!!      kinetic energy variables are set to 'INIT'; i.e. these variables will be
+!!      set equal to  zero by READ_FIELD according to the get indicators.
+!!       * The same procedure is applied to the dissipation of TKE. 
+!!       * if there is no moist variables RRn  in  initial file (OUSERn=.FALSE.)
+!!      and the segment to perform requires  moist variables RRn
+!!      (LUSERn=.TRUE.),  the get indicators for moist variables RRn are set
+!!      equal to 'INIT'; i.e. these variables will be set equal to  zero by 
+!!      READ_FIELD according to the get indicators.
+!!       * if there are KSV_USER additional scalar variables in initial file and the
+!!      segment to perform needs more than KSV_USER additional variables,  the get
+!!      indicators for these (NSV_USER-KSV_USER) additional scalar variables are set 
+!!      equal to 'INIT'; i.e. these variables will be set equal to  zero by 
+!!      READ_FIELD according to the get indicators. If the segment to perform
+!!      needs less additional scalar variables than there are in initial file,
+!!      the get indicators for these (KSV_USER - NSV_USER) additional scalar variables are
+!!      set equal to 'SKIP'.      
+!!       * warning messages are printed if the fields in initial file are the
+!!      same at time t and t-dt (HCONF='START') and  a leap-frog advance 
+!!      at first time step will be used  for the segment to perform
+!!      (CCONF='RESTA'); It is likewise when HCONF='RESTA' and CCONF='START'.
+!!       * A warning message is printed if the orography in initial file is zero
+!!      (OFLAT=.TRUE.) and the segment to perform considers no-zero orography
+!!      (LFLAT=.FALSE.). It is likewise for LFLAT=.TRUE. and OFLAT=.FALSE..
+!!       If the segment to perform requires zero orography (LFLAT=.TRUE.), the
+!!       orography (XZS) will not read in initial file but  set equal to zero 
+!!       by SET_GRID.  
+!!       * check of the depths of the Lateral Damping Layer in x and y 
+!!       direction is performed
+!!       * If some coupling files are specified, LSTEADYLS is set to T
+!!       * If no coupling files are specified, LSTEADYLS is set to F
+!!
+!!
+!!    EXTERNAL
+!!    --------
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------
+!!     Module MODN_CONF : CCONF,LTHINSHELL,LFLAT,NMODEL,NVERB     
+!!
+!!      Module MODN_DYN : LCORIO, LZDIFFU
+!!
+!!      Module MODN_NESTING : NDAD(m),NDTRATIO(m),XWAY(m)
+!!
+!!      Module MODN_BUDGET : CBUTYPE,XBULEN
+!!
+!!      Module MODN_CONF1 : LUSERV,LUSERC,LUSERR,LUSERI,LUSERS,LUSERG,LUSERH,CSEG
+!!
+!!      Module MODN_DYN1 : XTSTEP,CPRESOPT,NITR,XRELAX
+!!
+!!      Module MODD_ADV1 : CMET_ADV_SCHEME,CSV_ADV_SCHEME,CUVW_ADV_SCHEME,NLITER
+!!
+!!      Module MODN_PARAM1 : CTURB,CRAD,CDCONV,CSCONV
+!!
+!!      Module MODN_LUNIT1 : 
+!!      Module MODN_LBC1 : CLBCX,CLBCY,NLBLX,NLBLY,XCPHASE,XPOND
+!!
+!!      Module MODN_TURB_n : CTURBLEN,CTURBDIM
+!!
+!!      Module MODD_GET1: 
+!!        CGETTKEM,CGETTKET,
+!!        CGETRVM,CGETRCM,CGETRRM,CGETRIM,CGETRSM,CGETRGM,CGETRHM
+!!        CGETRVT,CGETRCT,CGETRRT,CGETRIT,CGETRST,CGETRGT,CGETRHT,CGETSVM
+!!        CGETSVT,CGETSIGS,CGETSRCM,CGETSRCT 
+!!        NCPL_NBR,NCPL_TIMES,NCPL_CUR
+!!      Module MODN_LES  : contains declaration of the control parameters
+!!                                for Large Eddy Simulations' storages
+!!                                for the forcing
+!!
+!!    REFERENCE
+!!    ---------
+!!      Book2 of the  documentation (routine READ_EXSEG_n)
+!!      
+!!
+!!    AUTHOR
+!!    ------
+!!  	V. Ducrocq       * Meteo France *
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original    07/06/94 
+!!      Modification   26/10/94  (Stein)  remove NAM_GET from the Namelists
+!!      present in DESFM + change the namelist names
+!!      Modification   22/11/94  (Stein)  add GET indicator for phi
+!!      Modification   21/12/94  (Stein)  add GET indicator for LS fields  
+!!      Modification   06/01/95  (Stein)  bug in the test for Scalar Var.
+!!      Modifications  09/01/95  (Stein)  add the turbulence scheme
+!!      Modifications  09/01/95  (Stein)  add the 1D switch
+!!      Modifications  10/03/95  (Mallet) add coherence in coupling case
+!!      Modifications  16/03/95  (Stein)  remove R from the historical variables
+!!      Modifications  01/03/95  (Hereil) add the budget namelists
+!!      Modifications  16/06/95  (Stein)  coherence control for the
+!!                microphysical scheme + remove the wrong messge for RESTA conf
+!!      Modifications  30/06/95  (Stein)  conditionnal reading of the fields
+!!                used by the moist turbulence scheme
+!!      Modifications  12/09/95  (Pinty)  add the radiation scheme
+!!      Modification   06/02/96  (J.Vila) implement scalar advection schemes
+!!      Modifications  24/02/96  (Stein)  change the default value for CCPLFILE
+!!      Modifications  02/05/96  (Stein Jabouille) change the Z0SEA activation
+!!      Modifications  24/05/96  (Stein)  change the SRC SIGS control
+!!      Modifications  08/09/96  (Masson) the coupling file names are reset to
+!!                               default value " " before reading in EXSEG1.nam
+!!                               to avoid extra non-existant coupling files
+!!
+!!      Modifications  25/04/95  (K.Suhre)add namelist NAM_BLANK
+!!                                        add read for LFORCING
+!!                     25/04/95  (K.Suhre)add namelist NAM_FRC
+!!                                        and switch checking
+!!                     06/08/96  (K.Suhre)add namelist NAM_CH_MNHCn
+!!                                        and NAM_CH_SOLVER
+!!      Modifications  10/10/96  (Stein)  change SRC into SRCM and SRCT
+!!      Modifications  11/04/96  (Pinty)  add the rain-ice microphysical scheme
+!!      Modifications  11/01/97  (Pinty)  add the deep convection scheme
+!!      Modifications  22/05/97  (Lafore) gridnesting implementation
+!!      Modifications  22/06/97  (Stein)  add the absolute pressure + cleaning
+!!      Modifications  25/08/97  (Masson) add tests on surface schemes
+!!                     22/10/97  (Stein) remove the RIMX /= 0 control
+!!                                       + new namelist + cleaning
+!!      Modifications  17/04/98  (Masson) add tests on character variables
+!!      Modification   15/03/99  (Masson) add tests on PROGRAM
+!!      Modification   04/01/00  (Masson) removes TSZ0 case
+!!      Modification   04/06/00  (Pinty)  add C2R2 scheme
+!!                     11/12/00  (Tomasini) add CSEA_FLUX to MODD_PARAMn
+!!                                          delete the test on SST_FRC only in 1D
+!!      Modification   22/01/01  (Gazen)  change NSV,KSV to NSV_USER,KSV_USER and add
+!!                                        NSV_* variables initialization
+!!      Modification   15/10/01  (Mallet) allow namelists in different orders
+!!      Modification   18/03/02  (Solmon)  new radiation scheme test
+!!      Modification   29/11/02 (JP Pinty) add C3R5, ICE2, ICE4, ELEC
+!!      Modification   06/11/02  (Masson)  new LES BL height diagnostic
+!!      Modification   06/11/02  (Jabouille)  remove LTHINSHELL LFORCING test
+!!      Modification   01/12/03  (Gazen)   change Chemical scheme interface
+!!      Modification   01/2004   (Masson) removes surface (externalization)
+!!      Modification   01/2005   (Masson) removes 1D and 2D switches
+!!      Modification   04/2005   (Tulet)  add dust, orilam
+!!      Modification   03/2006   (O.Geoffroy) Add KHKO scheme
+!!      Modification   04/2006   (Maric)  include 4th order advection scheme
+!!      Modification   05/2006   (Masson) add nudging
+!!      Modification   05/2006   Remove KEPS
+!!      Modification   04/2006   (Maric)  include PPM advection scheme
+!!      Modification   04/2006   (J.Escobar) Bug dollarn add CALL UPDATE_NAM_CONFN  
+!!      Modifications  01/2007   (Malardel,Pergaud)  add the MF shallow
+!!                               convection scheme MODN_PARAM_MFSHALL_n
+!!      Modification   09/2009   (J.Escobar) add more info on relaxation problems
+!!      Modification   09/2011   (J.Escobar) re-add 'ZRESI' choose
+!!      Modification   12/2011   (C.Lac) Adaptation to FIT temporal scheme 
+!!      Modification   12/2012   (S.Bielli) add NAM_NCOUT for netcdf output (removed 08/07/2016)
+!!      Modification   02/2012   (Pialat/Tulet) add ForeFire
+!!      Modification   02/2012   (T.Lunet) add of new Runge-Kutta methods
+!!      Modification   01/2015   (C. Barthe) add explicit LNOx
+!!      J.Escobar : 15/09/2015 : WENO5 & JPHEXT <> 1 
+!!      M.Leriche 18/12/2015 : bug chimie glace dans prep_real_case
+!!      Modification    01/2016  (JP Pinty) Add LIMA
+!!      Modification   02/2016   (M.Leriche) treat gas and aq. chemicals separately
+!!      P.Wautelet 08/07/2016 : removed MNH_NCWRIT define
+!!      Modification   10/2016    (C.LAC) Add OSPLIT_WENO + Add droplet
+!!                                deposition + Add max values
+!!      Modification   11/2016   (Ph. Wautelet) Allocate/initialise some output/backup structures
+!!      Modification   03/2017   (JP Chaboureau) Fix the initialization of
+!!                                               LUSERx-type variables for LIMA
+!!      M.Leriche      06/2017 for spawn and prep_real avoid abort if wet dep for 
+!!                             aerosol and no cloud scheme defined
+!!      Q.Libois       02/2018  ECRAD
+!!  Philippe Wautelet: 05/2016-04/2018: new data structures and calls for I/O
+!!      Modification   07/2017   (V. Vionnet) add blowing snow scheme
+!!      Modification   01/2019   (Q. Rodier) define XCEDIS depending on BL89 or RM17 mixing length
+!!      Modification   01/2019   (P. Wautelet) bugs correction: incorrect writes
+!!      Modification   01/2019   (R. Honnert) remove SURF in CMF_UPDRAFT
+!!      Bielli S. 02/2019  Sea salt : significant sea wave height influences salt emission; 5 salt modes
+!  P. Wautelet 10/04/2019: replace ABORT and STOP calls by Print_msg
+!!------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+USE MODD_PARAMETERS
+USE MODD_CONF
+USE MODD_CONFZ
+USE MODD_CONF_n,  ONLY: CSTORAGE_TYPE
+USE MODD_IO,   ONLY: TFILEDATA
+USE MODD_LUNIT_n, ONLY: TLUOUT
+USE MODD_VAR_ll,  ONLY: NPROC
+!
+USE MODN_BACKUP
+USE MODN_BUDGET
+USE MODN_LES
+USE MODN_CONF
+USE MODN_CONFZ
+USE MODN_FRC
+USE MODN_DYN
+USE MODN_NESTING
+USE MODN_OUTPUT
+USE MODN_CONF_n
+USE MODN_LBC_n      ! routine is used for each nested model. This has been done 
+USE MODN_DYN_n      ! to avoid the duplication of this routine for each model.
+USE MODN_ADV_n      ! The final filling of these modules for the model n is
+USE MODN_PARAM_n    ! realized in subroutine ini_model n
+USE MODN_PARAM_RAD_n
+USE MODN_PARAM_ECRAD_n
+USE MODN_PARAM_KAFR_n
+USE MODN_PARAM_MFSHALL_n
+USE MODN_PARAM_ICE
+USE MODN_LUNIT_n
+USE MODN_NUDGING_n
+USE MODN_TURB_n
+USE MODN_DRAG_n
+USE MODN_BLANK
+USE MODN_CH_MNHC_n
+USE MODN_CH_SOLVER_n
+USE MODN_PARAM_C2R2, ONLY : EPARAM_CCN=>HPARAM_CCN, EINI_CCN=>HINI_CCN, &
+                            WNUC=>XNUC, WALPHAC=>XALPHAC, NAM_PARAM_C2R2
+USE MODN_PARAM_C1R3, ONLY : NAM_PARAM_C1R3, CPRISTINE_ICE_C1R3,    &
+                            CHEVRIMED_ICE_C1R3
+USE MODN_PARAM_LIMA, ONLY : FINI_CCN=>HINI_CCN,NAM_PARAM_LIMA,NMOD_CCN,LSCAV, &
+                            CPRISTINE_ICE_LIMA, CHEVRIMED_ICE_LIMA, NMOD_IFN, &
+                            LCOLD, LACTI, LNUCL, XALPHAC, XNUC, LMEYERS, LHAIL
+USE MODN_ELEC
+USE MODN_SERIES
+USE MODN_SERIES_n 
+USE MODN_TURB_CLOUD
+USE MODN_TURB
+USE MODN_MEAN
+USE MODN_DRAGTREE
+USE MODN_LATZ_EDFLX
+!
+USE MODD_NSV,NSV_USER_n=>NSV_USER
+USE MODD_DYN
+USE MODD_DYN_n, ONLY : LHORELAX_SVLIMA
+USE MODD_GET_n
+USE MODD_GR_FIELD_n
+!
+USE MODE_POS
+USE MODE_MSG
+!
+USE MODI_TEST_NAM_VAR
+USE MODI_INI_NSV
+USE MODI_CH_INIT_SCHEME_n
+USE MODN_CH_ORILAM
+USE MODD_CH_AEROSOL
+USE MODD_DUST
+USE MODD_SALT
+USE MODD_PASPOL
+#ifdef MNH_FOREFIRE
+USE MODD_FOREFIRE
+USE MODN_FOREFIRE
+#endif
+USE MODD_CONDSAMP
+USE MODD_BLOWSNOW
+USE MODN_DUST
+USE MODN_SALT
+USE MODD_CH_M9_n, ONLY : NEQ
+USE MODN_PASPOL
+USE MODN_CONDSAMP
+USE MODN_BLOWSNOW
+USE MODN_BLOWSNOW_n
+USE MODN_2D_FRC
+USE MODN_VISCOSITY
+USE MODD_VISCOSITY
+USE MODD_DRAG_n
+!
+IMPLICIT NONE
+!
+!*       0.1   declarations of arguments
+!
+!
+!
+INTEGER,            INTENT(IN) :: KMI    ! Model index
+TYPE(TFILEDATA),    INTENT(IN) :: TPEXSEGFILE ! EXSEG file
+!     The following variables are read by READ_DESFM in DESFM descriptor : 
+CHARACTER (LEN=*),  INTENT(IN) :: HCONF  ! configuration var. linked to FMfile
+LOGICAL,            INTENT(IN) :: OFLAT  ! Logical for zero orography
+LOGICAL,            INTENT(IN) :: OUSERV,OUSERC,OUSERR,OUSERI,OUSERS, &
+                                  OUSERG,OUSERH  ! kind of moist variables in 
+                                                 ! FMfile
+LOGICAL,            INTENT(IN) :: OUSECI         ! ice concentration in
+                                                 ! FMfile
+LOGICAL,            INTENT(IN) :: OUSECHEM       ! Chemical FLAG in FMFILE
+LOGICAL,            INTENT(IN) :: OUSECHAQ       ! Aqueous chemical FLAG in FMFILE
+LOGICAL,            INTENT(IN) :: OUSECHIC       ! Ice chemical FLAG in FMFILE
+LOGICAL,            INTENT(IN) :: OCH_PH         ! pH FLAG in FMFILE
+LOGICAL,            INTENT(IN) :: OCH_CONV_LINOX ! LiNOx FLAG in FMFILE
+LOGICAL,            INTENT(IN) :: ODUST          ! Dust FLAG in FMFILE
+LOGICAL,DIMENSION(:), INTENT(IN) :: ODEPOS_DST   ! Dust Deposition FLAG in FMFILE
+LOGICAL,DIMENSION(:), INTENT(IN) :: ODEPOS_SLT   ! Sea Salt wet deposition FLAG in FMFILE     
+LOGICAL,DIMENSION(:), INTENT(IN) :: ODEPOS_AER   ! Orilam wet deposition FLAG in FMFILE     
+LOGICAL,            INTENT(IN) :: OSALT          ! Sea Salt FLAG in FMFILE
+LOGICAL,            INTENT(IN) :: OORILAM        ! Orilam FLAG in FMFILE
+LOGICAL,            INTENT(IN) :: OPASPOL        ! Passive pollutant FLAG in FMFILE
+#ifdef MNH_FOREFIRE
+LOGICAL,            INTENT(IN) :: OFOREFIRE      ! ForeFire FLAG in FMFILE
+#endif
+LOGICAL,            INTENT(IN) :: OLNOX_EXPLICIT ! explicit LNOx FLAG in FMFILE
+LOGICAL,            INTENT(IN) :: OCONDSAMP      ! Conditional sampling FLAG in FMFILE
+LOGICAL,            INTENT(IN) :: OCHTRANS       ! LCHTRANS FLAG in FMFILE
+LOGICAL,            INTENT(IN) :: OBLOWSNOW     ! Blowing snow FLAG in FMFILE
+
+LOGICAL,            INTENT(IN) :: OLG            ! lagrangian FLAG in FMFILE
+INTEGER,            INTENT(IN) :: KRIMX, KRIMY   ! number of points for the
+                       ! horizontal relaxation for the outermost verticals
+INTEGER,            INTENT(IN) :: KSV_USER    ! number of additional scalar
+                                         ! variables in FMfile 
+CHARACTER (LEN=*),  INTENT(IN) :: HTURB  ! Kind of turbulence parameterization
+                                         ! used to  produce FMFILE
+CHARACTER (LEN=*),  INTENT(IN) :: HTOM   ! Kind of third order moment
+LOGICAL,            INTENT(IN) :: ORMC01 ! flag for RMC01 SBL computations
+CHARACTER (LEN=*),  INTENT(IN) :: HRAD   ! Kind of radiation scheme
+CHARACTER (LEN=4),  INTENT(IN) :: HDCONV ! Kind of deep convection scheme
+CHARACTER (LEN=4),  INTENT(IN) :: HSCONV ! Kind of shallow convection scheme
+CHARACTER (LEN=4),  INTENT(IN) :: HCLOUD ! Kind of microphysical scheme
+CHARACTER (LEN=4),  INTENT(IN) :: HELEC  ! Kind of electrical scheme
+CHARACTER (LEN=*),  INTENT(IN) :: HEQNSYS! type of equations' system
+REAL,DIMENSION(:),  INTENT(INOUT):: PTSTEP_ALL ! Time STEP of ALL models
+CHARACTER (LEN=*),  INTENT(IN) :: HSTORAGE_TYPE ! type of initial file
+CHARACTER (LEN=*),  INTENT(IN) :: HINIFILEPGD ! name of PGD file
+!
+!*       0.2   declarations of local variables
+!
+INTEGER :: ILUSEG,ILUOUT ! logical unit numbers of EXSEG file and outputlisting
+INTEGER :: JS,JCI,JI,JSV       ! Loop indexes 
+LOGICAL :: GRELAX              
+LOGICAL :: GFOUND              ! Return code when searching namelist
+!
+INTEGER :: IMOMENTS, JMODE, IMODEIDX, JMOM, JSV_NAME, JMOD, I
+!
+!-------------------------------------------------------------------------------
+!
+!*       1.    READ EXSEG FILE
+!              ---------------
+!
+CALL PRINT_MSG(NVERB_DEBUG,'IO','READ_EXSEG_n','called for '//TRIM(TPEXSEGFILE%CNAME))
+!
+ILUSEG = TPEXSEGFILE%NLU
+ILUOUT = TLUOUT%NLU
+!
+CALL INIT_NAM_LUNITN
+CCPLFILE(:)="                            "
+CALL INIT_NAM_CONFN
+CALL INIT_NAM_DYNN
+CALL INIT_NAM_ADVN
+CALL INIT_NAM_PARAMN
+CALL INIT_NAM_PARAM_RADN
+#ifdef MNH_ECRAD
+CALL INIT_NAM_PARAM_ECRADN
+#endif
+CALL INIT_NAM_PARAM_KAFRN
+CALL INIT_NAM_PARAM_MFSHALLN
+CALL INIT_NAM_LBCN
+CALL INIT_NAM_NUDGINGN
+CALL INIT_NAM_TURBN
+CALL INIT_NAM_DRAGN
+CALL INIT_NAM_CH_MNHCN
+CALL INIT_NAM_CH_SOLVERN
+CALL INIT_NAM_SERIESN
+CALL INIT_NAM_BLOWSNOWN
+!
+WRITE(UNIT=ILUOUT,FMT="(/,'READING THE EXSEG.NAM FILE')")
+CALL POSNAM(ILUSEG,'NAM_LUNITN',GFOUND,ILUOUT)
+IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_LUNITn)
+CALL POSNAM(ILUSEG,'NAM_CONFN',GFOUND,ILUOUT)
+IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_CONFn)
+CALL POSNAM(ILUSEG,'NAM_DYNN',GFOUND,ILUOUT)
+IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_DYNn)
+CALL POSNAM(ILUSEG,'NAM_ADVN',GFOUND,ILUOUT)
+IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_ADVn)
+CALL POSNAM(ILUSEG,'NAM_PARAMN',GFOUND,ILUOUT)
+IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_PARAMn)
+CALL POSNAM(ILUSEG,'NAM_PARAM_RADN',GFOUND,ILUOUT)
+IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_PARAM_RADn)
+#ifdef MNH_ECRAD
+CALL POSNAM(ILUSEG,'NAM_PARAM_ECRADN',GFOUND,ILUOUT)
+IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_PARAM_ECRADn)
+#endif
+CALL POSNAM(ILUSEG,'NAM_PARAM_KAFRN',GFOUND,ILUOUT)
+IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_PARAM_KAFRn)
+CALL POSNAM(ILUSEG,'NAM_PARAM_MFSHALLN',GFOUND,ILUOUT)
+IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_PARAM_MFSHALLn)
+CALL POSNAM(ILUSEG,'NAM_LBCN',GFOUND,ILUOUT)
+IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_LBCn)
+CALL POSNAM(ILUSEG,'NAM_NUDGINGN',GFOUND,ILUOUT)
+IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_NUDGINGn)
+CALL POSNAM(ILUSEG,'NAM_TURBN',GFOUND,ILUOUT)
+IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_TURBn)
+CALL POSNAM(ILUSEG,'NAM_DRAGN',GFOUND,ILUOUT)
+IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_DRAGn)
+CALL POSNAM(ILUSEG,'NAM_CH_MNHCN',GFOUND,ILUOUT)
+IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_CH_MNHCn)
+CALL POSNAM(ILUSEG,'NAM_CH_SOLVERN',GFOUND,ILUOUT)
+IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_CH_SOLVERn)
+CALL POSNAM(ILUSEG,'NAM_SERIESN',GFOUND,ILUOUT)
+IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_SERIESn)
+CALL POSNAM(ILUSEG,'NAM_BLOWSNOWN',GFOUND,ILUOUT)
+IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_BLOWSNOWn)
+!
+IF (KMI == 1) THEN                                               
+  WRITE(UNIT=ILUOUT,FMT="(' namelists common to all the models ')")
+  CALL POSNAM(ILUSEG,'NAM_CONF',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_CONF)
+  CALL POSNAM(ILUSEG,'NAM_CONFZ',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_CONFZ)
+  CALL POSNAM(ILUSEG,'NAM_DYN',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_DYN)
+  CALL POSNAM(ILUSEG,'NAM_NESTING',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_NESTING)
+  CALL POSNAM(ILUSEG,'NAM_BACKUP',GFOUND,ILUOUT)
+  IF (GFOUND) THEN
+    !Should have been allocated before in READ_DESFM_n
+    IF (.NOT.ALLOCATED(XBAK_TIME)) THEN
+      ALLOCATE(XBAK_TIME(NMODEL,JPOUTMAX))
+      XBAK_TIME(:,:) = XNEGUNDEF
+    END IF
+    IF (.NOT.ALLOCATED(XOUT_TIME)) THEN
+      ALLOCATE(XOUT_TIME(NMODEL,JPOUTMAX)) !Allocate *OUT* variables to prevent
+      XOUT_TIME(:,:) = XNEGUNDEF
+    END IF
+    IF (.NOT.ALLOCATED(NBAK_STEP)) THEN
+      ALLOCATE(NBAK_STEP(NMODEL,JPOUTMAX))
+      NBAK_STEP(:,:) = NNEGUNDEF
+    END IF
+    IF (.NOT.ALLOCATED(NOUT_STEP)) THEN
+      ALLOCATE(NOUT_STEP(NMODEL,JPOUTMAX)) !problems if NAM_OUTPUT does not exist
+      NOUT_STEP(:,:) = NNEGUNDEF
+    END IF
+    IF (.NOT.ALLOCATED(COUT_VAR)) THEN
+      ALLOCATE(COUT_VAR (NMODEL,JPOUTVARMAX))
+      COUT_VAR(:,:)  = ''
+    END IF
+    READ(UNIT=ILUSEG,NML=NAM_BACKUP)
+  ELSE
+    CALL POSNAM(ILUSEG,'NAM_FMOUT',GFOUND)
+    IF (GFOUND) THEN
+      CALL PRINT_MSG(NVERB_FATAL,'IO','READ_EXSEG_n','use namelist NAM_BACKUP instead of namelist NAM_FMOUT')
+    ELSE
+      IF (CPROGRAM=='MESONH') CALL PRINT_MSG(NVERB_ERROR,'IO','READ_EXSEG_n','namelist NAM_BACKUP not found')
+    END IF
+  END IF
+  CALL POSNAM(ILUSEG,'NAM_OUTPUT',GFOUND,ILUOUT)
+  IF (GFOUND) THEN
+    !Should have been allocated before in READ_DESFM_n
+    IF (.NOT.ALLOCATED(XBAK_TIME)) THEN
+      ALLOCATE(XBAK_TIME(NMODEL,JPOUTMAX)) !Allocate *BAK* variables to prevent
+      XBAK_TIME(:,:) = XNEGUNDEF
+    END IF
+    IF (.NOT.ALLOCATED(XOUT_TIME)) THEN
+      ALLOCATE(XOUT_TIME(NMODEL,JPOUTMAX))
+      XOUT_TIME(:,:) = XNEGUNDEF
+    END IF
+    IF (.NOT.ALLOCATED(NBAK_STEP)) THEN
+      ALLOCATE(NBAK_STEP(NMODEL,JPOUTMAX)) !problems if NAM_BACKUP does not exist
+      NBAK_STEP(:,:) = NNEGUNDEF
+    END IF
+    IF (.NOT.ALLOCATED(NOUT_STEP)) THEN
+      ALLOCATE(NOUT_STEP(NMODEL,JPOUTMAX))
+      NOUT_STEP(:,:) = NNEGUNDEF
+    END IF
+    IF (.NOT.ALLOCATED(COUT_VAR)) THEN
+      ALLOCATE(COUT_VAR (NMODEL,JPOUTVARMAX))
+      COUT_VAR(:,:)  = ''
+    END IF
+    READ(UNIT=ILUSEG,NML=NAM_OUTPUT)
+  END IF
+  CALL POSNAM(ILUSEG,'NAM_BUDGET',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_BUDGET)
+  CALL POSNAM(ILUSEG,'NAM_BU_RU',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_BU_RU)
+  CALL POSNAM(ILUSEG,'NAM_BU_RV',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_BU_RV)
+  CALL POSNAM(ILUSEG,'NAM_BU_RW',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_BU_RW)
+  CALL POSNAM(ILUSEG,'NAM_BU_RTH',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_BU_RTH)
+  CALL POSNAM(ILUSEG,'NAM_BU_RTKE',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_BU_RTKE)
+  CALL POSNAM(ILUSEG,'NAM_BU_RRV',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_BU_RRV)
+  CALL POSNAM(ILUSEG,'NAM_BU_RRC',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_BU_RRC)
+  CALL POSNAM(ILUSEG,'NAM_BU_RRR',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_BU_RRR)
+  CALL POSNAM(ILUSEG,'NAM_BU_RRI',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_BU_RRI)
+  CALL POSNAM(ILUSEG,'NAM_BU_RRS',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_BU_RRS)
+  CALL POSNAM(ILUSEG,'NAM_BU_RRG',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_BU_RRG)
+  CALL POSNAM(ILUSEG,'NAM_BU_RRH',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_BU_RRH)
+  CALL POSNAM(ILUSEG,'NAM_BU_RSV',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_BU_RSV)
+  CALL POSNAM(ILUSEG,'NAM_LES',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_LES)
+  CALL POSNAM(ILUSEG,'NAM_MEAN',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_MEAN)
+  CALL POSNAM(ILUSEG,'NAM_PDF',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_PDF)
+  CALL POSNAM(ILUSEG,'NAM_BLANK',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_BLANK)
+  CALL POSNAM(ILUSEG,'NAM_FRC',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_FRC)
+  CALL POSNAM(ILUSEG,'NAM_PARAM_ICE',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_PARAM_ICE)
+  CALL POSNAM(ILUSEG,'NAM_PARAM_C2R2',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_PARAM_C2R2)
+  CALL POSNAM(ILUSEG,'NAM_PARAM_C1R3',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_PARAM_C1R3)
+  CALL POSNAM(ILUSEG,'NAM_PARAM_LIMA',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_PARAM_LIMA)
+  CALL POSNAM(ILUSEG,'NAM_ELEC',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_ELEC)
+  CALL POSNAM(ILUSEG,'NAM_SERIES',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_SERIES)
+  CALL POSNAM(ILUSEG,'NAM_TURB_CLOUD',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_TURB_CLOUD)
+  CALL POSNAM(ILUSEG,'NAM_TURB',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_TURB)
+  CALL POSNAM(ILUSEG,'NAM_CH_ORILAM',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_CH_ORILAM)
+  CALL POSNAM(ILUSEG,'NAM_DUST',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_DUST)
+  CALL POSNAM(ILUSEG,'NAM_SALT',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_SALT)
+  CALL POSNAM(ILUSEG,'NAM_PASPOL',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_PASPOL)
+#ifdef MNH_FOREFIRE
+  CALL POSNAM(ILUSEG,'NAM_FOREFIRE',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_FOREFIRE)
+#endif
+  CALL POSNAM(ILUSEG,'NAM_CONDSAMP',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_CONDSAMP)
+  CALL POSNAM(ILUSEG,'NAM_DRAGTREE',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_DRAGTREE)
+  CALL POSNAM(ILUSEG,'NAM_2D_FRC',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_2D_FRC)
+  CALL POSNAM(ILUSEG,'NAM_LATZ_EDFLX',GFOUND)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_LATZ_EDFLX)
+  CALL POSNAM(ILUSEG,'NAM_BLOWSNOW',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_BLOWSNOW)
+  CALL POSNAM(ILUSEG,'NAM_VISC',GFOUND,ILUOUT)
+  IF (GFOUND) READ(UNIT=ILUSEG,NML=NAM_VISC)
+END IF
+!
+!-------------------------------------------------------------------------------
+!
+CALL TEST_NAM_VAR(ILUOUT,'CPRESOPT',CPRESOPT,'RICHA','CGRAD','CRESI','ZRESI','ZSOLV',&
+                         'ZGRAD')
+!
+CALL TEST_NAM_VAR(ILUOUT,'CUVW_ADV_SCHEME',CUVW_ADV_SCHEME, &
+       'CEN4TH','CEN2ND','WENO_K' ) 
+CALL TEST_NAM_VAR(ILUOUT,'CMET_ADV_SCHEME',CMET_ADV_SCHEME, &
+      &'PPM_00','PPM_01','PPM_02')
+CALL TEST_NAM_VAR(ILUOUT,'CSV_ADV_SCHEME',CSV_ADV_SCHEME,   &
+      &'PPM_00','PPM_01','PPM_02')
+CALL TEST_NAM_VAR(ILUOUT,'CTEMP_SCHEME',CTEMP_SCHEME,       &
+  &'RK11','RK21','RK33','RKC4','RK53','RK4B','RK62','RK65','NP32','SP32','LEFR')
+!
+CALL TEST_NAM_VAR(ILUOUT,'CTURB',CTURB,'NONE','TKEL')
+CALL TEST_NAM_VAR(ILUOUT,'CRAD',CRAD,'NONE','FIXE','ECMW',&
+#ifdef MNH_ECRAD
+                 'ECRA',&
+#endif
+                 'TOPA')
+CALL TEST_NAM_VAR(ILUOUT,'CCLOUD',CCLOUD,'NONE','REVE','KESS',  &
+      & 'ICE3','ICE4','C2R2','C3R5','KHKO','LIMA')
+CALL TEST_NAM_VAR(ILUOUT,'CDCONV',CDCONV,'NONE','KAFR')
+CALL TEST_NAM_VAR(ILUOUT,'CSCONV',CSCONV,'NONE','KAFR','EDKF')
+CALL TEST_NAM_VAR(ILUOUT,'CELEC',CELEC,'NONE','ELE3','ELE4')
+!
+CALL TEST_NAM_VAR(ILUOUT,'CAER',CAER,'TANR','TEGE','SURF','NONE')
+CALL TEST_NAM_VAR(ILUOUT,'CAOP',CAOP,'CLIM','EXPL')
+CALL TEST_NAM_VAR(ILUOUT,'CLW',CLW,'RRTM','MORC')
+CALL TEST_NAM_VAR(ILUOUT,'CEFRADL',CEFRADL,'PRES','OCLN','MART','C2R2','LIMA')
+CALL TEST_NAM_VAR(ILUOUT,'CEFRADI',CEFRADI,'FX40','LIOU','SURI','C3R5','LIMA')
+CALL TEST_NAM_VAR(ILUOUT,'COPWLW',COPWLW,'SAVI','SMSH','LILI','MALA')
+CALL TEST_NAM_VAR(ILUOUT,'COPILW',COPILW,'FULI','EBCU','SMSH','FU98')
+CALL TEST_NAM_VAR(ILUOUT,'COPWSW',COPWSW,'SLIN','FOUQ','MALA')
+CALL TEST_NAM_VAR(ILUOUT,'COPISW',COPISW,'FULI','EBCU','FU96')
+!
+CALL TEST_NAM_VAR(ILUOUT,'CLBCX(1)',CLBCX(1),'CYCL','WALL','OPEN')
+CALL TEST_NAM_VAR(ILUOUT,'CLBCX(2)',CLBCX(2),'CYCL','WALL','OPEN')
+CALL TEST_NAM_VAR(ILUOUT,'CLBCY(1)',CLBCY(1),'CYCL','WALL','OPEN')
+CALL TEST_NAM_VAR(ILUOUT,'CLBCY(2)',CLBCY(2),'CYCL','WALL','OPEN')
+!
+CALL TEST_NAM_VAR(ILUOUT,'CTURBDIM',CTURBDIM,'1DIM','3DIM')
+CALL TEST_NAM_VAR(ILUOUT,'CTURBLEN',CTURBLEN,'DELT','BL89','RM17','DEAR','BLKR')
+CALL TEST_NAM_VAR(ILUOUT,'CTOM',CTOM,'NONE','TM06')
+CALL TEST_NAM_VAR(ILUOUT,'CSUBG_AUCV',CSUBG_AUCV,'NONE','CLFR','SIGM','PDF')
+!
+CALL TEST_NAM_VAR(ILUOUT,'CCH_TDISCRETIZATION',CCH_TDISCRETIZATION, &
+                 'SPLIT     ','CENTER    ','LAGGED    ')
+!
+CALL TEST_NAM_VAR(ILUOUT,'CCONF',CCONF,'START','RESTA')
+CALL TEST_NAM_VAR(ILUOUT,'CEQNSYS',CEQNSYS,'LHE','DUR','MAE')
+CALL TEST_NAM_VAR(ILUOUT,'CSPLIT',CSPLIT,'BSPLITTING','XSPLITTING','YSPLITTING')
+!
+CALL TEST_NAM_VAR(ILUOUT,'CBUTYPE',CBUTYPE,'NONE','CART','MASK')
+!
+CALL TEST_NAM_VAR(ILUOUT,'CRELAX_HEIGHT_TYPE',CRELAX_HEIGHT_TYPE,'FIXE','THGR')
+!
+CALL TEST_NAM_VAR(ILUOUT,'CLES_NORM_TYPE',CLES_NORM_TYPE,'NONE','CONV','EKMA','MOBU')
+CALL TEST_NAM_VAR(ILUOUT,'CBL_HEIGHT_DEF',CBL_HEIGHT_DEF,'TKE','KE','WTV','FRI','DTH')
+CALL TEST_NAM_VAR(ILUOUT,'CTURBLEN_CLOUD',CTURBLEN_CLOUD,'NONE','DEAR','DELT','BL89')
+!
+!   The test on the mass flux scheme for shallow convection
+!
+CALL TEST_NAM_VAR(ILUOUT,'CMF_UPDRAFT',CMF_UPDRAFT,'NONE','EDKF','RHCJ',&
+                   'HRIO','BOUT')
+CALL TEST_NAM_VAR(ILUOUT,'CMF_CLOUD',CMF_CLOUD,'NONE','STAT','DIRE')
+!
+!   The test on the CSOLVER name is made elsewhere
+!
+CALL TEST_NAM_VAR(ILUOUT,'CPRISTINE_ICE',CPRISTINE_ICE,'PLAT','COLU','BURO')
+CALL TEST_NAM_VAR(ILUOUT,'CSEDIM',CSEDIM,'SPLI','STAT','NONE')
+IF( CCLOUD == 'C3R5' ) THEN
+  CALL TEST_NAM_VAR(ILUOUT,'CPRISTINE_ICE_C1R3',CPRISTINE_ICE_C1R3, &
+                                                'PLAT','COLU','BURO')
+  CALL TEST_NAM_VAR(ILUOUT,'CHEVRIMED_ICE_C1R3',CHEVRIMED_ICE_C1R3, &
+                                                'GRAU','HAIL')
+END IF
+!
+IF( CCLOUD == 'LIMA' ) THEN
+  CALL TEST_NAM_VAR(ILUOUT,'CPRISTINE_ICE_LIMA',CPRISTINE_ICE_LIMA, &
+                                                'PLAT','COLU','BURO')
+  CALL TEST_NAM_VAR(ILUOUT,'CHEVRIMED_ICE_LIMA',CHEVRIMED_ICE_LIMA, &
+                                                'GRAU','HAIL')
+END IF
+IF(LBLOWSNOW) THEN
+       CALL TEST_NAM_VAR(ILUOUT,'CSNOWSEDIM',CSNOWSEDIM,'NONE','MITC','CARR','TABC')
+       IF (XALPHA_SNOW .NE. 3 .AND. CSNOWSEDIM=='TABC') THEN
+         WRITE(ILUOUT,*) '*****************************************'
+         WRITE(ILUOUT,*) '* XALPHA_SNW must be set to 3 when                '
+         WRITE(ILUOUT,*) '* CSNOWSEDIM = TABC                                 '
+         WRITE(ILUOUT,*) '* Update the look-up table in BLOWSNOW_SEDIM_LKT1D    '
+         WRITE(ILUOUT,*) '* to use TABC with a different value of XEMIALPHA_SNW'
+         WRITE(ILUOUT,*) '*****************************************'
+         !callabortstop
+         CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+       ENDIF
+END IF
+!
+!-------------------------------------------------------------------------------!
+!*       2.    FIRST INITIALIZATIONS
+!              ---------------------
+!
+!*       2.1   Time step in gridnesting case
+!
+IF (KMI /= 1 .AND. NDAD(KMI) /= KMI)  THEN
+  XTSTEP = PTSTEP_ALL(NDAD(KMI)) / NDTRATIO(KMI)
+END IF
+PTSTEP_ALL(KMI) = XTSTEP
+!
+!*       2.2    Fill the global configuration module 
+!
+! Check coherence between the microphysical scheme and water species and 
+!initialize the logicals LUSERn 
+!
+SELECT CASE ( CCLOUD )
+  CASE ( 'NONE' )
+    IF (.NOT. ( (.NOT. LUSERC) .AND. (.NOT. LUSERR) .AND. (.NOT. LUSERI) .AND. &
+                (.NOT. LUSERS) .AND. (.NOT. LUSERG) .AND. (.NOT. LUSERH)       &
+              ) .AND. CPROGRAM=='MESONH' )  THEN
+!
+      LUSERC=.FALSE.
+      LUSERR=.FALSE.; LUSERI=.FALSE.
+      LUSERS=.FALSE.; LUSERG=.FALSE. 
+      LUSERH=.FALSE.
+!
+    END IF
+!
+    IF (CSUBG_AUCV == 'SIGM')  THEN
+!
+      WRITE(UNIT=ILUOUT,FMT=9002) KMI
+      WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE THE SUBGRID AUTOCONVERSION SCHEME '                                         
+      WRITE(UNIT=ILUOUT,FMT=*) ' WITHOUT MICROPHYSICS'                         
+      WRITE(UNIT=ILUOUT,FMT=*) ' CSUBG_AUCV IS PUT TO "NONE"'                            
+!
+      CSUBG_AUCV = 'NONE'
+!
+    END IF
+!
+  CASE ( 'REVE' ) 
+    IF (.NOT. ( LUSERV .AND. LUSERC .AND. (.NOT. LUSERR) .AND. (.NOT. LUSERI) &
+               .AND. (.NOT. LUSERS) .AND. (.NOT. LUSERG) .AND. (.NOT. LUSERH) &
+              ) )  THEN
+!
+      WRITE(UNIT=ILUOUT,FMT=9002) KMI
+      WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE A REVERSIBLE MICROPHYSICAL "   ,&
+      &" SCHEME. YOU WILL ONLY HAVE VAPOR AND CLOUD WATER ",/,                 &
+      &" LUSERV AND LUSERC ARE TO TRUE AND THE OTHERS TO FALSE ")') 
+!
+      LUSERV=.TRUE. ; LUSERC=.TRUE.
+      LUSERR=.FALSE.; LUSERI=.FALSE.
+      LUSERS=.FALSE.; LUSERG=.FALSE. 
+      LUSERH=.FALSE.
+    END IF
+!
+    IF (CSUBG_AUCV == 'SIGM')  THEN
+!
+      WRITE(UNIT=ILUOUT,FMT=9003) KMI
+      WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE BOTH A REVERSIBLE MICROPHYSICAL SCHEME '
+      WRITE(UNIT=ILUOUT,FMT=*) ' AND THE SUBGRID AUTOCONVERSION SCHEME '       
+      WRITE(UNIT=ILUOUT,FMT=*) 'BUT YOU DO NOT HAVE RAIN in the "REVE" SCHEME'
+      WRITE(UNIT=ILUOUT,FMT=*) ' CSUBG_AUCV IS PUT TO "NONE"'                            
+!
+      CSUBG_AUCV = 'NONE'
+!
+    END IF
+!
+  CASE ( 'KESS' )
+    IF (.NOT. ( LUSERV .AND. LUSERC .AND. LUSERR .AND. (.NOT. LUSERI) .AND. &
+              (.NOT. LUSERS) .AND. (.NOT. LUSERG) .AND. (.NOT. LUSERH)      &
+              ) )  THEN
+!
+      WRITE(UNIT=ILUOUT,FMT=9002) KMI
+      WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE A KESSLER MICROPHYSICAL "   , &
+      &" SCHEME. YOU WILL ONLY HAVE VAPOR, CLOUD WATER AND RAIN ",/,           &
+      &" LUSERV, LUSERC AND LUSERR ARE SET TO TRUE AND THE OTHERS TO FALSE ")') 
+!
+      LUSERV=.TRUE. ; LUSERC=.TRUE. ; LUSERR=.TRUE.
+      LUSERI=.FALSE.; LUSERS=.FALSE.
+      LUSERG=.FALSE.; LUSERH=.FALSE.
+    END IF
+!
+    IF (CSUBG_AUCV == 'SIGM')  THEN
+!
+      WRITE(UNIT=ILUOUT,FMT=9003) KMI
+      WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE BOTH A KESSLER MICROPHYSICAL SCHEME '
+      WRITE(UNIT=ILUOUT,FMT=*) ' AND THE SUBGRID AUTOCONVERSION SCHEME USING'
+      WRITE(UNIT=ILUOUT,FMT=*) 'SIGMA_RC.'
+      WRITE(UNIT=ILUOUT,FMT=*) 'THIS IS NOT YET AVAILABLE.'
+      WRITE(UNIT=ILUOUT,FMT=*) 'SET CSUBG_AUCV TO "CLFR" or "NONE"  OR CCLOUD TO "ICE3"'
+!
+ !callabortstop
+      CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+    END IF
+!
+  CASE ( 'ICE3' )
+    IF (.NOT. ( LUSERV .AND. LUSERC .AND. LUSERR .AND. LUSERI .AND. LUSECI &
+                       .AND. LUSERS .AND. LUSERG .AND. (.NOT. LUSERH))     &
+                .AND. CPROGRAM=='MESONH' )  THEN
+      !
+      WRITE(UNIT=ILUOUT,FMT=9002) KMI
+      WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE THE ice3 SIMPLE MIXED PHASE'
+      WRITE(UNIT=ILUOUT,FMT=*) 'MICROPHYSICAL SCHEME. YOU WILL ONLY HAVE VAPOR, CLOUD WATER,'
+      WRITE(UNIT=ILUOUT,FMT=*) 'RAIN WATER, CLOUD ICE (MIXING RATIO AND CONCENTRATION)'
+      WRITE(UNIT=ILUOUT,FMT=*) 'SNOW-AGGREGATES AND GRAUPELN.'
+      WRITE(UNIT=ILUOUT,FMT=*) 'LUSERV,LUSERC,LUSERR,LUSERI,LUSECI,LUSERS,LUSERG ARE SET TO TRUE'
+      WRITE(UNIT=ILUOUT,FMT=*) 'AND LUSERH TO FALSE'
+!
+      LUSERV=.TRUE. ; LUSERC=.TRUE. ; LUSERR=.TRUE.
+      LUSERI=.TRUE. ; LUSECI=.TRUE.
+      LUSERS=.TRUE. ; LUSERG=.TRUE. 
+      LUSERH=.FALSE.
+    END IF    
+!
+    IF (CSUBG_AUCV == 'SIGM' .AND. .NOT. LSUBG_COND)  THEN
+      WRITE(UNIT=ILUOUT,FMT=9002) KMI
+      WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE SUBGRID AUTOCONVERSION SCHEME'
+      WRITE(UNIT=ILUOUT,FMT=*) ' WITHOUT THE SUBGRID CONDENSATION SCHEME.'
+      WRITE(UNIT=ILUOUT,FMT=*) 'THIS IS NOT ALLOWED: CSUBG_AUCV is SET to NONE' 
+      CSUBG_AUCV='NONE' 
+    END IF
+!
+    IF (CSUBG_AUCV == 'CLFR' .AND. CSCONV /= 'EDKF')  THEN
+      WRITE(UNIT=ILUOUT,FMT=9002) KMI
+      WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE SUBGRID AUTOCONVERSION SCHEME'
+      WRITE(UNIT=ILUOUT,FMT=*) 'WITH THE CONVECTIVE CLOUD FRACTION WITHOUT EDKF'
+      WRITE(UNIT=ILUOUT,FMT=*) 'THIS IS NOT ALLOWED: CSUBG_AUCV is SET to NONE' 
+      CSUBG_AUCV='NONE' 
+    END IF
+!
+  CASE ( 'ICE4' )
+    IF (.NOT. ( LUSERV .AND. LUSERC .AND. LUSERR .AND. LUSERI .AND. LUSECI &
+                       .AND. LUSERS .AND. LUSERG .AND. LUSERH)             &
+                .AND. CPROGRAM=='MESONH' )  THEN
+      !
+      WRITE(UNIT=ILUOUT,FMT=9002) KMI
+      WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE THE ice4 SIMPLE MIXED PHASE'
+      WRITE(UNIT=ILUOUT,FMT=*) 'MICROPHYSICAL SCHEME. YOU WILL ONLY HAVE VAPOR, CLOUD WATER,'
+      WRITE(UNIT=ILUOUT,FMT=*) 'RAIN WATER, CLOUD ICE (MIXING RATIO AND CONCENTRATION)'
+      WRITE(UNIT=ILUOUT,FMT=*) 'SNOW-AGGREGATES, GRAUPELN AND HAILSTONES.'
+      WRITE(UNIT=ILUOUT,FMT=*) 'LUSERV,LUSERC,LUSERR,LUSERI,LUSECI,LUSERS,LUSERG'
+      WRITE(UNIT=ILUOUT,FMT=*) 'AND LUSERH ARE SET TO TRUE'
+!
+      LUSERV=.TRUE. ; LUSERC=.TRUE. ; LUSERR=.TRUE.
+      LUSERI=.TRUE. ; LUSECI=.TRUE.
+      LUSERS=.TRUE. ; LUSERG=.TRUE. ; LUSERH=.TRUE.
+    END IF
+!
+    IF (CSUBG_AUCV /= 'NONE' .AND. .NOT. LSUBG_COND)  THEN
+      WRITE(UNIT=ILUOUT,FMT=9002) KMI
+      WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE SUBGRID AUTOCONVERSION SCHEME'
+      WRITE(UNIT=ILUOUT,FMT=*) ' WITHOUT THE SUBGRID CONDENSATION SCHEME.'
+      WRITE(UNIT=ILUOUT,FMT=*) 'THIS IS NOT ALLOWED: CSUBG_AUCV is SET to NONE' 
+      CSUBG_AUCV='NONE' 
+    END IF
+!
+  CASE ( 'C2R2','C3R5', 'KHKO' )
+    IF (( EPARAM_CCN == 'XXX') .OR. (EINI_CCN  == 'XXX')) THEN
+          WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE A 2-MOMENT MICROPHYSICAL ",    &
+         &" SCHEME BUT YOU DIDNT FILL CORRECTLY NAM_PARAM_C2R2", &
+         &" YOU HAVE TO FILL HPARAM_CCN and HINI_CCN ")')
+ !callabortstop
+        CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+    END IF
+    IF (HCLOUD == 'NONE') THEN
+      CGETCLOUD = 'SKIP'
+    ELSE IF (HCLOUD == 'REVE' ) THEN
+      CGETCLOUD = 'INI1'
+    ELSE IF (HCLOUD == 'KESS' ) THEN
+      CGETCLOUD = 'INI2'
+    ELSE IF (HCLOUD == 'ICE3' ) THEN
+      IF (CCLOUD == 'C3R5') THEN
+        CGETCLOUD = 'INI2'
+      ELSE
+        WRITE(UNIT=ILUOUT,FMT=9003) KMI
+        WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE THE WARM MICROPHYSICAL ",    &
+        &" SCHEME BUT YOU WERE USING THE ICE3 SCHEME PREVIOUSLY.",/,          &
+        &" AS THIS IS A LITTLE BIT STUPID IT IS NOT AUTHORIZED !!!")')
+ !callabortstop
+        CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+      END IF
+    ELSE
+      CGETCLOUD = 'READ' ! This is automatically done
+    END IF
+!
+    IF ((CCLOUD == 'C2R2' ).OR. (CCLOUD == 'KHKO' )) THEN
+      IF (.NOT. ( LUSERV .AND. LUSERC .AND. LUSERR .AND. (.NOT. LUSERI) .AND. &
+                (.NOT. LUSERS) .AND. (.NOT. LUSERG) .AND. (.NOT. LUSERH)      &
+                ) )  THEN
+        WRITE(UNIT=ILUOUT,FMT=9002) KMI
+        WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE THE C2R2 MICROPHYSICAL ",    &
+        &" SCHEME. YOU WILL ONLY HAVE VAPOR, CLOUD WATER AND RAIN ",/,        &
+        &"LUSERV, LUSERC AND LUSERR ARE SET TO TRUE AND THE OTHERS TO FALSE ")')
+!
+        LUSERV=.TRUE. ; LUSERC=.TRUE. ; LUSERR=.TRUE.
+        LUSERI=.FALSE.; LUSERS=.FALSE.
+        LUSERG=.FALSE.; LUSERH=.FALSE.
+      END IF
+    ELSE IF (CCLOUD == 'C3R5') THEN
+      IF (.NOT. ( LUSERV .AND. LUSERC .AND. LUSERR .AND. LUSERI .AND. &
+                  LUSERS .AND. LUSERG .AND. (.NOT. LUSERH)            &
+                ) )  THEN
+        WRITE(UNIT=ILUOUT,FMT=9002) KMI
+        WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE THE C3R5 MICROPHYS. SCHEME.",&
+        &" YOU WILL HAVE VAPOR, CLOUD WATER/ICE, RAIN, SNOW AND GRAUPEL ",/,  &
+        &"LUSERV, LUSERC, LUSERR, LUSERI, LUSERS, LUSERG ARE SET TO TRUE")' )
+!
+        LUSERV=.TRUE. ; LUSERC=.TRUE. ; LUSERR=.TRUE.
+        LUSERI=.TRUE. ; LUSECI=.TRUE.
+        LUSERS=.TRUE. ; LUSERG=.TRUE.
+        LUSERH=.FALSE.
+      END IF
+    ELSE IF (CCLOUD == 'LIMA') THEN
+      IF (.NOT. ( LUSERV .AND. LUSERC .AND. LUSERR .AND. LUSERI .AND. &
+                  LUSERS .AND. LUSERG .AND. (.NOT. LUSERH)            &
+                ) )  THEN
+        WRITE(UNIT=ILUOUT,FMT=9002) KMI
+        WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE THE LIMA MICROPHYS. SCHEME.",&
+        &" YOU WILL HAVE VAPOR, CLOUD WATER/ICE, RAIN, SNOW AND GRAUPEL ",/,  &
+        &"LUSERV, LUSERC, LUSERR, LUSERI, LUSERS, LUSERG ARE SET TO TRUE")' )
+!
+        LUSERV=.TRUE. ; LUSERC=.TRUE. ; LUSERR=.TRUE.
+        LUSERI=.TRUE. ; LUSECI=.TRUE.        
+        LUSERS=.TRUE. ; LUSERG=.TRUE. 
+        LUSERH=.FALSE.
+      END IF
+    END IF
+!
+    IF (LSUBG_COND)  THEN
+      WRITE(UNIT=ILUOUT,FMT=9003) KMI
+      WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE BOTH THE SIMPLE MIXED PHASE'
+      WRITE(UNIT=ILUOUT,FMT=*) 'MICROPHYS. SCHEME AND THE SUBGRID COND. SCHEME.'
+      WRITE(UNIT=ILUOUT,FMT=*) 'THIS IS NOT YET AVAILABLE.'
+      WRITE(UNIT=ILUOUT,FMT=*) 'SET LSUBG_COND TO FALSE OR CCLOUD TO "REVE", "KESS"' 
+ !callabortstop
+      CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+    END IF
+!
+    IF ( CEFRADL /= 'C2R2') THEN
+      WRITE(UNIT=ILUOUT,FMT=9001) KMI
+      WRITE(UNIT=ILUOUT,FMT=*) ' YOU DID NOT CHOOSE CEFRADL=C2R2 FOR RADIATION'
+      WRITE(UNIT=ILUOUT,FMT=*) ' IT IS ADVISED TO USE CEFRADL=C2R2 '                       
+      WRITE(UNIT=ILUOUT,FMT=*) ' WITH A 2-MOMENT MICROPHYSICAL SCHEME'                     
+    END IF
+!
+    IF ( CCLOUD == 'C3R5' .AND. CEFRADI /= 'C3R5') THEN
+      WRITE(UNIT=ILUOUT,FMT=9001) KMI
+      WRITE(UNIT=ILUOUT,FMT=*) ' YOU DID NOT CHOOSE CEFRADI=C3R5 FOR RADIATION'
+      WRITE(UNIT=ILUOUT,FMT=*) ' IT IS ADVISED TO USE CEFRADI=C3R5 '                       
+      WRITE(UNIT=ILUOUT,FMT=*) ' WITH A 2-MOMENT MICROPHYSICAL SCHEME'                     
+    END IF
+!
+   IF ( WALPHAC /= 3.0 .OR. WNUC /= 2.0) THEN
+      WRITE(UNIT=ILUOUT,FMT=9001) KMI
+      WRITE(UNIT=ILUOUT,FMT=*) 'IT IS ADVISED TO USE XALPHAC=3. and XNUC=2.'
+      WRITE(UNIT=ILUOUT,FMT=*) 'FOR STRATOCUMULUS WITH KHKO SCHEME. '
+   END IF
+!
+   IF ( CEFRADL /= 'C2R2') THEN
+      WRITE(UNIT=ILUOUT,FMT=9001) KMI
+      WRITE(UNIT=ILUOUT,FMT=*) ' YOU DID NOT CHOOSE CEFRADL=C2R2 FOR RADIATION'
+      WRITE(UNIT=ILUOUT,FMT=*) ' IT IS ADVISED TO USE CEFRADL=C2R2 '   
+      WRITE(UNIT=ILUOUT,FMT=*) ' WITH A 2-MOMENT MICROPHYSICAL SCHEME'
+   END IF
+!
+  CASE ( 'LIMA')
+    IF ((LACTI .AND. FINI_CCN  == 'XXX')) THEN
+      WRITE(UNIT=ILUOUT,FMT=9001) KMI
+      WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE A 2-MOMENT MICROPHYSICAL ",  &
+           &" SCHEME BUT YOU DIDNT FILL CORRECTLY NAM_PARAM_LIMA",             &
+           &" YOU HAVE TO FILL FINI_CCN ")')
+      call Print_msg( NVERB_FATAL, 'GEN', 'READ_EXSEG_n', '' )
+    END IF
+!
+    IF(LACTI .AND. NMOD_CCN == 0) THEN
+      WRITE(UNIT=ILUOUT,FMT=9001) KMI
+      WRITE(UNIT=ILUOUT,FMT='("ACTIVATION OF AEROSOL PARTICLES IS NOT ",      &
+           &"POSSIBLE IF NMOD_CCN HAS VALUE ZERO. YOU HAVE TO SET AN UPPER ", &
+           &"VALUE OF NMOD_CCN IN ORDER TO USE LIMA WARM ACTIVATION SCHEME.")') 
+      call Print_msg( NVERB_FATAL, 'GEN', 'READ_EXSEG_n', '' )
+    END IF
+!
+    IF(LNUCL .AND. NMOD_IFN == 0 .AND. (.NOT.LMEYERS)) THEN
+      WRITE(UNIT=ILUOUT,FMT=9001) KMI
+      WRITE(UNIT=ILUOUT,FMT='("NUCLEATION BY DEPOSITION AND CONTACT IS NOT ", &
+           &"POSSIBLE IF NMOD_IFN HAS VALUE ZERO. YOU HAVE TO SET AN UPPER",  &
+           &"VALUE OF NMOD_IFN IN ORDER TO USE LIMA COLD NUCLEATION SCHEME.")') 
+    END IF
+!
+    IF (HCLOUD == 'NONE') THEN
+      CGETCLOUD = 'SKIP'
+    ELSE IF (HCLOUD == 'REVE' ) THEN
+      CGETCLOUD = 'INI1'
+    ELSE IF (HCLOUD == 'KESS' ) THEN
+      CGETCLOUD = 'INI2'
+    ELSE IF (HCLOUD == 'ICE3' ) THEN
+      CGETCLOUD = 'INI2'
+    ELSE
+      CGETCLOUD = 'READ' ! This is automatically done
+    END IF
+!
+    IF (LWARM) THEN
+      LUSERV=.TRUE. ; LUSERC=.TRUE. ; LUSERR=.TRUE.
+      LUSERI=.FALSE.; LUSERS=.FALSE. ; LUSERG=.FALSE.; LUSERH=.FALSE.
+    END IF
+!
+    IF (LCOLD) THEN
+      LUSERV=.TRUE. ; LUSERC=.TRUE. ; LUSERR=.TRUE.
+      LUSERI=.TRUE. ; LUSERS=.TRUE. ; LUSERG=.TRUE.
+      LUSERH=LHAIL
+    END IF
+!
+    IF (LSUBG_COND .AND. LCOLD)  THEN
+      WRITE(UNIT=ILUOUT,FMT=9003) KMI
+      WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE BOTH THE SIMPLE MIXED PHASE'
+      WRITE(UNIT=ILUOUT,FMT=*) 'MICROPHYS. SCHEME AND THE SUBGRID COND. SCHEME.'
+      WRITE(UNIT=ILUOUT,FMT=*) 'THIS IS NOT YET AVAILABLE. SET LSUBG_COND '
+      WRITE(UNIT=ILUOUT,FMT=*) 'TO FALSE OR CCLOUD TO "REVE", "KESS" '
+ !callabortstop
+      CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+    END IF 
+!
+    IF ( XALPHAC /= 3.0 .OR. XNUC /= 2.0) THEN
+      WRITE(UNIT=ILUOUT,FMT=9001) KMI
+      WRITE(UNIT=ILUOUT,FMT=*) 'IT IS ADVISED TO USE XALPHAC=3. and XNUC=2.'
+      WRITE(UNIT=ILUOUT,FMT=*) 'FOR STRATOCUMULUS. '
+    END IF
+!
+    IF ( CEFRADL /= 'LIMA') THEN
+      WRITE(UNIT=ILUOUT,FMT=9001) KMI
+      WRITE(UNIT=ILUOUT,FMT=*) ' YOU DID NOT CHOOSE CEFRADL=LIMA FOR RADIATION'
+      WRITE(UNIT=ILUOUT,FMT=*) ' IT IS ADVISED TO USE CEFRADL=LIMA '
+      WRITE(UNIT=ILUOUT,FMT=*) ' WITH A 2-MOMENT MICROPHYSICAL SCHEME "LIMA"'
+    END IF
+
+    IF (LUSECHEM )  THEN
+      WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE BOTH LIMA MICROPHYS. SCHEME AND CHEMISTRY'
+      WRITE(UNIT=ILUOUT,FMT=*) 'THIS IS NOT YET AVAILABLE. SET LUSECHEM '
+      WRITE(UNIT=ILUOUT,FMT=*) 'TO FALSE OR CCLOUD TO "ICE3" '
+ !callabortstop
+      CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+    END IF 
+    IF (LDUST )  THEN
+      WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE BOTH LIMA MICROPHYS. SCHEME AND DUSTS '
+      WRITE(UNIT=ILUOUT,FMT=*) 'THIS IS NOT YET AVAILABLE. SET LDUST '
+      WRITE(UNIT=ILUOUT,FMT=*) 'TO FALSE OR CCLOUD TO "ICE3" '
+ !callabortstop
+      CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+    END IF   
+  IF (LSALT )  THEN
+      WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE BOTH LIMA MICROPHYS. SCHEME AND SEA SALTS '
+      WRITE(UNIT=ILUOUT,FMT=*) 'THIS IS NOT YET AVAILABLE. SET LSALT '
+      WRITE(UNIT=ILUOUT,FMT=*) 'TO FALSE OR CCLOUD TO "ICE3" '
+ !callabortstop
+      CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+    END IF 
+!
+END SELECT
+!
+LUSERV_G(KMI) = LUSERV
+LUSERC_G(KMI) = LUSERC
+LUSERR_G(KMI) = LUSERR
+LUSERI_G(KMI) = LUSERI
+LUSERS_G(KMI) = LUSERS
+LUSERG_G(KMI) = LUSERG
+LUSERH_G(KMI) = LUSERH
+LUSETKE(KMI) = (CTURB /= 'NONE')
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.3     Chemical and NSV_* variables initializations
+!
+CALL UPDATE_NAM_PARAMN
+CALL UPDATE_NAM_DYNN
+CALL UPDATE_NAM_CONFN
+!
+IF (LORILAM .AND. .NOT. LUSECHEM) THEN
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU CANNOT USE ORILAM AEROSOL SCHEME WITHOUT  '
+  WRITE(ILUOUT,FMT=*) 'CHEMICAL GASEOUS CHEMISTRY                    '
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LUSECHEM IS SET TO TRUE    '
+  LUSECHEM=.TRUE.
+END IF
+!
+IF (LUSECHAQ.AND.(.NOT.LUSECHEM))  THEN
+  WRITE(UNIT=ILUOUT,FMT=9003) KMI
+  WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE AQUEOUS PHASE CHEMISTRY'
+  WRITE(UNIT=ILUOUT,FMT=*) 'BUT THE CHEMISTRY IS NOT ACTIVATED'
+  WRITE(UNIT=ILUOUT,FMT=*) 'SET LUSECHEM TO TRUE IF YOU WANT REALLY USE CHEMISTRY' 
+  WRITE(UNIT=ILUOUT,FMT=*) 'OR SET LUSECHAQ TO FALSE IF YOU DO NOT WANT USE IT' 
+ !callabortstop
+  CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+END IF
+IF (LUSECHAQ.AND.(.NOT.LUSERC).AND.CPROGRAM=='MESONH')  THEN
+  WRITE(UNIT=ILUOUT,FMT=9003) KMI
+  WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE AQUEOUS PHASE CHEMISTRY'
+  WRITE(UNIT=ILUOUT,FMT=*) 'BUT CLOUD MICROPHYSICS IS NOT ACTIVATED'
+  WRITE(UNIT=ILUOUT,FMT=*) 'LUSECHAQ IS SET TO FALSE' 
+  LUSECHAQ = .FALSE.
+END IF
+IF (LUSECHAQ.AND.CCLOUD(1:3) == 'ICE'.AND. .NOT. LUSECHIC) THEN
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE AQUEOUS PHASE CHEMISTRY'
+  WRITE(UNIT=ILUOUT,FMT=*) 'WITH MIXED PHASE CLOUD MICROPHYSICS'
+  WRITE(UNIT=ILUOUT,FMT=*) 'SET LUSECHIC TO TRUE IF YOU WANT TO ACTIVATE'
+  WRITE(UNIT=ILUOUT,FMT=*) 'ICE PHASE CHEMICAL SPECIES'
+  IF (LCH_RET_ICE) THEN
+    WRITE(UNIT=ILUOUT,FMT=*) 'LCH_RET_ICE TRUE MEANS ALL SOLUBLE'
+    WRITE(UNIT=ILUOUT,FMT=*) 'GASES ARE RETAINED IN ICE PHASE'
+    WRITE(UNIT=ILUOUT,FMT=*) 'WHEN SUPERCOOLED WATER FREEZES'
+  ELSE
+    WRITE(UNIT=ILUOUT,FMT=*) 'LCH_RET_ICE FALSE MEANS ALL SOLUBLE'
+    WRITE(UNIT=ILUOUT,FMT=*) 'GASES GO BACK TO THE GAS PHASE WHEN'
+    WRITE(UNIT=ILUOUT,FMT=*) 'SUPERCOOLED WATER FREEZES'
+  ENDIF
+ENDIF
+IF (LUSECHIC.AND. .NOT. CCLOUD(1:3) == 'ICE'.AND.CPROGRAM=='MESONH') THEN
+  WRITE(UNIT=ILUOUT,FMT=9003) KMI
+  WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE ICE PHASE CHEMISTRY'
+  WRITE(UNIT=ILUOUT,FMT=*) 'BUT MIXED PHASE CLOUD MICROPHYSICS IS NOT ACTIVATED'
+  WRITE(UNIT=ILUOUT,FMT=*) 'LUSECHIC IS SET TO FALSE'  
+  LUSECHIC= .FALSE.
+ENDIF
+IF (LCH_PH.AND. (.NOT. LUSECHAQ)) THEN
+  WRITE(UNIT=ILUOUT,FMT=9003) KMI
+  WRITE(UNIT=ILUOUT,FMT=*) 'DIAGNOSTIC PH COMPUTATION IS ACTIVATED'
+  WRITE(UNIT=ILUOUT,FMT=*) 'BUT AQUEOUS PHASE CHEMISTRY IS NOT ACTIVATED'
+  WRITE(UNIT=ILUOUT,FMT=*) 'SET LUSECHAQ TO TRUE IF YOU WANT TO ACTIVATE IT'
+  WRITE(UNIT=ILUOUT,FMT=*) 'LCH_PH IS SET TO FALSE'
+  LCH_PH= .FALSE.
+ENDIF
+IF (LUSECHIC.AND.(.NOT.LUSECHAQ))  THEN
+  WRITE(UNIT=ILUOUT,FMT=9003) KMI
+  WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE ICE PHASE CHEMISTRY'
+  WRITE(UNIT=ILUOUT,FMT=*) 'BUT THE AQUEOUS PHASE CHEMISTRY IS NOT ACTIVATED'
+  WRITE(UNIT=ILUOUT,FMT=*) 'SET LUSECHAQ TO TRUE IF YOU WANT REALLY USE CLOUD CHEMISTRY'
+  WRITE(UNIT=ILUOUT,FMT=*) 'OR SET LUSECHIC TO FALSE IF YOU DO NOT WANT USE IT'
+!callabortstop
+  CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+END IF
+IF ((LUSECHIC).AND.(LCH_RET_ICE)) THEN
+  WRITE(UNIT=ILUOUT,FMT=9003) KMI
+  WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE RETENTION OF SOLUBLE GASES IN ICE'
+  WRITE(UNIT=ILUOUT,FMT=*) 'BUT THE ICE PHASE CHEMISTRY IS ACTIVATED'
+  WRITE(UNIT=ILUOUT,FMT=*) 'FLAG LCH_RET_ICE IS ONLY USES WHEN LUSECHIC IS SET'
+  WRITE(UNIT=ILUOUT,FMT=*) 'TO FALSE IE NO CHEMICAL SPECIES IN ICE' 
+ENDIF
+!
+IF (LUSECHEM) THEN
+  CALL CH_INIT_SCHEME_n(KMI,LUSECHAQ,LUSECHIC,LCH_PH,ILUOUT,NVERB)
+  IF (LORILAM) CALL CH_AER_INIT_SOA(ILUOUT, NVERB)
+END IF
+!
+
+CALL UPDATE_NAM_CH_MNHCN
+CALL INI_NSV(KMI)
+!
+! From this point, all NSV* variables contain valid values for model KMI
+! 
+DO JSV = 1,NSV
+ LUSESV(JSV,KMI) = .TRUE.
+END DO
+!
+IF ( CAOP=='EXPL' .AND. .NOT.LDUST .AND. .NOT.LORILAM          &
+                  .AND. .NOT.LSALT .AND. .NOT.(CCLOUD=='LIMA') ) THEN
+      WRITE(UNIT=ILUOUT,FMT=9001) KMI
+      WRITE(UNIT=ILUOUT,FMT=*) ' YOU WANT TO USE EXPLICIT AEROSOL OPTICAL '       
+      WRITE(UNIT=ILUOUT,FMT=*) 'PROPERTIES BUT YOU DONT HAVE DUST OR '            
+      WRITE(UNIT=ILUOUT,FMT=*) 'AEROSOL OR SALT THEREFORE CAOP=CLIM'            
+      CAOP='CLIM'
+END IF      
+!-------------------------------------------------------------------------------
+!
+!*       3.    CHECK COHERENCE BETWEEN EXSEG VARIABLES AND FMFILE ATTRIBUTES
+!              -------------------------------------------------------------
+!
+!
+!*       3.1  Turbulence variable 
+!
+IF ((CTURB /= 'NONE').AND.(HTURB == 'NONE')) THEN
+  CGETTKET ='INIT'
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(UNIT=ILUOUT,FMT=*)'YOU WANT TO USE TURBULENCE KINETIC ENERGY TKE'
+  WRITE(UNIT=ILUOUT,FMT=*)'WHEREAS IT  IS NOT IN INITIAL FMFILE'
+  WRITE(UNIT=ILUOUT,FMT=*)'TKE WILL BE INITIALIZED TO ZERO'
+ELSE 
+  IF (CTURB /= 'NONE') THEN 
+    CGETTKET ='READ'
+    IF ((CCONF=='START') .AND. CPROGRAM /= 'DIAG') CGETTKET='INIT' 
+  ELSE
+   CGETTKET ='SKIP'
+  END IF
+END IF
+!
+!
+IF ((CTOM == 'TM06').AND.(HTOM /= 'TM06')) THEN
+  CGETBL_DEPTH ='INIT'
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(UNIT=ILUOUT,FMT=*)'YOU WANT TO USE BL DEPTH FOR THIRD ORDER MOMENTS'
+  WRITE(UNIT=ILUOUT,FMT=*)'WHEREAS IT IS NOT IN INITIAL FMFILE'
+  WRITE(UNIT=ILUOUT,FMT=*)'IT WILL BE INITIALIZED TO ZERO'
+ELSE 
+  IF (CTOM == 'TM06') THEN 
+    CGETBL_DEPTH ='READ'
+  ELSE 
+    CGETBL_DEPTH ='SKIP'
+  END IF
+END IF
+!
+IF (LRMC01 .AND. .NOT. ORMC01) THEN
+  CGETSBL_DEPTH ='INIT'
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(UNIT=ILUOUT,FMT=*)'YOU WANT TO USE SBL DEPTH FOR RMC01'
+  WRITE(UNIT=ILUOUT,FMT=*)'WHEREAS IT IS NOT IN INITIAL FMFILE'
+  WRITE(UNIT=ILUOUT,FMT=*)'IT WILL BE INITIALIZED TO ZERO'
+ELSE 
+  IF (LRMC01) THEN 
+    CGETSBL_DEPTH ='READ'
+  ELSE 
+    CGETSBL_DEPTH ='SKIP'
+  END IF
+END IF
+!
+!
+!*       3.2  Moist  variables 
+!
+IF (LUSERV.AND. (.NOT.OUSERV)) THEN
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE VAPOR VARIABLE Rv WHEREAS IT  ", &
+                  & "IS NOT IN INITIAL FMFILE",/,                           &
+                  & "Rv WILL BE INITIALIZED TO ZERO")')
+  CGETRVT='INIT'
+ELSE                                                                
+  IF (LUSERV) THEN
+    CGETRVT='READ'
+  ELSE
+    CGETRVT='SKIP'
+  END IF
+END IF
+!
+IF (LUSERC.AND. (.NOT.OUSERC)) THEN
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE CLOUD VARIABLE Rc WHEREAS IT ",  &
+                 &   " IS NOT IN INITIAL FMFILE",/,                        &
+                 &   "Rc WILL BE INITIALIZED TO ZERO")')
+  CGETRCT='INIT'
+ELSE
+  IF (LUSERC) THEN
+    CGETRCT='READ'
+!   IF(CCONF=='START') CGETRCT='INIT' 
+  ELSE
+    CGETRCT='SKIP'
+  END IF
+END IF
+!
+IF (LUSERR.AND. (.NOT.OUSERR)) THEN
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE RAIN VARIABLE Rr WHEREAS IT ", &
+                  &  "IS NOT IN INITIAL FMFILE",/,                     &
+                  &  " Rr WILL BE INITIALIZED TO ZERO")')
+ 
+  CGETRRT='INIT'
+ELSE
+  IF (LUSERR) THEN
+    CGETRRT='READ'
+!   IF( (CCONF=='START').AND. CPROGRAM /= 'DIAG') CGETRRT='INIT' 
+  ELSE
+    CGETRRT='SKIP'
+  END IF
+END IF
+!
+IF (LUSERI.AND. (.NOT.OUSERI)) THEN
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE ICE VARIABLE Ri WHEREAS IT ", &
+               &    "IS NOT IN INITIAL FMFILE",/,                      &
+               &     " Ri WILL BE INITIALIZED TO ZERO")')
+  CGETRIT='INIT'
+ELSE
+  IF (LUSERI) THEN
+    CGETRIT='READ'
+!   IF(CCONF=='START') CGETRIT='INIT' 
+  ELSE
+    CGETRIT='SKIP'
+  END IF
+END IF
+!
+IF (LUSECI.AND. (.NOT.OUSECI)) THEN
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE ICE CONC. VARIABLE Ci WHEREAS IT ",&
+               &          "IS NOT IN INITIAL FMFILE",/,                       &
+               &          "   Ci WILL BE INITIALIZED TO ZERO")')
+  CGETCIT='INIT'
+ELSE
+  IF (LUSECI) THEN
+    CGETCIT='READ'
+  ELSE
+    CGETCIT='SKIP'
+  END IF
+END IF
+!
+IF (LUSERS.AND. (.NOT.OUSERS)) THEN
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE SNOW VARIABLE Rs WHEREAS IT ",&
+                  &  "IS NOT IN INITIAL FMFILE",/,                       &
+                  &  " Rs WILL BE INITIALIZED TO ZERO")')
+  CGETRST='INIT'
+ELSE
+  IF (LUSERS) THEN
+    CGETRST='READ'
+!   IF ( (CCONF=='START').AND. CPROGRAM /= 'DIAG') CGETRST='INIT' 
+  ELSE
+    CGETRST='SKIP'
+  END IF
+END IF
+!
+IF (LUSERG.AND. (.NOT.OUSERG)) THEN
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE GRAUPEL VARIABLE Rg WHEREAS ",&
+                   & " IT IS NOTIN INITIAL FMFILE",/,                    &
+                   & "Rg WILL BE INITIALIZED TO ZERO")')
+  CGETRGT='INIT'
+ELSE
+  IF (LUSERG) THEN
+    CGETRGT='READ'
+!   IF ( (CCONF=='START') .AND. CPROGRAM /= 'DIAG') CGETRGT='INIT' 
+  ELSE
+    CGETRGT='SKIP'
+  END IF
+END IF
+!
+IF (LUSERH.AND. (.NOT.OUSERH)) THEN
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE HAIL VARIABLE Rh WHEREAS",&
+                  &  "IT IS NOT IN INITIAL FMFILE",/,                &
+                  & " Rh WILL BE INITIALIZED TO ZERO")')
+   CGETRHT='INIT'
+ELSE
+  IF (LUSERH) THEN
+    CGETRHT='READ'
+!   IF ( (CCONF=='START') .AND. CPROGRAM /= 'DIAG') CGETRHT='INIT' 
+  ELSE
+    CGETRHT='SKIP'
+  END IF
+END IF
+!
+IF (LUSERC.AND. (.NOT.OUSERC)) THEN
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(UNIT=ILUOUT,FMT=*) 'THE CLOUD FRACTION WILL BE INITIALIZED ACCORDING'
+  WRITE(UNIT=ILUOUT,FMT=*) 'TO CLOUD MIXING RATIO VALUE OR SET TO 0'
+  CGETCLDFR = 'INIT'
+ELSE
+  IF ( LUSERC ) THEN
+    CGETCLDFR = 'READ'
+    IF ( (CCONF=='START') .AND. CPROGRAM /= 'DIAG') CGETCLDFR='INIT' 
+  ELSE
+    CGETCLDFR = 'SKIP'
+  END IF
+END IF
+!
+IF(CTURBLEN=='RM17') THEN
+  XCEDIS=0.34
+ELSE
+  XCEDIS=0.84
+END IF
+!
+!*       3.3  Moist turbulence
+!
+IF ( LUSERC .AND. CTURB /= 'NONE' ) THEN
+  IF ( .NOT. (OUSERC .AND. HTURB /= 'NONE') ) THEN
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE MOIST TURBULENCE WHEREAS IT ",/, &
+                 &   " WAS NOT THE CASE FOR THE INITIAL FMFILE GENERATION",/, &
+                 &    "SRC AND SIGS ARE INITIALIZED TO 0")')
+    CGETSRCT ='INIT'
+    CGETSIGS ='INIT'
+  ELSE
+    CGETSRCT ='READ'
+    IF ( (CCONF=='START') .AND. CPROGRAM /= 'DIAG') CGETSRCT ='INIT'
+    CGETSIGS ='READ'
+  END IF
+ELSE
+  CGETSRCT ='SKIP'
+  CGETSIGS ='SKIP'
+END IF
+!
+IF(NMODEL_CLOUD==KMI .AND. CTURBLEN_CLOUD/='NONE') THEN
+  IF (CTURB=='NONE' .OR. .NOT.LUSERC) THEN
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO COMPUTE A MIXING LENGTH FOR CLOUD=", &
+                 &   A4,/, &
+                 &   ", WHEREAS YOU DO NOT SPECIFY A TURBULENCE SCHEME OR ",  &
+                 &   "USE OF RC,",/," CTURBLEN_CLOUD IS SET TO NONE")')       &
+                 CTURBLEN_CLOUD
+    CTURBLEN_CLOUD='NONE'
+  END IF
+  IF( XCEI_MIN > XCEI_MAX ) THEN
+    WRITE(UNIT=ILUOUT,FMT=9003) KMI
+    WRITE(UNIT=ILUOUT,FMT='("PROBLEM OF CEI LIMITS FOR CLOUD MIXING  ",/, &
+                 &   "LENGTH COMPUTATION: XCEI_MIN=",E9.3,", XCEI_MAX=",E9.3)')&
+                 XCEI_MIN,XCEI_MAX
+ !callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+  END IF
+END IF
+!
+IF ( LSIGMAS ) THEN
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE SIGMA_S FROM TURBULENCE SCHEME",/, &
+                 &   " IN ICE SUBGRID CONDENSATION, SO YOUR SIGMA_S"/, &
+                 &   " MIGHT BE SMALL ABOVE PBL DEPENDING ON LENGTH SCALE")')
+END IF
+!
+IF (LSUBG_COND .AND. CTURB=='NONE' ) THEN
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE SUBGRID CONDENSATION'
+  WRITE(UNIT=ILUOUT,FMT=*) ' WITHOUT TURBULENCE '                           
+  WRITE(UNIT=ILUOUT,FMT=*) 'THIS IS NOT ALLOWED: LSUBG_COND is SET to FALSE'
+  LSUBG_COND=.FALSE.
+END IF
+!
+IF (L1D .AND. CTURB/='NONE' .AND. CTURBDIM == '3DIM') THEN
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE 3D TURBULENCE IN 1D CONFIGURATION '
+  WRITE(UNIT=ILUOUT,FMT=*) 'THIS IS NOT POSSIBLE: CTURBDIM IS SET TO 1DIM'
+  CTURBDIM = '1DIM'
+END IF
+!
+!*       3.4  Additional scalar variables 
+!
+IF (NSV_USER == KSV_USER) THEN
+  DO  JS = 1,KSV_USER             ! to read all the variables in initial file 
+    CGETSVT(JS)='READ'            ! and to initialize them 
+!   IF(CCONF=='START')CGETSVT(JS)='INIT'       ! with  these values  
+  END DO
+ELSEIF (NSV_USER > KSV_USER) THEN
+ IF (KSV_USER == 0) THEN
+    CGETSVT(1:NSV_USER)='INIT'
+ ELSE
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE MORE ADDITIONAL SCALAR  " ,&
+  &" VARIABLES THAN THERE ARE IN INITIAL FMFILE",/,                  &
+  & "THE SUPPLEMENTARY VARIABLES HAVE BEEN INITIALIZED TO ZERO ")') 
+  DO  JS = 1,KSV_USER             ! to read all the variables in initial file 
+    CGETSVT(JS)='READ'            ! and to initialize them
+!   IF(CCONF=='START')CGETSVT(JS)='INIT'        ! with  these values
+  END DO
+  DO JS = KSV_USER+1, NSV_USER    ! to initialize to zero supplementary
+    CGETSVT(JS)='INIT'            ! initial file)
+  END DO
+ END IF
+ELSE
+  WRITE(UNIT=ILUOUT,FMT=9000) KMI
+  WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE LESS ADDITIONAL SCALAR  " ,&
+  &" VARIABLES THAN THERE ARE IN INITIAL FMFILE")')
+  DO  JS = 1,NSV_USER             ! to read the first NSV_USER variables in initial file 
+    CGETSVT(JS)='READ'            ! and to initialize with these values
+!   IF(CCONF=='START') CGETSVT(JS)='INIT'  
+  END DO 
+  DO  JS = NSV_USER + 1, KSV_USER ! to skip the last (KSV_USER-NSV_USER) variables
+    CGETSVT(JS)='SKIP' 
+  END DO
+END IF
+!
+! C2R2 and KHKO SV case
+!
+IF (CCLOUD == 'C2R2' .OR. CCLOUD == 'C3R5' .OR. CCLOUD == 'KHKO') THEN 
+  IF (HCLOUD == 'C2R2' .OR. HCLOUD == 'C3R5' .OR. HCLOUD == 'KHKO') THEN
+    CGETSVT(NSV_C2R2BEG:NSV_C2R2END)='READ'
+!   IF(CCONF=='START') CGETSVT(NSV_C2R2BEG:NSV_C2R2END)='INIT'
+  ELSE
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='("THERE IS NO SCALAR VARIABLES FOR C2R2 &
+         & (or KHKO) SCHEME IN INITIAL FMFILE",/,&
+         & "THE C2R2 (or KHKO) VARIABLES HAVE BEEN INITIALIZED TO ZERO ")') 
+    CGETSVT(NSV_C2R2BEG:NSV_C2R2END)='INIT'
+  END IF
+END IF
+!
+! C3R5 SV case
+!
+IF (CCLOUD == 'C3R5') THEN 
+  IF (HCLOUD == 'C3R5') THEN
+    CGETSVT(NSV_C1R3BEG:NSV_C1R3END)='READ'
+!   IF(CCONF=='START') CGETSVT(NSV_C1R3BEG:NSV_C1R3END)='INIT'
+  ELSE
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='("THERE IS NO SCALAR VARIABLES FOR C3R5 &
+         &SCHEME IN INITIAL FMFILE",/,&
+         & "THE C1R3 VARIABLES HAVE BEEN INITIALIZED TO ZERO ")') 
+    CGETSVT(NSV_C1R3BEG:NSV_C1R3END)='INIT'
+  END IF
+END IF
+!
+! LIMA SV case
+!
+IF (CCLOUD == 'LIMA') THEN
+  IF (HCLOUD == 'LIMA') THEN
+    CGETSVT(NSV_LIMA_BEG:NSV_LIMA_END)='READ'
+!!JPP    IF(HSTORAGE_TYPE=='TT') CGETSVT(NSV_LIMA_BEG:NSV_LIMA_END)='INIT'
+  ELSE
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='("THERE IS NO SCALAR VARIABLES FOR LIMA &
+           & SCHEME IN INITIAL FMFILE",/,&
+           & "THE LIMA VARIABLES HAVE BEEN INITIALIZED TO ZERO ")') 
+    CGETSVT(NSV_LIMA_BEG:NSV_LIMA_END)='INIT'
+  END IF
+END IF
+!
+! Electrical SV case
+!
+IF (CELEC /= 'NONE') THEN 
+  IF (HELEC /= 'NONE') THEN
+    CGETSVT(NSV_ELECBEG:NSV_ELECEND)='READ'
+!   IF(CCONF=='START') CGETSVT(NSV_ELECBEG:NSV_ELECEND)='INIT'
+  ELSE
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='("THERE IS NO SCALAR VARIABLES FOR ELECTRICAL &
+         &SCHEME IN INITIAL FMFILE",/,&
+         & "THE ELECTRICAL VARIABLES HAVE BEEN INITIALIZED TO ZERO ")') 
+    CGETSVT(NSV_ELECBEG:NSV_ELECEND)='INIT'
+  END IF
+END IF
+!
+! (explicit) LINOx SV case 
+!
+IF (CELEC /= 'NONE' .AND. LLNOX_EXPLICIT) THEN
+  IF (HELEC /= 'NONE' .AND. OLNOX_EXPLICIT) THEN
+    CGETSVT(NSV_LNOXBEG:NSV_LNOXEND)='READ' 
+  ELSE
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='("THERE IS NO SCALAR VARIABLES FOR LINOX &
+         & IN INITIAL FMFILE",/,& 
+         & "THE LINOX VARIABLES HAVE BEEN INITIALIZED TO ZERO ")')  
+    CGETSVT(NSV_LNOXBEG:NSV_LNOXEND)='INIT' 
+  END IF
+END IF
+!
+! Chemical SV case (excluding aqueous chemical species)
+!
+IF (LUSECHEM) THEN
+  IF (OUSECHEM) THEN
+    CGETSVT(NSV_CHGSBEG:NSV_CHGSEND)='READ'
+    IF(CCONF=='START' .AND. LCH_INIT_FIELD ) CGETSVT(NSV_CHGSBEG:NSV_CHGSEND)='INIT'
+  ELSE
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='("THERE IS NO SCALAR VARIABLES FOR CHEMICAL &
+         &SCHEME IN INITIAL FMFILE",/,&
+         & "THE CHEMICAL VARIABLES HAVE BEEN INITIALIZED TO ZERO ")') 
+    CGETSVT(NSV_CHGSBEG:NSV_CHGSEND)='INIT'
+  END IF
+END IF
+! add aqueous chemical species
+IF (LUSECHAQ) THEN
+  IF (OUSECHAQ) THEN
+    CGETSVT(NSV_CHACBEG:NSV_CHACEND)='READ'
+!    IF(CCONF=='START') CGETSVT(NSV_CHACBEG:NSV_CHACEND)='INIT'
+  ELSE
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='("THERE IS NO SCALAR VARIABLES FOR CHEMICAL &
+         &SCHEME IN AQUEOUS PHASE IN INITIAL FMFILE",/,&
+         & "THE AQUEOUS PHASE CHEMICAL VARIABLES HAVE BEEN INITIALIZED TO ZERO ")') 
+    CGETSVT(NSV_CHACBEG:NSV_CHACEND)='INIT'
+  END IF
+END IF
+! add ice phase chemical species
+IF (LUSECHIC) THEN
+  IF (OUSECHIC) THEN
+    CGETSVT(NSV_CHICBEG:NSV_CHICEND)='READ'
+!   IF(CCONF=='START') CGETSVT(NSV_CHICBEG:NSV_CHICEND)='INIT'
+  ELSE
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='("THERE IS NO SCALAR VARIABLES FOR CHEMICAL &
+         &SPECIES IN ICE PHASE IN INITIAL FMFILE",/,&
+         & "THE ICE PHASE CHEMICAL VARIABLES HAVE BEEN INITIALIZED TO ZERO ")')
+    CGETSVT(NSV_CHICBEG:NSV_CHICEND)='INIT'
+  END IF
+END IF
+! pH values = diagnostics
+IF (LCH_PH .AND. .NOT. OCH_PH) THEN
+  CGETPHC ='INIT'  !will be initialized to XCH_PHINIT
+  IF (LUSERR) THEN
+    CGETPHR = 'INIT' !idem
+  ELSE 
+    CGETPHR = 'SKIP'
+  ENDIF
+ELSE
+  IF (LCH_PH) THEN
+    CGETPHC ='READ'
+    IF (LUSERR) THEN
+      CGETPHR = 'READ'
+    ELSE
+      CGETPHR = 'SKIP'
+    ENDIF
+  ELSE
+    CGETPHC ='SKIP'
+    CGETPHR ='SKIP'
+  END IF
+END IF
+!
+! Dust case
+!
+IF (LDUST) THEN
+  IF (ODUST) THEN
+    CGETSVT(NSV_DSTBEG:NSV_DSTEND)='READ'
+!   IF(CCONF=='START') CGETSVT(NSV_DSTBEG:NSV_DSTEND)='INIT'
+  ELSE
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='("THERE IS NO SCALAR VARIABLES FOR DUST &
+         &SCHEME IN INITIAL FMFILE",/,&
+         & "THE DUST VARIABLES HAVE BEEN INITIALIZED TO ZERO ")') 
+    CGETSVT(NSV_DSTBEG:NSV_DSTEND)='INIT'
+  END IF
+  IF (LDEPOS_DST(KMI)) THEN
+
+  IF((CCLOUD /= 'ICE3').AND.(CCLOUD /= 'ICE4').AND.(CCLOUD /= 'KESS')&
+  .AND.(CCLOUD /= 'KHKO').AND.(CCLOUD /= 'C2R2').AND.                &
+       (CPROGRAM/='SPAWN').AND.(CPROGRAM/='REAL'))  THEN
+    WRITE(UNIT=ILUOUT,FMT=9003) KMI
+    WRITE(UNIT=ILUOUT,FMT='("ERROR: WET DEPOSITION OF DUST IS ONLY CODED FOR THE",/,&
+         & "MICROPHYSICAL SCHEME as ICE3, ICE4, KESS, KHKO and C2R2")') 
+ !callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+  END IF  
+
+   IF (ODEPOS_DST(KMI) ) THEN
+    CGETSVT(NSV_DSTDEPBEG:NSV_DSTDEPEND)='READ'
+!   IF(CCONF=='START') CGETSVT(NSV_DSTDEPBEG:NSV_DSTDEPEND)='INIT'    
+   ELSE
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='("THERE IS NO SCALAR VARIABLES FOR RAIN and CLOUD DUST &
+         &  SCHEME IN INITIAL FMFILE",/,&
+         & "THE MOIST DUST VARIABLES HAVE BEEN INITIALIZED TO ZERO ")') 
+    CGETSVT(NSV_DSTDEPBEG:NSV_DSTDEPEND)='INIT'    
+   END IF
+  END IF  
+
+  IF(NMODE_DST.GT.3 .OR. NMODE_DST.LT.1) THEN
+    WRITE(UNIT=ILUOUT,FMT=9003) KMI
+    WRITE(UNIT=ILUOUT,FMT='("DUST MODES MUST BE BETWEEN 1 and 3 ")') 
+ !callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+  END IF     
+  IF(.NOT.ALLOCATED(CDUSTNAMES)) THEN
+    IMOMENTS = (NSV_DSTEND - NSV_DSTBEG +1 )/NMODE_DST
+    ALLOCATE(CDUSTNAMES(IMOMENTS*NMODE_DST))
+    !Loop on all dust modes
+    IF (IMOMENTS == 1) THEN
+    DO JMODE=1,NMODE_DST
+      IMODEIDX=JPDUSTORDER(JMODE)
+      JSV_NAME = (IMODEIDX - 1)*3 + 2
+      CDUSTNAMES(JMODE) = YPDUST_INI(JSV_NAME)
+    END DO
+    ELSE
+    DO JMODE=1,NMODE_DST  
+      !Find which mode we are dealing with
+      IMODEIDX=JPDUSTORDER(JMODE)
+      DO JMOM=1,IMOMENTS
+        !Find which number this is of the list of scalars
+        JSV = (JMODE-1)*IMOMENTS + JMOM
+        !Find what name this corresponds to, always 3 moments assumed in YPDUST_INI
+        JSV_NAME = (IMODEIDX - 1)*3 + JMOM
+        !Get the right CDUSTNAMES which should follow the list of scalars transported in XSVM/XSVT
+        CDUSTNAMES(JSV) = YPDUST_INI(JSV_NAME)
+      ENDDO ! Loop on moments
+    ENDDO    ! Loop on dust modes
+    END IF 
+  END IF 
+  ! Initialization of deposition scheme
+  IF (LDEPOS_DST(KMI)) THEN
+    IF(.NOT.ALLOCATED(CDEDSTNAMES)) THEN
+      ALLOCATE(CDEDSTNAMES(NMODE_DST*2))
+      DO JMODE=1,NMODE_DST  
+        IMODEIDX=JPDUSTORDER(JMODE)
+        CDEDSTNAMES(JMODE) = YPDEDST_INI(IMODEIDX)
+        CDEDSTNAMES(NMODE_DST+JMODE) = YPDEDST_INI(NMODE_DST+IMODEIDX)
+      ENDDO
+    ENDIF    
+  ENDIF
+
+END IF 
+!
+! Sea Salt case
+!
+IF (LSALT) THEN
+  IF (OSALT) THEN
+    CGETSVT(NSV_SLTBEG:NSV_SLTEND)='READ'
+    CGETZWS='READ'
+!   IF(CCONF=='START') CGETSVT(NSV_SLTBEG:NSV_SLTEND)='INIT'
+  ELSE
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='("THERE IS NO SCALAR VARIABLES FOR SALT &
+         &SCHEME IN INITIAL FMFILE",/,&
+         & "THE SALT VARIABLES HAVE BEEN INITIALIZED TO ZERO ")') 
+    CGETSVT(NSV_SLTBEG:NSV_SLTEND)='INIT'
+    CGETZWS='INIT'
+  END IF
+  IF (LDEPOS_SLT(KMI)) THEN
+
+  IF((CCLOUD /= 'ICE3').AND.(CCLOUD /= 'ICE4').AND.(CCLOUD /= 'KESS')&
+  .AND.(CCLOUD /= 'KHKO').AND.(CCLOUD /= 'C2R2').AND.                &
+       (CPROGRAM/='SPAWN').AND.(CPROGRAM/='REAL'))  THEN
+    WRITE(UNIT=ILUOUT,FMT=9003) KMI
+    WRITE(UNIT=ILUOUT,FMT='("ERROR: WET DEPOSITION OF SEA SALT AEROSOLS IS ONLY CODED FOR THE",/,&
+         & "MICROPHYSICAL SCHEME as ICE3, ICE4, KESS, KHKO and C2R2")') 
+ !callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+  END IF  
+
+   IF (ODEPOS_SLT(KMI) ) THEN
+    CGETSVT(NSV_SLTDEPBEG:NSV_SLTDEPEND)='READ'
+!   IF(CCONF=='START') CGETSVT(NSV_SLTDEPBEG:NSV_SLTDEPEND)='INIT'    
+   ELSE
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='("THERE IS NO SCALAR VARIABLES FOR RAIN and CLOUD SEA SALT &
+         &  SCHEME IN INITIAL FMFILE",/,&
+         & "THE MOIST SEA SALT VARIABLES HAVE BEEN INITIALIZED TO ZERO ")') 
+    CGETSVT(NSV_SLTDEPBEG:NSV_SLTDEPEND)='INIT'    
+   END IF
+  END IF
+  IF(NMODE_SLT.GT.5 .OR. NMODE_SLT.LT.1) THEN
+    WRITE(UNIT=ILUOUT,FMT=9003) KMI
+    WRITE(UNIT=ILUOUT,FMT='("SALT MODES MUST BE BETWEEN 1 and 5 ")') 
+ !callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+  END IF     
+  IF(.NOT.ALLOCATED(CSALTNAMES)) THEN
+    IMOMENTS = (NSV_SLTEND - NSV_SLTBEG +1 )/NMODE_SLT
+    ALLOCATE(CSALTNAMES(IMOMENTS*NMODE_SLT))
+    !Loop on all dust modes
+    IF (IMOMENTS == 1) THEN
+    DO JMODE=1,NMODE_SLT
+      IMODEIDX=JPSALTORDER(JMODE)
+      JSV_NAME = (IMODEIDX - 1)*3 + 2
+      CSALTNAMES(JMODE) = YPSALT_INI(JSV_NAME)
+    END DO
+    ELSE
+    DO JMODE=1,NMODE_SLT  
+      !Find which mode we are dealing with
+      IMODEIDX=JPSALTORDER(JMODE)
+      DO JMOM=1,IMOMENTS
+        !Find which number this is of the list of scalars
+        JSV = (JMODE-1)*IMOMENTS + JMOM
+        !Find what name this corresponds to, always 3 moments assumed in YPSALT_INI
+        JSV_NAME = (IMODEIDX - 1)*3 + JMOM
+        !Get the right CSALTNAMES which should follow the list of scalars transported in XSVM/XSVT
+        CSALTNAMES(JSV) = YPSALT_INI(JSV_NAME)
+      ENDDO ! Loop on moments
+    ENDDO    ! Loop on dust modes
+    END IF
+  END IF 
+  ! Initialization of deposition scheme
+  IF (LDEPOS_SLT(KMI)) THEN
+    IF(.NOT.ALLOCATED(CDESLTNAMES)) THEN
+      ALLOCATE(CDESLTNAMES(NMODE_SLT*2))
+      DO JMODE=1,NMODE_SLT  
+        IMODEIDX=JPSALTORDER(JMODE)
+        CDESLTNAMES(JMODE) = YPDESLT_INI(IMODEIDX)
+        CDESLTNAMES(NMODE_SLT+JMODE) = YPDESLT_INI(NMODE_SLT+IMODEIDX)
+      ENDDO
+    ENDIF    
+  ENDIF
+END IF 
+!
+! Orilam SV case
+!
+IF (LORILAM) THEN
+  IF (OORILAM) THEN
+    CGETSVT(NSV_AERBEG:NSV_AEREND)='READ'
+!   IF(CCONF=='START') CGETSVT(NSV_AERBEG:NSV_AEREND)='INIT'
+  ELSE
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='("THERE IS NO SCALAR VARIABLES FOR AEROSOL &
+         &SCHEME IN INITIAL FMFILE",/,&
+         & "THE AEROSOLS VARIABLES HAVE BEEN INITIALIZED TO ZERO ")') 
+    CGETSVT(NSV_AERBEG:NSV_AEREND)='INIT'
+  END IF
+  IF (LDEPOS_AER(KMI)) THEN
+
+  IF((CCLOUD /= 'ICE3').AND.(CCLOUD /= 'ICE4').AND.(CCLOUD /= 'KESS')&
+  .AND.(CCLOUD /= 'KHKO').AND.(CCLOUD /= 'C2R2').AND.                &
+       (CPROGRAM/='SPAWN').AND.(CPROGRAM/='REAL'))  THEN
+    WRITE(UNIT=ILUOUT,FMT=9003) KMI
+    WRITE(UNIT=ILUOUT,FMT='("ERROR: WET DEPOSITION OF ORILAM AEROSOLS IS ONLY CODED FOR THE",/,&
+         & "MICROPHYSICAL SCHEME as ICE3, ICE4, KESS, KHKO and C2R2")') 
+ !callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+  END IF  
+
+   IF (ODEPOS_AER(KMI) ) THEN
+    CGETSVT(NSV_AERDEPBEG:NSV_AERDEPEND)='READ'
+!   IF(CCONF=='START') CGETSVT(NSV_AERDEPBEG:NSV_AERDEPEND)='INIT'    
+   ELSE
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='("THERE IS NO SCALAR VARIABLES FOR RAIN and IN CLOUD  &
+         &  AEROSOL SCHEME IN INITIAL FMFILE",/,&
+         & "THE MOIST AEROSOL VARIABLES HAVE BEEN INITIALIZED TO ZERO ")') 
+    CGETSVT(NSV_AERDEPBEG:NSV_AERDEPEND)='INIT'    
+   END IF
+  END IF
+! Initialization of deposition scheme
+  IF (LDEPOS_AER(KMI)) THEN
+    IF(.NOT.ALLOCATED(CDEAERNAMES)) THEN
+      ALLOCATE(CDEAERNAMES(JPMODE*2))
+        CDEAERNAMES(:) = YPDEAER_INI(:)
+    ENDIF    
+  ENDIF
+END IF
+!
+! Lagrangian variables
+!
+IF (LINIT_LG .AND. .NOT.(LLG)) THEN
+      WRITE(UNIT=ILUOUT,FMT=9001) KMI
+      WRITE(UNIT=ILUOUT,FMT='("IT IS INCOHERENT TO HAVE LINIT_LG=.T. AND LLG=.F.",/,&
+      & "IF YOU WANT LAGRANGIAN TRACERS CHANGE LLG TO .T. ")')
+ENDIF
+IF (LLG) THEN
+  IF (OLG .AND. .NOT.(LINIT_LG .AND. CPROGRAM=='MESONH')) THEN
+    CGETSVT(NSV_LGBEG:NSV_LGEND)='READ'
+!   IF(CCONF=='START') CGETSVT(NSV_LGBEG:NSV_LGEND)='INIT'
+  ELSE
+    IF(.NOT.(LINIT_LG) .AND. CPROGRAM=='MESONH') THEN
+      WRITE(UNIT=ILUOUT,FMT=9001) KMI
+      WRITE(UNIT=ILUOUT,FMT='("THERE IS NO LAGRANGIAN VARIABLES IN INITIAL FMFILE",/,&
+                       & "THE LAGRANGIAN VARIABLES HAVE BEEN REINITIALIZED")')
+      LINIT_LG=.TRUE.
+    ENDIF
+    CGETSVT(NSV_LGBEG:NSV_LGEND)='INIT'
+  END IF
+END IF
+!
+!
+! LINOx SV case
+!
+IF (.NOT.LUSECHEM .AND. LCH_CONV_LINOX) THEN
+  IF (.NOT.OUSECHEM .AND. OCH_CONV_LINOX) THEN
+    CGETSVT(NSV_LNOXBEG:NSV_LNOXEND)='READ'
+  ELSE
+    WRITE(UNIT=ILUOUT,FMT=9002) KMI
+    WRITE(UNIT=ILUOUT,FMT='("THERE IS NO SCALAR VARIABLES FOR LINOX &
+         &IN INITIAL FMFILE",/,&
+         & "THE LINOX VARIABLES HAVE BEEN INITIALIZED TO ZERO ")') 
+    CGETSVT(NSV_LNOXBEG:NSV_LNOXEND)='INIT'
+  END IF
+END IF
+!
+! Passive pollutant case
+!
+IF (LPASPOL) THEN
+  IF (OPASPOL) THEN
+    CGETSVT(NSV_PPBEG:NSV_PPEND)='READ'
+!   IF(CCONF=='START') CGETSVT(NSV_PPBEG:NSV_PPEND)='INIT'    
+  ELSE
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='("THERE IS NO PASSIVE SCALAR VARIABLES IN INITIAL FMFILE",/,&
+                       & "THE VARIABLES HAVE BEEN INITIALIZED TO ZERO")')
+    CGETSVT(NSV_PPBEG:NSV_PPEND)='INIT'
+  END IF
+END IF
+!
+#ifdef MNH_FOREFIRE
+! ForeFire
+!
+IF (LFOREFIRE) THEN
+  IF (OFOREFIRE) THEN
+    CGETSVT(NSV_FFBEG:NSV_FFEND)='READ'
+    IF(HSTORAGE_TYPE=='TT') THEN
+      CGETSVT(NSV_FFBEG:NSV_FFEND)='INIT'
+    END IF
+  ELSE
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='("THERE IS NO FOREFIRE SCALAR VARIABLES IN INITIAL FMFILE",/,&
+                       & "THE VARIABLES HAVE BEEN INITIALIZED TO ZERO")')
+    CGETSVT(NSV_FFBEG:NSV_FFEND)='INIT'
+  END IF
+END IF
+#endif
+!
+! Conditional sampling case
+!
+IF (LCONDSAMP) THEN
+  IF (OCONDSAMP) THEN
+    CGETSVT(NSV_CSBEG:NSV_CSEND)='READ'
+!   IF(CCONF=='START') CGETSVT(NSV_CSBEG:NSV_CSEND)='INIT'       
+  ELSE
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='("THERE IS NO PASSIVE SCALAR VARIABLES IN INITIAL FMFILE",/,&
+                       & "THE VARIABLES HAVE BEEN INITIALIZED TO ZERO")')
+    CGETSVT(NSV_CSBEG:NSV_CSEND)='INIT'
+  END IF
+END IF
+!
+! Blowing snow scheme
+!
+IF (LBLOWSNOW) THEN
+  IF (OBLOWSNOW) THEN
+    CGETSVT(NSV_SNWBEG:NSV_SNWEND)='READ'
+  ELSE
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='("THERE IS NO SCALAR VARIABLES FOR BLOWING SNOW &
+         &SCHEME IN INITIAL FMFILE",/,&
+         & "THE BLOWING SNOW VARIABLES HAVE BEEN INITIALIZED TO ZERO ")')
+    CGETSVT(NSV_SNWBEG:NSV_SNWEND)='INIT'
+  END IF
+  IF(.NOT.ALLOCATED(CSNOWNAMES)) THEN
+    IMOMENTS = (NSV_SNWEND - NSV_SNWBEG +1 )
+    ALLOCATE(CSNOWNAMES(IMOMENTS))
+    DO JMOM=1,IMOMENTS
+      CSNOWNAMES(JMOM) = YPSNOW_INI(JMOM)
+    ENDDO ! Loop on moments
+  END IF
+END IF
+!
+!
+!
+!*       3.5  Check coherence between the radiation control parameters
+!
+IF( CRAD == 'ECMW' .AND. CPROGRAM=='MESONH' ) THEN
+  IF(CLW == 'RRTM' .AND. COPILW == 'SMSH') THEN
+    WRITE(UNIT=ILUOUT,FMT=9003) KMI
+    WRITE(UNIT=ILUOUT,FMT=*) 'the SMSH parametrisation of LW optical properties for cloud ice'
+    WRITE(UNIT=ILUOUT,FMT=*) '(COPILW) can not be used with RRTM radiation scheme'
+ !callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+  ENDIF
+  IF(CLW == 'MORC' .AND. COPWLW == 'LILI') THEN
+    WRITE(UNIT=ILUOUT,FMT=9003) KMI
+    WRITE(UNIT=ILUOUT,FMT=*) 'the LILI parametrisation of LW optical properties for cloud water'
+    WRITE(UNIT=ILUOUT,FMT=*) '(COPWLW) can not be used with MORC radiation scheme'
+ !callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+  ENDIF
+  IF( .NOT. LSUBG_COND) THEN
+    WRITE(UNIT=ILUOUT,FMT=9000) KMI
+    WRITE(UNIT=ILUOUT,FMT=*) 'YOU DO NOT WANT TO USE SUBGRID CONDENSATION'             
+    WRITE(UNIT=ILUOUT,FMT=*) 'THE OVERLAP OPTION IS NOVLP=5 IN ini_radconf.f90'
+  ELSE IF (CLW == 'MORC') THEN
+    WRITE(UNIT=ILUOUT,FMT=9000) KMI
+    WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE MORCRETTE LW SCHEME'                   
+    WRITE(UNIT=ILUOUT,FMT=*) 'THE OVERLAP OPTION IS NOVLP=5 IN ini_radconf.f90'
+  ELSE
+    WRITE(UNIT=ILUOUT,FMT=9000) KMI
+    WRITE(UNIT=ILUOUT,FMT=*) 'THE OVERLAP OPTION IS NOVLP=6 IN ini_radconf.f90'
+  ENDIF
+!
+  IF( LCLEAR_SKY .AND. XDTRAD_CLONLY /= XDTRAD) THEN
+    ! Check the validity of the LCLEAR_SKY approximation
+    WRITE(UNIT=ILUOUT,FMT=9003) KMI
+    WRITE(UNIT=ILUOUT,FMT=*) 'YOU WANT TO USE BOTH THE CLEAR-SKY APPROXIMATION'
+    WRITE(UNIT=ILUOUT,FMT=*) '(i.e. AVERAGE THE WHOLE CLOUDFREE VERTICALS BUT KEEP'
+    WRITE(UNIT=ILUOUT,FMT=*) 'ALL THE CLOUDY VERTICALS) AND'
+    WRITE(UNIT=ILUOUT,FMT=*) 'THE CLOUD-ONLY APPROXIMATION (i.e. YOU CALL MORE OFTEN THE'
+    WRITE(UNIT=ILUOUT,FMT=*) 'RADIATIONS FOR THE CLOUDY VERTICALS THAN FOR CLOUDFREE ONES).'
+    WRITE(UNIT=ILUOUT,FMT=*) 'THIS IS NOT POSSIBLE, SO CHOOSE BETWEEN :'
+    WRITE(UNIT=ILUOUT,FMT=*) 'XDTRAD_CLONLY = XDTRAD and LCLEAR_SKY = FALSE'
+!
+ !callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+  END IF
+!
+  IF( XDTRAD_CLONLY > XDTRAD ) THEN
+    WRITE(UNIT=ILUOUT,FMT=9003) KMI
+    WRITE(UNIT=ILUOUT,FMT='("BAD USE OF THE CLOUD-ONLY APPROXIMATION   " ,&
+    &" XDTRAD SHOULD BE LARGER THAN XDTRAD_CLONLY                      ")')
+!
+ !callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+  END IF
+!
+  IF(( XDTRAD < XTSTEP ).OR. ( XDTRAD_CLONLY < XTSTEP )) THEN
+    WRITE(UNIT=ILUOUT,FMT=9003) KMI
+    WRITE(UNIT=ILUOUT,FMT='("THE RADIATION CALL XDTRAD OR XDTRAD_CLONLY " ,&
+    &" IS MORE FREQUENT THAN THE TIME STEP SO ADJUST XDTRAD OR XDTRAD_CLONLY ")')
+!
+ !callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+  END IF
+END IF
+!
+IF ( CRAD /= 'NONE' .AND. CPROGRAM=='MESONH' ) THEN
+  CGETRAD='READ'
+  IF( HRAD == 'NONE' .AND. CCONF=='RESTA') THEN
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT=*) 'YOU ARE PERFORMING A RESTART. FOR THIS SEGMENT, YOU ARE USING A RADIATION'
+    WRITE(UNIT=ILUOUT,FMT=*) 'SCHEME AND NO RADIATION SCHEME WAS USED FOR THE PREVIOUS SEGMENT.'
+    CGETRAD='INIT'
+  END IF
+  IF(CCONF=='START') THEN
+    CGETRAD='INIT'
+  END IF
+END IF
+!
+!        3.6  check the initialization of the deep convection scheme
+!
+IF ( (CDCONV /= 'KAFR') .AND. &
+      (CSCONV /= 'KAFR') .AND. LCHTRANS ) THEN
+   WRITE(UNIT=ILUOUT,FMT=9003) KMI
+   WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE THE LCHTRANS OPTION= ",&
+    &"CONVECTIVE TRANSPORT OF TRACERS BUT  IT CAN ONLY",&
+    &"BE USED FOR THE KAIN FRITSCH SCHEME ")')
+ !callabortstop
+   CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+END IF
+!
+SELECT CASE ( CDCONV )
+  CASE( 'KAFR' )
+    IF (.NOT. ( LUSERV ) ) THEN
+      WRITE(UNIT=ILUOUT,FMT=9002) KMI
+      WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE THE KAIN-FRITSCH DEEP CONV. ",&
+      &" SCHEME. YOU MUST HAVE VAPOR ",/,"LUSERV IS SET TO TRUE ")')
+      LUSERV=.TRUE.
+    ELSE IF (.NOT. ( LUSERI ) ) THEN
+      WRITE(UNIT=ILUOUT,FMT=9002) KMI
+      WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE THE KAIN-FRITSCH",&
+      &" DEEP CONV. SCHEME. BUT THE DETRAINED CLOUD ICE WILL BE ADDED TO   ",&
+      &" THE CLOUD WATER  ")')
+    ELSE IF (.NOT. ( LUSERI.AND.LUSERC ) ) THEN
+      WRITE(UNIT=ILUOUT,FMT=9002) KMI
+      WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE THE KAIN-FRITSCH",&
+      &" DEEP CONV. SCHEME. BUT THE DETRAINED CLOUD WATER AND CLOUD ICE    ",&
+      &" WILL BE ADDED TO THE WATER VAPOR FIELD  ")')
+    END IF
+    IF ( LCHTRANS .AND. NSV == 0 ) THEN
+      WRITE(UNIT=ILUOUT,FMT=9002) KMI
+      WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE THE LCHTRANS OPTION= ",&
+      &"CONVECTIVE TRANSPORT OF TRACERS BUT YOUR TRACER ",&
+      &"NUMBER NSV IS ZERO ",/,"LCHTRANS IS SET TO FALSE")')
+      LCHTRANS=.FALSE.
+    END IF
+END SELECT
+!
+IF ( CDCONV == 'KAFR' .AND. LCHTRANS .AND. NSV > 0 ) THEN
+  IF( OCHTRANS ) THEN
+    CGETSVCONV='READ'
+  ELSE  
+    CGETSVCONV='INIT'
+  END IF
+END IF
+!
+SELECT CASE ( CSCONV )
+  CASE( 'KAFR' )
+    IF (.NOT. ( LUSERV ) ) THEN
+      WRITE(UNIT=ILUOUT,FMT=9002) KMI
+      WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE THE KAIN-FRITSCH SHALLOW CONV. ",&
+      &" SCHEME. YOU MUST HAVE VAPOR ",/,"LUSERV IS SET TO TRUE ")')
+      LUSERV=.TRUE.
+    ELSE IF (.NOT. ( LUSERI ) ) THEN
+      WRITE(UNIT=ILUOUT,FMT=9002) KMI
+      WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE THE KAIN-FRITSCH",&
+      &" SHALLOW CONV. SCHEME. BUT THE DETRAINED CLOUD ICE WILL BE ADDED TO   ",&
+      &" THE CLOUD WATER  ")')
+    ELSE IF (.NOT. ( LUSERI.AND.LUSERC ) ) THEN
+      WRITE(UNIT=ILUOUT,FMT=9002) KMI
+      WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE THE KAIN-FRITSCH",&
+      &" SHALLOW CONV. SCHEME. BUT THE DETRAINED CLOUD WATER AND CLOUD ICE    ",&
+      &" WILL BE ADDED TO THE WATER VAPOR FIELD  ")')
+    END IF
+    IF ( LCHTRANS .AND. NSV == 0 ) THEN
+      WRITE(UNIT=ILUOUT,FMT=9002) KMI
+      WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE THE LCHTRANS OPTION= ",&
+      &"CONVECTIVE TRANSPORT OF TRACERS BUT YOUR TRACER ",&
+      &"NUMBER NSV IS ZERO ",/,"LCHTRANS IS SET TO FALSE")')
+      LCHTRANS=.FALSE.
+    END IF
+ CASE( 'EDKF' )
+    IF (CTURB == 'NONE' ) THEN
+      WRITE(UNIT=ILUOUT,FMT=9003) KMI
+      WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE THE EDKF ", & 
+      &"SHALLOW CONVECTION WITHOUT TURBULENCE SCHEME : ", &
+      &"IT IS NOT POSSIBLE")')
+!
+ !callabortstop
+      CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+    END IF
+END SELECT
+!
+!
+CGETCONV = 'SKIP'
+!
+IF ( (CDCONV /= 'NONE' .OR. CSCONV == 'KAFR' ) .AND. CPROGRAM=='MESONH') THEN
+  CGETCONV = 'READ'
+  IF( HDCONV == 'NONE' .AND. CCONF=='RESTA') THEN
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(UNIT=ILUOUT,FMT='(" YOU ARE PERFORMING A RESTART. FOR THIS  ",&
+     &" SEGMENT, YOU ARE USING A DEEP CONVECTION SCHEME AND NO DEEP    ",&
+     &" CONVECTION SCHEME WAS USED FOR THE PREVIOUS SEGMENT. ")')
+!
+    CGETCONV = 'INIT'
+  END IF
+  IF(CCONF=='START') THEN
+    CGETCONV = 'INIT'
+  END IF
+END IF
+!
+!*       3.7  configuration and model version
+!
+IF (KMI == 1) THEN                                                
+! 
+  IF (L1D.AND.(CLBCX(1)/='CYCL'.AND.CLBCX(2)/='CYCL' &
+          .AND.CLBCY(1)/='CYCL'.AND.CLBCY(2)/='CYCL')) THEN
+    WRITE(UNIT=ILUOUT,FMT=9003) KMI
+    WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE A 1D MODEL VERSION WITH NON-CYCL",&
+                & "CLBCX OR CLBCY VALUES")')
+ !callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+  END IF
+  IF (L2D.AND.(CLBCY(1)/='CYCL'.AND.CLBCY(2)/='CYCL')) THEN
+    WRITE(UNIT=ILUOUT,FMT=9003) KMI
+    WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE A 2D MODEL VERSION WITH NON-CYCL",&
+                & " CLBCY VALUES")')
+ !callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+  END IF
+  !
+ IF ( (.NOT. LCARTESIAN) .AND. ( LCORIO) .AND. (.NOT. LGEOST_UV_FRC) ) THEN
+   WRITE(UNIT=ILUOUT,FMT=9002) KMI
+   WRITE(UNIT=ILUOUT,FMT='("BE CAREFUL YOU COULD HAVE SPURIOUS MOTIONS      " ,&
+        & " NEAR THE LBC AS LCORIO=T and  LGEOST_UV_FRC=F")')
+ END IF
+  !
+  IF ((.NOT.LFLAT).AND.OFLAT) THEN                                      
+    WRITE(UNIT=ILUOUT,FMT=9002) KMI 
+    WRITE(UNIT=ILUOUT,FMT=*) 'ZERO OROGRAPHY IN INITIAL FILE'
+    WRITE(UNIT=ILUOUT,FMT=*) '***** ALL TERMS HAVE BEEN NEVERTHELESS COMPUTED WITHOUT SIMPLIFICATION*****'
+    WRITE(UNIT=ILUOUT,FMT=*) 'THIS SHOULD LEAD TO ERRORS IN THE PRESSURE COMPUTATION'     
+  END IF
+  IF (LFLAT.AND.(.NOT.OFLAT)) THEN
+    WRITE(UNIT=ILUOUT,FMT=9002) KMI
+    WRITE(UNIT=ILUOUT,FMT='(" OROGRAPHY IS NOT EQUAL TO ZERO ",            &
+          & "IN INITIAL FILE" ,/,                                          &
+          & "******* OROGRAPHY HAS BEEN SET TO ZERO *********",/,          &
+          & "ACCORDING TO ZERO OROGRAPHY, SIMPLIFICATIONS  HAVE  ",        &
+          & "BEEN MADE IN  COMPUTATIONS")')
+  END IF 
+END IF
+!
+!*       3.8  System of equations
+!
+IF ( HEQNSYS /= CEQNSYS ) THEN
+  WRITE(UNIT=ILUOUT,FMT=9003) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU HAVE CHANGED THE SYSTEM OF EQUATIONS'
+  WRITE(ILUOUT,FMT=*) 'THE ANELASTIC CONSTRAINT IS PERHAPS CHANGED :'
+  WRITE(ILUOUT,FMT=*) 'FOR THE INITIAL FILE YOU HAVE USED ',HEQNSYS
+  WRITE(ILUOUT,FMT=*) 'FOR THE RUN YOU PLAN TO USE ',CEQNSYS
+  WRITE(ILUOUT,FMT=*) 'THIS CAN LEAD TO A NUMERICAL EXPLOSION IN THE FIRST TIME STEPS'
+ !callabortstop
+  CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+END IF
+!
+!        3.9  Numerical schemes
+!
+IF ( (CUVW_ADV_SCHEME == 'CEN4TH') .AND. &
+      (CTEMP_SCHEME /= 'LEFR') .AND. (CTEMP_SCHEME /= 'RKC4') ) THEN
+   WRITE(UNIT=ILUOUT,FMT=9003) KMI
+   WRITE(UNIT=ILUOUT,FMT='("CEN4TH SCHEME HAS TO BE USED WITH ",&
+    &"CTEMP_SCHEME = LEFR of RKC4 ONLY")')   
+ !callabortstop
+   CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+END IF
+!
+IF ( (CUVW_ADV_SCHEME == 'WENO_K') .AND. LNUMDIFU ) THEN
+   WRITE(UNIT=ILUOUT,FMT=9002) KMI
+   WRITE(UNIT=ILUOUT,FMT='("YOU WANT TO USE NUMERICAL DIFFUSION ",&
+    &"WITH WENO SCHEME ALREADY DIFFUSIVE")')   
+END IF
+!-------------------------------------------------------------------------------
+!
+!*       4.    CHECK COHERENCE BETWEEN EXSEG VARIABLES
+!              ---------------------------------------
+!        
+!*       4.1  coherence between coupling variables in EXSEG file  
+!                      
+IF (KMI == 1) THEN
+  NCPL_NBR = 0
+  DO JCI = 1,JPCPLFILEMAX
+    IF (LEN_TRIM(CCPLFILE(JCI)) /= 0) THEN        ! Finds the number 
+      NCPL_NBR = NCPL_NBR + 1                     ! of coupling files
+    ENDIF
+    IF (JCI/=JPCPLFILEMAX) THEN                   ! Deplaces the coupling files
+      IF ((LEN_TRIM(CCPLFILE(JCI)) == 0) .AND.   &! names if one missing
+          (LEN_TRIM(CCPLFILE(JCI+1)) /= 0)) THEN
+        DO JI=JCI,JPCPLFILEMAX-1
+          CCPLFILE(JI)=CCPLFILE(JI+1)
+        END DO
+        CCPLFILE(JPCPLFILEMAX)='    '
+      END IF
+    END IF
+  END DO
+!
+  IF (NCPL_NBR /= 0) THEN         
+    LSTEADYLS = .FALSE.
+  ELSE
+    LSTEADYLS = .TRUE.
+  ENDIF 
+END IF
+!        
+!*       4.3   check consistency in forcing switches
+!
+IF ( LFORCING ) THEN
+  IF ( LRELAX_THRV_FRC .AND. ( LTEND_THRV_FRC .OR. LGEOST_TH_FRC ) ) THEN
+    WRITE(UNIT=ILUOUT,FMT=9002) KMI
+    WRITE(ILUOUT,FMT=*) 'YOU CHOSE A TEMPERATURE AND HUMIDITY RELAXATION'
+    WRITE(ILUOUT,FMT=*) 'TOGETHER WITH TENDENCY OR GEOSTROPHIC FORCING'
+    WRITE(ILUOUT,FMT=*) &
+  'YOU MIGHT CHECK YOUR SWITCHES:  LRELAX_THRV_FRC, LTEND_THRV_FRC, AND'
+    WRITE(ILUOUT,FMT=*) 'LGEOST_TH_FRC'
+  END IF
+!
+  IF ( LRELAX_UV_FRC .AND. LGEOST_UV_FRC ) THEN
+    WRITE(UNIT=ILUOUT,FMT=9003) KMI
+    WRITE(ILUOUT,FMT=*) 'YOU MUST NOT USE A WIND RELAXATION' 
+    WRITE(ILUOUT,FMT=*) 'TOGETHER WITH A GEOSTROPHIC FORCING'
+    WRITE(ILUOUT,FMT=*) 'CHECK SWITCHES:  LRELAX_UV_FRC, LGEOST_UV_FRC'
+ !callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+  END IF
+!
+  IF ( CRELAX_HEIGHT_TYPE.NE."FIXE" .AND. CRELAX_HEIGHT_TYPE.NE."THGR" ) THEN
+    WRITE(UNIT=ILUOUT,FMT=9003) KMI
+    WRITE(ILUOUT,FMT=*) 'CRELAX_HEIGHT_TYPE MUST BE EITHER "FIXE" OR "THGR"'
+    WRITE(ILUOUT,FMT=*) 'BUT IT IS "', CRELAX_HEIGHT_TYPE, '"'
+ !callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+  END IF
+!
+  IF ( .NOT.LCORIO .AND. LGEOST_UV_FRC ) THEN
+    WRITE(UNIT=ILUOUT,FMT=9003) KMI
+    WRITE(ILUOUT,FMT=*) 'YOU CANNOT HAVE A GEOSTROPHIC FORCING WITHOUT'
+    WRITE(ILUOUT,FMT=*) 'ACTIVATING LCORIOLIS OPTION'
+ !callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+  END IF
+!
+  IF ( LPGROUND_FRC ) THEN
+    WRITE(ILUOUT,FMT=*) 'SURFACE PRESSURE FORCING NOT YET IMPLEMENTED'
+ !callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+  END IF
+!
+END IF
+!
+IF (LTRANS .AND. .NOT. LFLAT ) THEN
+    WRITE(UNIT=ILUOUT,FMT=9003) KMI
+    WRITE(ILUOUT,FMT=*) 'YOU ASK FOR A CONSTANT SPEED DOMAIN TRANSLATION '
+    WRITE(ILUOUT,FMT=*) 'BUT NOT IN THE FLAT TERRAIN CASE:'
+    WRITE(ILUOUT,FMT=*) 'THIS IS NOT ALLOWED ACTUALLY'
+ !callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+END IF
+!
+!*       4.4  Check the coherence between the LUSERn and LHORELAX
+!
+IF (.NOT. LUSERV .AND. LHORELAX_RV) THEN
+  LHORELAX_RV=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX RV FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_RV=FALSE'
+END IF
+!
+IF (.NOT. LUSERC .AND. LHORELAX_RC) THEN
+  LHORELAX_RC=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX RC FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_RC=FALSE'
+END IF
+!
+IF (.NOT. LUSERR .AND. LHORELAX_RR) THEN
+  LHORELAX_RR=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX RR FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_RR=FALSE'
+END IF
+!
+IF (.NOT. LUSERI .AND. LHORELAX_RI) THEN
+  LHORELAX_RI=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX RI FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_RI=FALSE'
+END IF
+!
+IF (.NOT. LUSERS .AND. LHORELAX_RS) THEN
+  LHORELAX_RS=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX RS FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_RS=FALSE'
+END IF
+!
+IF (.NOT. LUSERG .AND. LHORELAX_RG) THEN
+  LHORELAX_RG=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX RG FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_RG=FALSE'
+END IF
+!
+IF (.NOT. LUSERH .AND. LHORELAX_RH) THEN
+  LHORELAX_RH=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX RH FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_RH=FALSE'
+END IF
+!
+IF (CTURB=='NONE' .AND. LHORELAX_TKE) THEN
+  LHORELAX_TKE=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX TKE FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_TKE=FALSE'
+END IF
+!
+!
+IF (CCLOUD/='C2R2'  .AND. CCLOUD/='KHKO'  .AND. LHORELAX_SVC2R2) THEN
+  LHORELAX_SVC2R2=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX C2R2 or KHKO FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_SVC2R2=FALSE'
+END IF
+!
+IF (CCLOUD/='C3R5' .AND. LHORELAX_SVC1R3) THEN
+  LHORELAX_SVC1R3=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX C3R5 FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_SVC1R3=FALSE'
+END IF
+!
+IF (CCLOUD/='LIMA' .AND. LHORELAX_SVLIMA) THEN
+  LHORELAX_SVLIMA=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX LIMA FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_SVLIMA=FALSE'
+END IF
+!
+IF (CELEC(1:3) /= 'ELE' .AND. LHORELAX_SVELEC) THEN
+  LHORELAX_SVELEC=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX ELEC FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_SVELEC=FALSE'
+END IF
+!
+IF (.NOT. LUSECHEM .AND. LHORELAX_SVCHEM) THEN
+  LHORELAX_SVCHEM=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX CHEM FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_SVCHEM=FALSE'
+END IF
+!
+IF (.NOT. LUSECHIC .AND. LHORELAX_SVCHIC) THEN
+  LHORELAX_SVCHIC=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX ICE CHEM FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_SVCHIC=FALSE'
+END IF
+!
+IF (.NOT. LORILAM .AND. LHORELAX_SVAER) THEN
+  LHORELAX_SVAER=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX AEROSOL FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_SVAER=FALSE'
+END IF
+
+IF (.NOT. LDUST .AND. LHORELAX_SVDST) THEN
+  LHORELAX_SVDST=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX DUST FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_SVDST=FALSE'
+END IF
+
+IF (.NOT. LSALT .AND. LHORELAX_SVSLT) THEN
+  LHORELAX_SVSLT=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX SEA SALT FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_SVSLT=FALSE'
+END IF
+
+IF (.NOT. LPASPOL .AND. LHORELAX_SVPP) THEN
+  LHORELAX_SVPP=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX PASSIVE POLLUTANT FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_SVPP=FALSE'
+END IF
+#ifdef MNH_FOREFIRE
+IF (.NOT. LFOREFIRE .AND. LHORELAX_SVFF) THEN
+  LHORELAX_SVFF=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX FOREFIRE FLUXES BUT THEY DO NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_SVFF=FALSE'
+END IF
+#endif
+IF (.NOT. LCONDSAMP .AND. LHORELAX_SVCS) THEN
+  LHORELAX_SVCS=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX CONDITIONAL SAMPLING FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_SVCS=FALSE'
+END IF
+
+IF (.NOT. LBLOWSNOW .AND. LHORELAX_SVSNW) THEN
+  LHORELAX_SVSNW=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX BLOWING SNOW FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_SVSNW=FALSE'
+END IF
+
+IF (ANY(LHORELAX_SV(NSV+1:))) THEN
+  LHORELAX_SV(NSV+1:)=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX SV(NSV+1:) FIELD BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_SV(NSV+1:)=FALSE'
+END IF
+!
+!*       4.5   check the number of points for the horizontal relaxation
+!
+IF ( NRIMX > KRIMX .AND. .NOT.LHORELAX_SVELEC ) THEN
+  NRIMX = KRIMX 
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO USE A LARGER NUMBER OF POINTS '
+  WRITE(ILUOUT,FMT=*) 'FOR THE HORIZONTAL RELAXATION THAN THE '
+  WRITE(ILUOUT,FMT=*) 'CORRESPONDING NUMBER OF LARGE SCALE FIELDS:'
+  WRITE(ILUOUT,FMT=*) 'IT IS THEREFORE REDUCED TO NRIMX =',NRIMX
+END IF
+!
+IF ( L2D .AND. KRIMY>0 ) THEN
+  NRIMY = 0 
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO USE A 2D MODEL THEREFORE  NRIMY=0 '
+END IF
+!
+IF ( NRIMY > KRIMY .AND. .NOT.LHORELAX_SVELEC ) THEN
+  NRIMY = KRIMY 
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO USE A LARGER NUMBER OF POINTS '
+  WRITE(ILUOUT,FMT=*) 'FOR THE HORIZONTAL RELAXATION THAN THE '
+  WRITE(ILUOUT,FMT=*) 'CORRESPONDING NUMBER OF LARGE SCALE FIELDS:'
+  WRITE(ILUOUT,FMT=*) 'IT IS THEREFORE REDUCED TO NRIMY =',NRIMY
+END IF
+!
+IF ( (.NOT. LHORELAX_UVWTH) .AND. (.NOT.(ANY(LHORELAX_SV))) .AND.  &
+     (.NOT. LHORELAX_SVC2R2).AND. (.NOT. LHORELAX_SVC1R3)   .AND.  &
+     (.NOT. LHORELAX_SVLIMA).AND.                                  &
+     (.NOT. LHORELAX_SVELEC).AND. (.NOT. LHORELAX_SVCHEM)   .AND.  &
+     (.NOT. LHORELAX_SVLG)  .AND. (.NOT. LHORELAX_SVPP)     .AND.  &
+     (.NOT. LHORELAX_SVCS)  .AND.                                  &
+#ifdef MNH_FOREFIRE
+     (.NOT. LHORELAX_SVFF)  .AND.                                  &
+#endif
+     (.NOT. LHORELAX_RV)    .AND. (.NOT. LHORELAX_RC)       .AND.  &
+     (.NOT. LHORELAX_RR)    .AND. (.NOT. LHORELAX_RI)       .AND.  &
+     (.NOT. LHORELAX_RS)    .AND. (.NOT. LHORELAX_RG)       .AND.  &
+     (.NOT. LHORELAX_RH)    .AND. (.NOT. LHORELAX_TKE)      .AND.  &
+     (.NOT. LHORELAX_SVCHIC).AND.                                  &
+                                  (NRIMX /= 0 .OR. NRIMY /= 0))  THEN  
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU DO NOT WANT TO USE THE HORIZONTAL RELAXATION '
+  WRITE(ILUOUT,FMT=*) 'THEREFORE NRIMX=NRIMY=0     '
+  NRIMX=0
+  NRIMY=0
+END IF
+!
+IF ((LHORELAX_UVWTH  .OR. LHORELAX_SVPP   .OR.  &
+     LHORELAX_SVCS   .OR.                       &
+#ifdef MNH_FOREFIRE
+     LHORELAX_SVFF   .OR.                       &
+#endif
+     LHORELAX_SVC2R2 .OR. LHORELAX_SVC1R3 .OR.  &
+     LHORELAX_SVLIMA .OR.                       &
+     LHORELAX_SVELEC .OR. LHORELAX_SVCHEM .OR.  &
+     LHORELAX_SVLG   .OR. ANY(LHORELAX_SV) .OR. &
+     LHORELAX_RV     .OR. LHORELAX_RC .OR.      &
+     LHORELAX_RR     .OR. LHORELAX_RI .OR.      &
+     LHORELAX_RG     .OR. LHORELAX_RS .OR.      &
+     LHORELAX_RH     .OR. LHORELAX_TKE.OR.      &
+     LHORELAX_SVCHIC )                          &
+     .AND. (NRIMX==0 .OR. (NRIMY==0 .AND. .NOT.(L2D) ))) THEN
+  WRITE(UNIT=ILUOUT,FMT=9003) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO USE THE HORIZONTAL RELAXATION '
+  WRITE(ILUOUT,FMT=*) 'BUT NRIMX OR NRIMY=0 CHANGE YOUR VALUES   '
+  WRITE(ILUOUT,FMT=*) "LHORELAX_UVWTH=",LHORELAX_UVWTH
+  WRITE(ILUOUT,FMT=*) "LHORELAX_SVC2R2=",LHORELAX_SVC2R2
+  WRITE(ILUOUT,FMT=*) "LHORELAX_SVC1R3=",LHORELAX_SVC1R3
+  WRITE(ILUOUT,FMT=*) "LHORELAX_SVLIMA=",LHORELAX_SVLIMA
+  WRITE(ILUOUT,FMT=*) "LHORELAX_SVELEC=",LHORELAX_SVELEC
+  WRITE(ILUOUT,FMT=*) "LHORELAX_SVCHEM=",LHORELAX_SVCHEM
+  WRITE(ILUOUT,FMT=*) "LHORELAX_SVCHIC=",LHORELAX_SVCHIC
+  WRITE(ILUOUT,FMT=*) "LHORELAX_SVLG=",LHORELAX_SVLG
+  WRITE(ILUOUT,FMT=*) "LHORELAX_SVPP=",LHORELAX_SVPP
+#ifdef MNH_FOREFIRE
+  WRITE(ILUOUT,FMT=*) "LHORELAX_SVFF=",LHORELAX_SVFF
+#endif
+  WRITE(ILUOUT,FMT=*) "LHORELAX_SVCS=",LHORELAX_SVCS
+  WRITE(ILUOUT,FMT=*) "LHORELAX_SV=",LHORELAX_SV
+  WRITE(ILUOUT,FMT=*) "LHORELAX_RV=",LHORELAX_RV
+  WRITE(ILUOUT,FMT=*) "LHORELAX_RC=",LHORELAX_RC
+  WRITE(ILUOUT,FMT=*) "LHORELAX_RR=",LHORELAX_RR
+  WRITE(ILUOUT,FMT=*) "LHORELAX_RI=",LHORELAX_RI
+  WRITE(ILUOUT,FMT=*) "LHORELAX_RG=",LHORELAX_RG
+  WRITE(ILUOUT,FMT=*) "LHORELAX_RS=",LHORELAX_RS
+  WRITE(ILUOUT,FMT=*) "LHORELAX_RH=",LHORELAX_RH
+  WRITE(ILUOUT,FMT=*) "LHORELAX_TKE=", LHORELAX_TKE
+  WRITE(ILUOUT,FMT=*) "NRIMX=",NRIMX
+  WRITE(ILUOUT,FMT=*) "NRIMY=",NRIMY
+  WRITE(ILUOUT,FMT=*) "L2D=",L2D
+ !callabortstop
+  CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+END IF
+! 
+IF ((LHORELAX_UVWTH  .OR. LHORELAX_SVPP  .OR.   &
+     LHORELAX_SVCS   .OR.                       &
+#ifdef MNH_FOREFIRE
+     LHORELAX_SVFF   .OR.                       &
+#endif
+     LHORELAX_SVC2R2 .OR. LHORELAX_SVC1R3 .OR.  &
+     LHORELAX_SVLIMA .OR.                       &
+     LHORELAX_SVELEC .OR. LHORELAX_SVCHEM .OR.  &
+     LHORELAX_SVLG   .OR. ANY(LHORELAX_SV) .OR. &
+     LHORELAX_RV     .OR. LHORELAX_RC .OR.      &
+     LHORELAX_RR     .OR. LHORELAX_RI .OR.      &
+     LHORELAX_RG     .OR. LHORELAX_RS .OR.      &
+     LHORELAX_RH     .OR. LHORELAX_TKE.OR.      &
+     LHORELAX_SVCHIC )                          &
+     .AND. (KMI /=1)) THEN
+  WRITE(UNIT=ILUOUT,FMT=9003) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO USE THE HORIZONTAL RELAXATION '
+  WRITE(ILUOUT,FMT=*) 'FOR A NESTED MODEL BUT THE COUPLING IS ALREADY DONE' 
+  WRITE(ILUOUT,FMT=*) 'BY THE GRID NESTING. CHANGE LHORELAX TO FALSE'
+ !callabortstop
+  CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+END IF
+! 
+IF (KMI==1) THEN
+  GRELAX = .NOT.(OUSERV)  .AND.  LUSERV  .AND. LHORELAX_RV
+ELSE
+  GRELAX = .NOT.(LUSERV_G(NDAD(KMI)))  .AND.  LUSERV_G(KMI).AND. LHORELAX_RV 
+END IF 
+!
+IF ( GRELAX )  THEN
+  LHORELAX_RV=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX THE RV FIELD'
+  WRITE(ILUOUT,FMT=*) 'TOWARDS THE LARGE SCALE FIELD OF MODEL',NDAD(KMI)
+  WRITE(ILUOUT,FMT=*) 'BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_RV=FALSE'
+END IF
+!
+IF (KMI==1) THEN
+  GRELAX = .NOT.(OUSERC)  .AND.  LUSERC  .AND. LHORELAX_RC
+ELSE
+  GRELAX = .NOT.(LUSERC_G(NDAD(KMI)))  .AND.  LUSERC_G(KMI).AND. LHORELAX_RC 
+END IF 
+!
+IF ( GRELAX )  THEN
+  LHORELAX_RC=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX THE RC FIELD'
+  WRITE(ILUOUT,FMT=*) 'TOWARDS THE LARGE SCALE FIELD OF MODEL',NDAD(KMI)
+  WRITE(ILUOUT,FMT=*) 'BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_RC=FALSE'
+END IF
+!
+IF (KMI==1) THEN
+  GRELAX = .NOT.(OUSERR)  .AND.  LUSERR  .AND. LHORELAX_RR
+ELSE
+  GRELAX = .NOT.(LUSERR_G(NDAD(KMI)))  .AND.  LUSERR_G(KMI).AND. LHORELAX_RR 
+END IF 
+!
+IF ( GRELAX )  THEN
+  LHORELAX_RR=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX THE RR FIELD'
+  WRITE(ILUOUT,FMT=*) 'TOWARDS THE LARGE SCALE FIELD OF MODEL',NDAD(KMI)
+  WRITE(ILUOUT,FMT=*) 'BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_RR=FALSE'
+END IF
+!
+IF (KMI==1) THEN
+  GRELAX = .NOT.(OUSERI)  .AND.  LUSERI  .AND. LHORELAX_RI
+ELSE
+  GRELAX = .NOT.(LUSERI_G(NDAD(KMI)))  .AND.  LUSERI_G(KMI).AND. LHORELAX_RI 
+END IF 
+!
+IF ( GRELAX )  THEN
+  LHORELAX_RI=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX THE RI FIELD'
+  WRITE(ILUOUT,FMT=*) 'TOWARDS THE LARGE SCALE FIELD OF MODEL',NDAD(KMI)
+  WRITE(ILUOUT,FMT=*) 'BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_RI=FALSE'
+END IF
+!
+IF (KMI==1) THEN
+  GRELAX = .NOT.(OUSERG)  .AND.  LUSERG  .AND. LHORELAX_RG
+ELSE
+  GRELAX = .NOT.(LUSERG_G(NDAD(KMI)))  .AND.  LUSERG_G(KMI).AND. LHORELAX_RG 
+END IF 
+!
+IF ( GRELAX )  THEN
+  LHORELAX_RG=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX THE RG FIELD'
+  WRITE(ILUOUT,FMT=*) 'TOWARDS THE LARGE SCALE FIELD OF MODEL',NDAD(KMI)
+  WRITE(ILUOUT,FMT=*) 'BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_RG=FALSE'
+END IF
+!
+IF (KMI==1) THEN
+  GRELAX = .NOT.(OUSERH)  .AND.  LUSERH  .AND. LHORELAX_RH
+ELSE
+  GRELAX = .NOT.(LUSERH_G(NDAD(KMI)))  .AND.  LUSERH_G(KMI).AND. LHORELAX_RH 
+END IF 
+!
+IF ( GRELAX )  THEN
+  LHORELAX_RH=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX THE RH FIELD'
+  WRITE(ILUOUT,FMT=*) 'TOWARDS THE LARGE SCALE FIELD OF MODEL',NDAD(KMI)
+  WRITE(ILUOUT,FMT=*) 'BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_RH=FALSE'
+END IF
+!
+IF (KMI==1) THEN
+  GRELAX = .NOT.(OUSERS)  .AND.  LUSERS  .AND. LHORELAX_RS
+ELSE
+  GRELAX = .NOT.(LUSERS_G(NDAD(KMI)))  .AND.  LUSERS_G(KMI).AND. LHORELAX_RS 
+END IF 
+!
+IF ( GRELAX )  THEN
+  LHORELAX_RS=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX THE RS FIELD'
+  WRITE(ILUOUT,FMT=*) 'TOWARDS THE LARGE SCALE FIELD OF MODEL',NDAD(KMI)
+  WRITE(ILUOUT,FMT=*) 'BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_RS=FALSE'
+END IF
+!
+IF (KMI==1) THEN
+  GRELAX = HTURB=='NONE'  .AND.  LUSETKE(1).AND. LHORELAX_TKE
+ELSE
+  GRELAX = .NOT.(LUSETKE(NDAD(KMI)))  .AND.  LUSETKE(KMI) .AND. LHORELAX_TKE 
+END IF 
+!
+IF ( GRELAX )  THEN
+  LHORELAX_TKE=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX THE TKE FIELD'
+  WRITE(ILUOUT,FMT=*) 'TOWARDS THE LARGE SCALE FIELD OF MODEL',NDAD(KMI)
+  WRITE(ILUOUT,FMT=*) 'BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_TKE=FALSE'
+END IF
+!
+!
+DO JSV = 1,NSV_USER
+!
+  IF (KMI==1) THEN
+    GRELAX = KSV_USER<JSV  .AND.  LUSESV(JSV,1).AND.  LHORELAX_SV(JSV) 
+  ELSE
+    GRELAX = .NOT.(LUSESV(JSV,NDAD(KMI))) .AND. LUSESV(JSV,KMI) .AND. LHORELAX_SV(JSV)   
+  END IF 
+  !
+  IF ( GRELAX )  THEN
+  LHORELAX_SV(JSV)=.FALSE.
+  WRITE(UNIT=ILUOUT,FMT=9001) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO RELAX THE ',JSV,'  SV FIELD'
+  WRITE(ILUOUT,FMT=*) 'TOWARDS THE LARGE SCALE FIELD OF MODEL',NDAD(KMI)
+  WRITE(ILUOUT,FMT=*) 'BUT IT DOES NOT EXIST.'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LHORELAX_SV(',JSV,')=FALSE'
+ END IF
+END DO
+!
+!*       4.6   consistency in LES diagnostics choices
+!
+IF (CLES_NORM_TYPE=='EKMA' .AND. .NOT. LCORIO) THEN
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO USE THE EKMAN NORMALIZATION'
+  WRITE(ILUOUT,FMT=*) 'BUT CORIOLIS FORCE IS NOT USED (LCORIO=.FALSE.)'
+  WRITE(ILUOUT,FMT=*) 'THEN, NO NORMALIZATION IS PERFORMED'
+  CLES_NORM_TYPE='NONE'
+END IF
+!
+!*       4.7  Check the coherence with LNUMDIFF
+!
+IF (L1D .AND. (LNUMDIFU .OR. LNUMDIFTH .OR. LNUMDIFSV) ) THEN
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU WANT TO USE HORIZONTAL DIFFUSION '
+  WRITE(ILUOUT,FMT=*) 'BUT YOU ARE IN A COLUMN MODEL (L1D=.TRUE.).'
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LNUMDIFU and LNUMDIFTH and LNUMDIFSV'
+  WRITE(ILUOUT,FMT=*) 'ARE SET TO FALSE'
+  LNUMDIFU=.FALSE.
+  LNUMDIFTH=.FALSE.
+  LNUMDIFSV=.FALSE.
+END IF
+!
+IF (.NOT. LNUMDIFTH .AND. LZDIFFU) THEN
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(ILUOUT,FMT=*) 'YOU DO NOT WANT TO USE HORIZONTAL DIFFUSION (LNUMDIFTH=F)'
+  WRITE(ILUOUT,FMT=*) 'BUT YOU WANT TO USE Z-NUMERICAL DIFFUSION  '
+  WRITE(ILUOUT,FMT=*) 'THEREFORE LNUMDIFTH IS SET TO TRUE'
+  LNUMDIFTH=.TRUE.
+END IF
+!
+!*       4.8  Other
+!
+IF (XTNUDGING < 4.*XTSTEP) THEN
+  XTNUDGING = 4.*XTSTEP
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(UNIT=ILUOUT,FMT='("TIME SCALE FOR NUDGING CAN NOT BE SMALLER THAN",  &
+                 &   " FOUR TIMES THE TIME STEP")')
+  WRITE(ILUOUT,FMT=*) 'XTNUDGING is SET TO ',XTNUDGING
+END IF
+!
+!
+IF (XWAY(KMI) == 3. ) THEN
+  XWAY(KMI) = 2.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(UNIT=ILUOUT,FMT='("XWAY=3 DOES NOT EXIST ANYMORE; ", &                               
+                 &   " IT IS REPLACED BY XWAY=2 ")')
+END IF
+!
+IF ( (KMI == 1) .AND. XWAY(KMI) /= 0. ) THEN
+  XWAY(KMI) = 0.
+  WRITE(UNIT=ILUOUT,FMT=9002) KMI
+  WRITE(UNIT=ILUOUT,FMT='("XWAY MUST BE EQUAL TO 0 FOR DAD MODEL")')   
+END IF
+!
+!JUANZ ZRESI solver need BSPLITTING 
+IF ( CPRESOPT == 'ZRESI' .AND. CSPLIT /= 'BSPLITTING' ) THEN
+  WRITE(UNIT=ILUOUT,FMT=9003) KMI
+  WRITE(UNIT=ILUOUT,FMT='("Paralleliez in Z solver CPRESOPT=ZRESI need also CSPLIT=BSPLITTING ")')
+  WRITE(ILUOUT,FMT=*) ' ERROR you have to set also CSPLIT=BSPLITTING '
+ !callabortstop
+  CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+END IF
+!
+IF ( LEN_TRIM(HINIFILEPGD)>0 ) THEN
+  IF ( CINIFILEPGD/=HINIFILEPGD ) THEN 
+    WRITE(UNIT=ILUOUT,FMT=9001) KMI
+    WRITE(ILUOUT,FMT=*) ' ERROR : in EXSEG1.nam, in NAM_LUNITn you have CINIFILEPGD= ',CINIFILEPGD
+    WRITE(ILUOUT,FMT=*) ' whereas in .des you have CINIFILEPGD= ',HINIFILEPGD
+    WRITE(ILUOUT,FMT=*) ' Please check your Namelist '
+    WRITE(ILUOUT,FMT=*) ' For example, you may have specified the un-nested PGD file instead of the nested PGD file '
+    WRITE(ILUOUT,FMT=*) 
+    WRITE(ILUOUT,FMT=*) '###############'
+    WRITE(ILUOUT,FMT=*) ' MESONH ABORTS'
+    WRITE(ILUOUT,FMT=*) '###############'
+    WRITE(ILUOUT,FMT=*) 
+ !callabortstop
+    CALL PRINT_MSG(NVERB_FATAL,'GEN','READ_EXSEG_n','')
+  END IF
+ELSE
+  CINIFILEPGD = ''
+!* note that after a spawning, there is no value for CINIFILEPGD in the .des file,
+!  so the checking cannot be made if the user starts a simulation directly from
+!  a spawned file (without the prep_real_case stage)
+END IF
+!-------------------------------------------------------------------------------
+!
+!*       5.    WE DO NOT FORGET TO UPDATE ALL DOLLARN NAMELIST VARIABLES
+!              ---------------------------------------------------------
+!
+CALL UPDATE_NAM_LUNITN
+CALL UPDATE_NAM_CONFN
+CALL UPDATE_NAM_DYNN
+CALL UPDATE_NAM_ADVN
+CALL UPDATE_NAM_PARAMN
+CALL UPDATE_NAM_PARAM_RADN
+#ifdef MNH_ECRAD
+CALL UPDATE_NAM_PARAM_ECRADN
+#endif
+CALL UPDATE_NAM_PARAM_KAFRN
+CALL UPDATE_NAM_PARAM_MFSHALLN
+CALL UPDATE_NAM_LBCN
+CALL UPDATE_NAM_NUDGINGN
+CALL UPDATE_NAM_TURBN
+CALL UPDATE_NAM_CH_MNHCN
+CALL UPDATE_NAM_CH_SOLVERN
+CALL UPDATE_NAM_SERIESN
+CALL UPDATE_NAM_BLOWSNOWN
+!-------------------------------------------------------------------------------
+WRITE(UNIT=ILUOUT,FMT='(/)')
+!-------------------------------------------------------------------------------
+!
+!*       6.    FORMATS
+!              -------
+!
+9000  FORMAT(/,'NOTE  IN READ_EXSEG FOR MODEL ', I2, ' : ',/, &
+             '--------------------------------')
+9001  FORMAT(/,'CAUTION ERROR IN READ_EXSEG FOR MODEL ', I2,' : ',/, &
+             '----------------------------------------' )
+9002  FORMAT(/,'WARNING IN READ_EXSEG FOR MODEL ', I2,' : ',/, &
+             '----------------------------------' )
+9003  FORMAT(/,'FATAL ERROR IN READ_EXSEG FOR MODEL ', I2,' : ',/, &
+             '--------------------------------------' )
+!
+!-------------------------------------------------------------------------------
+!
+END SUBROUTINE READ_EXSEG_n
diff --git a/src/ZSOLVER/spectre.f90 b/src/ZSOLVER/spectre.f90
new file mode 100644
index 0000000000000000000000000000000000000000..545c60629410ef29c5a16bfd5289f96038c41e28
--- /dev/null
+++ b/src/ZSOLVER/spectre.f90
@@ -0,0 +1,217 @@
+!MNH_LIC Copyright 2011-2019 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+!     ######spl
+      PROGRAM SPECTRE
+!     ############
+!
+!!****
+!!
+!!    PURPOSE
+!!    -------
+!!    compute energy spectra from a MESONH file
+!!
+!!
+!!
+!!
+!! Modifications:
+!!  Philippe Wautelet: 05/2016-04/2018: new data structures and calls for I/O
+!-------------------------------------------------------------------------------
+!
+!*       0.     DECLARATIONS
+!               ------------
+!
+!
+USE MODD_CONF
+USE MODD_IO, ONLY: NIO_VERB,NVERB_DEBUG,TFILEDATA
+USE MODD_LUNIT
+USE MODD_LUNIT_n
+USE MODD_TIME_n
+USE MODD_DIM_ll
+USE MODD_SPECTRE
+!
+USE MODI_SPECTRE_MESONH
+USE MODI_SPECTRE_AROME
+!
+USE MODE_MSG
+USE MODE_POS
+USE MODE_IO,               only: IO_Config_set, IO_Init
+USE MODE_IO_FILE,          only: IO_File_close, IO_File_open
+USE MODE_IO_MANAGE_STRUCT, only: IO_File_add2list, IO_Filelist_print
+use mode_init_ll,          only: END_PARA_ll
+USE MODE_MODELN_HANDLER
+!USE MODD_TYPE_DATE
+USE MODI_VERSION
+!
+USE MODN_CONFZ
+USE MODN_CONFIO, ONLY : NAM_CONFIO
+!
+IMPLICIT NONE
+!
+!*       0.1   declarations of local variables
+!
+CHARACTER (LEN=28), DIMENSION(1) :: YINIFILE      ! names of the INPUT FM-file
+CHARACTER (LEN=50)               :: YOUTFILE      ! names of the OUTPUT FM-file
+INTEGER                          :: IRESP         ! return code in FM routines
+INTEGER                          :: ILUOUT0       ! Logical unit number for the output listing
+INTEGER                          :: ILUNAM        ! Logical unit numbers for the namelist file
+                                                  ! and for output_listing file
+LOGICAL                          :: GFOUND        ! Return code when searching namelist
+!
+INTEGER                          :: IINFO_ll      ! return code for _ll routines 
+!
+REAL,DIMENSION(:,:,:),ALLOCATABLE:: ZWORK         ! work array
+REAL,DIMENSION(:,:,:),ALLOCATABLE:: ZWORKAROME    ! work array
+INTEGER :: NI,NJ,NK
+REAL    ::XDELTAX,XDELTAY
+TYPE(TFILEDATA),POINTER :: TZNMLFILE  => NULL()
+!
+NAMELIST/NAM_SPECTRE/ LSPECTRE_U,LSPECTRE_V,LSPECTRE_W,LSPECTRE_TH,LSPECTRE_RV,&
+                      LSPECTRE_LSU,LSPECTRE_LSV,LSPECTRE_LSW,LSPECTRE_LSTH,LSPECTRE_LSRV,LSMOOTH
+!
+NAMELIST/NAM_SPECTRE_FILE/ YINIFILE,CTYPEFILE,YOUTFILE,LSTAT 
+NAMELIST/NAM_ZOOM_SPECTRE/ LZOOM,NITOT,NJTOT,NXDEB,NYDEB 
+NAMELIST/NAM_DOMAIN_AROME/ NI,NJ,NK,XDELTAX,XDELTAY
+!
+!-------------------------------------------------------------------------------
+!
+!*       0.0   Initializations
+!              ---------------
+!
+!
+CALL GOTO_MODEL(1)
+!
+CALL VERSION
+CPROGRAM='SPEC  '
+!
+CALL IO_Init()
+!
+! initialization 
+YINIFILE(:)   = '                         '
+CTYPEFILE     = 'MESONH'
+LSPECTRE_U    = .FALSE.
+LSPECTRE_V    = .FALSE.
+LSPECTRE_W    = .FALSE.
+LSPECTRE_TH   = .FALSE.
+LSPECTRE_RV   = .FALSE.
+LSPECTRE_LSU  = .FALSE.
+LSPECTRE_LSV  = .FALSE.
+LSPECTRE_LSW  = .FALSE.
+LSPECTRE_LSTH = .FALSE.
+LSPECTRE_LSRV = .FALSE.
+LSMOOTH       = .FALSE.
+LZOOM         = .FALSE.
+YOUTFILE      = '                         '
+LSTAT         = .FALSE.
+NI=750
+NJ=720
+NK=60
+XDELTAX=2500.
+XDELTAY=2500.
+!
+!
+!-------------------------------------------------------------------------------
+!
+!*       1.0   Namelist reading
+!              ----------------
+!
+PRINT*, ' '
+PRINT*, '*********************************************************************'
+PRINT*, '*********************************************************************'
+PRINT*, ' '
+!
+CALL IO_File_add2list(TZNMLFILE,'SPEC1.nam','NML','READ')
+CALL IO_File_open(TZNMLFILE)
+ILUNAM = TZNMLFILE%NLU
+!
+PRINT*, 'READ THE SPEC1.NAM FILE'
+!
+CALL POSNAM(ILUNAM,'NAM_SPECTRE',GFOUND)
+IF (GFOUND) THEN
+  READ(UNIT=ILUNAM,NML=NAM_SPECTRE)
+  PRINT*, '  namelist NAM_SPECTRE read'
+END IF
+!
+!
+CALL POSNAM(ILUNAM,'NAM_SPECTRE_FILE',GFOUND)
+IF (GFOUND) THEN
+  READ(UNIT=ILUNAM,NML=NAM_SPECTRE_FILE)
+  PRINT*, '  namelist NAM_SPECTRE_FILE read'
+END IF
+!
+CALL POSNAM(ILUNAM,'NAM_ZOOM_SPECTRE',GFOUND)
+IF (GFOUND) THEN
+  READ(UNIT=ILUNAM,NML=NAM_ZOOM_SPECTRE)
+  PRINT*, '  namelist NAM_ZOOM_SPECTRE read'
+END IF
+!
+CALL POSNAM(ILUNAM,'NAM_DOMAIN_AROME',GFOUND)
+IF (GFOUND) THEN
+  READ(UNIT=ILUNAM,NML=NAM_DOMAIN_AROME)
+  PRINT*, '  namelist NAM_DOMAIN_AROME read'
+END IF
+!
+CALL POSNAM(ILUNAM,'NAM_CONFZ',GFOUND)
+IF (GFOUND) THEN
+  READ(UNIT=ILUNAM,NML=NAM_CONFZ)
+  PRINT*, '  namelist NAM_CONFZ read'
+END IF
+!
+CALL POSNAM(ILUNAM,'NAM_CONFIO',GFOUND)
+IF (GFOUND) THEN
+  READ(UNIT=ILUNAM,NML=NAM_CONFIO)
+  PRINT*, '  namelist NAM_CONFIO read'
+END IF
+CALL IO_Config_set()
+!
+CALL IO_File_close(TZNMLFILE)
+!
+CINIFILE = YINIFILE(1)
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.0   file
+!              -----------
+!
+IF ( LEN_TRIM(CINIFILE)==0 ) THEN
+  CALL PRINT_MSG(NVERB_FATAL,'GEN','SPECTRE','LEN_TRIM(CINIFILE)==0')
+ENDIF
+!
+IF ( LEN_TRIM(YOUTFILE)==0 ) THEN
+  WRITE(YOUTFILE,FMT='(A,A)') "spectra_",TRIM(ADJUSTL(CINIFILE))
+ENDIF
+!
+!-------------------------------------------------------------------------------
+!
+!*       3.0   Fields initialization and spectra computation
+!
+IF (CTYPEFILE=='MESONH') THEN
+  CALL SPECTRE_MESONH(YOUTFILE)
+  !
+  CALL IO_File_close(LUNIT_MODEL(1)%TINIFILE)
+  IF(NIO_VERB>=NVERB_DEBUG) CALL IO_Filelist_print()
+  CALL IO_File_close(TLUOUT0)
+  CALL IO_File_close(TLUOUT)
+ELSEIF (CTYPEFILE=='AROME ')THEN
+ CALL SPECTRE_AROME(CINIFILE,YOUTFILE,XDELTAX,XDELTAY,NI,NJ,NK)
+ELSE
+  print*,"This type of file is not accept for SPECTRE PROGRAM"
+ENDIF
+!
+!-------------------------------------------------------------------------------
+!
+!*      4.    FINALIZE THE PARALLEL SESSION
+!              -----------------------------
+!
+CALL END_PARA_ll(IINFO_ll)
+!
+PRINT*, ' '
+PRINT*, '****************************************************'
+PRINT*, '*            EXIT  SPECTRE CORRECTLY          *'
+PRINT*, '****************************************************'
+PRINT*, ' '
+!-------------------------------------------------------------------------------
+END PROGRAM SPECTRE
+
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/communication.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/communication.f90
new file mode 100644
index 0000000000000000000000000000000000000000..794ac3a6f7c58f7c1bfdfb1baf02ed5b37386273
--- /dev/null
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/communication.f90
@@ -0,0 +1,2022 @@
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+!
+!  This file is part of the TensorProductMultigrid code.
+!  
+!  (c) The copyright relating to this work is owned jointly by the
+!  Crown, Met Office and NERC [2014]. However, it has been created
+!  with the help of the GungHo Consortium, whose members are identified
+!  at https://puma.nerc.ac.uk/trac/GungHo/wiki .
+!  
+!  Main Developer: Eike Mueller
+!  
+!  TensorProductMultigrid is free software: you can redistribute it and/or
+!  modify it under the terms of the GNU Lesser General Public License as
+!  published by the Free Software Foundation, either version 3 of the
+!  License, or (at your option) any later version.
+!  
+!  TensorProductMultigrid is distributed in the hope that it will be useful,
+!  but WITHOUT ANY WARRANTY; without even the implied warranty of
+!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+!  GNU Lesser General Public License for more details.
+!  
+!  You should have received a copy of the GNU Lesser General Public License
+!  along with TensorProductMultigrid (see files COPYING and COPYING.LESSER).
+!  If not, see <http://www.gnu.org/licenses/>.
+!
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+
+
+!==================================================================
+!
+!  MPI communication routines for multigrid code
+!
+!    Eike Mueller, University of Bath, Feb 2012
+!
+!==================================================================
+
+module communication
+  use messages
+  use datatypes
+
+#ifndef MNH
+  use mpi
+#else
+  use modd_mpif
+#endif   
+  use timer
+
+  use mode_mnh_allocate_mg_halo
+
+  implicit none
+
+public::comm_preinitialise
+public::comm_initialise
+public::comm_finalise
+public::scalarprod_mnh
+public::scalarprod
+public::print_scalaprod2
+public::boundary_mnh
+public::haloswap_mnh
+public::haloswap
+public::ihaloswap_mnh
+public::ihaloswap
+public::collect
+public::distribute
+public::i_am_master_mpi
+public::master_rank
+public::pproc
+public::MPI_COMM_HORIZ
+public::comm_parameters
+public::comm_measuretime
+
+
+  ! Number of processors
+  ! n_proc = 2^(2*pproc), with integer pproc
+  integer :: pproc
+
+! Rank of master process
+  integer, parameter :: master_rank = 0
+! Am I the master process?
+  logical :: i_am_master_mpi
+
+  integer, parameter :: dim = 3  ! Dimension
+  integer, parameter :: dim_horiz = 2  ! Horizontal dimension
+  integer :: MPI_COMM_HORIZ ! Communicator with horizontal partitioning
+
+private
+
+! Data types for halo exchange in both x- and y-direction
+  integer, dimension(:,:,:), allocatable :: halo_type
+
+! Array for Halo Exchange <-> GPU copy/managed
+  type type_halo_T
+     real, dimension(:,:,:), pointer, contiguous :: haloTin,haloTout
+  end type type_halo_T
+! MPI vector data types
+  ! Halo for data exchange in north-south direction
+  integer, allocatable, dimension(:,:) :: halo_ns
+  integer, allocatable, dimension(:,:) :: halo_nst
+  type(type_halo_T), allocatable, dimension(:,:) :: tab_halo_nt
+  type(type_halo_T), allocatable, dimension(:,:) :: tab_halo_st
+  integer, allocatable, dimension(:,:) :: halo_wet
+  type(type_halo_T), allocatable, dimension(:,:) :: tab_halo_wt
+  type(type_halo_T), allocatable, dimension(:,:) :: tab_halo_et
+  ! Vector data type for interior of field a(level,m)
+  integer, allocatable, dimension(:,:) :: interior
+  integer, allocatable, dimension(:,:) :: interiorT
+  type(type_halo_T), allocatable, dimension(:,:) :: tab_interiorT_ne,tab_interiorT_sw,tab_interiorT_se
+  ! Vector data type for one quarter of interior of field
+  ! at level a(level,m). This has the same size (and can be
+  ! used for communications with) the interior of a(level,m+1)
+  integer, allocatable, dimension(:,:) :: sub_interior
+  integer, allocatable, dimension(:,:) :: sub_interiorT
+  type(type_halo_T), allocatable, dimension(:,:) :: tab_sub_interiorT_ne,tab_sub_interiorT_sw,tab_sub_interiorT_se
+  ! Timer for halo swaps
+  type(time), allocatable, dimension(:,:) :: t_haloswap
+  ! Timer for collect and distribute
+  type(time), allocatable, dimension(:) :: t_collect
+  type(time), allocatable, dimension(:) :: t_distribute
+  ! Parallelisation parameters
+  ! Measure communication times?
+  logical :: comm_measuretime
+
+  ! Parallel communication parameters
+  type comm_parameters
+    ! Size of halos
+    integer :: halo_size
+  end type comm_parameters
+
+  type(comm_parameters) :: comm_param
+
+! Data layout
+! ===========
+!
+!  The number of processes has to be of the form nproc = 2^(2*pproc) to
+!  ensure that data can be distributed between processes.
+!  The processes are arranged in a (2^pproc) x (2^pproc) cartesian grid
+!  in the horizontal plane (i.e. vertical columns are always local to one
+!  process), which is implemented via the communicator MPI_COMM_HORIZ.
+!  This MPI_cart_rank() and MPI_cart_shift() can then be used to
+!  easily identify neighbouring processes.
+
+!  The number of data grid cells in each direction has to be a multiply
+!  of 2**(L-1) where L is the number of levels (including the coarse
+!  and fine level), with the coarse level corresponding to level=1.
+!  Also define L_split as the level where we start to pull together
+!  data. For levels > L_split each position in the cartesian grid is
+!  included in the work, below this only a subset of processes is
+!  used.
+!
+!  Each grid a(level,m) is identified by two numbers:
+!  (1) The multigrid level it belongs to (level)
+!  (2) The number of active processes that operate on it (2^(2*m)).
+!
+!  For level > L_split, m=procp. For L_split we store a(L_split,pproc) and
+!  a(L_split,pproc-1), and only processes with even coordinates in both
+!  horizontal directions use this grid.
+!  Below that level, store a(L_split-1,pproc-1) and a(L_split-1,pproc-2),
+!  where only processes for which both horiontal coordinates are
+!  multiples of four use the latter. This is continued until only on
+!  process is left.
+!
+!
+!  level
+!    L          a(L,pproc)
+!    L-1        a(L-1,pproc)
+!    ...
+!    L_split    a(L_split,pproc)    a(L_split  ,pproc-1)
+!    L_split-1                      a(L_split-1,pproc-1)  a(L_split-1,pproc-2)
+!
+!                                                                  ... a(3,1)
+!                                                                      a(2,1)
+!                                                                      a(1,1)
+!
+!  When moving from left to right in the above graph the total number of
+!  grid cells does not change, but the number of data points per process
+!  increases by a factor of 4.
+!
+! Parallel operations
+! ===================
+!
+!   (*)  Halo exchange. Update halo with data from neighbouring
+!        processors in cartesian grid on current (level,m)
+!   (*)  Collect data on all processes at (level,m) on those
+!        processes that are still active on (level,m-1).
+!   (*)  Distribute data at (level,m-1) and duplicate on all processes
+!        that are active at (level,m).
+!
+!   Note that in the cartesian processor grid the first coordinate
+!   is the North-South (y-) direction, the second coordinate is the
+!   East-West (x-) direction, i.e. the layout is this:
+!
+!   p_0 (0,0)   p_1 (0,1)   p_2 (0,2)   p_3 (0,3)
+!
+!   p_4 (1,0)   p_5 (1,1)   p_6 (1,2)   p_7 (1,3)
+!
+!   p_8 (2,0)   p_9 (2,1)   p_10 (2,2)  p_11 (2,3)
+!
+!                       [...]
+!
+!
+!   Normal multigrid restriction and prolongation are used to
+!   move between levels with fixed m.
+!
+!
+
+contains
+
+!==================================================================
+! Pre-initialise communication routines
+!==================================================================
+  subroutine comm_preinitialise()
+    implicit none
+    integer :: nproc, ierr, rank
+    call mpi_comm_size(MPI_COMM_WORLD, nproc, ierr)
+    call mpi_comm_rank(MPI_COMM_WORLD, rank, ierr)
+    i_am_master_mpi = (rank == master_rank)
+    ! Check that nproc = 2^(2*p)
+    pproc = floor(log(1.0d0*nproc)/log(4.0d0))
+    if ( (nproc - 4**pproc) .ne. 0) then
+      call fatalerror("Number of processors has to be 2^(2*pproc) with integer pproc.")
+    end if
+    if (i_am_master_mpi) then
+      write(STDOUT,'("PARALLEL RUN")')
+      write(STDOUT,'("Number of processors : 2^(2*pproc) = ",I10," with pproc = ",I6)') &
+        nproc, pproc
+    end if
+    ! Create halo data types
+
+  end subroutine comm_preinitialise
+
+!==================================================================
+! Initialise communication routines
+!==================================================================
+  subroutine comm_initialise(n_lev,        & !} multigrid parameters
+                            lev_split,     & !}
+                            grid_param,    & ! Grid parameters
+                            comm_param_in)   ! Parallel communication
+                                             ! parameters
+    implicit none
+    integer, intent(in) :: n_lev
+    integer, intent(in) :: lev_split
+    type(grid_parameters), intent(inout) :: grid_param
+    type(comm_parameters), intent(in)    :: comm_param_in
+    integer :: n
+    integer :: nz
+    integer :: rank, nproc, ierr
+    integer :: count, blocklength, stride
+    integer, dimension(2) :: p_horiz
+    integer :: m, level, nlocal
+    logical :: reduced_m
+    integer :: halo_size
+    character(len=32) :: t_label
+
+    integer,parameter    :: nb_dims=3
+    integer,dimension(nb_dims) :: profil_tab,profil_sous_tab,coord_debut
+
+    n = grid_param%n
+    nz = grid_param%nz
+
+    comm_param = comm_param_in
+    halo_size = comm_param%halo_size
+
+    call mpi_comm_size(MPI_COMM_WORLD, nproc, ierr)
+
+    ! Create cartesian topology
+    call mpi_cart_create(MPI_COMM_WORLD,        & ! Old communicator name
+                         dim_horiz,             & ! horizontal dimension
+                         (/2**pproc,2**pproc/), & ! extent in each horizontal direction
+                         (/.false.,.false./),   & ! periodic?
+                         .true.,                & ! reorder?
+                         MPI_COMM_HORIZ,        & ! Name of new communicator
+                         ierr)
+   ! calculate and display rank and corrdinates in cartesian grid
+    call mpi_comm_rank(MPI_COMM_HORIZ, rank, ierr)
+    call mpi_cart_coords(MPI_COMM_HORIZ,rank,dim_horiz,p_horiz,ierr)
+
+    ! Local size of (horizontal) grid
+    nlocal = n/2**pproc
+
+    ! === Set up data types ===
+    ! Halo for exchange in north-south direction
+    if (LUseO) allocate(halo_ns(n_lev,0:pproc))
+    if (LUseT) allocate(halo_nst(n_lev,0:pproc))
+    if (LUseT) allocate(tab_halo_nt(n_lev,0:pproc))
+    if (LUseT) allocate(tab_halo_st(n_lev,0:pproc))
+    if (LUseT) allocate(halo_wet(n_lev,0:pproc))
+    if (LUseT) allocate(tab_halo_wt(n_lev,0:pproc))
+    if (LUseT) allocate(tab_halo_et(n_lev,0:pproc))
+    ! Interior data types
+    if (LUseO) allocate(interior(n_lev,0:pproc))
+    if (LUseO) allocate(sub_interior(n_lev,0:pproc))
+    if (LUseT) allocate(interiorT(n_lev,0:pproc))
+    if (LUseT) allocate(sub_interiorT(n_lev,0:pproc))
+    if (LUseT) allocate(tab_interiorT_ne(n_lev,0:pproc))
+    if (LUseT) allocate(tab_interiorT_sw(n_lev,0:pproc))
+    if (LUseT) allocate(tab_interiorT_se(n_lev,0:pproc))
+    if (LUseT) allocate(tab_sub_interiorT_ne(n_lev,0:pproc))
+    if (LUseT) allocate(tab_sub_interiorT_sw(n_lev,0:pproc))
+    if (LUseT) allocate(tab_sub_interiorT_se(n_lev,0:pproc))
+    ! Timer
+    allocate(t_haloswap(n_lev,0:pproc))
+    allocate(t_collect(0:pproc))
+    allocate(t_distribute(0:pproc))
+    do m=0,pproc
+      write(t_label,'("t_collect(",I3,")")') m
+      call initialise_timer(t_collect(m),t_label)
+      write(t_label,'("t_distribute(",I3,")")') m
+      call initialise_timer(t_distribute(m),t_label)
+    end do
+
+    m = pproc
+    level = n_lev
+    reduced_m = .false.
+    do while (level > 0)
+      ! --- Create halo data types ---
+      if (LUseO) then
+      ! NS- (y-) direction
+      count = nlocal
+      blocklength = (nz+2)*halo_size
+      stride = (nlocal+2*halo_size)*(nz+2)
+      call mpi_type_vector(count,blocklength,stride,MPI_DOUBLE_PRECISION, &
+                           halo_ns(level,m),ierr)
+      call mpi_type_commit(halo_ns(level,m),ierr)
+      endif
+      ! tranpose
+      if (LUseT) then
+      ! NS- (y-) transpose direction
+      count =        nz+2                                        ! nlocal
+      blocklength =  nlocal*halo_size                            ! (nz+2)*halo_size
+      stride =       (nlocal+2*halo_size) * (nlocal+2*halo_size) ! (nlocal+2*halo_size)*(nz+2)
+      call mpi_type_vector(count,blocklength,stride,MPI_DOUBLE_PRECISION, &
+                           halo_nst(level,m),ierr)
+      call mpi_type_commit(halo_nst(level,m),ierr)
+      ! allocate send/recv buffer for GPU copy/managed
+      call mnh_allocate_mg_halo(tab_halo_nt(level,m)%haloTin,nlocal,halo_size,nz+2)
+      call mnh_allocate_mg_halo(tab_halo_nt(level,m)%haloTout,nlocal,halo_size,nz+2)
+      call mnh_allocate_mg_halo(tab_halo_st(level,m)%haloTin,nlocal,halo_size,nz+2)
+      call mnh_allocate_mg_halo(tab_halo_st(level,m)%haloTout,nlocal,halo_size,nz+2)      
+      
+     ! WE- (x-) transpose direction
+      count =        (nz+2)*(nlocal+2*halo_size)*halo_size       ! nlocal
+      blocklength =  1*halo_size                                 ! (nz+2)*halo_size
+      stride =       nlocal+2*halo_size                          ! (nlocal+2*halo_size)*(nz+2)
+      call mpi_type_vector(count,blocklength,stride,MPI_DOUBLE_PRECISION, &
+                           halo_wet(level,m),ierr)
+      call mpi_type_commit(halo_wet(level,m),ierr)
+      ! allocate send/recv buffer for GPU copy/managed      !
+      call mnh_allocate_mg_halo(tab_halo_wt(level,m)%haloTin,halo_size,nlocal+2*halo_size,nz+2)
+      call mnh_allocate_mg_halo(tab_halo_wt(level,m)%haloTout,halo_size,nlocal+2*halo_size,nz+2)
+      call mnh_allocate_mg_halo(tab_halo_et(level,m)%haloTin,halo_size,nlocal+2*halo_size,nz+2)
+      call mnh_allocate_mg_halo(tab_halo_et(level,m)%haloTout,halo_size,nlocal+2*halo_size,nz+2)      
+      endif
+#ifndef NDEBUG
+  if (ierr .ne. 0) &
+    call fatalerror("Commit halo_ns failed in mpi_type_commit().")
+#endif
+      ! --- Create interior data types ---
+      if (LUseO) then
+         count = nlocal
+         blocklength = nlocal*(nz+2)
+         stride = (nz+2)*(nlocal+2*halo_size)
+         call mpi_type_vector(count,blocklength,stride,MPI_DOUBLE_PRECISION,interior(level,m),ierr)
+         call mpi_type_commit(interior(level,m),ierr)
+         count = nlocal/2
+         blocklength = nlocal/2*(nz+2)
+         stride = (nlocal+2*halo_size)*(nz+2)
+         call mpi_type_vector(count,blocklength,stride,MPI_DOUBLE_PRECISION,sub_interior(level,m),ierr)
+         call mpi_type_commit(sub_interior(level,m),ierr)
+      end if
+      if (LUseT) then
+         ! interiorT
+         if ( nlocal /= 0 ) then
+            profil_tab      = (/ nlocal+2*halo_size , nlocal+2*halo_size , nz+2 /)
+            profil_sous_tab = (/ nlocal             , nlocal             , nz+2 /)
+            coord_debut     = (/ 0                  , 0                  , 0    /)
+            call MPI_TYPE_CREATE_SUBARRAY(nb_dims,profil_tab,profil_sous_tab,coord_debut,&
+                 MPI_ORDER_FORTRAN,MPI_DOUBLE_PRECISION,interiorT(level,m),ierr)
+            call mpi_type_commit(interiorT(level,m),ierr)
+            call mnh_allocate_mg_halo(tab_interiorT_ne(level,m)%haloTin,nlocal,nlocal,nz+2)
+            call mnh_allocate_mg_halo(tab_interiorT_ne(level,m)%haloTout,nlocal,nlocal,nz+2)
+            call mnh_allocate_mg_halo(tab_interiorT_sw(level,m)%haloTin,nlocal,nlocal,nz+2)
+            call mnh_allocate_mg_halo(tab_interiorT_sw(level,m)%haloTout,nlocal,nlocal,nz+2)
+            call mnh_allocate_mg_halo(tab_interiorT_se(level,m)%haloTin,nlocal,nlocal,nz+2)
+            call mnh_allocate_mg_halo(tab_interiorT_se(level,m)%haloTout,nlocal,nlocal,nz+2)
+         end if
+         ! sub_interiorT
+         if ( (nlocal/2) /= 0 ) then
+            profil_tab      = (/ nlocal+2*halo_size , nlocal+2*halo_size , nz+2 /)
+            profil_sous_tab = (/ nlocal/2           , nlocal/2           , nz+2 /)
+            coord_debut     = (/ 0                  , 0                  , 0    /)
+            call MPI_TYPE_CREATE_SUBARRAY(nb_dims,profil_tab,profil_sous_tab,coord_debut,&
+                 MPI_ORDER_FORTRAN,MPI_DOUBLE_PRECISION,sub_interiorT(level,m),ierr)
+            call mpi_type_commit(sub_interiorT(level,m),ierr)
+            call mnh_allocate_mg_halo(tab_sub_interiorT_ne(level,m)%haloTin,nlocal/2,nlocal/2,nz+2)
+            call mnh_allocate_mg_halo(tab_sub_interiorT_ne(level,m)%haloTout,nlocal/2,nlocal/2,nz+2)
+            call mnh_allocate_mg_halo(tab_sub_interiorT_sw(level,m)%haloTin,nlocal/2,nlocal/2,nz+2)
+            call mnh_allocate_mg_halo(tab_sub_interiorT_sw(level,m)%haloTout,nlocal/2,nlocal/2,nz+2)
+            call mnh_allocate_mg_halo(tab_sub_interiorT_se(level,m)%haloTin,nlocal/2,nlocal/2,nz+2)
+            call mnh_allocate_mg_halo(tab_sub_interiorT_se(level,m)%haloTout,nlocal/2,nlocal/2,nz+2)            
+         end if
+      end if
+      ! --- Create timers ---
+      write(t_label,'("t_haloswap(",I3,",",I3,")")') level,m
+      call initialise_timer(t_haloswap(level,m),t_label)
+
+      ! If we are below L_split, split data
+      if ( (level .le. lev_split) .and. (m > 0) .and. (.not. reduced_m)) then
+        reduced_m = .true.
+        m = m-1
+        nlocal = 2*nlocal
+        cycle
+      end if
+      reduced_m = .false.
+      level = level-1
+      nlocal = nlocal/2
+    end do
+
+  end subroutine comm_initialise
+
+!==================================================================
+! Finalise communication routines
+!==================================================================
+  subroutine comm_finalise(n_lev,   &  ! } Multigrid parameters
+                           lev_split,  & !}
+                           grid_param )  ! } Grid parameters
+    implicit none
+    integer, intent(in) :: n_lev
+    integer, intent(in) :: lev_split
+    type(grid_parameters), intent(in) :: grid_param
+    ! local var
+    logical :: reduced_m
+    integer :: level, m
+    integer :: ierr
+    integer :: nlocal,n
+    character(len=80) :: s
+
+   ! Local size of (horizontal) grid
+    n = grid_param%n
+    nlocal = n/2**pproc
+
+    m = pproc
+    level = n_lev
+    reduced_m = .false.
+    if (i_am_master_mpi) then
+      write(STDOUT,'(" *** Finalising communications ***")')
+    end if
+    call print_timerinfo("--- Communication timing results ---")
+    do while (level > 0)
+      write(s,'("level = ",I3,", m = ",I3)') level, m
+      call print_timerinfo(s)
+      ! --- Print out timer information ---
+      call print_elapsed(t_haloswap(level,m),.True.,1.0_rl)
+      ! --- Free halo data types ---
+      if (LUseO) call mpi_type_free(halo_ns(level,m),ierr)
+      if (LUseT) call mpi_type_free(halo_nst(level,m),ierr)
+      if (LUseT) call mpi_type_free(halo_wet(level,m),ierr)
+      ! --- Free interior data types ---
+      if (LUseO) call mpi_type_free(interior(level,m),ierr)
+      if (LUseO) call mpi_type_free(sub_interior(level,m),ierr)
+      if (LUseT .and. (nlocal /= 0 ) ) call mpi_type_free(interiorT(level,m),ierr)
+      if (LUseT .and. ( (nlocal/2) /= 0 ) ) call mpi_type_free(sub_interiorT(level,m),ierr)
+      ! If we are below L_split, split data
+      if ( (level .le. lev_split) .and. (m > 0) .and. (.not. reduced_m)) then
+        reduced_m = .true.
+        m = m-1
+        nlocal = 2*nlocal
+        cycle
+      end if
+      reduced_m = .false.
+      level = level-1
+      nlocal = nlocal/2
+    end do
+    do m=pproc,0,-1
+      write(s,'("m = ",I3)') m
+      call print_timerinfo(s)
+      ! --- Print out timer information ---
+      call print_elapsed(t_collect(m),.True.,1.0_rl)
+      call print_elapsed(t_distribute(m),.True.,1.0_rl)
+    end do
+
+    ! Deallocate arrays
+    if (LUseO) deallocate(halo_ns)
+    if (LUseT) deallocate(halo_nst,halo_wet)
+    if (LUseO) deallocate(interior)
+    if (LUseO) deallocate(sub_interior)
+    if (LUseT) deallocate(interiorT)
+    if (LUseT) deallocate(sub_interiorT)
+
+    deallocate(t_haloswap)
+    deallocate(t_collect)
+    deallocate(t_distribute)
+    if (i_am_master_mpi) then
+      write(STDOUT,'("")')
+    end if
+
+  end subroutine comm_finalise
+
+!==================================================================
+!  Scalar product of two fields
+!==================================================================
+  subroutine scalarprod_mnh(m, a, b, s)
+    implicit none
+    integer, intent(in) :: m
+    type(scalar3d), intent(in) :: a
+    type(scalar3d), intent(in) :: b
+    real(kind=rl), intent(out) :: s
+    !local var
+    integer :: nprocs, rank, ierr
+    integer :: p_horiz(2)
+    integer :: stepsize
+    integer, parameter :: dim_horiz = 2
+    real(kind=rl) :: local_sum, global_sum 
+    real(kind=rl) :: local_sumt,global_sumt
+    integer :: nlocal, nz, i
+    integer :: ix,iy,iz
+    real(kind=rl) :: ddot
+
+    integer :: iy_min,iy_max, ix_min,ix_max
+    real , dimension(:,:,:) , pointer , contiguous :: za_st,zb_st
+
+    nlocal = a%ix_max-a%ix_min+1
+    nz = a%grid_param%nz
+
+    iy_min = a%iy_min
+    iy_max = a%iy_max
+    ix_min = a%ix_min
+    ix_max = a%ix_max
+
+    ! Work out coordinates of processor
+    call mpi_comm_size(MPI_COMM_HORIZ,nprocs,ierr)
+    call mpi_comm_rank(MPI_COMM_HORIZ,rank,ierr)
+    stepsize = 2**(pproc-m)
+    if (nprocs > 1) then
+      ! Only inlcude local sum if the processor coordinates
+      ! are multiples of stepsize
+      call mpi_cart_coords(MPI_COMM_HORIZ,rank,dim_horiz,p_horiz,ierr)
+      if ( (stepsize == 1) .or.                   &
+           ( (stepsize > 1) .and.                 &
+             (mod(p_horiz(1),stepsize)==0) .and.  &
+             (mod(p_horiz(2),stepsize)==0) ) ) then
+        if (LUseO) then
+           local_sum = 0.0_rl
+           do i = 1, nlocal
+              local_sum = local_sum &
+                   + ddot((nz+2)*nlocal,a%s(0,1,i),1,b%s(0,1,i),1)
+           end do
+        end if
+        if (LUseT) then
+           local_sumt = 0.0_rl
+           !$acc kernels loop collapse(3)
+           do iz=0,nz+1
+              do iy=a%icompy_min,a%icompy_max
+                 do ix=a%icompx_min,a%icompx_max
+                    local_sumt = local_sumt &
+                         + a%st(ix,iy,iz)*b%st(ix,iy,iz)
+                 end do
+              end do
+           end do
+        end if
+      else
+        if (LUseO) local_sum = 0.0_rl
+        if (LUseT) local_sumt = 0.0_rl
+      end if
+      if (LUseO) call mpi_allreduce(local_sum,global_sum,1,MPI_DOUBLE_PRECISION, &
+                         MPI_SUM,MPI_COMM_HORIZ,ierr)
+      if (LUseT) call mpi_allreduce(local_sumt,global_sumt,1,MPI_DOUBLE_PRECISION, &
+                         MPI_SUM,MPI_COMM_HORIZ,ierr)
+    else
+      if (LUseO) then   
+      global_sum = 0.0_rl
+      do i = 1, nlocal
+        global_sum = global_sum &
+                   + ddot((nz+2)*nlocal,a%s(0,1,i),1,b%s(0,1,i),1)
+      end do
+      endif
+      if (LUseT) then
+      za_st => a%st
+      zb_st => b%st
+      global_sumt = 0.0_rl
+         !$acc kernels
+         do iz=0,nz+1
+            do iy=iy_min,iy_max
+               do ix=ix_min,ix_max
+                  global_sumt = global_sumt &
+                       + za_st(ix,iy,iz)*zb_st(ix,iy,iz)
+               end do
+            end do
+         end do
+         !$acc end kernels
+      endif
+    end if
+    if (LUseO) then
+       s = global_sum
+    else
+       s = global_sumt
+    end if
+    
+  end subroutine scalarprod_mnh
+!-------------------------------------------------------------------------------
+  subroutine scalarprod(m, a, b, s)
+    implicit none
+    integer, intent(in) :: m
+    type(scalar3d), intent(in) :: a
+    type(scalar3d), intent(in) :: b
+    real(kind=rl), intent(out) :: s
+    integer :: nprocs, rank, ierr
+    integer :: p_horiz(2)
+    integer :: stepsize
+    integer, parameter :: dim_horiz = 2
+    real(kind=rl) :: local_sum, global_sum
+    integer :: nlocal, nz, i
+    real(kind=rl) :: ddot
+
+    nlocal = a%ix_max-a%ix_min+1
+    nz = a%grid_param%nz
+    ! Work out coordinates of processor
+    call mpi_comm_size(MPI_COMM_HORIZ,nprocs,ierr)
+    call mpi_comm_rank(MPI_COMM_HORIZ,rank,ierr)
+    stepsize = 2**(pproc-m)
+    if (nprocs > 1) then
+      ! Only inlcude local sum if the processor coordinates
+      ! are multiples of stepsize
+      call mpi_cart_coords(MPI_COMM_HORIZ,rank,dim_horiz,p_horiz,ierr)
+      if ( (stepsize == 1) .or.                   &
+           ( (stepsize > 1) .and.                 &
+             (mod(p_horiz(1),stepsize)==0) .and.  &
+             (mod(p_horiz(2),stepsize)==0) ) ) then
+        local_sum = 0.0_rl
+        do i = 1, nlocal
+          local_sum = local_sum &
+                    + ddot((nz+2)*nlocal,a%s(0,1,i),1,b%s(0,1,i),1)
+        end do
+      else
+        local_sum = 0.0_rl
+      end if
+      call mpi_allreduce(local_sum,global_sum,1,MPI_DOUBLE_PRECISION, &
+                         MPI_SUM,MPI_COMM_HORIZ,ierr)
+    else
+      global_sum = 0.0_rl
+      do i = 1, nlocal
+        global_sum = global_sum &
+                   + ddot((nz+2)*nlocal,a%s(0,1,i),1,b%s(0,1,i),1)
+      end do
+    end if
+    s = global_sum
+  end subroutine scalarprod
+!==================================================================
+!  Pritn Scalar product^2  of 1 fields
+!==================================================================
+  subroutine print_scalaprod2(l,m, a, message )
+    implicit none
+    integer, intent(in) :: l,m
+    type(scalar3d), intent(in) :: a
+    character(len=*) , intent(in) :: message
+
+    !local 
+    real(kind=rl) :: s
+
+    call scalarprod_mnh(m, a, a, s)
+    s = sqrt(s)
+    if (i_am_master_mpi) then
+       write(STDOUT,'("Print_norm::",A,2I3,E23.15)') message, l,m,s
+       call flush(STDOUT)
+    end if
+
+  end subroutine print_scalaprod2
+!==================================================================
+! Boundary Neumann
+!==================================================================
+  subroutine boundary_mnh(a)              ! data field
+
+    implicit none
+ 
+    type(scalar3d), intent(inout) :: a
+
+    !local var
+    integer :: n, ix_min,ix_max,iy_min,iy_max
+    integer :: icompx_max,icompy_max
+
+    real , dimension(:,:,:) , pointer , contiguous :: za_st
+    
+    ! Update Real Boundary for Newman case   u(0) = u(1) , etc ...
+
+    !return
+
+    n      = a%grid_param%n
+    ix_min = a%ix_min
+    ix_max = a%ix_max
+    iy_min = a%iy_min
+    iy_max = a%iy_max
+    if (LUseO) then 
+    if ( ix_min == 1 ) then
+       a%s(:,:,0) = a%s(:,:,1)
+    endif
+    if ( ix_max == n ) then
+       a%s(:,:,a%icompx_max+1) = a%s(:,:,a%icompx_max)
+    endif
+    if ( iy_min == 1 ) then
+       a%s(:,0,:) = a%s(:,1,:)
+    endif
+    if ( iy_max == n ) then
+       a%s(:,a%icompy_max+1,:) = a%s(:,a%icompy_max,:)
+    endif
+    endif
+    if (LUseT) then
+    !  transpose
+
+    za_st => a%st
+    icompx_max = a%icompx_max
+    icompy_max = a%icompy_max
+
+    !$acc kernels
+    if ( ix_min == 1 ) then
+       !acc kernels
+       za_st(0,:,:) = za_st(1,:,:)
+       !acc end kernels
+    endif
+    if ( ix_max == n ) then
+       !acc kernels
+       za_st(icompx_max+1,:,:) = za_st(icompx_max,:,:)
+       !acc end kernels
+    endif
+    if ( iy_min == 1 ) then
+       !acc kernels
+       za_st(:,0,:) = za_st(:,1,:)
+       !acc end kernels
+    endif
+    if ( iy_max == n ) then
+       !acc kernels
+       za_st(:,icompy_max+1,:) = za_st(:,icompy_max,:)
+       !acc end kernels
+    endif
+    !$acc end kernels
+   
+    endif
+
+  end subroutine boundary_mnh
+!==================================================================
+!  Initiate asynchronous halo exchange
+!
+!  For all processes with horizontal indices that are multiples
+!  of 2^(pproc-m), update halos with information held by
+!  neighbouring processes, e.g. for pproc-m = 1, stepsize=2
+!
+!                      N  (0,2)
+!                      ^
+!                      !
+!                      v
+!
+!      W (2,0) <-->  (2,2)  <-->  E (2,4)
+!
+!                      ^
+!                      !
+!                      v
+!                      S (4,2)
+!
+!==================================================================
+  subroutine ihaloswap_mnh(level,m,       &  ! multigrid- and processor- level
+                       a,             &  ! data field
+                       send_requests, &  ! send requests (OUT)
+                       recv_requests,  &  ! recv requests (OUT)
+                       send_requestsT, &  ! send requests T (OUT)
+                       recv_requestsT  &  ! recv requests T (OUT)
+                       )
+    implicit none
+    integer, intent(in) :: level
+    integer, intent(in) :: m
+    integer, intent(out), dimension(4) :: send_requests
+    integer, intent(out), dimension(4) :: recv_requests
+    integer, intent(out), dimension(4) :: send_requestsT
+    integer, intent(out), dimension(4) :: recv_requestsT
+    type(scalar3d), intent(inout) :: a
+    integer :: a_n  ! horizontal grid size
+    integer :: nz   ! vertical grid size
+    integer, dimension(2) :: p_horiz
+    integer :: stepsize
+    integer :: ierr, rank, sendtag, recvtag
+    integer :: stat(MPI_STATUS_SIZE)
+    integer :: halo_size
+    integer :: neighbour_n_rank
+    integer :: neighbour_s_rank
+    integer :: neighbour_e_rank
+    integer :: neighbour_w_rank
+    integer :: yoffset, blocklength
+
+    halo_size = comm_param%halo_size
+
+    ! Do nothing if we are only using one processor
+    if (m > 0) then
+      a_n = a%ix_max-a%ix_min+1
+      nz = a%grid_param%nz
+      stepsize = 2**(pproc-m)
+
+      ! Work out rank, only execute on relevant processes
+      call mpi_comm_rank(MPI_COMM_HORIZ, rank, ierr)
+      call mpi_cart_coords(MPI_COMM_HORIZ,rank,dim_horiz,p_horiz,ierr)
+
+      ! Work out ranks of neighbours
+      ! W -> E
+      call mpi_cart_shift(MPI_COMM_HORIZ,1, stepsize, &
+                          neighbour_w_rank,neighbour_e_rank,ierr)
+      ! N -> S
+      call mpi_cart_shift(MPI_COMM_HORIZ,0, stepsize, &
+                          neighbour_n_rank,neighbour_s_rank,ierr)
+      if ( (stepsize == 1) .or.                   &
+         (  (mod(p_horiz(1),stepsize) == 0) .and. &
+            (mod(p_horiz(2),stepsize) == 0) ) ) then
+        if (halo_size == 1) then
+          ! Do not include corners in send/recv
+          yoffset = 1
+          blocklength = a_n*(nz+2)*halo_size
+        else
+          yoffset = 1-halo_size
+          blocklength = (a_n+2*halo_size)*(nz+2)*halo_size
+        end if
+        ! Receive from north
+        recvtag = 1002
+        if (LUseO) call mpi_irecv(a%s(0,0-(halo_size-1),1),1,       &
+                       halo_ns(level,m),neighbour_n_rank,recvtag,   &
+                       MPI_COMM_HORIZ, recv_requests(1), ierr)
+        recvtag = 1012
+        if (LUseT) then
+           call mpi_irecv(a%st(1,0-(halo_size-1),0),1,      &
+                halo_nst(level,m),neighbour_n_rank,recvtag,  &
+                MPI_COMM_HORIZ, recv_requestsT(1), ierr)
+        end if
+        ! Receive from south
+        recvtag = 1003
+        if (LUseO) call mpi_irecv(a%s(0,a_n+1,1),1,                 &
+                       halo_ns(level,m),neighbour_s_rank,recvtag,   &
+                       MPI_COMM_HORIZ, recv_requests(2), ierr)
+        recvtag = 1013
+        if (LUseT) then
+           call mpi_irecv(a%st(1,a_n+1,0),1,                &
+                halo_nst(level,m),neighbour_s_rank,recvtag,  &
+                MPI_COMM_HORIZ, recv_requestsT(2), ierr)
+        end if
+        ! Send to south
+        sendtag = 1002
+        if (LUseO) call mpi_isend(a%s(0,a_n-(halo_size-1),1),1,     &
+                       halo_ns(level,m),neighbour_s_rank,sendtag,   &
+                       MPI_COMM_HORIZ, send_requests(1), ierr)
+        sendtag = 1012
+        if (LUseT) then
+           call mpi_isend(a%st(1,a_n-(halo_size-1),0),1,    &
+                halo_nst(level,m),neighbour_s_rank,sendtag,  &
+                MPI_COMM_HORIZ, send_requestsT(1), ierr)
+        end if
+        ! Send to north
+        sendtag = 1003
+        if (LUseO) call mpi_isend(a%s(0,1,1),1,                     &
+                       halo_ns(level,m),neighbour_n_rank,sendtag,   &
+                       MPI_COMM_HORIZ, send_requests(2), ierr)
+        sendtag = 1013
+        if (LUseT) then
+           call mpi_isend(a%st(1,1,0),1,                    &
+                       halo_nst(level,m),neighbour_n_rank,sendtag,  &
+                       MPI_COMM_HORIZ, send_requestsT(2), ierr)
+        end if
+        ! Receive from west
+        recvtag = 1000
+        if (LUseO) call mpi_irecv(a%s(0,yoffset,0-(halo_size-1)),blocklength,  &
+                       MPI_DOUBLE_PRECISION,neighbour_w_rank,recvtag, &
+                       MPI_COMM_HORIZ, recv_requests(3), ierr)
+        recvtag = 1010
+        if (LUseT) then
+           call mpi_irecv(a%st(0-(halo_size-1),0,0),1,  &
+                halo_wet(level,m),neighbour_w_rank,recvtag, &
+                MPI_COMM_HORIZ, recv_requestsT(3), ierr)
+        end if
+        ! Receive from east
+        sendtag = 1001
+        if (LUseO) call mpi_irecv(a%s(0,yoffset,a_n+1),blocklength,          &
+                       MPI_DOUBLE_PRECISION,neighbour_e_rank,recvtag, &
+                       MPI_COMM_HORIZ, recv_requests(4), ierr)
+        sendtag = 1011
+        if (LUseT) then
+           call mpi_irecv(a%st(a_n+1,0,0),1,          &
+                halo_wet(level,m),neighbour_e_rank,recvtag, &
+                MPI_COMM_HORIZ, recv_requestsT(4), ierr)
+        end if
+        ! Send to east
+        sendtag = 1000
+        if (LUseO) call mpi_isend(a%s(0,yoffset,a_n-(halo_size-1)),blocklength,  &
+                       MPI_DOUBLE_PRECISION,neighbour_e_rank,sendtag, &
+                       MPI_COMM_HORIZ, send_requests(3), ierr)
+        sendtag = 1010
+        if (LUseT) then
+           call mpi_isend(a%st(a_n-(halo_size-1),0,0),1,  &
+                halo_wet(level,m),neighbour_e_rank,sendtag, &
+                MPI_COMM_HORIZ, send_requestsT(3), ierr)
+        end if
+        ! Send to west
+        recvtag = 1001
+        if (LUseO) call mpi_isend(a%s(0,yoffset,1),blocklength,                &
+                       MPI_DOUBLE_PRECISION,neighbour_w_rank,sendtag,   &
+                       MPI_COMM_HORIZ, send_requests(4), ierr)
+        recvtag = 1011
+        if (LUseT) then
+           call mpi_isend(a%st(1,0,0),1,                &
+                       halo_wet(level,m),neighbour_w_rank,sendtag,   &
+                       MPI_COMM_HORIZ, send_requestsT(4), ierr)
+        end if
+      end if
+    end if
+  end subroutine ihaloswap_mnh
+!==================================================================
+  subroutine ihaloswap(level,m,       &  ! multigrid- and processor- level
+                       a,             &  ! data field
+                       send_requests, &  ! send requests (OUT)
+                       recv_requests  &  ! recv requests (OUT)
+                       )
+    implicit none
+    integer, intent(in) :: level
+    integer, intent(in) :: m
+    integer, intent(out), dimension(4) :: send_requests
+    integer, intent(out), dimension(4) :: recv_requests
+    type(scalar3d), intent(inout) :: a
+    integer :: a_n  ! horizontal grid size
+    integer :: nz   ! vertical grid size
+    integer, dimension(2) :: p_horiz
+    integer :: stepsize
+    integer :: ierr, rank, sendtag, recvtag
+    integer :: stat(MPI_STATUS_SIZE)
+    integer :: halo_size
+    integer :: neighbour_n_rank
+    integer :: neighbour_s_rank
+    integer :: neighbour_e_rank
+    integer :: neighbour_w_rank
+    integer :: yoffset, blocklength
+
+    halo_size = comm_param%halo_size
+
+    ! Do nothing if we are only using one processor
+    if (m > 0) then
+      a_n = a%ix_max-a%ix_min+1
+      nz = a%grid_param%nz
+      stepsize = 2**(pproc-m)
+
+      ! Work out rank, only execute on relevant processes
+      call mpi_comm_rank(MPI_COMM_HORIZ, rank, ierr)
+      call mpi_cart_coords(MPI_COMM_HORIZ,rank,dim_horiz,p_horiz,ierr)
+
+      ! Work out ranks of neighbours
+      ! W -> E
+      call mpi_cart_shift(MPI_COMM_HORIZ,1, stepsize, &
+                          neighbour_w_rank,neighbour_e_rank,ierr)
+      ! N -> S
+      call mpi_cart_shift(MPI_COMM_HORIZ,0, stepsize, &
+                          neighbour_n_rank,neighbour_s_rank,ierr)
+      if ( (stepsize == 1) .or.                   &
+         (  (mod(p_horiz(1),stepsize) == 0) .and. &
+            (mod(p_horiz(2),stepsize) == 0) ) ) then
+        if (halo_size == 1) then
+          ! Do not include corners in send/recv
+          yoffset = 1
+          blocklength = a_n*(nz+2)*halo_size
+        else
+          yoffset = 1-halo_size
+          blocklength = (a_n+2*halo_size)*(nz+2)*halo_size
+        end if
+        ! Receive from north
+        recvtag = 2
+        call mpi_irecv(a%s(0,0-(halo_size-1),1),1,                  &
+                       halo_ns(level,m),neighbour_n_rank,recvtag,   &
+                       MPI_COMM_HORIZ, recv_requests(1), ierr)
+        ! Receive from south
+        recvtag = 3
+        call mpi_irecv(a%s(0,a_n+1,1),1,                            &
+                       halo_ns(level,m),neighbour_s_rank,recvtag,   &
+                       MPI_COMM_HORIZ, recv_requests(2), ierr)
+        ! Send to south
+        sendtag = 2
+        call mpi_isend(a%s(0,a_n-(halo_size-1),1),1,                &
+                       halo_ns(level,m),neighbour_s_rank,sendtag,   &
+                       MPI_COMM_HORIZ, send_requests(1), ierr)
+        ! Send to north
+        sendtag = 3
+        call mpi_isend(a%s(0,1,1),1,                                &
+                       halo_ns(level,m),neighbour_n_rank,sendtag,   &
+                       MPI_COMM_HORIZ, send_requests(2), ierr)
+        ! Receive from west
+        recvtag = 0
+        call mpi_irecv(a%s(0,yoffset,0-(halo_size-1)),blocklength,    &
+                       MPI_DOUBLE_PRECISION,neighbour_w_rank,recvtag, &
+                       MPI_COMM_HORIZ, recv_requests(3), ierr)
+        ! Receive from east
+        sendtag = 1
+        call mpi_irecv(a%s(0,yoffset,a_n+1),blocklength,          &
+                       MPI_DOUBLE_PRECISION,neighbour_e_rank,recvtag, &
+                       MPI_COMM_HORIZ, recv_requests(4), ierr)
+        ! Send to east
+        sendtag = 0
+        call mpi_isend(a%s(0,yoffset,a_n-(halo_size-1)),blocklength,  &
+                       MPI_DOUBLE_PRECISION,neighbour_e_rank,sendtag, &
+                       MPI_COMM_HORIZ, send_requests(3), ierr)
+        ! Send to west
+        recvtag = 1
+        call mpi_isend(a%s(0,yoffset,1),blocklength,                &
+                       MPI_DOUBLE_PRECISION,neighbour_w_rank,sendtag,   &
+                       MPI_COMM_HORIZ, send_requests(4), ierr)
+      end if
+    end if
+  end subroutine ihaloswap
+
+!==================================================================
+!  Halo exchange
+!
+!  For all processes with horizontal indices that are multiples
+!  of 2^(pproc-m), update halos with information held by
+!  neighbouring processes, e.g. for pproc-m = 1, stepsize=2
+!
+!                      N  (0,2)
+!                      ^
+!                      !
+!                      v
+!
+!      W (2,0) <-->  (2,2)  <-->  E (2,4)
+!
+!                      ^
+!                      !
+!                      v
+!                      S (4,2)
+!
+!==================================================================
+  subroutine haloswap_mnh(level,m, &  ! multigrid- and processor- level
+                      a)          ! data field
+    implicit none
+    integer, intent(in) :: level
+    integer, intent(in) :: m
+    type(scalar3d), intent(inout) :: a
+    !local var
+    integer :: a_n  ! horizontal grid size
+    integer :: nz   ! vertical grid size
+    integer, dimension(2) :: p_horiz
+    integer :: stepsize
+    integer :: ierr, rank, sendtag, recvtag
+    integer :: stat(MPI_STATUS_SIZE)
+    integer :: halo_size
+    integer :: neighbour_n_rank
+    integer :: neighbour_s_rank
+    integer :: neighbour_e_rank
+    integer :: neighbour_w_rank
+    integer :: yoffset, blocklength
+    integer, dimension(4) :: requests_ns
+    integer, dimension(4) :: requests_ew
+    integer, dimension(4) :: requests_nsT
+    integer, dimension(4) :: requests_ewT
+
+    integer :: ii,ij,ik
+    real , pointer , contiguous , dimension(:,:,:) :: zst
+    !
+    real , pointer , contiguous , dimension(:,:,:) :: ztab_halo_st_haloTin,ztab_halo_nt_haloTin
+    real , pointer , contiguous , dimension(:,:,:) :: ztab_halo_et_haloTin,ztab_halo_wt_haloTin
+    !
+    real , pointer , contiguous , dimension(:,:,:) :: ztab_halo_nt_haloTout,ztab_halo_st_haloTout
+    real , pointer , contiguous , dimension(:,:,:) :: ztab_halo_wt_haloTout,ztab_halo_et_haloTout
+
+    halo_size = comm_param%halo_size
+
+    ! Do nothing if we are only using one processor
+    if (m > 0) then
+      if (comm_measuretime) then
+        call start_timer(t_haloswap(level,m))
+      end if
+      a_n = a%ix_max-a%ix_min+1
+      nz = a%grid_param%nz
+      stepsize = 2**(pproc-m)
+
+      ! Work out rank, only execute on relevant processes
+      call mpi_comm_rank(MPI_COMM_HORIZ, rank, ierr)
+      call mpi_cart_coords(MPI_COMM_HORIZ,rank,dim_horiz,p_horiz,ierr)
+
+      ! Work out ranks of neighbours
+      ! W -> E
+      call mpi_cart_shift(MPI_COMM_HORIZ,1, stepsize, &
+                          neighbour_w_rank,neighbour_e_rank,ierr)
+      ! N -> S
+      call mpi_cart_shift(MPI_COMM_HORIZ,0, stepsize, &
+                          neighbour_n_rank,neighbour_s_rank,ierr)
+      if ( (stepsize == 1) .or.                   &
+         (  (mod(p_horiz(1),stepsize) == 0) .and. &
+            (mod(p_horiz(2),stepsize) == 0) ) ) then
+        if (halo_size == 1) then
+          ! Do not include corners in send/recv
+          yoffset = 1
+          blocklength = a_n*(nz+2)*halo_size
+        else
+          yoffset = 1-halo_size
+          blocklength = (a_n+2*halo_size)*(nz+2)*halo_size
+        end if
+        !
+        zst => a%st
+        !
+#ifdef MNH_GPUDIRECT
+        if (LUseT) then
+           !
+           ! Copy send buffer async to GPU
+           !
+           ! Send to south
+           ztab_halo_st_haloTin => tab_halo_st(level,m)%haloTin
+           !$acc parallel loop collapse(3) async(1)
+           do concurrent ( ii=1:a_n,ij=1:halo_size,ik=1:nz+2 )
+              ztab_halo_st_haloTin(ii,ij,ik) = zst(ii,ij+a_n-halo_size,ik-1)
+           end do
+           ! Send to north
+           ztab_halo_nt_haloTin => tab_halo_nt(level,m)%haloTin
+           !$acc parallel loop collapse(3) async(1)
+           do concurrent ( ii=1:a_n,ij=1:halo_size,ik=1:nz+2 )           
+              ztab_halo_nt_haloTin(ii,ij,ik) = zst(ii,ij,ik-1)
+           end do
+           ! Send to east
+           ztab_halo_et_haloTin => tab_halo_et(level,m)%haloTin
+           !$acc parallel loop collapse(3) async(1)
+           do concurrent ( ii=1:halo_size,ij=1:a_n+2*halo_size,ik=1:nz+2 ) 
+              ztab_halo_et_haloTin(ii,ij,ik) = zst(ii+a_n-halo_size,ij-halo_size,ik-1)
+           end do
+           ! Send to west
+           ztab_halo_wt_haloTin => tab_halo_wt(level,m)%haloTin
+           !$acc parallel loop collapse(3) async(1)
+           do concurrent ( ii=1:halo_size,ij=1:a_n+2*halo_size,ik=1:nz+2 ) 
+              ztab_halo_wt_haloTin(ii,ij,ik) = zst(ii,ij-halo_size,ik-1)
+           end do           
+        end if
+#endif
+        ! Receive from north
+        recvtag = 1002
+        if (LUseO) call mpi_irecv(a%s(0,0-(halo_size-1),1),1,       &
+                       halo_ns(level,m),neighbour_n_rank,recvtag,   &
+                       MPI_COMM_HORIZ, requests_ns(1), ierr)
+        recvtag = 1012
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT
+           ztab_halo_nt_haloTout => tab_halo_nt(level,m)%haloTout
+           !$acc host_data use_device(ztab_halo_nt_haloTout)
+           call mpi_irecv(ztab_halo_nt_haloTout,size(ztab_halo_nt_haloTout),      &
+                       MPI_DOUBLE_PRECISION,neighbour_n_rank,recvtag,  &
+                       MPI_COMM_HORIZ, requests_nsT(1), ierr)
+           !$acc end host_data
+#else
+           call mpi_irecv(a%st(1,0-(halo_size-1),0),1,      &
+                       halo_nst(level,m),neighbour_n_rank,recvtag,  &
+                       MPI_COMM_HORIZ, requests_nsT(1), ierr)
+#endif
+        end if
+        ! Receive from south
+        recvtag = 1003
+        if (LUseO) call mpi_irecv(a%s(0,a_n+1,1),1,                 &
+                       halo_ns(level,m),neighbour_s_rank,recvtag,   &
+                       MPI_COMM_HORIZ, requests_ns(2), ierr)
+        recvtag = 1013
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT
+           ztab_halo_st_haloTout => tab_halo_st(level,m)%haloTout
+           !$acc host_data use_device (ztab_halo_st_haloTout)
+           call mpi_irecv(ztab_halo_st_haloTout,size(ztab_halo_st_haloTout),  &
+                       MPI_DOUBLE_PRECISION,neighbour_s_rank,recvtag,  &
+                       MPI_COMM_HORIZ, requests_nsT(2), ierr)
+           !$acc end host_data
+#else
+           call mpi_irecv(a%st(1,a_n+1,0),1,                &
+                       halo_nst(level,m),neighbour_s_rank,recvtag,  &
+                       MPI_COMM_HORIZ, requests_nsT(2), ierr)           
+#endif
+        end if
+#ifdef MNH_GPUDIRECT
+        if (LUseT) then
+           ! wait for async copy of send buffer to GPU
+           !$acc wait(1)
+        end if
+#endif        
+        ! Send to south
+        sendtag = 1002
+        if (LUseO) call mpi_isend(a%s(0,a_n-(halo_size-1),1),1,     &
+                       halo_ns(level,m),neighbour_s_rank,sendtag,   &
+                       MPI_COMM_HORIZ, requests_ns(3), ierr)
+        sendtag = 1012
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT
+           !$acc host_data use_device(ztab_halo_st_haloTin)
+           call mpi_isend(ztab_halo_st_haloTin,size(ztab_halo_st_haloTin),    &
+                       MPI_DOUBLE_PRECISION,neighbour_s_rank,sendtag,  &
+                       MPI_COMM_HORIZ, requests_nsT(3), ierr)
+           !$acc end host_data
+#else   
+           call mpi_isend(a%st(1,a_n-(halo_size-1),0),1,    &
+                       halo_nst(level,m),neighbour_s_rank,sendtag,  &
+                       MPI_COMM_HORIZ, requests_nsT(3), ierr)
+#endif
+        end if
+        ! Send to north
+        sendtag = 1003
+        if (LUseO) call mpi_isend(a%s(0,1,1),1,                     &
+                       halo_ns(level,m),neighbour_n_rank,sendtag,   &
+                       MPI_COMM_HORIZ, requests_ns(4), ierr)
+        sendtag = 1013
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT
+           !$acc host_data use_device(ztab_halo_nt_haloTin)
+           call mpi_isend(ztab_halo_nt_haloTin,size(ztab_halo_nt_haloTin),   &
+                       MPI_DOUBLE_PRECISION,neighbour_n_rank,sendtag,  &
+                       MPI_COMM_HORIZ, requests_nsT(4), ierr)
+           !$acc end host_data
+#else
+           call mpi_isend(a%st(1,1,0),1,                    &
+                       halo_nst(level,m),neighbour_n_rank,sendtag,  &
+                       MPI_COMM_HORIZ, requests_nsT(4), ierr)           
+#endif
+        end if
+        if (halo_size > 1) then
+          ! Wait for North <-> South communication to complete
+          if (LUseO) call mpi_waitall(4,requests_ns, MPI_STATUSES_IGNORE, ierr)
+          if (LUseT) call mpi_waitall(4,requests_nsT, MPI_STATUSES_IGNORE, ierr)
+        end if
+        ! Receive from west
+        recvtag = 1000
+        if (LUseO) call mpi_irecv(a%s(0,yoffset,0-(halo_size-1)),blocklength,    &
+                       MPI_DOUBLE_PRECISION,neighbour_w_rank,recvtag, &
+                       MPI_COMM_HORIZ, requests_ew(1), ierr)
+        recvtag = 1010
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT
+           ztab_halo_wt_haloTout => tab_halo_wt(level,m)%haloTout
+           !$acc host_data use_device(ztab_halo_wt_haloTout)
+           call mpi_irecv(ztab_halo_wt_haloTout,size(ztab_halo_wt_haloTout),  &
+                       MPI_DOUBLE_PRECISION,neighbour_w_rank,recvtag, &
+                       MPI_COMM_HORIZ, requests_ewT(1), ierr)
+           !$acc end host_data
+#else
+           call mpi_irecv(a%st(0-(halo_size-1),0,0),1,  &
+                       halo_wet(level,m),neighbour_w_rank,recvtag, &
+                       MPI_COMM_HORIZ, requests_ewT(1), ierr)          
+#endif
+        end if
+        ! Receive from east
+        sendtag = 1001
+        if (LUseO) call mpi_irecv(a%s(0,yoffset,a_n+1),blocklength,          &
+                       MPI_DOUBLE_PRECISION,neighbour_e_rank,recvtag, &
+                       MPI_COMM_HORIZ, requests_ew(2), ierr)
+        sendtag = 1011
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT
+           ztab_halo_et_haloTout => tab_halo_et(level,m)%haloTout
+           !$acc host_data use_device(ztab_halo_et_haloTout)
+           call mpi_irecv(ztab_halo_et_haloTout,size(ztab_halo_et_haloTout),  &
+                       MPI_DOUBLE_PRECISION,neighbour_e_rank,recvtag, &
+                       MPI_COMM_HORIZ, requests_ewT(2), ierr)
+           !$acc end host_data
+#else
+           call mpi_irecv(a%st(a_n+1,0,0),1,          &
+                       halo_wet(level,m),neighbour_e_rank,recvtag, &
+                       MPI_COMM_HORIZ, requests_ewT(2), ierr)
+           
+#endif
+        end if
+        ! Send to east
+        sendtag = 1000
+        if (LUseO) call mpi_isend(a%s(0,yoffset,a_n-(halo_size-1)),blocklength,  &
+                       MPI_DOUBLE_PRECISION,neighbour_e_rank,sendtag, &
+                       MPI_COMM_HORIZ, requests_ew(3), ierr)
+        sendtag = 1010
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT
+           !$acc host_data use_device(ztab_halo_et_haloTin)
+           call mpi_isend(ztab_halo_et_haloTin,size(ztab_halo_et_haloTin),  &
+                       MPI_DOUBLE_PRECISION,neighbour_e_rank,sendtag, &
+                       MPI_COMM_HORIZ, requests_ewT(3), ierr)
+           !$acc end host_data
+#else
+           call mpi_isend(a%st(a_n-(halo_size-1),0,0),1,  &
+                       halo_wet(level,m),neighbour_e_rank,sendtag, &
+                       MPI_COMM_HORIZ, requests_ewT(3), ierr)           
+#endif
+        end if
+        ! Send to west
+        recvtag = 1001
+        if (LUseO) call mpi_isend(a%s(0,yoffset,1),blocklength,                &
+                       MPI_DOUBLE_PRECISION,neighbour_w_rank,sendtag,   &
+                       MPI_COMM_HORIZ, requests_ew(4), ierr)
+        recvtag = 1011
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT
+           !$acc host_data use_device(ztab_halo_wt_haloTin)
+           call mpi_isend(ztab_halo_wt_haloTin,size(ztab_halo_wt_haloTin),  &
+                       MPI_DOUBLE_PRECISION,neighbour_w_rank,sendtag,   &
+                       MPI_COMM_HORIZ, requests_ewT(4), ierr)
+           !$acc end host_data
+#else
+           call mpi_isend(a%st(1,0,0),1,                &
+                       halo_wet(level,m),neighbour_w_rank,sendtag,   &
+                       MPI_COMM_HORIZ, requests_ewT(4), ierr)           
+#endif
+        end if
+        ! Wait for East <-> West communication to complete
+        if (halo_size == 1) then
+          ! Wait for North <-> South communication to complete
+          if (LUseO) call mpi_waitall(4,requests_ns, MPI_STATUSES_IGNORE, ierr)
+          if (LUseT) call mpi_waitall(4,requests_nsT, MPI_STATUSES_IGNORE, ierr)
+        end if
+        if (LUseO) call mpi_waitall(4,requests_ew, MPI_STATUSES_IGNORE, ierr)
+        if (LUseT) call mpi_waitall(4,requests_ewT, MPI_STATUSES_IGNORE, ierr)
+#ifdef MNH_GPUDIRECT
+        if (LUseT) then
+           ! copy north halo for GPU managed
+           !$acc parallel loop collapse(3) async(3)
+           do concurrent ( ii=1:a_n,ij=1:halo_size,ik=1:nz+2 )
+              zst(ii,ij-halo_size,ik-1) = ztab_halo_nt_haloTout(ii,ij,ik)
+           end do
+           ! copy south halo for GPU managed
+           !$acc parallel loop collapse(3) async(3)
+           do concurrent ( ii=1:a_n,ij=1:halo_size,ik=1:nz+2 )
+              zst(ii,ij+a_n,ik-1) = ztab_halo_st_haloTout(ii,ij,ik)
+           end do          
+           ! copy west halo for GPU managed
+           !$acc parallel loop collapse(3) async(3)
+           do concurrent ( ii=1:halo_size,ij=1:a_n+2*halo_size,ik=1:nz+2 )
+              zst(ii-halo_size,ij-halo_size,ik-1) = ztab_halo_wt_haloTout(ii,ij,ik)
+           end do
+           ! copy east halo for GPU managed
+           !$acc parallel loop collapse(3) async(3)
+           do concurrent ( ii=1:halo_size,ij=1:a_n+2*halo_size,ik=1:nz+2 )
+              zst(ii+a_n,ij-halo_size,ik-1) = ztab_halo_et_haloTout(ii,ij,ik)
+           end do
+           !$acc wait(3)
+        end if 
+#endif
+      end if!  (stepsize == 1) ...
+      if (comm_measuretime) then
+        call finish_timer(t_haloswap(level,m))
+      end if
+    end if
+
+  end subroutine haloswap_mnh
+!==================================================================
+  subroutine haloswap(level,m, &  ! multigrid- and processor- level
+                      a)          ! data field
+    implicit none
+    integer, intent(in) :: level
+    integer, intent(in) :: m
+    type(scalar3d), intent(inout) :: a
+    integer :: a_n  ! horizontal grid size
+    integer :: nz   ! vertical grid size
+    integer, dimension(2) :: p_horiz
+    integer :: stepsize
+    integer :: ierr, rank, sendtag, recvtag
+    integer :: stat(MPI_STATUS_SIZE)
+    integer :: halo_size
+    integer :: neighbour_n_rank
+    integer :: neighbour_s_rank
+    integer :: neighbour_e_rank
+    integer :: neighbour_w_rank
+    integer :: yoffset, blocklength
+    integer, dimension(4) :: requests_ns
+    integer, dimension(4) :: requests_ew
+
+    halo_size = comm_param%halo_size
+
+    ! Do nothing if we are only using one processor
+    if (m > 0) then
+      if (comm_measuretime) then
+        call start_timer(t_haloswap(level,m))
+      end if
+      a_n = a%ix_max-a%ix_min+1
+      nz = a%grid_param%nz
+      stepsize = 2**(pproc-m)
+
+      ! Work out rank, only execute on relevant processes
+      call mpi_comm_rank(MPI_COMM_HORIZ, rank, ierr)
+      call mpi_cart_coords(MPI_COMM_HORIZ,rank,dim_horiz,p_horiz,ierr)
+
+      ! Work out ranks of neighbours
+      ! W -> E
+      call mpi_cart_shift(MPI_COMM_HORIZ,1, stepsize, &
+                          neighbour_w_rank,neighbour_e_rank,ierr)
+      ! N -> S
+      call mpi_cart_shift(MPI_COMM_HORIZ,0, stepsize, &
+                          neighbour_n_rank,neighbour_s_rank,ierr)
+      if ( (stepsize == 1) .or.                   &
+         (  (mod(p_horiz(1),stepsize) == 0) .and. &
+            (mod(p_horiz(2),stepsize) == 0) ) ) then
+        if (halo_size == 1) then
+          ! Do not include corners in send/recv
+          yoffset = 1
+          blocklength = a_n*(nz+2)*halo_size
+        else
+          yoffset = 1-halo_size
+          blocklength = (a_n+2*halo_size)*(nz+2)*halo_size
+        end if
+        ! Receive from north
+        recvtag = 2
+        call mpi_irecv(a%s(0,0-(halo_size-1),1),1,                  &
+                       halo_ns(level,m),neighbour_n_rank,recvtag,   &
+                       MPI_COMM_HORIZ, requests_ns(1), ierr)
+        ! Receive from south
+        recvtag = 3
+        call mpi_irecv(a%s(0,a_n+1,1),1,                            &
+                       halo_ns(level,m),neighbour_s_rank,recvtag,   &
+                       MPI_COMM_HORIZ, requests_ns(2), ierr)
+        ! Send to south
+        sendtag = 2
+        call mpi_isend(a%s(0,a_n-(halo_size-1),1),1,                &
+                       halo_ns(level,m),neighbour_s_rank,sendtag,   &
+                       MPI_COMM_HORIZ, requests_ns(3), ierr)
+        ! Send to north
+        sendtag = 3
+        call mpi_isend(a%s(0,1,1),1,                                &
+                       halo_ns(level,m),neighbour_n_rank,sendtag,   &
+                       MPI_COMM_HORIZ, requests_ns(4), ierr)
+        if (halo_size > 1) then
+          ! Wait for North <-> South communication to complete
+          call mpi_waitall(4,requests_ns, MPI_STATUSES_IGNORE, ierr)
+        end if
+        ! Receive from west
+        recvtag = 0
+        call mpi_irecv(a%s(0,yoffset,0-(halo_size-1)),blocklength,    &
+                       MPI_DOUBLE_PRECISION,neighbour_w_rank,recvtag, &
+                       MPI_COMM_HORIZ, requests_ew(1), ierr)
+        ! Receive from east
+        sendtag = 1
+        call mpi_irecv(a%s(0,yoffset,a_n+1),blocklength,          &
+                       MPI_DOUBLE_PRECISION,neighbour_e_rank,recvtag, &
+                       MPI_COMM_HORIZ, requests_ew(2), ierr)
+        ! Send to east
+        sendtag = 0
+        call mpi_isend(a%s(0,yoffset,a_n-(halo_size-1)),blocklength,  &
+                       MPI_DOUBLE_PRECISION,neighbour_e_rank,sendtag, &
+                       MPI_COMM_HORIZ, requests_ew(3), ierr)
+        ! Send to west
+        recvtag = 1
+        call mpi_isend(a%s(0,yoffset,1),blocklength,                &
+                       MPI_DOUBLE_PRECISION,neighbour_w_rank,sendtag,   &
+                       MPI_COMM_HORIZ, requests_ew(4), ierr)
+        ! Wait for East <-> West communication to complete
+        if (halo_size == 1) then
+          ! Wait for North <-> South communication to complete
+          call mpi_waitall(4,requests_ns, MPI_STATUSES_IGNORE, ierr)
+        end if
+        call mpi_waitall(4,requests_ew, MPI_STATUSES_IGNORE, ierr)
+      end if
+      if (comm_measuretime) then
+        call finish_timer(t_haloswap(level,m))
+      end if
+    end if
+  end subroutine haloswap
+!==================================================================
+!  Collect from a(level,m) and store on less processors
+!  in b(level,m-1)
+!
+!  Example for pproc-m = 1, i.e. stepsize = 2:
+!
+!   NW (0,0)  <--  NE (0,2)
+!
+!     ^      .
+!     !        .
+!                .
+!   SW (2,0)       SE (2,2) [send to 0,0]
+!
+!==================================================================
+  subroutine collect(level,m, &    ! multigrid and processor level
+                     a, &          ! IN: data on level (level,m)
+                     b)            ! OUT: data on level (level,m-1)
+    implicit none
+    integer, intent(in) :: level
+    integer, intent(in) :: m
+    type(scalar3d), intent(in) :: a
+    type(scalar3d), intent(inout) :: b
+    integer :: a_n, b_n   ! horizontal grid sizes
+    integer :: nz ! vertical grid size
+    integer, dimension(2) :: p_horiz
+    integer :: stepsize
+    integer :: ierr, source_rank, dest_rank, rank, recv_tag, send_tag, iz
+    logical :: corner_nw, corner_ne, corner_sw, corner_se
+    integer :: recv_request(3)
+    integer :: recv_requestT(3)
+
+    integer :: ii,ij,ik
+
+    real , pointer , contiguous , dimension(:,:,:) :: za_st,zb_st
+
+    real , pointer , contiguous , dimension(:,:,:) :: ztab_interiorT_ne_m_haloTin
+    real , pointer , contiguous , dimension(:,:,:) :: ztab_interiorT_sw_m_haloTin
+    real , pointer , contiguous , dimension(:,:,:) :: ztab_interiorT_se_m_haloTin
+
+    real , pointer , contiguous , dimension(:,:,:) :: ztab_sub_interiorT_ne_m_1_haloTout
+    real , pointer , contiguous , dimension(:,:,:) :: ztab_sub_interiorT_sw_m_1_haloTout
+    real , pointer , contiguous , dimension(:,:,:) :: ztab_sub_interiorT_se_m_1_haloTout
+
+    call start_timer(t_collect(m))
+
+    stepsize = 2**(pproc-m)
+
+    a_n = a%ix_max-a%ix_min+1
+    b_n = b%ix_max-b%ix_min+1
+    nz = b%grid_param%nz
+
+    ! Work out rank, only execute on relevant processes
+    call mpi_comm_rank(MPI_COMM_HORIZ, rank, ierr)
+    ! Store position in process grid in in p_horiz
+    ! Note we can NOT use cart_shift as we need diagonal neighburs as well
+    call mpi_cart_coords(MPI_COMM_HORIZ,rank,dim_horiz,p_horiz,ierr)
+
+    ! Ignore all processes that do not participate at this level
+    if ( (stepsize .eq. 1) .or. ((mod(p_horiz(1),stepsize) == 0) .and. (mod(p_horiz(2),stepsize)) == 0)) then
+      ! Determine position in local 2x2 block
+      if (stepsize .eq. 1) then
+        corner_nw = ((mod(p_horiz(1),2) == 0) .and. (mod(p_horiz(2),2) == 0))
+        corner_ne = ((mod(p_horiz(1),2) == 0) .and. (mod(p_horiz(2),2) == 1))
+        corner_sw = ((mod(p_horiz(1),2) == 1) .and. (mod(p_horiz(2),2) == 0))
+        corner_se = ((mod(p_horiz(1),2) == 1) .and. (mod(p_horiz(2),2) == 1))
+      else
+        corner_nw = ((mod(p_horiz(1)/stepsize,2) == 0) .and. (mod(p_horiz(2)/stepsize,2) == 0))
+        corner_ne = ((mod(p_horiz(1)/stepsize,2) == 0) .and. (mod(p_horiz(2)/stepsize,2) == 1))
+        corner_sw = ((mod(p_horiz(1)/stepsize,2) == 1) .and. (mod(p_horiz(2)/stepsize,2) == 0))
+        corner_se = ((mod(p_horiz(1)/stepsize,2) == 1) .and. (mod(p_horiz(2)/stepsize,2) == 1))
+      end if
+      ! NW receives from the other three processes
+      if ( corner_nw ) then
+        ! Receive from NE
+        call mpi_cart_rank(MPI_COMM_HORIZ, &
+                           (/p_horiz(1),p_horiz(2)+stepsize/), &
+                           source_rank, &
+                           ierr)
+        recv_tag = 1000
+        if (LUseO) call mpi_irecv(b%s(0,1,b_n/2+1),1,sub_interior(level,m-1),source_rank, recv_tag, MPI_COMM_HORIZ, &
+                           recv_request(1),ierr)
+        recv_tag = 1010
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT
+           ztab_sub_interiorT_ne_m_1_haloTout => tab_sub_interiorT_ne(level,m-1)%haloTout
+           !$acc host_data use_device(ztab_sub_interiorT_ne_m_1_haloTout)
+           call mpi_irecv(ztab_sub_interiorT_ne_m_1_haloTout,size(ztab_sub_interiorT_ne_m_1_haloTout), &
+                MPI_DOUBLE_PRECISION,source_rank, recv_tag, MPI_COMM_HORIZ, &
+                recv_requestT(1),ierr)
+           !$acc end host_data
+#else
+           call mpi_irecv(b%st(b_n/2+1,1,0),1,sub_interiorT(level,m-1), source_rank, recv_tag, MPI_COMM_HORIZ, &
+                recv_requestT(1),ierr)
+#endif
+        end if
+#ifndef NDEBUG
+  if (ierr .ne. 0) &
+    call fatalerror("Collect: receive from NE failed in mpi_irecv().")
+#endif
+         ! Receive from SW
+        call mpi_cart_rank(MPI_COMM_HORIZ, &
+                           (/p_horiz(1)+stepsize,p_horiz(2)/), &
+                           source_rank, &
+                           ierr)
+        recv_tag = 1001
+        if (LUseO) call mpi_irecv(b%s(0,b_n/2+1,1),1,sub_interior(level,m-1), source_rank, recv_tag, MPI_COMM_HORIZ, &
+                           recv_request(2),ierr)
+        recv_tag = 1011
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT
+           ztab_sub_interiorT_sw_m_1_haloTout => tab_sub_interiorT_sw(level,m-1)%haloTout
+           !$acc host_data use_device(ztab_sub_interiorT_sw_m_1_haloTout)
+           call mpi_irecv(ztab_sub_interiorT_sw_m_1_haloTout,size(ztab_sub_interiorT_sw_m_1_haloTout), &
+                MPI_DOUBLE_PRECISION,source_rank, recv_tag, MPI_COMM_HORIZ, &
+                recv_requestT(2),ierr)
+           !$acc end host_data
+#else
+           call mpi_irecv(b%st(1,b_n/2+1,0),1,sub_interiorT(level,m-1), source_rank, recv_tag, MPI_COMM_HORIZ, &
+                recv_requestT(2),ierr)         
+#endif           
+        endif
+
+#ifndef NDEBUG
+  if (ierr .ne. 0) &
+    call fatalerror("Collect: receive from SW failed in mpi_irecv().")
+#endif
+        ! Receive from SE
+        call mpi_cart_rank(MPI_COMM_HORIZ, &
+                           (/p_horiz(1)+stepsize,p_horiz(2)+stepsize/), &
+                           source_rank, &
+                           ierr)
+        recv_tag = 1002
+        if (LUseO) call mpi_irecv(b%s(0,b_n/2+1,b_n/2+1),1,sub_interior(level,m-1), source_rank, recv_tag, MPI_COMM_HORIZ, &
+                           recv_request(3),ierr)
+        recv_tag = 1012
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT
+           ztab_sub_interiorT_se_m_1_haloTout => tab_sub_interiorT_se(level,m-1)%haloTout
+           !$acc host_data use_device(ztab_sub_interiorT_se_m_1_haloTout)
+           call mpi_irecv(ztab_sub_interiorT_se_m_1_haloTout,size(ztab_sub_interiorT_se_m_1_haloTout), &
+                MPI_DOUBLE_PRECISION,source_rank, recv_tag, MPI_COMM_HORIZ, &
+                recv_requestT(3),ierr)
+           !$acc end host_data
+#else
+           call mpi_irecv(b%st(b_n/2+1,b_n/2+1,0),1,sub_interiorT(level,m-1), source_rank, recv_tag, MPI_COMM_HORIZ, &
+                recv_requestT(3),ierr)           
+#endif
+        end if
+#ifndef NDEBUG
+  if (ierr .ne. 0) &
+    call fatalerror("Collect: receive from SE failed in mpi_irecv().")
+#endif
+        ! Copy local data while waiting for data from other processes
+        if (LUseO) b%s(0:nz+1,1:a_n,1:a_n) = a%s(0:nz+1,1:a_n,1:a_n)
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT           
+           zb_st => b%st
+           za_st => a%st
+           !$acc parallel loop collapse(3)
+           do concurrent (ii=1:a_n,ij=1:a_n,ik=1:nz+2)
+              zb_st(ii,ij,ik-1) = za_st(ii,ij,ik-1)
+           end do
+#else           
+           b%st(1:a_n,1:a_n,0:nz+1) = a%st(1:a_n,1:a_n,0:nz+1)
+#endif
+        end if
+        ! Wait for receives to complete before proceeding
+        if (LUseO) call mpi_waitall(3,recv_request,MPI_STATUSES_IGNORE,ierr)
+        if (LUseT) call mpi_waitall(3,recv_requestT,MPI_STATUSES_IGNORE,ierr)
+#ifdef MNH_GPUDIRECT
+        if (LUseT) then
+           zb_st => b%st
+           ! copy from buffer for GPU DIRECT
+           ! Receive from NE
+           !$acc parallel loop collapse(3)
+           do concurrent (ii=1:b_n/2,ij=1:b_n/2,ik=1:nz+2)
+              zb_st(ii+b_n/2,ij,ik-1) = ztab_sub_interiorT_ne_m_1_haloTout(ii,ij,ik)
+           end do
+           ! Receive from SW
+           !$acc parallel loop collapse(3)
+           do concurrent (ii=1:b_n/2,ij=1:b_n/2,ik=1:nz+2)
+              zb_st(ii,ij+b_n/2,ik-1) = ztab_sub_interiorT_sw_m_1_haloTout(ii,ij,ik)
+           end do
+           ! Receive from SE
+           !$acc parallel loop collapse(3)
+            do concurrent (ii=1:b_n/2,ij=1:b_n/2,ik=1:nz+2)
+               zb_st(ii+b_n/2,ij+b_n/2,ik-1) = ztab_sub_interiorT_se_m_1_haloTout(ii,ij,ik)
+            end do
+        end if
+#endif
+      end if
+      if ( corner_ne ) then
+        ! Send to NW
+        call mpi_cart_rank(MPI_COMM_HORIZ, &
+                           (/p_horiz(1),p_horiz(2)-stepsize/), &
+                           dest_rank, &
+                           ierr)
+
+        za_st => a%st
+        
+        send_tag = 1000
+        if (LUseO) call mpi_send(a%s(0,1,1),1,interior(level,m),dest_rank,send_tag,MPI_COMM_HORIZ,ierr)
+        send_tag = 1010
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT
+           ztab_interiorT_ne_m_haloTin => tab_interiorT_ne(level,m)%haloTin
+           !$acc parallel loop collapse(3)
+           do concurrent (ii=1:a_n,ij=1:a_n,ik=1:nz+2)
+              ztab_interiorT_ne_m_haloTin(ii,ij,ik) = za_st(ii,ij,ik-1)
+           end do
+           !$acc host_data use_device(ztab_interiorT_ne_m_haloTin)
+           call mpi_send(ztab_interiorT_ne_m_haloTin,size(ztab_interiorT_ne_m_haloTin), &
+                MPI_DOUBLE_PRECISION,dest_rank,send_tag,MPI_COMM_HORIZ,ierr)
+           !$acc end host_data
+#else
+           call mpi_send(a%st(1,1,0),1,interiorT(level,m),dest_rank,send_tag,MPI_COMM_HORIZ,ierr)
+#endif
+        end if
+#ifndef NDEBUG
+  if (ierr .ne. 0) &
+    call fatalerror("Collect: send from NE failed in mpi_send().")
+#endif
+      end if
+      if ( corner_sw ) then
+        ! Send to NW
+        call mpi_cart_rank(MPI_COMM_HORIZ, &
+                           (/p_horiz(1)-stepsize,p_horiz(2)/), &
+                           dest_rank, &
+                           ierr)
+        
+        za_st => a%st
+        
+        send_tag = 1001
+        if (LUseO) call mpi_send(a%s(0,1,1),1,interior(level,m),dest_rank,send_tag,MPI_COMM_HORIZ,ierr)
+        send_tag = 1011
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT
+           ztab_interiorT_sw_m_haloTin => tab_interiorT_sw(level,m)%haloTin
+           !$acc parallel loop collapse(3)
+           do concurrent (ii=1:a_n,ij=1:a_n,ik=1:nz+2)
+              ztab_interiorT_sw_m_haloTin(ii,ij,ik) = za_st(ii,ij,ik-1)
+           end do
+           !$acc host_data use_device(ztab_interiorT_sw_m_haloTin)
+           call mpi_send(ztab_interiorT_sw_m_haloTin,size(ztab_interiorT_sw_m_haloTin), &
+                MPI_DOUBLE_PRECISION,dest_rank,send_tag,MPI_COMM_HORIZ,ierr)
+           !$acc end host_data
+#else
+           call mpi_send(a%st(1,1,0),1,interiorT(level,m),dest_rank,send_tag,MPI_COMM_HORIZ,ierr)        
+#endif
+        end if
+#ifndef NDEBUG
+  if (ierr .ne. 0) &
+    call fatalerror("Collect: send from SW failed in mpi_send().")
+#endif
+      end if
+      if ( corner_se ) then
+        ! send to NW
+        call mpi_cart_rank(MPI_COMM_HORIZ, &
+                           (/p_horiz(1)-stepsize,p_horiz(2)-stepsize/), &
+                           dest_rank, &
+                           ierr)
+
+        za_st => a%st
+        
+        send_tag = 1002
+        if (LUseO) call mpi_send(a%s(0,1,1),1,interior(level,m),dest_rank,send_tag,MPI_COMM_HORIZ,ierr)
+        send_tag = 1012
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT
+           ztab_interiorT_se_m_haloTin => tab_interiorT_se(level,m)%haloTin
+           !$acc parallel loop collapse(3)
+           do concurrent (ii=1:a_n,ij=1:a_n,ik=1:nz+2)
+              ztab_interiorT_se_m_haloTin(ii,ij,ik) = za_st(ii,ij,ik-1)
+           end do
+           !$acc host_data use_device(ztab_interiorT_se_m_haloTin)
+           call mpi_send(ztab_interiorT_se_m_haloTin,size(ztab_interiorT_se_m_haloTin), &
+                MPI_DOUBLE_PRECISION,dest_rank,send_tag,MPI_COMM_HORIZ,ierr)
+           !$acc end host_data
+#else
+           call mpi_send(a%st(1,1,0),1,interiorT(level,m),dest_rank,send_tag,MPI_COMM_HORIZ,ierr)
+#endif
+        end if
+#ifndef NDEBUG
+  if (ierr .ne. 0) &
+    call fatalerror("Collect: send from SE failed in mpi_send().")
+#endif
+      end if
+
+    end if
+    call finish_timer(t_collect(m))
+
+  end subroutine collect
+
+!==================================================================
+!  Distribute data in a(level,m-1) and store in b(level,m)
+!
+!  Example for p-m = 1, i.e. stepsize = 2:
+!
+!   NW (0,0)  -->  NE (2,0)
+!
+!     !      .
+!     v        .
+!                .
+!   SW (0,2)       SE (2,2) [receive from to 0,0]
+!==================================================================
+  subroutine distribute(level,m, &  ! multigrid and processor level
+                        a,       &  ! IN: Data on level (level,m-1)
+                        b)          ! OUT: Data on level (level,m)
+    implicit none
+    integer, intent(in) :: level
+    integer, intent(in) :: m
+    type(scalar3d), intent(in) :: a
+    type(scalar3d), intent(inout) :: b
+    integer :: a_n, b_n   ! horizontal grid sizes
+    integer :: nz ! vertical grid size
+    integer, dimension(2) :: p_horiz
+    integer :: stepsize
+    integer :: ierr, source_rank, dest_rank, send_tag, recv_tag, rank, iz
+    integer :: stat(MPI_STATUS_SIZE)
+    integer :: send_request(3)
+    integer :: send_requestT(3)
+    logical :: corner_nw, corner_ne, corner_sw, corner_se
+
+    integer :: ii,ij,ik
+
+    real , pointer , contiguous , dimension(:,:,:) :: za_st,zb_st
+
+    real , pointer , contiguous , dimension(:,:,:) :: ztab_sub_interiorT_ne_m_1_haloTin
+    real , pointer , contiguous , dimension(:,:,:) :: ztab_sub_interiorT_sw_m_1_haloTin
+    real , pointer , contiguous , dimension(:,:,:) :: ztab_sub_interiorT_se_m_1_haloTin
+
+    real , pointer , contiguous , dimension(:,:,:) :: ztab_interiorT_ne_m_haloTout
+    real , pointer , contiguous , dimension(:,:,:) :: ztab_interiorT_sw_m_haloTout
+    real , pointer , contiguous , dimension(:,:,:) :: ztab_interiorT_se_m_haloTout
+
+    call start_timer(t_distribute(m))
+
+    stepsize = 2**(pproc-m)
+
+    a_n = a%ix_max-a%ix_min+1
+    b_n = b%ix_max-b%ix_min+1
+    nz = a%grid_param%nz
+
+    ! Work out rank, only execute on relevant processes
+    call mpi_comm_rank(MPI_COMM_HORIZ, rank, ierr)
+    call mpi_cart_coords(MPI_COMM_HORIZ,rank,dim_horiz,p_horiz,ierr)
+
+    ! Ignore all processes that do not participate at this level
+    if ( (stepsize .eq. 1) .or. ((mod(p_horiz(1),stepsize) == 0) .and. (mod(p_horiz(2),stepsize)) == 0)) then
+      ! Work out coordinates in local 2 x 2 block
+      if (stepsize .eq. 1) then
+        corner_nw = ((mod(p_horiz(1),2) == 0) .and. (mod(p_horiz(2),2) == 0))
+        corner_ne = ((mod(p_horiz(1),2) == 0) .and. (mod(p_horiz(2),2) == 1))
+        corner_sw = ((mod(p_horiz(1),2) == 1) .and. (mod(p_horiz(2),2) == 0))
+        corner_se = ((mod(p_horiz(1),2) == 1) .and. (mod(p_horiz(2),2) == 1))
+      else
+        corner_nw = ((mod(p_horiz(1)/stepsize,2) == 0) .and. (mod(p_horiz(2)/stepsize,2) == 0))
+        corner_ne = ((mod(p_horiz(1)/stepsize,2) == 0) .and. (mod(p_horiz(2)/stepsize,2) == 1))
+        corner_sw = ((mod(p_horiz(1)/stepsize,2) == 1) .and. (mod(p_horiz(2)/stepsize,2) == 0))
+        corner_se = ((mod(p_horiz(1)/stepsize,2) == 1) .and. (mod(p_horiz(2)/stepsize,2) == 1))
+      end if
+      if ( corner_nw ) then
+        ! (Asynchronous) send to NE
+        call mpi_cart_rank(MPI_COMM_HORIZ, &
+                           (/p_horiz(1),p_horiz(2)+stepsize/), &
+                           dest_rank, &
+                           ierr)
+        
+        za_st => a%st
+        
+        send_tag = 1000
+        if (LUseO) call mpi_isend(a%s(0,1,a_n/2+1), 1,sub_interior(level,m-1),dest_rank, send_tag, &
+                       MPI_COMM_HORIZ,send_request(1),ierr)
+        send_tag = 1010
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT
+           ztab_sub_interiorT_ne_m_1_haloTin => tab_sub_interiorT_ne(level,m-1)%haloTin
+           !$acc parallel loop collapse(3)
+           do concurrent (ii=1:a_n/2,ij=1:a_n/2,ik=1:nz+2)
+              ztab_sub_interiorT_ne_m_1_haloTin(ii,ij,ik) = za_st(ii+a_n/2,ij,ik-1)
+           end do
+           !$acc host_data use_device(ztab_sub_interiorT_ne_m_1_haloTin)
+           call mpi_isend(ztab_sub_interiorT_ne_m_1_haloTin,size(ztab_sub_interiorT_ne_m_1_haloTin), &
+                MPI_DOUBLE_PRECISION,dest_rank, send_tag, &
+                MPI_COMM_HORIZ,send_requestT(1),ierr)
+           !$acc end host_data
+#else
+           call mpi_isend(a%st(a_n/2+1,1,0), 1,sub_interiorT(level,m-1),dest_rank, send_tag, &
+                MPI_COMM_HORIZ,send_requestT(1),ierr)          
+#endif
+        end if
+#ifndef NDEBUG
+  if (ierr .ne. 0) &
+    call fatalerror("Distribute: send to NE failed in mpi_isend().")
+#endif
+        ! (Asynchronous) send to SW
+        call mpi_cart_rank(MPI_COMM_HORIZ, &
+                           (/p_horiz(1)+stepsize,p_horiz(2)/), &
+                           dest_rank, &
+                           ierr)
+        send_tag = 1001
+        if (LUseO) call mpi_isend(a%s(0,a_n/2+1,1),1,sub_interior(level,m-1), dest_rank, send_tag, &
+                       MPI_COMM_HORIZ, send_request(2), ierr)
+        send_tag = 1011
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT
+           ztab_sub_interiorT_sw_m_1_haloTin => tab_sub_interiorT_sw(level,m-1)%haloTin
+           !$acc parallel loop collapse(3)
+           do concurrent (ii=1:a_n/2,ij=1:a_n/2,ik=1:nz+2)
+              ztab_sub_interiorT_sw_m_1_haloTin(ii,ij,ik) = za_st(ii,ij+a_n/2,ik-1)
+           end do
+           !$acc host_data use_device(ztab_sub_interiorT_sw_m_1_haloTin)
+           call mpi_isend(ztab_sub_interiorT_sw_m_1_haloTin,size(ztab_sub_interiorT_sw_m_1_haloTin), &
+                MPI_DOUBLE_PRECISION, dest_rank, send_tag, &
+                MPI_COMM_HORIZ, send_requestT(2), ierr)
+           !$acc end host_data
+#else
+           call mpi_isend(a%st(1,a_n/2+1,0),1,sub_interiorT(level,m-1), dest_rank, send_tag, &
+                MPI_COMM_HORIZ, send_requestT(2), ierr)           
+#endif
+        end if
+
+#ifndef NDEBUG
+  if (ierr .ne. 0) &
+    call fatalerror("Distribute: send to SW failed in mpi_isend().")
+#endif
+        ! (Asynchronous) send to SE
+        call mpi_cart_rank(MPI_COMM_HORIZ, &
+                           (/p_horiz(1)+stepsize,p_horiz(2)+stepsize/), &
+                           dest_rank, &
+                           ierr)
+        send_tag = 1002
+        if (LUseO) call mpi_isend(a%s(0,a_n/2+1,a_n/2+1),1,sub_interior(level,m-1), dest_rank, send_tag, &
+                      MPI_COMM_HORIZ, send_request(3), ierr)
+        send_tag = 1012
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT
+           ztab_sub_interiorT_se_m_1_haloTin => tab_sub_interiorT_se(level,m-1)%haloTin
+           !$acc parallel loop collapse(3)
+           do concurrent (ii=1:a_n/2,ij=1:a_n/2,ik=1:nz+2)
+              ztab_sub_interiorT_se_m_1_haloTin(ii,ij,ik) = za_st(ii+a_n/2,ij+a_n/2,ik-1)
+           end do
+           !$acc host_data use_device(ztab_sub_interiorT_se_m_1_haloTin)
+           call mpi_isend(ztab_sub_interiorT_se_m_1_haloTin,size(ztab_sub_interiorT_se_m_1_haloTin), &
+                MPI_DOUBLE_PRECISION, dest_rank, send_tag, &
+                MPI_COMM_HORIZ, send_requestT(3), ierr)
+           !$acc end host_data
+#else
+           call mpi_isend(a%st(a_n/2+1,a_n/2+1,0),1,sub_interiorT(level,m-1), dest_rank, send_tag, &
+                MPI_COMM_HORIZ, send_requestT(3), ierr)          
+#endif
+        end if
+#ifndef NDEBUG
+  if (ierr .ne. 0) &
+    call fatalerror("Distribute: send to SE failed in mpi_isend().")
+#endif
+        ! While sending, copy local data
+        if (LUseO) b%s(0:nz+1,1:b_n,1:b_n) = a%s(0:nz+1,1:b_n,1:b_n)
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT                     
+           zb_st => b%st
+           za_st => a%st
+           !$acc parallel loop collapse(3)
+           do concurrent (ii=1:b_n,ij=1:b_n,ik=1:nz+2)
+              zb_st(ii,ij,ik-1) = za_st(ii,ij,ik-1)
+           end do
+#else
+           b%st(1:b_n,1:b_n,0:nz+1) = a%st(1:b_n,1:b_n,0:nz+1)
+#endif
+        end if
+        ! Only proceed when async sends to complete
+        if (LUseO) call mpi_waitall(3, send_request, MPI_STATUSES_IGNORE, ierr)
+        if (LUseT) call mpi_waitall(3, send_requestT, MPI_STATUSES_IGNORE, ierr)
+      end if
+      if ( corner_ne ) then
+
+        ! Receive from NW
+        call mpi_cart_rank(MPI_COMM_HORIZ, &
+                           (/p_horiz(1),p_horiz(2)-stepsize/), &
+                           source_rank, &
+                           ierr)
+        
+        zb_st => b%st
+        
+        recv_tag = 1000
+        if (LUseO) call mpi_recv(b%s(0,1,1),1,interior(level,m),source_rank,recv_tag,MPI_COMM_HORIZ,stat,ierr)
+        recv_tag = 1010
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT
+           ztab_interiorT_ne_m_haloTout => tab_interiorT_ne(level,m)%haloTout
+           !$acc host_data use_device(ztab_interiorT_ne_m_haloTout)
+           call mpi_recv(ztab_interiorT_ne_m_haloTout,size(ztab_interiorT_ne_m_haloTout), &
+                MPI_DOUBLE_PRECISION,source_rank,recv_tag,MPI_COMM_HORIZ,stat,ierr)
+           !$acc end host_data
+           !$acc parallel loop collapse(3)
+           do concurrent (ii=1:b_n,ij=1:b_n,ik=1:nz+2)
+              zb_st(ii,ij,ik-1) = ztab_interiorT_ne_m_haloTout(ii,ij,ik)
+           end do
+#else
+           call mpi_recv(b%st(1,1,0),1,interiorT(level,m),source_rank,recv_tag,MPI_COMM_HORIZ,stat,ierr)           
+#endif
+        end if
+#ifndef NDEBUG
+  if (ierr .ne. 0) &
+    call fatalerror("Distribute: receive on NE failed in mpi_recv().")
+#endif
+      end if
+      if ( corner_sw ) then
+        ! Receive from NW
+        call mpi_cart_rank(MPI_COMM_HORIZ, &
+                           (/p_horiz(1)-stepsize,p_horiz(2)/), &
+                           source_rank, &
+                           ierr)
+
+        zb_st => b%st
+        
+        recv_tag = 1001
+        if (LUseO) call mpi_recv(b%s(0,1,1),1,interior(level,m),source_rank,recv_tag,MPI_COMM_HORIZ,stat,ierr)
+        recv_tag = 1011
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT
+           ztab_interiorT_sw_m_haloTout => tab_interiorT_sw(level,m)%haloTout
+           !$acc host_data use_device(ztab_interiorT_sw_m_haloTout)
+           call mpi_recv(ztab_interiorT_sw_m_haloTout,size(ztab_interiorT_sw_m_haloTout), &           
+                MPI_DOUBLE_PRECISION,source_rank,recv_tag,MPI_COMM_HORIZ,stat,ierr)
+           !$acc end host_data
+           !$acc parallel loop collapse(3)
+           do concurrent (ii=1:b_n,ij=1:b_n,ik=1:nz+2)
+              zb_st(ii,ij,ik-1) = ztab_interiorT_sw_m_haloTout(ii,ij,ik)
+           end do
+#else
+           call mpi_recv(b%st(1,1,0),1,interiorT(level,m),source_rank,recv_tag,MPI_COMM_HORIZ,stat,ierr)           
+#endif
+        end if
+#ifndef NDEBUG
+  if (ierr .ne. 0) &
+    call fatalerror("Distribute: receive on SW failed in mpi_recv().")
+#endif
+      end if
+      if ( corner_se ) then
+        ! Receive from NW
+        call mpi_cart_rank(MPI_COMM_HORIZ, &
+                           (/p_horiz(1)-stepsize,p_horiz(2)-stepsize/), &
+                           source_rank, &
+                           ierr)
+
+        zb_st => b%st
+        
+        recv_tag = 1002
+        if (LUseO) call mpi_recv(b%s(0,1,1),1,interior(level,m),source_rank,recv_tag,MPI_COMM_HORIZ,stat,ierr)
+        recv_tag = 1012
+        if (LUseT) then
+#ifdef MNH_GPUDIRECT
+           ztab_interiorT_se_m_haloTout => tab_interiorT_se(level,m)%haloTout
+           !$acc host_data use_device(ztab_interiorT_se_m_haloTout)
+           call mpi_recv(ztab_interiorT_se_m_haloTout,size(ztab_interiorT_se_m_haloTout), &
+                MPI_DOUBLE_PRECISION,source_rank,recv_tag,MPI_COMM_HORIZ,stat,ierr)
+           !$acc end host_data
+           !$acc parallel loop collapse(3)
+           do concurrent (ii=1:b_n,ij=1:b_n,ik=1:nz+2)
+              zb_st(ii,ij,ik-1) = ztab_interiorT_se_m_haloTout(ii,ij,ik)
+           end do           
+#else
+           call mpi_recv(b%st(1,1,0),1,interiorT(level,m),source_rank,recv_tag,MPI_COMM_HORIZ,stat,ierr)           
+#endif
+        end if
+#ifndef NDEBUG
+  if (ierr .ne. 0) &
+    call fatalerror("Distribute: receive on NW failed in mpi_recv().")
+#endif
+      end if
+
+    end if
+    call finish_timer(t_distribute(m))
+
+  end subroutine distribute
+
+end module communication
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/compile_tensor b/src/ZSOLVER/tensorproductmultigrid_Source/compile_tensor
new file mode 100755
index 0000000000000000000000000000000000000000..07637c68a0da31c9f105c3cea9208f4a40223d00
--- /dev/null
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/compile_tensor
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+set -x
+set -e
+
+OPT_BASE="  -Mbackslash -Mextend -Kieee -nofma  -Mallocatable=95 "
+#OPT_BASE="  -Mbackslash -Mextend   -Mallocatable=95 "
+
+#OPTLEVEL="  -O2 -ta=multicore,tesla:nofma,managed "
+#OPTLEVEL="  -g -O2 -ta=multicore,tesla:managed "
+#OPTLEVEL=" -tp=px -O2 -ta=multicore,tesla,nofma,cc35,cc50,cc70,cuda10.1,managed -Minfo=accel,ccff -Mprof=ccff  "
+#OPTLEVEL=" -O2 -ta=multicore,tesla,nofma,cc70,cuda11.0,managed -Minfo=accel "
+OPTLEVEL_MAN=" -Mpreprocess -O4 -ta=host,tesla,nofma,cc70,cuda11.0,managed -Minfo=accel "
+OPTLEVEL_ACC=" -Mpreprocess -O4 -ta=host,tesla,nofma,cc70,cuda11.0         -Minfo=accel "
+#OPTLEVEL=" -Mpreprocess -O2 -ta=host,tesla,nofma,cc70,cuda11.0,managed -Minfo=accel "
+#OPTLEVEL=" -O2 -ta=tesla:nofma,managed "
+
+#OPT="-r8 -DCARTESIANGEOMETRY -DOVERLAPCOMMS -DPIECEWISELINEAR -Mpreprocess ${OPT_BASE} ${OPTLEVEL} "
+OPT="-r8 -DMNH_GPUDIRECT -DCARTESIANGEOMETRY -DPIECEWISELINEAR -Mpreprocess ${OPT_BASE} ${OPTLEVEL_MAN} "
+
+OPT_ACC="-r8 -DMNH_GPUDIRECT -DCARTESIANGEOMETRY -DPIECEWISELINEAR -Mpreprocess ${OPT_BASE} ${OPTLEVEL_ACC} "
+
+F90="mpif90 ${OPT} "
+
+F90_ACC="mpif90 ${OPT_ACC} "
+
+rm -f *.o *.mod mg_main_mnh
+
+pgf90 -show ${OPT} mg_main_mnh.f90
+
+${F90_ACC} -c mode_mnh_allocate_mg_halo.f90
+
+for file in mode_openacc_set_device.f90 parameters.f90 messages.f90 datatypes.f90 timer.f90 communication.f90 discretisation.f90 \
+            solver.f90 conjugategradient.f90 multigrid.f90 profiles.f90 mode_mg_read_param.f90 \
+	    mode_mg.f90 mode_mg_read_param.f90 \
+	    dblas.f90 
+do
+echo ====== file=$file
+${F90} -c $file
+done
+
+
+${F90} -o mg_main_mnh${XYZ} mg_main_mnh.f90 *.o
+
+rm -f *.o *.mod
+
+
+
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/conjugategradient.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/conjugategradient.f90
new file mode 100644
index 0000000000000000000000000000000000000000..30277d8625ad6735444ad7335b761ab6ed369b7a
--- /dev/null
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/conjugategradient.f90
@@ -0,0 +1,529 @@
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+!
+!  This file is part of the TensorProductMultigrid code.
+!  
+!  (c) The copyright relating to this work is owned jointly by the
+!  Crown, Met Office and NERC [2014]. However, it has been created
+!  with the help of the GungHo Consortium, whose members are identified
+!  at https://puma.nerc.ac.uk/trac/GungHo/wiki .
+!  
+!  Main Developer: Eike Mueller
+!  
+!  TensorProductMultigrid is free software: you can redistribute it and/or
+!  modify it under the terms of the GNU Lesser General Public License as
+!  published by the Free Software Foundation, either version 3 of the
+!  License, or (at your option) any later version.
+!  
+!  TensorProductMultigrid is distributed in the hope that it will be useful,
+!  but WITHOUT ANY WARRANTY; without even the implied warranty of
+!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+!  GNU Lesser General Public License for more details.
+!  
+!  You should have received a copy of the GNU Lesser General Public License
+!  along with TensorProductMultigrid (see files COPYING and COPYING.LESSER).
+!  If not, see <http://www.gnu.org/licenses/>.
+!
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+
+
+!==================================================================
+!
+! Conjugate gradient solver
+!
+!    Eike Mueller, University of Bath, Feb 2012
+!
+!==================================================================
+module conjugategradient
+
+  use parameters
+  use datatypes
+  use discretisation
+  use messages
+  use communication
+#ifndef MNH
+  use mpi
+#else
+  use modd_mpif
+#endif
+
+  implicit none
+
+public::cg_parameters
+public::cg_initialise
+public::cg_finalise
+public::cg_solve_mnh
+public::cg_solve
+
+private
+
+  ! --- Conjugate gradient parameters type ---
+  type cg_parameters
+    ! Verbosity level
+    integer :: verbose
+    ! Maximal number of iterations
+    integer :: maxiter
+    ! Required residual reduction
+    real(kind=rl) :: resreduction
+    ! Smoother iterations in preconditioner
+    integer :: n_prec
+  end type cg_parameters
+
+! --- Parameters ---
+  type(cg_parameters) :: cg_param
+  type(grid_parameters) :: grid_param
+
+contains
+
+!==================================================================
+! Initialise conjugate gradient module,
+!==================================================================
+  subroutine cg_initialise(cg_param_in)    &  ! Conjugate gradient
+                                           &  ! parameters
+    implicit none
+    type(cg_parameters), intent(in)    :: cg_param_in
+
+    if (i_am_master_mpi) then
+      write(STDOUT,*) '*** Initialising Conjugate gradient ***'
+      write(STDOUT,*) ''
+    end if
+    cg_param = cg_param_in
+  end subroutine cg_initialise
+
+!==================================================================
+! Finalise conjugate gradient module,
+!==================================================================
+  subroutine cg_finalise()
+    implicit none
+
+    if (i_am_master_mpi) then
+      write(STDOUT,*) '*** Finalising Conjugate gradient ***'
+      write(STDOUT,*) ''
+    end if
+  end subroutine cg_finalise
+
+!==================================================================
+! Solve A.u = b.
+!==================================================================
+  subroutine cg_solve_mnh(level,m,b,u)
+    implicit none
+    integer, intent(in)           :: level
+    integer, intent(in)           :: m
+    type(scalar3d), intent(in)    :: b    ! RHS vector
+    type(scalar3d), intent(inout) :: u    ! solution vector
+    type(scalar3d)                :: p    ! } Auxilliary vectors
+    type(scalar3d)                :: r    ! } Auxilliary vectors
+    type(scalar3d)                :: Ap   ! }
+    type(scalar3d)                :: z    ! }
+    integer                       :: n_lin
+    real(kind=rl)                 :: res0, rz, rz_old, res, alpha
+    integer :: i
+    logical :: solver_converged = .false.
+    integer :: n, nz, nlocal, halo_size
+    real(kind=rl) :: pAp
+
+    ! Initialise auxiliary fields
+    p%grid_param = u%grid_param
+    p%ix_min = u%ix_min
+    p%ix_max = u%ix_max
+    p%iy_min = u%iy_min
+    p%iy_max = u%iy_max
+    p%icompx_min = u%icompx_min
+    p%icompx_max = u%icompx_max
+    p%icompy_min = u%icompy_min
+    p%icompy_max = u%icompy_max
+    p%halo_size = u%halo_size
+
+    r%grid_param = u%grid_param
+    r%ix_min = u%ix_min
+    r%ix_max = u%ix_max
+    r%iy_min = u%iy_min
+    r%iy_max = u%iy_max
+    r%icompx_min = u%icompx_min
+    r%icompx_max = u%icompx_max
+    r%icompy_min = u%icompy_min
+    r%icompy_max = u%icompy_max
+    r%halo_size = u%halo_size
+
+    z%grid_param = u%grid_param
+    z%ix_min = u%ix_min
+    z%ix_max = u%ix_max
+    z%iy_min = u%iy_min
+    z%iy_max = u%iy_max
+    z%icompx_min = u%icompx_min
+    z%icompx_max = u%icompx_max
+    z%icompy_min = u%icompy_min
+    z%icompy_max = u%icompy_max
+    z%halo_size = u%halo_size
+
+    Ap%grid_param = u%grid_param
+    Ap%ix_min = u%ix_min
+    Ap%ix_max = u%ix_max
+    Ap%iy_min = u%iy_min
+    Ap%iy_max = u%iy_max
+    Ap%icompx_min = u%icompx_min
+    Ap%icompx_max = u%icompx_max
+    Ap%icompy_min = u%icompy_min
+    Ap%icompy_max = u%icompy_max
+    Ap%halo_size = u%halo_size
+
+    n = u%ix_max-u%ix_min+1
+    nz = u%grid_param%nz
+
+    nlocal = u%ix_max - u%ix_min + 1
+    halo_size = u%halo_size
+
+    n_lin = (nlocal+2*halo_size)**2 * (nz+2)
+
+    if (LUseO) then
+    allocate(r%s(0:nz+1,                     &
+             1-halo_size:nlocal+halo_size,   &
+             1-halo_size:nlocal+halo_size) )
+    allocate(z%s(0:nz+1,                     &
+             1-halo_size:nlocal+halo_size,   &
+             1-halo_size:nlocal+halo_size) )
+    allocate(p%s(0:nz+1,                     &
+             1-halo_size:nlocal+halo_size,   &
+             1-halo_size:nlocal+halo_size) )
+    allocate(Ap%s(0:nz+1,                    &
+             1-halo_size:nlocal+halo_size,   &
+             1-halo_size:nlocal+halo_size) )
+    r%s = 0.0_rl
+    z%s = 0.0_rl
+    p%s = 0.0_rl
+    Ap%s = 0.0_rl
+    endif
+
+    if (LUseT) then
+    allocate(r%st(1-halo_size:nlocal+halo_size,   &
+                  1-halo_size:nlocal+halo_size,   &
+                  0:nz+1) )
+    allocate(z%st(1-halo_size:nlocal+halo_size,   &
+                  1-halo_size:nlocal+halo_size,   &
+                  0:nz+1) )
+    allocate(p%st(1-halo_size:nlocal+halo_size,   &
+                  1-halo_size:nlocal+halo_size,   &
+                  0:nz+1) )
+    allocate(Ap%st(1-halo_size:nlocal+halo_size,   &
+                   1-halo_size:nlocal+halo_size,   &
+                   0:nz+1) )
+    r%st = 0.0_rl
+    z%st = 0.0_rl
+    p%st = 0.0_rl
+    Ap%st = 0.0_rl
+    endif
+
+
+    ! Initialise
+    ! r <- b - A.u
+    call calculate_residual_mnh(level,m,b,u,r)
+    ! z <- M^{-1} r
+    if (cg_param%n_prec > 0) then
+      call smooth_mnh(level,m,cg_param%n_prec,DIRECTION_FORWARD,r,z)
+      call smooth_mnh(level,m,cg_param%n_prec,DIRECTION_BACKWARD,r,z)
+    else
+      if (LUseO) call dcopy(n_lin,r%s,1,z%s,1)
+      if (LUseT) call dcopy(n_lin,r%st,1,z%st,1)
+    end if
+    ! p <- z
+    if (LUseO) call dcopy(n_lin,z%s,1,p%s,1)
+    if (LUseT) call dcopy(n_lin,z%st,1,p%st,1)
+    ! rz_old = <r,z>
+    call scalarprod_mnh(m,r,z,rz_old)
+    ! res0 <- ||r||
+    call scalarprod_mnh(m,r,r,res0)
+    res0 = dsqrt(res0)
+    if (cg_param%verbose > 0) then
+      if (i_am_master_mpi) then
+        write(STDOUT,'("    *** CG Solver ( ",I10," dof ) ***")') n_lin
+        write(STDOUT,'("    <CG> Initial residual ||r_0|| = ",E12.6)') res0
+      end if
+    endif
+    if (res0 > tolerance) then
+      do i=1,cg_param%maxiter
+        ! Ap <- A.p
+        call haloswap_mnh(level,m,p)
+        call apply_mnh(p,Ap)
+        ! alpha <- res_old / <p,A.p>
+        call scalarprod_mnh(m,p,Ap,pAp)
+        alpha = rz_old/pAp
+        ! x <- x + alpha*p
+        if (LUseO) call daxpy(n_lin,alpha,p%s,1,u%s,1)
+        if (LUseT) call daxpy(n_lin,alpha,p%st,1,u%st,1)
+        ! r <- r - alpha*A.p
+        if (LUseO) call daxpy(n_lin,-alpha,Ap%s,1,r%s,1)
+        if (LUseT) call daxpy(n_lin,-alpha,Ap%st,1,r%st,1)
+        call scalarprod_mnh(m,r,r,res)
+        res = dsqrt(res)
+        if (cg_param%verbose > 1) then
+          if (i_am_master_mpi) then
+            write(STDOUT,'("    <CG> Iteration ",I6," ||r|| = ",E12.6)') &
+              i, res
+          end if
+        end if
+        if ( (res/res0 < cg_param%resreduction) .or. &
+             (res < tolerance ) ) then
+          solver_converged = .true.
+          exit
+        end if
+        ! z <- M^{-1} r
+        if (LUseO) z%s = 0.0_rl
+        if (LUseT) z%st = 0.0_rl
+        if (cg_param%n_prec > 0) then
+          call smooth_mnh(level,m,cg_param%n_prec,DIRECTION_FORWARD,r,z)
+          call smooth_mnh(level,m,cg_param%n_prec,DIRECTION_BACKWARD,r,z)
+        else
+          if (LUseO) call dcopy(n_lin,r%s,1,z%s,1)
+          if (LUseT) call dcopy(n_lin,r%st,1,z%st,1)
+        end if
+        call scalarprod_mnh(m,r,z,rz)
+        ! p <- res/res_old*p
+        if (LUseO) call dscal(n_lin,rz/rz_old,p%s,1)
+        if (LUseT) call dscal(n_lin,rz/rz_old,p%st,1)
+        ! p <- p + z
+        if (LUseO) call daxpy(n_lin,1.0_rl,z%s,1,p%s,1)
+        if (LUseT) call daxpy(n_lin,1.0_rl,z%st,1,p%st,1)
+        rz_old = rz
+      end do
+    else
+      res = res0
+      solver_converged = .true.
+    end if
+    if (cg_param%verbose>0) then
+      if (solver_converged) then
+        if (i_am_master_mpi) then
+          write(STDOUT,'("    <CG> Final residual    ||r|| = ",E12.6)') res
+          write(STDOUT,'("    <CG> CG solver converged after ",I6," iterations rho_avg = ",F10.6)') i, (res/res0)**(1.0_rl/i)
+        end if
+      else
+        call warning("    <CG> Solver did not converge")
+      endif
+    end if
+
+    if (LUseO) then
+    deallocate(r%s)
+    deallocate(z%s)
+    deallocate(p%s)
+    deallocate(Ap%s)
+    end if
+
+    if (LUseT) then
+    deallocate(r%st)
+    deallocate(z%st)
+    deallocate(p%st)
+    deallocate(Ap%st)
+    end if
+
+  end subroutine cg_solve_mnh
+!==================================================================
+! Solve A.u = b.
+!==================================================================
+  subroutine cg_solve(level,m,b,u)
+    implicit none
+    integer, intent(in)           :: level
+    integer, intent(in)           :: m
+    type(scalar3d), intent(in)    :: b    ! RHS vector
+    type(scalar3d), intent(inout) :: u    ! solution vector
+    type(scalar3d)                :: p    ! } Auxilliary vectors
+    type(scalar3d)                :: r    ! } Auxilliary vectors
+    type(scalar3d)                :: Ap   ! }
+    type(scalar3d)                :: z    ! }
+    integer                       :: n_lin
+    real(kind=rl)                 :: res0, rz, rz_old, res, alpha
+    integer :: i
+    logical :: solver_converged = .false.
+    integer :: n, nz, nlocal, halo_size
+    real(kind=rl) :: pAp
+
+    ! Initialise auxiliary fields
+    p%grid_param = u%grid_param
+    p%ix_min = u%ix_min
+    p%ix_max = u%ix_max
+    p%iy_min = u%iy_min
+    p%iy_max = u%iy_max
+    p%icompx_min = u%icompx_min
+    p%icompx_max = u%icompx_max
+    p%icompy_min = u%icompy_min
+    p%icompy_max = u%icompy_max
+    p%halo_size = u%halo_size
+
+    r%grid_param = u%grid_param
+    r%ix_min = u%ix_min
+    r%ix_max = u%ix_max
+    r%iy_min = u%iy_min
+    r%iy_max = u%iy_max
+    r%icompx_min = u%icompx_min
+    r%icompx_max = u%icompx_max
+    r%icompy_min = u%icompy_min
+    r%icompy_max = u%icompy_max
+    r%halo_size = u%halo_size
+
+    z%grid_param = u%grid_param
+    z%ix_min = u%ix_min
+    z%ix_max = u%ix_max
+    z%iy_min = u%iy_min
+    z%iy_max = u%iy_max
+    z%icompx_min = u%icompx_min
+    z%icompx_max = u%icompx_max
+    z%icompy_min = u%icompy_min
+    z%icompy_max = u%icompy_max
+    z%halo_size = u%halo_size
+
+    Ap%grid_param = u%grid_param
+    Ap%ix_min = u%ix_min
+    Ap%ix_max = u%ix_max
+    Ap%iy_min = u%iy_min
+    Ap%iy_max = u%iy_max
+    Ap%icompx_min = u%icompx_min
+    Ap%icompx_max = u%icompx_max
+    Ap%icompy_min = u%icompy_min
+    Ap%icompy_max = u%icompy_max
+    Ap%halo_size = u%halo_size
+
+    n = u%ix_max-u%ix_min+1
+    nz = u%grid_param%nz
+
+    nlocal = u%ix_max - u%ix_min + 1
+    halo_size = u%halo_size
+
+    n_lin = (nlocal+2*halo_size)**2 * (nz+2)
+
+    if (LUseO) then
+    allocate(r%s(0:nz+1,                     &
+             1-halo_size:nlocal+halo_size,   &
+             1-halo_size:nlocal+halo_size) )
+    allocate(z%s(0:nz+1,                     &
+             1-halo_size:nlocal+halo_size,   &
+             1-halo_size:nlocal+halo_size) )
+    allocate(p%s(0:nz+1,                     &
+             1-halo_size:nlocal+halo_size,   &
+             1-halo_size:nlocal+halo_size) )
+    allocate(Ap%s(0:nz+1,                    &
+             1-halo_size:nlocal+halo_size,   &
+             1-halo_size:nlocal+halo_size) )
+    r%s = 0.0_rl
+    z%s = 0.0_rl
+    p%s = 0.0_rl
+    Ap%s = 0.0_rl
+    end if
+
+    if (LUseT) then
+    allocate(r%st(1-halo_size:nlocal+halo_size,   &
+                  1-halo_size:nlocal+halo_size,   &
+                  0:nz+1) )
+    allocate(z%st(1-halo_size:nlocal+halo_size,   &
+                  1-halo_size:nlocal+halo_size,   &
+                  0:nz+1) )
+    allocate(p%st(1-halo_size:nlocal+halo_size,   &
+                  1-halo_size:nlocal+halo_size,   &
+                  0:nz+1) )
+    allocate(Ap%st(1-halo_size:nlocal+halo_size,  &
+                   1-halo_size:nlocal+halo_size,  &
+                   0:nz+1) )
+    r%st = 0.0_rl
+    z%st = 0.0_rl
+    p%st = 0.0_rl
+    Ap%st = 0.0_rl
+    end if
+
+    ! Initialise
+    ! r <- b - A.u
+    call calculate_residual(level,m,b,u,r)
+    ! z <- M^{-1} r
+    if (cg_param%n_prec > 0) then
+      call smooth(level,m,cg_param%n_prec,DIRECTION_FORWARD,r,z)
+      call smooth(level,m,cg_param%n_prec,DIRECTION_BACKWARD,r,z)
+    else
+      if (LUseO) call dcopy(n_lin,r%s,1,z%s,1)
+      if (LUseT) call dcopy(n_lin,r%st,1,z%st,1)
+    end if
+    ! p <- z
+    if (LUseO) call dcopy(n_lin,z%s,1,p%s,1)
+    if (LUseT) call dcopy(n_lin,z%st,1,p%st,1)
+    ! rz_old = <r,z>
+    call scalarprod(m,r,z,rz_old)
+    ! res0 <- ||r||
+    call scalarprod(m,r,r,res0)
+    res0 = dsqrt(res0)
+    if (cg_param%verbose > 0) then
+      if (i_am_master_mpi) then
+        write(STDOUT,'("    *** CG Solver ( ",I10," dof ) ***")') n_lin
+        write(STDOUT,'("    <CG> Initial residual ||r_0|| = ",E12.6)') res0
+      end if
+    endif
+    if (res0 > tolerance) then
+      do i=1,cg_param%maxiter
+        ! Ap <- A.p
+        call haloswap(level,m,p)
+        call apply(p,Ap)
+        ! alpha <- res_old / <p,A.p>
+        call scalarprod(m,p,Ap,pAp)
+        alpha = rz_old/pAp
+        ! x <- x + alpha*p
+        if (LUseO) call daxpy(n_lin,alpha,p%s,1,u%s,1)
+        if (LUseT) call daxpy(n_lin,alpha,p%st,1,u%st,1)
+        ! r <- r - alpha*A.p
+        if (LUseO) call daxpy(n_lin,-alpha,Ap%s,1,r%s,1)
+        if (LUseT) call daxpy(n_lin,-alpha,Ap%st,1,r%st,1)
+        call scalarprod(m,r,r,res)
+        res = dsqrt(res)
+        if (cg_param%verbose > 1) then
+          if (i_am_master_mpi) then
+            write(STDOUT,'("    <CG> Iteration ",I6," ||r|| = ",E12.6)') &
+              i, res
+          end if
+        end if
+        if ( (res/res0 < cg_param%resreduction) .or. &
+             (res < tolerance ) ) then
+          solver_converged = .true.
+          exit
+        end if
+        ! z <- M^{-1} r
+        if (LUseO) z%s = 0.0_rl
+        if (LUseT) z%st = 0.0_rl
+        if (cg_param%n_prec > 0) then
+          call smooth(level,m,cg_param%n_prec,DIRECTION_FORWARD,r,z)
+          call smooth(level,m,cg_param%n_prec,DIRECTION_BACKWARD,r,z)
+        else
+          if (LUseO) call dcopy(n_lin,r%s,1,z%s,1)
+          if (LUseT) call dcopy(n_lin,r%st,1,z%st,1)
+        end if
+        call scalarprod(m,r,z,rz)
+        ! p <- res/res_old*p
+        if (LUseO) call dscal(n_lin,rz/rz_old,p%s,1)
+        if (LUseT) call dscal(n_lin,rz/rz_old,p%st,1)
+        ! p <- p + z
+        if (LUseO) call daxpy(n_lin,1.0_rl,z%s,1,p%s,1)
+        if (LUseT) call daxpy(n_lin,1.0_rl,z%st,1,p%st,1)
+        rz_old = rz
+      end do
+    else
+      res = res0
+      solver_converged = .true.
+    end if
+    if (cg_param%verbose>0) then
+      if (solver_converged) then
+        if (i_am_master_mpi) then
+          write(STDOUT,'("    <CG> Final residual    ||r|| = ",E12.6)') res
+          write(STDOUT,'("    <CG> CG solver converged after ",I6," iterations rho_avg = ",F10.6)') i, (res/res0)**(1.0_rl/i)
+        end if
+      else
+        call warning("    <CG> Solver did not converge")
+      endif
+    end if
+
+    if (LUseO) then
+    deallocate(r%s)
+    deallocate(z%s)
+    deallocate(p%s)
+    deallocate(Ap%s)
+    end if
+    if (LUseT) then
+    deallocate(r%st)
+    deallocate(z%st)
+    deallocate(p%st)
+    deallocate(Ap%st)
+    end if
+  end subroutine cg_solve
+
+end module conjugategradient
+
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/datatypes.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/datatypes.f90
new file mode 100644
index 0000000000000000000000000000000000000000..d0ddee6daae5fa031349db044389cb510c92b144
--- /dev/null
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/datatypes.f90
@@ -0,0 +1,519 @@
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+!
+!  This file is part of the TensorProductMultigrid code.
+!  
+!  (c) The copyright relating to this work is owned jointly by the
+!  Crown, Met Office and NERC [2014]. However, it has been created
+!  with the help of the GungHo Consortium, whose members are identified
+!  at https://puma.nerc.ac.uk/trac/GungHo/wiki .
+!  
+!  Main Developer: Eike Mueller
+!  
+!  TensorProductMultigrid is free software: you can redistribute it and/or
+!  modify it under the terms of the GNU Lesser General Public License as
+!  published by the Free Software Foundation, either version 3 of the
+!  License, or (at your option) any later version.
+!  
+!  TensorProductMultigrid is distributed in the hope that it will be useful,
+!  but WITHOUT ANY WARRANTY; without even the implied warranty of
+!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+!  GNU Lesser General Public License for more details.
+!  
+!  You should have received a copy of the GNU Lesser General Public License
+!  along with TensorProductMultigrid (see files COPYING and COPYING.LESSER).
+!  If not, see <http://www.gnu.org/licenses/>.
+!
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+
+
+!==================================================================
+!
+!   Grid data types for three dimensional cell centred grids.
+!   We always assume that the number of gridcells and size in
+!   the x- and y- direction is identical.
+!
+!    Eike Mueller, University of Bath, Feb 2012
+!
+!==================================================================
+
+
+module datatypes
+
+#ifndef MNH
+  use mpi
+#else
+  use modd_mpif
+#endif  
+  use parameters
+  use messages
+
+  implicit none
+
+! Vertical boundary conditions
+  integer, parameter :: VERTBC_DIRICHLET = 1
+  integer, parameter :: VERTBC_NEUMANN = 2
+
+! Parameters of three dimensional grid
+  type grid_parameters
+    integer :: n         ! Total number of grid cells in horizontal direction
+    integer :: nz        ! Total number of grid cells in vertical direction
+    real(kind=rl) :: L   ! Global extent of grid in horizontal direction
+    real(kind=rl) :: H   ! Global extent of grid in vertical direction
+    integer :: vertbc    ! Vertical boundary condition (see VERTBC_DIRICHLET
+                         ! and VERTBC_NEUMANN)
+    logical :: graded    ! Is the vertical grid graded?
+  end type grid_parameters
+
+! Three dimensional scalar field s(z,y,x)
+  type scalar3d
+    integer :: ix_min     ! } (Inclusive) range of locally owned cells
+    integer :: ix_max     ! } in the x-direction
+    integer :: iy_min     ! } (these ranges DO NOT include halo cells)
+    integer :: iy_max     ! } in the y-direction
+    integer :: icompx_min ! } (Inclusive) ranges of computational cells,
+    integer :: icompx_max ! } in local coords. All cells in these ranges
+    integer :: icompy_min ! } are included in calculations, e.g. in the
+    integer :: icompy_max ! } smoother. This allows duplicating operations
+                          ! } on part of the halo for RB Gauss Seidel
+    integer :: halo_size  ! Size of halos
+    logical :: isactive   ! Is this field active, i.e. used on one of the
+                          ! active processes on coarser grids?
+    real(kind=rl),allocatable :: s(:,:,:)
+    real(kind=rl),pointer, contiguous :: st(:,:,:)
+    type(grid_parameters) :: grid_param
+  end type scalar3d
+
+public::VERTBC_DIRICHLET
+public::VERTBC_NEUMANN
+public::scalar3d
+public::grid_parameters
+public::L2norm_mnh
+public::L2norm
+public::daxpy_scalar3d
+public::save_scalar3d
+public::create_scalar3d
+public::volscale_scalar3d_mnh
+public::volscale_scalar3d
+public::destroy_scalar3d
+public::volume_of_element
+public::r_grid
+
+private
+
+  ! Vertical grid, this array of length n_z+1 stores the
+  ! vertices of the grid in the vertical direction
+  real(kind=rl), allocatable :: r_grid(:)
+
+  contains
+
+!==================================================================
+! volume of element on cubed sphere grid
+! NB: ix,iy are global indices
+!==================================================================
+  real(kind=rl) function volume_of_element(ix,iy,grid_param)
+    implicit none
+    integer, intent(in) :: ix
+    integer, intent(in) :: iy
+    type(grid_parameters), intent(in) :: grid_param
+    real(kind=rl) :: h
+    real(kind=rl) :: rho_i, sigma_j
+    h = 2.0_rl/grid_param%n
+    rho_i = 2.0_rl*(ix-0.5_rl)/grid_param%n-1.0_rl
+    sigma_j = 2.0_rl*(iy-0.5_rl)/grid_param%n-1.0_rl
+    volume_of_element = (1.0_rl+rho_i**2+sigma_j**2)**(-1.5_rl)*h**2
+  end function volume_of_element
+
+!==================================================================
+! Create scalar3d field on fine grid and set to zero
+!==================================================================
+  subroutine create_scalar3d(comm_horiz,grid_param, halo_size, phi)
+    implicit none
+
+    integer                             :: comm_horiz  ! Horizontal communicator
+    type(grid_parameters), intent(in)   :: grid_param  ! Grid parameters
+    integer, intent(in)                 :: halo_size   ! Halo size
+    type(scalar3d), intent(inout)       :: phi         ! Field to create
+    integer                             :: nproc       ! Number of processes
+    integer                             :: rank, ierr  ! rank and MPI error
+    integer, dimension(2)               :: p_horiz     ! position in 2d
+                                                       ! processor grid
+    integer                             :: nlocal      ! Local number of
+                                                       ! cells in horizontal
+                                                       ! direction
+    integer, parameter                  :: dim_horiz = 2 ! horiz. dimension
+
+    real(kind=rl) , dimension(:,:,:), pointer , contiguous :: zphi_st
+
+    phi%grid_param = grid_param
+    call mpi_comm_size(comm_horiz, nproc, ierr)
+    nlocal = grid_param%n/sqrt(1.0*nproc)
+
+    ! Work out position in 2d processor grid
+    call mpi_comm_rank(comm_horiz, rank, ierr)
+    call mpi_cart_coords(comm_horiz,rank,dim_horiz,p_horiz,ierr)
+    ! Set local data ranges
+    ! NB: p_horiz stores (py,px) in that order (see comment in
+    ! communication module)
+    phi%iy_min = p_horiz(1)*nlocal + 1
+    phi%iy_max = (p_horiz(1)+1)*nlocal
+    phi%ix_min = p_horiz(2)*nlocal + 1
+    phi%ix_max = (p_horiz(2)+1)*nlocal
+    ! Set computational ranges. Note that these are different at
+    ! the edges of the domain!
+    if (p_horiz(1) == 0) then
+      phi%icompy_min = 1
+    else
+      phi%icompy_min = 1 - (halo_size - 1)
+    end if
+    if (p_horiz(1) == floor(sqrt(1.0_rl*nproc))-1) then
+      phi%icompy_max = nlocal
+    else
+      phi%icompy_max = nlocal + (halo_size - 1)
+    end if
+    if (p_horiz(2) == 0) then
+      phi%icompx_min = 1
+    else
+      phi%icompx_min = 1 - (halo_size - 1)
+    end if
+    if (p_horiz(2) == floor(sqrt(1.0_rl*nproc))-1) then
+      phi%icompx_max = nlocal
+    else
+      phi%icompx_max = nlocal + (halo_size - 1)
+    end if
+    ! Set halo size
+    phi%halo_size = halo_size
+    ! Set field to active
+    phi%isactive = .true.
+    ! Allocate memory
+    if (LUseO) then
+    allocate(phi%s(0:grid_param%nz+1,            &
+                   1-halo_size:nlocal+halo_size, &
+                   1-halo_size:nlocal+halo_size))
+    phi%s(:,:,:) = 0.0_rl
+    end if
+    if (LUseT) then
+    allocate(zphi_st(1-halo_size:nlocal+halo_size, &
+                    1-halo_size:nlocal+halo_size, &
+                    0:grid_param%nz+1))
+    phi%st => zphi_st
+    !$acc kernels
+    zphi_st(:,:,:) = 0.0_rl
+    !$acc end kernels
+    end if
+
+  end subroutine create_scalar3d
+
+!==================================================================
+! Destroy scalar3d field on fine grid
+!==================================================================
+  subroutine destroy_scalar3d(phi)
+    implicit none
+    type(scalar3d), intent(inout) :: phi
+
+    if (LUseO) deallocate(phi%s)
+    if (LUseT) deallocate(phi%st)
+
+  end subroutine destroy_scalar3d
+
+!==================================================================
+! Scale fields with volume of element
+! Either multiply with volume factor |T| v_k (power = 1)
+! or divide by it (power = -1)
+!==================================================================
+  subroutine volscale_scalar3d_mnh(phi,power)
+    implicit none
+    type(scalar3d), intent(inout) :: phi
+    integer, intent(in) :: power
+    integer :: ix, iy, iz
+    integer :: ierr
+    integer :: nlocalx, nlocaly, nz
+    real(kind=rl) :: vol_h, vol_r, h, tmp
+
+    real , dimension(:,:,:), pointer , contiguous :: zphi_st
+
+    if (.not. ( ( power .eq. 1) .or. (power .eq. -1) ) ) then
+      call fatalerror("power has to be -1 or 1 when volume-scaling fields")
+    end if
+
+    if (phi%isactive) then
+
+    nlocalx = phi%ix_max-phi%ix_min+1
+    nlocaly = phi%iy_max-phi%iy_min+1
+    nz      = phi%grid_param%nz
+
+    h = phi%grid_param%L/phi%grid_param%n
+    vol_h = h**2
+    vol_r = 1.0_rl ! r_grid(iz+1)-r_grid(iz)
+    if (power == 1) then
+       tmp = vol_h*vol_r
+    else
+       tmp = 1.0_rl/(vol_h*vol_r)
+    end if
+  
+    if (LUseO) phi%s (1:nz,1:nlocaly,1:nlocalx) = tmp*phi%s (1:nz,1:nlocaly,1:nlocalx)
+    if (LUseT) then
+       zphi_st => phi%st
+       !$acc kernels
+       zphi_st(1:nlocalx,1:nlocaly,1:nz) = tmp*zphi_st(1:nlocalx,1:nlocaly,1:nz)
+       !$acc end kernels
+    end if
+
+    end if
+
+  end subroutine volscale_scalar3d_mnh
+
+!==================================================================
+! Scale fields with volume of element
+! Either multiply with volume factor |T| v_k (power = 1)
+! or divide by it (power = -1)
+!==================================================================
+  subroutine volscale_scalar3d(phi,power)
+    implicit none
+    type(scalar3d), intent(inout) :: phi
+    integer, intent(in) :: power
+    integer :: ix, iy, iz
+    integer :: ierr
+    integer :: nlocalx, nlocaly
+    real(kind=rl) :: vol_h, vol_r, h, tmp
+
+    if (.not. ( ( power .eq. 1) .or. (power .eq. -1) ) ) then
+      call fatalerror("power has to be -1 or 1 when volume-scaling fields")
+    end if
+
+    nlocalx = phi%ix_max-phi%ix_min+1
+    nlocaly = phi%iy_max-phi%iy_min+1
+
+    if (phi%isactive) then
+      do ix=1,nlocalx
+        do iy=1,nlocaly
+#ifdef CARTESIANGEOMETRY
+          h = phi%grid_param%L/phi%grid_param%n
+          vol_h = h**2
+#else
+          vol_h = volume_of_element(ix+(phi%ix_min-1), &
+                                    iy+(phi%iy_min-1), &
+                                    phi%grid_param)
+#endif
+          do iz=1,phi%grid_param%nz
+#ifdef CARTESIANGEOMETRY
+            vol_r = r_grid(iz+1)-r_grid(iz)
+#else
+            vol_r = (r_grid(iz+1)**3 - r_grid(iz)**3)/3.0_rl
+#endif
+            if (power == 1) then
+              tmp = vol_h*vol_r
+            else
+              tmp = 1.0_rl/(vol_h*vol_r)
+            end if
+             if (LUseO) phi%s(iz,iy,ix) = tmp*phi%s(iz,iy,ix)
+             if (LUseT) phi%st(ix,iy,iz) = tmp*phi%st(ix,iy,iz)
+          end do
+        end do
+      end do
+    end if
+
+  end subroutine volscale_scalar3d
+
+!==================================================================
+! Calculate L2 norm
+! If phi_is_volumeintegral is .true. then phi is interpreted
+! as the volume integral in a cell, otherwise it is interpreted as the
+! average value in a cell.
+!==================================================================
+  real(kind=rl) function l2norm_mnh(phi,phi_is_volumeintegral)
+    implicit none
+    type(scalar3d), intent(in) :: phi
+    logical, optional :: phi_is_volumeintegral
+    !local var
+    integer :: ix, iy, iz
+    real(kind=rl) :: tmp, global_tmp
+    real(kind=rl) :: tmpt, global_tmpt
+    integer :: ierr
+    integer :: nlocalx, nlocaly, nz
+    real(kind=rl) :: vol_h, vol_r, h
+    logical :: divide_by_volume
+    real(kind=rl) :: volume_factor
+
+    real , dimension(:,:,:) , pointer , contiguous :: zphi_st
+
+    nlocalx = phi%ix_max-phi%ix_min+1
+    nlocaly = phi%iy_max-phi%iy_min+1
+    nz      = phi%grid_param%nz
+
+    tmp = 0.0_rl
+    tmpt = 0.0_rl
+    if (phi%isactive) then
+
+       if (LUseO) then
+          do ix=1,nlocalx
+             do iy=1,nlocaly
+                do iz=1,nz
+                   tmp = tmp + phi%s(iz,iy,ix)**2 ! * volume_factor
+                end do
+             end do
+          end do
+       end if
+       
+       if (LUseT) then
+          zphi_st => phi%st
+          !$acc kernels loop collapse(3)
+          do iz=1,nz
+             do iy=1,nlocaly
+                do ix=1,nlocalx
+                   tmpt = tmpt + zphi_st(ix,iy,iz)**2 ! * volume_factor
+                end do
+             end do
+          end do
+          !$acc end kernels
+ 
+       end if
+    end if
+    
+    if (LUseO) then
+       call mpi_allreduce(tmp,global_tmp, 1, &
+            MPI_DOUBLE_PRECISION,MPI_SUM,MPI_COMM_WORLD,ierr)   
+       global_tmp = dsqrt(global_tmp)
+    endif
+    if (LUseT) then
+       call mpi_allreduce(tmpt,global_tmpt, 1, &
+            MPI_DOUBLE_PRECISION,MPI_SUM,MPI_COMM_WORLD,ierr)
+       global_tmpt = dsqrt(global_tmpt)
+    end if
+    if (LUseO) then
+       l2norm_mnh = global_tmp
+    else
+       l2norm_mnh = global_tmpt
+    endif
+
+  end function l2norm_mnh
+!----------------------------------------------------------------------------
+  real(kind=rl) function l2norm(phi,phi_is_volumeintegral)
+    implicit none
+    type(scalar3d), intent(in) :: phi
+    logical, optional :: phi_is_volumeintegral
+    integer :: ix, iy, iz
+    real(kind=rl) :: tmp, global_tmp
+    integer :: ierr
+    integer :: nlocalx, nlocaly
+    real(kind=rl) :: vol_h, vol_r, h
+    logical :: divide_by_volume
+    real(kind=rl) :: volume_factor
+    if (present(phi_is_volumeintegral)) then
+      divide_by_volume = phi_is_volumeintegral
+    else
+      divide_by_volume = .false.
+    end if
+
+    nlocalx = phi%ix_max-phi%ix_min+1
+    nlocaly = phi%iy_max-phi%iy_min+1
+
+    tmp = 0.0_rl
+    if (phi%isactive) then
+      do ix=1,nlocalx
+        do iy=1,nlocaly
+#ifdef CARTESIANGEOMETRY
+          h = phi%grid_param%L/phi%grid_param%n
+          vol_h = h**2
+#else
+          vol_h = volume_of_element(ix+(phi%ix_min-1), &
+                                    iy+(phi%iy_min-1), &
+                                    phi%grid_param)
+#endif
+          do iz=1,phi%grid_param%nz
+#ifdef CARTESIANGEOMETRY
+            vol_r = r_grid(iz+1)-r_grid(iz)
+#else
+            vol_r = (r_grid(iz+1)**3 - r_grid(iz)**3)/3.0_rl
+#endif
+            if (divide_by_volume) then
+              volume_factor = 1.0_rl/(vol_h*vol_r)
+            else
+              volume_factor = vol_h*vol_r
+            end if
+            tmp = tmp + volume_factor*phi%s(iz,iy,ix)**2
+          end do
+        end do
+      end do
+    end if
+
+    call mpi_allreduce(tmp,global_tmp, 1, &
+                       MPI_DOUBLE_PRECISION,MPI_SUM,MPI_COMM_WORLD,ierr)
+    l2norm = dsqrt(global_tmp)
+  end function l2norm
+
+!==================================================================
+! calculate phi <- phi + alpha*dphi
+!==================================================================
+  subroutine daxpy_scalar3d(alpha,dphi,phi)
+    implicit none
+    real(kind=rl), intent(in) :: alpha
+    type(scalar3d), intent(in) :: dphi
+    type(scalar3d), intent(inout) :: phi
+    integer :: nlin
+    integer :: nlocalx, nlocaly
+
+    nlocalx = phi%ix_max-phi%ix_min+1
+    nlocaly = phi%iy_max-phi%iy_min+1
+    nlin = (nlocalx+2*phi%halo_size) &
+         * (nlocaly+2*phi%halo_size) &
+         * (phi%grid_param%nz+2)
+
+    if (LUseO) call daxpy(nlin,alpha,dphi%s,1,phi%s,1)
+    if (LUseT) call daxpy(nlin,alpha,dphi%st,1,phi%st,1)
+    
+
+  end subroutine daxpy_scalar3d
+
+!==================================================================
+! Save scalar field to file
+!==================================================================
+  subroutine save_scalar3d(comm_horiz,phi,filename)
+    implicit none
+    integer, intent(in) :: comm_horiz
+    type(scalar3d), intent(in) :: phi
+    character(*), intent(in)   :: filename
+    integer :: file_id = 100
+    integer :: ix,iy,iz
+    integer :: nlocal
+    integer :: rank, nproc, ierr
+    character(len=21) :: s
+
+    nlocal = phi%ix_max-phi%ix_min+1
+
+    ! Get number of processes and rank
+    call mpi_comm_size(comm_horiz, nproc, ierr)
+    call mpi_comm_rank(comm_horiz, rank, ierr)
+
+    write(s,'(I10.10,"_",I10.10)') nproc, rank
+
+    open(unit=file_id,file=trim(filename)//"_"//trim(s)//".dat")
+    write(file_id,*) "# 3d scalar data file"
+    write(file_id,*) "# ==================="
+    write(file_id,*) "# Data is written as s(iz,iy,ix) "
+    write(file_id,*) "# with the leftmost index running fastest"
+    write(file_id,'(" n  = ",I8)') phi%grid_param%n
+    write(file_id,'(" nz = ",I8)') phi%grid_param%nz
+    write(file_id,'(" L  = ",F20.10)') phi%grid_param%L
+    write(file_id,'(" H  = ",F20.10)') phi%grid_param%H
+    write(file_id,'(" ix_min  = ",I10)') phi%ix_min
+    write(file_id,'(" ix_max  = ",I10)') phi%ix_max
+    write(file_id,'(" iy_min  = ",I10)') phi%iy_min
+    write(file_id,'(" iy_max  = ",I10)') phi%iy_max
+    write(file_id,'(" icompx_min  = ",I10)') phi%icompx_min
+    write(file_id,'(" icompx_max  = ",I10)') phi%icompx_max
+    write(file_id,'(" icompy_min  = ",I10)') phi%icompy_min
+    write(file_id,'(" icompy_max  = ",I10)') phi%icompy_max
+    write(file_id,'(" halosize    = ",I10)') phi%halo_size
+
+
+    do ix=1-phi%halo_size,nlocal+phi%halo_size
+      do iy=1-phi%halo_size,nlocal+phi%halo_size
+        do iz=0,phi%grid_param%nz+1
+          write(file_id,'(E24.15)') phi%s(iz,iy,ix)
+        end do
+      end do
+    end do
+    close(file_id)
+  end subroutine save_scalar3d
+
+end module datatypes
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/dblas.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/dblas.f90
new file mode 100644
index 0000000000000000000000000000000000000000..48d5dcdce4f328566fd6e968cd8ba21311c5dd30
--- /dev/null
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/dblas.f90
@@ -0,0 +1,241 @@
+subroutine dcopy(n,sx,incx,sy,incy)
+!
+!     copies a vector, x, to a vector, y.
+!     uses unrolled loops for increments equal to 1.
+!     jack dongarra, linpack, 3/11/78.
+!     modified 12/3/93, array(1) declarations changed to array(*)
+!     modified  12/12/00 change name to avoid confusion with spline routine
+!
+      real sx(*),sy(*)
+      integer i,incx,incy,ix,iy,m,mp1,n
+!
+      if(n.le.0)return
+      if(incx.eq.1.and.incy.eq.1)go to 20
+!
+!        code for unequal increments or equal increments
+!          not equal to 1
+!
+      ix = 1
+      iy = 1
+      if(incx.lt.0)ix = (-n+1)*incx + 1
+      if(incy.lt.0)iy = (-n+1)*incy + 1
+      do 10 i = 1,n
+        sy(iy) = sx(ix)
+        ix = ix + incx
+        iy = iy + incy
+   10 continue
+      return
+!
+!        code for both increments equal to 1
+!
+!
+!        clean-up loop
+!
+   20 m = mod(n,7)
+      if( m .eq. 0 ) go to 40
+      do 30 i = 1,m
+        sy(i) = sx(i)
+   30 continue
+      if( n .lt. 7 ) return
+   40 mp1 = m + 1
+      !$acc kernels
+      do 50 i = mp1,n,7
+        sy(i) = sx(i)
+        sy(i + 1) = sx(i + 1)
+        sy(i + 2) = sx(i + 2)
+        sy(i + 3) = sx(i + 3)
+        sy(i + 4) = sx(i + 4)
+        sy(i + 5) = sx(i + 5)
+        sy(i + 6) = sx(i + 6)
+       50 continue
+      !$acc end kernels
+      return
+
+end subroutine dcopy
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+SUBROUTINE DAXPY( N, SA, SX, INCX, SY, INCY )
+
+!          Y = A*X + Y  (X, Y = VECTORS, A = SCALAR)
+
+!  --INPUT--
+!        N  NUMBER OF ELEMENTS IN INPUT VECTORS 'X' AND 'Y'
+!       SA  SINGLE PRECISION SCALAR MULTIPLIER 'A'
+!       SX  SING-PREC ARRAY CONTAINING VECTOR 'X'
+!     INCX  SPACING OF ELEMENTS OF VECTOR 'X' IN 'SX'
+!       SY  SING-PREC ARRAY CONTAINING VECTOR 'Y'
+!     INCY  SPACING OF ELEMENTS OF VECTOR 'Y' IN 'SY'
+
+! --OUTPUT--
+!       SY   FOR I = 0 TO N-1, OVERWRITE  SY(LY+I*INCY) WITH 
+!                 SA*SX(LX+I*INCX) + SY(LY+I*INCY), 
+!            WHERE LX = 1          IF INCX .GE. 0,
+!                     = (-INCX)*N  IF INCX .LT. 0
+!            AND LY IS DEFINED IN A SIMILAR WAY USING INCY.
+
+	REAL SX(*), SY(*), SA
+
+
+	IF( N.LE.0 .OR. SA.EQ.0.0 ) RETURN
+
+	IF ( INCX.EQ.INCY .AND. INCX.GT.1 )  THEN
+
+	    DO 10  I = 1, 1+(N-1)*INCX, INCX
+	       SY(I) = SY(I) + SA * SX(I)
+   10     CONTINUE
+
+	ELSE IF ( INCX.EQ.INCY .AND. INCX.EQ.1 )  THEN
+
+!                                        ** EQUAL, UNIT INCREMENTS
+	   M = MOD(N,4)
+	   IF( M .NE. 0 ) THEN
+!                            ** CLEAN-UP LOOP SO REMAINING VECTOR LENGTH
+!                            ** IS A MULTIPLE OF 4.
+	      DO 20  I = 1, M
+	        SY(I) = SY(I) + SA * SX(I)
+   20       CONTINUE
+	   ENDIF
+!                              ** UNROLL LOOP FOR SPEED
+    !$acc kernels
+	   DO 30  I = M+1, N, 4
+	      SY(I)   = SY(I)   + SA * SX(I)
+	      SY(I+1) = SY(I+1) + SA * SX(I+1)
+	      SY(I+2) = SY(I+2) + SA * SX(I+2)
+	      SY(I+3) = SY(I+3) + SA * SX(I+3)
+   30    CONTINUE
+   !$acc end kernels
+
+	ELSE
+!               ** NONEQUAL OR NONPOSITIVE INCREMENTS.
+	   IX = 1
+	   IY = 1
+	   IF( INCX.LT.0 )  IX = 1 + (N-1)*(-INCX)
+	   IF( INCY.LT.0 )  IY = 1 + (N-1)*(-INCY)
+	   DO 40  I = 1, N
+	      SY(IY) = SY(IY) + SA*SX(IX)
+	      IX = IX + INCX
+	      IY = IY + INCY
+   40    CONTINUE
+
+	ENDIF
+
+	RETURN
+END SUBROUTINE DAXPY
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+SUBROUTINE  DSCAL( N, SA, SX, INCX )
+
+!         CALCULATE  X = A*X  (X = VECTOR, A = SCALAR)
+
+!  --INPUT--  N  NUMBER OF ELEMENTS IN VECTOR
+!            SA  SINGLE PRECISION SCALE FACTOR
+!            SX  SING-PREC ARRAY, LENGTH 1+(N-1)*INCX, CONTAINING VECTOR
+!          INCX  SPACING OF VECTOR ELEMENTS IN 'SX'
+
+! --OUTPUT-- SX  REPLACE  SX(1+I*INCX)  WITH  SA * SX(1+I*INCX) 
+!                FOR I = 0 TO N-1
+
+	REAL SA, SX(*)
+
+
+	IF( N.LE.0 ) RETURN
+
+	IF( INCX.NE.1 ) THEN
+
+	    DO 10  I = 1, 1+(N-1)*INCX, INCX
+	       SX(I) = SA * SX(I)
+   10     CONTINUE
+
+	ELSE
+
+	   M = MOD(N,5)
+	   IF( M.NE.0 ) THEN
+!                           ** CLEAN-UP LOOP SO REMAINING VECTOR LENGTH
+!                           ** IS A MULTIPLE OF 5.
+	      DO 30  I = 1, M
+	         SX(I) = SA * SX(I)
+   30       CONTINUE
+	   ENDIF
+!                             ** UNROLL LOOP FOR SPEED
+	   DO 50  I = M+1, N, 5
+	      SX(I)   = SA * SX(I)
+	      SX(I+1) = SA * SX(I+1)
+	      SX(I+2) = SA * SX(I+2)
+	      SX(I+3) = SA * SX(I+3)
+	      SX(I+4) = SA * SX(I+4)
+   50    CONTINUE
+
+	ENDIF
+
+	RETURN
+END SUBROUTINE  DSCAL
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+FUNCTION  DDOT( N, SX, INCX, SY, INCY )
+!     ##############################
+
+!          S.P. DOT PRODUCT OF VECTORS  'X'  AND  'Y'
+
+!  --INPUT--
+!        N  NUMBER OF ELEMENTS IN INPUT VECTORS 'X' AND 'Y'
+!       SX  SING-PREC ARRAY CONTAINING VECTOR 'X'
+!     INCX  SPACING OF ELEMENTS OF VECTOR 'X' IN 'SX'
+!       SY  SING-PREC ARRAY CONTAINING VECTOR 'Y'
+!     INCY  SPACING OF ELEMENTS OF VECTOR 'Y' IN 'SY'
+
+! --OUTPUT--
+!     DDOT   SUM FOR I = 0 TO N-1 OF  SX(LX+I*INCX) * SY(LY+I*INCY),
+!            WHERE  LX = 1          IF INCX .GE. 0, 
+!                      = (-INCX)*N  IF INCX .LT. 0,
+!            AND LY IS DEFINED IN A SIMILAR WAY USING INCY.
+
+        IMPLICIT NONE
+        INTEGER N,INCX,INCY
+	REAL SX(*), SY(*)
+        REAL DDOT
+        INTEGER I,M, IX, IY
+
+
+	DDOT = 0.0
+	IF( N.LE.0 )  RETURN
+
+	IF ( INCX.EQ.INCY .AND. INCX.GT.1 )  THEN
+
+	    DO 10  I = 1, 1+(N-1)*INCX, INCX
+	       DDOT = DDOT + SX(I) * SY(I)
+   10     CONTINUE
+
+	ELSE IF ( INCX.EQ.INCY .AND. INCX.EQ.1 )  THEN
+
+!                                        ** EQUAL, UNIT INCREMENTS
+	   M = MOD(N,5)
+	   IF( M .NE. 0 ) THEN
+!                            ** CLEAN-UP LOOP SO REMAINING VECTOR LENGTH
+!                            ** IS A MULTIPLE OF 4.
+	      DO 20  I = 1, M
+	         DDOT = DDOT + SX(I) * SY(I)
+   20       CONTINUE
+	   ENDIF
+!                              ** UNROLL LOOP FOR SPEED
+	   DO 30  I = M+1, N, 5
+	      DDOT = DDOT + SX(I)*SY(I)     + SX(I+1)*SY(I+1) &
+                          + SX(I+2)*SY(I+2) + SX(I+3)*SY(I+3) &
+                          + SX(I+4)*SY(I+4)
+   30    CONTINUE
+
+	ELSE
+!               ** NONEQUAL OR NONPOSITIVE INCREMENTS.
+	   IX = 1
+	   IY = 1
+	   IF( INCX.LT.0 )  IX = 1 + (N-1)*(-INCX)
+	   IF( INCY.LT.0 )  IY = 1 + (N-1)*(-INCY)
+	   DO 40  I = 1, N
+	      DDOT = DDOT + SX(IX) * SY(IY)
+	      IX = IX + INCX
+	      IY = IY + INCY
+   40    CONTINUE
+
+	ENDIF
+
+	RETURN
+END FUNCTION  DDOT
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/discretisation.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/discretisation.f90
new file mode 100644
index 0000000000000000000000000000000000000000..70d9063b2494dce63cf65cb43ce68cd9a379199b
--- /dev/null
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/discretisation.f90
@@ -0,0 +1,2068 @@
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+!
+!  This file is part of the TensorProductMultigrid code.
+!  
+!  (c) The copyright relating to this work is owned jointly by the
+!  Crown, Met Office and NERC [2014]. However, it has been created
+!  with the help of the GungHo Consortium, whose members are identified
+!  at https://puma.nerc.ac.uk/trac/GungHo/wiki .
+!  
+!  Main Developer: Eike Mueller
+!  
+!  TensorProductMultigrid is free software: you can redistribute it and/or
+!  modify it under the terms of the GNU Lesser General Public License as
+!  published by the Free Software Foundation, either version 3 of the
+!  License, or (at your option) any later version.
+!  
+!  TensorProductMultigrid is distributed in the hope that it will be useful,
+!  but WITHOUT ANY WARRANTY; without even the implied warranty of
+!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+!  GNU Lesser General Public License for more details.
+!  
+!  You should have received a copy of the GNU Lesser General Public License
+!  along with TensorProductMultigrid (see files COPYING and COPYING.LESSER).
+!  If not, see <http://www.gnu.org/licenses/>.
+!
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+
+
+!==================================================================
+!
+!  Discretisation module of the model problem
+!
+!
+!  -omega2 * (d^2/dx^2 + d^2/dy^2 + lambda2 * d^2/dz^2 ) u
+!                                                + delta u = RHS
+!  [Cartesian]
+!
+!  or
+!
+!  -omega2 * (laplace_{2d} + lambda2/r^2 d/dr (r^2 d/dr)) u
+!                                                + delta u = RHS
+!  [Spherical]
+!
+!  We use a cell centered finite volume discretisation with
+!  The equation is discretised either in a unit cube or on 1/6th
+!  of a cubed sphere grid.
+!
+!  The vertical grid spacing is not necessarily uniform and can
+!  be chosen by specifying the vertical grid in a vector.
+!
+!  The following boundary conditions are used:
+!
+!  * Dirichlet in the horizontal
+!  * Neumann in the vertical
+!
+!  For delta = 0 the operator reduces to the Poisson operator.
+!
+!    Eike Mueller, University of Bath, Feb 2012
+!
+!==================================================================
+
+module discretisation
+
+  use parameters
+  use messages
+  use datatypes
+  use communication
+#ifndef MNH
+  use mpi
+#else
+  use modd_mpif
+#endif 
+
+  implicit none
+
+private
+
+  type model_parameters
+    real(kind=rl) :: omega2   ! omega^2
+    real(kind=rl) :: lambda2  ! lambda^2
+    real(kind=rl) :: delta    ! delta
+  end type model_parameters
+
+! --- Stencil ---
+!
+
+! Grid traversal direction in SOR
+  integer, parameter :: DIRECTION_FORWARD = 1
+  integer, parameter :: DIRECTION_BACKWARD = 2
+
+! Ordering in SOR
+  ! Lexicographic ordering
+  integer, parameter :: ORDERING_LEX = 1
+  ! Red-black ordering
+  integer, parameter :: ORDERING_RB = 2
+
+  type smoother_parameters
+    ! smoother
+    integer :: smoother
+    ! relaxation parameter
+    real(kind=rl) :: rho
+    ! ordering of degrees of freedom
+    integer :: ordering
+  end type smoother_parameters
+
+  ! Allowed smoothers
+  integer, parameter :: SMOOTHER_LINE_SOR = 3
+  integer, parameter :: SMOOTHER_LINE_SSOR = 4
+  integer, parameter :: SMOOTHER_LINE_JAC = 6
+
+  ! Number of levels
+  integer :: nlev
+
+  ! Grid parameters
+  type(grid_parameters) :: grid_param
+
+  ! Model parameters
+  type(model_parameters) :: model_param
+
+  ! Smoother parameters
+  type(smoother_parameters) :: smoother_param
+
+  ! Arrays for measuring the residual reduction
+  real(kind=rl), allocatable :: log_resreduction(:)
+  integer, allocatable :: nsmooth_total(:)
+
+  ! Data structure for storing the vertical discretisation
+  type vertical_coefficients
+    real(kind=rl), pointer , contiguous :: a(:)
+    real(kind=rl), pointer , contiguous :: b(:)
+    real(kind=rl), pointer , contiguous :: c(:)
+    real(kind=rl), pointer , contiguous :: d(:)
+  end type vertical_coefficients
+
+  ! Stoarge for vertical coefficients
+  type(vertical_coefficients) :: vert_coeff
+
+public::discretisation_initialise_mnh
+public::discretisation_initialise
+public::discretisation_finalise
+public::smooth_mnh
+public::smooth
+public::line_SOR
+public::line_SSOR
+public::line_jacobi_mnh
+public::line_jacobi
+public::calculate_residual_mnh
+public::calculate_residual
+public::apply_mnh
+public::apply
+public::model_parameters
+public::smoother_parameters
+public::volume_of_element
+public::SMOOTHER_LINE_SOR
+public::SMOOTHER_LINE_SSOR
+public::SMOOTHER_LINE_JAC
+public::DIRECTION_FORWARD
+public::DIRECTION_BACKWARD
+public::ORDERING_LEX
+public::ORDERING_RB
+
+contains
+
+!==================================================================
+! Initialise module
+!==================================================================
+ subroutine discretisation_initialise_mnh(grid_param_in, &
+                                       model_param_in, &
+                                       smoother_param_in, &
+                                       nlev_in, &
+                                       PA_K,PB_K,PC_K,PD_K)
+    implicit none
+    type(grid_parameters), intent(in)   :: grid_param_in
+    type(model_parameters), intent(in)   :: model_param_in
+    type(smoother_parameters), intent(in)   :: smoother_param_in
+    integer, intent(in) :: nlev_in
+    real(kind=rl) , optional , intent (in) :: PA_K(:),PB_K(:),PC_K(:),PD_K(:)
+
+    ! local var
+    integer :: k
+
+    grid_param = grid_param_in
+    model_param = model_param_in
+    smoother_param = smoother_param_in
+    nlev = nlev_in
+    allocate(log_resreduction(nlev))
+    allocate(nsmooth_total(nlev))
+    log_resreduction(:) = 0.0_rl
+    nsmooth_total(:) = 0
+    allocate(r_grid(grid_param%nz+1))
+    if (grid_param%graded) then
+      do k=1,grid_param%nz+1
+        r_grid(k) = grid_param%H*(1.0_rl*(k-1.0_rl)/grid_param%nz)**2
+      end do
+    else
+      do k=1,grid_param%nz+1
+        r_grid(k) = grid_param%H*(1.0_rl*(k-1.0_rl)/grid_param%nz)
+      end do
+    end if
+    ! Allocate arrays for vertical discretisation matrices
+    ! and calculate matrix entries
+    allocate(vert_coeff%a(grid_param%nz))
+    allocate(vert_coeff%b(grid_param%nz))
+    allocate(vert_coeff%c(grid_param%nz))
+    allocate(vert_coeff%d(grid_param%nz))
+    call construct_vertical_coeff_mnh(PA_K,PB_K,PC_K,PD_K)
+  end subroutine discretisation_initialise_mnh
+
+  subroutine discretisation_initialise(grid_param_in, &
+                                       model_param_in, &
+                                       smoother_param_in, &
+                                       nlev_in)
+    implicit none
+    type(grid_parameters), intent(in)   :: grid_param_in
+    type(model_parameters), intent(in)   :: model_param_in
+    type(smoother_parameters), intent(in)   :: smoother_param_in
+    integer, intent(in) :: nlev_in
+    integer :: k
+    grid_param = grid_param_in
+    model_param = model_param_in
+    smoother_param = smoother_param_in
+    nlev = nlev_in
+    allocate(log_resreduction(nlev))
+    allocate(nsmooth_total(nlev))
+    log_resreduction(:) = 0.0_rl
+    nsmooth_total(:) = 0
+    allocate(r_grid(grid_param%nz+1))
+    if (grid_param%graded) then
+      do k=1,grid_param%nz+1
+        r_grid(k) = grid_param%H*(1.0_rl*(k-1.0_rl)/grid_param%nz)**2
+      end do
+    else
+      do k=1,grid_param%nz+1
+        r_grid(k) = grid_param%H*(1.0_rl*(k-1.0_rl)/grid_param%nz)
+      end do
+    end if
+#ifdef CARTESIANGEOMETRY
+#else
+    r_grid(:) = 1.0_rl + r_grid(:)
+#endif
+    ! Allocate arrays for vertical discretisation matrices
+    ! and calculate matrix entries
+    allocate(vert_coeff%a(grid_param%nz))
+    allocate(vert_coeff%b(grid_param%nz))
+    allocate(vert_coeff%c(grid_param%nz))
+    allocate(vert_coeff%d(grid_param%nz))
+    call construct_vertical_coeff()
+  end subroutine discretisation_initialise
+
+!==================================================================
+! Finalise module
+!==================================================================
+  subroutine discretisation_finalise()
+    implicit none
+    integer :: level
+    real(kind=rl) :: rho_avg
+#ifdef MEASURESMOOTHINGRATE
+    if (i_am_master_mpi) then
+      write(STDOUT,'("Average smoothing rates:")')
+      do level=nlev,1,-1
+        if (nsmooth_total(level) > 0) then
+          rho_avg = exp(log_resreduction(level)/nsmooth_total(level))
+        else
+          rho_avg = 1.0_rl
+        end if
+        write(STDOUT,'("rho_{avg}(",I3,") = ",E10.4," ( ",I5," x )")') &
+          level, rho_avg, nsmooth_total(level)
+      end do
+    end if
+#endif
+    deallocate(log_resreduction)
+    deallocate(nsmooth_total)
+    deallocate(r_grid)
+    ! Deallocate storage for vertical discretisation matrices
+    deallocate(vert_coeff%a)
+    deallocate(vert_coeff%b)
+    deallocate(vert_coeff%c)
+    deallocate(vert_coeff%d)
+  end subroutine discretisation_finalise
+
+!==================================================================
+! Construct alpha_{i',j'} and |T_{ij}| needed for the
+! horizontal stencil
+! ( alpha_{i+1,j},
+!   alpha_{i-1,j},
+!   alpha_{i,j+1},
+!   alpha_{i,j-1},
+!   alpha_{ij})
+! (ix,iy) are LOCAL indices of the grid boxes, which are
+! converted to global indices
+!==================================================================
+  subroutine construct_alpha_T_mnh(grid_param,ix,iy,alpha_T,Tij)
+    implicit none
+    type(grid_parameters), intent(in) :: grid_param
+    integer, intent(in) :: ix
+    integer, intent(in) :: iy
+    real(kind=rl), intent(inout), dimension(5) :: alpha_T
+    real(kind=rl), intent(out) :: Tij
+
+    !local var
+    real(kind=rl)              :: h, rho_i, sigma_j
+    real(kind=rl)              :: xcoef 
+    logical                    :: l2nd       
+
+    h = grid_param%L/grid_param%n
+    ! Cartesian coefficients
+    Tij = h**2
+    ! optimisation for newman MNH case = all coef constant
+    alpha_T(1:4) = 1.0_rl
+    alpha_T(5) = 4.0_rl
+    return
+    xcoef = 0.5_rl ! 0.0
+    l2nd = .false. ! .true. ! .false.
+    alpha_T(1) = 1.0
+    alpha_T(2) = 1.0
+    if (ix == grid_param%n) then
+      alpha_T(1) = xcoef * 2.0_rl
+      if (l2nd) alpha_T(2) = 2.0_rl
+    end if
+    if (ix == 1) then
+      alpha_T(2) = xcoef * 2.0_rl
+      if (l2nd) alpha_T(1) = 2.0_rl
+    end if
+    alpha_T(3) = 1.0
+    alpha_T(4) = 1.0
+    if (iy == grid_param%n) then
+      alpha_T(3) = xcoef * 2.0_rl
+      if (l2nd) alpha_T(4) = 2.0
+    end if
+    if (iy == 1) then
+      alpha_T(4) = xcoef * 2.0_rl
+      if (l2nd) alpha_T(3) = 2.0
+    end if
+
+    alpha_T(5) = alpha_T(1) + alpha_T(2) + alpha_T(3) + alpha_T(4)
+  end subroutine construct_alpha_T_mnh
+! constant coef for MNH
+  subroutine construct_alpha_T_cst_mnh(grid_param,alpha_T,Tij)
+    implicit none
+    type(grid_parameters), intent(in) :: grid_param
+    real(kind=rl), intent(inout), dimension(5) :: alpha_T
+    real(kind=rl), intent(out) :: Tij
+
+    !local var
+    real(kind=rl)              :: h
+
+    h = grid_param%L/grid_param%n
+    ! Cartesian coefficients
+    Tij = h**2
+    ! optimisation for newman MNH case = all coef constant
+    alpha_T(1:4) = 1.0_rl
+    alpha_T(5) = 4.0_rl
+ 
+  end subroutine construct_alpha_T_cst_mnh
+!==================================================================
+  subroutine construct_alpha_T(grid_param,ix,iy,alpha_T,Tij)
+    implicit none
+    type(grid_parameters), intent(in) :: grid_param
+    integer, intent(in) :: ix
+    integer, intent(in) :: iy
+    real(kind=rl), intent(inout), dimension(5) :: alpha_T
+    real(kind=rl), intent(out) :: Tij
+    real(kind=rl)              :: h, rho_i, sigma_j
+#ifdef CARTESIANGEOMETRY
+    h = grid_param%L/grid_param%n
+    ! Cartesian coefficients
+    Tij = h**2
+    if (ix == grid_param%n) then
+      alpha_T(1) = 2.0_rl  
+    else
+      alpha_T(1) = 1.0_rl
+    end if
+    if (ix == 1) then
+      alpha_T(2) = 2.0_rl  
+    else
+      alpha_T(2) = 1.0_rl
+    end if
+    if (iy == grid_param%n) then
+      alpha_T(3) = 2.0_rl  
+    else
+      alpha_T(3) = 1.0_rl
+    end if
+    if (iy == 1) then
+      alpha_T(4) = 2.0_rl  
+    else
+      alpha_T(4) = 1.0_rl
+    end if
+#else
+    ! Coefficients in cubed sphere geometry
+    ! (rho_i,sigma_j) \in [-1,1] x [-1,1] are the coordinates of the
+    ! cubed sphere segment
+    h = 2.0_rl/grid_param%n
+    Tij = volume_of_element(ix,iy,grid_param)
+    rho_i = 2.0_rl*(1.0_rl*ix-0.5_rl)/grid_param%n-1.0_rl
+    sigma_j = 2.0_rl*(1.0_rl*iy-0.5_rl)/grid_param%n-1.0_rl
+    ! alpha_{i+1,j}
+    if (ix == grid_param%n) then
+      alpha_T(1) = 2.0_rl*DSQRT((1.0_rl+(rho_i+0.25_rl*h)**2)/(1.0_rl+sigma_j**2))
+    else
+      alpha_T(1) = DSQRT((1.0_rl+(rho_i+0.5_rl*h)**2)/(1.0_rl+sigma_j**2))
+    end if
+    ! alpha_{i-1,j}
+    if (ix == 1) then
+      alpha_T(2) = 2.0_rl*DSQRT((1.0_rl+(rho_i-0.25_rl*h)**2)/(1.0_rl+sigma_j**2))
+    else
+      alpha_T(2) = DSQRT((1.0_rl+(rho_i-0.5_rl*h)**2)/(1.0_rl+sigma_j**2))
+    end if
+    ! alpha_{i,j+1}
+    if (iy == grid_param%n) then
+      alpha_T(3) = 2.0_rl*DSQRT((1.0_rl+(sigma_j+0.25_rl*h)**2)/(1.0_rl+rho_i**2))
+    else
+      alpha_T(3) = DSQRT((1.0_rl+(sigma_j+0.5_rl*h)**2)/(1.0_rl+rho_i**2))
+    end if
+    ! alpha_{i,j-1}
+    if (iy == 1) then
+      alpha_T(4) = 2.0_rl*DSQRT((1.0_rl+(sigma_j-0.25_rl*h)**2)/(1.0_rl+rho_i**2))
+    else
+      alpha_T(4) = DSQRT((1.0_rl+(sigma_j-0.5_rl*h)**2)/(1.0_rl+rho_i**2))
+    end if
+#endif
+    alpha_T(5) = alpha_T(1) + alpha_T(2) + alpha_T(3) + alpha_T(4)
+  end subroutine construct_alpha_T
+!==================================================================
+! Construct coefficients of tridiagonal matrix A_T
+! describing the coupling in the vertical direction and the
+! diagonal matrix diag(d)
+!==================================================================
+subroutine construct_vertical_coeff_mnh(PA_K,PB_K,PC_K,PD_K)
+  implicit none
+  real(kind=rl) , optional , intent (in) :: PA_K(:),PB_K(:),PC_K(:),PD_K(:)
+  !local var
+  real(kind=rl) :: a_k_tmp, b_k_tmp, c_k_tmp, d_k_tmp
+  real(kind=rl) :: omega2, lambda2, delta, vol_r, surface_k, surface_kp1
+  integer :: k
+  
+  IF (.NOT. PRESENT(PA_K)) THEN
+  omega2 = model_param%omega2
+  lambda2 = model_param%lambda2
+  delta = model_param%delta
+  do k = 1, grid_param%nz
+
+    vol_r = r_grid(k+1)-r_grid(k)
+    surface_k = 1.0_rl
+    surface_kp1 = 1.0_rl
+
+    ! Diagonal element
+    a_k_tmp = delta*vol_r
+    ! off diagonal elements
+    ! Boundary conditions
+    ! Top
+    if (k == grid_param%nz) then
+      if (grid_param%vertbc == VERTBC_DIRICHLET) then
+        b_k_tmp = - 2.0_rl * omega2*lambda2 &
+                           * surface_kp1/(r_grid(k+1)-r_grid(k))
+      else
+        b_k_tmp = 0.0_rl
+      end if
+    else
+      b_k_tmp = - 2.0_rl*omega2*lambda2 &
+              * surface_kp1/(r_grid(k+2)-r_grid(k))
+    end if
+    ! Bottom
+    if (k == 1) then
+      if (grid_param%vertbc == VERTBC_DIRICHLET) then
+        c_k_tmp = - 2.0_rl * omega2*lambda2 &
+                           * surface_k/(r_grid(k+1)-r_grid(k))
+      else
+        c_k_tmp = 0.0_rl
+      end if
+    else
+      c_k_tmp = - 2.0_rl * omega2 * lambda2 &
+              * surface_k/(r_grid(k+1)-r_grid(k-1))
+    end if
+    ! Diagonal matrix d_k
+    d_k_tmp = - omega2 * (r_grid(k+1)-r_grid(k))
+    vert_coeff%a(k) = a_k_tmp/d_k_tmp
+    vert_coeff%b(k) = b_k_tmp/d_k_tmp
+    vert_coeff%c(k) = c_k_tmp/d_k_tmp
+    vert_coeff%d(k) = d_k_tmp
+  end do
+  ELSE
+  do k = 1, grid_param%nz
+    vert_coeff%a(k) = PA_K(k)
+    vert_coeff%b(k) = PB_K(k)
+    vert_coeff%c(k) = PC_K(k)
+    vert_coeff%d(k) = PD_K(k)
+  end do
+  ENDIF
+end subroutine construct_vertical_coeff_mnh
+
+subroutine construct_vertical_coeff()
+  implicit none
+  real(kind=rl) :: a_k_tmp, b_k_tmp, c_k_tmp, d_k_tmp
+  real(kind=rl) :: omega2, lambda2, delta, vol_r, surface_k, surface_kp1
+  integer :: k
+  omega2 = model_param%omega2
+  lambda2 = model_param%lambda2
+  delta = model_param%delta
+  do k = 1, grid_param%nz
+#ifdef  CARTESIANGEOMETRY
+    vol_r = r_grid(k+1)-r_grid(k)
+    surface_k = 1.0_rl
+    surface_kp1 = 1.0_rl
+#else
+    vol_r = (r_grid(k+1)**3 - r_grid(k)**3)/3.0_rl
+    surface_k = r_grid(k)**2
+    surface_kp1 = r_grid(k+1)**2
+#endif
+    ! Diagonal element
+    a_k_tmp = delta*vol_r
+    ! off diagonal elements
+    ! Boundary conditions
+    ! Top
+    if (k == grid_param%nz) then
+      if (grid_param%vertbc == VERTBC_DIRICHLET) then
+        b_k_tmp = - 2.0_rl * omega2*lambda2 &
+                           * surface_kp1/(r_grid(k+1)-r_grid(k))
+      else
+        b_k_tmp = 0.0_rl
+      end if
+    else
+      b_k_tmp = - 2.0_rl*omega2*lambda2 &
+              * surface_kp1/(r_grid(k+2)-r_grid(k))
+    end if
+    ! Bottom
+    if (k == 1) then
+      if (grid_param%vertbc == VERTBC_DIRICHLET) then
+        c_k_tmp = - 2.0_rl * omega2*lambda2 &
+                           * surface_k/(r_grid(k+1)-r_grid(k))
+      else
+        c_k_tmp = 0.0_rl
+      end if
+    else
+      c_k_tmp = - 2.0_rl * omega2 * lambda2 &
+              * surface_k/(r_grid(k+1)-r_grid(k-1))
+    end if
+    ! Diagonal matrix d_k
+    d_k_tmp = - omega2 * (r_grid(k+1)-r_grid(k))
+    vert_coeff%a(k) = a_k_tmp/d_k_tmp
+    vert_coeff%b(k) = b_k_tmp/d_k_tmp
+    vert_coeff%c(k) = c_k_tmp/d_k_tmp
+    vert_coeff%d(k) = d_k_tmp
+  end do
+end subroutine construct_vertical_coeff
+
+!==================================================================
+! Calculate local residual r = b - A.u
+!==================================================================
+  subroutine calculate_residual_mnh(level,m,b,u,r)
+    implicit none
+    integer, intent(in)                :: level
+    integer, intent(in)                :: m
+    type(scalar3d), intent(in)         :: b
+    type(scalar3d), intent(inout)      :: u
+    type(scalar3d), intent(inout)      :: r
+    integer :: ix,iy,iz
+    integer ::  iib,iie,ijb,ije,ikb,ike
+
+    real , dimension(:,:,:) , pointer , contiguous :: zr_st , zb_st
+
+    ! r <- A.u
+    !call boundary_mnh(u)
+    call apply_mnh(u,r)
+    ! r <- b - r = b - A.u
+    if (LUseO) then
+       do ix=u%icompx_min,u%icompx_max
+          do iy=u%icompy_min,u%icompy_max
+             do iz=1,u%grid_param%nz
+                r%s(iz,iy,ix) = b%s(iz,iy,ix) - r%s(iz,iy,ix)
+             end do
+          end do
+       end do
+    endif
+    if (LUseT) then
+!!$       do iz=1,u%grid_param%nz
+!!$          do iy=u%icompy_min,u%icompy_max
+!!$             do ix=u%icompx_min,u%icompx_max
+!!$                r%st(ix,iy,iz) = b%st(ix,iy,iz) - r%st(ix,iy,iz)
+!!$             end do
+!!$          end do
+!!$       end do
+       !-----------------
+       iib=u%icompx_min
+       iie=u%icompx_max
+       ijb=u%icompy_min
+       ije=u%icompy_max
+       ikb=1
+       ike=u%grid_param%nz
+
+       zr_st => r%st
+       zb_st => b%st
+       !$acc kernels
+       zr_st(iib:iie,ijb:ije,ikb:ike) = zb_st(iib:iie,ijb:ije,ikb:ike) - zr_st(iib:iie,ijb:ije,ikb:ike)
+       !$acc end kernels
+    endif
+
+  end subroutine calculate_residual_mnh
+
+  subroutine calculate_residual(level,m,b,u,r)
+    implicit none
+    integer, intent(in)                :: level
+    integer, intent(in)                :: m
+    type(scalar3d), intent(in)         :: b
+    type(scalar3d), intent(inout)      :: u
+    type(scalar3d), intent(inout)      :: r
+    integer :: ix,iy,iz
+
+
+    ! r <- A.u
+    call apply(u,r)
+    ! r <- b - r = b - A.u
+    do ix=u%icompx_min,u%icompx_max
+      do iy=u%icompy_min,u%icompy_max
+        do iz=1,u%grid_param%nz
+          r%s(iz,iy,ix) = b%s(iz,iy,ix) - r%s(iz,iy,ix)
+        end do
+      end do
+    end do
+  end subroutine calculate_residual
+
+!==================================================================
+! Apply operator v = A.u
+!==================================================================
+  subroutine apply_mnh(u,v)
+    implicit none
+    type(scalar3d), intent(inout)      :: u
+    type(scalar3d), intent(inout)      :: v
+
+    ! local var
+    real(kind=rl), dimension(5) :: alpha_T
+    real(kind=rl) :: Tij
+    real(kind=rl) :: a_k, b_k, c_k, d_k
+    integer :: ix,iy,iz
+    real(kind=rl) :: tmp
+    integer :: iib,iie,ijb,ije
+
+    real(kind=rl), dimension(:,:,:) , pointer , contiguous :: zv_st , zu_st  
+    real(kind=rl), dimension(:)     , pointer , contiguous :: za_k, zb_k, zc_k, zd_k
+    integer :: ii,ij
+    integer :: ize
+
+    call boundary_mnh(u)
+
+    if (LUseO) then     
+       do ix=u%icompx_min,u%icompx_max
+          do iy=u%icompy_min,u%icompy_max
+             ! Construct horizontal part of stencil
+             call construct_alpha_T_mnh(u%grid_param,  &
+                  ix+u%ix_min-1, &
+                  iy+u%iy_min-1, &
+                  alpha_T,Tij)
+             do iz=1,u%grid_param%nz
+                a_k = vert_coeff%a(iz)
+                b_k = vert_coeff%b(iz)
+                c_k = vert_coeff%c(iz)
+                d_k = vert_coeff%d(iz)
+                tmp = ((a_k-b_k-c_k)*Tij ) * u%s(iz,iy,ix)
+                if (iz < grid_param%nz) then
+                   tmp = tmp + b_k*Tij * u%s(iz+1,iy,ix)
+                end if
+                if (iz > 1) then
+                   tmp = tmp + c_k*Tij * u%s(iz-1,iy,ix)
+                end if
+                if ((iz > 1) .and. (iz < grid_param%nz)) then
+                   tmp = tmp - alpha_T(5) * u%s(iz,  iy  ,ix  ) &
+                        + alpha_T(1) * u%s(iz,  iy  ,ix+1) &
+                        + alpha_T(2) * u%s(iz,  iy  ,ix-1) &
+                        + alpha_T(3) * u%s(iz,  iy+1,ix  ) &
+                        + alpha_T(4) * u%s(iz,  iy-1,ix  )
+                end if
+                v%s(iz,iy,ix) = d_k*tmp 
+             end do
+          end do
+       end do
+    endif
+    if (LUseT) then 
+       call construct_alpha_T_cst_mnh(u%grid_param,alpha_T,Tij)    
+       !-----------------------------------------------------------
+       iib=u%icompx_min
+       iie=u%icompx_max
+       ijb=u%icompy_min
+       ije=u%icompy_max
+       ize=u%grid_param%nz
+       !
+       zv_st => v%st
+       zu_st => u%st
+       zb_k => vert_coeff%b
+       zc_k => vert_coeff%c
+       zd_k => vert_coeff%d
+    
+       !$acc kernels 
+       iz=1
+       !$acc loop independent  collapse(2)
+       do ij=ijb,ije
+          do ii=iib,iie
+             zv_st(ii,ij,iz)   = zd_k(iz)* ( (-zb_k(iz)-zc_k(iz))*Tij * zu_st(ii,ij,iz  )  &
+                                              +zb_k(iz)          *Tij * zu_st(ii,ij,iz+1)  )
+          end do
+       end do
+       !
+       do iz=2,ize-1
+          !$acc loop independent  collapse(2)
+          do ij=ijb,ije
+             do ii=iib,iie
+                zv_st(ii,ij,iz) = zd_k(iz)* ( ((-zb_k(iz)-zc_k(iz))*Tij - 4.0_rl ) * zu_st(ii,ij,iz)    &
+                                                +zb_k(iz)          *Tij            * zu_st(ii,ij,iz+1)  &
+                                                         +zc_k(iz) *Tij            * zu_st(ii,ij,iz-1)  &
+                                           +                                         zu_st(ii+1,ij,iz) &
+                                           +                                         zu_st(ii-1,ij,iz) &
+                                           +                                         zu_st(ii,ij+1,iz) &
+                                           +                                         zu_st(ii,ij-1,iz) &
+                                       )
+             end do
+          end do
+       end do
+       !
+       iz=ize
+       !$acc loop independent  collapse(2)
+       do ij=ijb,ije
+          do ii=iib,iie
+             zv_st(ii,ij,iz) = zd_k(iz)*  (  (-zb_k(iz)-zc_k(iz))*Tij  * zu_st(ii,ij,iz)    &
+                                                       +zc_k(iz) *Tij  * zu_st(ii,ij,iz-1)  )
+          end do
+       end do
+
+       !$acc end kernels
+    endif
+    
+  end subroutine apply_mnh
+
+  subroutine apply(u,v)
+    implicit none
+    type(scalar3d), intent(in)         :: u
+    type(scalar3d), intent(inout)      :: v
+    real(kind=rl), dimension(5) :: alpha_T
+    real(kind=rl) :: Tij
+    real(kind=rl) :: a_k, b_k, c_k, d_k
+    integer :: ix,iy,iz
+    real(kind=rl) :: tmp
+
+    do ix=u%icompx_min,u%icompx_max
+      do iy=u%icompy_min,u%icompy_max
+        ! Construct horizontal part of stencil
+        call construct_alpha_T(u%grid_param,  &
+                               ix+u%ix_min-1, &
+                               iy+u%iy_min-1, &
+                               alpha_T,Tij)
+        do iz=1,u%grid_param%nz
+          a_k = vert_coeff%a(iz)
+          b_k = vert_coeff%b(iz)
+          c_k = vert_coeff%c(iz)
+          d_k = vert_coeff%d(iz)
+          tmp = ((a_k-b_k-c_k)*Tij - alpha_T(5)) * u%s(iz,iy,ix)
+          if (iz < grid_param%nz) then
+            tmp = tmp + b_k*Tij * u%s(iz+1,iy,ix)
+          end if
+          if (iz > 1) then
+            tmp = tmp + c_k*Tij * u%s(iz-1,iy,ix)
+          end if
+          tmp = tmp + alpha_T(1) * u%s(iz,  iy  ,ix+1) &
+                    + alpha_T(2) * u%s(iz,  iy  ,ix-1) &
+                    + alpha_T(3) * u%s(iz,  iy+1,ix  ) &
+                    + alpha_T(4) * u%s(iz,  iy-1,ix  )
+          v%s(iz,iy,ix) = d_k*tmp
+        end do
+      end do
+    end do
+  end subroutine apply
+!==================================================================
+!==================================================================
+!
+!     S M O O T H E R S
+!
+!==================================================================
+!==================================================================
+
+!==================================================================
+! Perform nsmooth smoother iterations
+!==================================================================
+  subroutine smooth_mnh(level,m,nsmooth,direction,b,u)
+    implicit none
+    integer, intent(in) :: level
+    integer, intent(in) :: m
+    integer, intent(in) :: nsmooth       ! Number of smoothing steps
+    integer, intent(in) :: direction     ! Direction
+    type(scalar3d), intent(inout) :: b   ! RHS
+    type(scalar3d), intent(inout) :: u   ! solution vector
+    integer :: i
+    real(kind=rl) :: log_res_initial, log_res_final
+    type(scalar3d) :: r
+    integer :: halo_size
+    integer :: nlocal, nz
+
+#ifdef MEASURESMOOTHINGRATE
+    r%ix_min = u%ix_min
+    r%ix_max = u%ix_max
+    r%iy_min = u%iy_min
+    r%iy_max = u%iy_max
+    r%icompx_min = u%icompx_min
+    r%icompx_max = u%icompx_max
+    r%icompy_min = u%icompy_min
+    r%icompy_max = u%icompy_max
+    r%halo_size = u%halo_size
+    r%isactive = u%isactive
+    r%grid_param = u%grid_param
+    nlocal = r%ix_max-r%ix_min+1
+    halo_size = r%halo_size
+    nz = r%grid_param%nz
+
+    if (LUseO) then
+       allocate(r%s(0:nz+1,                       &
+                    1-halo_size:nlocal+halo_size, &
+                    1-halo_size:nlocal+halo_size))
+    end if
+
+    if (LUseT) then
+       allocate(r%st(1-halo_size:nlocal+halo_size, &
+                     1-halo_size:nlocal+halo_size, &
+                     0:nz+1))
+    end if
+
+    call calculate_residual(level,m,b,u,r)
+    log_res_initial = log(l2norm(r))
+#endif
+    ! Carry out nsmooth iterations of the smoother
+    if (smoother_param%smoother == SMOOTHER_LINE_SOR) then
+      do i=1,nsmooth
+        call line_SOR_mnh(level,m,direction,b,u)
+      end do
+    else if (smoother_param%smoother == SMOOTHER_LINE_SSOR) then
+      do i=1,nsmooth
+        call line_SSOR_mnh(level,m,direction,b,u)
+      end do
+    else if (smoother_param%smoother == SMOOTHER_LINE_JAC) then
+      do i=1,nsmooth
+        call line_jacobi_mnh(level,m,b,u)
+      end do
+    end if
+#ifdef MEASURESMOOTHINGRATE
+    call calculate_residual_mnh(level,m,b,u,r)
+    log_res_final = log(l2norm(r))
+    log_resreduction(level) = log_resreduction(level) &
+                            + (log_res_final - log_res_initial)
+    nsmooth_total(level) = nsmooth_total(level) + nsmooth
+    if (LUseO) deallocate(r%s)
+    if (LUseT) deallocate(r%st)
+#endif
+  end subroutine smooth_mnh
+!==================================================================
+! Perform nsmooth smoother iterations
+!==================================================================
+  subroutine smooth(level,m,nsmooth,direction,b,u)
+    implicit none
+    integer, intent(in) :: level
+    integer, intent(in) :: m
+    integer, intent(in) :: nsmooth       ! Number of smoothing steps
+    integer, intent(in) :: direction     ! Direction
+    type(scalar3d), intent(inout) :: b   ! RHS
+    type(scalar3d), intent(inout) :: u   ! solution vector
+    integer :: i
+    real(kind=rl) :: log_res_initial, log_res_final
+    type(scalar3d) :: r
+    integer :: halo_size
+    integer :: nlocal, nz
+
+#ifdef MEASURESMOOTHINGRATE
+    r%ix_min = u%ix_min
+    r%ix_max = u%ix_max
+    r%iy_min = u%iy_min
+    r%iy_max = u%iy_max
+    r%icompx_min = u%icompx_min
+    r%icompx_max = u%icompx_max
+    r%icompy_min = u%icompy_min
+    r%icompy_max = u%icompy_max
+    r%halo_size = u%halo_size
+    r%isactive = u%isactive
+    r%grid_param = u%grid_param
+    nlocal = r%ix_max-r%ix_min+1
+    halo_size = r%halo_size
+    nz = r%grid_param%nz
+    if (LUseO) then
+    allocate(r%s(0:nz+1,                       &
+                 1-halo_size:nlocal+halo_size, &
+                 1-halo_size:nlocal+halo_size))
+    call calculate_residual(level,m,b,u,r)
+    endif
+    if (LUseT) then
+    allocate(r%st(1-halo_size:nlocal+halo_size,   &
+                  1-halo_size:nlocal+halo_size,   &
+                  0:nz+1) )
+    endif
+    log_res_initial = log(l2norm(r))
+#endif
+    ! Carry out nsmooth iterations of the smoother
+    if (smoother_param%smoother == SMOOTHER_LINE_SOR) then
+      do i=1,nsmooth
+        call line_SOR(level,m,direction,b,u)
+      end do
+    else if (smoother_param%smoother == SMOOTHER_LINE_SSOR) then
+      do i=1,nsmooth
+        call line_SSOR(level,m,direction,b,u)
+      end do
+    else if (smoother_param%smoother == SMOOTHER_LINE_JAC) then
+      do i=1,nsmooth
+        call line_jacobi(level,m,b,u)
+      end do
+    end if
+#ifdef MEASURESMOOTHINGRATE
+    call calculate_residual(level,m,b,u,r)
+    log_res_final = log(l2norm(r))
+    log_resreduction(level) = log_resreduction(level) &
+                            + (log_res_final - log_res_initial)
+    nsmooth_total(level) = nsmooth_total(level) + nsmooth
+    if (LUseO) deallocate(r%s)
+    if (LUseT) deallocate(r%st)
+#endif
+  end subroutine smooth
+!==================================================================
+! SOR line smoother mnh
+!==================================================================
+  subroutine line_SOR_mnh(level,m,direction,b,u)
+
+    implicit none
+
+    integer, intent(in)                :: level
+    integer, intent(in)                :: m
+    integer, intent(in)                :: direction
+    type(scalar3d), intent(in)         :: b
+    type(scalar3d), intent(inout)      :: u
+
+    !local Var
+    real(kind=rl), allocatable :: r(:)
+    integer :: nz, nlocal
+    real(kind=rl), allocatable :: c(:), utmp(:)
+    integer :: ixmin(5), ixmax(5), dix
+    integer :: iymin(5), iymax(5), diy
+    integer :: color
+    integer :: nsweeps, isweep
+    integer :: ordering
+    real(kind=rl) :: rho
+    integer, dimension(4) :: send_requests, recv_requests
+    integer, dimension(4) :: send_requestsT, recv_requestsT
+    integer :: tmp, ierr
+    integer :: iblock
+    logical :: overlap_comms
+
+    call boundary_mnh(u)
+
+    ordering = smoother_param%ordering
+    rho = smoother_param%rho
+
+    nz = u%grid_param%nz
+
+    ! Create residual vector
+    allocate(r(nz))
+    ! Allocate memory for auxiliary vectors for Thomas algorithm
+    allocate(c(nz))
+    allocate(utmp(nz))
+    nlocal = u%ix_max-u%ix_min+1
+#ifdef OVERLAPCOMMS
+    overlap_comms = (nlocal > 2)
+#else
+    overlap_comms = .false.
+#endif
+    ! Block 1 (N)
+    ixmin(1) = 1
+    ixmax(1) = nlocal
+    iymin(1) = 1
+    iymax(1) = 1
+    ! Block 2 (S)
+    ixmin(2) = 1
+    ixmax(2) = nlocal
+    iymin(2) = nlocal
+    iymax(2) = nlocal
+    ! Block 3 (W)
+    ixmin(3) = 1
+    ixmax(3) = 1
+    iymin(3) = 2
+    iymax(3) = nlocal-1
+    ! Block 4 (E)
+    ixmin(4) = nlocal
+    ixmax(4) = nlocal
+    iymin(4) = 2
+    iymax(4) = nlocal-1
+    ! Block 5 (INTERIOR)
+    if (overlap_comms) then
+      ixmin(5) = 2
+      ixmax(5) = nlocal-1
+      iymin(5) = 2
+      iymax(5) = nlocal-1
+    else
+      ! If there are no interior cells, do not overlap
+      ! communications and calculations, just loop over interior cells
+      ixmin(5) = 1
+      ixmax(5) = nlocal
+      iymin(5) = 1
+      iymax(5) = nlocal
+    end if
+    dix = +1
+    diy = +1
+    color = 1
+    ! When iteration backwards over the grid, reverse the direction
+    if (direction == DIRECTION_BACKWARD) then
+      do iblock = 1, 5
+        tmp = ixmax(iblock)
+        ixmax(iblock) = ixmin(iblock)
+        ixmin(iblock) = tmp
+        tmp = iymax(iblock)
+        iymax(iblock) = iymin(iblock)
+        iymin(iblock) = tmp
+      end do
+      dix = -1
+      diy = -1
+      color = 0
+    end if
+    nsweeps = 1
+    if (ordering == ORDERING_LEX) then
+      nsweeps = 1
+    else if (ordering == ORDERING_RB) then
+      nsweeps = 2
+    end if
+    do isweep = 1, nsweeps
+      if (overlap_comms) then
+        ! Loop over cells next to boundary (iblock = 1,...,4)
+        do iblock = 1, 4
+          call loop_over_grid_mnh(iblock)
+        end do
+        ! Initiate halo exchange
+        call ihaloswap_mnh(level,m,u,send_requests,recv_requests,send_requestsT,recv_requestsT)
+      end if
+      ! Loop over INTERIOR cells
+      iblock = 5
+      call loop_over_grid_mnh(iblock)
+      if (overlap_comms) then
+        if (m > 0) then
+          if (LUseO) call mpi_waitall(4,recv_requests, MPI_STATUSES_IGNORE, ierr)
+          if (LUseO) call mpi_waitall(4,send_requests, MPI_STATUSES_IGNORE, ierr)
+          if (LUseT) call mpi_waitall(4,recv_requestsT, MPI_STATUSES_IGNORE, ierr)
+          if (LUseT) call mpi_waitall(4,send_requestsT, MPI_STATUSES_IGNORE, ierr)
+        end if
+      else
+        call haloswap_mnh(level,m,u)
+      end if
+      color = 1-color
+    end do
+
+    ! Free memory again
+    deallocate(r)
+    deallocate(c)
+    deallocate(utmp)
+
+    contains
+
+    !------------------------------------------------------------------
+    ! Loop over grid, for a given block
+    !------------------------------------------------------------------
+    subroutine loop_over_grid_mnh(iblock)
+      implicit none
+      integer, intent(in) :: iblock
+      integer :: ix,iy,iz
+
+      if (LUseO) then
+         do ix=ixmin(iblock),ixmax(iblock),dix
+            do iy=iymin(iblock),iymax(iblock),diy
+               if (ordering == ORDERING_RB) then
+                  if (mod((ix+u%ix_min)+(iy+u%iy_min),2) .ne. color) cycle
+               end if
+               call apply_tridiag_solve_mnh(ix,iy,r,c,b,         &
+                    u%s(1:nz,iy  ,ix+1), &
+                    u%s(1:nz,iy  ,ix-1), &
+                    u%s(1:nz,iy+1,ix  ), &
+                    u%s(1:nz,iy-1,ix  ), &
+                    utmp)
+               ! Add to field with overrelaxation-factor
+               do iz=1,nz
+                  u%s(iz,iy,ix) = (1.0_rl-rho)*u%s(iz,iy,ix) + rho*utmp(iz)
+               end do
+            end do
+         end do
+      end if
+      if (LUseT) then
+         do ix=ixmin(iblock),ixmax(iblock),dix
+            do iy=iymin(iblock),iymax(iblock),diy
+               if (ordering == ORDERING_RB) then
+                  if (mod((ix+u%ix_min)+(iy+u%iy_min),2) .ne. color) cycle
+               end if
+               call apply_tridiag_solve_mnhT(ix,iy,r,c,b,         &
+                    u%st(ix+1,iy  ,1:nz), &
+                    u%st(ix-1,iy  ,1:nz), &
+                    u%st(ix  ,iy+1,1:nz), &
+                    u%st(ix  ,iy-1,1:nz), &
+                    utmp)
+               ! Add to field with overrelaxation-factor
+               do iz=1,nz
+                  u%st(ix,iy,iz) = (1.0_rl-rho)*u%st(ix,iy,iz) + rho*utmp(iz)
+               end do
+            end do
+         end do
+      end if   
+
+    end subroutine loop_over_grid_mnh
+
+  end subroutine line_SOR_mnh
+!==================================================================
+! SOR line smoother
+!==================================================================
+  subroutine line_SOR(level,m,direction,b,u)
+
+    implicit none
+
+    integer, intent(in)                :: level
+    integer, intent(in)                :: m
+    integer, intent(in)                :: direction
+    type(scalar3d), intent(in)         :: b
+    type(scalar3d), intent(inout)      :: u
+    real(kind=rl), allocatable :: r(:)
+    integer :: nz, nlocal
+    real(kind=rl), allocatable :: c(:), utmp(:)
+    integer :: ixmin(5), ixmax(5), dix
+    integer :: iymin(5), iymax(5), diy
+    integer :: color
+    integer :: nsweeps, isweep
+    integer :: ordering
+    real(kind=rl) :: rho
+    integer, dimension(4) :: send_requests, recv_requests
+    integer :: tmp, ierr
+    integer :: iblock
+    logical :: overlap_comms
+
+    ordering = smoother_param%ordering
+    rho = smoother_param%rho
+
+    nz = u%grid_param%nz
+
+    ! Create residual vector
+    allocate(r(nz))
+    ! Allocate memory for auxiliary vectors for Thomas algorithm
+    allocate(c(nz))
+    allocate(utmp(nz))
+    nlocal = u%ix_max-u%ix_min+1
+#ifdef OVERLAPCOMMS
+    overlap_comms = (nlocal > 2)
+#else
+    overlap_comms = .false.
+#endif
+    ! Block 1 (N)
+    ixmin(1) = 1
+    ixmax(1) = nlocal
+    iymin(1) = 1
+    iymax(1) = 1
+    ! Block 2 (S)
+    ixmin(2) = 1
+    ixmax(2) = nlocal
+    iymin(2) = nlocal
+    iymax(2) = nlocal
+    ! Block 3 (W)
+    ixmin(3) = 1
+    ixmax(3) = 1
+    iymin(3) = 2
+    iymax(3) = nlocal-1
+    ! Block 4 (E)
+    ixmin(4) = nlocal
+    ixmax(4) = nlocal
+    iymin(4) = 2
+    iymax(4) = nlocal-1
+    ! Block 5 (INTERIOR)
+    if (overlap_comms) then
+      ixmin(5) = 2
+      ixmax(5) = nlocal-1
+      iymin(5) = 2
+      iymax(5) = nlocal-1
+    else
+      ! If there are no interior cells, do not overlap
+      ! communications and calculations, just loop over interior cells
+      ixmin(5) = 1
+      ixmax(5) = nlocal
+      iymin(5) = 1
+      iymax(5) = nlocal
+    end if
+    dix = +1
+    diy = +1
+    color = 1
+    ! When iteration backwards over the grid, reverse the direction
+    if (direction == DIRECTION_BACKWARD) then
+      do iblock = 1, 5
+        tmp = ixmax(iblock)
+        ixmax(iblock) = ixmin(iblock)
+        ixmin(iblock) = tmp
+        tmp = iymax(iblock)
+        iymax(iblock) = iymin(iblock)
+        iymin(iblock) = tmp
+      end do
+      dix = -1
+      diy = -1
+      color = 0
+    end if
+    nsweeps = 1
+    if (ordering == ORDERING_LEX) then
+      nsweeps = 1
+    else if (ordering == ORDERING_RB) then
+      nsweeps = 2
+    end if
+    do isweep = 1, nsweeps
+      if (overlap_comms) then
+        ! Loop over cells next to boundary (iblock = 1,...,4)
+        do iblock = 1, 4
+          call loop_over_grid(iblock)
+        end do
+        ! Initiate halo exchange
+        call ihaloswap(level,m,u,send_requests,recv_requests)
+      end if
+      ! Loop over INTERIOR cells
+      iblock = 5
+      call loop_over_grid(iblock)
+      if (overlap_comms) then
+        if (m > 0) then
+          call mpi_waitall(4,recv_requests, MPI_STATUSES_IGNORE, ierr)
+        end if
+      else
+        call haloswap(level,m,u)
+      end if
+      color = 1-color
+    end do
+
+    ! Free memory again
+    deallocate(r)
+    deallocate(c)
+    deallocate(utmp)
+
+    contains
+
+    !------------------------------------------------------------------
+    ! Loop over grid, for a given block
+    !------------------------------------------------------------------
+    subroutine loop_over_grid(iblock)
+      implicit none
+      integer, intent(in) :: iblock
+      integer :: ix,iy,iz
+      do ix=ixmin(iblock),ixmax(iblock),dix
+        do iy=iymin(iblock),iymax(iblock),diy
+          if (ordering == ORDERING_RB) then
+            if (mod((ix+u%ix_min)+(iy+u%iy_min),2) .ne. color) cycle
+          end if
+          call apply_tridiag_solve(ix,iy,r,c,b,         &
+                                   u%s(1:nz,iy  ,ix+1), &
+                                   u%s(1:nz,iy  ,ix-1), &
+                                   u%s(1:nz,iy+1,ix  ), &
+                                   u%s(1:nz,iy-1,ix  ), &
+                                   utmp)
+           ! Add to field with overrelaxation-factor
+          do iz=1,nz
+            u%s(iz,iy,ix) = (1.0_rl-rho)*u%s(iz,iy,ix) + rho*utmp(iz)
+          end do
+        end do
+      end do
+    end subroutine loop_over_grid
+
+  end subroutine line_SOR
+
+!==================================================================
+! SSOR line smoother mnh
+!==================================================================
+  subroutine line_SSOR_mnh(level,m,direction,b,u)
+    implicit none
+    integer, intent(in)                :: level
+    integer, intent(in)                :: m
+    integer, intent(in)                :: direction
+    type(scalar3d), intent(in)         :: b
+    type(scalar3d), intent(inout)      :: u
+    if (direction == DIRECTION_FORWARD) then
+      call line_SOR_mnh(level,m,DIRECTION_FORWARD,b,u)
+      call line_SOR_mnh(level,m,DIRECTION_BACKWARD,b,u)
+    else
+      call line_SOR_mnh(level,m,DIRECTION_BACKWARD,b,u)
+      call line_SOR_mnh(level,m,DIRECTION_FORWARD,b,u)
+    end if
+  end subroutine line_SSOR_mnh
+
+!==================================================================
+! SSOR line smoother
+!==================================================================
+  subroutine line_SSOR(level,m,direction,b,u)
+    implicit none
+    integer, intent(in)                :: level
+    integer, intent(in)                :: m
+    integer, intent(in)                :: direction
+    type(scalar3d), intent(in)         :: b
+    type(scalar3d), intent(inout)      :: u
+    if (direction == DIRECTION_FORWARD) then
+      call line_SOR(level,m,DIRECTION_FORWARD,b,u)
+      call line_SOR(level,m,DIRECTION_BACKWARD,b,u)
+    else
+      call line_SOR(level,m,DIRECTION_BACKWARD,b,u)
+      call line_SOR(level,m,DIRECTION_FORWARD,b,u)
+    end if
+  end subroutine line_SSOR
+
+!==================================================================
+! Jacobi line smoother
+!==================================================================
+  subroutine line_Jacobi_mnh(level,m,b,u)
+    implicit none
+    integer, intent(in)                :: level
+    integer, intent(in)                :: m
+    type(scalar3d), intent(in)         :: b
+    type(scalar3d), intent(inout)      :: u
+    integer :: ix,iy,iz, nz
+    real(kind=rl), dimension(5) :: alpha_T
+    integer :: nlocal, halo_size
+    real(kind=rl) :: rho
+    logical :: overlap_comms
+    integer, dimension(4) :: send_requests, recv_requests
+    integer, dimension(4) :: send_requestsT, recv_requestsT
+    integer :: ixmin(5), ixmax(5)
+    integer :: iymin(5), iymax(5)
+    integer :: iblock, ierr
+
+    integer :: iib,iie,ijb,ije
+    
+    real , dimension(:,:,:) , pointer , contiguous :: zSut0_st , zu_st
+
+    integer , parameter :: max_lev = 128
+    logical , save                      :: Ljacob_first_call = .true.
+    logical , save , dimension(max_lev) :: Ljacob_first_call_level = .true.
+
+    real(kind=rl), pointer , contiguous :: r(:)
+    real(kind=rl), pointer , contiguous :: c(:), utmp(:)
+    real(kind=rl), pointer , contiguous :: u0(:,:,:) 
+    real(kind=rl), pointer , contiguous :: ut0(:,:,:)
+    type(scalar3d) , pointer :: Sr,Sc,Sut0,Sutmp
+
+    type Temp_jacobi
+       real(kind=rl), pointer , contiguous :: r(:)
+       real(kind=rl), pointer , contiguous :: c(:), utmp(:)
+       real(kind=rl), pointer , contiguous :: u0(:,:,:) 
+       real(kind=rl), pointer , contiguous :: ut0(:,:,:)
+       type(scalar3d) , pointer            :: Sr,Sc,Sut0,Sutmp
+    end type Temp_jacobi
+
+    type (Temp_jacobi) , save , dimension(max_lev) :: Tjacobi
+
+    !
+    !  init size , param
+    !
+    nz = u%grid_param%nz
+    nlocal = u%ix_max -u%ix_min + 1
+    halo_size = u%halo_size
+
+    ! Set optimal smoothing parameter on each level
+    !rho = 2.0_rl/(2.0_rl+4.0_rl*model_param%omega2*u%grid_param%n**2/(1.0_rl+4.0_rl*model_param%omega2*u%grid_param%n**2))
+    rho = smoother_param%rho
+    
+    ! Allocate data one for all by level
+    if (Ljacob_first_call_level(level)) then
+       Ljacob_first_call_level(level) = .false.
+       if (LUseO) then
+          allocate(Tjacobi(level)%u0(0:u%grid_param%nz+1,            &
+               1-halo_size:nlocal+halo_size,   &
+               1-halo_size:nlocal+halo_size) )
+          !$acc enter data create(Tjacobi(level)%u0)
+       end if
+       if (LUseT) then
+          allocate(Tjacobi(level)%ut0(1-halo_size:nlocal+halo_size,   &
+               1-halo_size:nlocal+halo_size,   &
+               0:u%grid_param%nz+1) )
+          !$acc enter data create(Tjacobi(level)%ut0)
+       end if
+       ! Create residual vector       
+       allocate(Tjacobi(level)%r(nz))
+       !$acc enter data create(Tjacobi(level)%r)
+       ! Allocate memory for auxiliary vectors for Thomas algorithm      
+       allocate(Tjacobi(level)%c(nz))
+       !$acc enter data create(Tjacobi(level)%c)
+       allocate(Tjacobi(level)%utmp(nz))
+       !$acc enter data create(Tjacobi(level)%utmp)
+       if (LUseT) then
+          allocate(Tjacobi(level)%Sr)
+          allocate(Tjacobi(level)%Sr%st(1-halo_size:nlocal+halo_size,   &
+               1-halo_size:nlocal+halo_size,   &
+               0:u%grid_param%nz+1) )
+          !$acc enter data create(Tjacobi(level)%Sr%st)
+          allocate(Tjacobi(level)%Sut0)
+          allocate(Tjacobi(level)%Sut0%st(1-halo_size:nlocal+halo_size,   &
+               1-halo_size:nlocal+halo_size,   &
+               0:u%grid_param%nz+1) )
+          !$acc enter data create(Tjacobi(level)%Sut0%st)
+          allocate(Tjacobi(level)%Sutmp)
+          allocate(Tjacobi(level)%Sutmp%st(1-halo_size:nlocal+halo_size,   &
+                            1-halo_size:nlocal+halo_size,   &
+                            0:u%grid_param%nz+1) )
+          !$acc enter data create(Tjacobi(level)%Sutmp%st)
+       end if
+    end if
+
+    call boundary_mnh(u)
+
+
+
+#ifdef OVERLAPCOMMS
+    overlap_comms = (nlocal > 2)
+#else
+    overlap_comms = .false.
+#endif
+
+    ! Block 1 (N)
+    ixmin(1) = 1
+    ixmax(1) = nlocal
+    iymin(1) = 1
+    iymax(1) = 1
+    ! Block 2 (S)
+    ixmin(2) = 1
+    ixmax(2) = nlocal
+    iymin(2) = nlocal
+    iymax(2) = nlocal
+    ! Block 3 (W)
+    ixmin(3) = 1
+    ixmax(3) = 1
+    iymin(3) = 2
+    iymax(3) = nlocal-1
+    ! Block 4 (E)
+    ixmin(4) = nlocal
+    ixmax(4) = nlocal
+    iymin(4) = 2
+    iymax(4) = nlocal-1
+    ! Block 5 (INTERIOR)
+    if (overlap_comms) then
+      ixmin(5) = 2
+      ixmax(5) = nlocal-1
+      iymin(5) = 2
+      iymax(5) = nlocal-1
+    else
+      ! If there are no interior cells, do not overlap
+      ! communications and calculations, just loop over interior cells
+      ixmin(5) = 1
+      ixmax(5) = nlocal
+      iymin(5) = 1
+      iymax(5) = nlocal
+    end if
+
+    ! Temporary vector 
+    if (LUseO) then
+!!$       allocate(u0(0:u%grid_param%nz+1,            &
+!!$                1-halo_size:nlocal+halo_size,   &
+!!$                1-halo_size:nlocal+halo_size) )
+       u0 => Tjacobi(level)%u0
+    end if
+    if (LUseT) then
+!!$       allocate(ut0(1-halo_size:nlocal+halo_size,   &
+!!$                            1-halo_size:nlocal+halo_size,   &
+!!$                            0:u%grid_param%nz+1) )
+       ut0 => Tjacobi(level)%ut0 
+    end if
+    if (LUseO) u0(:,:,:) = u%s(:,:,:)
+    if (LUseT) then
+       zu_st =>  u%st
+       !$acc kernels
+       ut0(:,:,:) = zu_st(:,:,:)
+       !$acc end kernels
+    end if
+    ! Create residual vector
+!!$    allocate(r(nz))
+    r => Tjacobi(level)%r
+    ! Allocate memory for auxiliary vectors for Thomas algorithm
+!!$    allocate(c(nz))
+    c => Tjacobi(level)%c    
+!!$    allocate(utmp(nz))
+    utmp => Tjacobi(level)%utmp
+    if (LUseT) then
+!!$       allocate(Sr%st(1-halo_size:nlocal+halo_size,   &
+!!$                            1-halo_size:nlocal+halo_size,   &
+!!$                            0:u%grid_param%nz+1) )
+       Sr => Tjacobi(level)%Sr
+!!$       allocate(Sut0%st(1-halo_size:nlocal+halo_size,   &
+!!$                            1-halo_size:nlocal+halo_size,   &
+!!$                            0:u%grid_param%nz+1) )
+       Sut0 => Tjacobi(level)%Sut0
+       
+       zSut0_st => Sut0%st
+       zu_st => u%st
+
+       !$acc kernels
+       zSut0_st(:,:,:) = zu_st(:,:,:)
+       !$acc end kernels
+
+!!$       allocate(Sutmp%st(1-halo_size:nlocal+halo_size,   &
+!!$                            1-halo_size:nlocal+halo_size,   &
+!!$                            0:u%grid_param%nz+1) )
+       Sutmp => Tjacobi(level)%Sutmp
+       
+    endif
+
+    ! Loop over grid
+    if (overlap_comms) then
+    ! Loop over cells next to boundary (iblock = 1,...,4)
+      do iblock = 1, 4
+        call loop_over_grid_jacobi_mnh(iblock)
+      end do
+      ! Initiate halo exchange
+      call ihaloswap_mnh(level,m,u,send_requests,recv_requests,send_requestsT,recv_requestsT)
+    end if
+    ! Loop over INTERIOR cells
+    iblock = 5
+    call loop_over_grid_jacobi_mnh(iblock)
+    if (overlap_comms) then
+      if (m > 0) then
+        if (LUseO) call mpi_waitall(4,recv_requests, MPI_STATUSES_IGNORE, ierr)
+        if (LUseO) call mpi_waitall(4,send_requests, MPI_STATUSES_IGNORE, ierr)
+        if (LUseT) call mpi_waitall(4,recv_requestsT, MPI_STATUSES_IGNORE, ierr)
+        if (LUseT) call mpi_waitall(4,send_requestsT, MPI_STATUSES_IGNORE, ierr)
+      end if
+    else
+      call haloswap_mnh(level,m,u)
+    end if
+
+    ! Free memory again
+!!$    deallocate(r)
+!!$    deallocate(c)
+!!$    if (LUseO) deallocate(u0)
+!!$    if (LUseT) deallocate(ut0)
+!!$    deallocate(utmp)
+!!$    if (LUseT) deallocate(Sr%st,Sut0%st,Sutmp%st)
+
+  contains
+
+  subroutine loop_over_grid_jacobi_mnh(iblock)
+    implicit none
+    integer, intent(in) :: iblock
+    integer :: ix,iy,iz
+
+    real , dimension(:,:,:) , pointer , contiguous :: zu_st , zSutmp_st , zSut0_st
+    
+    if (LUseO) then
+       do ix=ixmin(iblock),ixmax(iblock)
+          do iy=iymin(iblock),iymax(iblock)
+             call apply_tridiag_solve_mnh(ix,iy,r,c,b,        &
+                  u0(1:nz,iy  ,ix+1), &
+                  u0(1:nz,iy  ,ix-1), &
+                  u0(1:nz,iy+1,ix  ), &
+                  u0(1:nz,iy-1,ix  ), &
+                  utmp)
+             ! Add correction
+             do iz=1,nz
+                u%s(iz,iy,ix) = rho*utmp(iz) + (1.0_rl-rho)*u0(iz,iy,ix)
+             end do
+          end do
+       end do
+    end if
+   if (LUseT) then
+       iib=ixmin(iblock)
+       iie=ixmax(iblock)
+       ijb=iymin(iblock)
+       ije=iymax(iblock)
+
+       zu_st => u%st
+       zSutmp_st => Sutmp%st
+       zSut0_st => Sut0%st
+
+       call apply_tridiag_solve_mnh_allT(iib,iie,ijb,ije,Sr,c,b,        &
+                  Sut0, &
+                  Sutmp,level )
+       !$acc kernels
+       !$acc loop independent collapse(3)
+       do concurrent ( ix=iib:iie,iy=ijb:ije,iz=1:nz )
+          zu_st(ix,iy,iz) = & 
+               rho*zSutmp_st(ix,iy,iz) & 
+               + (1.0_rl-rho)*zSut0_st(ix,iy,iz)
+       end do ! concurrent
+       !$acc end kernels
+    end if
+
+  end subroutine loop_over_grid_jacobi_mnh
+
+end subroutine line_Jacobi_mnh
+!==================================================================
+! Jacobi line smoother
+!==================================================================
+  subroutine line_Jacobi(level,m,b,u)
+    implicit none
+    integer, intent(in)                :: level
+    integer, intent(in)                :: m
+    type(scalar3d), intent(in)         :: b
+    type(scalar3d), intent(inout)      :: u
+    real(kind=rl), allocatable :: r(:)
+    integer :: ix,iy,iz, nz
+    real(kind=rl), dimension(5) :: alpha_T
+    real(kind=rl), allocatable :: c(:), utmp(:)
+    real(kind=rl), allocatable :: u0(:,:,:)
+    integer :: nlocal, halo_size
+    real(kind=rl) :: rho
+    logical :: overlap_comms
+    integer, dimension(4) :: send_requests, recv_requests
+    integer :: ixmin(5), ixmax(5)
+    integer :: iymin(5), iymax(5)
+    integer :: iblock, ierr
+
+    ! Set optimal smoothing parameter on each level
+    rho = 2.0_rl/(2.0_rl+4.0_rl*model_param%omega2*u%grid_param%n**2/(1.0_rl+4.0_rl*model_param%omega2*u%grid_param%n**2))
+
+    nz = u%grid_param%nz
+    nlocal = u%ix_max -u%ix_min + 1
+    halo_size = u%halo_size
+
+#ifdef OVERLAPCOMMS
+    overlap_comms = (nlocal > 2)
+#else
+    overlap_comms = .false.
+#endif
+
+    ! Block 1 (N)
+    ixmin(1) = 1
+    ixmax(1) = nlocal
+    iymin(1) = 1
+    iymax(1) = 1
+    ! Block 2 (S)
+    ixmin(2) = 1
+    ixmax(2) = nlocal
+    iymin(2) = nlocal
+    iymax(2) = nlocal
+    ! Block 3 (W)
+    ixmin(3) = 1
+    ixmax(3) = 1
+    iymin(3) = 2
+    iymax(3) = nlocal-1
+    ! Block 4 (E)
+    ixmin(4) = nlocal
+    ixmax(4) = nlocal
+    iymin(4) = 2
+    iymax(4) = nlocal-1
+    ! Block 5 (INTERIOR)
+    if (overlap_comms) then
+      ixmin(5) = 2
+      ixmax(5) = nlocal-1
+      iymin(5) = 2
+      iymax(5) = nlocal-1
+    else
+      ! If there are no interior cells, do not overlap
+      ! communications and calculations, just loop over interior cells
+      ixmin(5) = 1
+      ixmax(5) = nlocal
+      iymin(5) = 1
+      iymax(5) = nlocal
+    end if
+
+    ! Temporary vector
+    allocate(u0(0:u%grid_param%nz+1,            &
+                1-halo_size:nlocal+halo_size,   &
+                1-halo_size:nlocal+halo_size) )
+    u0(:,:,:) = u%s(:,:,:)
+    ! Create residual vector
+    allocate(r(nz))
+    ! Allocate memory for auxiliary vectors for Thomas algorithm
+    allocate(c(nz))
+    allocate(utmp(nz))
+
+    ! Loop over grid
+    if (overlap_comms) then
+    ! Loop over cells next to boundary (iblock = 1,...,4)
+      do iblock = 1, 4
+        call loop_over_grid(iblock)
+      end do
+      ! Initiate halo exchange
+      call ihaloswap(level,m,u,send_requests,recv_requests)
+    end if
+    ! Loop over INTERIOR cells
+    iblock = 5
+    call loop_over_grid(iblock)
+    if (overlap_comms) then
+      if (m > 0) then
+        call mpi_waitall(4,recv_requests, MPI_STATUSES_IGNORE, ierr)
+      end if
+    else
+      call haloswap(level,m,u)
+    end if
+
+    ! Free memory again
+    deallocate(r)
+    deallocate(c)
+    deallocate(u0)
+    deallocate(utmp)
+
+  contains
+
+  subroutine loop_over_grid(iblock)
+    implicit none
+    integer, intent(in) :: iblock
+    integer :: ix,iy,iz
+    do ix=ixmin(iblock),ixmax(iblock)
+      do iy=iymin(iblock),iymax(iblock)
+        call apply_tridiag_solve(ix,iy,r,c,b,        &
+                                 u0(1:nz,iy  ,ix+1), &
+                                 u0(1:nz,iy  ,ix-1), &
+                                 u0(1:nz,iy+1,ix  ), &
+                                 u0(1:nz,iy-1,ix  ), &
+                                 utmp)
+        ! Add correction
+        do iz=1,nz
+          u%s(iz,iy,ix) = rho*utmp(iz) + (1.0_rl-rho)*u0(iz,iy,ix)
+        end do
+      end do
+    end do
+  end subroutine loop_over_grid
+
+  end subroutine line_Jacobi
+!==================================================================
+! At a given horizontal position (ix,iy) (local coordinates),
+! calculate
+!
+! u_out = T(ix,iy)^{-1} (b_(ix,iy)
+!       - sum_{ix',iy' != ix,iy} A_{(ix,iy),(ix',iy')}*u_in(ix',iy'))
+!
+!==================================================================
+  subroutine apply_tridiag_solve_mnh(ix,iy,r,c,b, &
+                                 u_in_1,      &
+                                 u_in_2,      &
+                                 u_in_3,      &
+                                 u_in_4,      &
+                                 u_out)
+
+    implicit none
+    integer, intent(in) :: ix
+    integer, intent(in) :: iy
+    real(kind=rl), intent(inout), dimension(:) :: r
+    real(kind=rl), intent(inout), dimension(:) :: c
+    type(scalar3d), intent(in) :: b
+    real(kind=rl), intent(in), dimension(:) :: u_in_1
+    real(kind=rl), intent(in), dimension(:) :: u_in_2
+    real(kind=rl), intent(in), dimension(:) :: u_in_3
+    real(kind=rl), intent(in), dimension(:) :: u_in_4
+    real(kind=rl), intent(inout), dimension(:) :: u_out
+    real(kind=rl), dimension(5) :: alpha_T
+    real(kind=rl) :: Tij
+    real(kind=rl) :: alpha_div_Tij, tmp, b_k_tmp, c_k_tmp
+    integer :: iz, nz
+
+    real(kind=rl) :: xctop_boot 
+
+    nz = b%grid_param%nz
+    xctop_boot = 0.0
+
+    call construct_alpha_T_mnh(b%grid_param,  &
+                           ix+b%ix_min-1, &
+                           iy+b%iy_min-1, &
+                           alpha_T,Tij)
+    ! Calculate r_i = b_i - A_{ij} u_i
+    !alpha_T(5) = 4
+    if (LUseO) then 
+       iz=1 
+       r(iz) = b%s(iz,iy,ix)
+       do iz=2,nz-1
+          r(iz) = b%s(iz,iy,ix) - vert_coeff%d(iz) * ( &
+               alpha_T(1) * u_in_1(iz) + &
+               alpha_T(2) * u_in_2(iz) + &
+               alpha_T(3) * u_in_3(iz) + &
+               alpha_T(4) * u_in_4(iz) )
+       end do
+       iz=nz
+       r(iz) = b%s(iz,iy,ix)
+       
+       ! Thomas algorithm
+       ! STEP 1: Create modified coefficients
+       iz = 1
+       alpha_div_Tij = alpha_T(5)/Tij
+       tmp = (vert_coeff%a(iz)-vert_coeff%b(iz)-vert_coeff%c(iz)) &
+            - xctop_boot*alpha_div_Tij
+       c(iz) = vert_coeff%b(iz)/tmp
+       u_out(iz) = r(iz) / (tmp*Tij*vert_coeff%d(iz))
+       do iz=2,nz-1
+          b_k_tmp = vert_coeff%b(iz)
+          c_k_tmp = vert_coeff%c(iz)
+          tmp = ((vert_coeff%a(iz)-b_k_tmp-c_k_tmp)-alpha_div_Tij) &
+               - c(iz-1)*c_k_tmp
+          c(iz) = b_k_tmp / tmp
+          u_out(iz) = (r(iz) / (Tij*vert_coeff%d(iz)) - u_out(iz-1)*c_k_tmp) / tmp
+       end do
+       iz=nz
+       b_k_tmp = vert_coeff%b(iz)
+       c_k_tmp = vert_coeff%c(iz)
+       tmp = ((vert_coeff%a(iz)-b_k_tmp-c_k_tmp)- xctop_boot*alpha_div_Tij) &
+            - c(iz-1)*c_k_tmp
+       c(iz) = b_k_tmp / tmp
+       u_out(iz) = (r(iz) / (Tij*vert_coeff%d(iz)) - u_out(iz-1)*c_k_tmp) / tmp
+       
+       ! STEP 2: back substitution
+       do iz=nz-1,1,-1
+          u_out(iz) = u_out(iz) - c(iz) * u_out(iz+1)
+       end do
+    end if
+    !
+
+  end subroutine apply_tridiag_solve_mnh
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! tranpose version 
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+  subroutine apply_tridiag_solve_mnhT(ix,iy,r,c,b, &
+                                 u_in_1,      &
+                                 u_in_2,      &
+                                 u_in_3,      &
+                                 u_in_4,      &
+                                 u_out)
+
+    implicit none
+    integer, intent(in) :: ix
+    integer, intent(in) :: iy
+    real(kind=rl), intent(inout), dimension(:) :: r
+    real(kind=rl), intent(inout), dimension(:) :: c
+    type(scalar3d), intent(in) :: b
+    real(kind=rl), intent(in), dimension(:) :: u_in_1
+    real(kind=rl), intent(in), dimension(:) :: u_in_2
+    real(kind=rl), intent(in), dimension(:) :: u_in_3
+    real(kind=rl), intent(in), dimension(:) :: u_in_4
+    real(kind=rl), intent(inout), dimension(:) :: u_out
+    real(kind=rl), dimension(5) :: alpha_T
+    real(kind=rl) :: Tij
+    real(kind=rl) :: alpha_div_Tij, tmp, b_k_tmp, c_k_tmp
+    integer :: iz, nz
+
+    real(kind=rl) :: xctop_boot 
+
+    nz = b%grid_param%nz
+    xctop_boot = 0.0
+
+    call construct_alpha_T_cst_mnh(b%grid_param,alpha_T,Tij)
+    ! Calculate r_i = b_i - A_{ij} u_i
+    if (LUseT ) then 
+       iz=1 
+       r(iz) = b%st(ix,iy,iz)
+       do iz=2,nz-1
+          r(iz) = b%st(ix,iy,iz) - vert_coeff%d(iz) * ( &
+               alpha_T(1) * u_in_1(iz) + &
+               alpha_T(2) * u_in_2(iz) + &
+               alpha_T(3) * u_in_3(iz) + &
+               alpha_T(4) * u_in_4(iz) )
+       end do
+       iz=nz
+       r(iz) = b%st(ix,iy,iz)
+       
+       ! Thomas algorithm
+       ! STEP 1: Create modified coefficients
+       iz = 1
+       alpha_div_Tij = alpha_T(5)/Tij
+       tmp = (vert_coeff%a(iz)-vert_coeff%b(iz)-vert_coeff%c(iz)) &
+            - xctop_boot*alpha_div_Tij
+       c(iz) = vert_coeff%b(iz)/tmp
+       u_out(iz) = r(iz) / (tmp*Tij*vert_coeff%d(iz))
+       do iz=2,nz-1
+          b_k_tmp = vert_coeff%b(iz)
+          c_k_tmp = vert_coeff%c(iz)
+          tmp = ((vert_coeff%a(iz)-b_k_tmp-c_k_tmp)-alpha_div_Tij) &
+               - c(iz-1)*c_k_tmp
+          c(iz) = b_k_tmp / tmp
+          u_out(iz) = (r(iz) / (Tij*vert_coeff%d(iz)) - u_out(iz-1)*c_k_tmp) / tmp
+       end do
+       iz=nz
+       b_k_tmp = vert_coeff%b(iz)
+       c_k_tmp = vert_coeff%c(iz)
+       tmp = ((vert_coeff%a(iz)-b_k_tmp-c_k_tmp)- xctop_boot*alpha_div_Tij) &
+            - c(iz-1)*c_k_tmp
+       c(iz) = b_k_tmp / tmp
+       u_out(iz) = (r(iz) / (Tij*vert_coeff%d(iz)) - u_out(iz-1)*c_k_tmp) / tmp
+       
+       ! STEP 2: back substitution
+       do iz=nz-1,1,-1
+          u_out(iz) = u_out(iz) - c(iz) * u_out(iz+1)
+       end do
+    end if
+
+  end subroutine apply_tridiag_solve_mnhT
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! tranpose version all xyz
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+  subroutine apply_tridiag_solve_mnh_allT(iib,iie,ijb,ije, &
+                                 Sr,c,b,Su_in,Su_out,level)
+
+    implicit none
+    integer, intent(in) :: iib,iie,ijb,ije
+    type(scalar3d), intent(inout) :: Sr
+    real(kind=rl), intent(inout), dimension(:) :: c
+    type(scalar3d), intent(in)    :: b
+    type(scalar3d), intent(in)    :: Su_in
+    type(scalar3d), intent(inout) :: Su_out
+    integer, intent(in) :: level
+
+    !local 
+    !real(kind=rl), dimension(5) :: alpha_T
+    real(kind=rl) :: Tij
+    real(kind=rl) :: alpha_div_Tij ! b_k_tmp, c_k_tmp
+    integer :: iz, nz
+
+    real, dimension(:,:,:) , pointer, contiguous :: zSr_st , zb_st , zSu_in_st , zSu_out_st
+    real, dimension(:)     , pointer, contiguous :: za_k, zb_k, zc_k, zd_k 
+    integer :: ii,ij
+
+    integer , parameter :: max_lev = 128
+    logical , save                                 :: Lfirst_call_tridiag_mnhallT = .true.
+    logical , save , dimension(max_lev)            :: Lfirst_call_level_tridiag_mnhallT = .true.
+
+    real, dimension(:), pointer, contiguous :: tmp_k,c_k
+    
+    type Temp_tridiag_mnh
+       real, dimension(:), pointer, contiguous :: tmp_k,c_k
+    end type Temp_tridiag_mnh
+
+    type(Temp_tridiag_mnh) , save , dimension(max_lev) :: Ttridiag_mnh
+
+    if (LUseT ) then
+       
+       nz = b%grid_param%nz
+       
+       !call construct_alpha_T_cst_mnh(b%grid_param,alpha_T,Tij)
+       Tij = ( b%grid_param%L/b%grid_param%n ) ** 2
+       alpha_div_Tij = 4.0_rl / Tij
+       !print*,"level=",level," Tij=",Tij," alpha_div_Tij=",alpha_div_Tij
+       ! Calculate r_i = b_i - A_{ij} u_i
+    
+      zSr_st => Sr%st
+      zb_st  => b%st
+      zSu_in_st => Su_in%st
+      zSu_out_st => Su_out%st
+      za_k  => vert_coeff%a
+      zb_k  => vert_coeff%b
+      zc_k  => vert_coeff%c
+      zd_k  => vert_coeff%d
+
+      if ( Lfirst_call_level_tridiag_mnhallT(level) ) then
+         Lfirst_call_level_tridiag_mnhallT(level) = .false.
+         allocate(Ttridiag_mnh(level)%tmp_k(size(zb_k)))
+         allocate(Ttridiag_mnh(level)%c_k(size(zb_k)))
+         
+         tmp_k => Ttridiag_mnh(level)%tmp_k
+         c_k => Ttridiag_mnh(level)%c_k
+         ! Thomas algorithm
+         ! STEP 1: Create modified coefficients
+         iz = 1
+         tmp_k(iz) = (za_k(iz)-zb_k(iz)-zc_k(iz))
+         c_k(iz) = zb_k(iz)/tmp_k(iz)
+         !
+         do iz=2,nz-1
+            tmp_k(iz) = ((za_k(iz)-zb_k(iz)-zc_k(iz))-alpha_div_Tij) &
+                 - c_k(iz-1)*zc_k(iz)
+            c_k(iz) = zb_k(iz) / tmp_k(iz)
+         end do
+         !
+         iz=nz
+         tmp_k(iz) = ((za_k(iz)-zb_k(iz)-zc_k(iz))) &
+              - c_k(iz-1)*zc_k(iz)
+         c_k(iz) = zb_k(iz) / tmp_k(iz)
+
+         !$acc enter data copyin(tmp_k,c_k)
+         
+      endif
+      
+      tmp_k => Ttridiag_mnh(level)%tmp_k
+      c_k => Ttridiag_mnh(level)%c_k
+         
+      !$acc kernels
+       iz=1 
+       zSr_st(iib:iie,ijb:ije,iz) = zb_st(iib:iie,ijb:ije,iz)
+       do iz=2,nz-1
+          zSr_st(iib:iie,ijb:ije,iz) = zb_st(iib:iie,ijb:ije,iz) - zd_k(iz) * ( &
+                            zSu_in_st(iib+1:iie+1,ijb:ije,iz) + &
+                            zSu_in_st(iib-1:iie-1,ijb:ije,iz) + &
+                            zSu_in_st(iib:iie,ijb+1:ije+1,iz) + &
+                            zSu_in_st(iib:iie,ijb-1:ije-1,iz) )
+       end do
+       iz=nz
+       zSr_st(iib:iie,ijb:ije,iz) = zb_st(iib:iie,ijb:ije,iz)
+       !
+       ! Thomas algorithm
+       ! 
+       iz = 1     
+       zSu_out_st(iib:iie,ijb:ije,iz) = zSr_st(iib:iie,ijb:ije,iz) / (tmp_k(iz)*Tij*zd_k(iz))
+       !
+       !$acc loop seq
+       do iz=2,nz-1
+          !$acc loop independent collapse(2)
+          do ij=ijb,ije
+             do ii=iib,iie
+                zSu_out_st(ii,ij,iz) = (zSr_st(ii,ij,iz) / (Tij*zd_k(iz)) & 
+                                     - zSu_out_st(ii,ij,iz-1)*zc_k(iz)) / tmp_k(iz)
+             end do
+          end do          
+       end do
+       !
+       iz=nz
+       zSu_out_st(iib:iie,ijb:ije,iz) = (zSr_st(iib:iie,ijb:ije,iz) / (Tij*zd_k(iz)) &
+                                     -  zSu_out_st(iib:iie,ijb:ije,iz-1)*zc_k(iz)) / tmp_k(iz)
+       
+       ! STEP 2: back substitution
+       !$acc loop seq
+       do iz=nz-1,1,-1
+          zSu_out_st(iib:iie,ijb:ije,iz) = zSu_out_st(iib:iie,ijb:ije,iz) & 
+                                        - c_k(iz) * zSu_out_st(iib:iie,ijb:ije,iz+1)
+       end do
+       !$acc end kernels
+       
+    end if
+
+  end subroutine apply_tridiag_solve_mnh_allT
+  !==================================================================
+! At a given horizontal position (ix,iy) (local coordinates),
+! calculate
+!
+! u_out = T(ix,iy)^{-1} (b_(ix,iy)
+!       - sum_{ix',iy' != ix,iy} A_{(ix,iy),(ix',iy')}*u_in(ix',iy'))
+!
+!==================================================================
+  subroutine apply_tridiag_solve(ix,iy,r,c,b, &
+                                 u_in_1,      &
+                                 u_in_2,      &
+                                 u_in_3,      &
+                                 u_in_4,      &
+                                 u_out)
+
+    implicit none
+    integer, intent(in) :: ix
+    integer, intent(in) :: iy
+    real(kind=rl), intent(inout), dimension(:) :: r
+    real(kind=rl), intent(inout), dimension(:) :: c
+    type(scalar3d), intent(in) :: b
+    real(kind=rl), intent(in), dimension(:) :: u_in_1
+    real(kind=rl), intent(in), dimension(:) :: u_in_2
+    real(kind=rl), intent(in), dimension(:) :: u_in_3
+    real(kind=rl), intent(in), dimension(:) :: u_in_4
+    real(kind=rl), intent(inout), dimension(:) :: u_out
+    real(kind=rl), dimension(5) :: alpha_T
+    real(kind=rl) :: Tij
+    real(kind=rl) :: alpha_div_Tij, tmp, b_k_tmp, c_k_tmp
+    integer :: iz, nz
+
+    nz = b%grid_param%nz
+
+    call construct_alpha_T(b%grid_param,  &
+                           ix+b%ix_min-1, &
+                           iy+b%iy_min-1, &
+                           alpha_T,Tij)
+    ! Calculate r_i = b_i - A_{ij} u_i
+    !alpha_T(5) = 4.0
+    do iz=1,nz
+      r(iz) = b%s(iz,iy,ix) - vert_coeff%d(iz) * ( &
+                alpha_T(1) * u_in_1(iz) + &
+                alpha_T(2) * u_in_2(iz) + &
+                alpha_T(3) * u_in_3(iz) + &
+                alpha_T(4) * u_in_4(iz) )
+    end do
+    !r(1:nz) = b%s(1:nz,iy,ix)
+    ! Thomas algorithm
+    ! STEP 1: Create modified coefficients
+    iz = 1
+    alpha_div_Tij = alpha_T(5)/Tij
+    tmp = (vert_coeff%a(iz)-vert_coeff%b(iz)-vert_coeff%c(iz)) &
+             - alpha_div_Tij
+    c(iz) = vert_coeff%b(iz)/tmp
+    u_out(iz) = r(iz) / (tmp*Tij*vert_coeff%d(iz))
+    do iz=2,nz
+      b_k_tmp = vert_coeff%b(iz)
+      c_k_tmp = vert_coeff%c(iz)
+      tmp = ((vert_coeff%a(iz)-b_k_tmp-c_k_tmp)-alpha_div_Tij) &
+          - c(iz-1)*c_k_tmp
+      c(iz) = b_k_tmp / tmp
+      u_out(iz) = (r(iz) / (Tij*vert_coeff%d(iz)) - u_out(iz-1)*c_k_tmp) / tmp
+    end do
+    ! STEP 2: back substitution
+    do iz=nz-1,1,-1
+      u_out(iz) = u_out(iz) - c(iz) * u_out(iz+1)
+    end do
+  end subroutine apply_tridiag_solve
+
+end module discretisation
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/messages.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/messages.f90
new file mode 100644
index 0000000000000000000000000000000000000000..7b4345777a92dcb235e12c456284ecc66b06c980
--- /dev/null
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/messages.f90
@@ -0,0 +1,104 @@
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+!
+!  This file is part of the TensorProductMultigrid code.
+!  
+!  (c) The copyright relating to this work is owned jointly by the
+!  Crown, Met Office and NERC [2014]. However, it has been created
+!  with the help of the GungHo Consortium, whose members are identified
+!  at https://puma.nerc.ac.uk/trac/GungHo/wiki .
+!  
+!  Main Developer: Eike Mueller
+!  
+!  TensorProductMultigrid is free software: you can redistribute it and/or
+!  modify it under the terms of the GNU Lesser General Public License as
+!  published by the Free Software Foundation, either version 3 of the
+!  License, or (at your option) any later version.
+!  
+!  TensorProductMultigrid is distributed in the hope that it will be useful,
+!  but WITHOUT ANY WARRANTY; without even the implied warranty of
+!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+!  GNU Lesser General Public License for more details.
+!  
+!  You should have received a copy of the GNU Lesser General Public License
+!  along with TensorProductMultigrid (see files COPYING and COPYING.LESSER).
+!  If not, see <http://www.gnu.org/licenses/>.
+!
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+
+
+!==================================================================
+!
+!  Module for error/warning/info messages
+!
+!    Eike Mueller, University of Bath, Feb 2012
+!
+!==================================================================
+module messages
+
+  use parameters
+#ifndef MNH
+  use mpi
+#else
+  use modd_mpif
+#endif  
+
+  implicit none
+
+contains
+
+!==================================================================
+! Print error message and exit
+!==================================================================
+  subroutine fatalerror(message)
+    implicit none
+    character(len=*), intent(in) :: message
+    integer :: ierr, rank
+    integer, parameter :: errorcode = -1
+    call mpi_comm_rank(MPI_COMM_WORLD,rank,ierr)
+    if (rank == 0) then
+      write(STDERR,'("FATAL ERROR: ",A)') message
+    end if
+    call mpi_finalize(ierr)
+    STOP
+  end subroutine fatalerror
+
+!==================================================================
+! Print error message
+!==================================================================
+  subroutine error(message)
+    implicit none
+    character(len=*), intent(in) :: message
+    integer :: ierr, rank
+    call mpi_comm_rank(MPI_COMM_WORLD,rank,ierr)
+    if (rank == 0) then
+      write(STDERR,'("ERROR: ",A)') message
+    end if
+  end subroutine error
+
+!==================================================================
+! Print warning message
+!==================================================================
+  subroutine warning(message)
+    implicit none
+    character(len=*), intent(in) :: message
+    integer :: ierr, rank
+    call mpi_comm_rank(MPI_COMM_WORLD,rank,ierr)
+    if (rank == 0) then
+      write(STDERR,'("WARNING: ",A)') message
+    end if
+  end subroutine warning
+
+!==================================================================
+! Print info message
+!==================================================================
+  subroutine information(message)
+    implicit none
+    character(len=*), intent(in) :: message
+    integer :: ierr, rank
+    call mpi_comm_rank(MPI_COMM_WORLD,rank,ierr)
+    if (rank == 0) then
+      write(STDERR,'("INFO: ",A)') message
+    end if
+  end subroutine information
+
+end module messages
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/mg_main.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/mg_main.f90
new file mode 100644
index 0000000000000000000000000000000000000000..a97d51b494603178c8f34336f074d49d4f8aa8ec
--- /dev/null
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/mg_main.f90
@@ -0,0 +1,85 @@
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+!
+!  This file is part of the TensorProductMultigrid code.
+!  
+!  (c) The copyright relating to this work is owned jointly by the
+!  Crown, Met Office and NERC [2014]. However, it has been created
+!  with the help of the GungHo Consortium, whose members are identified
+!  at https://puma.nerc.ac.uk/trac/GungHo/wiki .
+!  
+!  Main Developer: Eike Mueller
+!  
+!  TensorProductMultigrid is free software: you can redistribute it and/or
+!  modify it under the terms of the GNU Lesser General Public License as
+!  published by the Free Software Foundation, either version 3 of the
+!  License, or (at your option) any later version.
+!  
+!  TensorProductMultigrid is distributed in the hope that it will be useful,
+!  but WITHOUT ANY WARRANTY; without even the implied warranty of
+!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+!  GNU Lesser General Public License for more details.
+!  
+!  You should have received a copy of the GNU Lesser General Public License
+!  along with TensorProductMultigrid (see files COPYING and COPYING.LESSER).
+!  If not, see <http://www.gnu.org/licenses/>.
+!
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+
+
+!==================================================================
+!
+!  Main program for multigrid solver code for Helmholtz/Poisson
+!  equation, discretised in the cell centred finite volume scheme
+!
+!    Eike Mueller, University of Bath, Feb 2012
+!
+!==================================================================
+
+!==================================================================
+! Main program
+!==================================================================
+
+program mg_main
+
+  use discretisation
+  use parameters
+  use datatypes
+  use multigrid
+  use conjugategradient
+  use solver
+  use profiles
+  use messages
+  use communication
+  use timer
+#ifndef MNH
+  use mpi
+#else
+  use modd_mpif
+#endif
+
+  use mode_mg_read_param
+  use mode_mg
+
+  implicit none
+
+  call mg_init()
+
+  ! Initialise ghosts in initial solution, as mg_solve assumes that they
+  ! are up-to-date
+  call haloswap(mg_param%n_lev,pproc,xu_fine)
+
+  ! Solve using multigrid
+  call initialise_timer(t_solve,"t_solve")
+  call start_timer(t_solve)
+  comm_measuretime = .True.
+#ifdef MEASUREHALOSWAP
+  call measurehaloswap()
+#else
+  call mg_solve(xb_fine,xu_fine,solver_param)
+#endif
+  comm_measuretime = .False.
+  call finish_timer(t_solve)
+
+call mg_finalize()
+
+end program mg_main
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/mg_main_mnh.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/mg_main_mnh.f90
new file mode 100644
index 0000000000000000000000000000000000000000..21999316883d4dcffe25e5fa84fd544f2485a6b7
--- /dev/null
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/mg_main_mnh.f90
@@ -0,0 +1,203 @@
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+!
+!  This file is part of the TensorProductMultigrid code.
+!  
+!  (c) The copyright relating to this work is owned jointly by the
+!  Crown, Met Office and NERC [2014]. However, it has been created
+!  with the help of the GungHo Consortium, whose members are identified
+!  at https://puma.nerc.ac.uk/trac/GungHo/wiki .
+!  
+!  Main Developer: Eike Mueller
+!  
+!  TensorProductMultigrid is free software: you can redistribute it and/or
+!  modify it under the terms of the GNU Lesser General Public License as
+!  published by the Free Software Foundation, either version 3 of the
+!  License, or (at your option) any later version.
+!  
+!  TensorProductMultigrid is distributed in the hope that it will be useful,
+!  but WITHOUT ANY WARRANTY; without even the implied warranty of
+!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+!  GNU Lesser General Public License for more details.
+!  
+!  You should have received a copy of the GNU Lesser General Public License
+!  along with TensorProductMultigrid (see files COPYING and COPYING.LESSER).
+!  If not, see <http://www.gnu.org/licenses/>.
+!
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+
+
+!==================================================================
+!
+!  Main program for multigrid solver code for Helmholtz/Poisson
+!  equation, discretised in the cell centred finite volume scheme
+!
+!    Eike Mueller, University of Bath, Feb 2012
+!
+!==================================================================
+
+!==================================================================
+! Main program
+!==================================================================
+
+module mode_mg_main_mnh
+
+  use discretisation
+  use parameters
+  use datatypes
+  use multigrid
+  use conjugategradient
+  use solver
+  use profiles
+  use messages
+  use communication
+  use timer
+#ifndef MNH
+  use mpi
+#else
+  use modd_mpif
+#endif
+
+  use mode_mg_read_param
+  use mode_mg
+
+contains
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+  subroutine mg_main_mnh_init(KN,KNZ,PL,PH,PA_K,PB_K,PC_K,PD_K)
+
+    use parameters , only : LMean
+    
+    implicit none
+
+    integer       , optional , intent (in) :: KN,KNZ
+    real(kind=rl) , optional , intent (in) :: PL,PH
+    real(kind=rl) , optional , intent (in) :: PA_K(:),PB_K(:),PC_K(:),PD_K(:)
+
+    call mg_init_mnh(KN,KNZ,PL,PH,PA_K,PB_K,PC_K,PD_K)
+
+    ! Initialise ghosts in initial solution, as mg_solve assumes that they
+    ! are up-to-date
+    call haloswap_mnh(mg_param%n_lev,pproc,xu_fine)
+
+    if (.NOT. PRESENT(KN)) then 
+       !
+       ! Force some parameter for Idealized StandAlone Newman Solver until convergence
+       !
+       ! -> Mean must by set to 0 for covergence with Newmann boundaries
+       LMean = .true.
+       ! -> converge up to 1e-10 in 50 iteration
+       solver_param%resreduction =  1.0d-10
+       solver_param%maxiter = 50
+       
+       if (i_am_master_mpi) then
+          call flush(STDOUT)
+          write(STDOUT,*)
+          write(STDOUT,*) "!!!!! WARNING mg_main_mnh_init !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! "
+          write(STDOUT,*) "!!!!! FORCED PARAMETER FOR StandAlone Newman Solver until convergence !!!! "
+          write(STDOUT,*) "!!!!! LMean                     = " , LMean
+          write(STDOUT,*) "!!!!! solver_param%resreduction = " , solver_param%resreduction
+          write(STDOUT,*) "!!!!! solver_param%maxiter      = " , solver_param%maxiter
+          write(STDOUT,*) "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! "
+          write(STDOUT,*)
+          call flush(STDOUT)
+       end if
+    endif
+    
+  end subroutine mg_main_mnh_init
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+subroutine mg_main_initialise_rhs_mnh(KIB,KIE,KIU,KJB,KJE,KJU,KKU,PY)
+
+implicit none
+
+integer       , optional , intent(in) :: KIB,KIE,KIU,KJB,KJE,KJU,KKU
+real(kind=rl) , optional , intent(in) :: PY(:,:,:)
+
+ call initialise_rhs_mnh(grid_param,model_param,xb_fine,KIB,KIE,KIU,KJB,KJE,KJU,KKU,PY)
+ call haloswap_mnh(mg_param%n_lev,pproc,xb_fine)
+
+end subroutine mg_main_initialise_rhs_mnh
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+subroutine mg_main_initialise_u_mnh(KIB,KIE,KIU,KJB,KJE,KJU,KKU,PU)
+
+implicit none
+
+integer       , optional , intent(in) :: KIB,KIE,KIU,KJB,KJE,KJU,KKU
+real(kind=rl) , optional , intent(in) :: PU(:,:,:)
+
+ call initialise_u_mnh(grid_param,model_param,xu_fine,KIB,KIE,KIU,KJB,KJE,KJU,KKU,PU)
+ call haloswap_mnh(mg_param%n_lev,pproc,xu_fine)
+
+end subroutine mg_main_initialise_u_mnh
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+subroutine mg_main_get_u_mnh(KIB,KIE,KIU,KJB,KJE,KJU,KKU,PU)
+
+implicit none
+
+integer       , optional , intent(in)    :: KIB,KIE,KIU,KJB,KJE,KJU,KKU
+real(kind=rl) , optional , intent(inout) :: PU(:,:,:)
+
+ call get_u_mnh(grid_param,model_param,xu_fine,KIB,KIE,KIU,KJB,KJE,KJU,KKU,PU)
+
+end subroutine mg_main_get_u_mnh
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+  subroutine mg_main_mnh_solve()
+
+    implicit none
+
+    ! Solve using multigrid
+    call initialise_timer(t_solve,"t_solve")
+    call start_timer(t_solve)
+    comm_measuretime = .True.
+
+    call mg_solve_mnh(xb_fine,xu_fine,solver_param)
+
+    comm_measuretime = .False.
+    call finish_timer(t_solve)
+
+  end subroutine mg_main_mnh_solve
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+  subroutine mg_main_mnh_finalize()
+
+
+  end subroutine mg_main_mnh_finalize
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+  subroutine mg_main_mnh
+
+    implicit none
+
+    integer :: it
+
+    call  mg_main_mnh_init()
+
+    DO it=1,1
+       
+       call mg_main_initialise_rhs_mnh()
+       call mg_main_initialise_u_mnh()
+
+       if (i_am_master_mpi) then
+          write(STDOUT,*),'************************ IT=',it,' ***************************'
+          call flush(STDOUT)
+       end if
+       
+       call mg_main_mnh_solve()
+       
+    ENDDO
+
+    call mg_finalize()
+
+  end subroutine mg_main_mnh
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+end module mode_mg_main_mnh
+
+program mg_main_mnh_all
+  
+  use  mode_mg_main_mnh
+  
+  call mg_main_mnh()
+  
+end program mg_main_mnh_all
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/mode_mg.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/mode_mg.f90
new file mode 100644
index 0000000000000000000000000000000000000000..11ade04e65232027b59ee864585f82ad81bc9a1b
--- /dev/null
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/mode_mg.f90
@@ -0,0 +1,335 @@
+module mode_mg
+
+ use datatypes
+ use communication
+ use discretisation
+ use multigrid
+ use conjugategradient
+ use solver
+ use parameters
+ use timer
+#ifndef MNH
+  use mpi
+#else
+  use modd_mpif
+#endif
+ use profiles
+
+ use mode_mg_read_param
+
+implicit none
+
+  type(grid_parameters)     :: grid_param
+  type(comm_parameters)     :: comm_param
+  type(model_parameters)    :: model_param
+  type(smoother_parameters) :: smoother_param
+  type(mg_parameters)       :: mg_param
+  type(cg_parameters)       :: cg_param
+  type(solver_parameters)   :: solver_param
+
+  type(scalar3d) :: xu_fine
+  type(scalar3d) :: xb_fine
+  type(scalar3d) :: xr_fine
+#ifdef TESTCONVERGENCE
+  type(scalar3d) :: uerror
+  real(kind=rl) :: l2error
+#endif
+
+ ! --- Name of executable ---
+  character(len=256) :: executable
+
+ ! --- Parameter file ---
+  character(len=256) :: parameterfile
+
+ ! --- General parameters ---
+  logical :: savefields   ! Save fields to disk?
+
+  integer :: i, int_size
+  integer :: i_arg
+  integer :: ierr
+
+ ! Timers
+  type(time) :: t_solve
+  type(time) :: t_readparam
+  type(time) :: t_initialise
+  type(time) :: t_finalise
+
+contains
+
+subroutine mg_init_mnh(KN,KNZ,PL,PH,PA_K,PB_K,PC_K,PD_K)
+
+use MODE_OPENACC_SET_DEVICE
+  
+implicit none
+
+integer       , optional , intent (in) :: KN,KNZ
+real(kind=rl) , optional , intent (in) :: PL,PH
+real(kind=rl) , optional , intent (in) :: PA_K(:),PB_K(:),PC_K(:),PD_K(:)
+
+! local var
+
+logical :: gisinit
+
+ ! Initialise MPI ...
+  call mpi_initialized(gisinit, ierr )
+  if  (.not. gisinit ) then
+     call mpi_init(ierr)
+  end if
+  !
+  ! get default device type     
+  call MNH_OPENACC_GET_DEVICE_AT_INIT()
+  ! ... and pre initialise communication module
+  call comm_preinitialise()
+
+    parameterfile="parameters_mg.nam"
+
+  if (i_am_master_mpi) then
+    write(STDOUT,*) ''
+    write(STDOUT,*) 'Compile time parameters:'
+    write(STDOUT,*) ''
+#ifdef CARTESIANGEOMETRY
+    write(STDOUT,*) '  Geometry: Cartesian'
+#else
+    write(STDOUT,*) '  Geometry: Spherical'
+#endif
+#ifdef USELAPACK
+    write(STDOUT,*) '  Use Lapack: Yes'
+#else
+    write(STDOUT,*) '  Use Lapack: No'
+#endif
+#ifdef OVERLAPCOMMS
+    write(STDOUT,*) '  Overlap communications and calculation: Yes'
+#else
+    write(STDOUT,*) '  Overlap communications and calculation: No'
+#endif
+    write(STDOUT,*) ''
+
+  end if
+
+  ! Initialise timing module
+  call initialise_timing("timing.txt")
+
+  ! Read parameter files
+  call initialise_timer(t_readparam,"t_readparam")
+  call start_timer(t_readparam)
+  if (i_am_master_mpi) then
+    write(STDOUT,*) "Reading parameters from file '" // &
+                    trim(parameterfile) // "'"
+  end if
+  call read_general_parameters(parameterfile,savefields)
+  call read_solver_parameters(parameterfile,solver_param)
+  call read_grid_parameters_mnh(parameterfile,grid_param,KN,KNZ,PL,PH)
+  call read_comm_parameters(parameterfile,comm_param)
+  call read_model_parameters(parameterfile,model_param)
+  call read_smoother_parameters(parameterfile,smoother_param)
+  call read_multigrid_parameters(parameterfile,mg_param)
+  call read_conjugategradient_parameters(parameterfile,cg_param)
+  call finish_timer(t_readparam)
+
+  if (i_am_master_mpi) then
+    write(STDOUT,*) ''
+  end if
+
+  ! Initialise discretisation module
+  call discretisation_initialise_mnh(grid_param,     &
+                                 model_param,    &
+                                 smoother_param, &
+                                 mg_param%n_lev, &
+                                 PA_K,PB_K,PC_K,PD_K )
+
+  ! Initialise communication module
+  call initialise_timer(t_initialise,"t_initialise")
+  call start_timer(t_initialise)
+  call comm_initialise(mg_param%n_lev,     &
+                       mg_param%lev_split, &
+                       grid_param,         &
+                       comm_param)
+
+  ! Initialise multigrid
+  call mg_initialise(grid_param,       &
+                     comm_param,       &
+                     model_param,      &
+                     smoother_param,   &
+                     mg_param,         &
+                     cg_param          &
+                    )
+
+  call create_scalar3d(MPI_COMM_HORIZ,grid_param,comm_param%halo_size,xu_fine)
+  call create_scalar3d(MPI_COMM_HORIZ,grid_param,comm_param%halo_size,xb_fine)
+  call create_scalar3d(MPI_COMM_HORIZ,grid_param,comm_param%halo_size,xr_fine)
+ 
+!!$  call  mg_initialise_rhs_mnh()
+
+  call finish_timer(t_initialise)
+  if (i_am_master_mpi) then
+    write(STDOUT,*) ''
+  end if
+
+end subroutine mg_init_mnh
+
+subroutine mg_init()
+
+implicit none
+
+ ! Initialise MPI ...
+  call mpi_init(ierr)
+
+  ! ... and pre initialise communication module
+  call comm_preinitialise()
+
+    parameterfile="parameters_mg.nam"
+
+  if (i_am_master_mpi) then
+    write(STDOUT,*) ''
+    write(STDOUT,*) 'Compile time parameters:'
+    write(STDOUT,*) ''
+#ifdef CARTESIANGEOMETRY
+    write(STDOUT,*) '  Geometry: Cartesian'
+#else
+    write(STDOUT,*) '  Geometry: Spherical'
+#endif
+#ifdef USELAPACK
+    write(STDOUT,*) '  Use Lapack: Yes'
+#else
+    write(STDOUT,*) '  Use Lapack: No'
+#endif
+#ifdef OVERLAPCOMMS
+    write(STDOUT,*) '  Overlap communications and calculation: Yes'
+#else
+    write(STDOUT,*) '  Overlap communications and calculation: No'
+#endif
+    write(STDOUT,*) ''
+
+  end if
+
+  ! Initialise timing module
+  call initialise_timing("timing.txt")
+
+  ! Read parameter files
+  call initialise_timer(t_readparam,"t_readparam")
+  call start_timer(t_readparam)
+  if (i_am_master_mpi) then
+    write(STDOUT,*) "Reading parameters from file '" // &
+                    trim(parameterfile) // "'"
+  end if
+  call read_general_parameters(parameterfile,savefields)
+  call read_solver_parameters(parameterfile,solver_param)
+  call read_grid_parameters(parameterfile,grid_param)
+  call read_comm_parameters(parameterfile,comm_param)
+  call read_model_parameters(parameterfile,model_param)
+  call read_smoother_parameters(parameterfile,smoother_param)
+  call read_multigrid_parameters(parameterfile,mg_param)
+  call read_conjugategradient_parameters(parameterfile,cg_param)
+  call finish_timer(t_readparam)
+
+  if (i_am_master_mpi) then
+    write(STDOUT,*) ''
+  end if
+
+  ! Initialise discretisation module
+  call discretisation_initialise(grid_param,     &
+                                 model_param,    &
+                                 smoother_param, &
+                                 mg_param%n_lev )
+
+  ! Initialise communication module
+  call initialise_timer(t_initialise,"t_initialise")
+  call start_timer(t_initialise)
+  call comm_initialise(mg_param%n_lev,     &
+                       mg_param%lev_split, &
+                       grid_param,         &
+                       comm_param)
+
+  ! Initialise multigrid
+  call mg_initialise(grid_param,       &
+                     comm_param,       &
+                     model_param,      &
+                     smoother_param,   &
+                     mg_param,         &
+                     cg_param          &
+                    )
+
+  call create_scalar3d(MPI_COMM_HORIZ,grid_param,comm_param%halo_size,xu_fine)
+  call create_scalar3d(MPI_COMM_HORIZ,grid_param,comm_param%halo_size,xb_fine)
+  call create_scalar3d(MPI_COMM_HORIZ,grid_param,comm_param%halo_size,xr_fine)
+  call initialise_rhs(grid_param,model_param,xb_fine)
+#ifdef TESTCONVERGENCE
+  call create_scalar3d(MPI_COMM_HORIZ,grid_param,comm_param%halo_size,uerror)
+  call analytical_solution(grid_param,uerror)
+#endif
+  call finish_timer(t_initialise)
+  if (i_am_master_mpi) then
+    write(STDOUT,*) ''
+  end if
+
+end subroutine mg_init
+
+subroutine mg_finalize()
+
+implicit none
+
+#ifdef TESTCONVERGENCE
+  call daxpy_scalar3d(-1.0_rl,xu_fine,uerror)
+  call haloswap(mg_param%n_lev,pproc,uerror)
+  l2error = l2norm(uerror)
+  if (i_am_master_mpi) then
+    write(STDOUT,'("||error|| = ",E20.12," log_2(||error||) = ",E20.12)') &
+      l2error, log(l2error)/log(2.0_rl)
+  end if
+#endif
+
+#ifdef TESTCONVERGENCE
+  if (savefields) then
+    call save_scalar3d(MPI_COMM_HORIZ,uerror,"error")
+  end if
+#endif
+
+  ! Save fields to disk
+  if (savefields) then
+    call haloswap(mg_param%n_lev,pproc,xu_fine)
+    call save_scalar3d(MPI_COMM_HORIZ,xu_fine,"solution")
+    call volscale_scalar3d(xb_fine,1)
+    call calculate_residual(mg_param%n_lev,pproc,xb_fine,xu_fine,xr_fine)
+    call volscale_scalar3d(xb_fine,-1)
+    call volscale_scalar3d(xr_fine,-1)
+    call haloswap(mg_param%n_lev,pproc,xr_fine)
+    call save_scalar3d(MPI_COMM_HORIZ,xr_fine,"residual")
+  end if
+
+  if (i_am_master_mpi) then
+    write(STDOUT,*) ''
+  end if
+
+  call discretisation_finalise()
+
+  ! Finalise
+  call initialise_timer(t_finalise,"t_finalise")
+  call start_timer(t_finalise)
+  call mg_finalise()
+  call cg_finalise()
+  ! Deallocate memory
+  call destroy_scalar3d(xu_fine)
+  call destroy_scalar3d(xb_fine)
+  call destroy_scalar3d(xr_fine)
+#ifdef TESTCONVERGENCE
+  call destroy_scalar3d(uerror)
+#endif
+
+
+  ! Finalise communications ...
+  call comm_finalise(mg_param%n_lev,mg_param%lev_split,grid_param)
+  call finish_timer(t_finalise)
+  call print_timerinfo("# --- Main timing results ---")
+  call print_elapsed(t_readparam,.true.,1.0_rl)
+  call print_elapsed(t_initialise,.true.,1.0_rl)
+  call print_elapsed(t_solve,.true.,1.0_rl)
+  call print_elapsed(t_finalise,.true.,1.0_rl)
+  ! Finalise timing
+  call finalise_timing()
+  ! ... and MPI
+  call mpi_finalize(ierr)
+
+
+end subroutine mg_finalize
+
+end module mode_mg
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/mode_mg_read_param.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/mode_mg_read_param.f90
new file mode 100644
index 0000000000000000000000000000000000000000..b0f0181c71deeea7fb1fd0c23c11406106de9870
--- /dev/null
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/mode_mg_read_param.f90
@@ -0,0 +1,576 @@
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+!
+!  This file is part of the TensorProductMultigrid code.
+!  
+!  (c) The copyright relating to this work is owned jointly by the
+!  Crown, Met Office and NERC [2014]. However, it has been created
+!  with the help of the GungHo Consortium, whose members are identified
+!  at https://puma.nerc.ac.uk/trac/GungHo/wiki .
+!  
+!  Main Developer: Eike Mueller
+!  
+!  TensorProductMultigrid is free software: you can redistribute it and/or
+!  modify it under the terms of the GNU Lesser General Public License as
+!  published by the Free Software Foundation, either version 3 of the
+!  License, or (at your option) any later version.
+!  
+!  TensorProductMultigrid is distributed in the hope that it will be useful,
+!  but WITHOUT ANY WARRANTY; without even the implied warranty of
+!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+!  GNU Lesser General Public License for more details.
+!  
+!  You should have received a copy of the GNU Lesser General Public License
+!  along with TensorProductMultigrid (see files COPYING and COPYING.LESSER).
+!  If not, see <http://www.gnu.org/licenses/>.
+!
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+
+module mode_mg_read_param
+
+contains
+
+!==================================================================
+! Read general parameters from namelist file
+!==================================================================
+subroutine read_general_parameters(filename,savefields_out)
+  use parameters
+  use communication
+  use messages
+#ifndef MNH
+  use mpi
+#else
+  use modd_mpif
+#endif 
+  implicit none
+  character(*), intent(in) :: filename
+  logical, intent(out) :: savefields_out
+  integer, parameter :: file_id = 16
+  logical :: savefields
+  integer :: ierr
+  namelist /parameters_general/ savefields
+  if (i_am_master_mpi) then
+    open(file_id,file=filename)
+    read(file_id,NML=parameters_general)
+    close(file_id)
+    write(STDOUT,NML=parameters_general)
+    write(STDOUT,'("---------------------------------------------- ")')
+    write(STDOUT,'("General parameters")')
+    write(STDOUT,'("    Save fields = ",L6)') savefields
+    write(STDOUT,'("---------------------------------------------- ")')
+    write(STDOUT,'("")')
+  end if
+  call mpi_bcast(savefields,1,MPI_LOGICAL,master_rank,MPI_COMM_WORLD,ierr)
+  savefields_out = savefields
+end subroutine read_general_parameters
+
+!==================================================================
+! Read solver parameters from namelist file
+!==================================================================
+subroutine read_solver_parameters(filename,solver_param_out)
+  use solver
+  use parameters
+  use communication
+  use messages
+#ifndef MNH
+  use mpi
+#else
+  use modd_mpif
+#endif
+  implicit none
+  character(*), intent(in) :: filename
+  type(solver_parameters), intent(out) :: solver_param_out
+  integer :: solvertype
+  real(kind=rl) :: resreduction
+  integer :: maxiter
+  integer, parameter :: file_id = 16
+  integer :: ierr
+  namelist /parameters_solver/ solvertype,resreduction, maxiter &
+                               ,  LUseO , LUseT , LMean
+  if (i_am_master_mpi) then
+    open(file_id,file=filename)
+    read(file_id,NML=parameters_solver)
+    close(file_id)
+    write(STDOUT,NML=parameters_solver)
+    write(STDOUT,'("---------------------------------------------- ")')
+    write(STDOUT,'("  LMean = ",L8)') LMean
+    write(STDOUT,'("  LUseO = ",L8)') LUseO
+    write(STDOUT,'("  LUseT = ",L8)') LUseT
+    write(STDOUT,'("Solver parameters ")')
+    if (solvertype == SOLVER_RICHARDSON) then
+      write(STDOUT,'("    solver       = Richardson")')
+    else if (solvertype == SOLVER_CG) then
+      write(STDOUT,'("    solver       = CG")')
+    else
+      call fatalerror("Unknown solver type")
+    end if
+    write(STDOUT,'("    maxiter      = ",I8)') maxiter
+    write(STDOUT,'("    resreduction = ",E15.6)') resreduction
+    write(STDOUT,'("---------------------------------------------- ")')
+    write(*,'("")')
+  end if
+  call mpi_bcast(solvertype,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(maxiter,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(resreduction,1,MPI_DOUBLE_PRECISION,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(LMean,1,MPI_LOGICAL,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(LUseO,1,MPI_LOGICAL,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(LUseT,1,MPI_LOGICAL,master_rank,MPI_COMM_WORLD,ierr)
+  solver_param_out%solvertype = solvertype
+  solver_param_out%maxiter = maxiter
+  solver_param_out%resreduction = resreduction
+end subroutine read_solver_parameters
+
+!==================================================================
+! Read grid parameters from namelist file
+!==================================================================
+subroutine read_grid_parameters_mnh(filename,grid_param,KN,KNZ,PL,PH)
+  use parameters
+  use datatypes
+  use communication
+  use messages
+#ifndef MNH
+  use mpi
+#else
+  use modd_mpif
+#endif 
+  implicit none
+  character(*), intent(in) :: filename
+  type(grid_parameters), intent(out) :: grid_param
+
+  integer       , optional , intent (in) :: KN,KNZ
+  real(kind=rl) , optional , intent (in) :: PL,PH
+
+  ! Grid parameters
+  integer :: n, nz
+  real(kind=rl) :: L, H
+  integer :: vertbc
+  logical :: graded
+  integer, parameter :: file_id = 106
+  integer :: ierr
+  namelist /parameters_grid/ n, nz, L, H, vertbc, graded
+  if (i_am_master_mpi) then
+    open(file_id,file=filename)
+    read(file_id,NML=parameters_grid)
+    close(file_id)
+
+    if (vertbc == VERTBC_DIRICHLET) then
+      write(STDOUT,'("    vertbc = DIRICHLET")')
+    else if (vertbc == VERTBC_NEUMANN) then
+      write(STDOUT,'("    vertbc = NEUMANN")')
+    else
+      vertbc = -1
+    end if
+    write(STDOUT,'("    graded =",L3)') graded
+    write(STDOUT,'("---------------------------------------------- ")')
+    write(STDOUT,'("")')
+  end if
+  call mpi_bcast(n,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(nz,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(L,1,MPI_DOUBLE_PRECISION,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(H,1,MPI_DOUBLE_PRECISION,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(vertbc,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(graded,1,MPI_LOGICAL,master_rank,MPI_COMM_WORLD,ierr)
+  IF (PRESENT(KN)) THEN
+     n = KN
+     nz = KNZ
+     L = PL
+     H = PH
+  END IF
+  if (i_am_master_mpi) then
+    write(STDOUT,NML=parameters_grid)
+    write(STDOUT,'("---------------------------------------------- ")')
+    write(STDOUT,'("Grid parameters")')
+    write(STDOUT,'("    n      = ",I15)') n
+    write(STDOUT,'("    nz     = ",I15)') nz
+    write(STDOUT,'("    L      = ",E15.6)') L
+    write(STDOUT,'("    H      = ",E15.6)') H
+  end if
+  grid_param%n = n
+  grid_param%nz = nz
+  grid_param%L = L
+  grid_param%H = H
+  grid_param%vertbc = vertbc
+  grid_param%graded = graded
+  if (vertbc == -1) then
+    call fatalerror("vertbc has to be either 1 (Dirichlet) or 2 (Neumann)")
+  end if
+end subroutine read_grid_parameters_mnh
+!==================================================================
+! Read grid parameters from namelist file
+!==================================================================
+subroutine read_grid_parameters(filename,grid_param)
+  use parameters
+  use datatypes
+  use communication
+  use messages
+#ifndef MNH
+  use mpi
+#else
+  use modd_mpif
+#endif
+  
+  implicit none
+  character(*), intent(in) :: filename
+  type(grid_parameters), intent(out) :: grid_param
+  ! Grid parameters
+  integer :: n, nz
+  real(kind=rl) :: L, H
+  integer :: vertbc
+  logical :: graded
+  integer, parameter :: file_id = 16
+  integer :: ierr
+  namelist /parameters_grid/ n, nz, L, H, vertbc, graded
+  if (i_am_master_mpi) then
+    open(file_id,file=filename)
+    read(file_id,NML=parameters_grid)
+    close(file_id)
+    write(STDOUT,NML=parameters_grid)
+    write(STDOUT,'("---------------------------------------------- ")')
+    write(STDOUT,'("Grid parameters")')
+    write(STDOUT,'("    n      = ",I15)') n
+    write(STDOUT,'("    nz     = ",I15)') nz
+    write(STDOUT,'("    L      = ",E15.6)') L
+    write(STDOUT,'("    H      = ",E15.6)') H
+    if (vertbc == VERTBC_DIRICHLET) then
+      write(STDOUT,'("    vertbc = DIRICHLET")')
+    else if (vertbc == VERTBC_NEUMANN) then
+      write(STDOUT,'("    vertbc = NEUMANN")')
+    else
+      vertbc = -1
+    end if
+    write(STDOUT,'("    graded =",L3)') graded
+    write(STDOUT,'("---------------------------------------------- ")')
+    write(STDOUT,'("")')
+  end if
+  call mpi_bcast(n,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(nz,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(L,1,MPI_DOUBLE_PRECISION,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(H,1,MPI_DOUBLE_PRECISION,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(vertbc,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(graded,1,MPI_LOGICAL,master_rank,MPI_COMM_WORLD,ierr)
+  grid_param%n = n
+  grid_param%nz = nz
+  grid_param%L = L
+  grid_param%H = H
+  grid_param%vertbc = vertbc
+  grid_param%graded = graded
+  if (vertbc == -1) then
+    call fatalerror("vertbc has to be either 1 (Dirichlet) or 2 (Neumann)")
+  end if
+end subroutine read_grid_parameters
+!==================================================================
+! Read parallel communication parameters from namelist file
+!==================================================================
+subroutine read_comm_parameters(filename,comm_param)
+  use parameters
+  use communication
+  use messages
+#ifndef MNH
+  use mpi
+#else
+  use modd_mpif
+#endif 
+  implicit none
+  character(*), intent(in) :: filename
+  type(comm_parameters), intent(out) :: comm_param
+  ! Grid parameters
+  integer :: halo_size
+  integer, parameter :: file_id = 16
+  integer :: ierr
+  namelist /parameters_communication/ halo_size
+  if (i_am_master_mpi) then
+    open(file_id,file=filename)
+    read(file_id,NML=parameters_communication)
+    close(file_id)
+    write(STDOUT,NML=parameters_communication)
+    write(STDOUT,'("---------------------------------------------- ")')
+    write(STDOUT,'("Communication parameters")')
+    write(STDOUT,'("    halosize  = ",I3)') halo_size
+    write(STDOUT,'("---------------------------------------------- ")')
+    write(STDOUT,'("")')
+    if ( (halo_size .ne. 1) ) then
+      halo_size = -1
+    end if
+  end if
+  call mpi_bcast(halo_size,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  comm_param%halo_size = halo_size
+  if (halo_size == -1) then
+    call fatalerror("Halo size has to be 1.")
+  end if
+end subroutine read_comm_parameters
+
+!==================================================================
+! Read model parameters from namelist file
+!==================================================================
+subroutine read_model_parameters(filename,model_param)
+  use parameters
+  use discretisation
+  use communication
+  use messages
+#ifndef MNH
+  use mpi
+#else
+  use modd_mpif
+#endif 
+  implicit none
+  character(*), intent(in) :: filename
+  type(model_parameters), intent(out) :: model_param
+  real(kind=rl) :: omega2, lambda2, delta
+  integer, parameter :: file_id = 16
+  integer :: ierr
+  namelist /parameters_model/ omega2, lambda2, delta
+  if (i_am_master_mpi) then
+    open(file_id,file=filename)
+    read(file_id,NML=parameters_model)
+    close(file_id)
+    write(STDOUT,NML=parameters_model)
+    write(STDOUT,'("---------------------------------------------- ")')
+    write(STDOUT,'("Model parameters")')
+    write(STDOUT,'("    omega2  = ",E15.6)') omega2
+    write(STDOUT,'("    lambda2 = ",E15.6)') lambda2
+    write(STDOUT,'("    delta   = ",E15.6)') delta
+    write(STDOUT,'("---------------------------------------------- ")')
+    write(STDOUT,'("")')
+  end if
+  call mpi_bcast(omega2,1,MPI_DOUBLE_PRECISION,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(lambda2,1,MPI_DOUBLE_PRECISION,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(delta,1,MPI_DOUBLE_PRECISION,master_rank,MPI_COMM_WORLD,ierr)
+  model_param%omega2 = omega2
+  model_param%lambda2 = lambda2
+  model_param%delta = delta
+end subroutine read_model_parameters
+
+!==================================================================
+! Read smoother parameters from namelist file
+!==================================================================
+subroutine read_smoother_parameters(filename,smoother_param)
+  use parameters
+  use discretisation
+  use communication
+  use messages
+#ifndef MNH
+  use mpi
+#else
+  use modd_mpif
+#endif
+  implicit none
+  character(*), intent(in) :: filename
+  type(smoother_parameters), intent(out) :: smoother_param
+  integer, parameter :: file_id = 16
+  integer :: smoother, ordering
+  real(kind=rl) :: rho
+  integer :: ierr
+  namelist /parameters_smoother/ smoother,           &
+                                  ordering,           &
+                                  rho
+  if (i_am_master_mpi) then
+    open(file_id,file=filename)
+    read(file_id,NML=parameters_smoother)
+    close(file_id)
+    write(STDOUT,NML=parameters_smoother)
+
+    write(STDOUT,'("---------------------------------------------- ")')
+    write(STDOUT,'("Smoother parameters")')
+    ! Smoother
+    if (smoother == SMOOTHER_LINE_SOR) then
+      write(STDOUT,'("    smoother      = LINE_SOR")')
+    else if (smoother == SMOOTHER_LINE_SSOR) then
+      write(STDOUT,'("    smoother      = LINE_SSOR")')
+    else if (smoother == SMOOTHER_LINE_JAC) then
+      write(STDOUT,'("    smoother      = LINE_JACOBI")')
+    else
+      smoother = -1
+    end if
+
+    if (ordering == ORDERING_LEX) then
+      write(STDOUT,'("    ordering      = LEX")')
+    else if (ordering == ORDERING_RB) then
+      write(STDOUT,'("    ordering      = RB")')
+    else
+      ordering = -1
+    end if
+    write(STDOUT,'("    rho = ",E15.6)') rho
+    write(STDOUT,'("---------------------------------------------- ")')
+    write(STDOUT,'("")')
+  end if
+  call mpi_bcast(smoother,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(ordering,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(rho,1,MPI_DOUBLE_PRECISION,master_rank,MPI_COMM_WORLD,ierr)
+  smoother_param%smoother = smoother
+  smoother_param%ordering = ordering
+  smoother_param%rho = rho
+  if (smoother == -1) then
+    call fatalerror('Unknown smoother.')
+  end if
+  if (ordering == -1) then
+    call fatalerror('Unknown ordering.')
+  end if
+
+end subroutine read_smoother_parameters
+
+!==================================================================
+! Read multigrid parameters from namelist file
+!==================================================================
+subroutine read_multigrid_parameters(filename,mg_param)
+  use parameters
+  use multigrid
+  use communication
+  use messages
+#ifndef MNH
+  use mpi
+#else
+  use modd_mpif
+#endif
+
+  use MODE_OPENACC_SET_DEVICE, only : iswitch_cpu_gpu
+  
+  implicit none
+  character(*), intent(in) :: filename
+  type(mg_parameters), intent(out) :: mg_param
+  integer, parameter :: file_id = 16
+  integer :: verbose, n_lev, lev_split, n_presmooth, n_postsmooth,    &
+             prolongation, restriction, n_coarsegridsmooth, &
+             coarsegridsolver
+  integer :: ierr
+  namelist /parameters_multigrid/ verbose,            &
+                                  n_lev,              &
+                                  lev_split,          &
+                                  iswitch_cpu_gpu,    &
+                                  n_presmooth,        &
+                                  n_postsmooth,       &
+                                  n_coarsegridsmooth, &
+                                  prolongation,       &
+                                  restriction,        &
+                                  coarsegridsolver
+  if (i_am_master_mpi) then
+    open(file_id,file=filename)
+    read(file_id,NML=parameters_multigrid)
+    close(file_id)
+    write(STDOUT,NML=parameters_multigrid)
+    write(STDOUT,'("---------------------------------------------- ")')
+    write(STDOUT,'("Multigrid parameters")')
+    write(STDOUT,'("    verbose      = ",L6)') verbose
+    write(STDOUT,'("    levels       = ",I3)') n_lev
+    write(STDOUT,'("    splitlevel   = ",I3)') lev_split
+    !
+    ! switch lev_split from the top level to have constant lev_split
+    ! when changing n_lev
+    !
+    lev_split = n_lev - lev_split
+    write(STDOUT,'("    splitlevel/sw= ",I3)') lev_split
+    write(STDOUT,'(" iswitch_cpu_gpu = ",I3)') iswitch_cpu_gpu
+    iswitch_cpu_gpu = n_lev - iswitch_cpu_gpu
+    write(STDOUT,'("switch_cpu_gpu/s = ",I3)') iswitch_cpu_gpu
+    !
+    write(STDOUT,'("    n_presmooth  = ",I6)') n_presmooth
+    write(STDOUT,'("    n_postsmooth = ",I6)') n_postsmooth
+    if (restriction == REST_CELLAVERAGE) then
+      write(STDOUT,'("    restriction   = CELLAVERAGE")')
+   else if (restriction == REST_KHALIL) then
+      write(STDOUT,'("    restriction   = KHALIL ")')
+    else
+      restriction = -1
+    endif
+    if (prolongation == PROL_CONSTANT) then
+      write(STDOUT,'("    prolongation  = CONSTANT")')
+    else if (prolongation == PROL_TRILINEAR) then
+#ifdef PIECEWISELINEAR
+      write(STDOUT,'("    prolongation  = TRILINEAR (piecewise linear)")')
+#else
+      write(STDOUT,'("    prolongation  = TRILINEAR (regression plane)")')
+#endif
+    else
+      prolongation = -1
+    endif
+    if (coarsegridsolver == COARSEGRIDSOLVER_CG) then
+      write(STDOUT,'("    coarse solver = CG")')
+    else if (coarsegridsolver == COARSEGRIDSOLVER_SMOOTHER) then
+      write(STDOUT,'("    coarse solver = SMOOTHER (",I6," iterations)")') &
+        n_coarsegridsmooth
+    else
+      coarsegridsolver = -1
+    end if
+    write(STDOUT,'("---------------------------------------------- ")')
+    write(*,'("")')
+
+  end if
+  call mpi_bcast(verbose,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(n_lev,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(lev_split,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(iswitch_cpu_gpu,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(n_presmooth,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(n_postsmooth,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(n_coarsegridsmooth,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD, &
+                 ierr)
+  call mpi_bcast(prolongation,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(restriction,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(coarsegridsolver,1,MPI_Integer,master_rank,MPI_COMM_WORLD,ierr)
+  mg_param%verbose = verbose
+  mg_param%n_lev = n_lev
+  mg_param%lev_split = lev_split
+  mg_param%n_presmooth = n_presmooth
+  mg_param%n_postsmooth = n_postsmooth
+  mg_param%n_coarsegridsmooth = n_coarsegridsmooth
+  mg_param%prolongation = prolongation
+  mg_param%restriction = restriction
+  mg_param%coarsegridsolver = coarsegridsolver
+  if (restriction == -1) then
+    call fatalerror('Unknown restriction.')
+  end if
+  if (prolongation == -1) then
+    call fatalerror('Unknown prolongation.')
+  end if
+  if (coarsegridsolver == -1) then
+    call fatalerror('Unknown coarse grid solver.')
+  end if
+end subroutine read_multigrid_parameters
+
+!==================================================================
+! Read conjugate gradient parameters from namelist file
+!==================================================================
+subroutine read_conjugategradient_parameters(filename,cg_param)
+  use parameters
+  use communication
+  use conjugategradient
+  use communication
+  use messages
+#ifndef MNH
+  use mpi
+#else
+  use modd_mpif
+#endif 
+  implicit none
+  character(*), intent(in) :: filename
+  type(cg_parameters), intent(out) :: cg_param
+  integer, parameter :: file_id = 16
+  integer :: verbose, maxiter, n_prec
+  real(kind=rl) :: resreduction
+  integer :: ierr
+  namelist /parameters_conjugategradient/ verbose,      &
+                                          maxiter,      &
+                                          resreduction, &
+                                          n_prec
+  if (i_am_master_mpi) then
+    open(file_id,file=filename)
+    read(file_id,NML=parameters_conjugategradient)
+    close(file_id)
+    write(STDOUT,NML=parameters_conjugategradient)
+    write(STDOUT,'("---------------------------------------------- ")')
+    write(STDOUT,'("Conjugate gradient parameters")')
+    write(STDOUT,'("    verbose       = ",I6)') verbose
+    write(STDOUT,'("    maxiter       = ",I6)') maxiter
+    write(STDOUT,'("    resreduction  = ",E15.6)') resreduction
+    write(STDOUT,'("    n_prec        = ",I6)') n_prec
+    write(STDOUT,'("---------------------------------------------- ")')
+    write(STDOUT,'("")')
+  end if
+  call mpi_bcast(verbose,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(maxiter,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(resreduction,1,MPI_DOUBLE_PRECISION,master_rank,MPI_COMM_WORLD,ierr)
+  call mpi_bcast(n_prec,1,MPI_INTEGER,master_rank,MPI_COMM_WORLD,ierr)
+  cg_param%verbose = verbose
+  cg_param%maxiter = maxiter
+  cg_param%resreduction = resreduction
+  cg_param%n_prec = n_prec
+end subroutine read_conjugategradient_parameters
+
+end module mode_mg_read_param
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/mode_mnh_allocate_mg_halo.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/mode_mnh_allocate_mg_halo.f90
new file mode 100644
index 0000000000000000000000000000000000000000..7b41eaf44c6bcb823cb65dc6600c619dd86b75b3
--- /dev/null
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/mode_mnh_allocate_mg_halo.f90
@@ -0,0 +1,16 @@
+module mode_mnh_allocate_mg_halo
+contains
+  subroutine mnh_allocate_mg_halo(ptab,nx,ny,nz)
+    implicit none
+    integer , intent(in) :: nx,ny,nz
+    real, dimension(:,:,:) , pointer , contiguous :: ptab
+
+    real, dimension(:,:,:) , pointer , contiguous :: ztab
+
+    allocate (ztab(nx,ny,nz))
+    !$acc enter data create (ztab)
+
+    ptab => ztab
+    
+  end subroutine mnh_allocate_mg_halo
+end module mode_mnh_allocate_mg_halo
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/mode_openacc_set_device.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/mode_openacc_set_device.f90
new file mode 120000
index 0000000000000000000000000000000000000000..3c68748c1ae2179857dc555ec579b2d6a60ff446
--- /dev/null
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/mode_openacc_set_device.f90
@@ -0,0 +1 @@
+../../MNH/mode_openacc_set_device.f90
\ No newline at end of file
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/multigrid.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/multigrid.f90
new file mode 100644
index 0000000000000000000000000000000000000000..bb1a7d3f7ea79fe25eba3090a39a93cf9d9415b9
--- /dev/null
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/multigrid.f90
@@ -0,0 +1,1924 @@
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+!
+!  This file is part of the TensorProductMultigrid code.
+!  
+!  (c) The copyright relating to this work is owned jointly by the
+!  Crown, Met Office and NERC [2014]. However, it has been created
+!  with the help of the GungHo Consortium, whose members are identified
+!  at https://puma.nerc.ac.uk/trac/GungHo/wiki .
+!  
+!  Main Developer: Eike Mueller
+!  
+!  TensorProductMultigrid is free software: you can redistribute it and/or
+!  modify it under the terms of the GNU Lesser General Public License as
+!  published by the Free Software Foundation, either version 3 of the
+!  License, or (at your option) any later version.
+!  
+!  TensorProductMultigrid is distributed in the hope that it will be useful,
+!  but WITHOUT ANY WARRANTY; without even the implied warranty of
+!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+!  GNU Lesser General Public License for more details.
+!  
+!  You should have received a copy of the GNU Lesser General Public License
+!  along with TensorProductMultigrid (see files COPYING and COPYING.LESSER).
+!  If not, see <http://www.gnu.org/licenses/>.
+!
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+
+
+!==================================================================
+!
+!  Geometric multigrid module for cell centred finite volume
+!  discretisation.
+!
+!    Eike Mueller, University of Bath, Feb 2012
+!
+!==================================================================
+module multigrid
+
+#ifndef MNH
+  use mpi
+#else
+  use modd_mpif
+#endif
+  use parameters
+  use datatypes
+  use discretisation
+  use messages
+  use solver
+  use conjugategradient
+  use communication
+  use timer
+
+  implicit none
+
+public::mg_parameters
+public::mg_initialise
+public::mg_finalise
+public::mg_solve_mnh
+public::mg_solve
+public::measurehaloswap
+public::REST_CELLAVERAGE
+public::REST_KHALIL
+public::PROL_CONSTANT
+public::PROL_TRILINEAR
+public::COARSEGRIDSOLVER_SMOOTHER
+public::COARSEGRIDSOLVER_CG
+
+private
+
+  ! --- multigrid parameter constants ---
+  ! restriction
+  integer, parameter :: REST_CELLAVERAGE = 1
+  integer, parameter :: REST_KHALIL      = 2
+  ! prolongation method
+  integer, parameter :: PROL_CONSTANT = 1
+  integer, parameter :: PROL_TRILINEAR = 2
+  ! Coarse grid solver
+  integer, parameter :: COARSEGRIDSOLVER_SMOOTHER = 1
+  integer, parameter :: COARSEGRIDSOLVER_CG = 2
+
+  ! --- Multigrid parameters type ---
+  type mg_parameters
+    ! Verbosity level
+    integer :: verbose
+    ! Number of MG levels
+    integer :: n_lev
+    ! First level where data is pulled together
+    integer :: lev_split
+    ! Number of presmoothing steps
+    integer :: n_presmooth
+    ! Number of postsmoothing steps
+    integer :: n_postsmooth
+    ! Number of smoothing steps on coarsest level
+    integer :: n_coarsegridsmooth
+    ! Prolongation (see PROL_... for allowed values)
+    integer :: prolongation
+    ! Restriction (see RESTR_... for allowed values)
+    integer :: restriction
+    ! Smoother (see SMOOTHER_... for allowed values)
+    integer :: smoother
+    ! Relaxation factor
+    real(kind=rl) :: omega
+    ! Smoother on coarse grid
+    integer :: coarsegridsolver
+    ! ordering of grid points for smoother
+    integer :: ordering
+  end type mg_parameters
+
+! --- Parameters ---
+  type(mg_parameters) :: mg_param
+  type(model_parameters) :: model_param
+  type(smoother_parameters) :: smoother_param
+  type(grid_parameters) :: grid_param
+  type(comm_parameters) :: comm_param
+  type(cg_parameters) :: cg_param
+
+
+! --- Gridded and scalar data structures ---
+  ! Solution vector
+  type(scalar3d), allocatable :: xu_mg(:,:)
+  ! RHS vector
+  type(scalar3d), allocatable :: xb_mg(:,:)
+  ! residual
+  type(scalar3d), allocatable :: xr_mg(:,:)
+
+! --- Timer ---
+  type(time), allocatable, dimension(:,:) :: t_restrict
+  type(time), allocatable, dimension(:,:) :: t_prolongate
+  type(time), allocatable, dimension(:,:) :: t_residual
+  type(time), allocatable, dimension(:,:) :: t_addcorr
+  type(time), allocatable, dimension(:,:) :: t_smooth
+  type(time), allocatable, dimension(:,:) :: t_coarsesolve
+  type(time), allocatable, dimension(:,:) :: t_total
+
+contains
+
+!==================================================================
+! Initialise multigrid module, check and print out out parameters
+!==================================================================
+  subroutine mg_initialise(grid_param_in,     &  ! Grid parameters
+                           comm_param_in,     &  ! Comm parameters
+                           model_param_in,    &  ! Model parameters
+                           smoother_param_in, &  ! Smoother parameters
+                           mg_param_in,       &  ! Multigrid parameters
+                           cg_param_in        &  ! CG parameters
+                           )
+    implicit none
+    type(grid_parameters), intent(in)  :: grid_param_in
+    type(comm_parameters), intent(in)  :: comm_param_in
+    type(model_parameters), intent(in) :: model_param_in
+    type(smoother_parameters), intent(in) :: smoother_param_in
+    type(mg_parameters), intent(in)    :: mg_param_in
+    type(cg_parameters), intent(in)    :: cg_param_in
+    real(kind=rl)                      :: L, H
+    integer                            :: n, nz, m, nlocal
+    logical                            :: reduced_m
+    integer                            :: level
+    integer                            :: rank, ierr
+    integer, dimension(2)              :: p_horiz
+    integer, parameter                 :: dim_horiz = 2
+    logical                            :: grid_active
+    integer                            :: ix_min, ix_max, iy_min, iy_max
+    integer                            :: icompx_min, icompx_max, &
+                                          icompy_min, icompy_max
+    integer                            :: halo_size
+    integer                            :: vertbc
+    character(len=32)                  :: t_label
+
+    real , dimension(:,:,:) , pointer , contiguous :: zxu_mg_st,zxb_mg_st,zxr_mg_st
+
+    if (i_am_master_mpi) &
+      write(STDOUT,*) '*** Initialising multigrid ***'
+    ! Check that cell counts are valid
+    grid_param = grid_param_in
+    comm_param = comm_param_in
+    mg_param = mg_param_in
+    model_param = model_param_in
+    smoother_param = smoother_param_in
+    cg_param = cg_param_in
+    halo_size = comm_param%halo_size
+    vertbc = grid_param%vertbc
+
+    ! Check parameters
+    if (grid_param%n < 2**(mg_param%n_lev-1) ) then
+      call fatalerror('Number of cells in x-/y- direction has to be at least 2^{n_lev-1}.')
+    endif
+
+    if (mod(grid_param%n,2**(mg_param%n_lev-1)) .ne. 0 ) then
+      call fatalerror('Number of cells in x-/y- direction is not a multiple of 2^{n_lev-1}.')
+    end if
+    if (i_am_master_mpi) &
+      write(STDOUT,*) ''
+
+    ! Allocate memory for timers
+    allocate(t_smooth(mg_param%n_lev,0:pproc))
+    allocate(t_total(mg_param%n_lev,0:pproc))
+    allocate(t_restrict(mg_param%n_lev,0:pproc))
+    allocate(t_residual(mg_param%n_lev,0:pproc))
+    allocate(t_prolongate(mg_param%n_lev,0:pproc))
+    allocate(t_addcorr(mg_param%n_lev,0:pproc))
+    allocate(t_coarsesolve(mg_param%n_lev,0:pproc))
+
+    ! Allocate memory for all levels and initialise fields
+    allocate(xu_mg(mg_param%n_lev,0:pproc))
+    allocate(xb_mg(mg_param%n_lev,0:pproc))
+    allocate(xr_mg(mg_param%n_lev,0:pproc))
+    n = grid_param%n
+    nlocal = n/(2**pproc)
+    nz = grid_param%nz
+    L = grid_param%L
+    H = grid_param%H
+    level = mg_param%n_lev
+    m = pproc
+    reduced_m = .false.
+    ! Work out local processor coordinates (this is necessary to identify
+    ! global coordinates)
+    call mpi_comm_rank(MPI_COMM_HORIZ,rank,ierr)
+    call mpi_cart_coords(MPI_COMM_HORIZ,rank,dim_horiz,p_horiz,ierr)
+    if (i_am_master_mpi) then
+      write(STDOUT, &
+        '(" Global gridsize (x,y,z) (pproc = ",I4," )      : ",I8," x ",I8," x ",I8)') &
+        pproc, n, n, nz
+    end if
+    do while (level > 0)
+      if (i_am_master_mpi) &
+        write(STDOUT, &
+          '(" Local gridsize (x,y,z) on level ",I3," m = ",I4," : ",I8," x ",I8," x ",I8)') &
+          level, m, nlocal, nlocal, nz
+      if (nlocal < 1) then
+        call fatalerror('Number of grid points < 1')
+      end if
+
+      ! Set sizes of computational grid (take care at boundaries)
+      if (p_horiz(1) == 0) then
+        icompy_min = 1
+      else
+        icompy_min = 1 - (halo_size - 1)
+      end if
+
+      if (p_horiz(2) == 0) then
+        icompx_min = 1
+      else
+        icompx_min = 1 - (halo_size - 1)
+      end if
+
+      if (p_horiz(1) == 2**pproc-1) then
+        icompy_max = nlocal
+      else
+        icompy_max = nlocal + (halo_size - 1)
+      end if
+
+      if (p_horiz(2) == 2**pproc-1) then
+        icompx_max = nlocal
+      else
+        icompx_max = nlocal + (halo_size - 1)
+      end if
+
+      ! Allocate data
+      if (LUseO) then
+      allocate(xu_mg(level,m)%s(0:nz+1,                       &
+                            1-halo_size:nlocal+halo_size, &
+                            1-halo_size:nlocal+halo_size))
+      allocate(xb_mg(level,m)%s(0:nz+1,                       &
+                            1-halo_size:nlocal+halo_size, &
+                            1-halo_size:nlocal+halo_size))
+      allocate(xr_mg(level,m)%s(0:nz+1,                       &
+                            1-halo_size:nlocal+halo_size, &
+                            1-halo_size:nlocal+halo_size))
+      xu_mg(level,m)%s(:,:,:) = 0.0_rl
+      xb_mg(level,m)%s(:,:,:) = 0.0_rl
+      xr_mg(level,m)%s(:,:,:) = 0.0_rl
+      endif
+
+      if (LUseT) then
+         allocate(zxu_mg_st(1-halo_size:nlocal+halo_size, &
+              1-halo_size:nlocal+halo_size, &
+              0:nz+1))
+         xu_mg(level,m)%st => zxu_mg_st
+         
+         allocate(zxb_mg_st(1-halo_size:nlocal+halo_size, &
+              1-halo_size:nlocal+halo_size, &
+              0:nz+1))
+         xb_mg(level,m)%st => zxb_mg_st
+         
+         allocate(zxr_mg_st(1-halo_size:nlocal+halo_size, &
+              1-halo_size:nlocal+halo_size, &
+              0:nz+1))
+          xr_mg(level,m)%st => zxr_mg_st
+
+      
+      !$acc kernels
+      zxu_mg_st(:,:,:) = 0.0_rl
+      zxb_mg_st(:,:,:) = 0.0_rl
+      zxr_mg_st(:,:,:) = 0.0_rl
+      !$acc end kernels
+      endif
+
+      ! NB: 1st coordinate is in the y-direction of the processor grid,
+      ! second coordinate is in the x-direction (see comments in
+      ! communication module)
+      iy_min = (p_horiz(1)/2**(pproc-m))*nlocal+1
+      iy_max = (p_horiz(1)/2**(pproc-m)+1)*nlocal
+      ix_min = p_horiz(2)/2**(pproc-m)*nlocal+1
+      ix_max = (p_horiz(2)/2**(pproc-m)+1)*nlocal
+      ! Set grid parameters and local data ranges
+      ! Note that only n (and possibly nz) change as we
+      ! move down the levels
+      xu_mg(level,m)%grid_param%L = L
+      xu_mg(level,m)%grid_param%H = H
+      xu_mg(level,m)%grid_param%n = n
+      xu_mg(level,m)%grid_param%nz = nz
+      xu_mg(level,m)%grid_param%vertbc = vertbc
+      xu_mg(level,m)%ix_min = ix_min
+      xu_mg(level,m)%ix_max = ix_max
+      xu_mg(level,m)%iy_min = iy_min
+      xu_mg(level,m)%iy_max = iy_max
+      xu_mg(level,m)%icompx_min = icompx_min
+      xu_mg(level,m)%icompx_max = icompx_max
+      xu_mg(level,m)%icompy_min = icompy_min
+      xu_mg(level,m)%icompy_max = icompy_max
+      xu_mg(level,m)%halo_size = halo_size
+
+      xb_mg(level,m)%grid_param%L = L
+      xb_mg(level,m)%grid_param%H = H
+      xb_mg(level,m)%grid_param%n = n
+      xb_mg(level,m)%grid_param%nz = nz
+      xb_mg(level,m)%grid_param%vertbc = vertbc
+      xb_mg(level,m)%ix_min = ix_min
+      xb_mg(level,m)%ix_max = ix_max
+      xb_mg(level,m)%iy_min = iy_min
+      xb_mg(level,m)%iy_max = iy_max
+      xb_mg(level,m)%icompx_min = icompx_min
+      xb_mg(level,m)%icompx_max = icompx_max
+      xb_mg(level,m)%icompy_min = icompy_min
+      xb_mg(level,m)%icompy_max = icompy_max
+      xb_mg(level,m)%halo_size = halo_size
+
+      xr_mg(level,m)%grid_param%L = L
+      xr_mg(level,m)%grid_param%H = H
+      xr_mg(level,m)%grid_param%n = n
+      xr_mg(level,m)%grid_param%nz = nz
+      xr_mg(level,m)%grid_param%vertbc = vertbc
+      xr_mg(level,m)%ix_min = ix_min
+      xr_mg(level,m)%ix_max = ix_max
+      xr_mg(level,m)%iy_min = iy_min
+      xr_mg(level,m)%iy_max = iy_max
+      xr_mg(level,m)%icompx_min = icompx_min
+      xr_mg(level,m)%icompx_max = icompx_max
+      xr_mg(level,m)%icompy_min = icompy_min
+      xr_mg(level,m)%icompy_max = icompy_max
+      xr_mg(level,m)%halo_size = halo_size
+
+      ! Are these grids active?
+      if ( (m == pproc) .or. &
+           ( (mod(p_horiz(1),2**(pproc-m)) == 0) .and. &
+             (mod(p_horiz(2),2**(pproc-m)) == 0) ) ) then
+        grid_active = .true.
+      else
+        grid_active = .false.
+      end if
+      xu_mg(level,m)%isactive = grid_active
+      xb_mg(level,m)%isactive = grid_active
+      xr_mg(level,m)%isactive = grid_active
+      write(t_label,'("t_total(",I3,",",I3,")")') level, m
+      call initialise_timer(t_total(level,m),t_label)
+      write(t_label,'("t_smooth(",I3,",",I3,")")') level, m
+      call initialise_timer(t_smooth(level,m),t_label)
+      write(t_label,'("t_restrict(",I3,",",I3,")")') level, m
+      call initialise_timer(t_restrict(level,m),t_label)
+      write(t_label,'("t_residual(",I3,",",I3,")")') level, m
+      call initialise_timer(t_residual(level,m),t_label)
+      write(t_label,'("t_prolongate(",I3,",",I3,")")') level, m
+      call initialise_timer(t_prolongate(level,m),t_label)
+      write(t_label,'("t_addcorrection(",I3,",",I3,")")') level, m
+      call initialise_timer(t_addcorr(level,m),t_label)
+      write(t_label,'("t_coarsegridsolver(",I3,",",I3,")")') level, m
+      call initialise_timer(t_coarsesolve(level,m),t_label)
+
+      ! If we are below L_split, split data
+      if ( (level .le. mg_param%lev_split) .and. &
+           (m > 0) .and. (.not. reduced_m) ) then
+        reduced_m = .true.
+        m = m-1
+        nlocal = 2*nlocal
+        cycle
+      end if
+      reduced_m = .false.
+      level = level-1
+      n = n/2
+      nlocal = nlocal/2
+    end do
+    if (i_am_master_mpi) &
+      write(STDOUT,*) ''
+    call cg_initialise(cg_param)
+  end subroutine mg_initialise
+
+!==================================================================
+! Finalise, free memory for all data structures
+!==================================================================
+  subroutine mg_finalise()
+    implicit none
+    integer :: level, m
+    logical :: reduced_m
+    character(len=80) :: s
+    integer :: ierr
+
+    if (i_am_master_mpi) &
+      write(STDOUT,*) '*** Finalising multigrid ***'
+    ! Deallocate memory
+    level = mg_param%n_lev
+    m = pproc
+    reduced_m = .false.
+    call print_timerinfo("--- V-cycle timing results ---")
+    do while (level > 0)
+      write(s,'("level = ",I3,", m = ",I3)') level,m
+      call print_timerinfo(s)
+      call print_elapsed(t_smooth(level,m),.True.,1.0_rl)
+      call print_elapsed(t_restrict(level,m),.True.,1.0_rl)
+      call print_elapsed(t_prolongate(level,m),.True.,1.0_rl)
+      call print_elapsed(t_residual(level,m),.True.,1.0_rl)
+      call print_elapsed(t_addcorr(level,m),.True.,1.0_rl)
+      call print_elapsed(t_coarsesolve(level,m),.True.,1.0_rl)
+      call print_elapsed(t_total(level,m),.True.,1.0_rl)
+
+      if (LUseO) then
+      deallocate(xu_mg(level,m)%s)
+      deallocate(xb_mg(level,m)%s)
+      deallocate(xr_mg(level,m)%s)
+      endif
+
+      if (LUseT) then
+      deallocate(xu_mg(level,m)%st)
+      deallocate(xb_mg(level,m)%st)
+      deallocate(xr_mg(level,m)%st)
+      endif
+
+      ! If we are below L_split, split data
+      if ( (level .le. mg_param%lev_split) .and. &
+           (m > 0) .and. (.not. reduced_m) ) then
+        reduced_m = .true.
+        m = m-1
+        cycle
+      end if
+      reduced_m = .false.
+      level = level-1
+    end do
+    deallocate(xu_mg)
+    deallocate(xb_mg)
+    deallocate(xr_mg)
+    deallocate(t_total)
+    deallocate(t_smooth)
+    deallocate(t_restrict)
+    deallocate(t_prolongate)
+    deallocate(t_residual)
+    deallocate(t_addcorr)
+    deallocate(t_coarsesolve)
+      if (i_am_master_mpi) write(STDOUT,'("")')
+  end subroutine mg_finalise
+
+!==================================================================
+! Restrict from fine -> coarse
+!==================================================================
+  subroutine restrict_mnh(phifine,phicoarse)
+    implicit none
+    type(scalar3d), intent(in)    :: phifine
+    type(scalar3d), intent(inout) :: phicoarse
+    ! local var
+    integer :: ix,iy,iz
+    integer :: ix_min, ix_max, iy_min, iy_max, n
+    real(kind=rl) :: xn,xs,xw,xe
+
+    real , dimension(:,:,:) , pointer , contiguous :: zphifine_st , zphicoarse_st
+
+    n      = phicoarse%grid_param%n
+    ix_min = phicoarse%icompx_min
+    ix_max = phicoarse%icompx_max
+    iy_min = phicoarse%icompy_min
+    iy_max = phicoarse%icompy_max
+    ! three dimensional cell average
+    if (mg_param%restriction == REST_CELLAVERAGE) then
+      ! Do not coarsen in z-direction
+      if (LUseO) then 
+      do ix=ix_min,ix_max
+        do iy=iy_min,iy_max
+          do iz=1,phicoarse%grid_param%nz
+            phicoarse%s(iz,iy,ix) =  &
+              phifine%s(iz  ,2*iy  ,2*ix  ) + &
+              phifine%s(iz  ,2*iy-1,2*ix  ) + &
+              phifine%s(iz  ,2*iy  ,2*ix-1) + &
+              phifine%s(iz  ,2*iy-1,2*ix-1)
+          end do
+        end do
+      end do
+      endif
+      if (LUseT) then 
+         zphifine_st => phifine%st
+         zphicoarse_st => phicoarse%st
+         !$acc kernels loop independent  collapse(3)
+         do iz=1,phicoarse%grid_param%nz
+            do iy=iy_min,iy_max
+               do ix=ix_min,ix_max
+                  zphicoarse_st(ix,iy,iz) =  &
+                       zphifine_st(2*ix  ,2*iy  ,iz) + &
+                       zphifine_st(2*ix  ,2*iy-1,iz) + &
+                       zphifine_st(2*ix-1,2*iy  ,iz) + &
+                       zphifine_st(2*ix-1,2*iy-1,iz)
+               end do
+            end do
+         end do
+         !$acc end kernels
+      endif
+
+   elseif(mg_param%restriction == REST_KHALIL) then
+      if (LUseO) then 
+         do ix=ix_min,ix_max
+            xw=1.0
+            xe=1.0
+            if (ix==1) xw=0.0
+            if (ix==n) xe=0.0
+            do iy=iy_min,iy_max
+               xs=1.0
+               xn=1.0
+               if (iy==1) xs=0.0
+               if (iy==n) xn=0.0
+               do iz=1,phicoarse%grid_param%nz
+                  phicoarse%s(iz,iy,ix) = 0.25_rl *         ( &
+                       phifine%s(iz,2*iy+1,2*ix-1) * xn        + &
+                       phifine%s(iz,2*iy+1,2*ix  ) * xn        + &
+                       phifine%s(iz,2*iy  ,2*ix-2) * xw        + &
+                       phifine%s(iz,2*iy  ,2*ix-1) * (4-xw-xn) + &
+                       phifine%s(iz,2*iy  ,2*ix  ) * (4-xe-xn) + &
+                       phifine%s(iz,2*iy  ,2*ix+1) * xe        + &
+                       phifine%s(iz,2*iy-1,2*ix-2) * xw        + &
+                       phifine%s(iz,2*iy-1,2*ix-1) * (4-xw-xs) + &
+                       phifine%s(iz,2*iy-1,2*ix  ) * (4-xe-xs) + &
+                       phifine%s(iz,2*iy-2,2*ix-1) * xs        + &
+                       phifine%s(iz,2*iy-2,2*ix  ) * xs          &     
+                       & )   
+               end do
+            end do
+         end do
+      end if
+      if (LUseT) then 
+         do iz=1,phicoarse%grid_param%nz
+            do iy=iy_min,iy_max
+               xs=1.0
+               xn=1.0
+               if (iy==1) xs=0.0
+               if (iy==n) xn=0.0
+               do ix=ix_min,ix_max
+                  xw=1.0
+                  xe=1.0
+                  if (ix==1) xw=0.0
+                  if (ix==n) xe=0.0
+                  phicoarse%st(ix,iy,iz) = 0.25_rl *         ( &
+                       phifine%s(2*ix-1,2*iy+1,iz) * xn        + &
+                       phifine%s(2*ix  ,2*iy+1,iz) * xn        + &
+                       phifine%s(2*ix-2,2*iy  ,iz) * xw        + &
+                       phifine%s(2*ix-1,2*iy  ,iz) * (4-xw-xn) + &
+                       phifine%s(2*ix  ,2*iy  ,iz) * (4-xe-xn) + &
+                       phifine%s(2*ix+1,2*iy  ,iz) * xe        + &
+                       phifine%s(2*ix-2,2*iy-1,iz) * xw        + &
+                       phifine%s(2*ix-1,2*iy-1,iz) * (4-xw-xs) + &
+                       phifine%s(2*ix  ,2*iy-1,iz) * (4-xe-xs) + &
+                       phifine%s(2*ix-1,2*iy-2,iz) * xs        + &
+                       phifine%s(2*ix  ,2*iy-2,iz) * xs          &     
+                       & )                
+               end do
+            end do
+         end do
+      end if
+      
+    end if
+  end subroutine restrict_mnh
+!==================================================================
+! Restrict from fine -> coarse
+!==================================================================
+  subroutine restrict(phifine,phicoarse)
+    implicit none
+    type(scalar3d), intent(in)    :: phifine
+    type(scalar3d), intent(inout) :: phicoarse
+    integer :: ix,iy,iz
+    integer :: ix_min, ix_max, iy_min, iy_max
+
+    ix_min = phicoarse%icompx_min
+    ix_max = phicoarse%icompx_max
+    iy_min = phicoarse%icompy_min
+    iy_max = phicoarse%icompy_max
+    ! three dimensional cell average
+    if (mg_param%restriction == REST_CELLAVERAGE) then
+      ! Do not coarsen in z-direction
+      if (LUseO) then
+         do ix=ix_min,ix_max
+            do iy=iy_min,iy_max
+               do iz=1,phicoarse%grid_param%nz
+                  phicoarse%s(iz,iy,ix) =  &
+                       phifine%s(iz  ,2*iy  ,2*ix  ) + &
+                       phifine%s(iz  ,2*iy-1,2*ix  ) + &
+                       phifine%s(iz  ,2*iy  ,2*ix-1) + &
+                       phifine%s(iz  ,2*iy-1,2*ix-1)
+               end do
+            end do
+         end do
+      end if
+      if (LUseT) then 
+         do iz=1,phicoarse%grid_param%nz
+            do iy=iy_min,iy_max
+               do ix=ix_min,ix_max
+                  phicoarse%st(ix,iy,iz) =  &
+                       phifine%st(2*ix  ,2*iy  ,iz) + &
+                       phifine%st(2*ix  ,2*iy-1,iz) + &
+                       phifine%st(2*ix-1,2*iy  ,iz) + &
+                       phifine%st(2*ix-1,2*iy-1,iz)
+               end do
+            end do
+         end do
+      endif
+   end if
+ end subroutine restrict
+!==================================================================
+! Prolongate from coarse -> fine
+! level, m is the correspong to the fine grid level
+!==================================================================
+  subroutine prolongate_mnh(level,m,phicoarse,phifine)
+    implicit none
+    integer, intent(in) :: level
+    integer, intent(in) :: m
+    type(scalar3d), intent(in) :: phicoarse
+    type(scalar3d), intent(inout) :: phifine
+    real(kind=rl) :: tmp
+    integer :: nlocal
+    integer, dimension(5) :: ixmin, ixmax, iymin, iymax
+    integer :: n, nz
+    integer :: ix, iy, iz
+    integer :: dix, diy, diz
+    real(kind=rl) :: rhox, rhoy, rhoz
+    real(kind=rl) :: rho_i, sigma_j, h, c1, c2
+    logical :: overlap_comms
+    integer, dimension(4) :: send_requests, recv_requests
+    integer, dimension(4) :: send_requestsT, recv_requestsT
+    integer :: ierr
+    integer :: iblock
+
+    ! Needed for interpolation matrix
+#ifdef PIECEWISELINEAR
+#else
+    real(kind=rl) :: dx(4,3), A(3,3), dx_fine(4,2)
+    integer :: i,j,k
+    real(kind=rl) :: dxu(2), grad(2)
+    dx(1,3) = 1.0_rl
+    dx(2,3) = 1.0_rl
+    dx(3,3) = 1.0_rl
+    dx(4,3) = 1.0_rl
+#endif
+
+    nlocal = phicoarse%ix_max-phicoarse%ix_min+1
+    n = phicoarse%grid_param%n
+    nz = phicoarse%grid_param%nz
+
+#ifdef OVERLAPCOMMS
+    overlap_comms = (nlocal > 2)
+#else
+    overlap_comms = .false.
+#endif
+    ! Block 1 (N)
+    ixmin(1) = 1
+    ixmax(1) = nlocal
+    iymin(1) = 1
+    iymax(1) = 1
+    ! Block 2 (S)
+    ixmin(2) = 1
+    ixmax(2) = nlocal
+    iymin(2) = nlocal
+    iymax(2) = nlocal
+    ! Block 3 (W)
+    ixmin(3) = 1
+    ixmax(3) = 1
+    iymin(3) = 2
+    iymax(3) = nlocal-1
+    ! Block 4 (E)
+    ixmin(4) = nlocal
+    ixmax(4) = nlocal
+    iymin(4) = 2
+    iymax(4) = nlocal-1
+    ! Block 5 (INTERIOR)
+    if (overlap_comms) then
+      ixmin(5) = 2
+      ixmax(5) = nlocal-1
+      iymin(5) = 2
+      iymax(5) = nlocal-1
+    else
+      ! If there are no interior cells, do not overlap
+      ! communications and calculations, just loop over interior cells
+      ixmin(5) = 1
+      ixmax(5) = nlocal
+      iymin(5) = 1
+      iymax(5) = nlocal
+    end if
+
+    ! *** Constant prolongation or (tri-) linear prolongation ***
+    if ( (mg_param%prolongation == PROL_CONSTANT) .or. &
+         (mg_param%prolongation == PROL_TRILINEAR) ) then
+      if (overlap_comms) then
+        ! Loop over cells next to boundary (iblock = 1,...,4)
+        do iblock = 1, 4
+          if (mg_param%prolongation == PROL_CONSTANT) then
+            call loop_over_grid_constant_mnh(iblock)
+          end if
+          if (mg_param%prolongation == PROL_TRILINEAR) then
+            call loop_over_grid_linear_mnh(iblock)
+          end if
+        end do
+        ! Initiate halo exchange
+        call ihaloswap_mnh(level,m,phifine,send_requests,recv_requests,send_requestsT,recv_requestsT)
+      end if
+      ! Loop over INTERIOR cells
+      iblock = 5
+      if (mg_param%prolongation == PROL_CONSTANT) then
+        call loop_over_grid_constant_mnh(iblock)
+      end if
+      if (mg_param%prolongation == PROL_TRILINEAR) then
+        call loop_over_grid_linear_mnh(iblock)
+      end if
+      if (overlap_comms) then
+        if (m > 0) then
+          if (LUseO) call mpi_waitall(4,recv_requests, MPI_STATUSES_IGNORE, ierr)
+          if (LUseO) call mpi_waitall(4,send_requests, MPI_STATUSES_IGNORE, ierr)
+          if (LUseT) call mpi_waitall(4,recv_requestsT, MPI_STATUSES_IGNORE, ierr)
+          if (LUseT) call mpi_waitall(4,send_requestsT, MPI_STATUSES_IGNORE, ierr)
+        end if
+      else
+        call haloswap_mnh(level,m,phifine)
+      end if
+    else
+      call fatalerror("Unsupported prolongation.")
+    end if
+
+    contains
+
+    !------------------------------------------------------------------
+    ! The actual loops over the grid for the individual blocks,
+    ! when overlapping calculation and communication
+    !------------------------------------------------------------------
+
+    !------------------------------------------------------------------
+    ! (1) Constant interpolation
+    !------------------------------------------------------------------
+    subroutine loop_over_grid_constant_mnh(iblock)
+      implicit none
+      integer, intent(in) :: iblock
+      integer :: ix,iy,iz
+      
+      if (LUseO) then
+         do ix=ixmin(iblock),ixmax(iblock)
+            do iy=iymin(iblock),iymax(iblock)
+               do dix = -1,0
+                  do diy = -1,0
+                     do iz=1,phicoarse%grid_param%nz
+                        phifine%s(iz,2*iy+diy,2*ix+dix) = phicoarse%s(iz,iy,ix)
+                     end do
+                  end do
+               end do
+            end do
+         end do
+      end if
+     if (LUseT) then
+         do ix=ixmin(iblock),ixmax(iblock)
+            do iy=iymin(iblock),iymax(iblock)
+               do dix = -1,0
+                  do diy = -1,0
+                     do iz=1,phicoarse%grid_param%nz
+                        phifine%st(2*ix+dix,2*iy+diy,iz) = phicoarse%st(ix,iy,iz)
+                     end do
+                  end do
+               end do
+            end do
+         end do
+      end if
+
+    end subroutine loop_over_grid_constant_mnh
+
+    !------------------------------------------------------------------
+    ! (2) Linear interpolation
+    !------------------------------------------------------------------
+    subroutine loop_over_grid_linear_mnh(iblock)
+      implicit none
+      integer, intent(in) :: iblock
+      !local var
+      integer :: ix,iy,iz
+
+      real , dimension(:,:,:) , pointer , contiguous :: zphifine_st , zphicoarse_st
+
+      ! optimisation for newman MNH case : all coef constant
+      rhox = 0.25_rl
+      rhoy = 0.25_rl
+
+      if (LUseO) then     
+         do ix=ixmin(iblock),ixmax(iblock)
+            do iy=iymin(iblock),iymax(iblock)
+               ! Piecewise linear interpolation
+               do iz=1,phicoarse%grid_param%nz
+                  do dix = -1,0
+                     do diy = -1,0
+                        phifine%s(iz,2*iy+diy,2*ix+dix) =      &
+                             phicoarse%s(iz,iy,ix) +                &
+                             rhox*(phicoarse%s(iz,iy,ix+(2*dix+1))  &
+                             - phicoarse%s(iz,iy,ix)) +       &
+                             rhoy*(phicoarse%s(iz,iy+(2*diy+1),ix)  &
+                             - phicoarse%s(iz,iy,ix))
+                     end do
+                  end do
+               end do
+            end do
+         end do
+      end if
+      if (LUseT) then  
+         ! Piecewise linear interpolation
+         
+         zphifine_st => phifine%st
+         zphicoarse_st => phicoarse%st
+
+         !$acc kernels loop independent  collapse(5)
+         do iz=1,phicoarse%grid_param%nz 
+            do diy = -1,0
+               do dix = -1,0
+                  do iy=iymin(iblock),iymax(iblock)
+                     do ix=ixmin(iblock),ixmax(iblock)
+                        zphifine_st(2*ix+dix,2*iy+diy,iz) =      &
+                             zphicoarse_st(ix,iy,iz) +                &
+                             rhox*(zphicoarse_st(ix+(2*dix+1),iy,iz)  &
+                             - zphicoarse_st(ix,iy,iz)) +       &
+                             rhoy*(zphicoarse_st(ix,iy+(2*diy+1),iz)  &
+                             - zphicoarse_st(ix,iy,iz))
+                     end do
+                  end do
+               end do
+            end do
+         end do
+         !$acc end kernels
+      end if
+
+    end subroutine loop_over_grid_linear_mnh
+
+  end subroutine prolongate_mnh
+!==================================================================
+! Prolongate from coarse -> fine
+! level, m is the correspong to the fine grid level
+!==================================================================
+  subroutine prolongate(level,m,phicoarse,phifine)
+    implicit none
+    integer, intent(in) :: level
+    integer, intent(in) :: m
+    type(scalar3d), intent(in) :: phicoarse
+    type(scalar3d), intent(inout) :: phifine
+    real(kind=rl) :: tmp
+    integer :: nlocal
+    integer, dimension(5) :: ixmin, ixmax, iymin, iymax
+    integer :: n, nz
+    integer :: ix, iy, iz
+    integer :: dix, diy, diz
+    real(kind=rl) :: rhox, rhoy, rhoz
+    real(kind=rl) :: rho_i, sigma_j, h, c1, c2
+    logical :: overlap_comms
+    integer, dimension(4) :: send_requests, recv_requests
+    integer :: ierr
+    integer :: iblock
+
+    ! Needed for interpolation matrix
+#ifdef PIECEWISELINEAR
+#else
+    real(kind=rl) :: dx(4,3), A(3,3), dx_fine(4,2)
+    integer :: i,j,k
+    real(kind=rl) :: dxu(2), grad(2)
+    dx(1,3) = 1.0_rl
+    dx(2,3) = 1.0_rl
+    dx(3,3) = 1.0_rl
+    dx(4,3) = 1.0_rl
+#endif
+
+    nlocal = phicoarse%ix_max-phicoarse%ix_min+1
+    n = phicoarse%grid_param%n
+    nz = phicoarse%grid_param%nz
+
+#ifdef OVERLAPCOMMS
+    overlap_comms = (nlocal > 2)
+#else
+    overlap_comms = .false.
+#endif
+    ! Block 1 (N)
+    ixmin(1) = 1
+    ixmax(1) = nlocal
+    iymin(1) = 1
+    iymax(1) = 1
+    ! Block 2 (S)
+    ixmin(2) = 1
+    ixmax(2) = nlocal
+    iymin(2) = nlocal
+    iymax(2) = nlocal
+    ! Block 3 (W)
+    ixmin(3) = 1
+    ixmax(3) = 1
+    iymin(3) = 2
+    iymax(3) = nlocal-1
+    ! Block 4 (E)
+    ixmin(4) = nlocal
+    ixmax(4) = nlocal
+    iymin(4) = 2
+    iymax(4) = nlocal-1
+    ! Block 5 (INTERIOR)
+    if (overlap_comms) then
+      ixmin(5) = 2
+      ixmax(5) = nlocal-1
+      iymin(5) = 2
+      iymax(5) = nlocal-1
+    else
+      ! If there are no interior cells, do not overlap
+      ! communications and calculations, just loop over interior cells
+      ixmin(5) = 1
+      ixmax(5) = nlocal
+      iymin(5) = 1
+      iymax(5) = nlocal
+    end if
+
+    ! *** Constant prolongation or (tri-) linear prolongation ***
+    if ( (mg_param%prolongation == PROL_CONSTANT) .or. &
+         (mg_param%prolongation == PROL_TRILINEAR) ) then
+      if (overlap_comms) then
+        ! Loop over cells next to boundary (iblock = 1,...,4)
+        do iblock = 1, 4
+          if (mg_param%prolongation == PROL_CONSTANT) then
+            call loop_over_grid_constant(iblock)
+          end if
+          if (mg_param%prolongation == PROL_TRILINEAR) then
+            call loop_over_grid_linear(iblock)
+          end if
+        end do
+        ! Initiate halo exchange
+        call ihaloswap(level,m,phifine,send_requests,recv_requests)
+      end if
+      ! Loop over INTERIOR cells
+      iblock = 5
+      if (mg_param%prolongation == PROL_CONSTANT) then
+        call loop_over_grid_constant(iblock)
+      end if
+      if (mg_param%prolongation == PROL_TRILINEAR) then
+        call loop_over_grid_linear(iblock)
+      end if
+      if (overlap_comms) then
+        if (m > 0) then
+          call mpi_waitall(4,recv_requests, MPI_STATUSES_IGNORE, ierr)
+        end if
+      else
+        call haloswap(level,m,phifine)
+      end if
+    else
+      call fatalerror("Unsupported prolongation.")
+    end if
+
+    contains
+
+    !------------------------------------------------------------------
+    ! The actual loops over the grid for the individual blocks,
+    ! when overlapping calculation and communication
+    !------------------------------------------------------------------
+
+    !------------------------------------------------------------------
+    ! (1) Constant interpolation
+    !------------------------------------------------------------------
+    subroutine loop_over_grid_constant(iblock)
+      implicit none
+      integer, intent(in) :: iblock
+      integer :: ix,iy,iz
+      do ix=ixmin(iblock),ixmax(iblock)
+        do iy=iymin(iblock),iymax(iblock)
+          do dix = -1,0
+            do diy = -1,0
+              do iz=1,phicoarse%grid_param%nz
+                phifine%s(iz,2*iy+diy,2*ix+dix) = phicoarse%s(iz,iy,ix)
+              end do
+            end do
+          end do
+        end do
+      end do
+    end subroutine loop_over_grid_constant
+
+    !------------------------------------------------------------------
+    ! (2) Linear interpolation
+    !------------------------------------------------------------------
+    subroutine loop_over_grid_linear(iblock)
+      implicit none
+      integer, intent(in) :: iblock
+      integer :: ix,iy,iz
+      do ix=ixmin(iblock),ixmax(iblock)
+        do iy=iymin(iblock),iymax(iblock)
+#ifdef PIECEWISELINEAR
+          ! Piecewise linear interpolation
+          do iz=1,phicoarse%grid_param%nz
+            do dix = -1,0
+              do diy = -1,0
+                if ( (ix+(2*dix+1)+phicoarse%ix_min-1  < 1 ) .or. &
+                     (ix+(2*dix+1)+phicoarse%ix_min-1  > n ) ) then
+                  rhox = 0.5_rl
+                else
+                  rhox = 0.25_rl
+                end if
+                if ( (iy+(2*diy+1)+phicoarse%iy_min-1  < 1 ) .or. &
+                     (iy+(2*diy+1)+phicoarse%iy_min-1  > n ) ) then
+                  rhoy = 0.5_rl
+                else
+                  rhoy = 0.25_rl
+                end if
+                 phifine%s(iz,2*iy+diy,2*ix+dix) =      &
+                  phicoarse%s(iz,iy,ix) +                &
+                  rhox*(phicoarse%s(iz,iy,ix+(2*dix+1))  &
+                        - phicoarse%s(iz,iy,ix)) +       &
+                  rhoy*(phicoarse%s(iz,iy+(2*diy+1),ix)  &
+                        - phicoarse%s(iz,iy,ix))
+              end do
+            end do
+          end do
+#else
+          ! Fit a plane through the four neighbours of each
+          ! coarse grid point. Use the gradient of this plane and
+          ! the value of the field on the coarse grid point for
+          ! the linear interpolation
+          ! Calculate the displacement vectors
+#ifdef CARTESIANGEOMETRY
+          ! (ix-1, iy)
+          dx(1,1) = -1.0_rl
+          dx(1,2) =  0.0_rl
+          ! (ix+1, iy)
+          dx(2,1) = +1.0_rl
+          dx(2,2) =  0.0_rl
+          ! (ix, iy-1)
+          dx(3,1) =  0.0_rl
+          dx(3,2) = -1.0_rl
+          ! (ix, iy+1)
+          dx(4,1) =  0.0_rl
+          dx(4,2) = +1.0_rl
+#else
+          rho_i = 2.0_rl*(ix+(phicoarse%ix_min-1)-0.5_rl)/n-1.0_rl
+          sigma_j = 2.0_rl*(iy+(phicoarse%iy_min-1)-0.5_rl)/n-1.0_rl
+          if (abs(rho_i**2+sigma_j**2) > 1.0E-12) then
+            c1 = (1.0_rl+rho_i**2+sigma_j**2)/sqrt(rho_i**2+sigma_j**2)
+            c2 = sqrt(1.0_rl+rho_i**2+sigma_j**2)/sqrt(rho_i**2+sigma_j**2)
+          else
+            rho_i = 1.0_rl
+            sigma_j = 1.0_rl
+            c1 = sqrt(0.5_rl)
+            c2 = sqrt(0.5_rl)
+          end if
+          ! (ix-1, iy)
+          dx(1,1) = -c1*rho_i
+          dx(1,2) = +c2*sigma_j
+          ! (ix+1, iy)
+          dx(2,1) = +c1*rho_i
+          dx(2,2) = -c2*sigma_j
+          ! (ix, iy-1)
+          dx(3,1) = -c1*sigma_j
+          dx(3,2) = -c2*rho_i
+          ! (ix, iy+1)
+          dx(4,1) = +c1*sigma_j
+          dx(4,2) = +c2*rho_i
+          dx_fine(1,1) = 0.25_rl*(dx(1,1)+dx(3,1))
+          dx_fine(1,2) = 0.25_rl*(dx(1,2)+dx(3,2))
+          dx_fine(2,1) = 0.25_rl*(dx(2,1)+dx(3,1))
+          dx_fine(2,2) = 0.25_rl*(dx(2,2)+dx(3,2))
+          dx_fine(3,1) = 0.25_rl*(dx(1,1)+dx(4,1))
+          dx_fine(3,2) = 0.25_rl*(dx(1,2)+dx(4,2))
+          dx_fine(4,1) = 0.25_rl*(dx(2,1)+dx(4,1))
+          dx_fine(4,2) = 0.25_rl*(dx(2,2)+dx(4,2))
+#endif
+          ! Boundaries
+          if (ix-1+phicoarse%ix_min-1  < 1 ) then
+            dx(1,1) = 0.5_rl*dx(1,1)
+            dx(1,2) = 0.5_rl*dx(1,2)
+          end if
+          if (ix+1+phicoarse%ix_min-1  > n ) then
+            dx(2,1) = 0.5_rl*dx(2,1)
+            dx(2,2) = 0.5_rl*dx(2,2)
+          end if
+          if (iy-1+phicoarse%iy_min-1  < 1 ) then
+            dx(3,1) = 0.5_rl*dx(3,1)
+            dx(3,2) = 0.5_rl*dx(3,2)
+          end if
+          if (iy+1+phicoarse%iy_min-1  > n ) then
+            dx(4,1) = 0.5_rl*dx(4,1)
+            dx(4,2) = 0.5_rl*dx(4,2)
+          end if
+          ! Calculate matrix used for least squares linear fit
+          A(:,:) = 0.0_rl
+          do i = 1,4
+            do j=1,3
+              do k=1,3
+                A(j,k) = A(j,k) + dx(i,j)*dx(i,k)
+              end do
+            end do
+          end do
+          ! invert A
+          call invertA(A)
+          do iz=1,phicoarse%grid_param%nz
+            ! Calculate gradient on each level
+            dxu(1:2) = dx(1,1:2)*phicoarse%s(iz,iy  ,ix-1) &
+                     + dx(2,1:2)*phicoarse%s(iz,iy  ,ix+1) &
+                     + dx(3,1:2)*phicoarse%s(iz,iy-1,ix  ) &
+                     + dx(4,1:2)*phicoarse%s(iz,iy+1,ix  )
+            grad(:) = 0.0_rl
+            do j=1,2
+              do k=1,2
+                grad(j) = grad(j) + A(j,k)*dxu(k)
+              end do
+            end do
+            ! Use the gradient and the field value in the centre of
+            ! the coarse grid cell to interpolate to the fine grid
+            ! cells
+#ifdef CARTESIANGEOMETRY
+            do dix=-1,0
+              do diy=-1,0
+                phifine%s(iz,2*iy+diy,2*ix+dix) =       &
+                  phicoarse%s(iz,iy,ix)                 &
+                  + 0.25_rl*( grad(1)*(2.0*dix+1)    &
+                            + grad(2)*(2.0*diy+1))
+              end do
+            end do
+#else
+            phifine%s(iz,2*iy-1, 2*ix-1) = phicoarse%s(iz,iy,ix) + &
+                                         ( grad(1)*dx_fine(1,1)  + &
+                                           grad(2)*dx_fine(1,2) )
+            phifine%s(iz,2*iy-1, 2*ix  ) = phicoarse%s(iz,iy,ix) + &
+                                         ( grad(1)*dx_fine(2,1)  + &
+                                           grad(2)*dx_fine(2,2) )
+            phifine%s(iz,2*iy  , 2*ix-1) = phicoarse%s(iz,iy,ix) + &
+                                         ( grad(1)*dx_fine(3,1)  + &
+                                           grad(2)*dx_fine(3,2) )
+            phifine%s(iz,2*iy  , 2*ix  ) = phicoarse%s(iz,iy,ix) + &
+                                         ( grad(1)*dx_fine(4,1)  + &
+                                           grad(2)*dx_fine(4,2) )
+#endif
+          end do
+#endif
+        end do
+      end do
+    end subroutine loop_over_grid_linear
+
+  end subroutine prolongate
+  !------------------------------------------------------------------
+  ! Invert the 3x3 matrix A either using LaPack or the explicit
+  ! formula
+  !------------------------------------------------------------------
+  subroutine invertA(A)
+    implicit none
+    real(kind=rl), intent(inout), dimension(3,3) :: A
+    real(kind=rl), dimension(3,3) :: Anew
+    real(kind=rl) :: invdetA
+    integer :: ipiv(3), info
+    real(kind=rl) :: work(3)
+#ifdef USELAPACK
+    call DGETRF( 3, 3, A, 3, ipiv, info )
+    call DGETRI( 3, A, 3, ipiv, work, 3, info )
+#else
+    invdetA = 1.0_rl / ( A(1,1) * (A(3,3)*A(2,2) - A(3,2)*A(2,3)) &
+                       - A(2,1) * (A(3,3)*A(1,2) - A(3,2)*A(1,3)) &
+                       + A(3,1) * (A(2,3)*A(1,2) - A(2,2)*A(1,3)) )
+    Anew(1,1) =     A(3,3)*A(2,2) - A(3,2)*A(2,3)
+    Anew(1,2) = - ( A(3,3)*A(1,2) - A(3,2)*A(1,3) )
+    Anew(1,3) =     A(2,3)*A(1,2) - A(2,2)*A(1,3)
+    Anew(2,1) = - ( A(3,3)*A(2,1) - A(3,1)*A(2,3) )
+    Anew(2,2) =     A(3,3)*A(1,1) - A(3,1)*A(1,3)
+    Anew(2,3) = - ( A(2,3)*A(1,1) - A(2,1)*A(1,3) )
+    Anew(3,1) =     A(3,2)*A(2,1) - A(3,1)*A(2,2)
+    Anew(3,2) = - ( A(3,2)*A(1,1) - A(3,1)*A(1,2) )
+    Anew(3,3) =     A(2,2)*A(1,1) - A(2,1)*A(1,2)
+    A(:,:) = invdetA*Anew(:,:)
+#endif
+  end subroutine invertA
+
+!==================================================================
+! Multigrid V-cycle
+!==================================================================
+  recursive subroutine mg_vcycle_mnh(b,u,r,finelevel,splitlevel,level,m)
+    use MODE_OPENACC_SET_DEVICE
+    implicit none
+    integer, intent(in)                                     :: finelevel
+    type(scalar3d), intent(inout), dimension(finelevel,0:pproc) :: b
+    type(scalar3d), intent(inout), dimension(finelevel,0:pproc) :: u
+    type(scalar3d), intent(inout), dimension(finelevel,0:pproc) :: r
+    integer, intent(in)                                     :: splitlevel
+    integer, intent(in)                                     :: level
+    integer, intent(in)                                     :: m
+    !local var
+    integer                                                 :: n_gridpoints
+    integer                                                 :: nlocalx, nlocaly
+    integer                                                 :: halo_size
+
+    real , dimension(:,:,:) , pointer , contiguous ::  zu_level_1_m_st,zu_level_1_m_1_st
+
+    nlocalx = u(level,m)%ix_max-u(level,m)%ix_min+1
+    nlocaly = u(level,m)%iy_max-u(level,m)%iy_min+1
+    halo_size = u(level,m)%halo_size
+    n_gridpoints = (nlocalx+2*halo_size) &
+                 * (nlocaly+2*halo_size) &
+                 * (u(level,m)%grid_param%nz+2)
+
+    if (level > 1) then
+      ! Perform n_presmooth smoothing steps
+      call start_timer(t_smooth(level,m))
+      call start_timer(t_total(level,m))
+      call smooth_mnh(level,m,mg_param%n_presmooth, &
+                  DIRECTION_FORWARD, &
+                  b(level,m),u(level,m))
+      call finish_timer(t_total(level,m))
+      call finish_timer(t_smooth(level,m))
+      ! Calculate residual
+      call start_timer(t_residual(level,m))
+      call start_timer(t_total(level,m))
+      call calculate_residual_mnh(level,m,b(level,m),u(level,m),r(level,m))
+      call finish_timer(t_total(level,m))
+      call finish_timer(t_residual(level,m))
+      ! Restrict residual
+      call start_timer(t_restrict(level,m))
+      call start_timer(t_total(level,m))
+      call restrict_mnh(r(level,m),b(level-1,m))
+      call finish_timer(t_total(level,m))
+      call finish_timer(t_restrict(level,m))
+      if ( ((level-1) .le. splitlevel) .and. (m > 0) ) then
+        ! Collect data on coarser level
+        call start_timer(t_total(level,m))
+        call collect(level-1,m,b(level-1,m),b(level-1,m-1))
+!!$        call print_scalaprod2(level-1, m  , b(level-1,m)  , "After collect b(level-1,m  )=" )
+!!$        call print_scalaprod2(level-1, m-1, b(level-1,m-1), "After collect b(level-1,m-1)=" )
+        call finish_timer(t_total(level,m))
+        ! Set initial solution on coarser level to zero (incl. halos!)
+        if (LUseO) u(level-1,m-1)%s(:,:,:) = 0.0_rl
+        if (LUseT) then
+           zu_level_1_m_1_st => u(level-1,m-1)%st(:,:,:)
+           !$acc kernels
+           zu_level_1_m_1_st(:,:,:) = 0.0_rl
+           !$acc end kernels
+        end if
+        ! solve on coarser grid
+        call mg_vcycle_mnh(b,u,r,finelevel,splitlevel,level-1,m-1)
+        ! Distribute data on coarser grid
+        call start_timer(t_total(level,m))
+        call distribute(level-1,m,u(level-1,m-1),u(level-1,m))
+!!$        call print_scalaprod2(level-1, m  , u(level-1,m)  , "After distribute u(level-1,m  )=" )
+!!$        call print_scalaprod2(level-1, m-1, u(level-1,m-1), "After distribute u(level-1,m-1)=" )       
+        call finish_timer(t_total(level,m))
+      else
+        ! Set initial solution on coarser level to zero (incl. halos!)
+        if (LUseO) u(level-1,m)%s(:,:,:) = 0.0_rl
+        if (LUseT) then
+           zu_level_1_m_st =>  u(level-1,m)%st(:,:,:)
+           !$acc kernels 
+           zu_level_1_m_st(:,:,:) = 0.0_rl
+           !$acc end kernels
+        end if
+        ! solve on coarser grid
+        ! switch from GPU to CPU if level == iswitch_cpu_gpu 
+        if (level .EQ. iswitch_cpu_gpu ) then
+           !print*,' enter mg_vcycle_mnh level=', iswitch_cpu_gpu
+           !call MNH_OPENACC_GET_DEVICE()
+           call MNH_OPENACC_SET_DEVICE_HOST()
+           !call MNH_OPENACC_GET_DEVICE()
+        end if
+        call mg_vcycle_mnh(b,u,r,finelevel,splitlevel,level-1,m)       
+        if (level .EQ. iswitch_cpu_gpu) then
+           !print*,' exit mg_vcycle_mnh level=', iswitch_cpu_gpu
+           !call MNH_OPENACC_GET_DEVICE()
+           call MNH_OPENACC_SET_DEVICE_DEFAULT()
+           !call MNH_OPENACC_GET_DEVICE()
+        end if
+      end if
+      ! Prolongate error
+      call start_timer(t_prolongate(level,m))
+      call start_timer(t_total(level,m))
+      call haloswap_mnh(level-1,m,u(level-1,m))
+      call boundary_mnh(u(level-1,m))
+!!$      call print_scalaprod2(level-1 , m  , u(level-1,m)  , "Befor prolongate_mnh u(level-1,m  )=" )
+!!$      call print_scalaprod2(level   , m  , r(level  ,m)  , "Befor prolongate_mnh r(level  ,m  )=" )
+      call prolongate_mnh(level,m,u(level-1,m),r(level,m))
+!!$      call print_scalaprod2(level-1 , m  , u(level-1,m)  , "After prolongate_mnh u(level-1,m  )=" )
+!!$      call print_scalaprod2(level   , m  , r(level  ,m)  , "After prolongate_mnh r(level  ,m  )=" )
+      call finish_timer(t_total(level,m))
+      call finish_timer(t_prolongate(level,m))
+      ! Add error to fine grid solution
+      call start_timer(t_addcorr(level,m))
+      call start_timer(t_total(level,m))
+      if (LUseO) call daxpy(n_gridpoints,1.0_rl,r(level,m)%s,1,u(level,m)%s,1)
+      if (LUseT) call daxpy(n_gridpoints,1.0_rl,r(level,m)%st,1,u(level,m)%st,1)
+      call finish_timer(t_total(level,m))
+      call finish_timer(t_addcorr(level,m))
+      ! Perform n_postsmooth smoothing steps
+      call start_timer(t_smooth(level,m))
+      call start_timer(t_total(level,m))
+      call smooth_mnh(level,m, &
+                  mg_param%n_postsmooth, &
+                  DIRECTION_BACKWARD, &
+                  b(level,m),u(level,m))
+      call finish_timer(t_total(level,m))
+      call finish_timer(t_smooth(level,m))
+    else
+      call start_timer(t_coarsesolve(level,m))
+      call start_timer(t_total(level,m))
+      if (mg_param%coarsegridsolver == COARSEGRIDSOLVER_CG) then
+        call cg_solve_mnh(level,m,b(level,m),u(level,m))
+!!$        call print_scalaprod2(level, m , u(level,m), "After cg_solve_mnh u=(level,m)" )
+      else if (mg_param%coarsegridsolver == COARSEGRIDSOLVER_SMOOTHER) then
+        ! Smooth on coarsest level
+        call smooth_mnh(level,m, &
+                    mg_param%n_coarsegridsmooth,     &
+                    DIRECTION_FORWARD, &
+                    b(level,m),u(level,m))
+      end if
+      call finish_timer(t_total(level,m))
+      call finish_timer(t_coarsesolve(level,m))
+    end if
+
+  end subroutine mg_vcycle_mnh
+!==================================================================
+! Multigrid V-cycle
+!==================================================================
+  recursive subroutine mg_vcycle(b,u,r,finelevel,splitlevel,level,m)
+    implicit none
+    integer, intent(in)                                     :: finelevel
+    type(scalar3d), intent(inout), dimension(finelevel,0:pproc) :: b
+    type(scalar3d), intent(inout), dimension(finelevel,0:pproc) :: u
+    type(scalar3d), intent(inout), dimension(finelevel,0:pproc) :: r
+    integer, intent(in)                                     :: splitlevel
+    integer, intent(in)                                     :: level
+    integer, intent(in)                                     :: m
+    integer                                                 :: n_gridpoints
+    integer                                                 :: nlocalx, nlocaly
+    integer                                                 :: halo_size
+
+    nlocalx = u(level,m)%ix_max-u(level,m)%ix_min+1
+    nlocaly = u(level,m)%iy_max-u(level,m)%iy_min+1
+    halo_size = u(level,m)%halo_size
+    n_gridpoints = (nlocalx+2*halo_size) &
+                 * (nlocaly+2*halo_size) &
+                 * (u(level,m)%grid_param%nz+2)
+
+    if (level > 1) then
+      ! Perform n_presmooth smoothing steps
+      call start_timer(t_smooth(level,m))
+      call start_timer(t_total(level,m))
+      call smooth(level,m,mg_param%n_presmooth, &
+                  DIRECTION_FORWARD, &
+                  b(level,m),u(level,m))
+      call finish_timer(t_total(level,m))
+      call finish_timer(t_smooth(level,m))
+      ! Calculate residual
+      call start_timer(t_residual(level,m))
+      call start_timer(t_total(level,m))
+      call calculate_residual(level,m,b(level,m),u(level,m),r(level,m))
+      call finish_timer(t_total(level,m))
+      call finish_timer(t_residual(level,m))
+      ! Restrict residual
+      call start_timer(t_restrict(level,m))
+      call start_timer(t_total(level,m))
+      call restrict(r(level,m),b(level-1,m))
+      call finish_timer(t_total(level,m))
+      call finish_timer(t_restrict(level,m))
+      if ( ((level-1) .le. splitlevel) .and. (m > 0) ) then
+        ! Collect data on coarser level
+        call start_timer(t_total(level,m))
+        call collect(level-1,m,b(level-1,m),b(level-1,m-1))
+        call haloswap_mnh(level-1,m-1,b(level-1,m-1))
+        call finish_timer(t_total(level,m))
+        ! Set initial solution on coarser level to zero (incl. halos!)
+        if (LUseO) u(level-1,m-1)%s(:,:,:) = 0.0_rl
+        if (LUseT) u(level-1,m-1)%st(:,:,:) = 0.0_rl
+        ! solve on coarser grid
+        call mg_vcycle(b,u,r,finelevel,splitlevel,level-1,m-1)
+        ! Distribute data on coarser grid
+        call start_timer(t_total(level,m))
+        call distribute(level-1,m,u(level-1,m-1),u(level-1,m))
+        call haloswap(level-1,m,u(level-1,m))
+        call finish_timer(t_total(level,m))
+      else
+        ! Set initial solution on coarser level to zero (incl. halos!)
+        if (LUseO) u(level-1,m)%s(:,:,:) = 0.0_rl
+        if (LUseT) u(level-1,m)%st(:,:,:) = 0.0_rl
+        ! solve on coarser grid
+        call mg_vcycle(b,u,r,finelevel,splitlevel,level-1,m)
+      end if
+      ! Prolongate error
+      call start_timer(t_prolongate(level,m))
+      call start_timer(t_total(level,m))
+      call prolongate(level,m,u(level-1,m),r(level,m))
+      call finish_timer(t_total(level,m))
+      call finish_timer(t_prolongate(level,m))
+      ! Add error to fine grid solution
+      call start_timer(t_addcorr(level,m))
+      call start_timer(t_total(level,m))
+      if (LUseO) call daxpy(n_gridpoints,1.0_rl,r(level,m)%s,1,u(level,m)%s,1)
+      if (LUseT) call daxpy(n_gridpoints,1.0_rl,r(level,m)%st,1,u(level,m)%st,1)
+      call finish_timer(t_total(level,m))
+      call finish_timer(t_addcorr(level,m))
+      ! Perform n_postsmooth smoothing steps
+      call start_timer(t_smooth(level,m))
+      call start_timer(t_total(level,m))
+      call smooth(level,m, &
+                  mg_param%n_postsmooth, &
+                  DIRECTION_BACKWARD, &
+                  b(level,m),u(level,m))
+      call finish_timer(t_total(level,m))
+      call finish_timer(t_smooth(level,m))
+    else
+      call start_timer(t_coarsesolve(level,m))
+      call start_timer(t_total(level,m))
+      if (mg_param%coarsegridsolver == COARSEGRIDSOLVER_CG) then
+        call cg_solve(level,m,b(level,m),u(level,m))
+      else if (mg_param%coarsegridsolver == COARSEGRIDSOLVER_SMOOTHER) then
+        ! Smooth on coarsest level
+        call smooth(level,m, &
+                    mg_param%n_coarsegridsmooth,     &
+                    DIRECTION_FORWARD, &
+                    b(level,m),u(level,m))
+      end if
+      call finish_timer(t_total(level,m))
+      call finish_timer(t_coarsesolve(level,m))
+    end if
+
+  end subroutine mg_vcycle
+
+!==================================================================
+! Test halo exchanges
+!==================================================================
+  recursive subroutine mg_vcyclehaloswaponly(b,u,r,finelevel,splitlevel,level,m)
+    implicit none
+    integer, intent(in)                                     :: finelevel
+    type(scalar3d), intent(inout), dimension(finelevel,0:pproc) :: b
+    type(scalar3d), intent(inout), dimension(finelevel,0:pproc) :: u
+    type(scalar3d), intent(inout), dimension(finelevel,0:pproc) :: r
+    integer, intent(in)                                     :: splitlevel
+    integer, intent(in)                                     :: level
+    integer, intent(in)                                     :: m
+    integer, parameter :: nhaloswap = 100
+    integer :: i
+    integer :: ierr
+
+    if (level > 1) then
+      call mpi_barrier(MPI_COMM_HORIZ,ierr)
+      do i=1,nhaloswap
+        call haloswap(level,m,u(level,m))
+      end do
+      call mpi_barrier(MPI_COMM_HORIZ,ierr)
+      if ( ((level-1) .le. splitlevel) .and. (m > 0) ) then
+        call mpi_barrier(MPI_COMM_HORIZ,ierr)
+        do i=1,nhaloswap
+          call haloswap(level-1,m,u(level-1,m))
+        end do
+        call mpi_barrier(MPI_COMM_HORIZ,ierr)
+        call mg_vcyclehaloswaponly(b,u,r,finelevel,splitlevel,level-1,m-1)
+      else
+        call mg_vcyclehaloswaponly(b,u,r,finelevel,splitlevel,level-1,m)
+      end if
+    else
+      ! Haloswap on coarsest level
+      call mpi_barrier(MPI_COMM_HORIZ,ierr)
+      do i=1,nhaloswap
+        call haloswap(level,m,u(level,m))
+      end do
+      call mpi_barrier(MPI_COMM_HORIZ,ierr)
+    end if
+
+  end subroutine mg_vcyclehaloswaponly
+
+!==================================================================
+! Multigrid solve
+! Assumes that ghosts in initial solution are up-to-date
+!==================================================================
+  subroutine mg_solve_mnh(bRHS,usolution,solver_param)
+    implicit none
+    type(scalar3d), intent(in)      :: bRHS
+    type(scalar3d), intent(inout)   :: usolution
+    type(solver_parameters), intent(in) :: solver_param
+    integer :: solvertype
+    real(kind=rl)  :: resreduction
+    integer :: maxiter
+    integer :: n_gridpoints
+    integer :: iter, level, finelevel, splitlevel
+    real(kind=rl) :: res_old, res_new, res_initial , mean_initial , norm_initial
+    logical :: solverconverged = .false.
+    integer :: nlocalx, nlocaly
+    integer :: halo_size
+    type(time) :: t_prec, t_res, t_apply, t_l2norm, t_scalprod, t_mainloop
+    type(scalar3d) :: pp
+    type(scalar3d) :: q
+    type(scalar3d) :: z_one 
+    real(kind=rl) :: alpha, beta, pq, rz, rz_old
+    integer :: ierr
+    real(kind=rl) , pointer , contiguous , dimension(:,:,:) :: z_one_st
+
+    solvertype = solver_param%solvertype
+    resreduction = solver_param%resreduction
+    maxiter = solver_param%maxiter
+    nlocalx = usolution%ix_max - usolution%ix_min+1
+    nlocaly = usolution%iy_max - usolution%iy_min+1
+    halo_size = usolution%halo_size
+
+    level = mg_param%n_lev
+    finelevel = level
+    splitlevel = mg_param%lev_split
+
+    ! Initialise timers
+    call initialise_timer(t_prec,"t_prec")
+    call initialise_timer(t_apply,"t_apply")
+    call initialise_timer(t_l2norm,"t_l2norm")
+    call initialise_timer(t_scalprod,"t_scalarprod")
+    call initialise_timer(t_res,"t_residual")
+    call initialise_timer(t_mainloop,"t_mainloop")
+
+    n_gridpoints = (nlocalx+2*halo_size) &
+                 * (nlocaly+2*halo_size) &
+                 * (usolution%grid_param%nz+2)
+    !
+    ! Init 1 vector = z_one
+    call create_scalar3d(MPI_COMM_HORIZ,bRHS%grid_param,halo_size,z_one)
+    if (LUseO) then
+       z_one%s(:,:,:) = 0.0_rl
+       z_one%s(1:z_one%grid_param%nz,1:z_one%icompy_max,1:z_one%icompx_max) = 1.0_rl
+    end if
+    if (LUseT) then       
+       z_one_st => z_one%st
+       !$acc kernels
+       z_one_st(:,:,:) = 0.0_rl
+       z_one_st(1:z_one%icompx_max,1:z_one%icompy_max,1:z_one%grid_param%nz) = 1.0_rl
+       !$acc end kernels
+    end if
+    !   Mean / Norm of B
+    call scalarprod_mnh(pproc,z_one,z_one, mean_initial ) 
+    call scalarprod_mnh(pproc,z_one,bRHS, mean_initial ) 
+    norm_initial =  l2norm_mnh(bRHS,.true.)
+    mean_initial =  mean_initial / (( z_one%grid_param%nz ) * ( z_one%grid_param%n )**2)
+    norm_initial =  mean_initial / norm_initial
+    if (LMean) then
+       ! b <- b -mean_initial * z_one
+       if (LUseO) call daxpy(n_gridpoints,-mean_initial,z_one%s,1,bRHS%s,1)
+       if (LUseT) call daxpy(n_gridpoints,-mean_initial,z_one%st,1,bRHS%st,1)
+       call scalarprod_mnh(pproc,z_one,bRHS, mean_initial ) 
+    endif
+    !
+    ! Copy b to b(1)
+    ! Copy usolution to u(1)
+    if (LUseO) call dcopy(n_gridpoints,bRHS%s,1,xb_mg(level,pproc)%s,1)
+    if (LUseT) call dcopy(n_gridpoints,bRHS%st,1,xb_mg(level,pproc)%st,1)
+    if (LUseO) call dcopy(n_gridpoints,usolution%s,1,xu_mg(level,pproc)%s,1)
+    if (LUseT) call dcopy(n_gridpoints,usolution%st,1,xu_mg(level,pproc)%st,1)
+
+! Scale with volume of grid cells
+    call volscale_scalar3d_mnh(xb_mg(level,pproc),1)
+    call scalarprod_mnh(pproc,z_one,xb_mg(level,pproc), mean_initial )
+
+    call start_timer(t_res)
+    call calculate_residual_mnh(level, pproc, &
+                            xb_mg(level,pproc),xu_mg(level,pproc),xr_mg(level,pproc))
+    call finish_timer(t_res)
+    call start_timer(t_l2norm)
+    res_initial = l2norm_mnh(xr_mg(level,pproc),.true.)
+    call finish_timer(t_l2norm)
+    res_old = res_initial
+    if (mg_param%verbose > 0) then
+      if (i_am_master_mpi) then
+        write(STDOUT,'(" *** Multigrid solver ***")')
+        write(STDOUT,'(" <MG> Initial residual : ",E10.5)') res_initial
+      end if
+    end if
+    if (mg_param%verbose > 0) then
+      if (i_am_master_mpi) then
+        write(STDOUT,'(" <MG>   iter :   residual         rho")')
+        write(STDOUT,'(" <MG> --------------------------------")')
+      end if
+    end if
+
+    call mpi_barrier(MPI_COMM_WORLD,ierr)
+    call start_timer(t_mainloop)
+    if (solvertype == SOLVER_CG) then
+      ! NB: b(level,pproc) will be used as r in the following
+      call create_scalar3d(MPI_COMM_HORIZ,bRHS%grid_param,halo_size,pp)
+      call create_scalar3d(MPI_COMM_HORIZ,bRHS%grid_param,halo_size,q)
+      ! Apply preconditioner: Calculate p = M^{-1} r
+      ! (1) copy b <- r
+      if (LUseO) call dcopy(n_gridpoints,xr_mg(level,pproc)%s,1,xb_mg(level,pproc)%s,1)
+      if (LUseT) call dcopy(n_gridpoints,xr_mg(level,pproc)%st,1,xb_mg(level,pproc)%st,1)
+      ! (2) set u <- 0
+      if (LUseO) xu_mg(level,pproc)%s(:,:,:) = 0.0_rl
+      if (LUseT) xu_mg(level,pproc)%st(:,:,:) = 0.0_rl
+      ! (3) Call MG Vcycle
+      call start_timer(t_prec)
+      call mg_vcycle_mnh(xb_mg,xu_mg,xr_mg,finelevel,splitlevel,level,pproc)
+      call finish_timer(t_prec)
+      ! (4) copy pp <- u (=solution from MG Vcycle)
+      if (LUseO) call dcopy(n_gridpoints,xu_mg(level,pproc)%s,1,pp%s,1)
+      if (LUseT) call dcopy(n_gridpoints,xu_mg(level,pproc)%st,1,pp%st,1)
+      ! Calculate rz_old = <pp,b>
+      call start_timer(t_scalprod)
+      call scalarprod_mnh(pproc,pp,xb_mg(level,pproc),rz_old)
+      call finish_timer(t_scalprod)
+      do iter = 1, maxiter
+        ! Apply matrix q <- A.pp
+        call start_timer(t_apply)
+        call apply_mnh(pp,q)
+        call finish_timer(t_apply)
+        ! Calculate pq <- <pp,q>
+        call start_timer(t_scalprod)
+        call scalarprod_mnh(pproc,pp,q,pq)
+        call finish_timer(t_scalprod)
+        alpha = rz_old/pq
+        ! x <- x + alpha*p
+        if (LUseO) call daxpy(n_gridpoints,alpha,pp%s,1,usolution%s,1)
+        if (LUseT) call daxpy(n_gridpoints,alpha,pp%st,1,usolution%st,1)
+        ! b <- b - alpha*q
+        if (LUseO) call daxpy(n_gridpoints,-alpha,q%s,1,xb_mg(level,pproc)%s,1)
+        if (LUseT) call daxpy(n_gridpoints,-alpha,q%st,1,xb_mg(level,pproc)%st,1)
+        ! Calculate norm of residual and exit if it has been
+        ! reduced sufficiently
+        call start_timer(t_l2norm)
+        res_new = l2norm_mnh(xb_mg(level,pproc),.true.)
+        call finish_timer(t_l2norm)
+        if (mg_param%verbose > 1) then
+          if (i_am_master_mpi) then
+            write(STDOUT,'(" <MG> ",I7," : ",E10.5,"  ",F10.5)') iter, res_new, res_new/res_old
+          end if
+        end if
+        if (res_new/res_initial < resreduction) then
+          solverconverged = .true.
+          exit
+        end if
+        res_old = res_new
+        ! Apply preconditioner q <- M^{-1} b
+        ! (1) Initialise solution u <- 0
+        if (LUseO) xu_mg(level,pproc)%s(:,:,:) = 0.0_rl
+        if (LUseT) xu_mg(level,pproc)%st(:,:,:) = 0.0_rl
+        ! (2) Call MG Vcycle
+        call start_timer(t_prec)
+        call mg_vcycle_mnh(xb_mg,xu_mg,xr_mg,finelevel,splitlevel,level,pproc)
+        call finish_timer(t_prec)
+        ! (3) copy q <- u (solution from MG Vcycle)
+        if (LUseO) call dcopy(n_gridpoints,xu_mg(level,pproc)%s,1,q%s,1)
+        if (LUseT) call dcopy(n_gridpoints,xu_mg(level,pproc)%st,1,q%st,1)
+        call start_timer(t_scalprod)
+        call scalarprod_mnh(pproc,q,xb_mg(level,pproc),rz)
+        call finish_timer(t_scalprod)
+        beta = rz/rz_old
+        ! p <- beta*p
+        if (LUseO) call dscal(n_gridpoints,beta,pp%s,1)
+        if (LUseT) call dscal(n_gridpoints,beta,pp%st,1)
+        ! p <- p+q
+        if (LUseO) call daxpy(n_gridpoints,1.0_rl,q%s,1,pp%s,1)
+        if (LUseT) call daxpy(n_gridpoints,1.0_rl,q%st,1,pp%st,1)
+        rz_old = rz
+      end do
+      call destroy_scalar3d(pp)
+      call destroy_scalar3d(q)
+    else if (solvertype == SOLVER_RICHARDSON) then
+      ! Iterate until convergence
+      do iter=1,maxiter
+        call start_timer(t_prec)
+        call mg_vcycle_mnh(xb_mg,xu_mg,xr_mg,finelevel,splitlevel,level,pproc)
+        call finish_timer(t_prec)
+        call start_timer(t_res)
+        ! Ghosts are up-to-date here, so no need for halo exchange
+        call calculate_residual_mnh(level, pproc, &
+                                xb_mg(level,pproc),xu_mg(level,pproc),xr_mg(level,pproc))
+        call finish_timer(t_res)
+        call start_timer(t_l2norm)
+        res_new = l2norm_mnh(xr_mg(level,pproc),.true.)
+        call finish_timer(t_l2norm)
+        if (mg_param%verbose > 1) then
+          if (i_am_master_mpi) then
+            write(STDOUT,'(" <MG> ",I7," : ",E10.5,"  ",F10.5)') iter, res_new, res_new/res_old
+          end if
+        end if
+        if (res_new/res_initial < resreduction) then
+          solverconverged = .true.
+          exit
+        end if
+        res_old = res_new
+      end do
+      ! Copy u(1) to usolution
+      if (LUseO) call dcopy(n_gridpoints,xu_mg(level,pproc)%s,1,usolution%s,1)
+      if (LUseT) call dcopy(n_gridpoints,xu_mg(level,pproc)%st,1,usolution%st,1)
+    end if
+
+    call destroy_scalar3d(z_one)
+
+    call finish_timer(t_mainloop)
+
+    ! Print out solver information
+    if (mg_param%verbose > 0) then
+      if (solverconverged) then
+        if (i_am_master_mpi) then
+          write(STDOUT,'(" <MG> Final residual    ||r|| = ",E12.6)') res_new
+          write(STDOUT,'(" <MG> Solver converged in ",I7," iterations rho_{avg} = ",F10.5)') &
+          iter, (res_new/res_initial)**(1./(iter))
+        end if
+      else
+        if (i_am_master_mpi) then
+          write(STDOUT,'(" <MG> Solver failed to converge after ",I7," iterations rho_{avg} = ",F10.5)') &
+          maxiter, (res_new/res_initial)**(1./(iter))
+        end if
+      end if
+    end if
+    call print_timerinfo("--- Main iteration timing results ---")
+    call print_elapsed(t_apply,.True.,1.0_rl)
+    call print_elapsed(t_res,.True.,1.0_rl)
+    call print_elapsed(t_prec,.True.,1.0_rl)
+    call print_elapsed(t_l2norm,.True.,1.0_rl)
+    call print_elapsed(t_scalprod,.True.,1.0_rl)
+    call print_elapsed(t_mainloop,.True.,1.0_rl)
+    if (i_am_master_mpi) write(STDOUT,'("")')
+  end subroutine mg_solve_mnh
+
+  subroutine mg_solve(bRHS,usolution,solver_param)
+    implicit none
+    type(scalar3d), intent(in)      :: bRHS
+    type(scalar3d), intent(inout)   :: usolution
+    type(solver_parameters), intent(in) :: solver_param
+    integer :: solvertype
+    real(kind=rl)  :: resreduction
+    integer :: maxiter
+    integer :: n_gridpoints
+    integer :: iter, level, finelevel, splitlevel
+    real(kind=rl) :: res_old, res_new, res_initial
+    logical :: solverconverged = .false.
+    integer :: nlocalx, nlocaly
+    integer :: halo_size
+    type(time) :: t_prec, t_res, t_apply, t_l2norm, t_scalprod, t_mainloop
+    type(scalar3d) :: pp
+    type(scalar3d) :: q
+    real(kind=rl) :: alpha, beta, pq, rz, rz_old
+    integer :: ierr
+
+    solvertype = solver_param%solvertype
+    resreduction = solver_param%resreduction
+    maxiter = solver_param%maxiter
+    nlocalx = usolution%ix_max - usolution%ix_min+1
+    nlocaly = usolution%iy_max - usolution%iy_min+1
+    halo_size = usolution%halo_size
+
+    level = mg_param%n_lev
+    finelevel = level
+    splitlevel = mg_param%lev_split
+
+    ! Initialise timers
+    call initialise_timer(t_prec,"t_prec")
+    call initialise_timer(t_apply,"t_apply")
+    call initialise_timer(t_l2norm,"t_l2norm")
+    call initialise_timer(t_scalprod,"t_scalarprod")
+    call initialise_timer(t_res,"t_residual")
+    call initialise_timer(t_mainloop,"t_mainloop")
+
+    ! Copy b to b(1)
+    ! Copy usolution to u(1)
+    n_gridpoints = (nlocalx+2*halo_size) &
+                 * (nlocaly+2*halo_size) &
+                 * (usolution%grid_param%nz+2)
+    call dcopy(n_gridpoints,bRHS%s,1,xb_mg(level,pproc)%s,1)
+    call dcopy(n_gridpoints,usolution%s,1,xu_mg(level,pproc)%s,1)
+! Scale with volume of grid cells
+    call volscale_scalar3d(xb_mg(level,pproc),1)
+    call start_timer(t_res)
+    call calculate_residual(level, pproc, &
+                            xb_mg(level,pproc),xu_mg(level,pproc),xr_mg(level,pproc))
+    call finish_timer(t_res)
+    call start_timer(t_l2norm)
+    res_initial = l2norm(xr_mg(level,pproc),.true.)
+    call finish_timer(t_l2norm)
+    res_old = res_initial
+    if (mg_param%verbose > 0) then
+      if (i_am_master_mpi) then
+        write(STDOUT,'(" *** Multigrid solver ***")')
+        write(STDOUT,'(" <MG> Initial residual : ",E10.5)') res_initial
+      end if
+    end if
+    if (mg_param%verbose > 0) then
+      if (i_am_master_mpi) then
+        write(STDOUT,'(" <MG>   iter :   residual         rho")')
+        write(STDOUT,'(" <MG> --------------------------------")')
+      end if
+    end if
+
+    call mpi_barrier(MPI_COMM_WORLD,ierr)
+    call start_timer(t_mainloop)
+    if (solvertype == SOLVER_CG) then
+      ! NB: b(level,pproc) will be used as r in the following
+      call create_scalar3d(MPI_COMM_HORIZ,bRHS%grid_param,halo_size,pp)
+      call create_scalar3d(MPI_COMM_HORIZ,bRHS%grid_param,halo_size,q)
+      ! Apply preconditioner: Calculate p = M^{-1} r
+      ! (1) copy b <- r
+      call dcopy(n_gridpoints,xr_mg(level,pproc)%s,1,xb_mg(level,pproc)%s,1)
+      ! (2) set u <- 0
+      xu_mg(level,pproc)%s(:,:,:) = 0.0_rl
+      ! (3) Call MG Vcycle
+      call start_timer(t_prec)
+      call mg_vcycle(xb_mg,xu_mg,xr_mg,finelevel,splitlevel,level,pproc)
+      call finish_timer(t_prec)
+      ! (4) copy pp <- u (=solution from MG Vcycle)
+      call dcopy(n_gridpoints,xu_mg(level,pproc)%s,1,pp%s,1)
+      ! Calculate rz_old = <pp,b>
+      call start_timer(t_scalprod)
+      call scalarprod(pproc,pp,xb_mg(level,pproc),rz_old)
+      call finish_timer(t_scalprod)
+      do iter = 1, maxiter
+        ! Apply matrix q <- A.pp
+        call start_timer(t_apply)
+        call apply(pp,q)
+        call finish_timer(t_apply)
+        ! Calculate pq <- <pp,q>
+        call start_timer(t_scalprod)
+        call scalarprod(pproc,pp,q,pq)
+        call finish_timer(t_scalprod)
+        alpha = rz_old/pq
+        ! x <- x + alpha*p
+        call daxpy(n_gridpoints,alpha,pp%s,1,usolution%s,1)
+        ! b <- b - alpha*q
+        call daxpy(n_gridpoints,-alpha,q%s,1,xb_mg(level,pproc)%s,1)
+        ! Calculate norm of residual and exit if it has been
+        ! reduced sufficiently
+        call start_timer(t_l2norm)
+        res_new = l2norm(xb_mg(level,pproc),.true.)
+        call finish_timer(t_l2norm)
+        if (mg_param%verbose > 1) then
+          if (i_am_master_mpi) then
+            write(STDOUT,'(" <MG> ",I7," : ",E10.5,"  ",F10.5)') iter, res_new, res_new/res_old
+          end if
+        end if
+        if (res_new/res_initial < resreduction) then
+          solverconverged = .true.
+          exit
+        end if
+        res_old = res_new
+        ! Apply preconditioner q <- M^{-1} b
+        ! (1) Initialise solution u <- 0
+        xu_mg(level,pproc)%s(:,:,:) = 0.0_rl
+        ! (2) Call MG Vcycle
+        call start_timer(t_prec)
+        call mg_vcycle(xb_mg,xu_mg,xr_mg,finelevel,splitlevel,level,pproc)
+        call finish_timer(t_prec)
+        ! (3) copy q <- u (solution from MG Vcycle)
+        call dcopy(n_gridpoints,xu_mg(level,pproc)%s,1,q%s,1)
+        call start_timer(t_scalprod)
+        call scalarprod(pproc,q,xb_mg(level,pproc),rz)
+        call finish_timer(t_scalprod)
+        beta = rz/rz_old
+        ! p <- beta*p
+        call dscal(n_gridpoints,beta,pp%s,1)
+        ! p <- p+q
+        call daxpy(n_gridpoints,1.0_rl,q%s,1,pp%s,1)
+        rz_old = rz
+      end do
+      call destroy_scalar3d(pp)
+      call destroy_scalar3d(q)
+    else if (solvertype == SOLVER_RICHARDSON) then
+      ! Iterate until convergence
+      do iter=1,maxiter
+        call start_timer(t_prec)
+        call mg_vcycle(xb_mg,xu_mg,xr_mg,finelevel,splitlevel,level,pproc)
+        call finish_timer(t_prec)
+        call start_timer(t_res)
+        ! Ghosts are up-to-date here, so no need for halo exchange
+        call calculate_residual(level, pproc, &
+                                xb_mg(level,pproc),xu_mg(level,pproc),xr_mg(level,pproc))
+        call finish_timer(t_res)
+        call start_timer(t_l2norm)
+        res_new = l2norm(xr_mg(level,pproc),.true.)
+        call finish_timer(t_l2norm)
+        if (mg_param%verbose > 1) then
+          if (i_am_master_mpi) then
+            write(STDOUT,'(" <MG> ",I7," : ",E10.5,"  ",F10.5)') iter, res_new, res_new/res_old
+          end if
+        end if
+        if (res_new/res_initial < resreduction) then
+          solverconverged = .true.
+          exit
+        end if
+        res_old = res_new
+      end do
+      ! Copy u(1) to usolution
+      call dcopy(n_gridpoints,xu_mg(level,pproc)%s,1,usolution%s,1)
+    end if
+    call finish_timer(t_mainloop)
+
+    ! Print out solver information
+    if (mg_param%verbose > 0) then
+      if (solverconverged) then
+        if (i_am_master_mpi) then
+          write(STDOUT,'(" <MG> Final residual    ||r|| = ",E12.6)') res_new
+          write(STDOUT,'(" <MG> Solver converged in ",I7," iterations rho_{avg} = ",F10.5)') &
+          iter, (res_new/res_initial)**(1./(iter))
+        end if
+      else
+        if (i_am_master_mpi) then
+          write(STDOUT,'(" <MG> Solver failed to converge after ",I7," iterations rho_{avg} = ",F10.5)') &
+          maxiter, (res_new/res_initial)**(1./(iter))
+        end if
+      end if
+    end if
+    call print_timerinfo("--- Main iteration timing results ---")
+    call print_elapsed(t_apply,.True.,1.0_rl)
+    call print_elapsed(t_res,.True.,1.0_rl)
+    call print_elapsed(t_prec,.True.,1.0_rl)
+    call print_elapsed(t_l2norm,.True.,1.0_rl)
+    call print_elapsed(t_scalprod,.True.,1.0_rl)
+    call print_elapsed(t_mainloop,.True.,1.0_rl)
+    if (i_am_master_mpi) write(STDOUT,'("")')
+  end subroutine mg_solve
+
+!==================================================================
+! Test haloswap on all levels
+!==================================================================
+  subroutine measurehaloswap()
+    implicit none
+    integer :: iter, level, finelevel, splitlevel
+
+    level = mg_param%n_lev
+    finelevel = level
+    splitlevel = mg_param%lev_split
+    call mg_vcyclehaloswaponly(xb_mg,xu_mg,xr_mg,finelevel,splitlevel,level,pproc)
+  end subroutine measurehaloswap
+
+end module multigrid
+
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/parameters.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/parameters.f90
new file mode 100644
index 0000000000000000000000000000000000000000..5195982fdeffc44390f2a2fa9fd116f6e0d76660
--- /dev/null
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/parameters.f90
@@ -0,0 +1,64 @@
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+!
+!  This file is part of the TensorProductMultigrid code.
+!  
+!  (c) The copyright relating to this work is owned jointly by the
+!  Crown, Met Office and NERC [2014]. However, it has been created
+!  with the help of the GungHo Consortium, whose members are identified
+!  at https://puma.nerc.ac.uk/trac/GungHo/wiki .
+!  
+!  Main Developer: Eike Mueller
+!  
+!  TensorProductMultigrid is free software: you can redistribute it and/or
+!  modify it under the terms of the GNU Lesser General Public License as
+!  published by the Free Software Foundation, either version 3 of the
+!  License, or (at your option) any later version.
+!  
+!  TensorProductMultigrid is distributed in the hope that it will be useful,
+!  but WITHOUT ANY WARRANTY; without even the implied warranty of
+!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+!  GNU Lesser General Public License for more details.
+!  
+!  You should have received a copy of the GNU Lesser General Public License
+!  along with TensorProductMultigrid (see files COPYING and COPYING.LESSER).
+!  If not, see <http://www.gnu.org/licenses/>.
+!
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+
+
+!==================================================================
+!
+!  General parameters
+!
+!    Eike Mueller, University of Bath, Feb 2012
+!
+!==================================================================
+
+module parameters
+
+  implicit none
+
+! floating point precision. Always use rl_kind in code
+  integer, parameter :: single_precision=4        ! single precision
+  integer, parameter :: double_precision=8        ! double precision
+  integer, parameter :: rl=double_precision       ! global switch between
+                                                  ! single/double precision
+! NOTE: As we still use BLAS subroutines, these need to be
+!       replaced as well when switching between double and
+!       single precision!
+  real(kind=rl), parameter :: Tolerance = 1.0e-15
+
+! Output units
+  integer, parameter :: STDOUT = 6
+  integer, parameter :: STDERR = 0
+
+! Numerical constants
+  real(kind=rl), parameter :: two_pi = 6.2831853071795862_rl
+
+! Use Original (K,J,I)  or Transposed (I,J,K) array
+  logical :: LUseO = .false.
+  logical :: LUseT = .true. ! .false. ! .true.
+! Remove mean to B = Right Hand side 
+  logical :: LMean = .false.
+
+end module parameters
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/profiles.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/profiles.f90
new file mode 100644
index 0000000000000000000000000000000000000000..72338e703e1ab7a938de88d82c72d8b43c2ac763
--- /dev/null
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/profiles.f90
@@ -0,0 +1,392 @@
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+!
+!  This file is part of the TensorProductMultigrid code.
+!  
+!  (c) The copyright relating to this work is owned jointly by the
+!  Crown, Met Office and NERC [2014]. However, it has been created
+!  with the help of the GungHo Consortium, whose members are identified
+!  at https://puma.nerc.ac.uk/trac/GungHo/wiki .
+!  
+!  Main Developer: Eike Mueller
+!  
+!  TensorProductMultigrid is free software: you can redistribute it and/or
+!  modify it under the terms of the GNU Lesser General Public License as
+!  published by the Free Software Foundation, either version 3 of the
+!  License, or (at your option) any later version.
+!  
+!  TensorProductMultigrid is distributed in the hope that it will be useful,
+!  but WITHOUT ANY WARRANTY; without even the implied warranty of
+!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+!  GNU Lesser General Public License for more details.
+!  
+!  You should have received a copy of the GNU Lesser General Public License
+!  along with TensorProductMultigrid (see files COPYING and COPYING.LESSER).
+!  If not, see <http://www.gnu.org/licenses/>.
+!
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+
+
+!==================================================================
+!
+!  Analytical forms of RHS vectors
+!
+!    Eike Mueller, University of Bath, Feb 2012
+!
+!==================================================================
+module profiles
+
+  use communication
+  use parameters
+  use datatypes
+  use discretisation
+
+  implicit none
+
+  public::initialise_u_mnh
+  public::get_u_mnh
+  public::initialise_rhs_mnh
+  public::initialise_rhs
+  public::analytical_solution
+
+private
+  contains
+!==================================================================
+! Initialise U vector
+!==================================================================
+  subroutine initialise_u_mnh(grid_param,model_param,u,KIB,KIE,KIU,KJB,KJE,KJU,KKU,PU)
+    implicit none
+    type(grid_parameters), intent(in) :: grid_param
+    type(model_parameters), intent(in) :: model_param
+    type(scalar3d), intent(inout) :: u
+    integer :: ix, iy, iz, ix_min, ix_max, iy_min, iy_max
+    real(kind=rl) :: x, y, z
+    real(kind=rl) :: rho, sigma, theta, phi, r, b_low, b_up, pi
+
+    integer       , optional, intent(in) :: KIB,KIE,KIU,KJB,KJE,KJU,KKU
+    real(kind=rl) , optional, intent(in) :: PU(:,:,:)
+
+    real , dimension(:,:,:) , pointer , contiguous :: zu_st
+
+    ix_min = u%ix_min
+    ix_max = u%ix_max
+    iy_min = u%iy_min
+    iy_max = u%iy_max
+    IF (.NOT. PRESENT(KIB) ) THEN
+       ! Initialise RHS
+        if (LUseO) then
+           do ix=ix_min, ix_max
+              do iy=iy_min, iy_max
+                 do iz=1,u%grid_param%nz
+                    
+                    u%s(iz,iy-iy_min+1,ix-ix_min+1) = 0.0_rl
+                    
+                 end do
+              end do
+           end do
+        end if
+        if (LUseT) then
+           zu_st => u%st
+           !$acc kernels loop independent collapse(3)
+           do iz=1,u%grid_param%nz
+              do iy=iy_min, iy_max
+                 do ix=ix_min, ix_max
+                    
+                    zu_st(ix-ix_min+1,iy-iy_min+1,iz) = 0.0_rl
+                    
+                 end do
+              end do
+           end do
+           !$acc end kernels
+        end if
+     ELSE
+   ! Initialise RHS
+       if (LUseO) then
+          do ix=ix_min, ix_max
+             do iy=iy_min, iy_max
+                do iz=1,u%grid_param%nz
+                   u%s(iz,iy-iy_min+1,ix-ix_min+1) = PU(IX-ix_min+KIB,IY-iy_min+KJB,IZ)
+                end do
+             end do
+          end do
+       end if
+       if (LUseT) then
+          zu_st => u%st
+          !$acc kernels loop independent collapse(3)
+          do iz=1,u%grid_param%nz
+             do iy=iy_min, iy_max
+                do ix=ix_min, ix_max
+                   zu_st(ix-ix_min+1,iy-iy_min+1,iz) = PU(IX-ix_min+KIB,IY-iy_min+KJB,IZ)
+                end do
+             end do
+          end do
+          !$acc end kernels
+       end if
+    END IF
+  end subroutine initialise_u_mnh
+!==================================================================
+! Get U vector
+!==================================================================
+  subroutine get_u_mnh(grid_param,model_param,u,KIB,KIE,KIU,KJB,KJE,KJU,KKU,PU)
+    implicit none
+    type(grid_parameters), intent(in) :: grid_param
+    type(model_parameters), intent(in) :: model_param
+    type(scalar3d), intent(inout) :: u
+    integer :: ix, iy, iz, ix_min, ix_max, iy_min, iy_max
+    real(kind=rl) :: x, y, z
+    real(kind=rl) :: rho, sigma, theta, phi, r, b_low, b_up, pi
+
+    integer       , optional, intent(in)    :: KIB,KIE,KIU,KJB,KJE,KJU,KKU
+    real(kind=rl) , optional, intent(inout) :: PU(:,:,:)
+
+    real , dimension(:,:,:) , pointer , contiguous :: zu_st
+
+    ix_min = u%ix_min
+    ix_max = u%ix_max
+    iy_min = u%iy_min
+    iy_max = u%iy_max
+    IF (.NOT. PRESENT(KIB) ) THEN
+    ! 
+    ELSE
+   ! Get PU
+       if (LUseO) then
+          do ix=ix_min, ix_max
+             do iy=iy_min, iy_max
+                do iz=1,u%grid_param%nz
+                   PU(IX-ix_min+KIB,IY-iy_min+KJB,IZ) =  u%s(iz,iy-iy_min+1,ix-ix_min+1)
+                end do
+             end do
+          end do
+       else
+          zu_st => u%st
+          !$acc kernels loop independent collapse(3)
+          do iz=1,u%grid_param%nz
+             do iy=iy_min, iy_max
+                do ix=ix_min, ix_max
+                   PU(IX-ix_min+KIB,IY-iy_min+KJB,IZ) = zu_st(ix-ix_min+1,iy-iy_min+1,iz)
+                end do
+             end do
+          end do
+          !$acc end kernels
+       end if
+    END IF
+  end subroutine get_u_mnh
+!==================================================================
+! Initialise RHS vector
+!==================================================================
+  subroutine initialise_rhs_mnh(grid_param,model_param,b,KIB,KIE,KIU,KJB,KJE,KJU,KKU,PY)
+    implicit none
+    type(grid_parameters), intent(in) :: grid_param
+    type(model_parameters), intent(in) :: model_param
+    type(scalar3d), intent(inout) :: b
+    integer :: ix, iy, iz, ix_min, ix_max, iy_min, iy_max
+    real(kind=rl) :: x, y, z
+    real(kind=rl) :: rho, sigma, theta, phi, r, b_low, b_up, pi
+
+    integer       , optional, intent(in) :: KIB,KIE,KIU,KJB,KJE,KJU,KKU
+    real(kind=rl) , optional, intent(in) :: PY(:,:,:)
+
+    real , dimension(:,:,:) , pointer , contiguous :: zb_st
+
+    ix_min = b%ix_min
+    ix_max = b%ix_max
+    iy_min = b%iy_min
+    iy_max = b%iy_max
+    IF (.NOT. PRESENT(KIB) ) THEN
+    ! Initialise RHS
+       if (LUseO) then   
+          do ix=ix_min, ix_max
+             do iy=iy_min, iy_max
+                do iz=1,b%grid_param%nz
+                   x = 1.0_rl*((ix-0.5_rl)/(1.0_rl*b%grid_param%n))
+                   y = 1.0_rl*((iy-0.5_rl)/(1.0_rl*b%grid_param%n))
+                   z = 1.0_rl*((iz-0.5_rl)/(1.0_rl*b%grid_param%nz))
+                   
+                   b%s(iz,iy-iy_min+1,ix-ix_min+1) = 0.0_rl
+                   
+                   if ( ( x .ge. 0.1_rl ) .and. ( x .le. 0.4_rl ) &
+                        .and. (y .ge. 0.3_rl ) .and. ( y .le. 0.6_rl ) &
+                        .and. (z .ge. 0.2_rl ) .and. ( z .le. 0.7_rl ) ) &
+                        then
+                      
+                      b%s(iz,iy-iy_min+1,ix-ix_min+1) = 1.0_rl 
+                      
+                   end if
+                   
+                end do
+             end do
+          end do
+       endif
+       if (LUseT) then
+          zb_st => b%st
+          !$acc kernels loop independent collapse(3)
+          do iz=1,b%grid_param%nz
+             do iy=iy_min, iy_max
+                do ix=ix_min, ix_max
+                   x = 1.0_rl*((ix-0.5_rl)/(1.0_rl*b%grid_param%n))
+                   y = 1.0_rl*((iy-0.5_rl)/(1.0_rl*b%grid_param%n))
+                   z = 1.0_rl*((iz-0.5_rl)/(1.0_rl*b%grid_param%nz))
+                   
+                   zb_st(ix-ix_min+1,iy-iy_min+1,iz) = 0.0_rl
+                   
+                   if ( ( x .ge. 0.1_rl ) .and. ( x .le. 0.4_rl ) &
+                        .and. (y .ge. 0.3_rl ) .and. ( y .le. 0.6_rl ) &
+                        .and. (z .ge. 0.2_rl ) .and. ( z .le. 0.7_rl ) ) &
+                        then
+                      
+                      zb_st(ix-ix_min+1,iy-iy_min+1,iz) = 1.0_rl
+                      
+                   end if
+                   
+                end do
+             end do
+          end do
+          !$acc end kernels
+       end if
+    ELSE
+   ! Initialise RHS
+       if (LUseO) then    
+          do ix=ix_min, ix_max
+             do iy=iy_min, iy_max
+                do iz=1,b%grid_param%nz
+                   b%s(iz,iy-iy_min+1,ix-ix_min+1) = PY(IX-ix_min+KIB,IY-iy_min+KJB,IZ)
+                end do
+             end do
+          end do
+       end if
+       if (LUseT) then
+          zb_st => b%st
+          !$acc kernels loop independent collapse(3)
+          do iz=1,b%grid_param%nz 
+             do iy=iy_min, iy_max
+                do ix=ix_min, ix_max
+                   zb_st(ix-ix_min+1,iy-iy_min+1,iz) = PY(IX-ix_min+KIB,IY-iy_min+KJB,IZ)
+                end do
+             end do
+          end do
+          !$acc end kernels
+       end if
+    END IF
+  end subroutine initialise_rhs_mnh
+!==================================================================
+! Initialise RHS vector
+!==================================================================
+  subroutine initialise_rhs(grid_param,model_param,b)
+    implicit none
+    type(grid_parameters), intent(in) :: grid_param
+    type(model_parameters), intent(in) :: model_param
+    type(scalar3d), intent(inout) :: b
+    integer :: ix, iy, iz, ix_min, ix_max, iy_min, iy_max
+    real(kind=rl) :: x, y, z
+    real(kind=rl) :: rho, sigma, theta, phi, r, b_low, b_up, pi
+
+#ifdef TESTCONVERGENCE
+    real(kind=rl) :: px,py,pz
+#endif
+
+    ix_min = b%ix_min
+    ix_max = b%ix_max
+    iy_min = b%iy_min
+    iy_max = b%iy_max
+    b_low = 1.0_rl+0.25*b%grid_param%H
+    b_up = 1.0_rl+0.75*b%grid_param%H
+    pi = 4.0_rl*atan2(1.0_rl,1.0_rl)
+    ! Initialise RHS
+    do ix=ix_min, ix_max
+      do iy=iy_min, iy_max
+        do iz=1,b%grid_param%nz
+          x = 1.0_rl*((ix-0.5_rl)/(1.0_rl*b%grid_param%n))
+          y = 1.0_rl*((iy-0.5_rl)/(1.0_rl*b%grid_param%n))
+          z = 1.0_rl*((iz-0.5_rl)/(1.0_rl*b%grid_param%nz))
+#ifdef TESTCONVERGENCE
+          ! RHS for analytical solution x*(1-x)*y*(1-y)*z*(1-z)
+          if (grid_param%vertbc == VERTBC_DIRICHLET) then
+            px = x*(1.0_rl-x)
+            py = y*(1.0_rl-y)
+            pz = z*(1.0_rl-z)
+            b%s(iz,iy-iy_min+1,ix-ix_min+1) = &
+              ( 2.0_rl*model_param%omega2*((px+py)*pz &
+              + model_param%lambda2*px*py)+model_param%delta*px*py*pz)
+          else
+            px = x*(1.0_rl-x)
+            py = y*(1.0_rl-y)
+            pz = 1.0_rl
+            b%s(iz,iy-iy_min+1,ix-ix_min+1) = &
+              ( 2.0_rl*model_param%omega2*((px+py)*pz)+model_param%delta*px*py*pz)
+          end if
+#else
+          b%s(iz,iy-iy_min+1,ix-ix_min+1) = 0.0_rl
+#ifdef CARTESIANGEOMETRY
+          if ( ( x .ge. 0.1_rl ) .and. ( x .le. 0.4_rl ) &
+            .and. (y .ge. 0.3_rl ) .and. ( y .le. 0.6_rl ) &
+            .and. (z .ge. 0.2_rl ) .and. ( z .le. 0.7_rl ) ) &
+            then
+            b%s(iz,iy-iy_min+1,ix-ix_min+1) = 1.0_rl
+          end if
+#else
+          rho = 2.0_rl*(1.0_rl*ix-0.5_rl)/grid_param%n-1.0_rl
+          sigma = 2.0_rl*(1.0_rl*iy-0.5_rl)/grid_param%n-1.0_rl
+          phi = atan(sigma)
+          theta = atan(rho/sqrt(1.0_rl+sigma**2))
+          x = sin(theta)
+          y = cos(theta)*sin(phi)
+          z = cos(theta)*cos(phi)
+          phi = atan2(x,y)
+          theta = atan2(sqrt(x**2+y**2),z)
+          r = 0.5_rl*(r_grid(iz)+r_grid(iz+1))
+          if (( (r > b_low) .and. (r < b_up) ) .and. &
+              (((theta>pi/10.0_rl) .and. (theta<pi/5.0_rl )) .or. &
+               ((theta>3.0_rl*pi/8.0_rl) .and. (theta<5.0_rl*pi/8.0_rl )) .or. &
+               ((theta>4.0_rl*pi/5.0_rl) .and. (theta<9.0_rl*pi/10.0_rl)))) then
+            b%s(iz,iy-iy_min+1,ix-ix_min+1) = 1.0_rl
+          end if
+!    RHS used in GPU code:
+!          if ( (r > b_low) .and. (r < b_up) .and. &
+!               (rho > -0.5) .and. (rho < 0.5) .and. &
+!               (sigma > -0.5).and. (sigma < 0.5) ) then
+!            b%s(iz,iy-iy_min+1,ix-ix_min+1) = 1.0_rl
+!          end if
+#endif
+#endif
+        end do
+      end do
+    end do
+  end subroutine initialise_rhs
+!==================================================================
+! Exact solution for test problem
+!  u(x,y,z) = x*(1-x)*y*(1-y)*z*(1-z)
+!==================================================================
+  subroutine analytical_solution(grid_param,u)
+    implicit none
+    type(grid_parameters), intent(in) :: grid_param
+    type(scalar3d), intent(inout) :: u
+    integer :: ix, iy, iz, ix_min, ix_max, iy_min, iy_max
+    real(kind=rl) :: x, y, z
+
+    ix_min = u%ix_min
+    ix_max = u%ix_max
+    iy_min = u%iy_min
+    iy_max = u%iy_max
+
+    ! Initialise RHS
+    do ix=ix_min, ix_max
+      do iy=iy_min, iy_max
+        do iz=1,u%grid_param%nz
+          x = u%grid_param%L*((ix-0.5_rl)/(1.0_rl*u%grid_param%n))
+          y = u%grid_param%L*((iy-0.5_rl)/(1.0_rl*u%grid_param%n))
+          z = u%grid_param%H*((iz-0.5_rl)/(1.0_rl*u%grid_param%nz))
+          if (grid_param%vertbc == VERTBC_DIRICHLET) then
+            u%s(iz,iy-iy_min+1,ix-ix_min+1) &
+              = x*(1.0_rl-x) &
+              * y*(1.0_rl-y) &
+              * z*(1.0_rl-z)
+          else
+            u%s(iz,iy-iy_min+1,ix-ix_min+1) &
+              = x*(1.0_rl-x) &
+              * y*(1.0_rl-y)
+          end if
+        end do
+      end do
+    end do
+  end subroutine analytical_solution
+
+end module profiles
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/solver.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/solver.f90
new file mode 100644
index 0000000000000000000000000000000000000000..97f5a7b840cc0030902eaf39b55bb1d9c0460041
--- /dev/null
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/solver.f90
@@ -0,0 +1,61 @@
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+!
+!  This file is part of the TensorProductMultigrid code.
+!  
+!  (c) The copyright relating to this work is owned jointly by the
+!  Crown, Met Office and NERC [2014]. However, it has been created
+!  with the help of the GungHo Consortium, whose members are identified
+!  at https://puma.nerc.ac.uk/trac/GungHo/wiki .
+!  
+!  Main Developer: Eike Mueller
+!  
+!  TensorProductMultigrid is free software: you can redistribute it and/or
+!  modify it under the terms of the GNU Lesser General Public License as
+!  published by the Free Software Foundation, either version 3 of the
+!  License, or (at your option) any later version.
+!  
+!  TensorProductMultigrid is distributed in the hope that it will be useful,
+!  but WITHOUT ANY WARRANTY; without even the implied warranty of
+!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+!  GNU Lesser General Public License for more details.
+!  
+!  You should have received a copy of the GNU Lesser General Public License
+!  along with TensorProductMultigrid (see files COPYING and COPYING.LESSER).
+!  If not, see <http://www.gnu.org/licenses/>.
+!
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+
+
+!==================================================================
+!
+! Solver parameters
+!
+!    Eike Mueller, University of Bath, May 2012
+!
+!==================================================================
+module solver
+
+  use parameters
+  use datatypes
+
+  implicit none
+
+public::solver_parameters
+public::SOLVER_RICHARDSON
+public::SOLVER_CG
+
+private
+
+  integer, parameter :: SOLVER_RICHARDSON = 1
+  integer, parameter :: SOLVER_CG = 2
+
+
+  ! --- Solver parameters ---
+  type solver_parameters
+    integer :: solvertype ! Type of solver
+    real(kind=rl) :: resreduction ! Required relative residual reduction
+    integer :: maxiter    ! Maximal number of iterations
+  end type solver_parameters
+
+end module solver
+
diff --git a/src/ZSOLVER/tensorproductmultigrid_Source/timer.f90 b/src/ZSOLVER/tensorproductmultigrid_Source/timer.f90
new file mode 100644
index 0000000000000000000000000000000000000000..da0f17907a28016c0aad1fee4b78d348cf72ecfd
--- /dev/null
+++ b/src/ZSOLVER/tensorproductmultigrid_Source/timer.f90
@@ -0,0 +1,193 @@
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+!
+!  This file is part of the TensorProductMultigrid code.
+!  
+!  (c) The copyright relating to this work is owned jointly by the
+!  Crown, Met Office and NERC [2014]. However, it has been created
+!  with the help of the GungHo Consortium, whose members are identified
+!  at https://puma.nerc.ac.uk/trac/GungHo/wiki .
+!  
+!  Main Developer: Eike Mueller
+!  
+!  TensorProductMultigrid is free software: you can redistribute it and/or
+!  modify it under the terms of the GNU Lesser General Public License as
+!  published by the Free Software Foundation, either version 3 of the
+!  License, or (at your option) any later version.
+!  
+!  TensorProductMultigrid is distributed in the hope that it will be useful,
+!  but WITHOUT ANY WARRANTY; without even the implied warranty of
+!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+!  GNU Lesser General Public License for more details.
+!  
+!  You should have received a copy of the GNU Lesser General Public License
+!  along with TensorProductMultigrid (see files COPYING and COPYING.LESSER).
+!  If not, see <http://www.gnu.org/licenses/>.
+!
+!=== COPYRIGHT AND LICENSE STATEMENT ===
+
+
+!==================================================================
+!
+!  Timer module
+!
+!    Eike Mueller, University of Bath, Feb 2012
+!
+!==================================================================
+
+module timer
+
+#ifndef MNH
+  use mpi
+#else
+  use modd_mpif
+#endif 
+  use parameters
+
+  implicit none
+
+public::initialise_timing
+public::finalise_timing
+public::time
+public::initialise_timer
+public::start_timer
+public::finish_timer
+public::print_timerinfo
+public::print_elapsed
+
+private
+
+! Timer type
+  type time
+    character(len=32) :: label
+    real(kind=rl) :: start
+    real(kind=rl) :: finish
+    integer :: ncall
+    real(kind=rl) :: elapsed
+  end type time
+
+  ! id of timer output file
+  integer, parameter :: TIMEROUT = 9
+
+  ! used my MPI
+  integer :: rank, ierr
+
+contains
+
+!==================================================================
+! Initialise timer module
+!==================================================================
+  subroutine initialise_timing(filename)
+    implicit none
+    character(len=*), intent(in) :: filename
+    call mpi_comm_rank(MPI_COMM_WORLD,rank,ierr)
+    if (rank==0) then
+      open(UNIT=TIMEROUT,FILE=trim(filename))
+      write(STDOUT,'("Writing timer information to file ",A40)') filename
+      write(TIMEROUT,'("# ----------------------------------------------")')
+      write(TIMEROUT,'("# Timer information for geometric multigrid code")')
+      write(TIMEROUT,'("# ----------------------------------------------")')
+    end if
+  end subroutine initialise_timing
+
+!==================================================================
+! Finalise timer module
+!==================================================================
+  subroutine finalise_timing()
+    implicit none
+    if (rank==0) then
+      close(TIMEROUT)
+    end if
+  end subroutine finalise_timing
+
+!==================================================================
+! Initialise timer
+!==================================================================
+  subroutine initialise_timer(t,label)
+    implicit none
+    type(time), intent(inout) :: t
+    character(len=*), intent(in) :: label
+    t%label = label
+    t%start = 0.0_rl
+    t%ncall = 0
+    t%finish = 0.0_rl
+    t%elapsed = 0.0_rl
+  end subroutine initialise_timer
+
+!==================================================================
+! Start timer
+!==================================================================
+  subroutine start_timer(t)
+    implicit none
+    type(time), intent(inout) :: t
+    t%start = mpi_wtime()
+  end subroutine start_timer
+
+!==================================================================
+! Finish timer
+!==================================================================
+  subroutine finish_timer(t)
+    implicit none
+    type(time), intent(inout) :: t
+    t%finish = mpi_wtime()
+    t%elapsed = t%elapsed + (t%finish-t%start)
+    t%ncall = t%ncall + 1
+  end subroutine finish_timer
+
+!==================================================================
+! Print to timer file
+!==================================================================
+  subroutine print_timerinfo(msg)
+    implicit none
+    character(len=*), intent(in) :: msg
+    if (rank == 0) then
+      write(TIMEROUT,*) "# " // trim(msg)
+    end if
+  end subroutine print_timerinfo
+
+!==================================================================
+! Print timer information
+!==================================================================
+  subroutine print_elapsed(t,summaryonly,factor)
+    implicit none
+    type(time), intent(in)        :: t
+    logical, intent(in)           :: summaryonly
+    real(kind=rl), intent(in)     :: factor
+    real(kind=rl) :: elapsedtime
+    real(kind=rl) :: t_min
+    real(kind=rl) :: t_max
+    real(kind=rl) :: t_avg
+    integer :: rank, nprocs, ierr
+    integer :: nc
+
+    t_min = 0.0_rl
+    t_max = 0.0_rl
+    t_avg = 0.0_rl
+
+
+    elapsedtime = (t%elapsed) * factor
+    call mpi_reduce(elapsedtime,t_min,1,MPI_DOUBLE_PRECISION, &
+                    MPI_MIN, 0, MPI_COMM_WORLD,ierr)
+    call mpi_reduce(elapsedtime,t_avg,1,MPI_DOUBLE_PRECISION, &
+                    MPI_SUM, 0, MPI_COMM_WORLD,ierr)
+    call mpi_reduce(elapsedtime,t_max,1,MPI_DOUBLE_PRECISION, &
+                    MPI_MAX, 0, MPI_COMM_WORLD,ierr)
+    call mpi_comm_size(MPI_COMM_WORLD,nprocs,ierr)
+    call mpi_comm_rank(MPI_COMM_WORLD,rank,ierr)
+    t_avg = t_avg/nprocs
+    nc = t%ncall
+    if (nc == 0) nc = 1
+    if (summaryonly) then
+      if (rank == 0) then
+        write(TIMEROUT,'(A32," [",I7,"]: ",E10.4," / ",E10.4," / ",E10.4," (min/avg/max)")') &
+          t%label,t%ncall,t_min,t_avg,t_max
+        write(TIMEROUT,'(A32,"    t/call: ",E10.4," / ",E10.4," / ",E10.4," (min/avg/max)")') &
+          t%label,t_min/nc,t_avg/nc,t_max/nc
+      end if
+    else
+      write(TIMEROUT,'(A32," : ",I8," calls ",E10.4," (rank ",I8,")")') &
+        t%label,elapsedtime, rank
+    end if
+    write(TIMEROUT,'("")')
+  end subroutine print_elapsed
+
+end module timer
diff --git a/src/ZSOLVER/tridz.f90 b/src/ZSOLVER/tridz.f90
new file mode 100644
index 0000000000000000000000000000000000000000..203c413f8251bcfb5bd4d6e242198a7923efd16d
--- /dev/null
+++ b/src/ZSOLVER/tridz.f90
@@ -0,0 +1,848 @@
+!MNH_LIC Copyright 1994-2019 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+!     ################
+      MODULE MODI_TRIDZ
+!     ################
+!
+INTERFACE
+!
+      SUBROUTINE TRIDZ(HLBCX,HLBCY,                                     &
+                      PMAP,PDXHAT,PDYHAT,HPRESOPT,                      &
+                      PDXHATM,PDYHATM,PRHOM,                            &
+                      PAF,PCF,PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,            &
+                      PRHODJ,PTHVREF,PZZ,PBFY,PBFB,                     &
+                      PBF_SXP2_YP1_Z,                                   &
+                      PAF_ZS,PBF_ZS,PCF_ZS,                             &
+                      PDXATH_ZS,PDYATH_ZS,PRHO_ZS,                      &
+                      A_K,B_K,C_K,D_K) !JUAN  FULL ZSOLVER
+!
+IMPLICIT NONE
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX    ! x-direction LBC type
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY    ! y-direction LBC type
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRHODJ     ! density of reference * J
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PTHVREF    ! Virtual Potential
+                                        ! Temperature of the reference state
+!
+REAL, DIMENSION(:,:), INTENT(IN) :: PMAP         ! scale factor
+!
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PZZ        ! height z
+!
+REAL, DIMENSION(:), INTENT(IN) :: PDXHAT          ! Stretching in x direction
+REAL, DIMENSION(:), INTENT(IN) :: PDYHAT          ! Stretching in y direction
+CHARACTER (LEN=5), INTENT(IN) :: HPRESOPT        ! choice of the pressure solver
+!
+REAL, INTENT(OUT) :: PDXHATM                     ! mean grid increment in the x
+                                                 ! direction
+REAL, INTENT(OUT) :: PDYHATM                     ! mean grid increment in the y
+                                                 ! direction
+!
+REAL, DIMENSION (:), INTENT(OUT) :: PRHOM        !  mean of XRHODJ on the plane
+                                                 !  x y localized at a mass 
+                                                 !  level
+!
+REAL, DIMENSION(:), INTENT(OUT)     :: PAF,PCF  ! vectors giving the nonvanishing
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PBFY     ! elements (yslice) of the tri-diag.
+                                                ! matrix in the pressure eq. 
+!JUAN
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PBFB     ! elements (bsplit slide) of the tri-diag.
+                                                ! matrix in the pressure eq. 
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PBF_SXP2_YP1_Z ! elements of the tri-diag. SXP2_YP1_Z-slide 
+                                                   ! matrix in the pressure eq
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PAF_ZS,PBF_ZS,PCF_ZS
+REAL, DIMENSION(:,:)  , INTENT(OUT) :: PDXATH_ZS,PDYATH_ZS
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PRHO_ZS
+REAL, DIMENSION(:)    , INTENT(OUT) :: A_K,B_K,C_K,D_K
+!JUAN
+!
+                                                 ! arrays of sin or cos values
+                                                 ! for the FFT :
+REAL, DIMENSION(:), INTENT(OUT) :: PTRIGSX       ! - along x
+REAL, DIMENSION(:), INTENT(OUT) :: PTRIGSY       ! - along y
+!
+                                                 ! decomposition in prime
+                                                 ! numbers for the FFT:
+INTEGER, DIMENSION(19), INTENT(OUT) :: KIFAXX      ! - along x
+INTEGER, DIMENSION(19), INTENT(OUT) :: KIFAXY      ! - along y
+
+!
+END SUBROUTINE TRIDZ
+!
+END INTERFACE
+!
+END MODULE MODI_TRIDZ
+!
+!     ###################################################################
+      SUBROUTINE TRIDZ(HLBCX,HLBCY,                                     &
+                      PMAP,PDXHAT,PDYHAT,HPRESOPT,                      &
+                      PDXHATM,PDYHATM,PRHOM,                            &
+                      PAF,PCF,PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,            &
+                      PRHODJ,PTHVREF,PZZ,PBFY,PBFB,                     &
+                      PBF_SXP2_YP1_Z,                                   &
+                      PAF_ZS,PBF_ZS,PCF_ZS,                             &
+                      PDXATH_ZS,PDYATH_ZS,PRHO_ZS,                      &
+                      A_K,B_K,C_K,D_K) !JUAN  FULL ZSOLVER      
+!    ####################################################################
+!
+!!****  *TRIDZ * - Compute coefficients for the flat operator
+!!
+!!    PURPOSE
+!!    -------
+!       The purpose of this routine is to compute the vertical time independent 
+!     coefficients a(k), b(k), c(k) required for the calculation of the "flat"  
+!     (i.e. neglecting the orography) operator Laplacian.  RHOJ is averaged on 
+!     the whole horizontal domain. The form of the eigenvalues  of the flat 
+!     operator depends on the lateral boundary conditions. Furthermore, this
+!     routine initializes TRIGS and IFAX arrays required for the FFT transform 
+!     used in the routine PRECOND.
+!
+!!**  METHOD
+!!    ------
+!!     The forms of the eigenvalues of the horizontal Laplacian are given by:
+!!     Cyclic conditions:
+!!     -----------------
+!!                    <rhoj>        2 ( pi     )       <rhoj>      2 (  pi    )
+!!     b(m,n) = -4 -----------   sin  (----- m ) -4 ----------- sin  (----- n )
+!!                 <dxx> <dxx>        ( imax   )    <dyy> <dyy>      ( jmax   )
+!!
+!!     Open conditions:
+!!     -----------------
+!!                    <rhoj>        2 ( pi     )       <rhoj>      2 (  pi    )
+!!     b(m,n) = -4 -----------   sin  (----- m ) -4 ----------- sin  (----- n )
+!!                 <dxx> <dxx>        ( 2imax  )    <dyy> <dyy>      ( 2jmax  )
+!!      
+!!     Cyclic condition along x and open condition along y:
+!!     ------------------------------------------------------
+!!                    <rhoj>        2 ( pi     )       <rhoj>      2 (  pi    )
+!!     b(m,n) = -4 -----------   sin  (----- m ) -4 ----------- sin  (----- n )
+!!                 <dxx> <dxx>        ( imax   )    <dyy> <dyy>      ( 2jmax  )
+!!
+!!     Open condition along x and cyclic condition along y:
+!!     ------------------------------------------------------
+!!                    <rhoj>        2 ( pi     )       <rhoj>      2 (  pi    )
+!!     b(m,n) = -4 -----------   sin  (----- m ) -4 ----------- sin  (----- n )
+!!                 <dxx> <dxx>        ( 2imax  )    <dyy> <dyy>      ( jmax   )
+!!
+!!     where m = 0,1,2....imax-1, n = 0,1,2....jmax-1
+!!     Note that rhoj contains the Jacobian J = Deltax*Deltay*Deltaz = volume of
+!!     an elementary mesh.
+
+!!
+!!    EXTERNAL
+!!    --------
+!!      Function FFTFAX: initialization of TRIGSX,IFAXX,TRIGSY,IFAXY for  
+!!      the FFT transform
+!!      GET_DIM_EXT_ll    : get extended sub-domain sizes
+!!      GET_INDICE_ll     : get physical sub-domain bounds 
+!!      GET_DIM_PHYS_ll   : get physical sub-domain sizes
+!!      GET_GLOBALDIMS_ll : get physical global domain sizes
+!!      GET_OR_ll         : get origine coordonates of the physical sub-domain in global indices
+!!      REDUCESUM_ll      : sum into a scalar variable
+!!      GET_SLICE_ll    : get a slice of the global domain
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------ 
+!!      Module MODD_CST : define constants
+!!         XPI : pi
+!!         XCPD
+!!      Module MODD_PARAMETERS: declaration of parameter variables
+!!        JPHEXT, JPVEXT: define the number of marginal points out of the 
+!!        physical domain along horizontal and vertical directions respectively
+!!      Module MODD_CONF: model configurations 
+!!         LCARTESIAN: logical for CARTESIAN geometry
+!!                     .TRUE. = Cartesian geometry used
+!!         L2D: logical for 2D model version
+!!  
+!!    REFERENCE
+!!    ---------
+!!      Book2 of documentation (routine TRIDZ)
+!!      
+!!    AUTHOR
+!!    ------
+!!	P. HÃ…reil and J. Stein       * Meteo France *
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original    25/07/94 
+!!                  14/04/95  (J. Stein) bug in the ZDZM computation
+!!                                        ( stretched case)  
+!!                   8/07/96  (P. Jabouille) change the FFT initialization
+!!                            which now works for odd number.
+!!                  14/01/97 Durran anelastic equation (Stein,Lafore)
+!!                  15/06/98  (D.Lugato, R.Guivarch) Parallelisation
+!!                  10/08/98 (N. Asencio) add parallel code
+!!                                        use PDXHAT, PDYHAT and not PXHAT,PYHAT
+!!                                        PBFY is initialized
+!!                  20/08/00 (J. Stein, J. Escobar) optimisation of the solver
+!!                                        PBFY transposition
+!!                  14/03/02 (P. Jabouille) set values for meaningless spectral coefficients
+!!                                       (to avoid problem in bouissinesq configuration)
+!!   J.Escobar : 15/09/2015 : WENO5 & JPHEXT <> 1
+!!  Philippe Wautelet: 05/2016-04/2018: new data structures and calls for I/O
+!------------------------------------------------------------------------------
+!
+!*       0.    DECLARATIONS
+!              ------------
+USE MODD_CST
+USE MODD_CONF
+USE MODD_LUNIT_n, ONLY: TLUOUT
+USE MODD_PARAMETERS
+!
+USE MODE_ll
+USE MODE_MSG
+!JUAN P1/P2 SPLITTING
+USE MODE_SPLITTINGZ_ll , ONLY : GET_DIM_EXTZ_ll,GET_ORZ_ll,LWESTZ_ll,LSOUTHZ_ll
+!JUAN
+!
+!JUAN
+USE MODE_REPRO_SUM
+!JUAN
+USE MODE_MPPDB
+!
+USE mode_mg_main_mnh
+!
+IMPLICIT NONE
+!
+!
+!*       0.1   declarations of arguments
+!
+!
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX    ! x-direction LBC type
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY    ! y-direction LBC type
+!
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PRHODJ     ! density of reference * J
+REAL, DIMENSION(:,:,:),   INTENT(IN)    :: PTHVREF    ! Virtual Potential
+                                        ! Temperature of the reference state
+!
+REAL, DIMENSION(:,:), INTENT(IN) :: PMAP         ! scale factor
+!
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PZZ        ! height z
+!
+REAL, DIMENSION(:), INTENT(IN) :: PDXHAT          ! Stretching in x direction
+REAL, DIMENSION(:), INTENT(IN) :: PDYHAT          ! Stretching in y direction
+CHARACTER (LEN=5), INTENT(IN) :: HPRESOPT         ! choice of the pressure solver
+!
+REAL, INTENT(OUT) :: PDXHATM                     ! mean grid increment in the x
+                                                 ! direction
+REAL, INTENT(OUT) :: PDYHATM                     ! mean grid increment in the y
+                                                 ! direction
+!
+REAL, DIMENSION (:), INTENT(OUT) :: PRHOM        !  mean of XRHODJ on the plane
+                                                 !  x y localized at a mass 
+                                                 !  level
+!
+REAL, DIMENSION(:), INTENT(OUT)     :: PAF,PCF  ! vectors giving the nonvanishing
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PBFY     ! elements (yslice) of the tri-diag.
+! matrix in the pressure eq. which is transposed. PBFY is a y-slices structure
+!JUAN
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PBFB     ! elements (bsplit slide) of the tri-diag.
+                                                ! matrix in the pressure eq. 
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PBF_SXP2_YP1_Z ! elements of the tri-diag. SXP2_YP1_Z-slide 
+                                                   ! matrix in the pressure eq.
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PAF_ZS,PBF_ZS,PCF_ZS
+REAL, DIMENSION(:,:)  , INTENT(OUT) :: PDXATH_ZS,PDYATH_ZS
+REAL, DIMENSION(:,:,:), INTENT(OUT) :: PRHO_ZS
+REAL, DIMENSION(:)    , INTENT(OUT) :: A_K,B_K,C_K,D_K
+!JUAN
+!                                 
+                                                 ! arrays of sin or cos values
+                                                 ! for the FFT :
+REAL, DIMENSION(:), INTENT(OUT) :: PTRIGSX       ! - along x
+REAL, DIMENSION(:), INTENT(OUT) :: PTRIGSY       ! - along y
+!
+                                                 ! decomposition in prime
+                                                 ! numbers for the FFT:
+INTEGER, DIMENSION(19), INTENT(OUT) :: KIFAXX      ! - along x
+INTEGER, DIMENSION(19), INTENT(OUT) :: KIFAXY      ! - along y
+
+!
+!*       0.2   declarations of local variables
+!
+INTEGER                         ::  IRESP    ! FM return code
+INTEGER                         :: ILUOUT    ! Logical unit number for
+                                             ! output-listing   
+INTEGER :: IIB,IIE,IJB,IJE,IKB,IKE     ! indice values of the physical subdomain
+INTEGER :: IKU ,  IKBE                      ! size of the arrays along z
+INTEGER :: IIB_ll,IIE_ll,IJB_ll,IJE_ll !  indice values of the physical global domain
+INTEGER :: IIMAX,IJMAX       ! Number of points of the physical subdomain
+INTEGER :: IIMAX_ll,IJMAX_ll ! Number of points of Global physical domain
+!
+INTEGER :: JI,JJ,JK                                    ! loop indexes
+!
+INTEGER :: INN        ! temporary result for the computation of array TRIGS
+!
+REAL, DIMENSION (:,:), ALLOCATABLE  :: ZEIGEN_ll  ! eigenvalues b(m,n) in global representation
+REAL, DIMENSION (:),   ALLOCATABLE  :: ZEIGENX_ll ! used for the computation of ZEIGEN_ll 
+!
+REAL, DIMENSION( SIZE(PDXHAT))  :: ZWORKX  ! work array to compute PDXHATM
+REAL, DIMENSION( SIZE(PDYHAT))  :: ZWORKY  ! work array to compute PDYHATM
+!
+REAL :: ZGWNX,ZGWNY           ! greater wave numbers allowed by the model 
+                              ! configuration in x and y directions respectively
+!
+REAL, DIMENSION (SIZE(PZZ,3)) :: ZDZM      !  mean of deltaz on the plane x y
+                                           !  localized at a w-level
+!
+REAL :: ZANGLE,ZDEL ! needed for the initialization of the arrays used by the FFT
+!
+REAL :: ZINVMEAN ! inverse of inner points number in an horizontal grid
+!
+INTEGER ::  IINFO_ll         ! return code of parallel routine
+REAL, DIMENSION (SIZE(PMAP,1)) :: ZXMAP ! extraction of PMAP array along x
+REAL, DIMENSION (SIZE(PMAP,2)) :: ZYMAP ! extraction of PMAP array along y
+INTEGER :: IORXY_ll,IORYY_ll     ! origin's coordinates of the y-slices subdomain
+INTEGER :: IIUY_ll,IJUY_ll       ! dimensions of the y-slices subdomain
+INTEGER :: IXMODE_ll,IYMODE_ll   ! number of modes in the x and y direction for global point of view
+INTEGER :: IXMODEY_ll,IYMODEY_ll ! number of modes in the x and y direction for y_slice point of view
+!JUAN Z_SPLITTING
+INTEGER :: IORXB_ll,IORYB_ll     ! origin's coordinates of the b-slices subdomain
+INTEGER :: IIUB_ll,IJUB_ll       ! dimensions of the b-slices subdomain
+INTEGER :: IXMODEB_ll,IYMODEB_ll ! number of modes in the x and y direction for b_slice point of view
+!
+INTEGER :: IORX_SXP2_YP1_Z_ll,IORY_SXP2_YP1_Z_ll     ! origin's coordinates of the b-slices subdomain
+INTEGER :: IIU_SXP2_YP1_Z_ll,IJU_SXP2_YP1_Z_ll,IKU_SXP2_YP1_Z_ll       ! dimensions of the b-slices subdomain
+INTEGER :: IXMODE_SXP2_YP1_Z_ll,IYMODE_SXP2_YP1_Z_ll ! number of modes in the x and y direction for b_slice point of view
+!JUAN Z_SPLITTING
+!JUAN16
+!TYPE(DOUBLE_DOUBLE)  , DIMENSION (SIZE(PZZ,3)) :: ZRHOM_ll   , ZDZM_ll
+REAL, ALLOCATABLE, DIMENSION(:,:)              :: ZRHOM_2D   , ZDZM_2D
+REAL, ALLOCATABLE, DIMENSION(:,:,:)            :: ZDZM_ZS
+!JUAN16
+!
+!
+!
+!
+!
+!------------------------------------------------------------------------------
+!
+!*       1.    INITIALIZATION
+!              --------------
+!
+!*       1.1  retrieve a logical unit number
+!             ------------------------------
+!
+ILUOUT = TLUOUT%NLU
+!
+!*       1.2  compute loop bounds
+!             -------------------
+!
+!  extended sub-domain
+CALL GET_DIM_EXT_ll ('Y',IIUY_ll,IJUY_ll)
+!JUAN Z_SPLITTING
+CALL GET_DIM_EXT_ll ('B',IIUB_ll,IJUB_ll)
+! P1/P2 splitting
+CALL GET_DIM_EXTZ_ll('SXP2_YP1_Z',IIU_SXP2_YP1_Z_ll,IJU_SXP2_YP1_Z_ll,IKU_SXP2_YP1_Z_ll)
+!JUAN Z_SPLITTING
+IKU=SIZE(PRHODJ,3)                        
+!
+CALL GET_INDICE_ll (IIB,IJB,IIE,IJE)
+IKB=1   +JPVEXT                          
+IKE=IKU -JPVEXT
+!  physical sub-domain
+CALL GET_DIM_PHYS_ll ( 'B',IIMAX,IJMAX)
+!
+!  global physical domain limits
+CALL GET_GLOBALDIMS_ll ( IIMAX_ll, IJMAX_ll)
+IIB_ll = 1 + JPHEXT
+IIE_ll = IIMAX_ll  + JPHEXT
+IJB_ll = 1 + JPHEXT
+IJE_ll = IJMAX_ll + JPHEXT
+!
+!     the use of local array ZEIGENX and ZEIGEN would require some technical modifications
+!
+ALLOCATE (ZEIGENX_ll(IIMAX_ll+2*JPHEXT))
+ALLOCATE (ZEIGEN_ll(IIMAX_ll+2*JPHEXT,IJMAX_ll+2*JPHEXT))
+
+ZEIGEN_ll = 0.0
+!  Get the origin coordinates of the extended sub-domain in global landmarks
+CALL GET_OR_ll('Y',IORXY_ll,IORYY_ll)
+!JUAN Z_SPLITING
+CALL GET_OR_ll('B',IORXB_ll,IORYB_ll)
+! P1/P2 Splitting
+CALL GET_ORZ_ll('SXP2_YP1_Z',IORX_SXP2_YP1_Z_ll,IORY_SXP2_YP1_Z_ll)
+!JUAN Z_SPLITING
+!
+!*       1.3 allocate x-slice array
+
+!
+!*       1.4 variables for the eigenvalues computation
+!
+ZGWNX = XPI/REAL(IIMAX_ll)
+ZGWNY = XPI/REAL(IJMAX_ll)
+!
+!------------------------------------------------------------------------------
+!
+!*       2.    COMPUTE THE AVERAGE OF RHOJ*CPD*THETAVREF ALONG XY
+!              --------------------------------------------------
+!
+ZINVMEAN = 1./REAL(IIMAX_ll*IJMAX_ll)
+!JUAN16
+ALLOCATE(ZRHOM_2D(IIB:IIE, IJB:IJE)) 
+PRHO_ZS = 1.0
+!
+DO JK = 1,SIZE(PZZ,3)
+   IF ( CEQNSYS == 'DUR' .OR. CEQNSYS == 'MAE' ) THEN
+      DO JJ = IJB,IJE
+         DO JI = IIB,IIE
+            ZRHOM_2D(JI,JJ)    = PRHODJ(JI,JJ,JK)*XCPD*PTHVREF(JI,JJ,JK)
+            PRHO_ZS(JI,JJ,JK) = ZRHOM_2D(JI,JJ)
+         END DO
+      END DO
+   ELSEIF ( CEQNSYS == 'LHE' ) THEN
+      DO JJ = IJB,IJE
+         DO JI = IIB,IIE
+            ZRHOM_2D(JI,JJ)    = PRHODJ(JI,JJ,JK)  
+            PRHO_ZS(JI,JJ,JK) = ZRHOM_2D(JI,JJ)
+         END DO
+      END DO
+   END IF
+   !  global sum
+   PRHOM(JK) =  SUM_DD_R2_ll(ZRHOM_2D) * ZINVMEAN 
+END DO
+
+!
+!------------------------------------------------------------------------------
+!
+!*       3.    COMPUTE THE MEAN INCREMENT BETWEEN Z LEVELS
+!              -------------------------------------------
+!
+ALLOCATE(ZDZM_2D(IIB:IIE, IJB:IJE))
+ALLOCATE(ZDZM_ZS(IIB:IIE, IJB:IJE,IKU))
+ZDZM_ZS = 1.0
+!
+DO JK = IKB-1,IKE
+   DO JJ = IJB,IJE
+      DO JI = IIB,IIE
+         ZDZM_2D(JI,JJ) = (PZZ(JI,JJ,JK+1)-PZZ(JI,JJ,JK))
+         ZDZM_ZS(JI,JJ,JK) = ZDZM_2D(JI,JJ)
+      END DO
+   END DO
+   ZDZM(JK)  =  SUM_DD_R2_ll(ZDZM_2D) * ZINVMEAN
+END DO
+ZDZM(IKE+1) = ZDZM(IKE)
+ZDZM_ZS(:,:,IKE+1) = ZDZM_ZS(:,:,IKE)
+!
+! vertical average to arrive at a w-level 
+DO JK = IKE+1,IKB,-1
+  ZDZM(JK) = (ZDZM(JK) + ZDZM(JK-1))*0.5
+  ZDZM_ZS(IIB:IIE,IJB:IJE,JK) = (ZDZM_ZS(IIB:IIE,IJB:IJE,JK) + ZDZM_ZS(IIB:IIE,IJB:IJE,JK-1)) * 0.5
+END DO
+!
+ZDZM(IKB-1) = -999.
+ZDZM_ZS(IIB:IIE,IJB:IJE,IKB-1) = -999.
+!
+!------------------------------------------------------------------------------
+!
+!*       4.    COMPUTE THE MEAN INCREMENT BETWEEN X LEVELS
+!              -------------------------------------------
+!
+PDXHATM =0.
+!     . local sum
+IF (LCARTESIAN) THEN
+  PDXHATM = SUM_1DFIELD_ll ( PDXHAT,'X',IIB_ll,IIE_ll,IINFO_ll)
+  DO JJ=1,SIZE(PDXATH_ZS,2)
+     PDXATH_ZS(:,JJ) = PDXHAT(:)
+  END DO
+ELSE
+  ! Extraction of x-slice PMAP at j=(IJB_ll+IJE_ll)/2
+  CALL GET_SLICE_ll (PMAP,'X',(IJB_ll+IJE_ll)/2,ZXMAP(IIB:IIE) &
+                       ,IIB,IIE,IINFO_ll)
+  ! initialize the work array = PDXHAT/ZXMAP
+  ZWORKX(IIB:IIE) = PDXHAT(IIB:IIE)/ ZXMAP (IIB:IIE)
+  PDXHATM = SUM_1DFIELD_ll ( ZWORKX,'X',IIB_ll,IIE_ll,IINFO_ll)
+  DO JJ=1,SIZE(PDXATH_ZS,2)
+     PDXATH_ZS(:,JJ) = PDXHAT(:) / PMAP(:,JJ)
+  END DO
+END IF
+!    . division to complete sum
+PDXHATM = PDXHATM /  REAL(IIMAX_ll)
+!
+!------------------------------------------------------------------------------
+!
+!*       5.    COMPUTE THE MEAN INCREMENT BETWEEN Y LEVELS
+!              -------------------------------------------
+!
+PDYHATM = 0.
+IF (LCARTESIAN) THEN
+  PDYHATM = SUM_1DFIELD_ll ( PDYHAT,'Y',IJB_ll,IJE_ll,IINFO_ll)
+  DO JI=1,SIZE(PDYATH_ZS,1)
+     PDYATH_ZS(JI,:) = PDYHAT(:)
+  END DO
+ELSE
+  ! Extraction of y-slice PMAP at i=IIB_ll+IIE_ll/2 
+  CALL GET_SLICE_ll (PMAP,'Y',(IIB_ll+IIE_ll)/2,ZYMAP(IJB:IJE) &
+                       ,IJB,IJE,IINFO_ll)
+  ! initialize the work array = PDYHAT / ZYMAP
+  ZWORKY(IJB:IJE) = PDYHAT(IJB:IJE) / ZYMAP (IJB:IJE)
+  PDYHATM = SUM_1DFIELD_ll ( ZWORKY,'Y',IJB_ll,IJE_ll,IINFO_ll)
+  DO JI=1,SIZE(PDYATH_ZS,1)
+     PDYATH_ZS(JI,:) = PDYHAT(:) / PMAP(JI,:)
+  END DO
+END IF
+!    . division to complete sum
+PDYHATM= PDYHATM / REAL(IJMAX_ll)
+!
+!------------------------------------------------------------------------------
+!
+!*      6.    COMPUTE THE OUT-DIAGONAL ELEMENTS A AND C OF THE MATRIX
+!             -------------------------------------------------------
+!
+PAF_ZS = 1.0
+PCF_ZS = 1.0
+A_K = 0.0
+B_K = 0.0
+C_K = 0.0
+DO JK = IKB,IKE
+  PAF(JK) = 0.5 * ( PRHOM(JK-1) + PRHOM(JK)   ) / ZDZM(JK)   **2 
+  PCF(JK) = 0.5 * ( PRHOM(JK)   + PRHOM(JK+1) ) / ZDZM(JK+1) **2 
+
+  PAF_ZS(IIB:IIE,IJB:IJE,JK) = 0.5 * ( PRHO_ZS(IIB:IIE,IJB:IJE,JK-1) + PRHO_ZS(IIB:IIE,IJB:IJE,JK)   ) &
+                                     / ZDZM_ZS(IIB:IIE,IJB:IJE,JK)   **2 
+  PCF_ZS(IIB:IIE,IJB:IJE,JK) = 0.5 * ( PRHO_ZS(IIB:IIE,IJB:IJE,JK) + PRHO_ZS(IIB:IIE,IJB:IJE,JK+1)   ) &
+                                     / ZDZM_ZS(IIB:IIE,IJB:IJE,JK+1) **2 
+
+  D_K(JK) = PRHOM(JK) ! / ZDZM(JK)
+  B_K(JK) = PCF(JK) / D_K(JK)
+  C_K(JK) = PAF(JK) / D_K(JK)
+
+END DO
+
+!
+! at the upper and lower levels PAF and PCF are computed using the Neumann 
+! conditions applying on the vertical component of the gradient
+!            
+PAF(IKE+1) = -0.5 * ( PRHOM(IKE)   + PRHOM(IKE+1) ) / ZDZM(IKE+1) **2 
+D_K(IKE+1) = PRHOM(IKE+1) ! / ZDZM(IKE+1)
+C_K(IKE+1) = PAF(IKE+1) / D_K(IKE+1)
+
+PCF(IKB-1) =  0.5 * ( PRHOM(IKB-1) + PRHOM(IKB)   ) / ZDZM(IKB)   **2 
+D_K(IKB-1) = PRHOM(IKB-1) ! / ZDZM(IKB-1)
+B_K(IKB-1) = PCF(IKB-1) / D_K(IKB-1)
+
+!
+PAF(IKB-1) =  0.0 ! 0.5 * ( PRHOM(IKB-1) + PRHOM(IKB)   ) / ZDZM(IKB)   **2
+C_K(IKB-1) =  0.0
+
+PCF(IKE+1) =  0.0 ! 0.5 * ( PRHOM(IKE)   + PRHOM(IKE+1) ) / ZDZM(IKE+1) **2
+B_K(IKE+1) =  0.0
+
+PAF_ZS(IIB:IIE,IJB:IJE,IKE+1) = -0.5 * ( PRHO_ZS(IIB:IIE,IJB:IJE,IKE) + PRHO_ZS(IIB:IIE,IJB:IJE,IKE+1)   ) &
+                                     / ZDZM_ZS(IIB:IIE,IJB:IJE,IKE+1)   **2 
+PCF_ZS(IIB:IIE,IJB:IJE,IKB-1) =  0.5 * ( PRHO_ZS(IIB:IIE,IJB:IJE,IKB-1) + PRHO_ZS(IIB:IIE,IJB:IJE,IKB)   ) &
+                                     / ZDZM_ZS(IIB:IIE,IJB:IJE,IKB) **2 
+
+PAF_ZS(IIB:IIE,IJB:IJE,IKB-1) = 0.0
+PCF_ZS(IIB:IIE,IJB:IJE,IKE+1) = 0.0
+
+IKBE = IKU
+
+IF ( HPRESOPT == 'ZSOLV' ) THEN
+   call mg_main_mnh_init(IIMAX_ll,IKBE,PDXHATM*IIMAX_ll,ZDZM(IKB)*IKBE,&
+        A_K,B_K,C_K,D_K)
+END IF
+
+!------------------------------------------------------------------------------
+!*       7.    COMPUTE THE DIAGONAL ELEMENTS B OF THE MATRIX
+!              ---------------------------------------------
+!
+!*       7.1   compute the horizontal eigenvalues 
+!
+!
+!*       7.1.1   compute the eigenvalues along the x direction 
+!
+SELECT CASE (HLBCX(1))
+! in the cyclic case, the eigenvalues are the same for two following JM values:
+! it corresponds to the real and complex parts of the FFT
+  CASE('CYCL')                     ! cyclic case
+    IXMODE_ll = IIMAX_ll+2*JPHEXT ! +2
+    IXMODEY_ll = IIUY_ll
+    IXMODEB_ll = IIUB_ll !JUAN Z_SPLITTING
+!
+    DO JI = 1,IXMODE_ll
+      ZEIGENX_ll(JI) = - (   2. * SIN ( (JI-1)/2*ZGWNX ) / PDXHATM )**2
+    END DO
+  CASE DEFAULT                !    other cases
+    IXMODE_ll = IIMAX_ll
+!
+!
+    IF (LEAST_ll(HSPLITTING='Y')) THEN
+      IXMODEY_ll = IIUY_ll - 2*JPHEXT  ! -2
+    ELSE
+      IXMODEY_ll = IIUY_ll
+    END IF
+!JUAN Z_SPLITTING
+    IF (LEAST_ll(HSPLITTING='B')) THEN
+      IXMODEB_ll = IIUB_ll - 2*JPHEXT  ! -2
+    ELSE
+      IXMODEB_ll = IIUB_ll
+    END IF
+!JUAN Z_SPLITTING
+!
+!
+    DO JI = 1,IXMODE_ll
+      ZEIGENX_ll(JI) = - (   2. *SIN (0.5*REAL(JI-1)*ZGWNX ) / PDXHATM  )**2
+    END DO
+END SELECT
+!
+!*       7.1.2   compute the eventual eigenvalues along the y direction
+!
+IF (.NOT. L2D) THEN
+!
+! y lateral boundary conditions for three-dimensional cases
+!
+  SELECT CASE (HLBCY(1))
+! in the cyclic case, the eigenvalues are the same for two following JN values:
+! it corresponds to the real and complex parts of the FFT result
+!
+    CASE('CYCL')                      ! 3D cyclic case
+      IYMODE_ll = IJMAX_ll+2*JPHEXT ! +2
+      IYMODEY_ll = IJUY_ll
+      IYMODEB_ll = IJUB_ll !JUAN Z_SPLITTING
+!
+      DO JJ = 1,IYMODE_ll
+        DO JI = 1,IXMODE_ll
+          ZEIGEN_ll(JI,JJ) = ZEIGENX_ll(JI) -    &
+                         (  2.* SIN ( (JJ-1)/2*ZGWNY ) / PDYHATM  )**2
+        END DO
+      END DO
+!
+    CASE DEFAULT                      ! 3D non-cyclic cases
+      IYMODE_ll = IJMAX_ll
+      IYMODEY_ll = IJUY_ll - 2*JPHEXT ! -2
+      IYMODEB_ll = IJUB_ll - 2*JPHEXT ! -2 JUAN Z_SPLITTING
+!
+      DO JJ = 1,IYMODE_ll
+        DO JI = 1,IXMODE_ll
+          ZEIGEN_ll(JI,JJ) = ZEIGENX_ll(JI) - (  2.* SIN (0.5*REAL(JJ-1)*ZGWNY ) / &
+                                                 PDYHATM   )**2
+        END DO
+      END DO
+!
+  END SELECT
+ELSE
+!
+!  copy the x eigenvalue array in a 2D array for a 2D case
+!
+  IYMODE_ll = 1
+  IYMODEY_ll = 1
+  ZEIGEN_ll(1:IXMODE_ll,1)=ZEIGENX_ll(1:IXMODE_ll)
+!
+END IF
+!
+DEALLOCATE(ZEIGENX_ll)
+!
+!CALL MPPDB_CHECK2D(ZEIGEN_ll,"TRIDZ::ZEIGEN_ll",PRECISION)
+!
+!
+!*       7.2   compute the matrix diagonal elements
+!
+!
+PBFY = 1.
+PBFB = 1.  ! JUAN Z_SLIDE
+PBF_SXP2_YP1_Z = 1.  ! JUAN Z_SLIDE
+!
+IF (L2D) THEN
+  DO JK= IKB,IKE
+    DO JJ= 1, IYMODEY_ll
+      DO JI= 1, IXMODEY_ll
+        PBFY(JI,JJ,JK) = PRHOM(JK)* ZEIGEN_ll(JI+IORXY_ll-1,JJ+IORYY_ll-1) - 0.5 * &
+        ( ( PRHOM(JK-1) + PRHOM(JK)   ) / ZDZM(JK)  **2                          &
+         +( PRHOM(JK)   + PRHOM(JK+1) ) / ZDZM(JK+1)**2 )
+      END DO
+    END DO
+  END DO
+! at the upper and lower levels PBFY is computed using the Neumann
+! condition
+!
+  PBFY(1:IXMODEY_ll,1:IYMODEY_ll,IKB-1) = -0.5 * ( PRHOM(IKB-1) + PRHOM(IKB)   ) /  &
+                               ZDZM(IKB)   **2
+  !
+  PBFY(1:IXMODEY_ll,1:IYMODEY_ll,IKE+1) =  0.5 * ( PRHOM(IKE)   + PRHOM(IKE+1) ) /  &
+                               ZDZM(IKE+1) **2
+  !
+ELSE
+  DO JK= IKB,IKE
+    DO JJ= 1, IYMODEY_ll
+      DO JI= 1, IXMODEY_ll
+        PBFY(JJ,JI,JK) = PRHOM(JK)* ZEIGEN_ll(JI+IORXY_ll-1,JJ+IORYY_ll-1) - 0.5 * &
+        ( ( PRHOM(JK-1) + PRHOM(JK)   ) / ZDZM(JK)  **2                          &
+         +( PRHOM(JK)   + PRHOM(JK+1) ) / ZDZM(JK+1)**2 )
+      END DO
+    END DO
+  END DO
+! at the upper and lower levels PBFY is computed using the Neumann
+! condition
+!
+  PBFY(1:IYMODEY_ll,1:IXMODEY_ll,IKB-1) = -0.5 * ( PRHOM(IKB-1) + PRHOM(IKB)   ) /  &
+                               ZDZM(IKB)   **2
+  !
+  PBFY(1:IYMODEY_ll,1:IXMODEY_ll,IKE+1) =  0.5 * ( PRHOM(IKE)   + PRHOM(IKE+1) ) /  &
+                               ZDZM(IKE+1) **2
+  !
+
+!JUAN Z_SPLITTING
+!JUAN for Z splitting we need to do the vertical substitution
+!JUAN in Bsplitting slides so need PBFB 
+PBF_ZS = 1.0
+  DO JK= IKB,IKE
+    DO JJ= IJB,IJE
+      DO JI= IIB,IIE
+
+         PBFB(JI,JJ,JK) =  PRHOM(JK)* ( -2.0 / PDXHATM**2  -2.0 /PDYHATM**2  )       - 0.5 * &
+        ( ( PRHOM(JK-1) + PRHOM(JK)   ) / ZDZM(JK)  **2                                      &
+         +( PRHOM(JK)   + PRHOM(JK+1) ) / ZDZM(JK+1)**2 )
+
+         PBF_ZS(JI,JJ,JK) = PRHO_ZS(JI,JJ,JK)* ( -2.0 / PDXATH_ZS(JI,JJ)**2  -2.0 /PDYATH_ZS(JI,JJ)**2  )   - 0.5 * &
+        ( ( PRHO_ZS(JI,JJ,JK-1) + PRHO_ZS(JI,JJ,JK)   ) / ZDZM_ZS(JI,JJ,JK)  **2                                    &
+         +( PRHO_ZS(JI,JJ,JK)   + PRHO_ZS(JI,JJ,JK+1) ) / ZDZM_ZS(JI,JJ,JK+1)**2 )
+
+      END DO
+    END DO
+  END DO
+! at the upper and lower levels PBFB is computed using the Neumann
+! condition
+!
+  PBFB(IIB:IIE,IJB:IJE,IKB-1) = - 0.5 * ( PRHOM(IKB-1) + PRHOM(IKB)   ) / ZDZM(IKB)   **2
+  !
+  PBFB(IIB:IIE,IJB:IJE,IKE+1) = + 0.5 * ( PRHOM(IKE)   + PRHOM(IKE+1) ) / ZDZM(IKE+1) **2
+
+  PBF_ZS(IIB:IIE,IJB:IJE,IKB-1) = - 0.5 * ( PRHO_ZS(IIB:IIE,IJB:IJE,IKB-1) + PRHO_ZS(IIB:IIE,IJB:IJE,IKB)   ) &
+                                  / ZDZM_ZS(IIB:IIE,IJB:IJE,IKB)**2 
+
+  PBF_ZS(IIB:IIE,IJB:IJE,IKE+1) =   0.5 * ( PRHO_ZS(IIB:IIE,IJB:IJE,IKE)   + PRHO_ZS(IIB:IIE,IJB:IJE,IKE+1) ) &
+                                  / ZDZM_ZS(IIB:IIE,IJB:IJE,IKE+1)**2                         
+!
+IF (HLBCX(1) == 'CYCL' .AND. .NOT.(L2D) ) THEN
+   !JUAN
+   ! fil unused 2 coef with NI+1 coef (lost in Z transposition elsewhere )
+   JI = IXMODE_ll -1
+   ZEIGEN_ll(2,:)  = ZEIGEN_ll(JI,:)
+END IF
+IF (HLBCY(1) == 'CYCL' .AND. .NOT.(L2D) ) THEN
+   !JUAN
+   ! fill unused (:,2,:) coef with NJ+1 coef (lost in Z transposition elsewhere )
+   JJ = IYMODE_ll -1
+   ZEIGEN_ll(:,2)  = ZEIGEN_ll(:,JJ)
+END IF
+  !
+!JUAN Z_SPLITTING
+!JUAN Z_SPLITTING
+!JUAN for Z splitting we need to do the vertical substitution
+!JUAN in _SXP2_YP1_Zsplitting slides so need PBF_SXP2_YP1_Z 
+  DO JK=IKB,IKE
+    DO JJ= 1, IJU_SXP2_YP1_Z_ll
+      DO JI= 1, IIU_SXP2_YP1_Z_ll
+        PBF_SXP2_YP1_Z(JI,JJ,JK) = PRHOM(JK)* ZEIGEN_ll(JI+IORX_SXP2_YP1_Z_ll-IIB_ll,JJ+IORY_SXP2_YP1_Z_ll-IJB_ll) - 0.5 * &
+        ( ( PRHOM(JK-1) + PRHOM(JK)   ) / ZDZM(JK)  **2                          &
+         +( PRHOM(JK)   + PRHOM(JK+1) ) / ZDZM(JK+1)**2 )
+      END DO
+    END DO
+  END DO
+! at the upper and lower levels PBFB is computed using the Neumann
+! condition
+!
+  PBF_SXP2_YP1_Z(1:IIU_SXP2_YP1_Z_ll,1:IJU_SXP2_YP1_Z_ll,IKB-1) = -0.5 * ( PRHOM(IKB-1) + PRHOM(IKB)   ) /  &
+                               ZDZM(IKB)   **2
+  !
+  PBF_SXP2_YP1_Z(1:IIU_SXP2_YP1_Z_ll,1:IJU_SXP2_YP1_Z_ll,IKE+1) =  0.5 * ( PRHOM(IKE)   + PRHOM(IKE+1) ) /  &
+                               ZDZM(IKE+1) **2
+  !
+!JUAN Z_SPLITTING
+END IF
+!
+! second coefficent is meaningless in cyclic case
+IF (HLBCX(1) == 'CYCL' .AND. L2D .AND. SIZE(PBFY,1) .GE. 2 ) PBFY(2,:,:)=1.
+IF (HLBCX(1) == 'CYCL' .AND. .NOT.(L2D) .AND. LWEST_ll(HSPLITTING='Y') .AND. SIZE(PBFY,2) .GE.2 ) &
+    PBFY(:,2,:)=1.
+IF (HLBCY(1) == 'CYCL' .AND. .NOT.(L2D) .AND. SIZE(PBFY,1) .GE. 2  ) PBFY(2,:,:)=1.
+!JUAN Z_SPLITTING
+! second coefficent is meaningless in cyclic case
+!IF (HLBCX(1) == 'CYCL' .AND. L2D  .AND. SIZE(PBFB,1) .GE. 2  ) PBFB(2,:,:)=1.
+!IF (HLBCX(1) == 'CYCL' .AND. .NOT.(L2D) .AND. LWEST_ll(HSPLITTING='B')  .AND. SIZE(PBFB,2) .GE.2 ) &
+!    PBFB(:,2,:)=1.
+!IF (HLBCY(1) == 'CYCL' .AND. .NOT.(L2D)  .AND. SIZE(PBFB,1) .GE. 2 ) PBFB(2,:,:)=1.
+!JUAN Z_SPLITTING
+!
+DEALLOCATE(ZEIGEN_ll)
+!
+!
+!------------------------------------------------------------------------------
+!*       8.    INITIALIZATION OF THE TRIGS AND IFAX ARRAYS FOR THE FFT 
+!              -------------------------------------------------------
+!
+!        8.1 x lateral boundary conditions
+!                  
+CALL SET99(PTRIGSX,KIFAXX,IIMAX_ll)
+!
+! test on the value of KIMAX: KIMAX must be factorizable as a product
+! of powers of 2,3 and 5. KIFAXX(10) is equal to IIMAX if the decomposition 
+! is correct, then KIFAXX(1) contains the number of decomposition factors
+! of KIMAX.
+!
+IF (KIFAXX(10) /=  IIMAX_ll) THEN
+      WRITE(UNIT=ILUOUT,FMT="('   ERROR',/,                               &
+      &'     : THE FORM OF THE FFT USED FOR THE INVERSION OF THE FLAT ',/,&
+      &'    OPERATOR REQUIRES THAT KIMAX MUST BE FACTORIZABLE'         ,/,&
+      & '         AS A PRODUCT OF POWERS OF 2, 3 AND 5.')")
+ !callabortstop
+      CALL PRINT_MSG(NVERB_FATAL,'GEN','TRIDZ','')
+END IF 
+!
+IF (HLBCX(1) /= 'CYCL') THEN
+!
+!     extra trigs for shifted (co) sine transform (FFT55)
+!
+  INN=2*(IIMAX_ll)
+  ZDEL=ASIN(1.0)/REAL(IIMAX_ll)
+  DO JI=1,IIMAX_ll
+    ZANGLE=REAL(JI)*ZDEL
+    PTRIGSX(INN+JI)=SIN(ZANGLE)
+  END DO
+!
+ENDIF
+!
+!       8.2 y lateral boundary conditions
+!
+IF (.NOT. L2D) THEN 
+  CALL SET99(PTRIGSY,KIFAXY,IJMAX_ll)
+  !
+  ! test on the value of KJMAX: KJMAX must be factorizable as a product
+  ! of powers of 2,3 and 5. KIFAXY(10) is equal to IJMAX_ll if the decomposition 
+  ! is correct, then KIFAXX(1) contains the number of decomposition factors
+  ! of IIMAX_ll.
+  !
+  IF (KIFAXY(10) /= IJMAX_ll) THEN
+      WRITE(UNIT=ILUOUT,FMT="('   ERROR',/,                               &
+      &'     : THE FORM OF THE FFT USED FOR THE INVERSION OF THE FLAT ',/,&
+      &'    OPERATOR REQUIRES THAT KJMAX MUST BE FACTORIZABLE'         ,/,&
+      & '         AS A PRODUCT OF POWERS OF 2, 3 AND 5.')")
+ !callabortstop
+      CALL PRINT_MSG(NVERB_FATAL,'GEN','TRIDZ','')
+ END IF 
+ !
+ !
+ !     other cases 
+ !
+ IF (HLBCY(1) /= 'CYCL') THEN                
+ !
+ !     extra trigs for shifted (co) sine transform
+ !
+   INN=2*(IJMAX_ll)
+   ZDEL=ASIN(1.0)/REAL(IJMAX_ll)
+   DO JJ=1,IJMAX_ll
+     ZANGLE=REAL(JJ)*ZDEL
+     PTRIGSY(INN+JJ)=SIN(ZANGLE)
+   END DO
+ !
+ ENDIF
+ !
+ENDIF
+!
+!------------------------------------------------------------------------------
+!
+END SUBROUTINE TRIDZ
diff --git a/src/ZSOLVER/zconjgrad.f90 b/src/ZSOLVER/zconjgrad.f90
new file mode 100644
index 0000000000000000000000000000000000000000..35d82862f990a91586103de8401beed89b72f1a0
--- /dev/null
+++ b/src/ZSOLVER/zconjgrad.f90
@@ -0,0 +1,292 @@
+!MNH_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt  
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+!--------------- special set of characters for RCS information
+!-----------------------------------------------------------------
+! $Source$ $Revision$
+! MASDEV4_7 solver 2006/05/18 13:07:25
+!-----------------------------------------------------------------
+!     ####################
+      MODULE MODI_ZCONJGRAD
+!     ####################
+!
+INTERFACE
+!
+      SUBROUTINE ZCONJGRAD(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,PTHETAV, &
+      PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF,PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,         &
+      KITR,PY,PPHI)
+!  
+IMPLICIT NONE
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX    ! x-direction LBC type 
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY    ! y-direction LBC type 
+!
+                                                 ! Metric coefficients:
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDXX      ! d*xx 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDYY      ! d*yy 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZX      ! d*zx 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZY      ! d*zy 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZZ      ! d*zz
+!
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHODJ    ! density of reference * J
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PTHETAV   ! virtual potential temp. at time t
+!
+REAL, INTENT(IN) :: PDXHATM                     ! mean grid increment in the x
+                                                ! direction
+REAL, INTENT(IN) :: PDYHATM                     ! mean grid increment in the y
+                                                ! direction
+!
+REAL, DIMENSION (:), INTENT(IN) :: PRHOM         !  mean of XRHODJ on the plane x y 
+                                                 !  localized at a mass level
+!
+REAL, DIMENSION(:), INTENT(IN)     :: PAF,PCF    ! vectors giving the nonvanishing
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PBF        ! elements of the tri-diag. 
+                                                 ! matrix in the pressure eq.
+!
+                                                 ! arrays of sin or cos values
+                                                 ! for the FFT :
+REAL, DIMENSION(:), INTENT(IN) :: PTRIGSX        ! - along x
+REAL, DIMENSION(:), INTENT(IN) :: PTRIGSY        ! - along y
+!
+                                                 ! decomposition in prime 
+                                                 ! numbers for the FFT:
+INTEGER, DIMENSION(19), INTENT(IN) :: KIFAXX      ! - along x
+INTEGER, DIMENSION(19), INTENT(IN) :: KIFAXY      ! - along y
+!
+INTEGER, INTENT(IN) :: KITR                      ! number of iterations for the
+                                                 ! pressure solver
+!
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PY         ! RHS of the equation
+!          
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PPHI    ! solution of the equation 
+!
+END SUBROUTINE ZCONJGRAD
+!
+END INTERFACE
+!
+END  MODULE MODI_ZCONJGRAD
+!
+!
+!
+!     #########################################################################
+      SUBROUTINE ZCONJGRAD(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,PTHETAV, &
+      PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF,PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,         &
+      KITR,PY,PPHI)
+!     #########################################################################
+!
+!!****  *CONJGRAD * - solve an elliptic equation by the conjugate gradient 
+!!       method
+!!
+!!    PURPOSE
+!!    -------
+!       The purpose of this routine is to solve an elliptic equation using 
+!     the preditioned conjugate gradient (CG) method. This is a version of the 
+!     CG called ORTHOMIN (Young and Jea 1980).
+!     
+!!**  METHOD
+!!    ------
+!!      The equation to be solved reads:
+!!
+!!             Q (PHI) = Y
+!!
+!!    where Q is the quasi-Laplacian ( subroutine QLAP ) and PHI the pressure
+!!    function.
+!!    We precondition the problem by the operator F :
+!!             -1               -1 
+!!            F   * Q (PHI) = F    (Y)
+!!    F represents the flat Laplacian ie. without orography. Its inversion is 
+!!    realized in the routine FLAT_INV. This equation is solved with a Conjugate 
+!!    Gradient method.
+!!    The initial guess is given by the pressure at the previous time step.
+!!    The resolution stops after ITR iterations of the solver.
+!!
+!!    EXTERNAL
+!!    --------
+!!      Subroutine GDIV: compute J times the divergence of 1/J times a vector
+!!      Function QLAP: compute the complete quasi-Laplacian Q
+!!      Subroutine FLAT_INV : invert the flat quasi-laplacien F
+!!      Function DOTPROD: compute the dot product of 2 vectors
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------ 
+!!      Module MODI_GDIV: interface for the subroutine GDIV
+!!      Module MODI_QLAP: interface for the function QLAP
+!!      Module MODI_FLAT_INV: interface for the subroutine FLAT_INV
+!!      Module MODI_DOTPROD: interface for the function DOTPROD
+!!
+!!    REFERENCE
+!!    ---------
+!!      Book2 of documentation (routine CONJGRAD)
+!!      Kapitza and Eppel (1992) Beit. Physik ...
+!!      Young and Jea (1980) ....
+!!      
+!!    AUTHOR
+!!    ------
+!!	P. HÃ…reil and J. Stein       * Meteo France *
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original    25/07/94 
+!!
+!!                  14/01/97 Durran anelastic equation (Stein,Lafore)
+!-------------------------------------------------------------------------------
+!
+!*       0.     DECLARATIONS
+!               ------------
+!
+USE MODI_GDIV
+USE MODI_QLAP
+USE MODI_FLAT_INV
+USE MODI_DOTPROD
+USE MODI_ZSOLVER_INV
+!
+IMPLICIT NONE
+!
+!*      0.1    declarations of arguments
+!
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX    ! x-direction LBC type 
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY    ! y-direction LBC type 
+!
+                                                 ! Metric coefficients:
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDXX      ! d*xx 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDYY      ! d*yy 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZX      ! d*zx 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZY      ! d*zy 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZZ      ! d*zz
+!
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHODJ    ! density of reference * J
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PTHETAV   ! virtual potential temp. at time t
+!
+REAL, INTENT(IN) :: PDXHATM                     ! mean grid increment in the x
+                                                ! direction
+REAL, INTENT(IN) :: PDYHATM                     ! mean grid increment in the y
+                                                ! direction
+!
+REAL, DIMENSION (:), INTENT(IN) :: PRHOM         !  mean of XRHODJ on the plane x y 
+                                                 !  localized at a mass level
+!
+REAL, DIMENSION(:), INTENT(IN)     :: PAF,PCF    ! vectors giving the nonvanishing
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PBF        ! elements of the tri-diag. 
+                                                 ! matrix in the pressure eq.
+!
+                                                 ! arrays of sin or cos values
+                                                 ! for the FFT :
+REAL, DIMENSION(:), INTENT(IN) :: PTRIGSX        ! - along x
+REAL, DIMENSION(:), INTENT(IN) :: PTRIGSY        ! - along y
+!
+                                                 ! decomposition in prime 
+                                                 ! numbers for the FFT:
+INTEGER, DIMENSION(19), INTENT(IN) :: KIFAXX      ! - along x
+INTEGER, DIMENSION(19), INTENT(IN) :: KIFAXY      ! - along y
+!
+INTEGER, INTENT(IN) :: KITR                      ! number of iterations for the
+                                                 ! pressure solver
+!
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PY         ! RHS of the equation
+!          
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PPHI    ! solution of the equation 
+!
+!*      0.2    declarations of local variables
+!
+INTEGER :: JM                                    ! loop index   
+!
+REAL, DIMENSION(SIZE(PPHI,1),SIZE(PPHI,2),SIZE(PPHI,3)) :: ZDELTA  
+     ! array containing the auxilary field DELTA of the CG method
+!
+REAL, DIMENSION(SIZE(PPHI,1),SIZE(PPHI,2),SIZE(PPHI,3)) :: ZP  
+     ! array containing the auxilary field P of the CG method
+!
+REAL, DIMENSION(SIZE(PPHI,1),SIZE(PPHI,2),SIZE(PPHI,3)) :: ZWORK ! work 
+     ! array containing the source term to be multiplied by the F inverse
+!
+REAL, DIMENSION(SIZE(PPHI,1),SIZE(PPHI,2),SIZE(PPHI,3)) :: ZWORKD ! work 
+     ! array containing the result of the F inversion * Q (DELTA)
+!
+REAL, DIMENSION(SIZE(PPHI,1),SIZE(PPHI,2),SIZE(PPHI,3)) :: ZWORKP ! work 
+     ! array containing the result of the F inversion * Q (P)
+!
+REAL :: ZALPHA, ZLAMBDA      ! amplitude of the descent in the Conjugate
+                             ! directions
+REAL :: ZDOTPP               ! dot product of ZWORKP by itself
+!
+!-------------------------------------------------------------------------------
+!
+!*       1.    INITIALIZATIONS
+!              ---------------
+!
+ZLAMBDA = 0.
+ZP = 0.
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.    ITERATIVE LOOP
+!              --------------
+!
+DO JM = 1,KITR                                                         
+!
+!*       2.1    compute the new pressure function
+!
+  PPHI = PPHI + ZLAMBDA * ZP     !   the case JM =0 is special because 
+                                 !   PPHI is not changed
+!
+!*       2.2    compute the auxiliary field DELTA
+!
+!                                -1
+!   compute the vector DELTA = F  * ( Y - Q ( PHI ) )
+!    
+  ZWORK = QLAP(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,PTHETAV,PPHI) 
+                                                               ! Q (PHI)
+!                       
+  ZWORK = PY - ZWORK                                           ! Y - Q (PHI)
+!
+  CALL FLAT_INV(HLBCX,HLBCY,PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF, &!  -1
+                  PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,ZWORK,ZDELTA)   ! F  (Y - Q (PHI)))
+!   
+!*      2.3     compute the auxiliary field P
+!
+!                                         -1
+!   compute the vector P = DELTA + alpha F  * Q ( DELTA ) 
+!  
+  IF (JM == 1) THEN
+    ZP = ZDELTA          ! P = DELTA at the first solver iteration
+  ELSE
+    ZWORK  = QLAP(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,  &
+                PDZZ,PRHODJ,PTHETAV,ZDELTA)                         ! Q ( DELTA )
+    CALL FLAT_INV(HLBCX,HLBCY,PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF,  & !  -1
+            PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,ZWORK,ZWORKD)             ! F  * Q ( DELTA ) 
+!
+    ZALPHA = - DOTPROD(ZWORKD,ZWORKP,HLBCX,HLBCY)/ZDOTPP   ! ZWORKP,ZDOTPP come 
+                     ! from the previous solver iteration  (section 2.4)
+    ZP = ZDELTA + ZALPHA * ZP                              ! new vector P
+!
+  END IF
+!
+!*      2.4     compute LAMBDA
+!
+!
+  ZWORK = QLAP(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,&
+  PDZZ,PRHODJ,PTHETAV,ZP)                                       ! Q ( P )
+  CALL FLAT_INV(HLBCX,HLBCY,PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF,& !  -1
+  PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,ZWORK,ZWORKP)                   ! F  * Q ( P )
+!
+!    store the scalar product to compute lambda and next P
+  ZDOTPP = DOTPROD(ZWORKP,ZWORKP,HLBCX,HLBCY)   
+!
+  ZLAMBDA = DOTPROD(ZDELTA,ZWORKP,HLBCX,HLBCY) / ZDOTPP   ! lambda
+!
+!
+END DO              ! end of the loop for the iterative solver
+!
+!-------------------------------------------------------------------------------
+!
+!*       3.    COMPUTE THE FINAL PRESSURE FUNCTION
+!              -----------------------------------
+!
+PPHI = PPHI + ZLAMBDA * ZP
+!  
+!-------------------------------------------------------------------------------
+!
+END SUBROUTINE ZCONJGRAD
diff --git a/src/ZSOLVER/zsolver.f90 b/src/ZSOLVER/zsolver.f90
new file mode 100644
index 0000000000000000000000000000000000000000..779a6b5685912b69249552d79b93337d17edd1bf
--- /dev/null
+++ b/src/ZSOLVER/zsolver.f90
@@ -0,0 +1,314 @@
+!MNH_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt  
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+!--------------- special set of characters for RCS information
+!-----------------------------------------------------------------
+! $Source$ $Revision$
+! MASDEV4_7 solver 2006/05/18 13:07:25
+!-----------------------------------------------------------------
+!     ####################
+      MODULE MODI_ZSOLVER
+!     ####################
+!
+INTERFACE
+!
+      SUBROUTINE ZSOLVER(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,PTHETAV, &
+      PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF,PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,        &
+      KITR,PY,PPHI,                                                           &
+      PAF_ZS,PBF_ZS,PCF_ZS,                                                   &
+      PDXATH_ZS,PDYATH_ZS,PRHO_ZS,PBFB,                                     &
+      A_K,B_K,C_K,D_K) !JUAN FULL ZSOLVER
+!  
+IMPLICIT NONE
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX    ! x-direction LBC type 
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY    ! y-direction LBC type 
+!
+                                                 ! Metric coefficients:
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDXX      ! d*xx 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDYY      ! d*yy 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZX      ! d*zx 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZY      ! d*zy 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZZ      ! d*zz
+!
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHODJ    ! density of reference * J
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PTHETAV   ! virtual pot. temp. at time t
+!
+REAL, INTENT(IN) :: PDXHATM                     ! mean grid increment in the x
+                                                ! direction
+REAL, INTENT(IN) :: PDYHATM                     ! mean grid increment in the y
+                                                ! direction
+!
+REAL, DIMENSION (:), INTENT(IN) :: PRHOM         !  XRHODJ mean on the X Y plane
+                                                 !  localized at a mass level
+!
+REAL, DIMENSION(:), INTENT(IN)     :: PAF,PCF    ! vectors giving the nonvanishing
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PBF        ! elements of the tri-diag. 
+                                                 ! matrix in the pressure eq.
+!
+                                                 ! arrays of sin or cos values
+                                                 ! for the FFT :
+REAL, DIMENSION(:), INTENT(IN) :: PTRIGSX        ! - along x
+REAL, DIMENSION(:), INTENT(IN) :: PTRIGSY        ! - along y
+!
+                                                 ! decomposition in prime 
+                                                 ! numbers for the FFT:
+INTEGER, DIMENSION(19), INTENT(IN) :: KIFAXX      ! - along x
+INTEGER, DIMENSION(19), INTENT(IN) :: KIFAXY      ! - along y
+!
+INTEGER, INTENT(IN) :: KITR                      ! number of iterations for the
+                                                 ! pressure solver
+!
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PY         ! RHS of the equation
+!          
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PPHI    ! solution of the equation 
+
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PAF_ZS,PBF_ZS,PCF_ZS
+REAL, DIMENSION(:,:)  , INTENT(IN) :: PDXATH_ZS,PDYATH_ZS
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHO_ZS,PBFB
+REAL, DIMENSION(:)    , INTENT(IN) :: A_K,B_K,C_K,D_K
+!
+END SUBROUTINE ZSOLVER
+!
+END INTERFACE
+!
+END  MODULE MODI_ZSOLVER
+!
+!
+!
+!     #########################################################################
+      SUBROUTINE ZSOLVER(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,PTHETAV, &
+      PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF,PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,        &
+      KITR,PY,PPHI,                                                           &
+      PAF_ZS,PBF_ZS,PCF_ZS,                                                   &
+      PDXATH_ZS,PDYATH_ZS,PRHO_ZS,PBFB,                                       &
+      A_K,B_K,C_K,D_K)
+!     #########################################################################
+!
+!!****  *CONRESOL * - solve an elliptic equation by the conjugate residual
+!!       method
+!!
+!!    PURPOSE
+!!    -------
+!       The purpose of this routine is to solve an elliptic equation using 
+!     the preconditioned conjugate residual (CR) method. This is a version
+!     of the scheme proposed by Skamarock, Smolarkiewicz and Klemp (MWR, 1997).
+!     
+!!**  METHOD
+!!    ------
+!!      The equation to be solved reads:
+!!
+!!             Q (PHI) = Y
+!!
+!!    where Q is the quasi-Laplacian ( subroutine QLAP ) and PHI the pressure
+!!    function.
+!!    We precondition the problem by the operator F :
+!!             -1               -1 
+!!            F   * Q (PHI) = F    (Y)
+!!    F represents the flat Laplacian ie. without orography. Its inversion is 
+!!    realized in the routine FLAT_INV. This equation is solved with a Conjugate
+!!    Residual method.
+!!    The initial guess is given by the pressure at the previous time step.
+!!    The resolution stops after ITR iterations of the solver.
+!!
+!!    EXTERNAL
+!!    --------
+!!      Subroutine GDIV: compute J times the divergence of 1/J times a vector
+!!      Function QLAP: compute the complete quasi-Laplacian Q
+!!      Subroutine FLAT_INV : invert the flat quasi-laplacien F
+!!      Function DOTPROD: compute the dot product of 2 vectors
+!!
+!!    IMPLICIT ARGUMENTS
+!!    ------------------ 
+!!      Module MODI_GDIV: interface for the subroutine GDIV
+!!      Module MODI_QLAP: interface for the function QLAP
+!!      Module MODI_FLAT_INV: interface for the subroutine FLAT_INV
+!!      Module MODI_DOTPROD: interface for the function DOTPROD
+!!
+!!    REFERENCE
+!!    ---------
+!!      Book2 of documentation (routine CONRESOL)
+!!      Skamarock, Smolarkiewicz and Klemp (1997) MWR
+!!      
+!!    AUTHOR
+!!    ------
+!!	J.-P. Pinty *Laboratoire d'Aerologie*
+!!
+!!    MODIFICATIONS
+!!    -------------
+!!      Original    25/08/99 
+!!      J.-P. Pinty & P. Jabouille
+!!                  11/07/00 bug in ZALPHA
+!!
+!-------------------------------------------------------------------------------
+!
+!*       0.     DECLARATIONS
+!               ------------
+!
+USE MODI_GDIV
+USE MODI_QLAP
+USE MODI_FLAT_INV
+USE MODI_ZSOLVER_INV
+USE MODI_DOTPROD
+!
+IMPLICIT NONE
+!
+!*      0.1    declarations of arguments
+!
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX    ! x-direction LBC type 
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY    ! y-direction LBC type 
+!
+                                                 ! Metric coefficients:
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDXX      ! d*xx 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDYY      ! d*yy 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZX      ! d*zx 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZY      ! d*zy 
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PDZZ      ! d*zz
+!
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PRHODJ    ! density of reference * J
+REAL, DIMENSION(:,:,:), INTENT(IN)  :: PTHETAV   ! virtual pot. temp. at time t
+!
+REAL, INTENT(IN) :: PDXHATM                     ! mean grid increment in the x
+                                                ! direction
+REAL, INTENT(IN) :: PDYHATM                     ! mean grid increment in the y
+                                                ! direction
+!
+REAL, DIMENSION (:), INTENT(IN) :: PRHOM         !  mean of XRHODJ on the plane x y 
+                                                 !  localized at a mass level
+!
+REAL, DIMENSION(:), INTENT(IN)     :: PAF,PCF    ! vectors giving the nonvanishing
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PBF        ! elements of the tri-diag. 
+                                                 ! matrix in the pressure eq.
+!
+                                                 ! arrays of sin or cos values
+                                                 ! for the FFT :
+REAL, DIMENSION(:), INTENT(IN) :: PTRIGSX        ! - along x
+REAL, DIMENSION(:), INTENT(IN) :: PTRIGSY        ! - along y
+!
+                                                 ! decomposition in prime 
+                                                 ! numbers for the FFT:
+INTEGER, DIMENSION(19), INTENT(IN) :: KIFAXX      ! - along x
+INTEGER, DIMENSION(19), INTENT(IN) :: KIFAXY      ! - along y
+!
+INTEGER, INTENT(IN) :: KITR                      ! number of iterations for the
+                                                 ! pressure solver
+!
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PY         ! RHS of the equation
+!          
+REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PPHI    ! solution of the equation 
+
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PAF_ZS,PBF_ZS,PCF_ZS
+REAL, DIMENSION(:,:)  , INTENT(IN) :: PDXATH_ZS,PDYATH_ZS
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHO_ZS,PBFB
+REAL, DIMENSION(:)    , INTENT(IN) :: A_K,B_K,C_K,D_K
+!
+!*      0.2    declarations of local variables
+!
+INTEGER :: JM                                    ! loop index   
+!
+REAL, DIMENSION(SIZE(PPHI,1),SIZE(PPHI,2),SIZE(PPHI,3)) :: ZDELTA, ZKSI  
+     ! array containing the auxilary fields DELTA and KSI of the CR method
+REAL, DIMENSION(SIZE(PPHI,1),SIZE(PPHI,2),SIZE(PPHI,3)) :: ZP, ZQ  
+     ! array containing the auxilary fields P and Q of the CR method
+REAL, DIMENSION(SIZE(PPHI,1),SIZE(PPHI,2),SIZE(PPHI,3)) :: ZRESIDUE
+     ! array containing the error field at each iteration Q(PHI) - Y
+!
+REAL :: ZALPHA, ZLAMBDA      ! amplitude of the descent in the Conjugate
+                             ! directions
+REAL :: ZDOT_DELTA           ! dot product of ZDELTA by itself
+!
+!-------------------------------------------------------------------------------
+!
+!*       1.    INITIALIZATIONS
+!              ---------------
+!
+!                             
+!*       1.1    compute the vector: r^(0) =  Q(PHI) - Y
+!
+#ifndef MNH_OPENACC
+ZRESIDUE = QLAP(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,PTHETAV,PPHI) - PY
+#else
+CALL  QLAP_DEVICE(ZRESIDUE,HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,PTHETAV,PPHI)
+ZRESIDUE = ZRESIDUE - PY
+#endif
+!
+!*       1.2    compute the vector: p^(0) = F^(-1)*( Q(PHI) - Y )
+!    
+CALL ZSOLVER_INV(HLBCX,HLBCY,PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF,  &
+                     PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,ZRESIDUE,ZP,  &
+                     PAF_ZS,PBF_ZS,PCF_ZS,                       &
+                     PDXATH_ZS,PDYATH_ZS,PRHO_ZS,PBFB,           &
+                     A_K,B_K,C_K,D_K)
+!
+!*       1.3    compute the vector: delta^(0) = Q ( p^(0) )
+!
+#ifndef MNH_OPENACC
+ZDELTA = QLAP(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,PTHETAV,ZP)
+#else
+CALL  QLAP_DEVICE(ZDELTA,HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,PTHETAV,ZP)
+#endif
+!
+!-------------------------------------------------------------------------------
+!
+!*       2.    ITERATIVE LOOP
+!              --------------
+!
+DO JM = 1,KITR                                                         
+!
+!*       2.1    compute the step LAMBDA
+!
+  ZDOT_DELTA = DOTPROD(ZDELTA,  ZDELTA,HLBCX,HLBCY)            ! norm of DELTA
+  ZLAMBDA  = - DOTPROD(ZRESIDUE,ZDELTA,HLBCX,HLBCY) / ZDOT_DELTA
+!
+!*       2.2    update the pressure function PHI
+!
+  !$acc kernels
+  PPHI = PPHI + ZLAMBDA * ZP
+  !$acc end kernels
+!
+!
+  IF( JM == KITR ) EXIT
+!
+!
+!*       2.3    update the residual error: r
+  !
+  !$acc kernels
+  ZRESIDUE = ZRESIDUE + ZLAMBDA * ZDELTA
+  !$acc end kernels
+!                        
+!*       2.4    compute the vector: q = F^(-1)*( Q(PHI) - Y )
+!    
+  CALL ZSOLVER_INV(HLBCX,HLBCY,PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF,  &
+                       PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,ZRESIDUE,ZQ,  &
+                       PAF_ZS,PBF_ZS,PCF_ZS,                       &
+                       PDXATH_ZS,PDYATH_ZS,PRHO_ZS,PBFB,           &
+                       A_K,B_K,C_K,D_K)
+!   
+!*       2.5     compute the auxiliary field: ksi = Q ( q )
+!
+#ifndef MNH_OPENACC  
+  ZKSI= QLAP(HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,PTHETAV,ZQ)
+#else
+  CALL QLAP_DEVICE(ZKSI,HLBCX,HLBCY,PDXX,PDYY,PDZX,PDZY,PDZZ,PRHODJ,PTHETAV,ZQ)
+#endif  
+!                                         -1
+!*       2.6     compute the step ALPHA
+!  
+  ZALPHA = - DOTPROD(ZKSI,ZDELTA,HLBCX,HLBCY) / ZDOT_DELTA   ! lambda
+!
+!*       2.7     update p and DELTA
+!
+  !$acc kernels
+  ZP     = ZQ   + ZALPHA * ZP
+  ZDELTA = ZKSI + ZALPHA * ZDELTA
+  !$acc end kernels
+!
+END DO              ! end of the loop for the iterative solver
+!
+!  
+!-------------------------------------------------------------------------------
+!
+END SUBROUTINE ZSOLVER
diff --git a/src/ZSOLVER/zsolver_inv.f90 b/src/ZSOLVER/zsolver_inv.f90
new file mode 100644
index 0000000000000000000000000000000000000000..e6cfc214eef4a48d8064037fd25c42d35fee1078
--- /dev/null
+++ b/src/ZSOLVER/zsolver_inv.f90
@@ -0,0 +1,478 @@
+!MNH_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt  
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+!--------------- special set of characters for RCS information
+!-----------------------------------------------------------------
+! $Source$ $Revision$
+! MASDEV4_7 solver 2006/05/18 13:07:25
+!-----------------------------------------------------------------
+!     ####################
+      MODULE MODI_ZSOLVER_INV
+!     ####################
+!
+INTERFACE
+!
+      SUBROUTINE ZSOLVER_INV(HLBCX,HLBCY,PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF, &
+      PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,PY,PF_1_Y,                              &
+      PAF_ZS,PBF_ZS,PCF_ZS,                                                 &
+      PDXATH_ZS,PDYATH_ZS,PRHO_ZS,PBFB,                                     &
+      A_K,B_K,C_K,D_K)
+!
+!  
+IMPLICIT NONE
+!
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX    ! x-direction LBC type 
+CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY    ! y-direction LBC type 
+!
+REAL, INTENT(IN) :: PDXHATM                     ! mean grid increment in the x
+                                                ! direction
+REAL, INTENT(IN) :: PDYHATM                     ! mean grid increment in the y
+                                                ! direction
+!
+REAL, DIMENSION (:), INTENT(IN) :: PRHOM         !  mean of XRHODJ on the plane x y 
+                                                 !  localized at a mass level
+!
+REAL, DIMENSION(:), INTENT(IN)     :: PAF,PCF    ! vectors giving the nonvanishing
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PBF        ! elements of the tri-diag. 
+                                                 ! matrix in the pressure eq.
+!
+                                                 ! arrays of sin or cos values
+                                                 ! for the FFT :
+REAL, DIMENSION(:), INTENT(IN) :: PTRIGSX        ! - along x
+REAL, DIMENSION(:), INTENT(IN) :: PTRIGSY        ! - along y
+!
+                                                 ! decomposition in prime 
+                                                 ! numbers for the FFT:
+INTEGER, DIMENSION(19), INTENT(IN) :: KIFAXX      ! - along x
+INTEGER, DIMENSION(19), INTENT(IN) :: KIFAXY      ! - along y
+!
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PY         ! RHS of the equation
+!                                                         
+REAL, DIMENSION(:,:,:), INTENT(OUT):: PF_1_Y     ! solution of the equation
+!
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PAF_ZS,PBF_ZS,PCF_ZS
+REAL, DIMENSION(:,:)  , INTENT(IN) :: PDXATH_ZS,PDYATH_ZS
+REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHO_ZS,PBFB
+REAL, DIMENSION(:)    , INTENT(IN) :: A_K,B_K,C_K,D_K
+!
+!
+END SUBROUTINE ZSOLVER_INV
+!
+END INTERFACE
+!
+END MODULE MODI_ZSOLVER_INV
+!     ######################################################################
+SUBROUTINE ZSOLVER_INV(HLBCX,HLBCY,PDXHATM,PDYHATM,PRHOM,PAF,PBF,PCF, &
+     PTRIGSX,PTRIGSY,KIFAXX,KIFAXY,PY,PF_1_Y,                              &
+     PAF_ZS,PBF_ZS,PCF_ZS,                                                 &
+     PDXATH_ZS,PDYATH_ZS,PRHO_ZS,PBFB,                                     &
+     A_K,B_K,C_K,D_K)
+  !     ######################################################################
+  !
+  !!****  *FLAT_INV * - Invert the flat quasi-laplacian operator
+  !!
+  !!    PURPOSE
+  !!    -------
+  !       This routine solves the following equation:
+  !                    F ( F_1_Y ) =  Y 
+  !     where F represents the quasi-laplacian without orography. The solution is 
+  !     F_1_Y.
+  !
+  !!**  METHOD
+  !!    ------
+  !!      The horizontal part of F is inverted with a FFT transform. For each 
+  !!    horizontal direction, the FFT form depends on the lateral boundary 
+  !!    conditions :
+  !!    - CRAY intrinsic function RFFTMLT in the cyclic case 
+  !!    - fast cosine transform called FFT55 for all other boundary condtions.
+  !!    Then, in the wavenumber space, we invert for each 
+  !!    horizontal mode i,j a tridiagonal matrix by a classical double sweep 
+  !!    method.  The singular mean mode (i,j)=(0,0) corresponds to the 
+  !!    undetermination of the pressure to within a constant and is treated apart.
+  !!    To fix this degree of freedom, we set the horizontal mean value of the 
+  !!    pressure perturbation to 0 at the upper level of the model. 
+  !!       
+  !!    EXTERNAL
+  !!    --------
+  !!      Subroutine FFT55 : aplly multiple fast real staggered (shifted) 
+  !!    cosine transform
+  !!      Subroutine RFFTMLT : apply real-to-complex or complex-to-real Fast 
+  !!    Fourier Transform (FFT) on multiple input vectors.
+  !!      Subroutine FFT991  : equivalent to RFFTMLT
+  !!
+  !!    IMPLICIT ARGUMENTS
+  !!    ------------------ 
+  !!      Module MODD_PARAMETERS: declaration of parameter variables
+  !!        JPHEXT, JPVEXT: define the number of marginal points out of the 
+  !!        physical domain along horizontal and vertical directions respectively
+  !!      Module MODD_CONF: model configurations
+  !!        L2D: logical for 2D model version
+  !!
+  !!    REFERENCE
+  !!    ---------
+  !!      Book2 of documentation (subroutine FLAT_INV)     
+  !!
+  !!    AUTHOR
+  !!    ------
+  !!	P. Hereil and J. Stein       * Meteo France *
+  !!
+  !!    MODIFICATIONS
+  !!    -------------
+  !!      Original    20/07/94 
+  !!      Revision  Jabouille (juillet 96) replace the CRAY intrinsic function
+  !!                             RFFTMLT by the arpege routine FFT991
+  !!                  17/07/97  ( J. Stein and V. Masson) initialize the corner
+  !!                             verticals
+  !!                  17/07/97  ( J. Stein and V. Masson) initialize the corner
+  !!                             verticals
+  !!      Revision  Jabouille (septembre 97) suppress the particular case for
+  !!                                         tridiagonal inversion
+  !!                Stein     ( January 98 ) faster computation for the unused 
+  !!                                points under the ground and out of the domain  
+  !!      Modification   Lugato, Guivarch (June 1998) Parallelisation
+  !!                     Escobar, Stein   (July 2000) optimisation
+  !-------------------------------------------------------------------------------
+  !
+  !*       0.    DECLARATIONS
+  !              ------------
+  !
+  USE MODD_PARAMETERS
+  USE MODD_CONF
+  !
+  USE MODE_ll
+  USE MODD_ARGSLIST_ll, ONLY : LIST_ll
+  !
+  USE MODI_FFT55
+  USE MODI_GET_HALO
+  USE MODI_FLAT_INV
+  USE MODI_DOTPROD
+  !
+  USE mode_mg_main_mnh
+  !
+  IMPLICIT NONE
+  !
+  !*       0.1   declarations of arguments
+  !
+  CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX    ! x-direction LBC type 
+  CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY    ! y-direction LBC type 
+  !
+  REAL, INTENT(IN) :: PDXHATM                     ! mean grid increment in the x
+  ! direction
+  REAL, INTENT(IN) :: PDYHATM                     ! mean grid increment in the y
+  ! direction
+  !
+  REAL, DIMENSION (:), INTENT(IN) :: PRHOM         !  mean of XRHODJ on the plane x y 
+  !  localized at a mass level
+  !
+  REAL, DIMENSION(:), INTENT(IN)     :: PAF,PCF    ! vectors giving the nonvanishing
+  REAL, DIMENSION(:,:,:), INTENT(IN) :: PBF        ! elements of the tri-diag. 
+  ! matrix in the pressure eq.
+  !
+  ! arrays of sin or cos values
+  ! for the FFT :
+  REAL, DIMENSION(:), INTENT(IN) :: PTRIGSX        ! - along x
+  REAL, DIMENSION(:), INTENT(IN) :: PTRIGSY        ! - along y
+  !
+  ! decomposition in prime 
+  ! numbers for the FFT:
+  INTEGER, DIMENSION(19), INTENT(IN) :: KIFAXX      ! - along x
+  INTEGER, DIMENSION(19), INTENT(IN) :: KIFAXY      ! - along y
+  !
+  REAL, DIMENSION(:,:,:), INTENT(IN) :: PY         ! RHS of the equation
+  !                                                         
+  REAL, DIMENSION(:,:,:), INTENT(OUT):: PF_1_Y     ! solution of the equation
+  !
+  REAL, DIMENSION(:,:,:), INTENT(IN) :: PAF_ZS,PBF_ZS,PCF_ZS
+  REAL, DIMENSION(:,:)  , INTENT(IN) :: PDXATH_ZS,PDYATH_ZS
+  REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHO_ZS,PBFB
+  REAL, DIMENSION(:)    , INTENT(IN) :: A_K,B_K,C_K,D_K
+  !
+  !*       0.2   declaration of local variables
+  !
+  REAL, DIMENSION(SIZE(PY,1),SIZE(PY,2),SIZE(PY,3)) :: ZY ! work array to store 
+  ! the RHS of the equation
+  !
+  !REAL, DIMENSION(SIZE(PY,1),SIZE(PY,2),SIZE(PY,3)) :: ZWORK ! work array used by 
+  ! the FFT. It has been enlarged in order to be sufficient for 2D and 3D cases
+  !
+  REAL, DIMENSION(SIZE(PBF,1),SIZE(PBF,2),SIZE(PBF,3)) :: ZAF ! work array to
+  !                                                        ! expand PAF
+  INTEGER :: IIB          ! indice I for the first inner mass point along x
+  INTEGER :: IIE          ! indice I for the last inner mass point along x
+  INTEGER :: IJB          ! indice J for the first inner mass point along y
+  INTEGER :: IJE          ! indice J for the last inner mass point along y
+  INTEGER :: IKB          ! indice K for the first inner mass point along z
+  INTEGER :: IKE          ! indice K for the last inner mass point along z
+  INTEGER :: IKU          ! size of the arrays along z
+  !
+  INTEGER :: JI,JJ,JK     ! loop indexes along x, y, z respectively
+  INTEGER :: IIU,IJU
+  !-------------------------------------------------------------------------------
+  !
+  !*       1.    COMPUTE LOOP BOUNDS
+  !              -------------------
+  !
+  !CALL GET_PHYSICAL_ll(IIB,IJB,IIE,IJE)
+  CALL GET_INDICE_ll(IIB,IJB,IIE,IJE)
+  CALL GET_DIM_EXT_ll('B',IIU,IJU)
+  !
+  IKU=SIZE(PY,3)
+  IKB=1+JPVEXT
+  IKE=IKU - JPVEXT
+  !
+  !
+  !-------------------------------------------------------------------------------
+  !
+  !*      3.    FORM HOMOGENEOUS BOUNDARY CONDITIONS FOR A NONCYCLIC CASE
+  !             ---------------------------------------------------------
+  !
+  !
+  !*      3.1 copy the RHS in a local array REMAP functions will shift the indices for the FFT
+  !
+  !$acc kernels
+  PF_1_Y = 0.
+  ZY = PY
+  !$acc end kernels
+  !
+  !*      3.2 form homogeneous boundary condition used by the FFT for non-periodic
+  !           cases
+  !
+  !  modify the RHS in the x direction
+  !
+  IF (HLBCX(1) /= 'CYCL') THEN
+     !
+     IF (LWEST_ll(HSPLITTING='B')) THEN
+        !$acc kernels async
+        DO JK=IKB,IKE                    
+           DO JJ = IJB, IJE
+              ZY(IIB,JJ,JK)     = ZY(IIB,JJ,JK)     + PY(IIB-1,JJ,JK)
+           END DO
+        END DO
+        !$acc end kernels
+     END IF
+     !
+     IF (LEAST_ll(HSPLITTING='B')) THEN
+        !$acc kernels async
+        DO JK=IKB,IKE
+           DO JJ = IJB, IJE
+              ZY(IIE,JJ,JK)     = ZY(IIE,JJ,JK)     - PY(IIE+1,JJ,JK)
+           END DO
+        END DO
+        !$acc end kernels
+     END IF
+  END IF
+  !
+  ! modify the RHS in the same way along y
+  !
+  IF (HLBCY(1) /= 'CYCL'.AND. (.NOT. L2D)) THEN
+     IF (LSOUTH_ll(HSPLITTING='B')) THEN
+        !$acc kernels async
+        DO JK=IKB,IKE
+           DO JI = IIB, IIE
+              ZY(JI,IJB,JK)     = ZY(JI,IJB,JK)     + PY(JI,IJB-1,JK)
+           END DO
+        END DO
+        !$acc end kernels
+     END IF
+     !
+     IF (LNORTH_ll(HSPLITTING='B')) THEN
+        !$acc kernels async
+        DO JK=IKB,IKE
+           DO JI = IIB, IIE
+              ZY(JI,IJE,JK)     = ZY(JI,IJE,JK)     - PY(JI,IJE+1,JK)
+           END DO
+        END DO
+        !$acc end kernels
+     END IF
+  END IF
+  !$acc wait
+  !
+  !-------------------------------------------------------------------------------
+  !
+  !*      5.    MATRIX INVERSION FOR THE FLAT OPERATOR
+  !             --------------------------------------
+  !
+  IF (L2D) THEN
+     STOP ' NO 2D MULTIGRID YET '
+  END IF
+
+  call mg_main_initialise_rhs_mnh(IIB,IIE,IIU,IJB,IJE,IJU,IKU,ZY)
+  call mg_main_initialise_u_mnh(IIB,IIE,IIU,IJB,IJE,IJU,IKU,PF_1_Y)
+
+  !print*,'************************ mg_main_mnh_solve ***************************'
+       
+  call mg_main_mnh_solve()  
+  call mg_main_get_u_mnh(IIB,IIE,IIU,IJB,IJE,IJU,IKU,PF_1_Y)
+  !
+  !  WARNING WITH GET_HALO_D not BITREPROD !!!
+  !
+  CALL GET_HALO(PF_1_Y)
+  !
+  CALL PF_1_Y_BOUND(PF_1_Y)  
+  !-------------------------------------------------------------------------------
+  !
+CONTAINS
+
+SUBROUTINE PF_1_Y_BOUND(PF_1_Y)
+
+IMPLICIT NONE
+
+REAL , DIMENSION (:,:,:) :: PF_1_Y
+
+INTEGER :: ZDXM2, ZDYM2
+
+  !-------------------------------------------------------------------------------
+  !
+  !*      7.    RETURN TO A NON HOMOGENEOUS NEUMAN CONDITION FOR NON-CYCLIC CASES
+  !             -----------------------------------------------------------------
+  !
+  !*      7.2 complete the lateral boundaries
+  !
+  IF (HLBCX(1) /= 'CYCL') THEN
+     !
+     !*      7.2.1 return to a non-homogeneous case in the x direction
+     ! 
+     ZDXM2 = PDXHATM*PDXHATM
+     !
+     IF (LWEST_ll(HSPLITTING='B')) THEN
+        !$acc kernels loop independent collapse(2) async
+        DO JK=IKB,IKE
+           DO JJ = IJB,IJE
+              PF_1_Y(IIB-1,JJ,JK) = PF_1_Y(IIB,JJ,JK) - PY(IIB-1,JJ,JK)*ZDXM2/PRHOM(JK)
+           END DO
+        END DO
+        !$acc end kernels
+     END IF
+     !
+     IF (LEAST_ll(HSPLITTING='B')) THEN
+        !$acc kernels loop independent collapse(2) async
+        DO JK=IKB,IKE
+           DO JJ = IJB,IJE
+              PF_1_Y(IIE+1,JJ,JK) = PF_1_Y(IIE,JJ,JK) + PY(IIE+1,JJ,JK)*ZDXM2/PRHOM(JK)
+           END DO
+        END DO
+        !$acc end kernels
+     END IF
+     !$acc wait
+     !
+     !    we set the solution at the corner point by the condition:
+     !    dxm ( P ) = 0
+     IF (LWEST_ll(HSPLITTING='B')) THEN
+        !$acc kernels loop independent async
+        DO JJ = IJB,IJE
+           PF_1_Y(IIB-1,JJ,IKB-1) = PF_1_Y(IIB,JJ,IKB-1) 
+           PF_1_Y(IIB-1,JJ,IKE+1) = PF_1_Y(IIB,JJ,IKE+1)
+        END DO
+        !$acc end kernels
+     END IF
+     IF (LEAST_ll(HSPLITTING='B')) THEN
+        !$acc kernels loop independent async
+        DO JJ = IJB,IJE
+           PF_1_Y(IIE+1,JJ,IKB-1) = PF_1_Y(IIE,JJ,IKB-1)
+           PF_1_Y(IIE+1,JJ,IKE+1) = PF_1_Y(IIE,JJ,IKE+1)
+        END DO
+        !$acc end kernels
+     END IF
+     !$acc wait
+     !
+  ELSE
+     !
+     !*      7.2.2 periodize the pressure function field along the x direction
+     !
+     ! in fact this part is useless because it is done in the routine
+     ! REMAP_X_2WAY.
+     !
+  END IF
+!!$!
+  IF (.NOT.L2D) THEN
+     IF (HLBCY(1) /= 'CYCL') THEN
+        !
+        !*      7.2.3 return to a non-homogeneous case in the y direction
+        !
+        ZDYM2 = PDYHATM*PDYHATM 
+        !
+        IF (LSOUTH_ll(HSPLITTING='B')) THEN
+           !$acc kernels loop independent collapse(2) async
+           DO JK=IKB,IKE
+              DO JI = IIB,IIE
+                 PF_1_Y(JI,IJB-1,JK) = PF_1_Y(JI,IJB,JK) - PY(JI,IJB-1,JK)*ZDYM2/PRHOM(JK)
+              END DO
+           END DO
+           !$acc end kernels
+        END IF
+        !
+        IF (LNORTH_ll(HSPLITTING='B')) THEN
+           !$acc kernels loop independent collapse(2) async
+           DO JK=IKB,IKE
+              DO JI = IIB,IIE
+                 PF_1_Y(JI,IJE+1,JK) = PF_1_Y(JI,IJE,JK) + PY(JI,IJE+1,JK)*ZDYM2/PRHOM(JK)
+              END DO
+           END DO
+           !$acc end kernels
+        END IF
+        !$acc wait
+        !    we set the solution at the corner point by the condition:
+        !    dym ( P )  = 0
+        !
+        IF (LSOUTH_ll(HSPLITTING='B')) THEN
+           !$acc kernels loop independent async
+           DO JI = IIB,IIE
+              PF_1_Y(JI,IJB-1,IKB-1) = PF_1_Y(JI,IJB,IKB-1)
+              PF_1_Y(JI,IJB-1,IKE+1) = PF_1_Y(JI,IJB,IKE+1)
+           END DO
+           !$acc end kernels
+        END IF
+        !
+        IF (LNORTH_ll(HSPLITTING='B')) THEN
+           !$acc kernels loop independent async
+           DO JI = IIB,IIE
+              PF_1_Y(JI,IJE+1,IKB-1) = PF_1_Y(JI,IJE,IKB-1)
+              PF_1_Y(JI,IJE+1,IKE+1) = PF_1_Y(JI,IJE,IKE+1)
+           END DO
+           !$acc end kernels
+        END IF
+        !$acc wait
+     ELSE
+        !
+        !*      7.2.4 periodize the pressure function field along the y direction
+        !
+        !
+        ! in fact this part is useless because it is done in the routine
+        ! REMAP_X_2WAY.
+        !
+     END IF
+     !
+  END IF
+  !
+  IF (.NOT. L2D .AND. HLBCX(1)/='CYCL' .AND. HLBCY(1)/='CYCL') THEN
+     ! the following verticals are not used
+     IF ( (LWEST_ll(HSPLITTING='B')).AND.(LSOUTH_ll(HSPLITTING='B')) ) THEN
+        !$acc kernels async
+        PF_1_Y(IIB-1,IJB-1,:)= PF_1_Y(IIB,IJB,:) ! 0.0
+        !$acc end kernels
+     END IF
+     !
+     IF ( (LWEST_ll(HSPLITTING='B')).AND.(LNORTH_ll(HSPLITTING='B')) ) THEN
+        !$acc kernels async
+        PF_1_Y(IIB-1,IJE+1,:)= PF_1_Y(IIB,IJE,:) ! 0.0
+        !$acc end kernels
+     END IF
+     !
+     IF ( (LEAST_ll(HSPLITTING='B')).AND.(LSOUTH_ll(HSPLITTING='B')) ) THEN
+        !$acc kernels async
+        PF_1_Y(IIE+1,IJB-1,:)= PF_1_Y(IIE,IJB,:) ! 0.0
+        !$acc end kernels
+     END IF
+     !
+     IF ( (LEAST_ll(HSPLITTING='B')).AND.(LNORTH_ll(HSPLITTING='B')) ) THEN
+        !$acc kernels async
+        PF_1_Y(IIE+1,IJE+1,:)= PF_1_Y(IIE,IJE,:) ! 0.0
+        !$acc end kernels
+     END IF
+     !$acc wait
+  END IF
+END SUBROUTINE PF_1_Y_BOUND
+  !------------------------------------------------------------------------------  
+END SUBROUTINE ZSOLVER_INV