15 use atlas_module, 
only: atlas_field, atlas_fieldset, atlas_real, atlas_functionspace_pointcloud
 
   18 use fckit_mpi_module,           
only: fckit_mpi_comm
 
   19 use fckit_configuration_module, 
only: fckit_configuration
 
   22 use fms_io_mod,                 
only: fms_io_init, fms_io_exit
 
   23 use fms_mod,                    
only: fms_init
 
   24 use mpp_mod,                    
only: mpp_init, mpp_exit, mpp_pe, mpp_npes, mpp_error, fatal, note
 
   25 use mpp_domains_mod,            
only: domain2d, mpp_deallocate_domain, mpp_domains_init, &
 
   26                                       mpp_define_layout, mpp_define_mosaic, mpp_define_io_domain, &
 
   27                                       mpp_domains_exit, mpp_domains_set_stack_size
 
   30 use fv_arrays_mod,              
only: fv_atmos_type, deallocate_fv_atmos_type
 
   47   integer :: isd, ied, jsd, jed                                                     
 
   48   integer :: isc, iec, jsc, jec                                                     
 
   49   integer :: npx,npy,npz,ngrid                                                      
 
   50   integer :: layout(2), io_layout(2)                                                
 
   51   integer :: ntile, ntiles                                                          
 
   53   type(domain2d) :: domain_fix                                                      
 
   54   type(domain2d), 
pointer :: domain                                                 
 
   55   character(len=10) :: interp_method                                                
 
   56   real(kind=
kind_real), 
allocatable, 
dimension(:)       :: ak, bk                   
 
   57   real(kind=
kind_real), 
allocatable, 
dimension(:,:)     :: grid_lon, grid_lat       
 
   58   real(kind=
kind_real), 
allocatable, 
dimension(:,:)     :: egrid_lon, egrid_lat     
 
   59   real(kind=
kind_real), 
allocatable, 
dimension(:)       :: lon_us, lat_us           
 
   60   real(kind=
kind_real), 
allocatable, 
dimension(:,:)     :: area                     
 
   61   real(kind=
kind_real), 
allocatable, 
dimension(:,:)     :: dx, dy                   
 
   62   real(kind=
kind_real), 
allocatable, 
dimension(:,:)     :: dxc, dyc                 
 
   63   real(kind=
kind_real), 
allocatable, 
dimension(:,:,:)   :: grid, vlon, vlat
 
   64   real(kind=
kind_real), 
allocatable, 
dimension(:)       :: edge_vect_n, edge_vect_e
 
   65   real(kind=
kind_real), 
allocatable, 
dimension(:)       :: edge_vect_s, edge_vect_w
 
   66   real(kind=
kind_real), 
allocatable, 
dimension(:,:,:,:) :: es, ew
 
   67   real(kind=
kind_real), 
allocatable, 
dimension(:,:)     :: a11, a12, a21, a22
 
   68   type(fckit_mpi_comm) :: f_comm
 
   71   real(kind=
kind_real), 
allocatable, 
dimension(:,:)     :: rarea
 
   72   real(kind=
kind_real), 
allocatable, 
dimension(:,:,:)   :: sin_sg
 
   73   real(kind=
kind_real), 
allocatable, 
dimension(:,:)     :: cosa_u
 
   74   real(kind=
kind_real), 
allocatable, 
dimension(:,:)     :: cosa_v
 
   75   real(kind=
kind_real), 
allocatable, 
dimension(:,:)     :: cosa_s
 
   76   real(kind=
kind_real), 
allocatable, 
dimension(:,:)     :: rsin_u
 
   77   real(kind=
kind_real), 
allocatable, 
dimension(:,:)     :: rsin_v
 
   78   real(kind=
kind_real), 
allocatable, 
dimension(:,:)     :: rsin2
 
   79   real(kind=
kind_real), 
allocatable, 
dimension(:,:)     :: dxa, dya
 
   80   logical :: ne_corner, se_corner, sw_corner, nw_corner
 
   81   logical :: nested = .false.
 
   82   integer :: grid_type = 0
 
   83   logical :: dord4 = .true.
 
   84   type(atlas_functionspace_pointcloud) :: afunctionspace
 
  101 type(fckit_configuration), 
intent(in) :: conf
 
  102 type(fckit_mpi_comm),      
intent(in) :: comm
 
  105 integer :: stackmax = 4000000
 
  107 call mpp_init(localcomm=comm%communicator())
 
  108 call mpp_domains_init
 
  112 if (conf%has(
"stackmax")) 
call conf%get_or_die(
"stackmax",stackmax)
 
  114 call mpp_domains_set_stack_size(stackmax)
 
  120 subroutine create(self, conf, comm, fields)
 
  124 type(fckit_configuration),   
intent(in)    :: conf
 
  125 type(fckit_mpi_comm),        
intent(in)    :: comm
 
  129 character(len=256)                    :: file_akbk
 
  130 type(fv_atmos_type), 
allocatable      :: Atm(:)
 
  131 logical, 
allocatable                  :: grids_on_this_pe(:)
 
  132 integer                               :: i, j, jj, gtile
 
  133 integer                               :: p_split = 1
 
  134 integer                               :: ncstat, ncid, akvarid, bkvarid, readdim, dcount
 
  135 integer, 
dimension(nf90_max_var_dims) :: dimids, dimlens
 
  137 character(len=:), 
allocatable :: str
 
  138 logical :: do_write_geom = .false.
 
  146 self%interp_method = 
'barycent' 
  147 if (conf%has(
"interpolation method")) 
then 
  148   call conf%get_or_die(
"interpolation method",str)
 
  149   self%interp_method = str
 
  159 call fv_init(
atm, 300.0_kind_real, grids_on_this_pe, p_split, gtile)
 
  161 self%isd = 
atm(1)%bd%isd
 
  162 self%ied = 
atm(1)%bd%ied
 
  163 self%jsd = 
atm(1)%bd%jsd
 
  164 self%jed = 
atm(1)%bd%jed
 
  165 self%isc = 
atm(1)%bd%isc
 
  166 self%iec = 
atm(1)%bd%iec
 
  167 self%jsc = 
atm(1)%bd%jsc
 
  168 self%jec = 
atm(1)%bd%jec
 
  171 self%ntiles = 
atm(1)%flagstruct%ntiles
 
  173 self%npx = 
atm(1)%npx
 
  174 self%npy = 
atm(1)%npy
 
  175 self%npz = 
atm(1)%npz
 
  177 self%layout(1) = 
atm(1)%layout(1)
 
  178 self%layout(2) = 
atm(1)%layout(2)
 
  179 self%io_layout(1) = 
atm(1)%io_layout(1)
 
  180 self%io_layout(2) = 
atm(1)%io_layout(2)
 
  183 allocate(self%ak(self%npz+1) )
 
  184 allocate(self%bk(self%npz+1) )
 
  186 allocate(self%grid_lon   (self%isd  :self%ied,  self%jsd  :self%jed  ))
 
  187 allocate(self%grid_lat   (self%isd  :self%ied,  self%jsd  :self%jed  ))
 
  188 allocate(self%egrid_lon  (self%isd  :self%ied+1,self%jsd  :self%jed+1))
 
  189 allocate(self%egrid_lat  (self%isd  :self%ied+1,self%jsd  :self%jed+1))
 
  190 allocate(self%area       (self%isd  :self%ied,  self%jsd  :self%jed  ))
 
  191 allocate(self%dx         (self%isd  :self%ied  ,self%jsd  :self%jed+1))
 
  192 allocate(self%dy         (self%isd  :self%ied+1,self%jsd  :self%jed  ))
 
  193 allocate(self%dxc        (self%isd  :self%ied+1,self%jsd  :self%jed  ))
 
  194 allocate(self%dyc        (self%isd  :self%ied  ,self%jsd  :self%jed+1))
 
  196 allocate(self%grid       (self%isd  :self%ied+1,self%jsd  :self%jed+1,2))
 
  197 allocate(self%vlon       (self%isc-2:self%iec+2,self%jsc-2:self%jec+2,3))
 
  198 allocate(self%vlat       (self%isc-2:self%iec+2,self%jsc-2:self%jec+2,3))
 
  200 allocate(self%edge_vect_n(self%isd:self%ied))
 
  201 allocate(self%edge_vect_e(self%jsd:self%jed))
 
  202 allocate(self%edge_vect_s(self%isd:self%ied))
 
  203 allocate(self%edge_vect_w(self%jsd:self%jed))
 
  205 allocate(self%es(3,self%isd:self%ied  ,self%jsd:self%jed+1,2))
 
  206 allocate(self%ew(3,self%isd:self%ied+1,self%jsd:self%jed,  2))
 
  208 allocate(self%a11(self%isc-1:self%iec+1,self%jsc-1:self%jec+1) )
 
  209 allocate(self%a12(self%isc-1:self%iec+1,self%jsc-1:self%jec+1) )
 
  210 allocate(self%a21(self%isc-1:self%iec+1,self%jsc-1:self%jec+1) )
 
  211 allocate(self%a22(self%isc-1:self%iec+1,self%jsc-1:self%jec+1) )
 
  213 allocate(self%rarea (self%isd:self%ied  ,self%jsd:self%jed  ))
 
  214 allocate(self%sin_sg(self%isd:self%ied  ,self%jsd:self%jed  ,9))
 
  215 allocate(self%cosa_u(self%isd:self%ied+1,self%jsd:self%jed  ))
 
  216 allocate(self%cosa_v(self%isd:self%ied  ,self%jsd:self%jed+1))
 
  217 allocate(self%cosa_s(self%isd:self%ied  ,self%jsd:self%jed  ))
 
  218 allocate(self%rsin_u(self%isd:self%ied+1,self%jsd:self%jed  ))
 
  219 allocate(self%rsin_v(self%isd:self%ied  ,self%jsd:self%jed+1))
 
  220 allocate(self%rsin2 (self%isd:self%ied  ,self%jsd:self%jed  ))
 
  221 allocate(self%dxa   (self%isd:self%ied  ,self%jsd:self%jed  ))
 
  222 allocate(self%dya   (self%isd:self%ied  ,self%jsd:self%jed  ))
 
  226 if (self%npz > 1) 
then 
  229   call conf%get_or_die(
"akbk",str)
 
  233   call nccheck ( nf90_open(file_akbk, nf90_nowrite, ncid), 
"nf90_open "//file_akbk )
 
  236   ncstat = nf90_inq_varid(ncid, 
"ak", akvarid)
 
  237   if(ncstat /= nf90_noerr) 
call abor1_ftn(
"Failed to find ak in file "//file_akbk)
 
  240   ncstat = nf90_inq_varid(ncid, 
"bk", bkvarid)
 
  241   if(ncstat /= nf90_noerr) 
call abor1_ftn(
"Failed to find bk in file "//file_akbk)
 
  245   call nccheck ( nf90_inquire_variable(ncid, akvarid, dimids = dimids), 
"nf90_inq_var ak" )
 
  248   do i = 1,nf90_max_var_dims
 
  249     if (dimids(i) > 0) 
then 
  250        call nccheck( nf90_inquire_dimension(ncid, dimids(i), len = dimlens(i)), &
 
  251                      "nf90_inquire_dimension" )
 
  252        if (dimlens(i) == self%npz+1) 
then 
  258   if (readdim == -1) 
call abor1_ftn(
"ak/bk in file does not match dimension of npz from input.nml")
 
  261   call nccheck( nf90_get_var(ncid, akvarid, self%ak), 
"fv3jedi_geom, nf90_get_var ak" )
 
  262   call nccheck( nf90_get_var(ncid, bkvarid, self%bk), 
"fv3jedi_geom, nf90_get_var bk" )
 
  264   self%ak = 0.0_kind_real
 
  265   self%bk = 0.0_kind_real
 
  271 self%grid_lon  = real(
atm(1)%gridstruct%agrid_64(:,:,1),
kind_real)
 
  272 self%grid_lat  = real(
atm(1)%gridstruct%agrid_64(:,:,2),
kind_real)
 
  273 self%egrid_lon = real(
atm(1)%gridstruct%grid_64(:,:,1),
kind_real)
 
  274 self%egrid_lat = real(
atm(1)%gridstruct%grid_64(:,:,2),
kind_real)
 
  285 self%edge_vect_n = real(
atm(1)%gridstruct%edge_vect_n,
kind_real)
 
  286 self%edge_vect_e = real(
atm(1)%gridstruct%edge_vect_e,
kind_real)
 
  287 self%edge_vect_s = real(
atm(1)%gridstruct%edge_vect_s,
kind_real)
 
  288 self%edge_vect_w = real(
atm(1)%gridstruct%edge_vect_w,
kind_real)
 
  308 self%ne_corner = 
atm(1)%gridstruct%ne_corner
 
  309 self%se_corner = 
atm(1)%gridstruct%se_corner
 
  310 self%sw_corner = 
atm(1)%gridstruct%sw_corner
 
  311 self%nw_corner = 
atm(1)%gridstruct%nw_corner
 
  314 self%ngrid = (self%iec-self%isc+1)*(self%jec-self%jsc+1)
 
  315 allocate(self%lat_us(self%ngrid))
 
  316 allocate(self%lon_us(self%ngrid))
 
  319 do j = self%jsc,self%jec
 
  320   do i = self%isc,self%iec
 
  322      self%lat_us(jj) = self%grid_lat(i,j)
 
  323      self%lon_us(jj) = self%grid_lon(i,j)
 
  328 self%ptop = self%ak(1)
 
  331 call deallocate_fv_atmos_type(
atm(1))
 
  333 deallocate(grids_on_this_pe)
 
  336 call setup_domain( self%domain_fix, self%npx-1, self%npy-1, &
 
  337                    self%ntiles, self%layout, self%io_layout, 3)
 
  339 self%domain => self%domain_fix
 
  343 if (conf%has(
"do_write_geom")) 
then 
  344   call conf%get_or_die(
"do_write_geom",do_write_geom)
 
  347 if (do_write_geom) 
then 
  355 subroutine clone(self, other, fields)
 
  361 allocate(self%ak(other%npz+1) )
 
  362 allocate(self%bk(other%npz+1) )
 
  364 allocate(self%grid_lon   (other%isd  :other%ied,  other%jsd  :other%jed  ))
 
  365 allocate(self%grid_lat   (other%isd  :other%ied,  other%jsd  :other%jed  ))
 
  366 allocate(self%egrid_lon  (other%isd  :other%ied+1,other%jsd  :other%jed+1))
 
  367 allocate(self%egrid_lat  (other%isd  :other%ied+1,other%jsd  :other%jed+1))
 
  368 allocate(self%area       (other%isd  :other%ied,  other%jsd  :other%jed  ))
 
  369 allocate(self%dx         (other%isd  :other%ied  ,other%jsd  :other%jed+1))
 
  370 allocate(self%dy         (other%isd  :other%ied+1,other%jsd  :other%jed  ))
 
  371 allocate(self%dxc        (other%isd  :other%ied+1,other%jsd  :other%jed  ))
 
  372 allocate(self%dyc        (other%isd  :other%ied  ,other%jsd  :other%jed+1))
 
  374 allocate(self%grid       (other%isd  :other%ied+1,other%jsd  :other%jed+1,2))
 
  375 allocate(self%vlon       (other%isc-2:other%iec+2,other%jsc-2:other%jec+2,3))
 
  376 allocate(self%vlat       (other%isc-2:other%iec+2,other%jsc-2:other%jec+2,3))
 
  378 allocate(self%edge_vect_n(other%isd:other%ied))
 
  379 allocate(self%edge_vect_e(other%jsd:other%jed))
 
  380 allocate(self%edge_vect_s(other%isd:other%ied))
 
  381 allocate(self%edge_vect_w(other%jsd:other%jed))
 
  383 allocate(self%es(3,other%isd:other%ied  ,other%jsd:other%jed+1,2))
 
  384 allocate(self%ew(3,other%isd:other%ied+1,other%jsd:other%jed,  2))
 
  386 allocate(self%a11(other%isc-1:other%iec+1,other%jsc-1:other%jec+1) )
 
  387 allocate(self%a12(other%isc-1:other%iec+1,other%jsc-1:other%jec+1) )
 
  388 allocate(self%a21(other%isc-1:other%iec+1,other%jsc-1:other%jec+1) )
 
  389 allocate(self%a22(other%isc-1:other%iec+1,other%jsc-1:other%jec+1) )
 
  391 allocate(self%rarea (other%isd:other%ied  ,other%jsd:other%jed  ))
 
  392 allocate(self%sin_sg(other%isd:other%ied  ,other%jsd:other%jed  ,9))
 
  393 allocate(self%cosa_u(other%isd:other%ied+1,other%jsd:other%jed  ))
 
  394 allocate(self%cosa_v(other%isd:other%ied  ,other%jsd:other%jed+1))
 
  395 allocate(self%cosa_s(other%isd:other%ied  ,other%jsd:other%jed  ))
 
  396 allocate(self%rsin_u(other%isd:other%ied+1,other%jsd:other%jed  ))
 
  397 allocate(self%rsin_v(other%isd:other%ied  ,other%jsd:other%jed+1))
 
  398 allocate(self%rsin2 (other%isd:other%ied  ,other%jsd:other%jed  ))
 
  399 allocate(self%dxa   (other%isd:other%ied  ,other%jsd:other%jed  ))
 
  400 allocate(self%dya   (other%isd:other%ied  ,other%jsd:other%jed  ))
 
  402 allocate(self%lat_us(other%ngrid))
 
  403 allocate(self%lon_us(other%ngrid))
 
  408 self%ngrid           = other%ngrid
 
  409 self%layout          = other%layout
 
  410 self%io_layout       = other%io_layout
 
  419 self%ntile           = other%ntile
 
  420 self%ntiles          = other%ntiles
 
  421 self%ptop            = other%ptop
 
  424 self%grid_lon        = other%grid_lon
 
  425 self%grid_lat        = other%grid_lat
 
  426 self%egrid_lon       = other%egrid_lon
 
  427 self%egrid_lat       = other%egrid_lat
 
  428 self%area            = other%area
 
  433 self%grid            = other%grid
 
  434 self%vlon            = other%vlon
 
  435 self%vlat            = other%vlat
 
  436 self%edge_vect_n     = other%edge_vect_n
 
  437 self%edge_vect_e     = other%edge_vect_e
 
  438 self%edge_vect_s     = other%edge_vect_s
 
  439 self%edge_vect_w     = other%edge_vect_w
 
  446 self%f_comm          = other%f_comm
 
  447 self%interp_method   = other%interp_method
 
  449 self%rarea     = other%rarea
 
  450 self%sin_sg    = other%sin_sg
 
  451 self%cosa_u    = other%cosa_u
 
  452 self%cosa_v    = other%cosa_v
 
  453 self%cosa_s    = other%cosa_s
 
  454 self%rsin_u    = other%rsin_u
 
  455 self%rsin_v    = other%rsin_v
 
  456 self%rsin2     = other%rsin2
 
  459 self%ne_corner = other%ne_corner
 
  460 self%se_corner = other%se_corner
 
  461 self%sw_corner = other%sw_corner
 
  462 self%nw_corner = other%nw_corner
 
  464 self%domain => other%domain
 
  466 self%afunctionspace = atlas_functionspace_pointcloud(other%afunctionspace%c_ptr())
 
  470 self%lat_us = other%lat_us
 
  471 self%lon_us = other%lon_us
 
  484 deallocate(self%grid_lon)
 
  485 deallocate(self%grid_lat)
 
  486 deallocate(self%egrid_lon)
 
  487 deallocate(self%egrid_lat)
 
  488 deallocate(self%area)
 
  493 deallocate(self%grid)
 
  494 deallocate(self%vlon)
 
  495 deallocate(self%vlat)
 
  496 deallocate(self%edge_vect_n)
 
  497 deallocate(self%edge_vect_e)
 
  498 deallocate(self%edge_vect_s)
 
  499 deallocate(self%edge_vect_w)
 
  507 deallocate(self%rarea)
 
  508 deallocate(self%sin_sg)
 
  509 deallocate(self%cosa_u)
 
  510 deallocate(self%cosa_v)
 
  511 deallocate(self%cosa_s)
 
  512 deallocate(self%rsin_u)
 
  513 deallocate(self%rsin_v)
 
  514 deallocate(self%rsin2 )
 
  515 deallocate(self%dxa   )
 
  516 deallocate(self%dya   )
 
  518 deallocate(self%lat_us)
 
  519 deallocate(self%lon_us)
 
  524 call self%afunctionspace%final()
 
  539 type(atlas_fieldset), 
intent(inout) :: afieldset
 
  542 real(kind_real), 
pointer :: real_ptr(:,:)
 
  543 type(atlas_field) :: afield
 
  546 afield = atlas_field(name=
"lonlat", kind=atlas_real(kind_real), shape=(/2,(self%iec-self%isc+1)*(self%jec-self%jsc+1)/))
 
  547 call afield%data(real_ptr)
 
  548 real_ptr(1,:) = 
rad2deg*pack(self%grid_lon(self%isc:self%iec,self%jsc:self%jec),.true.)
 
  549 real_ptr(2,:) = 
rad2deg*pack(self%grid_lat(self%isc:self%iec,self%jsc:self%jec),.true.)
 
  550 call afieldset%add(afield)
 
  560 type(atlas_fieldset), 
intent(inout) :: afieldset
 
  565 real(kind=
kind_real), 
pointer :: real_ptr_1(:), real_ptr_2(:,:)
 
  566 type(atlas_field) :: afield
 
  569 afield = self%afunctionspace%create_field(name=
'area', kind=atlas_real(
kind_real), levels=0)
 
  570 call afield%data(real_ptr_1)
 
  571 real_ptr_1 = pack(self%area(self%isc:self%iec,self%jsc:self%jec),.true.)
 
  572 call afieldset%add(afield)
 
  576 afield = self%afunctionspace%create_field(name=
'vunit', kind=atlas_real(
kind_real), levels=self%npz)
 
  577 call afield%data(real_ptr_2)
 
  579   sigmaup = self%ak(jl+1)/
ps+self%bk(jl+1) 
 
  580   sigmadn = self%ak(jl  )/
ps+self%bk(jl  )
 
  581   real_ptr_2(jl,:) = 0.5*(sigmaup+sigmadn) 
 
  583 call afieldset%add(afield)
 
  590 subroutine setup_domain(domain, nx, ny, ntiles, layout_in, io_layout, halo)
 
  592  type(domain2d),   
intent(inout) :: domain
 
  593  integer,          
intent(in)    :: nx, ny, ntiles
 
  594  integer,          
intent(in)    :: layout_in(:), io_layout(:)
 
  595  integer,          
intent(in)    :: halo
 
  597  integer                              :: pe, npes, npes_per_tile, tile
 
  598  integer                              :: num_contact, num_alloc
 
  599  integer                              :: n, layout(2)
 
  600  integer, 
allocatable, 
dimension(:,:) :: global_indices, layout2D
 
  601  integer, 
allocatable, 
dimension(:)   :: pe_start, pe_end
 
  602  integer, 
allocatable, 
dimension(:)   :: tile1, tile2
 
  603  integer, 
allocatable, 
dimension(:)   :: istart1, iend1, jstart1, jend1
 
  604  integer, 
allocatable, 
dimension(:)   :: istart2, iend2, jstart2, jend2
 
  605  integer, 
allocatable :: tile_id(:)
 
  606  logical :: is_symmetry
 
  611   if (mod(npes,ntiles) /= 0) 
then 
  612      call mpp_error(note, 
"setup_domain: npes can not be divided by ntiles")
 
  615   npes_per_tile = npes/ntiles
 
  616   tile = pe/npes_per_tile + 1
 
  618   if (layout_in(1)*layout_in(2) == npes_per_tile) 
then 
  621      call mpp_define_layout( (/1,nx,1,ny/), npes_per_tile, layout )
 
  624   if (io_layout(1) <1 .or. io_layout(2) <1) 
call mpp_error(fatal, &
 
  625           "setup_domain: both elements of variable io_layout must be positive integer")
 
  626   if (mod(layout(1), io_layout(1)) /= 0 ) 
call mpp_error(fatal, &
 
  627        "setup_domain: layout(1) must be divided by io_layout(1)")
 
  628   if (mod(layout(2), io_layout(2)) /= 0 ) 
call mpp_error(fatal, &
 
  629        "setup_domain: layout(2) must be divided by io_layout(2)")
 
  631   allocate(global_indices(4,ntiles), layout2d(2,ntiles), pe_start(ntiles), pe_end(ntiles) )
 
  640     call mpp_error(fatal, 
"setup_domain: ntiles != 1 or 6")
 
  644      global_indices(:,n) = (/1,nx,1,ny/)
 
  645      layout2d(:,n)       = layout
 
  646      pe_start(n)         = (n-1)*npes_per_tile
 
  647      pe_end(n)           = n*npes_per_tile-1
 
  649   num_alloc = max(1, num_contact)
 
  651   allocate(tile1(num_alloc), tile2(num_alloc) )
 
  652   allocate(tile_id(ntiles))
 
  653   allocate(istart1(num_alloc), iend1(num_alloc), jstart1(num_alloc), jend1(num_alloc) )
 
  654   allocate(istart2(num_alloc), iend2(num_alloc), jstart2(num_alloc), jend2(num_alloc) )
 
  661     tile1(1) = 1; tile2(1) = 2
 
  662     istart1(1) = nx; iend1(1) = nx; jstart1(1) = 1;  jend1(1) = ny
 
  663     istart2(1) = 1;  iend2(1) = 1;  jstart2(1) = 1;  jend2(1) = ny
 
  665     tile1(2) = 1; tile2(2) = 3
 
  666     istart1(2) = 1;  iend1(2) = nx; jstart1(2) = ny; jend1(2) = ny
 
  667     istart2(2) = 1;  iend2(2) = 1;  jstart2(2) = ny; jend2(2) = 1
 
  669     tile1(3) = 1; tile2(3) = 5
 
  670     istart1(3) = 1;  iend1(3) = 1;  jstart1(3) = 1;  jend1(3) = ny
 
  671     istart2(3) = nx; iend2(3) = 1;  jstart2(3) = ny; jend2(3) = ny
 
  673     tile1(4) = 1; tile2(4) = 6
 
  674     istart1(4) = 1;  iend1(4) = nx; jstart1(4) = 1;  jend1(4) = 1
 
  675     istart2(4) = 1;  iend2(4) = nx; jstart2(4) = ny; jend2(4) = ny
 
  677     tile1(5) = 2; tile2(5) = 3
 
  678     istart1(5) = 1;  iend1(5) = nx; jstart1(5) = ny; jend1(5) = ny
 
  679     istart2(5) = 1;  iend2(5) = nx; jstart2(5) = 1;  jend2(5) = 1
 
  681     tile1(6) = 2; tile2(6) = 4
 
  682     istart1(6) = nx; iend1(6) = nx; jstart1(6) = 1;  jend1(6) = ny
 
  683     istart2(6) = nx; iend2(6) = 1;  jstart2(6) = 1;  jend2(6) = 1
 
  685     tile1(7) = 2; tile2(7) = 6
 
  686     istart1(7) = 1;  iend1(7) = nx; jstart1(7) = 1;  jend1(7) = 1
 
  687     istart2(7) = nx; iend2(7) = nx; jstart2(7) = ny; jend2(7) = 1
 
  689     tile1(8) = 3; tile2(8) = 4
 
  690     istart1(8) = nx; iend1(8) = nx; jstart1(8) = 1;  jend1(8) = ny
 
  691     istart2(8) = 1;  iend2(8) = 1;  jstart2(8) = 1;  jend2(8) = ny
 
  693     tile1(9) = 3; tile2(9) = 5
 
  694     istart1(9) = 1;  iend1(9) = nx; jstart1(9) = ny; jend1(9) = ny
 
  695     istart2(9) = 1;  iend2(9) = 1;  jstart2(9) = ny; jend2(9) = 1
 
  697     tile1(10) = 4; tile2(10) = 5
 
  698     istart1(10) = 1;  iend1(10) = nx; jstart1(10) = ny; jend1(10) = ny
 
  699     istart2(10) = 1;  iend2(10) = nx; jstart2(10) = 1;  jend2(10) = 1
 
  701     tile1(11) = 4; tile2(11) = 6
 
  702     istart1(11) = nx; iend1(11) = nx; jstart1(11) = 1;  jend1(11) = ny
 
  703     istart2(11) = nx; iend2(11) = 1;  jstart2(11) = 1;  jend2(11) = 1
 
  705     tile1(12) = 5; tile2(12) = 6
 
  706     istart1(12) = nx; iend1(12) = nx; jstart1(12) = 1;  jend1(12) = ny
 
  707     istart2(12) = 1;  iend2(12) = 1;  jstart2(12) = 1;  jend2(12) = ny
 
  714   call mpp_define_mosaic(global_indices, layout2d, domain, ntiles, num_contact, tile1, tile2, &
 
  715                          istart1, iend1, jstart1, jend1, istart2, iend2, jstart2, jend2,      &
 
  716                          pe_start, pe_end, whalo=halo, ehalo=halo, shalo=halo, nhalo=halo,    &
 
  717                          symmetry=is_symmetry, tile_id=tile_id, &
 
  720   if (io_layout(1) /= 1 .or. io_layout(2) /= 1) 
call mpp_define_io_domain(domain, io_layout)
 
  722   deallocate(pe_start, pe_end)
 
  723   deallocate(layout2d, global_indices)
 
  724   deallocate(tile1, tile2, tile_id)
 
  725   deallocate(istart1, iend1, jstart1, jend1)
 
  726   deallocate(istart2, iend2, jstart2, jend2)
 
  736   type(fckit_mpi_comm) :: f_comm
 
  737   character(len=255) :: filename
 
  738   integer :: ncid, xf_dimid, yf_dimid, xv_dimid, yv_dimid, ti_dimid, pe_dimid
 
  739   integer :: mydims(3,3), ijdims(1), ijdimf(1), tmpij(1)
 
  746   write(filename,
"(A9,I0.4,A4)") 
'fv3grid_c', self%npx-1, 
'.nc4' 
  749   call nccheck( nf90_create( trim(filename), ior(nf90_netcdf4, nf90_mpiio), ncid, &
 
  750                              comm = f_comm%communicator(), info = mpi_info_null), 
"nf90_create" )
 
  753   call nccheck ( nf90_def_dim(ncid, 
'fxdim', self%npx-1   , xf_dimid), 
"nf90_def_dim fxdim" )
 
  754   call nccheck ( nf90_def_dim(ncid, 
'fydim', self%npy-1   , yf_dimid), 
"nf90_def_dim fydim" )
 
  755   call nccheck ( nf90_def_dim(ncid, 
'vxdim', self%npx     , xv_dimid), 
"nf90_def_dim vxdim" )
 
  756   call nccheck ( nf90_def_dim(ncid, 
'vydim', self%npy     , yv_dimid), 
"nf90_def_dim vydim" )
 
  757   call nccheck ( nf90_def_dim(ncid, 
'ntile', 6            , ti_dimid), 
"nf90_def_dim ntile" )
 
  758   call nccheck ( nf90_def_dim(ncid, 
'nproc', f_comm%size(), pe_dimid), 
"nf90_def_dim ntile" )
 
  761   call nccheck( nf90_def_var(ncid, 
"flons", nf90_double, (/ xf_dimid, yf_dimid, ti_dimid /), varid(1)), 
"nf90_def_var flons" )
 
  762   call nccheck( nf90_put_att(ncid, varid(1), 
"long_name", 
"longitude of faces") )
 
  763   call nccheck( nf90_put_att(ncid, varid(1), 
"units", 
"degrees_east") )
 
  765   call nccheck( nf90_def_var(ncid, 
"flats", nf90_double, (/ xf_dimid, yf_dimid, ti_dimid /), varid(2)), 
"nf90_def_var flats" )
 
  766   call nccheck( nf90_put_att(ncid, varid(2), 
"long_name", 
"latitude of faces") )
 
  767   call nccheck( nf90_put_att(ncid, varid(2), 
"units", 
"degrees_north") )
 
  769   call nccheck( nf90_def_var(ncid, 
"vlons", nf90_double, (/ xv_dimid, yv_dimid, ti_dimid /), varid(3)), 
"nf90_def_var vlons" )
 
  770   call nccheck( nf90_put_att(ncid, varid(3), 
"long_name", 
"longitude of vertices") )
 
  771   call nccheck( nf90_put_att(ncid, varid(3), 
"units", 
"degrees_east") )
 
  773   call nccheck( nf90_def_var(ncid, 
"vlats", nf90_double, (/ xv_dimid, yv_dimid, ti_dimid /), varid(4)), 
"nf90_def_var vlats" )
 
  774   call nccheck( nf90_put_att(ncid, varid(4), 
"long_name", 
"latitude of vertices") )
 
  775   call nccheck( nf90_put_att(ncid, varid(4), 
"units", 
"degrees_north") )
 
  777   call nccheck( nf90_def_var(ncid, 
"isc", nf90_int, (/ pe_dimid /), varid(5)), 
"nf90_def_var isc" )
 
  778   call nccheck( nf90_put_att(ncid, varid(5), 
"long_name", 
"starting index i direction") )
 
  779   call nccheck( nf90_put_att(ncid, varid(5), 
"units", 
"1") )
 
  781   call nccheck( nf90_def_var(ncid, 
"iec", nf90_int, (/ pe_dimid /), varid(6)), 
"nf90_def_var iec" )
 
  782   call nccheck( nf90_put_att(ncid, varid(6), 
"long_name", 
"ending index i direction") )
 
  783   call nccheck( nf90_put_att(ncid, varid(6), 
"units", 
"1") )
 
  785   call nccheck( nf90_def_var(ncid, 
"jsc", nf90_int, (/ pe_dimid /), varid(7)), 
"nf90_def_var jsc" )
 
  786   call nccheck( nf90_put_att(ncid, varid(7), 
"long_name", 
"starting index j direction") )
 
  787   call nccheck( nf90_put_att(ncid, varid(7), 
"units", 
"1") )
 
  789   call nccheck( nf90_def_var(ncid, 
"jec", nf90_int, (/ pe_dimid /), varid(8)), 
"nf90_def_var jec" )
 
  790   call nccheck( nf90_put_att(ncid, varid(8), 
"long_name", 
"ending index j direction") )
 
  791   call nccheck( nf90_put_att(ncid, varid(8), 
"units", 
"1") )
 
  794   call nccheck( nf90_enddef(ncid), 
"nf90_enddef" )
 
  797   mydims(1,1) = 1;          mydims(2,1) = self%npx-1
 
  798   mydims(1,2) = 1;          mydims(2,2) = self%npy-1
 
  799   mydims(1,3) = self%ntile; mydims(2,3) = 1
 
  801   call nccheck( nf90_put_var( ncid, varid(1), self%grid_lon(self%isc:self%iec,self%jsc:self%jec), &
 
  802                               start = mydims(1,:), count = mydims(2,:) ), 
"nf90_put_var flons" )
 
  804   call nccheck( nf90_put_var( ncid, varid(2), self%grid_lat(self%isc:self%iec,self%jsc:self%jec), &
 
  805                               start = mydims(1,:), count = mydims(2,:) ), 
"nf90_put_var flats" )
 
  807   mydims(1,1) = 1;          mydims(2,1) = self%npx
 
  808   mydims(1,2) = 1;          mydims(2,2) = self%npy
 
  809   mydims(1,3) = self%ntile; mydims(2,3) = 1
 
  811   call nccheck( nf90_put_var( ncid, varid(3), self%egrid_lon(self%isc:self%iec+1,self%jsc:self%jec+1), &
 
  812                               start = mydims(1,:), count = mydims(2,:) ), 
"nf90_put_var vlons" )
 
  814   call nccheck( nf90_put_var( ncid, varid(4), self%egrid_lat(self%isc:self%iec+1,self%jsc:self%jec+1), &
 
  815                               start = mydims(1,:), count = mydims(2,:) ), 
"nf90_put_var vlats" )
 
  817   ijdims(1) = f_comm%rank()+1
 
  821   call nccheck( nf90_put_var( ncid, varid(5), tmpij, start = ijdims, count = ijdimf ), 
"nf90_put_var isc" )
 
  824   call nccheck( nf90_put_var( ncid, varid(6), tmpij, start = ijdims, count = ijdimf ), 
"nf90_put_var iec" )
 
  827   call nccheck( nf90_put_var( ncid, varid(7), tmpij, start = ijdims, count = ijdimf ), 
"nf90_put_var jsc" )
 
  830   call nccheck( nf90_put_var( ncid, varid(8), tmpij, start = ijdims, count = ijdimf ), 
"nf90_put_var jec" )
 
  833   call nccheck ( nf90_close(ncid), 
"nf90_close" )
 
  844   integer,              
intent(in) :: npz
 
  845   real(kind=
kind_real), 
intent(in) :: psurf
 
  846   real(kind=
kind_real), 
intent(out) :: vc(npz)
 
  848   real :: plevli(npz+1), plevlm
 
  849   real :: rd, cp, kap, kapr, kap1
 
  861     plevli(k) = self%ak(k) + self%bk(k)*psurf
 
  868     plevlm = ((plevli(k)**kap1-plevli(k+1)**kap1)/(kap1*(plevli(k)-plevli(k+1))))**kapr
 
  869     vc(k) = - log(plevlm)