diff --git a/src/MNH/modd_sensor.f90 b/src/MNH/modd_sensor.f90
index 4b052d64412a16337aa33783e9c90014ca233fbf..b780c39137fc86ee7ed5d63c5a9af8921b9b8c04 100644
--- a/src/MNH/modd_sensor.f90
+++ b/src/MNH/modd_sensor.f90
@@ -21,6 +21,8 @@ MODULE MODD_SENSOR
 
   INTEGER, PARAMETER :: NTAG_NCUR = 145
   INTEGER, PARAMETER :: NTAG_PACK = 245
+
+  INTEGER, PARAMETER :: NEMPTYDATA = -1 ! Size to communicate if exchange of no sensor data
   TYPE :: TSENSORTIME
       INTEGER                                    :: N_CUR   = 0       ! current step of storage
       REAL                                       :: XTSTEP  = 60.     ! storage time step (default reset later)
@@ -71,6 +73,7 @@ MODULE MODD_SENSOR
       INTEGER :: NV01 = NNEGUNDEF ! Z position for ni_m  , nj_v+1
       INTEGER :: NV10 = NNEGUNDEF ! Z position for ni_m+1, nj_v
       INTEGER :: NV11 = NNEGUNDEF ! Z position for ni_m+1, nj_v+1
+
       ! Coefficient to interpolate values (sensors are usually not exactly on mesh points)
       REAL :: XXMCOEF = XUNDEF ! Interpolation coefficient for X (mass-point)
       REAL :: XYMCOEF = XUNDEF ! Interpolation coefficient for Y (mass-point)
@@ -1251,9 +1254,9 @@ MODULE MODD_SENSOR
 
     END SUBROUTINE BUFFER_RECV
 
-    ! ##################################################################
-    SUBROUTINE SENSOR_COMM_SEND( TPSENSOR, KTO, OSEND_SIZE_TO_RECEIVER )
-    ! ##################################################################
+    ! ##############################################################################
+    SUBROUTINE SENSOR_COMM_SEND( TPSENSOR, KTO, OSEND_SIZE_TO_RECEIVER, OEMPTYSEND )
+    ! ##############################################################################
 
       USE MODD_IO, ONLY: ISP
 
@@ -1262,10 +1265,12 @@ MODULE MODD_SENSOR
       CLASS(TSENSOR),           INTENT(INOUT) :: TPSENSOR
       INTEGER,                  INTENT(IN)    :: KTO                    ! Process to which to send data
       LOGICAL,        OPTIONAL, INTENT(IN)    :: OSEND_SIZE_TO_RECEIVER ! If the buffer size has to be send to the receiver
+      LOGICAL,        OPTIONAL, INTENT(IN)    :: OEMPTYSEND             ! True if the sensor data has not to be sent
 
       CHARACTER(LEN=10) :: YFROM, YTO
       INTEGER           :: IPACKSIZE
       INTEGER           :: IPOS
+      LOGICAL           :: GEMPTYSEND
       LOGICAL           :: GSEND_SIZE_TO_RECEIVER
       REAL,    DIMENSION(:), ALLOCATABLE :: ZPACK ! buffer to store raw data of the sensor
 
@@ -1274,27 +1279,45 @@ MODULE MODD_SENSOR
       CALL PRINT_MSG( NVERB_DEBUG, 'GEN', 'Sensor_comm_send', &
                       'send sensor ' // TRIM(TPSENSOR%CNAME) // ': ' // TRIM(YFROM) // '->' // TRIM(YTO), OLOCAL = .TRUE. )
 
+      IF ( PRESENT( OEMPTYSEND ) ) THEN
+        GEMPTYSEND = OEMPTYSEND
+      ELSE
+        GEMPTYSEND = .FALSE.
+      END IF
+
       IF ( PRESENT( OSEND_SIZE_TO_RECEIVER ) ) THEN
         GSEND_SIZE_TO_RECEIVER = OSEND_SIZE_TO_RECEIVER
       ELSE
         GSEND_SIZE_TO_RECEIVER = .FALSE.
       END IF
 
-      IPACKSIZE = TPSENSOR%BUFFER_SIZE_COMPUTE( TPSENSOR%NSTORE_CUR )
+      IF ( GEMPTYSEND .AND. .NOT.GSEND_SIZE_TO_RECEIVER )                                                  &
+        CALL PRINT_MSG( NVERB_ERROR, 'GEN', 'Sensor_comm_send',                                            &
+                        'incompatible options: gemptysend=T and gsend_size_to_receiver=F', OLOCAL = .TRUE. )
+
+      IF ( GEMPTYSEND ) THEN
+        ! If 'empty send', ipacksize is set to NEMPTYDATA
+        ! This will allow the receiver to know that no sensor data will be sent
+        IPACKSIZE = NEMPTYDATA
+      ELSE
+        IPACKSIZE = TPSENSOR%BUFFER_SIZE_COMPUTE( TPSENSOR%NSTORE_CUR )
+      END IF
 
       IF ( GSEND_SIZE_TO_RECEIVER ) CALL TPSENSOR%BUFFER_SIZE_SEND( TPSENSOR%NSTORE_CUR, IPACKSIZE, KTO )
 
-      ALLOCATE( ZPACK(IPACKSIZE) )
+      IF ( .NOT. GEMPTYSEND ) THEN
+        ALLOCATE( ZPACK(IPACKSIZE) )
 
-      IPOS = 1
-      CALL TPSENSOR%BUFFER_PACK( ZPACK, IPOS, TPSENSOR%NSTORE_CUR )
+        IPOS = 1
+        CALL TPSENSOR%BUFFER_PACK( ZPACK, IPOS, TPSENSOR%NSTORE_CUR )
 
-      IF ( IPOS-1 /= IPACKSIZE ) &
-        CALL PRINT_MSG( NVERB_ERROR, 'GEN', 'Sensor_comm_send', 'IPOS-1 /= IPACKSIZE', OLOCAL = .TRUE. )
+        IF ( IPOS-1 /= IPACKSIZE ) &
+          CALL PRINT_MSG( NVERB_ERROR, 'GEN', 'Sensor_comm_send', 'IPOS-1 /= IPACKSIZE', OLOCAL = .TRUE. )
 
-      CALL TPSENSOR%BUFFER_SEND( ZPACK, KTO )
+        CALL TPSENSOR%BUFFER_SEND( ZPACK, KTO )
 
-      DEALLOCATE( ZPACK )
+        DEALLOCATE( ZPACK )
+      END IF
 
     END SUBROUTINE SENSOR_COMM_SEND
 
@@ -1313,26 +1336,28 @@ MODULE MODD_SENSOR
 
     END SUBROUTINE SENSOR_COMM_SEND_DEALLOCATE
 
-    ! ####################################################################################################
-    SUBROUTINE SENSOR_COMM_RECV_ALLOCATE( TPSENSOR, KFROM, KSTORE_CUR, KSTORE_MAX, ORECV_SIZE_FROM_OWNER )
-    ! ####################################################################################################
+    ! ################################################################################################################
+    SUBROUTINE SENSOR_COMM_RECV_ALLOCATE( TPSENSOR, KFROM, KSTORE_CUR, KSTORE_MAX, ORECV_SIZE_FROM_OWNER, OEMPTYRECV )
+    ! ################################################################################################################
 
       USE MODD_IO, ONLY: ISP
 
       USE MODE_MSG
 
       CLASS(TSENSOR),           INTENT(INOUT) :: TPSENSOR
-      INTEGER,                  INTENT(IN)    :: KFROM    ! Process from which to receive data
+      INTEGER,                  INTENT(IN)    :: KFROM      ! Process from which to receive data
       INTEGER,        OPTIONAL, INTENT(IN)    :: KSTORE_CUR ! Number of storage steps to receive
       INTEGER,        OPTIONAL, INTENT(IN)    :: KSTORE_MAX ! Maximum number of storage steps to store in sensor
                                                             ! (if not provided, kstore_* size must be given by the sender)
       LOGICAL,        OPTIONAL, INTENT(IN)    :: ORECV_SIZE_FROM_OWNER ! If the buffer size has to be send to the receiver
+      LOGICAL,        OPTIONAL, INTENT(OUT)   :: OEMPTYRECV ! True if the sensor data has not been received
 
       CHARACTER(LEN=10) :: YFROM, YTO
       INTEGER           :: IPACKSIZE
       INTEGER           :: IPOS
       INTEGER           :: ISTORE_CUR
       INTEGER           :: ISTORE_MAX
+      LOGICAL           :: GEMPTYRECV
       LOGICAL           :: GRECV_SIZE_FROM_OWNER
       REAL,    DIMENSION(:), ALLOCATABLE :: ZPACK ! buffer to store raw data of the sensor
 
@@ -1341,6 +1366,8 @@ MODULE MODD_SENSOR
       CALL PRINT_MSG( NVERB_DEBUG, 'GEN', 'Sensor_comm_recv_allocate', &
                       'receive sensor (name not yet known): ' // TRIM(YFROM) // '->' // TRIM(YTO), OLOCAL = .TRUE. )
 
+      GEMPTYRECV = .FALSE.
+
       IF ( PRESENT( ORECV_SIZE_FROM_OWNER ) ) THEN
         GRECV_SIZE_FROM_OWNER = ORECV_SIZE_FROM_OWNER
       ELSE
@@ -1380,19 +1407,29 @@ MODULE MODD_SENSOR
         IPACKSIZE = TPSENSOR%BUFFER_SIZE_COMPUTE( ISTORE_CUR )
       END IF
 
-      ! Allocate receive buffer
-      ALLOCATE( ZPACK(IPACKSIZE) )
+      IF ( IPACKSIZE == NEMPTYDATA ) THEN
+        GEMPTYRECV = .TRUE.
+        !call Print_msg( NVERB_DEBUG, 'GEN', 'Sensor_comm_recv_allocate', 'empty receive', olocal = .true. )
+        IF ( .NOT. PRESENT( OEMPTYRECV) )                                                                                       &
+          CALL PRINT_MSG( NVERB_ERROR, 'GEN', 'Sensor_comm_recv_allocate',                                                      &
+                          'optional dummy argument oemptyrecv must be provided in case of empty communication', OLOCAL = .TRUE. )
+      ELSE
+        ! Allocate receive buffer
+        ALLOCATE( ZPACK(IPACKSIZE) )
+
+        ! Allocation of sensor must be done only once the total number of stores is known (and only if not yet allocated)
+        IF (TPSENSOR%NSTORE_MAX < 0 ) CALL TPSENSOR%DATA_ARRAYS_ALLOCATE( ISTORE_MAX )
 
-      ! Allocation of sensor must be done only once the total number of stores is known (and only if not yet allocated)
-      IF (TPSENSOR%NSTORE_MAX < 0 ) CALL TPSENSOR%DATA_ARRAYS_ALLOCATE( ISTORE_MAX )
+        CALL TPSENSOR%BUFFER_RECV( ZPACK, KFROM )
 
-      CALL TPSENSOR%BUFFER_RECV( ZPACK, KFROM )
+        IPOS = 1
+        CALL TPSENSOR%BUFFER_UNPACK( ZPACK, IPOS, ISTORE_CUR )
 
-      IPOS = 1
-      CALL TPSENSOR%BUFFER_UNPACK( ZPACK, IPOS, ISTORE_CUR )
+        IF ( IPOS-1 /= IPACKSIZE ) &
+          CALL PRINT_MSG( NVERB_ERROR, 'GEN', 'Sensor_comm_recv_allocate', 'IPOS-1 /= IPACKSIZE', OLOCAL = .TRUE. )
+      END IF
 
-      IF ( IPOS-1 /= IPACKSIZE ) &
-        CALL PRINT_MSG( NVERB_ERROR, 'GEN', 'Sensor_comm_recv_allocate', 'IPOS-1 /= IPACKSIZE', OLOCAL = .TRUE. )
+      IF ( PRESENT( OEMPTYRECV) ) OEMPTYRECV = GEMPTYRECV
 
     END SUBROUTINE SENSOR_COMM_RECV_ALLOCATE
 
diff --git a/src/MNH/write_aircraft_balloon.f90 b/src/MNH/write_aircraft_balloon.f90
index 41335da49e79d689be27e647aebea076534b339d..a1b978be286734a3a65d09439ffd0d0792e0300c 100644
--- a/src/MNH/write_aircraft_balloon.f90
+++ b/src/MNH/write_aircraft_balloon.f90
@@ -78,7 +78,9 @@ SUBROUTINE WRITE_AIRCRAFT_BALLOON(TPDIAFILE)
 !
 USE MODD_AIRCRAFT_BALLOON
 USE MODD_IO,               ONLY: ISP, TFILEDATA
-!
+
+USE MODE_MODELN_HANDLER,   ONLY: GET_CURRENT_MODEL_INDEX
+
 IMPLICIT NONE
 !
 !
@@ -90,16 +92,21 @@ TYPE(TFILEDATA), INTENT(IN) :: TPDIAFILE ! file to write
 !
 !       0.2  declaration of local variables
 !
+INTEGER :: IMI
 INTEGER :: JI
+LOGICAL :: GEMPTYCOMM ! if TRUE, the communication is empty (no data is exchanged)
 !
 !----------------------------------------------------------------------------
 
+IMI = GET_CURRENT_MODEL_INDEX()
+
 DO JI = 1, NBALLOONS
   ! The balloon data is only available on the process where it is physically located => transfer it if necessary
 
   ! Send data from owner to writer if necessary
   IF ( ISP == NRANKCUR_BALLOON(JI) .AND. NRANKCUR_BALLOON(JI) /= TPDIAFILE%NMASTER_RANK ) THEN
-    CALL TBALLOONS(JI)%TBALLOON%SEND( KTO = TPDIAFILE%NMASTER_RANK, OSEND_SIZE_TO_RECEIVER = .TRUE. )
+    GEMPTYCOMM = ( TBALLOONS(JI)%TBALLOON%NMODEL /= IMI )
+    CALL TBALLOONS(JI)%TBALLOON%SEND( KTO = TPDIAFILE%NMASTER_RANK, OSEND_SIZE_TO_RECEIVER = .TRUE., OEMPTYSEND = GEMPTYCOMM )
   END IF
 
   IF ( ISP == TPDIAFILE%NMASTER_RANK ) THEN
@@ -108,11 +115,12 @@ DO JI = 1, NBALLOONS
       IF ( ASSOCIATED( TBALLOONS(JI)%TBALLOON ) ) &
         call Print_msg( NVERB_FATAL, 'GEN', 'WRITE_AIRCRAFT_BALLOON', 'balloon already associated' )
       ALLOCATE( TBALLOONS(JI)%TBALLOON )
-      CALL TBALLOONS(JI)%TBALLOON%RECV_ALLOCATE( KFROM = NRANKCUR_BALLOON(JI), ORECV_SIZE_FROM_OWNER = .TRUE. )
+      CALL TBALLOONS(JI)%TBALLOON%RECV_ALLOCATE( KFROM = NRANKCUR_BALLOON(JI), ORECV_SIZE_FROM_OWNER = .TRUE., &
+                                                 OEMPTYRECV = GEMPTYCOMM )
     END IF
 
-    ! Write data
-    CALL FLYER_DIACHRO( TPDIAFILE, TBALLOONS(JI)%TBALLOON )
+    ! Write data (if balloon is on this model (GEMPTYCOMM=F))
+    IF ( .NOT. GEMPTYCOMM ) CALL FLYER_DIACHRO( TPDIAFILE, TBALLOONS(JI)%TBALLOON )
 
     ! Remark: release of memory is done later by a call to AIRCRAFT_BALLOON_FREE_NONLOCAL
     !         This call must be done after the file is closed because flyer data is needed on the
@@ -125,7 +133,8 @@ DO JI = 1, NAIRCRAFTS
 
   ! Send data from owner to writer if necessary
   IF ( ISP == NRANKCUR_AIRCRAFT(JI) .AND. NRANKCUR_AIRCRAFT(JI) /= TPDIAFILE%NMASTER_RANK ) THEN
-    CALL TAIRCRAFTS(JI)%TAIRCRAFT%SEND( KTO = TPDIAFILE%NMASTER_RANK, OSEND_SIZE_TO_RECEIVER = .TRUE. )
+    GEMPTYCOMM = ( TAIRCRAFTS(JI)%TAIRCRAFT%NMODEL /= IMI )
+    CALL TAIRCRAFTS(JI)%TAIRCRAFT%SEND( KTO = TPDIAFILE%NMASTER_RANK, OSEND_SIZE_TO_RECEIVER = .TRUE., OEMPTYSEND = GEMPTYCOMM )
   END IF
 
   IF ( ISP == TPDIAFILE%NMASTER_RANK ) THEN
@@ -134,11 +143,12 @@ DO JI = 1, NAIRCRAFTS
       IF ( ASSOCIATED( TAIRCRAFTS(JI)%TAIRCRAFT ) ) &
         call Print_msg( NVERB_FATAL, 'GEN', 'WRITE_AIRCRAFT_BALLOON', 'aircraft already associated' )
       ALLOCATE( TAIRCRAFTS(JI)%TAIRCRAFT )
-      CALL TAIRCRAFTS(JI)%TAIRCRAFT%RECV_ALLOCATE( KFROM = NRANKCUR_AIRCRAFT(JI), ORECV_SIZE_FROM_OWNER = .TRUE. )
+      CALL TAIRCRAFTS(JI)%TAIRCRAFT%RECV_ALLOCATE( KFROM = NRANKCUR_AIRCRAFT(JI), ORECV_SIZE_FROM_OWNER = .TRUE., &
+                                                   OEMPTYRECV = GEMPTYCOMM )
     END IF
 
-    ! Write data
-    CALL FLYER_DIACHRO( TPDIAFILE, TAIRCRAFTS(JI)%TAIRCRAFT )
+    ! Write data (if aircraft is on this model (GEMPTYCOMM=F))
+    IF ( .NOT. GEMPTYCOMM ) CALL FLYER_DIACHRO( TPDIAFILE, TAIRCRAFTS(JI)%TAIRCRAFT )
 
     ! Remark: release of memory is done later by a call to AIRCRAFT_BALLOON_FREE_NONLOCAL
     !         This call must be done after the file is closed because flyer data is needed on the
@@ -168,7 +178,7 @@ IF ( ISP == TPDIAFILE%NMASTER_RANK ) THEN
   DO JI = 1, NBALLOONS
     ! Free ballon data if it was not stored on this process
     IF ( NRANKCUR_BALLOON(JI) /= TPDIAFILE%NMASTER_RANK ) THEN
-      CALL TBALLOONS(JI)%TBALLOON%DATA_ARRAYS_DEALLOCATE()
+      IF ( TBALLOONS(JI)%TBALLOON%NSTORE_MAX >= 0 ) CALL TBALLOONS(JI)%TBALLOON%DATA_ARRAYS_DEALLOCATE()
       DEALLOCATE( TBALLOONS(JI)%TBALLOON )
     END IF
   END DO
@@ -176,7 +186,7 @@ IF ( ISP == TPDIAFILE%NMASTER_RANK ) THEN
   DO JI = 1, NAIRCRAFTS
     ! Free aircraft data if it was not stored on this process
     IF ( NRANKCUR_AIRCRAFT(JI) /= TPDIAFILE%NMASTER_RANK ) THEN
-      CALL TAIRCRAFTS(JI)%TAIRCRAFT%DATA_ARRAYS_DEALLOCATE()
+      IF ( TAIRCRAFTS(JI)%TAIRCRAFT%NSTORE_MAX >= 0 ) CALL TAIRCRAFTS(JI)%TAIRCRAFT%DATA_ARRAYS_DEALLOCATE()
       DEALLOCATE( TAIRCRAFTS(JI)%TAIRCRAFT )
     END IF
   END DO
diff --git a/src/MNH/write_balloonn.f90 b/src/MNH/write_balloonn.f90
index 4c0e7d02b4acb61d35441843c96319153e74a333..e519c2b99e0d289941727eb4106293c8abab8ac6 100644
--- a/src/MNH/write_balloonn.f90
+++ b/src/MNH/write_balloonn.f90
@@ -73,12 +73,13 @@ TYPE(TFILEDATA),   INTENT(IN) :: TPFILE ! File characteristics
 !
 INTEGER :: IMI
 INTEGER :: JI
-LOGICAL :: OMONOPROC_SAVE ! Copy of true value of GSMONOPROC
+LOGICAL :: GEMPTYCOMM     ! if TRUE, the communication is empty (no data is exchanged)
+LOGICAL :: GMONOPROC_SAVE ! Copy of true value of GSMONOPROC
 
 IMI = GET_CURRENT_MODEL_INDEX()
 
 ! Save GSMONOPROC value
-OMONOPROC_SAVE = GSMONOPROC
+GMONOPROC_SAVE = GSMONOPROC
 ! Force GSMONOPROC to true to allow IO_Field_write on only 1 process! (not very clean hack)
 GSMONOPROC = .TRUE.
 
@@ -87,30 +88,33 @@ DO JI = 1, NBALLOONS
 
   ! Send data from owner to writer if necessary
   IF ( ISP == NRANKCUR_BALLOON(JI) .AND. NRANKCUR_BALLOON(JI) /= TPFILE%NMASTER_RANK ) THEN
-    CALL TBALLOONS(JI)%TBALLOON%SEND( KTO = TPFILE%NMASTER_RANK, OSEND_SIZE_TO_RECEIVER = .TRUE. )
+    GEMPTYCOMM = ( TBALLOONS(JI)%TBALLOON%NMODEL /= IMI )
+    CALL TBALLOONS(JI)%TBALLOON%SEND( KTO = TPFILE%NMASTER_RANK, OSEND_SIZE_TO_RECEIVER = .TRUE., OEMPTYSEND = GEMPTYCOMM )
   END IF
 
   IF ( ISP == TPFILE%NMASTER_RANK ) THEN
     ! Receive data from owner if not available on the writer process
     IF ( NRANKCUR_BALLOON(JI) /= TPFILE%NMASTER_RANK ) THEN
       ALLOCATE( TBALLOONS(JI)%TBALLOON )
-      CALL TBALLOONS(JI)%TBALLOON%RECV_ALLOCATE( KFROM = NRANKCUR_BALLOON(JI), ORECV_SIZE_FROM_OWNER = .TRUE. )
+      CALL TBALLOONS(JI)%TBALLOON%RECV_ALLOCATE( KFROM = NRANKCUR_BALLOON(JI), ORECV_SIZE_FROM_OWNER = .TRUE., &
+                                                 OEMPTYRECV = GEMPTYCOMM )
     END IF
 
     ! Write data (only if flyer is on the current model)
     ! It will also be written in the ancestry model files
-    IF ( TBALLOONS(JI)%TBALLOON%NMODEL == IMI ) CALL WRITE_BALLOON_POSITION( TPFILE, TBALLOONS(JI)%TBALLOON )
+    ! if GEMPTYCOMM=FALSE => flyer is on the current model (equivalent to TBALLOONS(JI)%TBALLOON%NMODEL==IMI)
+    IF ( .NOT. GEMPTYCOMM ) CALL WRITE_BALLOON_POSITION( TPFILE, TBALLOONS(JI)%TBALLOON )
 
     ! Free ballon data if it was not stored on this process
     IF ( NRANKCUR_BALLOON(JI) /= TPFILE%NMASTER_RANK ) THEN
-      CALL TBALLOONS(JI)%TBALLOON%DATA_ARRAYS_DEALLOCATE()
+      IF ( TBALLOONS(JI)%TBALLOON%NSTORE_MAX >= 0 ) CALL TBALLOONS(JI)%TBALLOON%DATA_ARRAYS_DEALLOCATE()
       DEALLOCATE( TBALLOONS(JI)%TBALLOON )
     END IF
   END IF
 END DO
 
 ! Restore correct value of GSMONOPROC
-GSMONOPROC = OMONOPROC_SAVE
+GSMONOPROC = GMONOPROC_SAVE
 
 END SUBROUTINE WRITE_BALLOON_n
 !-------------------------------------------------------------------------------
@@ -151,7 +155,7 @@ REAL                 :: ZLON          ! longitude of the balloon
 type(tfiledata)      :: tzfile
 TYPE(TFIELDMETADATA) :: TZFIELD
 
-! Do not write balloon position if not yet in fly or crashed
+! Do not write balloon position if not yet in flight or crashed
 IF ( .NOT.TPFLYER%LFLY .OR. TPFLYER%LCRASH ) RETURN
 
 ! Check if current model time is the same as the time corresponding to the balloon position