125 #include <fms_platform.h>   128                            error_mesg, close_file, fatal, note, stdlog,      &
   130                            field_size, lowercase, 
string,                    &
   134                            mpp_sync_self, stdout, 
mpp_max, event_recv,        &
   135                            mpp_get_current_pelist, mpp_clock_id, 
mpp_min,     &
   137                            mpp_clock_begin, mpp_clock_end, mpp_clock_sync,    &
   138                            comm_tag_1, comm_tag_2, comm_tag_3, comm_tag_4,    &
   139                            comm_tag_5, comm_tag_6, comm_tag_7, comm_tag_8,    &
   140                            comm_tag_9, comm_tag_10
   145                            yupdate, mpp_get_current_ntile, mpp_get_tile_id, &
   146                            mpp_get_ntile_count, mpp_get_tile_list,          &
   149                            mpp_get_domain_npes, mpp_get_domain_root_pe,     &
   151                            mpp_get_domain_pelist, mpp_compute_extent,       &
   152                            domainug, mpp_get_ug_compute_domains,            &
   153                            mpp_get_ug_domains_index, mpp_get_ug_domain_grid_index, &
   155 use mpp_io_mod,      
only: mpp_open, mpp_multi, mpp_single, mpp_overwr
   318   integer :: i1, j1, i2, j2 
   331    real, 
dimension(:,:),   
pointer :: dx     => null()
   332    real, 
dimension(:,:),   
pointer :: dy     => null()
   333    real, 
dimension(:,:),   
pointer :: area   => null()
   334    real, 
dimension(:),     
pointer :: edge_w => null()
   335    real, 
dimension(:),     
pointer :: edge_e => null()
   336    real, 
dimension(:),     
pointer :: edge_s => null()
   337    real, 
dimension(:),     
pointer :: edge_n => null()
   338    real, 
dimension(:,:,:), 
pointer :: en1    => null()
   339    real, 
dimension(:,:,:), 
pointer :: en2    => null()
   340    real, 
dimension(:,:,:), 
pointer :: vlon   => null()
   341    real, 
dimension(:,:,:), 
pointer :: vlat   => null()
   345   character(len=3)                :: id                               
   347   logical                         :: on_this_pe                       
   349   integer, 
pointer, 
dimension(:)  :: pelist                           
   352   integer, 
pointer, 
dimension(:)  :: tile =>null()                    
   353   integer, 
pointer, 
dimension(:)  :: is =>null(), ie =>null()         
   354   integer, 
pointer, 
dimension(:)  :: js =>null(), je =>null()         
   355   integer, 
pointer                :: is_me =>null(),  ie_me =>null()  
   356   integer, 
pointer                :: js_me =>null(),  je_me =>null()  
   357   integer                         :: isd_me, ied_me                   
   358   integer                         :: jsd_me, jed_me                   
   359   integer                         :: nxd_me, nyd_me                   
   360   integer                         :: nxc_me, nyc_me                   
   361   integer, 
pointer                :: tile_me                          
   362   integer                         :: im , jm , km                     
   363   real, 
pointer, 
dimension(:)     :: lon =>null(), lat =>null()       
   364   real, 
pointer, 
dimension(:,:)   :: geolon=>null(), geolat=>null()   
   365   real, 
pointer, 
dimension(:,:,:) :: frac_area =>null()               
   366   real, 
pointer, 
dimension(:,:)   :: area =>null()                    
   367   real, 
pointer, 
dimension(:,:)   :: area_inv =>null()                
   368   integer                         :: first, last                      
   369   integer                         :: first_get, last_get              
   372   integer                         :: size_repro                       
   381   integer, 
pointer                :: ls_me =>null(),  le_me =>null()  
   382   integer, 
pointer, 
dimension(:)  :: ls =>null(), le =>null()
   383   integer, 
pointer                :: gs_me =>null(),  ge_me =>null()  
   384   integer, 
pointer, 
dimension(:)  :: gs =>null(), ge =>null()
   385   integer, 
pointer, 
dimension(:)  :: l_index =>null()
   400   integer :: i, j, l, k, pos
   408    integer          :: buffer_pos
   409    integer, _allocatable :: i(:) _null
   410    integer, _allocatable :: j(:) _null
   411    integer, _allocatable :: 
g(:) _null
   412    integer, _allocatable :: xloc(:) _null
   413    integer, _allocatable :: tile(:) _null
   414    real,    _allocatable :: di(:) _null
   415    real,    _allocatable :: dj(:) _null
   419   integer                         :: nsend, nrecv
   420   integer                         :: sendsize, recvsize
   421   integer,            
pointer, 
dimension(:) :: unpack_ind=>null()
   431   integer :: me, npes, root_pe
   432   logical, 
pointer, 
dimension(:) :: your1my2  =>null()
   435   logical, 
pointer, 
dimension(:) :: your2my1 =>null() 
   438   integer, 
pointer, 
dimension(:) :: your2my1_size=>null() 
   443   type(
grid_type), 
pointer, 
dimension(:) :: grids =>null() 
   448   type(
x1_type), 
pointer, 
dimension(:) :: x1 =>null() 
   449   type(
x1_type), 
pointer, 
dimension(:) :: x1_put =>null() 
   450   type(
x2_type), 
pointer, 
dimension(:) :: x2 =>null() 
   451   type(
x2_type), 
pointer, 
dimension(:) :: x2_get =>null() 
   453   integer, 
pointer, 
dimension(:) :: send_count_repro =>null()
   454   integer, 
pointer, 
dimension(:) :: recv_count_repro  =>null()
   455   integer                        :: send_count_repro_tot 
   456   integer                        :: recv_count_repro_tot 
   459   integer, 
pointer, 
dimension(:) :: ind_get1 =>null() 
   460   integer, 
pointer, 
dimension(:) :: ind_put1 =>null() 
   468 #include<file_version.h>   470  real, 
parameter                              :: 
eps = 1.0e-10
   507 logical function in_box(i, j, is, ie, js, je)
   508   integer, 
intent(in) :: i, j, is, ie, js, je
   510   in_box = (i>=is) .and. (i<=ie) .and. (j>=js) .and. (j<=je)
   532   integer, 
intent(out) :: remap_method
   534   integer :: unit, ierr, io, out_unit
   540 #ifdef INTERNAL_FILE_NML   544   if ( file_exist( 
'input.nml' ) ) 
then   545       unit = open_namelist_file( )
   547       do while ( ierr /= 0 )
   548         read ( unit,  nml = xgrid_nml, iostat = io, end = 10 )
   552       call close_file ( unit )
   557   call write_version_number(
"XGRID_MOD", version)
   561   if ( mpp_pe() == mpp_root_pe() ) 
write (unit,nml=xgrid_nml)
   562   call close_file (unit)
   571          'xgrid_nml monotonic_exchange must be .false. when interp_method = first_order', fatal)  
   572      write(out_unit,*)
"NOTE from xgrid_mod: use first_order conservative exchange"   575         write(out_unit,*)
"NOTE from xgrid_mod: use monotonic second_order conservative exchange"   577         write(out_unit,*)
"NOTE from xgrid_mod: use second_order conservative exchange"   582       ' is not a valid namelist option', fatal)
   592      id_setup_xmap             = mpp_clock_id(
"setup_xmap", flags=mpp_clock_sync) 
   611 subroutine load_xgrid (xmap, grid, grid_file, grid1_id, grid_id, tile1, tile2, use_higher_order)
   612 type(xmap_type), 
intent(inout)         :: xmap
   613 type(grid_type), 
intent(inout)         :: grid
   614 character(len=*), 
intent(in)           :: grid_file
   615 character(len=3), 
intent(in)           :: grid1_id, grid_id
   616 integer,          
intent(in)           :: tile1, tile2
   617 logical,        
intent(in)             :: use_higher_order
   619   integer, 
pointer,       
dimension(:)   :: i1=>null(), j1=>null()
   620   integer, 
pointer,       
dimension(:)   :: i2=>null(), j2=>null()            
   621   real,    
pointer,       
dimension(:)   :: di=>null(), dj=>null()
   622   real,    
pointer,       
dimension(:)   :: area =>null()     
   623   integer, 
pointer,       
dimension(:)   :: i1_tmp=>null(), j1_tmp=>null()
   624   integer, 
pointer,       
dimension(:)   :: i2_tmp=>null(), j2_tmp=>null()
   625   real,    
pointer,       
dimension(:)   :: di_tmp=>null(), dj_tmp=>null()
   626   real,    
pointer,       
dimension(:)   :: area_tmp =>null()
   627   integer, 
pointer,       
dimension(:)   :: i1_side1=>null(), j1_side1=>null()
   628   integer, 
pointer,       
dimension(:)   :: i2_side1=>null(), j2_side1=>null()            
   629   real,    
pointer,       
dimension(:)   :: di_side1=>null(), dj_side1=>null()
   630   real,    
pointer,       
dimension(:)   :: area_side1 =>null()    
   632   real,    
allocatable, 
dimension(:,:) :: tmp
   633   real,    
allocatable, 
dimension(:)   :: send_buffer, recv_buffer
   634   type(
grid_type),   
pointer, 
save    :: grid1 =>null()
   635   integer                              :: l, ll, ll_repro, p, siz(4), nxgrid, size_prev
   636   type(xcell_type),   
allocatable      :: x_local(:)
   637   integer                              :: size_repro, out_unit
   638   logical                              :: scale_exist = .false.
   639   logical                              :: is_distribute = .false.
   640   real,    
allocatable,   
dimension(:) :: scale
   642   integer                              :: npes, isc, iec, nxgrid_local, pe, nxgrid_local_orig
   643   integer                              :: nxgrid1, nxgrid2, nset1, nset2, ndivs, cur_ind
   644   integer                              :: pos, nsend, nrecv, l1, l2, n, mypos, m
   645   integer                              :: start(4), nread(4)
   647   character(len=128)                   :: attvalue
   648   integer, 
dimension(0:xmap%npes-1)    :: pelist
   649   logical, 
dimension(0:xmap%npes-1)    :: subset_rootpe
   650   integer, 
dimension(0:xmap%npes-1)    :: nsend1, nsend2, nrecv1, nrecv2
   651   integer, 
dimension(0:xmap%npes-1)    :: send_cnt, recv_cnt
   652   integer, 
dimension(0:xmap%npes-1)    :: send_buffer_pos, recv_buffer_pos
   653   integer, 
dimension(0:xmap%npes-1)    :: ibegin, iend, pebegin, peend
   654   integer, 
dimension(2*xmap%npes)      :: ibuf1, ibuf2
   655   integer, 
dimension(0:xmap%npes-1)    :: pos_x, y2m1_size
   656   integer, 
allocatable,   
dimension(:) :: y2m1_pe
   657   integer, 
pointer, 
save               :: iarray(:), jarray(:)
   658   integer, 
allocatable, 
save           :: pos_s(:)
   659   integer, 
pointer,       
dimension(:) :: iarray2(:)=>null(), jarray2(:)=>null()
   661   integer                              :: nxgrid1_old
   664   scale_exist = .false.
   665   grid1 => xmap%grids(1)
   669   mypos = mpp_pe()-mpp_root_pe()
   671   call mpp_get_current_pelist(pelist)
   673   if( npes .NE. pelist(npes-1) - pelist(0) + 1 ) 
then   674      print*, 
"npes =", npes, 
", pelist(npes-1)=", pelist(npes-1), 
", pelist(0)=", pelist(0)
   675      call error_mesg(
'xgrid_mod', .NE.
'npes  pelist(npes-1) - pelist(0)', fatal)
   678   select case(xmap%version)
   680      call field_size(grid_file, 
'AREA_'//grid1_id//
'x'//grid_id, siz)
   682      if(nxgrid .LE. 0) 
return   686      if(nxgrid .LE. 0) 
return   690   if(nxgrid > npes) 
then   693      call mpp_compute_extent( 1, nxgrid, ndivs, ibegin, iend)
   694      if(npes == ndivs) 
then   695         p = mpp_pe()-mpp_root_pe()
   698         subset_rootpe(:) = .true.
   701         call mpp_compute_extent(pelist(0), pelist(npes-1), ndivs, pebegin, peend)
   703            if(pe == pebegin(n)) 
then   710         subset_rootpe(:) = .false.
   713            if(pelist(n) == pebegin(cur_ind)) 
then   714               subset_rootpe(n) = .true.
   716               if(cur_ind == ndivs) 
exit   720      is_distribute = .true.
   722      is_distribute = .false.
   723      isc = 1; iec = nxgrid
   728   if(use_higher_order) 
then   732   if(scale_exist) nset2 = nset1 + 1
   735   if(iec .GE. isc) 
then   736      nxgrid_local = iec - isc + 1
   737      allocate(i1_tmp(isc:iec), j1_tmp(isc:iec), i2_tmp(isc:iec), j2_tmp(isc:iec), area_tmp(isc:iec) )
   738      if(use_higher_order) 
allocate(di_tmp(isc:iec), dj_tmp(isc:iec))
   742      select case(xmap%version)
   744         start(1) = isc; nread(1) = nxgrid_local
   745         allocate(tmp(nxgrid_local,1))
   746         call read_data(grid_file, 
'I_'//grid1_id//
'_'//grid1_id//
'x'//grid_id, tmp, start, nread, no_domain=.true.)
   748         call read_data(grid_file, 
'J_'//grid1_id//
'_'//grid1_id//
'x'//grid_id, tmp, start, nread, no_domain=.true.)
   750         call read_data(grid_file, 
'I_'//grid_id//
'_'//grid1_id//
'x'//grid_id, tmp, start, nread, no_domain=.true.)
   752         call read_data(grid_file, 
'J_'//grid_id//
'_'//grid1_id//
'x'//grid_id, tmp, start, nread, no_domain=.true.)
   754         call read_data(grid_file, 
'AREA_'//grid1_id//
'x'//grid_id, tmp, start, nread, no_domain=.true.)
   756         if(use_higher_order) 
then   757            call read_data(grid_file, 
'DI_'//grid1_id//
'x'//grid_id, tmp, start, nread, no_domain=.true.)
   759            call read_data(grid_file, 
'DJ_'//grid1_id//
'x'//grid_id, tmp, start, nread, no_domain=.true.)
   764         nread(1) = 2; start(2) = isc; nread(2) = nxgrid_local
   765         allocate(tmp(2, isc:iec))
   766         call read_data(grid_file, 
"tile1_cell", tmp, start, nread, no_domain=.true.)
   767         i1_tmp(isc:iec) = tmp(1, isc:iec)
   768         j1_tmp(isc:iec) = tmp(2, isc:iec)
   769         call read_data(grid_file, 
"tile2_cell", tmp, start, nread, no_domain=.true.)
   770         i2_tmp(isc:iec) = tmp(1, isc:iec)
   771         j2_tmp(isc:iec) = tmp(2, isc:iec)
   772         if(use_higher_order) 
then   773            call read_data(grid_file, 
"tile1_distance", tmp, start, nread, no_domain=.true.)
   774            di_tmp(isc:iec) = tmp(1, isc:iec)
   775            dj_tmp(isc:iec) = tmp(2, isc:iec)
   778         start(1) = isc; nread(1) = nxgrid_local
   780         allocate(tmp(isc:iec,1) )
   781         call read_data(grid_file, 
"xgrid_area", tmp(:,1:1), start, nread, no_domain=.true.)
   784         if( trim(attvalue) == 
'm2' ) 
then   786            area_tmp = tmp(:,1)/garea
   787         else if( trim(attvalue) == 
'none' ) 
then   790            call error_mesg(
'xgrid_mod', 
'In file '//trim(grid_file)//
', xgrid_area units = '// &
   791                 trim(attvalue)//
' should be "m2" or "none"', fatal)
   796         if(grid1_id == 
'LND' .AND. grid_id == 
'OCN') 
then   798               allocate(scale(isc:iec))
   799               write(out_unit, *)
"NOTE from load_xgrid(xgrid_mod): field 'scale' exist in the file "// &
   800                    trim(grid_file)//
", this field will be read and the exchange grid cell area will be multiplied by scale"   801               call read_data(grid_file, 
"scale", tmp, start, nread, no_domain=.true.)
   811      nxgrid_local_orig = nxgrid_local
   812      allocate(i1(isc:iec), j1(isc:iec), i2(isc:iec), j2(isc:iec), area(isc:iec) )
   813      if(use_higher_order) 
allocate(di(isc:iec), dj(isc:iec))
   819            if(grid1%tile(p) == tile1) 
then   820               if(
in_box_nbr(i1_tmp(l), j1_tmp(l), grid1, p)) 
then   829               if(grid%tile(p) == tile2) 
then   830                  if (
in_box_nbr(i2_tmp(l), j2_tmp(l), grid, p)) 
then   836                     area(pos) = area_tmp(l)
   837                     if(use_higher_order) 
then   848      deallocate(i1_tmp, i2_tmp, j1_tmp, j2_tmp, area_tmp)
   849      if(use_higher_order) 
deallocate( di_tmp, dj_tmp)
   851      if(iec .GE. isc) 
then   852         nxgrid_local = iec - isc + 1
   858      nxgrid_local_orig = 0
   863   if(is_distribute) 
then   867      nsend1(:) = 0; nrecv1(:) = 0
   868      nsend2(:) = 0; nrecv2(:) = 0
   869      ibuf1(:)= 0; ibuf2(:)= 0
   872      if(nxgrid_local>0) 
then   873         allocate( send_buffer(nxgrid_local * (nset1+nset2)) )
   876            send_buffer_pos(p) = pos
   877            if(grid%tile(p) == tile2) 
then   880                     nsend2(p) = nsend2(p) + 1
   881                     send_buffer(pos+1) = i1(l)
   882                     send_buffer(pos+2) = j1(l)
   883                     send_buffer(pos+3) = i2(l)
   884                     send_buffer(pos+4) = j2(l)
   885                     send_buffer(pos+5) = area(l)
   886                     if(use_higher_order) 
then   887                        send_buffer(pos+6) = di(l)
   888                        send_buffer(pos+7) = dj(l)
   890                     if(scale_exist) send_buffer(pos+nset2) = scale(l)
   895            if(grid1%tile(p) == tile1) 
then   898                     nsend1(p) = nsend1(p) + 1
   899                     send_buffer(pos+1) = i1(l)
   900                     send_buffer(pos+2) = j1(l)
   901                     send_buffer(pos+3) = i2(l)
   902                     send_buffer(pos+4) = j2(l)
   903                     send_buffer(pos+5) = area(l)
   904                     if(use_higher_order) 
then   905                        send_buffer(pos+6) = di(l)
   906                        send_buffer(pos+7) = dj(l)
   921            ibuf1(2*p+1) = nsend1(p)
   922            ibuf1(2*p+2) = nsend2(p)
   927            p = mod(mypos+npes-n, npes)
   928            if(.not. subset_rootpe(p)) cycle
   929            call mpp_recv( ibuf2(2*p+1), glen=2, from_pe=pelist(p), block=.false., tag=comm_tag_1)
   932         if(nxgrid_local_orig>0) 
then   934               p = mod(mypos+n, npes)
   935               ibuf1(2*p+1) = nsend1(p)
   936               ibuf1(2*p+2) = nsend2(p)
   937               call mpp_send( ibuf1(2*p+1), plen=2, to_pe=pelist(p), tag=comm_tag_1)
   940         call mpp_sync_self(
check=event_recv)
   943         nrecv1(p) = ibuf2(2*p+1)
   944         nrecv2(p) = ibuf2(2*p+2)
   952         recv_buffer_pos(p) = pos
   953         pos = pos + nrecv1(p) * nset1 + nrecv2(p) * nset2
   957      nxgrid1 = sum(nrecv1)
   958      nxgrid2 = sum(nrecv2)
   959      if(nxgrid1>0 .OR. nxgrid2>0) 
allocate(recv_buffer(nxgrid1*nset1+nxgrid2*nset2))
   963         send_cnt(:) = nset1 * nsend1(:) + nset2 * nsend2(:)
   964         recv_cnt(:) = nset1 * nrecv1(:) + nset2 * nrecv2(:)
   966         call mpp_alltoall(send_buffer, send_cnt, send_buffer_pos, &
   967                           recv_buffer, recv_cnt, recv_buffer_pos)
   970            p = mod(mypos+npes-n, npes)
   971            nrecv = nrecv1(p)*nset1+nrecv2(p)*nset2
   973            pos = recv_buffer_pos(p)
   974            call mpp_recv(recv_buffer(pos+1), glen=nrecv, from_pe=pelist(p), &
   975                          block=.false., tag=comm_tag_2)
   979            p = mod(mypos+n, npes)
   980            nsend = nsend1(p)*nset1 + nsend2(p)*nset2
   982            pos = send_buffer_pos(p)
   983            call mpp_send(send_buffer(pos+1), plen=nsend, to_pe=pelist(p), &
   986         call mpp_sync_self(
check=event_recv)
   990      if( nxgrid_local>0) 
then   991         deallocate(i1,j1,i2,j2,area)
   994      allocate(i1(nxgrid2), j1(nxgrid2))
   995      allocate(i2(nxgrid2), j2(nxgrid2))
   996      allocate(area(nxgrid2))
   997      allocate(i1_side1(nxgrid1), j1_side1(nxgrid1))
   998      allocate(i2_side1(nxgrid1), j2_side1(nxgrid1))
   999      allocate(area_side1(nxgrid1))
  1000      if(use_higher_order) 
then  1001         if(nxgrid_local>0) 
deallocate(di,dj)
  1002         allocate(di(nxgrid2), dj(nxgrid2))
  1003         allocate(di_side1(nxgrid1), dj_side1(nxgrid1))
  1005      if(scale_exist) 
then  1006         if(nxgrid_local>0)
deallocate(scale)
  1007         allocate(scale(nxgrid2))
  1014            i1(l2) = recv_buffer(pos+1)
  1015            j1(l2) = recv_buffer(pos+2)
  1016            i2(l2) = recv_buffer(pos+3)
  1017            j2(l2) = recv_buffer(pos+4)
  1018            area(l2) = recv_buffer(pos+5)
  1019            if(use_higher_order) 
then  1020               di(l2) = recv_buffer(pos+6)
  1021               dj(l2) = recv_buffer(pos+7)
  1023            if(scale_exist)scale(l2) = recv_buffer(pos+nset2)
  1028            i1_side1(l1) = recv_buffer(pos+1)
  1029            j1_side1(l1) = recv_buffer(pos+2)
  1030            i2_side1(l1) = recv_buffer(pos+3)
  1031            j2_side1(l1) = recv_buffer(pos+4)
  1032            area_side1(l1) = recv_buffer(pos+5)
  1033            if(use_higher_order) 
then  1034               di_side1(l1) = recv_buffer(pos+6)
  1035               dj_side1(l1) = recv_buffer(pos+7)
  1040      call mpp_sync_self()
  1041      if(
allocated(send_buffer)) 
deallocate(send_buffer)
  1042      if(
allocated(recv_buffer)) 
deallocate(recv_buffer)
  1047      i1_side1 => i1; j1_side1 => j1
  1048      i2_side1 => i2; j2_side1 => j2
  1050      if(use_higher_order) 
then  1059   size_prev = grid%size
  1061   if(grid%tile_me == tile2) 
then  1063         if (
in_box_me(i2(l), j2(l), grid) ) 
then  1064            grid%size = grid%size + 1
  1066            if( grid1_id .NE. 
"ATM" .OR. tile1 .NE. 
tile_parent .OR.  &
  1069                  lll = grid%l_index((j2(l)-1)*grid%im+i2(l))
  1070                  grid%area(lll,1) = grid%area(lll,1)+area(l)
  1072                  grid%area(i2(l),j2(l)) = grid%area(i2(l),j2(l))+area(l)
  1076               if(grid1%tile(p) == tile1) 
then  1078                     xmap%your1my2(p) = .true.
  1086   if(grid%size > size_prev) 
then  1087      if(size_prev > 0) 
then   1088         allocate(x_local(size_prev))
  1090         if(
ASSOCIATED(grid%x)) 
deallocate(grid%x)
  1091         allocate( grid%x( grid%size ) )
  1092         grid%x(1:size_prev) = x_local
  1095         allocate( grid%x( grid%size ) )
  1096         grid%x%di = 0.0; grid%x%dj = 0.0
  1101   if( grid%tile_me == tile2 ) 
then   1106            grid%x(ll)%i1   = i1(l); grid%x(ll)%i2   = i2(l)
  1107            grid%x(ll)%j1   = j1(l); grid%x(ll)%j2   = j2(l)
  1109               grid%x(ll)%l2   = grid%l_index((j2(l)-1)*grid%im + i2(l))
  1114            grid%x(ll)%tile = tile1
  1115            grid%x(ll)%area = area(l)
  1116            if(scale_exist) 
then  1117               grid%x(ll)%scale = scale(l)
  1119               grid%x(ll)%scale = 1.0
  1121            if(use_higher_order) 
then  1122               grid%x(ll)%di  = di(l)
  1123               grid%x(ll)%dj  = dj(l)
  1128                  if(grid1%tile(p) == tile1) 
then  1130                        grid%x(ll)%pe = p + xmap%root_pe
  1139   if(grid%id == xmap%grids(
size(xmap%grids(:)))%id) 
then  1146   if(grid1%tile_me == tile1) 
then  1147      if(
associated(iarray)) 
then  1148         nxgrid1_old = 
size(iarray(:))
  1153      allocate(y2m1_pe(nxgrid1))
  1154      if(.not. last_grid ) 
allocate(pos_s(0:xmap%npes-1))
  1156      if(nxgrid1_old > 0) 
then  1158            y2m1_size(p) = xmap%your2my1_size(p)
  1165         if (
in_box_me(i1_side1(l), j1_side1(l), grid1) ) 
then  1166            if(grid1%is_ug) 
then  1167               lll = grid1%l_index((j1_side1(l)-1)*grid1%im+i1_side1(l))
  1168               grid1%area(lll,1) = grid1%area(lll,1) + area_side1(l)
  1170               grid1%area(i1_side1(l),j1_side1(l)) = grid1%area(i1_side1(l),j1_side1(l))+area_side1(l)
  1173               if (grid%tile(p) == tile2) 
then  1174                  if (
in_box_nbr(i2_side1(l), j2_side1(l), grid, p))  
then  1175                     xmap%your2my1(p) = .true.
  1177                     y2m1_size(p) = y2m1_size(p) + 1
  1181            size_repro = size_repro + 1
  1186         pos_x(p) = pos_x(p-1) + y2m1_size(p-1)
  1189      if(.not. last_grid) pos_s(:) = pos_x(:)
  1191      if(nxgrid1_old > 0) 
then  1192         y2m1_size(:) = xmap%your2my1_size(:)
  1195         allocate(iarray(nxgrid1+nxgrid1_old), jarray(nxgrid1+nxgrid1_old))
  1198            do n = 1, xmap%your2my1_size(p)
  1199               iarray(pos_x(p)+n) = iarray2(pos_s(p)+n)
  1200               jarray(pos_x(p)+n) = jarray2(pos_s(p)+n)
  1203         deallocate(iarray2, jarray2)        
  1205         allocate(iarray(nxgrid1), jarray(nxgrid1))
  1215         if(y2m1_size(p) > 0) 
then  1216            pos = pos_x(p)+y2m1_size(p)
  1217            if( i1_side1(l) == iarray(pos) .AND. j1_side1(l) == jarray(pos) ) 
then  1221               do n = 1, y2m1_size(p)
  1223                  if(i1_side1(l) == iarray(pos) .AND. j1_side1(l) == jarray(pos)) 
then  1231            y2m1_size(p) = y2m1_size(p)+1
  1232            pos = pos_x(p)+y2m1_size(p)
  1233            iarray(pos) = i1_side1(l)
  1234            jarray(pos) = j1_side1(l)
  1237      xmap%your2my1_size(:) =  y2m1_size(:)
  1240         deallocate(iarray, jarray)
  1241         if(
allocated(pos_s)) 
deallocate(pos_s)
  1245   if (grid1%tile_me == tile1 .and. size_repro > 0) 
then  1246      ll_repro = grid%size_repro
  1247      grid%size_repro = ll_repro + size_repro
  1248      if(ll_repro > 0) 
then    1249         allocate(x_local(ll_repro))
  1250         x_local = grid%x_repro
  1251         if(
ASSOCIATED(grid%x_repro)) 
deallocate(grid%x_repro)
  1252         allocate( grid%x_repro(grid%size_repro ) )
  1253         grid%x_repro(1:ll_repro) = x_local
  1256         allocate( grid%x_repro( grid%size_repro ) )
  1257         grid%x_repro%di = 0.0; grid%x_repro%dj = 0.0
  1260         if (
in_box_me(i1_side1(l),j1_side1(l), grid1) ) 
then  1261            ll_repro = ll_repro + 1
  1262            grid%x_repro(ll_repro)%i1   = i1_side1(l); grid%x_repro(ll_repro)%i2   = i2_side1(l)
  1263            grid%x_repro(ll_repro)%j1   = j1_side1(l); grid%x_repro(ll_repro)%j2   = j2_side1(l)
  1264            if(grid1%is_ug) 
then  1265               grid%x_repro(ll_repro)%l1 = grid1%l_index((j1_side1(l)-1)*grid1%im+i1_side1(l))
  1270            grid%x_repro(ll_repro)%tile = tile1
  1271            grid%x_repro(ll_repro)%area = area_side1(l)
  1272            if(use_higher_order) 
then  1273               grid%x_repro(ll_repro)%di  = di_side1(l)
  1274               grid%x_repro(ll_repro)%dj  = dj_side1(l)
  1278               if(grid%tile(p) == tile2) 
then  1279                  if (
in_box_nbr(i2_side1(l), j2_side1(l), grid, p)) 
then  1280                     grid%x_repro(ll_repro)%pe = p + xmap%root_pe
  1288   deallocate(i1, j1, i2, j2, area)
  1289   if(use_higher_order) 
deallocate(di, dj)
  1290   if(scale_exist) 
deallocate(scale)
  1291   if(is_distribute) 
then  1292      deallocate(i1_side1, j1_side1, i2_side1, j2_side1, area_side1)
  1293      if(use_higher_order) 
deallocate(di_side1, dj_side1)
  1296   i1=>null(); j1=>null(); i2=>null(); j2=>null()
  1311 subroutine get_grid(grid, grid_id, grid_file, grid_version)
  1312   type(grid_type), 
intent(inout) :: grid
  1313   character(len=3), 
intent(in)   :: grid_id
  1314   character(len=*), 
intent(in)   :: grid_file
  1315   integer,          
intent(in)   :: grid_version
  1317   real, 
dimension(grid%im) :: lonb
  1318   real, 
dimension(grid%jm) :: latb
  1319   real, 
allocatable        :: tmpx(:,:), tmpy(:,:)
  1321   integer                  :: is, ie, js, je, nlon, nlat, siz(4), i, j
  1322   integer                  :: start(4), nread(4), isc2, iec2, jsc2, jec2
  1328   select case(grid_version)
  1330      allocate(grid%lon(grid%im), grid%lat(grid%jm))
  1331      if(grid_id == 
'ATM') 
then  1343      else if(grid_id == 
'LND') 
then  1354      else if(grid_id == 
'OCN' ) 
then  1361      if(grid_id == 
'LND' .or. grid_id == 
'ATM') 
then  1362         grid%lon   = lonb * d2r
  1363         grid%lat   = latb * d2r
  1365      grid%is_latlon = .true.
  1367      call field_size(grid_file, 
'area', siz)
  1368      nlon = siz(1); nlat = siz(2)
  1369      if( mod(nlon,2) .NE. 0) 
call error_mesg(
'xgrid_mod',  &
  1370           'flux_exchange_mod: atmos supergrid longitude size can not be divided by 2', fatal)
  1371      if( mod(nlat,2) .NE. 0) 
call error_mesg(
'xgrid_mod',  &
  1372           'flux_exchange_mod: atmos supergrid latitude size can not be divided by 2', fatal)
  1375      if(nlon .NE. grid%im .OR. nlat .NE. grid%jm) 
call error_mesg(
'xgrid_mod', &
  1376          'grid size in tile_file does not match the global grid size', fatal)
  1378      if( grid_id == 
'LND' .or. grid_id == 
'ATM'  .or. grid_id == 
'WAV' ) 
then  1379         isc2 = 2*grid%is_me-1; iec2 = 2*grid%ie_me+1
  1380         jsc2 = 2*grid%js_me-1; jec2 = 2*grid%je_me+1
  1381         allocate(tmpx(isc2:iec2, jsc2:jec2) )
  1382         allocate(tmpy(isc2:iec2, jsc2:jec2) )   
  1383         start = 1; nread = 1          
  1384         start(1) = isc2; nread(1) = iec2 - isc2 + 1
  1385         start(2) = jsc2; nread(2) = jec2 - jsc2 + 1 
  1386         call read_data(grid_file, 
'x', tmpx, start, nread, no_domain=.true.)
  1387         call read_data(grid_file, 
'y', tmpy, start, nread, no_domain=.true.)      
  1389            deallocate(tmpx, tmpy)
  1390            start = 1; nread = 1
  1391            start(2) = 2; nread(1) = nlon*2+1
  1392            allocate(tmpx(nlon*2+1, 1), tmpy(1, nlat*2+1))
  1393            call read_data(grid_file, 
"x", tmpx, start, nread, no_domain=.true.)    
  1394            allocate(grid%lon(grid%im), grid%lat(grid%jm))
  1396               grid%lon(i) = tmpx(2*i,1) * d2r
  1398            start = 1; nread = 1
  1399            start(1) = 2; nread(2) = nlat*2+1
  1400            call read_data(grid_file, 
"y", tmpy, start, nread, no_domain=.true.)    
  1402               grid%lat(j) = tmpy(1, 2*j) * d2r
  1404            grid%is_latlon = .true.
  1406            allocate(grid%geolon(grid%isd_me:grid%ied_me, grid%jsd_me:grid%jed_me))
  1407            allocate(grid%geolat(grid%isd_me:grid%ied_me, grid%jsd_me:grid%jed_me))
  1411            do j = grid%js_me,grid%je_me
  1412               do i = grid%is_me,grid%ie_me
  1413                  grid%geolon(i, j) = tmpx(i*2,j*2)*d2r
  1414                  grid%geolat(i, j) = tmpy(i*2,j*2)*d2r
  1419            grid%is_latlon = .false.
  1421         deallocate(tmpx, tmpy)
  1432   character(len=*), 
intent(in) :: file
  1433   character(len=*), 
intent(in) :: name
  1434   type(domain2d),   
intent(in) :: domain
  1435   real, 
intent(out)            :: data(:,:)
  1438      call read_data(file, name, 
data, domain)
  1440      call error_mesg(
'xgrid_mod', 
'no field named '//trim(name)//
' in grid file '//trim(file)// &
  1441                      ' Will set data to negative values...', note)
  1469   type(
domain2d), 
intent(in) :: domain
  1470   character(len=*), 
intent(in) :: grid_file
  1471   integer :: is, ie, js, je
  1479   if(ie < is .or. je < js ) 
return  1513 subroutine setup_xmap(xmap, grid_ids, grid_domains, grid_file, atm_grid, lnd_ug_domain)
  1515   character(len=3), 
dimension(:),            
intent(in ) :: grid_ids
  1516   type(
domain2d), 
dimension(:),              
intent(in ) :: grid_domains
  1517   character(len=*),                          
intent(in ) :: grid_file
  1519   type(
domainug), 
optional,                  
intent(in ) :: lnd_ug_domain
  1521   integer :: 
g,     p, send_size, recv_size, i, siz(4)
  1522   integer :: unit, nxgrid_file, i1, i2, i3, tile1, tile2, j
  1523   integer :: nxc, nyc, out_unit
  1524   type(
grid_type), 
pointer, 
save :: grid =>null(), grid1 =>null()
  1525   real, 
dimension(3) :: xxx
  1526   real, 
dimension(:,:), 
allocatable   :: check_data
  1527   real, 
dimension(:,:,:), 
allocatable :: check_data_3d
  1528   real,                 
allocatable   :: tmp_2d(:,:), tmp_3d(:,:,:)
  1529   character(len=256)                  :: xgrid_file, xgrid_name
  1530   character(len=256)                  :: tile_file, mosaic_file
  1531   character(len=256)                  :: mosaic1, mosaic2, contact
  1532   character(len=256)                  :: tile1_name, tile2_name
  1533   character(len=256),     
allocatable :: tile1_list(:), tile2_list(:)
  1534   integer                             :: npes, npes2
  1535   integer,                
allocatable :: pelist(:)
  1537   logical :: use_higher_order = .false.
  1538   integer :: lnd_ug_id, l
  1539   integer, 
allocatable :: grid_index(:)
  1543   if(
interp_method .ne. 
'first_order')  use_higher_order = .true.
  1547   xmap%npes = mpp_npes()
  1548   xmap%root_pe = mpp_root_pe()
  1550   allocate( xmap%grids(1:
size(grid_ids(:))) )
  1552   allocate ( xmap%your1my2(0:xmap%npes-1), xmap%your2my1(0:xmap%npes-1) )
  1553   allocate ( xmap%your2my1_size(0:xmap%npes-1) )
  1555   xmap%your1my2 = .false.; xmap%your2my1 = .false.;
  1556   xmap%your2my1_size = 0
  1561   else if(
field_exist(grid_file, 
"ocn_mosaic_file" ) ) 
then  1564      call error_mesg(
'xgrid_mod', 
'both AREA_ATMxOCN and ocn_mosaic_file does not exist in '//trim(grid_file), fatal)
  1568      call error_mesg(
'xgrid_mod', 
'reading exchange grid information from grid spec file', note)
  1570      call error_mesg(
'xgrid_mod', 
'reading exchange grid information from mosaic grid file', note)
  1575   if(
present(lnd_ug_domain)) 
then  1576      do g=1,
size(grid_ids(:))
  1577         if(grid_ids(
g) == 
'LND') lnd_ug_id = 
g  1582   do g=1,
size(grid_ids(:))
  1583      grid => xmap%grids(
g)
  1584      if (
g==1) grid1 => xmap%grids(
g)
  1585      grid%id     = grid_ids(
g)
  1586      grid%domain = grid_domains(
g)
  1587      grid%on_this_pe = mpp_domain_is_initialized(grid_domains(
g))
  1588      allocate ( grid%is(0:xmap%npes-1), grid%ie(0:xmap%npes-1) )
  1589      allocate ( grid%js(0:xmap%npes-1), grid%je(0:xmap%npes-1) )
  1590      allocate ( grid%tile(0:xmap%npes-1) )
  1600      select case(xmap%version)
  1604         call read_data(grid_file, lowercase(grid_ids(
g))//
'_mosaic_file', mosaic_file)
  1608      if( 
g == 1 .AND. grid_ids(1) == 
'ATM' ) 
then   1609         if( .NOT. grid%on_this_pe ) 
call error_mesg(
'xgrid_mod', 
'ATM domain is not defined on some processor' ,fatal)
  1611      grid%npes =  mpp_get_domain_npes(grid%domain)
  1612      if( xmap%npes > grid%npes .AND. 
g == 1 .AND. grid_ids(1) == 
'ATM' ) 
then  1614      else if(xmap%npes > grid%npes) 
then  1616         grid%npes =  mpp_get_domain_npes(grid%domain)
  1620      allocate(grid%pelist(0:npes-1))
  1621      call mpp_get_domain_pelist(grid%domain, grid%pelist)
  1622      grid%root_pe = mpp_get_domain_root_pe(grid%domain)
  1624      call mpp_get_data_domain(grid%domain, grid%isd_me, grid%ied_me, grid%jsd_me, grid%jed_me, &
  1625                               xsize=grid%nxd_me, ysize=grid%nyd_me)
  1628      if( grid%root_pe == xmap%root_pe ) 
then  1630                                      ybegin=grid%js(0:npes-1), yend=grid%je(0:npes-1) )
  1631         call mpp_get_tile_list(grid%domain, grid%tile(0:npes-1))
  1632         if( xmap%npes > npes .AND. 
g == 1 .AND. grid_ids(1) == 
'ATM' ) 
then  1634                                         ybegin=grid%js(npes:xmap%npes-1), yend=grid%je(npes:xmap%npes-1) )
  1635            call mpp_get_tile_list(domain2, grid%tile(npes:xmap%npes-1))
  1638         npes2 = xmap%npes-npes
  1640                                      ybegin=grid%js(0:npes2-1), yend=grid%je(0:npes2-1) )
  1641         call mpp_get_compute_domains(grid%domain, xbegin=grid%is(npes2:xmap%npes-1), xend=grid%ie(npes2:xmap%npes-1), &
  1642                                      ybegin=grid%js(npes2:xmap%npes-1), yend=grid%je(npes2:xmap%npes-1) )
  1643         call mpp_get_tile_list(domain2, grid%tile(0:npes2-1))
  1644         call mpp_get_tile_list(grid%domain, grid%tile(npes2:xmap%npes-1))
  1646      if( xmap%npes > grid%npes .AND. 
g == 1 .AND. grid_ids(1) == 
'ATM' ) 
then  1650      if(  
g == 1 .AND. grid_ids(1) == 
'ATM' ) npes = xmap%npes
  1652         if(grid%tile(p) > grid%ntile .or. grid%tile(p) < 1) 
call error_mesg(
'xgrid_mod', &
  1653                  'tile id should between 1 and ntile', fatal)
  1661      grid%is_me => grid%is(xmap%me-xmap%root_pe); grid%ie_me => grid%ie(xmap%me-xmap%root_pe)
  1662      grid%js_me => grid%js(xmap%me-xmap%root_pe); grid%je_me => grid%je(xmap%me-xmap%root_pe)
  1663      grid%nxc_me = grid%ie_me - grid%is_me + 1
  1664      grid%nyc_me = grid%je_me - grid%js_me + 1
  1665      grid%tile_me => grid%tile(xmap%me-xmap%root_pe)
  1668      grid%is_ug = .false.
  1670      if( 
g == lnd_ug_id ) 
then  1672                                      'does not support unstructured grid for VERSION1 grid' ,fatal)
  1674         grid%ug_domain = lnd_ug_domain
  1675         allocate ( grid%ls(0:xmap%npes-1), grid%le(0:xmap%npes-1) )
  1676         allocate ( grid%gs(0:xmap%npes-1), grid%ge(0:xmap%npes-1) )
  1681         if(xmap%npes > grid%npes) 
then  1684         call mpp_get_ug_compute_domains(grid%ug_domain,  begin=grid%ls(0:npes-1), end=grid%le(0:npes-1) )
  1685         call mpp_get_ug_domains_index(grid%ug_domain,  grid%gs(0:npes-1), grid%ge(0:npes-1) )
  1686         call mpp_get_ug_domain_tile_list(grid%ug_domain, grid%tile(0:npes-1))
  1687         grid%ls_me => grid%ls(xmap%me-xmap%root_pe); grid%le_me => grid%le(xmap%me-xmap%root_pe)
  1688         grid%gs_me => grid%gs(xmap%me-xmap%root_pe); grid%ge_me => grid%ge(xmap%me-xmap%root_pe)
  1689         grid%tile_me => grid%tile(xmap%me-xmap%root_pe)
  1690         grid%nxl_me = grid%le_me - grid%ls_me + 1
  1691         allocate(grid%l_index(grid%gs_me:grid%ge_me))
  1692         allocate(grid_index(grid%ls_me:grid%le_me))
  1693         call mpp_get_ug_domain_grid_index(grid%ug_domain, grid_index)
  1696         do l = grid%ls_me,grid%le_me
  1697            grid%l_index(grid_index(l)) = l
  1700         if( grid%on_this_pe ) 
then  1701            allocate( grid%area    (grid%ls_me:grid%le_me,1) )
  1702            allocate( grid%area_inv(grid%ls_me:grid%le_me,1) )
  1707      else if( grid%on_this_pe ) 
then  1708         allocate( grid%area    (grid%is_me:grid%ie_me, grid%js_me:grid%je_me) )
  1709         allocate( grid%area_inv(grid%is_me:grid%ie_me, grid%js_me:grid%je_me) )
  1716      if(.not. grid%is_ug) 
then  1717         select case(xmap%version)
  1719            if( grid%npes .NE. xmap%npes ) 
then  1720               call error_mesg(
'xgrid_mod', .NE.
' grid%npes  xmap%npes ', fatal)
  1722            call get_grid(grid, grid_ids(
g), grid_file, xmap%version)
  1724            allocate(pelist(0:xmap%npes-1))
  1725            call mpp_get_current_pelist(pelist)
  1726            if( grid%on_this_pe ) 
then  1727               call mpp_set_current_pelist(grid%pelist)
  1728               call get_mosaic_tile_grid(tile_file, 
'INPUT/'//trim(mosaic_file), grid%domain)
  1729               call get_grid(grid, grid_ids(
g), tile_file, xmap%version)
  1731            call mpp_set_current_pelist(pelist)
  1734            if( 
g == 1 .AND. grid_ids(1) == 
'ATM' ) 
then  1740         if( use_higher_order .AND. grid%id == 
'ATM') 
then  1741            if( 
nnest > 0 ) 
call error_mesg(
'xgrid_mod', 
'second_order is not supported for nested coupler', fatal)
  1742            if( grid%is_latlon ) 
then  1743               call mpp_modify_domain(grid%domain, grid%domain_with_halo, whalo=1, ehalo=1, shalo=1, nhalo=1)
  1744               call mpp_get_data_domain(grid%domain_with_halo, grid%isd_me, grid%ied_me, grid%jsd_me, grid%jed_me, &
  1745                    xsize=grid%nxd_me, ysize=grid%nyd_me) 
  1747               if(.NOT. 
present(atm_grid)) 
call error_mesg(
'xgrid_mod', &
  1748                                           'when first grid is "ATM", atm_grid should be present', fatal)
  1749               if(grid%is_me-grid%isd_me .NE. 1 .or. grid%ied_me-grid%ie_me .NE. 1 .or.               &
  1750                    grid%js_me-grid%jsd_me .NE. 1 .or. grid%jed_me-grid%je_me .NE. 1 ) 
call error_mesg( &
  1751                    'xgrid_mod', 
'for non-latlon grid (cubic grid), the halo size should be 1 in all four direction', fatal)
  1752               if(.NOT.( 
ASSOCIATED(atm_grid%dx) .AND. 
ASSOCIATED(atm_grid%dy) .AND. 
ASSOCIATED(atm_grid%edge_w) .AND.    &
  1753                    ASSOCIATED(atm_grid%edge_e) .AND. 
ASSOCIATED(atm_grid%edge_s) .AND. 
ASSOCIATED(atm_grid%edge_n) .AND. &
  1754                    ASSOCIATED(atm_grid%en1) .AND. 
ASSOCIATED(atm_grid%en2) .AND. 
ASSOCIATED(atm_grid%vlon) .AND.         &
  1755                    ASSOCIATED(atm_grid%vlat) ) )  
call error_mesg( 
'xgrid_mod', &
  1756                    'for non-latlon grid (cubic grid), all the fields in atm_grid data type should be allocated', fatal)
  1757               nxc = grid%ie_me  - grid%is_me  + 1
  1758               nyc = grid%je_me  - grid%js_me  + 1
  1759               if(
size(atm_grid%dx,1) .NE. nxc .OR. 
size(atm_grid%dx,2) .NE. nyc+1)               &
  1760                    call error_mesg(
'xgrid_mod', 
'incorrect dimension size of atm_grid%dx', fatal)
  1761               if(
size(atm_grid%dy,1) .NE. nxc+1 .OR. 
size(atm_grid%dy,2) .NE. nyc)               &
  1762                    call error_mesg(
'xgrid_mod', 
'incorrect dimension sizeof atm_grid%dy', fatal)
  1763               if(
size(atm_grid%area,1) .NE. nxc .OR. 
size(atm_grid%area,2) .NE. nyc)             &
  1764                    call error_mesg(
'xgrid_mod', 
'incorrect dimension size of atm_grid%area', fatal)
  1765               if(
size(atm_grid%edge_w(:)) .NE. nyc+1 .OR. 
size(atm_grid%edge_e(:)) .NE. nyc+1)    &
  1766                    call error_mesg(
'xgrid_mod', 
'incorrect dimension size of atm_grid%edge_w/edge_e', fatal)
  1767               if(
size(atm_grid%edge_s(:)) .NE. nxc+1 .OR. 
size(atm_grid%edge_n(:)) .NE. nxc+1)    &
  1768                    call error_mesg(
'xgrid_mod', 
'incorrect dimension size of atm_grid%edge_s/edge_n', fatal)
  1769               if(
size(atm_grid%en1,1) .NE. 3 .OR. 
size(atm_grid%en1,2) .NE. nxc .OR. 
size(atm_grid%en1,3) .NE. nyc+1) & 
  1770                    call error_mesg( 
'xgrid_mod', 
'incorrect dimension size of atm_grid%en1', fatal)
  1771               if(
size(atm_grid%en2,1) .NE. 3 .OR. 
size(atm_grid%en2,2) .NE. nxc+1 .OR. 
size(atm_grid%en2,3) .NE. nyc) &
  1772                    call error_mesg( 
'xgrid_mod', 
'incorrect dimension size of atm_grid%en2', fatal)
  1773               if(
size(atm_grid%vlon,1) .NE. 3 .OR. 
size(atm_grid%vlon,2) .NE. nxc .OR. 
size(atm_grid%vlon,3) .NE. nyc)   &
  1774                    call error_mesg(
'xgrid_mod', 
'incorrect dimension size of atm_grid%vlon', fatal)
  1775               if(
size(atm_grid%vlat,1) .NE. 3 .OR. 
size(atm_grid%vlat,2) .NE. nxc .OR. 
size(atm_grid%vlat,3) .NE. nyc)   &
  1776                    call error_mesg(
'xgrid_mod', 
'incorrect dimension size of atm_grid%vlat', fatal)
  1777               allocate(grid%box%dx    (grid%is_me:grid%ie_me,   grid%js_me:grid%je_me+1 ))
  1778               allocate(grid%box%dy    (grid%is_me:grid%ie_me+1, grid%js_me:grid%je_me   ))
  1779               allocate(grid%box%area  (grid%is_me:grid%ie_me,   grid%js_me:grid%je_me   ))
  1780               allocate(grid%box%edge_w(grid%js_me:grid%je_me+1))
  1781               allocate(grid%box%edge_e(grid%js_me:grid%je_me+1))
  1782               allocate(grid%box%edge_s(grid%is_me:grid%ie_me+1))
  1783               allocate(grid%box%edge_n(grid%is_me:grid%ie_me+1))
  1784               allocate(grid%box%en1   (3, grid%is_me:grid%ie_me,   grid%js_me:grid%je_me+1 ))
  1785               allocate(grid%box%en2   (3, grid%is_me:grid%ie_me+1, grid%js_me:grid%je_me   ))
  1786               allocate(grid%box%vlon  (3, grid%is_me:grid%ie_me,   grid%js_me:grid%je_me   ))
  1787               allocate(grid%box%vlat  (3, grid%is_me:grid%ie_me,   grid%js_me:grid%je_me   ))
  1788               grid%box%dx     = atm_grid%dx
  1789               grid%box%dy     = atm_grid%dy
  1790               grid%box%area   = atm_grid%area
  1791               grid%box%edge_w = atm_grid%edge_w
  1792               grid%box%edge_e = atm_grid%edge_e
  1793               grid%box%edge_s = atm_grid%edge_s
  1794               grid%box%edge_n = atm_grid%edge_n
  1795               grid%box%en1    = atm_grid%en1
  1796               grid%box%en2    = atm_grid%en2
  1797               grid%box%vlon   = atm_grid%vlon
  1798               grid%box%vlat   = atm_grid%vlat
  1804         if(grid%on_this_pe) 
then  1806               allocate( grid%frac_area(grid%ls_me:grid%le_me, 1, grid%km) )
  1808               allocate( grid%frac_area(grid%is_me:grid%ie_me, grid%js_me:grid%je_me, grid%km) )
  1810            grid%frac_area = 1.0
  1814         select case(xmap%version)
  1816            call load_xgrid (xmap, grid, grid_file, grid_ids(1), grid_ids(
g), 1, 1, use_higher_order)
  1818            select case(grid_ids(1))
  1826               call error_mesg(
'xgrid_mod', 
'grid_ids(1) should be ATM, LND or WAV', fatal)
  1828            select case(grid_ids(
g))
  1830               xgrid_name = trim(xgrid_name)//
'Xl_file'  1832               xgrid_name = trim(xgrid_name)//
'Xo_file'  1834               xgrid_name = trim(xgrid_name)//
'Xw_file'  1836               call error_mesg(
'xgrid_mod', 
'grid_ids(g) should be LND, OCN or WAV', fatal)
  1839            call read_data(grid_file, lowercase(grid_ids(1))//
'_mosaic_file', mosaic1) 
  1840            call read_data(grid_file, lowercase(grid_ids(
g))//
'_mosaic_file', mosaic2) 
  1841            mosaic1 = 
'INPUT/'//trim(mosaic1)
  1842            mosaic2 = 
'INPUT/'//trim(mosaic2)
  1843            allocate(tile1_list(grid1%ntile), tile2_list(grid%ntile) )
  1844            do j = 1, grid1%ntile
  1845               call read_data(mosaic1, 
'gridtiles', tile1_list(j), level=j)
  1847            do j = 1, grid%ntile
  1848               call read_data(mosaic2, 
'gridtiles', tile2_list(j), level=j)
  1851               call field_size(grid_file, xgrid_name, siz)
  1852               nxgrid_file = siz(2)
  1854               do i = 1, nxgrid_file
  1855                  call read_data(grid_file, xgrid_name, xgrid_file, level = i)
  1856                  xgrid_file = 
'INPUT/'//trim(xgrid_file) 
  1857                  if( .NOT. file_exist(xgrid_file) )
call error_mesg(
'xgrid_mod', &
  1858                       'file '//trim(xgrid_file)//
' does not exist, check your xgrid file.', fatal)
  1861                  call read_data(xgrid_file, 
"contact", contact)
  1862                  i1 = index(contact, 
":")
  1863                  i2 = index(contact, 
"::")
  1864                  i3 = index(contact, 
":", back=.true. )
  1865                  if(i1 == 0 .OR. i2 == 0) 
call error_mesg(
'xgrid_mod', &
  1866                       'field contact in file '//trim(xgrid_file)//
' should contains ":" and "::" ', fatal)
  1868                       'field contact in file '//trim(xgrid_file)//
' should contains two ":"', fatal)
  1869                  tile1_name = contact(i1+1:i2-1)
  1870                  tile2_name = contact(i3+1:len_trim(contact))
  1871                  tile1 = 0; tile2 = 0
  1872                  do j = 1, grid1%ntile
  1873                     if( tile1_name == tile1_list(j) ) 
then  1878                  do j = 1, grid%ntile
  1879                     if( tile2_name == tile2_list(j) ) 
then  1884                  if(tile1 == 0) 
call error_mesg(
'xgrid_mod', &
  1885                       trim(tile1_name)//
' is not a tile of mosaic '//trim(mosaic1), fatal)
  1886                  if(tile2 == 0) 
call error_mesg(
'xgrid_mod', &
  1887                       trim(tile2_name)//
' is not a tile of mosaic '//trim(mosaic2), fatal)
  1889                  call load_xgrid (xmap, grid, xgrid_file, grid_ids(1), grid_ids(
g), tile1, tile2, &
  1893            deallocate(tile1_list, tile2_list)
  1895         if(grid%on_this_pe) 
then  1896            grid%area_inv = 0.0;
  1897            where (grid%area>0.0) grid%area_inv = 1.0/grid%area
  1904   grid1%area_inv = 0.0;
  1905   where (grid1%area>0.0)
  1906      grid1%area_inv = 1.0/grid1%area
  1909   xmap%your1my2(xmap%me-xmap%root_pe) = .false. 
  1910   xmap%your2my1(xmap%me-xmap%root_pe) = .false. 
  1913      allocate( xmap%send_count_repro(0:xmap%npes-1) )
  1914      allocate( xmap%recv_count_repro(0:xmap%npes-1) )
  1915      xmap%send_count_repro = 0
  1916      xmap%recv_count_repro = 0
  1917      do g=2,
size(xmap%grids(:))
  1919            if(xmap%grids(
g)%size >0) &
  1920                 xmap%send_count_repro(p) = xmap%send_count_repro(p) &
  1921                 +count(xmap%grids(
g)%x      (:)%pe==p+xmap%root_pe)
  1922            if(xmap%grids(
g)%size_repro >0) &
  1923                 xmap%recv_count_repro(p) = xmap%recv_count_repro(p) &
  1924                 +count(xmap%grids(
g)%x_repro(:)%pe==p+xmap%root_pe)
  1927      xmap%send_count_repro_tot = sum(xmap%send_count_repro)
  1928      xmap%recv_count_repro_tot = sum(xmap%recv_count_repro)
  1930      xmap%send_count_repro_tot = 0
  1931      xmap%recv_count_repro_tot = 0
  1935     call mpp_open( unit, 
'xgrid.out', action=mpp_overwr, threading=mpp_multi, &
  1936          fileset=mpp_multi, nohdrs=.true. )  
  1938     write( unit,* )xmap%grids(:)%id, 
' GRID: PE ', xmap%me, 
' #XCELLS=', &
  1939        xmap%grids(2:
size(xmap%grids(:)))%size, 
' #COMM. PARTNERS=', &
  1940        count(xmap%your1my2), 
'/', count(xmap%your2my1), &
  1941        pack((/(p+xmap%root_pe,p=0,xmap%npes-1)/), xmap%your1my2),  &
  1942        '/', pack((/(p+xmap%root_pe,p=0,xmap%npes-1)/), xmap%your2my1)
  1943     call close_file (unit)
  1946   allocate( xmap%x1(1:sum(xmap%grids(2:
size(xmap%grids(:)))%size)) )
  1947   allocate( xmap%x2(1:sum(xmap%grids(2:
size(xmap%grids(:)))%size)) )
  1948   allocate( xmap%x1_put(1:sum(xmap%grids(2:
size(xmap%grids(:)))%size)) )
  1949   allocate( xmap%x2_get(1:sum(xmap%grids(2:
size(xmap%grids(:)))%size)) )
  1952   allocate(xmap%get1, xmap%put1)
  1960     allocate(xmap%get1_repro)
  1972   if(lnd_ug_id ==0) 
then  1975      allocate(tmp_2d(grid1%is_me:grid1%ie_me, grid1%js_me:grid1%je_me))
  1980   write(out_unit,* )
"Checked data is array of constant 1"  1981   write(out_unit,* )grid1%id,
'(',xmap%grids(:)%id,
')=', xxx 
  1983   if(lnd_ug_id == 0) 
then  1984      do g=2,
size(xmap%grids(:))
  1986         write( out_unit,* )xmap%grids(
g)%id,
'(',xmap%grids(:)%id,
')=', xxx
  1989      do g=2,
size(xmap%grids(:))
  1990         grid => xmap%grids(
g)       
  1991         allocate(tmp_3d(grid%is_me:grid%ie_me, grid%js_me:grid%je_me,grid%km))
  1994         write( out_unit,* )xmap%grids(
g)%id,
'(',xmap%grids(:)%id,
')=', xxx
  1999   if(grid1%id == 
"ATM") 
then  2000      allocate(check_data(
size(grid1%area,1), 
size(grid1%area,2)))
  2001      call random_number(check_data)
  2004      if(lnd_ug_id ==0) 
then  2009      write( out_unit,* ) &
  2010           "Checked data is array of random number between 0 and 1 using "//trim(
interp_method)
  2011      write( out_unit,* )grid1%id,
'(',xmap%grids(:)%id,
')=', xxx 
  2013      deallocate(check_data)
  2014      do g=2,
size(xmap%grids(:))
  2015         allocate(check_data_3d(xmap%grids(
g)%is_me:xmap%grids(
g)%ie_me, &
  2016                  xmap%grids(
g)%js_me:xmap%grids(
g)%je_me, grid1%km))
  2017         call random_number(check_data_3d)
  2018         if(lnd_ug_id ==0) 
then  2023         write( out_unit,* )xmap%grids(
g)%id,
'(',xmap%grids(:)%id,
')=', xxx
  2024         deallocate( check_data_3d)
  2036 function get_nest_contact(mosaic_file, tile_nest_out, tile_parent_out, is_nest_out, &
  2037                           ie_nest_out, js_nest_out, je_nest_out, is_parent_out, &
  2038                           ie_parent_out, js_parent_out, je_parent_out)
  2039 character(len=*), 
intent(in) :: mosaic_file
  2040 integer,         
intent(out) :: tile_nest_out, tile_parent_out
  2041 integer,         
intent(out) :: is_nest_out, ie_nest_out
  2042 integer,         
intent(out) :: js_nest_out, je_nest_out
  2043 integer,         
intent(out) :: is_parent_out, ie_parent_out
  2044 integer,         
intent(out) :: js_parent_out, je_parent_out
  2047 integer                            :: ntiles, ncontacts, n, t1, t2
  2048 integer                            :: nx1_contact, ny1_contact
  2049 integer                            :: nx2_contact, ny2_contact
  2050 integer, 
allocatable, 
dimension(:) :: nx, ny
  2051 integer, 
allocatable, 
dimension(:) :: tile1, tile2
  2052 integer, 
allocatable, 
dimension(:) :: istart1, iend1, jstart1, jend1
  2053 integer, 
allocatable, 
dimension(:) :: istart2, iend2, jstart2, jend2
  2055   tile_nest_out = 0; tile_parent_out = 0
  2056   is_nest_out   = 0; ie_nest_out     = 0
  2057   js_nest_out   = 0; je_nest_out     = 0
  2058   is_parent_out = 0; ie_parent_out   = 0
  2059   js_parent_out = 0; je_parent_out   = 0
  2064   if( ntiles == 1 ) 
return  2065   allocate(nx(ntiles), ny(ntiles))  
  2069   if(ncontacts == 0) 
return  2070   allocate(tile1(ncontacts), tile2(ncontacts))
  2071   allocate(istart1(ncontacts), iend1(ncontacts))
  2072   allocate(jstart1(ncontacts), jend1(ncontacts))
  2073   allocate(istart2(ncontacts), iend2(ncontacts))
  2074   allocate(jstart2(ncontacts), jend2(ncontacts))
  2076   call get_mosaic_contact( mosaic_file, tile1, tile2, istart1, iend1, jstart1, jend1, &
  2077                            istart2, iend2, jstart2, jend2)
  2080     if( tile1(n) == tile2(n) ) cycle 
  2082     nx1_contact = iend1(n)-istart1(n)+1
  2083     ny1_contact = jend1(n)-jstart1(n)+1
  2084     nx2_contact = iend2(n)-istart2(n)+1
  2085     ny2_contact = jend2(n)-jstart2(n)+1
  2089     if( (nx(t1) .NE. nx1_contact .OR. ny(t1) .NE. ny1_contact ) .AND. &
  2090         (nx(t2) .NE. nx2_contact .OR. ny(t2) .NE. ny2_contact ) ) cycle
  2091     if(nx1_contact == nx2_contact .AND. ny1_contact == ny2_contact) 
then  2092       call error_mesg(
'xgrid_mod', 
'There is no refinement for the overlapping region', fatal)
  2097        call error_mesg(
'xgrid_mod', 
'only support one nest region, contact developer' ,fatal)
  2099     if(nx2_contact*ny2_contact > nx1_contact*ny1_contact) 
then  2100       is_nest_out     = istart2(n);
  2101       ie_nest_out     = iend2(n);
  2102       js_nest_out     = jstart2(n);
  2103       je_nest_out     = jend2(n);
  2104       tile_nest_out   = tile2(n);
  2105       is_parent_out   = istart1(n);
  2106       ie_parent_out   = iend1(n);
  2107       js_parent_out   = jstart1(n);
  2108       je_parent_out   = jend1(n);
  2109       tile_parent_out = tile1(n);
  2111       is_nest_out     = istart1(n);
  2112       ie_nest_out     = iend1(n);
  2113       js_nest_out     = jstart1(n);
  2114       je_nest_out     = jend1(n);
  2115       tile_nest_out   = tile1(n);
  2116       is_parent_out   = istart2(n);
  2117       ie_parent_out   = iend2(n);
  2118       js_parent_out   = jstart2(n);
  2119       je_parent_out   = jend2(n);
  2120       tile_parent_out = tile2(n);
  2124   deallocate(nx, ny, tile1, tile2)
  2125   deallocate(istart1, iend1, jstart1, jend1)
  2126   deallocate(istart2, iend2, jstart2, jend2)
  2136   integer, 
dimension(xmap%npes) :: pe_ind, cnt
  2137   integer, 
dimension(0:xmap%npes-1) :: send_ind, recv_ind, pl
  2138   integer :: npes, nsend, nrecv, mypos
  2139   integer :: m, p, pos, n, g, l, im, i, j
  2140   type(comm_type), 
pointer, 
save :: comm => null()
  2142   comm => xmap%get1_repro
  2146   mypos = mpp_pe() - mpp_root_pe()
  2148     p = mod(mypos+npes-m, npes)
  2149     if( xmap%recv_count_repro(p) > 0 ) 
then  2156   if( nrecv > 0 ) 
then  2157     allocate(comm%recv(nrecv))
  2161       comm%recv(n)%count = xmap%recv_count_repro(p)
  2162       comm%recv(n)%pe = p + xmap%root_pe
  2163       comm%recv(n)%buffer_pos = pos 
  2164       pos = pos + comm%recv(n)%count
  2171   mypos = mpp_pe() - mpp_root_pe()
  2173     p = mod(mypos+m, npes)
  2174     if( xmap%send_count_repro(p) > 0 ) 
then  2182   if( nsend > 0 ) 
then  2183      allocate(comm%send(nsend))
  2188         comm%send(n)%count = xmap%send_count_repro(p)
  2189         comm%send(n)%pe = p + xmap%root_pe 
  2190         comm%send(n)%buffer_pos = pos
  2191         pos = pos + comm%send(n)%count
  2192         allocate(comm%send(n)%i(comm%send(n)%count))
  2193         allocate(comm%send(n)%j(comm%send(n)%count))
  2194         allocate(comm%send(n)%g(comm%send(n)%count))
  2195         allocate(comm%send(n)%xLoc(comm%send(n)%count))
  2198      do g=2,
size(xmap%grids(:))
  2199         im = xmap%grids(g)%im
  2200         do l=1,xmap%grids(g)%size 
  2201            p = xmap%grids(g)%x(l)%pe-xmap%root_pe 
  2205            i = xmap%grids(g)%x(l)%i2
  2206            j = xmap%grids(g)%x(l)%j2
  2207            if(xmap%grids(g)%is_ug) 
then  2208               comm%send(n)%i(pos) = xmap%grids(g)%l_index((j-1)*im+i)
  2209               comm%send(n)%j(pos) = 1
  2211               comm%send(n)%i(pos) = xmap%grids(g)%x(l)%i2
  2212               comm%send(n)%j(pos) = xmap%grids(g)%x(l)%j2
  2214            comm%send(n)%g(pos) = g
  2219         if( comm%send(n)%count .NE. cnt(n) ) 
call error_mesg(
'xgrid_mod', &
  2220              .NE.
'comm%send(n)%count  cnt(n)', fatal)
  2226    do g=2,
size(xmap%grids(:))
  2227       do l=1,xmap%grids(g)%size_repro 
  2228          p = xmap%grids(g)%x_repro(l)%pe-xmap%root_pe
  2229          xmap%grids(g)%x_repro(l)%recv_pos = pl(p)
  2241   type(
grid_type), 
pointer, 
save :: grid1 =>null()
  2242   integer, 
allocatable :: send_size(:)
  2243   integer, 
allocatable :: recv_size(:)
  2244   integer              :: max_size, g, npes, l, ll, nset, m
  2245   integer              :: i1, j1, tile1, p, n, pos, buffer_pos, mypos
  2246   integer              :: nsend, nrecv, rbuf_size, sbuf_size, msgsize
  2248   real,    
allocatable :: recv_buf(:), send_buf(:)
  2249   real,    
allocatable :: diarray(:), djarray(:)
  2250   integer, 
allocatable :: iarray(:), jarray(:), tarray(:)
  2251   integer, 
allocatable :: pos_x(:), pelist(:), size_pe(:), pe_side1(:)
  2252   integer              :: recv_buffer_pos(0:xmap%npes)
  2253   integer              :: send_buffer_pos(0:xmap%npes)
  2254   type(comm_type), 
pointer, 
save :: comm => null()
  2258   do g=2,
size(xmap%grids(:))
  2259     max_size = max_size + xmap%grids(g)%size
  2262   grid1 => xmap%grids(1)
  2267   allocate(pelist(0:npes-1))
  2268   call mpp_get_current_pelist(pelist)
  2269   allocate(send_size(0:npes-1))
  2270   allocate(recv_size(0:npes-1))
  2271   allocate(size_pe(0:npes-1))
  2272   allocate(pos_x(0:npes-1))
  2277   if(max_size > 0) 
then  2278      allocate(pe_side1(max_size))
  2279      allocate(xmap%ind_get1(max_size))
  2283      do g=2,
size(xmap%grids(:))
  2284         do l=1,xmap%grids(g)%size
  2285            i1 = xmap%grids(g)%x(l)%i1
  2286            j1 = xmap%grids(g)%x(l)%j1
  2287            tile1 = xmap%grids(g)%x(l)%tile
  2289               if(grid1%tile(p) == tile1) 
then  2291                     size_pe(p) = size_pe(p) + 1     
  2296            if( p == npes ) 
then  2297               call error_mesg(
'xgrid_mod', 
'tile is not in grid1%tile(:)', fatal)
  2306         pos_x(p) = pos_x(p-1) + size_pe(p-1)
  2310      allocate(iarray(max_size))
  2311      allocate(jarray(max_size))
  2312      allocate(tarray(max_size))
  2314         allocate(diarray(max_size))
  2315         allocate(djarray(max_size))        
  2320      do g=2,
size(xmap%grids(:))
  2321         do l=1,xmap%grids(g)%size
  2322            i1 = xmap%grids(g)%x(l)%i1
  2323            j1 = xmap%grids(g)%x(l)%j1
  2324            tile1 = xmap%grids(g)%x(l)%tile
  2329            if(send_size(p) > 0) 
then  2330               if( i1 == iarray(pos_x(p)+send_size(p)) .AND. j1 == jarray(pos_x(p)+send_size(p)) &
  2331                    .AND. tile1 == tarray(pos_x(p)+send_size(p))) 
then  2336                  do n = 1, send_size(p)
  2337                     if(i1 == iarray(pos_x(p)+n) .AND. j1 == jarray(pos_x(p)+n) .AND. tile1 == tarray(pos_x(p)+n)) 
then  2345               send_size(p) = send_size(p)+1
  2346               pos = pos_x(p)+send_size(p)
  2351                  diarray(pos) = xmap%grids(g)%x(l)%di
  2352                  djarray(pos) = xmap%grids(g)%x(l)%dj
  2356            xmap%ind_get1(ll) = n
  2362         pos_x(p) = pos_x(p-1) + send_size(p-1)
  2366      do g=2,
size(xmap%grids(:))
  2367         do l=1,xmap%grids(g)%size
  2370            xmap%ind_get1(ll) = pos_x(p) + xmap%ind_get1(ll)
  2375   mypos = mpp_pe()-mpp_root_pe()
  2378   recv_size(:) = xmap%your2my1_size(:)
  2379   nsend = count( send_size> 0)  
  2382      allocate(comm%send(nsend))
  2383      comm%send(:)%count = 0
  2388      send_buffer_pos(p) = pos
  2389      pos = pos + send_size(p)
  2395      p = mod(mypos+n, npes)
  2396      if(send_size(p)>0) 
then  2398         allocate(comm%send(pos)%i(send_size(p)))
  2399         comm%send(pos)%buffer_pos = send_buffer_pos(p)
  2400         comm%send(pos)%count = send_size(p)
  2401         comm%send(pos)%pe = pelist(p)
  2402         comm%sendsize = comm%sendsize + send_size(p)
  2408   rbuf_size = sum(recv_size)*nset
  2409   sbuf_size = sum(send_size)*nset
  2410   if(rbuf_size>0) 
allocate(recv_buf(rbuf_size))
  2411   if(sbuf_size>0) 
allocate(send_buf(sbuf_size))
  2415      p = mod(mypos+npes-n, npes)
  2416      if(recv_size(p) ==0) cycle
  2417      msgsize = recv_size(p)*nset
  2418      call mpp_recv(recv_buf(pos+1), glen=msgsize, from_pe=pelist(p), block=.false., tag=comm_tag_4)
  2424      pos_x(p) = pos_x(p-1) + size_pe(p-1)
  2429      p = mod(mypos+n, npes)
  2430      do l = 1, send_size(p)
  2431         send_buf(pos+1) = iarray(pos_x(p)+l)
  2432         send_buf(pos+2) = jarray(pos_x(p)+l)
  2433         send_buf(pos+3) = tarray(pos_x(p)+l)
  2435            send_buf(pos+4) = diarray(pos_x(p)+l)
  2436            send_buf(pos+5) = djarray(pos_x(p)+l)
  2444      p = mod(mypos+n, npes)
  2445      if(send_size(p) ==0) cycle
  2446      msgsize = send_size(p)*nset
  2447      call mpp_send(send_buf(pos+1), plen=msgsize, to_pe=pelist(p), tag=comm_tag_4 )
  2451   call mpp_sync_self(
check=event_recv)
  2452   nrecv = count(recv_size>0)
  2457      allocate(comm%recv(nrecv))
  2458      comm%recv(:)%count = 0
  2462         recv_buffer_pos(p) = buffer_pos
  2463         buffer_pos = buffer_pos +  recv_size(p)
  2468         p = mod(mypos+npes-m, npes)
  2469         if(recv_size(p)>0) 
then  2471            allocate(comm%recv(pos)%i(recv_size(p)))
  2472            allocate(comm%recv(pos)%j(recv_size(p)))
  2473            allocate(comm%recv(pos)%tile(recv_size(p)))
  2474            comm%recv(pos)%buffer_pos = recv_buffer_pos(p)
  2475            comm%recv(pos)%pe = pelist(p)
  2476            comm%recv(pos)%count = recv_size(p)
  2477            comm%recvsize = comm%recvsize + recv_size(p)
  2479               allocate(comm%recv(pos)%di(recv_size(p)))
  2480               allocate(comm%recv(pos)%dj(recv_size(p)))
  2482            if(grid1%is_ug) 
then  2483               do n = 1, recv_size(p)
  2484                  i = recv_buf(buffer_pos+1)
  2485                  j = recv_buf(buffer_pos+2)
  2486                  comm%recv(pos)%i(n) = grid1%l_index((j-1)*grid1%im+i)
  2487                  comm%recv(pos)%j(n) = 1
  2488                  comm%recv(pos)%tile(n) = recv_buf(buffer_pos+3) 
  2490                     comm%recv(pos)%di(n) = recv_buf(buffer_pos+4) 
  2491                     comm%recv(pos)%dj(n) = recv_buf(buffer_pos+5) 
  2493                  buffer_pos = buffer_pos + nset
  2496               do n = 1, recv_size(p)
  2497                  comm%recv(pos)%i(n) = recv_buf(buffer_pos+1) - grid1%is_me + 1
  2498                  comm%recv(pos)%j(n) = recv_buf(buffer_pos+2) - grid1%js_me + 1
  2499                  comm%recv(pos)%tile(n) = recv_buf(buffer_pos+3) 
  2501                     comm%recv(pos)%di(n) = recv_buf(buffer_pos+4) 
  2502                     comm%recv(pos)%dj(n) = recv_buf(buffer_pos+5) 
  2504                  buffer_pos = buffer_pos + nset
  2509      allocate(comm%unpack_ind(nrecv))
  2512         if(recv_size(p)>0) 
then  2515               if(comm%recv(m)%pe == pelist(p)) 
then  2516                  comm%unpack_ind(pos) = m
  2523   call mpp_sync_self()
  2525   if(
allocated(send_buf) ) 
deallocate(send_buf)
  2526   if(
allocated(recv_buf) ) 
deallocate(recv_buf)
  2527   if(
allocated(pelist)   ) 
deallocate(pelist)
  2528   if(
allocated(pos_x)    ) 
deallocate(pos_x)
  2529   if(
allocated(pelist)   ) 
deallocate(pelist)
  2530   if(
allocated(iarray)   ) 
deallocate(iarray)
  2531   if(
allocated(jarray)   ) 
deallocate(jarray)
  2532   if(
allocated(tarray)   ) 
deallocate(tarray)
  2533   if(
allocated(size_pe)  ) 
deallocate(size_pe)
  2540   type(
grid_type), 
pointer, 
save :: grid1 =>null()
  2541   integer, 
allocatable :: send_size(:)
  2542   integer, 
allocatable :: recv_size(:)
  2543   integer              :: max_size, g, npes, l, ll, m, mypos
  2544   integer              :: i1, j1, tile1, p, n, pos, buffer_pos
  2545   integer              :: nsend, nrecv, msgsize, nset, rbuf_size, sbuf_size
  2547   real,    
allocatable :: recv_buf(:), send_buf(:)
  2548   real,    
allocatable :: diarray(:), djarray(:)
  2549   integer, 
allocatable :: iarray(:), jarray(:), tarray(:)
  2550   integer, 
allocatable :: pos_x(:), pelist(:), size_pe(:), pe_put1(:)
  2551   integer              :: root_pe, recvsize, sendsize
  2552   integer              :: recv_buffer_pos(0:xmap%npes)
  2553   type(comm_type), 
pointer, 
save :: comm => null()
  2557   if(
nnest == 0 .OR. xmap%grids(1)%id .NE. 
'ATM' ) 
then  2558      comm%nsend    = xmap%get1%nrecv
  2559      comm%nrecv    = xmap%get1%nsend   
  2560      comm%sendsize = xmap%get1%recvsize
  2561      comm%recvsize = xmap%get1%sendsize    
  2562      comm%send     => xmap%get1%recv
  2563      comm%recv     => xmap%get1%send
  2564      xmap%ind_put1 => xmap%ind_get1 
  2569   do g=2,
size(xmap%grids(:))
  2570      max_size = max_size + xmap%grids(g)%size
  2572   grid1 => xmap%grids(1)
  2576   allocate(pelist(0:npes-1))
  2577   call mpp_get_current_pelist(pelist)
  2578   allocate(send_size(0:npes-1))
  2579   allocate(recv_size(0:npes-1))
  2580   allocate(size_pe(0:npes-1))
  2581   allocate(pos_x(0:npes-1))
  2586   if(max_size > 0) 
then  2587      allocate(pe_put1(max_size))
  2588      allocate(xmap%ind_put1(max_size))
  2592      do g=2,
size(xmap%grids(:))
  2593         do l=1,xmap%grids(g)%size
  2594            i1 = xmap%grids(g)%x(l)%i1
  2595            j1 = xmap%grids(g)%x(l)%j1
  2596            tile1 = xmap%grids(g)%x(l)%tile
  2598               if(grid1%tile(p) == tile1) 
then  2599                  if(
in_box(i1, j1, grid1%is(p), grid1%ie(p), grid1%js(p), grid1%je(p))) 
then  2600                     size_pe(p) = size_pe(p) + 1     
  2612         pos_x(p) = pos_x(p-1) + size_pe(p-1)
  2616      allocate(iarray(max_size))
  2617      allocate(jarray(max_size))
  2618      allocate(tarray(max_size))
  2620         allocate(diarray(max_size))
  2621         allocate(djarray(max_size))        
  2626      do g=2,
size(xmap%grids(:))
  2627         do l=1,xmap%grids(g)%size
  2628            i1 = xmap%grids(g)%x(l)%i1
  2629            j1 = xmap%grids(g)%x(l)%j1
  2630            tile1 = xmap%grids(g)%x(l)%tile
  2635            if(send_size(p) > 0) 
then  2636               if( i1 == iarray(pos_x(p)+send_size(p)) .AND. j1 == jarray(pos_x(p)+send_size(p)) &
  2637                    .AND. tile1 == tarray(pos_x(p)+send_size(p))) 
then  2642                  do n = 1, send_size(p)
  2643                     if(i1 == iarray(pos_x(p)+n) .AND. j1 == jarray(pos_x(p)+n) .AND. tile1 == tarray(pos_x(p)+n)) 
then  2651               send_size(p) = send_size(p)+1
  2652               pos = pos_x(p)+send_size(p)
  2657                  diarray(pos) = xmap%grids(g)%x(l)%di
  2658                  djarray(pos) = xmap%grids(g)%x(l)%dj
  2662            xmap%ind_put1(ll) = n
  2668         pos_x(p) = pos_x(p-1) + send_size(p-1)
  2672      do g=2,
size(xmap%grids(:))
  2673         do l=1,xmap%grids(g)%size
  2674            i1 = xmap%grids(g)%x(l)%i1
  2675            j1 = xmap%grids(g)%x(l)%j1
  2676            tile1 = xmap%grids(g)%x(l)%tile
  2679            xmap%ind_put1(ll) = pos_x(p) + xmap%ind_put1(ll)
  2685   mypos = mpp_pe()-mpp_root_pe()
  2691         p = mod(mypos+npes-n, npes)
  2692         call mpp_recv(recv_size(p), glen=1, from_pe=pelist(p), block=.false., tag=comm_tag_5)
  2697         p = mod(mypos+n, npes)
  2698         call mpp_send(send_size(p), plen=1, to_pe=pelist(p), tag=comm_tag_5)
  2701      call mpp_sync_self(
check=event_recv)
  2702      call mpp_sync_self()
  2705   nrecv = count( send_size> 0)  
  2708      allocate(comm%recv(nrecv))
  2709      comm%recv(:)%count = 0
  2714      recv_buffer_pos(p) = pos
  2715      pos = pos + send_size(p)
  2720      p = mod(mypos+npes-n, npes)
  2721      if(send_size(p)>0) 
then  2723         allocate(comm%recv(pos)%i(send_size(p)))
  2724         comm%recv(pos)%buffer_pos = recv_buffer_pos(p)
  2725         comm%recv(pos)%count = send_size(p)
  2726         comm%recv(pos)%pe = pelist(p)
  2727         comm%recvsize = comm%recvsize + send_size(p)
  2733   rbuf_size = sum(recv_size)*nset
  2734   sbuf_size = sum(send_size)*nset
  2735   if(rbuf_size>0) 
allocate(recv_buf(rbuf_size))
  2736   if(sbuf_size>0) 
allocate(send_buf(sbuf_size))
  2740      p = mod(mypos+npes-n, npes)
  2741      if(recv_size(p) ==0) cycle
  2742      msgsize = recv_size(p)*nset
  2743      call mpp_recv(recv_buf(pos+1), glen=msgsize, from_pe=pelist(p), block=.false., tag=comm_tag_6)
  2749      pos_x(p) = pos_x(p-1) + size_pe(p-1)
  2754      p = mod(mypos+n, npes)
  2755      do l = 1, send_size(p)
  2756         send_buf(pos+1) = iarray(pos_x(p)+l)
  2757         send_buf(pos+2) = jarray(pos_x(p)+l)
  2758         send_buf(pos+3) = tarray(pos_x(p)+l)
  2760            send_buf(pos+4) = diarray(pos_x(p)+l)
  2761            send_buf(pos+5) = djarray(pos_x(p)+l)
  2769      p = mod(mypos+n, npes)
  2770      if(send_size(p) ==0) cycle
  2771      msgsize = send_size(p)*nset
  2772      call mpp_send(send_buf(pos+1), plen=msgsize, to_pe=pelist(p), tag=comm_tag_6 )
  2776   call mpp_sync_self(
check=event_recv)
  2777   nsend = count(recv_size>0)
  2782      allocate(comm%send(nsend))
  2783      comm%send(:)%count = 0
  2787         p = mod(mypos+npes-m, npes)
  2788         if(recv_size(p)>0) 
then  2790            allocate(comm%send(pos)%i(recv_size(p)))
  2791            allocate(comm%send(pos)%j(recv_size(p)))
  2792            allocate(comm%send(pos)%tile(recv_size(p)))
  2793            comm%send(pos)%pe = pelist(p)
  2794            comm%send(pos)%count = recv_size(p)
  2795            comm%sendsize = comm%sendsize + recv_size(p)
  2797               allocate(comm%send(pos)%di(recv_size(p)))
  2798               allocate(comm%send(pos)%dj(recv_size(p)))
  2800            do n = 1, recv_size(p)
  2801               comm%send(pos)%i(n) = recv_buf(buffer_pos+1) - grid1%is_me + 1
  2802               comm%send(pos)%j(n) = recv_buf(buffer_pos+2) - grid1%js_me + 1
  2803               comm%send(pos)%tile(n) = recv_buf(buffer_pos+3) 
  2805                  comm%send(pos)%di(n) = recv_buf(buffer_pos+4) 
  2806                  comm%send(pos)%dj(n) = recv_buf(buffer_pos+5) 
  2808               buffer_pos = buffer_pos + nset
  2814   call mpp_sync_self()
  2815   if(
allocated(send_buf) ) 
deallocate(send_buf)
  2816   if(
allocated(recv_buf) ) 
deallocate(recv_buf)
  2817   if(
allocated(pelist)   ) 
deallocate(pelist)
  2818   if(
allocated(pos_x)    ) 
deallocate(pos_x)
  2819   if(
allocated(pelist)   ) 
deallocate(pelist)
  2820   if(
allocated(iarray)   ) 
deallocate(iarray)
  2821   if(
allocated(jarray)   ) 
deallocate(jarray)
  2822   if(
allocated(tarray)   ) 
deallocate(tarray)
  2823   if(
allocated(size_pe)  ) 
deallocate(size_pe)
  2829 subroutine regen(xmap)
  2832   integer              :: g, l, k, max_size
  2833   integer              :: i1, j1, i2, j2, p
  2836   logical              :: overlap_with_nest
  2837   integer              :: cnt(xmap%get1%nsend)
  2838   integer              :: i,j,n,xloc,pos,nsend,m,npes, mypos
  2839   integer              :: send_ind(0:xmap%npes-1)
  2843   do g=2,
size(xmap%grids(:))
  2844     max_size = max_size + xmap%grids(g)%size * xmap%grids(g)%km
  2847   if (max_size>
size(xmap%x1(:))) 
then  2850     allocate( xmap%x1(1:max_size) )
  2851     allocate( xmap%x2(1:max_size) )
  2855   do g=2,
size(xmap%grids(:))
  2856     xmap%grids(g)%first = 1
  2857     xmap%grids(g)%last  = 0
  2862   do g=2,
size(xmap%grids(:))
  2863      xmap%grids(g)%first = xmap%size + 1;
  2865      do l=1,xmap%grids(g)%size
  2866         i1 = xmap%grids(g)%x(l)%i1
  2867         j1 = xmap%grids(g)%x(l)%j1
  2868         i2 = xmap%grids(g)%x(l)%i2
  2869         j2 = xmap%grids(g)%x(l)%j2
  2870         tile1 = xmap%grids(g)%x(l)%tile
  2872         if(xmap%grids(g)%is_ug) 
then  2873            do k=1,xmap%grids(g)%km
  2874               lll = xmap%grids(g)%l_index((j2-1)*xmap%grids(g)%im+i2)
  2875               if (xmap%grids(g)%frac_area(lll,1,k)/=0.0) 
then  2876               xmap%size = xmap%size+1
  2877               xmap%x1(xmap%size)%pos  = xmap%ind_get1(ll)
  2878               xmap%x1(xmap%size)%i    = xmap%grids(g)%x(l)%i1
  2879               xmap%x1(xmap%size)%j    = xmap%grids(g)%x(l)%j1
  2880               xmap%x1(xmap%size)%tile = xmap%grids(g)%x(l)%tile
  2881               xmap%x1(xmap%size)%area = xmap%grids(g)%x(l)%area &
  2882                    *xmap%grids(g)%frac_area(lll,1,k)
  2883               xmap%x1(xmap%size)%di   = xmap%grids(g)%x(l)%di
  2884               xmap%x1(xmap%size)%dj   = xmap%grids(g)%x(l)%dj
  2885               xmap%x2(xmap%size)%i    = xmap%grids(g)%x(l)%i2
  2886               xmap%x2(xmap%size)%j    = xmap%grids(g)%x(l)%j2
  2887               xmap%x2(xmap%size)%l    = lll
  2888               xmap%x2(xmap%size)%k    = k
  2889               xmap%x2(xmap%size)%area = xmap%grids(g)%x(l)%area * xmap%grids(g)%x(l)%scale
  2893            do k=1,xmap%grids(g)%km
  2894               if (xmap%grids(g)%frac_area(i2,j2,k)/=0.0) 
then  2895               xmap%size = xmap%size+1
  2896               xmap%x1(xmap%size)%pos  = xmap%ind_get1(ll)
  2897               xmap%x1(xmap%size)%i    = xmap%grids(g)%x(l)%i1
  2898               xmap%x1(xmap%size)%j    = xmap%grids(g)%x(l)%j1
  2899               xmap%x1(xmap%size)%tile = xmap%grids(g)%x(l)%tile
  2900               xmap%x1(xmap%size)%area = xmap%grids(g)%x(l)%area &
  2901                    *xmap%grids(g)%frac_area(i2,j2,k)
  2902               xmap%x1(xmap%size)%di   = xmap%grids(g)%x(l)%di 
  2903               xmap%x1(xmap%size)%dj   = xmap%grids(g)%x(l)%dj 
  2904               xmap%x2(xmap%size)%i    = xmap%grids(g)%x(l)%i2
  2905               xmap%x2(xmap%size)%j    = xmap%grids(g)%x(l)%j2
  2906               xmap%x2(xmap%size)%k    = k
  2907               xmap%x2(xmap%size)%area = xmap%grids(g)%x(l)%area * xmap%grids(g)%x(l)%scale 
  2912      xmap%grids(g)%last = xmap%size
  2916   if (max_size>
size(xmap%x1_put(:))) 
then  2917     deallocate(xmap%x1_put)
  2918     allocate( xmap%x1_put(1:max_size) )
  2920   if (max_size>
size(xmap%x2_get(:))) 
then  2921     deallocate(xmap%x2_get)
  2922     allocate( xmap%x2_get(1:max_size) )
  2925   do g=2,
size(xmap%grids(:))
  2926     xmap%grids(g)%first_get = 1
  2927     xmap%grids(g)%last_get  = 0
  2933   do g=2,
size(xmap%grids(:))
  2934      xmap%grids(g)%first_get = xmap%size_get2 + 1;
  2936      do l=1,xmap%grids(g)%size
  2937         i1 = xmap%grids(g)%x(l)%i1
  2938         j1 = xmap%grids(g)%x(l)%j1
  2939         i2 = xmap%grids(g)%x(l)%i2
  2940         j2 = xmap%grids(g)%x(l)%j2
  2941         tile1 = xmap%grids(g)%x(l)%tile
  2943         overlap_with_nest = .false.
  2944         if(  xmap%grids(1)%id == 
"ATM" .AND. tile1 == 
tile_parent .AND. &
  2946         if(xmap%grids(g)%is_ug) 
then  2947         do k=1,xmap%grids(g)%km
  2948            lll = xmap%grids(g)%l_index((j2-1)*xmap%grids(g)%im+i2)
  2949            if (xmap%grids(g)%frac_area(lll,1,k)/=0.0) 
then  2950               xmap%size_put1 = xmap%size_put1+1
  2951               xmap%x1_put(xmap%size_put1)%pos  = xmap%ind_put1(ll)
  2952               xmap%x1_put(xmap%size_put1)%i    = xmap%grids(g)%x(l)%i1
  2953               xmap%x1_put(xmap%size_put1)%j    = xmap%grids(g)%x(l)%j1
  2954               xmap%x1_put(xmap%size_put1)%tile = xmap%grids(g)%x(l)%tile
  2955               xmap%x1_put(xmap%size_put1)%area = xmap%grids(g)%x(l)%area &
  2956                    *xmap%grids(g)%frac_area(lll,1,k)
  2957               xmap%x1_put(xmap%size_put1)%di   = xmap%grids(g)%x(l)%di 
  2958               xmap%x1_put(xmap%size_put1)%dj   = xmap%grids(g)%x(l)%dj 
  2959               if( .not. overlap_with_nest) 
then  2960                  xmap%size_get2 = xmap%size_get2+1
  2961                  xmap%x2_get(xmap%size_get2)%i    = xmap%grids(g)%x(l)%i2
  2962                  xmap%x2_get(xmap%size_get2)%j    = xmap%grids(g)%x(l)%j2
  2963                  xmap%x2_get(xmap%size_get2)%l    = lll
  2964                  xmap%x2_get(xmap%size_get2)%k    = k
  2965                  xmap%x2_get(xmap%size_get2)%area = xmap%grids(g)%x(l)%area * xmap%grids(g)%x(l)%scale 
  2966                  xmap%x2_get(xmap%size_get2)%pos  = xmap%size_put1
  2971         do k=1,xmap%grids(g)%km
  2972            if (xmap%grids(g)%frac_area(i2,j2,k)/=0.0) 
then  2973               xmap%size_put1 = xmap%size_put1+1
  2974               xmap%x1_put(xmap%size_put1)%pos  = xmap%ind_put1(ll)
  2975               xmap%x1_put(xmap%size_put1)%i    = xmap%grids(g)%x(l)%i1
  2976               xmap%x1_put(xmap%size_put1)%j    = xmap%grids(g)%x(l)%j1
  2977               xmap%x1_put(xmap%size_put1)%tile = xmap%grids(g)%x(l)%tile
  2978               xmap%x1_put(xmap%size_put1)%area = xmap%grids(g)%x(l)%area &
  2979                    *xmap%grids(g)%frac_area(i2,j2,k)
  2980               xmap%x1_put(xmap%size_put1)%di   = xmap%grids(g)%x(l)%di
  2981               xmap%x1_put(xmap%size_put1)%dj   = xmap%grids(g)%x(l)%dj
  2982               if( .not. overlap_with_nest) 
then  2983                  xmap%size_get2 = xmap%size_get2+1
  2984                  xmap%x2_get(xmap%size_get2)%i    = xmap%grids(g)%x(l)%i2
  2985                  xmap%x2_get(xmap%size_get2)%j    = xmap%grids(g)%x(l)%j2
  2986                  xmap%x2_get(xmap%size_get2)%k    = k
  2987                  xmap%x2_get(xmap%size_get2)%area = xmap%grids(g)%x(l)%area * xmap%grids(g)%x(l)%scale
  2988                  xmap%x2_get(xmap%size_get2)%pos  = xmap%size_put1
  2994      xmap%grids(g)%last_get = xmap%size_get2
  2999   if (xmap%get1_repro%nsend > 0) 
then  3003      mypos = mpp_pe() - mpp_root_pe()
  3006         p = mod(mypos+m, npes)
  3007         if( xmap%send_count_repro(p) > 0 ) 
then  3012      do g=2,
size(xmap%grids(:))
  3013         do l=1,xmap%grids(g)%size 
  3014            p = xmap%grids(g)%x(l)%pe-xmap%root_pe 
  3018            xmap%get1_repro%send(n)%xLoc(pos) = xloc
  3019            if( xmap%grids(g)%is_ug ) 
then  3020              i = xmap%grids(g)%x(l)%l2
  3021              xloc = xloc + count(xmap%grids(g)%frac_area(i,1,:)/=0.0)
  3023              i = xmap%grids(g)%x(l)%i2
  3024              j = xmap%grids(g)%x(l)%j2
  3025              xloc = xloc + count(xmap%grids(g)%frac_area(i,j,:)/=0.0)
  3032 end subroutine regen  3053 real, 
dimension(:,:,:), 
intent(in   ) :: f
  3054 character(len=3),       
intent(in   ) :: grid_id
  3058   type(grid_type), 
pointer, 
save :: grid =>null()
  3060   if (grid_id==xmap%grids(1)%id) 
call error_mesg (
'xgrid_mod',  &
  3061                                    'set_frac_area called on side 1 grid', fatal)
  3062   do g=2,
size(xmap%grids(:))
  3063     grid => xmap%grids(g)
  3064     if (grid_id==grid%id) 
then  3065       if (
size(f,3)/=
size(grid%frac_area,3)) 
then  3066         deallocate (grid%frac_area)
  3067         grid%km = 
size(f,3);
  3068         allocate( grid%frac_area(grid%is_me:grid%ie_me, grid%js_me:grid%je_me, &
  3077   call error_mesg (
'xgrid_mod', 
'set_frac_area: could not find grid id', fatal)
  3101 real, 
dimension(:,:),   
intent(in   ) :: f
  3102 character(len=3),       
intent(in   ) :: grid_id
  3106   type(
grid_type), 
pointer, 
save :: grid =>null()
  3108   if (grid_id==xmap%grids(1)%id) 
call error_mesg (
'xgrid_mod',  &
  3109                                    'set_frac_area_ug called on side 1 grid', fatal)
  3110   if (grid_id .NE. 
'LND' ) 
call error_mesg (
'xgrid_mod',  &
  3111                                    .NE.
'set_frac_area_ug called for grid_id  LND', fatal)
  3112   do g=2,
size(xmap%grids(:))
  3113     grid => xmap%grids(
g)
  3114     if (grid_id==grid%id) 
then  3115       if (
size(f,2)/=
size(grid%frac_area,3)) 
then  3116         deallocate (grid%frac_area)
  3117         grid%km = 
size(f,2);
  3118         allocate( grid%frac_area(grid%ls_me:grid%le_me, 1, grid%km) )
  3120       grid%frac_area(:,1,:) = f(:,:);
  3126   call error_mesg (
'xgrid_mod', 
'set_frac_area_ug: could not find grid id', fatal)
  3167   real, 
dimension(:,:), 
intent(in   )    :: d
  3168   character(len=3),     
intent(in   )    :: grid_id
  3169   real, 
dimension(:),   
intent(inout)    :: x
  3171   integer, 
intent(in), 
optional          :: remap_method
  3172   logical, 
intent(in), 
optional          :: complete
  3174   logical                                         :: is_complete, set_mismatch
  3175   integer                                         :: g, method
  3176   character(len=2)                                :: text
  3177   integer,                                   
save :: isize=0
  3178   integer,                                   
save :: jsize=0
  3179   integer,                                   
save :: lsize=0
  3180   integer,                                   
save :: xsize=0
  3181   integer,                                   
save :: method_saved=0
  3182   character(len=3),                          
save :: grid_id_saved=
""  3183   integer(LONG_KIND), 
dimension(MAX_FIELDS), 
save :: d_addrs=-9999
  3184   integer(LONG_KIND), 
dimension(MAX_FIELDS), 
save :: x_addrs=-9999
  3186   if (grid_id==xmap%grids(1)%id) 
then  3188      if(
present(remap_method)) method = remap_method
  3189      is_complete = .true.
  3190      if(
present(complete)) is_complete=complete
  3194         call error_mesg (
'xgrid_mod',  
'MAX_FIELDS='//trim(text)//
' exceeded for group put_side1_to_xgrid', fatal)
  3196      d_addrs(lsize) = loc(d)
  3197      x_addrs(lsize) = loc(x)  
  3203         method_saved = method
  3204         grid_id_saved = grid_id
  3206         set_mismatch = .false.
  3207         set_mismatch = set_mismatch .OR. (isize /= 
size(d,1))
  3208         set_mismatch = set_mismatch .OR. (jsize /= 
size(d,2))
  3209         set_mismatch = set_mismatch .OR. (xsize /= 
size(x(:)))
  3210         set_mismatch = set_mismatch .OR. (method_saved /= method)
  3211         set_mismatch = set_mismatch .OR. (grid_id_saved /= grid_id)
  3212         if(set_mismatch)
then  3213            write( text,
'(i2)' ) lsize
  3214            call error_mesg (
'xgrid_mod', 
'Incompatible field at count '//text//
' for group put_side1_to_xgrid', fatal )
  3218      if(is_complete) 
then  3225            if(grid_id .NE. 
'ATM') 
call error_mesg (
'xgrid_mod',  &
  3226                 "second order put_to_xgrid should only be applied to 'ATM' model, "//&
  3227                 "contact developer", fatal)
  3243   do g=2,
size(xmap%grids(:))
  3244     if (grid_id==xmap%grids(g)%id)    &
  3246                        'put_to_xgrid expects a 3D side 2 grid', fatal)
  3249   call error_mesg (
'xgrid_mod', 
'put_to_xgrid: could not find grid id', fatal)
  3263 real, 
dimension(:,:,:), 
intent(in   ) :: d
  3264 character(len=3),       
intent(in   ) :: grid_id
  3265 real, 
dimension(:),     
intent(inout) :: x
  3270   if (grid_id==xmap%grids(1)%id) &
  3272                      'put_to_xgrid expects a 2D side 1 grid', fatal)
  3274   do g=2,
size(xmap%grids(:))
  3275     if (grid_id==xmap%grids(g)%id) 
then  3281   call error_mesg (
'xgrid_mod', 
'put_to_xgrid: could not find grid id', fatal)
  3295   real, 
dimension(:,:), 
intent(  out) :: d
  3296   character(len=3),     
intent(in   ) :: grid_id
  3297   real, 
dimension(:),   
intent(in   ) :: x
  3299   logical, 
intent(in), 
optional     :: complete
  3301   logical                                         :: is_complete, set_mismatch
  3303   character(len=2)                                :: text
  3304   integer,                                   
save :: isize=0
  3305   integer,                                   
save :: jsize=0
  3306   integer,                                   
save :: lsize=0
  3307   integer,                                   
save :: xsize=0
  3308   character(len=3),                          
save :: grid_id_saved=
""  3309   integer(LONG_KIND), 
dimension(MAX_FIELDS), 
save :: d_addrs=-9999
  3310   integer(LONG_KIND), 
dimension(MAX_FIELDS), 
save :: x_addrs=-9999
  3312   if (grid_id==xmap%grids(1)%id) 
then  3313      is_complete = .true.
  3314      if(
present(complete)) is_complete=complete
  3318         call error_mesg (
'xgrid_mod',  
'MAX_FIELDS='//trim(text)//
' exceeded for group get_side1_from_xgrid', fatal)
  3320      d_addrs(lsize) = loc(d)
  3321      x_addrs(lsize) = loc(x)  
  3327         grid_id_saved = grid_id
  3329         set_mismatch = .false.
  3330         set_mismatch = set_mismatch .OR. (isize /= 
size(d,1))
  3331         set_mismatch = set_mismatch .OR. (jsize /= 
size(d,2))
  3332         set_mismatch = set_mismatch .OR. (xsize /= 
size(x(:)))
  3333         set_mismatch = set_mismatch .OR. (grid_id_saved /= grid_id)
  3334         if(set_mismatch)
then  3335            write( text,
'(i2)' ) lsize
  3336            call error_mesg (
'xgrid_mod', 
'Incompatible field at count '//text//
' for group get_side1_from_xgrid', fatal )
  3340      if(is_complete) 
then  3346         d_addrs(1:lsize) = -9999
  3347         x_addrs(1:lsize) = -9999
  3357   do g=2,
size(xmap%grids(:))
  3358     if (grid_id==xmap%grids(g)%id) &
  3360                        'get_from_xgrid expects a 3D side 2 grid', fatal)
  3363   call error_mesg (
'xgrid_mod', 
'get_from_xgrid: could not find grid id', fatal)
  3377 real, 
dimension(:,:,:), 
intent(  out) :: d
  3378 character(len=3),       
intent(in   ) :: grid_id
  3379 real, 
dimension(:),     
intent(in   ) :: x
  3384   if (grid_id==xmap%grids(1)%id) &
  3386                      'get_from_xgrid expects a 2D side 1 grid', fatal)
  3388   do g=2,
size(xmap%grids(:))
  3389     if (grid_id==xmap%grids(g)%id) 
then  3395   call error_mesg (
'xgrid_mod', 
'get_from_xgrid: could not find grid id', fatal)
  3420 subroutine some(xmap, some_arr, grid_id)
  3422 character(len=3), 
optional, 
intent(in) :: grid_id
  3423 logical, 
dimension(:), 
intent(out) :: some_arr
  3427   if (.not.
present(grid_id)) 
then  3429     if(xmap%size > 0) 
then  3437   if (grid_id==xmap%grids(1)%id) &
  3438     call error_mesg (
'xgrid_mod', 
'some expects a side 2 grid id', fatal)
  3440   do g=2,
size(xmap%grids(:))
  3441     if (grid_id==xmap%grids(
g)%id) 
then  3443       some_arr(xmap%grids(
g)%first:xmap%grids(
g)%last) = .true.;
  3448   call error_mesg (
'xgrid_mod', 
'some could not find grid id', fatal)
  3457 real, 
dimension(grid%is_me:grid%ie_me, &
                grid%js_me:grid%je_me, grid%km), 
intent(in) :: d
  3458 real, 
dimension(:    ), 
intent(inout) :: x
  3464   do l=grid%first,grid%last
  3465     x(l) = d(xmap%x2(l)%i,xmap%x2(l)%j,xmap%x2(l)%k)
  3475 real, 
dimension(grid%is_me:grid%ie_me, &
                grid%js_me:grid%je_me, grid%km), 
intent(out) :: d
  3476 real, 
dimension(:),     
intent(in   ) :: x
  3484   do l=grid%first_get,grid%last_get
  3485     d(xmap%x2_get(l)%i,xmap%x2_get(l)%j,xmap%x2_get(l)%k) = &
  3486             d(xmap%x2_get(l)%i,xmap%x2_get(l)%j,xmap%x2_get(l)%k) + xmap%x2_get(l)%area*x(xmap%x2_get(l)%pos)
  3492     d(:,:,k) = d(:,:,k) * grid%area_inv
  3502   integer(LONG_KIND), 
dimension(:), 
intent(in) :: d_addrs
  3503   integer(LONG_KIND), 
dimension(:), 
intent(in) :: x_addrs
  3505   integer,                          
intent(in) :: isize, jsize, xsize, lsize
  3507   integer                         :: i, j, p, buffer_pos, msgsize
  3508   integer                         :: from_pe, to_pe, pos, n, l, count
  3509   integer                         :: ibegin, istart, iend, start_pos
  3510   type(
comm_type), 
pointer, 
save :: comm =>null()
  3511   real                            :: recv_buffer(xmap%put1%recvsize*lsize)
  3512   real                            :: send_buffer(xmap%put1%sendsize*lsize)
  3513   real                            :: unpack_buffer(xmap%put1%recvsize)
  3515   real, 
dimension(isize, jsize)   :: d
  3516   real, 
dimension(xsize)          :: x
  3524   do p = 1, comm%nrecv
  3525      msgsize = comm%recv(p)%count*lsize
  3526      from_pe = comm%recv(p)%pe
  3527      buffer_pos = comm%recv(p)%buffer_pos*lsize
  3528      call mpp_recv(recv_buffer(buffer_pos+1), glen=msgsize, from_pe = from_pe, block=.false., tag=comm_tag_7)
  3533   do p = 1, comm%nsend
  3534      msgsize = comm%send(p)%count*lsize
  3535      to_pe = comm%send(p)%pe
  3539         do n = 1, comm%send(p)%count
  3541            i = comm%send(p)%i(n)
  3542            j = comm%send(p)%j(n)
  3543            send_buffer(pos) = d(i,j)
  3546      call mpp_send(send_buffer(buffer_pos+1), plen=msgsize, to_pe = to_pe, tag=comm_tag_7 )
  3547      buffer_pos = buffer_pos + msgsize
  3550   call mpp_sync_self(
check=event_recv)
  3553   if( lsize == 1) 
then  3555      do l=1,xmap%size_put1
  3556         x(l) =  recv_buffer(xmap%x1_put(l)%pos)
  3564         do p = 1, comm%nrecv
  3565            count = comm%recv(p)%count
  3566            ibegin = comm%recv(p)%buffer_pos*lsize + 1
  3567            istart = ibegin + (l-1)*count
  3568            iend = istart + count - 1
  3569            pos = comm%recv(p)%buffer_pos
  3572               unpack_buffer(pos) = recv_buffer(n)
  3575         do i=1,xmap%size_put1
  3576            x(i) =  unpack_buffer(xmap%x1_put(i)%pos)
  3581   call mpp_sync_self()
  3591   integer(LONG_KIND), 
dimension(:), 
intent(in) :: d_addrs
  3592   integer(LONG_KIND), 
dimension(:), 
intent(in) :: x_addrs
  3594   integer,                          
intent(in) :: isize, jsize, xsize, lsize
  3597   real, 
dimension(0:isize+1, 0:jsize+1, lsize) :: tmp
  3598   real, 
dimension(isize,     jsize,     lsize) :: tmpx, tmpy
  3599   real, 
dimension(isize,     jsize,     lsize) :: d_bar_max, d_bar_min
  3600   real, 
dimension(isize,     jsize,     lsize) :: d_max, d_min
  3602   integer                         :: i, is, ie, im, j, js, je, jm, ii, jj
  3603   integer                         :: p, l, ioff, joff, isd, jsd
  3604   type(
grid_type), 
pointer, 
save :: grid1 =>null()
  3605   type(
comm_type), 
pointer, 
save :: comm  =>null()
  3606   integer                         :: buffer_pos, msgsize, from_pe, to_pe, pos, n
  3607   integer                         :: ibegin, count, istart, iend
  3608   real                            :: recv_buffer(xmap%put1%recvsize*lsize*3)
  3609   real                            :: send_buffer(xmap%put1%sendsize*lsize*3)
  3610   real                            :: unpack_buffer(xmap%put1%recvsize*3)
  3611   logical                         :: on_west_edge, on_east_edge, on_south_edge, on_north_edge
  3612   real, 
dimension(isize, jsize)   :: d
  3613   real, 
dimension(xsize)          :: x
  3618   grid1 => xmap%grids(1)
  3620   is = grid1%is_me;   ie = grid1%ie_me
  3621   js = grid1%js_me;   je = grid1%je_me
  3629      tmp(1:isize,1:jsize,l) = d(:,:)
  3632   if(grid1%is_latlon) 
then  3636         tmpy(:,:,l) = 
grad_merid_latlon(tmp(:,:,l), grid1%lat, is, ie, js, je, isd, jsd)
  3637         tmpx(:,:,l) = 
grad_zonal_latlon(tmp(:,:,l), grid1%lon, grid1%lat, is, ie, js, je, isd, jsd)
  3641      on_west_edge  = (is==1)
  3642      on_east_edge  = (ie==grid1%im)
  3643      on_south_edge = (js==1)
  3644      on_north_edge = (je==grid1%jm)
  3648         call gradient_cubic(tmp(:,:,l), grid1%box%dx, grid1%box%dy, grid1%box%area,   &
  3649                             grid1%box%edge_w, grid1%box%edge_e, grid1%box%edge_s,     &
  3650                             grid1%box%edge_n, grid1%box%en1, grid1%box%en2,           &
  3651                             grid1%box%vlon, grid1%box%vlat, tmpx(:,:,l), tmpy(:,:,l), &
  3652                             on_west_edge, on_east_edge, on_south_edge, on_north_edge)
  3659   do p = 1, comm%nrecv
  3660      msgsize = comm%recv(p)%count*lsize
  3661      buffer_pos = comm%recv(p)%buffer_pos*lsize
  3664         buffer_pos = buffer_pos*3
  3666      from_pe = comm%recv(p)%pe
  3667      call mpp_recv(recv_buffer(buffer_pos+1), glen=msgsize, from_pe = from_pe, block=.false., tag=comm_tag_8)
  3683                        if(tmp(i,j,l) > d_bar_max(i,j,l)) d_bar_max(i,j,l) = tmp(i,j,l)
  3684                        if(tmp(i,j,l) < d_bar_min(i,j,l)) d_bar_min(i,j,l) = tmp(i,j,l)
  3697      do p = 1, comm%nsend
  3698         msgsize = comm%send(p)%count*lsize
  3699         to_pe = comm%send(p)%pe
  3702            do n = 1, comm%send(p)%count
  3704               i = comm%send(p)%i(n)
  3705               j = comm%send(p)%j(n)
  3706               send_buffer(pos) = d(i,j) + tmpy(i,j,l)*comm%send(p)%dj(n) + tmpx(i,j,l)*comm%send(p)%di(n)
  3707               if(send_buffer(pos) > d_max(i,j,l)) d_max(i,j,l) = send_buffer(pos)
  3708               if(send_buffer(pos) < d_min(i,j,l)) d_min(i,j,l) = send_buffer(pos)              
  3713      do p = 1, comm%nsend
  3714         msgsize = comm%send(p)%count*lsize
  3715         to_pe = comm%send(p)%pe
  3719            do n = 1, comm%send(p)%count
  3721               i = comm%send(p)%i(n)
  3722               j = comm%send(p)%j(n)           
  3724               if( d_max(i,j,l) > d_bar_max(i,j,l) ) 
then  3725                  send_buffer(pos) = d_bar + ((send_buffer(pos)-d_bar)/(d_max(i,j,l)-d_bar)) * (d_bar_max(i,j,l)-d_bar)
  3726               else if( d_min(i,j,l) < d_bar_min(i,j,l) ) 
then  3727                  send_buffer(pos) = d_bar + ((send_buffer(pos)-d_bar)/(d_min(i,j,l)-d_bar)) * (d_bar_min(i,j,l)-d_bar)
  3731         call mpp_send(send_buffer(buffer_pos+1), plen=msgsize, to_pe = to_pe, tag=comm_tag_8 )
  3732         buffer_pos = buffer_pos + msgsize
  3735      do p = 1, comm%nsend
  3736         msgsize = comm%send(p)%count*lsize*3
  3737         to_pe = comm%send(p)%pe
  3741            do n = 1, comm%send(p)%count
  3743               i = comm%send(p)%i(n)
  3744               j = comm%send(p)%j(n)
  3745               send_buffer(pos-2) = d(i,j)
  3746               send_buffer(pos-1) = tmpy(i,j,l)
  3747               send_buffer(pos  ) = tmpx(i,j,l)
  3750         call mpp_send(send_buffer(buffer_pos+1), plen=msgsize, to_pe = to_pe, tag=comm_tag_8 )
  3751         buffer_pos = buffer_pos + msgsize
  3755   call mpp_sync_self(
check=event_recv)
  3759      if( lsize == 1) 
then  3761         do l=1,xmap%size_put1
  3762            pos = xmap%x1_put(l)%pos
  3763            x(l) =  recv_buffer(pos)
  3769            do p = 1, comm%nsend
  3770               count = comm%send(p)%count
  3771               ibegin = comm%recv(p)%buffer_pos*lsize + 1
  3772               istart = ibegin + (l-1)*count
  3773               iend = istart + count - 1
  3774               pos = comm%recv(p)%buffer_pos
  3777                  unpack_buffer(pos) = recv_buffer(n)
  3780            do i=1,xmap%size_put1
  3781               pos = xmap%x1_put(i)%pos
  3782               x(i) =  unpack_buffer(pos)
  3787      if( lsize == 1) 
then  3790         do l=1,xmap%size_put1
  3791            pos = xmap%x1_put(l)%pos
  3792            x(l) = recv_buffer(3*pos-2) + recv_buffer(3*pos-1)*xmap%x1_put(l)%dj + recv_buffer(3*pos)*xmap%x1_put(l)%di
  3801            do p = 1, comm%nrecv
  3802               count = comm%recv(p)%count*3
  3803               ibegin = comm%recv(p)%buffer_pos*lsize*3 + 1
  3804               istart = ibegin + (l-1)*count
  3805               iend = istart + count - 1
  3806               pos =  comm%recv(p)%buffer_pos*3
  3809                  unpack_buffer(pos) = recv_buffer(n)
  3812            do i=1,xmap%size_put1
  3813               pos = xmap%x1_put(i)%pos
  3814               x(i) = unpack_buffer(3*pos-2) + unpack_buffer(3*pos-1)*xmap%x1_put(i)%dj + unpack_buffer(3*pos)*xmap%x1_put(i)%di
  3820   call mpp_sync_self()
  3827 subroutine get_1_from_xgrid(d_addrs, x_addrs, xmap, isize, jsize, xsize, lsize)
  3828   integer(LONG_KIND), 
dimension(:), 
intent(in) :: d_addrs
  3829   integer(LONG_KIND), 
dimension(:), 
intent(in) :: x_addrs
  3831   integer,                          
intent(in) :: isize, jsize, xsize, lsize
  3833   real, 
dimension(xmap%size), 
target :: dg(xmap%size, lsize)
  3834   integer                            :: i, j, l, p, n, m
  3835   integer                            :: msgsize, buffer_pos, pos
  3836   integer                            :: istart, iend, count
  3837   real              , 
pointer, 
save  :: dgp =>null()
  3838   type(
grid_type) , 
pointer, 
save  :: grid1 =>null()
  3839   type(
comm_type) , 
pointer, 
save  :: comm  =>null()
  3840   type(overlap_type), 
pointer, 
save  :: send => null()
  3841   type(overlap_type), 
pointer, 
save  :: recv => null()
  3842   real                               :: recv_buffer(xmap%get1%recvsize*lsize*3)
  3843   real                               :: send_buffer(xmap%get1%sendsize*lsize*3)
  3844   real                               :: unpack_buffer(xmap%get1%recvsize*3)
  3845   real                               :: d(isize,jsize)
  3846   real, 
dimension(xsize)             :: x
  3853   grid1 => xmap%grids(1)
  3855   do p = 1, comm%nrecv
  3856      recv => comm%recv(p)
  3857      msgsize = recv%count*lsize
  3858      buffer_pos = recv%buffer_pos*lsize
  3859      call mpp_recv(recv_buffer(buffer_pos+1), glen=msgsize, from_pe = recv%pe, block=.false., tag=comm_tag_9)
  3867         dgp => dg(xmap%x1(i)%pos,l)
  3868         dgp =  dgp + xmap%x1(i)%area*x(i)
  3876   do p = 1, comm%nsend
  3877      send => comm%send(p)
  3878      msgsize = send%count*lsize
  3880      istart = send%buffer_pos+1
  3881      iend = istart + send%count - 1
  3885            send_buffer(pos) = dg(n,l)
  3888      call mpp_send(send_buffer(buffer_pos+1), plen=msgsize, to_pe = send%pe, tag=comm_tag_9 )
  3889      buffer_pos = buffer_pos + msgsize
  3893   call mpp_sync_self(
check=event_recv)
  3902   do p = 1, comm%nrecv
  3903      recv => comm%recv(p)
  3905      buffer_pos = recv%buffer_pos*lsize
  3906      if( recv%pe == xmap%me ) 
then  3910            pos = buffer_pos + (l-1)*count
  3916               d(i,j) = recv_buffer(pos) 
  3924   do m = 1, comm%nrecv
  3925      p = comm%unpack_ind(m)
  3926      recv => comm%recv(p)
  3927      if( recv%pe == xmap%me ) 
then  3930      buffer_pos = recv%buffer_pos*lsize
  3934         pos = buffer_pos + (l-1)*recv%count
  3936         do n = 1, recv%count
  3940            d(i,j) = d(i,j) + recv_buffer(pos) 
  3951      d = d * grid1%area_inv
  3953   call mpp_sync_self()
  3961   integer(LONG_KIND), 
dimension(:), 
intent(in) :: d_addrs
  3962   integer(LONG_KIND), 
dimension(:), 
intent(in) :: x_addrs
  3964   integer,                          
intent(in) :: xsize, lsize
  3966   integer                            :: g, i, j, k, p, l, n, l2, m, l3
  3967   integer                            :: msgsize, buffer_pos, pos
  3968   type(
grid_type), 
pointer, 
save :: grid =>null()
  3969   type(comm_type),  
pointer, 
save :: comm => null()
  3970   type(overlap_type), 
pointer, 
save  :: send => null()
  3971   type(overlap_type), 
pointer, 
save  :: recv => null()
  3972     integer,  
dimension(0:xmap%npes-1) :: pl, ml
  3973   real                               :: recv_buffer(xmap%recv_count_repro_tot*lsize)
  3974   real                               :: send_buffer(xmap%send_count_repro_tot*lsize)
  3975   real                               :: d(xmap%grids(1)%is_me:xmap%grids(1)%ie_me, &
  3976                                           xmap%grids(1)%js_me:xmap%grids(1)%je_me)
  3977   real, 
dimension(xsize)             :: x
  3982   comm => xmap%get1_repro
  3984   do p = 1, comm%nrecv
  3985      recv => comm%recv(p)
  3986      msgsize = recv%count*lsize
  3987      buffer_pos = recv%buffer_pos*lsize
  3988      call mpp_recv(recv_buffer(buffer_pos+1), glen=msgsize, from_pe = recv%pe, block=.false., tag=comm_tag_10)
  3989      n = recv%pe -xmap%root_pe
  3995   send_buffer(:) = 0.0
  3998   do p = 1, comm%nsend
  3999      pos = comm%send(p)%buffer_pos*lsize
  4000      send => comm%send(p)
  4003         do n = 1, send%count
  4009            do k =1, xmap%grids(g)%km
  4010              if(xmap%grids(g)%frac_area(i,j,k)/=0.0) 
then  4012               send_buffer(pos) = send_buffer(pos) + xmap%x1(l2)%area *x(l2)
  4020      buffer_pos = comm%send(p)%buffer_pos*lsize
  4021      msgsize = comm%send(p)%count*lsize
  4022      call mpp_send(send_buffer(buffer_pos+1), plen=msgsize, to_pe=comm%send(p)%pe, tag=comm_tag_10)
  4030   call mpp_sync_self(
check=event_recv)
  4036      do g=2,
size(xmap%grids(:))
  4037         grid => xmap%grids(g)
  4038         do l3=1,grid%size_repro 
  4039            i = grid%x_repro(l3)%i1
  4040            j = grid%x_repro(l3)%j1
  4041            p = grid%x_repro(l3)%pe-xmap%root_pe
  4042            pos = pl(p) + (l-1)*ml(p) + grid%x_repro(l3)%recv_pos
  4043            d(i,j) = d(i,j) + recv_buffer(pos)
  4047      d = d * xmap%grids(1)%area_inv
  4050   call mpp_sync_self()       
  4069 real, 
dimension(:,:),    
intent(in   ) :: d
  4070 character(len=3),        
intent(in   ) :: grid_id
  4073 integer, 
intent(in), 
optional :: remap_method
  4076   real, 
dimension(xmap%size) :: x_over, x_back
  4077   real, 
dimension(size(d,1),size(d,2)) :: d1
  4078   real, 
dimension(:,:,:), 
allocatable  :: d2
  4080   type(
grid_type), 
pointer, 
save      :: grid1 =>null(), grid2 =>null()
  4082   grid1 => xmap%grids(1)
  4088   call put_to_xgrid (d, grid1%id, x_over, xmap, remap_method)    
  4089   do g=2,
size(xmap%grids(:))
  4090     grid2 => xmap%grids(
g)
  4091     if(grid2%on_this_pe) 
then  4092       allocate (d2(grid2%is_me:grid2%ie_me, grid2%js_me:grid2%je_me,  grid2%km) )
  4095     if(grid2%on_this_pe) 
then  4099     if(
allocated(d2))
deallocate (d2)
  4123 real, 
dimension(:,:,:), 
intent(in   )  :: d
  4124 character(len=3),       
intent(in   )  :: grid_id
  4127 integer, 
intent(in), 
optional :: remap_method
  4130   real, 
dimension(xmap%size) :: x_over, x_back
  4131   real, 
dimension(:,:  ), 
allocatable :: d1
  4132   real, 
dimension(:,:,:), 
allocatable :: d2
  4134   type(
grid_type), 
pointer, 
save     :: grid1 =>null(), grid2 =>null()
  4136   grid1 => xmap%grids(1)
  4138   do g = 2,
size(xmap%grids(:))
  4139     grid2 => xmap%grids(
g)
  4140     if (grid_id==grid2%id) 
then  4141       if(grid2%on_this_pe) 
then  4146       call put_to_xgrid(0.0 * grid2%frac_area, grid2%id, x_over, xmap) 
  4150   allocate ( d1(
size(grid1%area,1),
size(grid1%area,2)) )
  4153   call put_to_xgrid(d1,  grid1%id, x_back, xmap,remap_method)   
  4157   do g = 2,
size(xmap%grids(:))
  4158     grid2 => xmap%grids(
g)
  4159     if(grid2%on_this_pe) 
then  4160        allocate ( d2( 
size(grid2%frac_area, 1), 
size(grid2%frac_area, 2),  &
  4161                                                  size(grid2%frac_area, 3) ) )
  4165     if(
allocated(d2) )
deallocate ( d2 )
  4185 real, 
dimension(:,:),    
intent(in   ) :: d
  4186 character(len=3),        
intent(in   ) :: grid_id
  4189 integer, 
intent(in), 
optional :: remap_method
  4192   real, 
dimension(xmap%size) :: x_over, x_back
  4193   real, 
dimension(size(d,1),size(d,2)) :: d1
  4194   real, 
dimension(:,:,:), 
allocatable  :: d2
  4195   real, 
dimension(:    ), 
allocatable  :: d_ug
  4196   real, 
dimension(:,:),   
allocatable  :: d2_ug
  4198   type(
grid_type), 
pointer, 
save      :: grid1 =>null(), grid2 =>null()
  4200   grid1 => xmap%grids(1)
  4204   if(grid1%is_ug) 
then  4205      allocate(d_ug(grid1%ls_me:grid1%le_me))
  4211      call put_to_xgrid (d, grid1%id, x_over, xmap, remap_method)    
  4213   do g=2,
size(xmap%grids(:))
  4214     grid2 => xmap%grids(
g)
  4215     if(grid2%is_ug) 
then  4216       if(grid2%on_this_pe) 
then  4217          allocate (d2_ug(grid2%ls_me:grid2%le_me, grid2%km) )
  4221       if(grid2%on_this_pe) 
then  4223                                           sum( grid2%area(:,1) * sum(grid2%frac_area(:,1,:)*d2_ug,dim=2) )
  4226       if(
allocated(d2_ug))
deallocate (d2_ug)
  4228        if(grid2%on_this_pe) 
then  4229           allocate (d2(grid2%is_me:grid2%ie_me, grid2%js_me:grid2%je_me,  grid2%km) )
  4232        if(grid2%on_this_pe) 
then  4236        if(
allocated(d2))
deallocate (d2)
  4239   if(grid1%is_ug) 
then  4246   if(
allocated(d_ug)) 
deallocate(d_ug)
  4265 real, 
dimension(:,:,:), 
intent(in   )  :: d
  4266 character(len=3),       
intent(in   )  :: grid_id
  4269 integer, 
intent(in),   
optional :: remap_method
  4272   real, 
dimension(xmap%size) :: x_over, x_back
  4273   real, 
dimension(:,:  ), 
allocatable :: d1, d_ug
  4274   real, 
dimension(:,:,:), 
allocatable :: d2
  4276   type(
grid_type), 
pointer, 
save     :: grid1 =>null(), grid2 =>null()
  4278   grid1 => xmap%grids(1)
  4280   do g = 2,
size(xmap%grids(:))
  4281     grid2 => xmap%grids(
g)
  4282     if (grid_id==grid2%id) 
then  4283        if(grid2%on_this_pe) 
then  4284           if(grid2%is_ug) 
then  4285              allocate(d_ug(grid2%ls_me:grid2%le_me,grid2%km))
  4292        if(grid2%is_ug) 
then  4297        if(
allocated(d_ug)) 
deallocate(d_ug)
  4299        if(grid2%is_ug) 
then  4300           call put_to_xgrid_ug(0.0 * grid2%frac_area(:,1,:), grid2%id, x_over, xmap) 
  4302           call put_to_xgrid(0.0 * grid2%frac_area, grid2%id, x_over, xmap) 
  4307   allocate ( d1(
size(grid1%area,1),
size(grid1%area,2)) )
  4308   if(grid1%is_ug) 
then  4314   if(grid1%is_ug) 
then  4317      call put_to_xgrid(d1,  grid1%id, x_back, xmap,remap_method)   
  4322   do g = 2,
size(xmap%grids(:))
  4323     grid2 => xmap%grids(
g)
  4324     if(grid2%on_this_pe) 
then  4325        allocate ( d2( 
size(grid2%frac_area, 1), 
size(grid2%frac_area, 2),  &
  4326                                                  size(grid2%frac_area, 3) ) )
  4328     if(grid2%is_ug) 
then  4334     if(
allocated(d2) )
deallocate ( d2 )
  4345   character(len=3),     
intent(in   ) :: id
  4347   real, 
dimension(:,:), 
intent(out  ) :: area
  4352    do g = 1, 
size(xmap%grids(:))
  4353       if (id==xmap%grids(
g)%id ) 
then  4354          if(
size(area,1) .NE. 
size(xmap%grids(
g)%area,1) .OR. 
size(area,2) .NE. 
size(xmap%grids(
g)%area,2) ) &
  4355            call error_mesg(
"xgrid_mod", 
"size mismatch between area and xmap%grids(g)%area", fatal)
  4356          area = xmap%grids(
g)%area
  4362    if(.not. found) 
call error_mesg(
"xgrid_mod", id//
" is not found in xmap%grids id", fatal)
  4374   integer,                    
intent(in) :: isd, jsd
  4375   real, 
dimension(isd:,jsd:), 
intent(in) :: d
  4376   real, 
dimension(:),         
intent(in) :: lon
  4377   real, 
dimension(:),         
intent(in) :: lat
  4378   integer,                    
intent(in) :: is, ie, js, je 
  4380   real                                   :: dx, costheta
  4381   integer                                :: i, j, ip1, im1
  4387      else if(i==
size(lon(:)) ) 
then  4390         ip1 = i+1; im1 = i-1
  4392      dx = lon(ip1) - lon(im1)
  4393      if(abs(dx).lt.
eps )  
call error_mesg(
'xgrids_mod(grad_zonal_latlon)', 
'Improper grid size in lontitude', fatal)
  4394      if(dx .gt. 
pi)  dx = dx - 2.0* 
pi  4395      if(dx .lt. -
pi) dx = dx + 2.0* 
pi  4397         costheta = cos(lat(j))
  4398         if(abs(costheta) .lt. 
eps) 
call error_mesg(
'xgrids_mod(grad_zonal_latlon)', 
'Improper latitude grid', fatal)
  4413   integer,                    
intent(in) :: isd, jsd
  4414   real, 
dimension(isd:,jsd:), 
intent(in) :: d
  4415   real, 
dimension(:),         
intent(in) :: lat
  4416   integer,                    
intent(in) :: is, ie, js, je 
  4419   integer                                :: i, j, jp1, jm1
  4425      else if(j == 
size(lat(:)) ) 
then  4428         jp1 = j+1; jm1 = j-1
  4430      dy = lat(jp1) - lat(jm1)
  4431      if(abs(dy).lt.
eps) 
call error_mesg(
'xgrids_mod(grad_merid_latlon)', 
'Improper grid size in latitude', fatal)
  4445   integer, 
intent(in)             :: grid_index
  4446   integer, 
intent(out)            :: is, ie, js, je, km
  4448   is = xmap % grids(grid_index) % is_me
  4449   ie = xmap % grids(grid_index) % ie_me
  4450   js = xmap % grids(grid_index) % js_me
  4451   je = xmap % grids(grid_index) % je_me
  4452   km = xmap % grids(grid_index) % km
  4457 subroutine stock_move_3d(from, to, grid_index, data, xmap, &
  4458      & delta_t, from_side, to_side, radius, verbose, ier)
  4468   type(stock_type), 
intent(inout), 
optional :: from, to
  4469   integer, 
intent(in)             :: grid_index        
  4470   real, 
intent(in)                :: data(:,:,:)  
  4471   type(xmap_type), 
intent(in)     :: xmap
  4472   real, 
intent(in)                :: delta_t
  4473   integer, 
intent(in)             :: from_side, to_side 
  4474   real, 
intent(in)                :: radius       
  4475   character(len=*), 
intent(in), 
optional      :: verbose
  4476   integer, 
intent(out)            :: ier
  4478   real    :: from_dq, to_dq
  4481   if(grid_index == 1) 
then  4487   if(.not. 
associated(xmap%grids) ) 
then  4492      from_dq = delta_t * 4.0*
pi*radius**2 * sum( sum(xmap%grids(grid_index)%area * &
  4493           & sum(xmap%grids(grid_index)%frac_area * 
data, dim=3), dim=1))
  4497   if(
present(to  )) to   % dq(  to_side) = to   % dq(  to_side) + to_dq
  4498   if(
present(from)) from % dq(from_side) = from % dq(from_side) - from_dq
  4503      from_dq = from_dq/(4.0*
pi*radius**2)
  4504      to_dq   = to_dq  /(4.0*
pi*radius**2)
  4505      if(mpp_pe()==mpp_root_pe()) 
then  4506         write(
stocks_file,
'(a,es19.12,a,es19.12,a)') verbose, from_dq,
' [*/m^2]'  4514 subroutine stock_move_2d(from, to, grid_index, data, xmap, &
  4515      & delta_t, from_side, to_side, radius, verbose, ier)
  4524   type(stock_type), 
intent(inout), 
optional :: from, to
  4525   integer, 
optional, 
intent(in)   :: grid_index
  4526   real, 
intent(in)                :: data(:,:)    
  4527   type(xmap_type), 
intent(in)     :: xmap
  4528   real, 
intent(in)                :: delta_t
  4529   integer, 
intent(in)             :: from_side, to_side 
  4530   real, 
intent(in)                :: radius       
  4531   character(len=*), 
intent(in)    :: verbose
  4532   integer, 
intent(out)            :: ier
  4534   real    :: to_dq, from_dq
  4538   if(.not. 
associated(xmap%grids) ) 
then  4543   if( .not. 
present(grid_index) .or. grid_index==1 ) 
then  4546      from_dq = delta_t * 4.0*
pi*radius**2 * sum(sum(xmap%grids(1)%area * 
data, dim=1))
  4557   if(
present(to  )) to   % dq(  to_side) = to   % dq(  to_side) + to_dq
  4558   if(
present(from)) from % dq(from_side) = from % dq(from_side) - from_dq
  4563      from_dq = from_dq/(4.0*
pi*radius**2)
  4564      to_dq   = to_dq  /(4.0*
pi*radius**2)
  4565      if(mpp_pe()==mpp_root_pe()) 
then  4566         write(
stocks_file,
'(a,es19.12,a,es19.12,a)') verbose, from_dq,
' [*/m^2]'  4575      & delta_t, from_side, to_side, radius, verbose, ier)
  4585   type(stock_type), 
intent(inout), 
optional :: from, to
  4586   integer, 
intent(in)             :: grid_index        
  4587   real, 
intent(in)                :: data(:,:)  
  4588   type(xmap_type), 
intent(in)     :: xmap
  4589   real, 
intent(in)                :: delta_t
  4590   integer, 
intent(in)             :: from_side, to_side 
  4591   real, 
intent(in)                :: radius       
  4592   character(len=*), 
intent(in), 
optional      :: verbose
  4593   integer, 
intent(out)            :: ier
  4594   real, 
dimension(size(data,1),size(data,2)) :: tmp
  4596   real    :: from_dq, to_dq
  4599   if(grid_index == 1) 
then  4605   if(.not. 
associated(xmap%grids) ) 
then  4610      tmp = xmap%grids(grid_index)%frac_area(:,1,:) * 
data  4611      from_dq = delta_t * 4.0*
pi*radius**2 * sum( xmap%grids(grid_index)%area(:,1) * &
  4616   if(
present(to  )) to   % dq(  to_side) = to   % dq(  to_side) + to_dq
  4617   if(
present(from)) from % dq(from_side) = from % dq(from_side) - from_dq
  4622      from_dq = from_dq/(4.0*
pi*radius**2)
  4623      to_dq   = to_dq  /(4.0*
pi*radius**2)
  4624      if(mpp_pe()==mpp_root_pe()) 
then  4625         write(
stocks_file,
'(a,es19.12,a,es19.12,a)') verbose, from_dq,
' [*/m^2]'  4640   real, 
intent(in)                :: data(:,:)    
  4642   real, 
intent(in)                :: delta_t
  4643   real, 
intent(in)                :: 
radius         4644   real, 
intent(out)               :: res
  4645   integer, 
intent(out)            :: ier
  4650   if(.not. 
associated(xmap%grids) ) 
then  4655   res = delta_t * 4.0*
pi*
radius**2 * sum(sum(xmap%grids(1)%area * 
data, dim=1))
  4664 subroutine stock_print(stck, Time, comp_name, index, ref_value, radius, pelist)
  4672   character(len=*)              :: comp_name
  4673   integer, 
intent(in)           :: index     
  4674   real, 
intent(in)              :: ref_value 
  4675   real, 
intent(in)              :: 
radius  4676   integer, 
intent(in), 
optional :: pelist(:)
  4678   integer, 
parameter :: initid = -2 
  4682   real :: f_value, c_value, planet_area
  4683   character(len=80) :: formatstring
  4684   integer :: iday, isec, hours
  4685   integer :: diagid, compind
  4686   integer, 
dimension(NELEMS,4), 
save :: f_valuediagid = initid
  4687   integer, 
dimension(NELEMS,4), 
save :: c_valuediagid = initid
  4688   integer, 
dimension(NELEMS,4), 
save :: fmc_valuediagid = initid
  4692   character(len=30) :: field_name, units
  4694   f_value = sum(stck % dq)
  4695   c_value = ref_value      - stck % q_start
  4696   if(
present(pelist)) 
then  4697      call mpp_sum(f_value, pelist=pelist)
  4698      call mpp_sum(c_value, pelist=pelist)
  4704   if(mpp_pe() == mpp_root_pe()) 
then  4707      f_value       = f_value     / planet_area
  4708      c_value       = c_value     / planet_area
  4710      if(comp_name == 
'ATM') compind = 1
  4711      if(comp_name == 
'LND') compind = 2
  4712      if(comp_name == 
'ICE') compind = 3
  4713      if(comp_name == 
'OCN') compind = 4
  4716      if(f_valuediagid(index,compind) == initid) 
then  4717         field_name = trim(comp_name) // trim(
stock_names(index))
  4718         field_name  = trim(field_name) // 
'StocksChange_Flux'  4724      if(c_valuediagid(index,compind) == initid) 
then  4725         field_name = trim(comp_name) // trim(
stock_names(index))
  4726         field_name = trim(field_name) // 
'StocksChange_Comp'  4732      if(fmc_valuediagid(index,compind) == initid) 
then  4733         field_name = trim(comp_name) // trim(
stock_names(index))
  4734         field_name = trim(field_name) // 
'StocksChange_Diff'  4740      diagid=f_valuediagid(index,compind)
  4742      if (diagid > 0)  used = 
send_data(diagid, diagfield, time)
  4743      diagid=c_valuediagid(index,compind)
  4745      if (diagid > 0)  used = 
send_data(diagid, diagfield, time)
  4746      diagid=fmc_valuediagid(index,compind)
  4747      diagfield = f_value-c_value
  4748      if (diagid > 0)  used = 
send_data(diagid, diagfield, time)
  4752      hours = iday*24 + isec/3600
  4753      formatstring = 
'(a,a,a,i16,2x,es22.15,2x,es22.15,2x,es22.15)'  4755           ,hours,f_value,c_value,f_value-c_value
  4765     real, 
dimension(:,:), 
intent(in) :: lon, lat
  4767     integer                          :: i, j, nlon, nlat, num
  4772     loop_lat: 
do j = 1, nlat
  4774           if(lat(i,j) .NE. lat(1,j)) 
then  4782        loop_lon: 
do i = 1, nlon
  4784              if(lon(i,j) .NE. lon(i,1)) 
then  4813   real, 
dimension(:),   
intent(  out) :: d
  4814   character(len=3),     
intent(in   ) :: grid_id
  4815   real, 
dimension(:),   
intent(in   ) :: x
  4817   logical, 
intent(in), 
optional     :: complete
  4819   logical                                         :: is_complete, set_mismatch
  4821   character(len=2)                                :: text
  4822   integer,                                   
save :: isize=0
  4823   integer,                                   
save :: lsize=0
  4824   integer,                                   
save :: xsize=0
  4825   character(len=3),                          
save :: grid_id_saved=
""  4826   integer(LONG_KIND), 
dimension(MAX_FIELDS), 
save :: d_addrs=-9999
  4827   integer(LONG_KIND), 
dimension(MAX_FIELDS), 
save :: x_addrs=-9999
  4829   if (grid_id==xmap%grids(1)%id) 
then  4830      is_complete = .true.
  4831      if(
present(complete)) is_complete=complete
  4835         call error_mesg (
'xgrid_mod',  
'MAX_FIELDS='//trim(text)//
' exceeded for group get_side1_from_xgrid_ug', fatal)
  4837      d_addrs(lsize) = loc(d)
  4838      x_addrs(lsize) = loc(x)  
  4843         grid_id_saved = grid_id
  4845         set_mismatch = .false.
  4846         set_mismatch = set_mismatch .OR. (isize /= 
size(d(:)))
  4847         set_mismatch = set_mismatch .OR. (xsize /= 
size(x(:)))
  4848         set_mismatch = set_mismatch .OR. (grid_id_saved /= grid_id)
  4849         if(set_mismatch)
then  4850            write( text,
'(i2)' ) lsize
  4851            call error_mesg (
'xgrid_mod', 
'Incompatible field at count '//text//
' for group get_side1_from_xgrid_ug', fatal )
  4855      if(is_complete) 
then  4861         d_addrs(1:lsize) = -9999
  4862         x_addrs(1:lsize) = -9999
  4871   do g=2,
size(xmap%grids(:))
  4872     if (grid_id==xmap%grids(g)%id) &
  4874                        'get_from_xgrid_ug expects a 3D side 2 grid', fatal)
  4877   call error_mesg (
'xgrid_mod', 
'get_from_xgrid_ug: could not find grid id', fatal)
  4892   real, 
dimension(:),   
intent(in   )    :: d
  4893   character(len=3),     
intent(in   )    :: grid_id
  4894   real, 
dimension(:),   
intent(inout)    :: x
  4896   logical, 
intent(in), 
optional          :: complete
  4898   logical                                         :: is_complete, set_mismatch
  4900   character(len=2)                                :: text
  4901   integer,                                   
save :: dsize=0
  4902   integer,                                   
save :: lsize=0
  4903   integer,                                   
save :: xsize=0
  4904   character(len=3),                          
save :: grid_id_saved=
""  4905   integer(LONG_KIND), 
dimension(MAX_FIELDS), 
save :: d_addrs=-9999
  4906   integer(LONG_KIND), 
dimension(MAX_FIELDS), 
save :: x_addrs=-9999
  4908   if (grid_id==xmap%grids(1)%id) 
then  4909      is_complete = .true.
  4910      if(
present(complete)) is_complete=complete
  4914         call error_mesg (
'xgrid_mod',  
'MAX_FIELDS='//trim(text)//
' exceeded for group put_side1_to_xgrid_ug', fatal)
  4916      d_addrs(lsize) = loc(d)
  4917      x_addrs(lsize) = loc(x)  
  4922         grid_id_saved = grid_id
  4924         set_mismatch = .false.
  4925         set_mismatch = set_mismatch .OR. (dsize /= 
size(d(:)))
  4926         set_mismatch = set_mismatch .OR. (xsize /= 
size(x(:)))
  4927         set_mismatch = set_mismatch .OR. (grid_id_saved /= grid_id)
  4928         if(set_mismatch)
then  4929            write( text,
'(i2)' ) lsize
  4930            call error_mesg (
'xgrid_mod', 
'Incompatible field at count '//text//
' for group put_side1_to_xgrid_ug', fatal )
  4934      if(is_complete) 
then  4936         d_addrs(1:lsize) = -9999
  4937         x_addrs(1:lsize) = -9999
  4946   do g=2,
size(xmap%grids(:))
  4947     if (grid_id==xmap%grids(g)%id)    &
  4949                        'put_to_xgrid_ug expects a 2D side 2 grid', fatal)
  4952   call error_mesg (
'xgrid_mod', 
'put_to_xgrid_ug: could not find grid id', fatal)
  4966   real, 
dimension(:,:), 
intent(in   ) :: d
  4967   character(len=3),     
intent(in   ) :: grid_id
  4968   real, 
dimension(:),   
intent(inout) :: x
  4973   if (grid_id==xmap%grids(1)%id) &
  4975                      'put_to_xgrid_ug expects a 2D side 1 grid', fatal)
  4977   do g=2,
size(xmap%grids(:))
  4978     if (grid_id==xmap%grids(g)%id) 
then  4984   call error_mesg (
'xgrid_mod', 
'put_to_xgrid_ug: could not find grid id', fatal)
  4998   real, 
dimension(:,:), 
intent(  out) :: d
  4999   character(len=3),     
intent(in   ) :: grid_id
  5000   real, 
dimension(:),   
intent(in   ) :: x
  5005   if (grid_id==xmap%grids(1)%id) &
  5007                      'get_from_xgrid_ug expects a 2D side 1 grid', fatal)
  5009   do g=2,
size(xmap%grids(:))
  5010     if (grid_id==xmap%grids(g)%id) 
then  5016   call error_mesg (
'xgrid_mod', 
'get_from_xgrid_ug: could not find grid id', fatal)
  5025   integer(LONG_KIND), 
dimension(:), 
intent(in) :: d_addrs
  5026   integer(LONG_KIND), 
dimension(:), 
intent(in) :: x_addrs
  5028   integer,                          
intent(in) :: dsize, xsize, lsize
  5030   integer                         :: i, j, p, buffer_pos, msgsize
  5031   integer                         :: from_pe, to_pe, pos, n, l, count
  5032   integer                         :: ibegin, istart, iend, start_pos
  5033   type(
comm_type), 
pointer, 
save :: comm =>null()
  5034   real                            :: recv_buffer(xmap%put1%recvsize*lsize)
  5035   real                            :: send_buffer(xmap%put1%sendsize*lsize)
  5036   real                            :: unpack_buffer(xmap%put1%recvsize)
  5038   real, 
dimension(dsize)   :: d
  5039   real, 
dimension(xsize)   :: x
  5048   do p = 1, comm%nrecv
  5049      msgsize = comm%recv(p)%count*lsize
  5050      from_pe = comm%recv(p)%pe
  5051      buffer_pos = comm%recv(p)%buffer_pos*lsize
  5052      call mpp_recv(recv_buffer(buffer_pos+1), glen=msgsize, from_pe = from_pe, block=.false., tag=comm_tag_7)
  5057   do p = 1, comm%nsend
  5058      msgsize = comm%send(p)%count*lsize
  5059      to_pe = comm%send(p)%pe
  5063         do n = 1, comm%send(p)%count
  5065            lll = comm%send(p)%i(n)
  5066            send_buffer(pos) = d(lll)
  5069      call mpp_send(send_buffer(buffer_pos+1), plen=msgsize, to_pe = to_pe, tag=comm_tag_7 )
  5070      buffer_pos = buffer_pos + msgsize
  5073   call mpp_sync_self(
check=event_recv)
  5076   if( lsize == 1) 
then  5078      do l=1,xmap%size_put1
  5079         x(l) =  recv_buffer(xmap%x1_put(l)%pos)
  5087         do p = 1, comm%nrecv
  5088            count = comm%recv(p)%count
  5089            ibegin = comm%recv(p)%buffer_pos*lsize + 1
  5090            istart = ibegin + (l-1)*count
  5091            iend = istart + count - 1
  5092            pos = comm%recv(p)%buffer_pos
  5095               unpack_buffer(pos) = recv_buffer(n)
  5098         do i=1,xmap%size_put1
  5099            x(i) =  unpack_buffer(xmap%x1_put(i)%pos)
  5104   call mpp_sync_self()
  5114 real, 
dimension(grid%ls_me:grid%le_me, grid%km), 
intent(in) :: d
  5115 real, 
dimension(:    ), 
intent(inout) :: x
  5121   do l=grid%first,grid%last
  5122     x(l) = d(xmap%x2(l)%l,xmap%x2(l)%k)
  5130   integer(LONG_KIND), 
dimension(:), 
intent(in) :: d_addrs
  5131   integer(LONG_KIND), 
dimension(:), 
intent(in) :: x_addrs
  5133   integer,                          
intent(in) :: isize, xsize, lsize
  5135   real, 
dimension(xmap%size), 
target :: dg(xmap%size, lsize)
  5136   integer                            :: i, j, l, p, n, m
  5137   integer                            :: msgsize, buffer_pos, pos
  5138   integer                            :: istart, iend, count
  5139   real              , 
pointer, 
save  :: dgp =>null()
  5140   type(
grid_type) , 
pointer, 
save  :: grid1 =>null()
  5141   type(
comm_type) , 
pointer, 
save  :: comm  =>null()
  5142   type(overlap_type), 
pointer, 
save  :: send => null()
  5143   type(overlap_type), 
pointer, 
save  :: recv => null()
  5144   real                               :: recv_buffer(xmap%get1%recvsize*lsize*3)
  5145   real                               :: send_buffer(xmap%get1%sendsize*lsize*3)
  5146   real                               :: unpack_buffer(xmap%get1%recvsize*3)
  5148   real, 
dimension(xsize)             :: x
  5155   grid1 => xmap%grids(1)
  5157   do p = 1, comm%nrecv
  5158      recv => comm%recv(p)
  5159      msgsize = recv%count*lsize
  5160      buffer_pos = recv%buffer_pos*lsize
  5161      call mpp_recv(recv_buffer(buffer_pos+1), glen=msgsize, from_pe = recv%pe, block=.false., tag=comm_tag_9)
  5169         dgp => dg(xmap%x1(i)%pos,l)
  5170         dgp =  dgp + xmap%x1(i)%area*x(i)
  5178   do p = 1, comm%nsend
  5179      send => comm%send(p)
  5180      msgsize = send%count*lsize
  5182      istart = send%buffer_pos+1
  5183      iend = istart + send%count - 1
  5187            send_buffer(pos) = dg(n,l)
  5190      call mpp_send(send_buffer(buffer_pos+1), plen=msgsize, to_pe = send%pe, tag=comm_tag_9 )
  5191      buffer_pos = buffer_pos + msgsize
  5195   call mpp_sync_self(
check=event_recv)
  5204   do p = 1, comm%nrecv
  5205      recv => comm%recv(p)
  5207      buffer_pos = recv%buffer_pos*lsize
  5208      if( recv%pe == xmap%me ) 
then  5212            pos = buffer_pos + (l-1)*count
  5217               d(i) = recv_buffer(pos) 
  5225   do m = 1, comm%nrecv
  5226      p = comm%unpack_ind(m)
  5227      recv => comm%recv(p)
  5228      if( recv%pe == xmap%me ) 
then  5231      buffer_pos = recv%buffer_pos*lsize
  5235         pos = buffer_pos + (l-1)*recv%count
  5237         do n = 1, recv%count
  5240            d(i) = d(i) + recv_buffer(pos) 
  5251      d = d * grid1%area_inv(:,1)
  5253   call mpp_sync_self()
  5261   integer(LONG_KIND), 
dimension(:), 
intent(in) :: d_addrs
  5262   integer(LONG_KIND), 
dimension(:), 
intent(in) :: x_addrs
  5264   integer,                          
intent(in) :: xsize, lsize
  5266   integer                            :: g, i, j, k, p, l, n, l2, m, l3
  5267   integer                            :: msgsize, buffer_pos, pos
  5268   type(
grid_type), 
pointer, 
save :: grid =>null()
  5269   type(comm_type),  
pointer, 
save :: comm => null()
  5270   type(overlap_type), 
pointer, 
save  :: send => null()
  5271   type(overlap_type), 
pointer, 
save  :: recv => null()
  5272     integer,  
dimension(0:xmap%npes-1) :: pl, ml
  5273   real                               :: recv_buffer(xmap%recv_count_repro_tot*lsize)
  5274   real                               :: send_buffer(xmap%send_count_repro_tot*lsize)
  5275   real                               :: d(xmap%grids(1)%ls_me:xmap%grids(1)%le_me)
  5276   real, 
dimension(xsize)             :: x
  5281   comm => xmap%get1_repro
  5283   do p = 1, comm%nrecv
  5284      recv => comm%recv(p)
  5285      msgsize = recv%count*lsize
  5286      buffer_pos = recv%buffer_pos*lsize
  5287      call mpp_recv(recv_buffer(buffer_pos+1), glen=msgsize, from_pe = recv%pe, block=.false., tag=comm_tag_10)
  5288      n = recv%pe -xmap%root_pe
  5294   send_buffer(:) = 0.0
  5297   do p = 1, comm%nsend
  5298      pos = comm%send(p)%buffer_pos*lsize
  5299      send => comm%send(p)
  5302         do n = 1, send%count
  5308            do k =1, xmap%grids(g)%km
  5309              if(xmap%grids(g)%frac_area(i,j,k)/=0.0) 
then  5311               send_buffer(pos) = send_buffer(pos) + xmap%x1(l2)%area *x(l2)
  5319      buffer_pos = comm%send(p)%buffer_pos*lsize
  5320      msgsize = comm%send(p)%count*lsize
  5321      call mpp_send(send_buffer(buffer_pos+1), plen=msgsize, to_pe=comm%send(p)%pe, tag=comm_tag_10)
  5329   call mpp_sync_self(
check=event_recv)
  5335      do g=2,
size(xmap%grids(:))
  5336         grid => xmap%grids(g)
  5337         do l3=1,grid%size_repro 
  5338            i = grid%x_repro(l3)%l1
  5339            p = grid%x_repro(l3)%pe-xmap%root_pe
  5340            pos = pl(p) + (l-1)*ml(p) + grid%x_repro(l3)%recv_pos
  5341            d(i) = d(i) + recv_buffer(pos)
  5345      d = d * xmap%grids(1)%area_inv(:,1)
  5348   call mpp_sync_self()       
  5358 real, 
dimension(grid%ls_me:grid%le_me, grid%km), 
intent(out) :: d
  5359 real, 
dimension(:),     
intent(in   ) :: x
  5367   do l=grid%first_get,grid%last_get
  5368     d(xmap%x2_get(l)%l,xmap%x2_get(l)%k) = &
  5369             d(xmap%x2_get(l)%l,xmap%x2_get(l)%k) + xmap%x2_get(l)%area*x(xmap%x2_get(l)%pos)
  5375     d(:,k) = d(:,k) * grid%area_inv(:,1)
  5384   integer,          
intent(in) :: i, j
  5389      g = (j-1)*grid%ni + i
  5392      in_box_me = (i>=grid%is_me) .and. (i<=grid%ie_me) .and. (j>=grid%js_me) .and. (j<=grid%je_me)
  5399   integer,          
intent(in) :: i, j, p
  5404      g = (j-1)*grid%ni + i
  5407      in_box_nbr = (i>=grid%is(p)) .and. (i<=grid%ie(p)) .and. (j>=grid%js(p)) .and. (j<=grid%je(p))
  5446   type(
xmap_type)  :: xmap_sfc, xmap_runoff
  5447   integer          :: npes, pe, root, i, nx, ny, ier
  5448   integer          :: patm_beg, patm_end, pocn_beg, pocn_end
  5449   integer          :: is, ie, js, je, km, index_ice, index_lnd
  5450   integer          :: layout(2)
  5452        &                    Lnd_stock(NELEMS), Ocn_stock(NELEMS)
  5453   type(
domain2d)   :: atm_domain, ice_domain, lnd_domain, ocn_domain
  5454   logical, 
pointer :: maskmap(:,:)
  5455   real, 
allocatable :: data2d(:,:), data3d(:,:,:)
  5456   real              :: dt, dq_tot_atm, dq_tot_ice, dq_tot_lnd, dq_tot_ocn
  5464   root   = mpp_root_pe()
  5466   patm_end = npes/2 - 1
  5467   pocn_beg = patm_end + 1
  5470   if(npes /= 30) 
call mpp_error(fatal,
'must run unit test on 30 pes')
  5472   call mpp_domains_init 
  5474   call mpp_declare_pelist( (/ (i, i=patm_beg, patm_end) /), 
'atm_lnd_ice pes' ) 
  5475   call mpp_declare_pelist( (/ (i, i=pocn_beg, pocn_end) /), 
'ocn pes' ) 
  5484      call mpp_set_current_pelist( (/ (i, i=patm_beg, patm_end) /) )
  5491           & xflags = cyclic_global_domain, name = 
'LAND MODEL' )
  5506      call setup_xmap(xmap_sfc, (/ 
'ATM', 
'OCN', 
'LND' /), &
  5507           &                    (/ atm_domain, ice_domain, lnd_domain /), &
  5508           &                    
"INPUT/grid_spec.nc")
  5519      call get_index_range(xmap=xmap_sfc, grid_index=i, is=is, ie=ie, js=js, je=je, km=km)
  5521      allocate(data3d(is:ie, js:je, km))
  5522      data3d(:,:,1   ) = 1.0/(4.0*
pi)
  5523      data3d(:,:,2:km) = 0.0
  5525           & grid_index=i, data=data3d, xmap=xmap_sfc, &
  5533      call get_index_range(xmap=xmap_sfc, grid_index=i, is=is, ie=ie, js=js, je=je, km=km)
  5535      allocate(data3d(is:ie, js:je, km))
  5536      data3d(:,:,1   ) = 1.0/(4.0*
pi)
  5537      data3d(:,:,2:km) = 0.0
  5539           & grid_index=i, data=data3d, xmap=xmap_sfc, &
  5545      call mpp_set_current_pelist( (/ (i, i=pocn_beg, pocn_end) /) )
  5559   if( pe < pocn_beg ) 
then   5561      call get_index_range(xmap=xmap_sfc, grid_index=i, is=is, ie=ie, js=js, je=je, km=km)
  5563      allocate(data3d(is:ie, js:je, km))
  5564      data3d(:,:,1   ) = 1.0/(4.0*
pi)
  5565      data3d(:,:,2:km) = 0.0
  5572      allocate(data3d(is:ie, js:je, km))
  5576        & grid_index=i, data=data3d(:,:,1), xmap=xmap_sfc, &
  5595      write(*,
'(a,4f10.7,a,e10.2)') 
' Total delta_q(water) Atm/Lnd/Ice/Ocn: ', &
  5596           & dq_tot_atm, dq_tot_lnd, dq_tot_ice, dq_tot_ocn, &
  5597           & 
' residue: ', dq_tot_atm + dq_tot_lnd + dq_tot_ice + dq_tot_ocn
  5604 
subroutine, public get_mosaic_contact(mosaic_file, tile1, tile2, istart1, iend1, jstart1, jend1, istart2, iend2, jstart2, jend2)
real, parameter, public radius
Radius of the Earth [m]. 
subroutine get_1_from_xgrid_ug_repro(d_addrs, x_addrs, xmap, xsize, lsize)
subroutine put_2_to_xgrid_ug(d, grid, x, xmap)
subroutine load_xgrid(xmap, grid, grid_file, grid1_id, grid_id, tile1, tile2, use_higher_order)
integer id_put_1_to_xgrid_order_2
character(len=64) interp_method
real function, dimension(3) conservation_check_ug_side1(d, grid_id, xmap, remap_method)
subroutine put_1_to_xgrid_order_2(d_addrs, x_addrs, xmap, isize, jsize, xsize, lsize)
logical make_exchange_reproduce
real, dimension(:,:), allocatable, public area_atm_model
logical monotonic_exchange
subroutine check(action, status)
real(kind=kind_real), parameter g
gravity (m^2 s^{-2}) 
integer id_put_1_to_xgrid_order_1
subroutine get_2_from_xgrid_ug(d, grid, x, xmap)
subroutine stock_move_2d(from, to, grid_index, data, xmap, delta_t, from_side, to_side, radius, verbose, ier)
real, dimension(:,:), allocatable, public area_ocn_sphere
integer, parameter, public istock_heat
integer, parameter, public istock_bottom
integer function, public get_mosaic_ntiles(mosaic_file)
integer id_put_2_to_xgrid
subroutine get_area_elements(file, name, domain, data)
character(len=12), dimension(nelems), parameter stock_units
subroutine, public get_ocean_model_area_elements(domain, grid_file)
integer id_get_1_from_xgrid_repro
subroutine put_side2_to_xgrid_ug(d, grid_id, x, xmap)
integer function, public check_nml_error(IOSTAT, NML_NAME)
integer, parameter, public first_order
integer, parameter, public istock_top
integer, parameter, public nelems
subroutine, public get_mosaic_grid_sizes(mosaic_file, nx, ny)
real, dimension(:,:), allocatable area_lnd_model
integer, parameter, public second_order
integer, parameter, public istock_side
subroutine get_side1_from_xgrid(d, grid_id, x, xmap, complete)
character(len=input_str_length), dimension(:), allocatable, target, public input_nml_file
integer function get_nest_contact(mosaic_file, tile_nest_out, tile_parent_out, is_nest_out, ie_nest_out, js_nest_out, je_nest_out, is_parent_out, ie_parent_out, js_parent_out, je_parent_out)
subroutine, public get_mosaic_xgrid(xgrid_file, i1, j1, i2, j2, area, ibegin, iend)
subroutine set_frac_area_sg(f, grid_id, xmap)
subroutine put_side2_to_xgrid(d, grid_id, x, xmap)
real, dimension(:,:), allocatable, public area_ocn_model
integer, public stocks_file
subroutine get_1_from_xgrid(d_addrs, x_addrs, xmap, isize, jsize, xsize, lsize)
int field_exist(const char *file, const char *name)
subroutine, public fms_init(localcomm)
real function, dimension(is:ie, js:je) grad_merid_latlon(d, lat, is, ie, js, je, isd, jsd)
subroutine, public stock_print(stck, Time, comp_name, index, ref_value, radius, pelist)
subroutine put_side1_to_xgrid_ug(d, grid_id, x, xmap, complete)
subroutine stock_move_3d(from, to, grid_index, data, xmap, delta_t, from_side, to_side, radius, verbose, ier)
subroutine get_side1_from_xgrid_ug(d, grid_id, x, xmap, complete)
logical function in_box(i, j, is, ie, js, je)
logical function in_box_me(i, j, grid)
subroutine get_2_from_xgrid(d, grid, x, xmap)
integer id_get_1_from_xgrid
logical function is_lat_lon(lon, lat)
subroutine put_1_to_xgrid_ug_order_1(d_addrs, x_addrs, xmap, dsize, xsize, lsize)
subroutine, public stock_integrate_2d(data, xmap, delta_t, radius, res, ier)
subroutine, public get_index_range(xmap, grid_index, is, ie, js, je, km)
real function, dimension(is:ie, js:je) grad_zonal_latlon(d, lon, lat, is, ie, js, je, isd, jsd)
integer, parameter version1
character(len=5), dimension(nelems), parameter stock_names
real function, dimension(3) conservation_check_side1(d, grid_id, xmap, remap_method)
integer function, public get_mosaic_ncontacts(mosaic_file)
subroutine, public setup_xmap(xmap, grid_ids, grid_domains, grid_file, atm_grid, lnd_ug_domain)
integer, parameter, public istock_water
integer id_get_2_from_xgrid
subroutine get_side2_from_xgrid_ug(d, grid_id, x, xmap)
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************subroutine READ_RECORD_CORE_(unit, field, nwords, data, start, axsiz) integer, intent(in) ::unit type(fieldtype), intent(in) ::field integer, intent(in) ::nwords MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in) ::start(:), axsiz(:) integer(SHORT_KIND) ::i2vals(nwords)!rab used in conjunction with transfer intrinsic to determine size of a variable integer(KIND=1) ::one_byte(8) integer ::word_sz!#ifdef __sgi integer(INT_KIND) ::ivals(nwords) real(FLOAT_KIND) ::rvals(nwords)!#else! integer ::ivals(nwords)! real ::rvals(nwords)!#endif real(DOUBLE_KIND) ::r8vals(nwords) pointer(ptr1, i2vals) pointer(ptr2, ivals) pointer(ptr3, rvals) pointer(ptr4, r8vals) if(mpp_io_stack_size< nwords) call mpp_io_set_stack_size(nwords) call mpp_error(FATAL, 'MPP_READ currently requires use_netCDF option') end subroutine READ_RECORD_CORE_ subroutine READ_RECORD_(unit, field, nwords, data, time_level, domain, position, tile_count, start_in, axsiz_in)!routine that is finally called by all mpp_read routines to perform the read!a non-netCDF record contains:! field ID! a set of 4 coordinates(is:ie, js:je) giving the data subdomain! a timelevel and a timestamp(=NULLTIME if field is static)! 3D real data(stored as 1D)!if you are using direct access I/O, the RECL argument to OPEN must be large enough for the above!in a global direct access file, record position on PE is given by %record.!Treatment of timestamp:! We assume that static fields have been passed without a timestamp.! Here that is converted into a timestamp of NULLTIME.! For non-netCDF fields, field is treated no differently, but is written! with a timestamp of NULLTIME. There is no check in the code to prevent! the user from repeatedly writing a static field. integer, intent(in) ::unit, nwords type(fieldtype), intent(in) ::field MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in), optional ::time_level type(domain2D), intent(in), optional ::domain integer, intent(in), optional ::position, tile_count integer, intent(in), optional ::start_in(:), axsiz_in(:) integer, dimension(size(field%axes(:))) ::start, axsiz integer ::tlevel !, subdomain(4) integer ::i, error, is, ie, js, je, isg, ieg, jsg, jeg type(domain2d), pointer ::io_domain=> tlevel if(PRESENT(start_in) .AND. PRESENT(axsiz_in)) then if(size(start(! the data domain and compute domain must refer to the subdomain being passed ! In this ! since that attempts to gather all data on PE size(field%axes(:)) axsiz(i)
integer id_conservation_check
real, parameter large_number
subroutine get_side2_from_xgrid(d, grid_id, x, xmap)
logical module_is_initialized
subroutine get_1_from_xgrid_repro(d_addrs, x_addrs, xmap, xsize, lsize)
subroutine put_side1_to_xgrid(d, grid_id, x, xmap, remap_method, complete)
subroutine set_comm_put1(xmap)
subroutine put_1_to_xgrid_order_1(d_addrs, x_addrs, xmap, isize, jsize, xsize, lsize)
integer function, public xgrid_count(xmap)
subroutine, public gradient_cubic(pin, dx, dy, area, edge_w, edge_e, edge_s, edge_n, en_n, en_e, vlon, vlat, grad_x, grad_y, on_west_edge, on_east_edge, on_south_edge, on_north_edge)
integer function, public get_mosaic_xgrid_size(xgrid_file)
logical function in_box_nbr(i, j, grid, p)
real function, dimension(3) conservation_check_ug_side2(d, grid_id, xmap, remap_method)
integer, parameter version2
real, dimension(:,:), allocatable area_lnd_sphere
subroutine, public get_time(Time, seconds, days, ticks, err_msg)
subroutine, public xgrid_init(remap_method)
subroutine, public error_mesg(routine, message, level)
subroutine, public some(xmap, some_arr, grid_id)
subroutine, public get_xmap_grid_area(id, xmap, area)
subroutine set_comm_get1_repro(xmap)
integer, parameter max_fields
subroutine set_comm_get1(xmap)
real function, dimension(3) conservation_check_side2(d, grid_id, xmap, remap_method)
subroutine get_1_from_xgrid_ug(d_addrs, x_addrs, xmap, isize, xsize, lsize)
real, dimension(:,:), allocatable, public area_atm_sphere
subroutine stock_move_ug_3d(from, to, grid_index, data, xmap, delta_t, from_side, to_side, radius, verbose, ier)
subroutine put_2_to_xgrid(d, grid, x, xmap)
subroutine, public set_frac_area_ug(f, grid_id, xmap)
real(fp), parameter, public pi