Index: codes/icosagcm/trunk/src/physics/physics.f90
===================================================================
--- codes/icosagcm/trunk/src/physics/physics.f90	(revision 713)
+++ codes/icosagcm/trunk/src/physics/physics.f90	(revision 871)
@@ -20,4 +20,5 @@
   CHARACTER(LEN=255),SAVE :: physics_type
 !$OMP THREADPRIVATE(physics_type)
+  TYPE(t_message),SAVE :: req_theta0, req_ue0, req_q0
 
   PUBLIC :: physics, init_physics, zero_du_phys
@@ -115,4 +116,6 @@
 
     IF(is_mpi_root) PRINT *, 'phys_type = ',phys_type
+    
+    
 !$OMP END PARALLEL
   END SUBROUTINE init_physics
@@ -159,45 +162,64 @@
     TYPE(t_field),POINTER :: f_wflux(:)
     TYPE(t_field),POINTER :: f_q(:)
-
+    
+    LOGICAL,SAVE :: first=.TRUE.
+!$OMP THREADPRIVATE(first)
+    
     LOGICAL:: firstcall,lastcall
     INTEGER :: ind
     TYPE(t_physics_inout) :: args
 
-    IF(MOD(it,itau_physics)==0 .AND. phys_type/=phys_none) THEN
-
-       ! as a result of the the two calls to add_du_phys,
-       ! du_phys increases by u(after physics) - u (before physics)
-       CALL add_du_phys(-1., f_ue)
-
-       SELECT CASE(phys_type)
-       CASE(phys_HS94)
-          CALL held_suarez(f_ps,f_theta_rhodz,f_ue) 
-       CASE (phys_lmdz_generic)
-         CALL physics_lmdz_generic(it ,f_phis, f_ps, f_theta_rhodz, f_ue, f_wflux, f_q)
-       CASE (phys_external)
-         CALL physics_external(it ,f_phis, f_ps, f_theta_rhodz, f_ue, f_wflux, f_q)
-       CASE(phys_LB2012)
-          CALL phys_venus(f_ps,f_theta_rhodz,f_ue) 
-       CASE DEFAULT
-          CALL physics_column(it, f_phis, f_ps, f_theta_rhodz, f_ue, f_q)
-       END SELECT
-
-       CALL transfert_request(f_theta_rhodz,req_i0)
-       CALL transfert_request(f_ue,req_e0_vect)
-       CALL transfert_request(f_q,req_i0)
-
-       CALL add_du_phys(1., f_ue)
-    END IF
-
-    IF (mod(it,itau_out)==0 ) THEN
-       CALL write_physics_tendencies
-       CALL zero_du_phys
-       SELECT CASE(phys_type)
-       CASE (phys_DCMIP)
-          CALL write_physics_dcmip
-       CASE (phys_DCMIP2016)
-          CALL write_physics_dcmip2016
-       END SELECT
-    END IF
+    IF (first) THEN
+      CALL init_message(f_theta_rhodz, req_i0, req_theta0)
+      CALL init_message(f_ue, req_e0_vect, req_ue0)
+      CALL init_message(f_q, req_i0, req_q0)
+      first=.FALSE.
+    ENDIF
+
+
+    IF (phys_external) THEN
+    
+      CALL physics_external(it ,f_phis, f_ps, f_theta_rhodz, f_ue, f_wflux, f_q)
+
+    ELSE
+    
+      IF(MOD(it,itau_physics)==0 .AND. phys_type/=phys_none) THEN
+
+         ! as a result of the the two calls to add_du_phys,
+         ! du_phys increases by u(after physics) - u (before physics)
+         CALL add_du_phys(-1., f_ue)
+
+         SELECT CASE(phys_type)
+         CASE(phys_HS94)
+            CALL held_suarez(f_ps,f_theta_rhodz,f_ue) 
+         CASE (phys_lmdz_generic)
+           CALL physics_lmdz_generic(it ,f_phis, f_ps, f_theta_rhodz, f_ue, f_wflux, f_q)
+         CASE(phys_LB2012)
+            CALL phys_venus(f_ps,f_theta_rhodz,f_ue) 
+         CASE DEFAULT
+            CALL physics_column(it, f_phis, f_ps, f_theta_rhodz, f_ue, f_q)
+         END SELECT
+
+         CALL send_message(f_theta_rhodz, req_theta0)
+         CALL send_message(f_ue, req_ue0)
+         CALL send_message(f_q, req_q0)
+         CALL wait_message(req_theta0)
+         CALL wait_message(req_ue0)
+         CALL wait_message(req_q0)
+       
+         CALL add_du_phys(1., f_ue)
+      END IF
+
+      IF (mod(it,itau_out)==0 ) THEN
+         CALL write_physics_tendencies
+         CALL zero_du_phys
+         SELECT CASE(phys_type)
+         CASE (phys_DCMIP)
+            CALL write_physics_dcmip
+         CASE (phys_DCMIP2016)
+            CALL write_physics_dcmip2016
+         END SELECT
+      END IF
+    ENDIF
     
   END SUBROUTINE physics
Index: codes/icosagcm/trunk/src/physics/physics_external.F90
===================================================================
--- codes/icosagcm/trunk/src/physics/physics_external.F90	(revision 713)
+++ codes/icosagcm/trunk/src/physics/physics_external.F90	(revision 871)
@@ -11,17 +11,52 @@
   TYPE(t_field),POINTER,SAVE :: f_wflux(:)
   TYPE(t_field),POINTER,SAVE :: f_q(:)
+
+  TYPE(t_field),POINTER,SAVE :: f_theta_rhodz0(:)
+  TYPE(t_field),POINTER,SAVE :: f_u0(:)
+  TYPE(t_field),POINTER,SAVE :: f_q0(:)
+ 
+  TYPE(t_field),POINTER,SAVE :: f_dtheta_rhodz(:)
+  TYPE(t_field),POINTER,SAVE :: f_du(:)
+  TYPE(t_field),POINTER,SAVE :: f_dq(:)
+
+  TYPE(t_field),POINTER,SAVE :: f_rhodz(:)
+  TYPE(t_field),POINTER,SAVE :: f_rhodz0(:)
   
-  
-  
+  LOGICAL,SAVE :: phys_smooth_tendency
+!$OMP THREADPRIVATE(phys_smooth_tendency)  
+
+
 CONTAINS
 
   SUBROUTINE init_physics
+  USE icosa
+  IMPLICIT NONE
 
     CALL initialize_external_physics
+    CALL allocate_field(f_theta_rhodz0, field_t, type_real, llm, nqdyn, name='theta_rhodz0')
+    CALL allocate_field(f_u0,field_u,type_real,llm,name='u0')
+    CALL allocate_field(f_q0,field_t,type_real,llm,nqtot,'q0')
+
+    CALL allocate_field(f_dtheta_rhodz, field_t, type_real, llm, nqdyn, name='theta_rhodz0')
+    CALL allocate_field(f_du,field_u,type_real,llm,name='u0')
+    CALL allocate_field(f_dq,field_t,type_real,llm,nqtot,'q0')
+
+    CALL allocate_field(f_rhodz, field_t, type_real, llm, name='rhodz')
+    
+    phys_smooth_tendency=.FALSE.
+    CALL getin("phys_smooth_tendency",phys_smooth_tendency)
+    
         
   END SUBROUTINE init_physics
   
   SUBROUTINE physics(it_,f_phis_, f_ps_, f_theta_rhodz_, f_u_, f_wflux_, f_q_)
+  USE icosa
   USE field_mod
+  USE mpipara
+  USE omp_para
+  USE xios
+  USE domain_mod
+  USE time_mod
+  USE disvert_mod
   IMPLICIT NONE
     INTEGER,INTENT(IN)    :: it_
@@ -33,5 +68,11 @@
     TYPE(t_field),POINTER :: f_q_(:)
 
-    it=it_
+    REAL(rstd),POINTER    :: theta_rhodz(:,:,:), theta_rhodz0(:,:,:), dtheta_rhodz(:,:,:) 
+    REAL(rstd),POINTER    :: u(:,:), u0(:,:), du(:,:)
+    REAL(rstd),POINTER    :: q(:,:,:),q0(:,:,:),dq(:,:,:)
+    REAL(rstd),POINTER    :: ps(:)
+    REAL(rstd),POINTER    :: rhodz(:,:)
+    INTEGER :: ind, iq
+    
     
 !$OMP BARRIER
@@ -46,6 +87,93 @@
 !$OMP BARRIER
 
-    CALL external_physics
+    IF (phys_smooth_tendency) THEN
     
+      IF (MOD(it_,itau_physics)==1) THEN
+        DO ind=1, ndomain
+          IF (.NOT. assigned_domain(ind)) CYCLE
+          CALL swap_dimensions(ind)
+          CALL swap_geometry(ind)
+          theta_rhodz=f_theta_rhodz(ind)
+          theta_rhodz0=f_theta_rhodz0(ind)
+          u=f_u(ind)
+          u0=f_u0(ind)
+          q=f_q(ind)
+          q0=f_q0(ind)
+          ps=f_ps(ind)
+          rhodz=f_rhodz(ind)
+       
+          theta_rhodz0(:,:,1)=theta_rhodz(:,:,1)
+          u0=u
+          q0=q
+          CALL compute_rhodz(.TRUE., ps, rhodz)
+        ENDDO
+     
+        IF (is_omp_master) CALL xios_timer_suspend("dynamico")
+        it = it_-1 + itau_physics
+        CALL external_physics
+        IF (is_omp_master) CALL xios_timer_resume("dynamico")
+
+        DO ind=1, ndomain
+          IF (.NOT. assigned_domain(ind)) CYCLE
+          CALL swap_dimensions(ind) 
+          CALL swap_geometry(ind) 
+          theta_rhodz=f_theta_rhodz(ind)
+          theta_rhodz0=f_theta_rhodz0(ind)
+          u=f_u(ind)
+          u0=f_u0(ind)
+          q=f_q(ind)
+          q0=f_q0(ind)
+          dtheta_rhodz=f_dtheta_rhodz(ind)
+          du=f_du(ind)
+          dq=f_dq(ind)
+          rhodz=f_rhodz(ind)
+       
+          dtheta_rhodz(:,:,1)=(theta_rhodz(:,:,1)-theta_rhodz0(:,:,1))/itau_physics
+          du=(u-u0)/itau_physics
+   
+          DO iq=1, nqtot
+            dq(:,:,iq)=((q(:,:,iq)-q0(:,:,iq))/itau_physics)/rhodz(:,:)
+          ENDDO
+         
+          theta_rhodz(:,:,1)=theta_rhodz0(:,:,1)
+          u=u0
+          q=q0
+        ENDDO
+     ENDIF
+   
+     DO ind=1, ndomain
+       IF (.NOT. assigned_domain(ind)) CYCLE
+       CALL swap_dimensions(ind)
+       CALL swap_geometry(ind)
+         
+       theta_rhodz=f_theta_rhodz(ind)
+       u=f_u(ind)
+       q=f_q(ind)
+       dtheta_rhodz=f_dtheta_rhodz(ind)
+       du=f_du(ind)
+       dq=f_dq(ind)
+       rhodz=f_rhodz(ind)
+       ps=f_ps(ind)
+
+       u=u+du
+       theta_rhodz=theta_rhodz+dtheta_rhodz
+       CALL compute_rhodz(.TRUE., ps, rhodz)
+       DO iq=1, nqtot
+         q(:,:,iq)=q(:,:,iq)+dq(:,:,iq)*rhodz(:,:)
+       ENDDO
+     ENDDO
+   
+   ELSE
+       
+     IF (MOD(it_,itau_physics)==0) THEN
+       it=it_
+       IF (is_omp_master) CALL xios_timer_suspend("dynamico")
+       CALL external_physics
+       IF (is_omp_master) CALL xios_timer_resume("dynamico")
+     ENDIF
+   
+   ENDIF      
+
+
   END SUBROUTINE physics
   
