program data_atm
  !****************************************************************
  !--- ATM main for testing
  !****************************************************************

  use mpi
  use com_cpl

!xxx  !--- Store and retrieve cccma logical records
!xxx  use com_ccdata

  implicit none

  !--- The mpi communicator assigned to the atm
  integer(kind=impi) :: atm_comm

  !--- Integer parameters passed to mpi routines
  integer(kind=impi) :: ierr, rank, nproc, mynode

  !--- misc
  integer :: ix, iy, iz, nwrds, idx, ntime, verbose=1
  integer :: curr_size, curr_tag
  integer(kind=8) :: curr_time
  character(len=32) :: name
  type(cpl_vinfo_t) :: cpl_vinfo

  !--- Buffer and work space used by CCCma io routines
  integer, parameter :: maxx=8392704  !---2049x4096
  real               :: wrk(maxx)
  integer            :: ibuf(8)

  !--- Start MPI
  call mpi_init( ierr )

  !--- Initialize groups for coupler, atm and ocn
  call define_group('atm', atm_comm)

  call mpi_comm_rank( atm_comm, rank, ierr )
  call mpi_comm_size( atm_comm, nproc, ierr )
  write(6,'(a,4i8)')'data_atm: atm_comm, rank, size, atm_master ',atm_comm,rank,nproc,atm_master

  !--- Determine rank in MPI_COMM_WORLD
  call mpi_comm_rank( MPI_COMM_WORLD, mynode, ierr )

  !--- IMPORTANT ---
  !--- atm_master is the rank in MPI_COMM_WORLD not the rank in atm_comm
  !--- IMPORTANT ---

  !--- Initialize ibuf and wrk
  ibuf(1:8) = (/ transfer("GRID",ix), 0, 0, 1, nlon_a+1, nlat_a, 1, 1 /)
  nwrds = ibuf(5) * ibuf(6)
  wrk(1:nwrds) = (/ (ix, ix=1,nwrds) /)

  !--- Loop over time
  do ntime=1,2

    curr_time = ntime

    if ( mynode == atm_master ) then
      !--- Recv MSG data from the coupler
      cpl_vinfo = find_cpl_vinfo( name="MSG" )
      curr_size = cpl_vinfo%size
      curr_tag  = cpl_vinfo%tag
      call recv_data_rec(wrk, ibuf, cpl_master, curr_size, curr_tag)
    endif

#ifdef couple_ICE_MODEL
    if ( mynode == atm_master ) then
      !--- Recv MSG_ice data from the coupler
      cpl_vinfo = find_cpl_vinfo( name="MSG_ice" )
      curr_size = cpl_vinfo%size
      curr_tag  = cpl_vinfo%tag
      call recv_data_rec(wrk, ibuf, cpl_master, curr_size, curr_tag)
    endif
#endif

!xxx    if ( mynode == atm_master ) then
!xxx      !--- Receive from the coupler, but only from the master node
!xxx      do idx=1,n_ocn_to_atm_list
!xxx        name = trim( ocn_to_atm_list(idx)%name )
!xxx        curr_size = ocn_to_atm_list(idx)%size
!xxx        curr_tag  = ocn_to_atm_list(idx)%tag
!xxx
!xxx        !--- Receive from coupler
!xxx        if (verbose>1) then
!xxx          write(6,'(3a)')'data_atm: RECV ',trim(name),' from coupler.'
!xxx          call flush(6)
!xxx        endif
!xxx        call recv_data_rec(wrk, ibuf, cpl_master, curr_size, curr_tag)
!xxx      enddo
!xxx    endif

!xxx    if ( mynode == atm_master ) then
!xxx      !--- Send to the coupler, but only from the master node
!xxx      do idx=1,n_atm_to_ocn_list
!xxx        name = trim( atm_to_ocn_list(idx)%name )
!xxx        curr_size = atm_to_ocn_list(idx)%size
!xxx        curr_tag  = atm_to_ocn_list(idx)%tag
!xxx
!xxx        !--- Read data at curr_time for the current variable
!xxx        call read_atm_data( trim(name), curr_time, curr_tag, curr_size, ibuf, wrk )
!xxx
!xxx        !--- Send to coupler
!xxx        if (verbose>1) then
!xxx          write(6,'(3a)')'data_atm: SEND ',trim(name),' to coupler.'
!xxx          call flush(6)
!xxx        endif
!xxx        call send_data_rec(wrk, ibuf, cpl_master, curr_size, curr_tag)
!xxx      enddo
!xxx    endif

    if ( mynode == atm_master ) then
      !--- Send MSG data to the coupler
      cpl_vinfo = find_cpl_vinfo( name="MSG" )
      curr_size = cpl_vinfo%size
      curr_tag  = cpl_vinfo%tag
      ibuf(1:8) = (/ transfer(" MSG",ix), curr_time, curr_tag, 1, 8, 1, 0, 1 /)
      wrk(1:curr_size) = 0.0
      wrk(1) = 1
      call send_data_rec(wrk, ibuf, cpl_master, curr_size, curr_tag)
    endif

#ifdef couple_ICE_MODEL
    if ( mynode == atm_master ) then
      !--- Send MSG_ice data to the coupler
      cpl_vinfo = find_cpl_vinfo( name="MSG_ice" )
      curr_size = cpl_vinfo%size
      curr_tag  = cpl_vinfo%tag
      ibuf(1:8) = (/ transfer("MSGI",ix), curr_time, curr_tag, 1, 8, 1, 0, 1 /)
      wrk(1:curr_size) = 0.0
      wrk(1) = 1
      call send_data_rec(wrk, ibuf, cpl_master, curr_size, curr_tag)
    endif
#endif

  enddo

  if (verbose>0) then
    write(6,'(a,i4,a)')'data_atm:  Node ',mynode,' is DONE.'
    call flush(6)
  endif

  !--- Stop MPI
  call mpi_finalize( ierr )

end program data_atm

subroutine read_atm_data( name, curr_time, curr_tag, curr_size, ibuf, wrk )

  use mpi
  use com_cpl

  implicit none

  integer, parameter :: maxx=8392704  !---2049x4096

  character(len=*), intent(in) :: name
  integer(kind=8), intent(in) :: curr_time
  integer, intent(in) :: curr_size, curr_tag
  real,    intent(out) :: wrk(maxx)
  integer, intent(out) :: ibuf(8)

  !--- local
  integer :: ix, nwrds

  !--- Initialize ibuf and wrk
  ibuf(1:8) = (/ transfer("GRID",ix), curr_time, curr_tag, 1, nlon_a+1, nlat_a, 1, 1 /)
  nwrds = ibuf(5) * ibuf(6)
  wrk(1:nwrds) = (/ (ix, ix=1,nwrds) /)
  wrk(1) = curr_tag

end subroutine read_atm_data

!xxx!-----------------------------------------------------------------------------
!xxx!--- Store atm data that is to be passed to the coupler
!xxx!-----------------------------------------------------------------------------
!xxxsubroutine store_data()
!xxx
!xxx  use mpi
!xxx  use com_cpl
!xxx
!xxx  !--- Store and retrieve cccma logical records
!xxx  use com_ccdata
!xxx
!xxx  implicit none
!xxx
!xxx  integer :: ix, nwrds, noise
!xxx
!xxx  !--- Integer parameters passed to mpi routines
!xxx  integer(kind=impi) :: ierr, rank, nproc, mynode
!xxx
!xxx  !--- Buffer and work space used by CCCma io routines
!xxx  integer, parameter :: maxx=8392704  !---2049x4096
!xxx  real               :: wrk(maxx)
!xxx  integer            :: ibuf(8)
!xxx
!xxx  !-----------------------------------------------------------------------------
!xxx
!xxx  call mpi_comm_rank( MPI_COMM_WORLD, mynode, ierr )
!xxx
!xxx  !--- Only allow the master task to print from store_ccdata
!xxx  noise = 0
!xxx  if (mynode .eq. atm_master) noise = 1
!xxx
!xxx  ibuf(1) = transfer("GRID",ix)
!xxx  ibuf(4) = 1
!xxx  ibuf(5) = nlon_a + 1
!xxx  ibuf(6) = nlat_a
!xxx  ibuf(7) = 1
!xxx  ibuf(8) = 1
!xxx  nwrds = ibuf(5) * ibuf(6)
!xxx  wrk(1:nwrds) = (/ (ix, ix=1,nwrds) /)
!xxx
!xxx  !--- MSG
!xxx  ibuf(2) = 123
!xxx  ibuf(3) = transfer(" MSG",ix)
!xxx  ibuf(5) = 8
!xxx  ibuf(6) = 1
!xxx  wrk(1) = 0
!xxx  call store_ccdata("MSG", "msg", ibuf, wrk, noise=noise)
!xxx
!xxx  ibuf(5) = nlon_a + 1
!xxx  ibuf(6) = nlat_a
!xxx
!xxx  !--- OUFS
!xxx  ibuf(2) = 123
!xxx  ibuf(3) = transfer("OUFS",ix)
!xxx  wrk(1) = 1
!xxx  call store_ccdata("OUFS", "atm", ibuf, wrk, noise=noise)
!xxx
!xxx  !--- OVFS
!xxx  ibuf(2) = 123
!xxx  ibuf(3) = transfer("OVFS",ix)
!xxx  wrk(1) = 2
!xxx  call store_ccdata("OVFS", "atm", ibuf, wrk, noise=noise)
!xxx
!xxx  !--- OBEG
!xxx  ibuf(2) = 123
!xxx  ibuf(3) = transfer("OBEG",ix)
!xxx  wrk(1) = 3
!xxx  call store_ccdata("OBEG", "atm", ibuf, wrk, noise=noise)
!xxx
!xxx  !--- OBWG
!xxx  ibuf(2) = 123
!xxx  ibuf(3) = transfer("OBWG",ix)
!xxx  wrk(1) = 4
!xxx  call store_ccdata("OBWG", "atm", ibuf, wrk, noise=noise)
!xxx
!xxx  !--- ROFO
!xxx  ibuf(2) = 123
!xxx  ibuf(3) = transfer("ROFO",ix)
!xxx  wrk(1) = 5
!xxx  call store_ccdata("ROFO", "atm", ibuf, wrk, noise=noise)
!xxx
!xxx  !---   GC
!xxx  ibuf(2) = 123
!xxx  ibuf(3) = transfer("  GC",ix)
!xxx  wrk(1) = 6
!xxx  call store_ccdata("  GC", "atm", ibuf, wrk, noise=noise)
!xxx
!xxx  !---   GT
!xxx  ibuf(2) = 123
!xxx  ibuf(3) = transfer("  GT",ix)
!xxx  wrk(1) = 7
!xxx  call store_ccdata("  GT", "atm", ibuf, wrk, noise=noise)
!xxx
!xxx  !---  SIC
!xxx  ibuf(2) = 123
!xxx  ibuf(3) = transfer(" SIC",ix)
!xxx  wrk(1) = 8
!xxx  call store_ccdata(" SIC", "atm", ibuf, wrk, noise=noise)
!xxx
!xxx  !--- SICN
!xxx  ibuf(2) = 123
!xxx  ibuf(3) = transfer("SICN",ix)
!xxx  wrk(1) = 9
!xxx  call store_ccdata("SICN", "atm", ibuf, wrk, noise=noise)
!xxx
!xxx  !---  SNO
!xxx  ibuf(2) = 123
!xxx  ibuf(3) = transfer(" SNO",ix)
!xxx  wrk(1) = 10
!xxx  call store_ccdata(" SNO", "atm", ibuf, wrk, noise=noise)
!xxx
!xxx  !--- OFSG
!xxx  ibuf(2) = 123
!xxx  ibuf(3) = transfer("OFSG",ix)
!xxx  wrk(1) = 11
!xxx  call store_ccdata("OFSG", "atm", ibuf, wrk, noise=noise)
!xxx
!xxx#if defined biogeochem
!xxx  !--- PMSL
!xxx  ibuf(2) = 123
!xxx  ibuf(3) = transfer("PMSL",ix)
!xxx  wrk(1) = 12
!xxx  call store_ccdata("PMSL", "atm", ibuf, wrk, noise=noise)
!xxx
!xxx  !--- SWMX
!xxx  ibuf(2) = 123
!xxx  ibuf(3) = transfer("SWMX",ix)
!xxx  wrk(1) = 13
!xxx  call store_ccdata("SWMX", "atm", ibuf, wrk, noise=noise)
!xxx
!xxx  !--- XSRF
!xxx  ibuf(2) = 123
!xxx  ibuf(3) = transfer("XL16",ix)
!xxx  wrk(1) = 14
!xxx  call store_ccdata("XSRF", "atm", ibuf, wrk, noise=noise)
!xxx#endif
!xxx
!xxxend subroutine store_data
