16 use fckit_configuration_module, 
only: fckit_configuration
 
   39  integer, 
allocatable :: ncid_forfield(:)
 
   45  character(len=maxstring) :: datapath = 
'' 
   46  character(len=maxstring) :: filenames(
numfiles) = 
'' 
   47  character(len=maxstring) :: filenames_conf(
numfiles) = 
'' 
   48  character(len=maxstring) :: filenames_default(
numfiles) = 
'' 
   50  logical :: geosingestmeta = .false.
 
   52  logical :: iam_io_proc
 
   53  type(fckit_mpi_comm) :: ccomm
 
   54  integer :: tcomm, ocomm       
 
   55  integer :: trank, tsize       
 
   56  integer :: crank, csize       
 
   57  integer :: orank, osize       
 
   59  integer :: is_r3_tile(5), ic_r3_tile(5)
 
   60  integer :: is_r2_tile(4), ic_r2_tile(4)
 
   61  integer :: is_r3_noti(4), ic_r3_noti(4)
 
   62  integer :: is_r2_noti(3), ic_r2_noti(3)
 
   63  integer :: vindex_tile = 4
 
   64  integer :: vindex_noti = 3
 
   66  logical :: clobber = .true.
 
   67  integer :: x_dimid, y_dimid, n_dimid, z_dimid, e_dimid, t_dimid, f_dimid, c_dimid, o_dimid
 
   69  logical :: ps_in_file = .false.
 
   90 type(fckit_configuration), 
intent(in)    :: f_conf
 
   92 integer :: ierr, n, var
 
   94 integer :: tileoffset, dt_in_name
 
   95 character(len=4) :: yyyy
 
   96 character(len=2) :: mm, dd, hh, min, ss
 
  101 n = n+1; self%filenames_default(n) = 
'bkg' 
  102 n = n+1; self%filenames_default(n) = 
'crtmsrf' 
  103 n = n+1; self%filenames_default(n) = 
'fvcore_internal_rst' 
  104 n = n+1; self%filenames_default(n) = 
'moist_internal_rst' 
  105 n = n+1; self%filenames_default(n) = 
'surf_import_rst' 
  108   call abor1_ftn(
"fv3jedi_io_geos_mod.setup: number of potential restart files & 
  109                   does not match numfiles")
 
  113 self%tiledim(1) = .true.  
 
  114 self%tiledim(2) = .true.  
 
  115 self%tiledim(3) = .false. 
 
  116 self%tiledim(4) = .false. 
 
  117 self%tiledim(5) = .false. 
 
  119 self%restart(1) = .false. 
 
  120 self%restart(2) = .false. 
 
  121 self%restart(3) = .true.  
 
  122 self%restart(4) = .true.  
 
  123 self%restart(5) = .true.  
 
  132   self%filenames(n) = trim(self%filenames_conf(n))
 
  137 self%ccomm = geom%f_comm
 
  138 self%csize = self%ccomm%size()
 
  139 self%crank = self%ccomm%rank()
 
  143 self%iam_io_proc = .true.
 
  145 if (self%csize > 6) 
then 
  148   call mpi_comm_split(self%ccomm%communicator(), geom%ntile, self%ccomm%rank(), self%tcomm, ierr)
 
  149   call mpi_comm_rank(self%tcomm, self%trank, ierr)
 
  150   call mpi_comm_size(self%tcomm, self%tsize, ierr)
 
  153   call mpi_comm_split(self%ccomm%communicator(), self%trank, geom%ntile, self%ocomm, ierr)
 
  154   call mpi_comm_rank(self%ocomm, self%orank, ierr)
 
  155   call mpi_comm_size(self%ocomm, self%osize, ierr)
 
  157   if (self%trank .ne. 0) self%iam_io_proc = .false.
 
  162   call mpi_comm_dup(self%ccomm%communicator(), self%ocomm, ierr)
 
  168 if (self%iam_io_proc) 
then 
  171   self%is_r3_tile(1) = 1;           self%ic_r3_tile(1) = geom%npx-1  
 
  172   self%is_r3_tile(2) = 1;           self%ic_r3_tile(2) = geom%npy-1  
 
  173   self%is_r3_tile(3) = geom%ntile;  self%ic_r3_tile(3) = 1           
 
  174   self%is_r3_tile(4) = 1;           self%ic_r3_tile(4) = 1           
 
  175   self%is_r3_tile(5) = 1;           self%ic_r3_tile(5) = 1           
 
  176   self%is_r2_tile(1) = 1;           self%ic_r2_tile(1) = geom%npx-1
 
  177   self%is_r2_tile(2) = 1;           self%ic_r2_tile(2) = geom%npy-1
 
  178   self%is_r2_tile(3) = geom%ntile;  self%ic_r2_tile(3) = 1
 
  179   self%is_r2_tile(4) = 1;           self%ic_r2_tile(4) = 1
 
  182   tileoffset = (geom%ntile-1)*(6*(geom%npy-1)/geom%ntiles)
 
  183   self%is_r3_noti(1) = 1;              self%ic_r3_noti(1) = geom%npx-1
 
  184   self%is_r3_noti(2) = tileoffset+1;   self%ic_r3_noti(2) = geom%npy-1
 
  185   self%is_r3_noti(3) = 1;              self%ic_r3_noti(3) = 1
 
  186   self%is_r3_noti(4) = 1;              self%ic_r3_noti(4) = 1
 
  187   self%is_r2_noti(1) = 1;              self%ic_r2_noti(1) = geom%npx-1
 
  188   self%is_r2_noti(2) = tileoffset+1;   self%ic_r2_noti(2) = geom%npy-1
 
  189   self%is_r2_noti(3) = 1;              self%ic_r2_noti(3) = 1
 
  200 type(datetime),            
intent(in)    :: vdate
 
  203 character(len=4) :: yyyy
 
  204 character(len=2) :: mm, dd, hh, min, ss
 
  214   self%filenames(n) = trim(self%filenames_conf(n))
 
  217   if (index(self%filenames(n),
"%yyyy") > 0) &
 
  218     self%filenames(n) = 
replace_text(self%filenames(n),
'%yyyy',yyyy)
 
  219   if (index(self%filenames(n),
"%mm"  ) > 0) &
 
  220     self%filenames(n) = 
replace_text(self%filenames(n),
'%mm'  ,mm  )
 
  221   if (index(self%filenames(n),
"%dd"  ) > 0) &
 
  222     self%filenames(n) = 
replace_text(self%filenames(n),
'%dd'  ,dd  )
 
  223   if (index(self%filenames(n),
"%hh"  ) > 0) &
 
  224     self%filenames(n) = 
replace_text(self%filenames(n),
'%hh'  ,hh  )
 
  225   if (index(self%filenames(n),
"%MM"  ) > 0) &
 
  226     self%filenames(n) = 
replace_text(self%filenames(n),
'%MM'  ,min )
 
  227   if (index(self%filenames(n),
"%ss"  ) > 0) &
 
  228     self%filenames(n) = 
replace_text(self%filenames(n),
'%ss'  ,ss  )
 
  240 type(fckit_configuration), 
intent(in)    :: f_conf
 
  246 call string_from_conf(f_conf,
"datapath",self%datapath,
'Data',memberswap=.true.)
 
  250 if (.not. f_conf%get(
'geosingestmeta',self%geosingestmeta)) self%geosingestmeta = .false.
 
  254 if (.not. f_conf%get(
'clobber',self%clobber)) self%clobber = .true.
 
  258 if (.not. f_conf%get(
'tiledim',self%tiledim(1))) self%tiledim(1) = .true.
 
  259 if (.not. f_conf%get(
'tiledim',self%tiledim(2))) self%tiledim(2) = .true.
 
  264 n = n+1; 
call string_from_conf(f_conf,
"filename_bkgd",self%filenames_conf(1), &
 
  265                                self%filenames_default(1),memberswap=.true.)
 
  266 n = n+1; 
call string_from_conf(f_conf,
"filename_crtm",self%filenames_conf(2), &
 
  267                                self%filenames_default(2),memberswap=.true.)
 
  268 n = n+1; 
call string_from_conf(f_conf,
"filename_core",self%filenames_conf(3), &
 
  269                                self%filenames_default(3),memberswap=.true.)
 
  270 n = n+1; 
call string_from_conf(f_conf,
"filename_mois",self%filenames_conf(4), &
 
  271                                self%filenames_default(4),memberswap=.true.)
 
  272 n = n+1; 
call string_from_conf(f_conf,
"filename_surf",self%filenames_conf(5), &
 
  273                                self%filenames_default(5),memberswap=.true.)
 
  278   call abor1_ftn(
"fv3jedi_io_geos_mod.get_conf: number of potential restart files & 
  279                   does not match numfiles")
 
  282 if (f_conf%has(
"psinfile")) 
call f_conf%get_or_die(
"psinfile",self%ps_in_file)
 
  297 if (
allocated(self%ncid_forfield)) 
deallocate(self%ncid_forfield)
 
  301 if (self%csize > 6) 
call mpi_comm_free(self%tcomm, ierr)
 
  302 call mpi_comm_free(self%ocomm, ierr)
 
  308 subroutine read_meta(self, geom, vdate, calendar_type, date_init, fields)
 
  313 type(datetime),         
intent(inout) :: vdate
 
  314 integer,                
intent(inout) :: calendar_type
 
  315 integer,                
intent(inout) :: date_init(6)
 
  318 integer :: varid, date(6), intdate, inttime, idate, isecs
 
  319 character(len=8) :: cdate
 
  320 character(len=6) :: ctime
 
  321 integer(kind=c_int) :: cidate, cisecs, n, df
 
  337 if (self%iam_io_proc) 
then 
  341     if (self%ncid_isneeded(n)) 
then 
  347   call nccheck ( nf90_inq_varid(self%ncid(df), 
"time", varid), 
"nf90_inq_varid time" )
 
  348   call nccheck ( nf90_get_att(self%ncid(df), varid, 
"begin_date", intdate), &
 
  349                  "nf90_get_att begin_date" )
 
  350   call nccheck ( nf90_get_att(self%ncid(df), varid, 
"begin_time", inttime), &
 
  351                  "nf90_get_att begin_time" )
 
  354   write(cdate,
"(I0.8)") intdate
 
  355   write(ctime,
"(I0.6)") inttime
 
  358   read(cdate(1:4),*) date(1)
 
  359   read(cdate(5:6),*) date(2)
 
  360   read(cdate(7:8),*) date(3)
 
  361   read(ctime(1:2),*) date(4)
 
  362   read(ctime(3:4),*) date(5)
 
  363   read(ctime(5:6),*) date(6)
 
  366   idate = date(1)*10000 + date(2)*100 + date(3)
 
  367   isecs = date(4)*3600  + date(5)*60  + date(6)
 
  372 call self%ccomm%broadcast(idate,0)
 
  373 call self%ccomm%broadcast(isecs,0)
 
  376 call datetime_from_ifs(vdate, cidate, cisecs)
 
  393 integer :: varid, var, lev, ncid
 
  395 integer, 
pointer :: istart(:), icount(:)
 
  396 integer, 
allocatable, 
target :: is_r3_tile(:), is_r3_noti(:)
 
  397 real(kind=
kind_real), 
allocatable :: arrayg(:,:), delp(:,:,:)
 
  409 allocate(is_r3_tile(
size(self%is_r3_tile)))
 
  410 is_r3_tile = self%is_r3_tile
 
  411 allocate(is_r3_noti(
size(self%is_r3_noti)))
 
  412 is_r3_noti = self%is_r3_noti
 
  416 allocate(arrayg(1:geom%npx-1,1:geom%npy-1))
 
  421 do var = 1,
size(fields)
 
  424   ncid = self%ncid(self%ncid_forfield(var))
 
  427   if (.not. self%ps_in_file) 
then 
  428     if (trim(fields(var)%fv3jedi_name) == 
'ps') 
then 
  429       fields(var)%short_name = 
'delp' 
  430       fields(var)%npz = geom%npz
 
  431       allocate(delp(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
 
  437   if (self%iam_io_proc) 
then 
  439     tiledim = self%tiledim(self%ncid_forfield(var))
 
  441     if (
associated(istart)) 
nullify(istart)
 
  442     if (
associated(icount)) 
nullify(icount)
 
  444     if (fields(var)%npz == 1) 
then 
  446         istart => self%is_r2_tile
 
  447         icount => self%ic_r2_tile
 
  449         istart => self%is_r2_noti
 
  450         icount => self%ic_r2_noti
 
  452     elseif (fields(var)%npz > 1) 
then 
  454         istart => is_r3_tile;
 
  455         icount => self%ic_r3_tile
 
  458         icount => self%ic_r3_noti
 
  463   if (self%iam_io_proc) 
then 
  464     call nccheck ( nf90_inq_varid(ncid, trim(fields(var)%short_name), varid), &
 
  465                   "nf90_inq_varid "//trim(fields(var)%short_name) )
 
  470   do lev = 1,fields(var)%npz
 
  472     arrayg = 0.0_kind_real
 
  474     if (self%iam_io_proc) 
then 
  477       is_r3_tile(self%vindex_tile) = lev
 
  478       is_r3_noti(self%vindex_noti) = lev
 
  481       call nccheck ( nf90_get_var( ncid, varid, arrayg, istart, icount), &
 
  482                     "nf90_get_var "//trim(fields(var)%short_name) )
 
  488     if (.not. self%ps_in_file .and. trim(fields(var)%fv3jedi_name) == 
'ps') 
then 
  489       if (self%csize > 6) 
then 
  490         call scatter_tile(geom, self%tcomm, 1, arrayg, delp(geom%isc:geom%iec,geom%jsc:geom%jec,lev))
 
  492         delp(geom%isc:geom%iec,geom%jsc:geom%jec,lev) = arrayg(geom%isc:geom%iec,geom%jsc:geom%jec)
 
  495       if (self%csize > 6) 
then 
  497                           fields(var)%array(geom%isc:geom%iec,geom%jsc:geom%jec,lev))
 
  499         fields(var)%array(geom%isc:geom%iec,geom%jsc:geom%jec,lev) = &
 
  500                                                          arrayg(geom%isc:geom%iec,geom%jsc:geom%jec)
 
  506   if (.not. self%ps_in_file .and. trim(fields(var)%fv3jedi_name) == 
'ps') 
then 
  507     fields(var)%short_name = 
'ps' 
  509     fields(var)%array(:,:,1) = sum(delp,3)
 
  518 deallocate(is_r3_tile,is_r3_noti)
 
  529 subroutine write(self, geom, fields, vdate)
 
  535 type(datetime),         
intent(in)    :: vdate
 
  547 if (self%clobber) 
call write_meta(self, geom, fields, vdate)
 
  567 type(datetime),                 
intent(in)    :: vdate
 
  569 integer :: var, ymult, k, n, vc
 
  570 character(len=15)  :: datefile
 
  571 integer :: date(6), date8, time6
 
  572 character(len=8)   :: date8s, cubesize
 
  573 character(len=6)   :: time6s
 
  574 character(len=4) :: XdimVar, YdimVar
 
  575 integer :: varid(10000)
 
  577 integer, 
pointer :: istart(:), icount(:)
 
  578 integer, 
allocatable :: dimidsg(:), tiles(:), levels(:)
 
  579 real(kind=
kind_real), 
allocatable :: latg(:,:), long(:,:), xdimydim(:)
 
  584 allocate(latg(1:geom%npx-1,1:geom%npy-1))
 
  585 allocate(long(1:geom%npx-1,1:geom%npy-1))
 
  587 if (self%csize > 6) 
then 
  588   call gather_tile(geom, self%tcomm, 1, 
rad2deg*geom%grid_lat(geom%isc:geom%iec,geom%jsc:geom%jec), latg)
 
  589   call gather_tile(geom, self%tcomm, 1, 
rad2deg*geom%grid_lon(geom%isc:geom%iec,geom%jsc:geom%jec), long)
 
  591   latg = 
rad2deg*geom%grid_lat(geom%isc:geom%iec,geom%jsc:geom%jec)
 
  592   long = 
rad2deg*geom%grid_lon(geom%isc:geom%iec,geom%jsc:geom%jec)
 
  595 write(cubesize,
'(I8)') geom%npx-1
 
  599 if (self%iam_io_proc) 
then 
  604   write(date8s,
'(I4,I0.2,I0.2)')   date(1),date(2),date(3)
 
  605   write(time6s,
'(I0.2,I0.2,I0.2)') date(4),date(5),date(6)
 
  612   allocate(xdimydim(geom%npx-1))
 
  628   allocate(levels(geom%npz+1))
 
  638     if (self%ncid_isneeded(n)) 
then 
  643       if (.not. self%tiledim(n)) ymult = 6
 
  645       if ( self%tiledim(n) ) 
then 
  654       call nccheck ( nf90_def_dim(self%ncid(n), trim(xdimvar), geom%npx-1,         self%x_dimid), &
 
  655                      "nf90_def_dim "//trim(xdimvar) )
 
  656       call nccheck ( nf90_def_dim(self%ncid(n), trim(ydimvar), ymult*(geom%npy-1), self%y_dimid), &
 
  657                      "nf90_def_dim "//trim(ydimvar) )
 
  658       if (self%tiledim(n)) &
 
  659         call nccheck ( nf90_def_dim(self%ncid(n), 
"n",  geom%ntiles, self%n_dimid), 
"nf90_def_dim n"    )
 
  660       call nccheck ( nf90_def_dim(self%ncid(n), 
"lev",  geom%npz,    self%z_dimid), 
"nf90_def_dim lev"  )
 
  661       call nccheck ( nf90_def_dim(self%ncid(n), 
"edge", geom%npz+1,  self%e_dimid), 
"nf90_def_dim edge" )
 
  662       call nccheck ( nf90_def_dim(self%ncid(n), 
"time", 1,           self%t_dimid), 
"nf90_def_dim time" )
 
  665       do var = 1,
size(fields)
 
  666         if (fields(var)%npz == 4) 
then 
  667           call nccheck ( nf90_def_dim(self%ncid(n), 
"lev4", 4, self%f_dimid), 
"nf90_def_dim lev"  )
 
  673       call nccheck ( nf90_def_dim(self%ncid(n), 
"ncontact",          4, self%c_dimid), &
 
  674                      "nf90_def_dim ncontact" )
 
  675       call nccheck ( nf90_def_dim(self%ncid(n), 
"orientationStrLen", 5, self%o_dimid), &
 
  676                      "nf90_def_dim orientationStrLend" )
 
  679       if (
allocated(dimidsg)) 
deallocate(dimidsg)
 
  680       if ( self%tiledim(n) ) 
then 
  682         dimidsg(:) = (/ self%x_dimid, self%y_dimid, self%n_dimid /)
 
  685         dimidsg(:) = (/ self%x_dimid, self%y_dimid /)
 
  691       if (self%tiledim(n)) 
then 
  693         call nccheck( nf90_def_var(self%ncid(n), 
"n", nf90_int, self%n_dimid, varid(vc)), 
"nf90_def_var n" )
 
  694         call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"long_name", 
"cubed-sphere face") )
 
  695         call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"axis", 
"e") )
 
  696         call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"grads_dim", 
"e") )
 
  700       call nccheck( nf90_def_var(self%ncid(n), trim(xdimvar), nf90_double, self%x_dimid, varid(vc)), &
 
  701                     "nf90_def_var "//trim(xdimvar) )
 
  702       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"long_name", 
"Fake Longitude for GrADS Compatibility") )
 
  703       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"units", 
"degrees_east") )
 
  706       call nccheck( nf90_def_var(self%ncid(n), trim(ydimvar), nf90_double, self%y_dimid, varid(vc)), &
 
  707                     "nf90_def_var "//trim(ydimvar) )
 
  708       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"long_name", 
"Fake Latitude for GrADS Compatibility") )
 
  709       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"units", 
"degrees_north") )
 
  712       call nccheck( nf90_def_var(self%ncid(n), 
"lons", nf90_double, dimidsg, varid(vc)), 
"nf90_def_var lons" )
 
  713       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"long_name", 
"longitude") )
 
  714       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"units", 
"degrees_east") )
 
  717       call nccheck( nf90_def_var(self%ncid(n), 
"lats", nf90_double, dimidsg, varid(vc)), 
"nf90_def_var lats" )
 
  718       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"long_name", 
"latitude") )
 
  719       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"units", 
"degrees_north") )
 
  722       call nccheck( nf90_def_var(self%ncid(n), 
"lev", nf90_double, self%z_dimid, varid(vc)), 
"nf90_def_var lev" )
 
  723       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"long_name", 
"vertical level") )
 
  724       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"units", 
"layer") )
 
  725       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"positive", 
"down") )
 
  726       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"coordinate", 
"eta") )
 
  727       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"standard_name", 
"model_layers") )
 
  730       call nccheck( nf90_def_var(self%ncid(n), 
"edge", nf90_double, self%e_dimid, varid(vc)), 
"nf90_def_var edge" )
 
  731       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"long_name", 
"vertical level edges") )
 
  732       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"units", 
"layer") )
 
  733       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"positive", 
"down") )
 
  734       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"coordinate", 
"eta") )
 
  735       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"standard_name", 
"model_layers") )
 
  738       call nccheck( nf90_def_var(self%ncid(n), 
"time", nf90_int, self%t_dimid, varid(vc)), 
"nf90_def_var time" )
 
  739       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"long_name", 
"time"), 
"nf90_def_var time long_name" )
 
  740       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"begin_date", date8), 
"nf90_def_var time begin_date" )
 
  741       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"begin_time", time6), 
"nf90_def_var time begin_time" )
 
  744       call nccheck( nf90_def_var(self%ncid(n), 
"cubed_sphere", nf90_char, varid(vc)), &
 
  745                     "nf90_def_var cubed_sphere" )
 
  746       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"grid_mapping_name", 
"gnomonic cubed-sphere"), &
 
  747                     "nf90_def_var time grid_mapping_name" )
 
  748       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"file_format_version", 
"2.90"), &
 
  749                     "nf90_def_var time file_format_version" )
 
  750       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"additional_vars", 
"contacts,orientation,anchor"), &
 
  751                     "nf90_def_var time additional_vars" )
 
  752       call nccheck( nf90_put_att(self%ncid(n), varid(vc), 
"gridspec_file", 
"C"//trim(cubesize)//
"_gridspec.nc4"), &
 
  753                     "nf90_def_var gridspec_file" )
 
  761       call nccheck( nf90_enddef(self%ncid(n)), 
"nf90_enddef" )
 
  773       if (self%tiledim(n)) 
then 
  775         call nccheck( nf90_put_var( self%ncid(n), varid(vc), tiles ), 
"nf90_put_var n" )
 
  779       vc=vc+1;
call nccheck( nf90_put_var( self%ncid(n), varid(vc), xdimydim ), 
"nf90_put_var "//trim(xdimvar) )
 
  780       vc=vc+1;
call nccheck( nf90_put_var( self%ncid(n), varid(vc), xdimydim ), 
"nf90_put_var "//trim(ydimvar) )
 
  783       if (
associated(istart)) 
nullify(istart)
 
  784       if (
associated(icount)) 
nullify(icount)
 
  785       if (self%tiledim(n)) 
then 
  786         istart => self%is_r2_tile(1:3); icount => self%ic_r2_tile(1:3)
 
  788         istart => self%is_r2_noti(1:2); icount => self%ic_r2_noti(1:2)
 
  792       vc=vc+1;
call nccheck( nf90_put_var( self%ncid(n), varid(vc), long, &
 
  795                                                   "nf90_put_var lons" )
 
  797       vc=vc+1;
call nccheck( nf90_put_var( self%ncid(n), varid(vc), latg, &
 
  800                                                   "nf90_put_var lats" )
 
  803       vc=vc+1;
call nccheck( nf90_put_var( self%ncid(n), varid(vc), levels(1:geom%npz) ), 
"nf90_put_var lev" )
 
  804       vc=vc+1;
call nccheck( nf90_put_var( self%ncid(n), varid(vc), levels ), 
"nf90_put_var edge" )
 
  807       vc=vc+1;
call nccheck( nf90_put_var( self%ncid(n), varid(vc), 0 ), 
"nf90_put_var time" )
 
  825 type(datetime),                 
intent(in)    :: vdate
 
  827 integer :: var, lev, n, ncid, filei, varid
 
  828 integer, 
target :: dimids2_tile(4), dimids3_tile(5), dimidse_tile(5), dimids4_tile(5)
 
  829 integer, 
target :: dimids2_noti(3), dimids3_noti(4), dimidse_noti(4), dimids4_noti(4)
 
  830 integer, 
pointer :: dimids2(:), dimids3(:), dimidse(:), dimids4(:), dimids(:)
 
  831 integer, 
allocatable, 
target :: is_r3_tile(:), is_r3_noti(:)
 
  832 real(kind=
kind_real), 
allocatable :: arrayg(:,:)
 
  833 integer, 
pointer :: istart(:), icount(:)
 
  838 allocate(arrayg(1:geom%npx-1,1:geom%npy-1))
 
  843 allocate(is_r3_tile(
size(self%is_r3_tile)))
 
  844 is_r3_tile = self%is_r3_tile
 
  845 allocate(is_r3_noti(
size(self%is_r3_noti)))
 
  846 is_r3_noti = self%is_r3_noti
 
  851 dimids2_tile = (/ self%x_dimid, self%y_dimid, self%n_dimid,               self%t_dimid /)
 
  852 dimids3_tile = (/ self%x_dimid, self%y_dimid, self%n_dimid, self%z_dimid, self%t_dimid /)
 
  853 dimidse_tile = (/ self%x_dimid, self%y_dimid, self%n_dimid, self%e_dimid, self%t_dimid /)
 
  854 dimids4_tile = (/ self%x_dimid, self%y_dimid, self%n_dimid, self%f_dimid, self%t_dimid /)
 
  856 dimids2_noti = (/ self%x_dimid, self%y_dimid,                             self%t_dimid /)
 
  857 dimids3_noti = (/ self%x_dimid, self%y_dimid,               self%z_dimid, self%t_dimid /)
 
  858 dimidse_noti = (/ self%x_dimid, self%y_dimid,               self%e_dimid, self%t_dimid /)
 
  859 dimids4_noti = (/ self%x_dimid, self%y_dimid,               self%f_dimid, self%t_dimid /)
 
  864 do var = 1,
size(fields)
 
  866   if (self%iam_io_proc) 
then 
  870     filei = self%ncid_forfield(var)
 
  871     ncid = self%ncid(filei)
 
  875     if (self%clobber) 
then 
  877       call nccheck( nf90_redef(ncid), 
"nf90_enddef" )
 
  881       if (
associated(dimids2)) 
nullify(dimids2)
 
  882       if (
associated(dimids3)) 
nullify(dimids3)
 
  883       if (
associated(dimidse)) 
nullify(dimidse)
 
  884       if (
associated(dimids4)) 
nullify(dimids4)
 
  886       if (self%tiledim(filei)) 
then 
  887         dimids2 => dimids2_tile
 
  888         dimids3 => dimids3_tile
 
  889         dimidse => dimidse_tile
 
  890         dimids4 => dimids4_tile
 
  892         dimids2 => dimids2_noti
 
  893         dimids3 => dimids3_noti
 
  894         dimidse => dimidse_noti
 
  895         dimids4 => dimids4_noti
 
  898       if (
associated(dimids)) 
nullify (dimids)
 
  900       if (fields(var)%npz == 1) 
then 
  902       elseif (fields(var)%npz == geom%npz) 
then 
  904       elseif (fields(var)%npz == geom%npz+1) 
then 
  906       elseif (fields(var)%npz == 4) 
then 
  909         call abor1_ftn(
"write_geos: vertical dimension not supported")
 
  913       call nccheck( nf90_def_var(ncid, trim(fields(var)%short_name), nf90_double, dimids, varid), &
 
  914                     "nf90_def_var"//trim(fields(var)%short_name))
 
  917       if (self%clobber) 
then 
  920         call nccheck( nf90_put_att(ncid, varid, 
"long_name"    , trim(fields(var)%long_name) ), 
"nf90_put_att" )
 
  921         call nccheck( nf90_put_att(ncid, varid, 
"units"        , trim(fields(var)%units)     ), 
"nf90_put_att" )
 
  924         if (.not.self%restart(filei)) 
then 
  925           call nccheck( nf90_put_att(ncid, varid, 
"standard_name", trim(fields(var)%long_name) ), 
"nf90_put_att" )
 
  926           call nccheck( nf90_put_att(ncid, varid, 
"coordinates"  , 
"lons lats"                 ), 
"nf90_put_att" )
 
  927           call nccheck( nf90_put_att(ncid, varid, 
"grid_mapping" , 
"cubed_sphere"              ), 
"nf90_put_att" )
 
  933       call nccheck( nf90_enddef(ncid), 
"nf90_enddef" )
 
  938       call nccheck ( nf90_inq_varid(ncid, trim(fields(var)%short_name), varid), &
 
  939                     "nf90_inq_varid "//trim(fields(var)%short_name) )
 
  946     if (
associated(istart)) 
nullify(istart)
 
  947     if (
associated(icount)) 
nullify(icount)
 
  949     if (fields(var)%npz == 1) 
then 
  950       if (self%tiledim(filei)) 
then 
  951         istart => self%is_r2_tile; icount => self%ic_r2_tile
 
  953         istart => self%is_r2_noti; icount => self%ic_r2_noti
 
  955     elseif (fields(var)%npz > 1) 
then 
  956       if (self%tiledim(filei)) 
then 
  957         istart => is_r3_tile; icount => self%ic_r3_tile
 
  959         istart => is_r3_noti; icount => self%ic_r3_noti
 
  965   do lev = 1,fields(var)%npz
 
  967     if (self%csize > 6) 
then 
  968       call gather_tile(geom, self%tcomm, 1, fields(var)%array(geom%isc:geom%iec,geom%jsc:geom%jec,lev), arrayg)
 
  970       arrayg = fields(var)%array(geom%isc:geom%iec,geom%jsc:geom%jec,lev)
 
  973     if (self%iam_io_proc) 
then 
  975       is_r3_tile(self%vindex_tile) = lev
 
  976       is_r3_noti(self%vindex_noti) = lev
 
  978       call nccheck( nf90_put_var( ncid, varid, arrayg, start = istart, count = icount ), &
 
  979                                   "nf90_put_var "//trim(fields(var)%short_name) )
 
  989 deallocate(is_r3_tile,is_r3_noti)
 
 1001 integer,              
intent(in)    :: comm
 
 1002 integer,              
intent(in)    :: nlev
 
 1003 real(kind=
kind_real), 
intent(in)    :: array_l(geom%isc:geom%iec,geom%jsc:geom%jec,1:nlev)  
 
 1004 real(kind=
kind_real), 
intent(inout) :: array_g(1:geom%npx-1,1:geom%npy-1,1:nlev)            
 
 1006 real(kind=
kind_real), 
allocatable :: vector_g(:), vector_l(:)
 
 1007 integer :: comm_size, ierr
 
 1008 integer :: ji, jj, jk, jc, n
 
 1009 integer :: npx_g, npy_g, npx_l, npy_l
 
 1010 integer, 
allocatable :: isc_l(:), iec_l(:), jsc_l(:), jec_l(:)
 
 1011 integer, 
allocatable :: counts(:), displs(:), vectorcounts(:), vectordispls(:)
 
 1014 call mpi_comm_size(comm, comm_size, ierr)
 
 1017 allocate(counts(comm_size), displs(comm_size))
 
 1026 npx_l = geom%iec-geom%isc+1
 
 1027 npy_l = geom%jec-geom%jsc+1
 
 1030 allocate(isc_l(comm_size), iec_l(comm_size), jsc_l(comm_size), jec_l(comm_size))
 
 1031 call mpi_allgatherv(geom%isc, 1, mpi_int, isc_l, counts, displs, mpi_int, comm, ierr)
 
 1032 call mpi_allgatherv(geom%iec, 1, mpi_int, iec_l, counts, displs, mpi_int, comm, ierr)
 
 1033 call mpi_allgatherv(geom%jsc, 1, mpi_int, jsc_l, counts, displs, mpi_int, comm, ierr)
 
 1034 call mpi_allgatherv(geom%jec, 1, mpi_int, jec_l, counts, displs, mpi_int, comm, ierr)
 
 1035 deallocate(counts,displs)
 
 1038 allocate(vectorcounts(comm_size), vectordispls(comm_size))
 
 1043   vectordispls(jc) = n
 
 1045     do jj = jsc_l(jc),jec_l(jc)
 
 1046       do ji = isc_l(jc),iec_l(jc)
 
 1051   vectorcounts(jc) = n - vectordispls(jc)
 
 1055 allocate(vector_l(npx_l*npy_l*nlev))
 
 1058   do jj = geom%jsc,geom%jec
 
 1059     do ji = geom%isc,geom%iec
 
 1061       vector_l(n) = array_l(ji,jj,jk)
 
 1067 allocate(vector_g(npx_g*npy_g*nlev))
 
 1068 call mpi_gatherv( vector_l, npx_l*npy_l, mpi_double_precision, &
 
 1069                   vector_g, vectorcounts, vectordispls, mpi_double_precision, &
 
 1071 deallocate(vector_l,vectorcounts,vectordispls)
 
 1077     do jj = jsc_l(jc),jec_l(jc)
 
 1078       do ji = isc_l(jc),iec_l(jc)
 
 1080         array_g(ji,jj,jk) = vector_g(n)
 
 1085 deallocate(isc_l, iec_l, jsc_l, jec_l)
 
 1087 deallocate(vector_g)
 
 1098 integer,              
intent(in)    :: comm
 
 1099 integer,              
intent(in)    :: nlev
 
 1100 real(kind=
kind_real), 
intent(in)    :: array_g(1:geom%npx-1,1:geom%npy-1,nlev)            
 
 1101 real(kind=
kind_real), 
intent(inout) :: array_l(geom%isc:geom%iec,geom%jsc:geom%jec,nlev)  
 
 1103 real(kind=
kind_real), 
allocatable :: vector_g(:), vector_l(:)
 
 1104 integer :: comm_size, ierr
 
 1105 integer :: ji, jj, jk, jc, n
 
 1106 integer :: npx_g, npy_g, npx_l, npy_l
 
 1107 integer, 
allocatable :: isc_l(:), iec_l(:), jsc_l(:), jec_l(:)
 
 1108 integer, 
allocatable :: counts(:), displs(:), vectorcounts(:), vectordispls(:)
 
 1111 call mpi_comm_size(comm, comm_size, ierr)
 
 1114 allocate(counts(comm_size), displs(comm_size))
 
 1123 npx_l = geom%iec-geom%isc+1
 
 1124 npy_l = geom%jec-geom%jsc+1
 
 1127 allocate(isc_l(comm_size), iec_l(comm_size), jsc_l(comm_size), jec_l(comm_size))
 
 1128 call mpi_allgatherv(geom%isc, 1, mpi_int, isc_l, counts, displs, mpi_int, comm, ierr)
 
 1129 call mpi_allgatherv(geom%iec, 1, mpi_int, iec_l, counts, displs, mpi_int, comm, ierr)
 
 1130 call mpi_allgatherv(geom%jsc, 1, mpi_int, jsc_l, counts, displs, mpi_int, comm, ierr)
 
 1131 call mpi_allgatherv(geom%jec, 1, mpi_int, jec_l, counts, displs, mpi_int, comm, ierr)
 
 1132 deallocate(counts,displs)
 
 1135 allocate(vector_g(npx_g*npy_g*nlev))
 
 1136 allocate(vectorcounts(comm_size), vectordispls(comm_size))
 
 1140   vectordispls(jc) = n
 
 1142     do jj = jsc_l(jc),jec_l(jc)
 
 1143       do ji = isc_l(jc),iec_l(jc)
 
 1145         vector_g(n) = array_g(ji,jj,jk)
 
 1149   vectorcounts(jc) = n - vectordispls(jc)
 
 1151 deallocate(isc_l, iec_l, jsc_l, jec_l)
 
 1154 allocate(vector_l(npx_l*npy_l*nlev))
 
 1156 call mpi_scatterv( vector_g, vectorcounts, vectordispls, mpi_double_precision, &
 
 1157                    vector_l, npx_l*npy_l, mpi_double_precision, &
 
 1160 deallocate(vector_g,vectorcounts,vectordispls)
 
 1165   do jj = geom%jsc,geom%jec
 
 1166     do ji = geom%isc,geom%iec
 
 1168       array_l(ji,jj,jk) = vector_l(n)
 
 1172 deallocate(vector_l)
 
 1195   if (self%ncid_isneeded(n)) 
then 
 1196     call nccheck ( nf90_open( trim(self%datapath)//
'/'//trim(self%filenames(n)), nf90_nowrite, &
 
 1197                    self%ncid(n) ), 
"nf90_open"//trim(self%filenames(n)) )
 
 1209 integer :: n, fileopts
 
 1213 if (self%iam_io_proc) 
then 
 1215   if (self%clobber) 
then 
 1217     fileopts = ior(nf90_netcdf4, nf90_mpiio)
 
 1221       if (self%ncid_isneeded(n)) 
then 
 1222         call nccheck( nf90_create( trim(self%datapath)//
'/'//trim(self%filenames(n)), fileopts, &
 
 1223                                    self%ncid(n), comm = self%ocomm, info = mpi_info_null), &
 
 1224                                    "nf90_create"//trim(self%filenames(n)) )
 
 1233       if (self%ncid_isneeded(n)) 
then 
 1234         call nccheck ( nf90_open( trim(self%datapath)//
'/'//trim(self%filenames(n)), nf90_write, &
 
 1235                        self%ncid(n) ), 
"nf90_open"//trim(self%filenames(n)) )
 
 1255 if (self%iam_io_proc) 
then 
 1257     if (self%ncid_isneeded(n)) 
then 
 1258       call nccheck ( nf90_close(self%ncid(n)), 
"nf90_close" )
 
 1272 integer :: var, grp, indfile
 
 1274 if (
allocated(self%ncid_forfield)) 
deallocate(self%ncid_forfield)
 
 1275 allocate(self%ncid_forfield(
size(fields)))
 
 1276 self%ncid_forfield = -1
 
 1277 self%ncid_isneeded = .false.
 
 1281 do var = 1,
size(fields)
 
 1283   select case (trim(fields(var)%short_name))
 
 1285   case(
"vtype",
"stype",
"vfrac")                       
 
 1287   case(
"U",
"V",
"W",
"PT",
"PKZ",
"PE",
"DZ")              
 
 1289   case(
"Q",
"QILS",
"QICN",
"QLLS",
"QLCN",
"CLLS",
"CLCN") 
 
 1298   self%ncid_forfield(var) = grp
 
 1299   self%ncid_isneeded(grp) = .true.