Index: LMDZ4/branches/V3_test/libf/phylmd/YOMCST.inc
===================================================================
--- LMDZ4/branches/V3_test/libf/phylmd/YOMCST.inc	(revision 711)
+++ LMDZ4/branches/V3_test/libf/phylmd/YOMCST.inc	(revision 711)
@@ -0,0 +1,39 @@
+!
+! $Header$
+!
+! A1.0 Fundamental constants
+      REAL RPI,RCLUM,RHPLA,RKBOL,RNAVO
+! A1.1 Astronomical constants
+      REAL RDAY,REA,REPSM,RSIYEA,RSIDAY,ROMEGA
+! A1.1.bis Constantes concernant l'orbite de la Terre:
+      REAL R_ecc, R_peri, R_incl
+! A1.2 Geoide
+      REAL RA,RG,R1SA
+! A1.3 Radiation
+!     REAL RSIGMA,RI0
+      REAL RSIGMA
+! A1.4 Thermodynamic gas phase
+      REAL R,RMD,RMO3,RMV,RD,RV,RCPD,RCPV,RCVD,RCVV
+      REAL RKAPPA,RETV
+! A1.5,6 Thermodynamic liquid,solid phases
+      REAL RCW,RCS
+! A1.7 Thermodynamic transition of phase
+      REAL RLVTT,RLSTT,RLMLT,RTT,RATM
+! A1.8 Curve of saturation
+      REAL RESTT,RALPW,RBETW,RGAMW,RALPS,RBETS,RGAMS
+      REAL RALPD,RBETD,RGAMD
+!
+!    S      ,RSIGMA,RI0
+      COMMON/YOMCST/RPI   ,RCLUM ,RHPLA ,RKBOL ,RNAVO  &
+     &      ,RDAY  ,REA   ,REPSM ,RSIYEA,RSIDAY,ROMEGA  &
+     &      ,R_ecc, R_peri, R_incl  &
+     &      ,RA    ,RG    ,R1SA  &
+     &      ,RSIGMA  &
+     &      ,R     ,RMD   ,RMO3  ,RMV   ,RD    ,RV    ,RCPD  &
+     &      ,RCPV  ,RCVD  ,RCVV  ,RKAPPA,RETV  &
+     &      ,RCW   ,RCS  &
+     &      ,RLVTT ,RLSTT ,RLMLT ,RTT   ,RATM  &
+     &      ,RESTT ,RALPW ,RBETW ,RGAMW ,RALPS ,RBETS ,RGAMS  &
+     &      ,RALPD ,RBETD ,RGAMD
+!    ------------------------------------------------------------------
+!$OMP THREADPRIVATE(/YOMCST/)
Index: LMDZ4/branches/V3_test/libf/phylmd/clesphys.inc
===================================================================
--- LMDZ4/branches/V3_test/libf/phylmd/clesphys.inc	(revision 711)
+++ LMDZ4/branches/V3_test/libf/phylmd/clesphys.inc	(revision 711)
@@ -0,0 +1,54 @@
+!
+! $Header$
+!
+!..include cles_phys.h
+!
+       LOGICAL cycle_diurne,soil_model,new_oliq,ok_orodr,ok_orolf 
+       LOGICAL ok_limitvrai
+       INTEGER nbapp_rad, iflag_con
+       REAL co2_ppm, solaire
+       REAL*8 RCO2, RCH4, RN2O, RCFC11, RCFC12  
+       REAL*8 CH4_ppb, N2O_ppb, CFC11_ppt, CFC12_ppt
+
+!OM ---> correction du bilan d'eau global
+!OM Correction sur precip KE
+       REAL cvl_corr
+!OM Fonte calotte dans bilan eau
+       LOGICAL ok_lic_melt
+
+!IM simulateur ISCCP 
+       INTEGER top_height, overlap
+!IM seuils cdrm, cdrh
+       REAL cdmmax, cdhmax
+!IM param. stabilite s/ terres et en dehors
+       REAL ksta, ksta_ter
+!IM ok_kzmin : clef calcul Kzmin dans la CL de surface cf FH
+       LOGICAL ok_kzmin
+!IM lev_histhf  : niveau sorties 6h
+!IM lev_histday : niveau sorties journalieres
+!IM lev_histmth : niveau sorties mensuelles
+       INTEGER lev_histhf, lev_histday, lev_histmth
+       CHARACTER*4 type_run
+       LOGICAL ok_isccp, ok_regdyn
+       REAL lonmin_ins, lonmax_ins, latmin_ins, latmax_ins
+       REAL ecrit_ins, ecrit_hf, ecrit_hf2mth, ecrit_day
+       REAL ecrit_mth, ecrit_tra, ecrit_reg 
+       REAL freqin_isccp, freqout_isccp
+       INTEGER :: ip_ebil_phy
+       LOGICAL ok_slab_sicOBS
+
+       COMMON/clesphys/cycle_diurne, soil_model, new_oliq,  &
+     &     ok_orodr, ok_orolf, ok_limitvrai, nbapp_rad, iflag_con  &
+     &     , co2_ppm, solaire, RCO2, RCH4, RN2O, RCFC11, RCFC12  &
+     &     , CH4_ppb, N2O_ppb, CFC11_ppt, CFC12_ppt  &
+     &     , top_height, overlap, cdmmax, cdhmax, ksta, ksta_ter  &
+     &     , ok_kzmin, lev_histhf, lev_histday, lev_histmth  &
+     &     , type_run, ok_isccp, ok_regdyn  &
+     &     , lonmin_ins, lonmax_ins, latmin_ins, latmax_ins  &
+     &     , ecrit_ins, ecrit_hf, ecrit_hf2mth, ecrit_day  &
+     &     , ecrit_mth, ecrit_tra, ecrit_reg  &
+     &     , freqin_isccp, freqout_isccp, ip_ebil_phy  &
+     &     , ok_slab_sicOBS, ok_lic_melt, cvl_corr
+     
+!$OMP THREADPRIVATE(/clesphys/)
+ 
Index: LMDZ4/branches/V3_test/libf/phylmd/mod_phys_mpi.F90
===================================================================
--- LMDZ4/branches/V3_test/libf/phylmd/mod_phys_mpi.F90	(revision 711)
+++ LMDZ4/branches/V3_test/libf/phylmd/mod_phys_mpi.F90	(revision 711)
@@ -0,0 +1,323 @@
+module mod_phys_mpi
+  
+  logical, save :: monocpu
+!  logical, save :: parallel
+   
+  INTEGER,SAVE :: iiphy_begin
+  INTEGER,SAVE :: iiphy_end
+  INTEGER,SAVE :: jjphy_begin
+  INTEGER,SAVE :: jjphy_end
+  INTEGER,SAVE :: jjphy_nb
+  INTEGER,SAVE :: ijphy_begin
+  INTEGER,SAVE :: ijphy_end
+  INTEGER,SAVE :: ijphy_nb
+  INTEGER,SAVE :: klon_begin
+  INTEGER,SAVE :: klon_end
+  INTEGER,SAVE :: klon_mpi
+  
+  INTEGER,SAVE,allocatable,dimension(:) :: jjphy_para_nb
+  INTEGER,SAVE,allocatable,dimension(:) :: jjphy_para_begin
+  INTEGER,SAVE,allocatable,dimension(:) :: jjphy_para_end
+  INTEGER,SAVE,dimension(:),allocatable :: Liste_i
+  INTEGER,SAVE,dimension(:),allocatable :: Liste_j
+  INTEGER,SAVE,dimension(:),allocatable :: klon_para_nb
+  INTEGER,SAVE,dimension(:),allocatable :: klon_para_begin
+  INTEGER,SAVE,dimension(:),allocatable :: klon_para_end 
+
+  
+  INTEGER,save :: phy_rank
+  INTEGER,save :: phy_size
+  
+
+  INTEGER,save :: klev, klevp1,klevm1,klon,kfdia,kidia
+  INTEGER,save :: klon2
+  INTEGER,save :: nbtr 
+  INTEGER,save :: kdlon, kflev
+!$OMP THREADPRIVATE(klon,kfdia,kidia,kdlon)
+
+ 
+contains
+  
+   subroutine InitDimphy
+
+#ifdef CPP_PARA
+   use parallel
+#endif
+
+   implicit none
+#include "dimensions90.h"
+#include "paramet90.h" 
+    integer :: rank
+    integer :: i,j,Pos,Index
+    logical,save :: First=.true.
+#ifndef CPP_PARA
+   logical, save :: pole_nord = .true.
+   logical, save :: pole_sud = .true.
+#endif
+
+#ifdef CPP_PARA      
+      monocpu=.false.
+#else
+      monocpu = .true.
+#endif
+      
+      if (monocpu) then
+        
+	phy_rank=0
+	phy_size=1
+	
+#ifdef CPP_PARA      
+      else
+ 
+        phy_rank=mpi_rank
+	phy_size=mpi_size
+#endif
+      
+      endif
+
+      if (First) then
+        allocate(jjphy_para_nb(0:phy_size-1))
+        allocate(jjphy_para_begin(0:phy_size-1))
+        allocate(jjphy_para_end(0:phy_size-1))
+        allocate(klon_para_nb(0:phy_size-1))
+        allocate(klon_para_begin(0:phy_size-1))
+        allocate(klon_para_end(0:phy_size-1))
+      endif
+	
+      klev=llm
+      klevp1=klev+1
+      klevm1=klev-1
+      klon2=iim*(jjm-1)+2
+      
+     
+!        do i=0,phy_size-1
+!          klon_para_nb(i)=(klon2/phy_size)
+!          if (i<MOD(klon2,phy_size)) klon_para_nb(i)=klon_para_nb(i)+1
+!          if (i==0) then 
+!            klon_para_begin(i)=1
+!          else 
+!            klon_para_begin(i)=klon_para_end(i-1)+1
+!          endif
+!          klon_para_end(i)=klon_para_begin(i)+klon_para_nb(i)-1
+!        enddo
+      
+      if (First) then
+        do i=0,phy_size-1
+          klon_para_nb(i)=(klon2/phy_size)
+          if (i<MOD(klon2,phy_size)) klon_para_nb(i)=klon_para_nb(i)+1
+        enddo
+      endif
+        
+      do i=0,phy_size-1
+        if (i==0) then 
+          klon_para_begin(i)=1
+        else 
+          klon_para_begin(i)=klon_para_end(i-1)+1
+        endif
+        klon_para_end(i)=klon_para_begin(i)+klon_para_nb(i)-1
+      enddo
+	
+      klon=klon_para_nb(phy_rank)
+      klon_mpi=klon_para_nb(phy_rank)
+      klon_begin=klon_para_begin(phy_rank)
+      klon_end=klon_para_end(phy_rank)
+	
+      nbtr=nqmx-2+1/(nqmx-1)
+
+      kflev=klev
+    
+      if (.not.first) then
+        deallocate(liste_i,liste_j)
+      endif
+      
+      
+      allocate(Liste_i(klon))
+      allocate(Liste_j(klon))
+    
+      Index=1
+      if (Pole_Nord) then
+        Liste_i(1)=1
+        Liste_j(1)=1
+        iiphy_begin=1
+        jjphy_begin=1
+	ijphy_begin=1
+        Index=Index+1
+      endif
+    
+      Pos=2
+      do j=2,jjm
+        do i=1,iim
+      
+	  if (Pos==klon_begin) then
+            iiphy_begin=i
+            jjphy_begin=j
+	    ijphy_begin=j*iip1+i
+          endif
+       
+          if (Pos==klon_end) then
+            iiphy_end=i
+            jjphy_end=j
+	    ijphy_end=j*iip1+i
+          endif
+        
+          if (Pos>=klon_begin .AND. Pos<=klon_end) then
+            Liste_i(Index)=i
+            Liste_j(Index)=j
+            Index=Index+1
+          endif
+          Pos=Pos+1
+        enddo
+      enddo
+    
+      if (pole_sud) then
+        Liste_i(Index)=1
+        Liste_j(Index)=jjp1
+        iiphy_end=1
+        jjphy_end=jjp1
+	ijphy_end=jjp1*iip1+1
+      endif
+    
+      ijphy_nb=ijphy_end-ijphy_begin+1
+      jjphy_nb=jjphy_end-jjphy_begin+1
+	
+	    
+      Pos=2
+      rank=0
+      jjphy_para_begin(rank)=1
+    
+      do j=2,jjm
+        do i=1,iim
+          if (Pos==klon_para_begin(rank)) then
+            jjphy_para_begin(rank)=j
+          endif
+          if (Pos==klon_para_end(rank)) then
+            jjphy_para_end(rank)=j
+            rank=rank+1
+          endif
+          Pos=Pos+1
+        enddo
+      enddo
+      jjphy_para_end(rank)=jjp1
+      
+      First=.false.    
+   end subroutine InitDimphy
+   
+
+   subroutine GatherField(Fields,Fieldr,ll)
+#ifdef CPP_PARA
+      USE parallel, ONLY : COMM_LMDZ
+#endif
+     implicit none
+#ifdef CPP_PARA      
+     include 'mpif.h'
+#endif
+     INTEGER :: ll
+     REAL, dimension(klon_mpi,ll) :: Fields
+     REAL, dimension(klon2,ll) :: Fieldr     
+     REAL, dimension(klon2*ll) :: Field_tmp     
+     INTEGER, dimension(0:phy_size-1) :: displs
+     INTEGER, dimension(0:phy_size-1) :: sendcounts
+     INTEGER :: l,Pos,rank,ierr
+     INTEGER :: klon_b,klon_e, Nb
+     
+     Pos=1     
+     do rank=0,phy_size-1
+       klon_b=klon_para_begin(rank)
+       klon_e=klon_para_end(rank)
+       Nb=klon_para_nb(rank)
+       displs(rank)=Pos-1
+       sendcounts(rank)=Nb*ll
+       Pos=Pos+Nb*ll
+     enddo
+         
+      if (monocpu) then
+        Fieldr(:,:)=Fields(:,:)
+#ifdef CPP_PARA      
+      else
+        call MPI_Gatherv(Fields,klon_mpi*ll,MPI_REAL8,Field_tmp,sendcounts,  &
+	                 displs,MPI_REAL8,0,COMM_LMDZ,ierr)
+#endif
+      endif
+      
+     Pos=1     
+     do rank=0,phy_size-1
+       klon_b=klon_para_begin(rank)
+       klon_e=klon_para_end(rank)
+       Nb=klon_para_nb(rank)
+       do l=1,ll
+         Fieldr(klon_b:klon_e,l)=Field_tmp(Pos:Pos+Nb-1)
+	 Pos=Pos+Nb
+       enddo
+     enddo
+      
+   end subroutine GatherField
+
+   subroutine AllGatherField(Fields,Fieldr,ll)
+#ifdef CPP_PARA
+      USE parallel, ONLY : COMM_LMDZ
+#endif
+     implicit none
+#ifdef CPP_PARA      
+     include 'mpif.h'
+#endif   
+     INTEGER :: ll
+     REAL, dimension(klon_mpi,ll) :: Fields
+     REAL, dimension(klon2,ll) :: Fieldr     
+     
+     INTEGER :: ierr
+      
+      IF (monocpu) THEN
+        Fieldr(:,:)=Fields(:,:)
+      ELSE 
+       call GatherField(Fields,Fieldr,ll)
+#ifdef CPP_PARA             
+       call MPI_BCAST(Fieldr,klon2*ll,MPI_REAL8,0,COMM_LMDZ,ierr)
+#endif 
+      ENDIF  
+   end subroutine AllGatherField
+   
+           
+   subroutine ScatterField(Fields,Fieldr,ll)
+#ifdef CPP_PARA
+      USE parallel, ONLY : COMM_LMDZ
+#endif
+     implicit none
+#ifdef CPP_PARA      
+     include 'mpif.h'
+#endif
+     INTEGER :: ll
+     REAL, dimension(klon2,ll) :: Fields
+     REAL, dimension(klon_mpi,ll) :: Fieldr     
+     REAL, dimension(klon2*ll) :: Field_tmp     
+     INTEGER, dimension(0:phy_size-1) :: displs
+     INTEGER, dimension(0:phy_size-1) :: sendcounts
+     INTEGER :: l,Pos,rank,ierr
+     INTEGER :: klon_b,klon_e, Nb
+
+     Pos=1    
+     do rank=0,phy_size-1
+       klon_b=klon_para_begin(rank)
+       klon_e=klon_para_end(rank)
+       Nb=klon_para_nb(rank)
+       displs(rank)=Pos-1
+       sendcounts(rank)=Nb*ll
+       do l=1,ll
+         Field_tmp(Pos:Pos+Nb-1)=Fields(klon_b:klon_e,l)
+	 Pos=Pos+Nb
+       enddo
+     enddo
+           
+     if (monocpu) then
+       Fieldr(:,:)=Fields(:,:)
+     else
+#ifdef CPP_PARA      
+       call MPI_Scatterv(Field_tmp,sendcounts,displs,MPI_REAL8,         &
+	                 Fieldr,klon_mpi*ll,MPI_REAL8,0,COMM_LMDZ,ierr)
+#endif
+     endif
+      
+        
+   end subroutine ScatterField
+   
+   
+end module mod_phys_mpi
Index: LMDZ4/branches/V3_test/libf/phylmd/mod_phys_openmp.F90
===================================================================
--- LMDZ4/branches/V3_test/libf/phylmd/mod_phys_openmp.F90	(revision 711)
+++ LMDZ4/branches/V3_test/libf/phylmd/mod_phys_openmp.F90	(revision 711)
@@ -0,0 +1,126 @@
+module mod_phys_openmp
+
+  integer,save :: omp_size
+  integer,save :: omp_rank
+  
+  INTEGER,SAVE,dimension(:),allocatable :: klon_omp_nb
+  INTEGER,SAVE,dimension(:),allocatable :: klon_omp_begin
+  INTEGER,SAVE,dimension(:),allocatable :: klon_omp_end    
+  INTEGER,SAVE :: klon_omp
+!$OMP  THREADPRIVATE(omp_rank,klon_omp)
+
+  REAL,save,allocatable,dimension(:) :: zmasq
+!$OMP THREADPRIVATE(zmasq)   
+
+contains
+  
+  subroutine init_phys_openmp
+  USE mod_phys_mpi, only : klon_mpi,kfdia,kidia,kdlon
+    implicit none
+    integer :: i
+#ifdef _OPENMP    
+    integer :: OMP_GET_NUM_THREADS
+    external OMP_GET_NUM_THREADS
+    integer :: OMP_GET_THREAD_NUM
+    external OMP_GET_THREAD_NUM
+#endif  
+
+#ifdef _OPENMP
+!$OMP MASTER
+        omp_size=OMP_GET_NUM_THREADS()
+!$OMP END MASTER
+        omp_rank=OMP_GET_THREAD_NUM()    
+#else    
+    omp_size=1
+    omp_rank=0
+#endif
+!$OMP MASTER 
+     print *,'MASTER :omp_rank',omp_rank
+    allocate(klon_omp_nb(0:omp_size-1))
+    allocate(klon_omp_begin(0:omp_size-1))
+    allocate(klon_omp_end(0:omp_size-1))
+    
+    do i=0,omp_size-1
+      klon_omp_nb(i)=klon_mpi/omp_size
+      if (i<MOD(klon_mpi,omp_size)) klon_omp_nb(i)=klon_omp_nb(i)+1
+    enddo
+    
+    klon_omp_begin(0)=1
+    klon_omp_end(0)=klon_omp_nb(0)
+    
+    do i=1,omp_size-1
+      klon_omp_begin(i)=klon_omp_end(i-1)+1
+      klon_omp_end(i)=klon_omp_begin(i)+klon_omp_nb(i)-1
+    enddo
+!$OMP END MASTER
+!$OMP BARRIER
+   
+    klon_omp=klon_omp_nb(omp_rank) 
+    allocate(zmasq(klon_omp))  
+ 
+    kidia=1
+    kfdia=klon_omp
+    kdlon=klon_omp
+    print *,omp_rank,' : klon_omp_nb',klon_omp_nb
+  end subroutine init_phys_openmp
+  
+
+  subroutine ScatterField_omp(Fields,Fieldr,ll)
+  USE mod_phys_mpi, only : klon_mpi
+  implicit none
+    INTEGER :: ll
+    REAL, dimension(klon_mpi,ll) :: Fields
+    REAL, dimension(klon_omp,ll) :: Fieldr     
+    REAL, dimension(:,:),ALLOCATABLE,SAVE :: Field_tmp     
+    
+    INTEGER :: i,l,offset
+    
+!$OMP BARRIER
+!$OMP MASTER 
+    ALLOCATE(Field_tmp(klon_mpi,ll))
+
+    DO l=1,ll
+      DO i=1,klon_mpi
+        Field_tmp(i,l)=fields(i,l)
+      ENDDO
+    ENDDO
+    
+!$OMP END MASTER
+
+!$OMP BARRIER    
+    offset=klon_omp_begin(omp_rank)-1
+    do l=1,ll
+      do i=1,klon_omp
+        Fieldr(i,l)=Field_tmp(offset+i,l)
+      enddo
+    enddo
+!$OMP BARRIER
+
+!$OMP MASTER 
+    DEALLOCATE(Field_tmp)
+!$OMP END MASTER
+
+  end subroutine ScatterField_omp
+
+  subroutine GatherField_omp(Fields,Fieldr,ll)
+  USE mod_phys_mpi, only : klon_mpi
+  implicit none
+    INTEGER :: ll
+    REAL, dimension(klon_omp,ll) :: Fields
+    REAL, dimension(klon_mpi,ll) :: Fieldr     
+    REAL, dimension(klon_omp,ll) :: Field_tmp
+    
+    INTEGER :: i,l,offset
+
+    Field_tmp(:,:)=Fields(:,:)
+!$OMP BARRIER      
+    offset=klon_omp_begin(omp_rank)-1
+    do l=1,ll
+      do i=1,klon_omp
+        Fieldr(offset+i,l)=Field_tmp(i,l)
+      enddo
+    enddo
+!$OMP BARRIER  
+  end subroutine GatherField_omp
+    
+end module mod_phys_openmp
Index: LMDZ4/branches/V3_test/libf/phylmd/write_field_phy.F90
===================================================================
--- LMDZ4/branches/V3_test/libf/phylmd/write_field_phy.F90	(revision 711)
+++ LMDZ4/branches/V3_test/libf/phylmd/write_field_phy.F90	(revision 711)
@@ -0,0 +1,39 @@
+MODULE write_field_phy
+
+  CONTAINS 
+ 
+    SUBROUTINE WriteField_phy(name,Field,ll)
+    USE dimphy
+    USE Write_Field
+    IMPLICIT NONE
+    include 'dimensions90.h'
+    include 'paramet90.h'
+
+    character(len=*)   :: name
+    INTEGER :: ll
+    real, dimension(klon_omp,ll) :: Field
+    real,save,allocatable :: Field_tmp(:,:)
+    real, dimension(klon2,ll):: New_Field
+    real, dimension(iim,jjp1,ll):: Field_2d
+	
+    if (omp_rank==0) then
+      allocate(Field_tmp(klon_mpi,ll))
+    endif
+    
+!$OMP BARRIER
+    CALL GatherField_omp(Field,Field_tmp,ll)
+!$OMP BARRIER
+
+  if (omp_rank==0) then
+    CALL GatherField(Field_tmp,New_Field,ll)
+    IF (phy_rank==0) THEN
+      CALL gr_fi_ecrit(ll, klon2,iim,jjp1, New_Field, Field_2d)
+      CALL WriteField(name,Field_2d)
+    ENDIF
+    deallocate(Field_tmp)
+  endif
+!$OMP BARRIER 
+  
+   END SUBROUTINE WriteField_phy
+ 
+ END MODULE write_field_phy
