Index: LMDZ5/branches/testing/libf/dyn3d_common/disvert.F90
===================================================================
--- LMDZ5/branches/testing/libf/dyn3d_common/disvert.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/dyn3d_common/disvert.F90	(revision 2839)
@@ -10,6 +10,6 @@
   use new_unit_m, only: new_unit
   use assert_m, only: assert
-  USE comvert_mod, ONLY: ap, bp, nivsigs, nivsig, dpres, presnivs, &
-                         pa, preff, scaleheight
+  USE comvert_mod, ONLY: ap, bp, aps, bps, nivsigs, nivsig, dpres, presnivs, &
+                         pseudoalt, pa, preff, scaleheight
   USE logic_mod, ONLY: ok_strato
 
@@ -346,7 +346,10 @@
   DO l = 1, llm
      dpres(l) = bp(l) - bp(l+1)
+     aps(l) =  0.5 *( ap(l) +ap(l+1))
+     bps(l) =  0.5 *( bp(l) +bp(l+1))
      presnivs(l) = 0.5 *( ap(l)+bp(l)*preff + ap(l+1)+bp(l+1)*preff )
+     pseudoalt(l) = log(preff/presnivs(l))*scaleheight
      write(lunout, *)'PRESNIVS(', l, ')=', presnivs(l), ' Z ~ ', &
-          log(preff/presnivs(l))*scaleheight &
+          pseudoalt(l) &
           , ' DZ ~ ', scaleheight*log((ap(l)+bp(l)*preff)/ &
           max(ap(l+1)+bp(l+1)*preff, 1.e-10))
Index: LMDZ5/branches/testing/libf/dyn3dmem/dynetat0_loc.f90
===================================================================
--- LMDZ5/branches/testing/libf/dyn3dmem/dynetat0_loc.f90	(revision 2787)
+++ LMDZ5/branches/testing/libf/dyn3dmem/dynetat0_loc.f90	(revision 2839)
@@ -153,4 +153,16 @@
   DO iq=1,nqtot
     var=tname(iq)
+#ifdef INCA
+    IF (var .eq. "O3" ) THEN 
+       IF(NF90_INQ_VARID(fID,var,vID) == NF90_NoErr) THEN
+          CALL get_var2(var,q_glo); q(ijb_u:ije_u,:,iq)=q_glo(ijb_u:ije_u,:); CYCLE
+       ELSE
+          WRITE(lunout,*) 'Tracer O3 is missing - it is initialized to OX'
+          IF(NF90_INQ_VARID(fID,"OX",vID) == NF90_NoErr) THEN
+             CALL get_var2("OX",q_glo); q(ijb_u:ije_u,:,iq)=q_glo(ijb_u:ije_u,:); CYCLE
+          ENDIF
+       ENDIF
+    ENDIF
+#endif
     IF(NF90_INQ_VARID(fID,var,vID)==NF90_NoErr) THEN
       CALL get_var2(var,q_glo); q(ijb_u:ije_u,:,iq)=q_glo(ijb_u:ije_u,:); CYCLE
Index: LMDZ5/branches/testing/libf/dynphy_lonlat/inigeomphy_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/dynphy_lonlat/inigeomphy_mod.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/dynphy_lonlat/inigeomphy_mod.F90	(revision 2839)
@@ -24,4 +24,7 @@
   USE mod_interface_dyn_phys, ONLY :  init_interface_dyn_phys
   USE nrtype, ONLY: pi
+  USE comvert_mod, ONLY: preff, ap, bp, aps, bps, presnivs, &
+                         scaleheight, pseudoalt
+  USE vertical_layers_mod, ONLY: init_vertical_layers
   IMPLICIT NONE
 
@@ -216,4 +219,8 @@
                      airefi,cufi,cvfi)
 
+  ! copy over preff , ap(), bp(), etc 
+  CALL init_vertical_layers(nlayer,preff,scaleheight, &
+                            ap,bp,aps,bps,presnivs,pseudoalt)
+
 !$OMP END PARALLEL
 
Index: LMDZ5/branches/testing/libf/dynphy_lonlat/phylmd/etat0phys_netcdf.F90
===================================================================
--- LMDZ5/branches/testing/libf/dynphy_lonlat/phylmd/etat0phys_netcdf.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/dynphy_lonlat/phylmd/etat0phys_netcdf.F90	(revision 2839)
@@ -82,5 +82,5 @@
   USE fonte_neige_mod
   USE pbl_surface_mod
-  USE regr_lat_time_climoz_m, ONLY: regr_lat_time_climoz
+  USE regr_horiz_time_climoz_m, ONLY: regr_horiz_time_climoz
   USE indice_sol_mod
   USE conf_phys_m, ONLY: conf_phys
@@ -170,6 +170,6 @@
   radsol(:) = 0.0                               !--- Net radiation at ground
   rugmer(:) = 0.001                             !--- Ocean rugosity
-  IF(read_climoz>=1) &                          !--- Ozone climatology
-    CALL regr_lat_time_climoz(read_climoz)
+  !--- Ozone (zonal or 3D) interpolation in space and time (if 2nd arg is TRUE)
+  IF(read_climoz>=1) CALL regr_horiz_time_climoz(read_climoz,ok_daily_climoz)
 
 ! Sub-surfaces initialization.
Index: LMDZ5/branches/testing/libf/dynphy_lonlat/phylmd/iniphysiq_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/dynphy_lonlat/phylmd/iniphysiq_mod.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/dynphy_lonlat/phylmd/iniphysiq_mod.F90	(revision 2839)
@@ -12,5 +12,4 @@
                      prad,pg,pr,pcpp,iflag_phys)
   USE dimphy, ONLY: init_dimphy
-  USE comvert_mod, ONLY: preff, ap, bp, presnivs, scaleheight, pseudoalt
   USE inigeomphy_mod, ONLY: inigeomphy
   USE mod_grid_phy_lmdz, ONLY: nbp_lon,nbp_lat,nbp_lev,klon_glo ! number of atmospheric columns (on full grid)
@@ -110,8 +109,4 @@
 !$OMP COPYIN(annee_ref, day_ini, day_ref, start_time)
 
-  ! copy over preff , ap(), bp(), etc 
-  CALL init_vertical_layers(nlayer,preff,scaleheight, &
-                            ap,bp,presnivs,pseudoalt)
-
   ! Initialize physical constants in physics:
   CALL inifis(punjours,prad,pg,pr,pcpp)
Index: LMDZ5/branches/testing/libf/dynphy_lonlat/phylmd/init_ssrf_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/dynphy_lonlat/phylmd/init_ssrf_m.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/dynphy_lonlat/phylmd/init_ssrf_m.F90	(revision 2839)
@@ -9,4 +9,5 @@
   USE grid_atob_m,        ONLY: grille_m
   USE ioipsl,             ONLY: flininfo, flinopen, flinget, flinclo
+  USE ioipsl_getin_p_mod, ONLY: getin_p
   USE comconst_mod, ONLY: im, pi
 
@@ -42,4 +43,5 @@
   REAL, ALLOCATABLE :: dlat_lic(:), lat_lic(:,:), flic_tmp(:,:), vtmp(:,:)
   REAL              :: date, lev(1), dt, deg2rad
+  LOGICAL           :: no_ter_antartique   ! If true, no land points are allowed at Antartic
 !-------------------------------------------------------------------------------
   deg2rad= pi/180.0
@@ -97,4 +99,24 @@
   END DO 
 
+
+  !--- Option no_ter_antartique removes all land fractions souther than 60S.
+  !--- Land ice is set instead of the land fractions on these latitudes.
+  !--- The ocean and sea-ice fractions are not changed.
+  no_ter_antartique=.FALSE.
+  CALL getin_p('no_ter_antartique',no_ter_antartique)
+  WRITE(lunout,*)"no_ter_antartique=",no_ter_antartique
+  IF (no_ter_antartique) THEN
+     ! Remove all land fractions souther than 60S and set land-ice instead
+     WRITE(lunout,*) "Remove land fractions souther than 60deg south by increasing"
+     WRITE(lunout,*) "the continental ice fractions. No land can now be found at Antartic."
+     DO ji=1, klon
+        IF (latitude_deg(ji)<-60.0) THEN
+           pctsrf(ji,is_lic) = pctsrf(ji,is_lic) + pctsrf(ji,is_ter)
+           pctsrf(ji,is_ter) = 0
+        END IF
+     END DO
+  END IF
+
+
 !--- Sub-surface ocean and sea ice (sea ice set to zero for start).
   pctsrf(:,is_oce)=(1.-zmasq(:))
Index: LMDZ5/branches/testing/libf/dynphy_lonlat/phymar/iniphysiq_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/dynphy_lonlat/phymar/iniphysiq_mod.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/dynphy_lonlat/phymar/iniphysiq_mod.F90	(revision 2839)
@@ -12,5 +12,4 @@
                      prad,pg,pr,pcpp,iflag_phys)
   USE dimphy, ONLY: init_dimphy
-  USE comvert_mod, ONLY: preff, ap, bp, presnivs, scaleheight, pseudoalt
   USE inigeomphy_mod, ONLY: inigeomphy
   USE vertical_layers_mod, ONLY : init_vertical_layers
@@ -71,8 +70,4 @@
 !$OMP PARALLEL
 
-  ! copy over preff , ap(), bp(), etc 
-  CALL init_vertical_layers(nlayer,preff,scaleheight, &
-                            ap,bp,presnivs,pseudoalt)
-
   ! Initialize tracer names, numbers, etc. for physics
   CALL init_infotrac_phy(nqtot)
Index: LMDZ5/branches/testing/libf/misc/regr1_conserv_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/misc/regr1_conserv_m.F90	(revision 2787)
+++ 	(revision )
@@ -1,358 +1,0 @@
-module regr1_conserv_m
-
-  ! Author: Lionel GUEZ
-
-  use assert_eq_m, only: assert_eq
-  use assert_m, only: assert
-  use interpolation, only: locate
-
-  implicit none
-
-  interface regr1_conserv
-
-     ! This generic procedure regrids a piecewise linear function (not
-     ! necessarily continuous) by averaging it. This is a conservative
-     ! regridding. The regridding operation is done on the first
-     ! dimension of the input array. Input are positions of cell
-     ! edges. The target grid should be included in the source grid:
-     ! no extrapolation is allowed.
-
-     ! The only difference between the procedures is the rank of the
-     ! first argument.
-
-     ! real, intent(in), rank >= 1:: vs ! (ns, ...)
-     ! averages of cells of the source grid
-     ! vs(is, ...) for [xs(is), xs(is + 1)]
-
-     ! real, intent(in):: xs(:) ! (ns + 1)
-     ! edges of cells of the source grid, in strictly ascending order
-
-     ! real, intent(in):: xt(:) ! (nt + 1)
-     ! edges of cells of the target grid, in strictly ascending order
-
-     ! real, intent(in), optional, rank >= 1:: slope ! (ns, ...)
-     ! same rank as vs
-     ! slopes inside cells of the source grid
-     ! slope(is, ...) for [xs(is), xs(is + 1)]
-     ! If not present, slopes are taken equal to 0. The regridding is
-     ! then first order.
-
-     ! real, intent(out), rank >= 1:: vt(nt, ...) 
-     ! has the same rank as vs and slope
-     ! averages of cells of the target grid
-     ! vt(it, ...) for  [xt(it), xt(it + 1)]
-
-     ! ns and nt must be >= 1.
-
-     ! See notes for explanations on the algorithm and justification
-     ! of algorithmic choices.
-
-     module procedure regr11_conserv, regr12_conserv, regr13_conserv, &
-          regr14_conserv
-  end interface regr1_conserv
-
-  private
-  public regr1_conserv
-
-contains
-
-  subroutine regr11_conserv(vs, xs, xt, vt, slope)
-
-    ! vs and slope have rank 1.
-
-    real, intent(in):: vs(:)
-    real, intent(in):: xs(:)
-    real, intent(in):: xt(:)
-    real, intent(out):: vt(:)
-    real, intent(in), optional:: slope(:)
-
-    ! Local:
-    integer is, it, ns, nt
-    logical slope_present
-
-    !---------------------------------------------
-
-    ns = assert_eq(size(vs), size(xs) - 1, "regr11_conserv ns")
-    nt = assert_eq(size(xt) - 1, size(vt), "regr11_conserv nt")
-
-    ! Quick check on sort order:
-    call assert(xs(1) < xs(2), "regr11_conserv xs bad order")
-    call assert(xt(1) < xt(2), "regr11_conserv xt bad order")
-
-    call assert(xs(1) <= xt(1) .and. xt(nt + 1) <= xs(ns + 1), &
-         "regr11_conserv extrapolation")
-    slope_present = present(slope)
-
-    is = locate(xs, xt(1)) ! 1 <= is <= ns, because we forbid extrapolation
-    do it = 1, nt
-       ! 1 <= is <= ns
-       ! xs(is) <= xt(it) < xs(is + 1)
-       if (xt(it + 1) <= xs(is + 1)) then
-          vt(it) = mean_lin(xt(it), xt(it + 1))
-       else
-          vt(it) = mean_lin(xt(it), xs(is + 1)) * (xs(is + 1) - xt(it))
-          is = is + 1
-          do while (xs(is + 1) < xt(it + 1))
-             ! 1 <= is <= ns - 1
-             vt(it) = vt(it) + (xs(is + 1) - xs(is)) * vs(is)
-             is = is + 1
-          end do
-          ! 1 <= is <= ns
-          vt(it) = (vt(it) + mean_lin(xs(is), xt(it + 1)) * (xt(it + 1) &
-               - xs(is))) / (xt(it + 1) - xt(it))
-       end if
-
-       if (xs(is + 1) == xt(it + 1)) is = is + 1
-       ! 1 <= is <= ns .or. it == nt
-    end do
-
-  contains
-
-    real function mean_lin(a, b)
-
-      ! mean in [a, b] of the linear function in [xs(is), xs(is + 1)]
-
-      real, intent(in):: a, b
-
-      !---------------------------------------------
-
-      if (slope_present) then
-         mean_lin = slope(is) / 2. * (a + b - xs(is) - xs(is + 1)) + vs(is)
-      else
-         mean_lin = vs(is)
-      end if
-
-    end function mean_lin
-
-  end subroutine regr11_conserv
-
-  !********************************************
-
-  subroutine regr12_conserv(vs, xs, xt, vt, slope)
-
-    ! vs and slope have rank 2.
-
-    real, intent(in):: vs(:, :)
-    real, intent(in):: xs(:)
-    real, intent(in):: xt(:)
-    real, intent(out):: vt(:, :)
-    real, intent(in), optional:: slope(:, :)
-
-    ! Local:
-    integer is, it, ns, nt, n2
-    logical slope_present
-
-    !---------------------------------------------
-
-    ns = assert_eq(size(vs, 1), size(xs) - 1, "regr12_conserv ns")
-    nt = assert_eq(size(xt) - 1, size(vt, 1), "regr12_conserv nt")
-    n2 = assert_eq(size(vs, 2), size(vt, 2), "regr12_conserv n2")
-
-    ! Quick check on sort order:
-    call assert(xs(1) < xs(2), "regr12_conserv xs bad order")
-    call assert(xt(1) < xt(2), "regr12_conserv xt bad order")
-
-    call assert(xs(1) <= xt(1) .and. xt(nt + 1) <= xs(ns + 1), &
-         "regr12_conserv extrapolation")
-    slope_present = present(slope)
-
-    is = locate(xs, xt(1)) ! 1 <= is <= ns, because we forbid extrapolation
-    do it = 1, nt
-       ! 1 <= is <= ns
-       ! xs(is) <= xt(it) < xs(is + 1)
-       if (xt(it + 1) <= xs(is + 1)) then
-          vt(it, :) = mean_lin(xt(it), xt(it + 1))
-       else
-          vt(it, :) = mean_lin(xt(it), xs(is + 1)) * (xs(is + 1) - xt(it))
-          is = is + 1
-          do while (xs(is + 1) < xt(it + 1))
-             ! 1 <= is <= ns - 1
-             vt(it, :) = vt(it, :) + (xs(is + 1) - xs(is)) * vs(is, :)
-             is = is + 1
-          end do
-          ! 1 <= is <= ns
-          vt(it, :) = (vt(it, :) + mean_lin(xs(is), xt(it + 1)) * (xt(it + 1) &
-               - xs(is))) / (xt(it + 1) - xt(it))
-       end if
-
-       if (xs(is + 1) == xt(it + 1)) is = is + 1
-       ! 1 <= is <= ns .or. it == nt
-    end do
-
-  contains
-
-    function mean_lin(a, b)
-
-      ! mean in [a, b] of the linear function in [xs(is), xs(is + 1)]
-
-      real, intent(in):: a, b
-      real mean_lin(n2)
-
-      !---------------------------------------------
-
-      if (slope_present) then
-         mean_lin = slope(is, :) / 2. * (a + b - xs(is) - xs(is + 1)) &
-              + vs(is, :)
-      else
-         mean_lin = vs(is, :)
-      end if
-
-    end function mean_lin
-
-  end subroutine regr12_conserv
-
-  !********************************************
-
-  subroutine regr13_conserv(vs, xs, xt, vt, slope)
-
-    ! vs and slope have rank 3.
-
-    real, intent(in):: vs(:, :, :)
-    real, intent(in):: xs(:)
-    real, intent(in):: xt(:)
-    real, intent(out):: vt(:, :, :)
-    real, intent(in), optional:: slope(:, :, :)
-
-    ! Local:
-    integer is, it, ns, nt, n2, n3
-    logical slope_present
-
-    !---------------------------------------------
-
-    ns = assert_eq(size(vs, 1), size(xs) - 1, "regr13_conserv ns")
-    nt = assert_eq(size(xt) - 1, size(vt, 1), "regr13_conserv nt")
-    n2 = assert_eq(size(vs, 2), size(vt, 2), "regr13_conserv n2")
-    n3 = assert_eq(size(vs, 3), size(vt, 3), "regr13_conserv n3")
-
-    ! Quick check on sort order:
-    call assert(xs(1) < xs(2), "regr13_conserv xs bad order")
-    call assert(xt(1) < xt(2), "regr13_conserv xt bad order")
-
-    call assert(xs(1) <= xt(1) .and. xt(nt + 1) <= xs(ns + 1), &
-         "regr13_conserv extrapolation")
-    slope_present = present(slope)
-
-    is = locate(xs, xt(1)) ! 1 <= is <= ns, because we forbid extrapolation
-    do it = 1, nt
-       ! 1 <= is <= ns
-       ! xs(is) <= xt(it) < xs(is + 1)
-       if (xt(it + 1) <= xs(is + 1)) then
-          vt(it, :, :) = mean_lin(xt(it), xt(it + 1))
-       else
-          vt(it, :, :) = mean_lin(xt(it), xs(is + 1)) * (xs(is + 1) - xt(it))
-          is = is + 1
-          do while (xs(is + 1) < xt(it + 1))
-             ! 1 <= is <= ns - 1
-             vt(it, :, :) = vt(it, :, :) + (xs(is + 1) - xs(is)) * vs(is, :, :)
-             is = is + 1
-          end do
-          ! 1 <= is <= ns
-          vt(it, :, :) = (vt(it, :, :) + mean_lin(xs(is), xt(it + 1)) &
-               * (xt(it + 1) - xs(is))) / (xt(it + 1) - xt(it))
-       end if
-
-       if (xs(is + 1) == xt(it + 1)) is = is + 1
-       ! 1 <= is <= ns .or. it == nt
-    end do
-
-  contains
-
-    function mean_lin(a, b)
-
-      ! mean in [a, b] of the linear function in [xs(is), xs(is + 1)]
-
-      real, intent(in):: a, b
-      real mean_lin(n2, n3)
-
-      !---------------------------------------------
-
-      if (slope_present) then
-         mean_lin = slope(is, :, :) / 2. * (a + b - xs(is) - xs(is + 1)) &
-              + vs(is, :, :)
-      else
-         mean_lin = vs(is, :, :)
-      end if
-
-    end function mean_lin
-
-  end subroutine regr13_conserv
-
-  !********************************************
-
-  subroutine regr14_conserv(vs, xs, xt, vt, slope)
-
-    ! vs and slope have rank 4.
-
-    real, intent(in):: vs(:, :, :, :)
-    real, intent(in):: xs(:)
-    real, intent(in):: xt(:)
-    real, intent(out):: vt(:, :, :, :)
-    real, intent(in), optional:: slope(:, :, :, :)
-
-    ! Local:
-    integer is, it, ns, nt, n2, n3, n4
-    logical slope_present
-
-    !---------------------------------------------
-
-    ns = assert_eq(size(vs, 1), size(xs) - 1, "regr14_conserv ns")
-    nt = assert_eq(size(xt) - 1, size(vt, 1), "regr14_conserv nt")
-    n2 = assert_eq(size(vs, 2), size(vt, 2), "regr14_conserv n2")
-    n3 = assert_eq(size(vs, 3), size(vt, 3), "regr14_conserv n3")
-    n4 = assert_eq(size(vs, 4), size(vt, 4), "regr14_conserv n4")
-
-    ! Quick check on sort order:
-    call assert(xs(1) < xs(2), "regr14_conserv xs bad order")
-    call assert(xt(1) < xt(2), "regr14_conserv xt bad order")
-
-    call assert(xs(1) <= xt(1) .and. xt(nt + 1) <= xs(ns + 1), &
-         "regr14_conserv extrapolation")
-    slope_present = present(slope)
-
-    is = locate(xs, xt(1)) ! 1 <= is <= ns, because we forbid extrapolation
-    do it = 1, nt
-       ! 1 <= is <= ns
-       ! xs(is) <= xt(it) < xs(is + 1)
-       if (xt(it + 1) <= xs(is + 1)) then
-          vt(it, :, :, :) = mean_lin(xt(it), xt(it + 1))
-       else
-          vt(it, :, :, :) = mean_lin(xt(it), xs(is + 1)) * (xs(is + 1) - xt(it))
-          is = is + 1
-          do while (xs(is + 1) < xt(it + 1))
-             ! 1 <= is <= ns - 1
-             vt(it, :, :, :) = vt(it, :, :, :) + (xs(is + 1) - xs(is)) &
-                  * vs(is, :, :, :)
-             is = is + 1
-          end do
-          ! 1 <= is <= ns
-          vt(it, :, :, :) = (vt(it, :, :, :) + mean_lin(xs(is), xt(it + 1)) &
-               * (xt(it + 1) - xs(is))) / (xt(it + 1) - xt(it))
-       end if
-
-       if (xs(is + 1) == xt(it + 1)) is = is + 1
-       ! 1 <= is <= ns .or. it == nt
-    end do
-
-  contains
-
-    function mean_lin(a, b)
-
-      ! mean in [a, b] of the linear function in [xs(is), xs(is + 1)]
-
-      real, intent(in):: a, b
-      real mean_lin(n2, n3, n4)
-
-      !---------------------------------------------
-
-      if (slope_present) then
-         mean_lin = slope(is, :, :, :) / 2. * (a + b - xs(is) - xs(is + 1)) &
-              + vs(is, :, :, :)
-      else
-         mean_lin = vs(is, :, :, :)
-      end if
-
-    end function mean_lin
-
-  end subroutine regr14_conserv
-
-end module regr1_conserv_m
Index: LMDZ5/branches/testing/libf/misc/regr1_lint_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/misc/regr1_lint_m.F90	(revision 2787)
+++ 	(revision )
@@ -1,98 +1,0 @@
-! $Id$
-module regr1_lint_m
-
-  ! Author: Lionel GUEZ
-
-  implicit none
-
-  interface regr1_lint
-     ! Each procedure regrids by linear interpolation.
-     ! The regridding operation is done on the first dimension of the
-     ! input array.
-     ! The difference betwwen the procedures is the rank of the first argument.
-     module procedure regr11_lint, regr12_lint
-  end interface
-
-  private
-  public regr1_lint
-
-contains
-
-  function regr11_lint(vs, xs, xt) result(vt)
-
-    ! "vs" has rank 1.
-
-    use assert_eq_m, only: assert_eq
-    use interpolation, only: hunt !!, polint
-
-    real, intent(in):: vs(:)
-    ! (values of the function at source points "xs")
-
-    real, intent(in):: xs(:)
-    ! (abscissas of points in source grid, in strictly monotonic order)
-
-    real, intent(in):: xt(:)
-    ! (abscissas of points in target grid)
-
-    real vt(size(xt)) ! values of the function on the target grid
-
-    ! Variables local to the procedure:
-    integer is, it, ns
-    integer is_b ! "is" bound between 1 and "ns - 1"
-
-    !--------------------------------------
-
-    ns = assert_eq(size(vs), size(xs), "regr11_lint ns")
-
-    is = -1 ! go immediately to bisection on first call to "hunt"
-
-    do it = 1, size(xt)
-       call hunt(xs, xt(it), is)
-       is_b = min(max(is, 1), ns - 1)
-!!       call polint(xs(is_b:is_b+1), vs(is_b:is_b+1), xt(it), vt(it))
-       vt(it) = ((xs(is_b+1) - xt(it)) * vs(is_b) &
-            + (xt(it) - xs(is_b)) * vs(is_b+1)) / (xs(is_b+1) - xs(is_b))
-    end do
-
-  end function regr11_lint
-
-  !*********************************************************
-
-  function regr12_lint(vs, xs, xt) result(vt)
-
-    ! "vs" has rank 2.
-
-    use assert_eq_m, only: assert_eq
-    use interpolation, only: hunt
-
-    real, intent(in):: vs(:, :)
-    ! (values of the function at source points "xs")
-
-    real, intent(in):: xs(:)
-    ! (abscissas of points in source grid, in strictly monotonic order)
-
-    real, intent(in):: xt(:)
-    ! (abscissas of points in target grid)
-
-    real vt(size(xt), size(vs, 2)) ! values of the function on the target grid
-
-    ! Variables local to the procedure:
-    integer is, it, ns
-    integer is_b ! "is" bound between 1 and "ns - 1"
-
-    !--------------------------------------
-
-    ns = assert_eq(size(vs, 1), size(xs), "regr12_lint ns")
-
-    is = -1 ! go immediately to bisection on first call to "hunt"
-
-    do it = 1, size(xt)
-       call hunt(xs, xt(it), is)
-       is_b = min(max(is, 1), ns - 1)
-       vt(it, :) = ((xs(is_b+1) - xt(it)) * vs(is_b, :) &
-            + (xt(it) - xs(is_b)) * vs(is_b+1, :)) / (xs(is_b+1) - xs(is_b))
-    end do
-
-  end function regr12_lint
-
-end module regr1_lint_m
Index: LMDZ5/branches/testing/libf/misc/regr3_lint_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/misc/regr3_lint_m.F90	(revision 2787)
+++ 	(revision )
@@ -1,100 +1,0 @@
-! $Id$
-module regr3_lint_m
-
-  ! Author: Lionel GUEZ
-
-  implicit none
-
-  interface regr3_lint
-     ! Each procedure regrids by linear interpolation.
-     ! The regridding operation is done on the third dimension of the
-     ! input array.
-     ! The difference betwwen the procedures is the rank of the first argument.
-     module procedure regr33_lint, regr34_lint
-  end interface
-
-  private
-  public regr3_lint
-
-contains
-
-  function regr33_lint(vs, xs, xt) result(vt)
-
-    ! "vs" has rank 3.
-
-    use assert_eq_m, only: assert_eq
-    use interpolation, only: hunt
-
-    real, intent(in):: vs(:, :, :)
-    ! (values of the function at source points "xs")
-
-    real, intent(in):: xs(:)
-    ! (abscissas of points in source grid, in strictly monotonic order)
-
-    real, intent(in):: xt(:)
-    ! (abscissas of points in target grid)
-
-    real vt(size(vs, 1), size(vs, 2), size(xt))
-    ! (values of the function on the target grid)
-
-    ! Variables local to the procedure:
-    integer is, it, ns
-    integer is_b ! "is" bound between 1 and "ns - 1"
-
-    !--------------------------------------
-
-    ns = assert_eq(size(vs, 3), size(xs), "regr33_lint ns")
-
-    is = -1 ! go immediately to bisection on first call to "hunt"
-
-    do it = 1, size(xt)
-       call hunt(xs, xt(it), is)
-       is_b = min(max(is, 1), ns - 1)
-       vt(:, :, it) = ((xs(is_b+1) - xt(it)) * vs(:, :, is_b) &
-            + (xt(it) - xs(is_b)) * vs(:, :, is_b+1)) / (xs(is_b+1) - xs(is_b))
-    end do
-
-  end function regr33_lint
-
-  !*********************************************************
-
-  function regr34_lint(vs, xs, xt) result(vt)
-
-    ! "vs" has rank 4.
-
-    use assert_eq_m, only: assert_eq
-    use interpolation, only: hunt
-
-    real, intent(in):: vs(:, :, :, :)
-    ! (values of the function at source points "xs")
-
-    real, intent(in):: xs(:)
-    ! (abscissas of points in source grid, in strictly monotonic order)
-
-    real, intent(in):: xt(:)
-    ! (abscissas of points in target grid)
-
-    real vt(size(vs, 1), size(vs, 2), size(xt), size(vs, 4))
-    ! (values of the function on the target grid)
-
-    ! Variables local to the procedure:
-    integer is, it, ns
-    integer is_b ! "is" bound between 1 and "ns - 1"
-
-    !--------------------------------------
-
-    ns = assert_eq(size(vs, 3), size(xs), "regr34_lint ns")
-
-    is = -1 ! go immediately to bisection on first call to "hunt"
-
-    do it = 1, size(xt)
-       call hunt(xs, xt(it), is)
-       is_b = min(max(is, 1), ns - 1)
-       vt(:, :, it, :) = ((xs(is_b+1) - xt(it)) * vs(:, :, is_b, :) &
-            + (xt(it) - xs(is_b)) * vs(:, :, is_b+1, :)) &
-            / (xs(is_b+1) - xs(is_b))
-    end do
-
-  end function regr34_lint
-
-end module regr3_lint_m
Index: LMDZ5/branches/testing/libf/misc/regr_conserv_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/misc/regr_conserv_m.F90	(revision 2839)
+++ LMDZ5/branches/testing/libf/misc/regr_conserv_m.F90	(revision 2839)
@@ -0,0 +1,388 @@
+MODULE regr_conserv_m
+
+  USE assert_eq_m,   ONLY: assert_eq
+  USE assert_m,      ONLY: assert
+  USE interpolation, ONLY: locate
+
+  IMPLICIT NONE
+
+! Purpose: Each procedure regrids a piecewise linear function (not necessarily
+!          continuous) by averaging it. This is a conservative regridding.
+!          The regridding operation is done along dimension "ix" of the input
+!          field "vs". Input are positions of cell edges.
+! Remarks:
+!   * The target grid should be included in the source grid:
+!     no extrapolation is allowed.
+!   * Field on target grid "vt" has same rank, slopes and averages as "vs".
+!   * If optional argument "slope" is not given, 0 is assumed for slopes.
+!     Then the regridding is first order instead of second.
+!   * "vs" and "vt" have the same dimensions except Nr. ix (ns for vs, nt for vt)
+
+! Argument                         Type         Description
+!-------------------------------------------------------------------------------
+!  INTEGER, INTENT(IN)  :: ix      Scalar       dimension regridded <=rank(vs)
+!  REAL,    INTENT(IN)  :: vs(*)   Rank>=1      averages in source grid cells
+!  REAL,    INTENT(IN)  :: xs(:)   Vector(ns+1) edges of source grid, asc. order
+!  REAL,    INTENT(IN)  :: xt(:)   Vector(nt+1) edges of target grid, asc. order
+!  REAL,    INTENT(OUT) :: vt(*)   Rank>=1      regridded field
+! [REAL,    INTENT(IN)  :: slope]  Rank>=1      slopes in source grid cells
+
+  INTERFACE regr_conserv
+    ! The procedures differ only from the rank of the input/output fields.
+    MODULE PROCEDURE regr1_conserv, regr2_conserv, regr3_conserv, &
+                     regr4_conserv, regr5_conserv
+  END INTERFACE
+
+  PRIVATE
+  PUBLIC :: regr_conserv
+
+CONTAINS
+
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE regr1_conserv(ix, vs, xs, xt, vt, slope)
+!
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER,        INTENT(IN)  :: ix
+  REAL,           INTENT(IN)  :: vs(:)
+  REAL,           INTENT(IN)  :: xs(:), xt(:)
+  REAL,           INTENT(OUT) :: vt(:)
+  REAL, OPTIONAL, INTENT(IN)  :: slope(:)
+!-------------------------------------------------------------------------------
+! Local variables:
+  INTEGER :: is, it, ns, nt
+  REAL    :: co, idt
+  LOGICAL :: lslope
+!-------------------------------------------------------------------------------
+  lslope=PRESENT(slope)
+  CALL check_size(ix,SHAPE(vs),SHAPE(vt),xs,xt,ns,nt)
+  is=locate(xs,xt(1))                    !--- 1<= is <= ns (no extrapolation)
+  vt(:)=0.
+  DO it=1, nt; idt=1./(xt(it+1)-xt(it))
+    IF(xt(it+1)<=xs(is+1)) THEN          !--- xs(is)<=xt(it)<=xt(it+1)<=xs(is+1)
+      CALL mean_lin(xt(it),xt(it+1))
+    ELSE
+      CALL mean_lin(xt(it),xs(is+1)); is=is+1
+      DO WHILE(xs(is+1)<xt(it+1))        !--- 1<=is<=ns-1
+      CALL mean_lin(xs(is),xs(is+1)); is=is+1
+      END DO
+      CALL mean_lin(xs(is),xt(it+1))     !--- 1<=is<=ns
+    END IF
+    IF(xs(is+1)==xt(it+1)) is=is+1       !--- 1<=is<=ns .OR. it==nt
+  END DO
+
+CONTAINS
+
+!-------------------------------------------------------------------------------
+SUBROUTINE mean_lin(a,b)  ! mean [a,b] of the linear function in [xs(is),xs(is+1)]
+!-------------------------------------------------------------------------------
+! Arguments:
+  REAL, INTENT(IN)    :: a, b
+!-------------------------------------------------------------------------------
+  IF(lslope.AND.(a/=xs(is).OR.b/=xs(is+1))) THEN; co=0.
+    IF(a==xt(it  )) co=co+xt(it  )-xs(is  )
+    IF(b==xt(it+1)) co=co+xt(it+1)-xs(is+1)
+    vt(it) = vt(it)+idt*(b-a)*(vs(is)+co*slope(is))
+  ELSE
+    vt(it) = vt(it)+idt*(b-a)* vs(is)
+  END IF
+
+END SUBROUTINE mean_lin
+!-------------------------------------------------------------------------------
+
+END SUBROUTINE regr1_conserv
+!
+!-------------------------------------------------------------------------------
+
+
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE regr2_conserv(ix, vs, xs, xt, vt, slope)
+!
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER,        INTENT(IN)  :: ix
+  REAL,           INTENT(IN)  :: vs(:,:)
+  REAL,           INTENT(IN)  :: xs(:), xt(:)
+  REAL,           INTENT(OUT) :: vt(:,:)
+  REAL, OPTIONAL, INTENT(IN)  :: slope(:,:)
+!-------------------------------------------------------------------------------
+! Local variables:
+  INTEGER :: is, it, ns, nt
+  REAL    :: co, idt
+  LOGICAL :: lslope
+!-------------------------------------------------------------------------------
+  lslope=PRESENT(slope)
+  CALL check_size(ix,SHAPE(vs),SHAPE(vt),xs,xt,ns,nt)
+  is=locate(xs,xt(1)) ! 1 <= is <= ns, because we forbid extrapolation
+  vt(:,:)=0.
+  DO it=1, nt; idt=1./(xt(it+1)-xt(it))
+    IF(xt(it+1)<=xs(is+1)) THEN          !--- xs(is)<=xt(it)<=xt(it+1)<=xs(is+1)
+      CALL mean_lin(xt(it),xt(it+1))
+    ELSE
+      CALL mean_lin(xt(it),xs(is+1)); is=is+1
+      DO WHILE(xs(is+1)<xt(it+1))        !--- 1<=is<=ns-1
+      CALL mean_lin(xs(is),xs(is+1)); is=is+1
+      END DO
+      CALL mean_lin(xs(is),xt(it+1))     !--- 1<=is<=ns
+    END IF
+    IF(xs(is+1)==xt(it+1)) is=is+1       !--- 1<=is<=ns .OR. it==nt
+  END DO
+
+CONTAINS
+
+!-------------------------------------------------------------------------------
+SUBROUTINE mean_lin(a,b)  ! mean [a,b] of the linear function in [xs(is),xs(is+1)]
+!-------------------------------------------------------------------------------
+! Arguments:
+  REAL, INTENT(IN)    :: a, b
+!-------------------------------------------------------------------------------
+  IF(lslope.AND.(a/=xs(is).OR.b/=xs(is+1))) THEN; co=0.
+    IF(a==xt(it  )) co=co+xt(it  )-xs(is  )
+    IF(b==xt(it+1)) co=co+xt(it+1)-xs(is+1)
+    IF(ix==1) vt(it,:) = vt(it,:)+idt*(b-a)*(vs(is,:)+co*slope(is,:))
+    IF(ix==2) vt(:,it) = vt(:,it)+idt*(b-a)*(vs(:,is)+co*slope(:,is))
+  ELSE
+    IF(ix==1) vt(it,:) = vt(it,:)+idt*(b-a)* vs(is,:)
+    IF(ix==2) vt(:,it) = vt(:,it)+idt*(b-a)* vs(:,is)
+  END IF
+
+END SUBROUTINE mean_lin
+!-------------------------------------------------------------------------------
+
+END SUBROUTINE regr2_conserv
+!
+!-------------------------------------------------------------------------------
+
+
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE regr3_conserv(ix, vs, xs, xt, vt, slope)
+!
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER,        INTENT(IN)  :: ix
+  REAL,           INTENT(IN)  :: vs(:,:,:)
+  REAL,           INTENT(IN)  :: xs(:), xt(:)
+  REAL,           INTENT(OUT) :: vt(:,:,:)
+  REAL, OPTIONAL, INTENT(IN)  :: slope(:,:,:)
+!-------------------------------------------------------------------------------
+! Local variables:
+  INTEGER :: is, it, ns, nt
+  REAL    :: co, idt
+  LOGICAL :: lslope
+!-------------------------------------------------------------------------------
+  lslope=PRESENT(slope)
+  CALL check_size(ix,SHAPE(vs),SHAPE(vt),xs,xt,ns,nt)
+  is=locate(xs,xt(1)) ! 1 <= is <= ns, because we forbid extrapolation
+  vt(:,:,:)=0.
+  DO it=1, nt; idt=1./(xt(it+1)-xt(it))
+    IF(xt(it+1)<=xs(is+1)) THEN          !--- xs(is)<=xt(it)<=xt(it+1)<=xs(is+1)
+      CALL mean_lin(xt(it),xt(it+1))
+    ELSE
+      CALL mean_lin(xt(it),xs(is+1)); is=is+1
+      DO WHILE(xs(is+1)<xt(it+1))        !--- 1<=is<=ns-1
+      CALL mean_lin(xs(is),xs(is+1)); is=is+1
+      END DO
+      CALL mean_lin(xs(is),xt(it+1))     !--- 1<=is<=ns
+    END IF
+    IF(xs(is+1)==xt(it+1)) is=is+1       !--- 1<=is<=ns .OR. it==nt
+  END DO
+
+CONTAINS
+
+!-------------------------------------------------------------------------------
+SUBROUTINE mean_lin(a,b)  ! mean [a,b] of the linear function in [xs(is),xs(is+1)]
+!-------------------------------------------------------------------------------
+! Arguments:
+  REAL, INTENT(IN)    :: a, b
+!-------------------------------------------------------------------------------
+  IF(lslope.AND.(a/=xs(is).OR.b/=xs(is+1))) THEN; co=0.
+    IF(a==xt(it  )) co=co+xt(it  )-xs(is  )
+    IF(b==xt(it+1)) co=co+xt(it+1)-xs(is+1)
+    IF(ix==1) vt(it,:,:) = vt(it,:,:)+idt*(b-a)*(vs(is,:,:)+co*slope(is,:,:))
+    IF(ix==2) vt(:,it,:) = vt(:,it,:)+idt*(b-a)*(vs(:,is,:)+co*slope(:,is,:))
+    IF(ix==3) vt(:,:,it) = vt(:,:,it)+idt*(b-a)*(vs(:,:,is)+co*slope(:,:,is))
+  ELSE
+    IF(ix==1) vt(it,:,:) = vt(it,:,:)+idt*(b-a)* vs(is,:,:)
+    IF(ix==2) vt(:,it,:) = vt(:,it,:)+idt*(b-a)* vs(:,is,:)
+    IF(ix==3) vt(:,:,it) = vt(:,:,it)+idt*(b-a)* vs(:,:,is)
+  END IF
+
+END SUBROUTINE mean_lin
+!-------------------------------------------------------------------------------
+
+END SUBROUTINE regr3_conserv
+!
+!-------------------------------------------------------------------------------
+
+
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE regr4_conserv(ix, vs, xs, xt, vt, slope)
+!
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER,        INTENT(IN)  :: ix
+  REAL,           INTENT(IN)  :: vs(:,:,:,:)
+  REAL,           INTENT(IN)  :: xs(:), xt(:)
+  REAL,           INTENT(OUT) :: vt(:,:,:,:)
+  REAL, OPTIONAL, INTENT(IN)  :: slope(:,:,:,:)
+!-------------------------------------------------------------------------------
+! Local variables:
+  INTEGER :: is, it, ns, nt
+  REAL    :: co, idt
+  LOGICAL :: lslope
+!-------------------------------------------------------------------------------
+  lslope=PRESENT(slope)
+  CALL check_size(ix,SHAPE(vs),SHAPE(vt),xs,xt,ns,nt)
+  is=locate(xs,xt(1)) ! 1 <= is <= ns, because we forbid extrapolation
+  vt(:,:,:,:)=0.
+  DO it=1, nt; idt=1./(xt(it+1)-xt(it))
+    IF(xt(it+1)<=xs(is+1)) THEN          !--- xs(is)<=xt(it)<=xt(it+1)<=xs(is+1)
+      CALL mean_lin(xt(it),xt(it+1))
+    ELSE
+      CALL mean_lin(xt(it),xs(is+1)); is=is+1
+      DO WHILE(xs(is+1)<xt(it+1))        !--- 1<=is<=ns-1
+      CALL mean_lin(xs(is),xs(is+1)); is=is+1
+      END DO
+      CALL mean_lin(xs(is),xt(it+1))     !--- 1<=is<=ns
+    END IF
+    IF(xs(is+1)==xt(it+1)) is=is+1       !--- 1<=is<=ns .OR. it==nt
+  END DO
+
+CONTAINS
+
+!-------------------------------------------------------------------------------
+SUBROUTINE mean_lin(a,b)  ! mean [a,b] of the linear function in [xs(is),xs(is+1)]
+!-------------------------------------------------------------------------------
+! Arguments:
+  REAL, INTENT(IN) :: a, b
+!-------------------------------------------------------------------------------
+  IF(lslope.AND.(a/=xs(is).OR.b/=xs(is+1))) THEN; co=0.
+    IF(a==xt(it  )) co=co+xt(it  )-xs(is  )
+    IF(b==xt(it+1)) co=co+xt(it+1)-xs(is+1)
+    IF(ix==1) vt(it,:,:,:) = vt(it,:,:,:)+idt*(b-a)*(vs(is,:,:,:)+co*slope(is,:,:,:))
+    IF(ix==2) vt(:,it,:,:) = vt(:,it,:,:)+idt*(b-a)*(vs(:,is,:,:)+co*slope(:,is,:,:))
+    IF(ix==3) vt(:,:,it,:) = vt(:,:,it,:)+idt*(b-a)*(vs(:,:,is,:)+co*slope(:,:,is,:))
+    IF(ix==4) vt(:,:,:,it) = vt(:,:,:,it)+idt*(b-a)*(vs(:,:,:,is)+co*slope(:,:,:,is))
+  ELSE
+    IF(ix==1) vt(it,:,:,:) = vt(it,:,:,:)+idt*(b-a)* vs(is,:,:,:)
+    IF(ix==2) vt(:,it,:,:) = vt(:,it,:,:)+idt*(b-a)* vs(:,is,:,:)
+    IF(ix==3) vt(:,:,it,:) = vt(:,:,it,:)+idt*(b-a)* vs(:,:,is,:)
+    IF(ix==4) vt(:,:,:,it) = vt(:,:,:,it)+idt*(b-a)* vs(:,:,:,is)
+  END IF
+
+END SUBROUTINE mean_lin
+!-------------------------------------------------------------------------------
+
+END SUBROUTINE regr4_conserv
+!
+!-------------------------------------------------------------------------------
+
+
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE regr5_conserv(ix, vs, xs, xt, vt, slope)
+!
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER,        INTENT(IN)  :: ix
+  REAL,           INTENT(IN)  :: vs(:,:,:,:,:)
+  REAL,           INTENT(IN)  :: xs(:), xt(:)
+  REAL,           INTENT(OUT) :: vt(:,:,:,:,:)
+  REAL, OPTIONAL, INTENT(IN)  :: slope(:,:,:,:,:)
+!-------------------------------------------------------------------------------
+! Local variables:
+  INTEGER :: is, it, ns, nt
+  REAL    :: co, idt
+  LOGICAL :: lslope
+!-------------------------------------------------------------------------------
+  lslope=PRESENT(slope)
+  CALL check_size(ix,SHAPE(vs),SHAPE(vt),xs,xt,ns,nt)
+  is=locate(xs,xt(1)) ! 1 <= is <= ns, because we forbid extrapolation
+  vt(:,:,:,:,:)=0.
+  DO it=1, nt; idt=1./(xt(it+1)-xt(it))
+    IF(xt(it+1)<=xs(is+1)) THEN          !--- xs(is)<=xt(it)<=xt(it+1)<=xs(is+1)
+      CALL mean_lin(xt(it),xt(it+1))
+    ELSE
+      CALL mean_lin(xt(it),xs(is+1)); is=is+1
+      DO WHILE(xs(is+1)<xt(it+1))        !--- 1<=is<=ns-1
+      CALL mean_lin(xs(is),xs(is+1)); is=is+1
+      END DO
+      CALL mean_lin(xs(is),xt(it+1))     !--- 1<=is<=ns
+    END IF
+    IF(xs(is+1)==xt(it+1)) is=is+1     !--- 1<=is<=ns .OR. it==nt
+  END DO
+
+CONTAINS
+
+!-------------------------------------------------------------------------------
+SUBROUTINE mean_lin(a,b)  ! mean [a,b] of the linear function in [xs(is),xs(is+1)]
+!-------------------------------------------------------------------------------
+! Arguments:
+  REAL, INTENT(IN) :: a, b
+!-------------------------------------------------------------------------------
+  IF(lslope.AND.(a/=xs(is).OR.b/=xs(is+1))) THEN; co=0.
+    IF(a==xt(it  )) co=co+xt(it  )-xs(is  )
+    IF(b==xt(it+1)) co=co+xt(it+1)-xs(is+1)
+    IF(ix==1) vt(it,:,:,:,:) = vt(it,:,:,:,:)+idt*(b-a)*(vs(is,:,:,:,:)+co*slope(is,:,:,:,:))
+    IF(ix==2) vt(:,it,:,:,:) = vt(:,it,:,:,:)+idt*(b-a)*(vs(:,is,:,:,:)+co*slope(:,is,:,:,:))
+    IF(ix==3) vt(:,:,it,:,:) = vt(:,:,it,:,:)+idt*(b-a)*(vs(:,:,is,:,:)+co*slope(:,:,is,:,:))
+    IF(ix==4) vt(:,:,:,it,:) = vt(:,:,:,it,:)+idt*(b-a)*(vs(:,:,:,is,:)+co*slope(:,:,:,is,:))
+    IF(ix==5) vt(:,:,:,:,it) = vt(:,:,:,:,it)+idt*(b-a)*(vs(:,:,:,:,is)+co*slope(:,:,:,:,is))
+  ELSE
+    IF(ix==1) vt(it,:,:,:,:) = vt(it,:,:,:,:)+idt*(b-a)* vs(is,:,:,:,:)
+    IF(ix==2) vt(:,it,:,:,:) = vt(:,it,:,:,:)+idt*(b-a)* vs(:,is,:,:,:)
+    IF(ix==3) vt(:,:,it,:,:) = vt(:,:,it,:,:)+idt*(b-a)* vs(:,:,is,:,:)
+    IF(ix==4) vt(:,:,:,it,:) = vt(:,:,:,it,:)+idt*(b-a)* vs(:,:,:,is,:)
+    IF(ix==5) vt(:,:,:,:,it) = vt(:,:,:,:,it)+idt*(b-a)* vs(:,:,:,:,is)
+  END IF
+
+END SUBROUTINE mean_lin
+!-------------------------------------------------------------------------------
+
+END SUBROUTINE regr5_conserv
+!
+!-------------------------------------------------------------------------------
+
+
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE check_size(ix,svs,svt,xs,xt,ns,nt)
+!
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER, INTENT(IN)  :: ix, svs(:), svt(:)
+  REAL,    INTENT(IN)  :: xs(:), xt(:)
+  INTEGER, INTENT(OUT) :: ns,    nt
+!-------------------------------------------------------------------------------
+! Local variables:
+  INTEGER :: rk, is, ii, n
+  CHARACTER(LEN=80) :: sub, msg
+!-------------------------------------------------------------------------------
+  WRITE(sub,'(a,2i0,a)')"regr",SIZE(svs),ix,"_conserv"
+  rk=assert_eq(SIZE(svs),SIZE(svt),TRIM(sub)//': inconsistent ranks')
+  WRITE(msg,'(a,2(i0,a))')TRIM(sub)//": ix (",ix,") exceeds field rank (",rk,")"
+  CALL assert(ix>=1.AND.ix<=rk,msg)
+  ii=0
+  DO is=1,rk; IF(is==ix) CYCLE
+    WRITE(msg,'(a,i0)')TRIM(sub)//" n",is
+    n=assert_eq(svs(is),svt(is),msg)
+    ii=ii+1
+  END DO
+  ns=assert_eq(svs(ix),SIZE(xs)-1,TRIM(sub)//" ns")
+  nt=assert_eq(svt(ix),SIZE(xt)-1,TRIM(sub)//" nt")
+
+  !--- Quick check on sort order:
+  CALL assert(xs(1)<xs(2), TRIM(sub)//": xs bad order")
+  CALL assert(xt(1)<xt(2), TRIM(sub)//": xt bad order")
+  CALL assert(xs(1)<=xt(1).AND.xt(nt+1)<=xs(ns+1), TRIM(sub)//": extrapolation")
+
+END SUBROUTINE check_size
+!
+!-------------------------------------------------------------------------------
+
+
+END MODULE regr_conserv_m
Index: LMDZ5/branches/testing/libf/misc/regr_lint_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/misc/regr_lint_m.F90	(revision 2839)
+++ LMDZ5/branches/testing/libf/misc/regr_lint_m.F90	(revision 2839)
@@ -0,0 +1,219 @@
+MODULE regr_lint_m
+
+  USE assert_eq_m,   ONLY: assert_eq
+  USE assert_m,      ONLY: assert
+  USE interpolation, ONLY: hunt
+
+  IMPLICIT NONE
+
+! Purpose: Each procedure regrids by linear interpolation along dimension "ix"
+!          the input field "vs" to the output field "vt".
+! Remark:
+!   * "vs" and "vt" have the same dimensions except Nr. ix (ns for vs, nt for vt)
+
+! Argument                         Type         Description
+!-------------------------------------------------------------------------------
+!  INTEGER, INTENT(IN)  :: ix      Scalar       dimension regridded <=rank(vs)
+!  REAL,    INTENT(IN)  :: vs(*)   Rank>=1      source grid field values
+!  REAL,    INTENT(IN)  :: xs(:)   Vector(ns)   centers of source grid, asc. order
+!  REAL,    INTENT(IN)  :: xt(:)   Vector(nt)   centers of target grid, asc. order
+!  REAL,    INTENT(OUT) :: vt(*)   Rank>=1      regridded field
+
+  INTERFACE regr_lint
+    ! The procedures differ only from the rank of the input/output fields.
+    MODULE PROCEDURE regr1_lint, regr2_lint, regr3_lint, &
+                     regr4_lint, regr5_lint
+  END INTERFACE
+
+  PRIVATE
+  PUBLIC :: regr_lint
+
+CONTAINS
+
+
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE regr1_lint(ix, vs, xs, xt, vt)
+!
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER, INTENT(IN)  :: ix
+  REAL,    INTENT(IN)  :: vs(:)
+  REAL,    INTENT(IN)  :: xs(:)
+  REAL,    INTENT(IN)  :: xt(:)
+  REAL,    INTENT(OUT) :: vt(:)
+!-------------------------------------------------------------------------------
+! Local variables:
+  INTEGER :: is, it, ns, nt, isb ! "is" bound between 1 and "ns - 1"
+  REAL    :: r
+!-------------------------------------------------------------------------------
+  CALL check_size(ix,SHAPE(vs),SHAPE(vt),SIZE(xs),SIZE(xt),ns,nt)
+  is = -1 ! go immediately to bisection on first call to "hunt"
+  DO it=1,SIZE(xt)
+    CALL hunt(xs,xt(it),is); isb=MIN(MAX(is,1),ns-1)
+    r=(xs(isb+1)-xt(it))/(xs(isb+1)-xs(isb))
+    vt(it)=r*vs(isb)+(1.-r)*vs(isb+1)
+  END DO
+
+END SUBROUTINE regr1_lint
+!
+!-------------------------------------------------------------------------------
+
+
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE regr2_lint(ix, vs, xs, xt, vt)
+!
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER, INTENT(IN)  :: ix
+  REAL,    INTENT(IN)  :: vs(:,:)
+  REAL,    INTENT(IN)  :: xs(:)
+  REAL,    INTENT(IN)  :: xt(:)
+  REAL,    INTENT(OUT) :: vt(:,:)
+!-------------------------------------------------------------------------------
+! Local variables:
+  INTEGER :: is, it, ns, nt, isb ! "is" bound between 1 and "ns - 1"
+  REAL    :: r
+!-------------------------------------------------------------------------------
+  CALL check_size(ix,SHAPE(vs),SHAPE(vt),SIZE(xs),SIZE(xt),ns,nt)
+  is = -1 ! go immediately to bisection on first call to "hunt"
+  DO it=1,SIZE(xt)
+    CALL hunt(xs,xt(it),is); isb=MIN(MAX(is,1),ns-1)
+    r=(xs(isb+1)-xt(it))/(xs(isb+1)-xs(isb))
+    IF(ix==1) vt(it,:)=r*vs(isb,:)+(1.-r)*vs(isb+1,:)
+    IF(ix==2) vt(:,it)=r*vs(:,isb)+(1.-r)*vs(:,isb+1)
+  END DO
+
+END SUBROUTINE regr2_lint
+!
+!-------------------------------------------------------------------------------
+
+
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE regr3_lint(ix, vs, xs, xt, vt)
+!
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER, INTENT(IN)  :: ix
+  REAL,    INTENT(IN)  :: vs(:,:,:)
+  REAL,    INTENT(IN)  :: xs(:)
+  REAL,    INTENT(IN)  :: xt(:)
+  REAL,    INTENT(OUT) :: vt(:,:,:)
+!-------------------------------------------------------------------------------
+! Local variables:
+  INTEGER :: is, it, ns, nt, isb ! "is" bound between 1 and "ns - 1"
+  REAL    :: r
+!-------------------------------------------------------------------------------
+  CALL check_size(ix,SHAPE(vs),SHAPE(vt),SIZE(xs),SIZE(xt),ns,nt)
+  is = -1 ! go immediately to bisection on first call to "hunt"
+  DO it=1,SIZE(xt)
+    CALL hunt(xs,xt(it),is); isb=MIN(MAX(is,1),ns-1)
+    r=(xs(isb+1)-xt(it))/(xs(isb+1)-xs(isb))
+    IF(ix==1) vt(it,:,:)=r*vs(isb,:,:)+(1.-r)*vs(isb+1,:,:)
+    IF(ix==2) vt(:,it,:)=r*vs(:,isb,:)+(1.-r)*vs(:,isb+1,:)
+    IF(ix==3) vt(:,:,it)=r*vs(:,:,isb)+(1.-r)*vs(:,:,isb+1)
+  END DO
+
+END SUBROUTINE regr3_lint
+!
+!-------------------------------------------------------------------------------
+
+
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE regr4_lint(ix, vs, xs, xt, vt)
+!
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER, INTENT(IN)  :: ix
+  REAL,    INTENT(IN)  :: vs(:,:,:,:)
+  REAL,    INTENT(IN)  :: xs(:)
+  REAL,    INTENT(IN)  :: xt(:)
+  REAL,    INTENT(OUT) :: vt(:,:,:,:)
+!-------------------------------------------------------------------------------
+! Local variables:
+  INTEGER :: is, it, ns, nt, isb ! "is" bound between 1 and "ns - 1"
+  REAL    :: r
+!-------------------------------------------------------------------------------
+  CALL check_size(ix,SHAPE(vs),SHAPE(vt),SIZE(xs),SIZE(xt),ns,nt)
+  is = -1 ! go immediately to bisection on first call to "hunt"
+  DO it=1,SIZE(xt)
+    CALL hunt(xs,xt(it),is); isb=MIN(MAX(is,1),ns-1)
+    r=(xs(isb+1)-xt(it))/(xs(isb+1)-xs(isb))
+    IF(ix==1) vt(it,:,:,:)=r*vs(isb,:,:,:)+(1.-r)*vs(isb+1,:,:,:)
+    IF(ix==2) vt(:,it,:,:)=r*vs(:,isb,:,:)+(1.-r)*vs(:,isb+1,:,:)
+    IF(ix==3) vt(:,:,it,:)=r*vs(:,:,isb,:)+(1.-r)*vs(:,:,isb+1,:)
+    IF(ix==4) vt(:,:,:,it)=r*vs(:,:,:,isb)+(1.-r)*vs(:,:,:,isb+1)
+  END DO
+
+END SUBROUTINE regr4_lint
+!
+!-------------------------------------------------------------------------------
+
+
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE regr5_lint(ix, vs, xs, xt, vt)
+!
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER, INTENT(IN)  :: ix
+  REAL,    INTENT(IN)  :: vs(:,:,:,:,:)
+  REAL,    INTENT(IN)  :: xs(:)
+  REAL,    INTENT(IN)  :: xt(:)
+  REAL,    INTENT(OUT) :: vt(:,:,:,:,:)
+!-------------------------------------------------------------------------------
+! Local variables:
+  INTEGER :: is, it, ns, nt, isb ! "is" bound between 1 and "ns - 1"
+  REAL    :: r
+!-------------------------------------------------------------------------------
+  CALL check_size(ix,SHAPE(vs),SHAPE(vt),SIZE(xs),SIZE(xt),ns,nt)
+  is = -1 ! go immediately to bisection on first call to "hunt"
+  DO it=1,SIZE(xt)
+    CALL hunt(xs,xt(it),is); isb=MIN(MAX(is,1),ns-1)
+    r=(xs(isb+1)-xt(it))/(xs(isb+1)-xs(isb))
+    IF(ix==1) vt(it,:,:,:,:)=r*vs(isb,:,:,:,:)+(1.-r)*vs(isb+1,:,:,:,:)
+    IF(ix==2) vt(:,it,:,:,:)=r*vs(:,isb,:,:,:)+(1.-r)*vs(:,isb+1,:,:,:)
+    IF(ix==3) vt(:,:,it,:,:)=r*vs(:,:,isb,:,:)+(1.-r)*vs(:,:,isb+1,:,:)
+    IF(ix==4) vt(:,:,:,it,:)=r*vs(:,:,:,isb,:)+(1.-r)*vs(:,:,:,isb+1,:)
+    IF(ix==5) vt(:,:,:,:,it)=r*vs(:,:,:,:,isb)+(1.-r)*vs(:,:,:,:,isb+1)
+  END DO
+
+END SUBROUTINE regr5_lint
+!
+!-------------------------------------------------------------------------------
+
+
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE check_size(ix,svs,svt,nxs,nxt,ns,nt)
+!
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER, INTENT(IN)  :: ix, svs(:), svt(:), nxs, nxt
+  INTEGER, INTENT(OUT) :: ns, nt
+!-------------------------------------------------------------------------------
+! Local variables:
+  INTEGER :: rk, is
+  CHARACTER(LEN=80) :: sub, msg
+!-------------------------------------------------------------------------------
+  rk=SIZE(svs)
+  WRITE(sub,'(a,2i0,a)')"regr",rk,ix,"_lint"
+  CALL assert(ix>=1.AND.ix<=rk,TRIM(sub)//": ix exceeds fields rank")
+  DO is=1,rk; IF(is==ix) CYCLE
+    WRITE(msg,'(a,i1)')TRIM(sub)//" n",is
+    CALL assert(svs(is)==svt(is),msg)
+  END DO
+  ns=assert_eq(svs(ix),nxs,TRIM(sub)//" ns")
+  nt=assert_eq(svt(ix),nxt,TRIM(sub)//" nt")
+
+END SUBROUTINE check_size
+!
+!-------------------------------------------------------------------------------
+
+END MODULE regr_lint_m
+!
+!-------------------------------------------------------------------------------
+
Index: LMDZ5/branches/testing/libf/misc/slopes_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/misc/slopes_m.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/misc/slopes_m.F90	(revision 2839)
@@ -1,226 +1,283 @@
-module slopes_m
+MODULE slopes_m
 
   ! Author: Lionel GUEZ
-
-  implicit none
-
-  interface slopes
-     ! This generic function computes second order slopes with Van
-     ! Leer slope-limiting, given cell averages. Reference: Dukowicz,
-     ! 1987, SIAM Journal on Scientific and Statistical Computing, 8,
-     ! 305.
-
-     ! The only difference between the specific functions is the rank
-     ! of the first argument and the equal rank of the result.
-
-     ! real, intent(in), rank >= 1:: f ! (n, ...) cell averages, n must be >= 1
-     ! real, intent(in):: x(:) ! (n + 1) cell edges
-     ! real slopes, same shape as f ! (n, ...)
-
-     module procedure slopes1, slopes2, slopes3, slopes4
-  end interface
-
-  private
-  public slopes
-
-contains
-
-  pure function slopes1(f, x)
-
-    real, intent(in):: f(:)
-    real, intent(in):: x(:)
-    real slopes1(size(f))
-
-    ! Local:
-    integer n, i
-    real xc(size(f)) ! (n) cell centers
-    real h
-
-    !------------------------------------------------------
-
-    n = size(f)
-    forall (i = 1:n) xc(i) = (x(i) + x(i + 1)) / 2.
-    slopes1(1) = 0.
-    slopes1(n) = 0.
-
-    do i = 2, n - 1
-       if (f(i) >= max(f(i - 1), f(i + 1)) .or. f(i) &
-            <= min(f(i - 1), f(i + 1))) then
-          ! Local extremum
-          slopes1(i) = 0.
-       else
-          ! (f(i - 1), f(i), f(i + 1)) strictly monotonous
-
-          ! Second order slope:
-          slopes1(i) = (f(i + 1) - f(i - 1)) / (xc(i + 1) - xc(i - 1))
-
-          ! Slope limitation:
-          h = abs(x(i + 1) - xc(i))
-          slopes1(i) = sign(min(abs(slopes1(i)), abs(f(i + 1) - f(i)) / h, &
-               abs(f(i) - f(i - 1)) / h), slopes1(i))
-       end if
-    end do
-
-  end function slopes1
-
-  !*************************************************************
-
-  pure function slopes2(f, x)
-
-    real, intent(in):: f(:, :)
-    real, intent(in):: x(:)
-    real slopes2(size(f, 1), size(f, 2))
-
-    ! Local:
-    integer n, i, j
-    real xc(size(f, 1)) ! (n) cell centers
-    real h(2:size(f, 1) - 1), delta_xc(2:size(f, 1) - 1) ! (2:n - 1)
-
-    !------------------------------------------------------
-
-    n = size(f, 1)
-    forall (i = 1:n) xc(i) = (x(i) + x(i + 1)) / 2.
-
-    forall (i = 2:n - 1) 
-       h(i) = abs(x(i + 1) - xc(i))
-       delta_xc(i) = xc(i + 1) - xc(i - 1)
-    end forall
-
-    do j = 1, size(f, 2)
-       slopes2(1, j) = 0.
-
-       do i = 2, n - 1
-          if (f(i, j) >= max(f(i - 1, j), f(i + 1, j)) .or. &
-               f(i, j) <= min(f(i - 1, j), f(i + 1, j))) then
-             ! Local extremum
-             slopes2(i, j) = 0.
-          else
-             ! (f(i - 1, j), f(i, j), f(i + 1, j))
-             ! strictly monotonous
-
-             ! Second order slope:
-             slopes2(i, j) = (f(i + 1, j) - f(i - 1, j)) / delta_xc(i)
-
-             ! Slope limitation:
-             slopes2(i, j) = sign(min(abs(slopes2(i, j)), &
-                  abs(f(i + 1, j) - f(i, j)) / h(i), &
-                  abs(f(i, j) - f(i - 1, j)) / h(i)), slopes2(i, j))
-          end if
-       end do
-
-       slopes2(n, j) = 0.
-    end do
-
-  end function slopes2
-
-  !*************************************************************
-
-  pure function slopes3(f, x)
-
-    real, intent(in):: f(:, :, :)
-    real, intent(in):: x(:)
-    real slopes3(size(f, 1), size(f, 2), size(f, 3))
-
-    ! Local:
-    integer n, i, j, k
-    real xc(size(f, 1)) ! (n) cell centers
-    real h(2:size(f, 1) - 1), delta_xc(2:size(f, 1) - 1) ! (2:n - 1)
-
-    !------------------------------------------------------
-
-    n = size(f, 1)
-    forall (i = 1:n) xc(i) = (x(i) + x(i + 1)) / 2.
-
-    forall (i = 2:n - 1) 
-       h(i) = abs(x(i + 1) - xc(i))
-       delta_xc(i) = xc(i + 1) - xc(i - 1)
-    end forall
-
-    do k = 1, size(f, 3)
-       do j = 1, size(f, 2)
-          slopes3(1, j, k) = 0.
-
-          do i = 2, n - 1
-             if (f(i, j, k) >= max(f(i - 1, j, k), f(i + 1, j, k)) .or. &
-                  f(i, j, k) <= min(f(i - 1, j, k), f(i + 1, j, k))) then
-                ! Local extremum
-                slopes3(i, j, k) = 0.
-             else
-                ! (f(i - 1, j, k), f(i, j, k), f(i + 1, j, k))
-                ! strictly monotonous
-
-                ! Second order slope:
-                slopes3(i, j, k) = (f(i + 1, j, k) - f(i - 1, j, k)) &
-                     / delta_xc(i)
-
-                ! Slope limitation:
-                slopes3(i, j, k) = sign(min(abs(slopes3(i, j, k)), &
-                     abs(f(i + 1, j, k) - f(i, j, k)) / h(i), &
-                     abs(f(i, j, k) - f(i - 1, j, k)) / h(i)), slopes3(i, j, k))
-             end if
-          end do
-
-          slopes3(n, j, k) = 0.
-       end do
-    end do
-
-  end function slopes3
-
-  !*************************************************************
-
-  pure function slopes4(f, x)
-
-    real, intent(in):: f(:, :, :, :)
-    real, intent(in):: x(:)
-    real slopes4(size(f, 1), size(f, 2), size(f, 3), size(f, 4))
-
-    ! Local:
-    integer n, i, j, k, l
-    real xc(size(f, 1)) ! (n) cell centers
-    real h(2:size(f, 1) - 1), delta_xc(2:size(f, 1) - 1) ! (2:n - 1)
-
-    !------------------------------------------------------
-
-    n = size(f, 1)
-    forall (i = 1:n) xc(i) = (x(i) + x(i + 1)) / 2.
-
-    forall (i = 2:n - 1) 
-       h(i) = abs(x(i + 1) - xc(i))
-       delta_xc(i) = xc(i + 1) - xc(i - 1)
-    end forall
-
-    do l = 1, size(f, 4)
-       do k = 1, size(f, 3)
-          do j = 1, size(f, 2)
-             slopes4(1, j, k, l) = 0.
-
-             do i = 2, n - 1
-                if (f(i, j, k, l) >= max(f(i - 1, j, k, l), f(i + 1, j, k, l)) &
-                     .or. f(i, j, k, l) &
-                     <= min(f(i - 1, j, k, l), f(i + 1, j, k, l))) then
-                   ! Local extremum
-                   slopes4(i, j, k, l) = 0.
-                else
-                   ! (f(i - 1, j, k, l), f(i, j, k, l), f(i + 1, j, k, l))
-                   ! strictly monotonous
-
-                   ! Second order slope:
-                   slopes4(i, j, k, l) = (f(i + 1, j, k, l) &
-                        - f(i - 1, j, k, l)) / delta_xc(i)
-
-                   ! Slope limitation:
-                   slopes4(i, j, k, l) = sign(min(abs(slopes4(i, j, k, l)), &
-                        abs(f(i + 1, j, k, l) - f(i, j, k, l)) / h(i), &
-                        abs(f(i, j, k, l) - f(i - 1, j, k, l)) / h(i)), &
-                        slopes4(i, j, k, l))
-                end if
-             end do
-
-             slopes4(n, j, k, l) = 0.
-          end do
-       end do
-    end do
-
-  end function slopes4
-
-end module slopes_m
+  ! Extension / factorisation: David CUGNET
+
+  IMPLICIT NONE
+
+  ! Those generic function computes second order slopes with Van
+  ! Leer slope-limiting, given cell averages. Reference: Dukowicz,
+  ! 1987, SIAM Journal on Scientific and Statistical Computing, 8,
+  ! 305.
+
+  ! The only difference between the specific functions is the rank
+  ! of the first argument and the equal rank of the result.
+
+  ! slope(ix,...) acts on ix th dimension.
+
+  ! real, intent(in), rank >= 1:: f ! (n, ...) cell averages, n must be >= 1
+  ! real, intent(in):: x(:) ! (n + 1) cell edges
+  ! real slopes, same shape as f ! (n, ...)
+  INTERFACE slopes
+     MODULE procedure slopes1, slopes2, slopes3, slopes4, slopes5
+  END INTERFACE
+
+  PRIVATE
+  PUBLIC :: slopes
+
+CONTAINS
+
+!-------------------------------------------------------------------------------
+!
+PURE FUNCTION slopes1(ix, f, x)
+!
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER, INTENT(IN) :: ix
+  REAL,    INTENT(IN) :: f(:)
+  REAL,    INTENT(IN) :: x(:)
+  REAL :: slopes1(SIZE(f,1))
+!-------------------------------------------------------------------------------
+! Local:
+  INTEGER :: n, i, j, sta(2), sto(2)
+  REAL :: xc(SIZE(f,1))                             ! (n) cell centers
+  REAL :: h(2:SIZE(f,1)-1), delta_xc(2:SIZE(f,1)-1) ! (2:n-1)
+  REAL :: fm, ff, fp, dx
+!-------------------------------------------------------------------------------
+  n=SIZE(f,ix)
+  FORALL(i=1:n) xc(i)=(x(i)+x(i+1))/2.
+  FORALL(i=2:n-1)
+    h(i)=ABS(x(i+1)-xc(i)) ; delta_xc(i)=xc(i+1)-xc(i-1)
+  END FORALL
+  slopes1(:)=0.
+  DO i=2,n-1
+    ff=f(i); fm=f(i-1); fp=f(i+1)
+    IF(ff>=MAX(fm,fp).OR.ff<=MIN(fm,fp)) THEN
+      slopes1(i)=0.; CYCLE           !--- Local extremum
+      !--- 2nd order slope ; (fm, ff, fp) strictly monotonous
+      slopes1(i)=(fp-fm)/delta_xc(i)
+      !--- Slope limitation
+      slopes1(i) = SIGN(MIN(ABS(slopes1(i)), &
+        ABS(fp-ff)/h(i),ABS(ff-fm)/h(i)),slopes1(i) )
+     END IF
+  END DO
+
+END FUNCTION slopes1
+!
+!-------------------------------------------------------------------------------
+
+
+!-------------------------------------------------------------------------------
+!
+PURE FUNCTION slopes2(ix, f, x)
+!
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER, INTENT(IN) :: ix
+  REAL,    INTENT(IN) :: f(:, :)
+  REAL,    INTENT(IN) :: x(:)
+  REAL :: slopes2(SIZE(f,1),SIZE(f,2))
+!-------------------------------------------------------------------------------
+! Local:
+  INTEGER :: n, i, j, sta(2), sto(2)
+  REAL, ALLOCATABLE :: xc(:)                        ! (n) cell centers
+  REAL, ALLOCATABLE :: h(:), delta_xc(:)            ! (2:n-1)
+  REAL :: fm, ff, fp, dx
+!-------------------------------------------------------------------------------
+  n=SIZE(f,ix); ALLOCATE(xc(n),h(2:n-1),delta_xc(2:n-1))
+  FORALL(i=1:n) xc(i)=(x(i)+x(i+1))/2.
+  FORALL(i=2:n-1)
+    h(i)=ABS(x(i+1)-xc(i)) ; delta_xc(i)=xc(i+1)-xc(i-1)
+  END FORALL
+  slopes2(:,:)=0.
+  sta=[1,1]; sta(ix)=2
+  sto=SHAPE(f); sto(ix)=n-1
+  DO j=sta(2),sto(2); IF(ix==2) dx=delta_xc(j)
+    DO i=sta(1),sto(1); IF(ix==1) dx=delta_xc(i)
+      ff=f(i,j)
+      SELECT CASE(ix)
+        CASE(1); fm=f(i-1,j); fp=f(i+1,j)
+        CASE(2); fm=f(i,j-1); fp=f(i,j+1)
+      END SELECT
+      IF(ff>=MAX(fm,fp).OR.ff<=MIN(fm,fp)) THEN
+        slopes2(i,j)=0.; CYCLE           !--- Local extremum
+        !--- 2nd order slope ; (fm, ff, fp) strictly monotonous
+        slopes2(i,j)=(fp-fm)/dx
+        !--- Slope limitation
+        slopes2(i,j) = SIGN(MIN(ABS(slopes2(i,j)), &
+          ABS(fp-ff)/h(i),ABS(ff-fm)/h(i)),slopes2(i,j) )
+       END IF
+    END DO
+  END DO
+  DEALLOCATE(xc,h,delta_xc)
+
+END FUNCTION slopes2
+!
+!-------------------------------------------------------------------------------
+
+
+!-------------------------------------------------------------------------------
+!
+PURE FUNCTION slopes3(ix, f, x)
+!
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER, INTENT(IN) :: ix
+  REAL,    INTENT(IN) :: f(:, :, :)
+  REAL,    INTENT(IN) :: x(:)
+  REAL :: slopes3(SIZE(f,1),SIZE(f,2),SIZE(f,3))
+!-------------------------------------------------------------------------------
+! Local:
+  INTEGER :: n, i, j, k, sta(3), sto(3)
+  REAL, ALLOCATABLE :: xc(:)                        ! (n) cell centers
+  REAL, ALLOCATABLE :: h(:), delta_xc(:)            ! (2:n-1)
+  REAL :: fm, ff, fp, dx
+!-------------------------------------------------------------------------------
+  n=SIZE(f,ix); ALLOCATE(xc(n),h(2:n-1),delta_xc(2:n-1))
+  FORALL(i=1:n) xc(i)=(x(i)+x(i+1))/2.
+  FORALL(i=2:n-1)
+    h(i)=ABS(x(i+1)-xc(i)) ; delta_xc(i)=xc(i+1)-xc(i-1)
+  END FORALL
+  slopes3(:,:,:)=0.
+  sta=[1,1,1]; sta(ix)=2
+  sto=SHAPE(f); sto(ix)=n-1
+  DO k=sta(3),sto(3); IF(ix==3) dx=delta_xc(k)
+    DO j=sta(2),sto(2); IF(ix==2) dx=delta_xc(j)
+      DO i=sta(1),sto(1); IF(ix==1) dx=delta_xc(i)
+        ff=f(i,j,k)
+        SELECT CASE(ix)
+          CASE(1); fm=f(i-1,j,k); fp=f(i+1,j,k)
+          CASE(2); fm=f(i,j-1,k); fp=f(i,j+1,k)
+          CASE(3); fm=f(i,j,k-1); fp=f(i,j,k+1)
+        END SELECT
+        IF(ff>=MAX(fm,fp).OR.ff<=MIN(fm,fp)) THEN
+          slopes3(i,j,k)=0.; CYCLE           !--- Local extremum
+          !--- 2nd order slope ; (fm, ff, fp) strictly monotonous
+          slopes3(i,j,k)=(fp-fm)/dx
+          !--- Slope limitation
+          slopes3(i,j,k) = SIGN(MIN(ABS(slopes3(i,j,k)), &
+            ABS(fp-ff)/h(i),ABS(ff-fm)/h(i)),slopes3(i,j,k) )
+         END IF
+      END DO
+    END DO
+  END DO
+  DEALLOCATE(xc,h,delta_xc)
+
+END FUNCTION slopes3
+!
+!-------------------------------------------------------------------------------
+
+
+!-------------------------------------------------------------------------------
+!
+PURE FUNCTION slopes4(ix, f, x)
+!
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER, INTENT(IN) :: ix
+  REAL,    INTENT(IN) :: f(:, :, :, :)
+  REAL,    INTENT(IN) :: x(:)
+  REAL :: slopes4(SIZE(f,1),SIZE(f,2),SIZE(f,3),SIZE(f,4))
+!-------------------------------------------------------------------------------
+! Local:
+  INTEGER :: n, i, j, k, l, m, sta(4), sto(4)
+  REAL, ALLOCATABLE :: xc(:)                        ! (n) cell centers
+  REAL, ALLOCATABLE :: h(:), delta_xc(:)            ! (2:n-1)
+  REAL :: fm, ff, fp, dx
+!-------------------------------------------------------------------------------
+  n=SIZE(f,ix); ALLOCATE(xc(n),h(2:n-1),delta_xc(2:n-1))
+  FORALL(i=1:n) xc(i)=(x(i)+x(i+1))/2.
+  FORALL(i=2:n-1)
+    h(i)=ABS(x(i+1)-xc(i)) ; delta_xc(i)=xc(i+1)-xc(i-1)
+  END FORALL
+  slopes4(:,:,:,:)=0.
+  sta=[1,1,1,1]; sta(ix)=2
+  sto=SHAPE(f); sto(ix)=n-1
+  DO l=sta(4),sto(4); IF(ix==4) dx=delta_xc(l)
+    DO k=sta(3),sto(3); IF(ix==3) dx=delta_xc(k)
+      DO j=sta(2),sto(2); IF(ix==2) dx=delta_xc(j)
+        DO i=sta(1),sto(1); IF(ix==1) dx=delta_xc(i)
+          ff=f(i,j,k,l)
+          SELECT CASE(ix)
+            CASE(1); fm=f(i-1,j,k,l); fp=f(i+1,j,k,l)
+            CASE(2); fm=f(i,j-1,k,l); fp=f(i,j+1,k,l)
+            CASE(3); fm=f(i,j,k-1,l); fp=f(i,j,k+1,l)
+            CASE(4); fm=f(i,j,k,l-1); fp=f(i,j,k,l+1)
+          END SELECT
+          IF(ff>=MAX(fm,fp).OR.ff<=MIN(fm,fp)) THEN
+            slopes4(i,j,k,l)=0.; CYCLE           !--- Local extremum
+            !--- 2nd order slope ; (fm, ff, fp) strictly monotonous
+            slopes4(i,j,k,l)=(fp-fm)/dx
+            !--- Slope limitation
+            slopes4(i,j,k,l) = SIGN(MIN(ABS(slopes4(i,j,k,l)), &
+              ABS(fp-ff)/h(i),ABS(ff-fm)/h(i)),slopes4(i,j,k,l) )
+           END IF
+        END DO
+      END DO
+    END DO
+  END DO
+  DEALLOCATE(xc,h,delta_xc)
+
+END FUNCTION slopes4
+!
+!-------------------------------------------------------------------------------
+
+
+!-------------------------------------------------------------------------------
+!
+PURE FUNCTION slopes5(ix, f, x)
+!
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER, INTENT(IN) :: ix
+  REAL,    INTENT(IN) :: f(:, :, :, :, :)
+  REAL,    INTENT(IN) :: x(:)
+  REAL :: slopes5(SIZE(f,1),SIZE(f,2),SIZE(f,3),SIZE(f,4),SIZE(f,5))
+!-------------------------------------------------------------------------------
+! Local:
+  INTEGER :: n, i, j, k, l, m, sta(5), sto(5)
+  REAL, ALLOCATABLE :: xc(:)                        ! (n) cell centers
+  REAL, ALLOCATABLE :: h(:), delta_xc(:)            ! (2:n-1)
+  REAL :: fm, ff, fp, dx
+!-------------------------------------------------------------------------------
+  n=SIZE(f,ix); ALLOCATE(xc(n),h(2:n-1),delta_xc(2:n-1))
+  FORALL(i=1:n) xc(i)=(x(i)+x(i+1))/2.
+  FORALL(i=2:n-1)
+    h(i)=ABS(x(i+1)-xc(i)) ; delta_xc(i)=xc(i+1)-xc(i-1)
+  END FORALL
+  slopes5(:,:,:,:,:)=0.
+  sta=[1,1,1,1,1]; sta(ix)=2
+  sto=SHAPE(f);    sto(ix)=n-1
+  DO m=sta(5),sto(5); IF(ix==5) dx=delta_xc(m)
+    DO l=sta(4),sto(4); IF(ix==4) dx=delta_xc(l)
+      DO k=sta(3),sto(3); IF(ix==3) dx=delta_xc(k)
+        DO j=sta(2),sto(2); IF(ix==2) dx=delta_xc(j)
+          DO i=sta(1),sto(1); IF(ix==1) dx=delta_xc(i)
+            ff=f(i,j,k,l,m)
+            SELECT CASE(ix)
+              CASE(1); fm=f(i-1,j,k,l,m); fp=f(i+1,j,k,l,m)
+              CASE(2); fm=f(i,j-1,k,l,m); fp=f(i,j+1,k,l,m)
+              CASE(3); fm=f(i,j,k-1,l,m); fp=f(i,j,k+1,l,m)
+              CASE(4); fm=f(i,j,k,l-1,m); fp=f(i,j,k,l+1,m)
+              CASE(5); fm=f(i,j,k,l,m-1); fp=f(i,j,k,l,m+1)
+            END SELECT
+            IF(ff>=MAX(fm,fp).OR.ff<=MIN(fm,fp)) THEN
+              slopes5(i,j,k,l,m)=0.; CYCLE           !--- Local extremum
+              !--- 2nd order slope ; (fm, ff, fp) strictly monotonous
+              slopes5(i,j,k,l,m)=(fp-fm)/dx
+              !--- Slope limitation
+              slopes5(i,j,k,l,m) = SIGN(MIN(ABS(slopes5(i,j,k,l,m)), &
+                ABS(fp-ff)/h(i),ABS(ff-fm)/h(i)),slopes5(i,j,k,l,m) )
+            END IF
+          END DO
+        END DO
+      END DO
+    END DO
+  END DO
+  DEALLOCATE(xc,h,delta_xc)
+
+END FUNCTION slopes5
+!
+!-------------------------------------------------------------------------------
+
+END MODULE slopes_m
Index: LMDZ5/branches/testing/libf/obsolete/regr1_conserv_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/obsolete/regr1_conserv_m.F90	(revision 2839)
+++ LMDZ5/branches/testing/libf/obsolete/regr1_conserv_m.F90	(revision 2839)
@@ -0,0 +1,358 @@
+module regr1_conserv_m
+
+  ! Author: Lionel GUEZ
+
+  use assert_eq_m, only: assert_eq
+  use assert_m, only: assert
+  use interpolation, only: locate
+
+  implicit none
+
+  interface regr1_conserv
+
+     ! This generic procedure regrids a piecewise linear function (not
+     ! necessarily continuous) by averaging it. This is a conservative
+     ! regridding. The regridding operation is done on the first
+     ! dimension of the input array. Input are positions of cell
+     ! edges. The target grid should be included in the source grid:
+     ! no extrapolation is allowed.
+
+     ! The only difference between the procedures is the rank of the
+     ! first argument.
+
+     ! real, intent(in), rank >= 1:: vs ! (ns, ...)
+     ! averages of cells of the source grid
+     ! vs(is, ...) for [xs(is), xs(is + 1)]
+
+     ! real, intent(in):: xs(:) ! (ns + 1)
+     ! edges of cells of the source grid, in strictly ascending order
+
+     ! real, intent(in):: xt(:) ! (nt + 1)
+     ! edges of cells of the target grid, in strictly ascending order
+
+     ! real, intent(in), optional, rank >= 1:: slope ! (ns, ...)
+     ! same rank as vs
+     ! slopes inside cells of the source grid
+     ! slope(is, ...) for [xs(is), xs(is + 1)]
+     ! If not present, slopes are taken equal to 0. The regridding is
+     ! then first order.
+
+     ! real, intent(out), rank >= 1:: vt(nt, ...) 
+     ! has the same rank as vs and slope
+     ! averages of cells of the target grid
+     ! vt(it, ...) for  [xt(it), xt(it + 1)]
+
+     ! ns and nt must be >= 1.
+
+     ! See notes for explanations on the algorithm and justification
+     ! of algorithmic choices.
+
+     module procedure regr11_conserv, regr12_conserv, regr13_conserv, &
+          regr14_conserv
+  end interface regr1_conserv
+
+  private
+  public regr1_conserv
+
+contains
+
+  subroutine regr11_conserv(vs, xs, xt, vt, slope)
+
+    ! vs and slope have rank 1.
+
+    real, intent(in):: vs(:)
+    real, intent(in):: xs(:)
+    real, intent(in):: xt(:)
+    real, intent(out):: vt(:)
+    real, intent(in), optional:: slope(:)
+
+    ! Local:
+    integer is, it, ns, nt
+    logical slope_present
+
+    !---------------------------------------------
+
+    ns = assert_eq(size(vs), size(xs) - 1, "regr11_conserv ns")
+    nt = assert_eq(size(xt) - 1, size(vt), "regr11_conserv nt")
+
+    ! Quick check on sort order:
+    call assert(xs(1) < xs(2), "regr11_conserv xs bad order")
+    call assert(xt(1) < xt(2), "regr11_conserv xt bad order")
+
+    call assert(xs(1) <= xt(1) .and. xt(nt + 1) <= xs(ns + 1), &
+         "regr11_conserv extrapolation")
+    slope_present = present(slope)
+
+    is = locate(xs, xt(1)) ! 1 <= is <= ns, because we forbid extrapolation
+    do it = 1, nt
+       ! 1 <= is <= ns
+       ! xs(is) <= xt(it) < xs(is + 1)
+       if (xt(it + 1) <= xs(is + 1)) then
+          vt(it) = mean_lin(xt(it), xt(it + 1))
+       else
+          vt(it) = mean_lin(xt(it), xs(is + 1)) * (xs(is + 1) - xt(it))
+          is = is + 1
+          do while (xs(is + 1) < xt(it + 1))
+             ! 1 <= is <= ns - 1
+             vt(it) = vt(it) + (xs(is + 1) - xs(is)) * vs(is)
+             is = is + 1
+          end do
+          ! 1 <= is <= ns
+          vt(it) = (vt(it) + mean_lin(xs(is), xt(it + 1)) * (xt(it + 1) &
+               - xs(is))) / (xt(it + 1) - xt(it))
+       end if
+
+       if (xs(is + 1) == xt(it + 1)) is = is + 1
+       ! 1 <= is <= ns .or. it == nt
+    end do
+
+  contains
+
+    real function mean_lin(a, b)
+
+      ! mean in [a, b] of the linear function in [xs(is), xs(is + 1)]
+
+      real, intent(in):: a, b
+
+      !---------------------------------------------
+
+      if (slope_present) then
+         mean_lin = slope(is) / 2. * (a + b - xs(is) - xs(is + 1)) + vs(is)
+      else
+         mean_lin = vs(is)
+      end if
+
+    end function mean_lin
+
+  end subroutine regr11_conserv
+
+  !********************************************
+
+  subroutine regr12_conserv(vs, xs, xt, vt, slope)
+
+    ! vs and slope have rank 2.
+
+    real, intent(in):: vs(:, :)
+    real, intent(in):: xs(:)
+    real, intent(in):: xt(:)
+    real, intent(out):: vt(:, :)
+    real, intent(in), optional:: slope(:, :)
+
+    ! Local:
+    integer is, it, ns, nt, n2
+    logical slope_present
+
+    !---------------------------------------------
+
+    ns = assert_eq(size(vs, 1), size(xs) - 1, "regr12_conserv ns")
+    nt = assert_eq(size(xt) - 1, size(vt, 1), "regr12_conserv nt")
+    n2 = assert_eq(size(vs, 2), size(vt, 2), "regr12_conserv n2")
+
+    ! Quick check on sort order:
+    call assert(xs(1) < xs(2), "regr12_conserv xs bad order")
+    call assert(xt(1) < xt(2), "regr12_conserv xt bad order")
+
+    call assert(xs(1) <= xt(1) .and. xt(nt + 1) <= xs(ns + 1), &
+         "regr12_conserv extrapolation")
+    slope_present = present(slope)
+
+    is = locate(xs, xt(1)) ! 1 <= is <= ns, because we forbid extrapolation
+    do it = 1, nt
+       ! 1 <= is <= ns
+       ! xs(is) <= xt(it) < xs(is + 1)
+       if (xt(it + 1) <= xs(is + 1)) then
+          vt(it, :) = mean_lin(xt(it), xt(it + 1))
+       else
+          vt(it, :) = mean_lin(xt(it), xs(is + 1)) * (xs(is + 1) - xt(it))
+          is = is + 1
+          do while (xs(is + 1) < xt(it + 1))
+             ! 1 <= is <= ns - 1
+             vt(it, :) = vt(it, :) + (xs(is + 1) - xs(is)) * vs(is, :)
+             is = is + 1
+          end do
+          ! 1 <= is <= ns
+          vt(it, :) = (vt(it, :) + mean_lin(xs(is), xt(it + 1)) * (xt(it + 1) &
+               - xs(is))) / (xt(it + 1) - xt(it))
+       end if
+
+       if (xs(is + 1) == xt(it + 1)) is = is + 1
+       ! 1 <= is <= ns .or. it == nt
+    end do
+
+  contains
+
+    function mean_lin(a, b)
+
+      ! mean in [a, b] of the linear function in [xs(is), xs(is + 1)]
+
+      real, intent(in):: a, b
+      real mean_lin(n2)
+
+      !---------------------------------------------
+
+      if (slope_present) then
+         mean_lin = slope(is, :) / 2. * (a + b - xs(is) - xs(is + 1)) &
+              + vs(is, :)
+      else
+         mean_lin = vs(is, :)
+      end if
+
+    end function mean_lin
+
+  end subroutine regr12_conserv
+
+  !********************************************
+
+  subroutine regr13_conserv(vs, xs, xt, vt, slope)
+
+    ! vs and slope have rank 3.
+
+    real, intent(in):: vs(:, :, :)
+    real, intent(in):: xs(:)
+    real, intent(in):: xt(:)
+    real, intent(out):: vt(:, :, :)
+    real, intent(in), optional:: slope(:, :, :)
+
+    ! Local:
+    integer is, it, ns, nt, n2, n3
+    logical slope_present
+
+    !---------------------------------------------
+
+    ns = assert_eq(size(vs, 1), size(xs) - 1, "regr13_conserv ns")
+    nt = assert_eq(size(xt) - 1, size(vt, 1), "regr13_conserv nt")
+    n2 = assert_eq(size(vs, 2), size(vt, 2), "regr13_conserv n2")
+    n3 = assert_eq(size(vs, 3), size(vt, 3), "regr13_conserv n3")
+
+    ! Quick check on sort order:
+    call assert(xs(1) < xs(2), "regr13_conserv xs bad order")
+    call assert(xt(1) < xt(2), "regr13_conserv xt bad order")
+
+    call assert(xs(1) <= xt(1) .and. xt(nt + 1) <= xs(ns + 1), &
+         "regr13_conserv extrapolation")
+    slope_present = present(slope)
+
+    is = locate(xs, xt(1)) ! 1 <= is <= ns, because we forbid extrapolation
+    do it = 1, nt
+       ! 1 <= is <= ns
+       ! xs(is) <= xt(it) < xs(is + 1)
+       if (xt(it + 1) <= xs(is + 1)) then
+          vt(it, :, :) = mean_lin(xt(it), xt(it + 1))
+       else
+          vt(it, :, :) = mean_lin(xt(it), xs(is + 1)) * (xs(is + 1) - xt(it))
+          is = is + 1
+          do while (xs(is + 1) < xt(it + 1))
+             ! 1 <= is <= ns - 1
+             vt(it, :, :) = vt(it, :, :) + (xs(is + 1) - xs(is)) * vs(is, :, :)
+             is = is + 1
+          end do
+          ! 1 <= is <= ns
+          vt(it, :, :) = (vt(it, :, :) + mean_lin(xs(is), xt(it + 1)) &
+               * (xt(it + 1) - xs(is))) / (xt(it + 1) - xt(it))
+       end if
+
+       if (xs(is + 1) == xt(it + 1)) is = is + 1
+       ! 1 <= is <= ns .or. it == nt
+    end do
+
+  contains
+
+    function mean_lin(a, b)
+
+      ! mean in [a, b] of the linear function in [xs(is), xs(is + 1)]
+
+      real, intent(in):: a, b
+      real mean_lin(n2, n3)
+
+      !---------------------------------------------
+
+      if (slope_present) then
+         mean_lin = slope(is, :, :) / 2. * (a + b - xs(is) - xs(is + 1)) &
+              + vs(is, :, :)
+      else
+         mean_lin = vs(is, :, :)
+      end if
+
+    end function mean_lin
+
+  end subroutine regr13_conserv
+
+  !********************************************
+
+  subroutine regr14_conserv(vs, xs, xt, vt, slope)
+
+    ! vs and slope have rank 4.
+
+    real, intent(in):: vs(:, :, :, :)
+    real, intent(in):: xs(:)
+    real, intent(in):: xt(:)
+    real, intent(out):: vt(:, :, :, :)
+    real, intent(in), optional:: slope(:, :, :, :)
+
+    ! Local:
+    integer is, it, ns, nt, n2, n3, n4
+    logical slope_present
+
+    !---------------------------------------------
+
+    ns = assert_eq(size(vs, 1), size(xs) - 1, "regr14_conserv ns")
+    nt = assert_eq(size(xt) - 1, size(vt, 1), "regr14_conserv nt")
+    n2 = assert_eq(size(vs, 2), size(vt, 2), "regr14_conserv n2")
+    n3 = assert_eq(size(vs, 3), size(vt, 3), "regr14_conserv n3")
+    n4 = assert_eq(size(vs, 4), size(vt, 4), "regr14_conserv n4")
+
+    ! Quick check on sort order:
+    call assert(xs(1) < xs(2), "regr14_conserv xs bad order")
+    call assert(xt(1) < xt(2), "regr14_conserv xt bad order")
+
+    call assert(xs(1) <= xt(1) .and. xt(nt + 1) <= xs(ns + 1), &
+         "regr14_conserv extrapolation")
+    slope_present = present(slope)
+
+    is = locate(xs, xt(1)) ! 1 <= is <= ns, because we forbid extrapolation
+    do it = 1, nt
+       ! 1 <= is <= ns
+       ! xs(is) <= xt(it) < xs(is + 1)
+       if (xt(it + 1) <= xs(is + 1)) then
+          vt(it, :, :, :) = mean_lin(xt(it), xt(it + 1))
+       else
+          vt(it, :, :, :) = mean_lin(xt(it), xs(is + 1)) * (xs(is + 1) - xt(it))
+          is = is + 1
+          do while (xs(is + 1) < xt(it + 1))
+             ! 1 <= is <= ns - 1
+             vt(it, :, :, :) = vt(it, :, :, :) + (xs(is + 1) - xs(is)) &
+                  * vs(is, :, :, :)
+             is = is + 1
+          end do
+          ! 1 <= is <= ns
+          vt(it, :, :, :) = (vt(it, :, :, :) + mean_lin(xs(is), xt(it + 1)) &
+               * (xt(it + 1) - xs(is))) / (xt(it + 1) - xt(it))
+       end if
+
+       if (xs(is + 1) == xt(it + 1)) is = is + 1
+       ! 1 <= is <= ns .or. it == nt
+    end do
+
+  contains
+
+    function mean_lin(a, b)
+
+      ! mean in [a, b] of the linear function in [xs(is), xs(is + 1)]
+
+      real, intent(in):: a, b
+      real mean_lin(n2, n3, n4)
+
+      !---------------------------------------------
+
+      if (slope_present) then
+         mean_lin = slope(is, :, :, :) / 2. * (a + b - xs(is) - xs(is + 1)) &
+              + vs(is, :, :, :)
+      else
+         mean_lin = vs(is, :, :, :)
+      end if
+
+    end function mean_lin
+
+  end subroutine regr14_conserv
+
+end module regr1_conserv_m
Index: LMDZ5/branches/testing/libf/obsolete/regr1_lint_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/obsolete/regr1_lint_m.F90	(revision 2839)
+++ LMDZ5/branches/testing/libf/obsolete/regr1_lint_m.F90	(revision 2839)
@@ -0,0 +1,98 @@
+! $Id$
+module regr1_lint_m
+
+  ! Author: Lionel GUEZ
+
+  implicit none
+
+  interface regr1_lint
+     ! Each procedure regrids by linear interpolation.
+     ! The regridding operation is done on the first dimension of the
+     ! input array.
+     ! The difference betwwen the procedures is the rank of the first argument.
+     module procedure regr11_lint, regr12_lint
+  end interface
+
+  private
+  public regr1_lint
+
+contains
+
+  function regr11_lint(vs, xs, xt) result(vt)
+
+    ! "vs" has rank 1.
+
+    use assert_eq_m, only: assert_eq
+    use interpolation, only: hunt !!, polint
+
+    real, intent(in):: vs(:)
+    ! (values of the function at source points "xs")
+
+    real, intent(in):: xs(:)
+    ! (abscissas of points in source grid, in strictly monotonic order)
+
+    real, intent(in):: xt(:)
+    ! (abscissas of points in target grid)
+
+    real vt(size(xt)) ! values of the function on the target grid
+
+    ! Variables local to the procedure:
+    integer is, it, ns
+    integer is_b ! "is" bound between 1 and "ns - 1"
+
+    !--------------------------------------
+
+    ns = assert_eq(size(vs), size(xs), "regr11_lint ns")
+
+    is = -1 ! go immediately to bisection on first call to "hunt"
+
+    do it = 1, size(xt)
+       call hunt(xs, xt(it), is)
+       is_b = min(max(is, 1), ns - 1)
+!!       call polint(xs(is_b:is_b+1), vs(is_b:is_b+1), xt(it), vt(it))
+       vt(it) = ((xs(is_b+1) - xt(it)) * vs(is_b) &
+            + (xt(it) - xs(is_b)) * vs(is_b+1)) / (xs(is_b+1) - xs(is_b))
+    end do
+
+  end function regr11_lint
+
+  !*********************************************************
+
+  function regr12_lint(vs, xs, xt) result(vt)
+
+    ! "vs" has rank 2.
+
+    use assert_eq_m, only: assert_eq
+    use interpolation, only: hunt
+
+    real, intent(in):: vs(:, :)
+    ! (values of the function at source points "xs")
+
+    real, intent(in):: xs(:)
+    ! (abscissas of points in source grid, in strictly monotonic order)
+
+    real, intent(in):: xt(:)
+    ! (abscissas of points in target grid)
+
+    real vt(size(xt), size(vs, 2)) ! values of the function on the target grid
+
+    ! Variables local to the procedure:
+    integer is, it, ns
+    integer is_b ! "is" bound between 1 and "ns - 1"
+
+    !--------------------------------------
+
+    ns = assert_eq(size(vs, 1), size(xs), "regr12_lint ns")
+
+    is = -1 ! go immediately to bisection on first call to "hunt"
+
+    do it = 1, size(xt)
+       call hunt(xs, xt(it), is)
+       is_b = min(max(is, 1), ns - 1)
+       vt(it, :) = ((xs(is_b+1) - xt(it)) * vs(is_b, :) &
+            + (xt(it) - xs(is_b)) * vs(is_b+1, :)) / (xs(is_b+1) - xs(is_b))
+    end do
+
+  end function regr12_lint
+
+end module regr1_lint_m
Index: LMDZ5/branches/testing/libf/obsolete/regr3_lint_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/obsolete/regr3_lint_m.F90	(revision 2839)
+++ LMDZ5/branches/testing/libf/obsolete/regr3_lint_m.F90	(revision 2839)
@@ -0,0 +1,100 @@
+! $Id$
+module regr3_lint_m
+
+  ! Author: Lionel GUEZ
+
+  implicit none
+
+  interface regr3_lint
+     ! Each procedure regrids by linear interpolation.
+     ! The regridding operation is done on the third dimension of the
+     ! input array.
+     ! The difference betwwen the procedures is the rank of the first argument.
+     module procedure regr33_lint, regr34_lint
+  end interface
+
+  private
+  public regr3_lint
+
+contains
+
+  function regr33_lint(vs, xs, xt) result(vt)
+
+    ! "vs" has rank 3.
+
+    use assert_eq_m, only: assert_eq
+    use interpolation, only: hunt
+
+    real, intent(in):: vs(:, :, :)
+    ! (values of the function at source points "xs")
+
+    real, intent(in):: xs(:)
+    ! (abscissas of points in source grid, in strictly monotonic order)
+
+    real, intent(in):: xt(:)
+    ! (abscissas of points in target grid)
+
+    real vt(size(vs, 1), size(vs, 2), size(xt))
+    ! (values of the function on the target grid)
+
+    ! Variables local to the procedure:
+    integer is, it, ns
+    integer is_b ! "is" bound between 1 and "ns - 1"
+
+    !--------------------------------------
+
+    ns = assert_eq(size(vs, 3), size(xs), "regr33_lint ns")
+
+    is = -1 ! go immediately to bisection on first call to "hunt"
+
+    do it = 1, size(xt)
+       call hunt(xs, xt(it), is)
+       is_b = min(max(is, 1), ns - 1)
+       vt(:, :, it) = ((xs(is_b+1) - xt(it)) * vs(:, :, is_b) &
+            + (xt(it) - xs(is_b)) * vs(:, :, is_b+1)) / (xs(is_b+1) - xs(is_b))
+    end do
+
+  end function regr33_lint
+
+  !*********************************************************
+
+  function regr34_lint(vs, xs, xt) result(vt)
+
+    ! "vs" has rank 4.
+
+    use assert_eq_m, only: assert_eq
+    use interpolation, only: hunt
+
+    real, intent(in):: vs(:, :, :, :)
+    ! (values of the function at source points "xs")
+
+    real, intent(in):: xs(:)
+    ! (abscissas of points in source grid, in strictly monotonic order)
+
+    real, intent(in):: xt(:)
+    ! (abscissas of points in target grid)
+
+    real vt(size(vs, 1), size(vs, 2), size(xt), size(vs, 4))
+    ! (values of the function on the target grid)
+
+    ! Variables local to the procedure:
+    integer is, it, ns
+    integer is_b ! "is" bound between 1 and "ns - 1"
+
+    !--------------------------------------
+
+    ns = assert_eq(size(vs, 3), size(xs), "regr34_lint ns")
+
+    is = -1 ! go immediately to bisection on first call to "hunt"
+
+    do it = 1, size(xt)
+       call hunt(xs, xt(it), is)
+       is_b = min(max(is, 1), ns - 1)
+       vt(:, :, it, :) = ((xs(is_b+1) - xt(it)) * vs(:, :, is_b, :) &
+            + (xt(it) - xs(is_b)) * vs(:, :, is_b+1, :)) &
+            / (xs(is_b+1) - xs(is_b))
+    end do
+
+  end function regr34_lint
+
+end module regr3_lint_m
Index: LMDZ5/branches/testing/libf/obsolete/regr_lat_time_climoz_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/obsolete/regr_lat_time_climoz_m.F90	(revision 2839)
+++ LMDZ5/branches/testing/libf/obsolete/regr_lat_time_climoz_m.F90	(revision 2839)
@@ -0,0 +1,450 @@
+! $Id$
+module regr_lat_time_climoz_m
+
+  ! Author: Lionel GUEZ
+
+  implicit none
+
+  private
+  public regr_lat_time_climoz
+
+contains
+
+  subroutine regr_lat_time_climoz(read_climoz)
+
+    ! "regr_lat_time_climoz" stands for "regrid latitude time
+    ! climatology ozone".
+
+    ! This procedure reads a climatology of ozone from a NetCDF file,
+    ! regrids it in latitude and time, and writes the regridded field
+    ! to a new NetCDF file.
+
+    ! The input field depends on time, pressure level and latitude.
+
+    ! If the input field has missing values, they must be signaled by
+    ! the "missing_value" attribute.
+
+    ! We assume that the input field is a step function of latitude
+    ! and that the input latitude coordinate gives the centers of steps.
+    ! Regridding in latitude is made by averaging, with a cosine of
+    ! latitude factor.
+    ! The target LMDZ latitude grid is the "scalar" grid: "rlatu".
+    ! The values of "rlatu" are taken to be the centers of intervals.
+
+    ! We assume that in the input file:
+
+    ! -- Latitude is in degrees.
+
+    ! -- Latitude and pressure are strictly monotonic (as all NetCDF
+    ! coordinate variables should be).
+
+    ! -- The time coordinate is in ascending order (even though we do
+    ! not use its values).
+    ! The input file may contain either values for 12 months or values
+    ! for 14 months.
+    ! If there are 14 months then we assume that we have (in that order):
+    ! December, January, February, ..., November, December, January
+
+    ! -- Missing values are contiguous, at the bottom of
+    ! the vertical domain and at the latitudinal boundaries.
+
+    ! If values are all missing at a given latitude and date, then we
+    ! replace those missing values by values at the closest latitude,
+    ! equatorward, with valid values.
+    ! Then, at each latitude and each date, the missing values are replaced
+    ! by the lowest valid value above missing values.
+
+    ! Regridding in time is by linear interpolation.
+    ! Monthly values are processed to get daily values, on the basis
+    ! of a 360-day calendar.
+    ! If there are 14 months, we use the first December value to
+    ! interpolate values between January 1st and mid-January.
+    ! We use the last January value to interpolate values between
+    ! mid-December and end of December.
+    ! If there are only 12 months in the input file then we assume
+    ! periodicity for interpolation at the beginning and at the end of the
+    ! year.
+
+    use mod_grid_phy_lmdz, ONLY : nbp_lat
+    use regr1_conserv_m, only: regr1_conserv
+    use regr3_lint_m, only: regr3_lint
+    use netcdf95, only: handle_err, nf95_close, nf95_get_att, nf95_gw_var, &
+         nf95_inq_dimid, nf95_inq_varid, nf95_inquire_dimension, nf95_open, &
+         nf95_put_var
+    use netcdf, only: nf90_get_att, nf90_get_var, nf90_noerr, nf90_nowrite
+    use assert_m, only: assert
+    use regular_lonlat_mod, only : boundslat_reg, south
+    use nrtype, only: pi
+    use slopes_m, only: slopes
+
+    integer, intent(in):: read_climoz ! read ozone climatology
+    ! Allowed values are 1 and 2
+    ! 1: read a single ozone climatology that will be used day and night
+    ! 2: read two ozone climatologies, the average day and night
+    ! climatology and the daylight climatology
+
+    ! Variables local to the procedure:
+
+    integer n_plev ! number of pressure levels in the input data
+    integer n_lat ! number of latitudes in the input data
+    integer n_month ! number of months in the input data
+
+    real, pointer:: latitude(:)
+    ! (of input data, converted to rad, sorted in strictly ascending order)
+
+    real, allocatable:: sin_lat_in_edg(:)
+    ! (sine of edges of latitude intervals for input data, in rad, in strictly
+    ! ascending order)
+
+    real, pointer:: plev(:)
+    ! pressure levels of input data, sorted in strictly ascending
+    ! order, converted to hPa
+
+    logical desc_lat ! latitude in descending order in the input file
+    logical desc_plev ! pressure levels in descending order in the input file
+
+    real, allocatable:: o3_in(:, :, :, :)
+    ! (n_lat, n_plev, n_month, read_climoz)
+    ! ozone climatologies from the input file
+    ! "o3_in(j, k, :, :)" is at latitude "latitude(j)" and pressure
+    ! level "plev(k)".
+    ! Third dimension is month index, first value may be December or January.
+    ! "o3_in(:, :, :, 1)" is for the day- night average, "o3_in(:, :, :, 2)"
+    ! is for daylight.
+
+    real missing_value
+
+    real, allocatable:: o3_regr_lat(:, :, :, :)
+    ! (nbp_lat, n_plev, 0:13, read_climoz)
+    ! mean of "o3_in" over a latitude interval of LMDZ
+    ! First dimension is latitude interval.
+    ! The latitude interval for "o3_regr_lat(j,:, :, :)" contains "rlatu(j)".
+    ! If "j" is between 2 and "nbp_lat - 1" then the interval is:
+    ! [rlatv(j), rlatv(j-1)]
+    ! If "j" is 1 or "nbp_lat" then the interval is:
+    ! [rlatv(1), pi / 2]
+    ! or:
+    ! [- pi / 2, rlatv(nbp_lat - 1)]
+    ! respectively.
+    ! "o3_regr_lat(:, k, :, :)" is for pressure level "plev(k)".
+    ! Third dimension is month number, 1 for January.
+    ! "o3_regr_lat(:, :, :, 1)" is average day and night,
+    ! "o3_regr_lat(:, :, :, 2)" is for daylight.
+
+    real, allocatable:: o3_out(:, :, :, :)
+    ! (nbp_lat, n_plev, 360, read_climoz)
+    ! regridded ozone climatology
+    ! "o3_out(j, k, l, :)" is at latitude "rlatu(j)", pressure
+    ! level "plev(k)" and date "January 1st 0h" + "tmidday(l)", in a
+    ! 360-day calendar.
+    ! "o3_out(:, :, :, 1)" is average day and night,
+    ! "o3_out(:, :, :, 2)" is for daylight.
+
+    integer j, k, l,m
+
+    ! For NetCDF:
+    integer ncid_in, ncid_out ! IDs for input and output files
+    integer varid_plev, varid_time, varid, ncerr, dimid
+    character(len=80) press_unit ! pressure unit
+
+    integer varid_in(read_climoz), varid_out(read_climoz)
+    ! index 1 is for average ozone day and night, index 2 is for
+    ! daylight ozone.
+
+    real, parameter:: tmidmonth(0:13) = (/(-15. + 30. * l, l = 0, 13)/)
+    ! (time to middle of month, in days since January 1st 0h, in a
+    ! 360-day calendar)
+    ! (We add values -15 and 375 so that, for example, day 3 of the year is
+    ! interpolated between the December and the January value.)
+
+    real, parameter:: tmidday(360) = (/(l + 0.5, l = 0, 359)/)
+    ! (time to middle of day, in days since January 1st 0h, in a
+    ! 360-day calendar)
+
+    !---------------------------------
+
+    print *, "Call sequence information: regr_lat_time_climoz"
+    call assert(read_climoz == 1 .or. read_climoz == 2, "regr_lat_time_climoz")
+
+    call nf95_open("climoz.nc", nf90_nowrite, ncid_in)
+
+    ! Get coordinates from the input file:
+
+    call nf95_inq_varid(ncid_in, "latitude", varid)
+    call nf95_gw_var(ncid_in, varid, latitude)
+    ! Convert from degrees to rad, because we will take the sine of latitude:
+    latitude = latitude / 180. * pi
+    n_lat = size(latitude)
+    ! We need to supply the latitudes to "regr1_conserv" in
+    ! ascending order, so invert order if necessary:
+    desc_lat = latitude(1) > latitude(n_lat)
+    if (desc_lat) latitude = latitude(n_lat:1:-1)
+
+    ! Compute edges of latitude intervals:
+    allocate(sin_lat_in_edg(n_lat + 1))
+    sin_lat_in_edg(1) = - 1.
+    forall (j = 2:n_lat) sin_lat_in_edg(j) = sin((latitude(j - 1) &
+         + latitude(j)) / 2.)
+    sin_lat_in_edg(n_lat + 1) = 1.
+    deallocate(latitude) ! pointer
+
+    call nf95_inq_varid(ncid_in, "plev", varid)
+    call nf95_gw_var(ncid_in, varid, plev)
+    n_plev = size(plev)
+    ! We only need the pressure coordinate to copy it to the output file.
+    ! The program "gcm" will assume that pressure levels are in
+    ! ascending order in the regridded climatology so invert order if
+    ! necessary:
+    desc_plev = plev(1) > plev(n_plev)
+    if (desc_plev) plev = plev(n_plev:1:-1)
+    call nf95_get_att(ncid_in, varid, "units", press_unit)
+    if (press_unit == "Pa") then
+       ! Convert to hPa:
+       plev = plev / 100.
+    elseif (press_unit /= "hPa") then
+       print *, "regr_lat_time_climoz: the only recognized units are Pa " &
+            // "and hPa."
+       stop 1
+    end if
+
+    ! Create the output file and get the variable IDs:
+    call prepare_out(ncid_in, n_plev, ncid_out, varid_out, varid_plev, &
+         varid_time)
+
+    ! Write remaining coordinate variables:
+    call nf95_put_var(ncid_out, varid_plev, plev)
+    call nf95_put_var(ncid_out, varid_time, tmidday)
+
+    deallocate(plev) ! pointer
+
+    ! Get the  number of months:
+    call nf95_inq_dimid(ncid_in, "time", dimid)
+    call nf95_inquire_dimension(ncid_in, dimid, nclen=n_month)
+
+    allocate(o3_in(n_lat, n_plev, n_month, read_climoz))
+
+    call nf95_inq_varid(ncid_in, "tro3", varid_in(1))
+    ncerr = nf90_get_var(ncid_in, varid_in(1), o3_in(:, :, :, 1))
+    call handle_err("regr_lat_time_climoz nf90_get_var tro3", ncerr, ncid_in)
+
+    if (read_climoz == 2) then
+       call nf95_inq_varid(ncid_in, "tro3_daylight", varid_in(2))
+       ncerr = nf90_get_var(ncid_in, varid_in(2), o3_in(:, :, :, 2))
+       call handle_err("regr_lat_time_climoz nf90_get_var tro3_daylight", &
+            ncerr, ncid_in, varid_in(2))
+    end if
+
+    if (desc_lat) o3_in = o3_in(n_lat:1:-1, :, :, :)
+    if (desc_plev) o3_in = o3_in(:, n_plev:1:-1, :, :)
+
+    do m = 1, read_climoz
+       ncerr = nf90_get_att(ncid_in, varid_in(m), "missing_value", &
+            missing_value)
+       if (ncerr == nf90_noerr) then
+          do l = 1, n_month
+             ! Take care of latitudes where values are all missing:
+
+             ! Next to the south pole:
+             j = 1
+             do while (o3_in(j, 1, l, m) == missing_value)
+                j = j + 1
+             end do
+             if (j > 1) o3_in(:j-1, :, l, m) = &
+                  spread(o3_in(j, :, l, m), dim=1, ncopies=j-1)
+             
+             ! Next to the north pole:
+             j = n_lat
+             do while (o3_in(j, 1, l, m) == missing_value)
+                j = j - 1
+             end do
+             if (j < n_lat) o3_in(j+1:, :, l, m) = &
+                  spread(o3_in(j, :, l, m), dim=1, ncopies=n_lat-j)
+
+             ! Take care of missing values at high pressure:
+             do j = 1, n_lat
+                ! Find missing values, starting from top of atmosphere
+                ! and going down.
+                ! We have already taken care of latitudes full of
+                ! missing values so the highest level has a valid value.
+                k = 2
+                do while  (o3_in(j, k, l, m) /= missing_value .and. k < n_plev)
+                   k = k + 1
+                end do
+                ! Replace missing values with the valid value at the
+                ! lowest level above missing values:
+                if (o3_in(j, k, l, m) == missing_value) &
+                     o3_in(j, k:n_plev, l, m) = o3_in(j, k-1, l, m)
+             end do
+          end do
+       else
+          print *, "regr_lat_time_climoz: field ", m, &
+               ", no missing value attribute"
+       end if
+    end do
+
+    call nf95_close(ncid_in)
+
+    allocate(o3_regr_lat(nbp_lat, n_plev, 0:13, read_climoz))
+    allocate(o3_out(nbp_lat, n_plev, 360, read_climoz))
+
+    ! Regrid in latitude:
+    ! We average with respect to sine of latitude, which is
+    ! equivalent to weighting by cosine of latitude:
+    if (n_month == 12) then
+       print *, &
+            "Found 12 months in ozone climatologies, assuming periodicity..."
+       call regr1_conserv(o3_in, xs = sin_lat_in_edg, &
+            xt = (/- 1., sin(boundslat_reg(nbp_lat - 1:1:- 1, south)), 1./), &
+            vt = o3_regr_lat(nbp_lat:1:- 1, :, 1:12, :), &
+            slope = slopes(o3_in, sin_lat_in_edg))
+       ! (invert order of indices in "o3_regr_lat" because "rlatu" is
+       ! in descending order)
+
+       ! Duplicate January and December values, in preparation of time
+       ! interpolation:
+       o3_regr_lat(:, :, 0, :) = o3_regr_lat(:, :, 12, :)
+       o3_regr_lat(:, :, 13, :) = o3_regr_lat(:, :, 1, :)
+    else
+       print *, "Using 14 months in ozone climatologies..."
+       call regr1_conserv(o3_in, xs = sin_lat_in_edg, &
+            xt = (/- 1., sin(boundslat_reg(nbp_lat - 1:1:- 1, south)), 1./), &
+            vt = o3_regr_lat(nbp_lat:1:- 1, :, :, :), &
+            slope = slopes(o3_in, sin_lat_in_edg))
+       ! (invert order of indices in "o3_regr_lat" because "rlatu" is
+       ! in descending order)
+    end if
+
+    ! Regrid in time by linear interpolation:
+    o3_out = regr3_lint(o3_regr_lat, tmidmonth, tmidday)
+
+    ! Write to file:
+    do m = 1, read_climoz
+       call nf95_put_var(ncid_out, varid_out(m), o3_out(nbp_lat:1:-1, :, :, m))
+       ! (The order of "rlatu" is inverted in the output file)
+    end do
+
+    call nf95_close(ncid_out)
+
+  end subroutine regr_lat_time_climoz
+
+  !********************************************
+
+  subroutine prepare_out(ncid_in, n_plev, ncid_out, varid_out, varid_plev, &
+       varid_time)
+
+    ! This subroutine creates the NetCDF output file, defines
+    ! dimensions and variables, and writes one of the coordinate variables.
+
+    use mod_grid_phy_lmdz, ONLY : nbp_lat
+    use netcdf95, only: nf95_create, nf95_def_dim, nf95_def_var, &
+         nf95_put_att, nf95_enddef, nf95_copy_att, nf95_put_var
+    use netcdf, only: nf90_clobber, nf90_float, nf90_global
+    use nrtype, only: pi
+    use regular_lonlat_mod, only : lat_reg
+
+    integer, intent(in):: ncid_in, n_plev
+    integer, intent(out):: ncid_out, varid_plev, varid_time
+
+    integer, intent(out):: varid_out(:) ! dim(1 or 2)
+    ! "varid_out(1)" is for average ozone day and night,
+    ! "varid_out(2)" is for daylight ozone.
+
+    ! Variables local to the procedure:
+
+    integer ncerr
+    integer dimid_rlatu, dimid_plev, dimid_time
+    integer varid_rlatu
+
+    !---------------------------
+
+    print *, "Call sequence information: prepare_out"
+
+    call nf95_create("climoz_LMDZ.nc", nf90_clobber, ncid_out)
+
+    ! Dimensions:
+    call nf95_def_dim(ncid_out, "time", 360, dimid_time)
+    call nf95_def_dim(ncid_out, "plev", n_plev, dimid_plev)
+    call nf95_def_dim(ncid_out, "rlatu", nbp_lat, dimid_rlatu)
+
+    ! Define coordinate variables:
+
+    call nf95_def_var(ncid_out, "time", nf90_float, dimid_time, varid_time)
+    call nf95_put_att(ncid_out, varid_time, "units", "days since 2000-1-1")
+    call nf95_put_att(ncid_out, varid_time, "calendar", "360_day")
+    call nf95_put_att(ncid_out, varid_time, "standard_name", "time")
+
+    call nf95_def_var(ncid_out, "plev", nf90_float, dimid_plev, varid_plev)
+    call nf95_put_att(ncid_out, varid_plev, "units", "millibar")
+    call nf95_put_att(ncid_out, varid_plev, "standard_name", "air_pressure")
+    call nf95_put_att(ncid_out, varid_plev, "long_name", "air pressure")
+
+    call nf95_def_var(ncid_out, "rlatu", nf90_float, dimid_rlatu, varid_rlatu)
+    call nf95_put_att(ncid_out, varid_rlatu, "units", "degrees_north")
+    call nf95_put_att(ncid_out, varid_rlatu, "standard_name", "latitude")
+
+    ! Define the primary variables:
+
+    call nf95_def_var(ncid_out, "tro3", nf90_float, &
+         (/dimid_rlatu, dimid_plev, dimid_time/), varid_out(1))
+    call nf95_put_att(ncid_out, varid_out(1), "long_name", &
+         "ozone mole fraction")
+    call nf95_put_att(ncid_out, varid_out(1), "standard_name", &
+         "mole_fraction_of_ozone_in_air")
+
+    if (size(varid_out) == 2) then
+       call nf95_def_var(ncid_out, "tro3_daylight", nf90_float, &
+            (/dimid_rlatu, dimid_plev, dimid_time/), varid_out(2))
+       call nf95_put_att(ncid_out, varid_out(2), "long_name", &
+            "ozone mole fraction in daylight")
+    end if
+
+    ! Global attributes:
+
+    ! The following commands, copying attributes, may fail.
+    ! That is OK.
+    ! It should just mean that the attribute is not defined in the input file.
+
+    call nf95_copy_att(ncid_in, nf90_global, "Conventions", ncid_out, &
+         nf90_global, ncerr)
+    call handle_err_copy_att("Conventions")
+
+    call nf95_copy_att(ncid_in, nf90_global, "title", ncid_out, nf90_global, &
+         ncerr)
+    call handle_err_copy_att("title")
+
+    call nf95_copy_att(ncid_in, nf90_global, "institution", ncid_out, &
+         nf90_global, ncerr)
+    call handle_err_copy_att("institution")
+
+    call nf95_copy_att(ncid_in, nf90_global, "source", ncid_out, nf90_global, &
+         ncerr)
+    call handle_err_copy_att("source")
+
+    call nf95_put_att(ncid_out, nf90_global, "comment", "Regridded for LMDZ")
+
+    call nf95_enddef(ncid_out)
+
+    ! Write one of the coordinate variables:
+    call nf95_put_var(ncid_out, varid_rlatu, lat_reg(nbp_lat:1:-1) / pi * 180.)
+    ! (convert from rad to degrees and sort in ascending order)
+
+  contains
+
+    subroutine handle_err_copy_att(att_name)
+
+      use netcdf, only: nf90_noerr, nf90_strerror
+
+      character(len=*), intent(in):: att_name
+
+      !----------------------------------------
+
+      if (ncerr /= nf90_noerr) then
+         print *, "regr_lat_time_climoz_m prepare_out nf95_copy_att " &
+              // att_name // " -- " // trim(nf90_strerror(ncerr))
+      end if
+
+    end subroutine handle_err_copy_att
+
+  end subroutine prepare_out
+
+end module regr_lat_time_climoz_m
Index: LMDZ5/branches/testing/libf/obsolete/regr_pr_av_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/obsolete/regr_pr_av_m.F90	(revision 2839)
+++ LMDZ5/branches/testing/libf/obsolete/regr_pr_av_m.F90	(revision 2839)
@@ -0,0 +1,124 @@
+! $Id$
+module regr_pr_av_m
+
+  ! Author: Lionel GUEZ
+
+  implicit none
+
+contains
+
+  subroutine regr_pr_av(ncid, name, julien, press_in_edg, paprs, v3)
+
+    ! "regr_pr_av" stands for "regrid pressure averaging".
+    ! In this procedure:
+    ! -- the root process reads 2D latitude-pressure fields from a
+    !    NetCDF file, at a given day.
+    ! -- the fields are packed to the LMDZ horizontal "physics"
+    !    grid and scattered to all threads of all processes;
+    ! -- in all the threads of all the processes, the fields are regridded in
+    !    pressure to the LMDZ vertical grid.
+    ! We assume that, in the input file, the fields have 3 dimensions:
+    ! latitude, pressure, julian day.
+    ! We assume that the input fields are already on the "rlatu"
+    ! latitudes, except that latitudes are in ascending order in the input
+    ! file.
+    ! We assume that all the inputs fields have the same coordinates.
+
+    ! The target vertical LMDZ grid is the grid of layer boundaries.
+    ! Regridding in pressure is conservative, second order.
+
+    ! All the fields are regridded as a single multi-dimensional array
+    ! so it saves CPU time to call this procedure once for several NetCDF
+    ! variables rather than several times, each time for a single
+    ! NetCDF variable.
+
+    use dimphy, only: klon
+    use netcdf95, only: nf95_inq_varid, handle_err
+    use netcdf, only: nf90_get_var
+    use assert_m, only: assert
+    use assert_eq_m, only: assert_eq
+    use regr1_conserv_m, only: regr1_conserv
+    use slopes_m, only: slopes
+    use mod_phys_lmdz_mpi_data, only: is_mpi_root
+    use mod_grid_phy_lmdz, only: nbp_lon, nbp_lat, nbp_lev
+    use mod_phys_lmdz_transfert_para, only: scatter2d
+    ! (pack to the LMDZ horizontal "physics" grid and scatter)
+
+    integer, intent(in):: ncid ! NetCDF ID of the file
+    character(len=*), intent(in):: name(:) ! of the NetCDF variables
+    integer, intent(in):: julien ! jour julien, 1 <= julien <= 360
+
+    real, intent(in):: press_in_edg(:)
+    ! edges of pressure intervals for input data, in Pa, in strictly
+    ! ascending order
+
+    real, intent(in):: paprs(:, :) ! (klon, llm + 1)
+    ! (pression pour chaque inter-couche, en Pa)
+
+    real, intent(out):: v3(:, :, :) ! (klon, llm, size(name))
+    ! regridded fields on the partial "physics" grid
+    ! "v3(i, k, l)" is at longitude "xlon(i)", latitude
+    ! "xlat(i)", in pressure interval "[paprs(i, k+1), paprs(i, k)]",
+    ! for NetCDF variable "name(l)".
+
+    ! Variables local to the procedure:
+
+    integer varid, ncerr ! for NetCDF
+
+    real  v1(nbp_lon, nbp_lat, size(press_in_edg) - 1, size(name))
+    ! input fields at day "julien", on the global "dynamics" horizontal grid
+    ! First dimension is for longitude.
+    ! The values are the same for all longitudes.
+    ! "v1(:, j, k, l)" is at latitude "rlatu(j)", for
+    ! pressure interval "[press_in_edg(k), press_in_edg(k+1)]" and
+    ! NetCDF variable "name(l)".
+
+    real v2(klon, size(press_in_edg) - 1, size(name))
+    ! fields scattered to the partial "physics" horizontal grid
+    ! "v2(i, k, l)" is at longitude "xlon(i)", latitude "xlat(i)",
+    ! for pressure interval "[press_in_edg(k), press_in_edg(k+1)]" and
+    ! NetCDF variable "name(l)".
+
+    integer i, n_var
+
+    !--------------------------------------------
+
+    call assert(size(v3, 1) == klon, size(v3, 2) == nbp_lev, &
+         "regr_pr_av v3 klon")
+    n_var = assert_eq(size(name), size(v3, 3), "regr_pr_av v3 n_var")
+    call assert(shape(paprs) == (/klon, nbp_lev+1/), "regr_pr_av paprs")
+
+    !$omp master
+    if (is_mpi_root) then
+       do i = 1, n_var
+          call nf95_inq_varid(ncid, trim(name(i)), varid)
+          
+          ! Get data at the right day from the input file:
+          ncerr = nf90_get_var(ncid, varid, v1(1, :, :, i), &
+               start=(/1, 1, julien/))
+          call handle_err("regr_pr_av nf90_get_var " // trim(name(i)), ncerr, &
+               ncid)
+       end do
+       
+       ! Latitudes are in ascending order in the input file while
+       ! "rlatu" is in descending order so we need to invert order:
+       v1(1, :, :, :) = v1(1, nbp_lat:1:-1, :, :)
+
+       ! Duplicate on all longitudes:
+       v1(2:, :, :, :) = spread(v1(1, :, :, :), dim=1, ncopies=nbp_lon-1)
+    end if
+    !$omp end master
+
+    call scatter2d(v1, v2)
+
+    ! Regrid in pressure at each horizontal position:
+    do i = 1, klon
+       call regr1_conserv(v2(i, :, :), press_in_edg, &
+            paprs(i, nbp_lev + 1:1:-1), v3(i, nbp_lev:1:-1, :), &
+            slopes(v2(i, :, :), press_in_edg))
+       ! (invert order of indices because "paprs" is in descending order)
+    end do
+
+  end subroutine regr_pr_av
+
+end module regr_pr_av_m
Index: LMDZ5/branches/testing/libf/phy_common/vertical_layers_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/phy_common/vertical_layers_mod.F90	(revision 2839)
+++ LMDZ5/branches/testing/libf/phy_common/vertical_layers_mod.F90	(revision 2839)
@@ -0,0 +1,56 @@
+! $Id: $
+
+MODULE vertical_layers_mod
+
+   REAL,SAVE             :: preff  ! reference surface pressure (Pa)
+   REAL,SAVE             :: scaleheight ! atmospheric reference scale height (km)
+   REAL,SAVE,ALLOCATABLE :: ap(:) ! hybrid (pressure contribution) coordinate 
+                                  ! at layer interfaces (Pa)
+   REAL,SAVE,ALLOCATABLE :: bp(:) ! hybrid (sigma contribution) coordinate 
+                                  ! at layer interfaces (Pa)
+   REAL,SAVE,ALLOCATABLE :: aps(:) ! hybrid (pressure contribution) coordinate 
+                                   ! at mid-layer (Pa)
+   REAL,SAVE,ALLOCATABLE :: bps(:) ! hybrid (sigma contribution) coordinate 
+                                   ! at mid-layer
+   REAL,SAVE,ALLOCATABLE :: presnivs(:) ! reference pressure at mid-layer (Pa),
+                                        ! based on preff, ap and bp
+   REAL,SAVE,ALLOCATABLE :: pseudoalt(:) ! pseudo-altitude of model layers (km),
+                                         ! based on preff and scaleheight
+   
+!$OMP THREADPRIVATE(preff,scaleheight,ap,bp,aps,bps,presnivs,pseudoalt)
+
+
+CONTAINS
+
+  SUBROUTINE init_vertical_layers(nlayer,preff_,scaleheight_,ap_,bp_,&
+                                 aps_,bps_,presnivs_, pseudoalt_)
+    IMPLICIT NONE
+    INTEGER,INTENT(IN) :: nlayer ! number of atmospheric layers
+    REAL,INTENT(IN)    :: preff_ ! reference surface pressure (Pa)
+    REAL,INTENT(IN)    :: scaleheight_ ! atmospheric scale height (km)
+    REAL,INTENT(IN)    :: ap_(nlayer+1) ! hybrid coordinate at interfaces
+    REAL,INTENT(IN)    :: bp_(nlayer+1) ! hybrid coordinate at interfaces
+    REAL,INTENT(IN)    :: aps_(nlayer) ! hybrid coordinate at mid-layer
+    REAL,INTENT(IN)    :: bps_(nlayer) ! hybrid coordinate at mid-layer
+    REAL,INTENT(IN)    :: presnivs_(nlayer) ! Appproximative pressure of atm. layers (Pa)
+    REAL,INTENT(IN)    :: pseudoalt_(nlayer) ! pseudo-altitude of atm. layers (km)
+  
+    ALLOCATE(ap(nlayer+1))
+    ALLOCATE(bp(nlayer+1))
+    ALLOCATE(aps(nlayer))
+    ALLOCATE(bps(nlayer))
+    ALLOCATE(presnivs(nlayer))
+    ALLOCATE(pseudoalt(nlayer))
+  
+    preff = preff_
+    scaleheight=scaleheight_
+    ap(:) = ap_(:)
+    bp(:) = bp_(:)
+    aps(:) = aps_(:)
+    bps(:) = bps_(:)
+    presnivs(:) = presnivs_(:)
+    pseudoalt(:) = pseudoalt_(:)
+
+  END SUBROUTINE init_vertical_layers
+
+END MODULE vertical_layers_mod
Index: LMDZ5/branches/testing/libf/phylmd/YOETHF.h
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/YOETHF.h	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/YOETHF.h	(revision 2839)
@@ -19,4 +19,6 @@
       REAL R5ALVCP,R5ALSCP,RALVDCP,RALSDCP,RALFDCP,RTWAT,RTBER,RTBERCU
       REAL RTICE,RTICECU,RTWAT_RTICE_R,RTWAT_RTICECU_R,RKOOP1,RKOOP2
+      LOGICAL OK_BAD_ECMWF_THERMO ! If TRUE, then variables set by rrtm/suphec.F90
+                                  ! If FALSE, then variables set by suphel.F90
       COMMON /YOETHF/R2ES, R3LES, R3IES, R4LES, R4IES, R5LES, R5IES,    &
      &               RVTMP2, RHOH2O,                                    &
@@ -24,5 +26,6 @@
      &               RALFDCP,RTWAT,RTBER,RTBERCU,                       &
      &               RTICE,RTICECU,RTWAT_RTICE_R,RTWAT_RTICECU_R,RKOOP1,&
-     &               RKOOP2
+     &               RKOOP2,                                            &
+     &               OK_BAD_ECMWF_THERMO
 
 !$OMP THREADPRIVATE(/YOETHF/)
Index: LMDZ5/branches/testing/libf/phylmd/add_pbl_tend.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/add_pbl_tend.F90	(revision 2787)
+++ 	(revision )
@@ -1,66 +1,0 @@
-SUBROUTINE add_pbl_tend(zdu, zdv, zdt, zdq, zdql, zdqi, paprs, text,abortphy,flag_inhib_tend)
-  ! ======================================================================
-  ! Ajoute les tendances de couche limite, soit determinees par la
-  ! parametrisation
-  ! physique, soit forcees,  aux variables d etat de la dynamique t_seri,
-  ! q_seri ...
-  ! ======================================================================
-
-
-  ! ======================================================================
-  ! Declarations
-  ! ======================================================================
-
-  USE dimphy
-  USE phys_local_var_mod
-  USE phys_state_var_mod
-  USE mod_grid_phy_lmdz, ONLY: nbp_lev
-  IMPLICIT NONE
-  REAL,SAVE,ALLOCATABLE :: hthturb_gcssold(:)
-  REAL,SAVE,ALLOCATABLE :: hqturb_gcssold(:)
-!$OMP THREADPRIVATE(hthturb_gcssold,hqturb_gcssold)
-  REAL,SAVE :: dtime_frcg
-  LOGICAL,SAVE :: turb_fcg_gcssold
-  LOGICAL,SAVE :: firstcall=.true.
-!$OMP THREADPRIVATE(firstcall,turb_fcg_gcssold,dtime_frcg)
-  INTEGER abortphy
-!  COMMON /turb_forcing/dtime_frcg, hthturb_gcssold, hqturb_gcssold, &
-!    turb_fcg_gcssold
-
-  ! Arguments :
-  ! ------------
-  REAL zdu(klon, klev), zdv(klon, klev)
-  REAL zdt(klon, klev), zdq(klon, klev), zdql(klon, klev), zdqi(klon, klev)
-  CHARACTER *(*) text
-  REAL paprs(klon,klev+1)
-  INTEGER flag_inhib_tend ! if flag_inhib_tend != 0, tendencies are not added
-
-  ! Local :
-  ! --------
-  REAL zzdt(klon, klev), zzdq(klon, klev)
-  INTEGER i, k
-
-  IF (firstcall) THEN
-    ALLOCATE(hthturb_gcssold(nbp_lev))
-    ALLOCATE(hqturb_gcssold(nbp_lev))
-    firstcall=.false.
-  ENDIF
-
-  IF (turb_fcg_gcssold) THEN
-    DO k = 1, klev
-      DO i = 1, klon
-        zzdt(i, k) = hthturb_gcssold(k)*dtime_frcg
-        zzdq(i, k) = hqturb_gcssold(k)*dtime_frcg
-      END DO
-    END DO
-    PRINT *, ' add_pbl_tend, dtime_frcg ', dtime_frcg
-    PRINT *, ' add_pbl_tend, zzdt ', zzdt
-    PRINT *, ' add_pbl_tend, zzdq ', zzdq
-    CALL add_phys_tend(zdu, zdv, zzdt, zzdq, zdql, zdqi, paprs, text,abortphy,flag_inhib_tend)
-  ELSE
-    CALL add_phys_tend(zdu, zdv, zdt, zdq, zdql, zdqi, paprs, text,abortphy,flag_inhib_tend)
-  END IF
-
-
-  RETURN
-END SUBROUTINE add_pbl_tend
Index: LMDZ5/branches/testing/libf/phylmd/add_phys_tend.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/add_phys_tend.F90	(revision 2787)
+++ 	(revision )
@@ -1,279 +1,0 @@
-!
-! $Id$
-!
-SUBROUTINE add_phys_tend (zdu,zdv,zdt,zdq,zdql,zdqi,paprs,text,abortphy,flag_inhib_tend)
-!======================================================================
-! Ajoute les tendances des variables physiques aux variables 
-! d'etat de la dynamique t_seri, q_seri ...
-! On en profite pour faire des tests sur les tendances en question.
-!======================================================================
-
-
-!======================================================================
-! Declarations
-!======================================================================
-
-USE dimphy, ONLY: klon, klev
-USE phys_local_var_mod, ONLY: u_seri, v_seri, ql_seri, qs_seri, q_seri, &
-                              t_seri
-USE phys_state_var_mod, ONLY: ftsol
-USE geometry_mod, ONLY: longitude_deg, latitude_deg
-USE print_control_mod, ONLY: prt_level
-USE cmp_seri_mod
-IMPLICIT none
-  include "YOMCST.h"
-  include "clesphys.h"
-
-! Arguments :
-!------------
-REAL zdu(klon,klev),zdv(klon,klev)
-REAL zdt(klon,klev),zdq(klon,klev),zdql(klon,klev),zdqi(klon,klev)
-REAL paprs(klon,klev+1)
-CHARACTER*(*) text
-INTEGER abortphy
-INTEGER flag_inhib_tend ! if flag_inhib_tend != 0, tendencies are not added
-
-! Local :
-!--------
-REAL zt,zq
-REAL zq_int, zqp_int, zq_new
-
-REAL zqp(klev)
-
-INTEGER i, k,j
-INTEGER jadrs(klon*klev), jbad
-INTEGER jqadrs(klon*klev), jqbad
-INTEGER kadrs(klon*klev)
-INTEGER kqadrs(klon*klev)
-
-LOGICAL done(klon)
-
-integer debug_level
-logical, save :: first=.true.
-!$OMP THREADPRIVATE(first)
-INTEGER, SAVE :: itap
-!$OMP THREADPRIVATE(itap)
-!======================================================================
-! Initialisations
-
-     IF (prt_level >= 5) then
-        write (*,*) "In add_phys_tend, after ",text
-        call flush
-     end if
-
-     ! if flag_inhib_tend != 0, tendencies are not added
-     IF (flag_inhib_tend /= 0) then
-        ! If requiered, diagnostics are shown
-        IF (flag_inhib_tend > 0) then
-           ! print some diagnostics if xxx_seri have changed
-           call cmp_seri(flag_inhib_tend,text)
-        END IF
-        RETURN ! on n ajoute pas les tendance
-     END IF
-
-     IF (abortphy==1) RETURN ! on n ajoute pas les tendance si le modele
-                              ! a deja plante.
-
-     debug_level=10
-     if (first) then
-        itap=0
-        first=.false.
-     endif
-! Incrementer le compteur de la physique
-     itap   = itap + 1
-!======================================================================
-! Ajout des tendances sur le vent et l'eau liquide
-!======================================================================
-
-     u_seri(:,:)=u_seri(:,:)+zdu(:,:)
-     v_seri(:,:)=v_seri(:,:)+zdv(:,:)
-     ql_seri(:,:)=ql_seri(:,:)+zdql(:,:)
-     qs_seri(:,:)=qs_seri(:,:)+zdqi(:,:)
-
-!======================================================================
-! On ajoute les tendances de la temperature et de la vapeur d'eau
-! en verifiant que ca ne part pas dans les choux
-!======================================================================
-
-      jbad=0
-      jqbad=0
-      DO k = 1, klev
-         DO i = 1, klon
-            zt=t_seri(i,k)+zdt(i,k)
-            zq=q_seri(i,k)+zdq(i,k)
-            IF ( zt>370. .or. zt<130. .or. abs(zdt(i,k))>50. ) then
-            jbad = jbad + 1
-            jadrs(jbad) = i
-            kadrs(jbad) = k
-            ENDIF
-            IF ( zq<0. .or. zq>0.1 .or. abs(zdq(i,k))>1.e-2 ) then
-            jqbad = jqbad + 1
-            jqadrs(jqbad) = i
-            kqadrs(jqbad) = k
-            ENDIF
-            t_seri(i,k)=zt
-            q_seri(i,k)=zq
-         ENDDO
-      ENDDO
-
-!=====================================================================================
-! Impression et stop en cas de probleme important
-!=====================================================================================
-
-IF (jbad .GT. 0) THEN
-      DO j = 1, jbad
-         i=jadrs(j)
-         if(prt_level.ge.debug_level) THEN
-          print*,'PLANTAGE POUR LE POINT i lon lat =',&
-                 i,longitude_deg(i),latitude_deg(i),text
-          print*,'l    T     dT       Q     dQ    '
-          DO k = 1, klev
-             write(*,'(i3,2f14.4,2e14.2)') k,t_seri(i,k),zdt(i,k),q_seri(i,k),zdq(i,k)
-          ENDDO
-          call print_debug_phys(i,debug_level,text)
-         endif
-      ENDDO
-ENDIF
-!
-!=====================================================================================
-! Impression, warning et correction en cas de probleme moins important
-!=====================================================================================
-IF (jqbad .GT. 0) THEN
-      done(:) = .false.                         !jyg
-      DO j = 1, jqbad
-        i=jqadrs(j)
-          if(prt_level.ge.debug_level) THEN
-           print*,'WARNING  : EAU POUR LE POINT i lon lat =',&
-                  i,longitude_deg(i),latitude_deg(i),text
-           print*,'l    T     dT       Q     dQ    '
-           DO k = 1, klev
-              write(*,'(i3,2f14.4,2e14.2)') k,t_seri(i,k),zdt(i,k),q_seri(i,k),zdq(i,k)
-           ENDDO
-          endif
-          IF (ok_conserv_q) THEN
-!jyg<20140228 Corrections pour conservation de l'eau
-            IF (.NOT.done(i)) THEN                  !jyg
-              DO k = 1, klev
-                zqp(k) = max(q_seri(i,k),1.e-15)
-              ENDDO
-              zq_int  = 0.
-              zqp_int = 0.
-              DO k = 1, klev
-                zq_int  = zq_int  + q_seri(i,k)*(paprs(i,k)-paprs(i,k+1))/Rg
-                zqp_int = zqp_int + zqp(k)     *(paprs(i,k)-paprs(i,k+1))/Rg
-              ENDDO
-              if(prt_level.ge.debug_level) THEN
-               print*,' cas q_seri<1.e-15 i k zq_int zqp_int zq_int/zqp_int :', &
-                                    i, kqadrs(j), zq_int, zqp_int, zq_int/zqp_int
-              endif
-              DO k = 1, klev
-                zq_new = zqp(k)*zq_int/zqp_int
-                zdq(i,k) = zdq(i,k) + zq_new - q_seri(i,k)
-                q_seri(i,k) = zq_new
-              ENDDO
-              done(i) = .true.
-            ENDIF !(.NOT.done(i))
-          ELSE 
-!jyg>
-            DO k = 1, klev
-              zq=q_seri(i,k)+zdq(i,k)
-              if (zq.lt.1.e-15) then
-                 if (q_seri(i,k).lt.1.e-15) then
-                  if(prt_level.ge.debug_level) THEN
-                   print*,' cas q_seri<1.e-15 i k q_seri zq zdq :',i,k,q_seri(i,k),zq,zdq(i,k)
-                  endif
-                  q_seri(i,k)=1.e-15
-                  zdq(i,k)=(1.e-15-q_seri(i,k))
-                 endif
-              endif
-!              zq=q_seri(i,k)+zdq(i,k)
-!              if (zq.lt.1.e-15) then
-!                 zdq(i,k)=(1.e-15-q_seri(i,k))
-!              endif
-            ENDDO
-!jyg<20140228
-          ENDIF   !  (ok_conserv_q)
-!jyg>
-      ENDDO ! j = 1, jqbad
-ENDIF
-!
-
-!IM ajout memes tests pour reverifier les jbad, jqbad beg
-      jbad=0
-      jqbad=0
-      DO k = 1, klev
-         DO i = 1, klon
-            IF ( t_seri(i,k)>370. .or. t_seri(i,k)<130. .or. abs(zdt(i,k))>50. ) then
-            jbad = jbad + 1
-            jadrs(jbad) = i
-!            if(prt_level.ge.debug_level) THEN
-!             print*,'cas2 i k t_seri zdt',i,k,t_seri(i,k),zdt(i,k)
-!            endif
-            ENDIF
-            IF ( q_seri(i,k)<0. .or. q_seri(i,k)>0.1 .or. abs(zdq(i,k))>1.e-2 ) then
-            jqbad = jqbad + 1
-            jqadrs(jqbad) = i
-            kqadrs(jqbad) = k
-!            if(prt_level.ge.debug_level) THEN
-!             print*,'cas2 i k q_seri zdq',i,k,q_seri(i,k),zdq(i,k)
-!            endif
-            ENDIF
-         ENDDO
-      ENDDO
-IF (jbad .GT. 0) THEN
-      DO j = 1, jbad
-         i=jadrs(j)
-         k=kadrs(j)
-         if(prt_level.ge.debug_level) THEN
-          print*,'PLANTAGE2 POUR LE POINT i itap lon lat txt jbad zdt t',&
-                 i,itap,longitude_deg(i),latitude_deg(i),text,jbad, &
-       &        zdt(i,k),t_seri(i,k)-zdt(i,k)
-!!!       if(prt_level.ge.10.and.itap.GE.229.and.i.EQ.3027) THEN 
-          print*,'l    T     dT       Q     dQ    '
-          DO k = 1, klev
-             write(*,'(i3,2f14.4,2e14.2)') k,t_seri(i,k),zdt(i,k),q_seri(i,k),zdq(i,k)
-          ENDDO
-          call print_debug_phys(i,debug_level,text)
-         endif
-      ENDDO
-ENDIF 
-!
-IF (jqbad .GT. 0) THEN
-      DO j = 1, jqbad
-         i=jqadrs(j)
-         k=kqadrs(j)
-         if(prt_level.ge.debug_level) THEN
-          print*,'WARNING  : EAU2 POUR LE POINT i itap lon lat txt jqbad zdq q zdql ql',&
-                 i,itap,longitude_deg(i),latitude_deg(i),text,jqbad,&
-       &        zdq(i,k), q_seri(i,k)-zdq(i,k), zdql(i,k), ql_seri(i,k)-zdql(i,k)
-!!!       if(prt_level.ge.10.and.itap.GE.229.and.i.EQ.3027) THEN 
-          print*,'l    T     dT       Q     dQ    '
-          DO k = 1, klev
-            write(*,'(i3,2f14.4,2e14.2)') k,t_seri(i,k),zdt(i,k),q_seri(i,k),zdq(i,k)
-          ENDDO
-          call print_debug_phys(i,debug_level,text)
-         endif
-      ENDDO
-ENDIF
-
-
-!======================================================================
-! Contrôle des min/max pour arrêt du modèle
-! Si le modele est en mode abortphy, on retire les tendances qu'on
-! vient d'ajouter. Pas exactement parce qu'on ne tient pas compte des
-! seuils.
-!======================================================================
-
-      CALL hgardfou(t_seri,ftsol,text,abortphy) 
-      IF (abortphy==1) THEN
-        Print*,'ERROR ABORT hgardfou dans ',text
-        u_seri(:,:)=u_seri(:,:)-zdu(:,:)
-        v_seri(:,:)=v_seri(:,:)-zdv(:,:)
-        ql_seri(:,:)=ql_seri(:,:)-zdql(:,:)
-        qs_seri(:,:)=qs_seri(:,:)-zdqi(:,:)
-      ENDIF
-
-
-
-  RETURN
-END SUBROUTINE add_phys_tend
Index: LMDZ5/branches/testing/libf/phylmd/add_phys_tend_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/add_phys_tend_mod.F90	(revision 2839)
+++ LMDZ5/branches/testing/libf/phylmd/add_phys_tend_mod.F90	(revision 2839)
@@ -0,0 +1,634 @@
+!
+MODULE add_phys_tend_mod
+
+  IMPLICIT NONE  
+  ! flag to compute diagnostics to check energy conservation. If  fl_ebil==0, no check
+  INTEGER, SAVE ::   fl_ebil
+!$OMP THREADPRIVATE(fl_ebil)
+  ! flag to include modifcations to ensure energy conservation. If  fl_cor_ebil==0, no corrections
+  ! Note that with time, all these modifications should be included by default
+  INTEGER, SAVE ::   fl_cor_ebil
+!$OMP THREADPRIVATE(fl_cor_ebil)
+
+CONTAINS
+
+SUBROUTINE add_pbl_tend(zdu, zdv, zdt, zdq, zdql, zdqi, paprs, text,abortphy,flag_inhib_tend, itap)
+  ! ======================================================================
+  ! Ajoute les tendances de couche limite, soit determinees par la
+  ! parametrisation
+  ! physique, soit forcees,  aux variables d etat de la dynamique t_seri,
+  ! q_seri ...
+  ! ======================================================================
+
+
+  ! ======================================================================
+  ! Declarations
+  ! ======================================================================
+
+  USE dimphy, ONLY: klon, klev
+!  USE dimphy
+  USE phys_local_var_mod
+  USE phys_state_var_mod
+  USE mod_grid_phy_lmdz, ONLY: nbp_lev
+  IMPLICIT NONE
+  REAL,SAVE,ALLOCATABLE :: hthturb_gcssold(:)
+  REAL,SAVE,ALLOCATABLE :: hqturb_gcssold(:)
+!$OMP THREADPRIVATE(hthturb_gcssold,hqturb_gcssold)
+  REAL,SAVE :: dtime_frcg
+  LOGICAL,SAVE :: turb_fcg_gcssold
+  LOGICAL,SAVE :: firstcall=.true.
+!$OMP THREADPRIVATE(firstcall,turb_fcg_gcssold,dtime_frcg)
+  INTEGER abortphy
+!  COMMON /turb_forcing/dtime_frcg, hthturb_gcssold, hqturb_gcssold, &
+!    turb_fcg_gcssold
+
+  ! Arguments :
+  ! ------------
+  REAL zdu(klon, klev), zdv(klon, klev)
+  REAL zdt(klon, klev), zdq(klon, klev), zdql(klon, klev), zdqi(klon, klev)
+  CHARACTER *(*) text
+  REAL paprs(klon,klev+1)
+  INTEGER flag_inhib_tend ! if flag_inhib_tend != 0, tendencies are not added
+  INTEGER itap ! time step number
+
+  ! Local :
+  ! --------
+  REAL zzdt(klon, klev), zzdq(klon, klev)
+  INTEGER i, k
+
+  IF (firstcall) THEN
+    ALLOCATE(hthturb_gcssold(nbp_lev))
+    ALLOCATE(hqturb_gcssold(nbp_lev))
+    firstcall=.false.
+  ENDIF
+
+  IF (turb_fcg_gcssold) THEN
+    DO k = 1, klev
+      DO i = 1, klon
+        zzdt(i, k) = hthturb_gcssold(k)*dtime_frcg
+        zzdq(i, k) = hqturb_gcssold(k)*dtime_frcg
+      END DO
+    END DO
+    PRINT *, ' add_pbl_tend, dtime_frcg ', dtime_frcg
+    PRINT *, ' add_pbl_tend, zzdt ', zzdt
+    PRINT *, ' add_pbl_tend, zzdq ', zzdq
+    CALL add_phys_tend(zdu, zdv, zzdt, zzdq, zdql, zdqi, paprs, text,abortphy,flag_inhib_tend, itap, 0)
+  ELSE
+    CALL add_phys_tend(zdu, zdv, zdt, zdq, zdql, zdqi, paprs, text,abortphy,flag_inhib_tend, itap, 0)
+  END IF
+
+
+  RETURN
+END SUBROUTINE add_pbl_tend
+!
+! $Id: add_phys_tend.F90 2611 2016-08-03 15:41:26Z jyg $
+!
+SUBROUTINE add_phys_tend (zdu,zdv,zdt,zdq,zdql,zdqi,paprs,text, &
+                          abortphy,flag_inhib_tend, itap, diag_mode)
+!======================================================================
+! Ajoute les tendances des variables physiques aux variables 
+! d'etat de la dynamique t_seri, q_seri ...
+! On en profite pour faire des tests sur les tendances en question.
+!======================================================================
+
+
+!======================================================================
+! Declarations
+!======================================================================
+
+USE dimphy, ONLY: klon, klev
+USE phys_state_var_mod, ONLY : dtime
+USE phys_local_var_mod, ONLY: u_seri, v_seri, ql_seri, qs_seri, q_seri, t_seri
+USE phys_state_var_mod, ONLY: ftsol
+USE geometry_mod, ONLY: longitude_deg, latitude_deg
+USE print_control_mod, ONLY: prt_level
+USE cmp_seri_mod
+USE phys_output_var_mod, ONLY : d_qw_col, d_ql_col, d_qs_col, d_qt_col, d_ek_col, d_h_dair_col &
+  &           , d_h_qw_col, d_h_ql_col, d_h_qs_col, d_h_col
+IMPLICIT none
+  include "YOMCST.h"
+  include "clesphys.h"
+
+! Arguments :
+!------------
+REAL, DIMENSION(klon,klev),     INTENT(IN)    :: zdu, zdv
+REAL, DIMENSION(klon,klev),     INTENT(IN)    :: zdt, zdql, zdqi
+REAL, DIMENSION(klon,klev+1),   INTENT(IN)    :: paprs
+CHARACTER*(*),                  INTENT(IN)    :: text
+INTEGER,                        INTENT(IN)    :: abortphy
+INTEGER,                        INTENT(IN)    :: flag_inhib_tend ! if not 0, tendencies are not added
+INTEGER,                        INTENT(IN)    :: itap            ! time step number
+INTEGER,                        INTENT(IN)    :: diag_mode       ! 0 -> normal effective mode
+                                                                 ! 1 -> only conservation stats are computed
+!
+REAL, DIMENSION(klon,klev),     INTENT(INOUT) :: zdq
+
+! Local :
+!--------
+REAL zt,zq
+REAL zq_int, zqp_int, zq_new
+
+REAL zqp(klev)
+
+! Save variables, used in diagnostic mode (diag_mode=1).
+REAL, DIMENSION(klon,klev)   :: sav_u_seri, sav_v_seri
+REAL, DIMENSION(klon,klev)   :: sav_ql_seri, sav_qs_seri, sav_q_seri
+REAL, DIMENSION(klon,klev)   :: sav_t_seri
+REAL, DIMENSION(klon,klev)   :: sav_zdq
+!
+INTEGER i, k,j, n
+INTEGER jadrs(klon*klev), jbad
+INTEGER jqadrs(klon*klev), jqbad
+INTEGER kadrs(klon*klev)
+INTEGER kqadrs(klon*klev)
+
+LOGICAL done(klon)
+
+integer debug_level
+logical, save :: first=.true.
+!$OMP THREADPRIVATE(first)
+!
+!======================================================================
+! Variables for energy conservation tests
+!======================================================================
+!
+
+! zh_col-------  total enthalpy of vertical air column
+! (air with watter vapour, liquid and solid) (J/m2)
+! zh_dair_col--- total enthalpy of dry air (J/m2)
+! zh_qw_col----  total enthalpy of watter vapour (J/m2)
+! zh_ql_col----  total enthalpy of liquid watter (J/m2)
+! zh_qs_col----  total enthalpy of solid watter  (J/m2)
+! zqw_col------  total mass of watter vapour (kg/m2)
+! zql_col------  total mass of liquid watter (kg/m2)
+! zqs_col------  total mass of solid watter (kg/m2)
+! zek_col------  total kinetic energy (kg/m2)
+!
+REAL zairm(klon, klev) ! layer air mass (kg/m2)
+REAL zqw_col(klon,2)
+REAL zql_col(klon,2)
+REAL zqs_col(klon,2)
+REAL zek_col(klon,2)
+REAL zh_dair_col(klon,2)
+REAL zh_qw_col(klon,2), zh_ql_col(klon,2), zh_qs_col(klon,2)
+REAL zh_col(klon,2)
+
+REAL zcpvap, zcwat, zcice
+
+!======================================================================
+! Initialisations
+
+     IF (prt_level >= 5) then
+        write (*,*) "In add_phys_tend, after ",text
+        call flush
+     end if
+
+     ! if flag_inhib_tend != 0, tendencies are not added
+     IF (flag_inhib_tend /= 0) then
+        ! If requiered, diagnostics are shown
+        IF (flag_inhib_tend > 0) then
+           ! print some diagnostics if xxx_seri have changed
+           call cmp_seri(flag_inhib_tend,text)
+        END IF
+        RETURN ! on n ajoute pas les tendance
+     END IF
+
+     IF (abortphy==1) RETURN ! on n ajoute pas les tendance si le modele
+                              ! a deja plante.
+
+     debug_level=10
+     if (first) then
+        print *,"TestJLD rcpv, rcw, rcs",rcpv, rcw, rcs
+        first=.false.
+     endif
+!
+!  print *,'add_phys_tend: paprs ',paprs
+! When in diagnostic mode, save initial values of out variables
+  IF (diag_mode == 1) THEN
+    sav_u_seri(:,:)  = u_seri(:,:)
+    sav_v_seri(:,:)  = v_seri(:,:)
+    sav_ql_seri(:,:) = ql_seri(:,:)
+    sav_qs_seri(:,:) = qs_seri(:,:)
+    sav_q_seri(:,:)  = q_seri(:,:)
+    sav_t_seri(:,:)  = t_seri(:,:)
+    sav_zdq(:,:)     = zdq(:,:)   
+  ENDIF ! (diag_mode == 1)
+!======================================================================
+! Diagnostics for energy conservation tests
+!======================================================================
+  DO k = 1, klev
+    ! layer air mass
+    zairm(:, k) = (paprs(:,k)-paprs(:,k+1))/rg
+  END DO
+
+  if (fl_ebil .GT. 0) then
+  ! Reset variables
+    zqw_col(:,:) = 0.
+    zql_col(:,:) = 0.
+    zqs_col(:,:) = 0.
+    zek_col(:,:) = 0.
+    zh_dair_col(:,:) = 0.
+    zh_qw_col(:,:) = 0.
+    zh_ql_col(:,:) = 0.
+    zh_qs_col(:,:) = 0.
+
+    zcpvap = rcpv
+    zcwat = rcw
+    zcice = rcs
+!JLD    write (*,*) "rcpd, zcpvap, zcwat, zcice ",rcpd, zcpvap, zcwat, zcice
+  
+    ! ------------------------------------------------
+    ! Compute vertical sum for each atmospheric column
+    ! ------------------------------------------------
+    n=1   ! begining of time step
+    DO k = 1, klev
+      DO i = 1, klon
+        ! Watter mass
+        zqw_col(i,n) = zqw_col(i,n) + q_seri(i, k)*zairm(i, k)
+        zql_col(i,n) = zql_col(i,n) + ql_seri(i, k)*zairm(i, k)
+        zqs_col(i,n) = zqs_col(i,n) + qs_seri(i, k)*zairm(i, k)
+        ! Kinetic Energy
+        zek_col(i,n) = zek_col(i,n) + 0.5*(u_seri(i,k)**2+v_seri(i,k)**2)*zairm(i, k)
+        ! Air enthalpy : dry air, water vapour, liquid, solid
+        zh_dair_col(i,n) = zh_dair_col(i,n) + rcpd*(1.-q_seri(i,k)-ql_seri(i,k)-qs_seri(i,k))* &
+          zairm(i, k)*t_seri(i, k)
+        zh_qw_col(i,n) = zh_qw_col(i,n) +  zcpvap*t_seri(i, k)         *q_seri(i, k)*zairm(i, k)    !jyg
+        zh_ql_col(i,n) = zh_ql_col(i,n) + (zcpvap*t_seri(i, k) - rlvtt)*ql_seri(i, k)*zairm(i, k)   !jyg
+        zh_qs_col(i,n) = zh_qs_col(i,n) + (zcpvap*t_seri(i, k) - rlstt)*qs_seri(i, k)*zairm(i, k)   !jyg
+      END DO
+    END DO
+    ! compute total air enthalpy
+    zh_col(:,n) = zh_dair_col(:,n) + zh_qw_col(:,n) + zh_ql_col(:,n) + zh_qs_col(:,n)
+
+  end if ! end if (fl_ebil .GT. 0)
+
+!======================================================================
+! Ajout des tendances sur le vent et l'eau liquide
+!======================================================================
+
+     u_seri(:,:)=u_seri(:,:)+zdu(:,:)
+     v_seri(:,:)=v_seri(:,:)+zdv(:,:)
+     ql_seri(:,:)=ql_seri(:,:)+zdql(:,:)
+     qs_seri(:,:)=qs_seri(:,:)+zdqi(:,:)
+
+!======================================================================
+! On ajoute les tendances de la temperature et de la vapeur d'eau
+! en verifiant que ca ne part pas dans les choux
+!======================================================================
+
+      jbad=0
+      jqbad=0
+      DO k = 1, klev
+         DO i = 1, klon
+            zt=t_seri(i,k)+zdt(i,k)
+            zq=q_seri(i,k)+zdq(i,k)
+            IF ( zt>370. .or. zt<130. .or. abs(zdt(i,k))>50. ) then
+            jbad = jbad + 1
+            jadrs(jbad) = i
+            kadrs(jbad) = k
+            ENDIF
+            IF ( zq<0. .or. zq>0.1 .or. abs(zdq(i,k))>1.e-2 ) then
+            jqbad = jqbad + 1
+            jqadrs(jqbad) = i
+            kqadrs(jqbad) = k
+            ENDIF
+            t_seri(i,k)=zt
+            q_seri(i,k)=zq
+         ENDDO
+      ENDDO
+
+!=====================================================================================
+! Impression et stop en cas de probleme important
+!=====================================================================================
+
+IF (jbad .GT. 0) THEN
+      DO j = 1, jbad
+         i=jadrs(j)
+         if(prt_level.ge.debug_level) THEN
+          print*,'PLANTAGE POUR LE POINT i lon lat =',&
+                 i,longitude_deg(i),latitude_deg(i),text
+          print*,'l    T     dT       Q     dQ    '
+          DO k = 1, klev
+             write(*,'(i3,2f14.4,2e14.2)') k,t_seri(i,k),zdt(i,k),q_seri(i,k),zdq(i,k)
+          ENDDO
+          call print_debug_phys(i,debug_level,text)
+         endif
+      ENDDO
+ENDIF
+!
+!=====================================================================================
+! Impression, warning et correction en cas de probleme moins important
+!=====================================================================================
+IF (jqbad .GT. 0) THEN
+      done(:) = .false.                         !jyg
+      DO j = 1, jqbad
+        i=jqadrs(j)
+          if(prt_level.ge.debug_level) THEN
+           print*,'WARNING  : EAU POUR LE POINT i lon lat =',&
+                  i,longitude_deg(i),latitude_deg(i),text
+           print*,'l    T     dT       Q     dQ    '
+           DO k = 1, klev
+              write(*,'(i3,2f14.4,2e14.2)') k,t_seri(i,k),zdt(i,k),q_seri(i,k),zdq(i,k)
+           ENDDO
+          endif
+          IF (ok_conserv_q) THEN
+!jyg<20140228 Corrections pour conservation de l'eau
+            IF (.NOT.done(i)) THEN                  !jyg
+              DO k = 1, klev
+                zqp(k) = max(q_seri(i,k),1.e-15)
+              ENDDO
+              zq_int  = 0.
+              zqp_int = 0.
+              DO k = 1, klev
+                zq_int  = zq_int  + q_seri(i,k)*(paprs(i,k)-paprs(i,k+1))/Rg
+                zqp_int = zqp_int + zqp(k)     *(paprs(i,k)-paprs(i,k+1))/Rg
+              ENDDO
+              if(prt_level.ge.debug_level) THEN
+               print*,' cas q_seri<1.e-15 i k zq_int zqp_int zq_int/zqp_int :', &
+                                    i, kqadrs(j), zq_int, zqp_int, zq_int/zqp_int
+              endif
+              DO k = 1, klev
+                zq_new = zqp(k)*zq_int/zqp_int
+                zdq(i,k) = zdq(i,k) + zq_new - q_seri(i,k)
+                q_seri(i,k) = zq_new
+              ENDDO
+              done(i) = .true.
+            ENDIF !(.NOT.done(i))
+          ELSE 
+!jyg>
+            DO k = 1, klev
+              zq=q_seri(i,k)+zdq(i,k)
+              if (zq.lt.1.e-15) then
+                 if (q_seri(i,k).lt.1.e-15) then
+                  if(prt_level.ge.debug_level) THEN
+                   print*,' cas q_seri<1.e-15 i k q_seri zq zdq :',i,k,q_seri(i,k),zq,zdq(i,k)
+                  endif
+                  q_seri(i,k)=1.e-15
+                  zdq(i,k)=(1.e-15-q_seri(i,k))
+                 endif
+              endif
+!              zq=q_seri(i,k)+zdq(i,k)
+!              if (zq.lt.1.e-15) then
+!                 zdq(i,k)=(1.e-15-q_seri(i,k))
+!              endif
+            ENDDO
+!jyg<20140228
+          ENDIF   !  (ok_conserv_q)
+!jyg>
+      ENDDO ! j = 1, jqbad
+ENDIF
+!
+
+!IM ajout memes tests pour reverifier les jbad, jqbad beg
+      jbad=0
+      jqbad=0
+      DO k = 1, klev
+         DO i = 1, klon
+            IF ( t_seri(i,k)>370. .or. t_seri(i,k)<130. .or. abs(zdt(i,k))>50. ) then
+            jbad = jbad + 1
+            jadrs(jbad) = i
+!            if(prt_level.ge.debug_level) THEN
+!             print*,'cas2 i k t_seri zdt',i,k,t_seri(i,k),zdt(i,k)
+!            endif
+            ENDIF
+            IF ( q_seri(i,k)<0. .or. q_seri(i,k)>0.1 .or. abs(zdq(i,k))>1.e-2 ) then
+            jqbad = jqbad + 1
+            jqadrs(jqbad) = i
+            kqadrs(jqbad) = k
+!            if(prt_level.ge.debug_level) THEN
+!             print*,'cas2 i k q_seri zdq',i,k,q_seri(i,k),zdq(i,k)
+!            endif
+            ENDIF
+         ENDDO
+      ENDDO
+IF (jbad .GT. 0) THEN
+      DO j = 1, jbad
+         i=jadrs(j)
+         k=kadrs(j)
+         if(prt_level.ge.debug_level) THEN
+          print*,'PLANTAGE2 POUR LE POINT i itap lon lat txt jbad zdt t',&
+                 i,itap,longitude_deg(i),latitude_deg(i),text,jbad, &
+       &        zdt(i,k),t_seri(i,k)-zdt(i,k)
+!!!       if(prt_level.ge.10.and.itap.GE.229.and.i.EQ.3027) THEN 
+          print*,'l    T     dT       Q     dQ    '
+          DO k = 1, klev
+             write(*,'(i3,2f14.4,2e14.2)') k,t_seri(i,k),zdt(i,k),q_seri(i,k),zdq(i,k)
+          ENDDO
+          call print_debug_phys(i,debug_level,text)
+         endif
+      ENDDO
+ENDIF 
+!
+IF (jqbad .GT. 0) THEN
+      DO j = 1, jqbad
+         i=jqadrs(j)
+         k=kqadrs(j)
+         if(prt_level.ge.debug_level) THEN
+          print*,'WARNING  : EAU2 POUR LE POINT i itap lon lat txt jqbad zdq q zdql ql',&
+                 i,itap,longitude_deg(i),latitude_deg(i),text,jqbad,&
+       &        zdq(i,k), q_seri(i,k)-zdq(i,k), zdql(i,k), ql_seri(i,k)-zdql(i,k)
+!!!       if(prt_level.ge.10.and.itap.GE.229.and.i.EQ.3027) THEN 
+          print*,'l    T     dT       Q     dQ    '
+          DO k = 1, klev
+            write(*,'(i3,2f14.4,2e14.2)') k,t_seri(i,k),zdt(i,k),q_seri(i,k),zdq(i,k)
+          ENDDO
+          call print_debug_phys(i,debug_level,text)
+         endif
+      ENDDO
+ENDIF
+
+!======================================================================
+! Contrôle des min/max pour arrêt du modèle
+! Si le modele est en mode abortphy, on retire les tendances qu'on
+! vient d'ajouter. Pas exactement parce qu'on ne tient pas compte des
+! seuils.
+!======================================================================
+
+      CALL hgardfou(t_seri,ftsol,text,abortphy) 
+      IF (abortphy==1) THEN
+        Print*,'ERROR ABORT hgardfou dans ',text
+! JLD pourquoi on ne modifie pas de meme t_seri et q_seri ?
+        u_seri(:,:)=u_seri(:,:)-zdu(:,:)
+        v_seri(:,:)=v_seri(:,:)-zdv(:,:)
+        ql_seri(:,:)=ql_seri(:,:)-zdql(:,:)
+        qs_seri(:,:)=qs_seri(:,:)-zdqi(:,:)
+      ENDIF
+
+!======================================================================
+! Diagnostics for energy conservation tests
+!======================================================================
+
+  if (fl_ebil .GT. 0) then
+  
+    ! ------------------------------------------------
+    ! Compute vertical sum for each atmospheric column
+    ! ------------------------------------------------
+    n=2   ! end of time step
+    DO k = 1, klev
+      DO i = 1, klon
+        ! Watter mass
+        zqw_col(i,n) = zqw_col(i,n) + q_seri(i, k)*zairm(i, k)
+        zql_col(i,n) = zql_col(i,n) + ql_seri(i, k)*zairm(i, k)
+        zqs_col(i,n) = zqs_col(i,n) + qs_seri(i, k)*zairm(i, k)
+        ! Kinetic Energy
+        zek_col(i,n) = zek_col(i,n) + 0.5*(u_seri(i,k)**2+v_seri(i,k)**2)*zairm(i, k)
+        ! Air enthalpy : dry air, water vapour, liquid, solid
+        zh_dair_col(i,n) = zh_dair_col(i,n) + rcpd*(1.-q_seri(i,k)-ql_seri(i,k)-qs_seri(i,k))* &
+          zairm(i, k)*t_seri(i, k)
+        zh_qw_col(i,n) = zh_qw_col(i,n) +  zcpvap*t_seri(i, k)         *q_seri(i, k)*zairm(i, k)     !jyg
+        zh_ql_col(i,n) = zh_ql_col(i,n) + (zcpvap*t_seri(i, k) - rlvtt)*ql_seri(i, k)*zairm(i, k)    !jyg
+        zh_qs_col(i,n) = zh_qs_col(i,n) + (zcpvap*t_seri(i, k) - rlstt)*qs_seri(i, k)*zairm(i, k)    !jyg
+      END DO
+    END DO
+    ! compute total air enthalpy
+    zh_col(:,n) = zh_dair_col(:,n) + zh_qw_col(:,n) + zh_ql_col(:,n) + zh_qs_col(:,n)
+
+    ! ------------------------------------------------
+    ! Compute the changes by unit of time
+    ! ------------------------------------------------
+
+    d_qw_col(:) = (zqw_col(:,2)-zqw_col(:,1))/dtime
+    d_ql_col(:) = (zql_col(:,2)-zql_col(:,1))/dtime
+    d_qs_col(:) = (zqs_col(:,2)-zqs_col(:,1))/dtime
+    d_qt_col(:) = d_qw_col(:) + d_ql_col(:) + d_qs_col(:)
+
+    d_ek_col(:) = (zek_col(:,2)-zek_col(:,1))/dtime
+
+    d_h_dair_col(:) = (zh_dair_col(:,2)-zh_dair_col(:,1))/dtime
+    d_h_qw_col(:) = (zh_qw_col(:,2)-zh_qw_col(:,1))/dtime
+    d_h_ql_col(:) = (zh_ql_col(:,2)-zh_ql_col(:,1))/dtime
+    d_h_qs_col(:) = (zh_qs_col(:,2)-zh_qs_col(:,1))/dtime
+
+    d_h_col = (zh_col(:,2)-zh_col(:,1))/dtime 
+
+  end if ! end if (fl_ebil .GT. 0)
+!
+! When in diagnostic mode, restore "out" variables to initial values.
+  IF (diag_mode == 1) THEN
+    u_seri(:,:)  = sav_u_seri(:,:)
+    v_seri(:,:)  = sav_v_seri(:,:)
+    ql_seri(:,:) = sav_ql_seri(:,:)
+    qs_seri(:,:) = sav_qs_seri(:,:)
+    q_seri(:,:)  = sav_q_seri(:,:)
+    t_seri(:,:)  = sav_t_seri(:,:)
+    zdq(:,:)     = sav_zdq(:,:)   
+  ENDIF ! (mode == 1)
+
+  RETURN
+END SUBROUTINE add_phys_tend
+
+SUBROUTINE prt_enerbil (text, itap)
+!======================================================================
+! Print enenrgy budget diagnotics for the 1D case
+!======================================================================
+
+!======================================================================
+! Declarations
+!======================================================================
+
+USE dimphy, ONLY: klon, klev
+USE phys_state_var_mod, ONLY : dtime
+USE phys_state_var_mod, ONLY : topsw, toplw, solsw, sollw, rain_con, snow_con
+USE geometry_mod, ONLY: longitude_deg, latitude_deg
+USE print_control_mod, ONLY: prt_level
+USE cmp_seri_mod
+USE phys_output_var_mod, ONLY : d_qw_col, d_ql_col, d_qs_col, d_qt_col, d_ek_col, d_h_dair_col &
+  &           , d_h_qw_col, d_h_ql_col, d_h_qs_col, d_h_col
+USE phys_local_var_mod, ONLY: evap, sens
+USE phys_local_var_mod, ONLY: u_seri, v_seri, ql_seri, qs_seri, q_seri, t_seri &
+   &  , rain_lsc, snow_lsc
+USE climb_hq_mod, ONLY : d_h_col_vdf, f_h_bnd
+IMPLICIT none
+include "YOMCST.h"
+
+! Arguments :
+!------------
+CHARACTER*(*) text ! text specifing the involved parametrization 
+integer itap        ! time step number
+! local variables
+! ---------------
+real bilq_seuil,  bilh_seuil ! thresold on error in Q and H budget
+real bilq_error,  bilh_error ! erros in Q and H budget
+real bilq_bnd,  bilh_bnd     ! Q and H budget due to exchange with boundaries
+integer bilq_ok,  bilh_ok
+CHARACTER*(12) status
+
+bilq_seuil = 1.E-10
+bilh_seuil = 1.E-1
+bilq_ok=0
+bilh_ok=0
+
+!!print *,'prt_level:',prt_level,' fl_ebil:',fl_ebil,' fl_cor_ebil:',fl_cor_ebil
+if ( (fl_ebil .GT. 0) .and. (klon .EQ. 1)) then
+
+  bilq_bnd = 0.
+  bilh_bnd = 0.
+
+  param: SELECT CASE (text)
+  CASE("vdf") param
+      bilq_bnd = evap(1)
+      bilh_bnd = sens(1)+(rcpv-rcpd)*evap(1)*t_seri(1,1)
+  CASE("lsc") param
+      bilq_bnd = - rain_lsc(1) - snow_lsc(1)
+      bilh_bnd = (-(rcw-rcpd)*t_seri(1,1) + rlvtt) * rain_lsc(1) &
+    &         + (-(rcs-rcpd)*t_seri(1,1) + rlstt) * snow_lsc(1)
+  CASE("convection") param
+      bilq_bnd = - rain_con(1) - snow_con(1)
+      bilh_bnd = (-(rcw-rcpd)*t_seri(1,1) + rlvtt) * rain_con(1) &
+    &         + (-(rcs-rcpd)*t_seri(1,1) + rlstt) * snow_con(1)
+  CASE("SW") param
+      bilh_bnd = topsw(1) - solsw(1)
+  CASE("LW") param
+      bilh_bnd = -(toplw(1) + sollw(1))
+  CASE DEFAULT param
+      bilq_bnd = 0.
+      bilh_bnd = 0.
+  END SELECT param
+
+  bilq_error = d_qt_col(1) - bilq_bnd
+  bilh_error = d_h_col(1) - bilh_bnd
+! are the errors too large?
+  if ( abs(bilq_error) .gt. bilq_seuil) bilq_ok=1
+  if ( abs(bilh_error) .gt. bilh_seuil) bilh_ok=1
+!
+! Print diagnostics
+! =================
+  if ( (bilq_ok .eq. 0).and.(bilh_ok .eq. 0) ) then
+    status="enerbil-OK"
+  else
+    status="enerbil-PB"
+  end if
+
+  if ( prt_level .GE. 3) then
+    write(*,9010) text,status," itap:",itap,"enerbilERROR: Q", bilq_error,"  H", bilh_error
+9010  format (1x,A8,2x,A12,A6,I4,A18,E15.6,A5,E15.6)
+  end if
+  if ( prt_level .GE. 3) then
+    write(*,9000) text,"enerbil: Q,H,KE budget", d_qt_col(1), d_h_col(1),d_ek_col(1)
+  end if
+  if ( prt_level .GE. 5) then
+    write(*,9000) text,"enerbil at boundaries: Q, H",bilq_bnd, bilh_bnd
+    write(*,9000) text,"enerbil: water budget",d_qt_col(1),d_qw_col(1),d_ql_col(1),d_qs_col(1)
+    write(*,9000) text,"enerbil: enthalpy budget",d_h_col(1),d_h_dair_col(1),d_h_qw_col(1),d_h_ql_col(1),d_h_qs_col(1)
+  end if
+
+  specific_diag: SELECT CASE (text)
+  CASE("vdf") specific_diag
+    if ( prt_level .GE. 5) then
+      write(*,9000) text,"enerbil: d_h, bilh, sens,t_seri", d_h_col(1), bilh_bnd, sens(1), t_seri(1,1)
+      write(*,9000) text,"enerbil: d_h_col_vdf, f_h, diff",d_h_col_vdf, f_h_bnd, bilh_bnd-sens(1)
+    end if
+  CASE("lsc") specific_diag
+    if ( prt_level .GE. 5) then
+      write(*,9000) text,"enerbil: rain, bil_lat, bil_sens", rain_lsc(1), rlvtt * rain_lsc(1), -(rcw-rcpd)*t_seri(1,1) * rain_lsc(1)
+      write(*,9000) text,"enerbil: snow, bil_lat, bil_sens", snow_lsc(1), rlstt * snow_lsc(1), -(rcs-rcpd)*t_seri(1,1) * snow_lsc(1)
+    end if
+  END SELECT specific_diag
+
+9000 format (1x,A8,2x,A30,10E15.6)
+
+end if ! end if (fl_ebil .GT. 0)
+
+END SUBROUTINE prt_enerbil
+
+END MODULE add_phys_tend_mod
Index: LMDZ5/branches/testing/libf/phylmd/aero_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/aero_mod.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/aero_mod.F90	(revision 2839)
@@ -46,5 +46,5 @@
 ! 2/ Total number of aerosols for which an aerosol mass is provided
 
-  INTEGER, PARAMETER :: naero_spc = 10
+  INTEGER, PARAMETER :: naero_spc = 13
 
 ! Corresponding names for the aerosols
@@ -59,5 +59,8 @@
        "CIDUSTM", &
        "AIBCM  ", &
-       "AIPOMM " /)
+       "AIPOMM " ,&
+       "ASNO3M ", & 
+       "CSNO3M ", &
+       "CINO3M " /)
 
 ! 3/ Number of aerosol groups
Index: LMDZ5/branches/testing/libf/phylmd/calcul_divers.h
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/calcul_divers.h	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/calcul_divers.h	(revision 2839)
@@ -5,10 +5,4 @@
       IF(itap.EQ.1) THEN
          itapm1=0
-!        surface terre
-         DO i=1, klon
-            IF(pctsrf(i,is_ter).GT.0.) THEN
-               paire_ter(i)=cell_area(i)*pctsrf(i,is_ter)
-            ENDIF 
-         ENDDO
       ENDIF
 
Index: LMDZ5/branches/testing/libf/phylmd/clesphys.h
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/clesphys.h	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/clesphys.h	(revision 2839)
@@ -87,4 +87,6 @@
        LOGICAL :: ok_qch4
        LOGICAL :: ok_conserv_q
+       LOGICAL :: adjust_tropopause
+       LOGICAL :: ok_daily_climoz
 
        COMMON/clesphys/                                                 &
@@ -130,5 +132,6 @@
      &     , iflag_rrtm, ok_strato,ok_hines, ok_qch4                    &
      &     , iflag_ice_thermo, ok_gwd_rando, NSW, iflag_albedo          &
-     &     , ok_chlorophyll,ok_conserv_q, ok_all_xml
+     &     , ok_chlorophyll,ok_conserv_q, adjust_tropopause             &
+     &     , ok_daily_climoz, ok_all_xml
      
        save /clesphys/
Index: LMDZ5/branches/testing/libf/phylmd/climb_hq_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/climb_hq_mod.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/climb_hq_mod.F90	(revision 2839)
@@ -9,5 +9,5 @@
   SAVE 
   PRIVATE
-  PUBLIC :: climb_hq_down, climb_hq_up
+  PUBLIC :: climb_hq_down, climb_hq_up, d_h_col_vdf, f_h_bnd
 
   REAL, DIMENSION(:,:), ALLOCATABLE :: gamaq, gamah
@@ -23,4 +23,10 @@
   REAL, DIMENSION(:,:), ALLOCATABLE :: Kcoefhq
   !$OMP THREADPRIVATE(Kcoefhq)
+  REAL, SAVE, DIMENSION(:,:), ALLOCATABLE :: h_old ! for diagnostics, h before solving diffusion
+  !$OMP THREADPRIVATE(h_old)
+  REAL, SAVE, DIMENSION(:), ALLOCATABLE :: d_h_col_vdf ! for diagnostics, vertical integral of enthalpy change
+  !$OMP THREADPRIVATE(d_h_col_vdf)
+  REAL, SAVE, DIMENSION(:), ALLOCATABLE :: f_h_bnd ! for diagnostics, enthalpy flux at surface
+  !$OMP THREADPRIVATE(f_h_bnd)
 
 CONTAINS
@@ -71,9 +77,9 @@
     LOGICAL, SAVE                            :: first=.TRUE.
     !$OMP THREADPRIVATE(first)
-    REAL, DIMENSION(klon,klev)               :: local_H
+! JLD now renamed h_old and declared in module
+!    REAL, DIMENSION(klon,klev)               :: local_H
     REAL, DIMENSION(klon)                    :: psref 
     REAL                                     :: delz, pkh
     INTEGER                                  :: k, i, ierr
-
 ! Include
 !****************************************************************************************
@@ -113,4 +119,13 @@
        ALLOCATE(gamah(1:klon,2:klev), STAT=ierr)
        IF ( ierr /= 0 ) PRINT*,' pb in allloc gamah, ierr=', ierr
+       
+       ALLOCATE(h_old(klon,klev), STAT=ierr)
+       IF ( ierr /= 0 )  PRINT*,' pb in allloc h_old, ierr=', ierr
+       
+       ALLOCATE(d_h_col_vdf(klon), STAT=ierr)
+       IF ( ierr /= 0 )  PRINT*,' pb in allloc d_h_col_vdf, ierr=', ierr
+       
+       ALLOCATE(f_h_bnd(klon), STAT=ierr)
+       IF ( ierr /= 0 )  PRINT*,' pb in allloc f_h_bnd, ierr=', ierr
     END IF
 
@@ -177,15 +192,15 @@
 !
 !****************************************************************************************
-    local_H(:,:) = 0.0
+    h_old(:,:) = 0.0
 
     DO k=1,klev
        DO i = 1, knon
           ! convertie la temperature en entalpie potentielle
-          local_H(i,k) = RCPD * temp(i,k) * &
+          h_old(i,k) = RCPD * temp(i,k) * &
                (psref(i)/pplay(i,k))**RKAPPA
        ENDDO
     ENDDO
 
-    CALL calc_coef(knon, Kcoefhq(:,:), gamah(:,:), delp(:,:), local_H(:,:), &
+    CALL calc_coef(knon, Kcoefhq(:,:), gamah(:,:), delp(:,:), h_old(:,:), &
          Ccoef_H(:,:), Dcoef_H(:,:), Acoef_H, Bcoef_H)
  
@@ -349,4 +364,5 @@
 ! 1) 
 ! Definition of some variables
+    REAL, DIMENSION(klon,klev)               :: d_h, zairm
 !
 !****************************************************************************************
@@ -355,4 +371,6 @@
     d_q(:,:)    = 0.0
     d_t(:,:)    = 0.0
+    d_h(:,:)    = 0.0
+    f_h_bnd(:)= 0.0
 
     psref(1:knon) = paprs(1:knon,1)  
@@ -393,5 +411,5 @@
     q_new(1:knon,1) = Acoef_Q(1:knon) + Bcoef_Q(1:knon)*flx_q1(1:knon)*dtime
     h_new(1:knon,1) = Acoef_H(1:knon) + Bcoef_H(1:knon)*flx_h1(1:knon)*dtime
-    
+    f_h_bnd(1:knon) = flx_h1(1:knon)
 !- All the other layers 
     DO k = 2, klev
@@ -427,10 +445,15 @@
 !
 !****************************************************************************************
-
+    d_h_col_vdf(:) = 0.0
     DO k = 1, klev
        DO i = 1, knon
           d_t(i,k) = h_new(i,k)/(psref(i)/pplay(i,k))**RKAPPA/RCPD - t_old(i,k)
           d_q(i,k) = q_new(i,k) - q_old(i,k)
-       END DO
+          d_h(i,k) = h_new(i,k) - h_old(i,k)
+!JLD          d_t(i,k) = d_h(i,k)/(psref(i)/pplay(i,k))**RKAPPA/RCPD    !correction a venir
+    ! layer air mass
+          zairm(i, k) = (paprs(i,k)-paprs(i,k+1))/rg
+          d_h_col_vdf(i) = d_h_col_vdf(i) + d_h(i,k)*zairm(i,k)
+        END DO
     END DO
 
@@ -448,4 +471,6 @@
        DEALLOCATE(Kcoefhq,stat=ierr)
        IF ( ierr /= 0 )  PRINT*,' pb in dealllocate Kcoefhq, ierr=', ierr
+       DEALLOCATE(h_old, d_h_col_vdf, f_h_bnd, stat=ierr)
+       IF ( ierr /= 0 )  PRINT*,' pb in dealllocate h_old, d_h_col_vdf, f_h_bnd, ierr=', ierr
     END IF
   END SUBROUTINE climb_hq_up
Index: LMDZ5/branches/testing/libf/phylmd/concvl.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/concvl.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/concvl.F90	(revision 2839)
@@ -5,5 +5,6 @@
                   d_t, d_q, d_u, d_v, d_tra, &
                   rain, snow, kbas, ktop, sigd, &
-                  cbmf, plcl, plfc, wbeff, upwd, dnwd, dnwdbis, &
+                  cbmf, plcl, plfc, wbeff, convoccur, &
+                  upwd, dnwd, dnwdbis, &
                   Ma, mip, Vprecip, &
                   cape, cin, tvp, Tconv, iflag, &
@@ -157,4 +158,5 @@
   REAL qs(klon, klev), qs_wake(klon, klev)
   REAL cbmf(klon), plcl(klon), plfc(klon), wbeff(klon)
+  REAL convoccur(klon)
 !LF          SAVE cbmf
 !IM/JYG      REAL, SAVE, ALLOCATABLE :: cbmf(:)
@@ -228,4 +230,7 @@
     ALLOCATE (t1(klon,klev))
     ALLOCATE (q1(klon,klev))
+!
+    convoccur(:) = 0.
+!
     itap = 0
     igout = klon/2 + 1/klon
@@ -450,4 +455,15 @@
   END DO
 
+  IF (iflag_con==3) THEN
+    DO i = 1,klon
+      IF (wbeff(i) > 100. .OR. wbeff(i) == 0 .OR. iflag(i) > 3) THEN
+        wbeff(i) = 0.
+        convoccur(i) = 0.  
+      ELSE
+        convoccur(i) = 1.
+      ENDIF
+    ENDDO
+  ENDIF
+
   IF (iflag_con==30) THEN
     DO itra = 1, ntra
Index: LMDZ5/branches/testing/libf/phylmd/conf_phys_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/conf_phys_m.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/conf_phys_m.F90	(revision 2839)
@@ -222,4 +222,6 @@
     LOGICAL,SAVE  :: carbon_cycle_tr_omp
     LOGICAL,SAVE  :: carbon_cycle_cpl_omp
+    LOGICAL,SAVE  :: adjust_tropopause_omp
+    LOGICAL,SAVE  :: ok_daily_climoz_omp
 
     INTEGER, INTENT(OUT):: read_climoz ! read ozone climatology, OpenMP shared
@@ -2035,4 +2037,24 @@
     !Config Help = ... 
     !
+    !
+    adjust_tropopause = .FALSE.
+    CALL getin('adjust_tropopause', adjust_tropopause_omp)
+    !
+    !Config Key  = adjust_tropopause
+    !Config Desc = Adjust the ozone field from the climoz file by stretching its
+    !              tropopause so that it matches the one of LMDZ.
+    !Config Def  = .FALSE.
+    !Config Help = Ensure tropospheric ozone column conservation.
+    !
+    !
+    ok_daily_climoz = .FALSE.
+    CALL getin('ok_daily_climoz', ok_daily_climoz_omp)
+    !
+    !Config Key  = ok_daily_climoz
+    !Config Desc = Interpolate in time the ozone forcings within ce0l.
+    !              .TRUE. if backward compatibility is needed.
+    !Config Def  = .TRUE.
+    !Config Help = .FALSE. ensure much fewer (no calendar dependency)
+    !  and lighter monthly climoz files, inetrpolated in time at gcm run time.
     !
     ecrit_LES_omp = 1./8.
@@ -2291,4 +2313,6 @@
     callstats = callstats_omp
     ecrit_LES = ecrit_LES_omp
+    adjust_tropopause = adjust_tropopause_omp
+    ok_daily_climoz = ok_daily_climoz_omp
     carbon_cycle_tr = carbon_cycle_tr_omp
     carbon_cycle_cpl = carbon_cycle_cpl_omp
@@ -2485,5 +2509,5 @@
     write(lunout,*)' aerosol_couple = ', aerosol_couple
     write(lunout,*)' flag_aerosol = ', flag_aerosol
-    write(lunout,*)' flag_aerosol_strat = ', flag_aerosol_strat
+    write(lunout,*)' flag_aerosol_strat= ', flag_aerosol_strat
     write(lunout,*)' new_aod = ', new_aod
     write(lunout,*)' aer_type = ',aer_type
@@ -2568,4 +2592,6 @@
     write(lunout,*) 'SSO gkwake=',gkwake
     write(lunout,*) 'SSO gklift=',gklift
+    write(lunout,*) 'adjust_tropopause = ', adjust_tropopause
+    write(lunout,*) 'ok_daily_climoz = ',ok_daily_climoz
     write(lunout,*) 'read_climoz = ', read_climoz
     write(lunout,*) 'carbon_cycle_tr = ', carbon_cycle_tr
Index: LMDZ5/branches/testing/libf/phylmd/cosp/cosp_output_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/cosp/cosp_output_mod.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/cosp/cosp_output_mod.F90	(revision 2839)
@@ -20,8 +20,8 @@
       INTEGER, DIMENSION(3), SAVE  :: nhoricosp,nvert,nvertmcosp,nvertcol,nvertbze, &
                                       nvertsratio,nvertisccp,nvertp,nverttemp,nvertmisr, &
-                                      nvertReffIce,nvertReffLiq
+                                      nvertReffIce,nvertReffLiq,nverttau
       REAL, DIMENSION(3), SAVE                :: zoutm_cosp
 !$OMP THREADPRIVATE(nhoricosp, nvert,nvertmcosp,nvertcol,nvertsratio,nvertbze,nvertisccp,nvertp,zoutm_cosp,nverttemp,nvertmisr)
-!$OMP THREADPRIVATE(nvertReffIce,nvertReffLiq)
+!$OMP THREADPRIVATE(nvertReffIce,nvertReffLiq,nverttau)
       REAL, SAVE                   :: zdtimemoy_cosp
 !$OMP THREADPRIVATE(zdtimemoy_cosp) 
@@ -207,6 +207,5 @@
   SUBROUTINE cosp_output_open(Nlevlmdz, Ncolumns, presnivs, dtime, freq_cosp, &
                               ok_mensuelCOSP, ok_journeCOSP, ok_hfCOSP, ok_all_xml,  &
-                              ecrit_mth, ecrit_day, ecrit_hf, use_vgrid, vgrid)
-
+                              ecrit_mth, ecrit_day, ecrit_hf, use_vgrid, vgrid, stlidar)
 
   USE iophy
@@ -229,4 +228,5 @@
   logical                  :: ok_mensuelCOSP, ok_journeCOSP, ok_hfCOSP, use_vgrid, ok_all_xml                    
   type(cosp_vgrid)   :: vgrid   ! Information on vertical grid of stats
+  type(cosp_lidarstats) :: stlidar ! Summary statistics from lidar simulator
 
 !!! Variables locales
@@ -236,4 +236,5 @@
   real,dimension(2,SR_BINS) :: sratio_bounds
   real,dimension(SR_BINS)   ::  sratio_ax
+  real,dimension(DBZE_BINS) ::  dbze_ax
   CHARACTER(LEN=20), DIMENSION(3)  :: chfreq = (/ '1day', '1d  ', '3h  ' /)            
 
@@ -257,18 +258,19 @@
     enddo
 
-!    do ii=1,DBZE_BINS
-!     dbze_ax(i) = CFAD_ZE_MIN + CFAD_ZE_WIDTH*(ii - 0.5)
-!    enddo
-
-!   sratio_bounds(2,:)=stlidar%srbval(:) ! srbval contains the upper
+    do i=1,DBZE_BINS
+     dbze_ax(i) = CFAD_ZE_MIN + CFAD_ZE_WIDTH*(i - 0.5)
+    enddo
+ 
+
+    sratio_bounds(2,:)=stlidar%srbval(:) ! srbval contains the upper
 !                                         limits from lmd_ipsl_stats.f90
-!   sratio_bounds(1,2:SR_BINS) = stlidar%srbval(1:SR_BINS-1)
-!   sratio_bounds(1,1)         = 0.0
-!   sratio_bounds(2,SR_BINS)   = 1.e5 ! This matches with Chepfer et al., JGR,
+    sratio_bounds(1,2:SR_BINS) = stlidar%srbval(1:SR_BINS-1)
+    sratio_bounds(1,1)         = 0.0
+    sratio_bounds(2,SR_BINS)   = 1.e5 ! This matches with Chepfer et al., JGR,
 !                                    ! 2009. However, it is not consistent 
                                      ! with the upper limit in
                                      ! lmd_ipsl_stats.f90, which is
                                      ! LIDAR_UNDEF-1=998.999
-!    sratio_ax(:) = (sratio_bounds(1,:)+sratio_bounds(2,:))/2.0 
+     sratio_ax(:) = (sratio_bounds(1,:)+sratio_bounds(2,:))/2.0 
 
     cosp_outfilenames(1) = 'histmthCOSP'
@@ -331,8 +333,10 @@
    CALL wxios_add_vaxis("temp", LIDAR_NTEMP, LIDAR_PHASE_TEMP)
    CALL wxios_add_vaxis("cth16", MISR_N_CTH, MISR_CTH)
-!   CALL wxios_add_vaxis("dbze", DBZE_BINS, dbze_ax) 
-!   CALL wxios_add_vaxis("scatratio", SR_BINS, sratio_ax)
+   CALL wxios_add_vaxis("dbze", DBZE_BINS, dbze_ax) 
+   CALL wxios_add_vaxis("scatratio", SR_BINS, sratio_ax)
    CALL wxios_add_vaxis("ReffIce", numMODISReffIceBins, reffICE_binCenters)
    CALL wxios_add_vaxis("ReffLiq", numMODISReffLiqBins, reffLIQ_binCenters)
+   print*,'reffICE_binCenters=',reffICE_binCenters
+   CALL wxios_add_vaxis("tau", 7, ISCCP_TAU)
 
 #endif
@@ -384,7 +388,9 @@
                     nvertReffLiq(iff))
 
-!      CALL histvert(cosp_nidfiles(iff),"dbze","equivalent_reflectivity_factor","dBZ",DBZE_BINS,dbze_ax,nvertbze(iff))
+      CALL histvert(cosp_nidfiles(iff),"dbze","equivalent_reflectivity_factor","dBZ",DBZE_BINS,dbze_ax,nvertbze(iff))
      
-!      CALL histvert(cosp_nidfiles(iff),"scatratio","backscattering_ratio","1",SR_BINS,sratio_ax,nvertsratio(iff))
+      CALL histvert(cosp_nidfiles(iff),"scatratio","backscattering_ratio","1",SR_BINS,sratio_ax,nvertsratio(iff))
+
+      CALL histvert(cosp_nidfiles(iff),"tau","cloud optical depth","1",7,ISCCP_TAU,nverttau(iff)) 
      
 !!! Valeur indefinie en cas IOIPSL
Index: LMDZ5/branches/testing/libf/phylmd/cosp/cosp_output_write_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/cosp/cosp_output_write_mod.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/cosp/cosp_output_write_mod.F90	(revision 2839)
@@ -17,5 +17,5 @@
    CONTAINS
 
-  SUBROUTINE cosp_output_write(Nlevlmdz, Npoints, Ncolumns, itap, dtime, freq_COSP, &
+  SUBROUTINE cosp_output_write(Nlevlmdz, Npoints, Ncolumns, itap, dtime, freq_COSP, missing_cosp, &
                                cfg, gbx, vgrid, sglidar, sgradar, stlidar, stradar, &
                                isccp, misr, modis)
@@ -32,5 +32,5 @@
 !!! Variables d'entree
   integer               :: itap, Nlevlmdz, Ncolumns, Npoints
-  real                  :: freq_COSP, dtime
+  real                  :: freq_COSP, dtime, missing_val, missing_cosp
   type(cosp_config)     :: cfg     ! Control outputs
   type(cosp_gridbox)    :: gbx     ! Gridbox information. Input for COSP
@@ -49,4 +49,11 @@
   integer               :: itau_wcosp
   real, dimension(Npoints,PARASOL_NREFL) :: parasolcrefl, Ncref
+
+
+#ifdef CPP_XIOS
+  missing_val=missing_cosp
+#else
+  missing_val=0.
+#endif
 
   Nlevout = vgrid%Nlvgrid
@@ -95,5 +102,5 @@
      do ip = 1,Npoints
      if(stlidar%lidarcld(ip,k).eq.R_UNDEF)then
-      stlidar%lidarcld(ip,k)=Cosp_fill_value
+      stlidar%lidarcld(ip,k)=missing_val
      endif
      enddo
@@ -102,5 +109,5 @@
       do ip = 1,Npoints
        if(stlidar%cfad_sr(ip,ii,k).eq.R_UNDEF)then
-        stlidar%cfad_sr(ip,ii,k)=Cosp_fill_value
+        stlidar%cfad_sr(ip,ii,k)=missing_val
        endif
       enddo
@@ -111,10 +118,10 @@
    do k = 1,Nlevlmdz
      if(sglidar%beta_mol(ip,k).eq.R_UNDEF)then
-      sglidar%beta_mol(ip,k)=Cosp_fill_value
+      sglidar%beta_mol(ip,k)=missing_val
      endif
 
      do ii= 1,Ncolumns
        if(sglidar%beta_tot(ip,ii,k).eq.R_UNDEF)then
-        sglidar%beta_tot(ip,ii,k)=Cosp_fill_value
+        sglidar%beta_tot(ip,ii,k)=missing_val
        endif
      enddo
@@ -126,5 +133,5 @@
     do ip = 1,Npoints
      if(stlidar%cldlayer(ip,k).eq.R_UNDEF)then
-      stlidar%cldlayer(ip,k)=Cosp_fill_value
+       stlidar%cldlayer(ip,k)=missing_val
      endif
     enddo
@@ -133,9 +140,9 @@
 ! AI 11 / 2015
 
-   where(stlidar%parasolrefl == R_UNDEF) stlidar%parasolrefl = 0.0
-   where(stlidar%lidarcldtmp == R_UNDEF) stlidar%lidarcldtmp = 0.0
-   where(stlidar%cldlayerphase == R_UNDEF) stlidar%cldlayerphase = 0.0
-   where(stlidar%lidarcldphase == R_UNDEF) stlidar%lidarcldphase = 0.0
-   where(stlidar%lidarcldtmp == R_UNDEF) stlidar%lidarcldtmp = 0.0
+   where(stlidar%parasolrefl == R_UNDEF) stlidar%parasolrefl = missing_val
+   where(stlidar%lidarcldtmp == R_UNDEF) stlidar%lidarcldtmp = missing_val
+   where(stlidar%cldlayerphase == R_UNDEF) stlidar%cldlayerphase = missing_val
+   where(stlidar%lidarcldphase == R_UNDEF) stlidar%lidarcldphase = missing_val
+   where(stlidar%lidarcldtmp == R_UNDEF) stlidar%lidarcldtmp = missing_val
    
 
@@ -169,9 +176,12 @@
    CALL histwrite3d_cosp(o_clcalipsotmpun,stlidar%lidarcldtmp(:,:,4),nverttemp)
 
+#ifdef CPP_XIOS
+   CALL histwrite4d_cosp(o_cfad_lidarsr532,stlidar%cfad_sr)
+#else
    do icl=1,SR_BINS
       CALL histwrite3d_cosp(o_cfad_lidarsr532,stlidar%cfad_sr(:,icl,:),nvert,icl)
    enddo
-
-   CALL histwrite3d_cosp(o_parasol_refl,stlidar%parasolrefl,nvertp)
+     CALL histwrite3d_cosp(o_parasol_refl,stlidar%parasolrefl,nvertp)
+#endif
 
    do k=1,PARASOL_NREFL
@@ -182,5 +192,5 @@
         Ncref(ip,k) = 1.
      else
-        parasolcrefl(ip,k)=0.
+        parasolcrefl(ip,k)=missing_val
         Ncref(ip,k) = 0.
      endif
@@ -190,11 +200,21 @@
    CALL histwrite3d_cosp(o_parasol_crefl,parasolcrefl,nvertp)
 
+#ifdef CPP_XIOS
+   CALL histwrite4d_cosp(o_atb532,sglidar%beta_tot)
+#else
    do icl=1,Ncolumns 
       CALL histwrite3d_cosp(o_atb532,sglidar%beta_tot(:,icl,:),nvertmcosp,icl)
    enddo
+#endif
+
    CALL histwrite3d_cosp(o_beta_mol532,sglidar%beta_mol,nvertmcosp) 
  endif !Lidar
 
  if (cfg%Lradar_sim) then
+
+#ifdef CPP_XIOS
+   CALL histwrite4d_cosp(o_dbze94,sgradar%Ze_tot)
+   CALL histwrite4d_cosp(o_cfadDbze94,stradar%cfad_ze)
+#else
    do icl=1,Ncolumns
       CALL histwrite3d_cosp(o_dbze94,sgradar%Ze_tot(:,icl,:),nvertmcosp,icl)
@@ -203,12 +223,13 @@
     CALL histwrite3d_cosp(o_cfadDbze94,stradar%cfad_ze(:,icl,:),nvert,icl)
    enddo
+#endif
  endif
 
  if (cfg%Llidar_sim .and. cfg%Lradar_sim) then
    where(stradar%lidar_only_freq_cloud == R_UNDEF) &
-                           stradar%lidar_only_freq_cloud = 0.0
+                           stradar%lidar_only_freq_cloud = missing_val
    CALL histwrite3d_cosp(o_clcalipso2,stradar%lidar_only_freq_cloud,nvert)
    where(stradar%radar_lidar_tcc == R_UNDEF) &
-                           stradar%radar_lidar_tcc = 0.0 
+                           stradar%radar_lidar_tcc = missing_val
    CALL histwrite2d_cosp(o_cltlidarradar,stradar%radar_lidar_tcc)
  endif
@@ -219,20 +240,20 @@
    do ip = 1,Npoints
     if(isccp%totalcldarea(ip).eq.R_UNDEF)then
-      isccp%totalcldarea(ip)=Cosp_fill_value
+      isccp%totalcldarea(ip)=missing_val
     endif
     if(isccp%meanptop(ip).eq.R_UNDEF)then
-      isccp%meanptop(ip)=Cosp_fill_value
+      isccp%meanptop(ip)=missing_val
     endif
     if(isccp%meantaucld(ip).eq.R_UNDEF)then
-      isccp%meantaucld(ip)=Cosp_fill_value
+      isccp%meantaucld(ip)=missing_val
     endif
     if(isccp%meanalbedocld(ip).eq.R_UNDEF)then
-      isccp%meanalbedocld(ip)=Cosp_fill_value
+     isccp%meanalbedocld(ip)=missing_val
     endif
     if(isccp%meantb(ip).eq.R_UNDEF)then
-      isccp%meantb(ip)=Cosp_fill_value
+     isccp%meantb(ip)=missing_val
     endif
     if(isccp%meantbclr(ip).eq.R_UNDEF)then
-      isccp%meantbclr(ip)=Cosp_fill_value
+       isccp%meantbclr(ip)=missing_val
     endif
 
@@ -240,5 +261,5 @@
      do ii=1,7
      if(isccp%fq_isccp(ip,ii,k).eq.R_UNDEF)then
-      isccp%fq_isccp(ip,ii,k)=Cosp_fill_value
+      isccp%fq_isccp(ip,ii,k)=missing_val
      endif
      enddo
@@ -247,5 +268,5 @@
     do ii=1,Ncolumns
      if(isccp%boxtau(ip,ii).eq.R_UNDEF)then
-       isccp%boxtau(ip,ii)=Cosp_fill_value
+       isccp%boxtau(ip,ii)=missing_val
      endif
     enddo
@@ -253,5 +274,5 @@
     do ii=1,Ncolumns
      if(isccp%boxptop(ip,ii).eq.R_UNDEF)then
-       isccp%boxptop(ip,ii)=Cosp_fill_value
+      isccp%boxptop(ip,ii)=missing_val
      endif
     enddo
@@ -259,7 +280,11 @@
 
    CALL histwrite2d_cosp(o_sunlit,gbx%sunlit)
+#ifdef CPP_XIOS
+   CALL histwrite4d_cosp(o_clisccp2,isccp%fq_isccp)
+#else
    do icl=1,7
    CALL histwrite3d_cosp(o_clisccp2,isccp%fq_isccp(:,icl,:),nvertisccp,icl) 
    enddo
+#endif
    CALL histwrite3d_cosp(o_boxtauisccp,isccp%boxtau,nvertcol)
    CALL histwrite3d_cosp(o_boxptopisccp,isccp%boxptop,nvertcol) 
@@ -278,5 +303,5 @@
        do k=1,MISR_N_CTH
         if(misr%fq_MISR(ip,ii,k).eq.R_UNDEF)then
-              misr%fq_MISR(ip,ii,k)=Cosp_fill_value
+            misr%fq_MISR(ip,ii,k)=missing_val
         endif
        enddo
@@ -284,7 +309,11 @@
    enddo
 
+#ifdef CPP_XIOS
+   CALL histwrite4d_cosp(o_clMISR,misr%fq_MISR)
+#else
    do icl=1,7 
       CALL histwrite3d_cosp(o_clMISR,misr%fq_MISR(:,icl,:),nvertmisr,icl)
    enddo
+#endif
  endif
 
@@ -294,47 +323,57 @@
   do ip=1,Npoints
     if(modis%Cloud_Fraction_Low_Mean(ip).eq.R_UNDEF)then
-       modis%Cloud_Fraction_Low_Mean(ip)=Cosp_fill_value
+      modis%Cloud_Fraction_Low_Mean(ip)=missing_val
     endif
     if(modis%Cloud_Fraction_High_Mean(ip).eq.R_UNDEF)then
-       modis%Cloud_Fraction_High_Mean(ip)=Cosp_fill_value
+       modis%Cloud_Fraction_High_Mean(ip)=missing_val 
     endif
     if(modis%Cloud_Fraction_Mid_Mean(ip).eq.R_UNDEF)then
-       modis%Cloud_Fraction_Mid_Mean(ip)=Cosp_fill_value
+       modis%Cloud_Fraction_Mid_Mean(ip)=missing_val
     endif
     if(modis%Cloud_Fraction_Total_Mean(ip).eq.R_UNDEF)then
-       modis%Cloud_Fraction_Total_Mean(ip)=Cosp_fill_value
+       modis%Cloud_Fraction_Total_Mean(ip)=missing_val
     endif
     if(modis%Cloud_Fraction_Water_Mean(ip).eq.R_UNDEF)then
-       modis%Cloud_Fraction_Water_Mean(ip)=Cosp_fill_value
+       modis%Cloud_Fraction_Water_Mean(ip)=missing_val
     endif
     if(modis%Cloud_Fraction_Ice_Mean(ip).eq.R_UNDEF)then
-       modis%Cloud_Fraction_Ice_Mean(ip)=Cosp_fill_value
+       modis%Cloud_Fraction_Ice_Mean(ip)=missing_val
     endif
     if(modis%Optical_Thickness_Total_Mean(ip).eq.R_UNDEF)then
-       modis%Optical_Thickness_Total_Mean(ip)=Cosp_fill_value
+       modis%Optical_Thickness_Total_Mean(ip)=missing_val
     endif
     if(modis%Optical_Thickness_Water_Mean(ip).eq.R_UNDEF)then
-       modis%Optical_Thickness_Water_Mean(ip)=Cosp_fill_value
+       modis%Optical_Thickness_Water_Mean(ip)=missing_val
     endif
     if(modis%Optical_Thickness_Ice_Mean(ip).eq.R_UNDEF)then
-       modis%Optical_Thickness_Ice_Mean(ip)=Cosp_fill_value
+       modis%Optical_Thickness_Ice_Mean(ip)=missing_val
     endif
     if(modis%Cloud_Particle_Size_Water_Mean(ip).eq.R_UNDEF)then
-       modis%Cloud_Particle_Size_Water_Mean(ip)=Cosp_fill_value
+       modis%Cloud_Particle_Size_Water_Mean(ip)=missing_val
     endif
     if(modis%Cloud_Particle_Size_Ice_Mean(ip).eq.R_UNDEF)then
-       modis%Cloud_Particle_Size_Ice_Mean(ip)=Cosp_fill_value
+       modis%Cloud_Particle_Size_Ice_Mean(ip)=missing_val
     endif
     if(modis%Cloud_Top_Pressure_Total_Mean(ip).eq.R_UNDEF)then
-       modis%Cloud_Top_Pressure_Total_Mean(ip)=Cosp_fill_value
+       modis%Cloud_Top_Pressure_Total_Mean(ip)=missing_val
     endif
     if(modis%Liquid_Water_Path_Mean(ip).eq.R_UNDEF)then
-       modis%Liquid_Water_Path_Mean(ip)=Cosp_fill_value
+       modis%Liquid_Water_Path_Mean(ip)=missing_val
     endif
     if(modis%Ice_Water_Path_Mean(ip).eq.R_UNDEF)then
-       modis%Ice_Water_Path_Mean(ip)=Cosp_fill_value
+       modis%Ice_Water_Path_Mean(ip)=missing_val
     endif
 
   enddo
+
+    where(modis%Optical_Thickness_Total_LogMean == R_UNDEF) &
+          modis%Optical_Thickness_Total_LogMean = missing_val
+           
+ 
+    where(modis%Optical_Thickness_Water_LogMean == R_UNDEF) &
+          modis%Optical_Thickness_Water_LogMean = missing_val
+
+    where(modis%Optical_Thickness_Ice_LogMean == R_UNDEF) &
+          modis%Optical_Thickness_Ice_LogMean = missing_val
     
    CALL histwrite2d_cosp(o_cllmodis,modis%Cloud_Fraction_Low_Mean)
@@ -360,5 +399,5 @@
        do k=1,7
        if(modis%Optical_Thickness_vs_Cloud_Top_Pressure(ip,ii,k).eq.R_UNDEF)then
-          modis%Optical_Thickness_vs_Cloud_Top_Pressure(ip,ii,k)=0.
+          modis%Optical_Thickness_vs_Cloud_Top_Pressure(ip,ii,k)=missing_val
         endif
        enddo
@@ -366,15 +405,25 @@
     enddo 
 
+#ifdef CPP_XIOS
+   CALL histwrite4d_cosp(o_clmodis,modis%Optical_Thickness_vs_Cloud_Top_Pressure)
+#else
    do icl=1,7
    CALL histwrite3d_cosp(o_clmodis, &
      modis%Optical_Thickness_vs_Cloud_Top_Pressure(:,icl,:),nvertisccp,icl)           
    enddo
+#endif
 
     where(modis%Optical_Thickness_vs_ReffIce == R_UNDEF) &
-          modis%Optical_Thickness_vs_ReffIce = Cosp_fill_value
+          modis%Optical_Thickness_vs_ReffIce = missing_val
 
     where(modis%Optical_Thickness_vs_ReffLiq == R_UNDEF) &
-          modis%Optical_Thickness_vs_ReffLiq = Cosp_fill_value
-
+          modis%Optical_Thickness_vs_ReffLiq = missing_val
+
+#ifdef CPP_XIOS
+!    print*,'dimension de crimodis=',size(modis%Optical_Thickness_vs_ReffIce,2),&
+!                                    size(modis%Optical_Thickness_vs_ReffIce,3)
+    CALL histwrite4d_cosp(o_crimodis,modis%Optical_Thickness_vs_ReffIce)
+    CALL histwrite4d_cosp(o_crlmodis,modis%Optical_Thickness_vs_ReffLiq)
+#else
     do icl=1,7
    CALL histwrite3d_cosp(o_crimodis, &
@@ -383,4 +432,5 @@
      modis%Optical_Thickness_vs_ReffLiq(:,icl,:),nvertReffLiq,icl)
     enddo
+#endif
  endif
 
@@ -784,4 +834,58 @@
   END SUBROUTINE histwrite3d_cosp
 
+! ug NOUVELLE VERSION DES WRITE AVEC LA BOUCLE DO RENTREE
+! AI sept 2013
+  SUBROUTINE histwrite4d_cosp(var, field)
+  USE dimphy
+  USE mod_phys_lmdz_para
+  USE ioipsl
+  use iophy
+  USE mod_grid_phy_lmdz, ONLY: nbp_lon
+  USE print_control_mod, ONLY: lunout,prt_level
+
+#ifdef CPP_XIOS
+  USE xios, only: xios_send_field
+#endif
+
+
+  IMPLICIT NONE
+  INCLUDE 'clesphys.h'
+
+    TYPE(ctrl_outcosp), INTENT(IN)    :: var
+    REAL, DIMENSION(:,:,:), INTENT(IN)  :: field ! --> field(klon,:)
+
+    INTEGER :: iff, k
+
+    REAL,DIMENSION(klon_mpi,SIZE(field,2),SIZE(field,3)) :: buffer_omp
+    REAL :: field4d(nbp_lon,jj_nb,SIZE(field,2),SIZE(field,3))
+    INTEGER :: ip, n, nlev, nlev2
+    INTEGER, ALLOCATABLE, DIMENSION(:) :: index4d
+    CHARACTER(LEN=20) ::  nomi, nom
+
+  IF (prt_level >= 9) write(lunout,*)'Begin histrwrite4d ',var%name
+
+  IF(cosp_varsdefined) THEN
+    !Et sinon on.... Ã©crit
+    IF (SIZE(field,1)/=klon) &
+   CALL abort_physic('iophy::histwrite3d','Field first DIMENSION not equal to klon',1)            
+
+    nlev=SIZE(field,2)
+    nlev2=SIZE(field,3)
+    CALL Gather_omp(field,buffer_omp)
+!$OMP MASTER
+    CALL grid1Dto2D_mpi(buffer_omp,field4d)
+
+#ifdef CPP_XIOS
+    IF (ok_all_xml) THEN
+     CALL xios_send_field(var%name, Field4d(:,:,1:nlev,1:nlev2))
+     IF (prt_level >= 1) WRITE(lunout,*)'xios_send_field ',var%name
+    ENDIF
+#endif
+
+!$OMP END MASTER   
+  ENDIF ! vars_defined
+  IF (prt_level >= 9) write(lunout,*)'End histrwrite4d_cosp ',nom
+  END SUBROUTINE histwrite4d_cosp
+
   SUBROUTINE conf_cospoutputs(nam_var,cles_var)
 !!! Lecture des noms et cles de sortie des variables dans config.def
Index: LMDZ5/branches/testing/libf/phylmd/cosp/modis_simulator.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/cosp/modis_simulator.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/cosp/modis_simulator.F90	(revision 2839)
@@ -532,11 +532,13 @@
 
     ! ########################################################################################
-    ! Normalize pixel counts to fraction. The first three cloud fractions have been set to -1 
-    ! in cloud-free areas, so set those places to 0.
-    ! ########################################################################################
-    Cloud_Fraction_High_Mean(1:nPoints)  = Cloud_Fraction_High_Mean(1:nPoints) /nSubcols
-    Cloud_Fraction_Mid_Mean(1:nPoints)   = Cloud_Fraction_Mid_Mean(1:nPoints)  /nSubcols
-    Cloud_Fraction_Low_Mean(1:nPoints)   = Cloud_Fraction_Low_Mean(1:nPoints)  /nSubcols
-
+    ! Normalize pixel counts to fraction.
+    ! ########################################################################################
+    Cloud_Fraction_High_Mean(1:nPoints)  = Cloud_Fraction_High_Mean(1:nPoints)  /nSubcols
+    Cloud_Fraction_Mid_Mean(1:nPoints)   = Cloud_Fraction_Mid_Mean(1:nPoints)   /nSubcols
+    Cloud_Fraction_Low_Mean(1:nPoints)   = Cloud_Fraction_Low_Mean(1:nPoints)   /nSubcols
+    Cloud_Fraction_Total_Mean(1:nPoints) = Cloud_Fraction_Total_Mean(1:nPoints) /nSubcols
+    Cloud_Fraction_Ice_Mean(1:nPoints)   = Cloud_Fraction_Ice_Mean(1:nPoints)   /nSubcols
+    Cloud_Fraction_Water_Mean(1:nPoints) = Cloud_Fraction_Water_Mean(1:nPoints) /nSubcols
+    
     ! ########################################################################################
     ! Set clear-scenes to undefined
Index: LMDZ5/branches/testing/libf/phylmd/cosp/phys_cosp.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/cosp/phys_cosp.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/cosp/phys_cosp.F90	(revision 2839)
@@ -7,5 +7,5 @@
   subroutine phys_cosp( itap,dtime,freq_cosp, &
                         ok_mensuelCOSP,ok_journeCOSP,ok_hfCOSP, &
-                        ecrit_mth,ecrit_day,ecrit_hf, ok_all_xml, &
+                        ecrit_mth,ecrit_day,ecrit_hf, ok_all_xml, missing_val, &
                         Nptslmdz,Nlevlmdz,lon,lat, presnivs,overlaplmdz,sunlit, &
                         ref_liq,ref_ice,fracTerLic,u_wind,v_wind,phis,phi,ph,p,skt,t, &
@@ -130,5 +130,5 @@
 ! Declaration necessaires pour les sorties IOIPSL
   integer :: ii
-  real    :: ecrit_day,ecrit_hf,ecrit_mth
+  real    :: ecrit_day,ecrit_hf,ecrit_mth, missing_val
   logical :: ok_mensuelCOSP,ok_journeCOSP,ok_hfCOSP, ok_all_xml
 
@@ -192,5 +192,7 @@
 ! Allocate memory for gridbox type
 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-        print *, 'Allocating memory for gridbox type...'
+! AI mars 2017
+!        print *, 'Allocating memory for gridbox type...'
+
 !! AI
 !        call construct_cosp_gridbox(dble(itap),radar_freq,surface_radar,use_mie_tables,use_gas_abs,do_ray,melt_lay,k2, &
@@ -215,5 +217,5 @@
 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
-        print *, 'Populating input structure...'
+!        print *, 'Populating input structure...'
         gbx%longitude = lon
         gbx%latitude = lat
@@ -299,5 +301,5 @@
         ! Define new vertical grid
 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-        print *, 'Defining new vertical grid...'
+!        print *, 'Defining new vertical grid...'
         call construct_cosp_vgrid(gbx,Nlr,use_vgrid,csat_vgrid,vgrid)
 
@@ -305,5 +307,5 @@
        ! Allocate memory for other types
 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-        print *, 'Allocating memory for other types...'
+!        print *, 'Allocating memory for other types...'
         call construct_cosp_subgrid(Npoints, Ncolumns, Nlevels, sgx)
         call construct_cosp_sgradar(cfg,Npoints,Ncolumns,Nlevels,N_HYDRO,sgradar)
@@ -325,5 +327,5 @@
         call cosp_output_open(Nlevlmdz, Ncolumns, presnivs, dtime, freq_cosp, &
                               ok_mensuelCOSP, ok_journeCOSP, ok_hfCOSP, ok_all_xml, &
-                              ecrit_mth, ecrit_day, ecrit_hf, use_vgrid, vgrid)
+                              ecrit_mth, ecrit_day, ecrit_hf, use_vgrid, vgrid, stlidar)
       !$OMP END MASTER
       !$OMP BARRIER
@@ -333,5 +335,5 @@
         ! Call simulator
 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-        print *, 'Calling simulator...'
+!        print *, 'Calling simulator...'
 !! AI 
 !        call cosp(overlap,Ncolumns,cfg,vgrid,gbx,sgx,sgradar,sglidar,isccp,misr,stradar,stlidar)
@@ -347,6 +349,6 @@
 !!!!!!!!!!!!!!!!!! Ecreture des sorties Cosp !!!!!!!!!!!!!!r!!!!!!:!!!!!
 
-       print *, 'Calling write output'
-        call cosp_output_write(Nlevlmdz, Npoints, Ncolumns, itap, dtime, freq_COSP, &
+!       print *, 'Calling write output'
+        call cosp_output_write(Nlevlmdz, Npoints, Ncolumns, itap, dtime, freq_COSP, missing_val, &
                                cfg, gbx, vgrid, sglidar, sgradar, stlidar, stradar, & 
                                isccp, misr, modis)
@@ -355,5 +357,5 @@
         ! Deallocate memory in derived types
 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-        print *, 'Deallocating memory...'
+!        print *, 'Deallocating memory...'
         call free_cosp_gridbox(gbx)
         call free_cosp_subgrid(sgx)
Index: LMDZ5/branches/testing/libf/phylmd/cv3_routines.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/cv3_routines.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/cv3_routines.F90	(revision 2839)
@@ -281,4 +281,6 @@
                     wghti, tnk, thnk, qnk, qsnk, unk, vnk, &
                     cpnk, hnk, nk, icb, icbmax, iflag, gznk, plcl)
+
+  USE mod_phys_lmdz_transfert_para, ONLY : bcast
   IMPLICIT NONE
 
@@ -349,6 +351,7 @@
     END IF
     PRINT *, ' ok_new_feed: ', ok_new_feed
-    first = .FALSE.
 !$OMP END MASTER
+    call bcast(ok_new_feed)
+    first = .FALSE.   
   END IF
 !jyg>
Index: LMDZ5/branches/testing/libf/phylmd/cv3p1_closure.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/cv3p1_closure.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/cv3p1_closure.F90	(revision 2839)
@@ -543,4 +543,6 @@
       ELSE IF (flag_wb==2) THEN
         wbeff(il) = wbmax*(0.01*(ph(il,1)-plfc(il)))**2
+      ELSE ! Option provisoire ou le iflag_wb/10 est considere comme une vitesse
+        wbeff(il) = flag_wb*0.01+wbmax/(1.+500./(ph(il,1)-plfc(il)))
       END IF
     END IF
Index: LMDZ5/branches/testing/libf/phylmd/dyn1d/1DUTILS.h
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/dyn1d/1DUTILS.h	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/dyn1d/1DUTILS.h	(revision 2839)
@@ -2783,4 +2783,5 @@
          hq_mod_cas(l)= hq_prof_cas(k2) - frac*(hq_prof_cas(k2)-hq_prof_cas(k1))
          vq_mod_cas(l)= vq_prof_cas(k2) - frac*(vq_prof_cas(k2)-vq_prof_cas(k1))
+         dtrad_mod_cas(l)= dtrad_prof_cas(k2) - frac*(dtrad_prof_cas(k2)-dtrad_prof_cas(k1))
      
          else !play>plev_prof_cas(1)
@@ -2809,4 +2810,5 @@
          hq_mod_cas(l)= frac1*hq_prof_cas(k1) - frac2*hq_prof_cas(k2)
          vq_mod_cas(l)= frac1*vq_prof_cas(k1) - frac2*vq_prof_cas(k2)
+         dtrad_mod_cas(l)= frac1*dtrad_prof_cas(k1) - frac2*dtrad_prof_cas(k2)
 
          endif ! play.le.plev_prof_cas(1)
@@ -2837,4 +2839,5 @@
          hq_mod_cas(l)= hq_prof_cas(nlev_cas)*fact                            !jyg
          vq_mod_cas(l)= vq_prof_cas(nlev_cas)*fact                            !jyg
+         dtrad_mod_cas(l)= dtrad_prof_cas(nlev_cas)*fact                      !jyg
  
         endif ! play
@@ -5162,4 +5165,5 @@
          hq_mod_cas(l)= hq_prof_cas(k2) - frac*(hq_prof_cas(k2)-hq_prof_cas(k1))
          vq_mod_cas(l)= vq_prof_cas(k2) - frac*(vq_prof_cas(k2)-vq_prof_cas(k1))
+         dtrad_mod_cas(l)= dtrad_prof_cas(k2) - frac*(dtrad_prof_cas(k2)-dtrad_prof_cas(k1))
      
          else !play>plev_prof_cas(1)
@@ -5198,4 +5202,5 @@
          hq_mod_cas(l)= frac1*hq_prof_cas(k1) - frac2*hq_prof_cas(k2)
          vq_mod_cas(l)= frac1*vq_prof_cas(k1) - frac2*vq_prof_cas(k2)
+         dtrad_mod_cas(l)= frac1*dtrad_prof_cas(k1) - frac2*dtrad_prof_cas(k2)
 
          endif ! play.le.plev_prof_cas(1)
@@ -5234,4 +5239,5 @@
          hq_mod_cas(l)= hq_prof_cas(nlev_cas)*fact                     !jyg
          vq_mod_cas(l)= vq_prof_cas(nlev_cas)*fact                     !jyg
+         dtrad_mod_cas(l)= dtrad_prof_cas(nlev_cas)*fact               !jyg
  
         endif ! play
Index: LMDZ5/branches/testing/libf/phylmd/dyn1d/lmdz1d.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/dyn1d/lmdz1d.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/dyn1d/lmdz1d.F90	(revision 2839)
@@ -40,5 +40,5 @@
    USE physiq_mod, ONLY: physiq
    USE comvert_mod, ONLY: presnivs, ap, bp, dpres,nivsig, nivsigs, pa, &
-                          preff
+                          preff, aps, bps, pseudoalt, scaleheight
    USE temps_mod, ONLY: annee_ref, calend, day_end, day_ini, day_ref, &
                         itau_dyn, itau_phy, start_time
@@ -634,4 +634,8 @@
         call disvert0(pa,preff,ap,bp,dpres,presnivs,nivsigs,nivsig)
         print *,'On utilise disvert0'
+        aps(1:llm)=0.5*(ap(1:llm)+ap(2:llm+1))
+        bps(1:llm)=0.5*(bp(1:llm)+bp(2:llm+1))
+        scaleheight=8.
+        pseudoalt(1:llm)=-scaleheight*log(presnivs(1:llm)/preff)
       ELSE
         call disvert()
@@ -640,5 +644,5 @@
 !       Dans ce cas, on lit ap,bp dans le fichier hybrid.txt
       ENDIF
-      ! initialize ap,bp, etc. in vertical_layers_mod
+
       sig_s=presnivs/preff
       plev =ap+bp*psurf
Index: LMDZ5/branches/testing/libf/phylmd/ener_conserv.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/ener_conserv.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/ener_conserv.F90	(revision 2839)
@@ -153,4 +153,5 @@
 
       bils_ec(:)=0.
+      bils_ech(:)=0.
       bils_tke(:)=0.
       bils_diss(:)=0.
Index: LMDZ5/branches/testing/libf/phylmd/fisrtilp.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/fisrtilp.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/fisrtilp.F90	(revision 2839)
@@ -17,4 +17,7 @@
   USE cloudth_mod 
   USE ioipsl_getin_p_mod, ONLY : getin_p
+  USE phys_local_var_mod, ONLY: ql_seri,qs_seri
+  ! flag to include modifications to ensure energy conservation (if flag >0)
+  USE add_phys_tend_mod, only : fl_cor_ebil 
   IMPLICIT none
   !======================================================================
@@ -26,8 +29,20 @@
   !             et ilp (il pleut, L. Li)
   ! Principales parties:
+  ! P0> Thermalisation des precipitations venant de la couche du dessus
   ! P1> Evaporation de la precipitation (qui vient du niveau k+1)
   ! P2> Formation du nuage (en k) 
+  ! P2.A.0> Calcul des grandeurs nuageuses une pdf en creneau
+  ! P2.A.1> Avec les nouvelles PDFs, calcul des grandeurs nuageuses pour 
+  ! les valeurs de T et Q initiales
+  ! P2.A.2> Prise en compte du couplage entre eau condensee et T.
+  ! P2.A.3> Calcul des valeures finales associees a la formation des nuages
+  ! P2.B> Nuage "tout ou rien"
+  ! P2.C> Prise en compte de la Chaleur latente apres formation nuage
   ! P3> Formation de la precipitation (en k)
   !======================================================================
+  ! JLD: 
+  ! * Routine probablement fausse (au moins incoherente) si thermcep = .false.
+  ! * fl_cor_ebil doit etre > 0 ; 
+  !   fl_cor_ebil= 0 pour reproduire anciens bugs
   !======================================================================
   include "YOMCST.h"
@@ -38,51 +53,51 @@
   ! Principaux inputs:
   !
-  REAL dtime ! intervalle du temps (s)
-  REAL paprs(klon,klev+1) ! pression a inter-couche
-  REAL pplay(klon,klev) ! pression au milieu de couche
-  REAL t(klon,klev) ! temperature (K)
-  REAL q(klon,klev) ! humidite specifique (kg/kg)
+  REAL, INTENT(IN)                              :: dtime  ! intervalle du temps (s)
+  REAL, DIMENSION(klon,klev+1),    INTENT(IN)   :: paprs  ! pression a inter-couche
+  REAL, DIMENSION(klon,klev),      INTENT(IN)   :: pplay  ! pression au milieu de couche
+  REAL, DIMENSION(klon,klev),      INTENT(IN)   :: t      ! temperature (K)
+  REAL, DIMENSION(klon,klev),      INTENT(IN)   :: q      ! humidite specifique (kg/kg)
+  LOGICAL, DIMENSION(klon,klev),   INTENT(IN)   :: ptconv ! points ou le schema de conv. prof. est actif
+  INTEGER,                         INTENT(IN)   :: iflag_cld_th
+  INTEGER,                         INTENT(IN)   :: iflag_ice_thermo
+  !
+  ! Inputs lies aux thermiques
+  ! 
+  REAL, DIMENSION(klon,klev),      INTENT(IN)   :: ztv
+  REAL, DIMENSION(klon,klev),      INTENT(IN)   :: zqta, fraca 
+  REAL, DIMENSION(klon,klev),      INTENT(IN)   :: zpspsk, ztla
+  REAL, DIMENSION(klon,klev),      INTENT(IN)   :: zthl
+  !
+  !  Input/output
+  REAL, DIMENSION(klon,klev),      INTENT(INOUT):: ratqs  ! determine la largeur de distribution de vapeur
   !
   ! Principaux outputs:
   !
-  REAL d_t(klon,klev) ! incrementation de la temperature (K)
-  REAL d_q(klon,klev) ! incrementation de la vapeur d'eau
-  REAL d_ql(klon,klev) ! incrementation de l'eau liquide
-  REAL d_qi(klon,klev) ! incrementation de l'eau glace
-  REAL rneb(klon,klev) ! fraction nuageuse
-  REAL radliq(klon,klev) ! eau liquide utilisee dans rayonnements
-  REAL rhcl(klon,klev) ! humidite relative en ciel clair
-  REAL rain(klon) ! pluies (mm/s)
-  REAL snow(klon) ! neige (mm/s)
-  REAL prfl(klon,klev+1) ! flux d'eau precipitante aux interfaces (kg/m2/s)
-  REAL psfl(klon,klev+1) ! flux d'eau precipitante aux interfaces (kg/m2/s) 
-  !
-  ! Autres arguments
-  ! 
-  REAL ztv(klon,klev)
-  REAL zqta(klon,klev),fraca(klon,klev) 
-  REAL sigma1(klon,klev),sigma2(klon,klev)
-  REAL qltot(klon,klev),ctot(klon,klev)
-  REAL zpspsk(klon,klev),ztla(klon,klev)
-  REAL zthl(klon,klev)
-  REAL ztfondue, qsl, qsi
-
-  logical lognormale(klon)
-  logical ice_thermo
+  REAL, DIMENSION(klon,klev),      INTENT(OUT)  :: d_t  ! incrementation de la temperature (K)
+  REAL, DIMENSION(klon,klev),      INTENT(OUT)  :: d_q  ! incrementation de la vapeur d'eau
+  REAL, DIMENSION(klon,klev),      INTENT(OUT)  :: d_ql ! incrementation de l'eau liquide
+  REAL, DIMENSION(klon,klev),      INTENT(OUT)  :: d_qi ! incrementation de l'eau glace
+  REAL, DIMENSION(klon,klev),      INTENT(OUT)  :: rneb ! fraction nuageuse
+  REAL, DIMENSION(klon,klev),      INTENT(OUT)  :: radliq ! eau liquide utilisee dans rayonnements
+  REAL, DIMENSION(klon,klev),      INTENT(OUT)  :: rhcl ! humidite relative en ciel clair
+  REAL, DIMENSION(klon),           INTENT(OUT)  :: rain
+  REAL, DIMENSION(klon),           INTENT(OUT)  :: snow
+  REAL, DIMENSION(klon,klev+1),    INTENT(OUT)  :: prfl
+  REAL, DIMENSION(klon,klev+1),    INTENT(OUT)  :: psfl 
 
   !AA
   ! Coeffients de fraction lessivee : pour OFF-LINE
   !
-  REAL pfrac_nucl(klon,klev)
-  REAL pfrac_1nucl(klon,klev)
-  REAL pfrac_impa(klon,klev)
+  REAL, DIMENSION(klon,klev),      INTENT(OUT)  :: pfrac_nucl
+  REAL, DIMENSION(klon,klev),      INTENT(OUT)  :: pfrac_1nucl
+  REAL, DIMENSION(klon,klev),      INTENT(OUT)  :: pfrac_impa
   !
   ! Fraction d'aerosols lessivee par impaction et par nucleation
   ! POur ON-LINE
   !
-  REAL frac_impa(klon,klev)
-  REAL frac_nucl(klon,klev)
-  real zct      ,zcl
+  REAL, DIMENSION(klon,klev),      INTENT(OUT)  :: frac_impa
+  REAL, DIMENSION(klon,klev),      INTENT(OUT)  :: frac_nucl
   !AA
+  ! --------------------------------------------------------------------------------
   !
   ! Options du programme:
@@ -92,12 +107,34 @@
 
   INTEGER ninter ! sous-intervals pour la precipitation
-  INTEGER ncoreczq  
-  INTEGER iflag_cld_th
-  INTEGER iflag_ice_thermo
   PARAMETER (ninter=5)
   LOGICAL evap_prec ! evaporation de la pluie
   PARAMETER (evap_prec=.TRUE.)
-  REAL ratqs(klon,klev) ! determine la largeur de distribution de vapeur
-  logical ptconv(klon,klev) ! determine la largeur de distribution de vapeur
+  !
+  LOGICAL cpartiel ! condensation partielle
+  PARAMETER (cpartiel=.TRUE.)
+  REAL t_coup
+  PARAMETER (t_coup=234.0)
+  REAL DDT0
+  PARAMETER (DDT0=.01)
+  REAL ztfondue
+  PARAMETER (ztfondue=278.15)
+  ! --------------------------------------------------------------------------------
+  !
+  ! Variables locales:
+  !
+  INTEGER i, k, n, kk
+  REAL qsl, qsi
+  real zct      ,zcl
+  INTEGER ncoreczq  
+  REAL ctot(klon,klev)
+  REAL zqs(klon), zdqs(klon), zdelta, zcor, zcvm5  
+  REAL zdqsdT_raw(klon)
+  REAL Tbef(klon),qlbef(klon),DT(klon),num,denom
+
+  logical lognormale(klon)
+  logical ice_thermo
+  LOGICAL convergence(klon)
+  INTEGER n_i(klon), iter
+  REAL cste
 
   real zpdf_sig(klon),zpdf_k(klon),zpdf_delta(klon)
@@ -105,20 +142,4 @@
   real erf   
   REAL qcloud(klon)
-  !
-  LOGICAL cpartiel ! condensation partielle
-  PARAMETER (cpartiel=.TRUE.)
-  REAL t_coup
-  PARAMETER (t_coup=234.0)
-  !
-  ! Variables locales:
-  !
-  INTEGER i, k, n, kk
-  REAL zqs(klon), zdqs(klon), zdelta, zcor, zcvm5  
-  REAL Tbef(klon),qlbef(klon),DT(klon),num,denom
-  LOGICAL convergence(klon)
-  REAL DDT0
-  PARAMETER (DDT0=.01)
-  INTEGER n_i(klon), iter
-  REAL cste
  
   REAL zrfl(klon), zrfln(klon), zqev, zqevt 
@@ -134,12 +155,13 @@
   REAL zdz(klon),zrho(klon),ztot      , zrhol(klon)
   REAL zchau      ,zfroi      ,zfice(klon),zneb(klon)
-  REAL zmelt, zpluie, zice, zcondold
-  PARAMETER (ztfondue=278.15)
+  REAL zmelt, zpluie, zice
   REAL dzfice(klon)
   REAL zsolid
 !!!!
 !  Variables pour Bergeron
-  REAL zcp, coef1, DeltaT
+  REAL zcp, coef1, DeltaT, Deltaq, Deltaqprecl
   REAL zqpreci(klon), zqprecl(klon)
+! Variable pour conservation enegie des precipitations
+  REAL zmqc(klon)
   !
   LOGICAL appel1er
@@ -170,5 +192,5 @@
   REAL   beta(klon,klev) ! taux de conversion de l'eau cond
 ! RomP <<<
-  REAL zmair, zcpair, zcpeau
+  REAL zmair(klon), zcpair, zcpeau
   !     Pour la conversion eau-neige
   REAL zlh_solid(klon), zm_solid
@@ -180,4 +202,5 @@
                      ! (Heymsfield & Donner, 1990)
   REAL zzz
+
   include "YOETHF.h"
   include "FCTTRE.h"
@@ -312,31 +335,55 @@
      ENDDO
      !
+     ! ----------------------------------------------------------------
+     ! P0> Thermalisation des precipitations venant de la couche du dessus
+     ! ----------------------------------------------------------------
      ! Calculer la varition de temp. de l'air du a la chaleur sensible
-     ! transporter par la pluie.
-     ! Il resterait a rajouter cet effet de la chaleur sensible sur les
-     ! flux de surface, du a la diff. de temp. entre le 1er niveau et la
-     ! surface.
+     ! transporter par la pluie. On thermalise la pluie avec l'air de la couche.
+     ! Cette quantite de pluie qui est thermalisee, et devra continue a l'etre lors
+     ! des differentes transformations thermodynamiques. Cette masse d'eau doit
+     ! donc etre ajoute a l'humidite de la couche lorsque l'on calcule la variation
+     ! de l'enthalpie  de la couche avec la temperature
+     ! Variables calculees ou modifiees:
+     !   -  zt: temperature de la cocuhe
+     !   - zmqc: masse de precip qui doit etre thermalisee
      !
      IF(k.LE.klevm1) THEN         
         DO i = 1, klon
            !IM
-           zmair=(paprs(i,k)-paprs(i,k+1))/RG
+           zmair(i)=(paprs(i,k)-paprs(i,k+1))/RG
+           ! il n'y a pas encore d'eau liquide ni glace dans la maiille, donc zq suffit
            zcpair=RCPD*(1.0+RVTMP2*zq(i))
            zcpeau=RCPD*RVTMP2
+         if (fl_cor_ebil .GT. 0) then
+           ! zmqc: masse de precip qui doit etre thermalisee avec l'air de la couche atm 
+           ! pour s'assurer que la precip arrivant au sol aura bien la temperature de la 
+           ! derniere couche
+           zmqc(i) = (zrfl(i)+zifl(i))*dtime/zmair(i)
+           ! t(i,k+1)+d_t(i,k+1): nouvelle temp de la couche au dessus
+           zt(i) = ( (t(i,k+1)+d_t(i,k+1))*zmqc(i)*zcpeau + zcpair*zt(i) ) &
+                 / (zcpair + zmqc(i)*zcpeau)
+         else ! si on maintient les anciennes erreurs
            zt(i) = ( (t(i,k+1)+d_t(i,k+1))*zrfl(i)*dtime*zcpeau &
-                + zmair*zcpair*zt(i) ) &
-                / (zmair*zcpair + zrfl(i)*dtime*zcpeau)
-           !     C        WRITE (6,*) 'cppluie ', zt(i)-(t(i,k+1)+d_t(i,k+1))
+                + zmair(i)*zcpair*zt(i) ) &
+                / (zmair(i)*zcpair + zrfl(i)*dtime*zcpeau)
+         end if
         ENDDO
-     ENDIF
-     ! ----------------------------------------------------------------
-     ! P1> Debut evaporation de la precipitation
-     ! ----------------------------------------------------------------
+     ENDIF ! end IF(k.LE.klevm1)
+     !
+     ! ----------------------------------------------------------------
+     ! P1> Calcul de l'evaporation de la precipitation
+     ! ----------------------------------------------------------------
+     ! On evapore une partie des precipitations venant de la maille du dessus.
+     ! On calcule l'evaporation et la sublimation des precipitations, jusqu'a
+     ! ce que la fraction de cette couche qui est sous le nuage soit saturee.
+     ! Variables calculees ou modifiees:
+     !   - zrfl et zifl: flux de precip liquide et glace
+     !   - zq, zt: humidite et temperature de la cocuhe
+     !   - zmqc: masse de precip qui doit etre thermalisee
+     !
      IF (evap_prec) THEN
         DO i = 1, klon
-!AJ<
-!!           IF (zrfl(i) .GT.0.) THEN
+!          S'il y a des precipitations
            IF (zrfl(i)+zifl(i).GT.0.) THEN
-!>AJ
               ! Calcul du qsat
               IF (thermcep) THEN
@@ -356,12 +403,41 @@
         ENDDO
 !AJ<
+
        IF (.NOT. ice_thermo) THEN
         DO i = 1, klon
-!AJ<
-!!           IF (zrfl(i) .GT.0.) THEN
+!          S'il y a des precipitations
            IF (zrfl(i)+zifl(i).GT.0.) THEN
-!>AJ
                 ! Evap max pour ne pas saturer la fraction sous le nuage
+                ! Evap max jusqu'à atteindre la saturation dans la partie
+                ! de la maille qui est sous le nuage de la couche du dessus
+                !!! On ne tient compte de cette fraction que sous une seule
+                !!! couche sous le nuage
                 zqev = MAX (0.0, (zqs(i)-zq(i))*zneb(i) )
+             ! Ajout de la prise en compte des precip a thermiser
+             ! avec petite reecriture 
+             if  (fl_cor_ebil .GT. 0) then ! nouveau
+                ! Calcul de l'evaporation du flux de precip herite
+                !   d'au-dessus
+                zqevt = coef_eva * (1.0-zq(i)/zqs(i)) * SQRT(zrfl(i)) &
+                     * zmair(i)/pplay(i,k)*zt(i)*RD
+                zqevt = MAX(0.0,MIN(zqevt,zrfl(i))) * dtime/zmair(i)
+
+                ! Seuil pour ne pas saturer la fraction sous le nuage
+                zqev = MIN (zqev, zqevt)
+                ! Nouveau flux de precip
+                zrfln(i) = zrfl(i) - zqev*zmair(i)/dtime
+                ! Aucun flux liquide pour T < t_coup, on reevapore tout.
+                IF (zt(i) .LT. t_coup.and.reevap_ice) THEN
+                  zrfln(i)=0.
+                  zqev = (zrfl(i)-zrfln(i))/zmair(i)*dtime
+                END IF
+                ! Nouvelle vapeur 
+                zq(i) = zq(i) + zqev
+                zmqc(i) = zmqc(i)-zqev
+                ! Nouvelle temperature (chaleur latente)
+                zt(i) = zt(i) - zqev &
+                     * RLVTT/RCPD/(1.0+RVTMP2*(zq(i)+zmqc(i)))
+!!JLD debut de partie a supprimer a terme
+            else ! if  (fl_cor_ebil .GT. 0)
                 ! Calcul de l'evaporation du flux de precip herite
                 !   d'au-dessus
@@ -384,4 +460,6 @@
                      * (RG/(paprs(i,k)-paprs(i,k+1)))*dtime &
                      * RLVTT/RCPD/(1.0+RVTMP2*zq(i))
+              end if ! if  (fl_cor_ebil .GT. 0)
+!!JLD fin de partie a supprimer a terme
                 zrfl(i) = zrfln(i)
                 zifl(i) = 0.
@@ -390,24 +468,19 @@
 !
        ELSE ! (.NOT. ice_thermo) 
-!
+!      ================================
+!      Avec thermodynamique de la glace
+!      ================================
         DO i = 1, klon
 !AJ<
-!!           IF (zrfl(i) .GT.0.) THEN
-           IF (zrfl(i)+zifl(i).GT.0.) THEN
-!>AJ
-     !JAM !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-     ! Modification de l'evaporation avec la glace
-     ! Differentiation entre precipitation liquide et solide 
-     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  
+!        S'il y a des precipitations
+         IF (zrfl(i)+zifl(i).GT.0.) THEN
      
-     ! Evap max pour ne pas saturer la fraction sous le nuage
+        ! Evap max pour ne pas saturer la fraction sous le nuage
          zqev0 = MAX (0.0, (zqs(i)-zq(i))*zneb(i) )
-     !    zqev0 = MAX (0.0, zqs(i)-zq(i) ) 
-
-     !JAM !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-     ! On differencie qsat pour l'eau et la glace
-     ! Si zdelta=1. --> glace
-     ! Si zdelta=0. --> eau liquide
-     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+         !JAM
+         ! On differencie qsat pour l'eau et la glace
+         ! Si zdelta=1. --> glace
+         ! Si zdelta=0. --> eau liquide
         
          ! Calcul du qsat par rapport a l'eau liquide
@@ -417,6 +490,5 @@
          qsl= qsl*zcor
          
-         ! Calcul de l'evaporation du flux de precip herite
-         !   d'au-dessus
+         ! Calcul de l'evaporation du flux de precip venant du dessus
          ! Formulation en racine du flux de precip
          ! (Klemp & Wilhelmson, 1978; Sundqvist, 1988)
@@ -425,5 +497,4 @@
          zqevt = MAX(0.0,MIN(zqevt,zrfl(i))) &
               *RG*dtime/(paprs(i,k)-paprs(i,k+1)) 
-
          
          ! Calcul du qsat par rapport a la glace
@@ -440,21 +511,21 @@
               *RG*dtime/(paprs(i,k)-paprs(i,k+1))   
 
-              
-     !JAM!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-     ! Verification sur l'evaporation
-     ! On s'assure qu'on ne sature pas 
-     ! la fraction sous le nuage sinon on
-     ! repartit zqev0 en gardant la proportion
-     ! liquide / glace
-     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+        !JAM
+        ! Limitation de l'evaporation. On s'assure qu'on ne sature pas 
+        ! la fraction de la couche sous le nuage sinon on repartit zqev0 
+        ! en conservant la proportion liquide / glace
      
          IF (zqevt+zqevti.GT.zqev0) THEN
-	          zqev=zqev0*zqevt/(zqevt+zqevti)
-	          zqevi=zqev0*zqevti/(zqevt+zqevti)
-             
+            zqev=zqev0*zqevt/(zqevt+zqevti)
+            zqevi=zqev0*zqevti/(zqevt+zqevti)
          ELSE
+!JLD je ne comprends pas les lignes ci-dessous. On repartit les precips
+!       liquides et solides meme si on ne sature pas la couche. 
+!       A mon avis, le test est inutile, et il faudrait tout remplacer par:
+!            zqev=zqevt
+!            zqevi=zqevti
              IF (zqevt+zqevti.GT.0.) THEN
-	          zqev=MIN(zqev0*zqevt/(zqevt+zqevti),zqevt)
-	          zqevi=MIN(zqev0*zqevti/(zqevt+zqevti),zqevti)
+                zqev=MIN(zqev0*zqevt/(zqevt+zqevti),zqevt)
+                zqevi=MIN(zqev0*zqevti/(zqevt+zqevti),zqevti)
              ELSE
              zqev=0.
@@ -471,4 +542,14 @@
          zq(i) = zq(i) - (zrfln(i)+zifln(i)-zrfl(i)-zifl(i)) &
                   * (RG/(paprs(i,k)-paprs(i,k+1)))*dtime
+       if (fl_cor_ebil .GT. 0) then ! avec correction thermalisation des precips
+         zmqc(i) = zmqc(i) + (zrfln(i)+zifln(i)-zrfl(i)-zifl(i)) &
+                  * (RG/(paprs(i,k)-paprs(i,k+1)))*dtime
+         zt(i) = zt(i) + (zrfln(i)-zrfl(i)) &
+                  * (RG/(paprs(i,k)-paprs(i,k+1)))*dtime &
+                  * RLVTT/RCPD/(1.0+RVTMP2*(zq(i)+zmqc(i))) &
+                  + (zifln(i)-zifl(i)) &
+                  * (RG/(paprs(i,k)-paprs(i,k+1)))*dtime &
+                  * RLSTT/RCPD/(1.0+RVTMP2*(zq(i)+zmqc(i)))
+       else ! sans correction thermalisation des precips
          zt(i) = zt(i) + (zrfln(i)-zrfl(i)) &
                   * (RG/(paprs(i,k)-paprs(i,k+1)))*dtime &
@@ -477,5 +558,6 @@
                   * (RG/(paprs(i,k)-paprs(i,k+1)))*dtime &
                   * RLSTT/RCPD/(1.0+RVTMP2*zq(i))
-     
+       end if
+        ! Nouvelles vaeleurs des precips liquides et solides 
          zrfl(i) = zrfln(i)
          zifl(i) = zifln(i)
@@ -486,16 +568,25 @@
 !jyg : Bug !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! jyg
            zmelt = ((zt(i)-273.15)/(ztfondue-273.15))             ! jyg
+           ! fraction de la precip solide qui est fondue
            zmelt = MIN(MAX(zmelt,0.),1.)
            ! Fusion de la glace
            zrfl(i)=zrfl(i)+zmelt*zifl(i)
-           zifl(i)=zifl(i)*(1.-zmelt)
-!           print*,zt(i),'octavio1'
+           if (fl_cor_ebil .LE. 0) then
+             ! the following line should not be here. Indeed, if zifl is modified
+             ! now, zifl(i)*zmelt is no more the amount of ice that has melt
+             ! and therefore the change in temperature computed below is wrong
+             zifl(i)=zifl(i)*(1.-zmelt)
+           end if
            ! Chaleur latente de fusion
+        if (fl_cor_ebil .GT. 0) then ! avec correction thermalisation des precips
+           zt(i)=zt(i)-zifl(i)*zmelt*(RG*dtime)/(paprs(i,k)-paprs(i,k+1)) &
+                      *RLMLT/RCPD/(1.0+RVTMP2*(zq(i)+zmqc(i)))
+        else ! sans correction thermalisation des precips
            zt(i)=zt(i)-zifl(i)*zmelt*(RG*dtime)/(paprs(i,k)-paprs(i,k+1)) &
                       *RLMLT/RCPD/(1.0+RVTMP2*zq(i))
-!           print*,zt(i),zrfl(i),zifl(i),zmelt,'octavio2'
-!fin CR
-
-
+        end if
+           if (fl_cor_ebil .GT. 0) then ! correction bug, deplacement ligne precedente
+             zifl(i)=zifl(i)*(1.-zmelt)
+           end if
 
            ENDIF ! (zrfl(i)+zifl(i).GT.0.)
@@ -515,5 +606,9 @@
            zdelta = MAX(0.,SIGN(1.,RTT-zt(i)))
            zcvm5 = R5LES*RLVTT*(1.-zdelta) + R5IES*RLSTT*zdelta
+       if  (fl_cor_ebil .GT. 0) then ! nouveau
+           zcvm5 = zcvm5 /RCPD/(1.0+RVTMP2*(zq(i)+zmqc(i)))
+       else    
            zcvm5 = zcvm5 /RCPD/(1.0+RVTMP2*zq(i))
+       endif
            zqs(i) = R2ES*FOEEW(zt(i),zdelta)/pplay(i,k)
            zqs(i) = MIN(0.5,zqs(i))
@@ -521,4 +616,6 @@
            zqs(i) = zqs(i)*zcor
            zdqs(i) = FOEDE(zt(i),zdelta,zcvm5,zqs(i),zcor)
+           zdqsdT_raw(i) = zdqs(i)*  &
+         &         RCPD*(1.0+RVTMP2*zq(i)) / (RLVTT*(1.-zdelta) + RLSTT*zdelta)
         ENDDO
      ELSE
@@ -547,7 +644,15 @@
      ! P2> Formation du nuage
      ! ----------------------------------------------------------------
+     ! Variables calculees:
+     !   rneb  : fraction nuageuse
+     !   zcond : eau condensee moyenne dans la maille.
+     !   rhcl: humidite relative ciel-clair
+     !   zt : temperature de la maille
+     ! ----------------------------------------------------------------
+     !
      IF (cpartiel) THEN
-
-        !        print*,'Dans partiel k=',k
+        ! -------------------------
+        ! P2.A> Nuage fractionnaire
+        ! -------------------------
         !
         !   Calcul de l'eau condensee et de la fraction nuageuse et de l'eau
@@ -561,4 +666,7 @@
         !   Version avec les raqts
 
+        ! ----------------------------------------------------------------
+        ! P2.A.0> Calcul des grandeurs nuageuses une pdf en creneau
+        ! ----------------------------------------------------------------
         if (iflag_pdf.eq.0) then
 
@@ -570,7 +678,9 @@
            enddo
 
-        else
-           !
-           !   Version avec les nouvelles PDFs.
+        else !  if (iflag_pdf.eq.0)
+           ! ----------------------------------------------------------------
+           ! P2.A.1> Avec les nouvelles PDFs, calcul des grandeurs nuageuses pour 
+           ! les valeurs de T et Q initiales
+           ! ----------------------------------------------------------------
            do i=1,klon
               if(zq(i).lt.1.e-15) then
@@ -620,4 +730,17 @@
            enddo
 
+        ! ----------------------------------------------------------------
+        ! P2.A.2> Prise en compte du couplage entre eau condensee et T.
+        ! Calcul des grandeurs nuageuses en tenant compte de l'effet de
+        ! la condensation sur T, et donc sur qsat et sur les grandeurs nuageuses
+        ! qui en dependent. Ce changement de temperature est provisoire, et
+        ! la valeur definitive sera calcule plus tard.
+        ! Variables calculees: 
+        !   rneb : nebulosite
+        !   zcond: eau condensee en moyenne dans la maille
+        ! note JLD: si on n'a pas de pdf lognormale, ce qui se passe ne me semble
+        ! pas clair, il n'y a probablement pas de prise en compte de l'effet de
+        ! T sur qsat
+        ! ----------------------------------------------------------------
 
 !Boucle iterative: ATTENTION, l'option -1 n'est plus activable ici
@@ -629,7 +752,19 @@
                do i=1,klon
 !                 do while ((abs(DT(i)).gt.DDT0).or.(n_i(i).eq.0))
+                 ! !! convergence = .true. tant que l'on n'a pas converge !!
+                 ! ------------------------------
                  convergence(i)=abs(DT(i)).gt.DDT0
                  if ((convergence(i).or.(n_i(i).eq.0)).and.lognormale(i)) then
-                 Tbef(i)=Tbef(i)+DT(i) 
+                 ! si on n'a pas converge
+                 !
+                 ! P2.A.2.1> Calcul de la fraction nuageuse et de la quantite d'eau condensee
+                 ! ---------------------------------------------------------------
+                 ! Variables calculees: 
+                 ! rneb : nebulosite
+                 ! zqn : eau condensee, dans le nuage (in cloud water content)
+                 ! zcond: eau condensee en moyenne dans la maille
+                 ! rhcl: humidite relative ciel-clair
+                 !
+                 Tbef(i)=Tbef(i)+DT(i) ! nouvelle temperature
                  if (.not.ice_thermo) then   
                     zdelta = MAX(0.,SIGN(1.,RTT-Tbef(i)))
@@ -641,12 +776,16 @@
                           zdelta = MAX(0.,SIGN(1.,t_glace_max-Tbef(i)))
                        else
-!avec bug : zdelta = MAX(0.,SIGN(1.,t_glace_min-Tbef(i)))
+                          !avec bug : zdelta = MAX(0.,SIGN(1.,t_glace_min-Tbef(i)))
                           zdelta = MAX(0.,SIGN(1.,t_glace_min-Tbef(i)))
                        endif
                     endif
                  endif
-                 ! Calcul des PDF lognormales
+                 ! Calcul de rneb, qzn et zcond pour les PDF lognormales
                  zcvm5 = R5LES*RLVTT*(1.-zdelta) + R5IES*RLSTT*zdelta
+               if (fl_cor_ebil .GT. 0) then
+                 zcvm5 = zcvm5 /RCPD/(1.0+RVTMP2*(zq(i)+zmqc(i)))
+               else
                  zcvm5 = zcvm5 /RCPD/(1.0+RVTMP2*zq(i))
+               end if
                  zqs(i) = R2ES*FOEEW(Tbef(i),zdelta)/pplay(i,k)
                  zqs(i) = MIN(0.5,zqs(i))
@@ -677,11 +816,21 @@
                enddo ! boucle en i
 
+                 ! P2.A.2.2> Calcul APPROCHE de la variation de temperature DT 
+                 !         due a la condensation.
+                 ! ---------------------------------------------------------------
+                 ! Variables calculees: 
+                 ! DT : variation de temperature due a la condensation 
+
                  if (.not. ice_thermo) then
-
+                 ! --------------------------
                  do i=1,klon
                  if ((convergence(i).or.(n_i(i).eq.0)).and.lognormale(i)) then
 
                  qlbef(i)=max(0.,zqn(i)-zqs(i))
+               if (fl_cor_ebil .GT. 0) then
+                 num=-Tbef(i)+zt(i)+rneb(i,k)*RLVTT/RCPD/(1.0+RVTMP2*(zq(i)+zmqc(i)))*qlbef(i)
+               else
                  num=-Tbef(i)+zt(i)+rneb(i,k)*RLVTT/RCPD/(1.0+RVTMP2*zq(i))*qlbef(i)
+               end if
                  denom=1.+rneb(i,k)*zdqs(i)
                  DT(i)=num/denom
@@ -690,6 +839,6 @@
                  enddo
 
-                 else
-                 ! Iteration pour convergence avec qsat(T)
+                 else ! if (.not. ice_thermo)
+                 ! --------------------------
                  if (iflag_t_glace.ge.1) then
                  CALL icefrac_lsc(klon,zt(:),pplay(:,k)/paprs(:,1),zfice(:))
@@ -703,9 +852,11 @@
                     zfice(i) = MIN(MAX(zfice(i),0.0),1.0)
                     zfice(i) = zfice(i)**exposant_glace_old
-                    dzfice(i)= exposant_glace_old * zfice(i)**(exposant_glace_old-1) / (t_glace_min_old - RTT)
+                    dzfice(i)= exposant_glace_old * zfice(i)**(exposant_glace_old-1) &
+          &                     / (t_glace_min_old - RTT)
                  endif
                  
                  if (iflag_t_glace.ge.1) then
-                 dzfice(i)= exposant_glace * zfice(i)**(exposant_glace-1) / (t_glace_min - t_glace_max)
+                 dzfice(i)= exposant_glace * zfice(i)**(exposant_glace-1) &
+          &                    / (t_glace_min - t_glace_max)
                  endif
                
@@ -721,7 +872,16 @@
 
                  qlbef(i)=max(0.,zqn(i)-zqs(i))
-                 num=-Tbef(i)+zt(i)+rneb(i,k)*((1-zfice(i))*RLVTT+zfice(i)*RLSTT)/RCPD/(1.0+RVTMP2*zq(i))*qlbef(i)
-                 denom=1.+rneb(i,k)*((1-zfice(i))*RLVTT+zfice(i)*RLSTT)/cste*zdqs(i) &
+               if (fl_cor_ebil .GT. 0) then
+                 num = -Tbef(i)+zt(i)+rneb(i,k)*((1-zfice(i))*RLVTT &
+           &          +zfice(i)*RLSTT)/RCPD/(1.0+RVTMP2*(zq(i)+zmqc(i)))*qlbef(i)
+                 denom = 1.+rneb(i,k)*((1-zfice(i))*RLVTT+zfice(i)*RLSTT)/cste*zdqs(i) &
+                         -(RLSTT-RLVTT)/RCPD/(1.0+RVTMP2*(zq(i)+zmqc(i)))*rneb(i,k)    &
+           &               *qlbef(i)*dzfice(i)
+               else
+                 num = -Tbef(i)+zt(i)+rneb(i,k)*((1-zfice(i))*RLVTT &
+           &         +zfice(i)*RLSTT)/RCPD/(1.0+RVTMP2*zq(i))*qlbef(i)
+                 denom = 1.+rneb(i,k)*((1-zfice(i))*RLVTT+zfice(i)*RLSTT)/cste*zdqs(i) &
                          -(RLSTT-RLVTT)/RCPD/(1.0+RVTMP2*zq(i))*rneb(i,k)*qlbef(i)*dzfice(i)
+               end if
                  DT(i)=num/denom
                  n_i(i)=n_i(i)+1
@@ -732,16 +892,13 @@
                  endif !ice_thermo
 
-!                 endif
-!               enddo
-  
-          
              enddo ! iter=1,iflag_fisrtilp_qsat+1
              ! Fin d'iteration pour condensation avec variation de qsat(T) 
              ! -----------------------------------------------------------
-           endif
-
+           endif !  if (iflag_fisrtilp_qsat.ge.0)
+     ! ----------------------------------------------------------------
+     ! Fin de P2.A.2> la prise en compte du couplage entre eau condensee et T
+     ! ----------------------------------------------------------------
 
         endif ! iflag_pdf
-
 
 !        if (iflag_fisrtilp_qsat.eq.-1) then 
@@ -771,9 +928,17 @@
 
 !        ELSE
-
-        ! Calcul de l'eau in-cloud (zqn),
-        ! moyenne dans la maille (zcond),
-        ! fraction nuageuse (rneb) et
-        ! humidite relative ciel-clair (rhcl)
+        ! ----------------------------------------------------------------
+        ! P2.A.3> Calcul des valeures finales associees a la formation des nuages
+        ! Variables calculees: 
+        !   rneb : nebulosite
+        !   zcond: eau condensee en moyenne dans la maille
+        !   zq : eau vapeur dans la maille
+        !   zt : temperature de la maille
+        !   rhcl: humidite relative ciel-clair
+        ! ----------------------------------------------------------------
+        !
+        ! Bornage de l'eau in-cloud (zqn) et de la fraction nuageuse (rneb) 
+        ! Calcule de l'eau condensee moyenne dans la maille (zcond),
+        ! et de l'humidite relative ciel-clair (rhcl)
         DO i=1,klon
            IF (rneb(i,k) .LE. 0.0) THEN
@@ -793,9 +958,11 @@
         ENDDO
 
-
 !        ENDIF
 
      ELSE ! de IF (cpartiel) 
-        ! Cas "tout ou rien"
+        ! -------------------------
+        ! P2.B> Nuage "tout ou rien"
+        ! -------------------------
+        ! note JLD: attention, rhcl non calcule. Ca peut avoir des consequences?
         DO i = 1, klon
            IF (zq(i).GT.zqs(i)) THEN
@@ -806,10 +973,8 @@
            zcond(i) = MAX(0.0,zq(i)-zqs(i))/(1.+zdqs(i))
         ENDDO
-     ENDIF
-     ! ----------------------------------------------------------------
-     ! Fin de formation du nuage
-     ! ----------------------------------------------------------------
+     ENDIF ! de IF (cpartiel) 
      !
      ! Mise a jour vapeur d'eau
+     ! -------------------------
      DO i = 1, klon
         zq(i) = zq(i) - zcond(i)
@@ -817,6 +982,10 @@
      ENDDO
 !AJ<
-     ! Chaleur latente apres formation nuage
+     ! ------------------------------------
+     ! P2.C> Prise en compte de la Chaleur latente apres formation nuage
      ! -------------------------------------
+     ! Variable calcule:
+     !   zt : temperature de la maille
+     !
      IF (.NOT. ice_thermo) THEN
         if (iflag_fisrtilp_qsat.lt.1) then
@@ -826,5 +995,9 @@
         else if (iflag_fisrtilp_qsat.gt.0) then
            DO i= 1, klon
+    if (fl_cor_ebil .GT. 0) then
+             zt(i) = zt(i) + zcond(i) * RLVTT/RCPD/(1.0+RVTMP2*(zq(i)+zmqc(i)+zcond(i)))
+    else
              zt(i) = zt(i) + zcond(i) * RLVTT/RCPD/(1.0+RVTMP2*(zq(i)+zcond(i)))
+    end if
            ENDDO
         endif
@@ -856,6 +1029,12 @@
                     zfice(i) = zfice(i)**exposant_glace_old
               endif
+        if (fl_cor_ebil .GT. 0) then
+              zt(i) = zt(i) + (1.-zfice(i))*zcond(i) & 
+           &             * RLVTT/RCPD/(1.0+RVTMP2*(zq(i)+zmqc(i)+zcond(i))) &
+                      +zfice(i)*zcond(i) * RLSTT/RCPD/(1.0+RVTMP2*(zq(i)+zmqc(i)+zcond(i)))
+        else 
               zt(i) = zt(i) + (1.-zfice(i))*zcond(i) * RLVTT/RCPD/(1.0+RVTMP2*(zq(i)+zcond(i))) &
-                       +zfice(i)*zcond(i) * RLSTT/RCPD/(1.0+RVTMP2*(zq(i)+zcond(i)))
+                      +zfice(i)*zcond(i) * RLSTT/RCPD/(1.0+RVTMP2*(zq(i)+zcond(i)))
+        end if
            ENDDO
          endif
@@ -863,4 +1042,5 @@
        ENDIF
 !>AJ
+
      ! ----------------------------------------------------------------
      ! P3> Formation des precipitations
@@ -958,4 +1138,8 @@
      !         zoliqp = MAX(zoliq(i)*(1.-zfice(i))-1.*zpluie   , 0.0)
      !         zoliqi = MAX(zoliq(i)*zfice(i)-1.*zice   , 0.0)
+!JLD : les 2 variables zoliqp et zoliqi crorresponent a des pseudo precip
+!      temporaires et ne doivent pas etre calcule (alors qu'elles le sont
+!      si iflag_bergeron <> 2
+!      A SUPPRIMER A TERME
               zoliqp(i) = MAX(zoliq(i)*(1.-zfice(i))-1.*zpluie  , 0.0)
               zoliqi(i) = MAX(zoliq(i)*zfice(i)-1.*zice  , 0.0)
@@ -966,4 +1150,5 @@
         ENDDO  ! i = 1,klon
      ENDDO     ! n = 1,ninter
+
      ! ----------------------------------------------------------------
      !
@@ -994,4 +1179,26 @@
              zqpreci(i)=(zcond(i)-zoliq(i))*zfice(i)
              zqprecl(i)=(zcond(i)-zoliq(i))*(1.-zfice(i))
+           if (fl_cor_ebil .GT. 0) then
+             zcp=RCPD*(1.0+RVTMP2*(zq(i)+zmqc(i)+zcond(i)))
+             coef1 = rneb(i,k)*RLSTT/zcp*zdqsdT_raw(i)
+!            Calcul de DT si toute les precips liquides congelent
+             DeltaT = RLMLT*zqprecl(i) / (zcp*(1.+coef1))
+!            On ne veut pas que T devienne superieur a la temp. de congelation.
+!            donc que Delta > RTT-zt(i
+             DeltaT = max( min( RTT-zt(i), DeltaT) , 0. )
+             zt(i)      = zt(i)      + DeltaT
+!            Eau vaporisee du fait de l'augmentation de T
+             Deltaq = rneb(i,k)*zdqsdT_raw(i)*DeltaT
+!            on reajoute cette eau vaporise a la vapeur et on l'enleve des precips
+             zq(i) = zq(i) +  Deltaq
+!            Les 3 max si dessous prtotegent uniquement des erreurs d'arrondies
+             zcond(i)   = max( zcond(i)- Deltaq, 0. )
+!            precip liquide qui congele ou qui s'evapore
+             Deltaqprecl = -zcp/RLMLT*(1.+coef1)*DeltaT
+             zqprecl(i) = max( zqprecl(i) + Deltaqprecl, 0. )
+!            bilan eau glacee
+             zqpreci(i) = max (zqpreci(i) - Deltaqprecl - Deltaq, 0.)
+           else ! if (fl_cor_ebil .GT. 0)
+!            ancien calcul
              zcp=RCPD*(1.0+RVTMP2*(zq(i)+zcond(i)))
              coef1 = RLMLT*zdqs(i)/RLVTT
@@ -1002,4 +1209,5 @@
              zq(i)      = zq(i)      + zcp/RLVTT*zdqs(i)*DeltaT
              zt(i)      = zt(i)      + DeltaT
+           end if ! if (fl_cor_ebil .GT. 0)
            ENDIF  ! rneb(i,k) .GT. 0.0
          ENDDO
@@ -1021,11 +1229,12 @@
          IF (rneb(i,k).GT.0.0) THEN
 !CR on prend en compte la phase glace
-           if (.not.ice_thermo) then
-           d_ql(i,k) = zoliq(i)
-           d_qi(i,k) = 0.
-           else
+!JLD inutile car on ne passe jamais ici si .not.ice_thermo
+!           if (.not.ice_thermo) then
+!           d_ql(i,k) = zoliq(i)
+!           d_qi(i,k) = 0.
+!           else
            d_ql(i,k) = (1-zfice(i))*zoliq(i)
            d_qi(i,k) = zfice(i)*zoliq(i)
-           endif
+!           endif
 !AJ<
            zrfl(i) = zrfl(i)+ MAX(zcond(i)*(1.-zfice(i))-zoliqp(i),0.0) &
@@ -1043,6 +1252,11 @@
               zifl(i) = zifl(i)+zrfl(i)
               zrfl(i) = 0.
+           if (fl_cor_ebil .GT. 0) then
+              zt(i)=zt(i)+zsolid*(RG*dtime)/(paprs(i,k)-paprs(i,k+1)) &
+                      *(RLSTT-RLVTT)/RCPD/(1.0+RVTMP2*(zq(i)+zmqc(i)))
+           else
               zt(i)=zt(i)+zsolid*(RG*dtime)/(paprs(i,k)-paprs(i,k+1)) &
                       *(RLSTT-RLVTT)/RCPD/(1.0+RVTMP2*zq(i))
+           end if
            ENDIF  ! (iflag_bergeron .EQ. 1) .AND. (zt(i) .LT. 273.15)
 !RC   
@@ -1094,5 +1308,4 @@
      ! Fin de formation des precipitations
      ! ----------------------------------------------------------------
-     !
      !
      ! Calculer les tendances de q et de t:
@@ -1202,7 +1415,7 @@
      DO i = 1, klon
         zcpair=RCPD*(1.0+RVTMP2*(q(i,k)+d_q(i,k)))
-        zmair=(paprs(i,k)-paprs(i,k+1))/RG
+        zmair(i)=(paprs(i,k)-paprs(i,k+1))/RG
         zm_solid = (prfl(i,k)-prfl(i,k+1)+psfl(i,k)-psfl(i,k+1))*dtime
-        d_t(i,k) = d_t(i,k) + zlh_solid(i) *zm_solid / (zcpair*zmair)
+        d_t(i,k) = d_t(i,k) + zlh_solid(i) *zm_solid / (zcpair*zmair(i))
      END DO
   END DO
Index: LMDZ5/branches/testing/libf/phylmd/iophys.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/iophys.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/iophys.F90	(revision 2839)
@@ -1,2 +1,7 @@
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! Interface pour ecrire en netcdf avec les routines d'enseignement
+! iotd de Frederic Hourdin
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
       subroutine iophys_ecrit(nom,lllm,titre,unite,px)
 
@@ -62,4 +67,45 @@
       end
 
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! Version avec reindexation pour appeler depuis les routines internes
+! à la sous surface
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+    subroutine iophys_ecrit_index(nom,lllm,titre,unite,knon,knindex,px)
+
+    USE mod_phys_lmdz_para, ONLY: klon_omp
+    USE dimphy, ONLY : klon
+    USE mod_grid_phy_lmdz, ONLY: klon_glo
+    IMPLICIT NONE
+
+! This subroutine returns the sea surface temperature already read from limit.nc
+!
+
+! Arguments on input:
+    INTEGER lllm
+    CHARACTER (len=*) :: nom,titre,unite
+    REAL px(klon_omp,lllm)
+    INTEGER, INTENT(IN)                  :: knon     ! nomber of points on compressed grid
+    INTEGER, DIMENSION(klon), INTENT(IN) :: knindex  ! grid point number for compressed grid
+    REAL, DIMENSION(klon,lllm) :: varout
+
+    INTEGER :: i,l
+
+    IF (klon/=klon_omp) THEN
+      print*,'klon, klon_omp',klon,klon_omp
+      STOP'probleme de dimension parallele'
+    ENDIF
+
+    varout(1:klon,1:lllm)=0.
+    DO l = 1, lllm
+    DO i = 1, knon
+       varout(knindex(i),l) = px(i,l)
+    END DO
+    END DO
+    CALL iophys_ecrit(nom,lllm,titre,unite,varout)
+
+  END SUBROUTINE iophys_ecrit_index
+
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       SUBROUTINE iophys_ini
@@ -68,4 +114,5 @@
       USE regular_lonlat_mod, ONLY: lon_reg, lat_reg
       USE dimphy, ONLY: klev
+      USE mod_grid_phy_lmdz, ONLY: klon_glo
 
       IMPLICIT NONE
@@ -88,4 +135,5 @@
 
 real pi
+INTEGER nlat_eff
 
 !   Arguments:
@@ -94,8 +142,16 @@
 !$OMP MASTER
     IF (is_mpi_root) THEN       
+
+! Bidouille pour gerer le fait que lat_reg contient deux latitudes
+! en version uni-dimensionnelle (chose qui pourrait être résolue
+! par ailleurs)
+IF (klon_glo==1) THEN
+   nlat_eff=1
+ELSE
+   nlat_eff=size(lat_reg)
+ENDIF
 pi=2.*asin(1.)
 call iotd_ini('phys.nc   ', &
-!iim,jjp1,llm,rlonv(1:iim)*180./pi,rlatu*180./pi,presnivs)
-size(lon_reg),size(lat_reg),klev,lon_reg(:)*180./pi,lat_reg*180./pi,presnivs)
+size(lon_reg),nlat_eff,klev,lon_reg(:)*180./pi,lat_reg*180./pi,presnivs)
     ENDIF
 !$OMP END MASTER
Index: LMDZ5/branches/testing/libf/phylmd/limit_read_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/limit_read_mod.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/limit_read_mod.F90	(revision 2839)
@@ -223,5 +223,5 @@
           ierr=NF90_INQUIRE(nid, UnlimitedDimID=ndimid)
           ierr=NF90_INQUIRE_DIMENSION(nid, ndimid, len=nn)
-          WRITE(abort_message,'(a,2(i0,a))')'limit.nc records number (',nn,') does no'//&
+          WRITE(abort_message,'(a,2(i3,a))')'limit.nc records number (',nn,') does no'//&
             't match year length (',year_len,')'
           IF(nn/=year_len) CALL abort_physic(modname,abort_message,1)
Index: LMDZ5/branches/testing/libf/phylmd/open_climoz_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/open_climoz_m.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/open_climoz_m.F90	(revision 2839)
@@ -1,73 +1,101 @@
 ! $Id$
-module open_climoz_m
+MODULE open_climoz_m
 
-  implicit none
+  USE print_control_mod, ONLY: lunout
+  IMPLICIT NONE
 
-contains
+CONTAINS
 
-  subroutine open_climoz(ncid, press_in_edg)
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE open_climoz(ncid, press_in_cen, press_in_edg, time_in, daily, adjust)
+!
+!-------------------------------------------------------------------------------
+  USE netcdf95, ONLY: nf95_open, nf95_close, nf95_gw_var, nf95_inq_varid
+  USE netcdf,   ONLY: nf90_nowrite
+  USE mod_phys_lmdz_mpi_data,      ONLY: is_mpi_root
+  USE mod_phys_lmdz_mpi_transfert, ONLY: bcast_mpi
+  USE phys_cal_mod,                ONLY: calend, year_len, year_cur
+!-------------------------------------------------------------------------------
+! Purpose: This procedure should be called once per "gcm" run, by a single
+!          thread of each MPI process.
+!          The root MPI process opens "climoz_LMDZ.nc", reads the pressure
+! levels and the times and broadcasts them to the other processes.
+!          We assume that, in "climoz_LMDZ.nc", the pressure levels are in hPa
+! and in strictly ascending order.
+!-------------------------------------------------------------------------------
+! Arguments (OpenMP shared):
+  INTEGER, INTENT(OUT):: ncid      !--- "climoz_LMDZ.nc" identifier
+  REAL, POINTER :: press_in_cen(:) !--- at cells centers
+  REAL, POINTER :: press_in_edg(:) !--- at the interfaces (pressure intervals)
+  REAL, POINTER :: time_in(:)      !--- records times, in days since Jan. 1st
+  LOGICAL, INTENT(IN) :: daily     !--- daily files (calendar dependent days nb)
+  LOGICAL, INTENT(IN) :: adjust    !--- tropopause adjustement required
+!   pressure levels press_in_cen/edg are in Pa a,d strictly ascending order.
+!   time_in is only used for monthly files (14 records)
+!-------------------------------------------------------------------------------
+! Local variables:
+  INTEGER :: varid                 !--- NetCDF variables identifier
+  INTEGER :: nlev, ntim            !--- pressure levels and time records numbers
+  CHARACTER(LEN=80)  :: sub
+  CHARACTER(LEN=320) :: msg
+!-------------------------------------------------------------------------------
+  sub="open_climoz"
+  WRITE(lunout,*)"Entering routine "//TRIM(sub)
 
-    ! This procedure should be called once per "gcm" run, by a single
-    ! thread of each MPI process.
-    ! The root MPI process opens "climoz_LMDZ.nc", reads the pressure
-    ! levels and broadcasts them to the other processes.
+  IF(is_mpi_root) THEN
 
-    ! We assume that, in "climoz_LMDZ.nc", the pressure levels are in hPa
-    ! and in strictly ascending order.
+    !--- OPEN FILE, READ PRESSURE LEVELS AND TIME VECTOR
+    CALL nf95_open("climoz_LMDZ.nc", nf90_nowrite, ncid)
+    CALL nf95_inq_varid(ncid, "plev", varid)
+    CALL nf95_gw_var(ncid, varid, press_in_cen)
+    ! Convert from hPa to Pa because "paprs" and "pplay" are in Pa:
+    press_in_cen = press_in_cen * 100.
+    nlev = SIZE(press_in_cen)
+    CALL NF95_INQ_VARID(ncID, "time", varID)
+    CALL NF95_GW_VAR(ncid, varid, time_in)
+    ntim = SIZE(time_in)
 
-    use netcdf95, only: nf95_open, nf95_close, nf95_gw_var, nf95_inq_varid
-    use netcdf, only: nf90_nowrite
+    !--- BUILD EDGES OF PRESSURE INTERVALS: HALFWAY IN LOGARITHMS
+    ALLOCATE(press_in_edg(nlev+1))
+    press_in_edg=[0.,SQRT(press_in_cen(1:nlev-1)*press_in_cen(2:nlev)),HUGE(0.)]
 
-    use mod_phys_lmdz_mpi_data, only: is_mpi_root
-    use mod_phys_lmdz_mpi_transfert, only: bcast_mpi ! broadcast
+    !--- CHECK RECORDS NUMBER AND DISPLAY CORRESPONDING INFORMATION
+    IF(daily.AND.ntim/=year_len) THEN
+      WRITE(msg,'(a,3(i4,a))')TRIM(sub)//': Expecting a daily ozone file with',&
+     &year_len,' records (year ',year_cur,') ; found ',ntim,' instead'
+      CALL abort_physic(sub, msg, 1)
+    ELSE IF(ALL([360,14]/=ntim)) THEN
+      WRITE(msg,'(a,i4,a)')TRIM(sub)//': Expecting an ozone file with 14 (mont'&
+     &//'hly case) or 360 (old style files) records ; found ',ntim,' instead'
+      CALL abort_physic(sub, msg, 1)
+    ELSE
+      IF(daily) THEN
+         WRITE(msg,'(a,2(i4,a))')'daily file (',ntim,' days in ',year_cur,')'
+       ELSE IF(ntim==14) THEN
+         msg='14 records monthly file'
+       ELSE
+         msg='360 records files (old convention)'
+       END IF
+      WRITE(lunout,*)TRIM(sub)//': Using a '//TRIM(msg)
+    END IF
 
-    integer, intent(out):: ncid ! of "climoz_LMDZ.nc", OpenMP shared
+    !--- MESSAGE ABOUT OPTIONAL STRETCHING FOR TROPOPAUSES MATCHING
+    IF(adjust) THEN
+      WRITE(lunout,*)TRIM(sub)//': Adjusting O3 field to match gcm tropopause.'
+    ELSE
+      WRITE(lunout,*)TRIM(sub)//': Interpolating O3 field directly on gcm levels.'
+    END IF
 
-    real, pointer:: press_in_edg(:)
-    ! edges of pressure intervals for ozone climatology, in Pa, in strictly
-    ! ascending order, OpenMP shared
+  END IF
+  CALL bcast_mpi(nlev)
+  IF(.NOT.is_mpi_root) ALLOCATE(press_in_cen(nlev  )); CALL bcast_mpi(press_in_cen)
+  IF(.NOT.is_mpi_root) ALLOCATE(press_in_edg(nlev+1)); CALL bcast_mpi(press_in_edg)
+  CALL bcast_mpi(ntim)
+  IF(.NOT.is_mpi_root) ALLOCATE(time_in(ntim));        CALL bcast_mpi(time_in)
 
-    ! Variables local to the procedure:
+END SUBROUTINE open_climoz
+!
+!-------------------------------------------------------------------------------
 
-    real, pointer:: plev(:)
-    ! (pressure levels for ozone climatology, converted to Pa, in strictly
-    ! ascending order)
-
-    integer varid ! for NetCDF
-    integer n_plev ! number of pressure levels in the input data
-    integer k
-
-    !---------------------------------------
-
-    print *, "Call sequence information: open_climoz"
-
-    if (is_mpi_root) then
-       call nf95_open("climoz_LMDZ.nc", nf90_nowrite, ncid)
-
-       call nf95_inq_varid(ncid, "plev", varid)
-       call nf95_gw_var(ncid, varid, plev)
-       ! Convert from hPa to Pa because "paprs" and "pplay" are in Pa:
-       plev = plev * 100.
-       n_plev = size(plev)
-    end if
-
-    call bcast_mpi(n_plev)
-    if (.not. is_mpi_root) allocate(plev(n_plev))
-    call bcast_mpi(plev)
-    
-    ! Compute edges of pressure intervals:
-    allocate(press_in_edg(n_plev + 1))
-    if (is_mpi_root) then
-       press_in_edg(1) = 0.
-       ! We choose edges halfway in logarithm:
-       forall (k = 2:n_plev) press_in_edg(k) = sqrt(plev(k - 1) * plev(k))
-       press_in_edg(n_plev + 1) = huge(0.)
-       ! (infinity, but any value guaranteed to be greater than the
-       ! surface pressure would do)
-    end if
-    call bcast_mpi(press_in_edg)
-    deallocate(plev) ! pointer
-
-  end subroutine open_climoz
-
-end module open_climoz_m
+END MODULE open_climoz_m
Index: LMDZ5/branches/testing/libf/phylmd/phyaqua_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/phyaqua_mod.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/phyaqua_mod.F90	(revision 2839)
@@ -339,4 +339,5 @@
     PRINT *, 'iniaqua: before phyredem'
 
+    pbl_tke(:,:,:)=1.e-8
     falb1 = albedo
     falb2 = albedo
@@ -354,4 +355,8 @@
     entr_therm = 0.
     detr_therm = 0.
+    ale_bl = 0.
+    ale_bl_trig =0. 
+    alp_bl =0.
+
 
 
Index: LMDZ5/branches/testing/libf/phylmd/phys_cal_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/phys_cal_mod.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/phys_cal_mod.F90	(revision 2839)
@@ -9,5 +9,5 @@
   INTEGER,SAVE :: day_cur       ! current day
 !$OMP THREADPRIVATE(day_cur)
-  INTEGER,SAVE :: days_elapsed  ! number of whole days since start of the simulation 
+  INTEGER,SAVE :: days_elapsed  ! number of whole days since start of the current year
 !$OMP THREADPRIVATE(days_elapsed)
   INTEGER,SAVE :: mth_len       ! number of days in the current month
@@ -33,11 +33,12 @@
 !$OMP THREADPRIVATE(calend)
 
-
 CONTAINS
   
   SUBROUTINE phys_cal_init(annee_ref,day_ref)
-  USE IOIPSL, ONLY:  ymds2ju
-  USE ioipsl_getin_p_mod, ONLY: getin_p
-  IMPLICIT NONE
+
+    USE IOIPSL, ONLY:  ymds2ju
+    USE ioipsl_getin_p_mod, ONLY: getin_p
+
+    IMPLICIT NONE
     INTEGER,INTENT(IN) :: annee_ref
     INTEGER,INTENT(IN) :: day_ref
@@ -79,3 +80,2 @@
 
 END MODULE phys_cal_mod
-
Index: LMDZ5/branches/testing/libf/phylmd/phys_local_var_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/phys_local_var_mod.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/phys_local_var_mod.F90	(revision 2839)
@@ -163,4 +163,6 @@
       REAL, SAVE, ALLOCATABLE :: lcc3dstra(:,:)
       !$OMP THREADPRIVATE(lcc3dstra)
+      REAL, SAVE, ALLOCATABLE :: od443aer(:) 
+      !$OMP THREADPRIVATE(od443aer) 
       REAL, SAVE, ALLOCATABLE :: od550aer(:) 
       !$OMP THREADPRIVATE(od550aer) 
@@ -207,4 +209,6 @@
       REAL, SAVE, ALLOCATABLE :: loaddust(:) 
       !$OMP THREADPRIVATE(loaddust) 
+      REAL, SAVE, ALLOCATABLE :: loadno3(:) 
+      !$OMP THREADPRIVATE(loadno3) 
       REAL, SAVE, ALLOCATABLE :: load_tmp1(:) 
       !$OMP THREADPRIVATE(load_tmp1) 
@@ -213,12 +217,4 @@
       REAL, SAVE, ALLOCATABLE :: load_tmp3(:) 
       !$OMP THREADPRIVATE(load_tmp3) 
-      REAL, SAVE, ALLOCATABLE :: load_tmp4(:) 
-      !$OMP THREADPRIVATE(load_tmp4) 
-      REAL, SAVE, ALLOCATABLE :: load_tmp5(:) 
-      !$OMP THREADPRIVATE(load_tmp5) 
-      REAL, SAVE, ALLOCATABLE :: load_tmp6(:) 
-      !$OMP THREADPRIVATE(load_tmp6) 
-      REAL, SAVE, ALLOCATABLE :: load_tmp7(:) 
-      !$OMP THREADPRIVATE(load_tmp7) 
 
 !IM ajout variables CFMIP2/CMIP5
@@ -352,6 +348,6 @@
 !>jyg+nrlmd
   !
-      REAL,ALLOCATABLE,SAVE,DIMENSION(:) :: wbeff, zmax_th, zq2m, zt2m
-!$OMP THREADPRIVATE(wbeff, zmax_th, zq2m, zt2m)
+      REAL,ALLOCATABLE,SAVE,DIMENSION(:) :: wbeff, convoccur, zmax_th, zq2m, zt2m
+!$OMP THREADPRIVATE(wbeff, convoccur, zmax_th, zq2m, zt2m)
       REAL,ALLOCATABLE,SAVE,DIMENSION(:) :: zt2m_min_mon, zt2m_max_mon
 !$OMP THREADPRIVATE(zt2m_min_mon, zt2m_max_mon)
@@ -487,4 +483,6 @@
 !$OMP THREADPRIVATE(budg_sed_part)
 #endif
+      REAL, ALLOCATABLE, SAVE, DIMENSION(:) :: pr_tropopause
+!$OMP THREADPRIVATE(pr_tropopause)
 
 CONTAINS
@@ -578,4 +576,5 @@
       allocate(lcc3dcon(klon, klev))
       allocate(lcc3dstra(klon, klev))
+      allocate(od443aer(klon))
       allocate(od550aer(klon))
       allocate(od865aer(klon))
@@ -600,11 +599,8 @@
       allocate(loadss(klon))
       allocate(loaddust(klon))
+      allocate(loadno3(klon))
       allocate(load_tmp1(klon))
       allocate(load_tmp2(klon))
       allocate(load_tmp3(klon))
-      allocate(load_tmp4(klon))
-      allocate(load_tmp5(klon))
-      allocate(load_tmp6(klon))
-      allocate(load_tmp7(klon))
 
 !IM ajout variables CFMIP2/CMIP5
@@ -628,4 +624,5 @@
 !!          Wake variables
       ALLOCATE(ale_wake(klon), alp_wake(klon))
+      ale_wake(:)=0.
       ALLOCATE(wake_h(klon),wake_k(klon))
       ALLOCATE(wake_omg(klon, klev))
@@ -677,5 +674,5 @@
       ALLOCATE(kh(klon), kh_x(klon), kh_w(klon))
 !
-      ALLOCATE(wbeff(klon), zmax_th(klon))
+      ALLOCATE(wbeff(klon), convoccur(klon), zmax_th(klon))
       ALLOCATE(zq2m(klon), zt2m(klon), weak_inversion(klon))
       ALLOCATE(zt2m_min_mon(klon), zt2m_max_mon(klon))
@@ -764,4 +761,5 @@
       ALLOCATE (vsed_aer(klon,klev))
 #endif
+      ALLOCATE (pr_tropopause(klon))
 
 END SUBROUTINE phys_local_var_init
@@ -837,4 +835,5 @@
       deallocate(lcc3dcon)
       deallocate(lcc3dstra)
+      deallocate(od443aer)
       deallocate(od550aer)
       deallocate(od865aer)
@@ -859,11 +858,8 @@
       deallocate(loadss) 
       deallocate(loaddust) 
+      deallocate(loadno3) 
       deallocate(load_tmp1)
       deallocate(load_tmp2)
       deallocate(load_tmp3)
-      deallocate(load_tmp4)
-      deallocate(load_tmp5)
-      deallocate(load_tmp6)
-      deallocate(load_tmp7)
       deallocate(du_gwd_hines,dv_gwd_hines,d_t_hin)
       deallocate(d_q_ch4)
@@ -935,5 +931,5 @@
       DEALLOCATE(kh, kh_x, kh_w)
 !
-      DEALLOCATE(wbeff, zmax_th)
+      DEALLOCATE(wbeff, convoccur, zmax_th)
       DEALLOCATE(zq2m, zt2m, weak_inversion)
       DEALLOCATE(zt2m_min_mon, zt2m_max_mon)
@@ -1018,4 +1014,5 @@
       DEALLOCATE (budg_sed_part)
 #endif
+      DEALLOCATE (pr_tropopause)
 
 END SUBROUTINE phys_local_var_end
Index: LMDZ5/branches/testing/libf/phylmd/phys_output_ctrlout_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/phys_output_ctrlout_mod.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/phys_output_ctrlout_mod.F90	(revision 2839)
@@ -669,4 +669,6 @@
   TYPE(ctrl_out), SAVE :: o_wbeff = ctrl_out((/ 1, 10, 10, 10, 10, 10, 11, 11, 11, 11/), &
     'wbeff', 'Conv. updraft velocity at LFC (<100)', 'm/s', (/ ('', i=1, 10) /))
+  TYPE(ctrl_out), SAVE :: o_convoccur = ctrl_out((/ 1, 10, 10, 10, 10, 10, 11, 11, 11, 11/), &
+    'convoccur', 'Convective occurence', '', (/ ('', i=1, 10) /))
   TYPE(ctrl_out), SAVE :: o_prw = ctrl_out((/ 1, 1, 10, 10, 10, 10, 11, 11, 11, 11/), &
     'prw', 'Precipitable water', 'kg/m2', (/ ('', i=1, 10) /))
@@ -1092,4 +1094,6 @@
     'OD_10um_STRAT', 'Stratospheric Aerosol Optical depth at 10 um ', '1', (/ ('', i=1, 10) /))
 !
+  TYPE(ctrl_out), SAVE :: o_od443aer = ctrl_out((/ 2, 6, 10, 10, 10, 10, 11, 11, 11, 11/), &
+    'od443aer', 'Total aerosol optical depth at 440nm', '-', (/ ('', i=1, 10) /))
   TYPE(ctrl_out), SAVE :: o_od550aer = ctrl_out((/ 2, 6, 10, 10, 10, 10, 11, 11, 11, 11/), &
     'od550aer', 'Total aerosol optical depth at 550nm', '-', (/ ('', i=1, 10) /))
@@ -1134,4 +1138,6 @@
   TYPE(ctrl_out), SAVE :: o_loaddust = ctrl_out((/ 2, 6, 10, 10, 10, 10, 11, 11, 11, 11/), &
     'loaddust', 'Column Load of Dust ', 'kg/m2', (/ ('', i=1, 10) /))
+  TYPE(ctrl_out), SAVE :: o_loadno3 = ctrl_out((/ 2, 6, 10, 10, 10, 10, 11, 11, 11, 11/), &
+    'loadno3', 'Column Load of Nitrate ', 'kg/m2', (/ ('', i=1, 10) /))
   TYPE(ctrl_out), SAVE :: o_swtoaas_nat = ctrl_out((/ 4, 6, 10, 10, 10, 10, 11, 11, 11, 11/), &
     'swtoaas_nat', 'Natural aerosol radiative forcing all-sky at TOA', 'W/m2', (/ ('', i=1, 10) /))
Index: LMDZ5/branches/testing/libf/phylmd/phys_output_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/phys_output_mod.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/phys_output_mod.F90	(revision 2839)
@@ -5,5 +5,4 @@
   USE indice_sol_mod
   USE phys_output_var_mod
-  USE aero_mod, only : naero_spc,name_aero
   USE phys_output_write_mod, ONLY : phys_output_write
   REAL, DIMENSION(nfiles),SAVE :: ecrit_files
@@ -40,5 +39,4 @@
     USE phys_cal_mod, only : hour, calend
     USE mod_phys_lmdz_para
-    USE aero_mod, only : naero_spc,name_aero
     !Martin
     USE surface_data, ONLY : ok_snow
@@ -46,5 +44,5 @@
     USE mod_grid_phy_lmdz, only: klon_glo,nbp_lon,nbp_lat
     USE print_control_mod, ONLY: prt_level,lunout
-    USE vertical_layers_mod, ONLY: ap,bp,preff,presnivs
+    USE vertical_layers_mod, ONLY: ap,bp,preff,presnivs, aps, bps, pseudoalt
     USE time_phylmdz_mod, ONLY: day_ini, itau_phy, start_time, annee_ref, day_ref
 #ifdef CPP_XIOS
@@ -95,5 +93,4 @@
     INTEGER                               :: idayref
     REAL                                  :: zjulian_start, zjulian
-    REAL, DIMENSION(klev)                 :: Ahyb, Bhyb, Alt
     CHARACTER(LEN=4), DIMENSION(nlevSTD)  :: clevSTD
     REAL, DIMENSION(nlevSTD)              :: rlevSTD
@@ -293,15 +290,4 @@
     zdtime_moy = dtime         ! Frequence ou l on moyenne
 
-    ! Calcul des Ahyb, Bhyb et Alt
-    DO k=1,klev
-       Ahyb(k)=(ap(k)+ap(k+1))/2.
-       Bhyb(k)=(bp(k)+bp(k+1))/2.
-       Alt(k)=log(preff/presnivs(k))*8.
-    ENDDO
-    !          if(prt_level.ge.1) then
-    WRITE(lunout,*)'Ap Hybrid = ',Ahyb(1:klev)
-    WRITE(lunout,*)'Bp Hybrid = ',Bhyb(1:klev)
-    WRITE(lunout,*)'Alt approx des couches pour une haut d echelle de 8km = ',Alt(1:klev)
-    !          ENDIF
 
   ecrit_files(7) = ecrit_files(1)
@@ -345,9 +331,9 @@
             levmax(iff) - levmin(iff) + 1, presnivs(levmin(iff):levmax(iff)))
     CALL wxios_add_vaxis("Ahyb", &
-            levmax(iff) - levmin(iff) + 1, Ahyb)
+            levmax(iff) - levmin(iff) + 1, aps)
     CALL wxios_add_vaxis("Bhyb", &
-            levmax(iff) - levmin(iff) + 1, Bhyb)
+            levmax(iff) - levmin(iff) + 1, bps)
     CALL wxios_add_vaxis("Alt", &
-            levmax(iff) - levmin(iff) + 1, Alt)
+            levmax(iff) - levmin(iff) + 1, pseudoalt)
    ELSE
     ! NMC files
@@ -418,11 +404,11 @@
 !!!! Composantes de la coordonnee sigma-hybride 
           CALL histvert(nid_files(iff), "Ahyb","Ahyb comp of Hyb Cord ", "Pa", &
-               levmax(iff) - levmin(iff) + 1,Ahyb,nvertap(iff))
+               levmax(iff) - levmin(iff) + 1,aps,nvertap(iff))
 
           CALL histvert(nid_files(iff), "Bhyb","Bhyb comp of Hyb Cord", " ", &
-               levmax(iff) - levmin(iff) + 1,Bhyb,nvertbp(iff))
+               levmax(iff) - levmin(iff) + 1,bps,nvertbp(iff))
 
           CALL histvert(nid_files(iff), "Alt","Height approx for scale heigh of 8km at levels", "Km", &                       
-               levmax(iff) - levmin(iff) + 1,Alt,nvertAlt(iff))
+               levmax(iff) - levmin(iff) + 1,pseudoalt,nvertAlt(iff))
 
           ELSE
Index: LMDZ5/branches/testing/libf/phylmd/phys_output_var_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/phys_output_var_mod.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/phys_output_var_mod.F90	(revision 2839)
@@ -24,4 +24,17 @@
   REAL, SAVE, ALLOCATABLE :: bils_latent(:) ! bilan de chaleur au sol
   !$OMP THREADPRIVATE(bils_ec,bils_ech,bils_tke,bils_diss,bils_kinetic,bils_enthalp,bils_latent)
+  ! output variables for energy conservation tests, computed in add_phys_tend
+  REAL, SAVE, ALLOCATABLE :: d_qw_col(:)      ! watter vapour mass budget for each column (kg/m2/s)
+  REAL, SAVE, ALLOCATABLE :: d_ql_col(:)      ! liquid watter mass budget for each column (kg/m2/s)
+  REAL, SAVE, ALLOCATABLE :: d_qs_col(:)      ! solid watter mass budget for each column (kg/m2/s)
+  REAL, SAVE, ALLOCATABLE :: d_qt_col(:)      ! total watter mass budget for each column (kg/m2/s)
+  REAL, SAVE, ALLOCATABLE :: d_ek_col(:)      ! kinetic energy budget for each column (W/m2)
+  REAL, SAVE, ALLOCATABLE :: d_h_dair_col(:)  ! enthalpy budget of dry air for each column (W/m2)
+  REAL, SAVE, ALLOCATABLE :: d_h_qw_col(:)    ! enthalpy budget of watter vapour for each column (W/m2)
+  REAL, SAVE, ALLOCATABLE :: d_h_ql_col(:)    ! enthalpy budget of liquid watter for each column (W/m2)
+  REAL, SAVE, ALLOCATABLE :: d_h_qs_col(:)    ! enthalpy budget of solid watter  for each column (W/m2)
+  REAL, SAVE, ALLOCATABLE :: d_h_col(:)       ! total enthalpy budget for each column (W/m2)
+  !$OMP THREADPRIVATE(d_qw_col, d_ql_col, d_qs_col, d_qt_col, d_ek_col, d_h_dair_col)
+  !$OMP THREADPRIVATE(d_h_qw_col, d_h_ql_col, d_h_qs_col, d_h_col)
 
 ! Marine
@@ -121,4 +134,8 @@
 
     allocate (bils_ec(klon),bils_ech(klon),bils_tke(klon),bils_diss(klon),bils_kinetic(klon),bils_enthalp(klon),bils_latent(klon))
+    allocate (d_qw_col(klon), d_ql_col(klon), d_qs_col(klon), d_qt_col(klon), d_ek_col(klon), d_h_dair_col(klon) &
+  &         , d_h_qw_col(klon), d_h_ql_col(klon), d_h_qs_col(klon), d_h_col(klon))
+    d_qw_col=0. ; d_ql_col=0. ; d_qs_col=0. ; d_qt_col=0. ; d_ek_col=0. ; d_h_dair_col =0.
+    d_h_qw_col=0. ; d_h_ql_col=0. ; d_h_qs_col=0. ; d_h_col=0.
 
 ! Marine
@@ -155,4 +172,6 @@
     deallocate(snow_o,zfra_o,itau_con)
     deallocate (bils_ec,bils_ech,bils_tke,bils_diss,bils_kinetic,bils_enthalp,bils_latent)
+    deallocate (d_qw_col, d_ql_col, d_qs_col, d_qt_col, d_ek_col, d_h_dair_col &
+  &           , d_h_qw_col, d_h_ql_col, d_h_qs_col, d_h_col)
 
 ! Marine
Index: LMDZ5/branches/testing/libf/phylmd/phys_output_write_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/phys_output_write_mod.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/phys_output_write_mod.F90	(revision 2839)
@@ -68,5 +68,5 @@
          o_ue, o_ve, o_uq, o_vq, o_cape, o_pbase, &
          o_ptop, o_fbase, o_plcl, o_plfc, &
-         o_wbeff, o_cape_max, o_upwd, o_ep,o_epmax_diag, o_Ma, &
+         o_wbeff, o_convoccur, o_cape_max, o_upwd, o_ep,o_epmax_diag, o_Ma, &
          o_dnwd, o_dnwd0, o_ftime_con, o_mc, &
          o_prw, o_prlw, o_prsw, o_s_pblh, o_s_pblt, o_s_lcl, &
@@ -99,5 +99,5 @@
          o_SWdownOR, o_LWdownOR, o_snowl, &
          o_solldown, o_dtsvdfo, o_dtsvdft, &
-         o_dtsvdfg, o_dtsvdfi, o_z0m, o_z0h, o_od550aer, &
+         o_dtsvdfg, o_dtsvdfi, o_z0m, o_z0h, o_od443aer, o_od550aer, &
          o_od865aer, o_absvisaer, o_od550lt1aer, &
          o_sconcso4, o_sconcno3, o_sconcoa, o_sconcbc, &
@@ -105,5 +105,5 @@
          o_concoa, o_concbc, o_concss, o_concdust, &
          o_loadso4, o_loadoa, o_loadbc, o_loadss, &
-         o_loaddust, o_tausumaero, o_tausumaero_lw, &
+         o_loaddust, o_loadno3, o_tausumaero, o_tausumaero_lw, &
          o_topswad, o_topswad0, o_solswad, o_solswad0, &
          o_toplwad, o_toplwad0, o_sollwad, o_sollwad0, &
@@ -196,5 +196,5 @@
 #endif
 
-    USE phys_state_var_mod, ONLY: pctsrf, paire_ter, rain_fall, snow_fall, &
+    USE phys_state_var_mod, ONLY: pctsrf, rain_fall, snow_fall, &
          qsol, z0m, z0h, fevap, agesno, &
          nday_rain, rain_con, snow_con, &
@@ -236,5 +236,5 @@
          cldh, cldt, JrNt, cldljn, cldmjn, cldhjn, &
          cldtjn, cldq, flwp, fiwp, ue, ve, uq, vq, &
-         plcl, plfc, wbeff, upwd, dnwd, dnwd0, prw, prlw, prsw, &
+         plcl, plfc, wbeff, convoccur, upwd, dnwd, dnwd0, prw, prlw, prsw, &
          s_pblh, s_pblt, s_lcl, s_therm, uwriteSTD, &
          vwriteSTD, wwriteSTD, phiwriteSTD, qwriteSTD, &
@@ -252,9 +252,9 @@
          weak_inversion, dthmin, cldtau, cldemi, &
          pmflxr, pmflxs, prfl, psfl, re, fl, rh2m, &
-         qsat2m, tpote, tpot, d_ts, od550aer, &
+         qsat2m, tpote, tpot, d_ts, od443aer, od550aer, &
          od865aer, absvisaer, od550lt1aer, sconcso4, sconcno3, &
          sconcoa, sconcbc, sconcss, sconcdust, concso4, concno3, &
          concoa, concbc, concss, concdust, loadso4, &
-         loadoa, loadbc, loadss, loaddust, tausum_aero, &
+         loadoa, loadbc, loadss, loaddust, loadno3, tausum_aero, &
          topswad_aero, topswad0_aero, solswad_aero, &
          solswad0_aero, topsw_aero, solsw_aero, &
@@ -325,5 +325,4 @@
     USE geometry_mod, ONLY: cell_area
     USE surface_data, ONLY: type_ocean, version_ocean, ok_veget, ok_snow
-!    USE aero_mod, ONLY: naero_spc
     USE aero_mod, ONLY: naero_tot, id_STRAT_phy
     USE ioipsl, ONLY: histend, histsync
@@ -410,5 +409,6 @@
 #ifdef CPP_XIOS
 #ifdef CPP_StratAer
-    IF (.NOT.vars_defined) THEN
+!$OMP MASTER
+   IF (.NOT.vars_defined) THEN
           !On ajoute les variables 3D traceurs par l interface fortran 
           CALL xios_get_handle("fields_strataer_trac_3D", group_handle)
@@ -474,7 +474,7 @@
           ENDDO
     ENDIF
-#endif
-#endif
-
+!$OMP END MASTER
+#endif
+#endif
     ! ug la boucle qui suit ne sert qu'une fois, pour l'initialisation, sinon il n'y a toujours qu'un seul passage:
     DO iinit=1, iinitend
@@ -513,5 +513,4 @@
        CALL histwrite_phy(o_contfracATM, zx_tmp_fi2d)
        CALL histwrite_phy(o_contfracOR, pctsrf(:,is_ter))
-       CALL histwrite_phy(o_aireTER, paire_ter)
 !
 #ifdef CPP_XIOS
@@ -739,7 +738,5 @@
        CALL histwrite_phy(o_bils_diss, bils_diss)
        CALL histwrite_phy(o_bils_ec, bils_ec)
-       IF (iflag_ener_conserv>=1) THEN
-         CALL histwrite_phy(o_bils_ech, bils_ech)
-       ENDIF
+       CALL histwrite_phy(o_bils_ech, bils_ech)
        CALL histwrite_phy(o_bils_tke, bils_tke)
        CALL histwrite_phy(o_bils_kinetic, bils_kinetic)
@@ -890,4 +887,5 @@
              CALL histwrite_phy(o_plfc, plfc)
              CALL histwrite_phy(o_wbeff, wbeff)
+             CALL histwrite_phy(o_convoccur, convoccur)
           ENDIF
 
@@ -1172,4 +1170,5 @@
        IF (new_aod) THEN
           IF (flag_aerosol.GT.0) THEN
+             CALL histwrite_phy(o_od443aer, od443aer)
              CALL histwrite_phy(o_od550aer, od550aer)
              CALL histwrite_phy(o_od865aer, od865aer)
@@ -1193,4 +1192,5 @@
              CALL histwrite_phy(o_loadss, loadss)
              CALL histwrite_phy(o_loaddust, loaddust)
+             CALL histwrite_phy(o_loadno3, loadno3)
              !--STRAT AER
           ENDIF
Index: LMDZ5/branches/testing/libf/phylmd/phys_state_var_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/phys_state_var_mod.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/phys_state_var_mod.F90	(revision 2839)
@@ -275,6 +275,4 @@
       REAL,ALLOCATABLE,SAVE :: total_rain(:), nday_rain(:)  
 !$OMP THREADPRIVATE(total_rain,nday_rain)
-      REAL,ALLOCATABLE,SAVE :: paire_ter(:)
-!$OMP THREADPRIVATE(paire_ter)
 ! albsol1: albedo du sol total pour SW visible
 ! albsol2: albedo du sol total pour SW proche IR
@@ -536,5 +534,4 @@
       ALLOCATE(pfrac_1nucl(klon,klev))
       ALLOCATE(total_rain(klon), nday_rain(klon))
-      ALLOCATE(paire_ter(klon))
       ALLOCATE(albsol1(klon), albsol2(klon))
 !albedo SB >>>
@@ -675,5 +672,4 @@
       deallocate(pfrac_1nucl)
       deallocate(total_rain, nday_rain)
-      deallocate(paire_ter)
       deallocate(albsol1, albsol2)
 !albedo SB >>>
Index: LMDZ5/branches/testing/libf/phylmd/physiq_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/physiq_mod.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/physiq_mod.F90	(revision 2839)
@@ -35,4 +35,5 @@
     USE change_srf_frac_mod
     USE surface_data,     ONLY : type_ocean, ok_veget, ok_snow
+    USE tropopause_m,     ONLY: dyn_tropopause
 #ifdef CPP_Dust
     USE phytracr_spl_mod, ONLY: phytracr_spl
@@ -154,5 +155,5 @@
 !!!       d_s_the, d_dens_the, &            ! due to thermals
        !                                  
-       wbeff, zmax_th, &
+       wbeff, convoccur, zmax_th, &
        sens, flwp, fiwp,  &
        ale_bl_stat,alp_bl_conv,alp_bl_det,  &
@@ -191,5 +192,6 @@
        beta_prec,  &
        rneb,  &
-       zxsnow,snowhgt,qsnow,to_ice,sissnow,runoff,albsol3_lic
+       zxsnow,snowhgt,qsnow,to_ice,sissnow,runoff,albsol3_lic, &
+       pr_tropopause
        !
     USE phys_state_var_mod ! Variables sauvegardees de la physique
@@ -205,5 +207,5 @@
     USE phys_output_ctrlout_mod
     use open_climoz_m, only: open_climoz ! ozone climatology from a file
-    use regr_pr_av_m, only: regr_pr_av
+    use regr_pr_time_av_m, only: regr_pr_time_av
     use netcdf95, only: nf95_close
     !IM for NMC files
@@ -240,4 +242,6 @@
 
     USE cmp_seri_mod
+    USE add_phys_tend_mod, only : add_pbl_tend, add_phys_tend, prt_enerbil, &
+  &      fl_ebil, fl_cor_ebil
 
     !IM stations CFMIP
@@ -245,4 +249,6 @@
     use FLOTT_GWD_rando_m, only: FLOTT_GWD_rando
     use ACAMA_GWD_rando_m, only: ACAMA_GWD_rando
+    USE VERTICAL_LAYERS_MOD, ONLY: aps,bps
+
 
     IMPLICIT none
@@ -404,6 +410,6 @@
     REAL pphis(klon)
     REAL presnivs(klev)
-    REAL znivsig(klev)
-    real pir
+!JLD    REAL znivsig(klev)
+!JLD    real pir
 
     REAL u(klon,klev)
@@ -465,6 +471,6 @@
     ! jmin_debut : indice minimum de j; nbptj : nombre de points en
     ! direction j (latitude)
-    INTEGER imin_debut, nbpti
-    INTEGER jmin_debut, nbptj 
+!JLD    INTEGER imin_debut, nbpti
+!JLD    INTEGER jmin_debut, nbptj 
     !IM: region='3d' <==> sorties en global
     CHARACTER*3 region
@@ -530,4 +536,9 @@
     REAL Tconv(klon,klev)
     REAL sij(klon,klev,klev)
+!!    !
+!!    ! variables pour tester la conservation de l'energie dans concvl
+!!    REAL, DIMENSION(klon,klev)     :: d_t_con_sat
+!!    REAL, DIMENSION(klon,klev)     :: d_q_con_sat
+!!    REAL, DIMENSION(klon,klev)     :: dql_sat
 
     real, save :: alp_bl_prescr=0.
@@ -615,6 +626,6 @@
     real env_tke_max0(klon)     ! TKE dans l'environnement au LCL 
 
-    !---D\'eclenchement stochastique
-    integer :: tau_trig(klon)
+!JLD    !---D\'eclenchement stochastique
+!JLD    integer :: tau_trig(klon)
 
     REAL,SAVE :: random_notrig_max=1.
@@ -650,5 +661,4 @@
     REAL beta_prec_fisrt(klon,klev) ! taux de conv de l'eau cond (fisrt)
     ! RomP <<<
-
     REAL          :: calday
 
@@ -749,5 +759,7 @@
     REAL conv_t(klon,klev) ! convergence de la temperature(K/s)
     !
+#ifdef INCA
     REAL zxsnow_dummy(klon)
+#endif
     REAL zsav_tsol(klon)
     !
@@ -760,9 +772,9 @@
     LOGICAL zx_ajustq
     !
-    REAL za, zb
-    REAL zx_t, zx_qs, zdelta, zcor, zlvdcp, zlsdcp
+    REAL za
+    REAL zx_t, zx_qs, zdelta, zcor
     real zqsat(klon,klev)
     !
-    INTEGER i, k, iq, j, nsrf, ll, l
+    INTEGER i, k, iq, nsrf, l
     !
     REAL t_coup
@@ -820,4 +832,6 @@
     REAL, dimension(klon)     :: dsig0, ddens0
     INTEGER, dimension(klon)  :: wkoccur1
+    ! tendance buffer pour appel de add_phys_tend
+    REAL, DIMENSION(klon,klev)  :: d_q_ch4_dtime
     !
     ! Flag pour pouvoir ne pas ajouter les tendances. 
@@ -872,5 +886,5 @@
 
     !
-    integer itau_w   ! pas de temps ecriture = itap + itau_phy
+!JLD    integer itau_w   ! pas de temps ecriture = itap + itau_phy
     !
     !
@@ -884,9 +898,9 @@
     REAL tabcntr0( length       )
     !
-    INTEGER ndex2d(nbp_lon*nbp_lat)
+!JLD    INTEGER ndex2d(nbp_lon*nbp_lat)
     !IM
     !
     !IM AMIP2 BEG
-    REAL moyglo, mountor
+!JLD    REAL moyglo, mountor
     !IM 141004 BEG
     REAL zustrdr(klon), zvstrdr(klon)
@@ -902,6 +916,6 @@
     !  REAL airedyn(nbp_lon+1,nbp_lat)
     !IM 190504 END
-    LOGICAL ok_msk
-    REAL msk(klon)
+!JLD    LOGICAL ok_msk
+!JLD    REAL msk(klon)
     !ym A voir plus tard
     !ym      REAL zm_wo(jjmp1, klev)
@@ -910,7 +924,7 @@
     REAL zx_tmp_fi2d(klon)      ! variable temporaire grille physique
     REAL zx_tmp_fi3d(klon,klev) ! variable temporaire pour champs 3D 
-    REAL zx_tmp_2d(nbp_lon,nbp_lat)
-    REAL zx_lon(nbp_lon,nbp_lat)
-    REAL zx_lat(nbp_lon,nbp_lat)
+!JLD    REAL zx_tmp_2d(nbp_lon,nbp_lat)
+!JLD    REAL zx_lon(nbp_lon,nbp_lat)
+!JLD    REAL zx_lat(nbp_lon,nbp_lat)
     !
     INTEGER nid_ctesGCM
@@ -928,11 +942,11 @@
     REAL uq_lay(klon,klev) ! transport zonal de l'eau a chaque niveau vert.
     !
-    REAL zjulian
-    SAVE zjulian
-!$OMP THREADPRIVATE(zjulian)
-
-    INTEGER nhori, nvert
-    REAL zsto
-    REAL zstophy, zout
+!JLD    REAL zjulian
+!JLD    SAVE zjulian
+!JLD!$OMP THREADPRIVATE(zjulian)
+
+!JLD    INTEGER nhori, nvert
+!JLD    REAL zsto
+!JLD    REAL zstophy, zout
 
     character*20 modname
@@ -948,22 +962,10 @@
     parameter (prof2d_on = 1, prof3d_on = 2, &
          prof2d_av = 3, prof3d_av = 4)
-    !     Variables liees au bilan d'energie et d'enthalpi
     REAL ztsol(klon)
-    REAL      d_h_vcol, d_qt, d_qw, d_ql, d_qs, d_ec
-    REAL      d_h_vcol_phy
-    REAL      fs_bound, fq_bound
-    SAVE      d_h_vcol_phy
-    !$OMP THREADPRIVATE(d_h_vcol_phy)
-    REAL      zero_v(klon)
-    CHARACTER*40 ztit
-    INTEGER   ip_ebil  ! PRINT level for energy conserv. diag.
-    SAVE      ip_ebil
-    DATA      ip_ebil/0/
-    !$OMP THREADPRIVATE(ip_ebil)
     REAL q2m(klon,nbsrf)  ! humidite a 2m
 
     !IM: t2m, q2m, ustar, u10m, v10m et t2mincels, t2maxcels
     CHARACTER*40 t2mincels, t2maxcels       !t2m min., t2m max
-    CHARACTER*40 tinst, tave, typeval
+    CHARACTER*40 tinst, tave
     REAL cldtaupi(klon,klev) ! Cloud optical thickness for
     ! pre-industrial (pi) aerosols
@@ -1006,5 +1008,7 @@
     !$OMP THREADPRIVATE(first)
 
-    integer, save::  read_climoz ! read ozone climatology
+    ! VARIABLES RELATED TO OZONE CLIMATOLOGIES ; all are OpenMP shared
+    ! Note that pressure vectors are in Pa and in stricly ascending order
+    INTEGER,SAVE :: read_climoz                ! Read ozone climatology
     !     (let it keep the default OpenMP shared attribute)
     !     Allowed values are 0, 1 and 2
@@ -1013,18 +1017,15 @@
     !     2: read two ozone climatologies, the average day and night
     !     climatology and the daylight climatology
-
-    integer, save:: ncid_climoz ! NetCDF file containing ozone climatologies
-    !     (let it keep the default OpenMP shared attribute)
-
-    real, pointer, save:: press_climoz(:)
-    ! (let it keep the default OpenMP shared attribute)
-    ! edges of pressure intervals for ozone climatologies, in Pa, in strictly
-    ! ascending order
-
-    integer ro3i
-    !     required time index in NetCDF file for the ozone fields, between 1
-    !     and 360
-
-    INTEGER ierr
+    INTEGER,SAVE :: ncid_climoz                ! NetCDF file identifier
+    REAL, POINTER, SAVE :: press_cen_climoz(:) ! Pressure levels
+    REAL, POINTER, SAVE :: press_edg_climoz(:) ! Edges of pressure intervals
+    REAL, POINTER, SAVE :: time_climoz(:)      ! Time vector
+    CHARACTER(LEN=13), PARAMETER :: vars_climoz(2) &
+                                  = ["tro3         ","tro3_daylight"]
+    ! vars_climoz(1:read_climoz): variables names in climoz file.
+    ! vars_climoz(1:read_climoz-2) if read_climoz>2 (temporary)
+    REAL :: ro3i ! 0<=ro3i<=360 ; required time index in NetCDF file for
+                 ! the ozone fields, old method.
+
     include "YOMCST.h"
     include "YOETHF.h"
@@ -1040,6 +1041,7 @@
     ! Declarations pour Simulateur COSP
     !============================================================
+#ifdef CPP_COSP
     real :: mr_ozone(klon,klev)
-
+#endif
     !IM stations CFMIP
     INTEGER, SAVE :: nCFMIP
@@ -1090,5 +1092,5 @@
     !--OB variables for mass fixer (hard coded for now)
     logical, parameter :: mass_fixer=.false.
-    real qql1(klon),qql2(klon),zdz,corrqql
+    real qql1(klon),qql2(klon),corrqql
 
     ! Ehouarn: set value of jjmp1 since it is no longer a "fixed parameter"
@@ -1194,10 +1196,4 @@
 
     modname = 'physiq'
-    !IM
-    IF (ip_ebil_phy.ge.1) THEN
-       DO i=1,klon
-          zero_v(i)=0.
-       ENDDO
-    ENDIF
 
     IF (debut) THEN
@@ -1211,4 +1207,11 @@
        iflag_wake_tend = 0
        CALL getin_p('iflag_wake_tend',iflag_wake_tend)
+       ok_bad_ecmwf_thermo=.TRUE. ! By default thermodynamical constants are set 
+                                  ! in rrtm/suphec.F90 (and rvtmp2 is set to 0).
+       CALL getin_p('ok_bad_ecmwf_thermo',ok_bad_ecmwf_thermo)
+       fl_ebil = 0 ! by default, conservation diagnostics are desactivated
+       CALL getin_p('fl_ebil',fl_ebil)
+       fl_cor_ebil = 0 ! by default, no correction to ensure energy conservation
+       CALL getin_p('fl_cor_ebil',fl_cor_ebil)
     ENDIF
 
@@ -1274,6 +1277,4 @@
        clwcon(:,:) = 0.0
 
-       !IM      
-       IF (ip_ebil_phy.ge.1) d_h_vcol_phy=0.
        !
        print*,'iflag_coupl,iflag_clos,iflag_wake', &
@@ -1656,4 +1657,5 @@
                start_time, &
                itau_phy, &
+               date0, &
                io_lon, &
                io_lat)
@@ -1671,7 +1673,6 @@
 
        !$omp single
-       IF (read_climoz >= 1) THEN
-          CALL open_climoz(ncid_climoz, press_climoz)
-       ENDIF
+       IF (read_climoz >= 1) CALL open_climoz(ncid_climoz, press_cen_climoz,   &
+           press_edg_climoz, time_climoz, ok_daily_climoz, adjust_tropopause)
        !$omp end single
        !
@@ -1737,8 +1738,9 @@
     !
     itap   = itap + 1
-    IF (is_mpi_root .AND. is_omp_root) THEN
+    IF (is_master .OR. prt_level > 9) THEN
       IF (prt_level > 5 .or. MOD(itap,5) == 0) THEN
-         WRITE(LUNOUT,*)'Entering physics current time = ', current_time
-         WRITE(LUNOUT,*)'Date = ',year_cur,'/',mth_cur,'/',day_cur,':',hour/3600
+         WRITE(LUNOUT,*)'Entering physics elapsed seconds since start ', current_time
+         WRITE(LUNOUT,100)year_cur,mth_cur,day_cur,hour/3600.
+ 100     FORMAT('Date = ',i4.4,' / ',i2.2, ' / ',i2.2,' : ',f20.17)
       ENDIF
     ENDIF
@@ -1978,24 +1980,23 @@
           wo(:,:,1)=ozonecm(latitude_deg, paprs,read_climoz,rjour=zzz)
        ELSE
-          ro3i = int((days_elapsed + jh_cur - jh_1jan) / year_len * 360.) + 1
-
-          IF (ro3i == 361) ro3i = 360
-          ! (This should never occur, except perhaps because of roundup
-          ! error. See documentation.)
-
-          IF (read_climoz == 1) THEN
-             CALL regr_pr_av(ncid_climoz, (/"tro3"/), julien=ro3i, &
-                  press_in_edg=press_climoz, paprs=paprs, v3=wo)
+          !--- ro3i = elapsed days number since current year 1st january, 0h
+          ro3i=days_elapsed+jh_cur-jh_1jan
+          !--- scaling for old style files (360 records)
+          IF(SIZE(time_climoz)==360.AND..NOT.ok_daily_climoz) ro3i=ro3i*360./year_len
+          IF(adjust_tropopause) THEN
+             CALL dyn_tropopause(t_seri, ztsol, paprs, pplay, presnivs, rot, &
+                  pr_tropopause)
+             CALL regr_pr_time_av(ncid_climoz, vars_climoz(1:read_climoz),   &
+                      ro3i,  press_edg_climoz,  paprs,   wo, time_climoz,    &
+                           latitude_deg,  press_cen_climoz,  pr_tropopause)
           ELSE
-             ! read_climoz == 2
-             CALL regr_pr_av(ncid_climoz, (/"tro3         ", &
-                  "tro3_daylight"/), julien=ro3i, press_in_edg=press_climoz, &
-                  paprs=paprs, v3=wo)
-          ENDIF
+             CALL regr_pr_time_av(ncid_climoz, vars_climoz(1:read_climoz),   &
+                      ro3i,  press_edg_climoz,  paprs,  wo,  time_climoz)
+          END IF
           ! Convert from mole fraction of ozone to column density of ozone in a
           ! cell, in kDU:
           FORALL (l = 1: read_climoz) wo(:, :, l) = wo(:, :, l) * rmo3 / rmd &
                * zmasse / dobson_u / 1e3
-          ! (By regridding ozone values for LMDZ only once per day, we
+          ! (By regridding ozone values for LMDZ only once a day, we
           ! have already neglected the variation of pressure in one
           ! day. So do not recompute "wo" at each time step even if
@@ -2011,5 +2012,6 @@
      CALL add_phys_tend &
             (du0,dv0,d_t_eva,d_q_eva,d_ql_eva,d_qi_eva,paprs,&
-               'eva',abortphy,flag_inhib_tend)
+               'eva',abortphy,flag_inhib_tend,itap,0)
+    call prt_enerbil('eva',itap)
 
     !=========================================================================
@@ -2233,10 +2235,11 @@
           CALL add_pbl_tend &
                (d_u_vdf,d_v_vdf,d_t_vdf+d_t_diss,d_q_vdf,dql0,dqi0,paprs,&
-               'vdf',abortphy,flag_inhib_tend)
+               'vdf',abortphy,flag_inhib_tend,itap)
        ELSE
           CALL add_phys_tend &
                (d_u_vdf,d_v_vdf,d_t_vdf+d_t_diss,d_q_vdf,dql0,dqi0,paprs,&
-               'vdf',abortphy,flag_inhib_tend)
-       ENDIF
+               'vdf',abortphy,flag_inhib_tend,itap,0)
+       ENDIF
+       call prt_enerbil('vdf',itap)
        !--------------------------------------------------------------------
 
@@ -2485,5 +2488,5 @@
                d_t_con,d_q_con,d_u_con,d_v_con,d_tr, &
                rain_con, snow_con, ibas_con, itop_con, sigd, &
-               ema_cbmf,plcl,plfc,wbeff,upwd,dnwd,dnwd0, &
+               ema_cbmf,plcl,plfc,wbeff,convoccur,upwd,dnwd,dnwd0, &
                Ma,mip,Vprecip,cape,cin,tvp,Tconv,iflagctrl, &
                pbase,bbase,dtvpdt1,dtvpdq1,dplcldt,dplcldr,qcondc,wd, &
@@ -2618,6 +2621,18 @@
     itapcv = itapcv+1
 
+!!!jyg  Appel diagnostique a add_phys_tend pour tester la conservation de 
+!!!     l'energie dans les courants satures.
+!!    d_t_con_sat(:,:) = d_t_con(:,:) - ftd(:,:)*dtime
+!!    d_q_con_sat(:,:) = d_q_con(:,:) - fqd(:,:)*dtime
+!!    dql_sat(:,:) = (wdtrainA(:,:)+wdtrainM(:,:))*dtime/zmasse(:,:)
+!!    CALL add_phys_tend(d_u_con, d_v_con, d_t_con_sat, d_q_con_sat, dql_sat,   &
+!!                     dqi0, paprs, 'convection_sat', abortphy, flag_inhib_tend,&  
+!!                     itap, 1)
+!!    call prt_enerbil('convection_sat',itap)
+!!
+!!
     CALL add_phys_tend(d_u_con, d_v_con, d_t_con, d_q_con, dql0, dqi0, paprs, &
-         'convection',abortphy,flag_inhib_tend)
+         'convection',abortphy,flag_inhib_tend,itap,0)
+    call prt_enerbil('convection',itap)
 
     !-------------------------------------------------------------------------
@@ -2748,5 +2763,6 @@
        ! ajout des tendances des poches froides
        CALL add_phys_tend(du0,dv0,d_t_wake,d_q_wake,dql0,dqi0,paprs,'wake', &
-            abortphy,flag_inhib_tend)
+            abortphy,flag_inhib_tend,itap,0)
+       call prt_enerbil('wake',itap)
        !------------------------------------------------------------------------
 
@@ -2757,5 +2773,5 @@
             (d_deltat_wk, d_deltaq_wk, d_s_wk, d_dens_wk, wake_k, &
              'wake', abortphy) 
-
+          call prt_enerbil('wake',itap)
        ENDIF   ! (iflag_wake_tend .GT. 0.)
 
@@ -2878,9 +2894,11 @@
              CALL add_wake_tend &
                  (d_deltat_the, d_deltaq_the, dsig0, ddens0, wkoccur1, 'the', abortphy) 
+             call prt_enerbil('the',itap)
           !
           ENDIF  ! (mod(iflag_pbl_split/2,2) .EQ. 1)
           !
           CALL add_phys_tend(d_u_ajs,d_v_ajs,d_t_ajs,d_q_ajs,  &
-                             dql0,dqi0,paprs,'thermals', abortphy,flag_inhib_tend)
+                             dql0,dqi0,paprs,'thermals', abortphy,flag_inhib_tend,itap,0)
+          call prt_enerbil('thermals',itap)
           !
 !
@@ -2944,5 +2962,6 @@
           ! ajout des tendances de l'ajustement sec ou des thermiques
           CALL add_phys_tend(du0,dv0,d_t_ajsb,d_q_ajsb,dql0,dqi0,paprs, &
-               'ajsb',abortphy,flag_inhib_tend)
+               'ajsb',abortphy,flag_inhib_tend,itap,0)
+          call prt_enerbil('ajsb',itap)
           d_t_ajs(:,:)=d_t_ajs(:,:)+d_t_ajsb(:,:)
           d_q_ajs(:,:)=d_q_ajs(:,:)+d_q_ajsb(:,:)
@@ -2987,6 +3006,13 @@
     WHERE (snow_lsc < 0) snow_lsc = 0.
 
+!+JLD
+!    write(*,9000) 'phys lsc',"enerbil: bil_q, bil_e,",rain_lsc+snow_lsc &
+!        & ,((rcw-rcpd)*rain_lsc + (rcs-rcpd)*snow_lsc)*t_seri(1,1)-rlvtt*rain_lsc+rlstt*snow_lsc &
+!        & ,rain_lsc,snow_lsc
+!    write(*,9000) "rcpv","rcw",rcpv,rcw,rcs,t_seri(1,1)
+!-JLD 
     CALL add_phys_tend(du0,dv0,d_t_lsc,d_q_lsc,d_ql_lsc,d_qi_lsc,paprs, &
-         'lsc',abortphy,flag_inhib_tend)
+         'lsc',abortphy,flag_inhib_tend,itap,0)
+    call prt_enerbil('lsc',itap)
     rain_num(:)=0.
     DO k = 1, klev
@@ -3767,6 +3793,8 @@
     ENDDO
 
-    CALL add_phys_tend(du0,dv0,d_t_swr,dq0,dql0,dqi0,paprs,'SW',abortphy,flag_inhib_tend)
-    CALL add_phys_tend(du0,dv0,d_t_lwr,dq0,dql0,dqi0,paprs,'LW',abortphy,flag_inhib_tend)
+    CALL add_phys_tend(du0,dv0,d_t_swr,dq0,dql0,dqi0,paprs,'SW',abortphy,flag_inhib_tend,itap,0)
+    call prt_enerbil('SW',itap)
+    CALL add_phys_tend(du0,dv0,d_t_lwr,dq0,dql0,dqi0,paprs,'LW',abortphy,flag_inhib_tend,itap,0)
+    call prt_enerbil('LW',itap)
 
     !
@@ -3838,5 +3866,6 @@
        ! ajout des tendances de la trainee de l'orographie
        CALL add_phys_tend(d_u_oro,d_v_oro,d_t_oro,dq0,dql0,dqi0,paprs,'oro', &
-            abortphy,flag_inhib_tend)
+            abortphy,flag_inhib_tend,itap,0)
+       call prt_enerbil('oro',itap)
        !----------------------------------------------------------------------
        !
@@ -3884,5 +3913,6 @@
        ! ajout des tendances de la portance de l'orographie
        CALL add_phys_tend(d_u_lif, d_v_lif, d_t_lif, dq0, dql0, dqi0, paprs, &
-            'lif', abortphy,flag_inhib_tend)
+            'lif', abortphy,flag_inhib_tend,itap,0)
+       call prt_enerbil('lif',itap)
     ENDIF ! fin de test sur ok_orolf
 
@@ -3907,5 +3937,6 @@
        d_t_hin(:, :)=0.
        CALL add_phys_tend(du_gwd_hines, dv_gwd_hines, d_t_hin, dq0, dql0, &
-            dqi0, paprs, 'hin', abortphy,flag_inhib_tend)
+            dqi0, paprs, 'hin', abortphy,flag_inhib_tend,itap,0)
+       call prt_enerbil('hin',itap)
     ENDIF
 
@@ -3924,5 +3955,6 @@
 
        CALL add_phys_tend(du_gwd_front, dv_gwd_front, dt0, dq0, dql0, dqi0, &
-            paprs, 'front_gwd_rando', abortphy,flag_inhib_tend)
+            paprs, 'front_gwd_rando', abortphy,flag_inhib_tend,itap,0)
+       call prt_enerbil('front_gwd_rando',itap)
     ENDIF
 
@@ -3932,5 +3964,6 @@
             du_gwd_rando, dv_gwd_rando, east_gwstress, west_gwstress)
        CALL add_phys_tend(du_gwd_rando, dv_gwd_rando, dt0, dq0, dql0, dqi0, &
-            paprs, 'flott_gwd_rando', abortphy,flag_inhib_tend)
+            paprs, 'flott_gwd_rando', abortphy,flag_inhib_tend,itap,0)
+       call prt_enerbil('flott_gwd_rando',itap)
        zustr_gwd_rando=0.
        zvstr_gwd_rando=0.
@@ -3981,6 +4014,8 @@
        CALL METHOX(1,klon,klon,klev,q_seri,d_q_ch4,pplay)
        ! ajout de la tendance d'humidite due au methane
-       CALL add_phys_tend(du0, dv0, dt0, d_q_ch4*dtime, dql0, dqi0, paprs, &
-            'q_ch4', abortphy,flag_inhib_tend)
+       d_q_ch4_dtime(:,:) = d_q_ch4(:,:)*dtime
+       CALL add_phys_tend(du0, dv0, dt0, d_q_ch4_dtime, dql0, dqi0, paprs, &
+            'q_ch4', abortphy,flag_inhib_tend,itap,0)
+       d_q_ch4(:,:) = d_q_ch4_dtime(:,:)/dtime
     ENDIF
     !
@@ -4004,5 +4039,5 @@
           CALL phys_cosp(itap,dtime,freq_cosp, &
                ok_mensuelCOSP,ok_journeCOSP,ok_hfCOSP, &
-               ecrit_mth,ecrit_day,ecrit_hf, ok_all_xml, &
+               ecrit_mth,ecrit_day,ecrit_hf, ok_all_xml, missing_val, &
                klon,klev,longitude_deg,latitude_deg,presnivs,overlap, &
                JrNt,ref_liq,ref_ice, &
@@ -4211,5 +4246,6 @@
             pphi, &
             pphis, &
-            zx_rh)
+            zx_rh, &
+            aps, bps)
 
        CALL VTe(VTinca)
@@ -4465,5 +4501,6 @@
              CALL nf95_close(ncid_climoz)
           ENDIF
-          DEALLOCATE(press_climoz) ! pointer
+          DEALLOCATE(press_edg_climoz) ! pointer
+          DEALLOCATE(press_cen_climoz) ! pointer
        ENDIF
        !$OMP END MASTER
Index: LMDZ5/branches/testing/libf/phylmd/readaerosol.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/readaerosol.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/readaerosol.F90	(revision 2839)
@@ -222,11 +222,11 @@
     REAL, ALLOCATABLE, DIMENSION(:)       :: varktmp
 
-    REAL, DIMENSION(nbp_lon,nbp_lat,12)         :: psurf_glo2D   ! Surface pression for 12 months on dynamics global grid
+    REAL, DIMENSION(nbp_lon,nbp_lat,12)   :: psurf_glo2D   ! Surface pression for 12 months on dynamics global grid
     REAL, DIMENSION(klon_glo,12)          :: psurf_glo1D   ! -"- on physical global grid
-    REAL, DIMENSION(nbp_lon,nbp_lat,12)         :: load_glo2D    ! Load for 12 months on dynamics global grid
+    REAL, DIMENSION(nbp_lon,nbp_lat,12)   :: load_glo2D    ! Load for 12 months on dynamics global grid
     REAL, DIMENSION(klon_glo,12)          :: load_glo1D    ! -"- on physical global grid
-    REAL, DIMENSION(nbp_lon,nbp_lat)            :: vartmp
-    REAL, DIMENSION(nbp_lon)                  :: lon_src              ! longitudes in file
-    REAL, DIMENSION(nbp_lat)                :: lat_src, lat_src_inv ! latitudes in file
+    REAL, DIMENSION(nbp_lon,nbp_lat)      :: vartmp
+    REAL, DIMENSION(nbp_lon)              :: lon_src              ! longitudes in file
+    REAL, DIMENSION(nbp_lat)              :: lat_src, lat_src_inv ! latitudes in file
     LOGICAL                               :: new_file             ! true if new file format detected
     LOGICAL                               :: invert_lat           ! true if the field has to be inverted for latitudes
@@ -245,5 +245,5 @@
   
        WRITE(lunout,*) 'reading variable ',TRIM(varname),' in file ', TRIM(fname)
-       CALL check_err( nf90_open(TRIM(fname), NF90_NOWRITE, ncid), "pb open "//trim(varname) )
+       CALL check_err( nf90_open(TRIM(fname), NF90_NOWRITE, ncid), "pb open "//trim(fname) )
 
 ! Test for equal longitudes and latitudes in file and model
@@ -338,8 +338,14 @@
 !****************************************************************************************
           ! Get variable id
-          CALL check_err( nf90_inq_varid(ncid, TRIM(varname), varid),"pb inq var "//TRIM(varname) )
-          
-          ! Get the variable
-          CALL check_err( nf90_get_var(ncid, varid, varyear(:,:,:,:)),"pb get var "//TRIM(varname) )
+          !CALL check_err( nf90_inq_varid(ncid, TRIM(varname), varid),"pb inq var "//TRIM(varname) )
+          print *,'readaerosol ', TRIM(varname)
+          IF ( nf90_inq_varid(ncid, TRIM(varname), varid) /= NF90_NOERR ) THEN 
+            ! Variable is not there
+            WRITE(lunout,*) 'Attention '//TRIM(varname)//' is not in aerosol input file'
+            varyear(:,:,:,:)=0.0
+          ELSE 
+            ! Get the variable
+            CALL check_err( nf90_get_var(ncid, varid, varyear(:,:,:,:)),"pb get var "//TRIM(varname) )
+          ENDIF
           
 ! ++) Read surface pression, 12 month in one variable
@@ -353,7 +359,12 @@
 !****************************************************************************************
           ! Get variable id
-          CALL check_err( nf90_inq_varid(ncid, "load_"//TRIM(varname), varid) ,"pb inq var load_"//TRIM(varname))
-          ! Get the variable
-          CALL check_err( nf90_get_var(ncid, varid, load_glo2D),"pb get var load_"//TRIM(varname) )
+          !CALL check_err( nf90_inq_varid(ncid, "load_"//TRIM(varname), varid) ,"pb inq var load_"//TRIM(varname))
+          IF ( nf90_inq_varid(ncid, "load_"//TRIM(varname), varid) /= NF90_NOERR ) THEN 
+            WRITE(lunout,*) 'Attention load_'//TRIM(varname)//' is not in aerosol input file'
+            load_glo2D(:,:,:)=0.0
+          ELSE
+            ! Get the variable
+            CALL check_err( nf90_get_var(ncid, varid, load_glo2D),"pb get var load_"//TRIM(varname) )
+          ENDIF
           
 ! ++) Read ap
Index: LMDZ5/branches/testing/libf/phylmd/readaerosol_optic.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/readaerosol_optic.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/readaerosol_optic.F90	(revision 2839)
@@ -16,5 +16,5 @@
   USE phys_local_var_mod, only: sconcso4,sconcno3,sconcoa,sconcbc,sconcss,sconcdust, &
       concso4,concno3,concoa,concbc,concss,concdust,loadso4,loadoa,loadbc,loadss,loaddust, &
-      load_tmp1,load_tmp2,load_tmp3,load_tmp4,load_tmp5,load_tmp6,load_tmp7
+      load_tmp1,load_tmp2,load_tmp3
   IMPLICIT NONE
 
@@ -93,6 +93,6 @@
 
      ! Get bc aerosol distribution 
-     CALL readaerosol_interp(id_ASBCM_phy, itap, pdtphys, rjourvrai, debut, pplay, paprs, t_seri, bcsol, bcsol_pi, load_tmp1 )
-     CALL readaerosol_interp(id_AIBCM_phy, itap, pdtphys, rjourvrai, debut, pplay, paprs, t_seri, bcins, bcins_pi, load_tmp2 )
+     CALL readaerosol_interp(id_ASBCM_phy, itap, pdtphys, rjourvrai, debut, pplay, paprs, t_seri, bcsol, bcsol_pi, load_tmp1)
+     CALL readaerosol_interp(id_AIBCM_phy, itap, pdtphys, rjourvrai, debut, pplay, paprs, t_seri, bcins, bcins_pi, load_tmp2)
      loadbc(:)=load_tmp1(:)+load_tmp2(:)
   ELSE
@@ -107,7 +107,7 @@
        flag_aerosol .EQ. 6 ) THEN
 
-     CALL readaerosol_interp(id_ASPOMM_phy, itap, pdtphys, rjourvrai, debut, pplay, paprs, t_seri, pomsol, pomsol_pi, load_tmp3)
-     CALL readaerosol_interp(id_AIPOMM_phy, itap, pdtphys, rjourvrai, debut, pplay, paprs, t_seri, pomins, pomins_pi, load_tmp4)
-     loadoa(:)=load_tmp3(:)+load_tmp4(:)
+     CALL readaerosol_interp(id_ASPOMM_phy, itap, pdtphys, rjourvrai, debut, pplay, paprs, t_seri, pomsol, pomsol_pi, load_tmp1)
+     CALL readaerosol_interp(id_AIPOMM_phy, itap, pdtphys, rjourvrai, debut, pplay, paprs, t_seri, pomins, pomins_pi, load_tmp2)
+     loadoa(:)=load_tmp1(:)+load_tmp2(:)
   ELSE
      pomsol(:,:) = 0. ; pomsol_pi(:,:) = 0.
@@ -121,13 +121,13 @@
       flag_aerosol .EQ. 6 ) THEN 
 
-      CALL readaerosol_interp(id_SSSSM_phy ,itap, pdtphys, rjourvrai, debut, pplay, paprs, t_seri, sssupco, sssupco_pi, load_tmp5) 
-      CALL readaerosol_interp(id_CSSSM_phy ,itap, pdtphys, rjourvrai, debut, pplay, paprs, t_seri, sscoarse,sscoarse_pi, load_tmp6) 
-      CALL readaerosol_interp(id_ASSSM_phy ,itap, pdtphys, rjourvrai, debut, pplay, paprs, t_seri, ssacu, ssacu_pi, load_tmp7) 
-     loadss(:)=load_tmp5(:)+load_tmp6(:)+load_tmp7(:)
-  ELSE
-     sscoarse(:,:) = 0. ; sscoarse_pi(:,:) = 0. 
-     ssacu(:,:)    = 0. ; ssacu_pi(:,:) = 0. 
-     sssupco(:,:)  = 0. ; sssupco_pi = 0. 
-     loadss=0.
+      CALL readaerosol_interp(id_SSSSM_phy ,itap, pdtphys, rjourvrai, debut, pplay, paprs, t_seri, sssupco, sssupco_pi,  load_tmp1) 
+      CALL readaerosol_interp(id_CSSSM_phy ,itap, pdtphys, rjourvrai, debut, pplay, paprs, t_seri, sscoarse,sscoarse_pi, load_tmp2) 
+      CALL readaerosol_interp(id_ASSSM_phy ,itap, pdtphys, rjourvrai, debut, pplay, paprs, t_seri, ssacu,   ssacu_pi,    load_tmp3) 
+      loadss(:)=load_tmp1(:)+load_tmp2(:)+load_tmp3(:)
+  ELSE
+      sscoarse(:,:) = 0. ; sscoarse_pi(:,:) = 0. 
+      ssacu(:,:)    = 0. ; ssacu_pi(:,:) = 0. 
+      sssupco(:,:)  = 0. ; sssupco_pi = 0. 
+      loadss=0.
   ENDIF
 
@@ -137,5 +137,4 @@
 
       CALL readaerosol_interp(id_CIDUSTM_phy, itap, pdtphys, rjourvrai, debut, pplay, paprs, t_seri, cidust, cidust_pi, loaddust) 
-
   ELSE
       cidust(:,:) = 0. ; cidust_pi(:,:) = 0. 
@@ -174,5 +173,4 @@
   m_allaer_pi(:,:,id_CSNO3M_phy) = 0.0
   m_allaer_pi(:,:,id_CINO3M_phy) = 0.0
-
 !
 ! Calculate the total mass of all soluble aersosols
@@ -214,5 +212,4 @@
      
   END IF
-
 
 ! Diagnostics calculation for CMIP5 protocol
@@ -230,4 +227,3 @@
   concdust(:,:)=m_allaer(:,:,id_CIDUSTM_phy)*1.e-9
 
-
 END SUBROUTINE readaerosol_optic
Index: LMDZ5/branches/testing/libf/phylmd/reevap.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/reevap.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/reevap.F90	(revision 2839)
@@ -2,5 +2,7 @@
    &         d_t_eva,d_q_eva,d_ql_eva,d_qs_eva)
 
-
+    ! flag to include modifications to ensure energy conservation (if flag >0)
+    USE add_phys_tend_mod, only : fl_cor_ebil 
+    
     IMPLICIT none
     !>======================================================================
@@ -22,7 +24,11 @@
     ! Re-evaporer l'eau liquide nuageuse
     !
-
+!print *,'rrevap ; fl_cor_ebil:',fl_cor_ebil,' iflag_ice_thermo:',iflag_ice_thermo,' RVTMP2',RVTMP2
     DO k = 1, klev  ! re-evaporation de l'eau liquide nuageuse
        DO i = 1, klon
+        if (fl_cor_ebil .GT. 0) then
+          zlvdcp=RLVTT/RCPD/(1.0+RVTMP2*(q_seri(i,k)+ql_seri(i,k)+qs_seri(i,k)))
+          zlsdcp=RLSTT/RCPD/(1.0+RVTMP2*(q_seri(i,k)+ql_seri(i,k)+qs_seri(i,k)))
+        else
           zlvdcp=RLVTT/RCPD/(1.0+RVTMP2*q_seri(i,k))
           !jyg<
@@ -30,4 +36,5 @@
           !                  A verifier !!!
           zlsdcp=RLSTT/RCPD/(1.0+RVTMP2*q_seri(i,k))
+        end if
           IF (iflag_ice_thermo .EQ. 0) THEN
              zlsdcp=zlvdcp
@@ -39,4 +46,5 @@
 
              zdelta = MAX(0.,SIGN(1.,RTT-t_seri(i,k)))
+  zdelta = 0.
              zb = MAX(0.0,ql_seri(i,k))
              za = - MAX(0.0,ql_seri(i,k)) &
Index: LMDZ5/branches/testing/libf/phylmd/regr_horiz_time_climoz_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/regr_horiz_time_climoz_m.F90	(revision 2839)
+++ LMDZ5/branches/testing/libf/phylmd/regr_horiz_time_climoz_m.F90	(revision 2839)
@@ -0,0 +1,510 @@
+MODULE regr_horiz_time_climoz_m
+
+  USE interpolation,     ONLY: locate
+  USE mod_grid_phy_lmdz, ONLY: nlon_ou => nbp_lon, nlat_ou => nbp_lat
+  USE nrtype,            ONLY: pi
+  USE netcdf,   ONLY: NF90_CLOBBER, NF90_FLOAT,     NF90_GET_VAR, NF90_OPEN,   &
+                      NF90_NOWRITE, NF90_NOERR,     NF90_GET_ATT, NF90_GLOBAL
+  USE netcdf95, ONLY: NF95_DEF_DIM, NF95_INQ_DIMID, NF95_INQUIRE_DIMENSION,    &
+                      NF95_DEF_VAR, NF95_INQ_VARID, NF95_INQUIRE_VARIABLE,     &
+          NF95_OPEN,  NF95_CREATE,  NF95_GET_ATT,   NF95_GW_VAR,  HANDLE_ERR,  &
+          NF95_CLOSE, NF95_ENDDEF,  NF95_PUT_ATT,   NF95_PUT_VAR, NF95_COPY_ATT
+  USE print_control_mod, ONLY: lunout
+  IMPLICIT NONE
+  PRIVATE
+  PUBLIC :: regr_horiz_time_climoz
+  REAL, PARAMETER :: deg2rad=pi/180.
+  CHARACTER(LEN=13), PARAMETER :: vars_in(2)=['tro3         ','tro3_daylight']
+
+CONTAINS
+
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE regr_horiz_time_climoz(read_climoz,interpt)
+!
+!-------------------------------------------------------------------------------
+! Purpose: Regrid horizontally and in time zonal or 3D ozone climatologies.
+!   * Read ozone climatology from netcdf file
+!   * Regrid it horizontaly to LMDZ grid (quasi-conservative method)
+!   * If interpt=T, interpolate linearly in time (one record each day)
+!     If interpt=F, keep original time sampling  (14 months).
+!   * Save it to a new netcdf file.
+!-------------------------------------------------------------------------------
+! Remarks:
+!   * Up to 2 variables treated: "tro3" and "tro3_daylight" (if read_climoz=2)
+!   * Input fields coordinates: (longitudes, latitudes, pressure_levels, time)
+!   * Output grid cells centers coordinates given by [rlonv,] rlatu.
+!   * Output grid cells edges   coordinates given by [rlonu,] rlatv.
+!   * Input file [longitudes and] latitudes given in degrees.
+!   * Input file pressure levels are given in Pa or hPa.
+!   * All coordinates variables are stricly monotonic.
+!   * Monthly fields are interpolated linearly in time to get daily values.
+!   * Fields are known at the middle of the months, so interpolation requires an
+!     additional record both for 1st half of january and 2nd half of december:
+!     - For a 14-records "climoz.nc": records 1 and 14.
+!     - For 12-records files:
+!       record 12 of "climoz_m.nc" if available, or record 1  of "climoz.nc".
+!       record 1  of "climoz_p.nc" if available, or record 12 of "climoz.nc".
+!   * Calendar is taken into account to get one record each day (not 360 always).
+!   * Missing values are filled in from sky to ground by copying lowest valid one.
+!     Attribute "missing_value" or "_FillValue" must be present in input file.
+!-------------------------------------------------------------------------------
+  USE assert_m,           ONLY: assert
+  USE cal_tools_m,        ONLY: year_len, mid_month
+  USE control_mod,        ONLY: anneeref
+  USE ioipsl,             ONLY: ioget_year_len, ioget_calendar
+  USE regr_conserv_m,     ONLY: regr_conserv
+  USE regr_lint_m,        ONLY: regr_lint
+  USE regular_lonlat_mod, ONLY: boundslon_reg, boundslat_reg, south, west, east
+  USE slopes_m,           ONLY: slopes
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER, INTENT(IN) :: read_climoz ! read ozone climatology, 1 or 2
+!                         1: read a single ozone climatology used day and night
+!                         2: same + read also a daylight climatology
+  LOGICAL, INTENT(IN) :: interpt     ! TRUE  => daily interpolation
+                                     ! FALSE => no interpolation (14 months)
+!-------------------------------------------------------------------------------
+! Local variables:
+
+!--- Input files variables
+  INTEGER :: nlon_in                       ! Number of longitudes
+  INTEGER :: nlat_in                       ! Number of latitudes
+  INTEGER :: nlev_in                       ! Number of pressure levels
+  INTEGER :: nmth_in                       ! Number of months
+  REAL, POINTER     :: lon_in(:)           ! Longitudes   (ascending order, rad)
+  REAL, POINTER     :: lat_in(:)           ! Latitudes    (ascending order, rad)
+  REAL, POINTER     :: lev_in(:)           ! Pressure levels (ascen. order, hPa)
+  REAL, ALLOCATABLE :: lon_in_edge(:)      ! Longitude intervals edges
+                                           !              (ascending order,  / )
+  REAL, ALLOCATABLE :: sinlat_in_edge(:)   ! Sinus of latitude intervals edges
+                                           !              (ascending order,  / )
+  LOGICAL :: ldec_lon, ldec_lat, ldec_lev  ! Decreasing order in input file
+  CHARACTER(LEN=20) :: cal_in              ! Calendar
+  REAL, ALLOCATABLE :: o3_in3(:,:,:,:,:)   ! Ozone climatologies
+  REAL, ALLOCATABLE :: o3_in2  (:,:,:,:)   ! Ozone climatologies
+  ! last index: 1 for the day-night average, 2 for the daylight field.
+  REAL :: NaN
+
+!--- Partially or totally regridded variables      (:,:,nlev_in,:,read_climoz)
+  REAL, ALLOCATABLE :: o3_regr_lon   (:,:,:,:,:) ! (nlon_ou,nlat_in,:,0:13   ,:)
+  REAL, ALLOCATABLE :: o3_regr_lonlat(:,:,:,:,:) ! (nlon_ou,nlat_ou,:,0:13   ,:)
+  REAL, ALLOCATABLE :: o3_out3       (:,:,:,:,:) ! (nlon_ou,nlat_ou,:,ntim_ou,:)
+  REAL, ALLOCATABLE :: o3_regr_lat     (:,:,:,:) !         (nlat_in,:,0:13   ,:)
+  REAL, ALLOCATABLE :: o3_out2         (:,:,:,:) !         (nlat_ou,:,ntim_ou,:)
+! Dimension number  | Interval                | Contains  | For variables:
+!   1 (longitude)   | [rlonu(i-1), rlonu(i)]  | rlonv(i)  | all
+!   2 (latitude)    | [rlatv(j), rlatv(j-1)]  | rlatu(j)  | all but o3_regr_lon
+!   3 (press level) |                         |   lev(k)  | all
+! Note that rlatv(0)=pi/2 and rlatv(nlat_ou)=-pi/2.
+! Dimension 4 is: month number                             (all vars but o3_out)
+!                 days elapsed since Jan. 1st 0h at mid-day (o3_out only)
+  REAL, ALLOCATABLE :: v1(:)
+
+!--- For NetCDF:
+  INTEGER :: fID_in_m, fID_in, levID_ou, dimid, vID_in(read_climoz), ntim_ou
+  INTEGER :: fID_in_p, fID_ou, timID_ou, varid, vID_ou(read_climoz), ndims, ncerr
+  INTEGER, POINTER :: dIDs(:)
+  CHARACTER(LEN=20) :: cal_ou     !--- Calendar; no time inter => same as input
+  CHARACTER(LEN=80) :: press_unit !--- Pressure unit
+  REAL    :: tmidmonth(0:13)      !--- Elapsed days since Jan-1 0h at mid-months
+                                  ! Additional records 0, 13 for interpolation
+  REAL, ALLOCATABLE :: tmidday(:) !--- Output times (mid-days since Jan 1st 0h)
+  LOGICAL :: lprev, lnext         !--- Flags: previous/next files are present
+  LOGICAL :: l3D, l2D             !--- Flag:  input fields are 3D or zonal
+  INTEGER :: ii, i, j, k, l, m, dln, ib, ie, iv, dx1, dx2
+  INTEGER, ALLOCATABLE :: sta(:), cnt(:)
+  CHARACTER(LEN=80) :: sub, dim_nam, msg
+!-------------------------------------------------------------------------------
+  sub="regr_horiz_time_climoz"
+  WRITE(lunout,*)"Call sequence information: "//TRIM(sub)
+  CALL assert(read_climoz == 1 .OR. read_climoz == 2, "regr_lat_time_climoz")
+
+  CALL  NF95_OPEN("climoz.nc"  , NF90_NOWRITE, fID_in)
+  lprev=NF90_OPEN("climoz_m.nc", NF90_NOWRITE, fID_in_m)==NF90_NOERR
+  lnext=NF90_OPEN("climoz_p.nc", NF90_NOWRITE, fID_in_p)==NF90_NOERR
+
+  !--- Get coordinates from the input file. Converts lon/lat in radians.
+  !    Few inversions because "regr_conserv" and gcm need ascending vectors.
+  CALL NF95_INQ_VARID(fID_in, vars_in(1), varid)
+  CALL NF95_INQUIRE_VARIABLE(fID_in, varid, dimids=dIDs, ndims=ndims)
+  l3D=ndims==4; l2D=ndims==3
+  IF(l3D) WRITE(lunout,*)"Input files contain full 3D ozone fields."
+  IF(l2D) WRITE(lunout,*)"Input files contain zonal 2D ozone fields."
+  DO i=1,ndims
+    CALL NF95_INQUIRE_DIMENSION(fID_in, dIDs(i), name=dim_nam, nclen=dln)
+    CALL NF95_INQ_VARID(fID_in, dim_nam, varid)
+    ii=i; IF(l2D) ii=i+1                              !--- ndims==3:NO LONGITUDE 
+    SELECT CASE(ii)
+      CASE(1)                                         !--- LONGITUDE
+        CALL NF95_GW_VAR(fID_in, varid, lon_in)
+        ldec_lon=lon_in(1)>lon_in(dln); IF(ldec_lon) lon_in=lon_in(dln:1:-1)
+        nlon_in=dln; lon_in=lon_in*deg2rad
+      CASE(2)                                         !--- LATITUDE
+        CALL NF95_GW_VAR(fID_in, varid, lat_in)
+        ldec_lat=lat_in(1)>lat_in(dln); IF(ldec_lat) lat_in=lat_in(dln:1:-1)
+        nlat_in=dln; lat_in=lat_in*deg2rad
+      CASE(3)                                         !--- PRESSURE LEVELS
+        CALL NF95_GW_VAR(fID_in, varid, lev_in)
+        ldec_lev=lev_in(1)>lev_in(dln); IF(ldec_lev) lev_in=lev_in(dln:1:-1)
+        nlev_in=dln
+        CALL NF95_GET_ATT(fID_in, varid, "units", press_unit)
+        k=LEN_TRIM(press_unit)
+        DO WHILE(ICHAR(press_unit(k:k))==0)
+          press_unit(k:k)=' '; k=LEN_TRIM(press_unit) !--- REMOVE NULL END CHAR
+        END DO
+        IF(press_unit ==  "Pa") THEN
+          lev_in = lev_in/100.                        !--- CONVERT TO hPa
+        ELSE IF(press_unit /= "hPa") THEN
+          CALL abort_physic(sub, "the only recognized units are Pa and hPa.",1)
+        END IF
+      CASE(4)                                         !--- TIME
+        CALL NF95_INQUIRE_DIMENSION(fID_in, dIDs(i), nclen=nmth_in)
+        cal_in='gregorian'
+        IF(NF90_GET_ATT(fID_in, varid, 'calendar', cal_in)/=NF90_NOERR)        &
+          WRITE(lunout,*)'WARNING: missing "calendar" attribute for "'//       &
+          TRIM(dim_nam)//'" in "climoz.nc". Choosing default: "gregorian".'
+        k=LEN_TRIM(cal_in)
+        DO WHILE(ICHAR(cal_in(k:k))==0)
+          cal_in(k:k)=' '; k=LEN_TRIM(cal_in)         !--- REMOVE NULL END CHAR
+        END DO
+    END SELECT
+  END DO
+
+  !--- Longitudes management:
+  !    * Need to shift data if the origin of input file longitudes /= -pi
+  !    * Need to add some margin in longitude to ensure input interval contains
+  !      all the output intervals => at least one longitudes slice has to be
+  !      duplicated, possibly more for undersampling.
+  IF(l3D) THEN
+    !--- Compute input edges longitudes vector (no end point yet)
+    ALLOCATE(v1(nlon_in))
+    v1(1)=(lon_in(nlon_in)+lon_in(1))/2.-pi
+    FORALL(i=2:nlon_in) v1(i)=(lon_in(i-1)+lon_in(i))/2.
+    DEALLOCATE(lon_in)
+
+    !--- Shift input longitudes vector until it contains first output point boundslon_reg(1,east)
+    v1=v1+2*pi*REAL(FLOOR((boundslon_reg(1,east)-v1(1))/(2.*pi)))
+
+    !--- Ensure first input longitudes interval contains first output point boundslon_reg(1,east)
+    dx1=locate(v1,boundslon_reg(1,east))-1
+    v1=CSHIFT(v1,SHIFT=dx1,DIM=1); v1(nlon_in-dx1+1:)=v1(nlon_in-dx1+1:)+2.*pi
+
+    !--- Extend input longitudes vector until last interval contains boundslon_reg(nlat_ou,west)
+    dx2=0; DO WHILE(v1(1+dx2)+2.*pi<boundslon_reg(nlat_ou,west)); dx2=dx2+1; END DO
+
+    !--- Final edges longitudes vector (with margin and end point)
+    ALLOCATE(lon_in_edge(nlon_in+dx2+1)); lon_in_edge=[v1,v1(1:1+dx2)+2.*pi]
+    DEALLOCATE(v1)
+  END IF
+
+  !--- Compute sinus of intervals edges latitudes:
+  ALLOCATE(sinlat_in_edge(nlat_in+1))
+  sinlat_in_edge(1) = -1. ; sinlat_in_edge(nlat_in+1) = 1.
+  FORALL(j=2:nlat_in) sinlat_in_edge(j)=SIN((lat_in(j-1)+lat_in(j))/2.)
+  DEALLOCATE(lat_in)
+
+  !--- Prepare quantities for time interpolation
+  tmidmonth=mid_month(anneeref, cal_in)
+  IF(interpt) THEN
+    ntim_ou=ioget_year_len(anneeref)
+    ALLOCATE(tmidday(ntim_ou))
+    tmidday=[(REAL(k)-0.5,k=1,ntim_ou)]
+    CALL ioget_calendar(cal_ou)
+  ELSE
+    ntim_ou=14
+    cal_ou=cal_in
+  END IF
+
+  !--- Create the output file and get the variable IDs:
+  CALL prepare_out(fID_in,nlev_in,ntim_ou, fID_ou,levID_ou,timID_ou,vID_ou, &
+                   ndims, cal_ou)
+
+  !--- Write remaining coordinate variables:
+  CALL NF95_PUT_VAR(fID_ou, levID_ou, lev_in); DEALLOCATE(lev_in)
+  IF(     interpt) CALL NF95_PUT_VAR(fID_ou, timID_ou, tmidday)
+  IF(.NOT.interpt) CALL NF95_PUT_VAR(fID_ou, timID_ou, tmidmonth)
+
+  !--- Check for contiguous years:
+  ib=0; ie=13
+  IF(nmth_in == 14) THEN; lprev=.FALSE.; lnext=.FALSE.
+    WRITE(lunout,*)'Using 14 months ozone climatology "climoz.nc"...'
+  ELSE
+    IF(     lprev) WRITE(lunout,*)'Using "climoz_m.nc" last record (previous year).'
+    IF(.NOT.lprev) WRITE(lunout,*)"No previous year file ; assuming periodicity."
+    IF(     lnext) WRITE(lunout,*)'Using "climoz_p.nc" first record (next year).'
+    IF(.NOT.lnext) WRITE(lunout,*)"No next year file ; assuming periodicity."
+    IF(.NOT.lprev) ib=1
+    IF(.NOT.lnext) ie=12
+  END IF
+  ALLOCATE(sta(ndims),cnt(ndims)); sta(:)=1
+  IF(l3D) cnt=[nlon_in,nlat_in,nlev_in,1]
+  IF(l2D) cnt=[        nlat_in,nlev_in,1]
+  IF(l3D) ALLOCATE(o3_in3(nlon_in+dx2,nlat_in,nlev_in,ib:ie,read_climoz))
+  IF(l2D) ALLOCATE(o3_in2(            nlat_in,nlev_in,ib:ie,read_climoz))
+
+  !--- Read full current file and one record each available contiguous file
+  DO iv=1,read_climoz
+    msg=TRIM(sub)//" NF90_GET_VAR "//TRIM(vars_in(iv))
+    CALL NF95_INQ_VARID(fID_in, vars_in(1), vID_in(iv))
+    IF(l3D) ncerr=NF90_GET_VAR(fID_in, vID_in(iv), o3_in3(1:nlon_in,:,:,1:12,iv))
+    IF(l2D) ncerr=NF90_GET_VAR(fID_in, vID_in(iv), o3_in2(          :,:,1:12,iv))
+    CALL handle_err(TRIM(msg), ncerr, fID_in)
+    IF(lprev) THEN; sta(ndims)=12
+      CALL NF95_INQ_VARID(fID_in_m, vars_in(1), vID_in(iv))
+      IF(l3D) ncerr=NF90_GET_VAR(fID_in_m,vID_in(iv),o3_in3(1:nlon_in,:,:, 0,iv),sta,cnt)
+      IF(l2d) ncerr=NF90_GET_VAR(fID_in_m,vID_in(iv),o3_in2(          :,:, 0,iv),sta,cnt)
+      CALL handle_err(TRIM(msg)//" previous", ncerr, fID_in_m)
+    END IF
+    IF(lnext) THEN; sta(ndims)=1
+      CALL NF95_INQ_VARID(fID_in_p, vars_in(1), vID_in(iv))
+      IF(l3D) ncerr=NF90_GET_VAR(fID_in_p,vID_in(iv),o3_in3(1:nlon_in,:,:,13,iv),sta,cnt)
+      IF(l2D) ncerr=NF90_GET_VAR(fID_in_p,vID_in(iv),o3_in2(          :,:,13,iv),sta,cnt)
+      CALL handle_err(TRIM(msg)//" next", ncerr, fID_in_p)
+    END IF
+  END DO
+  IF(lprev.OR.lnext) DEALLOCATE(sta,cnt)
+  IF(lprev) CALL NF95_CLOSE(fID_in_m)
+  IF(lnext) CALL NF95_CLOSE(fID_in_p)
+
+  !--- Revert decreasing coordinates vector
+  IF(l3D) THEN
+    IF(ldec_lon) o3_in3(1:nlon_in,:,:,:,:) = o3_in3(nlon_in:1:-1,:,:,:,:)
+    IF(ldec_lat) o3_in3 = o3_in3(:,nlat_in:1:-1,:,:,:)
+    IF(ldec_lev) o3_in3 = o3_in3(:,:,nlev_in:1:-1,:,:)
+    !--- Shift values for longitude and duplicate some longitudes slices
+    o3_in3(1:nlon_in,:,:,:,:)=CSHIFT(o3_in3(1:nlon_in,:,:,:,:),SHIFT=dx1,DIM=1)
+    o3_in3(nlon_in+1:nlon_in+dx2,:,:,:,:)=o3_in3(1:dx2,:,:,:,:)
+  ELSE
+    IF(ldec_lat) o3_in2 = o3_in2(  nlat_in:1:-1,:,:,:)
+    IF(ldec_lev) o3_in2 = o3_in2(  :,nlev_in:1:-1,:,:)
+  END IF
+
+ !--- Deal with missing values
+  DO m=1, read_climoz
+    WRITE(msg,'(a,i0)')"regr_lat_time_climoz: field Nr.",m
+    IF(NF90_GET_ATT(fID_in,vID_in(m),"missing_value",NaN)/= NF90_NOERR) THEN
+      IF(NF90_GET_ATT(fID_in, vID_in(m),"_FillValue",NaN)/= NF90_NOERR) THEN
+        WRITE(lunout,*)TRIM(msg)//": no missing value attribute found."; CYCLE
+      END IF
+    END IF
+    WRITE(lunout,*)TRIM(msg)//": missing value attribute found."
+    WRITE(lunout,*)"Trying to fill in NaNs ; a full field would be better."
+
+    !--- Check top layer contains no NaNs & search NaNs from top to ground
+    msg=TRIM(sub)//": NaNs in top layer !"
+    IF(l3D) THEN
+      IF(ANY(o3_in3(:,:,1,:,m)==NaN)) CALL abort_physic(sub,msg,1)
+      DO k = 2,nlev_in
+        WHERE(o3_in3(:,:,k,:,m)==NaN) o3_in3(:,:,k,:,m)=o3_in3(:,:,k-1,:,m)
+      END DO
+    ELSE
+      IF(ANY(o3_in2(  :,1,:,m)==NaN)) THEN
+        WRITE(lunout,*)msg
+        !--- Fill in latitudes where all values are missing
+        DO l=1,nmth_in
+          !--- Next to south pole
+          j=1;       DO WHILE(o3_in2(j,1,l,m)==NaN); j=j+1; END DO
+          IF(j>1) &
+            o3_in2(:j-1,:,l,m)=SPREAD(o3_in2(j,:,l,m),DIM=1,ncopies=j-1)
+          !--- Next to north pole
+          j=nlat_in; DO WHILE(o3_in2(j,1,l,m)==NaN); j=j+1; END DO
+          IF(j<nlat_in) &
+            o3_in2(j+1:,:,l,m)=SPREAD(o3_in2(j,:,l,m),DIM=1,ncopies=nlat_in-j)
+        END DO
+      END IF
+
+      !--- Fill in high latitudes missing values
+      !--- Highest level been filled-in, so has always valid values.
+      DO k = 2,nlev_in
+        WHERE(o3_in2(:,k,:,m)==NaN) o3_in2(:,k,:,m)=o3_in2(:,k-1,:,m)
+      END DO
+    END IF
+  END DO
+  CALL NF95_CLOSE(fID_in)
+
+  !=============================================================================
+  IF(l3D) THEN                                                   !=== 3D FIELDS
+  !=============================================================================
+    !--- Regrid in longitude
+    ALLOCATE(o3_regr_lon(nlon_ou, nlat_in, nlev_in, ie-ib+1, read_climoz))
+    CALL regr_conserv(1, o3_in3, xs = lon_in_edge,                             &
+                        xt = [boundslon_reg(1,east),boundslon_reg(:,west)],    &
+                        vt = o3_regr_lon, slope = slopes(1,o3_in3, lon_in_edge))
+    DEALLOCATE(o3_in3)
+
+    !--- Regrid in latitude: averaging with respect to SIN(lat) is
+    !                        equivalent to weighting by COS(lat)
+    !--- (inverted indices in "o3_regr_lonlat" because "rlatu" is decreasing)
+    ALLOCATE(o3_regr_lonlat(nlon_ou, nlat_ou, nlev_in, 0:13, read_climoz))
+    CALL regr_conserv(2, o3_regr_lon, xs = sinlat_in_edge,                     &
+                    xt = [- 1., SIN(boundslat_reg(nlat_ou-1:1:-1,south)), 1.], &
+                    vt = o3_regr_lonlat(:,nlat_ou:1:- 1,:,ib:ie,:),            &
+                 slope = slopes(2,o3_regr_lon, sinlat_in_edge))
+    DEALLOCATE(o3_regr_lon)
+
+    !--- Duplicate previous/next record(s) if they are not available
+    IF(.NOT.lprev) o3_regr_lonlat(:,:,:, 0,:) = o3_regr_lonlat(:,:,:,12,:)
+    IF(.NOT.lnext) o3_regr_lonlat(:,:,:,13,:) = o3_regr_lonlat(:,:,:, 1,:)
+
+    !--- Regrid in time by linear interpolation:
+    ALLOCATE(o3_out3(nlon_ou, nlat_ou, nlev_in, ntim_ou, read_climoz))
+    IF(     interpt) CALL regr_lint(4,o3_regr_lonlat,tmidmonth,tmidday,o3_out3)
+    IF(.NOT.interpt) o3_out3=o3_regr_lonlat
+    DEALLOCATE(o3_regr_lonlat)
+
+    !--- Write to file (the order of "rlatu" is inverted in the output file):
+    DO m = 1, read_climoz
+      CALL NF95_PUT_VAR(fID_ou, vID_ou(m), o3_out3(:,nlat_ou:1:-1,:,:,m))
+    END DO
+
+  !=============================================================================
+  ELSE                                                         !=== ZONAL FIELDS
+  !=============================================================================
+    !--- Regrid in latitude: averaging with respect to SIN(lat) is
+    !                        equivalent to weighting by COS(lat)
+    !--- (inverted indices in "o3_regr_lat" because "rlatu" is decreasing)
+    ALLOCATE(o3_regr_lat(nlat_ou, nlev_in, 0:13, read_climoz))
+    CALL regr_conserv(1, o3_in2, xs = sinlat_in_edge,                          &
+                    xt = [- 1., SIN(boundslat_reg(nlat_ou-1:1:-1,south)), 1.], &
+                    vt = o3_regr_lat(nlat_ou:1:- 1,:,ib:ie,:),                 &
+                 slope = slopes(1,o3_in2, sinlat_in_edge))
+    DEALLOCATE(o3_in2)
+
+    !--- Duplicate previous/next record(s) if they are not available
+    IF(.NOT.lprev) o3_regr_lat(:,:, 0,:) = o3_regr_lat(:,:,12,:)
+    IF(.NOT.lnext) o3_regr_lat(:,:,13,:) = o3_regr_lat(:,:, 1,:)
+
+    !--- Regrid in time by linear interpolation:
+    ALLOCATE(o3_out2(nlat_ou, nlev_in, ntim_ou, read_climoz))
+    IF(     interpt) CALL regr_lint(3,o3_regr_lat, tmidmonth, tmidday, o3_out2)
+    IF(.NOT.interpt) o3_out2=o3_regr_lat
+    DEALLOCATE(o3_regr_lat)
+
+    !--- Write to file (the order of "rlatu" is inverted in the output file):
+    DO m = 1, read_climoz
+      CALL NF95_PUT_VAR(fID_ou, vID_ou(m), o3_out2(nlat_ou:1:-1,:,:,m))
+    END DO
+
+  !=============================================================================
+  END IF
+  !=============================================================================
+
+  CALL NF95_CLOSE(fID_ou)
+
+END SUBROUTINE regr_horiz_time_climoz
+!
+!-------------------------------------------------------------------------------
+
+
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE prepare_out(fID_in, nlev_in, ntim_ou, fID_ou, vlevID, vtimID, &
+                       vID_ou, ndims, cal_ou)
+!-------------------------------------------------------------------------------
+! Purpose:  This subroutine creates the NetCDF output file, defines
+!     dimensions and variables, and writes some of the coordinate variables.
+!-------------------------------------------------------------------------------
+  USE regular_lonlat_mod, ONLY: lon_reg, lat_reg
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER, INTENT(IN)  :: fID_in, nlev_in, ntim_ou
+  INTEGER, INTENT(OUT) :: fID_ou, vlevID,  vtimID
+  INTEGER, INTENT(OUT) :: vID_ou(:)      ! dim(1/2) 1: O3day&night 2: O3daylight
+  INTEGER, INTENT(IN)  :: ndims          ! fields rank (3 or 4)
+  CHARACTER(LEN=*), INTENT(IN) :: cal_ou ! calendar
+!-------------------------------------------------------------------------------
+! Local variables:
+  INTEGER :: dlonID, dlatID, dlevID, dtimID, dIDs(4)
+  INTEGER :: vlonID, vlatID, ncerr,  is
+  CHARACTER(LEN=80) :: sub
+!-------------------------------------------------------------------------------
+  sub="prepare_out"
+  WRITE(lunout,*)"CALL sequence information: "//TRIM(sub)
+  CALL NF95_CREATE("climoz_LMDZ.nc", NF90_clobber, fID_ou)
+
+  !--- Dimensions:
+  IF(ndims==4) &
+  CALL NF95_DEF_DIM(fID_ou, "rlonv", nlon_ou, dlonID)
+  CALL NF95_DEF_DIM(fID_ou, "rlatu", nlat_ou, dlatID)
+  CALL NF95_DEF_DIM(fID_ou, "plev",  nlev_in, dlevID)
+  CALL NF95_DEF_DIM(fID_ou, "time",  ntim_ou, dtimID)
+
+  !--- Define coordinate variables:
+  IF(ndims==4) &
+  CALL NF95_DEF_VAR(fID_ou, "rlonv", NF90_FLOAT, dlonID, vlonID)
+  CALL NF95_DEF_VAR(fID_ou, "rlatu", NF90_FLOAT, dlatID, vlatID)
+  CALL NF95_DEF_VAR(fID_ou, "plev",  NF90_FLOAT, dlevID, vlevID)
+  CALL NF95_DEF_VAR(fID_ou, "time",  NF90_FLOAT, dtimID, vtimID)
+  IF(ndims==4) &
+  CALL NF95_PUT_ATT(fID_ou, vlonID, "units", "degrees_east")
+  CALL NF95_PUT_ATT(fID_ou, vlatID, "units", "degrees_north")
+  CALL NF95_PUT_ATT(fID_ou, vlevID, "units", "millibar")
+  CALL NF95_PUT_ATT(fID_ou, vtimID, "units", "days since 2000-1-1")
+  IF(ndims==4) &
+  CALL NF95_PUT_ATT(fID_ou, vlonID, "standard_name", "longitude")
+  CALL NF95_PUT_ATT(fID_ou, vlatID, "standard_name", "latitude")
+  CALL NF95_PUT_ATT(fID_ou, vlevID, "standard_name", "air_pressure")
+  CALL NF95_PUT_ATT(fID_ou, vtimID, "standard_name", "time")
+  CALL NF95_PUT_ATT(fID_ou, vlevID, "long_name",     "air pressure")
+  CALL NF95_PUT_ATT(fID_ou, vtimID, "calendar",      cal_ou)
+
+  !--- Define the main variables:
+  IF(ndims==3) dIDs(1:3) = [ dlatID, dlevID, dtimID]
+  IF(ndims==4) dIDs=[dlonID, dlatID, dlevID, dtimID]
+  CALL NF95_DEF_VAR(fID_ou, vars_in(1), NF90_FLOAT, dIDs(1:ndims), vID_ou(1))
+  CALL NF95_PUT_ATT(fID_ou, vID_ou(1), "long_name", "ozone mole fraction")
+  CALL NF95_PUT_ATT(fID_ou, vID_ou(1), "standard_name", "mole_fraction_of_ozone&
+      &_in_air")
+  IF(SIZE(vID_ou) == 2) THEN
+    CALL NF95_DEF_VAR(fID_ou, vars_in(2), NF90_FLOAT, dIDs(1:ndims), vID_ou(2))
+    CALL NF95_PUT_ATT(fID_ou, vID_ou(2), "long_name","ozone mole fraction in da&
+      &ylight")
+  END IF
+
+  !--- Global attributes:
+  ! The following commands, copying attributes, may fail. That is OK.
+  ! It should just mean that the attribute is not defined in the input file.
+  CALL NF95_COPY_ATT(fID_in,NF90_GLOBAL,"Conventions",fID_ou,NF90_GLOBAL, ncerr)
+  CALL handle_err_copy_att("Conventions")
+  CALL NF95_COPY_ATT(fID_in,NF90_GLOBAL,"title",      fID_ou,NF90_GLOBAL, ncerr)
+  CALL handle_err_copy_att("title")
+  CALL NF95_COPY_ATT(fID_in,NF90_GLOBAL,"institution",fID_ou,NF90_GLOBAL, ncerr)
+  CALL handle_err_copy_att("institution")
+  CALL NF95_COPY_ATT(fID_in,NF90_GLOBAL,"source",     fID_ou,NF90_GLOBAL, ncerr)
+  CALL handle_err_copy_att("source")
+  CALL NF95_PUT_ATT (fID_ou,NF90_GLOBAL,"comment", "Regridded for LMDZ")
+  CALL NF95_ENDDEF(fID_ou)
+
+  !--- Write one of the coordinate variables:
+  IF(ndims==4) CALL NF95_PUT_VAR(fID_ou, vlonID, lon_reg/deg2rad)
+  CALL NF95_PUT_VAR(fID_ou, vlatID, lat_reg(nlat_ou:1:-1)/deg2rad)
+  !    (convert from rad to degrees and sort in ascending order)
+
+CONTAINS
+
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE handle_err_copy_att(att_name)
+!
+!-------------------------------------------------------------------------------
+  USE netcdf, ONLY: NF90_NOERR, NF90_strerror
+!-------------------------------------------------------------------------------
+! Arguments:
+  CHARACTER(LEN=*), INTENT(IN) :: att_name
+!-------------------------------------------------------------------------------
+  IF(ncerr /= NF90_NOERR) &
+    WRITE(lunout,*)TRIM(sub)//" prepare_out NF95_COPY_ATT "//TRIM(att_name)//  &
+                      " -- "//TRIM(NF90_strerror(ncerr))
+
+END SUBROUTINE handle_err_copy_att
+!
+!-------------------------------------------------------------------------------
+
+END SUBROUTINE prepare_out
+!
+!-------------------------------------------------------------------------------
+
+END MODULE regr_horiz_time_climoz_m
+!
+!-------------------------------------------------------------------------------
Index: LMDZ5/branches/testing/libf/phylmd/regr_lat_time_climoz_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/regr_lat_time_climoz_m.F90	(revision 2787)
+++ 	(revision )
@@ -1,450 +1,0 @@
-! $Id$
-module regr_lat_time_climoz_m
-
-  ! Author: Lionel GUEZ
-
-  implicit none
-
-  private
-  public regr_lat_time_climoz
-
-contains
-
-  subroutine regr_lat_time_climoz(read_climoz)
-
-    ! "regr_lat_time_climoz" stands for "regrid latitude time
-    ! climatology ozone".
-
-    ! This procedure reads a climatology of ozone from a NetCDF file,
-    ! regrids it in latitude and time, and writes the regridded field
-    ! to a new NetCDF file.
-
-    ! The input field depends on time, pressure level and latitude.
-
-    ! If the input field has missing values, they must be signaled by
-    ! the "missing_value" attribute.
-
-    ! We assume that the input field is a step function of latitude
-    ! and that the input latitude coordinate gives the centers of steps.
-    ! Regridding in latitude is made by averaging, with a cosine of
-    ! latitude factor.
-    ! The target LMDZ latitude grid is the "scalar" grid: "rlatu".
-    ! The values of "rlatu" are taken to be the centers of intervals.
-
-    ! We assume that in the input file:
-
-    ! -- Latitude is in degrees.
-
-    ! -- Latitude and pressure are strictly monotonic (as all NetCDF
-    ! coordinate variables should be).
-
-    ! -- The time coordinate is in ascending order (even though we do
-    ! not use its values).
-    ! The input file may contain either values for 12 months or values
-    ! for 14 months.
-    ! If there are 14 months then we assume that we have (in that order):
-    ! December, January, February, ..., November, December, January
-
-    ! -- Missing values are contiguous, at the bottom of
-    ! the vertical domain and at the latitudinal boundaries.
-
-    ! If values are all missing at a given latitude and date, then we
-    ! replace those missing values by values at the closest latitude,
-    ! equatorward, with valid values.
-    ! Then, at each latitude and each date, the missing values are replaced
-    ! by the lowest valid value above missing values.
-
-    ! Regridding in time is by linear interpolation.
-    ! Monthly values are processed to get daily values, on the basis
-    ! of a 360-day calendar.
-    ! If there are 14 months, we use the first December value to
-    ! interpolate values between January 1st and mid-January.
-    ! We use the last January value to interpolate values between
-    ! mid-December and end of December.
-    ! If there are only 12 months in the input file then we assume
-    ! periodicity for interpolation at the beginning and at the end of the
-    ! year.
-
-    use mod_grid_phy_lmdz, ONLY : nbp_lat
-    use regr1_conserv_m, only: regr1_conserv
-    use regr3_lint_m, only: regr3_lint
-    use netcdf95, only: handle_err, nf95_close, nf95_get_att, nf95_gw_var, &
-         nf95_inq_dimid, nf95_inq_varid, nf95_inquire_dimension, nf95_open, &
-         nf95_put_var
-    use netcdf, only: nf90_get_att, nf90_get_var, nf90_noerr, nf90_nowrite
-    use assert_m, only: assert
-    use regular_lonlat_mod, only : boundslat_reg, south
-    use nrtype, only: pi
-    use slopes_m, only: slopes
-
-    integer, intent(in):: read_climoz ! read ozone climatology
-    ! Allowed values are 1 and 2
-    ! 1: read a single ozone climatology that will be used day and night
-    ! 2: read two ozone climatologies, the average day and night
-    ! climatology and the daylight climatology
-
-    ! Variables local to the procedure:
-
-    integer n_plev ! number of pressure levels in the input data
-    integer n_lat ! number of latitudes in the input data
-    integer n_month ! number of months in the input data
-
-    real, pointer:: latitude(:)
-    ! (of input data, converted to rad, sorted in strictly ascending order)
-
-    real, allocatable:: sin_lat_in_edg(:)
-    ! (sine of edges of latitude intervals for input data, in rad, in strictly
-    ! ascending order)
-
-    real, pointer:: plev(:)
-    ! pressure levels of input data, sorted in strictly ascending
-    ! order, converted to hPa
-
-    logical desc_lat ! latitude in descending order in the input file
-    logical desc_plev ! pressure levels in descending order in the input file
-
-    real, allocatable:: o3_in(:, :, :, :)
-    ! (n_lat, n_plev, n_month, read_climoz)
-    ! ozone climatologies from the input file
-    ! "o3_in(j, k, :, :)" is at latitude "latitude(j)" and pressure
-    ! level "plev(k)".
-    ! Third dimension is month index, first value may be December or January.
-    ! "o3_in(:, :, :, 1)" is for the day- night average, "o3_in(:, :, :, 2)"
-    ! is for daylight.
-
-    real missing_value
-
-    real, allocatable:: o3_regr_lat(:, :, :, :)
-    ! (nbp_lat, n_plev, 0:13, read_climoz)
-    ! mean of "o3_in" over a latitude interval of LMDZ
-    ! First dimension is latitude interval.
-    ! The latitude interval for "o3_regr_lat(j,:, :, :)" contains "rlatu(j)".
-    ! If "j" is between 2 and "nbp_lat - 1" then the interval is:
-    ! [rlatv(j), rlatv(j-1)]
-    ! If "j" is 1 or "nbp_lat" then the interval is:
-    ! [rlatv(1), pi / 2]
-    ! or:
-    ! [- pi / 2, rlatv(nbp_lat - 1)]
-    ! respectively.
-    ! "o3_regr_lat(:, k, :, :)" is for pressure level "plev(k)".
-    ! Third dimension is month number, 1 for January.
-    ! "o3_regr_lat(:, :, :, 1)" is average day and night,
-    ! "o3_regr_lat(:, :, :, 2)" is for daylight.
-
-    real, allocatable:: o3_out(:, :, :, :)
-    ! (nbp_lat, n_plev, 360, read_climoz)
-    ! regridded ozone climatology
-    ! "o3_out(j, k, l, :)" is at latitude "rlatu(j)", pressure
-    ! level "plev(k)" and date "January 1st 0h" + "tmidday(l)", in a
-    ! 360-day calendar.
-    ! "o3_out(:, :, :, 1)" is average day and night,
-    ! "o3_out(:, :, :, 2)" is for daylight.
-
-    integer j, k, l,m
-
-    ! For NetCDF:
-    integer ncid_in, ncid_out ! IDs for input and output files
-    integer varid_plev, varid_time, varid, ncerr, dimid
-    character(len=80) press_unit ! pressure unit
-
-    integer varid_in(read_climoz), varid_out(read_climoz)
-    ! index 1 is for average ozone day and night, index 2 is for
-    ! daylight ozone.
-
-    real, parameter:: tmidmonth(0:13) = (/(-15. + 30. * l, l = 0, 13)/)
-    ! (time to middle of month, in days since January 1st 0h, in a
-    ! 360-day calendar)
-    ! (We add values -15 and 375 so that, for example, day 3 of the year is
-    ! interpolated between the December and the January value.)
-
-    real, parameter:: tmidday(360) = (/(l + 0.5, l = 0, 359)/)
-    ! (time to middle of day, in days since January 1st 0h, in a
-    ! 360-day calendar)
-
-    !---------------------------------
-
-    print *, "Call sequence information: regr_lat_time_climoz"
-    call assert(read_climoz == 1 .or. read_climoz == 2, "regr_lat_time_climoz")
-
-    call nf95_open("climoz.nc", nf90_nowrite, ncid_in)
-
-    ! Get coordinates from the input file:
-
-    call nf95_inq_varid(ncid_in, "latitude", varid)
-    call nf95_gw_var(ncid_in, varid, latitude)
-    ! Convert from degrees to rad, because we will take the sine of latitude:
-    latitude = latitude / 180. * pi
-    n_lat = size(latitude)
-    ! We need to supply the latitudes to "regr1_conserv" in
-    ! ascending order, so invert order if necessary:
-    desc_lat = latitude(1) > latitude(n_lat)
-    if (desc_lat) latitude = latitude(n_lat:1:-1)
-
-    ! Compute edges of latitude intervals:
-    allocate(sin_lat_in_edg(n_lat + 1))
-    sin_lat_in_edg(1) = - 1.
-    forall (j = 2:n_lat) sin_lat_in_edg(j) = sin((latitude(j - 1) &
-         + latitude(j)) / 2.)
-    sin_lat_in_edg(n_lat + 1) = 1.
-    deallocate(latitude) ! pointer
-
-    call nf95_inq_varid(ncid_in, "plev", varid)
-    call nf95_gw_var(ncid_in, varid, plev)
-    n_plev = size(plev)
-    ! We only need the pressure coordinate to copy it to the output file.
-    ! The program "gcm" will assume that pressure levels are in
-    ! ascending order in the regridded climatology so invert order if
-    ! necessary:
-    desc_plev = plev(1) > plev(n_plev)
-    if (desc_plev) plev = plev(n_plev:1:-1)
-    call nf95_get_att(ncid_in, varid, "units", press_unit)
-    if (press_unit == "Pa") then
-       ! Convert to hPa:
-       plev = plev / 100.
-    elseif (press_unit /= "hPa") then
-       print *, "regr_lat_time_climoz: the only recognized units are Pa " &
-            // "and hPa."
-       stop 1
-    end if
-
-    ! Create the output file and get the variable IDs:
-    call prepare_out(ncid_in, n_plev, ncid_out, varid_out, varid_plev, &
-         varid_time)
-
-    ! Write remaining coordinate variables:
-    call nf95_put_var(ncid_out, varid_plev, plev)
-    call nf95_put_var(ncid_out, varid_time, tmidday)
-
-    deallocate(plev) ! pointer
-
-    ! Get the  number of months:
-    call nf95_inq_dimid(ncid_in, "time", dimid)
-    call nf95_inquire_dimension(ncid_in, dimid, nclen=n_month)
-
-    allocate(o3_in(n_lat, n_plev, n_month, read_climoz))
-
-    call nf95_inq_varid(ncid_in, "tro3", varid_in(1))
-    ncerr = nf90_get_var(ncid_in, varid_in(1), o3_in(:, :, :, 1))
-    call handle_err("regr_lat_time_climoz nf90_get_var tro3", ncerr, ncid_in)
-
-    if (read_climoz == 2) then
-       call nf95_inq_varid(ncid_in, "tro3_daylight", varid_in(2))
-       ncerr = nf90_get_var(ncid_in, varid_in(2), o3_in(:, :, :, 2))
-       call handle_err("regr_lat_time_climoz nf90_get_var tro3_daylight", &
-            ncerr, ncid_in, varid_in(2))
-    end if
-
-    if (desc_lat) o3_in = o3_in(n_lat:1:-1, :, :, :)
-    if (desc_plev) o3_in = o3_in(:, n_plev:1:-1, :, :)
-
-    do m = 1, read_climoz
-       ncerr = nf90_get_att(ncid_in, varid_in(m), "missing_value", &
-            missing_value)
-       if (ncerr == nf90_noerr) then
-          do l = 1, n_month
-             ! Take care of latitudes where values are all missing:
-
-             ! Next to the south pole:
-             j = 1
-             do while (o3_in(j, 1, l, m) == missing_value)
-                j = j + 1
-             end do
-             if (j > 1) o3_in(:j-1, :, l, m) = &
-                  spread(o3_in(j, :, l, m), dim=1, ncopies=j-1)
-             
-             ! Next to the north pole:
-             j = n_lat
-             do while (o3_in(j, 1, l, m) == missing_value)
-                j = j - 1
-             end do
-             if (j < n_lat) o3_in(j+1:, :, l, m) = &
-                  spread(o3_in(j, :, l, m), dim=1, ncopies=n_lat-j)
-
-             ! Take care of missing values at high pressure:
-             do j = 1, n_lat
-                ! Find missing values, starting from top of atmosphere
-                ! and going down.
-                ! We have already taken care of latitudes full of
-                ! missing values so the highest level has a valid value.
-                k = 2
-                do while  (o3_in(j, k, l, m) /= missing_value .and. k < n_plev)
-                   k = k + 1
-                end do
-                ! Replace missing values with the valid value at the
-                ! lowest level above missing values:
-                if (o3_in(j, k, l, m) == missing_value) &
-                     o3_in(j, k:n_plev, l, m) = o3_in(j, k-1, l, m)
-             end do
-          end do
-       else
-          print *, "regr_lat_time_climoz: field ", m, &
-               ", no missing value attribute"
-       end if
-    end do
-
-    call nf95_close(ncid_in)
-
-    allocate(o3_regr_lat(nbp_lat, n_plev, 0:13, read_climoz))
-    allocate(o3_out(nbp_lat, n_plev, 360, read_climoz))
-
-    ! Regrid in latitude:
-    ! We average with respect to sine of latitude, which is
-    ! equivalent to weighting by cosine of latitude:
-    if (n_month == 12) then
-       print *, &
-            "Found 12 months in ozone climatologies, assuming periodicity..."
-       call regr1_conserv(o3_in, xs = sin_lat_in_edg, &
-            xt = (/- 1., sin(boundslat_reg(nbp_lat - 1:1:- 1, south)), 1./), &
-            vt = o3_regr_lat(nbp_lat:1:- 1, :, 1:12, :), &
-            slope = slopes(o3_in, sin_lat_in_edg))
-       ! (invert order of indices in "o3_regr_lat" because "rlatu" is
-       ! in descending order)
-
-       ! Duplicate January and December values, in preparation of time
-       ! interpolation:
-       o3_regr_lat(:, :, 0, :) = o3_regr_lat(:, :, 12, :)
-       o3_regr_lat(:, :, 13, :) = o3_regr_lat(:, :, 1, :)
-    else
-       print *, "Using 14 months in ozone climatologies..."
-       call regr1_conserv(o3_in, xs = sin_lat_in_edg, &
-            xt = (/- 1., sin(boundslat_reg(nbp_lat - 1:1:- 1, south)), 1./), &
-            vt = o3_regr_lat(nbp_lat:1:- 1, :, :, :), &
-            slope = slopes(o3_in, sin_lat_in_edg))
-       ! (invert order of indices in "o3_regr_lat" because "rlatu" is
-       ! in descending order)
-    end if
-
-    ! Regrid in time by linear interpolation:
-    o3_out = regr3_lint(o3_regr_lat, tmidmonth, tmidday)
-
-    ! Write to file:
-    do m = 1, read_climoz
-       call nf95_put_var(ncid_out, varid_out(m), o3_out(nbp_lat:1:-1, :, :, m))
-       ! (The order of "rlatu" is inverted in the output file)
-    end do
-
-    call nf95_close(ncid_out)
-
-  end subroutine regr_lat_time_climoz
-
-  !********************************************
-
-  subroutine prepare_out(ncid_in, n_plev, ncid_out, varid_out, varid_plev, &
-       varid_time)
-
-    ! This subroutine creates the NetCDF output file, defines
-    ! dimensions and variables, and writes one of the coordinate variables.
-
-    use mod_grid_phy_lmdz, ONLY : nbp_lat
-    use netcdf95, only: nf95_create, nf95_def_dim, nf95_def_var, &
-         nf95_put_att, nf95_enddef, nf95_copy_att, nf95_put_var
-    use netcdf, only: nf90_clobber, nf90_float, nf90_global
-    use nrtype, only: pi
-    use regular_lonlat_mod, only : lat_reg
-
-    integer, intent(in):: ncid_in, n_plev
-    integer, intent(out):: ncid_out, varid_plev, varid_time
-
-    integer, intent(out):: varid_out(:) ! dim(1 or 2)
-    ! "varid_out(1)" is for average ozone day and night,
-    ! "varid_out(2)" is for daylight ozone.
-
-    ! Variables local to the procedure:
-
-    integer ncerr
-    integer dimid_rlatu, dimid_plev, dimid_time
-    integer varid_rlatu
-
-    !---------------------------
-
-    print *, "Call sequence information: prepare_out"
-
-    call nf95_create("climoz_LMDZ.nc", nf90_clobber, ncid_out)
-
-    ! Dimensions:
-    call nf95_def_dim(ncid_out, "time", 360, dimid_time)
-    call nf95_def_dim(ncid_out, "plev", n_plev, dimid_plev)
-    call nf95_def_dim(ncid_out, "rlatu", nbp_lat, dimid_rlatu)
-
-    ! Define coordinate variables:
-
-    call nf95_def_var(ncid_out, "time", nf90_float, dimid_time, varid_time)
-    call nf95_put_att(ncid_out, varid_time, "units", "days since 2000-1-1")
-    call nf95_put_att(ncid_out, varid_time, "calendar", "360_day")
-    call nf95_put_att(ncid_out, varid_time, "standard_name", "time")
-
-    call nf95_def_var(ncid_out, "plev", nf90_float, dimid_plev, varid_plev)
-    call nf95_put_att(ncid_out, varid_plev, "units", "millibar")
-    call nf95_put_att(ncid_out, varid_plev, "standard_name", "air_pressure")
-    call nf95_put_att(ncid_out, varid_plev, "long_name", "air pressure")
-
-    call nf95_def_var(ncid_out, "rlatu", nf90_float, dimid_rlatu, varid_rlatu)
-    call nf95_put_att(ncid_out, varid_rlatu, "units", "degrees_north")
-    call nf95_put_att(ncid_out, varid_rlatu, "standard_name", "latitude")
-
-    ! Define the primary variables:
-
-    call nf95_def_var(ncid_out, "tro3", nf90_float, &
-         (/dimid_rlatu, dimid_plev, dimid_time/), varid_out(1))
-    call nf95_put_att(ncid_out, varid_out(1), "long_name", &
-         "ozone mole fraction")
-    call nf95_put_att(ncid_out, varid_out(1), "standard_name", &
-         "mole_fraction_of_ozone_in_air")
-
-    if (size(varid_out) == 2) then
-       call nf95_def_var(ncid_out, "tro3_daylight", nf90_float, &
-            (/dimid_rlatu, dimid_plev, dimid_time/), varid_out(2))
-       call nf95_put_att(ncid_out, varid_out(2), "long_name", &
-            "ozone mole fraction in daylight")
-    end if
-
-    ! Global attributes:
-
-    ! The following commands, copying attributes, may fail.
-    ! That is OK.
-    ! It should just mean that the attribute is not defined in the input file.
-
-    call nf95_copy_att(ncid_in, nf90_global, "Conventions", ncid_out, &
-         nf90_global, ncerr)
-    call handle_err_copy_att("Conventions")
-
-    call nf95_copy_att(ncid_in, nf90_global, "title", ncid_out, nf90_global, &
-         ncerr)
-    call handle_err_copy_att("title")
-
-    call nf95_copy_att(ncid_in, nf90_global, "institution", ncid_out, &
-         nf90_global, ncerr)
-    call handle_err_copy_att("institution")
-
-    call nf95_copy_att(ncid_in, nf90_global, "source", ncid_out, nf90_global, &
-         ncerr)
-    call handle_err_copy_att("source")
-
-    call nf95_put_att(ncid_out, nf90_global, "comment", "Regridded for LMDZ")
-
-    call nf95_enddef(ncid_out)
-
-    ! Write one of the coordinate variables:
-    call nf95_put_var(ncid_out, varid_rlatu, lat_reg(nbp_lat:1:-1) / pi * 180.)
-    ! (convert from rad to degrees and sort in ascending order)
-
-  contains
-
-    subroutine handle_err_copy_att(att_name)
-
-      use netcdf, only: nf90_noerr, nf90_strerror
-
-      character(len=*), intent(in):: att_name
-
-      !----------------------------------------
-
-      if (ncerr /= nf90_noerr) then
-         print *, "regr_lat_time_climoz_m prepare_out nf95_copy_att " &
-              // att_name // " -- " // trim(nf90_strerror(ncerr))
-      end if
-
-    end subroutine handle_err_copy_att
-
-  end subroutine prepare_out
-
-end module regr_lat_time_climoz_m
Index: LMDZ5/branches/testing/libf/phylmd/regr_lat_time_coefoz_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/regr_lat_time_coefoz_m.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/regr_lat_time_coefoz_m.F90	(revision 2839)
@@ -41,6 +41,6 @@
 
     use mod_grid_phy_lmdz, ONLY : nbp_lat
-    use regr1_conserv_m, only: regr1_conserv
-    use regr3_lint_m, only: regr3_lint
+    use regr_conserv_m, only: regr_conserv
+    use regr_lint_m, only: regr_lint
     use netcdf95, only: nf95_open, nf95_close, nf95_inq_varid, handle_err, &
          nf95_put_var, nf95_gw_var
@@ -84,5 +84,5 @@
     ! Last dimension is month number.)
 
-    real, allocatable:: o3_par_out(:, :, :) ! (jjm + 1, n_plev, 360)
+    real, allocatable:: o3_par_out(:, :, :) ! (jjm + 1, n_plev, ndays)
     ! (regridded ozone parameter)
     ! ("o3_par_out(j, l, day)" is at latitude "rlatu(j)", pressure
@@ -162,5 +162,5 @@
     latitude = latitude / 180. * pi
     n_lat = size(latitude)
-    ! We need to supply the latitudes to "regr1_conserv" in
+    ! We need to supply the latitudes to "regr_conserv" in
     ! ascending order, so invert order if necessary:
     desc_lat = latitude(1) > latitude(n_lat)
@@ -209,5 +209,5 @@
        ! We average with respect to sine of latitude, which is
        ! equivalent to weighting by cosine of latitude:
-       call regr1_conserv(o3_par_in, xs = sin(lat_in_edg), &
+       call regr_conserv(1, o3_par_in, xs = sin(lat_in_edg), &
             xt = (/-1., sin((/boundslat_reg(nbp_lat-1:1:-1,south)/)), 1./), &
             vt = v_regr_lat(nbp_lat:1:-1, :, 1:12))
@@ -221,5 +221,5 @@
 
        ! Regrid in time by linear interpolation:
-       o3_par_out = regr3_lint(v_regr_lat, tmidmonth, tmidday)
+       call regr_lint(3, v_regr_lat, tmidmonth, tmidday, o3_par_out)
 
        ! Write to file:
Index: LMDZ5/branches/testing/libf/phylmd/regr_pr_av_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/regr_pr_av_m.F90	(revision 2787)
+++ 	(revision )
@@ -1,124 +1,0 @@
-! $Id$
-module regr_pr_av_m
-
-  ! Author: Lionel GUEZ
-
-  implicit none
-
-contains
-
-  subroutine regr_pr_av(ncid, name, julien, press_in_edg, paprs, v3)
-
-    ! "regr_pr_av" stands for "regrid pressure averaging".
-    ! In this procedure:
-    ! -- the root process reads 2D latitude-pressure fields from a
-    !    NetCDF file, at a given day.
-    ! -- the fields are packed to the LMDZ horizontal "physics"
-    !    grid and scattered to all threads of all processes;
-    ! -- in all the threads of all the processes, the fields are regridded in
-    !    pressure to the LMDZ vertical grid.
-    ! We assume that, in the input file, the fields have 3 dimensions:
-    ! latitude, pressure, julian day.
-    ! We assume that the input fields are already on the "rlatu"
-    ! latitudes, except that latitudes are in ascending order in the input
-    ! file.
-    ! We assume that all the inputs fields have the same coordinates.
-
-    ! The target vertical LMDZ grid is the grid of layer boundaries.
-    ! Regridding in pressure is conservative, second order.
-
-    ! All the fields are regridded as a single multi-dimensional array
-    ! so it saves CPU time to call this procedure once for several NetCDF
-    ! variables rather than several times, each time for a single
-    ! NetCDF variable.
-
-    use dimphy, only: klon
-    use netcdf95, only: nf95_inq_varid, handle_err
-    use netcdf, only: nf90_get_var
-    use assert_m, only: assert
-    use assert_eq_m, only: assert_eq
-    use regr1_conserv_m, only: regr1_conserv
-    use slopes_m, only: slopes
-    use mod_phys_lmdz_mpi_data, only: is_mpi_root
-    use mod_grid_phy_lmdz, only: nbp_lon, nbp_lat, nbp_lev
-    use mod_phys_lmdz_transfert_para, only: scatter2d
-    ! (pack to the LMDZ horizontal "physics" grid and scatter)
-
-    integer, intent(in):: ncid ! NetCDF ID of the file
-    character(len=*), intent(in):: name(:) ! of the NetCDF variables
-    integer, intent(in):: julien ! jour julien, 1 <= julien <= 360
-
-    real, intent(in):: press_in_edg(:)
-    ! edges of pressure intervals for input data, in Pa, in strictly
-    ! ascending order
-
-    real, intent(in):: paprs(:, :) ! (klon, llm + 1)
-    ! (pression pour chaque inter-couche, en Pa)
-
-    real, intent(out):: v3(:, :, :) ! (klon, llm, size(name))
-    ! regridded fields on the partial "physics" grid
-    ! "v3(i, k, l)" is at longitude "xlon(i)", latitude
-    ! "xlat(i)", in pressure interval "[paprs(i, k+1), paprs(i, k)]",
-    ! for NetCDF variable "name(l)".
-
-    ! Variables local to the procedure:
-
-    integer varid, ncerr ! for NetCDF
-
-    real  v1(nbp_lon, nbp_lat, size(press_in_edg) - 1, size(name))
-    ! input fields at day "julien", on the global "dynamics" horizontal grid
-    ! First dimension is for longitude.
-    ! The values are the same for all longitudes.
-    ! "v1(:, j, k, l)" is at latitude "rlatu(j)", for
-    ! pressure interval "[press_in_edg(k), press_in_edg(k+1)]" and
-    ! NetCDF variable "name(l)".
-
-    real v2(klon, size(press_in_edg) - 1, size(name))
-    ! fields scattered to the partial "physics" horizontal grid
-    ! "v2(i, k, l)" is at longitude "xlon(i)", latitude "xlat(i)",
-    ! for pressure interval "[press_in_edg(k), press_in_edg(k+1)]" and
-    ! NetCDF variable "name(l)".
-
-    integer i, n_var
-
-    !--------------------------------------------
-
-    call assert(size(v3, 1) == klon, size(v3, 2) == nbp_lev, &
-         "regr_pr_av v3 klon")
-    n_var = assert_eq(size(name), size(v3, 3), "regr_pr_av v3 n_var")
-    call assert(shape(paprs) == (/klon, nbp_lev+1/), "regr_pr_av paprs")
-
-    !$omp master
-    if (is_mpi_root) then
-       do i = 1, n_var
-          call nf95_inq_varid(ncid, trim(name(i)), varid)
-          
-          ! Get data at the right day from the input file:
-          ncerr = nf90_get_var(ncid, varid, v1(1, :, :, i), &
-               start=(/1, 1, julien/))
-          call handle_err("regr_pr_av nf90_get_var " // trim(name(i)), ncerr, &
-               ncid)
-       end do
-       
-       ! Latitudes are in ascending order in the input file while
-       ! "rlatu" is in descending order so we need to invert order:
-       v1(1, :, :, :) = v1(1, nbp_lat:1:-1, :, :)
-
-       ! Duplicate on all longitudes:
-       v1(2:, :, :, :) = spread(v1(1, :, :, :), dim=1, ncopies=nbp_lon-1)
-    end if
-    !$omp end master
-
-    call scatter2d(v1, v2)
-
-    ! Regrid in pressure at each horizontal position:
-    do i = 1, klon
-       call regr1_conserv(v2(i, :, :), press_in_edg, &
-            paprs(i, nbp_lev + 1:1:-1), v3(i, nbp_lev:1:-1, :), &
-            slopes(v2(i, :, :), press_in_edg))
-       ! (invert order of indices because "paprs" is in descending order)
-    end do
-
-  end subroutine regr_pr_av
-
-end module regr_pr_av_m
Index: LMDZ5/branches/testing/libf/phylmd/regr_pr_comb_coefoz_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/regr_pr_comb_coefoz_m.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/regr_pr_comb_coefoz_m.F90	(revision 2839)
@@ -76,5 +76,5 @@
     use dimphy, only: klon
     use mod_phys_lmdz_mpi_data, only: is_mpi_root
-    use regr_pr_av_m, only: regr_pr_av
+    use regr_pr_time_av_m, only: regr_pr_time_av
     use regr_pr_int_m, only: regr_pr_int
     use press_coefoz_m, only: press_in_edg, plev
@@ -128,6 +128,6 @@
     !$omp end master
 
-    call regr_pr_av(ncid, (/"a2       ", "a4       ", "a6       ", &
-         "P_net_Mob", "r_Mob    ", "temp_Mob ", "R_Het    "/), julien, &
+    call regr_pr_time_av(ncid, (/"a2       ", "a4       ", "a6       ", &
+         "P_net_Mob", "r_Mob    ", "temp_Mob ", "R_Het    "/), REAL(julien-1), &
          press_in_edg, paprs, coefoz)
     a2 = coefoz(:, :, 1)
Index: LMDZ5/branches/testing/libf/phylmd/regr_pr_int_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/regr_pr_int_m.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/regr_pr_int_m.F90	(revision 2839)
@@ -28,5 +28,5 @@
     use netcdf, only: nf90_get_var
     use assert_m, only: assert
-    use regr1_lint_m, only: regr1_lint
+    use regr_lint_m, only: regr_lint
     use mod_phys_lmdz_mpi_data, only: is_mpi_root
     use mod_grid_phy_lmdz, only: nbp_lon, nbp_lat, nbp_lev
@@ -97,5 +97,6 @@
     ! Regrid in pressure at each horizontal position:
     do i = 1, klon
-       v3(i, nbp_lev:1:-1) = regr1_lint(v2(i, :), (/0., plev/), pplay(i, nbp_lev:1:-1))
+       call regr_lint(1, v2(i, :), (/0., plev/), pplay(i, nbp_lev:1:-1), &
+                         v3(i, nbp_lev:1:-1))
        ! (invert order of indices because "pplay" is in descending order)
     end do
Index: LMDZ5/branches/testing/libf/phylmd/regr_pr_o3_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/regr_pr_o3_m.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/regr_pr_o3_m.F90	(revision 2839)
@@ -28,5 +28,5 @@
     use netcdf, only:  nf90_nowrite, nf90_get_var
     use assert_m, only: assert
-    use regr1_conserv_m, only: regr1_conserv
+    use regr_conserv_m, only: regr_conserv
     use press_coefoz_m, only: press_in_edg
     use time_phylmdz_mod, only: day_ref
@@ -75,5 +75,5 @@
     ! Poles:
     do j = 1, nbp_lat, nbp_lat-1
-       call regr1_conserv(r_mob(j, :), press_in_edg, &
+       call regr_conserv(1, r_mob(j, :), press_in_edg, &
             p3d(1, j, nbp_lev + 1:1:-1), o3_mob_regr(1, j, nbp_lev:1:-1))
        ! (invert order of indices because "p3d" is in descending order)
@@ -83,5 +83,5 @@
     do j = 2, nbp_lat-1
        do i = 1, nbp_lon
-          call regr1_conserv(r_mob(j, :), press_in_edg, &
+          call regr_conserv(1, r_mob(j, :), press_in_edg, &
                p3d(i, j, nbp_lev + 1:1:-1), o3_mob_regr(i, j, nbp_lev:1:-1))
           ! (invert order of indices because "p3d" is in descending order)
Index: LMDZ5/branches/testing/libf/phylmd/regr_pr_time_av_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/regr_pr_time_av_m.F90	(revision 2839)
+++ LMDZ5/branches/testing/libf/phylmd/regr_pr_time_av_m.F90	(revision 2839)
@@ -0,0 +1,403 @@
+! $Id$
+MODULE regr_pr_time_av_m
+
+  USE print_control_mod, ONLY: lunout
+  USE write_field_phy
+  USE mod_phys_lmdz_transfert_para, ONLY: bcast
+  IMPLICIT NONE
+
+!-------------------------------------------------------------------------------
+! Purpose: Regrid pressure with an averaging method. Operations done:
+!  * on the root process: read a NetCDF 3D or 4D field at a given day.
+!  * pack the fields to the LMDZ "horizontal "physics" grid and scatter
+!    to all threads of all processes;
+!  * in all the threads of all the processes, regrid the fields in pressure
+!    to the LMDZ vertical grid.
+!  * input files fields are stretched in the viscinity (+/- 5 kms) of the mean
+!    tropopause (geometrical mean of LMDZ and input fields tropopauses) to force
+!    the resulting field tropopause height to the one of LMDZ. To switch this
+!    feature on, the following arguments must be present:
+!     - "lat_in":   input file latitudes.
+!     - "pcen_in":  input file cells center pressure levels.
+!     - "ptrop_ou": target grid (LMDZ) tropopause pressure.
+!    Note that the ozone quantity conservation is not ensured.
+!-------------------------------------------------------------------------------
+! Initial routine: regr_pr_av_m module (L. Guez).
+! Present version: David Cugnet ; corresponding additions:
+!    - time interpolation
+!    - 3D compliant
+!    - vertical stretching of the field to allow tropopause and ground pressure
+!      matching between input field and current lmdz field.
+!-------------------------------------------------------------------------------
+! Remarks:
+!  * 3D fields are zonal means, with dimensions (latitude, pressure, julian day)
+!  * 4D fields have the dimensions:  (longitude, latitude, pressure, julian day)
+!  * All the fields are already on the horizontal grid (rlatu) or (rlatu,rlonv),
+!    except that the latitudes are in ascending order in the input file.
+!  * We assume that all the input fields have the same coordinates.
+!  * The target vertical LMDZ grid is the grid of layer boundaries.
+!  * Regridding in pressure is conservative, second order.
+!  * All the fields are regridded as a single multi-dimensional array, so it
+!    saves CPU time to call this procedure once for several NetCDF variables
+!    rather than several times, each time for a single NetCDF variable.
+!  * The input file pressure at tropopause can be (in decreasing priority):
+!    1) read from the file if "tropopause_air_pressure" field is available.
+!    2) computed from the input file ozone field using:
+!       - o3 concentration at tropopause if "tro3_at_tropopause" is available.
+!       - a default value (100ppbv) if not.
+!  * If available, the field "ps" (input file pressure at surface) is used.
+!    If not, the current LMDZ ground pressure is taken instead.
+!  * The O3 threshold for tropopause is defined using 3 coefficients:
+!    o3t(ppbV)=co1+co2*SIN(PI*(month-2)/6)*TANH(lat_deg/c)
+!     => co1 and co2 are in ppmV, and co3 in degrees.
+!     => co3 allow a smooth transition between north and south hemispheres.
+!-------------------------------------------------------------------------------
+! * Fields with suffix "m"/"p" are at the closest records earlier/later than the
+!   middle of the julian day "julien", on the global "dynamics" horizontal grid.
+! * Fields(i,j,k,l) are at longitude-latitude "rlonv(i)-rlatu(j)", pressure
+!   interval "pint_in(k:k+1)]" and variable "nam(l)".
+! * In the 2D file case, the values are the same for all longitudes.
+! * The following fields are on the global "dynamics" grid, as read from files:
+  REAL,    SAVE, ALLOCATABLE :: v1m(:,:,:,:)       !--- Previous ozone fields
+  REAL,    SAVE, ALLOCATABLE :: v1p(:,:,:,:)       !--- Next ozone fields
+  REAL,    SAVE, ALLOCATABLE :: psm(:,:), psp(:,:) !--- Surface pressure
+  REAL,    SAVE, ALLOCATABLE :: ptm(:,:), ptp(:,:) !--- Tropopause pressure
+  REAL,    SAVE, ALLOCATABLE :: otm(:,:), otp(:,:) !--- Tropopause o3 mix. ratio
+  INTEGER, SAVE :: irec                            !--- Current time index
+!      * for daily   input files: current julian day number
+!      * for monthly input files: julien is in [time_in(irec),time_in(irec+1)]
+  LOGICAL, SAVE :: linterp                         !--- Interpolation in time
+  LOGICAL, SAVE :: lPrSurf                         !--- Surface pressure flag
+  LOGICAL, SAVE :: lPrTrop                         !--- Tropopause pressure flag
+  LOGICAL, SAVE :: lO3Trop                         !--- Tropopause ozone flag
+  LOGICAL, SAVE :: lfirst=.TRUE.                   !--- First call flag
+!$OMP THREADPRIVATE(lfirst)
+  REAL, PARAMETER :: co3(3)=[91.,28.,20.]          !--- Coeffs for o3 threshold
+  REAL, PARAMETER :: prtrop=5.E+3  !--- Value lower than the tropopause pressure
+  REAL, PARAMETER :: delta =5.     !--- Dist. around tropopause for strain (kms)
+
+CONTAINS
+
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE regr_pr_time_av(fID, nam, julien, pint_in, pint_ou, v3, time_in,    &
+                                     lat_in, pcen_in, ptrop_ou)
+!
+!-------------------------------------------------------------------------------
+  USE dimphy,         ONLY: klon
+  USE netcdf95,       ONLY: NF95_INQ_VARID, NF95_INQUIRE_VARIABLE, handle_err
+  USE netcdf,         ONLY: NF90_INQ_VARID, NF90_GET_VAR, NF90_NOERR
+  USE assert_m,       ONLY: assert
+  USE assert_eq_m,    ONLY: assert_eq
+  USE comvert_mod,    ONLY: scaleheight
+  USE interpolation,  ONLY: locate
+  USE regr_conserv_m, ONLY: regr_conserv
+  USE regr_lint_m,    ONLY: regr_lint
+  USE slopes_m,       ONLY: slopes
+  USE mod_phys_lmdz_mpi_data,       ONLY: is_mpi_root
+  USE mod_grid_phy_lmdz,            ONLY: nbp_lon, nbp_lat, nbp_lev
+  USE mod_phys_lmdz_transfert_para, ONLY: scatter2d, scatter
+  USE phys_cal_mod,                 ONLY: calend, year_len, days_elapsed, jH_cur
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER, INTENT(IN)  :: fID           !--- NetCDF file ID
+  CHARACTER(LEN=13), INTENT(IN) :: nam(:)     !--- NetCDF variables names
+  REAL,    INTENT(IN)  :: julien        !--- Days since Jan 1st
+  REAL,    INTENT(IN)  :: pint_in(:)    !--- Interfaces file Pres, Pa, ascending
+  REAL,    INTENT(IN)  :: pint_ou(:,:)  !--- Interfaces LMDZ Pres, Pa (klon,llm+1)
+  REAL,    INTENT(OUT) :: v3(:,:,:)     !--- Regridded field (klon,llm,SIZE(nam))
+  REAL,    INTENT(IN), OPTIONAL :: time_in(:) !--- Records times, in days
+                                              !    since Jan 1 of current year
+  REAL,    INTENT(IN), OPTIONAL :: lat_in(:)  !--- Input/output latitudes vector
+  REAL,    INTENT(IN), OPTIONAL :: pcen_in(:) !--- Mid-layers file pressure
+  REAL,    INTENT(IN), OPTIONAL :: ptrop_ou(:)!--- Output tropopause pressure (klon)
+!-------------------------------------------------------------------------------
+! Local variables:
+  include "clesphys.h"
+  include "YOMCST.h"
+  CHARACTER(LEN=80)  :: sub
+  CHARACTER(LEN=320) :: msg
+  INTEGER :: vID, ncerr, n_var, nlev_in,ntim_in, ndim, i, ibot, itop, itrp,itrp0
+  LOGICAL :: lAdjTro                          !--- Need to adjust tropopause
+  REAL    :: y_frac                           !--- Elapsed year fraction
+  REAL    :: alpha, beta, al                  !--- For strectching/interpolation
+  REAL    :: SigT_in, SigT_ou, SigT_mn        !--- Tropopause: in/out/mean
+  REAL    :: SigA_bot, SigA_top               !--- Strained domain bounds
+  REAL    :: Sig_in (SIZE(pint_in))           !--- Input field sigma levels
+  REAL    :: phi    (SIZE(pint_in))           !--- Stretching exponent anomaly
+  REAl    :: Pint_st(SIZE(pint_in))           !--- Stretched pressure levels
+  REAL    :: v1(nbp_lon,nbp_lat,SIZE(pint_in)-1,SIZE(nam))
+  REAL    :: v2(klon,           SIZE(pint_in)-1,SIZE(nam))
+! v1: Field read/interpol at time "julien" on the global "dynamics" horiz. grid.
+! v2: Field scattered to the partial "physics" horizontal grid.
+!     In the 2D file case, the values are the same for all longitudes.
+!     "v2(i,    k, l)" is at longitude-latitude  "xlon(i)-xlat(i)".
+! Both are for pressure interval "press_in_edg(k:k+1)]" and variable "nam(l)"
+  REAL, DIMENSION(nbp_lon, nbp_lat) ::  ps1, pt1, ot1
+  REAL, DIMENSION(klon)             ::  ps2, pt2, ot2
+!-------------------------------------------------------------------------------
+  sub="regr_pr_time_av"
+  nlev_in=SIZE(pint_in)-1; ntim_in=SIZE(time_in)
+  CALL assert(SIZE(v3,1)==klon,                 TRIM(sub)//" v3 klon")
+  CALL assert(SIZE(v3,2)==nbp_lev,              TRIM(sub)//" v3 nbp_lev")
+  n_var = assert_eq(SIZE(nam), SIZE(v3,3),      TRIM(sub)//" v3 n_var")
+  CALL assert(SHAPE(pint_ou)==[klon, nbp_lev+1],TRIM(sub)//" pint_ou")
+  IF(PRESENT(lat_in))   CALL assert(SIZE(lat_in  )==klon,TRIM(sub)//" lat_in klon")
+  IF(PRESENT(ptrop_ou)) CALL assert(SIZE(ptrop_ou)==klon,TRIM(sub)//" ptrop_ou klon")
+  IF(PRESENT(pcen_in))  CALL assert(SIZE(pcen_in)==nlev_in,TRIM(sub)//" pcen_in")
+  lAdjTro=PRESENT(ptrop_ou)
+  IF(lAdjTro.AND.(.NOT.PRESENT(lat_in).OR..NOT.PRESENT(pcen_in))) &
+  CALL abort_physic(sub, 'Missing lat_in and/or pcen_in (adjust_tropopause=T)', 1)
+
+  !$OMP MASTER
+  IF(is_mpi_root) THEN
+
+    !=== CHECK WHICH FIELDS ARE AVAILABLE IN THE INPUT FILE
+    IF(lfirst) THEN
+      lPrSurf=NF90_INQ_VARID(fID,"ps"                     ,vID)==NF90_NOERR
+      lPrTrop=NF90_INQ_VARID(fID,"tropopause_air_pressure",vID)==NF90_NOERR
+      lO3Trop=NF90_INQ_VARID(fID,"tro3_at_tropopause"     ,vID)==NF90_NOERR
+      linterp=PRESENT(time_in); IF(linterp) linterp=ntim_in==14
+      IF(linterp) THEN
+        ALLOCATE(v1m(nbp_lon,nbp_lat,nlev_in,n_var))
+        ALLOCATE(v1p(nbp_lon,nbp_lat,nlev_in,n_var))
+        ALLOCATE(psm(nbp_lon,nbp_lat),psp(nbp_lon,nbp_lat))
+        ALLOCATE(ptm(nbp_lon,nbp_lat),ptp(nbp_lon,nbp_lat))
+        IF(lO3Trop) ALLOCATE(otm(nbp_lon,nbp_lat),otp(nbp_lon,nbp_lat))
+      END IF
+      !--- INITIAL INDEX: LOCATE A LAYER WELL ABOVE TROPOPAUSE (50hPa)
+      IF(lAdjTro) itrp0=locate(pcen_in,prtrop)
+      IF(lPrSurf) WRITE(lunout,*)TRIM(sub)//': Using GROUND PRESSURE from input O3 forcing file.'
+      IF(linterp) WRITE(lunout,*)TRIM(sub)//': Monthly O3 files => ONLINE TIME INTERPOLATION.'
+      IF(lAdjTro) THEN
+        WRITE(lunout,*)TRIM(sub)//': o3 forcing file tropopause location uses:'
+        IF(lPrTrop) THEN
+          WRITE(lunout,*)'    PRESSURE AT TROPOPAUSE from file.'
+        ELSE IF(lO3Trop) THEN
+          WRITE(lunout,*)'    O3 CONCENTRATION AT TROPOPAUSE from file.'
+        ELSE
+          WRITE(lunout,*)'    PARAMETRIZED O3 concentration at tropopause.'
+        END IF
+      END IF
+    END IF
+
+    !=== UPDATE (ALWAYS FOR DAILY FILES, EACH MONTH FOR MONTHLY FILES)
+    CALL update_fields()
+
+
+    !=== TIME INTERPOLATION FOR MONTHLY INPUT FILES
+    IF(linterp) THEN
+      WRITE(lunout,'(3(a,f7.3))')TRIM(sub)//': Interpolating O3 at julian day '&
+      &,julien,' from fields at times ',time_in(irec),' and ', time_in(irec+1)
+      al=(time_in(irec+1)-julien)/(time_in(irec+1)-time_in(irec))
+      v1=al*v1m+(1.-al)*v1p
+      IF(lPrSurf) ps1=al*psm+(1.-al)*psp
+      IF(lPrTrop) pt1=al*ptm+(1.-al)*ptp
+      IF(lO3Trop) ot1=al*otm+(1.-al)*otp
+    END IF
+  END IF
+  !$OMP END MASTER
+  IF(lfirst) THEN
+    lfirst=.FALSE. ;     CALL bcast(lfirst) ; CALL bcast(lPrSurf)
+    CALL bcast(lPrTrop); CALL bcast(lO3Trop); CALL bcast(linterp)
+    IF(lAdjTro) CALL bcast(itrp0)
+  END IF
+  CALL scatter2d(v1,v2)
+  !--- No "ps" in input file => assumed to be equal to current LMDZ ground press
+  IF(lPrSurf) THEN; CALL scatter2d(ps1,ps2); ELSE; ps2=Pint_ou(:,1); END IF
+  IF(lPrTrop) CALL scatter2d(pt1,pt2)
+  IF(lO3Trop) CALL scatter2d(ot1,ot2)
+
+  !--- REGRID IN PRESSURE ; 3rd index inverted because "paprs" is decreasing
+  IF(.NOT.lAdjTro) THEN
+    DO i=1,klon
+      CALL regr_conserv(1,v2(i,:,:) , Pint_in , Pint_ou(i,nbp_lev+1:1:-1),    &
+                          v3(i,nbp_lev:1:-1,:), slopes(1,v2(i,:,:),pint_in))
+    END DO
+  ELSE
+    y_frac=(REAL(days_elapsed)+jH_cur)/year_len
+    DO i=1,klon
+      SigT_in = get_SigTrop(i,itrp)        !--- input  (file) tropopause
+      SigT_ou = ptrop_ou(i)/pint_ou(i,1)   !--- output (lmdz) tropopause
+      SigT_mn = SQRT(SigT_in*SigT_ou)      !--- mean tropopause>strained domain
+
+      !--- DEFINE THE VERTICAL LAYER IN WHICH THE PROFILE IS STRECHED
+      beta=EXP(delta/scaleheight); Sig_in(:) = [pint_in(1:nlev_in)/ps2(i),1.]
+      SigA_bot = SigT_mn*beta ; ibot=locate(Sig_in(:),SigA_bot)
+      SigA_top = SigT_mn/beta ; itop=locate(Sig_in(:),SigA_top)+1
+
+      !--- HAT FUNCTION phi (/=0 in [SigA_bot,SigA_top] only)
+      phi(:)=0.
+      phi(itop:itrp)=(Sig_in(itop:itrp)-SigA_top)/(SigT_in-SigA_top)
+      phi(itrp:ibot)=(SigA_bot-Sig_in(itrp:ibot))/(SigA_bot-SigT_in)
+
+      !--- STRAINED INPUT logP PROFILE ; alpha: MAX. STRETCH. EXPONENT INCREMENT
+      alpha = LOG(SigT_ou/SigT_in)/LOG(SigT_in)
+      Pint_st(:) = pint_ou(i,1) * Sig_in(:)**(1+alpha*phi(:))
+
+      !--- REGRID INPUT PROFILE ON STRAINED VERTICAL LEVELS
+      CALL regr_conserv(1,v2(i,:,:) , Pint_st,  Pint_ou(i,nbp_lev+1:1:-1),     &
+                          v3(i,nbp_lev:1:-1,:), slopes(1,v2(i,:,:),Pint_st))
+    END DO
+  END IF
+
+
+CONTAINS
+
+
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE update_fields()
+!
+!-------------------------------------------------------------------------------
+  IF(.NOT.linterp) THEN                 !=== DAILY FILES: NO TIME INTERPOLATION
+    WRITE(lunout,*)TRIM(sub)//': Updating Ozone forcing field: read from file.'
+    irec=MIN(INT(julien)+1,ntim_in)     !--- irec is just the julian day number
+    !--- MIN -> Security in the unlikely case of roundup errors.
+    CALL get_3Dfields(v1)               !--- Read ozone field(s)
+    IF(lAdjTro) THEN                    !--- Additional files for fields strain
+      IF(lPrSurf) CALL get_2Dfield(ps1,"ps")
+      IF(lPrTrop) CALL get_2Dfield(pt1,"tropopause_air_pressure")
+      IF(lO3Trop) CALL get_2Dfield(ot1,"tro3_at_tropopause")
+    END IF
+  ELSE                                  !=== MONTHLY FILES: GET 2 NEAREST RECS
+    IF(.NOT.lfirst.AND.julien<time_in(irec+1)) RETURN
+    WRITE(lunout,*)TRIM(sub)//': Refreshing adjacent Ozone forcing fields.'
+    IF(lfirst) THEN                     !=== READ EARLIEST TIME FIELDS
+      irec=locate(time_in,julien)       !--- Need to locate surrounding times
+      CALL get_3Dfields(v1m)            !--- Read ozone field(s)
+      IF(lAdjTro) THEN                  !--- Additional files for fields strain
+        IF(lPrSurf) CALL get_2Dfield(psm,"ps")
+        IF(lPrTrop) CALL get_2Dfield(ptm,"tropopause_air_pressure")
+        IF(lO3Trop) CALL get_2Dfield(otm,"tro3_at_tropopause")
+      END IF
+    ELSE                                !=== SHIFT FIELDS
+      v1m=v1p                           !--- Ozone fields
+      IF(lAdjTro) THEN                  !--- Additional files for fields strain
+        IF(lPrSurf) psm=psp             !--- Surface pressure
+        IF(lPrTrop) ptm=ptp             !--- Tropopause pressure
+        IF(lO3Trop) otm=otp             !--- Tropopause ozone
+      END IF
+    END IF
+    irec=irec+1
+    CALL get_3Dfields(v1p)              !--- Read ozone field(s)
+    IF(lAdjTro) THEN                    !--- Additional files for fields strain
+      IF(lPrSurf) CALL get_2Dfield(psp,"ps")
+      IF(lPrTrop) CALL get_2Dfield(ptp,"tropopause_air_pressure")
+      IF(lO3Trop) CALL get_2Dfield(otp,"tro3_at_tropopause")
+    END IF
+    IF(lfirst) irec=irec-1
+  END IF
+
+END SUBROUTINE update_fields
+!
+!-------------------------------------------------------------------------------
+
+
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE get_2Dfield(v,var)
+!
+!-------------------------------------------------------------------------------
+! Purpose: Shortcut to get the "irec"th record of the surface field named "var"
+!          from the input file.
+! Remark: In case the field is zonal, it is duplicated along first dimension.
+!-------------------------------------------------------------------------------
+! Arguments:
+  REAL,             INTENT(INOUT) :: v(:,:)
+  CHARACTER(LEN=*), INTENT(IN)    :: var
+!-------------------------------------------------------------------------------
+  CALL NF95_INQ_VARID(fID, TRIM(var), vID)
+  CALL NF95_INQUIRE_VARIABLE(fID, vID, ndims=ndim)
+  IF(ndim==2) ncerr=NF90_GET_VAR(fID,vID,v(1,:), start=[  1,irec])
+  IF(ndim==3) ncerr=NF90_GET_VAR(fID,vID,v(:,:), start=[1,1,irec])
+  CALL handle_err(TRIM(sub)//" NF90_GET_VAR "//TRIM(var),ncerr,fID)
+
+  !--- Flip latitudes: ascending in input file, descending in "rlatu".
+  IF(ndim==3) THEN
+    v(1,:) = v(1,nbp_lat:1:-1)
+    v(2:,:)= SPREAD(v(1,:),DIM=1,ncopies=nbp_lon-1)  !--- Duplication
+  ELSE
+    v(:,:) = v(:,nbp_lat:1:-1)
+  END IF
+
+END SUBROUTINE get_2Dfield
+!
+!-------------------------------------------------------------------------------
+
+
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE get_3Dfields(v)
+!
+!-------------------------------------------------------------------------------
+! Purpose: Shortcut to get the "irec"th record of the 3D fields named "nam"
+!          from the input file. Fields are stacked on fourth dimension.
+! Remark: In case the field is zonal, it is duplicated along first dimension.
+!-------------------------------------------------------------------------------
+! Arguments:
+  REAL, INTENT(INOUT) :: v(:,:,:,:)
+!-------------------------------------------------------------------------------
+  DO i=1,SIZE(nam)
+    CALL NF95_INQ_VARID(fID, TRIM(nam(i)), vID)
+    CALL NF95_INQUIRE_VARIABLE(fID, vID, ndims=ndim)
+    IF(ndim==3) ncerr=NF90_GET_VAR(fID,vID,v(1,:,:,i), start=[  1,1,irec])
+    IF(ndim==4) ncerr=NF90_GET_VAR(fID,vID,v(:,:,:,i), start=[1,1,1,irec])
+    CALL handle_err(TRIM(sub)//" NF90_GET_VAR "//TRIM(nam(i)),ncerr,fID)
+  END DO
+
+  !--- Flip latitudes: ascending in input file, descending in "rlatu".
+  IF(ndim==3) THEN
+    v(1,:,:,:) = v(1,nbp_lat:1:-1,:,:)
+    v(2:,:,:,:)= SPREAD(v(1,:,:,:),DIM=1,ncopies=nbp_lon-1)  !--- Duplication
+  ELSE
+    v(:,:,:,:) = v(:,nbp_lat:1:-1,:,:)
+  END IF
+
+END SUBROUTINE get_3Dfields
+!
+!-------------------------------------------------------------------------------
+
+
+!-------------------------------------------------------------------------------
+!
+FUNCTION get_SigTrop(ih,it)
+!
+!-------------------------------------------------------------------------------
+! Arguments:
+  INTEGER, INTENT(IN)  :: ih
+  INTEGER, INTENT(OUT) :: it
+  REAL                 :: get_Sigtrop
+!-------------------------------------------------------------------------------
+! Local variables:
+  INTEGER :: ii                                !--- Idx of layer containing o3t
+  REAL    :: o3t                               !--- Ozone concent. at tropopause
+  REAL    :: prt                               !--- Air pressure   at tropopause
+  REAL    :: al                                !--- Interpolation coefficient
+  REAL    :: coef                              !--- Coef: North/South transition
+!-------------------------------------------------------------------------------
+  !--- DETERMINE PRESSURE AT TROPOPAUSE AND DIVIDE IT BY GROUND PRESSURE
+  IF(lPrTrop) THEN                             !--- PrTrop KNOWN FROM FILE
+    get_SigTrop=pt2(ih)/ps2(ih)
+    it=locate(pint_in(:),pt2(ih))
+  ELSE                                         !--- O3 THRESHOLD
+    coef = TANH(lat_in(i)/co3(3))              !--- Latitude dependant ponderat.
+    coef = SIN (2.*RPI*(y_frac-1./6.)) * coef  !--- Time-dependant ponderation
+    o3t  = 1.E-9 * (co3(1)+co3(2)*coef)        !--- Value from parametrization
+    IF(lO3Trop) o3t=ot2(ih)                    !--- Value from file
+    !--- Starts from 50hPa and go down.
+    it=itrp0; DO WHILE(v2(ih,it+1,1)>=o3t); it=it+1; END DO
+    al=(v2(ih,it,1)-o3t)/(v2(ih,it,1)-v2(ih,it+1,1))
+    get_SigTrop = ( pcen_in(it)**(1.-al) * pcen_in(it+1)**al )/ps2(ih)
+  END IF
+
+END FUNCTION get_SigTrop
+!
+!-------------------------------------------------------------------------------
+
+
+END SUBROUTINE regr_pr_time_av
+!
+!-------------------------------------------------------------------------------
+
+END MODULE regr_pr_time_av_m
Index: LMDZ5/branches/testing/libf/phylmd/rrtm/aeropt_5wv_rrtm.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/rrtm/aeropt_5wv_rrtm.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/rrtm/aeropt_5wv_rrtm.F90	(revision 2839)
@@ -12,5 +12,5 @@
   USE DIMPHY
   USE aero_mod
-  USE phys_local_var_mod, ONLY: od550aer,od865aer,ec550aer,od550lt1aer
+  USE phys_local_var_mod, ONLY: od443aer,od550aer,od865aer,ec550aer,od550lt1aer
   USE YOMCST, ONLY: RD,RG
 
@@ -327,5 +327,6 @@
         soluble=.TRUE.
         spsol=4
-        fac=1.375    ! (NH4)2-SO4/SO4 132/96 mass conversion factor for AOD
+        !fac=1.375    ! (NH4)2-SO4/SO4 132/96 mass conversion factor for AOD
+        fac=0.0      !--6 March 2017 - OB as Didier H said CSSO4 should not be used
     ELSEIF (aerosol_name(m).EQ.id_SSSSM_phy) THEN 
         soluble=.TRUE.
@@ -366,6 +367,8 @@
     DO la=1,las
 
-    !--only 550, 670 and 865 nm are used
-    IF (la.NE.la550.AND.la.NE.la670.AND.la.NE.la865) CYCLE
+    !--only 443, 550, 670 and 865 nm are used
+    !--to save time 670 and AI are not computed for CMIP6
+    !IF (la.NE.la443.AND.la.NE.la550.AND.la.NE.la670.AND.la.NE.la865) CYCLE
+    IF (la.NE.la443.AND.la.NE.la550.AND.la.NE.la865) CYCLE
 
       IF (soluble) THEN            ! For soluble aerosol
@@ -433,6 +436,7 @@
 
 !--AOD calculations for diagnostics
+  od443aer(:)=SUM(tausum(:,la443,:),dim=2)
   od550aer(:)=SUM(tausum(:,la550,:),dim=2)
-  od670aer(:)=SUM(tausum(:,la670,:),dim=2)
+  !od670aer(:)=SUM(tausum(:,la670,:),dim=2)
   od865aer(:)=SUM(tausum(:,la865,:),dim=2)
 
@@ -441,5 +445,6 @@
 
 !--aerosol index
-  ai(:)=-LOG(MAX(od670aer(:),1.e-8)/MAX(od865aer(:),1.e-8))/LOG(670./865.)
+  ai(:)=0.0
+  !ai(:)=-LOG(MAX(od670aer(:),1.e-8)/MAX(od865aer(:),1.e-8))/LOG(670./865.)
 
   od550lt1aer(:)=tausum(:,la550,id_ASSO4M_phy)+tausum(:,la550,id_ASBCM_phy) +tausum(:,la550,id_AIBCM_phy)+ &
Index: LMDZ5/branches/testing/libf/phylmd/rrtm/aeropt_6bands_rrtm.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/rrtm/aeropt_6bands_rrtm.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/rrtm/aeropt_6bands_rrtm.F90	(revision 2839)
@@ -566,5 +566,6 @@
         soluble=.TRUE.
         spsol=3
-        fac=1.375    ! (NH4)2-SO4/SO4 132/96 mass conversion factor for AOD
+        !fac=1.375    ! (NH4)2-SO4/SO4 132/96 mass conversion factor for AOD
+        fac=0.0      !--6 March 2017 - OB as Didier H said CSSO4 should not be used
      ELSEIF  (aerosol_name(m).EQ.id_ASSO4M_phy) THEN
         soluble=.TRUE.
Index: LMDZ5/branches/testing/libf/phylmd/rrtm/read_rsun_rrtm.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/rrtm/read_rsun_rrtm.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/rrtm/read_rsun_rrtm.F90	(revision 2839)
@@ -10,5 +10,5 @@
   USE netcdf, ONLY: nf90_get_var, nf90_noerr, nf90_nowrite
 
-  USE phys_cal_mod, ONLY : day_cur, year_len
+  USE phys_cal_mod, ONLY : days_elapsed, year_len
 
   USE mod_phys_lmdz_mpi_data, ONLY: is_mpi_root
@@ -23,10 +23,10 @@
 
   ! Input arguments
-  LOGICAL, INTENT(IN)          :: debut
+  LOGICAL, INTENT(IN) :: debut
 
 ! Local variables
-  INTEGER               :: ncid, dimid, varid, ncerr, nbday
+  INTEGER :: ncid, dimid, varid, ncerr, nbday
   REAL, POINTER :: wlen(:), time(:)
-  REAL, ALLOCATABLE, SAVE, DIMENSION(:,:)   :: SSI_FRAC
+  REAL, ALLOCATABLE, SAVE, DIMENSION(:,:) :: SSI_FRAC
 !$OMP THREADPRIVATE(SSI_FRAC)
   REAL, ALLOCATABLE, SAVE, DIMENSION(:) :: TSI(:)
@@ -90,15 +90,16 @@
     ENDIF
 
-!--only read at beginning of month
-    IF (debut.OR.day_cur.NE.day_pre) THEN
+!--only read at beginning of day
+!--day in year is provided as days_elapsed since the beginning of the year +1
+    IF (debut.OR.days_elapsed+1.NE.day_pre) THEN
 
-!--keep memory of previous month
-      day_pre=day_cur
+!--keep memory of previous day
+      day_pre=days_elapsed+1
 
 !--copy 
-      RSUN(1:NSW)=SSI_FRAC(:,day_cur)
-      solaire=TSI(day_cur)
+      RSUN(1:NSW)=SSI_FRAC(:,days_elapsed+1)
+      solaire=TSI(days_elapsed+1)
 
-      print *,'READ_RSUN_RRTM day=', day_cur,' solaire=', solaire, ' RSUN=', RSUN(1:NSW)
+      print *,'READ_RSUN_RRTM day=', days_elapsed+1,' solaire=', solaire, ' RSUN=', RSUN(1:NSW)
 
     ENDIF !--fin allocation
Index: LMDZ5/branches/testing/libf/phylmd/rrtm/readaerosol_optic_rrtm.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/rrtm/readaerosol_optic_rrtm.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/rrtm/readaerosol_optic_rrtm.F90	(revision 2839)
@@ -17,5 +17,5 @@
   USE phys_local_var_mod, only: sconcso4,sconcno3,sconcoa,sconcbc,sconcss,sconcdust, &
        concso4,concno3,concoa,concbc,concss,concdust,loadso4,loadoa,loadbc,loadss,loaddust, &
-       load_tmp1,load_tmp2,load_tmp3,load_tmp4,load_tmp5,load_tmp6,load_tmp7
+       loadno3, load_tmp1,load_tmp2,load_tmp3
 
   USE infotrac_phy
@@ -195,7 +195,7 @@
      IF ( flag_aerosol .EQ. 3 .OR. flag_aerosol .EQ. 6 ) THEN
 
-        CALL readaerosol_interp(id_ASPOMM_phy, itap, pdtphys, rjourvrai, debut, pplay, paprs, t_seri, pomsol, pomsol_pi, load_tmp3)
-        CALL readaerosol_interp(id_AIPOMM_phy, itap, pdtphys, rjourvrai, debut, pplay, paprs, t_seri, pomins, pomins_pi, load_tmp4)
-        loadoa(:)=load_tmp3(:)+load_tmp4(:)
+        CALL readaerosol_interp(id_ASPOMM_phy, itap, pdtphys, rjourvrai, debut, pplay, paprs, t_seri, pomsol, pomsol_pi, load_tmp1)
+        CALL readaerosol_interp(id_AIPOMM_phy, itap, pdtphys, rjourvrai, debut, pplay, paprs, t_seri, pomins, pomins_pi, load_tmp2)
+        loadoa(:)=load_tmp1(:)+load_tmp2(:)
      ELSE
         pomsol(:,:) = 0. ; pomsol_pi(:,:) = 0.
@@ -208,10 +208,10 @@
 
         CALL readaerosol_interp(id_SSSSM_phy ,itap, pdtphys,rjourvrai, &
-        debut, pplay, paprs, t_seri, sssupco, sssupco_pi, load_tmp5) 
+        debut, pplay, paprs, t_seri, sssupco, sssupco_pi, load_tmp1) 
         CALL readaerosol_interp(id_CSSSM_phy ,itap, pdtphys,rjourvrai, &
-        debut, pplay, paprs, t_seri, sscoarse,sscoarse_pi, load_tmp6) 
-        CALL readaerosol_interp(id_ASSSM_phy ,itap, pdtphys, rjourvrai, &
-        debut, pplay, paprs, t_seri, ssacu, ssacu_pi, load_tmp7) 
-        loadss(:)=load_tmp5(:)+load_tmp6(:)+load_tmp7(:)
+        debut, pplay, paprs, t_seri, sscoarse,sscoarse_pi, load_tmp2) 
+        CALL readaerosol_interp(id_ASSSM_phy ,itap, pdtphys,rjourvrai, &
+        debut, pplay, paprs, t_seri, ssacu, ssacu_pi, load_tmp3) 
+        loadss(:)=load_tmp1(:)+load_tmp2(:)+load_tmp3(:)
      ELSE
         sscoarse(:,:) = 0. ; sscoarse_pi(:,:) = 0. 
@@ -231,15 +231,25 @@
      ENDIF
      !
+     ! Read and interpolate cidustm
+     IF (flag_aerosol .EQ. 6) THEN 
+
+        CALL readaerosol_interp(id_ASNO3M_phy, itap, pdtphys, rjourvrai, & 
+        debut, pplay, paprs, t_seri, nitracc, nitracc_pi, load_tmp1) 
+        CALL readaerosol_interp(id_CSNO3M_phy, itap, pdtphys, rjourvrai, & 
+        debut, pplay, paprs, t_seri, nitrcoarse, nitrcoarse_pi, load_tmp2) 
+        CALL readaerosol_interp(id_CINO3M_phy, itap, pdtphys, rjourvrai, & 
+        debut, pplay, paprs, t_seri, nitrinscoarse, nitrinscoarse_pi, load_tmp3) 
+        loadss(:)=load_tmp1(:)+load_tmp2(:)+load_tmp3(:)
+
+     ELSE
+        nitracc(:,:)         =   0.0 ; nitracc_pi(:,:)      =   0.0 
+        nitrcoarse(:,:)      =   0.0 ; nitrcoarse_pi(:,:)   =   0.0
+        nitrinscoarse(:,:)   =   0.0 ; nitrinscoarse_pi(:,:)=   0.0
+        loadno3(:)=0.0
+     ENDIF
+     !
+     ! CSSO4M is set to 0 as not reliable
      sulfcoarse(:,:)      =   0.0 ! CSSO4M (=SO4) + CSMSAM (=MSA) 
      sulfcoarse_pi(:,:)   =   0.0 ! CSSO4M (=SO4) + CSMSAM (=MSA) pre-ind
-     !
-     !--placeholder for offline nitrate   
-     !
-     nitracc(:,:)         =   0.0 
-     nitracc_pi(:,:)      =   0.0 
-     nitrcoarse(:,:)      =   0.0
-     nitrcoarse_pi(:,:)   =   0.0
-     nitrinscoarse(:,:)   =   0.0
-     nitrinscoarse_pi(:,:)=   0.0
 
   ENDIF !--not aerosol_couple
Index: LMDZ5/branches/testing/libf/phylmd/rrtm/suphec.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/rrtm/suphec.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/rrtm/suphec.F90	(revision 2839)
@@ -129,36 +129,46 @@
 
 IF (LHOOK) CALL DR_HOOK('SUPHEC',0,ZHOOK_HANDLE)
-!CALL GSTATS(1811,0) ! MPL 28.11.08
-!RVTMP2=RCPV/RCPD-1.0_JPRB   !use cp,moist
-RVTMP2=0.0_JPRB              !neglect cp,moist
-RHOH2O=RATM/100._JPRB
-R2ES=611.21_JPRB*RD/RV
-R3LES=17.502_JPRB
-R3IES=22.587_JPRB
-R4LES=32.19_JPRB
-R4IES=-0.7_JPRB
-R5LES=R3LES*(RTT-R4LES)
-R5IES=R3IES*(RTT-R4IES)
-R5ALVCP=R5LES*RLVTT/RCPD
-R5ALSCP=R5IES*RLSTT/RCPD
-RALVDCP=RLVTT/RCPD
-RALSDCP=RLSTT/RCPD
-RALFDCP=RLMLT/RCPD
-RTWAT=RTT
-RTBER=RTT-5._JPRB
-RTBERCU=RTT-5.0_JPRB
-RTICE=RTT-23._JPRB
-RTICECU=RTT-23._JPRB
-
-RTWAT_RTICE_R=1.0_JPRB/(RTWAT-RTICE)
-RTWAT_RTICECU_R=1.0_JPRB/(RTWAT-RTICECU)
-IF(NPHYINT == 0) THEN
-  ISMAX=NSMAX
-ELSE
-  ISMAX=PHYS_GRID%NSMAX
-ENDIF
-
-RKOOP1=2.583_JPRB
-RKOOP2=0.48116E-2_JPRB
+!
+  IF (OK_BAD_ECMWF_THERMO) THEN
+!
+     ! Modify constants defined in suphel.F90 and set RVTMP2 to 0.
+     ! CALL GSTATS(1811,0) ! MPL 28.11.08
+     ! RVTMP2=RCPV/RCPD-1.0_JPRB   !use cp,moist
+     RVTMP2=0.0_JPRB              !neglect cp,moist
+     RHOH2O=RATM/100._JPRB
+     R2ES=611.21_JPRB*RD/RV
+     R3LES=17.502_JPRB
+     R3IES=22.587_JPRB
+     R4LES=32.19_JPRB
+     R4IES=-0.7_JPRB
+     R5LES=R3LES*(RTT-R4LES)
+     R5IES=R3IES*(RTT-R4IES)
+     R5ALVCP=R5LES*RLVTT/RCPD
+     R5ALSCP=R5IES*RLSTT/RCPD
+     RALVDCP=RLVTT/RCPD
+     RALSDCP=RLSTT/RCPD
+     RALFDCP=RLMLT/RCPD
+     RTWAT=RTT
+     RTBER=RTT-5._JPRB
+     RTBERCU=RTT-5.0_JPRB
+     RTICE=RTT-23._JPRB
+     RTICECU=RTT-23._JPRB
+     
+     RTWAT_RTICE_R=1.0_JPRB/(RTWAT-RTICE)
+     RTWAT_RTICECU_R=1.0_JPRB/(RTWAT-RTICECU)
+     IF(NPHYINT == 0) THEN
+       ISMAX=NSMAX
+     ELSE
+       ISMAX=PHYS_GRID%NSMAX
+     ENDIF
+     
+     RKOOP1=2.583_JPRB
+     RKOOP2=0.48116E-2_JPRB
+     
+  ELSE 
+     ! Keep constants defined in suphel.F90
+     RTICE=RTT-23._JPRB
+!
+  ENDIF  ! (OK_BAD_ECMWF_THERMO)
 
 !     ------------------------------------------------------------------
Index: LMDZ5/branches/testing/libf/phylmd/time_phylmdz_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/time_phylmdz_mod.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/time_phylmdz_mod.F90	(revision 2839)
@@ -1,4 +1,4 @@
 !
-! $Id: $
+! $Id$
 !
 MODULE time_phylmdz_mod
@@ -28,5 +28,5 @@
     INTEGER,SAVE :: itaufin_phy      ! final iteration (in itau_phy steps)
 !$OMP THREADPRIVATE(itaufin_phy)
-    REAL,SAVE    :: current_time ! current elapsed time (fraction of day) from the begining of the run
+    REAL,SAVE    :: current_time ! current elapsed time in seconds from the begining of the run
 !$OMP THREADPRIVATE(current_time)
     
@@ -84,7 +84,9 @@
   IMPLICIT NONE
   INCLUDE 'YOMCST.h'
-    REAL,INTENT(IN) :: pdtphys_
-    REAL            :: julian_date
-    
+  REAL,INTENT(IN) :: pdtphys_
+  REAL            :: julian_date
+  INTEGER         :: cur_day
+  REAL            :: cur_sec
+
     ! Check if the physics timestep has changed
     IF ( ABS( (pdtphys-pdtphys_) / ((pdtphys+pdtphys_)/2))> 10.*EPSILON(pdtphys_)) THEN
@@ -95,8 +97,12 @@
     
     ! Update elapsed time since begining of run:
-    current_time=current_time+pdtphys/rday
+    current_time = current_time + pdtphys
+    cur_day = int(current_time/rday)
+    cur_sec = current_time - (cur_day * rday) 
 
     ! Compute corresponding Julian date and update calendar
-    CALL ymds2ju(annee_ref,1,day_ini,(start_time+current_time)*rday,julian_date)
+    cur_day = cur_day + day_ini
+    cur_sec = cur_sec + (start_time * rday)
+    CALL ymds2ju(annee_ref,1, cur_day, cur_sec, julian_date)
     CALL phys_cal_update(julian_date)
     
Index: LMDZ5/branches/testing/libf/phylmd/tropopause_m.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/tropopause_m.F90	(revision 2839)
+++ LMDZ5/branches/testing/libf/phylmd/tropopause_m.F90	(revision 2839)
@@ -0,0 +1,104 @@
+MODULE tropopause_m
+
+!  USE phys_local_var_mod, ONLY: ptrop => pr_tropopause
+  PRIVATE
+  PUBLIC :: dyn_tropopause
+
+CONTAINS
+
+!-------------------------------------------------------------------------------
+!
+SUBROUTINE dyn_tropopause(t,ts,paprs,pplay,presnivs,rot,ptrop,tpot0,pvor0,pmin0,pmax0)
+!
+!-------------------------------------------------------------------------------
+  USE assert_m,      ONLY: assert
+  USE assert_eq_m,   ONLY: assert_eq
+  USE comvert_mod,   ONLY: preff
+  USE dimphy,        ONLY: klon, klev
+  USE geometry_mod,  ONLY: latitude_deg, longitude_deg
+  USE interpolation, ONLY: locate
+  IMPLICIT NONE
+!-------------------------------------------------------------------------------
+! Arguments:
+  REAL, INTENT(IN)  ::      t(:,:) !--- Cells-centers temperature
+  REAL, INTENT(IN)  ::     ts(:)   !--- Surface       temperature
+  REAL, INTENT(IN)  ::  paprs(:,:) !--- Cells-edges   pressure
+  REAL, INTENT(IN)  ::  pplay(:,:) !--- Cells-centers pressure
+  REAL, INTENT(IN)  :: presnivs(:) !--- Cells-centers nominal pressure
+  REAL, INTENT(IN)  ::    rot(:,:) !--- Cells-centers relative vorticity
+  REAL, INTENT(OUT) :: ptrop(klon) !--- Tropopause pressure
+  REAL, INTENT(IN), OPTIONAL :: tpot0, pvor0, pmin0, pmax0
+!-------------------------------------------------------------------------------
+! Local variables:
+  include "YOMCST.h"
+  CHARACTER(LEN=80)  :: sub
+  INTEGER :: it, i, nsrf, k, nh, kmin, kmax
+  REAL    :: p1, p2, tpo0, pvo0, pmn0, pmx0, al
+  REAL, DIMENSION(klon,klev)   :: t_edg, t_pot
+  REAL, DIMENSION(klon,klev-1) :: pvort
+!-------------------------------------------------------------------------------
+  sub='dyn_tropopause'
+  CALL assert(SIZE(t ,1)==klon, TRIM(sub)//" t klon")
+  CALL assert(SIZE(t ,2)==klev, TRIM(sub)//" t klev")
+  CALL assert(SIZE(ts,1)==klon, TRIM(sub)//" ts klon")
+  CALL assert(SIZE(presnivs,1)==klev, TRIM(sub)//" presnivs klev")
+  CALL assert(SHAPE(paprs)==[klon,klev+1],TRIM(sub)//" paprs shape")
+  CALL assert(SHAPE(pplay)==[klon,klev  ],TRIM(sub)//" pplay shape")
+  CALL assert(SHAPE(rot)  ==[klon,klev  ],TRIM(sub)//" rot shape")
+
+  !--- DEFAULT THRESHOLDS
+  tpo0=380.;   IF(PRESENT(tpot0)) tpo0=tpot0  !--- In kelvins
+  pvo0=2.0;    IF(PRESENT(pvor0)) pvo0=pvor0  !--- In PVU
+  pmn0= 8000.; IF(PRESENT(pmin0)) pmn0=pmin0  !--- In pascals
+  pmx0=50000.; IF(PRESENT(pmax0)) pmx0=pmax0  !--- In pascals
+  kmin=klev-locate(presnivs(klev:1:-1),pmx0)+1
+  kmax=klev-locate(presnivs(klev:1:-1),pmn0)+1
+
+  !--- POTENTIAL TEMPERATURE AT CELLS CENTERS
+  DO k= 1, klev
+    DO i = 1, klon
+      t_pot(i,k) = t(i,k)*(preff/pplay(i,k))**RKAPPA
+    END DO
+  END DO
+
+  !--- TEMPERATURE AT CELLS INTERFACES (except in top layer)
+  t_edg(:,1) = ts(:)
+  DO k= 2, klev
+    DO i = 1, klon
+      al = LOG(pplay(i,k-1)/paprs(i,k))/LOG(pplay(i,k-1)/pplay(i,k))
+      t_edg(i,k) = t(i,k) + al*(t(i,k-1)-t(i,k))
+    END DO
+  END DO
+
+  !--- ERTEL POTENTIAL VORTICITY AT CELLS CENTERS (except in top layer)
+  DO k= 1, klev-1
+    DO i = 1, klon
+      IF(paprs(i,k)==paprs(i,k+1)) THEN; pvort(i,k)=HUGE(1.); CYCLE; END IF
+      pvort(i,k) = -1.E6 * RG * 2.*ROMEGA*ABS(SIN(latitude_deg(i)*RPI/180.))   &
+                         * ( t_edg(i,k+1)*(preff/paprs(i,k+1) )**RKAPPA        &
+                           - t_edg(i,k  )*(preff/paprs(i,k  ) )**RKAPPA)       &
+                         / ( paprs(i,k+1)  -     paprs(i,k  ) )
+    END DO
+  END DO
+
+  !--- LOCATE TROPOPAUSE
+  ptrop(:)=0.
+  DO i = 1, klon
+    !--- Dynamical tropopause
+    it=kmax; DO WHILE(pvort(i,it)>pvo0.AND.it>=kmin); it=it-1; END DO
+    IF(pvort(i,it+1)/=pvort(i,it).AND.ALL([kmax,kmin-1]/=it) &
+      .AND.ALL([pvort(i,it),pvort(i,it+1)]/=HUGE(1.))) THEN
+      al = (pvort(i,it+1)-pvo0)/(pvort(i,it+1)-pvort(i,it))
+      ptrop(i) = MAX(ptrop(i),pplay(i,it)**al * pplay(i,it+1)**(1.-al))
+    END IF
+    !--- Potential temperature iso-surface
+    it = kmin-1+locate(t_pot(i,kmin:kmax),tpo0)
+    IF(t_pot(i,it+1)/=t_pot(i,it).AND.ALL([kmin-1,kmax]/=it)) THEN
+      al = (t_pot(i,it+1)-tpo0)/(t_pot(i,it+1)-t_pot(i,it))
+      ptrop(i) = MAX(ptrop(i),pplay(i,it)**al * pplay(i,it+1)**(1.-al))
+    END IF
+  END DO
+
+END SUBROUTINE dyn_tropopause
+
+END MODULE tropopause_m
Index: LMDZ5/branches/testing/libf/phylmd/vertical_layers_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/vertical_layers_mod.F90	(revision 2787)
+++ 	(revision )
@@ -1,46 +1,0 @@
-! $Id: $
-
-MODULE vertical_layers_mod
-
-   REAL,SAVE             :: preff  ! reference surface pressure (Pa)
-   REAL,SAVE             :: scaleheight ! atmospheric reference scale height (km)
-   REAL,SAVE,ALLOCATABLE :: ap(:) ! hybrid (pressure contribution) coordinate 
-                                  ! at layer interfaces (Pa)
-   REAL,SAVE,ALLOCATABLE :: bp(:) ! hybrid (sigma contribution) coordinate 
-                                  ! at layer interfaces (Pa)
-   REAL,SAVE,ALLOCATABLE :: presnivs(:) ! reference pressure at mid-layer (Pa),
-                                        ! based on preff, ap and bp
-   REAL,SAVE,ALLOCATABLE :: pseudoalt(:) ! pseudo-altitude of model layers (km),
-                                         ! based on preff and scaleheight
-   
-!$OMP THREADPRIVATE(preff,scaleheight,ap,bp,presnivs,pseudoalt)
-
-
-CONTAINS
-
-  SUBROUTINE init_vertical_layers(nlayer,preff_,scaleheight_,ap_,bp_,&
-                                 presnivs_, pseudoalt_)
-    IMPLICIT NONE
-    INTEGER,INTENT(IN) :: nlayer ! number of atmospheric layers
-    REAL,INTENT(IN)    :: preff_ ! reference surface pressure (Pa)
-    REAL,INTENT(IN)    :: scaleheight_ ! atmospheric scale height (km)
-    REAL,INTENT(IN)    :: ap_(nlayer+1) ! hybrid coordinate at interfaces
-    REAL,INTENT(IN)    :: bp_(nlayer+1) ! hybrid coordinate at interfaces
-    REAL,INTENT(IN)    :: presnivs_(nlayer) ! Appproximative pressure of atm. layers (Pa)
-    REAL,INTENT(IN)    :: pseudoalt_(nlayer) ! pseudo-altitude of atm. layers (km)
-  
-    ALLOCATE(ap(nlayer+1))
-    ALLOCATE(bp(nlayer+1))
-    ALLOCATE(presnivs(nlayer))
-    ALLOCATE(pseudoalt(nlayer))
-  
-    preff = preff_
-    scaleheight=scaleheight_
-    ap(:) = ap_(:)
-    bp(:) = bp_(:)
-    presnivs(:) = presnivs_(:)
-    pseudoalt(:) = pseudoalt_(:)
-
-  END SUBROUTINE init_vertical_layers
-
-END MODULE vertical_layers_mod
Index: LMDZ5/branches/testing/libf/phylmd/yamada4.F90
===================================================================
--- LMDZ5/branches/testing/libf/phylmd/yamada4.F90	(revision 2787)
+++ LMDZ5/branches/testing/libf/phylmd/yamada4.F90	(revision 2839)
@@ -57,5 +57,5 @@
   !                          -> the model can run with longer time-steps.
   !             2016/11/30 (EV etienne.vignon@univ-grenoble-alpes.fr)
-  !               On met tke (=q2/2) en entrée plutôt que q2
+  !               On met tke (=q2/2) en entr??e plut??t que q2
   !               On corrige l'update de la tke
   !
@@ -120,5 +120,7 @@
   DATA first, ipas/.FALSE., 0/
   !$OMP THREADPRIVATE( first,ipas)
-  LOGICAL hboville
+  LOGICAL,SAVE :: hboville=.TRUE.
+  REAL,SAVE :: viscom,viscoh
+  !$OMP THREADPRIVATE( hboville,viscom,viscoh)
   INTEGER ig, k
   REAL ri, zrif, zalpha, zsm, zsn
@@ -130,4 +132,5 @@
   REAL zz(klon, klev+1)
   INTEGER iter
+  REAL dissip(klon,klev), tkeprov,tkeexp, shear(klon,klev), buoy(klon,klev)
   REAL,SAVE :: ric0,ric,rifc, b1, kap
   !$OMP THREADPRIVATE(ric0,ric,rifc,b1,kap)
@@ -138,6 +141,7 @@
   !$OMP THREADPRIVATE(lmixmin)
   LOGICAL, SAVE :: new_yamada4
-  !$OMP THREADPRIVATE(new_yamada4)
-  REAL, SAVE :: yun,ydeux
+  INTEGER, SAVE :: yamada4_num
+  !$OMP THREADPRIVATE(new_yamada4,yamada4_num)
+  REAL, SAVE :: yun,ydeux,disseff
   !$OMP THREADPRIVATE(yun,ydeux)
   REAL frif, falpha, fsm
@@ -161,7 +165,7 @@
     new_yamada4=.false.
     CALL getin_p('new_yamada4',new_yamada4)
-! Pour garantir la continuite dans la mise au point de CMIP6.
-! Eliminer l'option new_yamada4 des le printemps 2016
+
     IF (new_yamada4) THEN
+! Corrections et reglages issus du travail de these d'Etienne Vignon.
        ric=0.143 ! qui donne des valeurs proches des seuils proposes
                  ! dans YAMADA 1983 : sm=0.0845 (0.085 dans Y83)
@@ -169,5 +173,5 @@
        CALL getin_p('yamada4_ric',ric)
        ric0=0.19489      ! ric=0.195 originalement, mais produisait sm<0
-       ric=min(ric,ric0) ! Au delà de ric0, sm devient négatif
+       ric=min(ric,ric0) ! Au dela de ric0, sm devient n??gatif
        rifc=frif(ric)
        seuilsm=fsm(frif(ric))
@@ -175,8 +179,10 @@
        yun=1.
        ydeux=2.
-!      yun=2.
-!      ydeux=1.
+       hboville=.FALSE.
+       viscom=1.46E-5
+       viscoh=2.06E-5
+       lmixmin=0.
+       yamada4_num=5
     ELSE
-  !!  DATA ric, rifc, b1, kap/0.195, 0.191, 16.6, 0.4/
        ric=0.195
        rifc=0.191
@@ -185,9 +191,16 @@
        yun=2.
        ydeux=1.
+       hboville=.TRUE.
+       viscom=0.
+       viscoh=0.
+       lmixmin=1.
+       yamada4_num=0
     ENDIF
+
     PRINT*,'YAMADA4 RIc, RIfc, Sm_min, Alpha_min',ric,rifc,seuilsm,seuilalpha
     firstcall = .FALSE.
-    lmixmin=1.
     CALL getin_p('lmixmin',lmixmin)
+    CALL getin_p('yamada4_hboville',hboville)
+    CALL getin_p('yamada4_num',yamada4_num)
   END IF
 
@@ -199,5 +212,4 @@
 
 ! On utilise ou non la routine de Holstalg Boville pour les cas tres stables
-   hboville=.TRUE.
 
 
@@ -290,5 +302,5 @@
   !=======================================================================
 
-  ! On commence par calculé q2 à partir de la tke
+  ! On commence par calculer q2 a partir de la tke
 
   IF (new_yamada4) THEN
@@ -400,4 +412,103 @@
   ELSE IF (iflag_pbl>=10) THEN
 
+    IF (yamada4_num>=1) THEN
+ 
+    DO k = 2, klev - 1
+      DO ig=1,ngrid
+      q2(ig, k) = min(max(q2(ig,k),1.E-10), 1.E4)
+      km(ig, k) = l(ig, k)*sqrt(q2(ig,k))*sm(ig, k)
+      shear(ig,k)=km(ig, k)*m2(ig, k)
+      buoy(ig,k)=km(ig, k)*m2(ig, k)*(-1.*rif(ig,k))
+      dissip(ig,k)=((sqrt(q2(ig,k)))**3)/(b1*l(ig,k))
+     ENDDO
+    ENDDO
+
+    IF (yamada4_num==1) THEN ! Schema du MAR tel quel
+       DO k = 2, klev - 1
+         DO ig=1,ngrid
+         tkeprov=q2(ig,k)/ydeux
+         tkeprov= tkeprov*                           &
+           &  (tkeprov+dt*(shear(ig,k)+max(0.,buoy(ig,k))))/ &
+           &  (tkeprov+dt*((-1.)*min(0.,buoy(ig,k))+dissip(ig,k)))
+         q2(ig,k)=tkeprov*ydeux
+        ENDDO
+       ENDDO
+    ELSE IF (yamada4_num==2) THEN ! version modifiee avec integration exacte pour la dissipation
+       DO k = 2, klev - 1
+         DO ig=1,ngrid
+         tkeprov=q2(ig,k)/ydeux
+         disseff=dissip(ig,k)-min(0.,buoy(ig,k))
+         tkeprov = tkeprov/(1.+dt*disseff/(2.*tkeprov))**2
+         tkeprov= tkeprov+dt*(shear(ig,k)+max(0.,buoy(ig,k)))
+         q2(ig,k)=tkeprov*ydeux
+         ! En cas stable, on traite la flotabilite comme la
+         ! dissipation, en supposant que buoy/q2^3 est constant.
+         ! Puis on prend la solution exacte
+        ENDDO
+       ENDDO
+    ELSE IF (yamada4_num==3) THEN ! version modifiee avec integration exacte pour la dissipation
+       DO k = 2, klev - 1
+         DO ig=1,ngrid
+         tkeprov=q2(ig,k)/ydeux
+         disseff=dissip(ig,k)-min(0.,buoy(ig,k))
+         tkeprov=tkeprov*exp(-dt*disseff/tkeprov)
+         tkeprov= tkeprov+dt*(shear(ig,k)+max(0.,buoy(ig,k)))
+         q2(ig,k)=tkeprov*ydeux
+         ! En cas stable, on traite la flotabilite comme la
+         ! dissipation, en supposant que buoy/q2^3 est constant.
+         ! Puis on prend la solution exacte
+        ENDDO
+       ENDDO
+    ELSE IF (yamada4_num==4) THEN ! version modifiee avec integration exacte pour la dissipation
+       DO k = 2, klev - 1
+         DO ig=1,ngrid
+         tkeprov=q2(ig,k)/ydeux
+         tkeprov= tkeprov+dt*(shear(ig,k)+max(0.,buoy(ig,k)))
+         tkeprov= tkeprov*                           &
+           &  tkeprov/ &
+           &  (tkeprov+dt*((-1.)*min(0.,buoy(ig,k))+dissip(ig,k)))
+         q2(ig,k)=tkeprov*ydeux
+         ! En cas stable, on traite la flotabilite comme la
+         ! dissipation, en supposant que buoy/q2^3 est constant.
+         ! Puis on prend la solution exacte
+        ENDDO
+       ENDDO
+    ELSE IF (yamada4_num==5) THEN ! version modifiee avec integration exacte pour la dissipation
+       DO k = 2, klev - 1
+         DO ig=1,ngrid
+         tkeprov=q2(ig,k)/ydeux
+         disseff=dissip(ig,k)-min(0.,buoy(ig,k))
+         tkeexp=exp(-dt*disseff/tkeprov)
+         tkeprov= shear(ig,k)*tkeprov/disseff*(1.-tkeexp)+tkeprov*tkeexp
+         q2(ig,k)=tkeprov*ydeux
+         ! En cas stable, on traite la flotabilite comme la
+         ! dissipation, en supposant que buoy/q2^3 est constant.
+         ! Puis on prend la solution exacte
+        ENDDO
+       ENDDO
+    ELSE IF (yamada4_num==6) THEN ! version modifiee avec integration exacte pour la dissipation
+       DO k = 2, klev - 1
+         DO ig=1,ngrid
+         tkeprov=q2(ig,k)/ydeux
+         tkeprov=tkeprov+max(buoy(ig,k)+shear(ig,k),0.)*dt
+         disseff=dissip(ig,k)-min(0.,buoy(ig,k)+shear(ig,k))
+         tkeexp=exp(-dt*disseff/tkeprov)
+         tkeprov= tkeprov*tkeexp
+         q2(ig,k)=tkeprov*ydeux
+         ! En cas stable, on traite la flotabilite comme la
+         ! dissipation, en supposant que buoy/q2^3 est constant.
+         ! Puis on prend la solution exacte
+        ENDDO
+       ENDDO
+    ENDIF
+
+    DO k = 2, klev - 1
+      DO ig=1,ngrid
+      q2(ig, k) = min(max(q2(ig,k),1.E-10), 1.E4)
+      ENDDO
+    ENDDO
+
+   ELSE 
+
     DO k = 2, klev - 1
       km(1:ngrid, k) = l(1:ngrid, k)*sqrt(q2(1:ngrid,k))*sm(1:ngrid, k)
@@ -410,4 +521,5 @@
     END DO
 
+  ENDIF
 
   ELSE
@@ -529,4 +641,9 @@
  END IF ! hboville
 
+! Ajout d'une viscosite moleculaire
+   km(:,:)=km(:,:)+viscom
+   kn(:,:)=kn(:,:)+viscoh
+   kq(:,:)=kq(:,:)+viscoh
+
   IF (prt_level>1) THEN
     PRINT *, 'YAMADA4 1'
@@ -575,5 +692,5 @@
 
 !============================================================================
-! Mise à jour de la tke
+! Mise a jour de la tke
 !============================================================================
 
Index: LMDZ5/branches/testing/libf/phymar/vertical_layers_mod.F90
===================================================================
--- LMDZ5/branches/testing/libf/phymar/vertical_layers_mod.F90	(revision 2787)
+++ 	(revision )
@@ -1,46 +1,0 @@
-! $Id: $
-
-MODULE vertical_layers_mod
-
-   REAL,SAVE             :: preff  ! reference surface pressure (Pa)
-   REAL,SAVE             :: scaleheight ! atmospheric reference scale height (km)
-   REAL,SAVE,ALLOCATABLE :: ap(:) ! hybrid (pressure contribution) coordinate 
-                                  ! at layer interfaces (Pa)
-   REAL,SAVE,ALLOCATABLE :: bp(:) ! hybrid (sigma contribution) coordinate 
-                                  ! at layer interfaces (Pa)
-   REAL,SAVE,ALLOCATABLE :: presnivs(:) ! reference pressure at mid-layer (Pa),
-                                        ! based on preff, ap and bp
-   REAL,SAVE,ALLOCATABLE :: pseudoalt(:) ! pseudo-altitude of model layers (km),
-                                         ! based on preff and scaleheight
-   
-!$OMP THREADPRIVATE(preff,scaleheight,ap,bp,presnivs,pseudoalt)
-
-
-CONTAINS
-
-  SUBROUTINE init_vertical_layers(nlayer,preff_,scaleheight_,ap_,bp_,&
-                                 presnivs_, pseudoalt_)
-    IMPLICIT NONE
-    INTEGER,INTENT(IN) :: nlayer ! number of atmospheric layers
-    REAL,INTENT(IN)    :: preff_ ! reference surface pressure (Pa)
-    REAL,INTENT(IN)    :: scaleheight_ ! atmospheric scale height (km)
-    REAL,INTENT(IN)    :: ap_(nlayer+1) ! hybrid coordinate at interfaces
-    REAL,INTENT(IN)    :: bp_(nlayer+1) ! hybrid coordinate at interfaces
-    REAL,INTENT(IN)    :: presnivs_(nlayer) ! Appproximative pressure of atm. layers (Pa)
-    REAL,INTENT(IN)    :: pseudoalt_(nlayer) ! pseudo-altitude of atm. layers (km)
-  
-    ALLOCATE(ap(nlayer+1))
-    ALLOCATE(bp(nlayer+1))
-    ALLOCATE(presnivs(nlayer))
-    ALLOCATE(pseudoalt(nlayer))
-  
-    preff = preff_
-    scaleheight=scaleheight_
-    ap(:) = ap_(:)
-    bp(:) = bp_(:)
-    presnivs(:) = presnivs_(:)
-    pseudoalt(:) = pseudoalt_(:)
-
-  END SUBROUTINE init_vertical_layers
-
-END MODULE vertical_layers_mod
