 SUBROUTINE synchro_mpi(calc)
!=========================== DOCUMENTATION ============================= 
!DOCDEBh*    NUM/synchro_mpi  *
!
!    NOM
! synchro_mpi(calc)
!    DESCRIPTION 
!*
! Envoie des donnees entre domaines et calcul du pas de temps global 
! Sending data between domains and calculating the global time step 
!*
! 
!    ENTREES / INPUT
! calc : objet calcul / calcul object
!    SORTIES / OUTPUT
! calc : objet calcul / calcul object
!
!    SOURCE
! Ce logiciel est regi par la licence [CeCILL-B]
! This software is governed by the [CeCILL-B] license
!=========================== DEBUT DES DECLARATIONS ==================== 
!.1-----  Implicit, Use
  use num_typ
  IMPLICIT NONE
#ifdef _MPI
  include 'mpif.h'
#endif
!.2-----  Declaration
  type(calcul), intent(inout)          :: calc !! Objet calcul / Calcul object
  
  real(kind=kind(0.d0))                :: dt_glob,vmax_glob,xb_level_cell_glob
  integer                              :: ierr,isize,nbs,nbr,jj,kc,ii
#ifdef _MPI
  integer, dimension(MPI_STATUS_SIZE)  :: istat
#endif

! tableau des donnees a  echanger dimensionne au max des cellules a  envoyer ou recevoir
! conserve entre chaque appel a synchro_mpi
!  type(vect_nvar),dimension(:),save,allocatable :: buffer_send,buffer_recv  ! version non visqueuse
  type(state),dimension(:),save,allocatable :: buffer_send,buffer_recv       ! version visqueuse (passage des gradients)
!=========================== DEBUT DU CODE EXECUTABLE ==================

! Si buffer n est pas reserve, recherche de sa taille et allocation
  isize=0
  IF (.not.allocated(buffer_send)) THEN
      DO ii=1,calc%msh%nb_dom
          IF (associated(calc%msh%list_send(ii)%L))isize=max(isize,size(calc%msh%list_send(ii)%L))
          IF (associated(calc%msh%list_recv(ii)%L))isize=max(isize,size(calc%msh%list_recv(ii)%L))
      END DO
      allocate(buffer_send(isize))
      allocate(buffer_recv(isize))
  END IF

#ifdef _MPI
  CALL MPI_ALLREDUCE(calc%dt,dt_glob,1,MPI_DOUBLE_PRECISION, MPI_MIN,MPI_COMM_WORLD,ierr)
  CALL MPI_ALLREDUCE(calc%vmax,vmax_glob,1,MPI_DOUBLE_PRECISION,MPI_MAX,MPI_COMM_WORLD,ierr)
  CALL MPI_ALLREDUCE(calc%msh%nb_level_cell*1.d0,xb_level_cell_glob,1,MPI_DOUBLE_PRECISION,MPI_MAX,MPI_COMM_WORLD,ierr)
  calc%dt                = dt_glob
  calc%vmax              = vmax_glob
  calc%msh%nb_level_cell = int(xb_level_cell_glob)
#endif
  
! Echange des donnees entre les sous-domaines
  DO ii=1,calc%msh%nb_dom
        
! Remplissage de buffer_send
      IF (associated(calc%msh%list_send(ii)%L)) THEN
          DO jj=1,size(calc%msh%list_send(ii)%L)
              kc=calc%msh%list_send(ii)%L(jj)
              buffer_send(jj)=calc%msh%list_cell(kc)%w        
          END DO
           
          nbs=size(calc%msh%list_send(ii)%L)
          nbr=size(calc%msh%list_recv(ii)%L)

#ifdef _MPI
          CALL MPI_SENDRECV(buffer_send,(5*nvarmax+4)*nbs,           &
               MPI_DOUBLE_PRECISION,ii-1,calc%ipas,         &
               buffer_recv,(5*nvarmax+4)*nbr,                        &
               MPI_DOUBLE_PRECISION,ii-1,calc%ipas,         &
               MPI_COMM_WORLD,istat,ierr)                 
#endif           
        
! Distribution de buffer_recv dans les celllules

          DO jj=1,size(calc%msh%list_recv(ii)%L)
             kc=calc%msh%list_recv(ii)%L(jj)
             calc%msh%list_cell(kc)%w=buffer_recv(jj)  ! version visqueuse
          END DO
           
      END IF
         
  END DO

  deallocate(buffer_send)
  deallocate(buffer_recv)

!===========================   FIN DE LA ROUTINE    ====================
END SUBROUTINE synchro_mpi
!DOCFIN
